diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 2ac7d9e47730..b86fef4c0aef 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -10,7 +10,7 @@ If this is a bug fix, make sure your description includes "fixes #xxxx", or Please provide the following information: --> -**- What I did** +**- Why I did it** **- How I did it** diff --git a/.gitignore b/.gitignore index d9ca023fedc3..9c32299fdd61 100644 --- a/.gitignore +++ b/.gitignore @@ -20,94 +20,6 @@ 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 dockers/*/Dockerfile @@ -125,6 +37,8 @@ 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 diff --git a/Makefile b/Makefile index 13a3f247fc31..b855017f928f 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,17 @@ # SONiC make file NOJESSIE ?= 0 +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,18 @@ ifeq ($(NOJESSIE), 0) make -f Makefile.work jessie endif +stretch: + @echo "+++ Making $@ +++" +ifeq ($(NOSTRETCH), 0) + make -f Makefile.work stretch +endif + clean reset init configure 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 $@ diff --git a/Makefile.cache b/Makefile.cache index 78ee4541a861..fb79e51e7f1d 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 @@ -73,7 +73,8 @@ SONIC_COMMON_FLAGS_LIST := $(CONFIGURED_PLATFORM) \ 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-slave-stretch/Dockerfile.j2 sonic-slave-stretch/Dockerfile.user \ + sonic-slave-buster/Dockerfile.j2 sonic-slave-buster/Dockerfile.user @@ -105,7 +106,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 +173,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,7 +247,7 @@ 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)) echo "[ CACHE::LOADED ] $($(1)_CACHE_DIR)/$($(1)_MOD_CACHE_FILE)" >> $($(1)_DST_PATH)/$(1).log @@ -315,7 +322,7 @@ 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 @@ -455,19 +462,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)) @@ -571,7 +580,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 +590,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 +601,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 +609,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 +617,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 +625,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 +662,7 @@ show-%: )\ )\ ) - $(info ) + $(info ) diff --git a/Makefile.work b/Makefile.work index 579d35a1ed60..ac87eef87937 100644 --- a/Makefile.work +++ b/Makefile.work @@ -9,6 +9,7 @@ # through http. # * ENABLE_ZTP: Enables zero touch provisioning. # * SHUTDOWN_BGP_ON_START: Sets admin-down state for all bgp peerings after restart. +# * INSTALL_KUBERNETES: Allows including Kubernetes # * ENABLE_PFCWD_ON_START: Enable PFC Watchdog (PFCWD) on server-facing ports # * by default for TOR switch. # * ENABLE_SYNCD_RPC: Enables rpc-based syncd builds. @@ -75,11 +76,14 @@ 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);}') SLAVE_BASE_IMAGE = $(SLAVE_DIR) @@ -176,6 +180,10 @@ SONIC_BUILD_INSTRUCTION := make \ ENABLE_DHCP_GRAPH_SERVICE=$(ENABLE_DHCP_GRAPH_SERVICE) \ ENABLE_ZTP=$(ENABLE_ZTP) \ SHUTDOWN_BGP_ON_START=$(SHUTDOWN_BGP_ON_START) \ + INSTALL_KUBERNETES=$(INSTALL_KUBERNETES) \ + KUBERNETES_VERSION=$(KUBERNETES_VERSION) \ + K8s_GCR_IO_PAUSE_VERSION=$(K8s_GCR_IO_PAUSE_VERSION) \ + K8s_CNI_FLANNEL_VERSION=$(K8s_CNI_FLANNEL_VERSION) \ SONIC_ENABLE_PFCWD_ON_START=$(ENABLE_PFCWD_ON_START) \ SONIC_ENABLE_SYNCD_RPC=$(ENABLE_SYNCD_RPC) \ SONIC_INSTALL_DEBUG_TOOLS=$(INSTALL_DEBUG_TOOLS) \ @@ -192,8 +200,9 @@ SONIC_BUILD_INSTRUCTION := make \ HTTPS_PROXY=$(https_proxy) \ SONIC_ENABLE_SYSTEM_TELEMETRY=$(ENABLE_SYSTEM_TELEMETRY) \ SONIC_ENABLE_RESTAPI=$(ENABLE_RESTAPI) \ - EXTRA_JESSIE_TARGETS=$(EXTRA_JESSIE_TARGETS) \ + EXTRA_DOCKER_TARGETS=$(EXTRA_DOCKER_TARGETS) \ BUILD_LOG_TIMESTAMP=$(BUILD_LOG_TIMESTAMP) \ + SONIC_ENABLE_IMAGE_SIGNATURE=$(ENABLE_IMAGE_SIGNATURE) \ $(SONIC_OVERRIDE_BUILD_VARS) .PHONY: sonic-slave-build sonic-slave-bash init reset @@ -209,7 +218,7 @@ ifneq ($(BLDENV), ) endif endif @$(OVERLAY_MODULE_CHECK) - + @docker inspect --type image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) &> /dev/null || \ { echo Image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) not found. Building... ; \ $(DOCKER_BASE_BUILD) ; } @@ -226,6 +235,9 @@ else @$(DOCKER_RUN) $(SLAVE_IMAGE):$(SLAVE_TAG) $(SONIC_BUILD_INSTRUCTION) $@ endif +sonic-slave-base-build : + $(DOCKER_BASE_BUILD) + sonic-slave-build : $(DOCKER_BASE_BUILD) $(DOCKER_BUILD) @@ -240,6 +252,16 @@ sonic-slave-bash : $(DOCKER_BUILD) ; } @$(DOCKER_RUN) -t $(SLAVE_IMAGE):$(SLAVE_TAG) bash +sonic-slave-run : + @$(OVERLAY_MODULE_CHECK) + @docker inspect --type image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) &> /dev/null || \ + { echo Image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) not found. Building... ; \ + $(DOCKER_BASE_BUILD) ; } + @docker inspect --type image $(SLAVE_IMAGE):$(SLAVE_TAG) &> /dev/null || \ + { echo Image $(SLAVE_IMAGE):$(SLAVE_TAG) not found. Building... ; \ + $(DOCKER_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) @@ -262,8 +284,8 @@ 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 update --init --recursive; echo "Reset complete!"; else diff --git a/README.md b/README.md index fda75bde93fc..82ac09e4b536 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ -*master builds*: - [![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*: + [![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) [![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) diff --git a/build_debian.sh b/build_debian.sh index fd247bbdf6aa..8d1db8ca37c1 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -35,9 +35,9 @@ 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 + DOCKER_VERSION=5:18.09.8~3-0~debian-$IMAGE_DISTRO fi -LINUX_KERNEL_VERSION=4.9.0-11-2 +LINUX_KERNEL_VERSION=4.19.0-6 ## Working directory to prepare the file system FILESYSTEM_ROOT=./fsroot @@ -81,9 +81,9 @@ 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 + sudo http_proxy=$http_proxy debootstrap --variant=minbase --arch $CONFIGURED_ARCH $IMAGE_DISTRO $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 + sudo http_proxy=$http_proxy debootstrap --variant=minbase --arch $CONFIGURED_ARCH $IMAGE_DISTRO $FILESYSTEM_ROOT http://debian-archive.trafficmanager.net/debian fi ## Config hostname and hosts, otherwise 'sudo ...' will complain 'sudo: unable to resolve host ...' @@ -98,12 +98,12 @@ 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 ## 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 @@ -129,7 +129,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 +165,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) @@ -184,11 +188,6 @@ if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then 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 -fi - ## Install docker echo '[INFO] Install docker' ## Install apparmor utils since they're missing and apparmor is enabled in the kernel @@ -203,11 +202,32 @@ sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT curl -o /tmp/docker 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} +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 + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y remove software-properties-common gnupg2 +if [ "$INSTALL_KUBERNETES" == "y" ] +then + ## Install Kubernetes + echo '[INFO] Install kubernetes' + sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT curl -fsSL \ + https://packages.cloud.google.com/apt/doc/apt-key.gpg | \ + sudo LANG=C chroot $FILESYSTEM_ROOT apt-key add - + ## Check out the sources list update matches current Debian version + sudo cp files/image_config/kubernetes/kubernetes.list $FILESYSTEM_ROOT/etc/apt/sources.list.d/ + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get update + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install kubeadm=${KUBERNETES_VERSION}-00 + # kubeadm package auto install kubelet & kubectl +else + echo '[INFO] Skipping Install kubernetes' +fi + ## Add docker config drop-in to specify dockerd command line sudo mkdir -p $FILESYSTEM_ROOT/etc/systemd/system/docker.service.d/ ## Note: $_ means last argument of last command @@ -282,14 +302,16 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in makedumpfile \ conntrack \ python-pip \ - python3-pip + python3-pip \ + cron \ + haveged 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-------. @@ -309,9 +331,9 @@ sudo sed -i '/^#.* en_US.* /s/^#//' $FILESYSTEM_ROOT/etc/locale.gen && \ 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 @@ -353,6 +375,12 @@ 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 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 +" + ## Config sysctl sudo mkdir -p $FILESYSTEM_ROOT/var/core sudo augtool --autosave " @@ -409,14 +437,8 @@ set /files/etc/sysctl.conf/net.core.somaxconn 512 " -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 - -## 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' +## docker Python API package is needed by Ansible docker module +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install 'docker==4.1.0' ## Note: keep pip installed for maintainance purpose ## Get gcc and python dev pkgs @@ -444,6 +466,10 @@ 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 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/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..b402867a7d20 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_as5835_54t-r0/Accton-AS5835-54T/td3-as5835t-48x10G+6x100G.config.bcm b/device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/mv2-as5835t-48x10G+6x100G.config.bcm old mode 100644 new mode 100755 similarity index 97% rename from device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/td3-as5835t-48x10G+6x100G.config.bcm rename to device/accton/x86_64-accton_as5835_54t-r0/Accton-AS5835-54T/mv2-as5835t-48x10G+6x100G.config.bcm index 4b73e8c29db3..1a575bd18a69 --- 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/mv2-as5835t-48x10G+6x100G.config.bcm @@ -14,10 +14,29 @@ parity_enable=0 mem_cache_enable=0 l2_mem_entries=32768 -#l3_mem_entries=49152 -#fpem_mem_entries=16384 +l3_mem_entries=16384 +fpem_mem_entries=16384 l2xmsg_mode=1 +# Platform specfic +bcm_num_cos=8 +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 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..44dc691640be --- 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,2 @@ -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 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_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_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_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_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_as7726_32x-r0/Accton-AS7726-32X/sai.profile b/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile index 46f5cb3bf850..461cdd76c4d5 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 @@ -SAI_INIT_CONFIG_FILE=/etc/bcm/td3-as7726-32x100G.config.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-as7726-32x100G.config.bcm 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..49838f4b0bec 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 @@ -11,26 +11,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_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 +102,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_as7816_64x-r0/Accton-AS7816-64X/sai.profile b/device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/sai.profile index e2f945e9a073..30fc08adde62 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 @@ -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 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-64x25G-48x100G_row1.config.bcm similarity index 99% rename from device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/th2-as7816-64x100G.config.bcm rename to device/accton/x86_64-accton_as7816_64x-r0/Accton-AS7816-64X/th2-as7816-64x25G-48x100G_row1.config.bcm index 2a440fbfe07c..0b19742ffe3f 100644 --- 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-64x25G-48x100G_row1.config.bcm @@ -26,20 +26,21 @@ 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 +#portmap_33=260:10 # port 66 is the first management port -portmap_66=257:10 +#portmap_66=257:10 # port 67 is the second loopback port -portmap_67=261:10 +#portmap_67=261:10 # port 100 is the second management port -portmap_100=259:10 +#portmap_100=259:10 # port 101 is the third loopback port -portmap_101=262:10 +#portmap_101=262:10 # port 135 is the fourth loopback port -portmap_135=263:10 +#portmap_135=263:10 #Port0 #FC18 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..b366aeaa93c9 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 @@ -SAI_INIT_CONFIG_FILE=/etc/bcm/th3-as9716-32x400G.config.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-as9716-32x400G.config.bcm \ No newline at end of file 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/sfputil.py b/device/accton/x86_64-accton_as9716_32d-r0/plugins/sfputil.py index bc3297471c5c..9cec97c44fb1 100644 --- 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,8 @@ try: import time + import os + import sys, getopt from sonic_sfp.sfputilbase import SfpUtilBase except ImportError as e: raise ImportError("%s - required module not found" % str(e)) @@ -141,10 +143,91 @@ def reset(self, port_num): 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< 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.iteritems(): + 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, {} \ No newline at end of file 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/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..e66e2e98416e 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 @@ -35,7 +35,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_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-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-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_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..f4450ebac53f 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 @@ -872,7 +872,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/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..cdbc4f4430b4 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 @@ -744,7 +744,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_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..bf99bb0ad4d2 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/jr2-a7280cr3-32d4-40x100G.config.bcm 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_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_7280cr3_32d4/plugins b/device/arista/x86_64-arista_7280cr3_32d4/plugins new file mode 120000 index 000000000000..5fbbf98a6284 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4/plugins @@ -0,0 +1 @@ +../x86_64-arista_common/plugins/ \ 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_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_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/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/sfputil.py b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/sfputil.py index 1daee453573e..00ab0f94ec1a 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 @@ -35,6 +35,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): @@ -94,7 +96,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 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 d00d924bcd17..ae8601e866b4 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,7 +1,8 @@ { + "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/pmon_daemon_control.json b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json index d00d924bcd17..ae8601e866b4 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,7 +1,8 @@ { + "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..e80e0d4c89b0 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 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/config_th_32x100.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th_32x100.config.bcm 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..25ea4849f7d5 100644 --- a/device/broadcom/x86_64-bcm_xlr-r0/plugins/eeprom.py +++ b/device/broadcom/x86_64-bcm_xlr-r0/plugins/eeprom.py @@ -8,10 +8,12 @@ # - 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: @@ -21,7 +23,9 @@ 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/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-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/sonic_platform/chassis.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py index 7db46e55bd8c..421d03c82bb4 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 @@ -8,20 +8,10 @@ # ############################################################################# -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 helper import APIHelper except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -44,39 +34,53 @@ 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): + from sonic_platform.sfp import Sfp + for index in range(0, NUM_SFP): + sfp = Sfp(index) + 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 for index in range(0, NUM_THERMAL): thermal = Thermal(index) 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 __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 __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 get_base_mac(self): """ @@ -108,7 +112,6 @@ 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 @@ -119,16 +122,14 @@ def get_reboot_cause(self): description = 'None' reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER - 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 + 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 hw_reboot_cause = self._component_list[0].get_register_value(RESET_REGISTER) - sw_reboot_cause = self.__read_txt_file( + sw_reboot_cause = self._api_helper.read_txt_file( reboot_cause_path) or "Unknown" - prev_sw_reboot_cause = self.__read_txt_file( + prev_sw_reboot_cause = self._api_helper.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": @@ -147,6 +148,60 @@ def get_reboot_cause(self): 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 + + ############################################################## + ####################### Other methods ######################## + ############################################################## + def get_watchdog(self): """ Retreives hardware watchdog device on this chassis @@ -159,3 +214,47 @@ 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 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.get_serial_number() + + 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/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..e51cd639a2ef 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 @@ -8,14 +8,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 +28,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 +40,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: 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..c38b57f83cd9 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 @@ -14,6 +14,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 +39,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 +79,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 +99,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 +107,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 +148,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 +159,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 +178,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 +267,43 @@ 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 + """ + return self.get_presence() and self.get_speed() > 0 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..86fc5ea726ef --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python + +import os +import struct +import subprocess +from sonic_daemon_base.daemon_base import DaemonBase +from mmap import * + +HOST_CHK_CMD = "docker > /dev/null 2>&1" +EMPTY_STRING = "" + + +class APIHelper(): + + def __init__(self): + (self.platform, self.hwsku) = DaemonBase().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, 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 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: + 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: + 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: + status = False + return status, result 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..d34c130dd4be 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 @@ -14,6 +14,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 +42,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 +56,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 +75,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): @@ -104,7 +97,7 @@ def get_voltage(self): in_num = 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 @@ -127,7 +120,7 @@ def get_current(self): cur_num = 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 @@ -150,7 +143,7 @@ def get_power(self): pw_num = 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 +189,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..c4bfbdfafb2e 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 @@ -8,7 +8,6 @@ # ############################################################################# -import os import time import subprocess import sonic_device_util @@ -16,19 +15,40 @@ 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.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.inf8628 import inf8628InterfaceId 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") 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 +57,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,62 +88,110 @@ 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): + 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.platform = self._api_helper.platform + self.hwsku = self._api_helper.hwsku # 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 = {} + + 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', 'hardwarerev', 'serialnum', 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] @@ -118,9 +202,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 __get_sfp_info(self): + port_name = "Unknown" + sfp_type = "Unknown" - def _convert_string_to_num(self, value_str): + 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,22 +236,10 @@ 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 + platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.platform]) + hwsku_path = "/".join([platform_path, self.hwsku] + ) if self._api_helper.is_host() else self.PMON_HWSKU_PATH return "/".join([hwsku_path, "port_config.ini"]) def __read_eeprom_specific_bytes(self, offset, num_bytes): @@ -180,6 +264,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_qsfp_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 @@ -203,85 +387,183 @@ 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['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['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' - if sfp_interface_bulk_data: + 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) + + 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['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['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 +592,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 not self.get_presence() or not sfpi_obj or not sfpd_obj: - return {} + 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 = 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 +741,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 +848,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 +864,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 +895,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 +928,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 +965,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 +1011,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 +1028,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 +1060,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 +1071,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 +1087,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 +1104,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 +1134,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 +1173,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 +1205,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 +1251,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 +1284,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): """ @@ -899,7 +1333,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 +1341,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) @@ -942,4 +1376,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..18c2bd30c03e 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 @@ -14,6 +14,7 @@ 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") @@ -27,6 +28,7 @@ class Thermal(ThermalBase): def __init__(self, thermal_index): self.index = thermal_index + self._api_helper = APIHelper() # Add thermal name self.THERMAL_NAME_LIST.append("Front-panel temp sensor 1") @@ -48,19 +50,11 @@ def __init__(self, thermal_index): self.ss_key = self.THERMAL_NAME_LIST[self.index] 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) + 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) 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_48x6q-r0/E582-48x6q/port_config.ini b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/port_config.ini index efb24937cec1..5e370ab2f1a3 100644 --- a/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/port_config.ini +++ b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/port_config.ini @@ -1,16 +1,16 @@ # name lanes alias speed -Ethernet1 4 eth-0-1 1000 -Ethernet2 5 eth-0-2 1000 -Ethernet3 6 eth-0-3 1000 -Ethernet4 8 eth-0-4 1000 -Ethernet5 9 eth-0-5 1000 -Ethernet6 10 eth-0-6 1000 -Ethernet7 12 eth-0-7 1000 -Ethernet8 13 eth-0-8 1000 -Ethernet9 14 eth-0-9 1000 -Ethernet10 16 eth-0-10 1000 -Ethernet11 17 eth-0-11 1000 -Ethernet12 18 eth-0-12 1000 +Ethernet1 4 eth-0-1 10000 +Ethernet2 5 eth-0-2 10000 +Ethernet3 6 eth-0-3 10000 +Ethernet4 8 eth-0-4 10000 +Ethernet5 9 eth-0-5 10000 +Ethernet6 10 eth-0-6 10000 +Ethernet7 12 eth-0-7 10000 +Ethernet8 13 eth-0-8 10000 +Ethernet9 14 eth-0-9 10000 +Ethernet10 16 eth-0-10 10000 +Ethernet11 17 eth-0-11 10000 +Ethernet12 18 eth-0-12 10000 Ethernet13 20 eth-0-13 10000 Ethernet14 21 eth-0-14 10000 Ethernet15 22 eth-0-15 10000 @@ -23,33 +23,33 @@ Ethernet21 31 eth-0-21 10000 Ethernet22 32 eth-0-22 10000 Ethernet23 34 eth-0-23 10000 Ethernet24 35 eth-0-24 10000 -Ethernet25 36 eth-0-25 10000 -Ethernet26 37 eth-0-26 10000 -Ethernet27 39 eth-0-27 10000 -Ethernet28 40 eth-0-28 10000 -Ethernet29 41 eth-0-29 10000 -Ethernet30 43 eth-0-30 10000 -Ethernet31 47 eth-0-31 10000 -Ethernet32 46 eth-0-32 10000 -Ethernet33 45 eth-0-33 10000 -Ethernet34 44 eth-0-34 10000 -Ethernet35 92 eth-0-35 10000 -Ethernet36 93 eth-0-36 10000 -Ethernet37 94 eth-0-37 10000 -Ethernet38 95 eth-0-38 10000 -Ethernet39 90 eth-0-39 10000 -Ethernet40 89 eth-0-40 10000 -Ethernet41 88 eth-0-41 10000 -Ethernet42 87 eth-0-42 10000 -Ethernet43 86 eth-0-43 10000 -Ethernet44 85 eth-0-44 10000 -Ethernet45 84 eth-0-45 10000 -Ethernet46 82 eth-0-46 10000 -Ethernet47 81 eth-0-47 10000 -Ethernet48 80 eth-0-48 10000 -Ethernet49 77,78,76,79 eth-0-49 40000 -Ethernet50 73,74,72,75 eth-0-50 40000 -Ethernet51 70,71,69,68 eth-0-51 40000 -Ethernet52 61,63,60,62 eth-0-52 40000 -Ethernet53 59,57,58,56 eth-0-53 40000 -Ethernet54 53,55,54,52 eth-0-54 40000 +Ethernet25 48 eth-0-25 10000 +Ethernet26 49 eth-0-26 10000 +Ethernet27 51 eth-0-27 10000 +Ethernet28 36 eth-0-28 10000 +Ethernet29 37 eth-0-29 10000 +Ethernet30 39 eth-0-30 10000 +Ethernet31 55 eth-0-31 10000 +Ethernet32 54 eth-0-32 10000 +Ethernet33 53 eth-0-33 10000 +Ethernet34 52 eth-0-34 10000 +Ethernet35 116 eth-0-35 10000 +Ethernet36 117 eth-0-36 10000 +Ethernet37 118 eth-0-37 10000 +Ethernet38 119 eth-0-38 10000 +Ethernet39 102 eth-0-39 10000 +Ethernet40 101 eth-0-40 10000 +Ethernet41 100 eth-0-41 10000 +Ethernet42 115 eth-0-42 10000 +Ethernet43 114 eth-0-43 10000 +Ethernet44 113 eth-0-44 10000 +Ethernet45 112 eth-0-45 10000 +Ethernet46 98 eth-0-46 10000 +Ethernet47 97 eth-0-47 10000 +Ethernet48 96 eth-0-48 10000 +Ethernet49 93,94,92,95 eth-0-49 40000 +Ethernet50 89,90,88,91 eth-0-50 40000 +Ethernet51 86,87,85,84 eth-0-51 40000 +Ethernet52 77,79,76,78 eth-0-52 40000 +Ethernet53 75,73,74,72 eth-0-53 40000 +Ethernet54 69,71,70,68 eth-0-54 40000 diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/default_sku b/device/centec/x86_64-centec_e582_48x6q-r0/default_sku index e0f7b24535b6..bad98ce86f83 100644 --- a/device/centec/x86_64-centec_e582_48x6q-r0/default_sku +++ b/device/centec/x86_64-centec_e582_48x6q-r0/default_sku @@ -1 +1 @@ -E582-48x6q t1 +E582-48x6q l2 diff --git a/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/buffers.json.j2 b/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/buffers.json.j2 new file mode 100644 index 000000000000..08e21e428b6c --- /dev/null +++ b/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/buffers.json.j2 @@ -0,0 +1,70 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} +{% set default_ports_num = 54 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(1,default_ports_num+1) %} + {% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + } +} + diff --git a/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/pg_profile_lookup.ini b/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/pg_profile_lookup.ini new file mode 100644 index 000000000000..a65244e69b5b --- /dev/null +++ b/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/pg_profile_lookup.ini @@ -0,0 +1,21 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 1000 5m 34816 18432 16384 0 + 10000 5m 34816 18432 16384 0 + 25000 5m 34816 18432 16384 0 + 40000 5m 34816 18432 16384 0 + 50000 5m 34816 18432 16384 0 + 100000 5m 36864 18432 18432 0 + 1000 40m 36864 18432 18432 0 + 10000 40m 36864 18432 18432 0 + 25000 40m 39936 18432 21504 0 + 40000 40m 41984 18432 23552 0 + 50000 40m 41984 18432 23552 0 + 100000 40m 54272 18432 35840 0 + 1000 300m 49152 18432 30720 0 + 10000 300m 49152 18432 30720 0 + 25000 300m 71680 18432 53248 0 + 40000 300m 94208 18432 75776 0 + 50000 300m 94208 18432 75776 0 + 100000 300m 184320 18432 165888 0 + diff --git a/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/port_config.ini b/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/port_config.ini index b9a831f22e8d..5b35cd7f5111 100644 --- a/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/port_config.ini +++ b/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/port_config.ini @@ -1,33 +1,55 @@ -# name lanes -Ethernet0 1 -Ethernet4 2 -Ethernet8 3 -Ethernet12 4 -Ethernet16 5 -Ethernet20 6 -Ethernet24 7 -Ethernet28 8 -Ethernet32 9 -Ethernet36 10 -Ethernet40 11 -Ethernet44 12 -Ethernet48 13 -Ethernet52 14 -Ethernet56 15 -Ethernet60 16 -Ethernet64 17 -Ethernet68 18 -Ethernet72 19 -Ethernet76 20 -Ethernet80 21 -Ethernet84 22 -Ethernet88 23 -Ethernet92 24 -Ethernet96 25 -Ethernet100 26 -Ethernet104 27 -Ethernet108 28 -Ethernet112 29 -Ethernet116 30 -Ethernet120 31 -Ethernet124 32 +# name lanes alias speed +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 +Ethernet24 2 eth-0-24 10000 +Ethernet25 4 eth-0-25 10000 +Ethernet26 5 eth-0-26 10000 +Ethernet27 6 eth-0-27 10000 +Ethernet28 7 eth-0-28 10000 +Ethernet29 8 eth-0-29 10000 +Ethernet30 9 eth-0-30 10000 +Ethernet31 10 eth-0-31 10000 +Ethernet32 12 eth-0-32 10000 +Ethernet33 13 eth-0-33 10000 +Ethernet34 15 eth-0-34 10000 +Ethernet35 16 eth-0-35 10000 +Ethernet36 18 eth-0-36 10000 +Ethernet37 19 eth-0-37 10000 +Ethernet38 21 eth-0-38 10000 +Ethernet39 22 eth-0-39 10000 +Ethernet40 24 eth-0-40 10000 +Ethernet41 25 eth-0-41 10000 +Ethernet42 27 eth-0-42 10000 +Ethernet43 28 eth-0-43 10000 +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 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-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/qos.json b/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/qos.json new file mode 100644 index 000000000000..b9dc80abb07f --- /dev/null +++ b/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/qos.json @@ -0,0 +1,133 @@ +{ + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"0", + "4":"0", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"1", + "10":"1", + "11":"1", + "12":"1", + "13":"1", + "14":"1", + "15":"1", + "16":"2", + "17":"2", + "18":"2", + "19":"2", + "20":"2", + "21":"2", + "22":"2", + "23":"2", + "24":"3", + "25":"3", + "26":"3", + "27":"3", + "28":"3", + "29":"3", + "30":"3", + "31":"3", + "32":"4", + "33":"4", + "34":"4", + "35":"4", + "36":"4", + "37":"4", + "38":"4", + "39":"4", + "40":"5", + "41":"5", + "42":"5", + "43":"5", + "44":"5", + "45":"5", + "46":"5", + "47":"5", + "48":"6", + "49":"6", + "50":"6", + "51":"6", + "52":"6", + "53":"6", + "54":"6", + "55":"6", + "56":"7", + "57":"7", + "58":"7", + "59":"7", + "60":"7", + "61":"7", + "62":"7", + "63":"7" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type":"DWRR", + "weight": "25" + }, + "scheduler.1": { + "type":"DWRR", + "weight": "30" + }, + "scheduler.2": { + "type":"DWRR", + "weight": "20" + } + }, + "PORT_QOS_MAP": { + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSY": { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "red_max_threshold":"32760", + "red_min_threshold":"4095", + "yellow_max_threshold":"32760", + "yellow_min_threshold":"4095", + "green_max_threshold": "32760", + "green_min_threshold": "4095" + }, + "AZURE_LOSSLESS": { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "red_max_threshold":"32760", + "red_min_threshold":"4095", + "yellow_max_threshold":"32760", + "yellow_min_threshold":"4095", + "green_max_threshold": "32760", + "green_min_threshold": "4095" + } + }, + "QUEUE": { + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|0-2": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|5-7": { + "scheduler" : "[SCHEDULER|scheduler.2]" + }, + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|0-2": { + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" + }, + + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|5-7": { + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" + }, + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|3-4": { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + } + } +} + + diff --git a/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/sai.profile b/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/sai.profile index 6a5af192a2b7..006512cb0bf9 100644 --- a/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/sai.profile +++ b/device/centec/x86_64-ew_es6220_x48q2h4-r0/ES6428A-X48Q2H4/sai.profile @@ -1 +1,2 @@ -BOARD_CONFIG_FILE_PATH=/etc/centec/ES6428A-X48Q2H4.json +SAI_INIT_CONFIG_FILE=/etc/centec/ES6428A-X48Q2H4-chip-profile.txt +SAI_HW_PORT_PROFILE_ID_CONFIG_FILE=/etc/centec/ES6428A-X48Q2H4-datapath-cfg.txt diff --git a/device/centec/x86_64-ew_es6220_x48q2h4-r0/default_sku b/device/centec/x86_64-ew_es6220_x48q2h4-r0/default_sku index d10e1b46328c..6f0b38195095 100644 --- a/device/centec/x86_64-ew_es6220_x48q2h4-r0/default_sku +++ b/device/centec/x86_64-ew_es6220_x48q2h4-r0/default_sku @@ -1 +1 @@ -ES6428A-X48Q2H4 t1 +ES6428A-X48Q2H4 l2 diff --git a/device/centec/x86_64-ew_es6220_x48q2h4-r0/installer.conf b/device/centec/x86_64-ew_es6220_x48q2h4-r0/installer.conf new file mode 100644 index 000000000000..5b03827200c5 --- /dev/null +++ b/device/centec/x86_64-ew_es6220_x48q2h4-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_SPEED=115200 +CONSOLE_DEV=2 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="acpi_enforce_resources=no" diff --git a/device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/eeprom.py b/device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/eeprom.py new file mode 100644 index 000000000000..8ac693f7cf58 --- /dev/null +++ b/device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/eeprom.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python + +############################################################################# +# EmbedWay +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + import exceptions + import binascii + import time + import optparse + import warnings + import os + import sys + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + import subprocess +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + #output = os.popen('i2cdetect -l | grep CP') + #a=output.read() + #b=a[4] + self.eeprom_path = "/home/admin/eeprom.bin" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/psuutil.py b/device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/psuutil.py new file mode 100644 index 000000000000..643b80c8986e --- /dev/null +++ b/device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/psuutil.py @@ -0,0 +1,57 @@ +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_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 = 39 + 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: + status = 1 + except IOError: + return True + return status == 1 + + def get_psu_presence(self, index): + if index is None: + return False + Base_bus_number = 39 + 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/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..5ac85e067618 --- /dev/null +++ b/device/centec/x86_64-ew_es6220_x48q2h4-r0/plugins/sfputil.py @@ -0,0 +1,187 @@ +# 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 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_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_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/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..273dfdbe98bb --- /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=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=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..be36c1eb832f --- /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=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=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..8d8be86636b8 --- /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=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=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/plugins/eeprom.py b/device/dell/x86_64-dell_s6000_s1220-r0/plugins/eeprom.py index b326d24f6d44..10364c2c9f8e 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 @@ -10,13 +10,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(eeprom_tlvinfo.TlvInfoDecoder): +class board(object): - 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) + def __new__(cls, name, path, cpld_root, ro): + eeprom_path = "/sys/class/i2c-adapter/i2c-10/10-0053/eeprom" + + with open("/sys/class/dmi/id/product_name", "r") as fd: + board_type = fd.read() + + 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/pmon_daemon_control.json b/device/dell/x86_64-dell_s6000_s1220-r0/pmon_daemon_control.json index 94592fa8cebc..44871c057e82 100644 --- a/device/dell/x86_64-dell_s6000_s1220-r0/pmon_daemon_control.json +++ b/device/dell/x86_64-dell_s6000_s1220-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-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/pmon_daemon_control.json b/device/dell/x86_64-dell_s6100_c2538-r0/pmon_daemon_control.json index 94592fa8cebc..44871c057e82 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/pmon_daemon_control.json +++ b/device/dell/x86_64-dell_s6100_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-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-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..98ec91a9b694 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t0.j2 @@ -0,0 +1,37 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "28550336", + "type": "ingress", + "mode": "dynamic", + "xoff": "4194112" + }, + "egress_pool": { + "size": "28550336", + "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]", + "size":"0", + "mode": "static", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_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..98ec91a9b694 --- /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": "28550336", + "type": "ingress", + "mode": "dynamic", + "xoff": "4194112" + }, + "egress_pool": { + "size": "28550336", + "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]", + "size":"0", + "mode": "static", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_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..0daed30c3bc2 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5232f-8x100G+48x50G.config.bcm 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..b9762a712d94 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/td3-s5232f-8x100G+48x50G.config.bcm @@ -0,0 +1,572 @@ +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-DEFAULT-LOSSLESS-P3P4" +sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc + diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/installer.conf b/device/dell/x86_64-dellemc_s5232f_c3538-r0/installer.conf index 925a32fc0c3a..924e0fb81963 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/installer.conf +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/installer.conf @@ -1,3 +1,2 @@ CONSOLE_PORT=0x3f8 CONSOLE_DEV=0 -CONSOLE_SPEED=115200 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py index 978ade1ce319..03bf1585d935 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 @@ -244,6 +244,9 @@ def reset(self, port_num): 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) @@ -256,9 +259,18 @@ 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) + + return True, port_dict - time.sleep(0.5) def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_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/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..9d3f2cccc2da --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/Delta-agc032/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-agc032-32x400G.config.bcm 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..631adbfc6bbd --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/plugins/eeprom.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/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..0636417def1f --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/plugins/psuutil.py @@ -0,0 +1,62 @@ +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..a448d4101939 --- /dev/null +++ b/device/delta/x86_64-delta_agc032-r0/plugins/sfputil.py @@ -0,0 +1,241 @@ +# 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 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/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/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_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/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/sai.profile b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/sai.profile new file mode 100644 index 000000000000..4bcf21c09c41 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/Juniper-QFX5200-32C-S/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-qfx5200-32x100g.config.bcm 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..7e219ae76048 --- /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=106496 +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 +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=40960 +xgxs_tx_lane_map_20=0x0213 +xgxs_tx_lane_map_12=0x3120 +num_ipv6_lpm_128b_entries=1024 +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..aec90682bc09 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/media_settings.json @@ -0,0 +1,36 @@ +{ + "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" + } + }, + "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..49a903290a18 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/eeprom.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# +# 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, 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..d85b65696d69 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/led_control.py @@ -0,0 +1,189 @@ +#!/usr/bin/env python +# +# 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, 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..a7fef390b2a0 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/psuutil.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python +# +# 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..a5e3d454350c --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_eeprom_data.py @@ -0,0 +1,415 @@ +#!/usr/bin/env python +# +# 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 os +import commands +import binascii +from sonic_eeprom import eeprom_tlvinfo + +def main(): + eeprom_qfx5200 = Eeprom() + FAN0_TYPE="cat /sys/devices/pci0000:00/0000:00:1c.0/0000:0f:00.0/refpga-tmc.15/fan0_type" + + try: + status,fan0_type=commands.getstatusoutput(FAN0_TYPE) + except Exception as e: + print "Error on refpga-tmc.15 fan0_type e:" + str(e) + return False + + AFO = "1" + + # 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 fan0_type == AFO: + 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 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..c6846ec12a8a --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_sfp_init.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# +# 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 pprint import pprint + +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): + port_inited = False + if jnpr_sfp.gpio_sfp_presence_get(port): + port_inited = jnpr_sfp.gpio_sfp_reset_set(port, 0) + + if port_inited: + i2c_eeprom_dev_update(port, True) + else: + i2c_eeprom_dev_update(port, False) + + time.sleep(2) + + #Enable optics for all ports which have XCVRs present + for port in range(jnpr_sfp.GPIO_PORT_START, jnpr_sfp.GPIO_PORT_END + 1): + if jnpr_sfp.gpio_sfp_presence_get(port): + jnpr_sfp.gpio_sfp_lpmode_set(port, 1) + + time.sleep(2) + + +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..2e3e453403a2 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5200-r0/plugins/sfputil.py @@ -0,0 +1,884 @@ +#!/usr/bin/env python +# +# 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 + 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 ctypes import create_string_buffer + +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +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 + + +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 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 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 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 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: 7, + 1: 6, + 2: 6, + 3: 6, + 4: 6, + 5: 5, + 6: 6, + 7: 5, + 8: 5, + 9: 5, + 10: 7, + 11: 7, + 12: 6, + 13: 5, + 14: 4, + 15: 3, + 16: 4, + 17: 5, + 18: 6, + 19: 6, + 20: 7, + 21: 6, + 22: 5, + 23: 5, + 24: 5, + 25: 5, + 26: 6, + 27: 5, + 28: 6, + 29: 6, + 30: 7, + 31: 7 + } + + optics_list_100g = { + "AFBR-89CDDZ-JU1", + "FTLC9551REPM-J1", + "LUX42604CO", + "EOLQ-161HG-10-LJ1", + "FTLC1151RDPL-J1", + "TR-FC13R-NJ3", + "SPQ-CE-LR-CDFB-J2" + } + + def is_100g_optics(self,part_num): + ret = part_num in self.optics_list_100g + return ret + + def process_TxCTLE(self, port_num, part_num): + + eeprom = None + + try: + if self.is_100g_optics(part_num): + # Accessing page 3 of optics + regval = 0x3 + buffer = create_string_buffer(1) + buffer[0] = chr(regval) + eeprom = open(self._port_to_eeprom_mapping[port_num], "r+b") + eeprom.seek(127) + eeprom.write(buffer[0]) + + regval = self.port_ctle_settings[port_num] + + eeprom.seek(234) + buffer[0] = eeprom.read(1) + if (buffer[0] != chr(regval)): + buffer[0] = chr(regval) + eeprom.write(buffer[0]) + eeprom.seek(235) + eeprom.write(buffer[0]) + else: + pass + # Moving back the optics page to 0 + regval = 0x0 + buffer[0] = chr(regval) + eeprom.seek(127) + eeprom.write(buffer[0]) + else: + pass + except IOError as e: + print "Error: unable to open file: %s" % str(e) + + finally: + if eeprom is not None: + eeprom.close + + @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 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]) + + 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 == 1: + return True + + return False + + def set_low_power_mode(self, port_num, lpmode): + + if lpmode == False: + lpmode = 0 + else: + lpmode = 1 + + 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 + + if not os.path.isfile(self.cmd): + pass + else: + if (self.read_from_file(self.cmd) == False): + return False, defl_dict + else: + previous_sfp_values = self.read_from_file(self.cmd) + + # 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]}) + if (current_sfp_values[port] != previous_sfp_values[port]): + ret_dict.update({port:current_sfp_values[port]}) + if(self.write_to_file(self.cmd, current_sfp_values) == True): + return True, ret_dict + else: + 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 = {} + + # 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['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'] + # 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['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['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 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: + 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 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: + transceiver_info_dict['nominal_bit_rate'] = 'N/A' + + sfp_pn_num = str(sfp_vendor_pn_data['data']['Vendor PN']['value']) + self.process_TxCTLE(port_num,sfp_pn_num) + + return transceiver_info_dict + + def get_transceiver_dom_info_dict(self, port_num): + transceiver_dom_info_dict = {} + + 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_qsfp_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' + + return transceiver_dom_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/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/plugins/psuutil.py b/device/juniper/x86_64-juniper_qfx5210-r0/plugins/psuutil.py old mode 100755 new mode 100644 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..973a2abe492b --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5210-r0/plugins/qfx5210_eeprom_data.py @@ -0,0 +1,331 @@ +#!/usr/bin/env python +# +# 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 commands +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 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/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/armhf-marvell_et6448m_52x-r0/plugins/sfputil.py b/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/sfputil.py index 92a1604f311a..431d2bc615aa 100755 --- a/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/sfputil.py +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/sfputil.py @@ -4,10 +4,17 @@ 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") +if sys.version_info[0] < 3: + import commands as cmd +else: + import subprocess as cmd + smbus_present = 1 try: @@ -24,40 +31,45 @@ 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) - + _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 : os.system("i2cset -y -m 0x0f 0 0x41 0x5 0x00") else : bus = smbus.SMBus(0) DEVICE_ADDRESS = 0x41 - DEVICEREG = 0x5 + 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,9 +77,9 @@ 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: @@ -88,53 +100,35 @@ 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 - - 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 = cmd.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 False + def read_porttab_mappings(self, porttabfile): logical = [] - logical_to_bcm = {} logical_to_physical = {} physical_to_logical = {} last_fp_port_index = 0 @@ -166,14 +160,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 +170,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 +187,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,17 +209,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)''' - @property @@ -244,15 +221,50 @@ def port_start(self): @property def port_end(self): return self._port_end - + @property def qsfp_ports(self): return self._qsfp_ports - @property + @property def port_to_eeprom_mapping(self): return self._port_to_eeprom_mapping - - @property - def get_transceiver_change_event(self): - raise NotImplementedError + + def get_transceiver_change_event(self, timeout): + port_dict = {} + port = 0 + + if timeout == 0: + cd_ms = sys.maxint + 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 index 94592fa8cebc..a3ecea34bcc9 100644 --- a/device/marvell/armhf-marvell_et6448m_52x-r0/pmon_daemon_control.json +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/pmon_daemon_control.json @@ -1,3 +1,4 @@ { + "skip_thermalctld": true, "skip_ledd": true } 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..9b937225b6ff 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -33,16 +33,16 @@ 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_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") @@ -86,14 +86,14 @@ def port_to_eeprom_mapping(self): 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, 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() + 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] 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..d12b2100eea8 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,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_fancontrol": true } 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_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/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..df63cbe39ac3 --- /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 0 +Ethernet4 4 etp2 1 +Ethernet8 8 etp3 2 +Ethernet12 12 etp4 3 +Ethernet16 16 etp5 4 +Ethernet20 20 etp6 5 +Ethernet24 24 etp7 6 +Ethernet28 28 etp8 7 +Ethernet32 32 etp9 8 +Ethernet36 36 etp10 9 +Ethernet40 40 etp11 10 +Ethernet44 44 etp12 11 +Ethernet48 48 etp13 12 +Ethernet52 52 etp14 13 +Ethernet56 56 etp15 14 +Ethernet60 60 etp16 15 +Ethernet64 64 etp17 16 +Ethernet68 68 etp18 17 +Ethernet72 72 etp19 18 +Ethernet76 76 etp20 19 +Ethernet80 80 etp21 20 +Ethernet84 84 etp22 21 +Ethernet88 88 etp23 22 +Ethernet92 92 etp24 23 +Ethernet96 96 etp25 24 +Ethernet100 100 etp26 25 +Ethernet104 104 etp27 26 +Ethernet108 108 etp28 27 +Ethernet112 112 etp29 28 +Ethernet116 116 etp30 29 +Ethernet120 120 etp31 30 +Ethernet124 124 etp32 31 +Ethernet128 128 etp33 32 +Ethernet132 132 etp34 33 +Ethernet136 136 etp35 34 +Ethernet140 140 etp36 35 +Ethernet144 144 etp37 36 +Ethernet148 148 etp38 37 +Ethernet152 152 etp39 38 +Ethernet156 156 etp40 39 +Ethernet160 160 etp41 40 +Ethernet164 164 etp42 41 +Ethernet168 168 etp43 42 +Ethernet172 172 etp44 43 +Ethernet176 176 etp45 44 +Ethernet180 180 etp46 45 +Ethernet184 184 etp47 46 +Ethernet188 188 etp48 47 +Ethernet192 192,193,194,195 etp49 48 +Ethernet196 196,197,198,199 etp50 49 +Ethernet200 200,201,202,203 etp51 50 +Ethernet204 204,205,206,207 etp52 51 +Ethernet208 208,209,210,211 etp53 52 +Ethernet212 212,213,214,215 etp54 53 +Ethernet216 216,217,218,219 etp55 54 +Ethernet220 220,221,222,223 etp56 55 +Ethernet224 224,225,226,227 etp57 56 +Ethernet228 228,229,230,231 etp58 57 +Ethernet232 232,233,234,235 etp59 58 +Ethernet236 236,237,238,239 etp60 59 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/platform_components.json b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json new file mode 100644 index 000000000000..f3ea5918a09f --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/platform_components.json @@ -0,0 +1,12 @@ +{ + "chassis": { + "x86_64-mlnx_msn3420-r0": { + "component": { + "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..4519b4841700 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3420-r0/sensors.conf @@ -0,0 +1,113 @@ +################################################################################ +# 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 "tps53679-i2c-*-70" + label in1 "PMIC-1 PSU 12V Rail (in1)" + label in2 "PMIC-1 PSU 12V Rail (in2)" + label in3 "PMIC-1 COMEX 1.8V Rail (out)" + label in4 "PMIC-1 COMEX 1.05V Rail (out)" + label temp1 "PMIC-1 Temp 1" + label temp2 "PMIC-1 Temp 2" + label power1 "PMIC-1 COMEX 1.8V Rail Pwr (out)" + label power2 "PMIC-1 COMEX 1.05V Rail Pwr (out)" + label curr1 "PMIC-1 COMEX 1.8V Rail Curr (out)" + label curr2 "PMIC-1 COMEX 1.05V 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 COMEX 1.8V Rail (out)" + label in4 "PMIC-2 COMEX 1.05V Rail (out)" + label temp1 "PMIC-2 Temp 1" + label temp2 "PMIC-2 Temp 2" + label power1 "PMIC-2 COMEX 1.8V Rail Pwr (out)" + label power2 "PMIC-2 COMEX 1.05V Rail Pwr (out)" + label curr1 "PMIC-2 COMEX 1.8V Rail Curr (out)" + label curr2 "PMIC-2 COMEX 1.05V Rail Curr (out)" + +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.8V Rail (out)" + label in4 "PMIC-4 COMEX 1.05V Rail (out)" + label temp1 "PMIC-4 Temp 1" + label temp2 "PMIC-4 Temp 2" + label power1 "PMIC-4 COMEX 1.8V Rail Pwr (out)" + label power2 "PMIC-4 COMEX 1.05V Rail Pwr (out)" + label curr1 "PMIC-4 COMEX 1.8V Rail Curr (out)" + label curr2 "PMIC-4 COMEX 1.05V Rail Curr (out)" + +# 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/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/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_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_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 index 102842d72275..a72edb85633d 100644 --- 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 @@ -5,6 +5,9 @@ 00:02:03:04:05:00 + + 1 + 64 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_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/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..7ccff5a8da4b --- /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 0 +Ethernet8 8,9,10,11 etp2 1 +Ethernet16 16,17,18,19 etp3 2 +Ethernet24 24,25,26,27 etp4 3 +Ethernet32 32,33,34,35 etp5 4 +Ethernet40 40,41,42,43 etp6 5 +Ethernet48 48,49,50,51 etp7 6 +Ethernet56 56,57,58,59 etp8 7 +Ethernet64 64,65,66,67 etp9 8 +Ethernet72 72,73,74,75 etp10 9 +Ethernet80 80,81,82,83 etp11 10 +Ethernet88 88,89,90,91 etp12 11 +Ethernet96 96,97,98,99 etp13 12 +Ethernet104 104,105,106,107 etp14 13 +Ethernet112 112,113,114,115 etp15 14 +Ethernet120 120,121,122,123 etp16 15 +Ethernet128 128,129,130,131 etp17 16 +Ethernet136 136,137,138,139 etp18 17 +Ethernet144 144,145,146,147 etp19 18 +Ethernet152 152,153,154,155 etp20 19 +Ethernet160 160,161,162,163 etp21 20 +Ethernet168 168,169,170,171 etp22 21 +Ethernet176 176,177,178,179 etp23 22 +Ethernet184 184,185,186,187 etp24 23 +Ethernet192 192,193,194,195 etp25 24 +Ethernet200 200,201,202,203 etp26 25 +Ethernet208 208,209,210,211 etp27 26 +Ethernet216 216,217,218,219 etp28 27 +Ethernet224 224,225,226,227 etp29 28 +Ethernet232 232,233,234,235 etp30 29 +Ethernet240 240,241,242,243 etp31 30 +Ethernet248 248,249,250,251 etp32 31 +Ethernet256 256,257,258,259 etp33 32 +Ethernet264 264,265,266,267 etp34 33 +Ethernet272 272,273,274,275 etp35 34 +Ethernet280 280,281,282,283 etp36 35 +Ethernet288 288,289,290,291 etp37 36 +Ethernet296 296,297,298,299 etp38 37 +Ethernet304 304,305,306,307 etp39 38 +Ethernet312 312,313,314,315 etp40 39 +Ethernet320 320,321,322,323 etp41 40 +Ethernet328 328,329,330,331 etp42 41 +Ethernet336 336,337,338,339 etp43 42 +Ethernet344 344,345,346,347 etp44 43 +Ethernet352 352,353,354,355 etp45 44 +Ethernet360 360,361,362,363 etp46 45 +Ethernet368 368,369,370,371 etp47 46 +Ethernet376 376,377,378,379 etp48 47 +Ethernet384 384,385,386,387 etp49 48 +Ethernet392 392,393,394,395 etp50 49 +Ethernet400 400,401,402,403 etp51 50 +Ethernet408 408,409,410,411 etp52 51 +Ethernet416 416,417,418,419 etp53 52 +Ethernet424 424,425,426,427 etp54 53 +Ethernet432 432,433,434,435 etp55 54 +Ethernet440 440,441,442,443 etp56 55 +Ethernet448 448,449,450,451 etp57 56 +Ethernet456 456,457,458,459 etp58 57 +Ethernet464 464,465,466,467 etp59 58 +Ethernet472 472,473,474,475 etp60 59 +Ethernet480 480,481,482,483 etp61 60 +Ethernet488 488,489,490,491 etp62 61 +Ethernet496 496,497,498,499 etp63 62 +Ethernet504 504,505,506,507 etp64 63 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/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/platform_components.json b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json new file mode 100644 index 000000000000..300a3827a0c4 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform_components.json @@ -0,0 +1,12 @@ +{ + "chassis": { + "x86_64-mlnx_msn4600c-r0": { + "component": { + "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/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/port_config.ini b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini index 1e1906ff0ef5..2a14b4a79eb6 100644 --- 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 @@ -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,4,5,6,7 etp1 0 +Ethernet8 8,9,10,11,12,13,14,15 etp2 1 +Ethernet16 16,17,18,19,20,21,22,23 etp3 2 +Ethernet24 24,25,26,27,28,29,30,31 etp4 3 +Ethernet32 32,33,34,35,36,37,38,39 etp5 4 +Ethernet40 40,41,42,43,44,45,46,47 etp6 5 +Ethernet48 48,49,50,51,52,53,54,55 etp7 6 +Ethernet56 56,57,58,59,60,61,62,63 etp8 7 +Ethernet64 64,65,66,67,68,69,70,71 etp9 8 +Ethernet72 72,73,74,75,76,77,78,79 etp10 9 +Ethernet80 80,81,82,83,84,85,86,87 etp11 10 +Ethernet88 88,89,90,91,92,93,94,95 etp12 11 +Ethernet96 96,97,98,99,100,101,102,103 etp13 12 +Ethernet104 104,105,106,107,108,109,110,111 etp14 13 +Ethernet112 112,113,114,115,116,117,118,119 etp15 14 +Ethernet120 120,121,122,123,124,125,126,127 etp16 15 +Ethernet128 128,129,130,131,132,133,134,135 etp17 16 +Ethernet136 136,137,138,139,140,141,142,143 etp18 17 +Ethernet144 144,145,146,147,148,149,150,151 etp19 18 +Ethernet152 152,153,154,155,156,157,158,159 etp20 19 +Ethernet160 160,161,162,163,164,165,166,167 etp21 20 +Ethernet168 168,169,170,171,172,173,174,175 etp22 21 +Ethernet176 176,177,178,179,180,181,182,183 etp23 22 +Ethernet184 184,185,186,187,188,189,190,191 etp24 23 +Ethernet192 192,193,194,195,196,197,198,199 etp25 24 +Ethernet200 200,201,202,203,204,205,206,207 etp26 25 +Ethernet208 208,209,210,211,212,213,214,215 etp27 26 +Ethernet216 216,217,218,219,220,221,222,223 etp28 27 +Ethernet224 224,225,226,227,228,229,230,231 etp29 28 +Ethernet232 232,233,234,235,236,237,238,239 etp30 29 +Ethernet240 240,241,242,243,244,245,246,247 etp31 30 +Ethernet248 248,249,250,251,252,253,254,255 etp32 31 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 index 31b3fd09ddd9..d145093cab96 100644 --- a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai.profile +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_4700_100G.xml +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_100G.xml b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700.xml similarity index 88% rename from device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700_100G.xml rename to device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700.xml index a76e23d5d119..177a79d13d6f 100644 --- a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700_100G.xml +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700.xml @@ -12,189 +12,189 @@ 1 - 4 + 8 17 3 1536 5 - 4 + 8 16 3 1536 9 - 4 + 8 19 3 1536 13 - 4 + 8 18 3 1536 17 - 4 + 8 21 3 1536 21 - 4 + 8 20 3 1536 25 - 4 + 8 23 3 1536 29 - 4 + 8 22 3 1536 33 - 4 + 8 29 3 1536 37 - 4 + 8 28 3 1536 41 - 4 + 8 31 3 1536 45 - 4 + 8 30 3 1536 49 - 4 + 8 25 3 1536 53 - 4 + 8 24 3 1536 57 - 4 + 8 27 3 1536 61 - 4 + 8 26 3 1536 65 - 4 + 8 14 3 1536 69 - 4 + 8 15 3 1536 73 - 4 + 8 12 3 1536 77 - 4 + 8 13 3 1536 81 - 4 + 8 10 3 1536 85 - 4 + 8 11 3 1536 89 - 4 + 8 8 3 1536 93 - 4 + 8 9 3 1536 97 - 4 + 8 2 3 1536 101 - 4 + 8 3 3 1536 105 - 4 + 8 0 @@ -205,35 +205,35 @@ 109 - 4 + 8 1 3 1536 113 - 4 + 8 6 3 1536 117 - 4 + 8 7 3 1536 121 - 4 + 8 4 3 1536 125 - 4 + 8 5 3 1536 diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf index b4eaf76f2ec0..39fa9a5f93d3 100644 --- a/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf @@ -21,83 +21,118 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" # Power controllers bus "i2c-5" "i2c-1-mux (chan_id 4)" - chip "tps53679-i2c-*-62" - label in1 "PMIC-1 PSU 12V Rail (in)" - label in2 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail (out)" - ignore in3 + 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.85V VCORE_T6_7 Rail (out)" + label in4 "PMIC-1 ASIC 1.8V T6_7 Rail (out)" label temp1 "PMIC-1 Temp 1" label temp2 "PMIC-1 Temp 2" - label power1 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail Pwr (out)" - ignore power2 - label curr1 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail Curr (out)" - ignore curr2 - chip "tps53679-i2c-*-64" - label in1 "PMIC-2 PSU 12V Rail (in)" - label in2 "PMIC-2 ASIC 1.8V MAIN Rail (out)" - compute in2 (1.5)*@, @/(1.5) - label in3 "PMIC-2 ASIC 1.2V MAIN Rail (out)" + label power1 "PMIC-1 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-1 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-1 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-1 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-1 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-1 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-1 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr4 "PMIC-1 ASIC 1.8V T6_7 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 ASIC 0.85V VCORE_T6_7 Rail (out)" + label in4 "PMIC-2 ASIC 1.8V T6_7 Rail (out)" label temp1 "PMIC-2 Temp 1" label temp2 "PMIC-2 Temp 2" - label power1 "PMIC-2 ASIC 1.8V MAIN Rail Pwr (out)" - label power2 "PMIC-2 ASIC 1.2V MAIN Rail Pwr (out)" - label curr1 "PMIC-2 ASIC 1.8V MAIN Rail Curr (out)" - label curr2 "PMIC-2 ASIC 1.2V MAIN Rail Curr (out)" - chip "tps53679-i2c-*-66" - label in1 "PMIC-3 PSU 12V Rail (in)" - label in2 "PMIC-3 ASIC 0.85V VCORE_T0_1 Rail (out)" - label in3 "PMIC-3 ASIC 1.8V T0_1 Rail (out)" + label power1 "PMIC-2 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-2 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-2 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-2 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-2 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-2 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-2 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr4 "PMIC-2 ASIC 1.8V T6_7 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 VCORE_T6_7 Rail (out)" + label in4 "PMIC-3 ASIC 1.8V T6_7 Rail (out)" label temp1 "PMIC-3 Temp 1" label temp2 "PMIC-3 Temp 2" - label power1 "PMIC-3 ASIC 0.85V VCORE_T0_1 Rail Pwr (out)" - label power2 "PMIC-3 ASIC 1.8V T0_1 Rail Pwr (out)" - label curr1 "PMIC-3 ASIC 0.85V VCORE_T0_1 Rail Curr (out)" - label curr2 "PMIC-3 ASIC 1.8V T0_1 Rail Curr (out)" - chip "tps53679-i2c-*-68" - label in1 "PMIC-4 PSU 12V Rail (in)" - label in2 "PMIC-4 ASIC 0.85V VCORE_T2_3 Rail (out)" - label in3 "PMIC-4 ASIC 1.8V T2_3 Rail (out)" + label power1 "PMIC-3 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-3 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-3 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-3 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-3 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-3 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-3 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr4 "PMIC-3 ASIC 1.8V T6_7 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 VCORE_T6_7 Rail (out)" + label in4 "PMIC-4 ASIC 1.8V T6_7 Rail (out)" label temp1 "PMIC-4 Temp 1" label temp2 "PMIC-4 Temp 2" - label power1 "PMIC-4 ASIC 0.85V VCORE_T2_3 Rail Pwr (out)" - label power2 "PMIC-4 ASIC 1.8V T2_3 Rail Pwr (out)" - label curr1 "PMIC-4 ASIC 0.85V VCORE_T2_3 Rail Curr (out)" - label curr2 "PMIC-4 ASIC 1.8V T2_3 Rail Curr (out)" - chip "tps53679-i2c-*-6a" - label in1 "PMIC-5 PSU 12V Rail (in)" - label in2 "PMIC-5 ASIC 0.85V VCORE_T4_5 Rail (out)" - label in3 "PMIC-5 ASIC 1.8V T4_5 Rail (out)" + label power1 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-4 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-4 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-4 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-4 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr4 "PMIC-4 ASIC 1.8V T6_7 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 VCORE_T6_7 Rail (out)" + label in4 "PMIC-5 ASIC 1.8V T6_7 Rail (out)" label temp1 "PMIC-5 Temp 1" label temp2 "PMIC-5 Temp 2" - label power1 "PMIC-5 ASIC 0.85V VCORE_T4_5 Rail Pwr (out)" - label power2 "PMIC-5 ASIC 1.8V T4_5 Rail Pwr (out)" - label curr1 "PMIC-5 ASIC 0.85V VCORE_T4_5 Rail Curr (out)" - label curr2 "PMIC-5 ASIC 1.8V T4_5 Rail Curr (out)" - chip "tps53679-i2c-*-6c" - label in1 "PMIC-6 PSU 12V Rail (in)" - label in2 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail (out)" - label in3 "PMIC-6 ASIC 1.8V T6_7 Rail (out)" + label power1 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-5 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-5 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-5 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-5 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr4 "PMIC-5 ASIC 1.8V T6_7 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 VCORE_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 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" - label power2 "PMIC-6 ASIC 1.8V T6_7 Rail Pwr (out)" - label curr1 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" - label curr2 "PMIC-6 ASIC 1.8V T6_7 Rail Curr (out)" - chip "tps53679-i2c-*-6e" - label in1 "PMIC-7 PSU 12V Rail (in)" - label in2 "PMIC-7 ASIC 1.2V T0_3 Rail (out)" - label in3 "PMIC-7 ASIC 1.2V T4_7 Rail (out)" + label power1 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-6 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-6 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-6 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-6 ASIC 0.85V VCORE_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 0.85V VCORE_T6_7 Rail (out)" + label in4 "PMIC-7 ASIC 1.8V T6_7 Rail (out)" label temp1 "PMIC-7 Temp 1" label temp2 "PMIC-7 Temp 2" - label power1 "PMIC-7 ASIC 1.2V T0_3 Rail Pwr (out)" - label power2 "PMIC-7 ASIC 1.2V T4_7 Rail Pwr (out)" - label curr1 "PMIC-7 ASIC 1.2V T0_3 Rail Curr (out)" - label curr2 "PMIC-7 ASIC 1.2V T4_7 Rail Curr (out)" + label power1 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Pwr (in)" + label power2 "PMIC-7 ASIC 1.8V T6_7 Rail Pwr (in)" + label power3 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power4 "PMIC-7 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Curr (in)" + label curr2 "PMIC-7 ASIC 1.8V T6_7 Rail Curr (in)" + label curr3 "PMIC-7 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr4 "PMIC-7 ASIC 1.8V T6_7 Rail Curr (out)" bus "i2c-15" "i2c-1-mux (chan_id 6)" chip "tps53679-i2c-*-58" - label in1 "PMIC-8 PSU 12V Rail (in)" - label in2 "PMIC-8 COMEX 1.8V Rail (out)" - label in3 "PMIC-8 COMEX 1.05V Rail (out)" + label 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)" @@ -105,15 +140,16 @@ bus "i2c-15" "i2c-1-mux (chan_id 6)" label curr1 "PMIC-8 COMEX 1.8V Rail Curr (out)" label curr2 "PMIC-8 COMEX 1.05V Rail Curr (out)" chip "tps53679-i2c-*-61" - label in1 "PMIC-9 PSU 12V Rail (in)" - label in2 "PMIC-9 COMEX 1.2V Rail (out)" - ignore in3 + label 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 + ignore power2 label curr1 "PMIC-9 COMEX 1.2V Rail Curr (out)" - ignore curr2 + ignore curr2 # Power supplies bus "i2c-4" "i2c-1-mux (chan_id 3)" 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/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..c6a21eb19fc5 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/pmon_daemon_control.json @@ -0,0 +1,7 @@ +{ + "skip_ledd": true, + "skip_xcvrd": true, + "skip_psud": true, + "skip_syseepromd": true, + "skip_thermalctld": true +} diff --git a/dockers/docker-base-buster/Dockerfile.j2 b/dockers/docker-base-buster/Dockerfile.j2 new file mode 100644 index 000000000000..fcf983229504 --- /dev/null +++ b/dockers/docker-base-buster/Dockerfile.j2 @@ -0,0 +1,108 @@ +{% 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 \ + less \ + perl \ + procps \ + python \ + python-pip \ + python3 \ + python3-pip \ + rsyslog \ + vim-tiny \ +# Install dependencies of supervisor + python-pkg-resources \ + python-meld3 \ +# dependencies of redis-tools + libatomic1 \ + libjemalloc2 \ + liblua5.1-0 \ + lua-bitop \ + lua-cjson \ +# common dependencies + libpython2.7 \ + libdaemon0 \ + libdbus-1-3 \ + libjansson4 \ +# ip and ifconfig utility missing in docker for arm arch + iproute2 \ + net-tools \ +# for arm arch: Installing j2cli dependency package MarkupSafe from source relies on weeksetuptools and wheel + python-setuptools \ + python-wheel + +# For templating +RUN pip install j2cli + +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 %} + +# Add support for supervisord to handle startup dependencies +RUN pip install supervisord-dependent-startup==1.4.0 + +# 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..7c7a64d7afe0 --- /dev/null +++ b/dockers/docker-base-buster/etc/rsyslog.d/supervisor.conf @@ -0,0 +1,9 @@ +$ModLoad imfile + +$InputFileName /var/log/supervisor/supervisord.log +$InputFileTag supervisord +$InputFileStateFile state-supervisor +$InputFileSeverity info +$InputFileFacility local0 +$InputFilePersistStateInterval 1 +$InputRunFileMonitor 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..4a94e3161ab1 --- /dev/null +++ b/dockers/docker-base-buster/sources.list @@ -0,0 +1,8 @@ +## 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 diff --git a/dockers/docker-base-buster/sources.list.arm64 b/dockers/docker-base-buster/sources.list.arm64 new file mode 100644 index 000000000000..b92971dccead --- /dev/null +++ b/dockers/docker-base-buster/sources.list.arm64 @@ -0,0 +1,7 @@ +## 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 diff --git a/dockers/docker-base-buster/sources.list.armhf b/dockers/docker-base-buster/sources.list.armhf new file mode 100644 index 000000000000..e28fd605678f --- /dev/null +++ b/dockers/docker-base-buster/sources.list.armhf @@ -0,0 +1,7 @@ +## 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 diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index 17047d13a839..30e59eccf705 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -44,6 +44,7 @@ RUN apt-get update && \ perl \ procps \ python \ + python-pip \ rsyslog \ vim-tiny \ # Install dependencies of supervisor @@ -59,12 +60,16 @@ RUN apt-get update && \ libpython2.7 \ libdaemon0 \ libdbus-1-3 \ - libjansson4 - + libjansson4 \ # ip and ifconfig utility missing in docker for arm arch -RUN apt-get -y install \ iproute2 \ - net-tools + net-tools \ +# for arm arch: Installing j2cli dependency package MarkupSafe from source relies on weeksetuptools and wheel + python-setuptools \ + python-wheel + +# For templating +RUN pip install j2cli RUN mkdir -p /etc/supervisor /var/log/supervisor @@ -82,6 +87,9 @@ RUN apt-get -y purge \ {{ install_debian_packages(docker_base_stretch_debs.split(' ')) }} {%- endif %} +# Add support for supervisord to handle startup dependencies +RUN pip install supervisord-dependent-startup==1.4.0 + # Clean up apt # Remove /var/lib/apt/lists/*, could be obsoleted for derived images RUN apt-get clean -y && \ 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-config-engine-buster/Dockerfile.j2 b/dockers/docker-config-engine-buster/Dockerfile.j2 new file mode 100644 index 000000000000..e24414a0fc26 --- /dev/null +++ b/dockers/docker-config-engine-buster/Dockerfile.j2 @@ -0,0 +1,50 @@ +{% 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 \ + # Dependencies for sonic-cfggen + python-lxml \ + python-yaml \ + python-bitarray \ + python-pip \ + python-dev \ + python-natsort \ + apt-utils \ + python-setuptools + +RUN pip install --upgrade pip + +RUN pip install \ + netaddr \ + ipaddr \ + jinja2 \ + pyangbind==0.6.0 + +{% 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 %} + +## Clean up +RUN apt-get purge -y \ + python-pip \ + python-dev && \ + apt-get clean -y && \ + apt-get autoclean -y && \ + apt-get autoremove -y && \ + rm -rf /debs /python-wheels diff --git a/dockers/docker-database/Dockerfile.j2 b/dockers/docker-database/Dockerfile.j2 index 8cd181614672..24416c838db5 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 @@ -34,8 +34,8 @@ 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 ["critical_processes", "/etc/supervisor"] diff --git a/dockers/docker-database/database_config.json b/dockers/docker-database/database_config.json.j2 similarity index 94% rename from dockers/docker-database/database_config.json rename to dockers/docker-database/database_config.json.j2 index c62bf746acba..3383ec161144 100644 --- a/dockers/docker-database/database_config.json +++ b/dockers/docker-database/database_config.json.j2 @@ -3,7 +3,7 @@ "redis":{ "hostname" : "127.0.0.1", "port" : 6379, - "unix_socket_path" : "/var/run/redis/redis.sock", + "unix_socket_path" : "/var/run/redis{{NAMESPACE_ID}}/redis.sock", "persistence_for_warm_boot" : "yes" } }, 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..5dae34d8f616 100755 --- a/dockers/docker-database/docker-database-init.sh +++ b/dockers/docker-database/docker-database-init.sh @@ -1,13 +1,26 @@ #!/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 +REDIS_DIR=/var/run/redis$NAMESPACE_ID +mkdir -p $REDIS_DIR/sonic-db + +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 - cp /etc/default/sonic-db/database_config.json /var/run/redis/sonic-db + j2 /usr/share/sonic/templates/database_config.json.j2 > $REDIS_DIR/sonic-db/database_config.json fi mkdir -p /etc/supervisor/conf.d/ + +# 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 + # 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 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..44268274cdad 100644 --- a/dockers/docker-database/supervisord.conf.j2 +++ b/dockers/docker-database/supervisord.conf.j2 @@ -10,7 +10,7 @@ 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 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..97de4f360428 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -3,27 +3,39 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -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 dhcp_relay events=PROCESS_STATE_EXITED 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 %} @@ -81,6 +93,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited {% endif %} {% endif %} @@ -128,6 +142,8 @@ 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/start.sh b/dockers/docker-dhcp-relay/start.sh index dbbf32251080..86ba91147ef5 100755 --- a/dockers/docker-dhcp-relay/start.sh +++ b/dockers/docker-dhcp-relay/start.sh @@ -1,11 +1,5 @@ #!/usr/bin/env bash -# Remove stale rsyslog PID file if it exists -rm -f /var/run/rsyslogd.pid - -# Start rsyslog -supervisorctl start rsyslogd - # If our supervisor config has entries in the "isc-dhcp-relay" group... if [ $(supervisorctl status | grep -c "^isc-dhcp-relay:") -gt 0 ]; then # Wait for all interfaces to come up and be assigned IPv4 addresses before @@ -15,13 +9,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 c382df3c2ba3..9499cc1ed51a 100644 --- a/dockers/docker-fpm-frr/Dockerfile.j2 +++ b/dockers/docker-fpm-frr/Dockerfile.j2 @@ -39,9 +39,8 @@ RUN apt-get clean -y && \ apt-get autoremove -y && \ rm -rf /debs ~/.cache -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 ["bgpcfgd", "docker_init.sh", "/usr/bin/"] COPY ["snmp.conf", "/etc/snmp/frr.conf"] COPY ["TSA", "/usr/bin/TSA"] COPY ["TSB", "/usr/bin/TSB"] @@ -52,4 +51,4 @@ RUN chmod a+x /usr/bin/TSA && \ chmod a+x /usr/bin/TSB && \ chmod a+x /usr/bin/TSC -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/bin/docker_init.sh"] diff --git a/dockers/docker-fpm-frr/TSA b/dockers/docker-fpm-frr/TSA index 1d74757b2d5f..441765694a4f 100755 --- a/dockers/docker-fpm-frr/TSA +++ b/dockers/docker-fpm-frr/TSA @@ -1,22 +1,38 @@ #!/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+$?)) +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'); + do + echo "$config" | grep -q "route-map $route_map_name permit 2" + c=$((c+$?)) + echo "$config" | grep -q "route-map $route_map_name deny 3" + c=$((c+$?)) + done + return $c +} -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 + case "$route_map_name" in + *V4*) + ip_version=V4 + ;; + *V6*) + ip_version=V6 + ;; + esac + sonic-cfggen -d -a "{\"route_map_name\":\"$route_map_name\", \"ip_version\": \"$ip_version\"}" -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..84a3c183e659 100755 --- a/dockers/docker-fpm-frr/TSB +++ b/dockers/docker-fpm-frr/TSB @@ -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+$?)) +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'); + do + echo "$config" | grep -q "route-map $route_map_name permit 2" + c=$((c+$?)) + e=$((e+1)) + echo "$config" | grep -q "route-map $route_map_name deny 3" + c=$((c+$?)) + e=$((e+1)) + done + return $((e-c)) +} -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 + 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..3a3ad73d00b4 100755 --- a/dockers/docker-fpm-frr/TSC +++ b/dockers/docker-fpm-frr/TSC @@ -1,21 +1,48 @@ #!/bin/bash +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'); + do + echo "$config" | grep -q "route-map $route_map_name permit 2" + c=$((c+$?)) + echo "$config" | grep -q "route-map $route_map_name deny 3" + 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'); + do + echo "$config" | grep -q "route-map $route_map_name permit 2" + c=$((c+$?)) + e=$((e+1)) + echo "$config" | grep -q "route-map $route_map_name deny 3" + c=$((c+$?)) + e=$((e+1)) + done + return $((e-c)) +} + 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+$?)) -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 diff --git a/dockers/docker-fpm-frr/bgpcfgd b/dockers/docker-fpm-frr/bgpcfgd index 4e638def47b7..adc142c109d2 100755 --- a/dockers/docker-fpm-frr/bgpcfgd +++ b/dockers/docker-fpm-frr/bgpcfgd @@ -10,10 +10,11 @@ import traceback import os import tempfile import json -from collections import defaultdict +from collections import defaultdict, OrderedDict from pprint import pprint -from pprint import pformat +from functools import partial +import yaml import jinja2 import netaddr from swsscommon import swsscommon @@ -23,35 +24,178 @@ g_run = True g_debug = False -def run_command(command, shell=False): - str_cmd = " ".join(command) +def log_debug(msg): + """ Send a message msg to the syslog as DEBUG """ if g_debug: - syslog.syslog(syslog.LOG_DEBUG, "execute command {}.".format(str_cmd)) + 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) + + +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) 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)) + 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 +class ConfigMgr(object): + """ The class represents frr configuration """ + def __init__(self): + self.current_config = None + + def reset(self): + """ Reset stored config """ + self.current_config = None + + def update(self): + """ Read current config from FRR """ + self.current_config = None + 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 + self.current_config = self.to_canonical(out) + + def push(self, cmd): + """ + Push new changes to FRR + :param cmd: configuration change for FRR. Type: String + :return: True if change was applied successfully, False otherwise + """ + return self.write(cmd) + + def write(self, cmd): + """ + Write configuration change to FRR. + :param cmd: new configuration to write into FRR. Type: String + :return: True if change was applied successfully, False otherwise + """ + fd, tmp_filename = tempfile.mkstemp(dir='/tmp') + os.close(fd) + with open(tmp_filename, 'w') as fp: + fp.write("%s\n" % cmd) + command = ["vtysh", "-f", tmp_filename] + ret_code, out, err = run_command(command) + if not g_debug: + os.remove(tmp_filename) + if ret_code != 0: + err_tuple = str(cmd), ret_code, out, err + log_err("ConfigMgr::push(): can't push configuration '%s', rc='%d', stdout='%s', stderr='%s'" % err_tuple) + if ret_code == 0: + self.current_config = None # invalidate config + return ret_code == 0 + + @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 = [] + cur_offset = 0 + lines = raw_config.split("\n") + cur_path = [lines[0]] + for line in lines: + if line.strip().startswith('!') or line.strip() == '': + continue + n_spaces = ConfigMgr.count_spaces(line) + s_line = line.strip() + assert(n_spaces == cur_offset or (n_spaces + 1) == cur_offset or (n_spaces - 1) == cur_offset) + 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 + + class TemplateFabric(object): + """ Fabric for rendering jinja2 templates """ 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 = 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): @@ -59,12 +203,13 @@ class TemplateFabric(object): else: try: addr = netaddr.IPNetwork(str(value)) - except: + 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): @@ -72,56 +217,70 @@ class TemplateFabric(object): else: try: addr = netaddr.IPNetwork(str(value)) - except: + 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)) -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) + @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 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) + if not value: + return table - def run(self): - while g_run: - state, _ = self.selector.select(Daemon.SELECT_TIMEOUT) - if state == self.selector.TIMEOUT: + for key, val in value.items(): + if not isinstance(key, tuple): 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)) + table[key] = val + return table 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) - self.notify = defaultdict(lambda: defaultdict(list)) + 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 == '': @@ -133,77 +292,229 @@ class Directory(object): d = d[p] return True, d - def path_exist(self, slot, path): + 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, slot, path): + 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, slot, key, value): + 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(slot, path): + if self.path_exist(db, table, path): for handler in self.notify[slot][path]: handler() - def get(self, slot, key): + 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 remove(self, 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: - syslog.syslog(syslog.LOG_ERR, "Directory: Can't remove key '%s' from slot '%s'. The key doesn't exist" % (key, slot)) + 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)) + log_err("Directory: Can't remove key '%s' from slot '%s'. The slot doesn't exist" % (key, slot)) - def remove_slot(self, slot, key): + 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: - syslog.syslog(syslog.LOG_ERR, "Directory: Can't remove slot '%s'. The slot doesn't exist" % slot) + 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): + 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 slot, path in deps: - res = res and self.path_exist(slot, path) + for db, table, path in deps: + res = res and self.path_exist(db, table, path) return res def subscribe(self, deps, handler): - for slot, path in deps: + """ + 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) +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): + """ Constructor """ + 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: + 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().getDbId()][subscriber.getTableName()]: + callback(key, op, dict(fvs)) + + class Manager(object): - def __init__(self, daemon, directory, deps, database, table_name): - self.directory = directory + """ 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 = [] - daemon.add_manager(database, table_name, self.handler) - directory.subscribe(deps, self.on_deps_change) + 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): + if self.directory.available_deps(self.deps): # all required dependencies are set in the Directory? res = self.set_handler(key, data) - if not res: + 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: - syslog.syslog(syslog.LOG_ERR, 'Invalid operation "%s" for key "%s"' % (op, key)) + 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 = [] @@ -214,286 +525,409 @@ class Manager(object): 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__)) + """ Placeholder for 'SET' command """ + log_err("set_handler() wasn't implemented for %s" % self.__class__.__name__) def del_handler(self, key): - syslog.syslog(syslog.LOG_ERR, "%s wasn't implemented for %s" % (self.__name__, self.__class__)) + """ Placeholder for 'DEL' command """ + log_err("del_handler wasn't implemented for %s" % self.__class__.__name__) -class BGPDeviceMetaMgr(Manager): - def __init__(self, daemon, directory): - super(BGPDeviceMetaMgr, self).__init__( - daemon, - directory, +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, [], - "CONFIG_DB", - swsscommon.CFG_DEVICE_METADATA_TABLE_NAME + db, + table, ) 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) + """ 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): - self.directory.remove("meta", key) + """ Implementation of 'DEL' command for this class """ + self.directory.remove(self.db_name, self.table_name, key) -class BGPNeighborMetaMgr(Manager): - def __init__(self, daemon, directory): - super(BGPNeighborMetaMgr, self).__init__( - daemon, - directory, +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, [], - "CONFIG_DB", - swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME + db, + table, ) def set_handler(self, key, data): - self.directory.put("neigmeta", 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, data["interface"])) + 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): - self.directory.remove("neigmeta", key) - - -class BGPPeerMgr(Manager): - def __init__(self, daemon, directory): - super(BGPPeerMgr, self).__init__( - daemon, - directory, - [ - ("meta", "localhost/bgp_asn"), - ("neigmeta", ""), - ("local_addresses", ""), - ("interfaces", ""), - ], - "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'), - } + """ 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) - def set_handler(self, key, data): - key = self.normalize_key(key) - vrf, nbr = key.split('|', 1) - if key not in self.peers: - cmd = None - if "local_addr" not in data: - syslog.syslog(syslog.LOG_WARNING, 'Peer {}. Error in missing required attribute "local_addr"'.format(key)) - else: - # The bgp session that belongs to a vnet cannot be advertised as the default BGP session. - # So we need to check whether this bgp session belongs to a vnet. - interface = InterfaceMgr.get_local_interface(self.directory, data["local_addr"]) - if not interface: - syslog.syslog(syslog.LOG_INFO, - 'Peer {} with local address {} wait for the corresponding interface to be set'.format( - key, - data["local_addr"] - ) - ) - return False - vnet = InterfaceMgr.get_vnet(interface) - if vnet: - # Ignore the bgp session that is in a vnet - syslog.syslog( - syslog.LOG_INFO, - 'Ignore the BGP peer {} as the interface {} is in vnet {}'.format( - key, - interface, - vnet - ) - ) - return True +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") - neigmeta = self.directory.get_slot("neigmeta") - if 'name' in data and data["name"] not in neigmeta: - syslog.syslog(syslog.LOG_INFO, - 'Peer {} with neighbor name {} wait for the corresponding neighbor metadata to be set'.format( - key, - data["name"] - ) - ) - return False - try: - cmd = self.templates["add"].render( - 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 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 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 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 - 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) + return self.update_entity(policy, "Routing policy for peer '%s'" % name) - command = ["vtysh", "-f", tmp_filename] - rc, _, _ = run_command(command) - os.remove(tmp_filename) - return rc == 0 + 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 - @staticmethod - def normalize_key(key): - if '|' not in key: - return 'default|' + key + if kwargs['vrf'] == 'default': + cmd = ('router bgp %s\n' % kwargs['bgp_asn']) + pg else: - return key + cmd = ('router bgp %s vrf %s\n' % (kwargs['bgp_asn'], kwargs['vrf'])) + pg - @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() + return self.update_entity(cmd, "Peer-group for peer '%s'" % name) - 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)) + 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: + """ + ret_code = self.cfg_mgr.push(cmd) + if ret_code: + log_info("%s was updated" % txt) + else: + log_err("Can't update %s" % txt) + return ret_code - return peers +class BGPPeerMgrBase(Manager): + """ Manager of BGP peers """ + def __init__(self, common_objs, db_name, table_name, peer_type): + """ + 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 -class InterfaceMgr(Manager): - def __init__(self, daemon, directory, interface_table = swsscommon.CFG_INTF_TABLE_NAME): - super(InterfaceMgr, self).__init__( - daemon, - directory, - [], - "CONFIG_DB", - interface_table + 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", ""), + ] + + self.check_neig_meta = 'bgp' in self.constants \ + and 'use_neighbors_meta' in self.constants['bgp'] \ + and self.constants['bgp']['use_neighbors_meta'] + 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): - # Interface table can have two keys, - # one with ip prefix and one without ip prefix - if '|' in key: - data = {} - data["interface"], network = key.split('|', 1) - try: - network = netaddr.IPNetwork(str(network)) - except: - syslog.syslog( - syslog.LOG_WARNING, - 'Subnet {} format is wrong for interface {}'.format( - network, - data["interface"] - ) - ) + """ + 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. + 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 - data["prefixlen"] = str(network.prefixlen) - ip = str(network.ip) - self.directory.put("local_addresses", ip, data) + 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), + '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: + ret_code = self.apply_op(cmd, vrf) + key = (vrf, nbr) + if ret_code: + self.peers.add(key) + log_info("Peer '(%s|%s)' added with attributes '%s'" % print_data) + else: + log_err("Peer '(%s|%s)' wasn't added." % (vrf, nbr)) + + 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: - self.directory.put("interfaces", key, data) + 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): - if '|' in key: - interface, network = key.split('|', 1) - try: - network = netaddr.IPNetwork(str(network)) - except: - syslog.syslog( - syslog.LOG_WARNING, - 'Subnet {} format is wrong for interface {}'.format( - network, - interface - ) - ) - return False - ip = str(network.ip) - self.directory.remove("local_addresses", ip) + """ + '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(key) else: - self.directory.remove("interfaces", key) + log_err("Peer '(%s|%s)' hasn't been removed" % (vrf, nbr)) - @staticmethod - def get_local_interface(directory, local_addr): + 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 + return self.cfg_mgr.push(cmd) + + def get_lo0_ipv4(self): + """ + Extract Loopback0 ipv4 address from the Directory + :return: ipv4 address for Loopback0, None if nothing found """ - @summary: Get interface according to the local address from the directory - @param directory: Directory object that stored metadata of interfaces - @param local_addr: Local address of the interface - @return: Return the metadata of the interface with the local address + loopback0_ipv4 = None + for loopback in self.directory.get_slot("CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME).iterkeys(): + 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 = directory.get_slot("local_addresses") + 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 = directory.get_slot("interfaces") + interfaces = self.directory.get_slot("LOCAL", "interfaces") # Check if the information for the interface of this local address has been set if local_address.has_key("interface") and local_address["interface"] in interfaces: return interfaces[local_address["interface"]] @@ -503,9 +937,9 @@ class InterfaceMgr(Manager): @staticmethod def get_vnet(interface): """ - @summary: Get the VNet name of the interface - @param interface: The metadata of the interface - @return: Return the vnet name of the interface if this interface belongs to a vnet, + Get the VNet name of the interface + :param: interface: The metadata of the interface + :return: Return the vnet name of the interface if this interface belongs to a vnet, Otherwise return None """ if interface.has_key("vnet_name") and interface["vnet_name"]: @@ -513,65 +947,166 @@ class InterfaceMgr(Manager): 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)) -class LoopbackInterfaceMgr(InterfaceMgr): - def __init__(self, daemon, directory): - super(LoopbackInterfaceMgr, self).__init__( - daemon, - directory, - swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME - ) - + @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))) -class VlanInterfaceMgr(InterfaceMgr): - def __init__(self, daemon, directory): - super(VlanInterfaceMgr, self).__init__( - daemon, - directory, - swsscommon.CFG_VLAN_INTF_TABLE_NAME - ) + return peers -class PortChannelInterfaceMgr(InterfaceMgr): - def __init__(self, daemon, directory): - super(PortChannelInterfaceMgr, self).__init__( - daemon, - directory, - swsscommon.CFG_LAG_INTF_TABLE_NAME +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 address: '%s'" % ip_addr_w_mask) + return True + ip_addr = ip_addr_w_mask[:slash_pos] + try: + if TemplateFabric.is_ipv4(ip_addr) and 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="") + elif TemplateFabric.is_ipv6(ip_addr) and 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_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 + if self.cfg_mgr.push(txt): + log_info("The 'set src' configuration with Loopback0 ip '%s' was pushed" % ip_addr) + else: + log_err("The 'set src' configuration with Loopback0 ip '%s' wasn't pushed" % ip_addr) + return True -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())) + 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") + + +def wait_for_daemons(daemons, seconds): + """ + Wait until FRR daemons are ready for requests + :param daemons: list of FRR daemons to wait + :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: - 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())) + 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 daemons): + log_info("All required daemons have 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") + 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) + + +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) + 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"] def main(): + """ Main function """ + wait_for_daemons(["bgpd", "zebra", "staticd"], seconds=20) + # + common_objs = { + 'directory': Directory(), + 'cfg_mgr': ConfigMgr(), + 'tf': TemplateFabric(), + 'constants': read_constants(), + } managers = [ - BGPDeviceMetaMgr, - BGPNeighborMetaMgr, - BGPPeerMgr, - InterfaceMgr, - LoopbackInterfaceMgr, - VlanInterfaceMgr, - PortChannelInterfaceMgr, + # 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"), + BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_MONITORS", "monitors"), + BGPPeerMgrBase(common_objs, "CONFIG_DB", "BGP_PEER_RANGE", "dynamic"), ] - wait_for_bgpd() - daemon = Daemon() - directory = Directory() - manager_instanses = [ manager(daemon, directory) for manager in managers ] - daemon.run() + runner = Runner() + for mgr in managers: + runner.add_manager(mgr) + runner.run() -def signal_handler(signum, frame): +def signal_handler(_, __): # signal_handler(signum, frame) + """ signal handler """ global g_run g_run = False @@ -584,13 +1119,17 @@ if __name__ == '__main__': 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)) + log_notice("Keyboard interrupt") + except RuntimeError as exc: + log_crit(str(exc)) rc = -2 - except Exception as e: - syslog.syslog(syslog.LOG_CRIT, "Got an exception %s: Traceback: %s" % (str(e), traceback.format_exc())) + 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: 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 2bf80b80a787..000000000000 --- a/dockers/docker-fpm-frr/bgpd.conf.default.j2 +++ /dev/null @@ -1,180 +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 DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} -route-map HIDE_INTERNAL permit 10 - set community local-AS -! -{% endif %} -{% if DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} -route-map OVERRIDE_ORIGINATOR_ID permit 10 -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if prefix | ipv4 and name == 'Loopback0' %} - set originator-id {{ prefix | ip }} -{% endif %} -{% endfor %} -! -{% endif %} -{% if BGP_MONITORS is defined and BGP_MONITORS|length > 0 %} -route-map FROM_BGPMON deny 10 -! -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'] }} -{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} - redistribute connected route-map HIDE_INTERNAL -{% endif %} - bgp log-neighbor-changes - bgp bestpath as-path multipath-relax - no bgp default ipv4-unicast - 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 -{% if DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} - neighbor {{ neighbor_addr }} route-map OVERRIDE_ORIGINATOR_ID in -{% endif %} - address-family ipv6 - neighbor {{ neighbor_addr }} activate - exit-address-family -{% endfor %} -{% endif %} -{% endblock bgp_monitors %} -! 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/start.sh b/dockers/docker-fpm-frr/docker_init.sh similarity index 57% rename from dockers/docker-fpm-frr/start.sh rename to dockers/docker-fpm-frr/docker_init.sh index b3cef5e63244..a4db7d3cf3c6 100755 --- a/dockers/docker-fpm-frr/start.sh +++ b/dockers/docker-fpm-frr/docker_init.sh @@ -1,13 +1,15 @@ #!/usr/bin/env bash mkdir -p /etc/frr +mkdir -p /etc/supervisor/conf.d -CONFIG_TYPE=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["docker_routing_config_mode"]'` +sonic-cfggen -d -t /usr/share/sonic/templates/supervisord/supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf +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 + sonic-cfggen -d -t /usr/share/sonic/templates/bgpd/bgpd.conf.j2 -y /etc/sonic/constants.yml > /etc/frr/bgpd.conf + sonic-cfggen -d -t /usr/share/sonic/templates/zebra/zebra.conf.j2 > /etc/frr/zebra.conf + sonic-cfggen -d -t /usr/share/sonic/templates/staticd/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 @@ -29,24 +31,4 @@ 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 +exec /usr/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/bgpd.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.conf.j2 similarity index 50% rename from dockers/docker-fpm-frr/bgpd.conf.j2 rename to dockers/docker-fpm-frr/frr/bgpd/bgpd.conf.j2 index b4b2cd59c9b9..85182e5430e8 100644 --- a/dockers/docker-fpm-frr/bgpd.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.conf.j2 @@ -1,4 +1,8 @@ ! +! 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 @@ -6,13 +10,15 @@ ! {% endblock banner %} ! -{% include "daemons.common.conf.j2" %} +{% include "common/daemons.common.conf.j2" %} ! agentx ! {% if DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" %} -{% include "bgpd.conf.spine_chassis_frontend_router.j2" %} +{% include "bgpd.spine_chassis_frontend_router.conf.j2" %} {% endif %} ! -{% include "bgpd.conf.default.j2" %} +{% 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..051cfa4e9dd9 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 @@ -0,0 +1,86 @@ +! +! 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 DEVICE_METADATA['localhost']['sub_role'] == 'FrontEnd' %} +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 +! +{% 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 #} + bgp router-id {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }} +! +{# advertise loopback #} + network {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/32 +! +{% 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 %} +{% endblock bgp_init %} +! +{% 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 %} +! +! +{% 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/bgpd.conf.spine_chassis_frontend_router.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.spine_chassis_frontend_router.conf.j2 similarity index 100% rename from dockers/docker-fpm-frr/bgpd.conf.spine_chassis_frontend_router.j2 rename to dockers/docker-fpm-frr/frr/bgpd/bgpd.spine_chassis_frontend_router.conf.j2 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..efb1546dac4b --- /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/BGP_SPEAKER/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/bgpd.peer.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 old mode 100755 new mode 100644 similarity index 55% rename from dockers/docker-fpm-frr/bgpd.peer.conf.j2 rename to dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 index bcc520f6b2df..aed32d291c76 --- a/dockers/docker-fpm-frr/bgpd.peer.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/instance.conf.j2 @@ -1,4 +1,6 @@ -{% block bgp_peer %} +! +! 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 #} @@ -6,27 +8,45 @@ 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 bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and CONFIG_DB__DEVICE_METADATA['localhost'].has_key('default_bgp_status') and CONFIG_DB__DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} neighbor {{ neighbor_addr }} shutdown {% endif %} +! {% if neighbor_addr | ipv4 %} address-family ipv4 +{% if 'ASIC' in bgp_session['name'] %} + neighbor {{ neighbor_addr }} peer-group PEER_V4_INT +{% else %} neighbor {{ neighbor_addr }} peer-group PEER_V4 +{% endif %} +{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} + neighbor {{ neighbor_addr }} route-map FROM_BGP_PEER_V4_INT in +{% endif %} {% 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 %} +{% if 'ASIC' in bgp_session['name'] %} + neighbor {{ neighbor_addr }} peer-group PEER_V6_INT +{% else %} neighbor {{ neighbor_addr }} peer-group PEER_V6 +{% endif %} +{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} + neighbor {{ neighbor_addr }} route-map FROM_BGP_PEER_V6_INT in +{% endif %} {% 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" %} +{% if 'ASIC' in bgp_session['name'] %} + neighbor {{ neighbor_addr }} next-hop-self force +{% endif %} +! +{% 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 @@ -34,4 +54,6 @@ {% endif %} neighbor {{ neighbor_addr }} activate exit-address-family -{% endblock bgp_peer %} +! +! 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..b0acd1b2a460 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/peer-group.conf.j2 @@ -0,0 +1,40 @@ +! +! template: bgpd/templates/general/peer-group.conf.j2 +! + neighbor PEER_V4 peer-group + neighbor PEER_V4_INT peer-group + neighbor PEER_V6 peer-group + neighbor PEER_V6_INT peer-group + address-family ipv4 +{% if CONFIG_DB__DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} + neighbor PEER_V4 allowas-in 1 + neighbor PEER_V4_INT allowas-in 1 +{% endif %} +{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} + neighbor PEER_V4_INT route-reflector-client +{% 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 + neighbor PEER_V4_INT soft-reconfiguration inbound + neighbor PEER_V4_INT route-map FROM_BGP_PEER_V4 in + neighbor PEER_V4_INT 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 + neighbor PEER_V6_INT allowas-in 1 + {% endif %} +{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} + neighbor PEER_V6_INT route-reflector-client +{% 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 + neighbor PEER_V6_INT soft-reconfiguration inbound + neighbor PEER_V6_INT route-map FROM_BGP_PEER_V6 in + neighbor PEER_V6_INT 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..c545cf272892 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/bgpd/templates/general/policies.conf.j2 @@ -0,0 +1,30 @@ +! +! 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 + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_PEER_V6 permit 100 +! +route-map TO_BGP_PEER_V6 permit 100 +! +{% if CONFIG_DB__DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} +route-map FROM_BGP_PEER_V4_INT permit 2 + set originator-id {{ loopback0_ipv4 | ip }} +! +route-map FROM_BGP_PEER_V6_INT permit 1 + set ipv6 next-hop prefer-global +! +route-map FROM_BGP_PEER_V6_INT permit 2 + set originator-id {{ loopback0_ipv4 | ip }} +{% endif %} +! +! end of template: bgpd/templates/general/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..88b1c5acb2eb --- /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 2 + match ip address prefix-list PL_Loopback{{ ip_version }} + set community {{ constants.bgp.traffic_shift_community }} +route-map {{ route_map_name }} deny 3 +! 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..22244b3ac883 --- /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 2 +no route-map {{ route_map_name }} deny 3 +! diff --git a/dockers/docker-fpm-frr/daemons.common.conf.j2 b/dockers/docker-fpm-frr/frr/common/daemons.common.conf.j2 similarity index 71% rename from dockers/docker-fpm-frr/daemons.common.conf.j2 rename to dockers/docker-fpm-frr/frr/common/daemons.common.conf.j2 index 23eb5184f5e0..1c3efdfa72fb 100644 --- a/dockers/docker-fpm-frr/daemons.common.conf.j2 +++ b/dockers/docker-fpm-frr/frr/common/daemons.common.conf.j2 @@ -1,3 +1,4 @@ +! template: common/daemons.common.conf.j2 ! {% block sys_init %} hostname {{ DEVICE_METADATA['localhost']['hostname'] }} @@ -10,3 +11,4 @@ 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..9857f068fe93 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/common/functions.conf.j2 @@ -0,0 +1,23 @@ +{% 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 %} 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..9e5def4ba013 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/frr.conf.j2 @@ -0,0 +1,19 @@ +! +{% 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 "bgpd/bgpd.main.conf.j2" %} +! 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/staticd.conf.j2 b/dockers/docker-fpm-frr/frr/staticd/staticd.conf.j2 similarity index 85% rename from dockers/docker-fpm-frr/staticd.conf.j2 rename to dockers/docker-fpm-frr/frr/staticd/staticd.conf.j2 index 4e39e17d7dbf..932871dfce4b 100644 --- a/dockers/docker-fpm-frr/staticd.conf.j2 +++ b/dockers/docker-fpm-frr/frr/staticd/staticd.conf.j2 @@ -6,7 +6,7 @@ ! {% endblock banner %} ! -{% include "daemons.common.conf.j2" %} +{% include "common/daemons.common.conf.j2" %} ! {% include "staticd.default_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/supervisord.conf b/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 similarity index 60% rename from dockers/docker-fpm-frr/supervisord.conf rename to dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 index 3e544b64b296..31af4bad43e3 100644 --- a/dockers/docker-fpm-frr/supervisord.conf +++ b/dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2 @@ -3,38 +3,29 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -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 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 +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 @@ -44,6 +35,8 @@ autorestart=false startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:staticd] command=/usr/lib/frr/staticd -A 127.0.0.1 @@ -53,6 +46,8 @@ autorestart=false startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running [program:bgpd] command=/usr/lib/frr/bgpd -A 127.0.0.1 -M snmp @@ -63,25 +58,45 @@ autorestart=false startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running -[program:vtysh_b] -command=/usr/bin/vtysh -b +[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 -[program:fpmsyncd] -command=fpmsyncd +[program:bgpcfgd] +command=/usr/bin/bgpcfgd +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.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=rsyslogd: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 @@ -91,3 +106,6 @@ startsecs=0 startretries=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd: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/zebra.conf.j2 b/dockers/docker-fpm-frr/frr/zebra/zebra.conf.j2 similarity index 63% rename from dockers/docker-fpm-frr/zebra.conf.j2 rename to dockers/docker-fpm-frr/frr/zebra/zebra.conf.j2 index 8c1c6f96484b..51d998e90d36 100644 --- a/dockers/docker-fpm-frr/zebra.conf.j2 +++ b/dockers/docker-fpm-frr/frr/zebra/zebra.conf.j2 @@ -1,12 +1,12 @@ ! {% block banner %} ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/quagga/zebra.conf.j2 using config DB data +! generated by templates/zebra/zebra.conf.j2 using config DB data ! file: zebra.conf ! {% endblock banner %} ! -{% include "daemons.common.conf.j2" %} +{% 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..484efeba5850 --- /dev/null +++ b/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 @@ -0,0 +1,25 @@ +! +{% 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 %} +! 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/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-iccpd/Dockerfile.j2 b/dockers/docker-iccpd/Dockerfile.j2 index 3c7e01ed54e9..3424c0e97fc9 100644 --- a/dockers/docker-iccpd/Dockerfile.j2 +++ b/dockers/docker-iccpd/Dockerfile.j2 @@ -9,7 +9,6 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ apt-get install -y ebtables -RUN apt-get -y install -f kmod COPY \ {% for deb in docker_iccpd_debs.split(' ') -%} diff --git a/dockers/docker-iccpd/start.sh b/dockers/docker-iccpd/start.sh index d17634cb836a..f2e9807f314f 100644 --- a/dockers/docker-iccpd/start.sh +++ b/dockers/docker-iccpd/start.sh @@ -10,9 +10,3 @@ sonic-cfggen -d -t /usr/share/sonic/templates/iccpd.j2 > $ICCPD_CONF_PATH/iccpd. 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 iccpd diff --git a/dockers/docker-iccpd/supervisord.conf b/dockers/docker-iccpd/supervisord.conf index dc71f07c6c30..38d1ee56e643 100644 --- a/dockers/docker-iccpd/supervisord.conf +++ b/dockers/docker-iccpd/supervisord.conf @@ -3,21 +3,33 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true -[program:start.sh] -command=/usr/bin/start.sh -priority=1 +[eventlistener:dependent-startup] +command=python -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: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:iccpd] command=/usr/bin/iccpd.sh @@ -26,4 +38,5 @@ 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/Dockerfile.j2 similarity index 67% rename from dockers/docker-lldp-sv2/Dockerfile.j2 rename to dockers/docker-lldp/Dockerfile.j2 index 6a720514ef9b..6024e844f1e0 100644 --- a/dockers/docker-lldp-sv2/Dockerfile.j2 +++ b/dockers/docker-lldp/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,20 +10,20 @@ ENV DEBIAN_FRONTEND=noninteractive # Update apt's cache of available packages RUN apt-get update -{% if docker_lldp_sv2_debs.strip() -%} +{% if docker_lldp_debs.strip() -%} # Copy locally-built Debian package dependencies -{{ copy_files("debs/", docker_lldp_sv2_debs.split(' '), "/debs/") }} +{{ copy_files("debs/", docker_lldp_debs.split(' '), "/debs/") }} # Install locally-built Debian packages and implicitly install their dependencies -{{ install_debian_packages(docker_lldp_sv2_debs.split(' ')) }} +{{ install_debian_packages(docker_lldp_debs.split(' ')) }} {%- endif %} -{% if docker_lldp_sv2_whls.strip() -%} +{% if docker_lldp_whls.strip() -%} # Copy locally-built Python wheel dependencies -{{ copy_files("python-wheels/", docker_lldp_sv2_whls.split(' '), "/python-wheels/") }} +{{ copy_files("python-wheels/", docker_lldp_whls.split(' '), "/python-wheels/") }} # Install locally-built Python wheel dependencies -{{ install_python_wheels(docker_lldp_sv2_whls.split(' ')) }} +{{ install_python_wheels(docker_lldp_whls.split(' ')) }} {% endif %} # Clean up @@ -35,12 +35,14 @@ RUN apt-get purge -y python-pip && \ /python-wheels \ ~/.cache +COPY ["docker-lldp-init.sh", "/usr/bin/"] COPY ["start.sh", "/usr/bin/"] -COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["waitfor_lldp_ready.sh", "/usr/bin/"] +COPY ["supervisord.conf.j2", "/usr/share/sonic/templates/"] 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"] +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 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-sv2/base_image_files/monit_lldp b/dockers/docker-lldp/base_image_files/monit_lldp similarity index 100% rename from dockers/docker-lldp-sv2/base_image_files/monit_lldp rename to dockers/docker-lldp/base_image_files/monit_lldp diff --git a/dockers/docker-lldp-sv2/critical_processes b/dockers/docker-lldp/critical_processes similarity index 100% rename from dockers/docker-lldp-sv2/critical_processes rename to dockers/docker-lldp/critical_processes diff --git a/dockers/docker-lldp/docker-lldp-init.sh b/dockers/docker-lldp/docker-lldp-init.sh new file mode 100755 index 000000000000..ae507e8f506a --- /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/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-sv2/lldpd.conf.j2 b/dockers/docker-lldp/lldpd.conf.j2 similarity index 100% rename from dockers/docker-lldp-sv2/lldpd.conf.j2 rename to dockers/docker-lldp/lldpd.conf.j2 diff --git a/dockers/docker-lldp-sv2/lldpmgrd b/dockers/docker-lldp/lldpmgrd similarity index 96% rename from dockers/docker-lldp-sv2/lldpmgrd rename to dockers/docker-lldp/lldpmgrd index 7e9ef1642a06..a0dff5d402f8 100755 --- a/dockers/docker-lldp-sv2/lldpmgrd +++ b/dockers/docker-lldp/lldpmgrd @@ -119,7 +119,11 @@ class LldpManager(object): else: return False else: - log_error("Port '{}' not found in {} table in App DB".format(port_name, swsscommon.APP_PORT_TABLE_NAME)) + # 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: + 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): diff --git a/dockers/docker-lldp/start.sh b/dockers/docker-lldp/start.sh new file mode 100755 index 000000000000..5cb6042cee58 --- /dev/null +++ b/dockers/docker-lldp/start.sh @@ -0,0 +1,8 @@ +#!/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/lldpd.socket diff --git a/dockers/docker-lldp-sv2/supervisord.conf b/dockers/docker-lldp/supervisord.conf.j2 similarity index 56% rename from dockers/docker-lldp-sv2/supervisord.conf rename to dockers/docker-lldp/supervisord.conf.j2 index 73ff52f4420e..776dcd029621 100644 --- a/dockers/docker-lldp-sv2/supervisord.conf +++ b/dockers/docker-lldp/supervisord.conf.j2 @@ -3,27 +3,39 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -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 lldp events=PROCESS_STATE_EXITED 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:lldpd] # https://github.com/vincentbernat/lldpd/commit/9856f2792c301116cc4a3fcfba91b9672ee5db1f @@ -31,12 +43,29 @@ stderr_logfile=syslog # - `-dd` means to stay in foreground, log warnings to console # - `-ddd` means to stay in foreground, log warnings and info to console # - `-dddd` means to stay in foreground, log all to console +{% 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 python2 -m lldp_syncd @@ -45,6 +74,8 @@ 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 @@ -53,3 +84,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-sv2/start.sh b/dockers/docker-lldp/waitfor_lldp_ready.sh similarity index 63% rename from dockers/docker-lldp-sv2/start.sh rename to dockers/docker-lldp/waitfor_lldp_ready.sh index 76666e77aca2..ecb16dc2e5f0 100755 --- a/dockers/docker-lldp-sv2/start.sh +++ b/dockers/docker-lldp/waitfor_lldp_ready.sh @@ -1,15 +1,4 @@ -#!/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 +#!/bin/bash # Current lldpd version has a bug. # When lldpd starts it is in the pause state by default @@ -33,6 +22,3 @@ 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-nat/restore_nat_entries.py b/dockers/docker-nat/restore_nat_entries.py index 9fb62e82f573..d07facab290b 100755 --- a/dockers/docker-nat/restore_nat_entries.py +++ b/dockers/docker-nat/restore_nat_entries.py @@ -24,7 +24,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) @@ -44,7 +43,7 @@ def add_nat_conntrack_entry_in_kernel(ipproto, srcip, dstip, srcport, dstport, n # 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) 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..a6fb78aa1bc1 100644 --- a/dockers/docker-nat/supervisord.conf +++ b/dockers/docker-nat/supervisord.conf @@ -3,27 +3,39 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -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 nat events=PROCESS_STATE_EXITED 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 +44,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 +54,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 +66,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 43c9d5896f34..d08ecdb49d48 100755 --- a/dockers/docker-orchagent/Dockerfile.j2 +++ b/dockers/docker-orchagent/Dockerfile.j2 @@ -59,8 +59,9 @@ RUN apt-get clean -y && \ rm -rf /debs COPY ["files/arp_update", "/usr/bin"] +COPY ["arp_update.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", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["critical_processes", "/etc/supervisor/"] @@ -68,4 +69,4 @@ COPY ["critical_processes", "/etc/supervisor/"] ## 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/start.sh b/dockers/docker-orchagent/docker-init.sh similarity index 52% rename from dockers/docker-orchagent/start.sh rename to dockers/docker-orchagent/docker-init.sh index b7357ad58f67..82ae41b117bf 100755 --- a/dockers/docker-orchagent/start.sh +++ b/dockers/docker-orchagent/docker-init.sh @@ -11,40 +11,10 @@ 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 + cp /usr/share/sonic/templates/arp_update.conf /etc/supervisord/conf.d/ fi + +exec /usr/bin/supervisord diff --git a/dockers/docker-orchagent/enable_counters.py b/dockers/docker-orchagent/enable_counters.py index 75f8ef82cb4c..b2ec4b85a202 100755 --- a/dockers/docker-orchagent/enable_counters.py +++ b/dockers/docker-orchagent/enable_counters.py @@ -12,6 +12,7 @@ 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') diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh index 3352e5fbb7ec..917205f3ebf2 100755 --- a/dockers/docker-orchagent/orchagent.sh +++ b/dockers/docker-orchagent/orchagent.sh @@ -17,6 +17,22 @@ ORCHAGENT_ARGS="-d /var/log/swss " # Set orchagent pop batch size to 8192 ORCHAGENT_ARGS+="-b 8192 " +# 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=`sonic-cfggen -d -v DEVICE_METADATA.localhost.asic_id` +if [ -n "$asic_id" ] +then + ORCHAGENT_ARGS+="-i $asic_id " +fi + # Add platform specific arguments if necessary if [ "$platform" == "broadcom" ]; then ORCHAGENT_ARGS+="-m $MAC_ADDRESS" @@ -25,10 +41,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 diff --git a/dockers/docker-orchagent/supervisord.conf b/dockers/docker-orchagent/supervisord.conf index 6b21d73f3c81..cefbce98c64a 100644 --- a/dockers/docker-orchagent/supervisord.conf +++ b/dockers/docker-orchagent/supervisord.conf @@ -3,27 +3,28 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -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 swss 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 +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 @@ -32,22 +33,20 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running -[program:portsyncd] -command=/usr/bin/portsyncd +[program:restore_neighbors] +command=/usr/bin/restore_neighbors.py priority=4 autostart=false autorestart=false +startsecs=0 +startretries=0 stdout_logfile=syslog stderr_logfile=syslog - -[program:neighsyncd] -command=/usr/bin/neighsyncd -priority=5 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=orchagent:running [program:swssconfig] command=/usr/bin/swssconfig.sh @@ -58,14 +57,28 @@ startretries=0 startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=orchagent:running -[program:arp_update] -command=/usr/bin/arp_update -priority=7 +[program:portsyncd] +command=/usr/bin/portsyncd +priority=4 autostart=false -autorestart=unexpected +autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited + +[program:neighsyncd] +command=/usr/bin/neighsyncd +priority=5 +autostart=false +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 +87,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 +97,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,6 +107,8 @@ 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 @@ -98,14 +117,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog - -[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:vrfmgrd] command=/usr/bin/vrfmgrd @@ -114,16 +127,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog - -[program:restore_neighbors] -command=/usr/bin/restore_neighbors.py -priority=14 -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 @@ -132,6 +137,8 @@ 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 @@ -140,3 +147,15 @@ 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 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=swssconfig:exited diff --git a/dockers/docker-platform-monitor/Dockerfile.j2 b/dockers/docker-platform-monitor/Dockerfile.j2 index 4f5f2b77141b..b167dea0085e 100755 --- a/dockers/docker-platform-monitor/Dockerfile.j2 +++ b/dockers/docker-platform-monitor/Dockerfile.j2 @@ -17,7 +17,9 @@ RUN apt-get update && \ rrdtool \ python-smbus \ ethtool \ - dmidecode + dmidecode \ + i2c-tools && \ + pip install enum34 {% if docker_platform_monitor_debs.strip() -%} # Copy locally-built Debian package dependencies @@ -53,8 +55,8 @@ RUN apt-get purge -y \ /python-wheels \ ~/.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_init.sh", "lm-sensors.sh", "start.sh", "/usr/bin/"] +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 788ba53f3ec4..9798dffc4c27 100644 --- a/dockers/docker-platform-monitor/critical_processes +++ b/dockers/docker-platform-monitor/critical_processes @@ -1,4 +1,3 @@ ledd xcvrd psud -syseepromd diff --git a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 index 21b508ab8f05..a002d2bded83 100644 --- a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 +++ b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 @@ -3,29 +3,41 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -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 pmon events=PROCESS_STATE_EXITED 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 +[program:start] +command=/usr/bin/start.sh priority=2 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +startsecs=0 +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running +{% if not skip_sensors and HAVE_SENSORS_CONF == 1 %} [program:lm-sensors] command=/usr/bin/lm-sensors.sh priority=3 @@ -34,7 +46,11 @@ autorestart=false stdout_logfile=syslog stderr_logfile=syslog startsecs=0 +dependent_startup=true +dependent_startup_wait_for=start:exited +{% endif %} +{% if not skip_fancontrol and HAVE_FANCONTROL_CONF == 1 %} [program:fancontrol] command=/usr/sbin/fancontrol priority=4 @@ -43,6 +59,9 @@ autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog startsecs=10 +dependent_startup=true +dependent_startup_wait_for=start:exited +{% endif %} {% if not skip_ledd %} [program:ledd] @@ -53,6 +72,8 @@ autorestart=false stdout_logfile=syslog stderr_logfile=syslog startsecs=0 +dependent_startup=true +dependent_startup_wait_for=start:exited {% endif %} {% if not skip_xcvrd %} @@ -64,6 +85,8 @@ autorestart=false stdout_logfile=syslog stderr_logfile=syslog startsecs=0 +dependent_startup=true +dependent_startup_wait_for=start:exited {% endif %} {% if not skip_psud %} @@ -75,6 +98,8 @@ autorestart=false stdout_logfile=syslog stderr_logfile=syslog startsecs=0 +dependent_startup=true +dependent_startup_wait_for=start:exited {% endif %} {% if not skip_syseepromd %} @@ -82,10 +107,12 @@ startsecs=0 command=/usr/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=start:exited {% endif %} {% if not skip_thermalctld %} @@ -93,8 +120,10 @@ startsecs=0 command=/usr/bin/thermalctld priority=9 autostart=false -autorestart=true +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog -startsecs=0 +startsecs=10 +dependent_startup=true +dependent_startup_wait_for=start:exited {% endif %} diff --git a/dockers/docker-platform-monitor/docker_init.sh b/dockers/docker-platform-monitor/docker_init.sh index a2be49f49dd3..3485c6e9767a 100755 --- a/dockers/docker-platform-monitor/docker_init.sh +++ b/dockers/docker-platform-monitor/docker_init.sh @@ -3,16 +3,40 @@ # 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 ]; + +HAVE_SENSORS_CONF=0 +HAVE_FANCONTROL_CONF=0 + +if [ -e /usr/share/sonic/platform/sensors.conf ]; then + HAVE_SENSORS_CONF=1 +fi + +if [ -e /usr/share/sonic/platform/fancontrol ]; then + HAVE_FANCONTROL_CONF=1 +fi + +confvar="{\"HAVE_SENSORS_CONF\":$HAVE_SENSORS_CONF, \"HAVE_FANCONTROL_CONF\":$HAVE_FANCONTROL_CONF}" + +if [ -e /usr/share/sonic/platform/pmon_daemon_control.json ]; 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 + sonic-cfggen -j /usr/share/sonic/platform/pmon_daemon_control.json -a "$confvar" -t /usr/share/sonic/templates/docker-pmon.supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf 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-cfggen -a "$confvar" -t /usr/share/sonic/templates/docker-pmon.supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf fi -exec /usr/bin/supervisord +# If this platform has an lm-sensors config file, copy it to it's proper place. +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/ +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/templates/fancontrol.conf /etc/supervisord/conf.d/ +fi + +exec /usr/bin/supervisord diff --git a/dockers/docker-platform-monitor/start.sh.j2 b/dockers/docker-platform-monitor/start.sh old mode 100644 new mode 100755 similarity index 51% rename from dockers/docker-platform-monitor/start.sh.j2 rename to dockers/docker-platform-monitor/start.sh index a72f4fa8eb85..58e481476b93 --- a/dockers/docker-platform-monitor/start.sh.j2 +++ b/dockers/docker-platform-monitor/start.sh @@ -5,10 +5,6 @@ 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 @@ -19,25 +15,6 @@ if [ -e /usr/share/sonic/platform/platform_wait ]; then 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 @@ -54,24 +31,3 @@ if [ $? -ne 0 ]; then 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/Dockerfile.j2 b/dockers/docker-ptf/Dockerfile.j2 index 8d529779ccdb..c9f7be803a20 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 \ @@ -64,7 +63,9 @@ RUN sed --in-place 's/httpredir.debian.org/debian-archive.trafficmanager.net/' / rsyslog \ ntp \ ntpstat \ - ntpdate + ntpdate \ + arping \ + bridge-utils RUN dpkg -i \ {% for deb in docker_ptf_debs.split(' ') -%} @@ -72,6 +73,7 @@ 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 \ @@ -115,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 @@ -126,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 @@ -135,6 +139,6 @@ RUN ln -s /usr/bin/tcpdump /usr/sbin/tcpdump RUN mkdir -p /var/log/supervisor -EXPOSE 22 +EXPOSE 22 8009 ENTRYPOINT ["/usr/local/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"] 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/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..7f57ade4fade 100644 --- a/dockers/docker-router-advertiser/Dockerfile.j2 +++ b/dockers/docker-router-advertiser/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 @@ -24,10 +24,9 @@ RUN apt-get clean -y && \ apt-get autoremove -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_intf.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/docker-init.sh b/dockers/docker-router-advertiser/docker-init.sh new file mode 100755 index 000000000000..f93544e7cb64 --- /dev/null +++ b/dockers/docker-router-advertiser/docker-init.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +mkdir -p /etc/supervisor/conf.d +sonic-cfggen -d -t /usr/share/sonic/templates/docker-router-advertiser.supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf + +# Generate /etc/radvd.conf config file +sonic-cfggen -d -t /usr/share/sonic/templates/radvd.conf.j2 > /etc/radvd.conf + +# 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 + +exec /usr/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..146e7c1b67db --- /dev/null +++ b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf.j2 @@ -0,0 +1,65 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE + +[eventlistener:supervisor-proc-exit-script] +command=/usr/bin/supervisor-proc-exit-listener --container-name radv +events=PROCESS_STATE_EXITED +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 + +{# Router advertiser should only run on ToR (T0) devices #} +{% if DEVICE_METADATA.localhost.type == "ToRRouter" %} + + {% if VLAN_INTERFACE %} + {% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} + {# If this VLAN has an IPv6 address... #} + {% if prefix | ipv6 %} + {% set ipv6_found = true %} + {% endif %} + {% endfor %} + {% endif %} + + {# Enusre at least one ipv6 vlan interface #} + {% if ipv6_found == true %} +[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=rsyslogd:running + +[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 %} + +{% endif %} diff --git a/dockers/docker-router-advertiser/start.sh b/dockers/docker-router-advertiser/start.sh deleted file mode 100755 index 8d5f73a8bcb0..000000000000 --- a/dockers/docker-router-advertiser/start.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env 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 -fi - -# Generate /etc/radvd.conf config file -sonic-cfggen -d -t /usr/share/sonic/templates/radvd.conf.j2 > /etc/radvd.conf - -# Enusre at least one interface is specified in radvd.conf -NUM_IFACES=$(grep -c "^interface " /etc/radvd.conf) -if [ $NUM_IFACES -eq 0 ]; then - echo "No interfaces specified in radvd.conf. Not starting router advertiser process." - exit 0 -fi - -# 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-sflow/Dockerfile.j2 b/dockers/docker-sflow/Dockerfile.j2 index 75da64e02e4d..f532a4040e07 100644 --- a/dockers/docker-sflow/Dockerfile.j2 +++ b/dockers/docker-sflow/Dockerfile.j2 @@ -27,7 +27,6 @@ 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"] 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..3605e50318dc 100644 --- a/dockers/docker-sflow/supervisord.conf +++ b/dockers/docker-sflow/supervisord.conf @@ -3,32 +3,35 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -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 sflow 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 +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true [program:sflowmgrd] command=/usr/bin/sflowmgrd -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/dockers/docker-snmp-sv2/Dockerfile.j2 b/dockers/docker-snmp/Dockerfile.j2 similarity index 56% rename from dockers/docker-snmp-sv2/Dockerfile.j2 rename to dockers/docker-snmp/Dockerfile.j2 index b62ff61eaf95..213d941c58f6 100644 --- a/dockers/docker-snmp-sv2/Dockerfile.j2 +++ b/dockers/docker-snmp/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 "dockers/dockerfile-macros.j2" import install_debian_packages, install_python3_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 @@ -11,30 +11,24 @@ ENV PYTHONOPTIMIZE 1 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 +# Install make/gcc which is required for installing hiredis RUN apt-get update && \ apt-get install -y \ - curl \ - ca-certificates \ + python3-dev \ gcc \ make \ - libdpkg-perl \ ipmitool -{% if docker_snmp_sv2_debs.strip() -%} +{% if docker_snmp_debs.strip() -%} # Copy locally-built Debian package dependencies -{{ copy_files("debs/", docker_snmp_sv2_debs.split(' '), "/debs/") }} +{{ copy_files("debs/", docker_snmp_debs.split(' '), "/debs/") }} # Install locally-built Debian packages and implicitly install their dependencies -{{ install_debian_packages(docker_snmp_sv2_debs.split(' ')) }} +{{ install_debian_packages(docker_snmp_debs.split(' ')) }} {%- endif %} # Fix for hiredis compilation issues for ARM -# python will throw for missing locale +# 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 @@ -43,38 +37,30 @@ 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 +RUN pip3 install --no-cache-dir setuptools wheel # 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 \ +RUN python3 -m pip install --no-cache-dir \ hiredis \ pyyaml \ smbus -{% if docker_snmp_sv2_whls.strip() -%} +{% if docker_snmp_whls.strip() -%} # Copy locally-built Python wheel dependencies -{{ copy_files("python-wheels/", docker_snmp_sv2_whls.split(' '), "/python-wheels/") }} +{{ copy_files("python-wheels/", docker_snmp_whls.split(' '), "/python-wheels/") }} # Install locally-built Python wheel dependencies -{{ install_python_wheels(docker_snmp_sv2_whls.split(' ')) }} +{{ install_python3_wheels(docker_snmp_whls.split(' ')) }} {% endif %} -RUN python3.6 -m sonic_ax_impl install +RUN python3 -m sonic_ax_impl install # Clean up RUN apt-get -y purge \ - libpython3.6-dev \ - libpython3.6 \ - curl \ + python3-dev \ 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 && \ + make && \ apt-get clean -y && \ apt-get autoclean -y && \ apt-get autoremove -y --purge && \ diff --git a/dockers/docker-snmp-sv2/base_image_files/monit_snmp b/dockers/docker-snmp/base_image_files/monit_snmp similarity index 76% rename from dockers/docker-snmp-sv2/base_image_files/monit_snmp rename to dockers/docker-snmp/base_image_files/monit_snmp index 811f9d14b3d4..cfb1a2b66831 100644 --- a/dockers/docker-snmp-sv2/base_image_files/monit_snmp +++ b/dockers/docker-snmp/base_image_files/monit_snmp @@ -4,8 +4,8 @@ ## snmpd ## snmpd_subagent ############################################################################### -check process snmpd matching "/usr/sbin/snmpd -f" +check process snmpd matching "/usr/sbin/snmpd\s" if does not exist for 5 times within 5 cycles then alert -check process snmp_subagent matching "python3.6 -m sonic_ax_impl" +check process snmp_subagent matching "python3 -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/critical_processes similarity index 100% rename from dockers/docker-snmp-sv2/critical_processes rename to dockers/docker-snmp/critical_processes diff --git a/dockers/docker-snmp-sv2/snmpd.conf.j2 b/dockers/docker-snmp/snmpd.conf.j2 similarity index 100% rename from dockers/docker-snmp-sv2/snmpd.conf.j2 rename to dockers/docker-snmp/snmpd.conf.j2 diff --git a/dockers/docker-snmp-sv2/start.sh b/dockers/docker-snmp/start.sh similarity index 76% rename from dockers/docker-snmp-sv2/start.sh rename to dockers/docker-snmp/start.sh index 6ec3379df58f..c4929738f9d8 100755 --- a/dockers/docker-snmp-sv2/start.sh +++ b/dockers/docker-snmp/start.sh @@ -8,9 +8,3 @@ sonic-cfggen -d -y /etc/sonic/snmp.yml -t /usr/share/sonic/templates/snmpd.conf. mkdir -p /var/sonic echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status - -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/supervisord.conf similarity index 62% rename from dockers/docker-snmp-sv2/supervisord.conf rename to dockers/docker-snmp/supervisord.conf index 992292330552..2ca3686dcd11 100644 --- a/dockers/docker-snmp-sv2/supervisord.conf +++ b/dockers/docker-snmp/supervisord.conf @@ -3,27 +3,39 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -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 snmp events=PROCESS_STATE_EXITED 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 -priority=2 -autostart=false -autorestart=unexpected +[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 @@ -32,11 +44,15 @@ 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.6 -m sonic_ax_impl +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..37675dbc33ff 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,22 +6,17 @@ 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 apt-get update && \ + apt-get install -y g++ python-dev + 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 - COPY \ {% for deb in docker_sonic_mgmt_framework_debs.split(' ') -%} debs/{{ deb }}{{' '}} @@ -36,6 +31,7 @@ debs/{{ deb }}{{' '}} COPY ["start.sh", "rest-server.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +RUN apt-get remove -y g++ python-dev RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs 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..f78d0ec84121 100644 --- a/dockers/docker-sonic-mgmt-framework/supervisord.conf +++ b/dockers/docker-sonic-mgmt-framework/supervisord.conf @@ -3,21 +3,33 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true -[program:start.sh] -command=/usr/bin/start.sh -priority=1 +[eventlistener:dependent-startup] +command=python -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: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 +38,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 c19cea4b9727..acb4417636ec 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -2,57 +2,67 @@ FROM ubuntu:16.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 \ + libffi-dev \ + libssl-dev \ + libxml2 \ + libxslt1-dev \ + make \ + openssh-server \ + psmisc \ + python \ + python-dev \ + python-scapy \ + python-setuptools \ + rsyslog \ + snmp \ + sshpass \ + sudo \ + tcpdump \ + telnet \ + vim + +RUN easy_install pip==20.1.1 + +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 \ + 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 \ + pycryptodome \ + 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-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 \ @@ -90,9 +100,7 @@ RUN apt-get update \ 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 \ @@ -106,10 +114,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 @@ -121,6 +137,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 @@ -151,5 +168,3 @@ RUN ~/lib/azure-cli/bin/python -m pip install azure-keyvault==0.3.7 -U # Install Virtual Environment RUN python -m virtualenv --system-site-packages env-201811 RUN env-201811/bin/pip install ansible==2.0.0.2 - -RUN git clone https://github.com/Azure/sonic-mgmt diff --git a/dockers/docker-sonic-restapi/Dockerfile.j2 b/dockers/docker-sonic-restapi/Dockerfile.j2 index de8080880fc7..32904531f1fc 100644 --- a/dockers/docker-sonic-restapi/Dockerfile.j2 +++ b/dockers/docker-sonic-restapi/Dockerfile.j2 @@ -20,6 +20,9 @@ RUN apt-get update ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y +COPY ["start.sh", "restapi.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-sonic-restapi/base_image_files/monit_restapi b/dockers/docker-sonic-restapi/base_image_files/monit_restapi new file mode 100644 index 000000000000..2e90baf30d57 --- /dev/null +++ b/dockers/docker-sonic-restapi/base_image_files/monit_restapi @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for restapi container +## process list: +## restapi +############################################################################### +check process restapi matching "/usr/sbin/go-server-server" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-sonic-restapi/critical_processes b/dockers/docker-sonic-restapi/critical_processes new file mode 100644 index 000000000000..3106eaa9410a --- /dev/null +++ b/dockers/docker-sonic-restapi/critical_processes @@ -0,0 +1 @@ +restapi diff --git a/dockers/docker-sonic-restapi/restapi.sh b/dockers/docker-sonic-restapi/restapi.sh new file mode 100755 index 000000000000..d009507a7bc3 --- /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']"` + CLIENT_CA_CRT=`sonic-cfggen -d -v "RESTAPI['certs']['client_ca_crt']"` + CLIENT_CRT_CNAME=`sonic-cfggen -d -v "RESTAPI['certs']['client_crt_cname']"` + if [[ -f $SERVER_CRT && -f $SERVER_KEY && -f $CLIENT_CA_CRT ]]; then + RESTAPI_ARGS+=" -enablehttps=true -servercert=$SERVER_CRT -serverkey=$SERVER_KEY -clientcert=$CLIENT_CA_CRT -clientcertcommonname=$CLIENT_CRT_CNAME" + break + fi + fi + fi + logger "Waiting for certificates..." + sleep 60 +done + +LOG_LEVEL=`sonic-cfggen -d -v "RESTAPI['config']['log_level']"` +if [ ! -z $LOG_LEVEL ]; then + RESTAPI_ARGS+=" -loglevel=$LOG_LEVEL" +else + RESTAPI_ARGS+=" -loglevel=trace" +fi + +logger "RESTAPI_ARGS: $RESTAPI_ARGS" +exec /usr/sbin/go-server-server ${RESTAPI_ARGS} diff --git a/dockers/docker-sonic-restapi/start.sh b/dockers/docker-sonic-restapi/start.sh index 015d246d1200..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..6f907a0ab082 100644 --- a/dockers/docker-sonic-restapi/supervisord.conf +++ b/dockers/docker-sonic-restapi/supervisord.conf @@ -3,10 +3,48 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true -[program:restapi] -command=/usr/sbin/go-server-server -loglevel trace -priority=1 +[eventlistener:dependent-startup] +command=python -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 restapi +events=PROCESS_STATE_EXITED 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 cbc8a1e916fa..d3b95c3b4002 100644 --- a/dockers/docker-sonic-telemetry/Dockerfile.j2 +++ b/dockers/docker-sonic-telemetry/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 diff --git a/dockers/docker-sonic-telemetry/start.sh b/dockers/docker-sonic-telemetry/start.sh index b307e387d557..d6722a27fc77 100755 --- a/dockers/docker-sonic-telemetry/start.sh +++ b/dockers/docker-sonic-telemetry/start.sh @@ -2,10 +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 telemetry -supervisorctl start dialout diff --git a/dockers/docker-sonic-telemetry/supervisord.conf b/dockers/docker-sonic-telemetry/supervisord.conf index 54f4c5b2348d..d968983cddca 100644 --- a/dockers/docker-sonic-telemetry/supervisord.conf +++ b/dockers/docker-sonic-telemetry/supervisord.conf @@ -3,27 +3,39 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -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 telemetry events=PROCESS_STATE_EXITED 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 +44,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 +54,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-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..166b0be0f7dc 100644 --- a/dockers/docker-teamd/supervisord.conf +++ b/dockers/docker-teamd/supervisord.conf @@ -3,27 +3,39 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -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 teamd events=PROCESS_STATE_EXITED 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 +44,16 @@ 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 diff --git a/dockers/dockerfile-macros.j2 b/dockers/dockerfile-macros.j2 index 408ee9fec622..8a4a3ae01411 100644 --- a/dockers/dockerfile-macros.j2 +++ b/dockers/dockerfile-macros.j2 @@ -9,6 +9,10 @@ RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return RUN cd /python-wheels/ && pip install {{ packages | join(' ') }} {%- endmacro %} +{% macro install_python3_wheels(packages) -%} +RUN cd /python-wheels/ && pip3 install {{ packages | join(' ') }} +{%- endmacro %} + {% macro copy_files(prefix, files, dest) -%} COPY \ {%- for file in files %} diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index 3c61c631af93..0ac7d8e12a9d 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -312,6 +312,10 @@ platform_specific() { aboot_machine=arista_7280cr3_32d4 flash_size=7382 fi + if [ "$sid" = "SmartsvilleDDBK" ]; then + aboot_machine=arista_7280cr3k_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 @@ -321,10 +325,14 @@ platform_specific() { echo "iommu=on intel_iommu=on" >>/tmp/append read_system_eeprom fi - if in_array "$platform" "crow" "woodpecker" "magpie"; then + if in_array "$platform" "crow" "magpie"; then echo "amd_iommu=off modprobe.blacklist=snd_hda_intel,hdaudio" >> /tmp/append read_system_eeprom fi + if in_array "$platform" "woodpecker"; then + echo "modprobe.blacklist=snd_hda_intel,hdaudio" >> /tmp/append + read_system_eeprom + fi if [ $flash_size -ge 28000 ]; then varlog_size=4096 @@ -391,6 +399,9 @@ write_boot_configs() { fi fi + # setting secure_boot_enable=y when secure boot enabled + [ -f /bin/securebootctl ] && securebootctl secureboot -display | grep -i "Secure Boot enable" -q && echo "secure_boot_enable=y" >> /tmp/append + mkdir -p "$image_path" cat /tmp/append > $cmdline_image [ -s ${target_path}/machine.conf ] || write_machine_config diff --git a/files/apt/sources.list.amd64 b/files/apt/sources.list.amd64 index 752b1bb4fc60..4a94e3161ab1 100644 --- a/files/apt/sources.list.amd64 +++ b/files/apt/sources.list.amd64 @@ -1,8 +1,8 @@ ## 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 diff --git a/files/apt/sources.list.arm64 b/files/apt/sources.list.arm64 index bbe8fe2e9407..dd82c744de1d 100644 --- a/files/apt/sources.list.arm64 +++ b/files/apt/sources.list.arm64 @@ -1,8 +1,8 @@ ## 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 diff --git a/files/apt/sources.list.armhf b/files/apt/sources.list.armhf index 5dd0c306724b..760906188a94 100644 --- a/files/apt/sources.list.armhf +++ b/files/apt/sources.list.armhf @@ -1,8 +1,8 @@ ## 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 diff --git a/files/build_templates/buffers_config.j2 b/files/build_templates/buffers_config.j2 index a5212d979fcb..ba4dcf49e813 100644 --- a/files/build_templates/buffers_config.j2 +++ b/files/build_templates/buffers_config.j2 @@ -7,7 +7,7 @@ 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' %} {%- set filename_postfix = 't0' %} diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 6067c58f41e9..90a234c009eb 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -64,7 +64,7 @@ function preStartAction() docker cp /tmp/dump.rdb database$DEV:/var/lib/redis/ fi {%- elif docker_container_name == "snmp" %} - sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) + $SONIC_DB_CLI STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) {%- else %} : # nothing {%- endif %} @@ -74,33 +74,40 @@ function postStartAction() { {%- if docker_container_name == "database" %} if [ "$DEV" ]; then + docker exec -i database$DEV sysctl -w net.ipv6.conf.all.disable_ipv6=0 link_namespace $DEV fi + # Wait until redis starts - /usr/bin/docker exec database$DEV ping_pong_db_insts + until [[ $($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-netns-exec "$NET_NS" sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db$DEV.json --write-to-db + $SONIC_CFGGEN -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db$DEV.json --write-to-db else - sonic-netns-exec "$NET_NS" sonic-cfggen -j /etc/sonic/config_db$DEV.json --write-to-db + $SONIC_CFGGEN -j /etc/sonic/config_db$DEV.json --write-to-db fi fi if [[ "$BOOT_TYPE" == "fast" ]]; then # set the key to expire in 3 minutes - /usr/bin/sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180" + $SONIC_DB_CLI STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180" fi - /usr/bin/sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" + $SONIC_DB_CLI CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" fi if [[ -x /usr/bin/db_migrator.py ]]; then # Migrate the DB to the latest schema version if needed - /usr/bin/db_migrator.py -o migrate + if [ -z "$DEV" ]; then + /usr/bin/db_migrator.py -o migrate + fi fi {%- elif docker_container_name == "swss" %} docker exec swss$DEV rm -f /ready # remove cruft @@ -132,14 +139,20 @@ start() { BOOT_TYPE=`getBootType` # Obtain our platform as we will mount directories with these names in each docker - PLATFORM=`sonic-netns-exec "$NET_NS" sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + PLATFORM=`$SONIC_CFGGEN -H -v DEVICE_METADATA.localhost.platform` + + # 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="" {%- else %} # Obtain our HWSKU as we will mount directories with these names in each docker - HWSKU=`sonic-netns-exec "$NET_NS" sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` + HWSKU=`$SONIC_CFGGEN -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` {%- endif %} DOCKERCHECK=`docker inspect --type container {{docker_container_name}}$DEV 2>/dev/null` @@ -168,18 +181,64 @@ start() { {%- if docker_container_name == "database" %} echo "Creating new {{docker_container_name}}$DEV container" + 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.json ]; then + 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.json /etc/sonic/ + mv /etc/sonic/old_config/database_config$DEV.json /etc/sonic/ fi {%- else %} echo "Creating new {{docker_container_name}}$DEV container with HWSKU $HWSKU" {%- 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 [ -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 + {%- 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" {%- else %} @@ -227,6 +286,7 @@ start() { -v /etc/sonic/frr/$DEV:/etc/frr:rw \ {%- endif %} -v /var/run/redis$DEV:/var/run/redis:rw \ + $REDIS_MNT \ -v /usr/share/sonic/device/$PLATFORM:/usr/share/sonic/platform:ro \ {%- if docker_container_name != "database" %} -v /usr/share/sonic/device/$PLATFORM/$HWSKU/$DEV:/usr/share/sonic/hwsku:ro \ @@ -235,6 +295,11 @@ start() { --tmpfs /tmp \ {%- endif %} --tmpfs /var/tmp \ +{%- if docker_container_name == "database" %} + --env "NAMESPACE_ID"="$DEV" \ + --env "NAMESPACE_PREFIX"="$NAMESPACE_PREFIX" \ + --env "NAMESPACE_COUNT"=$NUM_ASIC \ +{%- endif %} --name={{docker_container_name}}$DEV {{docker_image_name}}:latest || { echo "Failed to docker run" >&1 exit 4 @@ -260,10 +325,21 @@ stop() { OP=$1 DEV=$2 # namespace/device number to operate on +NAMESPACE_PREFIX="asic" if [ "$DEV" ]; then - NET_NS="asic$DEV" #name of the network namespace -else + NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace + + # While using -n (namespace) argument, sonic-cfggen/sonic-db-cli uses redis UNIX socket + # for accessing redis DB in a namespace. This unix socket has permission restrictions since + # it is created by systemd database.servce started with [User] as [root]. + # sudo is needed here for services which are started by systemd with [User] as [admin] + # and needs to override this unix socket permission restrictions. + SONIC_CFGGEN="sudo sonic-cfggen -n $NET_NS" + SONIC_DB_CLI="sudo sonic-db-cli -n $NET_NS" + else NET_NS="" + SONIC_CFGGEN="sonic-cfggen" + SONIC_DB_CLI="sonic-db-cli" fi case "$1" in diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index c187e02762b8..7a0a8d15880d 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -18,9 +18,9 @@ } }, "FEATURE": { -{%- for feature in ["sflow", "telemetry"] %} +{%- for feature, status in [("sflow", "disabled"), ("telemetry", "enabled")] %} "{{feature}}": { - "status": "disabled" + "status": "{{status}}" }{% if not loop.last %},{% endif -%} {% endfor %} }, 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..bd4d28a2ee55 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] diff --git a/files/build_templates/nat.service.j2 b/files/build_templates/nat.service.j2 index 79a56f67ca89..4a0e20efaee8 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 diff --git a/files/build_templates/per_namespace/swss.service.j2 b/files/build_templates/per_namespace/swss.service.j2 index 53d6b4497df7..352d1593a60b 100644 --- a/files/build_templates/per_namespace/swss.service.j2 +++ b/files/build_templates/per_namespace/swss.service.j2 @@ -8,8 +8,6 @@ After=topology.service {% endif %} {% if sonic_asic_platform == 'broadcom' %} Requires=opennsl-modules.service -{% elif sonic_asic_platform == 'nephos' %} -Requires=nps-modules-4.9.0-11-2-amd64.service {% endif %} Requires=updategraph.service After=updategraph.service diff --git a/files/build_templates/per_namespace/syncd.service.j2 b/files/build_templates/per_namespace/syncd.service.j2 index b2922e0d12b6..0c9bf073e940 100644 --- a/files/build_templates/per_namespace/syncd.service.j2 +++ b/files/build_templates/per_namespace/syncd.service.j2 @@ -11,8 +11,8 @@ After=topology.service Requires=opennsl-modules.service After=opennsl-modules.service {% elif sonic_asic_platform == 'nephos' %} -Requires=nps-modules-4.9.0-11-2-amd64.service -After=nps-modules-4.9.0-11-2-amd64.service +Requires=nps-modules.service +After=nps-modules.service {% endif %} Requires=updategraph.service After=updategraph.service diff --git a/files/build_templates/qos_config.j2 b/files/build_templates/qos_config.j2 index 2a9a5be8d83c..9420be7a0671 100644 --- a/files/build_templates/qos_config.j2 +++ b/files/build_templates/qos_config.j2 @@ -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/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index dad1cb9b8906..2afc17024337 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -33,6 +33,7 @@ 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_TEMPLATES="$FILESYSTEM_ROOT_USR_SHARE_SONIC/templates" @@ -42,9 +43,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 @@ -101,6 +102,13 @@ sudo rm -rf $FILESYSTEM_ROOT/$CONFIG_ENGINE_WHEEL_NAME # Install Python client for Redis sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install "redis==2.10.6" +# 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 @@ -110,12 +118,35 @@ 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 SwSS SDK Python 3 package +# Note: the scripts will be overwritten by corresponding Python 2 package +if [ -e {{swsssdk_py3_wheel_path}} ]; then + 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 +fi + # 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 rm -rf $FILESYSTEM_ROOT/$SWSSSDK_PY2_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 +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 Python package +SONIC_YANG_MGMT_PY_WHEEL_NAME=$(basename {{sonic_yang_mgmt_py_wheel_path}}) +sudo cp {{sonic_yang_mgmt_py_wheel_path}} $FILESYSTEM_ROOT/$SONIC_YANG_MGMT_PY_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $SONIC_YANG_MGMT_PY_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$SONIC_YANG_MGMT_PY_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 @@ -190,23 +221,28 @@ sudo chmod 600 $FILESYSTEM_ROOT/etc/monit/conf.d/* 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/ # 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 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.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 logrotate.d configuration files sudo cp -f $IMAGE_CONFIGS/logrotate/logrotate.d/* $FILESYSTEM_ROOT/etc/logrotate.d/ @@ -214,7 +250,7 @@ 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 @@ -230,20 +266,29 @@ sudo cp $IMAGE_CONFIGS/interfaces/init_interfaces $FILESYSTEM_ROOT/etc/network/i sudo mkdir -p $FILESYSTEM_ROOT/etc/network/interfaces.d # Copy hostcfgd files -sudo cp $IMAGE_CONFIGS/hostcfgd/hostcfgd.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $IMAGE_CONFIGS/hostcfgd/hostcfgd.service $FILESYSTEM_ROOT_USR_LIB_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 +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install azure-storage==0.36.0 +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install watchdog==0.10.2 +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install futures==3.3.0 + +{% if install_kubernetes == "y" %} +# Copy kubelet service files +# Keep it disabled until join, else it continuously restart and as well spew too many +# non-required log lines wasting syslog resources. +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl disable kubelet.service +{% endif %} # Copy the buffer configuration template sudo cp $BUILD_TEMPLATES/buffers_config.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ @@ -252,7 +297,7 @@ sudo cp $BUILD_TEMPLATES/buffers_config.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMP sudo cp $BUILD_TEMPLATES/qos_config.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ # 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 +306,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,7 +327,7 @@ 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 @@ -298,22 +343,22 @@ 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/ +sudo cp $IMAGE_CONFIGS/caclmgrd/caclmgrd.service $FILESYSTEM_ROOT_USR_LIB_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/ +sudo cp $IMAGE_CONFIGS/procdockerstatsd/procdockerstatsd.service $FILESYSTEM_ROOT_USR_LIB_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 cp $BUILD_TEMPLATES/process-reboot-cause.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable process-reboot-cause.timer # Copy process-reboot-cause service files -sudo cp $IMAGE_CONFIGS/process-reboot-cause/process-reboot-cause.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $IMAGE_CONFIGS/process-reboot-cause/process-reboot-cause.service $FILESYSTEM_ROOT_USR_LIB_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/ @@ -328,7 +373,14 @@ 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 +if [ -e tmpdir ] ; +then + rm -rf tmpdir; +fi +sudo mkdir tmpdir +sudo dpkg --extract {{deb}} tmpdir +for subdir in $(ls tmpdir) ; do sudo cp -R tmpdir/$subdir/* $FILESYSTEM_ROOT/$subdir; done +sudo rm -rf tmpdir {% else %} sudo dpkg --root=$FILESYSTEM_ROOT -i {{deb}} || sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f {% endif %} @@ -363,7 +415,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 @@ -387,6 +439,11 @@ 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 @@ -401,6 +458,17 @@ sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS ta sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS tag {{imagename}}:latest {{imagebasename}}:latest {% endif %} {% endfor %} + +{% if install_kubernetes == "y" %} +## Pull in kubernetes docker images +echo "pulling universal k8s images ..." +FLANNEL_ARCH=$([ "${CONFIGURED_ARCH}" == "armhf" ] && echo "arm64" || echo "${CONFIGURED_ARCH}") +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull k8s.gcr.io/pause:${K8s_GCR_IO_PAUSE_VERSION} +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull k8s.gcr.io/kube-proxy:v${KUBERNETES_VERSION} +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull quay.io/coreos/flannel:${K8s_CNI_FLANNEL_VERSION}-${FLANNEL_ARCH} +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 @@ -410,18 +478,19 @@ 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 {% 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 @@ -443,10 +512,10 @@ sudo LANG=C cp $SCRIPTS_DIR/sonic-netns-exec $FILESYSTEM_ROOT/usr/bin/sonic-netn # Copy systemd timer configuration # It implements delayed start of services -sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT_USR_LIB_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 cp $BUILD_TEMPLATES/telemetry.timer $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable telemetry.timer {% endif %} @@ -469,7 +538,8 @@ sudo cp $files_path/$MLNX_SPC2_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC2.mfa sudo cp $files_path/$MLNX_SPC3_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC3.mfa sudo cp $files_path/$ISSU_VERSION_FILE $FILESYSTEM_ROOT/etc/mlnx/issu-version sudo cp $files_path/$MLNX_FFB_SCRIPT $FILESYSTEM_ROOT/usr/bin/mlnx-ffb.sh -sudo cp $files_path/$ONIE_FW_UPDATE $FILESYSTEM_ROOT/usr/bin/onie-fw-update.sh +sudo cp $files_path/$MLNX_ONIE_FW_UPDATE $FILESYSTEM_ROOT/usr/bin/$MLNX_ONIE_FW_UPDATE +sudo cp $files_path/$MLNX_SSD_FW_UPDATE $FILESYSTEM_ROOT/usr/bin/$MLNX_SSD_FW_UPDATE j2 platform/mellanox/mlnx-fw-upgrade.j2 | sudo tee $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh diff --git a/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/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index e5744c7ca65b..ce60ebc9d40b 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -11,7 +11,7 @@ # try: - import ipaddr as ipaddress + import ipaddress import os import subprocess import sys @@ -44,6 +44,15 @@ def log_error(msg): syslog.syslog(syslog.LOG_ERR, msg) syslog.closelog() +# ========================== Helper Functions ========================= + +def _ip_prefix_in_key(key): + """ + Function to check if IP prefix is present in a Redis database key. + If it is present, then the key will be a tuple. Otherwise, the + key will be a string. + """ + return (isinstance(key, tuple)) # ============================== Classes ============================== @@ -61,12 +70,21 @@ class ControlPlaneAclManager(object): 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" + # To specify a port range instead of a single port, 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"]} + "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): @@ -115,6 +133,94 @@ class ControlPlaneAclManager(object): tcp_flags_str = tcp_flags_str[:-1] return tcp_flags_str + def generate_block_ip2me_traffic_iptables_commands(self): + LOOPBACK_INTERFACE_TABLE_NAME = "LOOPBACK_INTERFACE" + MGMT_INTERFACE_TABLE_NAME = "MGMT_INTERFACE" + VLAN_INTERFACE_TABLE_NAME = "VLAN_INTERFACE" + PORTCHANNEL_INTERFACE_TABLE_NAME = "PORTCHANNEL_INTERFACE" + INTERFACE_TABLE_NAME = "INTERFACE" + + block_ip2me_cmds = [] + + # Add iptables rules to drop all packets destined for loopback interface IP addresses + loopback_iface_table = self.config_db.get_table(LOOPBACK_INTERFACE_TABLE_NAME) + if loopback_iface_table: + for key, _ in loopback_iface_table.iteritems(): + if not _ip_prefix_in_key(key): + continue + iface_name, iface_cidr = key + ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) + if isinstance(ip_ntwrk, ipaddress.IPv4Network): + block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) + elif isinstance(ip_ntwrk, ipaddress.IPv6Network): + block_ip2me_cmds.append("ip6tables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) + else: + log_warning("Unrecognized IP address type on interface '{}': {}".format(iface_name, ip_ntwrk)) + + # Add iptables rules to drop all packets destined for management interface IP addresses + mgmt_iface_table = self.config_db.get_table(MGMT_INTERFACE_TABLE_NAME) + if mgmt_iface_table: + for key, _ in mgmt_iface_table.iteritems(): + if not _ip_prefix_in_key(key): + continue + iface_name, iface_cidr = key + ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) + if isinstance(ip_ntwrk, ipaddress.IPv4Network): + block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) + elif isinstance(ip_ntwrk, ipaddress.IPv6Network): + block_ip2me_cmds.append("ip6tables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) + else: + log_warning("Unrecognized IP address type on interface '{}': {}".format(iface_name, ip_ntwrk)) + + # Add iptables rules to drop all packets destined for our VLAN interface gateway IP addresses + vlan_iface_table = self.config_db.get_table(VLAN_INTERFACE_TABLE_NAME) + if vlan_iface_table: + for key, _ in vlan_iface_table.iteritems(): + if not _ip_prefix_in_key(key): + continue + iface_name, iface_cidr = key + ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) + first_host = next(ip_ntwrk.hosts()) + if isinstance(ip_ntwrk, ipaddress.IPv4Network): + block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(first_host, ip_ntwrk.max_prefixlen)) + elif isinstance(ip_ntwrk, ipaddress.IPv6Network): + block_ip2me_cmds.append("ip6tables -A INPUT -d {}/{} -j DROP".format(first_host, ip_ntwrk.max_prefixlen)) + else: + log_warning("Unrecognized IP address type on interface '{}': {}".format(iface_name, ip_ntwrk)) + + # Add iptables rules to drop all packets destined for point-to-point interface IP addresses + # (All portchannel interfaces and configured front-panel interfaces) + portchannel_iface_table = self.config_db.get_table(PORTCHANNEL_INTERFACE_TABLE_NAME) + if portchannel_iface_table: + for key, _ in portchannel_iface_table.iteritems(): + if not _ip_prefix_in_key(key): + continue + iface_name, iface_cidr = key + ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) + if isinstance(ip_ntwrk, ipaddress.IPv4Network): + block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) + elif isinstance(ip_ntwrk, ipaddress.IPv6Network): + block_ip2me_cmds.append("ip6tables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) + else: + log_warning("Unrecognized IP address type on interface '{}': {}".format(iface_name, ip_ntwrk)) + + iface_table = self.config_db.get_table(INTERFACE_TABLE_NAME) + if iface_table: + for key, _ in iface_table.iteritems(): + if not _ip_prefix_in_key(key): + continue + iface_name, iface_cidr = key + ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) + if isinstance(ip_ntwrk, ipaddress.IPv4Network): + block_ip2me_cmds.append("iptables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) + elif isinstance(ip_ntwrk, ipaddress.IPv6Network): + block_ip2me_cmds.append("ip6tables -A INPUT -d {}/{} -j DROP".format(ip_ntwrk.network_address, ip_ntwrk.max_prefixlen)) + else: + log_warning("Unrecognized IP address type on interface '{}': {}".format(iface_name, ip_ntwrk)) + + return block_ip2me_cmds + + def get_acl_rules_and_translate_to_iptables_commands(self): """ Retrieves current ACL tables and rules from Config DB, translates @@ -147,14 +253,58 @@ class ControlPlaneAclManager(object): iptables_cmds.append("ip6tables -F") iptables_cmds.append("ip6tables -X") - # Add iptables commands to allow all IPv4 and IPv6 traffic from localhost + # Add iptables/ip6tables commands to allow all 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") + # Add iptables/ip6tables commands to allow all incoming packets from established + # TCP sessions or new TCP sessions which are related to established TCP sessions + iptables_cmds.append("iptables -A INPUT -p tcp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p tcp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT") + + # Add iptables/ip6tables commands to allow bidirectional ICMPv4 ping and traceroute + # TODO: Support processing ICMPv4 service ACL rules, and remove this blanket acceptance + iptables_cmds.append("iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT") + iptables_cmds.append("iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT") + iptables_cmds.append("iptables -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT") + iptables_cmds.append("iptables -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT") + + # Add iptables/ip6tables commands to allow bidirectional ICMPv6 ping and traceroute + # TODO: Support processing ICMPv6 service ACL rules, and remove this blanket acceptance + iptables_cmds.append("ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-reply -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p icmpv6 --icmpv6-type destination-unreachable -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p icmpv6 --icmpv6-type time-exceeded -j ACCEPT") + + # Add iptables/ip6tables commands to allow all incoming Neighbor Discovery Protocol (NDP) NS/NA/RS/RA messages + # TODO: Support processing NDP service ACL rules, and remove this blanket acceptance + iptables_cmds.append("ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p icmpv6 --icmpv6-type router-solicitation -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p icmpv6 --icmpv6-type router-advertisement -j ACCEPT") + + # Add iptables/ip6tables commands to allow all incoming IPv4 DHCP packets + iptables_cmds.append("iptables -A INPUT -p udp --dport 67:68 --sport 67:68 -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p udp --dport 67:68 --sport 67:68 -j ACCEPT") + + # Add iptables/ip6tables commands to allow all incoming IPv6 DHCP packets + iptables_cmds.append("iptables -A INPUT -p udp --dport 546:547 --sport 546:547 -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p udp --dport 546:547 --sport 546:547 -j ACCEPT") + + # Add iptables/ip6tables commands to allow all incoming BGP traffic + # TODO: Determine BGP ACLs based on configured device sessions, and remove this blanket acceptance + iptables_cmds.append("iptables -A INPUT -p tcp --dport 179 -j ACCEPT") + iptables_cmds.append("iptables -A INPUT -p tcp --sport 179 -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p tcp --dport 179 -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p tcp --sport 179 -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) + num_ctrl_plane_acl_rules = 0 + # Walk the ACL tables for (table_name, table_data) in self._tables_db_info.iteritems(): @@ -246,6 +396,23 @@ class ControlPlaneAclManager(object): rule_cmd += " -j {}".format(rule_props["PACKET_ACTION"]) iptables_cmds.append(rule_cmd) + num_ctrl_plane_acl_rules += 1 + + # Add iptables commands to block ip2me traffic + iptables_cmds += self.generate_block_ip2me_traffic_iptables_commands() + + # Add iptables/ip6tables commands to allow all incoming packets with TTL of 0 or 1 + # This allows the device to respond to tools like tcptraceroute + iptables_cmds.append("iptables -A INPUT -m ttl --ttl-lt 2 -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -p tcp -m hl --hl-lt 2 -j ACCEPT") + + # Finally, if the device has control plane ACLs configured, + # add iptables/ip6tables commands to drop all other incoming packets + if num_ctrl_plane_acl_rules > 0: + iptables_cmds.append("iptables -A INPUT -j DROP") + iptables_cmds.append("iptables -A FORWARD -j DROP") + iptables_cmds.append("ip6tables -A INPUT -j DROP") + iptables_cmds.append("ip6tables -A FORWARD -j DROP") return iptables_cmds diff --git a/files/image_config/config-setup/config-setup b/files/image_config/config-setup/config-setup index afff97806518..1f95a10bb053 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 @@ -103,24 +107,16 @@ 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 - fi + config load_minigraph -y -n + config save -y } +# Reload exisitng config db file on disk +reload_configdb() +{ + echo "Reloading existing config db..." + config reload -y -n +} # Restore SONiC configuration from a backup copy function copy_config_files_and_directories() { @@ -281,15 +277,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" # 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 +332,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,6 +374,14 @@ 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_initialization fi @@ -371,6 +404,13 @@ boot_config() } ### Execution starts here ### +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..3e1b76be0157 100644 --- a/files/image_config/constants/constants.yml +++ b/files/image_config/constants/constants.yml @@ -1,4 +1,34 @@ 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 + peers: + general: # peer_type + db_table: "BGP_NEIGHBOR" + template_dir: "general" + 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/ebtables/ebtables.default b/files/image_config/ebtables/ebtables.default new file mode 100644 index 000000000000..93706fe56257 --- /dev/null +++ b/files/image_config/ebtables/ebtables.default @@ -0,0 +1,35 @@ +# Unload modules on restart and stop +# Value: yes|no, default: yes +# This option has to be 'yes' to get to a sane state for a firewall +# restart or stop. Only set to 'no' if there are problems unloading netfilter +# modules. +EBTABLES_MODULES_UNLOAD="yes" + +# Load firewall rules on system startup. +# Value: yes|no, default: no +# Restores the ebtables rulesets from the last saved state when the +# system boots up. +EBTABLES_LOAD_ON_START="yes" + +# Save current firewall rules on stop. +# Value: yes|no, default: no +# Saves all firewall rules if firewall gets stopped +# (e.g. on system shutdown). +EBTABLES_SAVE_ON_STOP="no" + +# Save current firewall rules on restart. +# Value: yes|no, default: no +# Saves all firewall rules if firewall gets restarted. +EBTABLES_SAVE_ON_RESTART="no" + +# Save (and restore) rule counters. +# Value: yes|no, default: no +# Save rule counters when saving a kernel table to a file. If the +# rule counters were saved, they will be restored when restoring the table. +EBTABLES_SAVE_COUNTER="no" + +# Backup suffix for ruleset save files. +# Value: , default: "~" +# Keep one backup level of saved rules. +# Set this variable to the empty string to disable backups. +EBTABLES_BACKUP_SUFFIX="~" diff --git a/files/image_config/ebtables/ebtables.filter b/files/image_config/ebtables/ebtables.filter index 4faad1f5f4bd..dfe55672769d 100644 Binary files a/files/image_config/ebtables/ebtables.filter and b/files/image_config/ebtables/ebtables.filter differ diff --git a/files/image_config/ebtables/ebtables.init b/files/image_config/ebtables/ebtables.init new file mode 100755 index 000000000000..12182902319c --- /dev/null +++ b/files/image_config/ebtables/ebtables.init @@ -0,0 +1,175 @@ +#!/bin/bash +# +# init script for the Ethernet Bridge filter tables +# +# Written by Dag Wieers +# Modified by Rok Papez +# Bart De Schuymer +# Adapted to Debian by Jan Christoph Nordholz +# +# chkconfig: - 15 85 +# description: Ethernet Bridge filtering tables +# +### BEGIN INIT INFO +# Provides: ebtables +# Required-Start: +# Required-Stop: +# Should-Start: $local_fs +# Should-Stop: $local_fs +# Default-Start: S +# Default-Stop: 0 1 6 +# Short-Description: ebtables ruleset management +# Description: Saves and restores the state of the ebtables rulesets. +### END INIT INFO + +. /lib/lsb/init-functions + +test -f /sbin/ebtables || exit 0 + +EBTABLES_DUMPFILE_STEM=/etc/ebtables + +RETVAL=0 +prog="ebtables" +desc="Ethernet bridge filtering" +umask 0077 + +#default configuration +EBTABLES_MODULES_UNLOAD="yes" +EBTABLES_LOAD_ON_START="no" +EBTABLES_SAVE_ON_STOP="no" +EBTABLES_SAVE_ON_RESTART="no" +EBTABLES_SAVE_COUNTER="no" +EBTABLES_BACKUP_SUFFIX="~" + +config=/etc/default/$prog +[ -f "$config" ] && . "$config" + +function get_supported_tables() { + EBTABLES_SUPPORTED_TABLES= + /sbin/ebtables -t filter -L 2>&1 1>/dev/null | grep -q permission + if [ $? -eq 0 ]; then + log_failure_msg "Error: insufficient privileges to access the ebtables rulesets." + exit 1 + fi + for table in filter nat broute; do + /sbin/ebtables -t $table -L &> /dev/null + if [ $? -eq 0 ]; then + EBTABLES_SUPPORTED_TABLES="${EBTABLES_SUPPORTED_TABLES} $table" + fi + done +} + +function load() { + RETVAL=0 + get_supported_tables + log_daemon_msg "Restoring ebtables rulesets" + for table in $EBTABLES_SUPPORTED_TABLES; do + log_progress_msg "$table" + if [ -s ${EBTABLES_DUMPFILE_STEM}.$table ]; then + /sbin/ebtables -t $table --atomic-file ${EBTABLES_DUMPFILE_STEM}.$table --atomic-commit + RET=$? + if [ $RET -ne 0 ]; then + log_progress_msg "(failed)" + RETVAL=$RET + fi + else + log_progress_msg "(no saved state)" + fi + done + if [ -z "$EBTABLES_SUPPORTED_TABLES" ]; then + log_progress_msg "no kernel support" + else + log_progress_msg "done" + fi + log_end_msg $RETVAL +} + +function clear() { + RETVAL=0 + get_supported_tables + log_daemon_msg "Clearing ebtables rulesets" + for table in $EBTABLES_SUPPORTED_TABLES; do + log_progress_msg "$table" + /sbin/ebtables -t $table --init-table + done + + if [ "$EBTABLES_MODULES_UNLOAD" = "yes" ]; then + for mod in $(grep -E '^(ebt|ebtable)_' /proc/modules | cut -d' ' -f1) ebtables; do + rmmod $mod 2> /dev/null + done + fi + if [ -z "$EBTABLES_SUPPORTED_TABLES" ]; then + log_progress_msg "no kernel support" + else + log_progress_msg "done" + fi + log_end_msg $RETVAL +} + +function save() { + RETVAL=0 + get_supported_tables + log_daemon_msg "Saving ebtables rulesets" + for table in $EBTABLES_SUPPORTED_TABLES; do + log_progress_msg "$table" + [ -n "$EBTABLES_BACKUP_SUFFIX" ] && [ -s ${EBTABLES_DUMPFILE_STEM}.$table ] && \ + mv ${EBTABLES_DUMPFILE_STEM}.$table ${EBTABLES_DUMPFILE_STEM}.$table$EBTABLES_BACKUP_SUFFIX + /sbin/ebtables -t $table --atomic-file ${EBTABLES_DUMPFILE_STEM}.$table --atomic-save + RET=$? + if [ $RET -ne 0 ]; then + log_progress_msg "(failed)" + RETVAL=$RET + else + if [ "$EBTABLES_SAVE_COUNTER" = "no" ]; then + /sbin/ebtables -t $table --atomic-file ${EBTABLES_DUMPFILE_STEM}.$table -Z + fi + fi + done + if [ -z "$EBTABLES_SUPPORTED_TABLES" ]; then + log_progress_msg "no kernel support" + else + log_progress_msg "done" + fi + log_end_msg $RETVAL +} + +case "$1" in + start) + [ "$EBTABLES_LOAD_ON_START" = "yes" ] && load + ;; + stop) + [ "$EBTABLES_SAVE_ON_STOP" = "yes" ] && save + clear + ;; + restart|reload|force-reload) + [ "$EBTABLES_SAVE_ON_RESTART" = "yes" ] && save + clear + [ "$EBTABLES_LOAD_ON_START" = "yes" ] && load + ;; + load) + load + ;; + save) + save + ;; + status) + get_supported_tables + if [ -z "$EBTABLES_SUPPORTED_TABLES" ]; then + log_failure_msg "No kernel support for ebtables." + RETVAL=1 + else + log_daemon_msg "Ebtables support available, number of installed rules" + for table in $EBTABLES_SUPPORTED_TABLES; do + COUNT=$(( $(/sbin/ebtables -t $table -L | sed -e "/^Bridge chain/! d" -e "s/^.*entries: //" -e "s/,.*$/ +/") 0 )) + log_progress_msg "$table($COUNT)" + done + log_end_msg 0 + RETVAL=0 + fi + ;; + *) + echo "Usage: $0 {start|stop|restart|reload|force-reload|load|save|status}" >&2 + RETVAL=1 +esac + +exit $RETVAL diff --git a/files/image_config/ebtables/ebtables.service b/files/image_config/ebtables/ebtables.service new file mode 100644 index 000000000000..bb2cb8fd0a06 --- /dev/null +++ b/files/image_config/ebtables/ebtables.service @@ -0,0 +1,19 @@ +[Unit] +Description=ebtables ruleset management +DefaultDependencies=no +Before=network-pre.target +Wants=network-pre.target +After=local-fs.target +# n.b. use below if we want to tear down rules before shutting down. +#Before=shutdown.target +#Conflicts=shutdown.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/etc/init.d/ebtables start +ExecStop=/etc/init.d/ebtables stop +ExecReload=/etc/init.d/ebtables reload + +[Install] +WantedBy=multi-user.target diff --git a/files/image_config/fstrim/fstrim.service b/files/image_config/fstrim/fstrim.service index cf740d3af34d..0383b5fa010b 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/bin/log_ssd_health ExecStart=/sbin/fstrim -av diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index edbbacca86c2..6d4615d85823 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -267,39 +267,42 @@ class HostConfigDaemon: 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)) + continue + + status = status_data[key]['status'] + if not status: + syslog.syslog(syslog.LOG_WARNING, "status is missing for {}".format(key)) + continue + if status == "enabled": + start_cmds=[] + start_cmds.append("sudo systemctl unmask {}.service".format(key)) + start_cmds.append("sudo systemctl enable {}.service".format(key)) + start_cmds.append("sudo systemctl start {}.service".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)) + continue + syslog.syslog(syslog.LOG_INFO, "Feature '{}' is enabled and started".format(key)) + elif status == "disabled": + stop_cmds=[] + stop_cmds.append("sudo systemctl stop {}.service".format(key)) + stop_cmds.append("sudo systemctl disable {}.service".format(key)) + stop_cmds.append("sudo systemctl mask {}.service".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)) + continue + 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)) diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index 0e852a1150fb..dbedd5e9418a 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -76,10 +76,6 @@ iface eth0 {{ 'inet' if prefix | ipv4 else 'inet6' }} static 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 %} {% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %} up ip rule add to {{ route }} table {{ vrf_table }} {% endfor %} @@ -87,9 +83,6 @@ iface eth0 {{ 'inet' if prefix | ipv4 else 'inet6' }} static pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete default via {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} dev eth0 table {{ vrf_table }} pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete {{ prefix | network }}/{{ prefix | prefixlen }} dev eth0 table {{ vrf_table }} pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} rule delete from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} -{% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} - down cgdelete -g l3mdev:mgmt -{% endif %} {% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %} pre-down ip rule delete to {{ route }} table {{ vrf_table }} {% endfor %} @@ -100,9 +93,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/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/misc/docker-wait-any b/files/image_config/misc/docker-wait-any index 3988a9fbdf57..b6a2d95c8821 100755 --- a/files/image_config/misc/docker-wait-any +++ b/files/image_config/misc/docker-wait-any @@ -11,13 +11,13 @@ 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. + NOTE: This script is written against docker Python package 4.1.0. Newer + versions of docker may have a different API. """ import sys import threading -from docker import Client +from docker import APIClient # Instantiate a global event to share among our threads g_thread_exit_event = threading.Event() @@ -40,7 +40,7 @@ def wait_for_container(docker_client, container_name): def main(): thread_list = [] - docker_client = Client(base_url='unix://var/run/docker.sock') + docker_client = APIClient(base_url='unix://var/run/docker.sock') # Ensure we were passed at least one argument if len(sys.argv) < 2: diff --git a/files/image_config/ntp/ntp-config.sh b/files/image_config/ntp/ntp-config.sh index 601b7bd421f0..0cec0f7af2db 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 +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 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..759a69496b2c --- /dev/null +++ b/files/image_config/ntp/ntp-systemd-wrapper @@ -0,0 +1,38 @@ +#!/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 + vrfEnabled=$(/usr/local/bin/sonic-cfggen -d -v 'MGMT_VRF_CONFIG["vrf_global"]["mgmtVrfEnabled"]' 2> /dev/null) + if [ "$vrfEnabled" = "true" ] + then + ip vrf exec mgmt start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $NTPD_OPTS + else + start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $NTPD_OPTS + fi +) 9>$LOCKFILE + diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index 2884270b7870..ad67f0ff425a 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -340,4 +340,10 @@ if [ -f $FIRST_BOOT_FILE ]; then 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/process-reboot-cause/process-reboot-cause b/files/image_config/process-reboot-cause/process-reboot-cause index 409deb7d6859..c9d57fd77b0a 100755 --- a/files/image_config/process-reboot-cause/process-reboot-cause +++ b/files/image_config/process-reboot-cause/process-reboot-cause @@ -12,6 +12,8 @@ try: import sys import syslog import re + + import sonic_device_util except ImportError as err: raise ImportError("%s - required module not found" % str(err)) @@ -34,7 +36,7 @@ REBOOT_TYPE_KEXEC_FILE = "/proc/cmdline" 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" +REBOOT_CAUSE_UNKNOWN = "Unknown" # ========================== Syslog wrappers ========================== @@ -72,7 +74,7 @@ def parse_warmfast_reboot_from_proc_cmdline(): def find_software_reboot_cause(): - software_reboot_cause = UNKNOWN_REBOOT_CAUSE + software_reboot_cause = REBOOT_CAUSE_UNKNOWN if os.path.isfile(REBOOT_CAUSE_FILE): with open(REBOOT_CAUSE_FILE, "r") as cause_file: @@ -82,6 +84,10 @@ def find_software_reboot_cause(): log_info("Reboot cause file {} not found".format(REBOOT_CAUSE_FILE)) if os.path.isfile(FIRST_BOOT_PLATFORM_FILE): + if software_reboot_cause == REBOOT_CAUSE_UNKNOWN: + version_info = sonic_device_util.get_sonic_version_info() + build_version = version_info['build_version'] if version_info else "unknown" + software_reboot_cause += " (First boot of SONiC version {})".format(build_version) os.remove(FIRST_BOOT_PLATFORM_FILE) return software_reboot_cause @@ -148,7 +154,7 @@ def main(): os.remove(PREVIOUS_REBOOT_CAUSE_FILE) # Set a default previous reboot cause - previous_reboot_cause = UNKNOWN_REBOOT_CAUSE + previous_reboot_cause = REBOOT_CAUSE_UNKNOWN # 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() @@ -188,7 +194,7 @@ def main(): # 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) + cause_file.write(REBOOT_CAUSE_UNKNOWN) if __name__ == "__main__": diff --git a/files/image_config/secureboot/allowlist_paths.conf b/files/image_config/secureboot/allowlist_paths.conf new file mode 100644 index 000000000000..fe5b890e0678 --- /dev/null +++ b/files/image_config/secureboot/allowlist_paths.conf @@ -0,0 +1,35 @@ +home/.* +var/core/.* +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/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/syslog/host_umount.sh b/files/image_config/syslog/host_umount.sh new file mode 100755 index 000000000000..cedbb5b11107 --- /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 + systemctl stop systemd-journald.socket + systemctl stop systemd-journald-audit.socket + systemctl stop systemd-journald-dev-log.socket +} + +delete_loop_device() { + umount /var/log + if [[ $? -ne 0 ]] + then + exit 0 + fi + losetup -d /dev/loop1 +} + +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..74f7aea9f076 --- /dev/null +++ b/files/image_config/syslog/override.conf @@ -0,0 +1,6 @@ +[Unit] +After=var-log.mount host.mount + +[Socket] +ExecStopPre=/usr/bin/host_umount.sh journal_stop +ExecStopPost=/usr/bin/host_umount.sh delete_loop_device diff --git a/files/image_config/updategraph/updategraph b/files/image_config/updategraph/updategraph index a24d452b1ad2..86ee8a800ae1 100755 --- a/files/image_config/updategraph/updategraph +++ b/files/image_config/updategraph/updategraph @@ -3,25 +3,8 @@ 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 } if [ ! -f /etc/sonic/updategraph.conf ]; then @@ -141,7 +124,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..01ad921137b6 100755 --- a/files/image_config/warmboot-finalizer/finalize-warmboot.sh +++ b/files/image_config/warmboot-finalizer/finalize-warmboot.sh @@ -29,7 +29,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") ]]; diff --git a/files/initramfs-tools/arista-convertfs.j2 b/files/initramfs-tools/arista-convertfs.j2 index 56616d2ba04a..0dad56e5776b 100644 --- a/files/initramfs-tools/arista-convertfs.j2 +++ b/files/initramfs-tools/arista-convertfs.j2 @@ -224,7 +224,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/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/union-mount.j2 b/files/initramfs-tools/union-mount.j2 index 0fadb9a73edb..8c8bb926444d 100644 --- a/files/initramfs-tools/union-mount.j2 +++ b/files/initramfs-tools/union-mount.j2 @@ -39,10 +39,43 @@ set_tmpfs_log_partition_size() [ $maxsize -le $varlogsize ] && varlogsize=$maxsize } +remove_not_in_allowlist_files() +{ + image_dir=$1 + allowlist_file=${rootmnt}/host/$image_dir/allowlist_paths.conf + + # Return if the secure_boot_enable option is not set + if ! (cat /proc/cmdline | grep -i -q "secure_boot_enable=[y1]"); then + return + fi + + # 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 + + rw_dir=${rootmnt}/host/$image_dir/rw + + # Set the grep pattern file, remove the blank line in config file + allowlist_pattern_file=${rootmnt}/host/$image_dir/allowlist_paths.pattern + awk -v rw_dir="$rw_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 ${rw_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 +## Remove the files not in allowlist in the rw folder +remove_not_in_allowlist_files "$image_dir" +## Remove the executable permission for all the files in rw folder except home folder +rw_dir=${rootmnt}/host/$image_dir/rw +find ${rw_dir} -type f -not -path ${rw_dir}/home -exec chmod a-x {} + + mount -n -o lowerdir=${rootmnt},upperdir=${rootmnt}/host/$image_dir/rw,workdir=${rootmnt}/host/$image_dir/work -t overlay root-overlay ${rootmnt} ## Check if the root block device is still there [ -b ${ROOT} ] || mdev -s @@ -85,5 +118,12 @@ then 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/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/swss.sh b/files/scripts/swss.sh index 360e331f3636..74828c740fe1 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -28,8 +28,8 @@ function unlock_service_state_change() function check_warm_boot() { - SYSTEM_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" else @@ -40,7 +40,7 @@ function check_warm_boot() function validate_restore_count() { if [[ x"$WARM_BOOT" == x"true" ]]; then - RESTORE_COUNT=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` + RESTORE_COUNT=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` # We have to make sure db data has not been flushed. if [[ -z "$RESTORE_COUNT" ]]; then WARM_BOOT="false" @@ -51,10 +51,12 @@ function validate_restore_count() function wait_for_database_service() { # Wait for redis server start before database clean - /usr/bin/docker exec database$DEV ping_pong_db_insts + until [[ $($SONIC_DB_CLI PING | grep -c PONG) -gt 0 ]]; do + sleep 1; + done # Wait for configDB initialization - until [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $($SONIC_DB_CLI CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -64,7 +66,7 @@ function wait_for_database_service() # $2 the string of a list of table prefixes function clean_up_tables() { - sonic-netns-exec "$NET_NS" sonic-db-cli $1 EVAL " + $SONIC_DB_CLI $1 EVAL " local tables = {$2} for i = 1, table.getn(tables) do local matches = redis.call('KEYS', tables[i]) @@ -132,10 +134,10 @@ start() { # Don't flush DB during warm boot if [[ x"$WARM_BOOT" != x"true" ]]; then debug "Flushing APP, ASIC, COUNTER, CONFIG, and partial STATE databases ..." - sonic-netns-exec "$NET_NS" sonic-db-cli APPL_DB FLUSHDB - sonic-netns-exec "$NET_NS" sonic-db-cli ASIC_DB FLUSHDB - sonic-netns-exec "$NET_NS" sonic-db-cli COUNTERS_DB FLUSHDB - sonic-netns-exec "$NET_NS" sonic-db-cli FLEX_COUNTER_DB FLUSHDB + $SONIC_DB_CLI APPL_DB FLUSHDB + $SONIC_DB_CLI ASIC_DB FLUSHDB + $SONIC_DB_CLI COUNTERS_DB FLUSHDB + $SONIC_DB_CLI FLEX_COUNTER_DB FLUSHDB clean_up_tables STATE_DB "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" fi @@ -206,10 +208,13 @@ 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="asic$DEV" #name of the network namespace + NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace + SONIC_DB_CLI="sonic-db-cli -n $NET_NS" else - NET_NS="" + NET_NS="" + SONIC_DB_CLI="sonic-db-cli" fi case "$1" in diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 9847cfec9406..045b8a22bfb8 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -26,8 +26,8 @@ function unlock_service_state_change() function check_warm_boot() { - SYSTEM_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" @@ -39,10 +39,12 @@ function check_warm_boot() function wait_for_database_service() { # Wait for redis server start before database clean - /usr/bin/docker exec database$DEV ping_pong_db_insts + until [[ $($SONIC_DB_CLI PING | grep -c PONG) -gt 0 ]]; do + sleep 1; + done # Wait for configDB initialization - until [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $($SONIC_DB_CLI CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -59,7 +61,7 @@ function getBootType() ;; *SONIC_BOOT_TYPE=fast*|*fast-reboot*) # check that the key exists - if [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then + if [[ $($SONIC_DB_CLI STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then TYPE='fast' else TYPE='cold' @@ -161,11 +163,21 @@ stop() { debug "${TYPE} shutdown syncd process ..." /usr/bin/docker exec -i syncd$DEV /usr/bin/syncd_request_shutdown --${TYPE} - # wait until syncd quits gracefully - while docker top syncd$DEV | grep -q /usr/bin/syncd; do + # 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 + 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 @@ -195,10 +207,13 @@ 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="asic$DEV" #name of the network namespace + 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 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..29e6e7776615 100755 --- a/installer/x86_64/install.sh +++ b/installer/x86_64/install.sh @@ -545,8 +545,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 +583,22 @@ EOF $onie_root_dir/tools/bin/onie-boot-mode -q -o install fi -# Add a menu entry for the DEMO OS +# Add a menu entry for the SONiC OS # Note: assume that apparmor is supported in the kernel demo_grub_entry="$demo_volume_revision_label" if [ "$install_env" = "sonic" ]; then old_sonic_menuentry=$(cat /host/grub/grub.cfg | sed "/$running_sonic_revision/,/}/!d") - demo_dev=$(echo $old_sonic_menuentry | sed -e "s/.*root\=\(.*\)rw.*/\1/") + grub_cfg_root=$(echo $old_sonic_menuentry | sed -e "s/.*root\=\(.*\)rw.*/\1/") onie_menuentry=$(cat /host/grub/grub.cfg | sed "/menuentry ONIE/,/}/!d") -fi - -if [ "$install_env" = "build" ]; then +elif [ "$install_env" = "build" ]; then grub_cfg_root=%%SONIC_ROOT%% -else - grub_cfg_root=$demo_dev +else # install_env = "onie" + uuid=$(blkid "$demo_dev" | sed -ne 's/.* UUID=\"\([^"]*\)\".*/\1/p') + if [ -z "$uuid" ]; then + grub_cfg_root=$demo_dev + else + grub_cfg_root=UUID=$uuid + fi fi cat <> $grub_cfg @@ -606,12 +609,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-6-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-6-amd64 } EOF 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..13a3b72a03b7 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-6-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 1abbedffd6c6..57acf3e95d0f 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,4 +1,4 @@ -BFN_PLATFORM = bfnplatform_20200407_deb9.deb +BFN_PLATFORM = bfnplatform_20200610_deb9.deb $(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_PLATFORM)" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index b58cce6fcf47..232c37e7492d 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,4 +1,4 @@ -BFN_SAI = bfnsdk_20200407_deb9.deb +BFN_SAI = bfnsdk_20200610_deb9.deb $(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_SAI)" $(BFN_SAI)_DEPENDS += $(LIBNL_GENL3_DEV) diff --git a/platform/barefoot/docker-ptf-bfn.mk b/platform/barefoot/docker-ptf-bfn.mk index 573e9cd9cffa..752e7345752a 100644 --- a/platform/barefoot/docker-ptf-bfn.mk +++ b/platform/barefoot/docker-ptf-bfn.mk @@ -3,3 +3,4 @@ DOCKER_PTF_BFN = docker-ptf-bfn.gz $(DOCKER_PTF_BFN)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift $(DOCKER_PTF_BFN)_LOAD_DOCKERS += $(DOCKER_PTF) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_BFN) diff --git a/platform/barefoot/docker-syncd-bfn.mk b/platform/barefoot/docker-syncd-bfn.mk index 3a5c693e2fa8..ae4ca9d9f272 100644 --- a/platform/barefoot/docker-syncd-bfn.mk +++ b/platform/barefoot/docker-syncd-bfn.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/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..7083a174c59b 100644 --- a/platform/barefoot/docker-syncd-bfn/supervisord.conf +++ b/platform/barefoot/docker-syncd-bfn/supervisord.conf @@ -3,33 +3,47 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -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 syncd events=PROCESS_STATE_EXITED 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/platform-modules-arista.mk b/platform/barefoot/platform-modules-arista.mk index 28c893b80713..298bc93d9250 100644 --- a/platform/barefoot/platform-modules-arista.mk +++ b/platform/barefoot/platform-modules-arista.mk @@ -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..7d0e0a6cc261 100644 --- a/platform/barefoot/platform-modules-bfn-newport.mk +++ b/platform/barefoot/platform-modules-bfn-newport.mk @@ -9,5 +9,3 @@ $(BFN_NEWPORT_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-module $(BFN_NEWPORT_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(BFN_NEWPORT_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as9516bf_32d-r0 SONIC_DPKG_DEBS += $(BFN_NEWPORT_PLATFORM_MODULE) - -SONIC_STRETCH_DEBS += $(BFN_NEWPORT_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 e9294dd81399..2e45dce8e78b 100644 --- a/platform/barefoot/rules.mk +++ b/platform/barefoot/rules.mk @@ -20,11 +20,13 @@ 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) +#$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(WNC_OSW1800_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) +$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) ifeq ($(ENABLE_SYNCD_RPC),y) $(LIBSAIREDIS)_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 39860a109853..9ea7795ac085 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 39860a109853b2f37367dfe68905e019b509d5bf +Subproject commit 9ea7795ac085452bd14e4146a446ef842152e7de diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control index e3f5356f22db..9a512bd0e143 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn-montara Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control index bc6c990efebb..1538a7041800 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn-newport Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-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/debian/control b/platform/barefoot/sonic-platform-modules-bfn/debian/control index cca87831f1f1..639db9110df5 100644 --- a/platform/barefoot/sonic-platform-modules-bfn/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control index 6070cf9ad1fc..63857c093532 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-6-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.mk b/platform/broadcom/docker-ptf-brcm.mk index 510f21e8a436..35780aea76ca 100644 --- a/platform/broadcom/docker-ptf-brcm.mk +++ b/platform/broadcom/docker-ptf-brcm.mk @@ -5,3 +5,4 @@ $(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) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_BRCM) diff --git a/platform/broadcom/docker-saiserver-brcm.mk b/platform/broadcom/docker-saiserver-brcm.mk index b754ab679884..d587a39ba22c 100644 --- a/platform/broadcom/docker-saiserver-brcm.mk +++ b/platform/broadcom/docker-saiserver-brcm.mk @@ -6,6 +6,7 @@ $(DOCKER_SAISERVER_BRCM)_DEPENDS += $(SAISERVER) $(DOCKER_SAISERVER_BRCM)_FILES += $(DSSERVE) $(BCMCMD) $(DOCKER_SAISERVER_BRCM)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) SONIC_DOCKER_IMAGES += $(DOCKER_SAISERVER_BRCM) +SONIC_STRETCH_DOCKERS += $(DOCKER_SAISERVER_BRCM) $(DOCKER_SAISERVER_BRCM)_CONTAINER_NAME = saiserver $(DOCKER_SAISERVER_BRCM)_RUN_OPT += --net=host --privileged -t diff --git a/platform/broadcom/docker-syncd-brcm.mk b/platform/broadcom/docker-syncd-brcm.mk index d3a6d67c5cbc..71a834ab67df 100644 --- a/platform/broadcom/docker-syncd-brcm.mk +++ b/platform/broadcom/docker-syncd-brcm.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/broadcom/docker-syncd-brcm/Dockerfile.j2 b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 index 1ef1c588777c..ae517eac08ef 100755 --- a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 +++ b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 @@ -21,7 +21,7 @@ debs/ ## TODO: add kmod into Depends RUN apt-get install -yf kmod -COPY ["files/dsserve", "files/bcmcmd", "start.sh", "bcmsh", "/usr/bin/"] +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/"] 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..01d25cded8ea --- /dev/null +++ b/platform/broadcom/docker-syncd-brcm/start_led.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +PLATFORM_DIR=/usr/share/sonic/platform +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 +} + +# 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 +fi + +/usr/bin/bcmcmd -t 60 "rcload /usr/share/sonic/platform/led_proc_init.soc" diff --git a/platform/broadcom/docker-syncd-brcm/supervisord.conf b/platform/broadcom/docker-syncd-brcm/supervisord.conf index 3fa8febb85d8..e0ac48c0a243 100644 --- a/platform/broadcom/docker-syncd-brcm/supervisord.conf +++ b/platform/broadcom/docker-syncd-brcm/supervisord.conf @@ -3,27 +3,39 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -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 syncd events=PROCESS_STATE_EXITED 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 +44,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..86ac56b750b2 100644 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -57,7 +57,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 28c893b80713..ac2c65fdf3c5 100644 --- a/platform/broadcom/platform-modules-arista.mk +++ b/platform/broadcom/platform-modules-arista.mk @@ -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..18fafa3c0c8d 100644 --- a/platform/broadcom/platform-modules-dell.mk +++ b/platform/broadcom/platform-modules-dell.mk @@ -46,7 +46,6 @@ $(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) #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..b947f8a5e7d0 100644 --- a/platform/broadcom/platform-modules-inventec.mk +++ b/platform/broadcom/platform-modules-inventec.mk @@ -40,4 +40,3 @@ 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) 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/sai-modules.mk b/platform/broadcom/sai-modules.mk index 93132c2287bd..5f48efefa19a 100644 --- a/platform/broadcom/sai-modules.mk +++ b/platform/broadcom/sai-modules.mk @@ -1,6 +1,5 @@ # Broadcom SAI modules -KVERSION = 4.9.0-11-2-amd64 BRCM_OPENNSL_KERNEL_VERSION = 3.7.3.3-1 BRCM_OPENNSL_KERNEL = opennsl-modules_$(BRCM_OPENNSL_KERNEL_VERSION)_amd64.deb @@ -8,4 +7,3 @@ $(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.mk b/platform/broadcom/sai.mk index 3d38c760d85b..572ae0a70f68 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,8 @@ -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_3.7.4.2-2_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.4.2-2_amd64.deb?sv=2015-04-05&sr=b&sig=sl819d71a%2BcgrDtOt%2BmywfSL9N2EQS58qMJFq0aKqo8%3D&se=2034-02-11T20%3A28%3A46Z&sp=r" +BRCM_SAI_DEV = libsaibcm-dev_3.7.4.2-2_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.3.3-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/3.7/libsaibcm-dev_3.7.4.2-2_amd64.deb?sv=2015-04-05&sr=b&sig=cvOpP0PWFVmBNeYLMkxyI4BFBQf1DopD32t%2B3AkJHRg%3D&se=2034-02-11T20%3A27%3A46Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) 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/control b/platform/broadcom/saibcm-modules/debian/control index fafe7dfb9299..72542564abf7 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-6-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..fe56bc4cf388 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-6-amd64/extra diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install index 9802d2f2443a..6d1ffa2fc51e 100644 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install @@ -1,6 +1,6 @@ -systems/linux/user/x86-smp_generic_64-2_6/linux-bcm-knet.ko lib/modules/4.9.0-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-6-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-kernel-bde.ko lib/modules/4.19.0-6-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-user-bde.ko lib/modules/4.19.0-6-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-knet-cb.ko lib/modules/4.19.0-6-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/psample.ko lib/modules/4.19.0-6-amd64/extra systemd/opennsl-modules.service lib/systemd/system diff --git a/platform/broadcom/saibcm-modules/debian/rules b/platform/broadcom/saibcm-modules/debian/rules index 636874251aa9..a22bcc4ac6ff 100755 --- a/platform/broadcom/saibcm-modules/debian/rules +++ b/platform/broadcom/saibcm-modules/debian/rules @@ -34,6 +34,7 @@ sname:=opennsl PACKAGE=opennsl-modules # modifieable for experiments or debugging m-a MA_DIR ?= /usr/share/modass +KVERSION ?= 4.19.0-6-amd64 # load generic variable handling -include $(MA_DIR)/include/generic.make # load default rules, including kdist, kdist_image, ... @@ -60,7 +61,10 @@ 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-$(KVERSION) \ + KERNEL_SRC=/usr/src/linux-headers-$(KVERSION) \ + $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean # rm -f driver/*.o driver/*.ko # ### end KERNEL SETUP @@ -78,7 +82,10 @@ build-arch-stamp: dh_testdir # Add here command to compile/build the package. - SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-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-$(KVERSION) \ + KERNEL_SRC=/usr/src/linux-headers-$(KVERSION) \ + $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 touch $@ @@ -103,7 +110,10 @@ clean: rm -f build-arch-stamp build-indep-stamp configure-stamp # Add here commands to clean up after the build process. - SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-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-$(KVERSION) \ + KERNEL_SRC=/usr/src/linux-headers-$(KVERSION) \ + $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean dh_clean 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/utils/accton_as4630_54pe_util.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py index 2f73726f846d..fbfa46377fa2 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 @@ -108,7 +107,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) @@ -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/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/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/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-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/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/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/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-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/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/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/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/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-alphanetworks/debian/control b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control index beba5b5f4e62..55533f735a53 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-6-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-6-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 39860a109853..9ea7795ac085 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 39860a109853b2f37367dfe68905e019b509d5bf +Subproject commit 9ea7795ac085452bd14e4146a446ef842152e7de 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..b69c44beab63 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-6-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-6-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-6-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-6-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.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-haliburton.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install index df78b7a34ea4..4fdfd33f1ec3 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,7 @@ 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 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 100755 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/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/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-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_pmc.c b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c index e8cddf4fad11..da4f451700eb 100644 --- a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c +++ b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c @@ -1785,6 +1785,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; } @@ -2027,6 +2037,8 @@ 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 */ diff --git a/platform/broadcom/sonic-platform-modules-dell/common/ipmihelper.py b/platform/broadcom/sonic-platform-modules-dell/common/ipmihelper.py index 182d74c218cf..046ca21938db 100644 --- a/platform/broadcom/sonic-platform-modules-dell/common/ipmihelper.py +++ b/platform/broadcom/sonic-platform-modules-dell/common/ipmihelper.py @@ -185,33 +185,44 @@ def _get_ipmitool_fru_print(self): 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') + + def get_board_product(self): + """ + Returns a string containing the manufacturer id of the FRU. + """ + return self._get_from_fru('Board Product') - return board_pn.group(1).strip() def get_fru_data(self, offset, count=1): """ 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..b0020144a4fb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/common/sonic_platform/hwaccess.py @@ -0,0 +1,24 @@ +# Helper functions to access hardware + +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) diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/control b/platform/broadcom/sonic-platform-modules-dell/debian/control index e4d5a24f3542..6a0ab0e7d2ac 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/control +++ b/platform/broadcom/sonic-platform-modules-dell/debian/control @@ -7,35 +7,35 @@ 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-6-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-6-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-6-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-6-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-6-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-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9332f Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned 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..74b8bc380199 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 @@ -6,6 +6,7 @@ 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 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 diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/rules b/platform/broadcom/sonic-platform-modules-dell/debian/rules index 3f0f79979886..17627fd4d44e 100755 --- a/platform/broadcom/sonic-platform-modules-dell/debian/rules +++ b/platform/broadcom/sonic-platform-modules-dell/debian/rules @@ -35,6 +35,11 @@ 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); \ + 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; \ + cd $(MOD_SRC_DIR); \ fi; \ echo "making man page alias $$mod -> $$mod APIs";\ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ @@ -82,6 +87,11 @@ 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; \ fi; \ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \ done); \ 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 6f5119044039..7079da825adc 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 @@ -155,6 +155,21 @@ platform_firmware_versions() { r_maj=`/usr/sbin/i2cget -y 600 0x33 0x1 | sed ' s/.*\(0x..\)$/\1/'` echo "Slave CPLD 4: $((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) +} + +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 +} + init_devnum if [ "$1" == "init" ]; then @@ -170,6 +185,7 @@ if [ "$1" == "init" ]; then switch_board_sfp "new_device" switch_board_modsel switch_board_led_default + install_python_api_package python /usr/bin/qsfp_irq_enable.py platform_firmware_versions @@ -178,9 +194,9 @@ elif [ "$1" == "deinit" ]; then switch_board_qsfp "delete_device" switch_board_sfp "delete_device" switch_board_qsfp_mux "delete_device" - switch_board_sfp "delete_device" modprobe -r i2c-mux-pca954x modprobe -r i2c-dev + remove_python_api_package 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..8b137891791f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/__init__.py @@ -0,0 +1 @@ + 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..6acd54d3934b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/chassis.py @@ -0,0 +1,231 @@ +#!/usr/bin/env python + +############################################################################# +# DELLEMC S5232F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + import sys + from __future__ import division + 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.watchdog import Watchdog + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +MAX_S5232F_COMPONENT = 6 # BIOS,BMC,FPGA,SYSTEM CPLD,4 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 = 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() + self._num_sfps = self.PORT_END + self._num_fans = MAX_S5232F_FANTRAY * MAX_S5232F_FAN + self._fan_list = [Fan(i, j) for i in range(MAX_S5232F_FANTRAY) \ + for j in range(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 + """ + port_dict = {} + change_dict = {} + change_dict['sfp'] = port_dict + elapsed_time_ms = 0 + sleep_time_ms = 500 + sleep_time = sleep_time_ms / 1000 + + while True: + 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 != 0: + elapsed_time_ms += sleep_time_ms + if elapsed_time_ms > timeout: + break + + time.sleep(sleep_time) + 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)-1)) + 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 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..bf33bd043d83 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/component.py @@ -0,0 +1,123 @@ +#!/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']).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'] + ).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..eb4a7978fdb3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/eeprom.py @@ -0,0 +1,141 @@ +#!/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 + import binascii +except ImportError, 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 = (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): + """ + 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] + + 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([binascii.b2a_hex(T) for T in t[2]]) + + 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] + + 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] + + 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] + + 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] + + 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..41acae72d88e --- /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": 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: 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 (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 + + 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/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..e7f05a0a17b6 --- /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 "{:.1f}".format(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 "{:.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: + power = 0 + + 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 == 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..adb61113d41e --- /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', 'hardwarerev', 'serialnum', + 'manufacturename', 'modelname', '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'], + 'manufacturename': [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'], + 'vendor_date': [QSFP_INFO_OFFSET, 84, 8, 'parse_vendor_date'], + 'dom_capability': [QSFP_INFO_OFFSET, 92, 1, 'parse_qsfp_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'], + 'manufacturename': [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'], + '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('manufacturename') + 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('modelname') + 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') + 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') + 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['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('modelname') + 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('serialnum') + 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..cc7867917345 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/thermal.py @@ -0,0 +1,155 @@ +#!/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 "{:.3f}".format(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("UpperNonRecoverable") + if not is_valid: + high_threshold = 0 + + return "{:.3f}".format(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 "{:.3f}".format(low_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/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..98fb13b1522f 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,6 +60,20 @@ 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) @@ -86,6 +100,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/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py index 8bb95cac1d63..06fb6c2ff0e9 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 @@ -15,7 +15,7 @@ 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.eeprom import Eeprom, EepromS6000 from sonic_platform.fan import Fan from sonic_platform.psu import Psu from sonic_platform.thermal import Thermal @@ -68,7 +68,14 @@ def __init__(self): # Get Transceiver status self.modprs_register = self._get_transceiver_status() - self._eeprom = Eeprom() + 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_FAN): fan = Fan(i) self._fan_list.append(fan) @@ -138,7 +145,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 +161,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 +169,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): """ @@ -181,7 +188,7 @@ def get_base_mac(self): A string containing the MAC address in the format 'XX:XX:XX:XX:XX:XX' """ - return self._eeprom.base_mac_addr() + return self._eeprom.get_base_mac() def get_serial_number(self): """ @@ -191,7 +198,7 @@ def get_serial_number(self): A string containing the hardware serial number for this chassis. """ - return self._eeprom.serial_number_str() + return self._eeprom.get_serial_number() def get_system_eeprom_info(self): """ @@ -237,13 +244,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 +282,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 +302,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 +313,7 @@ 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 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..1a8a3a84b601 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,17 @@ try: + import binascii import os + 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 = [ @@ -200,13 +205,13 @@ def _get_eeprom_field(self, field_name): 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. """ @@ -222,19 +227,19 @@ def airflow_fan_type(self): return int(self.fan_type.encode('hex'), 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 +252,252 @@ 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 = '\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} {: 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/pcisysfs.py b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/pcisysfs.py new file mode 100755 index 000000000000..767b66f43b63 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/pcisysfs.py @@ -0,0 +1,91 @@ +#! /usr/bin/python + +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) + close(fd) + +def pci_get_value(resource,offset): + fd=open(resource,O_RDWR) + mm=mmap(fd,0) + pci_mem_read(mm,offset) + 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/s6100_bitbang_reset.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_bitbang_reset.sh new file mode 100644 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 index 04cff29ea7af..af91f378339e 100755 --- 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 @@ -245,6 +245,7 @@ if [[ "$1" == "init" ]]; then sys_eeprom "new_device" switch_board_eeprom "new_device" switch_board_cpld "new_device" + /usr/local/bin/s6100_bitbang_reset.sh switch_board_qsfp_mux "new_device" switch_board_sfp "new_device" switch_board_qsfp "new_device" diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py index a1c7692b5f6e..3284e671bfe0 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 @@ -39,6 +39,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 @@ -81,6 +82,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 +113,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 @@ -215,3 +235,103 @@ 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 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..c6f6314dcb6d 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 @@ -138,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): """ @@ -156,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): """ @@ -174,11 +174,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/z9100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py index 3e070d54004e..3f03f9671f91 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,8 +10,8 @@ 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 @@ -60,6 +60,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 +76,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) @@ -112,6 +116,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 +141,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 @@ -162,7 +190,7 @@ def get_serial(self): string: Serial number of chassis """ return self._eeprom.serial_str() - + def get_sfp(self, index): """ Retrieves sfp represented by (1-based) index @@ -252,3 +280,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/thermal.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/thermal.py index 05d012b114c0..e781a545e8ea 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 @@ -134,11 +134,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 +152,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 +170,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/z9264f/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/thermal.py index 58a39005b54e..ab66c59b8600 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): """ @@ -109,7 +109,7 @@ def get_high_threshold(self): if not is_valid: high_threshold = 0 - return "{:.3f}".format(high_threshold) + return float(high_threshold) def get_low_threshold(self): """ @@ -124,7 +124,7 @@ def get_low_threshold(self): if not is_valid: low_threshold = 0 - return "{:.3f}".format(low_threshold) + return float(low_threshold) def set_high_threshold(self, temperature): """ 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-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..e4d4946cce29 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-6-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-6-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-6-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-6-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-6-amd64-unsigned Description: kernel modules for platform devices such as syseeprom, sfp + +Package: platform-modules-agc032 +Architecture: amd64 +Depends: linux-image-4.19.0-6-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/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/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/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..31a6e67d0982 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/control +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/control @@ -7,30 +7,30 @@ Standards-Version: 3.9.3 Package: platform-modules-d7032q28b Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-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-6-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-6-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-6-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-6-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-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led 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..741b6da7b36a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.install @@ -0,0 +1,3 @@ +qfx5200/utils/juniper_qfx5200_util.py usr/local/bin +qfx5200/utils/juniper_qfx5200_monitor.py usr/local/bin +qfx5200/service/qfx5200-platform-init.service etc/systemd/system 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..195f30e66820 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5200.postinst @@ -0,0 +1,31 @@ +#!/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 +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..26e8b06db3aa --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/modules/jnx-refpga-lpcm.c @@ -0,0 +1,117 @@ +/* + * 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) +{ + iounmap(fpga); + release_mem_region(REFPGA_LPC_BASE_ADDRESS, REFPGA_LPC_WINDOW_SIZE); + /* + * Unregister the cpld soft reset handler + */ + if (!unregister_restart_handler(&qfx5200_nb)) { + printk(KERN_CRIT "Failed to uregister restart handler\n"); + } + 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..ec9ebe97f0ee --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/README @@ -0,0 +1,117 @@ + +Copyright (c) 2019, 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 4 fans and each of the fan has 2 fan modules. Overall there are +8 fans in the system. + +Fan controls can be found in /sys/bus/i2c/devices/17-0068. All the fans +are controlled by one duty cycle value, ranges from 0 to 100 + +Fan duty cycle can be controlled through /sys/bus/i2c/devices/17-0068/pwm1 + +Fan module presence is given by /sys/bus/i2c/devices/17-0068/fan[1-4]_present +file. A value of '1' indicate that fan is present & a value of '0' otherwise. + +Fan rotation direction is given by /sys/bus/i2c/devices/17-0068/fan[1-4]_direction. +A value of '0' indicate the direction is AFO (Front to back airflow) or Airflow +out. A value of '1' indicate that direction is AFI (Back to front airflow) or +Airflow in. + +Fan speed is given by fan[1-4]_input + +Temperature sensors +=================== +There are 6 temperature sensors. The readings are available in +/sys/bus/i2c/devices/{0}-00{1}/hwmon/hwmon*/temp1_input + +System PSUs +=========== +There are two independent PSUs. These are controlled by a dedicated CPLD. +The status registers are mapped under /sys/bus/i2c/devices/9-0050 and +/sys/bus/i2c/devices/10-0053. + +SFPs +==== +There are 64 QSFP+ modules supported in qfx5210 platform. EEPORMs will be +mapped under /sys/bus/i2c/devices/[25-88]-0050/ sysfs directory. + +FEC should be turned on for 100G SR optics and should be turned off for +100G LR optics. If the optic is changed, please update the entry and +reload the configuration. If the FEC mode is not set as per the optic +type the port may not link up or work properly. + +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. +If you want to get all the sensor data including the SFPs & LEDs, you can +invoke 'sudo juniper_qfx5210_util.py show' + +Platform poweroff +================= +Linux poweroff commands such as 'poweroff', 'shutdown', 'halt', etc. will not +power off qfx5210 platform as there are custom CPLDs control the power off +sequences. So acpi poweroff hooks are added for powering off the qfx5210. The +following messages are displayed in the console towards end of poweroff +sequence: + + [ 52.500807] System halt/power_off + [ 52.866331] reboot: Power down + [ 52.903257] pm_power_off: qfx5210_cpld_power_off + +Once the above messages are seen, you can safely remove the power to the system. + +Similarly 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: qfx5210_cpld_soft_reset + +Platform monitoring daemon +========================== +“juniper_qfx5210_monitor.py” is the platform monitoring script. +It implements the qfx5210 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. + 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..9620b4e9de43 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_monitor.py @@ -0,0 +1,1033 @@ +#!/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 +isFireThresholdReached = False +isFireThresholdPrint = True +FireThresholdSecsRemaining = 120 +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' + + """ 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 isFireThresholdReached + global FireThresholdSecsRemaining + global isFireThresholdPrint + 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], + } + # if the Firethreshold Flag is set and 120 seconds have elapsed, invoking the "poweroff" to shutdown the box + if (isFireThresholdReached == True): + firethr = FireThresholdSecsRemaining - 20 + if firethr == 0: + logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown now') + os.system("echo 'CRITICAL: Fire Threshold reached: System is going to shutdown now' > /dev/console") + else: + logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown in %s seconds', firethr) + os.system("echo 'CRITICAL: Fire Threshold reached: System is going to shutdown in %s seconds' > /dev/console" % firethr) + + FireThresholdSecsRemaining = FireThresholdSecsRemaining - 20 + logging.critical('CRITICAL: Value of FireThresholdSecsRemaining %s seconds', FireThresholdSecsRemaining) + + if (FireThresholdSecsRemaining == 0): + isFireThresholdReached == False + time.sleep(20) + logging.debug('Executing poweroff command') + cmd = "poweroff" + os.system(cmd) + + 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]): + + isFireThresholdReached = True + + if (isFireThresholdPrint == True): + logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown in 120 seconds') + os.system("echo 'CRITICAL: Fire Threshold reached: System is going to shutdown in 120 seconds' > /dev/console") + isFireThresholdPrint = False + + self.set_alarm_led_brightness(2) + logging.debug('Setting Red Alarm as one temp sensor is running at soft shutdown temp value') + + # 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]): + + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + 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]): + + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + 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]): + + if (isFireThresholdReached == True): + 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]): + pass + else: + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + 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]): + + if (isFireThresholdReached == True): + 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]): + pass + else: + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + 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]): + + if (isFireThresholdReached == True): + 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]): + pass + else: + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + 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]): + + if (isFireThresholdReached == True): + 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]): + pass + else: + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + 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]): + + if (isFireThresholdReached == True): + 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]): + pass + else: + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + 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]): + + if (isFireThresholdReached == True): + 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]): + pass + else: + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + 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]): + + if (isFireThresholdReached == True): + 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]): + pass + else: + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + 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]): + + if (isFireThresholdReached == True): + + 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]): + pass + else: + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + 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]): + + if (isFireThresholdReached == True): + + 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]): + pass + else: + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + 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, + filemode='w', + level=log_level, + format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', + datefmt='%H:%M:%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/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/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/utils/juniper_qfx5210_monitor.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py index dbf0b831248f..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,27 +545,26 @@ 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+') @@ -605,9 +588,7 @@ def manage_device(self): 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..26eed74c944a 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(): diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/setup.py b/platform/broadcom/sonic-platform-modules-juniper/setup.py similarity index 57% rename from platform/broadcom/sonic-platform-modules-juniper/qfx5210/setup.py rename to platform/broadcom/sonic-platform-modules-juniper/setup.py index 536f814a3509..283c00d3860f 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/setup.py +++ b/platform/broadcom/sonic-platform-modules-juniper/setup.py @@ -8,9 +8,9 @@ setup( name='sonic_platform', version='1.0', - description='Module to initialize Juniper QFX5210-64X platforms', + description='Module to initialize Juniper platforms', packages=['sonic_platform'], - package_dir={'sonic_platform': 'qfx5210/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/qfx5210/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/chassis.py similarity index 54% rename from platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/chassis.py rename to platform/broadcom/sonic-platform-modules-juniper/sonic_platform/chassis.py index 674d9184df3c..0e3d43fa07e4 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/chassis.py @@ -5,7 +5,7 @@ # Description: Module contains the definitions of SONiC platform APIs # which provide the chassis specific details # -# Copyright (c) 2019, Juniper Networks, Inc. +# Copyright (c) 2020, Juniper Networks, Inc. # All rights reserved. # # Notice and Disclaimer: This code is licensed to you under the GNU General @@ -39,26 +39,24 @@ 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" -class Chassis(ChassisBase): - """ - JUNIPER QFX5210 Platform-specific Chassis class - """ +def log_info(msg): + syslog.openlog(SYSLOG_IDENTIFIER) + syslog.syslog(syslog.LOG_INFO, msg) + syslog.closelog() - # Find the last reboot reason out of following - # CPLD_WATCHDOG_RESET 0x08 - # POWER_ON_RESET 0x20 - # CPU_WATCHDOG_RESET 0x40 - # SOFTWARE_RESET 0x80 +class Chassis(ChassisBase): def __init__(self): ChassisBase.__init__(self) - def get_qfx5210_parameter_value(self,parameter_name): + def get_parameter_value(self,parameter_name): try: with open("/var/run/eeprom", "r") as file: for item in file: @@ -71,7 +69,7 @@ def get_qfx5210_parameter_value(self,parameter_name): return "False" def get_product_name(self): - product_name_list = self.get_qfx5210_parameter_value('Product Name') + product_name_list = self.get_parameter_value('Product Name') if product_name_list: product_name = ''.join(product_name_list) return product_name @@ -80,7 +78,7 @@ def get_product_name(self): def get_part_number(self): - part_number_list = self.get_qfx5210_parameter_value('Part Number') + part_number_list = self.get_parameter_value('Part Number') if part_number_list: part_number = ''.join(part_number_list) return part_number @@ -89,7 +87,7 @@ def get_part_number(self): def get_serial_number(self): - serial_number_list = self.get_qfx5210_parameter_value('Serial Number') + serial_number_list = self.get_parameter_value('Serial Number') if serial_number_list: serial_number = ''.join(serial_number_list) return serial_number @@ -98,7 +96,7 @@ def get_serial_number(self): def get_base_mac(self): - mac_list = self.get_qfx5210_parameter_value('MAC') + mac_list = self.get_parameter_value('MAC') if mac_list: mac = ''.join(mac_list) return mac @@ -107,7 +105,7 @@ def get_base_mac(self): def get_mfg_date(self): - mfgdate_list = self.get_qfx5210_parameter_value('Manufacture Date') + mfgdate_list = self.get_parameter_value('Manufacture Date') if mfgdate_list: mfgdate = ''.join(mfgdate_list) return mfgdate @@ -115,7 +113,7 @@ def get_mfg_date(self): return False def get_deviceversion_name(self): - device_version_list = self.get_qfx5210_parameter_value('Device Version') + device_version_list = self.get_parameter_value('Device Version') if device_version_list: deviceversion_name = ''.join(device_version_list) return deviceversion_name @@ -123,7 +121,7 @@ def get_deviceversion_name(self): return False def get_platform_name(self): - platform_name_list = self.get_qfx5210_parameter_value('Platform Name') + platform_name_list = self.get_parameter_value('Platform Name') if platform_name_list: platform_name = ''.join(platform_name_list) return platform_name @@ -131,7 +129,7 @@ def get_platform_name(self): return False def get_MACnumber_name(self): - MACnumber_name_list = self.get_qfx5210_parameter_value('Number of MAC Addresses') + MACnumber_name_list = self.get_parameter_value('Number of MAC Addresses') if MACnumber_name_list: MACnumber_name = ''.join(MACnumber_name_list) return MACnumber_name @@ -139,7 +137,7 @@ def get_MACnumber_name(self): return False def get_vendor_name(self): - vendor_name_list = self.get_qfx5210_parameter_value('Vendor Name') + vendor_name_list = self.get_parameter_value('Vendor Name') if vendor_name_list: vendor_name = ''.join(vendor_name_list) return vendor_name @@ -147,7 +145,7 @@ def get_vendor_name(self): return False def get_mfg_name(self): - mfg_name_list = self.get_qfx5210_parameter_value('Manufacture Name') + mfg_name_list = self.get_parameter_value('Manufacture Name') if mfg_name_list: mfg_name = ''.join(mfg_name_list) return mfg_name @@ -155,7 +153,7 @@ def get_mfg_name(self): return False def get_vendorext_name(self): - vendorext_list = self.get_qfx5210_parameter_value('Vendor Extension') + vendorext_list = self.get_parameter_value('Vendor Extension') if vendorext_list: vendorext = ''.join(vendorext_list) return vendorext @@ -163,7 +161,7 @@ def get_vendorext_name(self): return False def get_vendorextIANA_name(self): - vendorext_list = self.get_qfx5210_parameter_value('IANA') + vendorext_list = self.get_parameter_value('IANA') if vendorext_list: vendorext = ''.join(vendorext_list) return vendorext @@ -171,7 +169,7 @@ def get_vendorextIANA_name(self): return False def get_vendorextASMREV_name(self): - vendorext_list = self.get_qfx5210_parameter_value('Assembly Part Number Rev') + vendorext_list = self.get_parameter_value('Assembly Part Number Rev') if vendorext_list: vendorext = ''.join(vendorext_list) return vendorext @@ -179,7 +177,7 @@ def get_vendorextASMREV_name(self): return False def get_vendorextASMPartNum_name(self): - vendorext_list = self.get_qfx5210_parameter_value('Assembly Part Number') + vendorext_list = self.get_parameter_value('Assembly Part Number') if vendorext_list: vendorext = ''.join(vendorext_list) return vendorext @@ -187,7 +185,7 @@ def get_vendorextASMPartNum_name(self): return False def get_vendorextASMID_name(self): - vendorext_list = self.get_qfx5210_parameter_value('Assembly ID') + vendorext_list = self.get_parameter_value('Assembly ID') if vendorext_list: vendorext = ''.join(vendorext_list) return vendorext @@ -195,7 +193,7 @@ def get_vendorextASMID_name(self): return False def get_vendorextASMMajNum_name(self): - vendorext_list = self.get_qfx5210_parameter_value('Assembly Major Revision') + vendorext_list = self.get_parameter_value('Assembly Major Revision') if vendorext_list: vendorext = ''.join(vendorext_list) return vendorext @@ -203,7 +201,7 @@ def get_vendorextASMMajNum_name(self): return False def get_vendorextASMMinNum_name(self): - vendorext_list = self.get_qfx5210_parameter_value('Assembly Minor Revision') + vendorext_list = self.get_parameter_value('Assembly Minor Revision') if vendorext_list: vendorext = ''.join(vendorext_list) return vendorext @@ -211,7 +209,7 @@ def get_vendorextASMMinNum_name(self): return False def get_vendorextCLEI_name(self): - vendorext_list = self.get_qfx5210_parameter_value('CLEI code') + vendorext_list = self.get_parameter_value('CLEI code') if vendorext_list: vendorext = ''.join(vendorext_list) return vendorext @@ -219,7 +217,7 @@ def get_vendorextCLEI_name(self): return False def get_onieversion_name(self): - onieversion_name_list = self.get_qfx5210_parameter_value('ONIE Version') + onieversion_name_list = self.get_parameter_value('ONIE Version') if onieversion_name_list: onieversion_name = ''.join(onieversion_name_list) return onieversion_name @@ -227,51 +225,75 @@ def get_onieversion_name(self): return False def get_crc_name(self): - crc_list = self.get_qfx5210_parameter_value('CRC') + crc_list = self.get_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") + 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: - return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") + 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, last_reboot_reason = commands.getstatusoutput("busybox devmem 0xFED50004 8") + 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("busybox devmem 0xFED50004 8") + 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") + log_info("Juniper QFX5200 and QFX5210 platforms are supported") diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/platform.py similarity index 71% rename from platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/platform.py rename to platform/broadcom/sonic-platform-modules-juniper/sonic_platform/platform.py index 5620fec54f65..c3a596111d38 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/platform.py +++ b/platform/broadcom/sonic-platform-modules-juniper/sonic_platform/platform.py @@ -2,10 +2,10 @@ # # Name: platform.py, version: 1.0 # -# Description: Module contains the definitions of SONiC platform APIs +# Description: Module contains the definition of SONiC platform API # which provide the platform specific details # -# Copyright (c) 2019, Juniper Networks, Inc. +# Copyright (c) 2020, Juniper Networks, Inc. # All rights reserved. # # Notice and Disclaimer: This code is licensed to you under the GNU General @@ -39,29 +39,14 @@ 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) -platformDict = {'platform':'QFX5210-64C'} - class Platform(PlatformBase): + """ + Juniper Platform-specific class + """ 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 - + 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..b693fb382a89 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-6-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..233aa9ec7baf 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-6-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 index 4665345586a8..ea96fd050bfe 100644 --- a/platform/cavium/docker-ptf-cavm.mk +++ b/platform/cavium/docker-ptf-cavm.mk @@ -5,3 +5,4 @@ $(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) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_CAVM) diff --git a/platform/centec/centec-dal/Makefile b/platform/centec/centec-dal/Makefile new file mode 100644 index 000000000000..1140f6b2f93e --- /dev/null +++ b/platform/centec/centec-dal/Makefile @@ -0,0 +1,2 @@ +obj-m := dal.o +dal-y := dal_kernel.o dal_mpool.o diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.c b/platform/centec/centec-dal/dal_kernel.c similarity index 98% rename from platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.c rename to platform/centec/centec-dal/dal_kernel.c index 32a38f842cfa..e47178d1496f 100644 --- a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.c +++ b/platform/centec/centec-dal/dal_kernel.c @@ -580,25 +580,6 @@ _dal_set_msi_enabe(unsigned int lchip, unsigned int irq_num) 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; } diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.h b/platform/centec/centec-dal/dal_kernel.h similarity index 100% rename from platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.h rename to platform/centec/centec-dal/dal_kernel.h diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.c b/platform/centec/centec-dal/dal_mpool.c similarity index 100% rename from platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.c rename to platform/centec/centec-dal/dal_mpool.c diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.h b/platform/centec/centec-dal/dal_mpool.h similarity index 100% rename from platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.h rename to platform/centec/centec-dal/dal_mpool.h diff --git a/platform/centec/docker-ptf-centec.mk b/platform/centec/docker-ptf-centec.mk index ff84ed0becb7..47284f71756c 100644 --- a/platform/centec/docker-ptf-centec.mk +++ b/platform/centec/docker-ptf-centec.mk @@ -2,6 +2,7 @@ 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)_DEPENDS += $(PYTHON_SAITHRIFT) $(DOCKER_PTF_CENTEC)_LOAD_DOCKERS += $(DOCKER_PTF) SONIC_DOCKER_IMAGES += $(DOCKER_PTF_CENTEC) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_CENTEC) diff --git a/platform/centec/docker-syncd-centec-rpc.mk b/platform/centec/docker-syncd-centec-rpc.mk index 47c672dd93de..8915f1c35679 100644 --- a/platform/centec/docker-syncd-centec-rpc.mk +++ b/platform/centec/docker-syncd-centec-rpc.mk @@ -10,14 +10,15 @@ $(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) +SONIC_STRETCH_DOCKERS += $(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.mk b/platform/centec/docker-syncd-centec.mk index a0dbcc629dee..ada63a218d4a 100644 --- a/platform/centec/docker-syncd-centec.mk +++ b/platform/centec/docker-syncd-centec.mk @@ -1,23 +1,19 @@ # 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 +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BASE) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SYNCD_BASE_DBG) + +$(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..f6c875bab1cc 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-stretch ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf @@ -20,11 +20,10 @@ 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 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..dc6977ed4710 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:dependent-startup] +command=python -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 syncd 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 +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..366080f04114 --- /dev/null +++ b/platform/centec/platform-modules-embedway.mk @@ -0,0 +1,13 @@ +# 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_STRETCH_DEBS += $(EMBEDWAY_ES6220_PLATFORM_MODULE) +SONIC_DPKG_DEBS += $(EMBEDWAY_ES6220_PLATFORM_MODULE) \ No newline at end of file diff --git a/platform/centec/rules.mk b/platform/centec/rules.mk index 53759cb67f40..6f3ac98ecab4 100644 --- a/platform/centec/rules.mk +++ b/platform/centec/rules.mk @@ -1,4 +1,5 @@ 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 @@ -6,14 +7,12 @@ 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 sairedis $(LIBSAIREDIS)_DEPENDS += $(CENTEC_SAI) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV_CENTEC) +$(LIBSAIREDIS)_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..5a5c888e0b09 100644 --- a/platform/centec/sdk.mk +++ b/platform/centec/sdk.mk @@ -1,5 +1,5 @@ # 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.1_amd64.deb +$(CENTEC_SAI)_URL = https://github.com/CentecNetworks/sonic-binaries/raw/master/amd64/libsai_1.6.1-1.0_amd64.deb 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/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..1c31c94244ec 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-6-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-6-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..044c847ddad6 --- /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-6-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 index 6c81734676fd..53ba41e9d386 100755 --- a/platform/innovium/docker-ptf-invm.mk +++ b/platform/innovium/docker-ptf-invm.mk @@ -5,3 +5,4 @@ $(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) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_INVM) 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..27054e23e472 100755 --- a/platform/innovium/docker-syncd-invm/Dockerfile.j2 +++ b/platform/innovium/docker-syncd-invm/Dockerfile.j2 @@ -24,7 +24,6 @@ RUN dpkg -i \ debs/{{ deb }}{{' '}} {%- endfor %} -COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] ## Clean up 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..a614d68f2890 100755 --- a/platform/innovium/docker-syncd-invm/supervisord.conf +++ b/platform/innovium/docker-syncd-invm/supervisord.conf @@ -3,26 +3,29 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true -[program:start.sh] -command=/usr/bin/start.sh -priority=1 +[eventlistener:dependent-startup] +command=python -m supervisord_dependent_startup autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE [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..9f013208201b 100755 --- a/platform/innovium/invm-sai.mk +++ b/platform/innovium/invm-sai.mk @@ -11,4 +11,3 @@ $(INVM_HSAI)_URL = $(INVM_SAI_ONLINE)/$(INVM_HSAI) $(INVM_DRV)_URL = $(INVM_SAI_ONLINE)/$(INVM_DRV) 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/sonic-platform-modules-cel/debian/control b/platform/innovium/sonic-platform-modules-cel/debian/control index 543d381ab6f7..30baa323c36a 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-6-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..7395157d35f8 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-6-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 index 69dff4a90dd4..72c860aec868 100644 --- a/platform/marvell-arm64/docker-ptf-mrvl.mk +++ b/platform/marvell-arm64/docker-ptf-mrvl.mk @@ -5,3 +5,4 @@ $(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) +SONIC_STRETCH_DOCKERS += $(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.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..5f5097f4b4aa 100755 --- a/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 @@ -26,9 +26,8 @@ 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 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..e1fd242b4e6d 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf @@ -3,27 +3,28 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -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 syncd 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 +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 +33,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-armhf/docker-ptf-mrvl.mk b/platform/marvell-armhf/docker-ptf-mrvl.mk index 69dff4a90dd4..72c860aec868 100644 --- a/platform/marvell-armhf/docker-ptf-mrvl.mk +++ b/platform/marvell-armhf/docker-ptf-mrvl.mk @@ -5,3 +5,4 @@ $(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) +SONIC_STRETCH_DOCKERS += $(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.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..5f5097f4b4aa 100755 --- a/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 @@ -26,9 +26,8 @@ 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 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..0adb188ce329 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf @@ -3,32 +3,35 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -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 syncd 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 +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/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/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..5679fb38e338 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/"] 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..12752786ebba 100644 --- a/platform/marvell/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell/docker-syncd-mrvl/supervisord.conf @@ -3,27 +3,28 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -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 syncd 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 +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 +33,5 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog - +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running diff --git a/platform/mellanox/docker-ptf-mlnx.dep b/platform/mellanox/docker-ptf-mlnx.dep new file mode 100644 index 000000000000..652fe0001c76 --- /dev/null +++ b/platform/mellanox/docker-ptf-mlnx.dep @@ -0,0 +1,10 @@ +# DPKG FRK + +DPATH := $($(DOCKER_PTF_MLNX)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/docker-ptf-mlnx.mk $(PLATFORM_PATH)/docker-ptf-mlnx.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files -- $(DPATH)) + +$(DOCKER_PTF_MLNX)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_PTF_MLNX)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_PTF_MLNX)_DEP_FILES := $(DEP_FILES) diff --git a/platform/mellanox/docker-ptf-mlnx.mk b/platform/mellanox/docker-ptf-mlnx.mk index f6d17e72fcfe..eaaa54897d80 100644 --- a/platform/mellanox/docker-ptf-mlnx.mk +++ b/platform/mellanox/docker-ptf-mlnx.mk @@ -5,3 +5,4 @@ $(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) +SONIC_STRETCH_DOCKERS += $(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-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.dep b/platform/mellanox/docker-syncd-mlnx.dep new file mode 100644 index 000000000000..b8bdfdf625b7 --- /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 +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.mk b/platform/mellanox/docker-syncd-mlnx.mk index 9bdc5a8ad8ec..c89d8dbc4ddc 100644 --- a/platform/mellanox/docker-syncd-mlnx.mk +++ b/platform/mellanox/docker-syncd-mlnx.mk @@ -14,5 +14,8 @@ ifeq ($(SDK_FROM_SRC), y) $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(MLNX_SDK_DBG_DEBS) $(MLNX_SAI_DBGSYM) endif +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/mellanox/docker-syncd-mlnx/Dockerfile.j2 b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 index 6953933735fa..c2cfc9edbbdd 100755 --- a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 +++ b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 @@ -35,7 +35,6 @@ 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/"] 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..dc6977ed4710 100644 --- a/platform/mellanox/docker-syncd-mlnx/supervisord.conf +++ b/platform/mellanox/docker-syncd-mlnx/supervisord.conf @@ -3,32 +3,35 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -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 syncd 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 +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..115d3e5f4726 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.2007.1244 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2007.0322 +MLNX_SPC2_FW_VERSION = 29.2007.1244 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) -MLNX_SPC3_FW_VERSION = 30.2007.0322 +MLNX_SPC3_FW_VERSION = 30.2007.1244 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,6 +34,8 @@ else SONIC_ONLINE_FILES += $(MLNX_FW_FILES) endif +MLNX_FILES += $(MLNX_FW_FILES) + export MLNX_SPC_FW_VERSION export MLNX_SPC_FW_FILE @@ -42,5 +44,3 @@ export MLNX_SPC2_FW_FILE export MLNX_SPC3_FW_VERSION export MLNX_SPC3_FW_FILE - -export MLNX_FW_FILES diff --git a/platform/mellanox/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..eb90cf16d4f2 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.1000 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-Disable-hw-management-thermal-control-shell-script.patch b/platform/mellanox/hw-management/0001-Disable-hw-management-thermal-control-shell-script.patch new file mode 100644 index 000000000000..eef970ed23c7 --- /dev/null +++ b/platform/mellanox/hw-management/0001-Disable-hw-management-thermal-control-shell-script.patch @@ -0,0 +1,28 @@ +From 3bce9e33132a86c0a53a7b0a49ee1932d65bfb7f Mon Sep 17 00:00:00 2001 +From: junchao +Date: Wed, 6 May 2020 11:37:56 +0800 +Subject: [PATCH] Disable hw-management thermal control shell script + +--- + usr/usr/bin/hw-management.sh | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/usr/usr/bin/hw-management.sh b/usr/usr/bin/hw-management.sh +index 65e5d39..cffff7a 100755 +--- a/usr/usr/bin/hw-management.sh ++++ b/usr/usr/bin/hw-management.sh +@@ -832,7 +832,10 @@ do_start() + if [ -f $config_path/max_tachos ]; then + max_tachos=$(<$config_path/max_tachos) + fi +- $THERMAL_CONTROL $thermal_type $max_tachos $max_psus& ++ ++ # Disable thermal control shell script in hw-management ++ # 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/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/hw-mgmt b/platform/mellanox/hw-management/hw-mgmt index 2f659142ab3b..cdacf1e932f9 160000 --- a/platform/mellanox/hw-management/hw-mgmt +++ b/platform/mellanox/hw-management/hw-mgmt @@ -1 +1 @@ -Subproject commit 2f659142ab3b4deb58989a2ca38b0b1671600509 +Subproject commit cdacf1e932f929c8dedde6c7e14759a2083aac66 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 229ba86b4a7b..605944cd5074 100644 --- a/platform/mellanox/mft.mk +++ b/platform/mellanox/mft.mk @@ -1,7 +1,7 @@ # Mellanox SAI -MFT_VERSION = 4.14.0 -MFT_REVISION = 500 +MFT_VERSION = 4.14.1 +MFT_REVISION = 8 export MFT_VERSION MFT_REVISION @@ -15,5 +15,3 @@ $(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..2e28536c4fd0 100644 --- a/platform/mellanox/mft/Makefile +++ b/platform/mellanox/mft/Makefile @@ -27,6 +27,6 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # 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) + mv $(MFT_NAME)/SDEBS/ubuntu-drivers/4.19.0/kernel-mft-dkms_$(MFT_VERSION)-$(KVERSION)_all.deb $(MFT_NAME)/DEBS/* $(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-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..5a62e74b647b --- /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..865fe2a7ee4d --- /dev/null +++ b/platform/mellanox/mlnx-platform-api.dep @@ -0,0 +1,11 @@ +# 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)) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 995d5cc8ae57..567f5f0c541d 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -12,10 +12,10 @@ 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_device_util import get_platform_info from sonic_daemon_base.daemon_base import Logger from os import listdir from os.path import isfile, join - from glob import glob import sys import io import re @@ -29,6 +29,7 @@ MLNX_NUM_PSU = 2 GET_HWSKU_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.hwsku" +GET_PLATFORM_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.platform" EEPROM_CACHE_ROOT = '/var/cache/sonic/decode-syseeprom' EEPROM_CACHE_FILE = 'syseeprom_cache' @@ -47,10 +48,10 @@ # 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, 'ACS-MSN4700': 0} -port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1)] +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} +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""" @@ -58,13 +59,17 @@ class Chassis(ChassisBase): def __init__(self): super(Chassis, self).__init__() - # Initialize SKU name + # Initialize SKU name and Platform name self.sku_name = self._get_sku_name() + self.platform_name = self._get_platform_name() + mi = get_machine_info() if mi is not None: self.name = mi['onie_platform'] + self.platform_name = get_platform_info(mi) else: self.name = self.sku_name + self.platform_name = self._get_platform_name() # move the initialization of each components to their dedicated initializer # which will be called from platform @@ -84,36 +89,29 @@ def initialize_psu(self): # 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, False, self.sku_name) - else: - fan = Fan(has_fan_dir, index, index, False, self.sku_name) - 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) + fan_index += 1 + drawer._fan_list.append(fan) + self._fan_list.append(fan) def initialize_sfp(self): @@ -122,7 +120,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] @@ -141,7 +139,7 @@ def initialize_sfp(self): def initialize_thermals(self): from sonic_platform.thermal import initialize_thermals # Initialize thermals - initialize_thermals(self.sku_name, self._thermal_list, self._psu_list) + initialize_thermals(self.platform_name, self._thermal_list, self._psu_list) def initialize_eeprom(self): @@ -152,7 +150,9 @@ def initialize_eeprom(self): 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.extend(ComponentCPLD.get_component_list()) @@ -245,8 +245,13 @@ def _get_sku_name(self): 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_platform_name(self): + p = subprocess.Popen(GET_PLATFORM_CMD, shell=True, stdout=subprocess.PIPE) + out, err = p.communicate() + return out.rstrip('\n') + + def _get_port_position_tuple_by_platform_name(self): + position_tuple = port_position_tuple_list[platform_dict_port[self.platform_name]] return position_tuple @@ -448,25 +453,12 @@ def get_change_event(self, timeout=0): timeout = MAX_SELECT_DELAY while True: status = self.sfp_event.check_sfp_status(port_dict, timeout) - if not port_dict == {}: + if bool(port_dict): break else: status = self.sfp_event.check_sfp_status(port_dict, timeout) if status: - # get_change_event has the meaning of retrieving all the notifications through a single call. - # Typically this is implemented via a select framework which requires the underlay file-reading - # interface able to retrieve all notifications without blocking once the fd has been selected. - # However, sdk doesn't provide any interface satisfied the requirement. as a result, - # check_sfp_status returns only one notification may indicate more notifications in its queue. - # In this sense, we have to iterate in a loop to get all the notifications in case that - # the first call returns at least one. - i = 0 - while i < self.MAX_SELECT_EVENT_RETURNED: - status = self.sfp_event.check_sfp_status(port_dict, 0) - if not status: - break - i = i + 1 return True, {'sfp':port_dict} else: return True, {'sfp':{}} diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index 70fd96023b8c..0552e09ae5f5 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -6,20 +6,308 @@ # 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 + import ConfigParser + + from sonic_platform_base.component_base import ComponentBase except ImportError as e: raise ImportError(str(e) + "- required module not found") -ZERO = '0' -NEWLINE = '\n' + +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()) + + 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()) + + 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).rstrip('\n') + + os.mkdir(fs_mountpoint) + cmd = "mount -n -r -t ext4 {} {}".format(fs_path, fs_mountpoint) + subprocess.check_call(cmd, shell=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) + + 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()) + 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()) + 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()) + 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).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).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).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): @@ -27,27 +315,12 @@ def __init__(self): 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): - """ - Retrieves the description of the component - - Returns: - A string containing the description of the component - """ return self.description - @staticmethod def _read_generic_file(filename, len, ignore_errors=False): """ @@ -64,7 +337,6 @@ def _read_generic_file(filename, len, ignore_errors=False): return result - @staticmethod def _get_command_result(cmdline): try: @@ -80,149 +352,246 @@ def _get_command_result(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): - COMPONENT_NAME = 'BIOS' - COMPONENT_DESCRIPTION = 'BIOS - Basic Input/Output System' - COMPONENT_FIRMWARE_EXTENSION = '.rom' + ONIE_IMAGE_VERSION_ATTR = 'image_version' - # 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' + def __init__(self): + super(ComponentONIE, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + self.onie_updater = ONIEUpdater() + + def __install_firmware(self, image_path): + if not self._check_file_validity(image_path): + return False + + 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 + + return True + + def get_firmware_version(self): + return self.onie_updater.get_onie_version() - 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 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)) - 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' + return firmware_info[self.ONIE_IMAGE_VERSION_ATTR] - BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' + 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): + super(ComponentSSD, self).__init__() + self.name = self.COMPONENT_NAME self.description = self.COMPONENT_DESCRIPTION self.image_ext_name = self.COMPONENT_FIRMWARE_EXTENSION + def __install_firmware(self, image_path): + if not self._check_file_validity(image_path): + return False + + cmd = self.SSD_FIRMWARE_UPDATE_COMMAND.format(image_path) + + try: + print("INFO: Installing {} firmware update".format(self.name)) + subprocess.check_call(cmd.split()) + 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 + + try: + output = subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT).rstrip('\n') + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to get {} info: {}".format(self.name, str(e))) - Returns: - A string containing the firmware version of the component + for line in output.splitlines(): + if line.startswith(self.FIRMWARE_VERSION_ATTR): + return line.split(':')[1].lstrip(' \t') - 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. + raise RuntimeError("Failed to parse {} version".format(self.name)) - Handle 0x0022, DMI type 11, 5 bytes - OEM Strings - String 1:*0ABZS017_02.02.002* - String 2: To Be Filled By O.E.M. + 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).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).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).rstrip('\n') + except subprocess.CalledProcessError as e: + raise RuntimeError("Failed to get {} version: {}".format(self.name, str(e))) + + return version + + def get_available_firmware_version(self, image_path): + raise NotImplementedError("{} component doesn't support firmware version query".format(self.name)) + + 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 ComponentCPLD(Component): @@ -230,39 +599,67 @@ class ComponentCPLD(Component): COMPONENT_DESCRIPTION = 'CPLD - Complex Programmable Logic Device' COMPONENT_FIRMWARE_EXTENSION = '.vme' + MST_DEVICE_PATH = '/dev/mst' + MST_DEVICE_PATTERN = 'mt[0-9]*_pci_cr0' + CPLD_NUMBER_FILE = '/var/run/hw-management/config/cpld_num' CPLD_PART_NUMBER_FILE = '/var/run/hw-management/system/cpld{}_pn' CPLD_VERSION_FILE = '/var/run/hw-management/system/cpld{}_version' - CPLD_VERSION_MINOR_FILE = '/var/run/hw-management/system/cpld{}_version_minor' + CPLD_VERSION_MINOR_FILE = '/var/run/hw-management/system/cpld{}_version_min' CPLD_NUMBER_MAX_LENGTH = 1 CPLD_PART_NUMBER_MAX_LENGTH = 6 CPLD_VERSION_MAX_LENGTH = 2 CPLD_VERSION_MINOR_MAX_LENGTH = 2 - CPLD_PART_NUMBER_DEFAULT = ZERO - CPLD_VERSION_MINOR_DEFAULT = ZERO + CPLD_PART_NUMBER_DEFAULT = '0' + CPLD_VERSION_MINOR_DEFAULT = '0' - CPLD_UPDATE_COMMAND = 'cpldupdate --dev {} {}' - CPLD_INSTALL_SUCCESS_FLAG = 'PASS!' - - MST_DEVICE_PATTERN = '/dev/mst/mt[0-9]*_pci_cr0' + CPLD_FIRMWARE_UPDATE_COMMAND = 'cpldupdate --dev {} --print-progress {}' 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 + + pattern = os.path.join(self.MST_DEVICE_PATH, self.MST_DEVICE_PATTERN) - def get_firmware_version(self): - """ - Retrieves the firmware version of the component + 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 - Returns: - A string containing the firmware version of the component - """ + return mst_dev_list[0] + def __install_firmware(self, image_path): + if not self._check_file_validity(image_path): + return False + + mst_dev = self.__get_mst_device() + if mst_dev is None: + return False + + cmd = self.CPLD_FIRMWARE_UPDATE_COMMAND.format(mst_dev, image_path) + + try: + print("INFO: Installing {} firmware update: path={}".format(self.name, image_path)) + subprocess.check_call(cmd.split()) + 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): 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) @@ -277,96 +674,52 @@ def get_firmware_version(self): if version_minor is None: version_minor = self.CPLD_VERSION_MINOR_DEFAULT - part_number = part_number.rstrip(NEWLINE).zfill(self.CPLD_PART_NUMBER_MAX_LENGTH) - version = version.rstrip(NEWLINE).zfill(self.CPLD_VERSION_MAX_LENGTH) - version_minor = version_minor.rstrip(NEWLINE).zfill(self.CPLD_VERSION_MINOR_MAX_LENGTH) + 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)) - def _get_mst_device(self): - mst_dev_list = glob(self.MST_DEVICE_PATTERN) - if mst_dev_list is None or len(mst_dev_list) != 1: - return None - return mst_dev_list - - - def install_firmware(self, image_path): - """ - Installs firmware to the component - - Args: - image_path: A string, path to firmware image - - Returns: - A boolean, True if install was successful, False if not - - Details: - The command "cpldupdate" is provided to install CPLD. There are two ways to do it: - 1. To burn CPLD via gpio, which is faster but only supported on new systems, like Anaconda, ... - 2. To install CPLD via firmware, which is slower but supported on older systems. - This also requires the mst device designated. - "cpldupdate --dev " has the logic of testing whether to update via gpio is supported, - and if so then go this way, otherwise tries updating software via fw. So we take advantage of it to update the CPLD. - By doing so we don't have to mind whether to update via gpio supported, which belongs to hardware details. - - So the procedure should be: - 1. Test whether the file exists - 2. Fetch the mst device name - 3. Update CPLD via executing "cpldupdate --dev " - 4. Check the result - """ - # check whether the image file exists - if not self._check_file_validity(image_path): - return False - - mst_dev_list = self._get_mst_device() - if mst_dev_list is None: - print("ERROR: Failed to get mst device which is required for CPLD updating or multiple device files matched") - return False - - cmdline = self.CPLD_UPDATE_COMMAND.format(mst_dev_list[0], image_path) - outputline = "" - success_flag = False - try: - proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) - while True: - out = proc.stdout.read(1) + return mpfa.get_metadata().get('version', self.name) - if out == '' and proc.poll() != None: - break + 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) - if out != '': - sys.stdout.write(out) - sys.stdout.flush() - outputline += out + return "Immediate power cycle is required to complete {} firmware update".format(self.name) - 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 + def install_firmware(self, image_path): + return self.__install_firmware(image_path) - if proc.returncode: - print("ERROR: Upgrade CPLD failed, return code {}".format(proc.returncode)) - success_flag = False + 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)) - except OSError as e: - raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) - - if success_flag: - print("INFO: Refresh or power cycle is required to finish CPLD installation") - else: - print("ERROR: Failed to install CPLD") + burn_firmware = mpfa.get_metadata().get('firmware', 'burn') + refresh_firmware = mpfa.get_metadata().get('firmware', 'refresh') - return success_flag + 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(NEWLINE) + cpld_number = cpld_number.rstrip('\n') for cpld_idx in xrange(1, int(cpld_number) + 1): component_list.append(cls(cpld_idx)) 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..fd3c7ad50e23 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py @@ -0,0 +1,233 @@ +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: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":16}, + "unk_untrust": {"-127: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:120":16}, + "unk_untrust": {"-127:120":16}, + } + }, + '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/fan.py b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py index 9ce65d1e2f98..5b843749f0ee 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/fan.py @@ -9,61 +9,66 @@ ############################################################################# import os.path +import subprocess try: from sonic_platform_base.fan_base import FanBase + from .led import FanLed, ComponentFaultyIndicator 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" - -# SKUs with unplugable FANs: -# 1. don't have fanX_status and should be treated as always present -hwsku_dict_with_unplugable_fan = ['ACS-MSN2010', 'ACS-MSN2100'] +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, sku = None): + 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, psu_fan = False): + 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.is_psu_fan = psu_fan - self.always_presence = False if sku not in hwsku_dict_with_unplugable_fan else True + 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._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, 1) self.fan_max_speed_path = None + 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): @@ -85,20 +90,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 or not self.get_presence(): + 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.drawer_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 @@ -116,7 +111,7 @@ def get_status(self): else: try: with open(os.path.join(FAN_PATH, self.fan_status_path), 'r') as fault_status: - status = int(fault_status.read()) + status = int(fault_status.read().strip()) except (ValueError, IOError): status = 1 @@ -136,17 +131,9 @@ def get_presence(self): status = 1 else: status = 0 + return status == 1 else: - if self.always_presence: - status = 1 - 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 + return self.fan_drawer.get_presence() def _get_min_speed_in_rpm(self): @@ -164,7 +151,7 @@ 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()) + speed = int(max_fan_speed.read().strip()) except (ValueError, IOError): speed = 0 @@ -181,7 +168,7 @@ def get_speed(self): 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()) + speed_in_rpm = int(fan_curr_speed.read().strip()) except (ValueError, IOError): speed_in_rpm = 0 @@ -210,7 +197,7 @@ def get_target_speed(self): try: with open(os.path.join(FAN_PATH, self.fan_speed_set_path), 'r') as fan_pwm: - pwm = int(fan_pwm.read()) + pwm = int(fan_pwm.read().strip()) except (ValueError, IOError): pwm = 0 @@ -231,13 +218,36 @@ 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: + with open(self.psu_i2c_bus_path, 'r') as f: + bus = f.read().strip() + with open(self.psu_i2c_addr_path, 'r') as f: + addr = f.read().strip() + with open(self.psu_i2c_command_path, 'r') as f: + command = f.read().strip() + 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) + 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: + 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)) with open(os.path.join(FAN_PATH, self.fan_speed_set_path), 'w') as fan_pwm: fan_pwm.write(str(pwm)) except (ValueError, IOError): @@ -246,18 +256,6 @@ def set_speed(self, speed): 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 @@ -269,48 +267,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): @@ -320,26 +277,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): @@ -352,3 +290,42 @@ def get_speed_tolerance(self): """ # The tolerance value is fixed as 20% for all the Mellanox platform return 20 + + @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. + with open(COOLING_STATE_PATH, 'w') as cooling_state: + cooling_state.write(str(level + 10)) + + # We need set cooling level after resetting the cooling level vector + with open(COOLING_STATE_PATH, 'w') as cooling_state: + cooling_state.write(str(cur_state)) + except (ValueError, IOError) as e: + raise RuntimeError("Failed to set cooling level - {}".format(e)) + + @classmethod + def get_cooling_level(cls): + try: + with open(COOLING_STATE_PATH, 'r') as cooling_state: + cooling_level = int(cooling_state.read().strip()) + return cooling_level + 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..bed6c7ab042a --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/fan_drawer.py @@ -0,0 +1,104 @@ +#!/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() + + +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..ebc2de25a5c1 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/led.py @@ -0,0 +1,201 @@ +import os + + +class Led(object): + STATUS_LED_COLOR_GREEN = 'green' + STATUS_LED_COLOR_RED = 'red' + STATUS_LED_COLOR_ORANGE = 'orange' + STATUS_LED_COLOR_OFF = 'off' + + LED_ON = '1' + LED_OFF = '0' + + 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: + 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 get_status(self): + led_cap_list = self.get_capability() + if led_cap_list is None: + return Led.STATUS_LED_COLOR_OFF + + try: + 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_capability(self): + cap_list = None + try: + with open(self.get_led_cap_path(), 'r') as led_cap: + caps = led_cap.read() + cap_list = caps.split() + except (ValueError, IOError): + pass + + return cap_list + + def get_green_led_path(self): + pass + + def get_red_led_path(self): + pass + + def get_orange_led_path(self): + pass + + 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 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: + if SharedLed.LED_PRIORITY[virtual_led.get_led_color()] < SharedLed.LED_PRIORITY[target_color]: + target_color = virtual_led.get_led_color() + + 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): + self._color = color + return self._shared_led.update_status_led() + + 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/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index 1dfcf54baf17..6279f2d9e349 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -13,11 +13,11 @@ from sonic_platform_base.psu_base import PsuBase from sonic_daemon_base.daemon_base 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} -# 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, 'ACS-MSN4700': 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, 4700 + # 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,15 +98,18 @@ def __init__(self, psu_index, sku): psu_presence = os.path.join(self.psu_path, psu_presence) self.psu_presence = psu_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 sku not in hwsku_dict_with_unplugable_psu: - fan = Fan(sku, psu_index, psu_index, True) + if self.psu_data['hot_swappable']: + fan = Fan(psu_index, None, True) self._fan_list.append(fan) - 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" + if self.psu_data['led_num'] == 1: + self.led = ComponentFaultyIndicator(Psu.get_shared_led()) + else: # 2010/2100 + self.led = PsuLed(self.index) def get_name(self): @@ -120,8 +122,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 @@ -146,8 +150,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 @@ -194,19 +198,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 @@ -221,45 +212,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): @@ -269,26 +222,10 @@ 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.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 + if self.psu_data['led_num'] == 1: + return Psu.get_shared_led().get_status() + else: + return self.led.get_status() def get_power_available_status(self): @@ -307,3 +244,64 @@ def get_power_available_status(self): else: return True, "" + @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_event.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py index e92884fc3f33..0ed75c26c63a 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py @@ -11,15 +11,69 @@ from python_sdk_api.sx_api import * from sonic_daemon_base.daemon_base import Logger -SDK_SFP_STATE_IN = 0x1 +# SFP status from PMAOS register +# 0x1 plug in +# 0x2 plug out +# 0x3 plug in with error +# 0x4 disabled, at this status SFP eeprom is not accessible, +# and presence status also will be not present, +# so treate it as plug out. +SDK_SFP_STATE_IN = 0x1 SDK_SFP_STATE_OUT = 0x2 +SDK_SFP_STATE_ERR = 0x3 +SDK_SFP_STATE_DIS = 0x4 + +# SFP status that will be handled by XCVRD STATUS_PLUGIN = '1' STATUS_PLUGOUT = '0' -STATUS_UNKNOWN = '2' +STATUS_ERR_I2C_STUCK = '2' +STATUS_ERR_BAD_EEPROM = '3' +STATUS_ERR_UNSUPPORTED_CABLE = '4' +STATUS_ERR_HIGH_TEMP = '5' +STATUS_ERR_BAD_CABLE = '6' + +# SFP status used in this file only, will not expose to XCVRD +# STATUS_ERROR will be mapped to different status according to the error code +STATUS_UNKNOWN = '-1' +STATUS_ERROR = '-2' + +# SFP error code, only valid when SFP at SDK_SFP_STATE_ERR status +# Only 0x2, 0x3, 0x5, 0x6 and 0x7 will block the eeprom access, +# so will only report above errors to XCVRD and other errors will be +# printed to syslog. + +''' +0x0: "Power_Budget_Exceeded", +0x1: "Long_Range_for_non_MLNX_cable_or_module", +0x2: "Bus_stuck", +0x3: "bad_or_unsupported_EEPROM", +0x4: "Enforce_part_number_list", +0x5: "unsupported_cable", +0x6: "High_Temperature", +0x7: "bad_cable", +0x8: "PMD_type_is_not_enabled", +0x9: "[internal]Laster_TEC_failure", +0xa: "[internal]High_current", +0xb: "[internal]High_voltage", +0xd: "[internal]High_power", +0xe: "[internal]Module_state_machine_fault", +0xc: "pcie_system_power_slot_Exceeded" +''' + +# SFP errors that will block eeprom accessing +sdk_sfp_err_type_dict = { + 0x2: STATUS_ERR_I2C_STUCK, + 0x3: STATUS_ERR_BAD_EEPROM, + 0x5: STATUS_ERR_UNSUPPORTED_CABLE, + 0x6: STATUS_ERR_HIGH_TEMP, + 0x7: STATUS_ERR_BAD_CABLE +} sfp_value_status_dict = { - SDK_SFP_STATE_IN: STATUS_PLUGIN, - SDK_SFP_STATE_OUT: STATUS_PLUGOUT, + SDK_SFP_STATE_IN: STATUS_PLUGIN, + SDK_SFP_STATE_OUT: STATUS_PLUGOUT, + SDK_SFP_STATE_ERR: STATUS_ERROR, + SDK_SFP_STATE_DIS: STATUS_PLUGOUT, } # system level event/error @@ -174,7 +228,7 @@ def check_sfp_status(self, port_change, timeout): for fd in read: if fd == self.rx_fd_p.fd: - success, port_list, module_state = self.on_pmpe(self.rx_fd_p) + success, port_list, module_state, error_type = self.on_pmpe(self.rx_fd_p) if not success: logger.log_error("failed to read from {}".format(fd)) break @@ -192,15 +246,23 @@ def check_sfp_status(self, port_change, timeout): found += 1 continue + # If get SFP status error(0x3) from SDK, then need to read the error_type to get the detailed error + if sfp_state == STATUS_ERROR: + if error_type in sdk_sfp_err_type_dict.keys(): + # In SFP at error status case, need to overwrite the sfp_state with the exact error code + sfp_state = sdk_sfp_err_type_dict[error_type] + else: + # For errors don't block the eeprom accessing, we don't report it to XCVRD + logger.log_info("SFP error on port but not blocking eeprom read, error_type {}".format(error_type)) + found +=1 + continue + for port in port_list: logger.log_info("SFP on port {} state {}".format(port, sfp_state)) port_change[port] = sfp_state found += 1 - if found == 0: - return False - else: - return True + return found != 0 def on_pmpe(self, fd_p): ''' on port module plug event handler ''' @@ -228,7 +290,17 @@ def on_pmpe(self, fd_p): port_list_size = pmpe_t.list_size logical_port_list = pmpe_t.log_port_list module_state = pmpe_t.module_state - + error_type = pmpe_t.error_type + module_id = pmpe_t.module_id + + if module_state == SDK_SFP_STATE_ERR: + logger.log_error("Receive PMPE error event on module {}: status {} error type {}".format(module_id, module_state, error_type)) + elif module_state == SDK_SFP_STATE_DIS: + logger.log_info("Receive PMPE disable event on module {}: status {}".format(module_id, module_state)) + elif module_state == SDK_SFP_STATE_IN or module_state == SDK_SFP_STATE_OUT: + logger.log_info("Receive PMPE plug in/out event on module {}: status {}".format(module_id, module_state)) + else: + logger.log_error("Receive PMPE unknown event on module {}: status {}".format(module_id, module_state)) for i in xrange(port_list_size): logical_port = sx_port_log_id_t_arr_getitem(logical_port_list, i) rc = sx_api_port_device_get(self.handle, 1 , 0, port_attributes_list, port_cnt_p) @@ -247,4 +319,4 @@ def on_pmpe(self, fd_p): delete_sx_port_attributes_t_arr(port_attributes_list) delete_uint32_t_p(port_cnt_p) - return status, label_port_list, module_state, + return status, label_port_list, module_state, error_type diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index a5faa5ea793a..3525220a4035 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -42,6 +42,16 @@ 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_cpu_core = { THERMAL_API_GET_TEMPERATURE:"cpu_core{}", THERMAL_API_GET_HIGH_THRESHOLD:"cpu_core{}_max", @@ -114,7 +124,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, 'ACS-MSN4700': 8} +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} thermal_profile_list = [ # 2700 { @@ -254,14 +264,47 @@ 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 + ] + ) } ] -def initialize_thermals(sku, thermal_list, psu_list): +def initialize_thermals(platform, thermal_list, psu_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 for category in thermal_device_categories_all: if category == THERMAL_DEV_CATEGORY_AMBIENT: count, ambient_list = thermal_profile[category] @@ -290,6 +333,9 @@ def initialize_thermals(sku, thermal_list, psu_list): class Thermal(ThermalBase): + thermal_profile = None + thermal_algorithm_status = False + def __init__(self, category, index, has_index, dependency = None): """ index should be a string for category ambient and int for other categories @@ -321,14 +367,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 @@ -420,3 +467,131 @@ 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 + + + @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..94e18a2e00b0 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 = 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 82c186495f5e..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 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/tests/mock_platform.py b/platform/mellanox/mlnx-platform-api/tests/mock_platform.py index f34ace97968d..8edb9d4fb163 100644 --- a/platform/mellanox/mlnx-platform-api/tests/mock_platform.py +++ b/platform/mellanox/mlnx-platform-api/tests/mock_platform.py @@ -1,13 +1,24 @@ 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: @@ -21,6 +32,9 @@ def get_presence(self): 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/test_fan_api.py b/platform/mellanox/mlnx-platform-api/tests/test_fan_api.py index 381260163c0f..24158997abf7 100644 --- a/platform/mellanox/mlnx-platform-api/tests/test_fan_api.py +++ b/platform/mellanox/mlnx-platform-api/tests/test_fan_api.py @@ -1,17 +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 = Fan(True, 0, 0) - fan.get_presence = MagicMock(return_value=False) - assert fan.fan_dir is not None + fan_drawer = RealDrawer(0, DEVICE_DATA['x86_64-mlnx_msn2700-r0']['fans']) + fan = Fan(0, fan_drawer) + 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) + fan2 = Fan(1, fan_drawer) + 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 843244e937fa..87fac359b2fd 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() @@ -77,35 +91,47 @@ 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.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_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 == 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(): @@ -159,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() @@ -275,6 +339,53 @@ 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: @@ -315,4 +426,89 @@ class MockThermalManager(ThermalManagerBase): 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=35000) + 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=25000) + 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..ba954beb7ae0 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.16.1-master +MLNX_SAI_VERSION = SAIRel1.16.4.1-sai16 export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index ef47a5592190..b318bb380ac1 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit ef47a5592190c08d2f127d3fe8fa5a77ee4087ba +Subproject commit b318bb380ac13dba98c94b163fbe644ab7eb236e 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/rules.dep b/platform/mellanox/rules.dep new file mode 100644 index 000000000000..8986eb2e0808 --- /dev/null +++ b/platform/mellanox/rules.dep @@ -0,0 +1,18 @@ +# 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)/docker-ptf-mlnx.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..1270579e2942 100644 --- a/platform/mellanox/rules.mk +++ b/platform/mellanox/rules.mk @@ -12,7 +12,8 @@ include $(PLATFORM_PATH)/libsaithrift-dev.mk include $(PLATFORM_PATH)/docker-ptf-mlnx.mk include $(PLATFORM_PATH)/mlnx-ffb.mk include $(PLATFORM_PATH)/issu-version.mk -include $(PLATFORM_PATH)/onie-fw-update.mk +include $(PLATFORM_PATH)/mlnx-onie-fw-update.mk +include $(PLATFORM_PATH)/mlnx-ssd-fw-update.mk SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) @@ -28,6 +29,3 @@ $(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) diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index 07425a0957d1..bf5651d92c21 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 bf5651d92c21e62837aea2970488a01b0ff94768 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..28700ff40b71 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ -MLNX_SDK_VERSION = 4.4.0542 +MLNX_SDK_VERSION = 4.4.0940 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) @@ -152,8 +152,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 index 7fbbd271cf65..15855bc89a1f 100644 --- a/platform/nephos/docker-ptf-nephos.mk +++ b/platform/nephos/docker-ptf-nephos.mk @@ -5,3 +5,4 @@ $(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) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF_NEPHOS) 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..967dad316967 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/"] 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..dc6977ed4710 100644 --- a/platform/nephos/docker-syncd-nephos/supervisord.conf +++ b/platform/nephos/docker-syncd-nephos/supervisord.conf @@ -3,32 +3,35 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -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 syncd 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 +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 50a2d0e5c080..5e055537a428 100644 --- a/platform/nephos/nephos-modules.mk +++ b/platform/nephos/nephos-modules.mk @@ -1,26 +1,9 @@ # Nephos Platform modules -VERSION = 1.0.1 +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/control b/platform/nephos/nephos-modules/debian/control index 3d06ca971f89..8450eeae1e01 100644 --- a/platform/nephos/nephos-modules/debian/control +++ b/platform/nephos/nephos-modules/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: nephos-modules Architecture: amd64 -Depends: linux-image-4.9.0-11-2-amd64 +Depends: linux-image-4.19.0-6-amd64-unsigned Description: kernel modules for nephos asic diff --git a/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9-amd64 b/platform/nephos/nephos-modules/modules/init.d/nps-modules similarity index 92% rename from platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9-amd64 rename to platform/nephos/nephos-modules/modules/init.d/nps-modules index a6deb4217a95..d6f841ee02e7 100755 --- a/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9-amd64 +++ b/platform/nephos/nephos-modules/modules/init.d/nps-modules @@ -45,7 +45,7 @@ force-reload|restart) ;; *) - echo "Usage: /etc/init.d/nps-modules-4.9.0-11-2-amd64.init {start|stop}" + echo "Usage: /etc/init.d/nps-modules {start|stop}" exit 1 ;; esac diff --git a/platform/nephos/nephos-modules/modules/service/nps-modules-4.9-amd64.service b/platform/nephos/nephos-modules/modules/service/nps-modules.service similarity index 63% rename from platform/nephos/nephos-modules/modules/service/nps-modules-4.9-amd64.service rename to platform/nephos/nephos-modules/modules/service/nps-modules.service index fc45a597d74c..22aa9a7510c6 100644 --- a/platform/nephos/nephos-modules/modules/service/nps-modules-4.9-amd64.service +++ b/platform/nephos/nephos-modules/modules/service/nps-modules.service @@ -5,8 +5,8 @@ Before=syncd.service [Service] Type=oneshot -ExecStart=-/etc/init.d/nps-modules-4.9-amd64 start -ExecStop=-/etc/init.d/nps-modules-4.9-amd64 stop +ExecStart=-/etc/init.d/nps-modules start +ExecStop=-/etc/init.d/nps-modules stop RemainAfterExit=yes [Install] 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/sonic-platform-modules-accton/debian/control b/platform/nephos/sonic-platform-modules-accton/debian/control index 639534f3edcc..a1068b7a7c5c 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-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp 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/debian/control b/platform/nephos/sonic-platform-modules-cig/debian/control index bf40791b24e0..0c70d57ddbf2 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-6-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-6-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-6-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..4fed2d1aa15e 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-6-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp 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-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index f8fcf974b65c..54d585f29e23 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -7,6 +7,23 @@ HWSKU=Force10-S6000 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 SYSTEM_MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') @@ -17,7 +34,7 @@ if [ -f /etc/sonic/config_db.json ]; then 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/hwsku/port_config.ini -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 -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 diff --git a/platform/vs/docker-syncd-vs/Dockerfile.j2 b/platform/vs/docker-syncd-vs/Dockerfile.j2 index 25d82499edf1..fea26b2f103e 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=4.20.0-2 libcap2-bin=1:2.25-2 COPY \ {% for deb in docker_syncd_vs_debs.split(' ') -%} 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 0c6285d46ae0..b097d1aa8c10 100644 --- a/platform/vs/docker-syncd-vs/supervisord.conf +++ b/platform/vs/docker-syncd-vs/supervisord.conf @@ -3,27 +3,39 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -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 syncd events=PROCESS_STATE_EXITED 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,3 +44,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/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.mk b/platform/vs/rules.mk index 557604d9ec4d..d91f487a5edb 100644 --- a/platform/vs/rules.mk +++ b/platform/vs/rules.mk @@ -5,5 +5,6 @@ include $(PLATFORM_PATH)/docker-syncd-vs.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/tests/bgp/test_gr_livelock.py b/platform/vs/tests/bgp/test_gr_livelock.py index f269f1e8eee4..aff0afdb02b4 100644 --- a/platform/vs/tests/bgp/test_gr_livelock.py +++ b/platform/vs/tests/bgp/test_gr_livelock.py @@ -86,10 +86,10 @@ def test_gr_livelock(dvs, testlog): 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..24f3d8790b9c 100644 --- a/platform/vs/tests/bgp/test_invalid_nexthop.py +++ b/platform/vs/tests/bgp/test_invalid_nexthop.py @@ -10,7 +10,7 @@ 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") diff --git a/platform/vs/tests/bgp/test_no_export.py b/platform/vs/tests/bgp/test_no_export.py index efbc5331fef8..92bece320c1c 100644 --- a/platform/vs/tests/bgp/test_no_export.py +++ b/platform/vs/tests/bgp/test_no_export.py @@ -9,10 +9,10 @@ def test_bounce(dvs, testlog): 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("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/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/config b/rules/config index e9eb460c4dc1..f20708bbd2b9 100644 --- a/rules/config +++ b/rules/config @@ -117,7 +117,7 @@ DEFAULT_VS_PREPARE_MEM = yes # ENABLE_ICCPD - build docker-iccpd for mclag support -ENABLE_ICCPD = y +ENABLE_ICCPD = n # ENABLE_SYSTEM_SFLOW - build docker-sonic-sflow for sFlow support ENABLE_SFLOW = y @@ -131,3 +131,24 @@ ENABLE_RESTAPI = n # ENABLE_NAT - build docker-sonic-nat for nat support ENABLE_NAT = y +# INSTALL_KUBERNETES - if set to y kubernetes packages are installed to be able to +# run as worker node in kubernetes cluster. +INSTALL_KUBERNETES = n + +# KUBERNETES_VERSION - Set to the required version. +# K8s_GCR_IO_PAUSE_VERSION - Version of k8s universal pause container image +# K8s_CNI_FLANNEL_VERSION - Flannel used as CNI; Appropriate version for this Kubernetes version +# These are Used *only* when INSTALL_KUBERNETES=y +# NOTE: As a worker node it has to run version compatible to kubernetes master. +# +KUBERNETES_VERSION = 1.18.0 +K8s_GCR_IO_PAUSE_VERSION = 3.2 +K8s_CNI_FLANNEL_VERSION = v0.12.0 + +# 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 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..e1f02d19f30e --- /dev/null +++ b/rules/docker-base-buster.mk @@ -0,0 +1,17 @@ +# 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 += $(SUPERVISOR) $(REDIS_TOOLS) +$(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-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..cd4703e578a6 --- /dev/null +++ b/rules/docker-config-engine-buster.mk @@ -0,0 +1,13 @@ +# 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)_PYTHON_WHEELS += $(SWSSSDK_PY2) +$(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE) +$(DOCKER_CONFIG_ENGINE_BUSTER)_LOAD_DOCKERS += $(DOCKER_BASE_BUSTER) + +$(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-database.mk b/rules/docker-database.mk index 7e372048afab..9fb15855c247 100644 --- a/rules/docker-database.mk +++ b/rules/docker-database.mk @@ -7,20 +7,18 @@ 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 = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_DATABASE)_DBG_DEPENDS += $(REDIS_TOOLS_DBG) -$(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 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 index da661e9a2244..106da8e589d8 100644 --- a/rules/docker-iccpd.mk +++ b/rules/docker-iccpd.mk @@ -1,14 +1,22 @@ # docker image for iccpd agent -DOCKER_ICCPD = docker-iccpd.gz -$(DOCKER_ICCPD)_PATH = $(DOCKERS_PATH)/docker-iccpd +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) $(REDIS_TOOLS) $(ICCPD) +$(DOCKER_ICCPD)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_ICCPD)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) $(ICCPD_DBG) +$(DOCKER_ICCPD)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) $(DOCKER_ICCPD)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) ifeq ($(ENABLE_ICCPD), y) SONIC_DOCKER_IMAGES += $(DOCKER_ICCPD) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_ICCPD) SONIC_STRETCH_DOCKERS += $(DOCKER_ICCPD) +SONIC_DOCKER_DBG_IMAGES += $(DOCKER_ICCPD_DBG) +SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_ICCPD_DBG) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_ICCPD_DBG) endif $(DOCKER_ICCPD)_CONTAINER_NAME = iccpd 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..af3d77a1c8c1 --- /dev/null +++ b/rules/docker-lldp.mk @@ -0,0 +1,32 @@ +# 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) $(PYTHON_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_PY2) +$(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)_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-ptf.mk b/rules/docker-ptf.mk index 2782c45339bd..b2d45068334d 100644 --- a/rules/docker-ptf.mk +++ b/rules/docker-ptf.mk @@ -4,3 +4,4 @@ DOCKER_PTF = docker-ptf.gz $(DOCKER_PTF)_PATH = $(DOCKERS_PATH)/docker-ptf $(DOCKER_PTF)_DEPENDS += $(LIBTHRIFT) $(PYTHON_THRIFT) $(PTF) SONIC_DOCKER_IMAGES += $(DOCKER_PTF) +SONIC_STRETCH_DOCKERS += $(DOCKER_PTF) diff --git a/rules/docker-restapi.mk b/rules/docker-restapi.mk index 2141dea64d17..bd91aabd86c5 100644 --- a/rules/docker-restapi.mk +++ b/rules/docker-restapi.mk @@ -19,4 +19,9 @@ 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 += -v /etc/sonic/credentials:/etc/sonic/credentials:ro +$(DOCKER_RESTAPI)_RUN_OPT += -p=8081:8081/tcp $(DOCKER_RESTAPI)_RUN_OPT += -p=8090:8090/tcp + +$(DOCKER_RESTAPI)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_RESTAPI)_BASE_IMAGE_FILES += monit_restapi:/etc/monit/conf.d diff --git a/rules/docker-router-advertiser.mk b/rules/docker-router-advertiser.mk index ec3fcf6e1fa3..c7efe7c1f560 100644 --- a/rules/docker-router-advertiser.mk +++ b/rules/docker-router-advertiser.mk @@ -7,20 +7,18 @@ 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 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..39d5f2584b36 --- /dev/null +++ b/rules/docker-snmp.mk @@ -0,0 +1,32 @@ +# 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_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 +# mount Arista platform python libraries to support corresponding platforms SNMP power status query +$(DOCKER_SNMP)_RUN_OPT += -v /usr/lib/python3/dist-packages/arista:/usr/lib/python3/dist-packages/arista: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..b0e11c89f510 100644 --- a/rules/docker-sonic-mgmt-framework.mk +++ b/rules/docker-sonic-mgmt-framework.mk @@ -7,22 +7,20 @@ 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 = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_MGMT_FRAMEWORK)_DBG_DEPENDS += $(REDIS_TOOLS) $(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) 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) 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 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-telemetry.mk b/rules/docker-telemetry.mk index 04f1871f334b..e4c689bde5d1 100644 --- a/rules/docker-telemetry.mk +++ b/rules/docker-telemetry.mk @@ -7,21 +7,19 @@ 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)_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) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_TELEMETRY) -SONIC_STRETCH_DOCKERS += $(DOCKER_TELEMETRY) endif SONIC_DOCKER_DBG_IMAGES += $(DOCKER_TELEMETRY_DBG) ifeq ($(ENABLE_SYSTEM_TELEMETRY), y) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_TELEMETRY_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_TELEMETRY_DBG) endif $(DOCKER_TELEMETRY)_CONTAINER_NAME = telemetry diff --git a/rules/frr.mk b/rules/frr.mk index df924c8af711..321f11feb967 100644 --- a/rules/frr.mk +++ b/rules/frr.mk @@ -12,7 +12,6 @@ $(FRR)_DEPENDS += $(LIBSNMP_DEV) $(LIBYANG_DEV) $(FRR)_RDEPENDS += $(LIBYANG) $(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))) 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 index d54faaba5b76..eb97efc52b9f 100644 --- a/rules/iccpd.mk +++ b/rules/iccpd.mk @@ -2,13 +2,18 @@ ICCPD_VERSION = 0.0.5 -ICCPD = iccpd_$(ICCPD_VERSION)_amd64.deb +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_MAKE_DEBS += $(ICCPD) -# SONIC_STRETCH_DEBS += $(ICCPD) +SONIC_DPKG_DEBS += $(ICCPD) -# Export these variables so they can be used in a sub-make -export ICCPD_VERSION -export 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..a166f5817a8b 100644 --- a/rules/iptables.mk +++ b/rules/iptables.mk @@ -4,21 +4,20 @@ IPTABLES_VERSION = 1.6.0+snapshot20161117 IPTABLES_VERSION_SUFFIX = 6 IPTABLES_VERSION_FULL = $(IPTABLES_VERSION)-$(IPTABLES_VERSION_SUFFIX) -IPTABLES = iptables_$(IPTABLES_VERSION_FULL)_amd64.deb +IPTABLES = 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..e4bf23355076 100644 --- a/rules/isc-dhcp.mk +++ b/rules/isc-dhcp.mk @@ -8,7 +8,5 @@ ISC_DHCP_RELAY = isc-dhcp-relay_$(ISC_DHCP_VERSION)_$(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 $(eval $(call add_derived_package,$(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/libyang.mk b/rules/libyang.mk index d10c2ea2cc66..fc739a30bc39 100644 --- a/rules/libyang.mk +++ b/rules/libyang.mk @@ -12,7 +12,6 @@ LIBYANG = libyang_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb $(LIBYANG)_SRC_PATH = $(SRC_PATH)/libyang $(LIBYANG)_DEPENDS += $(SWIG_BASE) $(SWIG) 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 +20,15 @@ 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))) export LIBYANG LIBYANG_DBG LIBYANG_DEV LIBYANG_CPP LIBYANG_PY3 LIBYANG_PY2 diff --git a/rules/linux-kernel.mk b/rules/linux-kernel.mk index e6742bdf14cf..0b906a2623ba 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-6 KVERSION = $(KVERSION_SHORT)-$(CONFIGURED_ARCH) -KERNEL_VERSION = 4.9.189 -KERNEL_SUBVERSION = 3+deb9u2 +KERNEL_VERSION = 4.19.67 +KERNEL_SUBVERSION = 2+deb10u2 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,5 @@ 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 +LINUX_KERNEL = linux-image-$(KVERSION)-unsigned_$(KERNEL_VERSION)-$(KERNEL_SUBVERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LINUX_HEADERS_COMMON),$(LINUX_KERNEL))) 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/python-click.mk b/rules/python-click.mk index 5d48dc30d604..59e22b371159 100644 --- a/rules/python-click.mk +++ b/rules/python-click.mk @@ -7,11 +7,10 @@ # 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 +PYTHON_CLICK_VERSION = 7.0-1 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.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.mk b/rules/radvd.mk index fcde8c5767b8..f0a048280443 100644 --- a/rules/radvd.mk +++ b/rules/radvd.mk @@ -1,13 +1,12 @@ # radvd package -RADVD_VERSION = 2.17-2~bpo9+1 +RADVD_VERSION = 2.17-2 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))) 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/sflow.mk b/rules/sflow.mk index a7ca1b3b1d0d..39054bad61c2 100644 --- a/rules/sflow.mk +++ b/rules/sflow.mk @@ -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 168cad70ef2a..cc340e92e6bb 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 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-mgmt-framework.mk b/rules/sonic-mgmt-framework.mk index a57ce6b1b083..d3536edcfb65 100644 --- a/rules/sonic-mgmt-framework.mk +++ b/rules/sonic-mgmt-framework.mk @@ -2,13 +2,13 @@ ifeq ($(ENABLE_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_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-yang-mgmt-py2.dep b/rules/sonic-yang-mgmt-py2.dep new file mode 100644 index 000000000000..a4ec4264b49a --- /dev/null +++ b/rules/sonic-yang-mgmt-py2.dep @@ -0,0 +1,10 @@ + +SPATH := $($(SONIC_YANG_MGMT_PY)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-yang-mgmt-py2.mk rules/sonic-yang-mgmt-py2.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_YANG_MGMT_PY)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_YANG_MGMT_PY)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_YANG_MGMT_PY)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/sonic-yang-mgmt-py2.mk b/rules/sonic-yang-mgmt-py2.mk new file mode 100644 index 000000000000..0b85d7eb9bdc --- /dev/null +++ b/rules/sonic-yang-mgmt-py2.mk @@ -0,0 +1,12 @@ +# sonic-yang-mgmt python2 wheel + +SONIC_YANG_MGMT_PY = sonic_yang_mgmt-1.0-py2-none-any.whl +$(SONIC_YANG_MGMT_PY)_SRC_PATH = $(SRC_PATH)/sonic-yang-mgmt +$(SONIC_YANG_MGMT_PY)_PYTHON_VERSION = 2 +$(SONIC_YANG_MGMT_PY)_DEBS_DEPENDS = $(LIBYANG) $(LIBYANG_CPP) $(LIBYANG_PY2) \ + $(LIBYANG_PY3) +$(SONIC_YANG_MGMT_PY)_DEPENDS = $(SONIC_YANG_MODELS_PY3) +$(SONIC_YANG_MGMT_PY)_RDEPENDS = $(SONIC_YANG_MODELS_PY3) $(LIBYANG) \ + $(LIBYANG_CPP) $(LIBYANG_PY2) + +SONIC_PYTHON_WHEELS += $(SONIC_YANG_MGMT_PY) 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.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/swig.mk b/rules/swig.mk index c5c3c27b6f4b..cb964bb49b44 100644 --- a/rules/swig.mk +++ b/rules/swig.mk @@ -11,7 +11,6 @@ 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))) diff --git a/rules/swss-common.mk b/rules/swss-common.mk index 2d49867f9392..12d91e73fb8f 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) $(SWIG) $(LIBSWSSCOMMON)_RDEPENDS += $(LIBHIREDIS) $(LIBNL3) $(LIBNL_GENL3) \ $(LIBNL_ROUTE3) $(LIBNL_NF3) $(LIBNL_CLI) SONIC_DPKG_DEBS += $(LIBSWSSCOMMON) 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/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/scripts/build_kvm_image.sh b/scripts/build_kvm_image.sh index f9cd9490181d..e0a7ec2feff4 100755 --- a/scripts/build_kvm_image.sh +++ b/scripts/build_kvm_image.sh @@ -51,6 +51,7 @@ create_disk prepare_installer_disk echo "Prepare memory for KVM build: $vs_build_prepare_mem" +sudo 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 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/slave.mk b/slave.mk index 3a3fd2421d3f..4b14f4fea227 100644 --- a/slave.mk +++ b/slave.mk @@ -34,8 +34,12 @@ 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 @@ -45,10 +49,17 @@ 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 CONFIGURED_PLATFORM export CONFIGURED_ARCH +export PYTHON_WHEELS_PATH +export IMAGE_DISTRO +export IMAGE_DISTRO_DEBS_PATH ############################################################################### ## Utility rules @@ -62,12 +73,16 @@ 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) @echo $(PLATFORM) > .platform @echo $(PLATFORM_ARCH) > .arch @@ -191,6 +206,7 @@ $(info "USERNAME" : "$(USERNAME)") $(info "PASSWORD" : "$(PASSWORD)") $(info "ENABLE_DHCP_GRAPH_SERVICE" : "$(ENABLE_DHCP_GRAPH_SERVICE)") $(info "SHUTDOWN_BGP_ON_START" : "$(SHUTDOWN_BGP_ON_START)") +$(info "INSTALL_KUBERNETES" : "$(INSTALL_KUBERNETES)") $(info "ENABLE_PFCWD_ON_START" : "$(ENABLE_PFCWD_ON_START)") $(info "INSTALL_DEBUG_TOOLS" : "$(INSTALL_DEBUG_TOOLS)") $(info "ROUTING_STACK" : "$(SONIC_ROUTING_STACK)") @@ -282,7 +298,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 @@ -524,8 +540,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 @@ -543,7 +559,7 @@ $(addprefix $(PYTHON_WHEELS_PATH)/, $(SONIC_PYTHON_WHEELS)) : $(PYTHON_WHEELS_PA if [ -f ../$(notdir $($*_SRC_PATH)).patch/series ]; then quilt pop -a -f; fi popd $(LOG_SIMPLE) mv $($*_SRC_PATH)/dist/$* $(PYTHON_WHEELS_PATH) $(LOG) - + # Save the target deb into DPKG cache $(call SAVE_CACHE,$*,$@) fi @@ -598,23 +614,43 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_SIMPLE_DOCKER_IMAGES)) : $(TARGET_PATH)/%.g 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 +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),) - DOCKER_IMAGES_FOR_INSTALLERS := $(sort $(foreach installer,$(SONIC_INSTALLERS),$($(installer)_DOCKERS))) 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))) \ @@ -634,8 +670,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 @@ -659,7 +695,7 @@ $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) : $(TARGET_PATH)/%.gz : .platform docker save $* | gzip -c > $@ # Clean up if [ -f $($*.gz_PATH).patch/series ]; then pushd $($*.gz_PATH) && quilt pop -a -f; popd; fi - + # Save the target deb into DPKG cache $(call SAVE_CACHE,$*.gz,$@) fi @@ -670,7 +706,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) @@ -682,7 +718,7 @@ $(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]++')) @@ -729,10 +765,10 @@ $(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) \ @@ -743,20 +779,21 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(MONIT)) \ $$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \ $$(addprefix $(FILES_PATH)/,$$($$*_FILES)) \ - $(if $(findstring y,$(ENABLE_ZTP)),$(addprefix $(DEBS_PATH)/,$(SONIC_ZTP))) \ - $(addprefix $(STRETCH_FILES_PATH)/, $(if $(filter $(CONFIGURED_ARCH),amd64), $(IXGBE_DRIVER))) \ + $(if $(findstring y,$(ENABLE_ZTP)),$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$(SONIC_ZTP))) \ $(addprefix $(PYTHON_DEBS_PATH)/,$(SONIC_UTILS)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2)) \ - $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2)) + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MODELS_PY3)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY)) $(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)" @@ -769,15 +806,20 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export enable_ztp="$(ENABLE_ZTP)" export enable_nat="$(ENABLE_NAT)" export shutdown_bgp_on_start="$(SHUTDOWN_BGP_ON_START)" + export install_kubernetes="$(INSTALL_KUBERNETES)" export enable_pfcwd_on_start="$(ENABLE_PFCWD_ON_START)" - export installer_debs="$(addprefix $(STRETCH_DEBS_PATH)/,$($*_INSTALLS))" - export lazy_installer_debs="$(foreach deb, $($*_LAZY_INSTALLS),$(foreach device, $($(deb)_PLATFORM),$(addprefix $(device)@, $(STRETCH_DEBS_PATH)/$(deb))))" + 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 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 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_yang_mgmt_py_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY))" export multi_instance="false" $(foreach docker, $($*_DOCKERS),\ @@ -825,7 +867,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ ) ) 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 @@ -852,6 +894,11 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ 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), \ @@ -923,12 +970,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 diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2 new file mode 100644 index 000000000000..3e3191264790 --- /dev/null +++ b/sonic-slave-buster/Dockerfile.j2 @@ -0,0 +1,430 @@ +{%- 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 %} + +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 + +{%- 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 +{%- 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 +{%- 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 \ + libboost-program-options1.67-dev \ + libtinyxml2-dev \ + python \ + python-pip \ + libncurses5-dev \ + texinfo \ + dh-autoreconf \ + python3-pip \ + doxygen \ + devscripts \ + git-buildpackage \ + perl-modules \ + libswitch-perl \ + dh-systemd \ +# 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 \ + libboost-all-dev \ + 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 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 \ + pylint \ + python-pytest \ + gcovr \ + python-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-lxml \ + python-jinja2 \ + python-netaddr \ + python-ipaddr \ + python-yaml \ + python3-yaml \ +# 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 python-click build + python-sphinx \ + python3-pallets-sphinx-themes \ + python-docutils \ + python3-all \ + python3-setuptools \ + python3-sphinx \ + python3-docutils \ + python3-requests \ + python3-pytest \ + python3-colorama \ +# For bash + texi2html \ +# For initramfs + shellcheck \ + bash-completion \ +{%- if CONFIGURED_ARCH == "amd64" %} +# For sonic vs image build + dosfstools \ + qemu-kvm \ + libvirt-clients \ +{%- endif %} +# 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 SWI Tools + python-m2crypto + +## 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 + +# For p4 build +RUN pip install \ + ctypesgen==0.r125 \ + crc16 + +# 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" + +# 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 + +# For sonic snmpagent mock testing +RUN pip3 install mockredispy==2.9.3 + +RUN pip3 install "PyYAML>=5.1" + +# 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 + +# 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 + +# For sonic-swss-common testing +RUN pip install Pympler==0.8 + +# For sonic_yang_mgmt build +RUN pip install ijson==2.6.1 +RUN pip3 install ijson==2.6.1 +RUN pip install jsondiff==1.2.0 +RUN pip install xmltodict==0.12.0 +RUN pip install pyang==2.1.1 + +# For mgmt-framework build +RUN pip install mmh3 +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 +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 +{%- if CONFIGURED_ARCH == "amd64" %} +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 +{%- 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 +RUN update-alternatives --set iptables /usr/sbin/iptables-legacy + +# Install swi tools +RUN python -m pip install git+https://github.com/aristanetworks/swi-tools.git@d51761ec0bb93c73039233f3c01ed48235ffad00 diff --git a/sonic-slave-buster/Dockerfile.user b/sonic-slave-buster/Dockerfile.user new file mode 100644 index 000000000000..e292a8a6776a --- /dev/null +++ b/sonic-slave-buster/Dockerfile.user @@ -0,0 +1,30 @@ +ARG slave_base_tag_ref=latest +FROM sonic-slave-buster:${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-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..f4278bf5c299 100644 --- a/sonic-slave-jessie/Dockerfile.j2 +++ b/sonic-slave-jessie/Dockerfile.j2 @@ -278,7 +278,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 \ @@ -324,6 +324,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 +372,6 @@ 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 swi tools +RUN python -m pip install git+https://github.com/aristanetworks/swi-tools.git@d51761ec0bb93c73039233f3c01ed48235ffad00 diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index f9e96791464d..a7266806437a 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -295,10 +295,14 @@ 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 SWI Tools + python-m2crypto ## Config dpkg ## install the configuration file if it’s currently missing @@ -315,7 +319,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 \ @@ -367,6 +371,16 @@ 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 + +# For sonic_yang_mgmt build +RUN pip install ijson==2.6.1 +RUN pip3 install ijson==2.6.1 +RUN pip install jsondiff==1.2.0 +RUN pip install xmltodict==0.12.0 +RUN pip install pyang==2.1.1 + # For mgmt-framework build RUN pip install mmh3 @@ -420,8 +434,11 @@ 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 swi tools +RUN python -m pip install git+https://github.com/aristanetworks/swi-tools.git@d51761ec0bb93c73039233f3c01ed48235ffad00 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/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/src/dhcp_device.c b/src/dhcpmon/src/dhcp_device.c index aa0c0f835cbd..554a1dcf0a97 100644 --- a/src/dhcpmon/src/dhcp_device.c +++ b/src/dhcpmon/src/dhcp_device.c @@ -33,6 +33,23 @@ #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 + +/** + * 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; #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 +60,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] @@ -90,47 +108,63 @@ static dhcp_device_counters_t glob_counters_snapshot[DHCP_DIR_COUNT] = { }; /** - * @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: + case DHCP_MESSAGE_TYPE_DISCOVER: + giaddr = ntohl(dhcphdr[DHCP_GIADDR_OFFSET] << 24 | dhcphdr[DHCP_GIADDR_OFFSET + 1] << 16 | + dhcphdr[DHCP_GIADDR_OFFSET + 2] << 8 | dhcphdr[DHCP_GIADDR_OFFSET + 3]); context->counters[dir].discover++; - if ((context->is_uplink && dir == DHCP_TX) || (!context->is_uplink && dir == DHCP_RX)) { + if ((context->vlan_ip == giaddr && context->is_uplink && dir == DHCP_TX) || + (!context->is_uplink && dir == DHCP_RX && iphdr->ip_dst.s_addr == INADDR_BROADCAST)) { glob_counters[dir].discover++; } break; - case 2: + case DHCP_MESSAGE_TYPE_OFFER: context->counters[dir].offer++; - if ((!context->is_uplink && dir == DHCP_TX) || (context->is_uplink && dir == DHCP_RX)) { + if ((context->vlan_ip == iphdr->ip_dst.s_addr && context->is_uplink && dir == DHCP_RX) || + (!context->is_uplink && dir == DHCP_TX)) { glob_counters[dir].offer++; } break; - case 3: + case DHCP_MESSAGE_TYPE_REQUEST: + giaddr = ntohl(dhcphdr[DHCP_GIADDR_OFFSET] << 24 | dhcphdr[DHCP_GIADDR_OFFSET + 1] << 16 | + dhcphdr[DHCP_GIADDR_OFFSET + 2] << 8 | dhcphdr[DHCP_GIADDR_OFFSET + 3]); context->counters[dir].request++; - if ((context->is_uplink && dir == DHCP_TX) || (!context->is_uplink && dir == DHCP_RX)) { + if ((context->vlan_ip == giaddr && context->is_uplink && dir == DHCP_TX) || + (!context->is_uplink && dir == DHCP_RX && iphdr->ip_dst.s_addr == INADDR_BROADCAST)) { glob_counters[dir].request++; } break; - case 5: + case DHCP_MESSAGE_TYPE_ACK: context->counters[dir].ack++; - if ((!context->is_uplink && dir == DHCP_TX) || (context->is_uplink && dir == DHCP_RX)) { + if ((context->vlan_ip == iphdr->ip_dst.s_addr && context->is_uplink && dir == DHCP_RX) || + (!context->is_uplink && dir == DHCP_TX)) { glob_counters[dir].ack++; } break; - case 4: // type: Decline - case 6 ... 8: - // type: NAK, Release, Inform + case DHCP_MESSAGE_TYPE_DECLINE: + case DHCP_MESSAGE_TYPE_NAK: + case DHCP_MESSAGE_TYPE_RELEASE: + case DHCP_MESSAGE_TYPE_INFORM: break; default: syslog(LOG_WARNING, "handle_dhcp_option_53(%s): Unknown DHCP option 53 type %d", context->intf, dhcp_option[2]); @@ -146,7 +180,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 +191,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 +216,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; @@ -260,31 +295,21 @@ static void dhcp_print_counters(dhcp_device_counters_t *counters) } /** - * @code init_socket(context, intf, snaplen, base); + * @code init_socket(context, intf); * * @brief initializes socket, bind it to interface and bpf prgram, and * associate with libevent base * * @param context pointer to device (interface) context * @param intf interface name - * @param snaplen length of packet capture - * @param base libevent base * * @return 0 on success, otherwise for failure */ -static int init_socket(dhcp_device_context_t *context, - const char *intf, - size_t snaplen, - struct event_base *base) +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 +326,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 +383,32 @@ 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_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,8 +417,8 @@ 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; @@ -414,6 +437,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); * diff --git a/src/dhcpmon/src/dhcp_device.h b/src/dhcpmon/src/dhcp_device.h index 04113eeabdc0..bc1582d46a82 100644 --- a/src/dhcpmon/src/dhcp_device.h +++ b/src/dhcpmon/src/dhcp_device.h @@ -49,6 +49,7 @@ 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 */ @@ -60,23 +61,48 @@ typedef struct } 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_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); diff --git a/src/dhcpmon/src/dhcp_devman.c b/src/dhcpmon/src/dhcp_devman.c index c19cbde591b8..077ed210a299 100644 --- a/src/dhcpmon/src/dhcp_devman.c +++ b/src/dhcpmon/src/dhcp_devman.c @@ -28,6 +28,23 @@ static uint32_t dhcp_num_south_intf = 0; /** dhcp_num_north_intf number of north interfaces */ static uint32_t dhcp_num_north_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; + +/** vlan interface name */ +static char vlan_intf[IF_NAMESIZE] = "Undefined"; + +/** + * @code dhcp_devman_get_vlan_intf(); + * + * Accessor method + */ +const char* dhcp_devman_get_vlan_intf() +{ + return vlan_intf; +} + /** * @code dhcp_devman_init(); * @@ -65,7 +82,7 @@ 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. */ @@ -84,9 +101,15 @@ int dhcp_devman_add_intf(const char *name, uint8_t is_uplink) assert(dhcp_num_south_intf <= 1); } - LIST_INSERT_HEAD(&intfs, dev, entry); + rv = dhcp_device_init(&dev->dev_context, dev->name, dev->is_uplink); + if (rv == 0 && !is_uplink) { + rv = dhcp_device_get_ip(dev->dev_context, &vlan_ip); - rv = 0; + strncpy(vlan_intf, name, sizeof(vlan_intf) - 1); + vlan_intf[sizeof(vlan_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 +123,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", diff --git a/src/dhcpmon/src/dhcp_devman.h b/src/dhcpmon/src/dhcp_devman.h index a0753b4b93a1..2f66fa407ca2 100644 --- a/src/dhcpmon/src/dhcp_devman.h +++ b/src/dhcpmon/src/dhcp_devman.h @@ -31,29 +31,38 @@ void dhcp_devman_init(); */ void dhcp_devman_shutdown(); +/** + * @code dhcp_devman_get_vlan_intf(); + * + * @brief Accessor method + * + * @return pointer to vlan ip interface name + */ +const char* dhcp_devman_get_vlan_intf(); + /** * @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 is_uplink true for uplink (north) interface * * @return 0 on success, nonzero otherwise */ int dhcp_devman_add_intf(const char *name, uint8_t is_uplink); /** - * @code dhcp_devman_start_capture(snaplen, timeout_ms); + * @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(); diff --git a/src/dhcpmon/src/dhcp_mon.c b/src/dhcpmon/src/dhcp_mon.c index dc0a7d94f149..623bc46f5276 100644 --- a/src/dhcpmon/src/dhcp_mon.c +++ b/src/dhcpmon/src/dhcp_mon.c @@ -36,13 +36,13 @@ 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); + syslog(LOG_ALERT, "Received signal %s\n", strsignal(fd)); dhcp_devman_print_status(); dhcp_mon_stop(); } @@ -67,7 +67,9 @@ static void timeout_callback(evutil_socket_t fd, short event, void *arg) { 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); + syslog(LOG_ALERT, "dhcpmon detected disparity in DHCP Relay behavior. Failure count: %d for vlan: '%s'\n", + count, dhcp_devman_get_vlan_intf()); + dhcp_devman_print_status(); } break; case DHCP_MON_STATUS_HEALTHY: @@ -151,7 +153,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; 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..9d155393a6e6 100644 --- a/src/dhcpmon/src/main.c +++ b/src/dhcpmon/src/main.c @@ -21,7 +21,7 @@ #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; @@ -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)); 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/iccpd/Makefile b/src/iccpd/Makefile deleted file mode 100644 index 401ff394d145..000000000000 --- a/src/iccpd/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -.ONESHELL: -SHELL = /bin/bash -.SHELLFLAGS += -e - -MAIN_TARGET = iccpd_$(ICCPD_VERSION)_amd64.deb -DEB_PATH = debian - -all: iccpd-build mclagdctl-build - -iccpd-build: - make -C src - -mclagdctl-build: - make -C src/mclagdctl - -$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : - make all - if [ ! -d $(DEB_PATH)/usr/bin ]; then - mkdir -p $(DEB_PATH)/usr/bin - fi - cp iccpd $(DEB_PATH)/usr/bin/iccpd - cp src/mclagdctl/mclagdctl $(DEB_PATH)/usr/bin/mclagdctl - chmod +x $(DEB_PATH)/usr/bin/iccpd - chmod +x $(DEB_PATH)/usr/bin/mclagdctl - md5sum $(DEB_PATH)/usr/bin/iccpd > $(DEB_PATH)/DEBIAN/md5sums - md5sum $(DEB_PATH)/usr/bin/mclagdctl >> $(DEB_PATH)/DEBIAN/md5sums - dpkg-deb -b $(DEB_PATH) $(DEST)/$(MAIN_TARGET) - -clean: iccpd-clean mclagdctl-clean - -iccpd-clean: - make -C src clean - -mclagdctl-clean: - make -C src/mclagdctl clean 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/DEBIAN/control b/src/iccpd/debian/DEBIAN/control deleted file mode 100644 index cedfa03f37c0..000000000000 --- a/src/iccpd/debian/DEBIAN/control +++ /dev/null @@ -1,12 +0,0 @@ -Package: iccpd-0.0.5-amd64 -Source: nps -Version: 0.0.5 -Architecture: amd64 -Maintainer: Simon Ji -Installed-Size: 1508 -Depends: -Section: main -Priority: extra -Homepage: https://github.com/NephosInc/SONiC -Description: - 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/iccp_cmd_show.h b/src/iccpd/include/iccp_cmd_show.h index 0fedca7cdddd..a41fbadf8c77 100644 --- a/src/iccpd/include/iccp_cmd_show.h +++ b/src/iccpd/include/iccp_cmd_show.h @@ -29,6 +29,7 @@ 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); diff --git a/src/iccpd/include/iccp_csm.h b/src/iccpd/include/iccp_csm.h index 9cf1022dd10c..01e424d13271 100644 --- a/src/iccpd/include/iccp_csm.h +++ b/src/iccpd/include/iccp_csm.h @@ -31,6 +31,7 @@ #include #include #include +#include #include "../include/app_csm.h" #include "../include/msg_format.h" @@ -45,7 +46,9 @@ #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 diff --git a/src/iccpd/include/iccp_ifm.h b/src/iccpd/include/iccp_ifm.h index 7fbb1a8cf4f9..bbb1af67ee90 100644 --- a/src/iccpd/include/iccp_ifm.h +++ b/src/iccpd/include/iccp_ifm.h @@ -28,9 +28,10 @@ int iccp_sys_local_if_list_get_init(); -int iccp_arp_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); diff --git a/src/iccpd/include/iccp_netlink.h b/src/iccpd/include/iccp_netlink.h index 612a1859591b..a4f321736d0c 100644 --- a/src/iccpd/include/iccp_netlink.h +++ b/src/iccpd/include/iccp_netlink.h @@ -31,6 +31,25 @@ #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); @@ -41,6 +60,7 @@ 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/mlacp_fsm.h b/src/iccpd/include/mlacp_fsm.h index 6442d9ff560d..b335e78cd007 100644 --- a/src/iccpd/include/mlacp_fsm.h +++ b/src/iccpd/include/mlacp_fsm.h @@ -53,6 +53,7 @@ enum MLACP_SYNC_STATE MLACP_SYNC_AGGINFO, MLACP_SYNC_PEERLINKINFO, MLACP_SYNC_ARP_INFO, + MLACP_SYNC_NDISC_INFO, MLACP_SYNC_DONE, }; @@ -85,6 +86,8 @@ struct mLACP 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; diff --git a/src/iccpd/include/mlacp_link_handler.h b/src/iccpd/include/mlacp_link_handler.h index 55892d1861c8..624b4111a7ee 100644 --- a/src/iccpd/include/mlacp_link_handler.h +++ b/src/iccpd/include/mlacp_link_handler.h @@ -43,17 +43,17 @@ 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); -int mlacp_fsm_arp_set(char *ifname, uint32_t ip, char *mac); -int mlacp_fsm_arp_del(char *ifname, uint32_t ip); -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); +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(); diff --git a/src/iccpd/include/mlacp_sync_prepare.h b/src/iccpd/include/mlacp_sync_prepare.h index f4ea7a419f51..17cd8f260155 100644 --- a/src/iccpd/include/mlacp_sync_prepare.h +++ b/src/iccpd/include/mlacp_sync_prepare.h @@ -46,6 +46,7 @@ int mlacp_prepare_for_sync_data_tlv(struct CSM* csm, char* buf, size_t max_buf_s 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); diff --git a/src/iccpd/include/mlacp_sync_update.h b/src/iccpd/include/mlacp_sync_update.h index d42abe216af6..2a5d5b598d05 100644 --- a/src/iccpd/include/mlacp_sync_update.h +++ b/src/iccpd/include/mlacp_sync_update.h @@ -36,12 +36,13 @@ 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); diff --git a/src/iccpd/include/mlacp_tlv.h b/src/iccpd/include/mlacp_tlv.h index 86bce2e0e943..7d3a4e18e4e2 100644 --- a/src/iccpd/include/mlacp_tlv.h +++ b/src/iccpd/include/mlacp_tlv.h @@ -374,6 +374,14 @@ struct ARPMsg 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 */ @@ -385,6 +393,17 @@ struct mLACPARPInfoTLV 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 */ @@ -413,11 +432,11 @@ struct mLACPWarmbootTLV uint8_t warmboot; } __attribute__ ((packed)); -enum ARP_OP_TYPE +enum NEIGH_OP_TYPE { - ARP_SYNC_LIF, - ARP_SYNC_ADD, - ARP_SYNC_DEL, + NEIGH_SYNC_LIF, + NEIGH_SYNC_ADD, + NEIGH_SYNC_DEL, }; enum MAC_AGE_TYPE diff --git a/src/iccpd/include/msg_format.h b/src/iccpd/include/msg_format.h index 5f4deb18772b..1af8bf8a46a8 100644 --- a/src/iccpd/include/msg_format.h +++ b/src/iccpd/include/msg_format.h @@ -98,7 +98,8 @@ #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_LIST_END 0x104a //list end +#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) diff --git a/src/iccpd/include/port.h b/src/iccpd/include/port.h index bdcaf66a68ad..dbd9d45fa83d 100644 --- a/src/iccpd/include/port.h +++ b/src/iccpd/include/port.h @@ -102,6 +102,8 @@ struct LocalInterface 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]; @@ -139,6 +141,7 @@ 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); diff --git a/src/iccpd/include/scheduler.h b/src/iccpd/include/scheduler.h index b3be274282c8..a1b31039d794 100644 --- a/src/iccpd/include/scheduler.h +++ b/src/iccpd/include/scheduler.h @@ -35,6 +35,7 @@ #include struct CSM; +struct System; #define CONNECT_INTERVAL_SEC 1 #define CONNECT_TIMEOUT_MSEC 100 diff --git a/src/iccpd/include/system.h b/src/iccpd/include/system.h index bb89dbb2f3c2..3ee314d253aa 100644 --- a/src/iccpd/include/system.h +++ b/src/iccpd/include/system.h @@ -58,6 +58,7 @@ struct System int sync_fd; int sync_ctrl_fd; int arp_receive_fd; + int ndisc_receive_fd; int epoll_fd; struct nl_sock * genric_sock; diff --git a/src/iccpd/src/Makefile b/src/iccpd/src/Makefile deleted file mode 100644 index 5e8cebc703c0..000000000000 --- a/src/iccpd/src/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -LIBNL_CFLAGS = -I/usr/include/libnl3 -LIBNL_LIBS = -lnl-cli-3 -lnl-genl-3 -lnl-nf-3 -lnl-route-3 -lnl-3 - -CC = gcc -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 - -OBJECTS = app_csm.o cmd_option.o iccp_cli.o iccp_cmd_show.o iccp_cmd.o \ -iccp_csm.o iccp_ifm.o iccp_main.o logger.o \ -port.o scheduler.o system.o iccp_consistency_check.o\ -mlacp_link_handler.o \ -mlacp_sync_prepare.o mlacp_sync_update.o \ -mlacp_fsm.o \ -iccp_netlink.o - -HEADERS = ../include/app_csm.h ../include/cmd_option.h ../include/iccp_cli.h \ -../include/iccp_cmd_show.h \ -../include/iccp_csm.h ../include/iccp_ifm.h \ -../include/logger.h ../include/mlacp_fsm.h \ -../include/mlacp_tlv.h ../include/msg_format.h ../include/port.h \ -../include/scheduler.h ../include/system.h \ -../include/iccp_consistency_check.h ../include/route_info.h \ -../include/iccp_netlink.h - -//CFLAGS = -g -O2 -fstack-protector-strong -Wformat -Werror=format-security $(LIBNL_CFLAGS) -I../include/ -CFLAGS = -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -I../include/ $(LIBNL_CFLAGS) -LDFLAGS = $(LIBNL_LIBS) -lpthread -LDADD = $(LIBZEBRA_BIN) - -all: iccpd - -%.o: %.c $(HEADERS) - -iccpd: $(OBJECTS) - $(CC) -o ../iccpd $(OBJECTS) $(LDFLAGS) - -DEPS = $(patsubst %.o, %.d, $(OBJECTS)) - --include $(DEPS) -%.d:%.c - @set -e; rm -f $@; \ - gcc -MM $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - - - -.PHONY: clean -clean: - -rm -f $(OBJECTS) $(DEPS) ../iccpd 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/iccp_cmd_show.c b/src/iccpd/src/iccp_cmd_show.c index e25a653e74b3..b0a60fb5f49c 100644 --- a/src/iccpd/src/iccp_cmd_show.c +++ b/src/iccpd/src/iccp_cmd_show.c @@ -177,7 +177,7 @@ int iccp_arp_dump(char * *buf, int *num, int mclag_id) 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(htonl(iccpd_arp->ipv4_addr)), 16); + 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), @@ -204,6 +204,72 @@ int iccp_arp_dump(char * *buf, int *num, int mclag_id) 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; diff --git a/src/iccpd/src/iccp_ifm.c b/src/iccpd/src/iccp_ifm.c index cf874366b97b..ea8ce20f05c3 100644 --- a/src/iccpd/src/iccp_ifm.c +++ b/src/iccpd/src/iccp_ifm.c @@ -137,34 +137,21 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int memset(buf, 0, MAX_BUFSIZE); msg_len = sizeof(struct ARPMsg); arp_msg = (struct ARPMsg*)&buf; - arp_msg->op_type = ARP_SYNC_LIF; + 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 = ntohl(arp_msg->ipv4_addr); + arp_msg->ipv4_addr = arp_msg->ipv4_addr; - ICCPD_LOG_DEBUG(__FUNCTION__, "ARP type %s, state (%04X)(%d) ifindex [%d] (%s) ip %s, mac [%02X:%02X:%02X:%02X:%02X:%02X]", + 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(htonl(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]); - - /*Debug*/ - #if 0 - /* dump receive kernel ARP req*/ - fprintf(stderr, "\n======== Kernel ARP ==========\n"); - fprintf(stderr, " Type = [%d] (New=%d, Del=%d)\n", msgtype, RTM_NEWNEIGH, RTM_DELNEIGH); - fprintf(stderr, " State = (%04X)(%d)\n", ndm->ndm_state, fwd_neigh_state_valid(ndm->ndm_state)); - fprintf(stderr, " ifindex = [%d] (%s)\n", ndm->ndm_ifindex, arp_msg->ifname); - fprintf(stderr, " IP = [%s]\n", show_ip_str(htonl(arp_msg->ipv4_addr))); - fprintf(stderr, " MAC = [%02X:%02X:%02X:%02X:%02X:%02X]\n", - 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]); - fprintf(stderr, "==============================\n"); - #endif + 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) @@ -228,7 +215,7 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int free(msg->buf); free(msg); msg = NULL; - ICCPD_LOG_DEBUG(__FUNCTION__, "Delete ARP %s", show_ip_str(htonl(arp_msg->ipv4_addr))); + ICCPD_LOG_DEBUG(__FUNCTION__, "Delete ARP %s", show_ip_str(arp_msg->ipv4_addr)); } else { @@ -242,7 +229,7 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int 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(htonl(arp_msg->ipv4_addr))); + ICCPD_LOG_DEBUG(__FUNCTION__, "Update ARP for %s", show_ip_str(arp_msg->ipv4_addr)); } } break; @@ -256,31 +243,31 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int /* enquene lif_msg (add)*/ if (!msg) { - arp_msg->op_type = ARP_SYNC_LIF; + 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(htonl(arp_msg->ipv4_addr)));*/ + 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(htonl(arp_msg->ipv4_addr))); + 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 = ARP_SYNC_ADD; + 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(htonl(arp_msg->ipv4_addr)));*/ + show_ip_str(arp_msg->ipv4_addr));*/ } else ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[ADD] message for %s", - show_ip_str(htonl(arp_msg->ipv4_addr))); + show_ip_str(arp_msg->ipv4_addr)); } } @@ -289,58 +276,218 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int /* enqueue iccp_msg (delete)*/ if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) { - arp_msg->op_type = ARP_SYNC_DEL; + 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(htonl(arp_msg->ipv4_addr)));*/ + show_ip_str(arp_msg->ipv4_addr));*/ } else ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[DEL] message for %s", - show_ip_str(htonl(arp_msg->ipv4_addr))); + show_ip_str(arp_msg->ipv4_addr)); } } - /*Debug: dump for dequeue ARP Info*/ - #if 0 - fprintf(stderr, "\n======== ARP Info List ========\n"); - TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail) + 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) { - arp_msg = (struct ARPMsg*)msg->buf; - fprintf(stderr, "type %d,ifname %s , ip %s\n", arp_msg->op_type, arp_msg->ifname, show_ip_str(htonl(arp_msg->ipv4_addr))); + 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; } - fprintf(stderr, "==============================\n"); - #endif - /*TEST dump for dequeue ARP message*/ - #if 0 + if (msg && !neigh_update) + return; - while (MLACP(csm).arp_updated && !TAILQ_EMPTY(&(MLACP(csm).arp_msg_list))) + if (msgtype != RTM_DELNEIGH) { - msg = TAILQ_FIRST(&(MLACP(csm).arp_msg_list)); - TAILQ_REMOVE(&(MLACP(csm).arp_msg_list), msg, tail); - arp_msg = (struct ARPMsg *)msg->buf; - fprintf(stderr, "\n======== Dequeue ARP ========\n"); - fprintf(stderr, " Type = [%d]\n", arp_msg->op_type); - fprintf(stderr, " State = (%04X)(%d)\n", ndm->ndm_state, fwd_neigh_state_valid(ndm->ndm_state)); - fprintf(stderr, " ifname = [%s]\n", arp_msg->ifname); - fprintf(stderr, " IP = [%s]\n", show_ip_str(arp_msg->ipv4_addr)); - fprintf(stderr, " MAC = [%02X:%02X:%02X:%02X:%02X:%02X]\n", - 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]); - fprintf(stderr, "==============================\n"); - free(msg->buf); - free(msg); + /* 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)); - MLACP(csm).arp_updated = 0; - #endif + } + } 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)) @@ -392,11 +539,14 @@ int do_one_neigh_request(struct nlmsghdr *n) 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); } -/*Handle arp received from kernel*/ -static int iccp_arp_valid_handler(struct nl_msg *msg, void *arg) +static int iccp_neigh_valid_handler(struct nl_msg *msg, void *arg) { struct nlmsghdr *nlh = nlmsg_hdr(msg); @@ -405,8 +555,7 @@ static int iccp_arp_valid_handler(struct nl_msg *msg, void *arg) return 0; } -/*Get kernel arp information during initialization*/ -int iccp_arp_get_init() +int iccp_neigh_get_init() { struct System *sys = NULL; struct nl_cb *cb; @@ -440,7 +589,7 @@ int iccp_arp_get_init() return -ENOMEM; } - nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, iccp_arp_valid_handler, sys); + 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); @@ -485,27 +634,16 @@ void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, ui memset(buf, 0, MAX_BUFSIZE); msg_len = sizeof(struct ARPMsg); arp_msg = (struct ARPMsg*)&buf; - arp_msg->op_type = ARP_SYNC_LIF; + 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(htonl(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]); - /*Debug*/ - #if 0 - /* dump receive kernel ARP req*/ - fprintf(stderr, "\n======== Kernel ARP Update==========\n"); - fprintf(stderr, " Type = (New=%d)\n", RTM_NEWNEIGH); - fprintf(stderr, " ifindex = [%d] (%s)\n", ifindex, arp_lif->name); - fprintf(stderr, " IP = [%s]\n", show_ip_str(htonl(arp_msg->ipv4_addr))); - fprintf(stderr, " MAC = [%02X:%02X:%02X:%02X:%02X:%02X]\n", - 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]); - fprintf(stderr, "==============================\n"); - #endif + 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) @@ -553,10 +691,10 @@ void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, ui if (!verify_arp) return; - if (iccp_check_if_addr_from_netlink(AF_INET, &addr, arp_lif)) + 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(htonl(arp_msg->ipv4_addr)), arp_lif->name); + show_ip_str(arp_msg->ipv4_addr), arp_lif->name); return; } @@ -576,8 +714,9 @@ void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, ui 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(htonl(arp_msg->ipv4_addr))); + 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; } @@ -585,36 +724,196 @@ void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, ui /* enquene lif_msg (add)*/ if (!msg) { - arp_msg->op_type = ARP_SYNC_LIF; + 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(htonl(arp_msg->ipv4_addr)));*/ + 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(htonl(arp_msg->ipv4_addr))); + 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 = ARP_SYNC_ADD; + 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(htonl(arp_msg->ipv4_addr)));*/ + show_ip_str(arp_msg->ipv4_addr));*/ } else ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[ADD] message for %s", - show_ip_str(htonl(arp_msg->ipv4_addr))); + 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; @@ -656,29 +955,6 @@ void iccp_from_netlink_port_state_handler( char * ifname, int state) 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 iccp_parse_if_vlan_info_from_netlink(struct nlmsghdr *n) { struct LocalInterface *lif = NULL; @@ -759,4 +1035,4 @@ void iccp_parse_if_vlan_info_from_netlink(struct nlmsghdr *n) n = NLMSG_NEXT(n, msglen); } -} \ No newline at end of file +} diff --git a/src/iccpd/src/iccp_netlink.c b/src/iccpd/src/iccp_netlink.c index ec8971d0ceee..002c254ae9c1 100644 --- a/src/iccpd/src/iccp_netlink.c +++ b/src/iccpd/src/iccp_netlink.c @@ -35,15 +35,18 @@ #include #include #include +#include +#include #include #include -#include #include #include #include #include #include +#include +#include #include "../include/system.h" #include "../include/iccp_ifm.h" @@ -53,6 +56,8 @@ #include "../include/scheduler.h" #include "../include/mlacp_link_handler.h" #include "../include/msg_format.h" +#include "../include/iccp_netlink.h" + /** * SECTION: Netlink helpers */ @@ -324,13 +329,6 @@ int iccp_get_portchannel_member_list_handler(struct nl_msg *msg, void * arg) { memset(local_if->portchannel_member_buf, 0, 512); memcpy(local_if->portchannel_member_buf, temp_buf, sizeof(local_if->portchannel_member_buf) - 1); - #if 0 - if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE) - { - /*peerlink portchannel member changed*/ - update_peerlink_isolate_from_all_csm_lif(csm); - } - #endif } } } @@ -491,7 +489,7 @@ void iccp_set_interface_ipadd_mac(struct LocalInterface *lif, char * mac_addr ) dst_len = strlen(mac_addr); memcpy(sub_msg->data, mac_addr, dst_len); - ICCPD_LOG_DEBUG(__FUNCTION__, "If name %s ip %s mac %s", lif->name, show_ip_str(htonl(lif->ipv4_addr)), sub_msg->data); + 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); @@ -504,6 +502,51 @@ void iccp_set_interface_ipadd_mac(struct LocalInterface *lif, char * mac_addr ) 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; @@ -535,7 +578,7 @@ void update_if_ipmac_on_standby(struct LocalInterface* lif_po) /*Backup old sysmac*/ memcpy(lif_po->mac_addr_ori, lif_po->mac_addr, ETHER_ADDR_LEN); - ICCPD_LOG_DEBUG(__FUNCTION__, + 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], @@ -546,6 +589,10 @@ void update_if_ipmac_on_standby(struct LocalInterface* lif_po) { 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 */ @@ -576,8 +623,12 @@ void update_if_ipmac_on_standby(struct LocalInterface* lif_po) { ICCPD_LOG_ERR(__FUNCTION__, "Set %s mac error, ret = %d", vlan->vlan_itf->name, ret); } - - iccp_set_interface_ipadd_mac(vlan->vlan_itf, macaddr ); + + /* 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); } } @@ -611,7 +662,7 @@ void recover_if_ipmac_on_standby(struct LocalInterface* lif_po) /*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_DEBUG(__FUNCTION__, + 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], @@ -622,6 +673,10 @@ void recover_if_ipmac_on_standby(struct LocalInterface* lif_po) { 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 */ @@ -648,6 +703,10 @@ void recover_if_ipmac_on_standby(struct LocalInterface* lif_po) 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); } @@ -657,6 +716,80 @@ void recover_if_ipmac_on_standby(struct LocalInterface* lif_po) 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; @@ -789,6 +922,103 @@ void iccp_event_handler_obj_input_dellink(struct nl_object *obj, void *arg) 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 @@ -893,61 +1123,6 @@ int iccp_check_if_addr_from_netlink(int family, uint8_t *addr, struct LocalInter return 0; } -int iccp_local_if_addr_update(struct nl_msg *msg, void *arg) -{ - int len; - struct ifaddrmsg *ifa; - struct LocalInterface *lif; - - struct nlmsghdr *n = nlmsg_hdr(msg); - - if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR) - return 0; - - ifa = NLMSG_DATA(n); - - if (ifa->ifa_family != AF_INET ) - return 0; - - lif = local_if_find_by_ifindex(ifa->ifa_index); - if (!lif) - { - return 0; - } - - if (n->nlmsg_type == RTM_DELADDR) - { - lif->ipv4_addr = 0; - lif->prefixlen = 0; - lif->l3_mode = 0; - memset(lif->l3_mac_addr, 0, ETHER_ADDR_LEN); - } - - len = n->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifaddrmsg)); - if (len < 0) - return 0; - - struct rtattr *rth = IFA_RTA(ifa); - int rtl = IFA_PAYLOAD(n); - - while (rtl && RTA_OK(rth, rtl)) - { - if (rth->rta_type == IFA_ADDRESS) - { - uint32_t ipaddr = ntohl(*((uint32_t *)RTA_DATA(rth))); - lif->ipv4_addr = ipaddr; - lif->prefixlen = ifa->ifa_prefixlen; - lif->l3_mode = 1; - lif->port_config_sync = 1; - update_if_ipmac_on_standby(lif); - ICCPD_LOG_DEBUG(__FUNCTION__, "If name %s index %d ip %s", lif->name, lif->ifindex, show_ip_str(htonl(lif->ipv4_addr))); - } - rth = RTA_NEXT(rth, rtl); - } - - return 0; -} - int iccp_sys_local_if_list_get_addr() { struct System *sys = NULL; @@ -983,7 +1158,7 @@ int iccp_sys_local_if_list_get_addr() return -ENOMEM; } - nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, iccp_local_if_addr_update, sys); + 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) @@ -1022,9 +1197,13 @@ static int iccp_route_event_handler(struct nl_msg *msg, void *arg) break; case RTM_NEWADDR: - iccp_local_if_addr_update(msg, NULL); + 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; } @@ -1048,6 +1227,53 @@ static int iccp_genric_event_handler(struct nl_msg *msg, void *arg) 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() { @@ -1135,45 +1361,7 @@ int iccp_system_init_netlink_socket() ICCPD_LOG_ERR(__FUNCTION__, "Failed to set buffer size of netlink event sock."); goto err_return; } -#if 0 - sys->family = genl_ctrl_resolve(sys->genric_sock, TEAM_GENL_NAME); - while (sys->family < 0) - { - sleep(1); - log_err_period++; - /*If no portchannel configuration, teamd will not started, genl_ctrl_resolve() will return <0 forever */ - /*Only log error message 5 times*/ - if (log_err_period == 1 && log_err_time < 5) - { - ICCPD_LOG_ERR(__FUNCTION__, "Failed to resolve netlink family. %d of TEAM_GENL_NAME %s ", sys->family, TEAM_GENL_NAME); - log_err_time++; - } - else - { - /*Log error message every 30s per time*/ - if (log_err_period == 30) - log_err_period = 0; - } - - 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); - goto err_return; - } - - err = nl_socket_add_membership(sys->genric_event_sock, grp_id); - if (err < 0) - { - ICCPD_LOG_ERR(__FUNCTION__, "Failed to add netlink membership."); - goto err_return; - } -#endif 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); @@ -1202,8 +1390,13 @@ int iccp_system_init_netlink_socket() ICCPD_LOG_ERR(__FUNCTION__, "Failed to add netlink membership."); goto err_return; } - - /*receive arp packet socket*/ + 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) { @@ -1225,6 +1418,13 @@ int iccp_system_init_netlink_socket() } } + sys->ndisc_receive_fd = iccp_make_nd_socket(); + + if (sys->ndisc_receive_fd < 0) + { + goto err_return; + } + goto succes_return; err_return: @@ -1295,6 +1495,11 @@ 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]; @@ -1328,7 +1533,100 @@ static int iccp_receive_arp_packet_handler(struct System *sys) 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, ntohl(addr), mac_addr); + 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; } @@ -1412,7 +1710,11 @@ static const struct iccp_eventfd iccp_eventfds[] = { { .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 */ diff --git a/src/iccpd/src/mclagdctl/Makefile b/src/iccpd/src/mclagdctl/Makefile deleted file mode 100644 index 5520da22cee2..000000000000 --- a/src/iccpd/src/mclagdctl/Makefile +++ /dev/null @@ -1,28 +0,0 @@ - - -C = gcc -SOURCES = \ -mclagdctl.c - -OBJECTS = \ -mclagdctl.o - -HEADERS = \ -mclagdctl.h - -CFLAGS = -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -LDFLAGS = -LDADD = - -all: mclagdctl - -%.o: %.c $(HEADERS) - -mclagdctl: $(OBJECTS) - $(CC) -o ./mclagdctl $(OBJECTS) $(LDFLAGS) - -.PHONY: clean -clean: - -rm -f $(OBJECTS) ./mclagdctl - - 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 index 7c5d7284066d..630e333be6ed 100644 --- a/src/iccpd/src/mclagdctl/mclagdctl.c +++ b/src/iccpd/src/mclagdctl/mclagdctl.c @@ -1,5 +1,5 @@ /* - /* Copyright(c) 2016-2019 Nephos. + * 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, @@ -21,6 +21,8 @@ #include #include +#include +#include #include #include #include @@ -65,6 +67,14 @@ static struct command_type command_types[] = .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, @@ -290,6 +300,24 @@ int mclagdctl_enca_dump_arp(char *msg, int mclag_id, int argc, char **argv) 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; @@ -322,6 +350,38 @@ int mclagdctl_parse_dump_arp(char *msg, int data_len) 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; diff --git a/src/iccpd/src/mclagdctl/mclagdctl.h b/src/iccpd/src/mclagdctl/mclagdctl.h index 1b8c6f278cc5..91155ecb7321 100644 --- a/src/iccpd/src/mclagdctl/mclagdctl.h +++ b/src/iccpd/src/mclagdctl/mclagdctl.h @@ -25,6 +25,7 @@ #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 @@ -62,6 +63,7 @@ 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, @@ -137,6 +139,14 @@ struct mclagd_arp_msg 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*/ @@ -186,7 +196,9 @@ struct mclagd_peer_if 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); diff --git a/src/iccpd/src/mlacp_fsm.c b/src/iccpd/src/mlacp_fsm.c index f479b75f36cc..c56eb9051736 100644 --- a/src/iccpd/src/mlacp_fsm.c +++ b/src/iccpd/src/mlacp_fsm.c @@ -101,12 +101,14 @@ * ***************************************/ 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*/ @@ -204,7 +206,7 @@ static void mlacp_sync_send_aggState(struct CSM* csm) return; } #define MAX_MAC_ENTRY_NUM 30 -#define MAX_ARP_ENTRY_NUM 40 +#define MAX_NEIGH_ENTRY_NUM 40 static void mlacp_sync_send_syncMacInfo(struct CSM* csm) { int msg_len = 0; @@ -253,7 +255,7 @@ static void mlacp_sync_send_syncArpInfo(struct CSM* csm) count++; free(msg->buf); free(msg); - if (count >= MAX_ARP_ENTRY_NUM) + if (count >= MAX_NEIGH_ENTRY_NUM) { iccp_csm_send(csm, g_csm_buf, msg_len); count = 0; @@ -268,6 +270,37 @@ static void mlacp_sync_send_syncArpInfo(struct CSM* csm) 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; @@ -353,7 +386,7 @@ static void mlacp_sync_recv_sysConf(struct CSM* csm, struct Msg* msg) 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_DEBUG(__FUNCTION__, "Same Node ID = %d, send NAK", MLACP(csm).remote_system.node_id); + ICCPD_LOG_WARN(__FUNCTION__, "Same Node ID = %d, send NAK", MLACP(csm).remote_system.node_id); mlacp_sync_send_nak_handler(csm, msg); } @@ -476,6 +509,15 @@ static void mlacp_sync_recv_arpInfo(struct CSM* csm, struct Msg* msg) 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*/ @@ -520,6 +562,7 @@ void mlacp_init(struct CSM* csm, int all) 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); @@ -528,6 +571,7 @@ void mlacp_init(struct CSM* csm, int all) { /* 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); @@ -551,8 +595,10 @@ void mlacp_finalize(struct CSM* csm) /* 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 */ @@ -590,6 +636,7 @@ void mlacp_fsm_transit(struct CSM* csm) { 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; } @@ -651,6 +698,7 @@ void mlacp_fsm_transit(struct CSM* csm) 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) @@ -788,7 +836,7 @@ static void mlacp_resync_arp(struct CSM* csm) TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail) { arp_msg = (struct ARPMsg*)msg->buf; - arp_msg->op_type = ARP_SYNC_ADD; + 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); @@ -797,6 +845,31 @@ static void mlacp_resync_arp(struct CSM* csm) } } +/****************************************** +* 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 * @@ -928,6 +1001,10 @@ static void mlacp_sync_receiver_handler(struct CSM* csm, struct Msg* msg) 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; @@ -980,6 +1057,10 @@ static void mlacp_sync_sender_handler(struct CSM* csm) 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; @@ -1194,6 +1275,9 @@ static void mlacp_exchange_handler(struct CSM* csm, struct Msg* msg) /* 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) { diff --git a/src/iccpd/src/mlacp_link_handler.c b/src/iccpd/src/mlacp_link_handler.c index 66a75c4b8620..8bc533e387bd 100644 --- a/src/iccpd/src/mlacp_link_handler.c +++ b/src/iccpd/src/mlacp_link_handler.c @@ -39,6 +39,7 @@ #include "../include/iccp_csm.h" #include "mclagdctl/mclagdctl.h" #include "../include/iccp_cmd_show.h" +#include "../include/iccp_netlink.h" /***************************************** * Enum * @@ -50,12 +51,12 @@ typedef enum route_manipulate_type ROUTE_DEL } ROUTE_MANIPULATE_TYPE_E; - /***************************************** * Global * * ***************************************/ char g_ipv4_str[INET_ADDRSTRLEN]; +char g_ipv6_str[INET6_ADDRSTRLEN]; /***************************************** * Tool : show ip string @@ -72,6 +73,14 @@ char *show_ip_str(uint32_t ipv4_addr) 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; @@ -95,107 +104,6 @@ static int getHwAddr(char *buff, char *mac) return 0; } -/* Set an entry in the ARP cache. */ -int mlacp_fsm_arp_set(char *ifname, uint32_t ip, char *mac) -{ - struct arpreq arpreq; - struct sockaddr_in *sin; - struct in_addr ina; - int flags; - int rc; - int sock_fd = 0; - - ICCPD_LOG_DEBUG(__FUNCTION__, "Set arp entry for IP:%s MAC:%s ifname:%s", show_ip_str(htonl(ip)), mac, ifname); - - if (ifname == NULL || ip == 0 || mac == NULL) - { - return MCLAG_ERROR; - } - - /*you must add this becasue some system will return "Invlid argument" - because some argument isn't zero */ - memset(&arpreq, 0, sizeof(struct arpreq)); - sin = (struct sockaddr_in *)&arpreq.arp_pa; - memset(sin, 0, sizeof(struct sockaddr_in)); - sin->sin_family = AF_INET; - ina.s_addr = htonl(ip); - memcpy(&sin->sin_addr, (char *)&ina, sizeof(struct in_addr)); - - if (getHwAddr((char *)arpreq.arp_ha.sa_data, mac) < 0) - { - return MCLAG_ERROR; - } - - strncpy(arpreq.arp_dev, ifname, 15); - - flags = ATF_COM; //note, must set flag, if not,you will get error - - arpreq.arp_flags = flags; - - sock_fd = socket(AF_INET, SOCK_DGRAM, 0); - if (sock_fd < 0) - { - return MCLAG_ERROR; - } - - rc = ioctl(sock_fd, SIOCSARP, &arpreq); - if (rc < 0) - { - close(sock_fd); - return MCLAG_ERROR; - } - - close(sock_fd); - - return 0; -} - -/* Delete an entry from the ARP cache. */ -int mlacp_fsm_arp_del(char *ifname, uint32_t ip) -{ - struct arpreq arpreq; - struct sockaddr_in *sin; - struct in_addr ina; - int rc; - int sock_fd = 0; - - ICCPD_LOG_DEBUG(__FUNCTION__, "Del arp entry for IP : %s ifname:%s", show_ip_str(htonl(ip)), ifname); - - if (ifname == NULL || ip == 0) - { - return MCLAG_ERROR; - } - - /*you must add this becasue some system will return "Invlid argument" - because some argument isn't zero */ - memset(&arpreq, 0, sizeof(struct arpreq)); - - sin = (struct sockaddr_in *)&arpreq.arp_pa; - memset(sin, 0, sizeof(struct sockaddr_in)); - sin->sin_family = AF_INET; - ina.s_addr = htonl(ip); - memcpy(&sin->sin_addr, (char *)&ina, sizeof(struct in_addr)); - - strncpy(arpreq.arp_dev, ifname, 15); - - sock_fd = socket(AF_INET, SOCK_DGRAM, 0); - if (sock_fd < 0) - { - return MCLAG_ERROR; - } - - rc = ioctl(sock_fd, SIOCDARP, &arpreq); - if (rc < 0) - { - close(sock_fd); - return MCLAG_ERROR; - } - - close(sock_fd); - - return 0; -} - static int arp_set_handler(struct CSM* csm, struct LocalInterface* lif, int add) @@ -223,7 +131,7 @@ static int arp_set_handler(struct CSM* csm, arp_msg = (struct ARPMsg*)msg->buf; /* only process add*/ - if (arp_msg->op_type == ARP_SYNC_DEL) + if (arp_msg->op_type == NEIGH_SYNC_DEL) continue; /* find the ARP for lif_list*/ @@ -233,9 +141,9 @@ static int arp_set_handler(struct CSM* csm, 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]); - mlacp_fsm_arp_set(arp_msg->ifname, arp_msg->ipv4_addr, mac_str); + 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(htonl(arp_msg->ipv4_addr)));*/ + show_ip_str(arp_msg->ipv4_addr));*/ } goto done; @@ -250,19 +158,82 @@ static int arp_set_handler(struct CSM* csm, continue; /* don't process del*/ - if (arp_msg->op_type == ARP_SYNC_DEL) + if (arp_msg->op_type == NEIGH_SYNC_DEL) continue; /* link broken, del all dynamic arp on the lif*/ - mlacp_fsm_arp_del(arp_msg->ifname, arp_msg->ipv4_addr); + 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(htonl(arp_msg->ipv4_addr)));*/ + 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 * @@ -286,20 +257,13 @@ static void set_route_by_linux_route(struct CSM* csm, return; sprintf(ipv4_dest_str, "%s", show_ip_str(htonl(local_if->ipv4_addr))); - ptr = strrchr(ipv4_dest_str, '.'); strcpy(ptr, ".0\0"); + ptr = strrchr(ipv4_dest_str, '.'); + strcpy(ptr, ".0\0"); -#if 1 - /* set gw route*/ - /*sprintf(syscmd, "ip route %s %s/%d proto static metric 200 nexthop via %s > /dev/null 2>&1",*/ + /* 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); -#else - // set interface route - sprintf(syscmd, "route %s -net %s/%d %s > /dev/null 2>&1", - (is_add) ? "add" : "del", ipv4_dest_str, local_if->prefixlen, - local_if->name); -#endif + (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); @@ -374,12 +338,14 @@ static void set_l3_itf_state(struct CSM *csm, 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 */ } } @@ -428,7 +394,7 @@ static void mlacp_clean_fdb(void) if (sys->sync_fd) write(sys->sync_fd, msg_buf, msg_hdr->len); - ICCPD_LOG_DEBUG(__FUNCTION__, "Notify mclagsyncd to clear FDB"); + ICCPD_LOG_NOTICE(__FUNCTION__, "Notify mclagsyncd to clear FDB"); return; } @@ -467,7 +433,7 @@ void set_peerlink_mlag_port_learn(struct LocalInterface *lif, int enable) msg_hdr->len += sizeof(mclag_sub_option_hdr_t); msg_hdr->len += sub_msg->op_len; - ICCPD_LOG_DEBUG(__FUNCTION__, "Send %s port MAC learn msg to mclagsyncd for %s", + 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*/ @@ -489,12 +455,12 @@ static void set_peerlink_mlag_port_kernel_forward( sprintf(cmd, "ebtables %s FORWARD -i %s -o %s -j DROP", "-D", csm->peer_link_if->name, lif->name); - ICCPD_LOG_DEBUG(__FUNCTION__, " ebtable cmd %s", cmd ); + 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_DEBUG(__FUNCTION__, " ebtable cmd %s", cmd ); + ICCPD_LOG_NOTICE(__FUNCTION__, " ebtable cmd %s", cmd ); system(cmd); return; @@ -600,11 +566,11 @@ void update_peerlink_isolate_from_all_csm_lif( if (dst_len) { memcpy(sub_msg->data, mlag_po_buf, dst_len); - ICCPD_LOG_DEBUG(__FUNCTION__, "Send port isolate msg to mclagsyncd, src port %s, dst port %s", csm->peer_link_if->name, mlag_po_buf); + 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_DEBUG(__FUNCTION__, "Send port isolate msg to mclagsyncd, src port %s, dst port is NULL", csm->peer_link_if->name); + ICCPD_LOG_NOTICE(__FUNCTION__, "Send port isolate msg to mclagsyncd, src port %s, dst port is NULL", csm->peer_link_if->name); } /*send msg*/ @@ -902,7 +868,7 @@ void syn_arp_info_to_peer(struct CSM *csm, struct LocalInterface *local_if) continue; arp_msg = (struct ARPMsg*)msg->buf; - arp_msg->op_type = ARP_SYNC_ADD; + arp_msg->op_type = NEIGH_SYNC_ADD; if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, sizeof(struct ARPMsg)) == 0) { @@ -912,13 +878,46 @@ void syn_arp_info_to_peer(struct CSM *csm, struct LocalInterface *local_if) } else ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[ADD] for %s", - show_ip_str(htonl(arp_msg->ipv4_addr))); + 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) @@ -948,6 +947,7 @@ void update_stp_peer_link(struct CSM *csm, if (po_state == 1 && lif->po_active == 1) { syn_arp_info_to_peer(csm, lif); + syn_ndisc_info_to_peer(csm, lif); } } else @@ -972,6 +972,7 @@ void update_stp_peer_link(struct CSM *csm, 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); } } } @@ -1034,7 +1035,7 @@ void iccp_send_fdb_entry_to_syncd( struct MACMsg* mac_msg, uint8_t mac_type) mac_info->op_type = mac_msg->op_type; msg_hdr->len = sizeof(struct IccpSyncdHDr) + sizeof(struct mclag_fdb_info); - ICCPD_LOG_DEBUG(__FUNCTION__, "Send mac %s msg to mclagsyncd, vid %d ; ifname %s ; mac %s; type %s", + 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*/ @@ -1141,7 +1142,7 @@ static void update_l2_mac_state(struct CSM *csm, /*portchannel down*/ if (po_state == 0) { - ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s down, age local MAC %s vlan-id %d", + 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); @@ -1180,7 +1181,7 @@ static void update_l2_mac_state(struct CSM *csm, memcpy(mac_msg->ifname, csm->peer_itf_name, IFNAMSIZ); } - ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s down, redirect MAC %s vlan-id %d to peer-link %s", + 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 @@ -1188,7 +1189,7 @@ static void update_l2_mac_state(struct CSM *csm, /*peer-link is not configured, del mac from ASIC, mac still in mac_list*/ del_mac_from_chip(mac_msg); - ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s down, peer-link is not configured: MAC %s vlan-id %d", + 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); } } @@ -1199,7 +1200,7 @@ static void update_l2_mac_state(struct CSM *csm, /*when this portchannel up, recover the mac back*/ if (strcmp(mac_msg->ifname, csm->peer_itf_name) == 0) { - ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s up, redirect MAC %s vlan-id %d from peerlink to %s", + 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*/ @@ -1215,7 +1216,7 @@ static void update_l2_mac_state(struct CSM *csm, { /*this may be peerlink is not configured and portchannel is down*/ /*when this portchannel up, add the mac back to ASIC*/ - ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s up, add MAC %s vlan-id %d 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*/ @@ -1319,7 +1320,7 @@ static void mlacp_fix_bridge_mac(struct CSM* csm) /*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_DEBUG(__FUNCTION__, " %s ret = %d", syscmd, ret); + ICCPD_LOG_NOTICE(__FUNCTION__, " %s ret = %d", syscmd, ret); } return; @@ -1345,7 +1346,7 @@ void mlacp_peer_conn_handler(struct CSM* csm) { /*If peer reconnected, reset peer disconnect time*/ csm->warm_reboot_disconn_time = 0; - ICCPD_LOG_DEBUG(__FUNCTION__, "Peer warm reboot and reconnect, reset peer disconnect time!"); + ICCPD_LOG_NOTICE(__FUNCTION__, "Peer warm reboot and reconnect, reset peer disconnect time!"); } if (csm->peer_link_if) @@ -1368,36 +1369,10 @@ void mlacp_peer_conn_handler(struct CSM* csm) mlacp_conn_handler_fdb(csm); -#if 0 - // When peer-link ready, suppose all MLAG link are alive - LIST_FOREACH(pif, &(MLACP(csm).pif_list), mlacp_next) - { - pif->po_active = 1; - } -#endif LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next) { if (lif->type == IF_T_PORT_CHANNEL) { -#if 0 - if (local_if_is_l3_mode(lif)) - { - set_route_by_linux_route( csm, lif, 1); - } - else - { - LIST_FOREACH(vlan, &(lif->vlan_list), port_next) - { - if (!vlan->vlan_itf) - continue; - if (!local_if_is_l3_mode(vlan->vlan_itf)) - continue; - - set_route_by_linux_route(csm, vlan->vlan_itf, 1); /* add static route by linux route tool*/ - } - } -#endif - mlacp_portchannel_state_handler(csm, lif, (lif->state == PORT_STATE_UP) ? 1 : 0); } } @@ -1432,7 +1407,7 @@ void mlacp_peer_disconn_handler(struct CSM* csm) /*peer connection must be establised again within 90s from last disconnection for peer warm reboot*/ time(&csm->warm_reboot_disconn_time); - ICCPD_LOG_DEBUG(__FUNCTION__, "Peer warm reboot and disconnect, recover to normal reboot for next time!"); + ICCPD_LOG_NOTICE(__FUNCTION__, "Peer warm reboot and disconnect, recover to normal reboot for next time!"); return; } @@ -1448,7 +1423,7 @@ void mlacp_peer_disconn_handler(struct CSM* csm) if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0 && mac_msg->age_flag != (MAC_AGE_LOCAL | MAC_AGE_PEER)) continue; - ICCPD_LOG_DEBUG(__FUNCTION__, "Peer disconnect, del MAC for peer-link: %s, MAC %s vlan-id %d", + 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*/ @@ -1493,7 +1468,7 @@ void mlacp_peerlink_up_handler(struct CSM* csm) if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0) continue; - ICCPD_LOG_DEBUG(__FUNCTION__, "Peer link up, add MAC to ASIC for peer-link: %s, MAC %s vlan-id %d", + 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*/ @@ -1520,7 +1495,7 @@ void mlacp_peerlink_down_handler(struct CSM* csm) if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0) continue; - ICCPD_LOG_DEBUG(__FUNCTION__, "Peer link down, del MAC for peer-link: %s, MAC %s vlan-id %d", + 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); @@ -1686,17 +1661,7 @@ void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, ch mac_msg->age_flag = 0; - ICCPD_LOG_DEBUG(__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"); - /*Debug*/ - #if 0 - /* dump receive MAC info*/ - fprintf(stderr, "\n======== MAC Update==========\n"); - fprintf(stderr, " MAC = %s\n", mac_str); - fprintf(stderr, " vlan id = %d\n", vid); - fprintf(stderr, " fdb type = %s\n", fdb_type == MAC_TYPE_STATIC ? "static" : "dynamic"); - fprintf(stderr, " op type = %s\n", op_type == MAC_SYNC_ADD ? "add" : "del"); - fprintf(stderr, "==============================\n"); - #endif + 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) @@ -1868,7 +1833,7 @@ void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, ch /*peer-link learn mac is control by iccpd, ignore the chip del info*/ add_mac_to_chip(mac_info, MAC_TYPE_DYNAMIC); - ICCPD_LOG_DEBUG(__FUNCTION__, "Recv MAC del msg: %s(peer-link is up), add back %s vlan-id %d", + 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); } @@ -1890,7 +1855,7 @@ void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, ch } else { - ICCPD_LOG_DEBUG(__FUNCTION__, "Recv MAC del msg: %s, del %s vlan-id %d, peer is not age, add back to chip", + 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; @@ -1905,7 +1870,7 @@ void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, ch if (csm->peer_link_if && csm->peer_link_if->state == PORT_STATE_UP) { add_mac_to_chip(mac_info, MAC_TYPE_DYNAMIC); - ICCPD_LOG_DEBUG(__FUNCTION__, "Recv MAC del msg: %s(down), del %s vlan-id %d, redirect to peer-link", + 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); } } @@ -1984,6 +1949,9 @@ char * mclagd_ctl_cmd_str(int req_type) case INFO_TYPE_DUMP_ARP: return "dump arp"; + case INFO_TYPE_DUMP_NDISC: + return "dump nd"; + case INFO_TYPE_DUMP_MAC: return "dump mac"; @@ -2205,6 +2173,46 @@ void mclagd_ctl_handle_dump_arp(int client_fd, int mclag_id) 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; @@ -2375,6 +2383,10 @@ int mclagd_ctl_interactive_process(int client_fd) 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; diff --git a/src/iccpd/src/mlacp_sync_prepare.c b/src/iccpd/src/mlacp_sync_prepare.c index f40a59884e49..ef1cd244a90a 100644 --- a/src/iccpd/src/mlacp_sync_prepare.c +++ b/src/iccpd/src/mlacp_sync_prepare.c @@ -326,7 +326,7 @@ int mlacp_prepare_for_mac_info_to_peer(struct CSM* csm, char* buf, size_t max_bu sprintf(MacData->ifname, "%s", mac_msg->origin_ifname); MacData->vid = htons(mac_msg->vid); - ICCPD_LOG_DEBUG(__FUNCTION__, "Send MAC messge to peer, port %s mac = %s, vid = %d, type = %s count %d ", mac_msg->origin_ifname, + 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; @@ -370,15 +370,68 @@ int mlacp_prepare_for_arp_info(struct CSM* csm, char* buf, size_t max_buf_size, tlv->icc_parameter.type = htons(TLV_T_MLACP_ARP_INFO); } - ArpData = (struct mLACPMACData *)&buf[sizeof(ICCHdr) + sizeof(struct mLACPARPInfoTLV) + sizeof(struct ARPMsg) * count]; + 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 = htonl(arp_msg->ipv4_addr); + ArpData->ipv4_addr = arp_msg->ipv4_addr; memcpy(ArpData->mac_addr, arp_msg->mac_addr, ETHER_ADDR_LEN); - ICCPD_LOG_DEBUG(__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)); + 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; } @@ -597,7 +650,7 @@ int mlacp_prepare_for_warm_reboot(struct CSM* csm, char* buf, size_t max_buf_siz tlv->icc_parameter.len = htons(sizeof(struct mLACPWarmbootTLV) - sizeof(ICCParameter)); tlv->warmboot = 0x1; - ICCPD_LOG_DEBUG(__FUNCTION__, "Send warm reboot notification to peer!"); + ICCPD_LOG_NOTICE(__FUNCTION__, "Send warm reboot notification to peer!"); return msg_len; } diff --git a/src/iccpd/src/mlacp_sync_update.c b/src/iccpd/src/mlacp_sync_update.c index 40dc33187885..b82fc1c16cb9 100644 --- a/src/iccpd/src/mlacp_sync_update.c +++ b/src/iccpd/src/mlacp_sync_update.c @@ -33,6 +33,7 @@ #include "../include/mlacp_link_handler.h" #include "../include/iccp_consistency_check.h" #include "../include/port.h" +#include "../include/iccp_netlink.h" /***************************************** * Port-Conf Update * @@ -166,7 +167,7 @@ int mlacp_fsm_update_mac_entry_from_peer( struct CSM* csm, struct mLACPMACData * struct LocalInterface* local_if = NULL; uint8_t from_mclag_intf = 0;/*0: orphan port, 1: MCLAG port*/ - ICCPD_LOG_INFO(__FUNCTION__, + 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"); @@ -266,27 +267,7 @@ int mlacp_fsm_update_mac_entry_from_peer( struct CSM* csm, struct mLACPMACData * add_mac_to_chip(mac_msg, MAC_TYPE_DYNAMIC); } } - - #if 0 - mac_msg->op_type = MAC_SYNC_ACK; - if (iccp_csm_init_msg(&msg_send, (char*)mac_msg, sizeof(struct MACMsg)) == 0) - { - /*Reply mac ack message to peer, peer will clean MAC_AGE_PEER flag*/ - TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg_send, tail); - ICCPD_LOG_DEBUG(__FUNCTION__, "Recv ADD, MAC-msg-list enqueue: %s, add %s vlan-id %d, op_type %d", - mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->op_type); - } - #endif - } - #if 0 - else if (tlv->type == MAC_SYNC_ACK) - { - /*Clean the MAC_AGE_PEER flag*/ - mac_msg->age_flag &= ~MAC_AGE_PEER; - ICCPD_LOG_DEBUG(__FUNCTION__, "Recv ACK, Remove peer age flag:%d ifname %s, add %s vlan-id %d, op_type %d", - mac_msg->age_flag, mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->op_type); } - #endif break; } @@ -332,7 +313,7 @@ int mlacp_fsm_update_mac_entry_from_peer( struct CSM* csm, struct mLACPMACData * if (strlen(csm->peer_itf_name) == 0) { - ICCPD_LOG_DEBUG(__FUNCTION__, "From orphan port or portchannel is down, but peer-link is not configured: ifname %s, MAC %s vlan-id %d", + 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*/ @@ -344,7 +325,7 @@ int mlacp_fsm_update_mac_entry_from_peer( struct CSM* csm, struct mLACPMACData * /*Redirect the mac to peer-link*/ memcpy(&mac_msg->ifname, csm->peer_itf_name, IFNAMSIZ); - ICCPD_LOG_DEBUG(__FUNCTION__, "Redirect to peerlink for orphan port or portchannel is down, Add local age flag: %d ifname %s, MAC %s vlan-id %d", + 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); } } @@ -371,17 +352,6 @@ int mlacp_fsm_update_mac_entry_from_peer( struct CSM* csm, struct mLACPMACData * /*from MCLAG port and the local port is up*/ add_mac_to_chip(mac_msg, mac_msg->fdb_type); } - - #if 0 - mac_msg->op_type = MAC_SYNC_ACK; - if (iccp_csm_init_msg(&msg_send, (char*)mac_msg, sizeof(struct MACMsg)) == 0) - { - /*Reply mac ack message to peer, peer will clean MAC_AGE_PEER flag*/ - 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, op_type %d", - mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->op_type); - } - #endif } } @@ -422,7 +392,7 @@ void mlacp_enqueue_arp(struct CSM* csm, struct Msg* msg) return; arp_msg = (struct ARPMsg*)msg->buf; - if (arp_msg->op_type != ARP_SYNC_DEL) + if (arp_msg->op_type != NEIGH_SYNC_DEL) { TAILQ_INSERT_TAIL(&(MLACP(csm).arp_list), msg, tail); } @@ -430,6 +400,32 @@ void mlacp_enqueue_arp(struct CSM* csm, struct Msg* msg) 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 * ***************************************/ @@ -449,7 +445,7 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) 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_INFO(__FUNCTION__, + 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], @@ -537,9 +533,9 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) /* set dynamic ARP*/ if (set_arp_flag == 1) { - if (arp_entry->op_type == ARP_SYNC_ADD) + if (arp_entry->op_type == NEIGH_SYNC_ADD) { - if (mlacp_fsm_arp_set(arp_entry->ifname, ntohl(arp_entry->ipv4_addr), mac_str) < 0) + 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); @@ -548,7 +544,7 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) } else { - if (mlacp_fsm_arp_del(arp_entry->ifname, ntohl(arp_entry->ipv4_addr)) < 0) + 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); @@ -561,7 +557,7 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) } else { - ICCPD_LOG_DEBUG(__FUNCTION__, "Failure: port-channel is not alive"); + ICCPD_LOG_NOTICE(__FUNCTION__, "Failure: port-channel is not alive"); /*TODO Set static route through peer-link or just skip it?*/ } @@ -569,7 +565,7 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) TAILQ_FOREACH(msg, &(MLACP(csm).arp_list), tail) { arp_msg = (struct ARPMsg*)msg->buf; - if (arp_msg->ipv4_addr == ntohl(arp_entry->ipv4_addr)) + if (arp_msg->ipv4_addr == arp_entry->ipv4_addr) { /*arp_msg->op_type = tlv->type;*/ sprintf(arp_msg->ifname, "%s", arp_entry->ifname); @@ -579,18 +575,18 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) } /* delete/add ARP list*/ - if (msg && arp_entry->op_type == ARP_SYNC_DEL) + 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 == ARP_SYNC_ADD) + 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 = ntohl(arp_entry->ipv4_addr); + 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) @@ -604,7 +600,7 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) TAILQ_FOREACH(msg, &(MLACP(csm).arp_msg_list), tail) { arp_msg = (struct ARPMsg*)msg->buf; - if (arp_msg->ipv4_addr == ntohl(arp_entry->ipv4_addr)) + if (arp_msg->ipv4_addr == arp_entry->ipv4_addr) break; } @@ -617,7 +613,7 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry) TAILQ_FOREACH(msg, &(MLACP(csm).arp_msg_list), tail) { arp_msg = (struct ARPMsg*)msg->buf; - if (arp_msg->ipv4_addr == ntohl(arp_entry->ipv4_addr)) + if (arp_msg->ipv4_addr == arp_entry->ipv4_addr) break; } } @@ -641,6 +637,216 @@ int mlacp_fsm_update_arp_info(struct CSM* csm, struct mLACPARPInfoTLV* tlv) } } +/***************************************** +* 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 * ***************************************/ @@ -703,10 +909,10 @@ int mlacp_fsm_update_peerlink_info(struct CSM* csm, } if (csm->peer_link_if->type != tlv->port_type) - ICCPD_LOG_DEBUG(__FUNCTION__, "Peerlink port type of peer %d is not same with local %d !", tlv->port_type, csm->peer_link_if->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_DEBUG(__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); + 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; } @@ -733,7 +939,7 @@ int mlacp_fsm_update_warmboot(struct CSM* csm, struct mLACPWarmbootTLV* tlv) return MCLAG_ERROR; time(&csm->peer_warm_reboot_time); - ICCPD_LOG_DEBUG(__FUNCTION__, "Receive warm reboot notification from peer!"); + 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 index 1414a1f86c87..e63429a77c2e 100644 --- a/src/iccpd/src/port.c +++ b/src/iccpd/src/port.c @@ -28,6 +28,8 @@ #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) { @@ -329,11 +331,12 @@ void local_if_destroy(char *ifname) 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) + if (local_if->ipv4_addr != 0 || memcmp(local_if->ipv6_addr, addr_null, 16) != 0) ret = 1; return ret; diff --git a/src/iccpd/src/scheduler.c b/src/iccpd/src/scheduler.c index 9d08e137dce0..0ff9d4f5e083 100644 --- a/src/iccpd/src/scheduler.c +++ b/src/iccpd/src/scheduler.c @@ -312,7 +312,7 @@ void scheduler_init() iccp_config_from_file(sys->config_file_path); /*Get kernel ARP info */ - iccp_arp_get_init(); + iccp_neigh_get_init(); if (iccp_connect_syncd() < 0) { @@ -731,7 +731,10 @@ int scheduler_unregister_sock_read_event_callback(struct CSM* csm) return MCLAG_ERROR; } - FD_CLR(csm->sock_fd, &(sys->readfd)); + if (csm->sock_fd > 0) + { + FD_CLR(csm->sock_fd, &(sys->readfd)); + } return 0; } diff --git a/src/iccpd/src/system.c b/src/iccpd/src/system.c index 9665b416ca52..33aca67f8079 100644 --- a/src/iccpd/src/system.c +++ b/src/iccpd/src/system.c @@ -57,6 +57,7 @@ void system_init(struct System* sys) 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; @@ -132,6 +133,8 @@ void system_finalize() 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) 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/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..faf80b287f0f 100644 --- a/src/initramfs-tools/Makefile +++ b/src/initramfs-tools/Makefile @@ -5,12 +5,12 @@ 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 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/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/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..3268ab5afea3 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 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/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/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/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/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/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..fa997e3486c8 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 diff --git a/src/lm-sensors/.gitignore b/src/lm-sensors/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/lm-sensors/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile 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/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/python-click/.gitignore b/src/python-click/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/python-click/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/python3/.gitignore b/src/python3/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/python3/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/radvd/.gitignore b/src/radvd/.gitignore new file mode 100644 index 000000000000..d19db76ab9a9 --- /dev/null +++ b/src/radvd/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!Makefile +!patch/ 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/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/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/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/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/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..5e5c2a88098a 100644 --- a/src/snmpd/Makefile +++ b/src/snmpd/Makefile @@ -19,10 +19,7 @@ $(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 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/sonic-config-engine/.gitignore b/src/sonic-config-engine/.gitignore new file mode 100644 index 000000000000..e41d5b085e5b --- /dev/null +++ b/src/sonic-config-engine/.gitignore @@ -0,0 +1,2 @@ +dist/ +tests/output diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index c640d1378614..b560df3332cd 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -14,6 +14,7 @@ from lxml.etree import QName from portconfig import get_port_config +from sonic_device_util import get_npu_id_from_name """minigraph.py version_added: "1.9" @@ -34,6 +35,10 @@ VLAN_SUB_INTERFACE_SEPARATOR = '.' VLAN_SUB_INTERFACE_VLAN_ID = '10' +FRONTEND_ASIC_SUB_ROLE = 'FrontEnd' +BACKEND_ASIC_SUB_ROLE = 'BackEnd' +BACKEND_ASIC_INTERFACE_NAME_PREFIX = 'Ethernet-BP' + # Default Virtual Network Index (VNI) vni_default = 8000 @@ -118,14 +123,13 @@ 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): endport = port_alias_map[endport] neighbors[endport] = {'name': startdevice, 'port': startport} if bandwidth: port_speeds[endport] = bandwidth - else: + elif startdevice.lower() == hname.lower(): if port_alias_map.has_key(startport): startport = port_alias_map[startport] neighbors[startport] = {'name': enddevice, 'port': endport} @@ -159,9 +163,113 @@ def parse_png(png, hname): return (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speeds, console_ports) +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 ((port_alias_asic_map.has_key(endport)) 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 ((port_alias_asic_map.has_key(startport)) 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 port_alias_map.has_key(endport): + 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 port_alias_map.has_key(startport): + 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, mgmt_prefix, name, hwsku, d_type, deployment_id) = parse_device(device) + device_data = {'lo_addr': lo_prefix, 'type': d_type, 'mgmt_addr': mgmt_prefix, 'hwsku': hwsku } + if deployment_id: + device_data['deployment_id'] = deployment_id + devices[name] = device_data + return (neighbors, devices, port_speeds) def parse_dpg(dpg, hname): + aclintfs = None + mgmtintfs = None 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 @@ -197,7 +305,6 @@ 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 @@ -254,7 +361,6 @@ def parse_dpg(dpg, hname): 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"))): if aclintf.find(str(QName(ns, "InAcl"))) is not None: @@ -287,8 +393,8 @@ def parse_dpg(dpg, hname): # 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'): + 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 @@ -299,7 +405,9 @@ 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: @@ -369,7 +477,7 @@ def parse_cpg(cpg, hname): 'keepalive': keepalive, 'nhopself': nhopself } - else: + elif start_router.lower() == hname.lower(): bgp_sessions[end_peer.lower()] = { 'name': end_router, 'local_addr': start_peer.lower(), @@ -419,6 +527,8 @@ def parse_meta(meta, hname): mgmt_routes = [] erspan_dst = [] deployment_id = None + region = None + cloudtype = 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(): @@ -441,7 +551,57 @@ 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 + return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype + + +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 + + 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 + + linkmetas[port] = {} + if fec_disabled: + linkmetas[port]["FECDisabled"] = fec_disabled + 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 = {} @@ -477,8 +637,7 @@ def parse_spine_chassis_fe(results, vni, lo_intfs, phyport_intfs, pc_intfs, pc_m lo_network = ipaddress.IPNetwork(lo[1]) if lo_network.version == 4: lo_addr = str(lo_network.ip) - break - + break results['VXLAN_TUNNEL'] = {chassis_vxlan_tunnel: { 'src_ip': lo_addr }} @@ -517,7 +676,7 @@ 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) @@ -537,37 +696,93 @@ 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. - """ +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 = [] + + # Get the front panel port channel. It will use port_alias_asic_map + # which will get populated from port_config.ini for Multi-NPU + # architecture + for port_channel_intf in port_channels: + backend_port_channel = any(lag_member in port_alias_asic_map \ + and lag_member.startswith(BACKEND_ASIC_INTERFACE_NAME_PREFIX) \ + 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.iteritems(): 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', []): + if port in port_alias_asic_map and port.startswith(BACKEND_ASIC_INTERFACE_NAME_PREFIX): + continue + 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) - acls[acl_table]['ports'] = active_ports + filter_acls[acl_table]['ports'] = active_ports + + return filter_acls - return 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): +def parse_xml(filename, platform=None, port_config_file=None, asic_name=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. + """ root = ET.parse(filename).getroot() - mini_graph_path = filename u_neighbors = None u_devices = None @@ -585,7 +800,7 @@ def parse_xml(filename, platform=None, port_config_file=None): lo_intfs = None neighbors = None devices = None - hostname = None + sub_role = None docker_routing_config_mode = "separated" port_speeds_default = {} port_speed_png = {} @@ -599,6 +814,16 @@ 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 = {} + + # hostname is the asic_name, get the asic_id from the asic_name + if asic_name is not None: + asic_id = get_npu_id_from_name(asic_name) + else: + asic_id = None hwsku_qn = QName(ns, "HwSku") hostname_qn = QName(ns, "Hostname") @@ -611,33 +836,66 @@ 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) port_alias_map.update(alias_map) + port_alias_asic_map.update(alias_asic_map) + 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) = 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, region, cloudtype) = 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) = parse_dpg(child, asic_name) + elif child.tag == str(QName(ns, "CpgDec")): + (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name) + enable_internal_bgp_session(bgp_sessions, filename, asic_name) + 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'] + 'type': device_type } } + # 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 results['BGP_NEIGHBOR'] = bgp_sessions results['BGP_MONITORS'] = bgp_monitors results['BGP_PEER_RANGE'] = bgp_peers_with_range @@ -698,14 +956,23 @@ def parse_xml(filename, platform=None, port_config_file=None): 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 >> sys.stderr, "Warning: ignore interface '%s' as it is not in the port_config.ini" % port_name + continue ports.setdefault(port_name, {})['speed'] = port_speed_png[port_name] for port_name, port in ports.items(): - if port.get('speed') == '100000': + # get port alias from port_config.ini + if port_config_file: + alias = port.get('alias') + else: + 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' # set port description if parsed from deviceinfo @@ -804,16 +1071,19 @@ def parse_xml(filename, platform=None, port_config_file=None): for nghbr in neighbors.keys(): # remove port not in port_config.ini if nghbr not in ports: - print >> sys.stderr, "Warning: ignore interface '%s' in DEVICE_NEIGHBOR as it is not in the port_config.ini" % nghbr + if port_config_file is not None: + print >> sys.stderr, "Warning: ignore interface '%s' in DEVICE_NEIGHBOR as it is not in the port_config.ini" % nghbr del neighbors[nghbr] - results['DEVICE_NEIGHBOR'] = neighbors - results['DEVICE_NEIGHBOR_METADATA'] = { key:devices[key] for key in devices if key.lower() != hostname.lower() } + 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' @@ -831,7 +1101,19 @@ def parse_xml(filename, platform=None, port_config_file=None): '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', + 'client_ca_crt': '/etc/sonic/credentials/restapiclient.crt', + 'client_crt_cname': 'client.restapi.sonic' + } + } # Do not configure the minigraph's mirror session, which is currently unused # mirror_sessions = {} # if erspan_dst: @@ -873,8 +1155,17 @@ def parse_device_desc_xml(filename): 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 port_alias_map = {} +port_alias_asic_map = {} def print_parse_xml(filename): diff --git a/src/sonic-config-engine/portconfig.py b/src/sonic-config-engine/portconfig.py index db2baa308174..87e13687ed55 100644 --- a/src/sonic-config-engine/portconfig.py +++ b/src/sonic-config-engine/portconfig.py @@ -3,11 +3,13 @@ import sys -def get_port_config_file_name(hwsku=None, platform=None): +def get_port_config_file_name(hwsku=None, platform=None, asic=None): port_config_candidates = [] port_config_candidates.append('/usr/share/sonic/hwsku/port_config.ini') if hwsku: if platform: + if asic: + port_config_candidates.append(os.path.join('/usr/share/sonic/device', platform, hwsku, asic,'port_config.ini')) 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')) @@ -17,17 +19,19 @@ def get_port_config_file_name(hwsku=None, platform=None): 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, asic=None): if not port_config_file: - port_config_file = get_port_config_file_name(hwsku, platform) + port_config_file = get_port_config_file_name(hwsku, platform, asic) if not port_config_file: - return ({}, {}) + return ({}, {}, {}) 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 +53,14 @@ 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) diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index dddfde32428b..c247d85abec3 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -37,13 +37,15 @@ from functools import partial from minigraph import minigraph_encoder from minigraph import parse_xml from minigraph import parse_device_desc_xml +from minigraph import parse_asic_sub_role 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 sonic_device_util import get_npu_id_from_name from config_samples import generate_sample_config from config_samples import get_available_config -from swsssdk import SonicV2Connector, ConfigDBConnector +from swsssdk import SonicV2Connector, ConfigDBConnector, SonicDBConfig from redis_bcc import RedisBytecodeCache from collections import OrderedDict from natsort import natsorted @@ -195,6 +197,7 @@ 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("-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=[]) @@ -204,6 +207,7 @@ def main(): 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") + 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') @@ -221,13 +225,22 @@ def main(): data = {} hwsku = args.hwsku + asic_name = args.namespace + asic_id = None + if asic_name is not None: + asic_id = get_npu_id_from_name(asic_name) + + + # 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) + (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) @@ -241,11 +254,11 @@ def main(): minigraph = args.minigraph if platform: if args.port_config != None: - deep_update(data, parse_xml(minigraph, platform, args.port_config)) + deep_update(data, parse_xml(minigraph, platform, args.port_config, asic_name=asic_name)) 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)) if args.device_description != None: deep_update(data, parse_device_desc_xml(args.device_description)) @@ -262,20 +275,44 @@ def main(): deep_update(data, json.loads(args.additional_data)) if args.from_db: - configdb = ConfigDBConnector(**db_kwargs) + if args.namespace is None: + configdb = ConfigDBConnector(**db_kwargs) + else: + configdb = ConfigDBConnector(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 = get_system_mac(namespace=asic_name) + else: + mac = get_system_mac() + else: + mac = 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: + if args.template is not None: template_file = os.path.abspath(args.template) paths = ['/', '/usr/share/sonic/templates', os.path.dirname(template_file)] + if args.template_dir is not None: + template_dir = os.path.abspath(args.template_dir) + paths.append(template_dir) loader = jinja2.FileSystemLoader(paths) redis_bcc = RedisBytecodeCache(SonicV2Connector(host='127.0.0.1')) @@ -302,7 +339,11 @@ def main(): 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 = ConfigDBConnector(**db_kwargs) + else: + configdb = ConfigDBConnector(use_unix_socket_path=True, namespace=args.namespace, **db_kwargs) + configdb.connect(False) configdb.mod_config(FormatConverter.output_to_db(data)) diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index 34877600fd13..5984a7047fe7 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -3,6 +3,9 @@ import yaml import subprocess import re +from natsort import natsorted +import glob +from swsssdk import ConfigDBConnector, SonicDBConfig DOCUMENTATION = ''' --- @@ -17,6 +20,12 @@ TODO: this file shall be renamed and moved to other places in future to have it shared with multiple applications. ''' +SONIC_DEVICE_PATH = '/usr/share/sonic/device' +NPU_NAME_PREFIX = 'asic' +NAMESPACE_PATH_GLOB = '/run/netns/*' +ASIC_CONF_FILENAME = 'asic.conf' +FRONTEND_ASIC_SUB_ROLE = 'FrontEnd' +BACKEND_ASIC_SUB_ROLE = 'BackEnd' def get_machine_info(): if not os.path.isfile('/host/machine.conf'): return None @@ -27,7 +36,86 @@ def get_machine_info(): if len(tokens) < 2: continue machine_vars[tokens[0]] = tokens[1].strip() - return machine_vars + return machine_vars + +def get_npu_id_from_name(npu_name): + if npu_name.startswith(NPU_NAME_PREFIX): + return npu_name[len(NPU_NAME_PREFIX):] + else: + return None + +def get_num_npus(): + platform = get_platform_info(get_machine_info()) + if not platform: + return 1 + asic_conf_file_path = os.path.join(SONIC_DEVICE_PATH, platform, ASIC_CONF_FILENAME) + if not os.path.isfile(asic_conf_file_path): + return 1 + with open(asic_conf_file_path) as asic_conf_file: + for line in asic_conf_file: + tokens = line.split('=') + if len(tokens) < 2: + continue + if tokens[0].lower() == 'num_asic': + num_npus = tokens[1].strip() + return int(num_npus) + +def get_namespaces(): + """ + In a multi NPU platform, each NPU is in a Linux Namespace. + This method returns list of all the Namespace present on the device + """ + ns_list = [] + for path in glob.glob(NAMESPACE_PATH_GLOB): + ns = os.path.basename(path) + ns_list.append(ns) + return natsorted(ns_list) + +def get_hwsku(): + config_db = ConfigDBConnector() + config_db.connect() + metadata = config_db.get_table('DEVICE_METADATA') + return metadata['localhost']['hwsku'] + +def get_platform(): + if not os.path.isfile('/host/machine.conf'): + return '' + + with open('/host/machine.conf') as machine_conf: + for line in machine_conf: + tokens = line.split('=') + if tokens[0].strip() == 'onie_platform' or tokens[0].strip() == 'aboot_platform': + return tokens[1].strip() + return '' + +def is_multi_npu(): + num_npus = get_num_npus() + return (num_npus > 1) + +def get_all_namespaces(): + """ + In case of Multi-Asic platform, Each ASIC will have a linux network namespace created. + So we loop through the databases in different namespaces and depending on the sub_role + decide whether this is a front end ASIC/namespace or a back end one. + """ + front_ns = [] + back_ns = [] + num_npus = get_num_npus() + SonicDBConfig.load_sonic_global_db_config() + + if is_multi_npu(): + for npu in range(num_npus): + namespace = "{}{}".format(NPU_NAME_PREFIX, npu) + config_db = ConfigDBConnector(use_unix_socket_path=True, namespace=namespace) + config_db.connect() + + metadata = config_db.get_table('DEVICE_METADATA') + if metadata['localhost']['sub_role'] == FRONTEND_ASIC_SUB_ROLE: + front_ns.append(namespace) + elif metadata['localhost']['sub_role'] == BACKEND_ASIC_SUB_ROLE: + back_ns.append(namespace) + + return {'front_ns':front_ns, 'back_ns':back_ns} def get_platform_info(machine_info): if machine_info != None: @@ -51,7 +139,7 @@ def get_sonic_version_info(): 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(): +def get_system_mac(namespace=None): version_info = get_sonic_version_info() if (version_info['asic_type'] == 'mellanox'): @@ -73,10 +161,14 @@ def get_system_mac(): # 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=' + profile_cmd = 'cat' + SONIC_DEVICE_PATH + '/' + platform +'/'+ hwsku +'/profile.ini | grep switchMacAddress | 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}'" ] + mac_address_cmd = "cat /sys/class/net/eth0/address" + if namespace is not None: + mac_address_cmd = "sudo ip netns exec {} {}".format(namespace, mac_address_cmd) + + hw_mac_entry_cmds = [mac_address_cmd] for get_mac_cmd in hw_mac_entry_cmds: proc = subprocess.Popen(get_mac_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) @@ -93,7 +185,7 @@ def get_system_mac(): # 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') + aligned_last_byte = format(int(int(last_byte, 16) + 1), '02x') mac = mac[:-2] + aligned_last_byte return mac 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..8ca17925c6ec --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml @@ -0,0 +1,1214 @@ + + + + + + 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 + Loopback0 + + 8.0.0.0/32 + + 8.0.0.0/32 + + + + + + + + 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 + Loopback0 + + 8.0.0.1/32 + + 8.0.0.1/32 + + + + + + + + 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 + Loopback0 + + 8.0.0.4/32 + + 8.0.0.4/32 + + + + + + + + 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 + Loopback0 + + 8.0.0.5/32 + + 8.0.0.5/32 + + + + + + + + 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..3fe912c98c45 --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini @@ -0,0 +1,9 @@ +# name lanes alias asic_port_name +Ethernet0 33,34,35,36 Ethernet1/1 Eth0-ASIC0 +Ethernet4 29,30,31,32 Ethernet1/2 Eth1-ASIC0 +Ethernet8 41,42,43,44 Ethernet1/3 Eth2-ASIC0 +Ethernet12 37,38,39,40 Ethernet1/4 Eth3-ASIC0 +Ethernet-BP0 13,14,15,16 Ethernet-BP0 Eth4-ASIC0 +Ethernet-BP4 17,18,19,20 Ethernet-BP4 Eth5-ASIC0 +Ethernet-BP8 21,22,23,24 Ethernet-BP8 Eth6-ASIC0 +Ethernet-BP12 25,26,27,28 Ethernet-BP12 Eth7-ASIC0 \ No newline at end of file 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..c496e0712a49 --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini @@ -0,0 +1,9 @@ +# name lanes alias asic_port_name +Ethernet16 33,34,35,36 Ethernet1/5 Eth0-ASIC1 +Ethernet20 29,30,31,32 Ethernet1/6 Eth1-ASIC1 +Ethernet24 41,42,43,44 Ethernet1/7 Eth2-ASIC1 +Ethernet28 37,38,39,40 Ethernet1/8 Eth3-ASIC1 +Ethernet-BP16 13,14,15,16 Ethernet-BP16 Eth4-ASIC1 +Ethernet-BP20 17,18,19,20 Ethernet-BP20 Eth5-ASIC1 +Ethernet-BP24 21,22,23,24 Ethernet-BP24 Eth6-ASIC1 +Ethernet-BP28 25,26,27,28 Ethernet-BP28 Eth7-ASIC1 \ No newline at end of file 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..4ae0575835a7 --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini @@ -0,0 +1,9 @@ +# name lanes alias asic_port_name +Ethernet-BP256 61,62,63,64 Ethernet-BP256 Eth0-ASIC2 +Ethernet-BP260 57,58,59,60 Ethernet-BP260 Eth1-ASIC2 +Ethernet-BP264 53,54,55,56 Ethernet-BP264 Eth2-ASIC2 +Ethernet-BP268 49,50,51,52 Ethernet-BP268 Eth3-ASIC2 +Ethernet-BP272 45,46,47,48 Ethernet-BP272 Eth4-ASIC2 +Ethernet-BP276 41,42,43,44 Ethernet-BP276 Eth5-ASIC2 +Ethernet-BP280 37,38,39,40 Ethernet-BP280 Eth6-ASIC2 +Ethernet-BP284 33,34,35,36 Ethernet-BP284 Eth7-ASIC2 \ No newline at end of file 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..8f45ed14946e --- /dev/null +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini @@ -0,0 +1,9 @@ +# name lanes alias asic_port_name +Ethernet-BP384 29,30,31,32 Ethernet-BP384 Eth0-ASIC3 +Ethernet-BP388 25,26,27,28 Ethernet-BP388 Eth1-ASIC3 +Ethernet-BP392 21,22,23,24 Ethernet-BP392 Eth2-ASIC3 +Ethernet-BP396 17,18,19,20 Ethernet-BP396 Eth3-ASIC3 +Ethernet-BP400 13,14,15,16 Ethernet-BP400 Eth4-ASIC3 +Ethernet-BP404 9,10,11,12 Ethernet-BP404 Eth5-ASIC3 +Ethernet-BP408 5,6,7,8 Ethernet-BP408 Eth6-ASIC3 +Ethernet-BP412 1,2,3,4 Ethernet-BP412 Eth7-ASIC3 \ 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_output/bgpd_frr.conf b/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf index 566d6384fcfd..1f0f97e2ff57 100644 --- a/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf @@ -1,9 +1,13 @@ ! +! 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 @@ -11,79 +15,57 @@ 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 ! -route-map FROM_BGP_SPEAKER_V4 permit 10 +! BGP configuration ! -route-map TO_BGP_SPEAKER_V4 deny 10 +! TSA configuration ! 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 ! +ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 ! -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 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 - 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 +! +! 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/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf index fde1d6c7714d..6eeba48fe9af 100644 --- a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf +++ b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf @@ -3,27 +3,39 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python -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 dhcp_relay events=PROCESS_STATE_EXITED 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 [group:isc-dhcp-relay] programs=isc-dhcp-relay-Vlan1000 @@ -35,6 +47,8 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited [group:dhcpmon] @@ -47,6 +61,8 @@ 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/frr.conf b/src/sonic-config-engine/tests/sample_output/frr.conf index 47855ce7c841..07354c6cf656 100644 --- a/src/sonic-config-engine/tests/sample_output/frr.conf +++ b/src/sonic-config-engine/tests/sample_output/frr.conf @@ -1,9 +1,10 @@ ! ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/frr/frr.conf.j2 with config DB data +! generated by templates/frr.conf.j2 with config DB data ! file: frr.conf ! ! +! template: common/daemons.common.conf.j2 ! hostname switch-t0 password zebra @@ -11,7 +12,8 @@ enable password zebra ! log syslog informational log facility local4 -!! +! +! end of template: common/daemons.common.conf.j2! agentx ! ! @@ -29,93 +31,55 @@ 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 !! ! +! template: bgpd/bgpd.main.conf.j2 ! ! bgp multiple-instance ! -route-map FROM_BGP_SPEAKER_V4 permit 10 +! BGP configuration ! -route-map TO_BGP_SPEAKER_V4 deny 10 +! TSA configuration ! 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 ! +ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 ! -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 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 - 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 +! +! end of template: bgpd/bgpd.main.conf.j2 !! diff --git a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces index 633d8aa4498d..085f5111c3f5 100644 --- a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces +++ b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces @@ -29,13 +29,10 @@ iface eth0 inet static 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 @@ -47,13 +44,10 @@ iface eth0 inet6 static 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/qos-arista7050.json b/src/sonic-config-engine/tests/sample_output/qos-arista7050.json new file mode 100644 index 000000000000..aa05ef4ec36c --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/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/qos-dell6100.json b/src/sonic-config-engine/tests/sample_output/qos-dell6100.json index 680ca6232e11..75d9b3a87eee 100644 --- a/src/sonic-config-engine/tests/sample_output/qos-dell6100.json +++ b/src/sonic-config-engine/tests/sample_output/qos-dell6100.json @@ -430,7 +430,7 @@ "wred_red_enable" : "true", "ecn" : "ecn_all", "green_max_threshold" : "2097152", - "green_min_threshold" : "1048576", + "green_min_threshold" : "250000", "yellow_max_threshold" : "2097152", "yellow_min_threshold" : "1048576", "red_max_threshold" : "2097152", diff --git a/src/sonic-config-engine/tests/sample_output/staticd_frr.conf b/src/sonic-config-engine/tests/sample_output/staticd_frr.conf index 12a81de82125..31a11d8578aa 100644 --- a/src/sonic-config-engine/tests/sample_output/staticd_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/staticd_frr.conf @@ -4,6 +4,7 @@ ! file: staticd.conf ! ! +! template: common/daemons.common.conf.j2 ! hostname switch-t0 password zebra @@ -11,7 +12,8 @@ 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 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 index b0b5e2cb1192..dd79ae3950bb 100644 --- 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 @@ -1,9 +1,13 @@ ! +! 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 @@ -11,7 +15,8 @@ enable password zebra ! log syslog informational log facility local4 -!! +! +! end of template: common/daemons.common.conf.j2! agentx ! ! @@ -37,49 +42,46 @@ router bgp 4000 vrf VnetFE exit-address-family !! ! +! template: bgpd/bgpd.main.conf.j2 ! ! bgp multiple-instance ! -route-map FROM_BGP_SPEAKER_V4 permit 10 +! BGP configuration ! -route-map TO_BGP_SPEAKER_V4 deny 10 +! TSA configuration ! 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 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 - 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 +! +! 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/t2-chassis-fe-vni-zebra.conf b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-vni-zebra.conf index bd2b5c84f471..180a0e9fab89 100644 --- 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 @@ -1,9 +1,10 @@ ! ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/quagga/zebra.conf.j2 using config DB data +! generated by templates/zebra/zebra.conf.j2 using config DB data ! file: zebra.conf ! ! +! template: common/daemons.common.conf.j2 ! hostname SpineFront01 password zebra @@ -11,7 +12,8 @@ enable password zebra ! log syslog informational log facility local4 -!! +! +! end of template: common/daemons.common.conf.j2! ! vrf VnetFE vni 9000 @@ -27,11 +29,4 @@ 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 index e047fcd64f29..661b27268255 100644 --- 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 @@ -1,9 +1,10 @@ ! ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/quagga/zebra.conf.j2 using config DB data +! generated by templates/zebra/zebra.conf.j2 using config DB data ! file: zebra.conf ! ! +! template: common/daemons.common.conf.j2 ! hostname SpineFront01 password zebra @@ -11,7 +12,8 @@ enable password zebra ! log syslog informational log facility local4 -!! +! +! end of template: common/daemons.common.conf.j2! ! vrf VnetFE vni 8000 @@ -27,11 +29,4 @@ 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 index 690f609dafcf..e3d0c2d55bc3 100644 --- a/src/sonic-config-engine/tests/sample_output/zebra_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/zebra_frr.conf @@ -1,9 +1,10 @@ ! ! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== -! generated by templates/quagga/zebra.conf.j2 using config DB data +! 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 @@ -11,7 +12,8 @@ enable password zebra ! log syslog informational log facility local4 -!! +! +! end of template: common/daemons.common.conf.j2! ! ! ! Enable link-detect (default disabled) @@ -27,17 +29,4 @@ 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/simple-sample-graph-metadata.xml b/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml index 1b1da1ff1787..4bde42cdda3a 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 diff --git a/src/sonic-config-engine/tests/t0-sample-graph.xml b/src/sonic-config-engine/tests/t0-sample-graph.xml index 47985f870e50..5e4a68db0e87 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph.xml @@ -303,6 +303,11 @@ everflowV6 Everflow + + EGRESS_ERSPAN + everflow_egress + Everflow + PortChannel01;PortChannel02;PortChannel03;PortChannel04 DataAclIngress @@ -376,13 +381,14 @@ Ethernet1/1 switch-t0 fortyGigE0/124 + 100000 DeviceInterfaceLink true - 10000 + 100000 switch-t0 - fortyGigE0/2 + fortyGigE0/4 true ARISTA05T1 Ethernet1/33 @@ -434,6 +440,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/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 7f5eb155092f..66ca26f3250e 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -53,6 +53,16 @@ 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_print_data(self): argument = '-m "' + self.sample_graph + '" --print-data' output = self.run_script(argument) @@ -102,10 +112,9 @@ 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" "{'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL', 'stage': 'ingress'}, " "'EVERFLOW': {'stage': 'ingress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4'], 'policy_desc': 'EVERFLOW'}, " + "'EVERFLOW_EGRESS': {'stage': 'egress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4'], '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'}, " @@ -185,7 +194,18 @@ def test_minigraph_extra_neighbors(self): 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(output.strip(), "{'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(output.strip(), "{'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(output.strip(), "{'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\']"' diff --git a/src/sonic-config-engine/tests/test_frr.py b/src/sonic-config-engine/tests/test_frr.py index fcbff063b13b..dd41e1711760 100644 --- a/src/sonic-config-engine/tests/test_frr.py +++ b/src/sonic-config-engine/tests/test_frr.py @@ -37,8 +37,11 @@ def run_diff(self, file1, file2): return subprocess.check_output('diff -u {} {} || true'.format(file1, file2), shell=True) 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) @@ -52,11 +55,11 @@ 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..1cdfcc91fccb 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -18,6 +18,7 @@ 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.output_file = os.path.join(self.test_dir, 'output') def run_script(self, argument): @@ -57,7 +58,7 @@ def test_dhcp_relay(self): self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', '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') + lldpd_conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-lldp', 'lldpd.conf.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + 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)) @@ -93,6 +94,25 @@ def test_l2switch_template(self): self.assertTrue(filecmp.cmp(sample_output_file, self.output_file)) + 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) + + # cleanup + qos_config_file_new = os.path.join(arista_dir_path, 'qos_config.j2') + os.remove(qos_config_file_new) + + sample_output_file = os.path.join(self.test_dir, 'sample_output', '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') qos_file = os.path.join(dell_dir_path, 'qos.json.j2') 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..a3c50b8a263d 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 @@ -30,8 +30,11 @@ 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) @@ -42,13 +45,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_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py new file mode 100644 index 000000000000..c3307b482b79 --- /dev/null +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -0,0 +1,247 @@ +import unittest +from unittest import TestCase +import subprocess +import os +import json +import yaml + +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 = 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) + + 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 --var-json \"PORTCHANNEL_MEMBER\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertListEqual(output.keys(), \ + ['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 --var-json \"PORTCHANNEL_MEMBER\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertListEqual(output.keys(), \ + ['PortChannel4013|Ethernet-BP384', 'PortChannel4014|Ethernet-BP392', 'PortChannel4014|Ethernet-BP396', 'PortChannel4013|Ethernet-BP388']) + + def test_frontend_asic_portchannel_intf(self): + argument = "-m {} -p {} -n asic0 --var-json \"PORTCHANNEL_INTERFACE\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertListEqual(output.keys(), \ + ['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 --var-json \"PORTCHANNEL_INTERFACE\"".format(self.sample_graph, self.port_config[3]) + output = json.loads(self.run_script(argument)) + self.assertListEqual(output.keys(), \ + ['PortChannel4013', 'PortChannel4013|10.1.0.2/31', 'PortChannel4014', 'PortChannel4014|10.1.0.6/31']) + + 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', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}, + 'ASIC2': {'lo_addr': '0.0.0.0/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', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}, + 'ASIC0': {'lo_addr': '0.0.0.0/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'}, + '10.1.0.0': {'rrclient': 0, 'name': 'ASIC2', 'local_addr': '10.1.0.1', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0', 'admin_status': 'up'}, + 'fc00::2': {'rrclient': 0, 'name': '01T2', 'local_addr': 'fc00::1', 'nhopself': 0, 'holdtime': '10', 'asn': '65200', 'keepalive': '3'}, + '10.1.0.2': {'rrclient': 0, 'name': 'ASIC3', 'local_addr': '10.1.0.3', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0', 'admin_status': 'up'}}) + + def test_backend_asic_bgp_neighbor(self): + argument = "-m {} -p {} -n asic3 --var-json \"BGP_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, 'holdtime': '0', 'asn': '65100', 'keepalive': '0', 'admin_status': 'up'}, + '10.1.0.3': {'rrclient': 0, 'name': 'ASIC0', 'local_addr': '10.1.0.2', 'nhopself': 0, 'holdtime': '0', 'asn': '65100', 'keepalive': '0', 'admin_status': 'up'}}) + + 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, {}) diff --git a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py index d3807bf91524..c74f9bed15e7 100644 --- a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py +++ b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py @@ -13,10 +13,6 @@ # # Constants ==================================================================== # - -# Redis DB information -REDIS_HOSTNAME = 'localhost' -REDIS_PORT = 6379 REDIS_TIMEOUT_MSECS = 0 # Platform root directory inside docker @@ -36,12 +32,11 @@ # Helper functions ============================================================= # -def db_connect(db): +def db_connect(db_name): from swsscommon import swsscommon - return swsscommon.DBConnector(db, - REDIS_HOSTNAME, - REDIS_PORT, - REDIS_TIMEOUT_MSECS) + return swsscommon.DBConnector(db_name, + REDIS_TIMEOUT_MSECS, + True) # # Helper classes =============================================================== diff --git a/src/sonic-device-data/.gitignore b/src/sonic-device-data/.gitignore new file mode 100644 index 000000000000..963a3ac55363 --- /dev/null +++ b/src/sonic-device-data/.gitignore @@ -0,0 +1,2 @@ +src/debian +src/device diff --git a/src/sonic-device-data/src/Makefile b/src/sonic-device-data/src/Makefile index aca0cbea2a4d..10525fdeb27e 100644 --- a/src/sonic-device-data/src/Makefile +++ b/src/sonic-device-data/src/Makefile @@ -11,4 +11,7 @@ test: for f in $$(find ../../../device -name media_settings.json); do ./media_checker $$f done + for f in $$(find ../../../device -name platform.json); do + ./platform_json_checker $$f + done popd diff --git a/src/sonic-device-data/tests/media_checker b/src/sonic-device-data/tests/media_checker index 6b4139585a24..132756cb4b77 100755 --- a/src/sonic-device-data/tests/media_checker +++ b/src/sonic-device-data/tests/media_checker @@ -138,7 +138,7 @@ def main(argv): # Load target file if len(argv) == 0: - files = glob.glob('*.json') + files = glob.glob('*media_settings.json') else: files = argv diff --git a/src/sonic-device-data/tests/permitted_list b/src/sonic-device-data/tests/permitted_list index 7740da96aa2d..9585c19301d4 100644 --- a/src/sonic-device-data/tests/permitted_list +++ b/src/sonic-device-data/tests/permitted_list @@ -133,6 +133,7 @@ serdes_pre_driver_current serdes_preemphasis serdes_rx_los serdes_sgmii_m +serdes_tx_taps_cd serdes_tx_taps skip_L2_USER_ENTRY sram_scan_enable diff --git a/src/sonic-device-data/tests/platform_json_checker b/src/sonic-device-data/tests/platform_json_checker new file mode 100755 index 000000000000..c0257a27e80c --- /dev/null +++ b/src/sonic-device-data/tests/platform_json_checker @@ -0,0 +1,99 @@ +#!/usr/bin/env python +try: + import re + import sys + import glob + import json +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +# TODO: need to remove basestring once migrate to Python 3 and just change to str +try: + basestring +except NameError: + basestring = str + +# Global variable +PORT_ATTRIBUTES = ["index", "lanes", "alias_at_lanes", "breakout_modes"] +ATTR_LEN = len(PORT_ATTRIBUTES) +PORT_REG = "Ethernet(\d+)" +PLATFORM_JSON = '*platform.json' +INTF_KEY = "interfaces" + +def usage(): + print "Usage: " + sys.argv[0] + " " + sys.exit(1) + +def check_port_attr(port_attr): + for each_key in port_attr: + if each_key not in PORT_ATTRIBUTES: + print "Error: "+ each_key + " is not the correct Port attribute." + return False + if not port_attr[each_key]: + print "Error: "+ each_key + " has no value." + return False + # TODO: need to remove basestring once migrate to Python 3 and just change to str + if not isinstance(port_attr[each_key], basestring): + print "Error:value type of "+ each_key + " must be string." + return False + return True + +def check_file(platform_json_file): + try: + platform_cap_file = open(platform_json_file,"r") + platform_file_data = platform_cap_file.read() + port_dict = json.loads(platform_file_data) + + for each_port in port_dict[INTF_KEY]: + # Validate port at top level + port_id = re.search(PORT_REG, each_port) + if port_id is None: + print "Error: Unknown Interface " + str(each_port) + " at top level" + return False + + total_attr = len(port_dict[INTF_KEY][each_port].keys()) + port_attr = port_dict[INTF_KEY][each_port] + + if total_attr != ATTR_LEN: + missing_attr = ', '.join(set(PORT_ATTRIBUTES).difference(list(port_attr))) + print "Error: " + missing_attr + " of " + each_port + " is/are missing" + return False + + #Validate port attributes for each port + if not check_port_attr(port_attr): + return False + except IOError: + print "Error: Cannot open file " + platform_json_file + return False + except ValueError,e: + print "Error in parsing json file " + platform_json_file + " " + print str(e) + return False + return True + +def main(argv): + if len(argv) > 0 and argv[0] == "-h": + usage() + + # Load target file + if len(argv) == 0: + files = glob.glob(PLATFORM_JSON) + else: + files = argv + + all_good = True + + for f in files: + good = check_file(f) + if good: + print "File " + f + " passed validity check" + else: + print "File " + f + " failed validity check" + + all_good = all_good and good + + if not all_good: + sys.exit(-1) + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index 231bebb41b86..1573762bfa36 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit 231bebb41b86c9f744adc86972773d75fd4a2a2a +Subproject commit 1573762bfa36e32867e911a730aa7ce18b762eb0 diff --git a/src/sonic-platform-common b/src/sonic-platform-common index dc59b105ff23..75698a8dd8f5 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit dc59b105ff234bd89b9042c934b17c10b9b261f7 +Subproject commit 75698a8dd8f5a9ea2a0e72c5f7e2b3196d22571a diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index 97e40cefae31..0f4fd835f324 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit 97e40cefae31928fe8faf0a0995c8263e7f62465 +Subproject commit 0f4fd835f324cb754a8b955f9a5fad6b54d7d6dc diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index df617345d807..132f8d5f1b00 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit df617345d807bc01e3f5740fdfdc4b9799f1cf63 +Subproject commit 132f8d5f1b00fb8a1b3cdbd7a5c69bb89cfff0e3 diff --git a/src/sonic-quagga b/src/sonic-quagga index 7101eeda1a1c..e3b3b634e76b 160000 --- a/src/sonic-quagga +++ b/src/sonic-quagga @@ -1 +1 @@ -Subproject commit 7101eeda1a1ccef2e951e4bea5a2f15d9a43e3b5 +Subproject commit e3b3b634e76b53cc4dce9301839451846eea7415 diff --git a/src/sonic-restapi b/src/sonic-restapi index 163ee272ae99..ed640ac1f917 160000 --- a/src/sonic-restapi +++ b/src/sonic-restapi @@ -1 +1 @@ -Subproject commit 163ee272ae992f5885990dcca6552cd86b74391a +Subproject commit ed640ac1f917f52c2298c0b799fb6a6cfbecccb4 diff --git a/src/sonic-sairedis b/src/sonic-sairedis index f4d9398c87ae..322dd01db434 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit f4d9398c87aee4fa66a0391b0d83f91595bc4480 +Subproject commit 322dd01db434d00394898d4d1ac34433e95447cd diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent index 862e51ab85d4..89b7b2c90099 160000 --- a/src/sonic-snmpagent +++ b/src/sonic-snmpagent @@ -1 +1 @@ -Subproject commit 862e51ab85d48290082adfcbb801bfbbe3a95bf3 +Subproject commit 89b7b2c90099bc3404edeb1210b0aa90070a6a80 diff --git a/src/sonic-swss b/src/sonic-swss index 412c5ebd1762..a3a010af7283 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 412c5ebd1762f94afc51b1129f54a27a53f132bb +Subproject commit a3a010af728345b085d8a6e344b60b16c32815fd diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 7ee11792342f..35bc01a70946 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 7ee11792342f2673ea6905952d556e3f9a27234d +Subproject commit 35bc01a709464ad19eda2ae35a605987fe689fa1 diff --git a/src/sonic-utilities b/src/sonic-utilities index 798ce2fa0b1b..a21e01a2f07c 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 798ce2fa0b1b9a6e12deaa141c39a92c17b809e8 +Subproject commit a21e01a2f07c1567c3b8ada7b00f00a2dc7bf428 diff --git a/src/sonic-yang-mgmt/.gitignore b/src/sonic-yang-mgmt/.gitignore new file mode 100644 index 000000000000..ba74660506d9 --- /dev/null +++ b/src/sonic-yang-mgmt/.gitignore @@ -0,0 +1,57 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ diff --git a/src/sonic-yang-mgmt/AUTHORS.rst b/src/sonic-yang-mgmt/AUTHORS.rst new file mode 100644 index 000000000000..b5530bc13df3 --- /dev/null +++ b/src/sonic-yang-mgmt/AUTHORS.rst @@ -0,0 +1,15 @@ +======= +Credits +======= + +Development Lead +---------------- + +LNOS-CODERS +MSFT-LINUX-DEV + +Contributors +------------ + +Praveen Chaudhary +Ping Mao diff --git a/src/sonic-yang-mgmt/LICENSE b/src/sonic-yang-mgmt/LICENSE new file mode 100644 index 000000000000..cf593b111eab --- /dev/null +++ b/src/sonic-yang-mgmt/LICENSE @@ -0,0 +1,13 @@ +Copyright 2019 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/src/sonic-yang-mgmt/README.rst b/src/sonic-yang-mgmt/README.rst new file mode 100644 index 000000000000..4d6c90640de8 --- /dev/null +++ b/src/sonic-yang-mgmt/README.rst @@ -0,0 +1,6 @@ +" +This package includes python yang libraries which will be used with sonic utilities +pacakge to validate the config. This python libraries are written on top of libyang +and also provides functionality to translate the config from SONiC ConfigDB to SONiC +YANG and vice-versa. +" diff --git a/src/sonic-yang-mgmt/setup.py b/src/sonic-yang-mgmt/setup.py new file mode 100644 index 000000000000..63ea0640f899 --- /dev/null +++ b/src/sonic-yang-mgmt/setup.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""The setup script.""" + +from setuptools import setup, find_packages +from setuptools.command.build_py import build_py +from os import system +from sys import exit +import pytest + +setup_requirements = ['pytest-runner'] + +test_requirements = ['pytest>=3'] + +# read me +with open('README.rst') as readme_file: + readme = readme_file.read() + +# class for prerequisites to build this package +class pkgBuild(build_py): + """Custom Build PLY""" + + def run (self): + # run pytest for libyang python APIs + self.pytest_args = [] + errno = pytest.main(self.pytest_args) + if (errno): + exit(errno) + + # Continue usual build steps + build_py.run(self) + +setup( + cmdclass={ + 'build_py': pkgBuild, + }, + author="lnos-coders", + author_email='lnos-coders@linkedin.com', + python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*', + classifiers=[ + 'Development Status :: 2 - Pre-Alpha', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)', + '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', + ], + description="Package contains Python Library for YANG for sonic.", + tests_require = test_requirements, + license="GNU General Public License v3", + long_description=readme + '\n\n', + include_package_data=True, + keywords='sonic_yang_mgmt', + name='sonic_yang_mgmt', + py_modules=['sonic_yang', 'sonic_yang_ext'], + packages=find_packages(), + setup_requires=setup_requirements, + version='1.0', + zip_safe=False, +) diff --git a/src/sonic-yang-mgmt/sonic_yang.py b/src/sonic-yang-mgmt/sonic_yang.py new file mode 100644 index 000000000000..a9ec2f0ad63e --- /dev/null +++ b/src/sonic-yang-mgmt/sonic_yang.py @@ -0,0 +1,659 @@ +import yang as ly +import syslog + +from json import dump +from glob import glob +from sonic_yang_ext import SonicYangExtMixin, SonicYangException + +""" +Yang schema and data tree python APIs based on libyang python +Here, sonic_yang_ext_mixin extends funtionality of sonic_yang, +i.e. it is mixin not parent class. +""" +class SonicYang(SonicYangExtMixin): + + def __init__(self, yang_dir, debug=False): + self.yang_dir = yang_dir + self.ctx = None + self.module = None + self.root = None + + # logging vars + self.SYSLOG_IDENTIFIER = "sonic_yang" + self.DEBUG = debug + + # yang model files, need this map it to module + self.yangFiles = list() + # map from TABLE in config DB to container and module + self.confDbYangMap = dict() + # JSON format of yang model [similar to pyang conversion] + self.yJson = list() + # config DB json input, will be cropped as yang models + self.jIn = dict() + # YANG JSON, this is traslated from config DB json + self.xlateJson = dict() + # reverse translation from yang JSON, == config db json + self.revXlateJson = dict() + # below dict store the input config tables which have no YANG models + self.tablesWithOutYang = dict() + + try: + self.ctx = ly.Context(yang_dir) + except Exception as e: + self.fail(e) + + return + + def __del__(self): + pass + + def sysLog(self, debug=syslog.LOG_INFO, msg=None): + + # log debug only if enabled + if self.DEBUG == False and debug == syslog.LOG_DEBUG: + return + syslog.openlog(self.SYSLOG_IDENTIFIER) + syslog.syslog(debug, msg) + syslog.closelog() + + return + + def fail(self, e): + print(e) + raise e + + """ + load_schema_module(): load a Yang model file + input: yang_file - full path of a Yang model file + returns: Exception if error + """ + def _load_schema_module(self, yang_file): + try: + return self.ctx.parse_module_path(yang_file, ly.LYS_IN_YANG) + except Exception as e: + print("Failed to load yang module file: " + yang_file) + self.fail(e) + + """ + load_schema_module_list(): load all Yang model files in the list + input: yang_files - a list of Yang model file full path + returns: Exception if error + """ + def _load_schema_module_list(self, yang_files): + for file in yang_files: + try: + self._load_schema_module(file) + except Exception as e: + self.fail(e) + + """ + load_schema_modules(): load all Yang model files in the directory + input: yang_dir - the directory of the yang model files to be loaded + returns: Exception if error + """ + def _load_schema_modules(self, yang_dir): + py = glob(yang_dir+"/*.yang") + for file in py: + try: + self._load_schema_module(file) + except Exception as e: + self.fail(e) + + """ + load_schema_modules_ctx(): load all Yang model files in the directory to context: ctx + input: yang_dir, context + returns: Exception if error, returrns context object if no error + """ + def _load_schema_modules_ctx(self, yang_dir=None): + if not yang_dir: + yang_dir = self.yang_dir + + ctx = ly.Context(yang_dir) + + py = glob(yang_dir+"/*.yang") + for file in py: + try: + ctx.parse_module_path(str(file), ly.LYS_IN_YANG) + except Exception as e: + print("Failed to parse yang module file: " + file) + self.fail(e) + + return ctx + + """ + load_data_file(): load a Yang data json file + input: data_file - the full path of the yang json data file to be loaded + returns: Exception if error + """ + def _load_data_file(self, data_file): + try: + data_node = self.ctx.parse_data_path(data_file, ly.LYD_JSON, ly.LYD_OPT_CONFIG | ly.LYD_OPT_STRICT) + except Exception as e: + print("Failed to load data file: " + str(data_file)) + self.fail(e) + else: + self.root = data_node + + """ + get module name from xpath + input: path + returns: module name + """ + def _get_module_name(self, schema_xpath): + module_name = schema_xpath.split(':')[0].strip('/') + return module_name + + """ + get_module(): get module object from Yang module name + input: yang module name + returns: Schema_Node object + """ + def _get_module(self, module_name): + mod = self.ctx.get_module(module_name) + return mod + + """ + load_data_model(): load both Yang module fileis and data json files + input: yang directory, list of yang files and list of data files (full path) + returns: returns (context, root) if no error, or Exception if failed + """ + def _load_data_model(self, yang_dir, yang_files, data_files, output=None): + if (self.ctx is None): + self.ctx = ly.Context(yang_dir) + + try: + self._load_schema_module_list(yang_files) + if len(data_files) == 0: + return (self.ctx, self.root) + + self._load_data_file(data_files[0]) + + for i in range(1, len(data_files)): + self._merge_data(data_files[i]) + except Exception as e: + print("Failed to load data files") + self.fail(e) + return + + if output is not None: + self._print_data_mem(output) + + return (self.ctx, self.root) + + """ + print_data_mem(): print the data tree + input: option: "JSON" or "XML" + """ + def _print_data_mem(self, option): + if (option == "JSON"): + mem = self.root.print_mem(ly.LYD_JSON, ly.LYP_WITHSIBLINGS | ly.LYP_FORMAT) + else: + mem = self.root.print_mem(ly.LYD_XML, ly.LYP_WITHSIBLINGS | ly.LYP_FORMAT) + + return mem + + """ + save_data_file_json(): save the data tree in memory into json file + input: outfile - full path of the file to save the data tree to + """ + def _save_data_file_json(self, outfile): + mem = self.root.print_mem(ly.LYD_JSON, ly.LYP_FORMAT) + with open(outfile, 'w') as out: + dump(mem, out, indent=4) + + """ + get_module_tree(): get yang module tree in JSON or XMAL format + input: module name + returns: JSON or XML format of the input yang module schema tree + """ + def _get_module_tree(self, module_name, format): + result = None + + try: + module = self.ctx.get_module(str(module_name)) + except Exception as e: + print("Cound not get module: " + str(module_name)) + self.fail(e) + else: + if (module is not None): + if (format == "XML"): + #libyang bug with format + result = module.print_mem(ly.LYD_JSON, ly.LYP_FORMAT) + else: + result = module.print_mem(ly.LYD_XML, ly.LYP_FORMAT) + + return result + + """ + validate_data(): validate data tree + input: + node: root of the data tree + ctx: context + returns: Exception if failed + """ + def _validate_data(self, node=None, ctx=None): + if not node: + node = self.root + + if not ctx: + ctx = self.ctx + + try: + node.validate(ly.LYD_OPT_CONFIG, ctx) + except Exception as e: + self.fail(e) + + """ + validate_data_tree(): validate the data tree. (Public) + returns: Exception if failed + """ + def validate_data_tree(self): + try: + self._validate_data(self.root, self.ctx) + except Exception as e: + print("Failed to validate data tree") + raise SonicYangException("Failed to validate data tree\n{}".\ + format(str(e))) + + """ + find_parent_data_node(): find the parent node object + input: data_xpath - xpath of the data node + returns: parent node + """ + def _find_parent_data_node(self, data_xpath): + if (self.root is None): + print("data not loaded") + return None + try: + data_node = self._find_data_node(data_xpath) + except Exception as e: + print("Failed to find data node from xpath: " + str(data_xpath)) + self.fail(e) + else: + if data_node is not None: + return data_node.parent() + + return None + + """ + get_parent_data_xpath(): find the parent data node's xpath + input: data_xpath - xpathof the data node + returns: - xpath of parent data node + - Exception if error + """ + def _get_parent_data_xpath(self, data_xpath): + path="" + try: + data_node = self._find_parent_data_node(data_xpath) + except Exception as e: + print("Failed to find parent node from xpath: " + str(data_xpath)) + self.fail(e) + else: + if data_node is not None: + path = data_node.path() + return path + + """ + new_data_node(): create a new data node in the data tree + input: + xpath: xpath of the new node + value: value of the new node + returns: new Data_Node object if success, Exception if falied + """ + def _new_data_node(self, xpath, value): + val = str(value) + try: + data_node = self.root.new_path(self.ctx, xpath, val, 0, 0) + except Exception as e: + print("Failed to add data node for path: " + str(xpath)) + self.fail(e) + else: + return data_node + + """ + find_data_node(): find the data node from xpath + input: data_xpath: xpath of the data node + returns - Data_Node object if found + - None if not exist + - Exception if there is error + """ + def _find_data_node(self, data_xpath): + try: + set = self.root.find_path(data_xpath) + except Exception as e: + print("Failed to find data node from xpath: " + str(data_xpath)) + self.fail(e) + else: + if set is not None: + for data_node in set.data(): + if (data_xpath == data_node.path()): + return data_node + return None + """ + find_schema_node(): find the schema node from schema xpath + example schema xpath: + "/sonic-port:sonic-port/sonic-port:PORT/sonic-port:PORT_LIST/sonic-port:port_name" + input: xpath of the node + returns: Schema_Node oject or None if not found + """ + def _find_schema_node(self, schema_xpath): + try: + schema_set = self.ctx.find_path(schema_xpath) + for schema_node in schema_set.schema(): + if (schema_xpath == schema_node.path()): + return schema_node + except Exception as e: + self.fail(e) + return None + else: + for schema_node in schema_set.schema(): + if schema_xapth == schema_node.path(): + return schema_node + return None + """ + find_data_node_schema_xpath(): find the xpath of the schema node from data xpath + data xpath example: + "/sonic-port:sonic-port/PORT/PORT_LIST[port_name='Ethernet0']/port_name" + input: data_xpath - xpath of the data node + returns: - xpath of the schema node if success + - Exception if error + """ + def _find_data_node_schema_xpath(self, data_xpath): + path = "" + try: + set = self.root.find_path(data_xpath) + except Exception as e: + self.fail(e) + else: + for data_node in set.data(): + if data_xpath == data_node.path(): + return data_node.schema().path() + return path + + """ + add_node(): add a node to Yang schema or data tree + input: xpath and value of the node to be added + returns: Exception if failed + """ + def _add_data_node(self, data_xpath, value): + try: + self._new_data_node(data_xpath, value) + #check if the node added to the data tree + self._find_data_node(data_xpath) + except Exception as e: + print("add_node(): Failed to add data node for xpath: " + str(data_xpath)) + self.fail(e) + + """ + merge_data(): merge a data file to the existing data tree + input: yang model directory and full path of the data json file to be merged + returns: Exception if failed + """ + def _merge_data(self, data_file, yang_dir=None): + #load all yang models to ctx + if not yang_dir: + yang_dir = self.yang_dir + + try: + ctx = self._load_schema_modules_ctx(yang_dir) + + #source data node + source_node = ctx.parse_data_path(str(data_file), ly.LYD_JSON, ly.LYD_OPT_CONFIG | ly.LYD_OPT_STRICT) + + #merge + self.root.merge(source_node, 0) + except Exception as e: + self.fail(e) + + """ + _deleteNode(): delete a node from the schema/data tree, internal function + input: xpath of the schema/data node + returns: True - success False - failed + """ + def _deleteNode(self, xpath=None, node=None): + if node is None: + node = self._find_data_node(xpath) + + if (node): + node.unlink() + dnode = self._find_data_node(xpath) + if (dnode is None): + #deleted node not found + return True + else: + print('Could not delete Node') + return False + else: + print("failed to find node, xpath: " + xpath) + + return False + + """ + find_data_node_value(): find the value of a node from the data tree + input: data_xpath of the data node + returns: value string of the node + """ + def _find_data_node_value(self, data_xpath): + output = "" + try: + data_node = self._find_data_node(data_xpath) + except Exception as e: + print("find_data_node_value(): Failed to find data node from xpath: {}".format(data_xpath)) + self.fail(e) + else: + if (data_node is not None): + subtype = data_node.subtype() + if (subtype is not None): + value = subtype.value_str() + return value + return output + + """ + set the value of a node in the data tree + input: xpath of the data node + returns: Exception if failed + """ + def _set_data_node_value(self, data_xpath, value): + try: + self.root.new_path(self.ctx, data_xpath, str(value), ly.LYD_ANYDATA_STRING, ly.LYD_PATH_OPT_UPDATE) + except Exception as e: + print("set data node value failed for xpath: " + str(data_xpath)) + self.fail(e) + + """ + find_data_nodes(): find the set of nodes for the xpath + input: xpath of the data node + returns: list of xpath of the dataset + """ + def _find_data_nodes(self, data_xpath): + list = [] + node = self.root.child() + try: + node_set = node.find_path(data_xpath); + except Exception as e: + self.fail(e) + else: + if node_set is None: + raise Exception('data node not found') + + for data_set in node_set.data(): + data_set.schema() + list.append(data_set.path()) + return list + + """ + find_schema_dependencies(): find the schema dependencies from schema xpath + input: schema_xpath of the schema node + returns: - list of xpath of the dependencies + - Exception if schema node not found + """ + def _find_schema_dependencies(self, schema_xpath): + ref_list = [] + try: + schema_node = self._find_schema_node(schema_xpath) + except Exception as e: + print("Cound not find the schema node from xpath: " + str(schema_xpath)) + self.fail(e) + return ref_list + + schema_node = ly.Schema_Node_Leaf(schema_node) + backlinks = schema_node.backlinks() + if backlinks.number() > 0: + for link in backlinks.schema(): + print("backlink schema: {}".format(link.path())) + ref_list.append(link.path()) + return ref_list + + """ + find_data_dependencies(): find the data dependencies from data xpath + input: data_xpath - xpath of data node. (Public) + returns: - list of xpath + - Exception if error + """ + def find_data_dependencies(self, data_xpath): + ref_list = [] + node = self.root + try: + data_node = self._find_data_node(data_xpath) + except Exception as e: + print("find_data_dependencies(): Failed to find data node from xpath: {}".format(data_xapth)) + return ref_list + + try: + value = str(self._find_data_node_value(data_xpath)) + + schema_node = ly.Schema_Node_Leaf(data_node.schema()) + backlinks = schema_node.backlinks() + if backlinks.number() > 0: + for link in backlinks.schema(): + node_set = node.find_path(link.path()) + for data_set in node_set.data(): + data_set.schema() + casted = data_set.subtype() + if value == casted.value_str(): + ref_list.append(data_set.path()) + except Exception as e: + print('Failed to find node or dependencies for {}'.format(data_xpath)) + raise SonicYangException("Failed to find node or dependencies for \ + {}\n{}".format(data_xpath, str(e))) + + return ref_list + + """ + get_module_prefix: get the prefix of a Yang module + input: name of the Yang module + output: prefix of the Yang module + """ + def _get_module_prefix(self, module_name): + prefix = "" + try: + module = self._get_module(module_name) + except Exception as e: + self.fail(e) + return prefix + else: + return module.prefix() + + """ + str_to_type: map string to type of node + input: string + output: type + """ + def _str_to_type(self, type_str): + mapped_type = { + "LY_TYPE_DER":ly.LY_TYPE_DER, + "LY_TYPE_BINARY":ly.LY_TYPE_BINARY, + "LY_TYPE_BITS":ly.LY_TYPE_BITS, + "LY_TYPE_BOOL":ly.LY_TYPE_BOOL, + "LY_TYPE_DEC64":ly.LY_TYPE_DEC64, + "LY_TYPE_EMPTY":ly.LY_TYPE_EMPTY, + "LY_TYPE_ENUM":ly.LY_TYPE_ENUM, + "LY_TYPE_IDENT":ly.LY_TYPE_IDENT, + "LY_TYPE_INST":ly.LY_TYPE_INST, + "LY_TYPE_LEAFREF":ly.LY_TYPE_LEAFREF, + "LY_TYPE_STRING":ly.LY_TYPE_STRING, + "LY_TYPE_UNION":ly.LY_TYPE_UNION, + "LY_TYPE_INT8":ly.LY_TYPE_INT8, + "LY_TYPE_UINT8":ly.LY_TYPE_UINT8, + "LY_TYPE_INT16":ly.LY_TYPE_INT16, + "LY_TYPE_UINT16":ly.LY_TYPE_UINT16, + "LY_TYPE_INT32":ly.LY_TYPE_INT32, + "LY_TYPE_UINT32":ly.LY_TYPE_UINT32, + "LY_TYPE_INT64":ly.LY_TYPE_INT64, + "LY_TYPE_UINT64":ly.LY_TYPE_UINT64, + "LY_TYPE_UNKNOWN":ly.LY_TYPE_UNKNOWN + } + + if type_str not in mapped_type: + return ly.LY_TYPE_UNKNOWN + + return mapped_type[type_str] + + def _get_data_type(self, schema_xpath): + try: + schema_node = self._find_schema_node(schema_xpath) + except Exception as e: + print("get_data_type(): Failed to find schema node from xpath: {}".format(schema_xpath)) + self.fail(e) + return None + + if (schema_node is not None): + return schema_node.subtype().type().base() + + return ly.LY_TYPE_UNKNOWN + + """ + get_leafref_type: find the type of node that leafref references to + input: data_xpath - xpath of a data node + output: type of the node this leafref references to + """ + def _get_leafref_type(self, data_xpath): + data_node = self._find_data_node(data_xpath) + if (data_node is not None): + subtype = data_node.subtype() + if (subtype is not None): + if data_node.schema().subtype().type().base() != ly.LY_TYPE_LEAFREF: + print("get_leafref_type() node type for data xpath: {} is not LEAFREF".format(data_xpath)) + return ly.LY_TYPE_UNKNOWN + else: + return subtype.value_type() + + return ly.LY_TYPE_UNKNOWN + + """ + get_leafref_path(): find the leafref path + input: schema_xpath - xpath of a schema node + output: path value of the leafref node + """ + def _get_leafref_path(self, schema_xpath): + schema_node = self._find_schema_node(schema_xpath) + if (schema_node is not None): + subtype = schema_node.subtype() + if (subtype is not None): + if subtype.type().base() != ly.LY_TYPE_LEAFREF: + return None + else: + return subtype.type().info().lref().path() + + return None + + """ + get_leafref_type_schema: find the type of node that leafref references to + input: schema_xpath - xpath of a schema node + output: type of the node this leafref references to + """ + def _get_leafref_type_schema(self, schema_xpath): + schema_node = self._find_schema_node(schema_xpath) + if (schema_node is not None): + subtype = schema_node.subtype() + if (subtype is not None): + if subtype.type().base() != ly.LY_TYPE_LEAFREF: + return None + else: + subtype.type().info().lref().path() + target = subtype.type().info().lref().target() + target_path = target.path() + target_type = self._get_data_type(target_path) + return target_type + + return None diff --git a/src/sonic-yang-mgmt/sonic_yang_ext.py b/src/sonic-yang-mgmt/sonic_yang_ext.py new file mode 100644 index 000000000000..3cfad3aaaf63 --- /dev/null +++ b/src/sonic-yang-mgmt/sonic_yang_ext.py @@ -0,0 +1,756 @@ +# This script is used as extension of sonic_yang class. It has methods of +# class sonic_yang. A separate file is used to avoid a single large file. + +from __future__ import print_function +import yang as ly +import re +import syslog + +from json import dump, dumps, loads +from xmltodict import parse +from glob import glob + +""" +This is the Exception thrown out of all public function of this class. +""" +class SonicYangException(Exception): + pass + +# class sonic_yang methods, use mixin to extend sonic_yang +class SonicYangExtMixin: + + """ + load all YANG models, create JSON of yang models. (Public function) + """ + def loadYangModel(self): + + try: + # get all files + self.yangFiles = glob(self.yang_dir +"/*.yang") + # load yang modules + for file in self.yangFiles: + m = self._load_schema_module(file) + if m is not None: + self.sysLog(msg="module: {} is loaded successfully".format(m.name())) + else: + raise(Exception("Could not load module {}".format(file))) + + # keep only modules name in self.yangFiles + self.yangFiles = [f.split('/')[-1] for f in self.yangFiles] + self.yangFiles = [f.split('.')[0] for f in self.yangFiles] + print('Loaded below Yang Models') + print(self.yangFiles) + + # load json for each yang model + self._loadJsonYangModel() + # create a map from config DB table to yang container + self._createDBTableToModuleMap() + + except Exception as e: + print("Yang Models Load failed") + raise SonicYangException("Yang Models Load failed\n{}".format(str(e))) + + return True + + """ + load JSON schema format from yang models + """ + def _loadJsonYangModel(self): + + try: + for f in self.yangFiles: + m = self.ctx.get_module(f) + if m is not None: + xml = m.print_mem(ly.LYD_JSON, ly.LYP_FORMAT) + self.yJson.append(parse(xml)) + self.sysLog(msg="Parsed Json for {}".format(m.name())) + except Exception as e: + raise e + + return + + """ + Create a map from config DB tables to container in yang model + This module name and topLevelContainer are fetched considering YANG models are + written using below Guidelines: + https://github.com/Azure/SONiC/blob/master/doc/mgmt/SONiC_YANG_Model_Guidelines.md. + """ + def _createDBTableToModuleMap(self): + + for j in self.yJson: + # get module name + moduleName = j['module']['@name'] + # get top level container + topLevelContainer = j['module'].get('container') + # if top level container is none, this is common yang files, which may + # have definitions. Store module. + if topLevelContainer is None: + self.confDbYangMap[moduleName] = j['module'] + continue + + # top level container must exist for rest of the yang files and it should + # have same name as module name. + assert topLevelContainer['@name'] == moduleName + + # Each container inside topLevelContainer maps to a sonic config table. + container = topLevelContainer['container'] + # container is a list + if isinstance(container, list): + for c in container: + self.confDbYangMap[c['@name']] = { + "module" : moduleName, + "topLevelContainer": topLevelContainer['@name'], + "container": c + } + # container is a dict + else: + self.confDbYangMap[container['@name']] = { + "module" : moduleName, + "topLevelContainer": topLevelContainer['@name'], + "container": container + } + return + + """ + Get module, topLevelContainer(TLC) and json container for a config DB table + """ + def _getModuleTLCcontainer(self, table): + cmap = self.confDbYangMap + m = cmap[table]['module'] + t = cmap[table]['topLevelContainer'] + c = cmap[table]['container'] + return m, t, c + + """ + Crop config as per yang models, + This Function crops from config only those TABLEs, for which yang models is + provided. The Tables without YANG models are stored in + self.tablesWithOutYangModels. + """ + def _cropConfigDB(self, croppedFile=None): + + for table in self.jIn.keys(): + if table not in self.confDbYangMap: + # store in tablesWithOutYang + self.tablesWithOutYang[table] = self.jIn[table] + del self.jIn[table] + + if len(self.tablesWithOutYang): + print("Note: Below table(s) have no YANG models:") + for table in self.tablesWithOutYang.keys(): + print(unicode(table), end=", ") + print() + + if croppedFile: + with open(croppedFile, 'w') as f: + dump(self.jIn, f, indent=4) + + return + + """ + Extract keys from table entry in Config DB and return in a dict + + Input: + tableKey: Config DB Primary Key, Example tableKey = "Vlan111|2a04:5555:45:6709::1/64" + keys: key string from YANG list, i.e. 'vlan_name ip-prefix'. + regex: A regex to extract keys from tableKeys, good to have it as accurate as possible. + + Return: + KeyDict = {"vlan_name": "Vlan111", "ip-prefix": "2a04:5555:45:6709::1/64"} + """ + def _extractKey(self, tableKey, keys, regex): + + keyList = keys.split() + # get the value groups + value = re.match(regex, tableKey) + # create the keyDict + i = 1 + keyDict = dict() + for k in keyList: + if value.group(i): + keyDict[k] = value.group(i) + else: + raise Exception("Value not found for {} in {}".format(k, tableKey)) + i = i + 1 + + return keyDict + + """ + Fill the dict based on leaf as a list or dict @model yang model object + """ + def _fillLeafDict(self, leafs, leafDict, isleafList=False): + + if leafs is None: + return + + # fill default values + def _fillSteps(leaf): + leaf['__isleafList'] = isleafList + leafDict[leaf['@name']] = leaf + return + + if isinstance(leafs, list): + for leaf in leafs: + #print("{}:{}".format(leaf['@name'], leaf)) + _fillSteps(leaf) + else: + #print("{}:{}".format(leaf['@name'], leaf)) + _fillSteps(leafs) + + return + + """ + create a dict to map each key under primary key with a dict yang model. + This is done to improve performance of mapping from values of TABLEs in + config DB to leaf in YANG LIST. + """ + def _createLeafDict(self, model): + + leafDict = dict() + #Iterate over leaf, choices and leaf-list. + self._fillLeafDict(model.get('leaf'), leafDict) + + #choices, this is tricky, since leafs are under cases in tree. + choices = model.get('choice') + if choices: + for choice in choices: + cases = choice['case'] + for case in cases: + self._fillLeafDict(case.get('leaf'), leafDict) + + # leaf-lists + self._fillLeafDict(model.get('leaf-list'), leafDict, True) + + return leafDict + + """ + Convert a string from Config DB value to Yang Value based on type of the + key in Yang model. + @model : A List of Leafs in Yang model list + """ + def _findYangTypedValue(self, key, value, leafDict): + + # convert config DB string to yang Type + def _yangConvert(val): + # Convert everything to string + val = str(val) + # find type of this key from yang leaf + type = leafDict[key]['type']['@name'] + + if 'uint' in type: + vValue = int(val, 10) + # TODO: find type of leafref from schema node + elif 'leafref' in type: + vValue = val + #TODO: find type in sonic-head, as of now, all are enumeration + elif 'head:' in type: + vValue = val + else: + vValue = val + return vValue + + # if it is a leaf-list do it for each element + if leafDict[key]['__isleafList']: + vValue = list() + for v in value: + vValue.append(_yangConvert(v)) + else: + vValue = _yangConvert(value) + + return vValue + + """ + Xlate a list + This function will xlate from a dict in config DB to a Yang JSON list + using yang model. Output will be go in self.xlateJson + """ + def _xlateList(self, model, yang, config, table): + + #create a dict to map each key under primary key with a dict yang model. + #This is done to improve performance of mapping from values of TABLEs in + #config DB to leaf in YANG LIST. + leafDict = self._createLeafDict(model) + + # fetch regex from YANG models. + keyRegEx = model['ext:key-regex-configdb-to-yang']['@value'] + # seperator `|` has special meaning in regex, so change it appropriately. + keyRegEx = re.sub('\|', '\\|', keyRegEx) + # get keys from YANG model list itself + listKeys = model['key']['@value'] + self.sysLog(msg="xlateList regex:{} keyList:{}".\ + format(keyRegEx, listKeys)) + + for pkey in config.keys(): + try: + vKey = None + self.sysLog(syslog.LOG_DEBUG, "xlateList Extract pkey:{}".\ + format(pkey)) + # Find and extracts key from each dict in config + keyDict = self._extractKey(pkey, listKeys, keyRegEx) + # fill rest of the values in keyDict + for vKey in config[pkey]: + self.sysLog(syslog.LOG_DEBUG, "xlateList vkey {}".format(vKey)) + keyDict[vKey] = self._findYangTypedValue(vKey, \ + config[pkey][vKey], leafDict) + yang.append(keyDict) + # delete pkey from config, done to match one key with one list + del config[pkey] + + except Exception as e: + # log debug, because this exception may occur with multilists + self.sysLog(syslog.LOG_DEBUG, "xlateList Exception {}".format(e)) + # with multilist, we continue matching other keys. + continue + + return + + """ + Process list inside a Container. + This function will call xlateList based on list(s) present in Container. + """ + def _xlateListInContainer(self, model, yang, configC, table): + clist = model + #print(clist['@name']) + yang[clist['@name']] = list() + self.sysLog(msg="xlateProcessListOfContainer: {}".format(clist['@name'])) + self._xlateList(clist, yang[clist['@name']], configC, table) + # clean empty lists + if len(yang[clist['@name']]) == 0: + del yang[clist['@name']] + + return + + """ + Process container inside a Container. + This function will call xlateContainer based on Container(s) present + in outer Container. + """ + def _xlateContainerInContainer(self, model, yang, configC, table): + ccontainer = model + #print(ccontainer['@name']) + yang[ccontainer['@name']] = dict() + if not configC.get(ccontainer['@name']): + return + self.sysLog(msg="xlateProcessListOfContainer: {}".format(ccontainer['@name'])) + self._xlateContainer(ccontainer, yang[ccontainer['@name']], \ + configC[ccontainer['@name']], table) + # clean empty container + if len(yang[ccontainer['@name']]) == 0: + del yang[ccontainer['@name']] + # remove copy after processing + del configC[ccontainer['@name']] + + return + + """ + Xlate a container + This function will xlate from a dict in config DB to a Yang JSON container + using yang model. Output will be stored in self.xlateJson + """ + def _xlateContainer(self, model, yang, config, table): + + # To Handle multiple Lists, Make a copy of config, because we delete keys + # from config after each match. This is done to match one pkey with one list. + configC = config.copy() + + clist = model.get('list') + # If single list exists in container, + if clist and isinstance(clist, dict) and \ + clist['@name'] == model['@name']+"_LIST" and bool(configC): + self._xlateListInContainer(clist, yang, configC, table) + # If multi-list exists in container, + elif clist and isinstance(clist, list) and bool(configC): + for modelList in clist: + self._xlateListInContainer(modelList, yang, configC, table) + + # Handle container(s) in container + ccontainer = model.get('container') + # If single list exists in container, + if ccontainer and isinstance(ccontainer, dict) and bool(configC): + self._xlateContainerInContainer(ccontainer, yang, configC, table) + # If multi-list exists in container, + elif ccontainer and isinstance(ccontainer, list) and bool(configC): + for modelContainer in ccontainer: + self._xlateContainerInContainer(modelContainer, yang, configC, table) + + ## Handle other leaves in container, + leafDict = self._createLeafDict(model) + for vKey in configC.keys(): + #vkey must be a leaf\leaf-list\choice in container + if leafDict.get(vKey): + self.sysLog(syslog.LOG_DEBUG, "xlateContainer vkey {}".format(vKey)) + yang[vKey] = self._findYangTypedValue(vKey, configC[vKey], leafDict) + # delete entry from copy of config + del configC[vKey] + + # All entries in copy of config must have been parsed. + if len(configC): + self.sysLog(syslog.LOG_ERR, "Alert: Remaining keys in Config") + raise(Exception("All Keys are not parsed in {}\n{}".format(table, \ + configC.keys()))) + + return + + """ + xlate ConfigDB json to Yang json + """ + def _xlateConfigDBtoYang(self, jIn, yangJ): + + # find top level container for each table, and run the xlate_container. + for table in jIn.keys(): + cmap = self.confDbYangMap[table] + # create top level containers + key = cmap['module']+":"+cmap['topLevelContainer'] + subkey = cmap['topLevelContainer']+":"+cmap['container']['@name'] + # Add new top level container for first table in this container + yangJ[key] = dict() if yangJ.get(key) is None else yangJ[key] + yangJ[key][subkey] = dict() + self.sysLog(msg="xlateConfigDBtoYang {}:{}".format(key, subkey)) + self._xlateContainer(cmap['container'], yangJ[key][subkey], \ + jIn[table], table) + + return + + """ + Read config file and crop it as per yang models + """ + def _xlateConfigDB(self, xlateFile=None): + + jIn= self.jIn + yangJ = self.xlateJson + # xlation is written in self.xlateJson + self._xlateConfigDBtoYang(jIn, yangJ) + + if xlateFile: + with open(xlateFile, 'w') as f: + dump(self.xlateJson, f, indent=4) + + return + + """ + create config DB table key from entry in yang JSON + """ + def _createKey(self, entry, regex): + + keyDict = dict() + keyV = regex + # get the keys from regex of key extractor + keyList = re.findall(r'<(.*?)>', regex) + for key in keyList: + val = entry.get(key) + if val: + #print("pair: {} {}".format(key, val)) + keyDict[key] = sval = str(val) + keyV = re.sub(r'<'+key+'>', sval, keyV) + #print("VAL: {} {}".format(regex, keyV)) + else: + raise Exception("key {} not found in entry".format(key)) + #print("kDict {}".format(keyDict)) + return keyV, keyDict + + """ + Convert a string from Config DB value to Yang Value based on type of the + key in Yang model. + @model : A List of Leafs in Yang model list + """ + def _revFindYangTypedValue(self, key, value, leafDict): + + # convert yang Type to config DB string + def _revYangConvert(val): + # config DB has only strings, thank god for that :), wait not yet!!! + return str(val) + + # if it is a leaf-list do it for each element + if leafDict[key]['__isleafList']: + vValue = list() + for v in value: + vValue.append(_revYangConvert(v)) + else: + vValue = _revYangConvert(value) + + return vValue + + """ + Rev xlate from _LIST to table in config DB + """ + def _revXlateList(self, model, yang, config, table): + + # fetch regex from YANG models + keyRegEx = model['ext:key-regex-yang-to-configdb']['@value'] + self.sysLog(msg="revXlateList regex:{}".format(keyRegEx)) + + # create a dict to map each key under primary key with a dict yang model. + # This is done to improve performance of mapping from values of TABLEs in + # config DB to leaf in YANG LIST. + leafDict = self._createLeafDict(model) + + # list with name _LIST should be removed, + if "_LIST" in model['@name']: + for entry in yang: + # create key of config DB table + pkey, pkeydict = self._createKey(entry, keyRegEx) + self.sysLog(syslog.LOG_DEBUG, "revXlateList pkey:{}".format(pkey)) + config[pkey]= dict() + # fill rest of the entries + for key in entry: + if key not in pkeydict: + config[pkey][key] = self._revFindYangTypedValue(key, \ + entry[key], leafDict) + + return + + """ + Rev xlate a list inside a yang container + """ + def _revXlateListInContainer(self, model, yang, config, table): + modelList = model + # Pass matching list from Yang Json if exist + if yang.get(modelList['@name']): + self.sysLog(msg="revXlateListInContainer {}".format(modelList['@name'])) + self._revXlateList(modelList, yang[modelList['@name']], config, table) + return + + """ + Rev xlate a container inside a yang container + """ + def _revXlateContainerInContainer(self, model, yang, config, table): + modelContainer = model + # Pass matching list from Yang Json if exist + if yang.get(modelContainer['@name']): + config[modelContainer['@name']] = dict() + self.sysLog(msg="revXlateContainerInContainer {}".format(modelContainer['@name'])) + self._revXlateContainer(modelContainer, yang[modelContainer['@name']], \ + config[modelContainer['@name']], table) + return + + """ + Rev xlate from yang container to table in config DB + """ + def _revXlateContainer(self, model, yang, config, table): + + # IF container has only one list + clist = model.get('list') + if isinstance(clist, dict): + self._revXlateListInContainer(clist, yang, config, table) + # IF container has lists + elif isinstance(clist, list): + for modelList in clist: + self._revXlateListInContainer(modelList, yang, config, table) + + ccontainer = model.get('container') + # IF container has only one inner container + if isinstance(ccontainer, dict): + self._revXlateContainerInContainer(ccontainer, yang, config, table) + # IF container has only many inner container + elif isinstance(ccontainer, list): + for modelContainer in ccontainer: + self._revXlateContainerInContainer(modelContainer, yang, config, table) + + ## Handle other leaves in container, + leafDict = self._createLeafDict(model) + for vKey in yang: + #vkey must be a leaf\leaf-list\choice in container + if leafDict.get(vKey): + self.sysLog(syslog.LOG_DEBUG, "revXlateContainer vkey {}".format(vKey)) + config[vKey] = self._revFindYangTypedValue(vKey, yang[vKey], leafDict) + + return + + """ + rev xlate ConfigDB json to Yang json + """ + def _revXlateYangtoConfigDB(self, yangJ, cDbJson): + + yangJ = self.xlateJson + cDbJson = self.revXlateJson + + # find table in config DB, use name as a KEY + for module_top in yangJ.keys(): + # module _top will be of from module:top + for container in yangJ[module_top].keys(): + #table = container.split(':')[1] + table = container + #print("revXlate " + table) + cmap = self.confDbYangMap[table] + cDbJson[table] = dict() + #print(key + "--" + subkey) + self.sysLog(msg="revXlateYangtoConfigDB {}".format(table)) + self._revXlateContainer(cmap['container'], yangJ[module_top][container], \ + cDbJson[table], table) + + return + + """ + Reverse Translate tp config DB + """ + def _revXlateConfigDB(self, revXlateFile=None): + + yangJ = self.xlateJson + cDbJson = self.revXlateJson + # xlation is written in self.xlateJson + self._revXlateYangtoConfigDB(yangJ, cDbJson) + + if revXlateFile: + with open(revXlateFile, 'w') as f: + dump(self.revXlateJson, f, indent=4) + + return + + """ + Find a list in YANG Container + c = container + l = list name + return: list if found else None + """ + def _findYangList(self, container, listName): + + if isinstance(container['list'], dict): + clist = container['list'] + if clist['@name'] == listName: + return clist + + elif isinstance(container['list'], list): + clist = [l for l in container['list'] if l['@name'] == listName] + return clist[0] + + return None + + """ + Find xpath of the PORT Leaf in PORT container/list. Xpath of Leaf is needed, + because only leaf can have leafrefs depend on them. (Public) + """ + def findXpathPortLeaf(self, portName): + + try: + table = "PORT" + xpath = self.findXpathPort(portName) + module, topc, container = self._getModuleTLCcontainer(table) + list = self._findYangList(container, table+"_LIST") + xpath = xpath + "/" + list['key']['@value'].split()[0] + except Exception as e: + print("find xpath of port Leaf failed") + raise SonicYangException("find xpath of port Leaf failed\n{}".format(str(e))) + + return xpath + + """ + Find xpath of PORT. (Public) + """ + def findXpathPort(self, portName): + + try: + table = "PORT" + module, topc, container = self._getModuleTLCcontainer(table) + xpath = "/" + module + ":" + topc + "/" + table + + list = self._findYangList(container, table+"_LIST") + xpath = self._findXpathList(xpath, list, [portName]) + except Exception as e: + print("find xpath of port failed") + raise SonicYangException("find xpath of port failed\n{}".format(str(e))) + + return xpath + + """ + Find xpath of a YANG LIST from keys, + xpath: xpath till list + list: YANG List + keys: list of keys in YANG LIST + """ + def _findXpathList(self, xpath, list, keys): + + try: + # add list name in xpath + xpath = xpath + "/" + list['@name'] + listKeys = list['key']['@value'].split() + i = 0; + for listKey in listKeys: + xpath = xpath + '['+listKey+'=\''+keys[i]+'\']' + i = i + 1 + except Exception as e: + raise e + + return xpath + + """ + load_data: load Config DB, crop, xlate and create data tree from it. (Public) + input: data + returns: True - success False - failed + """ + def loadData(self, configdbJson): + + try: + self.jIn = configdbJson + # reset xlate and tablesWithOutYang + self.xlateJson = dict() + self.tablesWithOutYang = dict() + # self.jIn will be cropped + self._cropConfigDB() + # xlated result will be in self.xlateJson + self._xlateConfigDB() + #print(self.xlateJson) + self.sysLog(msg="Try to load Data in the tree") + self.root = self.ctx.parse_data_mem(dumps(self.xlateJson), \ + ly.LYD_JSON, ly.LYD_OPT_CONFIG|ly.LYD_OPT_STRICT) + + except Exception as e: + self.root = None + print("Data Loading Failed") + raise SonicYangException("Data Loading Failed\n{}".format(str(e))) + + return True + + """ + Get data from Data tree, data tree will be assigned in self.xlateJson. (Public) + """ + def getData(self): + + try: + self.xlateJson = loads(self._print_data_mem('JSON')) + # reset reverse xlate + self.revXlateJson = dict() + # result will be stored self.revXlateJson + self._revXlateConfigDB() + + except Exception as e: + print("Get Data Tree Failed") + raise SonicYangException("Get Data Tree Failed\n{}".format(str(e))) + + return self.revXlateJson + + """ + Delete a node from data tree, if this is LEAF and KEY Delete the Parent. + (Public) + """ + def deleteNode(self, xpath): + + # These MACROS used only here, can we get it from Libyang Header ? + try: + LYS_LEAF = 4 + node = self._find_data_node(xpath) + if node is None: + raise('Node {} not found'.format(xpath)) + + snode = node.schema() + # check for a leaf if it is a key. If yes delete the parent + if (snode.nodetype() == LYS_LEAF): + leaf = ly.Schema_Node_Leaf(snode) + if leaf.is_key(): + # try to delete parent + nodeP = self._find_parent_data_node(xpath) + xpathP = nodeP.path() + if self._deleteNode(xpath=xpathP, node=nodeP) == False: + raise Exception('_deleteNode failed') + else: + return True + + # delete non key element + if self._deleteNode(xpath=xpath, node=node) == False: + raise Exception('_deleteNode failed') + except Exception as e: + raise SonicYangException("Failed to delete node {}\n{}".\ + format( xpath, str(e))) + + return True + + # End of class sonic_yang diff --git a/src/sonic-yang-mgmt/tests/__init__.py b/src/sonic-yang-mgmt/tests/__init__.py new file mode 100644 index 000000000000..ec983d6590c7 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +"""Unit test package for sonic_yang_mgmt.""" diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/config_data.json b/src/sonic-yang-mgmt/tests/libyang-python-tests/config_data.json new file mode 100644 index 000000000000..8a4eaed176d2 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/config_data.json @@ -0,0 +1,260 @@ +{ + "test-vlan:vlan": { + "test-vlan:VLAN_INTERFACE": { + "VLAN_INTERFACE_LIST": [{ + "vlanid": 111, + "ip-prefix": "2000:f500:45:6709::1/64", + "scope": "global", + "family": "IPv6" + }, + { + "vlanid": 111, + "ip-prefix": "10.1.1.65/26", + "scope": "global", + "family": "IPv4" + }, + { + "vlanid": 111, + "ip-prefix": "fe80::1/10", + "scope": "local", + "family": "IPv6" + }, + { + "vlanid": 555, + "ip-prefix": "2000:f500:41:4e9::1/64", + "scope": "global", + "family": "IPv6" + }, + { + "vlanid": 555, + "ip-prefix": "10.1.5.65/26", + "scope": "global", + "family": "IPv4" + }, + { + "vlanid": 555, + "ip-prefix": "fe80::1/10", + "scope": "local", + "family": "IPv6" + } + ] + }, + + "test-vlan:VLAN": { + "VLAN_LIST": [{ + "vlanid": 111, + "description": "server_vlan", + "dhcp_servers": [ + "10.1.7.116" + ], + "mtu": "9216", + "admin_status": "up" + }, + { + "vlanid": 555, + "description": "ipmi_vlan", + "dhcp_servers": [ + "10.1.7.116" + ], + "mtu": "9216", + "admin_status": "up" + } + ] + }, + + "test-vlan:VLAN_MEMBER": { + "VLAN_MEMBER_LIST": [{ + "vlanid": 111, + "port": "Ethernet0", + "tagging_mode": "tagged" + }, + { + "vlanid": 111, + "port": "Ethernet1", + "tagging_mode": "tagged" + }, + { + "vlanid": 111, + "port": "Ethernet2", + "tagging_mode": "tagged" + }, + { + "vlanid": 111, + "port": "Ethernet3", + "tagging_mode": "tagged" + }, + { + "vlanid": 111, + "port": "Ethernet4", + "tagging_mode": "tagged" + }, + { + "vlanid": 111, + "port": "Ethernet5", + "tagging_mode": "tagged" + }, + { + "vlanid": 111, + "port": "Ethernet6", + "tagging_mode": "tagged" + } + ] + } + }, + "test-port:port": { + "test-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet2", + "alias": "eth2", + "description": "Ethernet2", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet3", + "alias": "eth2", + "description": "Ethernet3", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet4", + "alias": "eth4", + "description": "Ethernet4", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet5", + "alias": "eth5", + "description": "Ethernet5", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet6", + "alias": "eth6", + "description": "Ethernet6", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet7", + "alias": "eth7", + "description": "Ethernet7", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet8", + "alias": "eth8", + "description": "Ethernet8", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet9", + "alias": "eth9", + "description": "Ethernet9", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + }, + + "test-acl:acl": { + "test-acl:ACL_RULE": { + "ACL_RULE_LIST": [{ + "ACL_TABLE_NAME": "PACL-V4", + "RULE_NAME": "Rule_20", + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.1.72.0/26", + "SRC_IP": "10.1.0.0/15", + "PRIORITY": "999980", + "IP_TYPE": "IPV4ANY" + }, + { + "ACL_TABLE_NAME": "PACL-V4", + "RULE_NAME": "Rule_40", + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.1.72.64/26", + "SRC_IP": "10.1.0.0/15", + "PRIORITY": "999960", + "IP_TYPE": "IPV4ANY", + "INNER_ETHER_TYPE": "0x88CC" + }, + { + "ACL_TABLE_NAME": "PACL-V6", + "RULE_NAME": "Rule_20", + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IP", + "SRC_IPV6": "2000:f500:41::/48", + "PRIORITY": "999980", + "DST_IPV6": "2000:f500:43:320::/64", + "L4_SRC_PORT_RANGE": "653-1053" + } + ] + }, + + "test-acl:ACL_TABLE": { + "ACL_TABLE_LIST": [{ + "ACL_TABLE_NAME": "PACL-V6", + "policy_desc": "Filter IPv6", + "type": "L3V6", + "stage": "EGRESS", + "ports": ["Ethernet7", "Ethernet9", "Ethernet8"] + }, + { + "ACL_TABLE_NAME": "PACL-V4", + "policy_desc": "Filter IPv6", + "type": "L3", + "stage": "INGRESS", + "ports": ["Ethernet2", "Ethernet0", "Ethernet1"] + } + ] + } + }, + + "test-interface:interface": { + "test-interface:INTERFACE": { + "INTERFACE_LIST": [{ + "interface": "Ethernet8", + "ip-prefix": "10.1.1.65/26", + "scope": "global", + "family": "IPv4" + }, + { + "interface": "Ethernet8", + "ip-prefix": "2000:f500:40:a749::2/126", + "scope": "global", + "family": "IPv6" + } + ] + } + } +} diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/config_data_merge.json b/src/sonic-yang-mgmt/tests/libyang-python-tests/config_data_merge.json new file mode 100644 index 000000000000..73838a157c4a --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/config_data_merge.json @@ -0,0 +1,154 @@ +{ + "test-vlan:vlan": { + "test-vlan:VLAN_INTERFACE": { + "VLAN_INTERFACE_LIST": [{ + "vlanid": 111, + "ip-prefix": "2000:f500:45:6709::1/64", + "scope": "global", + "family": "IPv6" + }, + { + "vlanid": 111, + "ip-prefix": "10.1.1.64/26", + "scope": "global", + "family": "IPv4" + }, + { + "vlanid": 200, + "ip-prefix": "2000:f500:45:6708::1/64", + "scope": "global", + "family": "IPv6" + }, + { + "vlanid": 200, + "ip-prefix": "2000:f500:45:6709::1/64", + "scope": "global", + "family": "IPv6" + } + ] + }, + + "test-vlan:VLAN": { + "VLAN_LIST": [{ + "vlanid": 200, + "description": "server_vlan", + "dhcp_servers": [ + "10.1.72.116" + ], + "mtu": "9216", + "admin_status": "up" + }, + { + "vlanid": 111, + "description": "server_vlan", + "dhcp_servers": [ + "10.1.72.116" + ], + "mtu": "9216", + "admin_status": "up" + } + ] + }, + + "test-vlan:VLAN_MEMBER": { + "VLAN_MEMBER_LIST": [{ + "vlanid": 200, + "port": "Ethernet0", + "tagging_mode": "tagged" + }] + } + }, + "test-port:port": { + "test-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet2", + "alias": "eth2", + "description": "Ethernet2", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet3", + "alias": "eth2", + "description": "Ethernet3", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet4", + "alias": "eth4", + "description": "Ethernet4", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet5", + "alias": "eth5", + "description": "Ethernet5", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet6", + "alias": "eth6", + "description": "Ethernet6", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet7", + "alias": "eth7", + "description": "Ethernet7", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet8", + "alias": "eth8", + "description": "Ethernet8", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet9", + "alias": "eth9", + "description": "Ethernet9", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet10", + "alias": "eth10", + "description": "Ethernet10", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + } +} diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-acl.yang b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-acl.yang new file mode 100644 index 000000000000..0d7d93a1429a --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-acl.yang @@ -0,0 +1,268 @@ +module test-acl { + + yang-version 1.1; + + namespace "http://github.com/Azure/acl"; + prefix acl; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import test-head { + prefix head; + revision-date 2019-07-01; + } + + import test-port { + prefix port; + revision-date 2019-07-01; + } + + import test-portchannel { + prefix lag; + revision-date 2019-07-01; + } + + revision 2019-07-01 { + description "First Revision"; + } + + container acl { + + container ACL_RULE { + + description "ACL_RULE part of config_db.json"; + + list ACL_RULE_LIST { + + key "ACL_TABLE_NAME RULE_NAME"; + + leaf ACL_TABLE_NAME { + type leafref { + path "/acl:acl/acl:ACL_TABLE/acl:ACL_TABLE_LIST/acl:ACL_TABLE_NAME"; + } + } + + leaf RULE_NAME { + type string { + length 1..255; + } + } + + leaf PACKET_ACTION { + type head:packet_action; + } + + leaf IP_TYPE { + type head:ip_type; + } + + leaf PRIORITY { + type uint32 { + range 0..999999; + } + } + + choice ip_prefix { + + case ip4_prefix { + when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV4' or .='IPV4ANY' or .='ARP'])"; + leaf SRC_IP { + type inet:ipv4-prefix; + } + + leaf DST_IP { + type inet:ipv4-prefix; + } + } + + case ip6_prefix { + when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV6' or .='IPV6ANY'])"; + leaf SRC_IPV6 { + type inet:ipv6-prefix; + } + + leaf DST_IPV6 { + type inet:ipv6-prefix; + } + } + } + + leaf-list IN_PORTS { + /* Values in leaf list are UNIQUE */ + type uint16; + } + + leaf-list OUT_PORTS { + /* Values in leaf list are UNIQUE */ + type uint16; + } + + choice src_port { + case l4_src_port { + leaf L4_SRC_PORT { + type uint16; + } + } + + case l4_src_port_range { + leaf L4_SRC_PORT_RANGE { + type string { + pattern '([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])-([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])'; + } + } + } + } + + choice dst_port { + case l4_dst_port { + leaf L4_DST_PORT { + type uint16; + } + } + + case l4_dst_port_range { + leaf L4_DST_PORT_RANGE { + type string { + pattern '([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])-([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])'; + } + } + } + } + + leaf ETHER_TYPE { + type string { + pattern "(0x88CC|0x8100|0x8915|0x0806|0x0800|0x86DD|0x8847)"; + } + } + + leaf IP_PROTOCOL { + type uint8 { + range 1..143; + } + } + + leaf TCP_FLAGS { + type string { + pattern '0[x][0-9a-fA-F]{1,2}|0[X][0-9a-fA-F]{1,2}'; + } + } + + leaf DSCP { + type uint8; + } + + leaf TC { + type uint8; + } + + choice icmp { + + case icmp4 { + when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV4' or .='IPV4ANY' or .='ARP'])"; + leaf ICMP_TYPE { + type uint8 { + range 1..44; + } + } + + leaf ICMP_CODE { + type uint8 { + range 1..16; + } + } + } + + case icmp6 { + when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV6' or .='IPV6ANY'])"; + leaf ICMPV6_TYPE { + type uint8 { + range 1..44; + } + } + + leaf ICMPV6_CODE { + type uint8 { + range 1..16; + } + } + } + } + + leaf INNER_ETHER_TYPE { + type string { + pattern "(0x88CC|0x8100|0x8915|0x0806|0x0800|0x86DD|0x8847)"; + } + } + + leaf INNER_IP_PROTOCOL { + type uint8 { + range 1..143; + } + } + + leaf INNER_L4_SRC_PORT { + type uint16; + } + + leaf INNER_L4_DST_PORT { + type uint16; + } + } + /* end of ACL_RULE_LIST */ + } + /* end of container ACL_RULE */ + + container ACL_TABLE { + + description "ACL_TABLE part of config_db.json"; + + list ACL_TABLE_LIST { + + key "ACL_TABLE_NAME"; + + leaf ACL_TABLE_NAME { + type string; + } + + leaf policy_desc { + type string { + length 1..255; + } + } + + leaf type { + type head:acl_table_type; + } + + leaf stage { + type enumeration { + enum INGRESS; + enum EGRESS; + } + } + + leaf-list ports { + /* union of leafref is allowed in YANG 1.1 */ + type union { + type leafref { + path /port:port/port:PORT/port:PORT_LIST/port:port_name; + } + type leafref { + path /lag:portchannel/lag:PORTCHANNEL/lag:PORTCHANNEL_LIST/lag:portchannel_name; + } + } + } + } + /* end of ACL_TABLE_LIST */ + } + /* end of container ACL_TABLE */ + } + /* end of container acl */ +} +/* end of module acl */ diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-head.yang b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-head.yang new file mode 100644 index 000000000000..cdb45a3d0d15 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-head.yang @@ -0,0 +1,66 @@ +module test-head { + + namespace "http://head"; + prefix head; + + revision 2019-07-01 { + description "First Revision"; + } + + typedef ip-family { + type enumeration { + enum IPv4; + enum IPv6; + } + } + + typedef admin_status { + type enumeration { + enum up; + enum down; + } + } + + typedef packet_action{ + type enumeration { + enum DROP; + enum FORWARD; + enum REDIRECT; + } + } + + typedef ip_type { + type enumeration { + enum ANY; + enum IP; + enum NON_IP; + enum IPV4; + enum IPV6; + enum IPV4ANY; + enum NON_IPv4; + enum IPV6ANY; + enum NON_IPv6; + enum ARP; + } + } + + typedef acl_table_type { + type enumeration { + enum L2; + enum L3; + enum L3V6; + enum MIRROR; + enum MIRRORV6; + enum MIRROR_DSCP; + enum CTRLPLANE; + } + } + + typedef vlan_tagging_mode { + type enumeration { + enum tagged; + enum untagged; + enum priority_tagged; + } + } +} diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-interface.yang b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-interface.yang new file mode 100644 index 000000000000..2f453ac6e278 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-interface.yang @@ -0,0 +1,72 @@ +module test-interface { + + namespace "http://github.com/Azure/interface"; + prefix intf; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import test-head { + prefix head; + revision-date 2019-07-01; + } + + import test-port { + prefix port; + revision-date 2019-07-01; + } + + revision 2019-07-01 { + description "First Revision"; + } + + container interface { + container INTERFACE { + + description "INTERFACE part of config_db.json"; + + list INTERFACE_LIST { + + key "interface ip-prefix"; + + leaf interface { + type leafref { + path /port:port/port:PORT/port:PORT_LIST/port:port_name; + } + } + + leaf ip-prefix { + type inet:ip-prefix; + } + + leaf scope { + type enumeration { + enum global; + enum local; + } + } + + leaf family { + + /* family leaf needed for backward compatibility + Both ip4 and ip6 address are string in IETF RFC 6021, + so must statement can check based on : or ., family + should be IPv4 or IPv6 according. + */ + + must "(contains(../ip-prefix, ':') and current()='IPv6') or + (contains(../ip-prefix, '.') and current()='IPv4')"; + type head:ip-family; + } + } + /* end of INTERFACE_LIST */ + + } + /* end of INTERFACE container */ + } +} diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-port.yang b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-port.yang new file mode 100644 index 000000000000..5e2bf68f7914 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-port.yang @@ -0,0 +1,78 @@ +module test-port{ + + namespace "http://github.com/Azure/port"; + prefix port; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import test-head { + prefix head; + revision-date 2019-07-01; + } + + revision 2019-07-01 { + description "First Revision"; + } + + container port{ + container PORT { + + description "PORT part of config_db.json"; + + list PORT_LIST { + + key "port_name"; + + leaf port_name { + type string { + length 1..128; + } + } + + leaf alias { + type string { + length 1..128; + } + } + + leaf lanes { + type string { + length 1..128; + } + } + + leaf description { + type string { + length 1..255; + } + } + + leaf speed { + type uint32 { + range 1..100000; + } + } + + leaf mtu { + type uint16 { + range 1..9216; + } + } + + leaf admin_status { + mandatory true; + type head:admin_status; + } + } /* end of list PORT_LIST */ + + } /* end of container PORT */ + + } /* end of container port */ + +} /* end of module port */ diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-portchannel.yang b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-portchannel.yang new file mode 100644 index 000000000000..2081383aeda8 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-portchannel.yang @@ -0,0 +1,79 @@ +module test-portchannel { + + namespace "http://github.com/Azure/portchannel"; + prefix lag; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import test-head { + prefix head; + revision-date 2019-07-01; + } + + import test-port { + prefix port; + revision-date 2019-07-01; + } + + revision 2019-07-01 { + description "First Revision"; + } + + container portchannel { + container PORTCHANNEL { + + description "PORTCHANNEL part of config_db.json"; + + list PORTCHANNEL_LIST { + + key "portchannel_name"; + + leaf portchannel_name { + type string { + length 1..128; + pattern 'PortChannel[0-9]{1,4}'; + } + } + + leaf-list members { + /* leaf-list members are unique by default */ + type leafref { + path /port:port/port:PORT/port:PORT_LIST/port:port_name; + } + } + + leaf min_links { + type uint8 { + range 1..128; + } + } + + leaf description { + type string { + length 1..255; + } + } + + leaf mtu { + type uint16 { + range 1..9216; + } + } + + leaf admin_status { + mandatory true; + type head:admin_status; + } + } /* end of list PORTCHANNEL_LIST */ + + } /* end of container PORTCHANNEL */ + + } /* end of container portchannel */ + +} /* end of module port */ diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-vlan.yang b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-vlan.yang new file mode 100644 index 000000000000..2ca80607b410 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample-yang-models/test-vlan.yang @@ -0,0 +1,144 @@ +module test-vlan { + + namespace "http://github.com/Azure/vlan"; + prefix vlan; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import test-head { + prefix head; + revision-date 2019-07-01; + } + + import test-port { + prefix port; + revision-date 2019-07-01; + } + + revision 2019-07-01 { + description "First Revision"; + } + + container vlan { + container VLAN_INTERFACE { + + description "VLAN_INTERFACE part of config_db.json"; + + list VLAN_INTERFACE_LIST { + + key "vlanid ip-prefix"; + + leaf vlanid { + type leafref { + path ../../../VLAN/VLAN_LIST/vlanid; + } + } + + leaf ip-prefix { + mandatory true; + type inet:ip-prefix; + } + + leaf scope { + type enumeration { + enum global; + enum local; + } + } + + leaf family { + + /* family leaf needed for backward compatibility + Both ip4 and ip6 address are string in IETF RFC 6021, + so must statement can check based on : or ., family + should be IPv4 or IPv6 according. + */ + + must "(contains(../ip-prefix, ':') and current()='IPv6') or + (contains(../ip-prefix, '.') and current()='IPv4')"; + type head:ip-family; + } + } + /* end of VLAN_INTERFACE_LIST */ + } + /* end of VLAN_INTERFACE container */ + + container VLAN { + + description "VLAN part of config_db.json"; + + list VLAN_LIST { + + key "vlanid"; + + leaf vlanid { + type uint16 { + range 1..4094; + } + } + + leaf description { + type string { + length 1..255; + } + } + + leaf-list dhcp_servers { + type inet:ip-address; + } + + leaf mtu { + type uint16 { + range 1..9216; + } + } + + leaf admin_status { + mandatory true; + type head:admin_status; + } + } + /* end of VLAN_LIST */ + } + /* end of container VLAN */ + + container VLAN_MEMBER { + + description "VLAN_MEMBER part of config_db.json"; + + list VLAN_MEMBER_LIST { + + key "vlanid port"; + + leaf vlanid { + type leafref { + path ../../../VLAN/VLAN_LIST/vlanid; + } + } + + leaf port { + /* key elements are mandatory by default */ + mandatory true; + type leafref { + path /port:port/port:PORT/port:PORT_LIST/port:port_name; + } + } + + leaf tagging_mode { + mandatory true; + type head:vlan_tagging_mode; + } + } + /* end of list VLAN_MEMBER_LIST */ + } + /* end of container VLAN_MEMBER */ + } + /* end of container vlan */ +} +/* end of module vlan */ diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/sample_config_db.json b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample_config_db.json new file mode 100644 index 000000000000..a37639fb4b73 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/sample_config_db.json @@ -0,0 +1,648 @@ +{ + "VLAN_INTERFACE": { + "Vlan111|2a04:5555:45:6709::1/64": { + "scope": "global", + "family": "IPv6" + }, + "Vlan111|10.222.10.65/26": { + "scope": "global", + "family": "IPv4" + }, + "Vlan111|fe80::1/10": { + "scope": "local", + "family": "IPv6" + }, + "Vlan777|2a04:5555:41:4e9::1/64": { + "scope": "global", + "family": "IPv6" + }, + "Vlan777|10.111.58.65/26": { + "scope": "global", + "family": "IPv4" + }, + "Vlan777|fe80::1/10": { + "scope": "local", + "family": "IPv6" + } + }, + "ACL_RULE": { + "V4-ACL-TABLE|DEFAULT_DENY": { + "PACKET_ACTION": "DROP", + "IP_TYPE": "IPv4ANY", + "PRIORITY": "0" + }, + "V4-ACL-TABLE|Rule_20": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.222.72.0/26", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777780", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_40": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.222.72.64/26", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777760", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_60": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.222.80.0/26", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777740", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_80": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.222.80.64/26", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777720", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_111": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.152.17.52/32", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777700", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_120": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.252.208.41/32", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777880", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_140": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.148.128.245/32", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777860", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_160": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.222.1.245/32", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777840", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_180": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.252.222.21/32", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777820", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_9000": { + "PACKET_ACTION": "DROP", + "DST_IP": "0.0.0.0/0", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "991110", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_11100": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "0.0.0.0/0", + "SRC_IP": "0.0.0.0/0", + "PRIORITY": "990000", + "IP_TYPE": "IPv4ANY" + }, + "V6-ACL-TBLE|DEFAULT_DENY": { + "PACKET_ACTION": "DROP", + "IP_TYPE": "IPv6ANY", + "PRIORITY": "0" + }, + "V6-ACL-TBLE|Rule_20": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "777780", + "DST_IPV6": "2a04:5555:43:320::/64" + }, + "V6-ACL-TBLE|Rule_40": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "777760", + "DST_IPV6": "2a04:5555:43:321::/64" + }, + "V6-ACL-TBLE|Rule_60": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "777740", + "DST_IPV6": "2a04:5555:43:340::/64" + }, + "V6-ACL-TBLE|Rule_80": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "777720", + "DST_IPV6": "2a04:5555:43:341::/64" + }, + "V6-ACL-TBLE|Rule_111": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "777700", + "DST_IPV6": "2a04:5555:32:12::/64" + }, + "V6-ACL-TBLE|Rule_9000": { + "PACKET_ACTION": "DROP", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "991110", + "DST_IPV6": "::/0" + }, + "V6-ACL-TBLE|Rule_11100": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "::/0", + "PRIORITY": "990000", + "DST_IPV6": "::/0" + } + }, + "DEVICE_METADATA": { + "localhost": { + "mg_type": "ToR", + "mac": "00:11:22:33:dd:5a", + "hostname": "asw.dc", + "bgp_asn": "64850", + "hwsku": "Stone" + } + }, + "VLAN": { + "Vlan111": { + "description": "svlan", + "dhcp_servers": [ + "10.222.72.116" + ], + "vlanid": "111", + "mtu": "9216", + "admin_status": "up", + "members": [ + "Ethernet8", + "Ethernet3", + "Ethernet0", + "Ethernet1", + "Ethernet6", + "Ethernet4", + "Ethernet5", + "Ethernet9", + "Ethernet2", + "Ethernet7", + "Ethernet32", + "Ethernet30", + "Ethernet31", + "Ethernet36", + "Ethernet34", + "Ethernet33", + "Ethernet35", + "Ethernet29", + "Ethernet21", + "Ethernet20", + "Ethernet23", + "Ethernet22", + "Ethernet27", + "Ethernet26", + "Ethernet18", + "Ethernet19", + "Ethernet14", + "Ethernet15", + "Ethernet16", + "Ethernet17", + "Ethernet10", + "Ethernet11", + "Ethernet12", + "Ethernet13", + "Ethernet28" + ] + }, + "Vlan777": { + "description": "pvlan", + "dhcp_servers": [ + "10.222.72.116" + ], + "vlanid": "777", + "mtu": "9216", + "admin_status": "up", + "members": [ + "Ethernet9", + "Ethernet2", + "Ethernet8", + "Ethernet27", + "Ethernet14", + "Ethernet35" + ] + } + }, + "DEVICE_NEIGHBOR": { + "Ethernet112": { + "name": "dccsw01.nw", + "port": "Eth18" + }, + "Ethernet114": { + "name": "dccsw02.nw", + "port": "Eth18" + }, + "Ethernet116": { + "name": "dccsw03.nw", + "port": "Eth18" + }, + "Ethernet118": { + "name": "dccsw04.nw", + "port": "Eth18" + } + }, + "PORT": { + "Ethernet0": { + "alias": "Eth1/1", + "lanes": "65", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet1": { + "alias": "Eth1/2", + "lanes": "66", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet2": { + "alias": "Eth1/3", + "lanes": "67", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet3": { + "alias": "Eth1/4", + "lanes": "68", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet4": { + "alias": "Eth2/1", + "lanes": "69", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet5": { + "alias": "Eth2/2", + "lanes": "70", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet6": { + "alias": "Eth2/3", + "lanes": "71", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet7": { + "alias": "Eth2/4", + "lanes": "72", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet8": { + "alias": "Eth3/1", + "lanes": "73", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet9": { + "alias": "Eth3/2", + "lanes": "74", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet10": { + "alias": "Eth3/3", + "lanes": "75", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet11": { + "alias": "Eth3/4", + "lanes": "76", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet12": { + "alias": "Eth4/1", + "lanes": "77", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet13": { + "alias": "Eth4/2", + "lanes": "78", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet14": { + "alias": "Eth4/3", + "lanes": "79", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet15": { + "alias": "Eth4/4", + "lanes": "80", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet16": { + "alias": "Eth5/1", + "lanes": "33", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet17": { + "alias": "Eth5/2", + "lanes": "34", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet18": { + "alias": "Eth5/3", + "lanes": "35", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet19": { + "alias": "Eth5/4", + "lanes": "36", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet20": { + "alias": "Eth6/1", + "lanes": "37", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet21": { + "alias": "Eth6/2", + "lanes": "38", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet22": { + "alias": "Eth6/3", + "lanes": "39", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet23": { + "alias": "Eth6/4", + "lanes": "40", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet24": { + "alias": "Eth7/1", + "lanes": "41", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet25": { + "alias": "Eth7/2", + "lanes": "42", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet26": { + "alias": "Eth7/3", + "lanes": "43", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet27": { + "alias": "Eth7/4", + "lanes": "44", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet28": { + "alias": "Eth8/1", + "lanes": "45", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet29": { + "alias": "Eth8/2", + "lanes": "46", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet30": { + "alias": "Eth8/3", + "lanes": "47", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet31": { + "alias": "Eth8/4", + "lanes": "48", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet32": { + "alias": "Eth9/1", + "lanes": "49", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet33": { + "alias": "Eth9/2", + "lanes": "50", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet34": { + "alias": "Eth9/3", + "lanes": "51", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet35": { + "alias": "Eth9/4", + "lanes": "52", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet36": { + "alias": "Eth10/1", + "lanes": "53", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet112": { + "alias": "Eth29/1", + "lanes": "113,114", + "description": "50G|dccsw01.nw|Eth18", + "fec": "fc", + "admin_status": "up" + } + }, + "ACL_TABLE": { + "V4-ACL-TABLE": { + "type": "L3", + "policy_desc": "V4-ACL-TABLE", + "ports": [ + "Ethernet26", + "Ethernet27", + "Ethernet24" + ] + }, + "V6-ACL-TBLE": { + "type": "L3V6", + "policy_desc": "V6-ACL-TBLE", + "ports": [ + "Ethernet14", + "Ethernet15", + "Ethernet23", + "Ethernet30", + "Ethernet31", + "Ethernet18", + "Ethernet19", + "Ethernet25", + "Ethernet24" + ] + } + }, + "INTERFACE": { + "Ethernet112|2a04:5555:40:a709::2/126": { + "scope": "global", + "family": "IPv6" + }, + "Ethernet112|10.184.228.211/31": { + "scope": "global", + "family": "IPv4" + }, + "Ethernet14|2a04:5555:40:a749::2/126": { + "scope": "global", + "family": "IPv6" + }, + "Ethernet14|10.184.229.211/31": { + "scope": "global", + "family": "IPv4" + }, + "Ethernet16|2a04:5555:40:a789::2/126": { + "scope": "global", + "family": "IPv6" + }, + "Ethernet16|10.184.230.211/31": { + "scope": "global", + "family": "IPv4" + }, + "Ethernet18|2a04:5555:40:a7c9::2/126": { + "scope": "global", + "family": "IPv6" + }, + "Ethernet18|10.184.231.211/31": { + "scope": "global", + "family": "IPv4" + } + }, + "VLAN_MEMBER": { + "Vlan111|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet1": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet2": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet3": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet5": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet6": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet29": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet30": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet31": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet32": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet33": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet34": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet35": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet36": { + "tagging_mode": "untagged" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0|2a04:5555:40:4::4e9/128": { + "scope": "global", + "family": "IPv6" + }, + "Loopback0|10.184.8.233/32": { + "scope": "global", + "family": "IPv4" + } + }, + "CRM": { + "Config": { + "polling_interval": "0" + } + } +} diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/test_SonicYang.json b/src/sonic-yang-mgmt/tests/libyang-python-tests/test_SonicYang.json new file mode 100644 index 000000000000..f3e0c46f76b2 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/test_SonicYang.json @@ -0,0 +1,144 @@ +{ + "yang_dir":"./tests/libyang-python-tests/sample-yang-models/", + "data_file":"./tests/libyang-python-tests/config_data.json", + "data_merge_file":"./tests/libyang-python-tests/config_data_merge.json", + "modules":[ + {"file":"test-head.yang", "module":"test-head"}, + {"file":"test-port.yang", "module":"test-port"}, + {"file":"test-acl.yang", "module":"test-acl"}, + {"file":"test-interface.yang", "module":"test-interface"}, + {"file":"test-portchannel.yang", "module":"test-portchannel"}, + {"file":"test-vlan.yang", "module":"test-vlan"} + ], + + "merged_nodes":[ + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet10']/speed", "value":"25000"}, + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='200'][ip-prefix='2000:f500:45:6708::/64']/family", + "value":"IPv6"} + ], + + "new_nodes":[ + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet12']/alias", "value":"Ethernet10_alias"}, + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet12']/speed", "value":"5000"}, + {"xpath":"/test-acl:acl/ACL_RULE/ACL_RULE_LIST[ACL_TABLE_NAME='PACL-test'][RULE_NAME='rule_20']/RULE_NAME", + "value":"rule_20"} + ], + + "data_nodes":[ + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/alias", "valid":"True"}, + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet20']/alias", "valid":"False"}, + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE", "valid":"True"}, + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST", "valid":"False"}, + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='2000:f500:45:6709::/64']", "valid":"True"} + ], + + "set_nodes":[ + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet10']/speed", "value":"10000"}, + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/mtu", "value":"1500"}, + {"xpath":"/test-vlan:vlan/VLAN/VLAN_LIST[vlanid='111']/description", "value":"server_vlan111"} + ], + + "node_values":[ + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/speed", "value":"25000"}, + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='2000:f500:45:6709::/64']/family", + "value":"IPv6"} + ], + + "schema_nodes":[ + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']/family", + "value":"/test-vlan:vlan/test-vlan:VLAN_INTERFACE/test-vlan:VLAN_INTERFACE_LIST/test-vlan:family"}, + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/speed", + "value":"/test-port:port/test-port:PORT/test-port:PORT_LIST/test-port:speed"} + ], + + "delete_nodes":[ + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet10']/speed", "valid":"False"}, + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/mtu", "valid":"True"}, + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet20']/mtu", "valid":"False"} + ], + + "dependencies":[ + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet8']/port_name", + "dependencies": + ["/test-acl:acl/ACL_TABLE/ACL_TABLE_LIST[ACL_TABLE_NAME='PACL-V6']/ports[.='Ethernet8']", + "/test-interface:interface/INTERFACE/INTERFACE_LIST[interface='Ethernet8'][ip-prefix='10.1.1.64/26']/interface", + "/test-interface:interface/INTERFACE/INTERFACE_LIST[interface='Ethernet8'][ip-prefix='2000:f500:40:a749::/126']/interface"]} + ], + "schema_dependencies":[ + {"xpath":"/test-port:port/test-port:PORT/test-port:PORT_LIST/test-port:port_name", + "schema_dependencies": + ["/test-acl:acl/test-acl:ACL_TABLE/test-acl:ACL_TABLE_LIST/test-acl:ports", + "/test-portchannel:portchannel/test-portchannel:PORTCHANNEL/test-portchannel:PORTCHANNEL_LIST/test-portchannel:members", + "/test-interface:interface/test-interface:INTERFACE/test-interface:INTERFACE_LIST/test-interface:interface", + "/test-vlan:vlan/test-vlan:VLAN_MEMBER/test-vlan:VLAN_MEMBER_LIST/test-vlan:port"]} + ], + "members":[ + {"xpath":"/test-port:port/PORT/PORT_LIST", + "members": + ["/test-port:port/PORT/PORT_LIST[port_name='Ethernet0']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet1']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet2']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet3']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet4']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet5']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet6']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet7']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet8']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet10']", + "/test-port:port/PORT/PORT_LIST[port_name='Ethernet12']"]} + ], + + "parents":[ + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='2000:f500:45:6709::/64']/family", + "parent":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='2000:f500:45:6709::/64']"}, + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']/scope", + "parent":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']"}, + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']/vlanid", + "parent":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']"}, + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']/ip-prefix", + "parent":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']"}, + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']/family", + "parent":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']"}, + {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/speed", + "parent":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']"} + ], + "prefix":[ + {"module_name":"test-head", "module_prefix":"head"}, + {"module_name":"test-port", "module_prefix":"port"}, + {"module_name":"test-acl", "module_prefix":"acl"}, + {"module_name":"test-interface", "module_prefix":"intf"}, + {"module_name":"test-portchannel", "module_prefix":"lag"}, + {"module_name":"test-vlan", "module_prefix":"vlan"} + ], + "data_type":[ + {"xpath":"/test-port:port/test-port:PORT/test-port:PORT_LIST/test-port:port_name", "data_type":"LY_TYPE_STRING"}, + {"xpath":"/test-vlan:vlan/test-vlan:VLAN_INTERFACE/test-vlan:VLAN_INTERFACE_LIST/test-vlan:vlanid", "data_type":"LY_TYPE_LEAFREF"} + ], + "leafref_type":[ + {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='2000:f500:45:6709::/64']/vlanid", "data_type":"LY_TYPE_UINT16"}, + {"xpath":"/test-interface:interface/INTERFACE/INTERFACE_LIST[interface='Ethernet8'][ip-prefix='2000:f500:40:a749::/126']/interface", "data_type":"LY_TYPE_STRING"}, + {"xpath":"/test-vlan:vlan/VLAN_MEMBER/VLAN_MEMBER_LIST[vlanid='111'][port='Ethernet0']/port", "data_type":"LY_TYPE_STRING"}, + {"xpath":"/test-vlan:vlan/VLAN_MEMBER/VLAN_MEMBER_LIST[vlanid='111'][port='Ethernet0']/vlanid", "data_type":"LY_TYPE_UINT16"} + ], + "leafref_type_schema":[ + {"xpath":"/test-vlan:vlan/test-vlan:VLAN_INTERFACE/test-vlan:VLAN_INTERFACE_LIST/test-vlan:vlanid", + "data_type":"LY_TYPE_UINT16"}, + {"xpath":"/test-interface:interface/test-interface:INTERFACE/test-interface:INTERFACE_LIST/test-interface:interface", + "data_type":"LY_TYPE_STRING"}, + {"xpath":"/test-vlan:vlan/test-vlan:VLAN_MEMBER/test-vlan:VLAN_MEMBER_LIST/test-vlan:port", + "data_type":"LY_TYPE_STRING"}, + {"xpath":"/test-vlan:vlan/test-vlan:VLAN_MEMBER/test-vlan:VLAN_MEMBER_LIST/test-vlan:vlanid", + "data_type":"LY_TYPE_UINT16"} + ], + "leafref_path":[ + {"xpath":"/test-vlan:vlan/test-vlan:VLAN_INTERFACE/test-vlan:VLAN_INTERFACE_LIST/test-vlan:vlanid", + "leafref_path":"../../../VLAN/VLAN_LIST/vlanid"}, + {"xpath":"/test-interface:interface/test-interface:INTERFACE/test-interface:INTERFACE_LIST/test-interface:interface", + "leafref_path":"/test-port:port/test-port:PORT/test-port:PORT_LIST/test-port:port_name"}, + {"xpath":"/test-vlan:vlan/test-vlan:VLAN_MEMBER/test-vlan:VLAN_MEMBER_LIST/test-vlan:port", + "leafref_path":"/test-port:port/test-port:PORT/test-port:PORT_LIST/test-port:port_name"}, + {"xpath":"/test-vlan:vlan/test-vlan:VLAN_MEMBER/test-vlan:VLAN_MEMBER_LIST/test-vlan:vlanid", + "leafref_path":"../../../VLAN/VLAN_LIST/vlanid"} + ] +} diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py b/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py new file mode 100644 index 000000000000..b5fa35842990 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py @@ -0,0 +1,324 @@ +import sys +import os +import pytest +import sonic_yang as sy +import json +import glob +import logging +from ijson import items as ijson_itmes + +test_path = os.path.dirname(os.path.abspath(__file__)) +modules_path = os.path.dirname(test_path) +sys.path.insert(0, modules_path) + +logging.basicConfig(level=logging.DEBUG) +log = logging.getLogger("YANG-TEST") +log.setLevel(logging.INFO) +log.addHandler(logging.NullHandler()) + +class Test_SonicYang(object): + # class vars + + @pytest.fixture(autouse=True, scope='class') + def data(self): + test_file = "./tests/libyang-python-tests/test_SonicYang.json" + data = self.jsonTestParser(test_file) + return data + + @pytest.fixture(autouse=True, scope='class') + def yang_s(self, data): + yang_dir = str(data['yang_dir']) + yang_s = sy.SonicYang(yang_dir) + return yang_s + + def jsonTestParser(self, file): + """ + Open the json test file + """ + with open(file) as data_file: + data = json.load(data_file) + return data + + """ + Get the JSON input based on func name + and return jsonInput + """ + def readIjsonInput(self, yang_test_file, test): + try: + # load test specific Dictionary, using Key = func + # this is to avoid loading very large JSON in memory + print(" Read JSON Section: " + test) + jInput = "" + with open(yang_test_file, 'rb') as f: + jInst = ijson_itmes(f, test) + for it in jInst: + jInput = jInput + json.dumps(it) + except Exception as e: + print("Reading Ijson failed") + raise(e) + return jInput + + def setup_class(self): + pass + + def load_yang_model_file(self, yang_s, yang_dir, yang_file, module_name): + yfile = yang_dir + yang_file + try: + yang_s._load_schema_module(str(yfile)) + except Exception as e: + print(e) + raise + + #test load and get yang module + def test_load_yang_model_files(self, data, yang_s): + yang_dir = data['yang_dir'] + for module in data['modules']: + file = str(module['file']) + module = str(module['module']) + + self.load_yang_model_file(yang_s, yang_dir, file, module) + assert yang_s._get_module(module) is not None + + #test load non-exist yang module file + def test_load_invalid_model_files(self, data, yang_s): + yang_dir = data['yang_dir'] + file = "invalid.yang" + module = "invalid" + + with pytest.raises(Exception): + assert self.load_yang_model_file(yang_s, yang_dir, file, module) + + #test load yang modules in directory + def test_load_yang_model_dir(self, data, yang_s): + yang_dir = data['yang_dir'] + yang_s._load_schema_modules(str(yang_dir)) + + for module_name in data['modules']: + assert yang_s._get_module(str(module_name['module'])) is not None + + #test load yang modules and data files + def test_load_yang_model_data(self, data, yang_s): + yang_dir = str(data['yang_dir']) + yang_files = glob.glob(yang_dir+"/*.yang") + data_file = str(data['data_file']) + data_merge_file = str(data['data_merge_file']) + + data_files = [] + data_files.append(data_file) + data_files.append(data_merge_file) + print(yang_files) + yang_s._load_data_model(yang_dir, yang_files, data_files) + + #validate the data tree from data_merge_file is loaded + for node in data['merged_nodes']: + xpath = str(node['xpath']) + value = str(node['value']) + val = yang_s._find_data_node_value(xpath) + assert str(val) == str(value) + + #test load data file + def test_load_data_file(self, data, yang_s): + data_file = str(data['data_file']) + yang_s._load_data_file(data_file) + + #test_validate_data_tree(): + def test_validate_data_tree(self, data, yang_s): + yang_s.validate_data_tree() + + #test find node + def test_find_node(self, data, yang_s): + for node in data['data_nodes']: + expected = node['valid'] + xpath = str(node['xpath']) + dnode = yang_s._find_data_node(xpath) + + if(expected == "True"): + assert dnode is not None + assert dnode.path() == xpath + else: + assert dnode is None + + #test add node + def test_add_node(self, data, yang_s): + for node in data['new_nodes']: + xpath = str(node['xpath']) + value = node['value'] + yang_s._add_data_node(xpath, str(value)) + + data_node = yang_s._find_data_node(xpath) + assert data_node is not None + + #test find node value + def test_find_data_node_value(self, data, yang_s): + for node in data['node_values']: + xpath = str(node['xpath']) + value = str(node['value']) + print(xpath) + print(value) + val = yang_s._find_data_node_value(xpath) + assert str(val) == str(value) + + #test delete data node + def test_delete_node(self, data, yang_s): + for node in data['delete_nodes']: + xpath = str(node['xpath']) + yang_s._deleteNode(xpath) + + #test set node's value + def test_set_datanode_value(self, data, yang_s): + for node in data['set_nodes']: + xpath = str(node['xpath']) + value = node['value'] + yang_s._set_data_node_value(xpath, value) + + val = yang_s._find_data_node_value(xpath) + assert str(val) == str(value) + + #test list of members + def test_find_members(self, yang_s, data): + for node in data['members']: + members = node['members'] + xpath = str(node['xpath']) + list = yang_s._find_data_nodes(xpath) + assert list.sort() == members.sort() + + #get parent xpath + def test_get_parent_data_xpath(self, yang_s, data): + for node in data['parents']: + xpath = str(node['xpath']) + expected_xpath = str(node['parent']) + path = yang_s._get_parent_data_xpath(xpath) + assert path == expected_xpath + + #test find_data_node_schema_xpath + def test_find_data_node_schema_xpath(self, yang_s, data): + for node in data['schema_nodes']: + xpath = str(node['xpath']) + schema_xpath = str(node['value']) + path = yang_s._find_data_node_schema_xpath(xpath) + assert path == schema_xpath + + #test data dependencies + def test_find_data_dependencies(self, yang_s, data): + for node in data['dependencies']: + xpath = str(node['xpath']) + list = node['dependencies'] + depend = yang_s.find_data_dependencies(xpath) + assert set(depend) == set(list) + + #test data dependencies + def test_find_schema_dependencies(self, yang_s, data): + for node in data['schema_dependencies']: + xpath = str(node['xpath']) + list = node['schema_dependencies'] + depend = yang_s._find_schema_dependencies(xpath) + assert set(depend) == set(list) + + #test merge data tree + def test_merge_data_tree(self, data, yang_s): + data_merge_file = data['data_merge_file'] + yang_dir = str(data['yang_dir']) + yang_s._merge_data(data_merge_file, yang_dir) + #yang_s.root.print_mem(ly.LYD_JSON, ly.LYP_FORMAT) + + #test get module prefix + def test_get_module_prefix(self, yang_s, data): + for node in data['prefix']: + xpath = str(node['module_name']) + expected = node['module_prefix'] + prefix = yang_s._get_module_prefix(xpath) + assert expected == prefix + + #test get data type + def test_get_data_type(self, yang_s, data): + for node in data['data_type']: + xpath = str(node['xpath']) + expected = node['data_type'] + expected_type = yang_s._str_to_type(expected) + data_type = yang_s._get_data_type(xpath) + assert expected_type == data_type + + def test_get_leafref_type(self, yang_s, data): + for node in data['leafref_type']: + xpath = str(node['xpath']) + expected = node['data_type'] + expected_type = yang_s._str_to_type(expected) + data_type = yang_s._get_leafref_type(xpath) + assert expected_type == data_type + + def test_get_leafref_path(self, yang_s, data): + for node in data['leafref_path']: + xpath = str(node['xpath']) + expected_path = node['leafref_path'] + path = yang_s._get_leafref_path(xpath) + assert expected_path == path + + def test_get_leafref_type_schema(self, yang_s, data): + for node in data['leafref_type_schema']: + xpath = str(node['xpath']) + expected = node['data_type'] + expected_type = yang_s._str_to_type(expected) + data_type = yang_s._get_leafref_type_schema(xpath) + assert expected_type == data_type + + """ + This is helper function to load YANG models for tests cases, which works + on Real SONiC Yang models. Mainly tests for translation and reverse + translation. + """ + @pytest.fixture(autouse=True, scope='class') + def sonic_yang_data(self): + sonic_yang_dir = "../sonic-yang-models/yang-models/" + sonic_yang_test_file = "../sonic-yang-models/tests/yang_model_tests/yangTest.json" + + syc = sy.SonicYang(sonic_yang_dir) + syc.loadYangModel() + + sonic_yang_data = dict() + sonic_yang_data['yang_dir'] = sonic_yang_dir + sonic_yang_data['test_file'] = sonic_yang_test_file + sonic_yang_data['syc'] = syc + + return sonic_yang_data + + def test_xlate_rev_xlate(self, sonic_yang_data): + # In this test, xlation and revXlation is tested with latest Sonic + # YANG model. + test_file = sonic_yang_data['test_file'] + syc = sonic_yang_data['syc'] + + jIn = self.readIjsonInput(test_file, 'SAMPLE_CONFIG_DB_JSON') + + syc.loadData(json.loads(jIn)) + + # TODO: Make sure no extra table is loaded + + syc.getData() + + if syc.jIn and syc.jIn == syc.revXlateJson: + print("Xlate and Rev Xlate Passed") + else: + print("Xlate and Rev Xlate failed") + # make it fail + assert False == True + + return + + def test_table_with_no_yang(self, sonic_yang_data): + # in this test, tables with no YANG models must be stored seperately + # by this library. + test_file = sonic_yang_data['test_file'] + syc = sonic_yang_data['syc'] + + jIn = self.readIjsonInput(test_file, 'SAMPLE_CONFIG_DB_JSON_1') + + syc.loadData(json.loads(jIn)) + + ty = syc.tablesWithOutYang + + assert (len(ty) and "UNKNOWN_TABLE" in ty) + + return + + def teardown_class(self): + pass diff --git a/src/sonic-yang-mgmt/tests/test_sonic_yang_mgmt.py b/src/sonic-yang-mgmt/tests/test_sonic_yang_mgmt.py new file mode 100644 index 000000000000..e5364fb172a9 --- /dev/null +++ b/src/sonic-yang-mgmt/tests/test_sonic_yang_mgmt.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""Tests for `sonic_yang_mgmt` package.""" + +import pytest + +@pytest.fixture +def response(): + """Sample pytest fixture. + + See more at: http://doc.pytest.org/en/latest/fixture.html + """ + # import requests + # return requests.get('https://github.com/audreyr/cookiecutter-pypackage') + + +def test_content(response): + """Sample pytest test function with the pytest fixture as an argument.""" + # from bs4 import BeautifulSoup + # assert 'GitHub' in BeautifulSoup(response.content).title.string diff --git a/src/sonic-yang-models/.gitignore b/src/sonic-yang-models/.gitignore new file mode 100644 index 000000000000..c5522334f759 --- /dev/null +++ b/src/sonic-yang-models/.gitignore @@ -0,0 +1,59 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +yang-models/sonic_yang_tree diff --git a/src/sonic-yang-models/AUTHORS.rst b/src/sonic-yang-models/AUTHORS.rst new file mode 100644 index 000000000000..43adb0900334 --- /dev/null +++ b/src/sonic-yang-models/AUTHORS.rst @@ -0,0 +1,14 @@ +======= +Credits +======= + +Development Lead +---------------- + +LNOS-CODERS +MSFT-LINUX-DEV + +Contributors +------------ + +Praveen Chaudhary diff --git a/src/sonic-yang-models/LICENSE b/src/sonic-yang-models/LICENSE new file mode 100644 index 000000000000..cf593b111eab --- /dev/null +++ b/src/sonic-yang-models/LICENSE @@ -0,0 +1,13 @@ +Copyright 2019 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/src/sonic-yang-models/README.rst b/src/sonic-yang-models/README.rst new file mode 100644 index 000000000000..6cb6d091367b --- /dev/null +++ b/src/sonic-yang-models/README.rst @@ -0,0 +1,4 @@ +" +This Package contains YANG models for sonic which are written with guidelines mentioned in +https://github.com/Azure/SONiC/blob/master/doc/mgmt/SONiC_YANG_Model_Guidelines.md. +" diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py new file mode 100644 index 000000000000..6add4c22bffa --- /dev/null +++ b/src/sonic-yang-models/setup.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""The setup script.""" + +from setuptools import setup, find_packages +from setuptools.command.build_py import build_py +from os import system +from sys import exit + +setup_requirements = ['pytest-runner'] + +test_requirements = ['pytest>=3'] + +# read me +with open('README.rst') as readme_file: + readme = readme_file.read() + +# class for prerequisites to build this package +class pkgBuild(build_py): + """Custom Build PLY""" + + def run (self): + # json file for YANG model test cases. + test_yangJson_file = './tests/yang_model_tests/yangTest.json' + # YANG models are in below dir + yang_model_dir = './yang-models/' + # yang model tester python module + yang_test_py = './tests/yang_model_tests/yangModelTesting.py' + # run tests for yang models + test_yang_cmd = "python {} -f {} -y {}".format(yang_test_py, test_yangJson_file, yang_model_dir) + if (system(test_yang_cmd)): + print("YANG Tests failed\n") + exit(1) + else: + print("YANG Tests passed\n") + + # Generate YANG Tree + pyang_tree_cmd = "pyang -f tree ./yang-models/*.yang > ./yang-models/sonic_yang_tree" + if (system(pyang_tree_cmd)): + print("Failed: {}".format(pyang_tree_cmd)) + else: + print("Passed: {}".format(pyang_tree_cmd)) + + # Continue usual build steps + build_py.run(self) + +setup( + cmdclass={ + 'build_py': pkgBuild, + }, + author="lnos-coders", + author_email='lnos-coders@linkedin.com', + python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*', + classifiers=[ + 'Development Status :: 2 - Pre-Alpha', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)', + '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', + ], + description="Package contains YANG models for sonic.", + tests_require = test_requirements, + license="GNU General Public License v3", + long_description=readme + '\n\n', + include_package_data=True, + keywords='sonic_yang_models', + name='sonic_yang_models', + py_modules=[], + packages=find_packages(), + setup_requires=setup_requirements, + version='1.0', + data_files=[ + ('yang-models', ['./yang-models/sonic-types.yang', + './yang-models/sonic-extension.yang', + './yang-models/sonic-acl.yang', + './yang-models/sonic-interface.yang', + './yang-models/sonic-loopback-interface.yang', + './yang-models/sonic-port.yang', + './yang-models/sonic-portchannel.yang', + './yang-models/sonic-vlan.yang', + './yang-models/sonic_yang_tree']), + ], + zip_safe=False, +) diff --git a/src/sonic-yang-models/tests/__init__.py b/src/sonic-yang-models/tests/__init__.py new file mode 100644 index 000000000000..c116c5072b34 --- /dev/null +++ b/src/sonic-yang-models/tests/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +"""Unit test package for sonic_yang_models.""" diff --git a/src/sonic-yang-models/tests/test_sonic_yang_models.py b/src/sonic-yang-models/tests/test_sonic_yang_models.py new file mode 100644 index 000000000000..e8acedf9f974 --- /dev/null +++ b/src/sonic-yang-models/tests/test_sonic_yang_models.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""Tests for `sonic_yang_models` package.""" + +import pytest + +@pytest.fixture +def response(): + """Sample pytest fixture. + + See more at: http://doc.pytest.org/en/latest/fixture.html + """ + # import requests + # return requests.get('https://github.com/audreyr/cookiecutter-pypackage') + + +def test_content(response): + """Sample pytest test function with the pytest fixture as an argument.""" + # from bs4 import BeautifulSoup + # assert 'GitHub' in BeautifulSoup(response.content).title.string diff --git a/src/sonic-yang-models/tests/yang_model_tests/yangModelTesting.py b/src/sonic-yang-models/tests/yang_model_tests/yangModelTesting.py new file mode 100644 index 000000000000..d36416adcae7 --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/yangModelTesting.py @@ -0,0 +1,288 @@ +# This script is used to + +import yang as ly +import logging +import argparse +import sys +import ijson +import json +#import sonic_yang as sy +from glob import glob +from os import listdir +from os.path import isfile, join, splitext + +#Globals vars +PASS = 0 +FAIL = 1 +logging.basicConfig(level=logging.DEBUG) +log = logging.getLogger("YANG-TEST") +log.setLevel(logging.INFO) +log.addHandler(logging.NullHandler()) + +# Global functions +def printExceptionDetails(): + try: + excType, excObj, traceBack = sys.exc_info() + fileName = traceBack.tb_frame.f_code.co_filename + lineNumber = traceBack.tb_lineno + log.error(" Exception >{}< in {}:{}".format(excObj, fileName, lineNumber)) + except Exception as e: + log.error(" Exception in printExceptionDetails") + return + +# class for YANG Model YangModelTesting +# Run function will run all the tests +# from a user given list. + +class YangModelTesting: + + def __init__(self, tests, yangDir, jsonFile): + self.defaultYANGFailure = { + 'Must': ['Must condition', 'not satisfied'], + 'InvalidValue': ['Invalid value'], + 'LeafRef': ['Leafref', 'non-existing'], + 'When': ['When condition', 'not satisfied'], + 'Pattern': ['pattern', 'does not satisfy'], + 'None': [''] + } + + self.ExceptionTests = { + 'WRONG_FAMILY_WITH_IP_PREFIX': { + 'desc': 'Configure Wrong family with ip-prefix for VLAN_Interface Table', + 'eStr': self.defaultYANGFailure['Must'] + }, + 'DHCP_SERVER_INCORRECT_FORMAT': { + 'desc': 'Add dhcp_server which is not in correct ip-prefix format.', + 'eStr': self.defaultYANGFailure['InvalidValue'] + ['dhcp_servers'] + }, + 'VLAN_WITH_NON_EXIST_PORT': { + 'desc': 'Configure a member port in VLAN_MEMBER table which does not exist.', + 'eStr': self.defaultYANGFailure['LeafRef'] + }, + 'VLAN_MEMEBER_WITH_NON_EXIST_VLAN': { + 'desc': 'Configure vlan-id in VLAN_MEMBER table which does not exist in VLAN table.', + 'eStr': self.defaultYANGFailure['LeafRef'] + }, + 'TAGGING_MODE_WRONG_VALUE': { + 'desc': 'Configure wrong value for tagging_mode.', + 'eStr': self.defaultYANGFailure['InvalidValue'] + ['tagging_mode'] + }, + 'INTERFACE_IP_PREFIX_EMPTY_STRING': { + 'desc': 'Configure empty string as ip-prefix in INTERFACE table.', + 'eStr': self.defaultYANGFailure['InvalidValue'] + ['ip-prefix'] + }, + 'ACL_RULE_UNDEFINED_PACKET_ACTION': { + 'desc': 'Configure undefined packet_action in ACL_RULE table.', + 'eStr': self.defaultYANGFailure['InvalidValue'] + ['PACKET_ACTION'] + }, + 'ACL_TABLE_UNDEFINED_TABLE_TYPE': { + 'desc': 'Configure undefined acl_table_type in ACL_TABLE table.', + 'eStr': self.defaultYANGFailure['InvalidValue'] + ['type'] + }, + 'ACL_RULE_WITH_NON_EXIST_ACL_TABLE': { + 'desc': 'Configure non-existing ACL_TABLE in ACL_RULE.', + 'eStr': self.defaultYANGFailure['LeafRef'] + }, + 'ACL_RULE_IP_TYPE_SRC_IPV6_MISMATCH': { + 'desc': 'Configure IP_TYPE as ipv4any and SRC_IPV6 in ACL_RULE.', + 'eStr': self.defaultYANGFailure['When'] + ['IP_TYPE'] + }, + 'ACL_RULE_ARP_TYPE_DST_IPV6_MISMATCH': { + 'desc': 'Configure IP_TYPE as ARP and DST_IPV6 in ACL_RULE.', + 'eStr': self.defaultYANGFailure['When'] + ['IP_TYPE'] + }, + 'ACL_RULE_WRONG_L4_SRC_PORT_RANGE': { + 'desc': 'Configure l4_src_port_range as 99999-99999 in ACL_RULE', + 'eStr': self.defaultYANGFailure['Pattern'] + }, + 'ACL_RULE_ARP_TYPE_ICMPV6_CODE_MISMATCH': { + 'desc': 'Configure IP_TYPE as ARP and ICMPV6_CODE in ACL_RULE.', + 'eStr': self.defaultYANGFailure['When'] + ['IP_TYPE'] + }, + 'ACL_RULE_WRONG_INNER_ETHER_TYPE': { + 'desc': 'Configure INNER_ETHER_TYPE as 0x080C in ACL_RULE.', + 'eStr': self.defaultYANGFailure['Pattern'] + }, + 'INTERFACE_IPPREFIX_PORT_MUST_CONDITION_FALSE': { + 'desc': 'Interface Ip-prefix port-name must condition failure.', + 'eStr': self.defaultYANGFailure['Must'] + }, + 'INTERFACE_IPPREFIX_PORT_MUST_CONDITION_TRUE': { + 'desc': 'Interface Ip-prefix port-name must condition pass.', + 'eStr': self.defaultYANGFailure['None'] + }, + 'VLAN_INTERFACE_IPPREFIX_MUST_CONDITION_FALSE': { + 'desc': 'Vlan Interface Ip-prefix must condition failure.', + 'eStr': self.defaultYANGFailure['Must'] + }, + 'LOOPBACK_IPPREFIX_PORT_MUST_CONDITION_FALSE': { + 'desc': 'Loopback Ip-prefix port-name must condition failure.', + 'eStr': self.defaultYANGFailure['Must'] + } + } + + self.tests = tests + if (self.tests == None): + self.tests = self.ExceptionTests.keys() + self.yangDir = yangDir + self.jsonFile = jsonFile + self.testNum = 1 + # other class vars + # self.ctx + return + + """ + load all YANG models before test run + """ + def loadYangModel(self, yangDir): + + try: + # create context + self.ctx = ly.Context(yangDir) + # get all files + yangFiles = glob(yangDir +"/*.yang") + # load yang modules + for file in yangFiles: + log.debug(file) + m = self.ctx.parse_module_path(file, ly.LYS_IN_YANG) + if m is not None: + log.info("module: {} is loaded successfully".format(m.name())) + else: + log.info("Could not load module: {}".format(file)) + + except Exception as e: + printExceptionDetails() + raise e + return + + """ + Run all tests from list self.tests + """ + def run(self): + try: + self.loadYangModel(self.yangDir) + ret = 0 + for test in self.tests: + test = test.strip() + if test in self.ExceptionTests: + ret = ret + self.runExceptionTest(test); + except Exception as e: + printExceptionDetails() + raise e + return ret + + """ + Get the JSON input based on func name + and return jsonInput + """ + def readJsonInput(self, test): + try: + # load test specific Dictionary, using Key = func + # this is to avoid loading very large JSON in memory + log.debug(" Read JSON Section: " + test) + jInput = "" + with open(self.jsonFile, 'rb') as f: + jInst = ijson.items(f, test) + for it in jInst: + jInput = jInput + json.dumps(it) + log.debug(jInput) + except Exception as e: + printExceptionDetails() + return jInput + + """ + Log the start of a test + """ + def logStartTest(self, desc): + log.info("\n------------------- Test "+ str(self.testNum) +\ + ": " + desc + "---------------------") + self.testNum = self.testNum + 1 + return + + """ + Load Config Data and return Exception as String + """ + def loadConfigData(self, jInput): + s = "" + try: + node = self.ctx.parse_data_mem(jInput, ly.LYD_JSON, \ + ly.LYD_OPT_CONFIG | ly.LYD_OPT_STRICT) + except Exception as e: + s = str(e) + log.debug(s) + return s + + """ + Run Exception Test + """ + def runExceptionTest(self, test): + try: + desc = self.ExceptionTests[test]['desc'] + self.logStartTest(desc) + jInput = self.readJsonInput(test) + # load the data, expect a exception with must condition failure + s = self.loadConfigData(jInput) + eStr = self.ExceptionTests[test]['eStr'] + log.debug(eStr) + if (sum(1 for str in eStr if str not in s) == 0): + log.info(desc + " Passed\n") + return PASS + except Exception as e: + printExceptionDetails() + log.info(desc + " Failed\n") + return FAIL + +# End of Class + +""" + Start Here +""" +def main(): + parser = argparse.ArgumentParser(description='Script to run YANG model tests', + formatter_class=argparse.RawTextHelpFormatter, + epilog=""" +Usage: +python yangModelTesting.py -h +""") + parser.add_argument('-t', '--tests', type=str, \ + help='tests to run separated by comma') + parser.add_argument('-f', '--json-file', type=str, \ + help='JSON input for tests ', required=True) + parser.add_argument('-y', '--yang-dir', type=str, \ + help='Path to YANG models', required=True) + parser.add_argument('-v', '--verbose-level', \ + help='Verbose mode', action='store_true') + parser.add_argument('-l', '--list-tests', \ + help='list all tests', action='store_true') + + args = parser.parse_args() + try: + tests = args.tests + jsonFile = args.json_file + yangDir = args.yang_dir + logLevel = args.verbose_level + listTests = args.list_tests + if logLevel: + log.setLevel(logging.DEBUG) + # Make a list + if (tests): + tests = tests.split(",") + + yTest = YangModelTesting(tests, yangDir, jsonFile) + if (listTests): + for key in yTest.ExceptionTests.keys(): + log.info(key) + sys.exit(0) + + ret = yTest.run() + if ret == 0: + log.info("All Test Passed") + sys.exit(ret) + + except Exception as e: + printExceptionDetails() + sys.exit(1) + + return +if __name__ == '__main__': + main() diff --git a/src/sonic-yang-models/tests/yang_model_tests/yangTest.json b/src/sonic-yang-models/tests/yang_model_tests/yangTest.json new file mode 100644 index 000000000000..2f85d0259bfa --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/yangTest.json @@ -0,0 +1,1350 @@ +{ + "WRONG_FAMILY_WITH_IP_PREFIX": { + "sonic-vlan:sonic-vlan": { + "sonic-vlan:VLAN_INTERFACE": { + "VLAN_INTERFACE_LIST": [{ + "vlan_name": "Vlan100" + }], + "VLAN_INTERFACE_IPPREFIX_LIST": [{ + "vlan_name": "Vlan100", + "ip-prefix": "2a04:5555:66:7777::1/64", + "scope": "global", + "family": "IPv4" + }] + }, + "sonic-vlan:VLAN": { + "VLAN_LIST": [{ + "vlan_name": "Vlan100", + "description": "server_vlan" + }] + } + } + }, + + "DHCP_SERVER_INCORRECT_FORMAT": { + "sonic-vlan:sonic-vlan": { + "sonic-vlan:VLAN": { + "VLAN_LIST": [{ + "vlan_name": "Vlan100", + "description": "server_vlan", + "dhcp_servers": [ + "10.186.72.566" + ], + "mtu": "9216", + "admin_status": "up" + }] + } + } + }, + + "VLAN_WITH_NON_EXIST_PORT": { + "sonic-vlan:sonic-vlan": { + "sonic-vlan:VLAN_MEMBER": { + "VLAN_MEMBER_LIST": [{ + "vlan_name": "Vlan100", + "port": "Ethernet156", + "tagging_mode": "tagged" + }] + }, + "sonic-vlan:VLAN": { + "VLAN_LIST": [{ + "vlan_name": "Vlan100", + "description": "server_vlan" + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + } + }, + + "VLAN_MEMEBER_WITH_NON_EXIST_VLAN": { + "sonic-vlan:sonic-vlan": { + "sonic-vlan:VLAN_MEMBER": { + "VLAN_MEMBER_LIST": [{ + "vlan_name": "Vlan200", + "port": "Ethernet0", + "tagging_mode": "tagged" + }] + }, + "sonic-vlan:VLAN": { + "VLAN_LIST": [{ + "vlan_name": "Vlan100", + "description": "server_vlan" + }, + { + "vlan_name": "Vlan300", + "description": "ipmi_vlan" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }] + } + } + }, + + "TAGGING_MODE_WRONG_VALUE": { + "sonic-vlan:sonic-vlan": { + "sonic-vlan:VLAN_MEMBER": { + "VLAN_MEMBER_LIST": [{ + "vlan_name": 100, + "port": "Ethernet0", + "tagging_mode": "non-tagged" + }] + }, + "sonic-vlan:VLAN": { + "VLAN_LIST": [{ + "vlan_name": "Vlan100", + "description": "server_vlan" + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }] + } + } + }, + + "INTERFACE_IP_PREFIX_EMPTY_STRING": { + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_LIST": [{ + "port_name": "Ethernet8" + }], + "INTERFACE_IPPREFIX_LIST": [{ + "port_name": "Ethernet8", + "ip-prefix": "", + "scope": "global", + "family": "IPv4" + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet8", + "alias": "eth8", + "description": "Ethernet8", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }] + } + } + }, + + "ACL_RULE_UNDEFINED_PACKET_ACTION": { + "sonic-acl:sonic-acl": { + "sonic-acl:ACL_RULE": { + "ACL_RULE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V4", + "RULE_NAME": "Rule_20", + "PACKET_ACTION": "SEND", + "DST_IP": "10.186.72.0/26", + "SRC_IP": "10.176.0.0/15", + "PRIORITY": 999980, + "IP_TYPE": "IPV4ANY" + }] + }, + "sonic-acl:ACL_TABLE": { + "ACL_TABLE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V4", + "policy_desc": "Filter IPv4", + "type": "L3", + "stage": "EGRESS", + "ports": ["Ethernet0", "Ethernet1"] + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + } + }, + + "ACL_TABLE_UNDEFINED_TABLE_TYPE": { + "sonic-acl:sonic-acl": { + "sonic-acl:ACL_TABLE": { + "ACL_TABLE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V6", + "policy_desc": "Filter IPv6", + "type": "LAYER3V4", + "stage": "EGRESS", + "ports": ["Ethernet0", "Ethernet1"] + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + } + }, + + "ACL_RULE_WITH_NON_EXIST_ACL_TABLE": { + "sonic-acl:sonic-acl": { + "sonic-acl:ACL_RULE": { + "ACL_RULE_LIST": [{ + "ACL_TABLE_NAME": "NOT-EXIST", + "RULE_NAME": "Rule_20", + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.186.72.0/26", + "SRC_IP": "10.176.0.0/15", + "PRIORITY": 999980, + "IP_TYPE": "IPv4ANY" + }] + }, + "sonic-acl:ACL_TABLE": { + "ACL_TABLE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V4", + "policy_desc": "Filter IPv6", + "type": "L3", + "stage": "EGRESS", + "ports": ["Ethernet0", "Ethernet1"] + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + } + }, + + "ACL_RULE_IP_TYPE_SRC_IPV6_MISMATCH": { + "sonic-acl:sonic-acl": { + "sonic-acl:ACL_RULE": { + "ACL_RULE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V4", + "RULE_NAME": "Rule_20", + "PACKET_ACTION": "FORWARD", + "SRC_IPV6": "2001::1/64", + "PRIORITY": 999980, + "IP_TYPE": "IPv4ANY" + }] + }, + "sonic-acl:ACL_TABLE": { + "ACL_TABLE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V4", + "policy_desc": "Filter IPv4", + "type": "L3", + "stage": "EGRESS", + "ports": ["Ethernet0", "Ethernet1"] + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + } + }, + + "ACL_RULE_ARP_TYPE_DST_IPV6_MISMATCH": { + "sonic-acl:sonic-acl": { + "sonic-acl:ACL_RULE": { + "ACL_RULE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V6", + "RULE_NAME": "Rule_20", + "PACKET_ACTION": "FORWARD", + "DST_IPV6": "2001::2/64", + "PRIORITY": 999980, + "IP_TYPE": "ARP" + }] + }, + "sonic-acl:ACL_TABLE": { + "ACL_TABLE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V6", + "policy_desc": "Filter IPv6", + "type": "L3V6", + "stage": "EGRESS", + "ports": ["Ethernet0", "Ethernet1"] + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + } + }, + + "ACL_RULE_WRONG_L4_SRC_PORT_RANGE": { + "sonic-acl:sonic-acl": { + "sonic-acl:ACL_RULE": { + "ACL_RULE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V6", + "RULE_NAME": "Rule_20", + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IP", + "SRC_IPV6": "2a04:f547:41::/48", + "PRIORITY": 999980, + "DST_IPV6": "2a04:f547:43:320::/64", + "L4_SRC_PORT_RANGE": "99999-99999" + }] + }, + "sonic-acl:ACL_TABLE": { + "ACL_TABLE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V6", + "policy_desc": "Filter IPv6", + "type": "L3V6", + "stage": "EGRESS", + "ports": ["Ethernet0", "Ethernet1"] + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + } + }, + + "VLAN_INTERFACE_IPPREFIX_MUST_CONDITION_FALSE": { + "sonic-vlan:sonic-vlan": { + "sonic-vlan:VLAN_INTERFACE": { + "VLAN_INTERFACE_IPPREFIX_LIST": [{ + "vlan_name": "Vlan100", + "ip-prefix": "2a04:5555:66:7777::1/64", + "scope": "global", + "family": "IPv6" + }] + }, + "sonic-vlan:VLAN": { + "VLAN_LIST": [{ + "vlan_name": "Vlan100", + "description": "server_vlan" + }] + } + } + }, + + "LOOPBACK_IPPREFIX_PORT_MUST_CONDITION_FALSE": { + "sonic-loopback-interface:sonic-loopback-interface": { + "sonic-loopback-interface:LOOPBACK_INTERFACE": { + "LOOPBACK_INTERFACE_IPPREFIX_LIST": [{ + "loopback_interface_name": "lo1", + "ip-prefix": "2a04:5555:66:7777::1/64", + "scope": "global", + "family": "IPv6" + }] + } + } + }, + + "INTERFACE_IPPREFIX_PORT_MUST_CONDITION_FALSE": { + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_LIST": [{ + "port_name": "Ethernet9" + }], + "INTERFACE_IPPREFIX_LIST": [{ + "port_name": "Ethernet8", + "ip-prefix": "10.0.0.1/30", + "scope": "global", + "family": "IPv4" + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet8", + "alias": "eth8", + "description": "Ethernet8", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet9", + "alias": "eth9", + "description": "Ethernet9", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }] + } + } + }, + + "INTERFACE_IPPREFIX_PORT_MUST_CONDITION_TRUE": { + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_LIST": [{ + "port_name": "Ethernet8" + }], + "INTERFACE_IPPREFIX_LIST": [{ + "port_name": "Ethernet8", + "ip-prefix": "10.0.0.1/30", + "scope": "global", + "family": "IPv4" + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet8", + "alias": "eth8", + "description": "Ethernet8", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }] + } + } + }, + + "ACL_RULE_ARP_TYPE_ICMPV6_CODE_MISMATCH": { + "sonic-acl:sonic-acl": { + "sonic-acl:ACL_RULE": { + "ACL_RULE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V4", + "RULE_NAME": "Rule_40", + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.186.72.64/26", + "SRC_IP": "10.176.0.0/15", + "PRIORITY": 999960, + "ICMPV6_CODE": 5, + "IP_TYPE": "ARP", + "INNER_ETHER_TYPE": "0x88CC" + }] + }, + "sonic-acl:ACL_TABLE": { + "ACL_TABLE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V4", + "policy_desc": "Filter IPv4", + "type": "L3", + "stage": "EGRESS", + "ports": ["Ethernet0", "Ethernet1"] + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + } + }, + + "ACL_RULE_WRONG_INNER_ETHER_TYPE": { + "sonic-acl:sonic-acl": { + "sonic-acl:ACL_RULE": { + "ACL_RULE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V4", + "RULE_NAME": "Rule_40", + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.186.72.64/26", + "SRC_IP": "10.176.0.0/15", + "PRIORITY": 999960, + "IP_TYPE": "ARP", + "INNER_ETHER_TYPE": "0x080C" + + }] + }, + "sonic-acl:ACL_TABLE": { + "ACL_TABLE_LIST": [{ + "ACL_TABLE_NAME": "NO-NSW-PACL-V4", + "policy_desc": "Filter IPv4", + "type": "L3", + "stage": "EGRESS", + "ports": ["Ethernet0", "Ethernet1"] + }] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [{ + "port_name": "Ethernet0", + "alias": "eth0", + "description": "Ethernet0", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + }, + { + "port_name": "Ethernet1", + "alias": "eth1", + "description": "Ethernet1", + "speed": 25000, + "mtu": 9000, + "admin_status": "up" + } + ] + } + } + }, + + "SAMPLE_CONFIG_DB_JSON": { + "VLAN_INTERFACE": { + "Vlan111": {}, + "Vlan777": {}, + "Vlan111|2a04:5555:45:6709::1/64": { + "scope": "global", + "family": "IPv6" + }, + "Vlan111|10.222.10.65/26": { + "scope": "global", + "family": "IPv4" + }, + "Vlan111|fe80::1/10": { + "scope": "local", + "family": "IPv6" + }, + "Vlan777|2a04:5555:41:4e9::1/64": { + "scope": "global", + "family": "IPv6" + }, + "Vlan777|10.111.58.65/26": { + "scope": "global", + "family": "IPv4" + }, + "Vlan777|fe80::1/10": { + "scope": "local", + "family": "IPv6" + } + }, + "ACL_RULE": { + "V4-ACL-TABLE|DEFAULT_DENY": { + "PACKET_ACTION": "DROP", + "IP_TYPE": "IPv4ANY", + "PRIORITY": "0" + }, + "V4-ACL-TABLE|Rule_20": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.222.72.0/26", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777780", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_40": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.222.72.64/26", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777760", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_60": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.222.80.0/26", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777740", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_80": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.222.80.64/26", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777720", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_111": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.152.17.52/32", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777700", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_120": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.252.208.41/32", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777880", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_140": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.148.128.245/32", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777860", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_160": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.222.1.245/32", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777840", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_180": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.252.222.21/32", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "777820", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_9000": { + "PACKET_ACTION": "DROP", + "DST_IP": "0.0.0.0/0", + "SRC_IP": "10.222.0.0/15", + "PRIORITY": "991110", + "IP_TYPE": "IPv4ANY" + }, + "V4-ACL-TABLE|Rule_11100": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "0.0.0.0/0", + "SRC_IP": "0.0.0.0/0", + "PRIORITY": "990000", + "IP_TYPE": "IPv4ANY" + }, + "V6-ACL-TBLE|DEFAULT_DENY": { + "PACKET_ACTION": "DROP", + "IP_TYPE": "IPv6ANY", + "PRIORITY": "0" + }, + "V6-ACL-TBLE|Rule_20": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "777780", + "DST_IPV6": "2a04:5555:43:320::/64" + }, + "V6-ACL-TBLE|Rule_40": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "777760", + "DST_IPV6": "2a04:5555:43:321::/64" + }, + "V6-ACL-TBLE|Rule_60": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "777740", + "DST_IPV6": "2a04:5555:43:340::/64" + }, + "V6-ACL-TBLE|Rule_80": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "777720", + "DST_IPV6": "2a04:5555:43:341::/64" + }, + "V6-ACL-TBLE|Rule_111": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "777700", + "DST_IPV6": "2a04:5555:32:12::/64" + }, + "V6-ACL-TBLE|Rule_9000": { + "PACKET_ACTION": "DROP", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "2a04:5555:41::/48", + "PRIORITY": "991110", + "DST_IPV6": "::/0" + }, + "V6-ACL-TBLE|Rule_11100": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "SRC_IPV6": "::/0", + "PRIORITY": "990000", + "DST_IPV6": "::/0" + } + }, + "DEVICE_METADATA": { + "localhost": { + "type": "ToR", + "mac": "00:11:22:33:dd:5a", + "hostname": "asw.dc", + "bgp_asn": "64850", + "hwsku": "Stone" + } + }, + "VLAN": { + "Vlan111": { + "description": "svlan", + "dhcp_servers": [ + "10.222.72.116" + ], + "vlanid": "111", + "mtu": "9216", + "admin_status": "up", + "members": [ + "Ethernet8", + "Ethernet3", + "Ethernet0", + "Ethernet1", + "Ethernet6", + "Ethernet4", + "Ethernet5", + "Ethernet9", + "Ethernet2", + "Ethernet7", + "Ethernet32", + "Ethernet30", + "Ethernet31", + "Ethernet36", + "Ethernet34", + "Ethernet33", + "Ethernet35", + "Ethernet29", + "Ethernet21", + "Ethernet20", + "Ethernet23", + "Ethernet22", + "Ethernet27", + "Ethernet26", + "Ethernet18", + "Ethernet19", + "Ethernet14", + "Ethernet15", + "Ethernet16", + "Ethernet17", + "Ethernet10", + "Ethernet11", + "Ethernet12", + "Ethernet13", + "Ethernet28" + ] + }, + "Vlan777": { + "description": "pvlan", + "dhcp_servers": [ + "10.222.72.116" + ], + "vlanid": "777", + "mtu": "9216", + "admin_status": "up", + "members": [ + "Ethernet9", + "Ethernet2", + "Ethernet8", + "Ethernet27", + "Ethernet14", + "Ethernet35" + ] + } + }, + "DEVICE_NEIGHBOR": { + "Ethernet112": { + "name": "dccsw01.nw", + "port": "Eth18" + }, + "Ethernet114": { + "name": "dccsw02.nw", + "port": "Eth18" + }, + "Ethernet116": { + "name": "dccsw03.nw", + "port": "Eth18" + }, + "Ethernet118": { + "name": "dccsw04.nw", + "port": "Eth18" + } + }, + "PORT": { + "Ethernet0": { + "alias": "Eth1/1", + "lanes": "65", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet1": { + "alias": "Eth1/2", + "lanes": "66", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet2": { + "alias": "Eth1/3", + "lanes": "67", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet3": { + "alias": "Eth1/4", + "lanes": "68", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet4": { + "alias": "Eth2/1", + "lanes": "69", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet5": { + "alias": "Eth2/2", + "lanes": "70", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet6": { + "alias": "Eth2/3", + "lanes": "71", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet7": { + "alias": "Eth2/4", + "lanes": "72", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet8": { + "alias": "Eth3/1", + "lanes": "73", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet9": { + "alias": "Eth3/2", + "lanes": "74", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet10": { + "alias": "Eth3/3", + "lanes": "75", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet11": { + "alias": "Eth3/4", + "lanes": "76", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet12": { + "alias": "Eth4/1", + "lanes": "77", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet13": { + "alias": "Eth4/2", + "lanes": "78", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet14": { + "alias": "Eth4/3", + "lanes": "79", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet15": { + "alias": "Eth4/4", + "lanes": "80", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet16": { + "alias": "Eth5/1", + "lanes": "33", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet17": { + "alias": "Eth5/2", + "lanes": "34", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet18": { + "alias": "Eth5/3", + "lanes": "35", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet19": { + "alias": "Eth5/4", + "lanes": "36", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet20": { + "alias": "Eth6/1", + "lanes": "37", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet21": { + "alias": "Eth6/2", + "lanes": "38", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet22": { + "alias": "Eth6/3", + "lanes": "39", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet23": { + "alias": "Eth6/4", + "lanes": "40", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet24": { + "alias": "Eth7/1", + "lanes": "41", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet25": { + "alias": "Eth7/2", + "lanes": "42", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet26": { + "alias": "Eth7/3", + "lanes": "43", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet27": { + "alias": "Eth7/4", + "lanes": "44", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet28": { + "alias": "Eth8/1", + "lanes": "45", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet29": { + "alias": "Eth8/2", + "lanes": "46", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet30": { + "alias": "Eth8/3", + "lanes": "47", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet31": { + "alias": "Eth8/4", + "lanes": "48", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet32": { + "alias": "Eth9/1", + "lanes": "49", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet33": { + "alias": "Eth9/2", + "lanes": "50", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet34": { + "alias": "Eth9/3", + "lanes": "51", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet35": { + "alias": "Eth9/4", + "lanes": "52", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet36": { + "alias": "Eth10/1", + "lanes": "53", + "description": "", + "speed": "11100", + "admin_status": "up" + }, + "Ethernet112": { + "alias": "Eth29/1", + "lanes": "113,114", + "description": "50G|dccsw01.nw|Eth18", + "fec": "fc", + "speed": "11100", + "admin_status": "up" + } + }, + "ACL_TABLE": { + "V4-ACL-TABLE": { + "type": "L3", + "policy_desc": "V4-ACL-TABLE", + "ports": [ + "Ethernet26", + "Ethernet27", + "Ethernet24" + ] + }, + "V6-ACL-TBLE": { + "type": "L3V6", + "policy_desc": "V6-ACL-TBLE", + "ports": [ + "Ethernet14", + "Ethernet15", + "Ethernet23", + "Ethernet30", + "Ethernet31", + "Ethernet18", + "Ethernet19", + "Ethernet25", + "Ethernet24" + ] + } + }, + "INTERFACE": { + "Ethernet112": {}, + "Ethernet14": {}, + "Ethernet16": {}, + "Ethernet18": {}, + "Ethernet112|2a04:5555:40:a709::2/126": { + "scope": "global", + "family": "IPv6" + }, + "Ethernet112|10.184.228.211/31": { + "scope": "global", + "family": "IPv4" + }, + "Ethernet14|2a04:5555:40:a749::2/126": { + "scope": "global", + "family": "IPv6" + }, + "Ethernet14|10.184.229.211/31": { + "scope": "global", + "family": "IPv4" + }, + "Ethernet16|2a04:5555:40:a789::2/126": { + "scope": "global", + "family": "IPv6" + }, + "Ethernet16|10.184.230.211/31": { + "scope": "global", + "family": "IPv4" + }, + "Ethernet18|2a04:5555:40:a7c9::2/126": { + "scope": "global", + "family": "IPv6" + }, + "Ethernet18|10.184.231.211/31": { + "scope": "global", + "family": "IPv4" + } + }, + "VLAN_MEMBER": { + "Vlan111|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet1": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet2": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet3": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet5": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet6": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet29": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet30": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet31": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet32": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet33": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet34": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet35": { + "tagging_mode": "untagged" + }, + "Vlan111|Ethernet36": { + "tagging_mode": "untagged" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0": {}, + "Loopback0|2a04:5555:40:4::4e9/128": { + "scope": "global", + "family": "IPv6" + }, + "Loopback0|10.184.8.233/32": { + "scope": "global", + "family": "IPv4" + } + }, + "BREAKOUT_CFG": { + "Ethernet0": { + "brkout_mode": "1x100G[40G]" + }, + "Ethernet4": { + "brkout_mode": "4x25G" + }, + "Ethernet8": { + "brkout_mode": "1x100G[40G]" + } + }, + "VERSIONS": { + "DATABASE": { + "VERSION": "version_1_0_3" + } + }, + "FLEX_COUNTER_TABLE": { + "PFCWD": { + "FLEX_COUNTER_STATUS": "enable" + }, + "PG_WATERMARK": { + "FLEX_COUNTER_STATUS": "enable" + }, + "PORT": { + "FLEX_COUNTER_STATUS": "enable" + }, + "QUEUE": { + "FLEX_COUNTER_STATUS": "enable" + }, + "QUEUE_WATERMARK": { + "FLEX_COUNTER_STATUS": "enable" + } + }, + "CRM": { + "Config": { + "acl_counter_high_threshold": "85", + "acl_counter_low_threshold": "70", + "acl_counter_threshold_type": "percentage", + "polling_interval": "0" + } + } + }, + "SAMPLE_CONFIG_DB_JSON_1": { + "FLEX_COUNTER_TABLE": { + "PFCWD": { + "FLEX_COUNTER_STATUS": "enable" + }, + "PG_WATERMARK": { + "FLEX_COUNTER_STATUS": "enable" + }, + "PORT": { + "FLEX_COUNTER_STATUS": "enable" + }, + "QUEUE": { + "FLEX_COUNTER_STATUS": "enable" + }, + "QUEUE_WATERMARK": { + "FLEX_COUNTER_STATUS": "enable" + } + }, + "CRM": { + "Config": { + "acl_counter_high_threshold": "85", + "acl_counter_low_threshold": "70", + "acl_counter_threshold_type": "percentage", + "polling_interval": "0" + } + }, + "UNKNOWN_TABLE": { + "Error": "This Table is for testing, This Table does not have YANG models." + } + } +} diff --git a/src/sonic-yang-models/yang-models/sonic-acl.yang b/src/sonic-yang-models/yang-models/sonic-acl.yang new file mode 100644 index 000000000000..ec8a485b4829 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-acl.yang @@ -0,0 +1,283 @@ +module sonic-acl { + + yang-version 1.1; + + namespace "http://github.com/Azure/sonic-acl"; + prefix acl; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import sonic-types { + prefix stypes; + revision-date 2019-07-01; + } + + import sonic-extension { + prefix ext; + revision-date 2019-07-01; + } + + import sonic-port { + prefix port; + revision-date 2019-07-01; + } + + import sonic-portchannel { + prefix lag; + revision-date 2019-07-01; + } + + description "ACL YANG Module for SONiC OS"; + + revision 2019-07-01 { + description "First Revision"; + } + + container sonic-acl { + + container ACL_RULE { + + description "ACL_RULE part of config_db.json"; + + list ACL_RULE_LIST { + + key "ACL_TABLE_NAME RULE_NAME"; + + ext:key-regex-configdb-to-yang "^([a-zA-Z0-9_-]+)|([a-zA-Z0-9_-]+)$"; + + ext:key-regex-yang-to-configdb "|"; + + leaf ACL_TABLE_NAME { + type leafref { + path "/acl:sonic-acl/acl:ACL_TABLE/acl:ACL_TABLE_LIST/acl:ACL_TABLE_NAME"; + } + } + + leaf RULE_NAME { + type string { + length 1..255; + } + } + + leaf PACKET_ACTION { + type stypes:packet_action; + } + + leaf IP_TYPE { + type stypes:ip_type; + } + + leaf PRIORITY { + type uint32 { + range 0..999999; + } + } + + choice ip_prefix { + + case ip4_prefix { + when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV4' or .='IPv4ANY' or .='ARP'])"; + leaf SRC_IP { + type inet:ipv4-prefix; + } + + leaf DST_IP { + type inet:ipv4-prefix; + } + } + + case ip6_prefix { + when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV6' or .='IPv6ANY'])"; + leaf SRC_IPV6 { + type inet:ipv6-prefix; + } + + leaf DST_IPV6 { + type inet:ipv6-prefix; + } + } + } + + leaf-list IN_PORTS { + /* Values in leaf list are UNIQUE */ + type uint16; + } + + leaf-list OUT_PORTS { + /* Values in leaf list are UNIQUE */ + type uint16; + } + + choice src_port { + case l4_src_port { + leaf L4_SRC_PORT { + type uint16; + } + } + + case l4_src_port_range { + leaf L4_SRC_PORT_RANGE { + type string { + pattern '([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])-([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])'; + } + } + } + } + + choice dst_port { + case l4_dst_port { + leaf L4_DST_PORT { + type uint16; + } + } + + case l4_dst_port_range { + leaf L4_DST_PORT_RANGE { + type string { + pattern '([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])-([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])'; + } + } + } + } + + leaf ETHER_TYPE { + type string { + pattern "(0x88CC|0x8100|0x8915|0x0806|0x0800|0x86DD|0x8847)"; + } + } + + leaf IP_PROTOCOL { + type uint8 { + range 1..143; + } + } + + leaf TCP_FLAGS { + type string { + pattern '0[x][0-9a-fA-F]{1,2}|0[X][0-9a-fA-F]{1,2}'; + } + } + + leaf DSCP { + type uint8; + } + + leaf TC { + type uint8; + } + + choice icmp { + + case icmp4 { + when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV4' or .='IPv4ANY' or .='ARP'])"; + leaf ICMP_TYPE { + type uint8 { + range 1..44; + } + } + + leaf ICMP_CODE { + type uint8 { + range 1..16; + } + } + } + + case icmp6 { + when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV6' or .='IPv6ANY'])"; + leaf ICMPV6_TYPE { + type uint8 { + range 1..44; + } + } + + leaf ICMPV6_CODE { + type uint8 { + range 1..16; + } + } + } + } + + leaf INNER_ETHER_TYPE { + type string { + pattern "(0x88CC|0x8100|0x8915|0x0806|0x0800|0x86DD|0x8847)"; + } + } + + leaf INNER_IP_PROTOCOL { + type uint8 { + range 1..143; + } + } + + leaf INNER_L4_SRC_PORT { + type uint16; + } + + leaf INNER_L4_DST_PORT { + type uint16; + } + } + /* end of ACL_RULE_LIST */ + } + /* end of container ACL_RULE */ + + container ACL_TABLE { + + description "ACL_TABLE part of config_db.json"; + + list ACL_TABLE_LIST { + + key "ACL_TABLE_NAME"; + + ext:key-regex-configdb-to-yang "^([a-zA-Z0-9-_]+)$"; + + ext:key-regex-yang-to-configdb ""; + + leaf ACL_TABLE_NAME { + type string; + } + + leaf policy_desc { + type string { + length 1..255; + } + } + + leaf type { + type stypes:acl_table_type; + } + + leaf stage { + type enumeration { + enum INGRESS; + enum EGRESS; + } + } + + leaf-list ports { + /* union of leafref is allowed in YANG 1.1 */ + type union { + type leafref { + path /port:sonic-port/port:PORT/port:PORT_LIST/port:port_name; + } + type leafref { + path /lag:sonic-portchannel/lag:PORTCHANNEL/lag:PORTCHANNEL_LIST/lag:portchannel_name; + } + } + } + } + /* end of ACL_TABLE_LIST */ + } + /* end of container ACL_TABLE */ + } + /* end of container sonic-acl */ +} +/* end of module sonic-acl */ diff --git a/src/sonic-yang-models/yang-models/sonic-extension.yang b/src/sonic-yang-models/yang-models/sonic-extension.yang new file mode 100644 index 000000000000..5632e893d9ca --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-extension.yang @@ -0,0 +1,23 @@ +module sonic-extension { + + yang-version 1.1; + + namespace "http://github.com/Azure/sonic-extension"; + prefix sonic-extension; + + description "Extension yang Module for SONiC OS"; + + revision 2019-07-01 { + description "First Revision"; + } + + extension key-regex-configdb-to-yang { + description "Key regex used to convert config DB keys to YANG Config"; + argument "value"; + } + + extension key-regex-yang-to-configdb { + description "Key regex used to convert config DB keys to YANG Config"; + argument "value"; + } +} diff --git a/src/sonic-yang-models/yang-models/sonic-interface.yang b/src/sonic-yang-models/yang-models/sonic-interface.yang new file mode 100644 index 000000000000..d47268be69f9 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-interface.yang @@ -0,0 +1,122 @@ +module sonic-interface { + + yang-version 1.1; + + namespace "http://github.com/Azure/sonic-interface"; + prefix intf; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import sonic-types { + prefix stypes; + revision-date 2019-07-01; + } + + import sonic-extension { + prefix ext; + revision-date 2019-07-01; + } + + import sonic-port { + prefix port; + revision-date 2019-07-01; + } + + description "INTERFACE yang Module for SONiC OS"; + + revision 2019-07-01 { + description "First Revision"; + } + + container sonic-interface { + + container INTERFACE { + + description "INTERFACE part of config_db.json"; + + list INTERFACE_LIST { + + description "INTERFACE part of config_db.json with vrf"; + + key "port_name"; + + ext:key-regex-configdb-to-yang "^(Ethernet[0-9]+)$"; + + ext:key-regex-yang-to-configdb ""; + + leaf port_name { + type leafref { + path /port:sonic-port/port:PORT/port:PORT_LIST/port:port_name; + } + } + + leaf vrf_name { + type string { + pattern "Vrf[a-zA-Z0-9_-]+"; + length 3..255; + } + } + } + /* end of INTERFACE_LIST */ + + list INTERFACE_IPPREFIX_LIST { + + description "INTERFACE part of config_db.json with ip-prefix"; + + key "port_name ip-prefix"; + + ext:key-regex-configdb-to-yang "^(Ethernet[0-9]+)|([a-fA-F0-9:./]+)$"; + + ext:key-regex-yang-to-configdb "|"; + + leaf port_name { + /* This node must be present in INTERFACE_LIST */ + must "(current() = ../../INTERFACE_LIST[port_name=current()]/port_name)" + { + error-message "Must condition not satisfied, Try adding PORT: {}, Example: 'Ethernet0': {}"; + } + + type leafref { + path /port:sonic-port/port:PORT/port:PORT_LIST/port:port_name; + } + } + + leaf ip-prefix { + type union { + type stypes:sonic-ip4-prefix; + type stypes:sonic-ip6-prefix; + } + } + + leaf scope { + type enumeration { + enum global; + enum local; + } + } + + leaf family { + + /* family leaf needed for backward compatibility + Both ip4 and ip6 address are string in IETF RFC 6021, + so must statement can check based on : or ., family + should be IPv4 or IPv6 according. + */ + + must "(contains(../ip-prefix, ':') and current()='IPv6') or + (contains(../ip-prefix, '.') and current()='IPv4')"; + type stypes:ip-family; + } + } + /* end of INTERFACE_IPPREFIX_LIST */ + + } + /* end of INTERFACE container */ + } +} diff --git a/src/sonic-yang-models/yang-models/sonic-loopback-interface.yang b/src/sonic-yang-models/yang-models/sonic-loopback-interface.yang new file mode 100644 index 000000000000..92b059af64ca --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-loopback-interface.yang @@ -0,0 +1,98 @@ +module sonic-loopback-interface { + + namespace "http://github.com/Azure/sonic-loopback-interface"; + prefix lointf; + + import ietf-inet-types { + prefix inet; + } + + import sonic-types { + prefix stypes; + revision-date 2019-07-01; + } + + import sonic-extension { + prefix ext; + revision-date 2019-07-01; + } + + description + "SONIC LOOPBACK INTERFACE"; + + revision 2020-02-05 { + description "First Revision"; + } + + container sonic-loopback-interface { + + container LOOPBACK_INTERFACE { + + list LOOPBACK_INTERFACE_LIST { + key "loopback_interface_name"; + + ext:key-regex-configdb-to-yang "^([a-zA-Z0-9-_]+)$"; + + ext:key-regex-yang-to-configdb ""; + + leaf loopback_interface_name{ + type string; + } + + leaf vrf_name { + type string { + pattern "Vrf[a-zA-Z0-9_-]+"; + length 3..255; + } + } + } + /* end of LOOPBACK_INTERFACE_LIST */ + + list LOOPBACK_INTERFACE_IPPREFIX_LIST { + + key "loopback_interface_name ip-prefix"; + + ext:key-regex-configdb-to-yang "^([a-zA-Z0-9-_]+)|([a-fA-F0-9:./]+$)"; + + ext:key-regex-yang-to-configdb "|"; + + leaf loopback_interface_name{ + /* This node must be present in LOOPBACK_INTERFACE_LIST */ + must "(current() = ../../LOOPBACK_INTERFACE_LIST[loopback_interface_name=current()]/loopback_interface_name)" + { + error-message "Must condition not satisfied, Try adding lo<>: {}, Example: 'lo1': {}"; + } + type string; + } + + leaf ip-prefix { + type union { + type stypes:sonic-ip4-prefix; + type stypes:sonic-ip6-prefix; + } + } + + leaf scope { + type enumeration { + enum global; + enum local; + } + } + + leaf family { + + /* family leaf needed for backward compatibility + Both ip4 and ip6 address are string in IETF RFC 6021, + so must statement can check based on : or ., family + should be IPv4 or IPv6 according. + */ + + must "(contains(../ip-prefix, ':') and current()='IPv6') or + (contains(../ip-prefix, '.') and current()='IPv4')"; + type stypes:ip-family; + } + } + } + /* end of LOOPBACK_INTERFACE_IPPREFIX_LIST */ + } +} diff --git a/src/sonic-yang-models/yang-models/sonic-port.yang b/src/sonic-yang-models/yang-models/sonic-port.yang new file mode 100644 index 000000000000..88fcf72dadbc --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-port.yang @@ -0,0 +1,105 @@ +module sonic-port{ + + yang-version 1.1; + + namespace "http://github.com/Azure/sonic-port"; + prefix port; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import sonic-types { + prefix stypes; + revision-date 2019-07-01; + } + + import sonic-extension { + prefix ext; + revision-date 2019-07-01; + } + + description "PORT yang Module for SONiC OS"; + + revision 2019-07-01 { + description "First Revision"; + } + + container sonic-port{ + + container PORT { + + description "PORT part of config_db.json"; + + list PORT_LIST { + + key "port_name"; + + ext:key-regex-configdb-to-yang "^(Ethernet[0-9]+)$"; + + ext:key-regex-yang-to-configdb ""; + + leaf port_name { + type string { + length 1..128; + } + } + + leaf alias { + type string { + length 1..128; + } + } + + leaf lanes { + mandatory true; + type string { + length 1..128; + } + } + + leaf description { + type string { + length 0..255; + } + } + + leaf speed { + mandatory true; + type uint32 { + range 1..100000; + } + } + + leaf mtu { + type uint16 { + range 1..9216; + } + } + + leaf index { + type uint16 { + range 0..256; + } + } + + leaf admin_status { + type stypes:admin_status; + } + + leaf fec { + type string { + pattern "rc|fc|None"; + } + } + } /* end of list PORT_LIST */ + + } /* end of container PORT */ + + } /* end of container sonic-port */ + +} /* end of module sonic-port */ diff --git a/src/sonic-yang-models/yang-models/sonic-portchannel.yang b/src/sonic-yang-models/yang-models/sonic-portchannel.yang new file mode 100644 index 000000000000..8f758fd51c81 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-portchannel.yang @@ -0,0 +1,92 @@ +module sonic-portchannel { + + yang-version 1.1; + + namespace "http://github.com/Azure/sonic-portchannel"; + prefix lag; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import sonic-types { + prefix stypes; + revision-date 2019-07-01; + } + + import sonic-extension { + prefix ext; + revision-date 2019-07-01; + } + + import sonic-port { + prefix port; + revision-date 2019-07-01; + } + + description "PORTCHANNEL yang Module for SONiC OS"; + + revision 2019-07-01 { + description "First Revision"; + } + + container sonic-portchannel { + container PORTCHANNEL { + + description "PORTCHANNEL part of config_db.json"; + + list PORTCHANNEL_LIST { + + key "portchannel_name"; + + ext:key-regex-configdb-to-yang "^(Ethernet[0-9]+)$"; + + ext:key-regex-yang-to-configdb ""; + + leaf portchannel_name { + type string { + length 1..128; + pattern 'PortChannel[0-9]{1,4}'; + } + } + + leaf-list members { + /* leaf-list members are unique by default */ + type leafref { + path /port:sonic-port/port:PORT/port:PORT_LIST/port:port_name; + } + } + + leaf min_links { + type uint8 { + range 1..128; + } + } + + leaf description { + type string { + length 1..255; + } + } + + leaf mtu { + type uint16 { + range 1..9216; + } + } + + leaf admin_status { + mandatory true; + type stypes:admin_status; + } + } /* end of list PORTCHANNEL_LIST */ + + } /* end of container PORTCHANNEL */ + + } /* end of container sonic-portchannel */ + +} /* end of module sonic-port */ diff --git a/src/sonic-yang-models/yang-models/sonic-types.yang b/src/sonic-yang-models/yang-models/sonic-types.yang new file mode 100644 index 000000000000..fb651847582e --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-types.yang @@ -0,0 +1,92 @@ +module sonic-types { + + yang-version 1.1; + + namespace "http://github.com/Azure/sonic-head"; + prefix sonic-types; + + description "SONiC type for yang Models of SONiC OS"; + + revision 2019-07-01 { + description "First Revision"; + } + + typedef ip-family { + type enumeration { + enum IPv4; + enum IPv6; + } + } + + typedef sonic-ip4-prefix { + type string { + 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]))'; + } + } + + typedef sonic-ip6-prefix { + type string { + 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])))'; + pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|' + + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)' + + '(/.+)'; + } + } + + typedef admin_status { + type enumeration { + enum up; + enum down; + } + } + + typedef packet_action{ + type enumeration { + enum DROP; + enum FORWARD; + enum REDIRECT; + } + } + + typedef ip_type { + type enumeration { + enum ANY; + enum IP; + enum NON_IP; + enum IPV4; + enum IPV6; + enum IPv4ANY; + enum NON_IP4; + enum IPv6ANY; + enum NON_IPv6; + enum ARP; + } + } + + typedef acl_table_type { + type enumeration { + enum L2; + enum L3; + enum L3V6; + enum MIRROR; + enum MIRRORV6; + enum MIRROR_DSCP; + enum CTRLPLANE; + } + } + + typedef vlan_tagging_mode { + type enumeration { + enum tagged; + enum untagged; + enum priority_tagged; + } + } +} diff --git a/src/sonic-yang-models/yang-models/sonic-vlan.yang b/src/sonic-yang-models/yang-models/sonic-vlan.yang new file mode 100644 index 000000000000..4c3aecaf8106 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-vlan.yang @@ -0,0 +1,209 @@ +module sonic-vlan { + + namespace "http://github.com/Azure/sonic-vlan"; + prefix vlan; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import sonic-types { + prefix stypes; + revision-date 2019-07-01; + } + + import sonic-extension { + prefix ext; + revision-date 2019-07-01; + } + + import sonic-port { + prefix port; + revision-date 2019-07-01; + } + + description "VLAN yang Module for SONiC OS"; + + revision 2019-07-01 { + description "First Revision"; + } + + container sonic-vlan { + + container VLAN_INTERFACE { + + description "VLAN_INTERFACE part of config_db.json"; + + list VLAN_INTERFACE_LIST { + + description "VLAN INTERFACE part of config_db.json with vrf"; + + key "vlan_name"; + + ext:key-regex-configdb-to-yang "^(Vlan[a-zA-Z0-9_-]+)$"; + + ext:key-regex-yang-to-configdb ""; + + leaf vlan_name { + type leafref { + path /vlan:sonic-vlan/vlan:VLAN/vlan:VLAN_LIST/vlan:vlan_name; + } + } + + leaf vrf_name { + type string { + pattern "Vrf[a-zA-Z0-9_-]+"; + length 3..255; + } + } + } + /* end of VLAN_INTERFACE_LIST */ + + list VLAN_INTERFACE_IPPREFIX_LIST { + + key "vlan_name ip-prefix"; + + ext:key-regex-configdb-to-yang "^(Vlan[a-zA-Z0-9_-]+)|([a-fA-F0-9:./]+$)"; + + ext:key-regex-yang-to-configdb "|"; + + leaf vlan_name { + /* This node must be present in VLAN_INTERFACE_LIST */ + must "(current() = ../../VLAN_INTERFACE_LIST[vlan_name=current()]/vlan_name)" + { + error-message "Must condition not satisfied, Try adding Vlan: {}, Example: 'Vlan100': {}"; + } + + type leafref { + path "/vlan:sonic-vlan/vlan:VLAN/vlan:VLAN_LIST/vlan:vlan_name"; + } + } + + leaf ip-prefix { + type union { + type stypes:sonic-ip4-prefix; + type stypes:sonic-ip6-prefix; + } + } + + leaf scope { + type enumeration { + enum global; + enum local; + } + } + + leaf family { + + /* family leaf needed for backward compatibility + Both ip4 and ip6 address are string in IETF RFC 6021, + so must statement can check based on : or ., family + should be IPv4 or IPv6 according. + */ + + must "(contains(../ip-prefix, ':') and current()='IPv6') or + (contains(../ip-prefix, '.') and current()='IPv4')"; + type stypes:ip-family; + } + } + /* end of VLAN_INTERFACE_LIST */ + } + /* end of VLAN_INTERFACE container */ + + container VLAN { + + description "VLAN part of config_db.json"; + + list VLAN_LIST { + + key "vlan_name"; + + ext:key-regex-configdb-to-yang "^(Vlan[a-zA-Z0-9_-]+)$"; + + ext:key-regex-yang-to-configdb ""; + + leaf vlan_name { + type string { + pattern 'Vlan([0-9]{1,3}|[0-3][0-9]{4}|[4][0][0-8][0-9]|[4][0][9][0-4])'; + } + } + + leaf vlanid { + type uint16 { + range 1..4094; + } + } + + leaf description { + type string { + length 1..255; + } + } + + leaf-list dhcp_servers { + type inet:ip-address; + } + + leaf mtu { + type uint16 { + range 1..9216; + } + } + + leaf admin_status { + type stypes:admin_status; + } + + leaf-list members { + /* leaf-list members are unique by default */ + + type leafref { + path "/port:sonic-port/port:PORT/port:PORT_LIST/port:port_name"; + } + } + } + /* end of VLAN_LIST */ + } + /* end of container VLAN */ + + container VLAN_MEMBER { + + description "VLAN_MEMBER part of config_db.json"; + + list VLAN_MEMBER_LIST { + + key "vlan_name port"; + + ext:key-regex-configdb-to-yang "^(Vlan[a-zA-Z0-9-_]+)|(Ethernet[0-9]+)$"; + + ext:key-regex-yang-to-configdb "|"; + + leaf vlan_name { + type leafref { + path "/vlan:sonic-vlan/vlan:VLAN/vlan:VLAN_LIST/vlan:vlan_name"; + } + } + + leaf port { + /* key elements are mandatory by default */ + type leafref { + path /port:sonic-port/port:PORT/port:PORT_LIST/port:port_name; + } + } + + leaf tagging_mode { + mandatory true; + type stypes:vlan_tagging_mode; + } + } + /* end of list VLAN_MEMBER_LIST */ + } + /* end of container VLAN_MEMBER */ + } + /* end of container sonic-vlan */ +} +/* end of module sonic-vlan */ diff --git a/src/sonic-ztp b/src/sonic-ztp index 374c9e804a9f..c959371ece3b 160000 --- a/src/sonic-ztp +++ b/src/sonic-ztp @@ -1 +1 @@ -Subproject commit 374c9e804a9f434cdb58fa7afe0c3f6201bfe56f +Subproject commit c959371ece3baebff2d3d748aba863de87b1d0a8 diff --git a/src/supervisor/.gitignore b/src/supervisor/.gitignore new file mode 100644 index 000000000000..d19db76ab9a9 --- /dev/null +++ b/src/supervisor/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!Makefile +!patch/ diff --git a/src/swig/.gitignore b/src/swig/.gitignore new file mode 100644 index 000000000000..a0991ff4402b --- /dev/null +++ b/src/swig/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/src/systemd-sonic-generator/.gitignore b/src/systemd-sonic-generator/.gitignore new file mode 100644 index 000000000000..06e13f381b69 --- /dev/null +++ b/src/systemd-sonic-generator/.gitignore @@ -0,0 +1,6 @@ +systemd-sonic-generator +debian/* +!debian/changelog +!debian/compat +!debian/control +!debian/rules diff --git a/src/systemd-sonic-generator/systemd-sonic-generator.c b/src/systemd-sonic-generator/systemd-sonic-generator.c index 566d37ff0a4c..9a5fabd33484 100644 --- a/src/systemd-sonic-generator/systemd-sonic-generator.c +++ b/src/systemd-sonic-generator/systemd-sonic-generator.c @@ -14,7 +14,7 @@ #define MAX_NUM_UNITS 128 #define MAX_BUF_SIZE 512 -static const char* UNIT_FILE_PREFIX = "/etc/systemd/system/"; +static const char* UNIT_FILE_PREFIX = "/usr/lib/systemd/system/"; static const char* CONFIG_FILE = "/etc/sonic/generated_services.conf"; static const char* MACHINE_CONF_FILE = "/host/machine.conf"; static int num_asics; diff --git a/src/tacacs/.gitignore b/src/tacacs/.gitignore new file mode 100644 index 000000000000..3e483805dfe3 --- /dev/null +++ b/src/tacacs/.gitignore @@ -0,0 +1,8 @@ +* +!.gitignore +nsm/* +!nsm/Makefile +!nsm/*.patch +pam/* +!pam/Makefile +!pam/*.patch diff --git a/src/tacacs/nss/0006-fix-compiling-warning-about-token-dereference.patch b/src/tacacs/nss/0006-fix-compiling-warning-about-token-dereference.patch new file mode 100644 index 000000000000..37d9c37acebc --- /dev/null +++ b/src/tacacs/nss/0006-fix-compiling-warning-about-token-dereference.patch @@ -0,0 +1,34 @@ +From d8300dca720dc17e19d39efa3abbe3c3e5600262 Mon Sep 17 00:00:00 2001 +From: Guohan Lu +Date: Wed, 5 Feb 2020 07:25:13 +0000 +Subject: [PATCH] fix compiling warning about token dereference + +--- + nss_tacplus.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/nss_tacplus.c b/nss_tacplus.c +index 3ff3c35..7feeda6 100644 +--- a/nss_tacplus.c ++++ b/nss_tacplus.c +@@ -87,7 +87,7 @@ static int parse_tac_server(char *srv_buf) + + token = strsep(&srv_buf, delim); + while(token) { +- if('\0' != token) { ++ if('\0' != token[0]) { + if(!strncmp(token, "server=", 7)) { + struct addrinfo hints, *server; + int rv; +@@ -161,7 +161,7 @@ static int parse_user_priv(char *buf) + + token = strsep(&buf, delim); + while(token) { +- if('\0' != token) { ++ if('\0' != token[0]) { + if(!strncmp(token, "user_priv=", 10)) { + priv = (int)strtoul(token + 10, NULL, 0); + if(priv > MAX_TACACS_USER_PRIV || priv < MIN_TACACS_USER_PRIV) +-- +2.17.1 + diff --git a/src/tacacs/nss/Makefile b/src/tacacs/nss/Makefile index a0c42bd2f222..cb9382d07a89 100644 --- a/src/tacacs/nss/Makefile +++ b/src/tacacs/nss/Makefile @@ -23,6 +23,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : git $(GIT_APPLY) ../0003-management-vrf-support.patch git $(GIT_APPLY) ../0004-Skip-accessing-tacacs-servers-for-local-non-tacacs-u.patch git $(GIT_APPLY) ../0005-libnss-Modify-parsing-of-IP-addr-and-port-number-str.patch + git $(GIT_APPLY) ../0006-fix-compiling-warning-about-token-dereference.patch dpkg-buildpackage -rfakeroot -b -us -uc popd diff --git a/src/thrift/.gitignore b/src/thrift/.gitignore new file mode 100644 index 000000000000..d19db76ab9a9 --- /dev/null +++ b/src/thrift/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!Makefile +!patch/