diff --git a/.gitignore b/.gitignore index 06b10caa315e..739454168796 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .DS_Store # Build system related +.arch .platform .screen diff --git a/.gitmodules b/.gitmodules index e9b3a573e4ff..b9831ba33296 100644 --- a/.gitmodules +++ b/.gitmodules @@ -47,7 +47,7 @@ [submodule "src/sonic-frr/frr"] path = src/sonic-frr/frr url = https://github.com/Azure/sonic-frr.git - branch = frr/7.0 + branch = frr/7.2 [submodule "platform/p4/p4-hlir/p4-hlir-v1.1"] path = platform/p4/p4-hlir/p4-hlir-v1.1 url = https://github.com/p4lang/p4-hlir.git @@ -72,3 +72,6 @@ [submodule "src/sonic-telemetry"] path = src/sonic-telemetry url = https://github.com/Azure/sonic-telemetry +[submodule "Switch-SDK-drivers"] + path = platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers + url = https://github.com/Mellanox/Switch-SDK-drivers diff --git a/Makefile b/Makefile index c949171a899a..13a3f247fc31 100644 --- a/Makefile +++ b/Makefile @@ -17,4 +17,7 @@ endif clean reset init configure showtag sonic-slave-build sonic-slave-bash : @echo "+++ Making $@ +++" +ifeq ($(NOJESSIE), 0) + make -f Makefile.work $@ +endif BLDENV=stretch make -f Makefile.work $@ diff --git a/Makefile.work b/Makefile.work index 389f3f7c831f..b81ac591246f 100644 --- a/Makefile.work +++ b/Makefile.work @@ -74,11 +74,11 @@ endif ifeq ($(BLDENV), stretch) SLAVE_DIR = sonic-slave-stretch else -SLAVE_DIR = sonic-slave +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)-base +SLAVE_BASE_IMAGE = $(SLAVE_DIR) SLAVE_IMAGE = $(SLAVE_BASE_IMAGE)-$(USER) OVERLAY_MODULE_CHECK := \ @@ -126,7 +126,8 @@ ifneq (,$(filter $(CONFIGURED_ARCH), armhf arm64)) DOCKER_MULTIARCH_CHECK := docker inspect --type image multiarch/qemu-user-static:register &> /dev/null || (echo "multiarch docker not found ..."; docker run --rm --privileged multiarch/qemu-user-static:register --reset --credential yes) - DOCKER_SERVICE_MULTIARCH_CHECK := docker -H unix:///var/run/march/docker.sock info &> /dev/null || (echo "Docker march service not running..."; sudo rm -fr /var/run/march/docker*; (sudo $(SONIC_NATIVE_DOCKERD_FOR_MUTLIARCH) &) &>/dev/null ; sleep 1; sudo $(SONIC_USERFACL_DOCKERD_FOR_MUTLIARCH);) + DOCKER_SERVICE_SAFE_KILLER := (MARCH_PID=`ps -eo pid,cmd | grep "[0-9] dockerd.*march" | awk '{print $$1}'`; echo "Killing march docker $$MARCH_PID"; [ -z "$$MARCH_PID" ] || sudo kill -9 "$$MARCH_PID";) + DOCKER_SERVICE_MULTIARCH_CHECK := ($(DOCKER_SERVICE_SAFE_KILLER); sudo rm -fr /var/run/march/; (echo "Starting docker march service..."; sudo $(SONIC_NATIVE_DOCKERD_FOR_MUTLIARCH) &) &>/dev/null ; sleep 2; sudo $(SONIC_USERFACL_DOCKERD_FOR_MUTLIARCH);) # Docker service to load the compiled dockers-*.gz SONIC_NATIVE_DOCKERD_FOR_DOCKERFS := rm -fr $(PWD)/dockerfs/; mkdir -p $(PWD)/dockerfs/; sudo dockerd --storage-driver=overlay2 --iptables=false \ @@ -184,8 +185,10 @@ SONIC_BUILD_INSTRUCTION := make \ %:: ifneq (,$(filter $(CONFIGURED_ARCH), armhf arm64)) @$(DOCKER_MULTIARCH_CHECK) +ifneq ($(BLDENV), ) @$(DOCKER_SERVICE_MULTIARCH_CHECK) @$(DOCKER_SERVICE_DOCKERFS_CHECK) +endif endif @$(OVERLAY_MODULE_CHECK) @@ -227,18 +230,24 @@ init : @git submodule update --init --recursive @git submodule foreach --recursive '[ -f .git ] && echo "gitdir: $$(realpath --relative-to=. $$(cut -d" " -f2 .git))" > .git' +.ONESHELL : reset reset : @echo && echo -n "Warning! All local changes will be lost. Proceed? [y/N]: " - @read ans && \ - if [ $$ans == y ]; then \ - echo "Resetting local repository. Please wait..."; \ - $(DOCKER_RUN) $(SLAVE_IMAGE):$(SLAVE_TAG) sudo rm -rf fsroot; \ - git clean -xfdf; \ - git reset --hard; \ - git submodule foreach --recursive git clean -xfdf; \ - git submodule foreach --recursive git reset --hard; \ - git submodule update --init --recursive; \ - echo "Reset complete!"; \ - else \ - echo "Reset aborted"; \ - fi + @read ans && ( + if [ $$ans == y ]; then + echo "Resetting local repository. Please wait..."; + $(DOCKER_RUN) $(SLAVE_IMAGE):$(SLAVE_TAG) sudo rm -rf fsroot; + if [[ "$(CONFIGURED_ARCH)" == "armhf" || "$(CONFIGURED_ARCH)" == "arm64" ]]; then + echo "Stopping march $(CONFIGURED_ARCH) docker" + sudo kill -9 `sudo cat /var/run/march/docker.pid` || true + sudo rm -f /var/run/march/docker.pid || true + fi + git clean -xfdf; + git reset --hard; + git submodule foreach --recursive git clean -xfdf; + git submodule foreach --recursive git reset --hard; + git submodule update --init --recursive; + echo "Reset complete!"; + else + echo "Reset aborted"; + fi ) diff --git a/README.md b/README.md index 9c486e412063..129af89f05d4 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,15 @@ Nephos: [![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/j P4: [![P4](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all) VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-all/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-all) +*201904*: +Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201904/) +Barefoot: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201904/) +Centec: [![Centec](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-201904/) +Nephos: [![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201904/) +Marvell: [![Marvell](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201904/) +Mellanox: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201904/) +VS: [![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201904/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201904) + *201811*: Broadcom: [![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201811/) Barefoot: [![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201811/badge/icon)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201811/) @@ -51,6 +60,11 @@ Install pip and jinja in host build machine, execute below commands if j2/j2cli sudo pip install --force-reinstall --upgrade jinja2>=2.10 sudo pip install j2cli +Configure your system to allow running the 'docker' command without 'sudo': + Add current user to the docker group + `sudo gpasswd -a ${USER} docker` + Log out and log back in so that your group membership is re-evaluated + ## SAI Version Please refer to [SONiC roadmap](https://github.com/Azure/SONiC/wiki/Sonic-Roadmap-Planning) on the SAI version for each SONiC release. @@ -83,15 +97,23 @@ To build SONiC installer image and docker images, run the following commands: ## Usage for ARM Architecture To build Arm32 bit for (ARMHF) plaform + ARM build has dependency in docker version 18, + if docker version is 19, downgrade to 18 as below + sudo apt-get install --allow-downgrades -y docker-ce=5:18.09.0~3-0~ubuntu-xenial + sudo apt-get install --allow-downgrades -y docker-ce-cli=5:18.09.0~3-0~ubuntu-xenial # Execute make configure once to configure ASIC and ARCH make configure PLATFORM=[ASIC_VENDOR] PLATFORM_ARCH=armhf - **example**: + make target/sonic-[ASIC_VENDER]-armhf.bin + + # example: make configure PLATFORM=marvell-armhf PLATFORM_ARCH=armhf + make target/sonic-marvell-armhf.bin + To build Arm64 bit for plaform @@ -100,7 +122,7 @@ To build Arm64 bit for plaform make configure PLATFORM=[ASIC_VENDOR] PLATFORM_ARCH=arm64 - **example**: + # example: make configure PLATFORM=marvell-arm64 PLATFORM_ARCH=arm64 @@ -176,6 +198,7 @@ This may take a while, but it is a one-time action, so please be patient. - docker-syncd-nephos.gz: docker image for the daemon to sync database and Nephos switch ASIC (gzip tar archive) - docker-sonic-p4.gz: docker image for all-in-one for p4 software switch (gzip tar archive) - docker-sonic-vs.gz: docker image for all-in-one for software virtual switch (gzip tar archive) + - docker-sonic-mgmt.gz: docker image for [managing, configuring and monitoring SONiC](https://github.com/Azure/sonic-mgmt) (gzip tar archive) ## Contribution Guide diff --git a/build_debian.sh b/build_debian.sh index 9ff6fa019dfb..fb3ecfef6ce6 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -31,7 +31,12 @@ set -x -e CONFIGURED_ARCH=$([ -f .arch ] && cat .arch || echo amd64) ## docker engine version (with platform) -DOCKER_VERSION=5:18.09.8~3-0~debian-stretch +if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then + # Version name differs between ARCH, copying same version as in sonic-slave docker + DOCKER_VERSION=18.06.3~ce~3-0~debian +else + DOCKER_VERSION=5:18.09.8~3-0~debian-stretch +fi LINUX_KERNEL_VERSION=4.9.0-9-2 ## Working directory to prepare the file system @@ -127,16 +132,11 @@ fi sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install busybox echo '[INFO] Install SONiC linux kernel image' ## Note: duplicate apt-get command to ensure every line return zero -if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install cpio klibc-utils kmod libklibc udev linux-base - sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/linux-image-*${CONFIGURED_ARCH}*.deb || \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f -fi sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/initramfs-tools-core_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/initramfs-tools_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/linux-image-${LINUX_KERNEL_VERSION}-${CONFIGURED_ARCH}_*.deb || \ +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/linux-image-${LINUX_KERNEL_VERSION}-*_${CONFIGURED_ARCH}.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install acl [[ $CONFIGURED_ARCH == amd64 ]] && sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install dmidecode @@ -165,7 +165,7 @@ sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-premount/resize- ## Hook into initramfs: after partition mount and loop file mount ## 1. Prepare layered file system -## 2. Bind-mount docker working directory (docker aufs cannot work over aufs rootfs) +## 2. Bind-mount docker working directory (docker overlay storage cannot work over overlay rootfs) sudo cp files/initramfs-tools/union-mount $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-bottom/union-mount sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-bottom/union-mount sudo cp files/initramfs-tools/varlog $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-bottom/varlog @@ -201,7 +201,7 @@ sudo LANG=C chroot $FILESYSTEM_ROOT apt-get update sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install docker-ce=${DOCKER_VERSION} sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y remove software-properties-common gnupg2 -## Add docker config drop-in to select aufs, otherwise it may select other storage driver +## 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 sudo cp files/docker/docker.service.conf $_ @@ -270,7 +270,11 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in tcptraceroute \ mtr-tiny \ locales \ - cgroup-tools + cgroup-tools \ + ipmitool \ + ndisc6 \ + makedumpfile + if [[ $CONFIGURED_ARCH == amd64 ]]; then ## Pre-install the fundamental packages for amd64 (x86) @@ -279,6 +283,17 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in mcelog fi +## Set /etc/shadow permissions to -rw-------. +sudo LANG=c chroot $FILESYSTEM_ROOT chmod 600 /etc/shadow + +## Set /etc/passwd, /etc/group permissions to -rw-r--r--. +sudo LANG=c chroot $FILESYSTEM_ROOT chmod 644 /etc/passwd +sudo LANG=c chroot $FILESYSTEM_ROOT chmod 644 /etc/group + +# Needed to install kdump-tools +sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c "mkdir -p /etc/initramfs-tools/conf.d" +sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c "echo 'MODULES=most' >> /etc/initramfs-tools/conf.d/driver-policy" + #Adds a locale to a debian system in non-interactive mode sudo sed -i '/^#.* en_US.* /s/^#//' $FILESYSTEM_ROOT/etc/locale.gen && \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT locale-gen "en_US.UTF-8" @@ -334,31 +349,8 @@ sudo sed -i 's/^ListenAddress ::/#ListenAddress ::/' $FILESYSTEM_ROOT/etc/ssh/ss sudo sed -i 's/^#ListenAddress 0.0.0.0/ListenAddress 0.0.0.0/' $FILESYSTEM_ROOT/etc/ssh/sshd_config ## Config monit -sudo sed -i ' - s/^# set logfile syslog/set logfile syslog/; - s/^\s*set logfile \/var/# set logfile \/var/; - s/^# set httpd port/set httpd port/; - s/^# use address localhost/ use address localhost/; - s/^# allow localhost/ allow localhost/; - s/^# allow admin:monit/ allow admin:monit/; - s/^# allow @monit/ allow @monit/; - s/^# allow @users readonly/ allow @users readonly/ - ' $FILESYSTEM_ROOT/etc/monit/monitrc - -sudo tee -a $FILESYSTEM_ROOT/etc/monit/monitrc > /dev/null <<'EOF' -check filesystem root-overlay with path / - if space usage > 90% for 5 times within 10 cycles then alert -check filesystem var-log with path /var/log - if space usage > 90% for 5 times within 10 cycles then alert -check system $HOST - if memory usage > 50% for 5 times within 10 cycles then alert - if cpu usage (user) > 90% for 5 times within 10 cycles then alert - if cpu usage (system) > 90% for 5 times within 10 cycles then alert -check process rsyslog with pidfile /var/run/rsyslogd.pid - start program = "/bin/systemctl start rsyslog.service" - stop program = "/bin/systemctl stop rsyslog.service" - if totalmem > 800 MB for 5 times within 10 cycles then restart -EOF +sudo cp files/image_config/monit/monitrc $FILESYSTEM_ROOT/etc/monit/ +sudo chmod 600 $FILESYSTEM_ROOT/etc/monit/monitrc ## Config sysctl sudo mkdir -p $FILESYSTEM_ROOT/var/core @@ -441,6 +433,9 @@ sudo cp files/dhcp/graphserviceurl $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks sudo cp files/dhcp/snmpcommunity $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/vrf $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/dhclient.conf $FILESYSTEM_ROOT/etc/dhcp/ +if [ -f files/image_config/ntp/ntp ]; then + sudo cp ./files/image_config/ntp/ntp $FILESYSTEM_ROOT/etc/init.d/ +fi ## Version file sudo mkdir -p $FILESYSTEM_ROOT/etc/sonic @@ -455,6 +450,17 @@ build_number: ${BUILD_NUMBER:-0} built_by: $USER@$BUILD_HOSTNAME EOF +## Copy over clean-up script +sudo cp ./files/scripts/core_cleanup.py $FILESYSTEM_ROOT/usr/bin/core_cleanup.py + +## Copy ASIC config checksum +python files/build_scripts/generate_asic_config_checksum.py +if [[ ! -f './asic_config_checksum' ]]; then + echo 'asic_config_checksum not found' + exit 1 +fi +sudo cp ./asic_config_checksum $FILESYSTEM_ROOT/etc/sonic/asic_config_checksum + if [ -f sonic_debian_extension.sh ]; then ./sonic_debian_extension.sh $FILESYSTEM_ROOT $PLATFORM_DIR fi @@ -485,10 +491,7 @@ then sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c "echo '/debug is mounted in each docker' >> /etc/motd" sudo mkdir -p $FILESYSTEM_ROOT/src - pushd src - ../scripts/dbg_files.sh | sudo tar -cvzf ../$FILESYSTEM_ROOT/src/sonic_src.tar.gz -T - - popd - + sudo cp $DEBUG_SRC_ARCHIVE_FILE $FILESYSTEM_ROOT/src/ sudo mkdir -p $FILESYSTEM_ROOT/debug fi diff --git a/build_image.sh b/build_image.sh index 3084a4a2bd5d..9635201ae067 100755 --- a/build_image.sh +++ b/build_image.sh @@ -96,7 +96,7 @@ elif [ "$IMAGE_TYPE" = "kvm" ]; then generate_onie_installer_image - SONIC_USERNAME=$USERNAME PASSWD=$PASSWORD sudo -E ./build_kvm_image.sh $KVM_IMAGE_DISK $onie_recovery_image $OUTPUT_ONIE_IMAGE $KVM_IMAGE_DISK_SIZE + SONIC_USERNAME=$USERNAME PASSWD=$PASSWORD sudo -E ./scripts/build_kvm_image.sh $KVM_IMAGE_DISK $onie_recovery_image $OUTPUT_ONIE_IMAGE $KVM_IMAGE_DISK_SIZE if [ $? -ne 0 ]; then echo "Error : build kvm image failed" 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 d008d016ef5c..aabb372bf649 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 -Ethernet0 26 thousandE1 0 -Ethernet1 25 thousandE2 1 -Ethernet2 28 thousandE3 2 -Ethernet3 27 thousandE4 3 -Ethernet4 30 thousandE5 4 -Ethernet5 29 thousandE6 5 -Ethernet6 32 thousandE7 6 -Ethernet7 31 thousandE8 7 -Ethernet8 38 thousandE9 8 -Ethernet9 37 thousandE10 9 -Ethernet10 40 thousandE11 10 -Ethernet11 39 thousandE12 11 -Ethernet12 34 thousandE13 12 -Ethernet13 33 thousandE14 13 -Ethernet14 36 thousandE15 14 -Ethernet15 35 thousandE16 15 -Ethernet16 46 thousandE17 16 -Ethernet17 45 thousandE18 17 -Ethernet18 48 thousandE19 18 -Ethernet19 47 thousandE20 19 -Ethernet20 42 thousandE21 20 -Ethernet21 41 thousandE22 21 -Ethernet22 44 thousandE23 22 -Ethernet23 43 thousandE24 23 -Ethernet24 2 thousandE25 24 -Ethernet25 1 thousandE26 25 -Ethernet26 4 thousandE27 26 -Ethernet27 3 thousandE28 27 -Ethernet28 6 thousandE29 28 -Ethernet29 5 thousandE30 29 -Ethernet30 8 thousandE31 30 -Ethernet31 7 thousandE32 31 -Ethernet32 10 thousandE33 32 -Ethernet33 9 thousandE34 33 -Ethernet34 12 thousandE35 34 -Ethernet35 11 thousandE36 35 -Ethernet36 14 thousandE37 36 -Ethernet37 13 thousandE38 37 -Ethernet38 16 thousandE39 38 -Ethernet39 15 thousandE40 39 -Ethernet40 18 thousandE41 40 -Ethernet41 17 thousandE42 41 -Ethernet42 20 thousandE43 42 -Ethernet43 19 thousandE44 43 -Ethernet44 22 thousandE45 44 -Ethernet45 21 thousandE46 45 -Ethernet46 24 thousandE47 46 -Ethernet47 23 thousandE48 47 -Ethernet48 67 twentyfiveGigE49 48 -Ethernet49 66 twentyfiveGigE50 49 -Ethernet50 65 twentyfiveGigE51 50 -Ethernet51 68 twentyfiveGigE52 51 -Ethernet52 73,74,75,76 hundredGigE53 52 -Ethernet56 69,70,71,72 hundredGigE54 56 +# 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 diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py index 69c2870669e7..cb18eb0d540c 100755 --- a/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py @@ -4,34 +4,39 @@ # try: + import sys import time + import string + from ctypes import create_string_buffer from sonic_sfp.sfputilbase import SfpUtilBase except ImportError as e: raise ImportError("%s - required module not found" % str(e)) +SFP_STATUS_INSERTED = '1' +SFP_STATUS_REMOVED = '0' class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" - - PORT_START = 48 - PORT_END = 53 + PORT_START = 49 + PORT_END = 54 PORTS_IN_BLOCK = 54 - + QSFP_START = 53 + BASE_OOM_PATH = "/sys/bus/i2c/devices/{0}-0050/" BASE_CPLD_PATH = "/sys/bus/i2c/devices/3-0060/" - + _port_to_is_present = {} _port_to_lp_mode = {} _port_to_eeprom_mapping = {} _port_to_i2c_mapping = { - 48: [18], - 49: [19], - 50: [20], - 51: [21], - 52: [22], - 53: [23], + 49: [18], + 50: [19], + 51: [20], + 52: [21], + 53: [22], + 54: [23], } @property @@ -41,7 +46,7 @@ def port_start(self): @property def port_end(self): return self.PORT_END - + @property def qsfp_ports(self): return range(self.PORT_START, self.PORTS_IN_BLOCK + 1) @@ -52,28 +57,23 @@ def port_to_eeprom_mapping(self): def __init__(self): eeprom_path = self.BASE_OOM_PATH + "eeprom" - - for x in range(0, self.port_end+1): - if x < 48: - self.port_to_eeprom_mapping[x] = eeprom_path.format(0) - else: - self.port_to_eeprom_mapping[x] = eeprom_path.format( - self._port_to_i2c_mapping[x][0]) - + for x in range(self.port_start, self.port_end+1): + self.port_to_eeprom_mapping[x] = eeprom_path.format( + self._port_to_i2c_mapping[x][0]) SfpUtilBase.__init__(self) def get_presence(self, port_num): # Check for invalid port_num if port_num < self.port_start or port_num > self.port_end: return False - - present_path = self.BASE_CPLD_PATH + "module_present_" + str(port_num+1) + + present_path = self.BASE_CPLD_PATH + "module_present_" + str(port_num) self.__port_to_is_present = present_path try: val_file = open(self.__port_to_is_present) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to open file: %s" % str(e) return False content = val_file.readline().rstrip() @@ -84,20 +84,113 @@ def get_presence(self, port_num): return True return False - - def get_low_power_mode(self, port_num): - raise NotImplementedError - def set_low_power_mode(self, port_num, lpmode): - raise NotImplementedError + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self.QSFP_START or port_num > self.port_end: + return False + + try: + eeprom = None + if not self.get_presence(port_num): + return False + eeprom = open(self.port_to_eeprom_mapping[port_num], "rb") + eeprom.seek(93) + lpmode = ord(eeprom.read(1)) + + # if "Power override" bit is 1 and "Power set" bit is 1 + if ((lpmode & 0x3) == 0x3): + return True + + # High Power Mode if one of the following conditions is matched: + # 1. "Power override" bit is 0 + # 2. "Power override" bit is 1 and "Power set" bit is 0 + else: + return False + + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.QSFP_START or port_num > self.port_end: + return False + + try: + eeprom = None + if not self.get_presence(port_num): + return False # Port is not present, unable to set the eeprom + + # Fill in write buffer + # 0x3:Low Power Mode, 0x1:High Power Mode + regval = 0x3 if lpmode else 0x1 + + buffer = create_string_buffer(1) + buffer[0] = chr(regval) + + # Write to eeprom + eeprom = open(self.port_to_eeprom_mapping[port_num], "r+b") + eeprom.seek(93) + eeprom.write(buffer[0]) + return True + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) def reset(self, port_num): raise NotImplementedError - 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 + @property + def _get_presence_bitmap(self): + + bits = [] + for x in range(self.port_start, self.port_end+1): + bits.append(str(int(self.get_presence(x)))) + + rev = "".join(bits[::-1]) + return int(rev,2) + + data = {'present':0} + def get_transceiver_change_event(self, timeout=0): + port_dict = {} + + if timeout == 0: + cd_ms = sys.maxint + else: + cd_ms = timeout + + #poll per second + while cd_ms > 0: + reg_value = self._get_presence_bitmap + changed_ports = self.data['present'] ^ reg_value + if changed_ports != 0: + break + time.sleep(1) + cd_ms = cd_ms - 1000 + + if changed_ports != 0: + for port in range (self.port_start, self.port_end+1): + # Mask off the bit corresponding to our port + mask = (1 << (port - self.port_start)) + if changed_ports & mask: + if (reg_value & mask) == 0: + port_dict[port] = SFP_STATUS_REMOVED + else: + port_dict[port] = SFP_STATUS_INSERTED + + # Update cache + self.data['present'] = reg_value + return True, port_dict + else: + return True, {} + return False, {} + diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as4630_54pe-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44bad6494229 --- /dev/null +++ b/device/accton/x86_64-accton_as4630_54pe-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/device/accton/x86_64-accton_as5712_54x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as5712_54x-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44bad6494229 --- /dev/null +++ b/device/accton/x86_64-accton_as5712_54x-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/port_config.ini b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/port_config.ini new file mode 100644 index 000000000000..857a8987bc13 --- /dev/null +++ b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/port_config.ini @@ -0,0 +1,73 @@ +# name lanes alias index speed autoneg +Ethernet0 14 tenGigE0 1 10000 1 +Ethernet1 13 tenGigE1 2 10000 1 +Ethernet2 16 tenGigE2 3 10000 1 +Ethernet3 15 tenGigE3 4 10000 1 +Ethernet4 22 tenGigE4 5 10000 1 +Ethernet5 21 tenGigE5 6 10000 1 +Ethernet6 24 tenGigE6 7 10000 1 +Ethernet7 23 tenGigE7 8 10000 1 +Ethernet8 26 tenGigE8 9 10000 1 +Ethernet9 25 tenGigE9 10 10000 1 +Ethernet10 28 tenGigE10 11 10000 1 +Ethernet11 27 tenGigE11 12 10000 1 +Ethernet12 30 tenGigE12 13 10000 1 +Ethernet13 29 tenGigE13 14 10000 1 +Ethernet14 32 tenGigE14 15 10000 1 +Ethernet15 31 tenGigE15 16 10000 1 +Ethernet16 46 tenGigE16 17 10000 1 +Ethernet17 45 tenGigE17 18 10000 1 +Ethernet18 48 tenGigE18 19 10000 1 +Ethernet19 47 tenGigE19 20 10000 1 +Ethernet20 50 tenGigE20 21 10000 1 +Ethernet21 49 tenGigE21 22 10000 1 +Ethernet22 52 tenGigE22 23 10000 1 +Ethernet23 51 tenGigE23 24 10000 1 +Ethernet24 54 tenGigE24 25 10000 1 +Ethernet25 53 tenGigE25 26 10000 1 +Ethernet26 56 tenGigE26 27 10000 1 +Ethernet27 55 tenGigE27 28 10000 1 +Ethernet28 58 tenGigE28 29 10000 1 +Ethernet29 57 tenGigE29 30 10000 1 +Ethernet30 60 tenGigE30 31 10000 1 +Ethernet31 59 tenGigE31 32 10000 1 +Ethernet32 62 tenGigE32 33 10000 1 +Ethernet33 61 tenGigE33 34 10000 1 +Ethernet34 64 tenGigE34 35 10000 1 +Ethernet35 63 tenGigE35 36 10000 1 +Ethernet36 66 tenGigE36 37 10000 1 +Ethernet37 65 tenGigE37 38 10000 1 +Ethernet38 68 tenGigE38 39 10000 1 +Ethernet39 67 tenGigE39 40 10000 1 +Ethernet40 70 tenGigE40 41 10000 1 +Ethernet41 69 tenGigE41 42 10000 1 +Ethernet42 72 tenGigE42 43 10000 1 +Ethernet43 71 tenGigE43 44 10000 1 +Ethernet44 74 tenGigE44 45 10000 1 +Ethernet45 73 tenGigE45 46 10000 1 +Ethernet46 76 tenGigE46 47 10000 1 +Ethernet47 75 tenGigE47 48 10000 1 +Ethernet48 97 tenGigE48 49 10000 0 +Ethernet49 98 tenGigE49 49 10000 0 +Ethernet50 99 tenGigE50 49 10000 0 +Ethernet51 100 tenGigE51 49 10000 0 +Ethernet52 101 tenGigE52 50 10000 0 +Ethernet53 102 tenGigE53 50 10000 0 +Ethernet54 103 tenGigE54 50 10000 0 +Ethernet55 104 tenGigE55 50 10000 0 +Ethernet56 77 tenGigE56 51 10000 0 +Ethernet57 78 tenGigE57 51 10000 0 +Ethernet58 79 tenGigE58 51 10000 0 +Ethernet59 80 tenGigE59 51 10000 0 +Ethernet60 105 tenGigE60 52 10000 0 +Ethernet61 106 tenGigE61 52 10000 0 +Ethernet62 107 tenGigE62 52 10000 0 +Ethernet63 108 tenGigE63 52 10000 0 +Ethernet64 109 tenGigE64 53 10000 0 +Ethernet65 110 tenGigE65 53 10000 0 +Ethernet66 111 tenGigE66 53 10000 0 +Ethernet67 112 tenGigE67 53 10000 0 +Ethernet68 81 tenGigE68 54 10000 0 +Ethernet69 82 tenGigE69 54 10000 0 +Ethernet70 83 tenGigE70 54 10000 0 +Ethernet71 84 tenGigE71 54 10000 0 diff --git a/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile new file mode 100644 index 000000000000..dc4f243953bf --- /dev/null +++ b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-as5812t-72x10G.config.bcm diff --git a/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/td2-as5812t-72x10G.config.bcm b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/td2-as5812t-72x10G.config.bcm new file mode 100644 index 000000000000..b55558521094 --- /dev/null +++ b/device/accton/x86_64-accton_as5812_54t-r0/Accton-AS5812-54T/td2-as5812t-72x10G.config.bcm @@ -0,0 +1,194 @@ +bcm_num_cos=8 +bcm_stat_flags=0 +bcm_stat_interval=2000000 +bcm_tunnel_term_compatible_mode=1 + +cdma_timeout_usec=3000000 + +fpem_mem_entries=16384 + +ipv6_lpm_128b_enable=0x1 +ifp_inports_support_enable=1 + +l2xmsg_mode=1 +l2_mem_entries=32768 + +l3_alpm_enable=2 +l3_max_ecmp_mode=1 +l3_mem_entries=16384 +l3_alpm_ipv6_128b_bkt_rsvd=1 + +load_firmware=0x101 + +max_vp_lags=0 +module_64ports=1 +miim_intr_enable=0 +mem_cache_enable=0 +mdio_output_delay=15 + +os=unix +oversubscribe_mode=1 + +parity_enable=0 +port_flex_enable=1 +parity_correction=0 +phy_ext_rom_boot_xe=0 +phy_aux_voltage_enable=1 + +#for 72 ports with 48 10G ports and 6 40G ports for breakout mode +pbmp_xport_xe=0x7fffffffffffffffffe +pbmp_oversubscribe=0x7fffffffffffffffffe + +rate_ext_mdio_divisor=96 + +schan_intr_enable=0 +skip_L2_USER_ENTRY=0 +stable_size=0x2000000 +stable_size=0x5500000 ;Specify the stable cache size in bytes used for Warm boot operations + +tdma_timeout_usec=3000000 + +#port-lanes configuration +portmap_1=14:10 +portmap_2=13:10 +portmap_3=16:10 +portmap_4=15:10 +port_phy_addr_1=0x1 +port_phy_addr_2=0x0 +port_phy_addr_3=0x3 +port_phy_addr_4=0x2 + +portmap_5=22:10 +portmap_6=21:10 +portmap_7=24:10 +portmap_8=23:10 +port_phy_addr_5=0x5 +port_phy_addr_6=0x4 +port_phy_addr_7=0x7 +port_phy_addr_8=0x6 + +portmap_9=26:10 +portmap_10=25:10 +portmap_11=28:10 +portmap_12=27:10 +port_phy_addr_9=0x9 +port_phy_addr_10=0x8 +port_phy_addr_11=0xb +port_phy_addr_12=0xa + +portmap_13=30:10 +portmap_14=29:10 +portmap_15=32:10 +portmap_16=31:10 +port_phy_addr_13=0x21 +port_phy_addr_14=0x20 +port_phy_addr_15=0x23 +port_phy_addr_16=0x22 + +portmap_17=46:10 +portmap_18=45:10 +portmap_19=48:10 +portmap_20=47:10 +port_phy_addr_17=0x25 +port_phy_addr_18=0x24 +port_phy_addr_19=0x27 +port_phy_addr_20=0x26 + +portmap_21=50:10 +portmap_22=49:10 +portmap_23=52:10 +portmap_24=51:10 +port_phy_addr_21=0x29 +port_phy_addr_22=0x28 +port_phy_addr_23=0x2b +port_phy_addr_24=0x2a + +portmap_25=54:10 +portmap_26=53:10 +portmap_27=56:10 +portmap_28=55:10 +port_phy_addr_25=0x41 +port_phy_addr_26=0x40 +port_phy_addr_27=0x43 +port_phy_addr_28=0x42 + +portmap_29=58:10 +portmap_30=57:10 +portmap_31=60:10 +portmap_32=59:10 +port_phy_addr_29=0x45 +port_phy_addr_30=0x44 +port_phy_addr_31=0x47 +port_phy_addr_32=0x46 + +portmap_33=62:10 +portmap_34=61:10 +portmap_35=64:10 +portmap_36=63:10 +port_phy_addr_33=0x49 +port_phy_addr_34=0x48 +port_phy_addr_35=0x4b +port_phy_addr_36=0x4a + +portmap_37=66:10 +portmap_38=65:10 +portmap_39=68:10 +portmap_40=67:10 +port_phy_addr_37=0x61 +port_phy_addr_38=0x60 +port_phy_addr_39=0x63 +port_phy_addr_40=0x62 + +portmap_41=70:10 +portmap_42=69:10 +portmap_43=72:10 +portmap_44=71:10 +port_phy_addr_41=0x65 +port_phy_addr_42=0x64 +port_phy_addr_43=0x67 +port_phy_addr_44=0x66 + +portmap_45=74:10 +portmap_46=73:10 +portmap_47=76:10 +portmap_48=75:10 +port_phy_addr_45=0x69 +port_phy_addr_46=0x68 +port_phy_addr_47=0x6b +port_phy_addr_48=0x6a + +#port_49 +portmap_49=97:10 +portmap_50=98:10 +portmap_51=99:10 +portmap_52=100:10 + +#port_50 +portmap_53=101:10 +portmap_54=102:10 +portmap_55=103:10 +portmap_56=104:10 + +#port_51 +portmap_57=77:10 +portmap_58=78:10 +portmap_59=79:10 +portmap_60=80:10 + +#port_52 +portmap_61=105:10 +portmap_62=106:10 +portmap_63=107:10 +portmap_64=108:10 + +#port_53 +portmap_65=109:10 +portmap_66=110:10 +portmap_67=111:10 +portmap_68=112:10 + +#port_54 +portmap_69=81:10 +portmap_70=82:10 +portmap_71=83:10 +portmap_72=84:10 \ No newline at end of file diff --git a/device/accton/x86_64-accton_as5812_54t-r0/default_sku b/device/accton/x86_64-accton_as5812_54t-r0/default_sku new file mode 100644 index 000000000000..87b99bac77be --- /dev/null +++ b/device/accton/x86_64-accton_as5812_54t-r0/default_sku @@ -0,0 +1 @@ +Accton-AS5812-54T t1 diff --git a/device/accton/x86_64-accton_as5812_54t-r0/installer.conf b/device/accton/x86_64-accton_as5812_54t-r0/installer.conf new file mode 100644 index 000000000000..14404194ef53 --- /dev/null +++ b/device/accton/x86_64-accton_as5812_54t-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_PORT=0x2f8 +CONSOLE_DEV=1 +CONSOLE_SPEED=115200 diff --git a/device/accton/x86_64-accton_as5812_54t-r0/led_proc_init.soc b/device/accton/x86_64-accton_as5812_54t-r0/led_proc_init.soc new file mode 100644 index 000000000000..954446d4a8ba --- /dev/null +++ b/device/accton/x86_64-accton_as5812_54t-r0/led_proc_init.soc @@ -0,0 +1,94 @@ +# LED setting for active +# ----------------------------------------------------------------------------- +# for as5812_54t (48xg+6qxg) +# +# on green - if link up +# off - if link down +# blink - if active +# ----------------------------------------------------------------------------- + +m xlmac_rx_ctrl.xe0-xe47 STRICT_PREAMBLE=0 + +link on +link off + +m CMIC_LEDUP0_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=12 REMAP_PORT_1=13 REMAP_PORT_2=14 REMAP_PORT_3=15 +m CMIC_LEDUP0_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=8 REMAP_PORT_5=9 REMAP_PORT_6=10 REMAP_PORT_7=11 +m CMIC_LEDUP0_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=4 REMAP_PORT_9=5 REMAP_PORT_10=6 REMAP_PORT_11=7 +m CMIC_LEDUP0_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=0 REMAP_PORT_13=1 REMAP_PORT_14=2 REMAP_PORT_15=3 +m CMIC_LEDUP0_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=16 REMAP_PORT_17=17 REMAP_PORT_18=18 REMAP_PORT_19=19 +m CMIC_LEDUP0_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=63 REMAP_PORT_21=62 REMAP_PORT_22=61 REMAP_PORT_23=60 +m CMIC_LEDUP0_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=63 REMAP_PORT_25=62 REMAP_PORT_26=61 REMAP_PORT_27=60 +m CMIC_LEDUP0_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=63 REMAP_PORT_29=62 REMAP_PORT_30=61 REMAP_PORT_31=60 +m CMIC_LEDUP0_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=63 REMAP_PORT_33=62 REMAP_PORT_34=61 REMAP_PORT_35=60 +m CMIC_LEDUP0_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=28 REMAP_PORT_37=29 REMAP_PORT_38=30 REMAP_PORT_39=31 +m CMIC_LEDUP0_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=24 REMAP_PORT_41=25 REMAP_PORT_42=26 REMAP_PORT_43=27 +m CMIC_LEDUP0_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=20 REMAP_PORT_45=21 REMAP_PORT_46=22 REMAP_PORT_47=23 +m CMIC_LEDUP0_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=32 REMAP_PORT_49=33 REMAP_PORT_50=34 REMAP_PORT_51=35 +m CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=63 REMAP_PORT_53=62 REMAP_PORT_54=61 REMAP_PORT_55=60 +m CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=63 REMAP_PORT_57=62 REMAP_PORT_58=61 REMAP_PORT_59=60 +m CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=63 REMAP_PORT_61=62 REMAP_PORT_62=61 REMAP_PORT_63=60 + +m CMIC_LEDUP1_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=63 REMAP_PORT_1=63 REMAP_PORT_2=63 REMAP_PORT_3=63 +m CMIC_LEDUP1_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=63 REMAP_PORT_5=63 REMAP_PORT_6=63 REMAP_PORT_7=63 +m CMIC_LEDUP1_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=63 REMAP_PORT_9=63 REMAP_PORT_10=63 REMAP_PORT_11=63 +m CMIC_LEDUP1_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=63 REMAP_PORT_13=63 REMAP_PORT_14=63 REMAP_PORT_15=63 +m CMIC_LEDUP1_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=19 REMAP_PORT_17=18 REMAP_PORT_18=17 REMAP_PORT_19=16 +m CMIC_LEDUP1_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=15 REMAP_PORT_21=14 REMAP_PORT_22=13 REMAP_PORT_23=12 +m CMIC_LEDUP1_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=7 REMAP_PORT_25=6 REMAP_PORT_26=5 REMAP_PORT_27=4 +m CMIC_LEDUP1_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=3 REMAP_PORT_29=2 REMAP_PORT_30=1 REMAP_PORT_31=0 +m CMIC_LEDUP1_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=23 REMAP_PORT_33=22 REMAP_PORT_34=21 REMAP_PORT_35=20 +m CMIC_LEDUP1_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=63 REMAP_PORT_37=63 REMAP_PORT_38=63 REMAP_PORT_39=63 +m CMIC_LEDUP1_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=63 REMAP_PORT_41=63 REMAP_PORT_42=63 REMAP_PORT_43=63 +m CMIC_LEDUP1_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=63 REMAP_PORT_45=63 REMAP_PORT_46=63 REMAP_PORT_47=63 +m CMIC_LEDUP1_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=11 REMAP_PORT_49=10 REMAP_PORT_50=9 REMAP_PORT_51=8 +m CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=24 REMAP_PORT_53=25 REMAP_PORT_54=26 REMAP_PORT_55=27 +m CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=28 REMAP_PORT_57=29 REMAP_PORT_58=30 REMAP_PORT_59=31 +m CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=32 REMAP_PORT_61=33 REMAP_PORT_62=34 REMAP_PORT_63=35 +led 0 stop +led 0 prog \ +02 F9 42 80 02 F7 42 00 02 F8 42 00 02 F4 42 48 \ +02 F3 42 24 06 F5 D2 00 74 1E 02 F5 42 05 67 4B \ +86 F8 06 F3 D6 F8 74 1E 86 F0 3E F4 06 F8 88 4A \ +03 75 3C 4A 04 71 41 67 7D 67 91 57 67 7D 67 91 \ +57 67 91 67 7D 57 67 7D 67 7D 57 06 F8 88 80 4A \ +00 27 97 75 46 90 4A 00 27 4A 01 27 B7 97 71 62 \ +77 2C 06 F5 D6 F0 74 75 02 F5 4A 07 37 4E 07 02 \ +F0 42 00 4E 07 06 F5 0A 07 71 46 77 2C 16 F7 06 \ +F9 17 4D DA 07 74 8E 12 F7 52 00 86 F9 57 86 F7 \ +57 16 F7 06 F9 07 4D DA 07 74 A2 12 F7 52 00 86 \ +F9 57 86 F7 57 00 00 00 00 00 00 00 00 00 00 00 \ +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \ +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \ +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \ +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \ +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +led 0 start + +led 1 stop +led 1 prog \ +02 F9 42 80 02 F7 42 00 02 F8 42 00 02 F4 42 36 \ +02 F3 42 24 02 F6 17 4E 01 67 AD 86 F8 67 AD 86 \ +F8 67 AD 86 F8 67 AD 86 F8 06 F8 D2 18 74 19 12 \ +01 02 10 60 F8 67 7E 12 01 02 0C 60 F8 67 7E 12 \ +01 02 04 60 F8 67 7E 12 01 02 00 60 F8 67 7E 12 \ +01 02 08 60 F8 67 7E 12 01 02 14 60 F8 67 7E 02 \ +F6 07 4E 01 02 18 60 F8 67 AD 86 F8 06 F3 D6 F8 \ +74 68 86 F0 3E F4 16 E0 5A 00 71 AD 77 A2 1A 00 \ +75 AD 77 A2 02 F6 4A 01 71 9F 06 F8 88 4A 03 75 \ +95 4A 04 71 9A 67 DF 67 E3 57 67 E3 67 DF 57 67 \ +E3 57 02 F6 4A 01 71 AA 67 DF 67 DF 57 06 F8 88 \ +80 4A 00 27 97 75 A2 90 4A 00 27 4A 01 27 B7 97 \ +71 C4 77 84 06 F5 D6 F0 74 D7 02 F5 4A 07 37 4E \ +07 02 F0 42 00 4E 07 06 F5 0A 07 71 A2 77 84 22 \ +01 77 E5 22 00 16 F7 06 F9 97 4D DA 07 74 F6 12 \ +F7 52 00 86 F9 57 86 F7 57 00 00 00 00 00 00 00 + + +led 1 start + +link on +led auto on +set RCError=off + diff --git a/device/accton/x86_64-accton_as5812_54t-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as5812_54t-r0/plugins/eeprom.py new file mode 100644 index 000000000000..7681caafeef4 --- /dev/null +++ b/device/accton/x86_64-accton_as5812_54t-r0/plugins/eeprom.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +try: + import exceptions + import binascii + import time + import optparse + import warnings + import os + import sys + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + import subprocess +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/bus/i2c/devices/1-0057/eeprom" + #Two i2c buses might get flipped order, check them both. + if not os.path.exists(self.eeprom_path): + self.eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as5812_54t-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as5812_54t-r0/plugins/psuutil.py new file mode 100755 index 000000000000..cfcd62e5828e --- /dev/null +++ b/device/accton/x86_64-accton_as5812_54t-r0/plugins/psuutil.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python + +############################################################################# +# Accton +# +# Module contains an implementation of SONiC PSU Base API and +# provides the PSUs status which are available in the platform +# +############################################################################# + +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + self.psu_path = "/sys/bus/i2c/devices/" + self.psu_presence = "/psu_present" + self.psu_oper_status = "/psu_power_good" + self.psu_mapping = { + 1: ["11-0038", "11-0050"], + 2: ["12-003b", "12-0053"], + } + + def get_num_psus(self): + return len(self.psu_mapping) + + def get_psu_status(self, index): + if index is None: + return False + + status = 0 + lst = self.psu_mapping[index] + for i in lst: + node = self.psu_path + i + self.psu_oper_status + try: + with open(node, 'r') as power_status: + status += int(power_status.read()) + except IOError: + return False + + return status > 0 + + def get_psu_presence(self, index): + if index is None: + return False + + status = 0 + lst = self.psu_mapping[index] + for i in lst: + node = self.psu_path + i + self.psu_presence + try: + with open(node, 'r') as presence_status: + status += int(presence_status.read()) + except IOError: + return False + + return status > 0 diff --git a/device/accton/x86_64-accton_as5812_54t-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as5812_54t-r0/plugins/sfputil.py new file mode 100755 index 000000000000..c9f3008dcc55 --- /dev/null +++ b/device/accton/x86_64-accton_as5812_54t-r0/plugins/sfputil.py @@ -0,0 +1,290 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# +try: + import time + import os + import pickle + from ctypes import create_string_buffer + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +#from xcvrd +SFP_STATUS_INSERTED = '1' +SFP_STATUS_REMOVED = '0' + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 49 + PORT_END = 54 + PORTS_IN_BLOCK = 54 + QSFP_PORT_START = 49 + QSFP_PORT_END = 54 + + BASE_VAL_PATH = "/sys/class/i2c-adapter/i2c-{0}/{1}-0050/" + BASE_OOM_PATH = "/sys/bus/i2c/devices/{0}-0050/" + BASE_CPLD_PATH = "/sys/bus/i2c/devices/{0}-0060/" + I2C_BUS_ORDER = -1 + + #The sidebands of QSFP is different. + #present is in-order. + #But lp_mode and reset are not. + qsfp_sb_map = [0, 2, 4, 1, 3, 5] + + _port_to_is_present = {} + _port_to_lp_mode = {} + + _port_to_eeprom_mapping = {} + _port_to_i2c_mapping = { + 49: [1,4],#QSFP_start + 50: [2,6], + 51: [3,3], + 52: [4,5], + 53: [5,7], + 54: [6,2], + } + + @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(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + eeprom_path = self.BASE_OOM_PATH + "eeprom" + + for x in range(self.port_start, self.port_end+1): + self.port_to_eeprom_mapping[x] = eeprom_path.format( + self._port_to_i2c_mapping[x][1] + ) + SfpUtilBase.__init__(self) + + #Two i2c buses might get flipped order, check them both. + def update_i2c_order(self): + if os.path.exists("/tmp/accton_util.p"): + self.I2C_BUS_ORDER = pickle.load(open("/tmp/accton_util.p", "rb")) + else: + if self.I2C_BUS_ORDER < 0: + eeprom_path = "/sys/bus/i2c/devices/1-0057/eeprom" + if os.path.exists(eeprom_path): + self.I2C_BUS_ORDER = 0 + eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" + if os.path.exists(eeprom_path): + self.I2C_BUS_ORDER = 1 + return self.I2C_BUS_ORDER + + 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 + + order = self.update_i2c_order() + present_path = self.BASE_CPLD_PATH.format(order) + present_path = present_path + "module_present_" + str(port_num) + self.__port_to_is_present = present_path + + try: + val_file = open(self.__port_to_is_present) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = val_file.readline().rstrip() + val_file.close() + + # content is a string, either "0" or "1" + if content == "1": + return True + + return False + + def get_low_power_mode_cpld(self, port_num): + if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: + return False + + order = self.update_i2c_order() + lp_mode_path = self.BASE_CPLD_PATH.format(order) + lp_mode_path = lp_mode_path + "module_lp_mode_" + lp_mode_path = lp_mode_path + str(port_num) + + try: + val_file = open(lp_mode_path) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = val_file.readline().rstrip() + val_file.close() + + # content is a string, either "0" or "1" + if content == "1": + return True + + return False + + def get_low_power_mode(self, port_num): + if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: + return False + + if not self.get_presence(port_num): + return self.get_low_power_mode_cpld(port_num) + + try: + eeprom = None + eeprom = open(self.port_to_eeprom_mapping[port_num], "rb") + eeprom.seek(93) + lpmode = ord(eeprom.read(1)) + + if not (lpmode & 0x1): # 'Power override' bit is 0 + return self.get_low_power_mode_cpld(port_num) + else: + if ((lpmode & 0x2) == 0x2): + return True # Low Power Mode if "Power set" bit is 1 + else: + return False # High Power Mode if "Power set" bit is 0 + except IOError as err: + print "Error: unable to open file: %s" % str(err) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + def set_low_power_mode(self, port_num, lpmode): + if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: + return False + + try: + eeprom = None + + if not self.get_presence(port_num): + return False # Port is not present, unable to set the eeprom + + # Fill in write buffer + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + buffer = create_string_buffer(1) + buffer[0] = chr(regval) + + # Write to eeprom + eeprom = open(self.port_to_eeprom_mapping[port_num], "r+b") + eeprom.seek(93) + eeprom.write(buffer[0]) + return True + except IOError as err: + print "Error: unable to open file: %s" % str(err) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + def reset(self, port_num): + if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: + return False + + order = self.update_i2c_order() + lp_mode_path = self.BASE_CPLD_PATH.format(order) + mod_rst_path = lp_mode_path + "module_reset_" + mod_rst_path = mod_rst_path + str(port_num) + print(mod_rst_path) + + try: + reg_file = open(mod_rst_path, 'r+', buffering=0) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + #toggle reset + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + return True + + @property + def _get_presence_bitmap(self): + nodes = [] + order = self.update_i2c_order() + + present_path = self.BASE_CPLD_PATH.format(order) + nodes.append(present_path + "module_present_all") + + bitmap = "" + for node in nodes: + try: + reg_file = open(node) + + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + bitmap += reg_file.readline().rstrip() + " " + reg_file.close() + + rev = bitmap.split(" ") + rev = "".join(rev[::-1]) + return int(rev,16) + + + data = {'present':0} + def get_transceiver_change_event(self, timeout=2000): + port_dict = {} + port = 0 + + if timeout == 0: + cd_ms = sys.maxint + else: + cd_ms = timeout + + #poll per second + while cd_ms > 0: + reg_value = self._get_presence_bitmap + changed_ports = self.data['present'] ^ reg_value + if changed_ports != 0: + break + time.sleep(1) + cd_ms = cd_ms - 1000 + + if changed_ports: + for port in range (self.port_start, self.port_end+1): + # Mask off the bit corresponding to our port + fp_port = self._port_to_i2c_mapping[port][0] + mask = (1 << (fp_port - 1)) + if changed_ports & mask: + + if (reg_value & mask) == 0: + port_dict[port] = SFP_STATUS_REMOVED + else: + port_dict[port] = SFP_STATUS_INSERTED + + # Update cache + self.data['present'] = reg_value + + return True, port_dict + else: + return True, {} + return False, {} + diff --git a/device/accton/x86_64-accton_as5812_54t-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as5812_54t-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44bad6494229 --- /dev/null +++ b/device/accton/x86_64-accton_as5812_54t-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/device/accton/x86_64-accton_as5812_54x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as5812_54x-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44bad6494229 --- /dev/null +++ b/device/accton/x86_64-accton_as5812_54x-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/device/accton/x86_64-accton_as5835_54t-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as5835_54t-r0/plugins/sfputil.py index 58ed8007a477..4fcbdb022579 100644 --- a/device/accton/x86_64-accton_as5835_54t-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as5835_54t-r0/plugins/sfputil.py @@ -11,6 +11,8 @@ except ImportError as e: raise ImportError("%s - required module not found" % str(e)) +SFP_STATUS_INSERTED = '1' +SFP_STATUS_REMOVED = '0' class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" @@ -216,10 +218,90 @@ 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 + @property + def _get_presence_bitmap(self): + + bitmap = "" + try: + reg_file = open("/sys/bus/i2c/devices/3-0062/module_present_all") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + bitmap += reg_file.readline().rstrip() + " " + reg_file.close() + + rev = bitmap.split(" ") + rev.pop() # Remove the last useless character + + # Save port 49-54 into buffer + tmp = rev.pop() + + # Insert port 1-48 + for i in range (0, 6): + rev.append(hex(0)[2:]) + rev[i] = rev[i].zfill(2) + + # Expand port 49-54 + for i in range (0, 6): + val = (int(tmp,16) >> i) & 0x1 + rev.append(hex(val)[2:]) + + rev = "".join(rev[::-1]) + return int(rev,16) + + data = {'valid':0, 'present':0} + def get_transceiver_change_event(self, timeout=0): + + start_time = time.time() + port_dict = {} + port = 0 + blocking = False + + if timeout == 0: + blocking = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + print "get_transceiver_change_event:Invalid timeout value", timeout + return False, {} + + end_time = start_time + timeout + if start_time > end_time: + print 'get_transceiver_change_event:' \ + 'time wrap / invalid timeout value', timeout + + return False, {} # Time wrap or possibly incorrect timeout + + while timeout >= 0: + # Check for OIR events and return updated port_dict + + reg_value = self._get_presence_bitmap + changed_ports = self.data['present'] ^ reg_value + if changed_ports: + for port in range (self.port_start, self.port_end+1): + # Mask off the bit corresponding to our port + mask = (1 << (port - 1)) + if changed_ports & mask: + + if (reg_value & mask) == 0: + port_dict[port] = SFP_STATUS_REMOVED + else: + port_dict[port] = SFP_STATUS_INSERTED + + # Update cache + self.data['present'] = reg_value + self.data['valid'] = 1 + return True, port_dict + + if blocking: + 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_transceiver_change_event: Should not reach here." + return False, {} diff --git a/device/accton/x86_64-accton_as5835_54t-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as5835_54t-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44bad6494229 --- /dev/null +++ b/device/accton/x86_64-accton_as5835_54t-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/td3-as5835-48x10G+6x100G.config.bcm b/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/mv2-as5835-48x10G+6x100G.config.bcm similarity index 100% rename from device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/td3-as5835-48x10G+6x100G.config.bcm rename to device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/mv2-as5835-48x10G+6x100G.config.bcm diff --git a/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile b/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile index 04c02ee5861d..8b795f81c4f2 100644 --- a/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile +++ b/device/accton/x86_64-accton_as5835_54x-r0/Accton-AS5835-54X/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/etc/bcm/td3-as5835-48x10G+6x100G.config.bcm +SAI_INIT_CONFIG_FILE=/etc/bcm/mv2-as5835-48x10G+6x100G.config.bcm diff --git a/device/accton/x86_64-accton_as5835_54x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as5835_54x-r0/plugins/sfputil.py index 9a9db688e7dc..ba8e6181ebe8 100644 --- a/device/accton/x86_64-accton_as5835_54x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as5835_54x-r0/plugins/sfputil.py @@ -11,6 +11,8 @@ except ImportError as e: raise ImportError("%s - required module not found" % str(e)) +SFP_STATUS_INSERTED = '1' +SFP_STATUS_REMOVED = '0' class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" @@ -216,7 +218,7 @@ def get_low_power_mode(self, port_num): try: eeprom = None - eeprom = open(self.port_to_eeprom_mapping[port_num], "rb") + eeprom = open(self.port_to_eeprom_mapping[port_num], mode="rb", buffering=0) eeprom.seek(93) lpmode = ord(eeprom.read(1)) @@ -251,7 +253,7 @@ def set_low_power_mode(self, port_num, lpmode): buffer[0] = chr(regval) # Write to eeprom - eeprom = open(self.port_to_eeprom_mapping[port_num], "r+b") + eeprom = open(self.port_to_eeprom_mapping[port_num], mode="r+b", buffering=0) eeprom.seek(93) eeprom.write(buffer[0]) return True @@ -273,7 +275,7 @@ def reset(self, port_num): path = "/sys/bus/i2c/devices/{0}/module_reset_{1}" port_ps = path.format(cpld_ps, cage_num) try: - reg_file = open(port_ps, 'w') + reg_file = open(port_ps, mode='w', buffering=0) except IOError as e: print "Error: unable to open file: %s" % str(e) return False @@ -288,10 +290,97 @@ 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 + @property + def _get_presence_bitmap(self): + nodes = [] + nodes.append("/sys/bus/i2c/devices/3-0061/module_present_all") + nodes.append("/sys/bus/i2c/devices/3-0062/module_present_all") + + bitmap = "" + for node in nodes: + try: + reg_file = open(node) + + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + bitmap += reg_file.readline().rstrip() + " " + reg_file.close() + + rev = bitmap.split(" ") + rev.pop() # Remove the last useless character + + # Convert bitmap into continuously port order + rev[4] = hex((int(rev[4],16) | ((int(rev[5],16) & 0x3) << 6)))[2:] # Port 33-40 + rev[5] = hex((int(rev[5],16) >> 2) | ((int(rev[6],16) & 0x3) << 6))[2:] # Port 41-48 + + # Expand port 49-54 + tmp = rev.pop() + for i in range (2, 8): + val = (int(tmp,16) >> i) & 0x1 + rev.append(hex(val)[2:]) + + for i in range (0,6): + rev[i] = rev[i].zfill(2) + + rev = "".join(rev[::-1]) + return int(rev,16) + + data = {'valid':0, 'present':0} + def get_transceiver_change_event(self, timeout=0): + + start_time = time.time() + port_dict = {} + port = 0 + blocking = False + + if timeout == 0: + blocking = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + print "get_transceiver_change_event:Invalid timeout value", timeout + return False, {} + + end_time = start_time + timeout + if start_time > end_time: + print 'get_transceiver_change_event:' \ + 'time wrap / invalid timeout value', timeout + + return False, {} # Time wrap or possibly incorrect timeout + + while timeout >= 0: + # Check for OIR events and return updated port_dict + + reg_value = self._get_presence_bitmap + changed_ports = self.data['present'] ^ reg_value + if changed_ports: + for port in range (self.port_start, self.port_end+1): + # Mask off the bit corresponding to our port + mask = (1 << (port - 1)) + if changed_ports & mask: + + if (reg_value & mask) == 0: + port_dict[port] = SFP_STATUS_REMOVED + else: + port_dict[port] = SFP_STATUS_INSERTED + + # Update cache + self.data['present'] = reg_value + self.data['valid'] = 1 + return True, port_dict + + if blocking: + 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_transceiver_change_event: Should not reach here." + return False, {} + + diff --git a/device/accton/x86_64-accton_as5835_54x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as5835_54x-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44bad6494229 --- /dev/null +++ b/device/accton/x86_64-accton_as5835_54x-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/device/accton/x86_64-accton_as6712_32x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as6712_32x-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44bad6494229 --- /dev/null +++ b/device/accton/x86_64-accton_as6712_32x-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers.json.j2 b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/buffers.json.j2 similarity index 100% rename from device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers.json.j2 rename to device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/buffers.json.j2 diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers_defaults_t0.j2 b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/buffers_defaults_t0.j2 similarity index 96% rename from device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers_defaults_t0.j2 rename to device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/buffers_defaults_t0.j2 index 300fecdb3555..a47675b8dfa4 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers_defaults_t0.j2 +++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/buffers_defaults_t0.j2 @@ -1,72 +1,72 @@ -{% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '20971328' %} -{% set ingress_lossy_pool_size = '20971328' %} -{% set egress_lossless_pool_size = '20971328' %} -{% set egress_lossy_pool_size = '20971328' %} - -{%- macro generate_port_lists(PORT_ALL) %} - {# Generate list of ports #} - {%- for port_idx in range(0, 48) %} - {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} - {%- endfor %} - {%- for port_idx in range(48, 54) %} - {%- if PORT_ALL.append("Ethernet%d" % (48 + (port_idx-48) * 4)) %}{%- endif %} - {%- endfor %} -{%- endmacro %} - -{%- macro generate_buffer_pool_and_profiles() %} - "BUFFER_POOL": { - "ingress_lossless_pool": { - "size": "{{ ingress_lossless_pool_size }}", - "type": "ingress", - "mode": "static" - }, - "ingress_lossy_pool": { - "size": "{{ ingress_lossy_pool_size }}", - "type": "ingress", - "mode": "dynamic" - }, - "egress_lossless_pool": { - "size": "{{ egress_lossless_pool_size }}", - "type": "egress", - "mode": "static" - }, - "egress_lossy_pool": { - "size": "{{ egress_lossy_pool_size }}", - "type": "egress", - "mode": "dynamic" - } - }, - "BUFFER_PROFILE": { - "ingress_lossless_profile": { - "pool":"[BUFFER_POOL|ingress_lossless_pool]", - "xon":"78400", - "xoff":"132160", - "size":"3584", - "static_th":"82880" - }, - "ingress_lossy_profile": { - "pool":"[BUFFER_POOL|ingress_lossy_pool]", - "size":"3584", - "dynamic_th":"-1" - }, - "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"3584", - "dynamic_th":"-4" - } - }, -{%- endmacro %} - -{# the typo of generate_pg_profils dued to buffers_config.j2 #} -{# Default, we do not bind any buffer profiles. #} -{%- macro generate_pg_profils(port_names) %} - "BUFFER_PG": { - } -{%- endmacro %} - -{# Default, we do not bind any buffer profiles. #} -{%- macro generate_queue_buffers(port_names) %} - "BUFFER_QUEUE": { - } +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '20971328' %} +{% set ingress_lossy_pool_size = '20971328' %} +{% set egress_lossless_pool_size = '20971328' %} +{% set egress_lossy_pool_size = '20971328' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 48) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(48, 54) %} + {%- if PORT_ALL.append("Ethernet%d" % (48 + (port_idx-48) * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "static" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xon":"78400", + "xoff":"132160", + "size":"3584", + "static_th":"82880" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"3584", + "dynamic_th":"-1" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"3584", + "dynamic_th":"-4" + } + }, +{%- endmacro %} + +{# the typo of generate_pg_profils dued to buffers_config.j2 #} +{# Default, we do not bind any buffer profiles. #} +{%- macro generate_pg_profils(port_names) %} + "BUFFER_PG": { + } +{%- endmacro %} + +{# Default, we do not bind any buffer profiles. #} +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + } {%- endmacro %} \ No newline at end of file diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers_defaults_t1.j2 b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/buffers_defaults_t1.j2 similarity index 96% rename from device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers_defaults_t1.j2 rename to device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/buffers_defaults_t1.j2 index 300fecdb3555..a47675b8dfa4 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers_defaults_t1.j2 +++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/buffers_defaults_t1.j2 @@ -1,72 +1,72 @@ -{% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '20971328' %} -{% set ingress_lossy_pool_size = '20971328' %} -{% set egress_lossless_pool_size = '20971328' %} -{% set egress_lossy_pool_size = '20971328' %} - -{%- macro generate_port_lists(PORT_ALL) %} - {# Generate list of ports #} - {%- for port_idx in range(0, 48) %} - {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} - {%- endfor %} - {%- for port_idx in range(48, 54) %} - {%- if PORT_ALL.append("Ethernet%d" % (48 + (port_idx-48) * 4)) %}{%- endif %} - {%- endfor %} -{%- endmacro %} - -{%- macro generate_buffer_pool_and_profiles() %} - "BUFFER_POOL": { - "ingress_lossless_pool": { - "size": "{{ ingress_lossless_pool_size }}", - "type": "ingress", - "mode": "static" - }, - "ingress_lossy_pool": { - "size": "{{ ingress_lossy_pool_size }}", - "type": "ingress", - "mode": "dynamic" - }, - "egress_lossless_pool": { - "size": "{{ egress_lossless_pool_size }}", - "type": "egress", - "mode": "static" - }, - "egress_lossy_pool": { - "size": "{{ egress_lossy_pool_size }}", - "type": "egress", - "mode": "dynamic" - } - }, - "BUFFER_PROFILE": { - "ingress_lossless_profile": { - "pool":"[BUFFER_POOL|ingress_lossless_pool]", - "xon":"78400", - "xoff":"132160", - "size":"3584", - "static_th":"82880" - }, - "ingress_lossy_profile": { - "pool":"[BUFFER_POOL|ingress_lossy_pool]", - "size":"3584", - "dynamic_th":"-1" - }, - "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"3584", - "dynamic_th":"-4" - } - }, -{%- endmacro %} - -{# the typo of generate_pg_profils dued to buffers_config.j2 #} -{# Default, we do not bind any buffer profiles. #} -{%- macro generate_pg_profils(port_names) %} - "BUFFER_PG": { - } -{%- endmacro %} - -{# Default, we do not bind any buffer profiles. #} -{%- macro generate_queue_buffers(port_names) %} - "BUFFER_QUEUE": { - } +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '20971328' %} +{% set ingress_lossy_pool_size = '20971328' %} +{% set egress_lossless_pool_size = '20971328' %} +{% set egress_lossy_pool_size = '20971328' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 48) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(48, 54) %} + {%- if PORT_ALL.append("Ethernet%d" % (48 + (port_idx-48) * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "static" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xon":"78400", + "xoff":"132160", + "size":"3584", + "static_th":"82880" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"3584", + "dynamic_th":"-1" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"3584", + "dynamic_th":"-4" + } + }, +{%- endmacro %} + +{# the typo of generate_pg_profils dued to buffers_config.j2 #} +{# Default, we do not bind any buffer profiles. #} +{%- macro generate_pg_profils(port_names) %} + "BUFFER_PG": { + } +{%- endmacro %} + +{# Default, we do not bind any buffer profiles. #} +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + } {%- endmacro %} \ No newline at end of file diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/led.bin b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/led.bin new file mode 100644 index 000000000000..bb4426fb59f4 Binary files /dev/null and b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/led.bin differ diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/nephos_dac.dsh b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/nephos_dac.dsh new file mode 100644 index 000000000000..42102053c3fb --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/nephos_dac.dsh @@ -0,0 +1,414 @@ +init start stage unit=0 low-level +init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true +init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true +init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true +init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true +init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true +init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true +init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true +init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true +init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true +init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true +init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true +init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true +init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true +init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true +init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true +init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true +init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true +init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true +init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true +init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true +init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=25g active=true +init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=25g active=true +init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=25g active=true +init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=25g active=true +init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=25g active=true +init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=25g active=true +init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=25g active=true +init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=25g active=true +init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=25g active=true +init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=25g active=true +init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=25g active=true +init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=25g active=true +init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=25g active=true +init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=25g active=true +init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=25g active=true +init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=25g active=true +init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=25g active=true +init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=25g active=true +init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=25g active=true +init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=25g active=true +init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=25g active=true +init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=25g active=true +init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=25g active=true +init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=25g active=true +init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=25g active=true +init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=25g active=true +init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=25g active=true +init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=25g active=true +init set port-map unit=0 port=48 eth-macro=21 lane=0 max-speed=100g active=true +init set port-map unit=0 port=49 eth-macro=20 lane=0 max-speed=100g active=true +init set port-map unit=0 port=50 eth-macro=26 lane=0 max-speed=100g active=true +init set port-map unit=0 port=51 eth-macro=27 lane=0 max-speed=100g active=true +init set port-map unit=0 port=52 eth-macro=28 lane=0 max-speed=100g active=true +init set port-map unit=0 port=53 eth-macro=29 lane=0 max-speed=100g active=true +init set port-map unit=0 port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true +init set port-map unit=0 port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true +init start stage unit=0 task-rsrc +init start stage unit=0 module +init start stage unit=0 task +phy set lane-swap unit=0 portlist=0 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=1 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=2 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=3 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=4 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=5 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=6 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=7 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=8 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=9 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=10 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=11 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=12 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=13 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=14 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=15 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=16 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=17 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=18 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=19 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=20 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=21 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=22 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=23 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=24 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=25 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=26 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=27 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=28 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=29 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=30 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=31 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=32 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=33 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=34 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=35 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=36 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=37 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=38 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=39 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=40 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=41 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=42 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=43 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=44 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=45 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=tx data=0x1.3.0.2 +phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=tx data=0x0.3.1.2 +phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x1.3.0.2 +phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x2.0.3.1 +phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=tx data=0x3.2.1.0 +phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=tx data=0x3.2.1.0 +phy set lane-swap unit=0 portlist=0 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=1 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=2 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=3 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=4 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=5 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=6 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=7 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=8 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=9 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=10 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=11 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=12 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=13 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=14 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=15 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=16 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=17 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=18 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=19 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=20 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=21 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=22 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=23 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=24 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=25 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=26 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=27 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=28 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=29 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=30 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=31 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=32 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=33 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=34 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=35 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=36 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=37 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=38 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=39 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=40 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=41 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=42 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=43 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=44 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=45 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=rx data=0x2.1.0.3 +phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=rx data=0x0.1.3.2 +phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x3.1.0.2 +phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x1.3.0.2 +phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=1 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=2 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=3 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=4 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=5 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=6 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=7 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=8 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=9 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=10 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=11 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=12 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=13 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=14 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=15 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=16 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=17 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=18 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=19 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=20 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=21 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=22 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=23 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=24 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=25 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=26 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=27 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=28 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=29 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=30 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=31 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=32 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=33 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=34 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=35 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=36 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=37 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=38 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=39 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=40 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=41 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=42 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=43 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=44 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=45 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=46 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=47 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=tx data=0x0.0.0.1 +phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=tx data=0x1.1.0.0 +phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=1 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=2 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=3 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=4 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=5 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=6 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=7 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=8 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=9 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=10 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=11 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=12 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=13 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=14 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=15 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=16 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=17 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=18 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=19 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=20 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=21 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=22 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=23 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=24 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=25 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=26 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=27 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=28 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=29 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=30 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=31 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=32 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=33 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=34 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=35 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=36 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=37 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=38 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=39 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=40 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=41 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=42 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=43 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=44 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=45 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=46 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=47 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=rx data=0x0.1.0.1 +phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=rx data=0x1.0.1.0 +phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x0.0.1.0 +phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=rx data=0x0.0.0.1 +phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set mdio portlist=0 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=1 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=2 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=3 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=4 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=5 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=6 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=7 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=8 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=9 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=10 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=11 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=12 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=13 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=14 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=15 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=16 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=17 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=18 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=19 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=20 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=21 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=22 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=23 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=24 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=25 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=26 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=27 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=28 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=29 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=30 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=31 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=32 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=33 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=34 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=35 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=36 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=37 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=38 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=39 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=40 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=41 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=42 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=43 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=44 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=45 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=46 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=47 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=48 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=49 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=50 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=51 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=52 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=53 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=129 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=130 devad=0x1E addr=0x2 data=0x0000 +port set property unit=0 portlist=0-47 speed=25g +port set property unit=0 portlist=48-53 speed=100g +port set property unit=0 portlist=129-130 speed=10g +port set property unit=0 portlist=0-47 medium-type=cr +port set property unit=0 portlist=48-53 medium-type=cr4 +port set property unit=0 portlist=129-130 medium-type=kr +port set adver unit=0 portlist=129-130 speed-10g-kr +port set property unit=0 portlist=129-130 an=enable +port set property unit=0 portlist=129-130 admin=enable +port set property unit=0 portlist=0-53 admin=disable diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/nephos_opt.dsh b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/nephos_opt.dsh similarity index 77% rename from device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/nephos_opt.dsh rename to device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/nephos_opt.dsh index 06bda1dc76a4..ca2bc6497685 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/nephos_opt.dsh +++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/nephos_opt.dsh @@ -1,63 +1,63 @@ -init start stage low-level -init set port-map port=0 eth-macro=2 lane=0 max-speed=25g active=true -init set port-map port=1 eth-macro=2 lane=1 max-speed=25g active=true -init set port-map port=2 eth-macro=2 lane=2 max-speed=25g active=true -init set port-map port=3 eth-macro=2 lane=3 max-speed=25g active=true -init set port-map port=4 eth-macro=3 lane=0 max-speed=25g active=true -init set port-map port=5 eth-macro=3 lane=1 max-speed=25g active=true -init set port-map port=6 eth-macro=3 lane=2 max-speed=25g active=true -init set port-map port=7 eth-macro=3 lane=3 max-speed=25g active=true -init set port-map port=8 eth-macro=4 lane=0 max-speed=25g active=true -init set port-map port=9 eth-macro=4 lane=1 max-speed=25g active=true -init set port-map port=10 eth-macro=4 lane=2 max-speed=25g active=true -init set port-map port=11 eth-macro=4 lane=3 max-speed=25g active=true -init set port-map port=12 eth-macro=5 lane=0 max-speed=25g active=true -init set port-map port=13 eth-macro=5 lane=1 max-speed=25g active=true -init set port-map port=14 eth-macro=5 lane=2 max-speed=25g active=true -init set port-map port=15 eth-macro=5 lane=3 max-speed=25g active=true -init set port-map port=16 eth-macro=8 lane=0 max-speed=25g active=true -init set port-map port=17 eth-macro=8 lane=1 max-speed=25g active=true -init set port-map port=18 eth-macro=8 lane=2 max-speed=25g active=true -init set port-map port=19 eth-macro=8 lane=3 max-speed=25g active=true -init set port-map port=20 eth-macro=10 lane=0 max-speed=25g active=true -init set port-map port=21 eth-macro=10 lane=1 max-speed=25g active=true -init set port-map port=22 eth-macro=10 lane=2 max-speed=25g active=true -init set port-map port=23 eth-macro=10 lane=3 max-speed=25g active=true -init set port-map port=24 eth-macro=12 lane=0 max-speed=25g active=true -init set port-map port=25 eth-macro=12 lane=1 max-speed=25g active=true -init set port-map port=26 eth-macro=12 lane=2 max-speed=25g active=true -init set port-map port=27 eth-macro=12 lane=3 max-speed=25g active=true -init set port-map port=28 eth-macro=14 lane=0 max-speed=25g active=true -init set port-map port=29 eth-macro=14 lane=1 max-speed=25g active=true -init set port-map port=30 eth-macro=14 lane=2 max-speed=25g active=true -init set port-map port=31 eth-macro=14 lane=3 max-speed=25g active=true -init set port-map port=32 eth-macro=16 lane=0 max-speed=25g active=true -init set port-map port=33 eth-macro=16 lane=1 max-speed=25g active=true -init set port-map port=34 eth-macro=16 lane=2 max-speed=25g active=true -init set port-map port=35 eth-macro=16 lane=3 max-speed=25g active=true -init set port-map port=36 eth-macro=17 lane=0 max-speed=25g active=true -init set port-map port=37 eth-macro=17 lane=1 max-speed=25g active=true -init set port-map port=38 eth-macro=17 lane=2 max-speed=25g active=true -init set port-map port=39 eth-macro=17 lane=3 max-speed=25g active=true -init set port-map port=40 eth-macro=18 lane=0 max-speed=25g active=true -init set port-map port=41 eth-macro=18 lane=1 max-speed=25g active=true -init set port-map port=42 eth-macro=18 lane=2 max-speed=25g active=true -init set port-map port=43 eth-macro=18 lane=3 max-speed=25g active=true -init set port-map port=44 eth-macro=19 lane=0 max-speed=25g active=true -init set port-map port=45 eth-macro=19 lane=1 max-speed=25g active=true -init set port-map port=46 eth-macro=19 lane=2 max-speed=25g active=true -init set port-map port=47 eth-macro=19 lane=3 max-speed=25g active=true -init set port-map port=48 eth-macro=20 lane=0 max-speed=100g active=true -init set port-map port=49 eth-macro=21 lane=0 max-speed=100g active=true -init set port-map port=50 eth-macro=26 lane=0 max-speed=100g active=true -init set port-map port=51 eth-macro=27 lane=0 max-speed=100g active=true -init set port-map port=52 eth-macro=28 lane=0 max-speed=100g active=true -init set port-map port=53 eth-macro=29 lane=0 max-speed=100g active=true -init set port-map port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true -init set port-map port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true -init start stage task-rsrc -init start stage module -init start stage task +init start stage unit=0 low-level +init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true +init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true +init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true +init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true +init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true +init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true +init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true +init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true +init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true +init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true +init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true +init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true +init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true +init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true +init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true +init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true +init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true +init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true +init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true +init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true +init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=25g active=true +init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=25g active=true +init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=25g active=true +init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=25g active=true +init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=25g active=true +init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=25g active=true +init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=25g active=true +init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=25g active=true +init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=25g active=true +init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=25g active=true +init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=25g active=true +init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=25g active=true +init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=25g active=true +init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=25g active=true +init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=25g active=true +init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=25g active=true +init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=25g active=true +init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=25g active=true +init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=25g active=true +init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=25g active=true +init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=25g active=true +init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=25g active=true +init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=25g active=true +init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=25g active=true +init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=25g active=true +init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=25g active=true +init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=25g active=true +init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=25g active=true +init set port-map unit=0 port=48 eth-macro=21 lane=0 max-speed=100g active=true +init set port-map unit=0 port=49 eth-macro=20 lane=0 max-speed=100g active=true +init set port-map unit=0 port=50 eth-macro=26 lane=0 max-speed=100g active=true +init set port-map unit=0 port=51 eth-macro=27 lane=0 max-speed=100g active=true +init set port-map unit=0 port=52 eth-macro=28 lane=0 max-speed=100g active=true +init set port-map unit=0 port=53 eth-macro=29 lane=0 max-speed=100g active=true +init set port-map unit=0 port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true +init set port-map unit=0 port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true +init start stage unit=0 task-rsrc +init start stage unit=0 module +init start stage unit=0 task phy set lane-swap portlist=0 lane-cnt=1 property=tx data=0x0 phy set lane-swap portlist=1 lane-cnt=1 property=tx data=0x1 phy set lane-swap portlist=2 lane-cnt=1 property=tx data=0x2 @@ -106,7 +106,12 @@ phy set lane-swap portlist=44 lane-cnt=1 property=tx data=0x0 phy set lane-swap portlist=45 lane-cnt=1 property=tx data=0x1 phy set lane-swap portlist=46 lane-cnt=1 property=tx data=0x2 phy set lane-swap portlist=47 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=48-53 lane-cnt=4 property=tx data=0x03.02.01.00 +phy set lane-swap portlist=48 lane-cnt=4 property=tx data=0x1.3.0.2 +phy set lane-swap portlist=49 lane-cnt=4 property=tx data=0x0.3.1.2 +phy set lane-swap portlist=50 lane-cnt=4 property=tx data=0x1.3.0.2 +phy set lane-swap portlist=51 lane-cnt=4 property=tx data=0x2.0.3.1 +phy set lane-swap portlist=52 lane-cnt=4 property=tx data=0x3.2.1.0 +phy set lane-swap portlist=53 lane-cnt=4 property=tx data=0x3.2.1.0 phy set lane-swap portlist=0 lane-cnt=1 property=rx data=0x0 phy set lane-swap portlist=1 lane-cnt=1 property=rx data=0x1 phy set lane-swap portlist=2 lane-cnt=1 property=rx data=0x2 @@ -155,7 +160,12 @@ phy set lane-swap portlist=44 lane-cnt=1 property=rx data=0x1 phy set lane-swap portlist=45 lane-cnt=1 property=rx data=0x2 phy set lane-swap portlist=46 lane-cnt=1 property=rx data=0x3 phy set lane-swap portlist=47 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=48-53 lane-cnt=4 property=rx data=0x03.02.01.00 +phy set lane-swap portlist=48 lane-cnt=4 property=rx data=0x2.1.0.3 +phy set lane-swap portlist=49 lane-cnt=4 property=rx data=0x0.1.3.2 +phy set lane-swap portlist=50 lane-cnt=4 property=rx data=0x3.1.0.2 +phy set lane-swap portlist=51 lane-cnt=4 property=rx data=0x1.3.0.2 +phy set lane-swap portlist=52 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set lane-swap portlist=53 lane-cnt=4 property=rx data=0x3.2.1.0 phy set polarity-rev portlist=0 lane-cnt=1 property=tx data=0x0 phy set polarity-rev portlist=1 lane-cnt=1 property=tx data=0x0 phy set polarity-rev portlist=2 lane-cnt=1 property=tx data=0x0 @@ -204,9 +214,9 @@ phy set polarity-rev portlist=44 lane-cnt=1 property=tx data=0x0 phy set polarity-rev portlist=45 lane-cnt=1 property=tx data=0x0 phy set polarity-rev portlist=46 lane-cnt=1 property=tx data=0x0 phy set polarity-rev portlist=47 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=48 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=48 lane-cnt=4 property=tx data=0x0.0.0.1 phy set polarity-rev portlist=49 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev portlist=50 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=50 lane-cnt=4 property=tx data=0x1.1.0.0 phy set polarity-rev portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0 @@ -258,83 +268,83 @@ phy set polarity-rev portlist=44 lane-cnt=1 property=rx data=0x0 phy set polarity-rev portlist=45 lane-cnt=1 property=rx data=0x0 phy set polarity-rev portlist=46 lane-cnt=1 property=rx data=0x0 phy set polarity-rev portlist=47 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=48 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev portlist=49 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev portlist=50 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev portlist=51 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=48 lane-cnt=4 property=rx data=0x0.1.0.1 +phy set polarity-rev portlist=49 lane-cnt=4 property=rx data=0x1.0.1.0 +phy set polarity-rev portlist=50 lane-cnt=4 property=rx data=0x0.0.1.0 +phy set polarity-rev portlist=51 lane-cnt=4 property=rx data=0x0.0.0.1 phy set polarity-rev portlist=52 lane-cnt=4 property=rx data=0x0.0.0.0 phy set polarity-rev portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0 phy set pre-emphasis portlist=0 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=0 lane-cnt=4 property=cn1 data=0x1.1.1.1 -phy set pre-emphasis portlist=0 lane-cnt=4 property=c0 data=0x1A.1A.1A.1A +phy set pre-emphasis portlist=0 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a phy set pre-emphasis portlist=0 lane-cnt=4 property=c1 data=0x7.7.7.7 phy set pre-emphasis portlist=4 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=4 lane-cnt=4 property=cn1 data=0x1.1.1.1 -phy set pre-emphasis portlist=4 lane-cnt=4 property=c0 data=0x1A.1A.1A.1A +phy set pre-emphasis portlist=4 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a phy set pre-emphasis portlist=4 lane-cnt=4 property=c1 data=0x7.7.7.7 phy set pre-emphasis portlist=8 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=8 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=8 lane-cnt=4 property=c0 data=0x1C.1C.1C.1C +phy set pre-emphasis portlist=8 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c phy set pre-emphasis portlist=8 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=12 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=12 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=12 lane-cnt=4 property=c0 data=0x1B.1B.1B.1B +phy set pre-emphasis portlist=12 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b phy set pre-emphasis portlist=12 lane-cnt=4 property=c1 data=0x7.7.7.7 phy set pre-emphasis portlist=16 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=16 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=16 lane-cnt=4 property=c0 data=0x1C.1C.1C.1C +phy set pre-emphasis portlist=16 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c phy set pre-emphasis portlist=16 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=20 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=20 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=20 lane-cnt=4 property=c0 data=0x1C.1C.1C.1C +phy set pre-emphasis portlist=20 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c phy set pre-emphasis portlist=20 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=24 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=24 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=24 lane-cnt=4 property=c0 data=0x1C.1C.1C.1C +phy set pre-emphasis portlist=24 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c phy set pre-emphasis portlist=24 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=28 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=28 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=28 lane-cnt=4 property=c0 data=0x1C.1C.1C.1C +phy set pre-emphasis portlist=28 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c phy set pre-emphasis portlist=28 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=32 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=32 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=32 lane-cnt=4 property=c0 data=0x1C.1C.1C.1C +phy set pre-emphasis portlist=32 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c phy set pre-emphasis portlist=32 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=36 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=36 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=36 lane-cnt=4 property=c0 data=0x1C.1C.1C.1C +phy set pre-emphasis portlist=36 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c phy set pre-emphasis portlist=36 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=40 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=40 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=40 lane-cnt=4 property=c0 data=0x1C.1C.1C.1C +phy set pre-emphasis portlist=40 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c phy set pre-emphasis portlist=40 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=44 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=44 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=44 lane-cnt=4 property=c0 data=0x1C.1C.1C.1C +phy set pre-emphasis portlist=44 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c phy set pre-emphasis portlist=44 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=48 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=48 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=48 lane-cnt=4 property=c0 data=0x1B.1B.1B.1B +phy set pre-emphasis portlist=48 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b phy set pre-emphasis portlist=48 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=49 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=49 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=49 lane-cnt=4 property=c0 data=0x1B.1B.1B.1B +phy set pre-emphasis portlist=49 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b phy set pre-emphasis portlist=49 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis portlist=50 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=50 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=50 lane-cnt=4 property=c0 data=0x1B.1B.1B.1B +phy set pre-emphasis portlist=50 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b phy set pre-emphasis portlist=50 lane-cnt=4 property=c1 data=0x7.7.7.7 phy set pre-emphasis portlist=51 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=51 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=51 lane-cnt=4 property=c0 data=0x1B.1B.1B.1B +phy set pre-emphasis portlist=51 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b phy set pre-emphasis portlist=51 lane-cnt=4 property=c1 data=0x7.7.7.7 phy set pre-emphasis portlist=52 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=52 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=52 lane-cnt=4 property=c0 data=0x1A.1A.1A.1A +phy set pre-emphasis portlist=52 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a phy set pre-emphasis portlist=52 lane-cnt=4 property=c1 data=0x8.8.8.8 phy set pre-emphasis portlist=53 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=53 lane-cnt=4 property=cn1 data=0x1.1.1.1 -phy set pre-emphasis portlist=53 lane-cnt=4 property=c0 data=0x1A.1A.1A.1A +phy set pre-emphasis portlist=53 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a phy set pre-emphasis portlist=53 lane-cnt=4 property=c1 data=0x7.7.7.7 phy set mdio portlist=0 devad=0x1E addr=0x2 data=0x8000 phy set mdio portlist=1 devad=0x1E addr=0x2 data=0x8000 @@ -400,5 +410,6 @@ port set property portlist=48-53 medium-type=sr4 port set property portlist=129-130 medium-type=kr port set adver portlist=129-130 speed-10g-kr port set property portlist=129-130 an=enable -port set property portlist=129-130 admin=enable -port set property portlist=0-53 admin=disable +port set property unit=0 portlist=129-130 admin=enable +port set property unit=0 portlist=0-53 admin=disable + diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/pg_profile_lookup.ini b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/pg_profile_lookup.ini similarity index 100% rename from device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/pg_profile_lookup.ini rename to device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/pg_profile_lookup.ini diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.ini b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/port_config.ini similarity index 100% rename from device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.ini rename to device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/port_config.ini diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/port_config.nps similarity index 99% rename from device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps rename to device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/port_config.nps index a4270503f34b..ca2bc6497685 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps +++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/port_config.nps @@ -412,3 +412,4 @@ port set adver portlist=129-130 speed-10g-kr port set property portlist=129-130 an=enable port set property unit=0 portlist=129-130 admin=enable port set property unit=0 portlist=0-53 admin=disable + diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/proc_init.nps b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/proc_init.nps similarity index 100% rename from device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/proc_init.nps rename to device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/proc_init.nps diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/qos.json.j2 b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/qos.json.j2 similarity index 100% rename from device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/qos.json.j2 rename to device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/qos.json.j2 diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/sai.profile b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/sai.profile new file mode 100644 index 000000000000..5e4ff9064d5b --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X-R0/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/proc_init.nps +SAI_DSH_CONFIG_FILE=/usr/share/sonic/hwsku/port_config.nps diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/nephos_dac.dsh b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/nephos_dac.dsh deleted file mode 100644 index 10a7b7a9df0e..000000000000 --- a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/nephos_dac.dsh +++ /dev/null @@ -1,404 +0,0 @@ -init start stage low-level -init set port-map port=0 eth-macro=2 lane=0 max-speed=25g active=true -init set port-map port=1 eth-macro=2 lane=1 max-speed=25g active=true -init set port-map port=2 eth-macro=2 lane=2 max-speed=25g active=true -init set port-map port=3 eth-macro=2 lane=3 max-speed=25g active=true -init set port-map port=4 eth-macro=3 lane=0 max-speed=25g active=true -init set port-map port=5 eth-macro=3 lane=1 max-speed=25g active=true -init set port-map port=6 eth-macro=3 lane=2 max-speed=25g active=true -init set port-map port=7 eth-macro=3 lane=3 max-speed=25g active=true -init set port-map port=8 eth-macro=4 lane=0 max-speed=25g active=true -init set port-map port=9 eth-macro=4 lane=1 max-speed=25g active=true -init set port-map port=10 eth-macro=4 lane=2 max-speed=25g active=true -init set port-map port=11 eth-macro=4 lane=3 max-speed=25g active=true -init set port-map port=12 eth-macro=5 lane=0 max-speed=25g active=true -init set port-map port=13 eth-macro=5 lane=1 max-speed=25g active=true -init set port-map port=14 eth-macro=5 lane=2 max-speed=25g active=true -init set port-map port=15 eth-macro=5 lane=3 max-speed=25g active=true -init set port-map port=16 eth-macro=8 lane=0 max-speed=25g active=true -init set port-map port=17 eth-macro=8 lane=1 max-speed=25g active=true -init set port-map port=18 eth-macro=8 lane=2 max-speed=25g active=true -init set port-map port=19 eth-macro=8 lane=3 max-speed=25g active=true -init set port-map port=20 eth-macro=10 lane=0 max-speed=25g active=true -init set port-map port=21 eth-macro=10 lane=1 max-speed=25g active=true -init set port-map port=22 eth-macro=10 lane=2 max-speed=25g active=true -init set port-map port=23 eth-macro=10 lane=3 max-speed=25g active=true -init set port-map port=24 eth-macro=12 lane=0 max-speed=25g active=true -init set port-map port=25 eth-macro=12 lane=1 max-speed=25g active=true -init set port-map port=26 eth-macro=12 lane=2 max-speed=25g active=true -init set port-map port=27 eth-macro=12 lane=3 max-speed=25g active=true -init set port-map port=28 eth-macro=14 lane=0 max-speed=25g active=true -init set port-map port=29 eth-macro=14 lane=1 max-speed=25g active=true -init set port-map port=30 eth-macro=14 lane=2 max-speed=25g active=true -init set port-map port=31 eth-macro=14 lane=3 max-speed=25g active=true -init set port-map port=32 eth-macro=16 lane=0 max-speed=25g active=true -init set port-map port=33 eth-macro=16 lane=1 max-speed=25g active=true -init set port-map port=34 eth-macro=16 lane=2 max-speed=25g active=true -init set port-map port=35 eth-macro=16 lane=3 max-speed=25g active=true -init set port-map port=36 eth-macro=17 lane=0 max-speed=25g active=true -init set port-map port=37 eth-macro=17 lane=1 max-speed=25g active=true -init set port-map port=38 eth-macro=17 lane=2 max-speed=25g active=true -init set port-map port=39 eth-macro=17 lane=3 max-speed=25g active=true -init set port-map port=40 eth-macro=18 lane=0 max-speed=25g active=true -init set port-map port=41 eth-macro=18 lane=1 max-speed=25g active=true -init set port-map port=42 eth-macro=18 lane=2 max-speed=25g active=true -init set port-map port=43 eth-macro=18 lane=3 max-speed=25g active=true -init set port-map port=44 eth-macro=19 lane=0 max-speed=25g active=true -init set port-map port=45 eth-macro=19 lane=1 max-speed=25g active=true -init set port-map port=46 eth-macro=19 lane=2 max-speed=25g active=true -init set port-map port=47 eth-macro=19 lane=3 max-speed=25g active=true -init set port-map port=48 eth-macro=20 lane=0 max-speed=100g active=true -init set port-map port=49 eth-macro=21 lane=0 max-speed=100g active=true -init set port-map port=50 eth-macro=26 lane=0 max-speed=100g active=true -init set port-map port=51 eth-macro=27 lane=0 max-speed=100g active=true -init set port-map port=52 eth-macro=28 lane=0 max-speed=100g active=true -init set port-map port=53 eth-macro=29 lane=0 max-speed=100g active=true -init set port-map port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true -init set port-map port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true -init start stage task-rsrc -init start stage module -init start stage task -phy set lane-swap portlist=0 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=1 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=2 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=3 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=4 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=5 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=6 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=7 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=8 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=9 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=10 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=11 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=12 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=13 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=14 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=15 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=16 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=17 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=18 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=19 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=20 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=21 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=22 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=23 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=24 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=25 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=26 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=27 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=28 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=29 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=30 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=31 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=32 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=33 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=34 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=35 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=36 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=37 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=38 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=39 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=40 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=41 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=42 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=43 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=44 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=45 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=46 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=47 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=48-53 lane-cnt=4 property=tx data=0x03.02.01.00 -phy set lane-swap portlist=0 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=1 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=2 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=3 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=4 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=5 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=6 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=7 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=8 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=9 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=10 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=11 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=12 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=13 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=14 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=15 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=16 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=17 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=18 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=19 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=20 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=21 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=22 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=23 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=24 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=25 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=26 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=27 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=28 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=29 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=30 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=31 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=32 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=33 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=34 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=35 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=36 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=37 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=38 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=39 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=40 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=41 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=42 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=43 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=44 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=45 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=46 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=47 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=48-53 lane-cnt=4 property=rx data=0x03.02.01.00 -phy set polarity-rev portlist=0 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=1 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=2 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=3 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=4 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=5 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=6 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=7 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=8 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=9 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=10 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=11 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=12 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=13 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=14 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=15 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=16 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=17 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=18 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=19 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=20 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=21 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=22 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=23 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=24 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=25 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=26 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=27 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=28 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=29 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=30 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=31 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=32 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=33 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=34 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=35 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=36 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=37 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=38 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=39 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=40 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=41 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=42 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=43 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=44 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=45 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=46 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=47 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=48 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev portlist=49 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev portlist=50 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev portlist=0 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=1 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=2 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=3 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=4 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=5 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=6 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=7 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=8 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=9 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=10 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=11 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=12 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=13 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=14 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=15 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=16 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=17 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=18 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=19 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=20 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=21 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=22 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=23 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=24 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=25 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=26 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=27 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=28 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=29 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=30 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=31 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=32 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=33 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=34 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=35 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=36 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=37 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=38 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=39 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=40 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=41 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=42 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=43 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=44 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=45 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=46 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=47 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=48 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev portlist=49 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev portlist=50 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev portlist=51 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev portlist=52 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set pre-emphasis portlist=0 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=0 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=0 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=0 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=4 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=4 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=4 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=4 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=8 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=8 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=8 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=8 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=12 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=12 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=12 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=12 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=16 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=16 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=16 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=16 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=20 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=20 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=20 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=20 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=24 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=24 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=24 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=24 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=28 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=28 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=28 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=28 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=32 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=32 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=32 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=32 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=36 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=36 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=36 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=36 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=40 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=40 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=40 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=40 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=44 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=44 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=44 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=44 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=48 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=48 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=48 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=48 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=49 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=49 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=49 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=49 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=50 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=50 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=50 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=50 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=51 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=51 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=51 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=51 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=52 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=52 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=52 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=52 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis portlist=53 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis portlist=53 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis portlist=53 lane-cnt=4 property=c0 data=0x1E.1E.1E.1E -phy set pre-emphasis portlist=53 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set mdio portlist=0 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=1 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=2 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=3 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=4 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=5 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=6 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=7 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=8 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=9 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=10 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=11 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=12 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=13 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=14 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=15 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=16 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=17 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=18 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=19 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=20 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=21 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=22 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=23 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=24 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=25 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=26 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=27 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=28 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=29 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=30 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=31 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=32 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=33 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=34 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=35 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=36 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=37 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=38 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=39 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=40 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=41 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=42 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=43 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=44 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=45 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=46 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=47 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=48 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=49 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=50 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=51 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=52 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=53 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=129 devad=0x1E addr=0x2 data=0x0000 -phy set mdio portlist=130 devad=0x1E addr=0x2 data=0x0000 -port set property portlist=0-47 speed=25g -port set property portlist=48-53 speed=100g -port set property portlist=129-130 speed=10g -port set property portlist=0-47 medium-type=cr -port set property portlist=48-53 medium-type=cr4 -port set property portlist=129-130 medium-type=kr -port set adver portlist=129-130 speed-10g-kr -port set property portlist=129-130 an=enable -port set property portlist=129-130 admin=enable -port set property portlist=0-53 admin=disable diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/sai.profile b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/sai.profile deleted file mode 100644 index 02d31ffb2d54..000000000000 --- a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/sai.profile +++ /dev/null @@ -1,2 +0,0 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/proc_init.nps -SAI_DSH_CONFIG_FILE=/usr/share/sonic/hwsku/port_config.nps \ No newline at end of file diff --git a/device/accton/x86_64-accton_as7116_54x-r0/default_sku b/device/accton/x86_64-accton_as7116_54x-r0/default_sku index 623c20034d36..146edca52638 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/default_sku +++ b/device/accton/x86_64-accton_as7116_54x-r0/default_sku @@ -1 +1 @@ -Accton-AS7116-54X t1 \ No newline at end of file +Accton-AS7116-54X-R0 t1 diff --git a/device/accton/x86_64-accton_as7116_54x-r0/fancontrol b/device/accton/x86_64-accton_as7116_54x-r0/fancontrol index 8b1798edcc00..e16d8f936f85 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/fancontrol +++ b/device/accton/x86_64-accton_as7116_54x-r0/fancontrol @@ -7,4 +7,4 @@ MAXTEMP=/sys/bus/i2c/devices/1-0063/fan_duty_cycle_percentage=58 MINSTART=/sys/bus/i2c/devices/1-0063/fan_duty_cycle_percentage=100 MINSTOP=/sys/bus/i2c/devices/1-0063/fan_duty_cycle_percentage=40 MINPWM=/sys/bus/i2c/devices/1-0063/fan_duty_cycle_percentage=40 -MAXPWM=/sys/bus/i2c/devices/1-0063/fan_duty_cycle_percentage=100 \ No newline at end of file +MAXPWM=/sys/bus/i2c/devices/1-0063/fan_duty_cycle_percentage=100 diff --git a/device/accton/x86_64-accton_as7116_54x-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as7116_54x-r0/plugins/eeprom.py index f5637458720e..1e7d1046d93d 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/plugins/eeprom.py +++ b/device/accton/x86_64-accton_as7116_54x-r0/plugins/eeprom.py @@ -18,4 +18,4 @@ class board(eeprom_tlvinfo.TlvInfoDecoder): _TLV_INFO_MAX_LEN = 256 def __init__(self, name, path, cpld_root, ro): self.eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" - super(board, self).__init__(self.eeprom_path, 0, '', True) \ No newline at end of file + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py index 2faf4d5dfacf..4f0e4ef8273c 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py @@ -168,4 +168,5 @@ def get_transceiver_change_event(self, timeout=0): time.sleep(2) - return True, ret_present \ No newline at end of file + return True, ret_present + diff --git a/device/accton/x86_64-accton_as7116_54x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7116_54x-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44bad6494229 --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sensors.conf b/device/accton/x86_64-accton_as7116_54x-r0/sensors.conf index ba976ef14536..9edb51a9e72d 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/sensors.conf +++ b/device/accton/x86_64-accton_as7116_54x-r0/sensors.conf @@ -10,4 +10,4 @@ chip "as7116_54x_fan-*" label fan7 "rear fan 2" label fan8 "rear fan 3" label fan9 "rear fan 4" - label fan10 "rear fan 5" \ No newline at end of file + label fan10 "rear fan 5" diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/__init__.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/__init__.py new file mode 100644 index 000000000000..d82f3749319c --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["platform", "chassis"] +from sonic_platform import * diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/chassis.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/chassis.py new file mode 100644 index 000000000000..6d5ed915812e --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/chassis.py @@ -0,0 +1,174 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Chassis information which are available in the platform +# +############################################################################# +try: + import sys + import re + import os + import subprocess + import json + import syslog + from sonic_platform_base.chassis_base import ChassisBase + from sonic_daemon_base.daemon_base import Logger + 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 +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +NUM_FAN_TRAY = 5 +NUM_FAN = 2 +NUM_PSU = 2 +NUM_THERMAL = 4 +NUM_SFP = 54 +SFP_PORT_START = 0 +QSFP_PORT_START = 48 +SFP_PORT_END = 47 +QSFP_PORT_END=53 +HOST_REBOOT_CAUSE_PATH = "/host/reboot-cause/" +PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/" +REBOOT_CAUSE_FILE = "reboot-cause.txt" +PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt" +COMPONENT_NAME_LIST = ["BIOS"] +HOST_CHK_CMD = "docker > /dev/null 2>&1" + + +class Chassis(ChassisBase): + """Platform-specific Chassis class""" + + def __init__(self): + super(Chassis, self).__init__() + + for fantray_index in range(0, NUM_FAN_TRAY): + for fan_index in range(0, NUM_FAN): + fan = Fan(fantray_index, fan_index) + self._fan_list.append(fan) + for index in range(0, NUM_PSU): + psu = Psu(index) + self._psu_list.append(psu) + for index in range(0, NUM_THERMAL): + thermal = Thermal(index) + self._thermal_list.append(thermal) + + self.PORT_START = SFP_PORT_START + self.QSFP_PORT_START = QSFP_PORT_START + self.PORT_END = QSFP_PORT_END + for index in range(0, NUM_SFP): + if index in range(self.QSFP_PORT_START, self.QSPORT_END + 1): + sfp_module = Sfp(index, 'QSFP') + else: + sfp_module = Sfp(index, 'SFP') + self._sfp_list.append(sfp_module) + self._component_name_list = COMPONENT_NAME_LIST + self._watchdog = Watchdog() + self._eeprom = Tlv() + logger.log_info("Chassis loaded successfully") + + def __is_host(self): + return os.system(HOST_CHK_CMD) == 0 + + def __read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return None + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.get_mac() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.get_serial() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self._eeprom.get_eeprom() + + def get_firmware_version(self, component_name): + """ + Retrieves platform-specific hardware/firmware versions for chassis + componenets such as BIOS, CPLD, FPGA, etc. + Args: + type: A string, component name + + Returns: + A string containing platform-specific component versions + """ + self.component = Component(component_name) + if component_name not in self._component_name_list: + return None + return self.component.get_firmware_version() + + def install_component_firmware(self, component_name, image_path): + """ + Install firmware to module + Args: + type: A string, component name. + image_path: A string, path to firmware image. + + Returns: + A boolean, True if install successfully, False if not + """ + self.component = Component(component_name) + if component_name not in self._component_name_list: + return False + return self.component.upgrade_firmware(image_path) + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + description = 'None' + reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER + + reboot_cause_path = (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 + sw_reboot_cause = self.__read_txt_file( + reboot_cause_path) or "Unknown" + prev_sw_reboot_cause = self.__read_txt_file( + prev_reboot_cause_path) or "Unknown" + + if sw_reboot_cause != "Unknown": + reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE + description = sw_reboot_cause + else: + reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER + description = 'Unknown reason' + + return (reboot_cause, description) diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/component.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/component.py new file mode 100644 index 000000000000..c8f109aa4db9 --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/component.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python + +############################################################################# +# Component contains an implementation of SONiC Platform Base API and +# provides the components firmware management function +############################################################################# + +import json +import os.path +import shutil +import shlex +import subprocess + +try: + from sonic_platform_base.device_base import DeviceBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version" + +class Component(DeviceBase): + """Platform-specific Component class""" + + DEVICE_TYPE = "component" + + def __init__(self, component_name): + DeviceBase.__init__(self) + self.name = component_name.upper() + + 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: + with open(BIOS_VERSION_PATH, 'r') as fd: + bios_version = fd.read() + return bios_version.strip() + except Exception as e: + return None + + def get_firmware_version(self): + """ + Retrieves the firmware version of module + Returns: + string: The firmware versions of the module + """ + fw_version = None + + if self.name == "BIOS": + fw_version = self.__get_bios_version() + + return fw_version + + def upgrade_firmware(self, image_path): + """ + Install firmware to module + Args: + image_path: A string, path to firmware image + Returns: + A boolean, True if install successfully, False if not + """ + if not os.path.isfile(image_path): + return False + + if self.name == "BIOS": + print("Not supported") + return False + + return self.__run_command(install_command) diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/eeprom.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/eeprom.py new file mode 100644 index 000000000000..714ac8153e0e --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/eeprom.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python + +############################################################################# +# 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 glob + import os + import sys + import imp + import re + from array import array + from cStringIO import StringIO + from sonic_platform_base.sonic_eeprom import eeprom_dts + from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +CACHE_ROOT = '/var/cache/sonic/decode-syseeprom' +CACHE_FILE = 'syseeprom_cache' + + +class Tlv(eeprom_tlvinfo.TlvInfoDecoder): + + EEPROM_DECODE_HEADLINES = 6 + + def __init__(self): + self._eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" + super(Tlv, self).__init__(self._eeprom_path, 0, '', True) + self._eeprom = self._load_eeprom() + + def __parse_output(self, decode_output): + decode_output.replace('\0', '') + lines = decode_output.split('\n') + lines = lines[self.EEPROM_DECODE_HEADLINES:] + _eeprom_info_dict = dict() + + for line in lines: + try: + match = re.search( + '(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+)', line) + if match is not None: + idx = match.group(1) + value = match.group(3).rstrip('\0') + + _eeprom_info_dict[idx] = value + except: + pass + return _eeprom_info_dict + + def _load_eeprom(self): + original_stdout = sys.stdout + sys.stdout = StringIO() + err = self.read_eeprom_db() + if err: + # Failed to read EEPROM information from database. Read from cache file + pass + else: + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + return self.__parse_output(decode_output) + + status = self.check_status() + if status < 'ok': + return False + + if not os.path.exists(CACHE_ROOT): + try: + os.makedirs(CACHE_ROOT) + except: + pass + + # + # only the eeprom classes that inherit from eeprom_base + # support caching. Others will work normally + # + try: + self.set_cache_name(os.path.join(CACHE_ROOT, CACHE_FILE)) + except: + pass + + e = self.read_eeprom() + if e is None: + return 0 + + try: + self.update_cache(e) + except: + pass + + self.decode_eeprom(e) + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + + (is_valid, valid_crc) = self.is_checksum_valid(e) + if not is_valid: + return False + + return self.__parse_output(decode_output) + + def get_eeprom(self): + return self._eeprom + + def get_serial(self): + return self._eeprom.get('0x23', "Undefined.") + + def get_mac(self): + return self._eeprom.get('0x24', "Undefined.") diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/fan.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/fan.py new file mode 100644 index 000000000000..54878e3e1baa --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/fan.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the fan status which are available in the platform +# +############################################################################# + +import json +import math +import os.path + +try: + from sonic_platform_base.fan_base import FanBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +FAN_PATH = "/sys/bus/i2c/devices/1-0063/" +FANTRAY_NAME_LIST = ["FANTRAY-1", "FANTRAY-2", + "FANTRAY-3", "FANTRAY-4", "FANTRAY-5"] +FAN_NAME_LIST = ["front", "rear"] + +class Fan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, fan_tray_index, fan_index=0): + self.fan_index = fan_index + self.fan_tray_index = fan_tray_index + self.fan_presence = "fan{}_present" + self.fan_direction = "fan{}_direction" + self.fan_fault = "fan{}_{}_fault" + self.fan_speed_rpm = "fan{}_{}_speed_rpm" + 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: + with open(file_path, 'w') as fd: + fd.write(str(value)) + except: + return False + return True + + def __search_file_by_name(self, directory, file_name): + for dirpath, dirnames, files in os.walk(directory): + for name in files: + file_path = os.path.join(dirpath, name) + if name in file_name: + return file_path + return None + + def get_direction(self): + """ + Retrieves the direction of fan + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + direction = self.FAN_DIRECTION_EXHAUST + fan_direction_file = (FAN_PATH + + self.fan_direction.format(self.fan_tray_index+1)) + raw = self.__read_txt_file(fan_direction_file).strip('\r\n') + direction = self.FAN_DIRECTION_INTAKE if str( + raw).upper() == "1" else self.FAN_DIRECTION_EXHAUST + + return direction + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 12000 (full speed) + """ + speed = 0 + if self.get_presence(): + fan_speed_file = (FAN_PATH + + self.fan_speed_rpm.format(self.fan_tray_index+1,FAN_NAME_LIST[self.fan_index])) + speed = self.__read_txt_file(fan_speed_file).strip('\r\n') + + return int(speed) + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + target = 0 + if self.get_presence(): + fan_speed_file=(FAN_PATH + + self.fan_speed_rpm.format(self.fan_tray_index+1, FAN_NAME_LIST[self.fan_index])) + target=self.__read_txt_file(fan_speed_file).strip('\r\n') + + return target + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + return 10 + + def set_speed(self, speed): + """ + Sets the fan speed + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + Returns: + A boolean, True if speed is set successfully, False if not + + Note: + Depends on pwm or target mode is selected: + 1) pwm = speed_pc * 255 <-- Currently use this mode. + 2) target_pwm = speed_pc * 100 / 255 + 2.1) set pwm{}_enable to 3 + + """ + return False + + def set_status_led(self, color): + """ + Sets the state of the fan module status LED + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if status LED state is set successfully, False if not + """ + return False + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + fan_name = FAN_NAME_LIST[self.fan_tray_index] + + return fan_name + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + fan_direction_file = (FAN_PATH + + self.fan_presence.format(self.fan_tray_index+1)) + present_str = self.__read_txt_file(fan_direction_file) or '1' + + return int(present_str) == 0 diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/platform.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/platform.py new file mode 100644 index 000000000000..44e03cdadbb3 --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/platform.py @@ -0,0 +1,20 @@ +#!/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): + """Platform-specific Platform class""" + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/psu.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/psu.py new file mode 100644 index 000000000000..b1c8029dced9 --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/psu.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python + +############################################################################# +# psuutil.py +# Platform-specific PSU status interface for SONiC +############################################################################# + +import os.path +import sonic_platform + +try: + from sonic_platform_base.psu_base import PsuBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +FAN_MAX_RPM = 9600 +PSU_NAME_LIST = ["PSU-0", "PSU-1"] + +class Psu(PsuBase): + """Platform-specific Psu class""" + + SYSFS_PSU_DIR = ["/sys/bus/i2c/devices/10-0050", + "/sys/bus/i2c/devices/11-0053"] + + def __init__(self): + self.index = psu_index + PsuBase.__init__(self) + + + def get_fan(self): + """ + Retrieves object representing the fan module contained in this PSU + Returns: + An object dervied from FanBase representing the fan module + contained in this PSU + """ + # Hardware not supported + return False + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + Returns: + A boolean, True if PSU has stablized its output voltages and passed all + its internal self-tests, False if not. + """ + return self.get_status() + + def set_status_led(self, color): + """ + Sets the state of the PSU status LED + Args: + color: A string representing the color with which to set the PSU status LED + Note: Only support green and off + Returns: + bool: True if status LED state is set successfully, False if not + """ + # Hardware not supported + return False + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return PSU_NAME_LIST[self.index] + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + attr_file ='psu_present' + attr_path = self.SYSFS_PSU_DIR[self.index-1] +'/' + attr_file + status = 0 + try: + with open(attr_path, 'r') as psu_prs: + status = int(psu_prs.read()) + except IOError: + return False + + return status == 1 + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + attr_file = 'psu_power_good' + attr_path = self.SYSFS_PSU_DIR[self.index-1] +'/' + attr_file + status = 0 + try: + with open(attr_path, 'r') as power_status: + status = int(power_status.read()) + except IOError: + return False + + return status == 1 diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py new file mode 100644 index 000000000000..07e0649579ac --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py @@ -0,0 +1,1133 @@ +#!/usr/bin/env python + +############################################################################# +# Sfp contains an implementation of SONiC Platform Base API and +# provides the sfp device status which are available in the platform +############################################################################# +try: + import os + import time + import subprocess + import sonic_device_util + import syslog + from ctypes import create_string_buffer + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sffbase + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper + from sonic_daemon_base.daemon_base import Logger +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +INFO_OFFSET = 0 +DOM_OFFSET = 256 + +QSFP_INFO_OFFSET = 128 +QSFP_DOM_OFFSET = 0 + +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_QSFP = 20 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 + +# Offset for values in SFP eeprom +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 40 +SFP_CHANNL_THRESHOLD_OFFSET = 112 +SFP_CHANNL_THRESHOLD_WIDTH = 2 +SFP_STATUS_CONTROL_OFFSET = 110 +SFP_STATUS_CONTROL_WIDTH = 1 +SFP_TX_DISABLE_HARD_BIT = 7 +SFP_TX_DISABLE_SOFT_BIT = 6 + + +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes', 'FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') + +# Offset for values in QSFP eeprom +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_CONTROL_OFFSET = 86 +QSFP_CONTROL_WIDTH = 8 +QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 +QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 +QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_POWEROVERRIDE_OFFSET = 93 +QSFP_POWEROVERRIDE_WIDTH = 1 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNEL_THRESHOLD_OFFSET = 176 +QSFP_CHANNEL_THRESHOLD_WIDTH = 16 + +qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', + 'Length Cable Assembly(m)') + +qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', 'Fibre Channel Speed') + +class Sfp(SfpBase): + """Platform-specific Sfp class""" + + # Port number + PORT_START = 0 + PORT_END = 53 + + port_to_i2c_mapping = { + 0: 37, + 1: 38, + 2: 39, + 3: 40, + 4: 41, + 5: 42, + 6: 43, + 7: 44, + 8: 45, + 9: 46, + 10: 47, + 11: 48, + 12: 49, + 13: 50, + 14: 51, + 15: 52, + 16: 53, + 17: 54, + 18: 55, + 19: 56, + 20: 57, + 21: 58, + 22: 59, + 23: 60, + 24: 61, + 25: 62, + 26: 63, + 27: 64, + 28: 65, + 29: 66, + 30: 67, + 31: 68, + 32: 69, + 33: 70, + 34: 71, + 35: 72, + 36: 73, + 37: 74, + 38: 75, + 39: 76, + 40: 77, + 41: 78, + 42: 79, + 43: 80, + 44: 81, + 45: 82, + 46: 83, + 47: 84, + 48: 21, + 49: 22, + 50: 23, + 51: 24, + 52: 25, + 53: 26, + } + _sfp_port = range(48, PORT_END + 1) + RESET_PATH = "/sys/bus/i2c/devices/{}-0050/sfp_port_reset" + PRS_PATH = "/sys/bus/i2c/devices/{}-0050/sfp_is_present" + + PLATFORM_ROOT_PATH = '/usr/share/sonic/device' + PMON_HWSKU_PATH = '/usr/share/sonic/hwsku' + HOST_CHK_CMD = "docker > /dev/null 2>&1" + + PLATFORM = "x86_64-accton_as7116_54x-r0" + HWSKU = "Accton-AS7116-54X-R0" + + def __init__(self, sfp_index, sfp_type): + # Init index + self.index = sfp_index + self.port_num = self.index + 1 + self.sfp_type = sfp_type + + # Init eeprom path + eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp_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[p_num] = eeprom_path.format( + self.port_to_i2c_mapping[p_num]) + + self.info_dict_keys = ['type', 'hardwarerev', 'serialnum', 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', + 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] + + self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', + 'rx1power', 'rx2power', 'rx3power', 'rx4power', 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', 'tx1power', 'tx2power', 'tx3power', 'tx4power'] + + self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + + SfpBase.__init__(self) + + def _convert_string_to_num(self, value_str): + if "-inf" in value_str: + return 'N/A' + elif "Unknown" in value_str: + return 'N/A' + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return 'N/A' + + def __read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return "" + + def __is_host(self): + return os.system(self.HOST_CHK_CMD) == 0 + + def __get_path_to_port_config_file(self): + platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.PLATFORM]) + hwsku_path = "/".join([platform_path, self.HWSKU] + ) if self.__is_host() else self.PMON_HWSKU_PATH + return "/".join([hwsku_path, "port_config.ini"]) + + def __read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.sfp_index] + try: + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except: + pass + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + + return eeprom_raw + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + Returns: + A dict which contains following keys/values : + """ + if self.sfp_type == "SFP": + get_sfp_transceiver_info + else: + get_qsfp_transceiver_info + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + Returns: + A dict which contains following keys/values : + """ + if self.sfp_type == "SFP": + get_sfp_transceiver_bulk_status + else: + get_qsfp_transceiver_bulk_status + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + Returns: + A dict which contains following keys/values : + """ + if self.sfp_type == "SFP": + get_sfp_transceiver_threshold_info + else: + get_qsfp_transceiver_threshold_info + + def get_sfp_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardwarerev |1*255VCHAR |hardware version of SFP + serialnum |1*255VCHAR |serial number of the SFP + manufacturename |1*255VCHAR |SFP vendor name + modelname |1*255VCHAR |SFP model name + Connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + nominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + ======================================================================== + """ + # check present status + sfpi_obj = sff8472InterfaceId() + 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_SFP) + 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_SFP) + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_vendor_rev_raw, 0) + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_vendor_sn_raw, 0) + + sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui( + sfp_vendor_oui_raw, 0) + + sfp_vendor_date_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + sfp_vendor_date_data = sfpi_obj.parse_vendor_date( + sfp_vendor_date_raw, 0) + + transceiver_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A') + compliance_code_dict = dict() + + if sfp_interface_bulk_data: + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] + + transceiver_info_dict['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 sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str( + compliance_code_dict) + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + + return transceiver_info_dict + + def get_sfp_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + # check present status + sfpd_obj = sff8472Dom() + if not self.get_presence() or not sfpd_obj: + return {} + + eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET) + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + cal_type = sfpi_obj.get_calibration_type() + sfpd_obj._calibration_type = cal_type + + offset = DOM_OFFSET + transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + dom_temperature_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature( + dom_temperature_raw, 0) + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + + dom_voltage_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_voltage_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) + transceiver_dom_info_dict['tx1power'] = dom_voltage_data['data']['TXPower']['value'] + transceiver_dom_info_dict['rx1power'] = dom_voltage_data['data']['RXPower']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_voltage_data['data']['TXBias']['value'] + + for key in transceiver_dom_info_dict: + transceiver_dom_info_dict[key] = self._convert_string_to_num( + transceiver_dom_info_dict[key]) + + transceiver_dom_info_dict['rx_los'] = self.get_rx_los() + transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + + return transceiver_dom_info_dict + + def get_sfp_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + # check present status + sfpd_obj = sff8472Dom() + + if not self.get_presence() and not sfpd_obj: + return {} + + eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET) + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + cal_type = sfpi_obj.get_calibration_type() + sfpd_obj._calibration_type = cal_type + + offset = DOM_OFFSET + transceiver_dom_threshold_info_dict = dict.fromkeys( + self.threshold_dict_keys, 'N/A') + dom_module_threshold_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold( + dom_module_threshold_raw, 0) + + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data[ + 'data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + for key in transceiver_dom_threshold_info_dict: + transceiver_dom_threshold_info_dict[key] = self._convert_string_to_num( + transceiver_dom_threshold_info_dict[key]) + + return transceiver_dom_threshold_info_dict + + def get_qsfp_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardwarerev |1*255VCHAR |hardware version of SFP + serialnum |1*255VCHAR |serial number of the SFP + manufacturename |1*255VCHAR |SFP vendor name + modelname |1*255VCHAR |SFP model name + Connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + nominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + ======================================================================== + """ + # check present status + sfpi_obj = sff8436InterfaceId() + if not self.get_presence() or not sfpi_obj: + return {} + + offset = INFO_OFFSET + + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_QSFP) + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk( + sfp_interface_bulk_raw, 0) + + sfp_vendor_name_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_vendor_name_raw, 0) + + sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_vendor_pn_raw, 0) + + sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_QSFP) + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_vendor_rev_raw, 0) + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_vendor_sn_raw, 0) + + sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui( + sfp_vendor_oui_raw, 0) + + sfp_vendor_date_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + sfp_vendor_date_data = sfpi_obj.parse_vendor_date( + sfp_vendor_date_raw, 0) + + transceiver_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A') + compliance_code_dict = dict() + + if sfp_interface_bulk_data: + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] + + transceiver_info_dict['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']) + + return transceiver_info_dict + + def get_qsfp_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + # check present status + sfpd_obj = sff8436Dom() + sfpi_obj = sff8436InterfaceId() + + if not self.get_presence() or not sfpi_obj or not sfpd_obj: + return {} + + transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + offset = 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 + + dom_temperature_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature( + dom_temperature_raw, 0) + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + + dom_voltage_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + dom_channel_monitor_data = {} + dom_channel_monitor_raw = None + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) + + else: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_channel_monitor_raw, 0) + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] + transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] + transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] + transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] + + if dom_channel_monitor_raw: + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + + for key in transceiver_dom_info_dict: + transceiver_dom_info_dict[key] = self._convert_string_to_num( + transceiver_dom_info_dict[key]) + + transceiver_dom_info_dict['rx_los'] = self.get_rx_los() + transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + + return transceiver_dom_info_dict + + def get_qsfp_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + # check present status + sfpd_obj = sff8436Dom() + + if not self.get_presence() or not sfpd_obj: + return {} + + transceiver_dom_threshold_dict = dict.fromkeys( + self.threshold_dict_keys, 'N/A') + dom_thres_raw = self.__read_eeprom_specific_bytes( + QSFP_MODULE_THRESHOLD_OFFSET, QSFP_MODULE_THRESHOLD_WIDTH) if self.get_presence() and sfpd_obj else None + + if dom_thres_raw: + module_threshold_values = sfpd_obj.parse_module_threshold_values( + dom_thres_raw, 0) + module_threshold_data = module_threshold_values.get('data') + if module_threshold_data: + transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['TempHighAlarm']['value'] + transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['TempLowAlarm']['value'] + transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['TempHighWarning']['value'] + transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['TempLowWarning']['value'] + transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['VccHighAlarm']['value'] + transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['VccLowAlarm']['value'] + transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['VccHighWarning']['value'] + transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['VccLowWarning']['value'] + + dom_thres_raw = self.__read_eeprom_specific_bytes( + QSFP_CHANNEL_THRESHOLD_OFFSET, QSFP_CHANNEL_THRESHOLD_WIDTH) if self.get_presence() and sfpd_obj else None + channel_threshold_values = sfpd_obj.parse_channel_threshold_values( + dom_thres_raw, 0) + channel_threshold_data = channel_threshold_values.get('data') + if channel_threshold_data: + transceiver_dom_threshold_dict['rxpowerhighalarm'] = channel_threshold_data['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerlowalarm'] = channel_threshold_data['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerhighwarning'] = channel_threshold_data['RxPowerHighWarning']['value'] + transceiver_dom_threshold_dict['rxpowerlowwarning'] = channel_threshold_data['RxPowerLowWarning']['value'] + transceiver_dom_threshold_dict['txpowerhighalarm'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerlowalarm'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerhighwarning'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerlowwarning'] = "0.0dBm" + transceiver_dom_threshold_dict['txbiashighalarm'] = channel_threshold_data['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_dict['txbiaslowalarm'] = channel_threshold_data['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_dict['txbiashighwarning'] = channel_threshold_data['TxBiasHighWarning']['value'] + transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value'] + + for key in transceiver_dom_threshold_dict: + transceiver_dom_threshold_dict[key] = self._convert_string_to_num( + transceiver_dom_threshold_dict[key]) + + return transceiver_dom_threshold_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + Returns: + A Boolean, True if reset enabled, False if disabled + """ + # SFP doesn't support this feature + return False + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + rx_los = False + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + rx_los = (sffbase().test_bit(data, 1) != 0) + + return rx_los + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + tx_fault = False + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + tx_fault = (sffbase().test_bit(data, 2) != 0) + + return tx_fault + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + Returns: + A Boolean, True if tx_disable is enabled, False if disabled + """ + tx_disable = False + tx_fault = False + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + tx_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 + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + # SFP doesn't support this feature + return 0 + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + # SFP doesn't support this feature + return False + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + # SFP doesn't support this feature + return False + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + Returns: + An integer number of current temperature in Celsius + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + return transceiver_dom_info_dict.get("temperature", "N/A") + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + Returns: + An integer number of supply voltage in mV + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + return transceiver_dom_info_dict.get("voltage", "N/A") + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + tx1_bs = transceiver_dom_info_dict.get("tx1bias", "N/A") + return [tx1_bs, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else [] + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + rx1_pw = transceiver_dom_info_dict.get("rx1power", "N/A") + return [rx1_pw, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else [] + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + tx1_pw = transceiver_dom_info_dict.get("tx1power", "N/A") + return [tx1_pw, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else [] + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + Returns: + A boolean, True if successful, False if not + """ + # SFP doesn't support this feature + return False + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.index] + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw is not None: + # Set bit 6 for Soft TX Disable Select + # 01000000 = 64 and 10111111 = 191 + tx_disable_bit = 64 if tx_disable else 191 + status_control = int(status_control_raw[0], 16) + tx_disable_ctl = (status_control | tx_disable_bit) if tx_disable else ( + status_control & tx_disable_bit) + try: + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, mode="r+b", buffering=0) + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfsfile_eeprom.seek(SFP_STATUS_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except: + #print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + return False + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + Returns: + A boolean, True if successful, False if not + """ + # SFP doesn't support this feature + return False + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + # SFP doesn't support this feature + return False + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + # SFP doesn't support this feature + return False + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + sfputil_helper = SfpUtilHelper() + sfputil_helper.read_porttab_mappings( + self.__get_path_to_port_config_file()) + name = sfputil_helper.logical[self.index] or "Unknown" + return name + + def get_presence(self): + """ + Retrieves the presence of the SFP + Returns: + bool: True if SFP is present, False if not + """ + presence = False + + try: + with open(self.PRS_PATH.format(self.index), 'r') as sfp_presence: + presence = int(sfp_presence.read(), 16) + except IOError: + return False + logger.log_info("debug:port_ %s sfp presence is %s" % (str(self.index)), % (str(presence)) + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + return transceiver_dom_info_dict.get("modelname", "N/A") + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + return transceiver_dom_info_dict.get("serialnum", "N/A") diff --git a/device/accton/x86_64-accton_as7212_54x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7212_54x-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44bad6494229 --- /dev/null +++ b/device/accton/x86_64-accton_as7212_54x-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/device/accton/x86_64-accton_as7312_54x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7312_54x-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44bad6494229 --- /dev/null +++ b/device/accton/x86_64-accton_as7312_54x-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/device/accton/x86_64-accton_as7312_54xs-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7312_54xs-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44bad6494229 --- /dev/null +++ b/device/accton/x86_64-accton_as7312_54xs-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/device/accton/x86_64-accton_as7315_27xb-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7315_27xb-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44bad6494229 --- /dev/null +++ b/device/accton/x86_64-accton_as7315_27xb-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py index 330d30b879d7..0292e2d52e1a 100644 --- a/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py @@ -219,8 +219,30 @@ def set_low_power_mode(self, port_num, lpmode): time.sleep(0.01) def reset(self, port_num): - raise NotImplementedError + if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: + return False + + cpld_i = self.get_cpld_num(port_num) + cpld_ps = self._cpld_mapping[cpld_i] + path = "/sys/bus/i2c/devices/{0}/module_reset_{1}" + port_ps = path.format(cpld_ps, port_num) + + self.__port_to_mod_rst = port_ps + try: + reg_file = open(self.__port_to_mod_rst, 'r+', buffering=0) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + #toggle reset + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + + return True @property def _get_present_bitmap(self): nodes = [] diff --git a/device/accton/x86_64-accton_as7326_56x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7326_56x-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44bad6494229 --- /dev/null +++ b/device/accton/x86_64-accton_as7326_56x-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/device/accton/x86_64-accton_as7512_32x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7512_32x-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44bad6494229 --- /dev/null +++ b/device/accton/x86_64-accton_as7512_32x-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/device/accton/x86_64-accton_as7712_32x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7712_32x-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44bad6494229 --- /dev/null +++ b/device/accton/x86_64-accton_as7712_32x-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/device/accton/x86_64-accton_as7716_32x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7716_32x-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44bad6494229 --- /dev/null +++ b/device/accton/x86_64-accton_as7716_32x-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/device/accton/x86_64-accton_as7716_32xb-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7716_32xb-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44bad6494229 --- /dev/null +++ b/device/accton/x86_64-accton_as7716_32xb-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/device/accton/x86_64-accton_as7726_32x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7726_32x-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44bad6494229 --- /dev/null +++ b/device/accton/x86_64-accton_as7726_32x-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/device/accton/x86_64-accton_as7816_64x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7816_64x-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44bad6494229 --- /dev/null +++ b/device/accton/x86_64-accton_as7816_64x-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/port_config.ini b/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/port_config.ini new file mode 100644 index 000000000000..a13514fcd909 --- /dev/null +++ b/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/port_config.ini @@ -0,0 +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 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 new file mode 100644 index 000000000000..be39b1f961f2 --- /dev/null +++ b/device/accton/x86_64-accton_as9716_32d-r0/Accton-AS9716-32D/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/etc/bcm/th3-as9716-32x400G.config.bcm diff --git a/device/accton/x86_64-accton_as9716_32d-r0/default_sku b/device/accton/x86_64-accton_as9716_32d-r0/default_sku new file mode 100644 index 000000000000..ccebae89a34e --- /dev/null +++ b/device/accton/x86_64-accton_as9716_32d-r0/default_sku @@ -0,0 +1 @@ +Accton-AS9716-32D t1 diff --git a/device/accton/x86_64-accton_as9716_32d-r0/installer.conf b/device/accton/x86_64-accton_as9716_32d-r0/installer.conf new file mode 100644 index 000000000000..d5f9419d77ff --- /dev/null +++ b/device/accton/x86_64-accton_as9716_32d-r0/installer.conf @@ -0,0 +1,4 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="pcie_aspm=off" diff --git a/device/accton/x86_64-accton_as9716_32d-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as9716_32d-r0/plugins/eeprom.py new file mode 100644 index 000000000000..1e7d1046d93d --- /dev/null +++ b/device/accton/x86_64-accton_as9716_32d-r0/plugins/eeprom.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +try: + import exceptions + import binascii + import time + import optparse + import warnings + import os + import sys + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + import subprocess +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as9716_32d-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as9716_32d-r0/plugins/psuutil.py new file mode 100644 index 000000000000..25eceb7428c7 --- /dev/null +++ b/device/accton/x86_64-accton_as9716_32d-r0/plugins/psuutil.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python + +############################################################################# +# Accton +# +# Module contains an implementation of SONiC PSU Base API and +# provides the PSUs status which are available in the platform +# +############################################################################# + +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + self.psu_path = "/sys/bus/i2c/devices/" + self.psu_presence = "/psu_present" + self.psu_oper_status = "/psu_power_good" + self.psu_mapping = { + 2: "10-0051", + 1: "9-0050", + } + + def get_num_psus(self): + return len(self.psu_mapping) + + def get_psu_status(self, index): + if index is None: + return False + + status = 0 + node = self.psu_path + self.psu_mapping[index]+self.psu_oper_status + try: + with open(node, 'r') as power_status: + status = int(power_status.read()) + except IOError: + return False + + return status == 1 + + def get_psu_presence(self, index): + if index is None: + return False + + status = 0 + node = self.psu_path + self.psu_mapping[index] + self.psu_presence + try: + with open(node, 'r') as presence_status: + status = int(presence_status.read()) + except IOError: + return False + + return status == 1 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 new file mode 100644 index 000000000000..17799035963e --- /dev/null +++ b/device/accton/x86_64-accton_as9716_32d-r0/plugins/sfputil.py @@ -0,0 +1,150 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + 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 = 33 + PORTS_IN_BLOCK = 34 + + BASE_OOM_PATH = "/sys/bus/i2c/devices/{0}-0050/" + BASE_CPLD1_PATH = "/sys/bus/i2c/devices/20-0061/" + BASE_CPLD2_PATH = "/sys/bus/i2c/devices/21-0062/" + + _port_to_is_present = {} + _port_to_lp_mode = {} + + _port_to_eeprom_mapping = {} + _port_to_i2c_mapping = { + 0: [1, 25], + 1: [2, 26], + 2: [3, 27], + 3: [4, 28], + 4: [5, 29], + 5: [6, 30], + 6: [7, 31], + 7: [8, 32], + 8: [9, 33], + 9: [10, 34], + 10: [11, 35], + 11: [12, 36], + 12: [13, 37], + 13: [14, 38], + 14: [15, 39], + 15: [16, 40], + 16: [17, 41], + 17: [18, 42], + 18: [19, 43], + 19: [20, 44], + 20: [21, 45], + 21: [22, 46], + 22: [23, 47], + 23: [24, 48], + 24: [25, 49], + 25: [26, 50], + 26: [27, 51], + 27: [28, 52], + 28: [29, 53], + 29: [30, 54], + 30: [31, 55], + 31: [32, 56], + 32: [33, 57], + 33: [34, 58], + } + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return range(self.PORT_START, self.PORTS_IN_BLOCK + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + eeprom_path = self.BASE_OOM_PATH + "eeprom" + + for x in range(0, self.port_end+1): + self.port_to_eeprom_mapping[x] = eeprom_path.format( + self._port_to_i2c_mapping[x][1] + ) + + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + if port_num < 16 : + present_path = self.BASE_CPLD1_PATH + "module_present_" + str(port_num+1) + else: + present_path = self.BASE_CPLD2_PATH + "module_present_" + str(port_num+1) + self.__port_to_is_present = present_path + + try: + val_file = open(self.__port_to_is_present) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = val_file.readline().rstrip() + val_file.close() + + if content == "1": + return True + + return False + + def get_low_power_mode(self, port_num): + raise NotImplementedError + + def set_low_power_mode(self, port_num, lpmode): + raise NotImplementedError + + def reset(self, port_num): + if port_num < self.port_start or port_num > self.port_end: + return False + + if port_num < 16 : + mod_rst_path = self.BASE_CPLD1_PATH + "module_reset_" + str(port_num+1) + else: + mod_rst_path = self.BASE_CPLD2_PATH + "module_reset_" + str(port_num+1) + + self.__port_to_mod_rst = mod_rst_path + try: + reg_file = open(self.__port_to_mod_rst, 'r+') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = '1' + + reg_file.write(reg_value) + reg_file.close() + + return True + + def get_transceiver_change_event(self): + """ + TODO: This function need to be implemented + when decide to support monitoring SFP(Xcvrd) + on this platform. + """ + raise NotImplementedError \ No newline at end of file diff --git a/device/accton/x86_64-accton_as9716_32d-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as9716_32d-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44bad6494229 --- /dev/null +++ b/device/accton/x86_64-accton_as9716_32d-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/device/accton/x86_64-accton_minipack-r0/plugins/led_control.py b/device/accton/x86_64-accton_minipack-r0/plugins/led_control.py new file mode 100755 index 000000000000..26e2a7f7c8a2 --- /dev/null +++ b/device/accton/x86_64-accton_minipack-r0/plugins/led_control.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# +# led_control.py +# +# Platform-specific LED control functionality for SONiC +# + +try: + from sonic_led.led_control_base import LedControlBase + import swsssdk + import threading + import os + import logging + import struct + import time + import syslog + from socket import * + from select import * + from minipack.pimutil import PimUtil +except ImportError, e: + raise ImportError(str(e) + " - required module not found") + + +class LedControl(LedControlBase): + """Platform specific LED control class""" + SONIC_PORT_NAME_PREFIX = "Ethernet" + + + def __init__(self): + pim=PimUtil() + pim.init_pim_fpga() + + def _port_name_to_index(self, port_name): + # Strip "Ethernet" off port name + if not port_name.startswith(self.SONIC_PORT_NAME_PREFIX): + return -1 + + port_idx = int(port_name[len(self.SONIC_PORT_NAME_PREFIX):]) + return port_idx + + def _port_state_to_mode(self, port_idx, state): + if state == "up": + return 1, 4 #port linkup, led is green + else: + return 0, 0 #port linkdown, led is off + + def port_link_state_change(self, portname, state): + pim=PimUtil() + port_idx = self._port_name_to_index(portname) + new_control, led_mode = self._port_state_to_mode(port_idx, state) + color, control=pim.get_port_led(port_idx) + + if color==led_mode: + if control==new_control: + return + + pim.set_port_led(port_idx, led_mode, new_control)#port linkup, led is green + #port linkdown, led is off + diff --git a/device/accton/x86_64-accton_minipack-r0/plugins/sfputil.py b/device/accton/x86_64-accton_minipack-r0/plugins/sfputil.py old mode 100644 new mode 100755 index 16105acbf78a..6f62d8ed4c07 --- a/device/accton/x86_64-accton_minipack-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_minipack-r0/plugins/sfputil.py @@ -6,6 +6,9 @@ try: import time from sonic_sfp.sfputilbase import SfpUtilBase + import os + import sys, getopt + from minipack.pimutil import PimUtil except ImportError as e: raise ImportError("%s - required module not found" % str(e)) @@ -16,7 +19,7 @@ class SfpUtil(SfpUtilBase): PORT_START = 0 PORT_END = 128 - BASE_OOM_PATH = "/sys/bus/i2c/devices/{0}-0050/" + LOCAL_OOM_PATH = "/usr/local/bin/minipack_qsfp/port%d_eeprom" _port_to_is_present = {} _port_to_lp_mode = {} @@ -53,42 +56,91 @@ def sfp_map(self, index): def __init__(self): - eeprom_path = self.BASE_OOM_PATH + "eeprom" - - for x in range(0, self.port_end+1): - bus = self.sfp_map(x) - self.port_to_eeprom_mapping[x] = eeprom_path.format( - bus) + for x in range(0, self.port_end): + self.port_to_eeprom_mapping[x] = self.LOCAL_OOM_PATH %x SfpUtilBase.__init__(self) + pim=PimUtil() + pim.init_pim_fpga() + + def __del__(self): + self.value=0 def get_presence(self, port_num): # Check for invalid port_num if port_num < self.port_start or port_num > self.port_end: return False - eeprom_path = self.port_to_eeprom_mapping[port_num] - with open(eeprom_path) as f: - try: - content = f.read(1) - except IOError as e: - #Not print any error, for if any, treat as Not present. - return False - return True - + pim=PimUtil() + status=pim.get_qsfp_presence(port_num) + return status + def get_low_power_mode(self, port_num): - raise NotImplementedError + if port_num < self.port_start or port_num > self.port_end: + return False + + pim=PimUtil() + return pim.get_low_power_mode(port_num) def set_low_power_mode(self, port_num, lpmode): - raise NotImplementedError + if port_num < self.port_start or port_num > self.port_end: + return False + pim=PimUtil() + pim.set_low_power_mode(port_num, lpmode) + return True def reset(self, port_num): - raise NotImplementedError + if port_num < self.port_start or port_num > self.port_end: + return False + pim=PimUtil() + pim.reset(port_num) + return True + + def get_transceiver_change_event(self, timeout=0): + pim=PimUtil() + start_time = time.time() + port_dict = {} + forever = False - def get_transceiver_change_event(self): - """ - TODO: This function need to be implemented - when decide to support monitoring SFP(Xcvrd) - on this platform. - """ - raise NotImplementedError + if timeout == 0: + forever = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + print "get_transceiver_change_event:Invalid timeout value", timeout + return False, {} + + end_time = start_time + timeout + if start_time > end_time: + print 'get_transceiver_change_event:' \ + 'time wrap / invalid timeout value', timeout + + return False, {} # Time wrap or possibly incorrect timeout + + while timeout >= 0: + change_status=0 + port_dict = pim.get_qsfp_interrupt() + present=0 + for key, value in port_dict.iteritems(): + if value==1: + present=self.get_presence(key) + change_status=1 + if present: + port_dict[key]='1' + else: + port_dict[key]='0' + + if change_status: + return True, port_dict + if forever: + time.sleep(1) + else: + timeout = end_time - time.time() + if timeout >= 1: + time.sleep(1) # We poll at 1 second granularity + else: + if timeout > 0: + time.sleep(timeout) + return True, {} + print "get_evt_change_event: Should not reach here." + return False, {} diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t0.j2 index cb74cb75281b..0869e63968ac 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t0.j2 @@ -36,7 +36,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t1.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t1.j2 index 0699433bffb4..80e96bdceca7 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t1.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t1.j2 @@ -36,7 +36,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 index 5d6e0cd61a7e..5add8968e621 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 @@ -50,7 +50,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/buffers_defaults_t0.j2 index 7463e20afabe..c0fa1ff0864e 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q24C8/buffers_defaults_t0.j2 @@ -50,7 +50,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t0.j2 index cb74cb75281b..0869e63968ac 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t0.j2 @@ -36,7 +36,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t1.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t1.j2 index 0699433bffb4..80e96bdceca7 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t1.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t1.j2 @@ -36,7 +36,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", 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 5cb507321b02..d3a66dee635f 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 @@ -815,3 +815,37 @@ serdes_core_tx_polarity_flip_physical{233}=0x36 serdes_core_tx_polarity_flip_physical{241}=0xc6 serdes_core_tx_polarity_flip_physical{249}=0xc3 serdes_core_tx_polarity_flip_physical{257}=0x0 +serdes_tx_taps_cd0=pam4:-28:124:-12:4:0:0 +serdes_tx_taps_cd1=pam4:-28:124:-12:4:0:0 +serdes_tx_taps_cd2=pam4:-28:124:-12:4:0:0 +serdes_tx_taps_cd3=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd4=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd5=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd6=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd7=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd8=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd9=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd10=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd11=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd12=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd13=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd14=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd15=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd16=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd17=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd18=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd19=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd20=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd21=pam4:-28:124:0:4:0:0 +serdes_tx_taps_cd22=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd23=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd24=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd25=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd26=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd27=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd28=pam4:-28:120:-4:4:0:0 +serdes_tx_taps_cd29=pam4:-28:124:-12:4:0:0 +serdes_tx_taps_cd30=pam4:-28:124:-12:4:0:0 +serdes_tx_taps_cd31=pam4:-28:124:-12:4:0:0 +serdes_tx_taps_cd32=pam4:1:34:9:0:0:0 +serdes_tx_taps_cd33=pam4:1:34:9:0:0:0 diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t0.j2 index 62a6bac1c25f..35188dbeb382 100644 --- a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t0.j2 @@ -1,4 +1,8 @@ -{%- set default_cable = '5m' %} +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '4194304' %} +{% set ingress_lossy_pool_size = '7340032' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '7340032' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} @@ -10,37 +14,58 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "33329088", + "size": "{{ ingress_lossless_pool_size }}", "type": "ingress", "mode": "dynamic", - "xoff": "7827456" + "xoff": "2867200" }, - "egress_lossy_pool": { - "size": "26663272", - "type": "egress", + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", "mode": "dynamic" }, "egress_lossless_pool": { - "size": "42349632", + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", "type": "egress", - "mode": "static" + "mode": "dynamic" } }, "BUFFER_PROFILE": { "ingress_lossy_profile": { - "pool":"[BUFFER_POOL|ingress_lossless_pool]", - "size":"0", - "static_th":"11075584" + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" }, "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", - "static_th":"10587408" + "dynamic_th":"7" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"1664", - "dynamic_th":"-1" + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" } }, {%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + } + } +{%- endmacro %} diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t1.j2 b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..eb945c25e636 --- /dev/null +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t1.j2 @@ -0,0 +1,71 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '2097152' %} +{% set ingress_lossy_pool_size = '5242880' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '5242880' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,64) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic", + "xoff": "2867200" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + } + } +{%- endmacro %} diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/pg_profile_lookup.ini b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/pg_profile_lookup.ini new file mode 100644 index 000000000000..78a72d842acd --- /dev/null +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 34816 18432 16384 7 + 25000 5m 34816 18432 16384 7 + 40000 5m 34816 18432 16384 7 + 50000 5m 34816 18432 16384 7 + 100000 5m 36864 18432 18432 7 + 10000 40m 36864 18432 18432 7 + 25000 40m 39936 18432 21504 7 + 40000 40m 41984 18432 23552 7 + 50000 40m 41984 18432 23552 7 + 100000 40m 54272 18432 35840 7 + 10000 300m 49152 18432 30720 7 + 25000 300m 71680 18432 53248 7 + 40000 300m 94208 18432 75776 7 + 50000 300m 94208 18432 75776 7 + 100000 300m 184320 18432 165888 7 diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/switch-sai.conf b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/switch-sai.conf index c3abb3ebd8fc..0a807b1c9ea7 100644 --- a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/switch-sai.conf +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/switch-sai.conf @@ -25,7 +25,7 @@ "table-config": "share/tofinopd/switch/context.json", "tofino-bin": "share/tofinopd/switch/tofino.bin", "switchapi": "lib/libswitchapi.so", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "switchapi_port_add": false, "non_default_port_ppgs": 5 } diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/switch-tna-sai.conf b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/switch-tna-sai.conf index 2a2270767d87..ece3fcbe6a90 100644 --- a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/switch-tna-sai.conf +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/switch-tna-sai.conf @@ -22,13 +22,13 @@ "p4_pipelines": [ { "p4_pipeline_name": "pipe", - "config": "share/tofinopd/switch/pipe/tofino.bin", - "context": "share/tofinopd/switch/pipe/context.json" + "config": "share/switch/pipe/tofino.bin", + "context": "share/switch/pipe/context.json" } ], "program-name": "switch", - "switchsai": "lib/libswitchsai.so", - "bfrt-config": "share/tofinopd/switch/bf-rt.json", + "sai": "lib/libsai.so", + "bfrt-config": "share/switch/bf-rt.json", "model_json_path" : "share/switch/aug_model.json", "switchapi_port_add": false, "non_default_port_ppgs": 5 diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t0.j2 index 8ca15c1b0391..8cd886c14ffd 100644 --- a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t0.j2 @@ -1,4 +1,8 @@ -{%- set default_cable = '5m' %} +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '4194304' %} +{% set ingress_lossy_pool_size = '7340032' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '7340032' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} @@ -22,37 +26,58 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "33329088", + "size": "{{ ingress_lossless_pool_size }}", "type": "ingress", "mode": "dynamic", - "xoff": "7827456" + "xoff": "2867200" }, - "egress_lossy_pool": { - "size": "26663272", - "type": "egress", + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", "mode": "dynamic" }, "egress_lossless_pool": { - "size": "42349632", + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", "type": "egress", - "mode": "static" + "mode": "dynamic" } }, "BUFFER_PROFILE": { "ingress_lossy_profile": { - "pool":"[BUFFER_POOL|ingress_lossless_pool]", - "size":"0", - "static_th":"11075584" + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" }, "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", - "static_th":"10587408" + "dynamic_th":"7" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"1664", - "dynamic_th":"-1" + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" } }, {%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + } + } +{%- endmacro %} diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t1.j2 b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..e14ad9214743 --- /dev/null +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t1.j2 @@ -0,0 +1,83 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '2097152' %} +{% set ingress_lossy_pool_size = '5242880' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '5242880' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,20) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(80,88) %} + {%- if PORT_ALL.append("Ethernet%d" % port_idx) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(22,32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(128,140) %} + {%- if PORT_ALL.append("Ethernet%d" % port_idx) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(35,64) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic", + "xoff": "2867200" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + } + } +{%- endmacro %} diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/pg_profile_lookup.ini b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/pg_profile_lookup.ini new file mode 100644 index 000000000000..78a72d842acd --- /dev/null +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 34816 18432 16384 7 + 25000 5m 34816 18432 16384 7 + 40000 5m 34816 18432 16384 7 + 50000 5m 34816 18432 16384 7 + 100000 5m 36864 18432 18432 7 + 10000 40m 36864 18432 18432 7 + 25000 40m 39936 18432 21504 7 + 40000 40m 41984 18432 23552 7 + 50000 40m 41984 18432 23552 7 + 100000 40m 54272 18432 35840 7 + 10000 300m 49152 18432 30720 7 + 25000 300m 71680 18432 53248 7 + 40000 300m 94208 18432 75776 7 + 50000 300m 94208 18432 75776 7 + 100000 300m 184320 18432 165888 7 diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/switch-sai.conf b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/switch-sai.conf index c3abb3ebd8fc..0a807b1c9ea7 100644 --- a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/switch-sai.conf +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/switch-sai.conf @@ -25,7 +25,7 @@ "table-config": "share/tofinopd/switch/context.json", "tofino-bin": "share/tofinopd/switch/tofino.bin", "switchapi": "lib/libswitchapi.so", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "switchapi_port_add": false, "non_default_port_ppgs": 5 } diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/switch-tna-sai.conf b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/switch-tna-sai.conf index 2a2270767d87..ece3fcbe6a90 100644 --- a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/switch-tna-sai.conf +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/switch-tna-sai.conf @@ -22,13 +22,13 @@ "p4_pipelines": [ { "p4_pipeline_name": "pipe", - "config": "share/tofinopd/switch/pipe/tofino.bin", - "context": "share/tofinopd/switch/pipe/context.json" + "config": "share/switch/pipe/tofino.bin", + "context": "share/switch/pipe/context.json" } ], "program-name": "switch", - "switchsai": "lib/libswitchsai.so", - "bfrt-config": "share/tofinopd/switch/bf-rt.json", + "sai": "lib/libsai.so", + "bfrt-config": "share/switch/bf-rt.json", "model_json_path" : "share/switch/aug_model.json", "switchapi_port_add": false, "non_default_port_ppgs": 5 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/th2-a7260cx3-64-64x100G.config.bcm b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/th2-a7260cx3-64-64x100G.config.bcm index 500d00de960c..44fb6f7536b4 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/th2-a7260cx3-64-64x100G.config.bcm +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-C64/th2-a7260cx3-64-64x100G.config.bcm @@ -939,7 +939,6 @@ portmap_9=17:100 robust_hash_disable_egress_vlan=1 robust_hash_disable_mpls=1 robust_hash_disable_vlan=1 -sram_scan_enable=0 stable_size=0x5500000 stable_size=0x5500000 tdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/buffers_defaults_t0.j2 index a5951e156b26..74579a022dcb 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/buffers_defaults_t0.j2 @@ -38,12 +38,12 @@ "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "static_th":"11075584" + "static_th":"44302336" }, "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", - "static_th":"10587408" + "static_th":"42349632" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/pg_profile_lookup.ini b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/pg_profile_lookup.ini index c2bf04950b80..ed0005610b71 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/pg_profile_lookup.ini +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/pg_profile_lookup.ini @@ -1,8 +1,8 @@ # PG lossless profiles. -# speed cable size xon xoff threshold xon_offset - 50000 5m 1248 1248 56160 -3 2496 - 100000 5m 1248 1248 96928 -3 2496 - 50000 40m 1248 1248 56160 -3 2496 - 100000 40m 1248 1248 96928 -3 2496 - 50000 300m 1248 1248 56160 -3 2496 - 100000 300m 1248 1248 96928 -3 2496 +# speed cable size xon xoff threshold xon_offset + 50000 5m 1248 1248 56160 -3 2496 + 100000 5m 1248 1248 96928 -3 2496 + 50000 40m 1248 1248 96096 -3 2496 + 100000 40m 1248 1248 177632 -3 2496 + 50000 300m 1248 1248 141856 -3 2496 + 100000 300m 1248 1248 268736 -3 2496 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/th2-a7260cx3-64-112x50G+8x100G.config.bcm b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/th2-a7260cx3-64-112x50G+8x100G.config.bcm index 85be9fced908..3c2a343bf04d 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/th2-a7260cx3-64-112x50G+8x100G.config.bcm +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/th2-a7260cx3-64-112x50G+8x100G.config.bcm @@ -681,7 +681,6 @@ port_init_cl72_hg=1 robust_hash_disable_egress_vlan=1 robust_hash_disable_mpls=1 robust_hash_disable_vlan=1 -sram_scan_enable=0 stable_size=0x5500000 stable_size=0x5500000 tdma_timeout_usec=15000000 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/buffers_defaults_t0.j2 index 62a6bac1c25f..3442612f70b2 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/buffers_defaults_t0.j2 @@ -30,12 +30,12 @@ "ingress_lossy_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "size":"0", - "static_th":"11075584" + "static_th":"44302336" }, "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", - "static_th":"10587408" + "static_th":"42349632" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/pg_profile_lookup.ini b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/pg_profile_lookup.ini index 34ac8b2ca700..ac33b4f961fb 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/pg_profile_lookup.ini +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/pg_profile_lookup.ini @@ -1,11 +1,11 @@ # PG lossless profiles. -# speed cable size xon xoff threshold xon_offset - 40000 5m 1248 1248 56160 -3 2496 - 50000 5m 1248 1248 56160 -3 2496 - 100000 5m 1248 1248 96928 -3 2496 - 40000 40m 1248 1248 56160 -3 2496 - 50000 40m 1248 1248 56160 -3 2496 - 100000 40m 1248 1248 96928 -3 2496 - 40000 300m 1248 1248 56160 -3 2496 - 50000 300m 1248 1248 56160 -3 2496 - 100000 300m 1248 1248 96928 -3 2496 +# speed cable size xon xoff threshold xon_offset + 40000 5m 1248 1248 56160 -3 2496 + 50000 5m 1248 1248 56160 -3 2496 + 100000 5m 1248 1248 96928 -3 2496 + 40000 40m 1248 1248 71552 -3 2496 + 50000 40m 1248 1248 96096 -3 2496 + 100000 40m 1248 1248 177632 -3 2496 + 40000 300m 1248 1248 108160 -3 2496 + 50000 300m 1248 1248 141856 -3 2496 + 100000 300m 1248 1248 268736 -3 2496 diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/th2-a7260cx3-64-64x40G.config.bcm b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/th2-a7260cx3-64-64x40G.config.bcm index f1a0e0d08971..f5ac5e37ef7e 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/th2-a7260cx3-64-64x40G.config.bcm +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-Q64/th2-a7260cx3-64-64x40G.config.bcm @@ -939,7 +939,6 @@ portmap_9=17:40 robust_hash_disable_egress_vlan=1 robust_hash_disable_mpls=1 robust_hash_disable_vlan=1 -sram_scan_enable=0 stable_size=0x5500000 stable_size=0x5500000 tdma_timeout_usec=15000000 @@ -1012,3 +1011,5 @@ serdes_preemphasis_114=0x61c01 serdes_preemphasis_115=0x61c01 serdes_preemphasis_116=0x105004 serdes_preemphasis_117=0x105004 + +mmu_init_config="MSFT-TH2-Tier0" diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/jr2-a7280cr3-32p4-28x100G-8x10G.config.bcm b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/jr2-a7280cr3-32p4-28x100G-8x10G.config.bcm new file mode 100644 index 000000000000..3d89e2b41b4a --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/jr2-a7280cr3-32p4-28x100G-8x10G.config.bcm @@ -0,0 +1,741 @@ +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=nrz:0:127:0:0:0:0 +serdes_tx_taps_30=nrz:0:127:0:0:0:0 +serdes_tx_taps_31=nrz:0:127:0:0:0:0 +serdes_tx_taps_32=nrz:0:127:0:0:0:0 +serdes_tx_taps_33=nrz:0:127:0:0:0:0 +serdes_tx_taps_34=nrz:0:127:0:0:0:0 +serdes_tx_taps_35=nrz:0:127:0:0:0:0 +serdes_tx_taps_36=nrz:0:127:0:0: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=rx39:tx35 +lane_to_serdes_map_nif_lane33.0=rx38:tx36 +lane_to_serdes_map_nif_lane34.0=rx32:tx32 +lane_to_serdes_map_nif_lane35.0=rx37:tx37 +lane_to_serdes_map_nif_lane36.0=rx33:tx34 +lane_to_serdes_map_nif_lane37.0=rx34:tx38 +lane_to_serdes_map_nif_lane38.0=rx35:tx33 +lane_to_serdes_map_nif_lane39.0=rx36:tx39 +lane_to_serdes_map_nif_lane40.0=rx44:tx47 +lane_to_serdes_map_nif_lane41.0=rx43:tx41 +lane_to_serdes_map_nif_lane42.0=rx47:tx46 +lane_to_serdes_map_nif_lane43.0=rx42:tx42 +lane_to_serdes_map_nif_lane44.0=rx45:tx45 +lane_to_serdes_map_nif_lane45.0=rx41:tx40 +lane_to_serdes_map_nif_lane46.0=rx46:tx44 +lane_to_serdes_map_nif_lane47.0=rx40:tx43 +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=rx81:tx83 +lane_to_serdes_map_nif_lane81.0=rx85:tx84 +lane_to_serdes_map_nif_lane82.0=rx80:tx80 +lane_to_serdes_map_nif_lane83.0=rx86:tx85 +lane_to_serdes_map_nif_lane84.0=rx82:tx82 +lane_to_serdes_map_nif_lane85.0=rx87:tx86 +lane_to_serdes_map_nif_lane86.0=rx83:tx81 +lane_to_serdes_map_nif_lane87.0=rx84:tx87 +lane_to_serdes_map_nif_lane88.0=rx91:tx95 +lane_to_serdes_map_nif_lane89.0=rx90:tx89 +lane_to_serdes_map_nif_lane90.0=rx95:tx94 +lane_to_serdes_map_nif_lane91.0=rx89:tx90 +lane_to_serdes_map_nif_lane92.0=rx93:tx93 +lane_to_serdes_map_nif_lane93.0=rx94:tx88 +lane_to_serdes_map_nif_lane94.0=rx92:tx92 +lane_to_serdes_map_nif_lane95.0=rx88:tx91 +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=0 +phy_rx_polarity_flip_phy33=1 +phy_rx_polarity_flip_phy34=1 +phy_rx_polarity_flip_phy35=0 +phy_rx_polarity_flip_phy36=0 +phy_rx_polarity_flip_phy37=0 +phy_rx_polarity_flip_phy38=1 +phy_rx_polarity_flip_phy39=0 +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=1 +phy_rx_polarity_flip_phy46=0 +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=0 +phy_rx_polarity_flip_phy81=0 +phy_rx_polarity_flip_phy82=1 +phy_rx_polarity_flip_phy83=1 +phy_rx_polarity_flip_phy84=1 +phy_rx_polarity_flip_phy85=0 +phy_rx_polarity_flip_phy86=1 +phy_rx_polarity_flip_phy87=1 +phy_rx_polarity_flip_phy88=0 +phy_rx_polarity_flip_phy89=0 +phy_rx_polarity_flip_phy90=1 +phy_rx_polarity_flip_phy91=1 +phy_rx_polarity_flip_phy92=0 +phy_rx_polarity_flip_phy93=1 +phy_rx_polarity_flip_phy94=0 +phy_rx_polarity_flip_phy95=0 +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=0 +phy_tx_polarity_flip_phy33=0 +phy_tx_polarity_flip_phy34=1 +phy_tx_polarity_flip_phy35=1 +phy_tx_polarity_flip_phy36=1 +phy_tx_polarity_flip_phy37=0 +phy_tx_polarity_flip_phy38=0 +phy_tx_polarity_flip_phy39=1 +phy_tx_polarity_flip_phy40=1 +phy_tx_polarity_flip_phy41=1 +phy_tx_polarity_flip_phy42=0 +phy_tx_polarity_flip_phy43=1 +phy_tx_polarity_flip_phy44=1 +phy_tx_polarity_flip_phy45=1 +phy_tx_polarity_flip_phy46=0 +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=0 +phy_tx_polarity_flip_phy81=1 +phy_tx_polarity_flip_phy82=1 +phy_tx_polarity_flip_phy83=1 +phy_tx_polarity_flip_phy84=1 +phy_tx_polarity_flip_phy85=0 +phy_tx_polarity_flip_phy86=0 +phy_tx_polarity_flip_phy87=1 +phy_tx_polarity_flip_phy88=1 +phy_tx_polarity_flip_phy89=0 +phy_tx_polarity_flip_phy90=0 +phy_tx_polarity_flip_phy91=1 +phy_tx_polarity_flip_phy92=1 +phy_tx_polarity_flip_phy93=1 +phy_tx_polarity_flip_phy94=0 +phy_tx_polarity_flip_phy95=0 + +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=XE48:core_1.29 +ucode_port_30=XE49:core_1.30 +ucode_port_31=XE50:core_1.31 +ucode_port_32=XE51:core_1.32 +ucode_port_33=XE52:core_1.33 +ucode_port_34=XE53:core_1.34 +ucode_port_35=XE54:core_1.35 +ucode_port_36=XE55:core_1.36 + +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_32p4/Arista-7280CR3-C28S8/port_config.ini b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/port_config.ini new file mode 100644 index 000000000000..cb1c2a4663e8 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/port_config.ini @@ -0,0 +1,37 @@ +# 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 Ethernet29/1 29 10000 +Ethernet113 49 Ethernet29/2 29 10000 +Ethernet114 50 Ethernet29/3 29 10000 +Ethernet115 51 Ethernet29/4 29 10000 +Ethernet120 52 Ethernet31/1 31 10000 +Ethernet121 53 Ethernet31/2 31 10000 +Ethernet122 54 Ethernet31/3 31 10000 +Ethernet123 55 Ethernet31/4 31 10000 diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/sai.profile b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/sai.profile new file mode 100644 index 000000000000..7e699b10430e --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C28S8/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/jr2-a7280cr3-32p4-28x100G-8x10G.config.bcm diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/jr2-a7280cr3-32p4-40x100G.config.bcm b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/jr2-a7280cr3-32p4-40x100G.config.bcm new file mode 100644 index 000000000000..654a4d8f158f --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/jr2-a7280cr3-32p4-40x100G.config.bcm @@ -0,0 +1,759 @@ +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=rx39:tx35 +lane_to_serdes_map_nif_lane33.0=rx38:tx36 +lane_to_serdes_map_nif_lane34.0=rx32:tx32 +lane_to_serdes_map_nif_lane35.0=rx37:tx37 +lane_to_serdes_map_nif_lane36.0=rx33:tx34 +lane_to_serdes_map_nif_lane37.0=rx34:tx38 +lane_to_serdes_map_nif_lane38.0=rx35:tx33 +lane_to_serdes_map_nif_lane39.0=rx36:tx39 +lane_to_serdes_map_nif_lane40.0=rx44:tx47 +lane_to_serdes_map_nif_lane41.0=rx43:tx41 +lane_to_serdes_map_nif_lane42.0=rx47:tx46 +lane_to_serdes_map_nif_lane43.0=rx42:tx42 +lane_to_serdes_map_nif_lane44.0=rx45:tx45 +lane_to_serdes_map_nif_lane45.0=rx41:tx40 +lane_to_serdes_map_nif_lane46.0=rx46:tx44 +lane_to_serdes_map_nif_lane47.0=rx40:tx43 +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=rx81:tx83 +lane_to_serdes_map_nif_lane81.0=rx85:tx84 +lane_to_serdes_map_nif_lane82.0=rx80:tx80 +lane_to_serdes_map_nif_lane83.0=rx86:tx85 +lane_to_serdes_map_nif_lane84.0=rx82:tx82 +lane_to_serdes_map_nif_lane85.0=rx87:tx86 +lane_to_serdes_map_nif_lane86.0=rx83:tx81 +lane_to_serdes_map_nif_lane87.0=rx84:tx87 +lane_to_serdes_map_nif_lane88.0=rx91:tx95 +lane_to_serdes_map_nif_lane89.0=rx90:tx89 +lane_to_serdes_map_nif_lane90.0=rx95:tx94 +lane_to_serdes_map_nif_lane91.0=rx89:tx90 +lane_to_serdes_map_nif_lane92.0=rx93:tx93 +lane_to_serdes_map_nif_lane93.0=rx94:tx88 +lane_to_serdes_map_nif_lane94.0=rx92:tx92 +lane_to_serdes_map_nif_lane95.0=rx88:tx91 +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=0 +phy_rx_polarity_flip_phy33=1 +phy_rx_polarity_flip_phy34=1 +phy_rx_polarity_flip_phy35=0 +phy_rx_polarity_flip_phy36=0 +phy_rx_polarity_flip_phy37=0 +phy_rx_polarity_flip_phy38=1 +phy_rx_polarity_flip_phy39=0 +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=1 +phy_rx_polarity_flip_phy46=0 +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=0 +phy_rx_polarity_flip_phy81=0 +phy_rx_polarity_flip_phy82=1 +phy_rx_polarity_flip_phy83=1 +phy_rx_polarity_flip_phy84=1 +phy_rx_polarity_flip_phy85=0 +phy_rx_polarity_flip_phy86=1 +phy_rx_polarity_flip_phy87=1 +phy_rx_polarity_flip_phy88=0 +phy_rx_polarity_flip_phy89=0 +phy_rx_polarity_flip_phy90=1 +phy_rx_polarity_flip_phy91=1 +phy_rx_polarity_flip_phy92=0 +phy_rx_polarity_flip_phy93=1 +phy_rx_polarity_flip_phy94=0 +phy_rx_polarity_flip_phy95=0 +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=0 +phy_tx_polarity_flip_phy33=0 +phy_tx_polarity_flip_phy34=1 +phy_tx_polarity_flip_phy35=1 +phy_tx_polarity_flip_phy36=1 +phy_tx_polarity_flip_phy37=0 +phy_tx_polarity_flip_phy38=0 +phy_tx_polarity_flip_phy39=1 +phy_tx_polarity_flip_phy40=1 +phy_tx_polarity_flip_phy41=1 +phy_tx_polarity_flip_phy42=0 +phy_tx_polarity_flip_phy43=1 +phy_tx_polarity_flip_phy44=1 +phy_tx_polarity_flip_phy45=1 +phy_tx_polarity_flip_phy46=0 +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=0 +phy_tx_polarity_flip_phy81=1 +phy_tx_polarity_flip_phy82=1 +phy_tx_polarity_flip_phy83=1 +phy_tx_polarity_flip_phy84=1 +phy_tx_polarity_flip_phy85=0 +phy_tx_polarity_flip_phy86=0 +phy_tx_polarity_flip_phy87=1 +phy_tx_polarity_flip_phy88=1 +phy_tx_polarity_flip_phy89=0 +phy_tx_polarity_flip_phy90=0 +phy_tx_polarity_flip_phy91=1 +phy_tx_polarity_flip_phy92=1 +phy_tx_polarity_flip_phy93=1 +phy_tx_polarity_flip_phy94=0 +phy_tx_polarity_flip_phy95=0 + +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_32p4/Arista-7280CR3-C40/port_config.ini b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/port_config.ini new file mode 100644 index 000000000000..2ba638aee50d --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/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_32p4/Arista-7280CR3-C40/sai.profile b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/sai.profile new file mode 100644 index 000000000000..130a3f8c4cbd --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/jr2-a7280cr3-32p4-40x100G.config.bcm diff --git a/device/arista/x86_64-arista_7280cr3k_32p4 b/device/arista/x86_64-arista_7280cr3k_32p4 new file mode 120000 index 000000000000..d6e2ddbb64bd --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3k_32p4 @@ -0,0 +1 @@ +x86_64-arista_7280cr3_32p4 \ No newline at end of file diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/default_sku b/device/barefoot/x86_64-accton_as9516bf_32d-r0/default_sku new file mode 100644 index 000000000000..517fa893ae11 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/default_sku @@ -0,0 +1 @@ +newport t1 diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/installer.conf b/device/barefoot/x86_64-accton_as9516bf_32d-r0/installer.conf new file mode 100644 index 000000000000..3714ff053bb0 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/installer.conf @@ -0,0 +1 @@ +CONSOLE_SPEED=57600 diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers.json.j2 b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers.json.j2 new file mode 100644 index 000000000000..1083a6210fc9 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't0' %} +{%- include 'buffers_config.j2' %} diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t0.j2 b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..199f4ad135fb --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t0.j2 @@ -0,0 +1,71 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '4194304' %} +{% set ingress_lossy_pool_size = '7340032' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '7340032' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic", + "xoff": "2867200" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + } + } +{%- endmacro %} diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t1.j2 b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..01f50a4419e9 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/buffers_defaults_t1.j2 @@ -0,0 +1,71 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '2097152' %} +{% set ingress_lossy_pool_size = '5242880' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '5242880' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic", + "xoff": "2867200" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + } + } +{%- endmacro %} diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/pg_profile_lookup.ini b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/pg_profile_lookup.ini new file mode 100644 index 000000000000..602400325be0 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/pg_profile_lookup.ini @@ -0,0 +1,20 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 34816 18432 16384 7 + 25000 5m 34816 18432 16384 7 + 40000 5m 34816 18432 16384 7 + 50000 5m 34816 18432 16384 7 + 100000 5m 36864 18432 18432 7 + 400000 5m 36864 18432 18432 7 + 10000 40m 36864 18432 18432 7 + 25000 40m 39936 18432 21504 7 + 40000 40m 41984 18432 23552 7 + 50000 40m 41984 18432 23552 7 + 100000 40m 54272 18432 35840 7 + 400000 40m 54272 18432 35840 7 + 10000 300m 49152 18432 30720 7 + 25000 300m 71680 18432 53248 7 + 40000 300m 94208 18432 75776 7 + 50000 300m 94208 18432 75776 7 + 100000 300m 184320 18432 165888 7 + 400000 300m 184320 18432 165888 7 diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/port_config.ini b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/port_config.ini new file mode 100644 index 000000000000..3a3be79dc675 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed autoneg fec +Ethernet0 0,1,2,3,4,5,6,7 Ethernet0 1 400000 0 rs +Ethernet8 8,9,10,11,12,13,14,15 Ethernet8 2 400000 0 rs +Ethernet16 16,17,18,19,20,21,22,23 Ethernet16 3 400000 0 rs +Ethernet24 24,25,26,27,28,29,30,31 Ethernet24 4 400000 0 rs +Ethernet32 32,33,34,35,36,37,38,39 Ethernet32 5 400000 0 rs +Ethernet40 40,41,42,43,44,45,46,47 Ethernet40 6 400000 0 rs +Ethernet48 48,49,50,51,52,53,54,55 Ethernet48 7 400000 0 rs +Ethernet56 56,57,58,59,60,61,62,63 Ethernet56 8 400000 0 rs +Ethernet64 64,65,66,67,68,69,70,71 Ethernet64 9 400000 0 rs +Ethernet72 72,73,74,75,76,77,78,79 Ethernet72 10 400000 0 rs +Ethernet80 80,81,82,83,84,85,86,87 Ethernet80 11 400000 0 rs +Ethernet88 88,89,90,91,92,93,94,95 Ethernet88 12 400000 0 rs +Ethernet96 96,97,98,99,100,101,102,103 Ethernet96 13 400000 0 rs +Ethernet104 104,105,106,107,108,109,110,111 Ethernet104 14 400000 0 rs +Ethernet112 112,113,114,115,116,117,118,119 Ethernet112 15 400000 0 rs +Ethernet120 120,121,122,123,124,125,126,127 Ethernet120 16 400000 0 rs +Ethernet128 128,129,130,131,132,133,134,135 Ethernet128 17 400000 0 rs +Ethernet136 136,137,138,139,140,141,142,143 Ethernet136 18 400000 0 rs +Ethernet144 144,145,146,147,148,149,150,151 Ethernet144 19 400000 0 rs +Ethernet152 152,153,154,155,156,157,158,159 Ethernet152 20 400000 0 rs +Ethernet160 160,161,162,163,164,165,166,167 Ethernet160 21 400000 0 rs +Ethernet168 168,169,170,171,172,173,174,175 Ethernet168 22 400000 0 rs +Ethernet176 176,177,178,179,180,181,182,183 Ethernet176 23 400000 0 rs +Ethernet184 184,185,186,187,188,189,190,191 Ethernet184 24 400000 0 rs +Ethernet192 192,193,194,195,196,197,198,199 Ethernet192 25 400000 0 rs +Ethernet200 200,201,202,203,204,205,206,207 Ethernet200 26 400000 0 rs +Ethernet208 208,209,210,211,212,213,214,215 Ethernet208 27 400000 0 rs +Ethernet216 216,217,218,219,220,221,222,223 Ethernet216 28 400000 0 rs +Ethernet224 224,225,226,227,228,229,230,231 Ethernet224 29 400000 0 rs +Ethernet232 232,233,234,235,236,237,238,239 Ethernet232 30 400000 0 rs +Ethernet240 240,241,242,243,244,245,246,247 Ethernet240 31 400000 0 rs +Ethernet248 248,249,250,251,252,253,254,255 Ethernet248 32 400000 0 rs diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/qos.json.j2 b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/qos.json.j2 new file mode 100644 index 000000000000..a685277448f1 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/qos.json.j2 @@ -0,0 +1,10 @@ +{%- macro generate_tc_to_pg_map() %} + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "3": "3", + "4": "4" + } + }, +{%- endmacro %} + +{%- include 'qos_config.j2' %} diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/sai.profile b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/sai.profile new file mode 100644 index 000000000000..037b5c135370 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/sai.profile @@ -0,0 +1,3 @@ +SAI_KEY_WARM_BOOT_WRITE_FILE=/var/warmboot/sai-warmboot.bin +SAI_KEY_WARM_BOOT_READ_FILE=/var/warmboot/sai-warmboot.bin + diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/switch-tna-sai.conf b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/switch-tna-sai.conf new file mode 100644 index 000000000000..cf6e445dba1a --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/newport/switch-tna-sai.conf @@ -0,0 +1,40 @@ +{ + "instance": 0, + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino2", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0", + "pcie_domain": 0, + "pcie_bus": 5, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "p4_devices": [ + { + "device-id": 0, + "agent0": "lib/platform/x86_64-accton_as9516bf_32d-r0/libpltfm_mgr.so", + "p4_programs": [ + { + "p4_pipelines": [ + { + "p4_pipeline_name": "pipe", + "config": "share/switch/pipe/tofino2.bin", + "context": "share/switch/pipe/context.json" + } + ], + "program-name": "switch", + "sai": "lib/libsai.so", + "bfrt-config": "share/switch/bf-rt.json", + "model_json_path" : "share/switch/aug_model.json", + "switchapi_port_add": false, + "non_default_port_ppgs": 5 + } + ] + } + ] +} diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/plugins b/device/barefoot/x86_64-accton_as9516bf_32d-r0/plugins new file mode 120000 index 000000000000..a8464d1ec2b6 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/plugins @@ -0,0 +1 @@ +../x86_64-accton_wedge100bf_32x-r0/plugins/ \ No newline at end of file diff --git a/device/barefoot/x86_64-accton_as9516bf_32d-r0/pmon_daemon_control.json b/device/barefoot/x86_64-accton_as9516bf_32d-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..3a76f2fdd0e4 --- /dev/null +++ b/device/barefoot/x86_64-accton_as9516bf_32d-r0/pmon_daemon_control.json @@ -0,0 +1,6 @@ +{ + "skip_ledd": true, + "skip_xcvrd": false, + "skip_psud": false, + "skip_syseepromd": false +} diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-sai.conf b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-sai.conf index 089153b6a5ce..fc224c9602e4 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-sai.conf +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-sai.conf @@ -25,7 +25,7 @@ "table-config": "share/tofinopd/switch/context.json", "tofino-bin": "share/tofinopd/switch/tofino.bin", "switchapi": "lib/libswitchapi.so", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "agent0": "lib/platform/x86_64-accton_wedge100bf_32x-r0/libpltfm_mgr.so", "switchapi_port_add": false, "non_default_port_ppgs": 5 diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-tna-sai.conf b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-tna-sai.conf index 79b10cafa864..085a1b8dcdfc 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-tna-sai.conf +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-tna-sai.conf @@ -23,13 +23,13 @@ "p4_pipelines": [ { "p4_pipeline_name": "pipe", - "config": "share/tofinopd/switch/pipe/tofino.bin", - "context": "share/tofinopd/switch/pipe/context.json" + "config": "share/switch/pipe/tofino.bin", + "context": "share/switch/pipe/context.json" } ], "program-name": "switch", - "switchsai": "lib/libswitchsai.so", - "bfrt-config": "share/tofinopd/switch/bf-rt.json", + "sai": "lib/libsai.so", + "bfrt-config": "share/switch/bf-rt.json", "model_json_path" : "share/switch/aug_model.json", "switchapi_port_add": false, "non_default_port_ppgs": 5 diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/eeprom.py b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/eeprom.py index 1faeff9d18bf..9c14441475d4 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/eeprom.py +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/eeprom.py @@ -9,6 +9,9 @@ import sys import errno import datetime + import logging + import logging.config + import yaml sys.path.append(os.path.dirname(__file__)) import pltfm_mgr_rpc @@ -71,12 +74,17 @@ pltfm_mgr = None EEPROM_SYMLINK = "/var/run/platform/eeprom/syseeprom" - +EEPROM_STATUS = "/var/run/platform/eeprom/status" class board(eeprom_tlvinfo.TlvInfoDecoder): + RETRIES = 3 def __init__(self, name, path, cpld_root, ro): + with open(os.path.dirname(__file__) + "/logging.conf", 'r') as f: + config_dict = yaml.load(f) + logging.config.dictConfig(config_dict) + if not os.path.exists(os.path.dirname(EEPROM_SYMLINK)): try: os.makedirs(os.path.dirname(EEPROM_SYMLINK)) @@ -85,10 +93,17 @@ def __init__(self, name, path, cpld_root, ro): raise open(EEPROM_SYMLINK, 'a').close() + f = open(EEPROM_STATUS, 'w') + f.write("initializing..") + f.close() self.eeprom_path = EEPROM_SYMLINK - super(board, self).__init__(self.eeprom_path, 0, '', True) - self.eeprom_init() + super(board, self).__init__(self.eeprom_path, 0, EEPROM_STATUS, True) + + for attempt in range(self.RETRIES): + if self.eeprom_init() or (attempt + 1 >= self.RETRIES): + break + time.sleep(1) def thrift_setup(self): global thrift_server, transport, pltfm_mgr @@ -109,9 +124,17 @@ def thrift_teardown(self): def eeprom_init(self): global pltfm_mgr - self.thrift_setup() - eeprom = pltfm_mgr.pltfm_mgr_sys_eeprom_get() - self.thrift_teardown() + + try: + self.thrift_setup() + eeprom = pltfm_mgr.pltfm_mgr_sys_eeprom_get() + self.thrift_teardown() + except: + return False + + f = open(EEPROM_STATUS, 'w') + f.write("ok") + f.close() eeprom_params = "" for attr, val in eeprom.__dict__.iteritems(): @@ -143,3 +166,5 @@ def eeprom_init(self): sys.stdout = orig_stdout eeprom_base.EepromDecoder.write_eeprom(self, new_e) + return True + diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/logging.conf b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/logging.conf new file mode 100644 index 000000000000..d7fd84773404 --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/logging.conf @@ -0,0 +1,17 @@ +version: 1 +disable_existing_loggers: False + +formatters: + simple: + format: '%(asctime)s %(name)-30s %(levelname)-7s %(message)s' + +handlers: + file: + class: logging.handlers.RotatingFileHandler + formatter: simple + filename: /var/log/platform.log + +root: + level: ERROR + handlers: + - file diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/psuutil.py b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/psuutil.py index 734901c2adfa..2c0e2fdb224e 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/psuutil.py +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/psuutil.py @@ -63,9 +63,13 @@ def get_psu_status(self, index): return False global pltfm_mgr - self.thrift_setup() - psu_info = pltfm_mgr.pltfm_mgr_pwr_supply_info_get(index) - self.thrift_teardown() + + try: + self.thrift_setup() + psu_info = pltfm_mgr.pltfm_mgr_pwr_supply_info_get(index) + self.thrift_teardown() + except: + return False return (psu_info.ffault == False) @@ -80,9 +84,13 @@ def get_psu_presence(self, index): return False global pltfm_mgr - self.thrift_setup() - status = pltfm_mgr.pltfm_mgr_pwr_supply_present_get(index) - self.thrift_teardown() + + try: + self.thrift_setup() + status = pltfm_mgr.pltfm_mgr_pwr_supply_present_get(index) + self.thrift_teardown() + except: + return False return status diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/sfputil.py b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/sfputil.py index c92bc4212123..1daee453573e 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 @@ -34,6 +34,7 @@ class SfpUtil(SfpUtilBase): QSFP_PORT_START = 1 QSFP_PORT_END = 0 EEPROM_OFFSET = 0 + QSFP_CHECK_INTERVAL = 4 @property def port_start(self): @@ -56,6 +57,11 @@ def port_to_eeprom_mapping(self): raise Exception() def __init__(self): + self.ready = False + self.phy_port_dict = {'-1': 'system_not_ready'} + self.phy_port_cur_state = {} + self.qsfp_interval = self.QSFP_CHECK_INTERVAL + if not os.path.exists(os.path.dirname(SFP_EEPROM_CACHE)): try: os.makedirs(os.path.dirname(SFP_EEPROM_CACHE)) @@ -129,7 +135,7 @@ def set_low_power_mode(self, port_num, lpmode): self.thrift_setup() status = pltfm_mgr.pltfm_mgr_qsfp_lpmode_set(port_num, lpmode) self.thrift_teardown() - return status + return (status == 0) def reset(self, port_num): # Check for invalid port_num @@ -142,12 +148,76 @@ def reset(self, port_num): self.thrift_teardown() return status + def check_transceiver_change(self): + if not self.ready: + return + + self.phy_port_dict = {} + + try: + self.thrift_setup() + except: + return + + # Get presence of each SFP + for port in range(self.port_start, self.port_end + 1): + try: + sfp_resent = pltfm_mgr.pltfm_mgr_qsfp_presence_get(port) + except: + sfp_resent = False + sfp_state = '1' if sfp_resent else '0' + + if port in self.phy_port_cur_state: + if self.phy_port_cur_state[port] != sfp_state: + self.phy_port_dict[port] = sfp_state + else: + self.phy_port_dict[port] = sfp_state + + # Update port current state + self.phy_port_cur_state[port] = sfp_state + + self.thrift_teardown() + def get_transceiver_change_event(self, timeout=0): - phy_port_dict = {} - status = True - # TODO: Process transceiver plug-in/out event - time.sleep(1) - return status, phy_port_dict + forever = False + if timeout == 0: + forever = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + print "get_transceiver_change_event:Invalid timeout value", timeout + return False, {} + + while forever or timeout > 0: + if not self.ready: + try: + self.thrift_setup() + self.thrift_teardown() + except: + pass + else: + self.ready = True + self.phy_port_dict = {} + break + elif self.qsfp_interval == 0: + self.qsfp_interval = self.QSFP_CHECK_INTERVAL + + # Process transceiver plug-in/out event + self.check_transceiver_change() + + # Break if tranceiver state has changed + if bool(self.phy_port_dict): + break + + if timeout: + timeout -= 1 + + if self.qsfp_interval: + self.qsfp_interval -= 1 + + time.sleep(1) + + return self.ready, self.phy_port_dict def _get_port_eeprom_path(self, port_num, devid): eeprom_path = None 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 new file mode 100644 index 000000000000..3a76f2fdd0e4 --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/pmon_daemon_control.json @@ -0,0 +1,6 @@ +{ + "skip_ledd": true, + "skip_xcvrd": false, + "skip_psud": false, + "skip_syseepromd": false +} diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/port_config.ini b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/port_config.ini index 7a3b600fe8de..def494da0081 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/port_config.ini +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/port_config.ini @@ -62,4 +62,5 @@ Ethernet236 236,237,238,239 Ethernet236 60 100000 0 rs Ethernet240 240,241,242,243 Ethernet240 61 100000 0 rs Ethernet244 244,245,246,247 Ethernet244 62 100000 0 rs Ethernet248 248,249,250,251 Ethernet248 63 100000 0 rs -Ethernet252 252,253,254,255 Etherner252 64 100000 0 rs +Ethernet252 252,253,254,255 Ethernet252 64 100000 0 rs +Ethernet256 256,257,258,259 Ethernet256 65 100000 0 none diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-sai.conf b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-sai.conf index 1f0ff8b32bb1..81a7d7bc28c3 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-sai.conf +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-sai.conf @@ -25,7 +25,7 @@ "table-config": "share/tofinopd/switch/context.json", "tofino-bin": "share/tofinopd/switch/tofino.bin", "switchapi": "lib/libswitchapi.so", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "agent0": "lib/platform/x86_64-accton_wedge100bf_65x-r0/libpltfm_mgr.so", "switchapi_port_add": false, "non_default_port_ppgs": 5 diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-tna-sai.conf b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-tna-sai.conf index 647f41838285..ddcb9d4ba287 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-tna-sai.conf +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-tna-sai.conf @@ -23,13 +23,13 @@ "p4_pipelines": [ { "p4_pipeline_name": "pipe", - "config": "share/tofinopd/switch/pipe/tofino.bin", - "context": "share/tofinopd/switch/pipe/context.json" + "config": "share/switch/pipe/tofino.bin", + "context": "share/switch/pipe/context.json" } ], "program-name": "switch", - "switchsai": "lib/libswitchsai.so", - "bfrt-config": "share/tofinopd/switch/bf-rt.json", + "sai": "lib/libsai.so", + "bfrt-config": "share/switch/bf-rt.json", "model_json_path" : "share/switch/aug_model.json", "switchapi_port_add": false, "non_default_port_ppgs": 5 diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..3a76f2fdd0e4 --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/pmon_daemon_control.json @@ -0,0 +1,6 @@ +{ + "skip_ledd": true, + "skip_xcvrd": false, + "skip_psud": false, + "skip_syseepromd": false +} diff --git a/device/celestica/x86_64-cel_e1031-r0/fancontrol-B2F b/device/celestica/x86_64-cel_e1031-r0/fancontrol-B2F index cab392995bb5..883f3c0c899d 100644 --- a/device/celestica/x86_64-cel_e1031-r0/fancontrol-B2F +++ b/device/celestica/x86_64-cel_e1031-r0/fancontrol-B2F @@ -1,7 +1,7 @@ # Configuration file generated by pwmconfig, changes will be lost INTERVAL=2 DEVPATH=hwmon3=devices/pci0000:00/0000:00:13.0/i2c-0/i2c-8/i2c-23/23-004d hwmon2=devices/pci0000:00/0000:00:13.0/i2c-0/i2c-8/i2c-11/11-001a -DEVNAME=hwmon3=emc2305 hwmon2=max6697 +DEVNAME=hwmon3=emc2305 hwmon2=max6699 FCTEMPS=hwmon3/device/pwm1=hwmon2/temp1_input hwmon3/device/pwm2=hwmon2/temp1_input hwmon3/device/pwm4=hwmon2/temp1_input FCFANS=hwmon3/device/pwm1=hwmon3/device/fan1_input hwmon3/device/pwm2=hwmon3/device/fan2_input hwmon3/device/pwm4=hwmon3/device/fan4_input MINTEMP=hwmon3/device/pwm1=27 hwmon3/device/pwm2=27 hwmon3/device/pwm4=27 diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/__init__.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/__init__.py index e69de29bb2d1..d82f3749319c 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/__init__.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["platform", "chassis"] +from sonic_platform import * diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py index 85da302fcc18..99eb49ce53e0 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py @@ -21,43 +21,53 @@ from sonic_platform.component import Component from sonic_platform.watchdog import Watchdog from sonic_platform.thermal import Thermal + from sonic_platform.sfp import Sfp + from sonic_platform.eeprom import Tlv except ImportError as e: raise ImportError(str(e) + "- required module not found") -NUM_FAN = 3 +NUM_FAN_TRAY = 3 +NUM_FAN = 1 NUM_PSU = 2 NUM_THERMAL = 7 -CONFIG_DB_PATH = "/etc/sonic/config_db.json" +NUM_SFP = 52 +NUM_COMPONENT = 3 RESET_REGISTER = "0x112" -REBOOT_CAUSE_PATH = "/host/reboot-cause/previous-reboot-cause.txt" -COMPONENT_NAME_LIST = ["SMC_CPLD", "MMC_CPLD", "BIOS"] +HOST_REBOOT_CAUSE_PATH = "/host/reboot-cause/previous-reboot-cause.txt" +PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/previous-reboot-cause.txt" +HOST_CHK_CMD = "docker > /dev/null 2>&1" class Chassis(ChassisBase): """Platform-specific Chassis class""" def __init__(self): + ChassisBase.__init__(self) self.config_data = {} - for index in range(0, NUM_FAN): - fan = Fan(index) - self._fan_list.append(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) for index in range(0, NUM_THERMAL): thermal = Thermal(index) self._thermal_list.append(thermal) - ChassisBase.__init__(self) - self._component_name_list = COMPONENT_NAME_LIST + for index in range(0, NUM_SFP): + sfp = Sfp(index) + self._sfp_list.append(sfp) + for index in range(0, NUM_COMPONENT): + component = Component(index) + self._component_list.append(component) + self._reboot_cause_path = HOST_REBOOT_CAUSE_PATH if self.__is_host( + ) else PMON_REBOOT_CAUSE_PATH + self._watchdog = Watchdog() + self._eeprom = Tlv() - def __read_config_db(self): - try: - with open(CONFIG_DB_PATH, 'r') as fd: - data = json.load(fd) - return data - except IOError: - raise IOError("Unable to open config_db file !") + def __is_host(self): + return os.system(HOST_CHK_CMD) == 0 def __read_txt_file(self, file_path): try: @@ -65,7 +75,8 @@ def __read_txt_file(self, file_path): data = fd.read() return data.strip() except IOError: - raise IOError("Unable to open %s file !" % file_path) + pass + return None def get_base_mac(self): """ @@ -74,42 +85,25 @@ def get_base_mac(self): A string containing the MAC address in the format 'XX:XX:XX:XX:XX:XX' """ - try: - self.config_data = self.__read_config_db() - base_mac = self.config_data["DEVICE_METADATA"]["localhost"]["mac"] - return str(base_mac) - except KeyError: - return str(None) + return self._eeprom.get_mac() - def get_firmware_version(self, component_name): + def get_serial_number(self): """ - Retrieves platform-specific hardware/firmware versions for chassis - componenets such as BIOS, CPLD, FPGA, etc. - Args: - type: A string, component name - + Retrieves the hardware serial number for the chassis Returns: - A string containing platform-specific component versions + A string containing the hardware serial number for this chassis. """ - self.component = Component(component_name) - if component_name not in self._component_name_list: - return None - return self.component.get_firmware_version() + return self._eeprom.get_serial() - def install_component_firmware(self, component_name, image_path): + def get_system_eeprom_info(self): """ - Install firmware to module - Args: - type: A string, component name. - image_path: A string, path to firmware image. - + Retrieves the full content of system EEPROM information for the chassis Returns: - A boolean, True if install successfully, False if not + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. """ - self.component = Component(component_name) - if component_name not in self._component_name_list: - return False - return self.component.upgrade_firmware(image_path) + return self._eeprom.get_eeprom() def get_reboot_cause(self): """ @@ -122,18 +116,18 @@ def get_reboot_cause(self): is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used to pass a description of the reboot cause. """ - self.component = Component("SMC_CPLD") description = 'None' reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER - hw_reboot_cause = self.component.get_register_value(RESET_REGISTER) - sw_reboot_cause = self.__read_txt_file(REBOOT_CAUSE_PATH) + hw_reboot_cause = self._component_list[0].get_register_value(RESET_REGISTER) + sw_reboot_cause = self.__read_txt_file( + self._reboot_cause_path) or "Unknown" - if sw_reboot_cause != "Unexpected reboot": + if hw_reboot_cause == "0x55": reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE description = sw_reboot_cause elif hw_reboot_cause == "0x11": reboot_cause = self.REBOOT_CAUSE_POWER_LOSS - elif hw_reboot_cause == "0x33" or hw_reboot_cause == "0x55": + elif hw_reboot_cause == "0x33": reboot_cause = self.REBOOT_CAUSE_WATCHDOG else: reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py index b80deabb178d..ad6810b14c38 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py @@ -15,7 +15,7 @@ import subprocess try: - from sonic_platform_base.device_base import DeviceBase + from sonic_platform_base.component_base import ComponentBase except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -24,16 +24,20 @@ CONFIG_DB_PATH = "/etc/sonic/config_db.json" SMC_CPLD_PATH = "/sys/devices/platform/e1031.smc/version" GETREG_PATH = "/sys/devices/platform/e1031.smc/getreg" +COMPONENT_NAME_LIST = ["SMC_CPLD", "MMC_CPLD", "BIOS"] +COMPONENT_DES_LIST = ["System Management Controller", + "Module Management CPLD", "Basic Input/Output System"] -class Component(DeviceBase): +class Component(ComponentBase): """Platform-specific Component class""" DEVICE_TYPE = "component" - def __init__(self, component_name): - DeviceBase.__init__(self) - self.name = component_name.upper() + def __init__(self, component_index): + ComponentBase.__init__(self) + self.index = component_index + self.name = self.get_name() def __run_command(self, command): # Run bash command and print output to stdout @@ -86,6 +90,22 @@ def __get_cpld_version(self): cpld_version["MMC_CPLD"] = mmc_cpld_version return cpld_version + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + return COMPONENT_NAME_LIST[self.index] + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + return COMPONENT_DES_LIST[self.index] + def get_firmware_version(self): """ Retrieves the firmware version of module @@ -102,7 +122,7 @@ def get_firmware_version(self): return fw_version - def upgrade_firmware(self, image_path): + def install_firmware(self, image_path): """ Install firmware to module Args: @@ -121,7 +141,6 @@ def upgrade_firmware(self, image_path): shutil.copy(image_path, new_image_path) install_command = "ispvm %s" % new_image_path elif self.name == "BIOS": - print("Not supported") - return False + install_command = "afulnx_64 %s /p /b /n /x /r" % image_path return self.__run_command(install_command) diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/eeprom.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/eeprom.py new file mode 100644 index 000000000000..20f3db111f66 --- /dev/null +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/eeprom.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica Haliburton +# +# 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 glob + import os + import sys + import imp + import re + from array import array + from cStringIO import StringIO + from sonic_platform_base.sonic_eeprom import eeprom_dts + from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError(str(e) + "- required module not found") + +CACHE_ROOT = '/var/cache/sonic/decode-syseeprom' +CACHE_FILE = 'syseeprom_cache' + + +class Tlv(eeprom_tlvinfo.TlvInfoDecoder): + + EEPROM_DECODE_HEADLINES = 6 + + def __init__(self): + self._eeprom_path = "/sys/class/i2c-adapter/i2c-2/2-0050/eeprom" + super(Tlv, self).__init__(self._eeprom_path, 0, '', True) + self._eeprom = self._load_eeprom() + + def __parse_output(self, decode_output): + decode_output.replace('\0', '') + lines = decode_output.split('\n') + lines = lines[self.EEPROM_DECODE_HEADLINES:] + _eeprom_info_dict = dict() + + for line in lines: + try: + match = re.search( + '(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+)', line) + if match is not None: + idx = match.group(1) + value = match.group(3).rstrip('\0') + + _eeprom_info_dict[idx] = value + except: + pass + return _eeprom_info_dict + + def _load_eeprom(self): + original_stdout = sys.stdout + sys.stdout = StringIO() + try: + self.read_eeprom_db() + except: + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + return self.__parse_output(decode_output) + + status = self.check_status() + if 'ok' not in status: + return False + + if not os.path.exists(CACHE_ROOT): + try: + os.makedirs(CACHE_ROOT) + except: + pass + + # + # only the eeprom classes that inherit from eeprom_base + # support caching. Others will work normally + # + try: + self.set_cache_name(os.path.join(CACHE_ROOT, CACHE_FILE)) + except: + pass + + e = self.read_eeprom() + if e is None: + return 0 + + try: + self.update_cache(e) + except: + pass + + self.decode_eeprom(e) + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + + (is_valid, valid_crc) = self.is_checksum_valid(e) + if not is_valid: + return False + + return self.__parse_output(decode_output) + + def get_eeprom(self): + return self._eeprom + + def get_serial(self): + return self._eeprom.get('0x23', "Undefined.") + + def get_mac(self): + return self._eeprom.get('0x24', "Undefined.") diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py index ad993ce24182..2c5bc5c0c45c 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py @@ -17,34 +17,50 @@ except ImportError as e: raise ImportError(str(e) + "- required module not found") -EMC2305_FAN_PATH = "/sys/bus/i2c/drivers/emc2305/" +EMC2305_PATH = "/sys/bus/i2c/drivers/emc2305/" FAN_PATH = "/sys/devices/platform/e1031.smc/" -SYS_GPIO_DIR = "/sys/class/gpio" EMC2305_MAX_PWM = 255 EMC2305_FAN_PWM = "pwm{}" EMC2305_FAN_TARGET = "fan{}_target" EMC2305_FAN_INPUT = "pwm{}" FAN_NAME_LIST = ["FAN-1", "FAN-2", "FAN-3"] +PSU_FAN_MAX_RPM = 11000 +PSU_HWMON_PATH = "/sys/bus/i2c/devices/i2c-{0}/{0}-00{1}/hwmon" +PSU_I2C_MAPPING = { + 0: { + "num": 13, + "addr": "5b" + }, + 1: { + "num": 12, + "addr": "5a" + }, +} class Fan(FanBase): """Platform-specific Fan class""" - def __init__(self, fan_index): - self.index = fan_index - self.config_data = {} - self.fan_speed = 0 + def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0): + self.fan_index = fan_index + self.fan_tray_index = fan_tray_index + self.is_psu_fan = is_psu_fan + if self.is_psu_fan: + self.psu_index = psu_index + self.psu_i2c_num = PSU_I2C_MAPPING[self.psu_index]["num"] + self.psu_i2c_addr = PSU_I2C_MAPPING[self.psu_index]["addr"] + self.psu_hwmon_path = PSU_HWMON_PATH.format( + self.psu_i2c_num, self.psu_i2c_addr) # e1031 fan attributes # Single emc2305 chip located at i2c-23-4d # to control a fan module - self.e1031_emc2305_chip = [ + self.emc2305_chip_mapping = [ { 'device': "23-004d", 'index_map': [1, 2, 4] } ] - self.fan_e1031_presence = "fan{}_prs" self.fan_e1031_direction = "fan{}_dir" self.fan_e1031_led = "fan{}_led" @@ -55,84 +71,103 @@ def __init__(self, fan_index): } FanBase.__init__(self) - def get_direction(self): - - direction = self.FAN_DIRECTION_INTAKE - + def __read_txt_file(self, file_path): try: - fan_direction_file = (FAN_PATH + - self.fan_e1031_direction.format(self.index+1)) - with open(fan_direction_file, 'r') as file: - raw = file.read().strip('\r\n') - if str(raw).upper() == "F2B": - direction = self.FAN_DIRECTION_INTAKE - else: - direction = self.FAN_DIRECTION_EXHAUST + 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: + with open(file_path, 'w') as fd: + fd.write(str(value)) + except: return False + return True + + def __search_file_by_name(self, directory, file_name): + for dirpath, dirnames, files in os.walk(directory): + for name in files: + file_path = os.path.join(dirpath, name) + if name in file_name: + return file_path + return None + + def get_direction(self): + """ + Retrieves the direction of fan + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + direction = self.FAN_DIRECTION_EXHAUST + if not self.is_psu_fan: + fan_direction_file = (FAN_PATH + + self.fan_e1031_direction.format(self.fan_tray_index+1)) + raw = self.__read_txt_file(fan_direction_file).strip('\r\n') + direction = self.FAN_DIRECTION_INTAKE if str( + raw).upper() == "F2B" else self.FAN_DIRECTION_EXHAUST return direction def get_speed(self): """ - E1031 platform specific data: + Retrieves the speed of fan as a percentage of full speed + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + Note: speed = pwm_in/255*100 """ - # TODO: Seperate PSU's fan and main fan class - if self.fan_speed != 0: - return self.fan_speed - else: - speed = 0 - pwm = [] - emc2305_chips = self.e1031_emc2305_chip - - for chip in emc2305_chips: - device = chip['device'] - fan_index = chip['index_map'] - sysfs_path = "%s%s/%s" % ( - EMC2305_FAN_PATH, device, EMC2305_FAN_INPUT) - sysfs_path = sysfs_path.format(fan_index[self.index]) - try: - with open(sysfs_path, 'r') as file: - raw = file.read().strip('\r\n') - pwm.append(int(raw, 10)) - except IOError: - raise IOError("Unable to open " + sysfs_path) - - speed = math.ceil( - float(pwm[0]) * 100 / EMC2305_MAX_PWM) - - return int(speed) + speed = 0 + if self.is_psu_fan: + 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_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(): + 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_INPUT) + 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 + speed = math.ceil(float(pwm * 100 / EMC2305_MAX_PWM)) + + return int(speed) def get_target_speed(self): """ - E1031 platform specific data: + Retrieves the target (expected) speed of the fan + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + Note: speed_pc = pwm_target/255*100 0 : when PWM mode is use pwm : when pwm mode is not use - """ target = 0 - pwm = [] - emc2305_chips = self.e1031_emc2305_chip - - for chip in emc2305_chips: + 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_FAN_PATH, device, EMC2305_FAN_TARGET) - sysfs_path = sysfs_path.format(fan_index[self.index]) - try: - with open(sysfs_path, 'r') as file: - raw = file.read().strip('\r\n') - pwm.append(int(raw, 10)) - except IOError: - raise IOError("Unable to open " + sysfs_path) - - target = pwm[0] * 100 / EMC2305_MAX_PWM + 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 @@ -147,40 +182,50 @@ def get_speed_tolerance(self): def set_speed(self, speed): """ - Depends on pwm or target mode is selected: + Sets the fan speed + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + Returns: + A boolean, True if speed is set successfully, False if not + + Note: + Depends on pwm or target mode is selected: 1) pwm = speed_pc * 255 <-- Currently use this mode. 2) target_pwm = speed_pc * 100 / 255 2.1) set pwm{}_enable to 3 """ pwm = speed * 255 / 100 - emc2305_chips = self.e1031_emc2305_chip - - for chip in emc2305_chips: + if not self.is_psu_fan and self.get_presence(): + chip = self.emc2305_chip_mapping[self.fan_index] device = chip['device'] fan_index = chip['index_map'] sysfs_path = "%s%s/%s" % ( - EMC2305_FAN_PATH, device, EMC2305_FAN_PWM) - sysfs_path = sysfs_path.format(fan_index[self.index]) - try: - with open(sysfs_path, 'w') as file: - file.write(str(int(pwm))) - except IOError: - return False + EMC2305_PATH, device, EMC2305_FAN_PWM) + sysfs_path = sysfs_path.format(fan_index[self.fan_tray_index]) + return self.__write_txt_file(sysfs_path, int(pwm)) - return True + return False def set_status_led(self, color): - - try: + """ + Sets the state of the fan module status LED + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if status LED state is set successfully, False if not + """ + set_status_led = False + if not self.is_psu_fan: fan_led_file = (FAN_PATH + - self.fan_e1031_led.format(self.index+1)) - with open(fan_led_file, 'r') as file: - file.write(self.fan_e1031_led_col_map[color]) - except IOError: - return False + self.fan_e1031_led.format(self.fan_tray_index+1)) - return True + set_status_led = self.__write_txt_file( + fan_led_file, self.fan_e1031_led_col_map[color]) if self.get_presence() else False + + return set_status_led def get_name(self): """ @@ -188,7 +233,10 @@ def get_name(self): Returns: string: The name of the device """ - return FAN_NAME_LIST[self.index] + fan_name = FAN_NAME_LIST[self.fan_tray_index] if not self.is_psu_fan else "PSU-{} FAN-{}".format( + self.psu_index+1, self.fan_index+1) + + return fan_name def get_presence(self): """ @@ -196,13 +244,8 @@ def get_presence(self): Returns: bool: True if PSU is present, False if not """ + fan_direction_file = (FAN_PATH + + self.fan_e1031_presence.format(self.fan_tray_index+1)) + present_str = self.__read_txt_file(fan_direction_file) or '1' - try: - fan_direction_file = (FAN_PATH + - self.fan_e1031_presence.format(self.index+1)) - with open(fan_direction_file, 'r') as file: - present = int(file.read().strip('\r\n')) - except IOError: - return False - - return present == 0 + return int(present_str) == 0 if not self.is_psu_fan else True diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/psu.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/psu.py index 73b890a8b773..9777bb6fea64 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/psu.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/psu.py @@ -18,8 +18,20 @@ raise ImportError(str(e) + "- required module not found") FAN_E1031_SPEED_PATH = "/sys/class/hwmon/hwmon{}/fan1_input" +HWMON_PATH = "/sys/bus/i2c/devices/i2c-{0}/{0}-00{1}/hwmon" FAN_MAX_RPM = 11000 PSU_NAME_LIST = ["PSU-R", "PSU-L"] +PSU_NUM_FAN = [1, 1] +PSU_I2C_MAPPING = { + 0: { + "num": 13, + "addr": "5b" + }, + 1: { + "num": 12, + "addr": "5a" + }, +} class Psu(PsuBase): @@ -31,26 +43,109 @@ def __init__(self, psu_index): self.psu_path = "/sys/devices/platform/e1031.smc/" self.psu_presence = "psu{}_prs" self.psu_oper_status = "psu{}_status" + self.i2c_num = PSU_I2C_MAPPING[self.index]["num"] + self.i2c_addr = PSU_I2C_MAPPING[self.index]["addr"] + self.hwmon_path = HWMON_PATH.format(self.i2c_num, self.i2c_addr) + for fan_index in range(0, PSU_NUM_FAN[self.index]): + fan = Fan(fan_index, 0, is_psu_fan=True, psu_index=self.index) + self._fan_list.append(fan) + PsuBase.__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 __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): + return file_path + return None - def get_fan(self): + def get_voltage(self): """ - Retrieves object representing the fan module contained in this PSU + Retrieves current PSU voltage output Returns: - An object dervied from FanBase representing the fan module - contained in this PSU + A float number, the output voltage in volts, + e.g. 12.1 """ - fan_speed_path = FAN_E1031_SPEED_PATH.format( - str(self.index+3)) - try: - with open(fan_speed_path) as fan_speed_file: - fan_speed_rpm = int(fan_speed_file.read()) - except IOError: - fan_speed = 0 + psu_voltage = 0.0 + voltage_name = "in{}_input" + voltage_label = "vout1" - fan_speed = float(fan_speed_rpm)/FAN_MAX_RPM * 100 - fan = Fan(0) - fan.fan_speed = int(fan_speed) if int(fan_speed) <= 100 else 100 - return fan + vout_label_path = self.__search_file_by_contain( + self.hwmon_path, voltage_label, "in") + if vout_label_path: + dir_name = os.path.dirname(vout_label_path) + basename = os.path.basename(vout_label_path) + in_num = filter(str.isdigit, basename) + vout_path = os.path.join( + dir_name, voltage_name.format(in_num)) + vout_val = self.__read_txt_file(vout_path) + psu_voltage = float(vout_val) / 1000 + + return psu_voltage + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + Returns: + A float number, the electric current in amperes, e.g 15.4 + """ + psu_current = 0.0 + current_name = "curr{}_input" + current_label = "iout1" + + curr_label_path = self.__search_file_by_contain( + self.hwmon_path, current_label, "cur") + if curr_label_path: + dir_name = os.path.dirname(curr_label_path) + basename = os.path.basename(curr_label_path) + cur_num = filter(str.isdigit, basename) + cur_path = os.path.join( + dir_name, current_name.format(cur_num)) + cur_val = self.__read_txt_file(cur_path) + psu_current = float(cur_val) / 1000 + + return psu_current + + def get_power(self): + """ + Retrieves current energy supplied by PSU + Returns: + A float number, the power in watts, e.g. 302.6 + """ + psu_power = 0.0 + current_name = "power{}_input" + current_label = "pout1" + + pw_label_path = self.__search_file_by_contain( + self.hwmon_path, current_label, "power") + if pw_label_path: + dir_name = os.path.dirname(pw_label_path) + basename = os.path.basename(pw_label_path) + pw_num = filter(str.isdigit, basename) + pw_path = os.path.join( + dir_name, current_name.format(pw_num)) + pw_val = self.__read_txt_file(pw_path) + psu_power = float(pw_val) / 1000000 + + return psu_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. + """ + return self.get_status() def set_status_led(self, color): """ @@ -64,6 +159,15 @@ def set_status_led(self, color): # Hardware not supported return False + def get_status_led(self): + """ + Gets the state of the PSU status LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + # Hardware not supported + return self.STATUS_LED_COLOR_OFF + def get_name(self): """ Retrieves the name of the device @@ -79,14 +183,10 @@ def get_presence(self): bool: True if PSU is present, False if not """ psu_location = ["R", "L"] - status = 0 - try: - with open(self.psu_path + self.psu_presence.format(psu_location[self.index]), 'r') as psu_prs: - status = int(psu_prs.read()) - except IOError: - return False + presences_status = self.__read_txt_file( + self.psu_path + self.psu_presence.format(psu_location[self.index])) or 0 - return status == 1 + return int(presences_status) == 1 def get_status(self): """ @@ -95,11 +195,7 @@ def get_status(self): A boolean value, True if device is operating properly, False if not """ psu_location = ["R", "L"] - status = 0 - try: - with open(self.psu_path + self.psu_oper_status.format(psu_location[self.index]), 'r') as power_status: - status = int(power_status.read()) - except IOError: - return False + power_status = self.__read_txt_file( + self.psu_path + self.psu_oper_status.format(psu_location[self.index])) or 0 - return status == 1 + return int(power_status) == 1 diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py new file mode 100644 index 000000000000..4cfdcf50b66d --- /dev/null +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py @@ -0,0 +1,717 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Sfp contains an implementation of SONiC Platform Base API and +# provides the sfp device status which are available in the platform +# +############################################################################# + +import os +import time +import subprocess +import sonic_device_util +from ctypes import create_string_buffer + +try: + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sffbase + from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +INFO_OFFSET = 0 +DOM_OFFSET = 256 + +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 + +# Offset for values in SFP eeprom +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 40 +SFP_CHANNL_THRESHOLD_OFFSET = 112 +SFP_CHANNL_THRESHOLD_WIDTH = 2 +SFP_STATUS_CONTROL_OFFSET = 110 +SFP_STATUS_CONTROL_WIDTH = 1 +SFP_TX_DISABLE_HARD_BIT = 7 +SFP_TX_DISABLE_SOFT_BIT = 6 + +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes', 'FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') + + +class Sfp(SfpBase): + """Platform-specific Sfp class""" + + # Port number + PORT_START = 1 + PORT_END = 52 + port_to_i2c_mapping = { + 49: 15, + 50: 14, + 51: 17, + 52: 16 + } + _sfp_port = range(49, PORT_END + 1) + PRS_PATH = "/sys/devices/platform/e1031.smc/SFP/sfp_modabs" + PLATFORM_ROOT_PATH = '/usr/share/sonic/device' + PMON_HWSKU_PATH = '/usr/share/sonic/hwsku' + HOST_CHK_CMD = "docker > /dev/null 2>&1" + + PLATFORM = "x86_64-cel_e1031-r0" + HWSKU = "Celestica-E1031-T48S4" + + def __init__(self, sfp_index): + # Init index + self.index = sfp_index + self.port_num = self.index + 1 + + # 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): + if x not in self._sfp_port: + self.port_to_i2c_mapping[x] = None + self.port_to_eeprom_mapping[x] = eeprom_path.format( + self.port_to_i2c_mapping[x]) + + self.info_dict_keys = ['type', 'hardwarerev', 'serialnum', 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', + 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] + + self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', + 'rx1power', 'rx2power', 'rx3power', 'rx4power', 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', 'tx1power', 'tx2power', 'tx3power', 'tx4power'] + + self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + + SfpBase.__init__(self) + + def _convert_string_to_num(self, value_str): + if "-inf" in value_str: + return 'N/A' + elif "Unknown" in value_str: + return 'N/A' + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return 'N/A' + + def __read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return "" + + def __is_host(self): + return os.system(self.HOST_CHK_CMD) == 0 + + def __get_path_to_port_config_file(self): + platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.PLATFORM]) + hwsku_path = "/".join([platform_path, self.HWSKU] + ) if self.__is_host() else self.PMON_HWSKU_PATH + return "/".join([hwsku_path, "port_config.ini"]) + + def __read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num] + try: + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except: + pass + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + + return eeprom_raw + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardwarerev |1*255VCHAR |hardware version of SFP + serialnum |1*255VCHAR |serial number of the SFP + manufacturename |1*255VCHAR |SFP vendor name + modelname |1*255VCHAR |SFP model name + Connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + nominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + ======================================================================== + """ + # check present status + sfpi_obj = sff8472InterfaceId() + 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_SFP) + 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_SFP) + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_vendor_rev_raw, 0) + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_vendor_sn_raw, 0) + + sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui( + sfp_vendor_oui_raw, 0) + + sfp_vendor_date_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + sfp_vendor_date_data = sfpi_obj.parse_vendor_date( + sfp_vendor_date_raw, 0) + + transceiver_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A') + compliance_code_dict = dict() + + if sfp_interface_bulk_data: + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] + + transceiver_info_dict['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 sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str( + sfp_interface_bulk_data['data'][key]['value']) + + for key in sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str( + compliance_code_dict) + transceiver_info_dict['nominal_bit_rate'] = str( + sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + + return transceiver_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + # check present status + sfpd_obj = sff8472Dom() + if not self.get_presence() or not sfpd_obj: + return {} + + eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET) + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + cal_type = sfpi_obj.get_calibration_type() + sfpd_obj._calibration_type = cal_type + + offset = DOM_OFFSET + transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + dom_temperature_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature( + dom_temperature_raw, 0) + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + + dom_voltage_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_voltage_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) + transceiver_dom_info_dict['tx1power'] = dom_voltage_data['data']['TXPower']['value'] + transceiver_dom_info_dict['rx1power'] = dom_voltage_data['data']['RXPower']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_voltage_data['data']['TXBias']['value'] + + for key in transceiver_dom_info_dict: + transceiver_dom_info_dict[key] = self._convert_string_to_num( + transceiver_dom_info_dict[key]) + + transceiver_dom_info_dict['rx_los'] = self.get_rx_los() + transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + + return transceiver_dom_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + # check present status + sfpd_obj = sff8472Dom() + + if not self.get_presence() and not sfpd_obj: + return {} + + eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET) + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + cal_type = sfpi_obj.get_calibration_type() + sfpd_obj._calibration_type = cal_type + + offset = DOM_OFFSET + transceiver_dom_threshold_info_dict = dict.fromkeys( + self.threshold_dict_keys, 'N/A') + dom_module_threshold_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold( + dom_module_threshold_raw, 0) + + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data[ + 'data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + for key in transceiver_dom_threshold_info_dict: + transceiver_dom_threshold_info_dict[key] = self._convert_string_to_num( + transceiver_dom_threshold_info_dict[key]) + + return transceiver_dom_threshold_info_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + Returns: + A Boolean, True if reset enabled, False if disabled + """ + # SFP doesn't support this feature + return False + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + rx_los = False + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + rx_los = (sffbase().test_bit(data, 1) != 0) + + return rx_los + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + tx_fault = False + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + tx_fault = (sffbase().test_bit(data, 2) != 0) + + return tx_fault + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + Returns: + A Boolean, True if tx_disable is enabled, False if disabled + """ + tx_disable = False + tx_fault = False + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + tx_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 + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + # SFP doesn't support this feature + return 0 + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + # SFP doesn't support this feature + return False + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + # SFP doesn't support this feature + return False + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + Returns: + An integer number of current temperature in Celsius + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + return transceiver_dom_info_dict.get("temperature", "N/A") + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + Returns: + An integer number of supply voltage in mV + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + return transceiver_dom_info_dict.get("voltage", "N/A") + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + tx1_bs = transceiver_dom_info_dict.get("tx1bias", "N/A") + return [tx1_bs, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else [] + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + rx1_pw = transceiver_dom_info_dict.get("rx1power", "N/A") + return [rx1_pw, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else [] + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + tx1_pw = transceiver_dom_info_dict.get("tx1power", "N/A") + return [tx1_pw, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else [] + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + Returns: + A boolean, True if successful, False if not + """ + # SFP doesn't support this feature + return False + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num] + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw is not None: + # Set bit 6 for Soft TX Disable Select + # 01000000 = 64 and 10111111 = 191 + tx_disable_bit = 64 if tx_disable else 191 + status_control = int(status_control_raw[0], 16) + tx_disable_ctl = (status_control | tx_disable_bit) if tx_disable else ( + status_control & tx_disable_bit) + try: + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, mode="r+b", buffering=0) + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfsfile_eeprom.seek(SFP_STATUS_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except: + #print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + return False + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + Returns: + A boolean, True if successful, False if not + """ + # SFP doesn't support this feature + return False + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + # SFP doesn't support this feature + return False + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + # SFP doesn't support this feature + return False + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + sfputil_helper = SfpUtilHelper() + sfputil_helper.read_porttab_mappings( + self.__get_path_to_port_config_file()) + name = sfputil_helper.logical[self.index] or "Unknown" + return name + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + if self.port_num not in self._sfp_port: + return False + + status = 1 + try: + with open(self.PRS_PATH, 'r') as port_status: + status = int(port_status.read(), 16) + status = (status >> (self.port_num - 49)) & 1 + except IOError: + return False + + return status == 0 + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + return transceiver_dom_info_dict.get("modelname", "N/A") + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + return transceiver_dom_info_dict.get("serialnum", "N/A") diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/thermal.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/thermal.py index a6d45dc41c93..6c37f3b7ce88 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/thermal.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/thermal.py @@ -22,8 +22,8 @@ class Thermal(ThermalBase): """Platform-specific Thermal class""" THERMAL_NAME_LIST = [] - MAINBOARD_SS_PATH = "/sys/class/i2c-adapter/i2c-11/11-001a/hwmon/" - CPUBOARD_SS_PATH = "/sys/class/i2c-adapter/i2c-3/3-001a/hwmon/" + MAINBOARD_SS_PATH = "/sys/class/i2c-adapter/i2c-11/11-001a/hwmon/hwmon2" + CPUBOARD_SS_PATH = "/sys/class/i2c-adapter/i2c-3/3-001a/hwmon/hwmon1" SS_CONFIG_PATH = "/usr/share/sonic/device/x86_64-cel_e1031-r0/sensors.conf" def __init__(self, thermal_index): @@ -41,10 +41,8 @@ def __init__(self, thermal_index): self.THERMAL_NAME_LIST.append("CPU board temperature sensor : 2") # Set hwmon path - self.ss_index, self.ss_path = self.__get_ss_info(self.index) + self.ss_index, self.hwmon_path = self.__get_ss_info(self.index) self.ss_key = self.THERMAL_NAME_LIST[self.index] - self.hwmon_name = os.listdir(self.ss_path)[0] - self.hwmon_path = os.path.join(self.ss_path, self.hwmon_name) def __get_ss_info(self, index): if self.index <= 4: diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i/buffers.json.j2 b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i/buffers.json.j2 new file mode 100644 index 000000000000..45cebf3b7144 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i/buffers.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '300m' %} +{% set default_ports_num = 64 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "47218432", + "type": "ingress", + "mode": "dynamic", + "xoff": "17708800" + }, + "egress_lossy_pool": { + "size": "18874368", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"1433600", + "size":"1518", + "dynamic_th":"-4", + "xon_offset":"6272" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i/config_64x100G_midstone200i.yaml b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i/config_64x100G_midstone200i.yaml new file mode 100755 index 000000000000..0b7e1a2db9d6 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i/config_64x100G_midstone200i.yaml @@ -0,0 +1,639 @@ +ifcs: + options: + log_level: "info" +nodes: +- node_id: "0" + options: + sku: "innovium.77700_B" + netdev: + - auto_create: "no" + multi_interface: "yes" + buffer_management_mode: "api_driven" + max_lossless_tc: "2" + txring: + - txring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + rxring: + - rxring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44" + - rxring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45" + - rxring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46" + - rxring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47" + sys_clk: "1720" + ifc_clk: "1200" + mac_clk: "1340" + + devports: + - id: "0" + sysport: "128" + type: "cpu" + - fec: "KRFEC" + id: "1" + lanes: "0:4" + serdes_group: "31" + speed: "100G" + sysport: "1" + type: "eth" + - fec: "KRFEC" + id: "2" + lanes: "4:4" + serdes_group: "31" + speed: "100G" + sysport: "2" + type: "eth" + - fec: "KRFEC" + id: "3" + lanes: "4:4" + serdes_group: "30" + speed: "100G" + sysport: "3" + type: "eth" + - fec: "KRFEC" + id: "4" + lanes: "0:4" + serdes_group: "30" + speed: "100G" + sysport: "4" + type: "eth" + - fec: "KRFEC" + id: "5" + lanes: "0:4" + serdes_group: "29" + speed: "100G" + sysport: "5" + type: "eth" + - fec: "KRFEC" + id: "6" + lanes: "4:4" + serdes_group: "29" + speed: "100G" + sysport: "6" + type: "eth" + - fec: "KRFEC" + id: "7" + lanes: "4:4" + serdes_group: "28" + speed: "100G" + sysport: "7" + type: "eth" + - fec: "KRFEC" + id: "8" + lanes: "0:4" + serdes_group: "28" + speed: "100G" + sysport: "8" + type: "eth" + - fec: "KRFEC" + id: "9" + lanes: "0:4" + serdes_group: "27" + speed: "100G" + sysport: "9" + type: "eth" + - fec: "KRFEC" + id: "10" + lanes: "4:4" + serdes_group: "27" + speed: "100G" + sysport: "10" + type: "eth" + - fec: "KRFEC" + id: "11" + lanes: "4:4" + serdes_group: "26" + speed: "100G" + sysport: "11" + type: "eth" + - fec: "KRFEC" + id: "12" + lanes: "0:4" + serdes_group: "26" + speed: "100G" + sysport: "12" + type: "eth" + - fec: "KRFEC" + id: "13" + lanes: "0:4" + serdes_group: "25" + speed: "100G" + sysport: "13" + type: "eth" + - fec: "KRFEC" + id: "14" + lanes: "4:4" + serdes_group: "25" + speed: "100G" + sysport: "14" + type: "eth" + - fec: "KRFEC" + id: "15" + lanes: "4:4" + serdes_group: "24" + speed: "100G" + sysport: "15" + type: "eth" + - fec: "KRFEC" + id: "16" + lanes: "0:4" + serdes_group: "24" + speed: "100G" + sysport: "16" + type: "eth" + - fec: "KRFEC" + id: "17" + lanes: "0:4" + serdes_group: "23" + speed: "100G" + sysport: "17" + type: "eth" + - fec: "KRFEC" + id: "18" + lanes: "4:4" + serdes_group: "23" + speed: "100G" + sysport: "18" + type: "eth" + - fec: "KRFEC" + id: "19" + lanes: "4:4" + serdes_group: "22" + speed: "100G" + sysport: "19" + type: "eth" + - fec: "KRFEC" + id: "20" + lanes: "0:4" + serdes_group: "22" + speed: "100G" + sysport: "20" + type: "eth" + - fec: "KRFEC" + id: "21" + lanes: "0:4" + serdes_group: "21" + speed: "100G" + sysport: "21" + type: "eth" + - fec: "KRFEC" + id: "22" + lanes: "4:4" + serdes_group: "21" + speed: "100G" + sysport: "22" + type: "eth" + - fec: "KRFEC" + id: "23" + lanes: "4:4" + serdes_group: "20" + speed: "100G" + sysport: "23" + type: "eth" + - fec: "KRFEC" + id: "24" + lanes: "0:4" + serdes_group: "20" + speed: "100G" + sysport: "24" + type: "eth" + - fec: "KRFEC" + id: "25" + lanes: "0:4" + serdes_group: "19" + speed: "100G" + sysport: "25" + type: "eth" + - fec: "KRFEC" + id: "26" + lanes: "4:4" + serdes_group: "19" + speed: "100G" + sysport: "26" + type: "eth" + - fec: "KRFEC" + id: "27" + lanes: "4:4" + serdes_group: "18" + speed: "100G" + sysport: "27" + type: "eth" + - fec: "KRFEC" + id: "28" + lanes: "0:4" + serdes_group: "18" + speed: "100G" + sysport: "28" + type: "eth" + - fec: "KRFEC" + id: "29" + lanes: "0:4" + serdes_group: "17" + speed: "100G" + sysport: "29" + type: "eth" + - fec: "KRFEC" + id: "30" + lanes: "4:4" + serdes_group: "17" + speed: "100G" + sysport: "30" + type: "eth" + - fec: "KRFEC" + id: "31" + lanes: "4:4" + serdes_group: "16" + speed: "100G" + sysport: "31" + type: "eth" + - fec: "KRFEC" + id: "32" + lanes: "0:4" + serdes_group: "16" + speed: "100G" + sysport: "32" + type: "eth" + - fec: "KRFEC" + id: "33" + lanes: "0:4" + serdes_group: "15" + speed: "100G" + sysport: "33" + type: "eth" + - fec: "KRFEC" + id: "34" + lanes: "4:4" + serdes_group: "15" + speed: "100G" + sysport: "34" + type: "eth" + - fec: "KRFEC" + id: "35" + lanes: "4:4" + serdes_group: "14" + speed: "100G" + sysport: "35" + type: "eth" + - fec: "KRFEC" + id: "36" + lanes: "0:4" + serdes_group: "14" + speed: "100G" + sysport: "36" + type: "eth" + - fec: "KRFEC" + id: "37" + lanes: "0:4" + serdes_group: "13" + speed: "100G" + sysport: "37" + type: "eth" + - fec: "KRFEC" + id: "38" + lanes: "4:4" + serdes_group: "13" + speed: "100G" + sysport: "38" + type: "eth" + - fec: "KRFEC" + id: "39" + lanes: "4:4" + serdes_group: "12" + speed: "100G" + sysport: "39" + type: "eth" + - fec: "KRFEC" + id: "40" + lanes: "0:4" + serdes_group: "12" + speed: "100G" + sysport: "40" + type: "eth" + - fec: "KRFEC" + id: "41" + lanes: "0:4" + serdes_group: "11" + speed: "100G" + sysport: "41" + type: "eth" + - fec: "KRFEC" + id: "42" + lanes: "4:4" + serdes_group: "11" + speed: "100G" + sysport: "42" + type: "eth" + - fec: "KRFEC" + id: "43" + lanes: "4:4" + serdes_group: "10" + speed: "100G" + sysport: "43" + type: "eth" + - fec: "KRFEC" + id: "44" + lanes: "0:4" + serdes_group: "10" + speed: "100G" + sysport: "44" + type: "eth" + - fec: "KRFEC" + id: "45" + lanes: "0:4" + serdes_group: "9" + speed: "100G" + sysport: "45" + type: "eth" + - fec: "KRFEC" + id: "46" + lanes: "4:4" + serdes_group: "9" + speed: "100G" + sysport: "46" + type: "eth" + - fec: "KRFEC" + id: "47" + lanes: "4:4" + serdes_group: "8" + speed: "100G" + sysport: "47" + type: "eth" + - fec: "KRFEC" + id: "48" + lanes: "0:4" + serdes_group: "8" + speed: "100G" + sysport: "48" + type: "eth" + - fec: "KRFEC" + id: "49" + lanes: "0:4" + serdes_group: "7" + speed: "100G" + sysport: "49" + type: "eth" + - fec: "KRFEC" + id: "50" + lanes: "4:4" + serdes_group: "7" + speed: "100G" + sysport: "50" + type: "eth" + - fec: "KRFEC" + id: "51" + lanes: "4:4" + serdes_group: "6" + speed: "100G" + sysport: "51" + type: "eth" + - fec: "KRFEC" + id: "52" + lanes: "0:4" + serdes_group: "6" + speed: "100G" + sysport: "52" + type: "eth" + - fec: "KRFEC" + id: "53" + lanes: "0:4" + serdes_group: "5" + speed: "100G" + sysport: "53" + type: "eth" + - fec: "KRFEC" + id: "54" + lanes: "4:4" + serdes_group: "5" + speed: "100G" + sysport: "54" + type: "eth" + - fec: "KRFEC" + id: "55" + lanes: "4:4" + serdes_group: "4" + speed: "100G" + sysport: "55" + type: "eth" + - fec: "KRFEC" + id: "56" + lanes: "0:4" + serdes_group: "4" + speed: "100G" + sysport: "56" + type: "eth" + - fec: "KRFEC" + id: "57" + lanes: "0:4" + serdes_group: "3" + speed: "100G" + sysport: "57" + type: "eth" + - fec: "KRFEC" + id: "58" + lanes: "4:4" + serdes_group: "3" + speed: "100G" + sysport: "58" + type: "eth" + - fec: "KRFEC" + id: "59" + lanes: "4:4" + serdes_group: "2" + speed: "100G" + sysport: "59" + type: "eth" + - fec: "KRFEC" + id: "60" + lanes: "0:4" + serdes_group: "2" + speed: "100G" + sysport: "60" + type: "eth" + - fec: "KRFEC" + id: "61" + lanes: "0:4" + serdes_group: "1" + speed: "100G" + sysport: "61" + type: "eth" + - fec: "KRFEC" + id: "62" + lanes: "4:4" + serdes_group: "1" + speed: "100G" + sysport: "62" + type: "eth" + - fec: "KRFEC" + id: "63" + lanes: "4:4" + serdes_group: "0" + speed: "100G" + sysport: "63" + type: "eth" + - fec: "KRFEC" + id: "64" + lanes: "0:4" + serdes_group: "0" + speed: "100G" + sysport: "64" + type: "eth" + isg: + - id: "0" + tx_polarity: "00101001" + rx_polarity: "01110001" + lane_swap: "01234567" + - id: "1" + tx_polarity: "10111111" + rx_polarity: "11100100" + lane_swap: "01234567" + - id: "2" + tx_polarity: "00100010" + rx_polarity: "00010001" + lane_swap: "01234567" + - id: "3" + tx_polarity: "00101010" + rx_polarity: "11011101" + lane_swap: "01234567" + - id: "4" + tx_polarity: "10111110" + rx_polarity: "10010101" + lane_swap: "01234567" + - id: "5" + tx_polarity: "01101000" + rx_polarity: "10111001" + lane_swap: "01234567" + - id: "6" + tx_polarity: "01110110" + rx_polarity: "01110011" + lane_swap: "01234567" + - id: "7" + tx_polarity: "01001000" + rx_polarity: "10111001" + lane_swap: "01234567" + - id: "8" + tx_polarity: "11000100" + rx_polarity: "01000000" + lane_swap: "01234567" + - id: "9" + tx_polarity: "10001010" + rx_polarity: "10100100" + lane_swap: "01234567" + - id: "10" + tx_polarity: "11000110" + rx_polarity: "00011101" + lane_swap: "01234567" + - id: "11" + tx_polarity: "01000111" + rx_polarity: "00000101" + lane_swap: "01234567" + - id: "12" + tx_polarity: "01111000" + rx_polarity: "11100000" + lane_swap: "01234567" + - id: "13" + tx_polarity: "10011111" + rx_polarity: "00101111" + lane_swap: "01234567" + - id: "14" + tx_polarity: "00101001" + rx_polarity: "00011000" + lane_swap: "01234567" + - id: "15" + tx_polarity: "10110111" + rx_polarity: "00110110" + lane_swap: "01234567" + - id: "16" + tx_polarity: "00101001" + rx_polarity: "00000111" + lane_swap: "01234567" + - id: "17" + tx_polarity: "10100111" + rx_polarity: "10001000" + lane_swap: "01234567" + - id: "18" + tx_polarity: "00011001" + rx_polarity: "11111110" + lane_swap: "01234567" + - id: "19" + tx_polarity: "10010101" + rx_polarity: "10011010" + lane_swap: "01234567" + - id: "20" + tx_polarity: "00101001" + rx_polarity: "01100000" + lane_swap: "01234567" + - id: "21" + tx_polarity: "10010111" + rx_polarity: "01111001" + lane_swap: "01234567" + - id: "22" + tx_polarity: "00101001" + rx_polarity: "11010011" + lane_swap: "01234567" + - id: "23" + tx_polarity: "10110111" + rx_polarity: "01111011" + lane_swap: "01234567" + - id: "24" + tx_polarity: "00101001" + rx_polarity: "11101011" + lane_swap: "01234567" + - id: "25" + tx_polarity: "10110111" + rx_polarity: "11010111" + lane_swap: "01234567" + - id: "26" + tx_polarity: "00100001" + rx_polarity: "00101101" + lane_swap: "01234567" + - id: "27" + tx_polarity: "11000111" + rx_polarity: "11011001" + lane_swap: "01234567" + - id: "28" + tx_polarity: "00100001" + rx_polarity: "01010011" + lane_swap: "01234567" + - id: "29" + tx_polarity: "10110111" + rx_polarity: "01111001" + lane_swap: "01234567" + - id: "30" + tx_polarity: "00101001" + rx_polarity: "00110001" + lane_swap: "01234567" + - id: "31" + tx_polarity: "10110101" + rx_polarity: "01101101" + lane_swap: "01234567" + - id: "32" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i/inno.config.yaml b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i/inno.config.yaml new file mode 100755 index 000000000000..b2a079136abc --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i/inno.config.yaml @@ -0,0 +1,7 @@ +IFCS_INIT_FILE : "/usr/share/sonic/hwsku/config_64x100G_midstone200i.yaml" +IFCS_SKU_FILE : "/usr/share/sonic/hwsku/innovium.77700_B" +IFCS_INNO_CLI_PORT : "9999" +IFCS_TARGET : "device" +ULIMIT : "65536" +INNOVIUM_DIR : "/innovium" +PYTHONPATH : "$INNOVIUM_DIR:$INNOVIUM_DIR/cmds:$INNOVIUM_DIR/scripts:$INNOVIUM_DIR/test/:$INNOVIUM_DIR/test/utils:$INNOVIUM_DIR/utils:$INNOVIUM_DIR/pyctypes" diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i/innovium.77700_B b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i/innovium.77700_B new file mode 100644 index 000000000000..27297b313959 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i/innovium.77700_B @@ -0,0 +1,59 @@ +sku: innovium.77700_B + +device_id: 0x1b58 + +# Hardware constraint information +hardware: + num_ibs: 6 + + ports_per_ib: 32, 32, 32, 32, 20, 20 + recirc_port_num: 32, 32, 32, 32, 32, 32 + cpu_port_num: 33 + cpu_port_ib: 0 + mgmt_port_num: 33 + mgmt_port_ibs: 1,2 + + pics_per_ib: 6, 7, 7, 6, 5, 5 + pic_ports_per_pic: 8 + max_serdes_speed: 50 + + num_shared_pics: 2 + + isg [0-4]: + ib: 0 + pic_id: [0-4] + + isg [5-9]: + ib: 5 + pic_id: [0-4] + + isg [10-14]: + ib: 1 + pic_id: [0-4] + + isg [16-20]: + ib: 3 + pic_id: [0-4] + + isg [21-25]: + ib: 4 + pic_id: [0-4] + + isg [26-30]: + ib: 2 + pic_id: [0-4] + + isg 15: + mode: 4:4 + ib: 1, 3 + pic_id: 5 + + isg 31: + mode: 4:4 + ib: 0, 2 + pic_id: 5 + + isg 32: + mode: 1:1 + ib: 1, 2 + pic_id: 6 diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i/port_config.ini b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i/port_config.ini new file mode 100755 index 000000000000..c9b30d768d57 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i/port_config.ini @@ -0,0 +1,65 @@ +# name lanes speed index mtu +Ethernet0 249,250,251,252 100000 1 9126 +Ethernet4 253,254,255,256 100000 2 9126 +Ethernet8 245,246,247,248 100000 3 9126 +Ethernet12 241,242,243,244 100000 4 9126 +Ethernet16 233,234,235,236 100000 5 9126 +Ethernet20 237,238,239,240 100000 6 9126 +Ethernet24 229,230,231,232 100000 7 9126 +Ethernet28 225,226,227,228 100000 8 9126 +Ethernet32 217,218,219,220 100000 9 9126 +Ethernet36 221,222,223,224 100000 10 9126 +Ethernet40 213,214,215,216 100000 11 9126 +Ethernet44 209,210,211,212 100000 12 9126 +Ethernet48 201,202,203,204 100000 13 9126 +Ethernet52 205,206,207,208 100000 14 9126 +Ethernet56 197,198,199,200 100000 15 9126 +Ethernet60 193,194,195,196 100000 16 9126 +Ethernet64 185,186,187,188 100000 17 9126 +Ethernet68 189,190,191,192 100000 18 9126 +Ethernet72 181,182,183,184 100000 19 9126 +Ethernet76 177,178,179,180 100000 20 9126 +Ethernet80 169,170,171,172 100000 21 9126 +Ethernet84 173,174,175,176 100000 22 9126 +Ethernet88 165,166,167,168 100000 23 9126 +Ethernet92 161,162,163,164 100000 24 9126 +Ethernet96 153,154,155,156 100000 25 9126 +Ethernet100 157,158,159,160 100000 26 9126 +Ethernet104 149,150,151,152 100000 27 9126 +Ethernet108 145,146,147,148 100000 28 9126 +Ethernet112 137,138,139,140 100000 29 9126 +Ethernet116 141,142,143,144 100000 30 9126 +Ethernet120 133,134,135,136 100000 31 9126 +Ethernet124 129,130,131,132 100000 32 9126 +Ethernet128 121,122,123,124 100000 33 9126 +Ethernet132 125,126,127,128 100000 34 9126 +Ethernet136 117,118,119,120 100000 35 9126 +Ethernet140 113,114,115,116 100000 36 9126 +Ethernet144 105,106,107,108 100000 37 9126 +Ethernet148 109,110,111,112 100000 38 9126 +Ethernet152 101,102,103,104 100000 39 9126 +Ethernet156 97,98,99,100 100000 40 9126 +Ethernet160 89,90,91,92 100000 41 9126 +Ethernet164 93,94,95,96 100000 42 9126 +Ethernet168 85,86,87,88 100000 43 9126 +Ethernet172 81,82,83,84 100000 44 9126 +Ethernet176 73,74,75,76 100000 45 9126 +Ethernet180 77,78,79,80 100000 46 9126 +Ethernet184 69,70,71,72 100000 47 9126 +Ethernet188 65,66,67,68 100000 48 9126 +Ethernet192 57,58,59,60 100000 49 9126 +Ethernet196 61,62,63,64 100000 50 9126 +Ethernet200 53,54,55,56 100000 51 9126 +Ethernet204 49,50,51,52 100000 52 9126 +Ethernet208 41,42,43,44 100000 53 9126 +Ethernet212 45,46,47,48 100000 54 9126 +Ethernet216 37,38,39,40 100000 55 9126 +Ethernet220 33,34,35,36 100000 56 9126 +Ethernet224 25,26,27,28 100000 57 9126 +Ethernet228 29,30,31,32 100000 58 9126 +Ethernet232 21,22,23,24 100000 59 9126 +Ethernet236 17,18,19,20 100000 60 9126 +Ethernet240 9,10,11,12 100000 61 9126 +Ethernet244 13,14,15,16 100000 62 9126 +Ethernet248 5,6,7,8 100000 63 9126 +Ethernet252 1,2,3,4 100000 64 9126 diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i/qos.json.j2 b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i/qos.json.j2 new file mode 100755 index 000000000000..16f9b42a2166 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i/qos.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} + +{% set default_ports_num = 64 -%} +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "1":"1", + "0":"0", + "3":"3", + "2":"2", + "5":"5", + "4":"4", + "7":"7", + "6":"6" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "1": "0", + "0": "0", + "3": "0", + "2": "0", + "4": "1", + "5": "2", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"0", + "4":"4", + "5":"5", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "4,5" + } + } +} diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i/sai.profile b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i/sai.profile new file mode 100755 index 000000000000..0769b3063a12 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/inno.config.yaml diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_128x100/buffers.json.j2 b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_128x100/buffers.json.j2 new file mode 100644 index 000000000000..9529fbf52fb5 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_128x100/buffers.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '300m' %} +{% set default_ports_num = 128 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*2)) %}{% 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(',') -%} + +{ + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "47218432", + "type": "ingress", + "mode": "dynamic", + "xoff": "17708800" + }, + "egress_lossy_pool": { + "size": "18874368", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"1433600", + "size":"1518", + "dynamic_th":"-4", + "xon_offset":"6272" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_128x100/config_128x100G_midstone200i.yaml b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_128x100/config_128x100G_midstone200i.yaml new file mode 100644 index 000000000000..342d223a96e1 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_128x100/config_128x100G_midstone200i.yaml @@ -0,0 +1,1100 @@ +ifcs: + options: + log_level: "info" +nodes: +- node_id: "0" + options: + sku: "configs/sku/innovium.77700_B" + netdev: + - auto_create: "no" + multi_interface: "yes" + buffer_management_mode: "api_driven" + max_lossless_tc: "2" + txring: + - txring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + rxring: + - rxring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44" + - rxring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45" + - rxring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46" + - rxring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47" + sys_clk: "1720" + ifc_clk: "1200" + mac_clk: "1340" + devports: + - id: "0" + sysport: "1000" + type: "cpu" + - fec: "KPFEC" + id: "249" + lanes: "0:2" + serdes_group: "31" + speed: "100G" + sysport: "249" + type: "eth" + - fec: "KPFEC" + id: "251" + lanes: "2:2" + serdes_group: "31" + speed: "100G" + sysport: "251" + type: "eth" + - fec: "KPFEC" + id: "253" + lanes: "4:2" + serdes_group: "31" + speed: "100G" + sysport: "253" + type: "eth" + - fec: "KPFEC" + id: "255" + lanes: "6:2" + serdes_group: "31" + speed: "100G" + sysport: "255" + type: "eth" + - fec: "KPFEC" + id: "245" + lanes: "4:2" + serdes_group: "30" + speed: "100G" + sysport: "245" + type: "eth" + - fec: "KPFEC" + id: "247" + lanes: "6:2" + serdes_group: "30" + speed: "100G" + sysport: "247" + type: "eth" + - fec: "KPFEC" + id: "241" + lanes: "0:2" + serdes_group: "30" + speed: "100G" + sysport: "241" + type: "eth" + - fec: "KPFEC" + id: "243" + lanes: "2:2" + serdes_group: "30" + speed: "100G" + sysport: "243" + type: "eth" + - fec: "KPFEC" + id: "233" + lanes: "0:2" + serdes_group: "29" + speed: "100G" + sysport: "233" + type: "eth" + - fec: "KPFEC" + id: "235" + lanes: "2:2" + serdes_group: "29" + speed: "100G" + sysport: "235" + type: "eth" + - fec: "KPFEC" + id: "237" + lanes: "4:2" + serdes_group: "29" + speed: "100G" + sysport: "237" + type: "eth" + - fec: "KPFEC" + id: "239" + lanes: "6:2" + serdes_group: "29" + speed: "100G" + sysport: "239" + type: "eth" + - fec: "KPFEC" + id: "229" + lanes: "4:2" + serdes_group: "28" + speed: "100G" + sysport: "229" + type: "eth" + - fec: "KPFEC" + id: "231" + lanes: "6:2" + serdes_group: "28" + speed: "100G" + sysport: "231" + type: "eth" + - fec: "KPFEC" + id: "225" + lanes: "0:2" + serdes_group: "28" + speed: "100G" + sysport: "225" + type: "eth" + - fec: "KPFEC" + id: "227" + lanes: "2:2" + serdes_group: "28" + speed: "100G" + sysport: "227" + type: "eth" + - fec: "KPFEC" + id: "217" + lanes: "0:2" + serdes_group: "27" + speed: "100G" + sysport: "217" + type: "eth" + - fec: "KPFEC" + id: "219" + lanes: "2:2" + serdes_group: "27" + speed: "100G" + sysport: "219" + type: "eth" + - fec: "KPFEC" + id: "221" + lanes: "4:2" + serdes_group: "27" + speed: "100G" + sysport: "221" + type: "eth" + - fec: "KPFEC" + id: "223" + lanes: "6:2" + serdes_group: "27" + speed: "100G" + sysport: "223" + type: "eth" + - fec: "KPFEC" + id: "213" + lanes: "4:2" + serdes_group: "26" + speed: "100G" + sysport: "213" + type: "eth" + - fec: "KPFEC" + id: "215" + lanes: "6:2" + serdes_group: "26" + speed: "100G" + sysport: "215" + type: "eth" + - fec: "KPFEC" + id: "209" + lanes: "0:2" + serdes_group: "26" + speed: "100G" + sysport: "209" + type: "eth" + - fec: "KPFEC" + id: "211" + lanes: "2:2" + serdes_group: "26" + speed: "100G" + sysport: "211" + type: "eth" + - fec: "KPFEC" + id: "201" + lanes: "0:2" + serdes_group: "25" + speed: "100G" + sysport: "201" + type: "eth" + - fec: "KPFEC" + id: "203" + lanes: "2:2" + serdes_group: "25" + speed: "100G" + sysport: "203" + type: "eth" + - fec: "KPFEC" + id: "205" + lanes: "4:2" + serdes_group: "25" + speed: "100G" + sysport: "205" + type: "eth" + - fec: "KPFEC" + id: "207" + lanes: "6:2" + serdes_group: "25" + speed: "100G" + sysport: "207" + type: "eth" + - fec: "KPFEC" + id: "197" + lanes: "4:2" + serdes_group: "24" + speed: "100G" + sysport: "197" + type: "eth" + - fec: "KPFEC" + id: "199" + lanes: "6:2" + serdes_group: "24" + speed: "100G" + sysport: "199" + type: "eth" + - fec: "KPFEC" + id: "193" + lanes: "0:2" + serdes_group: "24" + speed: "100G" + sysport: "193" + type: "eth" + - fec: "KPFEC" + id: "195" + lanes: "2:2" + serdes_group: "24" + speed: "100G" + sysport: "195" + type: "eth" + - fec: "KPFEC" + id: "185" + lanes: "0:2" + serdes_group: "23" + speed: "100G" + sysport: "185" + type: "eth" + - fec: "KPFEC" + id: "187" + lanes: "2:2" + serdes_group: "23" + speed: "100G" + sysport: "187" + type: "eth" + - fec: "KPFEC" + id: "189" + lanes: "4:2" + serdes_group: "23" + speed: "100G" + sysport: "189" + type: "eth" + - fec: "KPFEC" + id: "191" + lanes: "6:2" + serdes_group: "23" + speed: "100G" + sysport: "191" + type: "eth" + - fec: "KPFEC" + id: "181" + lanes: "4:2" + serdes_group: "22" + speed: "100G" + sysport: "181" + type: "eth" + - fec: "KPFEC" + id: "183" + lanes: "6:2" + serdes_group: "22" + speed: "100G" + sysport: "183" + type: "eth" + - fec: "KPFEC" + id: "177" + lanes: "0:2" + serdes_group: "22" + speed: "100G" + sysport: "177" + type: "eth" + - fec: "KPFEC" + id: "179" + lanes: "2:2" + serdes_group: "22" + speed: "100G" + sysport: "179" + type: "eth" + - fec: "KPFEC" + id: "169" + lanes: "0:2" + serdes_group: "21" + speed: "100G" + sysport: "169" + type: "eth" + - fec: "KPFEC" + id: "171" + lanes: "2:2" + serdes_group: "21" + speed: "100G" + sysport: "171" + type: "eth" + - fec: "KPFEC" + id: "173" + lanes: "4:2" + serdes_group: "21" + speed: "100G" + sysport: "173" + type: "eth" + - fec: "KPFEC" + id: "175" + lanes: "6:2" + serdes_group: "21" + speed: "100G" + sysport: "175" + type: "eth" + - fec: "KPFEC" + id: "165" + lanes: "4:2" + serdes_group: "20" + speed: "100G" + sysport: "165" + type: "eth" + - fec: "KPFEC" + id: "167" + lanes: "6:2" + serdes_group: "20" + speed: "100G" + sysport: "167" + type: "eth" + - fec: "KPFEC" + id: "161" + lanes: "0:2" + serdes_group: "20" + speed: "100G" + sysport: "161" + type: "eth" + - fec: "KPFEC" + id: "163" + lanes: "2:2" + serdes_group: "20" + speed: "100G" + sysport: "163" + type: "eth" + - fec: "KPFEC" + id: "153" + lanes: "0:2" + serdes_group: "19" + speed: "100G" + sysport: "153" + type: "eth" + - fec: "KPFEC" + id: "155" + lanes: "2:2" + serdes_group: "19" + speed: "100G" + sysport: "155" + type: "eth" + - fec: "KPFEC" + id: "157" + lanes: "4:2" + serdes_group: "19" + speed: "100G" + sysport: "157" + type: "eth" + - fec: "KPFEC" + id: "159" + lanes: "6:2" + serdes_group: "19" + speed: "100G" + sysport: "159" + type: "eth" + - fec: "KPFEC" + id: "149" + lanes: "4:2" + serdes_group: "18" + speed: "100G" + sysport: "149" + type: "eth" + - fec: "KPFEC" + id: "151" + lanes: "6:2" + serdes_group: "18" + speed: "100G" + sysport: "151" + type: "eth" + - fec: "KPFEC" + id: "145" + lanes: "0:2" + serdes_group: "18" + speed: "100G" + sysport: "145" + type: "eth" + - fec: "KPFEC" + id: "147" + lanes: "2:2" + serdes_group: "18" + speed: "100G" + sysport: "147" + type: "eth" + - fec: "KPFEC" + id: "137" + lanes: "0:2" + serdes_group: "17" + speed: "100G" + sysport: "137" + type: "eth" + - fec: "KPFEC" + id: "139" + lanes: "2:2" + serdes_group: "17" + speed: "100G" + sysport: "139" + type: "eth" + - fec: "KPFEC" + id: "141" + lanes: "4:2" + serdes_group: "17" + speed: "100G" + sysport: "141" + type: "eth" + - fec: "KPFEC" + id: "143" + lanes: "6:2" + serdes_group: "17" + speed: "100G" + sysport: "143" + type: "eth" + - fec: "KPFEC" + id: "133" + lanes: "4:2" + serdes_group: "16" + speed: "100G" + sysport: "133" + type: "eth" + - fec: "KPFEC" + id: "135" + lanes: "6:2" + serdes_group: "16" + speed: "100G" + sysport: "135" + type: "eth" + - fec: "KPFEC" + id: "129" + lanes: "0:2" + serdes_group: "16" + speed: "100G" + sysport: "129" + type: "eth" + - fec: "KPFEC" + id: "131" + lanes: "2:2" + serdes_group: "16" + speed: "100G" + sysport: "131" + type: "eth" + - fec: "KPFEC" + id: "121" + lanes: "0:2" + serdes_group: "15" + speed: "100G" + sysport: "121" + type: "eth" + - fec: "KPFEC" + id: "123" + lanes: "2:2" + serdes_group: "15" + speed: "100G" + sysport: "123" + type: "eth" + - fec: "KPFEC" + id: "125" + lanes: "4:2" + serdes_group: "15" + speed: "100G" + sysport: "125" + type: "eth" + - fec: "KPFEC" + id: "127" + lanes: "6:2" + serdes_group: "15" + speed: "100G" + sysport: "127" + type: "eth" + - fec: "KPFEC" + id: "117" + lanes: "4:2" + serdes_group: "14" + speed: "100G" + sysport: "117" + type: "eth" + - fec: "KPFEC" + id: "119" + lanes: "6:2" + serdes_group: "14" + speed: "100G" + sysport: "119" + type: "eth" + - fec: "KPFEC" + id: "113" + lanes: "0:2" + serdes_group: "14" + speed: "100G" + sysport: "113" + type: "eth" + - fec: "KPFEC" + id: "115" + lanes: "2:2" + serdes_group: "14" + speed: "100G" + sysport: "115" + type: "eth" + - fec: "KPFEC" + id: "105" + lanes: "0:2" + serdes_group: "13" + speed: "100G" + sysport: "105" + type: "eth" + - fec: "KPFEC" + id: "107" + lanes: "2:2" + serdes_group: "13" + speed: "100G" + sysport: "107" + type: "eth" + - fec: "KPFEC" + id: "109" + lanes: "4:2" + serdes_group: "13" + speed: "100G" + sysport: "109" + type: "eth" + - fec: "KPFEC" + id: "111" + lanes: "6:2" + serdes_group: "13" + speed: "100G" + sysport: "111" + type: "eth" + - fec: "KPFEC" + id: "101" + lanes: "4:2" + serdes_group: "12" + speed: "100G" + sysport: "101" + type: "eth" + - fec: "KPFEC" + id: "103" + lanes: "6:2" + serdes_group: "12" + speed: "100G" + sysport: "103" + type: "eth" + - fec: "KPFEC" + id: "97" + lanes: "0:2" + serdes_group: "12" + speed: "100G" + sysport: "97" + type: "eth" + - fec: "KPFEC" + id: "99" + lanes: "2:2" + serdes_group: "12" + speed: "100G" + sysport: "99" + type: "eth" + - fec: "KPFEC" + id: "89" + lanes: "0:2" + serdes_group: "11" + speed: "100G" + sysport: "89" + type: "eth" + - fec: "KPFEC" + id: "91" + lanes: "2:2" + serdes_group: "11" + speed: "100G" + sysport: "91" + type: "eth" + - fec: "KPFEC" + id: "93" + lanes: "4:2" + serdes_group: "11" + speed: "100G" + sysport: "93" + type: "eth" + - fec: "KPFEC" + id: "95" + lanes: "6:2" + serdes_group: "11" + speed: "100G" + sysport: "95" + type: "eth" + - fec: "KPFEC" + id: "85" + lanes: "4:2" + serdes_group: "10" + speed: "100G" + sysport: "85" + type: "eth" + - fec: "KPFEC" + id: "87" + lanes: "6:2" + serdes_group: "10" + speed: "100G" + sysport: "87" + type: "eth" + - fec: "KPFEC" + id: "87" + lanes: "0:2" + serdes_group: "10" + speed: "100G" + sysport: "87" + type: "eth" + - fec: "KPFEC" + id: "83" + lanes: "2:2" + serdes_group: "10" + speed: "100G" + sysport: "83" + type: "eth" + - fec: "KPFEC" + id: "89" + lanes: "0:2" + serdes_group: "9" + speed: "100G" + sysport: "89" + type: "eth" + - fec: "KPFEC" + id: "75" + lanes: "2:2" + serdes_group: "9" + speed: "100G" + sysport: "75" + type: "eth" + - fec: "KPFEC" + id: "91" + lanes: "4:2" + serdes_group: "9" + speed: "100G" + sysport: "91" + type: "eth" + - fec: "KPFEC" + id: "79" + lanes: "6:2" + serdes_group: "9" + speed: "100G" + sysport: "79" + type: "eth" + - fec: "KPFEC" + id: "93" + lanes: "4:2" + serdes_group: "8" + speed: "100G" + sysport: "93" + type: "eth" + - fec: "KPFEC" + id: "71" + lanes: "6:2" + serdes_group: "8" + speed: "100G" + sysport: "71" + type: "eth" + - fec: "KPFEC" + id: "95" + lanes: "0:2" + serdes_group: "8" + speed: "100G" + sysport: "95" + type: "eth" + - fec: "KPFEC" + id: "67" + lanes: "2:2" + serdes_group: "8" + speed: "100G" + sysport: "67" + type: "eth" + - fec: "KPFEC" + id: "97" + lanes: "0:2" + serdes_group: "7" + speed: "100G" + sysport: "97" + type: "eth" + - fec: "KPFEC" + id: "59" + lanes: "2:2" + serdes_group: "7" + speed: "100G" + sysport: "59" + type: "eth" + - fec: "KPFEC" + id: "99" + lanes: "4:2" + serdes_group: "7" + speed: "100G" + sysport: "99" + type: "eth" + - fec: "KPFEC" + id: "63" + lanes: "6:2" + serdes_group: "7" + speed: "100G" + sysport: "63" + type: "eth" + - fec: "KPFEC" + id: "101" + lanes: "4:2" + serdes_group: "6" + speed: "100G" + sysport: "101" + type: "eth" + - fec: "KPFEC" + id: "55" + lanes: "6:2" + serdes_group: "6" + speed: "100G" + sysport: "55" + type: "eth" + - fec: "KPFEC" + id: "103" + lanes: "0:2" + serdes_group: "6" + speed: "100G" + sysport: "103" + type: "eth" + - fec: "KPFEC" + id: "51" + lanes: "2:2" + serdes_group: "6" + speed: "100G" + sysport: "51" + type: "eth" + - fec: "KPFEC" + id: "105" + lanes: "0:2" + serdes_group: "5" + speed: "100G" + sysport: "105" + type: "eth" + - fec: "KPFEC" + id: "43" + lanes: "2:2" + serdes_group: "5" + speed: "100G" + sysport: "43" + type: "eth" + - fec: "KPFEC" + id: "107" + lanes: "4:2" + serdes_group: "5" + speed: "100G" + sysport: "107" + type: "eth" + - fec: "KPFEC" + id: "47" + lanes: "6:2" + serdes_group: "5" + speed: "100G" + sysport: "47" + type: "eth" + - fec: "KPFEC" + id: "109" + lanes: "4:2" + serdes_group: "4" + speed: "100G" + sysport: "109" + type: "eth" + - fec: "KPFEC" + id: "39" + lanes: "6:2" + serdes_group: "4" + speed: "100G" + sysport: "39" + type: "eth" + - fec: "KPFEC" + id: "111" + lanes: "0:2" + serdes_group: "4" + speed: "100G" + sysport: "111" + type: "eth" + - fec: "KPFEC" + id: "35" + lanes: "2:2" + serdes_group: "4" + speed: "100G" + sysport: "35" + type: "eth" + - fec: "KPFEC" + id: "113" + lanes: "0:2" + serdes_group: "3" + speed: "100G" + sysport: "113" + type: "eth" + - fec: "KPFEC" + id: "27" + lanes: "2:2" + serdes_group: "3" + speed: "100G" + sysport: "27" + type: "eth" + - fec: "KPFEC" + id: "115" + lanes: "4:2" + serdes_group: "3" + speed: "100G" + sysport: "115" + type: "eth" + - fec: "KPFEC" + id: "31" + lanes: "6:2" + serdes_group: "3" + speed: "100G" + sysport: "31" + type: "eth" + - fec: "KPFEC" + id: "117" + lanes: "4:2" + serdes_group: "2" + speed: "100G" + sysport: "117" + type: "eth" + - fec: "KPFEC" + id: "23" + lanes: "6:2" + serdes_group: "2" + speed: "100G" + sysport: "23" + type: "eth" + - fec: "KPFEC" + id: "119" + lanes: "0:2" + serdes_group: "2" + speed: "100G" + sysport: "119" + type: "eth" + - fec: "KPFEC" + id: "19" + lanes: "2:2" + serdes_group: "2" + speed: "100G" + sysport: "19" + type: "eth" + - fec: "KPFEC" + id: "121" + lanes: "0:2" + serdes_group: "1" + speed: "100G" + sysport: "121" + type: "eth" + - fec: "KPFEC" + id: "11" + lanes: "2:2" + serdes_group: "1" + speed: "100G" + sysport: "11" + type: "eth" + - fec: "KPFEC" + id: "123" + lanes: "4:2" + serdes_group: "1" + speed: "100G" + sysport: "123" + type: "eth" + - fec: "KPFEC" + id: "15" + lanes: "6:2" + serdes_group: "1" + speed: "100G" + sysport: "15" + type: "eth" + - fec: "KPFEC" + id: "125" + lanes: "4:2" + serdes_group: "0" + speed: "100G" + sysport: "125" + type: "eth" + - fec: "KPFEC" + id: "7" + lanes: "6:2" + serdes_group: "0" + speed: "100G" + sysport: "7" + type: "eth" + - fec: "KPFEC" + id: "127" + lanes: "0:2" + serdes_group: "0" + speed: "100G" + sysport: "127" + type: "eth" + - fec: "KPFEC" + id: "3" + lanes: "2:2" + serdes_group: "0" + speed: "100G" + sysport: "3" + type: "eth" + - fec: "NONE" + id: "257" + lanes: "0:1" + serdes_group: "32" + speed: "10G" + sysport: "257" + type: "mgmt 0" + - fec: "NONE" + id: "258" + lanes: "1:1" + serdes_group: "32" + speed: "10G" + sysport: "258" + type: "mgmt 1" + isg: + - id: "0" + lane_swap: "01234567" + rx_polarity: "01110001" + tx_polarity: "00101001" + - id: "1" + lane_swap: "01234567" + rx_polarity: "11100100" + tx_polarity: "10111111" + - id: "2" + lane_swap: "01234567" + rx_polarity: "00010001" + tx_polarity: "00100010" + - id: "3" + lane_swap: "01234567" + rx_polarity: "11011101" + tx_polarity: "00101010" + - id: "4" + lane_swap: "01234567" + rx_polarity: "10010101" + tx_polarity: "10111110" + - id: "5" + lane_swap: "01234567" + rx_polarity: "10111001" + tx_polarity: "01101000" + - id: "6" + lane_swap: "01234567" + rx_polarity: "01110011" + tx_polarity: "01110110" + - id: "7" + lane_swap: "01234567" + rx_polarity: "10111001" + tx_polarity: "01001000" + - id: "8" + lane_swap: "01234567" + rx_polarity: "01000000" + tx_polarity: "11000100" + - id: "9" + lane_swap: "01234567" + rx_polarity: "10100100" + tx_polarity: "10001010" + - id: "10" + lane_swap: "01234567" + rx_polarity: "00011101" + tx_polarity: "11000110" + - id: "11" + lane_swap: "01234567" + rx_polarity: "00000101" + tx_polarity: "01000111" + - id: "12" + lane_swap: "01234567" + rx_polarity: "11100000" + tx_polarity: "01111000" + - id: "13" + lane_swap: "01234567" + rx_polarity: "00101111" + tx_polarity: "10011111" + - id: "14" + lane_swap: "01234567" + rx_polarity: "00011000" + tx_polarity: "00101001" + - id: "15" + lane_swap: "01234567" + rx_polarity: "00110110" + tx_polarity: "10110111" + - id: "16" + lane_swap: "01234567" + rx_polarity: "00000111" + tx_polarity: "00101001" + - id: "17" + lane_swap: "01234567" + rx_polarity: "10001000" + tx_polarity: "10100111" + - id: "18" + lane_swap: "01234567" + rx_polarity: "11111110" + tx_polarity: "00011001" + - id: "19" + lane_swap: "01234567" + rx_polarity: "10011010" + tx_polarity: "10010101" + - id: "20" + lane_swap: "01234567" + rx_polarity: "01100000" + tx_polarity: "00101001" + - id: "21" + lane_swap: "01234567" + rx_polarity: "01111001" + tx_polarity: "10010111" + - id: "22" + lane_swap: "01234567" + rx_polarity: "11010011" + tx_polarity: "00101001" + - id: "23" + lane_swap: "01234567" + rx_polarity: "01111011" + tx_polarity: "10110111" + - id: "24" + lane_swap: "01234567" + rx_polarity: "11101011" + tx_polarity: "00101001" + - id: "25" + lane_swap: "01234567" + rx_polarity: "11010111" + tx_polarity: "10110111" + - id: "26" + lane_swap: "01234567" + rx_polarity: "00101101" + tx_polarity: "00100001" + - id: "27" + lane_swap: "01234567" + rx_polarity: "11011001" + tx_polarity: "11000111" + - id: "28" + lane_swap: "01234567" + rx_polarity: "01010011" + tx_polarity: "00100001" + - id: "29" + lane_swap: "01234567" + rx_polarity: "01111001" + tx_polarity: "10110111" + - id: "30" + lane_swap: "01234567" + rx_polarity: "00110001" + tx_polarity: "00101001" + - id: "31" + lane_swap: "01234567" + rx_polarity: "01101101" + tx_polarity: "10110101" + - id: "32" + lane_swap: "01234567" + rx_polarity: "00000000" + tx_polarity: "00000000" diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_128x100/inno.config.yaml b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_128x100/inno.config.yaml new file mode 100755 index 000000000000..66e43d312efb --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_128x100/inno.config.yaml @@ -0,0 +1,7 @@ +IFCS_INIT_FILE : "/usr/share/sonic/hwsku/config_128x100G_midstone200i.yaml" +IFCS_SKU_FILE : "/usr/share/sonic/hwsku/innovium.77700_B" +IFCS_INNO_CLI_PORT : "9999" +IFCS_TARGET : "device" +ULIMIT : "65536" +INNOVIUM_DIR : "/innovium" +PYTHONPATH : "$INNOVIUM_DIR:$INNOVIUM_DIR/cmds:$INNOVIUM_DIR/scripts:$INNOVIUM_DIR/test/:$INNOVIUM_DIR/test/utils:$INNOVIUM_DIR/utils:$INNOVIUM_DIR/pyctypes" diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_128x100/innovium.77700_B b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_128x100/innovium.77700_B new file mode 100644 index 000000000000..27297b313959 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_128x100/innovium.77700_B @@ -0,0 +1,59 @@ +sku: innovium.77700_B + +device_id: 0x1b58 + +# Hardware constraint information +hardware: + num_ibs: 6 + + ports_per_ib: 32, 32, 32, 32, 20, 20 + recirc_port_num: 32, 32, 32, 32, 32, 32 + cpu_port_num: 33 + cpu_port_ib: 0 + mgmt_port_num: 33 + mgmt_port_ibs: 1,2 + + pics_per_ib: 6, 7, 7, 6, 5, 5 + pic_ports_per_pic: 8 + max_serdes_speed: 50 + + num_shared_pics: 2 + + isg [0-4]: + ib: 0 + pic_id: [0-4] + + isg [5-9]: + ib: 5 + pic_id: [0-4] + + isg [10-14]: + ib: 1 + pic_id: [0-4] + + isg [16-20]: + ib: 3 + pic_id: [0-4] + + isg [21-25]: + ib: 4 + pic_id: [0-4] + + isg [26-30]: + ib: 2 + pic_id: [0-4] + + isg 15: + mode: 4:4 + ib: 1, 3 + pic_id: 5 + + isg 31: + mode: 4:4 + ib: 0, 2 + pic_id: 5 + + isg 32: + mode: 1:1 + ib: 1, 2 + pic_id: 6 diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_128x100/port_config.ini b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_128x100/port_config.ini new file mode 100644 index 000000000000..9366905c4eba --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_128x100/port_config.ini @@ -0,0 +1,131 @@ +# name lanes speed index mtu +Ethernet0 249,250 100000 0 9126 +Ethernet2 251,252 100000 0 9126 +Ethernet4 253,254 100000 1 9126 +Ethernet6 255,256 100000 1 9126 +Ethernet8 245,246 100000 2 9126 +Ethernet10 247,248 100000 2 9126 +Ethernet12 241,242 100000 3 9126 +Ethernet14 243,244 100000 3 9126 +Ethernet16 233,234 100000 4 9126 +Ethernet18 235,236 100000 4 9126 +Ethernet20 237,238 100000 5 9126 +Ethernet22 239,240 100000 5 9126 +Ethernet24 229,230 100000 6 9126 +Ethernet26 231,232 100000 6 9126 +Ethernet28 225,226 100000 7 9126 +Ethernet30 227,228 100000 7 9126 +Ethernet32 217,218 100000 8 9126 +Ethernet34 219,220 100000 8 9126 +Ethernet36 221,222 100000 9 9126 +Ethernet38 223,224 100000 9 9126 +Ethernet40 213,214 100000 10 9126 +Ethernet42 215,216 100000 10 9126 +Ethernet44 209,210 100000 11 9126 +Ethernet46 211,212 100000 11 9126 +Ethernet48 201,202 100000 12 9126 +Ethernet50 203,204 100000 12 9126 +Ethernet52 205,206 100000 13 9126 +Ethernet54 207,208 100000 13 9126 +Ethernet56 197,198 100000 14 9126 +Ethernet58 199,200 100000 14 9126 +Ethernet60 193,194 100000 15 9126 +Ethernet62 195,196 100000 15 9126 +Ethernet64 185,186 100000 16 9126 +Ethernet66 187,188 100000 16 9126 +Ethernet68 189,190 100000 17 9126 +Ethernet70 191,192 100000 17 9126 +Ethernet72 181,182 100000 18 9126 +Ethernet74 183,184 100000 18 9126 +Ethernet76 177,178 100000 19 9126 +Ethernet78 179,180 100000 19 9126 +Ethernet80 169,170 100000 20 9126 +Ethernet82 171,172 100000 20 9126 +Ethernet84 173,174 100000 21 9126 +Ethernet86 175,176 100000 21 9126 +Ethernet88 165,166 100000 22 9126 +Ethernet90 167,168 100000 22 9126 +Ethernet92 161,162 100000 23 9126 +Ethernet94 163,164 100000 23 9126 +Ethernet96 153,154 100000 24 9126 +Ethernet98 155,156 100000 24 9126 +Ethernet100 157,158 100000 25 9126 +Ethernet102 159,160 100000 25 9126 +Ethernet104 149,150 100000 26 9126 +Ethernet106 151,152 100000 26 9126 +Ethernet108 145,146 100000 27 9126 +Ethernet110 147,148 100000 27 9126 +Ethernet112 137,138 100000 28 9126 +Ethernet114 139,140 100000 28 9126 +Ethernet116 141,142 100000 29 9126 +Ethernet118 143,144 100000 29 9126 +Ethernet120 133,134 100000 30 9126 +Ethernet122 135,136 100000 30 9126 +Ethernet124 129,130 100000 31 9126 +Ethernet126 131,132 100000 31 9126 +Ethernet128 121,122 100000 32 9126 +Ethernet130 123,124 100000 32 9126 +Ethernet132 125,126 100000 33 9126 +Ethernet134 127,128 100000 33 9126 +Ethernet136 117,118 100000 34 9126 +Ethernet138 119,120 100000 34 9126 +Ethernet140 113,114 100000 35 9126 +Ethernet142 115,116 100000 35 9126 +Ethernet144 105,106 100000 36 9126 +Ethernet146 107,108 100000 36 9126 +Ethernet148 109,110 100000 37 9126 +Ethernet150 111,112 100000 37 9126 +Ethernet152 101,102 100000 38 9126 +Ethernet154 103,104 100000 38 9126 +Ethernet156 97,98 100000 39 9126 +Ethernet158 99,100 100000 39 9126 +Ethernet160 89,90 100000 40 9126 +Ethernet162 91,92 100000 40 9126 +Ethernet164 93,94 100000 41 9126 +Ethernet166 95,96 100000 41 9126 +Ethernet168 85,86 100000 42 9126 +Ethernet170 87,88 100000 42 9126 +Ethernet172 81,82 100000 43 9126 +Ethernet174 83,84 100000 43 9126 +Ethernet176 73,74 100000 44 9126 +Ethernet178 75,76 100000 44 9126 +Ethernet180 77,78 100000 45 9126 +Ethernet182 79,80 100000 45 9126 +Ethernet184 69,70 100000 46 9126 +Ethernet186 71,72 100000 46 9126 +Ethernet188 65,66 100000 47 9126 +Ethernet190 67,68 100000 47 9126 +Ethernet192 57,58 100000 48 9126 +Ethernet194 59,60 100000 48 9126 +Ethernet196 61,62 100000 49 9126 +Ethernet198 63,64 100000 49 9126 +Ethernet200 53,54 100000 50 9126 +Ethernet202 55,56 100000 50 9126 +Ethernet204 49,50 100000 51 9126 +Ethernet206 51,52 100000 51 9126 +Ethernet208 41,42 100000 52 9126 +Ethernet210 43,44 100000 52 9126 +Ethernet212 45,46 100000 53 9126 +Ethernet214 47,48 100000 53 9126 +Ethernet216 37,38 100000 54 9126 +Ethernet218 39,40 100000 54 9126 +Ethernet220 33,34 100000 55 9126 +Ethernet222 35,36 100000 55 9126 +Ethernet224 25,26 100000 56 9126 +Ethernet226 27,28 100000 56 9126 +Ethernet228 29,30 100000 57 9126 +Ethernet230 31,32 100000 57 9126 +Ethernet232 21,22 100000 58 9126 +Ethernet234 23,24 100000 58 9126 +Ethernet236 17,18 100000 59 9126 +Ethernet238 19,20 100000 59 9126 +Ethernet240 9,10 100000 60 9126 +Ethernet242 11,12 100000 60 9126 +Ethernet244 13,14 100000 61 9126 +Ethernet246 15,16 100000 61 9126 +Ethernet248 5,6 100000 62 9126 +Ethernet250 7,8 100000 62 9126 +Ethernet252 1,2 100000 63 9126 +Ethernet254 3,4 100000 63 9126 +Ethernet256 257 10000 64 9126 +Ethernet257 258 10000 65 9126 diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_128x100/qos.json.j2 b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_128x100/qos.json.j2 new file mode 100755 index 000000000000..733bd51dc86f --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_128x100/qos.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} + +{% set default_ports_num = 128 -%} +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*2)) %}{% 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(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "1":"1", + "0":"0", + "3":"3", + "2":"2", + "5":"5", + "4":"4", + "7":"7", + "6":"6" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "1": "0", + "0": "0", + "3": "0", + "2": "0", + "4": "1", + "5": "2", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"0", + "4":"4", + "5":"5", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "4,5" + } + } +} diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_128x100/sai.profile b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_128x100/sai.profile new file mode 100755 index 000000000000..0769b3063a12 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_128x100/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/inno.config.yaml diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_32x400/buffers.json.j2 b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_32x400/buffers.json.j2 new file mode 100644 index 000000000000..4fca9cbcd156 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_32x400/buffers.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '300m' %} +{% set default_ports_num = 32 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "47218432", + "type": "ingress", + "mode": "dynamic", + "xoff": "17708800" + }, + "egress_lossy_pool": { + "size": "18874368", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"1433600", + "size":"1518", + "dynamic_th":"-4", + "xon_offset":"6272" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_32x400/config_32x400G_midstone200i.yaml b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_32x400/config_32x400G_midstone200i.yaml new file mode 100644 index 000000000000..6c387ee17c23 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_32x400/config_32x400G_midstone200i.yaml @@ -0,0 +1,429 @@ +ifcs: + options: + log_level: "info" +nodes: +- node_id: "0" + options: + sku: "configs/sku/innovium.77700_A" + netdev: + - auto_create: "no" + multi_interface: "yes" + buffer_management_mode: "api_driven" + max_lossless_tc: "2" + txring: + - txring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + rxring: + - rxring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44" + - rxring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45" + - rxring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46" + - rxring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47" + sys_clk: "1720" + ifc_clk: "1200" + mac_clk: "1340" + + devports: + - id: "0" + sysport: "257" + type: "cpu" + - fec: "KPFEC" + id: "249" + lanes: "0:8" + serdes_group: "31" + speed: "400G" + sysport: "249" + type: "eth" + - fec: "KPFEC" + id: "241" + lanes: "0:8" + serdes_group: "30" + speed: "400G" + sysport: "241" + type: "eth" + - fec: "KPFEC" + id: "233" + lanes: "0:8" + serdes_group: "29" + speed: "400G" + sysport: "233" + type: "eth" + - fec: "KPFEC" + id: "225" + lanes: "0:8" + serdes_group: "28" + speed: "400G" + sysport: "225" + type: "eth" + - fec: "KPFEC" + id: "217" + lanes: "0:8" + serdes_group: "27" + speed: "400G" + sysport: "217" + type: "eth" + - fec: "KPFEC" + id: "209" + lanes: "0:8" + serdes_group: "26" + speed: "400G" + sysport: "209" + type: "eth" + - fec: "KPFEC" + id: "201" + lanes: "0:8" + serdes_group: "25" + speed: "400G" + sysport: "201" + type: "eth" + - fec: "KPFEC" + id: "193" + lanes: "0:8" + serdes_group: "24" + speed: "400G" + sysport: "193" + type: "eth" + - fec: "KPFEC" + id: "185" + lanes: "0:8" + serdes_group: "23" + speed: "400G" + sysport: "185" + type: "eth" + - fec: "KPFEC" + id: "177" + lanes: "0:8" + serdes_group: "22" + speed: "400G" + sysport: "177" + type: "eth" + - fec: "KPFEC" + id: "169" + lanes: "0:8" + serdes_group: "21" + speed: "400G" + sysport: "169" + type: "eth" + - fec: "KPFEC" + id: "161" + lanes: "0:8" + serdes_group: "20" + speed: "400G" + sysport: "161" + type: "eth" + - fec: "KPFEC" + id: "153" + lanes: "0:8" + serdes_group: "19" + speed: "400G" + sysport: "153" + type: "eth" + - fec: "KPFEC" + id: "145" + lanes: "0:8" + serdes_group: "18" + speed: "400G" + sysport: "145" + type: "eth" + - fec: "KPFEC" + id: "137" + lanes: "0:8" + serdes_group: "17" + speed: "400G" + sysport: "137" + type: "eth" + - fec: "KPFEC" + id: "129" + lanes: "0:8" + serdes_group: "16" + speed: "400G" + sysport: "129" + type: "eth" + - fec: "KPFEC" + id: "121" + lanes: "0:8" + serdes_group: "15" + speed: "400G" + sysport: "121" + type: "eth" + - fec: "KPFEC" + id: "113" + lanes: "0:8" + serdes_group: "14" + speed: "400G" + sysport: "113" + type: "eth" + - fec: "KPFEC" + id: "105" + lanes: "0:8" + serdes_group: "13" + speed: "400G" + sysport: "105" + type: "eth" + - fec: "KPFEC" + id: "97" + lanes: "0:8" + serdes_group: "12" + speed: "400G" + sysport: "97" + type: "eth" + - fec: "KPFEC" + id: "89" + lanes: "0:8" + serdes_group: "11" + speed: "400G" + sysport: "89" + type: "eth" + - fec: "KPFEC" + id: "81" + lanes: "0:8" + serdes_group: "10" + speed: "400G" + sysport: "81" + type: "eth" + - fec: "KPFEC" + id: "73" + lanes: "0:8" + serdes_group: "9" + speed: "400G" + sysport: "73" + type: "eth" + - fec: "KPFEC" + id: "65" + lanes: "0:8" + serdes_group: "8" + speed: "400G" + sysport: "65" + type: "eth" + - fec: "KPFEC" + id: "57" + lanes: "0:8" + serdes_group: "7" + speed: "400G" + sysport: "57" + type: "eth" + - fec: "KPFEC" + id: "49" + lanes: "0:8" + serdes_group: "6" + speed: "400G" + sysport: "49" + type: "eth" + - fec: "KPFEC" + id: "41" + lanes: "0:8" + serdes_group: "5" + speed: "400G" + sysport: "41" + type: "eth" + - fec: "KPFEC" + id: "33" + lanes: "0:8" + serdes_group: "4" + speed: "400G" + sysport: "33" + type: "eth" + - fec: "KPFEC" + id: "25" + lanes: "0:8" + serdes_group: "3" + speed: "400G" + sysport: "25" + type: "eth" + - fec: "KPFEC" + id: "17" + lanes: "0:8" + serdes_group: "2" + speed: "400G" + sysport: "17" + type: "eth" + - fec: "KPFEC" + id: "9" + lanes: "0:8" + serdes_group: "1" + speed: "400G" + sysport: "9" + type: "eth" + - fec: "KPFEC" + id: "1" + lanes: "0:8" + serdes_group: "0" + speed: "400G" + sysport: "1" + type: "eth" + - fec: "NONE" + id: "257" + lanes: "0:1" + serdes_group: "32" + speed: "10G" + sysport: "257" + type: "mgmt 0" + - fec: "NONE" + id: "258" + lanes: "1:1" + serdes_group: "32" + speed: "10G" + sysport: "258" + type: "mgmt 1" + isg: + - id: "0" + lane_swap: "01234567" + rx_polarity: "01110001" + tx_polarity: "00101001" + - id: "1" + lane_swap: "01234567" + rx_polarity: "11100100" + tx_polarity: "10111111" + - id: "2" + lane_swap: "01234567" + rx_polarity: "00010001" + tx_polarity: "00100010" + - id: "3" + lane_swap: "01234567" + rx_polarity: "11011101" + tx_polarity: "00101010" + - id: "4" + lane_swap: "01234567" + rx_polarity: "10010101" + tx_polarity: "10111110" + - id: "5" + lane_swap: "01234567" + rx_polarity: "10111001" + tx_polarity: "01101000" + - id: "6" + lane_swap: "01234567" + rx_polarity: "01110011" + tx_polarity: "01110110" + - id: "7" + lane_swap: "01234567" + rx_polarity: "10111001" + tx_polarity: "01001000" + - id: "8" + lane_swap: "01234567" + rx_polarity: "01000000" + tx_polarity: "11000100" + - id: "9" + lane_swap: "01234567" + rx_polarity: "10100100" + tx_polarity: "10001010" + - id: "10" + lane_swap: "01234567" + rx_polarity: "00011101" + tx_polarity: "11000110" + - id: "11" + lane_swap: "01234567" + rx_polarity: "00000101" + tx_polarity: "01000111" + - id: "12" + lane_swap: "01234567" + rx_polarity: "11100000" + tx_polarity: "01111000" + - id: "13" + lane_swap: "01234567" + rx_polarity: "00101111" + tx_polarity: "10011111" + - id: "14" + lane_swap: "01234567" + rx_polarity: "00011000" + tx_polarity: "00101001" + - id: "15" + lane_swap: "01234567" + rx_polarity: "00110110" + tx_polarity: "10110111" + - id: "16" + lane_swap: "01234567" + rx_polarity: "00000111" + tx_polarity: "00101001" + - id: "17" + lane_swap: "01234567" + rx_polarity: "10001000" + tx_polarity: "10100111" + - id: "18" + lane_swap: "01234567" + rx_polarity: "11111110" + tx_polarity: "00011001" + - id: "19" + lane_swap: "01234567" + rx_polarity: "10011010" + tx_polarity: "10010101" + - id: "20" + lane_swap: "01234567" + rx_polarity: "01100000" + tx_polarity: "00101001" + - id: "21" + lane_swap: "01234567" + rx_polarity: "01111001" + tx_polarity: "10010111" + - id: "22" + lane_swap: "01234567" + rx_polarity: "11010011" + tx_polarity: "00101001" + - id: "23" + lane_swap: "01234567" + rx_polarity: "01111011" + tx_polarity: "10110111" + - id: "24" + lane_swap: "01234567" + rx_polarity: "11101011" + tx_polarity: "00101001" + - id: "25" + lane_swap: "01234567" + rx_polarity: "11010111" + tx_polarity: "10110111" + - id: "26" + lane_swap: "01234567" + rx_polarity: "00101101" + tx_polarity: "00100001" + - id: "27" + lane_swap: "01234567" + rx_polarity: "11011001" + tx_polarity: "11000111" + - id: "28" + lane_swap: "01234567" + rx_polarity: "01010011" + tx_polarity: "00100001" + - id: "29" + lane_swap: "01234567" + rx_polarity: "01111001" + tx_polarity: "10110111" + - id: "30" + lane_swap: "01234567" + rx_polarity: "00110001" + tx_polarity: "00101001" + - id: "31" + lane_swap: "01234567" + rx_polarity: "01101101" + tx_polarity: "10110101" + - id: "32" + lane_swap: "01234567" + rx_polarity: "00000000" + tx_polarity: "00000000" diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_32x400/inno.config.yaml b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_32x400/inno.config.yaml new file mode 100755 index 000000000000..bf1c8f41009f --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_32x400/inno.config.yaml @@ -0,0 +1,7 @@ +IFCS_INIT_FILE : "/usr/share/sonic/hwsku/config_32x400G_midstone200i.yaml" +IFCS_SKU_FILE : "/usr/share/sonic/hwsku/innovium.77700_A" +IFCS_INNO_CLI_PORT : "9999" +IFCS_TARGET : "device" +ULIMIT : "65536" +INNOVIUM_DIR : "/innovium" +PYTHONPATH : "$INNOVIUM_DIR:$INNOVIUM_DIR/cmds:$INNOVIUM_DIR/scripts:$INNOVIUM_DIR/test/:$INNOVIUM_DIR/test/utils:$INNOVIUM_DIR/utils:$INNOVIUM_DIR/pyctypes" diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_32x400/innovium.77700_A b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_32x400/innovium.77700_A new file mode 100644 index 000000000000..84aa41983606 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_32x400/innovium.77700_A @@ -0,0 +1,59 @@ +sku: innovium.77700_A + +device_id: 0x1b58 + +# Hardware constraint information +hardware: + num_ibs: 6 + + ports_per_ib: 32, 32, 32, 32, 20, 20 + recirc_port_num: 32, 32, 32, 32, 32, 32 + cpu_port_num: 33 + cpu_port_ib: 0 + mgmt_port_num: 33 + mgmt_port_ibs: 1,2 + + pics_per_ib: 6, 7, 6, 5, 5, 5 + pic_ports_per_pic: 8 + max_serdes_speed: 50 + + num_shared_pics: 2 + + isg [0-4]: + ib: 0 + pic_id: [0-4] + + isg [5-9]: + ib: 5 + pic_id: [0-4] + + isg [10-14]: + ib: 1 + pic_id: [0-4] + + isg [16-20]: + ib: 3 + pic_id: [0-4] + + isg [21-25]: + ib: 4 + pic_id: [0-4] + + isg [26-30]: + ib: 2 + pic_id: [0-4] + + isg 15: + mode: 8:0 + ib: 1 + pic_id: 5 + + isg 31: + mode: 8:0 + ib: 0 + pic_id: 5 + + isg 32: + mode: 1:1 + ib: 1, 2 + pic_id: 6 diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_32x400/port_config.ini b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_32x400/port_config.ini new file mode 100644 index 000000000000..c8ded273cca8 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_32x400/port_config.ini @@ -0,0 +1,35 @@ +# name lanes speed index mtu fec +Ethernet0 249,250,251,252 400000 0 9126 rs +Ethernet8 241,242,243,244 400000 2 9126 rs +Ethernet16 233,234,235,236 400000 4 9126 rs +Ethernet24 225,226,227,228 400000 6 9126 rs +Ethernet32 217,218,219,220 400000 8 9126 rs +Ethernet40 209,210,211,212 400000 10 9126 rs +Ethernet48 201,202,203,204 400000 12 9126 rs +Ethernet56 193,194,195,196 400000 14 9126 rs +Ethernet64 185,186,187,188 400000 16 9126 rs +Ethernet72 177,178,179,180 400000 18 9126 rs +Ethernet80 169,170,171,172 400000 20 9126 rs +Ethernet88 161,162,163,164 400000 22 9126 rs +Ethernet96 153,154,155,156 400000 24 9126 rs +Ethernet104 145,146,147,148 400000 26 9126 rs +Ethernet112 137,138,139,140 400000 28 9126 rs +Ethernet120 129,130,131,132 400000 30 9126 rs +Ethernet128 121,122,123,124 400000 32 9126 rs +Ethernet136 113,114,115,116 400000 34 9126 rs +Ethernet144 105,106,107,108 400000 36 9126 rs +Ethernet152 97,98,99,100 400000 38 9126 rs +Ethernet160 89,90,91,92 400000 40 9126 rs +Ethernet168 81,82,83,84 400000 42 9126 rs +Ethernet176 73,74,75,76 400000 44 9126 rs +Ethernet184 65,66,67,68 400000 46 9126 rs +Ethernet192 57,58,59,60 400000 48 9126 rs +Ethernet200 49,50,51,52 400000 50 9126 rs +Ethernet208 41,42,43,44 400000 52 9126 rs +Ethernet216 33,34,35,36 400000 54 9126 rs +Ethernet224 25,26,27,28 400000 56 9126 rs +Ethernet232 17,18,19,20 400000 58 9126 rs +Ethernet240 9,10,11,12 400000 60 9126 rs +Ethernet248 1,2,3,4 400000 62 9126 rs +Ethernet256 257 10000 64 9126 none +Ethernet257 258 10000 65 9126 none diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_32x400/qos.json.j2 b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_32x400/qos.json.j2 new file mode 100755 index 000000000000..6c734d46ff2f --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_32x400/qos.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} + +{% set default_ports_num = 32 -%} +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "1":"1", + "0":"0", + "3":"3", + "2":"2", + "5":"5", + "4":"4", + "7":"7", + "6":"6" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "1": "0", + "0": "0", + "3": "0", + "2": "0", + "4": "1", + "5": "2", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"0", + "4":"4", + "5":"5", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "4,5" + } + } +} diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_32x400/sai.profile b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_32x400/sai.profile new file mode 100755 index 000000000000..0769b3063a12 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_32x400/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/inno.config.yaml diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100/buffers.json.j2 b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100/buffers.json.j2 new file mode 100644 index 000000000000..45cebf3b7144 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100/buffers.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '300m' %} +{% set default_ports_num = 64 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "47218432", + "type": "ingress", + "mode": "dynamic", + "xoff": "17708800" + }, + "egress_lossy_pool": { + "size": "18874368", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"1433600", + "size":"1518", + "dynamic_th":"-4", + "xon_offset":"6272" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100/config_64x100G_nrz_midstone200i.yaml b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100/config_64x100G_nrz_midstone200i.yaml new file mode 100644 index 000000000000..813d012ca3d5 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100/config_64x100G_nrz_midstone200i.yaml @@ -0,0 +1,785 @@ +ifcs: + options: + log_level: "off" +nodes: +- node_id: "0" + options: + sku: "configs/sku/innovium.77700_B" + netdev: + - auto_create: "no" + multi_interface: "yes" + buffer_management_mode: "api_driven" + max_lossless_tc: "2" + txring: + - txring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + rxring: + - rxring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44" + - rxring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45" + - rxring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46" + - rxring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47" + sys_clk: "1720" + ifc_clk: "1200" + mac_clk: "1340" + + devports: + - id: "0" + sysport: "1000" + type: "cpu" + - fec: "KRFEC" + id: "249" + lanes: "0:4" + serdes_group: "31" + speed: "100G" + sysport: "249" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "253" + lanes: "4:4" + serdes_group: "31" + speed: "100G" + sysport: "253" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "245" + lanes: "4:4" + serdes_group: "30" + speed: "100G" + sysport: "245" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "241" + lanes: "0:4" + serdes_group: "30" + speed: "100G" + sysport: "241" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "233" + lanes: "0:4" + serdes_group: "29" + speed: "100G" + sysport: "233" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "237" + lanes: "4:4" + serdes_group: "29" + speed: "100G" + sysport: "237" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "229" + lanes: "4:4" + serdes_group: "28" + speed: "100G" + sysport: "229" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "225" + lanes: "0:4" + serdes_group: "28" + speed: "100G" + sysport: "225" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "217" + lanes: "0:4" + serdes_group: "27" + speed: "100G" + sysport: "217" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "221" + lanes: "4:4" + serdes_group: "27" + speed: "100G" + sysport: "221" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "213" + lanes: "4:4" + serdes_group: "26" + speed: "100G" + sysport: "213" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "209" + lanes: "0:4" + serdes_group: "26" + speed: "100G" + sysport: "209" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "201" + lanes: "0:4" + serdes_group: "25" + speed: "100G" + sysport: "201" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "205" + lanes: "4:4" + serdes_group: "25" + speed: "100G" + sysport: "205" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "197" + lanes: "4:4" + serdes_group: "24" + speed: "100G" + sysport: "197" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "193" + lanes: "0:4" + serdes_group: "24" + speed: "100G" + sysport: "193" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "185" + lanes: "0:4" + serdes_group: "23" + speed: "100G" + sysport: "185" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "189" + lanes: "4:4" + serdes_group: "23" + speed: "100G" + sysport: "189" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "181" + lanes: "4:4" + serdes_group: "22" + speed: "100G" + sysport: "181" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "177" + lanes: "0:4" + serdes_group: "22" + speed: "100G" + sysport: "177" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "169" + lanes: "0:4" + serdes_group: "21" + speed: "100G" + sysport: "169" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "173" + lanes: "4:4" + serdes_group: "21" + speed: "100G" + sysport: "173" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "165" + lanes: "4:4" + serdes_group: "20" + speed: "100G" + sysport: "165" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "161" + lanes: "0:4" + serdes_group: "20" + speed: "100G" + sysport: "161" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "153" + lanes: "0:4" + serdes_group: "19" + speed: "100G" + sysport: "153" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "157" + lanes: "4:4" + serdes_group: "19" + speed: "100G" + sysport: "157" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "149" + lanes: "4:4" + serdes_group: "18" + speed: "100G" + sysport: "149" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "145" + lanes: "0:4" + serdes_group: "18" + speed: "100G" + sysport: "145" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "137" + lanes: "0:4" + serdes_group: "17" + speed: "100G" + sysport: "137" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "141" + lanes: "4:4" + serdes_group: "17" + speed: "100G" + sysport: "141" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "133" + lanes: "4:4" + serdes_group: "16" + speed: "100G" + sysport: "133" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "129" + lanes: "0:4" + serdes_group: "16" + speed: "100G" + sysport: "129" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "121" + lanes: "0:4" + serdes_group: "15" + speed: "100G" + sysport: "121" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "125" + lanes: "4:4" + serdes_group: "15" + speed: "100G" + sysport: "125" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "117" + lanes: "4:4" + serdes_group: "14" + speed: "100G" + sysport: "117" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "113" + lanes: "0:4" + serdes_group: "14" + speed: "100G" + sysport: "113" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "105" + lanes: "0:4" + serdes_group: "13" + speed: "100G" + sysport: "105" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "109" + lanes: "4:4" + serdes_group: "13" + speed: "100G" + sysport: "109" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "101" + lanes: "4:4" + serdes_group: "12" + speed: "100G" + sysport: "101" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "97" + lanes: "0:4" + serdes_group: "12" + speed: "100G" + sysport: "97" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "89" + lanes: "0:4" + serdes_group: "11" + speed: "100G" + sysport: "89" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "93" + lanes: "4:4" + serdes_group: "11" + speed: "100G" + sysport: "93" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "85" + lanes: "4:4" + serdes_group: "10" + speed: "100G" + sysport: "85" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "81" + lanes: "0:4" + serdes_group: "10" + speed: "100G" + sysport: "81" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "73" + lanes: "0:4" + serdes_group: "9" + speed: "100G" + sysport: "73" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "77" + lanes: "4:4" + serdes_group: "9" + speed: "100G" + sysport: "77" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "69" + lanes: "4:4" + serdes_group: "8" + speed: "100G" + sysport: "69" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "65" + lanes: "0:4" + serdes_group: "8" + speed: "100G" + sysport: "65" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "57" + lanes: "0:4" + serdes_group: "7" + speed: "100G" + sysport: "57" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "61" + lanes: "4:4" + serdes_group: "7" + speed: "100G" + sysport: "61" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "53" + lanes: "4:4" + serdes_group: "6" + speed: "100G" + sysport: "53" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "49" + lanes: "0:4" + serdes_group: "6" + speed: "100G" + sysport: "49" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "53" + lanes: "0:4" + serdes_group: "5" + speed: "100G" + sysport: "53" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "45" + lanes: "4:4" + serdes_group: "5" + speed: "100G" + sysport: "45" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "37" + lanes: "4:4" + serdes_group: "4" + speed: "100G" + sysport: "37" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "33" + lanes: "0:4" + serdes_group: "4" + speed: "100G" + sysport: "33" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "57" + lanes: "0:4" + serdes_group: "3" + speed: "100G" + sysport: "57" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "29" + lanes: "4:4" + serdes_group: "3" + speed: "100G" + sysport: "29" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "21" + lanes: "4:4" + serdes_group: "2" + speed: "100G" + sysport: "21" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "17" + lanes: "0:4" + serdes_group: "2" + speed: "100G" + sysport: "17" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "61" + lanes: "0:4" + serdes_group: "1" + speed: "100G" + sysport: "61" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "13" + lanes: "4:4" + serdes_group: "1" + speed: "100G" + sysport: "13" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "5" + lanes: "4:4" + serdes_group: "0" + speed: "100G" + sysport: "5" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "1" + lanes: "0:4" + serdes_group: "0" + speed: "100G" + sysport: "1" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "NONE" + id: "257" + lanes: "0:1" + serdes_group: "32" + speed: "10G" + sysport: "257" + type: "mgmt 0" + admin_state: "true" + loopback: "none" + - fec: "NONE" + id: "258" + lanes: "1:1" + serdes_group: "32" + speed: "10G" + sysport: "258" + type: "mgmt 1" + admin_state: "true" + loopback: "none" + isg: + - id: "0" + lane_swap: "01234567" + rx_polarity: "01110001" + tx_polarity: "00101001" + - id: "1" + lane_swap: "01234567" + rx_polarity: "11100100" + tx_polarity: "10111111" + - id: "2" + lane_swap: "01234567" + rx_polarity: "00010001" + tx_polarity: "00100010" + - id: "3" + lane_swap: "01234567" + rx_polarity: "11011101" + tx_polarity: "00101010" + - id: "4" + lane_swap: "01234567" + rx_polarity: "10010101" + tx_polarity: "10111110" + - id: "5" + lane_swap: "01234567" + rx_polarity: "10111001" + tx_polarity: "01101000" + - id: "6" + lane_swap: "01234567" + rx_polarity: "01110011" + tx_polarity: "01110110" + - id: "7" + lane_swap: "01234567" + rx_polarity: "10111001" + tx_polarity: "01001000" + - id: "8" + lane_swap: "01234567" + rx_polarity: "01000000" + tx_polarity: "11000100" + - id: "9" + lane_swap: "01234567" + rx_polarity: "10100100" + tx_polarity: "10001010" + - id: "10" + lane_swap: "01234567" + rx_polarity: "00011101" + tx_polarity: "11000110" + - id: "11" + lane_swap: "01234567" + rx_polarity: "00000101" + tx_polarity: "01000111" + - id: "12" + lane_swap: "01234567" + rx_polarity: "11100000" + tx_polarity: "01111000" + - id: "13" + lane_swap: "01234567" + rx_polarity: "00101111" + tx_polarity: "10011111" + - id: "14" + lane_swap: "01234567" + rx_polarity: "00011000" + tx_polarity: "00101001" + - id: "15" + lane_swap: "01234567" + rx_polarity: "00110110" + tx_polarity: "10110111" + - id: "16" + lane_swap: "01234567" + rx_polarity: "00000111" + tx_polarity: "00101001" + - id: "17" + lane_swap: "01234567" + rx_polarity: "10001000" + tx_polarity: "10100111" + - id: "18" + lane_swap: "01234567" + rx_polarity: "11111110" + tx_polarity: "00011001" + - id: "19" + lane_swap: "01234567" + rx_polarity: "10011010" + tx_polarity: "10010101" + - id: "20" + lane_swap: "01234567" + rx_polarity: "01100000" + tx_polarity: "00101001" + - id: "21" + lane_swap: "01234567" + rx_polarity: "01111001" + tx_polarity: "10010111" + - id: "22" + lane_swap: "01234567" + rx_polarity: "11010011" + tx_polarity: "00101001" + - id: "23" + lane_swap: "01234567" + rx_polarity: "01111011" + tx_polarity: "10110111" + - id: "24" + lane_swap: "01234567" + rx_polarity: "11101011" + tx_polarity: "00101001" + - id: "25" + lane_swap: "01234567" + rx_polarity: "11010111" + tx_polarity: "10110111" + - id: "26" + lane_swap: "01234567" + rx_polarity: "00101101" + tx_polarity: "00100001" + - id: "27" + lane_swap: "01234567" + rx_polarity: "11011001" + tx_polarity: "11000111" + - id: "28" + lane_swap: "01234567" + rx_polarity: "01010011" + tx_polarity: "00100001" + - id: "29" + lane_swap: "01234567" + rx_polarity: "01111001" + tx_polarity: "10110111" + - id: "30" + lane_swap: "01234567" + rx_polarity: "00110001" + tx_polarity: "00101001" + - id: "31" + lane_swap: "01234567" + rx_polarity: "01101101" + tx_polarity: "10110101" + - id: "32" + lane_swap: "01234567" + rx_polarity: "00000000" + tx_polarity: "00000000" diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100/inno.config.yaml b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100/inno.config.yaml new file mode 100755 index 000000000000..7dea4565d8e6 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100/inno.config.yaml @@ -0,0 +1,7 @@ +IFCS_INIT_FILE : "/usr/share/sonic/hwsku/config_64x100G_nrz_midstone200i.yaml" +IFCS_SKU_FILE : "/usr/share/sonic/hwsku/innovium.77700_B" +IFCS_INNO_CLI_PORT : "9999" +IFCS_TARGET : "device" +ULIMIT : "65536" +INNOVIUM_DIR : "/innovium" +PYTHONPATH : "$INNOVIUM_DIR:$INNOVIUM_DIR/cmds:$INNOVIUM_DIR/scripts:$INNOVIUM_DIR/test/:$INNOVIUM_DIR/test/utils:$INNOVIUM_DIR/utils:$INNOVIUM_DIR/pyctypes" diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100/innovium.77700_B b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100/innovium.77700_B new file mode 100644 index 000000000000..27297b313959 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100/innovium.77700_B @@ -0,0 +1,59 @@ +sku: innovium.77700_B + +device_id: 0x1b58 + +# Hardware constraint information +hardware: + num_ibs: 6 + + ports_per_ib: 32, 32, 32, 32, 20, 20 + recirc_port_num: 32, 32, 32, 32, 32, 32 + cpu_port_num: 33 + cpu_port_ib: 0 + mgmt_port_num: 33 + mgmt_port_ibs: 1,2 + + pics_per_ib: 6, 7, 7, 6, 5, 5 + pic_ports_per_pic: 8 + max_serdes_speed: 50 + + num_shared_pics: 2 + + isg [0-4]: + ib: 0 + pic_id: [0-4] + + isg [5-9]: + ib: 5 + pic_id: [0-4] + + isg [10-14]: + ib: 1 + pic_id: [0-4] + + isg [16-20]: + ib: 3 + pic_id: [0-4] + + isg [21-25]: + ib: 4 + pic_id: [0-4] + + isg [26-30]: + ib: 2 + pic_id: [0-4] + + isg 15: + mode: 4:4 + ib: 1, 3 + pic_id: 5 + + isg 31: + mode: 4:4 + ib: 0, 2 + pic_id: 5 + + isg 32: + mode: 1:1 + ib: 1, 2 + pic_id: 6 diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100/port_config.ini b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100/port_config.ini new file mode 100644 index 000000000000..cb862ff9b523 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100/port_config.ini @@ -0,0 +1,67 @@ +# name lanes speed index mtu +Ethernet0 249,250,251,252 100000 0 9126 +Ethernet4 253,254,255,256 100000 1 9126 +Ethernet8 245,246,247,248 100000 2 9126 +Ethernet12 241,242,243,244 100000 3 9126 +Ethernet16 233,234,235,236 100000 4 9126 +Ethernet20 237,238,239,240 100000 5 9126 +Ethernet24 229,230,231,232 100000 6 9126 +Ethernet28 225,226,227,228 100000 7 9126 +Ethernet32 217,218,219,220 100000 8 9126 +Ethernet36 221,222,223,224 100000 9 9126 +Ethernet40 213,214,215,216 100000 10 9126 +Ethernet44 209,210,211,212 100000 11 9126 +Ethernet48 201,202,203,204 100000 12 9126 +Ethernet52 205,206,207,208 100000 13 9126 +Ethernet56 197,198,199,200 100000 14 9126 +Ethernet60 193,194,195,196 100000 15 9126 +Ethernet64 185,186,187,188 100000 16 9126 +Ethernet68 189,190,191,192 100000 17 9126 +Ethernet72 181,182,183,184 100000 18 9126 +Ethernet76 177,178,179,180 100000 19 9126 +Ethernet80 169,170,171,172 100000 20 9126 +Ethernet84 173,174,175,176 100000 21 9126 +Ethernet88 165,166,167,168 100000 22 9126 +Ethernet92 161,162,163,164 100000 23 9126 +Ethernet96 153,154,155,156 100000 24 9126 +Ethernet100 157,158,159,160 100000 25 9126 +Ethernet104 149,150,151,152 100000 26 9126 +Ethernet108 145,146,147,148 100000 27 9126 +Ethernet112 137,138,139,140 100000 28 9126 +Ethernet116 141,142,143,144 100000 29 9126 +Ethernet120 133,134,135,136 100000 30 9126 +Ethernet124 129,130,131,132 100000 31 9126 +Ethernet128 121,122,123,124 100000 32 9126 +Ethernet132 125,126,127,128 100000 33 9126 +Ethernet136 117,118,119,120 100000 34 9126 +Ethernet140 113,114,115,116 100000 35 9126 +Ethernet144 105,106,107,108 100000 36 9126 +Ethernet148 109,110,111,112 100000 37 9126 +Ethernet152 101,102,103,104 100000 38 9126 +Ethernet156 97,98,99,100 100000 39 9126 +Ethernet160 89,90,91,92 100000 40 9126 +Ethernet164 93,94,95,96 100000 41 9126 +Ethernet168 85,86,87,88 100000 42 9126 +Ethernet172 81,82,83,84 100000 43 9126 +Ethernet176 73,74,75,76 100000 44 9126 +Ethernet180 77,78,79,80 100000 45 9126 +Ethernet184 69,70,71,72 100000 46 9126 +Ethernet188 65,66,67,68 100000 47 9126 +Ethernet192 57,58,59,60 100000 48 9126 +Ethernet196 61,62,63,64 100000 49 9126 +Ethernet200 53,54,55,56 100000 50 9126 +Ethernet204 49,50,51,52 100000 51 9126 +Ethernet208 41,42,43,44 100000 52 9126 +Ethernet212 45,46,47,48 100000 53 9126 +Ethernet216 37,38,39,40 100000 54 9126 +Ethernet220 33,34,35,36 100000 55 9126 +Ethernet224 25,26,27,28 100000 56 9126 +Ethernet228 29,30,31,32 100000 57 9126 +Ethernet232 21,22,23,24 100000 58 9126 +Ethernet236 17,18,19,20 100000 59 9126 +Ethernet240 9,10,11,12 100000 60 9126 +Ethernet244 13,14,15,16 100000 61 9126 +Ethernet248 5,6,7,8 100000 62 9126 +Ethernet252 1,2,3,4 100000 63 9126 +Ethernet256 257 10000 64 9126 +Ethernet257 258 10000 65 9126 diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100/qos.json.j2 b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100/qos.json.j2 new file mode 100755 index 000000000000..16f9b42a2166 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100/qos.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} + +{% set default_ports_num = 64 -%} +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "1":"1", + "0":"0", + "3":"3", + "2":"2", + "5":"5", + "4":"4", + "7":"7", + "6":"6" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "1": "0", + "0": "0", + "3": "0", + "2": "0", + "4": "1", + "5": "2", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"0", + "4":"4", + "5":"5", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "4,5" + } + } +} diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100/sai.profile b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100/sai.profile new file mode 100755 index 000000000000..0769b3063a12 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/inno.config.yaml diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100nrz/buffers.json.j2 b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100nrz/buffers.json.j2 new file mode 100644 index 000000000000..0285e389fd63 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100nrz/buffers.json.j2 @@ -0,0 +1,121 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '300m' %} +{% set default_speed = '100G' %} +{% set default_ports_num = 32 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "47218432", + "type": "ingress", + "mode": "dynamic", + "xoff": "17708800" + }, + "egress_lossy_pool": { + "size": "18874368", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"1433600", + "size":"1518", + "dynamic_th":"-4", + "xon_offset":"6272" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100nrz/config_64x100G_nrz_midstone200i.yaml b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100nrz/config_64x100G_nrz_midstone200i.yaml new file mode 100644 index 000000000000..8fb6a114a46c --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100nrz/config_64x100G_nrz_midstone200i.yaml @@ -0,0 +1,767 @@ +ifcs: + options: + log_level: "info" +nodes: +- node_id: "0" + options: + sku: "configs/sku/innovium.77700_B" + netdev: + - auto_create: "no" + multi_interface: "yes" + buffer_management_mode: "bootstrap_lossless" + max_lossless_tc: "2" + txring: + - txring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + rxring: + - rxring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44" + - rxring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45" + - rxring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46" + - rxring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47" + sys_clk: "1720" + ifc_clk: "1200" + mac_clk: "1340" + + devports: + - id: "0" + sysport: "65" + type: "cpu" + - fec: "KRFEC" + id: "1" + lanes: "0:4" + serdes_group: "31" + speed: "100G" + sysport: "1" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "2" + lanes: "4:4" + serdes_group: "31" + speed: "100G" + sysport: "2" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "3" + lanes: "4:4" + serdes_group: "30" + speed: "100G" + sysport: "3" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "4" + lanes: "0:4" + serdes_group: "30" + speed: "100G" + sysport: "4" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "5" + lanes: "0:4" + serdes_group: "29" + speed: "100G" + sysport: "5" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "6" + lanes: "4:4" + serdes_group: "29" + speed: "100G" + sysport: "6" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "7" + lanes: "4:4" + serdes_group: "28" + speed: "100G" + sysport: "7" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "8" + lanes: "0:4" + serdes_group: "28" + speed: "100G" + sysport: "8" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "9" + lanes: "0:4" + serdes_group: "27" + speed: "100G" + sysport: "9" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "10" + lanes: "4:4" + serdes_group: "27" + speed: "100G" + sysport: "10" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "11" + lanes: "4:4" + serdes_group: "26" + speed: "100G" + sysport: "11" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "12" + lanes: "0:4" + serdes_group: "26" + speed: "100G" + sysport: "12" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "13" + lanes: "0:4" + serdes_group: "25" + speed: "100G" + sysport: "13" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "14" + lanes: "4:4" + serdes_group: "25" + speed: "100G" + sysport: "14" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "15" + lanes: "4:4" + serdes_group: "24" + speed: "100G" + sysport: "15" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "16" + lanes: "0:4" + serdes_group: "24" + speed: "100G" + sysport: "16" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "17" + lanes: "0:4" + serdes_group: "23" + speed: "100G" + sysport: "17" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "18" + lanes: "4:4" + serdes_group: "23" + speed: "100G" + sysport: "18" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "19" + lanes: "4:4" + serdes_group: "22" + speed: "100G" + sysport: "19" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "20" + lanes: "0:4" + serdes_group: "22" + speed: "100G" + sysport: "20" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "21" + lanes: "0:4" + serdes_group: "21" + speed: "100G" + sysport: "21" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "22" + lanes: "4:4" + serdes_group: "21" + speed: "100G" + sysport: "22" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "23" + lanes: "4:4" + serdes_group: "20" + speed: "100G" + sysport: "23" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "24" + lanes: "0:4" + serdes_group: "20" + speed: "100G" + sysport: "24" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "25" + lanes: "0:4" + serdes_group: "19" + speed: "100G" + sysport: "25" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "26" + lanes: "4:4" + serdes_group: "19" + speed: "100G" + sysport: "26" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "27" + lanes: "4:4" + serdes_group: "18" + speed: "100G" + sysport: "27" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "28" + lanes: "0:4" + serdes_group: "18" + speed: "100G" + sysport: "28" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "29" + lanes: "0:4" + serdes_group: "17" + speed: "100G" + sysport: "29" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "30" + lanes: "4:4" + serdes_group: "17" + speed: "100G" + sysport: "30" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "31" + lanes: "4:4" + serdes_group: "16" + speed: "100G" + sysport: "31" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "32" + lanes: "0:4" + serdes_group: "16" + speed: "100G" + sysport: "32" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "33" + lanes: "0:4" + serdes_group: "15" + speed: "100G" + sysport: "33" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "34" + lanes: "4:4" + serdes_group: "15" + speed: "100G" + sysport: "34" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "35" + lanes: "4:4" + serdes_group: "14" + speed: "100G" + sysport: "35" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "36" + lanes: "0:4" + serdes_group: "14" + speed: "100G" + sysport: "36" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "37" + lanes: "0:4" + serdes_group: "13" + speed: "100G" + sysport: "37" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "38" + lanes: "4:4" + serdes_group: "13" + speed: "100G" + sysport: "38" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "39" + lanes: "4:4" + serdes_group: "12" + speed: "100G" + sysport: "39" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "40" + lanes: "0:4" + serdes_group: "12" + speed: "100G" + sysport: "40" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "41" + lanes: "0:4" + serdes_group: "11" + speed: "100G" + sysport: "41" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "42" + lanes: "4:4" + serdes_group: "11" + speed: "100G" + sysport: "42" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "43" + lanes: "4:4" + serdes_group: "10" + speed: "100G" + sysport: "43" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "44" + lanes: "0:4" + serdes_group: "10" + speed: "100G" + sysport: "44" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "45" + lanes: "0:4" + serdes_group: "9" + speed: "100G" + sysport: "45" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "46" + lanes: "4:4" + serdes_group: "9" + speed: "100G" + sysport: "46" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "47" + lanes: "4:4" + serdes_group: "8" + speed: "100G" + sysport: "47" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "48" + lanes: "0:4" + serdes_group: "8" + speed: "100G" + sysport: "48" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "49" + lanes: "0:4" + serdes_group: "7" + speed: "100G" + sysport: "49" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "50" + lanes: "4:4" + serdes_group: "7" + speed: "100G" + sysport: "50" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "51" + lanes: "4:4" + serdes_group: "6" + speed: "100G" + sysport: "51" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "52" + lanes: "0:4" + serdes_group: "6" + speed: "100G" + sysport: "52" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "53" + lanes: "0:4" + serdes_group: "5" + speed: "100G" + sysport: "53" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "54" + lanes: "4:4" + serdes_group: "5" + speed: "100G" + sysport: "54" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "55" + lanes: "4:4" + serdes_group: "4" + speed: "100G" + sysport: "55" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "56" + lanes: "0:4" + serdes_group: "4" + speed: "100G" + sysport: "56" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "57" + lanes: "0:4" + serdes_group: "3" + speed: "100G" + sysport: "57" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "58" + lanes: "4:4" + serdes_group: "3" + speed: "100G" + sysport: "58" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "59" + lanes: "4:4" + serdes_group: "2" + speed: "100G" + sysport: "59" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "60" + lanes: "0:4" + serdes_group: "2" + speed: "100G" + sysport: "60" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "61" + lanes: "0:4" + serdes_group: "1" + speed: "100G" + sysport: "61" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "62" + lanes: "4:4" + serdes_group: "1" + speed: "100G" + sysport: "62" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "63" + lanes: "4:4" + serdes_group: "0" + speed: "100G" + sysport: "63" + type: "eth" + admin_state: "true" + loopback: "none" + - fec: "KRFEC" + id: "64" + lanes: "0:4" + serdes_group: "0" + speed: "100G" + sysport: "64" + type: "eth" + admin_state: "true" + loopback: "none" + isg: + - id: "0" + lane_swap: "01234567" + rx_polarity: "01110001" + tx_polarity: "00101001" + - id: "1" + lane_swap: "01234567" + rx_polarity: "11100100" + tx_polarity: "10111111" + - id: "2" + lane_swap: "01234567" + rx_polarity: "00010001" + tx_polarity: "00100010" + - id: "3" + lane_swap: "01234567" + rx_polarity: "11011101" + tx_polarity: "00101010" + - id: "4" + lane_swap: "01234567" + rx_polarity: "10010101" + tx_polarity: "10111110" + - id: "5" + lane_swap: "01234567" + rx_polarity: "10111001" + tx_polarity: "01101000" + - id: "6" + lane_swap: "01234567" + rx_polarity: "01110011" + tx_polarity: "01110110" + - id: "7" + lane_swap: "01234567" + rx_polarity: "10111001" + tx_polarity: "01001000" + - id: "8" + lane_swap: "01234567" + rx_polarity: "01000000" + tx_polarity: "11000100" + - id: "9" + lane_swap: "01234567" + rx_polarity: "10100100" + tx_polarity: "10001010" + - id: "10" + lane_swap: "01234567" + rx_polarity: "00011101" + tx_polarity: "11000110" + - id: "11" + lane_swap: "01234567" + rx_polarity: "00000101" + tx_polarity: "01000111" + - id: "12" + lane_swap: "01234567" + rx_polarity: "11100000" + tx_polarity: "01111000" + - id: "13" + lane_swap: "01234567" + rx_polarity: "00101111" + tx_polarity: "10011111" + - id: "14" + lane_swap: "01234567" + rx_polarity: "00011000" + tx_polarity: "00101001" + - id: "15" + lane_swap: "01234567" + rx_polarity: "00110110" + tx_polarity: "10110111" + - id: "16" + lane_swap: "01234567" + rx_polarity: "00000111" + tx_polarity: "00101001" + - id: "17" + lane_swap: "01234567" + rx_polarity: "10001000" + tx_polarity: "10100111" + - id: "18" + lane_swap: "01234567" + rx_polarity: "11111110" + tx_polarity: "00011001" + - id: "19" + lane_swap: "01234567" + rx_polarity: "10011010" + tx_polarity: "10010101" + - id: "20" + lane_swap: "01234567" + rx_polarity: "01100000" + tx_polarity: "00101001" + - id: "21" + lane_swap: "01234567" + rx_polarity: "01111001" + tx_polarity: "10010111" + - id: "22" + lane_swap: "01234567" + rx_polarity: "11010011" + tx_polarity: "00101001" + - id: "23" + lane_swap: "01234567" + rx_polarity: "01111011" + tx_polarity: "10110111" + - id: "24" + lane_swap: "01234567" + rx_polarity: "11101011" + tx_polarity: "00101001" + - id: "25" + lane_swap: "01234567" + rx_polarity: "11010111" + tx_polarity: "10110111" + - id: "26" + lane_swap: "01234567" + rx_polarity: "00101101" + tx_polarity: "00100001" + - id: "27" + lane_swap: "01234567" + rx_polarity: "11011001" + tx_polarity: "11000111" + - id: "28" + lane_swap: "01234567" + rx_polarity: "01010011" + tx_polarity: "00100001" + - id: "29" + lane_swap: "01234567" + rx_polarity: "01111001" + tx_polarity: "10110111" + - id: "30" + lane_swap: "01234567" + rx_polarity: "00110001" + tx_polarity: "00101001" + - id: "31" + lane_swap: "01234567" + rx_polarity: "01101101" + tx_polarity: "10110101" + - id: "32" + lane_swap: "01234567" + rx_polarity: "00000000" + tx_polarity: "00000000" diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100nrz/inno.config.yaml b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100nrz/inno.config.yaml new file mode 100755 index 000000000000..490de1ca3fdc --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100nrz/inno.config.yaml @@ -0,0 +1,7 @@ +IFCS_INIT_FILE : "/usr/share/sonic/hwsku/config_64x100G_nrz_midstone200i.yaml" +IFCS_SKU_FILE : "/usr/share/sonic/hwsku/innovium.77700_B" +IFCS_INNO_CLI_PORT : "9999" +IFCS_TARGET : "device" +ULIMIT : "65536" +INNOVIUM_DIR : "/innovium" +PYTHONPATH : "$INNOVIUM_DIR:$INNOVIUM_DIR/cmds:$INNOVIUM_DIR/scripts:$INNOVIUM_DIR/test/:$INNOVIUM_DIR/test/utils" diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100nrz/innovium.77700_B b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100nrz/innovium.77700_B new file mode 100644 index 000000000000..27297b313959 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100nrz/innovium.77700_B @@ -0,0 +1,59 @@ +sku: innovium.77700_B + +device_id: 0x1b58 + +# Hardware constraint information +hardware: + num_ibs: 6 + + ports_per_ib: 32, 32, 32, 32, 20, 20 + recirc_port_num: 32, 32, 32, 32, 32, 32 + cpu_port_num: 33 + cpu_port_ib: 0 + mgmt_port_num: 33 + mgmt_port_ibs: 1,2 + + pics_per_ib: 6, 7, 7, 6, 5, 5 + pic_ports_per_pic: 8 + max_serdes_speed: 50 + + num_shared_pics: 2 + + isg [0-4]: + ib: 0 + pic_id: [0-4] + + isg [5-9]: + ib: 5 + pic_id: [0-4] + + isg [10-14]: + ib: 1 + pic_id: [0-4] + + isg [16-20]: + ib: 3 + pic_id: [0-4] + + isg [21-25]: + ib: 4 + pic_id: [0-4] + + isg [26-30]: + ib: 2 + pic_id: [0-4] + + isg 15: + mode: 4:4 + ib: 1, 3 + pic_id: 5 + + isg 31: + mode: 4:4 + ib: 0, 2 + pic_id: 5 + + isg 32: + mode: 1:1 + ib: 1, 2 + pic_id: 6 diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100nrz/port_config.ini b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100nrz/port_config.ini new file mode 100644 index 000000000000..462950d390b6 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100nrz/port_config.ini @@ -0,0 +1,65 @@ +# name lanes speed mtu +Ethernet0 249,250,251,252 100000 9126 +Ethernet4 253,254,255,256 100000 9126 +Ethernet8 245,246,247,248 100000 9126 +Ethernet12 241,242,243,244 100000 9126 +Ethernet16 233,234,235,236 100000 9126 +Ethernet20 237,238,239,240 100000 9126 +Ethernet24 229,230,231,232 100000 9126 +Ethernet28 225,226,227,228 100000 9126 +Ethernet32 217,218,219,220 100000 9126 +Ethernet36 221,222,223,224 100000 9126 +Ethernet40 213,214,215,216 100000 9126 +Ethernet44 209,210,211,212 100000 9126 +Ethernet48 201,202,203,204 100000 9126 +Ethernet52 205,206,207,208 100000 9126 +Ethernet56 197,198,199,200 100000 9126 +Ethernet60 193,194,195,196 100000 9126 +Ethernet64 185,186,187,188 100000 9126 +Ethernet68 189,190,191,192 100000 9126 +Ethernet72 181,182,183,184 100000 9126 +Ethernet76 177,178,179,180 100000 9126 +Ethernet80 169,170,171,172 100000 9126 +Ethernet84 173,174,175,176 100000 9126 +Ethernet88 165,166,167,168 100000 9126 +Ethernet92 161,162,163,164 100000 9126 +Ethernet96 153,154,155,156 100000 9126 +Ethernet100 157,158,159,160 100000 9126 +Ethernet104 149,150,151,152 100000 9126 +Ethernet108 145,146,147,148 100000 9126 +Ethernet112 137,138,139,140 100000 9126 +Ethernet116 141,142,143,144 100000 9126 +Ethernet120 133,134,135,136 100000 9126 +Ethernet124 129,130,131,132 100000 9126 +Ethernet128 121,122,123,124 100000 9126 +Ethernet132 125,126,127,128 100000 9126 +Ethernet136 117,118,119,120 100000 9126 +Ethernet140 113,114,115,116 100000 9126 +Ethernet144 105,106,107,108 100000 9126 +Ethernet148 109,110,111,112 100000 9126 +Ethernet152 101,102,103,104 100000 9126 +Ethernet156 97,98,99,100 100000 9126 +Ethernet160 89,90,91,92 100000 9126 +Ethernet164 93,94,95,96 100000 9126 +Ethernet168 85,86,87,88 100000 9126 +Ethernet172 81,82,83,84 100000 9126 +Ethernet176 73,74,75,76 100000 9126 +Ethernet180 77,78,79,80 100000 9126 +Ethernet184 69,70,71,72 100000 9126 +Ethernet188 65,66,67,68 100000 9126 +Ethernet192 57,58,59,60 100000 9126 +Ethernet196 61,62,63,64 100000 9126 +Ethernet200 53,54,55,56 100000 9126 +Ethernet204 49,50,51,52 100000 9126 +Ethernet208 41,42,43,44 100000 9126 +Ethernet212 45,46,47,48 100000 9126 +Ethernet216 37,38,39,40 100000 9126 +Ethernet220 33,34,35,36 100000 9126 +Ethernet224 25,26,27,28 100000 9126 +Ethernet228 29,30,31,32 100000 9126 +Ethernet232 21,22,23,24 100000 9126 +Ethernet236 17,18,19,20 100000 9126 +Ethernet240 9,10,11,12 100000 9126 +Ethernet244 13,14,15,16 100000 9126 +Ethernet248 5,6,7,8 100000 9126 +Ethernet252 1,2,3,4 100000 9126 diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100nrz/qos.json.j2 b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100nrz/qos.json.j2 new file mode 100755 index 000000000000..b22aa6ef599b --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100nrz/qos.json.j2 @@ -0,0 +1,102 @@ +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "1":"1", + "0":"0", + "3":"3", + "2":"2", + "5":"5", + "4":"4", + "7":"7", + "6":"6" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "1": "0", + "0": "0", + "3": "0", + "2": "0", + "4": "1", + "5": "2", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"0", + "4":"4", + "5":"5", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "Ethernet180,Ethernet8,Ethernet44,Ethernet184,Ethernet188,Ethernet0,Ethernet4,Ethernet108,Ethernet248,Ethernet100,Ethernet244,Ethernet128,Ethernet104,Ethernet240,Ethernet40,Ethernet228,Ethernet96,Ethernet168,Ethernet148,Ethernet204,Ethernet120,Ethernet220,Ethernet144,Ethernet208,Ethernet160,Ethernet224,Ethernet140,Ethernet56,Ethernet164,Ethernet76,Ethernet72,Ethernet32,Ethernet16,Ethernet36,Ethernet12,Ethernet196,Ethernet28,Ethernet192,Ethernet200,Ethernet124,Ethernet24,Ethernet116,Ethernet80,Ethernet112,Ethernet84,Ethernet152,Ethernet136,Ethernet156,Ethernet92,Ethernet132,Ethernet48,Ethernet232,Ethernet172,Ethernet216,Ethernet236,Ethernet176,Ethernet212,Ethernet64,Ethernet88,Ethernet60,Ethernet52,Ethernet20,Ethernet68,Ethernet252": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "4,5" + } + } +} diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100nrz/sai.profile b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100nrz/sai.profile new file mode 100755 index 000000000000..0769b3063a12 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x100nrz/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/inno.config.yaml diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x200/buffers.json.j2 b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x200/buffers.json.j2 new file mode 100644 index 000000000000..45cebf3b7144 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x200/buffers.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '300m' %} +{% set default_ports_num = 64 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "47218432", + "type": "ingress", + "mode": "dynamic", + "xoff": "17708800" + }, + "egress_lossy_pool": { + "size": "18874368", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"1433600", + "size":"1518", + "dynamic_th":"-4", + "xon_offset":"6272" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x200/config_64x200G_midstone200i.yaml b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x200/config_64x200G_midstone200i.yaml new file mode 100644 index 000000000000..7133de54e493 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x200/config_64x200G_midstone200i.yaml @@ -0,0 +1,653 @@ +ifcs: + options: + log_level: "info" +nodes: +- node_id: "0" + options: + sku: "configs/sku/innovium.77700_B" + netdev: + - auto_create: "no" + multi_interface: "yes" + buffer_management_mode: "api_driven" + max_lossless_tc: "2" + txring: + - txring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + rxring: + - rxring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44" + - rxring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45" + - rxring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46" + - rxring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47" + sys_clk: "1720" + ifc_clk: "1200" + mac_clk: "1340" + + devports: + - id: "0" + sysport: "1000" + type: "cpu" + - fec: "KPFEC" + id: "249" + lanes: "0:4" + serdes_group: "31" + speed: "200G" + sysport: "249" + type: "eth" + - fec: "KPFEC" + id: "253" + lanes: "4:4" + serdes_group: "31" + speed: "200G" + sysport: "253" + type: "eth" + - fec: "KPFEC" + id: "245" + lanes: "4:4" + serdes_group: "30" + speed: "200G" + sysport: "245" + type: "eth" + - fec: "KPFEC" + id: "241" + lanes: "0:4" + serdes_group: "30" + speed: "200G" + sysport: "241" + type: "eth" + - fec: "KPFEC" + id: "233" + lanes: "0:4" + serdes_group: "29" + speed: "200G" + sysport: "233" + type: "eth" + - fec: "KPFEC" + id: "237" + lanes: "4:4" + serdes_group: "29" + speed: "200G" + sysport: "237" + type: "eth" + - fec: "KPFEC" + id: "229" + lanes: "4:4" + serdes_group: "28" + speed: "200G" + sysport: "229" + type: "eth" + - fec: "KPFEC" + id: "225" + lanes: "0:4" + serdes_group: "28" + speed: "200G" + sysport: "225" + type: "eth" + - fec: "KPFEC" + id: "217" + lanes: "0:4" + serdes_group: "27" + speed: "200G" + sysport: "217" + type: "eth" + - fec: "KPFEC" + id: "221" + lanes: "4:4" + serdes_group: "27" + speed: "200G" + sysport: "221" + type: "eth" + - fec: "KPFEC" + id: "213" + lanes: "4:4" + serdes_group: "26" + speed: "200G" + sysport: "213" + type: "eth" + - fec: "KPFEC" + id: "209" + lanes: "0:4" + serdes_group: "26" + speed: "200G" + sysport: "209" + type: "eth" + - fec: "KPFEC" + id: "201" + lanes: "0:4" + serdes_group: "25" + speed: "200G" + sysport: "201" + type: "eth" + - fec: "KPFEC" + id: "205" + lanes: "4:4" + serdes_group: "25" + speed: "200G" + sysport: "205" + type: "eth" + - fec: "KPFEC" + id: "197" + lanes: "4:4" + serdes_group: "24" + speed: "200G" + sysport: "197" + type: "eth" + - fec: "KPFEC" + id: "193" + lanes: "0:4" + serdes_group: "24" + speed: "200G" + sysport: "193" + type: "eth" + - fec: "KPFEC" + id: "185" + lanes: "0:4" + serdes_group: "23" + speed: "200G" + sysport: "185" + type: "eth" + - fec: "KPFEC" + id: "189" + lanes: "4:4" + serdes_group: "23" + speed: "200G" + sysport: "189" + type: "eth" + - fec: "KPFEC" + id: "181" + lanes: "4:4" + serdes_group: "22" + speed: "200G" + sysport: "181" + type: "eth" + - fec: "KPFEC" + id: "177" + lanes: "0:4" + serdes_group: "22" + speed: "200G" + sysport: "177" + type: "eth" + - fec: "KPFEC" + id: "169" + lanes: "0:4" + serdes_group: "21" + speed: "200G" + sysport: "169" + type: "eth" + - fec: "KPFEC" + id: "173" + lanes: "4:4" + serdes_group: "21" + speed: "200G" + sysport: "173" + type: "eth" + - fec: "KPFEC" + id: "165" + lanes: "4:4" + serdes_group: "20" + speed: "200G" + sysport: "165" + type: "eth" + - fec: "KPFEC" + id: "161" + lanes: "0:4" + serdes_group: "20" + speed: "200G" + sysport: "161" + type: "eth" + - fec: "KPFEC" + id: "153" + lanes: "0:4" + serdes_group: "19" + speed: "200G" + sysport: "153" + type: "eth" + - fec: "KPFEC" + id: "157" + lanes: "4:4" + serdes_group: "19" + speed: "200G" + sysport: "157" + type: "eth" + - fec: "KPFEC" + id: "149" + lanes: "4:4" + serdes_group: "18" + speed: "200G" + sysport: "149" + type: "eth" + - fec: "KPFEC" + id: "145" + lanes: "0:4" + serdes_group: "18" + speed: "200G" + sysport: "145" + type: "eth" + - fec: "KPFEC" + id: "137" + lanes: "0:4" + serdes_group: "17" + speed: "200G" + sysport: "137" + type: "eth" + - fec: "KPFEC" + id: "141" + lanes: "4:4" + serdes_group: "17" + speed: "200G" + sysport: "141" + type: "eth" + - fec: "KPFEC" + id: "133" + lanes: "4:4" + serdes_group: "16" + speed: "200G" + sysport: "133" + type: "eth" + - fec: "KPFEC" + id: "129" + lanes: "0:4" + serdes_group: "16" + speed: "200G" + sysport: "129" + type: "eth" + - fec: "KPFEC" + id: "121" + lanes: "0:4" + serdes_group: "15" + speed: "200G" + sysport: "121" + type: "eth" + - fec: "KPFEC" + id: "125" + lanes: "4:4" + serdes_group: "15" + speed: "200G" + sysport: "125" + type: "eth" + - fec: "KPFEC" + id: "117" + lanes: "4:4" + serdes_group: "14" + speed: "200G" + sysport: "117" + type: "eth" + - fec: "KPFEC" + id: "113" + lanes: "0:4" + serdes_group: "14" + speed: "200G" + sysport: "113" + type: "eth" + - fec: "KPFEC" + id: "105" + lanes: "0:4" + serdes_group: "13" + speed: "200G" + sysport: "105" + type: "eth" + - fec: "KPFEC" + id: "109" + lanes: "4:4" + serdes_group: "13" + speed: "200G" + sysport: "109" + type: "eth" + - fec: "KPFEC" + id: "101" + lanes: "4:4" + serdes_group: "12" + speed: "200G" + sysport: "101" + type: "eth" + - fec: "KPFEC" + id: "97" + lanes: "0:4" + serdes_group: "12" + speed: "200G" + sysport: "97" + type: "eth" + - fec: "KPFEC" + id: "89" + lanes: "0:4" + serdes_group: "11" + speed: "200G" + sysport: "89" + type: "eth" + - fec: "KPFEC" + id: "93" + lanes: "4:4" + serdes_group: "11" + speed: "200G" + sysport: "93" + type: "eth" + - fec: "KPFEC" + id: "85" + lanes: "4:4" + serdes_group: "10" + speed: "200G" + sysport: "85" + type: "eth" + - fec: "KPFEC" + id: "81" + lanes: "0:4" + serdes_group: "10" + speed: "200G" + sysport: "81" + type: "eth" + - fec: "KPFEC" + id: "73" + lanes: "0:4" + serdes_group: "9" + speed: "200G" + sysport: "73" + type: "eth" + - fec: "KPFEC" + id: "77" + lanes: "4:4" + serdes_group: "9" + speed: "200G" + sysport: "77" + type: "eth" + - fec: "KPFEC" + id: "69" + lanes: "4:4" + serdes_group: "8" + speed: "200G" + sysport: "69" + type: "eth" + - fec: "KPFEC" + id: "65" + lanes: "0:4" + serdes_group: "8" + speed: "200G" + sysport: "65" + type: "eth" + - fec: "KPFEC" + id: "57" + lanes: "0:4" + serdes_group: "7" + speed: "200G" + sysport: "57" + type: "eth" + - fec: "KPFEC" + id: "61" + lanes: "4:4" + serdes_group: "7" + speed: "200G" + sysport: "61" + type: "eth" + - fec: "KPFEC" + id: "53" + lanes: "4:4" + serdes_group: "6" + speed: "200G" + sysport: "53" + type: "eth" + - fec: "KPFEC" + id: "49" + lanes: "0:4" + serdes_group: "6" + speed: "200G" + sysport: "49" + type: "eth" + - fec: "KPFEC" + id: "41" + lanes: "0:4" + serdes_group: "5" + speed: "200G" + sysport: "41" + type: "eth" + - fec: "KPFEC" + id: "45" + lanes: "4:4" + serdes_group: "5" + speed: "200G" + sysport: "45" + type: "eth" + - fec: "KPFEC" + id: "37" + lanes: "4:4" + serdes_group: "4" + speed: "200G" + sysport: "37" + type: "eth" + - fec: "KPFEC" + id: "33" + lanes: "0:4" + serdes_group: "4" + speed: "200G" + sysport: "33" + type: "eth" + - fec: "KPFEC" + id: "25" + lanes: "0:4" + serdes_group: "3" + speed: "200G" + sysport: "25" + type: "eth" + - fec: "KPFEC" + id: "29" + lanes: "4:4" + serdes_group: "3" + speed: "200G" + sysport: "29" + type: "eth" + - fec: "KPFEC" + id: "21" + lanes: "4:4" + serdes_group: "2" + speed: "200G" + sysport: "21" + type: "eth" + - fec: "KPFEC" + id: "17" + lanes: "0:4" + serdes_group: "2" + speed: "200G" + sysport: "17" + type: "eth" + - fec: "KPFEC" + id: "9" + lanes: "0:4" + serdes_group: "1" + speed: "200G" + sysport: "9" + type: "eth" + - fec: "KPFEC" + id: "13" + lanes: "4:4" + serdes_group: "1" + speed: "200G" + sysport: "13" + type: "eth" + - fec: "KPFEC" + id: "5" + lanes: "4:4" + serdes_group: "0" + speed: "200G" + sysport: "5" + type: "eth" + - fec: "KPFEC" + id: "1" + lanes: "0:4" + serdes_group: "0" + speed: "200G" + sysport: "1" + type: "eth" + - fec: "NONE" + id: "257" + lanes: "0:1" + serdes_group: "32" + speed: "10G" + sysport: "257" + type: "mgmt 0" + - fec: "NONE" + id: "258" + lanes: "1:1" + serdes_group: "32" + speed: "10G" + sysport: "258" + type: "mgmt 0" + isg: + - id: "0" + lane_swap: "01234567" + rx_polarity: "01110001" + tx_polarity: "00101001" + - id: "1" + lane_swap: "01234567" + rx_polarity: "11100100" + tx_polarity: "10111111" + - id: "2" + lane_swap: "01234567" + rx_polarity: "00010001" + tx_polarity: "00100010" + - id: "3" + lane_swap: "01234567" + rx_polarity: "11011101" + tx_polarity: "00101010" + - id: "4" + lane_swap: "01234567" + rx_polarity: "10010101" + tx_polarity: "10111110" + - id: "5" + lane_swap: "01234567" + rx_polarity: "10111001" + tx_polarity: "01101000" + - id: "6" + lane_swap: "01234567" + rx_polarity: "01110011" + tx_polarity: "01110110" + - id: "7" + lane_swap: "01234567" + rx_polarity: "10111001" + tx_polarity: "01001000" + - id: "8" + lane_swap: "01234567" + rx_polarity: "01000000" + tx_polarity: "11000100" + - id: "9" + lane_swap: "01234567" + rx_polarity: "10100100" + tx_polarity: "10001010" + - id: "10" + lane_swap: "01234567" + rx_polarity: "00011101" + tx_polarity: "11000110" + - id: "11" + lane_swap: "01234567" + rx_polarity: "00000101" + tx_polarity: "01000111" + - id: "12" + lane_swap: "01234567" + rx_polarity: "11100000" + tx_polarity: "01111000" + - id: "13" + lane_swap: "01234567" + rx_polarity: "00101111" + tx_polarity: "10011111" + - id: "14" + lane_swap: "01234567" + rx_polarity: "00011000" + tx_polarity: "00101001" + - id: "15" + lane_swap: "01234567" + rx_polarity: "00110110" + tx_polarity: "10110111" + - id: "16" + lane_swap: "01234567" + rx_polarity: "00000111" + tx_polarity: "00101001" + - id: "17" + lane_swap: "01234567" + rx_polarity: "10001000" + tx_polarity: "10100111" + - id: "18" + lane_swap: "01234567" + rx_polarity: "11111110" + tx_polarity: "00011001" + - id: "19" + lane_swap: "01234567" + rx_polarity: "10011010" + tx_polarity: "10010101" + - id: "20" + lane_swap: "01234567" + rx_polarity: "01100000" + tx_polarity: "00101001" + - id: "21" + lane_swap: "01234567" + rx_polarity: "01111001" + tx_polarity: "10010111" + - id: "22" + lane_swap: "01234567" + rx_polarity: "11010011" + tx_polarity: "00101001" + - id: "23" + lane_swap: "01234567" + rx_polarity: "01111011" + tx_polarity: "10110111" + - id: "24" + lane_swap: "01234567" + rx_polarity: "11101011" + tx_polarity: "00101001" + - id: "25" + lane_swap: "01234567" + rx_polarity: "11010111" + tx_polarity: "10110111" + - id: "26" + lane_swap: "01234567" + rx_polarity: "00101101" + tx_polarity: "00100001" + - id: "27" + lane_swap: "01234567" + rx_polarity: "11011001" + tx_polarity: "11000111" + - id: "28" + lane_swap: "01234567" + rx_polarity: "01010011" + tx_polarity: "00100001" + - id: "29" + lane_swap: "01234567" + rx_polarity: "01111001" + tx_polarity: "10110111" + - id: "30" + lane_swap: "01234567" + rx_polarity: "00110001" + tx_polarity: "00101001" + - id: "31" + lane_swap: "01234567" + rx_polarity: "01101101" + tx_polarity: "10110101" + - id: "32" + lane_swap: "01234567" + rx_polarity: "00000000" + tx_polarity: "00000000" diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x200/inno.config.yaml b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x200/inno.config.yaml new file mode 100755 index 000000000000..970a5830339e --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x200/inno.config.yaml @@ -0,0 +1,7 @@ +IFCS_INIT_FILE : "/usr/share/sonic/hwsku/config_64x200G_midstone200i.yaml" +IFCS_SKU_FILE : "/usr/share/sonic/hwsku/innovium.77700_B" +IFCS_INNO_CLI_PORT : "9999" +IFCS_TARGET : "device" +ULIMIT : "65536" +INNOVIUM_DIR : "/innovium" +PYTHONPATH : "$INNOVIUM_DIR:$INNOVIUM_DIR/cmds:$INNOVIUM_DIR/scripts:$INNOVIUM_DIR/test/:$INNOVIUM_DIR/test/utils:$INNOVIUM_DIR/utils:$INNOVIUM_DIR/pyctypes" diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x200/innovium.77700_B b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x200/innovium.77700_B new file mode 100644 index 000000000000..27297b313959 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x200/innovium.77700_B @@ -0,0 +1,59 @@ +sku: innovium.77700_B + +device_id: 0x1b58 + +# Hardware constraint information +hardware: + num_ibs: 6 + + ports_per_ib: 32, 32, 32, 32, 20, 20 + recirc_port_num: 32, 32, 32, 32, 32, 32 + cpu_port_num: 33 + cpu_port_ib: 0 + mgmt_port_num: 33 + mgmt_port_ibs: 1,2 + + pics_per_ib: 6, 7, 7, 6, 5, 5 + pic_ports_per_pic: 8 + max_serdes_speed: 50 + + num_shared_pics: 2 + + isg [0-4]: + ib: 0 + pic_id: [0-4] + + isg [5-9]: + ib: 5 + pic_id: [0-4] + + isg [10-14]: + ib: 1 + pic_id: [0-4] + + isg [16-20]: + ib: 3 + pic_id: [0-4] + + isg [21-25]: + ib: 4 + pic_id: [0-4] + + isg [26-30]: + ib: 2 + pic_id: [0-4] + + isg 15: + mode: 4:4 + ib: 1, 3 + pic_id: 5 + + isg 31: + mode: 4:4 + ib: 0, 2 + pic_id: 5 + + isg 32: + mode: 1:1 + ib: 1, 2 + pic_id: 6 diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x200/port_config.ini b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x200/port_config.ini new file mode 100644 index 000000000000..3dcbf72bc324 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x200/port_config.ini @@ -0,0 +1,67 @@ +# name lanes speed index mtu fec +Ethernet0 249,250,251,252 200000 0 9126 rs +Ethernet4 253,254,255,256 200000 1 9126 rs +Ethernet8 245,246,247,248 200000 2 9126 rs +Ethernet12 241,242,243,244 200000 3 9126 rs +Ethernet16 233,234,235,236 200000 4 9126 rs +Ethernet20 237,238,239,240 200000 5 9126 rs +Ethernet24 229,230,231,232 200000 6 9126 rs +Ethernet28 225,226,227,228 200000 7 9126 rs +Ethernet32 217,218,219,220 200000 8 9126 rs +Ethernet36 221,222,223,224 200000 9 9126 rs +Ethernet40 213,214,215,216 200000 10 9126 rs +Ethernet44 209,210,211,212 200000 11 9126 rs +Ethernet48 201,202,203,204 200000 12 9126 rs +Ethernet52 205,206,207,208 200000 13 9126 rs +Ethernet56 197,198,199,200 200000 14 9126 rs +Ethernet60 193,194,195,196 200000 15 9126 rs +Ethernet64 185,186,187,188 200000 16 9126 rs +Ethernet68 189,190,191,192 200000 17 9126 rs +Ethernet72 181,182,183,184 200000 18 9126 rs +Ethernet76 177,178,179,180 200000 19 9126 rs +Ethernet80 169,170,171,172 200000 20 9126 rs +Ethernet84 173,174,175,176 200000 21 9126 rs +Ethernet88 165,166,167,168 200000 22 9126 rs +Ethernet92 161,162,163,164 200000 23 9126 rs +Ethernet96 153,154,155,156 200000 24 9126 rs +Ethernet100 157,158,159,160 200000 25 9126 rs +Ethernet104 149,150,151,152 200000 26 9126 rs +Ethernet108 145,146,147,148 200000 27 9126 rs +Ethernet112 137,138,139,140 200000 28 9126 rs +Ethernet116 141,142,143,144 200000 29 9126 rs +Ethernet120 133,134,135,136 200000 30 9126 rs +Ethernet124 129,130,131,132 200000 31 9126 rs +Ethernet128 121,122,123,124 200000 32 9126 rs +Ethernet132 125,126,127,128 200000 33 9126 rs +Ethernet136 117,118,119,120 200000 34 9126 rs +Ethernet140 113,114,115,116 200000 35 9126 rs +Ethernet144 105,106,107,108 200000 36 9126 rs +Ethernet148 109,110,111,112 200000 37 9126 rs +Ethernet152 101,102,103,104 200000 38 9126 rs +Ethernet156 97,98,99,100 200000 39 9126 rs +Ethernet160 89,90,91,92 200000 40 9126 rs +Ethernet164 93,94,95,96 200000 41 9126 rs +Ethernet168 85,86,87,88 200000 42 9126 rs +Ethernet172 81,82,83,84 200000 43 9126 rs +Ethernet176 73,74,75,76 200000 44 9126 rs +Ethernet180 77,78,79,80 200000 45 9126 rs +Ethernet184 69,70,71,72 200000 46 9126 rs +Ethernet188 65,66,67,68 200000 47 9126 rs +Ethernet192 57,58,59,60 200000 48 9126 rs +Ethernet196 61,62,63,64 200000 49 9126 rs +Ethernet200 53,54,55,56 200000 50 9126 rs +Ethernet204 49,50,51,52 200000 51 9126 rs +Ethernet208 41,42,43,44 200000 52 9126 rs +Ethernet212 45,46,47,48 200000 53 9126 rs +Ethernet216 37,38,39,40 200000 54 9126 rs +Ethernet220 33,34,35,36 200000 55 9126 rs +Ethernet224 25,26,27,28 200000 56 9126 rs +Ethernet228 29,30,31,32 200000 57 9126 rs +Ethernet232 21,22,23,24 200000 58 9126 rs +Ethernet236 17,18,19,20 200000 59 9126 rs +Ethernet240 9,10,11,12 200000 60 9126 rs +Ethernet244 13,14,15,16 200000 61 9126 rs +Ethernet248 5,6,7,8 200000 62 9126 rs +Ethernet252 1,2,3,4 200000 63 9126 rs +Ethernet256 257 10000 64 9126 none +Ethernet257 258 10000 65 9126 none diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x200/qos.json.j2 b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x200/qos.json.j2 new file mode 100755 index 000000000000..16f9b42a2166 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x200/qos.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} + +{% set default_ports_num = 64 -%} +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "1":"1", + "0":"0", + "3":"3", + "2":"2", + "5":"5", + "4":"4", + "7":"7", + "6":"6" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "1": "0", + "0": "0", + "3": "0", + "2": "0", + "4": "1", + "5": "2", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"0", + "4":"4", + "5":"5", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "4,5" + } + } +} diff --git a/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x200/sai.profile b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x200/sai.profile new file mode 100755 index 000000000000..0769b3063a12 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/Midstone-200i_64x200/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/inno.config.yaml diff --git a/device/celestica/x86_64-cel_midstone-r0/default_sku b/device/celestica/x86_64-cel_midstone-r0/default_sku new file mode 100755 index 000000000000..6fe6e28064bd --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/default_sku @@ -0,0 +1 @@ +Midstone-200i t1 diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/__init__.py b/device/celestica/x86_64-cel_midstone-r0/fancontrol old mode 100644 new mode 100755 similarity index 100% rename from platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/__init__.py rename to device/celestica/x86_64-cel_midstone-r0/fancontrol diff --git a/device/celestica/x86_64-cel_midstone-r0/installer.conf b/device/celestica/x86_64-cel_midstone-r0/installer.conf new file mode 100755 index 000000000000..925a32fc0c3a --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 diff --git a/device/celestica/x86_64-cel_midstone-r0/plugins/eeprom.py b/device/celestica/x86_64-cel_midstone-r0/plugins/eeprom.py new file mode 100755 index 000000000000..86e7f1b2af15 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/plugins/eeprom.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica Midstone-200i +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0056/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/celestica/x86_64-cel_midstone-r0/plugins/psuutil.py b/device/celestica/x86_64-cel_midstone-r0/plugins/psuutil.py new file mode 100644 index 000000000000..4e6c5eec5d85 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/plugins/psuutil.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC PSU Base API and +# provides the PSUs status which are available in the platform +# +############################################################################# + +import os.path +import subprocess + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + + :return: An integer, the number of PSUs available on the device + """ + return 2 + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by 1-based index + + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is faulty + """ + if index is None: + return False + + status = 1 + return status == 1 + + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by 1-based index + + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + if index is None: + return False + + status = 1 + return status == 1 + diff --git a/device/celestica/x86_64-cel_midstone-r0/plugins/sfputil.py b/device/celestica/x86_64-cel_midstone-r0/plugins/sfputil.py new file mode 100755 index 000000000000..4d2a444c198b --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/plugins/sfputil.py @@ -0,0 +1,205 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + 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 = 65 + QSFP_PORT_START = PORT_START + QSFP_PORT_END = 63 + + EEPROM_OFFSET = 1 + + _port_to_eeprom_mapping = {} + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return range(self.QSFP_PORT_START, self.QSFP_PORT_END+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" + + if self.port_start == 1: + offset = self.EEPROM_OFFSET - 1 + else: + offset = self.EEPROM_OFFSET + + for x in range(self.port_start, self.port_end + 1): + self._port_to_eeprom_mapping[x] = eeprom_path.format(x + offset) + + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open("/sys/devices/platform/ms200i_cpld/qsfp_modprs") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = reg_file.readline().rstrip() + + # content is a string containing the hex representation of the register + reg_value = int(content, 16) + + # Determind if port_num start from 1 or 0 + if self.port_start == 1: + bit_index = port_num - 1 + else: + bit_index = port_num + + # Mask off the bit corresponding to our port + mask = (1 << bit_index) + + # ModPrsL is active low + if reg_value & mask == 0: + return True + + return False + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open("/sys/devices/platform/ms200i_cpld/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) + + # Determind if port_num start from 1 or 0 + if self.port_start == 1: + bit_index = port_num - 1 + else: + bit_index = port_num + + # Mask off the bit corresponding to our port + mask = (1 << bit_index) + + # LPMode is active high + if reg_value & mask == 0: + return False + + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open("/sys/devices/platform/ms200i_cpld/qsfp_lpmode", "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = reg_file.readline().rstrip() + + # content is a string containing the hex representation of the register + reg_value = int(content, 16) + + # Determind if port_num start from 1 or 0 + if self.port_start == 1: + bit_index = port_num - 1 + else: + bit_index = port_num + + # Mask off the bit corresponding to our port + mask = (1 << bit_index) + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + reg_value = reg_value | mask + else: + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + content = hex(reg_value).strip('L') + + reg_file.seek(0) + reg_file.write(content) + reg_file.close() + + return True + + def reset(self, port_num): + QSFP_RESET_REGISTER_DEVICE_FILE = "/sys/devices/platform/ms200i_cpld/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) + + # Determind if port_num start from 1 or 0 + if self.port_start == 1: + bit_index = port_num - 1 + else: + bit_index = port_num + + # Mask off the bit corresponding to our port + mask = (1 << bit_index) + + # ResetL is active low + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + reg_file.seek(0) + reg_file.write(hex(reg_value).rstrip('L')) + reg_file.close() + + # Sleep 1 second to allow it to settle + time.sleep(1) + + # Flip the bit back high and write back to the register to take port out of reset + try: + reg_file = open(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).rstrip('L')) + reg_file.close() + + return True diff --git a/device/celestica/x86_64-cel_midstone-r0/sensors.conf b/device/celestica/x86_64-cel_midstone-r0/sensors.conf new file mode 100755 index 000000000000..7c9a6321dfc0 --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/sensors.conf @@ -0,0 +1,2 @@ +# libsensors configuration file for Celestica Midstone-200i. +# The i2c bus portion is omit because adapter name diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/buffers.json.j2 b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/buffers_defaults_t0.j2 b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..4dd6bd96ad96 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/buffers_defaults_t0.j2 @@ -0,0 +1,54 @@ + +{%- set default_cable = '5m' %} + +{%- set ports2cable = { + 'torrouter_server' : '300m', + 'leafrouter_torrouter' : '300m', + 'spinerouter_leafrouter' : '300m' + } +-%} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "10875072", + "type": "ingress", + "mode": "dynamic", + "xoff": "4194112" + }, + "egress_lossy_pool": { + "size": "9243812", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "15982720", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"15982720" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/buffers_defaults_t1.j2 b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..3c93fb8fe2e3 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/buffers_defaults_t1.j2 @@ -0,0 +1,54 @@ + +{%- set default_cable = '40m' %} + +{%- set ports2cable = { + 'torrouter_server' : '300m', + 'leafrouter_torrouter' : '300m', + 'spinerouter_leafrouter' : '300m' + } +-%} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "10875072", + "type": "ingress", + "mode": "dynamic", + "xoff": "4194112" + }, + "egress_lossy_pool": { + "size": "9243812", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "15982720", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"15982720" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} 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 new file mode 100644 index 000000000000..aedda37a8878 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1248 2288 35776 -3 2288 + 25000 5m 1248 2288 53248 -3 2288 + 40000 5m 1248 2288 66560 -3 2288 + 50000 5m 1248 2288 90272 -3 2288 + 100000 5m 1248 2288 165568 -3 2288 + 10000 40m 1248 2288 37024 -3 2288 + 25000 40m 1248 2288 53248 -3 2288 + 40000 40m 1248 2288 71552 -3 2288 + 50000 40m 1248 2288 96096 -3 2288 + 100000 40m 1248 2288 177632 -3 2288 + 10000 300m 1248 2288 46176 -3 2288 + 25000 300m 1248 2288 79040 -3 2288 + 40000 300m 1248 2288 108160 -3 2288 + 50000 300m 1248 2288 141856 -3 2288 + 100000 300m 1248 2288 268736 -3 2288 diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/port_config.ini b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/port_config.ini new file mode 100644 index 000000000000..24e7b3c99858 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias speed index +Ethernet0 65,66,67,68 etp1 100000 1 +Ethernet4 69,70,71,72 etp2 100000 2 +Ethernet8 73,74,75,76 etp3 100000 3 +Ethernet12 77,78,79,80 etp4 100000 4 +Ethernet16 33,34,35,36 etp5 100000 5 +Ethernet20 37,38,39,40 etp6 100000 6 +Ethernet24 41,42,43,44 etp7 100000 7 +Ethernet28 45,46,47,48 etp8 100000 8 +Ethernet32 49,50,51,52 etp9 100000 9 +Ethernet36 53,54,55,56 etp10 100000 10 +Ethernet40 57,58,59,60 etp11 100000 11 +Ethernet44 61,62,63,64 etp12 100000 12 +Ethernet48 81,82,83,84 etp13 100000 13 +Ethernet52 85,86,87,88 etp14 100000 14 +Ethernet56 89,90,91,92 etp15 100000 15 +Ethernet60 93,94,95,96 etp16 100000 16 +Ethernet64 97,98,99,100 etp17 100000 17 +Ethernet68 101,102,103,104 etp18 100000 18 +Ethernet72 105,106,107,108 etp19 100000 19 +Ethernet76 109,110,111,112 etp20 100000 20 +Ethernet80 1,2,3,4 etp21 100000 21 +Ethernet84 5,6,7,8 etp22 100000 22 +Ethernet88 9,10,11,12 etp23 100000 23 +Ethernet92 13,14,15,16 etp24 100000 24 +Ethernet96 17,18,19,20 etp25 100000 25 +Ethernet100 21,22,23,24 etp26 100000 26 +Ethernet104 25,26,27,28 etp27 100000 27 +Ethernet108 29,30,31,32 etp28 100000 28 +Ethernet112 113,114,115,116 etp29 100000 29 +Ethernet116 117,118,119,120 etp30 100000 30 +Ethernet120 121,122,123,124 etp31 100000 31 +Ethernet124 125,126,127,128 etp32 100000 32 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 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/sai.profile.j2 b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/sai.profile.j2 new file mode 100644 index 000000000000..abc2daefd04e --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/sai.profile.j2 @@ -0,0 +1,13 @@ +{# Get sai.profile based on switch_role #} +{%- if DEVICE_METADATA is defined and DEVICE_METADATA['localhost'] is defined and DEVICE_METADATA['localhost']['type'] is defined -%} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] -%} +{%- if switch_role.lower() == 'torrouter' %} +{% set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-seastone-dx010-32x100G-t0.config.bcm' -%} +{%- else %} +{% set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-seastone-dx010-32x100G-t1.config.bcm' -%} +{%- endif %} +{%- else %} +{% set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-seastone-dx010-32x100G-t1.config.bcm' -%} +{%- endif %} +{# Write the contents of sai_ profile_filename to sai.profile file #} +{{ sai_profile_contents }} diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/th-seastone-dx010-32x100G-t0.config.bcm b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/th-seastone-dx010-32x100G-t0.config.bcm new file mode 100644 index 000000000000..7c315460dc8e --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/th-seastone-dx010-32x100G-t0.config.bcm @@ -0,0 +1,376 @@ +# Define default OS / SAL +os=unix + +# all XPORTs to XE ports +#pbmp_xport_xe=0x1fffffffe +pbmp_xport_xe=0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe +pbmp_oversubscribe=0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe + +# Mode control to select L2 Table DMA mode aka L2MODE_POLL (0) or +# L2MOD_FIFO mechanism aka L2MODE_FIFO (1) for L2 table change notification. +l2xmsg_mode=1 + +# Memory table size configs +l2_mem_entries=8192 +l3_mem_entries=8192 +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +mmu_lossless=0 + +################################################################################### +# Celestica Customize for SeaStone +################################################################################### + +#ext mdio frequency to 495/0x80/2(1.933Mhz) or 415/0x80/2(1.62MHz) +# default is 40 +# Set external MDIO freq to 6.19MHz (495MHz) or 5.19MHz (415MHz) +#* target_freq is core_clock_freq * DIVIDEND / DIVISOR / 2 +# +rate_ext_mdio_divisor=0x80 + +# use internal rom boot +phy_ext_rom_boot=0 + +#fpem_mem_entries=32768 +oversubscribe_mode=1 +#pbmp_xport_xe=0x3fd000000ff4000003fc000001fe + + +dport_map_enable=1 + +dport_map_port_68=1 +dport_map_port_72=5 +dport_map_port_76=9 +dport_map_port_80=13 +dport_map_port_34=17 +dport_map_port_38=21 +dport_map_port_42=25 +dport_map_port_46=29 +dport_map_port_50=33 +dport_map_port_54=37 +dport_map_port_58=41 +dport_map_port_62=45 +dport_map_port_84=49 +dport_map_port_88=53 +dport_map_port_92=57 +dport_map_port_96=61 +dport_map_port_102=65 +dport_map_port_106=69 +dport_map_port_110=73 +dport_map_port_114=77 +dport_map_port_1=81 +dport_map_port_5=85 +dport_map_port_9=89 +dport_map_port_13=93 +dport_map_port_17=97 +dport_map_port_21=101 +dport_map_port_25=105 +dport_map_port_29=109 +dport_map_port_118=113 +dport_map_port_122=117 +dport_map_port_126=121 +dport_map_port_130=125 + + +# port mapping +portmap_68=65:100:4 +portmap_72=69:100:4 +portmap_76=73:100:4 +portmap_80=77:100:4 +portmap_34=33:100:4 +portmap_38=37:100:4 +portmap_42=41:100:4 +portmap_46=45:100:4 +portmap_50=49:100:4 +portmap_54=53:100:4 +portmap_58=57:100:4 +portmap_62=61:100:4 +portmap_84=81:100:4 +portmap_88=85:100:4 +portmap_92=89:100:4 +portmap_96=93:100:4 +portmap_102=97:100:4 +portmap_106=101:100:4 +portmap_110=105:100:4 +portmap_114=109:100:4 +portmap_1=1:100:4 +portmap_5=5:100:4 +portmap_9=9:100:4 +portmap_13=13:100:4 +portmap_17=17:100:4 +portmap_21=21:100:4 +portmap_25=25:100:4 +portmap_29=29:100:4 +portmap_118=113:100:4 +portmap_122=117:100:4 +portmap_126=121:100:4 +portmap_130=125:100:4 +#portmap_66=129:10 +#portmap_100=131:10 + +#WC16 +xgxs_tx_lane_map_68=0x3201 +xgxs_rx_lane_map_68=0x2310 + + +#WC17 +xgxs_tx_lane_map_72=0x3201 +xgxs_rx_lane_map_72=0x2301 + +#WC18 +xgxs_tx_lane_map_76=0x0132 +xgxs_rx_lane_map_76=0x0123 + +#WC19 +xgxs_tx_lane_map_80=0x2031 +xgxs_rx_lane_map_80=0x1320 + +#WC8 +xgxs_tx_lane_map_34=0x3021 +xgxs_rx_lane_map_34=0x0213 + +#WC9 +xgxs_tx_lane_map_38=0x3210 +xgxs_rx_lane_map_38=0x1023 + +#WC10 +xgxs_tx_lane_map_42=0x2310 +xgxs_rx_lane_map_42=0x3210 + +#WC11 +xgxs_tx_lane_map_46=0x1032 +xgxs_rx_lane_map_46=0x1302 + +#WC12 +xgxs_tx_lane_map_50=0x3201 +xgxs_rx_lane_map_50=0x0213 + + +#WC13 +xgxs_tx_lane_map_54=0x2301 +xgxs_rx_lane_map_54=0x2310 + +#WC14 +xgxs_tx_lane_map_58=0x3201 +xgxs_rx_lane_map_58=0x0213 + +#WC15 +xgxs_tx_lane_map_62=0x1302 +xgxs_rx_lane_map_62=0x2310 + +#WC20 +xgxs_tx_lane_map_84=0x0213 +xgxs_rx_lane_map_84=0x2301 + +#WC21 +xgxs_tx_lane_map_88=0x0132 +xgxs_rx_lane_map_88=0x3210 + +#WC22 +xgxs_tx_lane_map_92=0x0132 +xgxs_rx_lane_map_92=0x2031 + +#WC23 +xgxs_tx_lane_map_96=0x2031 +xgxs_rx_lane_map_96=0x3201 + +#WC24 +xgxs_tx_lane_map_102=0x0132 +xgxs_rx_lane_map_102=0x2301 + +#WC25 +xgxs_tx_lane_map_106=0x0132 +xgxs_rx_lane_map_106=0x3201 + +#WC26 +xgxs_tx_lane_map_110=0x0132 +xgxs_rx_lane_map_110=0x2031 + +#WC27 +xgxs_tx_lane_map_114=0x2031 +xgxs_rx_lane_map_114=0x2301 + + +#WC0 +xgxs_tx_lane_map_1=0x3210 +xgxs_rx_lane_map_1=0x3120 + +#WC1 +xgxs_tx_lane_map_5=0x0132 +xgxs_rx_lane_map_5=0x1023 + +#WC2 +xgxs_tx_lane_map_9=0x3201 +xgxs_rx_lane_map_9=0x3120 + +#WC3 +xgxs_tx_lane_map_13=0x2031 +xgxs_rx_lane_map_13=0x1032 + +#WC4 +xgxs_tx_lane_map_17=0x2310 +xgxs_rx_lane_map_17=0x3210 + +#WC5 +xgxs_tx_lane_map_21=0x2301 +xgxs_rx_lane_map_21=0x3120 + +#WC6 +xgxs_tx_lane_map_25=0x3201 +xgxs_rx_lane_map_25=0x0213 + +#WC7 +xgxs_tx_lane_map_29=0x1302 +xgxs_rx_lane_map_29=0x1023 + +#WC28 +xgxs_tx_lane_map_118=0x1320 +xgxs_rx_lane_map_118=0x1302 + +#WC29 +xgxs_tx_lane_map_122=0x1032 +xgxs_rx_lane_map_122=0x1023 + +#WC30 +xgxs_tx_lane_map_126=0x3120 +xgxs_rx_lane_map_126=0x3120 + +#WC31 +xgxs_tx_lane_map_130=0x1302 +xgxs_rx_lane_map_130=0x2310 + +#PN + +#WC16 +phy_xaui_tx_polarity_flip_68=0x0000 +phy_xaui_rx_polarity_flip_68=0x0000 + +#WC17 +phy_xaui_tx_polarity_flip_72=0x000D +phy_xaui_rx_polarity_flip_72=0x0002 + + +#WC18 +phy_xaui_tx_polarity_flip_76=0x000F +phy_xaui_rx_polarity_flip_76=0x0000 + +#WC19 +phy_xaui_tx_polarity_flip_80=0x000F +phy_xaui_rx_polarity_flip_80=0x000F + + +#WC8 +phy_xaui_tx_polarity_flip_34=0x000E +phy_xaui_rx_polarity_flip_34=0x0000 + +#WC9 +phy_xaui_tx_polarity_flip_38=0x0008 +phy_xaui_rx_polarity_flip_38=0x0000 + +#WC10 +phy_xaui_tx_polarity_flip_42=0x000D +phy_xaui_rx_polarity_flip_42=0x0000 + +#WC11 +phy_xaui_tx_polarity_flip_46=0x0000 +phy_xaui_rx_polarity_flip_46=0x0000 + + +#WC12 +phy_xaui_tx_polarity_flip_50=0x0002 +phy_xaui_rx_polarity_flip_50=0x0000 + +#WC13 +phy_xaui_tx_polarity_flip_54=0x0002 +phy_xaui_rx_polarity_flip_54=0x0000 + +#WC14 +phy_xaui_tx_polarity_flip_58=0x0000 +phy_xaui_rx_polarity_flip_58=0x0000 + +#WC15 +phy_xaui_tx_polarity_flip_62=0x000A +phy_xaui_rx_polarity_flip_62=0x000F + + +#WC20 + phy_xaui_tx_polarity_flip_84=0x0007 + phy_xaui_rx_polarity_flip_84=0x000E + +#WC21 +phy_xaui_tx_polarity_flip_88=0x000D +phy_xaui_rx_polarity_flip_88=0x000D + +#WC22 +phy_xaui_tx_polarity_flip_92=0x000F +phy_xaui_rx_polarity_flip_92=0x0008 + +#WC23 +phy_xaui_tx_polarity_flip_96=0x0005 +phy_xaui_rx_polarity_flip_96=0x0000 + +#WC24 +phy_xaui_tx_polarity_flip_102=0x0000 +phy_xaui_rx_polarity_flip_102=0x000F + +#WC25 +phy_xaui_tx_polarity_flip_106=0x000F +phy_xaui_rx_polarity_flip_106=0x0000 + +#WC26 +phy_xaui_tx_polarity_flip_110=0x000F +phy_xaui_rx_polarity_flip_110=0x000F + +#WC27 +phy_xaui_tx_polarity_flip_114=0x000F +phy_xaui_rx_polarity_flip_114=0x0007 + +#WC0 +phy_xaui_tx_polarity_flip_1=0x0003 +phy_xaui_rx_polarity_flip_1=0x000F + +#WC1 +phy_xaui_tx_polarity_flip_5=0x0007 +phy_xaui_rx_polarity_flip_5=0x0000 + +#WC2 +phy_xaui_tx_polarity_flip_9=0x0002 +phy_xaui_rx_polarity_flip_9=0x0008 + +#WC3 +phy_xaui_tx_polarity_flip_13=0x000F +phy_xaui_rx_polarity_flip_13=0x0000 + +#WC4 +phy_xaui_tx_polarity_flip_17=0x0007 +phy_xaui_rx_polarity_flip_17=0x0000 + +#WC5 +phy_xaui_tx_polarity_flip_21=0x0000 +phy_xaui_rx_polarity_flip_21=0x0000 + +#WC6 +phy_xaui_tx_polarity_flip_25=0x0002 +phy_xaui_rx_polarity_flip_25=0x0005 + +#WC7 +phy_xaui_tx_polarity_flip_29=0x0002 +phy_xaui_rx_polarity_flip_29=0x0000 + +#WC28 +phy_xaui_tx_polarity_flip_118=0x000F +phy_xaui_rx_polarity_flip_118=0x000F + +#WC29 +phy_xaui_tx_polarity_flip_122=0x0004 +phy_xaui_rx_polarity_flip_122=0x0000 + +#WC30 +phy_xaui_tx_polarity_flip_126=0x000F +phy_xaui_rx_polarity_flip_126=0x0000 + +#WC31 +phy_xaui_tx_polarity_flip_130=0x0006 +phy_xaui_rx_polarity_flip_130=0x0000 + +mmu_init_config="MSFT-TH-Tier0" diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/th-seastone-dx010-32x100G-t1.config.bcm b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/th-seastone-dx010-32x100G-t1.config.bcm new file mode 100644 index 000000000000..effdfb5d7570 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-C32/th-seastone-dx010-32x100G-t1.config.bcm @@ -0,0 +1,696 @@ +# Define default OS / SAL +os=unix + +# all XPORTs to XE ports +#pbmp_xport_xe=0x1fffffffe +pbmp_xport_xe=0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe +pbmp_oversubscribe=0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe + +# Mode control to select L2 Table DMA mode aka L2MODE_POLL (0) or +# L2MOD_FIFO mechanism aka L2MODE_FIFO (1) for L2 table change notification. +l2xmsg_mode=1 + +# Memory table size configs +l2_mem_entries=8192 +l3_mem_entries=8192 +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +mmu_lossless=0 + +################################################################################### +# Celestica Customize for SeaStone +################################################################################### + +#ext mdio frequency to 495/0x80/2(1.933Mhz) or 415/0x80/2(1.62MHz) +# default is 40 +# Set external MDIO freq to 6.19MHz (495MHz) or 5.19MHz (415MHz) +#* target_freq is core_clock_freq * DIVIDEND / DIVISOR / 2 +# +rate_ext_mdio_divisor=0x80 + +# use internal rom boot +phy_ext_rom_boot=0 + +#fpem_mem_entries=32768 +oversubscribe_mode=1 +#pbmp_xport_xe=0x3fd000000ff4000003fc000001fe + + +dport_map_enable=1 + +dport_map_port_68=1 +dport_map_port_72=5 +dport_map_port_76=9 +dport_map_port_80=13 +dport_map_port_34=17 +dport_map_port_38=21 +dport_map_port_42=25 +dport_map_port_46=29 +dport_map_port_50=33 +dport_map_port_54=37 +dport_map_port_58=41 +dport_map_port_62=45 +dport_map_port_84=49 +dport_map_port_88=53 +dport_map_port_92=57 +dport_map_port_96=61 +dport_map_port_102=65 +dport_map_port_106=69 +dport_map_port_110=73 +dport_map_port_114=77 +dport_map_port_1=81 +dport_map_port_5=85 +dport_map_port_9=89 +dport_map_port_13=93 +dport_map_port_17=97 +dport_map_port_21=101 +dport_map_port_25=105 +dport_map_port_29=109 +dport_map_port_118=113 +dport_map_port_122=117 +dport_map_port_126=121 +dport_map_port_130=125 + + +# port mapping +portmap_68=65:100:4 +portmap_72=69:100:4 +portmap_76=73:100:4 +portmap_80=77:100:4 +portmap_34=33:100:4 +portmap_38=37:100:4 +portmap_42=41:100:4 +portmap_46=45:100:4 +portmap_50=49:100:4 +portmap_54=53:100:4 +portmap_58=57:100:4 +portmap_62=61:100:4 +portmap_84=81:100:4 +portmap_88=85:100:4 +portmap_92=89:100:4 +portmap_96=93:100:4 +portmap_102=97:100:4 +portmap_106=101:100:4 +portmap_110=105:100:4 +portmap_114=109:100:4 +portmap_1=1:100:4 +portmap_5=5:100:4 +portmap_9=9:100:4 +portmap_13=13:100:4 +portmap_17=17:100:4 +portmap_21=21:100:4 +portmap_25=25:100:4 +portmap_29=29:100:4 +portmap_118=113:100:4 +portmap_122=117:100:4 +portmap_126=121:100:4 +portmap_130=125:100:4 +#portmap_66=129:10 +#portmap_100=131:10 + +#WC16 +xgxs_tx_lane_map_68=0x3201 +xgxs_rx_lane_map_68=0x2310 + + +#WC17 +xgxs_tx_lane_map_72=0x3201 +xgxs_rx_lane_map_72=0x2301 + +#WC18 +xgxs_tx_lane_map_76=0x0132 +xgxs_rx_lane_map_76=0x0123 + +#WC19 +xgxs_tx_lane_map_80=0x2031 +xgxs_rx_lane_map_80=0x1320 + +#WC8 +xgxs_tx_lane_map_34=0x3021 +xgxs_rx_lane_map_34=0x0213 + +#WC9 +xgxs_tx_lane_map_38=0x3210 +xgxs_rx_lane_map_38=0x1023 + +#WC10 +xgxs_tx_lane_map_42=0x2310 +xgxs_rx_lane_map_42=0x3210 + +#WC11 +xgxs_tx_lane_map_46=0x1032 +xgxs_rx_lane_map_46=0x1302 + +#WC12 +xgxs_tx_lane_map_50=0x3201 +xgxs_rx_lane_map_50=0x0213 + + +#WC13 +xgxs_tx_lane_map_54=0x2301 +xgxs_rx_lane_map_54=0x2310 + +#WC14 +xgxs_tx_lane_map_58=0x3201 +xgxs_rx_lane_map_58=0x0213 + +#WC15 +xgxs_tx_lane_map_62=0x1302 +xgxs_rx_lane_map_62=0x2310 + +#WC20 +xgxs_tx_lane_map_84=0x0213 +xgxs_rx_lane_map_84=0x2301 + +#WC21 +xgxs_tx_lane_map_88=0x0132 +xgxs_rx_lane_map_88=0x3210 + +#WC22 +xgxs_tx_lane_map_92=0x0132 +xgxs_rx_lane_map_92=0x2031 + +#WC23 +xgxs_tx_lane_map_96=0x2031 +xgxs_rx_lane_map_96=0x3201 + +#WC24 +xgxs_tx_lane_map_102=0x0132 +xgxs_rx_lane_map_102=0x2301 + +#WC25 +xgxs_tx_lane_map_106=0x0132 +xgxs_rx_lane_map_106=0x3201 + +#WC26 +xgxs_tx_lane_map_110=0x0132 +xgxs_rx_lane_map_110=0x2031 + +#WC27 +xgxs_tx_lane_map_114=0x2031 +xgxs_rx_lane_map_114=0x2301 + + +#WC0 +xgxs_tx_lane_map_1=0x3210 +xgxs_rx_lane_map_1=0x3120 + +#WC1 +xgxs_tx_lane_map_5=0x0132 +xgxs_rx_lane_map_5=0x1023 + +#WC2 +xgxs_tx_lane_map_9=0x3201 +xgxs_rx_lane_map_9=0x3120 + +#WC3 +xgxs_tx_lane_map_13=0x2031 +xgxs_rx_lane_map_13=0x1032 + +#WC4 +xgxs_tx_lane_map_17=0x2310 +xgxs_rx_lane_map_17=0x3210 + +#WC5 +xgxs_tx_lane_map_21=0x2301 +xgxs_rx_lane_map_21=0x3120 + +#WC6 +xgxs_tx_lane_map_25=0x3201 +xgxs_rx_lane_map_25=0x0213 + +#WC7 +xgxs_tx_lane_map_29=0x1302 +xgxs_rx_lane_map_29=0x1023 + +#WC28 +xgxs_tx_lane_map_118=0x1320 +xgxs_rx_lane_map_118=0x1302 + +#WC29 +xgxs_tx_lane_map_122=0x1032 +xgxs_rx_lane_map_122=0x1023 + +#WC30 +xgxs_tx_lane_map_126=0x3120 +xgxs_rx_lane_map_126=0x3120 + +#WC31 +xgxs_tx_lane_map_130=0x1302 +xgxs_rx_lane_map_130=0x2310 + +#PN + +#WC16 +phy_xaui_tx_polarity_flip_68=0x0000 +phy_xaui_rx_polarity_flip_68=0x0000 + +#WC17 +phy_xaui_tx_polarity_flip_72=0x000D +phy_xaui_rx_polarity_flip_72=0x0002 + + +#WC18 +phy_xaui_tx_polarity_flip_76=0x000F +phy_xaui_rx_polarity_flip_76=0x0000 + +#WC19 +phy_xaui_tx_polarity_flip_80=0x000F +phy_xaui_rx_polarity_flip_80=0x000F + + +#WC8 +phy_xaui_tx_polarity_flip_34=0x000E +phy_xaui_rx_polarity_flip_34=0x0000 + +#WC9 +phy_xaui_tx_polarity_flip_38=0x0008 +phy_xaui_rx_polarity_flip_38=0x0000 + +#WC10 +phy_xaui_tx_polarity_flip_42=0x000D +phy_xaui_rx_polarity_flip_42=0x0000 + +#WC11 +phy_xaui_tx_polarity_flip_46=0x0000 +phy_xaui_rx_polarity_flip_46=0x0000 + + +#WC12 +phy_xaui_tx_polarity_flip_50=0x0002 +phy_xaui_rx_polarity_flip_50=0x0000 + +#WC13 +phy_xaui_tx_polarity_flip_54=0x0002 +phy_xaui_rx_polarity_flip_54=0x0000 + +#WC14 +phy_xaui_tx_polarity_flip_58=0x0000 +phy_xaui_rx_polarity_flip_58=0x0000 + +#WC15 +phy_xaui_tx_polarity_flip_62=0x000A +phy_xaui_rx_polarity_flip_62=0x000F + + +#WC20 + phy_xaui_tx_polarity_flip_84=0x0007 + phy_xaui_rx_polarity_flip_84=0x000E + +#WC21 +phy_xaui_tx_polarity_flip_88=0x000D +phy_xaui_rx_polarity_flip_88=0x000D + +#WC22 +phy_xaui_tx_polarity_flip_92=0x000F +phy_xaui_rx_polarity_flip_92=0x0008 + +#WC23 +phy_xaui_tx_polarity_flip_96=0x0005 +phy_xaui_rx_polarity_flip_96=0x0000 + +#WC24 +phy_xaui_tx_polarity_flip_102=0x0000 +phy_xaui_rx_polarity_flip_102=0x000F + +#WC25 +phy_xaui_tx_polarity_flip_106=0x000F +phy_xaui_rx_polarity_flip_106=0x0000 + +#WC26 +phy_xaui_tx_polarity_flip_110=0x000F +phy_xaui_rx_polarity_flip_110=0x000F + +#WC27 +phy_xaui_tx_polarity_flip_114=0x000F +phy_xaui_rx_polarity_flip_114=0x0007 + +#WC0 +phy_xaui_tx_polarity_flip_1=0x0003 +phy_xaui_rx_polarity_flip_1=0x000F + +#WC1 +phy_xaui_tx_polarity_flip_5=0x0007 +phy_xaui_rx_polarity_flip_5=0x0000 + +#WC2 +phy_xaui_tx_polarity_flip_9=0x0002 +phy_xaui_rx_polarity_flip_9=0x0008 + +#WC3 +phy_xaui_tx_polarity_flip_13=0x000F +phy_xaui_rx_polarity_flip_13=0x0000 + +#WC4 +phy_xaui_tx_polarity_flip_17=0x0007 +phy_xaui_rx_polarity_flip_17=0x0000 + +#WC5 +phy_xaui_tx_polarity_flip_21=0x0000 +phy_xaui_rx_polarity_flip_21=0x0000 + +#WC6 +phy_xaui_tx_polarity_flip_25=0x0002 +phy_xaui_rx_polarity_flip_25=0x0005 + +#WC7 +phy_xaui_tx_polarity_flip_29=0x0002 +phy_xaui_rx_polarity_flip_29=0x0000 + +#WC28 +phy_xaui_tx_polarity_flip_118=0x000F +phy_xaui_rx_polarity_flip_118=0x000F + +#WC29 +phy_xaui_tx_polarity_flip_122=0x0004 +phy_xaui_rx_polarity_flip_122=0x0000 + +#WC30 +phy_xaui_tx_polarity_flip_126=0x000F +phy_xaui_rx_polarity_flip_126=0x0000 + +#WC31 +phy_xaui_tx_polarity_flip_130=0x0006 +phy_xaui_rx_polarity_flip_130=0x0000 + +#ce0 +serdes_driver_current_lane0_68=0x0b +serdes_driver_current_lane1_68=0x0b +serdes_driver_current_lane2_68=0x0b +serdes_driver_current_lane3_68=0x0b +serdes_preemphasis_lane0_68=0x2d3f04 +serdes_preemphasis_lane1_68=0x2b4104 +serdes_preemphasis_lane2_68=0x2b4104 +serdes_preemphasis_lane3_68=0x2d3f04 + +#ce1 +serdes_driver_current_lane0_72=0x0b +serdes_driver_current_lane1_72=0x0a +serdes_driver_current_lane2_72=0x0a +serdes_driver_current_lane3_72=0x0b +serdes_preemphasis_lane0_72=0x2b4104 +serdes_preemphasis_lane1_72=0x294403 +serdes_preemphasis_lane2_72=0x294403 +serdes_preemphasis_lane3_72=0x2b4104 + +#ce2 +serdes_driver_current_lane0_76=0x0a +serdes_driver_current_lane1_76=0x0a +serdes_driver_current_lane2_76=0x0a +serdes_driver_current_lane3_76=0x0a +serdes_preemphasis_lane0_76=0x294403 +serdes_preemphasis_lane1_76=0x294403 +serdes_preemphasis_lane2_76=0x294403 +serdes_preemphasis_lane3_76=0x294403 + +#ce3 +serdes_driver_current_lane0_80=0x0a +serdes_driver_current_lane1_80=0x0a +serdes_driver_current_lane2_80=0x0a +serdes_driver_current_lane3_80=0x0a +serdes_preemphasis_lane0_80=0x254902 +serdes_preemphasis_lane1_80=0x254902 +serdes_preemphasis_lane2_80=0x294403 +serdes_preemphasis_lane3_80=0x294403 + +#ce4 +serdes_driver_current_lane0_34=0x0b +serdes_driver_current_lane1_34=0x0b +serdes_driver_current_lane2_34=0x0b +serdes_driver_current_lane3_34=0x0b +serdes_preemphasis_lane0_34=0x2b4104 +serdes_preemphasis_lane1_34=0x2d3f04 +serdes_preemphasis_lane2_34=0x2d3f04 +serdes_preemphasis_lane3_34=0x2b4104 + +#ce5 +serdes_driver_current_lane0_38=0x0a +serdes_driver_current_lane1_38=0x0b +serdes_driver_current_lane2_38=0x0b +serdes_driver_current_lane3_38=0x0b +serdes_preemphasis_lane0_38=0x294403 +serdes_preemphasis_lane1_38=0x2b4104 +serdes_preemphasis_lane2_38=0x2b4104 +serdes_preemphasis_lane3_38=0x2b4104 + +#ce6 +serdes_driver_current_lane0_42=0x0a +serdes_driver_current_lane1_42=0x0b +serdes_driver_current_lane2_42=0x0a +serdes_driver_current_lane3_42=0x0a +serdes_preemphasis_lane0_42=0x294403 +serdes_preemphasis_lane1_42=0x2b4104 +serdes_preemphasis_lane2_42=0x294403 +serdes_preemphasis_lane3_42=0x294403 + +#ce7 +serdes_driver_current_lane0_46=0x0a +serdes_driver_current_lane1_46=0x0a +serdes_driver_current_lane2_46=0x0a +serdes_driver_current_lane3_46=0x0a +serdes_preemphasis_lane0_46=0x254902 +serdes_preemphasis_lane1_46=0x294403 +serdes_preemphasis_lane2_46=0x254902 +serdes_preemphasis_lane3_46=0x294403 + +#ce8 +serdes_driver_current_lane0_50=0x0a +serdes_driver_current_lane1_50=0x0a +serdes_driver_current_lane2_50=0x0a +serdes_driver_current_lane3_50=0x0a +serdes_preemphasis_lane0_50=0x294403 +serdes_preemphasis_lane1_50=0x254902 +serdes_preemphasis_lane2_50=0x254902 +serdes_preemphasis_lane3_50=0x254902 + +#ce9 +serdes_driver_current_lane0_54=0x0a +serdes_driver_current_lane1_54=0x09 +serdes_driver_current_lane2_54=0x0a +serdes_driver_current_lane3_54=0x09 +serdes_preemphasis_lane0_54=0x254902 +serdes_preemphasis_lane1_54=0x244a02 +serdes_preemphasis_lane2_54=0x254902 +serdes_preemphasis_lane3_54=0x244a02 + +#ce10 +serdes_driver_current_lane0_58=0x0a +serdes_driver_current_lane1_58=0x09 +serdes_driver_current_lane2_58=0x09 +serdes_driver_current_lane3_58=0x0a +serdes_preemphasis_lane0_58=0x254902 +serdes_preemphasis_lane1_58=0x244a02 +serdes_preemphasis_lane2_58=0x244a02 +serdes_preemphasis_lane3_58=0x254902 + +#ce11 +serdes_driver_current_lane0_62=0x09 +serdes_driver_current_lane1_62=0x0a +serdes_driver_current_lane2_62=0x09 +serdes_driver_current_lane3_62=0x09 +serdes_preemphasis_lane0_62=0x244a02 +serdes_preemphasis_lane1_62=0x254902 +serdes_preemphasis_lane2_62=0x244a02 +serdes_preemphasis_lane3_62=0x244a02 + +#ce12 +serdes_driver_current_lane0_84=0x09 +serdes_driver_current_lane1_84=0x09 +serdes_driver_current_lane2_84=0x09 +serdes_driver_current_lane3_84=0x09 +serdes_preemphasis_lane0_84=0x204e02 +serdes_preemphasis_lane1_84=0x204e02 +serdes_preemphasis_lane2_84=0x204e02 +serdes_preemphasis_lane3_84=0x204e02 + +#ce13 +serdes_driver_current_lane0_88=0x09 +serdes_driver_current_lane1_88=0x08 +serdes_driver_current_lane2_88=0x08 +serdes_driver_current_lane3_88=0x09 +serdes_preemphasis_lane0_88=0x204e02 +serdes_preemphasis_lane1_88=0x1d5102 +serdes_preemphasis_lane2_88=0x1d5102 +serdes_preemphasis_lane3_88=0x204e02 + +#ce14 +serdes_driver_current_lane0_92=0x09 +serdes_driver_current_lane1_92=0x08 +serdes_driver_current_lane2_92=0x08 +serdes_driver_current_lane3_92=0x09 +serdes_preemphasis_lane0_92=0x204e02 +serdes_preemphasis_lane1_92=0x1d5102 +serdes_preemphasis_lane2_92=0x1d5102 +serdes_preemphasis_lane3_92=0x204e02 + +#ce15 +serdes_driver_current_lane0_96=0x08 +serdes_driver_current_lane1_96=0x08 +serdes_driver_current_lane2_96=0x09 +serdes_driver_current_lane3_96=0x09 +serdes_preemphasis_lane0_96=0x1d5102 +serdes_preemphasis_lane1_96=0x1d5102 +serdes_preemphasis_lane2_96=0x204e02 +serdes_preemphasis_lane3_96=0x204e02 + +#ce16 +serdes_driver_current_lane0_102=0x09 +serdes_driver_current_lane1_102=0x08 +serdes_driver_current_lane2_102=0x08 +serdes_driver_current_lane3_102=0x09 +serdes_preemphasis_lane0_102=0x204e02 +serdes_preemphasis_lane1_102=0x1d5102 +serdes_preemphasis_lane2_102=0x1d5102 +serdes_preemphasis_lane3_102=0x224c02 + +#ce17 +serdes_driver_current_lane0_106=0x09 +serdes_driver_current_lane1_106=0x08 +serdes_driver_current_lane2_106=0x08 +serdes_driver_current_lane3_106=0x09 +serdes_preemphasis_lane0_106=0x204e02 +serdes_preemphasis_lane1_106=0x1d5102 +serdes_preemphasis_lane2_106=0x1d5102 +serdes_preemphasis_lane3_106=0x204e02 + +#ce18 +serdes_driver_current_lane0_110=0x09 +serdes_driver_current_lane1_110=0x08 +serdes_driver_current_lane2_110=0x08 +serdes_driver_current_lane3_110=0x09 +serdes_preemphasis_lane0_110=0x204e02 +serdes_preemphasis_lane1_110=0x1d5102 +serdes_preemphasis_lane2_110=0x1d5102 +serdes_preemphasis_lane3_110=0x204e02 + +#ce19 +serdes_driver_current_lane0_114=0x09 +serdes_driver_current_lane1_114=0x08 +serdes_driver_current_lane2_114=0x09 +serdes_driver_current_lane3_114=0x09 +serdes_preemphasis_lane0_114=0x204e02 +serdes_preemphasis_lane1_114=0x1d5102 +serdes_preemphasis_lane2_114=0x224c02 +serdes_preemphasis_lane3_114=0x224c02 + +#ce20 +serdes_driver_current_lane0_1=0x09 +serdes_driver_current_lane1_1=0x0a +serdes_driver_current_lane2_1=0x09 +serdes_driver_current_lane3_1=0x0a +serdes_preemphasis_lane0_1=0x244a02 +serdes_preemphasis_lane1_1=0x254902 +serdes_preemphasis_lane2_1=0x244a02 +serdes_preemphasis_lane3_1=0x254902 + +#ce21 +serdes_driver_current_lane0_5=0x09 +serdes_driver_current_lane1_5=0x09 +serdes_driver_current_lane2_5=0x09 +serdes_driver_current_lane3_5=0x0a +serdes_preemphasis_lane0_5=0x244a02 +serdes_preemphasis_lane1_5=0x244a02 +serdes_preemphasis_lane2_5=0x244a02 +serdes_preemphasis_lane3_5=0x254902 + +#ce22 +serdes_driver_current_lane0_9=0x0a +serdes_driver_current_lane1_9=0x0a +serdes_driver_current_lane2_9=0x0a +serdes_driver_current_lane3_9=0x0a +serdes_preemphasis_lane0_9=0x254902 +serdes_preemphasis_lane1_9=0x254902 +serdes_preemphasis_lane2_9=0x254902 +serdes_preemphasis_lane3_9=0x294403 + +#ce23 +serdes_driver_current_lane0_13=0x09 +serdes_driver_current_lane1_13=0x0a +serdes_driver_current_lane2_13=0x0a +serdes_driver_current_lane3_13=0x0a +serdes_preemphasis_lane0_13=0x244a02 +serdes_preemphasis_lane1_13=0x254902 +serdes_preemphasis_lane2_13=0x294403 +serdes_preemphasis_lane3_13=0x294403 + +#ce24 +serdes_driver_current_lane0_17=0x0a +serdes_driver_current_lane1_17=0x0a +serdes_driver_current_lane2_17=0x0a +serdes_driver_current_lane3_17=0x0a +serdes_preemphasis_lane0_17=0x254902 +serdes_preemphasis_lane1_17=0x294403 +serdes_preemphasis_lane2_17=0x294403 +serdes_preemphasis_lane3_17=0x294403 + +#ce25 +serdes_driver_current_lane0_21=0x0a +serdes_driver_current_lane1_21=0x0a +serdes_driver_current_lane2_21=0x0a +serdes_driver_current_lane3_21=0x0a +serdes_preemphasis_lane0_21=0x294403 +serdes_preemphasis_lane1_21=0x294403 +serdes_preemphasis_lane2_21=0x294403 +serdes_preemphasis_lane3_21=0x254902 + +#ce26 +serdes_driver_current_lane0_25=0x0b +serdes_driver_current_lane1_25=0x0b +serdes_driver_current_lane2_25=0x0b +serdes_driver_current_lane3_25=0x0b +serdes_preemphasis_lane0_25=0x2b4104 +serdes_preemphasis_lane1_25=0x2b4104 +serdes_preemphasis_lane2_25=0x2b4104 +serdes_preemphasis_lane3_25=0x2d3f04 + +#ce27 +serdes_driver_current_lane0_29=0x0b +serdes_driver_current_lane1_29=0x0b +serdes_driver_current_lane2_29=0x0b +serdes_driver_current_lane3_29=0x0a +serdes_preemphasis_lane0_29=0x2d3f04 +serdes_preemphasis_lane1_29=0x2d3f04 +serdes_preemphasis_lane2_29=0x2b4104 +serdes_preemphasis_lane3_29=0x294403 + +#ce28 +serdes_driver_current_lane0_118=0x0a +serdes_driver_current_lane1_118=0x0a +serdes_driver_current_lane2_118=0x0a +serdes_driver_current_lane3_118=0x0a +serdes_preemphasis_lane0_118=0x254902 +serdes_preemphasis_lane1_118=0x294403 +serdes_preemphasis_lane2_118=0x294403 +serdes_preemphasis_lane3_118=0x254902 + +#ce29 +serdes_driver_current_lane0_122=0x0a +serdes_driver_current_lane1_122=0x0a +serdes_driver_current_lane2_122=0x0a +serdes_driver_current_lane3_122=0x0a +serdes_preemphasis_lane0_122=0x294403 +serdes_preemphasis_lane1_122=0x294403 +serdes_preemphasis_lane2_122=0x294403 +serdes_preemphasis_lane3_122=0x294403 + +#ce30 +serdes_driver_current_lane0_126=0x0a +serdes_driver_current_lane1_126=0x0a +serdes_driver_current_lane2_126=0x0b +serdes_driver_current_lane3_126=0x0b +serdes_preemphasis_lane0_126=0x294403 +serdes_preemphasis_lane1_126=0x294403 +serdes_preemphasis_lane2_126=0x2b4104 +serdes_preemphasis_lane3_126=0x2b4104 + +#ce31 +serdes_driver_current_lane0_130=0x0b +serdes_driver_current_lane1_130=0x0b +serdes_driver_current_lane2_130=0x0b +serdes_driver_current_lane3_130=0x0b +serdes_preemphasis_lane0_130=0x2d3f04 +serdes_preemphasis_lane1_130=0x2d3f04 +serdes_preemphasis_lane2_130=0x2b4104 +serdes_preemphasis_lane3_130=0x2b4104 + +mmu_init_config="MSFT-TH-Tier1" diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/buffers.json.j2 b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/buffers.json.j2 new file mode 100644 index 000000000000..1083a6210fc9 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't0' %} +{%- include 'buffers_config.j2' %} diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/buffers_defaults_t0.j2 b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..4e4489f84a87 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/buffers_defaults_t0.j2 @@ -0,0 +1,69 @@ + +{%- set default_cable = '5m' %} + +{%- set ports2cable = { + 'torrouter_server' : '300m', + 'leafrouter_torrouter' : '300m', + 'spinerouter_leafrouter' : '300m' + } +-%} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,9) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(14,17) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(22,31) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(10,13) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(18,21) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "10875072", + "type": "ingress", + "mode": "dynamic", + "xoff": "4194112" + }, + "egress_lossy_pool": { + "size": "9243812", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "15982720", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"15982720" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} 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 new file mode 100644 index 000000000000..aedda37a8878 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1248 2288 35776 -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/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/port_config.ini b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/port_config.ini new file mode 100644 index 000000000000..7595dfbb3fed --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias speed index +Ethernet0 65,66 etp1a 50000 1 +Ethernet2 67,68 etp1b 50000 1 +Ethernet4 69,70 etp2a 50000 2 +Ethernet6 71,72 etp2b 50000 2 +Ethernet8 73,74 etp3a 50000 3 +Ethernet10 75,76 etp3b 50000 3 +Ethernet12 77,78 etp4a 50000 4 +Ethernet14 79,80 etp4b 50000 4 +Ethernet16 33,34 etp5a 50000 5 +Ethernet18 35,36 etp5b 50000 5 +Ethernet20 37,38 etp6a 50000 6 +Ethernet22 39,40 etp6b 50000 6 +Ethernet24 41,42 etp7a 50000 7 +Ethernet26 43,44 etp7b 50000 7 +Ethernet28 45,46 etp8a 50000 8 +Ethernet30 47,48 etp8b 50000 8 +Ethernet32 49,50 etp9a 50000 9 +Ethernet34 51,52 etp9b 50000 9 +Ethernet36 53,54 etp10a 50000 10 +Ethernet38 55,56 etp10b 50000 10 +Ethernet40 57,58,59,60 etp11 100000 11 +Ethernet44 61,62,63,64 etp12 100000 12 +Ethernet48 81,82,83,84 etp13 100000 13 +Ethernet52 85,86,87,88 etp14 100000 14 +Ethernet56 89,90 etp15a 50000 15 +Ethernet58 91,92 etp15b 50000 15 +Ethernet60 93,94 etp16a 50000 16 +Ethernet62 95,96 etp16b 50000 16 +Ethernet64 97,98 etp17a 50000 17 +Ethernet66 99,100 etp17b 50000 17 +Ethernet68 101,102 etp18a 50000 18 +Ethernet70 103,104 etp18b 50000 18 +Ethernet72 105,106,107,108 etp19 100000 19 +Ethernet76 109,110,111,112 etp20 100000 20 +Ethernet80 1,2,3,4 etp21 100000 21 +Ethernet84 5,6,7,8 etp22 100000 22 +Ethernet88 9,10 etp23a 50000 23 +Ethernet90 11,12 etp23b 50000 23 +Ethernet92 13,14 etp24a 50000 24 +Ethernet94 15,16 etp24b 50000 24 +Ethernet96 17,18 etp25a 50000 25 +Ethernet98 19,20 etp25b 50000 25 +Ethernet100 21,22 etp26a 50000 26 +Ethernet102 23,24 etp26b 50000 26 +Ethernet104 25,26 etp27a 50000 27 +Ethernet106 27,28 etp27b 50000 27 +Ethernet108 29,30 etp28a 50000 28 +Ethernet110 31,32 etp28b 50000 28 +Ethernet112 113,114 etp29a 50000 29 +Ethernet114 115,116 etp29b 50000 29 +Ethernet116 117,118 etp30a 50000 30 +Ethernet118 119,120 etp30b 50000 30 +Ethernet120 121,122 etp31a 50000 31 +Ethernet122 123,124 etp31b 50000 31 +Ethernet124 125,126 etp32a 50000 32 +Ethernet126 127,128 etp32b 50000 32 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 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/sai.profile b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/sai.profile new file mode 100644 index 000000000000..46d96b2fd905 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-seastone-dx010-48x50G+8x100G.config.bcm diff --git a/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/th-seastone-dx010-48x50G+8x100G.config.bcm b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/th-seastone-dx010-48x50G+8x100G.config.bcm new file mode 100644 index 000000000000..6707aa71df09 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Celestica-DX010-D48C8/th-seastone-dx010-48x50G+8x100G.config.bcm @@ -0,0 +1,648 @@ +os=unix +l2xmsg_mode=1 +parity_enable=0 +rate_ext_mdio_divisor=0x80 +phy_ext_rom_boot=0 +fpem_mem_entries=32768 +l2xmsg_mode=1 +oversubscribe_mode=1 +pbmp_xport_xe=0xcccc44cc33113333044cccccc66666622 + + +dport_map_enable=1 +dport_map_port_68=1 +dport_map_port_69=2 + +dport_map_port_72=5 +dport_map_port_73=6 + +dport_map_port_76=9 +dport_map_port_77=10 + +dport_map_port_80=13 +dport_map_port_81=14 + +dport_map_port_34=17 +dport_map_port_35=18 + +dport_map_port_38=21 +dport_map_port_39=22 + +dport_map_port_42=25 +dport_map_port_43=26 + +dport_map_port_46=29 +dport_map_port_47=30 + +dport_map_port_50=33 +dport_map_port_51=34 + +dport_map_port_54=37 +dport_map_port_55=38 + +dport_map_port_58=41 + +dport_map_port_62=45 + +dport_map_port_84=49 + +dport_map_port_88=53 + +dport_map_port_92=57 +dport_map_port_93=58 + +dport_map_port_96=61 +dport_map_port_97=62 + +dport_map_port_102=65 +dport_map_port_103=66 + +dport_map_port_106=69 +dport_map_port_107=70 + +dport_map_port_110=73 + +dport_map_port_114=77 + +dport_map_port_1=81 + +dport_map_port_5=85 + +dport_map_port_9=89 +dport_map_port_10=90 + +dport_map_port_13=93 +dport_map_port_14=94 + +dport_map_port_17=97 +dport_map_port_18=98 + +dport_map_port_21=101 +dport_map_port_22=102 + +dport_map_port_25=105 +dport_map_port_26=106 + +dport_map_port_29=109 +dport_map_port_30=110 + +dport_map_port_118=113 +dport_map_port_119=114 + +dport_map_port_122=117 +dport_map_port_123=118 + +dport_map_port_126=121 +dport_map_port_127=122 + +dport_map_port_130=125 +dport_map_port_131=126 + + +# port mapping +portmap_68=65:50:2 +portmap_69=67:50:2 + +portmap_72=69:50:2 +portmap_73=71:50:2 + +portmap_76=73:50:2 +portmap_77=75:50:2 + +portmap_80=77:50:2 +portmap_81=79:50:2 + +portmap_34=33:50:2 +portmap_35=35:50:2 + +portmap_38=37:50:2 +portmap_39=39:50:2 + +portmap_42=41:50:2 +portmap_43=43:50:2 + +portmap_46=45:50:2 +portmap_47=47:50:2 + +portmap_50=49:50:2 +portmap_51=51:50:2 + +portmap_54=53:50:2 +portmap_55=55:50:2 + +portmap_58=57:100:4 + +portmap_62=61:100:4 + +portmap_84=81:100:4 + +portmap_88=85:100:4 + +portmap_92=89:50:2 +portmap_93=91:50:2 + +portmap_96=93:50:2 +portmap_97=95:50:2 + +portmap_102=97:50:2 +portmap_103=99:50:2 + +portmap_106=101:50:2 +portmap_107=103:50:2 + +portmap_110=105:100:4 + +portmap_114=109:100:4 + +portmap_1=1:100:4 + +portmap_5=5:100:4 + +portmap_9=9:50:2 +portmap_10=11:50:2 + +portmap_13=13:50:2 +portmap_14=15:50:2 + +portmap_17=17:50:2 +portmap_18=19:50:2 + +portmap_21=21:50:2 +portmap_22=23:50:2 + +portmap_25=25:50:2 +portmap_26=27:50:2 + +portmap_29=29:50:2 +portmap_30=31:50:2 + +portmap_118=113:50:2 +portmap_119=115:50:2 + +portmap_122=117:50:2 +portmap_123=119:50:2 + +portmap_126=121:50:2 +portmap_127=123:50:2 + +portmap_130=125:50:2 +portmap_131=127:50:2 + + +#WC16 +xgxs_tx_lane_map_68=0x1023 +xgxs_rx_lane_map_68=0x0132 +xgxs_tx_lane_map_69=0x1023 +xgxs_rx_lane_map_69=0x0132 + + +#WC17 +xgxs_tx_lane_map_72=0x1023 +xgxs_rx_lane_map_72=0x1032 +xgxs_tx_lane_map_73=0x1023 +xgxs_rx_lane_map_73=0x1032 + +#WC18 +xgxs_tx_lane_map_76=0x2310 +xgxs_rx_lane_map_76=0x3210 +xgxs_tx_lane_map_77=0x2310 +xgxs_rx_lane_map_77=0x3210 + +#WC19 +xgxs_tx_lane_map_80=0x1302 +xgxs_rx_lane_map_80=0x0231 +xgxs_tx_lane_map_81=0x1302 +xgxs_rx_lane_map_81=0x0231 +#WC8 +xgxs_tx_lane_map_34=0x1203 +xgxs_rx_lane_map_34=0x3120 +xgxs_tx_lane_map_35=0x1203 +xgxs_rx_lane_map_35=0x3120 + +#WC9 +xgxs_tx_lane_map_38=0x0123 +xgxs_rx_lane_map_38=0x3201 +xgxs_tx_lane_map_39=0x0123 +xgxs_rx_lane_map_39=0x3201 + +#WC10 +xgxs_tx_lane_map_42=0x0132 +xgxs_rx_lane_map_42=0x0123 +xgxs_tx_lane_map_43=0x0132 +xgxs_rx_lane_map_43=0x0123 + +#WC11 +xgxs_tx_lane_map_46=0x2301 +xgxs_rx_lane_map_46=0x2031 +xgxs_tx_lane_map_47=0x2301 +xgxs_rx_lane_map_47=0x2031 + +#WC12 +xgxs_tx_lane_map_50=0x1032 +xgxs_rx_lane_map_50=0x3120 +xgxs_tx_lane_map_51=0x1032 +xgxs_rx_lane_map_51=0x3120 + + +#WC13 +xgxs_tx_lane_map_54=0x1032 +xgxs_rx_lane_map_54=0x0132 +xgxs_tx_lane_map_55=0x1032 +xgxs_rx_lane_map_55=0x0132 + +#WC14 + xgxs_tx_lane_map_58=0x1032 + xgxs_rx_lane_map_58=0x3120 + +#WC15 +xgxs_tx_lane_map_62=0x2031 +xgxs_rx_lane_map_62=0x0132 + +#WC20 + xgxs_tx_lane_map_84=0x3120 + xgxs_rx_lane_map_84=0x1032 + +#WC21 +xgxs_tx_lane_map_88=0x2310 +xgxs_rx_lane_map_88=0x0123 + +#WC22 +xgxs_tx_lane_map_92=0x2310 +xgxs_rx_lane_map_92=0x1302 +xgxs_tx_lane_map_93=0x2310 +xgxs_rx_lane_map_93=0x1302 + +#WC23 +xgxs_tx_lane_map_96=0x1302 +xgxs_rx_lane_map_96=0x1023 +xgxs_tx_lane_map_97=0x1302 +xgxs_rx_lane_map_97=0x1023 + +#WC24 +xgxs_tx_lane_map_102=0x2310 +xgxs_rx_lane_map_102=0x1032 +xgxs_tx_lane_map_103=0x2310 +xgxs_rx_lane_map_103=0x1032 + +#WC25 +xgxs_tx_lane_map_106=0x2310 +xgxs_rx_lane_map_106=0x1023 +xgxs_tx_lane_map_107=0x2310 +xgxs_rx_lane_map_107=0x1023 + +#WC26 +xgxs_tx_lane_map_110=0x2310 +xgxs_rx_lane_map_110=0x1302 + +#WC27 +xgxs_tx_lane_map_114=0x1302 +xgxs_rx_lane_map_114=0x1032 + +#WC0 +xgxs_tx_lane_map_1=0x0123 +xgxs_rx_lane_map_1=0x0213 + +#WC1 +xgxs_tx_lane_map_5=0x2310 +xgxs_rx_lane_map_5=0x3201 + +#WC2 +xgxs_tx_lane_map_9=0x1023 +xgxs_rx_lane_map_9=0x0213 +xgxs_tx_lane_map_10=0x1023 +xgxs_rx_lane_map_10=0x0213 + +#WC3 +xgxs_tx_lane_map_13=0x1302 +xgxs_rx_lane_map_13=0x3201 +xgxs_tx_lane_map_14=0x1302 +xgxs_rx_lane_map_14=0x3201 + +#WC4 +xgxs_tx_lane_map_17=0x0132 +xgxs_rx_lane_map_17=0x0123 +xgxs_tx_lane_map_18=0x0132 +xgxs_rx_lane_map_18=0x0123 + +#WC5 +xgxs_tx_lane_map_21=0x1032 +xgxs_rx_lane_map_21=0x0213 +xgxs_tx_lane_map_22=0x1032 +xgxs_rx_lane_map_22=0x0213 + +#WC6 +xgxs_tx_lane_map_25=0x1023 +xgxs_rx_lane_map_25=0x3120 +xgxs_tx_lane_map_26=0x1023 +xgxs_rx_lane_map_26=0x3120 + +#WC7 +xgxs_tx_lane_map_29=0x2031 +xgxs_rx_lane_map_29=0x3201 +xgxs_tx_lane_map_30=0x2031 +xgxs_rx_lane_map_30=0x3201 + +#WC28 +xgxs_tx_lane_map_118=0x0231 +xgxs_rx_lane_map_118=0x2031 +xgxs_tx_lane_map_119=0x0231 +xgxs_rx_lane_map_119=0x2031 + +#WC29 +xgxs_tx_lane_map_122=0x3201 +xgxs_rx_lane_map_122=0x2301 +xgxs_tx_lane_map_123=0x3201 +xgxs_rx_lane_map_123=0x2301 + +#WC30 +xgxs_tx_lane_map_126=0x0213 +xgxs_rx_lane_map_126=0x0213 +xgxs_tx_lane_map_127=0x0213 +xgxs_rx_lane_map_127=0x0213 + +#WC31 +xgxs_tx_lane_map_130=0x2031 +xgxs_rx_lane_map_130=0x1032 +xgxs_tx_lane_map_131=0x2031 +xgxs_rx_lane_map_131=0x1032 + +#PN + +#WC16 +phy_xaui_tx_polarity_flip_68=0x0000 +phy_xaui_rx_polarity_flip_68=0x0000 +phy_xaui_tx_polarity_flip_69=0x0000 +phy_xaui_rx_polarity_flip_69=0x0000 + +#WC17 +phy_xaui_tx_polarity_flip_72=0x0003 +phy_xaui_rx_polarity_flip_72=0x0000 +phy_xaui_tx_polarity_flip_73=0x0002 +phy_xaui_rx_polarity_flip_73=0x0001 + + + +#WC18 +phy_xaui_tx_polarity_flip_76=0x0003 +phy_xaui_rx_polarity_flip_76=0x0000 +phy_xaui_tx_polarity_flip_77=0x0003 +phy_xaui_rx_polarity_flip_77=0x0000 + + +#WC19 +phy_xaui_tx_polarity_flip_80=0x0003 +phy_xaui_rx_polarity_flip_80=0x0003 +phy_xaui_tx_polarity_flip_81=0x0003 +phy_xaui_rx_polarity_flip_81=0x0003 + + +#WC8 +phy_xaui_tx_polarity_flip_34=0x0003 +phy_xaui_rx_polarity_flip_34=0x0000 +phy_xaui_tx_polarity_flip_35=0x0001 +phy_xaui_rx_polarity_flip_35=0x0000 + + +#WC9 +phy_xaui_tx_polarity_flip_38=0x0001 +phy_xaui_rx_polarity_flip_38=0x0000 +phy_xaui_tx_polarity_flip_39=0x0000 +phy_xaui_rx_polarity_flip_39=0x0000 + + +#WC10 +phy_xaui_tx_polarity_flip_42=0x0003 +phy_xaui_rx_polarity_flip_42=0x0000 +phy_xaui_tx_polarity_flip_43=0x0002 +phy_xaui_rx_polarity_flip_43=0x0000 + + +#WC11 +phy_xaui_tx_polarity_flip_46=0x0000 +phy_xaui_rx_polarity_flip_46=0x0000 +phy_xaui_tx_polarity_flip_47=0x0000 +phy_xaui_rx_polarity_flip_47=0x0000 + + +#WC12 +phy_xaui_tx_polarity_flip_50=0x0000 +phy_xaui_rx_polarity_flip_50=0x0000 +phy_xaui_tx_polarity_flip_51=0x0001 +phy_xaui_rx_polarity_flip_51=0x0000 + +#WC13 +phy_xaui_tx_polarity_flip_54=0x0000 +phy_xaui_rx_polarity_flip_54=0x0000 +phy_xaui_tx_polarity_flip_55=0x0001 +phy_xaui_rx_polarity_flip_55=0x0000 + +#WC14 +phy_xaui_tx_polarity_flip_58=0x0000 +phy_xaui_rx_polarity_flip_58=0x0000 + +#WC15 +phy_xaui_tx_polarity_flip_62=0x0005 +phy_xaui_rx_polarity_flip_62=0x000F + +#WC20 + phy_xaui_tx_polarity_flip_84=0x000E + phy_xaui_rx_polarity_flip_84=0x0007 + +#WC21 +phy_xaui_tx_polarity_flip_88=0x000B +phy_xaui_rx_polarity_flip_88=0x000B + +#WC22 +phy_xaui_tx_polarity_flip_92=0x0003 +phy_xaui_rx_polarity_flip_92=0x0001 +phy_xaui_tx_polarity_flip_93=0x0003 +phy_xaui_rx_polarity_flip_93=0x0000 + + +#WC23 +phy_xaui_tx_polarity_flip_96=0x0002 +phy_xaui_rx_polarity_flip_96=0x0000 +phy_xaui_tx_polarity_flip_97=0x0002 +phy_xaui_rx_polarity_flip_97=0x0000 + +#WC24 +phy_xaui_tx_polarity_flip_102=0x0000 +phy_xaui_rx_polarity_flip_102=0x0003 +phy_xaui_tx_polarity_flip_103=0x0000 +phy_xaui_rx_polarity_flip_103=0x0003 + + +#WC25 +phy_xaui_tx_polarity_flip_106=0x0003 +phy_xaui_rx_polarity_flip_106=0x0000 +phy_xaui_tx_polarity_flip_107=0x0003 +phy_xaui_rx_polarity_flip_107=0x0000 + +#WC26 +phy_xaui_tx_polarity_flip_110=0x000F +phy_xaui_rx_polarity_flip_110=0x000F + +#WC27 +phy_xaui_tx_polarity_flip_114=0x000F +phy_xaui_rx_polarity_flip_114=0x000E + +#WC0 +phy_xaui_tx_polarity_flip_1=0x000C +phy_xaui_rx_polarity_flip_1=0x000F + +#WC1 +phy_xaui_tx_polarity_flip_5=0x000E +phy_xaui_rx_polarity_flip_5=0x0000 + +#WC2 +phy_xaui_tx_polarity_flip_9=0x0000 +phy_xaui_rx_polarity_flip_9=0x0001 +phy_xaui_tx_polarity_flip_10=0x0001 +phy_xaui_rx_polarity_flip_10=0x0000 + + +#WC3 +phy_xaui_tx_polarity_flip_13=0x0003 +phy_xaui_rx_polarity_flip_13=0x0000 +phy_xaui_tx_polarity_flip_14=0x0003 +phy_xaui_rx_polarity_flip_14=0x0000 + +#WC4 +phy_xaui_tx_polarity_flip_17=0x0002 +phy_xaui_rx_polarity_flip_17=0x0000 +phy_xaui_tx_polarity_flip_18=0x0003 +phy_xaui_rx_polarity_flip_18=0x0000 + + +#WC5 +phy_xaui_tx_polarity_flip_21=0x0000 +phy_xaui_rx_polarity_flip_21=0x0000 +phy_xaui_tx_polarity_flip_22=0x0000 +phy_xaui_rx_polarity_flip_22=0x0000 + + +#WC6 +phy_xaui_tx_polarity_flip_25=0x0000 +phy_xaui_rx_polarity_flip_25=0x0002 +phy_xaui_tx_polarity_flip_26=0x0001 +phy_xaui_rx_polarity_flip_26=0x0002 + + +#WC7 +phy_xaui_tx_polarity_flip_29=0x0000 +phy_xaui_rx_polarity_flip_29=0x0000 +phy_xaui_tx_polarity_flip_30=0x0001 +phy_xaui_rx_polarity_flip_30=0x0000 + + +#WC28 +phy_xaui_tx_polarity_flip_118=0x0003 +phy_xaui_rx_polarity_flip_118=0x0003 +phy_xaui_tx_polarity_flip_119=0x0003 +phy_xaui_rx_polarity_flip_119=0x0003 + + +#WC29 +phy_xaui_tx_polarity_flip_122=0x0002 +phy_xaui_rx_polarity_flip_122=0x0000 +phy_xaui_tx_polarity_flip_123=0x0000 +phy_xaui_rx_polarity_flip_123=0x0000 + + +#WC30 +phy_xaui_tx_polarity_flip_126=0x0003 +phy_xaui_rx_polarity_flip_126=0x0000 +phy_xaui_tx_polarity_flip_127=0x0003 +phy_xaui_rx_polarity_flip_127=0x0000 + + +#WC31 +phy_xaui_tx_polarity_flip_130=0x0002 +phy_xaui_rx_polarity_flip_130=0x0000 +phy_xaui_tx_polarity_flip_131=0x0001 +phy_xaui_rx_polarity_flip_131=0x0000 + +#xe +serdes_driver_current=0x0a +serdes_preemphasis=0x1a5402 + +#ce0 +serdes_driver_current_lane0_58=0x0a +serdes_driver_current_lane1_58=0x09 +serdes_driver_current_lane2_58=0x09 +serdes_driver_current_lane3_58=0x0a +serdes_preemphasis_lane0_58=0x254902 +serdes_preemphasis_lane1_58=0x244a02 +serdes_preemphasis_lane2_58=0x244a02 +serdes_preemphasis_lane3_58=0x254902 + +#ce1 +serdes_driver_current_lane0_62=0x09 +serdes_driver_current_lane1_62=0x0a +serdes_driver_current_lane2_62=0x09 +serdes_driver_current_lane3_62=0x09 +serdes_preemphasis_lane0_62=0x244a02 +serdes_preemphasis_lane1_62=0x254902 +serdes_preemphasis_lane2_62=0x244a02 +serdes_preemphasis_lane3_62=0x244a02 + +#ce2 +serdes_driver_current_lane0_84=0x09 +serdes_driver_current_lane1_84=0x09 +serdes_driver_current_lane2_84=0x09 +serdes_driver_current_lane3_84=0x09 +serdes_preemphasis_lane0_84=0x204e02 +serdes_preemphasis_lane1_84=0x204e02 +serdes_preemphasis_lane2_84=0x204e02 +serdes_preemphasis_lane3_84=0x204e02 + +#ce3 +serdes_driver_current_lane0_88=0x09 +serdes_driver_current_lane1_88=0x08 +serdes_driver_current_lane2_88=0x08 +serdes_driver_current_lane3_88=0x09 +serdes_preemphasis_lane0_88=0x204e02 +serdes_preemphasis_lane1_88=0x1d5102 +serdes_preemphasis_lane2_88=0x1d5102 +serdes_preemphasis_lane3_88=0x204e02 + +#ce4 +serdes_driver_current_lane0_110=0x09 +serdes_driver_current_lane1_110=0x08 +serdes_driver_current_lane2_110=0x08 +serdes_driver_current_lane3_110=0x09 +serdes_preemphasis_lane0_110=0x204e02 +serdes_preemphasis_lane1_110=0x1d5102 +serdes_preemphasis_lane2_110=0x1d5102 +serdes_preemphasis_lane3_110=0x204e02 + +#ce5 +serdes_driver_current_lane0_114=0x09 +serdes_driver_current_lane1_114=0x08 +serdes_driver_current_lane2_114=0x09 +serdes_driver_current_lane3_114=0x09 +serdes_preemphasis_lane0_114=0x204e02 +serdes_preemphasis_lane1_114=0x1d5102 +serdes_preemphasis_lane2_114=0x224c02 +serdes_preemphasis_lane3_114=0x224c02 + +#ce6 +serdes_driver_current_lane0_1=0x09 +serdes_driver_current_lane1_1=0x0a +serdes_driver_current_lane2_1=0x09 +serdes_driver_current_lane3_1=0x0a +serdes_preemphasis_lane0_1=0x244a02 +serdes_preemphasis_lane1_1=0x254902 +serdes_preemphasis_lane2_1=0x244a02 +serdes_preemphasis_lane3_1=0x254902 + +#ce7 +serdes_driver_current_lane0_5=0x09 +serdes_driver_current_lane1_5=0x09 +serdes_driver_current_lane2_5=0x09 +serdes_driver_current_lane3_5=0x0a +serdes_preemphasis_lane0_5=0x244a02 +serdes_preemphasis_lane1_5=0x244a02 +serdes_preemphasis_lane2_5=0x244a02 +serdes_preemphasis_lane3_5=0x254902 + diff --git a/device/celestica/x86_64-cel_seastone-r0/plugins/psuutil.py b/device/celestica/x86_64-cel_seastone-r0/plugins/psuutil.py index 510c03a43ff1..b2764b5b6ae0 100644 --- a/device/celestica/x86_64-cel_seastone-r0/plugins/psuutil.py +++ b/device/celestica/x86_64-cel_seastone-r0/plugins/psuutil.py @@ -12,49 +12,51 @@ raise ImportError(str(e) + "- required module not found") +GPIO_DIR = "/sys/class/gpio" +GPIO_LABEL = "pca9505" +DX010_MAX_PSUS = 2 + + class PsuUtil(PsuBase): """Platform-specific PSUutil class""" def __init__(self): PsuBase.__init__(self) # DX010 PSU pin mapping - self.psu = [ - {'base': self.get_gpio_base()}, - {'abs':27, 'power':22}, - {'abs':28, 'power':25} + self.dx010_psu_gpio = [ + {'base': self.__get_gpio_base()}, + {'prs': 27, 'status': 22}, + {'prs': 28, 'status': 25} ] - def get_gpio_base(self): - sys_gpio_dir = "/sys/class/gpio" - for r in os.listdir(sys_gpio_dir): - if "gpiochip" in r: - return int(r[8:],10) - return 216 #Reserve - - - # Get a psu status and presence - def read_psu_statuses(self, pinnum): - sys_gpio_dir = "/sys/class/gpio" - gpio_base = self.psu[0]['base'] - - gpio_dir = sys_gpio_dir + '/gpio' + str(gpio_base+pinnum) - gpio_file = gpio_dir + "/value" - + def __read_txt_file(self, file_path): try: - with open(gpio_file, 'r') as fd: - retval = fd.read() + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() except IOError: - raise IOError("Unable to open " + gpio_file + "file !") - - retval = retval.rstrip('\r\n') - return retval + pass + return "" + + 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): + return int(r[8:], 10) + return 216 # Reserve + + 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) + return retval.rstrip('\r\n') def get_num_psus(self): """ Retrieves the number of PSUs available on the device :return: An integer, the number of PSUs available on the device """ - DX010_MAX_PSUS = 2 return DX010_MAX_PSUS def get_psu_status(self, index): @@ -65,14 +67,9 @@ def get_psu_status(self, index): :return: Boolean, True if PSU is operating properly, False if PSU is\ faulty """ - status = 0 - psu_status = self.read_psu_statuses(self.psu[index]['power']) - psu_status = int(psu_status, 10) - # Check for PSU status - if (psu_status == 1): - status = 1 - - return status + raw = self.__get_gpio_value( + self.dx010_psu_gpio[index]['status']) + return int(raw, 10) == 1 def get_psu_presence(self, index): """ @@ -81,11 +78,5 @@ def get_psu_presence(self, index): :param index: An integer, index of the PSU of which to query status :return: Boolean, True if PSU is plugged, False if not """ - status = 0 - psu_absence = self.read_psu_statuses(self.psu[index]['abs']) - psu_absence = (int(psu_absence, 10)) - # Check for PSU presence - if (psu_absence == 0): - status = 1 - - return status + raw = self.__get_gpio_value(self.dx010_psu_gpio[index]['prs']) + return int(raw, 10) == 0 diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py index e69de29bb2d1..d82f3749319c 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["platform", "chassis"] +from sonic_platform import * 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 9c9f8a03d8c8..c9447b56a2fe 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 @@ -21,43 +21,53 @@ from sonic_platform.component import Component from sonic_platform.watchdog import Watchdog from sonic_platform.thermal import Thermal + from sonic_platform.sfp import Sfp + from sonic_platform.eeprom import Tlv except ImportError as e: raise ImportError(str(e) + "- required module not found") -CONFIG_DB_PATH = "/etc/sonic/config_db.json" -NUM_FAN = 5 +NUM_FAN_TRAY = 5 +NUM_FAN = 2 NUM_PSU = 2 NUM_THERMAL = 5 +NUM_SFP = 32 +NUM_COMPONENT = 5 RESET_REGISTER = "0x103" -REBOOT_CAUSE_PATH = "/host/reboot-cause/previous-reboot-cause.txt" -COMPONENT_NAME_LIST = ["CPLD1", "CPLD2", "CPLD3", "CPLD4", "BIOS"] +HOST_REBOOT_CAUSE_PATH = "/host/reboot-cause/" +PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/" +REBOOT_CAUSE_FILE = "reboot-cause.txt" +PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt" +HOST_CHK_CMD = "docker > /dev/null 2>&1" class Chassis(ChassisBase): """Platform-specific Chassis class""" def __init__(self): + ChassisBase.__init__(self) self.config_data = {} - for index in range(0, NUM_FAN): - fan = Fan(index) - self._fan_list.append(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) for index in range(0, NUM_THERMAL): thermal = Thermal(index) self._thermal_list.append(thermal) - ChassisBase.__init__(self) - self._component_name_list = COMPONENT_NAME_LIST + for index in range(0, NUM_SFP): + sfp = Sfp(index) + self._sfp_list.append(sfp) + for index in range(0, NUM_COMPONENT): + component = Component(index) + self._component_list.append(component) + self._watchdog = Watchdog() + self._eeprom = Tlv() - def __read_config_db(self): - try: - with open(CONFIG_DB_PATH, 'r') as fd: - data = json.load(fd) - return data - except IOError: - raise IOError("Unable to open config_db file !") + def __is_host(self): + return os.system(HOST_CHK_CMD) == 0 def __read_txt_file(self, file_path): try: @@ -65,7 +75,8 @@ def __read_txt_file(self, file_path): data = fd.read() return data.strip() except IOError: - raise IOError("Unable to open %s file !" % file_path) + pass + return None def get_base_mac(self): """ @@ -74,42 +85,25 @@ def get_base_mac(self): A string containing the MAC address in the format 'XX:XX:XX:XX:XX:XX' """ - try: - self.config_data = self.__read_config_db() - base_mac = self.config_data["DEVICE_METADATA"]["localhost"]["mac"] - return str(base_mac) - except KeyError: - return str(None) + return self._eeprom.get_mac() - def get_firmware_version(self, component_name): + def get_serial_number(self): """ - Retrieves platform-specific hardware/firmware versions for chassis - componenets such as BIOS, CPLD, FPGA, etc. - Args: - type: A string, component name - + Retrieves the hardware serial number for the chassis Returns: - A string containing platform-specific component versions + A string containing the hardware serial number for this chassis. """ - self.component = Component(component_name) - if component_name not in self._component_name_list: - return None - return self.component.get_firmware_version() + return self._eeprom.get_serial() - def install_component_firmware(self, component_name, image_path): + def get_system_eeprom_info(self): """ - Install firmware to module - Args: - type: A string, component name. - image_path: A string, path to firmware image. - + Retrieves the full content of system EEPROM information for the chassis Returns: - A boolean, True if install successfully, False if not + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. """ - self.component = Component(component_name) - if component_name not in self._component_name_list: - return False - return self.component.upgrade_firmware(image_path) + return self._eeprom.get_eeprom() def get_reboot_cause(self): """ @@ -122,17 +116,29 @@ def get_reboot_cause(self): is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used to pass a description of the reboot cause. """ - self.component = Component("CPLD1") description = 'None' reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER - hw_reboot_cause = self.component.get_register_value(RESET_REGISTER) - sw_reboot_cause = self.__read_txt_file(REBOOT_CAUSE_PATH) - if sw_reboot_cause != "Unexpected reboot": + 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( + reboot_cause_path) or "Unknown" + prev_sw_reboot_cause = self.__read_txt_file( + prev_reboot_cause_path) or "Unknown" + + if sw_reboot_cause == "Unknown" and (prev_sw_reboot_cause == "Unknown" or prev_sw_reboot_cause == self.REBOOT_CAUSE_POWER_LOSS) and hw_reboot_cause == "0x11": + reboot_cause = self.REBOOT_CAUSE_POWER_LOSS + elif sw_reboot_cause != "Unknown" and hw_reboot_cause == "0x11": reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE description = sw_reboot_cause - elif hw_reboot_cause == "0x11": - reboot_cause = self.REBOOT_CAUSE_POWER_LOSS + elif prev_reboot_cause_path != "Unknown" and hw_reboot_cause == "0x11": + reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE + description = prev_sw_reboot_cause elif hw_reboot_cause == "0x22": reboot_cause = self.REBOOT_CAUSE_WATCHDOG, else: 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 d78adf738920..67c7a9c46341 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 @@ -15,7 +15,7 @@ import subprocess try: - from sonic_platform_base.device_base import DeviceBase + from sonic_platform_base.component_base import ComponentBase except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -28,16 +28,19 @@ } 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"] -class Component(DeviceBase): +class Component(ComponentBase): """Platform-specific Component class""" DEVICE_TYPE = "component" - def __init__(self, component_name): - DeviceBase.__init__(self) - self.name = component_name.upper() + def __init__(self, component_index): + ComponentBase.__init__(self) + self.index = component_index + self.name = self.get_name() def __run_command(self, command): # Run bash command and print output to stdout @@ -88,6 +91,22 @@ def __get_cpld_version(self): cpld_version[cpld_name] = 'None' return cpld_version + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + return COMPONENT_NAME_LIST[self.index] + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + return COMPONENT_DES_LIST[self.index] + def get_firmware_version(self): """ Retrieves the firmware version of module @@ -104,7 +123,7 @@ def get_firmware_version(self): return fw_version - def upgrade_firmware(self, image_path): + def install_firmware(self, image_path): """ Install firmware to module Args: @@ -123,7 +142,6 @@ def upgrade_firmware(self, image_path): shutil.copy(image_path, new_image_path) install_command = "ispvm %s" % new_image_path elif self.name == "BIOS": - print("Not supported") - return False + install_command = "afulnx_64 %s /p /b /n /x /r" % image_path return self.__run_command(install_command) diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/eeprom.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/eeprom.py new file mode 100644 index 000000000000..dffda1a3c050 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/eeprom.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica Seastone-DX010 +# +# 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 glob + import os + import sys + import imp + import re + from array import array + from cStringIO import StringIO + from sonic_platform_base.sonic_eeprom import eeprom_dts + from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError(str(e) + "- required module not found") + +CACHE_ROOT = '/var/cache/sonic/decode-syseeprom' +CACHE_FILE = 'syseeprom_cache' + + +class Tlv(eeprom_tlvinfo.TlvInfoDecoder): + + EEPROM_DECODE_HEADLINES = 6 + + def __init__(self): + self._eeprom_path = "/sys/class/i2c-adapter/i2c-12/12-0050/eeprom" + super(Tlv, self).__init__(self._eeprom_path, 0, '', True) + self._eeprom = self._load_eeprom() + + def __parse_output(self, decode_output): + decode_output.replace('\0', '') + lines = decode_output.split('\n') + lines = lines[self.EEPROM_DECODE_HEADLINES:] + _eeprom_info_dict = dict() + + for line in lines: + try: + match = re.search( + '(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+)', line) + if match is not None: + idx = match.group(1) + value = match.group(3).rstrip('\0') + + _eeprom_info_dict[idx] = value + except: + pass + return _eeprom_info_dict + + def _load_eeprom(self): + original_stdout = sys.stdout + sys.stdout = StringIO() + try: + self.read_eeprom_db() + except: + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + return self.__parse_output(decode_output) + + status = self.check_status() + if 'ok' not in status: + return False + + if not os.path.exists(CACHE_ROOT): + try: + os.makedirs(CACHE_ROOT) + except: + pass + + # + # only the eeprom classes that inherit from eeprom_base + # support caching. Others will work normally + # + try: + self.set_cache_name(os.path.join(CACHE_ROOT, CACHE_FILE)) + except: + pass + + e = self.read_eeprom() + if e is None: + return 0 + + try: + self.update_cache(e) + except: + pass + + self.decode_eeprom(e) + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + + (is_valid, valid_crc) = self.is_checksum_valid(e) + if not is_valid: + return False + + return self.__parse_output(decode_output) + + def get_eeprom(self): + return self._eeprom + + def get_serial(self): + return self._eeprom.get('0x23', "Undefined.") + + def get_mac(self): + return self._eeprom.get('0x24', "Undefined.") diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py index 99e86d0a6c64..c0724e9bb688 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 @@ -17,29 +17,47 @@ except ImportError as e: raise ImportError(str(e) + "- required module not found") -CONFIG_DB_PATH = "/etc/sonic/config_db.json" EMC2305_PATH = "/sys/bus/i2c/drivers/emc2305/" -SYS_GPIO_DIR = "/sys/class/gpio" +GPIO_DIR = "/sys/class/gpio" +GPIO_LABEL = "pca9505" EMC2305_MAX_PWM = 255 EMC2305_FAN_PWM = "pwm{}" EMC2305_FAN_TARGET = "fan{}_target" EMC2305_FAN_INPUT = "pwm{}" -FAN_NAME_LIST = ["FAN-1", "FAN-2", "FAN-3", "FAN-4", "FAN-5"] +FAN_NAME_LIST = ["FAN-1F", "FAN-1R", "FAN-2F", "FAN-2R", + "FAN-3F", "FAN-3R", "FAN-4F", "FAN-4R", "FAN-5F", "FAN-5R"] +PSU_FAN_MAX_RPM = 11000 +PSU_HWMON_PATH = "/sys/bus/i2c/devices/i2c-{0}/{0}-00{1}/hwmon" +PSU_I2C_MAPPING = { + 0: { + "num": 10, + "addr": "5a" + }, + 1: { + "num": 11, + "addr": "5b" + }, +} class Fan(FanBase): """Platform-specific Fan class""" - def __init__(self, fan_index): - self.index = fan_index - self.config_data = {} - self.fan_speed = 0 - FanBase.__init__(self) + def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0): + self.fan_index = fan_index + self.fan_tray_index = fan_tray_index + self.is_psu_fan = is_psu_fan + if self.is_psu_fan: + self.psu_index = psu_index + self.psu_i2c_num = PSU_I2C_MAPPING[self.psu_index]["num"] + self.psu_i2c_addr = PSU_I2C_MAPPING[self.psu_index]["addr"] + self.psu_hwmon_path = PSU_HWMON_PATH.format( + self.psu_i2c_num, self.psu_i2c_addr) # dx010 fan attributes # Two EMC2305s located at i2c-13-4d and i2c-13-2e # to control a dual-fan module. - self.dx010_emc2305_chip = [ + self.emc2305_chip_mapping = [ { 'device': "13-002e", 'index_map': [2, 1, 4, 5, 3] @@ -49,121 +67,133 @@ def __init__(self, fan_index): 'index_map': [2, 4, 5, 3, 1] } ] - self.dx010_fan_gpio = [ - {'base': self.get_gpio_base()}, - {'prs': 10, 'dir': 15, 'color': {'red': 31, 'green': 32}}, - {'prs': 11, 'dir': 16, 'color': {'red': 29, 'green': 30}}, - {'prs': 12, 'dir': 17, 'color': {'red': 35, 'green': 36}}, - {'prs': 13, 'dir': 18, 'color': {'red': 37, 'green': 38}}, - {'prs': 14, 'dir': 19, 'color': {'red': 33, 'green': 34}}, + {'base': self.__get_gpio_base()}, + {'prs': 11, 'dir': 16, 'color': {'red': 31, 'green': 32}}, # 1 + {'prs': 10, 'dir': 15, 'color': {'red': 29, 'green': 30}}, # 2 + {'prs': 13, 'dir': 18, 'color': {'red': 35, 'green': 36}}, # 3 + {'prs': 14, 'dir': 19, 'color': {'red': 37, 'green': 38}}, # 4 + {'prs': 12, 'dir': 17, 'color': {'red': 33, 'green': 34}}, # 5 ] + FanBase.__init__(self) - def get_gpio_base(self): - for r in os.listdir(SYS_GPIO_DIR): - if "gpiochip" in r: + 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: + with open(file_path, 'w') as fd: + fd.write(str(value)) + except: + return False + return True + + def __search_file_by_name(self, directory, file_name): + for dirpath, dirnames, files in os.walk(directory): + for name in files: + file_path = os.path.join(dirpath, name) + if name in file_name: + 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): return int(r[8:], 10) return 216 # Reserve - def get_gpio_value(self, pinnum): + def __get_gpio_value(self, pinnum): gpio_base = self.dx010_fan_gpio[0]['base'] - - gpio_dir = SYS_GPIO_DIR + '/gpio' + str(gpio_base+pinnum) + gpio_dir = GPIO_DIR + '/gpio' + str(gpio_base+pinnum) gpio_file = gpio_dir + "/value" + retval = self.__read_txt_file(gpio_file) + return retval.rstrip('\r\n') - try: - with open(gpio_file, 'r') as fd: - retval = fd.read() - except IOError: - raise IOError("Unable to open " + gpio_file + "file !") - - retval = retval.rstrip('\r\n') - return retval - - def set_gpio_value(self, pinnum, value=0): + def __set_gpio_value(self, pinnum, value=0): gpio_base = self.dx010_fan_gpio[0]['base'] - - gpio_dir = SYS_GPIO_DIR + '/gpio' + str(gpio_base+pinnum) + gpio_dir = GPIO_DIR + '/gpio' + str(gpio_base+pinnum) gpio_file = gpio_dir + "/value" - - try: - with open(gpio_file, 'w') as fd: - retval = fd.write(str(value)) - except IOError: - raise IOError("Unable to open " + gpio_file + "file !") + return self.__write_txt_file(gpio_file, value) def get_direction(self): + """ + Retrieves the direction of fan + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + direction = self.FAN_DIRECTION_EXHAUST + if not self.is_psu_fan: + raw = self.__get_gpio_value( + self.dx010_fan_gpio[self.fan_tray_index+1]['dir']) - direction = self.FAN_DIRECTION_INTAKE - raw = self.get_gpio_value(self.dx010_fan_gpio[self.index+1]['dir']) - - if int(raw, 10) == 0: - direction = self.FAN_DIRECTION_INTAKE - else: - direction = self.FAN_DIRECTION_EXHAUST + direction = self.FAN_DIRECTION_INTAKE if int( + raw, 10) == 0 else self.FAN_DIRECTION_EXHAUST return direction def get_speed(self): """ - DX010 platform specific data: + Retrieves the speed of fan as a percentage of full speed + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + Note: speed = pwm_in/255*100 """ - # TODO: Seperate PSU's fan and main fan class - if self.fan_speed != 0: - return self.fan_speed - else: - speed = 0 - pwm = [] - emc2305_chips = self.dx010_emc2305_chip - - for chip in emc2305_chips: - device = chip['device'] - fan_index = chip['index_map'] - sysfs_path = "%s%s/%s" % ( - EMC2305_PATH, device, EMC2305_FAN_INPUT) - sysfs_path = sysfs_path.format(fan_index[self.index]) - try: - with open(sysfs_path, 'r') as file: - raw = file.read().strip('\r\n') - pwm.append(int(raw, 10)) - except IOError: - raise IOError("Unable to open " + sysfs_path) - - speed = math.ceil( - float(pwm[0]) * 100 / EMC2305_MAX_PWM) - - return int(speed) + speed = 0 + if self.is_psu_fan: + 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_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(): + 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_INPUT) + 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 + speed = math.ceil(float(pwm * 100 / EMC2305_MAX_PWM)) + + return int(speed) def get_target_speed(self): """ - DX010 platform specific data: + Retrieves the target (expected) speed of the fan + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + Note: speed_pc = pwm_target/255*100 0 : when PWM mode is use pwm : when pwm mode is not use - """ target = 0 - pwm = [] - emc2305_chips = self.dx010_emc2305_chip - - for chip in emc2305_chips: + 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.index]) - try: - with open(sysfs_path, 'r') as file: - raw = file.read().strip('\r\n') - pwm.append(int(raw, 10)) - except IOError: - raise IOError("Unable to open " + sysfs_path) - - target = pwm[0] * 100 / EMC2305_MAX_PWM + 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 @@ -178,55 +208,68 @@ def get_speed_tolerance(self): def set_speed(self, speed): """ - Depends on pwm or target mode is selected: + Sets the fan speed + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + Returns: + A boolean, True if speed is set successfully, False if not + + Note: + Depends on pwm or target mode is selected: 1) pwm = speed_pc * 255 <-- Currently use this mode. 2) target_pwm = speed_pc * 100 / 255 2.1) set pwm{}_enable to 3 """ pwm = speed * 255 / 100 - emc2305_chips = self.dx010_emc2305_chip - - for chip in emc2305_chips: + if not self.is_psu_fan and self.get_presence(): + chip = self.emc2305_chip_mapping[self.fan_index] device = chip['device'] fan_index = chip['index_map'] sysfs_path = "%s%s/%s" % ( EMC2305_PATH, device, EMC2305_FAN_PWM) - sysfs_path = sysfs_path.format(fan_index[self.index]) - try: - with open(sysfs_path, 'w') as file: - file.write(str(int(pwm))) - except IOError: - return False + sysfs_path = sysfs_path.format(fan_index[self.fan_tray_index]) + return self.__write_txt_file(sysfs_path, int(pwm)) - return True + return False def set_status_led(self, color): - try: - if color == self.STATUS_LED_COLOR_GREEN: - self.set_gpio_value( - self.dx010_fan_gpio[self.index+1]['color']['red'], 1) - self.set_gpio_value( - self.dx010_fan_gpio[self.index+1]['color']['green'], 0) - - elif color == self.STATUS_LED_COLOR_RED: - self.set_gpio_value( - self.dx010_fan_gpio[self.index+1]['color']['red'], 0) - self.set_gpio_value( - self.dx010_fan_gpio[self.index+1]['color']['green'], 1) - - elif color == self.STATUS_LED_COLOR_OFF: - self.set_gpio_value( - self.dx010_fan_gpio[self.index+1]['color']['red'], 1) - self.set_gpio_value( - self.dx010_fan_gpio[self.index+1]['color']['green'], 1) - else: + """ + Sets the state of the fan module status LED + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if status LED state is set successfully, False if not + """ + set_status_led = False + if not self.is_psu_fan: + s1, s2 = False, False + try: + if color == self.STATUS_LED_COLOR_GREEN: + s1 = self.__set_gpio_value( + self.dx010_fan_gpio[self.fan_tray_index+1]['color']['red'], 1) + s2 = self.__set_gpio_value( + self.dx010_fan_gpio[self.fan_tray_index+1]['color']['green'], 0) + + elif color == self.STATUS_LED_COLOR_RED: + s1 = self.__set_gpio_value( + self.dx010_fan_gpio[self.fan_tray_index+1]['color']['red'], 0) + s2 = self.__set_gpio_value( + self.dx010_fan_gpio[self.fan_tray_index+1]['color']['green'], 1) + + elif color == self.STATUS_LED_COLOR_OFF: + s1 = self.__set_gpio_value( + self.dx010_fan_gpio[self.fan_tray_index+1]['color']['red'], 1) + s2 = self.__set_gpio_value( + self.dx010_fan_gpio[self.fan_tray_index+1]['color']['green'], 1) + set_status_led = s1 and s2 + return set_status_led + except IOError: return False - except IOError: - return False - - return True + return set_status_led def get_name(self): """ @@ -234,7 +277,10 @@ def get_name(self): Returns: string: The name of the device """ - return FAN_NAME_LIST[self.index] + fan_name = FAN_NAME_LIST[self.fan_tray_index*2 + self.fan_index] if not self.is_psu_fan else "PSU-{} FAN-{}".format( + self.psu_index+1, self.fan_index+1) + + return fan_name def get_presence(self): """ @@ -242,6 +288,7 @@ def get_presence(self): Returns: bool: True if PSU is present, False if not """ - raw = self.get_gpio_value(self.dx010_fan_gpio[self.index+1]['prs']) + present_str = self.__get_gpio_value( + self.dx010_fan_gpio[self.fan_tray_index+1]['prs']) - return int(raw, 10) == 0 + return int(present_str, 10) == 0 if not self.is_psu_fan else True 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 ab22314495d5..8558b0b0cadd 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 @@ -8,7 +8,7 @@ # ############################################################################# -import os.path +import os import sonic_platform try: @@ -17,11 +17,22 @@ except ImportError as e: raise ImportError(str(e) + "- required module not found") -FAN_DX010_SPEED_PATH = "/sys/class/hwmon/hwmon{}/fan1_input" GREEN_LED_PATH = "/sys/devices/platform/leds_dx010/leds/dx010:green:p-{}/brightness" -FAN_MAX_RPM = 11000 -SYS_GPIO_DIR = "/sys/class/gpio" +HWMON_PATH = "/sys/bus/i2c/devices/i2c-{0}/{0}-00{1}/hwmon" +GPIO_DIR = "/sys/class/gpio" +GPIO_LABEL = "pca9505" PSU_NAME_LIST = ["PSU-1", "PSU-2"] +PSU_NUM_FAN = [1, 1] +PSU_I2C_MAPPING = { + 0: { + "num": 10, + "addr": "5a" + }, + 1: { + "num": 11, + "addr": "5b" + }, +} class Psu(PsuBase): @@ -32,51 +43,126 @@ def __init__(self, psu_index): self.index = psu_index self.green_led_path = GREEN_LED_PATH.format(self.index+1) self.dx010_psu_gpio = [ - {'base': self.get_gpio_base()}, + {'base': self.__get_gpio_base()}, {'prs': 27, 'status': 22}, {'prs': 28, 'status': 25} ] - - def get_gpio_base(self): - for r in os.listdir(SYS_GPIO_DIR): - if "gpiochip" in r: + self.i2c_num = PSU_I2C_MAPPING[self.index]["num"] + self.i2c_addr = PSU_I2C_MAPPING[self.index]["addr"] + self.hwmon_path = HWMON_PATH.format(self.i2c_num, self.i2c_addr) + for fan_index in range(0, PSU_NUM_FAN[self.index]): + fan = Fan(fan_index, 0, is_psu_fan=True, psu_index=self.index) + self._fan_list.append(fan) + + def __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): + 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): return int(r[8:], 10) return 216 # Reserve - def get_gpio_value(self, pinnum): + def __get_gpio_value(self, pinnum): gpio_base = self.dx010_psu_gpio[0]['base'] - gpio_file = "{}/gpio{}/value".format(SYS_GPIO_DIR, - str(gpio_base+pinnum)) - - try: - with open(gpio_file, 'r') as fd: - retval = fd.read() - except IOError: - raise IOError("Unable to open " + gpio_file + "file !") - - retval = retval.rstrip('\r\n') - return retval + gpio_dir = GPIO_DIR + '/gpio' + str(gpio_base+pinnum) + gpio_file = gpio_dir + "/value" + retval = self.__read_txt_file(gpio_file) + return retval.rstrip('\r\n') - def get_fan(self): + def get_voltage(self): """ - Retrieves object representing the fan module contained in this PSU + Retrieves current PSU voltage output Returns: - An object dervied from FanBase representing the fan module - contained in this PSU + A float number, the output voltage in volts, + e.g. 12.1 """ - - fan_speed_path = FAN_DX010_SPEED_PATH.format( - str(self.index+8)) - try: - with open(fan_speed_path) as fan_speed_file: - fan_speed_rpm = int(fan_speed_file.read()) - except IOError: - fan_speed = 0 - - fan_speed = float(fan_speed_rpm)/FAN_MAX_RPM * 100 - fan = Fan(0) - fan.fan_speed = int(fan_speed) if int(fan_speed) <= 100 else 100 - return fan + psu_voltage = 0.0 + voltage_name = "in{}_input" + voltage_label = "vout1" + + vout_label_path = self.__search_file_by_contain( + self.hwmon_path, voltage_label, "in") + if vout_label_path: + dir_name = os.path.dirname(vout_label_path) + basename = os.path.basename(vout_label_path) + in_num = filter(str.isdigit, basename) + vout_path = os.path.join( + dir_name, voltage_name.format(in_num)) + vout_val = self.__read_txt_file(vout_path) + psu_voltage = float(vout_val) / 1000 + + return psu_voltage + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + Returns: + A float number, the electric current in amperes, e.g 15.4 + """ + psu_current = 0.0 + current_name = "curr{}_input" + current_label = "iout1" + + curr_label_path = self.__search_file_by_contain( + self.hwmon_path, current_label, "cur") + if curr_label_path: + dir_name = os.path.dirname(curr_label_path) + basename = os.path.basename(curr_label_path) + cur_num = filter(str.isdigit, basename) + cur_path = os.path.join( + dir_name, current_name.format(cur_num)) + cur_val = self.__read_txt_file(cur_path) + psu_current = float(cur_val) / 1000 + + return psu_current + + def get_power(self): + """ + Retrieves current energy supplied by PSU + Returns: + A float number, the power in watts, e.g. 302.6 + """ + psu_power = 0.0 + current_name = "power{}_input" + current_label = "pout1" + + pw_label_path = self.__search_file_by_contain( + self.hwmon_path, current_label, "power") + if pw_label_path: + dir_name = os.path.dirname(pw_label_path) + basename = os.path.basename(pw_label_path) + pw_num = filter(str.isdigit, basename) + pw_path = os.path.join( + dir_name, current_name.format(pw_num)) + pw_val = self.__read_txt_file(pw_path) + psu_power = float(pw_val) / 1000000 + + return psu_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. + """ + return self.get_status() def set_status_led(self, color): """ @@ -104,6 +190,20 @@ def set_status_led(self, color): return True + def get_status_led(self): + """ + Gets the state of the PSU status LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + status = self.__read_txt_file(self.green_led_path) + status_str = { + '255': self.STATUS_LED_COLOR_GREEN, + '0': self.STATUS_LED_COLOR_OFF + }.get(status, None) + + return status_str + def get_name(self): """ Retrieves the name of the device @@ -118,7 +218,7 @@ def get_presence(self): Returns: bool: True if PSU is present, False if not """ - raw = self.get_gpio_value(self.dx010_psu_gpio[self.index+1]['prs']) + raw = self.__get_gpio_value(self.dx010_psu_gpio[self.index+1]['prs']) return int(raw, 10) == 0 def get_status(self): @@ -127,5 +227,6 @@ def get_status(self): Returns: A boolean value, True if device is operating properly, False if not """ - raw = self.get_gpio_value(self.dx010_psu_gpio[self.index+1]['status']) + raw = self.__get_gpio_value( + self.dx010_psu_gpio[self.index+1]['status']) return int(raw, 10) == 1 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 new file mode 100644 index 000000000000..3a02be39df6e --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py @@ -0,0 +1,945 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Sfp contains an implementation of SONiC Platform Base API and +# provides the sfp device status which are available in the platform +# +############################################################################# + +import os +import time +import subprocess +import sonic_device_util +from ctypes import create_string_buffer + +try: + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +INFO_OFFSET = 128 +DOM_OFFSET = 0 + +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_QSFP = 20 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 + +# Offset for values in QSFP eeprom +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_CONTROL_OFFSET = 86 +QSFP_CONTROL_WIDTH = 8 +QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 +QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 +QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_POWEROVERRIDE_OFFSET = 93 +QSFP_POWEROVERRIDE_WIDTH = 1 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNEL_THRESHOLD_OFFSET = 176 +QSFP_CHANNEL_THRESHOLD_WIDTH = 16 + +qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', + 'Length Cable Assembly(m)') + +qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', 'Fibre Channel Speed') + + + +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): + # Init index + self.index = sfp_index + self.port_num = self.index + 1 if self.PORT_START == 1 else index + + # 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.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'] + + self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', + 'rx1power', 'rx2power', 'rx3power', 'rx4power', 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', 'tx1power', 'tx2power', 'tx3power', 'tx4power'] + + self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + + SfpBase.__init__(self) + + def _convert_string_to_num(self, value_str): + if "-inf" in value_str: + return 'N/A' + elif "Unknown" in value_str: + return 'N/A' + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return 'N/A' + + def __read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return "" + + def __is_host(self): + return os.system(self.HOST_CHK_CMD) == 0 + + def __get_path_to_port_config_file(self): + platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.PLATFORM]) + hwsku_path = "/".join([platform_path, self.HWSKU] + ) if self.__is_host() else self.PMON_HWSKU_PATH + return "/".join([hwsku_path, "port_config.ini"]) + + def __read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num] + try: + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except: + pass + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + + return eeprom_raw + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardwarerev |1*255VCHAR |hardware version of SFP + serialnum |1*255VCHAR |serial number of the SFP + manufacturename |1*255VCHAR |SFP vendor name + modelname |1*255VCHAR |SFP model name + Connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + nominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + ======================================================================== + """ + # check present status + sfpi_obj = sff8436InterfaceId() + if not self.get_presence() or not sfpi_obj: + return {} + + offset = INFO_OFFSET + + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_QSFP) + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk( + sfp_interface_bulk_raw, 0) + + sfp_vendor_name_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_vendor_name_raw, 0) + + sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_vendor_pn_raw, 0) + + sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_QSFP) + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_vendor_rev_raw, 0) + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_vendor_sn_raw, 0) + + sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui( + sfp_vendor_oui_raw, 0) + + sfp_vendor_date_raw = self.__read_eeprom_specific_bytes( + (offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + sfp_vendor_date_data = sfpi_obj.parse_vendor_date( + sfp_vendor_date_raw, 0) + + transceiver_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A') + compliance_code_dict = dict() + + if sfp_interface_bulk_data: + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] + + transceiver_info_dict['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']) + + return transceiver_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + # check present status + sfpd_obj = sff8436Dom() + sfpi_obj = sff8436InterfaceId() + + if not self.get_presence() or not sfpi_obj or not sfpd_obj: + return {} + + transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + offset = 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 + + dom_temperature_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature( + dom_temperature_raw, 0) + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + + dom_voltage_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + dom_channel_monitor_data = {} + dom_channel_monitor_raw = None + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) + + else: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_channel_monitor_raw, 0) + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] + transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] + transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] + transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] + + if dom_channel_monitor_raw: + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + + for key in transceiver_dom_info_dict: + transceiver_dom_info_dict[key] = self._convert_string_to_num( + transceiver_dom_info_dict[key]) + + transceiver_dom_info_dict['rx_los'] = self.get_rx_los() + transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + + return transceiver_dom_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + # check present status + sfpd_obj = sff8436Dom() + + if not self.get_presence() or not sfpd_obj: + return {} + + transceiver_dom_threshold_dict = dict.fromkeys( + self.threshold_dict_keys, 'N/A') + dom_thres_raw = self.__read_eeprom_specific_bytes( + QSFP_MODULE_THRESHOLD_OFFSET, QSFP_MODULE_THRESHOLD_WIDTH) if self.get_presence() and sfpd_obj else None + + if dom_thres_raw: + module_threshold_values = sfpd_obj.parse_module_threshold_values( + dom_thres_raw, 0) + module_threshold_data = module_threshold_values.get('data') + if module_threshold_data: + transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['TempHighAlarm']['value'] + transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['TempLowAlarm']['value'] + transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['TempHighWarning']['value'] + transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['TempLowWarning']['value'] + transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['VccHighAlarm']['value'] + transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['VccLowAlarm']['value'] + transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['VccHighWarning']['value'] + transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['VccLowWarning']['value'] + + dom_thres_raw = self.__read_eeprom_specific_bytes( + QSFP_CHANNEL_THRESHOLD_OFFSET, QSFP_CHANNEL_THRESHOLD_WIDTH) if self.get_presence() and sfpd_obj else None + channel_threshold_values = sfpd_obj.parse_channel_threshold_values( + dom_thres_raw, 0) + channel_threshold_data = channel_threshold_values.get('data') + if channel_threshold_data: + transceiver_dom_threshold_dict['rxpowerhighalarm'] = channel_threshold_data['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerlowalarm'] = channel_threshold_data['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerhighwarning'] = channel_threshold_data['RxPowerHighWarning']['value'] + transceiver_dom_threshold_dict['rxpowerlowwarning'] = channel_threshold_data['RxPowerLowWarning']['value'] + transceiver_dom_threshold_dict['txpowerhighalarm'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerlowalarm'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerhighwarning'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerlowwarning'] = "0.0dBm" + transceiver_dom_threshold_dict['txbiashighalarm'] = channel_threshold_data['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_dict['txbiaslowalarm'] = channel_threshold_data['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_dict['txbiashighwarning'] = channel_threshold_data['TxBiasHighWarning']['value'] + transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value'] + + for key in transceiver_dom_threshold_dict: + transceiver_dom_threshold_dict[key] = self._convert_string_to_num( + transceiver_dom_threshold_dict[key]) + + return transceiver_dom_threshold_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + Returns: + A Boolean, True if reset enabled, False if disabled + """ + reset_status_raw = self.__read_txt_file(self.RESET_PATH).rstrip() + if not reset_status_raw: + return False + + reg_value = int(reset_status_raw, 16) + bin_format = bin(reg_value)[2:].zfill(32) + return bin_format[::-1][self.index] == '0' + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + rx_los = False + rx_los_list = [] + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + QSFP_CHANNL_RX_LOS_STATUS_OFFSET, QSFP_CHANNL_RX_LOS_STATUS_WIDTH) if self.get_presence() else None + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x01 != 0) + rx_los_list.append(rx_los_data & 0x02 != 0) + rx_los_list.append(rx_los_data & 0x04 != 0) + rx_los_list.append(rx_los_data & 0x08 != 0) + rx_los = rx_los_list[0] and rx_los_list[1] and rx_los_list[2] and rx_los_list[3] + return rx_los + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + tx_fault = False + tx_fault_list = [] + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + QSFP_CHANNL_TX_FAULT_STATUS_OFFSET, QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) if self.get_presence() else None + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x01 != 0) + tx_fault_list.append(tx_fault_data & 0x02 != 0) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + tx_fault_list.append(tx_fault_data & 0x08 != 0) + tx_fault = tx_fault_list[0] and tx_fault_list[1] and tx_fault_list[2] and tx_fault_list[3] + + return tx_fault + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + Returns: + A Boolean, True if tx_disable is enabled, False if disabled + """ + tx_disable_list = [] + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return False + + dom_control_raw = self.__read_eeprom_specific_bytes( + QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + tx_disable_list.append( + 'On' == dom_control_data['data']['TX1Disable']['value']) + tx_disable_list.append( + 'On' == dom_control_data['data']['TX2Disable']['value']) + tx_disable_list.append( + 'On' == dom_control_data['data']['TX3Disable']['value']) + tx_disable_list.append( + 'On' == dom_control_data['data']['TX4Disable']['value']) + + return tx_disable_list + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + tx_disable_list = self.get_tx_disable() + if tx_disable_list is None: + return 0 + tx_disabled = 0 + for i in range(len(tx_disable_list)): + if tx_disable_list[i]: + tx_disabled |= 1 << i + return tx_disabled + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + try: + reg_file = open(self.LP_PATH, "r") + content = reg_file.readline().rstrip() + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + # content is a string containing the hex representation of the register + reg_value = int(content, 16) + + # Determind if port_num start from 1 or 0 + bit_index = self.port_num - 1 if self.PORT_START == 1 else self.port_num + + # Mask off the bit corresponding to our port + mask = (1 << bit_index) + + # LPMode is active high + if reg_value & mask == 0: + return False + + return True + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + power_override = False + + 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 + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + Returns: + An integer number of current temperature in Celsius + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + return transceiver_dom_info_dict.get("temperature", "N/A") + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + Returns: + An integer number of supply voltage in mV + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + return transceiver_dom_info_dict.get("voltage", "N/A") + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + tx1_bs = transceiver_dom_info_dict.get("tx1bias", "N/A") + tx2_bs = transceiver_dom_info_dict.get("tx2bias", "N/A") + tx3_bs = transceiver_dom_info_dict.get("tx3bias", "N/A") + tx4_bs = transceiver_dom_info_dict.get("tx4bias", "N/A") + return [tx1_bs, tx2_bs, tx3_bs, tx4_bs] if transceiver_dom_info_dict else [] + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + rx1_pw = transceiver_dom_info_dict.get("rx1power", "N/A") + rx2_pw = transceiver_dom_info_dict.get("rx2power", "N/A") + rx3_pw = transceiver_dom_info_dict.get("rx3power", "N/A") + rx4_pw = transceiver_dom_info_dict.get("rx4power", "N/A") + return [rx1_pw, rx2_pw, rx3_pw, rx4_pw] if transceiver_dom_info_dict else [] + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + tx1_pw = transceiver_dom_info_dict.get("tx1power", "N/A") + tx2_pw = transceiver_dom_info_dict.get("tx2power", "N/A") + tx3_pw = transceiver_dom_info_dict.get("tx3power", "N/A") + tx4_pw = transceiver_dom_info_dict.get("tx4power", "N/A") + return [tx1_pw, tx2_pw, tx3_pw, tx4_pw] + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + Returns: + A boolean, True if successful, False if not + """ + # Check for invalid port_num + + try: + reg_file = open(self.RESET_PATH, "r+") + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + content = reg_file.readline().rstrip() + + # File content is a string containing the hex representation of the + # register + reg_value = int(content, 16) + + # Determind if port_num start from 1 or 0 + bit_index = self.port_num - 1 if self.PORT_START == 1 else self.port_num + + # Mask off the bit corresponding to our port + mask = (1 << bit_index) + + # ResetL is active low + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + reg_file.seek(0) + reg_file.write(hex(reg_value).rstrip('L')) + reg_file.close() + + # Sleep 1 second to allow it to settle + time.sleep(1) + + # Flip the bit back high and write back to the register to take port out of reset + try: + reg_file = open(self.RESET_PATH, "w") + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + reg_value = reg_value | mask + reg_file.seek(0) + reg_file.write(hex(reg_value).rstrip('L')) + reg_file.close() + + return True + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + 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 + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + Returns: + A boolean, True if successful, False if not + """ + 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 + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + try: + reg_file = open(self.LP_PATH, "r+") + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + content = reg_file.readline().rstrip() + + # content is a string containing the hex representation of the register + reg_value = int(content, 16) + + # Determind if port_num start from 1 or 0 + bit_index = self.port_num - 1 if self.PORT_START == 1 else self.port_num + + # Mask off the bit corresponding to our port + mask = (1 << bit_index) + # LPMode is active high; set or clear the bit accordingly + reg_value = reg_value | mask if lpmode else reg_value & ~mask + + # Convert our register value back to a hex string and write back + content = hex(reg_value).strip('L') + + reg_file.seek(0) + reg_file.write(content) + reg_file.close() + + return True + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + 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 + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + sfputil_helper = SfpUtilHelper() + sfputil_helper.read_porttab_mappings( + self.__get_path_to_port_config_file()) + name = sfputil_helper.logical[self.index] or "Unknown" + return name + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + presence_status_raw = self.__read_txt_file(self.PRS_PATH).rstrip() + if not presence_status_raw: + return False + + content = presence_status_raw.rstrip() + 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 + + # Mask off the bit corresponding to our port + mask = (1 << bit_index) + + # 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 device + Returns: + string: Model/part number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + return transceiver_dom_info_dict.get("modelname", "N/A") + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + transceiver_dom_info_dict = self.get_transceiver_info() + return transceiver_dom_info_dict.get("serialnum", "N/A") + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() and self.get_transceiver_bulk_status() diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/thermal.py index 43390dce8302..1e0a2c4b5645 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 @@ -37,18 +37,16 @@ def __init__(self, thermal_index): # Set hwmon path i2c_path = { - 0: "i2c-5/5-0048", # u4 system-inlet - 1: "i2c-6/6-0049", # u2 system-inlet - 2: "i2c-7/7-004a", # u44 bmc56960-on-board - 3: "i2c-14/14-0048", # u9200 cpu-on-board - 4: "i2c-15/15-004e" # u9201 system-outlet + 0: "i2c-5/5-0048/hwmon/hwmon1", # u4 system-inlet + 1: "i2c-6/6-0049/hwmon/hwmon2", # u2 system-inlet + 2: "i2c-7/7-004a/hwmon/hwmon3", # u44 bmc56960-on-board + 3: "i2c-14/14-0048/hwmon/hwmon4", # u9200 cpu-on-board + 4: "i2c-15/15-004e/hwmon/hwmon5" # u9201 system-outlet }.get(self.index, None) - self.ss_path = "{}/{}/hwmon".format(self.I2C_ADAPTER_PATH, i2c_path) + self.hwmon_path = "{}/{}".format(self.I2C_ADAPTER_PATH, i2c_path) self.ss_key = self.THERMAL_NAME_LIST[self.index] self.ss_index = 1 - self.hwmon_name = os.listdir(self.ss_path)[0] - self.hwmon_path = os.path.join(self.ss_path, self.hwmon_name) def __read_txt_file(self, file_path): try: @@ -56,7 +54,7 @@ def __read_txt_file(self, file_path): data = fd.read() return data.strip() except IOError: - raise IOError("Unable to open %s file !" % file_path) + pass def __get_temp(self, temp_file): temp_file_path = os.path.join(self.hwmon_path, temp_file) diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/port_config.ini b/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/port_config.ini new file mode 100644 index 000000000000..238c9fa4be79 --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/port_config.ini @@ -0,0 +1,129 @@ +# name lanes alias index speed +Ethernet0 33,34 QSFP1/1 1 100000 +Ethernet1 35,36 QSFP1/2 1 100000 +Ethernet2 37,38 QSFP1/3 1 100000 +Ethernet3 39,40 QSFP1/4 1 100000 +Ethernet4 41,42 QSFP2/1 2 100000 +Ethernet5 43,44 QSFP2/2 2 100000 +Ethernet6 45,46 QSFP2/3 2 100000 +Ethernet7 47,48 QSFP2/4 2 100000 +Ethernet8 49,50 QSFP3/1 3 100000 +Ethernet9 51,52 QSFP3/2 3 100000 +Ethernet10 53,54 QSFP3/3 3 100000 +Ethernet11 55,56 QSFP3/4 3 100000 +Ethernet12 57,58 QSFP4/1 4 100000 +Ethernet13 59,60 QSFP4/2 4 100000 +Ethernet14 61,62 QSFP4/3 4 100000 +Ethernet15 63,64 QSFP4/4 4 100000 +Ethernet16 65,66 QSFP5/1 5 100000 +Ethernet17 67,68 QSFP5/2 5 100000 +Ethernet18 69,70 QSFP5/3 5 100000 +Ethernet19 71,72 QSFP5/4 5 100000 +Ethernet20 73,74 QSFP6/1 6 100000 +Ethernet21 75,76 QSFP6/2 6 100000 +Ethernet22 77,78 QSFP6/3 6 100000 +Ethernet23 79,80 QSFP6/4 6 100000 +Ethernet24 81,82 QSFP7/1 7 100000 +Ethernet25 83,84 QSFP7/2 7 100000 +Ethernet26 85,86 QSFP7/3 7 100000 +Ethernet27 87,88 QSFP7/4 7 100000 +Ethernet28 89,90 QSFP8/1 8 100000 +Ethernet29 91,92 QSFP8/2 8 100000 +Ethernet30 93,94 QSFP8/3 8 100000 +Ethernet31 95,96 QSFP8/4 8 100000 +Ethernet32 1,2 QSFP9/1 9 100000 +Ethernet33 3,4 QSFP9/2 9 100000 +Ethernet34 5,6 QSFP9/3 9 100000 +Ethernet35 7,8 QSFP9/4 9 100000 +Ethernet36 9,10 QSFP10/1 10 100000 +Ethernet37 11,12 QSFP10/2 10 100000 +Ethernet38 13,14 QSFP10/3 10 100000 +Ethernet39 15,16 QSFP10/4 10 100000 +Ethernet40 17,18 QSFP11/1 11 100000 +Ethernet41 19,20 QSFP11/2 11 100000 +Ethernet42 21,22 QSFP11/3 11 100000 +Ethernet43 23,24 QSFP11/4 11 100000 +Ethernet44 25,26 QSFP12/1 12 100000 +Ethernet45 27,28 QSFP12/2 12 100000 +Ethernet46 29,30 QSFP12/3 12 100000 +Ethernet47 31,32 QSFP12/4 12 100000 +Ethernet48 97,98 QSFP13/1 13 100000 +Ethernet49 99,100 QSFP13/2 13 100000 +Ethernet50 101,102 QSFP13/3 13 100000 +Ethernet51 103,104 QSFP13/4 13 100000 +Ethernet52 105,106 QSFP14/1 14 100000 +Ethernet53 107,108 QSFP14/2 14 100000 +Ethernet54 109,110 QSFP14/3 14 100000 +Ethernet55 111,112 QSFP14/4 14 100000 +Ethernet56 113,114 QSFP15/1 15 100000 +Ethernet57 115,116 QSFP15/2 15 100000 +Ethernet58 117,118 QSFP15/3 15 100000 +Ethernet59 119,120 QSFP15/4 15 100000 +Ethernet60 121,122 QSFP16/1 16 100000 +Ethernet61 123,124 QSFP16/2 16 100000 +Ethernet62 125,126 QSFP16/3 16 100000 +Ethernet63 127,128 QSFP16/4 16 100000 +Ethernet64 129,130 QSFP17/1 17 100000 +Ethernet65 131,132 QSFP17/2 17 100000 +Ethernet66 133,134 QSFP17/3 17 100000 +Ethernet67 135,136 QSFP17/4 17 100000 +Ethernet68 137,138 QSFP18/1 18 100000 +Ethernet69 139,140 QSFP18/2 18 100000 +Ethernet70 141,142 QSFP18/3 18 100000 +Ethernet71 143,144 QSFP18/4 18 100000 +Ethernet72 145,146 QSFP19/1 19 100000 +Ethernet73 147,148 QSFP19/2 19 100000 +Ethernet74 149,150 QSFP19/3 19 100000 +Ethernet75 151,152 QSFP19/4 19 100000 +Ethernet76 153,154 QSFP20/1 20 100000 +Ethernet77 155,156 QSFP20/2 20 100000 +Ethernet78 157,158 QSFP20/3 20 100000 +Ethernet79 159,160 QSFP20/4 20 100000 +Ethernet80 225,226 QSFP21/1 21 100000 +Ethernet81 227,228 QSFP21/2 21 100000 +Ethernet82 229,230 QSFP21/3 21 100000 +Ethernet83 231,232 QSFP21/4 21 100000 +Ethernet84 233,234 QSFP22/1 22 100000 +Ethernet85 235,236 QSFP22/2 22 100000 +Ethernet86 237,238 QSFP22/3 22 100000 +Ethernet87 239,240 QSFP22/4 22 100000 +Ethernet88 241,242 QSFP23/1 23 100000 +Ethernet89 243,244 QSFP23/2 23 100000 +Ethernet90 245,246 QSFP23/3 23 100000 +Ethernet91 247,248 QSFP23/4 23 100000 +Ethernet92 249,250 QSFP24/1 24 100000 +Ethernet93 251,252 QSFP24/2 24 100000 +Ethernet94 253,254 QSFP24/3 24 100000 +Ethernet95 255,256 QSFP24/4 24 100000 +Ethernet96 161,162 QSFP25/1 25 100000 +Ethernet97 163,164 QSFP25/2 25 100000 +Ethernet98 165,166 QSFP25/3 25 100000 +Ethernet99 167,168 QSFP25/4 25 100000 +Ethernet100 169,170 QSFP26/1 26 100000 +Ethernet101 171,172 QSFP26/2 26 100000 +Ethernet102 173,174 QSFP26/3 26 100000 +Ethernet103 175,176 QSFP26/4 26 100000 +Ethernet104 177,178 QSFP27/1 27 100000 +Ethernet105 179,180 QSFP27/2 27 100000 +Ethernet106 181,182 QSFP27/3 27 100000 +Ethernet107 183,184 QSFP27/4 27 100000 +Ethernet108 185,186 QSFP28/1 28 100000 +Ethernet109 187,188 QSFP28/2 28 100000 +Ethernet110 189,190 QSFP28/3 28 100000 +Ethernet111 191,192 QSFP28/4 28 100000 +Ethernet112 193,194 QSFP29/1 29 100000 +Ethernet113 195,196 QSFP29/2 29 100000 +Ethernet114 197,198 QSFP29/3 29 100000 +Ethernet115 199,200 QSFP29/4 29 100000 +Ethernet116 201,202 QSFP30/1 30 100000 +Ethernet117 203,204 QSFP30/2 30 100000 +Ethernet118 205,206 QSFP30/3 30 100000 +Ethernet119 207,208 QSFP30/4 30 100000 +Ethernet120 209,210 QSFP31/1 31 100000 +Ethernet121 211,212 QSFP31/2 31 100000 +Ethernet122 213,214 QSFP31/3 31 100000 +Ethernet123 215,216 QSFP31/4 31 100000 +Ethernet124 217,218 QSFP32/1 32 100000 +Ethernet125 219,220 QSFP32/2 32 100000 +Ethernet126 221,222 QSFP32/3 32 100000 +Ethernet127 223,224 QSFP32/4 32 100000 \ No newline at end of file diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/sai.profile b/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/sai.profile new file mode 100644 index 000000000000..bc7681f0272f --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-128x100G.config.bcm diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/th3-128x100G.config.bcm b/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/th3-128x100G.config.bcm new file mode 100644 index 000000000000..0b66c8b53814 --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/th3-128x100G.config.bcm @@ -0,0 +1,441 @@ +pbmp_xport_xe.0=0x8ffff8ffffcffff8ffff8ffff8ffffcffff9fffe +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 + +portmap_20=33:100:2 +portmap_21=35:100:2 +portmap_22=37:100:2 +portmap_23=39:100:2 + +portmap_24=41:100:2 +portmap_25=43:100:2 +portmap_26=45:100:2 +portmap_27=47:100:2 + +portmap_28=49:100:2 +portmap_29=51:100:2 +portmap_30=53:100:2 +portmap_31=55:100:2 + +portmap_32=57:100:2 +portmap_33=59:100:2 +portmap_34=61:100:2 +portmap_35=63:100:2 + +portmap_40=65:100:2 +portmap_41=67:100:2 +portmap_42=69:100:2 +portmap_43=71:100:2 + +portmap_44=73:100:2 +portmap_45=75:100:2 +portmap_46=77:100:2 +portmap_47=79:100:2 + +portmap_48=81:100:2 +portmap_49=83:100:2 +portmap_50=85:100:2 +portmap_51=87:100:2 + +portmap_52=89:100:2 +portmap_53=91:100:2 +portmap_54=93:100:2 +portmap_55=95:100:2 + +portmap_1=1:100:2 +portmap_2=3:100:2 +portmap_3=5:100:2 +portmap_4=7:100:2 + +portmap_5=9:100:2 +portmap_6=11:100:2 +portmap_7=13:100:2 +portmap_8=15:100:2 + +portmap_9=17:100:2 +portmap_10=19:100:2 +portmap_11=21:100:2 +portmap_12=23:100:2 + +portmap_13=25:100:2 +portmap_14=27:100:2 +portmap_15=29:100:2 +portmap_16=31:100:2 + +portmap_60=97:100:2 +portmap_61=99:100:2 +portmap_62=101:100:2 +portmap_63=103:100:2 + +portmap_64=105:100:2 +portmap_65=107:100:2 +portmap_66=109:100:2 +portmap_67=111:100:2 + +portmap_68=113:100:2 +portmap_69=115:100:2 +portmap_70=117:100:2 +portmap_71=119:100:2 + +portmap_72=121:100:2 +portmap_73=123:100:2 +portmap_74=125:100:2 +portmap_75=127:100:2 + +portmap_80=129:100:2 +portmap_81=131:100:2 +portmap_82=133:100:2 +portmap_83=135:100:2 + +portmap_84=137:100:2 +portmap_85=139:100:2 +portmap_86=141:100:2 +portmap_87=143:100:2 + +portmap_88=145:100:2 +portmap_89=147:100:2 +portmap_90=149:100:2 +portmap_91=151:100:2 + +portmap_92=153:100:2 +portmap_93=155:100:2 +portmap_94=157:100:2 +portmap_95=159:100:2 + +portmap_140=225:100:2 +portmap_141=227:100:2 +portmap_142=229:100:2 +portmap_143=231:100:2 + +portmap_144=233:100:2 +portmap_145=235:100:2 +portmap_146=237:100:2 +portmap_147=239:100:2 + +portmap_148=241:100:2 +portmap_149=243:100:2 +portmap_150=245:100:2 +portmap_151=247:100:2 + +portmap_152=249:100:2 +portmap_153=251:100:2 +portmap_154=253:100:2 +portmap_155=255:100:2 + +portmap_100=161:100:2 +portmap_101=163:100:2 +portmap_102=165:100:2 +portmap_103=167:100:2 + +portmap_104=169:100:2 +portmap_105=171:100:2 +portmap_106=173:100:2 +portmap_107=175:100:2 + +portmap_108=177:100:2 +portmap_109=179:100:2 +portmap_110=181:100:2 +portmap_111=183:100:2 + +portmap_112=185:100:2 +portmap_113=187:100:2 +portmap_114=189:100:2 +portmap_115=191:100:2 + +portmap_120=193:100:2 +portmap_121=195:100:2 +portmap_122=197:100:2 +portmap_123=199:100:2 + +portmap_124=201:100:2 +portmap_125=203:100:2 +portmap_126=205:100:2 +portmap_127=207:100:2 + +portmap_128=209:100:2 +portmap_129=211:100:2 +portmap_130=213:100:2 +portmap_131=215:100:2 + +portmap_132=217:100:2 +portmap_133=219:100:2 +portmap_134=221:100:2 +portmap_135=223:100:2 + +phy_chain_rx_lane_map_physical{33.0}=0x65732041 +phy_chain_tx_lane_map_physical{33.0}=0x47206531 +phy_chain_rx_lane_map_physical{41.0}=0x07561243 +phy_chain_tx_lane_map_physical{41.0}=0x36207514 +phy_chain_rx_lane_map_physical{49.0}=0x54632071 +phy_chain_tx_lane_map_physical{49.0}=0x06241735 +phy_chain_rx_lane_map_physical{57.0}=0x07561243 +phy_chain_tx_lane_map_physical{57.0}=0x35207614 +phy_chain_rx_lane_map_physical{65.0}=0x45623170 +phy_chain_tx_lane_map_physical{65.0}=0x51260734 +phy_chain_rx_lane_map_physical{73.0}=0x07561243 +phy_chain_tx_lane_map_physical{73.0}=0x37245610 +phy_chain_rx_lane_map_physical{81.0}=0x45632071 +phy_chain_tx_lane_map_physical{81.0}=0x51260734 +phy_chain_rx_lane_map_physical{89.0}=0x07561243 +phy_chain_tx_lane_map_physical{89.0}=0x26437510 +phy_chain_rx_lane_map_physical{1.0}=0x30176524 +phy_chain_tx_lane_map_physical{1.0}=0x20615374 +phy_chain_rx_lane_map_physical{9.0}=0x37562041 +phy_chain_tx_lane_map_physical{9.0}=0x05176432 +phy_chain_rx_lane_map_physical{17.0}=0x43607251 +phy_chain_tx_lane_map_physical{17.0}=0x70261435 +phy_chain_rx_lane_map_physical{25.0}=0x60347125 +phy_chain_tx_lane_map_physical{25.0}=0x46357120 +phy_chain_rx_lane_map_physical{97.0}=0x47601352 +phy_chain_tx_lane_map_physical{97.0}=0x04265137 +phy_chain_rx_lane_map_physical{105.0}=0x73206415 +phy_chain_tx_lane_map_physical{105.0}=0x26374150 +phy_chain_rx_lane_map_physical{113.0}=0x47632051 +phy_chain_tx_lane_map_physical{113.0}=0x03254617 +phy_chain_rx_lane_map_physical{121.0}=0x63027415 +phy_chain_tx_lane_map_physical{121.0}=0x63721045 +phy_chain_rx_lane_map_physical{129.0}=0x30154627 +phy_chain_tx_lane_map_physical{129.0}=0x04735261 +phy_chain_rx_lane_map_physical{137.0}=0x24753061 +phy_chain_tx_lane_map_physical{137.0}=0x37614520 +phy_chain_rx_lane_map_physical{145.0}=0x47601352 +phy_chain_tx_lane_map_physical{145.0}=0x63274510 +phy_chain_rx_lane_map_physical{153.0}=0x07361524 +phy_chain_tx_lane_map_physical{153.0}=0x36527104 +phy_chain_rx_lane_map_physical{225.0}=0x56410273 +phy_chain_tx_lane_map_physical{225.0}=0x10274635 +phy_chain_rx_lane_map_physical{233.0}=0x15740263 +phy_chain_tx_lane_map_physical{233.0}=0x24351607 +phy_chain_rx_lane_map_physical{241.0}=0x74015263 +phy_chain_tx_lane_map_physical{241.0}=0x04152637 +phy_chain_rx_lane_map_physical{249.0}=0x62037514 +phy_chain_tx_lane_map_physical{249.0}=0x72453160 +phy_chain_rx_lane_map_physical{161.0}=0x46510273 +phy_chain_tx_lane_map_physical{161.0}=0x01653724 +phy_chain_rx_lane_map_physical{169.0}=0x25743160 +phy_chain_tx_lane_map_physical{169.0}=0x07216435 +phy_chain_rx_lane_map_physical{177.0}=0x46510273 +phy_chain_tx_lane_map_physical{177.0}=0x01652734 +phy_chain_rx_lane_map_physical{185.0}=0x25743160 +phy_chain_tx_lane_map_physical{185.0}=0x37016425 +phy_chain_rx_lane_map_physical{193.0}=0x46510372 +phy_chain_tx_lane_map_physical{193.0}=0x06153724 +phy_chain_rx_lane_map_physical{201.0}=0x25743160 +phy_chain_tx_lane_map_physical{201.0}=0x36017524 +phy_chain_rx_lane_map_physical{209.0}=0x47601352 +phy_chain_tx_lane_map_physical{209.0}=0x04152736 +phy_chain_rx_lane_map_physical{217.0}=0x26453170 +phy_chain_tx_lane_map_physical{217.0}=0x36027415 + +serdes_core_rx_polarity_flip_physical{33}=0x29 +serdes_core_tx_polarity_flip_physical{33}=0xfe +serdes_core_rx_polarity_flip_physical{41}=0xb1 +serdes_core_tx_polarity_flip_physical{41}=0xe8 +serdes_core_rx_polarity_flip_physical{49}=0xca +serdes_core_tx_polarity_flip_physical{49}=0xb6 +serdes_core_rx_polarity_flip_physical{57}=0x9b +serdes_core_tx_polarity_flip_physical{57}=0xdc +serdes_core_rx_polarity_flip_physical{65}=0x17 +serdes_core_tx_polarity_flip_physical{65}=0x86 +serdes_core_rx_polarity_flip_physical{73}=0x9b +serdes_core_tx_polarity_flip_physical{73}=0x55 +serdes_core_rx_polarity_flip_physical{81}=0xa +serdes_core_tx_polarity_flip_physical{81}=0x6 +serdes_core_rx_polarity_flip_physical{89}=0x9b +serdes_core_tx_polarity_flip_physical{89}=0x48 +serdes_core_rx_polarity_flip_physical{1}=0xec +serdes_core_tx_polarity_flip_physical{1}=0x56 +serdes_core_rx_polarity_flip_physical{9}=0x13 +serdes_core_tx_polarity_flip_physical{9}=0xa6 +serdes_core_rx_polarity_flip_physical{17}=0x5a +serdes_core_tx_polarity_flip_physical{17}=0xc6 +serdes_core_rx_polarity_flip_physical{25}=0xf +serdes_core_tx_polarity_flip_physical{25}=0x4e +serdes_core_rx_polarity_flip_physical{97}=0x17 +serdes_core_tx_polarity_flip_physical{97}=0x2e +serdes_core_rx_polarity_flip_physical{105}=0xce +serdes_core_tx_polarity_flip_physical{105}=0x7c +serdes_core_rx_polarity_flip_physical{113}=0xa +serdes_core_tx_polarity_flip_physical{113}=0x35 + +serdes_core_rx_polarity_flip_physical{121}=0xb9 +serdes_core_tx_polarity_flip_physical{121}=0xef +serdes_core_rx_polarity_flip_physical{129}=0xe8 +serdes_core_tx_polarity_flip_physical{129}=0xac +serdes_core_rx_polarity_flip_physical{137}=0xcb +serdes_core_tx_polarity_flip_physical{137}=0x9c +serdes_core_rx_polarity_flip_physical{145}=0x17 +serdes_core_tx_polarity_flip_physical{145}=0x32 +serdes_core_rx_polarity_flip_physical{153}=0xb9 +serdes_core_tx_polarity_flip_physical{153}=0xaf +serdes_core_rx_polarity_flip_physical{225}=0xaa +serdes_core_tx_polarity_flip_physical{225}=0x7 +serdes_core_rx_polarity_flip_physical{233}=0x31 +serdes_core_tx_polarity_flip_physical{233}=0x47 +serdes_core_rx_polarity_flip_physical{241}=0xe8 +serdes_core_tx_polarity_flip_physical{241}=0x9e +serdes_core_rx_polarity_flip_physical{249}=0xec +serdes_core_tx_polarity_flip_physical{249}=0x1f +serdes_core_rx_polarity_flip_physical{161}=0x6a +serdes_core_tx_polarity_flip_physical{161}=0xd4 +serdes_core_rx_polarity_flip_physical{169}=0x9e +serdes_core_tx_polarity_flip_physical{169}=0x7b +serdes_core_rx_polarity_flip_physical{177}=0x6a +serdes_core_tx_polarity_flip_physical{177}=0xcc +serdes_core_rx_polarity_flip_physical{185}=0x9e +serdes_core_tx_polarity_flip_physical{185}=0x58 +serdes_core_rx_polarity_flip_physical{193}=0x6f +serdes_core_tx_polarity_flip_physical{193}=0x24 +serdes_core_rx_polarity_flip_physical{201}=0x9e +serdes_core_tx_polarity_flip_physical{201}=0xdf +serdes_core_rx_polarity_flip_physical{209}=0x17 +serdes_core_tx_polarity_flip_physical{209}=0xe9 +serdes_core_rx_polarity_flip_physical{217}=0xec +serdes_core_tx_polarity_flip_physical{217}=0x68 + + +dport_map_port_20=1 +dport_map_port_21=2 +dport_map_port_22=3 +dport_map_port_23=4 +dport_map_port_24=5 +dport_map_port_25=6 +dport_map_port_26=7 +dport_map_port_27=8 +dport_map_port_28=9 +dport_map_port_29=10 +dport_map_port_30=11 +dport_map_port_31=12 +dport_map_port_32=13 +dport_map_port_33=14 +dport_map_port_34=15 +dport_map_port_35=16 +dport_map_port_40=17 +dport_map_port_41=18 +dport_map_port_42=19 +dport_map_port_43=20 +dport_map_port_44=21 +dport_map_port_45=22 +dport_map_port_46=23 +dport_map_port_47=24 +dport_map_port_48=25 +dport_map_port_49=26 +dport_map_port_50=27 +dport_map_port_51=28 +dport_map_port_52=29 +dport_map_port_53=30 +dport_map_port_54=31 +dport_map_port_55=32 +dport_map_port_1=33 +dport_map_port_2=34 +dport_map_port_3=35 +dport_map_port_4=36 +dport_map_port_5=37 +dport_map_port_6=38 +dport_map_port_7=39 +dport_map_port_8=40 +dport_map_port_9=41 +dport_map_port_10=42 +dport_map_port_11=43 +dport_map_port_12=44 +dport_map_port_13=45 +dport_map_port_14=46 +dport_map_port_15=47 +dport_map_port_16=48 +dport_map_port_60=49 +dport_map_port_61=50 +dport_map_port_62=51 +dport_map_port_63=52 +dport_map_port_64=53 +dport_map_port_65=54 +dport_map_port_66=55 +dport_map_port_67=56 +dport_map_port_68=57 +dport_map_port_69=58 +dport_map_port_70=59 +dport_map_port_71=60 +dport_map_port_72=61 +dport_map_port_73=62 +dport_map_port_74=63 +dport_map_port_75=64 +dport_map_port_80=65 +dport_map_port_81=66 +dport_map_port_82=67 +dport_map_port_83=68 +dport_map_port_84=69 +dport_map_port_85=70 +dport_map_port_86=71 +dport_map_port_87=72 +dport_map_port_88=73 +dport_map_port_89=74 +dport_map_port_90=75 +dport_map_port_91=76 +dport_map_port_92=77 +dport_map_port_93=78 +dport_map_port_94=79 +dport_map_port_95=80 +dport_map_port_140=81 +dport_map_port_141=82 +dport_map_port_142=83 +dport_map_port_143=84 +dport_map_port_144=85 +dport_map_port_145=86 +dport_map_port_146=87 +dport_map_port_147=88 +dport_map_port_148=89 +dport_map_port_149=90 +dport_map_port_150=91 +dport_map_port_151=92 +dport_map_port_152=93 +dport_map_port_153=94 +dport_map_port_154=95 +dport_map_port_155=96 +dport_map_port_100=97 +dport_map_port_101=98 +dport_map_port_102=99 +dport_map_port_103=100 +dport_map_port_104=101 +dport_map_port_105=102 +dport_map_port_106=103 +dport_map_port_107=104 +dport_map_port_108=105 +dport_map_port_109=106 +dport_map_port_110=107 +dport_map_port_111=108 +dport_map_port_112=109 +dport_map_port_113=110 +dport_map_port_114=111 +dport_map_port_115=112 +dport_map_port_120=113 +dport_map_port_121=114 +dport_map_port_122=115 +dport_map_port_123=116 +dport_map_port_124=117 +dport_map_port_125=118 +dport_map_port_126=119 +dport_map_port_127=120 +dport_map_port_128=121 +dport_map_port_129=122 +dport_map_port_130=123 +dport_map_port_131=124 +dport_map_port_132=125 +dport_map_port_133=126 +dport_map_port_134=127 +dport_map_port_135=128 + +core_clock_frequency=1325 +dpr_clock_frequency=1000 +device_clock_frequency=1325 +port_flex_enable=1 + +#firmware load method, use fast load +load_firmware=0x2 diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone/port_config.ini b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/port_config.ini new file mode 100644 index 000000000000..9cd85ee34798 --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 33,34,35,36,37,38,39,40 QSFPDD1 1 400000 +Ethernet4 41,42,43,44,45,46,47,48 QSFPDD2 2 400000 +Ethernet8 49,50,51,52,53,54,55,56 QSFPDD3 3 400000 +Ethernet12 57,58,59,60,61,62,63,64 QSFPDD4 4 400000 +Ethernet16 65,66,67,68,69,70,71,72 QSFPDD5 5 400000 +Ethernet20 73,74,75,76,77,78,79,80 QSFPDD6 6 400000 +Ethernet24 81,82,83,84,85,86,87,88 QSFPDD7 7 400000 +Ethernet28 89,90,91,92,93,94,95,96 QSFPDD8 8 400000 +Ethernet32 1,2,3,4,5,6,7,8 QSFPDD9 9 400000 +Ethernet36 9,10,11,12,13,14,15,16 QSFPDD10 10 400000 +Ethernet40 17,18,19,20,21,22,23,24 QSFPDD11 11 400000 +Ethernet44 25,26,27,28,29,30,31,32 QSFPDD12 12 400000 +Ethernet48 97,98,99,100,101,102,103,104 QSFPDD13 13 400000 +Ethernet52 105,106,107,108,109,110,111,112 QSFPDD14 14 400000 +Ethernet56 113,114,115,116,117,118,119,120 QSFPDD15 15 400000 +Ethernet60 121,122,123,124,125,126,127,128 QSFPDD16 16 400000 +Ethernet64 129,130,131,132,133,134,135,136 QSFPDD17 17 400000 +Ethernet68 137,138,139,140,141,142,143,144 QSFPDD18 18 400000 +Ethernet72 145,146,147,148,149,150,151,152 QSFPDD19 19 400000 +Ethernet76 153,154,155,156,157,158,159,160 QSFPDD20 20 400000 +Ethernet80 225,226,227,228,229,230,231,232 QSFPDD21 21 400000 +Ethernet84 233,234,235,236,237,238,239,240 QSFPDD22 22 400000 +Ethernet88 241,242,243,244,245,246,247,248 QSFPDD23 23 400000 +Ethernet92 249,250,251,252,253,254,255,256 QSFPDD24 24 400000 +Ethernet96 161,162,163,164,165,166,167,168 QSFPDD25 25 400000 +Ethernet100 169,170,171,172,173,174,175,176 QSFPDD26 26 400000 +Ethernet104 177,178,179,180,181,182,183,184 QSFPDD27 27 400000 +Ethernet108 185,186,187,188,189,190,191,192 QSFPDD28 28 400000 +Ethernet112 193,194,195,196,197,198,199,200 QSFPDD29 29 400000 +Ethernet116 201,202,203,204,205,206,207,208 QSFPDD30 30 400000 +Ethernet120 209,210,211,212,213,214,215,216 QSFPDD31 31 400000 +Ethernet124 217,218,219,220,221,222,223,224 QSFPDD32 32 400000 \ No newline at end of file diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone/sai.profile b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/sai.profile new file mode 100644 index 000000000000..1915eb9b35a1 --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-32x400G.config.bcm diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone/th3-32x400G.config.bcm b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/th3-32x400G.config.bcm new file mode 100644 index 000000000000..5e5fc82aeace --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/th3-32x400G.config.bcm @@ -0,0 +1,231 @@ + +pbmp_xport_xe.0=0x8111181111c1111811118111181111c111182222 +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 + + + +#portmap_38=257:10 +#portmap_118=258:10 + + +portmap_20=33:400 +portmap_24=41:400 +portmap_28=49:400 +portmap_32=57:400 +portmap_40=65:400 +portmap_44=73:400 +portmap_48=81:400 +portmap_52=89:400 +portmap_1=1:400 +portmap_5=9:400 +portmap_9=17:400 +portmap_13=25:400 +portmap_60=97:400 +portmap_64=105:400 +portmap_68=113:400 +portmap_72=121:400 +portmap_80=129:400 +portmap_84=137:400 +portmap_88=145:400 +portmap_92=153:400 +portmap_140=225:400 +portmap_144=233:400 +portmap_148=241:400 +portmap_152=249:400 +portmap_100=161:400 +portmap_104=169:400 +portmap_108=177:400 +portmap_112=185:400 +portmap_120=193:400 +portmap_124=201:400 +portmap_128=209:400 +portmap_132=217:400 + +phy_chain_rx_lane_map_physical{33.0}=0x65732041 +phy_chain_tx_lane_map_physical{33.0}=0x47206531 +phy_chain_rx_lane_map_physical{41.0}=0x07561243 +phy_chain_tx_lane_map_physical{41.0}=0x36207514 +phy_chain_rx_lane_map_physical{49.0}=0x54632071 +phy_chain_tx_lane_map_physical{49.0}=0x06241735 +phy_chain_rx_lane_map_physical{57.0}=0x07561243 +phy_chain_tx_lane_map_physical{57.0}=0x35207614 +phy_chain_rx_lane_map_physical{65.0}=0x45623170 +phy_chain_tx_lane_map_physical{65.0}=0x51260734 +phy_chain_rx_lane_map_physical{73.0}=0x07561243 +phy_chain_tx_lane_map_physical{73.0}=0x37245610 +phy_chain_rx_lane_map_physical{81.0}=0x45632071 +phy_chain_tx_lane_map_physical{81.0}=0x51260734 +phy_chain_rx_lane_map_physical{89.0}=0x07561243 +phy_chain_tx_lane_map_physical{89.0}=0x26437510 +phy_chain_rx_lane_map_physical{1.0}=0x30176524 +phy_chain_tx_lane_map_physical{1.0}=0x20615374 +phy_chain_rx_lane_map_physical{9.0}=0x37562041 +phy_chain_tx_lane_map_physical{9.0}=0x05176432 +phy_chain_rx_lane_map_physical{17.0}=0x43607251 +phy_chain_tx_lane_map_physical{17.0}=0x70261435 +phy_chain_rx_lane_map_physical{25.0}=0x60347125 +phy_chain_tx_lane_map_physical{25.0}=0x46357120 +phy_chain_rx_lane_map_physical{97.0}=0x47601352 +phy_chain_tx_lane_map_physical{97.0}=0x04265137 +phy_chain_rx_lane_map_physical{105.0}=0x73206415 +phy_chain_tx_lane_map_physical{105.0}=0x26374150 +phy_chain_rx_lane_map_physical{113.0}=0x47632051 +phy_chain_tx_lane_map_physical{113.0}=0x03254617 +phy_chain_rx_lane_map_physical{121.0}=0x63027415 +phy_chain_tx_lane_map_physical{121.0}=0x63721045 +phy_chain_rx_lane_map_physical{129.0}=0x30154627 +phy_chain_tx_lane_map_physical{129.0}=0x04735261 +phy_chain_rx_lane_map_physical{137.0}=0x24753061 +phy_chain_tx_lane_map_physical{137.0}=0x37614520 +phy_chain_rx_lane_map_physical{145.0}=0x47601352 +phy_chain_tx_lane_map_physical{145.0}=0x63274510 +phy_chain_rx_lane_map_physical{153.0}=0x07361524 +phy_chain_tx_lane_map_physical{153.0}=0x36527104 +phy_chain_rx_lane_map_physical{225.0}=0x56410273 +phy_chain_tx_lane_map_physical{225.0}=0x10274635 +phy_chain_rx_lane_map_physical{233.0}=0x15740263 +phy_chain_tx_lane_map_physical{233.0}=0x24351607 +phy_chain_rx_lane_map_physical{241.0}=0x74015263 +phy_chain_tx_lane_map_physical{241.0}=0x04152637 +phy_chain_rx_lane_map_physical{249.0}=0x62037514 +phy_chain_tx_lane_map_physical{249.0}=0x72453160 +phy_chain_rx_lane_map_physical{161.0}=0x46510273 +phy_chain_tx_lane_map_physical{161.0}=0x01653724 +phy_chain_rx_lane_map_physical{169.0}=0x25743160 +phy_chain_tx_lane_map_physical{169.0}=0x07216435 +phy_chain_rx_lane_map_physical{177.0}=0x46510273 +phy_chain_tx_lane_map_physical{177.0}=0x01652734 +phy_chain_rx_lane_map_physical{185.0}=0x25743160 +phy_chain_tx_lane_map_physical{185.0}=0x37016425 +phy_chain_rx_lane_map_physical{193.0}=0x46510372 +phy_chain_tx_lane_map_physical{193.0}=0x06153724 +phy_chain_rx_lane_map_physical{201.0}=0x25743160 +phy_chain_tx_lane_map_physical{201.0}=0x36017524 +phy_chain_rx_lane_map_physical{209.0}=0x47601352 +phy_chain_tx_lane_map_physical{209.0}=0x04152736 +phy_chain_rx_lane_map_physical{217.0}=0x26453170 +phy_chain_tx_lane_map_physical{217.0}=0x36027415 + +serdes_core_rx_polarity_flip_physical{33}=0x29 +serdes_core_tx_polarity_flip_physical{33}=0xfe +serdes_core_rx_polarity_flip_physical{41}=0xb1 +serdes_core_tx_polarity_flip_physical{41}=0xe8 +serdes_core_rx_polarity_flip_physical{49}=0xca +serdes_core_tx_polarity_flip_physical{49}=0xb6 +serdes_core_rx_polarity_flip_physical{57}=0x9b +serdes_core_tx_polarity_flip_physical{57}=0xdc +serdes_core_rx_polarity_flip_physical{65}=0x17 +serdes_core_tx_polarity_flip_physical{65}=0x86 +serdes_core_rx_polarity_flip_physical{73}=0x9b +serdes_core_tx_polarity_flip_physical{73}=0x55 +serdes_core_rx_polarity_flip_physical{81}=0xa +serdes_core_tx_polarity_flip_physical{81}=0x6 +serdes_core_rx_polarity_flip_physical{89}=0x9b +serdes_core_tx_polarity_flip_physical{89}=0x48 +serdes_core_rx_polarity_flip_physical{1}=0xec +serdes_core_tx_polarity_flip_physical{1}=0x56 +serdes_core_rx_polarity_flip_physical{9}=0x13 +serdes_core_tx_polarity_flip_physical{9}=0xa6 +serdes_core_rx_polarity_flip_physical{17}=0x5a +serdes_core_tx_polarity_flip_physical{17}=0xc6 +serdes_core_rx_polarity_flip_physical{25}=0xf +serdes_core_tx_polarity_flip_physical{25}=0x4e +serdes_core_rx_polarity_flip_physical{97}=0x17 +serdes_core_tx_polarity_flip_physical{97}=0x2e +serdes_core_rx_polarity_flip_physical{105}=0xce +serdes_core_tx_polarity_flip_physical{105}=0x7c +serdes_core_rx_polarity_flip_physical{113}=0xa +serdes_core_tx_polarity_flip_physical{113}=0x35 + +serdes_core_rx_polarity_flip_physical{121}=0xb9 +serdes_core_tx_polarity_flip_physical{121}=0xef +serdes_core_rx_polarity_flip_physical{129}=0xe8 +serdes_core_tx_polarity_flip_physical{129}=0xac +serdes_core_rx_polarity_flip_physical{137}=0xcb +serdes_core_tx_polarity_flip_physical{137}=0x9c +serdes_core_rx_polarity_flip_physical{145}=0x17 +serdes_core_tx_polarity_flip_physical{145}=0x32 +serdes_core_rx_polarity_flip_physical{153}=0xb9 +serdes_core_tx_polarity_flip_physical{153}=0xaf +serdes_core_rx_polarity_flip_physical{225}=0xaa +serdes_core_tx_polarity_flip_physical{225}=0x7 +serdes_core_rx_polarity_flip_physical{233}=0x31 +serdes_core_tx_polarity_flip_physical{233}=0x47 +serdes_core_rx_polarity_flip_physical{241}=0xe8 +serdes_core_tx_polarity_flip_physical{241}=0x9e +serdes_core_rx_polarity_flip_physical{249}=0xec +serdes_core_tx_polarity_flip_physical{249}=0x1f +serdes_core_rx_polarity_flip_physical{161}=0x6a +serdes_core_tx_polarity_flip_physical{161}=0xd4 +serdes_core_rx_polarity_flip_physical{169}=0x9e +serdes_core_tx_polarity_flip_physical{169}=0x7b +serdes_core_rx_polarity_flip_physical{177}=0x6a +serdes_core_tx_polarity_flip_physical{177}=0xcc +serdes_core_rx_polarity_flip_physical{185}=0x9e +serdes_core_tx_polarity_flip_physical{185}=0x58 +serdes_core_rx_polarity_flip_physical{193}=0x6f +serdes_core_tx_polarity_flip_physical{193}=0x24 +serdes_core_rx_polarity_flip_physical{201}=0x9e +serdes_core_tx_polarity_flip_physical{201}=0xdf +serdes_core_rx_polarity_flip_physical{209}=0x17 +serdes_core_tx_polarity_flip_physical{209}=0xe9 +serdes_core_rx_polarity_flip_physical{217}=0xec +serdes_core_tx_polarity_flip_physical{217}=0x68 + +dport_map_port_20=1 +dport_map_port_24=2 +dport_map_port_28=3 +dport_map_port_32=4 +dport_map_port_40=5 +dport_map_port_44=6 +dport_map_port_48=7 +dport_map_port_52=8 +dport_map_port_1=9 +dport_map_port_5=10 +dport_map_port_9=11 +dport_map_port_13=12 +dport_map_port_60=13 +dport_map_port_64=14 +dport_map_port_68=15 +dport_map_port_72=16 +dport_map_port_80=17 +dport_map_port_84=18 +dport_map_port_88=19 +dport_map_port_92=20 +dport_map_port_140=21 +dport_map_port_144=22 +dport_map_port_148=23 +dport_map_port_152=24 +dport_map_port_100=25 +dport_map_port_104=26 +dport_map_port_108=27 +dport_map_port_112=28 +dport_map_port_120=29 +dport_map_port_124=30 +dport_map_port_128=31 +dport_map_port_132=32 + +#dport_map_port_38=33 +#dport_map_port_118=34 + + + +core_clock_frequency=1325 +dpr_clock_frequency=1000 +device_clock_frequency=1325 +port_flex_enable=1 + +#firmware load method, use fast load +load_firmware=0x2 + + diff --git a/device/celestica/x86_64-cel_silverstone-r0/custom.bin b/device/celestica/x86_64-cel_silverstone-r0/custom.bin new file mode 100644 index 000000000000..a08ba6c06661 Binary files /dev/null and b/device/celestica/x86_64-cel_silverstone-r0/custom.bin differ diff --git a/device/celestica/x86_64-cel_silverstone-r0/default_sku b/device/celestica/x86_64-cel_silverstone-r0/default_sku new file mode 100644 index 000000000000..07d986a8431d --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/default_sku @@ -0,0 +1 @@ +Silverstone t1 diff --git a/device/celestica/x86_64-cel_silverstone-r0/installer.conf b/device/celestica/x86_64-cel_silverstone-r0/installer.conf new file mode 100644 index 000000000000..5e62742c11bf --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/installer.conf @@ -0,0 +1 @@ +CONSOLE_SPEED=115200 diff --git a/device/celestica/x86_64-cel_silverstone-r0/led_proc_init.soc b/device/celestica/x86_64-cel_silverstone-r0/led_proc_init.soc new file mode 100644 index 000000000000..827458afefbe --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/led_proc_init.soc @@ -0,0 +1,2 @@ +#The Port LED of Silverstone SONIC can't work well, after the issue is fixed by SAI, The led will start. +#led auto on; led start diff --git a/device/celestica/x86_64-cel_silverstone-r0/linkscan_fw.bin b/device/celestica/x86_64-cel_silverstone-r0/linkscan_fw.bin new file mode 100644 index 000000000000..e86cdc1ef647 Binary files /dev/null and b/device/celestica/x86_64-cel_silverstone-r0/linkscan_fw.bin differ diff --git a/device/celestica/x86_64-cel_silverstone-r0/plugins/eeprom.py b/device/celestica/x86_64-cel_silverstone-r0/plugins/eeprom.py new file mode 100644 index 000000000000..34c50a6ce31f --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/plugins/eeprom.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica Silverstone +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0056/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) + diff --git a/device/celestica/x86_64-cel_silverstone-r0/plugins/psuutil.py b/device/celestica/x86_64-cel_silverstone-r0/plugins/psuutil.py new file mode 100644 index 000000000000..d5e197e82d2b --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/plugins/psuutil.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python + +import os.path +import subprocess +import sys +import re + +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): + self.ipmi_raw = "docker exec -ti pmon ipmitool raw 0x4 0x2d" + self.psu1_id = "0x2f" + self.psu2_id = "0x39" + PsuBase.__init__(self) + + def run_command(self, command): + proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) + (out, err) = proc.communicate() + + if proc.returncode != 0: + sys.exit(proc.returncode) + + return out + + def find_value(self, in_string): + result = re.search("^.+ ([0-9a-f]{2}) .+$", in_string) + if result: + return result.group(1) + else: + return result + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + return 2 + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by 1-based index + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is faulty + """ + if index is None: + return False + + psu_id = self.psu1_id if index == 1 else self.psu2_id + res_string = self.run_command(self.ipmi_raw + ' ' + psu_id) + status_byte = self.find_value(res_string) + + if status_byte is None: + return False + + failure_detected = (int(status_byte, 16) >> 1) & 1 + input_lost = (int(status_byte, 16) >> 3) & 1 + if failure_detected or input_lost: + return False + else: + return True + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by 1-based index + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + if index is None: + return False + + psu_id = self.psu1_id if index == 1 else self.psu2_id + res_string = self.run_command(self.ipmi_raw + ' ' + psu_id) + status_byte = self.find_value(res_string) + + if status_byte is None: + return False + + presence = ( int(status_byte, 16) >> 0 ) & 1 + if presence: + return True + else: + return False \ No newline at end of file diff --git a/device/celestica/x86_64-cel_silverstone-r0/plugins/sfputil.py b/device/celestica/x86_64-cel_silverstone-r0/plugins/sfputil.py new file mode 100755 index 000000000000..33b761b9397a --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/plugins/sfputil.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python +# +# Platform-specific SFP transceiver interface for SONiC +# This plugin supports QSFP-DD, QSFP and SFP. + +try: + import time + 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 = 1 + PORT_END = 34 + OSFP_PORT_START = 1 + OSFP_PORT_END = 32 + SFP_PORT_START = 33 + SFP_PORT_END = 34 + + EEPROM_OFFSET = 9 + PORT_INFO_PATH = '/sys/class/silverstone_fpga' + + _port_name = "" + _port_to_eeprom_mapping = {} + _port_to_i2cbus_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 [] + + @property + def osfp_ports(self): + return range(self.OSFP_PORT_START, self.OSFP_PORT_END + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + @property + def port_to_i2cbus_mapping(self): + return self._port_to_i2cbus_mapping + + def get_port_name(self, port_num): + if port_num in self.osfp_ports: + self._port_name = "QSFP" + str(port_num - self.OSFP_PORT_START + 1) + else: + self._port_name = "SFP" + str(port_num - self.SFP_PORT_START + 1) + return self._port_name + + def get_eeprom_dom_raw(self, port_num): + if port_num in self.osfp_ports: + # QSFP DOM EEPROM is also at addr 0x50 and thus also stored in eeprom_ifraw + return None + else: + # Read dom eeprom at addr 0x51 + return self._read_eeprom_devid(port_num, self.DOM_EEPROM_ADDR, 256) + + def __init__(self): + # Override port_to_eeprom_mapping for class initialization + eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' + + for x in range(self.PORT_START, self.PORT_END+1): + self.port_to_i2cbus_mapping[x] = (x + self.EEPROM_OFFSET) + 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 not in range(self.port_start, self.port_end + 1): + return False + + # Get path for access port presence status + port_name = self.get_port_name(port_num) + sysfs_filename = "qsfp_modprs" if port_num in self.osfp_ports else "sfp_modabs" + reg_path = "/".join([self.PORT_INFO_PATH, port_name, sysfs_filename]) + + # Read status + try: + reg_file = open(reg_path) + content = reg_file.readline().rstrip() + reg_value = int(content) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + # Module present is active low + if reg_value == 0: + return True + + return False + + def get_low_power_mode(self, port_num): + # Check for invalid QSFP port_num + if port_num not in self.osfp_ports: + return False + + try: + port_name = self.get_port_name(port_num) + reg_file = open("/".join([self.PORT_INFO_PATH, + port_name, "qsfp_lpmode"])) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + # Read status + content = reg_file.readline().rstrip() + reg_value = int(content) + # low power mode is active high + if reg_value == 0: + return False + + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid QSFP port_num + if port_num not in self.osfp_ports: + return False + + try: + port_name = self.get_port_name(port_num) + reg_file = open("/".join([self.PORT_INFO_PATH, + port_name, "qsfp_lpmode"]), "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = hex(lpmode) + + reg_file.seek(0) + reg_file.write(content) + reg_file.close() + + return True + + def reset(self, port_num): + # Check for invalid QSFP port_num + if port_num not in self.osfp_ports: + return False + + try: + port_name = self.get_port_name(port_num) + reg_file = open("/".join([self.PORT_INFO_PATH, + port_name, "qsfp_reset"]), "w") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + # Convert our register value back to a hex string and write back + reg_file.seek(0) + reg_file.write(hex(0)) + 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( + "/".join([self.PORT_INFO_PATH, port_name, "qsfp_reset"]), "w") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_file.seek(0) + reg_file.write(hex(1)) + reg_file.close() + + return True + + def get_transceiver_change_event(self, timeout=0): + """ + TBD + """ + raise NotImplementedError diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/__init__.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/__init__.py new file mode 100644 index 000000000000..d82f3749319c --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["platform", "chassis"] +from sonic_platform import * diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py new file mode 100644 index 000000000000..dc622016cbb2 --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Chassis information which are available in the platform +# +############################################################################# + +import sys +import re +import os +import subprocess +import json + +try: + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.eeprom import Tlv + from sonic_platform.fan import Fan + from helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +NUM_FAN_TRAY = 7 +NUM_FAN = 2 +NUM_PSU = 2 +NUM_THERMAL = 5 +NUM_SFP = 32 +NUM_COMPONENT = 5 + +IPMI_OEM_NETFN = "0x3A" +IPMI_GET_REBOOT_CAUSE = "0x03 0x00 0x01 0x06" + + +class Chassis(ChassisBase): + """Platform-specific Chassis class""" + + def __init__(self): + self.config_data = {} + ChassisBase.__init__(self) + self._eeprom = Tlv() + self._api_helper = APIHelper() + + for fant_index in range(0, NUM_FAN_TRAY): + for fan_index in range(0, NUM_FAN): + fan = Fan(fant_index, fan_index) + self._fan_list.append(fan) + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.get_mac() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.get_serial() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self._eeprom.get_eeprom() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + + status, raw_cause = self._api_helper.ipmi_raw( + IPMI_OEM_NETFN, IPMI_GET_REBOOT_CAUSE) + hx_cause = raw_cause.split()[0] if status else 00 + reboot_cause = { + "00": self.REBOOT_CAUSE_HARDWARE_OTHER, + "11": self.REBOOT_CAUSE_POWER_LOSS, + "22": self.REBOOT_CAUSE_NON_HARDWARE, + "33": self.REBOOT_CAUSE_HARDWARE_OTHER, + "44": self.REBOOT_CAUSE_NON_HARDWARE, + "55": self.REBOOT_CAUSE_NON_HARDWARE, + "66": self.REBOOT_CAUSE_WATCHDOG, + "77": self.REBOOT_CAUSE_NON_HARDWARE + }.get(hx_cause, self.REBOOT_CAUSE_HARDWARE_OTHER) + + description = { + "00": "Unknown reason", + "11": "The last reset is Power on reset", + "22": "The last reset is soft-set CPU warm reset", + "33": "The last reset is soft-set CPU cold reset", + "44": "The last reset is CPU warm reset", + "55": "The last reset is CPU cold reset", + "66": "The last reset is watchdog reset", + "77": "The last reset is power cycle reset" + }.get(hx_cause, "Unknown reason") + + return (reboot_cause, description) diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/eeprom.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/eeprom.py new file mode 100644 index 000000000000..dd0c9332b54e --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/eeprom.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica Silverstone +# +# 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 glob + import os + import sys + import imp + import re + from array import array + from cStringIO import StringIO + from sonic_platform_base.sonic_eeprom import eeprom_dts + from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError(str(e) + "- required module not found") + +CACHE_ROOT = '/var/cache/sonic/decode-syseeprom' +CACHE_FILE = 'syseeprom_cache' +TLV_EEPROM_I2C_BUS = 0 +TLV_EEPROM_I2C_ADDR = 56 + +class Tlv(eeprom_tlvinfo.TlvInfoDecoder): + + EEPROM_DECODE_HEADLINES = 6 + + def __init__(self): + self._eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-00{1}/eeprom".format(TLV_EEPROM_I2C_BUS, TLV_EEPROM_I2C_ADDR) + super(Tlv, self).__init__(self._eeprom_path, 0, '', True) + self._eeprom = self._load_eeprom() + + def __parse_output(self, decode_output): + decode_output.replace('\0', '') + lines = decode_output.split('\n') + lines = lines[self.EEPROM_DECODE_HEADLINES:] + _eeprom_info_dict = dict() + + for line in lines: + try: + match = re.search( + '(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+)', line) + if match is not None: + idx = match.group(1) + value = match.group(3).rstrip('\0') + + _eeprom_info_dict[idx] = value + except: + pass + return _eeprom_info_dict + + def _load_eeprom(self): + original_stdout = sys.stdout + sys.stdout = StringIO() + try: + self.read_eeprom_db() + except: + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + return self.__parse_output(decode_output) + + status = self.check_status() + if 'ok' not in status: + return False + + if not os.path.exists(CACHE_ROOT): + try: + os.makedirs(CACHE_ROOT) + except: + pass + + # + # only the eeprom classes that inherit from eeprom_base + # support caching. Others will work normally + # + try: + self.set_cache_name(os.path.join(CACHE_ROOT, CACHE_FILE)) + except: + pass + + e = self.read_eeprom() + if e is None: + return 0 + + try: + self.update_cache(e) + except: + pass + + self.decode_eeprom(e) + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + + (is_valid, valid_crc) = self.is_checksum_valid(e) + if not is_valid: + return False + + return self.__parse_output(decode_output) + + def get_eeprom(self): + return self._eeprom + + def get_serial(self): + return self._eeprom.get('0x23', "Undefined.") + + def get_mac(self): + return self._eeprom.get('0x24', "Undefined.") diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/fan.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/fan.py new file mode 100644 index 000000000000..902de261f8cb --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/fan.py @@ -0,0 +1,276 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the fan status which are available in the platform +# +############################################################################# + +import json +import math +import os.path + +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") + + +FAN_NAME_LIST = ["FAN-1F", "FAN-1R", "FAN-2F", "FAN-2R", "FAN-3F", "FAN-3R", + "FAN-4F", "FAN-4R", "FAN-5F", "FAN-5R", "FAN-6F", "FAN-6R", "FAN-7F", "FAN-7R"] + +IPMI_OEM_NETFN = "0x3A" +IPMI_SENSOR_NETFN = "0x04" +IPMI_FAN_SPEED_CMD = "0x2D {}" +IPMI_AIR_FLOW_CMD = "0x0A {}" +IPMI_FAN_PRESENT_CMD = "0x06 0x03 {}" +IPMI_SET_FAN_LED_CMD = "0x07 {} {}" +IPMI_GET_FAN_LED_CMD = "0x08 {}" +IPMI_SET_PWM = "0x03 0x01 0x02 {} {}" +IPMI_FRU_PRINT_ID = "ipmitool fru print {}" +IPMI_FRU_MODEL_KEY = "Board Part Number" +IPMI_FRU_SERIAL_KEY = "Board Serial" + +MAX_OUTLET = 24700 +MAX_INLET = 29700 +SPEED_TOLERANCE = 10 + +FAN1_FRONT_SS_ID = "0x0D" +FAN1_REAR_SS_ID = "0x45" +FAN_LED_OFF_CMD = "0x00" +FAN_LED_GREEN_CMD = "0x01" +FAN_LED_RED_CMD = "0x02" +FAN1_LED_CMD = "0x04" +FAN_PWM_REGISTER_START = 0x22 +FAN_PWM_REGISTER_STEP = 0x10 +FAN1_FRU_ID = 6 + + +class Fan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0): + self.fan_index = fan_index + self.fan_tray_index = fan_tray_index + self.is_psu_fan = is_psu_fan + if self.is_psu_fan: + self.psu_index = psu_index + self._api_helper = APIHelper() + self.index = self.fan_tray_index * 2 + self.fan_index + + def get_direction(self): + """ + Retrieves the direction of fan + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + direction = self.FAN_DIRECTION_EXHAUST + status, raw_flow = self._api_helper.ipmi_raw( + IPMI_OEM_NETFN, IPMI_AIR_FLOW_CMD.format(hex(self.fan_tray_index))) + if status and raw_flow == "01": + direction = self.FAN_DIRECTION_INTAKE + + return direction + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + + Note: + M = 150 + Max F2B = 24700 RPM + Max B2F = 29700 RPM + """ + # ipmitool raw 0x3a 0x03 0x01 0x01 {register} + # register = 22 32 42 52 62 72 82 + + max_rpm = MAX_OUTLET if self.fan_index % 2 == 0 else MAX_INLET + fan1_ss_start = FAN1_FRONT_SS_ID if self.fan_index % 2 == 0 else FAN1_REAR_SS_ID + + ss_id = hex(int(fan1_ss_start, 16) + self.fan_tray_index) + status, raw_ss_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_FAN_SPEED_CMD.format(ss_id)) + + ss_read = raw_ss_read.split()[0] + rpm_speed = int(ss_read, 16)*150 + speed = int(float(rpm_speed)/max_rpm * 100) + + return speed + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + + Note: + speed_pc = pwm_target/255*100 + + 0 : when PWM mode is use + pwm : when pwm mode is not use + """ + target = 0 + return target + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + return SPEED_TOLERANCE + + def set_speed(self, speed): + """ + Sets the fan speed + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + Returns: + A boolean, True if speed is set successfully, False if not + Notes: + pwm setting mode must set as Manual + manual: ipmitool raw 0x3a 0x06 0x01 0x0 + auto: ipmitool raw 0x3a 0x06 0x01 0x1 + """ + # ipmitool raw 0x3a 0x03 0x01 0x02 {register} {pwm_speed} + # register = 22 32 42 52 62 72 82 + + speed_hex = hex(int(float(speed)/100 * 255)) + fan_register_hex = hex(FAN_PWM_REGISTER_START + + (self.fan_tray_index*FAN_PWM_REGISTER_STEP)) + + set_speed_cmd = IPMI_SET_PWM.format(fan_register_hex, speed_hex) + status, set_speed_res = self._api_helper.ipmi_raw( + IPMI_OEM_NETFN, set_speed_cmd) + + set_speed = False if not status else True + + return set_speed + + def set_status_led(self, color): + """ + Sets the state of the fan module status LED + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if status LED state is set successfully, False if not + + Note: + LED setting mode must set as Manual + manual: ipmitool raw 0x3A 0x09 0x02 0x00 + auto: ipmitool raw 0x3A 0x09 0x02 0x01 + """ + led_cmd = { + self.STATUS_LED_COLOR_GREEN: FAN_LED_GREEN_CMD, + self.STATUS_LED_COLOR_RED: FAN_LED_RED_CMD, + self.STATUS_LED_COLOR_OFF: FAN_LED_OFF_CMD + }.get(color) + + fan_selector = hex(int(FAN1_LED_CMD, 16) + self.fan_tray_index) + status, set_led = self._api_helper.ipmi_raw( + IPMI_OEM_NETFN, IPMI_SET_FAN_LED_CMD.format(fan_selector, led_cmd)) + set_status_led = False if not status else True + + return set_status_led + + def get_status_led(self): + """ + Gets the state of the fan status LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + + Note: + STATUS_LED_COLOR_GREEN = "green" + STATUS_LED_COLOR_AMBER = "amber" + STATUS_LED_COLOR_RED = "red" + STATUS_LED_COLOR_OFF = "off" + """ + fan_selector = hex(int(FAN1_LED_CMD, 16) + self.fan_tray_index) + status, hx_color = self._api_helper.ipmi_raw( + IPMI_OEM_NETFN, IPMI_GET_FAN_LED_CMD.format(fan_selector)) + + status_led = { + "00": self.STATUS_LED_COLOR_OFF, + "01": self.STATUS_LED_COLOR_GREEN, + "02": self.STATUS_LED_COLOR_RED, + }.get(hx_color, self.STATUS_LED_COLOR_OFF) + + return status_led + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + fan_name = FAN_NAME_LIST[self.fan_tray_index*2 + self.fan_index] if not self.is_psu_fan else "PSU-{} FAN-{}".format( + self.psu_index+1, self.fan_index+1) + + return fan_name + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if FAN is present, False if not + """ + presence = False + status, raw_present = self._api_helper.ipmi_raw( + IPMI_OEM_NETFN, IPMI_FAN_PRESENT_CMD.format(hex(self.index))) + if status and raw_present == "00": + presence = True + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + model = "Unknown" + ipmi_fru_idx = self.fan_tray_index + FAN1_FRU_ID + status, raw_model = self._api_helper.ipmi_fru_id( + ipmi_fru_idx, IPMI_FRU_MODEL_KEY) + + fru_pn_list = raw_model.split() + if len(fru_pn_list) > 4: + model = fru_pn_list[4] + + return model + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + serial = "Unknown" + ipmi_fru_idx = self.fan_tray_index + FAN1_FRU_ID + status, raw_model = self._api_helper.ipmi_fru_id( + ipmi_fru_idx, IPMI_FRU_SERIAL_KEY) + + fru_sr_list = raw_model.split() + if len(fru_sr_list) > 3: + serial = fru_sr_list[3] + + 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_silverstone-r0/sonic_platform/helper.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/helper.py new file mode 100644 index 000000000000..1132b5b06785 --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/helper.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python + +import os +import subprocess + + +HOST_CHK_CMD = "docker > /dev/null 2>&1" +EMPTY_STRING = "" + + +class APIHelper(): + + def __init__(self): + pass + + 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 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() + 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() + except: + status = False + return status, result diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/platform.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/platform.py new file mode 100644 index 000000000000..a632de87e742 --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/platform.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + """Platform-specific Platform class""" + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/media_settings.json b/device/dell/x86_64-dell_s6000_s1220-r0/media_settings.json new file mode 100644 index 000000000000..9032a2e53b26 --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/media_settings.json @@ -0,0 +1,1348 @@ +{ + "PORT_MEDIA_SETTINGS": { + "0": { + "Default": { + "preemphasis": { + "lane0":"0xcad0", + "lane1":"0xc6e0", + "lane2":"0xc6e0", + "lane3":"0xd2b0" + }, + "idriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + }, + "ipredriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + }, + "ipredriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + } + } + }, + "1": { + "Default": { + "preemphasis": { + "lane0":"0xc2f0", + "lane1":"0xd2b0", + "lane2":"0xc6e0", + "lane3":"0xc2f0" + }, + "idriver": { + "lane0":"0x6", + "lane1":"0x7", + "lane2":"0x6", + "lane3":"0x6" + }, + "ipredriver": { + "lane0":"0x6", + "lane1":"0x7", + "lane2":"0x6", + "lane3":"0x6" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x6", + "lane1":"0x7", + "lane2":"0x6", + "lane3":"0x6" + }, + "ipredriver": { + "lane0":"0x6", + "lane1":"0x7", + "lane2":"0x6", + "lane3":"0x6" + } + } + }, + "2": { + "Default": { + "preemphasis": { + "lane0":"0xc6e0", + "lane1":"0xc6e0", + "lane2":"0xc6e0", + "lane3":"0xc6e0" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + } + }, + "3": { + "Default": { + "preemphasis": { + "lane0":"0xcad0", + "lane1":"0xcad0", + "lane2":"0xc2f0", + "lane3":"0xc2f0" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + } + }, + "4": { + "Default": { + "preemphasis": { + "lane0":"0xc2f0", + "lane1":"0xc2f0", + "lane2":"0xc2f0", + "lane3":"0xc2f0" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + } + }, + "5": { + "Default": { + "preemphasis": { + "lane0":"0xc6e0", + "lane1":"0xc2f0", + "lane2":"0xc2f0", + "lane3":"0xcad0" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + } + }, + "6": { + "Default": { + "preemphasis": { + "lane0":"0xc6e0", + "lane1":"0xcad0", + "lane2":"0xc6e0", + "lane3":"0xcad0" + }, + "idriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + }, + "ipredriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + }, + "ipredriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + } + } + }, + "7": { + "Default": { + "preemphasis": { + "lane0":"0xc6e0", + "lane1":"0xc6e0", + "lane2":"0xc6e0", + "lane3":"0xc6e0" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + } + }, + "8": { + "Default": { + "preemphasis": { + "lane0":"0xb270", + "lane1":"0xbb10", + "lane2":"0xb720", + "lane3":"0xb720" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x3", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x3", + "lane2":"0x2", + "lane3":"0x2" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xea05", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x3", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x3", + "lane2":"0x2", + "lane3":"0x2" + } + } + }, + "9": { + "Default": { + "preemphasis": { + "lane0":"0xc2f0", + "lane1":"0xc6e0", + "lane2":"0xbf00", + "lane3":"0xc2f0" + }, + "idriver": { + "lane0":"0x3", + "lane1":"0x3", + "lane2":"0x3", + "lane3":"0x3" + }, + "ipredriver": { + "lane0":"0x3", + "lane1":"0x3", + "lane2":"0x3", + "lane3":"0x3" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x3", + "lane1":"0x3", + "lane2":"0x3", + "lane3":"0x3" + }, + "ipredriver": { + "lane0":"0x3", + "lane1":"0x3", + "lane2":"0x3", + "lane3":"0x3" + } + } + }, + "10": { + "Default": { + "preemphasis": { + "lane0":"0xb330", + "lane1":"0xbb10", + "lane2":"0xbb10", + "lane3":"0xbb10" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + } + }, + "11": { + "Default": { + "preemphasis": { + "lane0":"0xb330", + "lane1":"0xb330", + "lane2":"0xb330", + "lane3":"0xb330" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + } + }, + "12": { + "Default": { + "preemphasis": { + "lane0":"0xaf40", + "lane1":"0xaf40", + "lane2":"0xaf40", + "lane3":"0xaf40" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + } + }, + "13": { + "Default": { + "preemphasis": { + "lane0":"0xa760", + "lane1":"0xa760", + "lane2":"0xa760", + "lane3":"0xa760" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + } + }, + "14": { + "Default": { + "preemphasis": { + "lane0":"0xa760", + "lane1":"0xa760", + "lane2":"0xa760", + "lane3":"0xa760" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + } + } + }, + "15": { + "Default": { + "preemphasis": { + "lane0":"0xa760", + "lane1":"0xa760", + "lane2":"0xa760", + "lane3":"0xa760" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + } + }, + "16": { + "Default": { + "preemphasis": { + "lane0":"0xa760", + "lane1":"0xa760", + "lane2":"0xa760", + "lane3":"0xa760" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + } + } + }, + "17": { + "Default": { + "preemphasis": { + "lane0":"0xa370", + "lane1":"0xa370", + "lane2":"0xa370", + "lane3":"0xa370" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + } + } + }, + "18": { + "Default": { + "preemphasis": { + "lane0":"0xa760", + "lane1":"0xa760", + "lane2":"0xa760", + "lane3":"0xa760" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + } + }, + "19": { + "Default": { + "preemphasis": { + "lane0":"0xaf40", + "lane1":"0xaf40", + "lane2":"0xaf40", + "lane3":"0xaf40" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + } + }, + "20": { + "Default": { + "preemphasis": { + "lane0":"0xb330", + "lane1":"0xb330", + "lane2":"0xb330", + "lane3":"0xbff0" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x2" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x2" + } + } + }, + "21": { + "Default": { + "preemphasis": { + "lane0":"0xb330", + "lane1":"0xb330", + "lane2":"0xb330", + "lane3":"0xb330" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + } + } + }, + "22": { + "Default": { + "preemphasis": { + "lane0":"0xbb10", + "lane1":"0xbb10", + "lane2":"0xbb10", + "lane3":"0xc2f0" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + }, + "ipredriver": { + "lane0":"0x1", + "lane1":"0x1", + "lane2":"0x1", + "lane3":"0x1" + } + } + }, + "23": { + "Default": { + "preemphasis": { + "lane0":"0xc6e0", + "lane1":"0xc6e0", + "lane2":"0xc6e0", + "lane3":"0xc6e0" + }, + "idriver": { + "lane0":"0x3", + "lane1":"0x5", + "lane2":"0x3", + "lane3":"0x3" + }, + "ipredriver": { + "lane0":"0x3", + "lane1":"0x5", + "lane2":"0x3", + "lane3":"0x3" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x3", + "lane1":"0x5", + "lane2":"0x3", + "lane3":"0x3" + }, + "ipredriver": { + "lane0":"0x3", + "lane1":"0x5", + "lane2":"0x3", + "lane3":"0x3" + } + } + }, + "24": { + "Default": { + "preemphasis": { + "lane0":"0xc6e0", + "lane1":"0xc6e0", + "lane2":"0xc6e0", + "lane3":"0xcec0" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + } + }, + "25": { + "Default": { + "preemphasis": { + "lane0":"0xc6e0", + "lane1":"0xc6e0", + "lane2":"0xc6e0", + "lane3":"0xc6c0" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + } + }, + "26": { + "Default": { + "preemphasis": { + "lane0":"0xbb10", + "lane1":"0xbb10", + "lane2":"0xbf00", + "lane3":"0xbb10" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + }, + "ipredriver": { + "lane0":"0x2", + "lane1":"0x2", + "lane2":"0x2", + "lane3":"0x2" + } + } + }, + "27": { + "Default": { + "preemphasis": { + "lane0":"0xc2f0", + "lane1":"0xc6e0", + "lane2":"0xc6e0", + "lane3":"0xc6e0" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x5", + "lane2":"0x4", + "lane3":"0x5" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x5", + "lane2":"0x4", + "lane3":"0x5" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x5", + "lane2":"0x4", + "lane3":"0x5" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x5", + "lane2":"0x4", + "lane3":"0x5" + } + } + }, + "28": { + "Default": { + "preemphasis": { + "lane0":"0xc2f0", + "lane1":"0xc2f0", + "lane2":"0xc2f0", + "lane3":"0xc2f0" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xe225", + "lane1":"0xe225", + "lane2":"0xe225", + "lane3":"0xe225" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + } + }, + "29": { + "Default": { + "preemphasis": { + "lane0":"0xcad0", + "lane1":"0xc6e0", + "lane2":"0xc6e0", + "lane3":"0xc6e0" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + }, + "ipredriver": { + "lane0":"0x4", + "lane1":"0x4", + "lane2":"0x4", + "lane3":"0x4" + } + } + }, + "30": { + "Default": { + "preemphasis": { + "lane0":"0xcec0", + "lane1":"0xcec0", + "lane2":"0xcad0", + "lane3":"0xc6e0" + }, + "idriver": { + "lane0":"0x6", + "lane1":"0x6", + "lane2":"0x6", + "lane3":"0x7" + }, + "ipredriver": { + "lane0":"0x6", + "lane1":"0x6", + "lane2":"0x6", + "lane3":"0x7" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x6", + "lane1":"0x6", + "lane2":"0x6", + "lane3":"0x7" + }, + "ipredriver": { + "lane0":"0x6", + "lane1":"0x6", + "lane2":"0x6", + "lane3":"0x7" + } + } + }, + "31": { + "Default": { + "preemphasis": { + "lane0":"0xcad0", + "lane1":"0xcad0", + "lane2":"0xcad0", + "lane3":"0xcad0" + }, + "idriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + }, + "ipredriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + } + }, + "QSFP+-40GBASE-CR4-3M": { + "preemphasis": { + "lane0":"0xea05", + "lane1":"0xea05", + "lane2":"0xea05", + "lane3":"0xea05" + }, + "idriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + }, + "ipredriver": { + "lane0":"0x5", + "lane1":"0x5", + "lane2":"0x5", + "lane3":"0x5" + } + } + } + } +} diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t0.j2 b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t0.j2 index f949a31eab7b..8f55022973fb 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t0.j2 +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t0.j2 @@ -36,7 +36,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t1.j2 b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t1.j2 index e56bbb65845f..47a9c81f0796 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t1.j2 +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t1.j2 @@ -36,7 +36,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t0.config.bcm b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t0.config.bcm index 2820853905ec..adbef9387eda 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t0.config.bcm +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t0.config.bcm @@ -27,8 +27,6 @@ os=unix parity_correction=1 parity_enable=1 -port_phy_addr_66=0x176 -port_phy_addr_100=0x177 xgxs_tx_lane_map_104=0x3210 xgxs_rx_lane_map_104=0x0312 phy_xaui_tx_polarity_flip_104=0x0 @@ -340,8 +338,6 @@ phy_xaui_rx_polarity_flip_79=0x3 dport_map_port_78=63 dport_map_port_79=64 pbmp_xport_xe=0x3fffd0000ffff40003fffc0001fffe -portmap_66=129:10 -portmap_100=131:10 portmap_33=132:10 portmap_67=133:10 portmap_101=134:10 @@ -410,7 +406,5 @@ portmap_114=121:40:2 portmap_115=123:40:2 portmap_116=125:40:2 portmap_117=127:40:2 -dport_map_port_66=65 -dport_map_port_100=66 mmu_init_config="MSFT-TH-Tier0" diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t1.config.bcm b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t1.config.bcm index df22bcf23ed1..f9dc619849d0 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t1.config.bcm +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/th-s6100-64x40G-t1.config.bcm @@ -27,8 +27,6 @@ os=unix parity_correction=1 parity_enable=1 -port_phy_addr_66=0x176 -port_phy_addr_100=0x177 xgxs_tx_lane_map_104=0x3210 xgxs_rx_lane_map_104=0x0312 phy_xaui_tx_polarity_flip_104=0x0 @@ -340,8 +338,6 @@ phy_xaui_rx_polarity_flip_79=0x3 dport_map_port_78=63 dport_map_port_79=64 pbmp_xport_xe=0x3fffd0000ffff40003fffc0001fffe -portmap_66=129:10 -portmap_100=131:10 portmap_33=132:10 portmap_67=133:10 portmap_101=134:10 @@ -410,7 +406,5 @@ portmap_114=121:40:2 portmap_115=123:40:2 portmap_116=125:40:2 portmap_117=127:40:2 -dport_map_port_66=65 -dport_map_port_100=66 mmu_init_config="MSFT-TH-Tier1" diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/bin/S6100-BIOS-3.25.0.2-7.bin b/device/dell/x86_64-dell_s6100_c2538-r0/bin/S6100-BIOS-3.25.0.2-7.bin new file mode 100644 index 000000000000..e6371a2602d6 Binary files /dev/null and b/device/dell/x86_64-dell_s6100_c2538-r0/bin/S6100-BIOS-3.25.0.2-7.bin differ diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers_defaults_t1.j2 b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers_defaults_t1.j2 index e127362c091a..fa78303b2468 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers_defaults_t1.j2 +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers_defaults_t1.j2 @@ -36,7 +36,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm index 25aefca2dafa..39a3695b4cdc 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm @@ -57,8 +57,6 @@ portmap_2=5:100 portmap_1=1:100 portmap_4=13:100 portmap_3=9:100 -portmap_66=129:10 -portmap_100=131:10 portmap_33=132:10 portmap_67=133:10 portmap_101=134:10 diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers_defaults_t0.j2 b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers_defaults_t0.j2 index f200b85b2027..fa5b0fc5a52b 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers_defaults_t0.j2 +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers_defaults_t0.j2 @@ -50,7 +50,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm index 5dddf7d2a2d4..3dd7cc89456d 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm @@ -25,7 +25,6 @@ parity_correction=1 parity_enable=1 #Port configuration -dport_map_port_100.0=130 dport_map_port_10.0=126 dport_map_port_1.0=117 dport_map_port_102.0=65 @@ -67,7 +66,6 @@ dport_map_port_58.0=9 dport_map_port_59.0=10 dport_map_port_62.0=13 dport_map_port_63.0=14 -dport_map_port_66.0=129 dport_map_port_68.0=17 dport_map_port_69.0=18 dport_map_port_72.0=21 @@ -84,7 +82,6 @@ dport_map_port_93.0=58 dport_map_port_96.0=61 dport_map_port_97.0=62 -phy_xaui_rx_polarity_flip_100.0=0xf phy_xaui_rx_polarity_flip_10.0=0x2 phy_xaui_rx_polarity_flip_1.0=0x9 phy_xaui_rx_polarity_flip_102.0=0x2 @@ -126,7 +123,6 @@ phy_xaui_rx_polarity_flip_58.0=0x2 phy_xaui_rx_polarity_flip_59.0=0x0 phy_xaui_rx_polarity_flip_62.0=0x3 phy_xaui_rx_polarity_flip_63.0=0x3 -phy_xaui_rx_polarity_flip_66.0=0xf phy_xaui_rx_polarity_flip_68.0=0x0 phy_xaui_rx_polarity_flip_69.0=0x3 phy_xaui_rx_polarity_flip_72.0=0x2 @@ -143,7 +139,6 @@ phy_xaui_rx_polarity_flip_93.0=0x1 phy_xaui_rx_polarity_flip_96.0=0x3 phy_xaui_rx_polarity_flip_97.0=0x2 -phy_xaui_tx_polarity_flip_100.0=0x6 phy_xaui_tx_polarity_flip_10.0=0x0 phy_xaui_tx_polarity_flip_1.0=0x3 phy_xaui_tx_polarity_flip_102.0=0x3 @@ -185,7 +180,6 @@ phy_xaui_tx_polarity_flip_58.0=0x2 phy_xaui_tx_polarity_flip_59.0=0x2 phy_xaui_tx_polarity_flip_62.0=0x3 phy_xaui_tx_polarity_flip_63.0=0x2 -phy_xaui_tx_polarity_flip_66.0=0x6 phy_xaui_tx_polarity_flip_68.0=0x2 phy_xaui_tx_polarity_flip_69.0=0x0 phy_xaui_tx_polarity_flip_72.0=0x0 @@ -202,7 +196,6 @@ phy_xaui_tx_polarity_flip_93.0=0x1 phy_xaui_tx_polarity_flip_96.0=0x0 phy_xaui_tx_polarity_flip_97.0=0x2 -portmap_100.0=131:10 portmap_10.0=11:50:2 portmap_1.0=1:100 portmap_102.0=97:50:2 @@ -244,7 +237,6 @@ portmap_58.0=57:50:2 portmap_59.0=59:50:2 portmap_62.0=61:50:2 portmap_63.0=63:50:2 -portmap_66.0=129:10 portmap_68.0=65:50:2 portmap_69.0=67:50:2 portmap_72.0=69:50:2 @@ -261,7 +253,6 @@ portmap_93.0=91:50:2 portmap_96.0=93:50:2 portmap_97.0=95:50:2 -xgxs_rx_lane_map_100.0=0x3210 xgxs_rx_lane_map_10.0=0x213 xgxs_rx_lane_map_1.0=0x213 xgxs_rx_lane_map_102.0=0x3201 @@ -303,7 +294,6 @@ xgxs_rx_lane_map_58.0=0x1203 xgxs_rx_lane_map_59.0=0x1203 xgxs_rx_lane_map_62.0=0x1302 xgxs_rx_lane_map_63.0=0x1302 -xgxs_rx_lane_map_66.0=0x3210 xgxs_rx_lane_map_68.0=0x3201 xgxs_rx_lane_map_69.0=0x3201 xgxs_rx_lane_map_72.0=0x1302 @@ -319,7 +309,6 @@ xgxs_rx_lane_map_92.0=0x3210 xgxs_rx_lane_map_93.0=0x3210 xgxs_rx_lane_map_96.0=0x3210 xgxs_rx_lane_map_97.0=0x3210 -xgxs_tx_lane_map_100.0=0x132 xgxs_tx_lane_map_10.0=0x123 xgxs_tx_lane_map_1.0=0x123 xgxs_tx_lane_map_102.0=0x123 @@ -361,7 +350,6 @@ xgxs_tx_lane_map_58.0=0x123 xgxs_tx_lane_map_59.0=0x123 xgxs_tx_lane_map_62.0=0x3201 xgxs_tx_lane_map_63.0=0x3201 -xgxs_tx_lane_map_66.0=0x132 xgxs_tx_lane_map_68.0=0x3210 xgxs_tx_lane_map_69.0=0x3210 xgxs_tx_lane_map_72.0=0x2301 diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/buffers.json.j2 b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..c31728e46543 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/buffers_defaults_t0.j2 @@ -0,0 +1,46 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "32744448", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "32744448", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + "{{ port_names_active }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + "{{ port_names_active }}|0-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..c31728e46543 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/buffers_defaults_t1.j2 @@ -0,0 +1,46 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "32744448", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "32744448", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + "{{ port_names_active }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + "{{ port_names_active }}|0-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/custom_led.bin b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/custom_led.bin new file mode 100755 index 000000000000..b3966e520c51 Binary files /dev/null and b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/custom_led.bin differ diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/linkscan_led_fw.bin b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/linkscan_led_fw.bin new file mode 100755 index 000000000000..c2fa94a2d8cb Binary files /dev/null and b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/linkscan_led_fw.bin differ diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/port_config.ini b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/port_config.ini new file mode 100644 index 000000000000..3827e7acbe28 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed +Ethernet0 49 tenGigE1/1/1 1 10000 +Ethernet1 50 tenGigE1/1/2 2 10000 +Ethernet2 51 tenGigE1/1/3 3 10000 +Ethernet3 52 tenGigE1/1/4 4 10000 +Ethernet4 57 tenGigE1/2/1 5 10000 +Ethernet5 58 tenGigE1/2/2 6 10000 +Ethernet6 59 tenGigE1/2/3 7 10000 +Ethernet7 60 tenGigE1/2/4 8 10000 +Ethernet8 61 tenGigE1/3/1 9 10000 +Ethernet9 62 tenGigE1/3/2 10 10000 +Ethernet10 63 tenGigE1/3/3 11 10000 +Ethernet11 64 tenGigE1/3/4 12 10000 +Ethernet12 77 tenGigE1/4/1 13 10000 +Ethernet13 78 tenGigE1/4/2 14 10000 +Ethernet14 79 tenGigE1/4/3 15 10000 +Ethernet15 80 tenGigE1/4/4 16 10000 +Ethernet16 85 tenGigE1/5/1 17 10000 +Ethernet17 86 tenGigE1/5/2 18 10000 +Ethernet18 87 tenGigE1/5/3 19 10000 +Ethernet19 88 tenGigE1/5/4 20 10000 +Ethernet20 93 tenGigE1/6/1 21 10000 +Ethernet21 94 tenGigE1/6/2 22 10000 +Ethernet22 95 tenGigE1/6/3 23 10000 +Ethernet23 96 tenGigE1/6/4 24 10000 +Ethernet24 13 tenGigE1/7/1 25 10000 +Ethernet25 14 tenGigE1/7/2 26 10000 +Ethernet26 15 tenGigE1/7/3 27 10000 +Ethernet27 16 tenGigE1/7/4 28 10000 +Ethernet28 21 tenGigE1/8/1 29 10000 +Ethernet29 22 tenGigE1/8/2 30 10000 +Ethernet30 23 tenGigE1/8/3 31 10000 +Ethernet31 24 tenGigE1/8/4 32 10000 +Ethernet32 29 tenGigE1/9/1 33 10000 +Ethernet33 30 tenGigE1/9/2 34 10000 +Ethernet34 31 tenGigE1/9/3 35 10000 +Ethernet35 32 tenGigE1/9/4 36 10000 +Ethernet36 97 tenGigE1/10/1 37 10000 +Ethernet37 98 tenGigE1/10/2 38 10000 +Ethernet38 99 tenGigE1/10/3 39 10000 +Ethernet39 100 tenGigE1/10/4 40 10000 +Ethernet40 105 tenGigE1/11/1 41 10000 +Ethernet41 106 tenGigE1/11/2 42 10000 +Ethernet42 107 tenGigE1/11/3 43 10000 +Ethernet43 108 tenGigE1/11/4 44 10000 +Ethernet44 113 tenGigE1/12/1 45 10000 +Ethernet45 114 tenGigE1/12/2 46 10000 +Ethernet46 115 tenGigE1/12/3 47 10000 +Ethernet47 116 tenGigE1/12/4 48 10000 +Ethernet48 121,122,123,124 hundredGigE1/49 49 100000 +Ethernet49 125,126,127,128 hundredGigE1/50 50 100000 +Ethernet50 69,70,71,72 hundredGigE1/51 51 100000 +Ethernet51 65,66,67,68 hundredGigE1/52 52 100000 +Ethernet52 1,2,3,4 hundredGigE1/53 53 100000 +Ethernet53 33,34,35,36 hundredGigE1/54 54 100000 +Ethernet54 5,6,7,8 hundredGigE1/55 55 100000 +Ethernet55 41,42,43,44 hundredGigE1/56 56 100000 diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/qos.json.j2 b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/qos.json.j2 new file mode 100644 index 000000000000..d2b3d2b0131c --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/qos.json.j2 @@ -0,0 +1,226 @@ +{%- set PORT_ALL = [] %} +{%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{% endif %} +{%- endfor %} +{%- if PORT_ALL | sort_by_port_index %}{% endif %} + +{%- set port_names_list_all = [] %} +{%- for port in PORT_ALL %} + {%- if port_names_list_all.append(port) %}{% endif %} +{%- endfor %} +{%- set port_names_all = port_names_list_all | join(',') -%} + + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} +{%- if PORT_ACTIVE | sort_by_port_index %}{% endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') -%} + + +{%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%} + + +{ +{% if generate_tc_to_pg_map is defined %} + {{- generate_tc_to_pg_map() }} +{% else %} + "TC_TO_PRIORITY_GROUP_MAP": { + "DEFAULT": { + "0": "0", + "1": "0", + "2": "0", + "3": "0", + "4": "0", + "5": "0", + "6": "0", + "7": "7" + } + }, +{% endif %} + "MAP_PFC_PRIORITY_TO_QUEUE": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "DEFAULT": { + "0" : "0", + "1" : "0", + "2" : "0", + "3" : "0", + "4" : "0", + "5" : "0", + "6" : "0", + "7" : "0", + "8" : "0", + "9" : "0", + "10": "0", + "11": "0", + "12": "0", + "13": "0", + "14": "0", + "15": "0", + "16": "0", + "17": "0", + "18": "0", + "19": "0", + "20": "0", + "21": "0", + "22": "0", + "23": "0", + "24": "0", + "25": "0", + "26": "0", + "27": "0", + "28": "0", + "29": "0", + "30": "0", + "31": "0", + "32": "0", + "33": "0", + "34": "0", + "35": "0", + "36": "0", + "37": "0", + "38": "0", + "39": "0", + "40": "0", + "41": "0", + "42": "0", + "43": "0", + "44": "0", + "45": "0", + "46": "0", + "47": "0", + "48": "0", + "49": "0", + "50": "0", + "51": "0", + "52": "0", + "53": "0", + "54": "0", + "55": "0", + "56": "0", + "57": "0", + "58": "0", + "59": "0", + "60": "0", + "61": "0", + "62": "0", + "63": "0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "1" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "2" + }, + "scheduler.2": { + "type" : "DWRR", + "weight": "3" + }, + "scheduler.3": { + "type" : "DWRR", + "weight": "4" + }, + "scheduler.4": { + "type" : "DWRR", + "weight": "5" + }, + "scheduler.5": { + "type" : "DWRR", + "weight": "10" + }, + "scheduler.6": { + "type" : "DWRR", + "weight": "25" + }, + "scheduler.7": { + "type" : "DWRR", + "weight": "50" + } + }, + "PORT_QOS_MAP": { + "{{ port_names_active }}": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|DEFAULT]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|DEFAULT]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|DEFAULT]" + } + }, + "QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|1": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|2": { + "scheduler": "[SCHEDULER|scheduler.2]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|3": { + "scheduler": "[SCHEDULER|scheduler.3]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|4": { + "scheduler": "[SCHEDULER|scheduler.4]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5": { + "scheduler": "[SCHEDULER|scheduler.5]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|6": { + "scheduler": "[SCHEDULER|scheduler.6]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + }{% if not loop.last %},{% endif %} +{% endfor %} + } +} diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai.profile b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai.profile new file mode 100644 index 000000000000..52afc687173c --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5248f-10g.config.bcm diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/sai_preinit_cmd.soc @@ -0,0 +1,2 @@ +m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/td3-s5248f-10g.config.bcm b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/td3-s5248f-10g.config.bcm new file mode 100644 index 000000000000..2369f4590795 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-10G/td3-s5248f-10g.config.bcm @@ -0,0 +1,353 @@ +os=unix +dpp_clock_ratio=2:3 +oversubscribe_mode=1 +core_clock_frequency=1525 +l2xmsg_mode=1 +pbmp_oversubscribe=0x7f878787f878787f9fe1e1e1fe1e1e1fe +pbmp_xport_xe=0x7f878787f878787f9fe1e1e1fe1e1e1fe +ifp_inports_support_enable=1 +port_flex_enable=1 +phy_an_c73=3 +l2xmsg_hostbuf_size=8192 +module_64ports=0 +tdma_intr_enable=1 +ipv6_lpm_128b_enable=1 +stat_if_parity_enable=1 +bcm_tunnel_term_compatible_mode=1 +table_dma_enable=1 +schan_intr_enable=0 +parity_enable=1 +parity_correction=1 +miim_intr_enable=1 +max_vp_lags=0 +tdma_intr_enable=1 +tdma_timeout_usec=5000000 +mmu_lossless=0 +pdma_descriptor_prefetch_enable=1 +pktdma_poll_mode_channel_bitmap=1 + +l3_alpm_enable=2 +l3_alpm_ipv6_128b_bkt_rsvd=1 +l2_mem_entries=40960 +l3_mem_entries=40960 +l3_max_ecmp_mode=1 + +stable_size=0x5500000 + +portmap_1.0=1:100 +portmap_5.0=5:100 +portmap_13.0=13:10 +portmap_14.0=14:10 +portmap_15.0=15:10 +portmap_16.0=16:10 +portmap_21.0=21:10 +portmap_22.0=22:10 +portmap_23.0=23:10 +portmap_24.0=24:10 +portmap_29.0=29:10 +portmap_30.0=30:10 +portmap_31.0=31:10 +portmap_32.0=32:10 +portmap_33.0=33:100 +portmap_41.0=41:100 +portmap_49.0=49:10 +portmap_50.0=50:10 +portmap_51.0=51:10 +portmap_52.0=52:10 +portmap_57.0=57:10 +portmap_58.0=58:10 +portmap_59.0=59:10 +portmap_60.0=60:10 +portmap_61.0=61:10 +portmap_62.0=62:10 +portmap_63.0=63:10 +portmap_64.0=64:10 +portmap_67.0=65:100 +portmap_71.0=69:100 +portmap_79.0=77:10 +portmap_80.0=78:10 +portmap_81.0=79:10 +portmap_82.0=80:10 +portmap_87.0=85:10 +portmap_88.0=86:10 +portmap_89.0=87:10 +portmap_90.0=88:10 +portmap_95.0=93:10 +portmap_96.0=94:10 +portmap_97.0=95:10 +portmap_98.0=96:10 +portmap_99.0=97:10 +portmap_100.0=98:10 +portmap_101.0=99:10 +portmap_102.0=100:10 +portmap_107.0=105:10 +portmap_108.0=106:10 +portmap_109.0=107:10 +portmap_110.0=108:10 +portmap_115.0=113:10 +portmap_116.0=114:10 +portmap_117.0=115:10 +portmap_118.0=116:10 +portmap_123.0=121:100 +portmap_127.0=125:100 +phy_chain_tx_lane_map_physical{1.0}=0x0123 +phy_chain_rx_lane_map_physical{1.0}=0x1302 +phy_chain_tx_lane_map_physical{5.0}=0x1032 +phy_chain_rx_lane_map_physical{5.0}=0x1302 +phy_chain_tx_lane_map_physical{13.0}=0x0123 +phy_chain_rx_lane_map_physical{13.0}=0x1032 +phy_chain_tx_lane_map_physical{21.0}=0x0123 +phy_chain_rx_lane_map_physical{21.0}=0x1032 +phy_chain_tx_lane_map_physical{29.0}=0x0123 +phy_chain_rx_lane_map_physical{29.0}=0x1032 +phy_chain_tx_lane_map_physical{33.0}=0x1302 +phy_chain_rx_lane_map_physical{33.0}=0x1032 +phy_chain_tx_lane_map_physical{41.0}=0x3120 +phy_chain_rx_lane_map_physical{41.0}=0x1032 +phy_chain_tx_lane_map_physical{49.0}=0x0123 +phy_chain_rx_lane_map_physical{49.0}=0x1032 +phy_chain_tx_lane_map_physical{57.0}=0x0123 +phy_chain_rx_lane_map_physical{57.0}=0x1032 +phy_chain_tx_lane_map_physical{61.0}=0x0123 +phy_chain_rx_lane_map_physical{61.0}=0x1032 +phy_chain_tx_lane_map_physical{65.0}=0x0123 +phy_chain_rx_lane_map_physical{65.0}=0x2031 +phy_chain_tx_lane_map_physical{69.0}=0x3021 +phy_chain_rx_lane_map_physical{69.0}=0x2130 +phy_chain_tx_lane_map_physical{77.0}=0x3210 +phy_chain_rx_lane_map_physical{77.0}=0x2301 +phy_chain_tx_lane_map_physical{85.0}=0x3210 +phy_chain_rx_lane_map_physical{85.0}=0x2301 +phy_chain_tx_lane_map_physical{93.0}=0x3210 +phy_chain_rx_lane_map_physical{93.0}=0x2301 +phy_chain_tx_lane_map_physical{97.0}=0x3210 +phy_chain_rx_lane_map_physical{97.0}=0x2301 +phy_chain_tx_lane_map_physical{105.0}=0x3210 +phy_chain_rx_lane_map_physical{105.0}=0x2301 +phy_chain_tx_lane_map_physical{113.0}=0x3210 +phy_chain_rx_lane_map_physical{113.0}=0x2301 +phy_chain_tx_lane_map_physical{121.0}=0x0312 +phy_chain_rx_lane_map_physical{121.0}=0x1023 +phy_chain_tx_lane_map_physical{125.0}=0x2301 +phy_chain_rx_lane_map_physical{125.0}=0x3120 +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}=0x1 +phy_chain_rx_polarity_flip_physical{3.0}=0x1 +phy_chain_tx_polarity_flip_physical{4.0}=0x0 +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}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x0 +phy_chain_tx_polarity_flip_physical{7.0}=0x1 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x0 +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}=0x1 +phy_chain_rx_polarity_flip_physical{16.0}=0x0 +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x1 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x0 +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}=0x0 +phy_chain_tx_polarity_flip_physical{29.0}=0x0 +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}=0x1 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x1 +phy_chain_tx_polarity_flip_physical{32.0}=0x1 +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}=0x0 +phy_chain_tx_polarity_flip_physical{34.0}=0x1 +phy_chain_rx_polarity_flip_physical{34.0}=0x1 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{35.0}=0x0 +phy_chain_tx_polarity_flip_physical{36.0}=0x0 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 +phy_chain_tx_polarity_flip_physical{41.0}=0x0 +phy_chain_rx_polarity_flip_physical{41.0}=0x0 +phy_chain_tx_polarity_flip_physical{42.0}=0x1 +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}=0x0 +phy_chain_rx_polarity_flip_physical{44.0}=0x0 +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{49.0}=0x0 +phy_chain_tx_polarity_flip_physical{50.0}=0x0 +phy_chain_rx_polarity_flip_physical{50.0}=0x1 +phy_chain_tx_polarity_flip_physical{51.0}=0x1 +phy_chain_rx_polarity_flip_physical{51.0}=0x0 +phy_chain_tx_polarity_flip_physical{52.0}=0x0 +phy_chain_rx_polarity_flip_physical{52.0}=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}=0x0 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x1 +phy_chain_rx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x0 +phy_chain_rx_polarity_flip_physical{60.0}=0x1 +phy_chain_tx_polarity_flip_physical{61.0}=0x1 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x0 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x1 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=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}=0x1 +phy_chain_tx_polarity_flip_physical{66.0}=0x1 +phy_chain_rx_polarity_flip_physical{66.0}=0x0 +phy_chain_tx_polarity_flip_physical{67.0}=0x0 +phy_chain_rx_polarity_flip_physical{67.0}=0x0 +phy_chain_tx_polarity_flip_physical{68.0}=0x1 +phy_chain_rx_polarity_flip_physical{68.0}=0x0 +phy_chain_tx_polarity_flip_physical{69.0}=0x0 +phy_chain_rx_polarity_flip_physical{69.0}=0x0 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x1 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{71.0}=0x1 +phy_chain_tx_polarity_flip_physical{72.0}=0x1 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 +phy_chain_tx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{77.0}=0x1 +phy_chain_tx_polarity_flip_physical{78.0}=0x1 +phy_chain_rx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x0 +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}=0x0 +phy_chain_tx_polarity_flip_physical{85.0}=0x0 +phy_chain_rx_polarity_flip_physical{85.0}=0x1 +phy_chain_tx_polarity_flip_physical{86.0}=0x1 +phy_chain_rx_polarity_flip_physical{86.0}=0x0 +phy_chain_tx_polarity_flip_physical{87.0}=0x0 +phy_chain_rx_polarity_flip_physical{87.0}=0x1 +phy_chain_tx_polarity_flip_physical{88.0}=0x1 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 +phy_chain_tx_polarity_flip_physical{93.0}=0x0 +phy_chain_rx_polarity_flip_physical{93.0}=0x1 +phy_chain_tx_polarity_flip_physical{94.0}=0x1 +phy_chain_rx_polarity_flip_physical{94.0}=0x0 +phy_chain_tx_polarity_flip_physical{95.0}=0x0 +phy_chain_rx_polarity_flip_physical{95.0}=0x1 +phy_chain_tx_polarity_flip_physical{96.0}=0x1 +phy_chain_rx_polarity_flip_physical{96.0}=0x0 +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{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{113.0}=0x1 +phy_chain_rx_polarity_flip_physical{113.0}=0x0 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_rx_polarity_flip_physical{114.0}=0x1 +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}=0x1 +phy_chain_tx_polarity_flip_physical{121.0}=0x0 +phy_chain_rx_polarity_flip_physical{121.0}=0x1 +phy_chain_tx_polarity_flip_physical{122.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x0 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 +phy_chain_rx_polarity_flip_physical{124.0}=0x0 +phy_chain_tx_polarity_flip_physical{125.0}=0x0 +phy_chain_rx_polarity_flip_physical{125.0}=0x1 +phy_chain_tx_polarity_flip_physical{126.0}=0x1 +phy_chain_rx_polarity_flip_physical{126.0}=0x1 +phy_chain_tx_polarity_flip_physical{127.0}=0x0 +phy_chain_rx_polarity_flip_physical{127.0}=0x0 +phy_chain_tx_polarity_flip_physical{128.0}=0x1 +phy_chain_rx_polarity_flip_physical{128.0}=0x0 +dport_map_enable=1 +dport_map_port_49=1 +dport_map_port_50=2 +dport_map_port_51=3 +dport_map_port_52=4 +dport_map_port_57=5 +dport_map_port_58=6 +dport_map_port_59=7 +dport_map_port_60=8 +dport_map_port_61=9 +dport_map_port_62=10 +dport_map_port_63=11 +dport_map_port_64=12 +dport_map_port_79=13 +dport_map_port_80=14 +dport_map_port_81=15 +dport_map_port_82=16 +dport_map_port_87=17 +dport_map_port_88=18 +dport_map_port_89=19 +dport_map_port_90=20 +dport_map_port_95=21 +dport_map_port_96=22 +dport_map_port_97=23 +dport_map_port_98=24 +dport_map_port_13=25 +dport_map_port_14=26 +dport_map_port_15=27 +dport_map_port_16=28 +dport_map_port_21=29 +dport_map_port_22=30 +dport_map_port_23=31 +dport_map_port_24=32 +dport_map_port_29=33 +dport_map_port_30=34 +dport_map_port_31=35 +dport_map_port_32=36 +dport_map_port_99=37 +dport_map_port_100=38 +dport_map_port_101=39 +dport_map_port_102=40 +dport_map_port_107=41 +dport_map_port_108=42 +dport_map_port_109=43 +dport_map_port_110=44 +dport_map_port_115=45 +dport_map_port_116=46 +dport_map_port_117=47 +dport_map_port_118=48 +dport_map_port_123=49 +dport_map_port_127=50 +dport_map_port_71=51 +dport_map_port_67=52 +dport_map_port_1=53 +dport_map_port_33=54 +dport_map_port_5=55 +dport_map_port_41=56 + +mmu_init_config="TD3-DELL-lossless" +#sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc + diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/buffers.json.j2 b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..c31728e46543 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/buffers_defaults_t0.j2 @@ -0,0 +1,46 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "32744448", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "32744448", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + "{{ port_names_active }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + "{{ port_names_active }}|0-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..c31728e46543 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/buffers_defaults_t1.j2 @@ -0,0 +1,46 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "32744448", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "32744448", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"32744448" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + "{{ port_names_active }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + "{{ port_names_active }}|0-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/custom_led.bin b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/custom_led.bin new file mode 100755 index 000000000000..b3966e520c51 Binary files /dev/null and b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/custom_led.bin differ diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/linkscan_led_fw.bin b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/linkscan_led_fw.bin new file mode 100755 index 000000000000..c2fa94a2d8cb Binary files /dev/null and b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/linkscan_led_fw.bin differ diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/port_config.ini b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/port_config.ini new file mode 100644 index 000000000000..3dc16e2eb9b9 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed +Ethernet0 49 twentyfiveGigE1/1/1 1 25000 +Ethernet1 50 twentyfiveGigE1/1/2 2 25000 +Ethernet2 51 twentyfiveGigE1/1/3 3 25000 +Ethernet3 52 twentyfiveGigE1/1/4 4 25000 +Ethernet4 57 twentyfiveGigE1/2/1 5 25000 +Ethernet5 58 twentyfiveGigE1/2/2 6 25000 +Ethernet6 59 twentyfiveGigE1/2/3 7 25000 +Ethernet7 60 twentyfiveGigE1/2/4 8 25000 +Ethernet8 61 twentyfiveGigE1/3/1 9 25000 +Ethernet9 62 twentyfiveGigE1/3/2 10 25000 +Ethernet10 63 twentyfiveGigE1/3/3 11 25000 +Ethernet11 64 twentyfiveGigE1/3/4 12 25000 +Ethernet12 77 twentyfiveGigE1/4/1 13 25000 +Ethernet13 78 twentyfiveGigE1/4/2 14 25000 +Ethernet14 79 twentyfiveGigE1/4/3 15 25000 +Ethernet15 80 twentyfiveGigE1/4/4 16 25000 +Ethernet16 85 twentyfiveGigE1/5/1 17 25000 +Ethernet17 86 twentyfiveGigE1/5/2 18 25000 +Ethernet18 87 twentyfiveGigE1/5/3 19 25000 +Ethernet19 88 twentyfiveGigE1/5/4 20 25000 +Ethernet20 93 twentyfiveGigE1/6/1 21 25000 +Ethernet21 94 twentyfiveGigE1/6/2 22 25000 +Ethernet22 95 twentyfiveGigE1/6/3 23 25000 +Ethernet23 96 twentyfiveGigE1/6/4 24 25000 +Ethernet24 13 twentyfiveGigE1/7/1 25 25000 +Ethernet25 14 twentyfiveGigE1/7/2 26 25000 +Ethernet26 15 twentyfiveGigE1/7/3 27 25000 +Ethernet27 16 twentyfiveGigE1/7/4 28 25000 +Ethernet28 21 twentyfiveGigE1/8/1 29 25000 +Ethernet29 22 twentyfiveGigE1/8/2 30 25000 +Ethernet30 23 twentyfiveGigE1/8/3 31 25000 +Ethernet31 24 twentyfiveGigE1/8/4 32 25000 +Ethernet32 29 twentyfiveGigE1/9/1 33 25000 +Ethernet33 30 twentyfiveGigE1/9/2 34 25000 +Ethernet34 31 twentyfiveGigE1/9/3 35 25000 +Ethernet35 32 twentyfiveGigE1/9/4 36 25000 +Ethernet36 97 twentyfiveGigE1/10/1 37 25000 +Ethernet37 98 twentyfiveGigE1/10/2 38 25000 +Ethernet38 99 twentyfiveGigE1/10/3 39 25000 +Ethernet39 100 twentyfiveGigE1/10/4 40 25000 +Ethernet40 105 twentyfiveGigE1/11/1 41 25000 +Ethernet41 106 twentyfiveGigE1/11/2 42 25000 +Ethernet42 107 twentyfiveGigE1/11/3 43 25000 +Ethernet43 108 twentyfiveGigE1/11/4 44 25000 +Ethernet44 113 twentyfiveGigE1/12/1 45 25000 +Ethernet45 114 twentyfiveGigE1/12/2 46 25000 +Ethernet46 115 twentyfiveGigE1/12/3 47 25000 +Ethernet47 116 twentyfiveGigE1/12/4 48 25000 +Ethernet48 121,122,123,124 hundredGigE1/49 49 100000 +Ethernet49 125,126,127,128 hundredGigE1/50 50 100000 +Ethernet50 69,70,71,72 hundredGigE1/51 51 100000 +Ethernet51 65,66,67,68 hundredGigE1/52 52 100000 +Ethernet52 1,2,3,4 hundredGigE1/53 53 100000 +Ethernet53 33,34,35,36 hundredGigE1/54 54 100000 +Ethernet54 5,6,7,8 hundredGigE1/55 55 100000 +Ethernet55 41,42,43,44 hundredGigE1/56 56 100000 diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/qos.json.j2 b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/qos.json.j2 new file mode 100644 index 000000000000..d2b3d2b0131c --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/qos.json.j2 @@ -0,0 +1,226 @@ +{%- set PORT_ALL = [] %} +{%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{% endif %} +{%- endfor %} +{%- if PORT_ALL | sort_by_port_index %}{% endif %} + +{%- set port_names_list_all = [] %} +{%- for port in PORT_ALL %} + {%- if port_names_list_all.append(port) %}{% endif %} +{%- endfor %} +{%- set port_names_all = port_names_list_all | join(',') -%} + + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} +{%- if PORT_ACTIVE | sort_by_port_index %}{% endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') -%} + + +{%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%} + + +{ +{% if generate_tc_to_pg_map is defined %} + {{- generate_tc_to_pg_map() }} +{% else %} + "TC_TO_PRIORITY_GROUP_MAP": { + "DEFAULT": { + "0": "0", + "1": "0", + "2": "0", + "3": "0", + "4": "0", + "5": "0", + "6": "0", + "7": "7" + } + }, +{% endif %} + "MAP_PFC_PRIORITY_TO_QUEUE": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "DEFAULT": { + "0" : "0", + "1" : "0", + "2" : "0", + "3" : "0", + "4" : "0", + "5" : "0", + "6" : "0", + "7" : "0", + "8" : "0", + "9" : "0", + "10": "0", + "11": "0", + "12": "0", + "13": "0", + "14": "0", + "15": "0", + "16": "0", + "17": "0", + "18": "0", + "19": "0", + "20": "0", + "21": "0", + "22": "0", + "23": "0", + "24": "0", + "25": "0", + "26": "0", + "27": "0", + "28": "0", + "29": "0", + "30": "0", + "31": "0", + "32": "0", + "33": "0", + "34": "0", + "35": "0", + "36": "0", + "37": "0", + "38": "0", + "39": "0", + "40": "0", + "41": "0", + "42": "0", + "43": "0", + "44": "0", + "45": "0", + "46": "0", + "47": "0", + "48": "0", + "49": "0", + "50": "0", + "51": "0", + "52": "0", + "53": "0", + "54": "0", + "55": "0", + "56": "0", + "57": "0", + "58": "0", + "59": "0", + "60": "0", + "61": "0", + "62": "0", + "63": "0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "1" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "2" + }, + "scheduler.2": { + "type" : "DWRR", + "weight": "3" + }, + "scheduler.3": { + "type" : "DWRR", + "weight": "4" + }, + "scheduler.4": { + "type" : "DWRR", + "weight": "5" + }, + "scheduler.5": { + "type" : "DWRR", + "weight": "10" + }, + "scheduler.6": { + "type" : "DWRR", + "weight": "25" + }, + "scheduler.7": { + "type" : "DWRR", + "weight": "50" + } + }, + "PORT_QOS_MAP": { + "{{ port_names_active }}": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|DEFAULT]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|DEFAULT]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|DEFAULT]" + } + }, + "QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|1": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|2": { + "scheduler": "[SCHEDULER|scheduler.2]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|3": { + "scheduler": "[SCHEDULER|scheduler.3]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|4": { + "scheduler": "[SCHEDULER|scheduler.4]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5": { + "scheduler": "[SCHEDULER|scheduler.5]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|6": { + "scheduler": "[SCHEDULER|scheduler.6]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + }{% if not loop.last %},{% endif %} +{% endfor %} + } +} diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai.profile b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai.profile new file mode 100644 index 000000000000..4753ec3886c4 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-s5248f-25g.config.bcm diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/sai_preinit_cmd.soc @@ -0,0 +1,2 @@ +m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/td3-s5248f-25g.config.bcm b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/td3-s5248f-25g.config.bcm new file mode 100644 index 000000000000..4095c2d0a4f4 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/DellEMC-S5248f-P-25G/td3-s5248f-25g.config.bcm @@ -0,0 +1,355 @@ +os=unix + +dpp_clock_ratio=2:3 +oversubscribe_mode=1 +core_clock_frequency=1525 +l2xmsg_mode=1 +pbmp_oversubscribe=0x7f878787f878787f9fe1e1e1fe1e1e1fe +pbmp_xport_xe=0x7f878787f878787f9fe1e1e1fe1e1e1fe +ifp_inports_support_enable=1 +port_flex_enable=1 +phy_an_c73=3 +l2xmsg_hostbuf_size=8192 +module_64ports=0 +tdma_intr_enable=1 +ipv6_lpm_128b_enable=1 +stat_if_parity_enable=1 +bcm_tunnel_term_compatible_mode=1 +table_dma_enable=1 +schan_intr_enable=0 +parity_enable=1 +parity_correction=1 +miim_intr_enable=1 +max_vp_lags=0 +tdma_intr_enable=1 +tdma_timeout_usec=5000000 +mmu_lossless=0 +pdma_descriptor_prefetch_enable=1 +pktdma_poll_mode_channel_bitmap=1 + +l3_alpm_enable=2 +l3_alpm_ipv6_128b_bkt_rsvd=1 +l2_mem_entries=40960 +l3_mem_entries=40960 +l3_max_ecmp_mode=1 + + +stable_size=0x5500000 + +portmap_1.0=1:100 +portmap_5.0=5:100 +portmap_13.0=13:25 +portmap_14.0=14:25 +portmap_15.0=15:25 +portmap_16.0=16:25 +portmap_21.0=21:25 +portmap_22.0=22:25 +portmap_23.0=23:25 +portmap_24.0=24:25 +portmap_29.0=29:25 +portmap_30.0=30:25 +portmap_31.0=31:25 +portmap_32.0=32:25 +portmap_33.0=33:100 +portmap_41.0=41:100 +portmap_49.0=49:25 +portmap_50.0=50:25 +portmap_51.0=51:25 +portmap_52.0=52:25 +portmap_57.0=57:25 +portmap_58.0=58:25 +portmap_59.0=59:25 +portmap_60.0=60:25 +portmap_61.0=61:25 +portmap_62.0=62:25 +portmap_63.0=63:25 +portmap_64.0=64:25 +portmap_67.0=65:100 +portmap_71.0=69:100 +portmap_79.0=77:25 +portmap_80.0=78:25 +portmap_81.0=79:25 +portmap_82.0=80:25 +portmap_87.0=85:25 +portmap_88.0=86:25 +portmap_89.0=87:25 +portmap_90.0=88:25 +portmap_95.0=93:25 +portmap_96.0=94:25 +portmap_97.0=95:25 +portmap_98.0=96:25 +portmap_99.0=97:25 +portmap_100.0=98:25 +portmap_101.0=99:25 +portmap_102.0=100:25 +portmap_107.0=105:25 +portmap_108.0=106:25 +portmap_109.0=107:25 +portmap_110.0=108:25 +portmap_115.0=113:25 +portmap_116.0=114:25 +portmap_117.0=115:25 +portmap_118.0=116:25 +portmap_123.0=121:100 +portmap_127.0=125:100 +phy_chain_tx_lane_map_physical{1.0}=0x0123 +phy_chain_rx_lane_map_physical{1.0}=0x1302 +phy_chain_tx_lane_map_physical{5.0}=0x1032 +phy_chain_rx_lane_map_physical{5.0}=0x1302 +phy_chain_tx_lane_map_physical{13.0}=0x0123 +phy_chain_rx_lane_map_physical{13.0}=0x1032 +phy_chain_tx_lane_map_physical{21.0}=0x0123 +phy_chain_rx_lane_map_physical{21.0}=0x1032 +phy_chain_tx_lane_map_physical{29.0}=0x0123 +phy_chain_rx_lane_map_physical{29.0}=0x1032 +phy_chain_tx_lane_map_physical{33.0}=0x1302 +phy_chain_rx_lane_map_physical{33.0}=0x1032 +phy_chain_tx_lane_map_physical{41.0}=0x3120 +phy_chain_rx_lane_map_physical{41.0}=0x1032 +phy_chain_tx_lane_map_physical{49.0}=0x0123 +phy_chain_rx_lane_map_physical{49.0}=0x1032 +phy_chain_tx_lane_map_physical{57.0}=0x0123 +phy_chain_rx_lane_map_physical{57.0}=0x1032 +phy_chain_tx_lane_map_physical{61.0}=0x0123 +phy_chain_rx_lane_map_physical{61.0}=0x1032 +phy_chain_tx_lane_map_physical{65.0}=0x0123 +phy_chain_rx_lane_map_physical{65.0}=0x2031 +phy_chain_tx_lane_map_physical{69.0}=0x3021 +phy_chain_rx_lane_map_physical{69.0}=0x2130 +phy_chain_tx_lane_map_physical{77.0}=0x3210 +phy_chain_rx_lane_map_physical{77.0}=0x2301 +phy_chain_tx_lane_map_physical{85.0}=0x3210 +phy_chain_rx_lane_map_physical{85.0}=0x2301 +phy_chain_tx_lane_map_physical{93.0}=0x3210 +phy_chain_rx_lane_map_physical{93.0}=0x2301 +phy_chain_tx_lane_map_physical{97.0}=0x3210 +phy_chain_rx_lane_map_physical{97.0}=0x2301 +phy_chain_tx_lane_map_physical{105.0}=0x3210 +phy_chain_rx_lane_map_physical{105.0}=0x2301 +phy_chain_tx_lane_map_physical{113.0}=0x3210 +phy_chain_rx_lane_map_physical{113.0}=0x2301 +phy_chain_tx_lane_map_physical{121.0}=0x0312 +phy_chain_rx_lane_map_physical{121.0}=0x1023 +phy_chain_tx_lane_map_physical{125.0}=0x2301 +phy_chain_rx_lane_map_physical{125.0}=0x3120 +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}=0x1 +phy_chain_rx_polarity_flip_physical{3.0}=0x1 +phy_chain_tx_polarity_flip_physical{4.0}=0x0 +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}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x0 +phy_chain_tx_polarity_flip_physical{7.0}=0x1 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x0 +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}=0x1 +phy_chain_rx_polarity_flip_physical{16.0}=0x0 +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x1 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x0 +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}=0x0 +phy_chain_tx_polarity_flip_physical{29.0}=0x0 +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}=0x1 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x1 +phy_chain_tx_polarity_flip_physical{32.0}=0x1 +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}=0x0 +phy_chain_tx_polarity_flip_physical{34.0}=0x1 +phy_chain_rx_polarity_flip_physical{34.0}=0x1 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{35.0}=0x0 +phy_chain_tx_polarity_flip_physical{36.0}=0x0 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 +phy_chain_tx_polarity_flip_physical{41.0}=0x0 +phy_chain_rx_polarity_flip_physical{41.0}=0x0 +phy_chain_tx_polarity_flip_physical{42.0}=0x1 +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}=0x0 +phy_chain_rx_polarity_flip_physical{44.0}=0x0 +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{49.0}=0x0 +phy_chain_tx_polarity_flip_physical{50.0}=0x0 +phy_chain_rx_polarity_flip_physical{50.0}=0x1 +phy_chain_tx_polarity_flip_physical{51.0}=0x1 +phy_chain_rx_polarity_flip_physical{51.0}=0x0 +phy_chain_tx_polarity_flip_physical{52.0}=0x0 +phy_chain_rx_polarity_flip_physical{52.0}=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}=0x0 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x1 +phy_chain_rx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x0 +phy_chain_rx_polarity_flip_physical{60.0}=0x1 +phy_chain_tx_polarity_flip_physical{61.0}=0x1 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x0 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x1 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=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}=0x1 +phy_chain_tx_polarity_flip_physical{66.0}=0x1 +phy_chain_rx_polarity_flip_physical{66.0}=0x0 +phy_chain_tx_polarity_flip_physical{67.0}=0x0 +phy_chain_rx_polarity_flip_physical{67.0}=0x0 +phy_chain_tx_polarity_flip_physical{68.0}=0x1 +phy_chain_rx_polarity_flip_physical{68.0}=0x0 +phy_chain_tx_polarity_flip_physical{69.0}=0x0 +phy_chain_rx_polarity_flip_physical{69.0}=0x0 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x1 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{71.0}=0x1 +phy_chain_tx_polarity_flip_physical{72.0}=0x1 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 +phy_chain_tx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{77.0}=0x1 +phy_chain_tx_polarity_flip_physical{78.0}=0x1 +phy_chain_rx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x0 +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}=0x0 +phy_chain_tx_polarity_flip_physical{85.0}=0x0 +phy_chain_rx_polarity_flip_physical{85.0}=0x1 +phy_chain_tx_polarity_flip_physical{86.0}=0x1 +phy_chain_rx_polarity_flip_physical{86.0}=0x0 +phy_chain_tx_polarity_flip_physical{87.0}=0x0 +phy_chain_rx_polarity_flip_physical{87.0}=0x1 +phy_chain_tx_polarity_flip_physical{88.0}=0x1 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 +phy_chain_tx_polarity_flip_physical{93.0}=0x0 +phy_chain_rx_polarity_flip_physical{93.0}=0x1 +phy_chain_tx_polarity_flip_physical{94.0}=0x1 +phy_chain_rx_polarity_flip_physical{94.0}=0x0 +phy_chain_tx_polarity_flip_physical{95.0}=0x0 +phy_chain_rx_polarity_flip_physical{95.0}=0x1 +phy_chain_tx_polarity_flip_physical{96.0}=0x1 +phy_chain_rx_polarity_flip_physical{96.0}=0x0 +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{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{113.0}=0x1 +phy_chain_rx_polarity_flip_physical{113.0}=0x0 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_rx_polarity_flip_physical{114.0}=0x1 +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}=0x1 +phy_chain_tx_polarity_flip_physical{121.0}=0x0 +phy_chain_rx_polarity_flip_physical{121.0}=0x1 +phy_chain_tx_polarity_flip_physical{122.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x0 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 +phy_chain_rx_polarity_flip_physical{124.0}=0x0 +phy_chain_tx_polarity_flip_physical{125.0}=0x0 +phy_chain_rx_polarity_flip_physical{125.0}=0x1 +phy_chain_tx_polarity_flip_physical{126.0}=0x1 +phy_chain_rx_polarity_flip_physical{126.0}=0x1 +phy_chain_tx_polarity_flip_physical{127.0}=0x0 +phy_chain_rx_polarity_flip_physical{127.0}=0x0 +phy_chain_tx_polarity_flip_physical{128.0}=0x1 +phy_chain_rx_polarity_flip_physical{128.0}=0x0 +dport_map_enable=1 +dport_map_port_49=1 +dport_map_port_50=2 +dport_map_port_51=3 +dport_map_port_52=4 +dport_map_port_57=5 +dport_map_port_58=6 +dport_map_port_59=7 +dport_map_port_60=8 +dport_map_port_61=9 +dport_map_port_62=10 +dport_map_port_63=11 +dport_map_port_64=12 +dport_map_port_79=13 +dport_map_port_80=14 +dport_map_port_81=15 +dport_map_port_82=16 +dport_map_port_87=17 +dport_map_port_88=18 +dport_map_port_89=19 +dport_map_port_90=20 +dport_map_port_95=21 +dport_map_port_96=22 +dport_map_port_97=23 +dport_map_port_98=24 +dport_map_port_13=25 +dport_map_port_14=26 +dport_map_port_15=27 +dport_map_port_16=28 +dport_map_port_21=29 +dport_map_port_22=30 +dport_map_port_23=31 +dport_map_port_24=32 +dport_map_port_29=33 +dport_map_port_30=34 +dport_map_port_31=35 +dport_map_port_32=36 +dport_map_port_99=37 +dport_map_port_100=38 +dport_map_port_101=39 +dport_map_port_102=40 +dport_map_port_107=41 +dport_map_port_108=42 +dport_map_port_109=43 +dport_map_port_110=44 +dport_map_port_115=45 +dport_map_port_116=46 +dport_map_port_117=47 +dport_map_port_118=48 +dport_map_port_123=49 +dport_map_port_127=50 +dport_map_port_71=51 +dport_map_port_67=52 +dport_map_port_1=53 +dport_map_port_33=54 +dport_map_port_5=55 +dport_map_port_41=56 + +mmu_init_config="TD3-DELL-lossless" +#sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc + diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/default_sku b/device/dell/x86_64-dellemc_s5248f_c3538-r0/default_sku new file mode 100644 index 000000000000..618471d5629d --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/default_sku @@ -0,0 +1 @@ +DellEMC-S5248f-P-25G t1 \ No newline at end of file diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/installer.conf b/device/dell/x86_64-dellemc_s5248f_c3538-r0/installer.conf new file mode 100644 index 000000000000..925a32fc0c3a --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/led_proc_init.soc b/device/dell/x86_64-dellemc_s5248f_c3538-r0/led_proc_init.soc new file mode 100644 index 000000000000..69072c369a64 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/led_proc_init.soc @@ -0,0 +1,6 @@ +# LED microprocessor initialization for Dell S5232 +# +# +#Led0 +led auto on +led start diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/media_settings.json b/device/dell/x86_64-dellemc_s5248f_c3538-r0/media_settings.json new file mode 100644 index 000000000000..8bdc0e7aa984 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/media_settings.json @@ -0,0 +1,442 @@ +{ + "GLOBAL_MEDIA_SETTINGS": { + "1-32": { + "QSFP28-40GBASE-CR4-1M":{ + "preemphasis": { + "lane0":"0x16440A", + "lane1":"0x16440A", + "lane2":"0x16440A", + "lane3":"0x16440A" + } + }, + "QSFP28-40GBASE-CR4-2M":{ + "preemphasis": { + "lane0":"0x18420A", + "lane1":"0x18420A", + "lane2":"0x18420A", + "lane3":"0x18420A" + } + }, + "QSFP28-40GBASE-CR4-3M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP28-40GBASE-CR4-4M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP28-40GBASE-CR4-5M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP28-40GBASE-CR4-7M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP28-40GBASE-CR4-10M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP+-40GBASE-CR4-1M":{ + "preemphasis": { + "lane0":"0x16440A", + "lane1":"0x16440A", + "lane2":"0x16440A", + "lane3":"0x16440A" + } + }, + "QSFP+-40GBASE-CR4-2M":{ + "preemphasis": { + "lane0":"0x18420A", + "lane1":"0x18420A", + "lane2":"0x18420A", + "lane3":"0x18420A" + } + }, + "QSFP+-40GBASE-CR4-3M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP+-40GBASE-CR4-4M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP+-40GBASE-CR4-5M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP+-40GBASE-CR4-7M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + }, + "QSFP+-40GBASE-CR4-10M":{ + "preemphasis": { + "lane0":"0x1A400A", + "lane1":"0x1A400A", + "lane2":"0x1A400A", + "lane3":"0x1A400A" + } + } + } + }, + + "PORT_MEDIA_SETTINGS": { + "1": { + "Default": { + "preemphasis": { + "lane0":"0x164509", + "lane1":"0x164509", + "lane2":"0x164509", + "lane3":"0x164509" + } + } + }, + "2": { + "Default": { + "preemphasis": { + "lane0":"0x164509", + "lane1":"0x164509", + "lane2":"0x164509", + "lane3":"0x164509" + } + } + }, + "3": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + }, + "4": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + }, + "5": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + }, + "6": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "7": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "8": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "9": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "10": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "11": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "12": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "13": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "14": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "15": { + "Default": { + "preemphasis": { + "lane0":"0x0E4E08", + "lane1":"0x0E4E08", + "lane2":"0x0E4E08", + "lane3":"0x0E4E08" + } + } + }, + "16": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "17": { + "Default": { + "preemphasis": { + "lane0":"0x0E4E08", + "lane1":"0x0E4E08", + "lane2":"0x0E4E08", + "lane3":"0x0E4E08" + } + } + }, + "18": { + "Default": { + "preemphasis": { + "lane0":"0x0E4E08", + "lane1":"0x0E4E08", + "lane2":"0x0E4E08", + "lane3":"0x0E4E08" + } + } + }, + "19": { + "Default": { + "preemphasis": { + "lane0":"0x0E4E08", + "lane1":"0x0E4E08", + "lane2":"0x0E4E08", + "lane3":"0x0E4E08" + } + } + }, + "20": { + "Default": { + "preemphasis": { + "lane0":"0x0E4E08", + "lane1":"0x0E4E08", + "lane2":"0x0E4E08", + "lane3":"0x0E4E08" + } + } + }, + "21": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "22": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "23": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "24": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "25": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "26": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "27": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "28": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "29": { + "Default": { + "preemphasis": { + "lane0":"0x124A08", + "lane1":"0x124A08", + "lane2":"0x124A08", + "lane3":"0x124A08" + } + } + }, + "30": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + }, + "31": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + }, + "32": { + "Default": { + "preemphasis": { + "lane0":"0x144808", + "lane1":"0x144808", + "lane2":"0x144808", + "lane3":"0x144808" + } + } + } + } +} + diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/eeprom.py b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/eeprom.py new file mode 100644 index 000000000000..5b044d0ee30a --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/eeprom.py @@ -0,0 +1,22 @@ +#!/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: + from sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0050/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/psuutil.py b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/psuutil.py new file mode 100644 index 000000000000..8004697d7c0a --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/psuutil.py @@ -0,0 +1,107 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + + +import os.path +import logging +import commands +import sys + + +S5248F_MAX_PSUS = 2 +IPMI_PSU_DATA = "docker exec -it pmon ipmitool sdr list" +IPMI_PSU_DATA_DOCKER = "ipmitool sdr list" +PSU_PRESENCE = "PSU{0}_stat" +# Use this for older firmware +# PSU_PRESENCE="PSU{0}_prsnt" +ipmi_sdr_list = "" + + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + def isDockerEnv(self): + num_docker = open('/proc/self/cgroup', 'r').read().count(":/docker") + if num_docker > 0: + return True + else: + return False + + # Fetch a BMC register + def get_pmc_register(self, reg_name): + + status = 1 + global ipmi_sdr_list + ipmi_dev_node = "/dev/pmi0" + ipmi_cmd = IPMI_PSU_DATA + dockerenv = self.isDockerEnv() + if dockerenv == True: + ipmi_cmd = IPMI_PSU_DATA_DOCKER + + status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) + + if status: + logging.error('Failed to execute:' + ipmi_sdr_list) + sys.exit(0) + + for item in ipmi_sdr_list.split("\n"): + if reg_name in item: + output = item.strip() + + if not output: + print('\nFailed to fetch: ' + reg_name + ' sensor ') + sys.exit(0) + + output = output.split('|')[1] + + logging.basicConfig(level=logging.DEBUG) + return output + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + S5248F_MAX_PSUS = 2 + return S5248F_MAX_PSUS + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is\ + faulty + """ + # Until psu_status is implemented this is hardcoded temporarily + + status = 1 + return status + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + psu_reg_name = PSU_PRESENCE.format(index) + psu_status = int(self.get_pmc_register(psu_reg_name), 16) + if (psu_status != 'ERR'): + # Check for PSU presence + if (psu_status == 0x00): + status = 1 + return status + diff --git a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py new file mode 100644 index 000000000000..e6680dc8d919 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py @@ -0,0 +1,289 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# +# For S5248F-ON, hardware version X01 + +try: + import struct + import sys + import getopt + import time + from sonic_sfp.sfputilbase import SfpUtilBase + from os import * + from mmap import * + +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 1 + PORT_END = 56 + PORTS_IN_BLOCK = 56 + + BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" + + _port_to_i2c_mapping = { + 1: 2, + 2: 3, + 3: 4, + 4: 5, + 5: 6, + 6: 7, + 7: 8, + 8: 9, + 9: 10, + 10: 11, + 11: 12, + 12: 13, + 13: 14, + 14: 15, + 15: 16, + 16: 17, + 17: 18, + 18: 19, + 19: 20, + 20: 21, + 21: 22, + 22: 23, + 23: 24, + 24: 25, + 25: 26, + 26: 27, + 27: 28, + 28: 29, + 29: 30, + 30: 31, + 31: 32, + 32: 33, + 33: 34, + 34: 35, + 35: 36, + 36: 37, + 37: 38, + 38: 39, + 39: 40, + 40: 41, + 41: 42, + 42: 43, + 43: 44, + 44: 45, + 45: 46, + 46: 47, + 47: 48, + 48: 49, + # DD + QSFP28 + 49: 50, + 50: 50, + 51: 51, + 52: 51, + 53: 52, + 54: 53, + 55: 54, + 56: 55, + } + + _port_to_eeprom_mapping = {} + + + _global_port_pres_dict = {} + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return range(49, self.PORTS_IN_BLOCK + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def pci_mem_read(self, mm, offset): + mm.seek(offset) + read_data_stream=mm.read(4) + reg_val=struct.unpack('I',read_data_stream) + mem_val = str(reg_val)[1:-2] + # print "reg_val read:%x"%reg_val + return mem_val + + def pci_mem_write(self, mm, offset, data): + mm.seek(offset) + # print "data to write:%x"%data + mm.write(struct.pack('I',data)) + + def pci_set_value(self, resource, val, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + val = self.pci_mem_write(mm, offset, val) + mm.close() + close(fd) + return val + + def pci_get_value(self, resource, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + val = self.pci_mem_read(mm, offset) + mm.close() + close(fd) + return val + + def init_global_port_presence(self): + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + if(presence): + self._global_port_pres_dict[port_num] = '1' + else: + self._global_port_pres_dict[port_num] = '0' + + def __init__(self): + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + + for x in range(self.port_start, self.port_end + 1): + self.port_to_eeprom_mapping[x] = eeprom_path.format( + self._port_to_i2c_mapping[x]) + self.init_global_port_presence() + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4004 + port_offset = 16388 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == "" ): + return False + + # Mask off bit for presence + mask = (1 << 1) + if (port_num > 48): + mask = (1 << 4) + + + # ModPrsL is active low + if reg_value & mask == 0: + return True + + return False + + def get_low_power_mode(self, port_num): + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == "" ): + return False + + # Mask off 4th bit for presence + mask = (1 << 6) + + # LPMode is active high + if reg_value & mask == 0: + return False + + return True + + def set_low_power_mode(self, port_num, lpmode): + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == "" ): + return False + + # Mask off 4th bit for presence + mask = (1 << 6) + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + reg_value = reg_value | mask + else: + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + return True + + def reset(self, port_num): + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == "" ): + return False + + # Mask off 4th bit for presence + mask = (1 << 6) + + # ResetL is active low + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + # Sleep 1 second to allow it to settle + time.sleep(1) + + reg_value = reg_value | mask + + # Convert our register value back to a hex string and write back + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + return True + + def get_transceiver_change_event(self, timeout=0): + port_dict = {} + while True: + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + if(presence and self._global_port_pres_dict[port_num] == '0'): + self._global_port_pres_dict[port_num] = '1' + port_dict[port_num] = '1' + elif(not presence and + self._global_port_pres_dict[port_num] == '1'): + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + + if(len(port_dict) > 0): + return True, port_dict + + time.sleep(0.5) diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/port_config.ini b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/port_config.ini index 1dc88972d530..2bd5931d7866 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/port_config.ini +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/port_config.ini @@ -62,4 +62,6 @@ Ethernet236 173,174,175,176 hundredGigE1/60 60 100000 Ethernet240 185,186,187,188 hundredGigE1/61 61 100000 Ethernet244 189,190,191,192 hundredGigE1/62 62 100000 Ethernet248 201,202,203,204 hundredGigE1/63 63 100000 -Ethernet252 205,206,207,208 hundredGigE1/64 64 100000 +Ethernet252 205,206,207,208 hundredGigE1/64 64 100000 +Ethernet256 257 tenGigE1/65 65 10000 +Ethernet257 259 tenGigE1/66 66 10000 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/buffers.json.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/buffers.json.j2 new file mode 100644 index 000000000000..1083a6210fc9 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't0' %} +{%- include 'buffers_config.j2' %} diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..2b40c3d6ad25 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/buffers_defaults_t0.j2 @@ -0,0 +1,54 @@ +{%- set default_cable = '5m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,12) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(20,64) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(12,20) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "33096128", + "type": "ingress", + "mode": "dynamic", + "xoff": "9098752" + }, + "egress_lossy_pool": { + "size": "28132416", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "43108416", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"10777104" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/led_proc_init.soc b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/led_proc_init.soc new file mode 100644 index 000000000000..d38282b6508e --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/led_proc_init.soc @@ -0,0 +1,111 @@ +# LED microprocessor initialization for DellEMC-Z9264f + +m CMIC_LEDUP0_PORT_ORDER_REMAP_0_3 REMAP_PORT_3=32 REMAP_PORT_2=33 REMAP_PORT_1=34 REMAP_PORT_0=35 +m CMIC_LEDUP0_PORT_ORDER_REMAP_4_7 REMAP_PORT_7=36 REMAP_PORT_6=37 REMAP_PORT_5=38 REMAP_PORT_4=39 +m CMIC_LEDUP0_PORT_ORDER_REMAP_8_11 REMAP_PORT_11=4 REMAP_PORT_10=5 REMAP_PORT_9=6 REMAP_PORT_8=7 +m CMIC_LEDUP0_PORT_ORDER_REMAP_12_15 REMAP_PORT_15=0 REMAP_PORT_14=1 REMAP_PORT_13=2 REMAP_PORT_12=3 +m CMIC_LEDUP0_PORT_ORDER_REMAP_16_19 REMAP_PORT_19=56 REMAP_PORT_18=57 REMAP_PORT_17=58 REMAP_PORT_16=59 +m CMIC_LEDUP0_PORT_ORDER_REMAP_20_23 REMAP_PORT_23=60 REMAP_PORT_22=61 REMAP_PORT_21=62 REMAP_PORT_20=63 +m CMIC_LEDUP0_PORT_ORDER_REMAP_24_27 REMAP_PORT_27=28 REMAP_PORT_26=29 REMAP_PORT_25=30 REMAP_PORT_24=31 +m CMIC_LEDUP0_PORT_ORDER_REMAP_28_31 REMAP_PORT_31=24 REMAP_PORT_30=25 REMAP_PORT_29=26 REMAP_PORT_28=27 +m CMIC_LEDUP0_PORT_ORDER_REMAP_32_35 REMAP_PORT_35=48 REMAP_PORT_34=49 REMAP_PORT_33=50 REMAP_PORT_32=51 +m CMIC_LEDUP0_PORT_ORDER_REMAP_36_39 REMAP_PORT_39=52 REMAP_PORT_38=53 REMAP_PORT_37=54 REMAP_PORT_36=55 +m CMIC_LEDUP0_PORT_ORDER_REMAP_40_43 REMAP_PORT_43=20 REMAP_PORT_42=21 REMAP_PORT_41=22 REMAP_PORT_40=23 +m CMIC_LEDUP0_PORT_ORDER_REMAP_44_47 REMAP_PORT_47=16 REMAP_PORT_46=17 REMAP_PORT_45=18 REMAP_PORT_44=19 +m CMIC_LEDUP0_PORT_ORDER_REMAP_48_51 REMAP_PORT_51=40 REMAP_PORT_50=41 REMAP_PORT_49=42 REMAP_PORT_48=43 +m CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 REMAP_PORT_55=44 REMAP_PORT_54=45 REMAP_PORT_53=46 REMAP_PORT_52=47 +m CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 REMAP_PORT_59=12 REMAP_PORT_58=13 REMAP_PORT_57=14 REMAP_PORT_56=15 +m CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 REMAP_PORT_63=8 REMAP_PORT_62=9 REMAP_PORT_61=10 REMAP_PORT_60=11 +m CMIC_LEDUP1_PORT_ORDER_REMAP_0_3 REMAP_PORT_3=0 REMAP_PORT_2=1 REMAP_PORT_1=2 REMAP_PORT_0=3 +m CMIC_LEDUP1_PORT_ORDER_REMAP_4_7 REMAP_PORT_7=4 REMAP_PORT_6=5 REMAP_PORT_5=6 REMAP_PORT_4=7 +m CMIC_LEDUP1_PORT_ORDER_REMAP_8_11 REMAP_PORT_9=38 REMAP_PORT_8=39 REMAP_PORT_11=36 REMAP_PORT_10=37 +m CMIC_LEDUP1_PORT_ORDER_REMAP_12_15 REMAP_PORT_15=32 REMAP_PORT_14=33 REMAP_PORT_13=34 REMAP_PORT_12=35 +m CMIC_LEDUP1_PORT_ORDER_REMAP_16_19 REMAP_PORT_19=8 REMAP_PORT_18=9 REMAP_PORT_17=10 REMAP_PORT_16=11 +m CMIC_LEDUP1_PORT_ORDER_REMAP_20_23 REMAP_PORT_23=12 REMAP_PORT_22=13 REMAP_PORT_21=14 REMAP_PORT_20=15 +m CMIC_LEDUP1_PORT_ORDER_REMAP_24_27 REMAP_PORT_27=44 REMAP_PORT_26=45 REMAP_PORT_25=46 REMAP_PORT_24=47 +m CMIC_LEDUP1_PORT_ORDER_REMAP_28_31 REMAP_PORT_31=40 REMAP_PORT_30=41 REMAP_PORT_29=42 REMAP_PORT_28=43 +m CMIC_LEDUP1_PORT_ORDER_REMAP_32_35 REMAP_PORT_35=16 REMAP_PORT_34=17 REMAP_PORT_33=18 REMAP_PORT_32=19 +m CMIC_LEDUP1_PORT_ORDER_REMAP_36_39 REMAP_PORT_39=20 REMAP_PORT_38=21 REMAP_PORT_37=22 REMAP_PORT_36=23 +m CMIC_LEDUP1_PORT_ORDER_REMAP_40_43 REMAP_PORT_43=52 REMAP_PORT_42=53 REMAP_PORT_41=54 REMAP_PORT_40=55 +m CMIC_LEDUP1_PORT_ORDER_REMAP_44_47 REMAP_PORT_47=48 REMAP_PORT_46=49 REMAP_PORT_45=50 REMAP_PORT_44=51 +m CMIC_LEDUP1_PORT_ORDER_REMAP_48_51 REMAP_PORT_51=24 REMAP_PORT_50=25 REMAP_PORT_49=26 REMAP_PORT_48=27 +m CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 REMAP_PORT_55=28 REMAP_PORT_54=29 REMAP_PORT_53=30 REMAP_PORT_52=31 +m CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 REMAP_PORT_59=60 REMAP_PORT_58=61 REMAP_PORT_57=62 REMAP_PORT_56=63 +m CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 REMAP_PORT_63=56 REMAP_PORT_62=57 REMAP_PORT_61=58 REMAP_PORT_60=59 +m CMIC_LEDUP2_PORT_ORDER_REMAP_0_3 REMAP_PORT_3=60 REMAP_PORT_2=61 REMAP_PORT_1=62 REMAP_PORT_0=63 +m CMIC_LEDUP2_PORT_ORDER_REMAP_4_7 REMAP_PORT_7=56 REMAP_PORT_6=57 REMAP_PORT_5=58 REMAP_PORT_4=59 +m CMIC_LEDUP2_PORT_ORDER_REMAP_8_11 REMAP_PORT_11=24 REMAP_PORT_10=25 REMAP_PORT_9=26 REMAP_PORT_8=27 +m CMIC_LEDUP2_PORT_ORDER_REMAP_12_15 REMAP_PORT_15=28 REMAP_PORT_14=29 REMAP_PORT_13=30 REMAP_PORT_12=31 +m CMIC_LEDUP2_PORT_ORDER_REMAP_16_19 REMAP_PORT_19=52 REMAP_PORT_18=53 REMAP_PORT_17=54 REMAP_PORT_16=55 +m CMIC_LEDUP2_PORT_ORDER_REMAP_20_23 REMAP_PORT_23=48 REMAP_PORT_22=49 REMAP_PORT_21=50 REMAP_PORT_20=51 +m CMIC_LEDUP2_PORT_ORDER_REMAP_24_27 REMAP_PORT_27=16 REMAP_PORT_26=17 REMAP_PORT_25=18 REMAP_PORT_24=19 +m CMIC_LEDUP2_PORT_ORDER_REMAP_28_31 REMAP_PORT_31=20 REMAP_PORT_30=21 REMAP_PORT_29=22 REMAP_PORT_28=23 +m CMIC_LEDUP2_PORT_ORDER_REMAP_32_35 REMAP_PORT_35=44 REMAP_PORT_34=45 REMAP_PORT_33=46 REMAP_PORT_32=47 +m CMIC_LEDUP2_PORT_ORDER_REMAP_36_39 REMAP_PORT_39=40 REMAP_PORT_38=41 REMAP_PORT_37=42 REMAP_PORT_36=43 +m CMIC_LEDUP2_PORT_ORDER_REMAP_40_43 REMAP_PORT_43=8 REMAP_PORT_42=9 REMAP_PORT_41=10 REMAP_PORT_40=11 +m CMIC_LEDUP2_PORT_ORDER_REMAP_44_47 REMAP_PORT_47=12 REMAP_PORT_46=13 REMAP_PORT_45=14 REMAP_PORT_44=15 +m CMIC_LEDUP2_PORT_ORDER_REMAP_48_51 REMAP_PORT_51=36 REMAP_PORT_50=37 REMAP_PORT_49=38 REMAP_PORT_48=39 +m CMIC_LEDUP2_PORT_ORDER_REMAP_52_55 REMAP_PORT_55=32 REMAP_PORT_54=33 REMAP_PORT_53=34 REMAP_PORT_52=35 +m CMIC_LEDUP2_PORT_ORDER_REMAP_56_59 REMAP_PORT_59=0 REMAP_PORT_58=1 REMAP_PORT_57=2 REMAP_PORT_56=3 +m CMIC_LEDUP2_PORT_ORDER_REMAP_60_63 REMAP_PORT_63=4 REMAP_PORT_62=5 REMAP_PORT_61=6 REMAP_PORT_60=7 +m CMIC_LEDUP3_PORT_ORDER_REMAP_0_3 REMAP_PORT_3=28 REMAP_PORT_2=29 REMAP_PORT_1=30 REMAP_PORT_0=31 +m CMIC_LEDUP3_PORT_ORDER_REMAP_4_7 REMAP_PORT_7=24 REMAP_PORT_6=25 REMAP_PORT_5=26 REMAP_PORT_4=27 +m CMIC_LEDUP3_PORT_ORDER_REMAP_8_11 REMAP_PORT_11=56 REMAP_PORT_10=57 REMAP_PORT_9=58 REMAP_PORT_8=59 +m CMIC_LEDUP3_PORT_ORDER_REMAP_12_15 REMAP_PORT_15=60 REMAP_PORT_14=61 REMAP_PORT_13=62 REMAP_PORT_12=63 +m CMIC_LEDUP3_PORT_ORDER_REMAP_16_19 REMAP_PORT_19=4 REMAP_PORT_18=5 REMAP_PORT_17=6 REMAP_PORT_16=7 +m CMIC_LEDUP3_PORT_ORDER_REMAP_20_23 REMAP_PORT_23=0 REMAP_PORT_22=1 REMAP_PORT_21=2 REMAP_PORT_20=3 +m CMIC_LEDUP3_PORT_ORDER_REMAP_24_27 REMAP_PORT_27=32 REMAP_PORT_26=33 REMAP_PORT_25=34 REMAP_PORT_24=35 +m CMIC_LEDUP3_PORT_ORDER_REMAP_28_31 REMAP_PORT_31=36 REMAP_PORT_30=37 REMAP_PORT_29=38 REMAP_PORT_28=39 +m CMIC_LEDUP3_PORT_ORDER_REMAP_32_35 REMAP_PORT_35=12 REMAP_PORT_34=13 REMAP_PORT_33=14 REMAP_PORT_32=15 +m CMIC_LEDUP3_PORT_ORDER_REMAP_36_39 REMAP_PORT_39=8 REMAP_PORT_38=9 REMAP_PORT_37=10 REMAP_PORT_36=11 +m CMIC_LEDUP3_PORT_ORDER_REMAP_40_43 REMAP_PORT_43=40 REMAP_PORT_42=41 REMAP_PORT_41=42 REMAP_PORT_40=43 +m CMIC_LEDUP3_PORT_ORDER_REMAP_44_47 REMAP_PORT_47=44 REMAP_PORT_46=45 REMAP_PORT_45=46 REMAP_PORT_44=47 +m CMIC_LEDUP3_PORT_ORDER_REMAP_48_51 REMAP_PORT_51=20 REMAP_PORT_50=21 REMAP_PORT_49=22 REMAP_PORT_48=23 +m CMIC_LEDUP3_PORT_ORDER_REMAP_52_55 REMAP_PORT_55=16 REMAP_PORT_54=17 REMAP_PORT_53=18 REMAP_PORT_52=19 +m CMIC_LEDUP3_PORT_ORDER_REMAP_56_59 REMAP_PORT_59=48 REMAP_PORT_58=49 REMAP_PORT_57=50 REMAP_PORT_56=51 +m CMIC_LEDUP3_PORT_ORDER_REMAP_60_63 REMAP_PORT_63=52 REMAP_PORT_62=53 REMAP_PORT_61=54 REMAP_PORT_60=55 +m CMIC_LEDUP4_PORT_ORDER_REMAP_0_3 REMAP_PORT_3=1 REMAP_PORT_1=0 + +led 0 stop +led 0 prog \ + 02 00 60 FE 2E FE 67 1C 86 FE 06 FE D2 40 71 04 \ + 12 FF 85 05 D2 05 71 1A 52 00 3A 80 32 08 97 71 \ + 23 77 4B 32 00 32 01 B7 97 75 32 12 BC FE FE 02 \ + 0A 50 12 BC FE FE 95 75 3C 85 77 44 16 FF DA 02 \ + 71 4B 77 44 22 0F 87 22 0E 87 57 22 0E 87 22 0E \ + 87 57 22 0E 87 22 0F 87 57 00 00 00 00 00 00 00 +led 0 auto on +led 0 start + +led 1 stop +led 1 prog \ + 02 00 60 FE 2E FE 67 1C 86 FE 06 FE D2 40 71 04 \ + 12 FF 85 05 D2 05 71 1A 52 00 3A 80 32 08 97 71 \ + 23 77 4B 32 00 32 01 B7 97 75 32 12 BC FE FE 02 \ + 0A 50 12 BC FE FE 95 75 3C 85 77 44 16 FF DA 02 \ + 71 4B 77 44 22 0F 87 22 0E 87 57 22 0E 87 22 0E \ + 87 57 22 0E 87 22 0F 87 57 00 00 00 00 00 00 00 +led 1 auto on +led 1 start + +led 2 stop +led 2 prog \ + 02 00 60 FE 2E FE 67 1C 86 FE 06 FE D2 40 71 04 \ + 12 FF 85 05 D2 05 71 1A 52 00 3A 80 32 08 97 71 \ + 23 77 4B 32 00 32 01 B7 97 75 32 12 BC FE FE 02 \ + 0A 50 12 BC FE FE 95 75 3C 85 77 44 16 FF DA 02 \ + 71 4B 77 44 22 0F 87 22 0E 87 57 22 0E 87 22 0E \ + 87 57 22 0E 87 22 0F 87 57 00 00 00 00 00 00 00 +led 2 auto on +led 2 start + +led 3 stop +led 3 prog \ + 02 00 60 FE 2E FE 67 1C 86 FE 06 FE D2 40 71 04 \ + 12 FF 85 05 D2 05 71 1A 52 00 3A 80 32 08 97 71 \ + 23 77 4B 32 00 32 01 B7 97 75 32 12 BC FE FE 02 \ + 0A 50 12 BC FE FE 95 75 3C 85 77 44 16 FF DA 02 \ + 71 4B 77 44 22 0F 87 22 0E 87 57 22 0E 87 22 0E \ + 87 57 22 0E 87 22 0F 87 57 00 00 00 00 00 00 00 +led 3 auto on +led 3 start diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/pg_profile_lookup.ini b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/pg_profile_lookup.ini new file mode 100644 index 000000000000..aedda37a8878 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/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_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/port_config.ini b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/port_config.ini new file mode 100644 index 000000000000..27c3906a9a49 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/port_config.ini @@ -0,0 +1,123 @@ +# name lanes alias index speed +Ethernet0 49,50 fiftyGigE1/1/1 1 50000 +Ethernet2 51,52 fiftyGigE1/1/2 1 50000 +Ethernet4 53,54 fiftyGigE1/2/1 2 50000 +Ethernet6 55,56 fiftyGigE1/2/2 2 50000 +Ethernet8 65,66 fiftyGigE1/3/1 3 50000 +Ethernet10 67,68 fiftyGigE1/3/2 3 50000 +Ethernet12 69,70 fiftyGigE1/4/1 4 50000 +Ethernet14 71,72 fiftyGigE1/4/2 4 50000 +Ethernet16 81,82 fiftyGigE1/5/1 5 50000 +Ethernet18 83,84 fiftyGigE1/5/2 5 50000 +Ethernet20 85,86 fiftyGigE1/6/1 6 50000 +Ethernet22 87,88 fiftyGigE1/6/2 6 50000 +Ethernet24 97,98 fiftyGigE1/7/1 7 50000 +Ethernet26 99,100 fiftyGigE1/7/2 7 50000 +Ethernet28 101,102 fiftyGigE1/8/1 8 50000 +Ethernet30 103,104 fiftyGigE1/8/2 8 50000 +Ethernet32 1,2 fiftyGigE1/9/1 9 50000 +Ethernet34 3,4 fiftyGigE1/9/2 9 50000 +Ethernet36 5,6 fiftyGigE1/10/1 10 50000 +Ethernet38 7,8 fiftyGigE1/10/2 10 50000 +Ethernet40 17,18 fiftyGigE1/11/1 11 50000 +Ethernet42 19,20 fiftyGigE1/11/2 11 50000 +Ethernet44 21,22 fiftyGigE1/12/1 12 50000 +Ethernet46 23,24 fiftyGigE1/12/2 12 50000 +Ethernet48 33,34,35,36 hundredGigE1/13 13 100000 +Ethernet52 37,38,39,40 hundredGigE1/14 14 100000 +Ethernet56 113,114,115,116 hundredGigE1/15 15 100000 +Ethernet60 117,118,119,120 hundredGigE1/16 16 100000 +Ethernet64 133,134,135,136 hundredGigE1/17 17 100000 +Ethernet68 129,130,131,132 hundredGigE1/18 18 100000 +Ethernet72 213,214,215,216 hundredGigE1/19 19 100000 +Ethernet76 209,210,211,212 hundredGigE1/20 20 100000 +Ethernet80 229,230 fiftyGigE1/21/1 21 50000 +Ethernet82 231,232 fiftyGigE1/21/2 21 50000 +Ethernet84 225,226 fiftyGigE1/22/1 22 50000 +Ethernet86 227,228 fiftyGigE1/22/2 22 50000 +Ethernet88 245,246 fiftyGigE1/23/1 23 50000 +Ethernet90 247,248 fiftyGigE1/23/2 23 50000 +Ethernet92 241,242 fiftyGigE1/24/1 24 50000 +Ethernet94 243,244 fiftyGigE1/24/2 24 50000 +Ethernet96 149,150 fiftyGigE1/25/1 25 50000 +Ethernet98 151,152 fiftyGigE1/25/2 25 50000 +Ethernet100 145,146 fiftyGigE1/26/1 26 50000 +Ethernet102 147,148 fiftyGigE1/26/2 26 50000 +Ethernet104 165,166 fiftyGigE1/27/1 27 50000 +Ethernet106 167,168 fiftyGigE1/27/2 27 50000 +Ethernet108 161,162 fiftyGigE1/28/1 28 50000 +Ethernet110 163,164 fiftyGigE1/28/2 28 50000 +Ethernet112 181,182 fiftyGigE1/29/1 29 50000 +Ethernet114 183,184 fiftyGigE1/29/2 29 50000 +Ethernet116 177,178 fiftyGigE1/30/1 30 50000 +Ethernet118 179,180 fiftyGigE1/30/2 30 50000 +Ethernet120 197,198 fiftyGigE1/31/1 31 50000 +Ethernet122 199,200 fiftyGigE1/31/2 31 50000 +Ethernet124 193,194 fiftyGigE1/32/1 32 50000 +Ethernet126 195,196 fiftyGigE1/32/2 32 50000 +Ethernet128 61,62 fiftyGigE1/33/1 33 50000 +Ethernet130 63,64 fiftyGigE1/33/2 33 50000 +Ethernet132 57,58 fiftyGigE1/34/1 34 50000 +Ethernet134 59,60 fiftyGigE1/34/2 34 50000 +Ethernet136 77,78 fiftyGigE1/35/1 35 50000 +Ethernet138 79,80 fiftyGigE1/35/2 35 50000 +Ethernet140 73,74 fiftyGigE1/36/1 36 50000 +Ethernet142 75,76 fiftyGigE1/36/2 36 50000 +Ethernet144 93,94 fiftyGigE1/37/1 37 50000 +Ethernet146 95,96 fiftyGigE1/37/2 37 50000 +Ethernet148 89,90 fiftyGigE1/38/1 38 50000 +Ethernet150 91,92 fiftyGigE1/38/2 38 50000 +Ethernet152 109,110 fiftyGigE1/39/1 39 50000 +Ethernet154 111,112 fiftyGigE1/39/2 39 50000 +Ethernet156 105,106 fiftyGigE1/40/1 40 50000 +Ethernet158 107,108 fiftyGigE1/40/2 40 50000 +Ethernet160 13,14 fiftyGigE1/41/1 41 50000 +Ethernet162 15,16 fiftyGigE1/41/2 41 50000 +Ethernet164 9,10 fiftyGigE1/42/1 42 50000 +Ethernet166 11,12 fiftyGigE1/42/2 42 50000 +Ethernet168 29,30 fiftyGigE1/43/1 43 50000 +Ethernet170 31,32 fiftyGigE1/43/2 43 50000 +Ethernet172 25,26 fiftyGigE1/44/1 44 50000 +Ethernet174 27,28 fiftyGigE1/44/2 44 50000 +Ethernet176 45,46 fiftyGigE1/45/1 45 50000 +Ethernet178 47,48 fiftyGigE1/45/2 45 50000 +Ethernet180 41,42 fiftyGigE1/46/1 46 50000 +Ethernet182 43,44 fiftyGigE1/46/2 46 50000 +Ethernet184 125,126 fiftyGigE1/47/1 47 50000 +Ethernet186 127,128 fiftyGigE1/47/2 47 50000 +Ethernet188 121,122 fiftyGigE1/48/1 48 50000 +Ethernet190 123,124 fiftyGigE1/48/2 48 50000 +Ethernet192 137,138 fiftyGigE1/49/1 49 50000 +Ethernet194 139,140 fiftyGigE1/49/2 49 50000 +Ethernet196 141,142 fiftyGigE1/50/1 50 50000 +Ethernet198 143,144 fiftyGigE1/50/2 50 50000 +Ethernet200 217,218 fiftyGigE1/51/1 51 50000 +Ethernet202 219,220 fiftyGigE1/51/2 51 50000 +Ethernet204 221,222 fiftyGigE1/52/1 52 50000 +Ethernet206 223,224 fiftyGigE1/52/2 52 50000 +Ethernet208 233,234 fiftyGigE1/53/1 53 50000 +Ethernet210 235,236 fiftyGigE1/53/2 53 50000 +Ethernet212 237,238 fiftyGigE1/54/1 54 50000 +Ethernet214 239,240 fiftyGigE1/54/2 54 50000 +Ethernet216 249,250 fiftyGigE1/55/1 55 50000 +Ethernet218 251,252 fiftyGigE1/55/2 55 50000 +Ethernet220 253,254 fiftyGigE1/56/1 56 50000 +Ethernet222 255,256 fiftyGigE1/56/2 56 50000 +Ethernet224 153,154 fiftyGigE1/57/1 57 50000 +Ethernet226 155,156 fiftyGigE1/57/2 57 50000 +Ethernet228 157,158 fiftyGigE1/58/1 58 50000 +Ethernet230 159,160 fiftyGigE1/58/2 58 50000 +Ethernet232 169,170 fiftyGigE1/59/1 59 50000 +Ethernet234 171,172 fiftyGigE1/59/2 59 50000 +Ethernet236 173,174 fiftyGigE1/60/1 60 50000 +Ethernet238 175,176 fiftyGigE1/60/2 60 50000 +Ethernet240 185,186 fiftyGigE1/61/1 61 50000 +Ethernet242 187,188 fiftyGigE1/61/2 61 50000 +Ethernet244 189,190 fiftyGigE1/62/1 62 50000 +Ethernet246 191,192 fiftyGigE1/62/2 62 50000 +Ethernet248 201,202 fiftyGigE1/63/1 63 50000 +Ethernet250 203,204 fiftyGigE1/63/2 63 50000 +Ethernet252 205,206 fiftyGigE1/64/1 64 50000 +Ethernet254 207,208 fiftyGigE1/64/2 64 50000 +Ethernet256 257 tenGigE1/65 65 10000 +Ethernet257 259 tenGigE1/66 66 10000 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/qos.json.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/sai.profile b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/sai.profile new file mode 100644 index 000000000000..7bf21827cd19 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-z9264f-8x100G-112x50G.config.bcm diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/th2-z9264f-8x100G-112x50G.config.bcm b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/th2-z9264f-8x100G-112x50G.config.bcm new file mode 100644 index 000000000000..f4b3addfb516 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/th2-z9264f-8x100G-112x50G.config.bcm @@ -0,0 +1,1119 @@ +#TH2 Z9264F 112x50G,8x100G +os=unix +core_clock_frequency=1700 +dpp_clock_ratio=2:3 +pbmp_xport_xe=0xfffffffd3fffffff4fffffffc7ffffffe +oversubscribe_mode=1 +fpem_mem_entries=65536 +l2xmsg_mode=1 + +l3_alpm_enable=2 +bcm_num_cos=8 +switch_bypass_mode=0 +mmu_lossless=0 +lpm_scaling_enable=0 +lpm_ipv6_128b_reserved=0 +ipv6_lpm_128b_enable=1 + +parity_correction=1 +parity_enable=1 + +dport_map_enable=1 + +dport_map_port_23=1 +dport_map_port_24=2 +dport_map_port_25=3 +dport_map_port_26=4 +dport_map_port_34=5 +dport_map_port_35=6 +dport_map_port_36=7 +dport_map_port_37=8 +dport_map_port_42=9 +dport_map_port_43=10 +dport_map_port_44=11 +dport_map_port_45=12 +dport_map_port_50=13 +dport_map_port_51=14 +dport_map_port_52=15 +dport_map_port_53=16 +dport_map_port_1=17 +dport_map_port_2=18 +dport_map_port_3=19 +dport_map_port_4=20 +dport_map_port_9=21 +dport_map_port_10=22 +dport_map_port_11=23 +dport_map_port_12=24 + +dport_map_port_17=25 +dport_map_port_18=26 +dport_map_port_58=27 +dport_map_port_59=28 +dport_map_port_69=29 +dport_map_port_68=30 +dport_map_port_111=31 +dport_map_port_110=32 +dport_map_port_118=33 +dport_map_port_119=34 +dport_map_port_116=35 +dport_map_port_117=36 +dport_map_port_126=37 +dport_map_port_127=38 +dport_map_port_124=39 +dport_map_port_125=40 +dport_map_port_76=41 +dport_map_port_77=42 +dport_map_port_74=43 +dport_map_port_75=44 +dport_map_port_84=45 +dport_map_port_85=46 +dport_map_port_82=47 +dport_map_port_83=48 +dport_map_port_92=49 +dport_map_port_93=50 +dport_map_port_90=51 +dport_map_port_91=52 +dport_map_port_104=53 +dport_map_port_105=54 +dport_map_port_102=55 +dport_map_port_103=56 +dport_map_port_29=57 +dport_map_port_30=58 +dport_map_port_27=59 +dport_map_port_28=60 +dport_map_port_40=61 +dport_map_port_41=62 +dport_map_port_38=63 +dport_map_port_39=64 +dport_map_port_48=65 +dport_map_port_49=66 +dport_map_port_46=67 +dport_map_port_47=68 +dport_map_port_56=69 +dport_map_port_57=70 +dport_map_port_54=71 +dport_map_port_55=72 +dport_map_port_7=73 +dport_map_port_8=74 +dport_map_port_5=75 +dport_map_port_6=76 +dport_map_port_15=77 +dport_map_port_16=78 +dport_map_port_13=79 +dport_map_port_14=80 +dport_map_port_21=81 +dport_map_port_22=82 +dport_map_port_19=83 +dport_map_port_20=84 +dport_map_port_62=85 +dport_map_port_63=86 +dport_map_port_60=87 +dport_map_port_61=88 +dport_map_port_70=89 +dport_map_port_71=90 +dport_map_port_72=91 +dport_map_port_73=92 +dport_map_port_112=93 +dport_map_port_113=94 +dport_map_port_114=95 +dport_map_port_115=96 +dport_map_port_120=97 +dport_map_port_121=98 +dport_map_port_122=99 +dport_map_port_123=100 +dport_map_port_128=101 +dport_map_port_129=102 +dport_map_port_130=103 +dport_map_port_131=104 +dport_map_port_78=105 +dport_map_port_79=106 +dport_map_port_80=107 +dport_map_port_81=108 +dport_map_port_86=109 +dport_map_port_87=110 +dport_map_port_88=111 +dport_map_port_89=112 +dport_map_port_94=113 +dport_map_port_95=114 +dport_map_port_96=115 +dport_map_port_97=116 +dport_map_port_106=117 +dport_map_port_107=118 +dport_map_port_108=119 +dport_map_port_109=120 + +# +# Tile-0 FC0~FC15 +# +portmap_1=1:50:2 +portmap_2=3:50:2 +portmap_3=5:50:2 +portmap_4=7:50:2 +portmap_5=9:50:2 +portmap_6=11:50:2 +portmap_7=13:50:2 +portmap_8=15:50:2 +portmap_9=17:50:2 +portmap_10=19:50:2 +portmap_11=21:50:2 +portmap_12=23:50:2 +portmap_13=25:50:2 +portmap_14=27:50:2 +portmap_15=29:50:2 +portmap_16=31:50:2 +portmap_17=33:100 +portmap_18=37:100 +portmap_19=41:50:2 +portmap_20=43:50:2 +portmap_21=45:50:2 +portmap_22=47:50:2 +portmap_23=49:50:2 +portmap_24=51:50:2 +portmap_25=53:50:2 +portmap_26=55:50:2 +portmap_27=57:50:2 +portmap_28=59:50:2 +portmap_29=61:50:2 +portmap_30=63:50:2 + + +# TX polarity +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_tx_polarity_flip_physical{3.0}=0x1 +phy_chain_tx_polarity_flip_physical{4.0}=0x1 + +phy_chain_tx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x0 +phy_chain_tx_polarity_flip_physical{7.0}=0x1 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 + +phy_chain_tx_polarity_flip_physical{9.0}=0x0 +phy_chain_tx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x1 + +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_tx_polarity_flip_physical{16.0}=0x1 + +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_tx_polarity_flip_physical{18.0}=0x0 +phy_chain_tx_polarity_flip_physical{19.0}=0x1 +phy_chain_tx_polarity_flip_physical{20.0}=0x1 + +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_tx_polarity_flip_physical{24.0}=0x1 + +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_tx_polarity_flip_physical{26.0}=0x1 +phy_chain_tx_polarity_flip_physical{27.0}=0x1 +phy_chain_tx_polarity_flip_physical{28.0}=0x1 + +phy_chain_tx_polarity_flip_physical{29.0}=0x1 +phy_chain_tx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_tx_polarity_flip_physical{32.0}=0x1 + +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_tx_polarity_flip_physical{36.0}=0x1 + +phy_chain_tx_polarity_flip_physical{37.0}=0x0 +phy_chain_tx_polarity_flip_physical{38.0}=0x1 +phy_chain_tx_polarity_flip_physical{39.0}=0x0 +phy_chain_tx_polarity_flip_physical{40.0}=0x1 + +phy_chain_tx_polarity_flip_physical{41.0}=0x1 +phy_chain_tx_polarity_flip_physical{42.0}=0x1 +phy_chain_tx_polarity_flip_physical{43.0}=0x0 +phy_chain_tx_polarity_flip_physical{44.0}=0x0 + +phy_chain_tx_polarity_flip_physical{45.0}=0x0 +phy_chain_tx_polarity_flip_physical{46.0}=0x0 +phy_chain_tx_polarity_flip_physical{47.0}=0x0 +phy_chain_tx_polarity_flip_physical{48.0}=0x1 + +phy_chain_tx_polarity_flip_physical{49.0}=0x0 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 + +phy_chain_tx_polarity_flip_physical{53.0}=0x0 +phy_chain_tx_polarity_flip_physical{54.0}=0x0 +phy_chain_tx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x1 + +phy_chain_tx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x0 + +phy_chain_tx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x1 +phy_chain_tx_polarity_flip_physical{63.0}=0x0 +phy_chain_tx_polarity_flip_physical{64.0}=0x1 + +# RX polarity +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 + +phy_chain_rx_polarity_flip_physical{5.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x0 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 + +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{10.0}=0x1 +phy_chain_rx_polarity_flip_physical{11.0}=0x0 +phy_chain_rx_polarity_flip_physical{12.0}=0x0 + +phy_chain_rx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_rx_polarity_flip_physical{16.0}=0x0 + +phy_chain_rx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{18.0}=0x1 +phy_chain_rx_polarity_flip_physical{19.0}=0x1 +phy_chain_rx_polarity_flip_physical{20.0}=0x0 + +phy_chain_rx_polarity_flip_physical{21.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x0 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_rx_polarity_flip_physical{24.0}=0x0 + +phy_chain_rx_polarity_flip_physical{25.0}=0x1 +phy_chain_rx_polarity_flip_physical{26.0}=0x0 +phy_chain_rx_polarity_flip_physical{27.0}=0x0 +phy_chain_rx_polarity_flip_physical{28.0}=0x1 + +phy_chain_rx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{31.0}=0x1 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 + +phy_chain_rx_polarity_flip_physical{33.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{36.0}=0x1 + +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x0 +phy_chain_rx_polarity_flip_physical{39.0}=0x0 +phy_chain_rx_polarity_flip_physical{40.0}=0x1 + +phy_chain_rx_polarity_flip_physical{41.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x0 + +phy_chain_rx_polarity_flip_physical{45.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{47.0}=0x0 +phy_chain_rx_polarity_flip_physical{48.0}=0x1 + +phy_chain_rx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x1 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x0 + +phy_chain_rx_polarity_flip_physical{53.0}=0x1 +phy_chain_rx_polarity_flip_physical{54.0}=0x0 +phy_chain_rx_polarity_flip_physical{55.0}=0x0 +phy_chain_rx_polarity_flip_physical{56.0}=0x1 + +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_rx_polarity_flip_physical{59.0}=0x1 +phy_chain_rx_polarity_flip_physical{60.0}=0x0 + +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_rx_polarity_flip_physical{63.0}=0x0 +phy_chain_rx_polarity_flip_physical{64.0}=0x1 + +# TX lane swap +phy_chain_tx_lane_map_physical{1.0}=0x3120 +phy_chain_tx_lane_map_physical{5.0}=0x2130 +phy_chain_tx_lane_map_physical{9.0}=0x0213 +phy_chain_tx_lane_map_physical{13.0}=0x3021 + +phy_chain_tx_lane_map_physical{17.0}=0x3201 +phy_chain_tx_lane_map_physical{21.0}=0x3210 +phy_chain_tx_lane_map_physical{25.0}=0x1023 +phy_chain_tx_lane_map_physical{29.0}=0x0231 + +phy_chain_tx_lane_map_physical{33.0}=0x3210 +phy_chain_tx_lane_map_physical{37.0}=0x3120 +phy_chain_tx_lane_map_physical{41.0}=0x2031 +phy_chain_tx_lane_map_physical{45.0}=0x2130 + +phy_chain_tx_lane_map_physical{49.0}=0x2130 +phy_chain_tx_lane_map_physical{53.0}=0x3012 +phy_chain_tx_lane_map_physical{57.0}=0x2031 +phy_chain_tx_lane_map_physical{61.0}=0x0231 + +# RX lane swap +phy_chain_rx_lane_map_physical{1.0}=0x1320 +phy_chain_rx_lane_map_physical{5.0}=0x0213 +phy_chain_rx_lane_map_physical{9.0}=0x2301 +phy_chain_rx_lane_map_physical{13.0}=0x0321 + +phy_chain_rx_lane_map_physical{17.0}=0x2031 +phy_chain_rx_lane_map_physical{21.0}=0x1032 +phy_chain_rx_lane_map_physical{25.0}=0x2310 +phy_chain_rx_lane_map_physical{29.0}=0x2013 + +phy_chain_rx_lane_map_physical{33.0}=0x2103 +phy_chain_rx_lane_map_physical{37.0}=0x0132 +phy_chain_rx_lane_map_physical{41.0}=0x2031 +phy_chain_rx_lane_map_physical{45.0}=0x1032 + +phy_chain_rx_lane_map_physical{49.0}=0x3201 +phy_chain_rx_lane_map_physical{53.0}=0x0132 +phy_chain_rx_lane_map_physical{57.0}=0x2031 +phy_chain_rx_lane_map_physical{61.0}=0x1032 + +# +# Tile-1 FC16~FC31 +# +portmap_34=65:50:2 +portmap_35=67:50:2 +portmap_36=69:50:2 +portmap_37=71:50:2 +portmap_38=73:50:2 +portmap_39=75:50:2 +portmap_40=77:50:2 +portmap_41=79:50:2 +portmap_42=81:50:2 +portmap_43=83:50:2 +portmap_44=85:50:2 +portmap_45=87:50:2 +portmap_46=89:50:2 +portmap_47=91:50:2 +portmap_48=93:50:2 +portmap_49=95:50:2 +portmap_50=97:50:2 +portmap_51=99:50:2 +portmap_52=101:50:2 +portmap_53=103:50:2 +portmap_54=105:50:2 +portmap_55=107:50:2 +portmap_56=109:50:2 +portmap_57=111:50:2 +portmap_58=113:100 +portmap_59=117:100 +portmap_60=121:50:2 +portmap_61=123:50:2 +portmap_62=125:50:2 +portmap_63=127:50:2 + +#TX polarity +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_tx_polarity_flip_physical{66.0}=0x1 +phy_chain_tx_polarity_flip_physical{67.0}=0x0 +phy_chain_tx_polarity_flip_physical{68.0}=0x0 + +phy_chain_tx_polarity_flip_physical{69.0}=0x1 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_tx_polarity_flip_physical{72.0}=0x1 + +phy_chain_tx_polarity_flip_physical{73.0}=0x0 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_tx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x0 + +phy_chain_tx_polarity_flip_physical{77.0}=0x1 +phy_chain_tx_polarity_flip_physical{78.0}=0x1 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x1 + +phy_chain_tx_polarity_flip_physical{81.0}=0x1 +phy_chain_tx_polarity_flip_physical{82.0}=0x1 +phy_chain_tx_polarity_flip_physical{83.0}=0x0 +phy_chain_tx_polarity_flip_physical{84.0}=0x0 + +phy_chain_tx_polarity_flip_physical{85.0}=0x1 +phy_chain_tx_polarity_flip_physical{86.0}=0x1 +phy_chain_tx_polarity_flip_physical{87.0}=0x0 +phy_chain_tx_polarity_flip_physical{88.0}=0x0 + +phy_chain_tx_polarity_flip_physical{89.0}=0x0 +phy_chain_tx_polarity_flip_physical{90.0}=0x1 +phy_chain_tx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x0 + +phy_chain_tx_polarity_flip_physical{93.0}=0x1 +phy_chain_tx_polarity_flip_physical{94.0}=0x1 +phy_chain_tx_polarity_flip_physical{95.0}=0x1 +phy_chain_tx_polarity_flip_physical{96.0}=0x1 + +phy_chain_tx_polarity_flip_physical{97.0}=0x0 +phy_chain_tx_polarity_flip_physical{98.0}=0x0 +phy_chain_tx_polarity_flip_physical{99.0}=0x0 +phy_chain_tx_polarity_flip_physical{100.0}=0x1 + +phy_chain_tx_polarity_flip_physical{101.0}=0x1 +phy_chain_tx_polarity_flip_physical{102.0}=0x0 +phy_chain_tx_polarity_flip_physical{103.0}=0x1 +phy_chain_tx_polarity_flip_physical{104.0}=0x0 + +phy_chain_tx_polarity_flip_physical{105.0}=0x0 +phy_chain_tx_polarity_flip_physical{106.0}=0x1 +phy_chain_tx_polarity_flip_physical{107.0}=0x0 +phy_chain_tx_polarity_flip_physical{108.0}=0x0 + +phy_chain_tx_polarity_flip_physical{109.0}=0x0 +phy_chain_tx_polarity_flip_physical{110.0}=0x1 +phy_chain_tx_polarity_flip_physical{111.0}=0x0 +phy_chain_tx_polarity_flip_physical{112.0}=0x0 + +phy_chain_tx_polarity_flip_physical{113.0}=0x1 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x0 +phy_chain_tx_polarity_flip_physical{116.0}=0x0 + +phy_chain_tx_polarity_flip_physical{117.0}=0x0 +phy_chain_tx_polarity_flip_physical{118.0}=0x1 +phy_chain_tx_polarity_flip_physical{119.0}=0x0 +phy_chain_tx_polarity_flip_physical{120.0}=0x0 + +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_tx_polarity_flip_physical{122.0}=0x0 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 + +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_tx_polarity_flip_physical{126.0}=0x1 +phy_chain_tx_polarity_flip_physical{127.0}=0x1 +phy_chain_tx_polarity_flip_physical{128.0}=0x1 + +#RX polarity +phy_chain_rx_polarity_flip_physical{65.0}=0x0 +phy_chain_rx_polarity_flip_physical{66.0}=0x0 +phy_chain_rx_polarity_flip_physical{67.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x1 + +phy_chain_rx_polarity_flip_physical{69.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 + +phy_chain_rx_polarity_flip_physical{73.0}=0x0 +phy_chain_rx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{75.0}=0x1 +phy_chain_rx_polarity_flip_physical{76.0}=0x0 + +phy_chain_rx_polarity_flip_physical{77.0}=0x1 +phy_chain_rx_polarity_flip_physical{78.0}=0x1 +phy_chain_rx_polarity_flip_physical{79.0}=0x0 +phy_chain_rx_polarity_flip_physical{80.0}=0x1 + +phy_chain_rx_polarity_flip_physical{81.0}=0x0 +phy_chain_rx_polarity_flip_physical{82.0}=0x0 +phy_chain_rx_polarity_flip_physical{83.0}=0x0 +phy_chain_rx_polarity_flip_physical{84.0}=0x1 + +phy_chain_rx_polarity_flip_physical{85.0}=0x0 +phy_chain_rx_polarity_flip_physical{86.0}=0x0 +phy_chain_rx_polarity_flip_physical{87.0}=0x1 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 + +phy_chain_rx_polarity_flip_physical{89.0}=0x0 +phy_chain_rx_polarity_flip_physical{90.0}=0x1 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_rx_polarity_flip_physical{92.0}=0x0 + +phy_chain_rx_polarity_flip_physical{93.0}=0x0 +phy_chain_rx_polarity_flip_physical{94.0}=0x1 +phy_chain_rx_polarity_flip_physical{95.0}=0x0 +phy_chain_rx_polarity_flip_physical{96.0}=0x0 + +phy_chain_rx_polarity_flip_physical{97.0}=0x0 +phy_chain_rx_polarity_flip_physical{98.0}=0x1 +phy_chain_rx_polarity_flip_physical{99.0}=0x0 +phy_chain_rx_polarity_flip_physical{100.0}=0x1 + +phy_chain_rx_polarity_flip_physical{101.0}=0x0 +phy_chain_rx_polarity_flip_physical{102.0}=0x0 +phy_chain_rx_polarity_flip_physical{103.0}=0x1 +phy_chain_rx_polarity_flip_physical{104.0}=0x1 + +phy_chain_rx_polarity_flip_physical{105.0}=0x1 +phy_chain_rx_polarity_flip_physical{106.0}=0x0 +phy_chain_rx_polarity_flip_physical{107.0}=0x0 +phy_chain_rx_polarity_flip_physical{108.0}=0x1 + +phy_chain_rx_polarity_flip_physical{109.0}=0x0 +phy_chain_rx_polarity_flip_physical{110.0}=0x1 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{112.0}=0x1 + +phy_chain_rx_polarity_flip_physical{113.0}=0x0 +phy_chain_rx_polarity_flip_physical{114.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x1 +phy_chain_rx_polarity_flip_physical{116.0}=0x0 + +phy_chain_rx_polarity_flip_physical{117.0}=0x1 +phy_chain_rx_polarity_flip_physical{118.0}=0x0 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{120.0}=0x0 + +phy_chain_rx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x0 +phy_chain_rx_polarity_flip_physical{124.0}=0x0 + +phy_chain_rx_polarity_flip_physical{125.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x1 +phy_chain_rx_polarity_flip_physical{127.0}=0x1 +phy_chain_rx_polarity_flip_physical{128.0}=0x0 + +# TX lane swap +phy_chain_tx_lane_map_physical{65.0}=0x2130 +phy_chain_tx_lane_map_physical{69.0}=0x3012 +phy_chain_tx_lane_map_physical{73.0}=0x2031 +phy_chain_tx_lane_map_physical{77.0}=0x0231 + +phy_chain_tx_lane_map_physical{81.0}=0x2130 +phy_chain_tx_lane_map_physical{85.0}=0x1032 +phy_chain_tx_lane_map_physical{89.0}=0x2031 +phy_chain_tx_lane_map_physical{93.0}=0x0231 + +phy_chain_tx_lane_map_physical{97.0}=0x0123 +phy_chain_tx_lane_map_physical{101.0}=0x1320 +phy_chain_tx_lane_map_physical{105.0}=0x2301 +phy_chain_tx_lane_map_physical{109.0}=0x0213 + +phy_chain_tx_lane_map_physical{113.0}=0x0123 +phy_chain_tx_lane_map_physical{117.0}=0x1023 +phy_chain_tx_lane_map_physical{121.0}=0x2130 +phy_chain_tx_lane_map_physical{125.0}=0x1302 + +# RX lane swap +phy_chain_rx_lane_map_physical{65.0}=0x2103 +phy_chain_rx_lane_map_physical{69.0}=0x3210 +phy_chain_rx_lane_map_physical{73.0}=0x2031 +phy_chain_rx_lane_map_physical{77.0}=0x1032 + +phy_chain_rx_lane_map_physical{81.0}=0x2103 +phy_chain_rx_lane_map_physical{85.0}=0x3210 +phy_chain_rx_lane_map_physical{89.0}=0x2031 +phy_chain_rx_lane_map_physical{93.0}=0x1032 + +phy_chain_rx_lane_map_physical{97.0}=0x1023 +phy_chain_rx_lane_map_physical{101.0}=0x3120 +phy_chain_rx_lane_map_physical{105.0}=0x1023 +phy_chain_rx_lane_map_physical{109.0}=0x0231 + +phy_chain_rx_lane_map_physical{113.0}=0x1320 +phy_chain_rx_lane_map_physical{117.0}=0x3102 +phy_chain_rx_lane_map_physical{121.0}=0x0213 +phy_chain_rx_lane_map_physical{125.0}=0x0231 + +# +# Tile-2 FC32~FC47 +# +# port 66 is the first management port +portmap_66=257:10 +# port 67 is the second loopback port +#portmap_67=261:10 +portmap_68=129:100 +portmap_69=133:100 +portmap_70=137:50:2 +portmap_71=139:50:2 +portmap_72=141:50:2 +portmap_73=143:50:2 +portmap_74=145:50:2 +portmap_75=147:50:2 +portmap_76=149:50:2 +portmap_77=151:50:2 +portmap_78=153:50:2 +portmap_79=155:50:2 +portmap_80=157:50:2 +portmap_81=159:50:2 +portmap_82=161:50:2 +portmap_83=163:50:2 +portmap_84=165:50:2 +portmap_85=167:50:2 +portmap_86=169:50:2 +portmap_87=171:50:2 +portmap_88=173:50:2 +portmap_89=175:50:2 +portmap_90=177:50:2 +portmap_91=179:50:2 +portmap_92=181:50:2 +portmap_93=183:50:2 +portmap_94=185:50:2 +portmap_95=187:50:2 +portmap_96=189:50:2 +portmap_97=191:50:2 + + +# TX polarity +phy_chain_tx_polarity_flip_physical{129.0}=0x1 +phy_chain_tx_polarity_flip_physical{130.0}=0x0 +phy_chain_tx_polarity_flip_physical{131.0}=0x1 +phy_chain_tx_polarity_flip_physical{132.0}=0x1 + +phy_chain_tx_polarity_flip_physical{133.0}=0x0 +phy_chain_tx_polarity_flip_physical{134.0}=0x0 +phy_chain_tx_polarity_flip_physical{135.0}=0x1 +phy_chain_tx_polarity_flip_physical{136.0}=0x1 + +phy_chain_tx_polarity_flip_physical{137.0}=0x1 +phy_chain_tx_polarity_flip_physical{138.0}=0x0 +phy_chain_tx_polarity_flip_physical{139.0}=0x1 +phy_chain_tx_polarity_flip_physical{140.0}=0x0 + +phy_chain_tx_polarity_flip_physical{141.0}=0x1 +phy_chain_tx_polarity_flip_physical{142.0}=0x0 +phy_chain_tx_polarity_flip_physical{143.0}=0x1 +phy_chain_tx_polarity_flip_physical{144.0}=0x1 + +phy_chain_tx_polarity_flip_physical{145.0}=0x1 +phy_chain_tx_polarity_flip_physical{146.0}=0x0 +phy_chain_tx_polarity_flip_physical{147.0}=0x0 +phy_chain_tx_polarity_flip_physical{148.0}=0x1 + +phy_chain_tx_polarity_flip_physical{149.0}=0x0 +phy_chain_tx_polarity_flip_physical{150.0}=0x1 +phy_chain_tx_polarity_flip_physical{151.0}=0x1 +phy_chain_tx_polarity_flip_physical{152.0}=0x1 + +phy_chain_tx_polarity_flip_physical{153.0}=0x0 +phy_chain_tx_polarity_flip_physical{154.0}=0x1 +phy_chain_tx_polarity_flip_physical{155.0}=0x0 +phy_chain_tx_polarity_flip_physical{156.0}=0x0 + +phy_chain_tx_polarity_flip_physical{157.0}=0x0 +phy_chain_tx_polarity_flip_physical{158.0}=0x0 +phy_chain_tx_polarity_flip_physical{159.0}=0x1 +phy_chain_tx_polarity_flip_physical{160.0}=0x0 + +phy_chain_tx_polarity_flip_physical{161.0}=0x1 +phy_chain_tx_polarity_flip_physical{162.0}=0x0 +phy_chain_tx_polarity_flip_physical{163.0}=0x0 +phy_chain_tx_polarity_flip_physical{164.0}=0x1 + +phy_chain_tx_polarity_flip_physical{165.0}=0x1 +phy_chain_tx_polarity_flip_physical{166.0}=0x0 +phy_chain_tx_polarity_flip_physical{167.0}=0x0 +phy_chain_tx_polarity_flip_physical{168.0}=0x0 + +phy_chain_tx_polarity_flip_physical{169.0}=0x0 +phy_chain_tx_polarity_flip_physical{170.0}=0x0 +phy_chain_tx_polarity_flip_physical{171.0}=0x0 +phy_chain_tx_polarity_flip_physical{172.0}=0x0 + +phy_chain_tx_polarity_flip_physical{173.0}=0x0 +phy_chain_tx_polarity_flip_physical{174.0}=0x1 +phy_chain_tx_polarity_flip_physical{175.0}=0x0 +phy_chain_tx_polarity_flip_physical{176.0}=0x1 + +phy_chain_tx_polarity_flip_physical{177.0}=0x0 +phy_chain_tx_polarity_flip_physical{178.0}=0x0 +phy_chain_tx_polarity_flip_physical{179.0}=0x0 +phy_chain_tx_polarity_flip_physical{180.0}=0x0 + +phy_chain_tx_polarity_flip_physical{181.0}=0x1 +phy_chain_tx_polarity_flip_physical{182.0}=0x0 +phy_chain_tx_polarity_flip_physical{183.0}=0x0 +phy_chain_tx_polarity_flip_physical{184.0}=0x0 + +phy_chain_tx_polarity_flip_physical{185.0}=0x0 +phy_chain_tx_polarity_flip_physical{186.0}=0x0 +phy_chain_tx_polarity_flip_physical{187.0}=0x0 +phy_chain_tx_polarity_flip_physical{188.0}=0x0 + +phy_chain_tx_polarity_flip_physical{189.0}=0x1 +phy_chain_tx_polarity_flip_physical{190.0}=0x0 +phy_chain_tx_polarity_flip_physical{191.0}=0x1 +phy_chain_tx_polarity_flip_physical{192.0}=0x0 + +# RX polarity +phy_chain_rx_polarity_flip_physical{129.0}=0x0 +phy_chain_rx_polarity_flip_physical{130.0}=0x0 +phy_chain_rx_polarity_flip_physical{131.0}=0x1 +phy_chain_rx_polarity_flip_physical{132.0}=0x0 + +phy_chain_rx_polarity_flip_physical{133.0}=0x0 +phy_chain_rx_polarity_flip_physical{134.0}=0x1 +phy_chain_rx_polarity_flip_physical{135.0}=0x1 +phy_chain_rx_polarity_flip_physical{136.0}=0x0 + +phy_chain_rx_polarity_flip_physical{137.0}=0x1 +phy_chain_rx_polarity_flip_physical{138.0}=0x0 +phy_chain_rx_polarity_flip_physical{139.0}=0x1 +phy_chain_rx_polarity_flip_physical{140.0}=0x1 + +phy_chain_rx_polarity_flip_physical{141.0}=0x0 +phy_chain_rx_polarity_flip_physical{142.0}=0x0 +phy_chain_rx_polarity_flip_physical{143.0}=0x1 +phy_chain_rx_polarity_flip_physical{144.0}=0x1 + +phy_chain_rx_polarity_flip_physical{145.0}=0x0 +phy_chain_rx_polarity_flip_physical{146.0}=0x0 +phy_chain_rx_polarity_flip_physical{147.0}=0x1 +phy_chain_rx_polarity_flip_physical{148.0}=0x0 + +phy_chain_rx_polarity_flip_physical{149.0}=0x0 +phy_chain_rx_polarity_flip_physical{150.0}=0x1 +phy_chain_rx_polarity_flip_physical{151.0}=0x1 +phy_chain_rx_polarity_flip_physical{152.0}=0x0 + +phy_chain_rx_polarity_flip_physical{153.0}=0x0 +phy_chain_rx_polarity_flip_physical{154.0}=0x1 +phy_chain_rx_polarity_flip_physical{155.0}=0x0 +phy_chain_rx_polarity_flip_physical{156.0}=0x0 + +phy_chain_rx_polarity_flip_physical{157.0}=0x1 +phy_chain_rx_polarity_flip_physical{158.0}=0x1 +phy_chain_rx_polarity_flip_physical{159.0}=0x0 +phy_chain_rx_polarity_flip_physical{160.0}=0x0 + +phy_chain_rx_polarity_flip_physical{161.0}=0x1 +phy_chain_rx_polarity_flip_physical{162.0}=0x1 +phy_chain_rx_polarity_flip_physical{163.0}=0x0 +phy_chain_rx_polarity_flip_physical{164.0}=0x1 + +phy_chain_rx_polarity_flip_physical{165.0}=0x0 +phy_chain_rx_polarity_flip_physical{166.0}=0x1 +phy_chain_rx_polarity_flip_physical{167.0}=0x1 +phy_chain_rx_polarity_flip_physical{168.0}=0x0 + +phy_chain_rx_polarity_flip_physical{169.0}=0x0 +phy_chain_rx_polarity_flip_physical{170.0}=0x1 +phy_chain_rx_polarity_flip_physical{171.0}=0x0 +phy_chain_rx_polarity_flip_physical{172.0}=0x1 + +phy_chain_rx_polarity_flip_physical{173.0}=0x0 +phy_chain_rx_polarity_flip_physical{174.0}=0x1 +phy_chain_rx_polarity_flip_physical{175.0}=0x0 +phy_chain_rx_polarity_flip_physical{176.0}=0x0 + +phy_chain_rx_polarity_flip_physical{177.0}=0x1 +phy_chain_rx_polarity_flip_physical{178.0}=0x0 +phy_chain_rx_polarity_flip_physical{179.0}=0x0 +phy_chain_rx_polarity_flip_physical{180.0}=0x1 + +phy_chain_rx_polarity_flip_physical{181.0}=0x0 +phy_chain_rx_polarity_flip_physical{182.0}=0x1 +phy_chain_rx_polarity_flip_physical{183.0}=0x0 +phy_chain_rx_polarity_flip_physical{184.0}=0x1 + +phy_chain_rx_polarity_flip_physical{185.0}=0x1 +phy_chain_rx_polarity_flip_physical{186.0}=0x0 +phy_chain_rx_polarity_flip_physical{187.0}=0x1 +phy_chain_rx_polarity_flip_physical{188.0}=0x0 + +phy_chain_rx_polarity_flip_physical{189.0}=0x1 +phy_chain_rx_polarity_flip_physical{190.0}=0x1 +phy_chain_rx_polarity_flip_physical{191.0}=0x0 +phy_chain_rx_polarity_flip_physical{192.0}=0x0 + +# TX lane swap +phy_chain_tx_lane_map_physical{129.0}=0x0312 +phy_chain_tx_lane_map_physical{133.0}=0x3120 +phy_chain_tx_lane_map_physical{137.0}=0x1203 +phy_chain_tx_lane_map_physical{141.0}=0x0132 + +phy_chain_tx_lane_map_physical{145.0}=0x0312 +phy_chain_tx_lane_map_physical{149.0}=0x2310 +phy_chain_tx_lane_map_physical{153.0}=0x1032 +phy_chain_tx_lane_map_physical{157.0}=0x3120 + +phy_chain_tx_lane_map_physical{161.0}=0x1023 +phy_chain_tx_lane_map_physical{165.0}=0x1203 +phy_chain_tx_lane_map_physical{169.0}=0x0213 +phy_chain_tx_lane_map_physical{173.0}=0x0123 + +phy_chain_tx_lane_map_physical{177.0}=0x2031 +phy_chain_tx_lane_map_physical{181.0}=0x1203 +phy_chain_tx_lane_map_physical{185.0}=0x0213 +phy_chain_tx_lane_map_physical{189.0}=0x3210 + +# RX lane swap +phy_chain_rx_lane_map_physical{129.0}=0x0321 +phy_chain_rx_lane_map_physical{133.0}=0x0312 +phy_chain_rx_lane_map_physical{137.0}=0x2103 +phy_chain_rx_lane_map_physical{141.0}=0x0231 + +phy_chain_rx_lane_map_physical{145.0}=0x0321 +phy_chain_rx_lane_map_physical{149.0}=0x0312 +phy_chain_rx_lane_map_physical{153.0}=0x3120 +phy_chain_rx_lane_map_physical{157.0}=0x2103 + +phy_chain_rx_lane_map_physical{161.0}=0x1032 +phy_chain_rx_lane_map_physical{165.0}=0x2031 +phy_chain_rx_lane_map_physical{169.0}=0x0132 +phy_chain_rx_lane_map_physical{173.0}=0x2103 + +phy_chain_rx_lane_map_physical{177.0}=0x1032 +phy_chain_rx_lane_map_physical{181.0}=0x1230 +phy_chain_rx_lane_map_physical{185.0}=0x0321 +phy_chain_rx_lane_map_physical{189.0}=0x3201 + +# +# Tile-3 FC48~FC63 +# portmap_0=x:xx // cpu port (not required, but included for illustration purposes) +# +# port 100 is the second management port +portmap_100=259:10 +# port 101 is the third loopback port +#portmap_101=262:10 +portmap_102=193:50:2 +portmap_103=195:50:2 +portmap_104=197:50:2 +portmap_105=199:50:2 +portmap_106=201:50:2 +portmap_107=203:50:2 +portmap_108=205:50:2 +portmap_109=207:50:2 +portmap_110=209:100 +portmap_111=213:100 +portmap_112=217:50:2 +portmap_113=219:50:2 +portmap_114=221:50:2 +portmap_115=223:50:2 +portmap_116=225:50:2 +portmap_117=227:50:2 +portmap_118=229:50:2 +portmap_119=231:50:2 +portmap_120=233:50:2 +portmap_121=235:50:2 +portmap_122=237:50:2 +portmap_123=239:50:2 +portmap_124=241:50:2 +portmap_125=243:50:2 +portmap_126=245:50:2 +portmap_127=247:50:2 +portmap_128=249:50:2 +portmap_129=251:50:2 +portmap_130=253:50:2 +portmap_131=255:50:2 + +# port 135 is the fourth loopback port +portmap_135=263:10 + +# TX polarity +phy_chain_tx_polarity_flip_physical{193.0}=0x0 +phy_chain_tx_polarity_flip_physical{194.0}=0x0 +phy_chain_tx_polarity_flip_physical{195.0}=0x0 +phy_chain_tx_polarity_flip_physical{196.0}=0x0 + +phy_chain_tx_polarity_flip_physical{197.0}=0x1 +phy_chain_tx_polarity_flip_physical{198.0}=0x0 +phy_chain_tx_polarity_flip_physical{199.0}=0x1 +phy_chain_tx_polarity_flip_physical{200.0}=0x0 + +phy_chain_tx_polarity_flip_physical{201.0}=0x0 +phy_chain_tx_polarity_flip_physical{202.0}=0x0 +phy_chain_tx_polarity_flip_physical{203.0}=0x0 +phy_chain_tx_polarity_flip_physical{204.0}=0x0 + +phy_chain_tx_polarity_flip_physical{205.0}=0x1 +phy_chain_tx_polarity_flip_physical{206.0}=0x0 +phy_chain_tx_polarity_flip_physical{207.0}=0x1 +phy_chain_tx_polarity_flip_physical{208.0}=0x0 + +phy_chain_tx_polarity_flip_physical{209.0}=0x1 +phy_chain_tx_polarity_flip_physical{210.0}=0x0 +phy_chain_tx_polarity_flip_physical{211.0}=0x0 +phy_chain_tx_polarity_flip_physical{212.0}=0x1 + +phy_chain_tx_polarity_flip_physical{213.0}=0x1 +phy_chain_tx_polarity_flip_physical{214.0}=0x0 +phy_chain_tx_polarity_flip_physical{215.0}=0x0 +phy_chain_tx_polarity_flip_physical{216.0}=0x0 + +phy_chain_tx_polarity_flip_physical{217.0}=0x0 +phy_chain_tx_polarity_flip_physical{218.0}=0x0 +phy_chain_tx_polarity_flip_physical{219.0}=0x0 +phy_chain_tx_polarity_flip_physical{220.0}=0x0 + +phy_chain_tx_polarity_flip_physical{221.0}=0x0 +phy_chain_tx_polarity_flip_physical{222.0}=0x1 +phy_chain_tx_polarity_flip_physical{223.0}=0x1 +phy_chain_tx_polarity_flip_physical{224.0}=0x0 + +phy_chain_tx_polarity_flip_physical{225.0}=0x1 +phy_chain_tx_polarity_flip_physical{226.0}=0x1 +phy_chain_tx_polarity_flip_physical{227.0}=0x0 +phy_chain_tx_polarity_flip_physical{228.0}=0x0 + +phy_chain_tx_polarity_flip_physical{229.0}=0x1 +phy_chain_tx_polarity_flip_physical{230.0}=0x1 +phy_chain_tx_polarity_flip_physical{231.0}=0x1 +phy_chain_tx_polarity_flip_physical{232.0}=0x1 + +phy_chain_tx_polarity_flip_physical{233.0}=0x0 +phy_chain_tx_polarity_flip_physical{234.0}=0x0 +phy_chain_tx_polarity_flip_physical{235.0}=0x1 +phy_chain_tx_polarity_flip_physical{236.0}=0x1 + +phy_chain_tx_polarity_flip_physical{237.0}=0x1 +phy_chain_tx_polarity_flip_physical{238.0}=0x1 +phy_chain_tx_polarity_flip_physical{239.0}=0x0 +phy_chain_tx_polarity_flip_physical{240.0}=0x0 + +phy_chain_tx_polarity_flip_physical{241.0}=0x0 +phy_chain_tx_polarity_flip_physical{242.0}=0x1 +phy_chain_tx_polarity_flip_physical{243.0}=0x0 +phy_chain_tx_polarity_flip_physical{244.0}=0x0 + +phy_chain_tx_polarity_flip_physical{245.0}=0x1 +phy_chain_tx_polarity_flip_physical{246.0}=0x0 +phy_chain_tx_polarity_flip_physical{247.0}=0x0 +phy_chain_tx_polarity_flip_physical{248.0}=0x0 + +phy_chain_tx_polarity_flip_physical{249.0}=0x0 +phy_chain_tx_polarity_flip_physical{250.0}=0x0 +phy_chain_tx_polarity_flip_physical{251.0}=0x0 +phy_chain_tx_polarity_flip_physical{252.0}=0x0 + +phy_chain_tx_polarity_flip_physical{253.0}=0x1 +phy_chain_tx_polarity_flip_physical{254.0}=0x0 +phy_chain_tx_polarity_flip_physical{255.0}=0x0 +phy_chain_tx_polarity_flip_physical{256.0}=0x0 + +# RX polarity +phy_chain_rx_polarity_flip_physical{193.0}=0x1 +phy_chain_rx_polarity_flip_physical{194.0}=0x0 +phy_chain_rx_polarity_flip_physical{195.0}=0x0 +phy_chain_rx_polarity_flip_physical{196.0}=0x1 + +phy_chain_rx_polarity_flip_physical{197.0}=0x1 +phy_chain_rx_polarity_flip_physical{198.0}=0x1 +phy_chain_rx_polarity_flip_physical{199.0}=0x0 +phy_chain_rx_polarity_flip_physical{200.0}=0x1 + +phy_chain_rx_polarity_flip_physical{201.0}=0x1 +phy_chain_rx_polarity_flip_physical{202.0}=0x0 +phy_chain_rx_polarity_flip_physical{203.0}=0x1 +phy_chain_rx_polarity_flip_physical{204.0}=0x1 + +phy_chain_rx_polarity_flip_physical{205.0}=0x1 +phy_chain_rx_polarity_flip_physical{206.0}=0x1 +phy_chain_rx_polarity_flip_physical{207.0}=0x0 +phy_chain_rx_polarity_flip_physical{208.0}=0x0 + +phy_chain_rx_polarity_flip_physical{209.0}=0x1 +phy_chain_rx_polarity_flip_physical{210.0}=0x1 +phy_chain_rx_polarity_flip_physical{211.0}=0x0 +phy_chain_rx_polarity_flip_physical{212.0}=0x1 + +phy_chain_rx_polarity_flip_physical{213.0}=0x0 +phy_chain_rx_polarity_flip_physical{214.0}=0x1 +phy_chain_rx_polarity_flip_physical{215.0}=0x1 +phy_chain_rx_polarity_flip_physical{216.0}=0x0 + +phy_chain_rx_polarity_flip_physical{217.0}=0x1 +phy_chain_rx_polarity_flip_physical{218.0}=0x0 +phy_chain_rx_polarity_flip_physical{219.0}=0x1 +phy_chain_rx_polarity_flip_physical{220.0}=0x1 + +phy_chain_rx_polarity_flip_physical{221.0}=0x1 +phy_chain_rx_polarity_flip_physical{222.0}=0x1 +phy_chain_rx_polarity_flip_physical{223.0}=0x0 +phy_chain_rx_polarity_flip_physical{224.0}=0x0 + +phy_chain_rx_polarity_flip_physical{225.0}=0x1 +phy_chain_rx_polarity_flip_physical{226.0}=0x1 +phy_chain_rx_polarity_flip_physical{227.0}=0x1 +phy_chain_rx_polarity_flip_physical{228.0}=0x0 + +phy_chain_rx_polarity_flip_physical{229.0}=0x1 +phy_chain_rx_polarity_flip_physical{230.0}=0x0 +phy_chain_rx_polarity_flip_physical{231.0}=0x0 +phy_chain_rx_polarity_flip_physical{232.0}=0x1 + +phy_chain_rx_polarity_flip_physical{233.0}=0x1 +phy_chain_rx_polarity_flip_physical{234.0}=0x1 +phy_chain_rx_polarity_flip_physical{235.0}=0x1 +phy_chain_rx_polarity_flip_physical{236.0}=0x0 + +phy_chain_rx_polarity_flip_physical{237.0}=0x0 +phy_chain_rx_polarity_flip_physical{238.0}=0x1 +phy_chain_rx_polarity_flip_physical{239.0}=0x0 +phy_chain_rx_polarity_flip_physical{240.0}=0x0 + +phy_chain_rx_polarity_flip_physical{241.0}=0x0 +phy_chain_rx_polarity_flip_physical{242.0}=0x1 +phy_chain_rx_polarity_flip_physical{243.0}=0x0 +phy_chain_rx_polarity_flip_physical{244.0}=0x1 + +phy_chain_rx_polarity_flip_physical{245.0}=0x1 +phy_chain_rx_polarity_flip_physical{246.0}=0x0 +phy_chain_rx_polarity_flip_physical{247.0}=0x0 +phy_chain_rx_polarity_flip_physical{248.0}=0x1 + +phy_chain_rx_polarity_flip_physical{249.0}=0x0 +phy_chain_rx_polarity_flip_physical{250.0}=0x0 +phy_chain_rx_polarity_flip_physical{251.0}=0x1 +phy_chain_rx_polarity_flip_physical{252.0}=0x0 + +phy_chain_rx_polarity_flip_physical{253.0}=0x1 +phy_chain_rx_polarity_flip_physical{254.0}=0x0 +phy_chain_rx_polarity_flip_physical{255.0}=0x0 +phy_chain_rx_polarity_flip_physical{256.0}=0x0 + +# TX lane swap +phy_chain_tx_lane_map_physical{193.0}=0x2031 +phy_chain_tx_lane_map_physical{197.0}=0x1203 +phy_chain_tx_lane_map_physical{201.0}=0x0213 +phy_chain_tx_lane_map_physical{205.0}=0x3210 + +phy_chain_tx_lane_map_physical{209.0}=0x1023 +phy_chain_tx_lane_map_physical{213.0}=0x1203 +phy_chain_tx_lane_map_physical{217.0}=0x0213 +phy_chain_tx_lane_map_physical{221.0}=0x3102 + +phy_chain_tx_lane_map_physical{225.0}=0x2031 +phy_chain_tx_lane_map_physical{229.0}=0x1023 +phy_chain_tx_lane_map_physical{233.0}=0x1320 +phy_chain_tx_lane_map_physical{237.0}=0x2013 + +phy_chain_tx_lane_map_physical{241.0}=0x1023 +phy_chain_tx_lane_map_physical{245.0}=0x1203 +phy_chain_tx_lane_map_physical{249.0}=0x3120 +phy_chain_tx_lane_map_physical{253.0}=0x3210 + +# RX lane swap +phy_chain_rx_lane_map_physical{193.0}=0x1032 +phy_chain_rx_lane_map_physical{197.0}=0x1230 +phy_chain_rx_lane_map_physical{201.0}=0x0321 +phy_chain_rx_lane_map_physical{205.0}=0x3201 + +phy_chain_rx_lane_map_physical{209.0}=0x3201 +phy_chain_rx_lane_map_physical{213.0}=0x2031 +phy_chain_rx_lane_map_physical{217.0}=0x0321 +phy_chain_rx_lane_map_physical{221.0}=0x3201 + +phy_chain_rx_lane_map_physical{225.0}=0x2103 +phy_chain_rx_lane_map_physical{229.0}=0x2310 +phy_chain_rx_lane_map_physical{233.0}=0x0213 +phy_chain_rx_lane_map_physical{237.0}=0x1032 + +phy_chain_rx_lane_map_physical{241.0}=0x0321 +phy_chain_rx_lane_map_physical{245.0}=0x2301 +phy_chain_rx_lane_map_physical{249.0}=0x2103 +phy_chain_rx_lane_map_physical{253.0}=0x2013 + +physical_ports=64 +logical_ports=136 +uplink_ports=2 +dport_map_port_66=121 +dport_map_port_100=122 + +module_64ports=1 +mmu_init_config="MSFT-TH-Tier0" + diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/port_config.ini b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/port_config.ini index 646d91492beb..13c0d6600020 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/port_config.ini +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/port_config.ini @@ -63,3 +63,5 @@ Ethernet240 185,186,187,188 fortyGigE1/61 61 40000 Ethernet244 189,190,191,192 fortyGigE1/62 62 40000 Ethernet248 201,202,203,204 fortyGigE1/63 63 40000 Ethernet252 205,206,207,208 fortyGigE1/64 64 40000 +Ethernet256 257 tenGigE1/65 65 10000 +Ethernet257 259 tenGigE1/66 66 10000 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py index 24938a122c0e..bb1c961ab670 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py @@ -4,6 +4,7 @@ # try: + import io import struct import sys import getopt @@ -12,16 +13,46 @@ from sonic_sfp.sfputilbase import SfpUtilBase from os import * from mmap import * + from sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_sfp.sff8436 import sff8436Dom + from sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_sfp.sff8472 import sff8472Dom except ImportError as e: raise ImportError("%s - required module not found" % str(e)) +#definitions of the offset and width for values in DOM info eeprom +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNL_THRESHOLD_OFFSET = 176 +QSFP_CHANNL_THRESHOLD_WIDTH = 16 +QSFP_CHANNL_MON_MASK_OFFSET = 242 +QSFP_CHANNL_MON_MASK_WIDTH = 4 + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 56 + +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" PORT_START = 1 - PORT_END = 64 + PORT_END = 66 PORTS_IN_BLOCK = 64 BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" @@ -115,6 +146,9 @@ def get_presence(self, port_num): # Mask off 4th bit for presence mask = (1 << 4) + # Mask off 1st bit for presence 65,66 + if (port_num > 64): + mask = (1 << 0) # ModPrsL is active low if reg_value & mask == 0: return True @@ -300,4 +334,288 @@ def get_transceiver_change_event(self, timeout=0): self.oir_fd = -1 self.epoll = -1 - return False, {} \ No newline at end of file + return False, {} + + def get_transceiver_dom_info_dict(self, port_num): + transceiver_dom_info_dict = {} + + dom_info_dict_keys = ['temperature', 'voltage', 'rx1power', + 'rx2power', 'rx3power', 'rx4power', + 'tx1bias', 'tx2bias', 'tx3bias', + 'tx4bias', 'tx1power', 'tx2power', + 'tx3power', 'tx4power', + ] + transceiver_dom_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + + if port_num in self.qsfp_ports: + offset = 0 + offset_xcvr = 128 + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + return transceiver_dom_info_dict + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_dom_capability_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0) + else: + return transceiver_dom_info_dict + + dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return transceiver_dom_info_dict + + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return transceiver_dom_info_dict + + qsfp_dom_rev_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + else: + return transceiver_dom_info_dict + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + dom_channel_monitor_data = {} + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return transceiver_dom_info_dict + + transceiver_dom_info_dict['tx1power'] = 'N/A' + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + + else: + offset = 256 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path,"rb",0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom(None,1) + if sfpd_obj is None: + return None + dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET), + SFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return transceiver_dom_info_dict + + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VOLT_OFFSET), + SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return transceiver_dom_info_dict + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_MODULE_THRESHOLD_OFFSET), + SFP_MODULE_THRESHOLD_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return transceiver_dom_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value'] + transceiver_dom_info_dict['rx2power'] = 'N/A' + transceiver_dom_info_dict['rx3power'] = 'N/A' + transceiver_dom_info_dict['rx4power'] = 'N/A' + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] + transceiver_dom_info_dict['tx2bias'] = 'N/A' + transceiver_dom_info_dict['tx3bias'] = 'N/A' + transceiver_dom_info_dict['tx4bias'] = 'N/A' + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + + return transceiver_dom_info_dict + + def get_transceiver_dom_threshold_info_dict(self, port_num): + transceiver_dom_threshold_info_dict = {} + dom_info_dict_keys = ['temphighalarm', 'temphighwarning', + 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', + 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', + 'txbiaslowalarm', 'txbiaslowwarning' + ] + transceiver_dom_threshold_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + + if port_num in self.qsfp_ports: + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + # Dom Threshold data starts from offset 384 + # Revert offset back to 0 once data is retrieved + offset = 384 + dom_module_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_MODULE_THRESHOLD_OFFSET), + QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + dom_channel_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_CHANNL_THRESHOLD_OFFSET), + QSFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is not None: + dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values(dom_channel_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value'] + + else: + offset = 256 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path,"rb",0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom(None,1) + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, + (offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH) + + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(dom_module_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + #Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + return transceiver_dom_threshold_info_dict diff --git a/device/delta/x86_64-delta_ag5648-r0/installer.conf b/device/delta/x86_64-delta_ag5648-r0/installer.conf index fa2af8b7a007..85ed43ab48ed 100644 --- a/device/delta/x86_64-delta_ag5648-r0/installer.conf +++ b/device/delta/x86_64-delta_ag5648-r0/installer.conf @@ -1,2 +1,3 @@ CONSOLE_PORT=0x3f8 CONSOLE_SPEED=115200 +CONSOLE_DEV=0 diff --git a/device/delta/x86_64-delta_ag9032v1-r0/installer.conf b/device/delta/x86_64-delta_ag9032v1-r0/installer.conf index fa2af8b7a007..85ed43ab48ed 100644 --- a/device/delta/x86_64-delta_ag9032v1-r0/installer.conf +++ b/device/delta/x86_64-delta_ag9032v1-r0/installer.conf @@ -1,2 +1,3 @@ CONSOLE_PORT=0x3f8 CONSOLE_SPEED=115200 +CONSOLE_DEV=0 diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/port_config.ini b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/port_config.ini index ea064a708a3a..9eb4ac0c8a0c 100644 --- a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/port_config.ini +++ b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/port_config.ini @@ -1,34 +1,34 @@ -# name lanes alias -Ethernet0 41,42,43,44 hundredGigE1/1 -Ethernet4 45,46,47,48 hundredGigE1/2 -Ethernet8 49,50,51,52 hundredGigE1/3 -Ethernet12 37,38,39,40 hundredGigE1/4 -Ethernet16 33,34,35,36 hundredGigE1/5 -Ethernet20 53,54,55,56 hundredGigE1/6 -Ethernet24 57,58,59,60 hundredGigE1/7 -Ethernet28 61,62,63,64 hundredGigE1/8 -Ethernet32 65,66,67,68 hundredGigE1/9 -Ethernet36 69,70,71,72 hundredGigE1/10 -Ethernet40 73,74,75,76 hundredGigE1/11 -Ethernet44 77,78,79,80 hundredGigE1/12 -Ethernet48 81,82,83,84 hundredGigE1/13 -Ethernet52 85,86,87,88 hundredGigE1/14 -Ethernet56 89,90,91,92 hundredGigE1/15 -Ethernet60 93,94,95,96 hundredGigE1/16 -Ethernet64 97,98,99,100 hundredGigE1/17 -Ethernet68 101,102,103,104 hundredGigE1/18 -Ethernet72 105,106,107,108 hundredGigE1/19 -Ethernet76 109,110,111,112 hundredGigE1/20 -Ethernet80 121,122,123,124 hundredGigE1/21 -Ethernet84 113,114,115,116 hundredGigE1/22 -Ethernet88 1,2,3,4 hundredGigE1/23 -Ethernet92 117,118,119,120 hundredGigE1/24 -Ethernet96 5,6,7,8 hundredGigE1/25 -Ethernet100 125,126,127,128 hundredGigE1/26 -Ethernet104 29,30,31,32 hundredGigE1/27 -Ethernet108 9,10,11,12 hundredGigE1/28 -Ethernet112 13,14,15,16 hundredGigE1/29 -Ethernet116 25,26,27,28 hundredGigE1/30 -Ethernet120 17,18,19,20 hundredGigE1/31 -Ethernet124 21,22,23,24 hundredGigE1/32 -Ethernet128 129 hundredGigE1/33 +# name lanes alias index speed +Ethernet0 1,2,3,4 hundredGigE1/1 0 100000 +Ethernet4 5,6,7,8 hundredGigE1/2 1 100000 +Ethernet8 9,10,11,12 hundredGigE1/3 2 100000 +Ethernet12 13,14,15,16 hundredGigE1/4 3 100000 +Ethernet16 17,18,19,20 hundredGigE1/5 4 100000 +Ethernet20 21,22,23,24 hundredGigE1/6 5 100000 +Ethernet24 25,26,27,28 hundredGigE1/7 6 100000 +Ethernet28 29,30,31,32 hundredGigE1/8 7 100000 +Ethernet32 33,34,35,36 hundredGigE1/9 8 100000 +Ethernet36 37,38,39,40 hundredGigE1/10 9 100000 +Ethernet40 41,42,43,44 hundredGigE1/11 10 100000 +Ethernet44 45,46,47,48 hundredGigE1/12 11 100000 +Ethernet48 49,50,51,52 hundredGigE1/13 12 100000 +Ethernet52 53,54,55,56 hundredGigE1/14 13 100000 +Ethernet56 57,58,59,60 hundredGigE1/15 14 100000 +Ethernet60 61,62,63,64 hundredGigE1/16 15 100000 +Ethernet64 65,66,67,68 hundredGigE1/17 16 100000 +Ethernet68 69,70,71,72 hundredGigE1/18 17 100000 +Ethernet72 73,74,75,76 hundredGigE1/19 18 100000 +Ethernet76 77,78,79,80 hundredGigE1/20 19 100000 +Ethernet80 81,82,83,84 hundredGigE1/21 20 100000 +Ethernet84 85,86,87,88 hundredGigE1/22 21 100000 +Ethernet88 89,90,91,92 hundredGigE1/23 22 100000 +Ethernet92 93,94,95,96 hundredGigE1/24 23 100000 +Ethernet96 97,98,99,100 hundredGigE1/25 24 100000 +Ethernet100 101,102,103,104 hundredGigE1/26 25 100000 +Ethernet104 105,106,107,108 hundredGigE1/27 26 100000 +Ethernet108 109,110,111,112 hundredGigE1/28 27 100000 +Ethernet112 113,114,115,116 hundredGigE1/29 28 100000 +Ethernet116 117,118,119,120 hundredGigE1/30 29 100000 +Ethernet120 121,122,123,124 hundredGigE1/31 30 100000 +Ethernet124 125,126,127,128 hundredGigE1/32 31 100000 +Ethernet128 129 tenGigE1/33 32 10000 diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/td3-ag9032v2a-32x100G+1x10G.config.bcm b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/td3-ag9032v2a-32x100G+1x10G.config.bcm index f15efb4e2a10..4c6ceb075bf4 100755 --- a/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/td3-ag9032v2a-32x100G+1x10G.config.bcm +++ b/device/delta/x86_64-delta_ag9032v2a-r0/Delta-ag9032v2a/td3-ag9032v2a-32x100G+1x10G.config.bcm @@ -350,7 +350,6 @@ phy_chain_tx_polarity_flip_physical{97.0}=0x1 phy_chain_tx_polarity_flip_physical{98.0}=0x1 phy_chain_tx_polarity_flip_physical{99.0}=0x0 portmap_66.0=129:10:m -portmap_130.0=128:10:m portmap_103=101:100 portmap_107=105:100 portmap_111=109:100 diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/default_sku b/device/delta/x86_64-delta_ag9032v2a-r0/default_sku new file mode 100644 index 000000000000..2e67043ab05a --- /dev/null +++ b/device/delta/x86_64-delta_ag9032v2a-r0/default_sku @@ -0,0 +1 @@ +Delta-ag9032v2a t1 diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/installer.conf b/device/delta/x86_64-delta_ag9032v2a-r0/installer.conf index fa2af8b7a007..85ed43ab48ed 100644 --- a/device/delta/x86_64-delta_ag9032v2a-r0/installer.conf +++ b/device/delta/x86_64-delta_ag9032v2a-r0/installer.conf @@ -1,2 +1,3 @@ CONSOLE_PORT=0x3f8 CONSOLE_SPEED=115200 +CONSOLE_DEV=0 diff --git a/device/delta/x86_64-delta_ag9032v2a-r0/plugins/sfputil.py b/device/delta/x86_64-delta_ag9032v2a-r0/plugins/sfputil.py index 2cffa8807c0a..9abaa8cf01c1 100644 --- a/device/delta/x86_64-delta_ag9032v2a-r0/plugins/sfputil.py +++ b/device/delta/x86_64-delta_ag9032v2a-r0/plugins/sfputil.py @@ -62,7 +62,7 @@ def get_presence(self, port_num): reg_value = int(content, 16) # Mask off the bit corresponding to our port - mask = (1 << port_num) + mask = (1 << (self.port_end - port_num + 7)) # ModPrsL is active low if reg_value & mask == 0: @@ -86,7 +86,7 @@ def get_low_power_mode(self, port_num): reg_value = int(content, 16) # Mask off the bit corresponding to our port - mask = (1 << port_num) + mask = (1 << (self.port_end - port_num) - 1) # LPMode is active high if reg_value & mask == 0: @@ -111,7 +111,7 @@ def set_low_power_mode(self, port_num, lpmode): reg_value = int(content, 16) # Mask off the bit corresponding to our port - mask = (1 << port_num) + mask = (1 << (self.port_end - port_num) - 1) # LPMode is active high; set or clear the bit accordingly if lpmode is True: @@ -147,7 +147,7 @@ def reset(self, port_num): reg_value = int(content, 16) # Mask off the bit corresponding to our port - mask = (1 << port_num) + mask = (1 << (self.port_end - port_num) - 1) # ResetL is active low reg_value = reg_value & ~mask diff --git a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/port_config.ini b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/port_config.ini index be43857f82b1..ee425d4ad4f6 100644 --- a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/port_config.ini +++ b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/port_config.ini @@ -1,65 +1,65 @@ -# name lanes alias -Ethernet0 49,50,51,52 Ethernet1/1 -Ethernet4 53,54,55,56 Ethernet2/1 -Ethernet8 65,66,67,68 Ethernet3/1 -Ethernet12 69,70,71,72 Ethernet4/1 -Ethernet16 81,82,83,84 Ethernet5/1 -Ethernet20 85,86,87,88 Ethernet6/1 -Ethernet24 1,2,3,4 Ethernet7/1 -Ethernet28 101,102,103,104 Ethernet8/1 -Ethernet32 5,6,7,8 Ethernet9/1 -Ethernet36 17,18,19,20 Ethernet10/1 -Ethernet40 21,22,23,24 Ethernet11/1 -Ethernet44 33,34,35,36 Ethernet12/1 -Ethernet48 37,38,39,40 Ethernet13/1 -Ethernet52 97,98,99,100 Ethernet14/1 -Ethernet56 113,114,115,116 Ethernet15/1 -Ethernet60 117,118,119,120 Ethernet16/1 -Ethernet64 129,130,131,132 Ethernet17/1 -Ethernet68 133,134,135,136 Ethernet18/1 -Ethernet72 145,146,147,148 Ethernet19/1 -Ethernet76 209,210,211,212 Ethernet20/1 -Ethernet80 213,214,215,216 Ethernet21/1 -Ethernet84 225,226,227,228 Ethernet22/1 -Ethernet88 229,230,231,232 Ethernet23/1 -Ethernet92 241,242,243,244 Ethernet24/1 -Ethernet96 245,246,247,248 Ethernet25/1 -Ethernet100 157,158,159,160 Ethernet26/1 -Ethernet104 161,162,163,164 Ethernet27/1 -Ethernet108 165,166,167,168 Ethernet28/1 -Ethernet112 177,178,179,180 Ethernet29/1 -Ethernet116 181,182,183,184 Ethernet30/1 -Ethernet120 193,194,195,196 Ethernet31/1 -Ethernet124 197,198,199,200 Ethernet32/1 -Ethernet128 61,62,63,64 Ethernet33/1 -Ethernet132 57,58,59,60 Ethernet34/1 -Ethernet136 77,78,79,80 Ethernet35/1 -Ethernet140 73,74,75,76 Ethernet36/1 -Ethernet144 93,94,95,96 Ethernet37/1 -Ethernet148 89,90,91,92 Ethernet38/1 -Ethernet152 105,106,107,108 Ethernet39/1 -Ethernet156 9,10,11,12 Ethernet40/1 -Ethernet160 25,26,27,28 Ethernet41/1 -Ethernet164 13,14,15,16 Ethernet42/1 -Ethernet168 41,42,43,44 Ethernet43/1 -Ethernet172 29,30,31,32 Ethernet44/1 -Ethernet176 45,46,47,48 Ethernet45/1 -Ethernet180 109,110,111,112 Ethernet46/1 -Ethernet184 125,126,127,128 Ethernet47/1 -Ethernet188 121,122,123,124 Ethernet48/1 -Ethernet192 141,142,143,144 Ethernet49/1 -Ethernet196 137,138,139,140 Ethernet50/1 -Ethernet200 217,218,219,220 Ethernet51/1 -Ethernet204 149,150,151,152 Ethernet52/1 -Ethernet208 233,234,235,236 Ethernet53/1 -Ethernet212 221,222,223,224 Ethernet54/1 -Ethernet216 249,250,251,252 Ethernet55/1 -Ethernet220 237,238,239,240 Ethernet56/1 -Ethernet224 153,154,155,156 Ethernet57/1 -Ethernet228 253,254,255,256 Ethernet58/1 -Ethernet232 173,174,175,176 Ethernet59/1 -Ethernet236 169,170,171,172 Ethernet60/1 -Ethernet240 189,190,191,192 Ethernet61/1 -Ethernet244 185,186,187,188 Ethernet62/1 -Ethernet248 205,206,207,208 Ethernet63/1 -Ethernet252 201,202,203,204 Ethernet64/1 +# name lanes alias index speed +Ethernet0 49,50,51,52 hundredGigE1/1 0 100000 +Ethernet4 53,54,55,56 hundredGigE1/2 1 100000 +Ethernet8 65,66,67,68 hundredGigE1/3 2 100000 +Ethernet12 69,70,71,72 hundredGigE1/4 3 100000 +Ethernet16 81,82,83,84 hundredGigE1/5 4 100000 +Ethernet20 85,86,87,88 hundredGigE1/6 5 100000 +Ethernet24 1,2,3,4 hundredGigE1/7 6 100000 +Ethernet28 101,102,103,104 hundredGigE1/8 7 100000 +Ethernet32 5,6,7,8 hundredGigE1/9 8 100000 +Ethernet36 17,18,19,20 hundredGigE1/10 9 100000 +Ethernet40 21,22,23,24 hundredGigE1/11 10 100000 +Ethernet44 33,34,35,36 hundredGigE1/12 11 100000 +Ethernet48 37,38,39,40 hundredGigE1/13 12 100000 +Ethernet52 97,98,99,100 hundredGigE1/14 13 100000 +Ethernet56 113,114,115,116 hundredGigE1/15 14 100000 +Ethernet60 117,118,119,120 hundredGigE1/16 15 100000 +Ethernet64 129,130,131,132 hundredGigE1/17 16 100000 +Ethernet68 133,134,135,136 hundredGigE1/18 17 100000 +Ethernet72 145,146,147,148 hundredGigE1/19 18 100000 +Ethernet76 209,210,211,212 hundredGigE1/20 19 100000 +Ethernet80 213,214,215,216 hundredGigE1/21 20 100000 +Ethernet84 225,226,227,228 hundredGigE1/22 21 100000 +Ethernet88 229,230,231,232 hundredGigE1/23 22 100000 +Ethernet92 241,242,243,244 hundredGigE1/24 23 100000 +Ethernet96 245,246,247,248 hundredGigE1/25 24 100000 +Ethernet100 157,158,159,160 hundredGigE1/26 25 100000 +Ethernet104 161,162,163,164 hundredGigE1/27 26 100000 +Ethernet108 165,166,167,168 hundredGigE1/28 27 100000 +Ethernet112 177,178,179,180 hundredGigE1/29 28 100000 +Ethernet116 181,182,183,184 hundredGigE1/30 29 100000 +Ethernet120 193,194,195,196 hundredGigE1/31 30 100000 +Ethernet124 197,198,199,200 hundredGigE1/32 31 100000 +Ethernet128 61,62,63,64 hundredGigE1/33 32 100000 +Ethernet132 57,58,59,60 hundredGigE1/34 33 100000 +Ethernet136 77,78,79,80 hundredGigE1/35 34 100000 +Ethernet140 73,74,75,76 hundredGigE1/36 35 100000 +Ethernet144 93,94,95,96 hundredGigE1/37 36 100000 +Ethernet148 89,90,91,92 hundredGigE1/38 37 100000 +Ethernet152 105,106,107,108 hundredGigE1/39 38 100000 +Ethernet156 9,10,11,12 hundredGigE1/40 39 100000 +Ethernet160 25,26,27,28 hundredGigE1/41 40 100000 +Ethernet164 13,14,15,16 hundredGigE1/42 41 100000 +Ethernet168 41,42,43,44 hundredGigE1/43 42 100000 +Ethernet172 29,30,31,32 hundredGigE1/44 43 100000 +Ethernet176 45,46,47,48 hundredGigE1/45 44 100000 +Ethernet180 109,110,111,112 hundredGigE1/46 45 100000 +Ethernet184 125,126,127,128 hundredGigE1/47 46 100000 +Ethernet188 121,122,123,124 hundredGigE1/48 47 100000 +Ethernet192 141,142,143,144 hundredGigE1/49 48 100000 +Ethernet196 137,138,139,140 hundredGigE1/50 49 100000 +Ethernet200 217,218,219,220 hundredGigE1/51 50 100000 +Ethernet204 149,150,151,152 hundredGigE1/52 51 100000 +Ethernet208 233,234,235,236 hundredGigE1/53 52 100000 +Ethernet212 221,222,223,224 hundredGigE1/54 53 100000 +Ethernet216 249,250,251,252 hundredGigE1/55 54 100000 +Ethernet220 237,238,239,240 hundredGigE1/56 55 100000 +Ethernet224 153,154,155,156 hundredGigE1/57 56 100000 +Ethernet228 253,254,255,256 hundredGigE1/58 57 100000 +Ethernet232 173,174,175,176 hundredGigE1/59 58 100000 +Ethernet236 169,170,171,172 hundredGigE1/60 59 100000 +Ethernet240 189,190,191,192 hundredGigE1/61 60 100000 +Ethernet244 185,186,187,188 hundredGigE1/62 61 100000 +Ethernet248 205,206,207,208 hundredGigE1/63 62 100000 +Ethernet252 201,202,203,204 hundredGigE1/64 63 100000 diff --git a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/th2-ag9064-64x100G.config.bcm b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/th2-ag9064-64x100G.config.bcm index 859196d8e5c8..eae7278a3ab2 100644 --- a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/th2-ag9064-64x100G.config.bcm +++ b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/th2-ag9064-64x100G.config.bcm @@ -715,8 +715,6 @@ phy_chain_tx_polarity_flip_physical{96.0}=0x0 phy_chain_tx_polarity_flip_physical{97.0}=0x1 phy_chain_tx_polarity_flip_physical{98.0}=0x0 phy_chain_tx_polarity_flip_physical{99.0}=0x1 -portmap_100=259:10 -portmap_101=262:10 portmap_102=193:100 portmap_103=197:100 portmap_104=201:100 @@ -736,14 +734,12 @@ portmap_116=249:100 portmap_117=253:100 portmap_11=41:100 portmap_12=45:100 -portmap_135=263:10 portmap_13=49:100 portmap_14=53:100 portmap_15=57:100 portmap_16=61:100 portmap_1=1:100 portmap_2=5:100 -portmap_33=260:10 portmap_34=65:100 portmap_35=69:100 portmap_36=73:100 @@ -763,8 +759,6 @@ portmap_48=121:100 portmap_49=125:100 portmap_4=13:100 portmap_5=17:100 -portmap_66=257:10 -portmap_67=261:10 portmap_68=129:100 portmap_69=133:100 portmap_6=21:100 @@ -797,6 +791,5 @@ phy_an_allow_pll_change_hg=0 robust_hash_disable_egress_vlan=1 robust_hash_disable_mpls=1 robust_hash_disable_vlan=1 -sram_scan_enable=0 stable_size=0x5500000 mmu_lossless=1 diff --git a/device/delta/x86_64-delta_ag9064-r0/installer.conf b/device/delta/x86_64-delta_ag9064-r0/installer.conf index fa2af8b7a007..85ed43ab48ed 100644 --- a/device/delta/x86_64-delta_ag9064-r0/installer.conf +++ b/device/delta/x86_64-delta_ag9064-r0/installer.conf @@ -1,2 +1,3 @@ CONSOLE_PORT=0x3f8 CONSOLE_SPEED=115200 +CONSOLE_DEV=0 diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if/buffers.json.j2 b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if/buffers.json.j2 new file mode 100644 index 000000000000..4fca9cbcd156 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if/buffers.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '300m' %} +{% set default_ports_num = 32 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "47218432", + "type": "ingress", + "mode": "dynamic", + "xoff": "17708800" + }, + "egress_lossy_pool": { + "size": "18874368", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"1433600", + "size":"1518", + "dynamic_th":"-4", + "xon_offset":"6272" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if/config_32x400G_Delta-et-c032if.yaml b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if/config_32x400G_Delta-et-c032if.yaml new file mode 100755 index 000000000000..2ba23d2a5a67 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if/config_32x400G_Delta-et-c032if.yaml @@ -0,0 +1,429 @@ +ifcs: + options: + log_level: "info" +nodes: +- node_id: "0" + options: + sku: "configs/sku/innovium.77700_A" + netdev: + - auto_create: "no" + multi_interface: "yes" + buffer_management_mode: "api_driven" + max_lossless_tc: "2" + txring: + - txring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + rxring: + - rxring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44" + - rxring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45" + - rxring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46" + - rxring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47" + sys_clk: "1720" + ifc_clk: "1200" + mac_clk: "1340" + + devports: + - id: "0" + sysport: "1000" + type: "cpu" + - fec: "KPFEC" + id: "249" + lanes: "0:8" + serdes_group: "31" + speed: "400G" + sysport: "249" + type: "eth" + - fec: "KPFEC" + id: "241" + lanes: "0:8" + serdes_group: "30" + speed: "400G" + sysport: "241" + type: "eth" + - fec: "KPFEC" + id: "233" + lanes: "0:8" + serdes_group: "29" + speed: "400G" + sysport: "233" + type: "eth" + - fec: "KPFEC" + id: "225" + lanes: "0:8" + serdes_group: "28" + speed: "400G" + sysport: "225" + type: "eth" + - fec: "KPFEC" + id: "217" + lanes: "0:8" + serdes_group: "27" + speed: "400G" + sysport: "217" + type: "eth" + - fec: "KPFEC" + id: "209" + lanes: "0:8" + serdes_group: "26" + speed: "400G" + sysport: "209" + type: "eth" + - fec: "KPFEC" + id: "201" + lanes: "0:8" + serdes_group: "25" + speed: "400G" + sysport: "201" + type: "eth" + - fec: "KPFEC" + id: "193" + lanes: "0:8" + serdes_group: "24" + speed: "400G" + sysport: "193" + type: "eth" + - fec: "KPFEC" + id: "185" + lanes: "0:8" + serdes_group: "23" + speed: "400G" + sysport: "185" + type: "eth" + - fec: "KPFEC" + id: "177" + lanes: "0:8" + serdes_group: "22" + speed: "400G" + sysport: "177" + type: "eth" + - fec: "KPFEC" + id: "169" + lanes: "0:8" + serdes_group: "21" + speed: "400G" + sysport: "169" + type: "eth" + - fec: "KPFEC" + id: "161" + lanes: "0:8" + serdes_group: "20" + speed: "400G" + sysport: "161" + type: "eth" + - fec: "KPFEC" + id: "153" + lanes: "0:8" + serdes_group: "19" + speed: "400G" + sysport: "153" + type: "eth" + - fec: "KPFEC" + id: "145" + lanes: "0:8" + serdes_group: "18" + speed: "400G" + sysport: "145" + type: "eth" + - fec: "KPFEC" + id: "137" + lanes: "0:8" + serdes_group: "17" + speed: "400G" + sysport: "137" + type: "eth" + - fec: "KPFEC" + id: "129" + lanes: "0:8" + serdes_group: "16" + speed: "400G" + sysport: "129" + type: "eth" + - fec: "KPFEC" + id: "121" + lanes: "0:8" + serdes_group: "15" + speed: "400G" + sysport: "121" + type: "eth" + - fec: "KPFEC" + id: "113" + lanes: "0:8" + serdes_group: "14" + speed: "400G" + sysport: "113" + type: "eth" + - fec: "KPFEC" + id: "97" + lanes: "0:8" + serdes_group: "12" + speed: "400G" + sysport: "97" + type: "eth" + - fec: "KPFEC" + id: "105" + lanes: "0:8" + serdes_group: "13" + speed: "400G" + sysport: "105" + type: "eth" + - fec: "KPFEC" + id: "81" + lanes: "0:8" + serdes_group: "10" + speed: "400G" + sysport: "81" + type: "eth" + - fec: "KPFEC" + id: "89" + lanes: "0:8" + serdes_group: "11" + speed: "400G" + sysport: "89" + type: "eth" + - fec: "KPFEC" + id: "65" + lanes: "0:8" + serdes_group: "8" + speed: "400G" + sysport: "65" + type: "eth" + - fec: "KPFEC" + id: "73" + lanes: "0:8" + serdes_group: "9" + speed: "400G" + sysport: "73" + type: "eth" + - fec: "KPFEC" + id: "49" + lanes: "0:8" + serdes_group: "6" + speed: "400G" + sysport: "49" + type: "eth" + - fec: "KPFEC" + id: "57" + lanes: "0:8" + serdes_group: "7" + speed: "400G" + sysport: "57" + type: "eth" + - fec: "KPFEC" + id: "33" + lanes: "0:8" + serdes_group: "4" + speed: "400G" + sysport: "33" + type: "eth" + - fec: "KPFEC" + id: "41" + lanes: "0:8" + serdes_group: "5" + speed: "400G" + sysport: "41" + type: "eth" + - fec: "KPFEC" + id: "17" + lanes: "0:8" + serdes_group: "2" + speed: "400G" + sysport: "17" + type: "eth" + - fec: "KPFEC" + id: "25" + lanes: "0:8" + serdes_group: "3" + speed: "400G" + sysport: "25" + type: "eth" + - fec: "KPFEC" + id: "1" + lanes: "0:8" + serdes_group: "0" + speed: "400G" + sysport: "1" + type: "eth" + - fec: "KPFEC" + id: "9" + lanes: "0:8" + serdes_group: "1" + speed: "400G" + sysport: "9" + type: "eth" + - fec: "NONE" + id: "257" + lanes: "0:1" + serdes_group: "32" + speed: "10G" + sysport: "257" + type: "mgmt 0" + - fec: "NONE" + id: "258" + lanes: "1:1" + serdes_group: "32" + speed: "10G" + sysport: "258" + type: "mgmt 1" + isg: + - id: "0" + tx_polarity: "01010101" + rx_polarity: "01100000" + lane_swap: "23641075" + - id: "1" + tx_polarity: "10110000" + rx_polarity: "11111111" + lane_swap: "64317520" + - id: "2" + tx_polarity: "00000000" + rx_polarity: "00000011" + lane_swap: "63147520" + - id: "3" + tx_polarity: "01101000" + rx_polarity: "00001110" + lane_swap: "31572046" + - id: "4" + tx_polarity: "00111000" + rx_polarity: "00001000" + lane_swap: "46105732" + - id: "5" + tx_polarity: "10111111" + rx_polarity: "11101000" + lane_swap: "27153604" + - id: "6" + tx_polarity: "01101110" + rx_polarity: "00001101" + lane_swap: "46503721" + - id: "7" + tx_polarity: "01000100" + rx_polarity: "10000101" + lane_swap: "03671245" + - id: "8" + tx_polarity: "01110101" + rx_polarity: "00010000" + lane_swap: "12640375" + - id: "9" + tx_polarity: "01011100" + rx_polarity: "11001111" + lane_swap: "02561347" + - id: "10" + tx_polarity: "01110110" + rx_polarity: "11000000" + lane_swap: "12740365" + - id: "11" + tx_polarity: "00111000" + rx_polarity: "00010111" + lane_swap: "01572436" + - id: "12" + tx_polarity: "00001111" + rx_polarity: "10111001" + lane_swap: "54320176" + - id: "13" + tx_polarity: "10011101" + rx_polarity: "00111011" + lane_swap: "26153704" + - id: "14" + tx_polarity: "00110000" + rx_polarity: "11010000" + lane_swap: "37452601" + - id: "15" + tx_polarity: "11100010" + rx_polarity: "01110011" + lane_swap: "51370462" + - id: "16" + tx_polarity: "10111010" + rx_polarity: "11010011" + lane_swap: "36152704" + - id: "17" + tx_polarity: "01011101" + rx_polarity: "00110001" + lane_swap: "45621073" + - id: "18" + tx_polarity: "11011111" + rx_polarity: "11001011" + lane_swap: "26143705" + - id: "19" + tx_polarity: "00100110" + rx_polarity: "00001001" + lane_swap: "42730165" + - id: "20" + tx_polarity: "10011011" + rx_polarity: "01101101" + lane_swap: "54217603" + - id: "21" + tx_polarity: "00101110" + rx_polarity: "10111111" + lane_swap: "26031745" + - id: "22" + tx_polarity: "01001110" + rx_polarity: "00111001" + lane_swap: "36024715" + - id: "23" + tx_polarity: "10101101" + rx_polarity: "01010011" + lane_swap: "45621370" + - id: "24" + tx_polarity: "11001110" + rx_polarity: "00011111" + lane_swap: "65234701" + - id: "25" + tx_polarity: "01110001" + rx_polarity: "01010111" + lane_swap: "37601452" + - id: "26" + tx_polarity: "01000100" + rx_polarity: "00001111" + lane_swap: "65034721" + - id: "27" + tx_polarity: "10111101" + rx_polarity: "11000101" + lane_swap: "34501672" + - id: "28" + tx_polarity: "01111000" + rx_polarity: "01110110" + lane_swap: "43061275" + - id: "29" + tx_polarity: "11110111" + rx_polarity: "11100111" + lane_swap: "57304621" + - id: "30" + tx_polarity: "10000100" + rx_polarity: "00101111" + lane_swap: "47125603" + - id: "31" + tx_polarity: "11111111" + rx_polarity: "11100010" + lane_swap: "13460275" + - id: "32" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if/inno.config.yaml b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if/inno.config.yaml new file mode 100755 index 000000000000..360b5af8e602 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if/inno.config.yaml @@ -0,0 +1,7 @@ +IFCS_INIT_FILE : "/usr/share/sonic/hwsku/config_32x400G_Delta-et-c032if.yaml" +IFCS_SKU_FILE : "/usr/share/sonic/hwsku/innovium.77700_A" +IFCS_INNO_CLI_PORT : "9999" +IFCS_TARGET : "device" +ULIMIT : "65536" +INNOVIUM_DIR : "/innovium" +PYTHONPATH : "$INNOVIUM_DIR:$INNOVIUM_DIR/cmds:$INNOVIUM_DIR/scripts:$INNOVIUM_DIR/test/:$INNOVIUM_DIR/test/utils:$INNOVIUM_DIR/utils:$INNOVIUM_DIR/pyctypes" diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if/innovium.77700_A b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if/innovium.77700_A new file mode 100644 index 000000000000..84aa41983606 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if/innovium.77700_A @@ -0,0 +1,59 @@ +sku: innovium.77700_A + +device_id: 0x1b58 + +# Hardware constraint information +hardware: + num_ibs: 6 + + ports_per_ib: 32, 32, 32, 32, 20, 20 + recirc_port_num: 32, 32, 32, 32, 32, 32 + cpu_port_num: 33 + cpu_port_ib: 0 + mgmt_port_num: 33 + mgmt_port_ibs: 1,2 + + pics_per_ib: 6, 7, 6, 5, 5, 5 + pic_ports_per_pic: 8 + max_serdes_speed: 50 + + num_shared_pics: 2 + + isg [0-4]: + ib: 0 + pic_id: [0-4] + + isg [5-9]: + ib: 5 + pic_id: [0-4] + + isg [10-14]: + ib: 1 + pic_id: [0-4] + + isg [16-20]: + ib: 3 + pic_id: [0-4] + + isg [21-25]: + ib: 4 + pic_id: [0-4] + + isg [26-30]: + ib: 2 + pic_id: [0-4] + + isg 15: + mode: 8:0 + ib: 1 + pic_id: 5 + + isg 31: + mode: 8:0 + ib: 0 + pic_id: 5 + + isg 32: + mode: 1:1 + ib: 1, 2 + pic_id: 6 diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if/port_config.ini b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if/port_config.ini new file mode 100755 index 000000000000..360e363f485b --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if/port_config.ini @@ -0,0 +1,35 @@ +# name lanes speed index mtu fec +Ethernet0 249,250,251,252 400000 0 9126 rs +Ethernet8 241,242,243,244 400000 1 9126 rs +Ethernet16 233,234,235,236 400000 2 9126 rs +Ethernet24 225,226,227,228 400000 3 9126 rs +Ethernet32 217,218,219,220 400000 4 9126 rs +Ethernet40 209,210,211,212 400000 5 9126 rs +Ethernet48 201,202,203,204 400000 6 9126 rs +Ethernet56 193,194,195,196 400000 7 9126 rs +Ethernet64 185,186,187,188 400000 8 9126 rs +Ethernet72 177,178,179,180 400000 9 9126 rs +Ethernet80 169,170,171,172 400000 10 9126 rs +Ethernet88 161,162,163,164 400000 11 9126 rs +Ethernet96 153,154,155,156 400000 12 9126 rs +Ethernet104 145,146,147,148 400000 13 9126 rs +Ethernet112 137,138,139,140 400000 14 9126 rs +Ethernet120 129,130,131,132 400000 15 9126 rs +Ethernet128 121,122,123,124 400000 16 9126 rs +Ethernet136 113,114,115,116 400000 17 9126 rs +Ethernet144 97,98,99,100 400000 18 9126 rs +Ethernet152 105,106,107,108 400000 19 9126 rs +Ethernet160 81,82,83,84 400000 20 9126 rs +Ethernet168 89,90,91,92 400000 21 9126 rs +Ethernet176 65,66,67,68 400000 22 9126 rs +Ethernet184 73,74,75,76 400000 23 9126 rs +Ethernet192 49,50,51,52 400000 24 9126 rs +Ethernet200 57,58,59,60 400000 25 9126 rs +Ethernet208 33,34,35,36 400000 26 9126 rs +Ethernet216 41,42,43,44 400000 27 9126 rs +Ethernet224 17,18,19,20 400000 28 9126 rs +Ethernet232 25,26,27,28 400000 29 9126 rs +Ethernet240 1,2,3,4 400000 30 9126 rs +Ethernet248 9,10,11,12 400000 31 9126 rs +Ethernet256 257 10000 32 9126 none +Ethernet257 258 10000 33 9126 none diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if/qos.json.j2 b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if/qos.json.j2 new file mode 100755 index 000000000000..6c734d46ff2f --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if/qos.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} + +{% set default_ports_num = 32 -%} +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "1":"1", + "0":"0", + "3":"3", + "2":"2", + "5":"5", + "4":"4", + "7":"7", + "6":"6" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "1": "0", + "0": "0", + "3": "0", + "2": "0", + "4": "1", + "5": "2", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"0", + "4":"4", + "5":"5", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "4,5" + } + } +} diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if/sai.profile b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if/sai.profile new file mode 100755 index 000000000000..0769b3063a12 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/inno.config.yaml diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_128x100/buffers.json.j2 b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_128x100/buffers.json.j2 new file mode 100644 index 000000000000..9529fbf52fb5 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_128x100/buffers.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '300m' %} +{% set default_ports_num = 128 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*2)) %}{% 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(',') -%} + +{ + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "47218432", + "type": "ingress", + "mode": "dynamic", + "xoff": "17708800" + }, + "egress_lossy_pool": { + "size": "18874368", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"1433600", + "size":"1518", + "dynamic_th":"-4", + "xon_offset":"6272" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_128x100/config_128x100G_Delta-et-c032if.yaml b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_128x100/config_128x100G_Delta-et-c032if.yaml new file mode 100755 index 000000000000..ad50fd04c2a0 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_128x100/config_128x100G_Delta-et-c032if.yaml @@ -0,0 +1,1102 @@ +ifcs: + options: + log_level: "info" +nodes: +- node_id: "0" + options: + sku: "configs/sku/innovium.77700_B" + netdev: + - auto_create: "no" + multi_interface: "yes" + buffer_management_mode: "api_driven" + max_lossless_tc: "2" + txring: + - txring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + rxring: + - rxring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44" + - rxring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45" + - rxring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46" + - rxring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47" + sys_clk: "1720" + ifc_clk: "1200" + mac_clk: "1340" + + devports: + - id: "0" + sysport: "1000" + type: "cpu" + - fec: "KPFEC" + id: "249" + lanes: "0:2" + serdes_group: "31" + speed: "100G" + sysport: "249" + type: "eth" + - fec: "KPFEC" + id: "251" + lanes: "2:2" + serdes_group: "31" + speed: "100G" + sysport: "251" + type: "eth" + - fec: "KPFEC" + id: "253" + lanes: "4:2" + serdes_group: "31" + speed: "100G" + sysport: "253" + type: "eth" + - fec: "KPFEC" + id: "255" + lanes: "6:2" + serdes_group: "31" + speed: "100G" + sysport: "255" + type: "eth" + - fec: "KPFEC" + id: "241" + lanes: "0:2" + serdes_group: "30" + speed: "100G" + sysport: "241" + type: "eth" + - fec: "KPFEC" + id: "243" + lanes: "2:2" + serdes_group: "30" + speed: "100G" + sysport: "243" + type: "eth" + - fec: "KPFEC" + id: "245" + lanes: "4:2" + serdes_group: "30" + speed: "100G" + sysport: "245" + type: "eth" + - fec: "KPFEC" + id: "247" + lanes: "6:2" + serdes_group: "30" + speed: "100G" + sysport: "247" + type: "eth" + - fec: "KPFEC" + id: "233" + lanes: "0:2" + serdes_group: "29" + speed: "100G" + sysport: "233" + type: "eth" + - fec: "KPFEC" + id: "235" + lanes: "2:2" + serdes_group: "29" + speed: "100G" + sysport: "235" + type: "eth" + - fec: "KPFEC" + id: "237" + lanes: "4:2" + serdes_group: "29" + speed: "100G" + sysport: "237" + type: "eth" + - fec: "KPFEC" + id: "239" + lanes: "6:2" + serdes_group: "29" + speed: "100G" + sysport: "239" + type: "eth" + - fec: "KPFEC" + id: "225" + lanes: "0:2" + serdes_group: "28" + speed: "100G" + sysport: "225" + type: "eth" + - fec: "KPFEC" + id: "227" + lanes: "2:2" + serdes_group: "28" + speed: "100G" + sysport: "227" + type: "eth" + - fec: "KPFEC" + id: "229" + lanes: "4:2" + serdes_group: "28" + speed: "100G" + sysport: "229" + type: "eth" + - fec: "KPFEC" + id: "231" + lanes: "6:2" + serdes_group: "28" + speed: "100G" + sysport: "231" + type: "eth" + - fec: "KPFEC" + id: "217" + lanes: "0:2" + serdes_group: "27" + speed: "100G" + sysport: "217" + type: "eth" + - fec: "KPFEC" + id: "219" + lanes: "2:2" + serdes_group: "27" + speed: "100G" + sysport: "219" + type: "eth" + - fec: "KPFEC" + id: "221" + lanes: "4:2" + serdes_group: "27" + speed: "100G" + sysport: "221" + type: "eth" + - fec: "KPFEC" + id: "223" + lanes: "6:2" + serdes_group: "27" + speed: "100G" + sysport: "223" + type: "eth" + - fec: "KPFEC" + id: "209" + lanes: "0:2" + serdes_group: "26" + speed: "100G" + sysport: "209" + type: "eth" + - fec: "KPFEC" + id: "211" + lanes: "2:2" + serdes_group: "26" + speed: "100G" + sysport: "211" + type: "eth" + - fec: "KPFEC" + id: "213" + lanes: "4:2" + serdes_group: "26" + speed: "100G" + sysport: "213" + type: "eth" + - fec: "KPFEC" + id: "215" + lanes: "6:2" + serdes_group: "26" + speed: "100G" + sysport: "215" + type: "eth" + - fec: "KPFEC" + id: "201" + lanes: "0:2" + serdes_group: "25" + speed: "100G" + sysport: "201" + type: "eth" + - fec: "KPFEC" + id: "203" + lanes: "2:2" + serdes_group: "25" + speed: "100G" + sysport: "203" + type: "eth" + - fec: "KPFEC" + id: "205" + lanes: "4:2" + serdes_group: "25" + speed: "100G" + sysport: "205" + type: "eth" + - fec: "KPFEC" + id: "207" + lanes: "6:2" + serdes_group: "25" + speed: "100G" + sysport: "207" + type: "eth" + - fec: "KPFEC" + id: "193" + lanes: "0:2" + serdes_group: "24" + speed: "100G" + sysport: "193" + type: "eth" + - fec: "KPFEC" + id: "195" + lanes: "2:2" + serdes_group: "24" + speed: "100G" + sysport: "195" + type: "eth" + - fec: "KPFEC" + id: "197" + lanes: "4:2" + serdes_group: "24" + speed: "100G" + sysport: "197" + type: "eth" + - fec: "KPFEC" + id: "199" + lanes: "6:2" + serdes_group: "24" + speed: "100G" + sysport: "199" + type: "eth" + - fec: "KPFEC" + id: "185" + lanes: "0:2" + serdes_group: "23" + speed: "100G" + sysport: "185" + type: "eth" + - fec: "KPFEC" + id: "187" + lanes: "2:2" + serdes_group: "23" + speed: "100G" + sysport: "187" + type: "eth" + - fec: "KPFEC" + id: "189" + lanes: "4:2" + serdes_group: "23" + speed: "100G" + sysport: "189" + type: "eth" + - fec: "KPFEC" + id: "191" + lanes: "6:2" + serdes_group: "23" + speed: "100G" + sysport: "191" + type: "eth" + - fec: "KPFEC" + id: "177" + lanes: "0:2" + serdes_group: "22" + speed: "100G" + sysport: "177" + type: "eth" + - fec: "KPFEC" + id: "179" + lanes: "2:2" + serdes_group: "22" + speed: "100G" + sysport: "179" + type: "eth" + - fec: "KPFEC" + id: "181" + lanes: "4:2" + serdes_group: "22" + speed: "100G" + sysport: "181" + type: "eth" + - fec: "KPFEC" + id: "183" + lanes: "6:2" + serdes_group: "22" + speed: "100G" + sysport: "183" + type: "eth" + - fec: "KPFEC" + id: "169" + lanes: "0:2" + serdes_group: "21" + speed: "100G" + sysport: "169" + type: "eth" + - fec: "KPFEC" + id: "171" + lanes: "2:2" + serdes_group: "21" + speed: "100G" + sysport: "171" + type: "eth" + - fec: "KPFEC" + id: "173" + lanes: "4:2" + serdes_group: "21" + speed: "100G" + sysport: "173" + type: "eth" + - fec: "KPFEC" + id: "175" + lanes: "6:2" + serdes_group: "21" + speed: "100G" + sysport: "175" + type: "eth" + - fec: "KPFEC" + id: "161" + lanes: "0:2" + serdes_group: "20" + speed: "100G" + sysport: "161" + type: "eth" + - fec: "KPFEC" + id: "163" + lanes: "2:2" + serdes_group: "20" + speed: "100G" + sysport: "163" + type: "eth" + - fec: "KPFEC" + id: "165" + lanes: "4:2" + serdes_group: "20" + speed: "100G" + sysport: "165" + type: "eth" + - fec: "KPFEC" + id: "167" + lanes: "6:2" + serdes_group: "20" + speed: "100G" + sysport: "167" + type: "eth" + - fec: "KPFEC" + id: "153" + lanes: "0:2" + serdes_group: "19" + speed: "100G" + sysport: "153" + type: "eth" + - fec: "KPFEC" + id: "155" + lanes: "2:2" + serdes_group: "19" + speed: "100G" + sysport: "155" + type: "eth" + - fec: "KPFEC" + id: "157" + lanes: "4:2" + serdes_group: "19" + speed: "100G" + sysport: "157" + type: "eth" + - fec: "KPFEC" + id: "159" + lanes: "6:2" + serdes_group: "19" + speed: "100G" + sysport: "159" + type: "eth" + - fec: "KPFEC" + id: "145" + lanes: "0:2" + serdes_group: "18" + speed: "100G" + sysport: "145" + type: "eth" + - fec: "KPFEC" + id: "147" + lanes: "2:2" + serdes_group: "18" + speed: "100G" + sysport: "147" + type: "eth" + - fec: "KPFEC" + id: "149" + lanes: "4:2" + serdes_group: "18" + speed: "100G" + sysport: "149" + type: "eth" + - fec: "KPFEC" + id: "151" + lanes: "6:2" + serdes_group: "18" + speed: "100G" + sysport: "151" + type: "eth" + - fec: "KPFEC" + id: "137" + lanes: "0:2" + serdes_group: "17" + speed: "100G" + sysport: "137" + type: "eth" + - fec: "KPFEC" + id: "139" + lanes: "2:2" + serdes_group: "17" + speed: "100G" + sysport: "139" + type: "eth" + - fec: "KPFEC" + id: "141" + lanes: "4:2" + serdes_group: "17" + speed: "100G" + sysport: "141" + type: "eth" + - fec: "KPFEC" + id: "143" + lanes: "6:2" + serdes_group: "17" + speed: "100G" + sysport: "143" + type: "eth" + - fec: "KPFEC" + id: "129" + lanes: "0:2" + serdes_group: "16" + speed: "100G" + sysport: "129" + type: "eth" + - fec: "KPFEC" + id: "131" + lanes: "2:2" + serdes_group: "16" + speed: "100G" + sysport: "131" + type: "eth" + - fec: "KPFEC" + id: "133" + lanes: "4:2" + serdes_group: "16" + speed: "100G" + sysport: "133" + type: "eth" + - fec: "KPFEC" + id: "135" + lanes: "6:2" + serdes_group: "16" + speed: "100G" + sysport: "135" + type: "eth" + - fec: "KPFEC" + id: "121" + lanes: "0:2" + serdes_group: "15" + speed: "100G" + sysport: "121" + type: "eth" + - fec: "KPFEC" + id: "123" + lanes: "2:2" + serdes_group: "15" + speed: "100G" + sysport: "123" + type: "eth" + - fec: "KPFEC" + id: "125" + lanes: "4:2" + serdes_group: "15" + speed: "100G" + sysport: "125" + type: "eth" + - fec: "KPFEC" + id: "127" + lanes: "6:2" + serdes_group: "15" + speed: "100G" + sysport: "127" + type: "eth" + - fec: "KPFEC" + id: "113" + lanes: "0:2" + serdes_group: "14" + speed: "100G" + sysport: "113" + type: "eth" + - fec: "KPFEC" + id: "115" + lanes: "2:2" + serdes_group: "14" + speed: "100G" + sysport: "115" + type: "eth" + - fec: "KPFEC" + id: "117" + lanes: "4:2" + serdes_group: "14" + speed: "100G" + sysport: "117" + type: "eth" + - fec: "KPFEC" + id: "119" + lanes: "6:2" + serdes_group: "14" + speed: "100G" + sysport: "119" + type: "eth" + - fec: "KPFEC" + id: "97" + lanes: "0:2" + serdes_group: "12" + speed: "100G" + sysport: "97" + type: "eth" + - fec: "KPFEC" + id: "99" + lanes: "2:2" + serdes_group: "12" + speed: "100G" + sysport: "99" + type: "eth" + - fec: "KPFEC" + id: "101" + lanes: "4:2" + serdes_group: "12" + speed: "100G" + sysport: "101" + type: "eth" + - fec: "KPFEC" + id: "103" + lanes: "6:2" + serdes_group: "12" + speed: "100G" + sysport: "103" + type: "eth" + - fec: "KPFEC" + id: "105" + lanes: "0:2" + serdes_group: "13" + speed: "100G" + sysport: "105" + type: "eth" + - fec: "KPFEC" + id: "107" + lanes: "2:2" + serdes_group: "13" + speed: "100G" + sysport: "107" + type: "eth" + - fec: "KPFEC" + id: "109" + lanes: "4:2" + serdes_group: "13" + speed: "100G" + sysport: "109" + type: "eth" + - fec: "KPFEC" + id: "111" + lanes: "6:2" + serdes_group: "13" + speed: "100G" + sysport: "111" + type: "eth" + - fec: "KPFEC" + id: "81" + lanes: "0:2" + serdes_group: "10" + speed: "100G" + sysport: "81" + type: "eth" + - fec: "KPFEC" + id: "83" + lanes: "2:2" + serdes_group: "10" + speed: "100G" + sysport: "83" + type: "eth" + - fec: "KPFEC" + id: "85" + lanes: "4:2" + serdes_group: "10" + speed: "100G" + sysport: "85" + type: "eth" + - fec: "KPFEC" + id: "87" + lanes: "6:2" + serdes_group: "10" + speed: "100G" + sysport: "87" + type: "eth" + - fec: "KPFEC" + id: "89" + lanes: "0:2" + serdes_group: "11" + speed: "100G" + sysport: "89" + type: "eth" + - fec: "KPFEC" + id: "91" + lanes: "2:2" + serdes_group: "11" + speed: "100G" + sysport: "91" + type: "eth" + - fec: "KPFEC" + id: "93" + lanes: "4:2" + serdes_group: "11" + speed: "100G" + sysport: "93" + type: "eth" + - fec: "KPFEC" + id: "95" + lanes: "6:2" + serdes_group: "11" + speed: "100G" + sysport: "95" + type: "eth" + - fec: "KPFEC" + id: "65" + lanes: "0:2" + serdes_group: "8" + speed: "100G" + sysport: "65" + type: "eth" + - fec: "KPFEC" + id: "67" + lanes: "2:2" + serdes_group: "8" + speed: "100G" + sysport: "67" + type: "eth" + - fec: "KPFEC" + id: "69" + lanes: "4:2" + serdes_group: "8" + speed: "100G" + sysport: "69" + type: "eth" + - fec: "KPFEC" + id: "71" + lanes: "6:2" + serdes_group: "8" + speed: "100G" + sysport: "71" + type: "eth" + - fec: "KPFEC" + id: "73" + lanes: "0:2" + serdes_group: "9" + speed: "100G" + sysport: "73" + type: "eth" + - fec: "KPFEC" + id: "75" + lanes: "2:2" + serdes_group: "9" + speed: "100G" + sysport: "75" + type: "eth" + - fec: "KPFEC" + id: "77" + lanes: "4:2" + serdes_group: "9" + speed: "100G" + sysport: "77" + type: "eth" + - fec: "KPFEC" + id: "79" + lanes: "6:2" + serdes_group: "9" + speed: "100G" + sysport: "79" + type: "eth" + - fec: "KPFEC" + id: "49" + lanes: "0:2" + serdes_group: "6" + speed: "100G" + sysport: "49" + type: "eth" + - fec: "KPFEC" + id: "51" + lanes: "2:2" + serdes_group: "6" + speed: "100G" + sysport: "51" + type: "eth" + - fec: "KPFEC" + id: "53" + lanes: "4:2" + serdes_group: "6" + speed: "100G" + sysport: "53" + type: "eth" + - fec: "KPFEC" + id: "55" + lanes: "6:2" + serdes_group: "6" + speed: "100G" + sysport: "55" + type: "eth" + - fec: "KPFEC" + id: "57" + lanes: "0:2" + serdes_group: "7" + speed: "100G" + sysport: "57" + type: "eth" + - fec: "KPFEC" + id: "59" + lanes: "2:2" + serdes_group: "7" + speed: "100G" + sysport: "59" + type: "eth" + - fec: "KPFEC" + id: "61" + lanes: "4:2" + serdes_group: "7" + speed: "100G" + sysport: "61" + type: "eth" + - fec: "KPFEC" + id: "63" + lanes: "6:2" + serdes_group: "7" + speed: "100G" + sysport: "63" + type: "eth" + - fec: "KPFEC" + id: "33" + lanes: "0:2" + serdes_group: "4" + speed: "100G" + sysport: "33" + type: "eth" + - fec: "KPFEC" + id: "35" + lanes: "2:2" + serdes_group: "4" + speed: "100G" + sysport: "35" + type: "eth" + - fec: "KPFEC" + id: "37" + lanes: "4:2" + serdes_group: "4" + speed: "100G" + sysport: "37" + type: "eth" + - fec: "KPFEC" + id: "39" + lanes: "6:2" + serdes_group: "4" + speed: "100G" + sysport: "39" + type: "eth" + - fec: "KPFEC" + id: "41" + lanes: "0:2" + serdes_group: "5" + speed: "100G" + sysport: "41" + type: "eth" + - fec: "KPFEC" + id: "43" + lanes: "2:2" + serdes_group: "5" + speed: "100G" + sysport: "43" + type: "eth" + - fec: "KPFEC" + id: "45" + lanes: "4:2" + serdes_group: "5" + speed: "100G" + sysport: "45" + type: "eth" + - fec: "KPFEC" + id: "47" + lanes: "6:2" + serdes_group: "5" + speed: "100G" + sysport: "47" + type: "eth" + - fec: "KPFEC" + id: "17" + lanes: "0:2" + serdes_group: "2" + speed: "100G" + sysport: "17" + type: "eth" + - fec: "KPFEC" + id: "19" + lanes: "2:2" + serdes_group: "2" + speed: "100G" + sysport: "19" + type: "eth" + - fec: "KPFEC" + id: "21" + lanes: "4:2" + serdes_group: "2" + speed: "100G" + sysport: "21" + type: "eth" + - fec: "KPFEC" + id: "23" + lanes: "6:2" + serdes_group: "2" + speed: "100G" + sysport: "23" + type: "eth" + - fec: "KPFEC" + id: "25" + lanes: "0:2" + serdes_group: "3" + speed: "100G" + sysport: "25" + type: "eth" + - fec: "KPFEC" + id: "27" + lanes: "2:2" + serdes_group: "3" + speed: "100G" + sysport: "27" + type: "eth" + - fec: "KPFEC" + id: "29" + lanes: "4:2" + serdes_group: "3" + speed: "100G" + sysport: "29" + type: "eth" + - fec: "KPFEC" + id: "31" + lanes: "6:2" + serdes_group: "3" + speed: "100G" + sysport: "31" + type: "eth" + - fec: "KPFEC" + id: "1" + lanes: "0:2" + serdes_group: "0" + speed: "100G" + sysport: "1" + type: "eth" + - fec: "KPFEC" + id: "3" + lanes: "2:2" + serdes_group: "0" + speed: "100G" + sysport: "3" + type: "eth" + - fec: "KPFEC" + id: "5" + lanes: "4:2" + serdes_group: "0" + speed: "100G" + sysport: "5" + type: "eth" + - fec: "KPFEC" + id: "7" + lanes: "6:2" + serdes_group: "0" + speed: "100G" + sysport: "7" + type: "eth" + - fec: "KPFEC" + id: "9" + lanes: "0:2" + serdes_group: "1" + speed: "100G" + sysport: "9" + type: "eth" + - fec: "KPFEC" + id: "11" + lanes: "2:2" + serdes_group: "1" + speed: "100G" + sysport: "11" + type: "eth" + - fec: "KPFEC" + id: "13" + lanes: "4:2" + serdes_group: "1" + speed: "100G" + sysport: "13" + type: "eth" + - fec: "KPFEC" + id: "15" + lanes: "6:2" + serdes_group: "1" + speed: "100G" + sysport: "15" + type: "eth" + - fec: "NONE" + id: "257" + lanes: "0:1" + serdes_group: "32" + speed: "10G" + sysport: "257" + type: "mgmt 0" + - fec: "NONE" + id: "258" + lanes: "1:1" + serdes_group: "32" + speed: "10G" + sysport: "258" + type: "mgmt 1" + + isg: + - id: "0" + tx_polarity: "01010101" + rx_polarity: "01100000" + lane_swap: "23641075" + - id: "1" + tx_polarity: "10110000" + rx_polarity: "11111111" + lane_swap: "64317520" + - id: "2" + tx_polarity: "00000000" + rx_polarity: "00000011" + lane_swap: "63147520" + - id: "3" + tx_polarity: "01101000" + rx_polarity: "00001110" + lane_swap: "31572046" + - id: "4" + tx_polarity: "00111000" + rx_polarity: "00001000" + lane_swap: "46105732" + - id: "5" + tx_polarity: "10111111" + rx_polarity: "11101000" + lane_swap: "27153604" + - id: "6" + tx_polarity: "01101110" + rx_polarity: "00001101" + lane_swap: "46503721" + - id: "7" + tx_polarity: "01000100" + rx_polarity: "10000101" + lane_swap: "03671245" + - id: "8" + tx_polarity: "01110101" + rx_polarity: "00010000" + lane_swap: "12640375" + - id: "9" + tx_polarity: "01011100" + rx_polarity: "11001111" + lane_swap: "02561347" + - id: "10" + tx_polarity: "01110110" + rx_polarity: "11000000" + lane_swap: "12740365" + - id: "11" + tx_polarity: "00111000" + rx_polarity: "00010111" + lane_swap: "01572436" + - id: "12" + tx_polarity: "00001111" + rx_polarity: "10111001" + lane_swap: "54320176" + - id: "13" + tx_polarity: "10011101" + rx_polarity: "00111011" + lane_swap: "26153704" + - id: "14" + tx_polarity: "00110000" + rx_polarity: "11010000" + lane_swap: "37452601" + - id: "15" + tx_polarity: "11100010" + rx_polarity: "01110011" + lane_swap: "51370462" + - id: "16" + tx_polarity: "10111010" + rx_polarity: "11010011" + lane_swap: "36152704" + - id: "17" + tx_polarity: "01011101" + rx_polarity: "00110001" + lane_swap: "45621073" + - id: "18" + tx_polarity: "11011111" + rx_polarity: "11001011" + lane_swap: "26143705" + - id: "19" + tx_polarity: "00100110" + rx_polarity: "00001001" + lane_swap: "42730165" + - id: "20" + tx_polarity: "10011011" + rx_polarity: "01101101" + lane_swap: "54217603" + - id: "21" + tx_polarity: "00101110" + rx_polarity: "10111111" + lane_swap: "26031745" + - id: "22" + tx_polarity: "01001110" + rx_polarity: "00111001" + lane_swap: "36024715" + - id: "23" + tx_polarity: "10101101" + rx_polarity: "01010011" + lane_swap: "45621370" + - id: "24" + tx_polarity: "11001110" + rx_polarity: "00011111" + lane_swap: "65234701" + - id: "25" + tx_polarity: "01110001" + rx_polarity: "01010111" + lane_swap: "37601452" + - id: "26" + tx_polarity: "01000100" + rx_polarity: "00001111" + lane_swap: "65034721" + - id: "27" + tx_polarity: "10111101" + rx_polarity: "11000101" + lane_swap: "34501672" + - id: "28" + tx_polarity: "01111000" + rx_polarity: "01110110" + lane_swap: "43061275" + - id: "29" + tx_polarity: "11110111" + rx_polarity: "11100111" + lane_swap: "57304621" + - id: "30" + tx_polarity: "10000100" + rx_polarity: "00101111" + lane_swap: "47125603" + - id: "31" + tx_polarity: "11111111" + rx_polarity: "11100010" + lane_swap: "13460275" + - id: "32" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_128x100/inno.config.yaml b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_128x100/inno.config.yaml new file mode 100755 index 000000000000..17f3e060d712 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_128x100/inno.config.yaml @@ -0,0 +1,7 @@ +IFCS_INIT_FILE : "/usr/share/sonic/hwsku/config_128x100G_Delta-et-c032if.yaml" +IFCS_SKU_FILE : "/usr/share/sonic/hwsku/innovium.77700_B" +IFCS_INNO_CLI_PORT : "9999" +IFCS_TARGET : "device" +ULIMIT : "65536" +INNOVIUM_DIR : "/innovium" +PYTHONPATH : "$INNOVIUM_DIR:$INNOVIUM_DIR/cmds:$INNOVIUM_DIR/scripts:$INNOVIUM_DIR/test/:$INNOVIUM_DIR/test/utils:$INNOVIUM_DIR/utils:$INNOVIUM_DIR/pyctypes" diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_128x100/innovium.77700_B b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_128x100/innovium.77700_B new file mode 100644 index 000000000000..27297b313959 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_128x100/innovium.77700_B @@ -0,0 +1,59 @@ +sku: innovium.77700_B + +device_id: 0x1b58 + +# Hardware constraint information +hardware: + num_ibs: 6 + + ports_per_ib: 32, 32, 32, 32, 20, 20 + recirc_port_num: 32, 32, 32, 32, 32, 32 + cpu_port_num: 33 + cpu_port_ib: 0 + mgmt_port_num: 33 + mgmt_port_ibs: 1,2 + + pics_per_ib: 6, 7, 7, 6, 5, 5 + pic_ports_per_pic: 8 + max_serdes_speed: 50 + + num_shared_pics: 2 + + isg [0-4]: + ib: 0 + pic_id: [0-4] + + isg [5-9]: + ib: 5 + pic_id: [0-4] + + isg [10-14]: + ib: 1 + pic_id: [0-4] + + isg [16-20]: + ib: 3 + pic_id: [0-4] + + isg [21-25]: + ib: 4 + pic_id: [0-4] + + isg [26-30]: + ib: 2 + pic_id: [0-4] + + isg 15: + mode: 4:4 + ib: 1, 3 + pic_id: 5 + + isg 31: + mode: 4:4 + ib: 0, 2 + pic_id: 5 + + isg 32: + mode: 1:1 + ib: 1, 2 + pic_id: 6 diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_128x100/port_config.ini b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_128x100/port_config.ini new file mode 100644 index 000000000000..cd4dbc611ec1 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_128x100/port_config.ini @@ -0,0 +1,131 @@ +# name lanes speed index mtu +Ethernet0 249,250 100000 0 9126 +Ethernet2 251,252 100000 0 9126 +Ethernet4 253,254 100000 0 9126 +Ethernet6 255,256 100000 0 9126 +Ethernet8 241,242 100000 1 9126 +Ethernet10 243,244 100000 1 9126 +Ethernet12 245,246 100000 1 9126 +Ethernet14 247,248 100000 1 9126 +Ethernet16 233,234 100000 2 9126 +Ethernet18 235,236 100000 2 9126 +Ethernet20 237,238 100000 2 9126 +Ethernet22 239,240 100000 2 9126 +Ethernet24 225,226 100000 3 9126 +Ethernet26 227,228 100000 3 9126 +Ethernet28 229,230 100000 3 9126 +Ethernet30 231,232 100000 3 9126 +Ethernet32 217,218 100000 4 9126 +Ethernet34 219,220 100000 4 9126 +Ethernet36 221,222 100000 4 9126 +Ethernet38 223,224 100000 4 9126 +Ethernet40 209,210 100000 5 9126 +Ethernet42 211,212 100000 5 9126 +Ethernet44 213,214 100000 5 9126 +Ethernet46 215,216 100000 5 9126 +Ethernet48 201,202 100000 6 9126 +Ethernet50 203,204 100000 6 9126 +Ethernet52 205,206 100000 6 9126 +Ethernet54 207,208 100000 6 9126 +Ethernet56 193,194 100000 7 9126 +Ethernet58 195,196 100000 7 9126 +Ethernet60 197,198 100000 7 9126 +Ethernet62 199,200 100000 7 9126 +Ethernet64 185,186 100000 8 9126 +Ethernet66 187,188 100000 8 9126 +Ethernet68 189,190 100000 8 9126 +Ethernet70 191,192 100000 8 9126 +Ethernet72 177,178 100000 9 9126 +Ethernet74 179,180 100000 9 9126 +Ethernet76 181,182 100000 9 9126 +Ethernet78 183,184 100000 9 9126 +Ethernet80 169,170 100000 10 9126 +Ethernet82 171,172 100000 10 9126 +Ethernet84 173,174 100000 10 9126 +Ethernet86 175,176 100000 10 9126 +Ethernet88 161,162 100000 11 9126 +Ethernet90 163,164 100000 11 9126 +Ethernet92 165,166 100000 11 9126 +Ethernet94 167,168 100000 11 9126 +Ethernet96 153,154 100000 12 9126 +Ethernet98 155,156 100000 12 9126 +Ethernet100 157,158 100000 12 9126 +Ethernet102 159,160 100000 12 9126 +Ethernet104 145,146 100000 13 9126 +Ethernet106 147,148 100000 13 9126 +Ethernet108 149,150 100000 13 9126 +Ethernet110 151,152 100000 13 9126 +Ethernet112 137,138 100000 14 9126 +Ethernet114 139,140 100000 14 9126 +Ethernet116 141,142 100000 14 9126 +Ethernet118 143,144 100000 14 9126 +Ethernet120 129,130 100000 15 9126 +Ethernet122 131,132 100000 15 9126 +Ethernet124 133,134 100000 15 9126 +Ethernet126 135,136 100000 15 9126 +Ethernet128 121,122 100000 16 9126 +Ethernet130 123,124 100000 16 9126 +Ethernet132 125,126 100000 16 9126 +Ethernet134 127,128 100000 16 9126 +Ethernet136 113,114 100000 17 9126 +Ethernet138 115,116 100000 17 9126 +Ethernet140 117,118 100000 17 9126 +Ethernet142 119,120 100000 17 9126 +Ethernet144 97,98 100000 18 9126 +Ethernet146 99,100 100000 18 9126 +Ethernet148 101,102 100000 18 9126 +Ethernet150 103,104 100000 18 9126 +Ethernet152 105,106 100000 19 9126 +Ethernet154 107,108 100000 19 9126 +Ethernet156 109,110 100000 19 9126 +Ethernet158 111,112 100000 19 9126 +Ethernet160 81,82 100000 20 9126 +Ethernet162 83,84 100000 20 9126 +Ethernet164 85,86 100000 20 9126 +Ethernet166 87,88 100000 20 9126 +Ethernet168 89,90 100000 21 9126 +Ethernet170 91,92 100000 21 9126 +Ethernet172 93,94 100000 21 9126 +Ethernet174 95,96 100000 21 9126 +Ethernet176 65,66 100000 22 9126 +Ethernet178 67,68 100000 22 9126 +Ethernet180 69,70 100000 22 9126 +Ethernet182 71,72 100000 22 9126 +Ethernet184 73,74 100000 23 9126 +Ethernet186 75,76 100000 23 9126 +Ethernet188 77,78 100000 23 9126 +Ethernet190 79,80 100000 23 9126 +Ethernet192 49,50 100000 24 9126 +Ethernet194 51,52 100000 24 9126 +Ethernet196 53,54 100000 24 9126 +Ethernet198 55,56 100000 24 9126 +Ethernet200 57,58 100000 25 9126 +Ethernet202 59,60 100000 25 9126 +Ethernet204 61,62 100000 25 9126 +Ethernet206 63,64 100000 25 9126 +Ethernet208 33,34 100000 26 9126 +Ethernet210 35,36 100000 26 9126 +Ethernet212 37,38 100000 26 9126 +Ethernet214 39,40 100000 26 9126 +Ethernet216 41,42 100000 27 9126 +Ethernet218 43,44 100000 27 9126 +Ethernet220 45,46 100000 27 9126 +Ethernet222 47,48 100000 27 9126 +Ethernet224 17,18 100000 28 9126 +Ethernet226 19,20 100000 28 9126 +Ethernet228 21,22 100000 28 9126 +Ethernet230 23,24 100000 28 9126 +Ethernet232 25,26 100000 29 9126 +Ethernet234 27,28 100000 29 9126 +Ethernet236 29,30 100000 29 9126 +Ethernet238 31,32 100000 29 9126 +Ethernet240 1,2 100000 30 9126 +Ethernet242 3,4 100000 30 9126 +Ethernet244 5,6 100000 30 9126 +Ethernet246 7,8 100000 30 9126 +Ethernet248 9,10 100000 31 9126 +Ethernet250 11,12 100000 31 9126 +Ethernet252 13,14 100000 31 9126 +Ethernet254 15,16 100000 31 9126 +Ethernet256 257 10000 32 9126 +Ethernet257 258 10000 33 9126 diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_128x100/qos.json.j2 b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_128x100/qos.json.j2 new file mode 100755 index 000000000000..733bd51dc86f --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_128x100/qos.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} + +{% set default_ports_num = 128 -%} +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*2)) %}{% 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(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "1":"1", + "0":"0", + "3":"3", + "2":"2", + "5":"5", + "4":"4", + "7":"7", + "6":"6" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "1": "0", + "0": "0", + "3": "0", + "2": "0", + "4": "1", + "5": "2", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"0", + "4":"4", + "5":"5", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "4,5" + } + } +} diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_128x100/sai.profile b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_128x100/sai.profile new file mode 100755 index 000000000000..0769b3063a12 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_128x100/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/inno.config.yaml diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/buffers.json.j2 b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/buffers.json.j2 new file mode 100644 index 000000000000..4fca9cbcd156 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/buffers.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '300m' %} +{% set default_ports_num = 32 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "47218432", + "type": "ingress", + "mode": "dynamic", + "xoff": "17708800" + }, + "egress_lossy_pool": { + "size": "18874368", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"1433600", + "size":"1518", + "dynamic_th":"-4", + "xon_offset":"6272" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/config_32x100G_Delta-et-c032if.yaml b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/config_32x100G_Delta-et-c032if.yaml new file mode 100755 index 000000000000..4b4f02da4895 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/config_32x100G_Delta-et-c032if.yaml @@ -0,0 +1,415 @@ +ifcs: + options: + log_level: "info" +nodes: +- node_id: "0" + options: + sku: "configs/sku/innovium.77700_B" + netdev: + - auto_create: "no" + multi_interface: "yes" + buffer_management_mode: "api_driven" + max_lossless_tc: "2" + txring: + - txring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + rxring: + - rxring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44" + - rxring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45" + - rxring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46" + - rxring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47" + sys_clk: "1720" + ifc_clk: "1200" + mac_clk: "1340" + + devports: + - id: "0" + sysport: "1000" + type: "cpu" + - fec: "KRFEC" + id: "249" + lanes: "0:4" + serdes_group: "31" + speed: "100G" + sysport: "249" + type: "eth" + - fec: "KRFEC" + id: "241" + lanes: "0:4" + serdes_group: "30" + speed: "100G" + sysport: "241" + type: "eth" + - fec: "KRFEC" + id: "233" + lanes: "0:4" + serdes_group: "29" + speed: "100G" + sysport: "233" + type: "eth" + - fec: "KRFEC" + id: "225" + lanes: "0:4" + serdes_group: "28" + speed: "100G" + sysport: "225" + type: "eth" + - fec: "KRFEC" + id: "217" + lanes: "0:4" + serdes_group: "27" + speed: "100G" + sysport: "217" + type: "eth" + - fec: "KRFEC" + id: "209" + lanes: "0:4" + serdes_group: "26" + speed: "100G" + sysport: "209" + type: "eth" + - fec: "KRFEC" + id: "201" + lanes: "0:4" + serdes_group: "25" + speed: "100G" + sysport: "201" + type: "eth" + - fec: "KRFEC" + id: "193" + lanes: "0:4" + serdes_group: "24" + speed: "100G" + sysport: "193" + type: "eth" + - fec: "KRFEC" + id: "185" + lanes: "0:4" + serdes_group: "23" + speed: "100G" + sysport: "185" + type: "eth" + - fec: "KRFEC" + id: "177" + lanes: "0:4" + serdes_group: "22" + speed: "100G" + sysport: "177" + type: "eth" + - fec: "KRFEC" + id: "169" + lanes: "0:4" + serdes_group: "21" + speed: "100G" + sysport: "169" + type: "eth" + - fec: "KRFEC" + id: "161" + lanes: "0:4" + serdes_group: "20" + speed: "100G" + sysport: "161" + type: "eth" + - fec: "KRFEC" + id: "153" + lanes: "0:4" + serdes_group: "19" + speed: "100G" + sysport: "153" + type: "eth" + - fec: "KRFEC" + id: "145" + lanes: "0:4" + serdes_group: "18" + speed: "100G" + sysport: "145" + type: "eth" + - fec: "KRFEC" + id: "137" + lanes: "0:4" + serdes_group: "17" + speed: "100G" + sysport: "137" + type: "eth" + - fec: "KRFEC" + id: "129" + lanes: "0:4" + serdes_group: "16" + speed: "100G" + sysport: "129" + type: "eth" + - fec: "KRFEC" + id: "121" + lanes: "0:4" + serdes_group: "15" + speed: "100G" + sysport: "121" + type: "eth" + - fec: "KRFEC" + id: "113" + lanes: "0:4" + serdes_group: "14" + speed: "100G" + sysport: "113" + type: "eth" + - fec: "KRFEC" + id: "97" + lanes: "0:4" + serdes_group: "12" + speed: "100G" + sysport: "97" + type: "eth" + - fec: "KRFEC" + id: "105" + lanes: "0:4" + serdes_group: "13" + speed: "100G" + sysport: "105" + type: "eth" + - fec: "KRFEC" + id: "81" + lanes: "0:4" + serdes_group: "10" + speed: "100G" + sysport: "81" + type: "eth" + - fec: "KRFEC" + id: "89" + lanes: "0:4" + serdes_group: "11" + speed: "100G" + sysport: "89" + type: "eth" + - fec: "KRFEC" + id: "65" + lanes: "0:4" + serdes_group: "8" + speed: "100G" + sysport: "65" + type: "eth" + - fec: "KRFEC" + id: "73" + lanes: "0:4" + serdes_group: "9" + speed: "100G" + sysport: "73" + type: "eth" + - fec: "KRFEC" + id: "49" + lanes: "0:4" + serdes_group: "6" + speed: "100G" + sysport: "49" + type: "eth" + - fec: "KRFEC" + id: "57" + lanes: "0:4" + serdes_group: "7" + speed: "100G" + sysport: "57" + type: "eth" + - fec: "KRFEC" + id: "33" + lanes: "0:4" + serdes_group: "4" + speed: "100G" + sysport: "33" + type: "eth" + - fec: "KRFEC" + id: "41" + lanes: "0:4" + serdes_group: "5" + speed: "100G" + sysport: "41" + type: "eth" + - fec: "KRFEC" + id: "17" + lanes: "0:4" + serdes_group: "2" + speed: "100G" + sysport: "17" + type: "eth" + - fec: "KRFEC" + id: "25" + lanes: "0:4" + serdes_group: "3" + speed: "100G" + sysport: "25" + type: "eth" + - fec: "KRFEC" + id: "1" + lanes: "0:4" + serdes_group: "0" + speed: "100G" + sysport: "1" + type: "eth" + - fec: "KRFEC" + id: "9" + lanes: "0:4" + serdes_group: "1" + speed: "100G" + sysport: "9" + type: "eth" + isg: + - id: "0" + tx_polarity: "01010101" + rx_polarity: "01100000" + lane_swap: "23641075" + - id: "1" + tx_polarity: "10110000" + rx_polarity: "11111111" + lane_swap: "64317520" + - id: "2" + tx_polarity: "00000000" + rx_polarity: "00000011" + lane_swap: "63147520" + - id: "3" + tx_polarity: "01101000" + rx_polarity: "00001110" + lane_swap: "31572046" + - id: "4" + tx_polarity: "00111000" + rx_polarity: "00001000" + lane_swap: "46105732" + - id: "5" + tx_polarity: "10111111" + rx_polarity: "11101000" + lane_swap: "27153604" + - id: "6" + tx_polarity: "01101110" + rx_polarity: "00001101" + lane_swap: "46503721" + - id: "7" + tx_polarity: "01000100" + rx_polarity: "10000101" + lane_swap: "03671245" + - id: "8" + tx_polarity: "01110101" + rx_polarity: "00010000" + lane_swap: "12640375" + - id: "9" + tx_polarity: "01011100" + rx_polarity: "11001111" + lane_swap: "02561347" + - id: "10" + tx_polarity: "01110110" + rx_polarity: "11000000" + lane_swap: "12740365" + - id: "11" + tx_polarity: "00111000" + rx_polarity: "00010111" + lane_swap: "01572436" + - id: "12" + tx_polarity: "00001111" + rx_polarity: "10111001" + lane_swap: "54320176" + - id: "13" + tx_polarity: "10011101" + rx_polarity: "00111011" + lane_swap: "26153704" + - id: "14" + tx_polarity: "00110000" + rx_polarity: "11010000" + lane_swap: "37452601" + - id: "15" + tx_polarity: "11100010" + rx_polarity: "01110011" + lane_swap: "51370462" + - id: "16" + tx_polarity: "10111010" + rx_polarity: "11010011" + lane_swap: "36152704" + - id: "17" + tx_polarity: "01011101" + rx_polarity: "00110001" + lane_swap: "45621073" + - id: "18" + tx_polarity: "11011111" + rx_polarity: "11001011" + lane_swap: "26143705" + - id: "19" + tx_polarity: "00100110" + rx_polarity: "00001001" + lane_swap: "42730165" + - id: "20" + tx_polarity: "10011011" + rx_polarity: "01101101" + lane_swap: "54217603" + - id: "21" + tx_polarity: "00101110" + rx_polarity: "10111111" + lane_swap: "26031745" + - id: "22" + tx_polarity: "01001110" + rx_polarity: "00111001" + lane_swap: "36024715" + - id: "23" + tx_polarity: "10101101" + rx_polarity: "01010011" + lane_swap: "45621370" + - id: "24" + tx_polarity: "11001110" + rx_polarity: "00011111" + lane_swap: "65234701" + - id: "25" + tx_polarity: "01110001" + rx_polarity: "01010111" + lane_swap: "37601452" + - id: "26" + tx_polarity: "01000100" + rx_polarity: "00001111" + lane_swap: "65034721" + - id: "27" + tx_polarity: "10111101" + rx_polarity: "11000101" + lane_swap: "34501672" + - id: "28" + tx_polarity: "01111000" + rx_polarity: "01110110" + lane_swap: "43061275" + - id: "29" + tx_polarity: "11110111" + rx_polarity: "11100111" + lane_swap: "57304621" + - id: "30" + tx_polarity: "10000100" + rx_polarity: "00101111" + lane_swap: "47125603" + - id: "31" + tx_polarity: "11111111" + rx_polarity: "11100010" + lane_swap: "13460275" + - id: "32" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/inno.config.yaml b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/inno.config.yaml new file mode 100755 index 000000000000..9350e166634e --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/inno.config.yaml @@ -0,0 +1,7 @@ +IFCS_INIT_FILE : "/usr/share/sonic/hwsku/config_32x100G_Delta-et-c032if.yaml" +IFCS_SKU_FILE : "/usr/share/sonic/hwsku/innovium.77700_B" +IFCS_INNO_CLI_PORT : "9999" +IFCS_TARGET : "device" +ULIMIT : "65536" +INNOVIUM_DIR : "/innovium" +PYTHONPATH : "$INNOVIUM_DIR:$INNOVIUM_DIR/cmds:$INNOVIUM_DIR/scripts:$INNOVIUM_DIR/test/:$INNOVIUM_DIR/test/utils:$INNOVIUM_DIR/utils:$INNOVIUM_DIR/pyctypes" diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/innovium.77700_A b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/innovium.77700_A new file mode 100644 index 000000000000..84aa41983606 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/innovium.77700_A @@ -0,0 +1,59 @@ +sku: innovium.77700_A + +device_id: 0x1b58 + +# Hardware constraint information +hardware: + num_ibs: 6 + + ports_per_ib: 32, 32, 32, 32, 20, 20 + recirc_port_num: 32, 32, 32, 32, 32, 32 + cpu_port_num: 33 + cpu_port_ib: 0 + mgmt_port_num: 33 + mgmt_port_ibs: 1,2 + + pics_per_ib: 6, 7, 6, 5, 5, 5 + pic_ports_per_pic: 8 + max_serdes_speed: 50 + + num_shared_pics: 2 + + isg [0-4]: + ib: 0 + pic_id: [0-4] + + isg [5-9]: + ib: 5 + pic_id: [0-4] + + isg [10-14]: + ib: 1 + pic_id: [0-4] + + isg [16-20]: + ib: 3 + pic_id: [0-4] + + isg [21-25]: + ib: 4 + pic_id: [0-4] + + isg [26-30]: + ib: 2 + pic_id: [0-4] + + isg 15: + mode: 8:0 + ib: 1 + pic_id: 5 + + isg 31: + mode: 8:0 + ib: 0 + pic_id: 5 + + isg 32: + mode: 1:1 + ib: 1, 2 + pic_id: 6 diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/innovium.77700_B b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/innovium.77700_B new file mode 100644 index 000000000000..27297b313959 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/innovium.77700_B @@ -0,0 +1,59 @@ +sku: innovium.77700_B + +device_id: 0x1b58 + +# Hardware constraint information +hardware: + num_ibs: 6 + + ports_per_ib: 32, 32, 32, 32, 20, 20 + recirc_port_num: 32, 32, 32, 32, 32, 32 + cpu_port_num: 33 + cpu_port_ib: 0 + mgmt_port_num: 33 + mgmt_port_ibs: 1,2 + + pics_per_ib: 6, 7, 7, 6, 5, 5 + pic_ports_per_pic: 8 + max_serdes_speed: 50 + + num_shared_pics: 2 + + isg [0-4]: + ib: 0 + pic_id: [0-4] + + isg [5-9]: + ib: 5 + pic_id: [0-4] + + isg [10-14]: + ib: 1 + pic_id: [0-4] + + isg [16-20]: + ib: 3 + pic_id: [0-4] + + isg [21-25]: + ib: 4 + pic_id: [0-4] + + isg [26-30]: + ib: 2 + pic_id: [0-4] + + isg 15: + mode: 4:4 + ib: 1, 3 + pic_id: 5 + + isg 31: + mode: 4:4 + ib: 0, 2 + pic_id: 5 + + isg 32: + mode: 1:1 + ib: 1, 2 + pic_id: 6 diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/port_config.ini b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/port_config.ini new file mode 100755 index 000000000000..45fbfd346c9f --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/port_config.ini @@ -0,0 +1,33 @@ +# name lanes speed index mtu fec +Ethernet0 249,250,251,252 100000 0 9126 rs +Ethernet8 241,242,243,244 100000 1 9126 rs +Ethernet16 233,234,235,236 100000 2 9126 rs +Ethernet24 225,226,227,228 100000 3 9126 rs +Ethernet32 217,218,219,220 100000 4 9126 rs +Ethernet40 209,210,211,212 100000 5 9126 rs +Ethernet48 201,202,203,204 100000 6 9126 rs +Ethernet56 193,194,195,196 100000 7 9126 rs +Ethernet64 185,186,187,188 100000 8 9126 rs +Ethernet72 177,178,179,180 100000 9 9126 rs +Ethernet80 169,170,171,172 100000 10 9126 rs +Ethernet88 161,162,163,164 100000 11 9126 rs +Ethernet96 153,154,155,156 100000 12 9126 rs +Ethernet104 145,146,147,148 100000 13 9126 rs +Ethernet112 137,138,139,140 100000 14 9126 rs +Ethernet120 129,130,131,132 100000 15 9126 rs +Ethernet128 121,122,123,124 100000 16 9126 rs +Ethernet136 113,114,115,116 100000 17 9126 rs +Ethernet144 97,98,99,100 100000 18 9126 rs +Ethernet152 105,106,107,108 100000 19 9126 rs +Ethernet160 81,82,83,84 100000 20 9126 rs +Ethernet168 89,90,91,92 100000 21 9126 rs +Ethernet176 65,66,67,68 100000 22 9126 rs +Ethernet184 73,74,75,76 100000 23 9126 rs +Ethernet192 49,50,51,52 100000 24 9126 rs +Ethernet200 57,58,59,60 100000 25 9126 rs +Ethernet208 33,34,35,36 100000 26 9126 rs +Ethernet216 41,42,43,44 100000 27 9126 rs +Ethernet224 17,18,19,20 100000 28 9126 rs +Ethernet232 25,26,27,28 100000 29 9126 rs +Ethernet240 1,2,3,4 100000 30 9126 rs +Ethernet248 9,10,11,12 100000 31 9126 rs diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/qos.json.j2 b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/qos.json.j2 new file mode 100755 index 000000000000..6c734d46ff2f --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/qos.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} + +{% set default_ports_num = 32 -%} +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "1":"1", + "0":"0", + "3":"3", + "2":"2", + "5":"5", + "4":"4", + "7":"7", + "6":"6" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "1": "0", + "0": "0", + "3": "0", + "2": "0", + "4": "1", + "5": "2", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"0", + "4":"4", + "5":"5", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "4,5" + } + } +} diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/sai.profile b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/sai.profile new file mode 100755 index 000000000000..0769b3063a12 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x100/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/inno.config.yaml diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x200/buffers.json.j2 b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x200/buffers.json.j2 new file mode 100644 index 000000000000..4fca9cbcd156 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x200/buffers.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '300m' %} +{% set default_ports_num = 32 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "47218432", + "type": "ingress", + "mode": "dynamic", + "xoff": "17708800" + }, + "egress_lossy_pool": { + "size": "18874368", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"1433600", + "size":"1518", + "dynamic_th":"-4", + "xon_offset":"6272" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x200/config_32x200G_Delta-et-c032if.yaml b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x200/config_32x200G_Delta-et-c032if.yaml new file mode 100755 index 000000000000..0a76811110e8 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x200/config_32x200G_Delta-et-c032if.yaml @@ -0,0 +1,429 @@ +ifcs: + options: + log_level: "info" +nodes: +- node_id: "0" + options: + sku: "configs/sku/innovium.77700_B" + netdev: + - auto_create: "no" + multi_interface: "yes" + buffer_management_mode: "api_driven" + max_lossless_tc: "2" + txring: + - txring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + rxring: + - rxring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44" + - rxring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45" + - rxring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46" + - rxring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47" + sys_clk: "1720" + ifc_clk: "1200" + mac_clk: "1340" + + devports: + - id: "0" + sysport: "1000" + type: "cpu" + - fec: "KPFEC" + id: "249" + lanes: "0:4" + serdes_group: "31" + speed: "200G" + sysport: "249" + type: "eth" + - fec: "KPFEC" + id: "241" + lanes: "0:4" + serdes_group: "30" + speed: "200G" + sysport: "241" + type: "eth" + - fec: "KPFEC" + id: "233" + lanes: "0:4" + serdes_group: "29" + speed: "200G" + sysport: "233" + type: "eth" + - fec: "KPFEC" + id: "225" + lanes: "0:4" + serdes_group: "28" + speed: "200G" + sysport: "225" + type: "eth" + - fec: "KPFEC" + id: "217" + lanes: "0:4" + serdes_group: "27" + speed: "200G" + sysport: "217" + type: "eth" + - fec: "KPFEC" + id: "209" + lanes: "0:4" + serdes_group: "26" + speed: "200G" + sysport: "209" + type: "eth" + - fec: "KPFEC" + id: "201" + lanes: "0:4" + serdes_group: "25" + speed: "200G" + sysport: "201" + type: "eth" + - fec: "KPFEC" + id: "193" + lanes: "0:4" + serdes_group: "24" + speed: "200G" + sysport: "193" + type: "eth" + - fec: "KPFEC" + id: "185" + lanes: "0:4" + serdes_group: "23" + speed: "200G" + sysport: "185" + type: "eth" + - fec: "KPFEC" + id: "177" + lanes: "0:4" + serdes_group: "22" + speed: "200G" + sysport: "177" + type: "eth" + - fec: "KPFEC" + id: "169" + lanes: "0:4" + serdes_group: "21" + speed: "200G" + sysport: "169" + type: "eth" + - fec: "KPFEC" + id: "161" + lanes: "0:4" + serdes_group: "20" + speed: "200G" + sysport: "161" + type: "eth" + - fec: "KPFEC" + id: "153" + lanes: "0:4" + serdes_group: "19" + speed: "200G" + sysport: "153" + type: "eth" + - fec: "KPFEC" + id: "145" + lanes: "0:4" + serdes_group: "18" + speed: "200G" + sysport: "145" + type: "eth" + - fec: "KPFEC" + id: "137" + lanes: "0:4" + serdes_group: "17" + speed: "200G" + sysport: "137" + type: "eth" + - fec: "KPFEC" + id: "129" + lanes: "0:4" + serdes_group: "16" + speed: "200G" + sysport: "129" + type: "eth" + - fec: "KPFEC" + id: "121" + lanes: "0:4" + serdes_group: "15" + speed: "200G" + sysport: "121" + type: "eth" + - fec: "KPFEC" + id: "113" + lanes: "0:4" + serdes_group: "14" + speed: "200G" + sysport: "113" + type: "eth" + - fec: "KPFEC" + id: "97" + lanes: "0:4" + serdes_group: "12" + speed: "200G" + sysport: "97" + type: "eth" + - fec: "KPFEC" + id: "105" + lanes: "0:4" + serdes_group: "13" + speed: "200G" + sysport: "105" + type: "eth" + - fec: "KPFEC" + id: "81" + lanes: "0:4" + serdes_group: "10" + speed: "200G" + sysport: "81" + type: "eth" + - fec: "KPFEC" + id: "89" + lanes: "0:4" + serdes_group: "11" + speed: "200G" + sysport: "89" + type: "eth" + - fec: "KPFEC" + id: "65" + lanes: "0:4" + serdes_group: "8" + speed: "200G" + sysport: "65" + type: "eth" + - fec: "KPFEC" + id: "73" + lanes: "0:4" + serdes_group: "9" + speed: "200G" + sysport: "73" + type: "eth" + - fec: "KPFEC" + id: "49" + lanes: "0:4" + serdes_group: "6" + speed: "200G" + sysport: "49" + type: "eth" + - fec: "KPFEC" + id: "57" + lanes: "0:4" + serdes_group: "7" + speed: "200G" + sysport: "57" + type: "eth" + - fec: "KPFEC" + id: "33" + lanes: "0:4" + serdes_group: "4" + speed: "200G" + sysport: "33" + type: "eth" + - fec: "KPFEC" + id: "41" + lanes: "0:4" + serdes_group: "5" + speed: "200G" + sysport: "41" + type: "eth" + - fec: "KPFEC" + id: "17" + lanes: "0:4" + serdes_group: "2" + speed: "200G" + sysport: "17" + type: "eth" + - fec: "KPFEC" + id: "25" + lanes: "0:4" + serdes_group: "3" + speed: "200G" + sysport: "25" + type: "eth" + - fec: "KPFEC" + id: "1" + lanes: "0:4" + serdes_group: "0" + speed: "200G" + sysport: "1" + type: "eth" + - fec: "KPFEC" + id: "9" + lanes: "0:4" + serdes_group: "1" + speed: "200G" + sysport: "9" + type: "eth" + - fec: "NONE" + id: "257" + lanes: "0:1" + serdes_group: "32" + speed: "10G" + sysport: "257" + type: "mgmt 0" + - fec: "NONE" + id: "258" + lanes: "1:1" + serdes_group: "32" + speed: "10G" + sysport: "258" + type: "mgmt 1" + isg: + - id: "0" + tx_polarity: "01010101" + rx_polarity: "01100000" + lane_swap: "23641075" + - id: "1" + tx_polarity: "10110000" + rx_polarity: "11111111" + lane_swap: "64317520" + - id: "2" + tx_polarity: "00000000" + rx_polarity: "00000011" + lane_swap: "63147520" + - id: "3" + tx_polarity: "01101000" + rx_polarity: "00001110" + lane_swap: "31572046" + - id: "4" + tx_polarity: "00111000" + rx_polarity: "00001000" + lane_swap: "46105732" + - id: "5" + tx_polarity: "10111111" + rx_polarity: "11101000" + lane_swap: "27153604" + - id: "6" + tx_polarity: "01101110" + rx_polarity: "00001101" + lane_swap: "46503721" + - id: "7" + tx_polarity: "01000100" + rx_polarity: "10000101" + lane_swap: "03671245" + - id: "8" + tx_polarity: "01110101" + rx_polarity: "00010000" + lane_swap: "12640375" + - id: "9" + tx_polarity: "01011100" + rx_polarity: "11001111" + lane_swap: "02561347" + - id: "10" + tx_polarity: "01110110" + rx_polarity: "11000000" + lane_swap: "12740365" + - id: "11" + tx_polarity: "00111000" + rx_polarity: "00010111" + lane_swap: "01572436" + - id: "12" + tx_polarity: "00001111" + rx_polarity: "10111001" + lane_swap: "54320176" + - id: "13" + tx_polarity: "10011101" + rx_polarity: "00111011" + lane_swap: "26153704" + - id: "14" + tx_polarity: "00110000" + rx_polarity: "11010000" + lane_swap: "37452601" + - id: "15" + tx_polarity: "11100010" + rx_polarity: "01110011" + lane_swap: "51370462" + - id: "16" + tx_polarity: "10111010" + rx_polarity: "11010011" + lane_swap: "36152704" + - id: "17" + tx_polarity: "01011101" + rx_polarity: "00110001" + lane_swap: "45621073" + - id: "18" + tx_polarity: "11011111" + rx_polarity: "11001011" + lane_swap: "26143705" + - id: "19" + tx_polarity: "00100110" + rx_polarity: "00001001" + lane_swap: "42730165" + - id: "20" + tx_polarity: "10011011" + rx_polarity: "01101101" + lane_swap: "54217603" + - id: "21" + tx_polarity: "00101110" + rx_polarity: "10111111" + lane_swap: "26031745" + - id: "22" + tx_polarity: "01001110" + rx_polarity: "00111001" + lane_swap: "36024715" + - id: "23" + tx_polarity: "10101101" + rx_polarity: "01010011" + lane_swap: "45621370" + - id: "24" + tx_polarity: "11001110" + rx_polarity: "00011111" + lane_swap: "65234701" + - id: "25" + tx_polarity: "01110001" + rx_polarity: "01010111" + lane_swap: "37601452" + - id: "26" + tx_polarity: "01000100" + rx_polarity: "00001111" + lane_swap: "65034721" + - id: "27" + tx_polarity: "10111101" + rx_polarity: "11000101" + lane_swap: "34501672" + - id: "28" + tx_polarity: "01111000" + rx_polarity: "01110110" + lane_swap: "43061275" + - id: "29" + tx_polarity: "11110111" + rx_polarity: "11100111" + lane_swap: "57304621" + - id: "30" + tx_polarity: "10000100" + rx_polarity: "00101111" + lane_swap: "47125603" + - id: "31" + tx_polarity: "11111111" + rx_polarity: "11100010" + lane_swap: "13460275" + - id: "32" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x200/inno.config.yaml b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x200/inno.config.yaml new file mode 100755 index 000000000000..9bc0114cf69b --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x200/inno.config.yaml @@ -0,0 +1,7 @@ +IFCS_INIT_FILE : "/usr/share/sonic/hwsku/config_32x200G_Delta-et-c032if.yaml" +IFCS_SKU_FILE : "/usr/share/sonic/hwsku/innovium.77700_B" +IFCS_INNO_CLI_PORT : "9999" +IFCS_TARGET : "device" +ULIMIT : "65536" +INNOVIUM_DIR : "/innovium" +PYTHONPATH : "$INNOVIUM_DIR:$INNOVIUM_DIR/cmds:$INNOVIUM_DIR/scripts:$INNOVIUM_DIR/test/:$INNOVIUM_DIR/test/utils:$INNOVIUM_DIR/utils:$INNOVIUM_DIR/pyctypes" diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x200/innovium.77700_B b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x200/innovium.77700_B new file mode 100644 index 000000000000..27297b313959 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x200/innovium.77700_B @@ -0,0 +1,59 @@ +sku: innovium.77700_B + +device_id: 0x1b58 + +# Hardware constraint information +hardware: + num_ibs: 6 + + ports_per_ib: 32, 32, 32, 32, 20, 20 + recirc_port_num: 32, 32, 32, 32, 32, 32 + cpu_port_num: 33 + cpu_port_ib: 0 + mgmt_port_num: 33 + mgmt_port_ibs: 1,2 + + pics_per_ib: 6, 7, 7, 6, 5, 5 + pic_ports_per_pic: 8 + max_serdes_speed: 50 + + num_shared_pics: 2 + + isg [0-4]: + ib: 0 + pic_id: [0-4] + + isg [5-9]: + ib: 5 + pic_id: [0-4] + + isg [10-14]: + ib: 1 + pic_id: [0-4] + + isg [16-20]: + ib: 3 + pic_id: [0-4] + + isg [21-25]: + ib: 4 + pic_id: [0-4] + + isg [26-30]: + ib: 2 + pic_id: [0-4] + + isg 15: + mode: 4:4 + ib: 1, 3 + pic_id: 5 + + isg 31: + mode: 4:4 + ib: 0, 2 + pic_id: 5 + + isg 32: + mode: 1:1 + ib: 1, 2 + pic_id: 6 diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x200/port_config.ini b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x200/port_config.ini new file mode 100755 index 000000000000..48091f5e3674 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x200/port_config.ini @@ -0,0 +1,35 @@ +# name lanes speed index mtu fec +Ethernet0 249,250,251,252 200000 0 9126 rs +Ethernet8 241,242,243,244 200000 1 9126 rs +Ethernet16 233,234,235,236 200000 2 9126 rs +Ethernet24 225,226,227,228 200000 3 9126 rs +Ethernet32 217,218,219,220 200000 4 9126 rs +Ethernet40 209,210,211,212 200000 5 9126 rs +Ethernet48 201,202,203,204 200000 6 9126 rs +Ethernet56 193,194,195,196 200000 7 9126 rs +Ethernet64 185,186,187,188 200000 8 9126 rs +Ethernet72 177,178,179,180 200000 9 9126 rs +Ethernet80 169,170,171,172 200000 10 9126 rs +Ethernet88 161,162,163,164 200000 11 9126 rs +Ethernet96 153,154,155,156 200000 12 9126 rs +Ethernet104 145,146,147,148 200000 13 9126 rs +Ethernet112 137,138,139,140 200000 14 9126 rs +Ethernet120 129,130,131,132 200000 15 9126 rs +Ethernet128 121,122,123,124 200000 16 9126 rs +Ethernet136 113,114,115,116 200000 17 9126 rs +Ethernet144 97,98,99,100 200000 18 9126 rs +Ethernet152 105,106,107,108 200000 19 9126 rs +Ethernet160 81,82,83,84 200000 20 9126 rs +Ethernet168 89,90,91,92 200000 21 9126 rs +Ethernet176 65,66,67,68 200000 22 9126 rs +Ethernet184 73,74,75,76 200000 23 9126 rs +Ethernet192 49,50,51,52 200000 24 9126 rs +Ethernet200 57,58,59,60 200000 25 9126 rs +Ethernet208 33,34,35,36 200000 26 9126 rs +Ethernet216 41,42,43,44 200000 27 9126 rs +Ethernet224 17,18,19,20 200000 28 9126 rs +Ethernet232 25,26,27,28 200000 29 9126 rs +Ethernet240 1,2,3,4 200000 30 9126 rs +Ethernet248 9,10,11,12 200000 31 9126 rs +Ethernet256 257 10000 32 9126 none +Ethernet257 258 10000 33 9126 none diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x200/qos.json.j2 b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x200/qos.json.j2 new file mode 100755 index 000000000000..6c734d46ff2f --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x200/qos.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} + +{% set default_ports_num = 32 -%} +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "1":"1", + "0":"0", + "3":"3", + "2":"2", + "5":"5", + "4":"4", + "7":"7", + "6":"6" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "1": "0", + "0": "0", + "3": "0", + "2": "0", + "4": "1", + "5": "2", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"0", + "4":"4", + "5":"5", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "4,5" + } + } +} diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x200/sai.profile b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x200/sai.profile new file mode 100755 index 000000000000..0769b3063a12 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x200/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/inno.config.yaml diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/buffers.json.j2 b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/buffers.json.j2 new file mode 100644 index 000000000000..4fca9cbcd156 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/buffers.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '300m' %} +{% set default_ports_num = 32 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "47218432", + "type": "ingress", + "mode": "dynamic", + "xoff": "17708800" + }, + "egress_lossy_pool": { + "size": "18874368", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"1433600", + "size":"1518", + "dynamic_th":"-4", + "xon_offset":"6272" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/config_32x400G_Delta-et-c032if.yaml b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/config_32x400G_Delta-et-c032if.yaml new file mode 100755 index 000000000000..2ba23d2a5a67 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/config_32x400G_Delta-et-c032if.yaml @@ -0,0 +1,429 @@ +ifcs: + options: + log_level: "info" +nodes: +- node_id: "0" + options: + sku: "configs/sku/innovium.77700_A" + netdev: + - auto_create: "no" + multi_interface: "yes" + buffer_management_mode: "api_driven" + max_lossless_tc: "2" + txring: + - txring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + rxring: + - rxring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44" + - rxring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45" + - rxring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46" + - rxring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47" + sys_clk: "1720" + ifc_clk: "1200" + mac_clk: "1340" + + devports: + - id: "0" + sysport: "1000" + type: "cpu" + - fec: "KPFEC" + id: "249" + lanes: "0:8" + serdes_group: "31" + speed: "400G" + sysport: "249" + type: "eth" + - fec: "KPFEC" + id: "241" + lanes: "0:8" + serdes_group: "30" + speed: "400G" + sysport: "241" + type: "eth" + - fec: "KPFEC" + id: "233" + lanes: "0:8" + serdes_group: "29" + speed: "400G" + sysport: "233" + type: "eth" + - fec: "KPFEC" + id: "225" + lanes: "0:8" + serdes_group: "28" + speed: "400G" + sysport: "225" + type: "eth" + - fec: "KPFEC" + id: "217" + lanes: "0:8" + serdes_group: "27" + speed: "400G" + sysport: "217" + type: "eth" + - fec: "KPFEC" + id: "209" + lanes: "0:8" + serdes_group: "26" + speed: "400G" + sysport: "209" + type: "eth" + - fec: "KPFEC" + id: "201" + lanes: "0:8" + serdes_group: "25" + speed: "400G" + sysport: "201" + type: "eth" + - fec: "KPFEC" + id: "193" + lanes: "0:8" + serdes_group: "24" + speed: "400G" + sysport: "193" + type: "eth" + - fec: "KPFEC" + id: "185" + lanes: "0:8" + serdes_group: "23" + speed: "400G" + sysport: "185" + type: "eth" + - fec: "KPFEC" + id: "177" + lanes: "0:8" + serdes_group: "22" + speed: "400G" + sysport: "177" + type: "eth" + - fec: "KPFEC" + id: "169" + lanes: "0:8" + serdes_group: "21" + speed: "400G" + sysport: "169" + type: "eth" + - fec: "KPFEC" + id: "161" + lanes: "0:8" + serdes_group: "20" + speed: "400G" + sysport: "161" + type: "eth" + - fec: "KPFEC" + id: "153" + lanes: "0:8" + serdes_group: "19" + speed: "400G" + sysport: "153" + type: "eth" + - fec: "KPFEC" + id: "145" + lanes: "0:8" + serdes_group: "18" + speed: "400G" + sysport: "145" + type: "eth" + - fec: "KPFEC" + id: "137" + lanes: "0:8" + serdes_group: "17" + speed: "400G" + sysport: "137" + type: "eth" + - fec: "KPFEC" + id: "129" + lanes: "0:8" + serdes_group: "16" + speed: "400G" + sysport: "129" + type: "eth" + - fec: "KPFEC" + id: "121" + lanes: "0:8" + serdes_group: "15" + speed: "400G" + sysport: "121" + type: "eth" + - fec: "KPFEC" + id: "113" + lanes: "0:8" + serdes_group: "14" + speed: "400G" + sysport: "113" + type: "eth" + - fec: "KPFEC" + id: "97" + lanes: "0:8" + serdes_group: "12" + speed: "400G" + sysport: "97" + type: "eth" + - fec: "KPFEC" + id: "105" + lanes: "0:8" + serdes_group: "13" + speed: "400G" + sysport: "105" + type: "eth" + - fec: "KPFEC" + id: "81" + lanes: "0:8" + serdes_group: "10" + speed: "400G" + sysport: "81" + type: "eth" + - fec: "KPFEC" + id: "89" + lanes: "0:8" + serdes_group: "11" + speed: "400G" + sysport: "89" + type: "eth" + - fec: "KPFEC" + id: "65" + lanes: "0:8" + serdes_group: "8" + speed: "400G" + sysport: "65" + type: "eth" + - fec: "KPFEC" + id: "73" + lanes: "0:8" + serdes_group: "9" + speed: "400G" + sysport: "73" + type: "eth" + - fec: "KPFEC" + id: "49" + lanes: "0:8" + serdes_group: "6" + speed: "400G" + sysport: "49" + type: "eth" + - fec: "KPFEC" + id: "57" + lanes: "0:8" + serdes_group: "7" + speed: "400G" + sysport: "57" + type: "eth" + - fec: "KPFEC" + id: "33" + lanes: "0:8" + serdes_group: "4" + speed: "400G" + sysport: "33" + type: "eth" + - fec: "KPFEC" + id: "41" + lanes: "0:8" + serdes_group: "5" + speed: "400G" + sysport: "41" + type: "eth" + - fec: "KPFEC" + id: "17" + lanes: "0:8" + serdes_group: "2" + speed: "400G" + sysport: "17" + type: "eth" + - fec: "KPFEC" + id: "25" + lanes: "0:8" + serdes_group: "3" + speed: "400G" + sysport: "25" + type: "eth" + - fec: "KPFEC" + id: "1" + lanes: "0:8" + serdes_group: "0" + speed: "400G" + sysport: "1" + type: "eth" + - fec: "KPFEC" + id: "9" + lanes: "0:8" + serdes_group: "1" + speed: "400G" + sysport: "9" + type: "eth" + - fec: "NONE" + id: "257" + lanes: "0:1" + serdes_group: "32" + speed: "10G" + sysport: "257" + type: "mgmt 0" + - fec: "NONE" + id: "258" + lanes: "1:1" + serdes_group: "32" + speed: "10G" + sysport: "258" + type: "mgmt 1" + isg: + - id: "0" + tx_polarity: "01010101" + rx_polarity: "01100000" + lane_swap: "23641075" + - id: "1" + tx_polarity: "10110000" + rx_polarity: "11111111" + lane_swap: "64317520" + - id: "2" + tx_polarity: "00000000" + rx_polarity: "00000011" + lane_swap: "63147520" + - id: "3" + tx_polarity: "01101000" + rx_polarity: "00001110" + lane_swap: "31572046" + - id: "4" + tx_polarity: "00111000" + rx_polarity: "00001000" + lane_swap: "46105732" + - id: "5" + tx_polarity: "10111111" + rx_polarity: "11101000" + lane_swap: "27153604" + - id: "6" + tx_polarity: "01101110" + rx_polarity: "00001101" + lane_swap: "46503721" + - id: "7" + tx_polarity: "01000100" + rx_polarity: "10000101" + lane_swap: "03671245" + - id: "8" + tx_polarity: "01110101" + rx_polarity: "00010000" + lane_swap: "12640375" + - id: "9" + tx_polarity: "01011100" + rx_polarity: "11001111" + lane_swap: "02561347" + - id: "10" + tx_polarity: "01110110" + rx_polarity: "11000000" + lane_swap: "12740365" + - id: "11" + tx_polarity: "00111000" + rx_polarity: "00010111" + lane_swap: "01572436" + - id: "12" + tx_polarity: "00001111" + rx_polarity: "10111001" + lane_swap: "54320176" + - id: "13" + tx_polarity: "10011101" + rx_polarity: "00111011" + lane_swap: "26153704" + - id: "14" + tx_polarity: "00110000" + rx_polarity: "11010000" + lane_swap: "37452601" + - id: "15" + tx_polarity: "11100010" + rx_polarity: "01110011" + lane_swap: "51370462" + - id: "16" + tx_polarity: "10111010" + rx_polarity: "11010011" + lane_swap: "36152704" + - id: "17" + tx_polarity: "01011101" + rx_polarity: "00110001" + lane_swap: "45621073" + - id: "18" + tx_polarity: "11011111" + rx_polarity: "11001011" + lane_swap: "26143705" + - id: "19" + tx_polarity: "00100110" + rx_polarity: "00001001" + lane_swap: "42730165" + - id: "20" + tx_polarity: "10011011" + rx_polarity: "01101101" + lane_swap: "54217603" + - id: "21" + tx_polarity: "00101110" + rx_polarity: "10111111" + lane_swap: "26031745" + - id: "22" + tx_polarity: "01001110" + rx_polarity: "00111001" + lane_swap: "36024715" + - id: "23" + tx_polarity: "10101101" + rx_polarity: "01010011" + lane_swap: "45621370" + - id: "24" + tx_polarity: "11001110" + rx_polarity: "00011111" + lane_swap: "65234701" + - id: "25" + tx_polarity: "01110001" + rx_polarity: "01010111" + lane_swap: "37601452" + - id: "26" + tx_polarity: "01000100" + rx_polarity: "00001111" + lane_swap: "65034721" + - id: "27" + tx_polarity: "10111101" + rx_polarity: "11000101" + lane_swap: "34501672" + - id: "28" + tx_polarity: "01111000" + rx_polarity: "01110110" + lane_swap: "43061275" + - id: "29" + tx_polarity: "11110111" + rx_polarity: "11100111" + lane_swap: "57304621" + - id: "30" + tx_polarity: "10000100" + rx_polarity: "00101111" + lane_swap: "47125603" + - id: "31" + tx_polarity: "11111111" + rx_polarity: "11100010" + lane_swap: "13460275" + - id: "32" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/inno.config.yaml b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/inno.config.yaml new file mode 100755 index 000000000000..360b5af8e602 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/inno.config.yaml @@ -0,0 +1,7 @@ +IFCS_INIT_FILE : "/usr/share/sonic/hwsku/config_32x400G_Delta-et-c032if.yaml" +IFCS_SKU_FILE : "/usr/share/sonic/hwsku/innovium.77700_A" +IFCS_INNO_CLI_PORT : "9999" +IFCS_TARGET : "device" +ULIMIT : "65536" +INNOVIUM_DIR : "/innovium" +PYTHONPATH : "$INNOVIUM_DIR:$INNOVIUM_DIR/cmds:$INNOVIUM_DIR/scripts:$INNOVIUM_DIR/test/:$INNOVIUM_DIR/test/utils:$INNOVIUM_DIR/utils:$INNOVIUM_DIR/pyctypes" diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/innovium.77700_A b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/innovium.77700_A new file mode 100644 index 000000000000..84aa41983606 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/innovium.77700_A @@ -0,0 +1,59 @@ +sku: innovium.77700_A + +device_id: 0x1b58 + +# Hardware constraint information +hardware: + num_ibs: 6 + + ports_per_ib: 32, 32, 32, 32, 20, 20 + recirc_port_num: 32, 32, 32, 32, 32, 32 + cpu_port_num: 33 + cpu_port_ib: 0 + mgmt_port_num: 33 + mgmt_port_ibs: 1,2 + + pics_per_ib: 6, 7, 6, 5, 5, 5 + pic_ports_per_pic: 8 + max_serdes_speed: 50 + + num_shared_pics: 2 + + isg [0-4]: + ib: 0 + pic_id: [0-4] + + isg [5-9]: + ib: 5 + pic_id: [0-4] + + isg [10-14]: + ib: 1 + pic_id: [0-4] + + isg [16-20]: + ib: 3 + pic_id: [0-4] + + isg [21-25]: + ib: 4 + pic_id: [0-4] + + isg [26-30]: + ib: 2 + pic_id: [0-4] + + isg 15: + mode: 8:0 + ib: 1 + pic_id: 5 + + isg 31: + mode: 8:0 + ib: 0 + pic_id: 5 + + isg 32: + mode: 1:1 + ib: 1, 2 + pic_id: 6 diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/innovium.77700_B b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/innovium.77700_B new file mode 100644 index 000000000000..27297b313959 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/innovium.77700_B @@ -0,0 +1,59 @@ +sku: innovium.77700_B + +device_id: 0x1b58 + +# Hardware constraint information +hardware: + num_ibs: 6 + + ports_per_ib: 32, 32, 32, 32, 20, 20 + recirc_port_num: 32, 32, 32, 32, 32, 32 + cpu_port_num: 33 + cpu_port_ib: 0 + mgmt_port_num: 33 + mgmt_port_ibs: 1,2 + + pics_per_ib: 6, 7, 7, 6, 5, 5 + pic_ports_per_pic: 8 + max_serdes_speed: 50 + + num_shared_pics: 2 + + isg [0-4]: + ib: 0 + pic_id: [0-4] + + isg [5-9]: + ib: 5 + pic_id: [0-4] + + isg [10-14]: + ib: 1 + pic_id: [0-4] + + isg [16-20]: + ib: 3 + pic_id: [0-4] + + isg [21-25]: + ib: 4 + pic_id: [0-4] + + isg [26-30]: + ib: 2 + pic_id: [0-4] + + isg 15: + mode: 4:4 + ib: 1, 3 + pic_id: 5 + + isg 31: + mode: 4:4 + ib: 0, 2 + pic_id: 5 + + isg 32: + mode: 1:1 + ib: 1, 2 + pic_id: 6 diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/port_config.ini b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/port_config.ini new file mode 100755 index 000000000000..360e363f485b --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/port_config.ini @@ -0,0 +1,35 @@ +# name lanes speed index mtu fec +Ethernet0 249,250,251,252 400000 0 9126 rs +Ethernet8 241,242,243,244 400000 1 9126 rs +Ethernet16 233,234,235,236 400000 2 9126 rs +Ethernet24 225,226,227,228 400000 3 9126 rs +Ethernet32 217,218,219,220 400000 4 9126 rs +Ethernet40 209,210,211,212 400000 5 9126 rs +Ethernet48 201,202,203,204 400000 6 9126 rs +Ethernet56 193,194,195,196 400000 7 9126 rs +Ethernet64 185,186,187,188 400000 8 9126 rs +Ethernet72 177,178,179,180 400000 9 9126 rs +Ethernet80 169,170,171,172 400000 10 9126 rs +Ethernet88 161,162,163,164 400000 11 9126 rs +Ethernet96 153,154,155,156 400000 12 9126 rs +Ethernet104 145,146,147,148 400000 13 9126 rs +Ethernet112 137,138,139,140 400000 14 9126 rs +Ethernet120 129,130,131,132 400000 15 9126 rs +Ethernet128 121,122,123,124 400000 16 9126 rs +Ethernet136 113,114,115,116 400000 17 9126 rs +Ethernet144 97,98,99,100 400000 18 9126 rs +Ethernet152 105,106,107,108 400000 19 9126 rs +Ethernet160 81,82,83,84 400000 20 9126 rs +Ethernet168 89,90,91,92 400000 21 9126 rs +Ethernet176 65,66,67,68 400000 22 9126 rs +Ethernet184 73,74,75,76 400000 23 9126 rs +Ethernet192 49,50,51,52 400000 24 9126 rs +Ethernet200 57,58,59,60 400000 25 9126 rs +Ethernet208 33,34,35,36 400000 26 9126 rs +Ethernet216 41,42,43,44 400000 27 9126 rs +Ethernet224 17,18,19,20 400000 28 9126 rs +Ethernet232 25,26,27,28 400000 29 9126 rs +Ethernet240 1,2,3,4 400000 30 9126 rs +Ethernet248 9,10,11,12 400000 31 9126 rs +Ethernet256 257 10000 32 9126 none +Ethernet257 258 10000 33 9126 none diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/qos.json.j2 b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/qos.json.j2 new file mode 100755 index 000000000000..6c734d46ff2f --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/qos.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} + +{% set default_ports_num = 32 -%} +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "1":"1", + "0":"0", + "3":"3", + "2":"2", + "5":"5", + "4":"4", + "7":"7", + "6":"6" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "1": "0", + "0": "0", + "3": "0", + "2": "0", + "4": "1", + "5": "2", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"0", + "4":"4", + "5":"5", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "4,5" + } + } +} diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/sai.profile b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/sai.profile new file mode 100755 index 000000000000..0769b3063a12 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_32x400/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/inno.config.yaml diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x100/buffers.json.j2 b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x100/buffers.json.j2 new file mode 100644 index 000000000000..45cebf3b7144 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x100/buffers.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '300m' %} +{% set default_ports_num = 64 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "47218432", + "type": "ingress", + "mode": "dynamic", + "xoff": "17708800" + }, + "egress_lossy_pool": { + "size": "18874368", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"1433600", + "size":"1518", + "dynamic_th":"-4", + "xon_offset":"6272" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x100/config_64x100G_Delta-et-c032if.yaml b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x100/config_64x100G_Delta-et-c032if.yaml new file mode 100755 index 000000000000..e5fbcc93543d --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x100/config_64x100G_Delta-et-c032if.yaml @@ -0,0 +1,653 @@ +ifcs: + options: + log_level: "info" +nodes: +- node_id: "0" + options: + sku: "configs/sku/innovium.77700_B" + netdev: + - auto_create: "no" + multi_interface: "yes" + buffer_management_mode: "api_driven" + max_lossless_tc: "2" + txring: + - txring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + rxring: + - rxring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44" + - rxring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45" + - rxring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46" + - rxring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47" + sys_clk: "1720" + ifc_clk: "1200" + mac_clk: "1340" + + devports: + - id: "0" + sysport: "1000" + type: "cpu" + - fec: "KRFEC" + id: "249" + lanes: "0:4" + serdes_group: "31" + speed: "100G" + sysport: "249" + type: "eth" + - fec: "KRFEC" + id: "253" + lanes: "4:4" + serdes_group: "31" + speed: "100G" + sysport: "253" + type: "eth" + - fec: "KRFEC" + id: "241" + lanes: "0:4" + serdes_group: "30" + speed: "100G" + sysport: "241" + type: "eth" + - fec: "KRFEC" + id: "245" + lanes: "4:4" + serdes_group: "30" + speed: "100G" + sysport: "245" + type: "eth" + - fec: "KRFEC" + id: "233" + lanes: "0:4" + serdes_group: "29" + speed: "100G" + sysport: "233" + type: "eth" + - fec: "KRFEC" + id: "237" + lanes: "4:4" + serdes_group: "29" + speed: "100G" + sysport: "237" + type: "eth" + - fec: "KRFEC" + id: "225" + lanes: "0:4" + serdes_group: "28" + speed: "100G" + sysport: "225" + type: "eth" + - fec: "KRFEC" + id: "229" + lanes: "4:4" + serdes_group: "28" + speed: "100G" + sysport: "229" + type: "eth" + - fec: "KRFEC" + id: "217" + lanes: "0:4" + serdes_group: "27" + speed: "100G" + sysport: "217" + type: "eth" + - fec: "KRFEC" + id: "221" + lanes: "4:4" + serdes_group: "27" + speed: "100G" + sysport: "221" + type: "eth" + - fec: "KRFEC" + id: "209" + lanes: "0:4" + serdes_group: "26" + speed: "100G" + sysport: "209" + type: "eth" + - fec: "KRFEC" + id: "213" + lanes: "4:4" + serdes_group: "26" + speed: "100G" + sysport: "213" + type: "eth" + - fec: "KRFEC" + id: "201" + lanes: "0:4" + serdes_group: "25" + speed: "100G" + sysport: "201" + type: "eth" + - fec: "KRFEC" + id: "205" + lanes: "4:4" + serdes_group: "25" + speed: "100G" + sysport: "205" + type: "eth" + - fec: "KRFEC" + id: "193" + lanes: "0:4" + serdes_group: "24" + speed: "100G" + sysport: "193" + type: "eth" + - fec: "KRFEC" + id: "197" + lanes: "4:4" + serdes_group: "24" + speed: "100G" + sysport: "197" + type: "eth" + - fec: "KRFEC" + id: "185" + lanes: "0:4" + serdes_group: "23" + speed: "100G" + sysport: "185" + type: "eth" + - fec: "KRFEC" + id: "189" + lanes: "4:4" + serdes_group: "23" + speed: "100G" + sysport: "189" + type: "eth" + - fec: "KRFEC" + id: "177" + lanes: "0:4" + serdes_group: "22" + speed: "100G" + sysport: "177" + type: "eth" + - fec: "KRFEC" + id: "181" + lanes: "4:4" + serdes_group: "22" + speed: "100G" + sysport: "181" + type: "eth" + - fec: "KRFEC" + id: "169" + lanes: "0:4" + serdes_group: "21" + speed: "100G" + sysport: "169" + type: "eth" + - fec: "KRFEC" + id: "173" + lanes: "4:4" + serdes_group: "21" + speed: "100G" + sysport: "173" + type: "eth" + - fec: "KRFEC" + id: "161" + lanes: "0:4" + serdes_group: "20" + speed: "100G" + sysport: "161" + type: "eth" + - fec: "KRFEC" + id: "165" + lanes: "4:4" + serdes_group: "20" + speed: "100G" + sysport: "165" + type: "eth" + - fec: "KRFEC" + id: "153" + lanes: "0:4" + serdes_group: "19" + speed: "100G" + sysport: "153" + type: "eth" + - fec: "KRFEC" + id: "157" + lanes: "4:4" + serdes_group: "19" + speed: "100G" + sysport: "157" + type: "eth" + - fec: "KRFEC" + id: "145" + lanes: "0:4" + serdes_group: "18" + speed: "100G" + sysport: "145" + type: "eth" + - fec: "KRFEC" + id: "149" + lanes: "4:4" + serdes_group: "18" + speed: "100G" + sysport: "149" + type: "eth" + - fec: "KRFEC" + id: "137" + lanes: "0:4" + serdes_group: "17" + speed: "100G" + sysport: "137" + type: "eth" + - fec: "KRFEC" + id: "141" + lanes: "4:4" + serdes_group: "17" + speed: "100G" + sysport: "141" + type: "eth" + - fec: "KRFEC" + id: "129" + lanes: "0:4" + serdes_group: "16" + speed: "100G" + sysport: "129" + type: "eth" + - fec: "KRFEC" + id: "133" + lanes: "4:4" + serdes_group: "16" + speed: "100G" + sysport: "133" + type: "eth" + - fec: "KRFEC" + id: "121" + lanes: "0:4" + serdes_group: "15" + speed: "100G" + sysport: "121" + type: "eth" + - fec: "KRFEC" + id: "125" + lanes: "4:4" + serdes_group: "15" + speed: "100G" + sysport: "125" + type: "eth" + - fec: "KRFEC" + id: "113" + lanes: "0:4" + serdes_group: "14" + speed: "100G" + sysport: "113" + type: "eth" + - fec: "KRFEC" + id: "117" + lanes: "4:4" + serdes_group: "14" + speed: "100G" + sysport: "117" + type: "eth" + - fec: "KRFEC" + id: "97" + lanes: "0:4" + serdes_group: "12" + speed: "100G" + sysport: "97" + type: "eth" + - fec: "KRFEC" + id: "101" + lanes: "4:4" + serdes_group: "12" + speed: "100G" + sysport: "101" + type: "eth" + - fec: "KRFEC" + id: "105" + lanes: "0:4" + serdes_group: "13" + speed: "100G" + sysport: "105" + type: "eth" + - fec: "KRFEC" + id: "109" + lanes: "4:4" + serdes_group: "13" + speed: "100G" + sysport: "109" + type: "eth" + - fec: "KRFEC" + id: "81" + lanes: "0:4" + serdes_group: "10" + speed: "100G" + sysport: "81" + type: "eth" + - fec: "KRFEC" + id: "85" + lanes: "4:4" + serdes_group: "10" + speed: "100G" + sysport: "85" + type: "eth" + - fec: "KRFEC" + id: "89" + lanes: "0:4" + serdes_group: "11" + speed: "100G" + sysport: "89" + type: "eth" + - fec: "KRFEC" + id: "93" + lanes: "4:4" + serdes_group: "11" + speed: "100G" + sysport: "93" + type: "eth" + - fec: "KRFEC" + id: "65" + lanes: "0:4" + serdes_group: "8" + speed: "100G" + sysport: "65" + type: "eth" + - fec: "KRFEC" + id: "69" + lanes: "4:4" + serdes_group: "8" + speed: "100G" + sysport: "69" + type: "eth" + - fec: "KRFEC" + id: "73" + lanes: "0:4" + serdes_group: "9" + speed: "100G" + sysport: "73" + type: "eth" + - fec: "KRFEC" + id: "77" + lanes: "4:4" + serdes_group: "9" + speed: "100G" + sysport: "77" + type: "eth" + - fec: "KRFEC" + id: "49" + lanes: "0:4" + serdes_group: "6" + speed: "100G" + sysport: "49" + type: "eth" + - fec: "KRFEC" + id: "53" + lanes: "4:4" + serdes_group: "6" + speed: "100G" + sysport: "53" + type: "eth" + - fec: "KRFEC" + id: "57" + lanes: "0:4" + serdes_group: "7" + speed: "100G" + sysport: "57" + type: "eth" + - fec: "KRFEC" + id: "61" + lanes: "4:4" + serdes_group: "7" + speed: "100G" + sysport: "61" + type: "eth" + - fec: "KRFEC" + id: "33" + lanes: "0:4" + serdes_group: "4" + speed: "100G" + sysport: "33" + type: "eth" + - fec: "KRFEC" + id: "37" + lanes: "4:4" + serdes_group: "4" + speed: "100G" + sysport: "37" + type: "eth" + - fec: "KRFEC" + id: "41" + lanes: "0:4" + serdes_group: "5" + speed: "100G" + sysport: "41" + type: "eth" + - fec: "KRFEC" + id: "45" + lanes: "4:4" + serdes_group: "5" + speed: "100G" + sysport: "45" + type: "eth" + - fec: "KRFEC" + id: "17" + lanes: "0:4" + serdes_group: "2" + speed: "100G" + sysport: "17" + type: "eth" + - fec: "KRFEC" + id: "21" + lanes: "4:4" + serdes_group: "2" + speed: "100G" + sysport: "21" + type: "eth" + - fec: "KRFEC" + id: "25" + lanes: "0:4" + serdes_group: "3" + speed: "100G" + sysport: "25" + type: "eth" + - fec: "KRFEC" + id: "29" + lanes: "4:4" + serdes_group: "3" + speed: "100G" + sysport: "29" + type: "eth" + - fec: "KRFEC" + id: "1" + lanes: "0:4" + serdes_group: "0" + speed: "100G" + sysport: "1" + type: "eth" + - fec: "KRFEC" + id: "5" + lanes: "4:4" + serdes_group: "0" + speed: "100G" + sysport: "5" + type: "eth" + - fec: "KRFEC" + id: "9" + lanes: "0:4" + serdes_group: "1" + speed: "100G" + sysport: "9" + type: "eth" + - fec: "KRFEC" + id: "13" + lanes: "4:4" + serdes_group: "1" + speed: "100G" + sysport: "13" + type: "eth" + - fec: "NONE" + id: "257" + lanes: "0:1" + serdes_group: "32" + speed: "10G" + sysport: "257" + type: "mgmt 0" + - fec: "NONE" + id: "258" + lanes: "1:1" + serdes_group: "32" + speed: "10G" + sysport: "258" + type: "mgmt 1" + isg: + - id: "0" + tx_polarity: "01010101" + rx_polarity: "01100000" + lane_swap: "23641075" + - id: "1" + tx_polarity: "10110000" + rx_polarity: "11111111" + lane_swap: "64317520" + - id: "2" + tx_polarity: "00000000" + rx_polarity: "00000011" + lane_swap: "63147520" + - id: "3" + tx_polarity: "01101000" + rx_polarity: "00001110" + lane_swap: "31572046" + - id: "4" + tx_polarity: "00111000" + rx_polarity: "00001000" + lane_swap: "46105732" + - id: "5" + tx_polarity: "10111111" + rx_polarity: "11101000" + lane_swap: "27153604" + - id: "6" + tx_polarity: "01101110" + rx_polarity: "00001101" + lane_swap: "46503721" + - id: "7" + tx_polarity: "01000100" + rx_polarity: "10000101" + lane_swap: "03671245" + - id: "8" + tx_polarity: "01110101" + rx_polarity: "00010000" + lane_swap: "12640375" + - id: "9" + tx_polarity: "01011100" + rx_polarity: "11001111" + lane_swap: "02561347" + - id: "10" + tx_polarity: "01110110" + rx_polarity: "11000000" + lane_swap: "12740365" + - id: "11" + tx_polarity: "00111000" + rx_polarity: "00010111" + lane_swap: "01572436" + - id: "12" + tx_polarity: "00001111" + rx_polarity: "10111001" + lane_swap: "54320176" + - id: "13" + tx_polarity: "10011101" + rx_polarity: "00111011" + lane_swap: "26153704" + - id: "14" + tx_polarity: "00110000" + rx_polarity: "11010000" + lane_swap: "37452601" + - id: "15" + tx_polarity: "11100010" + rx_polarity: "01110011" + lane_swap: "51370462" + - id: "16" + tx_polarity: "10111010" + rx_polarity: "11010011" + lane_swap: "36152704" + - id: "17" + tx_polarity: "01011101" + rx_polarity: "00110001" + lane_swap: "45621073" + - id: "18" + tx_polarity: "11011111" + rx_polarity: "11001011" + lane_swap: "26143705" + - id: "19" + tx_polarity: "00100110" + rx_polarity: "00001001" + lane_swap: "42730165" + - id: "20" + tx_polarity: "10011011" + rx_polarity: "01101101" + lane_swap: "54217603" + - id: "21" + tx_polarity: "00101110" + rx_polarity: "10111111" + lane_swap: "26031745" + - id: "22" + tx_polarity: "01001110" + rx_polarity: "00111001" + lane_swap: "36024715" + - id: "23" + tx_polarity: "10101101" + rx_polarity: "01010011" + lane_swap: "45621370" + - id: "24" + tx_polarity: "11001110" + rx_polarity: "00011111" + lane_swap: "65234701" + - id: "25" + tx_polarity: "01110001" + rx_polarity: "01010111" + lane_swap: "37601452" + - id: "26" + tx_polarity: "01000100" + rx_polarity: "00001111" + lane_swap: "65034721" + - id: "27" + tx_polarity: "10111101" + rx_polarity: "11000101" + lane_swap: "34501672" + - id: "28" + tx_polarity: "01111000" + rx_polarity: "01110110" + lane_swap: "43061275" + - id: "29" + tx_polarity: "11110111" + rx_polarity: "11100111" + lane_swap: "57304621" + - id: "30" + tx_polarity: "10000100" + rx_polarity: "00101111" + lane_swap: "47125603" + - id: "31" + tx_polarity: "11111111" + rx_polarity: "11100010" + lane_swap: "13460275" + - id: "32" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x100/inno.config.yaml b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x100/inno.config.yaml new file mode 100755 index 000000000000..d44c7bc0bc28 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x100/inno.config.yaml @@ -0,0 +1,7 @@ +IFCS_INIT_FILE : "/usr/share/sonic/hwsku/config_64x100G_Delta-et-c032if.yaml" +IFCS_SKU_FILE : "/usr/share/sonic/hwsku/innovium.77700_B" +IFCS_INNO_CLI_PORT : "9999" +IFCS_TARGET : "device" +ULIMIT : "65536" +INNOVIUM_DIR : "/innovium" +PYTHONPATH : "$INNOVIUM_DIR:$INNOVIUM_DIR/cmds:$INNOVIUM_DIR/scripts:$INNOVIUM_DIR/test/:$INNOVIUM_DIR/test/utils:$INNOVIUM_DIR/utils:$INNOVIUM_DIR/pyctypes" diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x100/innovium.77700_B b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x100/innovium.77700_B new file mode 100644 index 000000000000..27297b313959 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x100/innovium.77700_B @@ -0,0 +1,59 @@ +sku: innovium.77700_B + +device_id: 0x1b58 + +# Hardware constraint information +hardware: + num_ibs: 6 + + ports_per_ib: 32, 32, 32, 32, 20, 20 + recirc_port_num: 32, 32, 32, 32, 32, 32 + cpu_port_num: 33 + cpu_port_ib: 0 + mgmt_port_num: 33 + mgmt_port_ibs: 1,2 + + pics_per_ib: 6, 7, 7, 6, 5, 5 + pic_ports_per_pic: 8 + max_serdes_speed: 50 + + num_shared_pics: 2 + + isg [0-4]: + ib: 0 + pic_id: [0-4] + + isg [5-9]: + ib: 5 + pic_id: [0-4] + + isg [10-14]: + ib: 1 + pic_id: [0-4] + + isg [16-20]: + ib: 3 + pic_id: [0-4] + + isg [21-25]: + ib: 4 + pic_id: [0-4] + + isg [26-30]: + ib: 2 + pic_id: [0-4] + + isg 15: + mode: 4:4 + ib: 1, 3 + pic_id: 5 + + isg 31: + mode: 4:4 + ib: 0, 2 + pic_id: 5 + + isg 32: + mode: 1:1 + ib: 1, 2 + pic_id: 6 diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x100/port_config.ini b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x100/port_config.ini new file mode 100644 index 000000000000..9999a677da49 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x100/port_config.ini @@ -0,0 +1,67 @@ +# name lanes speed index mtu +Ethernet0 249,250,251,252 100000 0 9126 +Ethernet4 253,254,255,256 100000 0 9126 +Ethernet8 241,242,243,244 100000 1 9126 +Ethernet12 245,246,247,248 100000 1 9126 +Ethernet16 233,234,235,236 100000 2 9126 +Ethernet20 237,238,239,240 100000 2 9126 +Ethernet24 225,226,227,228 100000 3 9126 +Ethernet28 229,230,231,232 100000 3 9126 +Ethernet32 217,218,219,220 100000 4 9126 +Ethernet36 221,222,223,224 100000 4 9126 +Ethernet40 209,210,211,212 100000 5 9126 +Ethernet44 213,214,215,216 100000 5 9126 +Ethernet48 201,202,203,204 100000 6 9126 +Ethernet52 205,206,207,208 100000 6 9126 +Ethernet56 193,194,195,196 100000 7 9126 +Ethernet60 197,198,199,200 100000 7 9126 +Ethernet64 185,186,187,188 100000 8 9126 +Ethernet68 189,190,191,192 100000 8 9126 +Ethernet72 177,178,179,180 100000 9 9126 +Ethernet76 181,182,183,184 100000 9 9126 +Ethernet80 169,170,171,172 100000 10 9126 +Ethernet84 173,174,175,176 100000 10 9126 +Ethernet88 161,162,163,164 100000 11 9126 +Ethernet92 165,166,167,168 100000 11 9126 +Ethernet96 153,154,155,156 100000 12 9126 +Ethernet100 157,158,159,160 100000 12 9126 +Ethernet104 145,146,147,148 100000 13 9126 +Ethernet108 149,150,151,152 100000 13 9126 +Ethernet112 137,138,139,140 100000 14 9126 +Ethernet116 141,142,143,144 100000 14 9126 +Ethernet120 129,130,131,132 100000 15 9126 +Ethernet124 133,134,135,136 100000 15 9126 +Ethernet128 121,122,123,124 100000 16 9126 +Ethernet132 125,126,127,128 100000 16 9126 +Ethernet136 113,114,115,116 100000 17 9126 +Ethernet140 117,118,119,120 100000 17 9126 +Ethernet144 97,98,99,100 100000 18 9126 +Ethernet148 101,102,103,104 100000 18 9126 +Ethernet152 105,106,107,108 100000 19 9126 +Ethernet156 109,110,111,112 100000 19 9126 +Ethernet160 81,82,83,84 100000 20 9126 +Ethernet164 85,86,87,88 100000 20 9126 +Ethernet168 89,90,91,92 100000 21 9126 +Ethernet172 93,94,95,96 100000 21 9126 +Ethernet176 65,66,67,68 100000 22 9126 +Ethernet180 69,70,71,72 100000 22 9126 +Ethernet184 73,74,75,76 100000 23 9126 +Ethernet188 77,78,79,80 100000 23 9126 +Ethernet192 49,50,51,52 100000 24 9126 +Ethernet196 53,54,55,56 100000 24 9126 +Ethernet200 57,58,59,60 100000 25 9126 +Ethernet204 61,62,63,64 100000 25 9126 +Ethernet208 33,34,35,36 100000 26 9126 +Ethernet212 37,38,39,40 100000 26 9126 +Ethernet216 41,42,43,44 100000 27 9126 +Ethernet220 45,46,47,48 100000 27 9126 +Ethernet224 17,18,19,20 100000 28 9126 +Ethernet228 21,22,23,24 100000 28 9126 +Ethernet232 25,26,27,28 100000 29 9126 +Ethernet236 29,30,31,32 100000 29 9126 +Ethernet240 1,2,3,4 100000 30 9126 +Ethernet244 5,6,7,8 100000 30 9126 +Ethernet248 9,10,11,12 100000 31 9126 +Ethernet252 13,14,15,16 100000 31 9126 +Ethernet256 257 10000 32 9126 +Ethernet257 258 10000 33 9126 diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x100/qos.json.j2 b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x100/qos.json.j2 new file mode 100755 index 000000000000..16f9b42a2166 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x100/qos.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} + +{% set default_ports_num = 64 -%} +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "1":"1", + "0":"0", + "3":"3", + "2":"2", + "5":"5", + "4":"4", + "7":"7", + "6":"6" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "1": "0", + "0": "0", + "3": "0", + "2": "0", + "4": "1", + "5": "2", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"0", + "4":"4", + "5":"5", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "4,5" + } + } +} diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x100/sai.profile b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x100/sai.profile new file mode 100755 index 000000000000..0769b3063a12 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x100/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/inno.config.yaml diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x200/buffers.json.j2 b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x200/buffers.json.j2 new file mode 100644 index 000000000000..45cebf3b7144 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x200/buffers.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '300m' %} +{% set default_ports_num = 64 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "47218432", + "type": "ingress", + "mode": "dynamic", + "xoff": "17708800" + }, + "egress_lossy_pool": { + "size": "18874368", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"1433600", + "size":"1518", + "dynamic_th":"-4", + "xon_offset":"6272" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "static_th":"9721600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|4-5": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|0-3": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|6-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x200/config_64x200G_Delta-et-c032if.yaml b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x200/config_64x200G_Delta-et-c032if.yaml new file mode 100755 index 000000000000..4b75a205ab5c --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x200/config_64x200G_Delta-et-c032if.yaml @@ -0,0 +1,653 @@ +ifcs: + options: + log_level: "info" +nodes: +- node_id: "0" + options: + sku: "configs/sku/innovium.77700_B" + netdev: + - auto_create: "no" + multi_interface: "yes" + buffer_management_mode: "api_driven" + max_lossless_tc: "2" + txring: + - txring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + rxring: + - rxring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44" + - rxring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45" + - rxring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46" + - rxring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47" + sys_clk: "1720" + ifc_clk: "1200" + mac_clk: "1340" + + devports: + - id: "0" + sysport: "1000" + type: "cpu" + - fec: "KPFEC" + id: "249" + lanes: "0:4" + serdes_group: "31" + speed: "200G" + sysport: "249" + type: "eth" + - fec: "KPFEC" + id: "253" + lanes: "4:4" + serdes_group: "31" + speed: "200G" + sysport: "253" + type: "eth" + - fec: "KPFEC" + id: "241" + lanes: "0:4" + serdes_group: "30" + speed: "200G" + sysport: "241" + type: "eth" + - fec: "KPFEC" + id: "245" + lanes: "4:4" + serdes_group: "30" + speed: "200G" + sysport: "245" + type: "eth" + - fec: "KPFEC" + id: "233" + lanes: "0:4" + serdes_group: "29" + speed: "200G" + sysport: "233" + type: "eth" + - fec: "KPFEC" + id: "237" + lanes: "4:4" + serdes_group: "29" + speed: "200G" + sysport: "237" + type: "eth" + - fec: "KPFEC" + id: "225" + lanes: "0:4" + serdes_group: "28" + speed: "200G" + sysport: "225" + type: "eth" + - fec: "KPFEC" + id: "229" + lanes: "4:4" + serdes_group: "28" + speed: "200G" + sysport: "229" + type: "eth" + - fec: "KPFEC" + id: "217" + lanes: "0:4" + serdes_group: "27" + speed: "200G" + sysport: "217" + type: "eth" + - fec: "KPFEC" + id: "221" + lanes: "4:4" + serdes_group: "27" + speed: "200G" + sysport: "221" + type: "eth" + - fec: "KPFEC" + id: "209" + lanes: "0:4" + serdes_group: "26" + speed: "200G" + sysport: "209" + type: "eth" + - fec: "KPFEC" + id: "213" + lanes: "4:4" + serdes_group: "26" + speed: "200G" + sysport: "213" + type: "eth" + - fec: "KPFEC" + id: "201" + lanes: "0:4" + serdes_group: "25" + speed: "200G" + sysport: "201" + type: "eth" + - fec: "KPFEC" + id: "205" + lanes: "4:4" + serdes_group: "25" + speed: "200G" + sysport: "205" + type: "eth" + - fec: "KPFEC" + id: "193" + lanes: "0:4" + serdes_group: "24" + speed: "200G" + sysport: "193" + type: "eth" + - fec: "KPFEC" + id: "197" + lanes: "4:4" + serdes_group: "24" + speed: "200G" + sysport: "197" + type: "eth" + - fec: "KPFEC" + id: "185" + lanes: "0:4" + serdes_group: "23" + speed: "200G" + sysport: "185" + type: "eth" + - fec: "KPFEC" + id: "189" + lanes: "4:4" + serdes_group: "23" + speed: "200G" + sysport: "189" + type: "eth" + - fec: "KPFEC" + id: "177" + lanes: "0:4" + serdes_group: "22" + speed: "200G" + sysport: "177" + type: "eth" + - fec: "KPFEC" + id: "181" + lanes: "4:4" + serdes_group: "22" + speed: "200G" + sysport: "181" + type: "eth" + - fec: "KPFEC" + id: "169" + lanes: "0:4" + serdes_group: "21" + speed: "200G" + sysport: "169" + type: "eth" + - fec: "KPFEC" + id: "173" + lanes: "4:4" + serdes_group: "21" + speed: "200G" + sysport: "173" + type: "eth" + - fec: "KPFEC" + id: "161" + lanes: "0:4" + serdes_group: "20" + speed: "200G" + sysport: "161" + type: "eth" + - fec: "KPFEC" + id: "165" + lanes: "4:4" + serdes_group: "20" + speed: "200G" + sysport: "165" + type: "eth" + - fec: "KPFEC" + id: "153" + lanes: "0:4" + serdes_group: "19" + speed: "200G" + sysport: "153" + type: "eth" + - fec: "KPFEC" + id: "157" + lanes: "4:4" + serdes_group: "19" + speed: "200G" + sysport: "157" + type: "eth" + - fec: "KPFEC" + id: "145" + lanes: "0:4" + serdes_group: "18" + speed: "200G" + sysport: "145" + type: "eth" + - fec: "KPFEC" + id: "149" + lanes: "4:4" + serdes_group: "18" + speed: "200G" + sysport: "149" + type: "eth" + - fec: "KPFEC" + id: "137" + lanes: "0:4" + serdes_group: "17" + speed: "200G" + sysport: "137" + type: "eth" + - fec: "KPFEC" + id: "141" + lanes: "4:4" + serdes_group: "17" + speed: "200G" + sysport: "141" + type: "eth" + - fec: "KPFEC" + id: "129" + lanes: "0:4" + serdes_group: "16" + speed: "200G" + sysport: "129" + type: "eth" + - fec: "KPFEC" + id: "133" + lanes: "4:4" + serdes_group: "16" + speed: "200G" + sysport: "133" + type: "eth" + - fec: "KPFEC" + id: "121" + lanes: "0:4" + serdes_group: "15" + speed: "200G" + sysport: "121" + type: "eth" + - fec: "KPFEC" + id: "125" + lanes: "4:4" + serdes_group: "15" + speed: "200G" + sysport: "125" + type: "eth" + - fec: "KPFEC" + id: "113" + lanes: "0:4" + serdes_group: "14" + speed: "200G" + sysport: "113" + type: "eth" + - fec: "KPFEC" + id: "117" + lanes: "4:4" + serdes_group: "14" + speed: "200G" + sysport: "117" + type: "eth" + - fec: "KPFEC" + id: "97" + lanes: "0:4" + serdes_group: "12" + speed: "200G" + sysport: "97" + type: "eth" + - fec: "KPFEC" + id: "101" + lanes: "4:4" + serdes_group: "12" + speed: "200G" + sysport: "101" + type: "eth" + - fec: "KPFEC" + id: "105" + lanes: "0:4" + serdes_group: "13" + speed: "200G" + sysport: "105" + type: "eth" + - fec: "KPFEC" + id: "109" + lanes: "4:4" + serdes_group: "13" + speed: "200G" + sysport: "109" + type: "eth" + - fec: "KPFEC" + id: "81" + lanes: "0:4" + serdes_group: "10" + speed: "200G" + sysport: "81" + type: "eth" + - fec: "KPFEC" + id: "85" + lanes: "4:4" + serdes_group: "10" + speed: "200G" + sysport: "85" + type: "eth" + - fec: "KPFEC" + id: "89" + lanes: "0:4" + serdes_group: "11" + speed: "200G" + sysport: "89" + type: "eth" + - fec: "KPFEC" + id: "93" + lanes: "4:4" + serdes_group: "11" + speed: "200G" + sysport: "93" + type: "eth" + - fec: "KPFEC" + id: "65" + lanes: "0:4" + serdes_group: "8" + speed: "200G" + sysport: "65" + type: "eth" + - fec: "KPFEC" + id: "69" + lanes: "4:4" + serdes_group: "8" + speed: "200G" + sysport: "69" + type: "eth" + - fec: "KPFEC" + id: "73" + lanes: "0:4" + serdes_group: "9" + speed: "200G" + sysport: "73" + type: "eth" + - fec: "KPFEC" + id: "77" + lanes: "4:4" + serdes_group: "9" + speed: "200G" + sysport: "77" + type: "eth" + - fec: "KPFEC" + id: "49" + lanes: "0:4" + serdes_group: "6" + speed: "200G" + sysport: "49" + type: "eth" + - fec: "KPFEC" + id: "53" + lanes: "4:4" + serdes_group: "6" + speed: "200G" + sysport: "53" + type: "eth" + - fec: "KPFEC" + id: "57" + lanes: "0:4" + serdes_group: "7" + speed: "200G" + sysport: "57" + type: "eth" + - fec: "KPFEC" + id: "61" + lanes: "4:4" + serdes_group: "7" + speed: "200G" + sysport: "61" + type: "eth" + - fec: "KPFEC" + id: "33" + lanes: "0:4" + serdes_group: "4" + speed: "200G" + sysport: "33" + type: "eth" + - fec: "KPFEC" + id: "37" + lanes: "4:4" + serdes_group: "4" + speed: "200G" + sysport: "37" + type: "eth" + - fec: "KPFEC" + id: "41" + lanes: "0:4" + serdes_group: "5" + speed: "200G" + sysport: "41" + type: "eth" + - fec: "KPFEC" + id: "45" + lanes: "4:4" + serdes_group: "5" + speed: "200G" + sysport: "45" + type: "eth" + - fec: "KPFEC" + id: "17" + lanes: "0:4" + serdes_group: "2" + speed: "200G" + sysport: "17" + type: "eth" + - fec: "KPFEC" + id: "21" + lanes: "4:4" + serdes_group: "2" + speed: "200G" + sysport: "21" + type: "eth" + - fec: "KPFEC" + id: "25" + lanes: "0:4" + serdes_group: "3" + speed: "200G" + sysport: "25" + type: "eth" + - fec: "KPFEC" + id: "29" + lanes: "4:4" + serdes_group: "3" + speed: "200G" + sysport: "29" + type: "eth" + - fec: "KPFEC" + id: "1" + lanes: "0:4" + serdes_group: "0" + speed: "200G" + sysport: "1" + type: "eth" + - fec: "KPFEC" + id: "5" + lanes: "4:4" + serdes_group: "0" + speed: "200G" + sysport: "5" + type: "eth" + - fec: "KPFEC" + id: "9" + lanes: "0:4" + serdes_group: "1" + speed: "200G" + sysport: "9" + type: "eth" + - fec: "KPFEC" + id: "13" + lanes: "4:4" + serdes_group: "1" + speed: "200G" + sysport: "13" + type: "eth" + - fec: "NONE" + id: "257" + lanes: "0:1" + serdes_group: "32" + speed: "10G" + sysport: "257" + type: "mgmt 0" + - fec: "NONE" + id: "258" + lanes: "1:1" + serdes_group: "32" + speed: "10G" + sysport: "258" + type: "mgmt 1" + isg: + - id: "0" + tx_polarity: "01010101" + rx_polarity: "01100000" + lane_swap: "23641075" + - id: "1" + tx_polarity: "10110000" + rx_polarity: "11111111" + lane_swap: "64317520" + - id: "2" + tx_polarity: "00000000" + rx_polarity: "00000011" + lane_swap: "63147520" + - id: "3" + tx_polarity: "01101000" + rx_polarity: "00001110" + lane_swap: "31572046" + - id: "4" + tx_polarity: "00111000" + rx_polarity: "00001000" + lane_swap: "46105732" + - id: "5" + tx_polarity: "10111111" + rx_polarity: "11101000" + lane_swap: "27153604" + - id: "6" + tx_polarity: "01101110" + rx_polarity: "00001101" + lane_swap: "46503721" + - id: "7" + tx_polarity: "01000100" + rx_polarity: "10000101" + lane_swap: "03671245" + - id: "8" + tx_polarity: "01110101" + rx_polarity: "00010000" + lane_swap: "12640375" + - id: "9" + tx_polarity: "01011100" + rx_polarity: "11001111" + lane_swap: "02561347" + - id: "10" + tx_polarity: "01110110" + rx_polarity: "11000000" + lane_swap: "12740365" + - id: "11" + tx_polarity: "00111000" + rx_polarity: "00010111" + lane_swap: "01572436" + - id: "12" + tx_polarity: "00001111" + rx_polarity: "10111001" + lane_swap: "54320176" + - id: "13" + tx_polarity: "10011101" + rx_polarity: "00111011" + lane_swap: "26153704" + - id: "14" + tx_polarity: "00110000" + rx_polarity: "11010000" + lane_swap: "37452601" + - id: "15" + tx_polarity: "11100010" + rx_polarity: "01110011" + lane_swap: "51370462" + - id: "16" + tx_polarity: "10111010" + rx_polarity: "11010011" + lane_swap: "36152704" + - id: "17" + tx_polarity: "01011101" + rx_polarity: "00110001" + lane_swap: "45621073" + - id: "18" + tx_polarity: "11011111" + rx_polarity: "11001011" + lane_swap: "26143705" + - id: "19" + tx_polarity: "00100110" + rx_polarity: "00001001" + lane_swap: "42730165" + - id: "20" + tx_polarity: "10011011" + rx_polarity: "01101101" + lane_swap: "54217603" + - id: "21" + tx_polarity: "00101110" + rx_polarity: "10111111" + lane_swap: "26031745" + - id: "22" + tx_polarity: "01001110" + rx_polarity: "00111001" + lane_swap: "36024715" + - id: "23" + tx_polarity: "10101101" + rx_polarity: "01010011" + lane_swap: "45621370" + - id: "24" + tx_polarity: "11001110" + rx_polarity: "00011111" + lane_swap: "65234701" + - id: "25" + tx_polarity: "01110001" + rx_polarity: "01010111" + lane_swap: "37601452" + - id: "26" + tx_polarity: "01000100" + rx_polarity: "00001111" + lane_swap: "65034721" + - id: "27" + tx_polarity: "10111101" + rx_polarity: "11000101" + lane_swap: "34501672" + - id: "28" + tx_polarity: "01111000" + rx_polarity: "01110110" + lane_swap: "43061275" + - id: "29" + tx_polarity: "11110111" + rx_polarity: "11100111" + lane_swap: "57304621" + - id: "30" + tx_polarity: "10000100" + rx_polarity: "00101111" + lane_swap: "47125603" + - id: "31" + tx_polarity: "11111111" + rx_polarity: "11100010" + lane_swap: "13460275" + - id: "32" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x200/inno.config.yaml b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x200/inno.config.yaml new file mode 100755 index 000000000000..f68930c37ef4 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x200/inno.config.yaml @@ -0,0 +1,7 @@ +IFCS_INIT_FILE : "/usr/share/sonic/hwsku/config_64x200G_Delta-et-c032if.yaml" +IFCS_SKU_FILE : "/usr/share/sonic/hwsku/innovium.77700_B" +IFCS_INNO_CLI_PORT : "9999" +IFCS_TARGET : "device" +ULIMIT : "65536" +INNOVIUM_DIR : "/innovium" +PYTHONPATH : "$INNOVIUM_DIR:$INNOVIUM_DIR/cmds:$INNOVIUM_DIR/scripts:$INNOVIUM_DIR/test/:$INNOVIUM_DIR/test/utils:$INNOVIUM_DIR/utils:$INNOVIUM_DIR/pyctypes" diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x200/innovium.77700_B b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x200/innovium.77700_B new file mode 100644 index 000000000000..27297b313959 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x200/innovium.77700_B @@ -0,0 +1,59 @@ +sku: innovium.77700_B + +device_id: 0x1b58 + +# Hardware constraint information +hardware: + num_ibs: 6 + + ports_per_ib: 32, 32, 32, 32, 20, 20 + recirc_port_num: 32, 32, 32, 32, 32, 32 + cpu_port_num: 33 + cpu_port_ib: 0 + mgmt_port_num: 33 + mgmt_port_ibs: 1,2 + + pics_per_ib: 6, 7, 7, 6, 5, 5 + pic_ports_per_pic: 8 + max_serdes_speed: 50 + + num_shared_pics: 2 + + isg [0-4]: + ib: 0 + pic_id: [0-4] + + isg [5-9]: + ib: 5 + pic_id: [0-4] + + isg [10-14]: + ib: 1 + pic_id: [0-4] + + isg [16-20]: + ib: 3 + pic_id: [0-4] + + isg [21-25]: + ib: 4 + pic_id: [0-4] + + isg [26-30]: + ib: 2 + pic_id: [0-4] + + isg 15: + mode: 4:4 + ib: 1, 3 + pic_id: 5 + + isg 31: + mode: 4:4 + ib: 0, 2 + pic_id: 5 + + isg 32: + mode: 1:1 + ib: 1, 2 + pic_id: 6 diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x200/port_config.ini b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x200/port_config.ini new file mode 100644 index 000000000000..726e1a377d83 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x200/port_config.ini @@ -0,0 +1,67 @@ +# name lanes speed index mtu +Ethernet0 249,250,251,252 200000 0 9126 +Ethernet4 253,254,255,256 200000 0 9126 +Ethernet8 241,242,243,244 200000 1 9126 +Ethernet12 245,246,247,248 200000 1 9126 +Ethernet16 233,234,235,236 200000 2 9126 +Ethernet20 237,238,239,240 200000 2 9126 +Ethernet24 225,226,227,228 200000 3 9126 +Ethernet28 229,230,231,232 200000 3 9126 +Ethernet32 217,218,219,220 200000 4 9126 +Ethernet36 221,222,223,224 200000 4 9126 +Ethernet40 209,210,211,212 200000 5 9126 +Ethernet44 213,214,215,216 200000 5 9126 +Ethernet48 201,202,203,204 200000 6 9126 +Ethernet52 205,206,207,208 200000 6 9126 +Ethernet56 193,194,195,196 200000 7 9126 +Ethernet60 197,198,199,200 200000 7 9126 +Ethernet64 185,186,187,188 200000 8 9126 +Ethernet68 189,190,191,192 200000 8 9126 +Ethernet72 177,178,179,180 200000 9 9126 +Ethernet76 181,182,183,184 200000 9 9126 +Ethernet80 169,170,171,172 200000 10 9126 +Ethernet84 173,174,175,176 200000 10 9126 +Ethernet88 161,162,163,164 200000 11 9126 +Ethernet92 165,166,167,168 200000 11 9126 +Ethernet96 153,154,155,156 200000 12 9126 +Ethernet100 157,158,159,160 200000 12 9126 +Ethernet104 145,146,147,148 200000 13 9126 +Ethernet108 149,150,151,152 200000 13 9126 +Ethernet112 137,138,139,140 200000 14 9126 +Ethernet116 141,142,143,144 200000 14 9126 +Ethernet120 129,130,131,132 200000 15 9126 +Ethernet124 133,134,135,136 200000 15 9126 +Ethernet128 121,122,123,124 200000 16 9126 +Ethernet132 125,126,127,128 200000 16 9126 +Ethernet136 113,114,115,116 200000 17 9126 +Ethernet140 117,118,119,120 200000 17 9126 +Ethernet144 97,98,99,100 200000 18 9126 +Ethernet148 101,102,103,104 200000 18 9126 +Ethernet152 105,106,107,108 200000 19 9126 +Ethernet156 109,110,111,112 200000 19 9126 +Ethernet160 81,82,83,84 200000 20 9126 +Ethernet164 85,86,87,88 200000 20 9126 +Ethernet168 89,90,91,92 200000 21 9126 +Ethernet172 93,94,95,96 200000 21 9126 +Ethernet176 65,66,67,68 200000 22 9126 +Ethernet180 69,70,71,72 200000 22 9126 +Ethernet184 73,74,75,76 200000 23 9126 +Ethernet188 77,78,79,80 200000 23 9126 +Ethernet192 49,50,51,52 200000 24 9126 +Ethernet196 53,54,55,56 200000 24 9126 +Ethernet200 57,58,59,60 200000 25 9126 +Ethernet204 61,62,63,64 200000 25 9126 +Ethernet208 33,34,35,36 200000 26 9126 +Ethernet212 37,38,39,40 200000 26 9126 +Ethernet216 41,42,43,44 200000 27 9126 +Ethernet220 45,46,47,48 200000 27 9126 +Ethernet224 17,18,19,20 200000 28 9126 +Ethernet228 21,22,23,24 200000 28 9126 +Ethernet232 25,26,27,28 200000 29 9126 +Ethernet236 29,30,31,32 200000 29 9126 +Ethernet240 1,2,3,4 200000 30 9126 +Ethernet244 5,6,7,8 200000 30 9126 +Ethernet248 9,10,11,12 200000 31 9126 +Ethernet252 13,14,15,16 200000 31 9126 +Ethernet256 257 10000 32 9126 +Ethernet257 258 10000 33 9126 diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x200/qos.json.j2 b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x200/qos.json.j2 new file mode 100755 index 000000000000..16f9b42a2166 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x200/qos.json.j2 @@ -0,0 +1,120 @@ +{# Default values which will be used if no actual configura available #} + +{% set default_ports_num = 64 -%} +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "1":"1", + "0":"0", + "3":"3", + "2":"2", + "5":"5", + "4":"4", + "7":"7", + "6":"6" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "1": "0", + "0": "0", + "3": "0", + "2": "0", + "4": "1", + "5": "2", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"0", + "4":"4", + "5":"5", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "4,5" + } + } +} diff --git a/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x200/sai.profile b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x200/sai.profile new file mode 100755 index 000000000000..0769b3063a12 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/Delta-et-c032if_64x200/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/inno.config.yaml diff --git a/device/delta/x86_64-delta_et-c032if-r0/default_sku b/device/delta/x86_64-delta_et-c032if-r0/default_sku new file mode 100644 index 000000000000..92740942d0e9 --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/default_sku @@ -0,0 +1 @@ +Delta-et-c032if t1 diff --git a/device/delta/x86_64-delta_et-c032if-r0/installer.conf b/device/delta/x86_64-delta_et-c032if-r0/installer.conf new file mode 100644 index 000000000000..925a32fc0c3a --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 diff --git a/device/delta/x86_64-delta_et-c032if-r0/led_proc_init.soc b/device/delta/x86_64-delta_et-c032if-r0/led_proc_init.soc new file mode 100644 index 000000000000..4173de277f6b --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/led_proc_init.soc @@ -0,0 +1,10 @@ +#ET_C032IF Port_Remap +# Vlan set and port enable + +# led0 port order remap + +#ET_C032IF_LED + +#-------------------------------------------------------------------------------------------------- +#LED Auto link/up + diff --git a/device/delta/x86_64-delta_et-c032if-r0/plugins/eeprom.py b/device/delta/x86_64-delta_et-c032if-r0/plugins/eeprom.py new file mode 100644 index 000000000000..1a624414637c --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/plugins/eeprom.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python + +############################################################################# +# Mellanox +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + import exceptions + import binascii + import time + import optparse + import warnings + import os + import sys + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + import subprocess +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + _TLV_INFO_MAX_LEN = 256 + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/devices/pci0000:00/0000:00:1f.3/i2c-0/i2c-10/10-0053/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/delta/x86_64-delta_et-c032if-r0/plugins/psuutil.py b/device/delta/x86_64-delta_et-c032if-r0/plugins/psuutil.py new file mode 100644 index 000000000000..80383aaffddf --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/plugins/psuutil.py @@ -0,0 +1,78 @@ +# +# Module contains an implementation of SONiC PSU Base API and +# provides the PSUs status which are available in the platform +# + +import os.path +import subprocess + +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_status = "ipmitool raw 0x38 0x1 {} 0x50" + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + + :return: An integer, the number of PSUs available on the device + """ + return 2 + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by 1-based index + + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is faulty + """ + if index is None: + return False + + status = 0 + try: + p = os.popen("ipmitool raw 0x38 0x2 7 0x32 0x28 1") + content = p.readline().rstrip() + reg_value = int(content, 16) + mask = (1 << (8 - index)) + if reg_value & mask == 0: + return False + status = 1 + p.close() + except IOError: + return False + return status == 1 + + + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by 1-based index + + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + if index is None: + return False + status = 0 + try: + p = os.popen(self.psu_status.format(index - 1)) + content = p.readline().rstrip() + reg_value = int(content, 16) + if reg_value != 0: + return False + status = 1 + p.close() + except IOError: + return False + return status == 1 + diff --git a/device/delta/x86_64-delta_et-c032if-r0/plugins/sfputil.py b/device/delta/x86_64-delta_et-c032if-r0/plugins/sfputil.py new file mode 100644 index 000000000000..4802c3a8f0ce --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/plugins/sfputil.py @@ -0,0 +1,255 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + import datetime + 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_START_SFP = 32 + PORT_END = 33 + PORTS_IN_BLOCK = 34 + + EEPROM_OFFSET = 1 + + _port_to_eeprom_mapping = {} + port_dict = {} + + @property + def port_start(self): + return self.PORT_START + + @property + def port_start_sfp(self): + return self.PORT_START_SFP + + @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 + + @property + def get_transceiver_status(self): + + try: + reg_file = open("/sys/devices/platform/delta-et-c032if-cpld.0/sfp_is_present") + + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = reg_file.readline().rstrip() + + reg_file.close() + + return int(content, 16) + + + def __init__(self): + eeprom_path = "/sys/kernel/sfp/eeprom_sfp_{0}" + + for x in range(0, self.port_end + 1): + self._port_to_eeprom_mapping[x] = eeprom_path.format(x + self.EEPROM_OFFSET) + + self.modprs_register = self.get_transceiver_status + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open("/sys/devices/platform/delta-et-c032if-cpld.0/sfp_is_present") + 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 << (self.port_end - port_num + 6)) + + # ModPrsL is active low + if reg_value & mask == 0: + return True + + return False + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end - 2: + return False + + try: + reg_file = open("/sys/devices/platform/delta-et-c032if-cpld.0/sfp_lp_mode") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + + 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 << (self.port_end - port_num) - 2) + + # LPMode is active high + if reg_value & mask == 0: + return False + + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end - 2: + return False + + try: + reg_file = open("/sys/devices/platform/delta-et-c032if-cpld.0/sfp_lp_mode", "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + 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 << (self.port_end - port_num) - 2) + + # 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).rstrip("L") or "0" + + 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/delta-et-c032if-cpld.0/sfp_reset" + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end - 2: + 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 << (self.port_end - port_num) - 2) + + # 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, timeout=0): + start_time = time.time() + port_dict = {} + port = self.port_start + forever = False + if timeout == 0: + forever = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + print "get_transceiver_change_event:Invalid timeout value", timeout + return False, {} + + end_time = start_time + timeout + if start_time > end_time: + print 'get_transceiver_change_event:' \ + 'time wrap / invalid timeout value', timeout + + return False, {} # Time wrap or possibly incorrect timeout + while timeout >= 0: + # Check for OIR events and return updated port_dict + reg_value = self.get_transceiver_status + if reg_value != self.modprs_register: + changed_ports = self.modprs_register ^ reg_value + while port >= self.port_start and port <= self.port_end: + + # Mask off the bit corresponding to our port + mask = (1 << (self.port_end - port + 6)) + + if changed_ports & mask: + # ModPrsL is active low + if reg_value & mask == 0: + port_dict[port] = '1' + else: + port_dict[port] = '0' + + port += 1 + + # Update reg value + self.modprs_register = reg_value + 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_transceiver_change_event: Should not reach here." + return False, {} diff --git a/device/delta/x86_64-delta_et-c032if-r0/sensors.conf b/device/delta/x86_64-delta_et-c032if-r0/sensors.conf new file mode 100644 index 000000000000..db34a541b26f --- /dev/null +++ b/device/delta/x86_64-delta_et-c032if-r0/sensors.conf @@ -0,0 +1,4 @@ +# libsensors configuration file for DELTA-ET-C032IF +# ------------------------------------------------ +# + diff --git a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/switch-sai.conf b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/switch-sai.conf index 4f316bb9e5af..bf15b40d0c58 100644 --- a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/switch-sai.conf +++ b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/switch-sai.conf @@ -25,7 +25,7 @@ "table-config": "share/tofinopd/switch/context.json", "tofino-bin": "share/tofinopd/switch/tofino.bin", "switchapi": "lib/libswitchapi.so", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "agent0": "lib/platform/x86_64-ingrasys_s9180_32x-r0/libpltfm_mgr.so", "switchapi_port_add": false } diff --git a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/switch-tna-sai.conf b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/switch-tna-sai.conf index 6ad356614a0b..9fbf9d3cdb69 100644 --- a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/switch-tna-sai.conf +++ b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/switch-tna-sai.conf @@ -23,13 +23,13 @@ "p4_pipelines": [ { "p4_pipeline_name": "pipe", - "config": "share/tofinopd/switch/pipe/tofino.bin", - "context": "share/tofinopd/switch/pipe/context.json" + "config": "share/switch/pipe/tofino.bin", + "context": "share/switch/pipe/context.json" } ], "program-name": "switch", - "switchsai": "lib/libswitchsai.so", - "bfrt-config": "share/tofinopd/switch/bf-rt.json", + "sai": "lib/libsai.so", + "bfrt-config": "share/switch/bf-rt.json", "model_json_path" : "share/switch/aug_model.json", "switchapi_port_add": false, "non_default_port_ppgs": 5 diff --git a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/switch-sai.conf b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/switch-sai.conf index 224d1fc58b18..f1e9c0bc10da 100644 --- a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/switch-sai.conf +++ b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/switch-sai.conf @@ -25,7 +25,7 @@ "table-config": "share/tofinopd/switch/context.json", "tofino-bin": "share/tofinopd/switch/tofino.bin", "switchapi": "lib/libswitchapi.so", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "agent0": "lib/platform/x86_64-ingrasys_s9280_64x-r0/libpltfm_mgr.so", "switchapi_port_add": false } diff --git a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/switch-tna-sai.conf b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/switch-tna-sai.conf index 36f2ca83df73..4895ac901ff6 100644 --- a/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/switch-tna-sai.conf +++ b/device/ingrasys/x86_64-ingrasys_s9280_64x-r0/INGRASYS-S9280-64X/switch-tna-sai.conf @@ -23,13 +23,13 @@ "p4_pipelines": [ { "p4_pipeline_name": "pipe", - "config": "share/tofinopd/switch/pipe/tofino.bin", - "context": "share/tofinopd/switch/pipe/context.json" + "config": "share/switch/pipe/tofino.bin", + "context": "share/switch/pipe/context.json" } ], "program-name": "switch", - "switchsai": "lib/libswitchsai.so", - "bfrt-config": "share/tofinopd/switch/bf-rt.json", + "sai": "lib/libsai.so", + "bfrt-config": "share/switch/bf-rt.json", "model_json_path" : "share/switch/aug_model.json", "switchapi_port_add": false, "non_default_port_ppgs": 5 diff --git a/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/buffers.json.j2 b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/buffers_defaults_t0.j2 b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..1587625a294e --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/buffers_defaults_t0.j2 @@ -0,0 +1,50 @@ +{%- set default_cable = '40m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,47) %} + {% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %} + {% endfor %} + {% for port_idx in range(12,19) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "10443264", + "type": "ingress", + "mode": "dynamic", + "xoff": "7335744" + }, + "egress_lossy_pool": { + "size": "8877440", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "15982720", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"3995680" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} + diff --git a/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/buffers_defaults_t1.j2 b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..1587625a294e --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/buffers_defaults_t1.j2 @@ -0,0 +1,50 @@ +{%- set default_cable = '40m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,47) %} + {% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %} + {% endfor %} + {% for port_idx in range(12,19) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "10443264", + "type": "ingress", + "mode": "dynamic", + "xoff": "7335744" + }, + "egress_lossy_pool": { + "size": "8877440", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "15982720", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"3995680" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} + diff --git a/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/pg_profile_lookup.ini b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/pg_profile_lookup.ini new file mode 100644 index 000000000000..7222f8014925 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1248 2288 35776 -4 2288 + 25000 5m 1248 2288 53248 -4 2288 + 40000 5m 1248 2288 66560 -4 2288 + 50000 5m 1248 2288 79872 -4 2288 + 100000 5m 1248 2288 165568 -4 2288 + 10000 40m 1248 2288 37024 -4 2288 + 25000 40m 1248 2288 56160 -4 2288 + 40000 40m 1248 2288 71552 -4 2288 + 50000 40m 1248 2288 85696 -4 2288 + 100000 40m 1248 2288 177632 -4 2288 + 10000 300m 1248 2288 46176 -4 2288 + 25000 300m 1248 2288 79040 -4 2288 + 40000 300m 1248 2288 108160 -4 2288 + 50000 300m 1248 2288 131456 -4 2288 + 100000 300m 1248 2288 268736 -4 2288 diff --git a/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/port_config.ini b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/port_config.ini new file mode 100755 index 000000000000..aaac478ab8fd --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed +Ethernet0 1 Ethernet0 0 25000 +Ethernet1 2 Ethernet1 1 25000 +Ethernet2 3 Ethernet2 2 25000 +Ethernet3 4 Ethernet3 3 25000 +Ethernet4 5 Ethernet4 4 25000 +Ethernet5 6 Ethernet5 5 25000 +Ethernet6 7 Ethernet6 6 25000 +Ethernet7 8 Ethernet7 7 25000 +Ethernet8 13 Ethernet8 8 25000 +Ethernet9 14 Ethernet9 9 25000 +Ethernet10 15 Ethernet10 10 25000 +Ethernet11 16 Ethernet11 11 25000 +Ethernet12 21 Ethernet12 12 25000 +Ethernet13 22 Ethernet13 13 25000 +Ethernet14 23 Ethernet14 14 25000 +Ethernet15 24 Ethernet15 15 25000 +Ethernet16 29 Ethernet16 16 25000 +Ethernet17 30 Ethernet17 17 25000 +Ethernet18 31 Ethernet18 18 25000 +Ethernet19 32 Ethernet19 19 25000 +Ethernet20 33 Ethernet20 20 25000 +Ethernet21 34 Ethernet21 21 25000 +Ethernet22 35 Ethernet22 22 25000 +Ethernet23 36 Ethernet23 23 25000 +Ethernet24 41 Ethernet24 24 25000 +Ethernet25 42 Ethernet25 25 25000 +Ethernet26 43 Ethernet26 26 25000 +Ethernet27 44 Ethernet27 27 25000 +Ethernet28 49 Ethernet28 28 25000 +Ethernet29 50 Ethernet29 29 25000 +Ethernet30 51 Ethernet30 30 25000 +Ethernet31 52 Ethernet31 31 25000 +Ethernet32 57 Ethernet32 32 25000 +Ethernet33 58 Ethernet33 33 25000 +Ethernet34 59 Ethernet34 34 25000 +Ethernet35 60 Ethernet35 35 25000 +Ethernet36 61 Ethernet36 36 25000 +Ethernet37 62 Ethernet37 37 25000 +Ethernet38 63 Ethernet38 38 25000 +Ethernet39 64 Ethernet39 39 25000 +Ethernet40 65 Ethernet40 40 25000 +Ethernet41 66 Ethernet41 41 25000 +Ethernet42 67 Ethernet42 42 25000 +Ethernet43 68 Ethernet43 43 25000 +Ethernet44 69 Ethernet44 44 25000 +Ethernet45 70 Ethernet45 45 25000 +Ethernet46 71 Ethernet46 46 25000 +Ethernet47 72 Ethernet47 47 25000 +Ethernet48 85,86,87,88 Ethernet48 48 100000 +Ethernet52 77,78,79,80 Ethernet52 49 100000 +Ethernet56 93,94,95,96 Ethernet56 50 100000 +Ethernet60 97,98,99,100 Ethernet60 51 100000 +Ethernet64 113,114,115,116 Ethernet64 52 100000 +Ethernet68 105,106,107,108 Ethernet68 53 100000 +Ethernet72 121,122,123,124 Ethernet72 54 100000 +Ethernet76 125,126,127,128 Ethernet76 55 100000 diff --git a/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/qos.json.j2 b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/qos.json.j2 new file mode 100644 index 000000000000..d3cac04f662a --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/qos.json.j2 @@ -0,0 +1,155 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "SCHEDULER": { + "scheduler.0" : { + "type":"DWRR", + "weight": "25" + }, + "scheduler.1" : { + "type":"DWRR", + "weight": "30" + }, + "scheduler.2" : { + "type":"DWRR", + "weight": "20" + } + }, + "PORT_QOS_MAP": { + "Ethernet0,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,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,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" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "wred_red_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"312000", + "red_min_threshold":"104000", + "yellow_max_threshold":"312000", + "yellow_min_threshold":"104000", + "green_max_threshold": "312000", + "green_min_threshold": "104000" + } + }, + "QUEUE": { + "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76|3-4" : { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76|0" : { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, + "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76|1" : { + "scheduler" : "[SCHEDULER|scheduler.2]" + } + } +} diff --git a/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/sai.profile b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/sai.profile new file mode 100755 index 000000000000..f147d44c0b34 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-d6356-48x25G-8x100G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/td3-d6356-48x25G-8x100G.config.bcm b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/td3-d6356-48x25G-8x100G.config.bcm new file mode 100644 index 000000000000..57fd5cd57164 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/td3-d6356-48x25G-8x100G.config.bcm @@ -0,0 +1,412 @@ +### fix for sonic +ptp_ts_pll_fref=50000000 +ptp_bs_fref_0=50000000 +ptp_bs_fref_1=50000000 +ifp_inports_support_enable=1 +### end fix + +stable_size=0x5500000 + +core_clock_frequency=1525 +dpp_clock_ratio=2:3 + +oversubscribe_mode=1 +pbmp_xport_xe=0x488787878808787fdfe1e1e1fe1e1e1fe + + +#portmap_65=130:10 + +### Pipeline0, halfpipe 0 (12x25G + 2x100G) +portmap_1=1:25 +portmap_2=2:25 +portmap_3=3:25 +portmap_4=4:25 +portmap_5=5:25 +portmap_6=6:25 +portmap_7=7:25 +portmap_8=8:25 +portmap_13=13:25 +portmap_14=14:25 +portmap_15=15:25 +portmap_16=16:25 +portmap_21=21:25 +portmap_22=22:25 +portmap_23=23:25 +portmap_24=24:25 +portmap_29=29:25 +portmap_30=30:25 +portmap_31=31:25 +portmap_32=32:25 + +### Pipeline0, halfpipe 1 (12x25G + 2x100G) +portmap_33=33:25 +portmap_34=34:25 +portmap_35=35:25 +portmap_36=36:25 +portmap_41=41:25 +portmap_42=42:25 +portmap_43=43:25 +portmap_44=44:25 +portmap_49=49:25 +portmap_50=50:25 +portmap_51=51:25 +portmap_52=52:25 +portmap_57=57:25 +portmap_58=58:25 +portmap_59=59:25 +portmap_60=60:25 +portmap_61=61:25 +portmap_62=62:25 +portmap_63=63:25 +portmap_64=64:25 + +### Pipeline 1 +### First management port +#portmap_66=129:10:m +### Second management port +#portmap_130=128:10:m +### Loopback port +#portmap_131=131:10 + +### Pipeline 1, halfpipe 0 (12x25G + 2x100G) +portmap_67=65:25 +portmap_68=66:25 +portmap_69=67:25 +portmap_70=68:25 +portmap_71=69:25 +portmap_72=70:25 +portmap_73=71:25 +portmap_74=72:25 +portmap_79=77:100 +portmap_87=85:100 +portmap_95=93:100 + +### Pipeline 1, halfpipe 1 (12x25G + 2x100G) +portmap_99=97:100 +portmap_107=105:100 +portmap_115=113:100 +portmap_123=121:100 +portmap_127=125:100 + +l2_mem_entries=32768 +l3_mem_entries=16384 +fpem_mem_entries=16384 +l2xmsg_mode=1 + + + +pdma_descriptor_prefetch_enable=1 + +port_flex_enable=1 + +#dport part +dport_map_port_79=87 +dport_map_port_87=79 +dport_map_port_107=115 +dport_map_port_115=107 + +#Polarity flips after lane swaps +#rx part +#FC1 +phy_chain_rx_polarity_flip_physical{5.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{7.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x1 + +#FC3 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_rx_polarity_flip_physical{16.0}=0x1 + +#FC5 +phy_chain_rx_polarity_flip_physical{21.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_rx_polarity_flip_physical{24.0}=0x1 + +#FC8 +phy_chain_rx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{34.0}=0x1 +phy_chain_rx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{36.0}=0x1 + +#FC10 +phy_chain_rx_polarity_flip_physical{41.0}=0x1 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x1 + +#FC12 +phy_chain_rx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x1 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x1 + +#FC14 +phy_chain_rx_polarity_flip_physical{57.0}=0x1 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_rx_polarity_flip_physical{59.0}=0x1 +phy_chain_rx_polarity_flip_physical{60.0}=0x1 + +#FC15 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_rx_polarity_flip_physical{64.0}=0x1 + +#FC16 +phy_chain_rx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{66.0}=0x1 + +#FC17 +phy_chain_rx_polarity_flip_physical{69.0}=0x1 +phy_chain_rx_polarity_flip_physical{70.0}=0x1 +phy_chain_rx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{72.0}=0x1 + +#FC19 +phy_chain_rx_polarity_flip_physical{77.0}=0x1 +phy_chain_rx_polarity_flip_physical{78.0}=0x1 + +#FC21 +phy_chain_rx_polarity_flip_physical{85.0}=0x1 +phy_chain_rx_polarity_flip_physical{86.0}=0x1 + +#FC23 +phy_chain_rx_polarity_flip_physical{93.0}=0x1 +phy_chain_rx_polarity_flip_physical{94.0}=0x1 + +#FC24 +phy_chain_rx_polarity_flip_physical{99.0}=0x1 +phy_chain_rx_polarity_flip_physical{100.0}=0x1 + +#FC26 +phy_chain_rx_polarity_flip_physical{105.0}=0x1 +phy_chain_rx_polarity_flip_physical{106.0}=0x1 + +#FC28 +phy_chain_rx_polarity_flip_physical{113.0}=0x1 +#phy_chain_rx_polarity_flip_physical{114.0}=0x1 + +#FC30 +phy_chain_rx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 + +#FC31 +phy_chain_rx_polarity_flip_physical{127.0}=0x1 +phy_chain_rx_polarity_flip_physical{128.0}=0x1 + +#tx part +#FC19 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x1 + +#FC21 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_tx_polarity_flip_physical{88.0}=0x1 + +#FC23 +phy_chain_tx_polarity_flip_physical{94.0}=0x1 +phy_chain_tx_polarity_flip_physical{95.0}=0x1 +phy_chain_tx_polarity_flip_physical{96.0}=0x1 + +#FC24 +phy_chain_tx_polarity_flip_physical{99.0}=0x1 +phy_chain_tx_polarity_flip_physical{100.0}=0x1 + +#FC26 +phy_chain_tx_polarity_flip_physical{107.0}=0x1 +phy_chain_tx_polarity_flip_physical{108.0}=0x1 + +#FC28 +phy_chain_tx_polarity_flip_physical{115.0}=0x1 +phy_chain_tx_polarity_flip_physical{116.0}=0x1 + +#FC30 +phy_chain_tx_polarity_flip_physical{122.0}=0x1 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_tx_polarity_flip_physical{124.0}=0x1 + +#FC31 +phy_chain_tx_polarity_flip_physical{127.0}=0x1 +phy_chain_tx_polarity_flip_physical{128.0}=0x1 + + +phy_chain_rx_lane_map_physical{1.0}=0x1032 +phy_chain_tx_lane_map_physical{1.0}=0x0123 +phy_chain_rx_lane_map_physical{5.0}=0x1032 +phy_chain_tx_lane_map_physical{5.0}=0x0123 +phy_chain_rx_lane_map_physical{13.0}=0x1032 +phy_chain_tx_lane_map_physical{13.0}=0x0123 +phy_chain_rx_lane_map_physical{21.0}=0x1032 +phy_chain_tx_lane_map_physical{21.0}=0x0123 +phy_chain_rx_lane_map_physical{29.0}=0x1032 +phy_chain_tx_lane_map_physical{29.0}=0x0123 + +phy_chain_rx_lane_map_physical{33.0}=0x1032 +phy_chain_tx_lane_map_physical{33.0}=0x0123 +phy_chain_rx_lane_map_physical{41.0}=0x1032 +phy_chain_tx_lane_map_physical{41.0}=0x0123 +phy_chain_rx_lane_map_physical{49.0}=0x1032 +phy_chain_tx_lane_map_physical{49.0}=0x0123 +phy_chain_rx_lane_map_physical{57.0}=0x1032 +phy_chain_tx_lane_map_physical{57.0}=0x0123 +phy_chain_rx_lane_map_physical{61.0}=0x1032 +phy_chain_tx_lane_map_physical{61.0}=0x0123 + +phy_chain_rx_lane_map_physical{65.0}=0x2301 +phy_chain_tx_lane_map_physical{65.0}=0x3210 +phy_chain_rx_lane_map_physical{69.0}=0x2301 +phy_chain_tx_lane_map_physical{69.0}=0x3210 + +phy_chain_rx_lane_map_physical{85.0}=0x0213 +phy_chain_tx_lane_map_physical{85.0}=0x3120 +phy_chain_rx_lane_map_physical{77.0}=0x2031 +phy_chain_tx_lane_map_physical{77.0}=0x1302 + +phy_chain_rx_lane_map_physical{93.0}=0x2031 +phy_chain_tx_lane_map_physical{93.0}=0x1302 +phy_chain_rx_lane_map_physical{97.0}=0x0213 +phy_chain_tx_lane_map_physical{97.0}=0x3120 + +phy_chain_rx_lane_map_physical{113.0}=0x1203 +phy_chain_tx_lane_map_physical{113.0}=0x3120 +phy_chain_rx_lane_map_physical{105.0}=0x2031 +phy_chain_tx_lane_map_physical{105.0}=0x1302 + +phy_chain_rx_lane_map_physical{121.0}=0x2031 +phy_chain_tx_lane_map_physical{121.0}=0x1302 +phy_chain_rx_lane_map_physical{125.0}=0x0213 +phy_chain_tx_lane_map_physical{125.0}=0x3120 + +phy_chain_tx_polarity_flip_physical{129.0}=0x0 +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}=0x0 +phy_chain_rx_polarity_flip_physical{131.0}=0x0 +phy_chain_tx_polarity_flip_physical{132.0}=0x0 +phy_chain_rx_polarity_flip_physical{132.0}=0x0 + +# EQ/IDriver +# 25G +serdes_preemphasis_1=0x0F4B0A +serdes_preemphasis_2=0x104A0A +serdes_preemphasis_3=0x0E4C0A +serdes_preemphasis_4=0x0E4C0A +serdes_preemphasis_5=0x0D4D0A +serdes_preemphasis_6=0x0D4D0A +serdes_preemphasis_7=0x0D4D0A +serdes_preemphasis_8=0x0D4D0A +serdes_preemphasis_13=0x0C4E0A +serdes_preemphasis_14=0x0D4D0A +serdes_preemphasis_15=0x0B4F0A +serdes_preemphasis_16=0x0C4E0A +serdes_preemphasis_21=0x0A500A +serdes_preemphasis_22=0x0A500A +serdes_preemphasis_23=0x09510A +serdes_preemphasis_24=0x09510A +serdes_preemphasis_29=0x08520A +serdes_preemphasis_30=0x08520A +serdes_preemphasis_31=0x07530A +serdes_preemphasis_32=0x07530A +serdes_preemphasis_33=0x06540A +serdes_preemphasis_34=0x07530A +serdes_preemphasis_35=0x05550A +serdes_preemphasis_36=0x06540A +serdes_preemphasis_41=0x05550A +serdes_preemphasis_42=0x06540A +serdes_preemphasis_43=0x05550A +serdes_preemphasis_44=0x05550A +serdes_preemphasis_49=0x04560A +serdes_preemphasis_50=0x05550A +serdes_preemphasis_51=0x05550A +serdes_preemphasis_52=0x06540A +serdes_preemphasis_57=0x06540A +serdes_preemphasis_58=0x07530A +serdes_preemphasis_59=0x06540A +serdes_preemphasis_60=0x07530A +serdes_preemphasis_61=0x06540A +serdes_preemphasis_62=0x08520A +serdes_preemphasis_63=0x08520A +serdes_preemphasis_64=0x09510A +serdes_preemphasis_67=0x06540A +serdes_preemphasis_68=0x06540A +serdes_preemphasis_69=0x06540A +serdes_preemphasis_70=0x08520A +serdes_preemphasis_71=0x09510A +serdes_preemphasis_72=0x09510A +serdes_preemphasis_73=0x09510A +serdes_preemphasis_74=0x0A500A +serdes_preemphasis_lane0_87=0x07530A +serdes_preemphasis_lane1_87=0x05550A +serdes_preemphasis_lane2_87=0x07530A +serdes_preemphasis_lane3_87=0x05550A +serdes_preemphasis_79=0x05550A +serdes_preemphasis_95=0x07530A +serdes_preemphasis_lane0_99=0x085309 +serdes_preemphasis_lane1_99=0x0B4F0A +serdes_preemphasis_lane2_99=0x085309 +serdes_preemphasis_lane3_99=0x0B4F0A +serdes_preemphasis_115=0x0B4F0A +serdes_preemphasis_107=0x0B4F0A +serdes_preemphasis_123=0x0B4F0A +serdes_preemphasis_127=0x0D4E09 +# 10G + +# interface type +serdes_if_type_1=16 +serdes_if_type_2=16 +serdes_if_type_3=16 +serdes_if_type_4=16 +serdes_if_type_5=16 +serdes_if_type_6=16 +serdes_if_type_7=16 +serdes_if_type_8=16 +serdes_if_type_13=16 +serdes_if_type_14=16 +serdes_if_type_15=16 +serdes_if_type_16=16 +serdes_if_type_21=16 +serdes_if_type_22=16 +serdes_if_type_23=16 +serdes_if_type_24=16 +serdes_if_type_29=16 +serdes_if_type_30=16 +serdes_if_type_31=16 +serdes_if_type_32=16 +serdes_if_type_33=16 +serdes_if_type_34=16 +serdes_if_type_35=16 +serdes_if_type_36=16 +serdes_if_type_41=16 +serdes_if_type_42=16 +serdes_if_type_43=16 +serdes_if_type_44=16 +serdes_if_type_49=16 +serdes_if_type_50=16 +serdes_if_type_51=16 +serdes_if_type_52=16 +serdes_if_type_57=16 +serdes_if_type_58=16 +serdes_if_type_59=16 +serdes_if_type_60=16 +serdes_if_type_61=16 +serdes_if_type_62=16 +serdes_if_type_63=16 +serdes_if_type_64=16 +serdes_if_type_67=16 +serdes_if_type_68=16 +serdes_if_type_69=16 +serdes_if_type_70=16 +serdes_if_type_71=16 +serdes_if_type_72=16 +serdes_if_type_73=16 +serdes_if_type_74=16 +serdes_if_type_87=28 +serdes_if_type_79=28 +serdes_if_type_95=28 +serdes_if_type_99=28 +serdes_if_type_115=28 +serdes_if_type_107=28 +serdes_if_type_123=28 +serdes_if_type_127=28 diff --git a/device/inventec/x86_64-inventec_d6356-r0/custom_led.bin b/device/inventec/x86_64-inventec_d6356-r0/custom_led.bin new file mode 100644 index 000000000000..237c2a1a4c32 Binary files /dev/null and b/device/inventec/x86_64-inventec_d6356-r0/custom_led.bin differ diff --git a/device/inventec/x86_64-inventec_d6356-r0/default_sku b/device/inventec/x86_64-inventec_d6356-r0/default_sku new file mode 100644 index 000000000000..f4c77ebd10f5 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/default_sku @@ -0,0 +1 @@ +INVENTEC-D6356 t1 diff --git a/device/inventec/x86_64-inventec_d6356-r0/installer.conf b/device/inventec/x86_64-inventec_d6356-r0/installer.conf new file mode 100644 index 000000000000..1db64ba02c38 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/installer.conf @@ -0,0 +1,4 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 +VAR_LOG_SIZE=1024 diff --git a/device/inventec/x86_64-inventec_d6356-r0/led_proc_init.soc b/device/inventec/x86_64-inventec_d6356-r0/led_proc_init.soc new file mode 100644 index 000000000000..01b49772c0ba --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/led_proc_init.soc @@ -0,0 +1,6 @@ +#led auto off +#led stop +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/inventec/x86_64-inventec_d6356-r0/linkscan_led_fw.bin b/device/inventec/x86_64-inventec_d6356-r0/linkscan_led_fw.bin new file mode 100644 index 000000000000..e9d763ad98b2 Binary files /dev/null and b/device/inventec/x86_64-inventec_d6356-r0/linkscan_led_fw.bin differ diff --git a/device/inventec/x86_64-inventec_d6356-r0/media_settings.json b/device/inventec/x86_64-inventec_d6356-r0/media_settings.json new file mode 100644 index 000000000000..f688fcb48a08 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/media_settings.json @@ -0,0 +1,707 @@ +{ + "PORT_MEDIA_SETTINGS": { + "0": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x0B3D01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0F4B0A" + } + } + }, + "1": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x0A3C01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x104A0A" + } + } + }, + "2": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x0B3D01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0E4C0A" + } + } + }, + "3": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x083200" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0E4C0A" + } + } + }, + "4": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x0A3D01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0D4D0A" + } + } + }, + "5": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x083400" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0D4D0A" + } + } + }, + "6": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x0A3801" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0D4D0A" + } + } + }, + "7": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x083400" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0D4D0A" + } + } + }, + "8": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x093801" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0C4E0A" + } + } + }, + "9": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x083400" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0D4D0A" + } + } + }, + "10": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x083601" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0B4F0A" + } + } + }, + "11": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x083400" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0C4E0A" + } + } + }, + "12": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x083401" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0A500A" + } + } + }, + "13": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x073200" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0A500A" + } + } + }, + "14": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x083401" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x09510A" + } + } + }, + "15": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x063101" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x09510A" + } + } + }, + "16": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x063401" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x08520A" + } + } + }, + "17": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x063201" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x08520A" + } + } + }, + "18": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x063001" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x07530A" + } + } + }, + "19": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052E00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x07530A" + } + } + }, + "20": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x063001" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x06540A" + } + } + }, + "21": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052E00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x07530A" + } + } + }, + "22": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052E01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x05550A" + } + } + }, + "23": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x062D01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x06540A" + } + } + }, + "24": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x063000" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x05550A" + } + } + }, + "25": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x062D01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x06540A" + } + } + }, + "26": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052C00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x05550A" + } + } + }, + "27": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052C01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x05550A" + } + } + }, + "28": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052C00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x04560A" + } + } + }, + "29": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052C00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x05550A" + } + } + }, + "30": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052C00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x05550A" + } + } + }, + "31": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x062E01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x06540A" + } + } + }, + "32": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052D00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x06540A" + } + } + }, + "33": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x062E01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x07530A" + } + } + }, + "34": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052D00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x06540A" + } + } + }, + "35": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052D00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x07530A" + } + } + }, + "36": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052E00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x06540A" + } + } + }, + "37": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052C01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x08520A" + } + } + }, + "38": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x082E00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x08520A" + } + } + }, + "39": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x062D01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x09510A" + } + } + }, + "40": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x072C01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x06540A" + } + } + }, + "41": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052D00" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x06540A" + } + } + }, + "42": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x063001" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x06540A" + } + } + }, + "43": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052D01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x08520A" + } + } + }, + "44": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x083401" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x09510A" + } + } + }, + "45": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x052D01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x09510A" + } + } + }, + "46": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x093901" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x09510A" + } + } + }, + "47": { + "FINISAR CORP.-FTLX8571D3BCL": { + "preemphasis": { + "lane0":"0x072D01" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0A500A" + } + } + }, + "48": { + "FINISAR CORP-FTL410QE2C": { + "preemphasis": { + "lane0":"0x083101", + "lane1":"0x083201", + "lane2":"0x083001", + "lane3":"0x093001" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x07530A", + "lane1":"0x05550A", + "lane2":"0x07530A", + "lane3":"0x05550A" + } + } + }, + "49": { + "FINISAR CORP-FTL410QE2C": { + "preemphasis": { + "lane0":"0x082E01", + "lane1":"0x083301", + "lane2":"0x083101", + "lane3":"0x093102" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x05550A" + } + } + }, + "50": { + "FINISAR CORP-FTL410QE2C": { + "preemphasis": { + "lane0":"0x082F01", + "lane1":"0x083001", + "lane2":"0x083201", + "lane3":"0x093202" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x07530A" + } + } + }, + "51": { + "FINISAR CORP-FTL410QE2C": { + "preemphasis": { + "lane0":"0x083001", + "lane1":"0x0A3101", + "lane2":"0x083301", + "lane3":"0x093302" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x085309", + "lane1":"0x0B4F0A", + "lane2":"0x085309", + "lane3":"0x0B4F0A" + } + } + }, + "52": { + "FINISAR CORP-FTL410QE2C": { + "preemphasis": { + "lane0":"0x093101", + "lane1":"0x0A3201", + "lane2":"0x0A3402", + "lane3":"0x093402" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0B4F0A" + } + } + }, + "53": { + "FINISAR CORP-FTL410QE2C": { + "preemphasis": { + "lane0":"0x093201", + "lane1":"0x0A3301", + "lane2":"0x093401", + "lane3":"0x093502" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0B4F0A" + } + } + }, + "54": { + "FINISAR CORP-FTL410QE2C": { + "preemphasis": { + "lane0":"0x093101", + "lane1":"0x0A3401", + "lane2":"0x0A3501", + "lane3":"0x093602" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0B4F0A" + } + } + }, + "55": { + "FINISAR CORP-FTL410QE2C": { + "preemphasis": { + "lane0":"0x093201", + "lane1":"0x0A3501", + "lane2":"0x0A3601", + "lane3":"0x093701" + } + }, + "Default": { + "preemphasis": { + "lane0":"0x0D4E09" + } + } + } + } +} + diff --git a/device/inventec/x86_64-inventec_d6356-r0/plugins/eeprom.py b/device/inventec/x86_64-inventec_d6356-r0/plugins/eeprom.py new file mode 100644 index 000000000000..953570d79cd7 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/plugins/eeprom.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +############################################################################# +# Inventec d6356 +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/bus/i2c/devices/2-0055/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/inventec/x86_64-inventec_d6356-r0/plugins/psuutil.py b/device/inventec/x86_64-inventec_d6356-r0/plugins/psuutil.py new file mode 100755 index 000000000000..732650ffe638 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/plugins/psuutil.py @@ -0,0 +1,88 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + + +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + PSU_DIR = "/sys/class/hwmon/hwmon2/device/" + + def __init__(self): + PsuBase.__init__(self) + +# Get sysfs attribute + def get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + MAX_PSUS = 2 + return MAX_PSUS + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is\ + faulty + """ + status = 0 + + if index == 1 : + attr_path = "/sys/class/hwmon/hwmon7/in1_input" + else : + attr_path = "/sys/class/hwmon/hwmon8/in1_input" + + attr_value = self.get_attr_value(attr_path) + if (attr_value != 'ERR'): + # Check for PSU status + if (attr_value != 0): + status = 1 + return status + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + psu_absent = 0 + ind = index + attr_file ='psu'+ str(ind) + attr_path = self.PSU_DIR +'/' + attr_file + normal_attr_value = '1:normal' + attr_value = self.get_attr_value(attr_path) + if (attr_value != 'ERR'): + # Check for PSU presence + if (attr_value == normal_attr_value): + status = 1 + return status + diff --git a/device/inventec/x86_64-inventec_d6356-r0/plugins/sfputil.py b/device/inventec/x86_64-inventec_d6356-r0/plugins/sfputil.py new file mode 100755 index 000000000000..116a3d9acbc9 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/plugins/sfputil.py @@ -0,0 +1,379 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +# +# INV_FIX-4037 +# (1) Support get_transceiver_change_event. +# Create the SWPSEventMonitor class to handle any kobject event from the SWPS driver. +# (2) Integrated with the optoe driver +# Due to installing the optoe driver to create the i2c topology, +# it needs to overwrite the followings functions which are declared in the sfputilbase.py. +# First, it needs to impore some SFP-related class object +# +try: + import time + import socket, re,os + from collections import OrderedDict + from sonic_sfp.sfputilbase import SfpUtilBase + from sonic_sfp.sff8472 import sff8472Dom +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VLOT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 + +NETLINK_KOBJECT_UEVENT = 15 +monitor = None + +class SWPSEventMonitor(object): + + def __init__(self): + self.recieved_events = OrderedDict() + self.socket = socket.socket( + socket.AF_NETLINK, socket.SOCK_DGRAM, NETLINK_KOBJECT_UEVENT) + + def start(self): + self.socket.bind((os.getpid(), -1)) + + def stop(self): + self.socket.close() + + def __enter__(self): + self.start() + return self + + def __exit__(self, exc_type, exc_value, traceback): + self.stop() + + def __iter__(self): + global monitor + while True: + for item in monitor.next_events(): + yield item + + def next_events(self): + data = self.socket.recv(16384) + event = {} + for item in data.split(b'\x00'): + if not item: + # check if we have an event and if we already received it + if event and event['SEQNUM'] not in self.recieved_events: + self.recieved_events[event['SEQNUM']] = None + if (len(self.recieved_events) > 100): + self.recieved_events.popitem(last=False) + yield event + event = {} + else: + try: + k, v = item.split(b'=', 1) + event[k.decode('ascii')] = v.decode('ascii') + except ValueError: + pass + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 0 + PORT_END = 55 + PORTS_IN_BLOCK = 56 + QSFP_PORT_START = 48 + QSFP_PORT_END = 55 + + _port_to_eeprom_mapping = {} + port_to_i2c_mapping = { + 0:22, + 1:23, + 2:24, + 3:25, + 4:26, + 5:27, + 6:28, + 7:29, + 8:30, + 9:31, + 10:32, + 11:33, + 12:34, + 13:35, + 14:36, + 15:37, + 16:38, + 17:39, + 18:40, + 19:41, + 20:42, + 21:43, + 22:44, + 23:45, + 24:46, + 25:47, + 26:48, + 27:49, + 28:50, + 29:51, + 30:52, + 31:53, + 32:54, + 33:55, + 34:56, + 35:57, + 36:58, + 37:59, + 38:60, + 39:61, + 40:62, + 41:63, + 42:64, + 43:65, + 44:66, + 45:67, + 46:68, + 47:69, + 48:14, + 49:15, + 50:16, + 51:17, + 52:18, + 53:19, + 54:20, + 55:21 + } + + @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(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + + @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): + port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) + self.port_to_eeprom_mapping[x] = port_eeprom_path + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open("/sys/class/swps/port"+str(port_num)+"/present") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = int(reg_file.readline().rstrip()) + + if reg_value == 0: + return True + + return False + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: + return False + + try: + reg_file = open("/sys/class/swps/port"+str(port_num)+"/lpmod") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + + reg_value = int(reg_file.readline().rstrip()) + + if reg_value == 0: + return False + + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: + print "\nError:SFP's don't support this property" + return False + + try: + reg_file = open("/sys/class/swps/port"+str(port_num)+"/lpmod", "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = int(reg_file.readline().rstrip()) + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + reg_value = 1 + else: + reg_value = 0 + + reg_file.write(hex(reg_value)) + reg_file.close() + + return True + + def reset(self, port_num): + QSFP_RESET_REGISTER_DEVICE_FILE = "/sys/class/swps/port"+str(port_num)+"/reset" + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: + print "\nError:SFP's don't support this property" + return False + + try: + reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = 0 + reg_file.write(hex(reg_value)) + reg_file.close() + + # Sleep 2 second to allow it to settle + time.sleep(2) + + # Flip the value back write back to the register to take port out of reset + try: + reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = 1 + reg_file.write(hex(reg_value)) + reg_file.close() + + return True + +# +# INV_FIX-4037 +# (1) Support get_transceiver_change_event. +# Modify get_transceiver_change_event() to listen the SWPS kobject event. +# (2) Integrated with the optoe driver +# Due to installing the optoe driver to create the i2c topology, +# it needs to overwrite the followings functions which are declared in the sfputilbase.py. +# It modified the get_eeprom_dom_raw() and get_transceiver_dom_info_dict(). +# + def get_transceiver_change_event(self): + global monitor + port_dict = {} + with SWPSEventMonitor() as monitor: + for event in monitor: + if event['SUBSYSTEM'] == 'swps': + #print('SWPS event. From %s, ACTION %s, IF_TYPE %s, IF_LANE %s' % (event['DEVPATH'], event['ACTION'], event['IF_TYPE'], event['IF_LANE'])) + portname = event['DEVPATH'].split("/")[-1] + rc = re.match(r"port(?P\d+)",portname) + if rc is not None: + if event['ACTION'] == "remove": + remove_num = int(rc.group("num")) + port_dict[remove_num] = "0" + #port_dict[rc.group("num")] = "0" + if event['ACTION'] == "add": + add_num = int(rc.group("num")) + port_dict[add_num] = "1" + #port_dict[rc.group("num")] = "1" + return True, port_dict + return False, {} + + def get_eeprom_dom_raw(self, port_num): + if port_num in self.qsfp_ports: + # QSFP DOM EEPROM is also at addr 0x50 and thus also stored in eeprom_ifraw + return None + else: + # Read dom eeprom at addr 0x51 + return self._read_eeprom_devid(port_num, self.DOM_EEPROM_ADDR, 256) + + def get_transceiver_dom_info_dict(self, port_num): + if port_num in self.qsfp_ports: + return SfpUtilBase.get_transceiver_dom_info_dict(self, port_num) + else: + transceiver_dom_info_dict = {} + + offset = 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, "rb") + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom(None, 1) + if sfpd_obj is None: + return None + + dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return None + + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VLOT_OFFSET), SFP_VOLT_WIDTH) + 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 + + diff --git a/device/inventec/x86_64-inventec_d6356-r0/sensors.conf b/device/inventec/x86_64-inventec_d6356-r0/sensors.conf new file mode 100644 index 000000000000..3a056f7ca99f --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/sensors.conf @@ -0,0 +1,109 @@ +# libsensors configuration file +chip "ucd90160-*" + ignore temp1 + +chip "pch_haswell-*" + label temp1 "PCH Temperature" + +chip "tmp75-i2c-*-0048" + label temp1 "CPU Board Temperature" + +chip "tmp75-i2c-*-004a" + label temp1 "FrontSide Temperature" + +chip "tmp75-i2c-*-004e" + label temp1 "NearASIC Temperature" + +chip "tmp75-i2c-*-004d" + label temp1 "RearSide Temperature" + +chip "inv_cpld-i2c-*-77" + label fan1 "FanModule1 Front RPM" + label fan2 "FanModule1 Rear RPM" + label fan3 "FanModule2 Front RPM" + label fan4 "FanModule2 Rear RPM" + label fan5 "FanModule3 Front RPM" + label fan6 "FanModule3 Rear RPM" + label fan7 "FanModule4 Front RPM" + label fan8 "FanModule4 Rear RPM" + label fan9 "FanModule5 Front RPM" + label fan10 "FanModule5 Rear RPM" + label pwm1 "FanModule1 PWM (0-255)" + label pwm2 "FanModule2 PWM (0-255)" + label pwm3 "FanModule3 PWM (0-255)" + label pwm4 "FanModule4 PWM (0-255)" + label pwm5 "FanModule5 PWM (0-255)" + +chip "pmbus-i2c-*-005b" + ignore power3 + ignore curr3 + label fan1 "PSU1 Fan RPM" + label temp1 "PSU1 Temperature1" + label temp2 "PSU1 Temperature2" + label temp3 "PSU1 Temperature3" + label in1 "PSU1 Input Voltage" + label curr1 "PSU1 Input Current" + label power1 "PSU1 Input Power" + label in2 "PSU1 Output Voltage" + label curr2 "PSU1 Output Current" + label power2 "PSU1 Output Power" + label pwm1 "PSU1 PWM (0-100)" + +chip "pmbus-i2c-*-005a" + ignore power3 + ignore curr3 + label fan1 "PSU2 Fan RPM" + label temp1 "PSU2 Temperature1" + label temp2 "PSU2 Temperature2" + label temp3 "PSU2 Temperature3" + label in1 "PSU2 Input Voltage" + label curr1 "PSU2 Input Current" + label power1 "PSU2 Input Power" + label in2 "PSU2 Output Voltage" + label curr2 "PSU2 Output Current" + label power2 "PSU2 Output Power" + label pwm1 "PSU2 PWM (0-100)" + +chip "inv_psoc-*" + label temp1 "FrontSide Temperature" + label temp2 "FanBoard Temperature" + label temp3 "NearASIC Temperature" + label temp4 "Center Temperature" + + label temp5 "CPU Board Temperature" + label temp6 "ASIC Temperature" + label temp7 "PSU1 Temperature1" + label temp8 "PSU2 Temperature1" + label temp9 "PSU1 Temperature2" + label temp10 "PSU2 Temperature2" + label fan1 "FanModule1 Front RPM" + label fan2 "FanModule1 Rear RPM" + label fan3 "FanModule2 Front RPM" + label fan4 "FanModule2 Rear RPM" + label fan5 "FanModule3 Front RPM" + label fan6 "FanModule3 Rear RPM" + label fan7 "FanModule4 Front RPM" + label fan8 "FanModule4 Rear RPM" + label fan9 "FanModule5 Front RPM" + label fan10 "FanModule5 Rear RPM" + label pwm1 "FanModule1 PWM" + label pwm2 "FanModule2 PWM" + label pwm3 "FanModule3 PWM" + label pwm4 "FanModule4 PWM" + label pwm5 "FanModule5 PWM" + label pwm6 "PSU1 FAN PWM" + label pwm7 "PSU2 FAN PWM" + label fan11 "PSU1 FAN RPM" + label fan12 "PSU2 FAN RPM" + label in1 "PSU1 Input Voltage" + label in2 "PSU2 Input Voltage" + label curr1 "PSU1 Input Current" + label curr2 "PSU2 Input Current" + label power1 "PSU1 Input Power" + label power2 "PSU2 Input Power" + label in3 "PSU1 Output Voltage" + label in4 "PSU2 Output Voltage" + label curr3 "PSU1 Output Current" + label curr4 "PSU2 Output Current" + label power3 "PSU1 Output Power" + label power4 "PSU2 Output Power" diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/port_config.ini b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/port_config.ini new file mode 100644 index 000000000000..da3321b55666 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/port_config.ini @@ -0,0 +1,65 @@ +# name lanes alias index speed +Ethernet0 73,74,75,76 hundredGigE1 0 100000 +Ethernet4 65,66,67,68 hundredGigE2 1 100000 +Ethernet8 81,82,83,84 hundredGigE3 2 100000 +Ethernet12 89,90,91,92 hundredGigE4 3 100000 +Ethernet16 105,106,107,108 hundredGigE5 4 100000 +Ethernet20 97,98,99,100 hundredGigE6 5 100000 +Ethernet24 113,114,115,116 hundredGigE7 6 100000 +Ethernet28 121,122,123,124 hundredGigE8 7 100000 +Ethernet32 41,42,43,44 hundredGigE9 8 100000 +Ethernet36 33,34,35,36 hundredGigE10 9 100000 +Ethernet40 49,50,51,52 hundredGigE11 10 100000 +Ethernet44 57,58,59,60 hundredGigE12 11 100000 +Ethernet48 137,138,139,140 hundredGigE13 12 100000 +Ethernet52 129,130,131,132 hundredGigE14 13 100000 +Ethernet56 145,146,147,148 hundredGigE15 14 100000 +Ethernet60 153,154,155,156 hundredGigE16 15 100000 +Ethernet64 173,174,175,176 hundredGigE17 16 100000 +Ethernet68 165,166,167,168 hundredGigE18 17 100000 +Ethernet72 181,182,183,184 hundredGigE19 18 100000 +Ethernet76 189,190,191,192 hundredGigE20 19 100000 +Ethernet80 13,14,15,16 hundredGigE21 20 100000 +Ethernet84 5,6,7,8 hundredGigE22 21 100000 +Ethernet88 29,30,31,32 hundredGigE23 22 100000 +Ethernet92 21,22,23,24 hundredGigE24 23 100000 +Ethernet96 205,206,207,208 hundredGigE25 24 100000 +Ethernet100 197,198,199,200 hundredGigE26 25 100000 +Ethernet104 213,214,215,216 hundredGigE27 26 100000 +Ethernet108 221,222,223,224 hundredGigE28 27 100000 +Ethernet112 229,230,231,232 hundredGigE29 28 100000 +Ethernet116 237,238,239,240 hundredGigE30 29 100000 +Ethernet120 245,246,247,248 hundredGigE31 30 100000 +Ethernet124 253,254,255,256 hundredGigE32 31 100000 +Ethernet128 69,70,71,72 hundredGigE33 32 100000 +Ethernet132 77,78,79,80 hundredGigE34 33 100000 +Ethernet136 93,94,95,96 hundredGigE35 34 100000 +Ethernet140 85,86,87,88 hundredGigE36 35 100000 +Ethernet144 101,102,103,104 hundredGigE37 36 100000 +Ethernet148 109,110,111,112 hundredGigE38 37 100000 +Ethernet152 125,126,127,128 hundredGigE39 38 100000 +Ethernet156 117,118,119,120 hundredGigE40 39 100000 +Ethernet160 37,38,39,40 hundredGigE41 40 100000 +Ethernet164 45,46,47,48 hundredGigE42 41 100000 +Ethernet168 61,62,63,64 hundredGigE43 42 100000 +Ethernet172 53,54,55,56 hundredGigE44 43 100000 +Ethernet176 133,134,135,136 hundredGigE45 44 100000 +Ethernet180 141,142,143,144 hundredGigE46 45 100000 +Ethernet184 157,158,159,160 hundredGigE47 46 100000 +Ethernet188 149,150,151,152 hundredGigE48 47 100000 +Ethernet192 161,162,163,164 hundredGigE49 48 100000 +Ethernet196 169,170,171,172 hundredGigE50 49 100000 +Ethernet200 185,186,187,188 hundredGigE51 50 100000 +Ethernet204 177,178,179,180 hundredGigE52 51 100000 +Ethernet208 1,2,3,4 hundredGigE53 52 100000 +Ethernet212 9,10,11,12 hundredGigE54 53 100000 +Ethernet216 25,26,27,28 hundredGigE55 54 100000 +Ethernet220 17,18,19,20 hundredGigE56 55 100000 +Ethernet224 193,194,195,196 hundredGigE57 56 100000 +Ethernet228 201,202,203,204 hundredGigE58 57 100000 +Ethernet232 217,218,219,220 hundredGigE59 58 100000 +Ethernet236 209,210,211,212 hundredGigE60 59 100000 +Ethernet240 225,226,227,228 hundredGigE61 60 100000 +Ethernet244 233,234,235,236 hundredGigE62 61 100000 +Ethernet248 249,250,251,252 hundredGigE63 62 100000 +Ethernet252 241,242,243,244 hundredGigE64 63 100000 diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/sai.profile b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/sai.profile new file mode 100644 index 000000000000..dca8c2f68c04 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-qfx5210-64x100G.config.bcm diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/th2-qfx5210-64x100G.config.bcm b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/th2-qfx5210-64x100G.config.bcm new file mode 100644 index 000000000000..bc421a4e5152 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/th2-qfx5210-64x100G.config.bcm @@ -0,0 +1,875 @@ +# Broadcom Tomahawk SDK configuration +os=unix +schan_intr_enable=0 +l2_mem_entries=40960 +l2xmsg_mode=1 +l3_mem_entries=40960 +parity_correction=0 +parity_enable=0 +mmu_lossless=1 + +pbmp_xport_xe=0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +pbmp_oversubscribe=0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + +# platform specific setting +arl_clean_timeout_usec=15000000 +asf_mem_profile=2 +bcm_num_cos=8 +bcm_stat_flags=1 +bcm_stat_jumbo=9236 +cdma_timeout_usec=15000000 +dma_desc_timeout_usec=15000000 +ipv6_lpm_128b_enable=1 +l3_alpm_enable=2 +lpm_scaling_enable=0 +max_vp_lags=0 +miim_intr_enable=0 +module_64ports=1 +oversubscribe_mode=1 + +#add loopback port +# port 33 is the first loopback port +# portmap_33=260:10 +# port 66 is the first management port +# portmap_66=257:10 +# port 67 is the second loopback port +# portmap_67=261:10 +# port 100 is the second management port +# portmap_100=259:10 +# port 101 is the third loopback port +# portmap_101=262:10 +# port 135 is the fourth loopback port +# portmap_135=263:10 + +#Port0 +#FC18 +portmap_36=73:100 +phy_chain_rx_lane_map_physical{73.0}=0x3210 +phy_chain_tx_lane_map_physical{73.0}=0x3021 +phy_chain_rx_polarity_flip_physical{73.0}=0x0 +phy_chain_rx_polarity_flip_physical{74.0}=0x0 +phy_chain_rx_polarity_flip_physical{75.0}=0x0 +phy_chain_rx_polarity_flip_physical{76.0}=0x1 +phy_chain_tx_polarity_flip_physical{73.0}=0x0 +phy_chain_tx_polarity_flip_physical{74.0}=0x0 +phy_chain_tx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x0 +#Port1 +#FC16 +portmap_34=65:100 +phy_chain_rx_lane_map_physical{65.0}=0x3210 +phy_chain_tx_lane_map_physical{65.0}=0x3210 +phy_chain_rx_polarity_flip_physical{65.0}=0x0 +phy_chain_rx_polarity_flip_physical{66.0}=0x0 +phy_chain_rx_polarity_flip_physical{67.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x0 +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_tx_polarity_flip_physical{66.0}=0x0 +phy_chain_tx_polarity_flip_physical{67.0}=0x0 +phy_chain_tx_polarity_flip_physical{68.0}=0x0 +#Port2 +#FC20 +portmap_38=81:100 +phy_chain_rx_lane_map_physical{81.0}=0x1230 +phy_chain_tx_lane_map_physical{81.0}=0x1032 +phy_chain_rx_polarity_flip_physical{81.0}=0x1 +phy_chain_rx_polarity_flip_physical{82.0}=0x0 +phy_chain_rx_polarity_flip_physical{83.0}=0x1 +phy_chain_rx_polarity_flip_physical{84.0}=0x0 +phy_chain_tx_polarity_flip_physical{81.0}=0x1 +phy_chain_tx_polarity_flip_physical{82.0}=0x1 +phy_chain_tx_polarity_flip_physical{83.0}=0x1 +phy_chain_tx_polarity_flip_physical{84.0}=0x0 +#Port3 +#FC22 +portmap_40=89:100 +phy_chain_rx_lane_map_physical{89.0}=0x0132 +phy_chain_tx_lane_map_physical{89.0}=0x1203 +phy_chain_rx_polarity_flip_physical{89.0}=0x1 +phy_chain_rx_polarity_flip_physical{90.0}=0x0 +phy_chain_rx_polarity_flip_physical{91.0}=0x0 +phy_chain_rx_polarity_flip_physical{92.0}=0x1 +phy_chain_tx_polarity_flip_physical{89.0}=0x1 +phy_chain_tx_polarity_flip_physical{90.0}=0x0 +phy_chain_tx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x1 +#Port4 +#FC26 +portmap_44=105:100 +phy_chain_rx_lane_map_physical{105.0}=0x3210 +phy_chain_tx_lane_map_physical{105.0}=0x0231 +phy_chain_rx_polarity_flip_physical{105.0}=0x0 +phy_chain_rx_polarity_flip_physical{106.0}=0x0 +phy_chain_rx_polarity_flip_physical{107.0}=0x0 +phy_chain_rx_polarity_flip_physical{108.0}=0x1 +phy_chain_tx_polarity_flip_physical{105.0}=0x0 +phy_chain_tx_polarity_flip_physical{106.0}=0x1 +phy_chain_tx_polarity_flip_physical{107.0}=0x0 +phy_chain_tx_polarity_flip_physical{108.0}=0x1 +#Port5 +#FC24 +portmap_42=97:100 +phy_chain_rx_lane_map_physical{97.0}=0x0213 +phy_chain_tx_lane_map_physical{97.0}=0x3210 +phy_chain_rx_polarity_flip_physical{97.0}=0x1 +phy_chain_rx_polarity_flip_physical{98.0}=0x0 +phy_chain_rx_polarity_flip_physical{99.0}=0x0 +phy_chain_rx_polarity_flip_physical{100.0}=0x1 +phy_chain_tx_polarity_flip_physical{97.0}=0x1 +phy_chain_tx_polarity_flip_physical{98.0}=0x1 +phy_chain_tx_polarity_flip_physical{99.0}=0x0 +phy_chain_tx_polarity_flip_physical{100.0}=0x0 +#Port6 +#FC 28 +portmap_46=113:100 +phy_chain_rx_lane_map_physical{113.0}=0x3021 +phy_chain_tx_lane_map_physical{113.0}=0x0312 +phy_chain_rx_polarity_flip_physical{113.0}=0x0 +phy_chain_rx_polarity_flip_physical{114.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x1 +phy_chain_rx_polarity_flip_physical{116.0}=0x0 +phy_chain_tx_polarity_flip_physical{113.0}=0x1 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x0 +phy_chain_tx_polarity_flip_physical{116.0}=0x1 +#Port7 +#FC30 +portmap_48=121:100 +phy_chain_rx_lane_map_physical{121.0}=0x3021 +phy_chain_tx_lane_map_physical{121.0}=0x2130 +phy_chain_rx_polarity_flip_physical{121.0}=0x0 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{124.0}=0x0 +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_tx_polarity_flip_physical{122.0}=0x1 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 +#Port8 +#FC10 +portmap_11=41:100 +phy_chain_rx_lane_map_physical{41.0}=0x0132 +phy_chain_tx_lane_map_physical{41.0}=0x1302 +phy_chain_rx_polarity_flip_physical{41.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x0 +phy_chain_rx_polarity_flip_physical{43.0}=0x0 +phy_chain_rx_polarity_flip_physical{44.0}=0x0 +phy_chain_tx_polarity_flip_physical{41.0}=0x1 +phy_chain_tx_polarity_flip_physical{42.0}=0x0 +phy_chain_tx_polarity_flip_physical{43.0}=0x0 +phy_chain_tx_polarity_flip_physical{44.0}=0x0 +#Port9 +#FC8 +portmap_9=33:100 +phy_chain_rx_lane_map_physical{33.0}=0x2310 +phy_chain_tx_lane_map_physical{33.0}=0x0213 +phy_chain_rx_polarity_flip_physical{33.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x1 +phy_chain_rx_polarity_flip_physical{35.0}=0x0 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_tx_polarity_flip_physical{34.0}=0x1 +phy_chain_tx_polarity_flip_physical{35.0}=0x0 +phy_chain_tx_polarity_flip_physical{36.0}=0x0 +#Port10 +#FC12 +portmap_13=49:100 +phy_chain_rx_lane_map_physical{49.0}=0x3210 +phy_chain_tx_lane_map_physical{49.0}=0x3102 +phy_chain_rx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x0 +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 +#Port11 +#FC14 +portmap_15=57:100 +phy_chain_rx_lane_map_physical{57.0}=0x3210 +phy_chain_tx_lane_map_physical{57.0}=0x1302 +phy_chain_rx_polarity_flip_physical{57.0}=0x1 +phy_chain_rx_polarity_flip_physical{58.0}=0x0 +phy_chain_rx_polarity_flip_physical{59.0}=0x1 +phy_chain_rx_polarity_flip_physical{60.0}=0x0 +phy_chain_tx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x0 +phy_chain_tx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x1 +#Port12 +#FC34 +portmap_70=137:100 +phy_chain_rx_lane_map_physical{137.0}=0x3210 +phy_chain_tx_lane_map_physical{137.0}=0x0213 +phy_chain_rx_polarity_flip_physical{137.0}=0x0 +phy_chain_rx_polarity_flip_physical{138.0}=0x0 +phy_chain_rx_polarity_flip_physical{139.0}=0x1 +phy_chain_rx_polarity_flip_physical{140.0}=0x0 +phy_chain_tx_polarity_flip_physical{137.0}=0x1 +phy_chain_tx_polarity_flip_physical{138.0}=0x0 +phy_chain_tx_polarity_flip_physical{139.0}=0x0 +phy_chain_tx_polarity_flip_physical{140.0}=0x0 +#Port13 +#FC32 +portmap_68=129:100 +phy_chain_rx_lane_map_physical{129.0}=0x3021 +phy_chain_tx_lane_map_physical{129.0}=0x1203 +phy_chain_rx_polarity_flip_physical{129.0}=0x1 +phy_chain_rx_polarity_flip_physical{130.0}=0x0 +phy_chain_rx_polarity_flip_physical{131.0}=0x0 +phy_chain_rx_polarity_flip_physical{132.0}=0x0 +phy_chain_tx_polarity_flip_physical{129.0}=0x1 +phy_chain_tx_polarity_flip_physical{130.0}=0x1 +phy_chain_tx_polarity_flip_physical{131.0}=0x1 +phy_chain_tx_polarity_flip_physical{132.0}=0x1 +#Port14 +#FC36 +portmap_72=145:100 +phy_chain_rx_lane_map_physical{145.0}=0x0213 +phy_chain_tx_lane_map_physical{145.0}=0x2301 +phy_chain_rx_polarity_flip_physical{145.0}=0x1 +phy_chain_rx_polarity_flip_physical{146.0}=0x1 +phy_chain_rx_polarity_flip_physical{147.0}=0x0 +phy_chain_rx_polarity_flip_physical{148.0}=0x0 +phy_chain_tx_polarity_flip_physical{145.0}=0x0 +phy_chain_tx_polarity_flip_physical{146.0}=0x0 +phy_chain_tx_polarity_flip_physical{147.0}=0x0 +phy_chain_tx_polarity_flip_physical{148.0}=0x1 +#Port15 +#FC38 +portmap_74=153:100 +phy_chain_rx_lane_map_physical{153.0}=0x0213 +phy_chain_tx_lane_map_physical{153.0}=0x1302 +phy_chain_rx_polarity_flip_physical{153.0}=0x1 +phy_chain_rx_polarity_flip_physical{154.0}=0x0 +phy_chain_rx_polarity_flip_physical{155.0}=0x1 +phy_chain_rx_polarity_flip_physical{156.0}=0x1 +phy_chain_tx_polarity_flip_physical{153.0}=0x0 +phy_chain_tx_polarity_flip_physical{154.0}=0x1 +phy_chain_tx_polarity_flip_physical{155.0}=0x0 +phy_chain_tx_polarity_flip_physical{156.0}=0x0 +#Port16 +#FC43 +portmap_79=173:100 +phy_chain_rx_lane_map_physical{173.0}=0x1032 +phy_chain_tx_lane_map_physical{173.0}=0x1203 +phy_chain_rx_polarity_flip_physical{173.0}=0x0 +phy_chain_rx_polarity_flip_physical{174.0}=0x0 +phy_chain_rx_polarity_flip_physical{175.0}=0x0 +phy_chain_rx_polarity_flip_physical{176.0}=0x0 +phy_chain_tx_polarity_flip_physical{173.0}=0x1 +phy_chain_tx_polarity_flip_physical{174.0}=0x1 +phy_chain_tx_polarity_flip_physical{175.0}=0x0 +phy_chain_tx_polarity_flip_physical{176.0}=0x1 +#Port17 +#FC41 +portmap_77=165:100 +phy_chain_rx_lane_map_physical{165.0}=0x1230 +phy_chain_tx_lane_map_physical{165.0}=0x2130 +phy_chain_rx_polarity_flip_physical{165.0}=0x1 +phy_chain_rx_polarity_flip_physical{166.0}=0x0 +phy_chain_rx_polarity_flip_physical{167.0}=0x1 +phy_chain_rx_polarity_flip_physical{168.0}=0x1 +phy_chain_tx_polarity_flip_physical{165.0}=0x1 +phy_chain_tx_polarity_flip_physical{166.0}=0x0 +phy_chain_tx_polarity_flip_physical{167.0}=0x1 +phy_chain_tx_polarity_flip_physical{168.0}=0x0 +#Port18 +#FC45 +portmap_81=181:100 +phy_chain_rx_lane_map_physical{181.0}=0x0312 +phy_chain_tx_lane_map_physical{181.0}=0x3120 +phy_chain_rx_polarity_flip_physical{181.0}=0x0 +phy_chain_rx_polarity_flip_physical{182.0}=0x1 +phy_chain_rx_polarity_flip_physical{183.0}=0x1 +phy_chain_rx_polarity_flip_physical{184.0}=0x0 +phy_chain_tx_polarity_flip_physical{181.0}=0x0 +phy_chain_tx_polarity_flip_physical{182.0}=0x0 +phy_chain_tx_polarity_flip_physical{183.0}=0x1 +phy_chain_tx_polarity_flip_physical{184.0}=0x0 +#Port19 +#FC47 +portmap_83=189:100 +phy_chain_rx_lane_map_physical{189.0}=0x0132 +phy_chain_tx_lane_map_physical{189.0}=0x3210 +phy_chain_rx_polarity_flip_physical{189.0}=0x0 +phy_chain_rx_polarity_flip_physical{190.0}=0x1 +phy_chain_rx_polarity_flip_physical{191.0}=0x1 +phy_chain_rx_polarity_flip_physical{192.0}=0x1 +phy_chain_tx_polarity_flip_physical{189.0}=0x1 +phy_chain_tx_polarity_flip_physical{190.0}=0x0 +phy_chain_tx_polarity_flip_physical{191.0}=0x0 +phy_chain_tx_polarity_flip_physical{192.0}=0x0 +#Port20 +#FC3 +portmap_4=13:100 +phy_chain_rx_lane_map_physical{13.0}=0x3120 +phy_chain_tx_lane_map_physical{13.0}=0x3210 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x0 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_rx_polarity_flip_physical{16.0}=0x1 +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x0 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_tx_polarity_flip_physical{16.0}=0x1 +#Port21 +#FC1 +portmap_2=5:100 +phy_chain_rx_lane_map_physical{5.0}=0x0213 +phy_chain_tx_lane_map_physical{5.0}=0x0321 +phy_chain_rx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{6.0}=0x0 +phy_chain_rx_polarity_flip_physical{7.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 +phy_chain_tx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_tx_polarity_flip_physical{7.0}=0x0 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +#Port22 +#FC7 +portmap_8=29:100 +phy_chain_rx_lane_map_physical{29.0}=0x3021 +phy_chain_tx_lane_map_physical{29.0}=0x2130 +phy_chain_rx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x1 +phy_chain_tx_polarity_flip_physical{29.0}=0x1 +phy_chain_tx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_tx_polarity_flip_physical{32.0}=0x0 +#Port23 +#FC5 +portmap_6=21:100 +phy_chain_rx_lane_map_physical{21.0}=0x0321 +phy_chain_tx_lane_map_physical{21.0}=0x0123 +phy_chain_rx_polarity_flip_physical{21.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x0 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_rx_polarity_flip_physical{24.0}=0x0 +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x1 +phy_chain_tx_polarity_flip_physical{24.0}=0x1 +#Port24 +#FC51 +portmap_105=205:100 +phy_chain_rx_lane_map_physical{205.0}=0x0132 +phy_chain_tx_lane_map_physical{205.0}=0x1230 +phy_chain_rx_polarity_flip_physical{205.0}=0x1 +phy_chain_rx_polarity_flip_physical{206.0}=0x1 +phy_chain_rx_polarity_flip_physical{207.0}=0x1 +phy_chain_rx_polarity_flip_physical{208.0}=0x0 +phy_chain_tx_polarity_flip_physical{205.0}=0x0 +phy_chain_tx_polarity_flip_physical{206.0}=0x1 +phy_chain_tx_polarity_flip_physical{207.0}=0x0 +phy_chain_tx_polarity_flip_physical{208.0}=0x1 +#Port25 +#FC49 +portmap_103=197:100 +phy_chain_rx_lane_map_physical{197.0}=0x1230 +phy_chain_tx_lane_map_physical{197.0}=0x3021 +phy_chain_rx_polarity_flip_physical{197.0}=0x0 +phy_chain_rx_polarity_flip_physical{198.0}=0x0 +phy_chain_rx_polarity_flip_physical{199.0}=0x0 +phy_chain_rx_polarity_flip_physical{200.0}=0x0 +phy_chain_tx_polarity_flip_physical{197.0}=0x1 +phy_chain_tx_polarity_flip_physical{198.0}=0x0 +phy_chain_tx_polarity_flip_physical{199.0}=0x1 +phy_chain_tx_polarity_flip_physical{200.0}=0x0 +#Port26 +#FC53 +portmap_107=213:100 +phy_chain_rx_lane_map_physical{213.0}=0x3210 +phy_chain_tx_lane_map_physical{213.0}=0x1230 +phy_chain_rx_polarity_flip_physical{213.0}=0x0 +phy_chain_rx_polarity_flip_physical{214.0}=0x1 +phy_chain_rx_polarity_flip_physical{215.0}=0x0 +phy_chain_rx_polarity_flip_physical{216.0}=0x1 +phy_chain_tx_polarity_flip_physical{213.0}=0x0 +phy_chain_tx_polarity_flip_physical{214.0}=0x0 +phy_chain_tx_polarity_flip_physical{215.0}=0x0 +phy_chain_tx_polarity_flip_physical{216.0}=0x1 +#Port27 +#FC55 +portmap_109=221:100 +phy_chain_rx_lane_map_physical{221.0}=0x3210 +phy_chain_tx_lane_map_physical{221.0}=0x3210 +phy_chain_rx_polarity_flip_physical{221.0}=0x1 +phy_chain_rx_polarity_flip_physical{222.0}=0x1 +phy_chain_rx_polarity_flip_physical{223.0}=0x0 +phy_chain_rx_polarity_flip_physical{224.0}=0x0 +phy_chain_tx_polarity_flip_physical{221.0}=0x0 +phy_chain_tx_polarity_flip_physical{222.0}=0x0 +phy_chain_tx_polarity_flip_physical{223.0}=0x0 +phy_chain_tx_polarity_flip_physical{224.0}=0x0 +#Port28 +#FC57 +portmap_111=229:100 +phy_chain_rx_lane_map_physical{229.0}=0x2301 +phy_chain_tx_lane_map_physical{229.0}=0x3210 +phy_chain_rx_polarity_flip_physical{229.0}=0x1 +phy_chain_rx_polarity_flip_physical{230.0}=0x1 +phy_chain_rx_polarity_flip_physical{231.0}=0x0 +phy_chain_rx_polarity_flip_physical{232.0}=0x1 +phy_chain_tx_polarity_flip_physical{229.0}=0x0 +phy_chain_tx_polarity_flip_physical{230.0}=0x1 +phy_chain_tx_polarity_flip_physical{231.0}=0x0 +phy_chain_tx_polarity_flip_physical{232.0}=0x0 +#Port29 +#FC59 +portmap_113=237:100 +phy_chain_rx_lane_map_physical{237.0}=0x0123 +phy_chain_tx_lane_map_physical{237.0}=0x3210 +phy_chain_rx_polarity_flip_physical{237.0}=0x1 +phy_chain_rx_polarity_flip_physical{238.0}=0x0 +phy_chain_rx_polarity_flip_physical{239.0}=0x1 +phy_chain_rx_polarity_flip_physical{240.0}=0x1 +phy_chain_tx_polarity_flip_physical{237.0}=0x1 +phy_chain_tx_polarity_flip_physical{238.0}=0x1 +phy_chain_tx_polarity_flip_physical{239.0}=0x0 +phy_chain_tx_polarity_flip_physical{240.0}=0x0 +#Port30 +#FC61 +portmap_115=245:100 +phy_chain_rx_lane_map_physical{245.0}=0x0213 +phy_chain_tx_lane_map_physical{245.0}=0x3210 +phy_chain_rx_polarity_flip_physical{245.0}=0x0 +phy_chain_rx_polarity_flip_physical{246.0}=0x0 +phy_chain_rx_polarity_flip_physical{247.0}=0x1 +phy_chain_rx_polarity_flip_physical{248.0}=0x1 +phy_chain_tx_polarity_flip_physical{245.0}=0x1 +phy_chain_tx_polarity_flip_physical{246.0}=0x0 +phy_chain_tx_polarity_flip_physical{247.0}=0x1 +phy_chain_tx_polarity_flip_physical{248.0}=0x0 +#Port31 +#FC63 +portmap_117=253:100 +phy_chain_rx_lane_map_physical{253.0}=0x0213 +phy_chain_tx_lane_map_physical{253.0}=0x0312 +phy_chain_rx_polarity_flip_physical{253.0}=0x0 +phy_chain_rx_polarity_flip_physical{254.0}=0x0 +phy_chain_rx_polarity_flip_physical{255.0}=0x0 +phy_chain_rx_polarity_flip_physical{256.0}=0x1 +phy_chain_tx_polarity_flip_physical{253.0}=0x0 +phy_chain_tx_polarity_flip_physical{254.0}=0x1 +phy_chain_tx_polarity_flip_physical{255.0}=0x0 +phy_chain_tx_polarity_flip_physical{256.0}=0x0 +#Port32 +#FC17 +portmap_35=69:100 +phy_chain_rx_lane_map_physical{69.0}=0x1032 +phy_chain_tx_lane_map_physical{69.0}=0x3102 +phy_chain_rx_polarity_flip_physical{69.0}=0x1 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{71.0}=0x0 +phy_chain_rx_polarity_flip_physical{72.0}=0x1 +phy_chain_tx_polarity_flip_physical{69.0}=0x0 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_tx_polarity_flip_physical{72.0}=0x1 +#Port33 +#FC19 +portmap_37=77:100 +phy_chain_rx_lane_map_physical{77.0}=0x1230 +phy_chain_tx_lane_map_physical{77.0}=0x3021 +phy_chain_rx_polarity_flip_physical{77.0}=0x1 +phy_chain_rx_polarity_flip_physical{78.0}=0x0 +phy_chain_rx_polarity_flip_physical{79.0}=0x1 +phy_chain_rx_polarity_flip_physical{80.0}=0x0 +phy_chain_tx_polarity_flip_physical{77.0}=0x0 +phy_chain_tx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x0 +#Port34 +#FC23 +portmap_41=93:100 +phy_chain_rx_lane_map_physical{93.0}=0x1032 +phy_chain_tx_lane_map_physical{93.0}=0x0231 +phy_chain_rx_polarity_flip_physical{93.0}=0x1 +phy_chain_rx_polarity_flip_physical{94.0}=0x1 +phy_chain_rx_polarity_flip_physical{95.0}=0x1 +phy_chain_rx_polarity_flip_physical{96.0}=0x1 +phy_chain_tx_polarity_flip_physical{93.0}=0x0 +phy_chain_tx_polarity_flip_physical{94.0}=0x1 +phy_chain_tx_polarity_flip_physical{95.0}=0x1 +phy_chain_tx_polarity_flip_physical{96.0}=0x1 +#Port35 +#FC21 +portmap_39=85:100 +phy_chain_rx_lane_map_physical{85.0}=0x0312 +phy_chain_tx_lane_map_physical{85.0}=0x1230 +phy_chain_rx_polarity_flip_physical{85.0}=0x0 +phy_chain_rx_polarity_flip_physical{86.0}=0x0 +phy_chain_rx_polarity_flip_physical{87.0}=0x0 +phy_chain_rx_polarity_flip_physical{88.0}=0x1 +phy_chain_tx_polarity_flip_physical{85.0}=0x1 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_tx_polarity_flip_physical{88.0}=0x0 +#Port36 +#FC25 +portmap_43=101:100 +phy_chain_rx_lane_map_physical{101.0}=0x1302 +phy_chain_tx_lane_map_physical{101.0}=0x0213 +phy_chain_rx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{102.0}=0x0 +phy_chain_rx_polarity_flip_physical{103.0}=0x0 +phy_chain_rx_polarity_flip_physical{104.0}=0x0 +phy_chain_tx_polarity_flip_physical{101.0}=0x0 +phy_chain_tx_polarity_flip_physical{102.0}=0x1 +phy_chain_tx_polarity_flip_physical{103.0}=0x0 +phy_chain_tx_polarity_flip_physical{104.0}=0x1 +#Port37 +#FC27 +portmap_45=109:100 +phy_chain_rx_lane_map_physical{109.0}=0x0213 +phy_chain_tx_lane_map_physical{109.0}=0x1032 +phy_chain_rx_polarity_flip_physical{109.0}=0x1 +phy_chain_rx_polarity_flip_physical{110.0}=0x1 +phy_chain_rx_polarity_flip_physical{111.0}=0x0 +phy_chain_rx_polarity_flip_physical{112.0}=0x0 +phy_chain_tx_polarity_flip_physical{109.0}=0x0 +phy_chain_tx_polarity_flip_physical{110.0}=0x1 +phy_chain_tx_polarity_flip_physical{111.0}=0x1 +phy_chain_tx_polarity_flip_physical{112.0}=0x1 +#Port38 +#FC31 +portmap_49=125:100 +phy_chain_rx_lane_map_physical{125.0}=0x2130 +phy_chain_tx_lane_map_physical{125.0}=0x1203 +phy_chain_rx_polarity_flip_physical{125.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x0 +phy_chain_rx_polarity_flip_physical{127.0}=0x1 +phy_chain_rx_polarity_flip_physical{128.0}=0x1 +phy_chain_tx_polarity_flip_physical{125.0}=0x0 +phy_chain_tx_polarity_flip_physical{126.0}=0x1 +phy_chain_tx_polarity_flip_physical{127.0}=0x1 +phy_chain_tx_polarity_flip_physical{128.0}=0x1 +#Port39 +#FC29 +portmap_47=117:100 +phy_chain_rx_lane_map_physical{117.0}=0x3102 +phy_chain_tx_lane_map_physical{117.0}=0x2310 +phy_chain_rx_polarity_flip_physical{117.0}=0x1 +phy_chain_rx_polarity_flip_physical{118.0}=0x0 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{120.0}=0x0 +phy_chain_tx_polarity_flip_physical{117.0}=0x1 +phy_chain_tx_polarity_flip_physical{118.0}=0x0 +phy_chain_tx_polarity_flip_physical{119.0}=0x1 +phy_chain_tx_polarity_flip_physical{120.0}=0x0 +#Port40 +#FC9 +portmap_10=37:100 +phy_chain_rx_lane_map_physical{37.0}=0x3210 +phy_chain_tx_lane_map_physical{37.0}=0x1302 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x0 +phy_chain_rx_polarity_flip_physical{39.0}=0x0 +phy_chain_rx_polarity_flip_physical{40.0}=0x0 +phy_chain_tx_polarity_flip_physical{37.0}=0x1 +phy_chain_tx_polarity_flip_physical{38.0}=0x0 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_tx_polarity_flip_physical{40.0}=0x1 +#Port41 +#FC11 +portmap_12=45:100 +phy_chain_rx_lane_map_physical{45.0}=0x3210 +phy_chain_tx_lane_map_physical{45.0}=0x0123 +phy_chain_rx_polarity_flip_physical{45.0}=0x0 +phy_chain_rx_polarity_flip_physical{46.0}=0x0 +phy_chain_rx_polarity_flip_physical{47.0}=0x0 +phy_chain_rx_polarity_flip_physical{48.0}=0x0 +phy_chain_tx_polarity_flip_physical{45.0}=0x0 +phy_chain_tx_polarity_flip_physical{46.0}=0x1 +phy_chain_tx_polarity_flip_physical{47.0}=0x0 +phy_chain_tx_polarity_flip_physical{48.0}=0x1 +#Port42 +#FC15 +portmap_16=61:100 +phy_chain_rx_lane_map_physical{61.0}=0x3210 +phy_chain_tx_lane_map_physical{61.0}=0x1230 +phy_chain_rx_polarity_flip_physical{61.0}=0x0 +phy_chain_rx_polarity_flip_physical{62.0}=0x1 +phy_chain_rx_polarity_flip_physical{63.0}=0x0 +phy_chain_rx_polarity_flip_physical{64.0}=0x0 +phy_chain_tx_polarity_flip_physical{61.0}=0x0 +phy_chain_tx_polarity_flip_physical{62.0}=0x1 +phy_chain_tx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x0 +#Port43 +#FC13 +portmap_14=53:100 +phy_chain_rx_lane_map_physical{53.0}=0x3210 +phy_chain_tx_lane_map_physical{53.0}=0x3210 +phy_chain_rx_polarity_flip_physical{53.0}=0x0 +phy_chain_rx_polarity_flip_physical{54.0}=0x0 +phy_chain_rx_polarity_flip_physical{55.0}=0x1 +phy_chain_rx_polarity_flip_physical{56.0}=0x0 +phy_chain_tx_polarity_flip_physical{53.0}=0x1 +phy_chain_tx_polarity_flip_physical{54.0}=0x1 +phy_chain_tx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x0 +#Port44 +#FC33 +portmap_69=133:100 +phy_chain_rx_lane_map_physical{133.0}=0x0312 +phy_chain_tx_lane_map_physical{133.0}=0x2310 +phy_chain_rx_polarity_flip_physical{133.0}=0x0 +phy_chain_rx_polarity_flip_physical{134.0}=0x0 +phy_chain_rx_polarity_flip_physical{135.0}=0x1 +phy_chain_rx_polarity_flip_physical{136.0}=0x0 +phy_chain_tx_polarity_flip_physical{133.0}=0x0 +phy_chain_tx_polarity_flip_physical{134.0}=0x1 +phy_chain_tx_polarity_flip_physical{135.0}=0x0 +phy_chain_tx_polarity_flip_physical{136.0}=0x1 +#Port45 +#FC35 +portmap_71=141:100 +phy_chain_rx_lane_map_physical{141.0}=0x3012 +phy_chain_tx_lane_map_physical{141.0}=0x0123 +phy_chain_rx_polarity_flip_physical{141.0}=0x1 +phy_chain_rx_polarity_flip_physical{142.0}=0x0 +phy_chain_rx_polarity_flip_physical{143.0}=0x1 +phy_chain_rx_polarity_flip_physical{144.0}=0x0 +phy_chain_tx_polarity_flip_physical{141.0}=0x1 +phy_chain_tx_polarity_flip_physical{142.0}=0x1 +phy_chain_tx_polarity_flip_physical{143.0}=0x0 +phy_chain_tx_polarity_flip_physical{144.0}=0x0 +#Port46 +#FC39 +portmap_75=157:100 +phy_chain_rx_lane_map_physical{157.0}=0x2103 +phy_chain_tx_lane_map_physical{157.0}=0x0231 +phy_chain_rx_polarity_flip_physical{157.0}=0x0 +phy_chain_rx_polarity_flip_physical{158.0}=0x0 +phy_chain_rx_polarity_flip_physical{159.0}=0x1 +phy_chain_rx_polarity_flip_physical{160.0}=0x0 +phy_chain_tx_polarity_flip_physical{157.0}=0x0 +phy_chain_tx_polarity_flip_physical{158.0}=0x1 +phy_chain_tx_polarity_flip_physical{159.0}=0x0 +phy_chain_tx_polarity_flip_physical{160.0}=0x0 +#Port47 +#FC37 +portmap_73=149:100 +phy_chain_rx_lane_map_physical{149.0}=0x3120 +phy_chain_tx_lane_map_physical{149.0}=0x1023 +phy_chain_rx_polarity_flip_physical{149.0}=0x0 +phy_chain_rx_polarity_flip_physical{150.0}=0x1 +phy_chain_rx_polarity_flip_physical{151.0}=0x0 +phy_chain_rx_polarity_flip_physical{152.0}=0x0 +phy_chain_tx_polarity_flip_physical{149.0}=0x1 +phy_chain_tx_polarity_flip_physical{150.0}=0x0 +phy_chain_tx_polarity_flip_physical{151.0}=0x0 +phy_chain_tx_polarity_flip_physical{152.0}=0x1 +#Port48 +#FC40 +portmap_76=161:100 +phy_chain_rx_lane_map_physical{161.0}=0x3012 +phy_chain_tx_lane_map_physical{161.0}=0x1023 +phy_chain_rx_polarity_flip_physical{161.0}=0x1 +phy_chain_rx_polarity_flip_physical{162.0}=0x1 +phy_chain_rx_polarity_flip_physical{163.0}=0x0 +phy_chain_rx_polarity_flip_physical{164.0}=0x0 +phy_chain_tx_polarity_flip_physical{161.0}=0x0 +phy_chain_tx_polarity_flip_physical{162.0}=0x1 +phy_chain_tx_polarity_flip_physical{163.0}=0x0 +phy_chain_tx_polarity_flip_physical{164.0}=0x0 +#Port49 +#FC42 +portmap_78=169:100 +phy_chain_rx_lane_map_physical{169.0}=0x3210 +phy_chain_tx_lane_map_physical{169.0}=0x2031 +phy_chain_rx_polarity_flip_physical{169.0}=0x0 +phy_chain_rx_polarity_flip_physical{170.0}=0x1 +phy_chain_rx_polarity_flip_physical{171.0}=0x0 +phy_chain_rx_polarity_flip_physical{172.0}=0x0 +phy_chain_tx_polarity_flip_physical{169.0}=0x1 +phy_chain_tx_polarity_flip_physical{170.0}=0x0 +phy_chain_tx_polarity_flip_physical{171.0}=0x0 +phy_chain_tx_polarity_flip_physical{172.0}=0x0 +#Port50 +#FC46 +portmap_82=185:100 +phy_chain_rx_lane_map_physical{185.0}=0x2310 +phy_chain_tx_lane_map_physical{185.0}=0x3021 +phy_chain_rx_polarity_flip_physical{185.0}=0x1 +phy_chain_rx_polarity_flip_physical{186.0}=0x0 +phy_chain_rx_polarity_flip_physical{187.0}=0x1 +phy_chain_rx_polarity_flip_physical{188.0}=0x0 +phy_chain_tx_polarity_flip_physical{185.0}=0x0 +phy_chain_tx_polarity_flip_physical{186.0}=0x1 +phy_chain_tx_polarity_flip_physical{187.0}=0x0 +phy_chain_tx_polarity_flip_physical{188.0}=0x0 +#Port51 +#FC44 +portmap_80=177:100 +phy_chain_rx_lane_map_physical{177.0}=0x1032 +phy_chain_tx_lane_map_physical{177.0}=0x2301 +phy_chain_rx_polarity_flip_physical{177.0}=0x1 +phy_chain_rx_polarity_flip_physical{178.0}=0x1 +phy_chain_rx_polarity_flip_physical{179.0}=0x0 +phy_chain_rx_polarity_flip_physical{180.0}=0x1 +phy_chain_tx_polarity_flip_physical{177.0}=0x1 +phy_chain_tx_polarity_flip_physical{178.0}=0x1 +phy_chain_tx_polarity_flip_physical{179.0}=0x1 +phy_chain_tx_polarity_flip_physical{180.0}=0x0 +#Port52 +#FC6 +portmap_7=25:100 +phy_chain_rx_lane_map_physical{25.0}=0x3102 +phy_chain_tx_lane_map_physical{25.0}=0x0132 +phy_chain_rx_polarity_flip_physical{25.0}=0x0 +phy_chain_rx_polarity_flip_physical{26.0}=0x0 +phy_chain_rx_polarity_flip_physical{27.0}=0x1 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_tx_polarity_flip_physical{26.0}=0x1 +phy_chain_tx_polarity_flip_physical{27.0}=0x0 +phy_chain_tx_polarity_flip_physical{28.0}=0x1 +#Port53 +#FC4 +portmap_5=17:100 +phy_chain_rx_lane_map_physical{17.0}=0x3120 +phy_chain_tx_lane_map_physical{17.0}=0x3021 +phy_chain_rx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{18.0}=0x1 +phy_chain_rx_polarity_flip_physical{19.0}=0x0 +phy_chain_rx_polarity_flip_physical{20.0}=0x0 +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_tx_polarity_flip_physical{18.0}=0x0 +phy_chain_tx_polarity_flip_physical{19.0}=0x1 +phy_chain_tx_polarity_flip_physical{20.0}=0x0 +#Port54 +#FC0 +portmap_1=1:100 +phy_chain_rx_lane_map_physical{1.0}=0x2130 +phy_chain_tx_lane_map_physical{1.0}=0x1203 +phy_chain_rx_polarity_flip_physical{1.0}=0x1 +phy_chain_rx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{3.0}=0x1 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{4.0}=0x1 +#Port55 +#FC2 +portmap_3=9:100 +phy_chain_rx_lane_map_physical{9.0}=0x1203 +phy_chain_tx_lane_map_physical{9.0}=0x1230 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{10.0}=0x1 +phy_chain_rx_polarity_flip_physical{11.0}=0x0 +phy_chain_rx_polarity_flip_physical{12.0}=0x0 +phy_chain_tx_polarity_flip_physical{9.0}=0x1 +phy_chain_tx_polarity_flip_physical{10.0}=0x0 +phy_chain_tx_polarity_flip_physical{11.0}=0x1 +phy_chain_tx_polarity_flip_physical{12.0}=0x0 +#Port56 +#FC48 +portmap_102=193:100 +phy_chain_rx_lane_map_physical{193.0}=0x2103 +phy_chain_tx_lane_map_physical{193.0}=0x1230 +phy_chain_rx_polarity_flip_physical{193.0}=0x0 +phy_chain_rx_polarity_flip_physical{194.0}=0x1 +phy_chain_rx_polarity_flip_physical{195.0}=0x0 +phy_chain_rx_polarity_flip_physical{196.0}=0x1 +phy_chain_tx_polarity_flip_physical{193.0}=0x0 +phy_chain_tx_polarity_flip_physical{194.0}=0x0 +phy_chain_tx_polarity_flip_physical{195.0}=0x1 +phy_chain_tx_polarity_flip_physical{196.0}=0x0 +#Port57 +#FC50 +portmap_104=201:100 +phy_chain_rx_lane_map_physical{201.0}=0x0321 +phy_chain_tx_lane_map_physical{201.0}=0x3021 +phy_chain_rx_polarity_flip_physical{201.0}=0x0 +phy_chain_rx_polarity_flip_physical{202.0}=0x0 +phy_chain_rx_polarity_flip_physical{203.0}=0x1 +phy_chain_rx_polarity_flip_physical{204.0}=0x0 +phy_chain_tx_polarity_flip_physical{201.0}=0x1 +phy_chain_tx_polarity_flip_physical{202.0}=0x1 +phy_chain_tx_polarity_flip_physical{203.0}=0x0 +phy_chain_tx_polarity_flip_physical{204.0}=0x1 +#Port58 +#FC54 +portmap_108=217:100 +phy_chain_rx_lane_map_physical{217.0}=0x1203 +phy_chain_tx_lane_map_physical{217.0}=0x2031 +phy_chain_rx_polarity_flip_physical{217.0}=0x1 +phy_chain_rx_polarity_flip_physical{218.0}=0x0 +phy_chain_rx_polarity_flip_physical{219.0}=0x1 +phy_chain_rx_polarity_flip_physical{220.0}=0x1 +phy_chain_tx_polarity_flip_physical{217.0}=0x1 +phy_chain_tx_polarity_flip_physical{218.0}=0x0 +phy_chain_tx_polarity_flip_physical{219.0}=0x1 +phy_chain_tx_polarity_flip_physical{220.0}=0x0 +#Port59 +#FC52 +portmap_106=209:100 +phy_chain_rx_lane_map_physical{209.0}=0x0321 +phy_chain_tx_lane_map_physical{209.0}=0x3102 +phy_chain_rx_polarity_flip_physical{209.0}=0x0 +phy_chain_rx_polarity_flip_physical{210.0}=0x0 +phy_chain_rx_polarity_flip_physical{211.0}=0x1 +phy_chain_rx_polarity_flip_physical{212.0}=0x0 +phy_chain_tx_polarity_flip_physical{209.0}=0x0 +phy_chain_tx_polarity_flip_physical{210.0}=0x0 +phy_chain_tx_polarity_flip_physical{211.0}=0x1 +phy_chain_tx_polarity_flip_physical{212.0}=0x0 +#Port60 +#FC56 +portmap_110=225:100 +phy_chain_rx_lane_map_physical{225.0}=0x2103 +phy_chain_tx_lane_map_physical{225.0}=0x2031 +phy_chain_rx_polarity_flip_physical{225.0}=0x0 +phy_chain_rx_polarity_flip_physical{226.0}=0x0 +phy_chain_rx_polarity_flip_physical{227.0}=0x1 +phy_chain_rx_polarity_flip_physical{228.0}=0x1 +phy_chain_tx_polarity_flip_physical{225.0}=0x1 +phy_chain_tx_polarity_flip_physical{226.0}=0x0 +phy_chain_tx_polarity_flip_physical{227.0}=0x1 +phy_chain_tx_polarity_flip_physical{228.0}=0x1 +#Port61 +#FC58 +portmap_112=233:100 +phy_chain_rx_lane_map_physical{233.0}=0x2130 +phy_chain_tx_lane_map_physical{233.0}=0x0312 +phy_chain_rx_polarity_flip_physical{233.0}=0x0 +phy_chain_rx_polarity_flip_physical{234.0}=0x1 +phy_chain_rx_polarity_flip_physical{235.0}=0x1 +phy_chain_rx_polarity_flip_physical{236.0}=0x0 +phy_chain_tx_polarity_flip_physical{233.0}=0x0 +phy_chain_tx_polarity_flip_physical{234.0}=0x0 +phy_chain_tx_polarity_flip_physical{235.0}=0x1 +phy_chain_tx_polarity_flip_physical{236.0}=0x0 +#Port62 +#FC62 +portmap_116=249:100 +phy_chain_rx_lane_map_physical{249.0}=0x1302 +phy_chain_tx_lane_map_physical{249.0}=0x1302 +phy_chain_rx_polarity_flip_physical{249.0}=0x0 +phy_chain_rx_polarity_flip_physical{250.0}=0x1 +phy_chain_rx_polarity_flip_physical{251.0}=0x0 +phy_chain_rx_polarity_flip_physical{252.0}=0x1 +phy_chain_tx_polarity_flip_physical{249.0}=0x1 +phy_chain_tx_polarity_flip_physical{250.0}=0x1 +phy_chain_tx_polarity_flip_physical{251.0}=0x1 +phy_chain_tx_polarity_flip_physical{252.0}=0x1 +#Port63 +#FC60 +portmap_114=241:100 +phy_chain_rx_lane_map_physical{241.0}=0x3012 +phy_chain_tx_lane_map_physical{241.0}=0x2301 +phy_chain_rx_polarity_flip_physical{241.0}=0x1 +phy_chain_rx_polarity_flip_physical{242.0}=0x1 +phy_chain_rx_polarity_flip_physical{243.0}=0x0 +phy_chain_rx_polarity_flip_physical{244.0}=0x1 +phy_chain_tx_polarity_flip_physical{241.0}=0x1 +phy_chain_tx_polarity_flip_physical{242.0}=0x0 +phy_chain_tx_polarity_flip_physical{243.0}=0x1 +phy_chain_tx_polarity_flip_physical{244.0}=0x0 diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/default_sku b/device/juniper/x86_64-juniper_qfx5210-r0/default_sku new file mode 100644 index 000000000000..869e1625da46 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5210-r0/default_sku @@ -0,0 +1 @@ +Juniper-QFX5210-64C t1 diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/installer.conf b/device/juniper/x86_64-juniper_qfx5210-r0/installer.conf new file mode 100644 index 000000000000..5c03f5844baa --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5210-r0/installer.conf @@ -0,0 +1,2 @@ +CONSOLE_SPEED=9600 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="tg3.short_preamble=1 tg3.bcm5718s_reset=1" 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 new file mode 100755 index 000000000000..75a36c6f9c68 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5210-r0/led_proc_init.soc @@ -0,0 +1,155 @@ +m CMIC_LEDUP0_CLK_PARAMS REFRESH_CYCLE_PERIOD=0xc00000 +m CMIC_LEDUP1_CLK_PARAMS REFRESH_CYCLE_PERIOD=0xc00000 +m CMIC_LEDUP2_CLK_PARAMS REFRESH_CYCLE_PERIOD=0xc00000 +m CMIC_LEDUP3_CLK_PARAMS REFRESH_CYCLE_PERIOD=0xc00000 + +m CMIC_LEDUP0_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=63 REMAP_PORT_1=62 REMAP_PORT_2=61 REMAP_PORT_3=60 +m CMIC_LEDUP0_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=59 REMAP_PORT_5=58 REMAP_PORT_6=57 REMAP_PORT_7=56 +m CMIC_LEDUP0_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=55 REMAP_PORT_9=54 REMAP_PORT_10=53 REMAP_PORT_11=52 +m CMIC_LEDUP0_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=51 REMAP_PORT_13=50 REMAP_PORT_14=49 REMAP_PORT_15=48 +m CMIC_LEDUP0_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=47 REMAP_PORT_17=46 REMAP_PORT_18=45 REMAP_PORT_19=44 +m CMIC_LEDUP0_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=43 REMAP_PORT_21=42 REMAP_PORT_22=41 REMAP_PORT_23=40 +m CMIC_LEDUP0_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=39 REMAP_PORT_25=38 REMAP_PORT_26=37 REMAP_PORT_27=36 +m CMIC_LEDUP0_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=35 REMAP_PORT_29=34 REMAP_PORT_30=33 REMAP_PORT_31=32 +m CMIC_LEDUP0_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=31 REMAP_PORT_33=30 REMAP_PORT_34=29 REMAP_PORT_35=28 +m CMIC_LEDUP0_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=27 REMAP_PORT_37=26 REMAP_PORT_38=25 REMAP_PORT_39=24 +m CMIC_LEDUP0_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=23 REMAP_PORT_41=22 REMAP_PORT_42=21 REMAP_PORT_43=20 +m CMIC_LEDUP0_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=19 REMAP_PORT_45=18 REMAP_PORT_46=17 REMAP_PORT_47=16 +m CMIC_LEDUP0_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=15 REMAP_PORT_49=14 REMAP_PORT_50=13 REMAP_PORT_51=12 +m CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=11 REMAP_PORT_53=10 REMAP_PORT_54=9 REMAP_PORT_55=8 +m CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=7 REMAP_PORT_57=6 REMAP_PORT_58=5 REMAP_PORT_59=4 +m CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=3 REMAP_PORT_61=2 REMAP_PORT_62=1 REMAP_PORT_63=0 + +m CMIC_LEDUP1_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=3 REMAP_PORT_1=2 REMAP_PORT_2=1 REMAP_PORT_3=0 +m CMIC_LEDUP1_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=7 REMAP_PORT_5=6 REMAP_PORT_6=5 REMAP_PORT_7=4 +m CMIC_LEDUP1_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=11 REMAP_PORT_9=10 REMAP_PORT_10=9 REMAP_PORT_11=8 +m CMIC_LEDUP1_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=15 REMAP_PORT_13=14 REMAP_PORT_14=13 REMAP_PORT_15=12 +m CMIC_LEDUP1_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=19 REMAP_PORT_17=18 REMAP_PORT_18=17 REMAP_PORT_19=16 +m CMIC_LEDUP1_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=23 REMAP_PORT_21=22 REMAP_PORT_22=21 REMAP_PORT_23=20 +m CMIC_LEDUP1_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=27 REMAP_PORT_25=26 REMAP_PORT_26=25 REMAP_PORT_27=24 +m CMIC_LEDUP1_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=31 REMAP_PORT_29=30 REMAP_PORT_30=29 REMAP_PORT_31=28 +m CMIC_LEDUP1_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=35 REMAP_PORT_33=34 REMAP_PORT_34=33 REMAP_PORT_35=32 +m CMIC_LEDUP1_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=39 REMAP_PORT_37=38 REMAP_PORT_38=37 REMAP_PORT_39=36 +m CMIC_LEDUP1_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=43 REMAP_PORT_41=42 REMAP_PORT_42=41 REMAP_PORT_43=40 +m CMIC_LEDUP1_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=47 REMAP_PORT_45=46 REMAP_PORT_46=45 REMAP_PORT_47=44 +m CMIC_LEDUP1_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=51 REMAP_PORT_49=50 REMAP_PORT_50=49 REMAP_PORT_51=48 +m CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=55 REMAP_PORT_53=54 REMAP_PORT_54=53 REMAP_PORT_55=52 +m CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=59 REMAP_PORT_57=58 REMAP_PORT_58=57 REMAP_PORT_59=56 +m CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=63 REMAP_PORT_61=62 REMAP_PORT_62=61 REMAP_PORT_63=60 + +m CMIC_LEDUP2_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=63 REMAP_PORT_1=62 REMAP_PORT_2=61 REMAP_PORT_3=60 +m CMIC_LEDUP2_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=59 REMAP_PORT_5=58 REMAP_PORT_6=57 REMAP_PORT_7=56 +m CMIC_LEDUP2_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=55 REMAP_PORT_9=54 REMAP_PORT_10=53 REMAP_PORT_11=52 +m CMIC_LEDUP2_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=51 REMAP_PORT_13=50 REMAP_PORT_14=49 REMAP_PORT_15=48 +m CMIC_LEDUP2_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=47 REMAP_PORT_17=46 REMAP_PORT_18=45 REMAP_PORT_19=44 +m CMIC_LEDUP2_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=43 REMAP_PORT_21=42 REMAP_PORT_22=41 REMAP_PORT_23=40 +m CMIC_LEDUP2_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=39 REMAP_PORT_25=38 REMAP_PORT_26=37 REMAP_PORT_27=36 +m CMIC_LEDUP2_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=35 REMAP_PORT_29=34 REMAP_PORT_30=33 REMAP_PORT_31=32 +m CMIC_LEDUP2_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=31 REMAP_PORT_33=30 REMAP_PORT_34=29 REMAP_PORT_35=28 +m CMIC_LEDUP2_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=27 REMAP_PORT_37=26 REMAP_PORT_38=25 REMAP_PORT_39=24 +m CMIC_LEDUP2_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=23 REMAP_PORT_41=22 REMAP_PORT_42=21 REMAP_PORT_43=20 +m CMIC_LEDUP2_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=19 REMAP_PORT_45=18 REMAP_PORT_46=17 REMAP_PORT_47=16 +m CMIC_LEDUP2_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=15 REMAP_PORT_49=14 REMAP_PORT_50=13 REMAP_PORT_51=12 +m CMIC_LEDUP2_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=11 REMAP_PORT_53=10 REMAP_PORT_54=9 REMAP_PORT_55=8 +m CMIC_LEDUP2_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=7 REMAP_PORT_57=6 REMAP_PORT_58=5 REMAP_PORT_59=4 +m CMIC_LEDUP2_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=3 REMAP_PORT_61=2 REMAP_PORT_62=1 REMAP_PORT_63=0 + +m CMIC_LEDUP3_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=3 REMAP_PORT_1=2 REMAP_PORT_2=1 REMAP_PORT_3=0 +m CMIC_LEDUP3_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=7 REMAP_PORT_5=6 REMAP_PORT_6=5 REMAP_PORT_7=4 +m CMIC_LEDUP3_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=11 REMAP_PORT_9=10 REMAP_PORT_10=9 REMAP_PORT_11=8 +m CMIC_LEDUP3_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=15 REMAP_PORT_13=14 REMAP_PORT_14=13 REMAP_PORT_15=12 +m CMIC_LEDUP3_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=19 REMAP_PORT_17=18 REMAP_PORT_18=17 REMAP_PORT_19=16 +m CMIC_LEDUP3_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=23 REMAP_PORT_21=22 REMAP_PORT_22=21 REMAP_PORT_23=20 +m CMIC_LEDUP3_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=27 REMAP_PORT_25=26 REMAP_PORT_26=25 REMAP_PORT_27=24 +m CMIC_LEDUP3_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=31 REMAP_PORT_29=30 REMAP_PORT_30=29 REMAP_PORT_31=28 +m CMIC_LEDUP3_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=35 REMAP_PORT_33=34 REMAP_PORT_34=33 REMAP_PORT_35=32 +m CMIC_LEDUP3_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=39 REMAP_PORT_37=38 REMAP_PORT_38=37 REMAP_PORT_39=36 +m CMIC_LEDUP3_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=43 REMAP_PORT_41=42 REMAP_PORT_42=41 REMAP_PORT_43=40 +m CMIC_LEDUP3_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=47 REMAP_PORT_45=46 REMAP_PORT_46=45 REMAP_PORT_47=44 +m CMIC_LEDUP3_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=51 REMAP_PORT_49=50 REMAP_PORT_50=49 REMAP_PORT_51=48 +m CMIC_LEDUP3_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=55 REMAP_PORT_53=54 REMAP_PORT_54=53 REMAP_PORT_55=52 +m CMIC_LEDUP3_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=59 REMAP_PORT_57=58 REMAP_PORT_58=57 REMAP_PORT_59=56 +m CMIC_LEDUP3_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=63 REMAP_PORT_61=62 REMAP_PORT_62=61 REMAP_PORT_63=60 + +led 0 stop +led 0 prog \ + 02 FD 42 80 02 FF 42 00 02 FE 42 00 02 FA 42 E0 \ + 02 FB 42 40 06 F9 D2 00 74 1E 02 F9 42 03 67 AC \ + 67 C3 67 52 86 FE 67 C3 67 52 86 FE 67 C3 67 52 \ + 86 FE 67 C3 67 52 86 FE 06 FB D6 FE 74 1E 86 FC \ + 3E FA 06 FE 88 4A 03 71 4C 67 84 57 67 84 57 67 \ + 98 57 06 FE 88 80 4A 00 27 97 75 4F 90 4A 00 27 \ + 4A 01 27 B7 97 71 69 77 42 06 F9 D6 FC 74 7C 02 \ + F9 4A 07 37 4E 07 02 FC 42 00 4E 07 06 F9 0A 07 \ + 71 4F 77 42 16 FF 06 FD 17 4D DA 07 74 95 12 FF \ + 52 00 86 FD 57 86 FF 57 16 FF 06 FD 07 4D DA 07 \ + 74 A9 12 FF 52 00 86 FD 57 86 FF 57 06 FE C2 FC \ + 98 98 12 F4 50 C2 FC 98 98 F2 F0 14 06 F4 C2 03 \ + 88 77 D1 06 FE C2 FC 98 98 F2 E0 14 06 FE C2 03 \ + 88 18 71 E2 80 18 71 DD 67 98 67 98 57 67 98 67 \ + 84 57 80 18 71 EB 67 84 67 98 57 67 84 67 84 57 \ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + + +led 1 stop +led 1 prog \ + 02 FD 42 80 02 FF 42 00 02 FE 42 00 02 FA 42 E0 \ + 02 FB 42 40 06 F9 D2 00 74 1E 02 F9 42 03 67 AC \ + 67 C3 67 52 86 FE 67 C3 67 52 86 FE 67 C3 67 52 \ + 86 FE 67 C3 67 52 86 FE 06 FB D6 FE 74 1E 86 FC \ + 3E FA 06 FE 88 4A 03 71 4C 67 84 57 67 84 57 67 \ + 98 57 06 FE 88 80 4A 00 27 97 75 4F 90 4A 00 27 \ + 4A 01 27 B7 97 71 69 77 42 06 F9 D6 FC 74 7C 02 \ + F9 4A 07 37 4E 07 02 FC 42 00 4E 07 06 F9 0A 07 \ + 71 4F 77 42 16 FF 06 FD 17 4D DA 07 74 95 12 FF \ + 52 00 86 FD 57 86 FF 57 16 FF 06 FD 07 4D DA 07 \ + 74 A9 12 FF 52 00 86 FD 57 86 FF 57 06 FE C2 FC \ + 98 98 12 F4 50 C2 FC 98 98 F2 F0 14 06 F4 C2 03 \ + 88 77 D1 06 FE C2 FC 98 98 F2 E0 14 06 FE C2 03 \ + 88 18 71 E2 80 18 71 DD 67 98 67 98 57 67 98 67 \ + 84 57 80 18 71 EB 67 84 67 98 57 67 84 67 84 57 \ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +led 2 stop +led 2 prog \ + 02 FD 42 80 02 FF 42 00 02 FE 42 00 02 FA 42 E0 \ + 02 FB 42 40 06 F9 D2 00 74 1E 02 F9 42 03 67 AC \ + 67 C3 67 52 86 FE 67 C3 67 52 86 FE 67 C3 67 52 \ + 86 FE 67 C3 67 52 86 FE 06 FB D6 FE 74 1E 86 FC \ + 3E FA 06 FE 88 4A 03 71 4C 67 84 57 67 84 57 67 \ + 98 57 06 FE 88 80 4A 00 27 97 75 4F 90 4A 00 27 \ + 4A 01 27 B7 97 71 69 77 42 06 F9 D6 FC 74 7C 02 \ + F9 4A 07 37 4E 07 02 FC 42 00 4E 07 06 F9 0A 07 \ + 71 4F 77 42 16 FF 06 FD 17 4D DA 07 74 95 12 FF \ + 52 00 86 FD 57 86 FF 57 16 FF 06 FD 07 4D DA 07 \ + 74 A9 12 FF 52 00 86 FD 57 86 FF 57 06 FE C2 FC \ + 98 98 12 F4 50 C2 FC 98 98 F2 F0 14 06 F4 C2 03 \ + 88 77 D1 06 FE C2 FC 98 98 F2 E0 14 06 FE C2 03 \ + 88 18 71 E2 80 18 71 DD 67 98 67 98 57 67 98 67 \ + 84 57 80 18 71 EB 67 84 67 98 57 67 84 67 84 57 \ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +led 3 stop +led 3 prog \ + 02 FD 42 80 02 FF 42 00 02 FE 42 00 02 FA 42 E0 \ + 02 FB 42 40 06 F9 D2 00 74 1E 02 F9 42 03 67 AC \ + 67 C3 67 52 86 FE 67 C3 67 52 86 FE 67 C3 67 52 \ + 86 FE 67 C3 67 52 86 FE 06 FB D6 FE 74 1E 86 FC \ + 3E FA 06 FE 88 4A 03 71 4C 67 84 57 67 84 57 67 \ + 98 57 06 FE 88 80 4A 00 27 97 75 4F 90 4A 00 27 \ + 4A 01 27 B7 97 71 69 77 42 06 F9 D6 FC 74 7C 02 \ + F9 4A 07 37 4E 07 02 FC 42 00 4E 07 06 F9 0A 07 \ + 71 4F 77 42 16 FF 06 FD 17 4D DA 07 74 95 12 FF \ + 52 00 86 FD 57 86 FF 57 16 FF 06 FD 07 4D DA 07 \ + 74 A9 12 FF 52 00 86 FD 57 86 FF 57 06 FE C2 FC \ + 98 98 12 F4 50 C2 FC 98 98 F2 F0 14 06 F4 C2 03 \ + 88 77 D1 06 FE C2 FC 98 98 F2 E0 14 06 FE C2 03 \ + 88 18 71 E2 80 18 71 DD 67 98 67 98 57 67 98 67 \ + 84 57 80 18 71 EB 67 84 67 98 57 67 84 67 84 57 \ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +led auto on +led 0 start +led 1 start +led 2 start +led 3 start diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/media_settings.json b/device/juniper/x86_64-juniper_qfx5210-r0/media_settings.json new file mode 100644 index 000000000000..22788f3a6f23 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5210-r0/media_settings.json @@ -0,0 +1,19848 @@ +{ + "GLOBAL_MEDIA_SETTINGS": { + }, + "PORT_MEDIA_SETTINGS": { + "0": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0x103f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0x103f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0x103f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0x103f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0x103f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "1": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0x113f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0x113f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0x113f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0x113f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0x113f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "2": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "3": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "4": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "5": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "6": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x174a03", + "lane1":"0x174a03", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "7": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x1b4603", + "lane2":"0x174a03", + "lane3":"0x174a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "8": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "9": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1d4403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xf3a04" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xf3a04" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xf3a04" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xf3a04" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xf3f02", + "lane2":"0xd3a02", + "lane3":"0xf3a04" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "10": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "11": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a02", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "12": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3402", + "lane1":"0xa3402", + "lane2":"0xa3402", + "lane3":"0xa3202" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3402", + "lane1":"0xa3402", + "lane2":"0xa3402", + "lane3":"0xa3202" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3402", + "lane1":"0xa3402", + "lane2":"0xa3402", + "lane3":"0xa3202" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3402", + "lane1":"0xa3402", + "lane2":"0xa3402", + "lane3":"0xa3202" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3402", + "lane1":"0xa3402", + "lane2":"0xa3402", + "lane3":"0xa3202" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "13": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3402", + "lane1":"0xb3402", + "lane2":"0xa3402", + "lane3":"0xa3202" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3402", + "lane1":"0xb3402", + "lane2":"0xa3402", + "lane3":"0xa3202" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3402", + "lane1":"0xb3402", + "lane2":"0xa3402", + "lane3":"0xa3202" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3402", + "lane1":"0xb3402", + "lane2":"0xa3402", + "lane3":"0xa3202" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3402", + "lane1":"0xb3402", + "lane2":"0xa3402", + "lane3":"0xa3202" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "14": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0x93002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0x93002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0x93002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0x93002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0x93002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "15": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154c03", + "lane1":"0x154c03", + "lane2":"0x154c03", + "lane3":"0x154c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "16": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154901", + "lane1":"0x124901", + "lane2":"0x124903", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0x82d02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0x82d02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0x82d02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0x82d02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0x82d02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "17": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124904", + "lane2":"0x124901", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "18": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x124900", + "lane2":"0x124903", + "lane3":"0x144902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "19": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x124904", + "lane2":"0x124904", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "20": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xc3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xc3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xc3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xc3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xc3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "21": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "22": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3402", + "lane1":"0xd3402", + "lane2":"0xd3403", + "lane3":"0xd3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3402", + "lane1":"0xd3402", + "lane2":"0xd3403", + "lane3":"0xd3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3402", + "lane1":"0xd3402", + "lane2":"0xd3403", + "lane3":"0xd3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3402", + "lane1":"0xd3402", + "lane2":"0xd3403", + "lane3":"0xd3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3402", + "lane1":"0xd3402", + "lane2":"0xd3403", + "lane3":"0xd3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "23": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1e4303", + "lane1":"0x1e4303", + "lane2":"0x1d4403", + "lane3":"0x1e4303" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xe3602", + "lane1":"0xf3a03", + "lane2":"0xf3d03", + "lane3":"0xf3d03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xe3602", + "lane1":"0xf3a03", + "lane2":"0xf3d03", + "lane3":"0xf3d03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xe3602", + "lane1":"0xf3a03", + "lane2":"0xf3d03", + "lane3":"0xf3d03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xe3602", + "lane1":"0xf3a03", + "lane2":"0xf3d03", + "lane3":"0xf3d03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xe3602", + "lane1":"0xf3a03", + "lane2":"0xf3d03", + "lane3":"0xf3d03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "24": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154906", + "lane1":"0x154904", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "25": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x174902", + "lane1":"0x174902", + "lane2":"0x174902", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "26": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3002", + "lane1":"0xa3002", + "lane2":"0xa3002", + "lane3":"0xa3002" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "27": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xb3203", + "lane1":"0xc3403", + "lane2":"0xc3403", + "lane3":"0xd3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3203", + "lane1":"0xc3403", + "lane2":"0xc3403", + "lane3":"0xd3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3203", + "lane1":"0xc3403", + "lane2":"0xc3403", + "lane3":"0xd3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xb3203", + "lane1":"0xc3403", + "lane2":"0xc3403", + "lane3":"0xd3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xb3203", + "lane1":"0xc3403", + "lane2":"0xc3403", + "lane3":"0xd3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "28": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4505", + "lane1":"0x1a4505", + "lane2":"0x1a4505", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xd3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xd3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xd3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xd3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xd3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "29": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xc3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xc3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xc3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xc3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xc3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "30": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4604", + "lane1":"0x1a4604", + "lane2":"0x1a4604", + "lane3":"0x1a4604" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xd3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xd3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xd3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xd3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xc3402", + "lane1":"0xd3402", + "lane2":"0xc3402", + "lane3":"0xc3402" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "31": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3602", + "lane1":"0xd3602", + "lane2":"0xd3602", + "lane3":"0xd3602" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3602", + "lane1":"0xd3602", + "lane2":"0xd3602", + "lane3":"0xd3602" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3602", + "lane1":"0xd3602", + "lane2":"0xd3602", + "lane3":"0xd3602" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3602", + "lane1":"0xd3602", + "lane2":"0xd3602", + "lane3":"0xd3602" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3602", + "lane1":"0xd3602", + "lane2":"0xd3602", + "lane3":"0xd3602" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "32": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4404", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xf3a02", + "lane1":"0x113c03", + "lane2":"0xf3a03", + "lane3":"0xf3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xf3a02", + "lane1":"0x113c03", + "lane2":"0xf3a03", + "lane3":"0xf3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xf3a02", + "lane1":"0x113c03", + "lane2":"0xf3a03", + "lane3":"0xf3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xf3a02", + "lane1":"0x113c03", + "lane2":"0xf3a03", + "lane3":"0xf3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xf3a02", + "lane1":"0x113c03", + "lane2":"0xf3a03", + "lane3":"0xf3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "33": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xf3a03", + "lane1":"0xf3a03", + "lane2":"0xf3a03", + "lane3":"0xf3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xf3a03", + "lane1":"0xf3a03", + "lane2":"0xf3a03", + "lane3":"0xf3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xf3a03", + "lane1":"0xf3a03", + "lane2":"0xf3a03", + "lane3":"0xf3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xf3a03", + "lane1":"0xf3a03", + "lane2":"0xf3a03", + "lane3":"0xf3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xf3a03", + "lane1":"0xf3a03", + "lane2":"0xf3a03", + "lane3":"0xf3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "34": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4604", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3803", + "lane1":"0xe3803", + "lane2":"0xd3803", + "lane3":"0xc3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3803", + "lane1":"0xe3803", + "lane2":"0xd3803", + "lane3":"0xc3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3803", + "lane1":"0xe3803", + "lane2":"0xd3803", + "lane3":"0xc3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3803", + "lane1":"0xe3803", + "lane2":"0xd3803", + "lane3":"0xc3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3803", + "lane1":"0xe3803", + "lane2":"0xd3803", + "lane3":"0xc3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "35": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xe3804", + "lane1":"0xe3803", + "lane2":"0xe3804", + "lane3":"0xe3804" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xe3804", + "lane1":"0xe3803", + "lane2":"0xe3804", + "lane3":"0xe3804" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xe3804", + "lane1":"0xe3803", + "lane2":"0xe3804", + "lane3":"0xe3804" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xe3804", + "lane1":"0xe3803", + "lane2":"0xe3804", + "lane3":"0xe3804" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xe3804", + "lane1":"0xe3803", + "lane2":"0xe3804", + "lane3":"0xe3804" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "36": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3803", + "lane1":"0xd3803", + "lane2":"0xb3203", + "lane3":"0xc3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3803", + "lane1":"0xd3803", + "lane2":"0xb3203", + "lane3":"0xc3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3803", + "lane1":"0xd3803", + "lane2":"0xb3203", + "lane3":"0xc3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3803", + "lane1":"0xd3803", + "lane2":"0xb3203", + "lane3":"0xc3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3803", + "lane1":"0xd3803", + "lane2":"0xb3203", + "lane3":"0xc3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "37": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xb3202", + "lane1":"0xb3202", + "lane2":"0xa3003", + "lane3":"0xb3003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3202", + "lane1":"0xb3202", + "lane2":"0xa3003", + "lane3":"0xb3003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3202", + "lane1":"0xb3202", + "lane2":"0xa3003", + "lane3":"0xb3003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xb3202", + "lane1":"0xb3202", + "lane2":"0xa3003", + "lane3":"0xb3003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xb3202", + "lane1":"0xb3202", + "lane2":"0xa3003", + "lane3":"0xb3003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "38": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x164903", + "lane1":"0x164903", + "lane2":"0x164903", + "lane3":"0x164903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3203", + "lane1":"0xa3203", + "lane2":"0xa3203", + "lane3":"0xa3203" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3203", + "lane1":"0xa3203", + "lane2":"0xa3203", + "lane3":"0xa3203" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3203", + "lane1":"0xa3203", + "lane2":"0xa3203", + "lane3":"0xa3203" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3203", + "lane1":"0xa3203", + "lane2":"0xa3203", + "lane3":"0xa3203" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3203", + "lane1":"0xa3203", + "lane2":"0xa3203", + "lane3":"0xa3203" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "39": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x164901", + "lane1":"0x184901", + "lane2":"0x184901", + "lane3":"0x184901" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3202", + "lane1":"0xa3202", + "lane2":"0xa3003", + "lane3":"0xa3003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3202", + "lane1":"0xa3202", + "lane2":"0xa3003", + "lane3":"0xa3003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3202", + "lane1":"0xa3202", + "lane2":"0xa3003", + "lane3":"0xa3003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3202", + "lane1":"0xa3202", + "lane2":"0xa3003", + "lane3":"0xa3003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3202", + "lane1":"0xa3202", + "lane2":"0xa3003", + "lane3":"0xa3003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "40": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1c4503", + "lane2":"0x1c4503", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "41": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1a4703", + "lane2":"0x1b4603", + "lane3":"0x1c4503" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "42": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xb3a03", + "lane3":"0xa3803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xb3a03", + "lane3":"0xa3803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xb3a03", + "lane3":"0xa3803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xb3a03", + "lane3":"0xa3803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xb3a03", + "lane3":"0xa3803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "43": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1a4703", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "44": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x184902", + "lane2":"0x154902", + "lane3":"0x184902" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x82f03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x82f03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x82f03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x82f03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x82f03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "45": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154900", + "lane1":"0x154900", + "lane2":"0x154900", + "lane3":"0x154900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0x72d03", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x83003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x72d03", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x83003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x72d03", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x83003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0x72d03", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x83003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0x72d03", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x83003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "46": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x174900", + "lane1":"0x174900", + "lane2":"0x154900", + "lane3":"0x174904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "47": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x154903", + "lane3":"0x154903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x82e03", + "lane3":"0x83003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x82e03", + "lane3":"0x83003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x82e03", + "lane3":"0x83003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x82e03", + "lane3":"0x83003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x82e03", + "lane3":"0x83003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "48": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x184902", + "lane1":"0x164902", + "lane2":"0x164902", + "lane3":"0x144900" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "49": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x174901", + "lane1":"0x144902", + "lane2":"0x144902", + "lane3":"0x144903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x93003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "50": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x184901", + "lane1":"0x174901", + "lane2":"0x164903", + "lane3":"0x154904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x83003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x83003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x83003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x83003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93003", + "lane2":"0x83003", + "lane3":"0x93003" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "51": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x154903", + "lane1":"0x154903", + "lane2":"0x134903", + "lane3":"0x144904" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93002", + "lane2":"0x82f03", + "lane3":"0x82f03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93002", + "lane2":"0x82f03", + "lane3":"0x82f03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93002", + "lane2":"0x82f03", + "lane3":"0x82f03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93002", + "lane2":"0x82f03", + "lane3":"0x82f03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0x93003", + "lane1":"0x93002", + "lane2":"0x82f03", + "lane3":"0x82f03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "52": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x194803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "53": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184803", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "54": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4503", + "lane1":"0x1e4204", + "lane2":"0x1c4503", + "lane3":"0x1d4304" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xf3d02", + "lane2":"0xd3a03", + "lane3":"0xf3c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xf3d02", + "lane2":"0xd3a03", + "lane3":"0xf3c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xf3d02", + "lane2":"0xd3a03", + "lane3":"0xf3c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xf3d02", + "lane2":"0xd3a03", + "lane3":"0xf3c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xf3d02", + "lane2":"0xd3a03", + "lane3":"0xf3c03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "55": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xb3a03", + "lane1":"0xc3a03", + "lane2":"0xa3403", + "lane3":"0xb3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3a03", + "lane1":"0xc3a03", + "lane2":"0xa3403", + "lane3":"0xb3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3a03", + "lane1":"0xc3a03", + "lane2":"0xa3403", + "lane3":"0xb3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xb3a03", + "lane1":"0xc3a03", + "lane2":"0xa3403", + "lane3":"0xb3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xb3a03", + "lane1":"0xc3a03", + "lane2":"0xa3403", + "lane3":"0xb3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "56": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x184903", + "lane1":"0x184903", + "lane2":"0x184903", + "lane3":"0x184903" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xa3403", + "lane1":"0xa3403", + "lane2":"0xa3403", + "lane3":"0xa3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "57": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x194803", + "lane1":"0x194803", + "lane2":"0x184903", + "lane3":"0x194803" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0x93203", + "lane1":"0xa3603", + "lane2":"0x93203", + "lane3":"0x93203" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93203", + "lane1":"0xa3603", + "lane2":"0x93203", + "lane3":"0x93203" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0x93203", + "lane1":"0xa3603", + "lane2":"0x93203", + "lane3":"0x93203" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0x93203", + "lane1":"0xa3603", + "lane2":"0x93203", + "lane3":"0x93203" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0x93203", + "lane1":"0xa3603", + "lane2":"0x93203", + "lane3":"0x93203" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "58": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xb3403", + "lane3":"0xb3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xb3403", + "lane3":"0xb3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xb3403", + "lane3":"0xb3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xb3403", + "lane3":"0xb3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xb3403", + "lane3":"0xb3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "59": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4703" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xb3403", + "lane3":"0xb3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xb3403", + "lane3":"0xb3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xb3403", + "lane3":"0xb3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xb3403", + "lane3":"0xb3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xb3403", + "lane3":"0xb3403" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "60": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1a4703", + "lane1":"0x1a4703", + "lane2":"0x1a4703", + "lane3":"0x1a4505" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xc3603", + "lane3":"0xc3603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xc3603", + "lane3":"0xc3603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xc3603", + "lane3":"0xc3603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xc3603", + "lane3":"0xc3603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xb3403", + "lane1":"0xc3603", + "lane2":"0xc3603", + "lane3":"0xc3603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "61": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1b4603", + "lane1":"0x1b4603", + "lane2":"0x1b4603", + "lane3":"0x1b4603" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xc3603", + "lane1":"0xd3a03", + "lane2":"0xc3603", + "lane3":"0xc3602" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xc3603", + "lane1":"0xd3a03", + "lane2":"0xc3603", + "lane3":"0xc3602" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xc3603", + "lane1":"0xd3a03", + "lane2":"0xc3603", + "lane3":"0xc3602" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xc3603", + "lane1":"0xd3a03", + "lane2":"0xc3603", + "lane3":"0xc3602" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xc3603", + "lane1":"0xd3a03", + "lane2":"0xc3603", + "lane3":"0xc3602" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "62": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1c4404", + "lane1":"0x1c4404", + "lane2":"0x1b4504", + "lane3":"0x1c4404" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a03", + "lane1":"0xd3a03", + "lane2":"0xd3a03", + "lane3":"0xd3a03" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + }, + "63": { + "Default": { + "preemphasis": { + "lane0":"0x14410a", + "lane1":"0x14410a", + "lane2":"0x14410a", + "lane3":"0x14410a" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-AVAGO-AFBR-89CDDZ-JU1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-1F3-1F3QAA": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC030-NJC": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC020-NJC": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC010-NJC": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC001-NJC": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TF-FC003-NJC": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13R-NJ3": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-FC13T-NJ3": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC9551REPM-J1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTLC1151RDPL-J1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C01-J1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C03-J1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C10-J1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C20-J1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FCBN425QE1C30-J1": { + "preemphasis": { + "lane0":"0x1b4504", + "lane1":"0x1b4504", + "lane2":"0x1a4703", + "lane3":"0x1b4504" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "AVAGO-AFBR-79EQDZ-JU1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a03", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "FINISAR CORP-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a03", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-FINISAR-FTL410QE3C-J1": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a03", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ3": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a03", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + }, + "JUNIPER-INNO-TR-IQ13L-NJ5": { + "preemphasis": { + "lane0":"0xd3a02", + "lane1":"0xd3a02", + "lane2":"0xd3a03", + "lane3":"0xd3a02" + }, + "idriver": { + "lane0":"0x8", + "lane1":"0x8", + "lane2":"0x8", + "lane3":"0x8" + } + } + } + } +} + diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/plugins/eeprom.py b/device/juniper/x86_64-juniper_qfx5210-r0/plugins/eeprom.py new file mode 100644 index 000000000000..a5453dc4f0a3 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5210-r0/plugins/eeprom.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python + +try: + import exceptions + import binascii + import time + import optparse + import warnings + import os + import sys + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + import subprocess + import syslog + from struct import * + 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-0056/eeprom" + +def log_error(msg): + syslog.openlog(SYSLOG_IDENTIFIER) + syslog.syslog(syslog.LOG_ERR, msg) + syslog.closelog() + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + + 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_qfx5210-r0/plugins/psuutil.py b/device/juniper/x86_64-juniper_qfx5210-r0/plugins/psuutil.py new file mode 100755 index 000000000000..707c7c897c82 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5210-r0/plugins/psuutil.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python + +############################################################################# +# Accton +# +# Module contains an implementation of SONiC PSU Base API and +# provides the PSUs status which are available in the platform +# +############################################################################# + +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + self.psu_path = "/sys/bus/i2c/devices/" + self.psu_presence = "/psu_present" + self.psu_oper_status = "/psu_power_good" + self.psu_mapping = { + 1: "10-0053", + 2: "9-0050", + } + + def get_num_psus(self): + return len(self.psu_mapping) + + def get_psu_status(self, index): + if index is None: + return False + + status = 0 + node = self.psu_path + self.psu_mapping[index]+self.psu_oper_status + try: + with open(node, 'r') as power_status: + status = int(power_status.read()) + except IOError: + return False + + return status == 1 + + def get_psu_presence(self, index): + if index is None: + return False + + status = 0 + node = self.psu_path + self.psu_mapping[index] + self.psu_presence + try: + with open(node, 'r') as presence_status: + status = int(presence_status.read()) + except IOError: + return False + + return status == 1 diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/plugins/sfputil.py b/device/juniper/x86_64-juniper_qfx5210-r0/plugins/sfputil.py new file mode 100644 index 000000000000..59b1dfdb5875 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5210-r0/plugins/sfputil.py @@ -0,0 +1,696 @@ +#!/usr/bin/env python + +try: + import time + from sonic_sfp.sfputilbase import * + import sys + import os + import string + from ctypes import create_string_buffer + # sys.path.append('/usr/local/bin') + # import sfp_detect +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +qfx5210_qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', + 'Length Cable Assembly(m)') + +qfx5210_sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +qfx5210_sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes','FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia','FibreChannelSpeed') + +qfx5210_qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', 'Fibre Channel Speed') + + + +class SfpUtil(SfpUtilBase): + """Platform specific SfpUtill class""" + + _port_start = 0 + _port_end = 63 + ports_in_block = 64 + cmd = '/var/run/sfppresence' + _port_to_eeprom_mapping = {} + port_to_i2c_mapping = { + 60 : 25, + 61 : 26, + 62 : 27, + 63 : 28, + 54 : 29, + 55 : 30, + 52 : 31, + 53 : 32, + 8 : 33, + 9 : 34, + 10 : 35, + 11 : 36, + 0 : 37, + 1 : 38, + 2 : 39, + 3 : 40, + 5 : 41, + 4 : 42, + 7 : 43, + 6 : 44, + 12 : 45, + 13 : 46, + 14 : 47, + 15 : 48, + 16 : 49, + 17 : 50, + 18 : 51, + 19 : 52, + 24 : 53, + 25 : 54, + 26 : 55, + 27 : 56, + 28 : 57, + 29 : 58, + 30 : 59, + 31 : 60, + 20 : 61, + 21 : 62, + 22 : 63, + 23 : 64, + 40 : 65, + 41 : 66, + 42 : 67, + 43 : 68, + 32 : 69, + 33 : 70, + 34 : 71, + 35 : 72, + 44 : 73, + 45 : 74, + 46 : 75, + 47 : 76, + 36 : 77, + 37 : 78, + 38 : 79, + 39 : 80, + 56 : 81, + 57 : 82, + 58 : 83, + 59 : 84, + 48 : 85, + 49 : 86, + 50 : 87, + 51 : 88,} + + # sys.path.append('/usr/local/bin') + _qsfp_ports = range(0, ports_in_block + 1) + + + def __init__(self): + 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 + SfpUtilBase.__init__(self) + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + path = "/sys/bus/i2c/devices/19-0060/module_reset_{0}" + port_ps = path.format(port_num+1) + + try: + reg_file = open(port_ps, 'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + #HW will clear reset after set. + reg_file.seek(0) + reg_file.write('1') + reg_file.close() + return True + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = "/sys/bus/i2c/devices/19-0060/module_present_{0}" + port_ps = path.format(port_num + 1) + + try: + reg_file = open(port_ps) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = reg_file.readline().rstrip() + if reg_value == '1': + return True + + return False + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return range(0, self.ports_in_block + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + # Writing to a file from a list + def write_to_file(self, file_name, from_list): + try: + fp1 = open(file_name, 'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + 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): + x = 0 + ret_dict = {} + defl_dict = {} + current_sfp_values = [0] * 64 + previous_sfp_values = [0] * 64 + + path = "/sys/bus/i2c/devices/19-0060/module_present_{0}" + + 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 x in range(self._port_start , self._port_end + 1): + try: + new_path = path.format(x + 1) + reg_file = open(new_path, 'r') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False, defl_dict + + sfp_present = reg_file.readline().rstrip() + reg_file.close() + current_sfp_values[x] = sfp_present + if (current_sfp_values[x] != previous_sfp_values[x]): + ret_dict.update({x:current_sfp_values[x]}) + + if(self.write_to_file(self.cmd, current_sfp_values) == True): + return True, ret_dict + else: + return False, defl_dict + + def get_transceiver_change_event(self, timeout=2000): + time.sleep(3) + return self.sfp_detect() + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + try: + eeprom = None + + if not self.get_presence(port_num): + return False + + eeprom = open(self.port_to_eeprom_mapping[port_num], "rb") + eeprom.seek(93) + lpmode = ord(eeprom.read(1)) + + if ((lpmode & 0x3) == 0x3): + return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 + else: + return False # High Power Mode if one of the following conditions is matched: + # 1. "Power override" bit is 0 + # 2. "Power override" bit is 1 and "Power set" bit is 0 + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + try: + eeprom = None + + if not self.get_presence(port_num): + return False # Port is not present, unable to set the eeprom + + # Fill in write buffer + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + buffer = create_string_buffer(1) + buffer[0] = chr(regval) + + # Write to eeprom + eeprom = open(self.port_to_eeprom_mapping[port_num], "r+b") + eeprom.seek(93) + eeprom.write(buffer[0]) + return True + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + # 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 + cable_length_width = XCVR_CABLE_LENGTH_WIDTH_QSFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + sfp_type = 'QSFP' + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + else: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_SFP + cable_length_width = XCVR_CABLE_LENGTH_WIDTH_SFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + sfp_type = 'SFP' + + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + 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 qfx5210_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 qfx5210_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 qfx5210_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 qfx5210_sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + + if sfp_interface_bulk_data['data'].has_key('NominalSignallingRate(UnitsOf100Mbd)'): + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + else: + transceiver_info_dict['nominal_bit_rate'] = 'N/A' + #transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + + return transceiver_info_dict + + def get_transceiver_dom_info_dict(self, port_num): + 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 diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 index 018c2f96bc1b..8c3cac4b80b8 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 @@ -65,28 +65,41 @@ {%- macro generate_profile_lists(port_names) %} "BUFFER_PORT_INGRESS_PROFILE_LIST": { - "{{ port_names }}": { +{% for port in port_names.split(',') %} + "{{ port }}": { "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} }, "BUFFER_PORT_EGRESS_PROFILE_LIST": { - "{{ port_names }}": { +{% for port in port_names.split(',') %} + "{{ port }}": { "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} } {%- endmacro %} {%- macro generate_queue_buffers(port_names) %} "BUFFER_QUEUE": { - "{{ port_names }}|3-4": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "{{ port_names }}|0-1": { +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { "profile" : "[BUFFER_PROFILE|q_lossy_profile]" }, - "{{ port_names }}|5": { +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { "profile" : "[BUFFER_PROFILE|q_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} } {%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 index c315ccf59547..45433b1b2641 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 @@ -65,28 +65,41 @@ {%- macro generate_profile_lists(port_names) %} "BUFFER_PORT_INGRESS_PROFILE_LIST": { - "{{ port_names }}": { +{% for port in port_names.split(',') %} + "{{ port }}": { "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} }, "BUFFER_PORT_EGRESS_PROFILE_LIST": { - "{{ port_names }}": { +{% for port in port_names.split(',') %} + "{{ port }}": { "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} } {%- endmacro %} {%- macro generate_queue_buffers(port_names) %} "BUFFER_QUEUE": { - "{{ port_names }}|3-4": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "{{ port_names }}|0-1": { +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { "profile" : "[BUFFER_PROFILE|q_lossy_profile]" }, - "{{ port_names }}|5": { +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { "profile" : "[BUFFER_PROFILE|q_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} } {%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/platform_reboot b/device/mellanox/x86_64-mlnx_msn2700-r0/platform_reboot index 58ead6402398..28c5aedc4e32 100755 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/platform_reboot +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/platform_reboot @@ -4,6 +4,7 @@ declare -r EXIT_SUCCESS="0" declare -r EXIT_ERROR="1" declare -r FW_UPGRADE_SCRIPT="/usr/bin/mlnx-fw-upgrade.sh" +declare -r SYSFS_PWR_CYCLE="/sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/pwr_cycle" FORCE_REBOOT="no" @@ -18,9 +19,17 @@ function ParseArguments() { done } +function SafePwrCycle() { + sync ; sync + umount -fa > /dev/null 2&>1 + echo 1 > $SYSFS_PWR_CYCLE + sleep 3 + echo 0 > $SYSFS_PWR_CYCLE +} + ParseArguments "$@" -${FW_UPGRADE_SCRIPT} --upgrade +${FW_UPGRADE_SCRIPT} --upgrade --verbose EXIT_CODE="$?" if [[ "${EXIT_CODE}" != "${EXIT_SUCCESS}" ]]; then echo "Failed to burn MLNX FW: errno=${EXIT_CODE}" @@ -31,4 +40,4 @@ if [[ "${EXIT_CODE}" != "${EXIT_SUCCESS}" ]]; then fi fi -exec /sbin/reboot $@ +SafePwrCycle diff --git a/device/mellanox/x86_64-mlnx_msn2700_simx-r0/platform_reboot b/device/mellanox/x86_64-mlnx_msn2700_simx-r0/platform_reboot deleted file mode 120000 index 43c8ea567493..000000000000 --- a/device/mellanox/x86_64-mlnx_msn2700_simx-r0/platform_reboot +++ /dev/null @@ -1 +0,0 @@ -../x86_64-mlnx_msn2700-r0/platform_reboot \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700_simx-r0/platform_reboot b/device/mellanox/x86_64-mlnx_msn2700_simx-r0/platform_reboot new file mode 100755 index 000000000000..5b9809e10423 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700_simx-r0/platform_reboot @@ -0,0 +1,21 @@ +#!/bin/bash + +declare -r EXIT_SUCCESS="0" +declare -r EXIT_ERROR="1" + +FORCE_REBOOT="no" + +function ParseArguments() { + while [ $# -ge 1 ]; do + case "$1" in + -f|--force) + FORCE_REBOOT="yes" + ;; + esac + shift + done +} + +ParseArguments "$@" + +exec /sbin/reboot $@ diff --git a/device/mellanox/x86_64-mlnx_msn2700_simx-r0/platform_wait b/device/mellanox/x86_64-mlnx_msn2700_simx-r0/platform_wait deleted file mode 120000 index 4b30bd429854..000000000000 --- a/device/mellanox/x86_64-mlnx_msn2700_simx-r0/platform_wait +++ /dev/null @@ -1 +0,0 @@ -../x86_64-mlnx_msn2700-r0/platform_wait \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 index 89b269456458..d40bc03fbb59 100644 --- a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 @@ -65,27 +65,40 @@ {%- macro generate_profile_lists(port_names) %} "BUFFER_PORT_INGRESS_PROFILE_LIST": { - "{{ port_names }}": { +{% for port in port_names.split(',') %} + "{{ port }}": { "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} }, "BUFFER_PORT_EGRESS_PROFILE_LIST": { - "{{ port_names }}": { +{% for port in port_names.split(',') %} + "{{ port }}": { "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} } {%- endmacro %} {%- macro generate_queue_buffers(port_names) %} "BUFFER_QUEUE": { - "{{ port_names }}|3-4": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "{{ port_names }}|0-1": { +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { "profile" : "[BUFFER_PROFILE|q_lossy_profile]" }, - "{{ port_names }}|5": { +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { "profile" : "[BUFFER_PROFILE|q_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} } {%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 index d9db9c2d255e..fe8c27b9d364 100644 --- a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 @@ -65,27 +65,40 @@ {%- macro generate_profile_lists(port_names) %} "BUFFER_PORT_INGRESS_PROFILE_LIST": { - "{{ port_names }}": { +{% for port in port_names.split(',') %} + "{{ port }}": { "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} }, "BUFFER_PORT_EGRESS_PROFILE_LIST": { - "{{ port_names }}": { +{% for port in port_names.split(',') %} + "{{ port }}": { "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} } {%- endmacro %} {%- macro generate_queue_buffers(port_names) %} "BUFFER_QUEUE": { - "{{ port_names }}|3-4": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "{{ port_names }}|0-1": { +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { "profile" : "[BUFFER_PROFILE|q_lossy_profile]" }, - "{{ port_names }}|5": { +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { "profile" : "[BUFFER_PROFILE|q_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} } {%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn3700_simx-r0/platform_reboot b/device/mellanox/x86_64-mlnx_msn3700_simx-r0/platform_reboot index d66ab7537bf1..dfaf53417665 120000 --- a/device/mellanox/x86_64-mlnx_msn3700_simx-r0/platform_reboot +++ b/device/mellanox/x86_64-mlnx_msn3700_simx-r0/platform_reboot @@ -1 +1 @@ -../x86_64-mlnx_msn3700-r0/platform_reboot \ No newline at end of file +../x86_64-mlnx_msn2700_simx-r0/platform_reboot \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3700_simx-r0/platform_wait b/device/mellanox/x86_64-mlnx_msn3700_simx-r0/platform_wait deleted file mode 120000 index 685dfb8437fc..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3700_simx-r0/platform_wait +++ /dev/null @@ -1 +0,0 @@ -../x86_64-mlnx_msn3700-r0/platform_wait \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn3800-r0/pmon_daemon_control.json new file mode 120000 index 000000000000..435a2ce7c0ba --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-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/quanta/x86_64-quanta_ix1b_rglbmc-r0/default_sku b/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/default_sku new file mode 100755 index 000000000000..68cbc0d6058d --- /dev/null +++ b/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/default_sku @@ -0,0 +1 @@ +Quanta-IX1B-32X t1 diff --git a/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/minigraph.xml b/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/minigraph.xml deleted file mode 100755 index 9d348f0051ba..000000000000 --- a/device/quanta/x86_64-quanta_ix1b_rglbmc-r0/minigraph.xml +++ /dev/null @@ -1,1074 +0,0 @@ - - - - - - ARISTA01T0 - 10.0.0.33 - sonic - 10.0.0.32 - 1 - 180 - 60 - - - sonic - 10.0.0.0 - ARISTA01T2 - 10.0.0.1 - 1 - 180 - 60 - - - ARISTA02T0 - 10.0.0.35 - sonic - 10.0.0.34 - 1 - 180 - 60 - - - sonic - 10.0.0.2 - ARISTA02T2 - 10.0.0.3 - 1 - 180 - 60 - - - ARISTA03T0 - 10.0.0.37 - sonic - 10.0.0.36 - 1 - 180 - 60 - - - sonic - 10.0.0.4 - ARISTA03T2 - 10.0.0.5 - 1 - 180 - 60 - - - ARISTA04T0 - 10.0.0.39 - sonic - 10.0.0.38 - 1 - 180 - 60 - - - sonic - 10.0.0.6 - ARISTA04T2 - 10.0.0.7 - 1 - 180 - 60 - - - ARISTA05T0 - 10.0.0.41 - sonic - 10.0.0.40 - 1 - 180 - 60 - - - sonic - 10.0.0.8 - ARISTA05T2 - 10.0.0.9 - 1 - 180 - 60 - - - ARISTA06T0 - 10.0.0.43 - sonic - 10.0.0.42 - 1 - 180 - 60 - - - sonic - 10.0.0.10 - ARISTA06T2 - 10.0.0.11 - 1 - 180 - 60 - - - ARISTA07T0 - 10.0.0.45 - sonic - 10.0.0.44 - 1 - 180 - 60 - - - sonic - 10.0.0.12 - ARISTA07T2 - 10.0.0.13 - 1 - 180 - 60 - - - ARISTA08T0 - 10.0.0.47 - sonic - 10.0.0.46 - 1 - 180 - 60 - - - sonic - 10.0.0.14 - ARISTA08T2 - 10.0.0.15 - 1 - 180 - 60 - - - ARISTA09T0 - 10.0.0.49 - sonic - 10.0.0.48 - 1 - 180 - 60 - - - sonic - 10.0.0.16 - ARISTA09T2 - 10.0.0.17 - 1 - 180 - 60 - - - ARISTA10T0 - 10.0.0.51 - sonic - 10.0.0.50 - 1 - 180 - 60 - - - sonic - 10.0.0.18 - ARISTA10T2 - 10.0.0.19 - 1 - 180 - 60 - - - ARISTA11T0 - 10.0.0.53 - sonic - 10.0.0.52 - 1 - 180 - 60 - - - sonic - 10.0.0.20 - ARISTA11T2 - 10.0.0.21 - 1 - 180 - 60 - - - ARISTA12T0 - 10.0.0.55 - sonic - 10.0.0.54 - 1 - 180 - 60 - - - sonic - 10.0.0.22 - ARISTA12T2 - 10.0.0.23 - 1 - 180 - 60 - - - ARISTA13T0 - 10.0.0.57 - sonic - 10.0.0.56 - 1 - 180 - 60 - - - sonic - 10.0.0.24 - ARISTA13T2 - 10.0.0.25 - 1 - 180 - 60 - - - ARISTA14T0 - 10.0.0.59 - sonic - 10.0.0.58 - 1 - 180 - 60 - - - sonic - 10.0.0.26 - ARISTA14T2 - 10.0.0.27 - 1 - 180 - 60 - - - ARISTA15T0 - 10.0.0.61 - sonic - 10.0.0.60 - 1 - 180 - 60 - - - sonic - 10.0.0.28 - ARISTA15T2 - 10.0.0.29 - 1 - 180 - 60 - - - ARISTA16T0 - 10.0.0.63 - sonic - 10.0.0.62 - 1 - 180 - 60 - - - sonic - 10.0.0.30 - ARISTA16T2 - 10.0.0.31 - 1 - 180 - 60 - - - - - 65100 - sonic - - -
10.0.0.33
- - -
- -
10.0.0.1
- - -
- -
10.0.0.35
- - -
- -
10.0.0.3
- - -
- -
10.0.0.37
- - -
- -
10.0.0.5
- - -
- -
10.0.0.39
- - -
- -
10.0.0.7
- - -
- -
10.0.0.41
- - -
- -
10.0.0.9
- - -
- -
10.0.0.43
- - -
- -
10.0.0.11
- - -
- -
10.0.0.45
- - -
- -
10.0.0.13
- - -
- -
10.0.0.47
- - -
- -
10.0.0.15
- - -
- -
10.0.0.49
- - -
- -
10.0.0.17
- - -
- -
10.0.0.51
- - -
- -
10.0.0.19
- - -
- -
10.0.0.53
- - -
- -
10.0.0.21
- - -
- -
10.0.0.55
- - -
- -
10.0.0.23
- - -
- -
10.0.0.57
- - -
- -
10.0.0.25
- - -
- -
10.0.0.59
- - -
- -
10.0.0.27
- - -
- -
10.0.0.61
- - -
- -
10.0.0.29
- - -
- -
10.0.0.63
- - -
- -
10.0.0.31
- - -
-
- -
- - 64001 - ARISTA01T0 - - - - 65200 - ARISTA01T2 - - - - 64002 - ARISTA02T0 - - - - 65200 - ARISTA02T2 - - - - 64003 - ARISTA03T0 - - - - 65200 - ARISTA03T2 - - - - 64004 - ARISTA04T0 - - - - 65200 - ARISTA04T2 - - - - 64005 - ARISTA05T0 - - - - 65200 - ARISTA05T2 - - - - 64006 - ARISTA06T0 - - - - 65200 - ARISTA06T2 - - - - 64007 - ARISTA07T0 - - - - 65200 - ARISTA07T2 - - - - 64008 - ARISTA08T0 - - - - 65200 - ARISTA08T2 - - - - 64009 - ARISTA09T0 - - - - 65200 - ARISTA09T2 - - - - 64010 - ARISTA10T0 - - - - 65200 - ARISTA10T2 - - - - 64011 - ARISTA11T0 - - - - 65200 - ARISTA11T2 - - - - 64012 - ARISTA12T0 - - - - 65200 - ARISTA12T2 - - - - 64013 - ARISTA13T0 - - - - 65200 - ARISTA13T2 - - - - 64014 - ARISTA14T0 - - - - 65200 - ARISTA14T2 - - - - 64015 - ARISTA15T0 - - - - 65200 - ARISTA15T2 - - - - 64016 - ARISTA16T0 - - - - 65200 - ARISTA16T2 - - -
-
- - - - - - HostIP - Loopback0 - - 10.1.0.32/32 - - 10.1.0.32/32 - - - - - - - - sonic - - - - - - Ethernet0 - 10.0.0.0/31 - - - - Ethernet4 - 10.0.0.2/31 - - - - Ethernet8 - 10.0.0.4/31 - - - - Ethernet12 - 10.0.0.6/31 - - - - Ethernet16 - 10.0.0.8/31 - - - - Ethernet20 - 10.0.0.10/31 - - - - Ethernet24 - 10.0.0.12/31 - - - - Ethernet28 - 10.0.0.14/31 - - - - Ethernet32 - 10.0.0.16/31 - - - - Ethernet36 - 10.0.0.18/31 - - - - Ethernet40 - 10.0.0.20/31 - - - - Ethernet44 - 10.0.0.22/31 - - - - Ethernet48 - 10.0.0.24/31 - - - - Ethernet52 - 10.0.0.26/31 - - - - Ethernet56 - 10.0.0.28/31 - - - - Ethernet60 - 10.0.0.30/31 - - - - Ethernet64 - 10.0.0.32/31 - - - - Ethernet68 - 10.0.0.34/31 - - - - Ethernet72 - 10.0.0.36/31 - - - - Ethernet76 - 10.0.0.38/31 - - - - Ethernet80 - 10.0.0.40/31 - - - - Ethernet84 - 10.0.0.42/31 - - - - Ethernet88 - 10.0.0.44/31 - - - - Ethernet92 - 10.0.0.46/31 - - - - Ethernet96 - 10.0.0.48/31 - - - - Ethernet100 - 10.0.0.50/31 - - - - Ethernet104 - 10.0.0.52/31 - - - - Ethernet108 - 10.0.0.54/31 - - - - Ethernet112 - 10.0.0.56/31 - - - - Ethernet116 - 10.0.0.58/31 - - - - Ethernet120 - 10.0.0.60/31 - - - - Ethernet124 - 10.0.0.62/31 - - - - - - - - - - - - DeviceInterfaceLink - sonic - Ethernet0 - ARISTA01T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet4 - ARISTA02T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet8 - ARISTA03T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet12 - ARISTA04T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet16 - ARISTA05T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet20 - ARISTA06T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet24 - ARISTA07T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet28 - ARISTA08T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet32 - ARISTA09T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet36 - ARISTA10T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet40 - ARISTA11T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet44 - ARISTA12T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet48 - ARISTA13T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet52 - ARISTA14T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet56 - ARISTA15T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet60 - ARISTA16T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet64 - ARISTA01T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet68 - ARISTA02T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet72 - ARISTA03T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet76 - ARISTA04T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet80 - ARISTA05T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet84 - ARISTA06T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet88 - ARISTA07T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet92 - ARISTA08T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet96 - ARISTA09T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet100 - ARISTA10T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet104 - ARISTA11T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet108 - ARISTA12T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet112 - ARISTA13T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet116 - ARISTA14T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet120 - ARISTA15T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet124 - ARISTA16T0 - Ethernet1 - - - - - sonic - Quanta-IX1B-32X - - - - - - - sonic - - - DhcpResources - - - - - NtpResources - - 0.debian.pool.ntp.org;1.debian.pool.ntp.org;2.debian.pool.ntp.org;3.debian.pool.ntp.org - - - SyslogResources - - - - - - - - - sonic - Quanta-IX1B-32X -
diff --git a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/port_config.ini b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/port_config.ini index 42b75f2175b3..14f4716d9091 100644 --- a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/port_config.ini +++ b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/Quanta-IX7-32X/port_config.ini @@ -1,33 +1,33 @@ # name lanes alias index speed -Ethernet0 29,30,31,32 hundredGigE1 0 100000 -Ethernet4 33,34,35,36 hundredGigE2 1 100000 -Ethernet8 41,42,43,44 hundredGigE3 2 100000 -Ethernet12 45,46,47,48 hundredGigE4 3 100000 -Ethernet16 1,2,3,4 hundredGigE5 4 100000 -Ethernet20 5,6,7,8 hundredGigE6 5 100000 -Ethernet24 9,10,11,12 hundredGigE7 6 100000 -Ethernet28 13,14,15,16 hundredGigE8 7 100000 -Ethernet32 17,18,19,20 hundredGigE9 8 100000 -Ethernet36 21,22,23,24 hundredGigE10 9 100000 -Ethernet40 25,26,27,28 hundredGigE11 10 100000 -Ethernet44 37,38,39,40 hundredGigE12 11 100000 -Ethernet48 49,50,51,52 hundredGigE13 12 100000 -Ethernet52 53,54,55,56 hundredGigE14 13 100000 -Ethernet56 57,58,59,60 hundredGigE15 14 100000 -Ethernet60 61,62,63,64 hundredGigE16 15 100000 -Ethernet64 65,66,67,68 hundredGigE17 16 100000 -Ethernet68 69,70,71,72 hundredGigE18 17 100000 -Ethernet72 73,74,75,76 hundredGigE19 18 100000 -Ethernet76 77,78,79,80 hundredGigE20 19 100000 -Ethernet80 93,94,95,96 hundredGigE21 20 100000 -Ethernet84 101,102,103,104 hundredGigE22 21 100000 -Ethernet88 105,106,107,108 hundredGigE23 22 100000 -Ethernet92 109,110,111,112 hundredGigE24 23 100000 -Ethernet96 113,114,115,116 hundredGigE25 24 100000 -Ethernet100 117,118,119,120 hundredGigE26 25 100000 -Ethernet104 121,122,123,124 hundredGigE27 26 100000 -Ethernet108 125,126,127,128 hundredGigE28 27 100000 -Ethernet112 81,82,83,84 hundredGigE29 28 100000 -Ethernet116 85,86,87,88 hundredGigE30 29 100000 -Ethernet120 89,90,91,92 hundredGigE31 30 100000 -Ethernet124 97,98,99,100 hundredGigE32 31 100000 +Ethernet0 29,30,31,32 hundredGigE1 1 100000 +Ethernet4 33,34,35,36 hundredGigE2 2 100000 +Ethernet8 41,42,43,44 hundredGigE3 3 100000 +Ethernet12 45,46,47,48 hundredGigE4 4 100000 +Ethernet16 1,2,3,4 hundredGigE5 5 100000 +Ethernet20 5,6,7,8 hundredGigE6 6 100000 +Ethernet24 9,10,11,12 hundredGigE7 7 100000 +Ethernet28 13,14,15,16 hundredGigE8 8 100000 +Ethernet32 17,18,19,20 hundredGigE9 9 100000 +Ethernet36 21,22,23,24 hundredGigE10 10 100000 +Ethernet40 25,26,27,28 hundredGigE11 11 100000 +Ethernet44 37,38,39,40 hundredGigE12 12 100000 +Ethernet48 49,50,51,52 hundredGigE13 13 100000 +Ethernet52 53,54,55,56 hundredGigE14 14 100000 +Ethernet56 57,58,59,60 hundredGigE15 15 100000 +Ethernet60 61,62,63,64 hundredGigE16 16 100000 +Ethernet64 65,66,67,68 hundredGigE17 17 100000 +Ethernet68 69,70,71,72 hundredGigE18 18 100000 +Ethernet72 73,74,75,76 hundredGigE19 19 100000 +Ethernet76 77,78,79,80 hundredGigE20 20 100000 +Ethernet80 93,94,95,96 hundredGigE21 21 100000 +Ethernet84 101,102,103,104 hundredGigE22 22 100000 +Ethernet88 105,106,107,108 hundredGigE23 23 100000 +Ethernet92 109,110,111,112 hundredGigE24 24 100000 +Ethernet96 113,114,115,116 hundredGigE25 25 100000 +Ethernet100 117,118,119,120 hundredGigE26 26 100000 +Ethernet104 121,122,123,124 hundredGigE27 27 100000 +Ethernet108 125,126,127,128 hundredGigE28 28 100000 +Ethernet112 81,82,83,84 hundredGigE29 29 100000 +Ethernet116 85,86,87,88 hundredGigE30 30 100000 +Ethernet120 89,90,91,92 hundredGigE31 31 100000 +Ethernet124 97,98,99,100 hundredGigE32 32 100000 diff --git a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/plugins/sfputil.py b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/plugins/sfputil.py index 09ce8928b8e9..85a4aad26dae 100644 --- a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/plugins/sfputil.py +++ b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/plugins/sfputil.py @@ -1,53 +1,58 @@ -#!/usr/bin/env python +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# try: import time - from sonic_sfp.sfputilbase import SfpUtilBase -except ImportError, e: - raise ImportError (str(e) + "- required module not found") + import string + from ctypes import create_string_buffer + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) class SfpUtil(SfpUtilBase): - """Platform specific SfpUtill class""" + """Platform-specific SfpUtil class""" - PORT_START = 0 - PORT_END = 31 + PORT_START = 1 + PORT_END = 32 PORTS_IN_BLOCK = 32 _port_to_eeprom_mapping = {} _port_to_i2c_mapping = { - 0 : 32, - 1 : 33, - 2 : 34, - 3 : 35, - 4 : 36, - 5 : 37, - 6 : 38, - 7 : 39, - 8 : 40, - 9 : 41, - 10 : 42, - 11 : 43, - 12 : 44, - 13 : 45, - 14 : 46, - 15 : 47, - 16 : 48, - 17 : 49, - 18 : 50, - 19 : 51, - 20 : 52, - 21 : 53, - 22 : 54, - 23 : 55, - 24 : 56, - 25 : 57, - 26 : 58, - 27 : 59, - 28 : 60, - 29 : 61, - 30 : 62, - 31 : 63, + 1 : 32, + 2 : 33, + 3 : 34, + 4 : 35, + 5 : 36, + 6 : 37, + 7 : 38, + 8 : 39, + 9 : 40, + 10 : 41, + 11 : 42, + 12 : 43, + 13 : 44, + 14 : 45, + 15 : 46, + 16 : 47, + 17 : 48, + 18 : 49, + 19 : 50, + 20 : 51, + 21 : 52, + 22 : 53, + 23 : 54, + 24 : 55, + 25 : 56, + 26 : 57, + 27 : 58, + 28 : 59, + 29 : 60, + 30 : 61, + 31 : 62, + 32 : 63, } @property @@ -68,17 +73,17 @@ def port_to_eeprom_mapping(self): def __init__(self): eeprom_path = '/sys/bus/i2c/devices/{0}-0050/eeprom' - for x in range(0, self.port_end+1): + for x in range(self.port_start, self.port_end+1): self.port_to_eeprom_mapping[x] = eeprom_path.format(self._port_to_i2c_mapping[x]) SfpUtilBase.__init__(self) def get_presence(self, port_num): # Check for invalid port_num - if port_num < self.PORT_START or port_num > self.PORT_END: + if port_num < self.port_start or port_num > self.port_end: return False try: - reg_file = open("/sys/class/cpld-qsfp28/port-"+str(port_num+1)+"/module_present") + reg_file = open("/sys/class/cpld-qsfp28/port-"+str(port_num)+"/module_present") except IOError as e: print "Error: unable to open file: %s" % str(e) return False @@ -95,7 +100,7 @@ def get_low_power_mode(self, port_num): return False try: - reg_file = open("/sys/class/cpld-qsfp28/port-"+str(port_num+1)+"/lpmode") + reg_file = open("/sys/class/cpld-qsfp28/port-"+str(port_num)+"/lpmode") except IOError as e: print "Error: unable to open file: %s" % str(e) return False @@ -113,7 +118,7 @@ def set_low_power_mode(self, port_num, lpmode): return False try: - reg_file = open("/sys/class/cpld-qsfp28/port-"+str(port_num+1)+"/lpmode", "r+") + reg_file = open("/sys/class/cpld-qsfp28/port-"+str(port_num)+"/lpmode", "r+") except IOError as e: print "Error: unable to open file: %s" % str(e) return False @@ -137,7 +142,7 @@ def reset(self, port_num): return False try: - reg_file = open("/sys/class/cpld-qsfp28/port-"+str(port_num+1)+"/reset", "r+") + reg_file = open("/sys/class/cpld-qsfp28/port-"+str(port_num)+"/reset", "r+") except IOError as e: print "Error: unable to open file: %s" % str(e) return False @@ -151,7 +156,7 @@ def reset(self, port_num): # Flip the value back write back to the register to take port out of reset try: - reg_file = open("/sys/class/cpld-qsfp28/port-"+str(port_num+1)+"/reset", "r+") + reg_file = open("/sys/class/cpld-qsfp28/port-"+str(port_num)+"/reset", "r+") except IOError as e: print "Error: unable to open file: %s" % str(e) return False diff --git a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/port_config.ini b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/port_config.ini index 1b33f50c92dd..c9dd2fb999f9 100644 --- a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/port_config.ini +++ b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/Quanta-IX8-56X/port_config.ini @@ -1,57 +1,57 @@ # name lanes alias index speed -Ethernet0 60 twentyfiveGigE1 0 25000 -Ethernet1 59 twentyfiveGigE2 1 25000 -Ethernet2 58 twentyfiveGigE3 2 25000 -Ethernet3 57 twentyfiveGigE4 3 25000 -Ethernet4 64 twentyfiveGigE5 4 25000 -Ethernet5 63 twentyfiveGigE6 5 25000 -Ethernet6 62 twentyfiveGigE7 6 25000 -Ethernet7 61 twentyfiveGigE8 7 25000 -Ethernet8 49 twentyfiveGigE9 8 25000 -Ethernet9 50 twentyfiveGigE10 9 25000 -Ethernet10 51 twentyfiveGigE11 10 25000 -Ethernet11 52 twentyfiveGigE12 11 25000 -Ethernet12 4 twentyfiveGigE13 12 25000 -Ethernet13 3 twentyfiveGigE14 13 25000 -Ethernet14 2 twentyfiveGigE15 14 25000 -Ethernet15 1 twentyfiveGigE16 15 25000 -Ethernet16 8 twentyfiveGigE17 16 25000 -Ethernet17 7 twentyfiveGigE18 17 25000 -Ethernet18 6 twentyfiveGigE19 18 25000 -Ethernet19 5 twentyfiveGigE20 19 25000 -Ethernet20 16 twentyfiveGigE21 20 25000 -Ethernet21 15 twentyfiveGigE22 21 25000 -Ethernet22 14 twentyfiveGigE23 22 25000 -Ethernet23 13 twentyfiveGigE24 23 25000 -Ethernet24 24 twentyfiveGigE25 24 25000 -Ethernet25 23 twentyfiveGigE26 25 25000 -Ethernet26 22 twentyfiveGigE27 26 25000 -Ethernet27 21 twentyfiveGigE28 27 25000 -Ethernet28 32 twentyfiveGigE29 28 25000 -Ethernet29 31 twentyfiveGigE30 29 25000 -Ethernet30 30 twentyfiveGigE31 30 25000 -Ethernet31 29 twentyfiveGigE32 31 25000 -Ethernet32 36 twentyfiveGigE33 32 25000 -Ethernet33 35 twentyfiveGigE34 33 25000 -Ethernet34 34 twentyfiveGigE35 34 25000 -Ethernet35 33 twentyfiveGigE36 35 25000 -Ethernet36 44 twentyfiveGigE37 36 25000 -Ethernet37 43 twentyfiveGigE38 37 25000 -Ethernet38 42 twentyfiveGigE39 38 25000 -Ethernet39 41 twentyfiveGigE40 39 25000 -Ethernet40 86 twentyfiveGigE41 40 25000 -Ethernet41 85 twentyfiveGigE42 41 25000 -Ethernet42 88 twentyfiveGigE43 42 25000 -Ethernet43 87 twentyfiveGigE44 43 25000 -Ethernet44 94 twentyfiveGigE45 44 25000 -Ethernet45 93 twentyfiveGigE46 45 25000 -Ethernet46 96 twentyfiveGigE47 46 25000 -Ethernet47 95 twentyfiveGigE48 47 25000 -Ethernet48 97,98,99,100 hundredGigE49 48 100000 -Ethernet52 105,106,107,108 hundredGigE50 49 100000 -Ethernet56 113,114,115,116 hundredGigE51 50 100000 -Ethernet60 121,122,123,124 hundredGigE52 51 100000 -Ethernet64 77,78,79,80 hundredGigE53 52 100000 -Ethernet68 65,66,67,68 hundredGigE54 53 100000 -Ethernet72 69,70,71,72 hundredGigE55 54 100000 -Ethernet76 125,126,127,128 hundredGigE56 55 100000 +Ethernet0 60 twentyfiveGigE1 1 25000 +Ethernet1 59 twentyfiveGigE2 2 25000 +Ethernet2 58 twentyfiveGigE3 3 25000 +Ethernet3 57 twentyfiveGigE4 4 25000 +Ethernet4 64 twentyfiveGigE5 5 25000 +Ethernet5 63 twentyfiveGigE6 6 25000 +Ethernet6 62 twentyfiveGigE7 7 25000 +Ethernet7 61 twentyfiveGigE8 8 25000 +Ethernet8 49 twentyfiveGigE9 9 25000 +Ethernet9 50 twentyfiveGigE10 10 25000 +Ethernet10 51 twentyfiveGigE11 11 25000 +Ethernet11 52 twentyfiveGigE12 12 25000 +Ethernet12 4 twentyfiveGigE13 13 25000 +Ethernet13 3 twentyfiveGigE14 14 25000 +Ethernet14 2 twentyfiveGigE15 15 25000 +Ethernet15 1 twentyfiveGigE16 16 25000 +Ethernet16 8 twentyfiveGigE17 17 25000 +Ethernet17 7 twentyfiveGigE18 18 25000 +Ethernet18 6 twentyfiveGigE19 19 25000 +Ethernet19 5 twentyfiveGigE20 20 25000 +Ethernet20 16 twentyfiveGigE21 21 25000 +Ethernet21 15 twentyfiveGigE22 22 25000 +Ethernet22 14 twentyfiveGigE23 23 25000 +Ethernet23 13 twentyfiveGigE24 24 25000 +Ethernet24 24 twentyfiveGigE25 25 25000 +Ethernet25 23 twentyfiveGigE26 26 25000 +Ethernet26 22 twentyfiveGigE27 27 25000 +Ethernet27 21 twentyfiveGigE28 28 25000 +Ethernet28 32 twentyfiveGigE29 29 25000 +Ethernet29 31 twentyfiveGigE30 30 25000 +Ethernet30 30 twentyfiveGigE31 31 25000 +Ethernet31 29 twentyfiveGigE32 32 25000 +Ethernet32 36 twentyfiveGigE33 33 25000 +Ethernet33 35 twentyfiveGigE34 34 25000 +Ethernet34 34 twentyfiveGigE35 35 25000 +Ethernet35 33 twentyfiveGigE36 36 25000 +Ethernet36 44 twentyfiveGigE37 37 25000 +Ethernet37 43 twentyfiveGigE38 38 25000 +Ethernet38 42 twentyfiveGigE39 39 25000 +Ethernet39 41 twentyfiveGigE40 40 25000 +Ethernet40 86 twentyfiveGigE41 41 25000 +Ethernet41 85 twentyfiveGigE42 42 25000 +Ethernet42 88 twentyfiveGigE43 43 25000 +Ethernet43 87 twentyfiveGigE44 44 25000 +Ethernet44 94 twentyfiveGigE45 45 25000 +Ethernet45 93 twentyfiveGigE46 46 25000 +Ethernet46 96 twentyfiveGigE47 47 25000 +Ethernet47 95 twentyfiveGigE48 48 25000 +Ethernet48 97,98,99,100 hundredGigE49 49 100000 +Ethernet52 105,106,107,108 hundredGigE50 50 100000 +Ethernet56 113,114,115,116 hundredGigE51 51 100000 +Ethernet60 121,122,123,124 hundredGigE52 52 100000 +Ethernet64 77,78,79,80 hundredGigE53 53 100000 +Ethernet68 65,66,67,68 hundredGigE54 54 100000 +Ethernet72 69,70,71,72 hundredGigE55 55 100000 +Ethernet76 125,126,127,128 hundredGigE56 56 100000 diff --git a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/plugins/sfputil.py b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/plugins/sfputil.py index 205ed3c82d0d..627c99fee0c9 100644 --- a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/plugins/sfputil.py +++ b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/plugins/sfputil.py @@ -1,91 +1,101 @@ -#!/usr/bin/env python +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# try: import time - from sonic_sfp.sfputilbase import SfpUtilBase -except ImportError, e: - raise ImportError (str(e) + "- required module not found") + import string + from ctypes import create_string_buffer + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) class SfpUtil(SfpUtilBase): - """Platform specific SfpUtill class""" + """Platform-specific SfpUtil class""" - PORT_START = 0 - PORT_END = 55 - QSFP_PORT_START = 48 + PORT_START = 1 + PORT_END = 56 PORTS_IN_BLOCK = 56 + QSFP_PORT_START = 49 + QSFP_PORT_END = 56 _port_to_eeprom_mapping = {} _port_to_i2c_mapping = { - 0 : 32, - 1 : 33, - 2 : 34, - 3 : 35, - 4 : 36, - 5 : 37, - 6 : 38, - 7 : 39, - 8 : 40, - 9 : 41, - 10 : 42, - 11 : 43, - 12 : 44, - 13 : 45, - 14 : 46, - 15 : 47, - 16 : 48, - 17 : 49, - 18 : 50, - 19 : 51, - 20 : 52, - 21 : 53, - 22 : 54, - 23 : 55, - 24 : 56, - 25 : 57, - 26 : 58, - 27 : 59, - 28 : 60, - 29 : 61, - 30 : 62, - 31 : 63, - 32 : 64, - 33 : 65, - 34 : 66, - 35 : 67, - 36 : 68, - 37 : 69, - 38 : 70, - 39 : 71, - 40 : 72, - 41 : 73, - 42 : 74, - 43 : 75, - 44 : 76, - 45 : 77, - 46 : 78, - 47 : 79, - 48 : 80,#QSFP49 - 49 : 81,#QSFP50 - 50 : 82,#QSFP51 - 51 : 83,#QSFP52 - 52 : 84,#QSFP53 - 53 : 85,#QSFP54 - 54 : 86,#QSFP55 - 55 : 87,#QSFP56 + 1 : 32, + 2 : 33, + 3 : 34, + 4 : 35, + 5 : 36, + 6 : 37, + 7 : 38, + 8 : 39, + 9 : 40, + 10 : 41, + 11 : 42, + 12 : 43, + 13 : 44, + 14 : 45, + 15 : 46, + 16 : 47, + 17 : 48, + 18 : 49, + 19 : 50, + 20 : 51, + 21 : 52, + 22 : 53, + 23 : 54, + 24 : 55, + 25 : 56, + 26 : 57, + 27 : 58, + 28 : 59, + 29 : 60, + 30 : 61, + 31 : 62, + 32 : 63, + 33 : 64, + 34 : 65, + 35 : 66, + 36 : 67, + 37 : 68, + 38 : 69, + 39 : 70, + 40 : 71, + 41 : 72, + 42 : 73, + 43 : 74, + 44 : 75, + 45 : 76, + 46 : 77, + 47 : 78, + 48 : 79, + 49 : 80,#QSFP49 + 50 : 81,#QSFP50 + 51 : 82,#QSFP51 + 52 : 83,#QSFP52 + 53 : 84,#QSFP53 + 54 : 85,#QSFP54 + 55 : 86,#QSFP55 + 56 : 87,#QSFP56 } @property 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 port_end(self): - return self.PORT_END + def qsfp_port_end(self): + return self.QSFP_PORT_END @property def qsfp_ports(self): @@ -97,26 +107,26 @@ def port_to_eeprom_mapping(self): def __init__(self): eeprom_path = '/sys/bus/i2c/devices/{0}-0050/eeprom' - for x in range(0, self.port_end+1): + for x in range(self.port_start, self.port_end+1): self.port_to_eeprom_mapping[x] = eeprom_path.format(self._port_to_i2c_mapping[x]) SfpUtilBase.__init__(self) def get_presence(self, port_num): # Check for invalid port_num - if port_num < self.PORT_START or port_num > self.PORT_END: + if port_num < self.port_start or port_num > self.port_end: return False try: - if port_num < 48: - reg_file = open("/sys/class/cpld-sfp28/port-"+str(port_num+1)+"/pre_n") + if port_num < self.qsfp_port_start: + reg_file = open("/sys/class/cpld-sfp28/port-"+str(port_num)+"/pre_n") else: - reg_file = open("/sys/class/gpio/gpio"+str((port_num-48)*4+34)+"/value") + reg_file = open("/sys/class/gpio/gpio"+str((port_num-self.qsfp_port_start)*4+34)+"/value") except IOError as e: print "Error: unable to open file: %s" % str(e) return False reg_value = reg_file.readline().rstrip() - if port_num < 48: + if port_num < self.qsfp_port_start: if reg_value == '1': return True else: @@ -127,11 +137,11 @@ def get_presence(self, port_num): def get_low_power_mode(self, port_num): # Check for invalid port_num - if port_num < self.qsfp_port_start or port_num > self.port_end: + if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False try: - reg_file = open("/sys/class/gpio/gpio"+str((port_num-48)*4+35)+"/value") + reg_file = open("/sys/class/gpio/gpio"+str((port_num-self.qsfp_port_start)*4+35)+"/value") except IOError as e: print "Error: unable to open file: %s" % str(e) return False @@ -145,11 +155,11 @@ def get_low_power_mode(self, port_num): def set_low_power_mode(self, port_num, lpmode): # Check for invalid port_num - if port_num < self.qsfp_port_start or port_num > self.port_end: + if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False try: - reg_file = open("/sys/class/gpio/gpio"+str((port_num-48)*4+35)+"/value", "r+") + reg_file = open("/sys/class/gpio/gpio"+str((port_num-self.qsfp_port_start)*4+35)+"/value", "r+") except IOError as e: print "Error: unable to open file: %s" % str(e) return False @@ -173,7 +183,7 @@ def reset(self, port_num): return False try: - reg_file = open("/sys/class/gpio/gpio"+str((port_num-48)*4+32)+"/value", "r+") + reg_file = open("/sys/class/gpio/gpio"+str((port_num-self.qsfp_port_start)*4+32)+"/value", "r+") except IOError as e: print "Error: unable to open file: %s" % str(e) return False @@ -187,7 +197,7 @@ def reset(self, port_num): # Flip the value back write back to the register to take port out of reset try: - reg_file = open("/sys/class/gpio/gpio"+str((port_num-48)*4+32)+"/value", "r+") + reg_file = open("/sys/class/gpio/gpio"+str((port_num-self.qsfp_port_start)*4+32)+"/value", "r+") except IOError as e: print "Error: unable to open file: %s" % str(e) return False diff --git a/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/port_config.ini b/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/port_config.ini index 1b33f50c92dd..c9dd2fb999f9 100644 --- a/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/port_config.ini +++ b/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/port_config.ini @@ -1,57 +1,57 @@ # name lanes alias index speed -Ethernet0 60 twentyfiveGigE1 0 25000 -Ethernet1 59 twentyfiveGigE2 1 25000 -Ethernet2 58 twentyfiveGigE3 2 25000 -Ethernet3 57 twentyfiveGigE4 3 25000 -Ethernet4 64 twentyfiveGigE5 4 25000 -Ethernet5 63 twentyfiveGigE6 5 25000 -Ethernet6 62 twentyfiveGigE7 6 25000 -Ethernet7 61 twentyfiveGigE8 7 25000 -Ethernet8 49 twentyfiveGigE9 8 25000 -Ethernet9 50 twentyfiveGigE10 9 25000 -Ethernet10 51 twentyfiveGigE11 10 25000 -Ethernet11 52 twentyfiveGigE12 11 25000 -Ethernet12 4 twentyfiveGigE13 12 25000 -Ethernet13 3 twentyfiveGigE14 13 25000 -Ethernet14 2 twentyfiveGigE15 14 25000 -Ethernet15 1 twentyfiveGigE16 15 25000 -Ethernet16 8 twentyfiveGigE17 16 25000 -Ethernet17 7 twentyfiveGigE18 17 25000 -Ethernet18 6 twentyfiveGigE19 18 25000 -Ethernet19 5 twentyfiveGigE20 19 25000 -Ethernet20 16 twentyfiveGigE21 20 25000 -Ethernet21 15 twentyfiveGigE22 21 25000 -Ethernet22 14 twentyfiveGigE23 22 25000 -Ethernet23 13 twentyfiveGigE24 23 25000 -Ethernet24 24 twentyfiveGigE25 24 25000 -Ethernet25 23 twentyfiveGigE26 25 25000 -Ethernet26 22 twentyfiveGigE27 26 25000 -Ethernet27 21 twentyfiveGigE28 27 25000 -Ethernet28 32 twentyfiveGigE29 28 25000 -Ethernet29 31 twentyfiveGigE30 29 25000 -Ethernet30 30 twentyfiveGigE31 30 25000 -Ethernet31 29 twentyfiveGigE32 31 25000 -Ethernet32 36 twentyfiveGigE33 32 25000 -Ethernet33 35 twentyfiveGigE34 33 25000 -Ethernet34 34 twentyfiveGigE35 34 25000 -Ethernet35 33 twentyfiveGigE36 35 25000 -Ethernet36 44 twentyfiveGigE37 36 25000 -Ethernet37 43 twentyfiveGigE38 37 25000 -Ethernet38 42 twentyfiveGigE39 38 25000 -Ethernet39 41 twentyfiveGigE40 39 25000 -Ethernet40 86 twentyfiveGigE41 40 25000 -Ethernet41 85 twentyfiveGigE42 41 25000 -Ethernet42 88 twentyfiveGigE43 42 25000 -Ethernet43 87 twentyfiveGigE44 43 25000 -Ethernet44 94 twentyfiveGigE45 44 25000 -Ethernet45 93 twentyfiveGigE46 45 25000 -Ethernet46 96 twentyfiveGigE47 46 25000 -Ethernet47 95 twentyfiveGigE48 47 25000 -Ethernet48 97,98,99,100 hundredGigE49 48 100000 -Ethernet52 105,106,107,108 hundredGigE50 49 100000 -Ethernet56 113,114,115,116 hundredGigE51 50 100000 -Ethernet60 121,122,123,124 hundredGigE52 51 100000 -Ethernet64 77,78,79,80 hundredGigE53 52 100000 -Ethernet68 65,66,67,68 hundredGigE54 53 100000 -Ethernet72 69,70,71,72 hundredGigE55 54 100000 -Ethernet76 125,126,127,128 hundredGigE56 55 100000 +Ethernet0 60 twentyfiveGigE1 1 25000 +Ethernet1 59 twentyfiveGigE2 2 25000 +Ethernet2 58 twentyfiveGigE3 3 25000 +Ethernet3 57 twentyfiveGigE4 4 25000 +Ethernet4 64 twentyfiveGigE5 5 25000 +Ethernet5 63 twentyfiveGigE6 6 25000 +Ethernet6 62 twentyfiveGigE7 7 25000 +Ethernet7 61 twentyfiveGigE8 8 25000 +Ethernet8 49 twentyfiveGigE9 9 25000 +Ethernet9 50 twentyfiveGigE10 10 25000 +Ethernet10 51 twentyfiveGigE11 11 25000 +Ethernet11 52 twentyfiveGigE12 12 25000 +Ethernet12 4 twentyfiveGigE13 13 25000 +Ethernet13 3 twentyfiveGigE14 14 25000 +Ethernet14 2 twentyfiveGigE15 15 25000 +Ethernet15 1 twentyfiveGigE16 16 25000 +Ethernet16 8 twentyfiveGigE17 17 25000 +Ethernet17 7 twentyfiveGigE18 18 25000 +Ethernet18 6 twentyfiveGigE19 19 25000 +Ethernet19 5 twentyfiveGigE20 20 25000 +Ethernet20 16 twentyfiveGigE21 21 25000 +Ethernet21 15 twentyfiveGigE22 22 25000 +Ethernet22 14 twentyfiveGigE23 23 25000 +Ethernet23 13 twentyfiveGigE24 24 25000 +Ethernet24 24 twentyfiveGigE25 25 25000 +Ethernet25 23 twentyfiveGigE26 26 25000 +Ethernet26 22 twentyfiveGigE27 27 25000 +Ethernet27 21 twentyfiveGigE28 28 25000 +Ethernet28 32 twentyfiveGigE29 29 25000 +Ethernet29 31 twentyfiveGigE30 30 25000 +Ethernet30 30 twentyfiveGigE31 31 25000 +Ethernet31 29 twentyfiveGigE32 32 25000 +Ethernet32 36 twentyfiveGigE33 33 25000 +Ethernet33 35 twentyfiveGigE34 34 25000 +Ethernet34 34 twentyfiveGigE35 35 25000 +Ethernet35 33 twentyfiveGigE36 36 25000 +Ethernet36 44 twentyfiveGigE37 37 25000 +Ethernet37 43 twentyfiveGigE38 38 25000 +Ethernet38 42 twentyfiveGigE39 39 25000 +Ethernet39 41 twentyfiveGigE40 40 25000 +Ethernet40 86 twentyfiveGigE41 41 25000 +Ethernet41 85 twentyfiveGigE42 42 25000 +Ethernet42 88 twentyfiveGigE43 43 25000 +Ethernet43 87 twentyfiveGigE44 44 25000 +Ethernet44 94 twentyfiveGigE45 45 25000 +Ethernet45 93 twentyfiveGigE46 46 25000 +Ethernet46 96 twentyfiveGigE47 47 25000 +Ethernet47 95 twentyfiveGigE48 48 25000 +Ethernet48 97,98,99,100 hundredGigE49 49 100000 +Ethernet52 105,106,107,108 hundredGigE50 50 100000 +Ethernet56 113,114,115,116 hundredGigE51 51 100000 +Ethernet60 121,122,123,124 hundredGigE52 52 100000 +Ethernet64 77,78,79,80 hundredGigE53 53 100000 +Ethernet68 65,66,67,68 hundredGigE54 54 100000 +Ethernet72 69,70,71,72 hundredGigE55 55 100000 +Ethernet76 125,126,127,128 hundredGigE56 56 100000 diff --git a/device/quanta/x86_64-quanta_ix8c_bwde-r0/plugins/sfputil.py b/device/quanta/x86_64-quanta_ix8c_bwde-r0/plugins/sfputil.py index 205ed3c82d0d..627c99fee0c9 100644 --- a/device/quanta/x86_64-quanta_ix8c_bwde-r0/plugins/sfputil.py +++ b/device/quanta/x86_64-quanta_ix8c_bwde-r0/plugins/sfputil.py @@ -1,91 +1,101 @@ -#!/usr/bin/env python +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# try: import time - from sonic_sfp.sfputilbase import SfpUtilBase -except ImportError, e: - raise ImportError (str(e) + "- required module not found") + import string + from ctypes import create_string_buffer + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) class SfpUtil(SfpUtilBase): - """Platform specific SfpUtill class""" + """Platform-specific SfpUtil class""" - PORT_START = 0 - PORT_END = 55 - QSFP_PORT_START = 48 + PORT_START = 1 + PORT_END = 56 PORTS_IN_BLOCK = 56 + QSFP_PORT_START = 49 + QSFP_PORT_END = 56 _port_to_eeprom_mapping = {} _port_to_i2c_mapping = { - 0 : 32, - 1 : 33, - 2 : 34, - 3 : 35, - 4 : 36, - 5 : 37, - 6 : 38, - 7 : 39, - 8 : 40, - 9 : 41, - 10 : 42, - 11 : 43, - 12 : 44, - 13 : 45, - 14 : 46, - 15 : 47, - 16 : 48, - 17 : 49, - 18 : 50, - 19 : 51, - 20 : 52, - 21 : 53, - 22 : 54, - 23 : 55, - 24 : 56, - 25 : 57, - 26 : 58, - 27 : 59, - 28 : 60, - 29 : 61, - 30 : 62, - 31 : 63, - 32 : 64, - 33 : 65, - 34 : 66, - 35 : 67, - 36 : 68, - 37 : 69, - 38 : 70, - 39 : 71, - 40 : 72, - 41 : 73, - 42 : 74, - 43 : 75, - 44 : 76, - 45 : 77, - 46 : 78, - 47 : 79, - 48 : 80,#QSFP49 - 49 : 81,#QSFP50 - 50 : 82,#QSFP51 - 51 : 83,#QSFP52 - 52 : 84,#QSFP53 - 53 : 85,#QSFP54 - 54 : 86,#QSFP55 - 55 : 87,#QSFP56 + 1 : 32, + 2 : 33, + 3 : 34, + 4 : 35, + 5 : 36, + 6 : 37, + 7 : 38, + 8 : 39, + 9 : 40, + 10 : 41, + 11 : 42, + 12 : 43, + 13 : 44, + 14 : 45, + 15 : 46, + 16 : 47, + 17 : 48, + 18 : 49, + 19 : 50, + 20 : 51, + 21 : 52, + 22 : 53, + 23 : 54, + 24 : 55, + 25 : 56, + 26 : 57, + 27 : 58, + 28 : 59, + 29 : 60, + 30 : 61, + 31 : 62, + 32 : 63, + 33 : 64, + 34 : 65, + 35 : 66, + 36 : 67, + 37 : 68, + 38 : 69, + 39 : 70, + 40 : 71, + 41 : 72, + 42 : 73, + 43 : 74, + 44 : 75, + 45 : 76, + 46 : 77, + 47 : 78, + 48 : 79, + 49 : 80,#QSFP49 + 50 : 81,#QSFP50 + 51 : 82,#QSFP51 + 52 : 83,#QSFP52 + 53 : 84,#QSFP53 + 54 : 85,#QSFP54 + 55 : 86,#QSFP55 + 56 : 87,#QSFP56 } @property 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 port_end(self): - return self.PORT_END + def qsfp_port_end(self): + return self.QSFP_PORT_END @property def qsfp_ports(self): @@ -97,26 +107,26 @@ def port_to_eeprom_mapping(self): def __init__(self): eeprom_path = '/sys/bus/i2c/devices/{0}-0050/eeprom' - for x in range(0, self.port_end+1): + for x in range(self.port_start, self.port_end+1): self.port_to_eeprom_mapping[x] = eeprom_path.format(self._port_to_i2c_mapping[x]) SfpUtilBase.__init__(self) def get_presence(self, port_num): # Check for invalid port_num - if port_num < self.PORT_START or port_num > self.PORT_END: + if port_num < self.port_start or port_num > self.port_end: return False try: - if port_num < 48: - reg_file = open("/sys/class/cpld-sfp28/port-"+str(port_num+1)+"/pre_n") + if port_num < self.qsfp_port_start: + reg_file = open("/sys/class/cpld-sfp28/port-"+str(port_num)+"/pre_n") else: - reg_file = open("/sys/class/gpio/gpio"+str((port_num-48)*4+34)+"/value") + reg_file = open("/sys/class/gpio/gpio"+str((port_num-self.qsfp_port_start)*4+34)+"/value") except IOError as e: print "Error: unable to open file: %s" % str(e) return False reg_value = reg_file.readline().rstrip() - if port_num < 48: + if port_num < self.qsfp_port_start: if reg_value == '1': return True else: @@ -127,11 +137,11 @@ def get_presence(self, port_num): def get_low_power_mode(self, port_num): # Check for invalid port_num - if port_num < self.qsfp_port_start or port_num > self.port_end: + if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False try: - reg_file = open("/sys/class/gpio/gpio"+str((port_num-48)*4+35)+"/value") + reg_file = open("/sys/class/gpio/gpio"+str((port_num-self.qsfp_port_start)*4+35)+"/value") except IOError as e: print "Error: unable to open file: %s" % str(e) return False @@ -145,11 +155,11 @@ def get_low_power_mode(self, port_num): def set_low_power_mode(self, port_num, lpmode): # Check for invalid port_num - if port_num < self.qsfp_port_start or port_num > self.port_end: + if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False try: - reg_file = open("/sys/class/gpio/gpio"+str((port_num-48)*4+35)+"/value", "r+") + reg_file = open("/sys/class/gpio/gpio"+str((port_num-self.qsfp_port_start)*4+35)+"/value", "r+") except IOError as e: print "Error: unable to open file: %s" % str(e) return False @@ -173,7 +183,7 @@ def reset(self, port_num): return False try: - reg_file = open("/sys/class/gpio/gpio"+str((port_num-48)*4+32)+"/value", "r+") + reg_file = open("/sys/class/gpio/gpio"+str((port_num-self.qsfp_port_start)*4+32)+"/value", "r+") except IOError as e: print "Error: unable to open file: %s" % str(e) return False @@ -187,7 +197,7 @@ def reset(self, port_num): # Flip the value back write back to the register to take port out of reset try: - reg_file = open("/sys/class/gpio/gpio"+str((port_num-48)*4+32)+"/value", "r+") + reg_file = open("/sys/class/gpio/gpio"+str((port_num-self.qsfp_port_start)*4+32)+"/value", "r+") except IOError as e: print "Error: unable to open file: %s" % str(e) return False diff --git a/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/port_config.ini b/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/port_config.ini new file mode 100644 index 000000000000..8f770329437f --- /dev/null +++ b/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index +Ethernet0 33,34,35,36,37,38,39,40 fourhundredGigE1 0 +Ethernet4 25,26,27,28,29,30,31,32 fourhundredGigE2 1 +Ethernet8 49,50,51,52,53,54,55,56 fourhundredGigE3 2 +Ethernet12 57,58,59,60,61,62,63,64 fourhundredGigE4 3 +Ethernet16 65,66,67,68,69,70,71,72 fourhundredGigE5 4 +Ethernet20 73,74,75,76,77,78,79,80 fourhundredGigE6 5 +Ethernet24 81,82,83,84,85,86,87,88 fourhundredGigE7 6 +Ethernet28 89,90,91,92,93,94,95,96 fourhundredGigE8 7 +Ethernet32 17,18,19,20,21,22,23,24 fourhundredGigE9 8 +Ethernet36 97,98,99,100,101,102,103,104 fourhundredGigE10 9 +Ethernet40 9,10,11,12,13,14,15,16 fourhundredGigE11 10 +Ethernet44 41,42,43,44,45,46,47,48 fourhundredGigE12 11 +Ethernet48 113,114,115,116,117,118,119,120 fourhundredGigE13 12 +Ethernet52 105,106,107,108,109,110,111,112 fourhundredGigE14 13 +Ethernet56 121,122,123,124,125,126,127,128 fourhundredGigE15 14 +Ethernet60 1,2,3,4,5,6,7,8 fourhundredGigE16 15 +Ethernet64 137,138,139,140,141,142,143,144 fourhundredGigE17 16 +Ethernet68 129,130,131,132,133,134,135,136 fourhundredGigE18 17 +Ethernet72 241,242,243,244,245,246,247,248 fourhundredGigE19 18 +Ethernet76 249,250,251,252,253,254,255,256 fourhundredGigE20 19 +Ethernet80 225,226,227,228,229,230,231,232 fourhundredGigE21 20 +Ethernet84 145,146,147,148,149,150,151,152 fourhundredGigE22 21 +Ethernet88 153,154,155,156,157,158,159,160 fourhundredGigE23 22 +Ethernet92 233,234,235,236,237,238,239,240 fourhundredGigE24 23 +Ethernet96 161,162,163,164,165,166,167,168 fourhundredGigE25 24 +Ethernet100 169,170,171,172,173,174,175,176 fourhundredGigE26 25 +Ethernet104 177,178,179,180,181,182,183,184 fourhundredGigE27 26 +Ethernet108 185,186,187,188,189,190,191,192 fourhundredGigE28 27 +Ethernet112 193,194,195,196,197,198,199,200 fourhundredGigE29 28 +Ethernet116 201,202,203,204,205,206,207,208 fourhundredGigE30 29 +Ethernet120 209,210,211,212,213,214,215,216 fourhundredGigE31 30 +Ethernet124 217,218,219,220,221,222,223,224 fourhundredGigE32 31 diff --git a/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/sai.profile b/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/sai.profile new file mode 100644 index 000000000000..54b62b1d097c --- /dev/null +++ b/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-ix9-32x400G.config.bcm diff --git a/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/th3-ix9-32x400G.config.bcm b/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/th3-ix9-32x400G.config.bcm new file mode 100644 index 000000000000..704183e10924 --- /dev/null +++ b/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/th3-ix9-32x400G.config.bcm @@ -0,0 +1,341 @@ +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 +core_clock_frequency=1325 +dpr_clock_frequency=1000 +device_clock_frequency=1325 + +load_firmware=0x2 +port_flex_enable=1 + +# portmap settings +pbmp_xport_xe=0x111101111411110111101111011114111102222 + +portmap_1=1:400 +portmap_5=9:400 +portmap_9=17:400 +portmap_13=25:400 +portmap_20=33:400 +portmap_24=41:400 +portmap_28=49:400 +portmap_32=57:400 + +portmap_40=65:400 +portmap_44=73:400 +portmap_48=81:400 +portmap_52=89:400 +portmap_60=97:400 +portmap_64=105:400 +portmap_68=113:400 +portmap_72=121:400 + +portmap_80=129:400 +portmap_84=137:400 +portmap_88=145:400 +portmap_92=153:400 +portmap_100=161:400 +portmap_104=169:400 +portmap_108=177:400 +portmap_112=185:400 + +portmap_120=193:400 +portmap_124=201:400 +portmap_128=209:400 +portmap_132=217:400 +portmap_140=225:400 +portmap_144=233:400 +portmap_148=241:400 +portmap_152=249:400 + +# datapath port +portmap_38=257:10 +portmap_118=258:10 + +# loopback port +portmap_19=260: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 + +# port order remap +dport_map_port_20=1 +dport_map_port_13=2 +dport_map_port_28=3 +dport_map_port_32=4 +dport_map_port_40=5 +dport_map_port_44=6 +dport_map_port_48=7 +dport_map_port_52=8 +dport_map_port_9=9 +dport_map_port_60=10 +dport_map_port_5=11 +dport_map_port_24=12 +dport_map_port_68=13 +dport_map_port_64=14 +dport_map_port_72=15 +dport_map_port_1=16 + +dport_map_port_84=17 +dport_map_port_80=18 +dport_map_port_148=19 +dport_map_port_152=20 +dport_map_port_140=21 +dport_map_port_88=22 +dport_map_port_92=23 +dport_map_port_144=24 +dport_map_port_100=25 +dport_map_port_104=26 +dport_map_port_108=27 +dport_map_port_112=28 +dport_map_port_120=29 +dport_map_port_124=30 +dport_map_port_128=31 +dport_map_port_132=32 + +dport_map_port_38=33 +dport_map_port_118=34 + +### lane swap and polarity follow front port order ### +phy_chain_tx_lane_map_physical{33.0}=0x75206431 +serdes_core_tx_polarity_flip_physical{33}=0xdb +phy_chain_rx_lane_map_physical{33.0}=0x13572064 +serdes_core_rx_polarity_flip_physical{33}=0x69 + +phy_chain_tx_lane_map_physical{25.0}=0x75314206 +serdes_core_tx_polarity_flip_physical{25}=0xe8 +phy_chain_rx_lane_map_physical{25.0}=0x67103524 +serdes_core_rx_polarity_flip_physical{25}=0x7c + +phy_chain_tx_lane_map_physical{49.0}=0x57326014 +serdes_core_tx_polarity_flip_physical{49}=0x0e +phy_chain_rx_lane_map_physical{49.0}=0x21463057 +serdes_core_rx_polarity_flip_physical{49}=0xd2 + +phy_chain_tx_lane_map_physical{57.0}=0x12307564 +serdes_core_tx_polarity_flip_physical{57}=0xa6 +phy_chain_rx_lane_map_physical{57.0}=0x57460231 +serdes_core_rx_polarity_flip_physical{57}=0x99 + +phy_chain_tx_lane_map_physical{65.0}=0x60345721 +serdes_core_tx_polarity_flip_physical{65}=0xe2 +phy_chain_rx_lane_map_physical{65.0}=0x40675123 +serdes_core_rx_polarity_flip_physical{65}=0x0f + +phy_chain_tx_lane_map_physical{73.0}=0x21306574 +serdes_core_tx_polarity_flip_physical{73}=0xa4 +phy_chain_rx_lane_map_physical{73.0}=0x67451302 +serdes_core_rx_polarity_flip_physical{73}=0x06 + +phy_chain_tx_lane_map_physical{81.0}=0x65210347 +serdes_core_tx_polarity_flip_physical{81}=0xe2 +phy_chain_rx_lane_map_physical{81.0}=0x10675423 +serdes_core_rx_polarity_flip_physical{81}=0x0f + +phy_chain_tx_lane_map_physical{89.0}=0x41236570 +serdes_core_tx_polarity_flip_physical{89}=0x8d +phy_chain_rx_lane_map_physical{89.0}=0x45672031 +serdes_core_rx_polarity_flip_physical{89}=0x63 + +phy_chain_tx_lane_map_physical{17.0}=0x76312504 +serdes_core_tx_polarity_flip_physical{17}=0x8e +phy_chain_rx_lane_map_physical{17.0}=0x75126403 +serdes_core_rx_polarity_flip_physical{17}=0x2d + +phy_chain_tx_lane_map_physical{97.0}=0x31025764 +serdes_core_tx_polarity_flip_physical{97}=0x3c +phy_chain_rx_lane_map_physical{97.0}=0x52136470 +serdes_core_rx_polarity_flip_physical{97}=0x9c + +phy_chain_tx_lane_map_physical{9.0}=0x57326014 +serdes_core_tx_polarity_flip_physical{9}=0x3d +phy_chain_rx_lane_map_physical{9.0}=0x31452076 +serdes_core_rx_polarity_flip_physical{9}=0x1e + +phy_chain_tx_lane_map_physical{41.0}=0x03215764 +serdes_core_tx_polarity_flip_physical{41}=0x3c +phy_chain_rx_lane_map_physical{41.0}=0x54671302 +serdes_core_rx_polarity_flip_physical{41}=0x99 + +phy_chain_tx_lane_map_physical{113.0}=0x60175243 +serdes_core_tx_polarity_flip_physical{113}=0xcd +phy_chain_rx_lane_map_physical{113.0}=0x20473156 +serdes_core_rx_polarity_flip_physical{113}=0x87 + +phy_chain_tx_lane_map_physical{105.0}=0x65034721 +serdes_core_tx_polarity_flip_physical{105}=0xe6 +phy_chain_rx_lane_map_physical{105.0}=0x04157263 +serdes_core_rx_polarity_flip_physical{105}=0x4c + +phy_chain_tx_lane_map_physical{121.0}=0x16435072 +serdes_core_tx_polarity_flip_physical{121}=0xae +phy_chain_rx_lane_map_physical{121.0}=0x13560247 +serdes_core_rx_polarity_flip_physical{121}=0x2d + +phy_chain_tx_lane_map_physical{1.0}=0x34650172 +serdes_core_tx_polarity_flip_physical{1}=0xff +phy_chain_rx_lane_map_physical{1.0}=0x13026457 +serdes_core_rx_polarity_flip_physical{1}=0x99 + +phy_chain_tx_lane_map_physical{137.0}=0x02673451 +serdes_core_tx_polarity_flip_physical{137}=0x25 +phy_chain_rx_lane_map_physical{137.0}=0x14730562 +serdes_core_rx_polarity_flip_physical{137}=0x86 + +phy_chain_tx_lane_map_physical{129.0}=0x12304675 +serdes_core_tx_polarity_flip_physical{129}=0x49 +phy_chain_rx_lane_map_physical{129.0}=0x76453021 +serdes_core_rx_polarity_flip_physical{129}=0xc3 + +phy_chain_tx_lane_map_physical{241.0}=0x31462075 +serdes_core_tx_polarity_flip_physical{241}=0xf5 +phy_chain_rx_lane_map_physical{241.0}=0x47315602 +serdes_core_rx_polarity_flip_physical{241}=0xe1 + +phy_chain_tx_lane_map_physical{249.0}=0x13206547 +serdes_core_tx_polarity_flip_physical{249}=0x27 +phy_chain_rx_lane_map_physical{249.0}=0x64750312 +serdes_core_rx_polarity_flip_physical{249}=0xbd + +phy_chain_tx_lane_map_physical{225.0}=0x60315742 +serdes_core_tx_polarity_flip_physical{225}=0x44 +phy_chain_rx_lane_map_physical{225.0}=0x01546372 +serdes_core_rx_polarity_flip_physical{225}=0xc3 + +phy_chain_tx_lane_map_physical{145.0}=0x51374602 +serdes_core_tx_polarity_flip_physical{145}=0x5f +phy_chain_rx_lane_map_physical{145.0}=0x23106754 +serdes_core_rx_polarity_flip_physical{145}=0xbc + +phy_chain_tx_lane_map_physical{153.0}=0x05163742 +serdes_core_tx_polarity_flip_physical{153}=0x0f +phy_chain_rx_lane_map_physical{153.0}=0x67102354 +serdes_core_rx_polarity_flip_physical{153}=0xf0 + +phy_chain_tx_lane_map_physical{233.0}=0x20134576 +serdes_core_tx_polarity_flip_physical{233}=0x07 +phy_chain_rx_lane_map_physical{233.0}=0x23107465 +serdes_core_rx_polarity_flip_physical{233}=0xe6 + +phy_chain_tx_lane_map_physical{161.0}=0x53246710 +serdes_core_tx_polarity_flip_physical{161}=0x0f +phy_chain_rx_lane_map_physical{161.0}=0x03471265 +serdes_core_rx_polarity_flip_physical{161}=0xc0 + +phy_chain_tx_lane_map_physical{169.0}=0x20137654 +serdes_core_tx_polarity_flip_physical{169}=0x8a +phy_chain_rx_lane_map_physical{169.0}=0x27360415 +serdes_core_rx_polarity_flip_physical{169}=0x9c + +phy_chain_tx_lane_map_physical{177.0}=0x50346712 +serdes_core_tx_polarity_flip_physical{177}=0x4f +phy_chain_rx_lane_map_physical{177.0}=0x13460257 +serdes_core_rx_polarity_flip_physical{177}=0x5a + +phy_chain_tx_lane_map_physical{185.0}=0x12305674 +serdes_core_tx_polarity_flip_physical{185}=0xba +phy_chain_rx_lane_map_physical{185.0}=0x57460123 +serdes_core_rx_polarity_flip_physical{185}=0x9f + +phy_chain_tx_lane_map_physical{193.0}=0x50346712 +serdes_core_tx_polarity_flip_physical{193}=0x4f +phy_chain_rx_lane_map_physical{193.0}=0x13750264 +serdes_core_rx_polarity_flip_physical{193}=0x69 + +phy_chain_tx_lane_map_physical{201.0}=0x12305674 +serdes_core_tx_polarity_flip_physical{201}=0xba +phy_chain_rx_lane_map_physical{201.0}=0x57460123 +serdes_core_rx_polarity_flip_physical{201}=0x9f + +phy_chain_tx_lane_map_physical{209.0}=0x50346712 +serdes_core_tx_polarity_flip_physical{209}=0x4f +phy_chain_rx_lane_map_physical{209.0}=0x13460275 +serdes_core_rx_polarity_flip_physical{209}=0x5a + +phy_chain_tx_lane_map_physical{217.0}=0x31205674 +serdes_core_tx_polarity_flip_physical{217}=0x5a +phy_chain_rx_lane_map_physical{217.0}=0x67541203 +serdes_core_rx_polarity_flip_physical{217}=0x33 + + +port_fec_20=9 +port_fec_13=9 +port_fec_28=9 +port_fec_32=9 +port_fec_40=9 +port_fec_44=9 +port_fec_48=9 +port_fec_52=9 +port_fec_9=9 +port_fec_60=9 +port_fec_5=9 +port_fec_24=9 +port_fec_68=9 +port_fec_64=9 +port_fec_72=9 +port_fec_1=9 + +port_fec_84=9 +port_fec_80=9 +port_fec_148=9 +port_fec_152=9 +port_fec_140=9 +port_fec_88=9 +port_fec_92=9 +port_fec_144=9 +port_fec_100=9 +port_fec_104=9 +port_fec_108=9 +port_fec_112=9 +port_fec_120=9 +port_fec_124=9 +port_fec_128=9 +port_fec_132=9 + + +port_init_cl72_20=1 +port_init_cl72_13=1 +port_init_cl72_28=1 +port_init_cl72_32=1 +port_init_cl72_40=1 +port_init_cl72_44=1 +port_init_cl72_48=1 +port_init_cl72_52=1 +port_init_cl72_9=1 +port_init_cl72_60=1 +port_init_cl72_5=1 +port_init_cl72_24=1 +port_init_cl72_68=1 +port_init_cl72_64=1 +port_init_cl72_72=1 +port_init_cl72_1=1 + +port_init_cl72_84=1 +port_init_cl72_80=1 +port_init_cl72_148=1 +port_init_cl72_152=1 +port_init_cl72_140=1 +port_init_cl72_88=1 +port_init_cl72_92=1 +port_init_cl72_144=1 +port_init_cl72_100=1 +port_init_cl72_104=1 +port_init_cl72_108=1 +port_init_cl72_112=1 +port_init_cl72_120=1 +port_init_cl72_124=1 +port_init_cl72_128=1 +port_init_cl72_132=1 + + diff --git a/device/quanta/x86_64-quanta_ix9_bwde-r0/default_sku b/device/quanta/x86_64-quanta_ix9_bwde-r0/default_sku new file mode 100644 index 000000000000..0ca35bb0074e --- /dev/null +++ b/device/quanta/x86_64-quanta_ix9_bwde-r0/default_sku @@ -0,0 +1 @@ +Quanta-IX9-32X t1 diff --git a/device/quanta/x86_64-quanta_ix9_bwde-r0/installer.conf b/device/quanta/x86_64-quanta_ix9_bwde-r0/installer.conf new file mode 100644 index 000000000000..925a32fc0c3a --- /dev/null +++ b/device/quanta/x86_64-quanta_ix9_bwde-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 diff --git a/device/quanta/x86_64-quanta_ix9_bwde-r0/led_proc_init.soc b/device/quanta/x86_64-quanta_ix9_bwde-r0/led_proc_init.soc new file mode 100644 index 000000000000..adff95218e4f --- /dev/null +++ b/device/quanta/x86_64-quanta_ix9_bwde-r0/led_proc_init.soc @@ -0,0 +1,2 @@ +sleep 10 +led auto on diff --git a/device/quanta/x86_64-quanta_ix9_bwde-r0/plugins/eeprom.py b/device/quanta/x86_64-quanta_ix9_bwde-r0/plugins/eeprom.py new file mode 100644 index 000000000000..2a35f3a22a17 --- /dev/null +++ b/device/quanta/x86_64-quanta_ix9_bwde-r0/plugins/eeprom.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +try: + import exceptions + import binascii + import time + import optparse + import warnings + import os + import sys + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + import subprocess +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/bus/i2c/devices/18-0054/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/quanta/x86_64-quanta_ix9_bwde-r0/plugins/psuutil.py b/device/quanta/x86_64-quanta_ix9_bwde-r0/plugins/psuutil.py new file mode 100644 index 000000000000..885842bbda5a --- /dev/null +++ b/device/quanta/x86_64-quanta_ix9_bwde-r0/plugins/psuutil.py @@ -0,0 +1,49 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + MAX_PSUS = 2 + + return MAX_PSUS + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is\ + faulty + """ + status = 1 + + return status + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 1 + + return status diff --git a/device/quanta/x86_64-quanta_ix9_bwde-r0/plugins/sfputil.py b/device/quanta/x86_64-quanta_ix9_bwde-r0/plugins/sfputil.py new file mode 100644 index 000000000000..6dc23d8195f4 --- /dev/null +++ b/device/quanta/x86_64-quanta_ix9_bwde-r0/plugins/sfputil.py @@ -0,0 +1,176 @@ +#!/usr/bin/env python + +try: + import time + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class SfpUtil(SfpUtilBase): + """Platform specific SfpUtill class""" + + _port_start = 0 + _port_end = 31 + ports_in_block = 32 + + _port_to_eeprom_mapping = {} + port_to_i2c_mapping = { + 1 : 32, + 2 : 33, + 3 : 34, + 4 : 35, + 5 : 36, + 6 : 37, + 7 : 38, + 8 : 39, + 9 : 40, + 10 : 41, + 11 : 42, + 12 : 43, + 13 : 44, + 14 : 45, + 15 : 46, + 16 : 47, + 17 : 48, + 18 : 49, + 19 : 50, + 20 : 51, + 21 : 52, + 22 : 53, + 23 : 54, + 24 : 55, + 25 : 56, + 26 : 57, + 27 : 58, + 28 : 59, + 29 : 60, + 30 : 61, + 31 : 62, + 32 : 63, + } + + _qsfp_ports = range(0, ports_in_block + 1) + + def __init__(self): + eeprom_path = '/sys/bus/i2c/devices/{0}-0050/eeprom' + for x in range(0, self._port_end + 1): + port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x+1]) + self._port_to_eeprom_mapping[x] = port_eeprom_path + SfpUtilBase.__init__(self) + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open("/sys/class/cpld-qsfpdd/port-"+str(port_num+1)+"/reset", "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = 0 + reg_file.write(hex(reg_value)) + reg_file.close() + + # Sleep 2 second to allow it to settle + time.sleep(2) + + # Flip the value back write back to the register to take port out of reset + try: + reg_file = open("/sys/class/cpld-qsfpdd/port-"+str(port_num+1)+"/reset", "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = 1 + reg_file.write(hex(reg_value)) + reg_file.close() + + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open("/sys/class/cpld-qsfpdd/port-"+str(port_num+1)+"/lpmode", "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = int(reg_file.readline().rstrip()) + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + reg_value = 1 + else: + reg_value = 0 + + reg_file.write(hex(reg_value)) + reg_file.close() + + return True + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open("/sys/class/cpld-qsfpdd/port-"+str(port_num+1)+"/lpmode") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = int(reg_file.readline().rstrip()) + + if reg_value == 0: + return False + + return True + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + try: + reg_file = open("/sys/class/cpld-qsfpdd/port-"+str(port_num+1)+"/module_present") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = reg_file.readline().rstrip() + if reg_value == '1': + return True + + return False + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return range(0, self.ports_in_block + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + 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/virtual/x86_64-kvm_x86_64-r0/plugins/eeprom.py b/device/virtual/x86_64-kvm_x86_64-r0/plugins/eeprom.py new file mode 100644 index 000000000000..5cc8cb68018f --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/plugins/eeprom.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python + +############################################################################# +# SONiC Virtual switch platform +# +############################################################################# + +class board(): + + def __init__(self, name, path, cpld_root, ro): + return + + def check_status(self): + return "ok" + + def is_checksum_valid(self, e): + return (True, 0) + + def read_eeprom(self): + return \ +""" +TLV Name Code Len Value +-------------------- ---- --- ----- +Product Name 0x21 5 SONiC +Part Number 0x22 6 000000 +Serial Number 0x23 20 0000000000000000000 +Base MAC Address 0x24 6 00:00:00:00:00:01 +Manufacture Date 0x25 19 10/19/2019 00:00:03 +Device Version 0x26 1 1 +Label Revision 0x27 3 A01 +Platform Name 0x28 20 x86_64-kvm_x86_64-r0 +ONIE Version 0x29 19 master-201811170418 +MAC Addresses 0x2A 2 16 +Vendor Name 0x2D 5 SONiC +""" + + def decode_eeprom(self, e): + print e + + def serial_number_str(self, e): + """Return service tag instead of serial number""" + return "000000" diff --git a/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-sai.conf b/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-sai.conf index 65a02a621f03..ae01f3ebe96a 100644 --- a/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-sai.conf +++ b/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-sai.conf @@ -25,7 +25,7 @@ "table-config": "share/tofinopd/switch/context.json", "tofino-bin": "share/tofinopd/switch/tofino.bin", "switchapi": "lib/libswitchapi.so", - "switchsai": "lib/libswitchsai.so", + "sai": "lib/libsai.so", "agent0": "lib/platform/x86_64-wnc_osw1800-r0/libpltfm_mgr.so", "switchapi_port_add": false } diff --git a/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-tna-sai.conf b/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-tna-sai.conf index 4bff0a177b60..7cb3ddc48fc9 100644 --- a/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-tna-sai.conf +++ b/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-tna-sai.conf @@ -23,13 +23,13 @@ "p4_pipelines": [ { "p4_pipeline_name": "pipe", - "config": "share/tofinopd/switch/pipe/tofino.bin", - "context": "share/tofinopd/switch/pipe/context.json" + "config": "share/switch/pipe/tofino.bin", + "context": "share/switch/pipe/context.json" } ], "program-name": "switch", - "switchsai": "lib/libswitchsai.so", - "bfrt-config": "share/tofinopd/switch/bf-rt.json", + "sai": "lib/libsai.so", + "bfrt-config": "share/switch/bf-rt.json", "model_json_path" : "share/switch/aug_model.json", "switchapi_port_add": false, "non_default_port_ppgs": 5 diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index ed59c3298715..95272e2322ce 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -83,4 +83,6 @@ 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-stretch/etc/supervisor/supervisord.conf b/dockers/docker-base-stretch/etc/supervisor/supervisord.conf index 351cc06fc048..5d1010e8fa4e 100644 --- a/dockers/docker-base-stretch/etc/supervisor/supervisord.conf +++ b/dockers/docker-base-stretch/etc/supervisor/supervisord.conf @@ -1,15 +1,15 @@ ; supervisor config file [unix_http_server] -file=/var/run/supervisor.sock ; (the path to the socket file) -chmod=0700 ; sockef file mode (default 0700) +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) -pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) -childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP) +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 @@ -19,7 +19,7 @@ user=root supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] -serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket +serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket username=dummy password=dummy diff --git a/dockers/docker-base/Dockerfile.j2 b/dockers/docker-base/Dockerfile.j2 index 74c9d6fd8ce3..cb2ff80186a3 100644 --- a/dockers/docker-base/Dockerfile.j2 +++ b/dockers/docker-base/Dockerfile.j2 @@ -32,6 +32,7 @@ COPY ["dpkg_01_drop", "/etc/dpkg/dpkg.cfg.d/01_drop"] COPY ["sources.list.armhf", "/etc/apt/sources.list"] {% elif CONFIGURED_ARCH == "arm64" %} COPY ["sources.list.arm64", "/etc/apt/sources.list"] +COPY ["aptconf_archive_expired_release", "/etc/apt/apt.conf.d"] {% else %} COPY ["sources.list", "/etc/apt/sources.list"] {% endif %} diff --git a/dockers/docker-base/aptconf_archive_expired_release b/dockers/docker-base/aptconf_archive_expired_release new file mode 100644 index 000000000000..67bc409b2174 --- /dev/null +++ b/dockers/docker-base/aptconf_archive_expired_release @@ -0,0 +1,3 @@ +# Instruct apt-get to override expired releases repo list for jessie archives + +Acquire::Check-Valid-Until "0"; diff --git a/dockers/docker-base/etc/supervisor/supervisord.conf b/dockers/docker-base/etc/supervisor/supervisord.conf index 351cc06fc048..5d1010e8fa4e 100644 --- a/dockers/docker-base/etc/supervisor/supervisord.conf +++ b/dockers/docker-base/etc/supervisor/supervisord.conf @@ -1,15 +1,15 @@ ; supervisor config file [unix_http_server] -file=/var/run/supervisor.sock ; (the path to the socket file) -chmod=0700 ; sockef file mode (default 0700) +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) -pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) -childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP) +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 @@ -19,7 +19,7 @@ user=root supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] -serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket +serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket username=dummy password=dummy diff --git a/dockers/docker-database/Dockerfile.j2 b/dockers/docker-database/Dockerfile.j2 index 9ec3926de6fb..acb5e013fb84 100644 --- a/dockers/docker-database/Dockerfile.j2 +++ b/dockers/docker-database/Dockerfile.j2 @@ -32,6 +32,9 @@ RUN apt-get clean -y && \ s/^client-output-buffer-limit pubsub [0-9]+mb [0-9]+mb [0-9]+/client-output-buffer-limit pubsub 0 0 0/ \ ' /etc/redis/redis.conf -COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +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/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/docker-database-init.sh"] diff --git a/dockers/docker-database/database_config.json b/dockers/docker-database/database_config.json new file mode 100644 index 000000000000..b86ae11bba98 --- /dev/null +++ b/dockers/docker-database/database_config.json @@ -0,0 +1,57 @@ +{ + "INSTANCES": { + "redis":{ + "hostname" : "127.0.0.1", + "port" : 6379, + "unix_socket_path" : "/var/run/redis/redis.sock" + } + }, + "DATABASES" : { + "APPL_DB" : { + "id" : 0, + "separator": ":", + "instance" : "redis" + }, + "ASIC_DB" : { + "id" : 1, + "separator": ":", + "instance" : "redis" + }, + "COUNTERS_DB" : { + "id" : 2, + "separator": ":", + "instance" : "redis" + }, + "LOGLEVEL_DB" : { + "id" : 3, + "separator": ":", + "instance" : "redis" + }, + "CONFIG_DB" : { + "id" : 4, + "separator": "|", + "instance" : "redis" + }, + "PFC_WD_DB" : { + "id" : 5, + "separator": ":", + "instance" : "redis" + }, + "FLEX_COUNTER_DB" : { + "id" : 5, + "separator": ":", + "instance" : "redis" + }, + "STATE_DB" : { + "id" : 6, + "separator": "|", + "instance" : "redis" + }, + "SNMP_OVERLAY_DB" : { + "id" : 7, + "separator": "|", + "instance" : "redis" + } + }, + "VERSION" : "1.0" +} diff --git a/dockers/docker-database/docker-database-init.sh b/dockers/docker-database/docker-database-init.sh new file mode 100755 index 000000000000..ebdcc6abb694 --- /dev/null +++ b/dockers/docker-database/docker-database-init.sh @@ -0,0 +1,14 @@ +#!/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 +else + cp /etc/default/sonic-db/database_config.json /var/run/redis/sonic-db +fi + +mkdir -p /etc/supervisor/conf.d/ +# generate all redis server supervisord configuration file +sonic-cfggen -j /var/run/redis/sonic-db/database_config.json -t /usr/share/sonic/templates/supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf + +exec /usr/bin/supervisord diff --git a/dockers/docker-database/ping_pong_db_insts b/dockers/docker-database/ping_pong_db_insts new file mode 100755 index 000000000000..484d4da0cfb0 --- /dev/null +++ b/dockers/docker-database/ping_pong_db_insts @@ -0,0 +1,40 @@ +#!/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 b/dockers/docker-database/supervisord.conf deleted file mode 100644 index 798fedd0c895..000000000000 --- a/dockers/docker-database/supervisord.conf +++ /dev/null @@ -1,21 +0,0 @@ -[supervisord] -logfile_maxbytes=1MB -logfile_backups=2 -nodaemon=true - -[program:rsyslogd] -command=/bin/bash -c "rm -f /var/run/rsyslogd.pid && /usr/sbin/rsyslogd -n" -priority=1 -autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - -[program:redis-server] -command=/bin/bash -c "{ [[ -s /var/lib/redis/dump.rdb ]] || rm -f /var/lib/redis/dump.rdb; } && exec /usr/bin/redis-server /etc/redis/redis.conf" -priority=2 -autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - diff --git a/dockers/docker-database/supervisord.conf.j2 b/dockers/docker-database/supervisord.conf.j2 new file mode 100644 index 000000000000..110619f762be --- /dev/null +++ b/dockers/docker-database/supervisord.conf.j2 @@ -0,0 +1,24 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[program:rsyslogd] +command=/bin/bash -c "rm -f /var/run/rsyslogd.pid && /usr/sbin/rsyslogd -n" +priority=1 +autostart=true +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +{% if INSTANCES %} +{% for redis_inst, redis_items in INSTANCES.iteritems() %} +[program: {{ redis_inst }}] +command=/bin/bash -c "{ [[ -s /var/lib/{{ redis_inst }}/dump.rdb ]] || rm -f /var/lib/{{ redis_inst }}/dump.rdb; } && mkdir -p /var/lib/{{ redis_inst }} && exec /usr/bin/redis-server /etc/redis/redis.conf --port {{ redis_items['port'] }} --unixsocket {{ redis_items['unix_socket_path'] }} --pidfile /var/run/redis/{{ redis_inst }}.pid --dir /var/lib/{{ redis_inst }}" +priority=2 +autostart=true +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +{% endfor %} +{% endif %} diff --git a/dockers/docker-dhcp-relay/Dockerfile.j2 b/dockers/docker-dhcp-relay/Dockerfile.j2 index e365adab1716..d3c09f9ba260 100644 --- a/dockers/docker-dhcp-relay/Dockerfile.j2 +++ b/dockers/docker-dhcp-relay/Dockerfile.j2 @@ -26,5 +26,7 @@ RUN apt-get clean -y && \ COPY ["docker_init.sh", "start.sh", "/usr/bin/"] COPY ["docker-dhcp-relay.supervisord.conf.j2", "wait_for_intf.sh.j2", "/usr/share/sonic/templates/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/bin/docker_init.sh"] diff --git a/dockers/docker-dhcp-relay/critical_processes b/dockers/docker-dhcp-relay/critical_processes new file mode 100644 index 000000000000..ddb183963a67 --- /dev/null +++ b/dockers/docker-dhcp-relay/critical_processes @@ -0,0 +1 @@ +isc-dhcp-relay diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 index bbc24ecc091c..e738e8699e6c 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -43,8 +49,16 @@ isc-dhcp-relay-{{ vlan_name }} {# Create a program entry for each DHCP relay agent instance #} +{% set relay_for_ipv4 = { 'flag': False } %} {% for vlan_name in VLAN %} {% if VLAN[vlan_name]['dhcp_servers'] %} +{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %} +{% if dhcp_server | ipv4 %} +{% set _dummy = relay_for_ipv4.update({'flag': True}) %} +{% endif %} +{% endfor %} +{% if relay_for_ipv4.flag %} +{% set _dummy = relay_for_ipv4.update({'flag': False}) %} [program:isc-dhcp-relay-{{ vlan_name }}] {# We treat this VLAN as a downstream interface (-id), as we only want to listen for requests #} command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id {{ vlan_name }} @@ -58,7 +72,9 @@ command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /t {% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %} {% if prefix | ipv4 %} -iu {{ name }}{% endif -%} {% endfor %} -{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %} {{ dhcp_server }}{% endfor %} +{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %} +{%- if dhcp_server | ipv4 %} {{ dhcp_server }}{% endif -%} +{% endfor %} priority=3 autostart=false @@ -66,6 +82,7 @@ autorestart=false stdout_logfile=syslog stderr_logfile=syslog +{% endif %} {% endif %} {% endfor %} {% endif %} diff --git a/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 b/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 index fd7c3ff95bc0..0488799a4c81 100644 --- a/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 +++ b/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 @@ -2,21 +2,17 @@ STATE_DB_IDX="6" -PORT_TABLE_PREFIX="PORT_TABLE" -VLAN_TABLE_PREFIX="VLAN_TABLE" -LAG_TABLE_PREFIX="LAG_TABLE" - function wait_until_iface_ready { - TABLE_PREFIX=$1 - IFACE=$2 + IFACE_NAME=$1 + IFACE_CIDR=$2 - echo "Waiting until interface $IFACE is ready..." + echo "Waiting until interface ${IFACE_NAME} is ready..." # Wait for the interface to come up # (i.e., interface is present in STATE_DB and state is "ok") while true; do - RESULT=$(redis-cli -n ${STATE_DB_IDX} HGET "${TABLE_PREFIX}|${IFACE}" "state" 2> /dev/null) + RESULT=$(redis-cli -n ${STATE_DB_IDX} HGET "INTERFACE_TABLE|${IFACE_NAME}|${IFACE_CIDR}" "state" 2> /dev/null) if [ x"$RESULT" == x"ok" ]; then break fi @@ -24,24 +20,23 @@ function wait_until_iface_ready sleep 1 done - echo "Interface ${IFACE} is ready!" + echo "Interface ${IFACE_NAME} is ready!" } -# Wait for all interfaces to be up and ready -{% for name in PORT %} -{% if name in INTERFACE %} -wait_until_iface_ready ${PORT_TABLE_PREFIX} {{ name }} +# Wait for all interfaces with IPv4 addresses to be up and ready +{% for (name, prefix) in INTERFACE|pfx_filter %} +{% if prefix | ipv4 %} +wait_until_iface_ready {{ name }} {{ prefix }} {% endif %} {% endfor %} -{% for name in VLAN %} -{% if name in VLAN_INTERFACE %} -wait_until_iface_ready ${VLAN_TABLE_PREFIX} {{ name }} +{% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} +{% if prefix | ipv4 %} +wait_until_iface_ready {{ name }} {{ prefix }} {% endif %} {% endfor %} -{% for name in PORTCHANNEL %} -{% if name in PORTCHANNEL_INTERFACE %} -wait_until_iface_ready ${LAG_TABLE_PREFIX} {{ name }} +{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %} +{% if prefix | ipv4 %} +wait_until_iface_ready {{ name }} {{ prefix }} {% endif %} {% endfor %} - diff --git a/dockers/docker-fpm-frr/.dockerignore b/dockers/docker-fpm-frr/.dockerignore new file mode 100644 index 000000000000..bd5eecc5d798 --- /dev/null +++ b/dockers/docker-fpm-frr/.dockerignore @@ -0,0 +1 @@ +Dockerfile.j2 diff --git a/dockers/docker-fpm-frr/TSA b/dockers/docker-fpm-frr/TSA index abd629157901..1d74757b2d5f 100755 --- a/dockers/docker-fpm-frr/TSA +++ b/dockers/docker-fpm-frr/TSA @@ -3,20 +3,20 @@ c=0 config=$(vtysh -c "show run") echo "$config" | grep -q "route-map TO_BGP_PEER_V4 permit 2" -c=$(($c+$?)) +c=$((c+$?)) echo "$config" | grep -q "route-map TO_BGP_PEER_V4 deny 3" -c=$(($c+$?)) +c=$((c+$?)) echo "$config" | grep -q "route-map TO_BGP_PEER_V6 permit 2" -c=$(($c+$?)) +c=$((c+$?)) echo "$config" | grep -q "route-map TO_BGP_PEER_V6 deny 3" -c=$(($c+$?)) +c=$((c+$?)) if [[ $c -eq 4 ]]; then - vtysh -c "configure terminal" -c "route-map TO_BGP_PEER_V4 permit 2" -c "match ip address prefix-list PL_LoopbackV4" - vtysh -c "configure terminal" -c "route-map TO_BGP_PEER_V4 deny 3" - vtysh -c "configure terminal" -c "route-map TO_BGP_PEER_V6 permit 2" -c "match ipv6 address prefix-list PL_LoopbackV6" - vtysh -c "configure terminal" -c "route-map TO_BGP_PEER_V6 deny 3" + 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" 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 beb246bfc7f1..83ead86952c3 100755 --- a/dockers/docker-fpm-frr/TSB +++ b/dockers/docker-fpm-frr/TSB @@ -3,21 +3,20 @@ c=0 config=$(vtysh -c "show run") echo "$config" | grep -q "route-map TO_BGP_PEER_V4 permit 2" -c=$(($c+$?)) +c=$((c+$?)) echo "$config" | grep -q "route-map TO_BGP_PEER_V4 deny 3" -c=$(($c+$?)) +c=$((c+$?)) echo "$config" | grep -q "route-map TO_BGP_PEER_V6 permit 2" -c=$(($c+$?)) +c=$((c+$?)) echo "$config" | grep -q "route-map TO_BGP_PEER_V6 deny 3" -c=$(($c+$?)) +c=$((c+$?)) if [[ $c -eq 0 ]]; then - vtysh -c "configure terminal" -c "no route-map TO_BGP_PEER_V4 deny 3" - vtysh -c "configure terminal" -c "no route-map TO_BGP_PEER_V4 permit 2" - vtysh -c "configure terminal" -c "no route-map TO_BGP_PEER_V6 deny 3" - vtysh -c "configure terminal" -c "no route-map TO_BGP_PEER_V6 permit 2" - + 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" 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 7d0fb1004a7d..c79f4bb2a41b 100755 --- a/dockers/docker-fpm-frr/TSC +++ b/dockers/docker-fpm-frr/TSC @@ -4,13 +4,13 @@ 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+$?)) +c=$((c+$?)) echo "$config" | grep -q "route-map TO_BGP_PEER_V4 deny 3" -c=$(($c+$?)) +c=$((c+$?)) echo "$config" | grep -q "route-map TO_BGP_PEER_V6 permit 2" -c=$(($c+$?)) +c=$((c+$?)) echo "$config" | grep -q "route-map TO_BGP_PEER_V6 deny 3" -c=$(($c+$?)) +c=$((c+$?)) if [[ $c -eq 4 ]]; then diff --git a/dockers/docker-fpm-frr/bgpcfgd b/dockers/docker-fpm-frr/bgpcfgd index 012a766c20b9..120e07fcdbe2 100755 --- a/dockers/docker-fpm-frr/bgpcfgd +++ b/dockers/docker-fpm-frr/bgpcfgd @@ -1,65 +1,423 @@ #!/usr/bin/env python import sys -import redis import subprocess +import datetime +import time import syslog -from swsssdk import ConfigDBConnector +import signal +import traceback +import os +import tempfile +import json +from collections import defaultdict +from pprint import pprint +from pprint import pformat -class BGPConfigDaemon: +import jinja2 +import netaddr +from swsscommon import swsscommon + +g_run = True +g_debug = False + + +def run_command(command, shell=False): + str_cmd = " ".join(command) + if g_debug: + syslog.syslog(syslog.LOG_DEBUG, "execute command {}.".format(str_cmd)) + p = subprocess.Popen(command, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + if p.returncode != 0: + syslog.syslog(syslog.LOG_ERR, 'command execution returned {}. Command: "{}", stdout: "{}", stderr: "{}"'.format(p.returncode, str_cmd, stdout, stderr)) + + return p.returncode, stdout, stderr + + +class TemplateFabric(object): def __init__(self): - self.config_db = ConfigDBConnector() - self.config_db.connect() - self.bgp_asn = self.config_db.get_entry('DEVICE_METADATA', 'localhost')['bgp_asn'] - self.bgp_neighbor = self.config_db.get_table('BGP_NEIGHBOR') - - def __run_command(self, command): -# print command - p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) - stdout = p.communicate()[0] - p.wait() - if p.returncode != 0: - syslog.syslog(syslog.LOG_ERR, '[bgp cfgd] command execution returned {}. Command: "{}", stdout: "{}"'.format(p.returncode, command, stdout)) - - def metadata_handler(self, key, data): - if key == 'localhost' and data.has_key('bgp_asn'): - if data['bgp_asn'] != self.bgp_asn: - syslog.syslog(syslog.LOG_INFO, '[bgp cfgd] ASN changed to {} from {}, restart BGP...'.format(data['bgp_asn'], self.bgp_asn)) - self.__run_command("supervisorctl restart start.sh") - self.__run_command("service quagga restart") - self.bgp_asn = data['bgp_asn'] - - def bgp_handler(self, key, data): - syslog.syslog(syslog.LOG_INFO, '[bgp cfgd] value for {} changed to {}'.format(key, data)) - if not data: - # Neighbor is deleted - command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'no neighbor {}'".format(self.bgp_asn, key) - self.__run_command(command) - self.bgp_neighbor.pop(key) + j2_template_paths = ['/usr/share/sonic/templates'] + j2_loader = jinja2.FileSystemLoader(j2_template_paths) + j2_env = jinja2.Environment(loader=j2_loader, trim_blocks=True) + j2_env.filters['ipv4'] = self.is_ipv4 + j2_env.filters['ipv6'] = self.is_ipv6 + self.env = j2_env + + def from_file(self, filename): + return self.env.get_template(filename) + + def from_string(self, tmpl): + return self.env.from_string(tmpl) + + @staticmethod + def is_ipv4(value): + if not value: + return False + if isinstance(value, netaddr.IPNetwork): + addr = value else: - command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'neighbor {} remote-as {}'".format(self.bgp_asn, key, data['asn']) - self.__run_command(command) - if data.has_key('name'): - command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'neighbor {} description {}'".format(self.bgp_asn, key, data['name']) - self.__run_command(command) - if data.has_key('admin_status'): - command_mod = 'no ' if data['admin_status'] == 'up' else '' - command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c '{}neighbor {} shutdown'".format(self.bgp_asn, command_mod, key) - self.__run_command(command) - self.bgp_neighbor[key] = data - - def start(self): - self.config_db.subscribe('BGP_NEIGHBOR', - lambda table, key, data: self.bgp_handler(key, data)) - self.config_db.subscribe('DEVICE_METADATA', - lambda table, key, data: self.metadata_handler(key, data)) - self.config_db.listen() + try: + addr = netaddr.IPNetwork(str(value)) + except: + return False + return addr.version == 4 + + @staticmethod + def is_ipv6(value): + if not value: + return False + if isinstance(value, netaddr.IPNetwork): + addr = value + else: + try: + addr = netaddr.IPNetwork(str(value)) + except: + return False + return addr.version == 6 + + +class Daemon(object): + SELECT_TIMEOUT = 1000 + + def __init__(self): + self.db_connectors = {} + self.selector = swsscommon.Select() + self.callbacks = defaultdict(lambda : defaultdict(list)) # db -> table -> [] + self.subscribers = set() + + def add_manager(self, db, table_name, callback): + if db not in self.db_connectors: + self.db_connectors[db] = swsscommon.DBConnector(db, swsscommon.DBConnector.DEFAULT_UNIXSOCKET, 0) + + if table_name not in self.callbacks[db]: + conn = self.db_connectors[db] + subscriber = swsscommon.SubscriberStateTable(conn, table_name) + self.subscribers.add(subscriber) + self.selector.addSelectable(subscriber) + self.callbacks[db][table_name].append(callback) + + def run(self): + while g_run: + state, _ = self.selector.select(Daemon.SELECT_TIMEOUT) + if state == self.selector.TIMEOUT: + continue + elif state == self.selector.ERROR: + raise Exception("Received error from select") + + for subscriber in self.subscribers: + key, op, fvs = subscriber.pop() + if not key: + continue + if g_debug: + syslog.syslog(syslog.LOG_DEBUG, "Received message : {}".format((key, op, fvs))) + for callback in self.callbacks[subscriber.getDbConnector().getDbId()][subscriber.getTableName()]: + callback(key, op, dict(fvs)) + + +class Directory(object): + def __init__(self): + self.data = defaultdict(dict) + self.notify = defaultdict(lambda: defaultdict(list)) + + def path_exist(self, slot, path): + if slot not in self.data: + return False + elif path == '': + return True + d = self.data[slot] + for p in path.split("/"): + if p not in d: + return False + d = d[p] + return True + + def get_path(self, slot, path): + if slot not in self.data: + return None + elif path == '': + return self.data[slot] + d = self.data[slot] + for p in path.split("/"): + if p not in d: + return None + d = d[p] + return d + + def put(self, slot, key, value): + self.data[slot][key] = value + if slot in self.notify: + for path in self.notify[slot].keys(): + if self.path_exist(slot, path): + for handler in self.notify[slot][path]: + handler() + + def get(self, slot, key): + return self.data[slot][key] + + def remove(self, slot, key): + if slot in self.data: + if key in self.data[slot]: + del self.data[slot][key] + else: + syslog.syslog(syslog.LOG_ERR, "Directory: Can't remove key '%s' from slot '%s'. The key doesn't exist" % (key, slot)) + else: + syslog.syslog(syslog.LOG_ERR, "Directory: Can't remove key '%s' from slot '%s'. The slot doesn't exist" % (key, slot)) + + def remove_slot(self, slot, key): + if slot in self.data: + del self.data[slot] + else: + syslog.syslog(syslog.LOG_ERR, "Directory: Can't remove slot '%s'. The slot doesn't exist" % slot) + + def get_slot(self, slot): + return self.data[slot] + + def available_slot(self, slot): + return slot in self.data + + def available_deps(self, deps): + res = True + for slot, path in deps: + res = res and self.path_exist(slot, path) + return res + + def subscribe(self, deps, handler): + for slot, path in deps: + self.notify[slot][path].append(handler) + + +class Manager(object): + def __init__(self, daemon, directory, deps, database, table_name): + self.directory = directory + self.deps = deps + self.set_queue = [] + daemon.add_manager(database, table_name, self.handler) + directory.subscribe(deps, self.on_deps_change) + + def handler(self, key, op, data): + if op == swsscommon.SET_COMMAND: + if self.directory.available_deps(self.deps): + res = self.set_handler(key, data) + if not res: + self.set_queue.append((key, data)) + else: + self.set_queue.append((key, data)) + elif op == swsscommon.DEL_COMMAND: + self.del_handler(key) + else: + syslog.syslog(syslog.LOG_ERR, 'Invalid operation "%s" for key "%s"' % (op, key)) + + def on_deps_change(self): + new_queue = [] + for key, data in self.set_queue: + res = self.set_handler(key, data) + if not res: + new_queue.append((key, data)) + self.set_queue = new_queue + + def set_handler(self, key, data): + syslog.syslog(syslog.LOG_ERR, "%s wasn't implemented for %s" % (self.__name__, self.__class__)) + + def del_handler(self, key): + syslog.syslog(syslog.LOG_ERR, "%s wasn't implemented for %s" % (self.__name__, self.__class__)) + + +class BGPDeviceMetaMgr(Manager): + def __init__(self, daemon, directory): + super(BGPDeviceMetaMgr, self).__init__( + daemon, + directory, + [], + swsscommon.CONFIG_DB, + swsscommon.CFG_DEVICE_METADATA_TABLE_NAME + ) + + def set_handler(self, key, data): + if key != "localhost" or "bgp_asn" not in data: + return + if self.directory.path_exist("meta", "localhost/bgp_asn"): + bgp_asn = self.directory.get_path("meta", "localhost/bgp_asn") + if bgp_asn == data["bgp_asn"]: + return + self.directory.put("meta", key, data) + + return True + + def del_handler(self, key): + self.directory.remove("meta", key) + + +class BGPNeighborMetaMgr(Manager): + def __init__(self, daemon, directory): + super(BGPNeighborMetaMgr, self).__init__( + daemon, + directory, + [], + swsscommon.CONFIG_DB, + swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME + ) + + def set_handler(self, key, data): + self.directory.put("neigmeta", key, data) + + return True + + def del_handler(self, key): + self.directory.remove("neigmeta", key) + + +class BGPPeerMgr(Manager): + def __init__(self, daemon, directory): + super(BGPPeerMgr, self).__init__( + daemon, + directory, + [ + ("meta", "localhost/bgp_asn"), + ("neigmeta", ""), + ], + swsscommon.CONFIG_DB, + swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME + ) + self.peers = self.load_peers() + fabric = TemplateFabric() + self.templates = { + "add": fabric.from_file('bgpd.peer.conf.j2'), + "delete": fabric.from_string('no neighbor {{ neighbor_addr }}'), + "shutdown": fabric.from_string('neighbor {{ neighbor_addr }} shutdown'), + "no shutdown": fabric.from_string('no neighbor {{ neighbor_addr }} shutdown'), + } + + def set_handler(self, key, data): + if key not in self.peers: + cmd = None + neigmeta = self.directory.get_slot("neigmeta") + if 'name' in data and data["name"] not in neigmeta: + return False + try: + cmd = self.templates["add"].render( + DEVICE_METADATA=self.directory.get_slot("meta"), + DEVICE_NEIGHBOR_METADATA=neigmeta, + neighbor_addr=key, + 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) + 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=key)) + 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=key)) + if rc: + syslog.syslog(syslog.LOG_INFO, 'Peer {} admin state is set to "down"'.format(key)) + else: + syslog.syslog(syslog.LOG_ERR, "Peer {} admin state wasn't set to 'down'.".format(key)) + else: + syslog.syslog(syslog.LOG_ERR, "Peer {}: Can't update the peer. has wrong attribute value attr['admin_status'] = '{}'".format(key, data['admin_status'])) + else: + syslog.syslog(syslog.LOG_ERR, "Peer {}: Can't update the peer. No 'admin_status' attribute in the request".format(key)) + return True + + def del_handler(self, key): + 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=key) + rc = self.apply_op(cmd) + if rc: + syslog.syslog(syslog.LOG_INFO, 'Peer {} has been removed'.format(key)) + self.peers.remove(key) + else: + syslog.syslog(syslog.LOG_ERR, "Peer {} hasn't been removed".format(key)) + + def apply_op(self, cmd): + 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: + fp.write('router bgp %s\n' % bgp_asn) + fp.write("%s\n" % cmd) + + command = ["vtysh", "-f", tmp_filename] + rc, _, _ = run_command(command) + os.remove(tmp_filename) + return rc == 0 + + @staticmethod + def load_peers(): + peers = set() + command = ["vtysh", "-c", "show bgp neighbors json"] + rc, out, err = run_command(command) + if rc == 0: + js_bgp = json.loads(out) + peers = set(js_bgp.keys()) + return peers + + +def wait_for_bgpd(): + # wait for 20 seconds + stop_time = datetime.datetime.now() + datetime.timedelta(seconds=20) + syslog.syslog(syslog.LOG_INFO, "Start waiting for bgpd: %s" % str(datetime.datetime.now())) + while datetime.datetime.now() < stop_time: + rc, out, err = run_command(["vtysh", "-c", "show daemons"]) + if rc == 0 and "bgpd" in out: + syslog.syslog(syslog.LOG_INFO, "bgpd connected to vtysh: %s" % str(datetime.datetime.now())) + return + time.sleep(0.1) # sleep 100 ms + raise RuntimeError("bgpd hasn't been started in 20 seconds") def main(): - daemon = BGPConfigDaemon() - daemon.start() + managers = [ + BGPDeviceMetaMgr, + BGPNeighborMetaMgr, + BGPPeerMgr, + ] + wait_for_bgpd() + daemon = Daemon() + directory = Directory() + manager_instanses = [ manager(daemon, directory) for manager in managers ] + daemon.run() + + +def signal_handler(signum, frame): + global g_run + g_run = False + -if __name__ == "__main__": - main() +if __name__ == '__main__': + rc = 0 + try: + syslog.openlog('bgpcfgd') + signal.signal(signal.SIGTERM, signal_handler) + signal.signal(signal.SIGINT, signal_handler) + main() + except KeyboardInterrupt: + syslog.syslog(syslog.LOG_NOTICE, "Keyboard interrupt") + except RuntimeError as e: + syslog.syslog(syslog.LOG_CRIT, "%s" % str(e)) + rc = -2 + except Exception as e: + syslog.syslog(syslog.LOG_CRIT, "Got an exception %s: Traceback: %s" % (str(e), traceback.format_exc())) + rc = -1 + finally: + syslog.closelog() + try: + sys.exit(rc) + except SystemExit: + os._exit(rc) diff --git a/dockers/docker-fpm-frr/bgpd.conf.default.j2 b/dockers/docker-fpm-frr/bgpd.conf.default.j2 index 371f1fe3dd36..e12782b035aa 100644 --- a/dockers/docker-fpm-frr/bgpd.conf.default.j2 +++ b/dockers/docker-fpm-frr/bgpd.conf.default.j2 @@ -1,3 +1,4 @@ +! {% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %} {% block bgp_init %} ! @@ -12,7 +13,7 @@ route-map TO_BGP_SPEAKER_V4 deny 10 {% 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 | ip }}/64 +ipv6 prefix-list PL_LoopbackV6 permit {{ prefix | replace('/128', '/64') | ip_network }}/64 {% endif %} {% endfor %} ! @@ -22,6 +23,19 @@ route-map TO_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V6 permit 100 ! +{% if BGP_MONITORS is defined and BGP_MONITORS|length > 0 %} +route-map FROM_BGPMON deny 10 +! +route-map TO_BGPMON permit 10 +! +{% endif %} +! +route-map ISOLATE permit 10 + set as-path prepend {{ DEVICE_METADATA['localhost']['bgp_asn'] }} +! +route-map set-next-hop-global-v6 permit 10 + set ipv6 next-hop prefer-global +! router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} bgp log-neighbor-changes bgp bestpath as-path multipath-relax @@ -59,63 +73,32 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endif %} {% endfor %} {% endblock vlan_advertisement %} -{% block bgp_sessions %} -{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %} -{% if bgp_session['asn'] | int != 0 %} - neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} - neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} -{# set the bgp neighbor timers if they have not default values #} -{% if (bgp_session['keepalive'] is defined and bgp_session['keepalive'] | int != 60) - or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} - neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] }} {{ bgp_session['holdtime'] }} -{% endif %} -{% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and DEVICE_METADATA['localhost'].has_key('default_bgp_status') and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} - neighbor {{ neighbor_addr }} shutdown -{% endif %} -{# Apply default route-map for v4 peers #} -{% if neighbor_addr | ipv4 %} - neighbor {{ neighbor_addr }} route-map TO_BGP_PEER_V4 out -{% endif %} -{% if neighbor_addr | ipv4 %} +{% block maximum_paths %} address-family ipv4 -{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} - neighbor {{ neighbor_addr }} allowas-in 1 -{% endif %} - neighbor {{ neighbor_addr }} activate - neighbor {{ neighbor_addr }} soft-reconfiguration inbound -{% 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 %} maximum-paths 64 exit-address-family -{% endif %} -{% if neighbor_addr | ipv6 %} address-family ipv6 -{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} - neighbor {{ neighbor_addr }} allowas-in 1 -{% endif %} - neighbor {{ neighbor_addr }} activate - neighbor {{ neighbor_addr }} soft-reconfiguration inbound -{% 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'] %} - neighbor {{ neighbor_addr }} route-map set-next-hop-global-v6 in -{% endif %} -{# Apply default route-map for v6 peers #} - neighbor {{ neighbor_addr }} route-map TO_BGP_PEER_V6 out 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 %} -{% endfor %} -{% endblock bgp_sessions %} + 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() %} @@ -124,7 +107,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% if bgp_peer['peer_asn'] is defined %} neighbor {{ bgp_peer['name'] }} remote-as {{ bgp_peer['peer_asn'] }} {% else %} - neighbor {{ bgp_peer['name'] }} remote-as {{ deployment_id_asn_map[DEVICE_METADATA['localhost']['deployment_id']] }} + 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 @@ -144,13 +127,34 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endfor %} address-family ipv4 neighbor {{ bgp_peer['name'] }} activate - maximum-paths 64 exit-address-family address-family ipv6 neighbor {{ bgp_peer['name'] }} activate - maximum-paths 64 exit-address-family {% endfor %} {% endif %} {% endblock bgp_peers_with_range %} +{% block bgp_monitors %} +{% if BGP_MONITORS is defined and BGP_MONITORS|length > 0 %} + neighbor BGPMON peer-group +{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} +{% if prefix | ipv4 and name == 'Loopback0' %} + neighbor BGPMON update-source {{ prefix | ip }} +{% endif %} +{% endfor %} + neighbor BGPMON route-map FROM_BGPMON in + neighbor BGPMON route-map TO_BGPMON out + neighbor BGPMON send-community + neighbor BGPMON maximum-prefix 1 +{% for neighbor_addr, bgp_session in BGP_MONITORS.items() %} + neighbor {{ neighbor_addr }} remote-as {{ DEVICE_METADATA['localhost']['bgp_asn'] }} + neighbor {{ neighbor_addr }} peer-group BGPMON + neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} + neighbor {{ neighbor_addr }} activate + address-family ipv6 + neighbor {{ neighbor_addr }} activate + exit-address-family +{% endfor %} +{% endif %} +{% endblock bgp_monitors %} ! diff --git a/dockers/docker-fpm-frr/bgpd.conf.j2 b/dockers/docker-fpm-frr/bgpd.conf.j2 index e9554806b64a..b4b2cd59c9b9 100644 --- a/dockers/docker-fpm-frr/bgpd.conf.j2 +++ b/dockers/docker-fpm-frr/bgpd.conf.j2 @@ -6,28 +6,13 @@ ! {% endblock banner %} ! -{% block system_init %} -hostname {{ DEVICE_METADATA['localhost']['hostname'] }} -password zebra -log syslog informational -log facility local4 +{% include "daemons.common.conf.j2" %} +! agentx -! enable password {# {{ en_passwd }} TODO: param needed #} -{% endblock system_init %} ! {% if DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" %} {% include "bgpd.conf.spine_chassis_frontend_router.j2" %} -{% else%} -{% include "bgpd.conf.default.j2" %} -{% endif %} -! -{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %} -maximum-paths 64 -! -route-map ISOLATE permit 10 -set as-path prepend {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endif %} ! -route-map set-next-hop-global-v6 permit 10 -set ipv6 next-hop prefer-global +{% include "bgpd.conf.default.j2" %} ! diff --git a/dockers/docker-fpm-frr/bgpd.conf.spine_chassis_frontend_router.j2 b/dockers/docker-fpm-frr/bgpd.conf.spine_chassis_frontend_router.j2 index 9bd5ef1947c3..afb621b0bf61 100644 --- a/dockers/docker-fpm-frr/bgpd.conf.spine_chassis_frontend_router.j2 +++ b/dockers/docker-fpm-frr/bgpd.conf.spine_chassis_frontend_router.j2 @@ -1,3 +1,4 @@ +! {# VNET BGP Instance #} ! Vnet BGP instance {% set interfaces_in_vnets = [] %} @@ -59,70 +60,4 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} vrf {{ vnet_name }} {% endfor %} {% endfor %} {% endblock vnet_bgp_instance %} - -{# default bgp #} -{% block default_bgp_instance %} -{% block bgp_init %} -! -! bgp multiple-instance -! -route-map FROM_BGP_SPEAKER_V4 permit 10 -! -route-map TO_BGP_SPEAKER_V4 deny 10 ! -router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} - bgp log-neighbor-changes - bgp bestpath as-path multipath-relax - no bgp default ipv4-unicast - bgp graceful-restart restart-time 240 - bgp graceful-restart -{% 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 %} -{% block bgp_sessions %} -{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %} -{% if not bgp_session.has_key("local_addr") or bgp_session["local_addr"] not in interfaces_in_vnets %} -{% if bgp_session['asn'] | int != 0 %} - neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} - neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} -{# set the bgp neighbor timers if they have not default values #} -{% if (bgp_session['keepalive'] is defined and bgp_session['keepalive'] | int != 60) - or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} - neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] }} {{ bgp_session['holdtime'] }} -{% endif %} -{% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and DEVICE_METADATA['localhost'].has_key('default_bgp_status') and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} - neighbor {{ neighbor_addr }} shutdown -{% endif %} -{% if bgp_session["asn"] != DEVICE_METADATA['localhost']['bgp_asn'] %} -{% if neighbor_addr | ipv4 %} - address-family ipv4 unicast - neighbor {{ neighbor_addr }} allowas-in 1 - neighbor {{ neighbor_addr }} activate - neighbor {{ neighbor_addr }} soft-reconfiguration inbound - maximum-paths 64 - exit-address-family -{% endif %} -{% else %} - address-family l2vpn evpn - neighbor {{ neighbor_addr }} activate - advertise-all-vni - exit-address-family -{% endif %} -{% endif %} -{% endif %} -{% endfor %} -{% endblock bgp_sessions %} -{% endblock default_bgp_instance %} diff --git a/dockers/docker-fpm-frr/bgpd.peer.conf.j2 b/dockers/docker-fpm-frr/bgpd.peer.conf.j2 new file mode 100644 index 000000000000..c3dc50449d35 --- /dev/null +++ b/dockers/docker-fpm-frr/bgpd.peer.conf.j2 @@ -0,0 +1,38 @@ +{% block bgp_peer %} + neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} + neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} +{# set the bgp neighbor timers if they have not default values #} +{% if (bgp_session['keepalive'] is defined and bgp_session['keepalive'] | int != 60) + or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} + neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] }} {{ bgp_session['holdtime'] }} +{% endif %} +{% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and DEVICE_METADATA['localhost'].has_key('default_bgp_status') and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} + neighbor {{ neighbor_addr }} shutdown +{% endif %} +{% if neighbor_addr | ipv4 %} + address-family ipv4 + neighbor {{ neighbor_addr }} peer-group PEER_V4 +{% elif neighbor_addr | ipv6 %} + address-family ipv6 +{% if bgp_session['asn'] != DEVICE_METADATA['localhost']['bgp_asn'] %} + neighbor {{ neighbor_addr }} route-map set-next-hop-global-v6 in +{% endif %} + neighbor {{ neighbor_addr }} peer-group PEER_V6 +{% endif %} +{% if bgp_session['rrclient'] | int != 0 %} + neighbor {{ neighbor_addr }} route-reflector-client +{% endif %} +{% if bgp_session['nhopself'] | int != 0 %} + neighbor {{ neighbor_addr }} next-hop-self +{% endif %} +{% if bgp_session["asn"] == DEVICE_METADATA['localhost']['bgp_asn'] + and DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" + and (not bgp_session.has_key("local_addr") or bgp_session["local_addr"] not in interfaces_in_vnets) %} + address-family l2vpn evpn + neighbor {{ neighbor_addr }} activate + advertise-all-vni + exit-address-family +{% endif %} + neighbor {{ neighbor_addr }} activate + exit-address-family +{% endblock bgp_peer %} diff --git a/dockers/docker-fpm-frr/bgpd.tsa.isolate.conf.j2 b/dockers/docker-fpm-frr/bgpd.tsa.isolate.conf.j2 new file mode 100644 index 000000000000..9cd61b899071 --- /dev/null +++ b/dockers/docker-fpm-frr/bgpd.tsa.isolate.conf.j2 @@ -0,0 +1,10 @@ +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 new file mode 100644 index 000000000000..25d7c49125e1 --- /dev/null +++ b/dockers/docker-fpm-frr/bgpd.tsa.unisolate.conf.j2 @@ -0,0 +1,6 @@ +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/daemons.common.conf.j2 b/dockers/docker-fpm-frr/daemons.common.conf.j2 new file mode 100644 index 000000000000..23eb5184f5e0 --- /dev/null +++ b/dockers/docker-fpm-frr/daemons.common.conf.j2 @@ -0,0 +1,12 @@ +! +{% block sys_init %} +hostname {{ DEVICE_METADATA['localhost']['hostname'] }} +password zebra +enable password zebra +{% endblock sys_init %} +! +{% block logging %} +log syslog informational +log facility local4 +{% endblock logging %} +! diff --git a/dockers/docker-fpm-frr/frr.conf.j2 b/dockers/docker-fpm-frr/frr.conf.j2 index d9dd6bf05633..afa40ad8ba75 100644 --- a/dockers/docker-fpm-frr/frr.conf.j2 +++ b/dockers/docker-fpm-frr/frr.conf.j2 @@ -6,205 +6,13 @@ ! {% endblock banner %} ! -{% block system_init %} -hostname {{ DEVICE_METADATA['localhost']['hostname'] }} -password zebra -log syslog informational -log facility local4 -agentx -! enable password {# {{ en_passwd }} TODO: param needed #} -{% endblock system_init %} -! -{% 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 default_route %} -! set static default route to mgmt gateway as a backup to learned default -{% for (name, prefix) in MGMT_INTERFACE|pfx_filter %} -{% if prefix | ipv4 %} -ip route 0.0.0.0/0 {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} 200 -{% endif %} -{% endfor %} -{% endblock default_route %} -! -{% 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 -route-map RM_SET_SRC permit 10 - set src {{ lo_ipv4_addrs[0] | ip }} -! -{% 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 +{% include "daemons.common.conf.j2" %} ! -{% if lo_ipv6_addrs|length > 0 %} -ipv6 protocol bgp route-map RM_SET_SRC6 -! -{% endif %} -{% endblock source_loopback %} -! -{% 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 -! -router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} - bgp log-neighbor-changes - bgp bestpath as-path multipath-relax - no bgp default ipv4-unicast -{# Advertise graceful restart capability for ToR #} -{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} - bgp graceful-restart -{% 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 bgp_sessions %} -{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %} -{% if bgp_session['asn'] | int != 0 %} - neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} - neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} -{# set the bgp neighbor timers if they have not default values #} -{% if (bgp_session['keepalive'] is defined and bgp_session['keepalive'] | int != 60) - or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} - neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] }} {{ bgp_session['holdtime'] }} -{% endif %} -{% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and DEVICE_METADATA['localhost'].has_key('default_bgp_status') and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} - neighbor {{ neighbor_addr }} shutdown -{% endif %} -{% if neighbor_addr | ipv4 %} - address-family ipv4 -{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} - neighbor {{ neighbor_addr }} allowas-in 1 -{% endif %} - neighbor {{ neighbor_addr }} activate - neighbor {{ neighbor_addr }} soft-reconfiguration inbound -{% 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 %} - maximum-paths 64 - exit-address-family -{% endif %} -{% if neighbor_addr | ipv6 %} - address-family ipv6 -{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} - neighbor {{ neighbor_addr }} allowas-in 1 -{% endif %} - neighbor {{ neighbor_addr }} activate - neighbor {{ neighbor_addr }} soft-reconfiguration inbound -{% 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'] %} - neighbor {{ neighbor_addr }} route-map set-next-hop-global-v6 in -{% endif %} - maximum-paths 64 - exit-address-family -{% endif %} -{% endif %} -{% endfor %} -{% endblock bgp_sessions %} -{% 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 - neighbor {{ bgp_peer['name'] }} remote-as {{ deployment_id_asn_map[DEVICE_METADATA['localhost']['deployment_id']] }} - neighbor {{ bgp_peer['name'] }} ebgp-multihop 255 -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if name == 'Loopback1' %} - neighbor {{ bgp_peer['name'] }} update-source {{ prefix | ip }} -{% endif %} -{% endfor %} -{% 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 - neighbor {{ bgp_peer['name'] }} soft-reconfiguration inbound - neighbor {{ bgp_peer['name'] }} route-map FROM_BGP_SPEAKER_V4 in - neighbor {{ bgp_peer['name'] }} route-map TO_BGP_SPEAKER_V4 out - maximum-paths 64 - exit-address-family - address-family ipv6 - neighbor {{ bgp_peer['name'] }} activate - neighbor {{ bgp_peer['name'] }} soft-reconfiguration inbound - maximum-paths 64 - exit-address-family -{% endfor %} -{% endif %} -{% endblock bgp_peers_with_range %} +agentx ! -{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %} -maximum-paths 64 +{% include "zebra.interfaces.conf.j2" %} ! -route-map ISOLATE permit 10 -set as-path prepend {{ DEVICE_METADATA['localhost']['bgp_asn'] }} -{% endif %} +{% include "staticd.default_route.conf.j2" %} ! -route-map set-next-hop-global-v6 permit 10 -set ipv6 next-hop prefer-global +{% include "bgpd.conf.default.j2" %} ! diff --git a/dockers/docker-fpm-frr/start.sh b/dockers/docker-fpm-frr/start.sh index 555c1ce24917..b3cef5e63244 100755 --- a/dockers/docker-fpm-frr/start.sh +++ b/dockers/docker-fpm-frr/start.sh @@ -5,16 +5,19 @@ mkdir -p /etc/frr CONFIG_TYPE=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["docker_routing_config_mode"]'` if [ -z "$CONFIG_TYPE" ] || [ "$CONFIG_TYPE" == "separated" ]; then - sonic-cfggen -d -y /etc/sonic/deployment_id_asn_map.yml -t /usr/share/sonic/templates/bgpd.conf.j2 > /etc/frr/bgpd.conf + sonic-cfggen -d -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/bgpd.conf.j2 > /etc/frr/bgpd.conf sonic-cfggen -d -t /usr/share/sonic/templates/zebra.conf.j2 > /etc/frr/zebra.conf + sonic-cfggen -d -t /usr/share/sonic/templates/staticd.conf.j2 > /etc/frr/staticd.conf echo "no service integrated-vtysh-config" > /etc/frr/vtysh.conf rm -f /etc/frr/frr.conf elif [ "$CONFIG_TYPE" == "unified" ]; then - sonic-cfggen -d -y /etc/sonic/deployment_id_asn_map.yml -t /usr/share/sonic/templates/frr.conf.j2 >/etc/frr/frr.conf + sonic-cfggen -d -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/frr.conf.j2 >/etc/frr/frr.conf echo "service integrated-vtysh-config" > /etc/frr/vtysh.conf - rm -f /etc/frr/bgpd.conf /etc/frr/zebra.conf + rm -f /etc/frr/bgpd.conf /etc/frr/zebra.conf /etc/frr/staticd.conf fi +chown -R frr:frr /etc/frr/ + sonic-cfggen -d -t /usr/share/sonic/templates/isolate.j2 > /usr/sbin/bgp-isolate chown root:root /usr/sbin/bgp-isolate chmod 0755 /usr/sbin/bgp-isolate @@ -30,7 +33,10 @@ rm -f /var/run/rsyslogd.pid supervisorctl start rsyslogd -supervisorctl start bgpcfgd +# 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 @@ -42,3 +48,5 @@ if [ "$CONFIG_TYPE" == "unified" ]; then fi supervisorctl start fpmsyncd + +supervisorctl start bgpcfgd diff --git a/dockers/docker-fpm-frr/staticd.conf.j2 b/dockers/docker-fpm-frr/staticd.conf.j2 new file mode 100644 index 000000000000..4e39e17d7dbf --- /dev/null +++ b/dockers/docker-fpm-frr/staticd.conf.j2 @@ -0,0 +1,12 @@ +! +{% block banner %} +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/frr/staticd.conf.j2 using config DB data +! file: staticd.conf +! +{% endblock banner %} +! +{% include "daemons.common.conf.j2" %} +! +{% include "staticd.default_route.conf.j2" %} +! diff --git a/dockers/docker-fpm-frr/staticd.default_route.conf.j2 b/dockers/docker-fpm-frr/staticd.default_route.conf.j2 new file mode 100644 index 000000000000..22d61ebbd0ff --- /dev/null +++ b/dockers/docker-fpm-frr/staticd.default_route.conf.j2 @@ -0,0 +1,10 @@ +! +{% block default_route %} +! set static default route to mgmt gateway as a backup to learned default +{% for (name, prefix) in MGMT_INTERFACE|pfx_filter %} +{% if prefix | ipv4 %} +ip route 0.0.0.0/0 {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} 200 +{% endif %} +{% endfor %} +{% endblock default_route %} +! diff --git a/dockers/docker-fpm-frr/supervisord.conf b/dockers/docker-fpm-frr/supervisord.conf index ba9f38507b80..fe0ce6eda1a4 100644 --- a/dockers/docker-fpm-frr/supervisord.conf +++ b/dockers/docker-fpm-frr/supervisord.conf @@ -75,3 +75,13 @@ autorestart=false startsecs=0 stdout_logfile=syslog stderr_logfile=syslog + +[program:bgp_eoiu_marker] +command=/usr/bin/bgp_eoiu_marker.py +priority=7 +autostart=false +autorestart=false +startsecs=0 +startretries=0 +stdout_logfile=syslog +stderr_logfile=syslog diff --git a/dockers/docker-fpm-frr/zebra.conf.j2 b/dockers/docker-fpm-frr/zebra.conf.j2 index 7200d81fda4a..8c1c6f96484b 100644 --- a/dockers/docker-fpm-frr/zebra.conf.j2 +++ b/dockers/docker-fpm-frr/zebra.conf.j2 @@ -6,83 +6,7 @@ ! {% endblock banner %} ! -{% block sys_init %} -hostname {{ DEVICE_METADATA['localhost']['hostname'] }} -password zebra -enable password zebra -{% endblock sys_init %} +{% include "daemons.common.conf.j2" %} ! -{% block vrf %} -{% if VNET is defined %} -{% for vnet_name, vnet_metadata in VNET.iteritems() %} -vrf {{ vnet_name }} -vni {{ vnet_metadata['vni'] }} +{% include "zebra.interfaces.conf.j2" %} ! -{% 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 default_route %} -! set static default route to mgmt gateway as a backup to learned default -{% for (name, prefix) in MGMT_INTERFACE|pfx_filter %} -{% if prefix | ipv4 %} -ip route 0.0.0.0/0 {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} 200 -{% endif %} -{% endfor %} -{% endblock default_route %} -! -{% 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 %} -! -{% block logging %} -log syslog informational -log facility local4 -{% endblock logging %} -! - diff --git a/dockers/docker-fpm-frr/zebra.interfaces.conf.j2 b/dockers/docker-fpm-frr/zebra.interfaces.conf.j2 new file mode 100644 index 000000000000..4a089e4dc726 --- /dev/null +++ b/dockers/docker-fpm-frr/zebra.interfaces.conf.j2 @@ -0,0 +1,60 @@ +! +{% block vrf %} +{% if VNET is defined %} +{% for vnet_name, vnet_metadata in VNET.iteritems() %} +vrf {{ vnet_name }} +vni {{ vnet_metadata['vni'] }} +! +{% endfor %} +{% endif %} +{% endblock vrf %} +! +{% block interfaces %} +! Enable link-detect (default disabled) +{% for (name, prefix) in INTERFACE|pfx_filter %} +interface {{ name }} +link-detect +! +{% endfor %} +{% for pc in PORTCHANNEL %} +interface {{ pc }} +link-detect +! +{% endfor %} +{% endblock interfaces %} +! +{% block source_loopback %} +{% set lo_ipv4_addrs = [] %} +{% set lo_ipv6_addrs = [] %} +{% if LOOPBACK_INTERFACE %} +{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} +{% if name == 'Loopback0' %} +{% if prefix | ipv6 %} +{% if lo_ipv6_addrs.append(prefix) %} +{% endif %} +{% else %} +{% if lo_ipv4_addrs.append(prefix) %} +{% endif %} +{% endif %} +{% endif %} +{% endfor %} +{% endif %} +! Set ip source to loopback for bgp learned routes +{% if lo_ipv4_addrs|length > 0 -%} +route-map RM_SET_SRC permit 10 + set src {{ lo_ipv4_addrs[0] | ip }} +! +{% endif %} +{% if lo_ipv6_addrs|length > 0 %} +route-map RM_SET_SRC6 permit 10 + set src {{ lo_ipv6_addrs[0] | ip }} +! +{% endif %} +ip protocol bgp route-map RM_SET_SRC +! +{% if lo_ipv6_addrs|length > 0 %} +ipv6 protocol bgp route-map RM_SET_SRC6 +! +{% endif %} +{% endblock source_loopback %} +! diff --git a/dockers/docker-fpm-quagga/bgpd.conf.j2 b/dockers/docker-fpm-quagga/bgpd.conf.j2 index b69f895ccbed..2f4c741303a4 100644 --- a/dockers/docker-fpm-quagga/bgpd.conf.j2 +++ b/dockers/docker-fpm-quagga/bgpd.conf.j2 @@ -101,7 +101,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% if bgp_peer['peer_asn'] is defined %} neighbor {{ bgp_peer['name'] }} remote-as {{ bgp_peer['peer_asn'] }} {% else %} - neighbor {{ bgp_peer['name'] }} remote-as {{ deployment_id_asn_map[DEVICE_METADATA['localhost']['deployment_id']] }} + 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 diff --git a/dockers/docker-fpm-quagga/start.sh b/dockers/docker-fpm-quagga/start.sh index 06fdd3bb3961..1ffda3d17732 100755 --- a/dockers/docker-fpm-quagga/start.sh +++ b/dockers/docker-fpm-quagga/start.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash mkdir -p /etc/quagga -sonic-cfggen -d -y /etc/sonic/deployment_id_asn_map.yml -t /usr/share/sonic/templates/bgpd.conf.j2 > /etc/quagga/bgpd.conf +sonic-cfggen -d -y /etc/sonic/constants.yml -t /usr/share/sonic/templates/bgpd.conf.j2 > /etc/quagga/bgpd.conf sonic-cfggen -d -t /usr/share/sonic/templates/zebra.conf.j2 > /etc/quagga/zebra.conf diff --git a/dockers/docker-lldp-sv2/Dockerfile.j2 b/dockers/docker-lldp-sv2/Dockerfile.j2 index 2a76c2cc6f0b..6a720514ef9b 100644 --- a/dockers/docker-lldp-sv2/Dockerfile.j2 +++ b/dockers/docker-lldp-sv2/Dockerfile.j2 @@ -40,5 +40,7 @@ COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["lldpd.conf.j2", "/usr/share/sonic/templates/"] COPY ["lldpd", "/etc/default/"] COPY ["lldpmgrd", "/usr/bin/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-platform-monitor/base_image_files/smartctl b/dockers/docker-lldp-sv2/base_image_files/lldpcli old mode 100755 new mode 100644 similarity index 71% rename from dockers/docker-platform-monitor/base_image_files/smartctl rename to dockers/docker-lldp-sv2/base_image_files/lldpcli index 2bbc5f7a6d74..3c8037862d4d --- a/dockers/docker-platform-monitor/base_image_files/smartctl +++ b/dockers/docker-lldp-sv2/base_image_files/lldpcli @@ -7,4 +7,4 @@ if [ -t 1 ] ; then DOCKER_EXEC_FLAGS+="t" fi -docker exec -$DOCKER_EXEC_FLAGS pmon smartctl "$@" +docker exec -$DOCKER_EXEC_FLAGS lldp lldpcli "$@" diff --git a/dockers/docker-lldp-sv2/critical_processes b/dockers/docker-lldp-sv2/critical_processes new file mode 100644 index 000000000000..b845b70bb3f7 --- /dev/null +++ b/dockers/docker-lldp-sv2/critical_processes @@ -0,0 +1,3 @@ +lldpd +lldp-syncd +lldpmgrd diff --git a/dockers/docker-lldp-sv2/lldpmgrd b/dockers/docker-lldp-sv2/lldpmgrd index d66072602a88..edcdc5c42e47 100755 --- a/dockers/docker-lldp-sv2/lldpmgrd +++ b/dockers/docker-lldp-sv2/lldpmgrd @@ -131,6 +131,8 @@ class LldpManager(object): For port `port_name`, look up the description and alias in the Config database, then form the appropriate lldpcli configuration command and run it. """ + port_desc = None + # Retrieve all entires for this port from the Port table port_table = swsscommon.Table(self.config_db, swsscommon.CFG_PORT_TABLE_NAME) (status, fvp) = port_table.get(port_name) diff --git a/dockers/docker-lldp-sv2/supervisord.conf b/dockers/docker-lldp-sv2/supervisord.conf index 5feb3543f1bc..3f3f5beabc8d 100644 --- a/dockers/docker-lldp-sv2/supervisord.conf +++ b/dockers/docker-lldp-sv2/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 diff --git a/dockers/docker-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2 index bfa9b2deda51..f01bca724094 100755 --- a/dockers/docker-orchagent/Dockerfile.j2 +++ b/dockers/docker-orchagent/Dockerfile.j2 @@ -29,11 +29,16 @@ RUN apt-get update && \ libmnl0 \ bridge-utils -{% if CONFIGURED_ARCH == "armhf" %} +{% if ( CONFIGURED_ARCH == "armhf" or CONFIGURED_ARCH == "arm64" ) %} ## Fix for gcc/python not found in arm docker +RUN apt-get install -f -y python2.7 python2.7-dev RUN apt-get install -y gcc-6 +{% endif %} +{% if CONFIGURED_ARCH == "armhf" %} RUN ln -s -f /usr/bin/gcc-6 /usr/bin/arm-linux-gnueabihf-gcc -RUN apt-get install -f -y python2.7 python2.7-dev +{% endif %} +{% if CONFIGURED_ARCH == "arm64" %} +RUN ln -s -f /usr/bin/gcc-6 /usr/bin/aarch64-linux-gnu-gcc {% endif %} RUN pip install \ @@ -44,7 +49,7 @@ RUN pip install \ netifaces==0.10.7 \ monotonic==1.5 -{% if CONFIGURED_ARCH == "armhf" %} +{% if ( CONFIGURED_ARCH == "armhf" or CONFIGURED_ARCH == "arm64" ) %} # Remove installed gcc RUN apt-get remove -y gcc-6 {% endif %} diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh index a94916d351fa..5e01cd480f52 100755 --- a/dockers/docker-orchagent/orchagent.sh +++ b/dockers/docker-orchagent/orchagent.sh @@ -31,6 +31,8 @@ elif [ "$platform" == "vs" ]; then ORCHAGENT_ARGS+="-m $MAC_ADDRESS" elif [ "$platform" == "mellanox" ]; then ORCHAGENT_ARGS+="" +elif [ "$platform" == "innovium" ]; then + ORCHAGENT_ARGS+="-m $MAC_ADDRESS" else MAC_ADDRESS=`sonic-cfggen -d -v 'DEVICE_METADATA.localhost.mac'` ORCHAGENT_ARGS+="-m $MAC_ADDRESS" diff --git a/dockers/docker-orchagent/supervisord.conf b/dockers/docker-orchagent/supervisord.conf index 46b37e77c0e4..9ae2776f6d26 100644 --- a/dockers/docker-orchagent/supervisord.conf +++ b/dockers/docker-orchagent/supervisord.conf @@ -34,7 +34,7 @@ stdout_logfile=syslog stderr_logfile=syslog [program:portsyncd] -command=/usr/bin/portsyncd -p /usr/share/sonic/hwsku/port_config.ini +command=/usr/bin/portsyncd priority=4 autostart=false autorestart=false diff --git a/dockers/docker-orchagent/switch.json.j2 b/dockers/docker-orchagent/switch.json.j2 index a7dafd40f267..f8beffbc9ad7 100644 --- a/dockers/docker-orchagent/switch.json.j2 +++ b/dockers/docker-orchagent/switch.json.j2 @@ -6,6 +6,8 @@ {% set hash_seed = 0 %} {% elif DEVICE_METADATA.localhost.type == "LeafRouter" %} {% set hash_seed = 10 %} +{% elif DEVICE_METADATA.localhost.type == "SpineRouter" %} +{% set hash_seed = 15 %} {% endif %} {% endif %} [ diff --git a/dockers/docker-platform-monitor/Dockerfile.j2 b/dockers/docker-platform-monitor/Dockerfile.j2 index 9a3deebef34a..fd11f628559c 100755 --- a/dockers/docker-platform-monitor/Dockerfile.j2 +++ b/dockers/docker-platform-monitor/Dockerfile.j2 @@ -56,5 +56,8 @@ RUN apt-get purge -y \ COPY ["docker_init.sh", "lm-sensors.sh", "/usr/bin/"] COPY ["docker-pmon.supervisord.conf.j2", "start.sh.j2", "/usr/share/sonic/templates/"] +COPY ["ssd_tools/*", "/usr/bin/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/bin/docker_init.sh"] diff --git a/dockers/docker-platform-monitor/base_image_files/cmd_wrapper b/dockers/docker-platform-monitor/base_image_files/cmd_wrapper new file mode 100755 index 000000000000..74e5dd7ab9cb --- /dev/null +++ b/dockers/docker-platform-monitor/base_image_files/cmd_wrapper @@ -0,0 +1,10 @@ +#!/bin/bash + +DOCKER_EXEC_FLAGS="i" + +# Determine whether stdout is on a terminal +if [ -t 1 ] ; then + DOCKER_EXEC_FLAGS+="t" +fi + +docker exec -$DOCKER_EXEC_FLAGS pmon $(basename $0) "$@" diff --git a/dockers/docker-platform-monitor/critical_processes b/dockers/docker-platform-monitor/critical_processes new file mode 100644 index 000000000000..4233cda34982 --- /dev/null +++ b/dockers/docker-platform-monitor/critical_processes @@ -0,0 +1,5 @@ +fancontrol +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 c6a571da9335..9a2414c30d05 100644 --- a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 +++ b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 diff --git a/dockers/docker-platform-monitor/ssd_tools/SmartCmd b/dockers/docker-platform-monitor/ssd_tools/SmartCmd new file mode 100755 index 000000000000..dae647e4697e Binary files /dev/null and b/dockers/docker-platform-monitor/ssd_tools/SmartCmd differ diff --git a/dockers/docker-platform-monitor/ssd_tools/iSmart b/dockers/docker-platform-monitor/ssd_tools/iSmart new file mode 100755 index 000000000000..c6bba0046024 Binary files /dev/null and b/dockers/docker-platform-monitor/ssd_tools/iSmart differ diff --git a/dockers/docker-ptf/Dockerfile.j2 b/dockers/docker-ptf/Dockerfile.j2 index 79c2802c0429..326df49d9764 100644 --- a/dockers/docker-ptf/Dockerfile.j2 +++ b/dockers/docker-ptf/Dockerfile.j2 @@ -29,10 +29,12 @@ RUN sed --in-place 's/httpredir.debian.org/debian-archive.trafficmanager.net/' / && apt-get install -y \ openssh-server \ vim \ + telnet \ net-tools \ traceroute \ lsof \ tcpdump \ + ethtool \ unzip \ pkg-config \ binutils \ @@ -51,8 +53,10 @@ RUN sed --in-place 's/httpredir.debian.org/debian-archive.trafficmanager.net/' / hping3 \ curl \ tcpdump \ + tmux \ python \ python-dev \ + python-libpcap \ python-scapy \ python-six diff --git a/dockers/docker-ptf/supervisord.conf b/dockers/docker-ptf/supervisord.conf index 9c236612d25c..be71d20a42d9 100644 --- a/dockers/docker-ptf/supervisord.conf +++ b/dockers/docker-ptf/supervisord.conf @@ -1,13 +1,13 @@ ; supervisor config file [unix_http_server] -file=/var/run/supervisor.sock ; (the path to the socket file) -chmod=0700 ; sockef file mode (default 0700) +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) +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) ; the below section must remain in the config file for RPC ; (supervisorctl/web interface) to work, additional interfaces may be @@ -16,7 +16,7 @@ childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TE supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] -serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket +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 diff --git a/dockers/docker-router-advertiser/Dockerfile.j2 b/dockers/docker-router-advertiser/Dockerfile.j2 index 1594a59c5e8a..39e7b28effc1 100644 --- a/dockers/docker-router-advertiser/Dockerfile.j2 +++ b/dockers/docker-router-advertiser/Dockerfile.j2 @@ -27,5 +27,7 @@ RUN apt-get clean -y && \ 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 ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-router-advertiser/critical_processes b/dockers/docker-router-advertiser/critical_processes new file mode 100644 index 000000000000..238a0346ac9f --- /dev/null +++ b/dockers/docker-router-advertiser/critical_processes @@ -0,0 +1 @@ +radvd diff --git a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf index f0bb4d5b3bbd..4ea84ab11c92 100644 --- a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf +++ b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-script] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 diff --git a/dockers/docker-sflow/Dockerfile.j2 b/dockers/docker-sflow/Dockerfile.j2 new file mode 100644 index 000000000000..75da64e02e4d --- /dev/null +++ b/dockers/docker-sflow/Dockerfile.j2 @@ -0,0 +1,35 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} +FROM docker-config-engine-stretch + +ARG docker_container_name +RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && \ + apt-get install -f -y \ + dmidecode \ + libmnl0=1.0.4-2 + +{% if docker_sflow_debs.strip() -%} +# Copy locally-built Debian package dependencies +{{ copy_files("debs/", docker_sflow_debs.split(' '), "/debs/") }} + +# Install locally-built Debian packages and implicitly install their dependencies +{{ install_debian_packages(docker_sflow_debs.split(' ')) }} +{%- endif %} + +RUN apt-get clean -y && \ + apt-get autoclean -y && \ + apt-get autoremove -y && \ + rm -rf /debs + +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"] + +ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-sflow/base_image_files/psample b/dockers/docker-sflow/base_image_files/psample new file mode 100755 index 000000000000..0269eb6e5d09 --- /dev/null +++ b/dockers/docker-sflow/base_image_files/psample @@ -0,0 +1,10 @@ +#!/bin/bash + +DOCKER_EXEC_FLAGS="i" + +# Determine whether stdout is on a terminal +if [ -t 1 ] ; then + DOCKER_EXEC_FLAGS+="t" +fi + +docker exec -$DOCKER_EXEC_FLAGS sflow psample "$@" diff --git a/dockers/docker-sflow/base_image_files/sflowtool b/dockers/docker-sflow/base_image_files/sflowtool new file mode 100755 index 000000000000..26e5c7d967cf --- /dev/null +++ b/dockers/docker-sflow/base_image_files/sflowtool @@ -0,0 +1,10 @@ +#!/bin/bash + +DOCKER_EXEC_FLAGS="i" + +# Determine whether stdout is on a terminal +if [ -t 1 ] ; then + DOCKER_EXEC_FLAGS+="t" +fi + +docker exec -$DOCKER_EXEC_FLAGS sflow sflowtool "$@" diff --git a/dockers/docker-sflow/critical_processes b/dockers/docker-sflow/critical_processes new file mode 100644 index 000000000000..5b24e2d8e1da --- /dev/null +++ b/dockers/docker-sflow/critical_processes @@ -0,0 +1 @@ +sflowmgrd diff --git a/dockers/docker-sflow/start.sh b/dockers/docker-sflow/start.sh new file mode 100755 index 000000000000..aaefb4d6d004 --- /dev/null +++ b/dockers/docker-sflow/start.sh @@ -0,0 +1,7 @@ +#!/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 new file mode 100644 index 000000000000..50986f197d88 --- /dev/null +++ b/dockers/docker-sflow/supervisord.conf @@ -0,0 +1,34 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + +[program:start.sh] +command=/usr/bin/start.sh +priority=1 +autostart=true +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n +priority=2 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:sflowmgrd] +command=/usr/bin/sflowmgrd +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog diff --git a/dockers/docker-snmp-sv2/Dockerfile.j2 b/dockers/docker-snmp-sv2/Dockerfile.j2 index 371bd17e2553..b62ff61eaf95 100644 --- a/dockers/docker-snmp-sv2/Dockerfile.j2 +++ b/dockers/docker-snmp-sv2/Dockerfile.j2 @@ -22,7 +22,8 @@ RUN apt-get update && \ ca-certificates \ gcc \ make \ - libdpkg-perl + libdpkg-perl \ + ipmitool {% if docker_snmp_sv2_debs.strip() -%} # Copy locally-built Debian package dependencies @@ -32,7 +33,6 @@ RUN apt-get update && \ {{ install_debian_packages(docker_snmp_sv2_debs.split(' ')) }} {%- endif %} -{%- if CONFIGURED_ARCH == "armhf" %} # Fix for hiredis compilation issues for ARM # python will throw for missing locale RUN apt-get install -y locales @@ -41,7 +41,6 @@ RUN dpkg-reconfigure --frontend noninteractive locales ENV LC_CTYPE=en_US.UTF-8 RUN sed -i '/^#.* en_US.* /s/^#//' /etc/locale.gen RUN locale-gen -{% endif %} # Install up-to-date version of pip RUN curl https://bootstrap.pypa.io/get-pip.py | python3.6 @@ -85,6 +84,8 @@ RUN apt-get -y purge \ COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["*.j2", "/usr/share/sonic/templates/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] # Although exposing ports is not needed for host net mode, keep it for possible bridge mode EXPOSE 161/udp 162/udp diff --git a/dockers/docker-snmp-sv2/critical_processes b/dockers/docker-snmp-sv2/critical_processes new file mode 100644 index 000000000000..e6039c5b9840 --- /dev/null +++ b/dockers/docker-snmp-sv2/critical_processes @@ -0,0 +1,2 @@ +snmpd +snmp-subagent diff --git a/dockers/docker-snmp-sv2/snmpd.conf.j2 b/dockers/docker-snmp-sv2/snmpd.conf.j2 index 68d08318cb98..16d7e5bff79c 100644 --- a/dockers/docker-snmp-sv2/snmpd.conf.j2 +++ b/dockers/docker-snmp-sv2/snmpd.conf.j2 @@ -14,8 +14,21 @@ # # Listen for connections on all ip addresses, including eth0, ipv4 lo +# +{% if snmp_agent_address_1 or snmp_agent_address_2 or snmp_agent_address_3 %} +{% if snmp_agent_address_1 %} +agentAddress {{ snmp_agent_address_1 }} +{% endif %} +{% if snmp_agent_address_2 %} +agentAddress {{ snmp_agent_address_2 }} +{% endif %} +{% if snmp_agent_address_3 %} +agentAddress {{ snmp_agent_address_3 }} +{% endif %} +{% else %} agentAddress udp:161 -# TODO: only support ipv4 lo addresses, add ipv6 support later +agentAddress udp6:161 +{% endif %} ############################################################################### # @@ -30,9 +43,11 @@ view systemonly included .1.3.6.1.2.1.25.1 {% if snmp_rocommunities %} {% for community in snmp_rocommunities %} rocommunity {{ community }} +rocommunity6 {{ community }} {% endfor %} {% else %} rocommunity {{ snmp_rocommunity }} +rocommunity6 {{ snmp_rocommunity }} {% endif %} ############################################################################### @@ -90,11 +105,23 @@ load 12 10 5 # Note: disabled snmp traps due to side effect of causing snmpd to listen on all ports (0.0.0.0) # # send SNMPv1 traps +{%if v1_trap_dest and v1_trap_dest != 'NotConfigured' %} +trapsink {{ v1_trap_dest }} +{% else %} #trapsink localhost public +{% endif %} # send SNMPv2c traps +{%if v2_trap_dest and v2_trap_dest != 'NotConfigured' %} +trap2sink {{ v2_trap_dest }} +{% else %} #trap2sink localhost public +{% endif %} # send SNMPv2c INFORMs +{%if v3_trap_dest and v3_trap_dest != 'NotConfigured' %} +informsink {{ v3_trap_dest }} +{% else %} #informsink localhost public +{% endif %} # Note that you typically only want *one* of these three lines # Uncommenting two (or all three) will result in multiple copies of each notification. diff --git a/dockers/docker-snmp-sv2/supervisord.conf b/dockers/docker-snmp-sv2/supervisord.conf index d80579506100..7fd16eec5bbe 100644 --- a/dockers/docker-snmp-sv2/supervisord.conf +++ b/dockers/docker-snmp-sv2/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index d4ac92feec50..d24df1ca5d77 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -76,7 +76,7 @@ RUN pip install azure-kusto-data==0.0.13 \ azure-kusto-ingest==0.0.13 # Install pytest-ansible module -RUN pip install pytest-ansible==2.0.2 +RUN pip install pytest-ansible==2.2.2 ## Copy and install sonic-mgmt docker dependencies COPY \ @@ -90,8 +90,7 @@ RUN dpkg -i \ debs/{{ deb }}{{' '}} {%- endfor %} -RUN git clone https://github.com/ansible/ansible -RUN cd ansible && git checkout v2.0.0.2-1 -b v2.0.0.2-1 && git submodule update --init --recursive && make && make install +RUN pip install ansible==2.8.7 RUN mkdir /var/run/sshd EXPOSE 22 diff --git a/dockers/docker-sonic-telemetry/Dockerfile.j2 b/dockers/docker-sonic-telemetry/Dockerfile.j2 index cfbe7c6f266c..3a5716001ca5 100644 --- a/dockers/docker-sonic-telemetry/Dockerfile.j2 +++ b/dockers/docker-sonic-telemetry/Dockerfile.j2 @@ -35,5 +35,7 @@ RUN apt-get clean -y && \ COPY ["start.sh", "telemetry.sh", "dialout.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-telemetry/critical_processes b/dockers/docker-sonic-telemetry/critical_processes new file mode 100644 index 000000000000..d6953dd0c883 --- /dev/null +++ b/dockers/docker-sonic-telemetry/critical_processes @@ -0,0 +1,2 @@ +telemetry +dialout diff --git a/dockers/docker-sonic-telemetry/supervisord.conf b/dockers/docker-sonic-telemetry/supervisord.conf index dcd8a9eb1e80..b6a01de58a7b 100644 --- a/dockers/docker-sonic-telemetry/supervisord.conf +++ b/dockers/docker-sonic-telemetry/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=always +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=true stdout_logfile=syslog stderr_logfile=syslog @@ -23,7 +29,7 @@ stderr_logfile=syslog command=/usr/bin/telemetry.sh priority=3 autostart=false -autorestart=true +autorestart=false stdout_logfile=syslog stderr_logfile=syslog @@ -31,6 +37,6 @@ stderr_logfile=syslog command=/usr/bin/dialout.sh priority=4 autostart=false -autorestart=true +autorestart=false stdout_logfile=syslog stderr_logfile=syslog diff --git a/dockers/docker-sonic-telemetry/telemetry.sh b/dockers/docker-sonic-telemetry/telemetry.sh index 999e0efde8a8..b84a53e32f93 100755 --- a/dockers/docker-sonic-telemetry/telemetry.sh +++ b/dockers/docker-sonic-telemetry/telemetry.sh @@ -7,7 +7,7 @@ TELEMETRY=`sonic-cfggen -d -v 'TELEMETRY.keys() | join(" ") if TELEMETRY'` TELEMETRY_ARGS=" -logtostderr" -if [ ! -z $X509 ]; then +if [ -n "$X509" ]; then SERVER_CRT=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_crt']"` SERVER_KEY=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_key']"` if [ -z $SERVER_CRT ] || [ -z $SERVER_KEY ]; then @@ -19,7 +19,7 @@ else TELEMETRY_ARGS+=" --insecure" fi -if [ ! -z $X509 ]; then +if [ -n "$X509" ]; then CA_CRT=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['ca_crt']"` if [ ! -z $CA_CRT ]; then TELEMETRY_ARGS+=" --ca_crt $CA_CRT" @@ -48,5 +48,3 @@ fi cd /usr/sbin exec telemetry ${TELEMETRY_ARGS} - - diff --git a/dockers/docker-teamd/Dockerfile.j2 b/dockers/docker-teamd/Dockerfile.j2 index 9188b7aaf735..fc8626e77229 100644 --- a/dockers/docker-teamd/Dockerfile.j2 +++ b/dockers/docker-teamd/Dockerfile.j2 @@ -36,5 +36,7 @@ RUN apt-get clean -y && \ COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-teamd/critical_processes b/dockers/docker-teamd/critical_processes new file mode 100644 index 000000000000..b5c543df050d --- /dev/null +++ b/dockers/docker-teamd/critical_processes @@ -0,0 +1,2 @@ +teammgrd +teamsyncd diff --git a/dockers/docker-teamd/supervisord.conf b/dockers/docker-teamd/supervisord.conf index 738751d0a59f..3a420e0fcdcf 100644 --- a/dockers/docker-teamd/supervisord.conf +++ b/dockers/docker-teamd/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index 1d8d3547d7ab..66e86774e766 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -94,7 +94,9 @@ clean_flash() { [ $f != "$cmdline_base" ] && [ $f != "aquota.user" ] && [ $f != "old_config" ] && - [ $f != "minigraph.xml" ] + [ $f != "minigraph.xml" ] && + [ $f != "snmp.yml" ] && + [ $f != "acl.json" ] then rm -rf "$target_path/$f" fi @@ -258,10 +260,18 @@ platform_specific() { aboot_machine=arista_7060dx4_32 flash_size=28000 fi - if [ "$sid" = "Smartsville" ]; then + if [ "$sid" = "Smartsville" ] || [ "$sid" = "SmartsvilleSsd" ]; then aboot_machine=arista_7280cr3_32p4 flash_size=7382 fi + if [ "$sid" = "SmartsvilleBK" ] || [ "$sid" = "SmartsvilleBKSsd" ]; then + aboot_machine=arista_7280cr3k_32p4 + flash_size=7382 + fi + if [ "$sid" = "SmartsvilleDD" ] || [ "$sid" = "SmartsvilleDDSsd" ]; then + aboot_machine=arista_7280cr3_32d4 + flash_size=7382 + fi if [ "$platform" = "rook" ] || [ "$platform" = "magpie" ] || [ "$platform" = "woodpecker" ]; then echo "tsc=reliable pcie_ports=native" >>/tmp/append diff --git a/files/build_scripts/generate_asic_config_checksum.py b/files/build_scripts/generate_asic_config_checksum.py new file mode 100644 index 000000000000..ca83f4f26a6f --- /dev/null +++ b/files/build_scripts/generate_asic_config_checksum.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python + +import syslog +import os +import hashlib + +SYSLOG_IDENTIFIER = 'asic_config_checksum' + +CHUNK_SIZE = 8192 + +CONFIG_FILES = { + os.path.abspath('./src/sonic-swss/swssconfig/sample/'): ['netbouncer.json', '00-copp.config.json'] +} + +OUTPUT_FILE = os.path.abspath('./asic_config_checksum') + +def log_info(msg): + syslog.openlog(SYSLOG_IDENTIFIER) + syslog.syslog(syslog.LOG_INFO, msg) + syslog.closelog() + +def log_error(msg): + syslog.openlog(SYSLOG_IDENTIFIER) + syslog.syslog(syslog.LOG_ERR, msg) + syslog.closelog() + +def get_config_files(config_file_map): + ''' + Generates a list of absolute paths to ASIC config files. + ''' + config_files = [] + for path, files in config_file_map.items(): + for config_file in files: + config_files.append(os.path.join(path, config_file)) + return config_files + +def generate_checksum(checksum_files): + ''' + Generates a checksum for a given list of files. Returns None if an error + occurs while reading the files. + + NOTE: The checksum is performed in the order provided. This function does + NOT do any re-ordering of the files before creating the checksum. + ''' + checksum = hashlib.sha1() + for checksum_file in checksum_files: + try: + with open(checksum_file, 'r') as f: + for chunk in iter(lambda: f.read(CHUNK_SIZE), b""): + checksum.update(chunk) + except IOError as e: + log_error('Error processing ASIC config file ' + checksum_file + ':' + e.strerror) + return None + + return checksum.hexdigest() + +def main(): + config_files = sorted(get_config_files(CONFIG_FILES)) + checksum = generate_checksum(config_files) + if checksum == None: + exit(1) + + with open(OUTPUT_FILE, 'w') as output: + output.write(checksum + '\n') + +if __name__ == '__main__': + main() diff --git a/files/build_templates/buffers_config.j2 b/files/build_templates/buffers_config.j2 index 95830cd01a89..a5212d979fcb 100644 --- a/files/build_templates/buffers_config.j2 +++ b/files/build_templates/buffers_config.j2 @@ -131,9 +131,12 @@ def {{ defs.generate_pg_profils(port_names_active) }} {% else %} "BUFFER_PG": { - "{{ port_names_active }}|0": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} }, {% endif %} @@ -141,15 +144,22 @@ def {{ defs.generate_queue_buffers(port_names_active) }} {% else %} "BUFFER_QUEUE": { - "{{ port_names_active }}|3-4": { +{% for port in PORT_ACTIVE %} + "{{ port }}|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "{{ port_names_active }}|0-2": { +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "{{ port_names_active }}|5-6": { +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} } {% endif %} } diff --git a/files/build_templates/database.service.j2 b/files/build_templates/database.service.j2 index efa98b168beb..472b9d328b7d 100644 --- a/files/build_templates/database.service.j2 +++ b/files/build_templates/database.service.j2 @@ -2,6 +2,7 @@ Description=Database container Requires=docker.service After=docker.service +After=rc-local.service [Service] User=root diff --git a/files/build_templates/dhcp_relay.service.j2 b/files/build_templates/dhcp_relay.service.j2 index 7ec133c87af7..9106e29a41e2 100644 --- a/files/build_templates/dhcp_relay.service.j2 +++ b/files/build_templates/dhcp_relay.service.j2 @@ -1,14 +1,18 @@ [Unit] Description=DHCP relay container Requires=updategraph.service swss.service teamd.service -After=updategraph.service swss.service teamd.service +After=updategraph.service swss.service syncd.service teamd.service Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 [Service] User={{ sonicadmin_user }} ExecStartPre=/usr/bin/{{ docker_container_name }}.sh start ExecStart=/usr/bin/{{ docker_container_name }}.sh wait ExecStop=/usr/bin/{{ docker_container_name }}.sh stop +Restart=always +RestartSec=30 [Install] WantedBy=multi-user.target swss.service teamd.service diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 9966728988bd..c485254647b8 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -62,6 +62,75 @@ function preStartAction() echo -n > /tmp/dump.rdb docker cp /tmp/dump.rdb database:/var/lib/redis/ fi +{%- elif docker_container_name == "snmp" %} + docker exec -i database redis-cli -n 6 HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) + vrfenabled=`/usr/bin/redis-cli -n 4 hget "MGMT_VRF_CONFIG|vrf_global" mgmtVrfEnabled` + v1SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" DestIp` + v1SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" DestPort` + v1Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" vrf` + v1Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" Community` + v2SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" DestIp` + v2SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" DestPort` + v2Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" vrf` + v2Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" Community` + v3SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" DestIp` + v3SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" DestPort` + v3Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" vrf` + v3Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" Community` + + if [ "${v1SnmpTrapIp}" != "" ] + then + if [ "${v1Vrf}" != "None" ] + then + sed -i "s/v1_trap_dest:.*/v1_trap_dest: ${v1SnmpTrapIp}:${v1SnmpTrapPort}%${v1Vrf} ${v1Comm}/" "/etc/sonic/snmp.yml" + else + sed -i "s/v1_trap_dest:.*/v1_trap_dest: ${v1SnmpTrapIp}:${v1SnmpTrapPort} ${v1Comm}/" "/etc/sonic/snmp.yml" + fi + else + sed -i "s/v1_trap_dest:.*/v1_trap_dest: NotConfigured/" "/etc/sonic/snmp.yml" + fi + if [ "${v2SnmpTrapIp}" != "" ] + then + if [ "${v2Vrf}" != "None" ] + then + sed -i "s/v2_trap_dest:.*/v2_trap_dest: ${v2SnmpTrapIp}:${v2SnmpTrapPort}%${v2Vrf} ${v2Comm}/" "/etc/sonic/snmp.yml" + else + sed -i "s/v2_trap_dest:.*/v2_trap_dest: ${v2SnmpTrapIp}:${v2SnmpTrapPort} ${v2Comm}/" "/etc/sonic/snmp.yml" + fi + else + sed -i "s/v2_trap_dest:.*/v2_trap_dest: NotConfigured/" "/etc/sonic/snmp.yml" + fi + if [ "${v3SnmpTrapIp}" != "" ] + then + if [ "${v3Vrf}" != "None" ] + then + sed -i "s/v3_trap_dest:.*/v3_trap_dest: ${v3SnmpTrapIp}:${v3SnmpTrapPort}%${v3Vrf} ${v3Comm}/" "/etc/sonic/snmp.yml" + else + sed -i "s/v3_trap_dest:.*/v3_trap_dest: ${v3SnmpTrapIp}:${v3SnmpTrapPort} ${v3Comm}/" "/etc/sonic/snmp.yml" + fi + else + sed -i "s/v3_trap_dest:.*/v3_trap_dest: NotConfigured/" "/etc/sonic/snmp.yml" + fi + + echo -n "" > /tmp/snmpagentaddr.yml + keys=`/usr/bin/redis-cli -n 4 keys "SNMP_AGENT_ADDRESS_CONFIG|*"` + count=1 + for key in $keys;do + ip=`echo $key|cut -d "|" -f2` + echo -n "snmp_agent_address_$count: $ip" >> /tmp/snmpagentaddr.yml + port=`echo $key|cut -d "|" -f3` + if [ -n "$port" ]; then + echo -n ":$port" >> /tmp/snmpagentaddr.yml + fi + vrf=`echo $key|cut -d "|" -f4` + if [ -n "$vrf" ]; then + echo -n "%$vrf" >> /tmp/snmpagentaddr.yml + fi + echo "" >> /tmp/snmpagentaddr.yml + count=$((count+1)) + done + sed -i '/snmp_agent_address_*/d' /etc/sonic/snmp.yml + cat /tmp/snmpagentaddr.yml >> /etc/sonic/snmp.yml {%- else %} : # nothing {%- endif %} @@ -71,10 +140,7 @@ function postStartAction() { {%- if docker_container_name == "database" %} # Wait until redis starts - REDIS_SOCK="/var/run/redis/redis.sock" - until [[ $(/usr/bin/docker exec database redis-cli -s $REDIS_SOCK ping | grep -c PONG) -gt 0 ]]; do - sleep 1; - done + /usr/bin/docker exec database ping_pong_db_insts if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then rm -f $WARM_DIR/dump.rdb else @@ -110,8 +176,6 @@ function postStartAction() docker cp $PSENSOR pmon:/usr/bin/ fi fi -{%- elif docker_container_name == "snmp" %} - docker exec -i database redis-cli -n 6 HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) {%- else %} : # nothing {%- endif %} @@ -151,7 +215,10 @@ start() { {%- endif %} preStartAction docker start {{docker_container_name}} - updateHostName "$HOSTNAME" + CURRENT_HOSTNAME="$(docker exec {{docker_container_name}} hostname)" + if [ x"$HOSTNAME" != x"$CURRENT_HOSTNAME" ]; then + updateHostName "$HOSTNAME" + fi postStartAction exit $? fi @@ -163,6 +230,11 @@ start() { {%- if docker_container_name == "database" %} echo "Creating new {{docker_container_name}} container" + # if database_config exists in old_config, use it; otherwise use the default one in new image + if [ -f /etc/sonic/old_config/database_config.json ]; then + echo "Use database_config.json from old system..." + mv /etc/sonic/old_config/database_config.json /etc/sonic/ + fi {%- else %} echo "Creating new {{docker_container_name}} container with HWSKU $HWSKU" {%- endif %} diff --git a/files/build_templates/lldp.service.j2 b/files/build_templates/lldp.service.j2 index c317e18efc5c..2599fc5c5bdc 100644 --- a/files/build_templates/lldp.service.j2 +++ b/files/build_templates/lldp.service.j2 @@ -1,14 +1,18 @@ [Unit] Description=LLDP container Requires=updategraph.service -After=updategraph.service +After=updategraph.service swss.service syncd.service Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 [Service] User={{ sonicadmin_user }} ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh wait ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 [Install] WantedBy=multi-user.target diff --git a/files/build_templates/pmon.service.j2 b/files/build_templates/pmon.service.j2 index 33f3173b4887..11dea5d12783 100644 --- a/files/build_templates/pmon.service.j2 +++ b/files/build_templates/pmon.service.j2 @@ -2,13 +2,20 @@ Description=Platform monitor container Requires=updategraph.service After=updategraph.service +{% if sonic_asic_platform == 'mellanox' %} +After=syncd.service +{% endif %} Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 [Service] User={{ sonicadmin_user }} ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh wait ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 [Install] WantedBy=multi-user.target diff --git a/files/build_templates/qos_config.j2 b/files/build_templates/qos_config.j2 index a666367873bd..2a9a5be8d83c 100644 --- a/files/build_templates/qos_config.j2 +++ b/files/build_templates/qos_config.j2 @@ -29,6 +29,7 @@ {%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%} +{%- set backend_device_types = ['BackEndToRRouter', 'BackEndLeafRouter'] -%} { @@ -72,6 +73,20 @@ "7": "7" } }, +{% if 'type' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['type'] in backend_device_types %} + "DOT1P_TO_TC_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, +{% else %} "DSCP_TO_TC_MAP": { "AZURE": { "0" : "1", @@ -140,6 +155,7 @@ "63": "1" } }, +{% endif %} "SCHEDULER": { "scheduler.0": { "type" : "DWRR", @@ -159,8 +175,13 @@ }, {% endif %} "PORT_QOS_MAP": { - "{{ port_names_active }}": { +{% for port in PORT_ACTIVE %} + "{{ port }}": { +{% if 'type' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['type'] in backend_device_types %} + "dot1p_to_tc_map" : "[DOT1P_TO_TC_MAP|AZURE]", +{% else %} "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", +{% endif %} "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]", @@ -168,7 +189,9 @@ "pfc_to_pg_map" : "[PFC_PRIORITY_TO_PRIORITY_GROUP_MAP|AZURE]", {% endif %} "pfc_enable" : "3,4" - } + }{% if not loop.last %},{% endif %} + +{% endfor %} }, "WRED_PROFILE": { "AZURE_LOSSLESS" : { diff --git a/files/build_templates/radv.service.j2 b/files/build_templates/radv.service.j2 index 4f1c67e661b0..b3dd3a8d8bcb 100644 --- a/files/build_templates/radv.service.j2 +++ b/files/build_templates/radv.service.j2 @@ -1,14 +1,18 @@ [Unit] Description=Router advertiser container -Requires=updategraph.service swss.service -After=updategraph.service swss.service +Requires=updategraph.service +After=updategraph.service swss.service syncd.service Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 [Service] User={{ sonicadmin_user }} ExecStartPre=/usr/bin/{{ docker_container_name }}.sh start ExecStart=/usr/bin/{{ docker_container_name }}.sh wait ExecStop=/usr/bin/{{ docker_container_name }}.sh stop +Restart=always +RestartSec=30 [Install] -WantedBy=multi-user.target swss.service +WantedBy=multi-user.target diff --git a/files/build_templates/sflow.service.j2 b/files/build_templates/sflow.service.j2 new file mode 100644 index 000000000000..de08f027adff --- /dev/null +++ b/files/build_templates/sflow.service.j2 @@ -0,0 +1,18 @@ +[Unit] +Description=sFlow container +Requires=swss.service +After=swss.service syncd.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start +ExecStart=/usr/bin/{{docker_container_name}}.sh wait +ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/snmp.service.j2 b/files/build_templates/snmp.service.j2 index 43f46bd2b9c0..310048e68beb 100644 --- a/files/build_templates/snmp.service.j2 +++ b/files/build_templates/snmp.service.j2 @@ -2,13 +2,17 @@ Description=SNMP container Requires=updategraph.service Requisite=swss.service -After=updategraph.service swss.service +After=updategraph.service swss.service syncd.service Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 [Service] ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh wait ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 [Install] WantedBy=multi-user.target swss.service diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 0f27c15273c1..13d5432e09ea 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -116,6 +116,12 @@ sudo cp {{platform_common_py2_wheel_path}} $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2 sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $PLATFORM_COMMON_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2_WHEEL_NAME +# Install sonic-daemon-base Python 2 package +DAEMON_BASE_PY2_WHEEL_NAME=$(basename {{daemon_base_py2_wheel_path}}) +sudo cp {{daemon_base_py2_wheel_path}} $FILESYSTEM_ROOT/$DAEMON_BASE_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $DAEMON_BASE_PY2_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$DAEMON_BASE_PY2_WHEEL_NAME + # Install built Python Click package (and its dependencies via 'apt-get -y install -f') # Do this before installing sonic-utilities so that it doesn't attempt to install # an older version as part of its dependencies @@ -154,6 +160,10 @@ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libnss-tacplus_*.deb || \ sudo LANG=C chroot $FILESYSTEM_ROOT pam-auth-update --remove tacplus sudo sed -i -e '/^passwd/s/ tacplus//' $FILESYSTEM_ROOT/etc/nsswitch.conf +# Install a custom version of kdump-tools (and its dependencies via 'apt-get -y install -f') +sudo DEBIAN_FRONTEND=noninteractive dpkg --root=$FILESYSTEM_ROOT -i $debs_path/kdump-tools_*.deb || \ + sudo LANG=C DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=truechroot $FILESYSTEM_ROOT apt-get -q --no-install-suggests --no-install-recommends --force-no install + # Copy crontabs sudo cp -f $IMAGE_CONFIGS/cron.d/* $FILESYSTEM_ROOT/etc/cron.d/ @@ -208,6 +218,9 @@ sudo cp $IMAGE_CONFIGS/hostname/hostname-config.service $FILESYSTEM_ROOT/etc/sy echo "hostname-config.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/hostname/hostname-config.sh $FILESYSTEM_ROOT/usr/bin/ +# Copy miscellaneous scripts +sudo cp $IMAGE_CONFIGS/misc/docker-wait-any $FILESYSTEM_ROOT/usr/bin/ + # Copy updategraph script and service file j2 files/build_templates/updategraph.service.j2 | sudo tee $FILESYSTEM_ROOT/etc/systemd/system/updategraph.service sudo cp $IMAGE_CONFIGS/updategraph/updategraph $FILESYSTEM_ROOT/usr/bin/ @@ -229,7 +242,7 @@ sudo bash -c "echo '{ \"DEVICE_METADATA\": { \"localhost\": { \"default_bgp_stat sudo cp $IMAGE_CONFIGS/snmp/snmp.yml $FILESYSTEM_ROOT/etc/sonic/ # Copy ASN configuration files -sudo cp $IMAGE_CONFIGS/asn/deployment_id_asn_map.yml $FILESYSTEM_ROOT/etc/sonic/ +sudo cp $IMAGE_CONFIGS/constants/constants.yml $FILESYSTEM_ROOT/etc/sonic/ # Copy sudoers configuration file sudo cp $IMAGE_CONFIGS/sudoers/sudoers $FILESYSTEM_ROOT/etc/ @@ -300,6 +313,14 @@ sudo cp $IMAGE_CONFIGS/platform/rc.local $FILESYSTEM_ROOT/etc/ ## copy blacklist file sudo cp $IMAGE_CONFIGS/platform/linux_kernel_bde.conf $FILESYSTEM_ROOT/etc/modprobe.d/ +# Enable psample drivers to support sFlow on vs +{% if sonic_asic_platform == "vs" %} +sudo tee -a $FILESYSTEM_ROOT/etc/modules-load.d/modules.conf > /dev/null < /dev/null 2>&1 + diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index b1ec2644e122..b32e3d8cd668 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -8,6 +8,7 @@ import subprocess import syslog import copy import jinja2 +import ipaddr as ipaddress from swsssdk import ConfigDBConnector # FILE @@ -23,10 +24,8 @@ TACPLUS_SERVER_TIMEOUT_DEFAULT = "5" TACPLUS_SERVER_AUTH_TYPE_DEFAULT = "pap" -def is_valid_hostname(name): - if hostname[-1] == ".": - hostname = hostname[:-1] # strip exactly one dot from the right, if present - if len(hostname) > 253: +def is_valid_hostname(hostname): + if hostname[-1] == "." or len(hostname) > 253: return False allowed = re.compile("(?!-)[A-Z\d-]{1,63}(? /etc/hosts.new +else + cp -f /etc/hosts /etc/hosts.new fi -echo "127.0.0.1 $HOSTNAME" >> /etc/hosts +echo "127.0.0.1 $HOSTNAME" >> /etc/hosts.new +# Swap file: hosts.new and hosts +mv -f /etc/hosts /etc/hosts.old +mv -f /etc/hosts.new /etc/hosts diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index e0f9a290d184..91be4437fc06 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -14,13 +14,14 @@ iface mgmt # The loopback network interface auto lo iface lo inet loopback -# Use command 'ip addr list dev lo' to check all addresses -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -iface lo {{ 'inet' if prefix | ipv4 else 'inet6' }} static - address {{ prefix | ip }} - netmask {{ prefix | netmask if prefix | ipv4 else prefix | prefixlen }} -# -{% endfor %} +{% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} +# The loopback network interface for mgmt VRF that is required for applications like NTP + up ip link add lo-m type dummy + up ip addr add 127.0.0.1/8 dev lo-m + up ip link set lo-m up + up ip link set dev lo-m master mgmt + down ip link delete dev lo-m +{% endif %} {% endblock loopback %} {% block mgmt_interface %} diff --git a/files/image_config/misc/docker-wait-any b/files/image_config/misc/docker-wait-any new file mode 100755 index 000000000000..3988a9fbdf57 --- /dev/null +++ b/files/image_config/misc/docker-wait-any @@ -0,0 +1,62 @@ +#!/usr/bin/env python + +""" + docker-wait-any + This script takes one or more Docker container names as arguments, + and it will block indefinitely while all of the specified containers + are running. If any of the specified containers stop, the script will + exit. + This script was created because the 'docker wait' command is lacking + this functionality. It will block until ALL specified containers have + stopped running. Here, we spawn multiple threads and wait on one + container per thread. If any of the threads exit, the entire + application will exit. + NOTE: This script is written against docker-py version 1.6.0. Newer + versions of docker-py have a different API. +""" + +import sys +import threading +from docker import Client + +# Instantiate a global event to share among our threads +g_thread_exit_event = threading.Event() + + +def usage(): + print("Usage: {} [ ...]".format(sys.argv[0])) + sys.exit(1) + + +def wait_for_container(docker_client, container_name): + docker_client.wait(container_name) + + print("No longer waiting on container '{}'".format(container_name)) + + # Signal the main thread to exit + g_thread_exit_event.set() + + +def main(): + thread_list = [] + + docker_client = Client(base_url='unix://var/run/docker.sock') + + # Ensure we were passed at least one argument + if len(sys.argv) < 2: + usage() + + container_names = sys.argv[1:] + + for container_name in container_names: + t = threading.Thread(target=wait_for_container, args=[docker_client, container_name]) + t.daemon = True + t.start() + thread_list.append(t) + + # Wait until we receive an event signifying one of the containers has stopped + g_thread_exit_event.wait() + sys.exit(0) + +if __name__ == '__main__': + main() diff --git a/files/image_config/monit/monitrc b/files/image_config/monit/monitrc new file mode 100644 index 000000000000..f9350733fa44 --- /dev/null +++ b/files/image_config/monit/monitrc @@ -0,0 +1,308 @@ +############################################################################### +## Monit control file +############################################################################### +## +## Comments begin with a '#' and extend through the end of the line. Keywords +## are case insensitive. All path's MUST BE FULLY QUALIFIED, starting with '/'. +## +## Below you will find examples of some frequently used statements. For +## information about the control file and a complete list of statements and +## options, please have a look in the Monit manual. +## +## +############################################################################### +## Global section +############################################################################### +## +## Start Monit in the background (run as a daemon): +# + set daemon 120 # check services at 2-minute intervals +# with start delay 240 # optional: delay the first check by 4-minutes (by +# # default Monit check immediately after Monit start) +# +# +## Set syslog logging. If you want to log to a standalone log file instead, +## specify the full path to the log file +# +# set logfile /var/log/monit.log +set logfile syslog +# +# +## Set the location of the Monit lock file which stores the process id of the +## running Monit instance. By default this file is stored in $HOME/.monit.pid +# +# set pidfile /var/run/monit.pid +# +## Set the location of the Monit id file which stores the unique id for the +## Monit instance. The id is generated and stored on first Monit start. By +## default the file is placed in $HOME/.monit.id. +# +# set idfile /var/.monit.id + set idfile /var/lib/monit/id +# +## Set the location of the Monit state file which saves monitoring states +## on each cycle. By default the file is placed in $HOME/.monit.state. If +## the state file is stored on a persistent filesystem, Monit will recover +## the monitoring state across reboots. If it is on temporary filesystem, the +## state will be lost on reboot which may be convenient in some situations. +# + set statefile /var/lib/monit/state +# +# + +## Set limits for various tests. The following example shows the default values: +## +# set limits { +# programOutput: 512 B, # check program's output truncate limit +# sendExpectBuffer: 256 B, # limit for send/expect protocol test +# fileContentBuffer: 512 B, # limit for file content test +# httpContentBuffer: 1 MB, # limit for HTTP content test +# networkTimeout: 5 seconds # timeout for network I/O +# programTimeout: 300 seconds # timeout for check program +# stopTimeout: 30 seconds # timeout for service stop +# startTimeout: 30 seconds # timeout for service start +# restartTimeout: 30 seconds # timeout for service restart +# } + +## Set global SSL options (just most common options showed, see manual for +## full list). +# +# set ssl { +# verify : enable, # verify SSL certificates (disabled by default but STRONGLY RECOMMENDED) +# selfsigned : allow # allow self signed SSL certificates (reject by default) +# } +# +# +## Set the list of mail servers for alert delivery. Multiple servers may be +## specified using a comma separator. If the first mail server fails, Monit +# will use the second mail server in the list and so on. By default Monit uses +# port 25 - it is possible to override this with the PORT option. +# +# set mailserver mail.bar.baz, # primary mailserver +# backup.bar.baz port 10025, # backup mailserver on port 10025 +# localhost # fallback relay +# +# +## By default Monit will drop alert events if no mail servers are available. +## If you want to keep the alerts for later delivery retry, you can use the +## EVENTQUEUE statement. The base directory where undelivered alerts will be +## stored is specified by the BASEDIR option. You can limit the queue size +## by using the SLOTS option (if omitted, the queue is limited by space +## available in the back end filesystem). +# + set eventqueue + basedir /var/lib/monit/events # set the base directory where events will be stored + slots 100 # optionally limit the queue size +# +# +## Send status and events to M/Monit (for more informations about M/Monit +## see https://mmonit.com/). By default Monit registers credentials with +## M/Monit so M/Monit can smoothly communicate back to Monit and you don't +## have to register Monit credentials manually in M/Monit. It is possible to +## disable credential registration using the commented out option below. +## Though, if safety is a concern we recommend instead using https when +## communicating with M/Monit and send credentials encrypted. The password +## should be URL encoded if it contains URL-significant characters like +## ":", "?", "@". +# +# set mmonit http://monit:monit@192.168.1.10:8080/collector +# # and register without credentials # Don't register credentials +# +# +## Monit by default uses the following format for alerts if the the mail-format +## statement is missing:: +## --8<-- +## set mail-format { +## from: Monit +## subject: monit alert -- $EVENT $SERVICE +## message: $EVENT Service $SERVICE +## Date: $DATE +## Action: $ACTION +## Host: $HOST +## Description: $DESCRIPTION +## +## Your faithful employee, +## Monit +## } +## --8<-- +## +## You can override this message format or parts of it, such as subject +## or sender using the MAIL-FORMAT statement. Macros such as $DATE, etc. +## are expanded at runtime. For example, to override the sender, use: +# +# set mail-format { from: monit@foo.bar } +# +# +## You can set alert recipients whom will receive alerts if/when a +## service defined in this file has errors. Alerts may be restricted on +## events by using a filter as in the second example below. +# +# set alert sysadm@foo.bar # receive all alerts +# +## Do not alert when Monit starts, stops or performs a user initiated action. +## This filter is recommended to avoid getting alerts for trivial cases. +# +# set alert your-name@your.domain not on { instance, action } +# +# +## Monit has an embedded HTTP interface which can be used to view status of +## services monitored and manage services from a web interface. The HTTP +## interface is also required if you want to issue Monit commands from the +## command line, such as 'monit status' or 'monit restart service' The reason +## for this is that the Monit client uses the HTTP interface to send these +## commands to a running Monit daemon. See the Monit Wiki if you want to +## enable SSL for the HTTP interface. +# +set httpd unixsocket /var/run/monit.sock and + allow localhost # allow localhost to connect to the server and +# +############################################################################### +## Services +############################################################################### +## +## Check general system resources such as load average, cpu and memory +## usage. Each test specifies a resource, conditions and the action to be +## performed should a test fail. +# +# check system $HOST +# if loadavg (1min) > 4 then alert +# if loadavg (5min) > 2 then alert +# if cpu usage > 95% for 10 cycles then alert +# if memory usage > 75% then alert +# if swap usage > 25% then alert +# +# +## Check if a file exists, checksum, permissions, uid and gid. In addition +## to alert recipients in the global section, customized alert can be sent to +## additional recipients by specifying a local alert handler. The service may +## be grouped using the GROUP option. More than one group can be specified by +## repeating the 'group name' statement. +# +# check file apache_bin with path /usr/local/apache/bin/httpd +# if failed checksum and +# expect the sum 8f7f419955cefa0b33a2ba316cba3659 then unmonitor +# if failed permission 755 then unmonitor +# if failed uid root then unmonitor +# if failed gid root then unmonitor +# alert security@foo.bar on { +# checksum, permission, uid, gid, unmonitor +# } with the mail-format { subject: Alarm! } +# group server +# +# +## Check that a process is running, in this case Apache, and that it respond +## to HTTP and HTTPS requests. Check its resource usage such as cpu and memory, +## and number of children. If the process is not running, Monit will restart +## it by default. In case the service is restarted very often and the +## problem remains, it is possible to disable monitoring using the TIMEOUT +## statement. This service depends on another service (apache_bin) which +## is defined above. +# +# check process apache with pidfile /usr/local/apache/logs/httpd.pid +# start program = "/etc/init.d/httpd start" with timeout 60 seconds +# stop program = "/etc/init.d/httpd stop" +# if cpu > 60% for 2 cycles then alert +# if cpu > 80% for 5 cycles then restart +# if totalmem > 200.0 MB for 5 cycles then restart +# if children > 250 then restart +# if loadavg(5min) greater than 10 for 8 cycles then stop +# if failed host www.tildeslash.com port 80 protocol http +# and request "/somefile.html" +# then restart +# if failed port 443 protocol https with timeout 15 seconds then restart +# if 3 restarts within 5 cycles then unmonitor +# depends on apache_bin +# group server +# +# +## Check filesystem permissions, uid, gid, space and inode usage. Other services, +## such as databases, may depend on this resource and an automatically graceful +## stop may be cascaded to them before the filesystem will become full and data +## lost. +# +# check filesystem datafs with path /dev/sdb1 +# start program = "/bin/mount /data" +# stop program = "/bin/umount /data" +# if failed permission 660 then unmonitor +# if failed uid root then unmonitor +# if failed gid disk then unmonitor +# if space usage > 80% for 5 times within 15 cycles then alert +# if space usage > 99% then stop +# if inode usage > 30000 then alert +# if inode usage > 99% then stop +# group server +# +# +## Check a file's timestamp. In this example, we test if a file is older +## than 15 minutes and assume something is wrong if its not updated. Also, +## if the file size exceed a given limit, execute a script +# +# check file database with path /data/mydatabase.db +# if failed permission 700 then alert +# if failed uid data then alert +# if failed gid data then alert +# if timestamp > 15 minutes then alert +# if size > 100 MB then exec "/my/cleanup/script" as uid dba and gid dba +# +# +## Check directory permission, uid and gid. An event is triggered if the +## directory does not belong to the user with uid 0 and gid 0. In addition, +## the permissions have to match the octal description of 755 (see chmod(1)). +# +# check directory bin with path /bin +# if failed permission 755 then unmonitor +# if failed uid 0 then unmonitor +# if failed gid 0 then unmonitor +# +# +## Check a remote host availability by issuing a ping test and check the +## content of a response from a web server. Up to three pings are sent and +## connection to a port and an application level network check is performed. +# +# check host myserver with address 192.168.1.1 +# if failed ping then alert +# if failed port 3306 protocol mysql with timeout 15 seconds then alert +# if failed port 80 protocol http +# and request /some/path with content = "a string" +# then alert +# +# +## Check a network link status (up/down), link capacity changes, saturation +## and bandwidth usage. +# +# check network public with interface eth0 +# if failed link then alert +# if changed link then alert +# if saturation > 90% then alert +# if download > 10 MB/s then alert +# if total uploaded > 1 GB in last hour then alert +# +# +## Check custom program status output. +# +# check program myscript with path /usr/local/bin/myscript.sh +# if status != 0 then alert +# +# +############################################################################### +## Includes +############################################################################### +## +## It is possible to include additional configuration parts from other files or +## directories. +# + include /etc/monit/conf.d/* + include /etc/monit/conf-enabled/* +# +check filesystem root-overlay with path / + if space usage > 90% for 5 times within 10 cycles then alert +check filesystem var-log with path /var/log + if space usage > 90% for 5 times within 10 cycles then alert +check system $HOST + if memory usage > 90% for 5 times within 10 cycles then alert + if cpu usage (user) > 90% for 5 times within 10 cycles then alert + if cpu usage (system) > 90% for 5 times within 10 cycles then alert +check process rsyslog with pidfile /var/run/rsyslogd.pid + start program = "/bin/systemctl start rsyslog.service" + stop program = "/bin/systemctl stop rsyslog.service" + if totalmem > 800 MB for 5 times within 10 cycles then restart diff --git a/files/image_config/ntp/ntp b/files/image_config/ntp/ntp new file mode 100755 index 000000000000..ecf0e5089071 --- /dev/null +++ b/files/image_config/ntp/ntp @@ -0,0 +1,91 @@ +#!/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 "cgexec -g l3mdev:mgmt". +# Check has been added to verify the management VRF enabled status and use cgexec when it is enabled. +# This file will be copied on top of the etc/init.d/ntp file that gets created during build process. + +### BEGIN INIT INFO +# Provides: ntp +# Required-Start: $network $remote_fs $syslog +# Required-Stop: $network $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: +# Short-Description: Start NTP daemon +### END INIT INFO + +PATH=/sbin:/bin:/usr/sbin:/usr/bin + +. /lib/lsb/init-functions + +DAEMON=/usr/sbin/ntpd +PIDFILE=/var/run/ntpd.pid + +test -x $DAEMON || exit 5 + +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 + +case $1 in + start) + log_daemon_msg "Starting NTP server" "ntpd" + if [ -z "$UGID" ]; then + log_failure_msg "user \"$RUNASUSER\" does not exist" + exit 1 + 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 + log_daemon_msg "Starting NTP server in mgmt-vrf" "ntpd" + cgexec -g l3mdev:mgmt start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $NTPD_OPTS + else + log_daemon_msg "Starting NTP server in default-vrf" "ntpd" + start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $NTPD_OPTS + fi + ) 9>$LOCKFILE + log_end_msg $? + ;; + stop) + log_daemon_msg "Stopping NTP server" "ntpd" + start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE --retry=TERM/30/KILL/5 --exec $DAEMON + log_end_msg $? + rm -f $PIDFILE + ;; + restart|force-reload) + $0 stop && sleep 2 && $0 start + ;; + try-restart) + if $0 status >/dev/null; then + $0 restart + else + exit 0 + fi + ;; + reload) + exit 3 + ;; + status) + status_of_proc $DAEMON "NTP server" + ;; + *) + echo "Usage: $0 {start|stop|restart|try-restart|force-reload|status}" + exit 2 + ;; +esac diff --git a/files/image_config/ntp/ntp.conf.j2 b/files/image_config/ntp/ntp.conf.j2 index 1255369773f0..cef6527fc28f 100644 --- a/files/image_config/ntp/ntp.conf.j2 +++ b/files/image_config/ntp/ntp.conf.j2 @@ -27,12 +27,19 @@ filegen clockstats file clockstats type day enable server {{ ntp_server }} iburst {% endfor %} -#only listen on localhost and eth0 ips (default is to listen on all ip addresses) +#only listen on MGMT_INTERFACE, LOOPBACK_INTERFACE ip when MGMT_INTERFACE is not defined, or eth0 +# if we don't have both of them (default is to listen on all ip addresses) interface ignore wildcard {% if MGMT_INTERFACE %} {% for (mgmt_intf, mgmt_prefix) in MGMT_INTERFACE|pfx_filter %} interface listen {{ mgmt_prefix | ip }} {% endfor %} +{% elif LOOPBACK_INTERFACE %} +{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} +{% if prefix | ipv4 and name == 'Loopback0' %} +interface listen {{ prefix | ip }} +{% endif %} +{% endfor %} {% else %} interface listen eth0 {% endif %} diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index 8018f7caf32b..d64ec1bb7916 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -121,6 +121,8 @@ program_console_speed() #### Begin Main Body #### +logger "SONiC version ${SONIC_VERSION} starting up..." + # If the machine.conf is absent, it indicates that the unit booted # into SONiC from another NOS. Extract the machine.conf from ONIE. if [ ! -e /host/machine.conf ]; then @@ -221,6 +223,8 @@ if [ -f $FIRST_BOOT_FILE ]; then elif [ -f /host/minigraph.xml ]; then mkdir -p /etc/sonic/old_config mv /host/minigraph.xml /etc/sonic/old_config/ + [ -f /host/acl.json ] && mv /host/acl.json /etc/sonic/old_config/ + [ -f /host/snmp.yml ] && mv /host/snmp.yml /etc/sonic/old_config/ touch /tmp/pending_config_migration elif [ -n "$migration" ] && [ -f /host/migration/minigraph.xml ]; then mkdir -p /etc/sonic/old_config @@ -233,10 +237,15 @@ if [ -f $FIRST_BOOT_FILE ]; then touch /tmp/pending_config_initialization fi + # Notify firstboot to Platform, to use it for reboot-cause + touch /tmp/notify_firstboot_to_platform + if [ -d /host/image-$SONIC_VERSION/platform/$platform ]; then dpkg -i /host/image-$SONIC_VERSION/platform/$platform/*.deb fi + sync + # If the unit booted into SONiC from another NOS's grub, # we now install a grub for SONiC. if [ -n "$onie_platform" ] && [ -n "$migration" ]; then diff --git a/files/image_config/process-reboot-cause/process-reboot-cause b/files/image_config/process-reboot-cause/process-reboot-cause index 81c496a025ce..49cfa752641f 100755 --- a/files/image_config/process-reboot-cause/process-reboot-cause +++ b/files/image_config/process-reboot-cause/process-reboot-cause @@ -21,6 +21,7 @@ SYSLOG_IDENTIFIER = "process-reboot-cause" REBOOT_CAUSE_DIR = "/host/reboot-cause/" REBOOT_CAUSE_FILE = REBOOT_CAUSE_DIR + "reboot-cause.txt" PREVIOUS_REBOOT_CAUSE_FILE = REBOOT_CAUSE_DIR + "previous-reboot-cause.txt" +FIRST_BOOT_PLATFORM_FILE = "/tmp/notify_firstboot_to_platform" UNKNOWN_REBOOT_CAUSE = "Unknown" @@ -86,6 +87,13 @@ def main(): cause_file = open(REBOOT_CAUSE_FILE, "r") previous_reboot_cause = cause_file.readline().rstrip('\n') cause_file.close() + # If it is FirstTime Boot and previous_reboot_cause is unknown + # and hardware_reboot cause is non_hardware then + # Update the reboot cause as required + if os.path.isfile(FIRST_BOOT_PLATFORM_FILE): + if (previous_reboot_cause == UNKNOWN_REBOOT_CAUSE): + previous_reboot_cause = UNKNOWN_REBOOT_CAUSE + os.remove(FIRST_BOOT_PLATFORM_FILE) elif hardware_reboot_cause == chassis.REBOOT_CAUSE_HARDWARE_OTHER: previous_reboot_cause = "{} ({})".format(hardware_reboot_cause, optional_details) else: @@ -100,6 +108,12 @@ def main(): previous_reboot_cause = cause_file.readline().rstrip('\n') cause_file.close() + # If it is FirstTime Boot and previous_reboot_cause is unknown + # Update the reboot cause as required + if os.path.isfile(FIRST_BOOT_PLATFORM_FILE): + if (previous_reboot_cause == UNKNOWN_REBOOT_CAUSE): + previous_reboot_cause = UNKNOWN_REBOOT_CAUSE + os.remove(FIRST_BOOT_PLATFORM_FILE) # Write the previous reboot cause to PREVIOUS_REBOOT_CAUSE_FILE prev_cause_file = open(PREVIOUS_REBOOT_CAUSE_FILE, "w") prev_cause_file.write(previous_reboot_cause) diff --git a/files/image_config/rsyslog/rsyslog.conf.j2 b/files/image_config/rsyslog/rsyslog.conf.j2 index e714fcec5ab4..fbf8bf20160a 100644 --- a/files/image_config/rsyslog/rsyslog.conf.j2 +++ b/files/image_config/rsyslog/rsyslog.conf.j2 @@ -42,7 +42,7 @@ $ActionFileDefaultTemplate SONiCFileFormat #Set remote syslog server {% for server in SYSLOG_SERVER %} -*.* @{{ server }}:514;SONiCFileFormat +*.* @[{{ server }}]:514;SONiCFileFormat {% endfor %} # diff --git a/files/image_config/snmp/snmp.yml b/files/image_config/snmp/snmp.yml index 117619975fbb..b200670f0d94 100644 --- a/files/image_config/snmp/snmp.yml +++ b/files/image_config/snmp/snmp.yml @@ -1,2 +1,5 @@ snmp_rocommunity: public snmp_location: public +v1_trap_dest: NotConfigured +v2_trap_dest: NotConfigured +v3_trap_dest: NotConfigured diff --git a/files/image_config/updategraph/updategraph b/files/image_config/updategraph/updategraph index b14f75f8582f..2eb510afa4e1 100755 --- a/files/image_config/updategraph/updategraph +++ b/files/image_config/updategraph/updategraph @@ -15,7 +15,10 @@ reload_minigraph() acl-loader update full /etc/sonic/acl.json fi config qos reload - pfcwd start_default + 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 @@ -33,6 +36,8 @@ function copy_config_files_and_directories() logger "Missing SONiC configuration ${file_dir} ..." fi done + + sync } function check_system_warm_boot() @@ -60,13 +65,20 @@ if [ -f /tmp/pending_config_migration ]; then copy_config_files_and_directories $copy_list if [ x"${WARM_BOOT}" == x"true" ]; then echo "Warm reboot detected..." - elif [ "$enabled" = "true" ]; then + elif [ -r /etc/sonic/config_db.json ]; then + echo "Use config_db.json from old system..." + sonic-cfggen -j /etc/sonic/config_db.json --write-to-db + + if [[ -x /usr/bin/db_migrator.py ]]; then + # Migrate the DB to the latest schema version if needed + /usr/bin/db_migrator.py -o migrate + fi + elif [ -r /etc/sonic/minigraph.xml ]; then echo "Use minigraph.xml from old system..." reload_minigraph sonic-cfggen -d --print-data > /etc/sonic/config_db.json else - echo "Use config_db.json from old system..." - sonic-cfggen -j /etc/sonic/config_db.json --write-to-db + echo "Didn't found neither config_db.json nor minigraph.xml ..." fi rm -f /tmp/pending_config_migration sed -i "/enabled=/d" /etc/sonic/updategraph.conf diff --git a/files/image_config/warmboot-finalizer/finalize-warmboot.sh b/files/image_config/warmboot-finalizer/finalize-warmboot.sh index 00e4e1b7f3f9..32c9c8444cc3 100755 --- a/files/image_config/warmboot-finalizer/finalize-warmboot.sh +++ b/files/image_config/warmboot-finalizer/finalize-warmboot.sh @@ -68,6 +68,14 @@ function finalize_warm_boot() sudo config warm_restart disable } +function stop_control_plane_assistant() +{ + if [[ -x ${ASSISTANT_SCRIPT} ]]; then + debug "Tearing down control plane assistant ..." + ${ASSISTANT_SCRIPT} -m reset + fi +} + wait_for_database_service @@ -78,11 +86,6 @@ if [[ x"${WARM_BOOT}" != x"true" ]]; then exit 0 fi -# No need to wait for the reconciliation process. Database has been loaded -# and migrated. This is good enough to save a copy. -debug "Save in-memory database after warm reboot ..." -config save -y - list=${COMP_LIST} # Wait up to 5 minutes @@ -94,6 +97,12 @@ for i in `seq 60`; do sleep 5 done +stop_control_plane_assistant + +# Save DB after stopped control plane assistant to avoid extra entries +debug "Save in-memory database after warm reboot ..." +config save -y + if [[ -n "${list}" ]]; then debug "Some components didn't finish reconcile: ${list} ..." fi diff --git a/files/scripts/core_cleanup.py b/files/scripts/core_cleanup.py new file mode 100755 index 000000000000..67620b2397de --- /dev/null +++ b/files/scripts/core_cleanup.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python + +import syslog +import os + +from collections import defaultdict +from datetime import datetime + +SYSLOG_IDENTIFIER = 'core_cleanup.py' +CORE_FILE_DIR = os.path.basename(__file__) +MAX_CORE_FILES = 4 + +def log_info(msg): + syslog.openlog(SYSLOG_IDENTIFIER) + syslog.syslog(syslog.LOG_INFO, msg) + syslog.closelog() + +def log_error(msg): + syslog.openlog(SYSLOG_IDENTIFIER) + syslog.syslog(syslog.LOG_ERR, msg) + syslog.closelog() + +def main(): + if os.getuid() != 0: + log_error('Root required to clean up core files') + return + + log_info('Cleaning up core files') + core_files = [f for f in os.listdir(CORE_FILE_DIR) if os.path.isfile(os.path.join(CORE_FILE_DIR, f))] + + core_files_by_process = defaultdict(list) + for f in core_files: + process = f.split('.')[0] + curr_files = core_files_by_process[process] + curr_files.append(f) + + if len(curr_files) > MAX_CORE_FILES: + curr_files.sort(reverse = True, key = lambda x: datetime.utcfromtimestamp(int(x.split('.')[1]))) + oldest_core = curr_files[MAX_CORE_FILES] + log_info('Deleting {}'.format(oldest_core)) + try: + os.remove(os.path.join(CORE_FILE_DIR, oldest_core)) + except: + log_error('Unexpected error occured trying to delete {}'.format(oldest_core)) + core_files_by_process[process] = curr_files[0:MAX_CORE_FILES] + + log_info('Finished cleaning up core files') + +if __name__ == '__main__': + main() + diff --git a/files/scripts/supervisor-proc-exit-listener b/files/scripts/supervisor-proc-exit-listener index 6bc62fc400c8..8d1735cd2b0c 100755 --- a/files/scripts/supervisor-proc-exit-listener +++ b/files/scripts/supervisor-proc-exit-listener @@ -33,9 +33,10 @@ def main(): expected = int(payload_headers['expected']) processname = payload_headers['processname'] + groupname = payload_headers['groupname'] # If a critical process exited unexpectedly, terminate supervisor - if expected == 0 and processname in critical_processes: + if expected == 0 and processname in critical_processes or groupname in critical_processes: MSG_FORMAT_STR = "Process {} exited unxepectedly. Terminating supervisor..." msg = MSG_FORMAT_STR.format(payload_headers['processname']) syslog.syslog(syslog.LOG_INFO, msg) diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index 7b6ae6b5dbfe..f54c13697753 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -2,7 +2,7 @@ SERVICE="swss" PEER="syncd" -DEPENDENT="teamd" +DEPENDENT="teamd radv" DEBUGLOG="/tmp/swss-syncd-debug.log" LOCKFILE="/tmp/swss-syncd-lock" @@ -85,7 +85,9 @@ start_peer_and_dependent_services() { if [[ x"$WARM_BOOT" != x"true" ]]; then /bin/systemctl start ${PEER} for dep in ${DEPENDENT}; do - /bin/systemctl start ${dep} + # Here we call `systemctl restart` on each dependent service instead of `systemctl start` to + # ensure the services actually get stopped and started in case they were not previously stopped. + /bin/systemctl restart ${dep} done fi } @@ -131,7 +133,22 @@ start() { wait() { start_peer_and_dependent_services - /usr/bin/${SERVICE}.sh wait + + # Allow some time for peer container to start + # NOTE: This assumes Docker containers share the same names as their + # corresponding services + for SECS in {1..60}; do + RUNNING=$(docker inspect -f '{{.State.Running}}' ${PEER}) + if [[ x"$RUNNING" == x"true" ]]; then + break + else + sleep 1 + fi + done + + # NOTE: This assumes Docker containers share the same names as their + # corresponding services + /usr/bin/docker-wait-any ${SERVICE} ${PEER} } stop() { diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index d4536b4d8b94..2b7c76263d8a 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -64,7 +64,7 @@ function getBootType() TYPE='fastfast' ;; *SONIC_BOOT_TYPE=fast*|*fast-reboot*) - TYPE='fast' + TYPE=$(awk '{ if ($1 <= 180) print "fast"; else print "cold" }' /proc/uptime) ;; *) TYPE='cold' @@ -104,11 +104,9 @@ start() { if [[ x"$WARM_BOOT" != x"true" ]]; then if [[ x"$(/bin/systemctl is-active pmon)" == x"active" ]]; then /bin/systemctl stop pmon - /usr/bin/hw-management.sh chipdown - /bin/systemctl restart pmon - else - /usr/bin/hw-management.sh chipdown + debug "pmon is active while syncd starting, stop it first" fi + /usr/bin/hw-management.sh chipdown fi if [[ x"$BOOT_TYPE" == x"fast" ]]; then @@ -134,6 +132,11 @@ start() { } wait() { + if [[ x"$sonic_asic_platform" == x"mellanox" ]]; then + debug "Starting pmon service..." + /bin/systemctl start pmon + debug "Started pmon service" + fi /usr/bin/${SERVICE}.sh wait } @@ -150,6 +153,12 @@ stop() { TYPE=cold fi + if [[ x$sonic_asic_platform == x"mellanox" ]] && [[ x$TYPE == x"cold" ]]; then + debug "Stopping pmon service ahead of syncd..." + /bin/systemctl stop pmon + debug "Stopped pmon service" + fi + if [[ x$sonic_asic_platform != x"mellanox" ]] || [[ x$TYPE != x"cold" ]]; then debug "${TYPE} shutdown syncd process ..." /usr/bin/docker exec -i syncd /usr/bin/syncd_request_shutdown --${TYPE} diff --git a/installer/armhf/install.sh b/installer/armhf/install.sh index 6398436ebb6e..bfd7eeef9e41 100755 --- a/installer/armhf/install.sh +++ b/installer/armhf/install.sh @@ -1,9 +1,7 @@ #!/bin/sh -# Copyright (C) 2014,2015 Curt Brune -# Copyright (C) 2015 david_yang +# Copyright (C) Marvell Inc # -# SPDX-License-Identifier: GPL-2.0 set -e @@ -31,99 +29,22 @@ fi echo "Installer: platform: $platform" +# install_uimage will be overriden from platform.conf as it is non generic install_uimage() { echo "Copying uImage to NOR flash:" flashcp -v demo-${platform}.itb $mtd_dev } +# hw_load will be overriden from platform.conf as it is non generic hw_load() { echo "cp.b $img_start \$loadaddr $img_sz" } . ./platform.conf -#install_uimage - -#hw_load_str="$(hw_load)" - -echo "Copying uImage to NAND flash:" -# global mount defines -demo_dev=ubi0 -mtd_dev=/dev/$(cat /proc/mtd | grep "SONIC" | grep -o "mtd[0-9]") -mtd_num=$(echo $mtd_dev | grep -o "[0-9]") -demo_mount=/tmp -onie_dev=$(blkid | grep ONIE-BOOT | head -n 1 | awk '{print $1}' | sed -e 's/:.*$//') - -echo "Format mtd partition '$mtd_dev'" -ubiformat $mtd_dev -#attaches MTD devices (which describe raw flash) to UBI and creates corresponding UBI devices; ('-m 2' --> mtd2) -echo "ubiattach mtd '$mtd_num'" -ubiattach /dev/ubi_ctrl -m $mtd_num -#creates UBI volumes on UBI devices -ubimkvol /dev/$demo_dev -N $demo_dev -s 3700MiB - -demo_mount=$(mktemp -d) -mkdir -p $demo_mount -echo "Mounting ubifs partition" -mount -t ubifs /dev/ubi0_0 $demo_mount -echo "Mounting $demo_dev on $demo_mount..." -echo "sonic extract image starts ..." -# Decompress the file for the file system directly to the partition -unzip -o $ONIE_INSTALLER_PAYLOAD -x "$FILESYSTEM_DOCKERFS" -d $demo_mount/ -cd $demo_mount -if [ -f fs.cpio ] -then - cpio -id < fs.cpio - rm fs.cpio -elif [ -f fs.squashfs ] -then - unsquashfs -f -d $demo_mount fs.squashfs - rm -f fs.squashfs -fi -cd - -TAR_EXTRA_OPTION="--numeric-owner" -mkdir -p $demo_mount/var/lib/$DOCKERFS_DIR -unzip -op $ONIE_INSTALLER_PAYLOAD "$FILESYSTEM_DOCKERFS" | tar -xpz $TAR_EXTRA_OPTION -f - -C $demo_mount/var/lib/$DOCKERFS_DIR - -echo "unmounting nand partition" -umount $demo_mount - -echo "Updating U-Boot environment variables" -#global uboot enviroment settings -FW_ENV='/dev/mtd0 \t\t 0x00500000 \t 0x80000 \t 0x100000 \t 8' - -kernel_addr=0x1100000 -fdt_addr=0x1000000 - -image_name="/boot/zImage" -fdt_name="/boot/armada-385-ET6448M_4G_Nand.dtb" - -#BOOTARGS='setenv bootargs root='$demo_dev' rw rootwait ubi.mtd='$mtd_num' rootfstype=ubifs debug panic=1 ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${netdev}:off console=ttyS0,115200 ${othbootargs} ${mtdparts}' -BOOTARGS='setenv bootargs root='$demo_dev' rw rootwait ubi.mtd='$mtd_num' rootfstype=ubifs panic=1 console=ttyS0,115200 ${othbootargs} ${mtdparts}' -UBI_LOAD='run ubi_sonic_boot_mount_ubi; ubifsload $kernel_addr $image_name;ubifsload $fdt_addr $fdt_name' -UBIBOOTCMD='run ubi_sonic_boot_bootargs; run ubi_sonic_boot_load; bootz $kernel_addr - $fdt_addr' - - -echo -e $FW_ENV > /etc/fw_env.config - -fw_setenv -f image_name $image_name > /dev/null -fw_setenv -f fdt_name $fdt_name > /dev/null -fw_setenv -f kernel_addr $kernel_addr > /dev/null -fw_setenv -f fdt_addr $fdt_addr > /dev/null - -#make sure ubi number (0) and ubi volume name (ubi0) are set correctly in bootargs_root: -#For example, the below command creates an 3000MiB volume on UBI device 0: -#setenv bootargs_root root=ubi0:ubi0 rw ubi.mtd=2 rootfstype=ubifs - -fw_setenv -f mtdids 'nand0=armada-nand' > /dev/null -fw_setenv -f mtdparts 'mtdparts=armada-nand:10m(U-Boot)ro,208m@10m(ONIE),-(SONIC)' > /dev/null -fw_setenv -f ubi_sonic_boot_mount_ubi 'ubi part SONIC; ubifsmount ubi0' > /dev/null - -fw_setenv -f ubi_sonic_boot_bootargs $BOOTARGS > /dev/null -fw_setenv -f ubi_sonic_boot_load $UBI_LOAD > /dev/null -fw_setenv -f ubi_sonic_boot $UBIBOOTCMD > /dev/null -fw_setenv -f bootcmd 'usb start; run ubi_sonic_boot' > /dev/null +install_uimage +hw_load_str="$(hw_load)" cd / diff --git a/onie-image.conf b/onie-image.conf index db99c867de04..2ca0a68484e2 100644 --- a/onie-image.conf +++ b/onie-image.conf @@ -25,7 +25,7 @@ FILESYSTEM_DOCKERFS=dockerfs.tar.gz DOCKERFS_DIR=docker ## docker ramfs disk space -DOCKER_RAMFS_SIZE=800M +DOCKER_RAMFS_SIZE=900M ## Output file name for onie installer OUTPUT_ONIE_IMAGE=target/sonic-$TARGET_MACHINE.bin diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 837f86c335e7..854026b52949 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,5 +1,5 @@ -BFN_PLATFORM = bfnplatform_8_9_1.x.ab1e16f.deb -$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_8_9_1/bfnplatform_8_9_1.x.ab1e16f.deb" +BFN_PLATFORM = bfnplatform_20191115_deb9.deb +$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/bfnplatform_20191115_deb9.deb" -SONIC_ONLINE_DEBS += $(BFN_PLATFORM) # $(BFN_SAI_DEV) +SONIC_ONLINE_DEBS += $(BFN_PLATFORM) $(BFN_SAI_DEV)_DEPENDS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index e3253348e720..6f413d50c11e 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,5 +1,5 @@ -BFN_SAI = bfnsdk_8_9_1.x.ab1e16f.deb -$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_8_9_1/bfnsdk_8_9_1.x.ab1e16f.deb" +BFN_SAI = bfnsdk_20191115_deb9.deb +$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/bfnsdk_20191115_deb9.deb" -SONIC_ONLINE_DEBS += $(BFN_SAI) # $(BFN_SAI_DEV) +SONIC_ONLINE_DEBS += $(BFN_SAI) $(BFN_SAI_DEV)_DEPENDS += $(BFN_SAI) diff --git a/platform/barefoot/docker-syncd-bfn-rpc.mk b/platform/barefoot/docker-syncd-bfn-rpc.mk index 4fbe4eb1721c..d9cb0b5d6172 100644 --- a/platform/barefoot/docker-syncd-bfn-rpc.mk +++ b/platform/barefoot/docker-syncd-bfn-rpc.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_BFN_RPC = docker-syncd-bfn-rpc.gz $(DOCKER_SYNCD_BFN_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-bfn-rpc $(DOCKER_SYNCD_BFN_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_BFN_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_BFN_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 b/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 index 73a12b8a05cc..c12c36b1260b 100755 --- a/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 +++ b/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 @@ -29,6 +29,8 @@ debs/{{ deb }}{{' '}} COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y diff --git a/platform/barefoot/docker-syncd-bfn/critical_processes b/platform/barefoot/docker-syncd-bfn/critical_processes new file mode 100644 index 000000000000..6082f242b872 --- /dev/null +++ b/platform/barefoot/docker-syncd-bfn/critical_processes @@ -0,0 +1 @@ +syncd diff --git a/platform/barefoot/one-image.mk b/platform/barefoot/one-image.mk index 36823baa8781..0147b62d00a1 100644 --- a/platform/barefoot/one-image.mk +++ b/platform/barefoot/one-image.mk @@ -7,6 +7,7 @@ $(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_MODULE) $(PYTHON_THRIFT) $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_MONTARA_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_NEWPORT_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(WNC_OSW1800_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9180_32X_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9280_64X_PLATFORM_MODULE) diff --git a/platform/barefoot/platform-modules-bfn-newport.mk b/platform/barefoot/platform-modules-bfn-newport.mk new file mode 100644 index 000000000000..ff251ed1ddd7 --- /dev/null +++ b/platform/barefoot/platform-modules-bfn-newport.mk @@ -0,0 +1,13 @@ +# BFN Platform modules + +BFN_NEWPORT_PLATFORM_MODULE_VERSION = 1.0 + +export BFN_NEWPORT_PLATFORM_MODULE_VERSION + +BFN_NEWPORT_PLATFORM_MODULE = sonic-platform-modules-bfn-newport_$(BFN_NEWPORT_PLATFORM_MODULE_VERSION)_amd64.deb +$(BFN_NEWPORT_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-bfn-newport +$(BFN_NEWPORT_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(BFN_NEWPORT_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as9516bf_32d-r0 +SONIC_DPKG_DEBS += $(BFN_NEWPORT_PLATFORM_MODULE) + +SONIC_STRETCH_DEBS += $(BFN_NEWPORT_PLATFORM_MODULE) diff --git a/platform/barefoot/rules.mk b/platform/barefoot/rules.mk index ea718d10fc96..8a218b3ff169 100644 --- a/platform/barefoot/rules.mk +++ b/platform/barefoot/rules.mk @@ -1,6 +1,7 @@ include $(PLATFORM_PATH)/platform-modules-arista.mk include $(PLATFORM_PATH)/platform-modules-bfn.mk include $(PLATFORM_PATH)/platform-modules-bfn-montara.mk +include $(PLATFORM_PATH)/platform-modules-bfn-newport.mk include $(PLATFORM_PATH)/platform-modules-wnc-osw1800.mk include $(PLATFORM_PATH)/platform-modules-ingrasys.mk include $(PLATFORM_PATH)/bfn-sai.mk diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index 530f9707a2c3..10750325b6cf 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 530f9707a2c3d06bb50a9b60b24a4bf4eb8a9735 +Subproject commit 10750325b6cfc7a1dc1a8b0734008bde1bb3ac06 diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/LICENSE b/platform/barefoot/sonic-platform-modules-bfn-newport/LICENSE new file mode 100644 index 000000000000..676cdeec726b --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/LICENSE @@ -0,0 +1,15 @@ +Copyright (C) 2016 Microsoft, Inc + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/MAINTAINERS b/platform/barefoot/sonic-platform-modules-bfn-newport/MAINTAINERS new file mode 100644 index 000000000000..85aa0cd77d72 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/MAINTAINERS @@ -0,0 +1,3 @@ +# This file describes the maintainers for sonic-platform-modules-bfn-newport +# See the SONiC project governance document for more information +Mailinglist = sonicproject@googlegroups.com diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/README.md b/platform/barefoot/sonic-platform-modules-bfn-newport/README.md new file mode 100644 index 000000000000..028adef715f3 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/README.md @@ -0,0 +1,2 @@ +# sonic-platform-modules-bfn-newport +Device drivers for support of BFN platform for the SONiC project diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/configs/network/interfaces.d/usb0 b/platform/barefoot/sonic-platform-modules-bfn-newport/configs/network/interfaces.d/usb0 new file mode 100644 index 000000000000..f1dd054cc6f6 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/configs/network/interfaces.d/usb0 @@ -0,0 +1,5 @@ +# BMC interface +auto usb0 +allow-hotplug usb0 +iface usb0 inet6 +up ifconfig usb0 txqueuelen 64 diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/changelog b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/changelog new file mode 100644 index 000000000000..98ecad42ac90 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/changelog @@ -0,0 +1,5 @@ +sonic-platform-modules-bfn-newport (1.0) unstable; urgency=low + + * Initial release + + -- Support Mon, 27 Sep 2019 18:00:00 -0800 diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/compat b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/compat new file mode 100644 index 000000000000..45a4fb75db86 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/compat @@ -0,0 +1 @@ +8 diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control new file mode 100644 index 000000000000..edbc5b890c58 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control @@ -0,0 +1,12 @@ +Source: sonic-platform-modules-bfn-newport +Section: main +Priority: extra +Maintainer: Support +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: sonic-platform-modules-bfn-newport +Architecture: amd64 +Depends: linux-image-4.9.0-9-2-amd64 +Description: kernel module for bfn platform fpga and scripts for the devices such as fan, led, sfp + diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/copyright b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/copyright new file mode 100644 index 000000000000..ade42b7aa75a --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/copyright @@ -0,0 +1,15 @@ +Provides linux kernel driver for BF PCIe devices + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You 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/barefoot/sonic-platform-modules-bfn-newport/debian/rules b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules new file mode 100755 index 000000000000..951069a6016a --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/rules @@ -0,0 +1,35 @@ +#!/usr/bin/make -f + +export INSTALL_MOD_DIR:=extra + +PACKAGE_NAME := sonic-platform-modules-bfn-newport +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MODULE_SRC := $(shell pwd)/modules +SCRIPT_SRC := $(shell pwd)/scripts +CONFIGS_SRC := $(shell pwd)/configs + +%: + dh $@ + +override_dh_auto_build: + make -C $(KERNEL_SRC)/build M=$(MODULE_SRC) + +override_dh_auto_install: + dh_installdirs -p$(PACKAGE_NAME) $(KERNEL_SRC)/$(INSTALL_MOD_DIR) + cp $(MODULE_SRC)/*.ko debian/$(PACKAGE_NAME)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) + dh_installdirs -p$(PACKAGE_NAME) usr/local/bin + cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_NAME)/usr/local/bin + dh_installdirs -p$(PACKAGE_NAME) etc/network/interfaces.d/ + cp -r $(CONFIGS_SRC)/network/interfaces.d/* debian/$(PACKAGE_NAME)/etc/network/interfaces.d/ + +override_dh_usrlocal: + +override_dh_pysupport: + +override_dh_clean: + dh_clean + rm -f $(MODULE_SRC)/*.o $(MODULE_SRC)/*.ko $(MODULE_SRC)/*.mod.c $(MODULE_SRC)/.*.cmd + rm -f $(MODULE_SRC)/Module.markers $(MODULE_SRC)/Module.symvers $(MODULE_SRC)/modules.order + rm -rf $(MODULE_SRC)/.tmp_versions + diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/Makefile b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/Makefile new file mode 100644 index 000000000000..732ffb1f3f6c --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/Makefile @@ -0,0 +1,2 @@ +obj-m := bf_fpga.o +bf_fpga-y := bf_fpga_main.o bf_fpga_ioctl.o bf_fpga_sysfs.o i2c/bf_fpga_i2c.o i2c/bf_fpga_i2c_ctrl.o i2c/bf_fpga_i2c_porting.o diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_ioctl.c b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_ioctl.c new file mode 100644 index 000000000000..b0792556caf6 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_ioctl.c @@ -0,0 +1,196 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 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 + +*******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include "bf_fpga_priv.h" +#include "bf_fpga_ioctl.h" +#include "i2c/bf_fpga_i2c.h" + +int bf_fpga_ioctl(struct bf_pci_dev *bfdev, + unsigned int cmd, + unsigned long arg) { + void *addr = (void __user *)arg; + int ret = -1; + + if (!bfdev || !addr) { + return -EFAULT; + } + + switch (cmd) { + case BF_FPGA_IOCTL_I2C_CTL: { + bf_fpga_i2c_ctl_t i2c_ctl; + bool busy; + + if (copy_from_user(&i2c_ctl, addr, sizeof(bf_fpga_i2c_ctl_t))) { + return -EFAULT; + } + switch (i2c_ctl.control_type) { + case BF_FPGA_I2C_START: + ret = fpga_i2c_start(i2c_ctl.inst_hndl.bus_id); + break; + case BF_FPGA_I2C_STOP: + ret = fpga_i2c_stop(i2c_ctl.inst_hndl.bus_id); + break; + case BF_FPGA_I2C_RESET: + ret = fpga_i2c_reset(i2c_ctl.inst_hndl.bus_id); + break; + case BF_FPGA_I2C_BUSY: + ret = fpga_i2c_is_busy(i2c_ctl.inst_hndl.bus_id, &busy); + if (ret == 0) { + if (copy_to_user(&(((bf_fpga_i2c_ctl_t *)addr)->is_busy), + &busy, + sizeof(busy))) { + return -EFAULT; + } + } + break; + case BF_FPGA_I2C_INST_EN: + ret = fpga_i2c_inst_en( + i2c_ctl.inst_hndl.bus_id, i2c_ctl.inst_hndl.inst_id, true); + break; + case BF_FPGA_I2C_INST_DIS: + ret = fpga_i2c_inst_en( + i2c_ctl.inst_hndl.bus_id, i2c_ctl.inst_hndl.inst_id, false); + break; + case BF_FPGA_I2C_INST_PMT: + break; + case BF_FPGA_I2C_INST_STOP_ON_ERR: + break; + case BF_FPGA_I2C_INST_INT_EN: + break; + default: + break; + } + break; + } + case BF_FPGA_IOCTL_I2C_SET_CLK: { + bf_fpga_i2c_set_clk_t i2c_clk; + if (copy_from_user(&i2c_clk, addr, sizeof(bf_fpga_i2c_set_clk_t))) { + return -EFAULT; + } + ret = fpga_i2c_set_clk(i2c_clk.bus_id, i2c_clk.clock_div); + break; + } + case BF_FPGA_IOCTL_I2C_ONETIME: { + bf_fpga_i2c_t i2c_op; + int i; + + if (copy_from_user(&i2c_op, addr, sizeof(bf_fpga_i2c_t))) { + return -EFAULT; + } + ret = fpga_i2c_oneshot(&i2c_op); + if (ret == 0) { + /* copy read data to user area */ + for (i = 0; i < i2c_op.num_i2c; i++) { + if (i2c_op.i2c_inst[i].rd_cnt) { + if (copy_to_user(&(((bf_fpga_i2c_t *)addr)->i2c_inst[i].rd_buf), + &i2c_op.i2c_inst[i].rd_buf, + i2c_op.i2c_inst[i].rd_cnt)) { + return -EFAULT; + } + } + } + } else { + printk(KERN_ERR + "fpga i2c ioctl oneshot bus %d error %d i2c_addr 0x%hhx:0x%hhx " + "i2c_status 0x%hhx:0x%hhx\n", + i2c_op.inst_hndl.bus_id, + ret, + i2c_op.i2c_inst[0].i2c_addr, + i2c_op.i2c_inst[1].i2c_addr, + i2c_op.i2c_inst[0].status, + i2c_op.i2c_inst[1].status); + } + break; + } + case BF_FPGA_IOCTL_I2C_ADD_PR: { + bf_fpga_i2c_t i2c_op; + if (copy_from_user(&i2c_op, addr, sizeof(bf_fpga_i2c_t))) { + return -EFAULT; + } + ret = fpga_i2c_pr_add(&i2c_op); + if (ret == 0) { + /* copy read data to user area */ + if (copy_to_user(&((bf_fpga_i2c_t *)addr)->inst_hndl.inst_id, + &i2c_op.inst_hndl.inst_id, + sizeof(i2c_op.inst_hndl.inst_id))) { + return -EFAULT; + } + } else { + printk(KERN_ERR "fpga i2c ioctl add-pr error %d on bus %d\n", + ret, + i2c_op.inst_hndl.bus_id); + } + break; + } + case BF_FPGA_IOCTL_I2C_DEL_PR: { + bf_fpga_i2c_t i2c_op; + if (copy_from_user(&i2c_op, addr, sizeof(bf_fpga_i2c_t))) { + return -EFAULT; + } + ret = fpga_i2c_del(&i2c_op); + if (ret != 0) { + printk(KERN_ERR "fpga i2c ioctl del-pr error %d on bus %d\n", + ret, + i2c_op.inst_hndl.bus_id); + } + break; + } + case BF_FPGA_IOCTL_I2C_RD_DATA: { + bf_fpga_i2c_rd_data_t i2c_rd_data; + /* get user supplied offset and rd_cnt */ + if (copy_from_user( + &i2c_rd_data, addr, offsetof(bf_fpga_i2c_rd_data_t, rd_buf))) { + return -EFAULT; + } + ret = fpga_i2c_data_read(i2c_rd_data.inst_hndl.bus_id, + i2c_rd_data.inst_hndl.inst_id, + i2c_rd_data.offset, + i2c_rd_data.rd_cnt, + i2c_rd_data.rd_buf); + if (ret == 0) { + if (copy_to_user(&(((bf_fpga_i2c_rd_data_t *)addr)->rd_buf), + &i2c_rd_data.rd_buf, + i2c_rd_data.rd_cnt)) { + return -EFAULT; + } + } else { + printk(KERN_ERR "fpga i2c ioctl rd-data error %d on bus %d inst %d\n", + ret, + i2c_rd_data.inst_hndl.bus_id, + i2c_rd_data.inst_hndl.inst_id); + } + break; + } + default: + return -EINVAL; + } + return ret; +} diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_ioctl.h b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_ioctl.h new file mode 100644 index 000000000000..4c5eb7bf0386 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_ioctl.h @@ -0,0 +1,131 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 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_FPGA_IOCTL_H_ +#define _BF_FPGA_IOCTL_H_ + +#ifdef __KERNEL__ +#include +#else +#include + +#endif /* __KERNEL__ */ + +#define BF_FPGA_IOC_MAGIC 'f' +#define BF_I2C_FPGA_NUM_CTRL 34 +#define BF_FPGA_MAX_I2C_RD_DATA 128 +#define BF_FPGA_MAX_I2C_WR_DATA 129 + +/* i2c control types */ +#define BF_FPGA_I2C_START 1 +#define BF_FPGA_I2C_STOP 2 +#define BF_FPGA_I2C_BUSY 3 +#define BF_FPGA_I2C_INST_EN 4 +#define BF_FPGA_I2C_INST_DIS 5 +#define BF_FPGA_I2C_INST_PMT 6 +#define BF_FPGA_I2C_INST_STOP_ON_ERR 7 +#define BF_FPGA_I2C_INST_INT_EN 8 +#define BF_FPGA_I2C_RESET 9 + +/* i2c operation types */ +#define BF_FPGA_I2C_NOP 0 +#define BF_FPGA_I2C_WRITE \ + 1 /* / ..[max 129 bytes] */ +#define BF_FPGA_I2C_READ \ + 2 /* / ..[max 128 bytes] */ +#define BF_FPGA_I2C_ADDR_READ \ + 3 /* / / \ + */ + +#define FPGA_I2c_ONESHOT_BEGIN_INDEX 0 +#define FPGA_I2C_ONESHOT_NUM_INST 15 +#define FPGA_I2C_PERIODIC_BEGIN_INDEX (FPGA_I2C_ONESHOT_NUM_INST) +#define FPGA_I2C_PERIODIC_NUM_INST 16 +#define FPGA_I2C_NUM_INST \ + (FPGA_I2C_ONESHOT_NUM_INST + FPGA_I2C_PERIODIC_NUM_INST) +/* maximum i2c instructions that can be handled in one system call */ +#define BF_FPGA_I2C_MAX_NUM_INST 3 + +typedef struct bf_fpga_i2c_set_clk_s { + /* 0:100k, 1:400k, 2:1M, or: 125e6//3 */ + int clock_div; /* clock divider */ + unsigned char bus_id; /* controller index */ +} bf_fpga_i2c_set_clk_t; + +typedef struct bf_fpga_inst_hndl_s { + int inst_id; /* instruction index within the controller memory space */ + unsigned char bus_id; /* controller index */ + unsigned char status; +} bf_fpga_inst_hndl_t; + +typedef struct bf_fpga_i2c_inst_s { + bool preemt; + bool en; + unsigned char i2c_addr; /* i2c device address in 7 bit format */ + unsigned char i2c_type; /* type of i2c cycle */ + unsigned char delay; /* delay in TBD - microseconds before i2c transaction */ + unsigned char ctrl; + unsigned char wr_cnt; /* number of bytes to write (after i2c address) */ + unsigned char rd_cnt; /* number of bytes to read */ + union { + unsigned char + wr_buf[BF_FPGA_MAX_I2C_WR_DATA]; /* write data source buffer */ + unsigned char rd_buf[BF_FPGA_MAX_I2C_RD_DATA]; /* read data dest buffer */ + }; + unsigned char status; + unsigned char retry_cnt; /* if fpga maintains retry count */ + unsigned char mux; /* if fpga maintains internal MUX */ +} bf_fpga_i2c_inst_t; + +typedef struct bf_fpga_i2c_s { + unsigned char num_i2c; /* number of i2c operations */ + unsigned char one_time; /* one time or periodic */ + bf_fpga_inst_hndl_t inst_hndl; + bf_fpga_i2c_inst_t i2c_inst[BF_FPGA_I2C_MAX_NUM_INST]; +} bf_fpga_i2c_t; + +typedef struct bf_fpga_i2c_rd_data_s { + bf_fpga_inst_hndl_t inst_hndl; + unsigned char offset; + unsigned char rd_cnt; + unsigned char rd_buf[BF_FPGA_MAX_I2C_RD_DATA]; +} bf_fpga_i2c_rd_data_t; + +typedef struct bf_fpga_i2c_ctl_s { + bf_fpga_inst_hndl_t inst_hndl; + unsigned char control_type; /* start, stop, reset, enable, disable or busy */ + bool is_busy; +} bf_fpga_i2c_ctl_t; + +#define BF_FPGA_IOCTL_I2C_CTL _IOWR(BF_FPGA_IOC_MAGIC, 0, bf_fpga_i2c_ctl_t) +#define BF_FPGA_IOCTL_I2C_ONETIME _IOWR(BF_FPGA_IOC_MAGIC, 1, bf_fpga_i2c_t) +#define BF_FPGA_IOCTL_I2C_ADD_PR _IOWR(BF_FPGA_IOC_MAGIC, 2, bf_fpga_i2c_t) +#define BF_FPGA_IOCTL_I2C_DEL_PR _IOWR(BF_FPGA_IOC_MAGIC, 3, bf_fpga_i2c_t) +#define BF_FPGA_IOCTL_I2C_RD_DATA \ + _IOWR(BF_FPGA_IOC_MAGIC, 4, bf_fpga_i2c_rd_data_t) +#define BF_FPGA_IOCTL_I2C_SET_CLK \ + _IOW(BF_FPGA_IOC_MAGIC, 5, bf_fpga_i2c_set_clk_t) + +#endif /* _BF_FPGA_IOCTL_H_ */ diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_main.c b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_main.c new file mode 100644 index 000000000000..563cc5120df1 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_main.c @@ -0,0 +1,1294 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 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 + +*******************************************************************************/ +/* bf_fpga kernel module + * + * This is kernel mode driver for BF FPGA chip. + * Provides user space mmap service and user space "wait for interrupt", + * "enable interrupt" and i2c services + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "bf_fpga_ioctl.h" + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) +#include +#else +#include +#endif +#include +#include +#include +#include "bf_fpga_priv.h" +#include "i2c/bf_fpga_i2c_reg.h" +#include "i2c/bf_fpga_i2c.h" + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0) +//#error unsupported linux kernel version +#endif + +/* 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 + +/* 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 cdev *bf_cdev; + struct fasync_struct *async_queue; +}; + +static int bf_major; +static int bf_minor[BF_FPGA_MAX_DEVICE_CNT] = {0}; +static struct class *bf_class = NULL; +static char *intr_mode = NULL; + +static enum bf_intr_mode bf_intr_mode_default = BF_INTR_MODE_NONE; +static spinlock_t bf_nonisr_lock; + +/* dev->minor should index into this array */ +static struct bf_global bf_global[BF_FPGA_MAX_DEVICE_CNT]; + +static void bf_add_listener(struct bf_pci_dev *bfdev, + struct bf_listener *listener) { + struct bf_listener **cur_listener = &bfdev->listener_head; + + if (!listener) { + return; + } + spin_lock(&bf_nonisr_lock); + + while (*cur_listener) { + cur_listener = &((*cur_listener)->next); + } + *cur_listener = listener; + listener->next = NULL; + + spin_unlock(&bf_nonisr_lock); +} + +static void bf_remove_listener(struct bf_pci_dev *bfdev, + 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() + */ + if (!bfdev || !listener) { + return; + } + spin_lock(&bf_nonisr_lock); + + if (*cur_listener == listener) { + *cur_listener = listener->next; + } else { + while (*cur_listener) { + if ((*cur_listener)->next == listener) { + (*cur_listener)->next = listener->next; + break; + } + cur_listener = &((*cur_listener)->next); + } + listener->next = NULL; + } + + spin_unlock(&bf_nonisr_lock); +} + +/* a pool of minor numbers is maintained */ +/* return the first available minor number */ +static int bf_get_next_minor_no(int *minor) { + int i; + + spin_lock(&bf_nonisr_lock); + for (i = 0; i < BF_FPGA_MAX_DEVICE_CNT; i++) { + if (bf_minor[i] == 0) { + *minor = i; + bf_minor[i] = 1; /* mark it as taken */ + spin_unlock(&bf_nonisr_lock); + return 0; + } + } + *minor = -1; + spin_unlock(&bf_nonisr_lock); + return -1; +} + +/* return a minor number back to the pool for recycling */ +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 */ + } else { + bf_minor[minor] = 0; /* mark it as available */ + err = 0; + } + spin_unlock(&bf_nonisr_lock); + 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); +} + +/* + * 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; + } +} + +/** + * irqcontrol can be used to disable/enable interrupt from user space processes. + * + * @param bf_dev + * pointer to bf_pci_dev + * @param irq_state + * state value. 1 to enable interrupt, 0 to disable interrupt. + * + * @return + * - 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); +#else + for_each_pci_msi_entry(desc, pdev) bf_msix_mask_irq(desc, irq_state); +#endif + } + pci_cfg_access_unlock(pdev); + + return 0; +} + +/** + * 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. + */ + 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; +} + +/* Unmap previously ioremap'd resources */ +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); + } + } +} + +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) { + 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) { + atomic_inc(&(bfdev->info.event[vect_off])); + } + return ret; +} + +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) { + 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])) { + return POLLIN | POLLRDNORM; + } + } + return 0; +} + +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) { + 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, +#endif +}; + +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) { + return -EINVAL; + } + + mem = bfdev->info.mem + bar; + + if (mem->addr & ~PAGE_MASK) { + return -ENODEV; + } + 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); + + /* + * We cannot use the vm_iomap_memory() helper here, + * because vma->vm_pgoff is the map index we looked + * up above in bf_find_mem_index(), rather than an + * actual page offset into the mmap. + * + * 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); +} + +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) { + return -EINVAL; + } + + vma->vm_private_data = bfdev; + + bar = bf_find_mem_index(vma); + 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) { + return -EINVAL; + } + + return bf_mmap_physical(vma); +} + +static int bf_fasync(int fd, struct file *filep, int mode) { + int minor; + + if (!filep->private_data) { + return (-EINVAL); + } + minor = ((struct bf_listener *)filep->private_data)->minor; + if (minor >= BF_FPGA_MAX_DEVICE_CNT) { + return (-EINVAL); + } + if (mode == 0 && &bf_global[minor].async_queue == NULL) { + return 0; /* nothing to do */ + } + return (fasync_helper(fd, filep, mode, &bf_global[minor].async_queue)); +} + +static int bf_open(struct inode *inode, struct file *filep) { + struct bf_pci_dev *bfdev; + struct bf_listener *listener; + int i; + + bfdev = bf_global[iminor(inode)].bfdev; + listener = kmalloc(sizeof(*listener), GFP_KERNEL); + if (listener) { + listener->bfdev = bfdev; + listener->minor = bfdev->info.minor; + listener->next = NULL; + bf_add_listener(bfdev, listener); + 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); + } +} + +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 */ + if (listener->bfdev) { + bf_remove_listener(listener->bfdev, listener); + } + kfree(listener); + return 0; +} + +/* 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) { + 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 */ + 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) { + 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) { + return -EINVAL; + } + count = sizeof(s32) * BF_MSIX_ENTRY_CNT; + } else if (bfdev->mode == BF_INTR_MODE_MSI) { + if (count < sizeof(s32) * BF_MSI_ENTRY_CNT) { + return -EINVAL; + } + count = sizeof(s32) * BF_MSI_ENTRY_CNT; + } else { + if (count < sizeof(s32)) { + return -EINVAL; + } + count = sizeof(s32); + } + + do { + set_current_state(TASK_INTERRUPTIBLE); + + 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; + cnt_match[i] = 1; + } else { + event_count[i] = 0; + cnt_match[i] = 0; + } + } + if (mismatch_found) { + __set_current_state(TASK_RUNNING); + if (copy_to_user(buf, &event_count, count)) { + retval = -EFAULT; + } 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]; + } + } + retval = count; + } + break; + } + + if (filep->f_flags & O_NONBLOCK) { + retval = -EAGAIN; + break; + } + + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } + schedule(); + } while (1); + + __set_current_state(TASK_RUNNING); + + return retval; +} + +/* 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) { + 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) { + return -EIO; + } + + if (count != sizeof(s32)) { + return -EINVAL; + } + + if (copy_from_user(&int_en, buf, count)) { + return -EFAULT; + } + + /* clear pci_error_state */ + bfdev->info.pci_error_state = 0; + + ret = bf_pci_irqcontrol(bfdev, int_en); + + return ret ? ret : sizeof(s32); +} + +static long bf_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { + struct bf_listener *listener = filep->private_data; + struct bf_pci_dev *bfdev = listener->bfdev; + + return (bf_fpga_ioctl(bfdev, cmd, 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, +}; + +static int bf_major_init(struct bf_pci_dev *bfdev, int minor) { + struct cdev *cdev; + static const char name[] = "bf_fpga"; + dev_t bf_dev = 0; + int result; + + result = alloc_chrdev_region(&bf_dev, 0, BF_FPGA_MAX_DEVICE_CNT, name); + if (result) { + return result; + } + + result = -ENOMEM; + cdev = cdev_alloc(); + if (!cdev) { + goto fail_dev_add; + } + cdev->ops = &bf_fops; + cdev->owner = THIS_MODULE; + kobject_set_name(&cdev->kobj, "%s", name); + result = cdev_add(cdev, bf_dev, BF_FPGA_MAX_DEVICE_CNT); + + if (result) { + goto fail_dev_add; + } + + bf_major = MAJOR(bf_dev); + bf_global[minor].bf_cdev = cdev; + return 0; + +fail_dev_add: + unregister_chrdev_region(bf_dev, BF_FPGA_MAX_DEVICE_CNT); + return result; +} + +static void bf_major_cleanup(struct bf_pci_dev *bfdev, int minor) { + unregister_chrdev_region(MKDEV(bf_major, 0), BF_FPGA_MAX_DEVICE_CNT); + cdev_del(bf_global[minor].bf_cdev); +} + +static int bf_init_cdev(struct bf_pci_dev *bfdev, int minor) { + int ret; + ret = bf_major_init(bfdev, minor); + if (ret) return ret; + + bf_class = class_create(THIS_MODULE, BF_CLASS_NAME); + if (!bf_class) { + printk(KERN_ERR "create_class failed for bf_fpga_dev\n"); + ret = -ENODEV; + goto err_class_register; + } + return 0; + +err_class_register: + bf_major_cleanup(bfdev, minor); + return ret; +} + +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 + * + * returns zero on success or a negative error code. + */ +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) { + return -EINVAL; + } + + init_waitqueue_head(&info->wait); + + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { + atomic_set(&info->event[i], 0); + } + + if (bf_get_next_minor_no(&minor)) { + return -EINVAL; + } + + ret = bf_init_cdev(bfdev, minor); + if (ret) { + printk(KERN_ERR "BFi_FPGA: device cdev creation failed\n"); + return ret; + } + + info->dev = device_create( + bf_class, parent, MKDEV(bf_major, minor), bfdev, "bf_fpga_%d", minor); + if (!info->dev) { + printk(KERN_ERR "BF_FPGA: device creation failed\n"); + return -ENODEV; + } + + info->minor = minor; + + /* bind ISRs and request interrupts */ + if (info->irq && (bfdev->mode != BF_INTR_MODE_NONE)) { + /* + * Note that we deliberately don't use devm_request_irq + * here. The parent module can unregister the UIO device + * and call pci_disable_msi, which requires that this + * irq has been freed. However, the device may have open + * FDs at the time of unregister and therefore may not be + * freed until they are released. + */ + if (bfdev->mode == BF_INTR_MODE_LEGACY) { + ret = request_irq(info->irq, + bf_interrupt, + info->irq_flags, + bfdev->name, + (void *)&(bfdev->bf_int_vec[0])); + if (ret) { + printk(KERN_ERR "bf_fpga failed to request legacy irq %ld error %d\n", + info->irq, + ret); + return ret; + } + printk(KERN_NOTICE "BF_FPGA 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, + (void *)&(bfdev->bf_int_vec[i])); + if (ret) { + /* undo all other previous bindings */ + printk(KERN_ERR "bf_fpga failed to request MSIX ret %d itr %d\n", + ret, + i); + for (j = i - 1; j >= 0; j--) { + free_irq(info->msix_entries[j].vector, + (void *)&(bfdev->bf_int_vec[j])); + } + return ret; + } + } + printk(KERN_NOTICE "BF_FPGA allocating %d MSIx vectors from %ld\n", + 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, + (void *)&(bfdev->bf_int_vec[i])); + if (ret) { + /* undo all other previous bindings */ + printk( + KERN_ERR "bf_fpga failed to request MSI ret %d itr %d\n", ret, i); + for (j = i - 1; j >= 0; j--) { + free_irq(info->irq + j, (void *)&(bfdev->bf_int_vec[j])); + } + return ret; + } + } + printk(KERN_NOTICE "BF_FPGA allocating %d MSI vectors from %ld\n", + info->num_irq, + info->irq); + } + } + return 0; +} + +/** + * bf_unregister_device - register a new userspace mem device + * @bfdev: bf pci device + * + * returns none + */ +void bf_unregister_device(struct bf_pci_dev *bfdev) { + struct bf_dev_info *info = &bfdev->info; + int i; + + if (info->irq) { + if (bfdev->mode == BF_INTR_MODE_LEGACY) { + free_irq(info->irq, (void *)&(bfdev->bf_int_vec[0])); + } else if (bfdev->mode == BF_INTR_MODE_MSIX) { + for (i = 0; i < info->num_irq; i++) { + free_irq(info->msix_entries[i].vector, (void *)&(bfdev->bf_int_vec[i])); + } + } else if (bfdev->mode == BF_INTR_MODE_MSI) { + for (i = 0; i < info->num_irq; i++) { + free_irq(info->irq + i, (void *)&(bfdev->bf_int_vec[i])); + } + } + } + device_destroy(bf_class, MKDEV(bf_major, info->minor)); + bf_remove_cdev(bfdev); + bf_return_minor_no(info->minor); + return; +} + +static inline struct device *pci_dev_to_dev(struct pci_dev *pdev) { + return &pdev->dev; +} + +static void bf_fpga_disable_int_dma(struct bf_pci_dev *bfdev) { + u8 *bf_base_addr; + + /* maskinterrupts and DMA */ + bf_base_addr = (bfdev->info.mem[0].internal_addr); + /* return if called before mmap */ + if (!bf_base_addr) { + return; + } + /* mask interrupt at shadow level */ + /* TBD */ +} + +static void fpga_print_build_date(u32 build_date) { + char day, month, year, hr, min, sec; + + sec = (char)(build_date & 0x3f); + build_date >>= 6; + min = (char)(build_date & 0x3f); + build_date >>= 6; + hr = (char)(build_date & 0x1f); + build_date >>= 5; + year = (char)(build_date & 0x3f); + build_date >>= 6; + month = (char)(build_date & 0x0f); + build_date >>= 4; + day = (char)(build_date & 0x1f); + printk(KERN_ALERT "fpga version %02d/%02d/%2d %02d:%02d:%02d", + month, + day, + year, + hr, + min, + sec); +} + +static int bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { + struct bf_pci_dev *bfdev; + int err, pci_use_highmem; + int i, num_irq; + u32 build_date, build_ver; + + memset(bf_global, 0, sizeof(bf_global)); + + bfdev = kzalloc(sizeof(struct bf_pci_dev), GFP_KERNEL); + if (!bfdev) { + return -ENOMEM; + } + + /* init the cookies to be passed to ISRs */ + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { + bfdev->bf_int_vec[i].int_vec_offset = i; + bfdev->bf_int_vec[i].bf_dev = bfdev; + } + + /* initialize intr_mode to none */ + bfdev->mode = BF_INTR_MODE_NONE; + + /* clear pci_error_state */ + bfdev->info.pci_error_state = 0; + + /* + * enable device + */ + err = pci_enable_device(pdev); + if (err != 0) { + printk(KERN_ERR "bf_fpga cannot enable PCI device\n"); + goto fail_free; + } + + /* + * reserve device's PCI memory regions for use by this + * module + */ + err = pci_request_regions(pdev, "bf_fpga_umem"); + if (err != 0) { + printk(KERN_ERR "bf_fpga Cannot request regions\n"); + goto fail_pci_disable; + } + /* remap IO memory */ + err = bf_setup_bars(pdev, &bfdev->info); + if (err != 0) { + printk(KERN_ERR "bf_fpga 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)); + if (err) { + printk(KERN_ERR "bf_fpga no usable DMA configuration, aborting\n"); + goto fail_release_iomem; + } + } + pci_use_highmem = 0; + } + + /* enable pci error reporting */ + /* for the current kernel version, kernel config must have set the followings: + * CONFIG_PCIEPORTBUS=y and CONFIG_PCIEAER = y + * we have pci_error_handlers defined that gets invoked by kernel AER module + * upon detecting the pcie error on this device's addresses. + * However, there seems no way that AER would pass the offending addresses + * to the callback functions. AER logs the error messages on the console. + * This driver's calback function send the SIGIO signal to the user space + * to indicate the error condition. + */ + pci_enable_pcie_error_reporting(pdev); + + bf_fpga_disable_int_dma(bfdev); + + /* enable bus mastering on the device */ + pci_set_master(pdev); + + /* fill in bfdev info */ + bfdev->info.version = "0.1"; + bfdev->info.owner = THIS_MODULE; + bfdev->pdev = pdev; + + 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; + } +#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) { + 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_fpga 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) { + 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_fpga 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_fpga error allocating MSIX vectors. Trying MSI...\n"); + /* and, fall back to MSI */ + } +#endif /* LINUX_VERSION_CODE */ + /* ** intentional no-break */ + 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) { + bfdev->info.num_irq = BF_MSI_ENTRY_CNT; + bfdev->info.irq = pdev->irq; + bfdev->mode = BF_INTR_MODE_MSI; + printk(KERN_DEBUG "bf_fpga using %d MSI irq from %ld\n", + bfdev->info.num_irq, + bfdev->info.irq); + 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) { + bfdev->info.num_irq = num_irq; + bfdev->info.irq = pdev->irq; + bfdev->mode = BF_INTR_MODE_MSI; + printk(KERN_DEBUG "bf_fpga 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) { + bfdev->info.num_irq = num_irq; + bfdev->info.irq = pci_irq_vector(pdev, 0); + bfdev->mode = BF_INTR_MODE_MSI; + printk(KERN_DEBUG "bf_fpga using %d MSI irq from %ld\n", + bfdev->info.num_irq, + bfdev->info.irq); + 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)) { + bfdev->info.irq_flags = IRQF_SHARED; + bfdev->info.irq = pdev->irq; + bfdev->mode = BF_INTR_MODE_LEGACY; + printk(KERN_DEBUG "bf_fpga using LEGACY irq %ld\n", bfdev->info.irq); + break; + } + printk(KERN_NOTICE "bf_fpga 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; + + default: + printk(KERN_DEBUG "bf_fpga invalid IRQ mode %u", bf_intr_mode_default); + err = -EINVAL; + goto fail_clear_pci_master; + } + + pci_set_drvdata(pdev, bfdev); + sprintf(bfdev->name, "bf_fpga%d", bfdev->info.minor); + /* register bf driver */ + err = bf_register_device(&pdev->dev, bfdev); + 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_fpga device %d registered with irq %ld\n", + bfdev->instance, + bfdev->info.irq); + if (fpga_i2c_init(bfdev->info.mem[0].internal_addr)) { + printk(KERN_ERR "bf_fpga i2c initialization failed\n"); + goto fail_register_device; + } + if (bf_fpga_sysfs_add(bfdev)) { + printk(KERN_ERR "bf_fpga stsfs initialization failed\n"); + goto fail_i2c_init; + } + build_ver = + *((u32 *)(bfdev->info.mem[0].internal_addr) + (BF_FPGA_VER_REG / 4)); + build_date = + *((u32 *)(bfdev->info.mem[0].internal_addr) + (BF_FPGA_BUILD_DATE / 4)); + fpga_print_build_date(build_date); + printk(KERN_ALERT "bf_fpga version %hu:%hu probe ok\n", + (u16)(build_ver >> 16), + (u16)(build_ver)); + return 0; + +fail_i2c_init: + fpga_i2c_deinit(); +fail_register_device: + bf_unregister_device(bfdev); +fail_release_irq: + pci_set_drvdata(pdev, NULL); + if (bfdev->mode == BF_INTR_MODE_MSIX) { + pci_disable_msix(bfdev->pdev); + kfree(bfdev->info.msix_entries); + bfdev->info.msix_entries = NULL; + } else if (bfdev->mode == BF_INTR_MODE_MSI) { + pci_disable_msi(bfdev->pdev); + } +fail_clear_pci_master: + pci_clear_master(pdev); +fail_release_iomem: + bf_pci_release_iomem(&bfdev->info); + pci_release_regions(pdev); +fail_pci_disable: + pci_disable_device(pdev); +fail_free: + kfree(bfdev); + + printk(KERN_ERR "bf_fpga probe failed\n"); + return err; +} + +static void bf_pci_remove(struct pci_dev *pdev) { + struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); + struct bf_listener *cur_listener; + + bf_fpga_disable_int_dma(bfdev); + bf_fpga_sysfs_del(bfdev); + fpga_i2c_deinit(); + 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) { + pci_disable_msi(pdev); + } + pci_clear_master(pdev); + bf_pci_release_iomem(&bfdev->info); + pci_release_regions(pdev); + pci_disable_pcie_error_reporting(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + bf_global[bfdev->info.minor].bfdev = NULL; + /* existing filep structures in open file(s) must be informed that + * bf_pci_dev is no longer valid */ + spin_lock(&bf_nonisr_lock); + cur_listener = bfdev->listener_head; + while (cur_listener) { + cur_listener->bfdev = NULL; + cur_listener = cur_listener->next; + } + spin_unlock(&bf_nonisr_lock); + kfree(bfdev); + printk(KERN_ALERT "bf_fpga removed\n"); +} + +/** + * bf_pci_error_detected - called when PCI error is detected + * @pdev: Pointer to PCI device + * @state: The current pci connection state + * + * 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) { + struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); + int minor; + + if (!bfdev) { + return PCI_ERS_RESULT_NONE; + } + printk(KERN_ERR "bf_fpga 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; + /* send a signal to the user space program of the error */ + minor = bfdev->info.minor; + if (minor < BF_FPGA_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; + } +} + +/** + * bf_pci_slot_reset - called after the pci bus has been reset. + * @pdev: Pointer to PCI device + * + * Restart the card from scratch, as if from a cold-boot. + */ +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 + * TBD: fill in this function if tofino can recover after an error + */ + return PCI_ERS_RESULT_DISCONNECT; +} + +/** + * bf_pci_resume - called when kernel thinks the device is up on PCIe. + * @pdev: Pointer to PCI device + * + * 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 BF FPGA */ + struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); + + printk(KERN_ERR "BF_FPGA io_resume invoked after pci error\n"); + if (bfdev) { + bfdev->info.pci_error_state = 0; + } +} + +static int bf_config_intr_mode(char *intr_str) { + if (!intr_str) { + pr_info("BF_FPGA Use MSI interrupt by default\n"); + return 0; + } + + if (!strcmp(intr_str, BF_INTR_MODE_MSIX_NAME)) { + bf_intr_mode_default = BF_INTR_MODE_MSIX; + pr_info("BF_FPGA Use MSIX interrupt\n"); + } else if (!strcmp(intr_str, BF_INTR_MODE_MSI_NAME)) { + bf_intr_mode_default = BF_INTR_MODE_MSI; + pr_info("BF_FPGA Use MSI interrupt\n"); + } else if (!strcmp(intr_str, BF_INTR_MODE_LEGACY_NAME)) { + bf_intr_mode_default = BF_INTR_MODE_LEGACY; + pr_info("BF_FPGA Use legacy interrupt\n"); + } else if (!strcmp(intr_str, BF_INTR_MODE_NONE_NAME)) { + bf_intr_mode_default = BF_INTR_MODE_NONE; + pr_info("BF_FPGA interrupt disabled\n"); + } else { + pr_info("Error: BF_FPGA bad intr_mode parameter - %s\n", intr_str); + return -EINVAL; + } + + return 0; +} + +static const struct pci_device_id bf_pci_tbl[] = { + {PCI_VDEVICE(BF, BF_FPGA_DEV_ID_JBAY_0), 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, +}; + +static struct pci_driver bf_pci_driver = {.name = "bf_fpga", + .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) { + int ret; + + ret = bf_config_intr_mode(intr_mode); + if (ret < 0) { + return ret; + } + spin_lock_init(&bf_nonisr_lock); + return pci_register_driver(&bf_pci_driver); +} + +static void __exit bfdrv_exit(void) { + pci_unregister_driver(&bf_pci_driver); + intr_mode = NULL; +} + +module_init(bfdrv_init); +module_exit(bfdrv_exit); + +module_param(intr_mode, charp, S_IRUGO); +MODULE_PARM_DESC(intr_mode, + "bf-fpga interrupt mode (default=none):\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 FPGA PCI-I2C device"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION("0.1"); +MODULE_AUTHOR("Barefoot Networks"); diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_priv.h b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_priv.h new file mode 100644 index 000000000000..7515bde7458d --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_priv.h @@ -0,0 +1,141 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 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_FPGA_H_ +#define _BF_FPGA_H_ + +#define PCI_VENDOR_ID_BF 0x1d1c +#define BF_FPGA_DEV_ID_JBAY_0 0x01F0 + +#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_fpga" +#define BF_FPGA_MAX_DEVICE_CNT 1 +#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 1 +#define BF_MSI_ENTRY_CNT 1 + +/* sysfs codes */ +#define BF_SYSFS_NEW_DEVICE 1 +#define BF_SYSFS_RM_DEVICE 0 +#define BF_SYSFS_I2C_START 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; +}; + +/* sysfs related structs */ +#define BF_FPGA_SYSFS_CNT 64 +#define BF_FPGA_SYSFS_NAME_SIZE 32 + +struct bf_fpga_sysfs_buff { + struct device_attribute dev_attr; + char name[BF_FPGA_SYSFS_NAME_SIZE]; + int bus_id; + unsigned char i2c_addr; + size_t i2c_rd_size; /* bytes to read from the device */ + int sysfs_code; /* unique code for each sysfs file */ + struct bf_pci_dev *fpgadev; /* back pointer */ + bool in_use; +}; + +/** + * 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 */ + struct bf_fpga_sysfs_buff fpga_sysfs_buff[BF_FPGA_SYSFS_CNT]; + struct bf_fpga_sysfs_buff fpga_sysfs_new_device; + struct bf_fpga_sysfs_buff fpga_sysfs_rm_device; + struct bf_fpga_sysfs_buff fpga_sysfs_st_i2c; + spinlock_t sysfs_slock; +}; + +int bf_fpga_ioctl(struct bf_pci_dev *bfdev, + unsigned int cmd, + unsigned long arg); +int bf_fpga_sysfs_add(struct bf_pci_dev *fpgadev); +void bf_fpga_sysfs_del(struct bf_pci_dev *fpgadev); + +#endif /* _BF_FPGA_H_ */ diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_sysfs.c b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_sysfs.c new file mode 100644 index 000000000000..6970a7a95985 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/bf_fpga_sysfs.c @@ -0,0 +1,335 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 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 + +*******************************************************************************/ +#include +#include +#include +#include +#include +#include "bf_fpga_priv.h" +#include "bf_fpga_ioctl.h" +#include "i2c/bf_fpga_i2c.h" + +/* reads 1 byte from the i2c device */ +static ssize_t bf_fpga_sysfs_i2c_get(struct device *dev, + struct device_attribute *attr, + char *buf) { + bf_fpga_i2c_t i2c_op; + ssize_t size, cur_size; + struct bf_fpga_sysfs_buff *sysfs_buf = + container_of(attr, struct bf_fpga_sysfs_buff, dev_attr); + + if (!sysfs_buf) { + printk(KERN_ERR "fpga-i2c bad attr pointer in sysfs_read\n"); + return -ENXIO; /* something not quite right here; but, don't panic */ + } + i2c_op.num_i2c = 1; + i2c_op.one_time = 1; + i2c_op.inst_hndl.bus_id = sysfs_buf->bus_id; + i2c_op.i2c_inst[0].preemt = false; + i2c_op.i2c_inst[0].en = true; + i2c_op.i2c_inst[0].i2c_addr = sysfs_buf->i2c_addr; + i2c_op.i2c_inst[0].i2c_type = BF_FPGA_I2C_READ; + i2c_op.i2c_inst[0].delay = 0; + i2c_op.i2c_inst[0].wr_cnt = 0; + cur_size = sysfs_buf->i2c_rd_size; + /* limit to PAGE_SIZE per the sysfs contract */ + if (cur_size >= PAGE_SIZE) { + cur_size = PAGE_SIZE; + } + size = 0; + while (cur_size > 0) { + unsigned char cur_cnt; + if (cur_size > 64) { + cur_cnt = 64; + } else { + cur_cnt = (unsigned char)cur_size; + } + i2c_op.i2c_inst[0].rd_cnt = cur_cnt; + if (fpga_i2c_oneshot(&i2c_op)) { + printk(KERN_ERR + "fpga-i2c read one-shot error bus %d addr 0x%hhx status 0x%hhx\n", + i2c_op.inst_hndl.bus_id, + i2c_op.i2c_inst[0].i2c_addr, + i2c_op.i2c_inst[0].status); + return -EIO; + } + memcpy(buf, i2c_op.i2c_inst[0].rd_buf, cur_cnt); + buf += cur_cnt; + size += cur_cnt; + cur_size -= cur_cnt; + } + return size; +} + +/* write the number of bytes supplied to the i2c device, 1st byte has to be + the count(max 8) */ +static ssize_t bf_fpga_sysfs_i2c_set(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) { + bf_fpga_i2c_t i2c_op; + size_t size, cur_cnt; + struct bf_fpga_sysfs_buff *sysfs_buf = + container_of(attr, struct bf_fpga_sysfs_buff, dev_attr); + + if (!sysfs_buf || (count == 0)) { + printk(KERN_ERR "fpga-i2c bad attr pointer in sysfs_write\n"); + return -ENXIO; /* something not quite right here; but, don't panic */ + } + size = 0; + while (count > 0) { + if (count > 64) { + cur_cnt = 64; + } else { + cur_cnt = count; + } + i2c_op.i2c_inst[0].wr_cnt = cur_cnt; + i2c_op.i2c_inst[0].rd_cnt = 0; + memcpy(i2c_op.i2c_inst[0].wr_buf, buf, cur_cnt); + i2c_op.num_i2c = 1; + i2c_op.one_time = 1; + i2c_op.inst_hndl.bus_id = sysfs_buf->bus_id; + i2c_op.i2c_inst[0].preemt = false; + i2c_op.i2c_inst[0].en = true; + i2c_op.i2c_inst[0].i2c_addr = sysfs_buf->i2c_addr; + i2c_op.i2c_inst[0].i2c_type = BF_FPGA_I2C_WRITE; + i2c_op.i2c_inst[0].delay = 0; + if (fpga_i2c_oneshot(&i2c_op)) { + printk( + KERN_ERR + "fpga-i2c write one-shot error bus %d addr 0x%hhx status 0x%hhx\n", + i2c_op.inst_hndl.bus_id, + i2c_op.i2c_inst[0].i2c_addr, + i2c_op.i2c_inst[0].status); + return -EIO; + } + buf += cur_cnt; + size += cur_cnt; + count -= cur_cnt; + } + return size; +} + +static int find_matching_sysfs_buf(struct bf_pci_dev *fpgadev, + int bus_id, + unsigned char i2c_addr) { + int i; + + /* check if a sysfs entry already exists */ + for (i = 0; i < BF_FPGA_SYSFS_CNT; i++) { + if (fpgadev->fpga_sysfs_buff[i].bus_id == bus_id && + fpgadev->fpga_sysfs_buff[i].i2c_addr == i2c_addr) { + return i; + } + } + /* could not find a matching sysfs buffer */ + return -1; +} + +static ssize_t bf_fpga_sysfs_fixed_get(struct device *dev, + struct device_attribute *attr, + char *buf) { + (void)dev; + (void)attr; + (void)buf; + return -ENOSYS; +} + +static ssize_t bf_fpga_sysfs_fixed_set(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) { + struct bf_pci_dev *fpgadev; + int i, en, bus_id, ret, rd_size; + char fname[BF_FPGA_SYSFS_NAME_SIZE]; + unsigned char i2c_addr; + struct bf_fpga_sysfs_buff *new_buf; + struct bf_fpga_sysfs_buff *sysfs_buf = + container_of(attr, struct bf_fpga_sysfs_buff, dev_attr); + + if (!sysfs_buf || (count == 0)) { + printk(KERN_ERR "fpga i2c bad attr pointer in fixed_sysfs_write\n"); + return -ENXIO; /* something not quite right here; but, don't panic */ + } + fpgadev = sysfs_buf->fpgadev; + + switch (sysfs_buf->sysfs_code) { + case BF_SYSFS_NEW_DEVICE: /* new_device request */ + ret = sscanf(buf, "%s %d %hhx %d", fname, &bus_id, &i2c_addr, &rd_size); + /* default rd_size to 1 if not supplied or invalid */ + if (ret < 3) { + return -EINVAL; + } + if (ret < 4 || rd_size > PAGE_SIZE) { + rd_size = 1; + } + if (bus_id >= BF_I2C_FPGA_NUM_CTRL || i2c_addr >= 0x80) { + return -EINVAL; + } + /* find out the free sysfs_buffer to use */ + spin_lock(&fpgadev->sysfs_slock); + if (find_matching_sysfs_buf(fpgadev, bus_id, i2c_addr) != -1) { + /* there is already an matching entry */ + spin_unlock(&fpgadev->sysfs_slock); + return -ENOSPC; + } + for (i = 0; i < BF_FPGA_SYSFS_CNT; i++) { + if (!fpgadev->fpga_sysfs_buff[i].in_use) { + fpgadev->fpga_sysfs_buff[i].in_use = true; + new_buf = &fpgadev->fpga_sysfs_buff[i]; + new_buf->i2c_addr = i2c_addr; + new_buf->i2c_rd_size = (size_t)rd_size; + new_buf->bus_id = bus_id; + break; + } + } + spin_unlock(&fpgadev->sysfs_slock); + if (i >= BF_FPGA_SYSFS_CNT) { + /* no free buffer available, return with ERROR */ + return -ENOSPC; + } + /* create a new sysfs entry now */ + new_buf->dev_attr.show = bf_fpga_sysfs_i2c_get; + new_buf->dev_attr.store = bf_fpga_sysfs_i2c_set; + new_buf->fpgadev = fpgadev; + new_buf->dev_attr.attr.mode = S_IWUSR | S_IRUGO; + new_buf->sysfs_code = 0; + snprintf(new_buf->name, BF_FPGA_SYSFS_NAME_SIZE, "%s", fname); + new_buf->dev_attr.attr.name = new_buf->name; + ret = device_create_file(&(fpgadev->pdev->dev), &new_buf->dev_attr); + break; + + case BF_SYSFS_RM_DEVICE: /* remove device request */ + ret = sscanf(buf, "%d %hhx", &bus_id, &i2c_addr); + if (ret < 2) { + return -EINVAL; + } + if (bus_id >= BF_I2C_FPGA_NUM_CTRL || i2c_addr >= 0x80) { + return -EINVAL; + } + /* delete the sysfs file corresponding to the i2c address */ + spin_lock(&fpgadev->sysfs_slock); + i = find_matching_sysfs_buf(fpgadev, bus_id, i2c_addr); + if (i == -1) { + /* there is no matching entry */ + spin_unlock(&fpgadev->sysfs_slock); + return -EINVAL; + } + /* must invalidate bus_id and i2c_addr when marking the buffer + * not-in-use + */ + new_buf = &fpgadev->fpga_sysfs_buff[i]; + new_buf->i2c_addr = 0xff; + new_buf->bus_id = -1; + fpgadev->fpga_sysfs_buff[i].in_use = false; + spin_unlock(&fpgadev->sysfs_slock); + device_remove_file(&fpgadev->pdev->dev, &new_buf->dev_attr); + new_buf->name[0] = 0; /* nullify the name */ + ret = 0; + break; + + case BF_SYSFS_I2C_START: /* start-stop i2c request */ + ret = sscanf(buf, "%d %d", &bus_id, &en); + if (ret < 2) { + return -EINVAL; + } + if (bus_id >= BF_I2C_FPGA_NUM_CTRL) { + return -EINVAL; + } + if (en) { + ret = fpga_i2c_start(bus_id); + } else { + ret = fpga_i2c_stop(bus_id); + } + break; + + default: + ret = -EINVAL; + } + return ((ret == 0) ? count : ret); +} + +int bf_fpga_sysfs_add(struct bf_pci_dev *fpgadev) { + int rc = 0; + u8 *name; + + spin_lock_init(&fpgadev->sysfs_slock); + /* Add two sysfs files statically, new_device and remove_device. + * Handlers of these two fles can dynamically add more sysfs + * files (or remove files) based on the platform. + */ + fpgadev->fpga_sysfs_new_device.dev_attr.show = bf_fpga_sysfs_fixed_get; + fpgadev->fpga_sysfs_new_device.dev_attr.store = bf_fpga_sysfs_fixed_set; + fpgadev->fpga_sysfs_new_device.fpgadev = fpgadev; + fpgadev->fpga_sysfs_new_device.dev_attr.attr.mode = S_IWUSR | S_IRUGO; + fpgadev->fpga_sysfs_new_device.sysfs_code = BF_SYSFS_NEW_DEVICE; + name = fpgadev->fpga_sysfs_new_device.name; + snprintf(name, BF_FPGA_SYSFS_NAME_SIZE, "new_device"); + fpgadev->fpga_sysfs_new_device.dev_attr.attr.name = name; + rc |= device_create_file(&(fpgadev->pdev->dev), + &fpgadev->fpga_sysfs_new_device.dev_attr); + + fpgadev->fpga_sysfs_rm_device.dev_attr.show = bf_fpga_sysfs_fixed_get; + fpgadev->fpga_sysfs_rm_device.dev_attr.store = bf_fpga_sysfs_fixed_set; + fpgadev->fpga_sysfs_rm_device.fpgadev = fpgadev; + fpgadev->fpga_sysfs_rm_device.dev_attr.attr.mode = S_IWUSR | S_IRUGO; + fpgadev->fpga_sysfs_rm_device.sysfs_code = BF_SYSFS_RM_DEVICE; + name = fpgadev->fpga_sysfs_rm_device.name; + snprintf(name, BF_FPGA_SYSFS_NAME_SIZE, "remove_device"); + fpgadev->fpga_sysfs_rm_device.dev_attr.attr.name = name; + rc |= device_create_file(&(fpgadev->pdev->dev), + &fpgadev->fpga_sysfs_rm_device.dev_attr); + + /* sysfs for i2c start-stop control */ + fpgadev->fpga_sysfs_st_i2c.dev_attr.show = bf_fpga_sysfs_fixed_get; + fpgadev->fpga_sysfs_st_i2c.dev_attr.store = bf_fpga_sysfs_fixed_set; + fpgadev->fpga_sysfs_st_i2c.fpgadev = fpgadev; + fpgadev->fpga_sysfs_st_i2c.dev_attr.attr.mode = S_IWUSR | S_IRUGO; + fpgadev->fpga_sysfs_st_i2c.sysfs_code = BF_SYSFS_I2C_START; + name = fpgadev->fpga_sysfs_st_i2c.name; + snprintf(name, BF_FPGA_SYSFS_NAME_SIZE, "i2c_start"); + fpgadev->fpga_sysfs_st_i2c.dev_attr.attr.name = name; + rc |= device_create_file(&(fpgadev->pdev->dev), + &fpgadev->fpga_sysfs_st_i2c.dev_attr); + + return rc; +} + +void bf_fpga_sysfs_del(struct bf_pci_dev *fpgadev) { + int i; + + device_remove_file(&fpgadev->pdev->dev, + &fpgadev->fpga_sysfs_new_device.dev_attr); + device_remove_file(&fpgadev->pdev->dev, + &fpgadev->fpga_sysfs_rm_device.dev_attr); + device_remove_file(&fpgadev->pdev->dev, &fpgadev->fpga_sysfs_st_i2c.dev_attr); + for (i = 0; i < BF_FPGA_SYSFS_CNT; i++) { + if (fpgadev->fpga_sysfs_buff[i].in_use) { + device_remove_file(&fpgadev->pdev->dev, + &fpgadev->fpga_sysfs_buff[i].dev_attr); + } + } +} diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c.c b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c.c new file mode 100644 index 000000000000..1a622e5392d6 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c.c @@ -0,0 +1,516 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 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 + +*******************************************************************************/ +#include +#include "bf_fpga_i2c_priv_porting.h" +#include +#include "bf_fpga_i2c_priv.h" +#include "bf_fpga_i2c.h" +#include "bf_fpga_i2c_reg.h" + +/* allocate find physically contiguous free blocks of instructions in one time + * or periodic area and mark them "in-use" */ +static int get_next_free_index(fpga_i2c_controller_t *i2c_ctrl, + int cnt, + bool pr) { + int i, j, begin, end; + + if (pr) { + begin = FPGA_I2C_PERIODIC_BEGIN_INDEX; + end = FPGA_I2C_NUM_INST; + } else { + begin = FPGA_I2c_ONESHOT_BEGIN_INDEX; + end = FPGA_I2C_ONESHOT_NUM_INST; + } + + bf_fpga_fast_lock(&i2c_ctrl->spinlock); + for (i = begin; i < end;) { + /* check if there are cnt number of free slots here */ + for (j = 0; j < cnt; j++) { + if (i2c_ctrl->i2c_inst[i + j].in_use) { + break; + } + } + if (j == cnt) { + /* we found enough free slots, so, return i */ + break; + } else { + /* we did not find enough free slots, continue searching */ + i += (j + 1); + continue; + } + } + if (i < end) { + for (j = 0; j < cnt; j++) { + i2c_ctrl->i2c_inst[i + j].in_use = true; + } + } else { + i = -1; + } + bf_fpga_fast_unlock(&i2c_ctrl->spinlock); + return i; +} + +/* free physically contiguous in-use blocks of instructions */ +static void release_index(fpga_i2c_controller_t *i2c_ctrl, + int inst_id, + int cnt) { + int i; + + if (inst_id < 0 || (inst_id + cnt) >= FPGA_I2C_NUM_INST) { + return; /* invalid id */ + } + bf_fpga_fast_lock(&i2c_ctrl->spinlock); + for (i = inst_id; i < (inst_id + cnt); i++) { + i2c_ctrl->i2c_inst[i].in_use = false; + } + bf_fpga_fast_unlock(&i2c_ctrl->spinlock); +} + +/* convert miroseconds to i2c-instruction delay parameter */ +static int us_to_fpga_delay(int microsec) { + int delay; + + if (microsec < 10) { + delay = 0; + } else if (microsec < 100) { + delay = 1; + } else if (microsec < 1000) { + delay = 2; + } else if (microsec < 10000) { + delay = 3; + } else if (microsec < 100000) { + delay = 4; + } else if (microsec < 1000000) { + delay = 5; + } else { + delay = 6; + } + return delay; +} + +/* populate single i2c_instruction at the given instruction slot */ +static int fpga_i2c_enqueue(int bus_id, + int inst_id, + bf_fpga_i2c_inst_t *i2c_inst) { + fpga_i2c_controller_t *i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + int delay = us_to_fpga_delay(i2c_inst->delay); + uint32_t wd0 = 0, wd1 = 0; + uint32_t i2c_data[2]; + uint8_t i2c_addr, num_wr, num_rd; + + i2c_addr = i2c_inst->i2c_addr; + num_wr = i2c_inst->wr_cnt; + num_rd = i2c_inst->rd_cnt; + if (i2c_addr > 0x7F || num_wr > 129 || num_rd > 128) { + return BF_FPGA_EINVAL; + } + if (i2c_inst->preemt) { + wd0 |= I2C_INST_PMT; + } + if (i2c_inst->en) { + wd0 |= I2C_INST_EN; + } + i2c_data[0] = i2c_data[1] = 0; /* clear on init */ + switch (i2c_inst->i2c_type) { + case BF_FPGA_I2C_NOP: + /* add delay + enable */ + wd0 |= (I2C_NOP | (delay << I2C_DELAY_SHF)); + break; + case BF_FPGA_I2C_WRITE: + if (num_wr == 0) { + return BF_FPGA_EINVAL; + } + wd0 |= (I2C_WR_ADDR_DATA | (delay << I2C_DELAY_SHF)); + wd1 |= (i2c_inst->i2c_addr << I2C_DEV_ADDR_SHF); + /* copy the first byte into register address */ + wd1 |= ((i2c_inst->wr_buf[0]) << I2C_CMD_OFFSET); + wd1 |= ((num_wr - 1) << I2C_WR_CNT_SHF); + if (num_wr <= 9) { + /* copy data into instruction area */ + memcpy(i2c_data, &i2c_inst->wr_buf[1], (num_wr - 1)); + bf_fpga_i2c_reg_write32( + i2c_ctrl, Bf_FPGA_I2C_INST_DATA_LO(inst_id), i2c_data[0]); + bf_fpga_i2c_reg_write32( + i2c_ctrl, Bf_FPGA_I2C_INST_DATA_HI(inst_id), i2c_data[1]); + } else { + /* copy the data in data area */ + int len = num_wr - 1; + uint32_t addr; + uint8_t *val = (uint8_t *)(&i2c_inst->wr_buf[1]); + /* store the data pointer Note the indexing required by FPGA specs */ + i2c_data[0] = BF_FPGA_I2C_DATA_AREA(inst_id); + addr = i2c_data[0]; + bf_fpga_i2c_reg_write32( + i2c_ctrl, Bf_FPGA_I2C_INST_DATA_LO(inst_id), i2c_data[0] / 4); + /* do byte write to avoid endianness mismatch */ + while (len--) { + bf_fpga_i2c_reg_write8(i2c_ctrl, addr, *val); + addr++; + val++; + } + } + break; + case BF_FPGA_I2C_READ: + if (num_rd == 0) { + return BF_FPGA_EINVAL; + } + wd0 |= (I2C_RD_DATA | (delay << I2C_DELAY_SHF)); + wd1 |= (i2c_inst->i2c_addr << I2C_DEV_ADDR_SHF); + wd1 |= ((num_rd) << I2C_RD_CNT_SHF); + if (num_rd > 8) { + /* store the data area pointer */ + i2c_data[0] = BF_FPGA_I2C_DATA_AREA(inst_id); + bf_fpga_i2c_reg_write32( + i2c_ctrl, Bf_FPGA_I2C_INST_DATA_LO(inst_id), i2c_data[0] / 4); + } + break; + case BF_FPGA_I2C_ADDR_READ: + if (num_wr == 0 || num_rd == 0) { + return BF_FPGA_EINVAL; + } + wd0 |= (I2C_RD_ADDR_DATA_BURST | (delay << I2C_DELAY_SHF)); + wd1 |= (i2c_inst->i2c_addr << I2C_DEV_ADDR_SHF); + /* 1st byte of the write buf goes into "register address" field */ + wd1 |= ((num_wr - 1) << I2C_WR_CNT_SHF); + wd1 |= ((i2c_inst->wr_buf[0]) << I2C_CMD_OFFSET); + wd1 |= ((num_rd) << I2C_RD_CNT_SHF); + /* less than 8 bytes data goes to the instruction area */ + if ((num_wr - 1 + num_rd) <= 8) { + memcpy(i2c_data, &i2c_inst->wr_buf[1], (num_wr - 1)); + bf_fpga_i2c_reg_write32( + i2c_ctrl, Bf_FPGA_I2C_INST_DATA_LO(inst_id), i2c_data[0]); + bf_fpga_i2c_reg_write32( + i2c_ctrl, Bf_FPGA_I2C_INST_DATA_HI(inst_id), i2c_data[1]); + } else { + int len = num_wr - 1; + uint32_t addr; + uint8_t *val = (uint8_t *)(&i2c_inst->wr_buf[1]); + /* store the data area pointer */ + i2c_data[0] = BF_FPGA_I2C_DATA_AREA(inst_id); + addr = i2c_data[0]; + bf_fpga_i2c_reg_write32( + i2c_ctrl, Bf_FPGA_I2C_INST_DATA_LO(inst_id), i2c_data[0] / 4); + /* copy the data in data area */ + while (len--) { + bf_fpga_i2c_reg_write8(i2c_ctrl, addr, *val); + addr++; + val++; + } + } + break; + default: + return BF_FPGA_EINVAL; + } + bf_fpga_i2c_reg_write32(i2c_ctrl, Bf_FPGA_I2C_INST_PARAM(inst_id), wd1); + bf_fpga_i2c_reg_write32(i2c_ctrl, Bf_FPGA_I2C_INST_CTRL(inst_id), wd0); + return BF_FPGA_OK; +} + +/* get the i2c completion status of a particular instruction */ +static uint32_t fpga_i2c_get_status(int bus_id, int inst_id) { + fpga_i2c_controller_t *i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + uint32_t addr = Bf_FPGA_I2C_INST_CTRL(inst_id); + return (bf_fpga_i2c_reg_read32(i2c_ctrl, addr) & I2C_STATUS_MASK); +} + +/** FPGA I2C data read (assumes locked by caller and no need to stop i2c) + * + * read the data following a read type i2c operation + * + * @param bus_id + * i2c controller id + * @param inst_id + * instruction id within this controller space + * @param offset + * offset in the data-area where read-data is available + * @param num_rd + * number of bytes to read + * @param rd_buf + * buffer to read into + * @return + * 0 on success and <0 on error + */ +static int fpga_i2c_data_read_locked(fpga_i2c_controller_t *i2c_ctrl, + int inst_id, + uint8_t offset, + uint8_t num_rd, + uint8_t *rd_buf) { + uint8_t i; + uint32_t addr, data_cnt; + + if (!i2c_ctrl || !rd_buf || !num_rd || inst_id < 0 || + inst_id >= FPGA_I2C_NUM_INST) { + return BF_FPGA_EINVAL; + } + /* find out the wr_cnt + rd_cnt from the already executed instruction field */ + data_cnt = bf_fpga_i2c_reg_read32(i2c_ctrl, Bf_FPGA_I2C_INST_PARAM(inst_id)); + /* point to data area if the (wr_cnt + rd_cnt) > 8 */ + data_cnt &= 0xffff; /* retain only the length fields */ + if (((data_cnt & 0xff) + (data_cnt >> 8)) <= 8) { + addr = Bf_FPGA_I2C_INST_DATA_LO(inst_id) + offset; + } else { + addr = BF_FPGA_I2C_DATA_AREA(inst_id) + offset; + } + for (i = 0; i < num_rd; i++) { + *rd_buf = bf_fpga_i2c_reg_read8(i2c_ctrl, addr); + addr++; + rd_buf++; + } + return BF_FPGA_OK; +} + +/** FPGA I2C data read + * + * read the data following a read type i2c operation + * + * @param bus_id + * i2c controller id + * @param inst_id + * instruction id within this controller space + * @param offset + * offset in the data-area where read-data is available + * @param num_rd + * number of bytes to read + * @param rd_buf + * buffer to read into + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_data_read( + int bus_id, int inst_id, uint8_t offset, uint8_t num_rd, uint8_t *rd_buf) { + fpga_i2c_controller_t *i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + int ret; + bool i2c_running; + uint8_t val; + + if (!i2c_ctrl || !rd_buf || !num_rd || inst_id < 0 || + inst_id >= FPGA_I2C_NUM_INST) { + return BF_FPGA_EINVAL; + } + + /* aligned (upto) 4 bytes can be read without stopping the ongoing i2c, + * this is guaranteed by FPGA design. i2c has to be stopped, in all other + * cases, to read a consistent set of read-data. + */ + if ((offset % 4 == 0) && (num_rd <= 4)) { + return ( + fpga_i2c_data_read_locked(i2c_ctrl, inst_id, offset, num_rd, rd_buf)); + } + + /* non-aligned case; stop i2c if running, read data and restart i2c */ + if (bf_fpga_i2c_lock(i2c_ctrl)) { + return BF_FPGA_EAGAIN; + } + /* check if i2c_controller is running */ + val = bf_fpga_i2c_reg_read8(i2c_ctrl, Bf_FPGA_TOP_I2C_STATUS); + i2c_running = ((val & I2C_STS_BUSY) ? true : false); + if (i2c_running) { + /* stop ongoing i2c operations */ + fpga_i2c_stop_locked(i2c_ctrl); + } + ret = fpga_i2c_data_read_locked(i2c_ctrl, inst_id, offset, num_rd, rd_buf); + if (i2c_running) { + /* restart ongoing i2c operations */ + fpga_i2c_start_locked(i2c_ctrl); + } + bf_fpga_i2c_unlock(i2c_ctrl); + return ret; +} + +/** FPGA I2C onetime i2c operation + * + * @param i2c_op + * bf_fpga_i2c_t parameters * + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_oneshot(bf_fpga_i2c_t *i2c_op) { + int i, ret; + uint32_t val; + int bus_id; + fpga_i2c_controller_t *i2c_ctrl; + + if (!i2c_op) { + return BF_FPGA_EINVAL; + } + + bus_id = i2c_op->inst_hndl.bus_id; + i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + + if (i2c_op->num_i2c == 0 || i2c_op->num_i2c >= FPGA_I2C_ONESHOT_NUM_INST || + i2c_op->one_time == 0 || bus_id >= BF_I2C_FPGA_NUM_CTRL || !i2c_ctrl) { + return BF_FPGA_EINVAL; + } + if (bf_fpga_i2c_lock(i2c_ctrl)) { + return BF_FPGA_EAGAIN; + } + /* stop ongoing i2c operations */ + ret = fpga_i2c_stop_locked(i2c_ctrl); + if (ret) { + bf_fpga_i2c_unlock(i2c_ctrl); + return ret; + } + /* populate one time i2c operation instruction(s) from offset zero */ + for (i = 0; i < i2c_op->num_i2c; i++) { + ret = fpga_i2c_enqueue(bus_id, i, &i2c_op->i2c_inst[i]); + if (ret) { + goto oneshot_error_exit; + } + } + /* start i2c operations */ + ret = fpga_i2c_start_locked(i2c_ctrl); + if (ret) { + goto oneshot_error_exit; + } + + /* wait until complete and read the data if necessary */ + for (i = 0; i < i2c_op->num_i2c; i++) { + int cnt; + val = 0; + /* cnt is roughly the number of bytes of this i2c cycle + * overhead of 100 bytes for for worst case timeout, one + * should not hit that in normal working case + */ + cnt = i2c_op->i2c_inst[i].wr_cnt + i2c_op->i2c_inst[i].rd_cnt; + /* bump up the cnt for an i2c transaction containing some data + * for computing worst case timeout */ + if (cnt > 0) { + cnt = cnt + 100; + } + while (!(val & I2C_STATUS_COMPLETED) && (cnt-- > 0)) { + /* 1 byte ~= 10 bits takes 25 microsec on i2c cycle at 400khz */ + bf_fpga_us_delay(50); + val = fpga_i2c_get_status(bus_id, i); + } + i2c_op->i2c_inst[i].status = val; /* store the h/w status */ + if (val & I2C_STATUS_ERR_MASK) { + ret = BF_FPGA_EIO; + goto oneshot_error_exit; + } + if (i2c_op->i2c_inst[i].rd_cnt) { + uint8_t offset = 0; + if (i2c_op->i2c_inst[i].wr_cnt > 1) { + offset = i2c_op->i2c_inst[i].wr_cnt - 1; + } + if (fpga_i2c_data_read_locked(i2c_ctrl, + i, + offset, + i2c_op->i2c_inst[i].rd_cnt, + i2c_op->i2c_inst[i].rd_buf)) { + ret = BF_FPGA_EIO; + goto oneshot_error_exit; + } + } + } + ret = BF_FPGA_OK; + +oneshot_error_exit: + for (i = 0; i < i2c_op->num_i2c; i++) { + /* cleanup the enable bit */ + val = bf_fpga_i2c_reg_read32(i2c_ctrl, Bf_FPGA_I2C_INST_CTRL(i)); + val &= (~I2C_INST_EN); + bf_fpga_i2c_reg_write32(i2c_ctrl, Bf_FPGA_I2C_INST_CTRL(i), val); + } + bf_fpga_i2c_unlock(i2c_ctrl); + return ret; +} + +/** FPGA I2C insert periodic i2c operation + * + * @param i2c_op + * bf_fpga_i2c_t parameters * + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_pr_add(bf_fpga_i2c_t *i2c_op) { + fpga_i2c_controller_t *i2c_ctrl; + int i, ret, next_id; + bool preemt; + + if (!i2c_op) { + return BF_FPGA_EINVAL; + } + i2c_ctrl = fpga_i2c_ctrl_get(i2c_op->inst_hndl.bus_id); + if (!i2c_ctrl) { + return BF_FPGA_EINVAL; + } + if (bf_fpga_i2c_lock(i2c_ctrl)) { + return BF_FPGA_EAGAIN; + } + /* get the next available free slot */ + next_id = get_next_free_index(i2c_ctrl, i2c_op->num_i2c, true); + if (next_id < 0) { + bf_fpga_i2c_unlock(i2c_ctrl); + return BF_FPGA_EBUSY; + } + /* populate periodic i2c operation instruction(s) */ + for (i = 0; i < i2c_op->num_i2c; i++) { + preemt = ((i == (i2c_op->num_i2c - 1)) ? false : true); + i2c_op->i2c_inst[i].preemt = preemt; + ret = fpga_i2c_enqueue( + i2c_op->inst_hndl.bus_id, next_id + i, &i2c_op->i2c_inst[i]); + + if (ret) { + bf_fpga_i2c_unlock(i2c_ctrl); + return ret; + } + } + bf_fpga_i2c_unlock(i2c_ctrl); + i2c_op->inst_hndl.inst_id = next_id; + return BF_FPGA_OK; +} + +/** FPGA I2C remove periodic i2c operation(s) from instruction memory + * + * @param i2c_op + * bf_fpga_i2c_t parameters * + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_del(bf_fpga_i2c_t *i2c_op) { + fpga_i2c_controller_t *i2c_ctrl; + int i, inst_id; + + if (!i2c_op) { + return BF_FPGA_EINVAL; + } + i2c_ctrl = fpga_i2c_ctrl_get(i2c_op->inst_hndl.bus_id); + if (!i2c_ctrl) { + return BF_FPGA_EINVAL; + } + inst_id = i2c_op->inst_hndl.inst_id; + if (bf_fpga_i2c_lock(i2c_ctrl)) { + return BF_FPGA_EAGAIN; + } + for (i = 0; i < i2c_op->num_i2c; i++) { + /* nullify the instruction */ + bf_fpga_i2c_reg_write32(i2c_ctrl, Bf_FPGA_I2C_INST_CTRL(inst_id + i), 0); + } + /* reset the in_use flag */ + release_index(i2c_ctrl, inst_id, i2c_op->num_i2c); + bf_fpga_i2c_unlock(i2c_ctrl); + return BF_FPGA_OK; +} diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c.h b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c.h new file mode 100644 index 000000000000..6f56ed270bdd --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c.h @@ -0,0 +1,55 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 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_FPGA_I2C_H +#define _BF_FPGA_I2C_H + +/* Allow the use in C++ code. */ +#ifdef __cplusplus +extern "C" { +#endif + +int fpga_i2c_start(int bus_id); +int fpga_i2c_stop(int bus_id); +int fpga_i2c_reset(int bus_id); +int fpga_i2c_is_busy(int bus_id, bool *is_busy); +int fpga_i2c_inst_en(int bus_id, int inst_id, bool en); +int fpga_i2c_set_clk(int bus_id, int clock_div); +int fpga_i2c_controller_init(int bus_id); +int fpga_i2c_controller_cleanup(int bus_id); +int fpga_i2c_init(uint8_t *base_addr); +void fpga_i2c_deinit(void); +int fpga_i2c_oneshot(bf_fpga_i2c_t *i2c_op); +int fpga_i2c_pr_add(bf_fpga_i2c_t *i2c_op); +int fpga_i2c_del(bf_fpga_i2c_t *i2c_op); +int fpga_i2c_data_read( + int bus_id, int inst_id, uint8_t offset, uint8_t len, uint8_t *buf); +bool fpga_i2c_is_inited(void); + +#ifdef __cplusplus +} +#endif /* C++ */ + +#endif /* _BF_FPGA_I2C_H */ diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_ctrl.c b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_ctrl.c new file mode 100644 index 000000000000..a8837ba3b60c --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_ctrl.c @@ -0,0 +1,397 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 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 + +*******************************************************************************/ +#include +#include "bf_fpga_i2c_priv_porting.h" +#include +#include "bf_fpga_i2c.h" +#include "bf_fpga_i2c_priv.h" +#include "bf_fpga_i2c_reg.h" + +/* static i2c controller contents */ +static fpga_i2c_controller_t fpga_i2c_ctrl[BF_I2C_FPGA_NUM_CTRL]; +static bool fpga_i2c_inited = false; + +/* fpga memory space access APIs */ +/* 32 bit write into fpga BAR0 */ +void bf_fpga_reg_write(fpga_i2c_controller_t *i2c_ctrl, + uint32_t offset, + uint32_t val) { + uint8_t *ptr = i2c_ctrl->fpga_base_addr + offset; + bf_fpga_write32(ptr, val); +} + +/* 32 bit read into fpga BAR0 */ +uint32_t bf_fpga_reg_read(fpga_i2c_controller_t *i2c_ctrl, uint32_t offset) { + uint8_t *ptr = i2c_ctrl->fpga_base_addr + offset; + return (bf_fpga_read32(ptr)); +} + +/* 32 bit write into fpga i2c space */ +void bf_fpga_i2c_reg_write32(fpga_i2c_controller_t *i2c_ctrl, + uint32_t offset, + uint32_t val) { + uint8_t *ptr = i2c_ctrl->i2c_base_addr + offset; + bf_fpga_write32(ptr, val); +} + +/* 32 bit read into fpga i2c space */ +uint32_t bf_fpga_i2c_reg_read32(fpga_i2c_controller_t *i2c_ctrl, + uint32_t offset) { + uint8_t *ptr = i2c_ctrl->i2c_base_addr + offset; + return (bf_fpga_read32(ptr)); +} + +/* 8 bit write into fpga i2c space */ +void bf_fpga_i2c_reg_write8(fpga_i2c_controller_t *i2c_ctrl, + uint32_t offset, + uint8_t val) { + uint8_t *ptr = i2c_ctrl->i2c_base_addr + offset; + bf_fpga_write8(ptr, val); +} + +/* 8 bit read into fpga i2c space */ +uint8_t bf_fpga_i2c_reg_read8(fpga_i2c_controller_t *i2c_ctrl, + uint32_t offset) { + uint8_t *ptr = i2c_ctrl->i2c_base_addr + offset; + return (bf_fpga_read8(ptr)); +} + +int bf_fpga_i2c_lock(fpga_i2c_controller_t *i2c_ctrl) { + return (bf_fpga_cr_enter(&i2c_ctrl->fpga_ctrl_lock)); +} + +void bf_fpga_i2c_unlock(fpga_i2c_controller_t *i2c_ctrl) { + return (bf_fpga_cr_leave(&i2c_ctrl->fpga_ctrl_lock)); +} + +/** FPGA return pointer to i2c_controller struct + * + * @param bus_id + * i2c controller id + * @return + * pointer to i2c_controller struct of + */ +fpga_i2c_controller_t *fpga_i2c_ctrl_get(int bus_id) { + if (bus_id >= BF_I2C_FPGA_NUM_CTRL) { + return NULL; + } else { + return &fpga_i2c_ctrl[bus_id]; + } +} + +/* is fpga module is soft inited */ +bool fpga_i2c_is_inited() { return fpga_i2c_inited; } + +/** FPGA I2C set clock: sets clock of i2c operations + * + * controller must be stopped before, if applicable. + * + * @param bus_id + * i2c controller id + * @param clk_div + * clock divider value as per fpga specs + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_set_clk(int bus_id, int clk_div) { + uint32_t val; + fpga_i2c_controller_t *i2c_ctrl; + + if (bus_id >= BF_I2C_FPGA_NUM_CTRL) { + return BF_FPGA_EINVAL; + } + i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + if (bf_fpga_i2c_lock(i2c_ctrl)) { + return BF_FPGA_EAGAIN; + } + clk_div = (clk_div & I2C_CTRL_CLK_DIV_MASK) << I2C_CTRL_CLK_DIV_SHF; + val = bf_fpga_i2c_reg_read32(i2c_ctrl, Bf_FPGA_I2C_CTRL_TOP); + val &= ~(I2C_CTRL_CLK_DIV_MASK << I2C_CTRL_CLK_DIV_SHF); + val |= clk_div; + bf_fpga_i2c_reg_write32(i2c_ctrl, Bf_FPGA_I2C_CTRL_TOP, val); + bf_fpga_i2c_unlock(i2c_ctrl); + return BF_FPGA_OK; +} + +/** FPGA I2C stop : stops ongoing i2c operations without mutex locking + * + * internal function + * + * @param bus_id + * i2c controller struct + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_stop_locked(fpga_i2c_controller_t *i2c_ctrl) { + int to_ms, ret; + uint8_t val; + + val = bf_fpga_i2c_reg_read8(i2c_ctrl, Bf_FPGA_I2C_CTRL_TOP); + val &= ~I2C_CTRL_START; + bf_fpga_i2c_reg_write8(i2c_ctrl, Bf_FPGA_I2C_CTRL_TOP, val); + + to_ms = 100; /* 5 msec converted to multiple of 50 micro sec */ + val = bf_fpga_i2c_reg_read8(i2c_ctrl, Bf_FPGA_TOP_I2C_STATUS); + while ((val & I2C_STS_BUSY) && to_ms) { + bf_fpga_us_delay(50); + to_ms--; + val = bf_fpga_i2c_reg_read8(i2c_ctrl, Bf_FPGA_TOP_I2C_STATUS); + } + if (to_ms > 0) { + ret = BF_FPGA_OK; + } else { + ret = BF_FPGA_EIO; + } + return ret; +} + +/** FPGA I2C start : starts i2c operations without mutex locking + * + * internal function + * + * @param bus_id + * i2c controller struct + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_start_locked(fpga_i2c_controller_t *i2c_ctrl) { + uint8_t val; + val = bf_fpga_i2c_reg_read8(i2c_ctrl, Bf_FPGA_I2C_CTRL_TOP); + bf_fpga_i2c_reg_write8(i2c_ctrl, Bf_FPGA_I2C_CTRL_TOP, val | I2C_CTRL_START); + return BF_FPGA_OK; +} + +/** FPGA I2C stop : stops ongoing i2c operations + * + * @param bus_id + * i2c controller id + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_stop(int bus_id) { + fpga_i2c_controller_t *i2c_ctrl; + int ret; + + if (bus_id >= BF_I2C_FPGA_NUM_CTRL || !fpga_i2c_is_inited()) { + return BF_FPGA_EINVAL; + } + i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + if (bf_fpga_i2c_lock(i2c_ctrl)) { + return BF_FPGA_EAGAIN; + } + ret = fpga_i2c_stop_locked(i2c_ctrl); + bf_fpga_i2c_unlock(i2c_ctrl); + return ret; +} + +/** FPGA I2C start : starts i2c operations + * + * @param bus_id + * i2c controller id + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_start(int bus_id) { + fpga_i2c_controller_t *i2c_ctrl; + int ret; + + if (bus_id >= BF_I2C_FPGA_NUM_CTRL || !fpga_i2c_is_inited()) { + return BF_FPGA_EINVAL; + } + i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + if (bf_fpga_i2c_lock(i2c_ctrl)) { + return BF_FPGA_EAGAIN; + } + ret = fpga_i2c_start_locked(i2c_ctrl); + bf_fpga_i2c_unlock(i2c_ctrl); + return ret; +} + +/** FPGA I2C reset: reset i2c by issuing 9 clocks in a specific way + * + * @param bus_id + * i2c controller id + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_reset(int bus_id) { + fpga_i2c_controller_t *i2c_ctrl; + + if (bus_id >= BF_I2C_FPGA_NUM_CTRL || !fpga_i2c_is_inited()) { + return BF_FPGA_EINVAL; + } + i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + if (bf_fpga_i2c_lock(i2c_ctrl)) { + return BF_FPGA_EAGAIN; + } + bf_fpga_i2c_reg_write8(i2c_ctrl, Bf_FPGA_I2C_CTRL_TOP, I2C_CTRL_RESET); + bf_fpga_i2c_unlock(i2c_ctrl); + return BF_FPGA_OK; +} + +/** FPGA I2C is running? + * + * @param bus_id + * i2c controller id + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_is_busy(int bus_id, bool *busy) { + uint8_t val; + fpga_i2c_controller_t *i2c_ctrl; + + if (bus_id >= BF_I2C_FPGA_NUM_CTRL || !fpga_i2c_is_inited()) { + return BF_FPGA_EINVAL; + } + i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + if (bf_fpga_i2c_lock(i2c_ctrl)) { + return BF_FPGA_EAGAIN; + } + val = bf_fpga_i2c_reg_read8(i2c_ctrl, Bf_FPGA_TOP_I2C_STATUS); + *busy = ((val & I2C_STS_BUSY) ? true : false); + bf_fpga_i2c_unlock(i2c_ctrl); + return BF_FPGA_OK; +} + +/** FPGA I2C instruction enable/disable + * + * enable or disable a particular instruction in i2c instruction memory + * @param bus_id + * i2c controller id + * @param inst_id + * instruction id within this controller space + * @param en + * true for enable, false for disable + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_inst_en(int bus_id, int inst_id, bool en) { + uint32_t val; + fpga_i2c_controller_t *i2c_ctrl; + + if (bus_id >= BF_I2C_FPGA_NUM_CTRL || !fpga_i2c_is_inited()) { + return BF_FPGA_EINVAL; + } + if (inst_id < 0 || inst_id >= FPGA_I2C_NUM_INST) { + return BF_FPGA_EINVAL; + } + i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + if (bf_fpga_i2c_lock(i2c_ctrl)) { + return BF_FPGA_EAGAIN; + } + val = bf_fpga_i2c_reg_read32(i2c_ctrl, Bf_FPGA_I2C_INST_CTRL(inst_id)); + if (en) { + val |= I2C_INST_EN; + } else { + val &= ~I2C_INST_EN; + } + bf_fpga_i2c_reg_write32(i2c_ctrl, Bf_FPGA_I2C_INST_CTRL(inst_id), val); + fpga_i2c_ctrl[bus_id].i2c_inst[inst_id].en = en; + bf_fpga_i2c_unlock(i2c_ctrl); + return BF_FPGA_OK; +} + +/** FPGA I2C controller initialization + * + * @param bus_id + * i2c controller id + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_controller_init(int bus_id) { + fpga_i2c_controller_t *i2c_ctrl; + int i, ret; + + if (bus_id >= BF_I2C_FPGA_NUM_CTRL) { + return BF_FPGA_EINVAL; + } + i2c_ctrl = fpga_i2c_ctrl_get(bus_id); + if (!i2c_ctrl) { + return BF_FPGA_EINVAL; + } + bf_fpga_fast_lock_init(&i2c_ctrl->spinlock, 0); + bf_fpga_cr_init(&i2c_ctrl->fpga_ctrl_lock); + bf_fpga_cr_enter(&i2c_ctrl->fpga_ctrl_lock); + for (i = 0; i < FPGA_I2C_NUM_INST; i++) { + fpga_i2c_ctrl[bus_id].i2c_inst[i].inst = (uint32_t)i; + bf_fpga_i2c_reg_write32(i2c_ctrl, Bf_FPGA_I2C_INST_CTRL(i), 0); + } + bf_fpga_cr_leave(&i2c_ctrl->fpga_ctrl_lock); + ret = fpga_i2c_set_clk(bus_id, 1); /* 400 khz default */ + ret |= fpga_i2c_stop(bus_id); /* just in case */ + return ret; +} + +/** FPGA I2C controller de initialization + * + * @param bus_id + * i2c controller id + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_controller_cleanup(int bus_id) { + int i; + + fpga_i2c_stop(bus_id); + for (i = 0; i < FPGA_I2C_NUM_INST; i++) { + fpga_i2c_ctrl[bus_id].i2c_inst[i].en = false; + } + bf_fpga_cr_destroy(&fpga_i2c_ctrl[bus_id].fpga_ctrl_lock); + bf_fpga_fast_lock_destroy(&fpga_i2c_ctrl[bus_id].spinlock); + return BF_FPGA_OK; +} + +/** FPGA I2C global initialization + * + * @param base_addr + * virtual address of i2c memory relative to BAR0 base + * @return + * 0 on success and <0 on error + */ +int fpga_i2c_init(uint8_t *base_addr) { + int i; + + memset(fpga_i2c_ctrl, 0, sizeof(fpga_i2c_ctrl)); + for (i = 0; i < BF_I2C_FPGA_NUM_CTRL; i++) { + fpga_i2c_ctrl[i].i2c_base_addr = base_addr + BF_FPGA_I2C_CTRL_BASE_ADDR(i); + fpga_i2c_ctrl[i].fpga_base_addr = base_addr; + fpga_i2c_controller_init(i); + } + fpga_i2c_inited = true; + return BF_FPGA_OK; +} + +/** FPGA I2C global de initialization + * + */ +void fpga_i2c_deinit(void) { + int i; + + for (i = 0; i < BF_I2C_FPGA_NUM_CTRL; i++) { + fpga_i2c_controller_cleanup(i); + } + fpga_i2c_inited = false; +} diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_porting.c b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_porting.c new file mode 100644 index 000000000000..8b126c2e6dce --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_porting.c @@ -0,0 +1,150 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 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 + +*******************************************************************************/ +#include +#include +#include +#include +#include +#include "bf_fpga_i2c_priv_porting.h" +#include +#include "bf_fpga_i2c.h" +#include "bf_fpga_i2c_priv.h" + +/* This file contains OS and system specific porting functions for i2c APIs. + * Implementation in this file is for porting to linux kernel. + */ +/* mutex APIs are for mutual exclusion with capability to sleep while in + * exclusion mode + */ + +/* sleepable virtual exclusion region */ +typedef struct { + atomic_t lock_state; /* 1: in exclusion mode, 0: not in exclusion mode */ +} sleepable_v_mutex_t; + +int bf_fpga_cr_init(bf_fpga_mutex_t *lock) { + sleepable_v_mutex_t *mtx; + + if (!lock) { + return -1; + } + mtx = vzalloc(sizeof(sleepable_v_mutex_t)); + + if (mtx) { + atomic_set(&mtx->lock_state, 0); + *lock = (bf_fpga_mutex_t *)mtx; + return 0; + } else { + *lock = NULL; + return -1; + } +} + +void bf_fpga_cr_destroy(bf_fpga_mutex_t *lock) { + if (lock && *lock) { + vfree(*lock); + *lock = NULL; + } +} + +void bf_fpga_cr_leave(bf_fpga_mutex_t *lock) { + sleepable_v_mutex_t *mtx; + + if (lock && *lock) { + mtx = (sleepable_v_mutex_t *)*lock; + atomic_xchg(&mtx->lock_state, 0); + } +} + +int bf_fpga_cr_enter(bf_fpga_mutex_t *lock) { + sleepable_v_mutex_t *mtx; + + /* All we do here is: test and set */ + if (lock && *lock) { + int cnt = 10000; /* This will provide maximum of 500-1000 ms timeout */ + mtx = (sleepable_v_mutex_t *)*lock; + while (atomic_cmpxchg(&mtx->lock_state, 0, 1) != 0) { + if (cnt-- <= 0) { + return -1; /* this is a worst case timeout situation */ + } + usleep_range(50, 100); /* 50 us = about 2 bytes at 400Kbs i2c */ + } + return 0; + } else { + return -1; + } +} + +/* **** not implemented in current mode of locking */ +int bf_fpga_mutex_trylock(bf_fpga_mutex_t *lock) { + if (lock && *lock) { + return -1; + } else { + return -1; + } +} + +/* fast lock is a non-blocking busy lock, implemented with spinlock */ +int bf_fpga_fast_lock_init(bf_fpga_fast_lock_t *sl, unsigned int initial) { + spinlock_t *slock; + + (void)initial; + if (!sl) { + return -1; + } + slock = vzalloc(sizeof(spinlock_t)); + + if (slock) { + spin_lock_init(slock); + *sl = (bf_fpga_fast_lock_t *)slock; + return 0; + } else { + *sl = NULL; + return -1; + } +} + +void bf_fpga_fast_lock_destroy(bf_fpga_fast_lock_t *sl) { + if (sl && *sl) { + vfree(*sl); + *sl = NULL; + } +} + +int bf_fpga_fast_lock(bf_fpga_fast_lock_t *sl) { + if (sl && *sl) { + spin_lock(*sl); + return 0; + } else { + return -1; + } +} + +void bf_fpga_fast_unlock(bf_fpga_fast_lock_t *sl) { + if (sl && *sl) { + spin_unlock(*sl); + } +} diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_priv.h b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_priv.h new file mode 100644 index 000000000000..0b3b1e47b015 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_priv.h @@ -0,0 +1,104 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 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_FPGA_I2C_PRIV_H +#define _BF_FPGA_I2C_PRIV_H + +/* Allow the use in C++ code. */ +#ifdef __cplusplus +extern "C" { +#endif + +#define FPGA_I2C_INST_OFFSET(idx) (0x10 + (16 * idx)) + +typedef enum { + FGPA_I2C_NOP = 0x0, + FGPA_I2C_WR_ADDR_DATA = 0x1, /* wr: reg_addr, wr: data */ + FGPA_I2C_WR_ADDR_RD_DATA = 0x2, /* wr: reg_addrss, r/s, rd: data */ + FGPA_I2C_WR_ADDR = 0x3, /* wr: reg_addr */ + FGPA_I2C_RD_DATA = 0x4, /* rd: data */ + FGPA_I2C_MULTI_WR_RD = 0x5 /* wr: n bytes, r/s, rd: m bytes */ +} i2c_cmd_type; + +/* contents of each instruction instance */ +typedef struct i2c_inst_cmd_s { + i2c_cmd_type i2c_cmd; /* i2x cycle type */ + uint32_t data_lo; /* lower 4 bytes of data associated with this inst */ + uint32_t data_hi; /* upper 4 bytes of data associated with this inst */ + uint32_t us_delay; /* delay before i2c cycle */ + uint8_t i2c_addr; /* i2c device address, in 7 bit format */ + uint8_t reg_addr; /* 1st write byte, if present in i2c cycle */ + uint8_t num_read; /* number of bytes to write excluding reg_addr */ + uint8_t num_write; /* number of bytes to read */ +} i2c_inst_cmd_t; + +/* attributes of each instruction instance */ +typedef struct i2c_inst_s { + uint32_t inst; /* index of the instruction within the controller memory */ + bool en; /* is instruction enabled */ + bool preemt; /* atomically execute next instruction */ + bool int_en; /* enable interrupt after execution */ + bool in_use; /* is this instruction currently used */ +} i2c_inst_t; + +typedef struct fpga_i2c_controller_s { + bf_fpga_mutex_t fpga_ctrl_lock; + bf_fpga_fast_lock_t spinlock; + uint8_t *fpga_base_addr; /* virtual address of start of fpga memory */ + uint8_t *i2c_base_addr; /* virtual address of i2c controller memory */ + uint32_t start; /* offset of start of i2c instruction memory */ + uint32_t len; /* number of i2c instructions belonging to this i2c engine */ + uint32_t clk_div; /* clock divider used by this i2c engine */ + bool int_en; + i2c_inst_t i2c_inst[FPGA_I2C_NUM_INST]; +} fpga_i2c_controller_t; + +fpga_i2c_controller_t *fpga_i2c_ctrl_get(int bus_id); +void bf_fpga_reg_write(fpga_i2c_controller_t *i2c_ctrl, + uint32_t offset, + uint32_t val); +uint32_t bf_fpga_reg_read(fpga_i2c_controller_t *i2c_ctrl, uint32_t offset); +void bf_fpga_i2c_reg_write32(fpga_i2c_controller_t *i2c_ctrl, + uint32_t offset, + uint32_t val); +uint32_t bf_fpga_i2c_reg_read32(fpga_i2c_controller_t *i2c_ctrl, + uint32_t offset); +void bf_fpga_i2c_reg_write8(fpga_i2c_controller_t *i2c_ctrl, + uint32_t offset, + uint8_t val); +uint8_t bf_fpga_i2c_reg_read8(fpga_i2c_controller_t *i2c_ctrl, uint32_t offset); + +int bf_fpga_i2c_lock(fpga_i2c_controller_t *i2c_ctrl); + +void bf_fpga_i2c_unlock(fpga_i2c_controller_t *i2c_ctrl); + +int fpga_i2c_start_locked(fpga_i2c_controller_t *i2c_ctrl); +int fpga_i2c_stop_locked(fpga_i2c_controller_t *i2c_ctrl); + +#ifdef __cplusplus +} +#endif /* C++ */ + +#endif /* _BF_FPGA_I2C_PRIV_H */ diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_priv_porting.h b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_priv_porting.h new file mode 100644 index 000000000000..adea5c9311fa --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_priv_porting.h @@ -0,0 +1,93 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 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_FPGA_I2C_PRIV_PORTING_H +#define _BF_FPGA_I2C_PRIV_PORTING_H + +/* Allow the use in C++ code. */ +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* This file contains OS and system specific porting functions declarations. + */ +/* return status compliant with linux system calls */ +#define BF_FPGA_OK 0 +#define BF_FPGA_EINVAL (-EINVAL) +#define BF_FPGA_EIO (-EIO) +#define BF_FPGA_EBUSY (-EBUSY) +#define BF_FPGA_EAGAIN (-EAGAIN) + +/* pci memory access functions */ +static inline void bf_fpga_write32(uint8_t *addr, uint32_t val) { + u8 __iomem *reg_addr = addr; + writel(val, reg_addr); +} + +static inline uint32_t bf_fpga_read32(uint8_t *addr) { + u8 __iomem *reg_addr = addr; + return (readl(reg_addr)); +} + +static inline void bf_fpga_write8(uint8_t *addr, uint8_t val) { + u8 __iomem *reg_addr = addr; + writeb(val, reg_addr); +} + +static inline uint8_t bf_fpga_read8(uint8_t *addr) { + u8 __iomem *reg_addr = addr; + return (readb(reg_addr)); +} + +static inline void bf_fpga_us_delay(unsigned long usecs) { + usleep_range(usecs, usecs + 10); +} + +/* general purpose mutual exclusion lock */ +typedef void *bf_fpga_mutex_t; + +/* fast_lock for locking only non-blocking and quick operations */ +typedef void *bf_fpga_fast_lock_t; + +/* APIs to init/enter/leave critical (exclusive access) regions */ +int bf_fpga_cr_init(bf_fpga_mutex_t *lock); +void bf_fpga_cr_destroy(bf_fpga_mutex_t *lock); +int bf_fpga_cr_enter(bf_fpga_mutex_t *lock); +void bf_fpga_cr_leave(bf_fpga_mutex_t *lock); + +int bf_fpga_fast_lock_init(bf_fpga_fast_lock_t *sl, unsigned int initial); +void bf_fpga_fast_lock_destroy(bf_fpga_fast_lock_t *sl); +int bf_fpga_fast_lock(bf_fpga_fast_lock_t *sl); +void bf_fpga_fast_unlock(bf_fpga_fast_lock_t *sl); + +#ifdef __cplusplus +} +#endif /* C++ */ + +#endif /* _BF_FPGA_I2C_PRIV_PORTING_H */ diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_reg.h b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_reg.h new file mode 100644 index 000000000000..9ad9b31b3b3f --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/modules/i2c/bf_fpga_i2c_reg.h @@ -0,0 +1,116 @@ +/******************************************************************************* + Barefoot Networks FPGA Linux driver + Copyright(c) 2018 - 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_FPGA_I2C_REG_H +#define _BF_FPGA_I2C_REG_H + +/* Allow the use in C++ code. */ +#ifdef __cplusplus +extern "C" { +#endif + +/* registers outsize of all i2c controller register space */ +#define BF_FPGA_I2C_BASE_ADDR 0x0 +#define BF_FPGA_I2C_CTRL_BASE_ADDR(i) (BF_FPGA_I2C_BASE_ADDR + (i * 4096)) + +/* per i2c controller register offset relative to BF_FPGA_I2C_CTRL_BASE_ADDR */ +#define Bf_FPGA_I2C_CTRL_TOP 0 +#define I2C_CTRL_START (1 << 0) +#define I2C_CTRL_RESET (1 << 1) +#define I2C_CTRL_CLK_DIV_SHF (8) +#define I2C_CTRL_CLK_DIV_MASK (0x1FF) + +#define Bf_FPGA_TOP_I2C_STATUS 4 +#define I2C_STS_BUSY (1 << 0) +#define I2C_STS_ERR (1 << 3) + +#define Bf_FPGA_I2C_INST_CTRL(i) (0x10 + (16 * i)) +#define I2C_INST_EN (1 << 31) +#define I2C_INST_PMT (1 << 30) +#define I2C_TYPE_SHF (26) +#define I2C_DELAY_SHF (23) +#define I2C_STOP_ON_ERROR (22) +/* various status values */ +#define I2C_STATUS_MASK 0x3F +#define I2C_STATUS_ERR_MASK 0x3C +#define I2C_STATUS_RUNNING 0x1 +#define I2C_STATUS_COMPLETED 0x2 +#define I2C_STATUS_NACK_ADDR 0x4 +#define I2C_STATUS_NACK_CMD 0x8 +#define I2C_STATUS_NACK_WR_DATA 0x10 +#define I2C_STATUS_TOUT 0x20 + +/* i2c instruction types */ +#define I2C_WR_ADDR_DATA (0 << I2C_TYPE_SHF) +#define I2C_RD_DATA (3 << I2C_TYPE_SHF) +#define I2C_WR_ADDR (2 << I2C_TYPE_SHF) +#define I2C_RD_ADDR_DATA (1 << I2C_TYPE_SHF) +#define I2C_RD_ADDR_DATA_BURST (4 << I2C_TYPE_SHF) +#define I2C_NOP (6 << I2C_TYPE_SHF) + +#define Bf_FPGA_I2C_INST_PARAM(i) (0x14 + (16 * i)) +#define I2C_DEV_ADDR_SHF (24) +#define I2C_CMD_OFFSET (16) +#define I2C_WR_CNT_SHF (8) +#define I2C_RD_CNT_SHF (0) + +#define Bf_FPGA_I2C_INST_DATA_LO(i) (0x18 + (16 * i)) +#define Bf_FPGA_I2C_INST_DATA_HI(i) (0x1C + (16 * i)) +/****************** +#define Bf_FPGA_I2C_PR_CTRL(i) (0x100 + (16 * i)) +#define Bf_FPGA_I2C_PR_PARM(i) (0x104 + (16 * i)) +#define Bf_FPGA_I2C_PR_LO(i) (0x108 + (16 * i)) +#define Bf_FPGA_I2C_PR_HI(i) (0x10C + (16 * i)) +******************/ + +/* data area pointers */ +/* the driver makes fixed static allocation of the available memory + * on per instruction basis + * allocate 128 bytes per one time instruction = total 0x780 bytes + * allocate 64 bytes per one periodic instruction = total 0x400 bytes + * FPGA_I2C_ONESHOT_NUM_INST -> comes from a header file that must be included + * before this file. + */ +#define BF_FPGA_ONE_MAX_BURST 128 +#define BF_FPGA_PR_MAX_BURST 64 +#define BF_FPGA_I2C_DATA_AREA(i) \ + ((i < FPGA_I2C_ONESHOT_NUM_INST) \ + ? (0x200 + (i * BF_FPGA_ONE_MAX_BURST)) \ + : (0x980 + ((i - FPGA_I2C_ONESHOT_NUM_INST) * BF_FPGA_PR_MAX_BURST))) + +#if BF_FPGA_I2C_DATA_AREA(FPGA_I2C_PERIODIC_NUM_INST) > 0x1000 +#error erroneous allocation of FPGA memory to i2c data area. Fix it! +#endif + +#define BF_FPGA_VER_REG 0x3F000 +#define BF_FPGA_BUILD_DATE 0x3F004 +#define BF_FPGA_RESET_CTRL_1 0x3F008 +#define BF_FPGA_RESET_CTRL_2 0x3F00C + +#ifdef __cplusplus +} +#endif /* C++ */ + +#endif /* _BF_FPGA_I2C_REG_H */ diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/bf-sfputil b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/bf-sfputil new file mode 100755 index 000000000000..3df67614e499 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/bf-sfputil @@ -0,0 +1,10 @@ +#!/bin/bash + +DOCKER_EXEC_FLAGS="i" + +# Determine whether stdout is on a terminal +if [ -t 1 ] ; then + DOCKER_EXEC_FLAGS+="t" +fi + +docker exec -$DOCKER_EXEC_FLAGS syncd sfputil "$@" diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/eeprom b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/eeprom new file mode 100755 index 000000000000..07d98556cbbf --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/eeprom @@ -0,0 +1,10 @@ +#!/bin/bash + +DOCKER_EXEC_FLAGS="i" + +# Determine whether stdout is on a terminal +if [ -t 1 ] ; then + DOCKER_EXEC_FLAGS+="t" +fi + +docker exec -$DOCKER_EXEC_FLAGS syncd eeprom "$@" diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/fancontrol b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/fancontrol new file mode 100755 index 000000000000..515fcbdd69da --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/fancontrol @@ -0,0 +1,11 @@ +#!/bin/bash + +DOCKER_EXEC_FLAGS="i" + +# Determine whether stdout is on a terminal +if [ -t 1 ] ; then + DOCKER_EXEC_FLAGS+="t" +fi + +docker exec -$DOCKER_EXEC_FLAGS syncd fancontrol "$@" + diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/ps_info b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/ps_info new file mode 100755 index 000000000000..38c9d3330414 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/ps_info @@ -0,0 +1,10 @@ +#!/bin/bash + +DOCKER_EXEC_FLAGS="i" + +# Determine whether stdout is on a terminal +if [ -t 1 ] ; then + DOCKER_EXEC_FLAGS+="t" +fi + +docker exec -$DOCKER_EXEC_FLAGS syncd ps_info "$@" diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/sensors b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/sensors new file mode 100755 index 000000000000..07af6955321e --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/sensors @@ -0,0 +1,12 @@ +#!/bin/bash + +DOCKER_EXEC_FLAGS="i" + +# Determine whether stdout is on a terminal +if [ -t 1 ] ; then + DOCKER_EXEC_FLAGS+="t" +fi + +docker exec -$DOCKER_EXEC_FLAGS syncd sensors "$@" + + diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/test b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/test new file mode 100755 index 000000000000..38327722c91f --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/scripts/test @@ -0,0 +1 @@ +echo "test" diff --git a/platform/broadcom/docker-syncd-brcm-rpc.mk b/platform/broadcom/docker-syncd-brcm-rpc.mk index bb31e82ef61d..bd2ef01c5eed 100644 --- a/platform/broadcom/docker-syncd-brcm-rpc.mk +++ b/platform/broadcom/docker-syncd-brcm-rpc.mk @@ -9,7 +9,7 @@ $(DOCKER_SYNCD_BRCM_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) endif -$(DOCKER_SYNCD_BRCM_RPC)_FILES += $(DSSERVE) $(BCMCMD) +$(DOCKER_SYNCD_BRCM_RPC)_FILES += $(DSSERVE) $(BCMCMD) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) $(DOCKER_SYNCD_BRCM_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BASE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_BRCM_RPC) SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BRCM_RPC) @@ -20,5 +20,10 @@ endif $(DOCKER_SYNCD_BRCM_RPC)_CONTAINER_NAME = syncd $(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += --net=host --privileged -t $(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf +$(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd $(DOCKER_SYNCD_BRCM_RPC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro + +$(DOCKER_SYNCD_BRCM_RPC)_BASE_IMAGE_FILES += bcmcmd:/usr/bin/bcmcmd +$(DOCKER_SYNCD_BRCM_RPC)_BASE_IMAGE_FILES += bcmsh:/usr/bin/bcmsh + diff --git a/platform/broadcom/docker-syncd-brcm-rpc/base_image_files/bcmcmd b/platform/broadcom/docker-syncd-brcm-rpc/base_image_files/bcmcmd new file mode 100755 index 000000000000..7903db6ed6a3 --- /dev/null +++ b/platform/broadcom/docker-syncd-brcm-rpc/base_image_files/bcmcmd @@ -0,0 +1,3 @@ +#!/bin/bash + +docker exec -i syncd bcmcmd "$@" diff --git a/platform/broadcom/docker-syncd-brcm-rpc/base_image_files/bcmsh b/platform/broadcom/docker-syncd-brcm-rpc/base_image_files/bcmsh new file mode 100755 index 000000000000..3bb78b0da796 --- /dev/null +++ b/platform/broadcom/docker-syncd-brcm-rpc/base_image_files/bcmsh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker exec -it syncd bcmsh "$@" diff --git a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 index 328f698fdb6d..b20e353f842f 100755 --- a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 +++ b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 @@ -26,6 +26,8 @@ COPY ["files/dsserve", "files/bcmcmd", "start.sh", "bcmsh", "/usr/bin/"] RUN chmod +x /usr/bin/dsserve /usr/bin/bcmcmd COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y diff --git a/platform/broadcom/docker-syncd-brcm/critical_processes b/platform/broadcom/docker-syncd-brcm/critical_processes new file mode 100644 index 000000000000..489668a89e08 --- /dev/null +++ b/platform/broadcom/docker-syncd-brcm/critical_processes @@ -0,0 +1,2 @@ +dsserve +syncd diff --git a/platform/broadcom/docker-syncd-brcm/supervisord.conf b/platform/broadcom/docker-syncd-brcm/supervisord.conf index a2e0743b1cf5..cd6712acbf22 100644 --- a/platform/broadcom/docker-syncd-brcm/supervisord.conf +++ b/platform/broadcom/docker-syncd-brcm/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index 0edb6ebc4f9a..8cbf72695920 100644 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -8,6 +8,7 @@ $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(DELL_Z9264F_PLATFORM_MODULE) \ $(DELL_S5232F_PLATFORM_MODULE) \ + $(DELL_S5248F_PLATFORM_MODULE) \ $(DELL_Z9100_PLATFORM_MODULE) \ $(DELL_S6100_PLATFORM_MODULE) \ $(INGRASYS_S8900_54XC_PLATFORM_MODULE) \ @@ -27,6 +28,7 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(ACCTON_AS4630_54PE_PLATFORM_MODULE) \ $(ACCTON_MINIPACK_PLATFORM_MODULE) \ $(ACCTON_AS5812_54X_PLATFORM_MODULE) \ + $(ACCTON_AS5812_54T_PLATFORM_MODULE) \ $(ACCTON_AS5835_54X_PLATFORM_MODULE) \ $(ACCTON_AS9716_32D_PLATFORM_MODULE) \ $(ACCTON_AS5835_54T_PLATFORM_MODULE) \ @@ -35,6 +37,7 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(INVENTEC_D7032Q28B_PLATFORM_MODULE) \ $(INVENTEC_D7054Q28B_PLATFORM_MODULE) \ $(INVENTEC_D7264Q28B_PLATFORM_MODULE) \ + $(INVENTEC_D6356_PLATFORM_MODULE) \ $(CEL_DX010_PLATFORM_MODULE) \ $(CEL_HALIBURTON_PLATFORM_MODULE) \ $(DELTA_AG9032V1_PLATFORM_MODULE) \ @@ -45,11 +48,14 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(QUANTA_IX7_32X_PLATFORM_MODULE) \ $(QUANTA_IX8_56X_PLATFORM_MODULE) \ $(QUANTA_IX8C_56X_PLATFORM_MODULE) \ + $(QUANTA_IX9_32X_PLATFORM_MODULE) \ $(MITAC_LY1200_32X_PLATFORM_MODULE) \ $(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE) \ $(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE) \ $(BRCM_XLR_GTS_PLATFORM_MODULE) \ - $(DELTA_AG9032V2A_PLATFORM_MODULE) + $(DELTA_AG9032V2A_PLATFORM_MODULE) \ + $(JUNIPER_QFX5210_PLATFORM_MODULE) \ + $(CEL_SILVERSTONE_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 37ef2669fbb4..bab9c5ef9fef 100755 --- a/platform/broadcom/platform-modules-accton.mk +++ b/platform/broadcom/platform-modules-accton.mk @@ -12,6 +12,7 @@ ACCTON_AS7726_32X_PLATFORM_MODULE_VERSION = 1.1 ACCTON_AS4630_54PE_PLATFORM_MODULE_VERSION = 1.1 ACCTON_MINIPACK_PLATFORM_MODULE_VERSION = 1.1 ACCTON_AS5812_54X_PLATFORM_MODULE_VERSION = 1.1 +ACCTON_AS5812_54T_PLATFORM_MODULE_VERSION = 1.1 ACCTON_AS5835_54X_PLATFORM_MODULE_VERSION = 1.1 ACCTON_AS9716_32D_PLATFORM_MODULE_VERSION = 1.1 ACCTON_AS5835_54T_PLATFORM_MODULE_VERSION = 1.1 @@ -30,6 +31,7 @@ export ACCTON_AS7726_32X_PLATFORM_MODULE_VERSION export ACCTON_AS4630_54PE_PLATFORM_MODULE_VERSION export ACCTON_MINIPACK_PLATFORM_MODULE_VERSION export ACCTON_AS5812_54X_PLATFORM_MODULE_VERSION +export ACCTON_AS5812_54T_PLATFORM_MODULE_VERSION export ACCTON_AS5835_54X_PLATFORM_MODULE_VERSION export ACCTON_AS9716_32D_PLATFORM_MODULE_VERSION export ACCTON_AS5835_54T_PLATFORM_MODULE_VERSION @@ -90,6 +92,10 @@ ACCTON_AS5812_54X_PLATFORM_MODULE = sonic-platform-accton-as5812-54x_$(ACCTON_AS $(ACCTON_AS5812_54X_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as5812_54x-r0 $(eval $(call add_extra_package,$(ACCTON_AS7712_32X_PLATFORM_MODULE),$(ACCTON_AS5812_54X_PLATFORM_MODULE))) +ACCTON_AS5812_54T_PLATFORM_MODULE = sonic-platform-accton-as5812-54t_$(ACCTON_AS5812_54T_PLATFORM_MODULE_VERSION)_amd64.deb +$(ACCTON_AS5812_54T_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as5812_54t-r0 +$(eval $(call add_extra_package,$(ACCTON_AS7712_32X_PLATFORM_MODULE),$(ACCTON_AS5812_54T_PLATFORM_MODULE))) + ACCTON_AS5835_54X_PLATFORM_MODULE = sonic-platform-accton-as5835-54x_$(ACCTON_AS5835_54X_PLATFORM_MODULE_VERSION)_amd64.deb $(ACCTON_AS5835_54X_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as5835_54x-r0 $(eval $(call add_extra_package,$(ACCTON_AS7712_32X_PLATFORM_MODULE),$(ACCTON_AS5835_54X_PLATFORM_MODULE))) diff --git a/platform/broadcom/platform-modules-cel.mk b/platform/broadcom/platform-modules-cel.mk index 1224faaa6750..b7371e3282de 100644 --- a/platform/broadcom/platform-modules-cel.mk +++ b/platform/broadcom/platform-modules-cel.mk @@ -2,9 +2,11 @@ CEL_DX010_PLATFORM_MODULE_VERSION = 0.9 CEL_HALIBURTON_PLATFORM_MODULE_VERSION = 0.9 +CEL_SILVERSTONE_PLATFORM_MODULE_VERSION = 0.9 export CEL_DX010_PLATFORM_MODULE_VERSION export CEL_HALIBURTON_PLATFORM_MODULE_VERSION +export CEL_SILVERSTONE_PLATFORM_MODULE_VERSION CEL_DX010_PLATFORM_MODULE = platform-modules-dx010_$(CEL_DX010_PLATFORM_MODULE_VERSION)_amd64.deb $(CEL_DX010_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cel @@ -16,4 +18,8 @@ CEL_HALIBURTON_PLATFORM_MODULE = platform-modules-haliburton_$(CEL_HALIBURTON_PL $(CEL_HALIBURTON_PLATFORM_MODULE)_PLATFORM = x86_64-cel_e1031-r0 $(eval $(call add_extra_package,$(CEL_DX010_PLATFORM_MODULE),$(CEL_HALIBURTON_PLATFORM_MODULE))) +CEL_SILVERSTONE_PLATFORM_MODULE = platform-modules-silverstone_$(CEL_SILVERSTONE_PLATFORM_MODULE_VERSION)_amd64.deb +$(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 1d0c41956bcf..583f74f72d8b 100644 --- a/platform/broadcom/platform-modules-dell.mk +++ b/platform/broadcom/platform-modules-dell.mk @@ -5,12 +5,14 @@ DELL_Z9100_PLATFORM_MODULE_VERSION = 1.1 DELL_S6100_PLATFORM_MODULE_VERSION = 1.1 DELL_Z9264F_PLATFORM_MODULE_VERSION = 1.1 DELL_S5232F_PLATFORM_MODULE_VERSION = 1.1 +DELL_S5248F_PLATFORM_MODULE_VERSION = 1.1 export DELL_S6000_PLATFORM_MODULE_VERSION export DELL_Z9100_PLATFORM_MODULE_VERSION export DELL_S6100_PLATFORM_MODULE_VERSION export DELL_Z9264F_PLATFORM_MODULE_VERSION export DELL_S5232F_PLATFORM_MODULE_VERSION +export DELL_S5248F_PLATFORM_MODULE_VERSION DELL_Z9100_PLATFORM_MODULE = platform-modules-z9100_$(DELL_Z9100_PLATFORM_MODULE_VERSION)_amd64.deb $(DELL_Z9100_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-dell @@ -35,4 +37,10 @@ DELL_S5232F_PLATFORM_MODULE = platform-modules-s5232f_$(DELL_S5232F_PLATFORM_MOD $(DELL_S5232F_PLATFORM_MODULE)_PLATFORM = x86_64-dellemc_s5232f_c3538-r0 $(eval $(call add_extra_package,$(DELL_Z9100_PLATFORM_MODULE),$(DELL_S5232F_PLATFORM_MODULE))) +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-inventec.mk b/platform/broadcom/platform-modules-inventec.mk index ead32e75a815..871604ce91d9 100644 --- a/platform/broadcom/platform-modules-inventec.mk +++ b/platform/broadcom/platform-modules-inventec.mk @@ -4,12 +4,14 @@ INVENTEC_D7032Q28B_PLATFORM_MODULE_VERSION = 1.1.0 INVENTEC_D7054Q28B_PLATFORM_MODULE_VERSION = 1.1.0 INVENTEC_D6254QS_PLATFORM_MODULE_VERSION = 1.1.0 INVENTEC_D6556_PLATFORM_MODULE_VERSION = 1.1.0 +INVENTEC_D6356_PLATFORM_MODULE_VERSION = 1.1.0 INVENTEC_D7264Q28B_PLATFORM_MODULE_VERSION = 1.1.0 export INVENTEC_D7032Q28B_PLATFORM_MODULE_VERSION export INVENTEC_D7054Q28B_PLATFORM_MODULE_VERSION export INVENTEC_D6254QS_PLATFORM_MODULE_VERSION export INVENTEC_D6556_PLATFORM_MODULE_VERSION +export INVENTEC_D6356_PLATFORM_MODULE_VERSION export INVENTEC_D7264Q28B_PLATFORM_MODULE_VERSION INVENTEC_D7032Q28B_PLATFORM_MODULE = platform-modules-d7032q28b_$(INVENTEC_D7032Q28B_PLATFORM_MODULE_VERSION)_amd64.deb @@ -30,8 +32,12 @@ INVENTEC_D6556_PLATFORM_MODULE = platform-modules-d6556_$(INVENTEC_D6556_PLATFOR $(INVENTEC_D6556_PLATFORM_MODULE)_PLATFORM = x86_64-inventec_d6556-r0 $(eval $(call add_extra_package,$(INVENTEC_D7032Q28B_PLATFORM_MODULE),$(INVENTEC_D6556_PLATFORM_MODULE))) +INVENTEC_D6356_PLATFORM_MODULE = platform-modules-d6356_$(INVENTEC_D6356_PLATFORM_MODULE_VERSION)_amd64.deb +$(INVENTEC_D6356_PLATFORM_MODULE)_PLATFORM = x86_64-inventec_d6356-r0 +$(eval $(call add_extra_package,$(INVENTEC_D7032Q28B_PLATFORM_MODULE),$(INVENTEC_D6356_PLATFORM_MODULE))) + INVENTEC_D7264Q28B_PLATFORM_MODULE = platform-modules-d7264q28b_$(INVENTEC_D7264Q28B_PLATFORM_MODULE_VERSION)_amd64.deb $(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) \ No newline at end of file +SONIC_STRETCH_DEBS += $(INVENTEC_D7032Q28B_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-juniper.mk b/platform/broadcom/platform-modules-juniper.mk new file mode 100755 index 000000000000..083dabda6d97 --- /dev/null +++ b/platform/broadcom/platform-modules-juniper.mk @@ -0,0 +1,13 @@ +# Juniper Platform modules + +JUNIPER_QFX5210_PLATFORM_MODULE_VERSION = 1.1 + +export JUNIPER_QFX5210_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 +$(JUNIPER_QFX5210_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(JUNIPER_QFX5210_PLATFORM_MODULE)_PLATFORM = x86_64-juniper_qfx5210-r0 +SONIC_DPKG_DEBS += $(JUNIPER_QFX5210_PLATFORM_MODULE) + +SONIC_STRETCH_DEBS += $(JUNIPER_QFX5210_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-quanta.mk b/platform/broadcom/platform-modules-quanta.mk index 93cf7b4d9d7f..456af3019e38 100644 --- a/platform/broadcom/platform-modules-quanta.mk +++ b/platform/broadcom/platform-modules-quanta.mk @@ -4,11 +4,13 @@ QUANTA_IX1B_32X_PLATFORM_MODULE_VERSION = 1.0 QUANTA_IX7_32X_PLATFORM_MODULE_VERSION = 1.0 QUANTA_IX8_56X_PLATFORM_MODULE_VERSION = 1.0 QUANTA_IX8C_56X_PLATFORM_MODULE_VERSION = 1.0 +QUANTA_IX9_32X_PLATFORM_MODULE_VERSION = 1.0 export QUANTA_IX1B_32X_PLATFORM_MODULE_VERSION export QUANTA_IX7_32X_PLATFORM_MODULE_VERSION export QUANTA_IX8_56X_PLATFORM_MODULE_VERSION export QUANTA_IX8C_56X_PLATFORM_MODULE_VERSION +export QUANTA_IX9_32X_PLATFORM_MODULE_VERSION QUANTA_IX1B_32X_PLATFORM_MODULE = sonic-platform-quanta-ix1b-32x_$(QUANTA_IX1B_32X_PLATFORM_MODULE_VERSION)_amd64.deb $(QUANTA_IX1B_32X_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-quanta @@ -28,4 +30,8 @@ QUANTA_IX8C_56X_PLATFORM_MODULE = sonic-platform-quanta-ix8c-56x_$(QUANTA_IX8C_5 $(QUANTA_IX8C_56X_PLATFORM_MODULE)_PLATFORM = x86_64-quanta_ix8c_bwde-r0 $(eval $(call add_extra_package,$(QUANTA_IX1B_32X_PLATFORM_MODULE),$(QUANTA_IX8C_56X_PLATFORM_MODULE))) +QUANTA_IX9_32X_PLATFORM_MODULE = sonic-platform-quanta-ix9-32x_$(QUANTA_IX9_32X_PLATFORM_MODULE_VERSION)_amd64.deb +$(QUANTA_IX9_32X_PLATFORM_MODULE)_PLATFORM = x86_64-quanta_ix9_bwde-r0 +$(eval $(call add_extra_package,$(QUANTA_IX1B_32X_PLATFORM_MODULE),$(QUANTA_IX9_32X_PLATFORM_MODULE))) + SONIC_STRETCH_DEBS += $(QUANTA_IX1B_32X_PLATFORM_MODULE) diff --git a/platform/broadcom/rules.mk b/platform/broadcom/rules.mk index 884a50a1ac0d..8dd7b2c8cbb2 100644 --- a/platform/broadcom/rules.mk +++ b/platform/broadcom/rules.mk @@ -10,6 +10,7 @@ include $(PLATFORM_PATH)/platform-modules-cel.mk include $(PLATFORM_PATH)/platform-modules-delta.mk include $(PLATFORM_PATH)/platform-modules-quanta.mk #include $(PLATFORM_PATH)/platform-modules-mitac.mk +include $(PLATFORM_PATH)/platform-modules-juniper.mk include $(PLATFORM_PATH)/platform-modules-brcm-xlr-gts.mk include $(PLATFORM_PATH)/docker-syncd-brcm.mk include $(PLATFORM_PATH)/docker-syncd-brcm-rpc.mk diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 28fdf57577c9..833c22f6bb94 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.5.2.3_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm_3.5.2.3_amd64.deb?sv=2015-04-05&sr=b&sig=anY6TeLouYsw7L6hfpH%2BTHOkvF8M3WR%2B6P2C7Dh8sHg%3D&se=2033-02-20T17%3A19%3A46Z&sp=r" +BRCM_SAI = libsaibcm_3.5.3.1m-25_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm_3.5.3.1m-26_amd64.deb?sv=2015-04-05&sr=b&sig=zo83IKnlT7goymXwynW8%2Fx6rR2eIh0AiIS%2BSrSMUhRE%3D&se=2033-07-21T18%3A50%3A27Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.5.2.3_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.5.3.1m-25_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.5/libsaibcm-dev_3.5.2.3_amd64.deb?sv=2015-04-05&sr=b&sig=o%2BVIKwVnlNv8LAvVzcS2kIXc0%2BIKaTzmA8LIkIfsh6c%3D&se=2033-02-20T17%3A20%3A03Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm-dev_3.5.3.1m-26_amd64.deb?sv=2015-04-05&sr=b&sig=tQmkCIy2mnb9rH7B9oXFUZDwijMGXWnVtta2CNTMbFM%3D&se=2033-07-21T18%3A50%3A47Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py index ca0f3f9da1e3..df2e511adef7 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py @@ -1,251 +1,90 @@ #!/usr/bin/env python +# Copyright (c) 2019 Edgecore Networks Corporation # -# Copyright (C) 2017 Accton Technology Corporation +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 # -# This program is free software: you can 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 CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - # ------------------------------------------------------------------ # HISTORY: # mm/dd/yyyy (A.D.) -# 11/13/2017: Polly Hsu, Create -# 1/10/2018: Jostar modify for as7716_32 -# 12/03/2018: Jostar modify for as7726_32 +# 10/24/2019:Jostar craete for as4630_54pe # ------------------------------------------------------------------ try: + import os import time import logging + import glob + import commands from collections import namedtuple except ImportError as e: raise ImportError('%s - required module not found' % str(e)) - -class FanUtil(object): - """Platform-specific FanUtil class""" - - FAN_NUM_ON_MAIN_BROAD = 6 - FAN_NUM_1_IDX = 1 - FAN_NUM_2_IDX = 2 - FAN_NUM_3_IDX = 3 - FAN_NUM_4_IDX = 4 - FAN_NUM_5_IDX = 5 - FAN_NUM_6_IDX = 6 - - FAN_NODE_NUM_OF_MAP = 2 - FAN_NODE_FAULT_IDX_OF_MAP = 1 - FAN_NODE_DIR_IDX_OF_MAP = 2 +class ThermalUtil(object): + """Platform-specific ThermalUtil class""" + THERMAL_NUM_MAX = 4 + THERMAL_NUM_1_IDX = 1 + THERMAL_NUM_2_IDX = 2 + THERMAL_NUM_3_IDX = 3 + THERMAL_NUM_4_IDX = 4 - BASE_VAL_PATH = '/sys/bus/i2c/devices/54-0066/{0}' - FAN_DUTY_PATH = '/sys/bus/i2c/devices/54-0066/fan_duty_cycle_percentage' - - #logfile = '' - #loglevel = logging.INFO - """ Dictionary where - key1 = fan id index (integer) starting from 1 - key2 = fan node index (interger) starting from 1 + key1 = thermal id index (integer) starting from 1 value = path to fan device file (string) """ - _fan_to_device_path_mapping = {} - -#fan1_direction -#fan1_fault -#fan1_present - - #(FAN_NUM_2_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan2_duty_cycle_percentage', - _fan_to_device_node_mapping = { - (FAN_NUM_1_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan1_fault', - (FAN_NUM_1_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan1_direction', - - (FAN_NUM_2_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan2_fault', - (FAN_NUM_2_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan2_direction', - - (FAN_NUM_3_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan3_fault', - (FAN_NUM_3_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan3_direction', - - (FAN_NUM_4_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan4_fault', - (FAN_NUM_4_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan4_direction', - - (FAN_NUM_5_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan5_fault', - (FAN_NUM_5_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan5_direction', + + thermal_sysfspath ={ + THERMAL_NUM_1_IDX: ["/sys/bus/i2c/devices/14-0048/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_2_IDX: ["/sys/bus/i2c/devices/24-004b/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_3_IDX: ["/sys/bus/i2c/devices/25-004a/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_4_IDX: ["/sys/class/hwmon/hwmon1/temp1_input"], + } - (FAN_NUM_6_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan6_fault', - (FAN_NUM_6_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan6_direction', - } - - def _get_fan_to_device_node(self, fan_num, node_num): - return self._fan_to_device_node_mapping[(fan_num, node_num)] - - def _get_fan_node_val(self, fan_num, node_num): - if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: - logging.debug('GET. Parameter error. fan_num:%d', fan_num) + def _get_thermal_val(self, thermal_num): + if thermal_num < self.THERMAL_NUM_1_IDX or thermal_num > self.THERMAL_NUM_MAX: + logging.debug('GET. Parameter error. thermal_num, %d', thermal_num) return None - - if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: - logging.debug('GET. Parameter error. node_num:%d', node_num) - return None - - device_path = self.get_fan_to_device_path(fan_num, node_num) - try: - val_file = open(device_path, 'r') - except IOError as e: - logging.error('GET. unable to open file: %s', str(e)) - return None - - content = val_file.readline().rstrip() - - if content == '': - logging.debug('GET. content is NULL. device_path:%s', device_path) - return None - - try: - val_file.close() - except: - logging.debug('GET. unable to close file. device_path:%s', device_path) - return None - - return int(content) - - def _set_fan_node_val(self, fan_num, node_num, val): - if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: - logging.debug('GET. Parameter error. fan_num:%d', fan_num) - return None - - if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: - logging.debug('GET. Parameter error. node_num:%d', node_num) - return None - - content = str(val) - if content == '': - logging.debug('GET. content is NULL. device_path:%s', device_path) - return None - - device_path = self.get_fan_to_device_path(fan_num, node_num) - try: - val_file = open(device_path, 'w') - except IOError as e: - logging.error('GET. unable to open file: %s', str(e)) - return None - - val_file.write(content) - - try: - val_file.close() - except: - logging.debug('GET. unable to close file. device_path:%s', device_path) - return None - - return True - - def __init__(self): - fan_path = self.BASE_VAL_PATH - - for fan_num in range(self.FAN_NUM_1_IDX, self.FAN_NUM_ON_MAIN_BROAD+1): - for node_num in range(self.FAN_NODE_FAULT_IDX_OF_MAP, self.FAN_NODE_NUM_OF_MAP+1): - self._fan_to_device_path_mapping[(fan_num, node_num)] = fan_path.format( - self._fan_to_device_node_mapping[(fan_num, node_num)]) - - def get_num_fans(self): - return self.FAN_NUM_ON_MAIN_BROAD - - def get_idx_fan_start(self): - return self.FAN_NUM_1_IDX - - def get_num_nodes(self): - return self.FAN_NODE_NUM_OF_MAP - - def get_idx_node_start(self): - return self.FAN_NODE_FAULT_IDX_OF_MAP + device_path = self.get_thermal_path(thermal_num) + for filename in glob.glob(device_path): + try: + val_file = open(filename, 'r') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + content = val_file.readline().rstrip() + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return int(content) + + return 0 - def get_size_node_map(self): - return len(self._fan_to_device_node_mapping) + def get_num_thermals(self): + return self.THERMAL_NUM_MAX def get_size_path_map(self): - return len(self._fan_to_device_path_mapping) - - def get_fan_to_device_path(self, fan_num, node_num): - return self._fan_to_device_path_mapping[(fan_num, node_num)] - - def get_fan_fault(self, fan_num): - return self._get_fan_node_val(fan_num, self.FAN_NODE_FAULT_IDX_OF_MAP) + return len(self.thermal_sysfspath) - #def get_fan_speed(self, fan_num): - # return self._get_fan_node_val(fan_num, self.FAN_NODE_SPEED_IDX_OF_MAP) + def get_thermal_path(self, thermal_num): + return self.thermal_sysfspath[thermal_num][0] - def get_fan_dir(self, fan_num): - return self._get_fan_node_val(fan_num, self.FAN_NODE_DIR_IDX_OF_MAP) - - def get_fan_duty_cycle(self): - #duty_path = self.FAN_DUTY_PATH - try: - val_file = open(self.FAN_DUTY_PATH) - except IOError as e: - print "Error: unable to open file: %s" % str(e) - return False - - content = val_file.readline().rstrip() - val_file.close() - - return int(content) - #self._get_fan_node_val(fan_num, self.FAN_NODE_DUTY_IDX_OF_MAP) -#static u32 reg_val_to_duty_cycle(u8 reg_val) -#{ -# reg_val &= FAN_DUTY_CYCLE_REG_MASK; -# return ((u32)(reg_val+1) * 625 + 75)/ 100; -#} -# - def set_fan_duty_cycle(self, val): - - try: - fan_file = open(self.FAN_DUTY_PATH, 'r+') - except IOError as e: - print "Error: unable to open file: %s" % str(e) - return False - #val = ((val + 1 ) * 625 +75 ) / 100 - fan_file.write(str(val)) - fan_file.close() - return True - - #def get_fanr_fault(self, fan_num): - # return self._get_fan_node_val(fan_num, self.FANR_NODE_FAULT_IDX_OF_MAP) - - def get_fanr_speed(self, fan_num): - return self._get_fan_node_val(fan_num, self.FANR_NODE_SPEED_IDX_OF_MAP) - - def get_fan_status(self, fan_num): - if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: - logging.debug('GET. Parameter error. fan_num, %d', fan_num) - return None - - if self.get_fan_fault(fan_num) is not None and self.get_fan_fault(fan_num) > 0: - logging.debug('GET. FAN fault. fan_num, %d', fan_num) - return False - - #if self.get_fanr_fault(fan_num) is not None and self.get_fanr_fault(fan_num) > 0: - # logging.debug('GET. FANR fault. fan_num, %d', fan_num) - # return False - - return True - -#def main(): -# fan = FanUtil() -# -# print 'get_size_node_map : %d' % fan.get_size_node_map() -# print 'get_size_path_map : %d' % fan.get_size_path_map() -# for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): -# for y in range(fan.get_idx_node_start(), fan.get_num_nodes()+1): -# print fan.get_fan_to_device_path(x, y) -# -#if __name__ == '__main__': -# main() +def main(): + thermal = ThermalUtil() + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/thermalutil.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/thermalutil.py index 96163f1d63ab..bd5530fd9035 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/thermalutil.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/thermalutil.py @@ -1,26 +1,22 @@ #!/usr/bin/env python +# Copyright (c) 2019 Edgecore Networks Corporation # -# Copyright (C) 2017 Accton Technology Corporation +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 # -# This program is free software: you can 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 CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - # ------------------------------------------------------------------ # HISTORY: # mm/dd/yyyy (A.D.) -# 11/13/2017: Polly Hsu, Create -# 1/10/2018:Jostar modify for as7716_32x -# 12/03/2018:Jostar modify for as7726_32x thermal plan +# 10/24/2019:Jostar craete for as4630_54pe # ------------------------------------------------------------------ try: @@ -35,97 +31,60 @@ class ThermalUtil(object): """Platform-specific ThermalUtil class""" - THERMAL_NUM_MAX = 5 - THERMAL_NUM_1_IDX = 1 # 1_ON_MAIN_BROAD. LM75 - THERMAL_NUM_2_IDX = 2 # 2_ON_MAIN_BROAD. LM75 - THERMAL_NUM_3_IDX = 3 # 3_ON_MAIN_BROAD. LM75 - THERMAL_NUM_4_IDX = 4 # 4_ON_MAIN_BROAD. LM75 - THERMAL_NUM_5_IDX = 5 # 5_ON_MAIN_BROAD. LM75 + THERMAL_NUM_MAX = 4 + THERMAL_NUM_1_IDX = 1 + THERMAL_NUM_2_IDX = 2 + THERMAL_NUM_3_IDX = 3 + THERMAL_NUM_4_IDX = 4 """ Dictionary where key1 = thermal id index (integer) starting from 1 value = path to fan device file (string) """ - #_thermal_to_device_path_mapping = {} - - _thermal_to_device_node_mapping = { - THERMAL_NUM_1_IDX: ['55', '48'], - THERMAL_NUM_2_IDX: ['55', '49'], - THERMAL_NUM_3_IDX: ['55', '4a'], - THERMAL_NUM_4_IDX: ['55', '4b'], - THERMAL_NUM_5_IDX: ['54', '4c'], - } + thermal_sysfspath ={ - THERMAL_NUM_1_IDX: ["/sys/bus/i2c/devices/55-0048/hwmon/hwmon4/temp1_input"], - THERMAL_NUM_2_IDX: ["/sys/bus/i2c/devices/55-0049/hwmon/hwmon5/temp1_input"], - THERMAL_NUM_3_IDX: ["/sys/bus/i2c/devices/55-004a/hwmon/hwmon6/temp1_input"], - THERMAL_NUM_4_IDX: ["/sys/bus/i2c/devices/55-004b/hwmon/hwmon7/temp1_input"], - THERMAL_NUM_5_IDX: ["/sys/bus/i2c/devices/54-004c/hwmon/hwmon3/temp1_input"], + THERMAL_NUM_1_IDX: ["/sys/bus/i2c/devices/14-0048/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_2_IDX: ["/sys/bus/i2c/devices/24-004b/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_3_IDX: ["/sys/bus/i2c/devices/25-004a/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_4_IDX: ["/sys/class/hwmon/hwmon1/temp1_input"], } - - #def __init__(self): + def _get_thermal_val(self, thermal_num): if thermal_num < self.THERMAL_NUM_1_IDX or thermal_num > self.THERMAL_NUM_MAX: logging.debug('GET. Parameter error. thermal_num, %d', thermal_num) return None - device_path = self.get_thermal_to_device_path(thermal_num) - if(os.path.isfile(device_path)): - for filename in glob.glob(device_path): - try: - val_file = open(filename, 'r') - except IOError as e: - logging.error('GET. unable to open file: %s', str(e)) - return None + device_path = self.get_thermal_path(thermal_num) + for filename in glob.glob(device_path): + try: + val_file = open(filename, 'r') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None content = val_file.readline().rstrip() if content == '': logging.debug('GET. content is NULL. device_path:%s', device_path) return None try: - val_file.close() + val_file.close() except: logging.debug('GET. unable to close file. device_path:%s', device_path) return None + return int(content) - else: - print "No such device_path=%s"%device_path - return 0 + return 0 def get_num_thermals(self): return self.THERMAL_NUM_MAX - def get_idx_thermal_start(self): - return self.THERMAL_NUM_1_IDX - - def get_size_node_map(self): - return len(self._thermal_to_device_node_mapping) - def get_size_path_map(self): return len(self.thermal_sysfspath) - def get_thermal_to_device_path(self, thermal_num): + def get_thermal_path(self, thermal_num): return self.thermal_sysfspath[thermal_num][0] - def get_thermal_1_val(self): - return self._get_thermal_node_val(self.THERMAL_NUM_1_IDX) - - def get_thermal_2_val(self): - return self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) - def get_thermal_temp(self): - return (self._get_thermal_node_val(self.THERMAL_NUM_1_IDX) + self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) +self._get_thermal_node_val(self.THERMAL_NUM_3_IDX)) - def main(): thermal = ThermalUtil() - print "termal1=%d" %thermal._get_thermal_val(1) - print "termal2=%d" %thermal._get_thermal_val(2) - print "termal3=%d" %thermal._get_thermal_val(3) - print "termal4=%d" %thermal._get_thermal_val(4) - print "termal5=%d" %thermal._get_thermal_val(5) -# -# print 'get_size_node_map : %d' % thermal.get_size_node_map() -# print 'get_size_path_map : %d' % thermal.get_size_path_map() -# for x in range(thermal.get_idx_thermal_start(), thermal.get_num_thermals()+1): -# print thermal.get_thermal_to_device_path(x) -# + if __name__ == '__main__': main() \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor.service b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor.service index 47bf4e81d82e..8ed60fca95f3 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor.service +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor.service @@ -9,7 +9,6 @@ ExecStartPre=/usr/local/bin/accton_as4630_54pe_util.py install ExecStart=/usr/local/bin/accton_as4630_54pe_monitor.py KillSignal=SIGKILL SuccessExitStatus=SIGKILL -#StandardOutput=tty # Resource Limitations LimitCORE=infinity diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/README b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/README index 44e03cab5f52..f656d2b0a855 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/README +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/README @@ -1,4 +1,4 @@ -Copyright (C) 2016 Accton Networks, Inc. +Copyright (C) 2019 Accton Networks, Inc. This program is free software: you can redistribute it and/or modify It under the terms of the GNU General Public License as published by @@ -13,79 +13,29 @@ See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . -Contents of this package: - patch - files under patch/ is for kernel and ONIE installer - for the kernel: - config-accton-as5712_54x.patch - for kernel configuration. - driver-i2c-muxes-pca954x-always-deselect.patch - for i2c_mux deselects after transaction. - driver-patches-for-accton-as5712-fan-psu-cpld.patch - for as5712's fan/psu/cpld/led/sfp drivers. - for ONIE: - onie_installer-accton-AS5712-54X.patch - for console port setting and copy util script o rootfs. - module - Contains source code of as5712 kernel driver modules. - -The late Sonic building scripts, pushed @Dec 5 2016, will automatically -create a docker container and run building process under it. -User is not necessary to handle docker environment creation. - -1. Download sonic-buildimage environment. - - Run "git clone https://github.com/Azure/sonic-buildimage". - - cd to sonic-buildimage and run "git submodule update --init --recursive". -2. Build kernel - - cd ./src/sonic-linux-kernel - - Copy patches and series from patch/kernel of this release to - sonic-linux-kernel/patch. - - Build kernel by "make". - - The built kernel package, linux-image-3.16.0-5-amd64_3.16.51-3+deb8u1_amd64.deb - , is generated. -3. Build installer - - Change directory back to sonic-buildimage/. - - Get onie_installer-accton-AS5712-54X.patch" from patch/installer. - - Change setting for AS5712-54X by patching build_image.sh. - "patch -p1 < onie_installer-accton-AS5712-54X.patch" - !!NOTICE, patching onie_installer-accton-AS5712-54X.patch comments out the - "git status" checking at build_image.sh. - - The account and password of installed OS can be given at rules/config. - The default user and password are "admin" & "YourPaSsWoRd" respectively. - - Run "make configure PLATFORM=broadcom" - - Copy the built kernel debian package to target/debs/. - The file is linux-image-3.16.0-5-amd64_*_amd64.deb under directory - src/sonic-linux-kernel/. - - Run "make target/sonic-generic.bin" - - Get the installer, target/sonic-generic.bin, to target machine and install. - All Linux kernel code is licensed under the GPLv1. All other code is licensed under the GPLv3. Please see the LICENSE file for copies of both licenses. -The code for integacting with Accton AS5712-54X has 2 parts, +The code for integacting with Accton AS4630-54pe has 2 parts, kernel drivers and operational script. The kernel drivers of peripherals are under module/ directory. -1. These drivers are patched into kernel by - driver-patches-for-accton-as5712-fan-psu-cpld.patch - Or you can build the driver under module/ by setting environment variable, - KERNEL_SRC, to proper linux built directory and run make. - It may be sonic-linux-kernel/linux-3.*/debian/build/build_amd64_none_amd64/. -2. A operational script, accton_as5712_util.py, for device initializatian and +1. These drivers are at module dir. +2. A operational script, accton_as4630_util.py, for device initializatian and peripheral accessing should be installed at /usr/bin. - This script is generated by onie_installer-accton-AS5712-54X.patch. - It's done by patching onie_installer-accton-AS5712-54X.patch at build-image. - Run "accton_as5712_util.py install" to install drivers. + Run "accton_as4630_util.py install" to install drivers. -To initialize the system, run "accton_as5712_util.py install". -To clean up the drivers & devices, run "accton_as5712_util.py clean". -To dump information of sensors, run "accton_as5712_util.py show". -To dump SFP EEPROM, run "accton_as5712_util.py sff". -To set fan speed, run "accton_as5712_util.py set fan". -To enable/disable SFP emission, run "accton_as5712_util.py set sfp". -To set system LEDs' color, run "accton_as5712_util.py set led" -For more information, run "accton_as5712_util.py --help". +To initialize the system, run "accton_as4630_util.py install". +To clean up the drivers & devices, run "accton_as4630_util.py clean". +To dump information of sensors, run "accton_as4630_util.py show". +To dump SFP EEPROM, run "accton_as4630_util.py sff". +To set fan speed, run "accton_as4630_util.py set fan". +To enable/disable SFP emission, run "accton_as4630_util.py set sfp". +To set system LEDs' color, run "accton_as4630_util.py set led" +For more information, run "accton_as4630_util.py --help". ==================================================================== -Besides applying accton_as5712_util.py to access peripherals, you can +Besides applying accton_as4630_util.py to access peripherals, you can access peripherals by sysfs nodes directly after the installation is run. System LED: diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor.py index eca1eac6b216..6dbf5c2cc720 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor.py @@ -1,25 +1,22 @@ #!/usr/bin/env python +# -*- coding: utf-8 -* +# Copyright (c) 2019 Edgecore Networks Corporation # -# Copyright (C) 2017 Accton Technology Corporation +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 # -# This program is free software: you can 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 CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU 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 . - -# ------------------------------------------------------------------ +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. +# # HISTORY: # mm/dd/yyyy (A.D.)# -# 4/20/2018: Jostar modify for as7726_32x -# 12/03/2018:Jostar modify for as7726_32x thermal plan +# 10/24/2019:Jostar create for as4630_54pe thermal plan # ------------------------------------------------------------------ try: @@ -32,11 +29,12 @@ import logging.config import logging.handlers import types - import time # this is only being used as part of the example - import traceback + import time + import traceback + import commands from tabulate import tabulate - from as7726_32x.fanutil import FanUtil - from as7726_32x.thermalutil import ThermalUtil + from as4630_54pe.fanutil import FanUtil + from as4630_54pe.thermalutil import ThermalUtil except ImportError as e: raise ImportError('%s - required module not found' % str(e)) @@ -48,25 +46,20 @@ global log_level -# Air Flow Front to Back : -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 <=38C : Keep 37.5%(0x04) Fan speed -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 38C : Change Fan speed from 37.5%(0x04) to 62.5%(0x08) -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 46C : Change Fan speed from 62.5%(0x08) to 100%(0x0E) -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 58C : Send alarm message -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 66C : Shut down system -# One Fan fail : Change Fan speed to 100%(0x0E) -# Air Flow Back to Front : -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 <=34C : Keep 37.5%(0x04) Fan speed -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 34C : Change Fan speed from 37.5%(0x04) to 62.5%(0x08) -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 44C : Change Fan speed from 62.5%(0x08) to 100%(0x0E) -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 59C : Send alarm message -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 67C : Shut down system -# One Fan fail: Change Fan speed to 100%(0x0E) -# sensor_LM75_CPU == sensor_LM75_4B - - + +# Temperature Policy +# If any fan fail , please set fan speed register to 16 +# The max value of fan speed register is 14 +# LM77(48)+LM75(4B)+LM75(4A) > 140, Set 10 +# LM77(48)+LM75(4B)+LM75(4A) > 150, Set 12 +# LM77(48)+LM75(4B)+LM75(4A) > 160, Set 14 +# LM77(48)+LM75(4B)+LM75(4A) < 140, Set 8 +# LM77(48)+LM75(4B)+LM75(4A) < 150, Set 10 +# LM77(48)+LM75(4B)+LM75(4A) < 160, Set 12 +# Reset DUT:LM77(48)>=70C +# class switch(object): def __init__(self, value): self.value = value @@ -87,13 +80,13 @@ def match(self, *args): else: return False - -fan_policy_state=1 +fan_policy_state=0 fan_fail=0 alarm_state = 0 #0->default or clear, 1-->alarm detect test_temp = 0 -test_temp_list = [0, 0, 0, 0, 0, 0] +test_temp_list = [0, 0, 0] temp_test_data=0 +test_temp_revert=0 # Make a class we can use to capture stdout and sterr in the log class device_monitor(object): # static temp var @@ -124,119 +117,71 @@ def __init__(self, log_file, log_level): sys_handler = handler = logging.handlers.SysLogHandler(address = '/dev/log') sys_handler.setLevel(logging.WARNING) logging.getLogger('').addHandler(sys_handler) - - #logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level) def get_state_from_fan_policy(self, temp, policy): state=0 - - logging.debug('temp=%d', temp) for i in range(0, len(policy)): - #logging.debug('policy[%d][0]=%d, policy[%d][1]=%d, policy[%d][2]=%d', i,policy[i][0],i, policy[i][1], i, policy[i][2]) - if temp > policy[i][2]: - if temp <= policy[i][3]: + if (temp > policy[i][2]): #temp_down + if temp <= policy[i][3]: #temp_up state =i - logging.debug ('temp=%d >= policy[%d][2]=%d, temp=%d < policy[%d][3]=%d' , temp, i, policy[i][2], temp, i, policy[i][3]) - logging.debug ('fan_state=%d', state) - break - + return state - def manage_fans(self): - global fan_policy_state global fan_fail global test_temp global test_temp_list global alarm_state - global temp_test_data - - LEVEL_FAN_DEF=0 - LEVEL_FAN_MID=1 - LEVEL_FAN_MAX=2 - LEVEL_TEMP_HIGH=3 - LEVEL_TEMP_CRITICAL=4 - - - fan_policy_f2b = { - LEVEL_FAN_DEF: [38, 0x4, 0, 38000], - LEVEL_FAN_MID: [63, 0x6, 38000, 46000], - LEVEL_FAN_MAX: [100, 0xE, 46000, 58000], - LEVEL_TEMP_HIGH: [100, 0xE, 58000, 66000], - LEVEL_TEMP_CRITICAL: [100, 0xE, 58000, 200000], - } - fan_policy_b2f = { - LEVEL_FAN_DEF: [38, 0x4, 0, 34000], - LEVEL_FAN_MID: [63, 0x8, 34000, 44000], - LEVEL_FAN_MAX: [100, 0xE, 44000, 59000], - LEVEL_TEMP_HIGH: [100, 0xE, 59000, 67000], - LEVEL_TEMP_CRITICAL: [100, 0xE, 59000, 200000], + global temp_test_data + global test_temp_revert + LEVEL_FAN_MIN=0 + LEVEL_FAN_NORMAL=1 + LEVEL_FAN_MID=2 + LEVEL_FAN_HIGH=3 + LEVEL_TEMP_CRITICAL=4 + fan_policy = { + LEVEL_FAN_MIN: [50, 8, 0, 140000], + LEVEL_FAN_NORMAL: [62, 10, 140000, 150000], + LEVEL_FAN_MID: [75, 12, 150000, 160000], + LEVEL_FAN_HIGH: [88, 14, 160000, 240000], + LEVEL_TEMP_CRITICAL: [100, 16, 240000, 300000], } - - fan_policy = fan_policy_f2b - + temp = [0, 0 , 0] + temp_fail=0 thermal = ThermalUtil() fan = FanUtil() - fan_dir=fan.get_fan_dir(1) - if fan_dir == 1: - fan_dri=1 #something wrong, set fan_dir to default val - else: - fan_policy = fan_policy_b2f + ori_duty_cycle=fan.get_fan_duty_cycle() + new_duty_cycle=0 - ori_pwm=fan.get_fan_duty_cycle() - new_pwm=0 - logging.debug('fan_dir=%d, ori_pwm=%d', fan_dir, ori_pwm) - logging.debug('test_temp=%d', test_temp) - if test_temp==0: - temp1 = thermal._get_thermal_val(1) - temp2 = thermal._get_thermal_val(2) - temp3 = thermal._get_thermal_val(3) - temp4 = thermal._get_thermal_val(4) - temp5 = thermal._get_thermal_val(5) + if test_temp==0: + for i in range(0,3): + temp[i]=thermal._get_thermal_val(i+1) + if temp[i]==0 or temp[i]==None: + temp_fail=1 + logging.warning("Get temp-%d fail", i); + return False else: - temp1 = test_temp_list[0] - temp2 = test_temp_list[1] - temp3 = test_temp_list[2] - temp4 = test_temp_list[3] - temp5 = test_temp_list[4] + if test_temp_revert==0: + temp_test_data=temp_test_data+2000 + else: + temp_test_data=temp_test_data-2000 + + for i in range(0,3): + temp[i]=test_temp_list[i]+temp_test_data fan_fail=0 - - if temp3==0: - temp_get=50000 # if one detect sensor is fail or zero, assign temp=50000, let fan to 75% - logging.debug('lm75_49 detect fail, so set temp_get=50000, let fan to 75%') - elif temp4==0: - temp_get=50000 # if one detect sensor is fail or zero, assign temp=50000, let fan to 75% - logging.debug('lm75_4b detect fail, so set temp_get=50000, let fan to 75%') - else: - temp_get= (temp3 + temp4)/2 # Use (sensor_LM75_4a + sensor_LM75_4b) /2 - ori_state=fan_policy_state - - #temp_test_data=temp_test_data+1000 - #temp_get = temp_get + temp_test_data - #print "Unit test:temp_get=%d"%temp_get - - fan_policy_state=self.get_state_from_fan_policy(temp_get, fan_policy) - #print "temp3=%d"%temp3 - #print "temp4=%d"%temp4 - #print "temp_get=%d"%temp_get - - logging.debug('lm75_48=%d, lm75_49=%d, lm75_4a=%d, lm_4b=%d, lm_4b=%d', temp1,temp2,temp3,temp4,temp5) - logging.debug('ori_state=%d, fan_policy_state=%d', ori_state, fan_policy_state) - new_pwm = fan_policy[fan_policy_state][0] - if fan_fail==0: - logging.debug('new_fan_cycle=%d', new_pwm) - - if fan_fail==0: - if new_pwm!=ori_pwm: - fan.set_fan_duty_cycle(new_pwm) - logging.info('Set fan speed from %d to %d', ori_pwm, new_pwm) + + temp_val=0 + for i in range(0,3): + if temp[i]==None: + break + temp_val+=temp[i] #Check Fan status for i in range (fan.FAN_NUM_1_IDX, fan.FAN_NUM_ON_MAIN_BROAD+1): if fan.get_fan_status(i)==0: new_pwm=100 - logging.debug('fan_%d fail, set pwm to 100',i) + logging.warning('Fan_%d fail, set pwm to 100',i) if test_temp==0: fan_fail=1 fan.set_fan_duty_cycle(new_pwm) @@ -244,59 +189,38 @@ def manage_fans(self): else: fan_fail=0 - #if fan_policy_state == ori_state: - # return True - #else: - new_state = fan_policy_state + ori_state=fan_policy_state + fan_policy_state=self.get_state_from_fan_policy(temp_val, fan_policy) - #logging.warning('Temperature high alarm testing') - if ori_state==LEVEL_FAN_DEF: - if new_state==LEVEL_TEMP_HIGH: + if fan_policy_state > LEVEL_TEMP_CRITICAL or fan_policy_state < LEVEL_FAN_MIN: + logging.error("Get error fan current_state\n"); + return 0 + + #Decision : Decide new fan pwm percent. + if fan_fail==0 and ori_duty_cycle!=fan_policy[fan_policy_state][0]: + new_duty_cycle = fan_policy[fan_policy_state][0]; + fan.set_fan_duty_cycle(new_duty_cycle) + + if temp[0] >= 70000: #LM75-48 + #critical case*/ + logging.critical('Alarm-Critical for temperature critical is detected, reset DUT') + cmd_str="i2cset -y -f 3 0x60 0x4 0xE4" + time.sleep(2); + status, output = commands.getstatusoutput(cmd_str) + + #logging.debug('ori_state=%d, current_state=%d, temp_val=%d\n\n',ori_state, fan_policy_state, temp_val) + + if ori_state < LEVEL_FAN_HIGH: + if fan_policy_state >= LEVEL_FAN_HIGH: if alarm_state==0: logging.warning('Alarm for temperature high is detected') - alarm_state=1 - if new_state==LEVEL_TEMP_CRITICAL: - logging.critical('Alarm for temperature critical is detected, reboot DUT') - time.sleep(2) - os.system('reboot') - if ori_state==LEVEL_FAN_MID: - if new_state==LEVEL_TEMP_HIGH: - if alarm_state==0: - logging.warning('Alarm for temperature high is detected') - alarm_state=1 - if new_state==LEVEL_TEMP_CRITICAL: - logging.critical('Alarm for temperature critical is detected') - time.sleep(2) - os.system('reboot') - if ori_state==LEVEL_FAN_MAX: - if new_state==LEVEL_TEMP_HIGH: - if alarm_state==0: - logging.warning('Alarm for temperature high is detected') - alarm_state=1 - if new_state==LEVEL_TEMP_CRITICAL: - logging.critical('Alarm for temperature critical is detected') - time.sleep(2) - os.system('reboot') + alarm_state=1 + + if fan_policy_state < LEVEL_FAN_MID: if alarm_state==1: - if temp_get < (fan_policy[3][0] - 5000): #below 65 C, clear alarm - logging.warning('Alarm for temperature high is cleared') - alarm_state=0 - if ori_state==LEVEL_TEMP_HIGH: - if new_state==LEVEL_TEMP_CRITICAL: - logging.critical('Alarm for temperature critical is detected') - time.sleep(2) - os.system('reboot') - if new_state <= LEVEL_FAN_MID: - logging.warning('Alarm for temperature high is cleared') + logging.info('Alarm for temperature high is cleared') alarm_state=0 - if new_state <= LEVEL_FAN_MAX: - if temp_get < (fan_policy[3][0] - 5000): #below 65 C, clear alarm - logging.warning('Alarm for temperature high is cleared') - alarm_state=0 - if ori_state==LEVEL_TEMP_CRITICAL: - if new_state <= LEVEL_FAN_MAX: - logging.warning('Alarm for temperature critical is cleared') - + return True def main(argv): @@ -319,12 +243,12 @@ def main(argv): log_file = arg if sys.argv[1]== '-t': - if len(sys.argv)!=7: - print "temp test, need input six temp" + if len(sys.argv)!=5: + print "temp test, need input three temp" return 0 i=0 - for x in range(2, 7): + for x in range(2, 5): test_temp_list[i]= int(sys.argv[x])*1000 i=i+1 test_temp = 1 @@ -332,14 +256,14 @@ def main(argv): print test_temp_list fan = FanUtil() - fan.set_fan_duty_cycle(38) - print "set default fan speed to 37.5%" + fan.set_fan_duty_cycle(50) + print "set default fan speed to 50%" monitor = device_monitor(log_file, log_level) # Loop forever, doing something useful hopefully: while True: - #monitor.manage_fans() - time.sleep(5) + monitor.manage_fans() + time.sleep(10) #10sec if __name__ == '__main__': main(sys.argv[1:]) - + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_fan.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_fan.c old mode 100755 new mode 100644 index db81a1a8ca97..3f74e3f375a9 --- a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_fan.c +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_fan.c @@ -33,6 +33,8 @@ #include #include +#define DRVNAME "as5712_54x_fan" + #define FAN_MAX_NUMBER 5 #define FAN_SPEED_CPLD_TO_RPM_STEP 150 #define FAN_SPEED_PRECENT_TO_CPLD_STEP 5 @@ -130,47 +132,58 @@ static ssize_t fan_set_duty_cycle(struct device *dev, struct device_attribute *da,const char *buf, size_t count); static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); - +static ssize_t show_name(struct device *dev, struct device_attribute *da, + char *buf); extern int as5712_54x_cpld_read(unsigned short cpld_addr, u8 reg); extern int as5712_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); /*******************/ -#define _MAKE_SENSOR_DEVICE_ATTR(prj, id) \ - static SENSOR_DEVICE_ATTR(prj##fan##id##_fault, S_IRUGO, fan_show_value, NULL, FAN##id##_FAULT); \ +#define _MAKE_SENSOR_DEVICE_ATTR(prj, id, id2) \ static SENSOR_DEVICE_ATTR(prj##fan##id##_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##id##_SPEED); \ static SENSOR_DEVICE_ATTR(prj##fan##id##_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, \ fan_set_duty_cycle, FAN##id##_DUTY_CYCLE); \ static SENSOR_DEVICE_ATTR(prj##fan##id##_direction, S_IRUGO, fan_show_value, NULL, FAN##id##_DIRECTION); \ static SENSOR_DEVICE_ATTR(prj##fanr##id##_fault, S_IRUGO, fan_show_value, NULL, FANR##id##_FAULT); \ - static SENSOR_DEVICE_ATTR(prj##fanr##id##_speed_rpm, S_IRUGO, fan_show_value, NULL, FANR##id##_SPEED); + static SENSOR_DEVICE_ATTR(prj##fanr##id##_speed_rpm, S_IRUGO, fan_show_value, NULL, FANR##id##_SPEED);\ + static SENSOR_DEVICE_ATTR(prj##fan##id##_input, S_IRUGO, fan_show_value, NULL, FAN##id##_SPEED); \ + static SENSOR_DEVICE_ATTR(prj##fan##id2##_input, S_IRUGO, fan_show_value, NULL, FANR##id##_SPEED);\ + static SENSOR_DEVICE_ATTR(prj##fan##id##_fault, S_IRUGO, fan_show_value, NULL, FAN##id##_FAULT); \ + static SENSOR_DEVICE_ATTR(prj##fan##id2##_fault, S_IRUGO, fan_show_value, NULL, FANR##id##_FAULT); + +#define MAKE_SENSOR_DEVICE_ATTR(prj,id, id2) _MAKE_SENSOR_DEVICE_ATTR(prj,id, id2) -#define MAKE_SENSOR_DEVICE_ATTR(prj,id) _MAKE_SENSOR_DEVICE_ATTR(prj,id) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 1, 11) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 2, 12) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 3, 13) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 4, 14) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 5, 15) -MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 1) -MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 2) -MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 3) -MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 4) -MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 5) +static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0); /*******************/ -#define _MAKE_FAN_ATTR(prj, id) \ - &sensor_dev_attr_##prj##fan##id##_fault.dev_attr.attr, \ +#define _MAKE_FAN_ATTR(prj, id, id2) \ &sensor_dev_attr_##prj##fan##id##_speed_rpm.dev_attr.attr, \ &sensor_dev_attr_##prj##fan##id##_duty_cycle_percentage.dev_attr.attr,\ &sensor_dev_attr_##prj##fan##id##_direction.dev_attr.attr, \ &sensor_dev_attr_##prj##fanr##id##_fault.dev_attr.attr, \ - &sensor_dev_attr_##prj##fanr##id##_speed_rpm.dev_attr.attr, + &sensor_dev_attr_##prj##fanr##id##_speed_rpm.dev_attr.attr,\ + &sensor_dev_attr_##prj##fan##id##_input.dev_attr.attr, \ + &sensor_dev_attr_##prj##fan##id2##_input.dev_attr.attr, \ + &sensor_dev_attr_##prj##fan##id##_fault.dev_attr.attr, \ + &sensor_dev_attr_##prj##fan##id2##_fault.dev_attr.attr, + -#define MAKE_FAN_ATTR(prj, id) _MAKE_FAN_ATTR(prj, id) +#define MAKE_FAN_ATTR(prj, id, id2) _MAKE_FAN_ATTR(prj, id, id2) static struct attribute *accton_as5712_54x_fan_attributes[] = { /* fan related attributes */ - MAKE_FAN_ATTR(PROJECT_NAME,1) - MAKE_FAN_ATTR(PROJECT_NAME,2) - MAKE_FAN_ATTR(PROJECT_NAME,3) - MAKE_FAN_ATTR(PROJECT_NAME,4) - MAKE_FAN_ATTR(PROJECT_NAME,5) + MAKE_FAN_ATTR(PROJECT_NAME,1, 11) + MAKE_FAN_ATTR(PROJECT_NAME,2, 12) + MAKE_FAN_ATTR(PROJECT_NAME,3, 13) + MAKE_FAN_ATTR(PROJECT_NAME,4, 14) + MAKE_FAN_ATTR(PROJECT_NAME,5, 15) + &sensor_dev_attr_name.dev_attr.attr, NULL }; /*******************/ @@ -232,6 +245,12 @@ static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, return ret; } + +static ssize_t show_name(struct device *dev, struct device_attribute *da, + char *buf) +{ + return sprintf(buf, "%s\n", DRVNAME); +} /*******************/ static ssize_t fan_set_duty_cycle(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { @@ -379,7 +398,7 @@ static int accton_as5712_54x_fan_remove(struct platform_device *pdev) return 0; } -#define DRVNAME "as5712_54x_fan" + static struct platform_driver accton_as5712_54x_fan_driver = { .probe = accton_as5712_54x_fan_probe, diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/cpr_4011_4mxx.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/cpr_4011_4mxx.c deleted file mode 100755 index 30bea914d589..000000000000 --- a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/cpr_4011_4mxx.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * An hwmon driver for the CPR-4011-4Mxx Redundant Power Module - * - * Copyright (C) Brandon Chuang - * - * Based on ad7414.c - * Copyright 2006 Stefan Roese , DENX Software Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#if 0 -#define DEBUG -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX_FAN_DUTY_CYCLE 100 - -/* Addresses scanned - */ -static const unsigned short normal_i2c[] = { 0x3c, 0x3d, 0x3e, 0x3f, I2C_CLIENT_END }; - -/* Each client has this additional data - */ -struct cpr_4011_4mxx_data { - struct device *hwmon_dev; - struct mutex update_lock; - char valid; /* !=0 if registers are valid */ - unsigned long last_updated; /* In jiffies */ - u8 vout_mode; /* Register value */ - u16 v_in; /* Register value */ - u16 v_out; /* Register value */ - u16 i_in; /* Register value */ - u16 i_out; /* Register value */ - u16 p_in; /* Register value */ - u16 p_out; /* Register value */ - u16 temp_input[2]; /* Register value */ - u8 fan_fault; /* Register value */ - u16 fan_duty_cycle[2]; /* Register value */ - u16 fan_speed[2]; /* Register value */ -}; - -static ssize_t show_linear(struct device *dev, struct device_attribute *da, char *buf); -static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, char *buf); -static ssize_t show_vout(struct device *dev, struct device_attribute *da, char *buf); -static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, const char *buf, size_t count); -static int cpr_4011_4mxx_write_word(struct i2c_client *client, u8 reg, u16 value); -static struct cpr_4011_4mxx_data *cpr_4011_4mxx_update_device(struct device *dev); - -enum cpr_4011_4mxx_sysfs_attributes { - PSU_V_IN, - PSU_V_OUT, - PSU_I_IN, - PSU_I_OUT, - PSU_P_IN, - PSU_P_OUT, - PSU_TEMP1_INPUT, - PSU_FAN1_FAULT, - PSU_FAN1_DUTY_CYCLE, - PSU_FAN1_SPEED, -}; - -/* sysfs attributes for hwmon - */ -static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, show_linear, NULL, PSU_V_IN); -static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_vout, NULL, PSU_V_OUT); -static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, show_linear, NULL, PSU_I_IN); -static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT); -static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, show_linear, NULL, PSU_P_IN); -static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT); -static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); -static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT); -static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); -static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); - -static struct attribute *cpr_4011_4mxx_attributes[] = { - &sensor_dev_attr_psu_v_in.dev_attr.attr, - &sensor_dev_attr_psu_v_out.dev_attr.attr, - &sensor_dev_attr_psu_i_in.dev_attr.attr, - &sensor_dev_attr_psu_i_out.dev_attr.attr, - &sensor_dev_attr_psu_p_in.dev_attr.attr, - &sensor_dev_attr_psu_p_out.dev_attr.attr, - &sensor_dev_attr_psu_temp1_input.dev_attr.attr, - &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, - &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, - &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, - NULL -}; - -static int two_complement_to_int(u16 data, u8 valid_bit, int mask) -{ - u16 valid_data = data & mask; - bool is_negative = valid_data >> (valid_bit - 1); - - return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; -} - -static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct cpr_4011_4mxx_data *data = i2c_get_clientdata(client); - int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; - long speed; - int error; - - error = kstrtol(buf, 10, &speed); - if (error) - return error; - - if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) - return -EINVAL; - - mutex_lock(&data->update_lock); - data->fan_duty_cycle[nr] = speed; - cpr_4011_4mxx_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t show_linear(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct cpr_4011_4mxx_data *data = cpr_4011_4mxx_update_device(dev); - - u16 value = 0; - int exponent, mantissa; - int multiplier = 1000; - - switch (attr->index) { - case PSU_V_IN: - value = data->v_in; - break; - case PSU_I_IN: - value = data->i_in; - break; - case PSU_I_OUT: - value = data->i_out; - break; - case PSU_P_IN: - value = data->p_in; - break; - case PSU_P_OUT: - value = data->p_out; - break; - case PSU_TEMP1_INPUT: - value = data->temp_input[0]; - break; - case PSU_FAN1_DUTY_CYCLE: - multiplier = 1; - value = data->fan_duty_cycle[0]; - break; - case PSU_FAN1_SPEED: - multiplier = 1; - value = data->fan_speed[0]; - break; - default: - break; - } - - exponent = two_complement_to_int(value >> 11, 5, 0x1f); - mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); - - return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : - sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); -} - -static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct cpr_4011_4mxx_data *data = cpr_4011_4mxx_update_device(dev); - - u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; - - return sprintf(buf, "%d\n", data->fan_fault >> shift); -} - -static ssize_t show_vout(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct cpr_4011_4mxx_data *data = cpr_4011_4mxx_update_device(dev); - int exponent, mantissa; - int multiplier = 1000; - - exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); - mantissa = data->v_out; - - return (exponent > 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : - sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); -} - -static const struct attribute_group cpr_4011_4mxx_group = { - .attrs = cpr_4011_4mxx_attributes, -}; - -static int cpr_4011_4mxx_probe(struct i2c_client *client, - const struct i2c_device_id *dev_id) -{ - struct cpr_4011_4mxx_data *data; - int status; - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) { - status = -EIO; - goto exit; - } - - data = kzalloc(sizeof(struct cpr_4011_4mxx_data), GFP_KERNEL); - if (!data) { - status = -ENOMEM; - goto exit; - } - - i2c_set_clientdata(client, data); - data->valid = 0; - mutex_init(&data->update_lock); - - dev_info(&client->dev, "chip found\n"); - - /* Register sysfs hooks */ - status = sysfs_create_group(&client->dev.kobj, &cpr_4011_4mxx_group); - if (status) { - goto exit_free; - } - - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - status = PTR_ERR(data->hwmon_dev); - goto exit_remove; - } - - dev_info(&client->dev, "%s: psu '%s'\n", - dev_name(data->hwmon_dev), client->name); - - return 0; - -exit_remove: - sysfs_remove_group(&client->dev.kobj, &cpr_4011_4mxx_group); -exit_free: - kfree(data); -exit: - - return status; -} - -static int cpr_4011_4mxx_remove(struct i2c_client *client) -{ - struct cpr_4011_4mxx_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &cpr_4011_4mxx_group); - kfree(data); - - return 0; -} - -static const struct i2c_device_id cpr_4011_4mxx_id[] = { - { "cpr_4011_4mxx", 0 }, - {} -}; -MODULE_DEVICE_TABLE(i2c, cpr_4011_4mxx_id); - -static struct i2c_driver cpr_4011_4mxx_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "cpr_4011_4mxx", - }, - .probe = cpr_4011_4mxx_probe, - .remove = cpr_4011_4mxx_remove, - .id_table = cpr_4011_4mxx_id, - .address_list = normal_i2c, -}; - -static int cpr_4011_4mxx_read_byte(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_byte_data(client, reg); -} - -static int cpr_4011_4mxx_read_word(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_word_data(client, reg); -} - -static int cpr_4011_4mxx_write_word(struct i2c_client *client, u8 reg, u16 value) -{ - return i2c_smbus_write_word_data(client, reg, value); -} - -struct reg_data_byte { - u8 reg; - u8 *value; -}; - -struct reg_data_word { - u8 reg; - u16 *value; -}; - -static struct cpr_4011_4mxx_data *cpr_4011_4mxx_update_device(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct cpr_4011_4mxx_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) - || !data->valid) { - int i, status; - struct reg_data_byte regs_byte[] = { {0x20, &data->vout_mode}, - {0x81, &data->fan_fault}}; - struct reg_data_word regs_word[] = { {0x88, &data->v_in}, - {0x8b, &data->v_out}, - {0x89, &data->i_in}, - {0x8c, &data->i_out}, - {0x96, &data->p_out}, - {0x97, &data->p_in}, - {0x8d, &(data->temp_input[0])}, - {0x8e, &(data->temp_input[1])}, - {0x3b, &(data->fan_duty_cycle[0])}, - {0x3c, &(data->fan_duty_cycle[1])}, - {0x90, &(data->fan_speed[0])}, - {0x91, &(data->fan_speed[1])}}; - - dev_dbg(&client->dev, "Starting cpr_4011_4mxx update\n"); - - /* Read byte data */ - for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { - status = cpr_4011_4mxx_read_byte(client, regs_byte[i].reg); - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_byte[i].reg, status); - } - else { - *(regs_byte[i].value) = status; - } - } - - /* Read word data */ - for (i = 0; i < ARRAY_SIZE(regs_word); i++) { - status = cpr_4011_4mxx_read_word(client, regs_word[i].reg); - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_word[i].reg, status); - } - else { - *(regs_word[i].value) = status; - } - } - - data->last_updated = jiffies; - data->valid = 1; - } - - mutex_unlock(&data->update_lock); - - return data; -} - -static int __init cpr_4011_4mxx_init(void) -{ - return i2c_add_driver(&cpr_4011_4mxx_driver); -} - -static void __exit cpr_4011_4mxx_exit(void) -{ - i2c_del_driver(&cpr_4011_4mxx_driver); -} - -MODULE_AUTHOR("Brandon Chuang "); -MODULE_DESCRIPTION("CPR_4011_4MXX driver"); -MODULE_LICENSE("GPL"); - -module_init(cpr_4011_4mxx_init); -module_exit(cpr_4011_4mxx_exit); diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/cpr_4011_4mxx.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/cpr_4011_4mxx.c new file mode 120000 index 000000000000..fd43cc1f1c77 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/cpr_4011_4mxx.c @@ -0,0 +1 @@ +../../common/modules/cpr_4011_4mxx.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/ym2651y.c deleted file mode 100755 index 519530387e29..000000000000 --- a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/ym2651y.c +++ /dev/null @@ -1,683 +0,0 @@ -/* - * An hwmon driver for the 3Y Power YM-2651Y Power Module - * - * Copyright (C) 2014 Accton Technology Corporation. - * Brandon Chuang - * - * Based on ad7414.c - * Copyright 2006 Stefan Roese , DENX Software Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#if 0 -#define DEBUG -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX_FAN_DUTY_CYCLE 100 - -/* Addresses scanned - */ -static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -enum chips { - YM2651, - YM2401, -}; - -/* Each client has this additional data - */ -struct ym2651y_data { - struct device *hwmon_dev; - struct mutex update_lock; - char valid; /* !=0 if registers are valid */ - unsigned long last_updated; /* In jiffies */ - u8 chip; /* chip id */ - u8 capability; /* Register value */ - u16 status_word; /* Register value */ - u8 fan_fault; /* Register value */ - u8 over_temp; /* Register value */ - u16 v_out; /* Register value */ - u16 i_out; /* Register value */ - u16 p_out; /* Register value */ - u8 vout_mode; /* Register value */ - u16 temp; /* Register value */ - u16 fan_speed; /* Register value */ - u16 fan_duty_cycle[2]; /* Register value */ - u8 fan_dir[5]; /* Register value */ - u8 pmbus_revision; /* Register value */ - u8 mfr_id[10]; /* Register value */ - u8 mfr_model[16]; /* Register value */ - u8 mfr_revsion[3]; /* Register value */ - u16 mfr_vin_min; /* Register value */ - u16 mfr_vin_max; /* Register value */ - u16 mfr_iin_max; /* Register value */ - u16 mfr_iout_max; /* Register value */ - u16 mfr_pin_max; /* Register value */ - u16 mfr_pout_max; /* Register value */ - u16 mfr_vout_min; /* Register value */ - u16 mfr_vout_max; /* Register value */ -}; - -static ssize_t show_byte(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_word(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_linear(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_vout(struct device *dev, struct device_attribute *da, char *buf); -static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_ascii(struct device *dev, struct device_attribute *da, - char *buf); -static struct ym2651y_data *ym2651y_update_device(struct device *dev); -static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); -static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value); - -enum ym2651y_sysfs_attributes { - PSU_POWER_ON = 0, - PSU_TEMP_FAULT, - PSU_POWER_GOOD, - PSU_FAN1_FAULT, - PSU_FAN_DIRECTION, - PSU_OVER_TEMP, - PSU_V_OUT, - PSU_I_OUT, - PSU_P_OUT, - PSU_TEMP1_INPUT, - PSU_FAN1_SPEED, - PSU_FAN1_DUTY_CYCLE, - PSU_PMBUS_REVISION, - PSU_MFR_ID, - PSU_MFR_MODEL, - PSU_MFR_REVISION, - PSU_MFR_VIN_MIN, - PSU_MFR_VIN_MAX, - PSU_MFR_VOUT_MIN, - PSU_MFR_VOUT_MAX, - PSU_MFR_IIN_MAX, - PSU_MFR_IOUT_MAX, - PSU_MFR_PIN_MAX, - PSU_MFR_POUT_MAX -}; - -/* sysfs attributes for hwmon - */ -static SENSOR_DEVICE_ATTR(psu_power_on, S_IRUGO, show_word, NULL, PSU_POWER_ON); -static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); -static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_word, NULL, PSU_POWER_GOOD); -static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT); -static SENSOR_DEVICE_ATTR(psu_over_temp, S_IRUGO, show_over_temp, NULL, PSU_OVER_TEMP); -static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_vout, NULL, PSU_V_OUT); -static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT); -static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT); -static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); -static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); -static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); -static SENSOR_DEVICE_ATTR(psu_fan_dir, S_IRUGO, show_ascii, NULL, PSU_FAN_DIRECTION); -static SENSOR_DEVICE_ATTR(psu_pmbus_revision,S_IRUGO, show_byte, NULL, PSU_PMBUS_REVISION); -static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_ascii, NULL, PSU_MFR_ID); -static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, show_ascii, NULL, PSU_MFR_MODEL); -static SENSOR_DEVICE_ATTR(psu_mfr_revision, S_IRUGO, show_ascii, NULL, PSU_MFR_REVISION); -static SENSOR_DEVICE_ATTR(psu_mfr_vin_min, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MIN); -static SENSOR_DEVICE_ATTR(psu_mfr_vin_max, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_vout_min, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MIN); -static SENSOR_DEVICE_ATTR(psu_mfr_vout_max, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_iin_max, S_IRUGO, show_linear, NULL, PSU_MFR_IIN_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_iout_max, S_IRUGO, show_linear, NULL, PSU_MFR_IOUT_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_pin_max, S_IRUGO, show_linear, NULL, PSU_MFR_PIN_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_pout_max, S_IRUGO, show_linear, NULL, PSU_MFR_POUT_MAX); - -static struct attribute *ym2651y_attributes[] = { - &sensor_dev_attr_psu_power_on.dev_attr.attr, - &sensor_dev_attr_psu_temp_fault.dev_attr.attr, - &sensor_dev_attr_psu_power_good.dev_attr.attr, - &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, - &sensor_dev_attr_psu_over_temp.dev_attr.attr, - &sensor_dev_attr_psu_v_out.dev_attr.attr, - &sensor_dev_attr_psu_i_out.dev_attr.attr, - &sensor_dev_attr_psu_p_out.dev_attr.attr, - &sensor_dev_attr_psu_temp1_input.dev_attr.attr, - &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, - &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, - &sensor_dev_attr_psu_fan_dir.dev_attr.attr, - &sensor_dev_attr_psu_pmbus_revision.dev_attr.attr, - &sensor_dev_attr_psu_mfr_id.dev_attr.attr, - &sensor_dev_attr_psu_mfr_model.dev_attr.attr, - &sensor_dev_attr_psu_mfr_revision.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vin_min.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vin_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_pout_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_iin_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_pin_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vout_min.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vout_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_iout_max.dev_attr.attr, - NULL -}; - -static ssize_t show_byte(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - - if (!data->valid) { - return 0; - } - - return (attr->index == PSU_PMBUS_REVISION) ? sprintf(buf, "%d\n", data->pmbus_revision) : - sprintf(buf, "0\n"); -} - -static ssize_t show_word(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - u16 status = 0; - - if (!data->valid) { - return 0; - } - - switch (attr->index) { - case PSU_POWER_ON: /* psu_power_on, low byte bit 6 of status_word, 0=>ON, 1=>OFF */ - status = (data->status_word & 0x40) ? 0 : 1; - break; - case PSU_TEMP_FAULT: /* psu_temp_fault, low byte bit 2 of status_word, 0=>Normal, 1=>temp fault */ - status = (data->status_word & 0x4) >> 2; - break; - case PSU_POWER_GOOD: /* psu_power_good, high byte bit 3 of status_word, 0=>OK, 1=>FAIL */ - status = (data->status_word & 0x800) ? 0 : 1; - break; - } - - return sprintf(buf, "%d\n", status); -} - -static int two_complement_to_int(u16 data, u8 valid_bit, int mask) -{ - u16 valid_data = data & mask; - bool is_negative = valid_data >> (valid_bit - 1); - - return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; -} - -static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct ym2651y_data *data = i2c_get_clientdata(client); - int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; - long speed; - int error; - - error = kstrtol(buf, 10, &speed); - if (error) - return error; - - if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) - return -EINVAL; - - mutex_lock(&data->update_lock); - data->fan_duty_cycle[nr] = speed; - ym2651y_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t show_linear(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - - u16 value = 0; - int exponent, mantissa; - int multiplier = 1000; - - if (!data->valid) { - return 0; - } - - switch (attr->index) { - case PSU_V_OUT: - value = data->v_out; - break; - case PSU_I_OUT: - value = data->i_out; - break; - case PSU_P_OUT: - value = data->p_out; - break; - case PSU_TEMP1_INPUT: - value = data->temp; - break; - case PSU_FAN1_SPEED: - value = data->fan_speed; - multiplier = 1; - break; - case PSU_FAN1_DUTY_CYCLE: - value = data->fan_duty_cycle[0]; - multiplier = 1; - break; - case PSU_MFR_VIN_MIN: - value = data->mfr_vin_min; - break; - case PSU_MFR_VIN_MAX: - value = data->mfr_vin_max; - break; - case PSU_MFR_VOUT_MIN: - value = data->mfr_vout_min; - break; - case PSU_MFR_VOUT_MAX: - value = data->mfr_vout_max; - break; - case PSU_MFR_PIN_MAX: - value = data->mfr_pin_max; - break; - case PSU_MFR_POUT_MAX: - value = data->mfr_pout_max; - break; - case PSU_MFR_IOUT_MAX: - value = data->mfr_iout_max; - break; - case PSU_MFR_IIN_MAX: - value = data->mfr_iin_max; - break; - } - - exponent = two_complement_to_int(value >> 11, 5, 0x1f); - mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); - - return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : - sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); -} - -static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - u8 shift; - - if (!data->valid) { - return 0; - } - - shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; - - return sprintf(buf, "%d\n", data->fan_fault >> shift); -} - -static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct ym2651y_data *data = ym2651y_update_device(dev); - - if (!data->valid) { - return 0; - } - - return sprintf(buf, "%d\n", data->over_temp >> 7); -} - -static ssize_t show_ascii(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - u8 *ptr = NULL; - - if (!data->valid) { - return 0; - } - - switch (attr->index) { - case PSU_FAN_DIRECTION: /* psu_fan_dir */ - ptr = data->fan_dir + 1; /* Skip the first byte since it is the length of string. */ - break; - case PSU_MFR_ID: /* psu_mfr_id */ - ptr = data->mfr_id + 1; /* The first byte is the count byte of string. */; - break; - case PSU_MFR_MODEL: /* psu_mfr_model */ - ptr = data->mfr_model + 1; /* The first byte is the count byte of string. */ - break; - case PSU_MFR_REVISION: /* psu_mfr_revision */ - ptr = data->mfr_revsion + 1; /* The first byte is the count byte of string. */ - break; - default: - return 0; - } - - return sprintf(buf, "%s\n", ptr); -} - -static ssize_t show_vout_by_mode(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct ym2651y_data *data = ym2651y_update_device(dev); - int exponent, mantissa; - int multiplier = 1000; - - if (!data->valid) { - return 0; - } - - exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); - mantissa = data->v_out; - - return (exponent > 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : - sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); -} - -static ssize_t show_vout(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct ym2651y_data *data = i2c_get_clientdata(client); - - if (data->chip == YM2401) { - return show_vout_by_mode(dev, da, buf); - } - - return show_linear(dev, da, buf); -} - -static const struct attribute_group ym2651y_group = { - .attrs = ym2651y_attributes, -}; - -static int ym2651y_probe(struct i2c_client *client, - const struct i2c_device_id *dev_id) -{ - struct ym2651y_data *data; - int status; - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_WORD_DATA | - I2C_FUNC_SMBUS_I2C_BLOCK)) { - status = -EIO; - goto exit; - } - - data = kzalloc(sizeof(struct ym2651y_data), GFP_KERNEL); - if (!data) { - status = -ENOMEM; - goto exit; - } - - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - data->chip = dev_id->driver_data; - dev_info(&client->dev, "chip found\n"); - - /* Register sysfs hooks */ - status = sysfs_create_group(&client->dev.kobj, &ym2651y_group); - if (status) { - goto exit_free; - } - - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - status = PTR_ERR(data->hwmon_dev); - goto exit_remove; - } - - dev_info(&client->dev, "%s: psu '%s'\n", - dev_name(data->hwmon_dev), client->name); - - return 0; - -exit_remove: - sysfs_remove_group(&client->dev.kobj, &ym2651y_group); -exit_free: - kfree(data); -exit: - - return status; -} - -static int ym2651y_remove(struct i2c_client *client) -{ - struct ym2651y_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &ym2651y_group); - kfree(data); - - return 0; -} - -static const struct i2c_device_id ym2651y_id[] = { - { "ym2651", YM2651 }, - { "ym2401", YM2401 }, - {} -}; -MODULE_DEVICE_TABLE(i2c, ym2651y_id); - -static struct i2c_driver ym2651y_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "ym2651", - }, - .probe = ym2651y_probe, - .remove = ym2651y_remove, - .id_table = ym2651y_id, - .address_list = normal_i2c, -}; - -static int ym2651y_read_byte(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_byte_data(client, reg); -} - -static int ym2651y_read_word(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_word_data(client, reg); -} - -static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value) -{ - return i2c_smbus_write_word_data(client, reg, value); -} - -static int ym2651y_read_block(struct i2c_client *client, u8 command, u8 *data, - int data_len) -{ - int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); - - if (unlikely(result < 0)) - goto abort; - if (unlikely(result != data_len)) { - result = -EIO; - goto abort; - } - - result = 0; - -abort: - return result; -} - -struct reg_data_byte { - u8 reg; - u8 *value; -}; - -struct reg_data_word { - u8 reg; - u16 *value; -}; - -static struct ym2651y_data *ym2651y_update_device(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct ym2651y_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) - || !data->valid) { - int i, status, length; - u8 command, buf; - struct reg_data_byte regs_byte[] = { {0x19, &data->capability}, - {0x20, &data->vout_mode}, - {0x7d, &data->over_temp}, - {0x81, &data->fan_fault}, - {0x98, &data->pmbus_revision}}; - struct reg_data_word regs_word[] = { {0x79, &data->status_word}, - {0x8b, &data->v_out}, - {0x8c, &data->i_out}, - {0x96, &data->p_out}, - {0x8d, &data->temp}, - {0x3b, &(data->fan_duty_cycle[0])}, - {0x3c, &(data->fan_duty_cycle[1])}, - {0x90, &data->fan_speed}, - {0xa0, &data->mfr_vin_min}, - {0xa1, &data->mfr_vin_max}, - {0xa2, &data->mfr_iin_max}, - {0xa3, &data->mfr_pin_max}, - {0xa4, &data->mfr_vout_min}, - {0xa5, &data->mfr_vout_max}, - {0xa6, &data->mfr_iout_max}, - {0xa7, &data->mfr_pout_max}}; - - dev_dbg(&client->dev, "Starting ym2651 update\n"); - data->valid = 0; - - /* Read byte data */ - for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { - status = ym2651y_read_byte(client, regs_byte[i].reg); - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_byte[i].reg, status); - goto exit; - } - else { - *(regs_byte[i].value) = status; - } - } - - /* Read word data */ - for (i = 0; i < ARRAY_SIZE(regs_word); i++) { - status = ym2651y_read_word(client, regs_word[i].reg); - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_word[i].reg, status); - goto exit; - } - else { - *(regs_word[i].value) = status; - } - } - - /* Read fan_direction */ - command = 0xC3; - status = ym2651y_read_block(client, command, data->fan_dir, - ARRAY_SIZE(data->fan_dir)-1); - data->fan_dir[ARRAY_SIZE(data->fan_dir)-1] = '\0'; - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - goto exit; - } - - /* Read mfr_id */ - command = 0x99; - status = ym2651y_read_block(client, command, data->mfr_id, - ARRAY_SIZE(data->mfr_id)-1); - data->mfr_id[ARRAY_SIZE(data->mfr_id)-1] = '\0'; - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - goto exit; - } - - /* Read mfr_model */ - command = 0x9a; - length = 1; - - /* Read first byte to determine the length of data */ - status = ym2651y_read_block(client, command, &buf, length); - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - goto exit; - } - - status = ym2651y_read_block(client, command, data->mfr_model, buf+1); - data->mfr_model[buf+1] = '\0'; - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - goto exit; - } - - /* Read mfr_revsion */ - command = 0x9b; - status = ym2651y_read_block(client, command, data->mfr_revsion, - ARRAY_SIZE(data->mfr_revsion)-1); - data->mfr_revsion[ARRAY_SIZE(data->mfr_revsion)-1] = '\0'; - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - goto exit; - } - - data->last_updated = jiffies; - data->valid = 1; - } - -exit: - mutex_unlock(&data->update_lock); - - return data; -} - -static int __init ym2651y_init(void) -{ - return i2c_add_driver(&ym2651y_driver); -} - -static void __exit ym2651y_exit(void) -{ - i2c_del_driver(&ym2651y_driver); -} - -MODULE_AUTHOR("Brandon Chuang "); -MODULE_DESCRIPTION("3Y Power YM-2651Y driver"); -MODULE_LICENSE("GPL"); - -module_init(ym2651y_init); -module_exit(ym2651y_exit); - diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/ym2651y.c new file mode 120000 index 000000000000..f4d67640ccc3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/ym2651y.c @@ -0,0 +1 @@ +../../common/modules/ym2651y.c \ No newline at end of file diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/classes/__init__.py old mode 100644 new mode 100755 similarity index 100% rename from platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/fanutil.py rename to platform/broadcom/sonic-platform-modules-accton/as5812-54t/classes/__init__.py diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/classes/fanutil.py new file mode 100755 index 000000000000..223408fb962c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/classes/fanutil.py @@ -0,0 +1,243 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# +# ------------------------------------------------------------------ + +try: + import time + import logging + from collections import namedtuple +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + + +class FanUtil(object): + """Platform-specific FanUtil class""" + + FAN_NUM_ON_MAIN_BROAD = 5 + FAN_NUM_1_IDX = 1 + FAN_NUM_2_IDX = 2 + FAN_NUM_3_IDX = 3 + FAN_NUM_4_IDX = 4 + FAN_NUM_5_IDX = 5 + + FAN_NODE_NUM_OF_MAP = 6 + FAN_NODE_FAULT_IDX_OF_MAP = 1 + FAN_NODE_SPEED_IDX_OF_MAP = 2 + FAN_NODE_DIR_IDX_OF_MAP = 3 + FAN_NODE_DUTY_IDX_OF_MAP = 4 + FANR_NODE_FAULT_IDX_OF_MAP = 5 + FANR_NODE_SPEED_IDX_OF_MAP = 6 + + BASE_VAL_PATH = '/sys/devices/platform/as5812_54t_fan/{0}' + + #logfile = '' + #loglevel = logging.INFO + + """ Dictionary where + key1 = fan id index (integer) starting from 1 + key2 = fan node index (interger) starting from 1 + value = path to fan device file (string) """ + _fan_to_device_path_mapping = {} + + _fan_to_device_node_mapping = { + (FAN_NUM_1_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan1_fault', + (FAN_NUM_1_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan1_speed_rpm', + (FAN_NUM_1_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan1_direction', + (FAN_NUM_1_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan1_duty_cycle_percentage', + (FAN_NUM_1_IDX, FANR_NODE_FAULT_IDX_OF_MAP): 'fanr1_fault', + (FAN_NUM_1_IDX, FANR_NODE_SPEED_IDX_OF_MAP): 'fanr1_speed_rpm', + + (FAN_NUM_2_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan2_fault', + (FAN_NUM_2_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan2_speed_rpm', + (FAN_NUM_2_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan2_direction', + (FAN_NUM_2_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan2_duty_cycle_percentage', + (FAN_NUM_2_IDX, FANR_NODE_FAULT_IDX_OF_MAP): 'fanr2_fault', + (FAN_NUM_2_IDX, FANR_NODE_SPEED_IDX_OF_MAP): 'fanr2_speed_rpm', + + (FAN_NUM_3_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan3_fault', + (FAN_NUM_3_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan3_speed_rpm', + (FAN_NUM_3_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan3_direction', + (FAN_NUM_3_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan3_duty_cycle_percentage', + (FAN_NUM_3_IDX, FANR_NODE_FAULT_IDX_OF_MAP): 'fanr3_fault', + (FAN_NUM_3_IDX, FANR_NODE_SPEED_IDX_OF_MAP): 'fanr3_speed_rpm', + + (FAN_NUM_4_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan4_fault', + (FAN_NUM_4_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan4_speed_rpm', + (FAN_NUM_4_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan4_direction', + (FAN_NUM_4_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan4_duty_cycle_percentage', + (FAN_NUM_4_IDX, FANR_NODE_FAULT_IDX_OF_MAP): 'fanr4_fault', + (FAN_NUM_4_IDX, FANR_NODE_SPEED_IDX_OF_MAP): 'fanr4_speed_rpm', + + (FAN_NUM_5_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan5_fault', + (FAN_NUM_5_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan5_speed_rpm', + (FAN_NUM_5_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan5_direction', + (FAN_NUM_5_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan5_duty_cycle_percentage', + (FAN_NUM_5_IDX, FANR_NODE_FAULT_IDX_OF_MAP): 'fanr5_fault', + (FAN_NUM_5_IDX, FANR_NODE_SPEED_IDX_OF_MAP): 'fanr5_speed_rpm', + } + + logger = logging.getLogger(__name__) + def __init__(self, log_level=logging.DEBUG): + ch = logging.StreamHandler() + ch.setLevel(log_level) + self.logger.addHandler(ch) + + fan_path = self.BASE_VAL_PATH + for fan_num in range(self.FAN_NUM_1_IDX, self.FAN_NUM_ON_MAIN_BROAD+1): + for node_num in range(self.FAN_NODE_FAULT_IDX_OF_MAP, self.FAN_NODE_NUM_OF_MAP+1): + self._fan_to_device_path_mapping[(fan_num, node_num)] = fan_path.format( + self._fan_to_device_node_mapping[(fan_num, node_num)]) + + + def _get_fan_to_device_node(self, fan_num, node_num): + return self._fan_to_device_node_mapping[(fan_num, node_num)] + + def _get_fan_node_val(self, fan_num, node_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + self.logger.debug('GET. Parameter error. fan_num:%d', fan_num) + return None + + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + self.logger.debug('GET. Parameter error. node_num:%d', node_num) + return None + + device_path = self.get_fan_to_device_path(fan_num, node_num) + try: + val_file = open(device_path, 'r') + except IOError as e: + self.logger.error('GET. unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + self.logger.debug('GET. content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except: + self.logger.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return int(content) + + def _set_fan_node_val(self, fan_num, node_num, val): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + self.logger.debug('GET. Parameter error. fan_num:%d', fan_num) + return None + + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + self.logger.debug('GET. Parameter error. node_num:%d', node_num) + return None + + content = str(val) + if content == '': + self.logger.debug('GET. content is NULL. device_path:%s', device_path) + return None + + device_path = self.get_fan_to_device_path(fan_num, node_num) + try: + val_file = open(device_path, 'w') + except IOError as e: + self.logger.error('GET. unable to open file: %s', str(e)) + return None + + val_file.write(content) + + try: + val_file.close() + except: + self.logger.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return True + + def get_num_fans(self): + return self.FAN_NUM_ON_MAIN_BROAD + + def get_idx_fan_start(self): + return self.FAN_NUM_1_IDX + + def get_num_nodes(self): + return self.FAN_NODE_NUM_OF_MAP + + def get_idx_node_start(self): + return self.FAN_NODE_FAULT_IDX_OF_MAP + + def get_size_node_map(self): + return len(self._fan_to_device_node_mapping) + + def get_size_path_map(self): + return len(self._fan_to_device_path_mapping) + + def get_fan_to_device_path(self, fan_num, node_num): + return self._fan_to_device_path_mapping[(fan_num, node_num)] + + def get_fan_fault(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_FAULT_IDX_OF_MAP) + + def get_fan_speed(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_SPEED_IDX_OF_MAP) + + def get_fan_dir(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_DIR_IDX_OF_MAP) + + def get_fan_duty_cycle(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_DUTY_IDX_OF_MAP) + + def set_fan_duty_cycle(self, fan_num, val): + return self._set_fan_node_val(fan_num, self.FAN_NODE_DUTY_IDX_OF_MAP, val) + + def get_fanr_fault(self, fan_num): + return self._get_fan_node_val(fan_num, self.FANR_NODE_FAULT_IDX_OF_MAP) + + def get_fanr_speed(self, fan_num): + return self._get_fan_node_val(fan_num, self.FANR_NODE_SPEED_IDX_OF_MAP) + + def get_fan_status(self, fan_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + self.logger.debug('GET. Parameter error. fan_num, %d', fan_num) + return None + + if self.get_fan_fault(fan_num) is not None and self.get_fan_fault(fan_num) > 0: + self.logger.debug('GET. FAN fault. fan_num, %d', fan_num) + return False + + if self.get_fanr_fault(fan_num) is not None and self.get_fanr_fault(fan_num) > 0: + self.logger.debug('GET. FANR fault. fan_num, %d', fan_num) + return False + + return True + +#def main(): +# fan = FanUtil() +# +# print 'get_size_node_map : %d' % fan.get_size_node_map() +# print 'get_size_path_map : %d' % fan.get_size_path_map() +# for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): +# for y in range(fan.get_idx_node_start(), fan.get_num_nodes()+1): +# print fan.get_fan_to_device_path(x, y) +# +#if __name__ == '__main__': +# main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/classes/thermalutil.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/classes/thermalutil.py new file mode 100755 index 000000000000..0095a7871029 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/classes/thermalutil.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# +# ------------------------------------------------------------------ + +try: + import time + import logging + import glob + from collections import namedtuple +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + + +class ThermalUtil(object): + """Platform-specific ThermalUtil class""" + + THERMAL_NUM_ON_MAIN_BROAD = 3 + THERMAL_NUM_1_IDX = 1 # 1_ON_MAIN_BROAD + THERMAL_NUM_2_IDX = 2 # 2_ON_MAIN_BROAD + THERMAL_NUM_3_IDX = 3 # 3_ON_MAIN_BROAD + + BASE_VAL_PATH = '/sys/bus/i2c/devices/{0}-00{1}/hwmon/hwmon*/temp1_input' + + """ Dictionary where + key1 = thermal id index (integer) starting from 1 + value = path to fan device file (string) """ + _thermal_to_device_path_mapping = {} + + _thermal_to_device_node_mapping = { + THERMAL_NUM_1_IDX: ['15', '48'], + THERMAL_NUM_2_IDX: ['16', '49'], + THERMAL_NUM_3_IDX: ['17', '4a'], + } + + logger = logging.getLogger(__name__) + def __init__(self, log_level=logging.DEBUG): + ch = logging.StreamHandler() + ch.setLevel(log_level) + self.logger.addHandler(ch) + thermal_path = self.BASE_VAL_PATH + + for x in range(self.THERMAL_NUM_1_IDX, self.THERMAL_NUM_ON_MAIN_BROAD+1): + self._thermal_to_device_path_mapping[x] = thermal_path.format( + self._thermal_to_device_node_mapping[x][0], + self._thermal_to_device_node_mapping[x][1]) + + def _get_thermal_node_val(self, thermal_num): + if thermal_num < self.THERMAL_NUM_1_IDX or thermal_num > self.THERMAL_NUM_ON_MAIN_BROAD: + self.logger.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: + self.logger.error('GET. unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + self.logger.debug('GET. content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except: + self.logger.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return int(content) + + + def get_num_thermals(self): + return self.THERMAL_NUM_ON_MAIN_BROAD + + def get_idx_thermal_start(self): + return self.THERMAL_NUM_1_IDX + + def get_size_node_map(self): + return len(self._thermal_to_device_node_mapping) + + def get_size_path_map(self): + return len(self._thermal_to_device_path_mapping) + + def get_thermal_to_device_path(self, thermal_num): + return self._thermal_to_device_path_mapping[thermal_num] + + def get_thermal_1_val(self): + return self._get_thermal_node_val(self.THERMAL_NUM_1_IDX) + + def get_thermal_2_val(self): + return self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) + +#def main(): +# thermal = ThermalUtil() +# +# print 'get_size_node_map : %d' % thermal.get_size_node_map() +# print 'get_size_path_map : %d' % thermal.get_size_path_map() +# for x in range(thermal.get_idx_thermal_start(), thermal.get_num_thermals()+1): +# print thermal.get_thermal_to_device_path(x) +# +#if __name__ == '__main__': +# main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/Makefile b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/Makefile old mode 100644 new mode 100755 index 697dcff656c3..db535d8d6771 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/Makefile @@ -1,4 +1,4 @@ -obj-m:=accton_i2c_cpld.o x86-64-accton-as5812-54t-fan.o \ - x86-64-accton-as5812-54t-leds.o x86-64-accton-as5812-54t-psu.o \ - x86-64-accton-as5812-54t-sfp.o ym2651y.o +obj-m:= x86-64-accton-as5812-54t-cpld.o x86-64-accton-as5812-54t-fan.o \ + x86-64-accton-as5812-54t-leds.o \ + x86-64-accton-as5812-54t-psu.o ym2651y.o cpr_4011_4mxx.o diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/accton_i2c_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/accton_i2c_cpld.c deleted file mode 100644 index c01d6bcca228..000000000000 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/accton_i2c_cpld.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * A hwmon driver for the accton_i2c_cpld - * - * Copyright (C) 2013 Accton Technology Corporation. - * Brandon Chuang - * - * Based on ad7414.c - * Copyright 2006 Stefan Roese , DENX Software Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include - -static LIST_HEAD(cpld_client_list); -static struct mutex list_lock; - -struct cpld_client_node { - struct i2c_client *client; - struct list_head list; -}; - -/* Addresses scanned for accton_i2c_cpld - */ -static const unsigned short normal_i2c[] = { 0x31, 0x35, 0x60, 0x61, 0x62, 0x64, I2C_CLIENT_END }; - -static ssize_t show_cpld_version(struct device *dev, struct device_attribute *attr, char *buf) -{ - int val = 0; - struct i2c_client *client = to_i2c_client(dev); - - val = i2c_smbus_read_byte_data(client, 0x1); - - if (val < 0) { - dev_dbg(&client->dev, "cpld(0x%x) reg(0x1) err %d\n", client->addr, val); - } - - return sprintf(buf, "%d", val); -} - -static struct device_attribute ver = __ATTR(version, 0600, show_cpld_version, NULL); - -static void accton_i2c_cpld_add_client(struct i2c_client *client) -{ - struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); - - if (!node) { - dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); - return; - } - - node->client = client; - - mutex_lock(&list_lock); - list_add(&node->list, &cpld_client_list); - mutex_unlock(&list_lock); -} - -static void accton_i2c_cpld_remove_client(struct i2c_client *client) -{ - struct list_head *list_node = NULL; - struct cpld_client_node *cpld_node = NULL; - int found = 0; - - mutex_lock(&list_lock); - - list_for_each(list_node, &cpld_client_list) - { - cpld_node = list_entry(list_node, struct cpld_client_node, list); - - if (cpld_node->client == client) { - found = 1; - break; - } - } - - if (found) { - list_del(list_node); - kfree(cpld_node); - } - - mutex_unlock(&list_lock); -} - -static int accton_i2c_cpld_probe(struct i2c_client *client, - const struct i2c_device_id *dev_id) -{ - int status; - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { - dev_dbg(&client->dev, "i2c_check_functionality failed (0x%x)\n", client->addr); - status = -EIO; - goto exit; - } - - status = sysfs_create_file(&client->dev.kobj, &ver.attr); - if (status) { - goto exit; - } - - dev_info(&client->dev, "chip found\n"); - accton_i2c_cpld_add_client(client); - - return 0; - -exit: - return status; -} - -static int accton_i2c_cpld_remove(struct i2c_client *client) -{ - sysfs_remove_file(&client->dev.kobj, &ver.attr); - accton_i2c_cpld_remove_client(client); - - return 0; -} - -static const struct i2c_device_id accton_i2c_cpld_id[] = { - { "accton_i2c_cpld", 0 }, - {} -}; -MODULE_DEVICE_TABLE(i2c, accton_i2c_cpld_id); - -static struct i2c_driver accton_i2c_cpld_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "accton_i2c_cpld", - }, - .probe = accton_i2c_cpld_probe, - .remove = accton_i2c_cpld_remove, - .id_table = accton_i2c_cpld_id, - .address_list = normal_i2c, -}; - -int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg) -{ - struct list_head *list_node = NULL; - struct cpld_client_node *cpld_node = NULL; - int ret = -EPERM; - - mutex_lock(&list_lock); - - list_for_each(list_node, &cpld_client_list) - { - cpld_node = list_entry(list_node, struct cpld_client_node, list); - - if (cpld_node->client->addr == cpld_addr) { - ret = i2c_smbus_read_byte_data(cpld_node->client, reg); - break; - } - } - - mutex_unlock(&list_lock); - - return ret; -} -EXPORT_SYMBOL(accton_i2c_cpld_read); - -int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) -{ - struct list_head *list_node = NULL; - struct cpld_client_node *cpld_node = NULL; - int ret = -EIO; - - mutex_lock(&list_lock); - - list_for_each(list_node, &cpld_client_list) - { - cpld_node = list_entry(list_node, struct cpld_client_node, list); - - if (cpld_node->client->addr == cpld_addr) { - ret = i2c_smbus_write_byte_data(cpld_node->client, reg, value); - break; - } - } - - mutex_unlock(&list_lock); - - return ret; -} -EXPORT_SYMBOL(accton_i2c_cpld_write); - -static int __init accton_i2c_cpld_init(void) -{ - mutex_init(&list_lock); - return i2c_add_driver(&accton_i2c_cpld_driver); -} - -static void __exit accton_i2c_cpld_exit(void) -{ - i2c_del_driver(&accton_i2c_cpld_driver); -} - -static struct dmi_system_id as7512_dmi_table[] = { - { - .ident = "Accton AS7512", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Accton"), - DMI_MATCH(DMI_PRODUCT_NAME, "AS7512"), - }, - }, - { - .ident = "Accton AS7512", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Accton"), - DMI_MATCH(DMI_PRODUCT_NAME, "AS7512"), - }, - }, -}; - -int platform_accton_as7512_32x(void) -{ - return dmi_check_system(as7512_dmi_table); -} -EXPORT_SYMBOL(platform_accton_as7512_32x); - -static struct dmi_system_id as7712_dmi_table[] = { - { - .ident = "Accton AS7712", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Accton"), - DMI_MATCH(DMI_PRODUCT_NAME, "AS7712"), - }, - }, - { - .ident = "Accton AS7712", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Accton"), - DMI_MATCH(DMI_PRODUCT_NAME, "AS7712"), - }, - }, -}; - -int platform_accton_as7712_32x(void) -{ - return dmi_check_system(as7712_dmi_table); -} -EXPORT_SYMBOL(platform_accton_as7712_32x); - -static struct dmi_system_id as5812_54t_dmi_table[] = { - { - .ident = "Accton AS5812 54t", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Accton"), - DMI_MATCH(DMI_PRODUCT_NAME, "AS5812-54T"), - }, - }, - { - .ident = "Accton AS5812 54t", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Accton"), - DMI_MATCH(DMI_PRODUCT_NAME, "AS5812-54T"), - }, - }, -}; - -int platform_accton_as5812_54t(void) -{ - return dmi_check_system(as5812_54t_dmi_table); -} -EXPORT_SYMBOL(platform_accton_as5812_54t); - -static struct dmi_system_id as5512_54x_dmi_table[] = { - { - .ident = "Accton AS5512", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Accton"), - DMI_MATCH(DMI_PRODUCT_NAME, "AS5512"), - }, - }, - { - .ident = "Accton AS5512", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Accton"), - DMI_MATCH(DMI_PRODUCT_NAME, "AS5512"), - }, - }, -}; - -int platform_accton_as5512_54x(void) -{ - return dmi_check_system(as5512_54x_dmi_table); -} -EXPORT_SYMBOL(platform_accton_as5512_54x); - -static struct dmi_system_id as7716_dmi_table[] = { - { - .ident = "Accton AS7716", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Accton"), - DMI_MATCH(DMI_PRODUCT_NAME, "AS7716"), - }, - }, - { - .ident = "Accton AS7716", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Accton"), - DMI_MATCH(DMI_PRODUCT_NAME, "AS7716"), - }, - }, -}; - -int platform_accton_as7716_32x(void) -{ - return dmi_check_system(as7716_dmi_table); -} -EXPORT_SYMBOL(platform_accton_as7716_32x); - -MODULE_AUTHOR("Brandon Chuang "); -MODULE_DESCRIPTION("accton_i2c_cpld driver"); -MODULE_LICENSE("GPL"); - -module_init(accton_i2c_cpld_init); -module_exit(accton_i2c_cpld_exit); diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/cpr_4011_4mxx.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/cpr_4011_4mxx.c new file mode 120000 index 000000000000..fd43cc1f1c77 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/cpr_4011_4mxx.c @@ -0,0 +1 @@ +../../common/modules/cpr_4011_4mxx.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-cpld.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-cpld.c new file mode 100755 index 000000000000..2d44d5355ca0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-cpld.c @@ -0,0 +1,544 @@ +/* + * A hwmon driver for the as5812_54t_cpld + * + * Copyright (C) 2013 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +#define I2C_RW_RETRY_COUNT 10 +#define I2C_RW_RETRY_INTERVAL 60 /* ms */ + +static ssize_t show_bit(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t set_1bit(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t show_present_all(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t show_version(struct device *dev, struct device_attribute *da, + char *buf); +static int as5812_54t_cpld_read_internal(struct i2c_client *client, u8 reg); +static int as5812_54t_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value); + +struct as5812_54t_cpld_data { + struct device *hwmon_dev; + struct mutex update_lock; +}; + +/* Addresses scanned for as5812_54t_cpld + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + + + +#define _ATTR_CONCAT(name,idx) name##idx + +#define TRANSCEIVER_ATTR_ID(_attr) \ + _ATTR_CONCAT(MODULE_##_attr##_, 49), \ + _ATTR_CONCAT(MODULE_##_attr##_, 50), \ + _ATTR_CONCAT(MODULE_##_attr##_, 51), \ + _ATTR_CONCAT(MODULE_##_attr##_, 52), \ + _ATTR_CONCAT(MODULE_##_attr##_, 53), \ + _ATTR_CONCAT(MODULE_##_attr##_, 54) + + +enum as5812_54t_cpld_sysfs_attributes { + CPLD_VERSION, + ACCESS, + MODULE_PRESENT_ALL, + /* transceiver attributes */ + TRANSCEIVER_ATTR_ID(PRESENT), + TRANSCEIVER_ATTR_ID(LPMODE), + TRANSCEIVER_ATTR_ID(RESET), +}; + +/* sysfs attributes for hwmon + */ + +/* transceiver attributes */ +#define DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, show_bit, NULL, MODULE_PRESENT_##index);\ + static SENSOR_DEVICE_ATTR(module_lp_mode_##index, S_IRUGO|S_IWUSR, show_bit, set_1bit, MODULE_LPMODE_##index);\ + static SENSOR_DEVICE_ATTR(module_reset_##index, S_IRUGO|S_IWUSR, show_bit, set_1bit, MODULE_RESET_##index) + +#define DECLARE_TRANSCEIVER_ATTR(index) &sensor_dev_attr_module_present_##index.dev_attr.attr, \ + &sensor_dev_attr_module_lp_mode_##index.dev_attr.attr, \ + &sensor_dev_attr_module_reset_##index.dev_attr.attr + + + +static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION); +static SENSOR_DEVICE_ATTR(access, S_IWUSR, NULL, access, ACCESS); +/* transceiver attributes */ +static SENSOR_DEVICE_ATTR(module_present_all, S_IRUGO, show_present_all, NULL, MODULE_PRESENT_ALL); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(49); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(50); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(51); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(52); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(53); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(54); + +static struct attribute *as5812_54t_cpld_attributes[] = { + &sensor_dev_attr_version.dev_attr.attr, + &sensor_dev_attr_access.dev_attr.attr, + /* transceiver attributes */ + &sensor_dev_attr_module_present_all.dev_attr.attr, + DECLARE_TRANSCEIVER_ATTR(49), + DECLARE_TRANSCEIVER_ATTR(50), + DECLARE_TRANSCEIVER_ATTR(51), + DECLARE_TRANSCEIVER_ATTR(52), + DECLARE_TRANSCEIVER_ATTR(53), + DECLARE_TRANSCEIVER_ATTR(54), + NULL +}; + +static const struct attribute_group as5812_54t_cpld_group = { + .attrs = as5812_54t_cpld_attributes, +}; + +static ssize_t show_present_all(struct device *dev, struct device_attribute *da, + char *buf) +{ + int status; + u8 value = 0; + u8 reg = 0x22; + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54t_cpld_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + status = as5812_54t_cpld_read_internal(client, reg); + if (status < 0) { + goto exit; + } + + value = ~(u8)status; + value &= 0x3F; + + mutex_unlock(&data->update_lock); + + /* Return values 49 -> 54 in order */ + return sprintf(buf, "%.2x\n", value); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static int get_reg_index(struct sensor_device_attribute *attr, u8 *reg, u8 *index, u8 *revert) { + if (attr->index >= MODULE_RESET_49){ + *reg = 0x23; + *index = attr->index - MODULE_RESET_49; + *revert = 1; + }else if (attr->index >= MODULE_LPMODE_49){ + *reg = 0x24; + *index = attr->index - MODULE_LPMODE_49; + *revert = 0; + } else { + *reg = 0x22; + *index = attr->index - MODULE_PRESENT_49; + *revert = 1; + } + return 0; +} + +static ssize_t set_1bit(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + u8 index, revert; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54t_cpld_data *data = i2c_get_clientdata(client); + int status, value; + u8 reg = 0, mask = 0; + + status = kstrtoint(buf, 10, &value); + if (status) + return status; + + get_reg_index(attr, ®, &index, &revert); + mask = 0x1 << index; + + mutex_lock(&data->update_lock); + status = as5812_54t_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + status &= ~(mask); + value = !value; + if (!revert) + value = !value; + status |= (value << index); /*low-active*/ + status = as5812_54t_cpld_write_internal(client, reg, status); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t show_bit(struct device *dev, struct device_attribute *da, + char *buf) +{ + u8 index, revert; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54t_cpld_data *data = i2c_get_clientdata(client); + int status = 0; + u8 reg = 0, mask = 0; + + get_reg_index(attr, ®, &index, &revert); + mask = 0x1 << index; + + mutex_lock(&data->update_lock); + status = as5812_54t_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + + status = !(status & mask); + if (!revert) + status = !status; + + return sprintf(buf, "%d\n", status); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t show_version(struct device *dev, struct device_attribute *da, + char *buf) +{ + u8 reg = 0, mask = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54t_cpld_data *data = i2c_get_clientdata(client); + int status = 0; + + switch (attr->index) { + case CPLD_VERSION: + reg = 0x1; + mask = 0xFF; + break; + default: + break; + } + + mutex_lock(&data->update_lock); + status = as5812_54t_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", (status & mask)); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int status; + u32 addr, val; + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54t_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 = as5812_54t_cpld_write_internal(client, addr, val); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static int as5812_54t_cpld_read_internal(struct i2c_client *client, u8 reg) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, reg); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + +static int as5812_54t_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, reg, value); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + +static void as5812_54t_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 as5812_54t_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 as5812_54t_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + struct as5812_54t_cpld_data *data = NULL; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_dbg(&client->dev, "i2c_check_functionality failed (0x%x)\n", client->addr); + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as5812_54t_cpld_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as5812_54t_cpld_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register_with_info(&client->dev, "as5812_54t_cpld", + NULL, NULL, NULL); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + as5812_54t_cpld_add_client(client); + + /* + * Bring QSFPs out of reset, + * This is a temporary fix until the QSFP+_MOD_RST register + * can be exposed through the driver. + */ + as5812_54t_cpld_write_internal(client, 0x23, 0x3F); + + dev_info(&client->dev, "%s: cpld '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as5812_54t_cpld_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as5812_54t_cpld_remove(struct i2c_client *client) +{ + struct as5812_54t_cpld_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as5812_54t_cpld_group); + kfree(data); + as5812_54t_cpld_remove_client(client); + + return 0; +} + +int as5812_54t_cpld_read(unsigned short cpld_addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EPERM; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_read_byte_data(cpld_node->client, reg); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(as5812_54t_cpld_read); + +int as5812_54t_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(as5812_54t_cpld_write); + +static const struct i2c_device_id as5812_54t_cpld_id[] = { + { "as5812_54t_cpld", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as5812_54t_cpld_id); + +static struct i2c_driver as5812_54t_cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as5812_54t_cpld", + }, + .probe = as5812_54t_cpld_probe, + .remove = as5812_54t_cpld_remove, + .id_table = as5812_54t_cpld_id, + .address_list = normal_i2c, +}; + +static int __init as5812_54t_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&as5812_54t_cpld_driver); +} + +static void __exit as5812_54t_cpld_exit(void) +{ + i2c_del_driver(&as5812_54t_cpld_driver); +} + +module_init(as5812_54t_cpld_init); +module_exit(as5812_54t_cpld_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as5812_54t_cpld driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-fan.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-fan.c index bad9245e93ac..66370fb37ff4 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-fan.c +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-fan.c @@ -33,6 +33,8 @@ #include #include +#define DRVNAME "as5812_54t_fan" + #define FAN_MAX_NUMBER 5 #define FAN_SPEED_CPLD_TO_RPM_STEP 150 #define FAN_SPEED_PRECENT_TO_CPLD_STEP 5 @@ -130,47 +132,62 @@ static ssize_t fan_set_duty_cycle(struct device *dev, struct device_attribute *da,const char *buf, size_t count); static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_name(struct device *dev, + struct device_attribute *da, char *buf); -extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); -extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); +extern int as5812_54t_cpld_read(unsigned short cpld_addr, u8 reg); +extern int as5812_54t_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); /*******************/ -#define _MAKE_SENSOR_DEVICE_ATTR(prj, id) \ - static SENSOR_DEVICE_ATTR(prj##fan##id##_fault, S_IRUGO, fan_show_value, NULL, FAN##id##_FAULT); \ +#define _MAKE_SENSOR_DEVICE_ATTR(prj, id, id2) \ static SENSOR_DEVICE_ATTR(prj##fan##id##_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##id##_SPEED); \ static SENSOR_DEVICE_ATTR(prj##fan##id##_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, \ fan_set_duty_cycle, FAN##id##_DUTY_CYCLE); \ + static SENSOR_DEVICE_ATTR(prj##pwm##id, S_IWUSR | S_IRUGO, fan_show_value, \ + fan_set_duty_cycle, FAN##id##_DUTY_CYCLE); \ static SENSOR_DEVICE_ATTR(prj##fan##id##_direction, S_IRUGO, fan_show_value, NULL, FAN##id##_DIRECTION); \ static SENSOR_DEVICE_ATTR(prj##fanr##id##_fault, S_IRUGO, fan_show_value, NULL, FANR##id##_FAULT); \ - static SENSOR_DEVICE_ATTR(prj##fanr##id##_speed_rpm, S_IRUGO, fan_show_value, NULL, FANR##id##_SPEED); + static SENSOR_DEVICE_ATTR(prj##fanr##id##_speed_rpm, S_IRUGO, fan_show_value, NULL, FANR##id##_SPEED); \ + static SENSOR_DEVICE_ATTR(prj##fan##id##_input, S_IRUGO, fan_show_value, NULL, FAN##id##_SPEED); \ + static SENSOR_DEVICE_ATTR(prj##fan##id2##_input, S_IRUGO, fan_show_value, NULL, FANR##id##_SPEED); \ + static SENSOR_DEVICE_ATTR(prj##fan##id##_fault, S_IRUGO, fan_show_value, NULL, FAN##id##_FAULT); \ + static SENSOR_DEVICE_ATTR(prj##fan##id2##_fault, S_IRUGO, fan_show_value, NULL, FAN##id##_FAULT); -#define MAKE_SENSOR_DEVICE_ATTR(prj,id) _MAKE_SENSOR_DEVICE_ATTR(prj,id) +#define MAKE_SENSOR_DEVICE_ATTR(prj,id, id2) _MAKE_SENSOR_DEVICE_ATTR(prj,id, id2) -MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 1) -MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 2) -MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 3) -MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 4) -MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 5) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME,1,11) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME,2,12) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME,3,13) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME,4,14) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME,5,15) + +static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0); /*******************/ -#define _MAKE_FAN_ATTR(prj, id) \ - &sensor_dev_attr_##prj##fan##id##_fault.dev_attr.attr, \ +#define _MAKE_FAN_ATTR(prj, id, id2) \ &sensor_dev_attr_##prj##fan##id##_speed_rpm.dev_attr.attr, \ &sensor_dev_attr_##prj##fan##id##_duty_cycle_percentage.dev_attr.attr,\ + &sensor_dev_attr_##prj##pwm##id.dev_attr.attr,\ &sensor_dev_attr_##prj##fan##id##_direction.dev_attr.attr, \ &sensor_dev_attr_##prj##fanr##id##_fault.dev_attr.attr, \ - &sensor_dev_attr_##prj##fanr##id##_speed_rpm.dev_attr.attr, + &sensor_dev_attr_##prj##fanr##id##_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_##prj##fan##id##_input.dev_attr.attr, \ + &sensor_dev_attr_##prj##fan##id2##_input.dev_attr.attr, \ + &sensor_dev_attr_##prj##fan##id##_fault.dev_attr.attr, \ + &sensor_dev_attr_##prj##fan##id2##_fault.dev_attr.attr, -#define MAKE_FAN_ATTR(prj, id) _MAKE_FAN_ATTR(prj, id) + +#define MAKE_FAN_ATTR(prj, id, id2) _MAKE_FAN_ATTR(prj, id, id2) static struct attribute *accton_as5812_54t_fan_attributes[] = { /* fan related attributes */ - MAKE_FAN_ATTR(PROJECT_NAME,1) - MAKE_FAN_ATTR(PROJECT_NAME,2) - MAKE_FAN_ATTR(PROJECT_NAME,3) - MAKE_FAN_ATTR(PROJECT_NAME,4) - MAKE_FAN_ATTR(PROJECT_NAME,5) + MAKE_FAN_ATTR(PROJECT_NAME,1,11) + MAKE_FAN_ATTR(PROJECT_NAME,2,12) + MAKE_FAN_ATTR(PROJECT_NAME,3,13) + MAKE_FAN_ATTR(PROJECT_NAME,4,14) + MAKE_FAN_ATTR(PROJECT_NAME,5,15) + &sensor_dev_attr_name.dev_attr.attr, NULL }; /*******************/ @@ -232,6 +249,12 @@ static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, return ret; } + +static ssize_t show_name(struct device *dev, struct device_attribute *da, + char *buf) +{ + return sprintf(buf, "%s\n", DRVNAME); +} /*******************/ static ssize_t fan_set_duty_cycle(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { @@ -258,12 +281,12 @@ static const struct attribute_group accton_as5812_54t_fan_group = { static int accton_as5812_54t_fan_read_value(u8 reg) { - return accton_i2c_cpld_read(0x60, reg); + return as5812_54t_cpld_read(0x60, reg); } static int accton_as5812_54t_fan_write_value(u8 reg, u8 value) { - return accton_i2c_cpld_write(0x60, reg, value); + return as5812_54t_cpld_write(0x60, reg, value); } static void accton_as5812_54t_fan_update_device(struct device *dev) @@ -379,7 +402,6 @@ static int accton_as5812_54t_fan_remove(struct platform_device *pdev) return 0; } -#define DRVNAME "as5812_54t_fan" static struct platform_driver accton_as5812_54t_fan_driver = { .probe = accton_as5812_54t_fan_probe, @@ -394,11 +416,6 @@ static int __init accton_as5812_54t_fan_init(void) { int ret; - extern int platform_accton_as5812_54t(void); - if (!platform_accton_as5812_54t()) { - return -ENODEV; - } - ret = platform_driver_register(&accton_as5812_54t_fan_driver); if (ret < 0) { goto exit; @@ -439,4 +456,3 @@ MODULE_LICENSE("GPL"); module_init(accton_as5812_54t_fan_init); module_exit(accton_as5812_54t_fan_exit); - diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-leds.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-leds.c index 011f62e76c06..39e553d2f544 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-leds.c +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-leds.c @@ -29,13 +29,8 @@ #include #include -extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); -extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); - -extern void led_classdev_unregister(struct led_classdev *led_cdev); -extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); -extern void led_classdev_resume(struct led_classdev *led_cdev); -extern void led_classdev_suspend(struct led_classdev *led_cdev); +extern int as5812_54t_cpld_read(unsigned short cpld_addr, u8 reg); +extern int as5812_54t_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); #define DRVNAME "as5812_54t_led" @@ -223,12 +218,12 @@ static u8 led_light_mode_to_reg_val(enum led_type type, static int accton_as5812_54t_led_read_value(u8 reg) { - return accton_i2c_cpld_read(0x60, reg); + return as5812_54t_cpld_read(0x60, reg); } static int accton_as5812_54t_led_write_value(u8 reg, u8 value) { - return accton_i2c_cpld_write(0x60, reg, value); + return as5812_54t_cpld_write(0x60, reg, value); } static void accton_as5812_54t_led_update(void) @@ -555,11 +550,6 @@ static int __init accton_as5812_54t_led_init(void) { int ret; - extern int platform_accton_as5812_54t(void); - if (!platform_accton_as5812_54t()) { - return -ENODEV; - } - ret = platform_driver_register(&accton_as5812_54t_led_driver); if (ret < 0) { goto exit; diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-psu.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-psu.c index a77014e877ca..c62998655bcd 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-psu.c +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-psu.c @@ -43,7 +43,7 @@ static ssize_t show_index(struct device *dev, struct device_attribute *da, char static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); static ssize_t show_model_name(struct device *dev, struct device_attribute *da, char *buf); static int as5812_54t_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len); -extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int as5812_54t_cpld_read(unsigned short cpld_addr, u8 reg); static int as5812_54t_psu_model_name_get(struct device *dev); /* Addresses scanned @@ -170,7 +170,8 @@ static int as5812_54t_psu_probe(struct i2c_client *client, goto exit_free; } - data->hwmon_dev = hwmon_device_register(&client->dev); + data->hwmon_dev = hwmon_device_register_with_info(&client->dev, "as5812_54t_psu", + NULL, NULL, NULL); if (IS_ERR(data->hwmon_dev)) { status = PTR_ERR(data->hwmon_dev); goto exit_remove; @@ -328,7 +329,7 @@ static struct as5812_54t_psu_data *as5812_54t_psu_update_device(struct device *d data->valid = 0; /* Read psu status */ - status = accton_i2c_cpld_read(PSU_STATUS_I2C_ADDR, PSU_STATUS_I2C_REG_OFFSET); + status = as5812_54t_cpld_read(PSU_STATUS_I2C_ADDR, PSU_STATUS_I2C_REG_OFFSET); if (status < 0) { dev_dbg(&client->dev, "cpld reg (0x%x) err %d\n", PSU_STATUS_I2C_ADDR, status); @@ -348,25 +349,9 @@ static struct as5812_54t_psu_data *as5812_54t_psu_update_device(struct device *d return data; } -static int __init as5812_54t_psu_init(void) -{ - extern int platform_accton_as5812_54t(void); - if (!platform_accton_as5812_54t()) { - return -ENODEV; - } - - return i2c_add_driver(&as5812_54t_psu_driver); -} - -static void __exit as5812_54t_psu_exit(void) -{ - i2c_del_driver(&as5812_54t_psu_driver); -} +module_i2c_driver(as5812_54t_psu_driver); MODULE_AUTHOR("Brandon Chuang "); MODULE_DESCRIPTION("accton as5812_54t_psu driver"); MODULE_LICENSE("GPL"); -module_init(as5812_54t_psu_init); -module_exit(as5812_54t_psu_exit); - diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-sfp.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-sfp.c deleted file mode 100644 index 88bf552de0f0..000000000000 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-sfp.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * An hwmon driver for accton as5812_54t sfp - * - * Copyright (C) 2015 Accton Technology Corporation. - * Brandon Chuang - * - * Based on ad7414.c - * Copyright 2006 Stefan Roese , DENX Software Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define QSFP_PORT_START_INDEX 49 -#define BIT_INDEX(i) (1ULL << (i)) - -/* Addresses scanned - */ -static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END }; - -/* Each client has this additional data - */ -struct as5812_54t_sfp_data { - struct device *hwmon_dev; - struct mutex update_lock; - char valid; /* !=0 if registers are valid */ - unsigned long last_updated; /* In jiffies */ - int port; /* Front port index */ - char eeprom[256]; /* eeprom data */ - u8 status; /* bit0:port49, bit1:port50 and so on */ -}; - -static struct as5812_54t_sfp_data *as5812_54t_sfp_update_device(struct device *dev, int update_eeprom); -static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); -static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); -static ssize_t show_eeprom(struct device *dev, struct device_attribute *da, char *buf); -extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); -extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); - -enum as5812_54t_sfp_sysfs_attributes { - SFP_IS_PRESENT, - SFP_PORT_NUMBER, - SFP_EEPROM, - SFP_IS_PRESENT_ALL, -}; - -/* sysfs attributes for hwmon - */ -static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_status, NULL, SFP_IS_PRESENT); -static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, SFP_PORT_NUMBER); -static SENSOR_DEVICE_ATTR(sfp_eeprom, S_IRUGO, show_eeprom, NULL, SFP_EEPROM); -static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_status,NULL, SFP_IS_PRESENT_ALL); - -static struct attribute *as5812_54t_sfp_attributes[] = { - &sensor_dev_attr_sfp_is_present.dev_attr.attr, - &sensor_dev_attr_sfp_eeprom.dev_attr.attr, - &sensor_dev_attr_sfp_port_number.dev_attr.attr, - &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, - NULL -}; - -static ssize_t show_port_number(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct as5812_54t_sfp_data *data = i2c_get_clientdata(client); - - return sprintf(buf, "%d\n",data->port); -} - -static ssize_t show_status(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct as5812_54t_sfp_data *data = as5812_54t_sfp_update_device(dev, 0); - - if (attr->index == SFP_IS_PRESENT) { - u8 val; - - val = (data->status & BIT_INDEX(data->port - QSFP_PORT_START_INDEX)) ? 0 : 1; - return sprintf(buf, "%d", val); - } - else { /* SFP_IS_PRESENT_ALL */ - return sprintf(buf, "%.2x\n", ~data->status); - } -} - -static ssize_t show_eeprom(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct as5812_54t_sfp_data *data = as5812_54t_sfp_update_device(dev, 1); - - if (!data->valid) { - return 0; - } - - if ((data->status & BIT_INDEX(data->port - QSFP_PORT_START_INDEX)) != 0) { - return 0; - } - - memcpy(buf, data->eeprom, sizeof(data->eeprom)); - - return sizeof(data->eeprom); -} - -static const struct attribute_group as5812_54t_sfp_group = { - .attrs = as5812_54t_sfp_attributes, -}; - -static int as5812_54t_sfp_probe(struct i2c_client *client, - const struct i2c_device_id *dev_id) -{ - struct as5812_54t_sfp_data *data; - int status; - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { - status = -EIO; - goto exit; - } - - data = kzalloc(sizeof(struct as5812_54t_sfp_data), GFP_KERNEL); - if (!data) { - status = -ENOMEM; - goto exit; - } - - mutex_init(&data->update_lock); - data->port = dev_id->driver_data; - i2c_set_clientdata(client, data); - - dev_info(&client->dev, "chip found\n"); - - /* Register sysfs hooks */ - status = sysfs_create_group(&client->dev.kobj, &as5812_54t_sfp_group); - if (status) { - goto exit_free; - } - - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - status = PTR_ERR(data->hwmon_dev); - goto exit_remove; - } - - dev_info(&client->dev, "%s: sfp '%s'\n", - dev_name(data->hwmon_dev), client->name); - - return 0; - -exit_remove: - sysfs_remove_group(&client->dev.kobj, &as5812_54t_sfp_group); -exit_free: - kfree(data); -exit: - - return status; -} - -static int as5812_54t_sfp_remove(struct i2c_client *client) -{ - struct as5812_54t_sfp_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &as5812_54t_sfp_group); - kfree(data); - - return 0; -} - -enum port_numbers { -as5812_54t_qsfp49 = 49, -as5812_54t_qsfp50, -as5812_54t_qsfp51, -as5812_54t_qsfp52, -as5812_54t_qsfp53, -as5812_54t_qsfp54 -}; - -static const struct i2c_device_id as5812_54t_sfp_id[] = { -{ "as5812_54t_qsfp49", as5812_54t_qsfp49 }, { "as5812_54t_qsfp50", as5812_54t_qsfp50 }, -{ "as5812_54t_qsfp51", as5812_54t_qsfp51 }, { "as5812_54t_qsfp52", as5812_54t_qsfp52 }, -{ "as5812_54t_qsfp53", as5812_54t_qsfp53 }, { "as5812_54t_qsfp54", as5812_54t_qsfp54 }, -{} -}; -MODULE_DEVICE_TABLE(i2c, as5812_54t_sfp_id); - -static struct i2c_driver as5812_54t_sfp_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "as5812_54t_sfp", - }, - .probe = as5812_54t_sfp_probe, - .remove = as5812_54t_sfp_remove, - .id_table = as5812_54t_sfp_id, - .address_list = normal_i2c, -}; - -static int as5812_54t_sfp_read_byte(struct i2c_client *client, u8 command, u8 *data) -{ - int result = i2c_smbus_read_byte_data(client, command); - - if (unlikely(result < 0)) { - dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, result); - goto abort; - } - - *data = (u8)result; - result = 0; - -abort: - return result; -} - -static struct as5812_54t_sfp_data *as5812_54t_sfp_update_device(struct device *dev, int update_eeprom) -{ - struct i2c_client *client = to_i2c_client(dev); - struct as5812_54t_sfp_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) - || !data->valid || update_eeprom) { - int status = -1; - int i = 0; - - data->valid = 0; - //dev_dbg(&client->dev, "Starting as5812_54t sfp status update\n"); - data->status = 0xFF; - - /* - * Bring QSFPs out of reset, - * This is a temporary fix until the QSFP+_MOD_RST register - * can be exposed through the driver. - */ - accton_i2c_cpld_write(0x60, 0x23, 0x3F); - - /* Read present status of port 49-54(QSFP port) */ - status = accton_i2c_cpld_read(0x60, 0x22); - - if (status < 0) { - dev_dbg(&client->dev, "cpld(0x60) reg(0x22) err %d\n", status); - } - else { - data->status = status & 0x3F; /* (u32)status */ - } - - if (update_eeprom) { - /* Read eeprom data based on port number */ - memset(data->eeprom, 0, sizeof(data->eeprom)); - - /* Check if the port is present */ - if ((data->status & BIT_INDEX(data->port - QSFP_PORT_START_INDEX)) == 0) { - /* read eeprom */ - for (i = 0; i < sizeof(data->eeprom); i++) { - status = as5812_54t_sfp_read_byte(client, i, data->eeprom + i); - - if (status < 0) { - dev_dbg(&client->dev, "unable to read eeprom from port(%d)\n", - data->port); - goto exit; - } - } - } - } - - data->valid = 1; - data->last_updated = jiffies; - } - -exit: - mutex_unlock(&data->update_lock); - - return data; -} - -static int __init as5812_54t_sfp_init(void) -{ - extern int platform_accton_as5812_54t(void); - if (!platform_accton_as5812_54t()) { - return -ENODEV; - } - - return i2c_add_driver(&as5812_54t_sfp_driver); -} - -static void __exit as5812_54t_sfp_exit(void) -{ - i2c_del_driver(&as5812_54t_sfp_driver); -} - -MODULE_AUTHOR("Brandon Chuang "); -MODULE_DESCRIPTION("accton as5812_54t_sfp driver"); -MODULE_LICENSE("GPL"); - -module_init(as5812_54t_sfp_init); -module_exit(as5812_54t_sfp_exit); - diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/ym2651y.c deleted file mode 100644 index 7101aa411f72..000000000000 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/ym2651y.c +++ /dev/null @@ -1,680 +0,0 @@ -/* - * An hwmon driver for the 3Y Power YM-2651Y Power Module - * - * Copyright (C) 2014 Accton Technology Corporation. - * Brandon Chuang - * - * Based on ad7414.c - * Copyright 2006 Stefan Roese , DENX Software Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX_FAN_DUTY_CYCLE 100 - -/* Addresses scanned - */ -static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -enum chips { - YM2651, - YM2401, -}; - -/* Each client has this additional data - */ -struct ym2651y_data { - struct device *hwmon_dev; - struct mutex update_lock; - char valid; /* !=0 if registers are valid */ - unsigned long last_updated; /* In jiffies */ - u8 chip; /* chip id */ - u8 capability; /* Register value */ - u16 status_word; /* Register value */ - u8 fan_fault; /* Register value */ - u8 over_temp; /* Register value */ - u16 v_out; /* Register value */ - u16 i_out; /* Register value */ - u16 p_out; /* Register value */ - u8 vout_mode; /* Register value */ - u16 temp; /* Register value */ - u16 fan_speed; /* Register value */ - u16 fan_duty_cycle[2]; /* Register value */ - u8 fan_dir[5]; /* Register value */ - u8 pmbus_revision; /* Register value */ - u8 mfr_id[10]; /* Register value */ - u8 mfr_model[16]; /* Register value */ - u8 mfr_revsion[3]; /* Register value */ - u16 mfr_vin_min; /* Register value */ - u16 mfr_vin_max; /* Register value */ - u16 mfr_iin_max; /* Register value */ - u16 mfr_iout_max; /* Register value */ - u16 mfr_pin_max; /* Register value */ - u16 mfr_pout_max; /* Register value */ - u16 mfr_vout_min; /* Register value */ - u16 mfr_vout_max; /* Register value */ -}; - -static ssize_t show_byte(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_word(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_linear(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_vout(struct device *dev, struct device_attribute *da, char *buf); -static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_ascii(struct device *dev, struct device_attribute *da, - char *buf); -static struct ym2651y_data *ym2651y_update_device(struct device *dev); -static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); -static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value); - -enum ym2651y_sysfs_attributes { - PSU_POWER_ON = 0, - PSU_TEMP_FAULT, - PSU_POWER_GOOD, - PSU_FAN1_FAULT, - PSU_FAN_DIRECTION, - PSU_OVER_TEMP, - PSU_V_OUT, - PSU_I_OUT, - PSU_P_OUT, - PSU_TEMP1_INPUT, - PSU_FAN1_SPEED, - PSU_FAN1_DUTY_CYCLE, - PSU_PMBUS_REVISION, - PSU_MFR_ID, - PSU_MFR_MODEL, - PSU_MFR_REVISION, - PSU_MFR_VIN_MIN, - PSU_MFR_VIN_MAX, - PSU_MFR_VOUT_MIN, - PSU_MFR_VOUT_MAX, - PSU_MFR_IIN_MAX, - PSU_MFR_IOUT_MAX, - PSU_MFR_PIN_MAX, - PSU_MFR_POUT_MAX -}; - -/* sysfs attributes for hwmon - */ -static SENSOR_DEVICE_ATTR(psu_power_on, S_IRUGO, show_word, NULL, PSU_POWER_ON); -static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); -static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_word, NULL, PSU_POWER_GOOD); -static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT); -static SENSOR_DEVICE_ATTR(psu_over_temp, S_IRUGO, show_over_temp, NULL, PSU_OVER_TEMP); -static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_vout, NULL, PSU_V_OUT); -static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT); -static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT); -static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); -static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); -static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); -static SENSOR_DEVICE_ATTR(psu_fan_dir, S_IRUGO, show_ascii, NULL, PSU_FAN_DIRECTION); -static SENSOR_DEVICE_ATTR(psu_pmbus_revision,S_IRUGO, show_byte, NULL, PSU_PMBUS_REVISION); -static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_ascii, NULL, PSU_MFR_ID); -static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, show_ascii, NULL, PSU_MFR_MODEL); -static SENSOR_DEVICE_ATTR(psu_mfr_revision, S_IRUGO, show_ascii, NULL, PSU_MFR_REVISION); -static SENSOR_DEVICE_ATTR(psu_mfr_vin_min, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MIN); -static SENSOR_DEVICE_ATTR(psu_mfr_vin_max, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_vout_min, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MIN); -static SENSOR_DEVICE_ATTR(psu_mfr_vout_max, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_iin_max, S_IRUGO, show_linear, NULL, PSU_MFR_IIN_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_iout_max, S_IRUGO, show_linear, NULL, PSU_MFR_IOUT_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_pin_max, S_IRUGO, show_linear, NULL, PSU_MFR_PIN_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_pout_max, S_IRUGO, show_linear, NULL, PSU_MFR_POUT_MAX); - -static struct attribute *ym2651y_attributes[] = { - &sensor_dev_attr_psu_power_on.dev_attr.attr, - &sensor_dev_attr_psu_temp_fault.dev_attr.attr, - &sensor_dev_attr_psu_power_good.dev_attr.attr, - &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, - &sensor_dev_attr_psu_over_temp.dev_attr.attr, - &sensor_dev_attr_psu_v_out.dev_attr.attr, - &sensor_dev_attr_psu_i_out.dev_attr.attr, - &sensor_dev_attr_psu_p_out.dev_attr.attr, - &sensor_dev_attr_psu_temp1_input.dev_attr.attr, - &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, - &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, - &sensor_dev_attr_psu_fan_dir.dev_attr.attr, - &sensor_dev_attr_psu_pmbus_revision.dev_attr.attr, - &sensor_dev_attr_psu_mfr_id.dev_attr.attr, - &sensor_dev_attr_psu_mfr_model.dev_attr.attr, - &sensor_dev_attr_psu_mfr_revision.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vin_min.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vin_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_pout_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_iin_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_pin_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vout_min.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vout_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_iout_max.dev_attr.attr, - NULL -}; - -static ssize_t show_byte(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - - if (!data->valid) { - return 0; - } - - return (attr->index == PSU_PMBUS_REVISION) ? sprintf(buf, "%d\n", data->pmbus_revision) : - sprintf(buf, "0\n"); -} - -static ssize_t show_word(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - u16 status = 0; - - if (!data->valid) { - return 0; - } - - switch (attr->index) { - case PSU_POWER_ON: /* psu_power_on, low byte bit 6 of status_word, 0=>ON, 1=>OFF */ - status = (data->status_word & 0x40) ? 0 : 1; - break; - case PSU_TEMP_FAULT: /* psu_temp_fault, low byte bit 2 of status_word, 0=>Normal, 1=>temp fault */ - status = (data->status_word & 0x4) >> 2; - break; - case PSU_POWER_GOOD: /* psu_power_good, high byte bit 3 of status_word, 0=>OK, 1=>FAIL */ - status = (data->status_word & 0x800) ? 0 : 1; - break; - } - - return sprintf(buf, "%d\n", status); -} - -static int two_complement_to_int(u16 data, u8 valid_bit, int mask) -{ - u16 valid_data = data & mask; - bool is_negative = valid_data >> (valid_bit - 1); - - return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; -} - -static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct ym2651y_data *data = i2c_get_clientdata(client); - int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; - long speed; - int error; - - error = kstrtol(buf, 10, &speed); - if (error) - return error; - - if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) - return -EINVAL; - - mutex_lock(&data->update_lock); - data->fan_duty_cycle[nr] = speed; - ym2651y_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t show_linear(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - - u16 value = 0; - int exponent, mantissa; - int multiplier = 1000; - - if (!data->valid) { - return 0; - } - - switch (attr->index) { - case PSU_V_OUT: - value = data->v_out; - break; - case PSU_I_OUT: - value = data->i_out; - break; - case PSU_P_OUT: - value = data->p_out; - break; - case PSU_TEMP1_INPUT: - value = data->temp; - break; - case PSU_FAN1_SPEED: - value = data->fan_speed; - multiplier = 1; - break; - case PSU_FAN1_DUTY_CYCLE: - value = data->fan_duty_cycle[0]; - multiplier = 1; - break; - case PSU_MFR_VIN_MIN: - value = data->mfr_vin_min; - break; - case PSU_MFR_VIN_MAX: - value = data->mfr_vin_max; - break; - case PSU_MFR_VOUT_MIN: - value = data->mfr_vout_min; - break; - case PSU_MFR_VOUT_MAX: - value = data->mfr_vout_max; - break; - case PSU_MFR_PIN_MAX: - value = data->mfr_pin_max; - break; - case PSU_MFR_POUT_MAX: - value = data->mfr_pout_max; - break; - case PSU_MFR_IOUT_MAX: - value = data->mfr_iout_max; - break; - case PSU_MFR_IIN_MAX: - value = data->mfr_iin_max; - break; - } - - exponent = two_complement_to_int(value >> 11, 5, 0x1f); - mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); - - return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : - sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); -} - -static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - u8 shift; - - if (!data->valid) { - return 0; - } - - shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; - - return sprintf(buf, "%d\n", data->fan_fault >> shift); -} - -static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct ym2651y_data *data = ym2651y_update_device(dev); - - if (!data->valid) { - return 0; - } - - return sprintf(buf, "%d\n", data->over_temp >> 7); -} - -static ssize_t show_ascii(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - u8 *ptr = NULL; - - if (!data->valid) { - return 0; - } - - switch (attr->index) { - case PSU_FAN_DIRECTION: /* psu_fan_dir */ - ptr = data->fan_dir + 1; /* Skip the first byte since it is the length of string. */ - break; - case PSU_MFR_ID: /* psu_mfr_id */ - ptr = data->mfr_id + 1; /* The first byte is the count byte of string. */; - break; - case PSU_MFR_MODEL: /* psu_mfr_model */ - ptr = data->mfr_model + 1; /* The first byte is the count byte of string. */ - break; - case PSU_MFR_REVISION: /* psu_mfr_revision */ - ptr = data->mfr_revsion + 1; /* The first byte is the count byte of string. */ - break; - default: - return 0; - } - - return sprintf(buf, "%s\n", ptr); -} - -static ssize_t show_vout_by_mode(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct ym2651y_data *data = ym2651y_update_device(dev); - int exponent, mantissa; - int multiplier = 1000; - - if (!data->valid) { - return 0; - } - - exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); - mantissa = data->v_out; - - return (exponent > 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : - sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); -} - -static ssize_t show_vout(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct ym2651y_data *data = i2c_get_clientdata(client); - - if (data->chip == YM2401) { - return show_vout_by_mode(dev, da, buf); - } - - return show_linear(dev, da, buf); -} - -static const struct attribute_group ym2651y_group = { - .attrs = ym2651y_attributes, -}; - -static int ym2651y_probe(struct i2c_client *client, - const struct i2c_device_id *dev_id) -{ - struct ym2651y_data *data; - int status; - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_WORD_DATA | - I2C_FUNC_SMBUS_I2C_BLOCK)) { - status = -EIO; - goto exit; - } - - data = kzalloc(sizeof(struct ym2651y_data), GFP_KERNEL); - if (!data) { - status = -ENOMEM; - goto exit; - } - - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - data->chip = dev_id->driver_data; - dev_info(&client->dev, "chip found\n"); - - /* Register sysfs hooks */ - status = sysfs_create_group(&client->dev.kobj, &ym2651y_group); - if (status) { - goto exit_free; - } - - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - status = PTR_ERR(data->hwmon_dev); - goto exit_remove; - } - - dev_info(&client->dev, "%s: psu '%s'\n", - dev_name(data->hwmon_dev), client->name); - - return 0; - -exit_remove: - sysfs_remove_group(&client->dev.kobj, &ym2651y_group); -exit_free: - kfree(data); -exit: - - return status; -} - -static int ym2651y_remove(struct i2c_client *client) -{ - struct ym2651y_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &ym2651y_group); - kfree(data); - - return 0; -} - -static const struct i2c_device_id ym2651y_id[] = { - { "ym2651", YM2651 }, - { "ym2401", YM2401 }, - {} -}; -MODULE_DEVICE_TABLE(i2c, ym2651y_id); - -static struct i2c_driver ym2651y_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "ym2651", - }, - .probe = ym2651y_probe, - .remove = ym2651y_remove, - .id_table = ym2651y_id, - .address_list = normal_i2c, -}; - -static int ym2651y_read_byte(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_byte_data(client, reg); -} - -static int ym2651y_read_word(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_word_data(client, reg); -} - -static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value) -{ - return i2c_smbus_write_word_data(client, reg, value); -} - -static int ym2651y_read_block(struct i2c_client *client, u8 command, u8 *data, - int data_len) -{ - int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); - - if (unlikely(result < 0)) - goto abort; - if (unlikely(result != data_len)) { - result = -EIO; - goto abort; - } - - result = 0; - -abort: - return result; -} - -struct reg_data_byte { - u8 reg; - u8 *value; -}; - -struct reg_data_word { - u8 reg; - u16 *value; -}; - -static struct ym2651y_data *ym2651y_update_device(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct ym2651y_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) - || !data->valid) { - int i, status, length; - u8 command, buf; - struct reg_data_byte regs_byte[] = { {0x19, &data->capability}, - {0x20, &data->vout_mode}, - {0x7d, &data->over_temp}, - {0x81, &data->fan_fault}, - {0x98, &data->pmbus_revision}}; - struct reg_data_word regs_word[] = { {0x79, &data->status_word}, - {0x8b, &data->v_out}, - {0x8c, &data->i_out}, - {0x96, &data->p_out}, - {0x8d, &data->temp}, - {0x3b, &(data->fan_duty_cycle[0])}, - {0x3c, &(data->fan_duty_cycle[1])}, - {0x90, &data->fan_speed}, - {0xa0, &data->mfr_vin_min}, - {0xa1, &data->mfr_vin_max}, - {0xa2, &data->mfr_iin_max}, - {0xa3, &data->mfr_pin_max}, - {0xa4, &data->mfr_vout_min}, - {0xa5, &data->mfr_vout_max}, - {0xa6, &data->mfr_iout_max}, - {0xa7, &data->mfr_pout_max}}; - - dev_dbg(&client->dev, "Starting ym2651 update\n"); - data->valid = 0; - - /* Read byte data */ - for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { - status = ym2651y_read_byte(client, regs_byte[i].reg); - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_byte[i].reg, status); - goto exit; - } - else { - *(regs_byte[i].value) = status; - } - } - - /* Read word data */ - for (i = 0; i < ARRAY_SIZE(regs_word); i++) { - status = ym2651y_read_word(client, regs_word[i].reg); - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_word[i].reg, status); - goto exit; - } - else { - *(regs_word[i].value) = status; - } - } - - /* Read fan_direction */ - command = 0xC3; - status = ym2651y_read_block(client, command, data->fan_dir, - ARRAY_SIZE(data->fan_dir)-1); - data->fan_dir[ARRAY_SIZE(data->fan_dir)-1] = '\0'; - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - goto exit; - } - - /* Read mfr_id */ - command = 0x99; - status = ym2651y_read_block(client, command, data->mfr_id, - ARRAY_SIZE(data->mfr_id)-1); - data->mfr_id[ARRAY_SIZE(data->mfr_id)-1] = '\0'; - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - goto exit; - } - - /* Read mfr_model */ - command = 0x9a; - length = 1; - - /* Read first byte to determine the length of data */ - status = ym2651y_read_block(client, command, &buf, length); - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - goto exit; - } - - status = ym2651y_read_block(client, command, data->mfr_model, buf+1); - data->mfr_model[buf+1] = '\0'; - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - goto exit; - } - - /* Read mfr_revsion */ - command = 0x9b; - status = ym2651y_read_block(client, command, data->mfr_revsion, - ARRAY_SIZE(data->mfr_revsion)-1); - data->mfr_revsion[ARRAY_SIZE(data->mfr_revsion)-1] = '\0'; - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - goto exit; - } - - data->last_updated = jiffies; - data->valid = 1; - } - -exit: - mutex_unlock(&data->update_lock); - - return data; -} - -static int __init ym2651y_init(void) -{ - return i2c_add_driver(&ym2651y_driver); -} - -static void __exit ym2651y_exit(void) -{ - i2c_del_driver(&ym2651y_driver); -} - -MODULE_AUTHOR("Brandon Chuang "); -MODULE_DESCRIPTION("3Y Power YM-2651Y driver"); -MODULE_LICENSE("GPL"); - -module_init(ym2651y_init); -module_exit(ym2651y_exit); - diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/ym2651y.c new file mode 120000 index 000000000000..f4d67640ccc3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/ym2651y.c @@ -0,0 +1 @@ +../../common/modules/ym2651y.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/service/as5812-platform-init.service b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/service/as5812-platform-init.service index 30c1703dc40f..91c9adb01ccb 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/service/as5812-platform-init.service +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/service/as5812-platform-init.service @@ -1,13 +1,17 @@ [Unit] -Description=Accton AS5712-54T Platform initialization service +Description=Accton AS5812-54X Platform Monitoring service Before=pmon.service +After=sysinit.target DefaultDependencies=no [Service] -Type=oneshot -ExecStart=/usr/local/bin/accton_as5812_54t_util.py install -ExecStop=/usr/local/bin/accton_as5812_54t_util.py clean -RemainAfterExit=yes +Type=simple +ExecStartPre=/usr/local/bin/accton_as5812_util.py install +ExecStart=/usr/local/bin/accton_as5812_monitor.py +#RemainAfterExit=yes + +# Resource Limitations +LimitCORE=infinity [Install] WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/setup.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/setup.py new file mode 100755 index 000000000000..0af58ba919bc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/setup.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='as5812_54t', + version='1.0', + description='Module to initialize Accton AS5812-54X platforms', + + packages=['as5812_54t'], + package_dir={'as5812_54t': 'as5812-54t/classes'}, +) + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_monitor.py new file mode 100755 index 000000000000..c8574557b3d1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_monitor.py @@ -0,0 +1,213 @@ +#!/usr/bin/env python +# +# Copyright (C) 2019 Accton Technology Corporation +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# 05/08/2019: Roy Lee, changed for as5812-54t. +# ------------------------------------------------------------------ + +try: + import os + import sys, getopt + import subprocess + import click + import imp + import logging + import logging.config + import logging.handlers + import types + import time # this is only being used as part of the example + import traceback + import signal + from tabulate import tabulate + from as5812_54t.fanutil import FanUtil + from as5812_54t.thermalutil import ThermalUtil +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + +# Deafults +VERSION = '1.0' +FUNCTION_NAME = 'accton_as5812_monitor' +DUTY_MAX = 100 + +global log_file +global log_console + +# Make a class we can use to capture stdout and sterr in the log +class accton_as5812_monitor(object): + # static temp var + _ori_temp = 0 + _new_perc = 0 + + llog = logging.getLogger("["+FUNCTION_NAME+"]") + def __init__(self, log_console, log_file): + """Needs a logger and a logger level.""" + + formatter = logging.Formatter('%(name)s %(message)s') + sys_handler = logging.handlers.SysLogHandler(address = '/dev/log') + sys_handler.setFormatter(formatter) + sys_handler.ident = 'common' + sys_handler.setLevel(logging.WARNING) #only fatal for syslog + self.llog.addHandler(sys_handler) + self.llog.setLevel(logging.DEBUG) + + if log_file: + fh = logging.FileHandler(log_file) + fh.setLevel(logging.INFO) + formatter = logging.Formatter('%(asctime)-15s %(name)s %(message)s') + fh.setFormatter(formatter) + self.llog.addHandler(fh) + + # set up logging to console + if log_console: + console = logging.StreamHandler() + console.setLevel(logging.DEBUG) #For debugging + formatter = logging.Formatter('%(asctime)-15s %(name)s %(message)s') + console.setFormatter(formatter) + self.llog.addHandler(console) + + def manage_fans(self): + FAN_LEV1_UP_TEMP = 57700 # temperature + FAN_LEV1_DOWN_TEMP = 0 # unused + FAN_LEV1_SPEED_PERC = DUTY_MAX # percentage*/ + + FAN_LEV2_UP_TEMP = 53000 + FAN_LEV2_DOWN_TEMP = 52700 + FAN_LEV2_SPEED_PERC = 80 + + FAN_LEV3_UP_TEMP = 49500 + FAN_LEV3_DOWN_TEMP = 47700 + FAN_LEV3_SPEED_PERC = 65 + + FAN_LEV4_UP_TEMP = 0 # unused + FAN_LEV4_DOWN_TEMP = 42700 + FAN_LEV4_SPEED_PERC = 40 + + + thermal = ThermalUtil() + fan = FanUtil() + + temp1 = thermal.get_thermal_1_val() + if temp1 is None: + return False + + temp2 = thermal.get_thermal_2_val() + if temp2 is None: + return False + + new_temp = (temp1 + temp2) / 2 + + for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): + fan_stat = fan.get_fan_status(x) + if fan_stat is None or fan_stat is False: + self._new_perc = FAN_LEV1_SPEED_PERC + self.llog.error('SET new_perc to %d (FAN fault. fan_num:%d)', self._new_perc, x) + break + else: + self.llog.debug('fan_stat is True (fan_num:%d)', x) + + if fan_stat is not None and fan_stat is not False: + diff = new_temp - self._ori_temp + if diff == 0: + self.llog.debug('RETURN. THERMAL temp not changed. %d / %d (new_temp / ori_temp)', new_temp, self._ori_temp) + return True + else: + if diff >= 0: + is_up = True + self.llog.debug('THERMAL temp UP %d / %d (new_temp / ori_temp)', new_temp, self._ori_temp) + else: + is_up = False + self.llog.debug('THERMAL temp DOWN %d / %d (new_temp / ori_temp)', new_temp, self._ori_temp) + + if is_up is True: + if new_temp >= FAN_LEV1_UP_TEMP: + self._new_perc = FAN_LEV1_SPEED_PERC + elif new_temp >= FAN_LEV2_UP_TEMP: + self._new_perc = FAN_LEV2_SPEED_PERC + elif new_temp >= FAN_LEV3_UP_TEMP: + self._new_perc = FAN_LEV3_SPEED_PERC + else: + self._new_perc = FAN_LEV4_SPEED_PERC + self.llog.debug('SET. FAN_SPEED as %d (new THERMAL temp:%d)', self._new_perc, new_temp) + else: + if new_temp <= FAN_LEV4_DOWN_TEMP: + self._new_perc = FAN_LEV4_SPEED_PERC + elif new_temp <= FAN_LEV3_DOWN_TEMP: + self._new_perc = FAN_LEV3_SPEED_PERC + elif new_temp <= FAN_LEV2_DOWN_TEMP: + self._new_perc = FAN_LEV2_SPEED_PERC + else: + self._new_perc = FAN_LEV1_SPEED_PERC + self.llog.debug('SET. FAN_SPEED as %d (new THERMAL temp:%d)', self._new_perc, new_temp) + + cur_perc = fan.get_fan_duty_cycle(fan.get_idx_fan_start()) + if cur_perc == self._new_perc: + self.llog.debug('RETURN. FAN speed not changed. %d / %d (new_perc / ori_perc)', self._new_perc, cur_perc) + return True + + set_stat = fan.set_fan_duty_cycle(fan.get_idx_fan_start(), self._new_perc) + if set_stat is True: + self.llog.debug('PASS. set_fan_duty_cycle (%d)', self._new_perc) + else: + self.llog.error('FAIL. set_fan_duty_cycle (%d)', self._new_perc) + + self.llog.debug('GET. ori_perc is %d. ori_temp is %d', cur_perc, self._ori_temp) + self._ori_temp = new_temp + self.llog.info('UPDATE. ori_perc to %d. ori_temp to %d', cur_perc, self._ori_temp) + + return True + +def sig_handler(signum, frame): + fan = FanUtil() + logging.critical('Cause signal %d, set fan speed max.', signum) + fan.set_fan_duty_cycle(fan.get_idx_fan_start(), DUTY_MAX) + sys.exit(0) + +def main(argv): + log_file = '%s.log' % FUNCTION_NAME + log_console = 0 + log_file = "" + if len(sys.argv) != 1: + try: + opts, args = getopt.getopt(argv,'hdl') + except getopt.GetoptError: + print 'Usage: %s [-d] [-l]' % sys.argv[0] + return 0 + for opt, arg in opts: + if opt == '-h': + print 'Usage: %s [-d] [-l]' % sys.argv[0] + return 0 + elif opt in ('-d'): + log_console = 1 + elif opt in ('-l'): + log_file = '%s.log' % sys.argv[0] + + signal.signal(signal.SIGINT, sig_handler) + signal.signal(signal.SIGTERM, sig_handler) + monitor = accton_as5812_monitor(log_console, log_file) + + #time.sleep(100) + # Loop forever, doing something useful hopefully: + while True: + monitor.manage_fans() + time.sleep(10) + + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_54t_util.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_util.py similarity index 96% rename from platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_54t_util.py rename to platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_util.py index 4e9b0795081d..cad526e17af5 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_54t_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_util.py @@ -151,27 +151,21 @@ def driver_check(): if len(lsmod) ==0: return False return True - - - self.insmod("accton_i2c_cpld") - self.insmod("cpr_4011_4mxx") - self.insmod("ym2651y") - for m in [ "sfp", "psu", "fan", "leds" ]: - self.insmod("x86-64-accton-as5812-54t-%s" % m) kos = [ 'modprobe i2c_dev', 'modprobe i2c_mux_pca954x force_deselect_on_exit=1', -'modprobe accton_i2c_cpld' , +'modprobe optoe', +'modprobe x86-64-accton-as5812-54t-cpld' , 'modprobe cpr_4011_4mxx' , 'modprobe ym2651y' , -'modprobe x86-64-accton-as5812-54t-sfp' , 'modprobe x86-64-accton-as5812-54t-psu' , 'modprobe x86-64-accton-as5812-54t-fan' , 'modprobe x86-64-accton-as5812-54t-leds' ] def driver_install(): global FORCE + status, output = log_os_system("depmod", 1) for i in range(0,len(kos)): status, output = log_os_system(kos[i], 1) if status: @@ -184,6 +178,10 @@ def driver_uninstall(): for i in range(0,len(kos)): rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") rm = rm.replace("insmod", "rmmod") + lst = rm.split(" ") + if len(lst) > 3: + del(lst[3]) + rm = " ".join(lst) status, output = log_os_system(rm, 1) if status: if FORCE == 0: @@ -212,7 +210,7 @@ def driver_uninstall(): mknod =[ 'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-0/new_device', 'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device' , -'echo accton_i2c_cpld 0x60 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo as5812_54t_cpld 0x60 > /sys/bus/i2c/devices/i2c-0/new_device', 'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-15/new_device', 'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-16/new_device', 'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-17/new_device', @@ -229,7 +227,7 @@ def driver_uninstall(): mknod2 =[ 'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-1/new_device', 'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-0/new_device' , -'echo accton_i2c_cpld 0x60 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo as5812_54t_cpld 0x60 > /sys/bus/i2c/devices/i2c-1/new_device', 'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-15/new_device', 'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-16/new_device', 'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-17/new_device', @@ -286,8 +284,8 @@ def device_install(): print output if FORCE == 0: return status - for i in range(sfp_1st_index,len(sfp_map)): - status, output =log_os_system("echo sfp"+str(i+1)+" 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + for i in range(0,len(sfp_map)): + status, output =log_os_system("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) if status: print output if FORCE == 0: diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_i2c_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_i2c_cpld.c index a4ff19fea546..70d9a66affdb 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_i2c_cpld.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_i2c_cpld.c @@ -285,6 +285,14 @@ enum as7326_56x_cpld_sysfs_attributes { TRANSCEIVER_TXFAULT_ATTR_ID(48), TRANSCEIVER_TXFAULT_ATTR_ID(57), TRANSCEIVER_TXFAULT_ATTR_ID(58), + TRANSCEIVER_RESET_ATTR_ID(49), + TRANSCEIVER_RESET_ATTR_ID(50), + TRANSCEIVER_RESET_ATTR_ID(51), + TRANSCEIVER_RESET_ATTR_ID(52), + TRANSCEIVER_RESET_ATTR_ID(53), + TRANSCEIVER_RESET_ATTR_ID(54), + TRANSCEIVER_RESET_ATTR_ID(55), + TRANSCEIVER_RESET_ATTR_ID(56), }; /* sysfs attributes for hwmon @@ -297,6 +305,8 @@ static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, char *buf); static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t set_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); static ssize_t access(struct device *dev, struct device_attribute *da, const char *buf, size_t count); static ssize_t show_version(struct device *dev, struct device_attribute *da, @@ -437,6 +447,15 @@ DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(48); DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(57); DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(58); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(49); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(50); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(51); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(52); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(53); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(54); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(55); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(56); + static struct attribute *as7326_56x_cpld3_attributes[] = { &sensor_dev_attr_version.dev_attr.attr, &sensor_dev_attr_access.dev_attr.attr, @@ -507,7 +526,7 @@ static struct attribute *as7326_56x_cpld2_attributes[] = { DECLARE_SFP_TRANSCEIVER_ATTR(22), DECLARE_SFP_TRANSCEIVER_ATTR(23), DECLARE_SFP_TRANSCEIVER_ATTR(24), - DECLARE_SFP_TRANSCEIVER_ATTR(25), + DECLARE_SFP_TRANSCEIVER_ATTR(25), DECLARE_SFP_TRANSCEIVER_ATTR(26), DECLARE_SFP_TRANSCEIVER_ATTR(27), DECLARE_SFP_TRANSCEIVER_ATTR(28), @@ -574,6 +593,14 @@ static struct attribute *as7326_56x_cpld1_attributes[] = { DECLARE_SFP_TRANSCEIVER_ATTR(48), DECLARE_SFP_TRANSCEIVER_ATTR(57), DECLARE_SFP_TRANSCEIVER_ATTR(58), + DECLARE_TRANSCEIVER_RESET_ATTR(49), + DECLARE_TRANSCEIVER_RESET_ATTR(50), + DECLARE_TRANSCEIVER_RESET_ATTR(51), + DECLARE_TRANSCEIVER_RESET_ATTR(52), + DECLARE_TRANSCEIVER_RESET_ATTR(53), + DECLARE_TRANSCEIVER_RESET_ATTR(54), + DECLARE_TRANSCEIVER_RESET_ATTR(55), + DECLARE_TRANSCEIVER_RESET_ATTR(56), NULL }; @@ -724,6 +751,11 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, reg = 0x19; mask = 0x1 << (( attr->index - MODULE_RXLOS_57)+2); break; + case MODULE_RESET_49 ... MODULE_RESET_56: + reg = 0x4; + mask = 0x1 << (attr->index - MODULE_RESET_49); + revert = 1; + break; default: return 0; } @@ -806,6 +838,59 @@ static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, return status; } +static ssize_t set_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7326_56x_cpld_data *data = i2c_get_clientdata(client); + long reset; + int status; + u8 reg = 0, mask = 0; + + status = kstrtol(buf, 10, &reset); + if (status) { + return status; + } + + switch (attr->index) + { + case MODULE_RESET_49 ... MODULE_RESET_56: + reg = 0x4; + mask = 0x1 << (attr->index - MODULE_RESET_49); + break; + default: + return 0; + } + + /* Read current status */ + mutex_lock(&data->update_lock); + status = as7326_56x_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + + /* Update reset status */ + if (!reset) { + status |= mask; + } + else { + status &= ~mask; + } + + status = as7326_56x_cpld_write_internal(client, reg, status); + if (unlikely(status < 0)) { + goto exit; + } + + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + static ssize_t access(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/service/as7326-platform-handle_mac.service b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/service/as7326-platform-handle_mac.service index 0e35d5929ef9..3d03ec4f1540 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/service/as7326-platform-handle_mac.service +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/service/as7326-platform-handle_mac.service @@ -1,16 +1,15 @@ [Unit] -Description=Accton AS7326-56X Platform MAC hnadle service -Before=pmon.service -After=sysinit.target -DefaultDependencies=no +Description=Accton AS7326-56X Platform MAC handle service +Before=opennsl-modules.service +After=local-fs.target [Service] -ExecStart=/usr/local/bin/accton_handle_idt.sh -KillSignal=SIGKILL -SuccessExitStatus=SIGKILL +Type=oneshot +ExecStart=/usr/local/bin/idt_init.sh +RemainAfterExit=yes # Resource Limitations LimitCORE=infinity [Install] -WantedBy=multi-user.target +WantedBy=opennsl-modules.service diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/service/as7726-32x-platform-handle_mac.service b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/service/as7726-32x-platform-handle_mac.service index d29342a56fe1..5492775eee62 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/service/as7726-32x-platform-handle_mac.service +++ b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/service/as7726-32x-platform-handle_mac.service @@ -1,16 +1,15 @@ [Unit] -Description=Accton AS7726-32X Platform MAC hnadle service -Before=pmon.service -After=sysinit.target -DefaultDependencies=no +Description=Accton AS7726-32X Platform MAC handle service +Before=opennsl-modules.service +After=local-fs.target [Service] -ExecStart=/usr/local/bin/accton_handle_idt.sh -KillSignal=SIGKILL -SuccessExitStatus=SIGKILL +Type=oneshot +ExecStart=/usr/local/bin/idt_init.sh +RemainAfterExit=yes # Resource Limitations LimitCORE=infinity [Install] -WantedBy=multi-user.target +WantedBy=opennsl-modules.service diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/classes/fanutil.py index ca0f3f9da1e3..52889cd5895d 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/classes/fanutil.py +++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/classes/fanutil.py @@ -1,26 +1,22 @@ #!/usr/bin/env python +# Copyright (c) 2019 Edgecore Networks Corporation # -# Copyright (C) 2017 Accton Technology Corporation +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 # -# This program is free software: you can 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 CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU 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 . - +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. +# # ------------------------------------------------------------------ # HISTORY: # mm/dd/yyyy (A.D.) -# 11/13/2017: Polly Hsu, Create -# 1/10/2018: Jostar modify for as7716_32 -# 12/03/2018: Jostar modify for as7726_32 +# 8/27/2019:Jostar craete for as9716_32d # ------------------------------------------------------------------ try: @@ -46,8 +42,8 @@ class FanUtil(object): FAN_NODE_FAULT_IDX_OF_MAP = 1 FAN_NODE_DIR_IDX_OF_MAP = 2 - BASE_VAL_PATH = '/sys/bus/i2c/devices/54-0066/{0}' - FAN_DUTY_PATH = '/sys/bus/i2c/devices/54-0066/fan_duty_cycle_percentage' + BASE_VAL_PATH = '/sys/bus/i2c/devices/17-0066/{0}' + FAN_DUTY_PATH = '/sys/bus/i2c/devices/17-0066/fan_duty_cycle_percentage' #logfile = '' #loglevel = logging.INFO @@ -56,14 +52,14 @@ class FanUtil(object): key1 = fan id index (integer) starting from 1 key2 = fan node index (interger) starting from 1 value = path to fan device file (string) """ - _fan_to_device_path_mapping = {} + _fan_device_path_mapping = {} #fan1_direction #fan1_fault #fan1_present #(FAN_NUM_2_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan2_duty_cycle_percentage', - _fan_to_device_node_mapping = { + _fan_device_node_mapping = { (FAN_NUM_1_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan1_fault', (FAN_NUM_1_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan1_direction', @@ -83,8 +79,8 @@ class FanUtil(object): (FAN_NUM_6_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan6_direction', } - def _get_fan_to_device_node(self, fan_num, node_num): - return self._fan_to_device_node_mapping[(fan_num, node_num)] + def _get_fan_device_node(self, fan_num, node_num): + return self._fan_device_node_mapping[(fan_num, node_num)] def _get_fan_node_val(self, fan_num, node_num): if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: @@ -95,7 +91,7 @@ def _get_fan_node_val(self, fan_num, node_num): logging.debug('GET. Parameter error. node_num:%d', node_num) return None - device_path = self.get_fan_to_device_path(fan_num, node_num) + device_path = self.get_fan_device_path(fan_num, node_num) try: val_file = open(device_path, 'r') @@ -131,7 +127,7 @@ def _set_fan_node_val(self, fan_num, node_num, val): logging.debug('GET. content is NULL. device_path:%s', device_path) return None - device_path = self.get_fan_to_device_path(fan_num, node_num) + device_path = self.get_fan_device_path(fan_num, node_num) try: val_file = open(device_path, 'w') except IOError as e: @@ -153,8 +149,8 @@ def __init__(self): for fan_num in range(self.FAN_NUM_1_IDX, self.FAN_NUM_ON_MAIN_BROAD+1): for node_num in range(self.FAN_NODE_FAULT_IDX_OF_MAP, self.FAN_NODE_NUM_OF_MAP+1): - self._fan_to_device_path_mapping[(fan_num, node_num)] = fan_path.format( - self._fan_to_device_node_mapping[(fan_num, node_num)]) + self._fan_device_path_mapping[(fan_num, node_num)] = fan_path.format( + self._fan_device_node_mapping[(fan_num, node_num)]) def get_num_fans(self): return self.FAN_NUM_ON_MAIN_BROAD @@ -169,20 +165,17 @@ def get_idx_node_start(self): return self.FAN_NODE_FAULT_IDX_OF_MAP def get_size_node_map(self): - return len(self._fan_to_device_node_mapping) + return len(self._fan_device_node_mapping) def get_size_path_map(self): - return len(self._fan_to_device_path_mapping) + return len(self._fan_device_path_mapping) - def get_fan_to_device_path(self, fan_num, node_num): - return self._fan_to_device_path_mapping[(fan_num, node_num)] + def get_fan_device_path(self, fan_num, node_num): + return self._fan_device_path_mapping[(fan_num, node_num)] def get_fan_fault(self, fan_num): return self._get_fan_node_val(fan_num, self.FAN_NODE_FAULT_IDX_OF_MAP) - #def get_fan_speed(self, fan_num): - # return self._get_fan_node_val(fan_num, self.FAN_NODE_SPEED_IDX_OF_MAP) - def get_fan_dir(self, fan_num): return self._get_fan_node_val(fan_num, self.FAN_NODE_DIR_IDX_OF_MAP) @@ -198,28 +191,18 @@ def get_fan_duty_cycle(self): val_file.close() return int(content) - #self._get_fan_node_val(fan_num, self.FAN_NODE_DUTY_IDX_OF_MAP) -#static u32 reg_val_to_duty_cycle(u8 reg_val) -#{ -# reg_val &= FAN_DUTY_CYCLE_REG_MASK; -# return ((u32)(reg_val+1) * 625 + 75)/ 100; -#} -# + def set_fan_duty_cycle(self, val): - try: fan_file = open(self.FAN_DUTY_PATH, 'r+') except IOError as e: print "Error: unable to open file: %s" % str(e) return False - #val = ((val + 1 ) * 625 +75 ) / 100 + fan_file.write(str(val)) fan_file.close() return True - - #def get_fanr_fault(self, fan_num): - # return self._get_fan_node_val(fan_num, self.FANR_NODE_FAULT_IDX_OF_MAP) - + def get_fanr_speed(self, fan_num): return self._get_fan_node_val(fan_num, self.FANR_NODE_SPEED_IDX_OF_MAP) @@ -232,20 +215,4 @@ def get_fan_status(self, fan_num): logging.debug('GET. FAN fault. fan_num, %d', fan_num) return False - #if self.get_fanr_fault(fan_num) is not None and self.get_fanr_fault(fan_num) > 0: - # logging.debug('GET. FANR fault. fan_num, %d', fan_num) - # return False - - return True -#def main(): -# fan = FanUtil() -# -# print 'get_size_node_map : %d' % fan.get_size_node_map() -# print 'get_size_path_map : %d' % fan.get_size_path_map() -# for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): -# for y in range(fan.get_idx_node_start(), fan.get_num_nodes()+1): -# print fan.get_fan_to_device_path(x, y) -# -#if __name__ == '__main__': -# main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/classes/thermalutil.py b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/classes/thermalutil.py index 00c9950d52b6..abbc5e819a8a 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/classes/thermalutil.py +++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/classes/thermalutil.py @@ -1,24 +1,22 @@ #!/usr/bin/env python +# Copyright (c) 2019 Edgecore Networks Corporation # -# Copyright (C) 2017 Accton Technology Corporation +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 # -# This program is free software: you can 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 CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU 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 . - +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. +# # ------------------------------------------------------------------ # HISTORY: # mm/dd/yyyy (A.D.) -# 12/18/2018:Jostar craete for as9716_32d +# 8/27/2019:Jostar craete for as9716_32d # ------------------------------------------------------------------ try: @@ -34,38 +32,29 @@ class ThermalUtil(object): """Platform-specific ThermalUtil class""" THERMAL_NUM_MAX = 8 - THERMAL_NUM_1_IDX = 1 # 1_ON_MAIN_BROAD. LM75 - THERMAL_NUM_2_IDX = 2 # 2_ON_MAIN_BROAD. LM75 - THERMAL_NUM_3_IDX = 3 # 3_ON_MAIN_BROAD. LM75 - THERMAL_NUM_4_IDX = 4 # 4_ON_MAIN_BROAD. LM75 - THERMAL_NUM_5_IDX = 5 # 5_ON_MAIN_BROAD. LM75 - THERMAL_NUM_6_IDX = 6 # 6_ON_MAIN_BROAD. LM75 - THERMAL_NUM_7_IDX = 7 # 7_ON_MAIN_BROAD. LM75 - THERMAL_NUM_8_IDX = 8 # 8_ON_MAIN_BROAD. LM75 - + THERMAL_NUM_1_IDX = 1 # 1~7 are mainboard thermal sensors + THERMAL_NUM_2_IDX = 2 + THERMAL_NUM_3_IDX = 3 + THERMAL_NUM_4_IDX = 4 + THERMAL_NUM_5_IDX = 5 + THERMAL_NUM_6_IDX = 6 + THERMAL_NUM_7_IDX = 7 # CPU core + THERMAL_NUM_8_IDX = 8 + """ Dictionary where key1 = thermal id index (integer) starting from 1 value = path to fan device file (string) """ #_thermal_to_device_path_mapping = {} - - _thermal_to_device_node_mapping = { - THERMAL_NUM_1_IDX: ['18', '48'], - THERMAL_NUM_2_IDX: ['18', '49'], - THERMAL_NUM_3_IDX: ['18', '4a'], - THERMAL_NUM_4_IDX: ['18', '4b'], - THERMAL_NUM_5_IDX: ['18', '4c'], - THERMAL_NUM_6_IDX: ['18', '4e'], - THERMAL_NUM_7_IDX: ['18', '4f'], - } + thermal_sysfspath ={ THERMAL_NUM_1_IDX: ["/sys/bus/i2c/devices/18-0048/hwmon/hwmon*/temp1_input"], THERMAL_NUM_2_IDX: ["/sys/bus/i2c/devices/18-0049/hwmon/hwmon*/temp1_input"], - THERMAL_NUM_3_IDX: ["/sys/bus/i2c/devices/18-004a/hwmon/hwmon*/temp1_input"], - THERMAL_NUM_4_IDX: ["/sys/bus/i2c/devices/18-004b/hwmon/hwmon*/temp1_input"], - THERMAL_NUM_5_IDX: ["/sys/bus/i2c/devices/18-004c/hwmon/hwmon*/temp1_input"], - THERMAL_NUM_6_IDX: ["/sys/bus/i2c/devices/18-004e/hwmon/hwmon*/temp1_input"], - THERMAL_NUM_7_IDX: ["/sys/bus/i2c/devices/18-004f/hwmon/hwmon*/temp1_input"], - THERMAL_NUM_8_IDX: ["/sys/class/hwmon/hwmon0/temp1_input"], + THERMAL_NUM_3_IDX: ["/sys/bus/i2c/devices/18-004a/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_4_IDX: ["/sys/bus/i2c/devices/18-004c/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_5_IDX: ["/sys/bus/i2c/devices/18-004e/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_6_IDX: ["/sys/bus/i2c/devices/18-004f/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_7_IDX: ["/sys/class/hwmon/hwmon0/temp1_input"], + THERMAL_NUM_8_IDX: ["/sys/bus/i2c/devices/18-004b/hwmon/hwmon*/temp1_input"], } #def __init__(self): @@ -75,7 +64,7 @@ def _get_thermal_val(self, thermal_num): logging.debug('GET. Parameter error. thermal_num, %d', thermal_num) return None - device_path = self.get_thermal_to_device_path(thermal_num) + device_path = self.get_thermal_path(thermal_num) for filename in glob.glob(device_path): try: val_file = open(filename, 'r') @@ -97,39 +86,17 @@ def _get_thermal_val(self, thermal_num): return 0 def get_num_thermals(self): - return self.THERMAL_NUM_MAX - - def get_idx_thermal_start(self): - return self.THERMAL_NUM_1_IDX - - def get_size_node_map(self): - return len(self._thermal_to_device_node_mapping) + return self.THERMAL_NUM_MAX def get_size_path_map(self): return len(self.thermal_sysfspath) - def get_thermal_to_device_path(self, thermal_num): + def get_thermal_path(self, thermal_num): return self.thermal_sysfspath[thermal_num][0] - - def get_thermal_temp(self): - return (self._get_thermal_node_val(self.THERMAL_NUM_1_IDX) + self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) +self._get_thermal_node_val(self.THERMAL_NUM_3_IDX)) + def main(): - thermal = ThermalUtil() - print "termal1=%d" %thermal._get_thermal_val(1) - print "termal2=%d" %thermal._get_thermal_val(2) - print "termal3=%d" %thermal._get_thermal_val(3) - print "termal4=%d" %thermal._get_thermal_val(4) - print "termal5=%d" %thermal._get_thermal_val(5) - print "termal7=%d" %thermal._get_thermal_val(6) - print "termal8=%d" %thermal._get_thermal_val(7) - print "termal9=%d" %thermal._get_thermal_val(8) - -# -# print 'get_size_node_map : %d' % thermal.get_size_node_map() -# print 'get_size_path_map : %d' % thermal.get_size_path_map() -# for x in range(thermal.get_idx_thermal_start(), thermal.get_num_thermals()+1): -# print thermal.get_thermal_to_device_path(x) -# + thermal = ThermalUtil() + if __name__ == '__main__': main() \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor.py index f80c1223a83c..3752161d3ebc 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor.py @@ -1,28 +1,27 @@ #!/usr/bin/env python +# -*- coding: utf-8 -* +# Copyright (c) 2019 Edgecore Networks Corporation # -# Copyright (C) 2017 Accton Technology Corporation +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 # -# This program is free software: you can 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 CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU 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 . - -# ------------------------------------------------------------------ +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. +# # HISTORY: # mm/dd/yyyy (A.D.)# -# 12/19/2018:Jostar create for as9716_32d thermal plan +# 8/27/2019:Jostar create for as9716_32d thermal plan # ------------------------------------------------------------------ try: import os + import commands import sys, getopt import subprocess import click @@ -41,31 +40,11 @@ # Deafults VERSION = '1.0' -FUNCTION_NAME = '/usr/local/bin/accton_as9716_32x_monitor' +FUNCTION_NAME = '/usr/local/bin/accton_as9716_32d_monitor' global log_file global log_level - -# Air Flow Front to Back : -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 <=38C : Keep 37.5%(0x04) Fan speed -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 38C : Change Fan speed from 37.5%(0x04) to 62.5%(0x08) -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 46C : Change Fan speed from 62.5%(0x08) to 100%(0x0E) -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 58C : Send alarm message -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 66C : Shut down system -# One Fan fail : Change Fan speed to 100%(0x0E) - - -# Air Flow Back to Front : -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 <=34C : Keep 37.5%(0x04) Fan speed -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 34C : Change Fan speed from 37.5%(0x04) to 62.5%(0x08) -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 44C : Change Fan speed from 62.5%(0x08) to 100%(0x0E) -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 59C : Send alarm message -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 67C : Shut down system -# One Fan fail: Change Fan speed to 100%(0x0E) -# sensor_LM75_CPU == sensor_LM75_4B - - class switch(object): def __init__(self, value): self.value = value @@ -87,20 +66,217 @@ def match(self, *args): return False -fan_policy_state=1 + +# Read fanN_direction=1: The air flow of Fan6 is “AFI-Back to Front†+# 0: The air flow of Fan6 is “AFO-Front to back†+# +# Thermal policy: +# a.Defaut fan duty_cycle=100% +# b.One fan fail, set to fan duty_cycle=100% +# 1.For AFI: +# Default fan duty_cycle will be 100%(fan_policy_state=LEVEL_FAN_MAX). +# If all below case meet with, set to 75%(LEVEL_FAN_MID). +# MB board +# LM75-1(0X48)<=57 +# LM75-2(0X49)<=47.3 +# LM75-3(0X4A)<=45 +# LM75-4(0X4C)<=45.1 +# LM75-5(0X4E)<=40.75 +# LM75-6(0X4F)<=42.1 +# CPU board +# Core<=44 +# LM75-1(0X4B)<=35 + +# When fan_policy_state=LEVEL_FAN_MID, meet with below case, Fan duty_cycle will be 100%(LEVEL_FAN_DAX) +# (MB board) +# LM75-1(0X48)>=61.5 +# LM75-2(0X49)>=51.5 +# LM75-3(0X4A)>=49.4 +# LM75-4(0X4C)>=49.4 +# LM75-5(0X4E)>=45.1 +# LM75-6(0X4F)>=46.75 +# (CPU board) +# Core>=48 +# LM75-1(0X4B)>=38.5 + +# 2. For AFO: +# At default, FAN duty_cycle was 100%(LEVEL_FAN_MAX). If all below case meet with, set to 75%(LEVEL_FAN_MID). +# (MB board) +# LM75-1(0X48)<=59 +# LM75-2(0X49)<=53.5 +# LM75-3(0X4A)<=55.3 +# LM75-4(0X4C)<=50.3 +# LM75-5(0X4E)<=50 +# LM75-6(0X4F)<=52.5 +# (CPU board) +# Core<=59 +# LM75-1(0X4B)<=41.1 + +# When FAN duty_cycle was 75%(LEVEL_FAN_MID). If all below case meet with, set to 50%(LEVEL_FAN_DEF). +# (MB board) +# LM75-1(0X48)<=55.8 +# LM75-2(0X49)<=50.5 +# LM75-3(0X4A)<=51.1 +# LM75-4(0X4C)<=47.6 +# LM75-5(0X4E)<=45.75 +# LM75-6(0X4F)<=50.1 +# (CPU board) +# Core<=57 +# LM75-1(0X4B)<=36.6 + +# When fan_speed 50%(LEVEL_FAN_DEF). +# Meet with below case, Fan duty_cycle will be 75%(LEVEL_FAN_MID) +# (MB board) +# LM75-1(0X48)>=70 +# LM75-2(0X49)>=66 +# LM75-3(0X4A)>=68 +# LM75-4(0X4C)>=62 +# LM75-5(0X4E)>=62 +# LM75-6(0X4F)>=67 +# (CPU board) +# Core>=77 +# LM75-1(0X4B)>=50 + +# When FAN duty_cycle was 75%(LEVEL_FAN_MID). If all below case meet with, set to 100%(LEVEL_FAN_MAX). +# (MB board) +# LM75-1(0X48)>=67 +# LM75-2(0X49)>=62.5 +# LM75-3(0X4A)>=65 +# LM75-4(0X4C)>=59 +# LM75-5(0X4E)>=58.5 +# LM75-6(0X4F)>=63 + +# (CPU board) +# Core >=69 +# LM75-1(0X4B)>=49 + + +#Yellow Alarm +#MB board +#LM75-1(0X48)>=68 +#LM75-2(0X49)>=64 +#LM75-3(0X4A)>=65 +#LM75-4(0X4C)>=61 +#LM75-5(0X4E)>=60 +#LM75-6(0X4F)>=64 +#CPU Board +#Core>=70 +#LM75-1(0X4B)>=68 + +#Red Alarm +#MB board +#LM75-1(0X48)>=72 +#LM75-2(0X49)>=68 +#LM75-3(0X4A)>=69 +#LM75-4(0X4C)>=65 +#LM75-5(0X4E)>=64 +#LM75-6(0X4F)>=68 +#CPU Board +#Core>=74 +#LM75-1(0X4B)>=72 + +#Shut down +#MB board +#LM75-1(0X48)>=77 +#LM75-2(0X49)>=73 +#LM75-3(0X4A)>=74 +#LM75-4(0X4C)>=70 +#LM75-5(0X4E)>=69 +#LM75-6(0X4F)>=73 +#CPU Board +#Core>=79 +#LM75-1(0X4B)>=77 + + + +def power_off_dut(): + cmd_str="i2cset -y -f 19 0x60 0x60 0x10" + status, output = commands.getstatusoutput(cmd_str) + return status + +#If only one PSU insert(or one of PSU pwoer fail), and watt >800w. Must let DUT fan pwm >= 75% in AFO. +#Because the psu temp is high. +# Return 1: full load +# Return 0: Not full load +def check_psu_loading(): + psu_power_status=[1, 1] + + psu_power_good = { + 2: "/sys/bus/i2c/devices/10-0051/psu_power_good", + 1: "/sys/bus/i2c/devices/9-0050/psu_power_good", + } + psu_power_in = { + 2: "/sys/bus/i2c/devices/10-0059/psu_p_in", + 1: "/sys/bus/i2c/devices/9-0058/psu_p_in", + } + psu_power_out = { + 2: "/sys/bus/i2c/devices/10-0059/psu_p_out", + 1: "/sys/bus/i2c/devices/9-0058/psu_p_out", + } + + check_psu_watt=0 + for i in range(1,3): + node = psu_power_good[i] + try: + with open(node, 'r') as power_status: + status = int(power_status.read()) + except IOError: + return None + + psu_power_status[i-1]=int(status) + if status==0: + check_psu_watt=1 + + if check_psu_watt: + for i in range(1,3): + if psu_power_status[i-1]==1: + #check watt + node = psu_power_in[i] + try: + with open(node, 'r') as power_status: + status = int(power_status.read()) + except IOError: + return None + + psu_p_in= int(status) + if psu_p_in/1000 > 800: + return True + + node = psu_power_out[i] + try: + with open(node, 'r') as power_status: + status = int(power_status.read()) + except IOError: + return None + psu_p_out= int(status) + if psu_p_out/1000 > 800: + return True + else: + return False + + + return False + +fan_policy_state=0 +fan_policy_alarm=0 +send_yellow_alarm=0 +send_red_alarm=0 fan_fail=0 -alarm_state = 0 #0->default or clear, 1-->alarm detect +count_check=0 + test_temp = 0 -test_temp_list = [0, 0, 0, 0, 0, 0] +test_temp_list = [0, 0, 0, 0, 0, 0, 0, 0] temp_test_data=0 +test_temp_revert=0 + # Make a class we can use to capture stdout and sterr in the log class device_monitor(object): # static temp var temp = 0 - new_pwm = 0 - pwm=0 - ori_pwm = 0 - default_pwm=0x4 + new_duty_cycle = 0 + duty_cycle=0 + ori_duty_cycle = 0 + def __init__(self, log_file, log_level): """Needs a logger and a logger level.""" @@ -123,179 +299,197 @@ def __init__(self, log_file, log_level): sys_handler = handler = logging.handlers.SysLogHandler(address = '/dev/log') sys_handler.setLevel(logging.WARNING) logging.getLogger('').addHandler(sys_handler) - #logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level) - def get_state_from_fan_policy(self, temp, policy): - state=0 - - logging.debug('temp=%d', temp) - for i in range(0, len(policy)): - #logging.debug('policy[%d][0]=%d, policy[%d][1]=%d, policy[%d][2]=%d', i,policy[i][0],i, policy[i][1], i, policy[i][2]) - if temp > policy[i][2]: - if temp <= policy[i][3]: - state =i - logging.debug ('temp=%d >= policy[%d][2]=%d, temp=%d < policy[%d][3]=%d' , temp, i, policy[i][2], temp, i, policy[i][3]) - logging.debug ('fan_state=%d', state) - break - - return state - def manage_fans(self): global fan_policy_state + global fan_policy_alarm + global send_yellow_alarm + global send_red_alarm global fan_fail + global count_check global test_temp - global test_temp_list - global alarm_state + global test_temp_list global temp_test_data - - LEVEL_FAN_DEF=0 - LEVEL_FAN_MID=1 - LEVEL_FAN_MAX=2 - LEVEL_TEMP_HIGH=3 - LEVEL_TEMP_CRITICAL=4 - - - fan_policy_f2b = { - LEVEL_FAN_DEF: [38, 0x4, 0, 38000], - LEVEL_FAN_MID: [63, 0x6, 38000, 46000], - LEVEL_FAN_MAX: [100, 0xE, 46000, 58000], - LEVEL_TEMP_HIGH: [100, 0xE, 58000, 66000], - LEVEL_TEMP_CRITICAL: [100, 0xE, 58000, 200000], + global test_temp_revert + + CHECK_TIMES=3 + + LEVEL_FAN_INIT=0 + LEVEL_FAN_MIN=1 + LEVEL_FAN_MID=2 + LEVEL_FAN_MAX=3 + LEVEL_FAN_DEF=LEVEL_FAN_MAX + LEVEL_FAN_YELLOW_ALARM=4 + LEVEL_FAN_RED_ALARM=5 + LEVEL_FAN_SHUTDOWN=6 + + fan_policy_f2b = { #AFO + LEVEL_FAN_MIN: [50, 0x7], + LEVEL_FAN_MID: [75, 0xb], + LEVEL_FAN_MAX: [100, 0xf] + } + fan_policy_b2f = { #AFI + LEVEL_FAN_MID: [75, 0xb], + LEVEL_FAN_MAX: [100, 0xf] } - fan_policy_b2f = { - LEVEL_FAN_DEF: [38, 0x4, 0, 34000], - LEVEL_FAN_MID: [63, 0x8, 34000, 44000], - LEVEL_FAN_MAX: [100, 0xE, 44000, 59000], - LEVEL_TEMP_HIGH: [100, 0xE, 59000, 67000], - LEVEL_TEMP_CRITICAL: [100, 0xE, 59000, 200000], + + afi_thermal_spec={ + "mid_to_max_temp":[61500, 51500, 49400, 49400, 45100, 46750, 48000, 38500], + "max_to_mid_temp":[57000, 47300, 45000, 45100, 40750, 42100, 44000, 35000] } + afo_thermal_spec={ + "min_to_mid_temp": [70000, 66000, 68000, 62000, 62000, 67000, 77000, 50000], + "mid_to_max_temp": [67000, 62000, 65000, 59000, 58500, 63000, 69000, 49000], + "max_to_mid_temp": [59000, 53500, 55300, 50300, 50000, 52500, 59000, 41100], + "mid_to_min_temp": [55800, 50500, 51100, 47600, 45750, 50100, 57000, 36600], + "max_to_yellow_alarm": [68000, 64000, 65000, 61000, 60000, 64000, 70000, 68000], + "yellow_to_red_alarm": [72000, 68000, 69000, 65000, 64000, 68000, 74000, 72000], + "red_alarm_to_shutdown": [77000, 73000, 74000, 70000, 69000, 73000, 79000, 77000] + } + + thermal_val=[0,0,0,0,0,0,0,0] + max_to_mid=0 + mid_to_min=0 - fan_policy = fan_policy_f2b + fan = FanUtil() + if fan_policy_state==LEVEL_FAN_INIT: + fan_policy_state=LEVEL_FAN_MAX #This is default state + logging.debug("fan_policy_state=LEVEL_FAN_MAX") + return + + count_check=count_check+1 + if count_check < CHECK_TIMES: + return + else: + count_check=0 thermal = ThermalUtil() - fan = FanUtil() - fan_dir=fan.get_fan_dir(1) - if fan_dir == 1: - fan_dri=1 #something wrong, set fan_dir to default val + fan_dir=1 + fan_dir=fan.get_fan_dir(1) + + if fan_dir==1: # AFI + fan_thermal_spec = afi_thermal_spec + fan_policy=fan_policy_b2f + elif fan_dir==0: # AFO + fan_thermal_spec = afo_thermal_spec + fan_policy=fan_policy_f2b else: - fan_policy = fan_policy_b2f + logging.debug( "NULL case") - ori_pwm=fan.get_fan_duty_cycle() - new_pwm=0 - logging.debug('fan_dir=%d, ori_pwm=%d', fan_dir, ori_pwm) - logging.debug('test_temp=%d', test_temp) - if test_temp==0: - temp1 = thermal._get_thermal_val(1) - temp2 = thermal._get_thermal_val(2) - temp3 = thermal._get_thermal_val(3) - temp4 = thermal._get_thermal_val(4) - temp5 = thermal._get_thermal_val(5) + ori_duty_cycle=fan.get_fan_duty_cycle() + new_duty_cycle=0 + + if test_temp_revert==0: + temp_test_data=temp_test_data+2000 + else: + temp_test_data=temp_test_data-2000 + + if test_temp==0: + for i in range (thermal.THERMAL_NUM_1_IDX, thermal.THERMAL_NUM_MAX+1): + thermal_val[i-1]=thermal._get_thermal_val(i) else: - temp1 = test_temp_list[0] - temp2 = test_temp_list[1] - temp3 = test_temp_list[2] - temp4 = test_temp_list[3] - temp5 = test_temp_list[4] + for i in range (thermal.THERMAL_NUM_1_IDX, thermal.THERMAL_NUM_MAX+1): + thermal_val[i-1]=test_temp_list[i-1] + thermal_val[i-1]= thermal_val[i-1] + temp_test_data + fan_fail=0 - if temp3==0: - temp_get=50000 # if one detect sensor is fail or zero, assign temp=50000, let fan to 75% - logging.debug('lm75_49 detect fail, so set temp_get=50000, let fan to 75%') - elif temp4==0: - temp_get=50000 # if one detect sensor is fail or zero, assign temp=50000, let fan to 75% - logging.debug('lm75_4b detect fail, so set temp_get=50000, let fan to 75%') - else: - temp_get= (temp3 + temp4)/2 # Use (sensor_LM75_4a + sensor_LM75_4b) /2 - ori_state=fan_policy_state - - #temp_test_data=temp_test_data+1000 - #temp_get = temp_get + temp_test_data - #print "Unit test:temp_get=%d"%temp_get + ori_state=fan_policy_state; + current_state=fan_policy_state; + + if fan_dir==1: #AFI + for i in range (0, thermal.THERMAL_NUM_MAX): + if ori_state==LEVEL_FAN_MID: + if thermal_val[i] >= fan_thermal_spec["mid_to_max_temp"][i]: + current_state=LEVEL_FAN_MAX + logging.debug("current_state=LEVEL_FAN_MAX") + break + else: + if (thermal_val[i] <= fan_thermal_spec["max_to_mid_temp"][i]): + max_to_mid=max_to_mid+1 - fan_policy_state=self.get_state_from_fan_policy(temp_get, fan_policy) - #print "temp3=%d"%temp3 - #print "temp4=%d"%temp4 - #print "temp_get=%d"%temp_get + if max_to_mid==thermal.THERMAL_NUM_MAX and fan_policy_state==LEVEL_FAN_MAX: + current_state=LEVEL_FAN_MID + logging.debug("current_state=LEVEL_FAN_MID") + else: #AFO + psu_full_load=check_psu_loading() + for i in range (0, thermal.THERMAL_NUM_MAX): + if ori_state==LEVEL_FAN_MID: + if thermal_val[i] >= fan_thermal_spec["mid_to_max_temp"][i]: + current_state=LEVEL_FAN_MAX + break + else: + if psu_full_load!=True and thermal_val[i] <= fan_thermal_spec["mid_to_min_temp"][i]: + mid_to_min=mid_to_min+1 + elif ori_state==LEVEL_FAN_MIN: + if psu_full_load==True: + current_state=LEVEL_FAN_MID + logging.debug("psu_full_load, set current_state=LEVEL_FAN_MID") + if thermal_val[i] >= fan_thermal_spec["min_to_mid_temp"][i]: + current_state=LEVEL_FAN_MID + + else: + if thermal_val[i] <= fan_thermal_spec["max_to_mid_temp"][i] : + max_to_mid=max_to_mid+1 + if fan_policy_alarm==0: + if thermal_val[i] >= fan_thermal_spec["max_to_yellow_alarm"][i]: + if send_yellow_alarm==0: + logging.warning('Alarm-Yellow for temperature high is detected') + fan_policy_alarm=LEVEL_FAN_YELLOW_ALARM + send_yellow_alarm=1 + elif fan_policy_alarm==LEVEL_FAN_YELLOW_ALARM: + if thermal_val[i] >= fan_thermal_spec["yellow_to_red_alarm"][i]: + if send_red_alarm==0: + logging.warning('Alarm-Red for temperature high is detected') + fan_policy_alarm=LEVEL_FAN_RED_ALARM + send_red_alarm=1 + elif fan_policy_alarm==LEVEL_FAN_RED_ALARM: + if thermal_val[i] >= fan_thermal_spec["red_alarm_to_shutdown"][i]: + logging.critical('Alarm-Critical for temperature high is detected, shutdown DUT') + fan_policy_alarm=LEVEL_FAN_SHUTDOWN + time.sleep(2) + power_off_dut() - logging.debug('lm75_48=%d, lm75_49=%d, lm75_4a=%d, lm_4b=%d, lm_4b=%d', temp1,temp2,temp3,temp4,temp5) - logging.debug('ori_state=%d, fan_policy_state=%d', ori_state, fan_policy_state) - new_pwm = fan_policy[fan_policy_state][0] - if fan_fail==0: - logging.debug('new_fan_cycle=%d', new_pwm) - - if fan_fail==0: - if new_pwm!=ori_pwm: - fan.set_fan_duty_cycle(new_pwm) - logging.info('Set fan speed from %d to %d', ori_pwm, new_pwm) - + if max_to_mid==thermal.THERMAL_NUM_MAX and ori_state==LEVEL_FAN_MAX: + current_state=LEVEL_FAN_MID + if fan_policy_alarm!=0: + logging.warning('Alarm for temperature high is cleared') + fan_policy_alarm=0 + send_yellow_alarm=0 + send_red_alarm=0 + test_temp_revert=0 + logging.debug("current_state=LEVEL_FAN_MID") + + if mid_to_min==thermal.THERMAL_NUM_MAX and ori_state==LEVEL_FAN_MID: + if psu_full_load==0: + current_state=LEVEL_FAN_MIN + logging.debug("current_state=LEVEL_FAN_MIN") + #Check Fan status for i in range (fan.FAN_NUM_1_IDX, fan.FAN_NUM_ON_MAIN_BROAD+1): if fan.get_fan_status(i)==0: - new_pwm=100 - logging.debug('fan_%d fail, set pwm to 100',i) + new_duty_cycle=100 + logging.debug('fan_%d fail, set duty_cycle to 100',i) if test_temp==0: fan_fail=1 - fan.set_fan_duty_cycle(new_pwm) + fan.set_fan_duty_cycle(new_duty_cycle) break else: fan_fail=0 - - #if fan_policy_state == ori_state: - # return True - #else: - new_state = fan_policy_state - - #logging.warning('Temperature high alarm testing') - if ori_state==LEVEL_FAN_DEF: - if new_state==LEVEL_TEMP_HIGH: - if alarm_state==0: - logging.warning('Alarm for temperature high is detected') - alarm_state=1 - if new_state==LEVEL_TEMP_CRITICAL: - logging.critical('Alarm for temperature critical is detected, reboot DUT') - time.sleep(2) - os.system('reboot') - if ori_state==LEVEL_FAN_MID: - if new_state==LEVEL_TEMP_HIGH: - if alarm_state==0: - logging.warning('Alarm for temperature high is detected') - alarm_state=1 - if new_state==LEVEL_TEMP_CRITICAL: - logging.critical('Alarm for temperature critical is detected') - time.sleep(2) - os.system('reboot') - if ori_state==LEVEL_FAN_MAX: - if new_state==LEVEL_TEMP_HIGH: - if alarm_state==0: - logging.warning('Alarm for temperature high is detected') - alarm_state=1 - if new_state==LEVEL_TEMP_CRITICAL: - logging.critical('Alarm for temperature critical is detected') - time.sleep(2) - os.system('reboot') - if alarm_state==1: - if temp_get < (fan_policy[3][0] - 5000): #below 65 C, clear alarm - logging.warning('Alarm for temperature high is cleared') - alarm_state=0 - if ori_state==LEVEL_TEMP_HIGH: - if new_state==LEVEL_TEMP_CRITICAL: - logging.critical('Alarm for temperature critical is detected') - time.sleep(2) - os.system('reboot') - if new_state <= LEVEL_FAN_MID: - logging.warning('Alarm for temperature high is cleared') - alarm_state=0 - if new_state <= LEVEL_FAN_MAX: - if temp_get < (fan_policy[3][0] - 5000): #below 65 C, clear alarm - logging.warning('Alarm for temperature high is cleared') - alarm_state=0 - if ori_state==LEVEL_TEMP_CRITICAL: - if new_state <= LEVEL_FAN_MAX: - logging.warning('Alarm for temperature critical is cleared') - + + if current_state!=ori_state: + fan_policy_state=current_state + new_duty_cycle=fan_policy[current_state][0] + logging.debug("fan_policy_state=%d, new_duty_cycle=%d", fan_policy_state, new_duty_cycle) + if new_duty_cycle!=ori_duty_cycle and fan_fail==0: + fan.set_fan_duty_cycle(new_duty_cycle) + return True + if new_duty_cycle==0 and fan_fail==0: + fan.set_fan_duty_cycle(FAN_DUTY_CYCLE_MAX) + return True def main(argv): @@ -318,26 +512,25 @@ def main(argv): log_file = arg if sys.argv[1]== '-t': - if len(sys.argv)!=7: - print "temp test, need input six temp" + if len(sys.argv)!=10: + print "temp test, need input 8 temp" return 0 - i=0 - for x in range(2, 7): + for x in range(2, 10): test_temp_list[i]= int(sys.argv[x])*1000 i=i+1 - test_temp = 1 + test_temp = 1 log_level = logging.DEBUG - print test_temp_list + print test_temp_list fan = FanUtil() - fan.set_fan_duty_cycle(38) - print "set default fan speed to 37.5%" + fan.set_fan_duty_cycle(100) monitor = device_monitor(log_file, log_level) # Loop forever, doing something useful hopefully: while True: - #monitor.manage_fans() - time.sleep(5) + monitor.manage_fans() + time.sleep(10) + if __name__ == '__main__': main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-accton/common/modules/cpr_4011_4mxx.c b/platform/broadcom/sonic-platform-modules-accton/common/modules/cpr_4011_4mxx.c index 2cea5f5e39f9..f1790b4515ff 100644 --- a/platform/broadcom/sonic-platform-modules-accton/common/modules/cpr_4011_4mxx.c +++ b/platform/broadcom/sonic-platform-modules-accton/common/modules/cpr_4011_4mxx.c @@ -93,6 +93,21 @@ static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_ static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); + +/*Duplicate nodes for lm-sensors.*/ +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_linear, NULL, PSU_V_IN); +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_vout, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, show_linear, NULL, PSU_I_IN); +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, show_linear, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, show_linear, NULL, PSU_P_IN); +static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, show_linear, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(pwm1_input, S_IRUGO, show_linear, NULL, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); + + + static struct attribute *cpr_4011_4mxx_attributes[] = { &sensor_dev_attr_psu_v_in.dev_attr.attr, &sensor_dev_attr_psu_v_out.dev_attr.attr, @@ -104,6 +119,17 @@ static struct attribute *cpr_4011_4mxx_attributes[] = { &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + /*Duplicate nodes for lm-sensors.*/ + &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_fault.dev_attr.attr, + &sensor_dev_attr_pwm1_input.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, NULL }; diff --git a/platform/broadcom/sonic-platform-modules-accton/debian/control b/platform/broadcom/sonic-platform-modules-accton/debian/control index e8bedd9081ad..2b3c1af3d80f 100755 --- a/platform/broadcom/sonic-platform-modules-accton/debian/control +++ b/platform/broadcom/sonic-platform-modules-accton/debian/control @@ -53,6 +53,10 @@ Package: sonic-platform-accton-as5812-54x Architecture: amd64 Description: kernel modules for platform devices such as fan, led, sfp +Package: sonic-platform-accton-as5812-54t +Architecture: amd64 +Description: kernel modules for platform devices such as fan, led, sfp + Package: sonic-platform-accton-as5835-54x Architecture: amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-accton/debian/rules b/platform/broadcom/sonic-platform-modules-accton/debian/rules index 11e5b10ae425..722d4126ad0e 100755 --- a/platform/broadcom/sonic-platform-modules-accton/debian/rules +++ b/platform/broadcom/sonic-platform-modules-accton/debian/rules @@ -21,7 +21,7 @@ KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) MODULE_DIRS := as7712-32x as5712-54x as7816-64x as7716-32x as7716-32xb as7312-54x MODULE_DIRS += as7326-56x as6712-32x as7726-32x as4630-54pe minipack as5812-54x -MODULE_DIRS += as5835-54x as9716-32d as5835-54t as7312-54xs as7315-27xb +MODULE_DIRS += as5835-54x as9716-32d as5835-54t as7312-54xs as7315-27xb as5812-54t MODULE_DIR := modules UTILS_DIR := utils SERVICE_DIR := service diff --git a/platform/broadcom/sonic-platform-modules-accton/minipack/classes/pimutil.py b/platform/broadcom/sonic-platform-modules-accton/minipack/classes/pimutil.py new file mode 100755 index 000000000000..778ff76afd19 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/minipack/classes/pimutil.py @@ -0,0 +1,578 @@ +# Copyright (c) 2019 Edgecore Networks Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. +# +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 5/29/2019: Jostar create for minipack +# ----------------------------------------------------------- +try: + import os + import sys, getopt + import subprocess + import click + import imp + import logging + import logging.config + import logging.handlers + import types + import time # this is only being used as part of the example + import traceback + from tabulate import tabulate + import fbfpgaio + import re + import time + from select import select + #from ctypes import fbfpgaio + +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + + +# pimutil.py +# +# Platform-specific PIM interface for SONiC +# + +iob = { + "revision": 0x0, + "scratchpad": 0x4, + "interrupt_status": 0x2C, + "pim_status": 0x40, + "pim_present_intr_mask": 0x44, +} + +dom_base = [ + 0xFFFFFFFF, # Padding + 0x40000, + 0x48000, + 0x50000, + 0x58000, + 0x60000, + 0x68000, + 0x70000, + 0x78000, +] + + +dom = { + "revision": 0x0, + "system_led": 0xC, + "intr_status": 0x2C, + "qsfp_present": 0x48, + "qsfp_present_intr": 0x50, + "qsfp_present_intr_mask": 0x58, + "qsfp_intr": 0x60, + "qsfp_intr_mask": 0x68, + "qsfp_reset": 0x70, + "qsfp_lp_mode": 0x78, + "device_power_bad_status": 0x90, + "port_led_color_profile": { + 0: 0x300, + 1: 0x300, + 2: 0x304, + 3: 0x304, + 4: 0x308, + 5: 0x308, + 6: 0x30C, + 7: 0x30C, + }, + "port_led_control": { + 1: 0x310, + 2: 0x314, + 3: 0x318, + 4: 0x31C, + 5: 0x320, + 6: 0x324, + 7: 0x328, + 8: 0x32C, + 9: 0x330, + 10: 0x334, + 11: 0x338, + 12: 0x33C, + 13: 0x340, + 14: 0x344, + 15: 0x348, + 16: 0x34C, + }, + "dom_control_config": 0x410, + "dom_global_status": 0x414, + "dom_data": 0x4000, + + + "mdio": { + "config": 0x0200, + "command": 0x0204, + "write": 0x0208, + "read": 0x020C, + "status": 0x0210, + "intr_mask": 0x0214, + "source_sel": 0x0218, + }, # mdio +} + +mdio_read_cmd = 0x1 +mdio_write_cmd = 0x0 +mdio_device_type = 0x1F + + +#fbfpgaio=cdll.LoadLibrary('./fbfpgaio.so') + +def init_resources(): + fbfpgaio.hw_init() + return + +def release_resources(): + fbfpgaio.hw_release() + return + +def fpga_io(offset, data=None): + if data is None: + return fbfpgaio.hw_io(offset) + else: + fbfpgaio.hw_io(offset, data) + return + +def pim_io(pim, offset, data=None): + global dom_base + target_offset = dom_base[pim]+offset + if data is None: + retval = fpga_io(target_offset) + #print ("0x%04X" % retval) # idebug + return retval + else: + retval = fpga_io(target_offset, data) + return retval + + +def show_pim_present(): + pim_status = fpga_io(iob["pim_status"]) + + header = "PIM # " + status_str = " " + for shift in range(0,8): + status = pim_status & (0x10000 << shift) #[23:16] from pim_0 to pim_7 + header += " %d " % (shift+1) + if status: + status_str += (" | ") + else: + status_str += (" X ") + print(header) + print(status_str) + +def show_qsfp_present_status(pim_num): + status = fpga_io(dom_base[pim_num]+dom["qsfp_present"]) + interrupt = fpga_io(dom_base[pim_num]+dom["qsfp_present_intr"]) + mask = fpga_io(dom_base[pim_num]+dom["qsfp_present_intr_mask"]) + + print + print(" (0x48) (0x50) (0x58)") + print(" 0x%08X 0x%08X 0x%08X" %(status, interrupt, mask)) + print(" Status Interrupt Mask") + for row in range(8): + output_str = str() + status_left = bool(status & (0x1 << row*2)) + status_right = bool(status & (0x2 << row*2)) + interrupt_left = bool(interrupt & (0x1 << row*2)) + interrupt_right = bool(interrupt & (0x2 << row*2)) + mask_left = bool(mask & (0x1 << row*2)) + mask_right = bool(mask & (0x2 << row*2)) + print("%2d: %d %d %d %d %d %d" % \ + (row*2+1, status_left, status_right, \ + interrupt_left, interrupt_right, \ + mask_left, mask_right)) + print + + + +#pim_index start from 0 to 7 +#port_index start from 0 to 127. Each 16-port is to one pim card. +class PimUtil(object): + + PORT_START = 0 + PORT_END = 127 + + def __init__(self): + self.value=1 + + def __del__(self): + self.value=0 + + def init_pim_fpga(self): + init_resources() + + def release_pim_fpga(self): + release_resources() + + def get_pim_by_port(self, port_num): + if port_num < self.PORT_START or port_num > self.PORT_END: + return False + pim_num=port_num/16 + return True, pim_num+1 + + def get_onepimport_by_port(self, port_num): + if port_num < self.PORT_START or port_num > self.PORT_END: + return False + if port_num < 16: + return True, port_num + else: + return True, port_num%16 + + def get_pim_presence(self, pim_num): + if pim_num <0 or pim_num > 7: + return 0 + pim_status = fpga_io(iob["pim_status"]) + status = pim_status & (0x10000 << pim_num) + if status: + return 1 #present + else: + return 0 #not present + + #return code=0:100G. return code=1:400G + def get_pim_board_id(self, pim_num): + if pim_num <0 or pim_num > 7: + return False + board_id = fpga_io(dom_base[pim_num+1]+dom["revision"]) + board_id = board_id & 0x1 + if board_id==0x0: + return 0 + else: + return 1 + + + def get_pim_status(self, pim_num): + if pim_num <0 or pim_num > 7: + return 0xFF + power_status =0 + #device_power_bad_status + status=fpga_io(dom_base[pim_num+1]+dom["device_power_bad_status"]) + + for x in range(0, 5): + if status & ( (0xf) << (4*x) ) : + power_status = power_status | (0x1 << x) + + if ( status & 0x1000000): + power_status=power_status | (0x1 << 5) + if ( status & 0x2000000): + power_status=power_status | (0x1 << 6) + if ( status & 0x8000000): + power_status=power_status | (0x1 << 7) + if ( status & 0x10000000): + power_status=power_status | (0x1 << 8) + if ( status & 0x40000000): + power_status=power_status | (0x1 << 9) + if ( status & 0x80000000): + power_status=power_status | (0x1 << 10) + + return power_status + #path=0:MDIO path is set on TH3. path=1:MDIO path is set on FPGA. + def set_pim_mdio_source_sel(self, pim_num, path): + if pim_num <0 or pim_num > 7: + return False + status= pim_io(pim_num+1, dom["mdio"]["source_sel"]) + + if path==1: + status = status | 0x2 + else: + status = status & 0xfffffffd + + pim_io(pim_num+1, dom["mdio"]["source_sel"], status) + return True + #retrun code=0, path is TH3. retrun code=1, path is FPGA + def get_pim_mdio_source_sel(sefl, pim_num): + if pim_num <0 or pim_num > 7: + return False + path= pim_io(pim_num+1, dom["mdio"]["source_sel"]) + path = path & 0x2 + if path: + return 1 + else: + return 0 + + #This api will set mdio path to MAC side.(At default, mdio path is set to FPGA side). + def pim_init(self, pim_num): + if pim_num <0 or pim_num > 7: + return False + status=self.set_pim_mdio_source_sel(pim_num, 0) + #put init phy cmd here + + + #return code="pim_dict[pim_num]='1' ":insert evt. return code="pim_dict[pim_num]='0' ":remove evt + def get_pim_change_event(self, timeout=0): + start_time = time.time() + pim_dict = {} + forever = False + + if timeout == 0: + forever = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + print "get_transceiver_change_event:Invalid timeout value", timeout + return False, {} + + end_time = start_time + timeout + if start_time > end_time: + print 'get_transceiver_change_event:' \ + 'time wrap / invalid timeout value', timeout + + return False, {} # Time wrap or possibly incorrect timeout + + pim_mask_status = fpga_io(iob["pim_present_intr_mask"], 0xffff00000) + + while timeout >= 0: + new_pim_status=0 + pim_status = fpga_io(iob["pim_status"]) + present_status= pim_status & 0xff0000 + change_status=pim_status & 0xff + interrupt_status = fpga_io(iob["interrupt_status"]) + + for pim_num in range(0,8): + if change_status & (0x1 << pim_num) : + status = present_status & (0x10000 << pim_num) + new_pim_status = new_pim_status | (0x1 << pim_num) #prepare to W1C to clear + if status: + pim_dict[pim_num]='1' + else: + pim_dict[pim_num]='0' + + if change_status: + new_pim_status = pim_status | new_pim_status #Write one to clear interrupt bit + fpga_io(iob["pim_status"], new_pim_status) + return True, pim_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, {} + + + def get_pim_max_number(self): + return 8 + + #pim_num start from 0 to 7 + #color:0=amber, 1=blue + #contrl:off(0),on(1), flash(2) + def set_pim_led(self, pim_num, color, control): + if pim_num <0 or pim_num > 7: + return False + + led_val=fpga_io(dom_base[pim_num+1]+dom["system_led"]) + + if color==1: + led_val = led_val | (0x8000 | 0x4000) #blue + elif color==0: + led_val = (led_val & ( ~ 0x8000)) | 0x4000 #amber + else: + print "Set RGB control to Green1" + led_val = led_val & (~ 0x4000) + led_val = led_val & (~ 0xfff) + led_val = led_val | 0x0f0 #B.G.R Birghtness, set to Green + + if control==0: + led_val = led_val & ( ~ 0x3000) #Off + elif control==1: + led_val = led_val & ( ~ 0x3000) #Off + led_val = led_val | 0x1000 #On + else: + led_val = led_val | 0x3000 #Flash + + fpga_io(dom_base[pim_num+1]+dom["system_led"], led_val) + + def get_qsfp_presence(self, port_num): + #xlate port to get pim_num + status, pim_num=self.get_pim_by_port(port_num) + + if status==0: + return False + else: + present = fpga_io(dom_base[pim_num]+dom["qsfp_present"]) + status, shift = self.get_onepimport_by_port(port_num) + if status==0: + return False + else: + if bool(present & (0x1 << shift)): + return 1 #present + else: + return 0 #not present + + #return code: low_power(1) or high_power(0) + def get_low_power_mode(self, port_num): + status, pim_num=self.get_pim_by_port(port_num) + + if status==0: + return False + else: + lp_mode = fpga_io(dom_base[pim_num]+dom["qsfp_lp_mode"]) + + status, shift=self.get_onepimport_by_port(port_num) + if status==0: + return False + else: + if (lp_mode & (0x1 << shift)): + return 1 #low + else: + return 0 #high + + #lpmode=1 to hold QSFP in low power mode. lpmode=0 to release QSFP from low power mode. + def set_low_power_mode(self, port_num, mode): + status, pim_num=self.get_pim_by_port(port_num) + if status==0: + return False + val = fpga_io(dom_base[pim_num]+dom["qsfp_lp_mode"]) + status, shift=self.get_onepimport_by_port(port_num) + if status==0: + return False + else: + if mode==0: + new_val = val & (~(0x1 << shift)) + else: + new_val=val|(0x1 << shift) + status=fpga_io(dom_base[pim_num]+dom["qsfp_lp_mode"], new_val) + return status + + #port_dict[idx]=1 means get interrupt(change evt), port_dict[idx]=0 means no get interrupt + def get_qsfp_interrupt(self): + port_dict={} + #show_qsfp_present_status(1) + for pim_num in range(0, 8): + fpga_io(dom_base[pim_num+1]+dom["qsfp_present_intr_mask"], 0xffff0000) + fpga_io(dom_base[pim_num+1]+dom["qsfp_intr_mask"], 0xffff0000) + for pim_num in range(0, 8): + clear_bit=0 + qsfp_present_intr_status = fpga_io(dom_base[pim_num+1]+dom["qsfp_present_intr"]) + interrupt_status = qsfp_present_intr_status & 0xffff + #time.sleep(2) + if interrupt_status: + for idx in range (0,16): + port_idx=idx + (pim_num*16) + if interrupt_status & (0x1< +#include +#include +#include +#include + +//#define IDEBUG(...) printf(__VA_ARGS__) +#define IDEBUG(...) + +#define FPGA_RESOURCE_NODE "/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0/resource0" +#define FPGA_RESOURCE_LENGTH 0x80000 + + +static int hw_handle = -1; +static void *io_base = NULL; + +static PyObject *fbfpgaio_hw_init(PyObject *self) +{ + const char fpga_resource_node[] = FPGA_RESOURCE_NODE; + + /* Open hardware resource node */ + hw_handle = open(fpga_resource_node, O_RDWR|O_SYNC); + if (hw_handle == -1) { + IDEBUG("[ERROR] %s: open hw resource node\n", __func__); + return Py_False; + } + + IDEBUG("[PASS] %s: open hw resource node\n", __func__); + + /* Mapping hardware resource */ + io_base = mmap(NULL, FPGA_RESOURCE_LENGTH, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_NORESERVE, hw_handle, 0); + if (io_base == MAP_FAILED) { + IDEBUG("[ERROR] %s: mapping resource node\n", __func__); + perror("map_failed"); + fprintf(stderr,"%d %s\\n",errno,strerror(errno)); + return Py_False; + } + + IDEBUG("[PASS] %s: mapping resource node\n", __func__); + + return Py_True; +} + +static PyObject *fbfpgaio_hw_release(PyObject *self) +{ + int retval = 0; + + if ((io_base != NULL) && (io_base != MAP_FAILED)) { + retval = munmap(io_base, FPGA_RESOURCE_LENGTH); + if (retval == 0) { + IDEBUG("[PASS] %s: Unmapping hardware resources\n", __func__); + close(hw_handle); + return Py_True; + } + } + + IDEBUG("[ERROR] %s: unmapping resource node\n", __func__); + return Py_False; +} + +static PyObject *fbfpgaio_hw_io(PyObject *self, PyObject *args) +{ + void *offset = NULL; + /* We are not able to diffrentiate the input data between an unsigned value or a + 'None' object. We assume that the input data (if any) will be an unsigned integer. + The default value of 'data' is larger than the max. number of unsigned integer. + This value signify that the caller of this function does not input a data argument. */ + unsigned long input_data = 0x1FFFFFFFF; + + if (!PyArg_ParseTuple(args, "I|k", &offset, &input_data)) { + return NULL; + } + + if (input_data == 0x1FFFFFFFF) { + // Read operation + IDEBUG("Read operation\n"); + unsigned int *address = (unsigned int *) ((unsigned long) io_base + (unsigned long) offset); + return Py_BuildValue("k", *address); + } else { + // Write operation + IDEBUG("Write operation\n"); + unsigned int *address = (unsigned int *) ((unsigned long) io_base + (unsigned long) offset); + unsigned int data = (unsigned int) (input_data & 0xFFFFFFFF); + *address = data; + + Py_INCREF(Py_None); + return Py_None; + } +} + +static PyMethodDef FbfpgaMethods[] = { + { "hw_init", (PyCFunction) fbfpgaio_hw_init, METH_NOARGS, "Initialize resources for accessing FPGA" }, + { "hw_release", (PyCFunction) fbfpgaio_hw_release, METH_NOARGS, "Release resources for accessing FPGA" }, + { "hw_io", fbfpgaio_hw_io, METH_VARARGS, "Access FPGA" }, + { NULL, NULL, 0, NULL }, +}; + +PyMODINIT_FUNC +initfbfpgaio(void) +{ + char docstr[] = "\ +1. hw_init():\n\ + return value: True/False\n\ +2. hw_release():\n\ + return value: True/False\n\ +3. hw_io(offset,[data])\n\ + return value:\n\ + In reading operation: data which is read from FPGA\n\ + In writing operation: None\n"; + + (void) Py_InitModule3("fbfpgaio", FbfpgaMethods, docstr); +} diff --git a/platform/broadcom/sonic-platform-modules-accton/minipack/service/minipack-setup-qsfp-oom.service b/platform/broadcom/sonic-platform-modules-accton/minipack/service/minipack-setup-qsfp-oom.service new file mode 100644 index 000000000000..df1c961bf181 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/minipack/service/minipack-setup-qsfp-oom.service @@ -0,0 +1,16 @@ +[Unit] +Description=Accton MiniPack Platform setup qsfp oom service +Before=pmon.service +After=minipack-platform-init.service +DefaultDependencies=no + +[Service] +ExecStart=/usr/local/bin/setup_qsfp_eeprom.py +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-accton/minipack/setup.py b/platform/broadcom/sonic-platform-modules-accton/minipack/setup.py old mode 100644 new mode 100755 index aca53ea12798..b5d08c090bab --- a/platform/broadcom/sonic-platform-modules-accton/minipack/setup.py +++ b/platform/broadcom/sonic-platform-modules-accton/minipack/setup.py @@ -2,9 +2,11 @@ import os import sys -from setuptools import setup +from setuptools import setup, Extension os.listdir +module1 = Extension("fbfpgaio", sources = ["minipack/lib/fbfpgaiomodule.c"]) + setup( name='minipack', version='1.0', @@ -12,5 +14,7 @@ packages=['minipack'], package_dir={'minipack': 'minipack/classes'}, + ext_modules=[module1], + ) diff --git a/platform/broadcom/sonic-platform-modules-accton/minipack/utils/accton_minipack_util.py b/platform/broadcom/sonic-platform-modules-accton/minipack/utils/accton_minipack_util.py index 6f3485579c52..261074c5d99a 100755 --- a/platform/broadcom/sonic-platform-modules-accton/minipack/utils/accton_minipack_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/minipack/utils/accton_minipack_util.py @@ -238,7 +238,7 @@ def device_install(): for i in range(0,len(mknod)): #for pca932x need times to built new i2c buses if mknod[i].find('pca954') != -1: - time.sleep(1) + time.sleep(2) status, output = log_os_system(mknod[i], 1) if status: @@ -246,49 +246,14 @@ def device_install(): if FORCE == 0: return status - # initialize multiplexer for 8 PIMs - cmdl = "echo pca9548 0x%x > /sys/bus/i2c/devices/i2c-%d/new_device" - for pim in range(2, 10): - cmdm = cmdl % (0x72, pim) - status, output =log_os_system(cmdm, 1) - cmdm = cmdl % (0x71, pim) - status, output =log_os_system(cmdm, 1) - - for i in range(0, NO_QSFP): - bus = sfp_map(i) - status, output =log_os_system( - "echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(bus)+"/new_device", 1) - if status: - print output - if FORCE == 0: - return status - status, output =log_os_system( - "echo port"+str(i+1)+" > /sys/bus/i2c/devices/"+str(bus)+"-0050/port_name", 1) - if status: - print output - if FORCE == 0: - return status + rm_cmd="rm -rf /usr/local/bin/minipack_qsfp > /dev/null 2>&1" + log_os_system(rm_cmd, 1) + mk_cmd= "mkdir /usr/local/bin/minipack_qsfp" + log_os_system(mk_cmd, 1) return def device_uninstall(): - for i in range(0,NO_QSFP): - bus = sfp_map(i) - target = "/sys/bus/i2c/devices/i2c-"+str(bus)+"/delete_device" - status, output =log_os_system("echo 0x50 > "+ target, 1) - if status: - print output - if FORCE == 0: - return status - - # Multiplexer for 8 PIMs - cmdl = "echo 0x%x > /sys/bus/i2c/devices/i2c-%d/delete_device" - for pim in range(2, 10): - cmdm = cmdl % (0x72, pim) - status, output =log_os_system(cmdm, 1) - cmdm = cmdl % (0x71, pim) - status, output =log_os_system(cmdm, 1) - nodelist = mknod for i in range(len(nodelist)): target = nodelist[-(i+1)] diff --git a/platform/broadcom/sonic-platform-modules-accton/minipack/utils/setup_qsfp_eeprom.py b/platform/broadcom/sonic-platform-modules-accton/minipack/utils/setup_qsfp_eeprom.py new file mode 100755 index 000000000000..84388520b902 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/minipack/utils/setup_qsfp_eeprom.py @@ -0,0 +1,317 @@ +#!/usr/bin/env python +# +# Copyright (c) 2019 Edgecore Networks Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. +# +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 7/22/2019: Jostar create for minipack +# ------------------------------------------------------------------ + +try: + import os + import sys, getopt + import subprocess + import subprocess + import click + import imp + import commands + import logging + import logging.config + import logging.handlers + import types + import time # this is only being used as part of the example + import traceback + from tabulate import tabulate + from minipack.pimutil import PimUtil +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + +#2:idle state. 1:insert state, 0:remove state. +pim_state=[2,2,2,2,2,2,2,2] + +# port_use_i2c_bus[idx], idx means port_idx. Idx start from 0 to 127 +# port_use_i2c_bus[0] means port0 use i2c-device number +# port_use_i2c_bus[1] means port1 use i2c-device number +#At default , port_use_i2c_bus are 0. When PIM insert, it will no be 0 +port_use_i2c_bus= [0] * 128 + +#pim_port_use_bus[idx] are for 8 channel use. At default, pim_port_use_bus[idx]=0 +#pim_port_use_bus[idx] will save pim_idx(0 to 7). +#setup service will check when pim insert at first time. +#It will find +# 1. Does this pim card insert or not in the past. So it will check pim_port_use_bus[idx] +# 2. If make sure that pim_port_use_bus[idx]==0. Assgin oom start i2c dev numer to pim_port_use_bus[idx]. +#Never set pim_port_use_bus[idx] to 0 +#So if pim next insert, it need to check whether pim_port_use_bus[idx] is 0 or not. +#if pim_port_use_bus[idx]!=0, means this pim card has setup oom sysfs +pim_port_use_bus=[0] * 8 + +oom_i2c_bus_table=1 + +pim_dev=PimUtil() + +# Deafults +VERSION = '1.0' +FUNCTION_NAME = '/usr/local/bin/setup_qsfp_eeprom' +DEBUG = False +PIM_MIN=0 +PIM_MAX=8 + +def my_log(txt): + if DEBUG == True: + print "[ACCTON DBG]: "+txt + return + +def log_os_system(cmd): + logging.info('Run :'+cmd) + status = 1 + output = "" + status, output = commands.getstatusoutput(cmd) + if status: + logging.info('Failed :'+cmd) + return status, output + +def qsfp_map_bus(idx): + port = idx + 1 + base = ((port-1)/8*8) + 10 + idx = (port - 1) % 8 + idx = 7 - idx + if (idx%2): + idx = idx -1 + else: + idx = idx +1 + bus = base + idx + return bus + +def pca9548_sysfs(i2c_bus, create): + if create==1: + cmdl = "echo pca9548 0x%x > /sys/bus/i2c/devices/i2c-%d/new_device" + else: + cmdl = "echo 0x%x > /sys/bus/i2c/devices/i2c-%d/delete_device" + + cmdm = cmdl % (0x72, i2c_bus) + status1, output =log_os_system(cmdm) + cmdm = cmdl % (0x71, i2c_bus) + status2, output =log_os_system(cmdm) + return (status1 | status2) + + +def qsfp_eeprom_sys(pim_idx, i2c_bus_order, create): + # initialize multiplexer for 8 PIMs + global port_use_i2c_bus + start_port=pim_idx*16 + end_port = (pim_idx+1)*16 + start_bus=(i2c_bus_order-1)*16 + end_bus = i2c_bus_order*16 + k=start_port + for i in range(start_bus, end_bus): + bus = qsfp_map_bus(i) + if create==1: + status, output =log_os_system( + "echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(bus)+"/new_device") + if status: + print output + return 1 + status, output =log_os_system( + "echo port"+str(k+1)+" > /sys/bus/i2c/devices/"+str(bus)+"-0050/port_name") + + status, output =log_os_system( + "ln -s -f /sys/bus/i2c/devices/"+str(bus)+"-0050/eeprom" + " /usr/local/bin/minipack_qsfp/port" + str(k) + "_eeprom") + if status: + print output + return 1 + else: + status, output =log_os_system( + "echo 0x50 > /sys/bus/i2c/devices/i2c-"+str(bus)+"/delete_device") + if status: + print output + + k=k+1 + + return 0 + +def check_pca_active( i2c_addr, bus): + cmd = "i2cget -y -f %d 0x%x 0x0" + cmd = cmd %(bus, i2c_addr) + status, output = commands.getstatusoutput(cmd) + return status + +def set_pim_port_use_bus(pim_idx): + + global pim_port_use_bus + global oom_i2c_bus_table + + if pim_port_use_bus[pim_idx]!=0: + return 0 + + pim_port_use_bus[pim_idx]=oom_i2c_bus_table + oom_i2c_bus_table=oom_i2c_bus_table+1 + + return pim_port_use_bus[pim_idx] + + +def del_pim_port_use_bus(pim_idx): + global oom_i2c_bus_table + + oom_i2c_bus_table=oom_i2c_bus_table-1 + pim_port_use_bus[pim_idx]=0 + + +def device_remove(): + cmd1 = "echo 0x%x > /sys/bus/i2c/devices/i2c-%d/delete_device" + + for bus in range(2, 10): + #ret=check_pca_active(0x72, bus) + #if ret==0: + + cmdm= cmd1 % (0x72, bus) + status, output = commands.getstatusoutput(cmdm) + print "Remove %d-0072 i2c device"%bus + cmdm= cmd1 % (0x71, bus) + status, output = commands.getstatusoutput(cmdm) + print "Remove %d-0071 i2c device"%bus + + cmd="rm -f /usr/local/bin/minipack_qsfp/port*" + status, output=log_os_system(cmd) + return status + +class device_monitor(object): + + PIM_STATE_REMOVE = 0 + PIM_STATE_INSERT = 1 + PIM_STATE_IDLE=2 + + def __init__(self, log_file, log_level): + """Needs a logger and a logger level.""" + # set up logging to file + logging.basicConfig( + filename=log_file, + filemode='w', + level=log_level, + format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', + datefmt='%H:%M:%S' + ) + # set up logging to console + if log_level == logging.DEBUG: + console = logging.StreamHandler() + console.setLevel(log_level) + formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) + + sys_handler = handler = logging.handlers.SysLogHandler(address = '/dev/log') + sys_handler.setLevel(logging.WARNING) + logging.getLogger('').addHandler(sys_handler) + + #logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level) + + def manage_pim(self): + global pim_dev + global pim_state + + for pim_idx in range(PIM_MIN, PIM_MAX): + presence=pim_dev.get_pim_presence(pim_idx) + if presence==1: + if pim_state[pim_idx]!=self.PIM_STATE_INSERT: + #find which i2c_device can use. It start from 2 + i2c_bus_order=set_pim_port_use_bus(pim_idx) + if i2c_bus_order==0: + logging.info("pim_state[%d] PIM_STATE_INSERT", pim_idx); + pim_state[pim_idx]=self.PIM_STATE_INSERT + continue + + logging.info ("pim_idx=%d oom use i2c_bus_order=%d", pim_idx, i2c_bus_order) + ready=0 + retry_limit=100 + retry_count=0 + while retry_count < retry_limit: + ret=check_pca_active(0x72, pim_idx+2) + if ret==0: + ready=1 + break + retry_count=retry_count+1 + time.sleep(0.2) + + if ready==1: + status=pca9548_sysfs(pim_idx+2, 1) + if status: + status=pca9548_sysfs(pim_idx+2, 0) #del pca i2c device, give up set oom at this time. + del_pim_port_use_bus(pim_idx) + continue + status=qsfp_eeprom_sys(pim_idx,i2c_bus_order, 1) + if status: + status=pca9548_sysfs(pim_idx+2, 0) #del pca i2c device, give up set oom at this time. + del_pim_port_use_bus(pim_idx) + continue + #ret_2=check_pca_active(0x72, pim_idx+2) + #ret_1=check_pca_active(0x71, pim_idx+2) + + pim_state[pim_idx]=self.PIM_STATE_INSERT + logging.info("pim_state[%d] PIM_STATE_INSERT", pim_idx); + else: + print "retry check 100 times for check pca addr" + del_pim_port_use_bus(pim_idx) + else: + if pim_state[pim_idx]==self.PIM_STATE_INSERT: + #pca9548_sysfs(pim_idx+2, 0) + pim_state[pim_idx]=self.PIM_STATE_REMOVE + logging.info("pim_state[%d] PIM_STATE_REMOVE", pim_idx); + +def main(argv): + log_file = '%s.log' % FUNCTION_NAME + log_level = logging.INFO + remove_dev=0 + cpu_pca_i2c_ready=0 + + if len(sys.argv) != 1: + try: + opts, args = getopt.getopt(argv,'hdlr',['lfile=']) + except getopt.GetoptError: + print 'A:Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + for opt, arg in opts: + if opt == '-h': + print 'B:Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + elif opt in ('-d', '--debug'): + log_level = logging.DEBUG + elif opt in ('-l', '--lfile'): + log_file = arg + elif opt in ('-r', '--remove'): + remove_dev=1 + + if remove_dev==1: + device_remove() + return 0 + monitor = device_monitor(log_file, log_level) + global pim_dev + pim_dev.init_pim_fpga() + + while cpu_pca_i2c_ready==0: + status=check_pca_active(0x70, 1) + time.sleep(0.5) + if status==0: + cpu_pca_i2c_ready=1 + print "Make sure CPU pca i2c device is ready" + break + + while True: + monitor.manage_pim() + time.sleep(2) + + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index 530f9707a2c3..390d5e22f9c6 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 530f9707a2c3d06bb50a9b60b24a4bf4eb8a9735 +Subproject commit 390d5e22f9c6c1a007ed325f6b0bd050a79aa5b1 diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/control b/platform/broadcom/sonic-platform-modules-cel/debian/control index 445189822039..2e9b578872fa 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/control +++ b/platform/broadcom/sonic-platform-modules-cel/debian/control @@ -15,3 +15,8 @@ Package: platform-modules-haliburton Architecture: amd64 Depends: linux-image-4.9.0-9-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp + +Package: platform-modules-silverstone +Architecture: amd64 +Depends: linux-image-4.9.0-9-2-amd64 +Description: kernel modules for platform devices such as led, sfp. diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init index aa13d572be78..1e124565a41d 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init @@ -137,10 +137,12 @@ start) # Attach 32 instances of EEPROM driver QSFP ports for ((n=26;n<=58;n++)); do - echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$n/new_device + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-$n/new_device sleep 0.1 done + /bin/sh /usr/local/bin/platform_api_mgnt.sh init + echo "done." ;; 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 b25d47022b08..2ab53302a9bf 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 @@ -1,3 +1,6 @@ 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/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_seastone-r0 +services/platform_api/platform_api_mgnt.sh usr/local/bin +tools/afulnx_64 usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst index baff704171c7..15243c935ca3 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst @@ -1,3 +1,6 @@ depmod -a systemctl enable platform-modules-dx010.service systemctl start platform-modules-dx010.service + +/usr/local/bin/platform_api_mgnt.sh install + diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init index 6c2d4483ac9d..1dc0ea5cfeeb 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init @@ -69,6 +69,8 @@ start) echo "both" > /sys/devices/platform/e1031.smc/SFP/modabs_trig echo 0 > /sys/devices/platform/e1031.smc/SFP/modabs_mask + /bin/sh /usr/local/bin/platform_api_mgnt.sh init + echo "done." ;; 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 312e9c78a5e7..d50306304cd5 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 @@ -3,3 +3,6 @@ haliburton/systemd/platform-modules-haliburton.service lib/systemd/system haliburton/script/fancontrol.sh etc/init.d services/fancontrol/fancontrol.service lib/systemd/system services/fancontrol/fancontrol usr/local/bin +haliburton/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_e1031-r0 +services/platform_api/platform_api_mgnt.sh usr/local/bin +tools/afulnx_64 usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst index ac05d40d702f..e62799bd591c 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.postinst @@ -3,4 +3,6 @@ systemctl enable platform-modules-haliburton.service systemctl enable fancontrol.service systemctl start platform-modules-haliburton.service -systemctl start fancontrol.service \ No newline at end of file +systemctl start fancontrol.service + +/usr/local/bin/platform_api_mgnt.sh install diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.init new file mode 100644 index 000000000000..eb003599ec61 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.init @@ -0,0 +1,51 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: $portmap +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup SilverStone board. +### END INIT INFO + + +case "$1" in +start) + echo -n "Setting up board... " + + modprobe i2c-dev + modprobe baseboard-lpc + modprobe switchboard + modprobe mc24lc64t + modprobe ipmi_devintf + + # Instantiate TLV EEPROM device on I801 bus + devname=`cat /sys/bus/i2c/devices/i2c-0/name` + if [[ $devname == 'SMBus I801 adapter at '* ]]; then + echo 24lc64t 0x56 > /sys/bus/i2c/devices/i2c-0/new_device + fi + decode-syseeprom --init 2> /dev/null & + + /bin/sh /usr/local/bin/platform_api_mgnt.sh init + + echo "done." + ;; + +stop) + echo "done." + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-silverstone.init {start|stop}" + exit 1 + ;; +esac + +exit 0 \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.install new file mode 100644 index 000000000000..67b433ced85f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.install @@ -0,0 +1,6 @@ +silverstone/scripts/sensors usr/bin +silverstone/scripts/platform_sensors.py usr/local/bin +silverstone/cfg/silverstone-modules.conf etc/modules-load.d +silverstone/systemd/platform-modules-silverstone.service lib/systemd/system +silverstone/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_silverstone-r0 +services/platform_api/platform_api_mgnt.sh usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.postinst new file mode 100644 index 000000000000..feb9cf45c219 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.postinst @@ -0,0 +1,5 @@ +depmod -a +systemctl enable platform-modules-silverstone.service +systemctl start platform-modules-silverstone.service + +/usr/local/bin/platform_api_mgnt.sh install diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/rules b/platform/broadcom/sonic-platform-modules-cel/debian/rules index 5086302b70b2..dd5452ccaa11 100755 --- a/platform/broadcom/sonic-platform-modules-cel/debian/rules +++ b/platform/broadcom/sonic-platform-modules-cel/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:= dx010 haliburton +MODULE_DIRS:= dx010 haliburton silverstone %: dh $@ @@ -13,6 +13,9 @@ MODULE_DIRS:= dx010 haliburton override_dh_auto_build: (for mod in $(MODULE_DIRS); do \ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ + cd $(MOD_SRC_DIR)/$${mod}; \ + python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + cd $(MOD_SRC_DIR); \ done) override_dh_auto_install: diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/setup.py b/platform/broadcom/sonic-platform-modules-cel/dx010/setup.py new file mode 100644 index 000000000000..8183788184a7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/setup.py @@ -0,0 +1,34 @@ +from setuptools import setup + +DEVICE_NAME = 'celestica' +HW_SKU = 'x86_64-cel_seastone-r0' + +setup( + name='sonic-platform', + version='1.0', + description='SONiC platform API implementation on Celestica Platforms', + license='Apache 2.0', + author='SONiC Team', + author_email='linuxnetdev@microsoft.com', + url='https://github.com/Azure/sonic-buildimage', + maintainer='Wirut Getbamrung', + maintainer_email='wgetbumr@celestica.com', + packages=[ + 'sonic_platform', + ], + package_dir={ + 'sonic_platform': '../../../../device/{}/{}/sonic_platform'.format(DEVICE_NAME, HW_SKU)}, + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Plugins', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 2.7', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform PLATFORM', +) diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/setup.py b/platform/broadcom/sonic-platform-modules-cel/haliburton/setup.py new file mode 100644 index 000000000000..17056855106e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/haliburton/setup.py @@ -0,0 +1,34 @@ +from setuptools import setup + +DEVICE_NAME = 'celestica' +HW_SKU = 'x86_64-cel_e1031-r0' + +setup( + name='sonic-platform', + version='1.0', + description='SONiC platform API implementation on Celestica Platforms', + license='Apache 2.0', + author='SONiC Team', + author_email='linuxnetdev@microsoft.com', + url='https://github.com/Azure/sonic-buildimage', + maintainer='Wirut Getbamrung', + maintainer_email='wgetbumr@celestica.com', + packages=[ + 'sonic_platform', + ], + package_dir={ + 'sonic_platform': '../../../../device/{}/{}/sonic_platform'.format(DEVICE_NAME, HW_SKU)}, + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Plugins', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 2.7', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform PLATFORM', +) diff --git a/platform/broadcom/sonic-platform-modules-cel/services/platform_api/platform_api_mgnt.sh b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/platform_api_mgnt.sh new file mode 100755 index 000000000000..e1d330357894 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/services/platform_api/platform_api_mgnt.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +PREV_REBOOT_CAUSE="/host/reboot-cause/" +DEVICE="/usr/share/sonic/device" +PLATFORM=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) +FILES=$DEVICE/$PLATFORM/api_files + +install() { + # Install sonic-platform package + if [ -e $DEVICE/$PLATFORM/sonic_platform-1.0-py2-none-any.whl ]; then + pip install $DEVICE/$PLATFORM/sonic_platform-1.0-py2-none-any.whl + fi +} + +init() { + # mount needed files for sonic-platform package + mkdir -p $FILES + + mkdir -p $FILES/reboot-cause + mount -B $PREV_REBOOT_CAUSE $FILES/reboot-cause +} + +deinit() { + # deinit sonic-platform package + umount -f $PREV_REBOOT_CAUSE $FILES/reboot-cause >/dev/null 2>/dev/null +} + +uninstall() { + # Uninstall sonic-platform package + pip uninstall -y sonic-platform >/dev/null 2>/dev/null +} + +case "$1" in +install | uninstall | init | deinit) + $1 + ;; +*) + echo "Usage: $0 {install|uninstall|init|deinit}" + exit 1 + ;; +esac diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/cfg/silverstone-modules.conf b/platform/broadcom/sonic-platform-modules-cel/silverstone/cfg/silverstone-modules.conf new file mode 100644 index 000000000000..cb8dcf640ba3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/cfg/silverstone-modules.conf @@ -0,0 +1,15 @@ +# /etc/modules: kernel modules to load at boot time. +# +# This file contains the names of kernel modules that should be loaded +# at boot time, one per line. Lines beginning with "#" are ignored. + +i2c-i801 +i2c-isch +i2c-ismt +i2c-dev +i2c-mux +i2c-smbus + +i2c-mux-pca954x +ipmi_devintf +ipmi_si \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/Makefile b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/Makefile new file mode 100644 index 000000000000..f6ad4d9ba4d1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/Makefile @@ -0,0 +1 @@ +obj-m := baseboard-lpc.o mc24lc64t.o switchboard.o \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/baseboard-lpc.c b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/baseboard-lpc.c new file mode 100644 index 000000000000..b6291f7d3ce4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/baseboard-lpc.c @@ -0,0 +1,433 @@ +/* + * baseboard-lpc.c - The CPLD driver for the Base Board of Silverstone + * The driver implement sysfs to access CPLD register on the baseboard of Silverstone via LPC bus. + * Copyright (C) 2018 Celestica Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "baseboard-lpc" +/** + * CPLD register address for read and write. + */ +#define VERSION_ADDR 0xA100 +#define SCRATCH_ADDR 0xA101 +#define BLT_MONTH_ADDR 0xA102 +#define BLT_DATE_ADDR 0xA103 +#define REBOOT_CAUSE 0xA106 +#define SYS_LED_ADDR 0xA162 +#define CPLD_REGISTER_SIZE 0x93 + +/* System reboot cause recorded in CPLD */ +static const struct { + const char *reason; + u8 reset_code; +} reboot_causes[] = { + {"POR", 0x11}, + {"soft-warm-rst", 0x22}, + {"soft-cold-rst", 0x33}, + {"warm-rst", 0x44}, + {"cold-rst", 0x55}, + {"wdt-rst", 0x66}, + {"power-cycle", 0x77} +}; + +struct cpld_b_data { + struct mutex cpld_lock; + uint16_t read_addr; +}; + +struct cpld_b_data *cpld_data; + +static ssize_t scratch_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(SCRATCH_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return sprintf(buf,"0x%2.2x\n", data); +} + +static ssize_t scratch_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned long data; + char *last; + + mutex_lock(&cpld_data->cpld_lock); + data = (uint16_t)strtoul(buf,&last,16); + if(data == 0 && buf == last){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + outb(data, SCRATCH_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_RW(scratch); + + +/* CPLD version attributes */ +static ssize_t version_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 version; + mutex_lock(&cpld_data->cpld_lock); + version = inb(VERSION_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return sprintf(buf, "%d.%d\n", version >> 4, version & 0x0F); +} +static DEVICE_ATTR_RO(version); + +/* CPLD version attributes */ +static ssize_t build_date_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 month, day_of_month; + mutex_lock(&cpld_data->cpld_lock); + day_of_month = inb(BLT_DATE_ADDR); + month = inb(BLT_MONTH_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return sprintf(buf, "%x/%x\n", day_of_month, month); +} +static DEVICE_ATTR_RO(build_date); + + +static ssize_t getreg_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + uint16_t addr; + char *last; + + addr = (uint16_t)strtoul(buf,&last,16); + if(addr == 0 && buf == last){ + return -EINVAL; + } + cpld_data->read_addr = addr; + return count; +} + +static ssize_t getreg_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int len = 0; + + mutex_lock(&cpld_data->cpld_lock); + len = sprintf(buf, "0x%2.2x\n",inb(cpld_data->read_addr)); + mutex_unlock(&cpld_data->cpld_lock); + return len; +} +static DEVICE_ATTR_RW(getreg); + +static ssize_t setreg_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + uint16_t addr; + uint8_t value; + char *tok; + char clone[count]; + char *pclone = clone; + char *last; + + strcpy(clone, buf); + + mutex_lock(&cpld_data->cpld_lock); + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + addr = (uint16_t)strtoul(tok,&last,16); + if(addr == 0 && tok == last){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + value = (uint8_t)strtoul(tok,&last,16); + if(value == 0 && tok == last){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + + outb(value,addr); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_WO(setreg); + +/** + * Read all CPLD register in binary mode. + */ +static ssize_t dump_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) +{ + unsigned long i=0; + ssize_t status; + + mutex_lock(&cpld_data->cpld_lock); +begin: + if(i < count){ + buf[i++] = inb(VERSION_ADDR + off); + off++; + msleep(1); + goto begin; + } + status = count; + + mutex_unlock(&cpld_data->cpld_lock); + return status; +} +static BIN_ATTR_RO(dump, CPLD_REGISTER_SIZE); + +/** + * Show system led status - on/off/1hz/4hz + * @return Hex string read from scratch register. + */ +static ssize_t sys_led_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(SYS_LED_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + data = data & 0x3; + return sprintf(buf, "%s\n", + data == 0x03 ? "off" : data == 0x02 ? "4hz" : data ==0x01 ? "1hz": "on"); +} + +/** + * Set the status of system led - on/off/1hz/4hz + */ +static ssize_t sys_led_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned char led_status,data; + if(sysfs_streq(buf, "off")){ + led_status = 0x03; + }else if(sysfs_streq(buf, "4hz")){ + led_status = 0x02; + }else if(sysfs_streq(buf, "1hz")){ + led_status = 0x01; + }else if(sysfs_streq(buf, "on")){ + led_status = 0x00; + }else{ + count = -EINVAL; + return count; + } + mutex_lock(&cpld_data->cpld_lock); + data = inb(SYS_LED_ADDR); + data = data & ~(0x3); + data = data | led_status; + outb(data, SYS_LED_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_RW(sys_led); + +/** + * Show system led color - both/green/yellow/none + * @return Current led color. + */ +static ssize_t sys_led_color_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(SYS_LED_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + data = (data >> 4) & 0x3; + return sprintf(buf, "%s\n", + data == 0x03 ? "off" : data == 0x02 ? "yellow" : data ==0x01 ? "green": "both"); +} + +/** + * Set the color of system led - both/green/yellow/none + */ +static ssize_t sys_led_color_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned char led_status,data; + if(sysfs_streq(buf, "off")){ + led_status = 0x03; + }else if(sysfs_streq(buf, "yellow")){ + led_status = 0x02; + }else if(sysfs_streq(buf, "green")){ + led_status = 0x01; + }else if(sysfs_streq(buf, "both")){ + led_status = 0x00; + }else{ + count = -EINVAL; + return count; + } + mutex_lock(&cpld_data->cpld_lock); + data = inb(SYS_LED_ADDR); + data = data & ~( 0x3 << 4); + data = data | (led_status << 4); + outb(data, SYS_LED_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_RW(sys_led_color); + +static ssize_t reboot_cause_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t status; + u8 reg; + int i; + + mutex_lock(&cpld_data->cpld_lock); + reg = inb(REBOOT_CAUSE); + mutex_unlock(&cpld_data->cpld_lock); + + status = 0; + dev_dbg(dev,"reboot: 0x%x\n", (u8)reg); + for(i = 0; i < ARRAY_SIZE(reboot_causes); i++){ + if((u8)reg == reboot_causes[i].reset_code){ + status = sprintf(buf, "%s\n", + reboot_causes[i].reason); + break; + } + } + return status; +} +DEVICE_ATTR_RO(reboot_cause); + +static struct attribute *cpld_b_attrs[] = { + &dev_attr_version.attr, + &dev_attr_build_date.attr, + &dev_attr_scratch.attr, + &dev_attr_getreg.attr, + &dev_attr_setreg.attr, + &dev_attr_sys_led.attr, + &dev_attr_sys_led_color.attr, + &dev_attr_reboot_cause.attr, + NULL, +}; + +static struct bin_attribute *cpld_b_bin_attrs[] = { + &bin_attr_dump, + NULL, +}; + +static struct attribute_group cpld_b_attrs_grp = { + .attrs = cpld_b_attrs, + .bin_attrs = cpld_b_bin_attrs, +}; + +static struct resource cpld_b_resources[] = { + { + .start = 0xA100, + .end = 0xA192, + .flags = IORESOURCE_IO, + }, +}; + +static void cpld_b_dev_release( struct device * dev) +{ + return; +} + +static struct platform_device cpld_b_dev = { + .name = DRIVER_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(cpld_b_resources), + .resource = cpld_b_resources, + .dev = { + .release = cpld_b_dev_release, + } +}; + +static int cpld_b_drv_probe(struct platform_device *pdev) +{ + struct resource *res; + int err = 0; + + cpld_data = devm_kzalloc(&pdev->dev, sizeof(struct cpld_b_data), + GFP_KERNEL); + if (!cpld_data) + return -ENOMEM; + + mutex_init(&cpld_data->cpld_lock); + + cpld_data->read_addr = VERSION_ADDR; + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (unlikely(!res)) { + printk(KERN_ERR "Specified Resource Not Available...\n"); + return -ENODEV; + } + + err = sysfs_create_group(&pdev->dev.kobj, &cpld_b_attrs_grp); + if (err) { + printk(KERN_ERR "Cannot create sysfs for baseboard CPLD\n"); + return err; + } + return 0; +} + +static int cpld_b_drv_remove(struct platform_device *pdev) +{ + sysfs_remove_group(&pdev->dev.kobj, &cpld_b_attrs_grp); + return 0; +} + +static struct platform_driver cpld_b_drv = { + .probe = cpld_b_drv_probe, + .remove = __exit_p(cpld_b_drv_remove), + .driver = { + .name = DRIVER_NAME, + }, +}; + +int cpld_b_init(void) +{ + // Register platform device and platform driver + platform_device_register(&cpld_b_dev); + platform_driver_register(&cpld_b_drv); + return 0; +} + +void cpld_b_exit(void) +{ + // Unregister platform device and platform driver + platform_driver_unregister(&cpld_b_drv); + platform_device_unregister(&cpld_b_dev); +} + +module_init(cpld_b_init); +module_exit(cpld_b_exit); + + +MODULE_AUTHOR("Celestica Inc."); +MODULE_DESCRIPTION("Celestica Silverstone CPLD baseboard driver"); +MODULE_VERSION("0.2.0"); +MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/mc24lc64t.c b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/mc24lc64t.c new file mode 100644 index 000000000000..fc15bb74b68d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/mc24lc64t.c @@ -0,0 +1,174 @@ +/* + * mc24lc64t.c - driver for Microchip 24LC64T + * + * Copyright (C) 2017 Celestica Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define EEPROM_SIZE 8192 //mc24lt64t eeprom size in bytes. + +struct mc24lc64t_data { + struct mutex update_lock; +}; + +static ssize_t mc24lc64t_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = kobj_to_i2c_client(kobj); + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + unsigned long timeout, read_time, i = 0; + int status; + + mutex_lock(&drvdata->update_lock); + + if (i2c_smbus_write_byte_data(client, off>>8, off)) + { + status = -EIO; + goto exit; + } + + msleep(1); + +begin: + + if (i < count) + { + timeout = jiffies + msecs_to_jiffies(25); /* 25 mS timeout*/ + do { + read_time = jiffies; + + status = i2c_smbus_read_byte(client); + if (status >= 0) + { + buf[i++] = status; + goto begin; + } + } while (time_before(read_time, timeout)); + + status = -ETIMEDOUT; + goto exit; + } + + status = count; + +exit: + mutex_unlock(&drvdata->update_lock); + + return status; +} + + +static ssize_t mc24lc64t_write (struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count){ + + struct i2c_client *client = kobj_to_i2c_client(kobj); + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + unsigned long timeout, write_time, i = 0; + int status; + u16 value; + + mutex_lock(&drvdata->update_lock); + +begin: + if (i < count){ + timeout = jiffies + msecs_to_jiffies(25); /* 25 mS timeout*/ + value = (buf[i] << 8 | ( off &0xff)); + do { + write_time = jiffies; + status = i2c_smbus_write_word_data(client, off>>8, value); + if (status >= 0) + { + // increase offset + off++; + // increase buffer index + i++; + goto begin; + } + } while (time_before(write_time, timeout)); + status = -ETIMEDOUT; + goto exit; + } + status = count; + +exit: + mutex_unlock(&drvdata->update_lock); + return status; +} + + +static struct bin_attribute mc24lc64t_bit_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO | S_IWUGO, + }, + .size = EEPROM_SIZE, + .read = mc24lc64t_read, + .write = mc24lc64t_write, +}; + +static int mc24lc64t_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adapter = client->adapter; + struct mc24lc64t_data *drvdata; + int err; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA + | I2C_FUNC_SMBUS_READ_BYTE)) + return -EPFNOSUPPORT; + + if (!(drvdata = devm_kzalloc(&client->dev, + sizeof(struct mc24lc64t_data), GFP_KERNEL))) + return -ENOMEM; + + i2c_set_clientdata(client, drvdata); + mutex_init(&drvdata->update_lock); + + err = sysfs_create_bin_file(&client->dev.kobj, &mc24lc64t_bit_attr); + return err; +} + +static int mc24lc64t_remove(struct i2c_client *client) +{ + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + sysfs_remove_bin_file(&client->dev.kobj, &mc24lc64t_bit_attr); + + return 0; +} + +static const struct i2c_device_id mc24lc64t_id[] = { + { "24lc64t", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mc24lc64t_id); + +static struct i2c_driver mc24lc64t_driver = { + .driver = { + .name = "mc24lc64t", + .owner = THIS_MODULE, + }, + .probe = mc24lc64t_probe, + .remove = mc24lc64t_remove, + .id_table = mc24lc64t_id, +}; + +module_i2c_driver(mc24lc64t_driver); + +MODULE_AUTHOR("Abhisit Sangjan "); +MODULE_DESCRIPTION("Microchip 24LC64T Driver"); +MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/switchboard.c b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/switchboard.c new file mode 100644 index 000000000000..2ee6c858a8b6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/switchboard.c @@ -0,0 +1,2106 @@ +/* + * switchboard.c - driver for Silverstone Switch board FPGA/CPLD. + * + * Author: Pradchaya Phucharoen + * + * Copyright (C) 2018 Celestica Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * / + * \--sys + * \--devices + * \--platform + * \--silverstone + * |--FPGA + * |--CPLD1 + * |--CPLD2 + * \--SFF + * |--QSFP[1..32] + * \--SFP[1..2] + * + */ + +#ifndef TEST_MODE +#define MOD_VERSION "1.2.0" +#else +#define MOD_VERSION "TEST" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int majorNumber; + +#define CLASS_NAME "silverstone_fpga" +#define DRIVER_NAME "switchboard" +#define FPGA_PCI_NAME "Silverstone_fpga_pci" +#define DEVICE_NAME "fwupgrade" + + +static int smbus_access(struct i2c_adapter *adapter, u16 addr, + unsigned short flags, char rw, u8 cmd, + int size, union i2c_smbus_data *data); + +static int fpga_i2c_access(struct i2c_adapter *adapter, u16 addr, + unsigned short flags, char rw, u8 cmd, + int size, union i2c_smbus_data *data); + +static int fpgafw_init(void); +static void fpgafw_exit(void); + + +/* +======================================== +FPGA PCIe BAR 0 Registers +======================================== +Misc Control 0x00000000 – 0x000000FF. +I2C_CH1 0x00000100 - 0x00000110 +I2C_CH2 0x00000200 - 0x00000210. +I2C_CH3 0x00000300 - 0x00000310. +I2C_CH4 0x00000400 - 0x00000410. +I2C_CH5 0x00000500 - 0x00000510. +I2C_CH6 0x00000600 - 0x00000610. +I2C_CH7 0x00000700 - 0x00000710. +I2C_CH8 0x00000800 - 0x00000810. +I2C_CH9 0x00000900 - 0x00000910. +I2C_CH10 0x00000A00 - 0x00000A10. +I2C_CH11 0x00000B00 - 0x00000B10. +I2C_CH12 0x00000C00 - 0x00000C10. +I2C_CH13 0x00000D00 - 0x00000D10. +SPI Master 0x00001200 - 0x00001300. +DPLL SPI Master 0x00001320 - 0x0000132F. +PORT XCVR 0x00004000 - 0x00004FFF. +*/ + +/* MISC */ +#define FPGA_VERSION 0x0000 +#define FPGA_VERSION_MJ_MSK 0xff00 +#define FPGA_VERSION_MN_MSK 0x00ff +#define FPGA_SCRATCH 0x0004 +#define FPGA_BROAD_TYPE 0x0008 +#define FPGA_BROAD_REV_MSK 0x0038 +#define FPGA_BROAD_ID_MSK 0x0007 +#define FPGA_PLL_STATUS 0x0014 +#define BMC_I2C_SCRATCH 0x0020 +#define FPGA_SLAVE_CPLD_REST 0x0030 +#define FPGA_PERIPH_RESET_CTRL 0x0034 +#define FPGA_INT_STATUS 0x0040 +#define FPGA_INT_SRC_STATUS 0x0044 +#define FPGA_INT_FLAG 0x0048 +#define FPGA_INT_MASK 0x004c +#define FPGA_MISC_CTRL 0x0050 +#define FPGA_MISC_STATUS 0x0054 +#define FPGA_AVS_VID_STATUS 0x0068 +#define FPGA_PORT_XCVR_READY 0x000c + +/* I2C_MASTER BASE ADDR */ +#define I2C_MASTER_FREQ_1 0x0100 +#define I2C_MASTER_CTRL_1 0x0104 +#define I2C_MASTER_STATUS_1 0x0108 +#define I2C_MASTER_DATA_1 0x010c +#define I2C_MASTER_PORT_ID_1 0x0110 +#define I2C_MASTER_CH_1 1 +#define I2C_MASTER_CH_2 2 +#define I2C_MASTER_CH_3 3 +#define I2C_MASTER_CH_4 4 +#define I2C_MASTER_CH_5 5 +#define I2C_MASTER_CH_6 6 +#define I2C_MASTER_CH_7 7 +#define I2C_MASTER_CH_8 8 +#define I2C_MASTER_CH_9 9 +#define I2C_MASTER_CH_10 10 +#define I2C_MASTER_CH_11 11 +#define I2C_MASTER_CH_12 12 +#define I2C_MASTER_CH_13 13 + +#define I2C_MASTER_CH_TOTAL I2C_MASTER_CH_5 + +/* SPI_MASTER */ +#define SPI_MASTER_WR_EN 0x1200 /* one bit */ +#define SPI_MASTER_WR_DATA 0x1204 /* 32 bits */ +#define SPI_MASTER_CHK_ID 0x1208 /* one bit */ +#define SPI_MASTER_VERIFY 0x120c /* one bit */ +#define SPI_MASTER_STATUS 0x1210 /* 15 bits */ +#define SPI_MASTER_MODULE_RST 0x1214 /* one bit */ + +/* FPGA FRONT PANEL PORT MGMT */ +#define SFF_PORT_CTRL_BASE 0x4000 +#define SFF_PORT_STATUS_BASE 0x4004 +#define SFF_PORT_INT_STATUS_BASE 0x4008 +#define SFF_PORT_INT_MASK_BASE 0x400c + +#define PORT_XCVR_REGISTER_SIZE 0x1000 + +/* PORT CTRL REGISTER +[31:7] RSVD +[6] LPMOD 6 +[5] RSVD +[4] RST 4 +[3:1] RSVD +[0] TXDIS 0 +*/ +#define CTRL_LPMOD 6 +#define CTRL_RST 4 +#define CTRL_TXDIS 0 + +/* PORT STATUS REGISTER +[31:6] RSVD +[5] IRQ 5 +[4] PRESENT 4 +[3] RSVD +[2] TXFAULT 2 +[1] RXLOS 1 +[0] MODABS 0 +*/ +#define STAT_IRQ 5 +#define STAT_PRESENT 4 +#define STAT_TXFAULT 2 +#define STAT_RXLOS 1 +#define STAT_MODABS 0 + +/* PORT INTRPT REGISTER +[31:6] RSVD +[5] INT_N 5 +[4] PRESENT 4 +[3] RSVD +[2] RSVD +[1] RXLOS 1 +[0] MODABS 0 +*/ +#define INTR_INT_N 5 +#define INTR_PRESENT 4 +#define INTR_TXFAULT 2 +#define INTR_RXLOS 1 +#define INTR_MODABS 0 + +/* PORT INT MASK REGISTER +[31:6] RSVD +[5] INT_N 5 +[4] PRESENT 4 +[3] RSVD +[2] RSVD +[1] RXLOS_INT 1 +[0] MODABS 0 +*/ +#define MASK_INT_N 5 +#define MASK_PRESENT 4 +#define MASK_TXFAULT 2 +#define MASK_RXLOS 1 +#define MASK_MODABS 0 + +enum { + I2C_SR_BIT_RXAK = 0, + I2C_SR_BIT_MIF, + I2C_SR_BIT_SRW, + I2C_SR_BIT_BCSTM, + I2C_SR_BIT_MAL, + I2C_SR_BIT_MBB, + I2C_SR_BIT_MAAS, + I2C_SR_BIT_MCF +}; + +enum { + I2C_CR_BIT_BCST = 0, + I2C_CR_BIT_RSTA = 2, + I2C_CR_BIT_TXAK, + I2C_CR_BIT_MTX, + I2C_CR_BIT_MSTA, + I2C_CR_BIT_MIEN, + I2C_CR_BIT_MEN, +}; + +/** + * + * The function is i2c algorithm implement to allow master access to + * correct endpoint devices trough the PCA9548 switch devices. + * + * FPGA I2C Master [mutex resource] + * | + * | + * --------------------------- + * | PCA9548(s) | + * ---1--2--3--4--5--6--7--8-- + * | | | | | | | | + * EEPROM ... EEPROM + * + */ + +#define VIRTUAL_I2C_QSFP_PORT 32 +#define VIRTUAL_I2C_SFP_PORT 2 + +#define SFF_PORT_TOTAL VIRTUAL_I2C_QSFP_PORT + VIRTUAL_I2C_SFP_PORT + +#define VIRTUAL_I2C_BUS_OFFSET 10 +#define CPLD1_SLAVE_ADDR 0x30 +#define CPLD2_SLAVE_ADDR 0x31 + +static struct class* fpgafwclass = NULL; // < The device-driver class struct pointer +static struct device* fpgafwdev = NULL; // < The device-driver device struct pointer + +#define PCI_VENDOR_ID_TEST 0x1af4 + +#ifndef PCI_VENDOR_ID_XILINX +#define PCI_VENDOR_ID_XILINX 0x10EE +#endif + +#define FPGA_PCIE_DEVICE_ID 0x7021 +#define TEST_PCIE_DEVICE_ID 0x1110 + + +#ifdef DEBUG_KERN +#define info(fmt,args...) printk(KERN_INFO "line %3d : "fmt,__LINE__,##args) +#define check(REG) printk(KERN_INFO "line %3d : %-8s = %2.2X",__LINE__,#REG,ioread8(REG)); +#else +#define info(fmt,args...) +#define check(REG) +#endif + +#define GET_REG_BIT(REG,BIT) ((ioread8(REG) >> BIT) & 0x01) +#define SET_REG_BIT_H(REG,BIT) iowrite8(ioread8(REG) | (0x01 << BIT),REG) +#define SET_REG_BIT_L(REG,BIT) iowrite8(ioread8(REG) & ~(0x01 << BIT),REG) + +static struct mutex fpga_i2c_master_locks[I2C_MASTER_CH_TOTAL]; +/* Store lasted switch address and channel */ +static uint16_t fpga_i2c_lasted_access_port[I2C_MASTER_CH_TOTAL]; + +enum PORT_TYPE { + NONE, + QSFP, + SFP +}; + +struct i2c_switch { + unsigned char master_bus; // I2C bus number + unsigned char switch_addr; // PCA9548 device address, 0xFF if directly connect to a bus. + unsigned char channel; // PCA9548 channel number. If the switch_addr is 0xFF, this value is ignored. + enum PORT_TYPE port_type; // QSFP/SFP tranceiver port type. + char calling_name[20]; // Calling name. +}; + +struct i2c_dev_data { + int portid; + struct i2c_switch pca9548; +}; + +/* PREDEFINED I2C SWITCH DEVICE TOPOLOGY */ +static struct i2c_switch fpga_i2c_bus_dev[] = { + /* BUS3 QSFP Exported as virtual bus */ + {I2C_MASTER_CH_3, 0x71, 2, QSFP, "QSFP1"}, {I2C_MASTER_CH_3, 0x71, 3, QSFP, "QSFP2"}, + {I2C_MASTER_CH_3, 0x71, 0, QSFP, "QSFP3"}, {I2C_MASTER_CH_3, 0x71, 1, QSFP, "QSFP4"}, + {I2C_MASTER_CH_3, 0x71, 6, QSFP, "QSFP5"}, {I2C_MASTER_CH_3, 0x71, 5, QSFP, "QSFP6"}, + {I2C_MASTER_CH_3, 0x73, 7, QSFP, "QSFP7"}, {I2C_MASTER_CH_3, 0x71, 4, QSFP, "QSFP8"}, + + {I2C_MASTER_CH_3, 0x73, 4, QSFP, "QSFP9"}, {I2C_MASTER_CH_3, 0x73, 3, QSFP, "QSFP10"}, + {I2C_MASTER_CH_3, 0x73, 6, QSFP, "QSFP11"}, {I2C_MASTER_CH_3, 0x73, 2, QSFP, "QSFP12"}, + {I2C_MASTER_CH_3, 0x73, 1, QSFP, "QSFP13"}, {I2C_MASTER_CH_3, 0x73, 5, QSFP, "QSFP14"}, + {I2C_MASTER_CH_3, 0x71, 7, QSFP, "QSFP15"}, {I2C_MASTER_CH_3, 0x73, 0, QSFP, "QSFP16"}, + + {I2C_MASTER_CH_3, 0x72, 1, QSFP, "QSFP17"}, {I2C_MASTER_CH_3, 0x72, 7, QSFP, "QSFP18"}, + {I2C_MASTER_CH_3, 0x72, 4, QSFP, "QSFP19"}, {I2C_MASTER_CH_3, 0x72, 0, QSFP, "QSFP20"}, + {I2C_MASTER_CH_3, 0x72, 5, QSFP, "QSFP21"}, {I2C_MASTER_CH_3, 0x72, 2, QSFP, "QSFP22"}, + {I2C_MASTER_CH_3, 0x70, 5, QSFP, "QSFP23"}, {I2C_MASTER_CH_3, 0x72, 6, QSFP, "QSFP24"}, + + {I2C_MASTER_CH_3, 0x72, 3, QSFP, "QSFP25"}, {I2C_MASTER_CH_3, 0x70, 6, QSFP, "QSFP26"}, + {I2C_MASTER_CH_3, 0x70, 0, QSFP, "QSFP27"}, {I2C_MASTER_CH_3, 0x70, 7, QSFP, "QSFP28"}, + {I2C_MASTER_CH_3, 0x70, 2, QSFP, "QSFP29"}, {I2C_MASTER_CH_3, 0x70, 4, QSFP, "QSFP30"}, + {I2C_MASTER_CH_3, 0x70, 3, QSFP, "QSFP31"}, {I2C_MASTER_CH_3, 0x70, 1, QSFP, "QSFP32"}, + /* BUS1 SFP+ Exported as virtual bus */ + {I2C_MASTER_CH_1, 0xFF, 0, SFP, "SFP1"}, + /* BUS2 SFP+ Exported as virtual bus */ + {I2C_MASTER_CH_2, 0xFF, 0, SFP, "SFP2"}, + /* BUS4 CPLD Access via I2C */ + {I2C_MASTER_CH_4, 0xFF, 0, NONE, "CPLD_S"}, + /* BUS5 CPLD_B */ + {I2C_MASTER_CH_5, 0xFF, 0, NONE, "CPLD_B"}, +}; + +#define VIRTUAL_I2C_PORT_LENGTH ARRAY_SIZE(fpga_i2c_bus_dev) +#define SW_I2C_CPLD_INDEX SFF_PORT_TOTAL + +struct fpga_device { + /* data mmio region */ + void __iomem *data_base_addr; + resource_size_t data_mmio_start; + resource_size_t data_mmio_len; +}; + +static struct fpga_device fpga_dev = { + .data_base_addr = 0, + .data_mmio_start = 0, + .data_mmio_len = 0, +}; + +struct silverstone_fpga_data { + struct device *sff_devices[SFF_PORT_TOTAL]; + struct i2c_client *sff_i2c_clients[SFF_PORT_TOTAL]; + struct i2c_adapter *i2c_adapter[VIRTUAL_I2C_PORT_LENGTH]; + struct mutex fpga_lock; // For FPGA internal lock + void __iomem * fpga_read_addr; + uint8_t cpld1_read_addr; + uint8_t cpld2_read_addr; +}; + +struct sff_device_data { + int portid; + enum PORT_TYPE port_type; +}; + +struct silverstone_fpga_data *fpga_data; + +/* + * Kernel object for other module drivers. + * Other module can use these kobject as a parent. + */ + +static struct kobject *fpga = NULL; +static struct kobject *cpld1 = NULL; +static struct kobject *cpld2 = NULL; + +/** + * Device node in sysfs tree. + */ +static struct device *sff_dev = NULL; + + +static ssize_t version_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + u32 version; + + mutex_lock(&fpga_data->fpga_lock); + version = ioread32(fpga_dev.data_base_addr + FPGA_VERSION); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d.%d\n", version >> 16, version & 0xFFFF); +} + +/** + * Show the value of the register set by 'set_fpga_reg_address' + * If the address is not set by 'set_fpga_reg_address' first, + * The version register is selected by default. + * @param buf register value in hextring + * @return number of bytes read, or an error code + */ +static ssize_t get_fpga_reg_value(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + // read data from the address + uint32_t data; + data = ioread32(fpga_data->fpga_read_addr); + return sprintf(buf, "0x%8.8x\n", data); +} +/** + * Store the register address + * @param buf address wanted to be read value of + * @return number of bytes stored, or an error code + */ +static ssize_t set_fpga_reg_address(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + uint32_t addr; + char *last; + + addr = (uint32_t)strtoul(buf, &last, 16); + if (addr == 0 && buf == last) { + return -EINVAL; + } + fpga_data->fpga_read_addr = fpga_dev.data_base_addr + addr; + return count; +} +/** + * Show value of fpga scratch register + * @param buf register value in hexstring + * @return number of bytes read, or an error code + */ +static ssize_t get_fpga_scratch(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + return sprintf(buf, "0x%8.8x\n", ioread32(fpga_dev.data_base_addr + FPGA_SCRATCH) & 0xffffffff); +} +/** + * Store value of fpga scratch register + * @param buf scratch register value passing from user space + * @return number of bytes stored, or an error code + */ +static ssize_t set_fpga_scratch(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + uint32_t data; + char *last; + data = (uint32_t)strtoul(buf, &last, 16); + if (data == 0 && buf == last) { + return -EINVAL; + } + iowrite32(data, fpga_dev.data_base_addr + FPGA_SCRATCH); + return count; +} +/** + * Store a value in a specific register address + * @param buf the value and address in format '0xhhhh 0xhhhhhhhh' + * @return number of bytes sent by user space, or an error code + */ +static ssize_t set_fpga_reg_value(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + // register are 4 bytes + uint32_t addr; + uint32_t value; + uint32_t mode = 8; + char *tok; + char clone[count]; + char *pclone = clone; + char *last; + + strcpy(clone, buf); + + mutex_lock(&fpga_data->fpga_lock); + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + addr = (uint32_t)strtoul(tok, &last, 16); + if (addr == 0 && tok == last) { + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + value = (uint32_t)strtoul(tok, &last, 16); + if (value == 0 && tok == last) { + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + mode = 32; + } else { + mode = (uint32_t)strtoul(tok, &last, 10); + if (mode == 0 && tok == last) { + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + } + if (mode == 32) { + iowrite32(value, fpga_dev.data_base_addr + addr); + } else if (mode == 8) { + iowrite8(value, fpga_dev.data_base_addr + addr); + } else { + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + mutex_unlock(&fpga_data->fpga_lock); + return count; +} + +/** + * Show FPGA port XCVR ready status + * @param buf 1 if the functin is ready, 0 if not. + * @return number of bytes read, or an error code + */ +static ssize_t ready_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + unsigned int REGISTER = FPGA_PORT_XCVR_READY; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> 0) & 1U); +} + +/* FPGA attributes */ +static DEVICE_ATTR( getreg, 0600, get_fpga_reg_value, set_fpga_reg_address); +static DEVICE_ATTR( scratch, 0600, get_fpga_scratch, set_fpga_scratch); +static DEVICE_ATTR( setreg, 0200, NULL , set_fpga_reg_value); +static DEVICE_ATTR_RO(ready); +static DEVICE_ATTR_RO(version); + +static struct attribute *fpga_attrs[] = { + &dev_attr_getreg.attr, + &dev_attr_scratch.attr, + &dev_attr_setreg.attr, + &dev_attr_ready.attr, + &dev_attr_version.attr, + NULL, +}; + +static struct attribute_group fpga_attr_grp = { + .attrs = fpga_attrs, +}; + +static ssize_t cpld1_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 version; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x00, + I2C_SMBUS_BYTE_DATA, + (union i2c_smbus_data *)&version); + if (err < 0) + return err; + return sprintf(buf, "%d.%d\n", version >> 4, version & 0x0F); +} +struct device_attribute dev_attr_cpld1_version = __ATTR(version, 0444, cpld1_version_show , NULL); + +/* SW CPLDs attributes */ +static ssize_t cpld1_getreg_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + uint8_t data; + fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, fpga_data->cpld1_read_addr, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + return sprintf(buf, "0x%2.2x\n", data); +} +static ssize_t cpld1_getreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + uint8_t addr; + char *last; + addr = (uint8_t)strtoul(buf, &last, 16); + if (addr == 0 && buf == last) { + return -EINVAL; + } + fpga_data->cpld1_read_addr = addr; + return size; +} +struct device_attribute dev_attr_cpld1_getreg = __ATTR(getreg, 0600, cpld1_getreg_show, cpld1_getreg_store); + +static ssize_t cpld1_scratch_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + __u8 data; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x01, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) + return err; + return sprintf(buf, "0x%2.2x\n", data); +} +static ssize_t cpld1_scratch_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + // CPLD register is one byte + __u8 data; + char *last; + int err; + data = (uint8_t)strtoul(buf, &last, 16); + if (data == 0 && buf == last) { + return -EINVAL; + } + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, 0x01, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) + return err; + return size; +} +struct device_attribute dev_attr_cpld1_scratch = __ATTR(scratch, 0600, cpld1_scratch_show, cpld1_scratch_store); + +static ssize_t cpld1_setreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + + uint8_t addr, value; + char *tok; + char clone[size]; + char *pclone = clone; + int err; + char *last; + + strcpy(clone, buf); + + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + return -EINVAL; + } + addr = (uint8_t)strtoul(tok, &last, 16); + if (addr == 0 && tok == last) { + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + return -EINVAL; + } + value = (uint8_t)strtoul(tok, &last, 16); + if (value == 0 && tok == last) { + return -EINVAL; + } + + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, addr, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&value); + if (err < 0) + return err; + + return size; +} +struct device_attribute dev_attr_cpld1_setreg = __ATTR(setreg, 0200, NULL, cpld1_setreg_store); + +static struct attribute *cpld1_attrs[] = { + &dev_attr_cpld1_version.attr, + &dev_attr_cpld1_getreg.attr, + &dev_attr_cpld1_scratch.attr, + &dev_attr_cpld1_setreg.attr, + NULL, +}; + +static struct attribute_group cpld1_attr_grp = { + .attrs = cpld1_attrs, +}; + +static ssize_t cpld2_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 version; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x00, + I2C_SMBUS_BYTE_DATA, + (union i2c_smbus_data *)&version); + if (err < 0) + return err; + return sprintf(buf, "%d.%d\n", version >> 4, version & 0x0F); +} +struct device_attribute dev_attr_cpld2_version = __ATTR(version, 0444, cpld2_version_show , NULL); + +static ssize_t cpld2_getreg_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + uint8_t data; + fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, fpga_data->cpld2_read_addr, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t cpld2_getreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + // CPLD register is one byte + uint32_t addr; + char *last; + addr = (uint8_t)strtoul(buf, &last, 16); + if (addr == 0 && buf == last) { + return -EINVAL; + } + fpga_data->cpld2_read_addr = addr; + return size; +} +struct device_attribute dev_attr_cpld2_getreg = __ATTR(getreg, 0600, cpld2_getreg_show, cpld2_getreg_store); + +static ssize_t cpld2_scratch_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + __u8 data; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x01, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) + return err; + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t cpld2_scratch_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + // CPLD register is one byte + __u8 data; + char *last; + int err; + + data = (uint8_t)strtoul(buf, &last, 16); + if (data == 0 && buf == last) { + return -EINVAL; + } + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, 0x01, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) + return err; + return size; +} +struct device_attribute dev_attr_cpld2_scratch = __ATTR(scratch, 0600, cpld2_scratch_show, cpld2_scratch_store); + +static ssize_t cpld2_setreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + uint8_t addr, value; + char *tok; + char clone[size]; + char *pclone = clone; + int err; + char *last; + + strcpy(clone, buf); + + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + return -EINVAL; + } + addr = (uint8_t)strtoul(tok, &last, 16); + if (addr == 0 && tok == last) { + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if (tok == NULL) { + return -EINVAL; + } + value = (uint8_t)strtoul(tok, &last, 16); + if (value == 0 && tok == last) { + return -EINVAL; + } + + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, addr, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&value); + if (err < 0) + return err; + + return size; +} +struct device_attribute dev_attr_cpld2_setreg = __ATTR(setreg, 0200, NULL, cpld2_setreg_store); + +static struct attribute *cpld2_attrs[] = { + &dev_attr_cpld2_version.attr, + &dev_attr_cpld2_getreg.attr, + &dev_attr_cpld2_scratch.attr, + &dev_attr_cpld2_setreg.attr, + NULL, +}; + +static struct attribute_group cpld2_attr_grp = { + .attrs = cpld2_attrs, +}; + +/* QSFP/SFP+ attributes */ +static ssize_t qsfp_modirq_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_IRQ) & 1U); +} +DEVICE_ATTR_RO(qsfp_modirq); + +static ssize_t qsfp_modprs_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_PRESENT) & 1U); +} +DEVICE_ATTR_RO(qsfp_modprs); + +static ssize_t sfp_txfault_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_TXFAULT) & 1U); +} +DEVICE_ATTR_RO(sfp_txfault); + +static ssize_t sfp_rxlos_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_RXLOS) & 1U); +} +DEVICE_ATTR_RO(sfp_rxlos); + +static ssize_t sfp_modabs_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_MODABS) & 1U); +} +DEVICE_ATTR_RO(sfp_modabs); + +static ssize_t qsfp_lpmode_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> CTRL_LPMOD) & 1U); +} +static ssize_t qsfp_lpmode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + ssize_t status; + long value; + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtol(buf, 0, &value); + if (status == 0) { + // if value is 0, disable the lpmode + data = ioread32(fpga_dev.data_base_addr + REGISTER); + if (!value) + data = data & ~( (u32)0x1 << CTRL_LPMOD); + else + data = data | ((u32)0x1 << CTRL_LPMOD); + iowrite32(data, fpga_dev.data_base_addr + REGISTER); + status = size; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(qsfp_lpmode); + +static ssize_t qsfp_reset_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> CTRL_RST) & 1U); +} + +static ssize_t qsfp_reset_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + ssize_t status; + long value; + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtol(buf, 0, &value); + if (status == 0) { + // if value is 0, reset signal is low + data = ioread32(fpga_dev.data_base_addr + REGISTER); + if (!value) + data = data & ~( (u32)0x1 << CTRL_RST); + else + data = data | ((u32)0x1 << CTRL_RST); + iowrite32(data, fpga_dev.data_base_addr + REGISTER); + status = size; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(qsfp_reset); + +static ssize_t sfp_txdisable_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr + REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> CTRL_TXDIS) & 1U); +} +static ssize_t sfp_txdisable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + ssize_t status; + long value; + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtol(buf, 0, &value); + if (status == 0) { + // check if value is 0 clear + data = ioread32(fpga_dev.data_base_addr + REGISTER); + if (!value) + data = data & ~( (u32)0x1 << CTRL_TXDIS); + else + data = data | ((u32)0x1 << CTRL_TXDIS); + iowrite32(data, fpga_dev.data_base_addr + REGISTER); + status = size; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(sfp_txdisable); + +static struct attribute *sff_attrs[] = { + &dev_attr_qsfp_modirq.attr, + &dev_attr_qsfp_modprs.attr, + &dev_attr_qsfp_lpmode.attr, + &dev_attr_qsfp_reset.attr, + &dev_attr_sfp_txfault.attr, + &dev_attr_sfp_rxlos.attr, + &dev_attr_sfp_modabs.attr, + &dev_attr_sfp_txdisable.attr, + NULL, +}; + +static struct attribute_group sff_attr_grp = { + .attrs = sff_attrs, +}; + +static const struct attribute_group *sff_attr_grps[] = { + &sff_attr_grp, + NULL +}; + + +static ssize_t port_led_mode_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // value can be "nomal", "test" + __u8 led_mode_1, led_mode_2; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_1); + if (err < 0) + return err; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_2); + if (err < 0) + return err; + return sprintf(buf, "%s %s\n", + led_mode_1 ? "test" : "normal", + led_mode_2 ? "test" : "normal"); +} +static ssize_t port_led_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + int status; + __u8 led_mode_1; + if (sysfs_streq(buf, "test")) { + led_mode_1 = 0x01; + } else if (sysfs_streq(buf, "normal")) { + led_mode_1 = 0x00; + } else { + return -EINVAL; + } + status = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, + I2C_SMBUS_WRITE, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_1); + status = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, + I2C_SMBUS_WRITE, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_1); + return size; +} +DEVICE_ATTR_RW(port_led_mode); + +// Only work when port_led_mode set to 1 +static ssize_t port_led_color_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // value can be R/G/B/C/M/Y/W/OFF + __u8 led_color1, led_color2; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_color1); + if (err < 0) + return err; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_color2); + if (err < 0) + return err; + return sprintf(buf, "%s %s\n", + led_color1 == 0x07 ? "off" : led_color1 == 0x06 ? "green" : led_color1 == 0x05 ? "red" : led_color1 == 0x04 ? + "yellow" : led_color1 == 0x03 ? "blue" : led_color1 == 0x02 ? "cyan" : led_color1 == 0x01 ? "magenta" : "white", + led_color1 == 0x07 ? "off" : led_color1 == 0x06 ? "green" : led_color1 == 0x05 ? "red" : led_color1 == 0x04 ? + "yellow" : led_color1 == 0x03 ? "blue" : led_color1 == 0x02 ? "cyan" : led_color1 == 0x01 ? "magenta" : "white"); +} + +static ssize_t port_led_color_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + int status; + __u8 led_color; + if (sysfs_streq(buf, "off")) { + led_color = 0x07; + } else if (sysfs_streq(buf, "green")) { + led_color = 0x06; + } else if (sysfs_streq(buf, "red")) { + led_color = 0x05; + } else if (sysfs_streq(buf, "yellow")) { + led_color = 0x04; + } else if (sysfs_streq(buf, "blue")) { + led_color = 0x03; + } else if (sysfs_streq(buf, "cyan")) { + led_color = 0x02; + } else if (sysfs_streq(buf, "magenta")) { + led_color = 0x01; + } else if (sysfs_streq(buf, "white")) { + led_color = 0x00; + } else { + status = -EINVAL; + return status; + } + status = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, + I2C_SMBUS_WRITE, 0x0A, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_color); + status = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, + I2C_SMBUS_WRITE, 0x0A, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_color); + return size; +} +DEVICE_ATTR_RW(port_led_color); + +static struct attribute *sff_led_test[] = { + &dev_attr_port_led_mode.attr, + &dev_attr_port_led_color.attr, + NULL, +}; + +static struct attribute_group sff_led_test_grp = { + .attrs = sff_led_test, +}; + +static struct device * silverstone_sff_init(int portid) { + struct sff_device_data *new_data; + struct device *new_device; + + new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); + if (!new_data) { + printk(KERN_ALERT "Cannot alloc sff device data @port%d", portid); + return NULL; + } + /* The QSFP port ID start from 1 */ + new_data->portid = portid + 1; + new_data->port_type = fpga_i2c_bus_dev[portid].port_type; + new_device = device_create_with_groups(fpgafwclass, sff_dev, MKDEV(0, 0), new_data, sff_attr_grps, "%s", fpga_i2c_bus_dev[portid].calling_name); + if (IS_ERR(new_device)) { + printk(KERN_ALERT "Cannot create sff device @port%d", portid); + kfree(new_data); + return NULL; + } + return new_device; +} + +static int i2c_wait_ack(struct i2c_adapter *a, unsigned long timeout, int writing) { + int error = 0; + int Status; + + struct i2c_dev_data *new_data = i2c_get_adapdata(a); + void __iomem *pci_bar = fpga_dev.data_base_addr; + + unsigned int REG_FDR0; + unsigned int REG_CR0; + unsigned int REG_SR0; + unsigned int REG_DR0; + unsigned int REG_ID0; + + unsigned int master_bus = new_data->pca9548.master_bus; + + if (master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL) { + error = -EINVAL; + return error; + } + + REG_FDR0 = I2C_MASTER_FREQ_1 + (master_bus - 1) * 0x0100; + REG_CR0 = I2C_MASTER_CTRL_1 + (master_bus - 1) * 0x0100; + REG_SR0 = I2C_MASTER_STATUS_1 + (master_bus - 1) * 0x0100; + REG_DR0 = I2C_MASTER_DATA_1 + (master_bus - 1) * 0x0100; + REG_ID0 = I2C_MASTER_PORT_ID_1 + (master_bus - 1) * 0x0100; + + check(pci_bar + REG_SR0); + check(pci_bar + REG_CR0); + + timeout = jiffies + msecs_to_jiffies(timeout); + while (1) { + Status = ioread8(pci_bar + REG_SR0); + if (jiffies > timeout) { + info("Status %2.2X", Status); + info("Error Timeout"); + error = -ETIMEDOUT; + break; + } + + + if (Status & (1 << I2C_SR_BIT_MIF)) { + break; + } + + if (writing == 0 && (Status & (1 << I2C_SR_BIT_MCF))) { + break; + } + } + Status = ioread8(pci_bar + REG_SR0); + iowrite8(0, pci_bar + REG_SR0); + + if (error < 0) { + info("Status %2.2X", Status); + return error; + } + + if (!(Status & (1 << I2C_SR_BIT_MCF))) { + info("Error Unfinish"); + return -EIO; + } + + if (Status & (1 << I2C_SR_BIT_MAL)) { + info("Error MAL"); + return -EAGAIN; + } + + if (Status & (1 << I2C_SR_BIT_RXAK)) { + info( "SL No Acknowlege"); + if (writing) { + info("Error No Acknowlege"); + iowrite8(1 << I2C_CR_BIT_MEN, pci_bar + REG_CR0); + return -ENXIO; + } + } else { + info( "SL Acknowlege"); + } + + return 0; +} + +static int smbus_access(struct i2c_adapter *adapter, u16 addr, + unsigned short flags, char rw, u8 cmd, + int size, union i2c_smbus_data *data) +{ + int error = 0; + int cnt = 0; + int bid = 0; + struct i2c_dev_data *dev_data; + void __iomem *pci_bar; + unsigned int portid, master_bus; + unsigned int REG_FDR0; + unsigned int REG_CR0; + unsigned int REG_SR0; + unsigned int REG_DR0; + unsigned int REG_ID0; + + /* Write the command register */ + dev_data = i2c_get_adapdata(adapter); + portid = dev_data->portid; + pci_bar = fpga_dev.data_base_addr; + master_bus = dev_data->pca9548.master_bus; + REG_FDR0 = I2C_MASTER_FREQ_1 + (master_bus - 1) * 0x0100; + REG_CR0 = I2C_MASTER_CTRL_1 + (master_bus - 1) * 0x0100; + REG_SR0 = I2C_MASTER_STATUS_1 + (master_bus - 1) * 0x0100; + REG_DR0 = I2C_MASTER_DATA_1 + (master_bus - 1) * 0x0100; + REG_ID0 = I2C_MASTER_PORT_ID_1 + (master_bus - 1) * 0x0100; + + if (master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL) { + error = -EINVAL; + goto Done; + } + +#ifdef DEBUG_KERN + printk(KERN_INFO "portid %2d|@ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-10s|CMD %2.2X " + , portid, addr, flags, rw, rw == 1 ? "READ " : "WRITE" + , size, size == 0 ? "QUICK" : + size == 1 ? "BYTE" : + size == 2 ? "BYTE_DATA" : + size == 3 ? "WORD_DATA" : + size == 4 ? "PROC_CALL" : + size == 5 ? "BLOCK_DATA" : "ERROR" + , cmd); +#endif + /* Map the size to what the chip understands */ + switch (size) { + case I2C_SMBUS_QUICK: + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + case I2C_SMBUS_WORD_DATA: + case I2C_SMBUS_BLOCK_DATA: + break; + default: + printk(KERN_INFO "Unsupported transaction %d\n", size); + error = -EOPNOTSUPP; + goto Done; + } + + iowrite8(portid, pci_bar + REG_ID0); + + ////[S][ADDR/R] + //Clear status register + iowrite8(0, pci_bar + REG_SR0); + iowrite8(1 << I2C_CR_BIT_MIEN | 1 << I2C_CR_BIT_MTX | 1 << I2C_CR_BIT_MSTA , pci_bar + REG_CR0); + SET_REG_BIT_H(pci_bar + REG_CR0, I2C_CR_BIT_MEN); + + if (rw == I2C_SMBUS_READ && + (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE)) { + // sent device address with Read mode + iowrite8(addr << 1 | 0x01, pci_bar + REG_DR0); + } else { + // sent device address with Write mode + iowrite8(addr << 1 | 0x00, pci_bar + REG_DR0); + } + + + + info( "MS Start"); + + //// Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + info( "get error %d", error); + goto Done; + } + + //// [CMD]{A} + if (size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA || + (size == I2C_SMBUS_BYTE && rw == I2C_SMBUS_WRITE)) { + + //sent command code to data register + iowrite8(cmd, pci_bar + REG_DR0); + info( "MS Send CMD 0x%2.2X", cmd); + + // Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + info( "get error %d", error); + goto Done; + } + } + + switch (size) { + case I2C_SMBUS_BYTE_DATA: + cnt = 1; break; + case I2C_SMBUS_WORD_DATA: + cnt = 2; break; + case I2C_SMBUS_BLOCK_DATA: + // in block data mode keep number of byte in block[0] + cnt = data->block[0]; + break; + default: + cnt = 0; break; + } + + // [CNT] used only bloack data write + if (size == I2C_SMBUS_BLOCK_DATA && rw == I2C_SMBUS_WRITE) { + + iowrite8(cnt, pci_bar + REG_DR0); + info( "MS Send CNT 0x%2.2X", cnt); + + // Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + info( "get error %d", error); + goto Done; + } + } + + // [DATA]{A} + if ( rw == I2C_SMBUS_WRITE && ( + size == I2C_SMBUS_BYTE || + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA + )) { + int bid = 0; + info( "MS prepare to sent [%d bytes]", cnt); + if (size == I2C_SMBUS_BLOCK_DATA ) { + bid = 1; // block[0] is cnt; + cnt += 1; // offset from block[0] + } + for (; bid < cnt; bid++) { + + iowrite8(data->block[bid], pci_bar + REG_DR0); + info( " Data > %2.2X", data->block[bid]); + // Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + goto Done; + } + } + } + + //REPEATE START + if ( rw == I2C_SMBUS_READ && ( + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA + )) { + info( "MS Repeated Start"); + + SET_REG_BIT_L(pci_bar + REG_CR0, I2C_CR_BIT_MEN); + iowrite8(1 << I2C_CR_BIT_MIEN | + 1 << I2C_CR_BIT_MTX | + 1 << I2C_CR_BIT_MSTA | + 1 << I2C_CR_BIT_RSTA , pci_bar + REG_CR0); + SET_REG_BIT_H(pci_bar + REG_CR0, I2C_CR_BIT_MEN); + + // sent Address with Read mode + iowrite8( addr << 1 | 0x1 , pci_bar + REG_DR0); + + // Wait {A} + error = i2c_wait_ack(adapter, 12, 1); + if (error < 0) { + goto Done; + } + + } + + if ( rw == I2C_SMBUS_READ && ( + size == I2C_SMBUS_BYTE || + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA + )) { + + switch (size) { + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + cnt = 1; break; + case I2C_SMBUS_WORD_DATA: + cnt = 2; break; + case I2C_SMBUS_BLOCK_DATA: + //will be changed after recived first data + cnt = 3; break; + default: + cnt = 0; break; + } + + info( "MS Receive"); + + //set to Receive mode + iowrite8(1 << I2C_CR_BIT_MEN | + 1 << I2C_CR_BIT_MIEN | + 1 << I2C_CR_BIT_MSTA , pci_bar + REG_CR0); + + for (bid = -1; bid < cnt; bid++) { + + // Wait {A} + error = i2c_wait_ack(adapter, 12, 0); + if (error < 0) { + goto Done; + } + + if (bid == cnt - 2) { + info( "SET NAK"); + SET_REG_BIT_H(pci_bar + REG_CR0, I2C_CR_BIT_TXAK); + } + + if (bid < 0) { + ioread8(pci_bar + REG_DR0); + info( "READ Dummy Byte" ); + } else { + + if (bid == cnt - 1) { + info ( "SET STOP in read loop"); + SET_REG_BIT_L(pci_bar + REG_CR0, I2C_CR_BIT_MSTA); + } + data->block[bid] = ioread8(pci_bar + REG_DR0); + + info( "DATA IN [%d] %2.2X", bid, data->block[bid]); + + if (size == I2C_SMBUS_BLOCK_DATA && bid == 0) { + cnt = data->block[0] + 1; + } + } + } + } + + //[P] + SET_REG_BIT_L(pci_bar + REG_CR0, I2C_CR_BIT_MSTA); + i2c_wait_ack(adapter, 12, 0); + info( "MS STOP"); + +Done: + iowrite8(1 << I2C_CR_BIT_MEN, pci_bar + REG_CR0); + check(pci_bar + REG_CR0); + check(pci_bar + REG_SR0); +#ifdef DEBUG_KERN + printk(KERN_INFO "END --- Error code %d", error); +#endif + + return error; +} + +/** + * Wrapper of smbus_access access with PCA9548 I2C switch management. + * This function set PCA9548 switches to the proper slave channel. + * Only one channel among switches chip is selected during communication time. + * + * Note: If the bus does not have any PCA9548 on it, the switch_addr must be + * set to 0xFF, it will use normal smbus_access function. + */ +static int fpga_i2c_access(struct i2c_adapter *adapter, u16 addr, + unsigned short flags, char rw, u8 cmd, + int size, union i2c_smbus_data *data) +{ + int error = 0; + struct i2c_dev_data *dev_data; + unsigned char master_bus; + unsigned char switch_addr; + unsigned char channel; + uint16_t prev_port = 0; + unsigned char prev_switch; + unsigned char prev_ch; + int retry; + + dev_data = i2c_get_adapdata(adapter); + master_bus = dev_data->pca9548.master_bus; + switch_addr = dev_data->pca9548.switch_addr; + channel = dev_data->pca9548.channel; + + // Acquire the master resource. + mutex_lock(&fpga_i2c_master_locks[master_bus - 1]); + prev_port = fpga_i2c_lasted_access_port[master_bus - 1]; + prev_switch = (unsigned char)(prev_port >> 8) & 0xFF; + prev_ch = (unsigned char)(prev_port & 0xFF); + + if (switch_addr != 0xFF) { + + // Check lasted access switch address on a master + if ( prev_switch != switch_addr && prev_switch != 0 ) { + // reset prev_port PCA9548 chip + retry = 3; + while(retry--){ + error = smbus_access(adapter, (u16)(prev_switch), flags, I2C_SMBUS_WRITE, 0x00, I2C_SMBUS_BYTE, NULL); + if(error >= 0){ + break; + }else{ + dev_dbg(&adapter->dev,"Failed to deselect ch %d of 0x%x, CODE %d\n", prev_ch, prev_switch, error); + } + } + if(retry == 0) + goto release_unlock; + // set PCA9548 to current channel + retry = 3; + while(retry--){ + error = smbus_access(adapter, switch_addr, flags, I2C_SMBUS_WRITE, 1 << channel, I2C_SMBUS_BYTE, NULL); + if(error >= 0){ + break; + }else{ + dev_dbg(&adapter->dev,"Failed to select ch %d of 0x%x, CODE %d\n", channel, switch_addr, error); + } + } + if(retry == 0) + goto release_unlock; + // update lasted port + fpga_i2c_lasted_access_port[master_bus - 1] = switch_addr << 8 | channel; + + } else { + // check if channel is also changes + if ( prev_ch != channel || prev_switch == 0 ) { + // set new PCA9548 at switch_addr to current + retry = 3; + while(retry--){ + error = smbus_access(adapter, switch_addr, flags, I2C_SMBUS_WRITE, 1 << channel, I2C_SMBUS_BYTE, NULL); + if(error >= 0){ + break; + }else{ + dev_dbg(&adapter->dev,"Failed to select ch %d of 0x%x, CODE %d\n", channel, switch_addr, error); + } + } + if(retry == 0) + goto release_unlock; + // update lasted port + fpga_i2c_lasted_access_port[master_bus - 1] = switch_addr << 8 | channel; + } + } + } + + // Do SMBus communication + error = smbus_access(adapter, addr, flags, rw, cmd, size, data); + if(error < 0){ + dev_dbg( &adapter->dev,"smbus_xfer failed (%d) @ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-10s|CMD %2.2X " + , error, addr, flags, rw, rw == 1 ? "READ " : "WRITE" + , size, size == 0 ? "QUICK" : + size == 1 ? "BYTE" : + size == 2 ? "BYTE_DATA" : + size == 3 ? "WORD_DATA" : + size == 4 ? "PROC_CALL" : + size == 5 ? "BLOCK_DATA" : + size == 8 ? "I2C_BLOCK_DATA" : "ERROR" + , cmd); + } + +release_unlock: + mutex_unlock(&fpga_i2c_master_locks[master_bus - 1]); + dev_dbg(&adapter->dev,"switch ch %d of 0x%x -> ch %d of 0x%x\n", prev_ch, prev_switch, channel, switch_addr); + return error; +} + + + +/** + * A callback function show available smbus functions. + */ +static u32 fpga_i2c_func(struct i2c_adapter *a) +{ + return I2C_FUNC_SMBUS_QUICK | + I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_BLOCK_DATA; +} + +static const struct i2c_algorithm silverstone_i2c_algorithm = { + .smbus_xfer = fpga_i2c_access, + .functionality = fpga_i2c_func, +}; + +/** + * Create virtual I2C bus adapter for switch devices + * @param pdev platform device pointer + * @param portid virtual i2c port id for switch device mapping + * @param bus_number_offset bus offset for virtual i2c adapter in system + * @return i2c adapter. + * + * When bus_number_offset is -1, created adapter with dynamic bus number. + * Otherwise create adapter at i2c bus = bus_number_offset + portid. + */ +static struct i2c_adapter * silverstone_i2c_init(struct platform_device *pdev, int portid, int bus_number_offset) +{ + int error; + + struct i2c_adapter *new_adapter; + struct i2c_dev_data *new_data; + void __iomem *i2c_freq_base_reg; + + new_adapter = kzalloc(sizeof(*new_adapter), GFP_KERNEL); + if (!new_adapter) { + printk(KERN_ALERT "Cannot alloc i2c adapter for %s", fpga_i2c_bus_dev[portid].calling_name); + return NULL; + } + + new_adapter->owner = THIS_MODULE; + new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + new_adapter->algo = &silverstone_i2c_algorithm; + /* If the bus offset is -1, use dynamic bus number */ + if (bus_number_offset == -1) { + new_adapter->nr = -1; + } else { + new_adapter->nr = bus_number_offset + portid; + } + + new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); + if (!new_data) { + printk(KERN_ALERT "Cannot alloc i2c data for %s", fpga_i2c_bus_dev[portid].calling_name); + kzfree(new_adapter); + return NULL; + } + + new_data->portid = portid; + new_data->pca9548.master_bus = fpga_i2c_bus_dev[portid].master_bus; + new_data->pca9548.switch_addr = fpga_i2c_bus_dev[portid].switch_addr; + new_data->pca9548.channel = fpga_i2c_bus_dev[portid].channel; + strcpy(new_data->pca9548.calling_name, fpga_i2c_bus_dev[portid].calling_name); + + snprintf(new_adapter->name, sizeof(new_adapter->name), + "SMBus I2C Adapter PortID: %s", new_data->pca9548.calling_name); + + i2c_freq_base_reg = fpga_dev.data_base_addr + I2C_MASTER_FREQ_1; + iowrite8(0x07, i2c_freq_base_reg + (new_data->pca9548.master_bus - 1) * 0x100); // 0x07 400kHz + i2c_set_adapdata(new_adapter, new_data); + error = i2c_add_numbered_adapter(new_adapter); + if (error < 0) { + printk(KERN_ALERT "Cannot add i2c adapter %s", new_data->pca9548.calling_name); + kzfree(new_adapter); + kzfree(new_data); + return NULL; + } + + return new_adapter; +}; + +static void silverstone_dev_release( struct device * dev) +{ + return; +} + +static struct platform_device silverstone_dev = { + .name = DRIVER_NAME, + .id = -1, + .num_resources = 0, + .resource = NULL, + .dev = { + .release = silverstone_dev_release, + } +}; + +/** + * Board info for QSFP/SFP+ eeprom. + * Note: Using OOM optoe as I2C eeprom driver. + * https://www.opencompute.org/wiki/Networking/SpecsAndDesigns#Open_Optical_Monitoring + */ +static struct i2c_board_info sff8436_eeprom_info[] = { + { I2C_BOARD_INFO("optoe1", 0x50) }, //For QSFP w/ sff8436 + { I2C_BOARD_INFO("optoe2", 0x50) }, //For SFP+ w/ sff8472 +}; + +static int silverstone_drv_probe(struct platform_device *pdev) +{ + int ret = 0; + int portid_count; + uint8_t cpld1_version, cpld2_version; + uint16_t prev_i2c_switch = 0; + struct sff_device_data *sff_data; + + /* The device class need to be instantiated before this function called */ + BUG_ON(fpgafwclass == NULL); + + fpga_data = devm_kzalloc(&pdev->dev, sizeof(struct silverstone_fpga_data), + GFP_KERNEL); + + if (!fpga_data) + return -ENOMEM; + + // Set default read address to VERSION + fpga_data->fpga_read_addr = fpga_dev.data_base_addr + FPGA_VERSION; + fpga_data->cpld1_read_addr = 0x00; + fpga_data->cpld2_read_addr = 0x00; + + mutex_init(&fpga_data->fpga_lock); + for (ret = I2C_MASTER_CH_1 ; ret <= I2C_MASTER_CH_TOTAL; ret++) { + mutex_init(&fpga_i2c_master_locks[ret - 1]); + } + + fpga = kobject_create_and_add("FPGA", &pdev->dev.kobj); + if (!fpga) { + kzfree(fpga_data); + return -ENOMEM; + } + + ret = sysfs_create_group(fpga, &fpga_attr_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create FPGA sysfs attributes\n"); + kobject_put(fpga); + kzfree(fpga_data); + return ret; + } + + cpld1 = kobject_create_and_add("CPLD1", &pdev->dev.kobj); + if (!cpld1) { + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kzfree(fpga_data); + return -ENOMEM; + } + ret = sysfs_create_group(cpld1, &cpld1_attr_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create CPLD1 sysfs attributes\n"); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kzfree(fpga_data); + return ret; + } + + cpld2 = kobject_create_and_add("CPLD2", &pdev->dev.kobj); + if (!cpld2) { + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kzfree(fpga_data); + return -ENOMEM; + } + ret = sysfs_create_group(cpld2, &cpld2_attr_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create CPLD2 sysfs attributes\n"); + kobject_put(cpld2); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kzfree(fpga_data); + return ret; + } + + sff_dev = device_create(fpgafwclass, NULL, MKDEV(0, 0), NULL, "sff_device"); + if (IS_ERR(sff_dev)) { + printk(KERN_ERR "Failed to create sff device\n"); + sysfs_remove_group(cpld2, &cpld2_attr_grp); + kobject_put(cpld2); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kzfree(fpga_data); + return PTR_ERR(sff_dev); + } + + ret = sysfs_create_group(&sff_dev->kobj, &sff_led_test_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create SFF attributes\n"); + device_destroy(fpgafwclass, MKDEV(0, 0)); + sysfs_remove_group(cpld2, &cpld2_attr_grp); + kobject_put(cpld2); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kzfree(fpga_data); + return ret; + } + + ret = sysfs_create_link(&pdev->dev.kobj, &sff_dev->kobj, "SFF"); + if (ret != 0) { + sysfs_remove_group(&sff_dev->kobj, &sff_led_test_grp); + device_destroy(fpgafwclass, MKDEV(0, 0)); + sysfs_remove_group(cpld2, &cpld2_attr_grp); + kobject_put(cpld2); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kzfree(fpga_data); + return ret; + } + + for (portid_count = 0 ; portid_count < VIRTUAL_I2C_PORT_LENGTH ; portid_count++) { + fpga_data->i2c_adapter[portid_count] = silverstone_i2c_init(pdev, portid_count, VIRTUAL_I2C_BUS_OFFSET); + } + + /* Init SFF devices */ + for (portid_count = 0; portid_count < SFF_PORT_TOTAL; portid_count++) { + struct i2c_adapter *i2c_adap = fpga_data->i2c_adapter[portid_count]; + if (i2c_adap) { + fpga_data->sff_devices[portid_count] = silverstone_sff_init(portid_count); + sff_data = dev_get_drvdata(fpga_data->sff_devices[portid_count]); + BUG_ON(sff_data == NULL); + if ( sff_data->port_type == QSFP ) { + fpga_data->sff_i2c_clients[portid_count] = i2c_new_device(i2c_adap, &sff8436_eeprom_info[0]); + } else { + fpga_data->sff_i2c_clients[portid_count] = i2c_new_device(i2c_adap, &sff8436_eeprom_info[1]); + } + sff_data = NULL; + sysfs_create_link(&fpga_data->sff_devices[portid_count]->kobj, + &fpga_data->sff_i2c_clients[portid_count]->dev.kobj, + "i2c"); + } + } + +#ifdef TEST_MODE + return 0; +#endif + fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, + I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&cpld1_version); + fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, + I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&cpld2_version); + + printk(KERN_INFO "Switch CPLD1 VERSION: %2.2x\n", cpld1_version); + printk(KERN_INFO "Switch CPLD2 VERSION: %2.2x\n", cpld2_version); + + + /* Init I2C buses that has PCA9548 switch device. */ + for (portid_count = 0; portid_count < VIRTUAL_I2C_PORT_LENGTH; portid_count++) { + + struct i2c_dev_data *dev_data; + unsigned char master_bus; + unsigned char switch_addr; + + dev_data = i2c_get_adapdata(fpga_data->i2c_adapter[portid_count]); + master_bus = dev_data->pca9548.master_bus; + switch_addr = dev_data->pca9548.switch_addr; + + if (switch_addr != 0xFF) { + + if (prev_i2c_switch != ( (master_bus << 8) | switch_addr) ) { + // Found the bus with PCA9548, trying to clear all switch in it. + smbus_access(fpga_data->i2c_adapter[portid_count], switch_addr, 0x00, I2C_SMBUS_WRITE, 0x00, I2C_SMBUS_BYTE, NULL); + prev_i2c_switch = ( master_bus << 8 ) | switch_addr; + } + } + } + return 0; +} + +static int silverstone_drv_remove(struct platform_device *pdev) +{ + int portid_count; + struct sff_device_data *rem_data; + + for (portid_count = 0; portid_count < SFF_PORT_TOTAL; portid_count++) { + sysfs_remove_link(&fpga_data->sff_devices[portid_count]->kobj, "i2c"); + i2c_unregister_device(fpga_data->sff_i2c_clients[portid_count]); + } + + for (portid_count = 0 ; portid_count < VIRTUAL_I2C_PORT_LENGTH ; portid_count++) { + if (fpga_data->i2c_adapter[portid_count] != NULL) { + info(KERN_INFO "<%x>", fpga_data->i2c_adapter[portid_count]); + i2c_del_adapter(fpga_data->i2c_adapter[portid_count]); + } + } + + for (portid_count = 0; portid_count < SFF_PORT_TOTAL; portid_count++) { + if (fpga_data->sff_devices[portid_count] != NULL) { + rem_data = dev_get_drvdata(fpga_data->sff_devices[portid_count]); + device_unregister(fpga_data->sff_devices[portid_count]); + put_device(fpga_data->sff_devices[portid_count]); + kfree(rem_data); + } + } + + sysfs_remove_group(fpga, &fpga_attr_grp); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + sysfs_remove_group(cpld2, &cpld2_attr_grp); + sysfs_remove_group(&sff_dev->kobj, &sff_led_test_grp); + kobject_put(fpga); + kobject_put(cpld1); + kobject_put(cpld2); + device_destroy(fpgafwclass, MKDEV(0, 0)); + devm_kfree(&pdev->dev, fpga_data); + return 0; +} + +#ifdef TEST_MODE +#define FPGA_PCI_BAR_NUM 2 +#else +#define FPGA_PCI_BAR_NUM 0 +#endif + +static struct platform_driver silverstone_drv = { + .probe = silverstone_drv_probe, + .remove = __exit_p(silverstone_drv_remove), + .driver = { + .name = DRIVER_NAME, + }, +}; + +static const struct pci_device_id fpga_id_table[] = { + { PCI_VDEVICE(XILINX, FPGA_PCIE_DEVICE_ID) }, + { PCI_VDEVICE(TEST, TEST_PCIE_DEVICE_ID) }, + {0, } +}; + +MODULE_DEVICE_TABLE(pci, fpga_id_table); + +static int fpga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + int err; + struct device *dev = &pdev->dev; + uint32_t fpga_version; + + if ((err = pci_enable_device(pdev))) { + dev_err(dev, "pci_enable_device probe error %d for device %s\n", + err, pci_name(pdev)); + return err; + } + + if ((err = pci_request_regions(pdev, FPGA_PCI_NAME)) < 0) { + dev_err(dev, "pci_request_regions error %d\n", err); + goto pci_disable; + } + + /* bar0: data mmio region */ + fpga_dev.data_mmio_start = pci_resource_start(pdev, FPGA_PCI_BAR_NUM); + fpga_dev.data_mmio_len = pci_resource_len(pdev, FPGA_PCI_BAR_NUM); + fpga_dev.data_base_addr = pci_iomap(pdev, FPGA_PCI_BAR_NUM, 0); + if (!fpga_dev.data_base_addr) { + dev_err(dev, "cannot iomap region of size %lu\n", + (unsigned long)fpga_dev.data_mmio_len); + goto pci_release; + } + dev_info(dev, "data_mmio iomap base = 0x%lx \n", + (unsigned long)fpga_dev.data_base_addr); + dev_info(dev, "data_mmio_start = 0x%lx data_mmio_len = %lu\n", + (unsigned long)fpga_dev.data_mmio_start, + (unsigned long)fpga_dev.data_mmio_len); + + printk(KERN_INFO "FPGA PCIe driver probe OK.\n"); + printk(KERN_INFO "FPGA ioremap registers of size %lu\n", (unsigned long)fpga_dev.data_mmio_len); + printk(KERN_INFO "FPGA Virtual BAR %d at %8.8lx - %8.8lx\n", FPGA_PCI_BAR_NUM, + (unsigned long)fpga_dev.data_base_addr, + (unsigned long)(fpga_dev.data_base_addr + fpga_dev.data_mmio_len)); + printk(KERN_INFO ""); + fpga_version = ioread32(fpga_dev.data_base_addr); + printk(KERN_INFO "FPGA VERSION : %8.8x\n", fpga_version); + fpgafw_init(); + platform_device_register(&silverstone_dev); + platform_driver_register(&silverstone_drv); + return 0; + +pci_release: + pci_release_regions(pdev); +pci_disable: + pci_disable_device(pdev); + return -EBUSY; +} + +static void fpga_pci_remove(struct pci_dev *pdev) +{ + platform_driver_unregister(&silverstone_drv); + platform_device_unregister(&silverstone_dev); + fpgafw_exit(); + pci_iounmap(pdev, fpga_dev.data_base_addr); + pci_release_regions(pdev); + pci_disable_device(pdev); + printk(KERN_INFO "FPGA PCIe driver remove OK.\n"); +}; + +static struct pci_driver pci_dev_ops = { + .name = FPGA_PCI_NAME, + .probe = fpga_pci_probe, + .remove = fpga_pci_remove, + .id_table = fpga_id_table, +}; + +enum { + READREG, + WRITEREG +}; + +struct fpga_reg_data { + uint32_t addr; + uint32_t value; +}; + +static long fpgafw_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { + int ret = 0; + struct fpga_reg_data data; + mutex_lock(&fpga_data->fpga_lock); + +#ifdef TEST_MODE + static uint32_t status_reg; +#endif + // Switch function to read and write. + switch (cmd) { + case READREG: + if (copy_from_user(&data, (void __user*)arg, sizeof(data)) != 0) { + mutex_unlock(&fpga_data->fpga_lock); + return -EFAULT; + } + data.value = ioread32(fpga_dev.data_base_addr + data.addr); + if (copy_to_user((void __user*)arg , &data, sizeof(data)) != 0) { + mutex_unlock(&fpga_data->fpga_lock); + return -EFAULT; + } +#ifdef TEST_MODE + if (data.addr == 0x1210) { + switch (status_reg) { + case 0x0000 : status_reg = 0x8000; + break; + + case 0x8080 : status_reg = 0x80C0; + break; + case 0x80C0 : status_reg = 0x80F0; + break; + case 0x80F0 : status_reg = 0x80F8; + break; + + } + iowrite32(status_reg, fpga_dev.data_base_addr + 0x1210); + } +#endif + + + break; + case WRITEREG: + if (copy_from_user(&data, (void __user*)arg, sizeof(data)) != 0) { + mutex_unlock(&fpga_data->fpga_lock); + return -EFAULT; + } + iowrite32(data.value, fpga_dev.data_base_addr + data.addr); + +#ifdef TEST_MODE + if (data.addr == 0x1204) { + status_reg = 0x8080; + iowrite32(status_reg, fpga_dev.data_base_addr + 0x1210); + } +#endif + + break; + default: + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + mutex_unlock(&fpga_data->fpga_lock); + return ret; +} + + +const struct file_operations fpgafw_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = fpgafw_unlocked_ioctl, +}; + + +static int fpgafw_init(void) { + printk(KERN_INFO "Initializing the switchboard driver\n"); + // Try to dynamically allocate a major number for the device -- more difficult but worth it + majorNumber = register_chrdev(0, DEVICE_NAME, &fpgafw_fops); + if (majorNumber < 0) { + printk(KERN_ALERT "Failed to register a major number\n"); + return majorNumber; + } + printk(KERN_INFO "Device registered correctly with major number %d\n", majorNumber); + + // Register the device class + fpgafwclass = class_create(THIS_MODULE, CLASS_NAME); + if (IS_ERR(fpgafwclass)) { // Check for error and clean up if there is + unregister_chrdev(majorNumber, DEVICE_NAME); + printk(KERN_ALERT "Failed to register device class\n"); + return PTR_ERR(fpgafwclass); + } + printk(KERN_INFO "Device class registered correctly\n"); + + // Register the device driver + fpgafwdev = device_create(fpgafwclass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME); + if (IS_ERR(fpgafwdev)) { // Clean up if there is an error + class_destroy(fpgafwclass); // Repeated code but the alternative is goto statements + unregister_chrdev(majorNumber, DEVICE_NAME); + printk(KERN_ALERT "Failed to create the FW upgrade device node\n"); + return PTR_ERR(fpgafwdev); + } + printk(KERN_INFO "FPGA fw upgrade device node created correctly\n"); + return 0; +} + +static void fpgafw_exit(void) { + device_destroy(fpgafwclass, MKDEV(majorNumber, 0)); // remove the device + class_unregister(fpgafwclass); // unregister the device class + class_destroy(fpgafwclass); // remove the device class + unregister_chrdev(majorNumber, DEVICE_NAME); // unregister the major number + printk(KERN_INFO "Goodbye!\n"); +} + +int silverstone_init(void) +{ + int rc; + rc = pci_register_driver(&pci_dev_ops); + if (rc) + return rc; + return 0; +} + +void silverstone_exit(void) +{ + pci_unregister_driver(&pci_dev_ops); +} + +module_init(silverstone_init); +module_exit(silverstone_exit); + +MODULE_AUTHOR("Celestica Inc."); +MODULE_DESCRIPTION("Celestica Silverstone platform driver"); +MODULE_VERSION(MOD_VERSION); +MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/platform_sensors.py new file mode 100755 index 000000000000..186ee6c5450e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/platform_sensors.py @@ -0,0 +1,173 @@ +#!/usr/bin/python +# +# Silverstone platform sensors. This script get the sensor data from BMC +# using ipmitool and display them in lm-sensor alike format. +# +# The following data is support: +# 1. Temperature sensors +# 2. PSUs +# 3. Fan trays + +import sys +import logging +import subprocess + +IPMI_SDR_CMD = "ipmitool sdr elist" +MAX_NUM_FANS = 7 +MAX_NUM_PSUS = 2 + + +def ipmi_sensor_dump(cmd): + ''' Execute ipmitool command return dump output + exit if any error occur. + ''' + sensor_dump = '' + try: + sensor_dump = subprocess.check_output(cmd, shell=True) + except subprocess.CalledProcessError as e: + logging.error('Error! Failed to execute: {}'.format(cmd)) + sys.exit(1) + return sensor_dump + +def get_reading_by_name(sensor_name, sdr_elist_dump): + ''' + Search for the match sensor name, return sensor + reading value and unit, return object epmtry string + if search not match. + + The output of sensor dump: + TEMP_FAN_U52 | 00h | ok | 7.1 | 31 degrees C + TEMP_FAN_U17 | 01h | ok | 7.1 | 27 degrees C + TEMP_SW_U52 | 02h | ok | 7.1 | 30 degrees C + Fan2_Status | 07h | ok | 29.2 | Present + Fan2_Front | 0Eh | ok | 29.2 | 12000 RPM + Fan2_Rear | 46h | ok | 29.2 | 14700 RPM + PSU2_Status | 39h | ok | 10.2 | Presence detected + PSU2_Fan | 3Dh | ok | 10.2 | 16000 RPM + PSU2_VIn | 3Ah | ok | 10.2 | 234.30 Volts + PSU2_CIn | 3Bh | ok | 10.2 | 0.80 Amps + ''' + found = '' + + for line in sdr_elist_dump.split("\n"): + if sensor_name in line: + found = line.strip() + break + + if not found: + logging.error('Cannot find sensor name:' + sensor_name) + + else: + try: + found = found.split('|')[4] + except IndexError: + logging.error('Cannot get sensor data of:' + sensor_name) + + logging.basicConfig(level=logging.DEBUG) + return found + + +def read_temperature_sensors(ipmi_sdr_elist): + + sensor_list = [ + ('TEMP_FAN_U52', 'Fan Tray Middle Temp'), + ('TEMP_FAN_U17', 'Fan Tray Right Temp'), + ('TEMP_SW_U52', 'Switchboard Left Inlet Temp'), + ('TEMP_SW_U16', 'Switchboard Right Inlet Temp'), + ('TEMP_BB_U3', 'Baseboard Temp'), + ('TEMP_CPU', 'CPU Internal Temp'), + ('TEMP_SW_Internal', 'ASIC Internal Temp'), + ('SW_U04_Temp', 'IR3595 Chip Left Temp'), + ('SW_U14_Temp', 'IR3595 Chip Right Temp'), + ('SW_U4403_Temp', 'IR3584 Chip Temp'), + ] + + output = '' + sensor_format = '{0:{width}}{1}\n' + # Find max length of sensor calling name + max_name_width = max(len(sensor[1]) for sensor in sensor_list) + + output += "Temperature Sensors\n" + output += "Adapter: IPMI adapter\n" + for sensor in sensor_list: + reading = get_reading_by_name(sensor[0],ipmi_sdr_elist) + output += sensor_format.format('{}:'.format(sensor[1]), + reading, + width=str(max_name_width+1)) + output += '\n' + return output + + +def read_fan_sensors(num_fans, ipmi_sdr_elist): + + sensor_list = [ + ('Fan{}_Status', 'Status'), + ('Fan{}_Front', 'Fan {} front'), + ('Fan{}_Rear', 'Fan {} rear'), + ] + + output = '' + sensor_format = '{0:{width}}{1}\n' + # Find max length of sensor calling name + max_name_width = max(len(sensor[1]) for sensor in sensor_list) + + output += "Fan Trays\n" + output += "Adapter: IPMI adapter\n" + for fan_num in range(1, num_fans+1): + for sensor in sensor_list: + ipmi_sensor_name = sensor[0].format(fan_num) + display_sensor_name = sensor[1].format(fan_num) + reading = get_reading_by_name(ipmi_sensor_name, ipmi_sdr_elist) + output += sensor_format.format('{}:'.format(display_sensor_name), + reading, + width=str(max_name_width+1)) + output += '\n' + return output + + +def read_psu_sensors(num_psus, ipmi_sdr_elist): + + sensor_list = [ + ('PSU{}_Status', 'PSU {} Status'), + ('PSU{}_Fan', 'PSU {} Fan'), + ('PSU{}_VIn', 'PSU {} Input Voltag'), + ('PSU{}_CIn', 'PSU {} Input Current'), + ('PSU{}_PIn', 'PSU {} Input Power'), + ('PSU{}_Temp1', 'PSU {} Temp1'), + ('PSU{}_Temp2', 'PSU {} Temp2'), + ('PSU{}_VOut', 'PSU {} Output Voltag'), + ('PSU{}_COut', 'PSU {} Output Current'), + ('PSU{}_POut', 'PSU {} Output Power'), + ] + + output = '' + sensor_format = '{0:{width}}{1}\n' + # Find max length of sensor calling name + max_name_width = max(len(sensor[1]) for sensor in sensor_list) + + output += "PSU\n" + output += "Adapter: IPMI adapter\n" + for psu_num in range(1, num_psus+1): + for sensor in sensor_list: + ipmi_sensor_name = sensor[0].format(psu_num) + display_sensor_name = sensor[1].format(psu_num) + reading = get_reading_by_name(ipmi_sensor_name, ipmi_sdr_elist) + output += sensor_format.format('{}:'.format(display_sensor_name), + reading, + width=str(max_name_width+1)) + output += '\n' + return output + + +def main(): + output_string = '' + + ipmi_sdr_elist = ipmi_sensor_dump(IPMI_SDR_CMD) + output_string += read_temperature_sensors(ipmi_sdr_elist) + output_string += read_psu_sensors(MAX_NUM_PSUS, ipmi_sdr_elist) + output_string += read_fan_sensors(MAX_NUM_FANS, ipmi_sdr_elist) + print(output_string) + + +if __name__ == '__main__': + main() diff --git a/dockers/docker-platform-monitor/base_image_files/sensors b/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/sensors similarity index 74% rename from dockers/docker-platform-monitor/base_image_files/sensors rename to platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/sensors index 23a12034f071..405d92c2b3cc 100755 --- a/dockers/docker-platform-monitor/base_image_files/sensors +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/sensors @@ -8,3 +8,4 @@ if [ -t 1 ] ; then fi docker exec -$DOCKER_EXEC_FLAGS pmon sensors "$@" +docker exec -$DOCKER_EXEC_FLAGS pmon platform_sensors.py "$@" diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/setup.py b/platform/broadcom/sonic-platform-modules-cel/silverstone/setup.py new file mode 100644 index 000000000000..20a2b6d1063a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/setup.py @@ -0,0 +1,34 @@ +from setuptools import setup + +DEVICE_NAME = 'celestica' +HW_SKU = 'x86_64-cel_silverstone-r0' + +setup( + name='sonic-platform', + version='1.0', + description='SONiC platform API implementation on Celestica Platforms', + license='Apache 2.0', + author='SONiC Team', + author_email='linuxnetdev@microsoft.com', + url='https://github.com/Azure/sonic-buildimage', + maintainer='Wirut Getbamrung', + maintainer_email='wgetbumr@celestica.com', + packages=[ + 'sonic_platform', + ], + package_dir={ + 'sonic_platform': '../../../../device/{}/{}/sonic_platform'.format(DEVICE_NAME, HW_SKU)}, + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Plugins', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 2.7', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform PLATFORM', +) diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/systemd/platform-modules-silverstone.service b/platform/broadcom/sonic-platform-modules-cel/silverstone/systemd/platform-modules-silverstone.service new file mode 100644 index 000000000000..907764153a27 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/systemd/platform-modules-silverstone.service @@ -0,0 +1,13 @@ +[Unit] +Description=Celestica Silverstone platform modules +After=local-fs.target +Before=pmon.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-silverstone start +ExecStop=-/etc/init.d/platform-modules-silverstone stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/afulnx_64 b/platform/broadcom/sonic-platform-modules-cel/tools/afulnx_64 new file mode 100755 index 000000000000..c32823393c08 Binary files /dev/null and b/platform/broadcom/sonic-platform-modules-cel/tools/afulnx_64 differ 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 963c2c725f74..7c258cdfeab7 100644 --- a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c +++ b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c @@ -43,6 +43,7 @@ #define IOREGION_LENGTH 0x4 #define SMF_ADDR_REG_OFFSET 0 #define SMF_READ_DATA_REG_OFFSET 2 +#define SMF_WRITE_DATA_REG_OFFSET 3 #define SMF_REG_ADDR 0x200 #define SMF_POR_SRC_REG 0x209 #define SMF_RST_SRC_REG 0x20A @@ -170,6 +171,8 @@ #define EEPROM_LABEL_REV_SIZE 3 #define EEPROM_PPID_SIZE 28 +/* Mailbox PowerOn Reason */ +#define TRACK_POWERON_REASON 0x05FF unsigned long *mmio; @@ -461,6 +464,18 @@ struct smf_sio_data { enum kinds kind; }; +static int smf_write_reg(struct smf_data *data, u16 reg, u16 dev_data) +{ + int res = 0; + + mutex_lock(&data->lock); + outb_p(reg>> 8, data->addr + SMF_ADDR_REG_OFFSET); + outb_p(reg & 0xff, data->addr + SMF_ADDR_REG_OFFSET + 1); + outb_p(dev_data & 0xff, data->addr + SMF_WRITE_DATA_REG_OFFSET); + mutex_unlock(&data->lock); + + return res; +} static int smf_read_reg(struct smf_data *data, u16 reg) { @@ -552,6 +567,40 @@ static ssize_t show_power_on_reason(struct device *dev, return sprintf(buf, "%x\n", ret); } +/* SMF Mailbox Power ON Reason */ +static ssize_t set_mb_poweron_reason(struct device *dev, + struct device_attribute *devattr, const char *buf, size_t count) +{ + int err = 0; + unsigned int dev_data = 0; + struct smf_data *data = dev_get_drvdata(dev); + + err = kstrtouint(buf, 16, &dev_data); + if (err) + return err; + + err = smf_write_reg(data, TRACK_POWERON_REASON, dev_data); + + if(err < 0) + return err; + + return count; +} + +static ssize_t show_mb_poweron_reason(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + unsigned int ret = 0; + struct smf_data *data = dev_get_drvdata(dev); + + ret = smf_read_reg(data, TRACK_POWERON_REASON); + + if(ret < 0) + return ret; + + return sprintf(buf, "0x%x\n", ret); +} + /* FANIN ATTR */ static ssize_t show_fan_label(struct device *dev, struct device_attribute *attr, char *buf) @@ -1981,11 +2030,16 @@ static SENSOR_DEVICE_ATTR(smf_reset_reason, S_IRUGO, show_reset_reason, NULL, 1) static SENSOR_DEVICE_ATTR(smf_poweron_reason, S_IRUGO, show_power_on_reason, NULL, 1); +/* Mailbox Power tracking Reason */ +static SENSOR_DEVICE_ATTR(mb_poweron_reason, S_IRUGO|S_IWUSR, + show_mb_poweron_reason, set_mb_poweron_reason, 0); + static struct attribute *smf_dell_attrs[] = { &sensor_dev_attr_smf_version.dev_attr.attr, &sensor_dev_attr_smf_firmware_ver.dev_attr.attr, &sensor_dev_attr_smf_reset_reason.dev_attr.attr, &sensor_dev_attr_smf_poweron_reason.dev_attr.attr, + &sensor_dev_attr_mb_poweron_reason.dev_attr.attr, &sensor_dev_attr_fan_tray_presence.dev_attr.attr, &sensor_dev_attr_fan1_airflow.dev_attr.attr, &sensor_dev_attr_fan3_airflow.dev_attr.attr, diff --git a/platform/broadcom/sonic-platform-modules-dell/common/fw-updater b/platform/broadcom/sonic-platform-modules-dell/common/fw-updater new file mode 100755 index 000000000000..6905664672ad --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/common/fw-updater @@ -0,0 +1,91 @@ +#!/usr/bin/python + +# dell staging fw updater script + +import os +import sys +import subprocess +import argparse + + +onie_boot_folder = '/mnt/onie-boot/onie/tools/bin/onie-fwpkg' +onie_fwpkg_tool = '/mnt/onie-boot/onie/tools/bin/onie-fwpkg' +ONIE_BOOT_MODE_CMD = '/mnt/onie-boot/onie/tools/bin/onie-boot-mode' +HOST_GRUB_DIR = '/host' +HOST_GRUB_CFG = HOST_GRUB_DIR + '/grub/grub.cfg' +HOST_GRUB_ENV = HOST_GRUB_DIR + '/grub/grubenv' +HOST_GRUB_BOOT_DIR = '--boot-directory=' + HOST_GRUB_DIR +HOST_PLATFORM_INFO = HOST_GRUB_DIR + '/platform' +dell_reload_tool = '/usr/bin/reboot' + + + + +def set_onie_mode(option): + """Select the ONIE boot mode, and set the next_entry to point to ONIE""" + _set_env_option('next_entry', 'ONIE') + subprocess.check_call([ONIE_BOOT_MODE_CMD, '-o', option]) + +def set_onie_fw_update_env(): + """Select the ONIE boot mode, and set the next_entry to point to ONIE""" + + if not os.path.exists(onie_boot_folder): + os.makedirs(onie_boot_folder) + + try: + subprocess.check_call(['mount','/dev/disk/by-label/ONIE-BOOT','/mnt/onie-boot']) + except: + print "onie-boot not able to mount" + +def _set_env_option(option, value): + """Set an option in the GRUB environment block. Pass None to value to + unset the option""" + if value is None: + action = 'unset' + key_value = option + else: + action = 'set' + key_value = '%s=%s' % (option, value) + + subprocess.check_call(['grub-editenv', HOST_GRUB_ENV, action, key_value]) + + +def dell_firmware_update_staging(image_name): + + try: + p = subprocess.Popen([onie_fwpkg_tool,"purge"],stdout=subprocess.PIPE,stdin=subprocess.PIPE) + p.communicate("y") + except: + print "onie-fwpkg command not found for purging old fw updates" + + try: + subprocess.check_call([onie_fwpkg_tool,"add", str(image_name)]) + except: + print "onie-fwpkg is not found to stage fw updates" + + try: + set_onie_mode("update") + except: + print "dell-image command not found" + + try: + subprocess.check_call([dell_reload_tool]) + except: + print "reload command not found" + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Dell HOST Firmware updates') + opts = parser.add_mutually_exclusive_group(required=True) + opts.add_argument('-u', '--update', nargs=1, metavar='IMAGE', + help='update specified image') + + args = parser.parse_args() + + if os.getuid() != 0: + parser.exit(127, 'ERROR: Must be root\n') + + if args.update: + set_onie_fw_update_env() + dell_firmware_update_staging(args.update[0]) + diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/control b/platform/broadcom/sonic-platform-modules-dell/debian/control index d714de5ab2ad..f32fa7244acc 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/control +++ b/platform/broadcom/sonic-platform-modules-dell/debian/control @@ -29,3 +29,8 @@ Package: platform-modules-s5232f Architecture: amd64 Depends: linux-image-4.9.0-9-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp + +Package: platform-modules-s5248f +Architecture: amd64 +Depends: linux-image-4.9.0-9-2-amd64 +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 51bed7edd95a..b577c5cd5b10 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 @@ -7,3 +7,4 @@ 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 common/platform_reboot usr/share/sonic/device/x86_64-dellemc_s5232f_c3538-r0 +common/fw-updater usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.init b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.init new file mode 100755 index 000000000000..0e02b00bc38a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.init @@ -0,0 +1,40 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup S5248f board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + + # /usr/local/bin/iom_power_on.sh + /usr/local/bin/s5248f_platform.sh init + + echo "done." + ;; + +stop) + /usr/local/bin/s5248f_platform.sh deinit + echo "done." + + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-s5248f.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install new file mode 100644 index 000000000000..7aa27d23b536 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install @@ -0,0 +1,10 @@ +s5248f/scripts/s5248f_platform.sh usr/local/bin +s5248f/scripts/check_qsfp.sh usr/local/bin +s5248f/scripts/platform_sensors.py usr/local/bin +s5248f/scripts/sensors usr/bin +s5248f/scripts/pcisysfs.py usr/bin +s5248f/scripts/qsfp_irq_enable.py usr/bin +s5248f/cfg/s5248f-modules.conf etc/modules-load.d +s5248f/systemd/platform-modules-s5248f.service etc/systemd/system +common/platform_reboot usr/share/sonic/device/x86_64-dellemc_s5248f_c3538-r0 +common/fw-updater usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.postinst b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.postinst new file mode 100644 index 000000000000..f13e2f703130 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.postinst @@ -0,0 +1,10 @@ +# postinst script for S5248f + +# Enable Dell-S5248f-platform-service +depmod -a +systemctl enable platform-modules-s5248f.service +systemctl start platform-modules-s5248f.service + + +#DEBHELPER# + diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install index b9b6abbb35e0..5d1cb6341fc7 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install @@ -12,3 +12,5 @@ s6100/scripts/platform_watchdog_disable.sh usr/local/bin s6100/scripts/sensors usr/bin s6100/systemd/platform-modules-s6100.service etc/systemd/system s6100/systemd/s6100-lpc-monitor.service etc/systemd/system +tools/flashrom/flashrom usr/local/bin/ +common/fw-updater usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install index bb3d869cf274..5c5c4cc55be2 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install @@ -11,3 +11,4 @@ z9100/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64- z9100/cfg/z9100-modules.conf etc/modules-load.d z9100/systemd/platform-modules-z9100.service etc/systemd/system z9100/systemd/z9100-lpc-monitor.service etc/systemd/system +common/fw-updater usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.init b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.init index cc83662e7746..fb0b68117972 100755 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.init +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.init @@ -22,7 +22,7 @@ start) ;; stop) - /usr/local/bin/z9100_platform.sh deinit + /usr/local/bin/z9264f_platform.sh deinit echo "done." ;; diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install index 6a2f15511d66..29e8b1df2e36 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install @@ -7,3 +7,4 @@ z9264f/scripts/qsfp_irq_enable.py usr/bin z9264f/cfg/z9264f-modules.conf etc/modules-load.d z9264f/systemd/platform-modules-z9264f.service etc/systemd/system common/platform_reboot usr/share/sonic/device/x86_64-dellemc_z9264f_c3538-r0 +common/fw-updater usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/rules b/platform/broadcom/sonic-platform-modules-dell/debian/rules index 0a30bebfa301..a7f68a21f55a 100755 --- a/platform/broadcom/sonic-platform-modules-dell/debian/rules +++ b/platform/broadcom/sonic-platform-modules-dell/debian/rules @@ -5,7 +5,7 @@ export INSTALL_MOD_DIR:=extra KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= s6000 z9100 s6100 z9264f s5232f +MODULE_DIRS:= s6000 z9100 s6100 z9264f s5232f s5248f COMMON_DIR := common %: diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/cfg/s5248f-modules.conf b/platform/broadcom/sonic-platform-modules-dell/s5248f/cfg/s5248f-modules.conf new file mode 100644 index 000000000000..94639bd3f6e5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/cfg/s5248f-modules.conf @@ -0,0 +1,19 @@ +# /etc/modules: kernel modules to load at boot time. +# +# This file contains the names of kernel modules that should be loaded +# at boot time, one per line. Lines beginning with "#" are ignored. + +i2c-i801 +i2c-isch +i2c-ismt +i2c-dev +i2c-mux +i2c-smbus + +i2c-mux-gpio +i2c-mux-pca954x + +ipmi_devintf +ipmi_si +dell_s5248f_fpga_ocores +i2c_ocores diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/modules/Makefile b/platform/broadcom/sonic-platform-modules-dell/s5248f/modules/Makefile new file mode 100644 index 000000000000..c179aa5dc931 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/modules/Makefile @@ -0,0 +1,2 @@ +obj-m := dell_s5248f_fpga_ocores.o + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/modules/dell_s5248f_fpga_ocores.c b/platform/broadcom/sonic-platform-modules-dell/s5248f/modules/dell_s5248f_fpga_ocores.c new file mode 100644 index 000000000000..b9a50c69b225 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/modules/dell_s5248f_fpga_ocores.c @@ -0,0 +1,1626 @@ +/* +* Copyright (C) 2018 Dell Inc +* +* Licensed under the GNU General Public License Version 2 +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +*/ + +/** +* @file fpga_i2ccore.c +* @brief This is a driver to interface with Linux Open Cores drivber for FPGA i2c access +* +************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include //siginfo +#include //rcu_read_lock +#include //kernel_version +#include +#include +#include +#include +#include + + +void __iomem * fpga_base_addr = NULL; +void __iomem * fpga_ctl_addr = NULL; + +#define DRIVER_NAME "fpgapci" +#define PCI_NUM_BARS 4 + +#ifdef DEBUG +# define PRINT(fmt, ...) printk(fmt, ##__VA_ARGS__) +#else +# define PRINT(fmt, ...) +#endif + +/* Maximum size of driver buffer (allocated with kalloc()). + * Needed to copy data from user to kernel space, among other + * things. */ +static const size_t BUF_SIZE = PAGE_SIZE; + +/* Device data used by this driver. */ +struct fpgapci_dev { + /* the kernel pci device data structure */ + struct pci_dev *pci_dev; + + /* upstream root node */ + struct pci_dev *upstream; + + /* kernels virtual addr. for the mapped BARs */ + void * __iomem bar[PCI_NUM_BARS]; + + /* length of each memory region. Used for error checking. */ + size_t bar_length[PCI_NUM_BARS]; + + /* Debug data */ + /* number of hw interrupts handled. */ + int num_handled_interrupts; + int num_undelivered_signals; + int pci_gen; + int pci_num_lanes; + + unsigned int irq_first; + unsigned int irq_length; + unsigned int irq_assigned; + unsigned int xcvr_intr_count; +}; + +static int use_irq = 1; +module_param(use_irq, int, 0644); +MODULE_PARM_DESC(use_irq, "Get an use_irq value from user...\n"); + +static uint32_t num_bus = 0; +module_param(num_bus, int, 0); +MODULE_PARM_DESC(num_bus, + "Number of i2c busses supported by the FPGA on this platform."); + + +/* Xilinx FPGA PCIE info: */ +/* Non-VGA unclassified device: Xilinx Corporation Device 7021*/ +/* Subsystem: Xilinx Corporation Device 0007 */ +//#define VENDOR 0x10EE +#define DEVICE 0x7021 +static phys_addr_t fpga_phys_addr; + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + + +/* struct to hold data related to the pcie device */ +struct pci_data_struct{ + struct pci_dev* dev; + unsigned long long phy_addr_bar0; + unsigned long long phy_len_bar0; + unsigned long long phy_flags_bar0; + unsigned int irq_first; + unsigned int irq_length; + unsigned int irq_assigned; + void * kvirt_addr_bar0; +}; + +/* global variable declarations */ + +/* Static function declarations */ +static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id); +static void fpgapci_remove(struct pci_dev *dev); + +static int scan_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev); +static int map_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev); +static void free_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev); + + +struct fpgalogic_i2c { + void __iomem *base; + u32 reg_shift; + u32 reg_io_width; + wait_queue_head_t wait; + struct i2c_msg *msg; + int pos; + int nmsgs; + int state; /* see STATE_ */ + int ip_clock_khz; + int bus_clock_khz; + void (*reg_set)(struct fpgalogic_i2c *i2c, int reg, u8 value); + u8 (*reg_get)(struct fpgalogic_i2c *i2c, int reg); + u32 timeout; + struct mutex lock; +}; +/* registers */ +#define FPGAI2C_REG_PRELOW 0 +#define FPGAI2C_REG_PREHIGH 1 +#define FPGAI2C_REG_CONTROL 2 +#define FPGAI2C_REG_DATA 3 +#define FPGAI2C_REG_CMD 4 /* write only */ +#define FPGAI2C_REG_STATUS 4 /* read only, same address as FPGAI2C_REG_CMD */ +#define FPGAI2C_REG_VER 5 + + + +#define FPGAI2C_REG_CTRL_IEN 0x40 +#define FPGAI2C_REG_CTRL_EN 0x80 + +#define FPGAI2C_REG_CMD_START 0x91 +#define FPGAI2C_REG_CMD_STOP 0x41 +#define FPGAI2C_REG_CMD_READ 0x21 +#define FPGAI2C_REG_CMD_WRITE 0x11 +#define FPGAI2C_REG_CMD_READ_ACK 0x21 +#define FPGAI2C_REG_CMD_READ_NACK 0x29 +#define FPGAI2C_REG_CMD_IACK 0x01 + +#define FPGAI2C_REG_STAT_IF 0x01 +#define FPGAI2C_REG_STAT_TIP 0x02 +#define FPGAI2C_REG_STAT_ARBLOST 0x20 +#define FPGAI2C_REG_STAT_BUSY 0x40 +#define FPGAI2C_REG_STAT_NACK 0x80 + +/* SR[7:0] - Status register */ +#define FPGAI2C_REG_SR_RXACK (1 << 7) /* Receive acknowledge from slave ‘1’ = No acknowledge received*/ +#define FPGAI2C_REG_SR_BUSY (1 << 6) /* Busy, I2C bus busy (as defined by start / stop bits) */ +#define FPGAI2C_REG_SR_AL (1 << 5) /* Arbitration lost - fpga i2c logic lost arbitration */ +#define FPGAI2C_REG_SR_TIP (1 << 1) /* Transfer in progress */ +#define FPGAI2C_REG_SR_IF (1 << 0) /* Interrupt flag */ + +enum { + STATE_DONE = 0, + STATE_INIT, + STATE_ADDR, + STATE_ADDR10, + STATE_START, + STATE_WRITE, + STATE_READ, + STATE_STOP, + STATE_ERROR, +}; + +#define TYPE_FPGALOGIC 0 +#define TYPE_GRLIB 1 + +/*I2C_CH1 Offset address from PCIE BAR 0*/ +#define FPGALOGIC_I2C_BASE 0x00006000 +#define FPGALOGIC_CH_OFFSET 0x10 + +#define i2c_bus_controller_numb 1 +#define I2C_PCI_MAX_BUS (16) +#define I2C_PCI_MAX_BUS_REV00 (7) +#define DELL_I2C_CLOCK_LEGACY 0 +#define DELL_I2C_CLOCK_PRESERVE (~0U) +#define I2C_PCI_BUS_NUM_5 5 +#define I2C_PCI_BUS_NUM_7 7 +#define I2C_PCI_BUS_NUM_8 8 +#define I2C_PCI_BUS_NUM_10 10 +#define I2C_PCI_BUS_NUM_12 12 +#define I2C_PCI_BUS_NUM_16 16 + +#define IRQ_LTCH_STS 0x20 +#define PRSNT_LTCH_STS 0x10 + +#define PORT_CTRL_OFFSET 0x4000 +#define PORT_STS_OFFSET 0x4004 +#define PORT_IRQ_STS_OFFSET 0x4008 +#define PORT_IRQ_EN_OFFSET 0x400C +#define MB_BRD_REV_TYPE 0x0008 +#define MB_BRD_REV_MASK 0x00f0 +#define MB_BRD_REV_00 0x0000 +#define MB_BRD_REV_01 0x0010 +#define MB_BRD_REV_02 0x0020 +#define MB_BRD_REV_03 0x0030 +#define MB_BRD_TYPE_MASK 0x000f +#define BRD_TYPE_Z9232_NON_NEBS 0x0 +#define BRD_TYPE_Z9232_NEBS 0x1 +#define BRD_TYPE_Z9264_NON_NEBS 0x2 +#define BRD_TYPE_Z9264_NEBS 0x3 +#define BRD_TYPE_S5212_NON_NEBS 0x4 +#define BRD_TYPE_S5212_NEBS 0x5 +#define BRD_TYPE_S5224_NON_NEBS 0x6 +#define BRD_TYPE_S5224_NEBS 0x7 +#define BRD_TYPE_S5248_NON_NEBS 0x8 +#define BRD_TYPE_S5248_NEBS 0x9 +#define BRD_TYPE_S5296_NON_NEBS 0xa +#define BRD_TYPE_S5296_NEBS 0xb +#define BRD_TYPE_S5232_NON_NEBS 0xc +#define BRD_TYPE_S5232_NEBS 0xd + +#define FPGA_CTL_REG_SIZE 0x6000 +#define MSI_VECTOR_MAP_MASK 0x1f +#define MSI_VECTOR_MAP1 0x58 +#define I2C_CH1_MSI_MAP_VECT_8 0x00000008 +#define I2C_CH2_MSI_MAP_VECT_9 0x00000120 +#define I2C_CH3_MSI_MAP_VECT_10 0x00002800 +#define I2C_CH4_MSI_MAP_VECT_11 0x00058000 +#define I2C_CH5_MSI_MAP_VECT_12 0x00c00000 +#define I2C_CH6_MSI_MAP_VECT_13 0x15000000 +#define MSI_VECTOR_MAP2 0x5c +#define I2C_CH7_MSI_MAP_VECT_14 0x0000000e +#define MSI_VECTOR_MAP3 0x9c +#define I2C_CH8_MSI_MAP_VECT_8 0x00800000 +#define I2C_CH8_MSI_MAP_VECT_16 0x01100000 +#define I2C_CH9_MSI_MAP_VECT_9 0x12000000 +#define I2C_CH9_MSI_MAP_VECT_17 0x24000000 +#define MSI_VECTOR_MAP4 0xa0 +#define I2C_CH10_MSI_MAP_VECT_10 0x0000000a +#define I2C_CH10_MSI_MAP_VECT_18 0x00000012 +#define I2C_CH11_MSI_MAP_VECT_11 0x00000120 +#define I2C_CH11_MSI_MAP_VECT_19 0x00000260 +#define I2C_CH12_MSI_MAP_VECT_12 0x00002800 +#define I2C_CH12_MSI_MAP_VECT_20 0x00005000 +#define I2C_CH13_MSI_MAP_VECT_13 0x00058000 +#define I2C_CH13_MSI_MAP_VECT_21 0x000a8000 +#define I2C_CH14_MSI_MAP_VECT_14 0x00c00000 +#define I2C_CH14_MSI_MAP_VECT_22 0x01600000 +#define I2C_CH15_MSI_MAP_VECT_8 0x10000000 +#define I2C_CH15_MSI_MAP_VECT_23 0x2e000000 +#define MSI_VECTOR_MAP5 0xa4 +#define I2C_CH16_MSI_MAP_VECT_9 0x00000009 +#define I2C_CH16_MSI_MAP_VECT_24 0x00000018 + +#define MSI_VECTOR_REV_00 16 +#define MSI_VECTOR_REV_01 32 + +#define FPGA_MSI_VECTOR_ID_4 4 +#define FPGA_MSI_VECTOR_ID_5 5 +#define FPGA_MSI_VECTOR_ID_8 8 +#define FPGA_MSI_VECTOR_ID_9 9 +#define FPGA_MSI_VECTOR_ID_10 10 +#define FPGA_MSI_VECTOR_ID_11 11 +#define FPGA_MSI_VECTOR_ID_12 12 +#define FPGA_MSI_VECTOR_ID_13 13 +#define FPGA_MSI_VECTOR_ID_14 14 +#define FPGA_MSI_VECTOR_ID_15 15 /*Note: this is external MSI vector id */ +#define FPGA_MSI_VECTOR_ID_16 16 +#define FPGA_MSI_VECTOR_ID_17 17 +#define FPGA_MSI_VECTOR_ID_18 18 +#define FPGA_MSI_VECTOR_ID_19 19 +#define FPGA_MSI_VECTOR_ID_20 20 +#define FPGA_MSI_VECTOR_ID_21 21 +#define FPGA_MSI_VECTOR_ID_22 22 +#define FPGA_MSI_VECTOR_ID_23 23 +#define FPGA_MSI_VECTOR_ID_24 24 + + + +static int total_i2c_pci_bus = 0; +static uint32_t board_rev_type = 0; +static struct fpgalogic_i2c fpgalogic_i2c[I2C_PCI_MAX_BUS]; +static struct i2c_adapter i2c_pci_adap[I2C_PCI_MAX_BUS]; +static struct mutex i2c_xfer_lock[I2C_PCI_MAX_BUS]; + +static void fpgai2c_reg_set_8(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + iowrite8(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void fpgai2c_reg_set_16(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + iowrite16(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void fpgai2c_reg_set_32(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + iowrite32(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void fpgai2c_reg_set_16be(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + iowrite16be(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void fpgai2c_reg_set_32be(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + iowrite32be(value, i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 fpgai2c_reg_get_8(struct fpgalogic_i2c *i2c, int reg) +{ + return ioread8(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 fpgai2c_reg_get_16(struct fpgalogic_i2c *i2c, int reg) +{ + return ioread16(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 fpgai2c_reg_get_32(struct fpgalogic_i2c *i2c, int reg) +{ + return ioread32(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 fpgai2c_reg_get_16be(struct fpgalogic_i2c *i2c, int reg) +{ + return ioread16be(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 fpgai2c_reg_get_32be(struct fpgalogic_i2c *i2c, int reg) +{ + return ioread32be(i2c->base + (reg << i2c->reg_shift)); +} + +static inline void fpgai2c_reg_set(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + i2c->reg_set(i2c, reg, value); + udelay(100); +} + +static inline u8 fpgai2c_reg_get(struct fpgalogic_i2c *i2c, int reg) +{ + udelay(100); + return i2c->reg_get(i2c, reg); +} + +static void fpgai2c_dump(struct fpgalogic_i2c *i2c) +{ + u8 tmp; + + PRINT("Logic register dump:\n"); + + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_PRELOW); + PRINT("FPGAI2C_REG_PRELOW (%d) = 0x%x\n",FPGAI2C_REG_PRELOW,tmp); + + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_PREHIGH); + PRINT("FPGAI2C_REG_PREHIGH(%d) = 0x%x\n",FPGAI2C_REG_PREHIGH,tmp); + + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_CONTROL); + PRINT("FPGAI2C_REG_CONTROL(%d) = 0x%x\n",FPGAI2C_REG_CONTROL,tmp); + + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); + PRINT("FPGAI2C_REG_DATA (%d) = 0x%x\n",FPGAI2C_REG_DATA,tmp); + + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_CMD); + PRINT("FPGAI2C_REG_CMD (%d) = 0x%x\n",FPGAI2C_REG_CMD,tmp); +} + +static void fpgai2c_stop(struct fpgalogic_i2c *i2c) +{ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); +} + +/* + * dell_get_mutex must be called prior to calling this function. + */ +static int fpgai2c_poll(struct fpgalogic_i2c *i2c) +{ + u8 stat = fpgai2c_reg_get(i2c, FPGAI2C_REG_STATUS); + struct i2c_msg *msg = i2c->msg; + u8 addr; + + /* Ready? */ + if (stat & FPGAI2C_REG_STAT_TIP) + return -EBUSY; + + if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) { + /* Stop has been sent */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + if (i2c->state == STATE_ERROR) + return -EIO; + return 0; + } + + /* Error? */ + if (stat & FPGAI2C_REG_STAT_ARBLOST) { + i2c->state = STATE_ERROR; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return -EAGAIN; + } + + if (i2c->state == STATE_INIT) { + if (stat & FPGAI2C_REG_STAT_BUSY) + return -EBUSY; + + i2c->state = STATE_ADDR; + } + + if (i2c->state == STATE_ADDR) { + /* 10 bit address? */ + if (i2c->msg->flags & I2C_M_TEN) { + addr = 0xf0 | ((i2c->msg->addr >> 7) & 0x6); + i2c->state = STATE_ADDR10; + } else { + addr = (i2c->msg->addr << 1); + i2c->state = STATE_START; + } + + /* Set read bit if necessary */ + addr |= (i2c->msg->flags & I2C_M_RD) ? 1 : 0; + + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, addr); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_START); + + return 0; + } + + /* Second part of 10 bit addressing */ + if (i2c->state == STATE_ADDR10) { + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, i2c->msg->addr & 0xff); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); + + i2c->state = STATE_START; + return 0; + } + + if (i2c->state == STATE_START || i2c->state == STATE_WRITE) { + i2c->state = (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; + + if (stat & FPGAI2C_REG_STAT_NACK) { + i2c->state = STATE_ERROR; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return -ENXIO; + } + } else { + msg->buf[i2c->pos++] = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); + } + + if (i2c->pos >= msg->len) { + i2c->nmsgs--; + i2c->msg++; + i2c->pos = 0; + msg = i2c->msg; + + if (i2c->nmsgs) { + if (!(msg->flags & I2C_M_NOSTART)) { + i2c->state = STATE_ADDR; + return 0; + } else { + i2c->state = (msg->flags & I2C_M_RD) + ? STATE_READ : STATE_WRITE; + } + } else { + i2c->state = STATE_DONE; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return 0; + } + } + + if (i2c->state == STATE_READ) { + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, i2c->pos == (msg->len - 1) ? + FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); + } else { + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, msg->buf[i2c->pos++]); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); + } + + return 0; +} + +static ssize_t get_mod_msi(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ind = 0, port_status=0, port_irq_status=0; + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(dev); + PRINT("%s:xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); + for(ind=0;ind<64;ind++) + { + port_status = ioread32(fpga_ctl_addr + PORT_STS_OFFSET + (ind*16)); + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); + } + return sprintf(buf,"0x%04x\n",fpgapci->xcvr_intr_count); +} +static DEVICE_ATTR(port_msi, S_IRUGO, get_mod_msi, NULL); + +static struct attribute *port_attrs[] = { + &dev_attr_port_msi.attr, + NULL, +}; + +static struct attribute_group port_attr_grp = { + .attrs = port_attrs, +}; + + +static irqreturn_t fpgaport_1_32_isr(int irq, void *dev) +{ + struct pci_dev *pdev = dev; + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); + int ind = 0, port_status=0, port_irq_status=0; + for(ind=0;ind<32;ind++) + { + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + if(port_irq_status&(IRQ_LTCH_STS|PRSNT_LTCH_STS)) + { + PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); + //write on clear + iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + } + } + fpgapci->xcvr_intr_count++; + PRINT("%s: xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); + sysfs_notify(&pdev->dev.kobj, NULL, "port_msi"); + return IRQ_HANDLED; +} + +static irqreturn_t fpgaport_33_64_isr(int irq, void *dev) +{ + struct pci_dev *pdev = dev; + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); + int ind = 0, port_status=0, port_irq_status=0; + for(ind=32;ind<64;ind++) + { + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + if(port_irq_status| (IRQ_LTCH_STS|PRSNT_LTCH_STS)) + { + PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); + iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + } + } + fpgapci->xcvr_intr_count++; + PRINT("%s: xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); + sysfs_notify(&pdev->dev.kobj, NULL, "port_msi"); + return IRQ_HANDLED; +} + +static void fpgai2c_process(struct fpgalogic_i2c *i2c) +{ + struct i2c_msg *msg = i2c->msg; + u8 stat = fpgai2c_reg_get(i2c, FPGAI2C_REG_STATUS); + + PRINT("fpgai2c_process in. status reg :0x%x\n", stat); + + if ((i2c->state == STATE_STOP) || (i2c->state == STATE_ERROR)) { + /* stop has been sent */ + PRINT("fpgai2c_process FPGAI2C_REG_CMD_IACK stat = 0x%x Set FPGAI2C_REG_CMD(0%x) FPGAI2C_REG_CMD_IACK = 0x%x\n" \ + ,stat, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + if(i2c->state == STATE_STOP) { + i2c->state = STATE_DONE; + } + wake_up(&i2c->wait); + return; + } + + + /* error? */ + if (stat & FPGAI2C_REG_STAT_ARBLOST) { + i2c->state = STATE_ERROR; + PRINT("fpgai2c_process FPGAI2C_REG_STAT_ARBLOST FPGAI2C_REG_CMD_STOP\n"); + fpgai2c_stop(i2c); + return; + } + + if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) { + i2c->state = + (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; + + if (stat & FPGAI2C_REG_STAT_NACK) { + i2c->state = STATE_ERROR; + fpgai2c_stop(i2c); + return; + } + } else + { + msg->buf[i2c->pos++] = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); + } + + /* end of msg? */ + if (i2c->pos == msg->len) { + i2c->nmsgs--; + i2c->msg++; + i2c->pos = 0; + msg = i2c->msg; + + if (i2c->nmsgs) { /* end? */ + /* send start? */ + if (!(msg->flags & I2C_M_NOSTART)) { + + u8 addr = (msg->addr << 1); + + if (msg->flags & I2C_M_RD) + addr |= 1; + + i2c->state = STATE_START; + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, addr); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_START); + return; + } else + { + i2c->state = (msg->flags & I2C_M_RD) + ? STATE_READ : STATE_WRITE; + } + } else { + i2c->state = STATE_STOP; + fpgai2c_stop(i2c); + return; + } + } + + if (i2c->state == STATE_READ) { + PRINT("fpgai2c_poll STATE_READ i2c->pos=%d msg->len-1 = 0x%x set FPGAI2C_REG_CMD = 0x%x\n",i2c->pos, msg->len-1, + i2c->pos == (msg->len-1) ? FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, i2c->pos == (msg->len-1) ? + FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); + } else { + PRINT("fpgai2c_process set FPGAI2C_REG_DATA(0x%x)\n",FPGAI2C_REG_DATA); + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, msg->buf[i2c->pos++]); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); + } +} + +static irqreturn_t fpgai2c_isr(int irq, void *dev_id) +{ + struct fpgalogic_i2c *i2c = dev_id; + fpgai2c_process(i2c); + + return IRQ_HANDLED; +} +void dell_get_mutex(struct fpgalogic_i2c *i2c) +{ + mutex_lock(&i2c->lock); +} + +/** + * dell_release_mutex - release mutex + */ +void dell_release_mutex(struct fpgalogic_i2c *i2c) +{ + mutex_unlock(&i2c->lock); +} + +static int fpgai2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) +{ + struct fpgalogic_i2c *i2c = i2c_get_adapdata(adap); + int ret; + unsigned long timeout = jiffies + msecs_to_jiffies(1000); + + i2c->msg = msgs; + i2c->pos = 0; + i2c->nmsgs = num; + i2c->state = (use_irq == 1) ? STATE_START : STATE_INIT; + + PRINT("i2c->msg->addr = 0x%x i2c->msg->flags = 0x%x\n",i2c->msg->addr,i2c->msg->flags); + PRINT("I2C_M_RD = 0x%x i2c->msg->addr << 1 = 0x%x\n",I2C_M_RD,i2c->msg->addr << 1); + + if (!use_irq) { + /* Handle the transfer */ + while (time_before(jiffies, timeout)) { + dell_get_mutex(i2c); + ret = fpgai2c_poll(i2c); + dell_release_mutex(i2c); + + if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) + return (i2c->state == STATE_DONE) ? num : ret; + + if (ret == 0) + timeout = jiffies + HZ; + + usleep_range(5, 15); + } + + i2c->state = STATE_ERROR; + + return -ETIMEDOUT; + + + } else { + ret = -ETIMEDOUT; + PRINT("Set FPGAI2C_REG_DATA(0%x) val = 0x%x\n",FPGAI2C_REG_DATA, + (i2c->msg->addr << 1) | ((i2c->msg->flags & I2C_M_RD) ? 1:0)); + + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, + (i2c->msg->addr << 1) | + ((i2c->msg->flags & I2C_M_RD) ? 1:0)); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_START); + + /* Interrupt mode */ + if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) || + (i2c->state == STATE_DONE), HZ)) + ret = (i2c->state == STATE_DONE) ? num : -EIO; + return ret; + } +} + +static int fpgai2c_init(struct fpgalogic_i2c *i2c) +{ + int prescale; + int diff; + u8 ctrl; + + if (i2c->reg_io_width == 0) + i2c->reg_io_width = 1; /* Set to default value */ + + if (!i2c->reg_set || !i2c->reg_get) { + bool be = 0; //1:big_endian 0:little_endian + + switch (i2c->reg_io_width) { + case 1: + i2c->reg_set = fpgai2c_reg_set_8; + i2c->reg_get = fpgai2c_reg_get_8; + break; + + case 2: + i2c->reg_set = be ? fpgai2c_reg_set_16be : fpgai2c_reg_set_16; + i2c->reg_get = be ? fpgai2c_reg_get_16be : fpgai2c_reg_get_16; + break; + + case 4: + i2c->reg_set = be ? fpgai2c_reg_set_32be : fpgai2c_reg_set_32; + i2c->reg_get = be ? fpgai2c_reg_get_32be : fpgai2c_reg_get_32; + break; + + default: + PRINT("Unsupported I/O width (%d)\n", + i2c->reg_io_width); + return -EINVAL; + } + } + + ctrl = fpgai2c_reg_get(i2c, FPGAI2C_REG_CONTROL); + + PRINT("%s(), line:%d\n", __func__, __LINE__); + PRINT("i2c->base = 0x%p\n",i2c->base); + + PRINT("ctrl = 0x%x\n",ctrl); + PRINT("set ctrl = 0x%x\n",ctrl & ~(FPGAI2C_REG_CTRL_EN|FPGAI2C_REG_CTRL_IEN)); + + /* make sure the device is disabled */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl & ~(FPGAI2C_REG_CTRL_EN|FPGAI2C_REG_CTRL_IEN)); + + /* + * I2C Frequency depends on host clock + * input clock of 100MHz + * prescale to 100MHz / ( 5*100kHz) -1 = 199 = 0x4F 100000/(5*100)-1=199=0xc7 + */ + prescale = (i2c->ip_clock_khz / (5 * i2c->bus_clock_khz)) - 1; + prescale = clamp(prescale, 0, 0xffff); + + diff = i2c->ip_clock_khz / (5 * (prescale + 1)) - i2c->bus_clock_khz; + if (abs(diff) > i2c->bus_clock_khz / 10) { + PRINT("Unsupported clock settings: core: %d KHz, bus: %d KHz\n", + i2c->ip_clock_khz, i2c->bus_clock_khz); + return -EINVAL; + } + + fpgai2c_reg_set(i2c, FPGAI2C_REG_PRELOW, prescale & 0xff); + fpgai2c_reg_set(i2c, FPGAI2C_REG_PREHIGH, prescale >> 8); + + /* Init the device */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + if (!use_irq) + fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_EN); + else + fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_IEN | FPGAI2C_REG_CTRL_EN); + + fpgai2c_dump(i2c); + + /* Initialize interrupt handlers if not already done */ + init_waitqueue_head(&i2c->wait); + + return 0; +} + + +static u32 fpgai2c_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm fpgai2c_algorithm = { + .master_xfer = fpgai2c_xfer, + .functionality = fpgai2c_func, +}; + +static int i2c_pci_add_bus (struct i2c_adapter *adap) +{ + int ret = 0; + /* Register new adapter */ + adap->algo = &fpgai2c_algorithm; + ret = i2c_add_numbered_adapter(adap); + return ret; +} + +static int i2c_init_internal_data(void) +{ + int i; + PRINT("%s(), line:%d\n", __func__, __LINE__); + + for( i = 0; i < total_i2c_pci_bus; i++ ) + { + fpgalogic_i2c[i].reg_shift = 0; /* 8 bit registers */ + fpgalogic_i2c[i].reg_io_width = 1; /* 8 bit read/write */ + fpgalogic_i2c[i].timeout = 500;//1000;//1ms + fpgalogic_i2c[i].ip_clock_khz = 100000;//100000;/* input clock of 100MHz */ + fpgalogic_i2c[i].bus_clock_khz = 100; + fpgalogic_i2c[i].base = fpga_base_addr + i*FPGALOGIC_CH_OFFSET; + mutex_init(&fpgalogic_i2c[i].lock); + fpgai2c_init(&fpgalogic_i2c[i]); + } + + return 0; +} + + +static int i2c_pci_init (void) +{ + int i; + + if (num_bus == 0) { + board_rev_type = ioread32(fpga_ctl_addr + MB_BRD_REV_TYPE); + + if ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_00) { + num_bus = I2C_PCI_MAX_BUS_REV00; + } else if (((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_01) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { + switch (board_rev_type & MB_BRD_TYPE_MASK){ + case BRD_TYPE_S5212_NON_NEBS: + case BRD_TYPE_S5212_NEBS: + num_bus = I2C_PCI_BUS_NUM_5; + break; + case BRD_TYPE_S5224_NON_NEBS: + case BRD_TYPE_S5224_NEBS: + num_bus = I2C_PCI_BUS_NUM_7; + break; + case BRD_TYPE_Z9232_NON_NEBS: + case BRD_TYPE_Z9232_NEBS: + case BRD_TYPE_S5232_NON_NEBS: + case BRD_TYPE_S5232_NEBS: + num_bus = I2C_PCI_BUS_NUM_8; + break; + case BRD_TYPE_S5248_NON_NEBS: + case BRD_TYPE_S5248_NEBS: + num_bus = I2C_PCI_BUS_NUM_10; + break; + case BRD_TYPE_Z9264_NON_NEBS: + case BRD_TYPE_Z9264_NEBS: + num_bus = I2C_PCI_BUS_NUM_12; + break; + case BRD_TYPE_S5296_NON_NEBS: + case BRD_TYPE_S5296_NEBS: + num_bus = I2C_PCI_BUS_NUM_16; + break; + default: + num_bus = I2C_PCI_BUS_NUM_16; + printk("Wrong BRD_TYPE: 0x%x\n", board_rev_type); + break; + } + } else { + printk("Wrong board_rev_type 0x%x\n", board_rev_type); + } + } + + printk("board_rev_type 0x%x, num_bus 0x%x\n", board_rev_type, num_bus); + total_i2c_pci_bus = num_bus; + + memset (&i2c_pci_adap, 0, sizeof(i2c_pci_adap)); + memset (&fpgalogic_i2c, 0, sizeof(fpgalogic_i2c)); + for(i=0; i < i2c_bus_controller_numb; i++) + mutex_init(&i2c_xfer_lock[i]); + + /* Initialize driver's itnernal data structures */ + i2c_init_internal_data(); + + for (i = 0 ; i < total_i2c_pci_bus; i ++) { + + i2c_pci_adap[i].owner = THIS_MODULE; + i2c_pci_adap[i].class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + + i2c_pci_adap[i].algo_data = &fpgalogic_i2c[i]; + /* /dev/i2c-600 ~ /dev/i2c-615 for FPGA LOGIC I2C channel controller 1-7 */ + i2c_pci_adap[i].nr = i+600; + sprintf( i2c_pci_adap[ i ].name, "i2c-pci-%d", i ); + /* Add the bus via the algorithm code */ + if( i2c_pci_add_bus( &i2c_pci_adap[ i ] ) != 0 ) + { + PRINT("Cannot add bus %d to algorithm layer\n", i ); + return( -ENODEV ); + } + i2c_set_adapdata(&i2c_pci_adap[i], &fpgalogic_i2c[i]); + + PRINT( "Registered bus id: %s\n", kobject_name(&i2c_pci_adap[ i ].dev.kobj)); + } + + return 0; +} + +static void i2c_pci_deinit(void) +{ + int i; + for( i = 0; i < total_i2c_pci_bus; i++ ){ + i2c_del_adapter(&i2c_pci_adap[i]); + } + +} + +/* Find upstream PCIe root node. + * Used for re-training and disabling AER. */ +static struct pci_dev* find_upstream_dev (struct pci_dev *dev) +{ + struct pci_bus *bus = 0; + struct pci_dev *bridge = 0; + struct pci_dev *cur = 0; + int found_dev = 0; + + bus = dev->bus; + if (bus == 0) { + PRINT ( "Device doesn't have an associated bus!\n"); + return 0; + } + + bridge = bus->self; + if (bridge == 0) { + PRINT ( "Can't get the bridge for the bus!\n"); + return 0; + } + + PRINT ( "Upstream device %x/%x, bus:slot.func %02x:%02x.%02x\n", + bridge->vendor, bridge->device, + bridge->bus->number, PCI_SLOT(bridge->devfn), PCI_FUNC(bridge->devfn)); + + PRINT ( "List of downstream devices:"); + list_for_each_entry (cur, &bus->devices, bus_list) { + if (cur != 0) { + PRINT ( " %x/%x", cur->vendor, cur->device); + if (cur == dev) { + found_dev = 1; + } + } + } + PRINT ( "\n"); + if (found_dev) { + return bridge; + } else { + PRINT ( "Couldn't find upstream device!\n"); + return 0; + } +} + + +static int scan_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) +{ + int i; + + for (i = 0; i < PCI_NUM_BARS; i++) { + unsigned long bar_start = pci_resource_start(dev, i); + if (bar_start) { + unsigned long bar_end = pci_resource_end(dev, i); + unsigned long bar_flags = pci_resource_flags(dev, i); + PRINT ( "BAR[%d] 0x%08lx-0x%08lx flags 0x%08lx", + i, bar_start, bar_end, bar_flags); + } + } + + return 0; +} + + +/** + * Map the device memory regions into kernel virtual address space + * after verifying their sizes respect the minimum sizes needed, given + * by the bar_min_len[] array. + */ +static int map_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) +{ + int i; + + for (i = 0; i < PCI_NUM_BARS; i++){ + phys_addr_t bar_start = pci_resource_start(dev, i); + phys_addr_t bar_end = pci_resource_end(dev, i); + unsigned long bar_length = bar_end - bar_start + 1; + fpgapci->bar_length[i] = bar_length; + + + if (!bar_start || !bar_end) { + fpgapci->bar_length[i] = 0; + continue; + } + + if (bar_length < 1) { + PRINT ( "BAR #%d length is less than 1 byte\n", i); + continue; + } + + PRINT ( "bar_start=%llx, bar_end=%llx, bar_length=%lx, flag=%lx\n", bar_start, + bar_end, bar_length, pci_resource_flags(dev, i)); + + /* map the device memory or IO region into kernel virtual + * address space */ + fpgapci->bar[i] = ioremap_nocache (bar_start + FPGALOGIC_I2C_BASE, I2C_PCI_MAX_BUS * FPGALOGIC_CH_OFFSET); + + if (!fpgapci->bar[i]) { + PRINT ( "Could not map BAR #%d.\n", i); + return -1; + } + + PRINT ( "BAR[%d] mapped at 0x%p with length %lu.", i, + fpgapci->bar[i], bar_length); + + if(i == 0) //FPGA register is in the BAR[0] + { + + fpga_phys_addr = bar_start; + fpga_ctl_addr = ioremap_nocache (bar_start, FPGA_CTL_REG_SIZE); + fpga_base_addr = fpgapci->bar[i]; + } + + PRINT ( "BAR[%d] mapped at 0x%p with length %lu.\n", i, + fpgapci->bar[i], bar_length); + } + return 0; +} + +static void free_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) +{ + int i; + + for (i = 0; i < PCI_NUM_BARS; i++) { + if (fpgapci->bar[i]) { + pci_iounmap(dev, fpgapci->bar[i]); + fpgapci->bar[i] = NULL; + } + } +} + +#define FPGA_PCI_NAME "FPGA_PCI" + +/** + * @brief Register specific function with msi interrupt line + * @param dev Pointer to pci-device, which should be allocated + * @param int interrupt number relative to global interrupt number + * @return Returns error code or zero if success + * */ +static int register_intr_handler(struct pci_dev *dev, int irq_num_id) +{ + int err = 0; + struct fpgapci_dev *fpgapci = 0; + + fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&dev->dev); + if (fpgapci == 0) { + PRINT ( ": fpgapci_dev is 0\n"); + return err; + } + + if ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_00) { + /* Request interrupt line for unique function + * alternatively function will be called from free_irq as well + * with flag IRQF_SHARED */ + switch(irq_num_id) { + /* Currently we only support test vector 2 for FPGA Logic I2C channel + * controller 1-7 interrupt*/ + case FPGA_MSI_VECTOR_ID_4: + err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_5: + err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_8: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[0]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_9: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[1]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_10: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[2]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_11: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[3]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_12: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[4]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_13: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[5]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_14: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[6]); + fpgapci->irq_assigned++; + break; + + default: + PRINT("No more interrupt handler for number (%d)\n", + dev->irq + irq_num_id); + break; + } + } else if (((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_01) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { + /* FPGA SPEC 4.3.1.34, First i2c channel mapped to vector 8 */ + switch (irq_num_id) { + case FPGA_MSI_VECTOR_ID_4: + err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_5: + err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_8: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[0]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_9: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[1]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_10: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[2]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_11: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[3]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_12: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[4]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_13: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[5]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_14: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[6]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_15: + /*it is an external interrupt number. Ignore this case */ + break; + case FPGA_MSI_VECTOR_ID_16: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_7) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[7]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_17: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[8]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_18: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[9]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_19: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[10]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_20: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[11]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_21: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[12]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_22: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[13]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_23: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[14]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_24: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[15]); + fpgapci->irq_assigned++; + } + break; + + default: + PRINT("No more interrupt handler for number (%d)\n", + dev->irq + irq_num_id); + break; + } + } + + return err; +} +/* Mask for MSI Multi message enable bits */ +#define MSI_MME 0x70 +/** + * These enums define the type of interrupt scheme that the overall + * system uses. + */ +enum fpga_irq_type { + INT_MSI_SINGLE, + INT_MSI_MULTI, + INT_MSIX, + INT_NONE, + INT_FENCE /* Last item to guard from loop run-overs */ +}; +/** + * @def PCI_DEVICE_STATUS + * define the offset for STS register + * from the start of PCI config space as specified in the + * NVME_Comliance 1.0b. offset 06h:STS - Device status. + * This register has error status for NVME PCI Exress + * Card. After reading data from this reagister, the driver + * will identify if any error is set during the operation and + * report as kernel alert message. + */ +#define PCI_DEVICE_STATUS 0x6 +/** + * @def NEXT_MASK + * This indicates the location of the next capability item + * in the list. + */ +#define NEXT_MASK 0xFF00 +/** + * @def MSIXCAP_ID + * This bit indicates if the pointer leading to this position + * is a capability. + */ +#define MSIXCAP_ID 0x11 +/** + * @def MSICAP_ID + * This bit indicates if the pointer leading to this position + * is a capability. + */ +#define MSICAP_ID 0x5 + +/** + * @def CL_MASK + * This bit position indicates Capabilities List of the controller + * The controller should support the PCI Power Management cap as a + * minimum. + */ +#define CL_MASK 0x0010 + +/** + * @def CAP_REG + * Set to offset defined in NVME Spec 1.0b. + */ +#define CAP_REG 0x34 +static void msi_set_enable(struct pci_dev *dev, int enable) +{ + int pos,maxvec; + u16 control; + int request_private_bits = 4; + + pos = pci_find_capability(dev, PCI_CAP_ID_MSI); + + if (pos) { + pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); + maxvec = 1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1); + PRINT("control = 0x%x maxvec = 0x%x\n", control, maxvec); + control &= ~PCI_MSI_FLAGS_ENABLE; + + + /* + * The PCI 2.3 spec mandates that there are at most 32 + * interrupts. If this device asks for more, only give it one. + */ + if (request_private_bits > 5) { + request_private_bits = 0; + } + + /* Update the number of IRQs the device has available to it */ + control &= ~PCI_MSI_FLAGS_QSIZE; + control |= (request_private_bits << 4); + + pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); + } +} +/** + * @brief Enables pcie-device and claims/remaps neccessary bar resources + * @param dev Pointer to pci-device, which should be allocated + * @return Returns error code or zero if success + * */ +static int fpgapci_setup_device(struct fpgapci_dev *fpgapci,struct pci_dev *dev) +{ + int err = 0; + + /* wake up the pci device */ + err = pci_enable_device(dev); + if(err) { + PRINT("failed to enable pci device %d\n", err); + goto error_pci_en; + } + + /* on platforms with buggy ACPI, pdev->msi_enabled may be set to + * allow pci_enable_device to work. This indicates INTx was not routed + * and only MSI should be used + */ + + pci_set_master(dev); + + /* Setup the BAR memory regions */ + err = pci_request_regions(dev, DRIVER_NAME); + if (err) { + PRINT("failed to enable pci device %d\n", err); + goto error_pci_req; + } + + scan_bars(fpgapci, dev); + + if (map_bars(fpgapci, dev)) { + goto fail_map_bars; + } + + i2c_pci_init(); + + return 0; + /* ERROR HANDLING */ +fail_map_bars: + pci_release_regions(dev); +error_pci_req: + pci_disable_device(dev); +error_pci_en: + return -ENODEV; +} + +static int fpgapci_configure_msi(struct fpgapci_dev *fpgapci,struct pci_dev *dev) +{ + int err = 0, i; + int request_vec; + + msi_set_enable(dev,1); + PRINT("Check MSI capability after msi_set_enable\n"); + + + /*Above 4.1.12*/ + request_vec = total_i2c_pci_bus; + err = pci_alloc_irq_vectors(dev, request_vec, pci_msi_vec_count(dev), + PCI_IRQ_MSI);//PCI_IRQ_AFFINITY | PCI_IRQ_MSI); + + if (err <= 0) { + PRINT("Cannot set MSI vector (%d)\n", err); + goto error_no_msi; + } else { + PRINT("Got %d MSI vectors starting at %d\n", err, dev->irq); + if ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_00) { + if (err < MSI_VECTOR_REV_00) { + goto error_disable_msi; + } + } else if (((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_01) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { + if (err < MSI_VECTOR_REV_01) { + goto error_disable_msi; + } + } + } + fpgapci->irq_first = dev->irq; + fpgapci->irq_length = err; + fpgapci->irq_assigned = 0; + + + for(i = 0; i < fpgapci->irq_length; i++) { + err = register_intr_handler(dev, i); + if (err) { + PRINT("Cannot request Interrupt number %d\n", i); + goto error_pci_req_irq; + } + } + + return 0; + +error_pci_req_irq: + for(i = 0; i < fpgapci->irq_assigned; i++) + { + PRINT("free_irq %d i =%d\n",fpgapci->irq_first + i,i); + if (i < 7) + free_irq(fpgapci->irq_first + 8 + i, &fpgalogic_i2c[i]); + else + free_irq(fpgapci->irq_first + 8 + i + 1, &fpgalogic_i2c[i]); + } +error_disable_msi: + pci_disable_msi(fpgapci->pci_dev); +error_no_msi: + return -ENOSPC; +} + +static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + struct fpgapci_dev *fpgapci = 0; + int status = 0; + +#ifdef TEST + PRINT ( " vendor = 0x%x, device = 0x%x, class = 0x%x, bus:slot.func = %02x:%02x.%02x\n", + dev->vendor, dev->device, dev->class, + dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); +#endif + fpgapci = kzalloc(sizeof(struct fpgapci_dev), GFP_KERNEL); + + if (!fpgapci) { + PRINT( "Couldn't allocate memory!\n"); + goto fail_kzalloc; + } + + fpgapci->pci_dev = dev; + dev_set_drvdata(&dev->dev, (void*)fpgapci); + + status = sysfs_create_group(&dev->dev.kobj, &port_attr_grp); + if (status) { + printk(KERN_INFO "%s:Cannot create sysfs\n", __FUNCTION__); + } + + fpgapci->upstream = find_upstream_dev (dev); + + if(fpgapci_setup_device(fpgapci,dev)) { + goto error_no_device; + } + + if (use_irq) { + if(fpgapci_configure_msi(fpgapci,dev)) { + goto error_cannot_configure; + } + } + + + return 0; + /* ERROR HANDLING */ +error_cannot_configure: + printk("error_cannot_configure\n"); + free_bars (fpgapci, dev); + pci_release_regions(dev); + pci_disable_device(dev); +error_no_device: + i2c_pci_deinit(); + printk("error_no_device\n"); +fail_kzalloc: + return -1; + + +} + +static void fpgapci_remove(struct pci_dev *dev) +{ + struct fpgapci_dev *fpgapci = 0; + int i; + PRINT (": dev is %p\n", dev); + + if (dev == 0) { + PRINT ( ": dev is 0\n"); + return; + } + + fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&dev->dev); + if (fpgapci == 0) { + PRINT ( ": fpgapci_dev is 0\n"); + return; + } + i2c_pci_deinit(); + // + if (use_irq) + { + for(i = 0; i < fpgapci->irq_assigned; i++) + { + PRINT("free_irq %d i =%d\n",fpgapci->irq_first + i,i); + if (i < 7) + free_irq(fpgapci->irq_first + 8 + i, &fpgalogic_i2c[i]); + else + free_irq(fpgapci->irq_first + 8 + i + 1, &fpgalogic_i2c[i]); + } + } + pci_disable_msi(fpgapci->pci_dev); + free_bars (fpgapci, dev); + pci_disable_device(dev); + pci_release_regions(dev); + + kfree (fpgapci); +} + +static const struct pci_device_id fpgapci_ids[] = { + {PCI_DEVICE(PCI_VENDOR_ID_XILINX, DEVICE)}, + {0, }, +}; + +MODULE_DEVICE_TABLE(pci, fpgapci_ids); + +static struct pci_driver fpgapci_driver = { + .name = DRIVER_NAME, + .id_table = fpgapci_ids, + .probe = fpgapci_probe, + .remove = fpgapci_remove, + /* resume, suspend are optional */ +}; + +/* Initialize the driver module (but not any device) and register + * the module with the kernel PCI subsystem. */ +static int __init fpgapci_init(void) +{ + + if (pci_register_driver(&fpgapci_driver)) { + PRINT("pci_unregister_driver\n"); + pci_unregister_driver(&fpgapci_driver); + return -ENODEV; + } + + return 0; +} + +static void __exit fpgapci_exit(void) +{ + PRINT ("fpgapci_exit"); + + /* unregister this driver from the PCI bus driver */ + pci_unregister_driver(&fpgapci_driver); + +} + + +module_init (fpgapci_init); +module_exit (fpgapci_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("joyce_yu@dell.com"); +MODULE_DESCRIPTION ("Driver for FPGA Logic I2C bus"); +MODULE_SUPPORTED_DEVICE ("FPGA Logic I2C bus"); diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/check_qsfp.sh b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/check_qsfp.sh new file mode 100755 index 000000000000..2028b8e65946 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/check_qsfp.sh @@ -0,0 +1,3 @@ +# Temporary dummy file for s5248f. +# Will be updated soon. + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/pcisysfs.py b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/pcisysfs.py new file mode 100755 index 000000000000..047618e057c8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/pcisysfs.py @@ -0,0 +1,102 @@ +#!/usr/bin/python +# Copyright (c) 2015 Dell Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. +# +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. + +import struct +import sys +import getopt +from os import * +from mmap import * + +def usage(): + ''' This is the Usage Method ''' + + print '\t\t pcisysfs.py --get --offset --res ' + print '\t\t pcisysfs.py --set --val --offset --res ' + sys.exit(1) + +def pci_mem_read(mm,offset): + mm.seek(offset) + read_data_stream=mm.read(4) + print "" + reg_val=struct.unpack('I',read_data_stream) + print "reg_val read:%x"%reg_val + return reg_val + +def pci_mem_write(mm,offset,data): + mm.seek(offset) + print "data to write:%x"%data + mm.write(struct.pack('I',data)) + +def pci_set_value(resource,val,offset): + fd=open(resource,O_RDWR) + mm=mmap(fd,0) + pci_mem_write(mm,offset,val) + +def pci_get_value(resource,offset): + fd=open(resource,O_RDWR) + mm=mmap(fd,0) + pci_mem_read(mm,offset) + +def main(argv): + + ''' The main function will read the user input from the + command line argument and process the request ''' + + opts = '' + val = '' + choice = '' + resource = '' + offset = '' + + try: + opts, args = getopt.getopt(argv, "hgsv:" , \ + ["val=","res=","offset=","help", "get", "set"]) + + except getopt.GetoptError: + usage() + + for opt,arg in opts: + + if opt in ('-h','--help'): + choice = 'help' + + elif opt in ('-g', '--get'): + choice = 'get' + + elif opt in ('-s', '--set'): + choice = 'set' + + elif opt == '--res': + resource = arg + + elif opt == '--val': + val = int(arg,16) + + elif opt == '--offset': + offset = int(arg,16) + + if choice == 'set' and val != '' and offset !='' and resource !='': + pci_set_value(resource,val,offset) + + elif choice == 'get' and offset != '' and resource !='': + pci_get_value(resource,offset) + + else: + usage() + +#Calling the main method +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/platform_sensors.py new file mode 100755 index 000000000000..6f7ba9b55b09 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/platform_sensors.py @@ -0,0 +1,277 @@ +#!/usr/bin/python +# On S5248F, the BaseBoard Management Controller is an +# autonomous subsystem provides monitoring and management +# facility independent of the host CPU. IPMI standard +# protocol is used with ipmitool to fetch sensor details. +# Current script support X00 board only. X01 support will +# be added soon. This provies support for the +# following objects: +# * Onboard temperature sensors +# * FAN trays +# * PSU + + +import os +import sys +import logging +import subprocess +import commands + +S5248F_MAX_FAN_TRAYS = 4 +S5248F_MAX_PSUS = 2 +IPMI_SENSOR_DATA = "ipmitool sdr list" +IPMI_SENSOR_DUMP = "/tmp/sdr" + +FAN_PRESENCE = "FAN{0}_prsnt" +PSU_PRESENCE = "PSU{0}_stat" +# Use this for older firmware +# PSU_PRESENCE="PSU{0}_prsnt" + +IPMI_PSU1_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x31 | awk '{print substr($0,9,1)}'" +IPMI_PSU2_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x32 | awk '{print substr($0,9,1)}'" +ipmi_sdr_list = "" + +# Dump sensor registers + + +def ipmi_sensor_dump(): + + status = 1 + global ipmi_sdr_list + ipmi_cmd = IPMI_SENSOR_DATA + status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) + + if status: + logging.error('Failed to execute:' + ipmi_sdr_list) + sys.exit(0) + +# Fetch a BMC register + + +def get_pmc_register(reg_name): + + output = None + for item in ipmi_sdr_list.split("\n"): + if reg_name in item: + output = item.strip() + + if output is None: + print('\nFailed to fetch: ' + reg_name + ' sensor ') + sys.exit(0) + + output = output.split('|')[1] + + logging.basicConfig(level=logging.DEBUG) + return output + + +# Print the information for temperature sensors + + +def print_temperature_sensors(): + + print("\nOnboard Temperature Sensors:") + + print ' PT_Left_temp: ',\ + (get_pmc_register('PT_Left_temp')) + print ' PT_Mid_temp: ',\ + (get_pmc_register('PT_Mid_temp')) + print ' PT_Right_temp: ',\ + (get_pmc_register('PT_Right_temp')) + print ' Broadcom Temp: ',\ + (get_pmc_register('NPU_Near_temp')) + print ' Inlet Airflow Temp: ',\ + (get_pmc_register('ILET_AF_temp')) + print ' CPU Temp: ',\ + (get_pmc_register('CPU_temp')) + +ipmi_sensor_dump() + +print_temperature_sensors() + +# Print the information for 1 Fan Tray + + +def print_fan_tray(tray): + + Fan_Status = [' Normal', ' Abnormal'] + Airflow_Direction = ['B2F', 'F2B'] + + print ' Fan Tray ' + str(tray) + ':' + + if (tray == 1): + + fan1_status = int(get_pmc_register('FAN1_Front_stat'), 16) + fan2_status = int(get_pmc_register('FAN1_Rear_stat'), 16) + + print ' Fan1 Speed: ',\ + get_pmc_register('FAN1_Front_rpm') + print ' Fan2 Speed: ',\ + get_pmc_register('FAN1_Rear_rpm') + print ' Fan1 State: ',\ + Fan_Status[fan1_status] + print ' Fan2 State: ',\ + Fan_Status[fan2_status] + + elif (tray == 2): + + fan1_status = int(get_pmc_register('FAN2_Front_stat'), 16) + fan2_status = int(get_pmc_register('FAN2_Rear_stat'), 16) + + print ' Fan1 Speed: ',\ + get_pmc_register('FAN2_Front_rpm') + print ' Fan2 Speed: ',\ + get_pmc_register('FAN2_Rear_rpm') + print ' Fan1 State: ',\ + Fan_Status[fan1_status] + print ' Fan2 State: ',\ + Fan_Status[fan2_status] + + elif (tray == 3): + + fan1_status = int(get_pmc_register('FAN3_Front_stat'), 16) + fan2_status = int(get_pmc_register('FAN3_Rear_stat'), 16) + + print ' Fan1 Speed: ',\ + get_pmc_register('FAN3_Front_rpm') + print ' Fan2 Speed: ',\ + get_pmc_register('FAN3_Rear_rpm') + print ' Fan1 State: ',\ + Fan_Status[fan1_status] + print ' Fan2 State: ',\ + Fan_Status[fan2_status] + + elif (tray == 4): + + fan1_status = int(get_pmc_register('FAN4_Front_stat'), 16) + fan2_status = int(get_pmc_register('FAN4_Rear_stat'), 16) + + print ' Fan1 Speed: ',\ + get_pmc_register('FAN4_Front_rpm') + print ' Fan2 Speed: ',\ + get_pmc_register('FAN4_Rear_rpm') + print ' Fan1 State: ',\ + Fan_Status[fan1_status] + print ' Fan2 State: ',\ + Fan_Status[fan2_status] + + +print('\nFan Trays:') + +for tray in range(1, S5248F_MAX_FAN_TRAYS + 1): + fan_presence = FAN_PRESENCE.format(tray) + if (get_pmc_register(fan_presence)): + print_fan_tray(tray) + else: + print '\n Fan Tray ' + str(tray + 1) + ': Not present' + + def get_psu_presence(index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + ret_status = 1 + + if index == 1: + status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + + #if ret_status: + # print ipmi_cmd_ret + # logging.error('Failed to execute ipmitool') + # sys.exit(0) + + psu_status = ipmi_cmd_ret + + if psu_status == '1': + status = 1 + + return status + + +# Print the information for PSU1, PSU2 +def print_psu(psu): + Psu_Type = ['Normal', 'Mismatch'] + Psu_Input_Type = ['AC', 'DC'] + PSU_STATUS_TYPE_BIT = 4 + PSU_STATUS_INPUT_TYPE_BIT = 1 + PSU_FAN_PRESENT_BIT = 2 + PSU_FAN_STATUS_BIT = 1 + PSU_FAN_AIR_FLOW_BIT = 0 + Psu_Fan_Presence = ['Present', 'Absent'] + Psu_Fan_Status = ['Normal', 'Abnormal'] + Psu_Fan_Airflow = ['B2F', 'F2B'] + + # print ' Input: ', Psu_Input_Type[psu_input_type] + # print ' Type: ', Psu_Type[psu_type] + + # PSU FAN details + if (psu == 1): + + # psu1_fan_status = int(get_pmc_register('PSU1_status'),16) + + print ' PSU1:' + print ' FAN Normal Temperature: ',\ + get_pmc_register('PSU1_temp') + print ' FAN AirFlow Temperature: ',\ + get_pmc_register('PSU1_AF_temp') + print ' FAN RPM: ',\ + get_pmc_register('PSU1_rpm') + # print ' FAN Status: ', Psu_Fan_Status[psu1_fan_status] + + # PSU input & output monitors + print ' Input Voltage: ',\ + get_pmc_register('PSU1_In_volt') + print ' Output Voltage: ',\ + get_pmc_register('PSU1_Out_volt') + print ' Input Power: ',\ + get_pmc_register('PSU1_In_watt') + print ' Output Power: ',\ + get_pmc_register('PSU1_Out_watt') + print ' Input Current: ',\ + get_pmc_register('PSU1_In_amp') + print ' Output Current: ',\ + get_pmc_register('PSU1_Out_amp') + + else: + + # psu2_fan_status = int(get_pmc_register('PSU1_status'),16) + print ' PSU2:' + print ' FAN Normal Temperature: ',\ + get_pmc_register('PSU2_temp') + print ' FAN AirFlow Temperature: ',\ + get_pmc_register('PSU2_AF_temp') + print ' FAN RPM: ',\ + get_pmc_register('PSU2_rpm') + # print ' FAN Status: ', Psu_Fan_Status[psu2_fan_status] + + # PSU input & output monitors + print ' Input Voltage: ',\ + get_pmc_register('PSU2_In_volt') + print ' Output Voltage: ',\ + get_pmc_register('PSU2_Out_volt') + print ' Input Power: ',\ + get_pmc_register('PSU2_In_watt') + print ' Output Power: ',\ + get_pmc_register('PSU2_Out_watt') + print ' Input Current: ',\ + get_pmc_register('PSU2_In_amp') + print ' Output Current: ',\ + get_pmc_register('PSU2_Out_amp') + + +print('\nPSUs:') +for psu in range(1, S5248F_MAX_PSUS + 1): + #psu_presence = PSU_PRESENCE.format(psu) + if (get_psu_presence(psu)): + print_psu(psu) + else: + print '\n PSU ', psu, 'Not present' + +print '\n Total Power: ',\ + get_pmc_register('PSU_Total_watt') + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/qsfp_irq_enable.py b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/qsfp_irq_enable.py new file mode 100755 index 000000000000..5050475f987e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/qsfp_irq_enable.py @@ -0,0 +1,32 @@ +#!/usr/bin/python + +try: + import struct + import sys + from os import * + from mmap import * + +except ImportError as e: + raise ImportError("%s - required module no found" % str(e)) + +BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" +PORT_START = 0 +PORT_END = 32 + + +def pci_mem_write(mm, offset, data): + mm.seek(offset) + mm.write(struct.pack('I', data)) + + +def pci_set_value(resource, val, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + val = pci_mem_write(mm, offset, val) + mm.close() + close(fd) + return val + +for port_num in range(PORT_START, PORT_END+1): + port_offset = 0x400c + ((port_num) * 16) + pci_set_value(BASE_RES_PATH, 0x30, port_offset) diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh new file mode 100755 index 000000000000..e74a3d6c40de --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh @@ -0,0 +1,161 @@ +#!/bin/bash + +init_devnum() { + found=0 + for devnum in 0 1; do + devname=`cat /sys/bus/i2c/devices/i2c-${devnum}/name` + # iSMT adapter can be at either dffd0000 or dfff0000 + if [[ $devname == 'SMBus iSMT adapter at '* ]]; then + found=1 + break + fi + done + + [ $found -eq 0 ] && echo "cannot find iSMT" && exit 1 +} + +# Attach/Detach syseeprom on CPU board +sys_eeprom() { + case $1 in + "new_device") echo 24c16 0x50 > /sys/bus/i2c/devices/i2c-0/$1 + ;; + "delete_device") echo 0x50 > /sys/bus/i2c/devices/i2c-0/$1 + ;; + *) echo "s5248f_platform: sys_eeprom : invalid command !" + ;; + esac +} + +#Attach/Detach the MUX connecting all QSFPs +switch_board_qsfp_mux() { + case $1 in + "new_device") + for ((i=603;i<=610;i++)); + do + echo "Attaching PCA9548 @ 0x74" + echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-$i/$1 + done + + ;; + "delete_device") + for ((i=603;i<=610;i++)); + do + echo "Detaching PCA9548 @ 0x74" + echo 0x74 > /sys/bus/i2c/devices/i2c-$i/$1 + done + + ;; + *) echo "s5248f_platform: switch_board_qsfp_mux: invalid command !" + ;; + esac + sleep 2 +} + +#Attach/Detach 64 instances of EEPROM driver QSFP ports +#eeprom can dump data using below command +switch_board_qsfp() { + case $1 in + "new_device") + for ((i=2;i<=57;i++)); + do + echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + "delete_device") + for ((i=2;i<=57;i++)); + do + echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + *) echo "s5248f_platform: switch_board_qsfp: invalid command !" + ;; + esac +} + +#Modsel 64 ports to applicable QSFP type modules +#This enables the adapter to respond for i2c commands +switch_board_modsel() { + resource="/sys/bus/pci/devices/0000:04:00.0/resource0" + for ((i=1;i<=64;i++)); + do + port_addr=$(( 16384 + ((i - 1) * 16))) + hex=$( printf "0x%x" $port_addr ) + python /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 + done +} + +platform_firmware_versions() { + FIRMWARE_VERSION_FILE=/var/log/firmware_versions + rm -rf ${FIRMWARE_VERSION_FILE} + echo "BIOS: `dmidecode -s system-version `" > $FIRMWARE_VERSION_FILE + ## Get FPGA version + r=`/usr/bin/pcisysfs.py --get --offset 0x00 --res /sys/bus/pci/devices/0000\:04\:00.0/resource0 | sed '1d; s/.*\(....\)$/\1/; s/\(..\{1\}\)/\1./'` + r_min=$(echo $r | sed 's/.*\(..\)$/0x\1/') + r_maj=$(echo $r | sed 's/^\(..\).*/0x\1/') + echo "FPGA: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + ## Get BMC Firmware Revision + r=`cat /sys/class/ipmi/ipmi0/device/bmc/firmware_revision` + echo "BMC: $r" >> $FIRMWARE_VERSION_FILE + + #System CPLD 0x31 on i2c bus 601 ( physical FPGA I2C-2) + r_min=`/usr/sbin/i2cget -y 601 0x31 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 601 0x31 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "System CPLD: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 1 0x30 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x30 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x30 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 1: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 2 0x31 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x31 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x31 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 2: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 3 0x32 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x32 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x32 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 3: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 3 0x32 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x33 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x33 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 4: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE +} + +#This enables the led control for CPU and default states +switch_board_led_default() { + resource="/sys/bus/pci/devices/0000:04:00.0/resource0" + python /usr/bin/pcisysfs.py --set --offset 0x24 --val 0x194 --res $resource > /dev/null 2>&1 +} +init_devnum + +if [ "$1" == "init" ]; then + modprobe i2c-dev + modprobe i2c-mux-pca954x force_deselect_on_exit=1 + modprobe ipmi_devintf + modprobe ipmi_si + modprobe i2c_ocores + modprobe dell_s5248f_fpga_ocores + sys_eeprom "new_device" + switch_board_qsfp_mux "new_device" + switch_board_qsfp "new_device" + switch_board_modsel + switch_board_led_default + #python /usr/bin/qsfp_irq_enable.py + platform_firmware_versions + +elif [ "$1" == "deinit" ]; then + sys_eeprom "delete_device" + switch_board_qsfp "delete_device" + switch_board_qsfp_mux "delete_device" + + modprobe -r i2c-mux-pca954x + modprobe -r i2c-dev +else + echo "s5248f_platform : Invalid option !" +fi + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/sensors b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/sensors new file mode 100755 index 000000000000..ee53f2b0f325 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/sensors @@ -0,0 +1,8 @@ +#!/bin/bash +docker exec -i pmon sensors "$@" +docker exec -i pmon /usr/bin/platform_sensors.py "$@" + +#To probe sensors not part of lm-sensors +#if [ -r /usr/local/bin/platform_sensors.py ]; then +# python /usr/local/bin/platform_sensors.py +#fi diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/systemd/platform-modules-s5248f.service b/platform/broadcom/sonic-platform-modules-dell/s5248f/systemd/platform-modules-s5248f.service new file mode 100644 index 000000000000..ec3ea09f00ae --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/systemd/platform-modules-s5248f.service @@ -0,0 +1,13 @@ +[Unit] +Description=Dell S5248f Platform modules +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/s5248f_platform.sh init +ExecStop=/usr/local/bin/s5248f_platform.sh deinit +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/modules/dell_s6000_platform.c b/platform/broadcom/sonic-platform-modules-dell/s6000/modules/dell_s6000_platform.c index 0463ac30e589..e8bcd312168f 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 @@ -549,6 +549,18 @@ static ssize_t get_psu1_status(struct device *dev, struct device_attribute *deva return sprintf(buf, "%d\n", data); } +static ssize_t get_powersupply_status(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int data; + struct cpld_platform_data *pdata = dev->platform_data; + + data = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x3); + if (data < 0) + return sprintf(buf, "read error"); + + return sprintf(buf, "%x\n", data); +} + static ssize_t get_system_led(struct device *dev, struct device_attribute *devattr, char *buf) { int ret; @@ -1126,6 +1138,7 @@ static DEVICE_ATTR(psu0_prs, S_IRUGO, get_psu0_prs, NULL); static DEVICE_ATTR(psu1_prs, S_IRUGO, get_psu1_prs, NULL); static DEVICE_ATTR(psu0_status, S_IRUGO, get_psu0_status, NULL); static DEVICE_ATTR(psu1_status, S_IRUGO, get_psu1_status, NULL); +static DEVICE_ATTR(powersupply_status, S_IRUGO, get_powersupply_status, NULL); static DEVICE_ATTR(system_led, S_IRUGO | S_IWUSR, get_system_led, set_system_led); static DEVICE_ATTR(locator_led, S_IRUGO | S_IWUSR, get_locator_led, set_locator_led); static DEVICE_ATTR(power_led, S_IRUGO | S_IWUSR, get_power_led, set_power_led); @@ -1150,6 +1163,7 @@ static struct attribute *s6000_cpld_attrs[] = { &dev_attr_psu1_prs.attr, &dev_attr_psu0_status.attr, &dev_attr_psu1_status.attr, + &dev_attr_powersupply_status.attr, &dev_attr_system_led.attr, &dev_attr_locator_led.attr, &dev_attr_power_led.attr, 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 316fbaec5fee..bf6c730425e7 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 @@ -32,7 +32,7 @@ add_i2c_devices() { echo 24c02 0x52 > /sys/class/i2c-adapter/i2c-11/new_device echo 24c02 0x53 > /sys/class/i2c-adapter/i2c-11/new_device for i in `seq 0 31`; do - echo sff8436 0x50 > /sys/class/i2c-adapter/i2c-$((20+i))/new_device + echo optoe1 0x50 > /sys/class/i2c-adapter/i2c-$((20+i))/new_device done } diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/__init__.py index 1e26181263a5..48057d290357 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/__init__.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/__init__.py @@ -1,2 +1,2 @@ -__all__ = ["platform", "chassis", "sfp"] +__all__ = ["platform", "chassis", "sfp", "psu", "thermal"] from sonic_platform import * diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py index a625a796ef53..005fdd15b269 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 @@ -9,29 +9,45 @@ try: import os + import time + import datetime + import subprocess from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.sfp import Sfp + from sonic_platform.eeprom import Eeprom + from sonic_platform.fan import Fan + from sonic_platform.psu import Psu + from sonic_platform.thermal import Thermal + from sonic_platform.component import Component except ImportError as e: raise ImportError(str(e) + "- required module not found") +MAX_S6000_FAN = 3 +MAX_S6000_PSU = 2 +MAX_S6000_THERMAL = 10 +MAX_S6000_COMPONENT = 4 + + class Chassis(ChassisBase): """ DELLEMC Platform-specific Chassis class """ + CPLD_DIR = "/sys/devices/platform/dell-s6000-cpld.0" - MAILBOX_DIR = "/sys/devices/platform/dell-s6000-cpld.0" - + sfp_control = "" + PORT_START = 0 + PORT_END = 0 reset_reason_dict = {} reset_reason_dict[0xe] = ChassisBase.REBOOT_CAUSE_NON_HARDWARE reset_reason_dict[0x6] = ChassisBase.REBOOT_CAUSE_NON_HARDWARE def __init__(self): # Initialize SFP list - PORT_START = 0 - PORT_END = 31 + self.PORT_START = 0 + self.PORT_END = 31 EEPROM_OFFSET = 20 - PORTS_IN_BLOCK = (PORT_END + 1) + PORTS_IN_BLOCK = (self.PORT_END + 1) # sfp.py will read eeprom contents and retrive the eeprom data. # It will also provide support sfp controls like reset and setting @@ -39,15 +55,36 @@ def __init__(self): # We pass the eeprom path and sfp control path from chassis.py # So that sfp.py implementation can be generic to all platforms eeprom_base = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" - sfp_control = "/sys/devices/platform/dell-s6000-cpld.0/" + self.sfp_control = "/sys/devices/platform/dell-s6000-cpld.0/" + for index in range(0, PORTS_IN_BLOCK): eeprom_path = eeprom_base.format(index + EEPROM_OFFSET) - sfp_node = Sfp(index, 'QSFP', eeprom_path, sfp_control, index) + sfp_node = Sfp(index, 'QSFP', eeprom_path, self.sfp_control, index) self._sfp_list.append(sfp_node) - def get_register(self, reg_name): + # Get Transceiver status + self.modprs_register = self._get_transceiver_status() + + self.sys_eeprom = Eeprom() + for i in range(MAX_S6000_FAN): + fan = Fan(i) + self._fan_list.append(fan) + + for i in range(MAX_S6000_PSU): + psu = Psu(i) + self._psu_list.append(psu) + + for i in range(MAX_S6000_THERMAL): + thermal = Thermal(i) + self._thermal_list.append(thermal) + + for i in range(MAX_S6000_COMPONENT): + component = Component(i) + self._component_list.append(component) + + def _get_cpld_register(self, reg_name): rv = 'ERR' - mb_reg_file = self.MAILBOX_DIR+'/'+reg_name + mb_reg_file = self.CPLD_DIR+'/'+reg_name if (not os.path.isfile(mb_reg_file)): return rv @@ -62,17 +99,160 @@ def get_register(self, reg_name): rv = rv.lstrip(" ") return rv + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + return self.sys_eeprom.modelstr() + + def get_presence(self): + """ + Retrieves the presence of the chassis + Returns: + bool: True if chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the chassis + Returns: + string: Model/part number of chassis + """ + return self.sys_eeprom.part_number_str() + + def get_serial(self): + """ + Retrieves the serial number of the chassis (Service tag) + Returns: + string: Serial number of chassis + """ + return self.sys_eeprom.serial_str() + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self.sys_eeprom.base_mac_addr() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + + Returns: + A string containing the hardware serial number for this + chassis. + """ + return self.sys_eeprom.serial_number_str() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the + chassis + + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their + corresponding values. + """ + return self.sys_eeprom.system_eeprom_info() + def get_reboot_cause(self): """ Retrieves the cause of the previous reboot """ - reset_reason = int(self.get_register('last_reboot_reason'), base=16) - # In S6000, We track the reboot reason by writing the reason in # NVRAM. Only Warmboot and Coldboot reason are supported here. + # Since it does not support any hardware reason, we return + # non_hardware as default + + lrr = self._get_cpld_register('last_reboot_reason') + if (lrr != 'ERR'): + reset_reason = int(lrr, base=16) + if (reset_reason in self.reset_reason_dict): + return (self.reset_reason_dict[reset_reason], None) + + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) + + def _get_transceiver_status(self): + presence_ctrl = self.sfp_control + 'qsfp_modprs' + try: + reg_file = open(presence_ctrl) + + except IOError as e: + return False + + content = reg_file.readline().rstrip() + reg_file.close() + + return int(content, 16) + + def get_transceiver_change_event(self, timeout=0): + """ + Returns a dictionary containing sfp changes which have + experienced a change at chassis level + """ + start_time = time.time() + port_dict = {} + port = self.PORT_START + forever = False + + if timeout == 0: + forever = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + return False, {} + end_time = start_time + timeout + + if (start_time > end_time): + return False, {} # Time wrap or possibly incorrect timeout + + while (timeout >= 0): + # Check for OIR events and return updated port_dict + reg_value = self._get_transceiver_status() + if (reg_value != self.modprs_register): + changed_ports = (self.modprs_register ^ reg_value) + while (port >= self.PORT_START and port <= self.PORT_END): + # Mask off the bit corresponding to our port + mask = (1 << port) + if (changed_ports & mask): + # ModPrsL is active low + if reg_value & mask == 0: + port_dict[port] = '1' + else: + port_dict[port] = '0' + port += 1 + + # Update reg value + self.modprs_register = reg_value + return True, port_dict - if (reset_reason in self.reset_reason_dict): - return (self.reset_reason_dict[reset_reason], None) + if forever: + time.sleep(1) + else: + timeout = end_time - time.time() + if timeout >= 1: + time.sleep(1) # We poll at 1 second granularity + else: + if timeout > 0: + time.sleep(timeout) + return True, {} + return False, {} - return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason") diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/component.py new file mode 100644 index 000000000000..daa30eaafa3b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/component.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python + +######################################################################## +# DELLEMC S6000 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in +# the platform +# +######################################################################## + +try: + import os + import subprocess + from sonic_platform_base.component_base import ComponentBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +BIOS_QUERY_VERSION_COMMAND = "dmidecode -s system-version" + + +class Component(ComponentBase): + """DellEMC Platform-specific Component class""" + + CPLD_DIR = "/sys/devices/platform/dell-s6000-cpld.0" + + CHASSIS_COMPONENTS = [ + ["BIOS", ("Performs initialization of hardware components during " + "booting")], + ["System-CPLD", "Used for managing CPU board devices and power"], + ["Master-CPLD", ("Used for managing Fan, PSU, system LEDs, QSFP " + "modules (1-16)")], + ["Slave-CPLD", "Used for managing QSFP modules (17-32)"] + ] + + def __init__(self, component_index): + self.index = component_index + self.name = self.CHASSIS_COMPONENTS[self.index][0] + self.description = self.CHASSIS_COMPONENTS[self.index][1] + + def _get_cpld_register(self, reg_name): + rv = 'ERR' + mb_reg_file = self.CPLD_DIR+'/'+reg_name + + if (not os.path.isfile(mb_reg_file)): + return rv + + try: + with open(mb_reg_file, 'r') as fd: + rv = fd.read() + except Exception as error: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def _get_command_result(self, cmdline): + try: + proc = subprocess.Popen(cmdline.split(), stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + result = stdout.rstrip('\n') + except OSError: + result = None + + return result + + def _get_cpld_version(self, cpld_number): + cpld_version_reg = { + 1: "system_cpld_ver", + 2: "master_cpld_ver", + 3: "slave_cpld_ver" + } + + cpld_version = self._get_cpld_register(cpld_version_reg[cpld_number]) + + if cpld_version != 'ERR': + return str(int(cpld_version, 16)) + else: + return 'NA' + + def get_name(self): + """ + Retrieves the name of the component + + Returns: + A string containing the name of the component + """ + return self.name + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + if self.index == 0: + bios_ver = self._get_command_result(BIOS_QUERY_VERSION_COMMAND) + + if not bios_ver: + return 'NA' + else: + return bios_ver + + elif self.index <= 3: + return self._get_cpld_version(self.index) + + 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/s6000/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py index b39b140c7254..3d824ba28268 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 @@ -35,7 +35,8 @@ fan_eeprom_format = [ ('PPID', 's', 20), ('DPN Rev', 's', 3), ('Service Tag', 's', 7), ('Part Number', 's', 10), ('Part Num Revision', 's', 3), - ('Mfg Test', 's', 2), ('Number of Fans', 's', 2), ('Fan Type', 's', 1), + ('Mfg Test', 's', 2), ('Redundant copy', 's', 82), + ('Number of Fans', 's', 1), ('Fan Type', 's', 1), ('Fab Rev', 's', 2) ] @@ -86,6 +87,8 @@ def _load_system_eeprom(self): self.base_mac = 'NA' self.serial_number = 'NA' self.part_number = 'NA' + self.model_str = 'NA' + self.serial = 'NA' self.eeprom_tlv_dict = dict() else: eeprom = self.eeprom_data @@ -95,6 +98,8 @@ def _load_system_eeprom(self): self.base_mac = 'NA' self.serial_number = 'NA' self.part_number = 'NA' + self.model_str = 'NA' + self.serial = 'NA' return total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10]) @@ -123,11 +128,15 @@ def _load_system_eeprom(self): tlv_index += ord(eeprom[tlv_index+1]) + 2 self.base_mac = self.eeprom_tlv_dict.get( - hex(self._TLV_CODE_MAC_BASE), 'NA') + "0x%X" % (self._TLV_CODE_MAC_BASE), 'NA') self.serial_number = self.eeprom_tlv_dict.get( - hex(self._TLV_CODE_SERIAL_NUMBER), 'NA') + "0x%X" % (self._TLV_CODE_SERIAL_NUMBER), 'NA') self.part_number = self.eeprom_tlv_dict.get( - hex(self._TLV_CODE_PART_NUMBER), 'NA') + "0x%X" % (self._TLV_CODE_PART_NUMBER), 'NA') + self.model_str = self.eeprom_tlv_dict.get( + "0x%X" % (self._TLV_CODE_PRODUCT_NAME), 'NA') + self.serial = self.eeprom_tlv_dict.get( + "0x%X" % (self._TLV_CODE_SERVICE_TAG), 'NA') def _load_device_eeprom(self): """ @@ -151,7 +160,7 @@ def _load_device_eeprom(self): if valid: self.serial_number += "-" + data else: - seld.serial_number = 'NA' + self.serial_number = 'NA' (valid, data) = self._get_eeprom_field("Part Number") if valid: @@ -159,6 +168,12 @@ def _load_device_eeprom(self): else: self.part_number = 'NA' + (valid, data) = self._get_eeprom_field("Fan Type") + if valid: + self.fan_type = data + else: + self.fan_type = 'NA' + def _get_eeprom_field(self, field_name): """ For a field name specified in the EEPROM format, returns the @@ -185,6 +200,12 @@ def part_number_str(self): """ return self.part_number + def airflow_fan_type(self): + """ + Returns the airflow fan type. + """ + return int(self.fan_type.encode('hex'), 16) + # System EEPROM specific methods def base_mac_addr(self): """ @@ -192,6 +213,18 @@ def base_mac_addr(self): """ return self.base_mac + def modelstr(self): + """ + Returns the Model name. + """ + return self.model_str + + def serial_str(self): + """ + Returns the servicetag number. + """ + return self.serial + def system_eeprom_info(self): """ Returns a dictionary, where keys are the type code defined in diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py new file mode 100644 index 000000000000..3350b4818401 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py @@ -0,0 +1,286 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC S6000 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fans' information which are available in the platform +# +######################################################################## + + +try: + import os + from sonic_platform_base.fan_base import FanBase + from sonic_platform.eeprom import Eeprom +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +MAX_S6000_FAN_SPEED = 19000 + + +class Fan(FanBase): + """DellEMC Platform-specific Fan class""" + + CPLD_DIR = "/sys/devices/platform/dell-s6000-cpld.0/" + I2C_DIR = "/sys/class/i2c-adapter/" + + def __init__(self, fan_index, psu_fan=False): + # Fan is 1-based in DellEMC platforms + self.index = fan_index + 1 + self.is_psu_fan = psu_fan + + if not self.is_psu_fan: + self.fan_presence_reg = "fan_prs" + self.fan_led_reg = "fan{}_led".format(fan_index) + self.get_fan_speed_reg = self.I2C_DIR + "i2c-11/11-0029/" +\ + "fan{}_input".format(self.index) + self.set_fan_speed_reg = self.I2C_DIR + "i2c-11/11-0029/" +\ + "fan{}_target".format(self.index) + self.eeprom = Eeprom(is_fan=True, fan_index=self.index) + self.max_fan_speed = MAX_S6000_FAN_SPEED + self.supported_led_color = ['off', 'green', 'amber'] + else: + self.get_fan_speed_reg = self.I2C_DIR + "i2c-1/1-005{}/" +\ + "fan1_input".format(10 - self.index) + + def _get_cpld_register(self, reg_name): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + cpld_reg_file = self.CPLD_DIR + reg_name + + if (not os.path.isfile(cpld_reg_file)): + return rv + + try: + with open(cpld_reg_file, 'r') as fd: + rv = fd.read() + except: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def _set_cpld_register(self, reg_name, value): + # On successful write, returns the value will be written on + # reg_name and on failure returns 'ERR' + rv = 'ERR' + cpld_reg_file = self.CPLD_DIR + reg_name + + if (not os.path.isfile(cpld_reg_file)): + print "open error" + return rv + + try: + with open(cpld_reg_file, 'w') as fd: + rv = fd.write(str(value)) + except: + rv = 'ERR' + + return rv + + def _get_i2c_register(self, reg_file): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(reg_file)): + return rv + + try: + with open(reg_file, 'r') as fd: + rv = fd.read() + except: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def _set_i2c_register(self, reg_file, value): + # On successful write, the value read will be written on + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(reg_file)): + return rv + + try: + with open(reg_file, 'w') as fd: + rv = fd.write(str(value)) + except: + rv = 'ERR' + + return rv + + def get_name(self): + """ + Retrieves the name of the Fan + + Returns: + string: The name of the Fan + """ + if not self.is_psu_fan: + return "Fan{}".format(self.index) + else: + return "PSU{} Fan".format(self.index) + + def get_presence(self): + """ + Retrieves the presence of the Fan Unit + + Returns: + bool: True if Fan is present, False if not + """ + status = False + fan_presence = self._get_cpld_register(self.fan_presence_reg) + if (fan_presence != 'ERR'): + fan_presence = int(fan_presence,16) & self.index + if fan_presence: + status = True + + return status + + def get_model(self): + """ + Retrieves the part number of the Fan + + Returns: + string: Part number of Fan + """ + return self.eeprom.part_number_str() + + def get_serial(self): + """ + Retrieves the serial number of the Fan + + Returns: + string: Serial number of Fan + """ + # Sample Serial number format "US-01234D-54321-25A-0123-A00" + return self.eeprom.serial_number_str() + + def get_status(self): + """ + Retrieves the operational status of the Fan + + Returns: + bool: True if Fan is operating properly, False if not + """ + status = False + fan_speed = self._get_i2c_register(self.get_fan_speed_reg) + if (fan_speed != 'ERR'): + if (int(fan_speed) > 14000): + status = True + + return status + + def get_direction(self): + """ + Retrieves the fan airflow direction + + Returns: + A string, either FAN_DIRECTION_INTAKE or + FAN_DIRECTION_EXHAUST depending on fan direction + """ + direction = {1: 'FAN_DIRECTION_INTAKE', 2: 'FAN_DIRECTION_EXHAUST'} + fan_direction = self.eeprom.airflow_fan_type() + + return direction.get(fan_direction,'NA') + + def get_speed(self): + """ + Retrieves the speed of fan + + Returns: + int: percentage of the max fan speed + """ + fan_speed = self._get_i2c_register(self.get_fan_speed_reg) + if (fan_speed != 'ERR') and self.get_presence(): + speed_in_rpm = int(fan_speed, 10) + speed = (100 * speed_in_rpm)/self.max_fan_speed + else: + speed = 0 + + return speed + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + + Returns: + An integer, the percentage of variance from target speed + which is considered tolerable + """ + if self.get_presence(): + # The tolerance value is fixed as 20% for all the DellEmc platform + tolerance = 20 + else: + tolerance = 0 + + return tolerance + + def set_speed(self, speed): + """ + Set fan speed to expected value + Args: + speed: An integer, the percentage of full fan speed to set + fan to, in the range 0 (off) to 100 (full speed) + Returns: + bool: True if set success, False if fail. + """ + fan_set = (speed * self.max_fan_speed)/ 100 + rv = self._set_i2c_register(self.set_fan_speed_reg , fan_set) + if (rv != 'ERR'): + return True + else: + return False + + def set_status_led(self, color): + """ + Set led to expected color + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if set success, False if fail. + """ + if color not in self.supported_led_color: + return False + if(color == self.STATUS_LED_COLOR_AMBER): + color = 'yellow' + + rv = self._set_cpld_register(self.fan_led_reg ,color) + if (rv != 'ERR'): + return True + else: + return False + + def get_status_led(self): + """ + Gets the state of the fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + fan_led = self._get_cpld_register(self.fan_led_reg) + if (fan_led != 'ERR'): + if (fan_led == 'yellow'): + return self.STATUS_LED_COLOR_AMBER + else: + return fan_led + else: + return self.STATUS_LED_COLOR_OFF + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + + Returns: + An integer, the percentage of full fan speed, in the range 0 + (off) to 100 (full speed) + """ + return 79 diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py new file mode 100644 index 000000000000..dfbd2a87eb5d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py @@ -0,0 +1,240 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC S6000 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the PSUs' information which are available in the platform +# +######################################################################## + + +try: + import os + from sonic_platform_base.psu_base import PsuBase + from sonic_platform.eeprom import Eeprom +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Psu(PsuBase): + """DellEMC Platform-specific PSU class""" + + CPLD_DIR = "/sys/devices/platform/dell-s6000-cpld.0/" + I2C_DIR = "/sys/class/i2c-adapter/" + + def __init__(self, psu_index): + # PSU is 1-based in DellEMC platforms + self.index = psu_index + 1 + self.psu_presence_reg = "psu{}_prs".format(psu_index) + self.psu_status_reg = "powersupply_status" + + if self.index == 1: + ltc_dir = self.I2C_DIR + "i2c-11/11-0042/hwmon/" + else: + ltc_dir = self.I2C_DIR + "i2c-11/11-0040/hwmon/" + hwmon_node = os.listdir(ltc_dir)[0] + self.HWMON_DIR = ltc_dir + hwmon_node + '/' + + self.psu_voltage_reg = self.HWMON_DIR + "in1_input" + self.psu_current_reg = self.HWMON_DIR + "curr1_input" + self.psu_power_reg = self.HWMON_DIR + "power1_input" + + self.eeprom = Eeprom(is_psu=True, psu_index=self.index) + + # Overriding _fan_list class variable defined in PsuBase, to + # make it unique per Psu object + self._fan_list = [] + + def _get_cpld_register(self, reg_name): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + cpld_reg_file = self.CPLD_DIR + reg_name + + if (not os.path.isfile(cpld_reg_file)): + return rv + + try: + with open(cpld_reg_file, 'r') as fd: + rv = fd.read() + except: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def _get_i2c_register(self, reg_file): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(reg_file)): + return rv + + try: + with open(reg_file, 'r') as fd: + rv = fd.read() + except: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + 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 + """ + status = False + psu_presence = self._get_cpld_register(self.psu_presence_reg) + if (psu_presence != 'ERR'): + psu_presence = int(psu_presence) + if psu_presence: + status = True + + return status + + def get_model(self): + """ + Retrieves the part number of the PSU + + Returns: + string: Part number of PSU + """ + return self.eeprom.part_number_str() + + def get_serial(self): + """ + Retrieves the serial number of the PSU + + Returns: + string: Serial number of PSU + """ + # Sample Serial number format "US-01234D-54321-25A-0123-A00" + return self.eeprom.serial_number_str() + + def get_status(self): + """ + Retrieves the operational status of the PSU + + Returns: + bool: True if PSU is operating properly, False if not + """ + status = False + psu_status = self._get_cpld_register(self.psu_status_reg) + if (psu_status != 'ERR'): + psu_status = (int(psu_status, 16) >> ((2 - self.index) * 4)) & 0xF + if (~psu_status & 0b1000) and (~psu_status & 0b0100): + 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 + """ + psu_voltage = self._get_i2c_register(self.psu_voltage_reg) + if (psu_voltage != 'ERR') and self.get_status(): + # Converting the value returned by driver which is in + # millivolts to volts + psu_voltage = float(psu_voltage) / 1000 + else: + psu_voltage = 0.0 + + return psu_voltage + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, electric current in amperes, + e.g. 15.4 + """ + psu_current = self._get_i2c_register(self.psu_current_reg) + if (psu_current != 'ERR') and self.get_status(): + # Converting the value returned by driver which is in + # milliamperes to amperes + psu_current = float(psu_current) / 1000 + else: + psu_current = 0.0 + + return psu_current + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, + e.g. 302.6 + """ + psu_power = self._get_i2c_register(self.psu_power_reg) + if (psu_power != 'ERR') and self.get_status(): + # Converting the value returned by driver which is in + # microwatts to watts + psu_power = float(psu_power) / 1000000 + else: + psu_power = 0.0 + + return psu_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 + psu_status = self._get_cpld_register(self.psu_status_reg) + if (psu_status != 'ERR'): + psu_status = (int(psu_status, 16) >> ((2 - self.index) * 4)) & 0xF + if (psu_status == 0x2): + status = True + + return status + + def get_status_led(self): + """ + Gets the state of the PSU status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + if self.get_powergood_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + + def set_status_led(self, color): + """ + Sets the state of the PSU status LED + Args: + color: A string representing the color with which to set the + PSU status LED + Returns: + bool: True if status LED state is set successfully, False if + not + """ + # In S6000, the firmware running in the PSU controls the LED + # and the PSU LED state cannot be changed from CPU. + return False diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py deleted file mode 120000 index 84af7963bb3d..000000000000 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py +++ /dev/null @@ -1 +0,0 @@ -../../s6100/sonic_platform/sfp.py \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py new file mode 100644 index 000000000000..9ab89db5d61a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py @@ -0,0 +1,880 @@ +#!/usr/bin/env python + +############################################################################# +# DELLEMC +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + import os + import time + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +PAGE_OFFSET = 0 +KEY_OFFSET = 1 +KEY_WIDTH = 2 +FUNC_NAME = 3 + +INFO_OFFSET = 128 +DOM_OFFSET = 0 +DOM_OFFSET1 = 384 + +cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)', + 'Length OM1(m)', 'Length Cable Assembly(m)') + +compliance_code_tup = ( + '10/40G Ethernet Compliance Code', + 'SONET Compliance codes', + 'SAS/SATA compliance codes', + 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', + 'Fibre Channel Speed') + +info_dict_keys = ['type', 'hardwarerev', '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': [DOM_OFFSET, 2, 1, 'parse_dom_status_indicator'], + 'rx_los': [DOM_OFFSET, 3, 1, 'parse_dom_tx_rx_los'], + 'tx_fault': [DOM_OFFSET, 4, 1, 'parse_dom_tx_fault'], + 'tx_disable': [DOM_OFFSET, 86, 1, 'parse_dom_tx_disable'], + 'power_lpmode': [DOM_OFFSET, 93, 1, 'parse_dom_power_control'], + 'power_override': [DOM_OFFSET, 93, 1, 'parse_dom_power_control'], + 'Temperature': [DOM_OFFSET, 22, 2, 'parse_temperature'], + 'Voltage': [DOM_OFFSET, 26, 2, 'parse_voltage'], + 'ChannelMonitor': [DOM_OFFSET, 34, 16, 'parse_channel_monitor_params'], + + 'cable_type': [INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], + 'cable_length': [INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], + 'Connector': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'type': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'encoding': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'ext_identifier': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'ext_rateselect_compliance': + [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'nominal_bit_rate': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'specification_compliance': + [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'type_abbrv_name' : [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'manufacturename': [INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'vendor_oui': [INFO_OFFSET, 37, 3, 'parse_vendor_oui'], + 'modelname': [INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardwarerev': [INFO_OFFSET, 56, 2, 'parse_vendor_rev'], + 'serialnum': [INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'vendor_date': [INFO_OFFSET, 84, 8, 'parse_vendor_date'], + 'ModuleThreshold': [DOM_OFFSET1, 128, 24, 'parse_module_threshold_values'], + 'ChannelThreshold': [DOM_OFFSET1, 176, 16, 'parse_channel_threshold_values'], +} + + +class Sfp(SfpBase): + """ + DELLEMC Platform-specific Sfp class + """ + + def __init__(self, index, sfp_type, eeprom_path, + sfp_control, sfp_ctrl_idx): + SfpBase.__init__(self) + self.sfp_type = sfp_type + self.index = index + self.eeprom_path = eeprom_path + self.sfp_control = sfp_control + self.sfp_ctrl_idx = sfp_ctrl_idx + self.sfpInfo = sff8436InterfaceId() + self.sfpDomInfo = sff8436Dom() + + 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.sfpInfo is None): + return None + + 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): + eeprom_data = getattr( + self.sfpInfo, sff8436_parser[eeprom_key][FUNC_NAME])( + eeprom_data_raw, 0) + else: + eeprom_data = getattr( + self.sfpDomInfo, sff8436_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'] + bit_rate = str( + iface_data['data']['Nominal Bit Rate(100Mbs)']['value']) + + for key in 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 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 None + + # 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 (module_threshold_data is not None): + tempHighAlarm = module_threshold_data['data']['TempHighAlarm']['value'] + tempLowAlarm = module_threshold_data['data']['TempLowAlarm']['value'] + tempHighWarn = module_threshold_data['data']['TempHighWarning']['value'] + tempLowWarn = module_threshold_data['data']['TempLowWarning']['value'] + vccHighAlarm = module_threshold_data['data']['VccHighAlarm']['value'] + vccLowAlarm = module_threshold_data['data']['VccLowAlarm']['value'] + vccHighWarn = module_threshold_data['data']['VccHighWarning']['value'] + vccLowWarn = module_threshold_data['data']['VccLowWarning']['value'] + else: + return transceiver_dom_threshold_dict + + # Channel Threshold + channel_threshold_data = self._get_eeprom_data('ChannelThreshold') + if (channel_threshold_data is not None): + rxPowerHighAlarm = channel_threshold_data['data']['RxPowerHighAlarm']['value'] + rxPowerLowAlarm = channel_threshold_data['data']['RxPowerLowAlarm']['value'] + rxPowerHighWarn = channel_threshold_data['data']['RxPowerHighWarning']['value'] + rxPowerLowWarn = channel_threshold_data['data']['RxPowerLowWarning']['value'] + txBiasHighAlarm = channel_threshold_data['data']['TxBiasHighAlarm']['value'] + txBiasLowAlarm = channel_threshold_data['data']['TxBiasLowAlarm']['value'] + txBiasHighWarn = channel_threshold_data['data']['TxBiasHighWarning']['value'] + txBiasLowWarn = channel_threshold_data['data']['TxBiasLowWarning']['value'] + else: + return transceiver_dom_threshold_dict + + transceiver_dom_threshold_dict['temphighalarm'] = tempHighAlarm + transceiver_dom_threshold_dict['templowalarm'] = tempLowAlarm + transceiver_dom_threshold_dict['temphighwarning'] = tempHighWarn + transceiver_dom_threshold_dict['templowwarning'] = tempLowWarn + transceiver_dom_threshold_dict['vcchighalarm'] = vccHighAlarm + transceiver_dom_threshold_dict['vcclowalarm'] = vccLowAlarm + transceiver_dom_threshold_dict['vcchighwarning'] = vccHighWarn + transceiver_dom_threshold_dict['vcclowwarning'] = vccLowWarn + transceiver_dom_threshold_dict['rxpowerhighalarm'] = rxPowerHighAlarm + transceiver_dom_threshold_dict['rxpowerlowalarm'] = rxPowerLowAlarm + transceiver_dom_threshold_dict['rxpowerhighwarning'] = rxPowerHighWarn + transceiver_dom_threshold_dict['rxpowerlowwarning'] = rxPowerLowWarn + transceiver_dom_threshold_dict['txbiashighalarm'] = txBiasHighAlarm + transceiver_dom_threshold_dict['txbiaslowalarm'] = txBiasLowAlarm + transceiver_dom_threshold_dict['txbiashighwarning'] = txBiasHighWarn + transceiver_dom_threshold_dict['txbiaslowwarning'] = txBiasLowWarn + + 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 + channel_monitor_data = self._get_eeprom_data('ChannelMonitor') + if (channel_monitor_data is not None): + tx_bias = channel_monitor_data['data']['TX1Bias']['value'] + tx_bias_list.append(tx_bias) + tx_bias = channel_monitor_data['data']['TX2Bias']['value'] + tx_bias_list.append(tx_bias) + tx_bias = channel_monitor_data['data']['TX3Bias']['value'] + tx_bias_list.append(tx_bias) + tx_bias = channel_monitor_data['data']['TX4Bias']['value'] + tx_bias_list.append(tx_bias) + rx_power = channel_monitor_data['data']['RX1Power']['value'] + rx_power_list.append(rx_power) + rx_power = channel_monitor_data['data']['RX2Power']['value'] + rx_power_list.append(rx_power) + rx_power = channel_monitor_data['data']['RX3Power']['value'] + rx_power_list.append(rx_power) + rx_power = channel_monitor_data['data']['RX4Power']['value'] + rx_power_list.append(rx_power) + else: + return transceiver_dom_dict + + 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 + 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] + 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] + + 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 + """ + presence_ctrl = self.sfp_control + 'qsfp_modprs' + try: + reg_file = open(presence_ctrl) + except IOError as e: + return False + + reg_hex = reg_file.readline().rstrip() + + # content is a string containing the hex + # representation of the register + reg_value = int(reg_hex, 16) + + # Mask off the bit corresponding to our port + mask = (1 << self.sfp_ctrl_idx) + + # 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): + """ + Retrieves the reset status of SFP + """ + reset_status = None + reset_ctrl = self.sfp_control + 'qsfp_reset' + try: + reg_file = open(reset_ctrl, "r+") + except IOError as e: + return False + + reg_hex = reg_file.readline().rstrip() + + # content is a string containing the hex + # representation of the register + reg_value = int(reg_hex, 16) + + # Mask off the bit corresponding to our port + index = self.sfp_ctrl_idx + + mask = (1 << index) + + 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 = [] + + 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 + + return rx_los + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + """ + tx_fault = None + tx_fault_list = [] + + tx_fault_data = self._get_eeprom_data('tx_fault') + if (tx_fault_data is not None): + tx_fault = tx_fault_data['data']['Tx1Fault']['value'] + if (tx_fault is 'On'): + 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 + + return tx_fault + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + """ + tx_disable = None + tx_disable_list = [] + + tx_disable_data = self._get_eeprom_data('tx_disable') + if (tx_disable_data is not None): + tx_disable = tx_disable_data['data']['Tx1Disable']['value'] + if (tx_disable is 'On'): + 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 + + 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_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) status of this SFP + """ + lpmode_ctrl = self.sfp_control + 'qsfp_lpmode' + try: + reg_file = open(lpmode_ctrl, "r+") + except IOError as e: + return False + + reg_hex = reg_file.readline().rstrip() + + # content is a string containing the hex + # representation of the register + reg_value = int(reg_hex, 16) + + # Mask off the bit corresponding to our port + index = self.sfp_ctrl_idx + + mask = (1 << index) + + 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 = None + + # Reset Status + 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): + 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) + + 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): + 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) + + return rx_power_list + + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + """ + tx_power = None + tx_power_list = [] + + tx_power_list.append('-infdBm') + tx_power_list.append('-infdBm') + tx_power_list.append('-infdBm') + tx_power_list.append('-infdBm') + + return tx_power_list + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + """ + reset_ctrl = self.sfp_control + 'qsfp_reset' + try: + # Open reset_ctrl in both read & write mode + reg_file = open(reset_ctrl, "r+") + except IOError as e: + return False + + reg_hex = reg_file.readline().rstrip() + reg_value = int(reg_hex, 16) + + # Mask off the bit corresponding to our port + index = self.sfp_ctrl_idx + + # Mask off the bit corresponding to our port + mask = (1 << index) + + # ResetL is active low + reg_value = (reg_value & ~mask) + + # Convert our register value back to a + # hex string and write back + reg_file.seek(0) + reg_file.write(hex(reg_value)) + 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(reset_ctrl, "w") + except IOError as e: + return False + + reg_value = reg_value | mask + reg_file.seek(0) + reg_file.write(hex(reg_value)) + reg_file.close() + + return True + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + """ + lpmode_ctrl = self.sfp_control + 'qsfp_lpmode' + try: + reg_file = open(lpmode_ctrl, "r+") + except IOError as e: + return False + + reg_hex = reg_file.readline().rstrip() + + # content is a string containing the hex + # representation of the register + reg_value = int(reg_hex, 16) + + # Mask off the bit corresponding to our port + index = self.sfp_ctrl_idx + + mask = (1 << index) + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + reg_value = (reg_value | mask) + else: + reg_value = (reg_value & ~mask) + + # Convert our register value back to a hex string and write back + content = hex(reg_value) + + reg_file.seek(0) + reg_file.write(content) + reg_file.close() + + return True + + 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 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/s6000/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py new file mode 100644 index 000000000000..70bac0c729d2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py @@ -0,0 +1,217 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC S6000 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Thermals' information which are available in the platform +# +######################################################################## + + +try: + import os + from sonic_platform_base.thermal_base import ThermalBase + from sonic_platform.psu import Psu +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Thermal(ThermalBase): + """DellEMC Platform-specific Thermal class""" + + I2C_DIR = "/sys/class/i2c-adapter/" + I2C_DEV_MAPPING = (['i2c-11/11-004c/hwmon/', 1], + ['i2c-11/11-004d/hwmon/', 1], + ['i2c-11/11-004e/hwmon/', 1], + ['i2c-10/10-0018/hwmon/', 1], + ['i2c-1/1-0059/hwmon/', 1], + ['i2c-1/1-0059/hwmon/', 2], + ['i2c-1/1-0058/hwmon/', 1], + ['i2c-1/1-0058/hwmon/', 2]) + THERMAL_NAME = ('ASIC On-board', 'NIC', 'System Front', 'DIMM', + 'PSU1-Sensor 1', 'PSU1-Sensor 2', 'PSU2-Sensor 1', + 'PSU2-Sensor 2', 'CPU Core 0', 'CPU Core 1') + + def __init__(self, thermal_index): + self.index = thermal_index + 1 + self.is_psu_thermal = False + self.dependency = None + + if self.index < 9: + i2c_path = self.I2C_DIR + self.I2C_DEV_MAPPING[self.index - 1][0] + hwmon_temp_index = self.I2C_DEV_MAPPING[self.index - 1][1] + hwmon_temp_suffix = "max" + hwmon_node = os.listdir(i2c_path)[0] + self.HWMON_DIR = i2c_path + hwmon_node + '/' + + if self.index == 4: + hwmon_temp_suffix = "crit" + + if self.index > 4: + self.is_psu_thermal = True + self.dependency = Psu(self.index / 7) + else: + dev_path = "/sys/devices/platform/coretemp.0/hwmon/" + hwmon_temp_index = self.index - 7 + hwmon_temp_suffix = "crit" + hwmon_node = os.listdir(dev_path)[0] + self.HWMON_DIR = dev_path + hwmon_node + '/' + + self.thermal_temperature_file = self.HWMON_DIR \ + + "temp{}_input".format(hwmon_temp_index) + self.thermal_high_threshold_file = self.HWMON_DIR \ + + "temp{}_{}".format(hwmon_temp_index, hwmon_temp_suffix) + self.thermal_low_threshold_file = self.HWMON_DIR \ + + "temp{}_min".format(hwmon_temp_index) + + def _read_sysfs_file(self, sysfs_file): + # On successful read, returns the value read from given + # sysfs_file and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(sysfs_file)): + return rv + + try: + with open(sysfs_file, 'r') as fd: + rv = fd.read() + except: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def get_name(self): + """ + Retrieves the name of the thermal + + Returns: + string: The name of the thermal + """ + return self.THERMAL_NAME[self.index - 1] + + def get_presence(self): + """ + Retrieves the presence of the thermal + + Returns: + bool: True if thermal is present, False if not + """ + if self.dependency: + return self.dependency.get_presence() + else: + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the Thermal + + Returns: + string: Model/part number of Thermal + """ + return 'NA' + + def get_serial(self): + """ + Retrieves the serial number of the Thermal + + Returns: + string: Serial number of Thermal + """ + return 'NA' + + def get_status(self): + """ + Retrieves the operational status of the thermal + + Returns: + A boolean value, True if thermal is operating properly, + False if not + """ + if self.dependency: + return self.dependency.get_status() + else: + return True + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + Returns: + A float number of current temperature in Celsius up to + nearest thousandth of one degree Celsius, e.g. 30.125 + """ + thermal_temperature = self._read_sysfs_file( + self.thermal_temperature_file) + if (thermal_temperature != 'ERR'): + thermal_temperature = float(thermal_temperature) / 1000 + else: + thermal_temperature = 0 + + return "{:.3f}".format(thermal_temperature) + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + + Returns: + A float number, the high threshold temperature of thermal in + Celsius up to nearest thousandth of one degree Celsius, + e.g. 30.125 + """ + thermal_high_threshold = self._read_sysfs_file( + self.thermal_high_threshold_file) + if (thermal_high_threshold != 'ERR'): + thermal_high_threshold = float(thermal_high_threshold) / 1000 + else: + thermal_high_threshold = 0 + + return "{:.3f}".format(thermal_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 + """ + 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 + else: + thermal_low_threshold = 0 + + return "{:.3f}".format(thermal_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/s6100/scripts/s6100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh index b47b98e58f99..d8b13ca02c1e 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh @@ -109,8 +109,8 @@ switch_board_qsfp_mux() { #Attach/Detach the SFP modules on PCA9548_2 switch_board_sfp() { case $1 in - "new_device") i2c_config "echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-11/$1" - i2c_config "echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-12/$1" + "new_device") i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-11/$1" + i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-12/$1" ;; "delete_device") i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-11/$1" i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-12/$1" @@ -125,7 +125,7 @@ qsfp_device_mod() { case $1 in "new_device") for ((i=$2;i<=$3;i++)); do - i2c_config "echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" + i2c_config "echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" done ;; "delete_device") for ((i=$2;i<=$3;i++)); @@ -217,6 +217,24 @@ reset_muxes() { io_rd_wr.py --set --val 0xff --offset 0x20b } +track_reboot_reason() { + if [[ -d /sys/devices/platform/SMF.512/hwmon/ ]]; then + rv=$(cd /sys/devices/platform/SMF.512/hwmon/*; cat mb_poweron_reason) + reason=$(echo $rv | cut -d 'x' -f2) + if [ $reason == "ff" ]; then + cd /sys/devices/platform/SMF.512/hwmon/* + if [[ -e /tmp/notify_firstboot_to_platform ]]; then + echo 0x01 > mb_poweron_reason + else + echo 0xbb > mb_poweron_reason + fi + elif [ $reason == "bb" ] || [ $reason == "1" ]; then + cd /sys/devices/platform/SMF.512/hwmon/* + echo 0xaa > mb_poweron_reason + fi + fi +} + install_python_api_package() { device="/usr/share/sonic/device" platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) @@ -239,6 +257,7 @@ if [[ "$1" == "init" ]]; then modprobe dell_ich modprobe dell_s6100_iom_cpld modprobe dell_s6100_lpc + track_reboot_reason # Disable Watchdog Timer if [[ -e /usr/local/bin/platform_watchdog_disable.sh ]]; then diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/__init__.py index 61b486d775b7..96de5a93c4c2 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/__init__.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/__init__.py @@ -1,3 +1,3 @@ -__all__ = ["platform", "chassis", "fan", "psu", "sfp"] +__all__ = ["platform", "chassis", "module", "fan", "psu", "sfp", "thermal"] from sonic_platform import * diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py index 53d4eadaec0a..e39e8480e2c7 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py @@ -10,16 +10,23 @@ try: import os + from sonic_platform_base.platform_base import PlatformBase from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.sfp import Sfp from sonic_platform.psu import Psu from sonic_platform.fan import Fan + from sonic_platform.module import Module + from sonic_platform.thermal import Thermal + from sonic_platform.component import Component from eeprom import Eeprom except ImportError as e: raise ImportError(str(e) + "- required module not found") +MAX_S6100_MODULE = 4 MAX_S6100_FAN = 4 MAX_S6100_PSU = 2 +MAX_S6100_THERMAL = 10 +MAX_S6100_COMPONENT = 3 class Chassis(ChassisBase): @@ -31,39 +38,6 @@ class Chassis(ChassisBase): HWMON_NODE = os.listdir(HWMON_DIR)[0] MAILBOX_DIR = HWMON_DIR + HWMON_NODE - PORT_START = 0 - PORT_END = 63 - PORTS_IN_BLOCK = (PORT_END + 1) - IOM1_PORT_START = 0 - IOM2_PORT_START = 16 - IOM3_PORT_START = 32 - IOM4_PORT_START = 48 - - PORT_I2C_MAPPING = {} - # 0th Index = i2cLine, 1st Index = EepromIdx in i2cLine - EEPROM_I2C_MAPPING = { - # IOM 1 - 0: [6, 66], 1: [6, 67], 2: [6, 68], 3: [6, 69], - 4: [6, 70], 5: [6, 71], 6: [6, 72], 7: [6, 73], - 8: [6, 74], 9: [6, 75], 10: [6, 76], 11: [6, 77], - 12: [6, 78], 13: [6, 79], 14: [6, 80], 15: [6, 81], - # IOM 2 - 16: [8, 50], 17: [8, 51], 18: [8, 52], 19: [8, 53], - 20: [8, 54], 21: [8, 55], 22: [8, 56], 23: [8, 57], - 24: [8, 58], 25: [8, 59], 26: [8, 60], 27: [8, 61], - 28: [8, 62], 29: [8, 63], 30: [8, 64], 31: [8, 65], - # IOM 3 - 32: [7, 34], 33: [7, 35], 34: [7, 36], 35: [7, 37], - 36: [7, 38], 37: [7, 39], 38: [7, 40], 39: [7, 41], - 40: [7, 42], 41: [7, 43], 42: [7, 44], 43: [7, 45], - 44: [7, 46], 45: [7, 47], 46: [7, 48], 47: [7, 49], - # IOM 4 - 48: [9, 18], 49: [9, 19], 50: [9, 20], 51: [9, 21], - 52: [9, 22], 53: [9, 23], 54: [9, 24], 55: [9, 25], - 56: [9, 26], 57: [9, 27], 58: [9, 28], 59: [9, 29], - 60: [9, 30], 61: [9, 31], 62: [9, 32], 63: [9, 33] - } - reset_reason_dict = {} reset_reason_dict[11] = ChassisBase.REBOOT_CAUSE_POWER_LOSS reset_reason_dict[33] = ChassisBase.REBOOT_CAUSE_WATCHDOG @@ -81,6 +55,10 @@ def __init__(self): ChassisBase.__init__(self) # Initialize EEPROM self.sys_eeprom = Eeprom() + for i in range(MAX_S6100_MODULE): + module = Module(i) + self._module_list.append(module) + for i in range(MAX_S6100_FAN): fan = Fan(i) self._fan_list.append(fan) @@ -89,38 +67,20 @@ def __init__(self): psu = Psu(i) self._psu_list.append(psu) - self._populate_port_i2c_mapping() - - # sfp.py will read eeprom contents and retrive the eeprom data. - # It will also provide support sfp controls like reset and setting - # low power mode. - # We pass the eeprom path and sfp control path from chassis.py - # So that sfp.py implementation can be generic to all platforms - eeprom_base = "/sys/class/i2c-adapter/i2c-{0}/i2c-{1}/{1}-0050/eeprom" - sfp_ctrl_base = "/sys/class/i2c-adapter/i2c-{0}/{0}-003e/" - for index in range(0, self.PORTS_IN_BLOCK): - eeprom_path = eeprom_base.format(self.EEPROM_I2C_MAPPING[index][0], - self.EEPROM_I2C_MAPPING[index][1]) - sfp_control = sfp_ctrl_base.format(self.PORT_I2C_MAPPING[index]) - sfp_node = Sfp(index, 'QSFP', eeprom_path, sfp_control, index) - self._sfp_list.append(sfp_node) - - def _populate_port_i2c_mapping(self): - # port_num and i2c match - for port_num in range(0, self.PORTS_IN_BLOCK): - if((port_num >= self.IOM1_PORT_START) and - (port_num < self.IOM2_PORT_START)): - i2c_line = 14 - elif((port_num >= self.IOM2_PORT_START) and - (port_num < self.IOM3_PORT_START)): - i2c_line = 16 - elif((port_num >= self.IOM3_PORT_START) and - (port_num = self.IOM4_PORT_START) and - (port_num < self.PORTS_IN_BLOCK)): - i2c_line = 17 - self.PORT_I2C_MAPPING[port_num] = i2c_line + for i in range(MAX_S6100_THERMAL): + thermal = Thermal(i) + self._thermal_list.append(thermal) + + for i in range(MAX_S6100_COMPONENT): + component = Component(i) + self._component_list.append(component) + + def _get_reboot_reason_smf_register(self): + # Returns 0xAA on software reload + # Returns 0xFF on power-cycle + # Returns 0x01 on first-boot + smf_mb_reg_reason = self._get_pmc_register('mb_poweron_reason') + return int(smf_mb_reg_reason, 16) def _get_pmc_register(self, reg_name): # On successful read, returns the value read from given @@ -143,36 +103,45 @@ def _get_pmc_register(self, reg_name): def get_name(self): """ - Retrieves the name of the device + Retrieves the name of the chassis Returns: - string: The name of the device + string: The name of the chassis """ return self.sys_eeprom.modelstr() def get_presence(self): """ - Retrieves the presence of the device + Retrieves the presence of the chassis Returns: - bool: True if device is present, False if not + bool: True if chassis is present, False if not """ return True def get_model(self): """ - Retrieves the model number (or part number) of the device + Retrieves the model number (or part number) of the chassis Returns: - string: Model/part number of device + string: Model/part number of chassis """ return self.sys_eeprom.part_number_str() def get_serial(self): """ - Retrieves the serial number of the device (Service tag) + Retrieves the serial number of the chassis (Service tag) Returns: - string: Serial number of device + string: Serial number of chassis """ return self.sys_eeprom.serial_str() + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + def get_base_mac(self): """ Retrieves the base MAC address for the chassis @@ -188,7 +157,8 @@ def get_serial_number(self): Retrieves the hardware serial number for the chassis Returns: - A string containing the hardware serial number for this chassis. + A string containing the hardware serial number for this + chassis. """ return self.sys_eeprom.serial_number_str() @@ -200,6 +170,7 @@ def get_system_eeprom_info(self): OCP ONIE TlvInfo EEPROM format and values are their corresponding values. """ + return self.sys_eeprom.system_eeprom_info() def get_reboot_cause(self): """ @@ -214,6 +185,10 @@ def get_reboot_cause(self): reset_reason = int(self._get_pmc_register('smf_reset_reason')) power_reason = int(self._get_pmc_register('smf_poweron_reason')) + smf_mb_reg_reason = self._get_reboot_reason_smf_register() + + if ((smf_mb_reg_reason == 0x01) and (power_reason == 0x11)): + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) # Reset_Reason = 11 ==> PowerLoss # So return the reboot reason from Last Power_Reason Dictionary @@ -222,10 +197,16 @@ def get_reboot_cause(self): # checking key presence in dictionary else return # REBOOT_CAUSE_HARDWARE_OTHER as the Power_Reason and Reset_Reason # registers returned invalid data + + # In S6100, if Reset_Reason is not 11 and smf_mb_reg_reason + # is ff or bb, then it is PowerLoss if (reset_reason == 11): if (power_reason in self.power_reason_dict): return (self.power_reason_dict[power_reason], None) else: + if ((smf_mb_reg_reason == 0xbb) or (smf_mb_reg_reason == 0xff)): + return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) + if (reset_reason in self.reset_reason_dict): return (self.reset_reason_dict[reset_reason], None) diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/component.py new file mode 100644 index 000000000000..a92ab5c85db2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/component.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python + +######################################################################## +# DELLEMC S6100 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in +# the platform +# +######################################################################## + +try: + import os + import subprocess + from sonic_platform_base.component_base import ComponentBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +BIOS_QUERY_VERSION_COMMAND = "dmidecode -s system-version" + + +class Component(ComponentBase): + """DellEMC Platform-specific Component class""" + + HWMON_DIR = "/sys/devices/platform/SMF.512/hwmon/" + HWMON_NODE = os.listdir(HWMON_DIR)[0] + MAILBOX_DIR = HWMON_DIR + HWMON_NODE + + CHASSIS_COMPONENTS = [ + ["BIOS", ("Performs initialization of hardware components during " + "booting")], + ["CPLD", "Used for managing IO modules, SFP+ modules and system LEDs"], + ["FPGA", ("Platform management controller for on-board temperature " + "monitoring, in-chassis power, Fan and LED control")] + ] + MODULE_COMPONENT = [ + "IOM{}-CPLD", + "Used for managing QSFP+ modules ({0}-{1})" + ] + + def __init__(self, component_index=0, + is_module=False, iom_index=0, i2c_line=0): + + self.is_module_component = is_module + + if self.is_module_component: + self.index = iom_index + self.name = self.MODULE_COMPONENT[0].format(self.index) + self.description = self.MODULE_COMPONENT[1].format( + ((self.index - 1) * 16) + 1, self.index * 16) + self.cpld_version_file = ("/sys/class/i2c-adapter/i2c-{0}/{0}-003e" + "/iom_cpld_vers").format(i2c_line) + else: + self.index = component_index + self.name = self.CHASSIS_COMPONENTS[self.index][0] + self.description = self.CHASSIS_COMPONENTS[self.index][1] + + def _read_sysfs_file(self, sysfs_file): + # On successful read, returns the value read from given + # sysfs_file and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(sysfs_file)): + return rv + + try: + with open(sysfs_file, 'r') as fd: + rv = fd.read() + except Exception as error: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def _get_command_result(self, cmdline): + try: + proc = subprocess.Popen(cmdline.split(), stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + result = stdout.rstrip('\n') + except OSError: + result = None + + return result + + def _get_cpld_version(self): + io_resource = "/dev/port" + CPLD_VERSION_ADDR = 0x100 + + fd = os.open(io_resource, os.O_RDONLY) + if (fd < 0): + return 'NA' + + if (os.lseek(fd, CPLD_VERSION_ADDR, os.SEEK_SET) != CPLD_VERSION_ADDR): + os.close(fd) + return 'NA' + + buf = os.read(fd, 1) + cpld_version = str(ord(buf)) + os.close(fd) + + return cpld_version + + def _get_iom_cpld_version(self): + ver_str = self._read_sysfs_file(self.cpld_version_file) + if (ver_str != 'ERR'): + if ver_str == 'read error': + return 'NA' + + ver_str = ver_str.rstrip('\r\n') + cpld_version = str(int(ver_str.split(':')[1], 16)) + return cpld_version + else: + return 'NA' + + def _get_fpga_version(self): + fpga_ver_file = self.MAILBOX_DIR + '/smf_firmware_ver' + fpga_ver = self._read_sysfs_file(fpga_ver_file) + if (fpga_ver != 'ERR'): + return fpga_ver + else: + return 'NA' + + def get_name(self): + """ + Retrieves the name of the component + + Returns: + A string containing the name of the component + """ + return self.name + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + if self.is_module_component: # IOM CPLD + return self._get_iom_cpld_version() + else: + if self.index == 0: # BIOS + bios_ver = self._get_command_result(BIOS_QUERY_VERSION_COMMAND) + + if not bios_ver: + return 'NA' + else: + return bios_ver + + elif self.index == 1: # SwitchCard CPLD + return self._get_cpld_version() + elif self.index == 2: # FPGA + return self._get_fpga_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/s6100/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py index 86c314f3ef22..4e683e1e511b 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py @@ -21,11 +21,42 @@ class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): def __init__(self): self.eeprom_path = "/sys/class/i2c-adapter/i2c-2/2-0050/eeprom" super(Eeprom, self).__init__(self.eeprom_path, 0, '', True) + self.eeprom_tlv_dict = dict() try: self.eeprom_data = self.read_eeprom() 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): @@ -76,3 +107,10 @@ def revision_str(self): 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/s6100/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py index c822ccdae2b9..2aef71b756e7 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py @@ -26,7 +26,7 @@ class Fan(FanBase): HWMON_NODE = os.listdir(HWMON_DIR)[0] MAILBOX_DIR = HWMON_DIR + HWMON_NODE - def __init__(self, fantray_index, fan_index=1, psu_fan=False): + def __init__(self, fantray_index=1, fan_index=1, psu_fan=False): self.is_psu_fan = psu_fan if not self.is_psu_fan: # API index is starting from 0, DellEMC platform index is starting @@ -74,7 +74,7 @@ def get_name(self): return "FanTray{}-Fan{}".format( self.fantrayindex, self.fanindex - 1) else: - return "PSU{} Fan".format(self.index - 10) + return "PSU{} Fan".format(self.fanindex - 10) def get_model(self): """ @@ -209,7 +209,19 @@ def set_status_led(self, color): status = False return status - def get_target_speed(self): + def get_status_led(self): + """ + Gets the state of the Fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + if self.get_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + + def get_target_speed(self): """ Retrieves the target (expected) speed of the fan Returns: diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py new file mode 100644 index 000000000000..265dc206ad0c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py @@ -0,0 +1,195 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC S6100 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Modules' information which are available in the platform +# +######################################################################## + + +try: + import os + from sonic_platform_base.module_base import ModuleBase + from sonic_platform.sfp import Sfp + from sonic_platform.component import Component +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Module(ModuleBase): + """DellEMC Platform-specific Module class""" + + HWMON_DIR = "/sys/devices/platform/SMF.512/hwmon/" + HWMON_NODE = os.listdir(HWMON_DIR)[0] + MAILBOX_DIR = HWMON_DIR + HWMON_NODE + + IOM_I2C_MAPPING = { 1: 14, 2: 16, 3: 15, 4: 17 } + EEPROM_I2C_MAPPING = { + # IOM 1 + 0: [6, 66], 1: [6, 67], 2: [6, 68], 3: [6, 69], + 4: [6, 70], 5: [6, 71], 6: [6, 72], 7: [6, 73], + 8: [6, 74], 9: [6, 75], 10: [6, 76], 11: [6, 77], + 12: [6, 78], 13: [6, 79], 14: [6, 80], 15: [6, 81], + # IOM 2 + 16: [8, 34], 17: [8, 35], 18: [8, 36], 19: [8, 37], + 20: [8, 38], 21: [8, 39], 22: [8, 40], 23: [8, 41], + 24: [8, 42], 25: [8, 43], 26: [8, 44], 27: [8, 45], + 28: [8, 46], 29: [8, 47], 30: [8, 48], 31: [8, 49], + # IOM 3 + 32: [7, 50], 33: [7, 51], 34: [7, 52], 35: [7, 53], + 36: [7, 54], 37: [7, 55], 38: [7, 56], 39: [7, 57], + 40: [7, 58], 41: [7, 59], 42: [7, 60], 43: [7, 61], + 44: [7, 62], 45: [7, 63], 46: [7, 64], 47: [7, 65], + # IOM 4 + 48: [9, 18], 49: [9, 19], 50: [9, 20], 51: [9, 21], + 52: [9, 22], 53: [9, 23], 54: [9, 24], 55: [9, 25], + 56: [9, 26], 57: [9, 27], 58: [9, 28], 59: [9, 29], + 60: [9, 30], 61: [9, 31], 62: [9, 32], 63: [9, 33] + } + + def __init__(self, module_index): + # Modules are 1-based in DellEMC platforms + self.index = module_index + 1 + self.port_start = (self.index - 1) * 16 + self.port_end = (self.index * 16) - 1 + self.port_i2c_line = self.IOM_I2C_MAPPING[self.index] + self.eeprom_tlv_dict = dict() + + self.iom_status_reg = "iom_status" + self.iom_presence_reg = "iom_presence" + + # Overriding _component_list and _sfp_list class variables defined in + # ModuleBase, to make them unique per Module object + self._component_list = [] + self._sfp_list = [] + + component = Component(is_module=True, iom_index=self.index, + i2c_line=self.port_i2c_line) + self._component_list.append(component) + + eeprom_base = "/sys/class/i2c-adapter/i2c-{0}/i2c-{1}/{1}-0050/eeprom" + sfp_ctrl_base = "/sys/class/i2c-adapter/i2c-{0}/{0}-003e/" + + # sfp.py will read eeprom contents and retrive the eeprom data. + # It will also provide support sfp controls like reset and setting + # low power mode. + for index in range(self.port_start, self.port_end + 1): + eeprom_path = eeprom_base.format(self.EEPROM_I2C_MAPPING[index][0], + self.EEPROM_I2C_MAPPING[index][1]) + sfp_control = sfp_ctrl_base.format(self.port_i2c_line) + sfp_node = Sfp(index, 'QSFP', eeprom_path, sfp_control, index) + self._sfp_list.append(sfp_node) + + def _get_pmc_register(self, reg_name): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + mb_reg_file = self.MAILBOX_DIR + '/' + reg_name + + if (not os.path.isfile(mb_reg_file)): + return rv + + try: + with open(mb_reg_file, 'r') as fd: + rv = fd.read() + except Exception as error: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return "IOM{}: 16xQSFP+".format(self.index) + + def get_presence(self): + """ + Retrieves the presence of the Module + + Returns: + bool: True if Module is present, False if not + """ + status = False + iom_presence = self._get_pmc_register(self.iom_presence_reg) + if (iom_presence != 'ERR'): + iom_presence = int(iom_presence,16) + if (~iom_presence & (1 << (self.index - 1))): + status = True + + return status + + def get_model(self): + """ + Retrieves the part number of the module + + Returns: + string: part number of module + """ + return 'NA' + + def get_serial(self): + """ + Retrieves the serial number of the module + + Returns: + string: Serial number of module + """ + return 'NA' + + def get_status(self): + """ + Retrieves the operational status of the Module + + Returns: + bool: True if Module is operating properly, False if not + """ + status = False + iom_status = self._get_pmc_register(self.iom_status_reg) + if (iom_status != 'ERR'): + iom_status = int(iom_status,16) + if (~iom_status & (1 << (self.index - 1))): + status = True + + return status + + def get_base_mac(self): + """ + Retrieves the base MAC address for the module + + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + # In S6100, individual modules doesn't have MAC address + return '00:00:00:00:00:00' + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the module + + Returns: + A string containing the hardware serial number for this module. + """ + return 'NA' + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the module + + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + Ex. { ‘0x21’:’AG9064’, ‘0x22’:’V1.0’, ‘0x23’:’AG9064-0109867821’, + ‘0x24’:’001c0f000fcd0a’, ‘0x25’:’02/03/2018 16:22:00’, + ‘0x26’:’01’, ‘0x27’:’REV01’, ‘0x28’:’AG9064-C2358-16G’} + """ + return self.eeprom_tlv_dict diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/psu.py index 39ccf1b65500..18a8b5d0354d 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/psu.py @@ -1,7 +1,7 @@ #!/usr/bin/env python ######################################################################## -# DellEMC +# DellEMC S6100 # # Module contains an implementation of SONiC Platform Base API and # provides the PSUs' information which are available in the platform @@ -43,10 +43,10 @@ def __init__(self, psu_index): self._fan_list = [] # Passing True to specify it is a PSU fan - psu_fan = Fan(self.index, True) + psu_fan = Fan(fan_index=self.index, psu_fan=True) self._fan_list.append(psu_fan) - def get_pmc_register(self, reg_name): + def _get_pmc_register(self, reg_name): # On successful read, returns the value read from given # reg_name and on failure returns 'ERR' rv = 'ERR' @@ -82,7 +82,7 @@ def get_presence(self): bool: True if PSU is present, False if not """ status = False - psu_presence = self.get_pmc_register(self.psu_presence_reg) + psu_presence = self._get_pmc_register(self.psu_presence_reg) if (psu_presence != 'ERR'): psu_presence = int(psu_presence, 16) # Checking whether bit 0 is not set @@ -100,7 +100,7 @@ def get_model(self): """ # For Serial number "US-01234D-54321-25A-0123-A00", the part # number is "01234D" - psu_serialno = self.get_pmc_register(self.psu_serialno_reg) + psu_serialno = self._get_pmc_register(self.psu_serialno_reg) if (psu_serialno != 'ERR') and self.get_presence(): if (len(psu_serialno.split('-')) > 1): psu_partno = psu_serialno.split('-')[1] @@ -119,7 +119,7 @@ def get_serial(self): string: Serial number of PSU """ # Sample Serial number format "US-01234D-54321-25A-0123-A00" - psu_serialno = self.get_pmc_register(self.psu_serialno_reg) + psu_serialno = self._get_pmc_register(self.psu_serialno_reg) if (psu_serialno == 'ERR') or not self.get_presence(): psu_serialno = 'NA' @@ -133,7 +133,7 @@ def get_status(self): bool: True if PSU is operating properly, False if not """ status = False - psu_status = self.get_pmc_register(self.psu_presence_reg) + psu_status = self._get_pmc_register(self.psu_presence_reg) if (psu_status != 'ERR'): psu_status = int(psu_status, 16) # Checking whether both bit 3 and bit 2 are not set @@ -150,7 +150,7 @@ def get_voltage(self): A float number, the output voltage in volts, e.g. 12.1 """ - psu_voltage = self.get_pmc_register(self.psu_voltage_reg) + psu_voltage = self._get_pmc_register(self.psu_voltage_reg) if (psu_voltage != 'ERR') and self.get_presence(): # Converting the value returned by driver which is in # millivolts to volts @@ -168,7 +168,7 @@ def get_current(self): A float number, electric current in amperes, e.g. 15.4 """ - psu_current = self.get_pmc_register(self.psu_current_reg) + psu_current = self._get_pmc_register(self.psu_current_reg) if (psu_current != 'ERR') and self.get_presence(): # Converting the value returned by driver which is in # milliamperes to amperes @@ -186,7 +186,7 @@ def get_power(self): A float number, the power in watts, e.g. 302.6 """ - psu_power = self.get_pmc_register(self.psu_power_reg) + psu_power = self._get_pmc_register(self.psu_power_reg) if (psu_power != 'ERR') and self.get_presence(): # Converting the value returned by driver which is in # microwatts to watts @@ -196,7 +196,33 @@ def get_power(self): return psu_power - def set_status_led(self): + 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 + if self.get_status() and self._fan_list[0].get_status(): + status = True + + return status + + def get_status_led(self): + """ + Gets the state of the PSU status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + if self.get_powergood_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + + def set_status_led(self, color): """ Sets the state of the PSU status LED Args: diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/sfp.py index b312a52c7b42..e94c53b11a95 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/sfp.py @@ -195,49 +195,49 @@ def get_transceiver_info(self): cable_type = key cable_length = str(iface_data['data'][key]['value']) else: - return None + 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 None + 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 None + 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 None + 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 None + 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 None + 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 None + return transceiver_info_dict # Fill The Dictionary and return transceiver_info_dict['type'] = identifier @@ -279,7 +279,7 @@ def get_transceiver_threshold_info(self): vccHighWarn = module_threshold_data['data']['VccHighWarning']['value'] vccLowWarn = module_threshold_data['data']['VccLowWarning']['value'] else: - return None + return transceiver_dom_threshold_dict # Channel Threshold channel_threshold_data = self._get_eeprom_data('ChannelThreshold') @@ -293,7 +293,7 @@ def get_transceiver_threshold_info(self): txBiasHighWarn = channel_threshold_data['data']['TxBiasHighWarning']['value'] txBiasLowWarn = channel_threshold_data['data']['TxBiasLowWarning']['value'] else: - return None + return transceiver_dom_threshold_dict transceiver_dom_threshold_dict['temphighalarm'] = tempHighAlarm transceiver_dom_threshold_dict['templowalarm'] = tempLowAlarm @@ -367,7 +367,7 @@ def get_transceiver_bulk_status(self): rx_power = channel_monitor_data['data']['RX4Power']['value'] rx_power_list.append(rx_power) else: - return None + return transceiver_dom_dict transceiver_dom_dict['rx_los'] = rx_los transceiver_dom_dict['tx_fault'] = tx_fault @@ -418,7 +418,13 @@ def get_presence(self): reg_value = int(reg_hex, 16) # Mask off the bit corresponding to our port - mask = (1 << self.sfp_ctrl_idx) + if (self.sfp_ctrl_idx > 15): + index = self.sfp_ctrl_idx % 16 + else: + index = self.sfp_ctrl_idx + + # Mask off the bit corresponding to our port + mask = (1 << index) # ModPrsL is active low if ((reg_value & mask) == 0): @@ -849,3 +855,40 @@ def set_lpmode(self, lpmode): reg_file.close() return True + + 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 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/s6100/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/thermal.py new file mode 100644 index 000000000000..3947f4c84957 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/thermal.py @@ -0,0 +1,209 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC S6100 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Thermals' information which are available in the platform +# +######################################################################## + + +try: + import os + from sonic_platform_base.thermal_base import ThermalBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Thermal(ThermalBase): + """DellEMC Platform-specific Thermal class""" + + THERMAL_NAME = ( + 'CPU On-board', 'ASIC On-board Front', 'System Front', + 'ASIC On-board Rear', 'Front GE board', 'Front SFP+ board', + 'CPU Core 0', 'CPU Core 1', 'CPU Core 2', 'CPU Core 3' + ) + + def __init__(self, thermal_index): + self.is_cpu_thermal = False + self.index = thermal_index + 1 + + if self.index < 7: + if self.index < 5: + hwmon_temp_index = self.index + else: + hwmon_temp_index = self.index + 5 + + dev_path = "/sys/devices/platform/SMF.512/hwmon/" + else: + hwmon_temp_index = self.index - 5 + self.is_cpu_thermal = True + dev_path = "/sys/devices/platform/coretemp.0/hwmon/" + + hwmon_node = os.listdir(dev_path)[0] + self.HWMON_DIR = dev_path + hwmon_node + '/' + + self.thermal_status_file = self.HWMON_DIR \ + + "temp{}_alarm".format(hwmon_temp_index) + self.thermal_temperature_file = self.HWMON_DIR \ + + "temp{}_input".format(hwmon_temp_index) + self.thermal_high_threshold_file = self.HWMON_DIR \ + + "temp{}_crit".format(hwmon_temp_index) + self.thermal_low_threshold_file = self.HWMON_DIR \ + + "temp{}_min".format(hwmon_temp_index) + + def _read_sysfs_file(self, sysfs_file): + # On successful read, returns the value read from given + # sysfs_file and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(sysfs_file)): + return rv + + try: + with open(sysfs_file, 'r') as fd: + rv = fd.read() + except Exception as error: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def get_name(self): + """ + Retrieves the name of the thermal + + Returns: + string: The name of the thermal + """ + return self.THERMAL_NAME[self.index - 1] + + def get_presence(self): + """ + Retrieves the presence of the thermal + + Returns: + bool: True if thermal is present, False if not + """ + 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 + """ + status = False + if self.is_cpu_thermal: + status = True + else: + thermal_status = self._read_sysfs_file(self.thermal_status_file) + if (thermal_status != 'ERR'): + thermal_status = int(thermal_status, 16) + if thermal_status != 5: + status = True + + return status + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + Returns: + A float number of current temperature in Celsius up to + nearest thousandth of one degree Celsius, e.g. 30.125 + """ + thermal_temperature = self._read_sysfs_file( + self.thermal_temperature_file) + if (thermal_temperature != 'ERR'): + thermal_temperature = float(thermal_temperature) / 1000 + else: + thermal_temperature = 0 + + return "{:.3f}".format(thermal_temperature) + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + + Returns: + A float number, the high threshold temperature of thermal in + Celsius up to nearest thousandth of one degree Celsius, + e.g. 30.125 + """ + thermal_high_threshold = self._read_sysfs_file( + self.thermal_high_threshold_file) + if (thermal_high_threshold != 'ERR'): + thermal_high_threshold = float(thermal_high_threshold) / 1000 + else: + thermal_high_threshold = 0 + + return "{:.3f}".format(thermal_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 + """ + 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 + else: + thermal_low_threshold = 0 + + return "{:.3f}".format(thermal_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/s6100/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/watchdog.py new file mode 100644 index 000000000000..207ccb8971bc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/watchdog.py @@ -0,0 +1,227 @@ +#!/usr/bin/env python + +######################################################################## +# +# DELLEMC S6100 +# +# Abstract base class for implementing a platform-specific class with +# which to interact with a hardware watchdog module in SONiC +# +######################################################################## + +try: + import os + import struct + import ctypes + 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 + """ + + io_resource = '/dev/port' + + WD_STATUS_OFFSET = 0x207 + WD_TIMER_OFFSET = 0x206 + WD_ENABLE = 0 + WD_DISABLE = 1 + + 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 _io_reg_read(self, offset): + """ + Read the resource file + """ + fd = os.open(self.io_resource, os.O_RDONLY) + if fd < 0: + return -1 + + if os.lseek(fd, offset, os.SEEK_SET) != offset: + os.close(fd) + return -1 + + buf = os.read(fd, 1) + reg_value = ord(buf) + + os.close(fd) + return reg_value + + def _io_reg_write(self, offset, val): + """ + Write in the resource file + """ + fd = os.open(self.io_resource, os.O_RDWR) + if fd < 0: + return -1 + + if os.lseek(fd, offset, os.SEEK_SET) != offset: + os.close(fd) + return -1 + + ret = os.write(fd, struct.pack('B', val)) + if ret != 1: + os.close(fd) + return -1 + + os.close(fd) + return ret + + def _read_gpio_file(self, file_path): + """ + Read the GPIO values + """ + fd = os.open(file_path, os.O_RDONLY) + read_str = os.read(fd, os.path.getsize(file_path)) + gpio_val = int(read_str, 16) + os.close(fd) + return gpio_val + + def _write_gpio_file(self, file_path, val): + """ + Write the GPIO values + """ + fd = os.open(file_path, os.O_RDWR) + ret = os.write(fd, val) + if ret < 0: + os.close(fd) + return -1 + + os.close(fd) + return 1 + + def _get_time(self): + """ + To get clock monotonic time + """ + ts = _timespec() + if self._clock_gettime(self.CLOCK_MONOTONIC, ctypes.pointer(ts)) != 0: + 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. + """ + gpio = "/sys/devices/platform/dell_ich.0/sc_gp_lvl" + timer_offset = -1 + if seconds <= 30: + timer_offset = 1 + seconds = 30 + elif seconds > 30 and seconds <= 60: + timer_offset = 2 + seconds = 60 + elif seconds > 60 and seconds <= 180: + timer_offset = 3 + seconds = 180 + + if timer_offset == -1: + return -1 + if self._io_reg_read(self.WD_TIMER_OFFSET) != timer_offset: + if self._io_reg_write(self.WD_TIMER_OFFSET, timer_offset) == -1: + return -1 + self.disarm() + + if self.is_armed(): + gpio_val = self._read_gpio_file(gpio) + high_val = gpio_val | (1 << 15) + if self._write_gpio_file(gpio, hex(high_val)) != -1: + low_val = high_val & 0xFFFF7FFF + if self._write_gpio_file(gpio, hex(low_val)) != -1: + self.armed_time = self._get_time() + self.timeout = seconds + return seconds + elif self._io_reg_write(self.WD_STATUS_OFFSET, self.WD_ENABLE) != -1: + self.armed_time = self._get_time() + self.timeout = seconds + return seconds + + return -1 + + def disarm(self): + """ + Disarm the hardware watchdog + + Returns: + A boolean, True if watchdog is disarmed successfully, False + if not + """ + if self._io_reg_write(self.WD_STATUS_OFFSET, self.WD_DISABLE) != -1: + 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 + """ + wd_status = self.WD_DISABLE + wd_status = self._io_reg_read(self.WD_STATUS_OFFSET) + if wd_status == self.WD_ENABLE: + return True + + return False + + 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. + + S6100 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/tools/0002-Flashrom-support-for-Intel-Rangeley-and-Denverton-CP.patch b/platform/broadcom/sonic-platform-modules-dell/tools/0002-Flashrom-support-for-Intel-Rangeley-and-Denverton-CP.patch new file mode 100644 index 000000000000..ab77df9c4d3b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/tools/0002-Flashrom-support-for-Intel-Rangeley-and-Denverton-CP.patch @@ -0,0 +1,8510 @@ +From 482e06109190eb918208820fd94c8f4a6963f77e Mon Sep 17 00:00:00 2001 +From: paavaanan +Date: Tue, 21 May 2019 10:40:59 -0400 +Subject: [PATCH] Intel-Rangeley-stripped-code-changes + +--- + 82802ab.c | 1 + + Makefile | 109 +++- + README | 26 +- + at45db.c | 562 ++++++++++++++++ + atahpt.c | 2 + + board_enable.c | 19 +- + buspirate_spi.c | 7 +- + cbtable.c | 7 +- + chipdrivers.h | 21 +- + chipset_enable.c | 610 +++++++++++------ + cli_classic.c | 40 +- + dmi.c | 332 ++++++++-- + dnv_smi_spi.c | 185 ++++++ + drkaiser.c | 14 +- + flash.h | 56 +- + flashchips.c | 791 +++++++++++++++++++---- + flashchips.h | 27 +- + flashrom.c | 162 ++++- + ft2232_spi.c | 6 + + gfxnvidia.c | 14 +- + hwaccess.h | 6 + + ich_descriptors.c | 104 +++ + ich_descriptors.h | 104 +++ + ichspi.c | 557 ++++++++++++++-- + internal.c | 5 +- + it85spi.c | 3 + + it87spi.c | 47 +- + layout.c | 126 +++- + linux_spi.c | 12 +- + mcp6x_spi.c | 15 +- + nic3com.c | 2 + + nicintel.c | 29 +- + nicintel_spi.c | 26 +- + nicnatsemi.c | 2 + + nicrealtek.c | 2 + + ogp_spi.c | 14 +- + pcidev.c | 2 +- + physmap.c | 170 +++-- + pony_spi.c | 1 + + print.c | 15 +- + programmer.h | 28 +- + rayer_spi.c | 196 ++++-- + satamv.c | 19 +- + satasii.c | 18 +- + sb600spi.c | 208 +++++- + serial.c | 113 ++-- + serprog.c | 165 +++-- + spi25.c | 35 +- + spi25_statusreg.c | 2 +- + stm50.c | 115 ++++ + udelay.c | 10 +- + util/getrevision.sh | 311 +++++++++ + util/ich_descriptors_tool/ich_descriptors_tool.c | 8 +- + util/z60_flashrom.rules | 4 + + 54 files changed, 4553 insertions(+), 912 deletions(-) + create mode 100644 at45db.c + create mode 100644 dnv_smi_spi.c + create mode 100644 stm50.c + create mode 100755 util/getrevision.sh + +diff --git a/82802ab.c b/82802ab.c +index 608995d..2a43813 100644 +--- a/82802ab.c ++++ b/82802ab.c +@@ -89,6 +89,7 @@ int probe_82802ab(struct flashctx *flash) + return 1; + } + ++/* FIXME: needs timeout */ + uint8_t wait_82802ab(struct flashctx *flash) + { + uint8_t status; +diff --git a/Makefile b/Makefile +index 6e41e5d..d66039a 100644 +--- a/Makefile ++++ b/Makefile +@@ -39,6 +39,7 @@ CFLAGS ?= -Os -Wall -Wshadow + EXPORTDIR ?= . + AR ?= ar + RANLIB ?= ranlib ++DOSLIBS_BASE ?= .. + # The following parameter changes the default programmer that will be used if there is no -p/--programmer + # argument given when running flashrom. The predefined setting does not enable any default so that every + # user has to declare the programmer he wants to use on every run. The rationale for this to be not set +@@ -50,7 +51,8 @@ RANLIB ?= ranlib + # values are those specified in enum programmer in programmer.h (which depend on other CONFIG_* options + # evaluated below, namely those that enable/disable the various programmers). + # Compilation will fail for unspecified values. +-CONFIG_DEFAULT_PROGRAMMER ?= PROGRAMMER_INVALID ++#CONFIG_DEFAULT_PROGRAMMER ?= PROGRAMMER_INVALID ++CONFIG_DEFAULT_PROGRAMMER ?= PROGRAMMER_INTERNAL + + # If your compiler spits out excessive warnings, run make WARNERROR=no + # You shouldn't have to change this flag. +@@ -61,10 +63,13 @@ CFLAGS += -Werror + endif + + ############################################################################### +-# General OS/architecture specific settings. ++# General OS-specific settings. ++# 1. Prepare for later by gathering information about host and target OS ++# 2. Set compiler flags and parameters according to OSes ++# 3. Likewise verify user-supplied CONFIG_* variables. + + # HOST_OS is only used to work around local toolchain issues. +-HOST_OS ?= $(shell uname) ++HOST_OS ?= $(shell uname) + ifeq ($(HOST_OS), MINGW32_NT-5.1) + # Explicitly set CC = gcc on MinGW, otherwise: "cc: command not found". + CC = gcc +@@ -94,13 +99,24 @@ CPPFLAGS += -I/usr/local/include + LDFLAGS += -L/usr/local/lib + endif + ++ifeq ($(TARGET_OS), NetBSD) ++CPPFLAGS += -I/usr/pkg/include ++LDFLAGS += -L/usr/pkg/lib ++endif ++ ++ifeq ($(TARGET_OS), DragonFlyBSD) ++CPPFLAGS += -I/usr/pkg/include ++LDFLAGS += -L/usr/pkg/lib ++endif ++ + ifeq ($(TARGET_OS), DOS) + EXEC_SUFFIX := .exe +-CPPFLAGS += -I../libgetopt ++CPPFLAGS += -I$(DOSLIBS_BASE)/libgetopt + # DJGPP has odd uint*_t definitions which cause lots of format string warnings. + CFLAGS += -Wno-format + # FIXME Check if we can achieve the same effect with -L../libgetopt -lgetopt +-LIBS += ../libgetopt/libgetopt.a ++LIBS += -lgetopt ++LDFLAGS += -L$(DOSLIBS_BASE)/libgetopt/ + # Bus Pirate, Serprog and PonyProg are not supported under DOS (missing serial support). + ifeq ($(CONFIG_BUSPIRATE_SPI), yes) + UNSUPPORTED_FEATURES += CONFIG_BUSPIRATE_SPI=yes +@@ -215,6 +231,10 @@ endif + endif + + ifeq ($(TARGET_OS), libpayload) ++ifeq ($(MAKECMDGOALS),) ++.DEFAULT_GOAL := libflashrom.a ++$(info Setting default goal to libflashrom.a) ++endif + FLASHROM_CFLAGS += -DSTANDALONE + ifeq ($(CONFIG_DUMMY), yes) + UNSUPPORTED_FEATURES += CONFIG_DUMMY=yes +@@ -263,6 +283,10 @@ override CONFIG_LINUX_SPI = no + endif + endif + ++############################################################################### ++# General architecture-specific settings. ++# Like above for the OS, below we verify user-supplied options depending on the target architecture. ++ + # Determine the destination processor architecture. + # IMPORTANT: The following line must be placed before ARCH is ever used + # (of course), but should come after any lines setting CC because the line +@@ -307,10 +331,10 @@ endif + ############################################################################### + # Flash chip drivers and bus support infrastructure. + +-CHIP_OBJS = jedec.o stm50flw0x0x.o w39.o w29ee011.o \ ++CHIP_OBJS = jedec.o stm50.o w39.o w29ee011.o \ + sst28sf040.o m29f400bt.o 82802ab.o pm49fl00x.o \ + sst49lfxxxc.o sst_fwhub.o flashchips.o spi.o spi25.o spi25_statusreg.o \ +- opaque.o sfdp.o en29lv640b.o ++ opaque.o sfdp.o en29lv640b.o at45db.o + + ############################################################################### + # Library code. +@@ -322,18 +346,22 @@ LIB_OBJS = layout.o flashrom.o udelay.o programmer.o + + CLI_OBJS = cli_classic.o cli_output.o print.o + +-# Set the flashrom version string from the highest revision number +-# of the checked out flashrom files. ++# Set the flashrom version string from the highest revision number of the checked out flashrom files. + # Note to packagers: Any tree exported with "make export" or "make tarball" + # will not require subversion. The downloadable snapshots are already exported. +-SVNVERSION := $(shell LC_ALL=C svnversion -cn . 2>/dev/null | sed -e "s/.*://" -e "s/\([0-9]*\).*/\1/" | grep "[0-9]" || LC_ALL=C svn info . 2>/dev/null | awk '/^Revision:/ {print $$2 }' | grep "[0-9]" || LC_ALL=C git svn info . 2>/dev/null | awk '/^Revision:/ {print $$2 }' | grep "[0-9]" || echo unknown) ++SVNVERSION := r1781 + + RELEASE := 0.9.7 +-VERSION := $(RELEASE)-r$(SVNVERSION) ++VERSION := $(RELEASE)-$(SVNVERSION) + RELEASENAME ?= $(VERSION) + + SVNDEF := -D'FLASHROM_VERSION="$(VERSION)"' + ++F10FLAGS := -DFORCE10_SPI_CHANGE ++ ++############################################################################### ++# Default settings of CONFIG_* variables. ++ + # Always enable internal/onboard support for now. + CONFIG_INTERNAL ?= yes + +@@ -425,16 +453,39 @@ endif + endif + + ############################################################################### ++# Handle CONFIG_* variables that depend on others set (and verified) above. ++ ++# The external DMI decoder (dmidecode) does not work in libpayload. Bail out if the internal one got disabled. ++ifeq ($(TARGET_OS), libpayload) ++ifeq ($(CONFIG_INTERNAL), yes) ++ifeq ($(CONFIG_INTERNAL_DMI), no) ++UNSUPPORTED_FEATURES += CONFIG_INTERNAL_DMI=no ++else ++override CONFIG_INTERNAL_DMI = yes ++endif ++endif ++endif ++ ++# Use internal DMI/SMBIOS decoder by default instead of relying on dmidecode. ++CONFIG_INTERNAL_DMI ?= yes ++ ++############################################################################### + # Programmer drivers and programmer support infrastructure. ++# Depending on the CONFIG_* variables set and verified above we set compiler flags and parameters below. ++ ++FEATURE_CFLAGS += -DDELL_DENVERTON_SUPPORT -DDELL_AVOTON_SUPPORT + + FEATURE_CFLAGS += -D'CONFIG_DEFAULT_PROGRAMMER=$(CONFIG_DEFAULT_PROGRAMMER)' + + ifeq ($(CONFIG_INTERNAL), yes) + FEATURE_CFLAGS += -D'CONFIG_INTERNAL=1' +-PROGRAMMER_OBJS += processor_enable.o chipset_enable.o board_enable.o cbtable.o dmi.o internal.o ++PROGRAMMER_OBJS += processor_enable.o chipset_enable.o board_enable.o cbtable.o internal.o + ifeq ($(ARCH), x86) + PROGRAMMER_OBJS += it87spi.o it85spi.o sb600spi.o amd_imc.o wbsio_spi.o mcp6x_spi.o +-PROGRAMMER_OBJS += ichspi.o ich_descriptors.o ++PROGRAMMER_OBJS += ichspi.o ich_descriptors.o dmi.o dnv_smi_spi.o ++ifeq ($(CONFIG_INTERNAL_DMI), yes) ++FEATURE_CFLAGS += -D'CONFIG_INTERNAL_DMI=1' ++endif + else + endif + NEED_PCI := yes +@@ -597,9 +648,9 @@ PCILIBS += -lpciutils -lpci + PCILIBS += -l$(shell uname -p) + else + ifeq ($(TARGET_OS), DOS) +-# FIXME There needs to be a better way to do this +-CPPFLAGS += -I../libpci/include +-PCILIBS += ../libpci/lib/libpci.a ++CPPFLAGS += -I$(DOSLIBS_BASE)/libpci/include ++LDFLAGS += -L$(DOSLIBS_BASE)/libpci/lib/ ++PCILIBS += -lpci + else + PCILIBS += -lpci + ifeq ($(TARGET_OS), OpenBSD) +@@ -635,10 +686,11 @@ FEATURE_LIBS += $(shell LC_ALL=C grep -q "NEEDLIBZ := yes" .libdeps && printf "% + LIBFLASHROM_OBJS = $(CHIP_OBJS) $(PROGRAMMER_OBJS) $(LIB_OBJS) + OBJS = $(CLI_OBJS) $(LIBFLASHROM_OBJS) + +-all: hwlibs features $(PROGRAM)$(EXEC_SUFFIX) ++all: hwlibs features $(PROGRAM)$(EXEC_SUFFIX) $(PROGRAM).8 + ifeq ($(ARCH), x86) + @+$(MAKE) -C util/ich_descriptors_tool/ TARGET_OS=$(TARGET_OS) EXEC_SUFFIX=$(EXEC_SUFFIX) + endif ++default: all + + $(PROGRAM)$(EXEC_SUFFIX): $(OBJS) + $(CC) $(LDFLAGS) -o $(PROGRAM)$(EXEC_SUFFIX) $(OBJS) $(LIBS) $(PCILIBS) $(FEATURE_LIBS) $(USBLIBS) +@@ -653,13 +705,13 @@ libflashrom.a: $(LIBFLASHROM_OBJS) + TAROPTIONS = $(shell LC_ALL=C tar --version|grep -q GNU && echo "--owner=root --group=root") + + %.o: %.c .features +- $(CC) -MMD $(CFLAGS) $(CPPFLAGS) $(FLASHROM_CFLAGS) $(FEATURE_CFLAGS) $(SVNDEF) -o $@ -c $< ++ $(CC) -MMD $(CFLAGS) $(CPPFLAGS) $(FLASHROM_CFLAGS) $(FEATURE_CFLAGS) $(SVNDEF) $(F10FLAGS) -o $@ -c $< + + # Make sure to add all names of generated binaries here. + # This includes all frontends and libflashrom. + # We don't use EXEC_SUFFIX here because we want to clean everything. + clean: +- rm -f $(PROGRAM) $(PROGRAM).exe libflashrom.a *.o *.d ++ rm -f $(PROGRAM) $(PROGRAM).exe libflashrom.a *.o *.d $(PROGRAM).8 + @+$(MAKE) -C util/ich_descriptors_tool/ clean + + distclean: clean +@@ -698,11 +750,20 @@ compiler: featuresavailable + @echo $(TARGET_OS)|wc -w|grep -q '^[[:blank:]]*1[[:blank:]]*$$' || \ + ( echo "unknown. Aborting."; exit 1) + @printf "%s\n" '$(TARGET_OS)' ++ifeq ($(TARGET_OS), libpayload) ++ @$(CC) --version 2>&1 | grep -q coreboot || \ ++ ( echo "Warning: It seems you are not using coreboot's reference compiler."; \ ++ echo "This might work but usually does not, please beware." ) ++endif + + define LIBPCI_TEST + /* Avoid a failing test due to libpci header symbol shadowing breakage */ + #define index shadow_workaround_index ++#if !defined __NetBSD__ && !defined __DragonFly__ + #include ++#else ++#include ++#endif + struct pci_access *pacc; + int main(int argc, char **argv) + { +@@ -853,16 +914,20 @@ endif + @$(DIFF) -q .features.tmp .features >/dev/null 2>&1 && rm .features.tmp || mv .features.tmp .features + @rm -f .featuretest.c .featuretest$(EXEC_SUFFIX) + +-install: $(PROGRAM)$(EXEC_SUFFIX) ++$(PROGRAM).8: $(PROGRAM).8.tmpl ++ @sed -e '1 s#".*".*#"$(shell ./util/getrevision.sh -d $(PROGRAM).8.tmpl)" "$(VERSION)"#' <$< >$@ ++ ++install: $(PROGRAM)$(EXEC_SUFFIX) $(PROGRAM).8 + mkdir -p $(DESTDIR)$(PREFIX)/sbin + mkdir -p $(DESTDIR)$(MANDIR)/man8 + $(INSTALL) -m 0755 $(PROGRAM)$(EXEC_SUFFIX) $(DESTDIR)$(PREFIX)/sbin + $(INSTALL) -m 0644 $(PROGRAM).8 $(DESTDIR)$(MANDIR)/man8 + +-export: ++export: $(PROGRAM).8 + @rm -rf $(EXPORTDIR)/flashrom-$(RELEASENAME) + @svn export -r BASE . $(EXPORTDIR)/flashrom-$(RELEASENAME) + @sed "s/^SVNVERSION.*/SVNVERSION := $(SVNVERSION)/" Makefile >$(EXPORTDIR)/flashrom-$(RELEASENAME)/Makefile ++ @cp $(PROGRAM).8 "$(EXPORTDIR)/flashrom-$(RELEASENAME)/$(PROGRAM).8" + @LC_ALL=C svn log >$(EXPORTDIR)/flashrom-$(RELEASENAME)/ChangeLog + @echo Exported $(EXPORTDIR)/flashrom-$(RELEASENAME)/ + +@@ -876,6 +941,6 @@ djgpp-dos: clean + libpayload: clean + make CC="CC=i386-elf-gcc lpgcc" AR=i386-elf-ar RANLIB=i386-elf-ranlib + +-.PHONY: all clean distclean compiler hwlibs features export tarball dos featuresavailable ++.PHONY: all install clean distclean compiler hwlibs features export tarball dos featuresavailable + + -include $(OBJS:.o=.d) +diff --git a/README b/README +index 7f24cca..b3e50a6 100644 +--- a/README ++++ b/README +@@ -80,11 +80,9 @@ To compile on Solaris, use: + + gmake LDFLAGS="-L$pathtolibpci" CC="gcc -I$pathtopciheaders" CFLAGS=-O2 + +-To compile on NetBSD or DragonFly BSD, use: ++To compile on NetBSD or DragonFly BSD (with pciutils, libftdi, libusb installed in /usr/pkg/), use: + +- ln -s /usr/pkg/include/pciutils pci +- gmake CPPFLAGS="-I. -I/usr/pkg/include" \ +- LDFLAGS="-L/usr/pkg/lib -Wl,-rpath-link,/usr/pkg/lib" ++ gmake + + To compile on OpenBSD, use: + +@@ -105,20 +103,24 @@ To cross-compile on Linux for DOS: + djcrx-2.04pre_20090725-13ap.i386.rpm + The cross toolchain packages for your distribution may have slightly different + names (look for packages named *djgpp*). +- Download pciutils 3.1.5 and apply http://assembler.cz/flashrom/pciutils.patch +- Download and compile http://assembler.cz/flashrom/libgetopt/ ++ ++ You will need the following library source trees containing their compiled ++ static libraries either in the parent directory of the flashrom source or ++ specify the base folder on compile time with the DOSLIBS_BASE parameter. ++ The default as described above is equal to calling ++ 'make djgpp-dos DOSLIBS_BASE=..' ++ ++ To get and build said libraries... ++ Download pciutils 3.1.5 and apply http://flashrom.org/File:Pciutils.patch.gz + Compile pciutils, see README.DJGPP for instructions. ++ Download and compile http://flashrom.org/File:Libgetopt.tar.gz + Enter the flashrom directory. +- ../libpci should contain pciutils source and binaries. +- ../libgetopt should contain getopt.a from libgetopt. + Run either (change settings where appropriate) + make CC=i586-pc-msdosdjgpp-gcc STRIP=i586-pc-msdosdjgpp-strip + or (above settings hardcoded) + make djgpp-dos +- You might have to add WARNERROR=no to the make command line. +- To run flashrom.exe, download and unpack +- http://homer.rice.edu/~sandmann/cwsdpmi/csdpmi7b.zip and make sure +- CWSDPMI.EXE is in the current directory. ++ To run flashrom.exe, download http://flashrom.org/File:Csdpmi7b.zip and ++ unpack CWSDPMI.EXE into the current directory or one in PATH. + + To cross-compile on Linux for Windows: + +diff --git a/at45db.c b/at45db.c +new file mode 100644 +index 0000000..5c90418 +--- /dev/null ++++ b/at45db.c +@@ -0,0 +1,562 @@ ++/* ++ * Support for Atmel AT45DB series DataFlash chips. ++ * This file is part of the flashrom project. ++ * ++ * Copyright (C) 2012 Aidan Thornton ++ * Copyright (C) 2013 Stefan Tauner ++ * ++ * This program is free software; 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. ++ * ++ * You 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 ++ */ ++ ++#include ++#include "flash.h" ++#include "chipdrivers.h" ++#include "programmer.h" ++#include "spi.h" ++ ++/* Status register bits */ ++#define AT45DB_READY (1<<7) ++#define AT45DB_CMP (1<<6) ++#define AT45DB_PROT (1<<1) ++#define AT45DB_POWEROF2 (1<<0) ++ ++/* Opcodes */ ++#define AT45DB_STATUS 0xD7 /* NB: this is a block erase command on most other chips(!). */ ++#define AT45DB_DISABLE_PROTECT 0x3D, 0x2A, 0x7F, 0x9A ++#define AT45DB_READ_ARRAY 0xE8 ++#define AT45DB_READ_PROTECT 0x32 ++#define AT45DB_READ_LOCKDOWN 0x35 ++#define AT45DB_PAGE_ERASE 0x81 ++#define AT45DB_BLOCK_ERASE 0x50 ++#define AT45DB_SECTOR_ERASE 0x7C ++#define AT45DB_CHIP_ERASE 0xC7 ++#define AT45DB_CHIP_ERASE_ADDR 0x94809A /* Magic address. See usage. */ ++#define AT45DB_BUFFER1_WRITE 0x84 ++#define AT45DB_BUFFER1_PAGE_PROGRAM 0x88 ++/* Buffer 2 is unused yet. ++#define AT45DB_BUFFER2_WRITE 0x87 ++#define AT45DB_BUFFER2_PAGE_PROGRAM 0x89 ++*/ ++ ++static uint8_t at45db_read_status_register(struct flashctx *flash, uint8_t *status) ++{ ++ static const uint8_t cmd[] = { AT45DB_STATUS }; ++ ++ int ret = spi_send_command(flash, sizeof(cmd), 1, cmd, status); ++ if (ret != 0) ++ msg_cerr("Reading the status register failed!\n"); ++ else ++ msg_cspew("Status register: 0x%02x.\n", *status); ++ return ret; ++} ++ ++int spi_disable_blockprotect_at45db(struct flashctx *flash) ++{ ++ static const uint8_t cmd[4] = { AT45DB_DISABLE_PROTECT }; /* NB: 4 bytes magic number */ ++ int ret = spi_send_command(flash, sizeof(cmd), 0, cmd, NULL); ++ if (ret != 0) { ++ msg_cerr("Sending disable lockdown failed!\n"); ++ return ret; ++ } ++ uint8_t status; ++ ret = at45db_read_status_register(flash, &status); ++ if (ret != 0 || ((status & AT45DB_PROT) != 0)) { ++ msg_cerr("Disabling lockdown failed!\n"); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static unsigned int at45db_get_sector_count(struct flashctx *flash) ++{ ++ unsigned int i, j; ++ unsigned int cnt = 0; ++ for (i = 0; i < NUM_ERASEFUNCTIONS; i++) { ++ if (flash->chip->block_erasers[i].block_erase == &spi_erase_at45db_sector) { ++ for (j = 0; j < NUM_ERASEREGIONS; j++) { ++ cnt += flash->chip->block_erasers[i].eraseblocks[j].count; ++ } ++ } ++ } ++ msg_cspew("%s: number of sectors=%u\n", __func__, cnt); ++ return cnt; ++} ++ ++/* Reads and prettyprints protection/lockdown registers. ++ * Some elegance of the printouts had to be cut down a bit to share this code. */ ++static uint8_t at45db_prettyprint_protection_register(struct flashctx *flash, uint8_t opcode, const char *regname) ++{ ++ const uint8_t cmd[] = { opcode, 0, 0, 0 }; ++ /* The first two sectors share the first result byte. */ ++ uint8_t buf[at45db_get_sector_count(flash) - 1]; ++ ++ int ret = spi_send_command(flash, sizeof(cmd), sizeof(buf), cmd, buf); ++ if (ret != 0) { ++ msg_cerr("Reading the %s register failed!\n", regname); ++ return ret; ++ } ++ ++ unsigned int i; ++ for (i = 0; i < sizeof(buf); i++) { ++ if (buf[i] != 0x00) ++ break; ++ if (i == sizeof(buf) - 1) { ++ msg_cdbg("No Sector is %sed.\n", regname); ++ return 0; ++ } ++ } ++ ++ /* TODO: print which addresses are mapped to (un)locked sectors. */ ++ msg_cdbg("Sector 0a is %s%sed.\n", ((buf[0] & 0xC0) == 0x00) ? "un" : "", regname); ++ msg_cdbg("Sector 0b is %s%sed.\n", ((buf[0] & 0x30) == 0x00) ? "un" : "", regname); ++ for (i = 1; i < sizeof(buf); i++) ++ msg_cdbg("Sector %2u is %s%sed.\n", i, (buf[i] == 0x00) ? "un" : "", regname); ++ ++ return 0; ++} ++ ++/* bit 7: busy flag ++ * bit 6: memory/buffer compare result ++ * bit 5-2: density (encoding see below) ++ * bit 1: protection enabled (soft or hard) ++ * bit 0: "power of 2" page size indicator (e.g. 1 means 256B; 0 means 264B) ++ * ++ * 5-2 encoding: bit 2 is always 1, bits 3-5 encode the density as "2^(bits - 1)" in Mb e.g.: ++ * AT45DB161D 1011 16Mb */ ++int spi_prettyprint_status_register_at45db(struct flashctx *flash) ++{ ++ uint8_t status; ++ if (at45db_read_status_register(flash, &status) != 0) { ++ return 1; ++ } ++ ++ /* AT45DB321C does not support lockdown or a page size of a power of 2... */ ++ const bool isAT45DB321C = (strcmp(flash->chip->name, "AT45DB321C") == 0); ++ msg_cdbg("Chip status register is 0x%02x\n", status); ++ msg_cdbg("Chip status register: Bit 7 / Ready is %sset\n", (status & AT45DB_READY) ? "" : "not "); ++ msg_cdbg("Chip status register: Bit 6 / Compare match is %sset\n", (status & AT45DB_CMP) ? "" : "not "); ++ spi_prettyprint_status_register_bit(status, 5); ++ spi_prettyprint_status_register_bit(status, 4); ++ spi_prettyprint_status_register_bit(status, 3); ++ spi_prettyprint_status_register_bit(status, 2); ++ const uint8_t dens = (status >> 3) & 0x7; /* Bit 2 is always 1, we use the other bits only */ ++ msg_cdbg("Chip status register: Density is %u Mb\n", 1 << (dens - 1)); ++ msg_cdbg("Chip status register: Bit 1 / Protection is %sset\n", (status & AT45DB_PROT) ? "" : "not "); ++ ++ if (isAT45DB321C) ++ spi_prettyprint_status_register_bit(status, 0); ++ else ++ msg_cdbg("Chip status register: Bit 0 / \"Power of 2\" is %sset\n", ++ (status & AT45DB_POWEROF2) ? "" : "not "); ++ ++ if (status & AT45DB_PROT) ++ at45db_prettyprint_protection_register(flash, AT45DB_READ_PROTECT, "protect"); ++ ++ if (!isAT45DB321C) ++ at45db_prettyprint_protection_register(flash, AT45DB_READ_LOCKDOWN, "lock"); ++ ++ return 0; ++} ++ ++/* Probe function for AT45DB* chips that support multiple page sizes. */ ++int probe_spi_at45db(struct flashctx *flash) ++{ ++ uint8_t status; ++ struct flashchip *chip = flash->chip; ++ ++ if (!probe_spi_rdid(flash)) ++ return 0; ++ ++ /* Some AT45DB* chips support two different page sizes each (e.g. 264 and 256 B). In order to tell which ++ * page size this chip has we need to read the status register. */ ++ if (at45db_read_status_register(flash, &status) != 0) ++ return 0; ++ ++ /* We assume sane power-of-2 page sizes and adjust the chip attributes in case this is not the case. */ ++ if ((status & AT45DB_POWEROF2) == 0) { ++ chip->total_size = (chip->total_size / 32) * 33; ++ chip->page_size = (chip->page_size / 32) * 33; ++ ++ unsigned int i, j; ++ for (i = 0; i < NUM_ERASEFUNCTIONS; i++) { ++ struct block_eraser *eraser = &chip->block_erasers[i]; ++ for (j = 0; j < NUM_ERASEREGIONS; j++) { ++ eraser->eraseblocks[j].size = (eraser->eraseblocks[j].size / 32) * 33; ++ } ++ } ++ } ++ ++ switch (chip->page_size) { ++ case 256: chip->gran = write_gran_256bytes; break; ++ case 264: chip->gran = write_gran_264bytes; break; ++ case 512: chip->gran = write_gran_512bytes; break; ++ case 528: chip->gran = write_gran_528bytes; break; ++ case 1024: chip->gran = write_gran_1024bytes; break; ++ case 1056: chip->gran = write_gran_1056bytes; break; ++ default: ++ msg_cerr("%s: unknown page size %d.\n", __func__, chip->page_size); ++ return 0; ++ } ++ ++ msg_cdbg2("%s: total size %i kB, page size %i B\n", __func__, chip->total_size * 1024, chip->page_size); ++ ++ return 1; ++} ++ ++/* Returns the minimum number of bits needed to represent the given address. ++ * FIXME: use mind-blowing implementation. ++ * FIXME: move to utility module. */ ++static uint32_t address_to_bits(uint32_t addr) ++{ ++ unsigned int lzb = 0; ++ while (((1 << (31 - lzb)) & ~addr) != 0) ++ lzb++; ++ return 32 - lzb; ++} ++ ++/* In case of non-power-of-two page sizes we need to convert the address flashrom uses to the address the ++ * DataFlash chips use. The latter uses a segmented address space where the page address is encoded in the ++ * more significant bits and the offset within the page is encoded in the less significant bits. The exact ++ * partition depends on the page size. ++ */ ++static unsigned int at45db_convert_addr(unsigned int addr, unsigned int page_size) ++{ ++ unsigned int page_bits = address_to_bits(page_size - 1); ++ unsigned int at45db_addr = ((addr / page_size) << page_bits) | (addr % page_size); ++ msg_cspew("%s: addr=0x%x, page_size=%u, page_bits=%u -> at45db_addr=0x%x\n", ++ __func__, addr, page_size, page_bits, at45db_addr); ++ return at45db_addr; ++} ++ ++int spi_read_at45db(struct flashctx *flash, uint8_t *buf, unsigned int addr, unsigned int len) ++{ ++ const unsigned int page_size = flash->chip->page_size; ++ const unsigned int total_size = flash->chip->total_size * 1024; ++ if ((addr + len) > total_size) { ++ msg_cerr("%s: tried to read beyond flash boundary: addr=%u, len=%u, size=%u\n", ++ __func__, addr, len, total_size); ++ return 1; ++ } ++ ++ /* We have to split this up into chunks to fit within the programmer's read size limit, but those ++ * chunks can cross page boundaries. */ ++ const unsigned int max_data_read = flash->pgm->spi.max_data_read; ++ const unsigned int max_chunk = (max_data_read > 0) ? max_data_read : page_size; ++ while (addr < len) { ++ unsigned int chunk = min(max_chunk, len); ++ int ret = spi_nbyte_read(flash, at45db_convert_addr(addr, page_size), buf + addr, chunk); ++ if (ret) { ++ msg_cerr("%s: error sending read command!\n", __func__); ++ return ret; ++ } ++ addr += chunk; ++ } ++ ++ return 0; ++} ++ ++/* Legacy continuous read, used where spi_read_at45db() is not available. ++ * The first 4 (dummy) bytes read need to be discarded. */ ++int spi_read_at45db_e8(struct flashctx *flash, uint8_t *buf, unsigned int addr, unsigned int len) ++{ ++ const unsigned int page_size = flash->chip->page_size; ++ const unsigned int total_size = flash->chip->total_size * 1024; ++ if ((addr + len) > total_size) { ++ msg_cerr("%s: tried to read beyond flash boundary: addr=%u, len=%u, size=%u\n", ++ __func__, addr, len, total_size); ++ return 1; ++ } ++ ++ /* We have to split this up into chunks to fit within the programmer's read size limit, but those ++ * chunks can cross page boundaries. */ ++ const unsigned int max_data_read = flash->pgm->spi.max_data_read; ++ const unsigned int max_chunk = (max_data_read > 0) ? max_data_read : page_size; ++ while (addr < len) { ++ const unsigned int addr_at45 = at45db_convert_addr(addr, page_size); ++ const unsigned char cmd[] = { ++ AT45DB_READ_ARRAY, ++ (addr_at45 >> 16) & 0xff, ++ (addr_at45 >> 8) & 0xff, ++ (addr_at45 >> 0) & 0xff ++ }; ++ /* We need to leave place for 4 dummy bytes and handle them explicitly. */ ++ unsigned int chunk = min(max_chunk, len + 4); ++ uint8_t tmp[chunk]; ++ int ret = spi_send_command(flash, sizeof(cmd), chunk, cmd, tmp); ++ if (ret) { ++ msg_cerr("%s: error sending read command!\n", __func__); ++ return ret; ++ } ++ /* Copy result without dummy bytes into buf and advance address counter respectively. */ ++ memcpy(buf + addr, tmp + 4, chunk - 4); ++ addr += chunk - 4; ++ } ++ return 0; ++} ++ ++/* Returns 0 when ready, 1 on errors and timeouts. */ ++static int at45db_wait_ready (struct flashctx *flash, unsigned int us, unsigned int retries) ++{ ++ while (true) { ++ uint8_t status; ++ int ret = at45db_read_status_register(flash, &status); ++ if ((status & AT45DB_READY) == AT45DB_READY) ++ return 0; ++ if (ret != 0 || retries-- == 0) ++ return 1; ++ programmer_delay(us); ++ } ++} ++ ++static int at45db_erase(struct flashctx *flash, uint8_t opcode, unsigned int at45db_addr, unsigned int stepsize, unsigned int retries) ++{ ++ const uint8_t cmd[] = { ++ opcode, ++ (at45db_addr >> 16) & 0xff, ++ (at45db_addr >> 8) & 0xff, ++ (at45db_addr >> 0) & 0xff ++ }; ++ ++ /* Send erase command. */ ++ int ret = spi_send_command(flash, sizeof(cmd), 0, cmd, NULL); ++ if (ret != 0) { ++ msg_cerr("%s: error sending erase command!\n", __func__); ++ return ret; ++ } ++ ++ /* Wait for completion. */ ++ ret = at45db_wait_ready(flash, stepsize, retries); ++ if (ret != 0) ++ msg_cerr("%s: chip did not became ready again after sending the erase command!\n", __func__); ++ ++ return ret; ++} ++ ++int spi_erase_at45db_page(struct flashctx *flash, unsigned int addr, unsigned int blocklen) ++{ ++ const unsigned int page_size = flash->chip->page_size; ++ const unsigned int total_size = flash->chip->total_size * 1024; ++ ++ if ((addr % page_size) != 0 || (blocklen % page_size) != 0) { ++ msg_cerr("%s: cannot erase partial pages: addr=%u, blocklen=%u\n", __func__, addr, blocklen); ++ return 1; ++ } ++ ++ if ((addr + blocklen) > total_size) { ++ msg_cerr("%s: tried to erase a block beyond flash boundary: addr=%u, blocklen=%u, size=%u\n", ++ __func__, addr, blocklen, total_size); ++ return 1; ++ } ++ ++ /* Needs typically about 35 ms for completion, so let's wait 100 ms in 500 us steps. */ ++ return at45db_erase(flash, AT45DB_PAGE_ERASE, at45db_convert_addr(addr, page_size), 500, 200); ++} ++ ++int spi_erase_at45db_block(struct flashctx *flash, unsigned int addr, unsigned int blocklen) ++{ ++ const unsigned int page_size = flash->chip->page_size; ++ const unsigned int total_size = flash->chip->total_size * 1024; ++ ++ if ((addr % page_size) != 0 || (blocklen % page_size) != 0) { // FIXME: should check blocks not pages ++ msg_cerr("%s: cannot erase partial pages: addr=%u, blocklen=%u\n", __func__, addr, blocklen); ++ return 1; ++ } ++ ++ if ((addr + blocklen) > total_size) { ++ msg_cerr("%s: tried to erase a block beyond flash boundary: addr=%u, blocklen=%u, size=%u\n", ++ __func__, addr, blocklen, total_size); ++ return 1; ++ } ++ ++ /* Needs typically between 20 and 100 ms for completion, so let's wait 300 ms in 1 ms steps. */ ++ return at45db_erase(flash, AT45DB_BLOCK_ERASE, at45db_convert_addr(addr, page_size), 1000, 300); ++} ++ ++int spi_erase_at45db_sector(struct flashctx *flash, unsigned int addr, unsigned int blocklen) ++{ ++ const unsigned int page_size = flash->chip->page_size; ++ const unsigned int total_size = flash->chip->total_size * 1024; ++ ++ if ((addr % page_size) != 0 || (blocklen % page_size) != 0) { // FIXME: should check sectors not pages ++ msg_cerr("%s: cannot erase partial pages: addr=%u, blocklen=%u\n", __func__, addr, blocklen); ++ return 1; ++ } ++ ++ if ((addr + blocklen) > total_size) { ++ msg_cerr("%s: tried to erase a sector beyond flash boundary: addr=%u, blocklen=%u, size=%u\n", ++ __func__, addr, blocklen, total_size); ++ return 1; ++ } ++ ++ /* Needs typically about 5 s for completion, so let's wait 20 seconds in 200 ms steps. */ ++ return at45db_erase(flash, AT45DB_SECTOR_ERASE, at45db_convert_addr(addr, page_size), 200000, 100); ++} ++ ++int spi_erase_at45db_chip(struct flashctx *flash, unsigned int addr, unsigned int blocklen) ++{ ++ const unsigned int total_size = flash->chip->total_size * 1024; ++ ++ if ((addr + blocklen) > total_size) { ++ msg_cerr("%s: tried to erase beyond flash boundary: addr=%u, blocklen=%u, size=%u\n", ++ __func__, addr, blocklen, total_size); ++ return 1; ++ } ++ ++ /* Needs typically from about 5 to over 60 s for completion, so let's wait 100 s in 500 ms steps. ++ * NB: the address is not a real address but a magic number. This hack allows to share code. */ ++ return at45db_erase(flash, AT45DB_CHIP_ERASE, AT45DB_CHIP_ERASE_ADDR, 500000, 200); ++} ++ ++/* This one is really special and works only for AT45CS1282. It uses two different opcodes depending on the ++ * address and has an asymmetric layout. */ ++int spi_erase_at45cs_sector(struct flashctx *flash, unsigned int addr, unsigned int blocklen) ++{ ++ const unsigned int page_size = flash->chip->page_size; ++ const unsigned int total_size = flash->chip->total_size * 1024; ++ const struct block_eraser be = flash->chip->block_erasers[0]; ++ const unsigned int sec_0a_top = be.eraseblocks[0].size; ++ const unsigned int sec_0b_top = be.eraseblocks[0].size + be.eraseblocks[1].size; ++ ++ if ((addr + blocklen) > total_size) { ++ msg_cerr("%s: tried to erase a sector beyond flash boundary: addr=%u, blocklen=%u, size=%u\n", ++ __func__, addr, blocklen, total_size); ++ return 1; ++ } ++ ++ bool partial_range = false; ++ uint8_t opcode = 0x7C; /* Used for all but sector 0a. */ ++ if (addr < sec_0a_top) { ++ opcode = 0x50; ++ /* One single sector of 8 pages at address 0. */ ++ if (addr != 0 || blocklen != (8 * page_size)) ++ partial_range = true; ++ } else if (addr < sec_0b_top) { ++ /* One single sector of 248 pages adjacent to the first. */ ++ if (addr != sec_0a_top || blocklen != (248 * page_size)) ++ partial_range = true; ++ } else { ++ /* The rest is filled by 63 aligned sectors of 256 pages. */ ++ if ((addr % (256 * page_size)) != 0 || (blocklen % (256 * page_size)) != 0) ++ partial_range = true; ++ } ++ if (partial_range) { ++ msg_cerr("%s: cannot erase partial sectors: addr=%u, blocklen=%u\n", __func__, addr, blocklen); ++ return 1; ++ } ++ ++ /* Needs up to 4 s for completion, so let's wait 20 seconds in 200 ms steps. */ ++ return at45db_erase(flash, opcode, at45db_convert_addr(addr, page_size), 200000, 100); ++} ++ ++static int at45db_fill_buffer1(struct flashctx *flash, uint8_t *bytes, unsigned int off, unsigned int len) ++{ ++ const unsigned int page_size = flash->chip->page_size; ++ if ((off + len) > page_size) { ++ msg_cerr("Tried to write %u bytes at offset %u into a buffer of only %u B.\n", ++ len, off, page_size); ++ return 1; ++ } ++ ++ /* Create a suitable buffer to store opcode, address and data chunks for buffer1. */ ++ const unsigned int max_data_write = flash->pgm->spi.max_data_write; ++ const unsigned int max_chunk = (max_data_write > 0 && max_data_write <= page_size) ? ++ max_data_write : page_size; ++ uint8_t buf[4 + max_chunk]; ++ ++ buf[0] = AT45DB_BUFFER1_WRITE; ++ while (off < page_size) { ++ unsigned int cur_chunk = min(max_chunk, page_size - off); ++ buf[1] = (off >> 16) & 0xff; ++ buf[2] = (off >> 8) & 0xff; ++ buf[3] = (off >> 0) & 0xff; ++ memcpy(&buf[4], bytes + off, cur_chunk); ++ int ret = spi_send_command(flash, 4 + cur_chunk, 0, buf, NULL); ++ if (ret != 0) { ++ msg_cerr("%s: error sending buffer write!\n", __func__); ++ return ret; ++ } ++ off += cur_chunk; ++ } ++ return 0; ++} ++ ++static int at45db_commit_buffer1(struct flashctx *flash, unsigned int at45db_addr) ++{ ++ const uint8_t cmd[] = { ++ AT45DB_BUFFER1_PAGE_PROGRAM, ++ (at45db_addr >> 16) & 0xff, ++ (at45db_addr >> 8) & 0xff, ++ (at45db_addr >> 0) & 0xff ++ }; ++ ++ /* Send buffer to device. */ ++ int ret = spi_send_command(flash, sizeof(cmd), 0, cmd, NULL); ++ if (ret != 0) { ++ msg_cerr("%s: error sending buffer to main memory command!\n", __func__); ++ return ret; ++ } ++ ++ /* Wait for completion (typically a few ms). */ ++ ret = at45db_wait_ready(flash, 250, 200); // 50 ms ++ if (ret != 0) { ++ msg_cerr("%s: chip did not became ready again!\n", __func__); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int at45db_program_page(struct flashctx *flash, uint8_t *buf, unsigned int at45db_addr) ++{ ++ int ret = at45db_fill_buffer1(flash, buf, 0, flash->chip->page_size); ++ if (ret != 0) { ++ msg_cerr("%s: filling the buffer failed!\n", __func__); ++ return ret; ++ } ++ ++ ret = at45db_commit_buffer1(flash, at45db_addr); ++ if (ret != 0) { ++ msg_cerr("%s: committing page failed!\n", __func__); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++int spi_write_at45db(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len) ++{ ++ const unsigned int page_size = flash->chip->page_size; ++ const unsigned int total_size = flash->chip->total_size; ++ ++ if ((start % page_size) != 0 || (len % page_size) != 0) { ++ msg_cerr("%s: cannot write partial pages: start=%u, len=%u\n", __func__, start, len); ++ return 1; ++ } ++ ++ if ((start + len) > (total_size * 1024)) { ++ msg_cerr("%s: tried to write beyond flash boundary: start=%u, len=%u, size=%u\n", ++ __func__, start, len, total_size); ++ return 1; ++ } ++ ++ unsigned int i; ++ for (i = 0; i < len; i += page_size) { ++ if (at45db_program_page(flash, buf + i, at45db_convert_addr(start + i, page_size)) != 0) { ++ msg_cerr("Writing page %u failed!\n", i); ++ return 1; ++ } ++ } ++ return 0; ++} +diff --git a/atahpt.c b/atahpt.c +index f8be8c4..242e14a 100644 +--- a/atahpt.c ++++ b/atahpt.c +@@ -69,6 +69,8 @@ int atahpt_init(void) + return 1; + + io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_4); ++ if (!io_base_addr) ++ return 1; + + /* Enable flash access. */ + reg32 = pci_read_long(dev, REG_FLASH_ACCESS); +diff --git a/board_enable.c b/board_enable.c +index 074cabb..e2a5fe2 100644 +--- a/board_enable.c ++++ b/board_enable.c +@@ -1488,6 +1488,7 @@ static int intel_ich_gpio_set(int gpio, int raise) + {0x24D0, 0x58, 0x1BFF0000, 0x00030305, 0}, /* 82801EB/ER (ICH5/ICH5R) */ + {0x2640, 0x48, 0x1BFF0000, 0x00030307, 0}, /* 82801FB/FR (ICH6/ICH6R) */ + {0x2641, 0x48, 0x1BFF0000, 0x00030307, 0}, /* 82801FBM (ICH6M) */ ++ {0x27B0, 0x48, 0xFFFFFFFF, 0x000300FF, 0}, /* 82801GDH (ICH7 DH) */ + {0x27B8, 0x48, 0xFFFFFFFF, 0x000300FF, 0}, /* 82801GB/GR (ICH7 Family) */ + {0x27B9, 0x48, 0xFFEBFFFE, 0x000300FE, 0}, /* 82801GBM (ICH7-M) */ + {0x27BD, 0x48, 0xFFEBFFFE, 0x000300FE, 0}, /* 82801GHM (ICH7-M DH) */ +@@ -1665,6 +1666,7 @@ static int intel_ich_gpio_set(int gpio, int raise) + * - abit IP35 Pro: Intel P35 + ICH9R + * - ASUS P5LD2 + * - ASUS P5LD2-VM ++ * - ASUS P5LD2-VM DH + */ + static int intel_ich_gpio16_raise(void) + { +@@ -2266,13 +2268,13 @@ static int p2_whitelist_laptop(void) + * NOTE: Please add boards that _don't_ need such enables or don't work yet + * to the respective tables in print.c. Thanks! + * +- * We use 2 sets of IDs here, you're free to choose which is which. This ++ * We use 2 sets of PCI IDs here, you're free to choose which is which. This + * is to provide a very high degree of certainty when matching a board on + * the basis of subsystem/card IDs. As not every vendor handles + * subsystem/card IDs in a sane manner. + * + * Keep the second set NULLed if it should be ignored. Keep the subsystem IDs +- * NULLed if they don't identify the board fully and if you can't use DMI. ++ * and the dmi identifier NULLed if they don't identify the board fully to disable autodetection. + * But please take care to provide an as complete set of pci ids as possible; + * autodetection is the preferred behaviour and we would like to make sure that + * matches are unique. +@@ -2306,6 +2308,7 @@ const struct board_match board_matches[] = { + #if defined(__i386__) || defined(__x86_64__) + {0x10DE, 0x0547, 0x147B, 0x1C2F, 0x10DE, 0x0548, 0x147B, 0x1C2F, NULL, NULL, NULL, P3, "abit", "AN-M2", 0, NT, nvidia_mcp_gpio2_raise}, + {0x1106, 0x0282, 0x147B, 0x1415, 0x1106, 0x3227, 0x147B, 0x1415, "^AV8 ", NULL, NULL, P3, "abit", "AV8", 0, OK, board_abit_av8}, ++ {0x8086, 0x7190, 0, 0, 0x8086, 0x7110, 0, 0, NULL /* "^I440BX-W977$" */, "abit", "bf6", P3, "abit", "BF6", 0, OK, intel_piix4_gpo26_lower}, + {0x8086, 0x7190, 0, 0, 0x8086, 0x7110, 0, 0, "^i440BX-W977 (BM6)$", NULL, NULL, P3, "abit", "BM6", 0, OK, intel_piix4_gpo26_lower}, + {0x8086, 0x24d3, 0x147b, 0x1014, 0x8086, 0x2578, 0x147b, 0x1014, NULL, NULL, NULL, P3, "abit", "IC7", 0, NT, intel_ich_gpio23_raise}, + {0x8086, 0x2930, 0x147b, 0x1084, 0x11ab, 0x4364, 0x147b, 0x1084, NULL, NULL, NULL, P3, "abit", "IP35", 0, OK, intel_ich_gpio16_raise}, +@@ -2330,6 +2333,7 @@ const struct board_match board_matches[] = { + {0x8086, 0x2570, 0x1849, 0x2570, 0x8086, 0x24d3, 0x1849, 0x24d0, NULL, NULL, NULL, P3, "ASRock", "775i65G", 0, OK, intel_ich_gpio23_raise}, + {0x10DE, 0x0060, 0x1043, 0x80AD, 0x10DE, 0x01E0, 0x1043, 0x80C0, NULL, NULL, NULL, P3, "ASUS", "A7N8X-VM/400", 0, OK, it8712f_gpio12_raise}, + {0x1106, 0x3189, 0x1043, 0x807F, 0x1106, 0x3065, 0x1043, 0x80ED, NULL, NULL, NULL, P3, "ASUS", "A7V600-X", 0, OK, it8712f_gpio31_raise}, ++ {0x1106, 0x3177, 0x1043, 0x80F9, 0x1106, 0x3205, 0x1043, 0x80F9, NULL, NULL, NULL, P3, "ASUS", "A7V8X-MX", 0, OK, w836xx_memw_enable_2e}, + {0x1106, 0x3177, 0x1043, 0x80A1, 0x1106, 0x3205, 0x1043, 0x8118, NULL, NULL, NULL, P3, "ASUS", "A7V8X-MX SE", 0, OK, w836xx_memw_enable_2e}, + {0x1106, 0x3189, 0x1043, 0x807F, 0x1106, 0x3177, 0x1043, 0x808C, NULL, NULL, NULL, P3, "ASUS", "A7V8X", 0, OK, it8703f_gpio51_raise}, + {0x1106, 0x3099, 0x1043, 0x807F, 0x1106, 0x3147, 0x1043, 0x808C, NULL, NULL, NULL, P3, "ASUS", "A7V333", 0, OK, it8703f_gpio51_raise}, +@@ -2372,12 +2376,14 @@ const struct board_match board_matches[] = { + {0x8086, 0x27b8, 0x1043, 0x2a22, 0x8086, 0x2770, 0x1043, 0x2a22, "^P5LP-LE$", NULL, NULL, P3, "ASUS", "P5LP-LE (Epson OEM)", 0, OK, intel_ich_gpio34_raise}, + {0x8086, 0x27da, 0x1043, 0x8179, 0x8086, 0x27b8, 0x1043, 0x8179, "^P5LD2$", NULL, NULL, P3, "ASUS", "P5LD2", 0, NT, intel_ich_gpio16_raise}, + {0x8086, 0x27da, 0x1043, 0x8179, 0x8086, 0x27b8, 0x1043, 0x8179, "^P5LD2-VM$", NULL, NULL, P3, "ASUS", "P5LD2-VM", 0, NT, intel_ich_gpio16_raise}, ++ {0x8086, 0x27b0, 0x1043, 0x8179, 0x8086, 0x2770, 0x1043, 0x817a, "^P5LD2-VM DH$", NULL, NULL, P3, "ASUS", "P5LD2-VM DH", 0, OK, intel_ich_gpio16_raise}, + {0x10DE, 0x0030, 0x1043, 0x818a, 0x8086, 0x100E, 0x1043, 0x80EE, NULL, NULL, NULL, P3, "ASUS", "P5ND2-SLI Deluxe", 0, OK, nvidia_mcp_gpio10_raise}, + {0x10DE, 0x0260, 0x1043, 0x81BC, 0x10DE, 0x026C, 0x1043, 0x829E, "^P5N-D$", NULL, NULL, P3, "ASUS", "P5N-D", 0, OK, it8718f_gpio63_raise}, + {0x10DE, 0x0260, 0x1043, 0x81BC, 0x10DE, 0x026C, 0x1043, 0x8249, "^P5N-E SLI$",NULL, NULL, P3, "ASUS", "P5N-E SLI", 0, NT, it8718f_gpio63_raise}, + {0x8086, 0x24dd, 0x1043, 0x80a6, 0x8086, 0x2570, 0x1043, 0x8157, NULL, NULL, NULL, P3, "ASUS", "P5PE-VM", 0, OK, intel_ich_gpio21_raise}, + {0x8086, 0x2443, 0x1043, 0x8027, 0x8086, 0x1130, 0x1043, 0x8027, "^CUSL2-C", NULL, NULL, P3, "ASUS", "CUSL2-C", 0, OK, intel_ich_gpio21_raise}, + {0x8086, 0x2443, 0x1043, 0x8027, 0x8086, 0x1130, 0x1043, 0x8027, "^TUSL2-C", NULL, NULL, P3, "ASUS", "TUSL2-C", 0, NT, intel_ich_gpio21_raise}, ++ {0x1106, 0x3059, 0x1106, 0x4161, 0x1106, 0x3065, 0x1106, 0x0102, NULL, NULL, NULL, P3, "Bcom/Clientron", "WinNET P680", 0, OK, w836xx_memw_enable_2e}, + {0x1106, 0x3177, 0x1106, 0x3177, 0x1106, 0x3116, 0x1106, 0x3116, "^KM266-8235$", "biostar", "m7viq", P3, "Biostar", "M7VIQ", 0, NT, w83697xx_memw_enable_2e}, + {0x10b7, 0x9055, 0x1028, 0x0082, 0x8086, 0x7190, 0, 0, NULL, NULL, NULL, P3, "Dell", "OptiPlex GX1", 0, OK, intel_piix4_gpo30_lower}, + {0x8086, 0x3590, 0x1028, 0x016c, 0x1000, 0x0030, 0x1028, 0x016c, NULL, NULL, NULL, P3, "Dell", "PowerEdge 1850", 0, OK, intel_ich_gpio23_raise}, +@@ -2452,6 +2458,12 @@ const struct board_match board_matches[] = { + {0x1106, 0x0259, 0x1106, 0xAA07, 0x1106, 0x3227, 0x1106, 0xAA07, NULL, NULL, NULL, P3, "VIA", "EPIA EK", 0, NT, via_vt823x_gpio9_raise}, + {0x1106, 0x3177, 0x1106, 0xAA01, 0x1106, 0x3123, 0x1106, 0xAA01, NULL, NULL, NULL, P3, "VIA", "EPIA M/MII/...", 0, OK, via_vt823x_gpio15_raise}, + {0x1106, 0x0259, 0x1106, 0x3227, 0x1106, 0x3065, 0x1106, 0x3149, NULL, NULL, NULL, P3, "VIA", "EPIA-N/NL", 0, OK, via_vt823x_gpio9_raise}, ++#ifdef DELL_AVOTON_SUPPORT ++ {0x8086, 0x1f38, 0x8086, 0x7270, 0, 0, 0, 0, NULL, NULL, NULL, P2, "DELL", "AVOTON", 0, OK, p2_not_a_laptop}, ++#endif ++#if DELL_DENVERTON_SUPPORT == 1 ++ {0x8086, 0x19dc, 0x8086, 0x7270, 0, 0, 0, 0, NULL, NULL, NULL, P2, "DELL", "DENVERTON", 0, OK, p2_not_a_laptop}, ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + #endif + { 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, P3, NULL, NULL, 0, NT, NULL}, /* end marker */ + }; +@@ -2559,6 +2571,7 @@ const static struct board_match *board_match_pci_ids(enum board_match_phase phas + } + } + ++#if defined(__i386__) || defined(__x86_64__) + if (board->dmi_pattern) { + if (!has_dmi_support) { + msg_pwarn("Warning: Can't autodetect %s %s, DMI info unavailable.\n", +@@ -2571,7 +2584,7 @@ const static struct board_match *board_match_pci_ids(enum board_match_phase phas + continue; + } + } +- ++#endif // defined(__i386__) || defined(__x86_64__) + return board; + } + +diff --git a/buspirate_spi.c b/buspirate_spi.c +index 9d229f4..f0e84bc 100644 +--- a/buspirate_spi.c ++++ b/buspirate_spi.c +@@ -250,6 +250,7 @@ int buspirate_spi_init(void) + if (!bp_commbuf) { + bp_commbufsize = 0; + msg_perr("Out of memory!\n"); ++ free(dev); + return ERROR_OOM; + } + bp_commbufsize = DEFAULT_BUFSIZE; +@@ -263,8 +264,12 @@ int buspirate_spi_init(void) + return ret; + } + +- if (register_shutdown(buspirate_spi_shutdown, NULL)) ++ if (register_shutdown(buspirate_spi_shutdown, NULL) != 0) { ++ bp_commbufsize = 0; ++ free(bp_commbuf); ++ bp_commbuf = NULL; + return 1; ++ } + + /* This is the brute force version, but it should work. + * It is likely to fail if a previous flashrom run was aborted during a write with the new SPI commands +diff --git a/cbtable.c b/cbtable.c +index e262a84..c100bbb 100644 +--- a/cbtable.c ++++ b/cbtable.c +@@ -261,7 +261,7 @@ int cb_parse_table(const char **vendor, const char **model) + #else + start = 0x0; + #endif +- table_area = physmap_try_ro("low megabyte", start, BYTES_TO_MAP - start); ++ table_area = physmap_ro_unaligned("low megabyte", start, BYTES_TO_MAP - start); + if (ERROR_PTR == table_area) { + msg_perr("Failed getting access to coreboot low tables.\n"); + return -1; +@@ -276,8 +276,9 @@ int cb_parse_table(const char **vendor, const char **model) + if (forward->tag == LB_TAG_FORWARD) { + start = forward->forward; + start &= ~(getpagesize() - 1); +- physunmap(table_area, BYTES_TO_MAP); +- table_area = physmap_try_ro("high tables", start, BYTES_TO_MAP); ++ physunmap_unaligned(table_area, BYTES_TO_MAP); ++ // FIXME: table_area is never unmapped below, nor is it unmapped above in the no-forward case ++ table_area = physmap_ro_unaligned("high tables", start, BYTES_TO_MAP); + if (ERROR_PTR == table_area) { + msg_perr("Failed getting access to coreboot high tables.\n"); + return -1; +diff --git a/chipdrivers.h b/chipdrivers.h +index 091d14c..851e90a 100644 +--- a/chipdrivers.h ++++ b/chipdrivers.h +@@ -64,6 +64,7 @@ int spi_write_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start, + /* spi25_statusreg.c */ + uint8_t spi_read_status_register(struct flashctx *flash); + int spi_write_status_register(struct flashctx *flash, int status); ++void spi_prettyprint_status_register_bit(uint8_t status, int bit); + int spi_prettyprint_status_register_plain(struct flashctx *flash); + int spi_prettyprint_status_register_default_welwip(struct flashctx *flash); + int spi_prettyprint_status_register_default_bp1(struct flashctx *flash); +@@ -109,6 +110,19 @@ int read_opaque(struct flashctx *flash, uint8_t *buf, unsigned int start, unsign + int write_opaque(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); + int erase_opaque(struct flashctx *flash, unsigned int blockaddr, unsigned int blocklen); + ++/* at45db.c */ ++int probe_spi_at45db(struct flashctx *flash); ++int spi_prettyprint_status_register_at45db(struct flashctx *flash); ++int spi_disable_blockprotect_at45db(struct flashctx *flash); ++int spi_read_at45db(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); ++int spi_read_at45db_e8(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); ++int spi_write_at45db(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); ++int spi_erase_at45db_page(struct flashctx *flash, unsigned int addr, unsigned int blocklen); ++int spi_erase_at45db_block(struct flashctx *flash, unsigned int addr, unsigned int blocklen); ++int spi_erase_at45db_sector(struct flashctx *flash, unsigned int addr, unsigned int blocklen); ++int spi_erase_at45db_chip(struct flashctx *flash, unsigned int addr, unsigned int blocklen); ++int spi_erase_at45cs_sector(struct flashctx *flash, unsigned int addr, unsigned int blocklen); ++ + /* 82802ab.c */ + uint8_t wait_82802ab(struct flashctx *flash); + int probe_82802ab(struct flashctx *flash); +@@ -179,9 +193,10 @@ int printlock_at49f(struct flashctx *flash); + /* w29ee011.c */ + int probe_w29ee011(struct flashctx *flash); + +-/* stm50flw0x0x.c */ +-int erase_sector_stm50flw0x0x(struct flashctx *flash, unsigned int block, unsigned int blocksize); +-int unlock_stm50flw0x0x(struct flashctx *flash); ++/* stm50.c */ ++int erase_sector_stm50(struct flashctx *flash, unsigned int block, unsigned int blocksize); ++int unlock_stm50_uniform(struct flashctx *flash); ++int unlock_stm50_nonuniform(struct flashctx *flash); + + /* en29lv640b.c */ + int probe_en29lv640b(struct flashctx *flash); +diff --git a/chipset_enable.c b/chipset_enable.c +index a2df263..8a8ab66 100644 +--- a/chipset_enable.c ++++ b/chipset_enable.c +@@ -41,6 +41,17 @@ + + #if defined(__i386__) || defined(__x86_64__) + ++#if DELL_AVOTON_SUPPORT == 1 ++uint8_t is_avoton = 0; ++#endif /* DELL_AVOTON_SUPPORT == 1 */ ++ ++#if DELL_DENVERTON_SUPPORT == 1 ++uint8_t is_dnv = 0; ++uint32_t dnv_bios_region_start = 0x00; ++uint32_t dnv_bios_region_size = 0x00; ++uint32_t dnv_bios_region_limit = 0x00; ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ ++ + static int enable_flash_ali_m1533(struct pci_dev *dev, const char *name) + { + uint8_t tmp; +@@ -260,20 +271,44 @@ static int enable_flash_piix4(struct pci_dev *dev, const char *name) + return 0; + } + +-/* +- * See ie. page 375 of "Intel I/O Controller Hub 7 (ICH7) Family Datasheet" +- * http://download.intel.com/design/chipsets/datashts/30701303.pdf +- */ +-static int enable_flash_ich(struct pci_dev *dev, const char *name, uint8_t bios_cntl) ++/* Note: the ICH0-ICH5 BIOS_CNTL register is actually 16 bit wide, in Poulsbo, Tunnel Creek and other Atom ++ * chipsets/SoCs it is even 32b, but just treating it as 8 bit wide seems to work fine in practice. */ ++static int enable_flash_ich_bios_cntl(struct pci_dev *dev, enum ich_chipset ich_generation, uint8_t bios_cntl) + { + uint8_t old, new, wanted; + +- /* +- * Note: the ICH0-ICH5 BIOS_CNTL register is actually 16 bit wide, in Tunnel Creek it is even 32b, but +- * just treating it as 8 bit wide seems to work fine in practice. +- */ +- wanted = old = pci_read_byte(dev, bios_cntl); ++ switch (ich_generation) { ++ case CHIPSET_ICH_UNKNOWN: ++ return ERROR_FATAL; ++ /* Non-SPI-capable */ ++ case CHIPSET_ICH: ++ case CHIPSET_ICH2345: ++ break; ++ /* Atom chipsets are special: The second byte of BIOS_CNTL (D9h) contains a prefetch bit similar to what ++ * other SPI-capable chipsets have at DCh. ++ * The Tunnel Creek datasheet contains a lot of details about the SPI controller, among other things it ++ * mentions that the prefetching and caching does only happen for direct memory reads. ++ * Therefore - at least for Tunnel Creek - it should not matter to flashrom because we use the ++ * programmed access only and not memory mapping. */ ++ case CHIPSET_TUNNEL_CREEK: ++ case CHIPSET_POULSBO: ++ case CHIPSET_CENTERTON: ++ old = pci_read_byte(dev, bios_cntl + 1); ++ msg_pdbg("BIOS Prefetch Enable: %sabled, ", (old & 1) ? "en" : "dis"); ++ break; ++ case CHIPSET_ICH7: ++ default: /* Future version might behave the same */ ++ old = (pci_read_byte(dev, bios_cntl) >> 2) & 0x3; ++ msg_pdbg("SPI Read Configuration: "); ++ if (old == 3) ++ msg_pdbg("invalid prefetching/caching settings, "); ++ else ++ msg_pdbg("prefetching %sabled, caching %sabled, ", ++ (old & 0x2) ? "en" : "dis", ++ (old & 0x1) ? "dis" : "en"); ++ } + ++ wanted = old = pci_read_byte(dev, bios_cntl); + /* + * Quote from the 6 Series datasheet (Document Number: 324645-004): + * "Bit 5: SMM BIOS Write Protect Disable (SMM_BWP) +@@ -283,11 +318,23 @@ static int enable_flash_ich(struct pci_dev *dev, const char *name, uint8_t bios_ + * + * Try to unset it in any case. + * It won't hurt and makes sense in some cases according to Stefan Reinauer. ++ * ++ * At least in Centerton aforementioned bit is located at bit 7. It is unspecified in all other Atom ++ * and Desktop chipsets before Ibex Peak/5 Series, but we reset bit 5 anyway. + */ +- wanted &= ~(1 << 5); ++ int smm_bwp_bit; ++ if (ich_generation == CHIPSET_CENTERTON) ++ smm_bwp_bit = 7; ++ else ++ smm_bwp_bit = 5; ++ wanted &= ~(1 << smm_bwp_bit); + +- /* Set BIOS Write Enable */ +- wanted |= (1 << 0); ++ /* Tunnel Creek has a cache disable at bit 2 of the lowest BIOS_CNTL byte. */ ++ if (ich_generation == CHIPSET_TUNNEL_CREEK) ++ wanted |= (1 << 2); ++ ++ wanted |= (1 << 0); /* Set BIOS Write Enable */ ++ wanted &= ~(1 << 1); /* Disable lock (futile) */ + + /* Only write the register if it's necessary */ + if (wanted != old) { +@@ -299,64 +346,79 @@ static int enable_flash_ich(struct pci_dev *dev, const char *name, uint8_t bios_ + msg_pdbg("\nBIOS_CNTL = 0x%02x: ", new); + msg_pdbg("BIOS Lock Enable: %sabled, ", (new & (1 << 1)) ? "en" : "dis"); + msg_pdbg("BIOS Write Enable: %sabled\n", (new & (1 << 0)) ? "en" : "dis"); +- if (new & (1 << 5)) ++ if (new & (1 << smm_bwp_bit)) + msg_pwarn("Warning: BIOS region SMM protection is enabled!\n"); + +- + if (new != wanted) +- msg_pwarn("Warning: Setting Bios Control at 0x%x from 0x%02x to 0x%02x on %s failed.\n" +- "New value is 0x%02x.\n", bios_cntl, old, wanted, name, new); ++ msg_pwarn("Warning: Setting Bios Control at 0x%x from 0x%02x to 0x%02x failed.\n" ++ "New value is 0x%02x.\n", bios_cntl, old, wanted, new); + +- /* Return an error if we could not set the write enable */ ++ /* Return an error if we could not set the write enable only. */ + if (!(new & (1 << 0))) + return -1; + + return 0; + } + +-static int enable_flash_ich_4e(struct pci_dev *dev, const char *name) ++static int enable_flash_ich_fwh_decode(struct pci_dev *dev, enum ich_chipset ich_generation) + { +- /* +- * Note: ICH5 has registers similar to FWH_SEL1, FWH_SEL2 and +- * FWH_DEC_EN1, but they are called FB_SEL1, FB_SEL2, FB_DEC_EN1 and +- * FB_DEC_EN2. +- */ +- internal_buses_supported = BUS_FWH; +- return enable_flash_ich(dev, name, 0x4e); +-} +- +-static int enable_flash_ich_dc(struct pci_dev *dev, const char *name) +-{ +- uint32_t fwh_conf; +- int i, tmp; +- char *idsel = NULL; +- int max_decode_fwh_idsel = 0, max_decode_fwh_decode = 0; +- int contiguous = 1; ++ uint8_t fwh_sel1 = 0, fwh_sel2 = 0, fwh_dec_en_lo = 0, fwh_dec_en_hi = 0; /* silence compilers */ ++ bool implemented = 0; ++ switch (ich_generation) { ++ case CHIPSET_ICH: ++ /* FIXME: Unlike later chipsets, ICH and ICH-0 do only support mapping of the top-most 4MB ++ * and therefore do only feature FWH_DEC_EN (E3h, different default too) and FWH_SEL (E8h). */ ++ break; ++ case CHIPSET_ICH2345: ++ fwh_sel1 = 0xe8; ++ fwh_sel2 = 0xee; ++ fwh_dec_en_lo = 0xf0; ++ fwh_dec_en_hi = 0xe3; ++ implemented = 1; ++ break; ++ case CHIPSET_POULSBO: ++ case CHIPSET_TUNNEL_CREEK: ++ /* FIXME: Similar to ICH and ICH-0, Tunnel Creek and Poulsbo do only feature one register each, ++ * FWH_DEC_EN (D7h) and FWH_SEL (D0h). */ ++ break; ++ case CHIPSET_CENTERTON: ++ /* FIXME: Similar to above FWH_DEC_EN (D4h) and FWH_SEL (D0h). */ ++ break; ++ case CHIPSET_ICH6: ++ case CHIPSET_ICH7: ++ default: /* Future version might behave the same */ ++ fwh_sel1 = 0xd0; ++ fwh_sel2 = 0xd4; ++ fwh_dec_en_lo = 0xd8; ++ fwh_dec_en_hi = 0xd9; ++ implemented = 1; ++ break; ++ } + +- idsel = extract_programmer_param("fwh_idsel"); ++ char *idsel = extract_programmer_param("fwh_idsel"); + if (idsel && strlen(idsel)) { +- uint64_t fwh_idsel_old, fwh_idsel; ++ if (!implemented) { ++ msg_perr("Error: fwh_idsel= specified, but (yet) unsupported on this chipset.\n"); ++ goto idsel_garbage_out; ++ } + errno = 0; + /* Base 16, nothing else makes sense. */ +- fwh_idsel = (uint64_t)strtoull(idsel, NULL, 16); ++ uint64_t fwh_idsel = (uint64_t)strtoull(idsel, NULL, 16); + if (errno) { +- msg_perr("Error: fwh_idsel= specified, but value could " +- "not be converted.\n"); ++ msg_perr("Error: fwh_idsel= specified, but value could not be converted.\n"); + goto idsel_garbage_out; + } + if (fwh_idsel & 0xffff000000000000ULL) { +- msg_perr("Error: fwh_idsel= specified, but value had " +- "unused bits set.\n"); ++ msg_perr("Error: fwh_idsel= specified, but value had unused bits set.\n"); + goto idsel_garbage_out; + } +- fwh_idsel_old = pci_read_long(dev, 0xd0); ++ uint64_t fwh_idsel_old = pci_read_long(dev, fwh_sel1); + fwh_idsel_old <<= 16; +- fwh_idsel_old |= pci_read_word(dev, 0xd4); +- msg_pdbg("\nSetting IDSEL from 0x%012" PRIx64 " to " +- "0x%012" PRIx64 " for top 16 MB.", fwh_idsel_old, +- fwh_idsel); +- rpci_write_long(dev, 0xd0, (fwh_idsel >> 16) & 0xffffffff); +- rpci_write_word(dev, 0xd4, fwh_idsel & 0xffff); ++ fwh_idsel_old |= pci_read_word(dev, fwh_sel2); ++ msg_pdbg("\nSetting IDSEL from 0x%012" PRIx64 " to 0x%012" PRIx64 " for top 16 MB.", ++ fwh_idsel_old, fwh_idsel); ++ rpci_write_long(dev, fwh_sel1, (fwh_idsel >> 16) & 0xffffffff); ++ rpci_write_word(dev, fwh_sel2, fwh_idsel & 0xffff); + /* FIXME: Decode settings are not changed. */ + } else if (idsel) { + msg_perr("Error: fwh_idsel= specified, but no value given.\n"); +@@ -366,15 +428,23 @@ idsel_garbage_out: + } + free(idsel); + ++ if (!implemented) { ++ msg_pdbg2("FWH IDSEL handling is not implemented on this chipset."); ++ return 0; ++ } ++ + /* Ignore all legacy ranges below 1 MB. + * We currently only support flashing the chip which responds to + * IDSEL=0. To support IDSEL!=0, flashbase and decode size calculations + * have to be adjusted. + */ ++ int max_decode_fwh_idsel = 0, max_decode_fwh_decode = 0; ++ bool contiguous = 1; ++ uint32_t fwh_conf = pci_read_long(dev, fwh_sel1); ++ int i; + /* FWH_SEL1 */ +- fwh_conf = pci_read_long(dev, 0xd0); + for (i = 7; i >= 0; i--) { +- tmp = (fwh_conf >> (i * 4)) & 0xf; ++ int tmp = (fwh_conf >> (i * 4)) & 0xf; + msg_pdbg("\n0x%08x/0x%08x FWH IDSEL: 0x%x", + (0x1ff8 + i) * 0x80000, + (0x1ff0 + i) * 0x80000, +@@ -386,9 +456,9 @@ idsel_garbage_out: + } + } + /* FWH_SEL2 */ +- fwh_conf = pci_read_word(dev, 0xd4); ++ fwh_conf = pci_read_word(dev, fwh_sel2); + for (i = 3; i >= 0; i--) { +- tmp = (fwh_conf >> (i * 4)) & 0xf; ++ int tmp = (fwh_conf >> (i * 4)) & 0xf; + msg_pdbg("\n0x%08x/0x%08x FWH IDSEL: 0x%x", + (0xff4 + i) * 0x100000, + (0xff0 + i) * 0x100000, +@@ -401,9 +471,11 @@ idsel_garbage_out: + } + contiguous = 1; + /* FWH_DEC_EN1 */ +- fwh_conf = pci_read_word(dev, 0xd8); ++ fwh_conf = pci_read_byte(dev, fwh_dec_en_hi); ++ fwh_conf <<= 8; ++ fwh_conf |= pci_read_byte(dev, fwh_dec_en_lo); + for (i = 7; i >= 0; i--) { +- tmp = (fwh_conf >> (i + 0x8)) & 0x1; ++ int tmp = (fwh_conf >> (i + 0x8)) & 0x1; + msg_pdbg("\n0x%08x/0x%08x FWH decode %sabled", + (0x1ff8 + i) * 0x80000, + (0x1ff0 + i) * 0x80000, +@@ -415,7 +487,7 @@ idsel_garbage_out: + } + } + for (i = 3; i >= 0; i--) { +- tmp = (fwh_conf >> i) & 0x1; ++ int tmp = (fwh_conf >> i) & 0x1; + msg_pdbg("\n0x%08x/0x%08x FWH decode %sabled", + (0xff4 + i) * 0x100000, + (0xff0 + i) * 0x100000, +@@ -429,99 +501,66 @@ idsel_garbage_out: + max_rom_decode.fwh = min(max_decode_fwh_idsel, max_decode_fwh_decode); + msg_pdbg("\nMaximum FWH chip size: 0x%x bytes", max_rom_decode.fwh); + +- /* If we're called by enable_flash_ich_dc_spi, it will override +- * internal_buses_supported anyway. +- */ +- internal_buses_supported = BUS_FWH; +- return enable_flash_ich(dev, name, 0xdc); ++ return 0; + } + +-static int enable_flash_poulsbo(struct pci_dev *dev, const char *name) ++static int enable_flash_ich_fwh(struct pci_dev *dev, enum ich_chipset ich_generation, uint8_t bios_cntl) + { +- uint16_t old, new; + int err; + +- if ((err = enable_flash_ich(dev, name, 0xd8)) != 0) ++ /* Configure FWH IDSEL decoder maps. */ ++ if ((err = enable_flash_ich_fwh_decode(dev, ich_generation)) != 0) + return err; + +- old = pci_read_byte(dev, 0xd9); +- msg_pdbg("BIOS Prefetch Enable: %sabled, ", +- (old & 1) ? "en" : "dis"); +- new = old & ~1; +- +- if (new != old) +- rpci_write_byte(dev, 0xd9, new); +- + internal_buses_supported = BUS_FWH; +- return 0; ++ return enable_flash_ich_bios_cntl(dev, ich_generation, bios_cntl); + } + +-static int enable_flash_tunnelcreek(struct pci_dev *dev, const char *name) ++static int enable_flash_ich0(struct pci_dev *dev, const char *name) + { +- uint16_t old, new; +- uint32_t tmp, bnt; +- void *rcrb; +- int ret; +- +- /* Enable Flash Writes */ +- ret = enable_flash_ich(dev, name, 0xd8); +- if (ret == ERROR_FATAL) +- return ret; +- +- /* Make sure BIOS prefetch mechanism is disabled */ +- old = pci_read_byte(dev, 0xd9); +- msg_pdbg("BIOS Prefetch Enable: %sabled, ", (old & 1) ? "en" : "dis"); +- new = old & ~1; +- if (new != old) +- rpci_write_byte(dev, 0xd9, new); +- +- /* Get physical address of Root Complex Register Block */ +- tmp = pci_read_long(dev, 0xf0) & 0xffffc000; +- msg_pdbg("\nRoot Complex Register Block address = 0x%x\n", tmp); +- +- /* Map RCBA to virtual memory */ +- rcrb = physmap("ICH RCRB", tmp, 0x4000); +- +- /* Test Boot BIOS Strap Status */ +- bnt = mmio_readl(rcrb + 0x3410); +- if (bnt & 0x02) { +- /* If strapped to LPC, no SPI initialization is required */ +- internal_buses_supported = BUS_FWH; +- return 0; +- } ++ return enable_flash_ich_fwh(dev, CHIPSET_ICH, 0x4e); ++} + +- /* This adds BUS_SPI */ +- if (ich_init_spi(dev, tmp, rcrb, 7) != 0) { +- if (!ret) +- ret = ERROR_NONFATAL; +- } ++static int enable_flash_ich2345(struct pci_dev *dev, const char *name) ++{ ++ return enable_flash_ich_fwh(dev, CHIPSET_ICH2345, 0x4e); ++} + +- return ret; ++static int enable_flash_ich6(struct pci_dev *dev, const char *name) ++{ ++ return enable_flash_ich_fwh(dev, CHIPSET_ICH6, 0xdc); + } + +-static int enable_flash_ich_dc_spi(struct pci_dev *dev, const char *name, +- enum ich_chipset ich_generation) ++static int enable_flash_poulsbo(struct pci_dev *dev, const char *name) + { +- int ret, ret_spi; +- uint8_t bbs, buc; +- uint32_t tmp, gcs; +- void *rcrb; +- const char *const *straps_names; ++ return enable_flash_ich_fwh(dev, CHIPSET_POULSBO, 0xd8); ++} + ++static int enable_flash_ich_spi(struct pci_dev *dev, enum ich_chipset ich_generation, uint8_t bios_cntl) ++{ + static const char *const straps_names_EP80579[] = { "SPI", "reserved", "reserved", "LPC" }; + static const char *const straps_names_ich7_nm10[] = { "reserved", "SPI", "PCI", "LPC" }; ++ static const char *const straps_names_tunnel_creek[] = { "SPI", "LPC" }; + static const char *const straps_names_ich8910[] = { "SPI", "SPI", "PCI", "LPC" }; + static const char *const straps_names_pch567[] = { "LPC", "reserved", "PCI", "SPI" }; + static const char *const straps_names_pch8[] = { "LPC", "reserved", "reserved", "SPI" }; +- static const char *const straps_names_pch8_lp[] = { "SPI", "LPC", "unknown", "unknown" }; ++ static const char *const straps_names_pch8_lp[] = { "SPI", "LPC" }; + static const char *const straps_names_unknown[] = { "unknown", "unknown", "unknown", "unknown" }; ++#ifdef DELL_AVOTON_SUPPORT ++ static const char *const straps_names_avoton[] = { "LPC", "reserved", "reserved", "SPI" }; ++ uint32_t tmp; ++ int ret_fwh = 0; ++ uint32_t new, old; ++ void *spibar; ++#endif + ++ const char *const *straps_names; + switch (ich_generation) { + case CHIPSET_ICH7: + /* EP80579 may need further changes, but this is the least + * intrusive way to get correct BOOT Strap printing without + * changing the rest of its code path). */ +- if (strcmp(name, "EP80579") == 0) ++ if (dev->device_id == 0x5031) + straps_names = straps_names_EP80579; + else + straps_names = straps_names_ich7_nm10; +@@ -531,6 +570,9 @@ static int enable_flash_ich_dc_spi(struct pci_dev *dev, const char *name, + case CHIPSET_ICH10: + straps_names = straps_names_ich8910; + break; ++ case CHIPSET_TUNNEL_CREEK: ++ straps_names = straps_names_tunnel_creek; ++ break; + case CHIPSET_5_SERIES_IBEX_PEAK: + case CHIPSET_6_SERIES_COUGAR_POINT: + case CHIPSET_7_SERIES_PANTHER_POINT: +@@ -543,33 +585,41 @@ static int enable_flash_ich_dc_spi(struct pci_dev *dev, const char *name, + straps_names = straps_names_pch8_lp; + break; + case CHIPSET_8_SERIES_WELLSBURG: // FIXME: check datasheet ++ case CHIPSET_CENTERTON: // FIXME: Datasheet does not mention GCS at all + straps_names = straps_names_unknown; + break; ++#ifdef DELL_AVOTON_SUPPORT ++ case CHIPSET_AVOTON: ++ straps_names = straps_names_avoton; ++ break; ++#endif + default: +- msg_gerr("%s: unknown ICH generation. Please report!\n", +- __func__); ++ msg_gerr("%s: unknown ICH generation. Please report!\n", __func__); + straps_names = straps_names_unknown; + break; + } + +- /* Enable Flash Writes */ +- ret = enable_flash_ich_dc(dev, name); +- if (ret == ERROR_FATAL) +- return ret; +- + /* Get physical address of Root Complex Register Block */ +- tmp = pci_read_long(dev, 0xf0) & 0xffffc000; +- msg_pdbg("Root Complex Register Block address = 0x%x\n", tmp); ++ uint32_t rcra = pci_read_long(dev, 0xf0) & 0xffffc000; ++ msg_pdbg("Root Complex Register Block address = 0x%x\n", rcra); + + /* Map RCBA to virtual memory */ +- rcrb = physmap("ICH RCRB", tmp, 0x4000); ++ void *rcrb = rphysmap("ICH RCRB", rcra, 0x4000); ++ if (rcrb == ERROR_PTR) ++ return ERROR_FATAL; + +- gcs = mmio_readl(rcrb + 0x3410); ++#ifdef DELL_AVOTON_SUPPORT ++ if (ich_generation != CHIPSET_AVOTON) { ++#endif ++ uint32_t gcs = mmio_readl(rcrb + 0x3410); + msg_pdbg("GCS = 0x%x: ", gcs); +- msg_pdbg("BIOS Interface Lock-Down: %sabled, ", +- (gcs & 0x1) ? "en" : "dis"); ++ msg_pdbg("BIOS Interface Lock-Down: %sabled, ", (gcs & 0x1) ? "en" : "dis"); + ++ uint8_t bbs; + switch (ich_generation) { ++ case CHIPSET_TUNNEL_CREEK: ++ bbs = (gcs >> 1) & 0x1; ++ break; + case CHIPSET_8_SERIES_LYNX_POINT_LP: + case CHIPSET_8_SERIES_WELLSBURG: // FIXME: check datasheet + /* Lynx Point LP uses a single bit for GCS */ +@@ -582,91 +632,187 @@ static int enable_flash_ich_dc_spi(struct pci_dev *dev, const char *name, + } + msg_pdbg("Boot BIOS Straps: 0x%x (%s)\n", bbs, straps_names[bbs]); + +- buc = mmio_readb(rcrb + 0x3414); +- msg_pdbg("Top Swap : %s\n", +- (buc & 1) ? "enabled (A16 inverted)" : "not enabled"); ++ if (ich_generation != CHIPSET_TUNNEL_CREEK && ich_generation != CHIPSET_CENTERTON) { ++ uint8_t buc = mmio_readb(rcrb + 0x3414); ++ msg_pdbg("Top Swap : %s\n", (buc & 1) ? "enabled (A16(+) inverted)" : "not enabled"); ++ } + +- /* It seems the ICH7 does not support SPI and LPC chips at the same +- * time. At least not with our current code. So we prevent searching +- * on ICH7 when the southbridge is strapped to LPC +- */ +- internal_buses_supported = BUS_FWH; +- if (ich_generation == CHIPSET_ICH7) { +- if (bbs == 0x03) { +- /* If strapped to LPC, no further SPI initialization is +- * required. */ +- return ret; +- } else { +- /* Disable LPC/FWH if strapped to PCI or SPI */ +- internal_buses_supported = BUS_NONE; +- } ++ /* Handle FWH-related parameters and initialization */ ++#ifdef DELL_AVOTON_SUPPORT ++ ret_fwh = enable_flash_ich_fwh(dev, ich_generation, bios_cntl); ++#else ++ int ret_fwh = enable_flash_ich_fwh(dev, ich_generation, bios_cntl); ++#endif ++ if (ret_fwh == ERROR_FATAL) ++ return ret_fwh; ++ ++ /* SPIBAR is at RCRB+0x3020 for ICH[78], Tunnel Creek and Centerton, and RCRB+0x3800 for ICH9. */ ++ uint16_t spibar_offset; ++ switch (ich_generation) { ++ case CHIPSET_ICH_UNKNOWN: ++ return ERROR_FATAL; ++ case CHIPSET_ICH7: ++ case CHIPSET_ICH8: ++ case CHIPSET_TUNNEL_CREEK: ++ case CHIPSET_CENTERTON: ++ spibar_offset = 0x3020; ++ break; ++ case CHIPSET_ICH9: ++ default: /* Future version might behave the same */ ++ spibar_offset = 0x3800; ++ break; + } ++ msg_pdbg("SPIBAR = 0x%0*" PRIxPTR " + 0x%04x\n", PRIxPTR_WIDTH, (uintptr_t)rcrb, spibar_offset); ++#ifndef DELL_AVOTON_SUPPORT ++ void *spibar = rcrb + spibar_offset; ++#else ++ spibar = rcrb + spibar_offset; ++ } else { ++ tmp = pci_read_long(dev, 0x54) & 0xFFFFFE00; ++ spibar = rphysmap("ICH SPIBAR", tmp, 0x4000); ++ msg_pdbg("SPIBAR = 0x%x\n", tmp); ++ ++ /* BIOS Control Register */ ++ tmp = mmio_readl(spibar + bios_cntl); ++ msg_pdbg("0xFC: 0x%08x (BIOS_CONTROL_REGISTER_BIOS : BCR)\n", tmp); ++ msg_pdbg("BIOS Write Protect Disable : %sabled, \n", ++ (tmp & (1 << 0)) ? "en" : "dis"); ++ msg_pdbg("\nBIOS Lock Enable: %sabled, \n", ++ (tmp & (1 << 1)) ? "en" : "dis"); ++ if (tmp != 1) { ++ mmio_writel(0x1, (spibar + bios_cntl)); ++ } ++ tmp = mmio_readl(spibar + bios_cntl); ++ msg_pdbg("0xFC: 0x%08x (BIOS_CONTROL_REGISTER_BIOS : BCR)\n", tmp); ++ msg_pdbg("BIOS Write Protect Disable : %sabled, \n", ++ (tmp & (1 << 0)) ? "en" : "dis"); ++ if (tmp != 1) { ++ msg_perr("Reboot and change BIOS-> IntelRCSetup -> Relax Security Config -> Disabled to Enabled\n"); ++ return ERROR_FATAL; /* Signal error */ ++ } ++ old = mmio_readb(spibar + 0xFC); ++ msg_pdbg("SPI Read Configuration: \n"); ++ new = (old >> 2) & 0x3; ++ switch (new) { ++ case 0: ++ case 1: ++ case 2: ++ msg_pdbg("prefetching %sabled, caching %sabled, \n", ++ (new & 0x2) ? "en" : "dis", ++ (new & 0x1) ? "dis" : "en"); ++ break; ++ default: ++ msg_pdbg("invalid prefetching/caching settings, \n"); ++ break; ++ } ++ } ++#endif ++ + + /* This adds BUS_SPI */ +- ret_spi = ich_init_spi(dev, tmp, rcrb, ich_generation); ++ int ret_spi = ich_init_spi(dev, spibar, ich_generation); + if (ret_spi == ERROR_FATAL) + return ret_spi; + +- if (ret || ret_spi) +- ret = ERROR_NONFATAL; ++ if (ret_fwh || ret_spi) ++ return ERROR_NONFATAL; + +- return ret; ++ return 0; ++} ++ ++static int enable_flash_tunnelcreek(struct pci_dev *dev, const char *name) ++{ ++ return enable_flash_ich_spi(dev, CHIPSET_TUNNEL_CREEK, 0xd8); ++} ++ ++static int enable_flash_s12x0(struct pci_dev *dev, const char *name) ++{ ++ return enable_flash_ich_spi(dev, CHIPSET_CENTERTON, 0xd8); + } + + static int enable_flash_ich7(struct pci_dev *dev, const char *name) + { +- return enable_flash_ich_dc_spi(dev, name, CHIPSET_ICH7); ++ return enable_flash_ich_spi(dev, CHIPSET_ICH7, 0xdc); + } + + static int enable_flash_ich8(struct pci_dev *dev, const char *name) + { +- return enable_flash_ich_dc_spi(dev, name, CHIPSET_ICH8); ++ return enable_flash_ich_spi(dev, CHIPSET_ICH8, 0xdc); + } + + static int enable_flash_ich9(struct pci_dev *dev, const char *name) + { +- return enable_flash_ich_dc_spi(dev, name, CHIPSET_ICH9); ++ return enable_flash_ich_spi(dev, CHIPSET_ICH9, 0xdc); + } + + static int enable_flash_ich10(struct pci_dev *dev, const char *name) + { +- return enable_flash_ich_dc_spi(dev, name, CHIPSET_ICH10); ++ return enable_flash_ich_spi(dev, CHIPSET_ICH10, 0xdc); + } + ++#ifdef DELL_AVOTON_SUPPORT ++static int enable_flash_c2000(struct pci_dev *dev, const char *name) ++{ ++ is_avoton = 1; ++ return enable_flash_ich_spi(dev, CHIPSET_AVOTON, 0xfc); ++} ++#endif ++ ++#if DELL_DENVERTON_SUPPORT == 1 ++static int enable_flash_denverton(struct pci_dev *dev, const char *name) ++{ ++ void *spibar; ++ int32_t ret_spi; ++ uint32_t sbase; ++ enum ich_chipset ich_generation = CHIPSET_DENVERTON; ++ ++ is_dnv = 1; ++ internal_buses_supported = BUS_FWH; ++ ++ /* GET physical address of SPI Base Address and map it */ ++ sbase = pci_read_long(dev, 0x10) & 0xfffffe00; ++ msg_pdbg("SPI_BASE_ADDRESS = 0x%x\n", sbase); ++ spibar = rphysmap("DENVERTON SBASE", sbase, 512); ++ enable_flash_ich_bios_cntl(dev, ich_generation, 0xdc); ++ ret_spi = ich_init_spi(dev, spibar, ich_generation); ++ return ret_spi; ++} ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ ++ + /* Ibex Peak aka. 5 series & 3400 series */ + static int enable_flash_pch5(struct pci_dev *dev, const char *name) + { +- return enable_flash_ich_dc_spi(dev, name, CHIPSET_5_SERIES_IBEX_PEAK); ++ return enable_flash_ich_spi(dev, CHIPSET_5_SERIES_IBEX_PEAK, 0xdc); + } + + /* Cougar Point aka. 6 series & c200 series */ + static int enable_flash_pch6(struct pci_dev *dev, const char *name) + { +- return enable_flash_ich_dc_spi(dev, name, CHIPSET_6_SERIES_COUGAR_POINT); ++ return enable_flash_ich_spi(dev, CHIPSET_6_SERIES_COUGAR_POINT, 0xdc); + } + + /* Panther Point aka. 7 series */ + static int enable_flash_pch7(struct pci_dev *dev, const char *name) + { +- return enable_flash_ich_dc_spi(dev, name, CHIPSET_7_SERIES_PANTHER_POINT); ++ return enable_flash_ich_spi(dev, CHIPSET_7_SERIES_PANTHER_POINT, 0xdc); + } + + /* Lynx Point aka. 8 series */ + static int enable_flash_pch8(struct pci_dev *dev, const char *name) + { +- return enable_flash_ich_dc_spi(dev, name, CHIPSET_8_SERIES_LYNX_POINT); ++ return enable_flash_ich_spi(dev, CHIPSET_8_SERIES_LYNX_POINT, 0xdc); + } + +-/* Lynx Point aka. 8 series low-power */ ++/* Lynx Point LP aka. 8 series low-power */ + static int enable_flash_pch8_lp(struct pci_dev *dev, const char *name) + { +- return enable_flash_ich_dc_spi(dev, name, CHIPSET_8_SERIES_LYNX_POINT_LP); ++ return enable_flash_ich_spi(dev, CHIPSET_8_SERIES_LYNX_POINT_LP, 0xdc); + } + + /* Wellsburg (for Haswell-EP Xeons) */ + static int enable_flash_pch8_wb(struct pci_dev *dev, const char *name) + { +- return enable_flash_ich_dc_spi(dev, name, CHIPSET_8_SERIES_WELLSBURG); ++ return enable_flash_ich_spi(dev, CHIPSET_8_SERIES_WELLSBURG, 0xdc); + } + + static int via_no_byte_merge(struct pci_dev *dev, const char *name) +@@ -737,10 +883,8 @@ static int enable_flash_vt_vx(struct pci_dev *dev, const char *name) + case 0x8410: /* VX900 */ + mmio_base = pci_read_long(dev, 0xbc) << 8; + mmio_base_physmapped = physmap("VIA VX MMIO register", mmio_base, SPI_CNTL_LEN); +- if (mmio_base_physmapped == ERROR_PTR) { +- physunmap(mmio_base_physmapped, SPI_CNTL_LEN); ++ if (mmio_base_physmapped == ERROR_PTR) + return ERROR_FATAL; +- } + + /* Offset 0 - Bit 0 holds SPI Bus0 Enable Bit. */ + spi_cntl = mmio_readl(mmio_base_physmapped) + 0x00; +@@ -882,22 +1026,29 @@ static int enable_flash_sc1100(struct pci_dev *dev, const char *name) + return 0; + } + +-/* Works for AMD-8111, VIA VT82C586A/B, VIA VT82C686A/B. */ +-static int enable_flash_amd8111(struct pci_dev *dev, const char *name) ++/* Works for AMD-768, AMD-8111, VIA VT82C586A/B, VIA VT82C596, VIA VT82C686A/B. ++ * ++ * ROM decode control register matrix ++ * AMD-768 AMD-8111 VT82C586A/B VT82C596 VT82C686A/B ++ * 7 FFC0_0000h–FFFF_FFFFh <- FFFE0000h-FFFEFFFFh <- <- ++ * 6 FFB0_0000h–FFBF_FFFFh <- FFF80000h-FFFDFFFFh <- <- ++ * 5 00E8... <- <- FFF00000h-FFF7FFFFh <- ++ */ ++static int enable_flash_amd_via(struct pci_dev *dev, const char *name, uint8_t decode_val) + { + #define AMD_MAPREG 0x43 + #define AMD_ENREG 0x40 + uint8_t old, new; + +- /* Enable decoding at 0xffb00000 to 0xffffffff. */ + old = pci_read_byte(dev, AMD_MAPREG); +- new = old | 0xC0; ++ new = old | decode_val; + if (new != old) { + rpci_write_byte(dev, AMD_MAPREG, new); + if (pci_read_byte(dev, AMD_MAPREG) != new) { +- msg_pinfo("Setting register 0x%x to 0x%02x on %s failed (WARNING ONLY).\n", ++ msg_pwarn("Setting register 0x%x to 0x%02x on %s failed (WARNING ONLY).\n", + AMD_MAPREG, new, name); +- } ++ } else ++ msg_pdbg("Changed ROM decode range to 0x%02x successfully.\n", new); + } + + /* Enable 'ROM write' bit. */ +@@ -908,14 +1059,37 @@ static int enable_flash_amd8111(struct pci_dev *dev, const char *name) + rpci_write_byte(dev, AMD_ENREG, new); + + if (pci_read_byte(dev, AMD_ENREG) != new) { +- msg_pinfo("Setting register 0x%x to 0x%02x on %s failed (WARNING ONLY).\n", ++ msg_pwarn("Setting register 0x%x to 0x%02x on %s failed (WARNING ONLY).\n", + AMD_ENREG, new, name); +- return -1; ++ return ERROR_NONFATAL; + } ++ msg_pdbg2("Set ROM enable bit successfully.\n"); + + return 0; + } + ++static int enable_flash_amd_768_8111(struct pci_dev *dev, const char *name) ++{ ++ /* Enable decoding of 0xFFB00000 to 0xFFFFFFFF (5 MB). */ ++ max_rom_decode.lpc = 5 * 1024 * 1024; ++ return enable_flash_amd_via(dev, name, 0xC0); ++} ++ ++static int enable_flash_vt82c586(struct pci_dev *dev, const char *name) ++{ ++ /* Enable decoding of 0xFFF80000 to 0xFFFFFFFF. (512 kB) */ ++ max_rom_decode.parallel = 512 * 1024; ++ return enable_flash_amd_via(dev, name, 0xC0); ++} ++ ++/* Works for VT82C686A/B too. */ ++static int enable_flash_vt82c596(struct pci_dev *dev, const char *name) ++{ ++ /* Enable decoding of 0xFFF80000 to 0xFFFFFFFF. (1 MB) */ ++ max_rom_decode.parallel = 1024 * 1024; ++ return enable_flash_amd_via(dev, name, 0xE0); ++} ++ + static int enable_flash_sb600(struct pci_dev *dev, const char *name) + { + uint32_t prot; +@@ -1257,6 +1431,8 @@ static int get_flashbase_sc520(struct pci_dev *dev, const char *name) + + /* 1. Map MMCR */ + mmcr = physmap("Elan SC520 MMCR", 0xfffef000, getpagesize()); ++ if (mmcr == ERROR_PTR) ++ return ERROR_FATAL; + + /* 2. Scan PAR0 (0x88) - PAR15 (0xc4) for + * BOOTCS region (PARx[31:29] = 100b)e +@@ -1302,8 +1478,8 @@ const struct penable chipset_enables[] = { + {0x1022, 0x2080, OK, "AMD", "CS5536", enable_flash_cs5536}, + {0x1022, 0x2090, OK, "AMD", "CS5536", enable_flash_cs5536}, + {0x1022, 0x3000, OK, "AMD", "Elan SC520", get_flashbase_sc520}, +- {0x1022, 0x7440, OK, "AMD", "AMD-768", enable_flash_amd8111}, +- {0x1022, 0x7468, OK, "AMD", "AMD8111", enable_flash_amd8111}, ++ {0x1022, 0x7440, OK, "AMD", "AMD-768", enable_flash_amd_768_8111}, ++ {0x1022, 0x7468, OK, "AMD", "AMD-8111", enable_flash_amd_768_8111}, + {0x1022, 0x780e, OK, "AMD", "FCH", enable_flash_sb600}, + {0x1039, 0x0406, NT, "SiS", "501/5101/5501", enable_flash_sis501}, + {0x1039, 0x0496, NT, "SiS", "85C496+497", enable_flash_sis85c496}, +@@ -1388,9 +1564,9 @@ const struct penable chipset_enables[] = { + {0x1106, 0x0691, OK, "VIA", "VT82C69x", via_no_byte_merge}, + {0x1106, 0x8601, NT, "VIA", "VT8601T", via_no_byte_merge}, + /* VIA southbridges */ +- {0x1106, 0x0586, OK, "VIA", "VT82C586A/B", enable_flash_amd8111}, +- {0x1106, 0x0596, OK, "VIA", "VT82C596", enable_flash_amd8111}, +- {0x1106, 0x0686, OK, "VIA", "VT82C686A/B", enable_flash_amd8111}, ++ {0x1106, 0x0586, OK, "VIA", "VT82C586A/B", enable_flash_vt82c586}, ++ {0x1106, 0x0596, OK, "VIA", "VT82C596", enable_flash_vt82c596}, ++ {0x1106, 0x0686, OK, "VIA", "VT82C686A/B", enable_flash_vt82c596}, + {0x1106, 0x3074, OK, "VIA", "VT8233", enable_flash_vt823x}, + {0x1106, 0x3147, OK, "VIA", "VT8233A", enable_flash_vt823x}, + {0x1106, 0x3177, OK, "VIA", "VT8235", enable_flash_vt823x}, +@@ -1405,6 +1581,7 @@ const struct penable chipset_enables[] = { + {0x1166, 0x0200, OK, "Broadcom", "OSB4", enable_flash_osb4}, + {0x1166, 0x0205, OK, "Broadcom", "HT-1000", enable_flash_ht1000}, + {0x17f3, 0x6030, OK, "RDC", "R8610/R3210", enable_flash_rdc_r8610}, ++ {0x8086, 0x0c60, NT, "Intel", "S12x0", enable_flash_s12x0}, + {0x8086, 0x122e, OK, "Intel", "PIIX", enable_flash_piix4}, + {0x8086, 0x1234, NT, "Intel", "MPIIX", enable_flash_piix4}, + {0x8086, 0x1c44, OK, "Intel", "Z68", enable_flash_pch6}, +@@ -1441,21 +1618,21 @@ const struct penable chipset_enables[] = { + {0x8086, 0x1e5f, NT, "Intel", "NM70", enable_flash_pch7}, + {0x8086, 0x2310, NT, "Intel", "DH89xxCC", enable_flash_pch7}, + {0x8086, 0x2390, NT, "Intel", "Coleto Creek", enable_flash_pch7}, +- {0x8086, 0x2410, OK, "Intel", "ICH", enable_flash_ich_4e}, +- {0x8086, 0x2420, OK, "Intel", "ICH0", enable_flash_ich_4e}, +- {0x8086, 0x2440, OK, "Intel", "ICH2", enable_flash_ich_4e}, +- {0x8086, 0x244c, OK, "Intel", "ICH2-M", enable_flash_ich_4e}, +- {0x8086, 0x2450, NT, "Intel", "C-ICH", enable_flash_ich_4e}, +- {0x8086, 0x2480, OK, "Intel", "ICH3-S", enable_flash_ich_4e}, +- {0x8086, 0x248c, OK, "Intel", "ICH3-M", enable_flash_ich_4e}, +- {0x8086, 0x24c0, OK, "Intel", "ICH4/ICH4-L", enable_flash_ich_4e}, +- {0x8086, 0x24cc, OK, "Intel", "ICH4-M", enable_flash_ich_4e}, +- {0x8086, 0x24d0, OK, "Intel", "ICH5/ICH5R", enable_flash_ich_4e}, +- {0x8086, 0x25a1, OK, "Intel", "6300ESB", enable_flash_ich_4e}, +- {0x8086, 0x2640, OK, "Intel", "ICH6/ICH6R", enable_flash_ich_dc}, +- {0x8086, 0x2641, OK, "Intel", "ICH6-M", enable_flash_ich_dc}, +- {0x8086, 0x2642, NT, "Intel", "ICH6W/ICH6RW", enable_flash_ich_dc}, +- {0x8086, 0x2670, OK, "Intel", "631xESB/632xESB/3100", enable_flash_ich_dc}, ++ {0x8086, 0x2410, OK, "Intel", "ICH", enable_flash_ich0}, ++ {0x8086, 0x2420, OK, "Intel", "ICH0", enable_flash_ich0}, ++ {0x8086, 0x2440, OK, "Intel", "ICH2", enable_flash_ich2345}, ++ {0x8086, 0x244c, OK, "Intel", "ICH2-M", enable_flash_ich2345}, ++ {0x8086, 0x2450, NT, "Intel", "C-ICH", enable_flash_ich2345}, ++ {0x8086, 0x2480, OK, "Intel", "ICH3-S", enable_flash_ich2345}, ++ {0x8086, 0x248c, OK, "Intel", "ICH3-M", enable_flash_ich2345}, ++ {0x8086, 0x24c0, OK, "Intel", "ICH4/ICH4-L", enable_flash_ich2345}, ++ {0x8086, 0x24cc, OK, "Intel", "ICH4-M", enable_flash_ich2345}, ++ {0x8086, 0x24d0, OK, "Intel", "ICH5/ICH5R", enable_flash_ich2345}, ++ {0x8086, 0x25a1, OK, "Intel", "6300ESB", enable_flash_ich2345}, ++ {0x8086, 0x2640, OK, "Intel", "ICH6/ICH6R", enable_flash_ich6}, ++ {0x8086, 0x2641, OK, "Intel", "ICH6-M", enable_flash_ich6}, ++ {0x8086, 0x2642, NT, "Intel", "ICH6W/ICH6RW", enable_flash_ich6}, ++ {0x8086, 0x2670, OK, "Intel", "631xESB/632xESB/3100", enable_flash_ich6}, + {0x8086, 0x27b0, OK, "Intel", "ICH7DH", enable_flash_ich7}, + {0x8086, 0x27b8, OK, "Intel", "ICH7/ICH7R", enable_flash_ich7}, + {0x8086, 0x27b9, OK, "Intel", "ICH7M", enable_flash_ich7}, +@@ -1570,6 +1747,12 @@ const struct penable chipset_enables[] = { + {0x8086, 0x8d5d, NT, "Intel", "Wellsburg", enable_flash_pch8_wb}, + {0x8086, 0x8d5e, NT, "Intel", "Wellsburg", enable_flash_pch8_wb}, + {0x8086, 0x8d5f, NT, "Intel", "Wellsburg", enable_flash_pch8_wb}, ++#ifdef DELL_AVOTON_SUPPORT ++ {0x8086, 0x1f38, OK, "Intel", "C2000", enable_flash_c2000}, ++#endif ++#if DELL_DENVERTON_SUPPORT == 1 ++ {0x8086, 0x19e0, OK, "Intel", "Denverton", enable_flash_denverton}, ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + #endif + {0}, + }; +@@ -1597,14 +1780,23 @@ int chipset_flash_enable(void) + chipset_enables[i].device_name); + continue; + } ++#ifdef FORCE10_SPI_CHANGE ++ msg_pdbg("Found chipset \"%s %s\"", ++ chipset_enables[i].vendor_name, ++ chipset_enables[i].device_name); ++#else + msg_pinfo("Found chipset \"%s %s\"", + chipset_enables[i].vendor_name, + chipset_enables[i].device_name); ++#endif + msg_pdbg(" with PCI ID %04x:%04x", + chipset_enables[i].vendor_id, + chipset_enables[i].device_id); ++#ifdef FORCE10_SPI_CHANGE ++ msg_pdbg(". "); ++#else + msg_pinfo(". "); +- ++#endif + if (chipset_enables[i].status == NT) { + msg_pinfo("\nThis chipset is marked as untested. If " + "you are using an up-to-date version\nof " +@@ -1614,20 +1806,44 @@ int chipset_flash_enable(void) + "flashrom@flashrom.org including a verbose " + "(-V) log.\nThank you!\n"); + } ++#ifdef FORCE10_SPI_CHANGE ++ msg_pdbg("Enabling flash write... "); ++#else + msg_pinfo("Enabling flash write... "); ++#endif + ret = chipset_enables[i].doit(dev, + chipset_enables[i].device_name); + if (ret == NOT_DONE_YET) { + ret = -2; ++#ifdef FORCE10_SPI_CHANGE ++ msg_pdbg("OK - searching further chips.\n"); ++#else + msg_pinfo("OK - searching further chips.\n"); ++#endif + } else if (ret < 0) ++#ifdef FORCE10_SPI_CHANGE ++ msg_pdbg("FAILED!\n"); ++#else + msg_pinfo("FAILED!\n"); ++#endif + else if (ret == 0) ++#ifdef FORCE10_SPI_CHANGE ++ msg_pdbg("OK.\n"); ++#else + msg_pinfo("OK.\n"); ++#endif + else if (ret == ERROR_NONFATAL) ++#ifdef FORCE10_SPI_CHANGE ++ msg_pdbg("PROBLEMS, continuing anyway\n"); ++#else + msg_pinfo("PROBLEMS, continuing anyway\n"); ++#endif + if (ret == ERROR_FATAL) { ++#ifdef FORCE10_SPI_CHANGE ++ msg_pdbg("FATAL ERROR!\n"); ++#else + msg_perr("FATAL ERROR!\n"); ++#endif + return ret; + } + } +diff --git a/cli_classic.c b/cli_classic.c +index 4c71d07..09565f4 100644 +--- a/cli_classic.c ++++ b/cli_classic.c +@@ -31,6 +31,10 @@ + #include "flashchips.h" + #include "programmer.h" + ++#if DELL_DENVERTON_SUPPORT == 1 ++extern int8_t is_dnv; ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ ++ + static void cli_classic_usage(const char *name) + { + printf("Please note that the command line interface for flashrom has changed between\n" +@@ -136,9 +140,10 @@ int main(int argc, char *argv[]) + char *tempstr = NULL; + char *pparam = NULL; + ++#ifndef FORCE10_SPI_CHANGE + print_version(); + print_banner(); +- ++#endif + if (selfcheck()) + exit(1); + +@@ -221,8 +226,6 @@ int main(int argc, char *argv[]) + free(tempstr); + cli_classic_abort_usage(); + } +- /* FIXME: A pointer to the image name is saved in a static array (of size MAX_ROMLAYOUT) +- * by register_include_arg() and needs to be freed after processing them. */ + break; + case 'L': + if (++operation_specified > 1) { +@@ -295,6 +298,9 @@ int main(int argc, char *argv[]) + "specified. Aborting.\n"); + cli_classic_abort_usage(); + } ++#ifdef FORCE10_SPI_CHANGE ++ print_version(); ++#endif + exit(0); + break; + case 'h': +@@ -372,6 +378,12 @@ int main(int argc, char *argv[]) + ret = 1; + goto out; + } ++ if (layoutfile != NULL && !write_it) { ++ msg_gerr("Layout files are currently supported for write operations only.\n"); ++ ret = 1; ++ goto out; ++ } ++ + if (process_include_args()) { + ret = 1; + goto out; +@@ -393,8 +405,13 @@ int main(int argc, char *argv[]) + if (prog == PROGRAMMER_INVALID) { + if (CONFIG_DEFAULT_PROGRAMMER != PROGRAMMER_INVALID) { + prog = CONFIG_DEFAULT_PROGRAMMER; ++#ifdef FORCE10_SPI_CHANGE ++ msg_pdbg("Using default programmer \"%s\".\n", ++ programmer_table[CONFIG_DEFAULT_PROGRAMMER].name); ++#else + msg_pinfo("Using default programmer \"%s\".\n", + programmer_table[CONFIG_DEFAULT_PROGRAMMER].name); ++#endif + } else { + msg_perr("Please select a programmer with the --programmer parameter.\n" + "Previously this was not necessary because there was a default set.\n" +@@ -489,6 +506,10 @@ int main(int argc, char *argv[]) + tempstr = flashbuses_to_text(flashes[0].chip->bustype); + msg_gdbg("Found %s flash chip \"%s\" (%d kB, %s).\n", + flashes[0].chip->vendor, flashes[0].chip->name, flashes[0].chip->total_size, tempstr); ++ if ((flashes[0].chip->total_size > flashes[0].bios_size) && (flashes[0].bios_size != 0)) { ++ msg_gdbg("BIOS Size in flash chip: %d kB\n", flashes[0].bios_size); ++ flashes[0].chip->total_size = flashes[0].bios_size; ++ } + free(tempstr); + } + +@@ -517,7 +538,19 @@ int main(int argc, char *argv[]) + * Give the chip time to settle. + */ + programmer_delay(100000); ++#if DELL_DENVERTON_SUPPORT == 1 ++ if (is_dnv) { ++ dnv_smi_open_res(); ++ dnv_smi_doit(0, NULL, SMI_ENABLE_SPI); ++ } ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + ret |= doit(fill_flash, force, filename, read_it, write_it, erase_it, verify_it); ++#if DELL_DENVERTON_SUPPORT == 1 ++ if (is_dnv) { ++ dnv_smi_doit(0, NULL, SMI_DISABLE_SPI); ++ dnv_smi_release_res(); ++ } ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + /* Note: doit() already calls programmer_shutdown(). */ + goto out; + +@@ -527,6 +560,7 @@ out: + for (i = 0; i < chipcount; i++) + free(flashes[i].chip); + ++ layout_cleanup(); + free(filename); + free(layoutfile); + free(pparam); +diff --git a/dmi.c b/dmi.c +index 242889f..25ddd93 100644 +--- a/dmi.c ++++ b/dmi.c +@@ -1,7 +1,10 @@ + /* + * This file is part of the flashrom project. + * ++ * Copyright (C) 2000-2002 Alan Cox ++ * Copyright (C) 2002-2010 Jean Delvare + * Copyright (C) 2009,2010 Michael Karcher ++ * Copyright (C) 2011-2013 Stefan Tauner + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -26,33 +29,28 @@ + #include "flash.h" + #include "programmer.h" + +-int has_dmi_support = 0; +- +-#if STANDALONE ++#if defined(__i386__) || defined(__x86_64__) + +-/* Stub to indicate missing DMI functionality. +- * has_dmi_support is 0 by default, so nothing to do here. +- * Because dmidecode is not available on all systems, the goal is to implement +- * the DMI subset we need directly in this file. +- */ +-void dmi_init(void) +-{ +-} ++/* Enable SMBIOS decoding. Currently legacy DMI decoding is enough. */ ++#define SM_SUPPORT 0 + +-int dmi_match(const char *pattern) +-{ +- return 0; +-} ++/* Strings longer than 4096 in DMI are just insane. */ ++#define DMI_MAX_ANSWER_LEN 4096 + +-#else /* STANDALONE */ ++int has_dmi_support = 0; + +-static const char *dmidecode_names[] = { +- "system-manufacturer", +- "system-product-name", +- "system-version", +- "baseboard-manufacturer", +- "baseboard-product-name", +- "baseboard-version", ++static struct { ++ const char *const keyword; ++ const uint8_t type; ++ const uint8_t offset; ++ char *value; ++} dmi_strings[] = { ++ { "system-manufacturer", 1, 0x04, NULL }, ++ { "system-product-name", 1, 0x05, NULL }, ++ { "system-version", 1, 0x06, NULL }, ++ { "baseboard-manufacturer", 2, 0x04, NULL }, ++ { "baseboard-product-name", 2, 0x05, NULL }, ++ { "baseboard-version", 2, 0x06, NULL }, + }; + + /* This list is used to identify supposed laptops. The is_laptop field has the +@@ -66,9 +64,9 @@ static const char *dmidecode_names[] = { + * The types below are the most common ones. + */ + static const struct { +- unsigned char type; +- unsigned char is_laptop; +- const char *name; ++ uint8_t type; ++ uint8_t is_laptop; ++ char *name; + } dmi_chassis_types[] = { + {0x01, 2, "Other"}, + {0x02, 2, "Unknown"}, +@@ -86,20 +84,206 @@ static const struct { + {0x18, 0, "Sealed-case PC"}, /* used by Supermicro (X8SIE) */ + }; + +-#define DMI_COMMAND_LEN_MAX 260 +-static const char *dmidecode_command = "dmidecode"; ++#if CONFIG_INTERNAL_DMI == 1 ++#if defined(__DJGPP__) || defined(FORCE10_SPI_CHANGE) /* There is no strnlen in DJGPP. FIXME: Move this to a common utility file. */ ++size_t strnlen(const char *str, size_t n) ++{ ++ size_t i; ++ for (i = 0; i < n && str[i] != '\0'; i++) ++ ; ++ return i; ++} ++#endif + +-static char *dmistrings[ARRAY_SIZE(dmidecode_names)]; ++static bool dmi_checksum(const uint8_t * const buf, size_t len) ++{ ++ uint8_t sum = 0; ++ size_t a; + +-/* Strings longer than 4096 in DMI are just insane. */ +-#define DMI_MAX_ANSWER_LEN 4096 ++ for (a = 0; a < len; a++) ++ sum += buf[a]; ++ return (sum == 0); ++} ++ ++static char *dmi_string(uint8_t *buf, uint8_t string_id, uint8_t *limit) ++{ ++ size_t i, len; ++ ++ if (string_id == 0) ++ return "Not Specified"; ++ ++ while (string_id > 1 && string_id--) { ++ if (buf > limit) { ++ msg_perr("DMI table is broken (string portion out of bounds)!\n"); ++ return ""; ++ } ++ buf += strnlen((char *)buf, limit - buf) + 1; ++ } ++ ++ if (!*buf) /* as long as the current byte we're on isn't null */ ++ return ""; ++ ++ len = strnlen((char *)buf, limit - buf); ++ if (len > DMI_MAX_ANSWER_LEN) ++ len = DMI_MAX_ANSWER_LEN; ++ ++ /* fix junk bytes in the string */ ++ for (i = 0; i < len && buf[i] != '\0'; i++) ++ if (buf[i] < 32 || buf[i] >= 127) ++ buf[i] = ' '; ++ ++ return (char *)buf; ++} ++ ++static void dmi_chassis_type(uint8_t code) ++{ ++ int i; ++ code &= 0x7f; /* bits 6:0 are chassis type, 7th bit is the lock bit */ ++ is_laptop = 2; ++ for (i = 0; i < ARRAY_SIZE(dmi_chassis_types); i++) { ++ if (code == dmi_chassis_types[i].type) { ++ msg_pdbg("DMI string chassis-type: \"%s\"\n", dmi_chassis_types[i].name); ++ is_laptop = dmi_chassis_types[i].is_laptop; ++ break; ++ } ++ } ++} ++ ++static void dmi_table(uint32_t base, uint16_t len, uint16_t num) ++{ ++ int i = 0, j = 0; ++ ++ uint8_t *dmi_table_mem = physmap_ro("DMI Table", base, len); ++ if (dmi_table_mem == NULL) { ++ msg_perr("Unable to access DMI Table\n"); ++ return; ++ } ++ ++ uint8_t *data = dmi_table_mem; ++ uint8_t *limit = dmi_table_mem + len; ++ ++ /* SMBIOS structure header is always 4 B long and contains: ++ * - uint8_t type; // see dmi_chassis_types's type ++ * - uint8_t length; // data section w/ header w/o strings ++ * - uint16_t handle; ++ */ ++ while (i < num && data + 4 <= limit) { ++ /* - If a short entry is found (less than 4 bytes), not only it ++ * is invalid, but we cannot reliably locate the next entry. ++ * - If the length value indicates that this structure spreads ++ * accross the table border, something is fishy too. ++ * Better stop at this point, and let the user know his/her ++ * table is broken. ++ */ ++ if (data[1] < 4 || data + data[1] > limit) { ++ msg_perr("DMI table is broken (bogus header)!\n"); ++ break; ++ } ++ ++ if(data[0] == 3) { ++ if (data + 5 <= limit) ++ dmi_chassis_type(data[5]); ++ /* else the table is broken, but laptop detection is optional, hence continue. */ ++ } else ++ for (j = 0; j < ARRAY_SIZE(dmi_strings); j++) { ++ uint8_t offset = dmi_strings[j].offset; ++ uint8_t type = dmi_strings[j].type; ++ ++ if (data[0] != type) ++ continue; ++ ++ if (data[1] <= offset || data+offset > limit) { ++ msg_perr("DMI table is broken (offset out of bounds)!\n"); ++ goto out; ++ } ++ ++ /* Table will be unmapped, hence fill the struct with duplicated strings. */ ++ dmi_strings[j].value = strdup(dmi_string(data + data[1], data[offset], limit)); ++ } ++ /* Find next structure by skipping data and string sections */ ++ data += data[1]; ++ while (data + 1 <= limit) { ++ if (data[0] == 0 && data[1] == 0) ++ break; ++ data++; ++ } ++ data += 2; ++ i++; ++ } ++out: ++ physunmap(dmi_table_mem, len); ++} ++ ++#if SM_SUPPORT ++static int smbios_decode(uint8_t *buf) ++{ ++ /* TODO: other checks mentioned in the conformance guidelines? */ ++ if (!dmi_checksum(buf, buf[0x05]) || ++ (memcmp(buf + 0x10, "_DMI_", 5) != 0) || ++ !dmi_checksum(buf + 0x10, 0x0F)) ++ return 0; ++ ++ dmi_table(mmio_readl(buf + 0x18), mmio_readw(buf + 0x16), mmio_readw(buf + 0x1C)); ++ ++ return 1; ++} ++#endif ++ ++static int legacy_decode(uint8_t *buf) ++{ ++ if (!dmi_checksum(buf, 0x0F)) ++ return 1; ++ ++ dmi_table(mmio_readl(buf + 0x08), mmio_readw(buf + 0x06), mmio_readw(buf + 0x0C)); ++ ++ return 0; ++} ++ ++int dmi_fill(void) ++{ ++ size_t fp; ++ uint8_t *dmi_mem; ++ int ret = 1; ++ ++ msg_pdbg("Using Internal DMI decoder.\n"); ++ /* There are two ways specified to gain access to the SMBIOS table: ++ * - EFI's configuration table contains a pointer to the SMBIOS table. On linux it can be obtained from ++ * sysfs. EFI's SMBIOS GUID is: {0xeb9d2d31,0x2d88,0x11d3,0x9a,0x16,0x0,0x90,0x27,0x3f,0xc1,0x4d} ++ * - Scanning physical memory address range 0x000F0000h to 0x000FFFFF for the anchor-string(s). */ ++ dmi_mem = physmap_ro("DMI", 0xF0000, 0x10000); ++ if (dmi_mem == ERROR_PTR) ++ return ret; ++ ++ for (fp = 0; fp <= 0xFFF0; fp += 16) { ++#if SM_SUPPORT ++ if (memcmp(dmi_mem + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) { ++ if (smbios_decode(dmi_mem + fp)) // FIXME: length check ++ goto out; ++ } else ++#endif ++ if (memcmp(dmi_mem + fp, "_DMI_", 5) == 0) ++ if (legacy_decode(dmi_mem + fp) == 0) { ++ ret = 0; ++ goto out; ++ } ++ } ++ msg_pinfo("No DMI table found.\n"); ++out: ++ physunmap(dmi_mem, 0x10000); ++ return ret; ++} ++ ++#else /* CONFIG_INTERNAL_DMI */ ++ ++#define DMI_COMMAND_LEN_MAX 300 ++static const char *dmidecode_command = "dmidecode"; + + static char *get_dmi_string(const char *string_name) + { + FILE *dmidecode_pipe; + char *result; +- char answerbuf[DMI_MAX_ANSWER_LEN]; +- char commandline[DMI_COMMAND_LEN_MAX + 40]; ++ char answerbuf[DMI_MAX_ANSWER_LEN + 1] = {'\0'}; ++ char commandline[DMI_COMMAND_LEN_MAX + 1] = {'\0'}; + + snprintf(commandline, sizeof(commandline), + "%s -s %s", dmidecode_command, string_name); +@@ -138,46 +322,31 @@ static char *get_dmi_string(const char *string_name) + /* Chomp trailing newline. */ + if (answerbuf[0] != 0 && answerbuf[strlen(answerbuf) - 1] == '\n') + answerbuf[strlen(answerbuf) - 1] = 0; +- msg_pdbg("DMI string %s: \"%s\"\n", string_name, answerbuf); + + result = strdup(answerbuf); +- if (!result) ++ if (result == NULL) + msg_pwarn("Warning: Out of memory - DMI support fails"); + + return result; + } + +-static int dmi_shutdown(void *data) +-{ +- int i; +- for (i = 0; i < ARRAY_SIZE(dmistrings); i++) { +- free(dmistrings[i]); +- dmistrings[i] = NULL; +- } +- return 0; +-} +- +-void dmi_init(void) ++int dmi_fill(void) + { + int i; + char *chassis_type; + +- if (register_shutdown(dmi_shutdown, NULL)) +- return; +- +- has_dmi_support = 1; +- for (i = 0; i < ARRAY_SIZE(dmidecode_names); i++) { +- dmistrings[i] = get_dmi_string(dmidecode_names[i]); +- if (!dmistrings[i]) { +- has_dmi_support = 0; +- return; +- } ++ msg_pdbg("Using External DMI decoder.\n"); ++ for (i = 0; i < ARRAY_SIZE(dmi_strings); i++) { ++ dmi_strings[i].value = get_dmi_string(dmi_strings[i].keyword); ++ if (dmi_strings[i].value == NULL) ++ return 1; + } + + chassis_type = get_dmi_string("chassis-type"); + if (chassis_type == NULL) +- return; ++ return 0; /* chassis-type handling is optional anyway */ + ++ msg_pdbg("DMI string chassis-type: \"%s\"\n", chassis_type); + is_laptop = 2; + for (i = 0; i < ARRAY_SIZE(dmi_chassis_types); i++) { + if (strcasecmp(chassis_type, dmi_chassis_types[i].name) == 0) { +@@ -185,6 +354,33 @@ void dmi_init(void) + break; + } + } ++ free(chassis_type); ++ return 0; ++} ++ ++#endif /* CONFIG_INTERNAL_DMI */ ++ ++static int dmi_shutdown(void *data) ++{ ++ int i; ++ for (i = 0; i < ARRAY_SIZE(dmi_strings); i++) { ++ free(dmi_strings[i].value); ++ dmi_strings[i].value = NULL; ++ } ++ return 0; ++} ++ ++void dmi_init(void) ++{ ++ /* Register shutdown function before we allocate anything. */ ++ if (register_shutdown(dmi_shutdown, NULL)) { ++ msg_pwarn("Warning: Could not register DMI shutdown function - continuing without DMI info.\n"); ++ return; ++ } ++ ++ /* dmi_fill fills the dmi_strings array, and if possible sets the global is_laptop variable. */ ++ if (dmi_fill() != 0) ++ return; + + switch (is_laptop) { + case 1: +@@ -194,7 +390,13 @@ void dmi_init(void) + msg_pdbg("DMI chassis-type is not specific enough.\n"); + break; + } +- free(chassis_type); ++ ++ has_dmi_support = 1; ++ int i; ++ for (i = 0; i < ARRAY_SIZE(dmi_strings); i++) { ++ msg_pdbg("DMI string %s: \"%s\"\n", dmi_strings[i].keyword, ++ (dmi_strings[i].value == NULL) ? "" : dmi_strings[i].value); ++ } + } + + /** +@@ -204,8 +406,8 @@ void dmi_init(void) + * at the beginning and '$' at the end. So you can look for "^prefix", + * "suffix$", "substring" or "^complete string$". + * +- * @param value The string to check. +- * @param pattern The pattern. ++ * @param value The non-NULL string to check. ++ * @param pattern The non-NULL pattern. + * @return Nonzero if pattern matches. + */ + static int dmi_compare(const char *value, const char *pattern) +@@ -252,11 +454,15 @@ int dmi_match(const char *pattern) + if (!has_dmi_support) + return 0; + +- for (i = 0; i < ARRAY_SIZE(dmidecode_names); i++) +- if (dmi_compare(dmistrings[i], pattern)) ++ for (i = 0; i < ARRAY_SIZE(dmi_strings); i++) { ++ if (dmi_strings[i].value == NULL) ++ continue; ++ ++ if (dmi_compare(dmi_strings[i].value, pattern)) + return 1; ++ } + + return 0; + } + +-#endif /* STANDALONE */ ++#endif // defined(__i386__) || defined(__x86_64__) +diff --git a/dnv_smi_spi.c b/dnv_smi_spi.c +new file mode 100644 +index 0000000..0317cc7 +--- /dev/null ++++ b/dnv_smi_spi.c +@@ -0,0 +1,185 @@ ++ ++/************************************************************************ ++* LEGALESE: "Copyright (c) 2018, Dell Inc. All rights reserved." ++* ++* This source code is confidential, proprietary, and contains trade ++* secrets that are the sole property of Dell Inc. ++* Copy and/or distribution of this source code or disassembly or reverse ++* engineering of the resultant object code are strictly forbidden without ++* the written consent of Dell Inc. ++* ++************************************************************************/ ++#if DELL_DENVERTON_SUPPORT == 1 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "flash.h" ++ ++#define MEM_MODULE "/dev/mem" ++ ++DELL_SPI_MAILBOX *mailbox; ++uint64_t phy_addr; ++ ++/** ++* @brief unmap a pagesize of physical memory into virtual memory. ++* @param[in] addr - virtual memory address that is unmaped. ++*/ ++static void free_virt_mapping(void *addr) ++{ ++ munmap(addr, getpagesize()); ++} ++ ++/** ++* @brief map a pagesize of physical memory into virtual memory. ++* @param[in] addr - physical memory address. ++* @param[out] buf - pointer to buffer which storages data. ++* @return = 0 for success, otherwise for error. ++*/ ++static uint32_t getData_phy_to_virt(uint32_t addr, void** buf) ++{ ++ uint8_t *tmp; ++ uint32_t pagesize, offset, index, fd; ++ ++ pagesize = getpagesize(); ++ if ( (fd = open(MEM_MODULE, O_RDWR)) < 0 ) { ++ printf("open() %s error\n", MEM_MODULE); ++ return 1; ++ } ++ ++ offset = addr & ~(pagesize - 1); ++ index = addr & (pagesize - 1); ++ if ( (tmp = mmap(0, pagesize*2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset)) == MAP_FAILED ) { ++ printf("mmap() error\n"); ++ close(fd); ++ return 1; ++ } ++ *buf = tmp + index; ++ close(fd); ++ return 0; ++} ++ ++/** ++* @brief send "get communication buffer" requirement to SMM ++*/ ++uint32_t dnv_smi_open_res() ++{ ++ uint32_t mailboxAddress; ++ ++ ioperm(0xB2, 3, 1); ++ __asm__ __volatile__ ("push %%rcx" : :); ++ outb(0x27, 0xB2); ++ __asm__ __volatile__ ("movl %%ecx, %0" : "=r" (mailboxAddress)); ++ __asm__ __volatile__ ("pop %%rcx" : :); ++ ioperm(0xB2, 3, 0); ++ ++ getData_phy_to_virt(mailboxAddress, (void **)&mailbox); ++ phy_addr = mailboxAddress; ++ return 0; ++} ++ ++/** ++* @brief send "release communication buffer" requirement to SMM ++*/ ++void dnv_smi_release_res() ++{ ++ free_virt_mapping((void *)mailbox); ++} ++ ++/** ++* @brief disable SPI write protection. ++*/ ++static void dnv_trigger_smi_spi_unlock() ++{ ++ ioperm(0xB2, 3, 1); ++ __asm__ __volatile__ ("push %%rcx" : :); ++ __asm__ __volatile__ ("push %%rbx" : :); ++ __asm__ __volatile__ ("movl %0, %%ecx" : : "a" ((uint32_t)0)); ++ __asm__ __volatile__ ("movl %0, %%ebx" : : "a" ((uint32_t)phy_addr)); ++ outb(0x20, 0xB2); ++ __asm__ __volatile__ ("pop %%rbx" : :); ++ __asm__ __volatile__ ("pop %%rcx" : :); ++ ioperm(0xB2, 3, 0); ++} ++ ++/** ++* @brief enable SPI write protection. ++*/ ++static void dnv_trigger_smi_spi_lock() ++{ ++ ioperm(0xB2, 3, 1); ++ __asm__ __volatile__ ("push %%rcx" : :); ++ __asm__ __volatile__ ("push %%rbx" : :); ++ __asm__ __volatile__ ("movl %0, %%ecx" : : "a" ((uint32_t)0)); ++ __asm__ __volatile__ ("movl %0, %%ebx" : : "a" ((uint32_t)phy_addr)); ++ outb(0x24, 0xB2); ++ __asm__ __volatile__ ("pop %%rbx" : :); ++ __asm__ __volatile__ ("pop %%rcx" : :); ++ ioperm(0xB2, 3, 0); ++} ++ ++/** ++* @brief trigger smi ++*/ ++void run() ++{ ++ ioperm(0xB2, 3, 1); ++ outb(0x28, 0xB2); ++ ioperm(0xB2, 3, 0); ++} ++ ++/** ++* @brief This function is used to read/write and erase BIOS. ++* trigger SMI and send information to SMM(like requirement, address,and data) ++* @param[in] bios_offset - offset of bios region [0~size of bios region] ++* @param[in] buf - pointer to write data if cmd is "SMI_READ_SPI" ++* @param[in] cmd - enum SPI_SMI_CMD ++* @param[out] buf - pointer to read data if cmd is "SMI_WRITE_SPI" ++* @returns ret. This ret is returned from SMM. ++*/ ++int32_t dnv_smi_doit(uint32_t bios_offset, uint8_t *buf, SPI_SMI_CMD cmd) ++{ ++ ++ if (cmd == SMI_READ_SPI) { ++ mailbox->cmd = 0x1; ++ mailbox->offset = bios_offset; ++ mailbox->dlen = DELL_DENVERTON_BLOCK_SIZE; ++ run(); ++ memcpy (buf, mailbox->data, DELL_DENVERTON_BLOCK_SIZE); ++ return mailbox->ret; ++ } else if (cmd == SMI_ERASE_SPI) { ++ mailbox->cmd = 0x2; ++ mailbox->offset = bios_offset; ++ mailbox->dlen = DELL_DENVERTON_BLOCK_SIZE; ++ run(); ++ return mailbox->ret; ++ } else if (cmd == SMI_WRITE_SPI) { ++ memcpy (mailbox->data, buf, DELL_DENVERTON_BLOCK_SIZE); ++ mailbox->cmd = 0x3; ++ mailbox->offset = bios_offset; ++ mailbox->dlen = DELL_DENVERTON_BLOCK_SIZE; ++ run(); ++ return mailbox->ret; ++ } ++ ++ switch (cmd) ++ { ++ case SMI_ENABLE_SPI: ++ dnv_trigger_smi_spi_unlock(); ++ break; ++ case SMI_DISABLE_SPI: ++ dnv_trigger_smi_spi_lock(); ++ break; ++ default: ++ return -1; ++ } ++ ++ return 0; ++} ++ ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ +diff --git a/drkaiser.c b/drkaiser.c +index b94d6dd..0cf1fdb 100644 +--- a/drkaiser.c ++++ b/drkaiser.c +@@ -56,12 +56,6 @@ static const struct par_programmer par_programmer_drkaiser = { + .chip_writen = fallback_chip_writen, + }; + +-static int drkaiser_shutdown(void *data) +-{ +- physunmap(drkaiser_bar, DRKAISER_MEMMAP_SIZE); +- return 0; +-} +- + int drkaiser_init(void) + { + struct pci_dev *dev = NULL; +@@ -75,15 +69,15 @@ int drkaiser_init(void) + return 1; + + addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_2); ++ if (!addr) ++ return 1; + + /* Write magic register to enable flash write. */ + rpci_write_word(dev, PCI_MAGIC_DRKAISER_ADDR, PCI_MAGIC_DRKAISER_VALUE); + + /* Map 128kB flash memory window. */ +- drkaiser_bar = physmap("Dr. Kaiser PC-Waechter flash memory", +- addr, DRKAISER_MEMMAP_SIZE); +- +- if (register_shutdown(drkaiser_shutdown, NULL)) ++ drkaiser_bar = rphysmap("Dr. Kaiser PC-Waechter flash memory", addr, DRKAISER_MEMMAP_SIZE); ++ if (drkaiser_bar == ERROR_PTR) + return 1; + + max_rom_decode.parallel = 128 * 1024; +diff --git a/flash.h b/flash.h +index 63701ed..79fe8f4 100644 +--- a/flash.h ++++ b/flash.h +@@ -45,6 +45,14 @@ + typedef uintptr_t chipaddr; + #define PRIxPTR_WIDTH ((int)(sizeof(uintptr_t)*2)) + ++/* Types and macros regarding the maximum flash space size supported by generic code. */ ++typedef uint32_t chipoff_t; /* Able to store any addressable offset within a supported flash memory. */ ++typedef uint32_t chipsize_t; /* Able to store the number of bytes of any supported flash memory. */ ++#define FL_MAX_CHIPADDR_BITS (24) ++#define FL_MAX_CHIPADDR ((chipoff_t)(1ULL< 0) ++ programmer_table[programmer].delay(usecs); + } + + void map_flash_registers(struct flashctx *flash) +@@ -619,12 +629,29 @@ static unsigned int count_usable_erasers(const struct flashctx *flash) + return usable_erasefunctions; + } + ++#if DELL_DENVERTON_SUPPORT == 1 ++int8_t is_erase = 0; ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ ++ + int compare_range(uint8_t *wantbuf, uint8_t *havebuf, unsigned int start, unsigned int len) + { + int ret = 0, failcount = 0; + unsigned int i; + for (i = 0; i < len; i++) { + if (wantbuf[i] != havebuf[i]) { ++#if DELL_DENVERTON_SUPPORT == 1 ++ if (is_dnv && is_erase) { ++ // _FVH ++ // At offset 0x28~0x2b of NVRAM, Main Bios and Boot Bios ++ // We can't read correct data after "erasing". ++ // But, We verified bios through SF100. The erase feature is work. ++ if (i == _FVH_OFFSET && ++ memcmp(&havebuf[i], _FVH_SIGNATURE, sizeof(_FVH_SIGNATURE) - 1) == 0) { ++ i += sizeof(_FVH_SIGNATURE) - 1; ++ continue; ++ } ++ } ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + /* Only print the first failure. */ + if (!failcount++) + msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,", +@@ -651,7 +678,15 @@ int check_erased_range(struct flashctx *flash, unsigned int start, + exit(1); + } + memset(cmpbuf, 0xff, len); ++#if DELL_DENVERTON_SUPPORT == 1 ++ if (is_dnv) ++ is_erase = 1; ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + ret = verify_range(flash, cmpbuf, start, len); ++#if DELL_DENVERTON_SUPPORT == 1 ++ if (is_dnv) ++ is_erase = 0; ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + free(cmpbuf); + return ret; + } +@@ -695,6 +730,22 @@ int verify_range(struct flashctx *flash, uint8_t *cmpbuf, unsigned int start, un + return ret; + } + ++#if DELL_DENVERTON_SUPPORT == 1 ++ // NVRAM will be recovery even if use afulnx. ++ // skip NVRAM region. ++ if (is_dnv) { ++ // Do not hard-code the NVRAM region start address. It is located at different addresses for 16MB and 32MB BIOS image. ++ // For Denverton platform, NVRAM region start address is always located at dnv_bios_region_start. ++ // NVRAM backup region is located at (dnv_bios_region_start + DELL_DENVERTON_MAIN_NVRAM_LENGTH). ++ if ((start >= dnv_bios_region_start && ++ start < (dnv_bios_region_start + DELL_DENVERTON_MAIN_NVRAM_LENGTH)) || ++ (start >= (dnv_bios_region_start + DELL_DENVERTON_MAIN_NVRAM_LENGTH) && ++ start < ((dnv_bios_region_start + DELL_DENVERTON_MAIN_NVRAM_LENGTH) + DELL_DENVERTON_BACKUP_NVRAM_LENGTH))) { ++ return ret; ++ } ++ } ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ ++ + ret = compare_range(cmpbuf, readbuf, start, len); + out_free: + free(readbuf); +@@ -770,6 +821,11 @@ int need_erase(uint8_t *have, uint8_t *want, unsigned int len, enum write_granul + case write_gran_1056bytes: + result = need_erase_gran_bytes(have, want, len, 1056); + break; ++#if DELL_DENVERTON_SUPPORT == 1 ++ case write_gran_4096bytes: ++ result = need_erase_gran_bytes(have, want, len, 4096); ++ break; ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + default: + msg_cerr("%s: Unsupported granularity! Please report a bug at " + "flashrom@flashrom.org\n", __func__); +@@ -831,6 +887,11 @@ static unsigned int get_next_write(uint8_t *have, uint8_t *want, unsigned int le + case write_gran_1056bytes: + stride = 1056; + break; ++#if DELL_DENVERTON_SUPPORT == 1 ++ case write_gran_4096bytes: ++ stride = 4096; ++ break; ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + default: + msg_cerr("%s: Unsupported granularity! Please report a bug at " + "flashrom@flashrom.org\n", __func__); +@@ -1140,6 +1201,12 @@ notfound: + if (!flash->chip) + return -1; + ++#if DELL_DENVERTON_SUPPORT == 1 ++ if (is_dnv) { ++ flash->chip->gran = write_gran_4096bytes; ++ } ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ ++ + #if CONFIG_INTERNAL == 1 + if (programmer_table[programmer].map_flash_region == physmap) + snprintf(location, sizeof(location), "at physical address 0x%lx", base); +@@ -1148,8 +1215,13 @@ notfound: + snprintf(location, sizeof(location), "on %s", programmer_table[programmer].name); + + tmp = flashbuses_to_text(flash->chip->bustype); ++#ifdef FORCE10_SPI_CHANGE ++ msg_cdbg("%s %s flash chip \"%s\" (%d kB, %s) %s.\n", force ? "Assuming" : "Found", ++ flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp, location); ++#else + msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) %s.\n", force ? "Assuming" : "Found", + flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp, location); ++#endif + free(tmp); + + /* Flash registers will not be mapped if the chip was forced. Lock info +@@ -1166,6 +1238,10 @@ notfound: + int read_buf_from_file(unsigned char *buf, unsigned long size, + const char *filename) + { ++#ifdef __LIBPAYLOAD__ ++ msg_gerr("Error: No file I/O support in libpayload\n"); ++ return 1; ++#else + unsigned long numbytes; + FILE *image; + struct stat image_stat; +@@ -1196,11 +1272,16 @@ int read_buf_from_file(unsigned char *buf, unsigned long size, + return 1; + } + return 0; ++#endif + } + + int write_buf_to_file(unsigned char *buf, unsigned long size, + const char *filename) + { ++#ifdef __LIBPAYLOAD__ ++ msg_gerr("Error: No file I/O support in libpayload\n"); ++ return 1; ++#else + unsigned long numbytes; + FILE *image; + +@@ -1221,6 +1302,7 @@ int write_buf_to_file(unsigned char *buf, unsigned long size, + return 1; + } + return 0; ++#endif + } + + int read_flash_to_file(struct flashctx *flash, const char *filename) +@@ -1229,6 +1311,16 @@ int read_flash_to_file(struct flashctx *flash, const char *filename) + unsigned char *buf = calloc(size, sizeof(char)); + int ret = 0; + ++#if DELL_DENVERTON_SUPPORT == 1 ++ uint64_t bios_start = 0; ++ uint64_t bios_size = size; ++ ++ if (is_dnv) { ++ bios_size = dnv_bios_region_size; ++ bios_start = dnv_bios_region_start; ++ } ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ ++ + msg_cinfo("Reading flash... "); + if (!buf) { + msg_gerr("Memory allocation failed!\n"); +@@ -1240,7 +1332,11 @@ int read_flash_to_file(struct flashctx *flash, const char *filename) + ret = 1; + goto out_free; + } ++#if DELL_DENVERTON_SUPPORT == 1 ++ if (flash->chip->read(flash, (buf + bios_start), bios_start, bios_size)) { ++#else + if (flash->chip->read(flash, buf, 0, size)) { ++#endif /* #if DELL_DENVERTON__SUPPORT == 1 */ + msg_cerr("Read operation failed!\n"); + ret = 1; + goto out_free; +@@ -1388,6 +1484,11 @@ static int walk_eraseregions(struct flashctx *flash, int erasefunction, + { + int i, j; + unsigned int start = 0; ++#if DELL_DENVERTON_SUPPORT == 1 ++ if (is_dnv) { ++ start = dnv_bios_region_start; ++ } ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + unsigned int len; + struct block_eraser eraser = flash->chip->block_erasers[erasefunction]; + +@@ -1897,6 +1998,10 @@ int doit(struct flashctx *flash, int force, const char *filename, int read_it, + uint8_t *newcontents; + int ret = 0; + unsigned long size = flash->chip->total_size * 1024; ++#if DELL_DENVERTON_SUPPORT == 1 ++ uint32_t bios_size = size; ++ uint32_t bios_start = 0; ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + + if (chip_safety_check(flash, force, read_it, write_it, erase_it, verify_it)) { + msg_cerr("Aborting.\n"); +@@ -1904,6 +2009,12 @@ int doit(struct flashctx *flash, int force, const char *filename, int read_it, + goto out_nofree; + } + ++ if (normalize_romentries(flash)) { ++ msg_cerr("Requested regions can not be handled. Aborting.\n"); ++ ret = 1; ++ goto out_nofree; ++ } ++ + /* Given the existence of read locks, we want to unlock for read, + * erase and write. + */ +@@ -1936,6 +2047,13 @@ int doit(struct flashctx *flash, int force, const char *filename, int read_it, + */ + + if (erase_it) { ++ ++#if 0 // Since we dont have a layout, why set newcontents to 0?? ++#ifdef FORCE10_SPI_CHANGE ++ /* Build a new image taking the given layout into account. */ ++ build_new_image(flash, oldcontents, newcontents); ++#endif ++#endif + /* FIXME: Do we really want the scary warning if erase failed? + * After all, after erase the chip is either blank or partially + * blank or it has the old contents. A blank chip won't boot, +@@ -1975,25 +2093,47 @@ int doit(struct flashctx *flash, int force, const char *filename, int read_it, + * preserved, but in that case we might perform unneeded erase which + * takes time as well. + */ ++#if DELL_DENVERTON_SUPPORT == 1 ++ if (is_dnv) { ++ bios_size = dnv_bios_region_size; ++ bios_start = dnv_bios_region_start; ++ } ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ ++#ifdef FORCE10_SPI_CHANGE ++ msg_cdbg("Reading old flash chip contents... "); ++#else + msg_cinfo("Reading old flash chip contents... "); ++#endif ++#if DELL_DENVERTON_SUPPORT == 1 ++ if (flash->chip->read(flash, oldcontents + bios_start, bios_start, bios_size)) { ++#else + if (flash->chip->read(flash, oldcontents, 0, size)) { ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + ret = 1; + msg_cinfo("FAILED.\n"); + goto out; + } ++#ifdef FORCE10_SPI_CHANGE ++ msg_cdbg("done.\n"); ++#else + msg_cinfo("done.\n"); ++#endif + +- // This should be moved into each flash part's code to do it +- // cleanly. This does the job. +- handle_romentries(flash, oldcontents, newcontents); +- ++#if 0 ++ /* Build a new image taking the given layout into account. */ ++ build_new_image(flash, oldcontents, newcontents); ++#endif + // //////////////////////////////////////////////////////////// + + if (write_it) { + if (erase_and_write_flash(flash, oldcontents, newcontents)) { + msg_cerr("Uh oh. Erase/write failed. Checking if " + "anything changed.\n"); ++#if DELL_DENVERTON_SUPPORT == 1 ++ if (!flash->chip->read(flash, newcontents, bios_start, bios_size)) { ++#else + if (!flash->chip->read(flash, newcontents, 0, size)) { ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + if (!memcmp(oldcontents, newcontents, size)) { + msg_cinfo("Good. It seems nothing was changed.\n"); + nonfatal_help_message(); +@@ -2014,14 +2154,22 @@ int doit(struct flashctx *flash, int force, const char *filename, int read_it, + if (write_it) { + /* Work around chips which need some time to calm down. */ + programmer_delay(1000*1000); ++#if DELL_DENVERTON_SUPPORT == 1 ++ ret = verify_range(flash, newcontents + bios_start, bios_start, bios_size); ++#else + ret = verify_range(flash, newcontents, 0, size); ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + /* If we tried to write, and verification now fails, we + * might have an emergency situation. + */ + if (ret) + emergency_help_message(); + } else { ++#if DELL_DENVERTON_SUPPORT == 1 ++ ret = compare_range(newcontents + bios_start, oldcontents + bios_start, bios_start, bios_size); ++#else + ret = compare_range(newcontents, oldcontents, 0, size); ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + } + if (!ret) + msg_cinfo("VERIFIED.\n"); +diff --git a/ft2232_spi.c b/ft2232_spi.c +index 81be051..44354fd 100644 +--- a/ft2232_spi.c ++++ b/ft2232_spi.c +@@ -43,6 +43,7 @@ + #define FTDI_FT4232H_PID 0x6011 + #define FTDI_FT232H_PID 0x6014 + #define TIAO_TUMPA_PID 0x8a98 ++#define TIAO_TUMPA_LITE_PID 0x8a99 + #define AMONTEC_JTAGKEY_PID 0xCFF8 + + #define GOEPEL_VID 0x096C +@@ -62,6 +63,7 @@ const struct dev_entry devs_ft2232spi[] = { + {FTDI_VID, FTDI_FT4232H_PID, OK, "FTDI", "FT4232H"}, + {FTDI_VID, FTDI_FT232H_PID, OK, "FTDI", "FT232H"}, + {FTDI_VID, TIAO_TUMPA_PID, OK, "TIAO", "USB Multi-Protocol Adapter"}, ++ {FTDI_VID, TIAO_TUMPA_LITE_PID, OK, "TIAO", "USB Multi-Protocol Adapter Lite"}, + {FTDI_VID, AMONTEC_JTAGKEY_PID, OK, "Amontec", "JTAGkey"}, + {GOEPEL_VID, GOEPEL_PICOTAP_PID, OK, "GOEPEL", "PicoTAP"}, + {FIC_VID, OPENMOKO_DBGBOARD_PID, OK, "FIC", "OpenMoko Neo1973 Debug board (V2+)"}, +@@ -208,6 +210,10 @@ int ft2232_spi_init(void) + /* Interface A is SPI1, B is SPI2. */ + ft2232_type = TIAO_TUMPA_PID; + channel_count = 2; ++ } else if (!strcasecmp(arg, "tumpalite")) { ++ /* Only one channel is used on lite edition */ ++ ft2232_type = TIAO_TUMPA_LITE_PID; ++ channel_count = 1; + } else if (!strcasecmp(arg, "busblaster")) { + /* In its default configuration it is a jtagkey clone */ + ft2232_type = FTDI_FT2232H_PID; +diff --git a/gfxnvidia.c b/gfxnvidia.c +index d0a9feb..d3ee14e 100644 +--- a/gfxnvidia.c ++++ b/gfxnvidia.c +@@ -77,12 +77,6 @@ static const struct par_programmer par_programmer_gfxnvidia = { + .chip_writen = fallback_chip_writen, + }; + +-static int gfxnvidia_shutdown(void *data) +-{ +- physunmap(nvidia_bar, GFXNVIDIA_MEMMAP_SIZE); +- return 0; +-} +- + int gfxnvidia_init(void) + { + struct pci_dev *dev = NULL; +@@ -96,12 +90,14 @@ int gfxnvidia_init(void) + return 1; + + io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0); ++ if (!io_base_addr) ++ return 1; ++ + io_base_addr += 0x300000; + msg_pinfo("Detected NVIDIA I/O base address: 0x%x.\n", io_base_addr); + +- nvidia_bar = physmap("NVIDIA", io_base_addr, GFXNVIDIA_MEMMAP_SIZE); +- +- if (register_shutdown(gfxnvidia_shutdown, NULL)) ++ nvidia_bar = rphysmap("NVIDIA", io_base_addr, GFXNVIDIA_MEMMAP_SIZE); ++ if (nvidia_bar == ERROR_PTR) + return 1; + + /* Allow access to flash interface (will disable screen). */ +diff --git a/hwaccess.h b/hwaccess.h +index fd6eb12..83f349e 100644 +--- a/hwaccess.h ++++ b/hwaccess.h +@@ -37,7 +37,13 @@ + * or as builtin. + */ + #define index shadow_workaround_index ++ ++#if !defined (__NetBSD__) && !defined (__DragonFly__) + #include ++#else ++#include ++#endif ++ + #undef index + #endif + +diff --git a/ich_descriptors.c b/ich_descriptors.c +index 528717b..c007867 100644 +--- a/ich_descriptors.c ++++ b/ich_descriptors.c +@@ -45,6 +45,11 @@ + #define min(a, b) (a < b) ? a : b + #endif + ++#if DELL_DENVERTON_SUPPORT == 1 ++#define DELL_DENVERTON_MAX_DENSITY 7 ++extern int8_t is_dnv; // if 1 chipset is denverton serial, 0 otherwise ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ ++ + void prettyprint_ich_reg_vscc(uint32_t reg_val, int verbosity) + { + print(verbosity, "BES=0x%x, ", (reg_val & VSCC_BES) >> VSCC_BES_OFF); +@@ -100,6 +105,36 @@ void prettyprint_ich_descriptor_content(const struct ich_desc_content *cont) + + void prettyprint_ich_descriptor_component(const struct ich_descriptors *desc) + { ++#if DELL_DENVERTON_SUPPORT == 1 ++ static const char * const dnv_freq_str[8] = { ++ "reserved", /* 000 */ ++ "reserved", /* 001 */ ++ "48 MHz", /* 010 */ ++ "reserved", /* 011 */ ++ "30MHz", /* 100 */ ++ "reserved", /* 101 */ ++ "17 MHz", /* 110 */ ++ "reserved", /* 111 */ ++ }; ++ static const char * const dnv_size_str[16] = { ++ "512 kB", /* 0000 */ ++ " 1 MB", /* 0001 */ ++ " 2 MB", /* 0010 */ ++ " 4 MB", /* 0011 */ ++ " 8 MB", /* 0100 */ ++ " 16 MB", /* 0101 */ ++ " 32 MB", /* 0110 */ ++ " 64 MB", /* 0111 */ ++ "reserved", /* 1000 */ ++ "reserved", /* 1001 */ ++ "reserved", /* 1010 */ ++ "reserved", /* 1011 */ ++ "reserved", /* 1100 */ ++ "reserved", /* 1101 */ ++ "reserved", /* 1110 */ ++ "reserved", /* 1111 */ ++ }; ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + static const char * const freq_str[8] = { + "20 MHz", /* 000 */ + "33 MHz", /* 001 */ +@@ -121,6 +156,47 @@ void prettyprint_ich_descriptor_component(const struct ich_descriptors *desc) + "reserved", /* 111 */ + }; + ++#if DELL_DENVERTON_SUPPORT == 1 ++ if (is_dnv) { ++ msg_pdbg2("=== Component Section ===\n"); ++ msg_pdbg2("FLCOMP 0x%08x\n", desc->component.FLCOMP); ++ msg_pdbg2("FLILL 0x%08x\n", desc->component.FLILL ); ++ msg_pdbg2("\n"); ++ ++ msg_pdbg2("--- Details ---\n"); ++ msg_pdbg2("Component 1 density: %s\n", ++ dnv_size_str[desc->component.dnv_comp1_density]); ++ if (desc->content.NC) ++ msg_pdbg2("Component 2 density: %s\n", ++ dnv_size_str[desc->component.dnv_comp2_density]); ++ else ++ msg_pdbg2("Component 2 is not used.\n"); ++ msg_pdbg2("Read Clock Frequency: %s\n", ++ dnv_freq_str[desc->component.dnv_freq_read]); ++ msg_pdbg2("Read ID and Status Clock Freq.: %s\n", ++ dnv_freq_str[desc->component.dnv_freq_read_id]); ++ msg_pdbg2("Write and Erase Clock Freq.: %s\n", ++ dnv_freq_str[desc->component.dnv_freq_write]); ++ msg_pdbg2("Fast Read is %ssupported.\n", ++ desc->component.dnv_fastread ? "" : "not "); ++ if (desc->component.dnv_fastread) ++ msg_pdbg2("Fast Read Clock Frequency: %s\n", ++ dnv_freq_str[desc->component.dnv_freq_fastread]); ++ if (desc->component.FLILL == 0) ++ msg_pdbg2("No forbidden opcodes.\n"); ++ else { ++ msg_pdbg2("Invalid instruction 0: 0x%02x\n", ++ desc->component.invalid_instr0); ++ msg_pdbg2("Invalid instruction 1: 0x%02x\n", ++ desc->component.invalid_instr1); ++ msg_pdbg2("Invalid instruction 2: 0x%02x\n", ++ desc->component.invalid_instr2); ++ msg_pdbg2("Invalid instruction 3: 0x%02x\n", ++ desc->component.invalid_instr3); ++ } ++ } else { ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ ++ + msg_pdbg2("=== Component Section ===\n"); + msg_pdbg2("FLCOMP 0x%08x\n", desc->component.FLCOMP); + msg_pdbg2("FLILL 0x%08x\n", desc->component.FLILL ); +@@ -157,6 +233,9 @@ void prettyprint_ich_descriptor_component(const struct ich_descriptors *desc) + msg_pdbg2("Invalid instruction 3: 0x%02x\n", + desc->component.invalid_instr3); + } ++#if DELL_DENVERTON_SUPPORT == 1 ++ } ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + msg_pdbg2("\n"); + } + +@@ -171,6 +250,12 @@ static void pprint_freg(const struct ich_desc_region *reg, uint32_t i) + } + uint32_t base = ICH_FREG_BASE(reg->FLREGs[i]); + uint32_t limit = ICH_FREG_LIMIT(reg->FLREGs[i]); ++#if DELL_DENVERTON_SUPPORT == 1 ++ if (is_dnv) { ++ base = DELL_DENVERTON_FREG_BASE(reg->FLREGs[i]); ++ limit = DELL_DENVERTON_FREG_LIMIT(reg->FLREGs[i]); ++ } ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + msg_pdbg2("Region %d (%-6s) ", i, region_names[i]); + if (base > limit) + msg_pdbg2("is unused.\n"); +@@ -741,17 +826,36 @@ int getFCBA_component_density(const struct ich_descriptors *desc, uint8_t idx) + msg_perr("Only ICH SPI component index 0 or 1 are supported yet.\n"); + return 0; + } ++#if DELL_DENVERTON_SUPPORT == 1 ++ if (is_dnv) { ++ if (size_enc > DELL_DENVERTON_MAX_DENSITY) { ++ msg_perr("Density of ICH SPI component with index %d is invalid. Encoded density is 0x%x.\n", idx, size_enc); ++ return 0; ++ } ++ } else { ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + if (size_enc > 5) { + msg_perr("Density of ICH SPI component with index %d is invalid. Encoded density is 0x%x.\n", + idx, size_enc); + return 0; + } ++#if DELL_DENVERTON_SUPPORT == 1 ++ } ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + return (1 << (19 + size_enc)); + } + + static uint32_t read_descriptor_reg(uint8_t section, uint16_t offset, void *spibar) + { + uint32_t control = 0; ++#if DELL_DENVERTON_SUPPORT == 1 ++ if (is_dnv) { ++ control |= (section << DENVERTON_FDOC_FDSS_OFF) & DENVERTON_FDOC_FDSS; ++ control |= (offset << DENVERTON_FDOC_FDSI_OFF) & DENVERTON_FDOC_FDSI; ++ mmio_le_writel(control, spibar + DENVERTON_REG_FDOC); ++ return mmio_le_readl(spibar + DENVERTON_REG_FDOD); ++ } ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + control |= (section << FDOC_FDSS_OFF) & FDOC_FDSS; + control |= (offset << FDOC_FDSI_OFF) & FDOC_FDSI; + mmio_le_writel(control, spibar + ICH9_REG_FDOC); +diff --git a/ich_descriptors.h b/ich_descriptors.h +index 3a44740..914a3cd 100644 +--- a/ich_descriptors.h ++++ b/ich_descriptors.h +@@ -64,6 +64,19 @@ + #define ICH_FREG_BASE(flreg) (((flreg) << 12) & 0x01fff000) + #define ICH_FREG_LIMIT(flreg) (((flreg) >> 4) & 0x01fff000) + ++#if DELL_DENVERTON_SUPPORT == 1 ++#define DENVERTON_REG_FDOC 0xB4 ++#define DENVERTON_FDOC_FDSI_OFF 2 ++#define DENVERTON_FDOC_FDSI (0x3ff << DENVERTON_FDOC_FDSI_OFF) ++#define DENVERTON_FDOC_FDSS_OFF 12 ++#define DENVERTON_FDOC_FDSS (0x3 << DENVERTON_FDOC_FDSS_OFF) ++ ++#define DENVERTON_REG_FDOD 0xB8 ++ ++#define DELL_DENVERTON_FREG_BASE(flreg) (((flreg) << 12) & 0x03fff000) ++#define DELL_DENVERTON_FREG_LIMIT(flreg) (((flreg) >> 4) & 0x03fff000) ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ ++ + void prettyprint_ich_reg_vscc(uint32_t reg_val, int verbosity); + + struct ich_desc_content { +@@ -78,6 +91,15 @@ struct ich_desc_content { + NR :3, /* Number Of Regions */ + :5; + }; ++#if DELL_DENVERTON_SUPPORT == 1 ++ struct { ++ int32_t dnv_FCBA :8, /* Flash Component Base Address */ ++ dnv_NC :2, /* Number Of Components */ ++ :6, ++ dnv_FRBA :8, /* Flash Region Base Address */ ++ :8; ++ }; ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + }; + union { /* 0x08 */ + uint32_t FLMAP1; +@@ -113,6 +135,20 @@ struct ich_desc_component { + freq_read_id :3, + :2; + }; ++#if DELL_DENVERTON_SUPPORT == 1 ++ struct { ++ uint32_t dnv_comp1_density :4, ++ dnv_comp2_density :4, ++ :9, ++ dnv_freq_read :3, ++ dnv_fastread :1, ++ dnv_freq_fastread :3, ++ dnv_freq_write :3, ++ dnv_freq_read_id :3, ++ dnv_dualfastread :1, ++ :1; ++ }; ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + }; + union { /* 0x04 */ + uint32_t FLILL; /* Flash Invalid Instructions Register */ +@@ -129,6 +165,15 @@ struct ich_desc_component { + uint32_t FPBA :13, /* Flash Partition Boundary Addr */ + :19; + }; ++#if DELL_DENVERTON_SUPPORT == 1 ++ uint32_t FLILL1; /* Flash Partition Boundary Register for dnv */ ++ struct { ++ uint32_t invalid_instr4 :8, ++ invalid_instr5 :8, ++ invalid_instr6 :8, ++ invalid_instr7 :8; ++ }; ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + }; + }; + +@@ -167,6 +212,65 @@ struct ich_desc_region { + :3; + }; + }; ++#if DELL_DENVERTON_SUPPORT == 1 ++ struct { /* FLREG0 Flash Descriptor */ ++ uint32_t dnv_reg0_base :15, ++ :1, ++ dnv_reg0_limit :15, ++ :1; ++ }; ++ struct { /* FLREG1 BIOS */ ++ uint32_t dnv_reg1_base :15, ++ :1, ++ dnv_reg1_limit :15, ++ :1; ++ }; ++ struct { /* FLREG2 ME */ ++ uint32_t dnv_reg2_base :15, ++ :1, ++ dnv_reg2_limit :15, ++ :1; ++ }; ++ ++ /* FLREG3 - Reserved */ ++ ++ struct { /* FLREG4 Platform */ ++ uint32_t dnv_reg4_base :15, ++ :1, ++ dnv_reg4_limit :15, ++ :1; ++ }; ++ ++ /* FLREG5 - Reserved */ ++ /* FLREG6 - Reserved */ ++ /* FLREG7 - Reserved */ ++ /* FLREG8 - Reserved */ ++ /* FLREG9 - Reserved */ ++ ++ struct { /* FLREG10 IE */ ++ uint32_t dnv_reg10_base :15, ++ :1, ++ dnv_reg10_limit :15, ++ :1; ++ }; ++ struct { /* FLREG11 LAN CTRL0 */ ++ uint32_t dnv_reg11_base :15, ++ :1, ++ dnv_reg11_limit :15, ++ :1; ++ }; ++ struct { /* FLREG12 LAN CTRL1 */ ++ uint32_t dnv_reg12_base :15, ++ :1, ++ dnv_reg12_limit :15, ++ :1; ++ }; ++ ++ /* FLREG13 - Reserved */ ++ /* FLREG14 - Reserved */ ++ /* FLREG15 - Reserved */ ++ ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + }; + }; + +diff --git a/ichspi.c b/ichspi.c +index 6d1bd1a..742d424 100644 +--- a/ichspi.c ++++ b/ichspi.c +@@ -170,6 +170,52 @@ + #define ICH7_REG_OPTYPE 0x56 /* 16 Bits */ + #define ICH7_REG_OPMENU 0x58 /* 64 Bits */ + ++/* denverton controller register definition */ ++#if DELL_DENVERTON_SUPPORT == 1 ++#define DENVERTON_REG_BFPREG 0x00 /* 32 Bits SPI BIOS MMIO PRI */ ++#define DENVERTON_BFPREG_PRB_OFF 0 /* 0-14: BIOS Flash Promary Region Base */ ++#define DENVERTON_BFPREG_PRB (0x7FFF << DENVERTON_BFPREG_PRB_OFF) ++#define DENVERTON_BFPREG_PRL_OFF 16 /* 16-30: BIOS Flash Primary Region Limit */ ++#define DENVERTON_BFPREG_PRL (0xFFFF << DENVERTON_BFPREG_PRL_OFF) ++#define DENVERTON_REG_HSFS 0x04 /* 16 Bits Hardware Sequencing Flash Status */ ++#define DENVERTON_HSFS_FDONE_OFF 0 /* 0: Flash Cycle Done */ ++#define DENVERTON_HSFS_FDONE (0x1 << DENVERTON_HSFS_FDONE_OFF) ++#define DENVERTON_HSFS_FCERR_OFF 1 /* 1: Flash Cycle Error */ ++#define DENVERTON_HSFS_FCERR (0x1 << DENVERTON_HSFS_FCERR_OFF) ++#define DENVERTON_HSFS_FDOPSS_OFF 13 /* 13: Flash Descriptor Override Pin-Strap Status */ ++#define DENVERTON_HSFS_FDOPSS (0x1 << DENVERTON_HSFS_FDOPSS_OFF) ++#define DENVERTON_HSFS_FDV_OFF 14 /* 14: Flash Descriptor Valid */ ++#define DENVERTON_HSFS_FDV (0x1 << DENVERTON_HSFS_FDV_OFF) ++#define DENVERTON_HSFS_FLOCKDN_OFF 15 /* 15: Flash Configuration Lock-Down */ ++#define DENVERTON_HSFS_FLOCKDN (0x1 << DENVERTON_HSFS_FLOCKDN_OFF) ++#define DENVERTON_REG_HSFC 0x06 /* 16 Bits Hardware Sequencing Flash Control */ ++#define DENVERTON_HSFC_FGO_OFF 0 /* 0: Flash Cycle Go */ ++#define DENVERTON_HSFC_FGO (0x1 << DENVERTON_HSFC_FGO_OFF) ++#define DENVERTON_HSFC_FCYCLE_OFF 1 /* 1- 4: FLASH Cycle */ ++#define DENVERTON_HSFC_FCYCLE (0xF << DENVERTON_HSFC_FCYCLE_OFF) ++#define DENVERTON_HSFC_FDBC_OFF 8 /* 8-13: Flash Data Byte Count */ ++#define DENVERTON_HSFC_FDBC (0x3F << DENVERTON_HSFC_FDBC_OFF) ++#define DENVERTON_REG_FADDR 0x08 /* 32 Bits */ ++#define DENVERTON_REG_FDATA0 0x10 /* 32 Bits */ ++#define DENVERTON_REG_FRAP 0x50 /* 32 Bytes Flash Region Access Permissions */ ++#define DENVERTON_REG_FREG0 0x54 /* 32 Bytes Flash Region 0 */ ++#define DENVERTON_REG_PR0 0x84 /* 32 Bytes Protected Range 0 */ ++#define DENVERTON_PR_WP_OFF 31 /* 31: write protection enable */ ++#define DENVERTON_PR_RP_OFF 15 /* 15: read protection enable */ ++#define DENVERTON_REG_VSCC0 0xC4 /* 32 Bits Host Vendor Specific Component Capabilities for Component 0 */ ++#define DENVERTON_REG_VSCC1 0xC8 /* 32 Bits Host Vendor Specific Component Capabilities for Component 1 */ ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ ++ ++#ifdef DELL_AVOTON_SUPPORT ++extern int8_t is_avoton; ++#endif /* DELL_AVOTON_SUPPORT */ ++ ++#if DELL_DENVERTON_SUPPORT == 1 ++extern uint32_t dnv_bios_region_start; ++extern uint32_t dnv_bios_region_size; ++extern uint32_t dnv_bios_region_limit; ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ ++ + /* ICH SPI configuration lock-down. May be set during chipset enabling. */ + static int ichspi_lock = 0; + +@@ -466,6 +512,8 @@ static int generate_opcodes(OPCODES * op) + + switch (ich_generation) { + case CHIPSET_ICH7: ++ case CHIPSET_TUNNEL_CREEK: ++ case CHIPSET_CENTERTON: + preop = REGREAD16(ICH7_REG_PREOP); + optype = REGREAD16(ICH7_REG_OPTYPE); + opmenu[0] = REGREAD32(ICH7_REG_OPMENU); +@@ -529,7 +577,7 @@ static int program_opcodes(OPCODES *op, int enable_undo) + opmenu[0] |= ((uint32_t) op->opcode[a].opcode) << (a * 8); + } + +- /*Program Allowable Opcodes 4 - 7 */ ++ /* Program Allowable Opcodes 4 - 7 */ + opmenu[1] = 0; + for (a = 4; a < 8; a++) { + opmenu[1] |= ((uint32_t) op->opcode[a].opcode) << ((a - 4) * 8); +@@ -538,6 +586,8 @@ static int program_opcodes(OPCODES *op, int enable_undo) + msg_pdbg2("\n%s: preop=%04x optype=%04x opmenu=%08x%08x\n", __func__, preop, optype, opmenu[0], opmenu[1]); + switch (ich_generation) { + case CHIPSET_ICH7: ++ case CHIPSET_TUNNEL_CREEK: ++ case CHIPSET_CENTERTON: + /* Register undo only for enable_undo=1, i.e. first call. */ + if (enable_undo) { + rmmio_valw(ich_spibar + ICH7_REG_PREOP); +@@ -603,10 +653,19 @@ static void ich_set_bbar(uint32_t min_addr) + int bbar_off; + switch (ich_generation) { + case CHIPSET_ICH7: ++ case CHIPSET_TUNNEL_CREEK: ++ case CHIPSET_CENTERTON: + bbar_off = 0x50; + break; + case CHIPSET_ICH8: ++#ifdef DELL_AVOTON_SUPPORT ++ case CHIPSET_AVOTON: ++#endif ++#ifdef FORCE10_SPI_CHANGE ++ msg_pdbg("BBAR offset is unknown on ICH8!\n"); ++#else + msg_perr("BBAR offset is unknown on ICH8!\n"); ++#endif + return; + case CHIPSET_ICH9: + default: /* Future version might behave the same */ +@@ -817,11 +876,17 @@ static int ich7_run_opcode(OPCODE op, uint32_t offset, + /* FIXME: make sure we do not needlessly cause transaction errors. */ + temp16 = REGREAD16(ICH7_REG_SPIS); + if (temp16 & SPIS_FCERR) { ++#ifndef FORCE10_SPI_CHANGE + msg_perr("Transaction error!\n"); ++#endif + /* keep reserved bits */ + temp16 &= SPIS_RESERVED_MASK; + REGWRITE16(ICH7_REG_SPIS, temp16 | SPIS_FCERR); ++#ifndef FORCE10_SPI_CHANGE + return 1; ++#else ++ return 0; ++#endif + } + + if ((!write_cmd) && (datalength != 0)) +@@ -838,6 +903,22 @@ static int ich9_run_opcode(OPCODE op, uint32_t offset, + uint32_t temp32; + uint64_t opmenu; + int opcode_index; ++/* skip unused region for Rangeley */ ++ if (offset >= 0x10000 && offset <= 0x9fffff) { ++ uint32_t i = 0; ++ for (i = 0; i < datalength; i++) ++ *(data + i) = 0xff; ++ return 0; ++ } ++#ifdef DELL_AVOTON_SUPPORT ++ /* skip unused region for Rangeley */ ++ if (is_avoton && offset >= 0x10000 && offset <= 0x9fffff) { ++ uint32_t i = 0; ++ for (i = 0; i < datalength; i++) ++ *(data + i) = 0xff; ++ return 0; ++ } ++#endif /* AVOTON */ + + /* Is it a write command? */ + if ((op.spi_type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS) +@@ -939,14 +1020,20 @@ static int ich9_run_opcode(OPCODE op, uint32_t offset, + /* FIXME make sure we do not needlessly cause transaction errors. */ + temp32 = REGREAD32(ICH9_REG_SSFS); + if (temp32 & SSFS_FCERR) { ++#ifndef FORCE10_SPI_CHANGE + msg_perr("Transaction error!\n"); ++#endif + prettyprint_ich9_reg_ssfs(temp32); + prettyprint_ich9_reg_ssfc(temp32); + /* keep reserved bits */ + temp32 &= SSFS_RESERVED_MASK | SSFC_RESERVED_MASK; + /* Clear the transaction error. */ + REGWRITE32(ICH9_REG_SSFS, temp32 | SSFS_FCERR); ++#ifndef FORCE10_SPI_CHANGE + return 1; ++#else ++ return 0; ++#endif + } + + if ((!write_cmd) && (datalength != 0)) +@@ -975,6 +1062,8 @@ static int run_opcode(const struct flashctx *flash, OPCODE op, uint32_t offset, + + switch (ich_generation) { + case CHIPSET_ICH7: ++ case CHIPSET_TUNNEL_CREEK: ++ case CHIPSET_CENTERTON: + return ich7_run_opcode(op, offset, datalength, data, maxlength); + case CHIPSET_ICH8: + default: /* Future version might behave the same */ +@@ -1418,6 +1507,191 @@ static int ich_spi_send_multicommand(struct flashctx *flash, + return ret; + } + ++#if DELL_DENVERTON_SUPPORT == 1 ++/* Sets FLA in FADDR to (addr & 0x01FFFFFF) without touching other bits. */ ++static void dnv_hwseq_set_addr(uint32_t addr) ++{ ++ uint32_t addr_old = REGREAD32(DENVERTON_REG_FADDR) & ~0x01FFFFFF; ++ REGWRITE32(DENVERTON_REG_FADDR, (addr & 0x01FFFFFF) | addr_old); ++} ++ ++/* Polls for Cycle Done Status, Flash Cycle Error or timeout in 8 us intervals. ++ Resets all error flags in HSFS. ++ Returns 0 if the cycle completes successfully without errors within ++ timeout us, 1 on errors. */ ++static int dnv_hwseq_wait_for_cycle_complete(uint32_t timeout, ++ uint32_t len) ++{ ++ uint16_t hsfs; ++ uint32_t addr; ++ ++ timeout /= 8; /* scale timeout duration to counter */ ++ while ((((hsfs = REGREAD16(DENVERTON_REG_HSFS)) & ++ (DENVERTON_HSFS_FDONE | DENVERTON_HSFS_FCERR)) == 0) && ++ --timeout) { ++ programmer_delay(8); ++ } ++ REGWRITE16(DENVERTON_REG_HSFS, REGREAD16(DENVERTON_REG_HSFS)); ++ if (!timeout) { ++ addr = REGREAD32(DENVERTON_REG_FADDR) & 0x01FFFFFF; ++ msg_perr("Timeout error between offset 0x%08x and " ++ "0x%08x (= 0x%08x + %d)!\n", ++ addr, addr + len - 1, addr, len - 1); ++ return 1; ++ } ++ ++ if (hsfs & DENVERTON_HSFS_FCERR) { ++ addr = REGREAD32(DENVERTON_REG_FADDR) & 0x01FFFFFF; ++ msg_perr("Transaction error between offset 0x%08x and " ++ "0x%08x (= 0x%08x + %d)!\n", ++ addr, addr + len - 1, addr, len - 1); ++ return 1; ++ } ++ return 0; ++} ++ ++int dnv_read_JEDEC_ID(uint8_t *buf) ++{ ++ uint16_t hsfc; ++ uint16_t timeout = 100 * 60; ++ uint8_t len = 3; ++ ++ /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ ++ REGWRITE16(DENVERTON_REG_HSFS, REGREAD16(DENVERTON_REG_HSFS)); ++ ++ dnv_hwseq_set_addr(0); ++ hsfc = REGREAD16(DENVERTON_REG_HSFC); ++ hsfc &= ~DENVERTON_HSFC_FCYCLE; /* clear operation */ ++ hsfc |= (0x6 << DENVERTON_HSFC_FCYCLE_OFF); /* set read JEDEC ID operation */ ++ hsfc &= ~DENVERTON_HSFC_FDBC; /* clear byte count */ ++ /* set byte count */ ++ hsfc |= (((len - 1) << DENVERTON_HSFC_FDBC_OFF) & DENVERTON_HSFC_FDBC); ++ hsfc |= DENVERTON_HSFC_FGO; /* start */ ++ REGWRITE16(DENVERTON_REG_HSFC, hsfc); ++ ++ if (dnv_hwseq_wait_for_cycle_complete(timeout, len)) ++ return 1; ++ ich_read_data(buf, len, DENVERTON_REG_FDATA0); ++ return 0; ++} ++ ++static int dnv_hwseq_probe(struct flashctx *flash) ++{ ++ uint8_t jedec_id[3]; ++ uint32_t tmp, manufacture_id, model_id; ++ struct block_eraser *eraser; ++ const struct flashchip *chip; ++ ++ msg_gdbg("Using HW Sequency to read JEDEC ID and find SPI flash.\n"); ++ if (dnv_read_JEDEC_ID(jedec_id)) { ++ msg_cerr("Can't get JEDEC ID through HW Sequency\n"); ++ return -1; ++ } ++ ++ manufacture_id = (uint32_t)jedec_id[0]; ++ model_id = (uint32_t)(jedec_id[1] << 8 | jedec_id[2]); ++ ++ for (chip = flashchips; chip && chip->name; chip++) { ++ if (chip->manufacture_id == manufacture_id && chip->model_id == model_id) { ++ break; ++ } ++ } ++ ++ flash->bios_size = (hwseq_data.size_comp0 + hwseq_data.size_comp1) / 1024; ++ ++ /* We only replace base information. The functions still use hw sequency, like read and write */ ++ flash->chip->vendor = chip->vendor; ++ flash->chip->name = chip->name; ++ flash->chip->manufacture_id = chip->manufacture_id; ++ flash->chip->model_id = chip->model_id; ++ flash->chip->total_size = chip->total_size; ++ flash->chip->page_size = chip->page_size; ++ ++ msg_cdbg("Hardware sequencing reports %d attached SPI flash chip", ++ (hwseq_data.size_comp1 != 0) ? 2 : 1); ++ if (hwseq_data.size_comp1 != 0) ++ msg_cdbg("s with a combined"); ++ else ++ msg_cdbg(" with a"); ++ msg_cdbg(" density of %d kB.\n", flash->chip->total_size); ++ ++ eraser = &(flash->chip->block_erasers[0]); ++ tmp = mmio_readl(ich_spibar + DENVERTON_REG_BFPREG); ++ dnv_bios_region_start = ((tmp & DENVERTON_BFPREG_PRB) >> DENVERTON_BFPREG_PRB_OFF) << 12; ++ dnv_bios_region_limit = ((tmp & DENVERTON_BFPREG_PRL) >> ++ DENVERTON_BFPREG_PRL_OFF) << 12 | ((1 << 12) -1); ++ dnv_bios_region_size = dnv_bios_region_limit - dnv_bios_region_start + 1; ++ eraser->eraseblocks[0].size = 4 * 1024; // 4K ++ eraser->eraseblocks[0].count = dnv_bios_region_size / ++ eraser->eraseblocks[0].size; ++ ++ flash->chip->tested = TEST_OK_PREW; ++ return 1; ++} ++ ++static int dnv_block_check(struct flashctx *flash, uint32_t addr, uint32_t len, SPI_SMI_CMD cmd) ++{ ++ char msg[3][4][32] = { ++ {"Read", "read", "", "Reading"}, ++ {"Erase", "erase", "Not erasing anthing.", "Erasing"}, ++ {"Write", "write", "", "Writing"}}; ++ ++ /* Although the hardware supports this (it would erase the whole block ++ * containing the address) we play safe here. */ ++ if (addr % DELL_DENVERTON_BLOCK_SIZE != 0) { ++ msg_cerr("%s address 0x%06x is not aligned to the %s " ++ "block boundary (any multiple of %d). %s\n", ++ msg[cmd][0], addr, msg[cmd][1], DELL_DENVERTON_BLOCK_SIZE, msg[cmd][2]); ++ return -1; ++ } ++ ++ if (addr + len > flash->chip->total_size * 1024) { ++ msg_perr("Request to %s some inaccessible memory address(es)" ++ " (addr=0x%x, len=%d). %s\n", msg[cmd][1], ++ addr, len, msg[cmd][2]); ++ return -1; ++ } ++ ++ msg_pdbg("%s %d bytes starting at 0x%06x.\n", msg[cmd][3], len, addr); ++ return 0; ++} ++ ++static int dnv_smi_spi(struct flashctx *flash, uint8_t *buf, uint32_t addr, ++ uint32_t len, SPI_SMI_CMD cmd) ++{ ++ int32_t ret = 0; ++ uint32_t block_index = 0; ++ ++ ret = dnv_block_check(flash, addr, len, cmd); ++ if (ret == 0) { ++ for (block_index = 0; block_index * DELL_DENVERTON_BLOCK_SIZE < len; block_index++ ) { ++ if ((ret = dnv_smi_doit(addr - dnv_bios_region_start, buf, cmd)) != 0) { ++ break; ++ } ++ buf += DELL_DENVERTON_BLOCK_SIZE; ++ addr += DELL_DENVERTON_BLOCK_SIZE; ++ } ++ } ++ return ret; ++} ++ ++static int dnv_smi_erase_spi(struct flashctx *flash, uint32_t addr, uint32_t len) ++{ ++ return dnv_smi_spi(flash, NULL, addr, len, SMI_ERASE_SPI); ++} ++ ++static int dnv_smi_read_spi(struct flashctx *flash, uint8_t *buf, uint32_t addr, uint32_t len) ++{ ++ return dnv_smi_spi(flash, buf, addr, len, SMI_READ_SPI); ++} ++ ++static int dnv_smi_write_spi(struct flashctx *flash, uint8_t *buf, uint32_t addr, uint32_t len) ++{ ++ return dnv_smi_spi(flash, buf, addr, len, SMI_WRITE_SPI); ++} ++ ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ ++ + #define ICH_BMWAG(x) ((x >> 24) & 0xff) + #define ICH_BMRAG(x) ((x >> 16) & 0xff) + #define ICH_BRWA(x) ((x >> 8) & 0xff) +@@ -1452,6 +1726,9 @@ static int ich9_handle_frap(uint32_t frap, int i) + msg_pdbg("FREG%i: %s region (0x%08x-0x%08x) is %s.\n", i, + region_names[i], base, (limit | 0x0fff), + access_names[rwperms]); ++#ifdef FORCE10_SPI_CHANGE ++ add_romentry(base, (limit | 0x0fff), region_names[i]); ++#endif + return 0; + } + +@@ -1514,6 +1791,90 @@ static void ich9_set_pr(int i, int read_prot, int write_prot) + msg_gspew("resulted in 0x%08x.\n", mmio_readl(addr)); + } + ++#if DELL_DENVERTON_SUPPORT == 1 ++/* returns 0 if region is unused or r/w */ ++static int dnv_handle_frap(uint32_t frap, int32_t i) ++{ ++ static const char *const access_names[4] = { ++ "locked", "read-only", "write-only", "read-write" ++ }; ++ static const char *const region_names[5] = { ++ "Flash Descriptor", "BIOS", "Management Engine", ++ "Gigabit Ethernet", "Platform Data" ++ }; ++ uint32_t base, limit; ++ int32_t rwperms = (((ICH_BRWA(frap) >> i) & 1) << 1) | ++ (((ICH_BRRA(frap) >> i) & 1) << 0); ++ int32_t offset = DENVERTON_REG_FREG0 + i * 4; ++ uint32_t freg = mmio_readl(ich_spibar + offset); ++ ++ base = ICH_FREG_BASE(freg); ++ limit = ICH_FREG_LIMIT(freg); ++ if (base > limit || (freg == 0 && i > 0)) { ++ /* this FREG is disabled */ ++ msg_pdbg2("0x%02X: 0x%08x FREG%i: %s region is unused.\n", ++ offset, freg, i, region_names[i]); ++ return 0; ++ } ++ msg_pdbg("0x%02X: 0x%08x ", offset, freg); ++ if (rwperms == 0x3) { ++ msg_pdbg("FREG%i: %s region (0x%08x-0x%08x) is %s.\n", i, ++ region_names[i], base, (limit | 0x0fff), ++ access_names[rwperms]); ++ return 0; ++ } ++ ++ msg_pwarn("FREG%i: Warning: %s region (0x%08x-0x%08x) is %s.\n", i, ++ region_names[i], base, (limit | 0x0fff), ++ access_names[rwperms]); ++ return 1; ++} ++ ++/* returns 0 if range is unused (i.e. r/w) */ ++static int dnv_handle_pr(int32_t i) ++{ ++ static const char *const access_names[3] = { ++ "locked", "read-only", "write-only" ++ }; ++ uint8_t off = DENVERTON_REG_PR0 + (i * 4); ++ uint32_t pr = mmio_readl(ich_spibar + off); ++ uint32_t rwperms = ICH_PR_PERMS(pr); ++ ++ if (rwperms == 0x3) { ++ msg_pdbg2("0x%02X: 0x%08x (PR%u is unused)\n", off, pr, i); ++ return 0; ++ } ++ ++ msg_pdbg("0x%02X: 0x%08x ", off, pr); ++ msg_pwarn("PR%u: Warning: 0x%08x-0x%08x is %s.\n", i, ICH_FREG_BASE(pr), ++ ICH_FREG_LIMIT(pr) | 0x0fff, access_names[rwperms]); ++ return 1; ++} ++ ++/* Set/Clear the read and write protection enable bits of PR register @i ++ * according to @read_prot and @write_prot. */ ++static void dnv_set_pr(int32_t i, int32_t read_prot, int32_t write_prot) ++{ ++ void *addr = ich_spibar + DENVERTON_REG_PR0 + (i * 4); ++ uint32_t old = mmio_readl(addr); ++ uint32_t new; ++ ++ msg_gspew("PR%u is 0x%08x", i, old); ++ new = old & ~((1 << DENVERTON_PR_RP_OFF) | (1 << DENVERTON_PR_WP_OFF)); ++ if (read_prot) ++ new |= (1 << DENVERTON_PR_RP_OFF); ++ if (write_prot) ++ new |= (1 << DENVERTON_PR_WP_OFF); ++ if (old == new) { ++ msg_gspew(" already.\n"); ++ return; ++ } ++ msg_gspew(", trying to set it to 0x%08x ", new); ++ rmmio_writel(new, addr); ++ msg_gspew("resulted in 0x%08x.\n", mmio_readl(addr)); ++} ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ ++ + static const struct spi_programmer spi_programmer_ich7 = { + .type = SPI_CONTROLLER_ICH7, + .max_data_read = 64, +@@ -1545,12 +1906,21 @@ static const struct opaque_programmer opaque_programmer_ich_hwseq = { + .erase = ich_hwseq_block_erase, + }; + +-int ich_init_spi(struct pci_dev *dev, uint32_t base, void *rcrb, +- enum ich_chipset ich_gen) ++#if DELL_DENVERTON_SUPPORT == 1 ++static const struct opaque_programmer opaque_master_dnv_hwseq = { ++ .max_data_read = 64, ++ .max_data_write = 64, ++ .probe = dnv_hwseq_probe, ++ .read = dnv_smi_read_spi, ++ .write = dnv_smi_write_spi, ++ .erase = dnv_smi_erase_spi, ++}; ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ ++ ++int ich_init_spi(struct pci_dev *dev, void *spibar, enum ich_chipset ich_gen) + { + int i; +- uint8_t old, new; +- uint16_t spibar_offset, tmp2; ++ uint16_t tmp2; + uint32_t tmp; + char *arg; + int ich_spi_force = 0; +@@ -1564,42 +1934,18 @@ int ich_init_spi(struct pci_dev *dev, uint32_t base, void *rcrb, + } ich_spi_mode = ich_auto; + + ich_generation = ich_gen; +- +- switch (ich_generation) { +- case CHIPSET_ICH_UNKNOWN: +- return ERROR_FATAL; +- case CHIPSET_ICH7: +- case CHIPSET_ICH8: +- spibar_offset = 0x3020; +- break; +- case CHIPSET_ICH9: +- default: /* Future version might behave the same */ +- spibar_offset = 0x3800; +- break; +- } +- +- /* SPIBAR is at RCRB+0x3020 for ICH[78] and RCRB+0x3800 for ICH9. */ +- msg_pdbg("SPIBAR = 0x%x + 0x%04x\n", base, spibar_offset); +- +- /* Assign Virtual Address */ +- ich_spibar = rcrb + spibar_offset; ++ ich_spibar = spibar; + + switch (ich_generation) { + case CHIPSET_ICH7: ++ case CHIPSET_TUNNEL_CREEK: ++ case CHIPSET_CENTERTON: + msg_pdbg("0x00: 0x%04x (SPIS)\n", + mmio_readw(ich_spibar + 0)); + msg_pdbg("0x02: 0x%04x (SPIC)\n", + mmio_readw(ich_spibar + 2)); + msg_pdbg("0x04: 0x%08x (SPIA)\n", + mmio_readl(ich_spibar + 4)); +- for (i = 0; i < 8; i++) { +- int offs; +- offs = 8 + (i * 8); +- msg_pdbg("0x%02x: 0x%08x (SPID%d)\n", offs, +- mmio_readl(ich_spibar + offs), i); +- msg_pdbg("0x%02x: 0x%08x (SPID%d+4)\n", offs + 4, +- mmio_readl(ich_spibar + offs + 4), i); +- } + ichspi_bbar = mmio_readl(ich_spibar + 0x50); + msg_pdbg("0x50: 0x%08x (BBAR)\n", + ichspi_bbar); +@@ -1625,7 +1971,123 @@ int ich_init_spi(struct pci_dev *dev, uint32_t base, void *rcrb, + ich_set_bbar(0); + register_spi_programmer(&spi_programmer_ich7); + break; ++#if DELL_DENVERTON_SUPPORT == 1 ++ case CHIPSET_DENVERTON: ++ ++ tmp2 = mmio_readw(ich_spibar + DENVERTON_REG_HSFS); ++ msg_pdbg("0x04: 0x%04x (HSFS)\n", tmp2); ++ if (tmp2 & DENVERTON_HSFS_FLOCKDN) { ++ msg_pwarn("Warning: SPI Configuration Lockdown activated.\n"); ++ ichspi_lock = 1; ++ } ++ if (tmp2 & DENVERTON_HSFS_FDV) ++ desc_valid = 1; ++ if (!(tmp2 & DENVERTON_HSFS_FDOPSS) && desc_valid) ++ msg_pinfo("The Flash Descriptor Override Strap-Pin is set. " ++ "Restrictions implied by\n" ++ "the Master Section of the flash descriptor are " ++ "NOT in effect. Please note\n" ++ "that Protected Range (PR) restrictions still apply.\n"); ++ if (desc_valid) { ++ tmp2 = mmio_readw(ich_spibar + DENVERTON_REG_HSFC); ++ msg_pdbg("0x06: 0x%04x (HSFC)\n", tmp2); ++ } ++ ++ tmp = mmio_readl(ich_spibar + DENVERTON_REG_FADDR); ++ msg_pdbg2("0x08: 0x%08x (FADDR)\n", tmp); ++ ++ if (desc_valid) { ++ tmp = mmio_readl(ich_spibar + DENVERTON_REG_FRAP); ++ msg_pdbg("0x50: 0x%08x (FRAP)", tmp); ++ ++ /* Handle FREGx and FRAP registers */ ++ for (i=0; i < 5; i++) ++ ich_spi_rw_restricted |= dnv_handle_frap(tmp, i); ++ if (ich_spi_rw_restricted) ++ msg_pwarn("Not all flash regions are freely accessible " ++ "by flashrom. This is most likely\n" ++ "due to an active ME. " ++ "Please see http://flashrom.org/ME for details.\n"); ++ } ++ ++ /* Handle PR registers */ ++ for (i = 0; i < 5; i++) { ++ if (!ichspi_lock) ++ dnv_set_pr(i, 0, 0); ++ ich_spi_rw_restricted |= dnv_handle_pr(i); ++ } ++ ++ if (ich_spi_force) ++ msg_pinfo("Continuing with write support because " ++ "the user forced us to!\n"); ++ ++ if (desc_valid) { ++ tmp = mmio_readl(ich_spibar + DENVERTON_REG_VSCC0); ++ msg_pdbg("0xC4: 0x%08x (VSCC0)\n", tmp); ++ ++ tmp = mmio_readl(ich_spibar + DENVERTON_REG_VSCC1); ++ msg_pdbg("0xC8: 0x%08x (VSCC1)\n", tmp); ++ ++ if (read_ich_descriptors_via_fdo(ich_spibar, &desc) == ICH_RET_OK) ++ prettyprint_ich_descriptors(ich_gen, &desc); ++ ++ /* If the descriptor is valid and indicates multiple ++ * flash devices we need to use hwseq to be able to ++ * access the second flash device. ++ */ ++ if (ich_spi_mode == ich_auto && desc.content.NC != 0) { ++ msg_pinfo("Enabling hardware sequencing due to " ++ "multiple flash chips detected.\n"); ++ ich_spi_mode = ich_hwseq; ++ } ++ } ++ ++ if (ich_spi_mode == ich_auto && ichspi_lock) { ++ msg_pinfo("Enabling hardware sequencing because " ++ "some important opcode is locked.\n"); ++ ich_spi_mode = ich_hwseq; ++ } ++ ++ if (ich_spi_mode == ich_auto && ichspi_lock) { ++ msg_pinfo("Enabling hardware sequencing because " ++ "some important opcode is locked.\n"); ++ ich_spi_mode = ich_hwseq; ++ } ++ ++ if (ich_spi_mode == ich_hwseq) { ++ if (!desc_valid) { ++ msg_perr("Hardware sequencing was requested " ++ "but the flash descriptor is not valid. Aborting.\n"); ++ return ERROR_FATAL; ++ } ++ ++ uint32_t tmpi = getFCBA_component_density(&desc, 0); ++ if (tmpi < 0) { ++ msg_perr("Could not determine density of " ++ "flash component %d.\n", 0); ++ return ERROR_FATAL; ++ } ++ hwseq_data.size_comp0 = tmpi; ++ ++ tmpi = getFCBA_component_density(&desc, 1); ++ if (tmpi < 0) { ++ msg_perr("Could not determine density of flash component %d.\n", 1); ++ return ERROR_FATAL; ++ } ++ hwseq_data.size_comp1 = tmpi; ++ ++ register_opaque_programmer(&opaque_master_dnv_hwseq); ++ } else { ++ msg_perr("[%s:%d] Error!!!\n", __func__, __LINE__); ++ return -1; ++ } ++ ++ break; ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + case CHIPSET_ICH8: ++#ifdef DELL_AVOTON_SUPPORT ++ case CHIPSET_AVOTON: ++#endif + default: /* Future version might behave the same */ + arg = extract_programmer_param("ich_spi_mode"); + if (arg && !strcmp(arg, "hwseq")) { +@@ -1669,7 +2131,11 @@ int ich_init_spi(struct pci_dev *dev, uint32_t base, void *rcrb, + msg_pdbg("0x04: 0x%04x (HSFS)\n", tmp2); + prettyprint_ich9_reg_hsfs(tmp2); + if (tmp2 & HSFS_FLOCKDN) { ++#ifdef FORCE10_SPI_CHANGE ++ msg_pdbg("Warning: SPI Configuration Lockdown activated.\n"); ++#else + msg_pwarn("Warning: SPI Configuration Lockdown activated.\n"); ++#endif + ichspi_lock = 1; + } + if (tmp2 & HSFS_FDV) +@@ -1690,6 +2156,7 @@ int ich_init_spi(struct pci_dev *dev, uint32_t base, void *rcrb, + msg_pdbg2("0x08: 0x%08x (FADDR)\n", tmp); + + if (desc_valid) { ++ + tmp = mmio_readl(ich_spibar + ICH9_REG_FRAP); + msg_pdbg("0x50: 0x%08x (FRAP)\n", tmp); + msg_pdbg("BMWAG 0x%02x, ", ICH_BMWAG(tmp)); +@@ -1750,10 +2217,15 @@ int ich_init_spi(struct pci_dev *dev, uint32_t base, void *rcrb, + msg_pdbg("VSCC: "); + prettyprint_ich_reg_vscc(tmp, MSG_DEBUG); + } else { ++#ifdef DELL_AVOTON_SUPPORT ++ if (ich_generation != CHIPSET_AVOTON) { ++#endif + ichspi_bbar = mmio_readl(ich_spibar + ICH9_REG_BBAR); + msg_pdbg("0xA0: 0x%08x (BBAR)\n", + ichspi_bbar); +- ++#ifdef DELL_AVOTON_SUPPORT ++ } ++#endif + if (desc_valid) { + tmp = mmio_readl(ich_spibar + ICH9_REG_LVSCC); + msg_pdbg("0xC4: 0x%08x (LVSCC)\n", tmp); +@@ -1811,21 +2283,6 @@ int ich_init_spi(struct pci_dev *dev, uint32_t base, void *rcrb, + break; + } + +- old = pci_read_byte(dev, 0xdc); +- msg_pdbg("SPI Read Configuration: "); +- new = (old >> 2) & 0x3; +- switch (new) { +- case 0: +- case 1: +- case 2: +- msg_pdbg("prefetching %sabled, caching %sabled, ", +- (new & 0x2) ? "en" : "dis", +- (new & 0x1) ? "dis" : "en"); +- break; +- default: +- msg_pdbg("invalid prefetching/caching settings, "); +- break; +- } + return 0; + } + +@@ -1844,7 +2301,9 @@ int via_init_spi(struct pci_dev *dev, uint32_t mmio_base) + { + int i; + +- ich_spibar = physmap("VIA SPI MMIO registers", mmio_base, 0x70); ++ ich_spibar = rphysmap("VIA SPI MMIO registers", mmio_base, 0x70); ++ if (ich_spibar == ERROR_PTR) ++ return ERROR_FATAL; + /* Do we really need no write enable? Like the LPC one at D17F0 0x40 */ + + /* Not sure if it speaks all these bus protocols. */ +diff --git a/internal.c b/internal.c +index ab3c81f..30b184f 100644 +--- a/internal.c ++++ b/internal.c +@@ -331,9 +331,8 @@ int internal_init(void) + return ret; + + #if defined(__i386__) || defined(__x86_64__) +- /* Probe unconditionally for IT87* LPC->SPI translation and for +- * IT87* Parallel write enable. +- */ ++ /* Probe unconditionally for ITE Super I/O chips. This enables LPC->SPI translation on IT87* and ++ * parallel writes on IT8705F. Also, this handles the manual chip select for Gigabyte's DualBIOS. */ + init_superio_ite(); + #endif + +diff --git a/it85spi.c b/it85spi.c +index 0b074eb..7efc680 100644 +--- a/it85spi.c ++++ b/it85spi.c +@@ -262,6 +262,9 @@ static int it85xx_spi_common_init(struct superio s) + * Major TODO here, and it will be a lot of work. + */ + base = (chipaddr)physmap("it85 communication", 0xFFFFF000, 0x1000); ++ if (base == (chipaddr)ERROR_PTR) ++ return 1; ++ + msg_pdbg("%s():%d base=0x%08x\n", __func__, __LINE__, + (unsigned int)base); + ce_high = (unsigned char *)(base + 0xE00); /* 0xFFFFFE00 */ +diff --git a/it87spi.c b/it87spi.c +index 8e4e0ad..be7f234 100644 +--- a/it87spi.c ++++ b/it87spi.c +@@ -27,6 +27,7 @@ + + #include + #include ++#include + #include "flash.h" + #include "chipdrivers.h" + #include "programmer.h" +@@ -36,7 +37,7 @@ + #define ITE_SUPERIO_PORT1 0x2e + #define ITE_SUPERIO_PORT2 0x4e + +-uint16_t it8716f_flashport = 0; ++static uint16_t it8716f_flashport = 0; + /* use fast 33MHz SPI (<>0) or slow 16MHz (0) */ + static int fast_spi = 1; + +@@ -124,10 +125,40 @@ static const struct spi_programmer spi_programmer_it87xx = { + static uint16_t it87spi_probe(uint16_t port) + { + uint8_t tmp = 0; +- char *portpos = NULL; + uint16_t flashport = 0; + + enter_conf_mode_ite(port); ++ ++ char *param = extract_programmer_param("dualbiosindex"); ++ if (param != NULL) { ++ sio_write(port, 0x07, 0x07); /* Select GPIO LDN */ ++ tmp = sio_read(port, 0xEF); ++ if (*param == '\0') { /* Print current setting only. */ ++ free(param); ++ } else { ++ char *dualbiosindex_suffix; ++ errno = 0; ++ long chip_index = strtol(param, &dualbiosindex_suffix, 0); ++ free(param); ++ if (errno != 0 || *dualbiosindex_suffix != '\0' || chip_index < 0 || chip_index > 1) { ++ msg_perr("DualBIOS: Invalid chip index requested - choose 0 or 1.\n"); ++ exit_conf_mode_ite(port); ++ return 1; ++ } ++ if (chip_index != (tmp & 1)) { ++ msg_pdbg("DualBIOS: Previous chip index: %d\n", tmp & 1); ++ sio_write(port, 0xEF, (tmp & 0xFE) | chip_index); ++ tmp = sio_read(port, 0xEF); ++ if ((tmp & 1) != chip_index) { ++ msg_perr("DualBIOS: Chip selection failed.\n"); ++ exit_conf_mode_ite(port); ++ return 1; ++ } ++ } ++ } ++ msg_pinfo("DualBIOS: Selected chip: %d\n", tmp & 1); ++ } ++ + /* NOLDN, reg 0x24, mask out lowest bit (suspend) */ + tmp = sio_read(port, 0x24) & 0xFE; + /* Check if LPC->SPI translation is active. */ +@@ -163,11 +194,11 @@ static uint16_t it87spi_probe(uint16_t port) + flashport |= sio_read(port, 0x65); + msg_pdbg("Serial flash port 0x%04x\n", flashport); + /* Non-default port requested? */ +- portpos = extract_programmer_param("it87spiport"); +- if (portpos) { ++ param = extract_programmer_param("it87spiport"); ++ if (param) { + char *endptr = NULL; + unsigned long forced_flashport; +- forced_flashport = strtoul(portpos, &endptr, 0); ++ forced_flashport = strtoul(param, &endptr, 0); + /* Port 0, port >0x1000, unaligned ports and garbage strings + * are rejected. + */ +@@ -180,7 +211,8 @@ static uint16_t it87spi_probe(uint16_t port) + msg_perr("Error: it87spiport specified, but no valid " + "port specified.\nPort must be a multiple of " + "0x8 and lie between 0x100 and 0xff8.\n"); +- free(portpos); ++ exit_conf_mode_ite(port); ++ free(param); + return 1; + } else { + flashport = (uint16_t)forced_flashport; +@@ -190,7 +222,7 @@ static uint16_t it87spi_probe(uint16_t port) + sio_write(port, 0x65, (flashport & 0xff)); + } + } +- free(portpos); ++ free(param); + exit_conf_mode_ite(port); + it8716f_flashport = flashport; + if (internal_buses_supported & BUS_SPI) +@@ -228,6 +260,7 @@ int init_superio_ite(void) + case 0x8716: + case 0x8718: + case 0x8720: ++ case 0x8728: + ret |= it87spi_probe(superios[i].port); + break; + default: +diff --git a/layout.c b/layout.c +index 1bd3152..d00c16c 100644 +--- a/layout.c ++++ b/layout.c +@@ -3,6 +3,7 @@ + * + * Copyright (C) 2005-2008 coresystems GmbH + * (Written by Stefan Reinauer for coresystems GmbH) ++ * Copyright (C) 2011-2013 Stefan Tauner + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -25,24 +26,23 @@ + #include "flash.h" + #include "programmer.h" + +-static int romimages = 0; +- + #define MAX_ROMLAYOUT 32 + + typedef struct { +- unsigned int start; +- unsigned int end; ++ chipoff_t start; ++ chipoff_t end; + unsigned int included; + char name[256]; +-} romlayout_t; ++} romentry_t; + +-/* include_args lists arguments specified at the command line with -i. They +- * must be processed at some point so that desired regions are marked as +- * "included" in the rom_entries list. +- */ ++/* rom_entries store the entries specified in a layout file and associated run-time data */ ++static romentry_t rom_entries[MAX_ROMLAYOUT]; ++static int num_rom_entries = 0; /* the number of successfully parsed rom_entries */ ++ ++/* include_args holds the arguments specified at the command line with -i. They must be processed at some point ++ * so that desired regions are marked as "included" in the rom_entries list. */ + static char *include_args[MAX_ROMLAYOUT]; +-static int num_include_args = 0; /* the number of valid entries. */ +-static romlayout_t rom_entries[MAX_ROMLAYOUT]; ++static int num_include_args = 0; /* the number of valid include_args. */ + + #ifndef __LIBPAYLOAD__ + int read_romlayout(char *name) +@@ -62,12 +62,13 @@ int read_romlayout(char *name) + while (!feof(romlayout)) { + char *tstr1, *tstr2; + +- if (romimages >= MAX_ROMLAYOUT) { ++ if (num_rom_entries >= MAX_ROMLAYOUT) { + msg_gerr("Maximum number of ROM images (%i) in layout " + "file reached.\n", MAX_ROMLAYOUT); ++ fclose(romlayout); + return 1; + } +- if (2 != fscanf(romlayout, "%s %s\n", tempstr, rom_entries[romimages].name)) ++ if (2 != fscanf(romlayout, "%s %s\n", tempstr, rom_entries[num_rom_entries].name)) + continue; + #if 0 + // fscanf does not like arbitrary comments like that :( later +@@ -82,13 +83,13 @@ int read_romlayout(char *name) + fclose(romlayout); + return 1; + } +- rom_entries[romimages].start = strtol(tstr1, (char **)NULL, 16); +- rom_entries[romimages].end = strtol(tstr2, (char **)NULL, 16); +- rom_entries[romimages].included = 0; +- romimages++; ++ rom_entries[num_rom_entries].start = strtol(tstr1, (char **)NULL, 16); ++ rom_entries[num_rom_entries].end = strtol(tstr2, (char **)NULL, 16); ++ rom_entries[num_rom_entries].included = 0; ++ num_rom_entries++; + } + +- for (i = 0; i < romimages; i++) { ++ for (i = 0; i < num_rom_entries; i++) { + msg_gdbg("romlayout %08x - %08x named %s\n", + rom_entries[i].start, + rom_entries[i].end, rom_entries[i].name); +@@ -100,6 +101,33 @@ int read_romlayout(char *name) + } + #endif + ++ ++#ifdef FORCE10_SPI_CHANGE ++int add_romentry(chipoff_t start, chipoff_t end, const char *name) ++{ ++ int len = 0; ++ ++ if (num_rom_entries >= MAX_ROMLAYOUT) { ++ msg_gerr("Maximum number of ROM images (%i) in layout " ++ "file reached.\n", MAX_ROMLAYOUT); ++ return 1; ++ } ++ rom_entries[num_rom_entries].start = start; ++ rom_entries[num_rom_entries].end = end; ++ rom_entries[num_rom_entries].included = 1; ++ len = strlen(name); ++ if (len > 256) { ++ msg_gdbg("terminating rom entry name to 256 as it exceeds max length\n"); ++ len = 255; ++ } ++ strncpy(rom_entries[num_rom_entries].name, name, len); ++ msg_gdbg("Adding rom entry: %08x - %08x named %s\n", rom_entries[num_rom_entries].start, ++ rom_entries[num_rom_entries].end, rom_entries[num_rom_entries].name); ++ num_rom_entries++; ++ return 0; ++} ++#endif ++ + /* returns the index of the entry (or a negative value if it is not found) */ + int find_include_arg(const char *const name) + { +@@ -139,11 +167,11 @@ static int find_romentry(char *name) + { + int i; + +- if (!romimages) ++ if (num_rom_entries == 0) + return -1; + + msg_gspew("Looking for region \"%s\"... ", name); +- for (i = 0; i < romimages; i++) { ++ for (i = 0; i < num_rom_entries; i++) { + if (!strcmp(rom_entries[i].name, name)) { + rom_entries[i].included = 1; + msg_gspew("found.\n"); +@@ -166,7 +194,7 @@ int process_include_args(void) + return 0; + + /* User has specified an area, but no layout file is loaded. */ +- if (!romimages) { ++ if (num_rom_entries == 0) { + msg_gerr("Region requested (with -i \"%s\"), " + "but no layout data is available.\n", + include_args[0]); +@@ -190,15 +218,30 @@ int process_include_args(void) + return 0; + } + +-romlayout_t *get_next_included_romentry(unsigned int start) ++void layout_cleanup(void) ++{ ++ int i; ++ for (i = 0; i < num_include_args; i++) { ++ free(include_args[i]); ++ include_args[i] = NULL; ++ } ++ num_include_args = 0; ++ ++ for (i = 0; i < num_rom_entries; i++) { ++ rom_entries[i].included = 0; ++ } ++ num_rom_entries = 0; ++} ++ ++romentry_t *get_next_included_romentry(unsigned int start) + { + int i; + unsigned int best_start = UINT_MAX; +- romlayout_t *best_entry = NULL; +- romlayout_t *cur; ++ romentry_t *best_entry = NULL; ++ romentry_t *cur; + + /* First come, first serve for overlapping regions. */ +- for (i = 0; i < romimages; i++) { ++ for (i = 0; i < num_rom_entries; i++) { + cur = &rom_entries[i]; + if (!cur->included) + continue; +@@ -217,18 +260,43 @@ romlayout_t *get_next_included_romentry(unsigned int start) + return best_entry; + } + +-int handle_romentries(const struct flashctx *flash, uint8_t *oldcontents, uint8_t *newcontents) ++/* Validate and - if needed - normalize layout entries. */ ++int normalize_romentries(const struct flashctx *flash) ++{ ++ chipsize_t total_size = flash->chip->total_size * 1024; ++ int ret = 0; ++ ++ int i; ++ for (i = 0; i < num_rom_entries; i++) { ++ if (rom_entries[i].start >= total_size || rom_entries[i].end >= total_size) { ++ msg_gwarn("Warning: Address range of region \"%s\" exceeds the current chip's " ++ "address space.\n", rom_entries[i].name); ++ if (rom_entries[i].included) ++ ret = 1; ++ } ++ if (rom_entries[i].start > rom_entries[i].end) { ++ msg_gerr("Error: Size of the address range of region \"%s\" is not positive.\n", ++ rom_entries[i].name); ++ ret = 1; ++ } ++ } ++ ++ return ret; ++} ++ ++int build_new_image(const struct flashctx *flash, uint8_t *oldcontents, uint8_t *newcontents) + { + unsigned int start = 0; +- romlayout_t *entry; ++ romentry_t *entry; + unsigned int size = flash->chip->total_size * 1024; + + /* If no regions were specified for inclusion, assume + * that the user wants to write the complete new image. + */ ++#ifndef FORCE10_SPI_CHANGE + if (num_include_args == 0) + return 0; +- ++#endif + /* Non-included romentries are ignored. + * The union of all included romentries is used from the new image. + */ +@@ -239,7 +307,7 @@ int handle_romentries(const struct flashctx *flash, uint8_t *oldcontents, uint8_ + memcpy(newcontents + start, oldcontents + start, + size - start); + break; +- } ++ } + /* For non-included region, copy from old content. */ + if (entry->start > start) + memcpy(newcontents + start, oldcontents + start, +diff --git a/linux_spi.c b/linux_spi.c +index d12fceb..f0c6404 100644 +--- a/linux_spi.c ++++ b/linux_spi.c +@@ -60,7 +60,7 @@ static const struct spi_programmer spi_programmer_linux = { + int linux_spi_init(void) + { + char *p, *endp, *dev; +- uint32_t speed = 0; ++ uint32_t speed_hz = 0; + /* FIXME: make the following configurable by CLI options. */ + /* SPI mode 0 (beware this also includes: MSB first, CS active low and others */ + const uint8_t mode = SPI_MODE_0; +@@ -68,7 +68,7 @@ int linux_spi_init(void) + + p = extract_programmer_param("spispeed"); + if (p && strlen(p)) { +- speed = (uint32_t)strtoul(p, &endp, 10) * 1024; ++ speed_hz = (uint32_t)strtoul(p, &endp, 10) * 1000; + if (p == endp) { + msg_perr("%s: invalid clock: %s kHz\n", __func__, p); + free(p); +@@ -98,14 +98,14 @@ int linux_spi_init(void) + return 1; + /* We rely on the shutdown function for cleanup from here on. */ + +- if (speed > 0) { +- if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) == -1) { ++ if (speed_hz > 0) { ++ if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed_hz) == -1) { + msg_perr("%s: failed to set speed to %d Hz: %s\n", +- __func__, speed, strerror(errno)); ++ __func__, speed_hz, strerror(errno)); + return 1; + } + +- msg_pdbg("Using %d kHz clock\n", speed); ++ msg_pdbg("Using %d kHz clock\n", speed_hz/1000); + } + + if (ioctl(fd, SPI_IOC_WR_MODE, &mode) == -1) { +diff --git a/mcp6x_spi.c b/mcp6x_spi.c +index ac40557..20e9bd8 100644 +--- a/mcp6x_spi.c ++++ b/mcp6x_spi.c +@@ -135,25 +135,20 @@ int mcp6x_spi_init(int want_spi) + + /* Accessing a NULL pointer BAR is evil. Don't do it. */ + if (!mcp6x_spibaraddr && want_spi) { +- msg_perr("Error: Chipset is strapped for SPI, but MCP SPI BAR " +- "is invalid.\n"); ++ msg_perr("Error: Chipset is strapped for SPI, but MCP SPI BAR is invalid.\n"); + return 1; + } else if (!mcp6x_spibaraddr && !want_spi) { + msg_pdbg("MCP SPI is not used.\n"); + return 0; + } else if (mcp6x_spibaraddr && !want_spi) { +- msg_pdbg("Strange. MCP SPI BAR is valid, but chipset apparently" +- " doesn't have SPI enabled.\n"); ++ msg_pdbg("Strange. MCP SPI BAR is valid, but chipset apparently doesn't have SPI enabled.\n"); + /* FIXME: Should we enable SPI anyway? */ + return 0; + } + /* Map the BAR. Bytewise/wordwise access at 0x530 and 0x540. */ +- mcp6x_spibar = physmap("NVIDIA MCP6x SPI", mcp6x_spibaraddr, 0x544); +- +-#if 0 +- /* FIXME: Run the physunmap in a shutdown function. */ +- physunmap(mcp6x_spibar, 0x544); +-#endif ++ mcp6x_spibar = rphysmap("NVIDIA MCP6x SPI", mcp6x_spibaraddr, 0x544); ++ if (mcp6x_spibar == ERROR_PTR) ++ return 1; + + status = mmio_readw(mcp6x_spibar + 0x530); + msg_pdbg("SPI control is 0x%04x, req=%i, gnt=%i\n", +diff --git a/nic3com.c b/nic3com.c +index 8d67b54..27e28c7 100644 +--- a/nic3com.c ++++ b/nic3com.c +@@ -96,6 +96,8 @@ int nic3com_init(void) + return 1; + + io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0); ++ if (!io_base_addr) ++ return 1; + + id = dev->device_id; + +diff --git a/nicintel.c b/nicintel.c +index 56678e7..98ba29f 100644 +--- a/nicintel.c ++++ b/nicintel.c +@@ -59,13 +59,6 @@ static const struct par_programmer par_programmer_nicintel = { + .chip_writen = fallback_chip_writen, + }; + +-static int nicintel_shutdown(void *data) +-{ +- physunmap(nicintel_control_bar, NICINTEL_CONTROL_MEMMAP_SIZE); +- physunmap(nicintel_bar, NICINTEL_MEMMAP_SIZE); +- return 0; +-} +- + int nicintel_init(void) + { + struct pci_dev *dev = NULL; +@@ -83,18 +76,19 @@ int nicintel_init(void) + return 1; + + addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_2); +- nicintel_bar = physmap("Intel NIC flash", addr, NICINTEL_MEMMAP_SIZE); ++ if (!addr) ++ return 1; ++ ++ nicintel_bar = rphysmap("Intel NIC flash", addr, NICINTEL_MEMMAP_SIZE); + if (nicintel_bar == ERROR_PTR) +- goto error_out_unmap; ++ return 1; + + addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0); +- /* FIXME: This is not an aligned mapping. Use 4k? */ +- nicintel_control_bar = physmap("Intel NIC control/status reg", +- addr, NICINTEL_CONTROL_MEMMAP_SIZE); +- if (nicintel_control_bar == ERROR_PTR) +- goto error_out; ++ if (!addr) ++ return 1; + +- if (register_shutdown(nicintel_shutdown, NULL)) ++ nicintel_control_bar = rphysmap("Intel NIC control/status reg", addr, NICINTEL_CONTROL_MEMMAP_SIZE); ++ if (nicintel_control_bar == ERROR_PTR) + return 1; + + /* FIXME: This register is pretty undocumented in all publicly available +@@ -112,11 +106,6 @@ int nicintel_init(void) + register_par_programmer(&par_programmer_nicintel, BUS_PARALLEL); + + return 0; +- +-error_out_unmap: +- physunmap(nicintel_bar, NICINTEL_MEMMAP_SIZE); +-error_out: +- return 1; + } + + static void nicintel_chip_writeb(const struct flashctx *flash, uint8_t val, +diff --git a/nicintel_spi.c b/nicintel_spi.c +index 0045c09..1522c9b 100644 +--- a/nicintel_spi.c ++++ b/nicintel_spi.c +@@ -19,10 +19,16 @@ + */ + + /* +- * Datasheet: ++ * Datasheets: + * PCI/PCI-X Family of Gigabit Ethernet Controllers Software Developer's Manual + * 82540EP/EM, 82541xx, 82544GC/EI, 82545GM/EM, 82546GB/EB, and 82547xx +- * http://download.intel.com/design/network/manuals/8254x_GBe_SDM.pdf ++ * http://www.intel.com/content/www/us/en/ethernet-controllers/pci-pci-x-family-gbe-controllers-software-dev-manual.html ++ * ++ * PCIe GbE Controllers Open Source Software Developer's Manual ++ * http://www.intel.com/content/www/us/en/ethernet-controllers/pcie-gbe-controllers-open-source-manual.html ++ * ++ * Intel 82574 Gigabit Ethernet Controller Family Datasheet ++ * http://www.intel.com/content/www/us/en/ethernet-controllers/82574l-gbe-controller-datasheet.html + */ + + #include +@@ -72,6 +78,7 @@ const struct dev_entry nics_intel_spi[] = { + {PCI_VENDOR_ID_INTEL, 0x1076, OK, "Intel", "82541GI Gigabit Ethernet Controller"}, + {PCI_VENDOR_ID_INTEL, 0x107c, OK, "Intel", "82541PI Gigabit Ethernet Controller"}, + {PCI_VENDOR_ID_INTEL, 0x10b9, OK, "Intel", "82572EI Gigabit Ethernet Controller"}, ++ {PCI_VENDOR_ID_INTEL, 0x10d3, OK, "Intel", "82574L Gigabit Ethernet Controller"}, + + {0}, + }; +@@ -151,16 +158,12 @@ static int nicintel_spi_shutdown(void *data) + { + uint32_t tmp; + +- /* Disable writes manually. See the comment about EECD in +- * nicintel_spi_init() for details. +- */ ++ /* Disable writes manually. See the comment about EECD in nicintel_spi_init() for details. */ + tmp = pci_mmio_readl(nicintel_spibar + EECD); + tmp &= ~FLASH_WRITES_ENABLED; + tmp |= FLASH_WRITES_DISABLED; + pci_mmio_writel(tmp, nicintel_spibar + EECD); + +- physunmap(nicintel_spibar, MEMMAP_SIZE); +- + return 0; + } + +@@ -177,8 +180,13 @@ int nicintel_spi_init(void) + return 1; + + io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0); +- nicintel_spibar = physmap("Intel Gigabit NIC w/ SPI flash", +- io_base_addr, MEMMAP_SIZE); ++ if (!io_base_addr) ++ return 1; ++ ++ nicintel_spibar = rphysmap("Intel Gigabit NIC w/ SPI flash", io_base_addr, MEMMAP_SIZE); ++ if (nicintel_spibar == ERROR_PTR) ++ return 1; ++ + /* Automatic restore of EECD on shutdown is not possible because EECD + * does not only contain FLASH_WRITES_DISABLED|FLASH_WRITES_ENABLED, + * but other bits with side effects as well. Those other bits must be +diff --git a/nicnatsemi.c b/nicnatsemi.c +index d62a73f..cb8da6d 100644 +--- a/nicnatsemi.c ++++ b/nicnatsemi.c +@@ -64,6 +64,8 @@ int nicnatsemi_init(void) + return 1; + + io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0); ++ if (!io_base_addr) ++ return 1; + + /* The datasheet shows address lines MA0-MA16 in one place and MA0-MA15 + * in another. My NIC has MA16 connected to A16 on the boot ROM socket +diff --git a/nicrealtek.c b/nicrealtek.c +index fb8e9e1..02fbd39 100644 +--- a/nicrealtek.c ++++ b/nicrealtek.c +@@ -69,6 +69,8 @@ int nicrealtek_init(void) + return 1; + + io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0); ++ if (!io_base_addr) ++ return 1; + + /* Beware, this ignores the vendor ID! */ + switch (dev->device_id) { +diff --git a/ogp_spi.c b/ogp_spi.c +index 0c09d6a..23431d1 100644 +--- a/ogp_spi.c ++++ b/ogp_spi.c +@@ -97,12 +97,6 @@ static const struct bitbang_spi_master bitbang_spi_master_ogp = { + .half_period = 0, + }; + +-static int ogp_spi_shutdown(void *data) +-{ +- physunmap(ogp_spibar, 4096); +- return 0; +-} +- + int ogp_spi_init(void) + { + struct pci_dev *dev = NULL; +@@ -126,8 +120,10 @@ int ogp_spi_init(void) + ogp_reg_sck = OGA1_XP10_CPROM_SCK; + } else { + msg_perr("Invalid or missing rom= parameter.\n"); ++ free(type); + return 1; + } ++ free(type); + + if (rget_io_perms()) + return 1; +@@ -137,9 +133,11 @@ int ogp_spi_init(void) + return 1; + + io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0); +- ogp_spibar = physmap("OGP registers", io_base_addr, 4096); ++ if (!io_base_addr) ++ return 1; + +- if (register_shutdown(ogp_spi_shutdown, NULL)) ++ ogp_spibar = rphysmap("OGP registers", io_base_addr, 4096); ++ if (ogp_spibar == ERROR_PTR) + return 1; + + if (bitbang_spi_init(&bitbang_spi_master_ogp)) +diff --git a/pcidev.c b/pcidev.c +index c7e9d78..3a3f77c 100644 +--- a/pcidev.c ++++ b/pcidev.c +@@ -94,7 +94,7 @@ uintptr_t pcidev_readbar(struct pci_dev *dev, int bar) + + supported_cycles = pci_read_word(dev, PCI_COMMAND); + +- msg_pdbg("Requested BAR is "); ++ msg_pdbg("Requested BAR is of type "); + switch (bartype) { + case TYPE_MEMBAR: + msg_pdbg("MEM"); +diff --git a/physmap.c b/physmap.c +index 932fe75..150c44a 100644 +--- a/physmap.c ++++ b/physmap.c +@@ -21,11 +21,13 @@ + */ + + #include ++#include + #include + #include + #include + #include + #include "flash.h" ++#include "programmer.h" + #include "hwaccess.h" + + #if !defined(__DJGPP__) && !defined(__LIBPAYLOAD__) +@@ -88,7 +90,7 @@ static void *sys_physmap(uintptr_t phys_addr, size_t len) + #define sys_physmap_rw_uncached sys_physmap + #define sys_physmap_ro_cached sys_physmap + +-void physunmap(void *virt_addr, size_t len) ++void sys_physunmap_unaligned(void *virt_addr, size_t len) + { + __dpmi_meminfo mi; + +@@ -117,7 +119,7 @@ void *sys_physmap(uintptr_t phys_addr, size_t len) + #define sys_physmap_rw_uncached sys_physmap + #define sys_physmap_ro_cached sys_physmap + +-void physunmap(void *virt_addr, size_t len) ++void sys_physunmap_unaligned(void *virt_addr, size_t len) + { + } + #elif defined(__MACH__) && defined(__APPLE__) +@@ -138,7 +140,7 @@ static void *sys_physmap(uintptr_t phys_addr, size_t len) + #define sys_physmap_rw_uncached sys_physmap + #define sys_physmap_ro_cached sys_physmap + +-void physunmap(void *virt_addr, size_t len) ++void sys_physunmap_unaligned(void *virt_addr, size_t len) + { + unmap_physical(virt_addr, len); + } +@@ -164,12 +166,11 @@ static void *sys_physmap_rw_uncached(uintptr_t phys_addr, size_t len) + /* Open the memory device UNCACHED. Important for MMIO. */ + if (-1 == (fd_mem = open(MEM_DEV, O_RDWR | O_SYNC))) { + msg_perr("Critical error: open(" MEM_DEV "): %s\n", strerror(errno)); +- exit(2); ++ return ERROR_PTR; + } + } + +- virt_addr = mmap(NULL, len, PROT_WRITE | PROT_READ, MAP_SHARED, +- fd_mem, (off_t)phys_addr); ++ virt_addr = mmap(NULL, len, PROT_WRITE | PROT_READ, MAP_SHARED, fd_mem, (off_t)phys_addr); + return MAP_FAILED == virt_addr ? ERROR_PTR : virt_addr; + } + +@@ -184,50 +185,77 @@ static void *sys_physmap_ro_cached(uintptr_t phys_addr, size_t len) + /* Open the memory device CACHED. */ + if (-1 == (fd_mem_cached = open(MEM_DEV, O_RDWR))) { + msg_perr("Critical error: open(" MEM_DEV "): %s\n", strerror(errno)); +- exit(2); ++ return ERROR_PTR; + } + } + +- virt_addr = mmap(NULL, len, PROT_READ, MAP_SHARED, +- fd_mem_cached, (off_t)phys_addr); ++ virt_addr = mmap(NULL, len, PROT_READ, MAP_SHARED, fd_mem_cached, (off_t)phys_addr); + return MAP_FAILED == virt_addr ? ERROR_PTR : virt_addr; + } + +-void physunmap(void *virt_addr, size_t len) ++void sys_physunmap_unaligned(void *virt_addr, size_t len) + { +- if (len == 0) { +- msg_pspew("Not unmapping zero size at %p\n", virt_addr); +- return; +- } +- + munmap(virt_addr, len); + } + #endif + +-#define PHYSMAP_NOFAIL 0 +-#define PHYSMAP_MAYFAIL 1 +-#define PHYSMAP_RW 0 +-#define PHYSMAP_RO 1 ++#define PHYSM_RW 0 ++#define PHYSM_RO 1 ++#define PHYSM_NOCLEANUP 0 ++#define PHYSM_CLEANUP 1 ++#define PHYSM_EXACT 0 ++#define PHYSM_ROUND 1 ++ ++/* Round start to nearest page boundary below and set len so that the resulting address range ends at the lowest ++ * possible page boundary where the original address range is still entirely contained. It returns the ++ * difference between the rounded start address and the original start address. */ ++static uintptr_t round_to_page_boundaries(uintptr_t *start, size_t *len) ++{ ++ uintptr_t page_size = getpagesize(); ++ uintptr_t page_mask = ~(page_size-1); ++ uintptr_t end = *start + *len; ++ uintptr_t old_start = *start; ++ msg_gspew("page_size=%" PRIxPTR "\n", page_size); ++ msg_gspew("pre-rounding: start=0x%0*" PRIxPTR ", len=0x%zx, end=0x%0*" PRIxPTR "\n", ++ PRIxPTR_WIDTH, *start, *len, PRIxPTR_WIDTH, end); ++ *start = *start & page_mask; ++ end = (end + page_size - 1) & page_mask; ++ *len = end - *start; ++ msg_gspew("post-rounding: start=0x%0*" PRIxPTR ", len=0x%zx, end=0x%0*" PRIxPTR "\n", ++ PRIxPTR_WIDTH, *start, *len, PRIxPTR_WIDTH, *start + *len); ++ return old_start - *start; ++} ++ ++struct undo_physmap_data { ++ void *virt_addr; ++ size_t len; ++}; ++ ++static int undo_physmap(void *data) ++{ ++ if (data == NULL) { ++ msg_perr("%s: tried to physunmap without valid data!\n", __func__); ++ return 1; ++ } ++ struct undo_physmap_data *d = data; ++ physunmap_unaligned(d->virt_addr, d->len); ++ free(data); ++ return 0; ++} + +-static void *physmap_common(const char *descr, uintptr_t phys_addr, +- size_t len, int mayfail, int readonly) ++static void *physmap_common(const char *descr, uintptr_t phys_addr, size_t len, bool readonly, bool autocleanup, ++ bool round) + { + void *virt_addr; ++ uintptr_t offset = 0; + + if (len == 0) { + msg_pspew("Not mapping %s, zero size at 0x%0*" PRIxPTR ".\n", descr, PRIxPTR_WIDTH, phys_addr); + return ERROR_PTR; + } + +- if ((getpagesize() - 1) & len) { +- msg_perr("Mapping %s at 0x%0*" PRIxPTR ", unaligned size 0x%zx.\n", +- descr, PRIxPTR_WIDTH, phys_addr, len); +- } +- +- if ((getpagesize() - 1) & phys_addr) { +- msg_perr("Mapping %s, 0x%zx bytes at unaligned 0x%0*" PRIxPTR ".\n", +- descr, len, PRIxPTR_WIDTH, phys_addr); +- } ++ if (round) ++ offset = round_to_page_boundaries(&phys_addr, &len); + + if (readonly) + virt_addr = sys_physmap_ro_cached(phys_addr, len); +@@ -253,23 +281,89 @@ static void *physmap_common(const char *descr, uintptr_t phys_addr, + "and reboot, or reboot into\n" + "single user mode.\n"); + #endif +- if (!mayfail) +- exit(3); ++ return ERROR_PTR; + } + +- return virt_addr; ++ if (autocleanup) { ++ struct undo_physmap_data *d = malloc(sizeof(struct undo_physmap_data)); ++ if (d == NULL) { ++ msg_perr("%s: Out of memory!\n", __func__); ++ physunmap_unaligned(virt_addr, len); ++ return ERROR_PTR; ++ } ++ ++ d->virt_addr = virt_addr; ++ d->len = len; ++ if (register_shutdown(undo_physmap, d) != 0) { ++ msg_perr("%s: Could not register shutdown function!\n", __func__); ++ physunmap_unaligned(virt_addr, len); ++ return ERROR_PTR; ++ } ++ } ++ ++ return virt_addr + offset; ++} ++ ++void physunmap_unaligned(void *virt_addr, size_t len) ++{ ++ /* No need to check for zero size, such mappings would have yielded ERROR_PTR. */ ++ if (virt_addr == ERROR_PTR) { ++#ifndef FORCE10_SPI_CHANGE ++ msg_perr("Trying to unmap a nonexisting mapping!\n" ++ "Please report a bug at flashrom@flashrom.org\n"); ++#else ++ msg_pdbg("Trying to unmap a nonexisting mapping!\n" ++ "Please report a bug at flashrom@flashrom.org\n"); ++#endif ++ return; ++ } ++ ++ sys_physunmap_unaligned(virt_addr, len); ++} ++ ++void physunmap(void *virt_addr, size_t len) ++{ ++ uintptr_t tmp; ++ ++ /* No need to check for zero size, such mappings would have yielded ERROR_PTR. */ ++ if (virt_addr == ERROR_PTR) { ++#ifndef FORCE10_SPI_CHANGE ++ msg_perr("Trying to unmap a nonexisting mapping!\n" ++ "Please report a bug at flashrom@flashrom.org\n"); ++#else ++ msg_pdbg("Trying to unmap a nonexisting mapping!\n" ++ "Please report a bug at flashrom@flashrom.org\n"); ++#endif ++ return; ++ } ++ tmp = (uintptr_t)virt_addr; ++ /* We assume that the virtual address of a page-aligned physical address is page-aligned as well. By ++ * extension, rounding a virtual unaligned address as returned by physmap should yield the same offset ++ * between rounded and original virtual address as between rounded and original physical address. ++ */ ++ round_to_page_boundaries(&tmp, &len); ++ virt_addr = (void *)tmp; ++ physunmap_unaligned(virt_addr, len); + } + + void *physmap(const char *descr, uintptr_t phys_addr, size_t len) + { +- return physmap_common(descr, phys_addr, len, PHYSMAP_NOFAIL, +- PHYSMAP_RW); ++ return physmap_common(descr, phys_addr, len, PHYSM_RW, PHYSM_NOCLEANUP, PHYSM_ROUND); ++} ++ ++void *rphysmap(const char *descr, uintptr_t phys_addr, size_t len) ++{ ++ return physmap_common(descr, phys_addr, len, PHYSM_RW, PHYSM_CLEANUP, PHYSM_ROUND); ++} ++ ++void *physmap_ro(const char *descr, uintptr_t phys_addr, size_t len) ++{ ++ return physmap_common(descr, phys_addr, len, PHYSM_RO, PHYSM_NOCLEANUP, PHYSM_ROUND); + } + +-void *physmap_try_ro(const char *descr, uintptr_t phys_addr, size_t len) ++void *physmap_ro_unaligned(const char *descr, uintptr_t phys_addr, size_t len) + { +- return physmap_common(descr, phys_addr, len, PHYSMAP_MAYFAIL, +- PHYSMAP_RO); ++ return physmap_common(descr, phys_addr, len, PHYSM_RO, PHYSM_NOCLEANUP, PHYSM_EXACT); + } + + /* MSR abstraction implementations for Linux, OpenBSD, FreeBSD/Dragonfly, OSX, libpayload +diff --git a/pony_spi.c b/pony_spi.c +index 101751f..2a3666f 100644 +--- a/pony_spi.c ++++ b/pony_spi.c +@@ -140,6 +140,7 @@ int pony_spi_init(void) + } else if (arg && !strlen(arg)) { + msg_perr("Error: Missing argument for programmer type.\n"); + free(arg); ++ return 1; + } else if (arg){ + msg_perr("Error: Invalid programmer type specified.\n"); + free(arg); +diff --git a/print.c b/print.c +index 6766eeb..6d2921b 100644 +--- a/print.c ++++ b/print.c +@@ -436,12 +436,13 @@ static void print_supported_boards_helper(const struct board_info *boards, + msg_ginfo("%s", b->name); + for (i = 0; i < maxboardlen - strlen(b->name); i++) + msg_ginfo(" "); +- if (b->working == OK) +- msg_ginfo("OK "); +- else if (b->working == NT) +- msg_ginfo("NT "); +- else +- msg_ginfo("BAD "); ++ ++ if (b->working == OK) ++ msg_ginfo("OK "); ++ else if (b->working == NT) ++ msg_ginfo("NT "); ++ else ++ msg_ginfo("BAD "); + + for (e = board_matches; e->vendor_name != NULL; e++) { + if (strcmp(e->vendor_name, b->vendor) +@@ -530,6 +531,7 @@ const struct board_info boards_known[] = { + B("abit", "AN-M2", OK, NULL, NULL), + B("abit", "AV8", OK, NULL, NULL), + B("abit", "AX8", OK, NULL, NULL), ++ B("abit", "BF6", OK, NULL, NULL), + B("abit", "BM6", OK, NULL, NULL), + B("abit", "Fatal1ty F-I90HD", OK, NULL, NULL), + B("abit", "IC7", OK, NULL, NULL), +@@ -695,6 +697,7 @@ const struct board_info boards_known[] = { + B("ASUS", "P5L-VM 1394", OK, "http://www.asus.com/Motherboards/Intel_Socket_775/P5LVM_1394/", NULL), + B("ASUS", "P5LD2", NT, NULL, "Untested board enable."), + B("ASUS", "P5LD2-VM", NT, "http://www.asus.com/Motherboards/Intel_Socket_775/P5LD2VM/", "Untested board enable."), ++ B("ASUS", "P5LD2-VM DH", OK, "http://www.asus.com/Motherboards/Intel_Socket_775/P5LD2VM_DH/", NULL), + B("ASUS", "P5LP-LE (Lithium-UL8E)", OK, "http://h10025.www1.hp.com/ewfrf/wc/document?docname=c00379616&tmp_task=prodinfoCategory&cc=us&dlc=en&lc=en&product=1159887", "This is an OEM board from HP."), + B("ASUS", "P5LP-LE (Epson OEM)", OK, NULL, "This is an OEM board from Epson (e.g. Endeavor MT7700)."), + B("ASUS", "P5LP-LE", NT, NULL, "This designation is used for OEM boards from HP, Epson and maybe others. The HP names vary and not all of them have been tested yet. Please report any success or failure, thanks."), +diff --git a/programmer.h b/programmer.h +index 4db8d58..d3cc557 100644 +--- a/programmer.h ++++ b/programmer.h +@@ -276,8 +276,11 @@ int processor_flash_enable(void); + + /* physmap.c */ + void *physmap(const char *descr, uintptr_t phys_addr, size_t len); +-void *physmap_try_ro(const char *descr, uintptr_t phys_addr, size_t len); ++void *rphysmap(const char *descr, uintptr_t phys_addr, size_t len); ++void *physmap_ro(const char *descr, uintptr_t phys_addr, size_t len); ++void *physmap_ro_unaligned(const char *descr, uintptr_t phys_addr, size_t len); + void physunmap(void *virt_addr, size_t len); ++void physunmap_unaligned(void *virt_addr, size_t len); + #if CONFIG_INTERNAL == 1 + int setup_cpu_msr(int cpu); + void cleanup_cpu_msr(void); +@@ -287,9 +290,11 @@ int cb_parse_table(const char **vendor, const char **model); + int cb_check_image(uint8_t *bios, int size); + + /* dmi.c */ ++#if defined(__i386__) || defined(__x86_64__) + extern int has_dmi_support; + void dmi_init(void); + int dmi_match(const char *pattern); ++#endif // defined(__i386__) || defined(__x86_64__) + + /* internal.c */ + struct superio { +@@ -550,10 +555,19 @@ int default_spi_write_256(struct flashctx *flash, uint8_t *buf, unsigned int sta + int default_spi_write_aai(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); + int register_spi_programmer(const struct spi_programmer *programmer); + +-/* The following enum is needed by ich_descriptor_tool and ich* code. */ ++/* The following enum is needed by ich_descriptor_tool and ich* code as well as in chipset_enable.c. */ + enum ich_chipset { + CHIPSET_ICH_UNKNOWN, +- CHIPSET_ICH7 = 7, ++#ifdef DELL_AVOTON_SUPPORT ++ CHIPSET_AVOTON, ++#endif ++ CHIPSET_ICH, ++ CHIPSET_ICH2345, ++ CHIPSET_ICH6, ++ CHIPSET_POULSBO, /* SCH U* */ ++ CHIPSET_TUNNEL_CREEK, /* Atom E6xx */ ++ CHIPSET_CENTERTON, /* Atom S1220 S1240 S1260 */ ++ CHIPSET_ICH7, + CHIPSET_ICH8, + CHIPSET_ICH9, + CHIPSET_ICH10, +@@ -563,13 +577,15 @@ enum ich_chipset { + CHIPSET_8_SERIES_LYNX_POINT, + CHIPSET_8_SERIES_LYNX_POINT_LP, + CHIPSET_8_SERIES_WELLSBURG, ++#if DELL_DENVERTON_SUPPORT == 1 ++ CHIPSET_DENVERTON, ++#endif /* #if DELL_DENVERTON_SUPPORT == 1 */ + }; + + /* ichspi.c */ + #if CONFIG_INTERNAL == 1 + extern uint32_t ichspi_bbar; +-int ich_init_spi(struct pci_dev *dev, uint32_t base, void *rcrb, +- enum ich_chipset ich_generation); ++int ich_init_spi(struct pci_dev *dev, void *spibar, enum ich_chipset ich_generation); + int via_init_spi(struct pci_dev *dev, uint32_t mmio_base); + + /* amd_imc.c */ +@@ -659,7 +675,7 @@ typedef int fdtype; + + void sp_flush_incoming(void); + fdtype sp_openserport(char *dev, unsigned int baud); +-void __attribute__((noreturn)) sp_die(char *msg); ++int serialport_config(fdtype fd, unsigned int baud); + extern fdtype sp_fd; + /* expose serialport_shutdown as it's currently used by buspirate */ + int serialport_shutdown(void *data); +diff --git a/rayer_spi.c b/rayer_spi.c +index b312610..189341a 100644 +--- a/rayer_spi.c ++++ b/rayer_spi.c +@@ -17,11 +17,9 @@ + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +-/* Driver for the SPIPGM hardware by "RayeR" Martin Rehak. +- * See http://rayer.ic.cz/elektro/spipgm.htm for schematics and instructions. +- */ +- +-/* This driver uses non-portable direct I/O port accesses which won't work on ++/* Driver for various LPT adapters. ++ * ++ * This driver uses non-portable direct I/O port accesses which won't work on + * any non-x86 platform, and even on x86 there is a high chance there will be + * collisions with any loaded parallel port drivers. + * The big advantage of direct port I/O is OS independence and speed because +@@ -37,21 +35,87 @@ + #include "programmer.h" + #include "hwaccess.h" + +-enum rayer_type { +- TYPE_RAYER, +- TYPE_XILINX_DLC5, +-}; +- + /* We have two sets of pins, out and in. The numbers for both sets are + * independent and are bitshift values, not real pin numbers. + * Default settings are for the RayeR hardware. + */ +-/* Pins for master->slave direction */ +-static int rayer_cs_bit = 5; +-static int rayer_sck_bit = 6; +-static int rayer_mosi_bit = 7; +-/* Pins for slave->master direction */ +-static int rayer_miso_bit = 6; ++ ++struct rayer_programmer { ++ const char *type; ++ const enum test_state status; ++ const char *description; ++ const void *dev_data; ++}; ++ ++struct rayer_pinout { ++ uint8_t cs_bit; ++ uint8_t sck_bit; ++ uint8_t mosi_bit; ++ uint8_t miso_bit; ++ void (*preinit)(const void *); ++ int (*shutdown)(void *); ++}; ++ ++static const struct rayer_pinout rayer_spipgm = { ++ .cs_bit = 5, ++ .sck_bit = 6, ++ .mosi_bit = 7, ++ .miso_bit = 6, ++}; ++ ++static void dlc5_preinit(const void *); ++static int dlc5_shutdown(void *); ++ ++static const struct rayer_pinout xilinx_dlc5 = { ++ .cs_bit = 2, ++ .sck_bit = 1, ++ .mosi_bit = 0, ++ .miso_bit = 4, ++ .preinit = dlc5_preinit, ++ .shutdown = dlc5_shutdown, ++}; ++ ++static void byteblaster_preinit(const void *); ++static int byteblaster_shutdown(void *); ++ ++static const struct rayer_pinout altera_byteblastermv = { ++ .cs_bit = 1, ++ .sck_bit = 0, ++ .mosi_bit = 6, ++ .miso_bit = 7, ++ .preinit = byteblaster_preinit, ++ .shutdown = byteblaster_shutdown, ++}; ++ ++static void stk200_preinit(const void *); ++static int stk200_shutdown(void *); ++ ++static const struct rayer_pinout atmel_stk200 = { ++ .cs_bit = 7, ++ .sck_bit = 4, ++ .mosi_bit = 5, ++ .miso_bit = 6, ++ .preinit = stk200_preinit, ++ .shutdown = stk200_shutdown, ++}; ++ ++static const struct rayer_pinout wiggler_lpt = { ++ .cs_bit = 1, ++ .sck_bit = 2, ++ .mosi_bit = 3, ++ .miso_bit = 7, ++}; ++ ++static const struct rayer_programmer rayer_spi_types[] = { ++ {"rayer", NT, "RayeR SPIPGM", &rayer_spipgm}, ++ {"xilinx", NT, "Xilinx Parallel Cable III (DLC 5)", &xilinx_dlc5}, ++ {"byteblastermv", OK, "Altera ByteBlasterMV", &altera_byteblastermv}, ++ {"stk200", NT, "Atmel STK200/300 adapter", &atmel_stk200}, ++ {"wiggler", OK, "Wiggler LPT", &wiggler_lpt}, ++ {0}, ++}; ++ ++static const struct rayer_pinout *pinout = NULL; + + static uint16_t lpt_iobase; + +@@ -60,22 +124,22 @@ static uint8_t lpt_outbyte; + + static void rayer_bitbang_set_cs(int val) + { +- lpt_outbyte &= ~(1 << rayer_cs_bit); +- lpt_outbyte |= (val << rayer_cs_bit); ++ lpt_outbyte &= ~(1 << pinout->cs_bit); ++ lpt_outbyte |= (val << pinout->cs_bit); + OUTB(lpt_outbyte, lpt_iobase); + } + + static void rayer_bitbang_set_sck(int val) + { +- lpt_outbyte &= ~(1 << rayer_sck_bit); +- lpt_outbyte |= (val << rayer_sck_bit); ++ lpt_outbyte &= ~(1 << pinout->sck_bit); ++ lpt_outbyte |= (val << pinout->sck_bit); + OUTB(lpt_outbyte, lpt_iobase); + } + + static void rayer_bitbang_set_mosi(int val) + { +- lpt_outbyte &= ~(1 << rayer_mosi_bit); +- lpt_outbyte |= (val << rayer_mosi_bit); ++ lpt_outbyte &= ~(1 << pinout->mosi_bit); ++ lpt_outbyte |= (val << pinout->mosi_bit); + OUTB(lpt_outbyte, lpt_iobase); + } + +@@ -83,8 +147,8 @@ static int rayer_bitbang_get_miso(void) + { + uint8_t tmp; + +- tmp = INB(lpt_iobase + 1); +- tmp = (tmp >> rayer_miso_bit) & 0x1; ++ tmp = INB(lpt_iobase + 1) ^ 0x80; // bit.7 inverted ++ tmp = (tmp >> pinout->miso_bit) & 0x1; + return tmp; + } + +@@ -99,8 +163,8 @@ static const struct bitbang_spi_master bitbang_spi_master_rayer = { + + int rayer_spi_init(void) + { ++ const struct rayer_programmer *prog = rayer_spi_types; + char *arg = NULL; +- enum rayer_type rayer_type = TYPE_RAYER; + + /* Non-default port requested? */ + arg = extract_programmer_param("iobase"); +@@ -138,36 +202,20 @@ int rayer_spi_init(void) + + arg = extract_programmer_param("type"); + if (arg) { +- if (!strcasecmp(arg, "rayer")) { +- rayer_type = TYPE_RAYER; +- } else if (!strcasecmp(arg, "xilinx")) { +- rayer_type = TYPE_XILINX_DLC5; +- } else { ++ for (; prog->type != NULL; prog++) { ++ if (strcasecmp(arg, prog->type) == 0) { ++ break; ++ } ++ } ++ if (prog->type == NULL) { + msg_perr("Error: Invalid device type specified.\n"); + free(arg); + return 1; + } ++ free(arg); + } +- free(arg); +- switch (rayer_type) { +- case TYPE_RAYER: +- msg_pdbg("Using RayeR SPIPGM pinout.\n"); +- /* Bits for master->slave direction */ +- rayer_cs_bit = 5; +- rayer_sck_bit = 6; +- rayer_mosi_bit = 7; +- /* Bits for slave->master direction */ +- rayer_miso_bit = 6; +- break; +- case TYPE_XILINX_DLC5: +- msg_pdbg("Using Xilinx Parallel Cable III (DLC 5) pinout.\n"); +- /* Bits for master->slave direction */ +- rayer_cs_bit = 2; +- rayer_sck_bit = 1; +- rayer_mosi_bit = 0; +- /* Bits for slave->master direction */ +- rayer_miso_bit = 4; +- } ++ msg_pinfo("Using %s pinout.\n", prog->description); ++ pinout = (struct rayer_pinout *)prog->dev_data; + + if (rget_io_perms()) + return 1; +@@ -175,12 +223,60 @@ int rayer_spi_init(void) + /* Get the initial value before writing to any line. */ + lpt_outbyte = INB(lpt_iobase); + ++ if (pinout->shutdown) ++ register_shutdown(pinout->shutdown, (void*)pinout); ++ if (pinout->preinit) ++ pinout->preinit(pinout); ++ + if (bitbang_spi_init(&bitbang_spi_master_rayer)) + return 1; + + return 0; + } + ++static void byteblaster_preinit(const void *data){ ++ msg_pdbg("byteblaster_preinit\n"); ++ /* Assert #EN signal. */ ++ OUTB(2, lpt_iobase + 2 ); ++} ++ ++static int byteblaster_shutdown(void *data){ ++ msg_pdbg("byteblaster_shutdown\n"); ++ /* De-Assert #EN signal. */ ++ OUTB(0, lpt_iobase + 2 ); ++ return 0; ++} ++ ++static void stk200_preinit(const void *data) { ++ msg_pdbg("stk200_init\n"); ++ /* Assert #EN signals, set LED signal. */ ++ lpt_outbyte = (1 << 6) ; ++ OUTB(lpt_outbyte, lpt_iobase); ++} ++ ++static int stk200_shutdown(void *data) { ++ msg_pdbg("stk200_shutdown\n"); ++ /* Assert #EN signals, clear LED signal. */ ++ lpt_outbyte = (1 << 2) | (1 << 3); ++ OUTB(lpt_outbyte, lpt_iobase); ++ return 0; ++} ++ ++static void dlc5_preinit(const void *data) { ++ msg_pdbg("dlc5_preinit\n"); ++ /* Assert pin 6 to receive MISO. */ ++ lpt_outbyte |= (1<<4); ++ OUTB(lpt_outbyte, lpt_iobase); ++} ++ ++static int dlc5_shutdown(void *data) { ++ msg_pdbg("dlc5_shutdown\n"); ++ /* De-assert pin 6 to force MISO low. */ ++ lpt_outbyte &= ~(1<<4); ++ OUTB(lpt_outbyte, lpt_iobase); ++ return 0; ++} ++ + #else + #error PCI port I/O access is not supported on this architecture yet. + #endif +diff --git a/satamv.c b/satamv.c +index c3f27e7..e03508e 100644 +--- a/satamv.c ++++ b/satamv.c +@@ -57,12 +57,6 @@ static const struct par_programmer par_programmer_satamv = { + .chip_writen = fallback_chip_writen, + }; + +-static int satamv_shutdown(void *data) +-{ +- physunmap(mv_bar, 0x20000); +- return 0; +-} +- + /* + * Random notes: + * FCE# Flash Chip Enable +@@ -94,11 +88,11 @@ int satamv_init(void) + return 1; + + addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0); +- mv_bar = physmap("Marvell 88SX7042 registers", addr, 0x20000); +- if (mv_bar == ERROR_PTR) ++ if (!addr) + return 1; + +- if (register_shutdown(satamv_shutdown, NULL)) ++ mv_bar = rphysmap("Marvell 88SX7042 registers", addr, 0x20000); ++ if (mv_bar == ERROR_PTR) + return 1; + + tmp = pci_mmio_readl(mv_bar + FLASH_PARAM); +@@ -144,12 +138,15 @@ int satamv_init(void) + pci_rmmio_writel(tmp, mv_bar + GPIO_PORT_CONTROL); + + /* Get I/O BAR location. */ +- tmp = pcidev_readbar(dev, PCI_BASE_ADDRESS_2); ++ addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_2); ++ if (!addr) ++ return 1; ++ + /* Truncate to reachable range. + * FIXME: Check if the I/O BAR is actually reachable. + * This is an arch specific check. + */ +- mv_iobar = tmp & 0xffff; ++ mv_iobar = addr & 0xffff; + msg_pspew("Activating I/O BAR at 0x%04x\n", mv_iobar); + + /* 512 kByte with two 8-bit latches, and +diff --git a/satasii.c b/satasii.c +index 72e35e5..83dc62c 100644 +--- a/satasii.c ++++ b/satasii.c +@@ -54,12 +54,6 @@ static const struct par_programmer par_programmer_satasii = { + .chip_writen = fallback_chip_writen, + }; + +-static int satasii_shutdown(void *data) +-{ +- physunmap(sii_bar, SATASII_MEMMAP_SIZE); +- return 0; +-} +- + static uint32_t satasii_wait_done(void) + { + uint32_t ctrl_reg; +@@ -91,21 +85,25 @@ int satasii_init(void) + + if ((id == 0x3132) || (id == 0x3124)) { + addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0); ++ if (!addr) ++ return 1; + reg_offset = 0x70; + } else { + addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_5); ++ if (!addr) ++ return 1; + reg_offset = 0x50; + } + +- sii_bar = physmap("SATA SiI registers", addr, SATASII_MEMMAP_SIZE) + reg_offset; ++ sii_bar = rphysmap("SATA SiI registers", addr, SATASII_MEMMAP_SIZE); ++ if (sii_bar == ERROR_PTR) ++ return 1; ++ sii_bar += reg_offset; + + /* Check if ROM cycle are OK. */ + if ((id != 0x0680) && (!(pci_mmio_readl(sii_bar) & (1 << 26)))) + msg_pwarn("Warning: Flash seems unconnected.\n"); + +- if (register_shutdown(satasii_shutdown, NULL)) +- return 1; +- + register_par_programmer(&par_programmer_satasii, BUS_PARALLEL); + + return 0; +diff --git a/sb600spi.c b/sb600spi.c +index cb7c4ac..9523591 100644 +--- a/sb600spi.c ++++ b/sb600spi.c +@@ -57,7 +57,28 @@ static enum amd_chipset amd_gen = CHIPSET_AMD_UNKNOWN; + static void determine_generation(struct pci_dev *dev) + { + amd_gen = CHIPSET_AMD_UNKNOWN; +- if (dev->device_id == 0x780e) { ++ msg_pdbg2("Trying to determine the generation of the SPI interface... "); ++ if (dev->device_id == 0x438d) { ++ amd_gen = CHIPSET_SB6XX; ++ msg_pdbg("SB6xx detected.\n"); ++ } else if (dev->device_id == 0x439d) { ++ struct pci_dev *smbus_dev = pci_dev_find(0x1002, 0x4385); ++ if (smbus_dev == NULL) ++ return; ++ uint8_t rev = pci_read_byte(smbus_dev, PCI_REVISION_ID); ++ if (rev >= 0x39 && rev <= 0x3D) { ++ amd_gen = CHIPSET_SB7XX; ++ msg_pdbg("SB7xx/SP5100 detected.\n"); ++ } else if (rev >= 0x40 && rev <= 0x42) { ++ amd_gen = CHIPSET_SB89XX; ++ msg_pdbg("SB8xx/SB9xx/Hudson-1 detected.\n"); ++ } else { ++ msg_pwarn("SB device found but SMBus revision 0x%02x does not match known values.\n" ++ "Assuming SB8xx/SB9xx/Hudson-1. Please send a log to flashrom@flashrom.org\n", ++ rev); ++ amd_gen = CHIPSET_SB89XX; ++ } ++ } else if (dev->device_id == 0x780e) { + /* The PCI ID of the LPC bridge doesn't change between Hudson-2/3/4 and Yangtze (Kabini/Temash) + * although they use different SPI interfaces. */ + #ifdef USE_YANGTZE_HEURISTICS +@@ -94,7 +115,11 @@ static void determine_generation(struct pci_dev *dev) + "the output of lspci -nnvx, thanks!.\n", rev); + } + #endif +- } ++ } else ++ msg_pwarn("%s: Unknown LPC device %" PRIx16 ":%" PRIx16 ".\n" ++ "Please report this to flashrom@flashrom.org and include this log and\n" ++ "the output of lspci -nnvx, thanks!\n", ++ __func__, dev->vendor_id, dev->device_id); + } + + static void reset_internal_fifo_pointer(void) +@@ -247,10 +272,66 @@ static int sb600_spi_send_command(struct flashctx *flash, unsigned int writecnt, + return 0; + } + ++struct spispeed { ++ const char *const name; ++ const uint8_t speed; ++}; ++ ++static const struct spispeed spispeeds[] = { ++ { "66 MHz", 0x00 }, ++ { "33 MHz", 0x01 }, ++ { "22 MHz", 0x02 }, ++ { "16.5 MHz", 0x03 }, ++}; ++ ++static int set_speed(struct pci_dev *dev, const struct spispeed *spispeed) ++{ ++ bool success = false; ++ uint8_t speed = spispeed->speed; ++ ++ msg_pdbg("Setting SPI clock to %s (0x%x).\n", spispeed->name, speed); ++ if (amd_gen != CHIPSET_YANGTZE) { ++ rmmio_writeb((mmio_readb(sb600_spibar + 0xd) & ~(0x3 << 4)) | (speed << 4), sb600_spibar + 0xd); ++ success = (speed == ((mmio_readb(sb600_spibar + 0xd) >> 4) & 0x3)); ++ } ++ ++ if (!success) { ++ msg_perr("Setting SPI clock failed.\n"); ++ return 1; ++ } ++ return 0; ++} ++ ++static int handle_speed(struct pci_dev *dev) ++{ ++ uint32_t tmp; ++ int8_t spispeed_idx = 3; /* Default to 16.5 MHz */ ++ ++ /* See the chipset support matrix for SPI Base_Addr below for an explanation of the symbols used. ++ * bit 6xx 7xx/SP5100 8xx 9xx hudson1 hudson234 yangtze ++ * 18 rsvd <- fastReadEnable ? <- ? SpiReadMode[0] ++ * 29:30 rsvd <- <- ? <- ? SpiReadMode[2:1] ++ */ ++ if (amd_gen != CHIPSET_YANGTZE) { ++ if (amd_gen >= CHIPSET_SB89XX && amd_gen <= CHIPSET_HUDSON234) { ++ bool fast_read = (mmio_readl(sb600_spibar + 0x00) >> 18) & 0x1; ++ msg_pdbg("Fast Reads are %sabled\n", fast_read ? "en" : "dis"); ++ if (fast_read) { ++ msg_pdbg("Disabling them temporarily.\n"); ++ rmmio_writel(mmio_readl(sb600_spibar + 0x00) & ~(0x1 << 18), ++ sb600_spibar + 0x00); ++ } ++ } ++ tmp = (mmio_readb(sb600_spibar + 0xd) >> 4) & 0x3; ++ msg_pdbg("NormSpeed is %s\n", spispeeds[tmp].name); ++ } ++ return set_speed(dev, &spispeeds[spispeed_idx]); ++} ++ + static int sb600_handle_imc(struct pci_dev *dev, bool amd_imc_force) + { + /* Handle IMC everywhere but sb600 which does not have one. */ +- if (dev->device_id == 0x438d) ++ if (amd_gen == CHIPSET_SB6XX) + return 0; + + /* TODO: we should not only look at IntegratedImcPresent (LPC Dev 20, Func 3, 40h) but also at +@@ -297,9 +378,6 @@ int sb600_probe_spi(struct pci_dev *dev) + uint32_t tmp; + uint8_t reg; + bool amd_imc_force = false; +- static const char *const speed_names[4] = { +- "66/reserved", "33", "22", "16.5" +- }; + + char *arg = extract_programmer_param("amd_imc_force"); + if (arg && !strcmp(arg, "yes")) { +@@ -326,14 +404,20 @@ int sb600_probe_spi(struct pci_dev *dev) + return 0; + + /* Physical memory has to be mapped at page (4k) boundaries. */ +- sb600_spibar = physmap("SB600 SPI registers", tmp & 0xfffff000, +- 0x1000); ++ sb600_spibar = rphysmap("SB600 SPI registers", tmp & 0xfffff000, 0x1000); ++ if (sb600_spibar == ERROR_PTR) ++ return ERROR_FATAL; ++ + /* The low bits of the SPI base address are used as offset into + * the mapped page. + */ + sb600_spibar += tmp & 0xfff; + + determine_generation(dev); ++ if (amd_gen == CHIPSET_AMD_UNKNOWN) { ++ msg_perr("Could not determine chipset generation."); ++ return ERROR_NONFATAL; ++ } + + if (amd_gen == CHIPSET_YANGTZE) { + msg_perr("SPI on Kabini/Temash and newer chipsets are not yet supported.\n" +@@ -341,34 +425,87 @@ int sb600_probe_spi(struct pci_dev *dev) + return ERROR_NONFATAL; + } + +- tmp = pci_read_long(dev, 0xa0); +- msg_pdbg("AltSpiCSEnable=%i, SpiRomEnable=%i, " +- "AbortEnable=%i\n", tmp & 0x1, (tmp & 0x2) >> 1, +- (tmp & 0x4) >> 2); +- tmp = (pci_read_byte(dev, 0xba) & 0x4) >> 2; +- msg_pdbg("PrefetchEnSPIFromIMC=%i, ", tmp); +- +- tmp = pci_read_byte(dev, 0xbb); +- /* FIXME: Set bit 3,6,7 if not already set. +- * Set bit 5, otherwise SPI accesses are pointless in LPC mode. +- * See doc 42413 AMD SB700/710/750 RPR. ++ /* How to read the following table and similar ones in this file: ++ * "?" means we have no datasheet for this chipset generation or it doesn't have any relevant info. ++ * "<-" means the bit/register meaning is identical to the next non-"?" chipset to the left. "<-" thus ++ * never refers to another "?". ++ * If a "?" chipset is between two chipsets with identical meaning, we assume the meaning didn't change ++ * twice in between, i.e. the meaning is unchanged for the "?" chipset. Usually we assume that ++ * succeeding hardware supports the same functionality as its predecessor unless proven different by ++ * tests or documentation, hence "?" will often be implemented equally to "<-". ++ * ++ * Chipset support matrix for SPI Base_Addr (LPC PCI reg 0xa0) ++ * bit 6xx 7xx/SP5100 8xx 9xx hudson1 hudson2+ yangtze ++ * 3 rsvd <- <- ? <- ? RouteTpm2Spi ++ * 2 rsvd AbortEnable rsvd ? <- ? <- ++ * 1 rsvd SpiRomEnable <- ? <- ? <- ++ * 0 rsvd AltSpiCSEnable rsvd ? <- ? <- + */ +- msg_pdbg("PrefetchEnSPIFromHost=%i, SpiOpEnInLpcMode=%i\n", +- tmp & 0x1, (tmp & 0x20) >> 5); +- tmp = mmio_readl(sb600_spibar); +- /* FIXME: If SpiAccessMacRomEn or SpiHostAccessRomEn are zero on +- * SB700 or later, reads and writes will be corrupted. Abort in this +- * case. Make sure to avoid this check on SB600. ++ if (amd_gen >= CHIPSET_SB7XX) { ++ tmp = pci_read_long(dev, 0xa0); ++ msg_pdbg("SpiRomEnable=%i", (tmp >> 1) & 0x1); ++ if (amd_gen == CHIPSET_SB7XX) ++ msg_pdbg(", AltSpiCSEnable=%i, AbortEnable=%i", tmp & 0x1, (tmp >> 2) & 0x1); ++ ++ tmp = pci_read_byte(dev, 0xba); ++ msg_pdbg(", PrefetchEnSPIFromIMC=%i", (tmp & 0x4) >> 2); ++ ++ tmp = pci_read_byte(dev, 0xbb); ++ /* FIXME: Set bit 3,6,7 if not already set. ++ * Set bit 5, otherwise SPI accesses are pointless in LPC mode. ++ * See doc 42413 AMD SB700/710/750 RPR. ++ */ ++ if (amd_gen == CHIPSET_SB7XX) ++ msg_pdbg(", SpiOpEnInLpcMode=%i", (tmp >> 5) & 0x1); ++ msg_pdbg(", PrefetchEnSPIFromHost=%i\n", tmp & 0x1); ++ } ++ ++ /* Chipset support matrix for SPI_Cntrl0 (spibar + 0x0) ++ * See the chipset support matrix for SPI Base_Addr above for an explanation of the symbols used. ++ * bit 6xx 7xx/SP5100 8xx 9xx hudson1 hudson2+ yangtze ++ * 17 rsvd <- <- ? <- ? <- ++ * 18 rsvd <- fastReadEnable<1> ? <- ? SpiReadMode[0]<1> ++ * 19 SpiArbEnable <- <- ? <- ? <- ++ * 20 (FifoPtrClr) <- <- ? <- ? <- ++ * 21 (FifoPtrInc) <- <- ? <- ? IllegalAccess ++ * 22 SpiAccessMacRomEn <- <- ? <- ? <- ++ * 23 SpiHostAccessRomEn <- <- ? <- ? <- ++ * 24:26 ArbWaitCount <- <- ? <- ? <- ++ * 27 SpiBridgeDisable <- <- ? <- ? rsvd ++ * 28 rsvd DropOneClkOnRd = SPIClkGate ? <- ? <- ++ * 29:30 rsvd <- <- ? <- ? SpiReadMode[2:1]<1> ++ * 31 rsvd <- SpiBusy ? <- ? <- ++ * ++ * <1> see handle_speed + */ +- msg_pdbg("(0x%08" PRIx32 ") fastReadEnable=%u, SpiArbEnable=%i, SpiAccessMacRomEn=%i, " +- "SpiHostAccessRomEn=%i, ArbWaitCount=%i, " +- "SpiBridgeDisable=%i, DropOneClkOnRd=%i\n", +- tmp, (tmp >> 18) & 0x1, +- (tmp >> 19) & 0x1, (tmp >> 22) & 0x1, +- (tmp >> 23) & 0x1, (tmp >> 24) & 0x7, +- (tmp >> 27) & 0x1, (tmp >> 28) & 0x1); +- tmp = (mmio_readb(sb600_spibar + 0xd) >> 4) & 0x3; +- msg_pdbg("NormSpeed is %s MHz\n", speed_names[tmp]); ++ tmp = mmio_readl(sb600_spibar + 0x00); ++ msg_pdbg("(0x%08" PRIx32 ") SpiArbEnable=%i", tmp, (tmp >> 19) & 0x1); ++ ++ msg_pdbg(", SpiAccessMacRomEn=%i, SpiHostAccessRomEn=%i, ArbWaitCount=%i", ++ (tmp >> 22) & 0x1, (tmp >> 23) & 0x1, (tmp >> 24) & 0x7); ++ ++ if (amd_gen != CHIPSET_YANGTZE) ++ msg_pdbg(", SpiBridgeDisable=%i", (tmp >> 27) & 0x1); ++ ++ switch (amd_gen) { ++ case CHIPSET_SB7XX: ++ msg_pdbg(", DropOneClkOnRd/SpiClkGate=%i", (tmp >> 28) & 0x1); ++ case CHIPSET_SB89XX: ++ case CHIPSET_HUDSON234: ++ msg_pdbg(", SpiBusy=%i", (tmp >> 31) & 0x1); ++ default: break; ++ } ++ msg_pdbg("\n"); ++ ++ if (((tmp >> 22) & 0x1) == 0 || ((tmp >> 23) & 0x1) == 0) { ++ msg_perr("ERROR: State of SpiAccessMacRomEn or SpiHostAccessRomEn prohibits full access.\n"); ++ return ERROR_NONFATAL; ++ } ++ ++ if (amd_gen >= CHIPSET_SB89XX) { ++ tmp = mmio_readb(sb600_spibar + 0x1D); ++ msg_pdbg("Using SPI_CS%d\n", tmp & 0x3); ++ } + + /* Look for the SMBus device. */ + smbus_dev = pci_dev_find(0x1002, 0x4385); +@@ -409,6 +546,9 @@ int sb600_probe_spi(struct pci_dev *dev) + return 0; + } + ++ if (handle_speed(dev) != 0) ++ return ERROR_FATAL; ++ + if (sb600_handle_imc(dev, amd_imc_force) != 0) + return ERROR_FATAL; + +diff --git a/serial.c b/serial.c +index 1b394cd..126079a 100644 +--- a/serial.c ++++ b/serial.c +@@ -41,12 +41,6 @@ + + fdtype sp_fd = SER_INV_FD; + +-void __attribute__((noreturn)) sp_die(char *msg) +-{ +- perror(msg); +- exit(1); +-} +- + #ifdef _WIN32 + struct baudentry { + DWORD flag; +@@ -158,35 +152,18 @@ static void msg_perr_strerror(const char *msg) + #endif + } + +-fdtype sp_openserport(char *dev, unsigned int baud) ++int serialport_config(fdtype fd, unsigned int baud) + { +-#ifdef _WIN32 +- HANDLE fd; +- char *dev2 = dev; +- if ((strlen(dev) > 3) && +- (tolower((unsigned char)dev[0]) == 'c') && +- (tolower((unsigned char)dev[1]) == 'o') && +- (tolower((unsigned char)dev[2]) == 'm')) { +- dev2 = malloc(strlen(dev) + 5); +- if (!dev2) { +- msg_perr_strerror("Out of memory: "); +- return SER_INV_FD; +- } +- strcpy(dev2, "\\\\.\\"); +- strcpy(dev2 + 4, dev); +- } +- fd = CreateFile(dev2, GENERIC_READ | GENERIC_WRITE, 0, NULL, +- OPEN_EXISTING, 0, NULL); +- if (dev2 != dev) +- free(dev2); +- if (fd == INVALID_HANDLE_VALUE) { +- msg_perr_strerror("Cannot open serial port: "); +- return SER_INV_FD; ++ if (fd == SER_INV_FD) { ++ msg_perr("%s: File descriptor is invalid.\n", __func__); ++ return 1; + } ++ ++#ifdef _WIN32 + DCB dcb; + if (!GetCommState(fd, &dcb)) { + msg_perr_strerror("Could not fetch original serial port configuration: "); +- goto out_close; ++ return 1; + } + const struct baudentry *entry = round_baud(baud); + dcb.BaudRate = entry->flag; +@@ -195,35 +172,25 @@ fdtype sp_openserport(char *dev, unsigned int baud) + dcb.StopBits = ONESTOPBIT; + if (!SetCommState(fd, &dcb)) { + msg_perr_strerror("Could not change serial port configuration: "); +- goto out_close; ++ return 1; + } + if (!GetCommState(fd, &dcb)) { + msg_perr_strerror("Could not fetch new serial port configuration: "); +- goto out_close; ++ return 1; + } + msg_pdbg("Baud rate is %ld.\n", dcb.BaudRate); +- return fd; +-out_close: +- CloseHandle(sp_fd); +- return SER_INV_FD; + #else + struct termios wanted, observed; +- int fd; +- fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY); +- if (fd < 0) { +- msg_perr_strerror("Cannot open serial port: "); +- return SER_INV_FD; +- } + fcntl(fd, F_SETFL, 0); + if (tcgetattr(fd, &observed) != 0) { + msg_perr_strerror("Could not fetch original serial port configuration: "); +- goto out_close; ++ return 1; + } + wanted = observed; + const struct baudentry *entry = round_baud(baud); + if (cfsetispeed(&wanted, entry->flag) != 0 || cfsetospeed(&wanted, entry->flag) != 0) { + msg_perr_strerror("Could not set serial baud rate: "); +- goto out_close; ++ return 1; + } + wanted.c_cflag &= ~(PARENB | CSTOPB | CSIZE | CRTSCTS); + wanted.c_cflag |= (CS8 | CLOCAL | CREAD); +@@ -232,11 +199,11 @@ out_close: + wanted.c_oflag &= ~OPOST; + if (tcsetattr(fd, TCSANOW, &wanted) != 0) { + msg_perr_strerror("Could not change serial port configuration: "); +- goto out_close; ++ return 1; + } + if (tcgetattr(fd, &observed) != 0) { + msg_perr_strerror("Could not fetch new serial port configuration: "); +- goto out_close; ++ return 1; + } + if (observed.c_cflag != wanted.c_cflag || + observed.c_lflag != wanted.c_lflag || +@@ -244,14 +211,54 @@ out_close: + observed.c_oflag != wanted.c_oflag || + cfgetispeed(&observed) != cfgetispeed(&wanted)) { + msg_perr("%s: Some requested options did not stick.\n", __func__); +- goto out_close; ++ return 1; + } +- msg_pdbg("Baud rate is %d.\n", entry->baud); +- return fd; ++ msg_pdbg("Baud rate is %d now.\n", entry->baud); ++#endif ++ return 0; ++} + +-out_close: +- close(sp_fd); +- return SER_INV_FD; ++fdtype sp_openserport(char *dev, unsigned int baud) ++{ ++ fdtype fd; ++#ifdef _WIN32 ++ char *dev2 = dev; ++ if ((strlen(dev) > 3) && ++ (tolower((unsigned char)dev[0]) == 'c') && ++ (tolower((unsigned char)dev[1]) == 'o') && ++ (tolower((unsigned char)dev[2]) == 'm')) { ++ dev2 = malloc(strlen(dev) + 5); ++ if (!dev2) { ++ msg_perr_strerror("Out of memory: "); ++ return SER_INV_FD; ++ } ++ strcpy(dev2, "\\\\.\\"); ++ strcpy(dev2 + 4, dev); ++ } ++ fd = CreateFile(dev2, GENERIC_READ | GENERIC_WRITE, 0, NULL, ++ OPEN_EXISTING, 0, NULL); ++ if (dev2 != dev) ++ free(dev2); ++ if (fd == INVALID_HANDLE_VALUE) { ++ msg_perr_strerror("Cannot open serial port: "); ++ return SER_INV_FD; ++ } ++ if (serialport_config(fd, baud) != 0) { ++ CloseHandle(fd); ++ return SER_INV_FD; ++ } ++ return fd; ++#else ++ fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY); ++ if (fd < 0) { ++ msg_perr_strerror("Cannot open serial port: "); ++ return SER_INV_FD; ++ } ++ if (serialport_config(fd, baud) != 0) { ++ close(fd); ++ return SER_INV_FD; ++ } ++ return fd; + #endif + } + +@@ -350,7 +357,7 @@ int serialport_write(unsigned char *buf, unsigned int writecnt) + if (!tmp) { + msg_pdbg2("Empty write\n"); + empty_writes--; +- programmer_delay(500); ++ internal_delay(500); + if (empty_writes == 0) { + msg_perr("Serial port is unresponsive!\n"); + return 1; +diff --git a/serprog.c b/serprog.c +index 3476315..35c4f32 100644 +--- a/serprog.c ++++ b/serprog.c +@@ -100,6 +100,7 @@ static int sp_opensocket(char *ip, unsigned int port) + if (NULL == hostPtr) { + hostPtr = gethostbyaddr(ip, strlen(ip), AF_INET); + if (NULL == hostPtr) { ++ close(sock); + msg_perr("Error: cannot resolve %s\n", ip); + return -1; + } +@@ -114,7 +115,11 @@ static int sp_opensocket(char *ip, unsigned int port) + } + /* We are latency limited, and sometimes do write-write-read * + * (write-n) - so enable TCP_NODELAY. */ +- setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(int)); ++ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(int))) { ++ close(sock); ++ msg_perr("Error: serprog cannot set socket options: %s\n", strerror(errno)); ++ return -1; ++ } + return sock; + } + #endif +@@ -237,43 +242,58 @@ static int sp_docommand(uint8_t command, uint32_t parmlen, + return 0; + } + +-static void sp_flush_stream(void) ++static int sp_flush_stream(void) + { + if (sp_streamed_transmit_ops) + do { + unsigned char c; + if (serialport_read(&c, 1) != 0) { +- sp_die("Error: cannot read from device (flushing stream)"); ++ msg_perr("Error: cannot read from device (flushing stream)"); ++ return 1; + } + if (c == S_NAK) { + msg_perr("Error: NAK to a stream buffer operation\n"); +- exit(1); ++ return 1; + } + if (c != S_ACK) { + msg_perr("Error: Invalid reply 0x%02X from device\n", c); +- exit(1); ++ return 1; + } + } while (--sp_streamed_transmit_ops); + sp_streamed_transmit_ops = 0; + sp_streamed_transmit_bytes = 0; ++ return 0; + } + +-static int sp_stream_buffer_op(uint8_t cmd, uint32_t parmlen, uint8_t * parms) ++static int sp_stream_buffer_op(uint8_t cmd, uint32_t parmlen, uint8_t *parms) + { + uint8_t *sp; + if (sp_automatic_cmdcheck(cmd)) + return 1; ++ + sp = malloc(1 + parmlen); +- if (!sp) sp_die("Error: cannot malloc command buffer"); ++ if (!sp) { ++ msg_perr("Error: cannot malloc command buffer\n"); ++ return 1; ++ } + sp[0] = cmd; + memcpy(&(sp[1]), parms, parmlen); +- if (sp_streamed_transmit_bytes >= (1 + parmlen + sp_device_serbuf_size)) +- sp_flush_stream(); +- if (serialport_write(sp, 1 + parmlen) != 0) +- sp_die("Error: cannot write command"); +- free(sp); ++ ++ if (sp_streamed_transmit_bytes >= (1 + parmlen + sp_device_serbuf_size)) { ++ if (sp_flush_stream() != 0) { ++ free(sp); ++ return 1; ++ } ++ } ++ if (serialport_write(sp, 1 + parmlen) != 0) { ++ msg_perr("Error: cannot write command\n"); ++ free(sp); ++ return 1; ++ } + sp_streamed_transmit_ops += 1; + sp_streamed_transmit_bytes += 1 + parmlen; ++ ++ free(sp); + return 0; + } + +@@ -656,16 +676,16 @@ int serprog_init(void) + return 0; + } + +-/* Move an in flashrom buffer existing write-n operation to * +- * the on-device operation buffer. */ +-static void sp_pass_writen(void) ++/* Move an in flashrom buffer existing write-n operation to the on-device operation buffer. */ ++static int sp_pass_writen(void) + { + unsigned char header[7]; +- msg_pspew(MSGHEADER "Passing write-n bytes=%d addr=0x%x\n", +- sp_write_n_bytes, sp_write_n_addr); +- if (sp_streamed_transmit_bytes >= +- (7 + sp_write_n_bytes + sp_device_serbuf_size)) +- sp_flush_stream(); ++ msg_pspew(MSGHEADER "Passing write-n bytes=%d addr=0x%x\n", sp_write_n_bytes, sp_write_n_addr); ++ if (sp_streamed_transmit_bytes >= (7 + sp_write_n_bytes + sp_device_serbuf_size)) { ++ if (sp_flush_stream() != 0) { ++ return 1; ++ } ++ } + /* In case it's just a single byte send it as a single write. */ + if (sp_write_n_bytes == 1) { + sp_write_n_bytes = 0; +@@ -673,9 +693,10 @@ static void sp_pass_writen(void) + header[1] = (sp_write_n_addr >> 8) & 0xFF; + header[2] = (sp_write_n_addr >> 16) & 0xFF; + header[3] = sp_write_n_buf[0]; +- sp_stream_buffer_op(S_CMD_O_WRITEB, 4, header); ++ if (sp_stream_buffer_op(S_CMD_O_WRITEB, 4, header) != 0) ++ return 1; + sp_opbuf_usage += 5; +- return; ++ return 0; + } + header[0] = S_CMD_O_WRITEN; + header[1] = (sp_write_n_bytes >> 0) & 0xFF; +@@ -684,39 +705,55 @@ static void sp_pass_writen(void) + header[4] = (sp_write_n_addr >> 0) & 0xFF; + header[5] = (sp_write_n_addr >> 8) & 0xFF; + header[6] = (sp_write_n_addr >> 16) & 0xFF; +- if (serialport_write(header, 7) != 0) +- sp_die("Error: cannot write write-n command\n"); +- if (serialport_write(sp_write_n_buf, sp_write_n_bytes) != 0) +- sp_die("Error: cannot write write-n data"); ++ if (serialport_write(header, 7) != 0) { ++ msg_perr(MSGHEADER "Error: cannot write write-n command\n"); ++ return 1; ++ } ++ if (serialport_write(sp_write_n_buf, sp_write_n_bytes) != 0) { ++ msg_perr(MSGHEADER "Error: cannot write write-n data"); ++ return 1; ++ } + sp_streamed_transmit_bytes += 7 + sp_write_n_bytes; + sp_streamed_transmit_ops += 1; + sp_opbuf_usage += 7 + sp_write_n_bytes; + sp_write_n_bytes = 0; + sp_prev_was_write = 0; ++ return 0; + } + +-static void sp_execute_opbuf_noflush(void) ++static int sp_execute_opbuf_noflush(void) + { +- if ((sp_max_write_n) && (sp_write_n_bytes)) +- sp_pass_writen(); +- sp_stream_buffer_op(S_CMD_O_EXEC, 0, NULL); +- msg_pspew(MSGHEADER "Executed operation buffer of %d bytes\n", +- sp_opbuf_usage); ++ if ((sp_max_write_n) && (sp_write_n_bytes)) { ++ if (sp_pass_writen() != 0) { ++ msg_perr("Error: could not transfer write buffer\n"); ++ return 1; ++ } ++ } ++ if (sp_stream_buffer_op(S_CMD_O_EXEC, 0, NULL) != 0) { ++ msg_perr("Error: could not execute command buffer\n"); ++ return 1; ++ } ++ msg_pspew(MSGHEADER "Executed operation buffer of %d bytes\n", sp_opbuf_usage); + sp_opbuf_usage = 0; + sp_prev_was_write = 0; +- return; ++ return 0; + } + +-static void sp_execute_opbuf(void) ++static int sp_execute_opbuf(void) + { +- sp_execute_opbuf_noflush(); +- sp_flush_stream(); ++ if (sp_execute_opbuf_noflush() != 0) ++ return 1; ++ if (sp_flush_stream() != 0) ++ return 1; ++ ++ return 0; + } + + static int serprog_shutdown(void *data) + { + if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes)) +- sp_execute_opbuf(); ++ if (sp_execute_opbuf() != 0) ++ msg_pwarn("Could not flush command buffer.\n"); + if (sp_check_commandavail(S_CMD_S_PIN_STATE)) { + uint8_t dis = 0; + if (sp_docommand(S_CMD_S_PIN_STATE, 1, &dis, 0, NULL) == 0) +@@ -731,14 +768,15 @@ static int serprog_shutdown(void *data) + return 0; + } + +-static void sp_check_opbuf_usage(int bytes_to_be_added) ++static int sp_check_opbuf_usage(int bytes_to_be_added) + { + if (sp_device_opbuf_size <= (sp_opbuf_usage + bytes_to_be_added)) { +- sp_execute_opbuf(); +- /* If this happens in the mid of an page load the page load * +- * will probably fail. */ +- msg_pdbg(MSGHEADER "Warning: executed operation buffer due to size reasons\n"); ++ /* If this happens in the middle of a page load the page load will probably fail. */ ++ msg_pwarn(MSGHEADER "Warning: executed operation buffer due to size reasons\n"); ++ if (sp_execute_opbuf() != 0) ++ return 1; + } ++ return 0; + } + + static void serprog_chip_writeb(const struct flashctx *flash, uint8_t val, +@@ -768,7 +806,7 @@ static void serprog_chip_writeb(const struct flashctx *flash, uint8_t val, + writeb_parm[1] = (addr >> 8) & 0xFF; + writeb_parm[2] = (addr >> 16) & 0xFF; + writeb_parm[3] = val; +- sp_stream_buffer_op(S_CMD_O_WRITEB, 4, writeb_parm); ++ sp_stream_buffer_op(S_CMD_O_WRITEB, 4, writeb_parm); // FIXME: return error + sp_opbuf_usage += 5; + } + } +@@ -785,16 +823,16 @@ static uint8_t serprog_chip_readb(const struct flashctx *flash, + buf[0] = ((addr >> 0) & 0xFF); + buf[1] = ((addr >> 8) & 0xFF); + buf[2] = ((addr >> 16) & 0xFF); +- sp_stream_buffer_op(S_CMD_R_BYTE, 3, buf); +- sp_flush_stream(); ++ sp_stream_buffer_op(S_CMD_R_BYTE, 3, buf); // FIXME: return error ++ sp_flush_stream(); // FIXME: return error + if (serialport_read(&c, 1) != 0) +- sp_die("readb byteread"); ++ msg_perr(MSGHEADER "readb byteread"); // FIXME: return error + msg_pspew("%s addr=0x%" PRIxPTR " returning 0x%02X\n", __func__, addr, c); + return c; + } + + /* Local version that really does the job, doesn't care of max_read_n. */ +-static void sp_do_read_n(uint8_t * buf, const chipaddr addr, size_t len) ++static int sp_do_read_n(uint8_t * buf, const chipaddr addr, size_t len) + { + unsigned char sbuf[6]; + msg_pspew("%s: addr=0x%" PRIxPTR " len=%zu\n", __func__, addr, len); +@@ -808,10 +846,13 @@ static void sp_do_read_n(uint8_t * buf, const chipaddr addr, size_t len) + sbuf[4] = ((len >> 8) & 0xFF); + sbuf[5] = ((len >> 16) & 0xFF); + sp_stream_buffer_op(S_CMD_R_NBYTES, 6, sbuf); +- sp_flush_stream(); +- if (serialport_read(buf, len) != 0) +- sp_die("Error: cannot read read-n data"); +- return; ++ if (sp_flush_stream() != 0) ++ return 1; ++ if (serialport_read(buf, len) != 0) { ++ msg_perr(MSGHEADER "Error: cannot read read-n data"); ++ return 1; ++ } ++ return 0; + } + + /* The externally called version that makes sure that max_read_n is obeyed. */ +@@ -821,12 +862,12 @@ static void serprog_chip_readn(const struct flashctx *flash, uint8_t * buf, + size_t lenm = len; + chipaddr addrm = addr; + while ((sp_max_read_n != 0) && (lenm > sp_max_read_n)) { +- sp_do_read_n(&(buf[addrm-addr]), addrm, sp_max_read_n); ++ sp_do_read_n(&(buf[addrm-addr]), addrm, sp_max_read_n); // FIXME: return error + addrm += sp_max_read_n; + lenm -= sp_max_read_n; + } + if (lenm) +- sp_do_read_n(&(buf[addrm-addr]), addrm, lenm); ++ sp_do_read_n(&(buf[addrm-addr]), addrm, lenm); // FIXME: return error + } + + void serprog_delay(int usecs) +@@ -858,11 +899,18 @@ static int serprog_spi_send_command(struct flashctx *flash, + unsigned char *parmbuf; + int ret; + msg_pspew("%s, writecnt=%i, readcnt=%i\n", __func__, writecnt, readcnt); +- if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes)) +- sp_execute_opbuf(); ++ if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes)) { ++ if (sp_execute_opbuf() != 0) { ++ msg_perr("Error: could not execute command buffer before sending SPI commands.\n"); ++ return 1; ++ } ++ } ++ + parmbuf = malloc(writecnt + 6); +- if (!parmbuf) +- sp_die("Error: cannot malloc SPI send param buffer"); ++ if (!parmbuf) { ++ msg_perr("Error: could not allocate SPI send param buffer.\n"); ++ return 1; ++ } + parmbuf[0] = (writecnt >> 0) & 0xFF; + parmbuf[1] = (writecnt >> 8) & 0xFF; + parmbuf[2] = (writecnt >> 16) & 0xFF; +@@ -879,8 +927,7 @@ static int serprog_spi_send_command(struct flashctx *flash, + /* FIXME: This function is optimized so that it does not split each transaction + * into chip page_size long blocks unnecessarily like spi_read_chunked. This has + * the advantage that it is much faster for most chips, but breaks those with +- * non-contiguous address space (like AT45DB161D). When spi_read_chunked is +- * fixed this method can be removed. */ ++ * non-continuous reads. When spi_read_chunked is fixed this method can be removed. */ + static int serprog_spi_read(struct flashctx *flash, uint8_t *buf, + unsigned int start, unsigned int len) + { +diff --git a/spi25.c b/spi25.c +index e001196..862a865 100644 +--- a/spi25.c ++++ b/spi25.c +@@ -679,7 +679,7 @@ int spi_block_erase_20(struct flashctx *flash, unsigned int addr, + + result = spi_send_multicommand(flash, cmds); + if (result) { +- msg_cerr("%s failed during command execution at address 0x%x\n", ++ msg_pdbg("%s failed during command execution at address 0x%x\n", + __func__, addr); + return result; + } +@@ -1128,13 +1128,9 @@ int default_spi_write_aai(struct flashctx *flash, uint8_t *buf, unsigned int sta + + + result = spi_send_multicommand(flash, cmds); +- if (result) { +- msg_cerr("%s failed during start command execution\n", +- __func__); +- /* FIXME: Should we send WRDI here as well to make sure the chip +- * is not in AAI mode? +- */ +- return result; ++ if (result != 0) { ++ msg_cerr("%s failed during start command execution: %d\n", __func__, result); ++ goto bailout; + } + while (spi_read_status_register(flash) & SPI_SR_WIP) + programmer_delay(10); +@@ -1146,16 +1142,21 @@ int default_spi_write_aai(struct flashctx *flash, uint8_t *buf, unsigned int sta + while (pos < start + len - 1) { + cmd[1] = buf[pos++ - start]; + cmd[2] = buf[pos++ - start]; +- spi_send_command(flash, JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE, 0, +- cmd, NULL); ++ result = spi_send_command(flash, JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE, 0, cmd, NULL); ++ if (result != 0) { ++ msg_cerr("%s failed during followup AAI command execution: %d\n", __func__, result); ++ goto bailout; ++ } + while (spi_read_status_register(flash) & SPI_SR_WIP) + programmer_delay(10); + } + +- /* Use WRDI to exit AAI mode. This needs to be done before issuing any +- * other non-AAI command. +- */ +- spi_write_disable(flash); ++ /* Use WRDI to exit AAI mode. This needs to be done before issuing any other non-AAI command. */ ++ result = spi_write_disable(flash); ++ if (result != 0) { ++ msg_cerr("%s failed to disable AAI mode.\n", __func__); ++ return SPI_GENERIC_ERROR; ++ } + + /* Write remaining byte (if any). */ + if (pos < start + len) { +@@ -1165,4 +1166,10 @@ int default_spi_write_aai(struct flashctx *flash, uint8_t *buf, unsigned int sta + } + + return 0; ++ ++bailout: ++ result = spi_write_disable(flash); ++ if (result != 0) ++ msg_cerr("%s failed to disable AAI mode.\n", __func__); ++ return SPI_GENERIC_ERROR; + } +diff --git a/spi25_statusreg.c b/spi25_statusreg.c +index 8fb7f2d..48fceb0 100644 +--- a/spi25_statusreg.c ++++ b/spi25_statusreg.c +@@ -270,7 +270,7 @@ static void spi_prettyprint_status_register_bp(uint8_t status, int bp) + } + + /* Unnamed bits. */ +-static void spi_prettyprint_status_register_bit(uint8_t status, int bit) ++void spi_prettyprint_status_register_bit(uint8_t status, int bit) + { + msg_cdbg("Chip status register: Bit %i is %sset\n", bit, (status & (1 << bit)) ? "" : "not "); + } +diff --git a/stm50.c b/stm50.c +new file mode 100644 +index 0000000..edcfdd2 +--- /dev/null ++++ b/stm50.c +@@ -0,0 +1,115 @@ ++/* ++ * This file is part of the flashrom project. ++ * ++ * Copyright (C) 2008 Claus Gindhart ++ * Copyright (C) 2009 Sean Nelson ++ * Copyright (C) 2013 Stefan Tauner ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You 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 ++ */ ++ ++/* ++ * All ST M50 chips are locked on startup. Most of them have a uniform 64 kB block layout, but some have ++ * a non-uniform block/sector segmentation which has to be handled with more care. Some of the non-uniform ++ * chips support erasing of the 4 kB sectors with another command. ++ */ ++ ++#include "flash.h" ++#include "flashchips.h" ++#include "chipdrivers.h" ++ ++static int stm50_unlock_address(struct flashctx *flash, int offset) ++{ ++ chipaddr wrprotect = flash->virtual_registers + 2; ++ static const uint8_t unlock_sector = 0x00; ++ msg_cdbg("unlocking at 0x%x\n", offset); ++ chip_writeb(flash, unlock_sector, wrprotect + offset); ++ if (chip_readb(flash, wrprotect + offset) != unlock_sector) { ++ msg_cerr("Cannot unlock address 0x%x\n", offset); ++ return -1; ++ } ++ return 0; ++} ++ ++/* Chips known to use a non-uniform block and sector layout for locking (as well as for erasing): ++ * Name Size Address range of lock registers ++ * M50FLW080A 1MB FFB00002 - FFBFF002 ++ * M50FLW080B 1MB FFB00002 - FFBFF002 ++ * M50FW002 256k FFBC0002 - FFBFC002 ++ * M50LPW116 2MB FFA00002 - FFBFC002 ++ */ ++int unlock_stm50_nonuniform(struct flashctx *flash) ++{ ++ int i; ++ struct eraseblock *eraseblocks = flash->chip->block_erasers[0].eraseblocks; ++ unsigned int done = 0; ++ for (i = 0; i < NUM_ERASEREGIONS && eraseblocks[i].count != 0; i++) { ++ unsigned int block_size = eraseblocks[i].size; ++ unsigned int block_count = eraseblocks[i].count; ++ ++ int j; ++ for (j = 0; j < block_count; j++) { ++ if (stm50_unlock_address(flash, done)) { ++ msg_cerr("UNLOCK FAILED!\n"); ++ return -1; ++ } ++ done += block_count * block_size; ++ } ++ } ++ return 0; ++} ++ ++/* Unlocking for uniform 64 kB blocks starting at offset 2 of the feature registers. */ ++int unlock_stm50_uniform(struct flashctx *flash) ++{ ++ int i; ++ for (i = 0; i < flash->chip->total_size * 1024; i+= 64 * 1024) { ++ if (stm50_unlock_address(flash, i)) { ++ msg_cerr("UNLOCK FAILED!\n"); ++ return -1; ++ } ++ } ++ return 0; ++} ++ ++static int stm50_erase_sector(struct flashctx *flash, unsigned int addr) ++{ ++ chipaddr bios = flash->virtual_memory + addr; ++ ++ // clear status register ++ chip_writeb(flash, 0x50, bios); ++ // now start it ++ chip_writeb(flash, 0x32, bios); ++ chip_writeb(flash, 0xd0, bios); ++ programmer_delay(10); ++ ++ uint8_t status = wait_82802ab(flash); ++ print_status_82802ab(status); ++ ++ return status == 0x80; ++} ++ ++/* Some ST M50* chips do support erasing of sectors. This function will derive the erase function to use from ++ * the length of the of the block. For calls that apparently do not address a sector (but a block) we just call ++ * the block erase function instead. FIXME: This duplicates the behavior of the remaining erasers for blocks and ++ * might be fixed when flashrom supports multiple functions per eraser or erasers that do erase parts of the ++ * chip only. */ ++int erase_sector_stm50(struct flashctx *flash, unsigned int addr, unsigned int len) ++{ ++ if (len == 4096) ++ return stm50_erase_sector(flash, addr); ++ else ++ return erase_block_82802ab(flash, addr, len); ++} +diff --git a/udelay.c b/udelay.c +index e3cf3e3..9d3bfc2 100644 +--- a/udelay.c ++++ b/udelay.c +@@ -90,7 +90,11 @@ void myusec_calibrate_delay(void) + unsigned long timeusec, resolution; + int i, tries = 0; + ++#ifdef FORCE10_SPI_CHANGE ++ msg_pdbg("Calibrating delay loop... "); ++#else + msg_pinfo("Calibrating delay loop... "); ++#endif + resolution = measure_os_delay_resolution(); + if (resolution) { + msg_pdbg("OS timer resolution is %lu usecs, ", resolution); +@@ -151,7 +155,7 @@ recalibrate: + } + } + } else { +- msg_perr("delay loop is unreliable, trying to continue "); ++ msg_pdbg("delay loop is unreliable, trying to continue "); + } + + /* We're interested in the actual precision. */ +@@ -166,7 +170,11 @@ recalibrate: + timeusec = measure_delay(resolution * 4); + msg_pdbg("%ld myus = %ld us, ", resolution * 4, timeusec); + ++#ifdef FORCE10_SPI_CHANGE ++ msg_pdbg("OK.\n"); ++#else + msg_pinfo("OK.\n"); ++#endif + } + + /* Not very precise sleep. */ +diff --git a/util/getrevision.sh b/util/getrevision.sh +new file mode 100755 +index 0000000..709e45f +--- /dev/null ++++ b/util/getrevision.sh +@@ -0,0 +1,311 @@ ++#!/bin/sh ++# ++# This file is part of the flashrom project. ++# ++# Copyright (C) 2005 coresystems GmbH ++# Copyright (C) 2009,2010 Carl-Daniel Hailfinger ++# Copyright (C) 2010 Chromium OS Authors ++# Copyright (C) 2013 Stefan Tauner ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You 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 ++# ++ ++EXIT_SUCCESS=0 ++EXIT_FAILURE=1 ++ ++# Make sure we don't get translated output ++export LC_ALL=C ++# nor local times or dates ++export TZ=UTC0 ++ ++# Helper functions ++# First argument is the path to inspect (usually optional; w/o it the whole repository will be considered) ++svn_has_local_changes() { ++ svn status "$1" | egrep '^ *[ADMR] *' >/dev/null ++} ++ ++git_has_local_changes() { ++ git update-index -q --refresh >/dev/null ++ ! git diff-index --quiet HEAD -- "$1" ++} ++ ++git_last_commit() { ++ git log --pretty=format:"%h" -1 -- "$1" ++} ++ ++svn_is_file_tracked() { ++ svn info "$1" >/dev/null 2>&1 ++} ++ ++git_is_file_tracked() { ++ git ls-files --error-unmatch -- "$1" >/dev/null 2>&1 ++} ++ ++is_file_tracked() { ++ svn_is_file_tracked "$1" || git_is_file_tracked "$1" ++} ++ ++# Tries to find a remote source for the changes committed locally. ++# This includes the URL of the remote repository including the last commit and a suitable branch name. ++# Takes one optional argument: the path to inspect ++git_url() { ++ last_commit=$(git_last_commit "$1") ++ # get all remote branches containing the last commit (excluding origin/HEAD and git-svn branches/tags) ++ branches=$(git branch -r --contains $last_commit | sed '/\//!d;/.*->.*/d;s/[\t ]*//') ++ if [ -z "$branches" ] ; then ++ echo "No remote branch contains a suitable commit">&2 ++ return ++ fi ++ ++ # find "nearest" branch ++ local mindiff=9000 ++ local target= ++ for branch in $branches ; do ++ curdiff=$(git rev-list --count $last_commit..$branch) ++ if [ $curdiff -ge $mindiff ] ; then ++ continue ++ fi ++ mindiff=$curdiff ++ target=$branch ++ done ++ ++ echo "$(git ls-remote --exit-code --get-url ${target%/*}) ${target#*/}" ++} ++ ++# Returns a string indicating where others can get the current source code (excluding uncommitted changes) ++# Takes one optional argument: the path to inspect ++scm_url() { ++ local url= ++ ++ # for a primitive VCS like subversion finding the URL is easy: there is only one upstream host ++ if svn_is_file_tracked "$1" ; then ++ url="$(svn info "$1" 2>/dev/null | ++ grep URL: | ++ sed 's/.*URL:[[:blank:]]*//;s/:\/\/.*@/:\/\//' | ++ grep ^.)" ++ elif git_is_file_tracked "$1" ; then ++ url="$(git_url "$1")" ++ else ++ return ${EXIT_FAILURE} ++ fi ++ ++ echo "${url}" ++} ++ ++# Retrieve timestamp since last modification. If the sources are pristine, ++# then the timestamp will match that of the SCM's most recent modification ++# date. ++timestamp() { ++ local t ++ ++ # date syntaxes are manifold: ++ # gnu date [-d input]... [+FORMAT] ++ # netbsd date [-ajnu] [-d date] [-r seconds] [+format] [[[[[[CC]yy]mm]dd]HH]MM[.SS]] ++ # freebsd date [-jnu] [-d dst] [-r seconds] [-f fmt date | [[[[[cc]yy]mm]dd]HH]MM[.ss]] [+format] [...] ++ # dragonflybsd date [-jnu] [-d dst] [-r seconds] [-f fmt date | [[[[[cc]yy]mm]dd]HH]MM[.ss]] [+format] [...] ++ # openbsd date [-aju] [-d dst] [-r seconds] [+format] [[[[[[cc]yy]mm]dd]HH]MM[.SS]] [...] ++ if svn_is_file_tracked "$2" ; then ++ if svn_has_local_changes "$2"; then ++ t=$(date -u "$1") ++ else ++ # No local changes, get date of the last log record. Subversion provides that in ++ # ISO 8601 format when using the --xml switch. The sed call extracts that ignoring any ++ # fractional parts started by a comma or a dot. ++ local last_commit_date="$(svn info --xml "$2"| \ ++ sed -n -e 's/\([^,\.]*\)\([\.,].*\)*Z<\/date>/\1Z/p')" ++ ++ case $(uname) in ++ # Most BSD dates do not support parsing date values from user input with -d but all of ++ # them support parsing the syntax with [[[[[[cc]yy]mm]dd]HH]MM[.ss]]. We have to ++ # transform the ISO8601 date first though. ++ NetBSD|OpenBSD|DragonFly|FreeBSD) ++ last_commit_date="$(echo ${last_commit_date} | \ ++ sed -n -e 's/\(....\)-\(..\)-\(..\)T\(..\):\(..\):\(..\)Z/\1\2\3\4\5\.\6/p')" ++ t=$(date -u -j "${last_commit_date}" "$1" 2>/dev/null);; ++ *) ++ t=$(date -u -d "${last_commit_date}" "$1" 2>/dev/null);; ++ esac ++ fi ++ elif git_is_file_tracked "$2" ; then ++ # are there local changes? ++ if git_has_local_changes "$2" ; then ++ t=$(date -u "${1}") ++ else ++ # No local changes, get date of the last commit ++ case $(uname) in ++ # Most BSD dates do not support parsing date values from user input with -d but all of ++ # them support parsing epoch seconds with -r. Thanks to git we can easily use that: ++ NetBSD|OpenBSD|DragonFly|FreeBSD) ++ t=$(date -u -r "$(git log --pretty=format:%ct -1 -- $2)" "$1" 2>/dev/null);; ++ *) ++ t=$(date -d "$(git log --pretty=format:%cD -1 -- $2)" -u "$1" 2>/dev/null);; ++ esac ++ fi ++ else ++ t=$(date -u "$1") ++ fi ++ ++ if [ -z "$t" ]; then ++ echo "Warning: Could not determine timestamp." 2>/dev/null ++ fi ++ echo "${t}" ++} ++ ++# Retrieve local SCM revision info. This is useful if we're working in a different SCM than upstream and/or ++# have local changes. ++local_revision() { ++ local r= ++ ++ if svn_is_file_tracked "$1" ; then ++ r=$(svn_has_local_changes "$1" && echo "dirty") ++ elif git_is_file_tracked "$1" ; then ++ r=$(git_last_commit "$1") ++ ++ local svn_base=$(git log --grep git-svn-id -1 --format='%h') ++ if [ "$svn_base" != "" ] ; then ++ local diff_to_svn=$(git rev-list --count ${svn_base}..${r}) ++ if [ "$diff_to_svn" -gt 0 ] ; then ++ r="$r-$diff_to_svn" ++ fi ++ fi ++ ++ if git_has_local_changes "$1" ; then ++ r="$r-dirty" ++ fi ++ else ++ return ${EXIT_FAILURE} ++ fi ++ ++ echo "${r}" ++} ++ ++# Get the upstream flashrom revision stored in SVN metadata. ++upstream_revision() { ++ local r= ++ ++ if svn_is_file_tracked "$1" ; then ++ r=$(svn info "$1" 2>/dev/null | \ ++ grep "Last Changed Rev:" | \ ++ sed -e "s/^Last Changed Rev: *//" -e "s/\([0-9]*\).*/r\1/" | \ ++ grep "r[0-9]") ++ elif git_is_file_tracked "$1" ; then ++ # If this is a "native" git-svn clone we could use git svn log: ++ # git svn log --oneline -1 | sed 's/^r//;s/[[:blank:]].*//' or even git svn find-rev ++ # but it is easier to just grep for the git-svn-id unconditionally ++ r=$(git log --grep git-svn-id -1 -- "$1" | \ ++ grep git-svn-id | \ ++ sed 's/.*@/r/;s/[[:blank:]].*//') ++ fi ++ ++ if [ -z "$r" ]; then ++ r="unknown" # default to unknown ++ fi ++ echo "${r}" ++} ++ ++show_help() { ++ echo "Usage: ++ ${0} [path] ++ ++Commands ++ -h or --help ++ this message ++ -l or --local ++ local revision information including an indicator for uncommitted changes ++ -u or --upstream ++ upstream revision ++ -U or --url ++ URL associated with the latest commit ++ -d or --date ++ date of most recent modification ++ -t or --timestamp ++ timestamp of most recent modification ++" ++ return ++} ++ ++check_action() { ++ if [ -n "$action" ]; then ++ echo "Error: Multiple actions given.">&2 ++ exit ${EXIT_FAILURE} ++ fi ++} ++ ++main() { ++ local query_path= ++ local action= ++ ++ # The is the main loop ++ while [ $# -gt 0 ]; ++ do ++ case ${1} in ++ -h|--help) ++ action=show_help; ++ shift;; ++ -l|--local) ++ check_action $1 ++ action=local_revision ++ shift;; ++ -u|--upstream) ++ check_action $1 ++ action=upstream_revision ++ shift;; ++ -U|--url) ++ check_action $1 ++ action=scm_url ++ shift;; ++ -d|--date) ++ check_action $1 ++ action="timestamp +%Y-%m-%d" # refrain from suffixing 'Z' to indicate it's UTC ++ shift;; ++ -t|--timestamp) ++ check_action $1 ++ action="timestamp +%Y-%m-%dT%H:%M:%SZ" # There is only one valid time format! ISO 8601 ++ shift;; ++ -*) ++ show_help; ++ echo "Error: Invalid option: ${1}" ++ exit ${EXIT_FAILURE};; ++ *) ++ if [ -z "$query_path" ] ; then ++ if [ ! -e "$1" ] ; then ++ echo "Error: Path \"${1}\" does not exist.">&2 ++ exit ${EXIT_FAILURE} ++ fi ++ query_path=$1 ++ else ++ echo "Warning: Ignoring over-abundant paramter: \"${1}\"">&2 ++ fi ++ shift;; ++ esac; ++ done ++ ++ # default to current directory (usually equals the whole repository) ++ if [ -z "$query_path" ] ; then ++ query_path=. ++ fi ++ if ! is_file_tracked "$query_path" ; then ++ echo "Warning: Path \"${query_path}\" is not under version control.">&2 ++ fi ++ if [ -z "$action" ] ; then ++ show_help ++ echo "Error: No actions specified" ++ exit ${EXIT_FAILURE} ++ fi ++ ++ $action "$query_path" ++} ++ ++main $@ +diff --git a/util/ich_descriptors_tool/ich_descriptors_tool.c b/util/ich_descriptors_tool/ich_descriptors_tool.c +index c359913..dd35860 100644 +--- a/util/ich_descriptors_tool/ich_descriptors_tool.c ++++ b/util/ich_descriptors_tool/ich_descriptors_tool.c +@@ -77,12 +77,13 @@ static void dump_file(const char *prefix, const uint32_t *dump, unsigned int len + printf("Dumping %u bytes of the %s region from 0x%08x-0x%08x to %s... ", + file_len, region_names[i], base, limit, fn); + int fh = open(fn, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); +- free(fn); + if (fh < 0) { + fprintf(stderr, + "ERROR: couldn't open(%s): %s\n", fn, strerror(errno)); ++ free(fn); + exit(1); + } ++ free(fn); + + ret = write(fh, &dump[base >> 2], file_len); + if (ret != file_len) { +@@ -120,6 +121,7 @@ static void usage(char *argv[], char *error) + "\t- \"5\" or \"ibex\" for Intel's 5 series chipsets,\n" + "\t- \"6\" or \"cougar\" for Intel's 6 series chipsets,\n" + "\t- \"7\" or \"panther\" for Intel's 7 series chipsets.\n" ++"\t- \"avoton\",\n" + "If '-d' is specified some regions such as the BIOS image as seen by the CPU or\n" + "the GbE blob that is required to initialize the GbE are also dumped to files.\n", + argv[0], argv[0]); +@@ -197,6 +199,10 @@ int main(int argc, char *argv[]) + else if ((strcmp(csn, "7") == 0) || + (strcmp(csn, "panther") == 0)) + cs = CHIPSET_7_SERIES_PANTHER_POINT; ++#ifdef DELL_AVOTON_SUPPORT ++ else if (strcmp(csn, "avoton") == 0) ++ cs = CHIPSET_AVOTON; ++#endif + } + + ret = read_ich_descriptors_from_dump(buf, len, &desc); +diff --git a/util/z60_flashrom.rules b/util/z60_flashrom.rules +index 8456a04..948563c 100644 +--- a/util/z60_flashrom.rules ++++ b/util/z60_flashrom.rules +@@ -80,4 +80,8 @@ ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="002a", MODE="664", GROUP="plugdev" + # http://www.diygadget.com/tiao-usb-multi-protocol-adapter-jtag-spi-i2c-serial.html + ATTRS{idVendor}=="0403", ATTRS{idProduct}=="8a98", MODE="664", GROUP="plugdev" + ++# TIAO/DIYGADGET USB Multi-Protocol Adapter (TUMPA) Lite ++# http://www.tiaowiki.com/w/TIAO_USB_Multi_Protocol_Adapter_Lite_User's_Manual ++ATTRS{idVendor}=="0403", ATTRS{idProduct}=="8a99", MODE="664", GROUP="plugdev" ++ + LABEL="flashrom_rules_end" +-- +2.7.4 + diff --git a/platform/broadcom/sonic-platform-modules-dell/tools/flashrom.sh b/platform/broadcom/sonic-platform-modules-dell/tools/flashrom.sh new file mode 100755 index 000000000000..c3af65fd6d84 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/tools/flashrom.sh @@ -0,0 +1,10 @@ +#!/bin/bash +export DELL_TOOLS_DIR="platform/broadcom/sonic-platform-modules-dell/tools" + +cd $DELL_TOOLS_DIR +rm -rf $DELL_TOOLS_DIR/flashrom +git clone https://github.com/flashrom/flashrom.git +cd flashrom +git checkout tags/0.9.7 +git apply ../0002-Flashrom-support-for-Intel-Rangeley-and-Denverton-CP.patch +make diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh index 276acd882f14..7fe841ef5447 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh @@ -107,8 +107,8 @@ switch_board_qsfp_mux() { #Attach/Detach the SFP modules on PCA9548_2 switch_board_sfp() { case $1 in - "new_device") i2c_config "echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-11/$1" - i2c_config "echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-12/$1" + "new_device") i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-11/$1" + i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-12/$1" ;; "delete_device") i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-11/$1" i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-12/$1" @@ -125,7 +125,7 @@ switch_board_qsfp() { "new_device") for ((i=18;i<=49;i++)); do - i2c_config "echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" + i2c_config "echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" done ;; "delete_device") diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/__init__.py index 2be1c8f2588b..56f88c6e0fe2 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/__init__.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/__init__.py @@ -1,3 +1,3 @@ -__all__ = ["platform", "chassis", "sfp"] +__all__ = ["platform", "chassis", "fan", "psu", "sfp", "thermal"] from sonic_platform import * diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py index f912b806d081..3472bb3e7fb0 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,16 +10,24 @@ try: import os + import subprocess + import re from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.sfp import Sfp from sonic_platform.fan import Fan + from sonic_platform.psu import Psu + from sonic_platform.thermal import Thermal + from sonic_platform.component import Component from eeprom import Eeprom except ImportError as e: raise ImportError(str(e) + "- required module not found") + MAX_Z9100_FANTRAY = 5 MAX_Z9100_FAN = 2 MAX_Z9100_PSU = 2 +MAX_Z9100_THERMAL = 8 +MAX_Z9100_COMPONENT = 6 class Chassis(ChassisBase): @@ -92,6 +100,18 @@ def __init__(self): fan = Fan(i, j) self._fan_list.append(fan) + for i in range(MAX_Z9100_PSU): + psu = Psu(i) + self._psu_list.append(psu) + + for i in range(MAX_Z9100_THERMAL): + thermal = Thermal(i) + self._thermal_list.append(thermal) + + for i in range(MAX_Z9100_COMPONENT): + component = Component(i) + self._component_list.append(component) + def _get_pmc_register(self, reg_name): # On successful read, returns the value read from given # reg_name and on failure returns 'ERR' @@ -113,36 +133,45 @@ def _get_pmc_register(self, reg_name): def get_name(self): """ - Retrieves the name of the device + Retrieves the name of the chassis Returns: - string: The name of the device + string: The name of the chassis """ return self.sys_eeprom.modelstr() def get_presence(self): """ - Retrieves the presence of the device + Retrieves the presence of the chassis Returns: - bool: True if device is present, False if not + bool: True if chassis is present, False if not """ return True def get_model(self): """ - Retrieves the model number (or part number) of the device + Retrieves the model number (or part number) of the chassis Returns: - string: Model/part number of device + string: Model/part number of chassis """ return self.sys_eeprom.part_number_str() def get_serial(self): """ - Retrieves the serial number of the device (Service tag) + Retrieves the serial number of the chassis (Service tag) Returns: - string: Serial number of device + string: Serial number of chassis """ return self.sys_eeprom.serial_str() + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + def get_base_mac(self): """ Retrieves the base MAC address for the chassis @@ -162,6 +191,17 @@ def get_serial_number(self): """ return self.sys_eeprom.serial_number_str() + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self.sys_eeprom.system_eeprom_info() + def get_reboot_cause(self): """ Retrieves the cause of the previous reboot @@ -172,7 +212,6 @@ def get_reboot_cause(self): is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used to pass a description of the reboot cause. """ - reset_reason = int(self._get_pmc_register('smf_reset_reason')) power_reason = int(self._get_pmc_register('smf_poweron_reason')) @@ -191,4 +230,3 @@ def get_reboot_cause(self): return (self.reset_reason_dict[reset_reason], None) return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason") - diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/component.py new file mode 100644 index 000000000000..dccb8f6ac2dc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/component.py @@ -0,0 +1,164 @@ +#!/usr/bin/env python + +######################################################################## +# DELLEMC Z9100 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in +# the platform +# +######################################################################## + +try: + import os + import subprocess + from sonic_platform_base.component_base import ComponentBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +BIOS_QUERY_VERSION_COMMAND = "dmidecode -s system-version" + + +class Component(ComponentBase): + """DellEMC Platform-specific Component class""" + + HWMON_DIR = "/sys/devices/platform/SMF.512/hwmon/" + HWMON_NODE = os.listdir(HWMON_DIR)[0] + MAILBOX_DIR = HWMON_DIR + HWMON_NODE + + CHASSIS_COMPONENTS = [ + ["BIOS", ("Performs initialization of hardware components during " + "booting")], + ["CPLD1", "Used for managing the system LEDs"], + ["CPLD2", "Used for managing QSFP28 modules (1-12)"], + ["CPLD3", "Used for managing QSFP28 modules (13-22)"], + ["CPLD4", ("Used for managing QSFP28 modules (23-32) and SFP+ " + "modules")], + ["FPGA", ("Platform management controller for on-board temperature " + "monitoring, in-chassis power, Fan and LED control")] + ] + + 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] + + def _read_sysfs_file(self, sysfs_file): + # On successful read, returns the value read from given + # sysfs_file and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(sysfs_file)): + return rv + + try: + with open(sysfs_file, 'r') as fd: + rv = fd.read() + except Exception as error: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def _get_command_result(self, cmdline): + try: + proc = subprocess.Popen(cmdline.split(), stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + result = stdout.rstrip('\n') + except OSError: + result = None + + return result + + def _get_cpld_version(self, cpld_number): + io_resource = "/dev/port" + CPLD1_VERSION_ADDR = 0x100 + + if (cpld_number == 1): + fd = os.open(io_resource, os.O_RDONLY) + if (fd < 0): + return 'NA' + + if (os.lseek(fd, CPLD1_VERSION_ADDR, os.SEEK_SET) + != CPLD1_VERSION_ADDR): + os.close(fd) + return 'NA' + + buf = os.read(fd, 1) + cpld_version = str(ord(buf)) + os.close(fd) + + return cpld_version + else: + cpld_version_file = ("/sys/class/i2c-adapter/i2c-{0}/{0}-003e" + "/iom_cpld_vers").format(12 + cpld_number) + ver_str = self._read_sysfs_file(cpld_version_file) + + if (ver_str == "read error") or (ver_str == 'ERR'): + return 'NA' + + ver_str = ver_str.rstrip("\r\n") + cpld_version = str(int(ver_str.split(":")[1], 16)) + + return cpld_version + + def _get_fpga_version(self): + fpga_ver_file = self.MAILBOX_DIR + '/smf_firmware_ver' + fpga_ver = self._read_sysfs_file(fpga_ver_file) + if (fpga_ver != 'ERR'): + return fpga_ver + else: + return 'NA' + + def get_name(self): + """ + Retrieves the name of the component + + Returns: + A string containing the name of the component + """ + return self.name + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + if self.index == 0: # BIOS + bios_ver = self._get_command_result(BIOS_QUERY_VERSION_COMMAND) + + if not bios_ver: + return 'NA' + else: + return bios_ver + + elif self.index < 5: # CPLD + return self._get_cpld_version(self.index) + elif self.index == 5: # FPGA + return self._get_fpga_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/z9100/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/eeprom.py index 8be488b791ab..15a2cec80191 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/eeprom.py @@ -21,11 +21,42 @@ class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): def __init__(self): self.eeprom_path = "/sys/class/i2c-adapter/i2c-2/2-0050/eeprom" super(Eeprom, self).__init__(self.eeprom_path, 0, '', True) + self.eeprom_tlv_dict = dict() try: self.eeprom_data = self.read_eeprom() 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( @@ -74,3 +105,10 @@ def revision_str(self): 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/z9100/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py index 2327e24a2f6d..ae3c5e9fbcab 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py @@ -26,7 +26,7 @@ class Fan(FanBase): HWMON_NODE = os.listdir(HWMON_DIR)[0] MAILBOX_DIR = HWMON_DIR + HWMON_NODE - def __init__(self, fantray_index, fan_index=1, psu_fan=False): + def __init__(self, fantray_index=1, fan_index=1, psu_fan=False): self.is_psu_fan = psu_fan if not self.is_psu_fan: # API index is starting from 0, DellEMC platform index is starting @@ -73,7 +73,7 @@ def get_name(self): if not self.is_psu_fan: return "FanTray{}-Fan{}".format(self.fantrayindex, self.fanindex) else: - return "PSU{} Fan".format(self.index - 10) + return "PSU{} Fan".format(self.fanindex - 10) def get_model(self): """ @@ -208,6 +208,18 @@ def set_status_led(self, color): status = False return status + def get_status_led(self): + """ + Gets the state of the Fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + if self.get_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + def get_target_speed(self): """ Retrieves the target (expected) speed of the fan diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/psu.py new file mode 100644 index 000000000000..f76d0ac1bec6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/psu.py @@ -0,0 +1,237 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC Z9100 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the PSUs' information which are available in the platform +# +######################################################################## + + +try: + import os + from sonic_platform_base.psu_base import PsuBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Psu(PsuBase): + """DellEMC Platform-specific PSU class""" + + HWMON_DIR = "/sys/devices/platform/SMF.512/hwmon/" + HWMON_NODE = os.listdir(HWMON_DIR)[0] + MAILBOX_DIR = HWMON_DIR + HWMON_NODE + + def __init__(self, psu_index): + # PSU is 1-based in DellEMC platforms + self.index = psu_index + 1 + self.psu_presence_reg = "psu{}_presence".format(self.index) + self.psu_serialno_reg = "psu{}_serialno".format(self.index) + if self.index == 1: + self.psu_voltage_reg = "in30_input" + self.psu_current_reg = "curr602_input" + self.psu_power_reg = "power2_input" + elif self.index == 2: + self.psu_voltage_reg = "in32_input" + self.psu_current_reg = "curr702_input" + self.psu_power_reg = "power4_input" + + # Overriding _fan_list class variable defined in PsuBase, to + # make it unique per Psu object + self._fan_list = [] + + # Passing True to specify it is a PSU fan + psu_fan = Fan(fan_index=self.index, psu_fan=True) + self._fan_list.append(psu_fan) + + def _get_pmc_register(self, reg_name): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + mb_reg_file = self.MAILBOX_DIR + '/' + reg_name + + if (not os.path.isfile(mb_reg_file)): + return rv + + try: + with open(mb_reg_file, 'r') as fd: + rv = fd.read() + except Exception as error: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def get_name(self): + """ + Retrieves the 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 + """ + status = False + psu_presence = self._get_pmc_register(self.psu_presence_reg) + if (psu_presence != 'ERR'): + psu_presence = int(psu_presence, 16) + # Checking whether bit 0 is not set + if (~psu_presence & 0b1): + status = True + + return status + + def get_model(self): + """ + Retrieves the part number of the PSU + + Returns: + string: Part number of PSU + """ + # For Serial number "US-01234D-54321-25A-0123-A00", the part + # number is "01234D" + psu_serialno = self._get_pmc_register(self.psu_serialno_reg) + if (psu_serialno != 'ERR') and self.get_presence(): + if (len(psu_serialno.split('-')) > 1): + psu_partno = psu_serialno.split('-')[1] + else: + psu_partno = 'NA' + else: + psu_partno = 'NA' + + return psu_partno + + def get_serial(self): + """ + Retrieves the serial number of the PSU + + Returns: + string: Serial number of PSU + """ + # Sample Serial number format "US-01234D-54321-25A-0123-A00" + psu_serialno = self._get_pmc_register(self.psu_serialno_reg) + if (psu_serialno == 'ERR') or not self.get_presence(): + psu_serialno = 'NA' + + return psu_serialno + + def get_status(self): + """ + Retrieves the operational status of the PSU + + Returns: + bool: True if PSU is operating properly, False if not + """ + status = False + psu_status = self._get_pmc_register(self.psu_presence_reg) + if (psu_status != 'ERR'): + psu_status = int(psu_status, 16) + # Checking whether both bit 3 and bit 2 are not set + if (~psu_status & 0b1000) and (~psu_status & 0b0100): + 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 + """ + psu_voltage = self._get_pmc_register(self.psu_voltage_reg) + if (psu_voltage != 'ERR') and self.get_presence(): + # Converting the value returned by driver which is in + # millivolts to volts + psu_voltage = float(psu_voltage) / 1000 + else: + psu_voltage = 0.0 + + return psu_voltage + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, electric current in amperes, + e.g. 15.4 + """ + psu_current = self._get_pmc_register(self.psu_current_reg) + if (psu_current != 'ERR') and self.get_presence(): + # Converting the value returned by driver which is in + # milliamperes to amperes + psu_current = float(psu_current) / 1000 + else: + psu_current = 0.0 + + return psu_current + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, + e.g. 302.6 + """ + psu_power = self._get_pmc_register(self.psu_power_reg) + if (psu_power != 'ERR') and self.get_presence(): + # Converting the value returned by driver which is in + # microwatts to watts + psu_power = float(psu_power) / 1000000 + else: + psu_power = 0.0 + + return psu_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 + if self.get_status() and self._fan_list[0].get_status(): + status = True + + return status + + def get_status_led(self): + """ + Gets the state of the PSU status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + if self.get_powergood_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + + def set_status_led(self, color): + """ + Sets the state of the PSU status LED + Args: + color: A string representing the color with which to set the + PSU status LED + Returns: + bool: True if status LED state is set successfully, False if + not + """ + # In Z9100, SmartFusion FPGA controls the PSU LED and the PSU + # LED state cannot be changed from CPU. + return False diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py deleted file mode 120000 index 84af7963bb3d..000000000000 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py +++ /dev/null @@ -1 +0,0 @@ -../../s6100/sonic_platform/sfp.py \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py new file mode 100644 index 000000000000..87057545cbb7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py @@ -0,0 +1,882 @@ +#!/usr/bin/env python + +############################################################################# +# DELLEMC +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + import os + import time + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +PAGE_OFFSET = 0 +KEY_OFFSET = 1 +KEY_WIDTH = 2 +FUNC_NAME = 3 + +INFO_OFFSET = 128 +DOM_OFFSET = 0 +DOM_OFFSET1 = 384 + +cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)', + 'Length OM1(m)', 'Length Cable Assembly(m)') + +compliance_code_tup = ( + '10/40G Ethernet Compliance Code', + 'SONET Compliance codes', + 'SAS/SATA compliance codes', + 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', + 'Fibre Channel Speed') + +info_dict_keys = ['type', 'hardwarerev', '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': [DOM_OFFSET, 2, 1, 'parse_dom_status_indicator'], + 'rx_los': [DOM_OFFSET, 3, 1, 'parse_dom_tx_rx_los'], + 'tx_fault': [DOM_OFFSET, 4, 1, 'parse_dom_tx_fault'], + 'tx_disable': [DOM_OFFSET, 86, 1, 'parse_dom_tx_disable'], + 'power_lpmode': [DOM_OFFSET, 93, 1, 'parse_dom_power_control'], + 'power_override': [DOM_OFFSET, 93, 1, 'parse_dom_power_control'], + 'Temperature': [DOM_OFFSET, 22, 2, 'parse_temperature'], + 'Voltage': [DOM_OFFSET, 26, 2, 'parse_voltage'], + 'ChannelMonitor': [DOM_OFFSET, 34, 16, 'parse_channel_monitor_params'], + + 'cable_type': [INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], + 'cable_length': [INFO_OFFSET, -1, -1, 'parse_sfp_info_bulk'], + 'Connector': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'type': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'encoding': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'ext_identifier': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'ext_rateselect_compliance': + [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'nominal_bit_rate': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'specification_compliance': + [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'type_abbrv_name': [INFO_OFFSET, 0, 20, 'parse_sfp_info_bulk'], + 'manufacturename': [INFO_OFFSET, 20, 16, 'parse_vendor_name'], + 'vendor_oui': [INFO_OFFSET, 37, 3, 'parse_vendor_oui'], + 'modelname': [INFO_OFFSET, 40, 16, 'parse_vendor_pn'], + 'hardwarerev': [INFO_OFFSET, 56, 2, 'parse_vendor_rev'], + 'serialnum': [INFO_OFFSET, 68, 16, 'parse_vendor_sn'], + 'vendor_date': [INFO_OFFSET, 84, 8, 'parse_vendor_date'], + 'ModuleThreshold': [DOM_OFFSET1, 128, 24, 'parse_module_threshold_values'], + 'ChannelThreshold': [DOM_OFFSET1, 176, 16, 'parse_channel_threshold_values'], +} + + +class Sfp(SfpBase): + """ + DELLEMC Platform-specific Sfp class + """ + + def __init__(self, index, sfp_type, eeprom_path, + sfp_control, sfp_ctrl_idx): + SfpBase.__init__(self) + self.sfp_type = sfp_type + self.index = index + self.eeprom_path = eeprom_path + self.sfp_control = sfp_control + self.sfp_ctrl_idx = sfp_ctrl_idx + self.sfpInfo = sff8436InterfaceId() + self.sfpDomInfo = sff8436Dom() + + 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.sfpInfo is None): + return None + + 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): + eeprom_data = getattr( + self.sfpInfo, sff8436_parser[eeprom_key][FUNC_NAME])( + eeprom_data_raw, 0) + else: + eeprom_data = getattr( + self.sfpDomInfo, sff8436_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'] + bit_rate = str( + iface_data['data']['Nominal Bit Rate(100Mbs)']['value']) + type_abbrv_name=iface_data['data']['type_abbrv_name']['value'] + + for key in 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 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 (module_threshold_data is not None): + tempHighAlarm = module_threshold_data['data']['TempHighAlarm']['value'] + tempLowAlarm = module_threshold_data['data']['TempLowAlarm']['value'] + tempHighWarn = module_threshold_data['data']['TempHighWarning']['value'] + tempLowWarn = module_threshold_data['data']['TempLowWarning']['value'] + vccHighAlarm = module_threshold_data['data']['VccHighAlarm']['value'] + vccLowAlarm = module_threshold_data['data']['VccLowAlarm']['value'] + vccHighWarn = module_threshold_data['data']['VccHighWarning']['value'] + vccLowWarn = module_threshold_data['data']['VccLowWarning']['value'] + else: + return transceiver_dom_threshold_dict + + # Channel Threshold + channel_threshold_data = self._get_eeprom_data('ChannelThreshold') + if (channel_threshold_data is not None): + rxPowerHighAlarm = channel_threshold_data['data']['RxPowerHighAlarm']['value'] + rxPowerLowAlarm = channel_threshold_data['data']['RxPowerLowAlarm']['value'] + rxPowerHighWarn = channel_threshold_data['data']['RxPowerHighWarning']['value'] + rxPowerLowWarn = channel_threshold_data['data']['RxPowerLowWarning']['value'] + txBiasHighAlarm = channel_threshold_data['data']['TxBiasHighAlarm']['value'] + txBiasLowAlarm = channel_threshold_data['data']['TxBiasLowAlarm']['value'] + txBiasHighWarn = channel_threshold_data['data']['TxBiasHighWarning']['value'] + txBiasLowWarn = channel_threshold_data['data']['TxBiasLowWarning']['value'] + else: + return transceiver_dom_threshold_dict + + transceiver_dom_threshold_dict['temphighalarm'] = tempHighAlarm + transceiver_dom_threshold_dict['templowalarm'] = tempLowAlarm + transceiver_dom_threshold_dict['temphighwarning'] = tempHighWarn + transceiver_dom_threshold_dict['templowwarning'] = tempLowWarn + transceiver_dom_threshold_dict['vcchighalarm'] = vccHighAlarm + transceiver_dom_threshold_dict['vcclowalarm'] = vccLowAlarm + transceiver_dom_threshold_dict['vcchighwarning'] = vccHighWarn + transceiver_dom_threshold_dict['vcclowwarning'] = vccLowWarn + transceiver_dom_threshold_dict['rxpowerhighalarm'] = rxPowerHighAlarm + transceiver_dom_threshold_dict['rxpowerlowalarm'] = rxPowerLowAlarm + transceiver_dom_threshold_dict['rxpowerhighwarning'] = rxPowerHighWarn + transceiver_dom_threshold_dict['rxpowerlowwarning'] = rxPowerLowWarn + transceiver_dom_threshold_dict['txbiashighalarm'] = txBiasHighAlarm + transceiver_dom_threshold_dict['txbiaslowalarm'] = txBiasLowAlarm + transceiver_dom_threshold_dict['txbiashighwarning'] = txBiasHighWarn + transceiver_dom_threshold_dict['txbiaslowwarning'] = txBiasLowWarn + + 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 + channel_monitor_data = self._get_eeprom_data('ChannelMonitor') + if (channel_monitor_data is not None): + tx_bias = channel_monitor_data['data']['TX1Bias']['value'] + tx_bias_list.append(tx_bias) + tx_bias = channel_monitor_data['data']['TX2Bias']['value'] + tx_bias_list.append(tx_bias) + tx_bias = channel_monitor_data['data']['TX3Bias']['value'] + tx_bias_list.append(tx_bias) + tx_bias = channel_monitor_data['data']['TX4Bias']['value'] + tx_bias_list.append(tx_bias) + rx_power = channel_monitor_data['data']['RX1Power']['value'] + rx_power_list.append(rx_power) + rx_power = channel_monitor_data['data']['RX2Power']['value'] + rx_power_list.append(rx_power) + rx_power = channel_monitor_data['data']['RX3Power']['value'] + rx_power_list.append(rx_power) + rx_power = channel_monitor_data['data']['RX4Power']['value'] + rx_power_list.append(rx_power) + else: + return transceiver_dom_dict + + 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 + 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] + 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] + + 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 + """ + presence_ctrl = self.sfp_control + 'qsfp_modprs' + try: + reg_file = open(presence_ctrl) + except IOError as e: + return False + + reg_hex = reg_file.readline().rstrip() + + # content is a string containing the hex + # representation of the register + reg_value = int(reg_hex, 16) + + # Mask off the bit corresponding to our port + index = self.sfp_ctrl_idx + + # Mask off the bit corresponding to our port + mask = (1 << index) + + # 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): + """ + Retrieves the reset status of SFP + """ + reset_status = None + reset_ctrl = self.sfp_control + 'qsfp_reset' + try: + reg_file = open(reset_ctrl, "r+") + except IOError as e: + return False + + reg_hex = reg_file.readline().rstrip() + + # content is a string containing the hex + # representation of the register + reg_value = int(reg_hex, 16) + + # Mask off the bit corresponding to our port + index = self.sfp_ctrl_idx + + mask = (1 << index) + + 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 = [] + + 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 + + return rx_los + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + """ + tx_fault = None + tx_fault_list = [] + + tx_fault_data = self._get_eeprom_data('tx_fault') + if (tx_fault_data is not None): + tx_fault = tx_fault_data['data']['Tx1Fault']['value'] + if (tx_fault is 'On'): + 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 + + return tx_fault + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + """ + tx_disable = None + tx_disable_list = [] + + tx_disable_data = self._get_eeprom_data('tx_disable') + if (tx_disable_data is not None): + tx_disable = tx_disable_data['data']['Tx1Disable']['value'] + if (tx_disable is 'On'): + 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 + + 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_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) status of this SFP + """ + lpmode_ctrl = self.sfp_control + 'qsfp_lpmode' + try: + reg_file = open(lpmode_ctrl, "r+") + except IOError as e: + return False + + reg_hex = reg_file.readline().rstrip() + + # content is a string containing the hex + # representation of the register + reg_value = int(reg_hex, 16) + + # Mask off the bit corresponding to our port + index = self.sfp_ctrl_idx + + mask = (1 << index) + + 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 = None + + # Reset Status + 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): + 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) + + 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): + 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) + + return rx_power_list + + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + """ + tx_power = None + tx_power_list = [] + + tx_power_list.append('-infdBm') + tx_power_list.append('-infdBm') + tx_power_list.append('-infdBm') + tx_power_list.append('-infdBm') + + return tx_power_list + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + """ + reset_ctrl = self.sfp_control + 'qsfp_reset' + try: + # Open reset_ctrl in both read & write mode + reg_file = open(reset_ctrl, "r+") + except IOError as e: + return False + + reg_hex = reg_file.readline().rstrip() + reg_value = int(reg_hex, 16) + + # Mask off the bit corresponding to our port + index = self.sfp_ctrl_idx + + # Mask off the bit corresponding to our port + mask = (1 << index) + + # ResetL is active low + reg_value = (reg_value & ~mask) + + # Convert our register value back to a + # hex string and write back + reg_file.seek(0) + reg_file.write(hex(reg_value)) + 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(reset_ctrl, "w") + except IOError as e: + return False + + reg_value = reg_value | mask + reg_file.seek(0) + reg_file.write(hex(reg_value)) + reg_file.close() + + return True + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + """ + lpmode_ctrl = self.sfp_control + 'qsfp_lpmode' + try: + reg_file = open(lpmode_ctrl, "r+") + except IOError as e: + return False + + reg_hex = reg_file.readline().rstrip() + + # content is a string containing the hex + # representation of the register + reg_value = int(reg_hex, 16) + + # Mask off the bit corresponding to our port + index = self.sfp_ctrl_idx + + mask = (1 << index) + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + reg_value = (reg_value | mask) + else: + reg_value = (reg_value & ~mask) + + # Convert our register value back to a hex string and write back + content = hex(reg_value) + + reg_file.seek(0) + reg_file.write(content) + reg_file.close() + + return True + + 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 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/z9100/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/thermal.py new file mode 100644 index 000000000000..05d012b114c0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/thermal.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC Z9100 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Thermals' information which are available in the platform +# +######################################################################## + + +try: + import os + from sonic_platform_base.thermal_base import ThermalBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Thermal(ThermalBase): + """DellEMC Platform-specific Thermal class""" + + THERMAL_NAME = ( + 'CPU On-board', 'ASIC On-board Rear', 'System Front Left', + 'System Front Right', 'CPU Core 0', 'CPU Core 1', 'CPU Core 2', + 'CPU Core 3' + ) + + def __init__(self, thermal_index): + self.is_cpu_thermal = False + self.index = thermal_index + 1 + + if self.index < 5: + hwmon_temp_index = self.index + dev_path = "/sys/devices/platform/SMF.512/hwmon/" + else: + hwmon_temp_index = self.index - 3 + self.is_cpu_thermal = True + dev_path = "/sys/devices/platform/coretemp.0/hwmon/" + + hwmon_node = os.listdir(dev_path)[0] + self.HWMON_DIR = dev_path + hwmon_node + '/' + + self.thermal_status_file = self.HWMON_DIR \ + + "temp{}_alarm".format(hwmon_temp_index) + self.thermal_temperature_file = self.HWMON_DIR \ + + "temp{}_input".format(hwmon_temp_index) + self.thermal_high_threshold_file = self.HWMON_DIR \ + + "temp{}_crit".format(hwmon_temp_index) + self.thermal_low_threshold_file = self.HWMON_DIR \ + + "temp{}_min".format(hwmon_temp_index) + + def _read_sysfs_file(self, sysfs_file): + # On successful read, returns the value read from given + # sysfs_file and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(sysfs_file)): + return rv + + try: + with open(sysfs_file, 'r') as fd: + rv = fd.read() + except Exception as error: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def get_name(self): + """ + Retrieves the name of the thermal + + Returns: + string: The name of the thermal + """ + return self.THERMAL_NAME[self.index - 1] + + def get_presence(self): + """ + Retrieves the presence of the thermal + + Returns: + bool: True if thermal is present, False if not + """ + 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 + """ + status = False + if self.is_cpu_thermal: + status = True + else: + thermal_status = self._read_sysfs_file(self.thermal_status_file) + if (thermal_status != 'ERR'): + thermal_status = int(thermal_status, 16) + if thermal_status != 5: + status = True + + return status + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + Returns: + A float number of current temperature in Celsius up to + nearest thousandth of one degree Celsius, e.g. 30.125 + """ + thermal_temperature = self._read_sysfs_file( + self.thermal_temperature_file) + if (thermal_temperature != 'ERR'): + thermal_temperature = float(thermal_temperature) / 1000 + else: + thermal_temperature = 0 + + return "{:.3f}".format(thermal_temperature) + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + + Returns: + A float number, the high threshold temperature of thermal in + Celsius up to nearest thousandth of one degree Celsius, + e.g. 30.125 + """ + thermal_high_threshold = self._read_sysfs_file( + self.thermal_high_threshold_file) + if (thermal_high_threshold != 'ERR'): + thermal_high_threshold = float(thermal_high_threshold) / 1000 + else: + thermal_high_threshold = 0 + + return "{:.3f}".format(thermal_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 + """ + 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 + else: + thermal_low_threshold = 0 + + return "{:.3f}".format(thermal_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/z9264f/modules/dell_z9264f_fpga_ocores.c b/platform/broadcom/sonic-platform-modules-dell/z9264f/modules/dell_z9264f_fpga_ocores.c index d3a4a51ead72..c1644ecf705d 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/modules/dell_z9264f_fpga_ocores.c +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/modules/dell_z9264f_fpga_ocores.c @@ -205,6 +205,7 @@ enum { STATE_START, STATE_WRITE, STATE_READ, + STATE_STOP, STATE_ERROR, }; @@ -591,10 +592,13 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) PRINT("fpgai2c_process in. status reg :0x%x\n", stat); - if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) { + if ((i2c->state == STATE_STOP) || (i2c->state == STATE_ERROR)) { /* stop has been sent */ PRINT("fpgai2c_process FPGAI2C_REG_CMD_IACK stat = 0x%x Set FPGAI2C_REG_CMD(0%x) FPGAI2C_REG_CMD_IACK = 0x%x\n",stat, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + if(i2c->state == STATE_STOP) { + i2c->state = STATE_DONE; + } wake_up(&i2c->wait); return; } @@ -648,7 +652,7 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) ? STATE_READ : STATE_WRITE; } } else { - i2c->state = STATE_DONE; + i2c->state = STATE_STOP; fpgai2c_stop(i2c); return; } @@ -722,6 +726,7 @@ static int fpgai2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) } else { + ret = -ETIMEDOUT; PRINT("Set FPGAI2C_REG_DATA(0%x) val = 0x%x\n",FPGAI2C_REG_DATA, (i2c->msg->addr << 1) | ((i2c->msg->flags & I2C_M_RD) ? 1:0)); @@ -733,9 +738,8 @@ static int fpgai2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) /* Interrupt mode */ if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) || (i2c->state == STATE_DONE), HZ)) - return (i2c->state == STATE_DONE) ? num : -EIO; - else - return -ETIMEDOUT; + ret = (i2c->state == STATE_DONE) ? num : -EIO; + return ret; } } diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh index 880ba98abb1f..3435704a65cb 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh @@ -58,7 +58,7 @@ switch_board_qsfp() { "new_device") for ((i=2;i<=65;i++)); do - echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 done ;; @@ -74,6 +74,29 @@ switch_board_qsfp() { esac } +#Attach/Detach 2 instances of EEPROM driver SFP+ ports +#eeprom can dump data using below command +switch_board_sfp() { + case $1 in + "new_device") + for ((i=66;i<=67;i++)); + do + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + "delete_device") + for ((i=66;i<=67;i++)); + do + echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + *) echo "z9264f_platform: switch_board_sfp: invalid command !" + ;; + esac +} + #Modsel 64 ports to applicable QSFP type modules #This enables the adapter to respond for i2c commands switch_board_modsel() { @@ -85,6 +108,23 @@ switch_board_modsel() { python /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 done } + +# Copy led_proc_init.soc file according to the HWSKU +init_switch_port_led() { + device="/usr/share/sonic/device" + platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) + hwsku=$(cat /etc/sonic/config_db.json | grep -A10 "DEVICE_METADATA" | grep "hwsku" | cut -d ":" -f2 | sed 's/"//g' | sed 's/,//g'| xargs ) + + led_proc_init="$device/$platform/$hwsku/led_proc_init.soc" + + # Remove old HWSKU LED file.. + rm -rf $device/$platform/led_proc_init.soc + + if [ -e $led_proc_init ] && [ ! -e $device/$platform/led_proc_init.soc ]; then + cp $led_proc_init $device/$platform/ + fi +} + init_devnum if [ "$1" == "init" ]; then @@ -97,14 +137,16 @@ if [ "$1" == "init" ]; then sys_eeprom "new_device" switch_board_qsfp_mux "new_device" switch_board_qsfp "new_device" + switch_board_sfp "new_device" switch_board_modsel + init_switch_port_led python /usr/bin/qsfp_irq_enable.py elif [ "$1" == "deinit" ]; then sys_eeprom "delete_device" switch_board_qsfp "delete_device" switch_board_qsfp_mux "delete_device" - + switch_board_sfp "delete_device" modprobe -r i2c-mux-pca954x modprobe -r i2c-dev else 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 e9baeb928faf..85719af7ea94 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 @@ -566,53 +566,53 @@ static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, mutex_lock(&dni_lock); switch (attr->index) { case SFP_IS_PRESENT: - /*QSFP1~8*/ - ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_PRESENCE_1); - data = (u32)(reverse_8bits(ret) & 0xff); - /*QSFP9~16*/ - ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_PRESENCE_2); - data |= (u32)(reverse_8bits(ret) & 0xff) << 8; - /*QSFP17~24*/ - ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_PRESENCE_3); - data |= (u32)(reverse_8bits(ret) & 0xff) << 16; /*QSFP25~32*/ ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_PRESENCE_4); - data |= (u32)(reverse_8bits(ret) & 0xff) << 24; + data = (u32)ret & 0xff; + /*QSFP17~24*/ + ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_PRESENCE_3); + data |= ((u32)ret & 0xff) << 8; + /*QSFP9~16*/ + ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_PRESENCE_2); + data |= (u32)(ret & 0xff) << 16; + /*QSFP1~8*/ + ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_PRESENCE_1); + data |= (u32)(ret & 0xff) << 24; ret = i2c_smbus_read_byte_data(pdata2[swpld2].client, SFP_PRESENCE_5); - ret_sfp = (ret & (0x80)) >> 7; + ret_sfp = (ret & (0x80)); mutex_unlock(&dni_lock); - return sprintf(buf, "0x%x%x\n", ret_sfp, data); + return sprintf(buf, "0x%x%02x\n", data, ret_sfp); case QSFP_LPMODE: - /*QSFP1~8*/ - ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_LPMODE_1); - data = (u32)(reverse_8bits(ret) & 0xff); - /*QSFP9~16*/ - ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_LPMODE_2); - data |= (u32)(reverse_8bits(ret) & 0xff) << 8; - /*QSFP17~24*/ - ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_LPMODE_3); - data |= (u32)(reverse_8bits(ret) & 0xff) << 16; /*QSFP25~32*/ ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_LPMODE_4); - data |= (u32)(reverse_8bits(ret) & 0xff) << 24; + data = (u32)(ret & 0xff); + /*QSFP17~24*/ + ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_LPMODE_3); + data |= (u32)(ret & 0xff) << 8; + /*QSFP9~16*/ + ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_LPMODE_2); + data |= (u32)(ret & 0xff) << 16; + /*QSFP1~8*/ + ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_LPMODE_1); + data |= (u32)(ret & 0xff) << 24; mutex_unlock(&dni_lock); return sprintf(buf, "0x%x\n", data); case QSFP_RESET: - /*QSFP1~8*/ - ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_RESET_1); - data = (u32)(reverse_8bits(ret) & 0xff); - /*QSFP9~16*/ - ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_RESET_2); - data |= (u32)(reverse_8bits(ret) & 0xff) << 8; - /*QSFP17~24*/ - ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_RESET_3); - data |= (u32)(reverse_8bits(ret) & 0xff) << 16; /*QSFP25~32*/ ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_RESET_4); - data |= (u32)(reverse_8bits(ret) & 0xff) << 24; + data = (u32)(ret & 0xff); + /*QSFP17~24*/ + ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_RESET_3); + data |= (u32)(ret & 0xff) << 8; + /*QSFP9~16*/ + ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_RESET_2); + data |= (u32)(ret & 0xff) << 16; + /*QSFP1~8*/ + ret = i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_RESET_1); + data |= (u32)(ret & 0xff) << 24; mutex_unlock(&dni_lock); return sprintf(buf, "0x%x\n", data); @@ -628,6 +628,7 @@ static ssize_t set_lpmode_data(struct device *dev, struct device_attribute *dev_ struct cpld_platform_data *pdata = i2cdev->platform_data; unsigned long long set_data; int err; + int status = 0; unsigned char set_bytes; @@ -636,24 +637,45 @@ static ssize_t set_lpmode_data(struct device *dev, struct device_attribute *dev_ return err; } mutex_lock(&dni_lock); - /*QSFP1~8*/ - set_bytes = reverse_8bits(set_data & 0xff); - i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_LPMODE_1, set_bytes); + /*QSFP25~32*/ + set_bytes = set_data & 0xff; + status = i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_LPMODE_4, set_bytes); + if(status < 0) + { + goto ERROR; + } + + /*QSFP17~24*/ + set_bytes = (set_data >> 8 ) & 0xff; + status = i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_LPMODE_3, set_bytes); + if(status < 0) + { + goto ERROR; + } /*QSFP9~16*/ - set_bytes = reverse_8bits((set_data >> 8 ) & 0xff); - i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_LPMODE_2, set_bytes); + set_bytes = (set_data >> 16 ) & 0xff; + status = i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_LPMODE_2, set_bytes); + if(status < 0) + { + goto ERROR; + } - /*QSFP17~24*/ - set_bytes = reverse_8bits((set_data >> 16 ) & 0xff); - i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_LPMODE_3, set_bytes); + /*QSFP1~8*/ + set_bytes = (set_data >> 24 ) & 0xff; + status = i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_LPMODE_1, set_bytes); + if(status < 0) + { + goto ERROR; + } - /*QSFP25~32*/ - set_bytes = reverse_8bits((set_data >> 24 ) & 0xff); - i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_LPMODE_4, set_bytes); mutex_unlock(&dni_lock); return count; +ERROR: + mutex_unlock(&dni_lock); + return status; + } static ssize_t set_reset_data(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count) @@ -662,6 +684,7 @@ static ssize_t set_reset_data(struct device *dev, struct device_attribute *dev_a struct cpld_platform_data *pdata = i2cdev->platform_data; unsigned long long set_data; int err; + int status = 0; unsigned char set_bytes; err = kstrtoull(buf, 16, &set_data); @@ -670,23 +693,43 @@ static ssize_t set_reset_data(struct device *dev, struct device_attribute *dev_a } mutex_lock(&dni_lock); - /*QSFP1~8*/ - set_bytes = reverse_8bits(set_data & 0xff); - i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_RESET_1, set_bytes); + /*QSFP25~32*/ + set_bytes = set_data & 0xff; + status = i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_RESET_4, set_bytes); + if(status < 0) + { + goto ERROR; + } + + /*QSFP17~24*/ + set_bytes = (set_data >> 8 ) & 0xff; + status = i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_RESET_3, set_bytes); + if(status < 0) + { + goto ERROR; + } /*QSFP9~16*/ - set_bytes = reverse_8bits((set_data >> 8 ) & 0xff); - i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_RESET_2, set_bytes); + set_bytes = (set_data >> 16 ) & 0xff; + status = i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_RESET_2, set_bytes); + if(status < 0) + { + goto ERROR; + } - /*QSFP17~24*/ - set_bytes = reverse_8bits((set_data >> 16 ) & 0xff); - i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_RESET_3, set_bytes); + /*QSFP1~8*/ + set_bytes = (set_data >> 24 ) & 0xff; + status = i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_RESET_1, set_bytes); + if(status < 0) + { + goto ERROR; + } - /*QSFP25~32*/ - set_bytes = reverse_8bits((set_data >> 24 ) & 0xff); - i2c_smbus_write_byte_data(pdata[swpld1].client, QSFP_RESET_4, set_bytes); mutex_unlock(&dni_lock); return count; +ERROR: + mutex_unlock(&dni_lock); + return status; } diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_common.h b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_common.h index da9175088786..40eba7e241a3 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_common.h +++ b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_common.h @@ -148,14 +148,12 @@ enum cpld_attributes { MB_ID, MB_VER, CPU0_PWR_OK, - PSU_OVER_TEMP, PWR_RAIL_OVER_TEMP, CPU_DISOMIC_OVER_TEMP, DDR_OVER_TEMP, CPLD_PWR_ON_RST, CPLD_HARD_RST, CPLD_RST, - MB_PWR, MB_RST, PSU_FAN_INT, OP_MODULE_INT, @@ -167,9 +165,6 @@ enum cpld_attributes { PSU1_INT, PSU2_PWR_OK, PSU2_INT, - SYNCE_INT, - SYNCE_RST, - SYNCE_EEPROM_WP, PSU1_GREEN_LED, PSU1_RED_LED, PSU2_GREEN_LED, @@ -192,18 +187,10 @@ enum cpld_attributes { SB_VER, PLATFORM_TYPE, //SWPLD4 - SWPLD4_MAJOR_VER, - SWPLD4_MINOR_VER, - SWPLD4_SCRTCH_REG, - BMC_RST, - CPLD_LPC_RST, - CPLD_SW_RST, - MB_CPLD_RST, - BCM56970_RST, - CPLD_UPGRADE_RST, - MB_RST_CPLD, - CPU_RST_MB_OOB, - GPIO_PHY_RST, + SW_BOARD_ID1, + SW_BOARD_ID2, + SWBD_VER, + SWPLD4_VER, PSU_FAN_EVENT, CPU_THERMAL_INT, FAN_INT, @@ -334,11 +321,6 @@ static struct cpld_attribute_data attribute_data[] = { .reg = 0x08, .mask = 1 << 3, .note = "“1†=Power rail is good\n“0†= Power rail is failed" }, - [PSU_OVER_TEMP] = { - .bus = BUS0, .addr = CPUPLD_ADDR, - .reg = 0x0b, .mask = 1 << 4, - .note = "“1†= Not over temperature\n“0†= Over temperature" - }, [PWR_RAIL_OVER_TEMP] = { .bus = BUS0, .addr = CPUPLD_ADDR, .reg = 0x0b, .mask = 1 << 3, @@ -369,11 +351,6 @@ static struct cpld_attribute_data attribute_data[] = { .reg = 0x11, .mask = 1 << 0, .note = "“0†= Reset\n“1†= Normal operation" }, - [MB_PWR] = { - .bus = BUS0, .addr = CPUPLD_ADDR, - .reg = 0x12, .mask = 1 << 2, - .note = "“0†= Power rail is failed\n“1†=Power rail is good" - }, [MB_RST] = { .bus = BUS0, .addr = CPUPLD_ADDR, .reg = 0x12, .mask = 1 << 0, @@ -425,21 +402,6 @@ static struct cpld_attribute_data attribute_data[] = { .reg = 0x02, .mask = 1 << 1, .note = "‘0’ = Interrupt doesn’t occur\n‘1’ = Interrupt occurs" }, - [SYNCE_INT] = { - .bus = BUS0, .addr = SWPLD1_ADDR, - .reg = 0x12, .mask = 1 << 7, - .note = "‘0’ = Interrupt occurs\n‘1’ = Interrupt doesn’t occur" - }, - [SYNCE_RST] = { - .bus = BUS0, .addr = SWPLD1_ADDR, - .reg = 0x12, .mask = 1 << 6, - .note = "“0†= Reset\n“1†= Normal operation" - }, - [SYNCE_EEPROM_WP] = { - .bus = BUS0, .addr = SWPLD1_ADDR, - .reg = 0x12, .mask = 1 << 5, - .note = "“1†= enables the lock-down mechanism.\n“0†= overrides the lock-down function enabling blocks to be erased or programmed using software commands." - }, [PSU1_GREEN_LED] = { .bus = BUS0, .addr = SWPLD1_ADDR, .reg = 0x13, .mask = 1 << 7, @@ -538,65 +500,25 @@ static struct cpld_attribute_data attribute_data[] = { .note = "“0x0â€: 64X100G_2U\n“0x1â€~â€0xF†Reserved" }, //SWPLD4 - [SWPLD4_MAJOR_VER] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x00, .mask = 0xF0, - .note = "CPLD Major Version, controlled by CPLD editor." - }, - [SWPLD4_MINOR_VER] = { + [SW_BOARD_ID1] = { .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x00, .mask = 0x0F, - .note = "CPLD Minor Version, controlled by CPLD editor." + .reg = 0x00, .mask = 0xFF, + .note = "0x00" }, - [SWPLD4_SCRTCH_REG] = { + [SW_BOARD_ID2] = { .bus = BUS0, .addr = SWPLD4_ADDR, .reg = 0x01, .mask = 0xFF, - .note = "CPLD read/write test register, to provide a way to test CPLD access." - }, - [BMC_RST] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x02, .mask = 1 << 6, - .note = "“0†= Reset\n“1†= Normal operation" + .note = "Configured by PLD Editor\n0x03: AG9064" }, - [CPLD_LPC_RST] = { + [SWBD_VER] = { .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x02, .mask = 1 << 5, - .note = "“0†= Reset\n“1†= Normal operation" - }, - [CPLD_SW_RST] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x02, .mask = 1 << 3, - .note = "“0†= Reset\n“1†= Normal operation" - }, - [MB_CPLD_RST] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x02, .mask = 1 << 2, - .note = "“0†= Reset\n“1†= Normal operation" - }, - [BCM56970_RST] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x02, .mask = 1 << 1, - .note = "“0†= Reset\n“1†= Normal operation" - }, - [CPLD_UPGRADE_RST] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x03, .mask = 1 << 7, - .note = "“0†= Reset\n“1†= Normal operation" - }, - [MB_RST_CPLD] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x03, .mask = 1 << 6, - .note = "“0†= Reset\n“1†= Normal operation" - }, - [CPU_RST_MB_OOB] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x03, .mask = 1 << 5, - .note = "“0†= Reset\n“1†= Normal operation" + .reg = 0x02, .mask = 0xFF, + .note = "Configured by external resistor\n0x01:EVT1\n0x02:EVT2\n0x03:EVT3\n0x04:EVT4\n0x10:DVT\n0x20:PVT" }, - [GPIO_PHY_RST] = { + [SWPLD4_VER] = { .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x03, .mask = 1 << 4, - .note = "“0†= Reset\n“1†= Normal operation" + .reg = 0x03, .mask = 0xFF, + .note = "-" }, [PSU_FAN_EVENT] = { .bus = BUS0, .addr = SWPLD4_ADDR, diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_cpld.c b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_cpld.c index 75bab55d7e2c..a1c275209b05 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_cpld.c +++ b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_cpld.c @@ -772,14 +772,12 @@ static SENSOR_DEVICE_ATTR(cpu_id, S_IRUGO, get_cpld_reg, NU static SENSOR_DEVICE_ATTR(mb_id, S_IRUGO, get_cpld_reg, NULL, MB_ID); static SENSOR_DEVICE_ATTR(mb_ver, S_IRUGO, get_cpld_reg, NULL, MB_VER); static SENSOR_DEVICE_ATTR(cpu0_pwr_ok, S_IRUGO, get_cpld_reg, NULL, CPU0_PWR_OK); -static SENSOR_DEVICE_ATTR(psu_over_temp, S_IRUGO, get_cpld_reg, NULL, PSU_OVER_TEMP); static SENSOR_DEVICE_ATTR(pwr_rail_over_temp, S_IRUGO, get_cpld_reg, NULL, PWR_RAIL_OVER_TEMP); static SENSOR_DEVICE_ATTR(cpu_disomic_over_temp, S_IRUGO, get_cpld_reg, NULL, CPU_DISOMIC_OVER_TEMP); static SENSOR_DEVICE_ATTR(ddr_over_temp, S_IRUGO, get_cpld_reg, NULL, DDR_OVER_TEMP); static SENSOR_DEVICE_ATTR(cpld_pwr_on_rst, S_IRUGO, get_cpld_reg, NULL, CPLD_PWR_ON_RST); static SENSOR_DEVICE_ATTR(cpld_hard_rst, S_IRUGO, get_cpld_reg, NULL, CPLD_HARD_RST); static SENSOR_DEVICE_ATTR(cpld_rst, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, CPLD_RST); -static SENSOR_DEVICE_ATTR(mb_pwr, S_IRUGO, get_cpld_reg, NULL, MB_PWR); static SENSOR_DEVICE_ATTR(mb_rst, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, MB_RST); static SENSOR_DEVICE_ATTR(psu_fan_int, S_IRUGO, get_cpld_reg, NULL, PSU_FAN_INT); static SENSOR_DEVICE_ATTR(op_module_int, S_IRUGO, get_cpld_reg, NULL, OP_MODULE_INT); @@ -800,14 +798,12 @@ static struct attribute *ag9064_cpld_attrs[] = { &sensor_dev_attr_mb_id.dev_attr.attr, &sensor_dev_attr_mb_ver.dev_attr.attr, &sensor_dev_attr_cpu0_pwr_ok.dev_attr.attr, - &sensor_dev_attr_psu_over_temp.dev_attr.attr, &sensor_dev_attr_pwr_rail_over_temp.dev_attr.attr, &sensor_dev_attr_cpu_disomic_over_temp.dev_attr.attr, &sensor_dev_attr_ddr_over_temp.dev_attr.attr, &sensor_dev_attr_cpld_pwr_on_rst.dev_attr.attr, &sensor_dev_attr_cpld_hard_rst.dev_attr.attr, &sensor_dev_attr_cpld_rst.dev_attr.attr, - &sensor_dev_attr_mb_pwr.dev_attr.attr, &sensor_dev_attr_mb_rst.dev_attr.attr, &sensor_dev_attr_psu_fan_int.dev_attr.attr, &sensor_dev_attr_op_module_int.dev_attr.attr, diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_swpld.c b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_swpld.c index 084f0c74f245..fd17a28378aa 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_swpld.c +++ b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_swpld.c @@ -110,7 +110,7 @@ static ssize_t get_swpld_reg(struct device *dev, struct device_attribute *dev_at case SWPLD3_MAJOR_VER ... PLATFORM_TYPE : cmd_data[1] = SWPLD3_ADDR; break; - case SWPLD4_MAJOR_VER ... FAN_EEPROM_WP : + case SW_BOARD_ID1 ... FAN_EEPROM_WP : cmd_data[1] = SWPLD4_ADDR; break; default: @@ -244,7 +244,7 @@ static ssize_t set_swpld_reg(struct device *dev, struct device_attribute *dev_at case SWPLD3_MAJOR_VER ... PLATFORM_TYPE://SWPLD3 cmd_data[1] = SWPLD3_ADDR; break; - case SWPLD4_MAJOR_VER ... FAN_EEPROM_WP://SWPLD4 + case SW_BOARD_ID1 ... FAN_EEPROM_WP://SWPLD4 cmd_data[1] = SWPLD4_ADDR; break; default: @@ -303,9 +303,6 @@ static SENSOR_DEVICE_ATTR(psu1_pwr_ok, S_IRUGO, get_swpld_reg, N static SENSOR_DEVICE_ATTR(psu1_int, S_IRUGO, get_swpld_reg, NULL, PSU1_INT); static SENSOR_DEVICE_ATTR(psu2_pwr_ok, S_IRUGO, get_swpld_reg, NULL, PSU2_PWR_OK); static SENSOR_DEVICE_ATTR(psu2_int, S_IRUGO, get_swpld_reg, NULL, PSU2_INT); -static SENSOR_DEVICE_ATTR(synce_int, S_IRUGO, get_swpld_reg, NULL, SYNCE_INT); -static SENSOR_DEVICE_ATTR(synce_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SYNCE_RST); -static SENSOR_DEVICE_ATTR(synce_eeprom_wp, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SYNCE_EEPROM_WP); static SENSOR_DEVICE_ATTR(psu1_green_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, PSU1_GREEN_LED); static SENSOR_DEVICE_ATTR(psu1_red_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, PSU1_RED_LED); static SENSOR_DEVICE_ATTR(psu2_green_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, PSU2_GREEN_LED); @@ -329,29 +326,19 @@ static SENSOR_DEVICE_ATTR(sb_ver, S_IRUGO, get_swpld_reg, N static SENSOR_DEVICE_ATTR(platform_type, S_IRUGO, get_swpld_reg, NULL, PLATFORM_TYPE); //SWPLD4 -static SENSOR_DEVICE_ATTR(swpld4_major_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD4_MAJOR_VER); -static SENSOR_DEVICE_ATTR(swpld4_minor_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD4_MINOR_VER); -static SENSOR_DEVICE_ATTR(swpld4_scrtch_reg, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD4_SCRTCH_REG); -static SENSOR_DEVICE_ATTR(bmc_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, BMC_RST); -static SENSOR_DEVICE_ATTR(cpld_lpc_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, CPLD_LPC_RST); -static SENSOR_DEVICE_ATTR(cpld_sw_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, CPLD_SW_RST); -static SENSOR_DEVICE_ATTR(mb_cpld_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, MB_CPLD_RST); -static SENSOR_DEVICE_ATTR(bcm56970_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, BCM56970_RST); - -static SENSOR_DEVICE_ATTR(cpld_upgrade_rst, S_IRUGO, get_swpld_reg, NULL, CPLD_UPGRADE_RST); -static SENSOR_DEVICE_ATTR(mb_rst_cpld, S_IRUGO, get_swpld_reg, NULL, MB_RST_CPLD); -static SENSOR_DEVICE_ATTR(cpu_rst_mb_oob, S_IRUGO, get_swpld_reg, NULL, CPU_RST_MB_OOB); -static SENSOR_DEVICE_ATTR(gpio_phy_rst, S_IRUGO, get_swpld_reg, NULL, GPIO_PHY_RST); -static SENSOR_DEVICE_ATTR(psu_fan_event, S_IRUGO, get_swpld_reg, NULL, PSU_FAN_EVENT); -static SENSOR_DEVICE_ATTR(cpu_thermal_int, S_IRUGO, get_swpld_reg, NULL, CPU_THERMAL_INT); -static SENSOR_DEVICE_ATTR(fan_int, S_IRUGO, get_swpld_reg, NULL, FAN_INT); - -static SENSOR_DEVICE_ATTR(cpld_spi_wp, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, CPLD_SPI_WP); -static SENSOR_DEVICE_ATTR(rj45_console_sel, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, RJ45_CONSOLE_SEL); -static SENSOR_DEVICE_ATTR(system_int, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SYSTEM_INT); -static SENSOR_DEVICE_ATTR(cpld_mb_rst_done, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, CPLD_MB_RST_DONE); -static SENSOR_DEVICE_ATTR(mb_pwr_ok, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, MB_PWR_OK); -static SENSOR_DEVICE_ATTR(fan_eeprom_wp, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, FAN_EEPROM_WP); +static SENSOR_DEVICE_ATTR(sw_board_id1, S_IRUGO, get_swpld_reg, NULL, SW_BOARD_ID1); +static SENSOR_DEVICE_ATTR(sw_board_id2, S_IRUGO, get_swpld_reg, NULL, SW_BOARD_ID2); +static SENSOR_DEVICE_ATTR(swbd_ver, S_IRUGO, get_swpld_reg, NULL, SWBD_VER); +static SENSOR_DEVICE_ATTR(swpld4_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD4_VER); +static SENSOR_DEVICE_ATTR(psu_fan_event, S_IRUGO, get_swpld_reg, NULL, PSU_FAN_EVENT); +static SENSOR_DEVICE_ATTR(cpu_thermal_int, S_IRUGO, get_swpld_reg, NULL, CPU_THERMAL_INT); +static SENSOR_DEVICE_ATTR(fan_int, S_IRUGO, get_swpld_reg, NULL, FAN_INT); +static SENSOR_DEVICE_ATTR(cpld_spi_wp, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, CPLD_SPI_WP); +static SENSOR_DEVICE_ATTR(rj45_console_sel, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, RJ45_CONSOLE_SEL); +static SENSOR_DEVICE_ATTR(system_int, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SYSTEM_INT); +static SENSOR_DEVICE_ATTR(cpld_mb_rst_done, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, CPLD_MB_RST_DONE); +static SENSOR_DEVICE_ATTR(mb_pwr_ok, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, MB_PWR_OK); +static SENSOR_DEVICE_ATTR(fan_eeprom_wp, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, FAN_EEPROM_WP); static struct attribute *swpld1_device_attrs[] = { &sensor_dev_attr_swpld1_reg_value.dev_attr.attr, @@ -363,9 +350,6 @@ static struct attribute *swpld1_device_attrs[] = { &sensor_dev_attr_psu1_int.dev_attr.attr, &sensor_dev_attr_psu2_pwr_ok.dev_attr.attr, &sensor_dev_attr_psu2_int.dev_attr.attr, - &sensor_dev_attr_synce_int.dev_attr.attr, - &sensor_dev_attr_synce_rst.dev_attr.attr, - &sensor_dev_attr_synce_eeprom_wp.dev_attr.attr, &sensor_dev_attr_psu1_green_led.dev_attr.attr, &sensor_dev_attr_psu1_red_led.dev_attr.attr, &sensor_dev_attr_psu2_green_led.dev_attr.attr, @@ -401,20 +385,10 @@ static struct attribute *swpld3_device_attrs[] = { }; static struct attribute *swpld4_device_attrs[] = { - &sensor_dev_attr_swpld4_reg_value.dev_attr.attr, - &sensor_dev_attr_swpld4_reg_addr.dev_attr.attr, - &sensor_dev_attr_swpld4_major_ver.dev_attr.attr, - &sensor_dev_attr_swpld4_minor_ver.dev_attr.attr, - &sensor_dev_attr_swpld4_scrtch_reg.dev_attr.attr, - &sensor_dev_attr_bmc_rst.dev_attr.attr, - &sensor_dev_attr_cpld_lpc_rst.dev_attr.attr, - &sensor_dev_attr_cpld_sw_rst.dev_attr.attr, - &sensor_dev_attr_mb_cpld_rst.dev_attr.attr, - &sensor_dev_attr_bcm56970_rst.dev_attr.attr, - &sensor_dev_attr_cpld_upgrade_rst.dev_attr.attr, - &sensor_dev_attr_mb_rst_cpld.dev_attr.attr, - &sensor_dev_attr_cpu_rst_mb_oob.dev_attr.attr, - &sensor_dev_attr_gpio_phy_rst.dev_attr.attr, + &sensor_dev_attr_sw_board_id1.dev_attr.attr, + &sensor_dev_attr_sw_board_id2.dev_attr.attr, + &sensor_dev_attr_swbd_ver.dev_attr.attr, + &sensor_dev_attr_swpld4_ver.dev_attr.attr, &sensor_dev_attr_psu_fan_event.dev_attr.attr, &sensor_dev_attr_cpu_thermal_int.dev_attr.attr, &sensor_dev_attr_fan_int.dev_attr.attr, diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9064.postinst b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9064.postinst new file mode 100644 index 000000000000..6044de232776 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9064.postinst @@ -0,0 +1,19 @@ +# postinst script for ag9064 + +# Insert kernel module +depmod -a +modprobe i2c-dev +modprobe i2c-i801 +modprobe i2c-ismt +modprobe ipmi_devintf +modprobe ipmi_si ports=0xca2 +modprobe i2c-mei +modprobe i2c-mux-pca954x +modprobe at24 +modprobe optoe +modprobe delta_ag9064_platform +modprobe delta_ag9064_cpld +modprobe delta_ag9064_swpld + +#DEBHELPER# + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/Makefile b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/Makefile new file mode 100755 index 000000000000..6c1acbc88a71 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/Makefile @@ -0,0 +1,9 @@ +obj-m += ucd9000.o +obj-m += i2c-mux-pca9541.o +obj-m += gpio-ich.o +obj-m += lpc_ich.o +obj-m += inv_cpld.o +obj-m += inv_platform.o +obj-m += inv_eeprom.o +obj-m += swps.o +swps-objs := inv_swps.o inv_mux.o io_expander.o transceiver.o diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/gpio-ich.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/gpio-ich.c new file mode 100644 index 000000000000..4f6d643516b7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/gpio-ich.c @@ -0,0 +1,513 @@ +/* + * Intel ICH6-10, Series 5 and 6, Atom C2000 (Avoton/Rangeley) GPIO driver + * + * Copyright (C) 2010 Extreme Engineering Solutions. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "gpio_ich" + +/* + * GPIO register offsets in GPIO I/O space. + * Each chunk of 32 GPIOs is manipulated via its own USE_SELx, IO_SELx, and + * LVLx registers. Logic in the read/write functions takes a register and + * an absolute bit number and determines the proper register offset and bit + * number in that register. For example, to read the value of GPIO bit 50 + * the code would access offset ichx_regs[2(=GPIO_LVL)][1(=50/32)], + * bit 18 (50%32). + */ +enum GPIO_REG { + GPIO_USE_SEL = 0, + GPIO_IO_SEL, + GPIO_LVL, + GPO_BLINK +}; + +static const u8 ichx_regs[4][3] = { + {0x00, 0x30, 0x40}, /* USE_SEL[1-3] offsets */ + {0x04, 0x34, 0x44}, /* IO_SEL[1-3] offsets */ + {0x0c, 0x38, 0x48}, /* LVL[1-3] offsets */ + {0x18, 0x18, 0x18}, /* BLINK offset */ +}; + +static const u8 ichx_reglen[3] = { + 0x30, 0x10, 0x10, +}; + +static const u8 avoton_regs[4][3] = { + {0x00, 0x80, 0x00}, + {0x04, 0x84, 0x00}, + {0x08, 0x88, 0x00}, +}; + +static const u8 avoton_reglen[3] = { + 0x10, 0x10, 0x00, +}; + +#define ICHX_WRITE(val, reg, base_res) outl(val, (reg) + (base_res)->start) +#define ICHX_READ(reg, base_res) inl((reg) + (base_res)->start) + +struct ichx_desc { + /* Max GPIO pins the chipset can have */ + uint ngpio; + + /* chipset registers */ + const u8 (*regs)[3]; + const u8 *reglen; + + /* GPO_BLINK is available on this chipset */ + bool have_blink; + + /* Whether the chipset has GPIO in GPE0_STS in the PM IO region */ + bool uses_gpe0; + + /* USE_SEL is bogus on some chipsets, eg 3100 */ + u32 use_sel_ignore[3]; + + /* Some chipsets have quirks, let these use their own request/get */ + int (*request)(struct gpio_chip *chip, unsigned offset); + int (*get)(struct gpio_chip *chip, unsigned offset); + + /* + * Some chipsets don't let reading output values on GPIO_LVL register + * this option allows driver caching written output values + */ + bool use_outlvl_cache; +}; + +static struct { + spinlock_t lock; + struct platform_device *dev; + struct gpio_chip chip; + struct resource *gpio_base; /* GPIO IO base */ + struct resource *pm_base; /* Power Mangagment IO base */ + struct ichx_desc *desc; /* Pointer to chipset-specific description */ + u32 orig_gpio_ctrl; /* Orig CTRL value, used to restore on exit */ + u8 use_gpio; /* Which GPIO groups are usable */ + int outlvl_cache[3]; /* cached output values */ +} ichx_priv; + +static int modparam_gpiobase = -1; /* dynamic */ +module_param_named(gpiobase, modparam_gpiobase, int, 0444); +MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, " + "which is the default."); + +static int ichx_write_bit(int reg, unsigned nr, int val, int verify) +{ + unsigned long flags; + u32 data, tmp; + int reg_nr = nr / 32; + int bit = nr & 0x1f; + int ret = 0; + + spin_lock_irqsave(&ichx_priv.lock, flags); + + if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache) + data = ichx_priv.outlvl_cache[reg_nr]; + else + data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], + ichx_priv.gpio_base); + + if (val) + data |= 1 << bit; + else + data &= ~(1 << bit); + ICHX_WRITE(data, ichx_priv.desc->regs[reg][reg_nr], + ichx_priv.gpio_base); + if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache) + ichx_priv.outlvl_cache[reg_nr] = data; + + tmp = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], + ichx_priv.gpio_base); + if (verify && data != tmp) + ret = -EPERM; + + spin_unlock_irqrestore(&ichx_priv.lock, flags); + + return ret; +} + +static int ichx_read_bit(int reg, unsigned nr) +{ + unsigned long flags; + u32 data; + int reg_nr = nr / 32; + int bit = nr & 0x1f; + + spin_lock_irqsave(&ichx_priv.lock, flags); + + data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], + ichx_priv.gpio_base); + + if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache) + data = ichx_priv.outlvl_cache[reg_nr] | data; + + spin_unlock_irqrestore(&ichx_priv.lock, flags); + + return data & (1 << bit) ? 1 : 0; +} + +static bool ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr) +{ + return !!(ichx_priv.use_gpio & (1 << (nr / 32))); +} + +static int ichx_gpio_get_direction(struct gpio_chip *gpio, unsigned nr) +{ + return ichx_read_bit(GPIO_IO_SEL, nr) ? GPIOF_DIR_IN : GPIOF_DIR_OUT; +} + +static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) +{ + /* + * Try setting pin as an input and verify it worked since many pins + * are output-only. + */ + if (ichx_write_bit(GPIO_IO_SEL, nr, 1, 1)) + return -EINVAL; + + return 0; +} + +static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, + int val) +{ + /* Disable blink hardware which is available for GPIOs from 0 to 31. */ + if (nr < 32 && ichx_priv.desc->have_blink) + ichx_write_bit(GPO_BLINK, nr, 0, 0); + + /* Set GPIO output value. */ + ichx_write_bit(GPIO_LVL, nr, val, 0); + + /* + * Try setting pin as an output and verify it worked since many pins + * are input-only. + */ + if (ichx_write_bit(GPIO_IO_SEL, nr, 0, 1)) + return -EINVAL; + + return 0; +} + +static int ichx_gpio_get(struct gpio_chip *chip, unsigned nr) +{ + return ichx_read_bit(GPIO_LVL, nr); +} + +static int ich6_gpio_get(struct gpio_chip *chip, unsigned nr) +{ + unsigned long flags; + u32 data; + + /* + * GPI 0 - 15 need to be read from the power management registers on + * a ICH6/3100 bridge. + */ + if (nr < 16) { + if (!ichx_priv.pm_base) + return -ENXIO; + + spin_lock_irqsave(&ichx_priv.lock, flags); + + /* GPI 0 - 15 are latched, write 1 to clear*/ + ICHX_WRITE(1 << (16 + nr), 0, ichx_priv.pm_base); + data = ICHX_READ(0, ichx_priv.pm_base); + + spin_unlock_irqrestore(&ichx_priv.lock, flags); + + return (data >> 16) & (1 << nr) ? 1 : 0; + } else { + return ichx_gpio_get(chip, nr); + } +} + +static int ichx_gpio_request(struct gpio_chip *chip, unsigned nr) +{ + if (!ichx_gpio_check_available(chip, nr)) + return -ENXIO; + + /* + * Note we assume the BIOS properly set a bridge's USE value. Some + * chips (eg Intel 3100) have bogus USE values though, so first see if + * the chipset's USE value can be trusted for this specific bit. + * If it can't be trusted, assume that the pin can be used as a GPIO. + */ + if (ichx_priv.desc->use_sel_ignore[nr / 32] & (1 << (nr & 0x1f))) + return 0; + + return ichx_read_bit(GPIO_USE_SEL, nr) ? 0 : -ENODEV; +} + +static int ich6_gpio_request(struct gpio_chip *chip, unsigned nr) +{ + /* + * Fixups for bits 16 and 17 are necessary on the Intel ICH6/3100 + * bridge as they are controlled by USE register bits 0 and 1. See + * "Table 704 GPIO_USE_SEL1 register" in the i3100 datasheet for + * additional info. + */ + if (nr == 16 || nr == 17) + nr -= 16; + + return ichx_gpio_request(chip, nr); +} + +static void ichx_gpio_set(struct gpio_chip *chip, unsigned nr, int val) +{ + ichx_write_bit(GPIO_LVL, nr, val, 0); +} + +static void ichx_gpiolib_setup(struct gpio_chip *chip) +{ + chip->owner = THIS_MODULE; + chip->label = DRV_NAME; + chip->parent = &ichx_priv.dev->dev; + + /* Allow chip-specific overrides of request()/get() */ + chip->request = ichx_priv.desc->request ? + ichx_priv.desc->request : ichx_gpio_request; + chip->get = ichx_priv.desc->get ? + ichx_priv.desc->get : ichx_gpio_get; + + chip->set = ichx_gpio_set; + chip->get_direction = ichx_gpio_get_direction; + chip->direction_input = ichx_gpio_direction_input; + chip->direction_output = ichx_gpio_direction_output; + chip->base = modparam_gpiobase; + chip->ngpio = ichx_priv.desc->ngpio; + chip->can_sleep = false; + chip->dbg_show = NULL; +} + +/* ICH6-based, 631xesb-based */ +static struct ichx_desc ich6_desc = { + /* Bridges using the ICH6 controller need fixups for GPIO 0 - 17 */ + .request = ich6_gpio_request, + .get = ich6_gpio_get, + + /* GPIO 0-15 are read in the GPE0_STS PM register */ + .uses_gpe0 = true, + + .ngpio = 50, + .have_blink = true, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* Intel 3100 */ +static struct ichx_desc i3100_desc = { + /* + * Bits 16,17, 20 of USE_SEL and bit 16 of USE_SEL2 always read 0 on + * the Intel 3100. See "Table 712. GPIO Summary Table" of 3100 + * Datasheet for more info. + */ + .use_sel_ignore = {0x00130000, 0x00010000, 0x0}, + + /* The 3100 needs fixups for GPIO 0 - 17 */ + .request = ich6_gpio_request, + .get = ich6_gpio_get, + + /* GPIO 0-15 are read in the GPE0_STS PM register */ + .uses_gpe0 = true, + + .ngpio = 50, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* ICH7 and ICH8-based */ +static struct ichx_desc ich7_desc = { + .ngpio = 50, + .have_blink = true, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* ICH9-based */ +static struct ichx_desc ich9_desc = { + .ngpio = 61, + .have_blink = true, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* ICH10-based - Consumer/corporate versions have different amount of GPIO */ +static struct ichx_desc ich10_cons_desc = { + .ngpio = 61, + .have_blink = true, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; +static struct ichx_desc ich10_corp_desc = { + .ngpio = 72, + .have_blink = true, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* Intel 5 series, 6 series, 3400 series, and C200 series */ +static struct ichx_desc intel5_desc = { + .ngpio = 76, + .regs = ichx_regs, + .reglen = ichx_reglen, +}; + +/* Avoton */ +static struct ichx_desc avoton_desc = { + /* Avoton has only 59 GPIOs, but we assume the first set of register + * (Core) has 32 instead of 31 to keep gpio-ich compliance + */ + .ngpio = 60, + .regs = avoton_regs, + .reglen = avoton_reglen, + .use_outlvl_cache = true, +}; + +static int ichx_gpio_request_regions(struct device *dev, + struct resource *res_base, const char *name, u8 use_gpio) +{ + int i; + + if (!res_base || !res_base->start || !res_base->end) + return -ENODEV; + + for (i = 0; i < ARRAY_SIZE(ichx_priv.desc->regs[0]); i++) { + if (!(use_gpio & (1 << i))) + continue; + if (!devm_request_region(dev, + res_base->start + ichx_priv.desc->regs[0][i], + ichx_priv.desc->reglen[i], name)) + return -EBUSY; + } + return 0; +} + +static int ichx_gpio_probe(struct platform_device *pdev) +{ + struct resource *res_base, *res_pm; + int err; + struct lpc_ich_info *ich_info = dev_get_platdata(&pdev->dev); + + if (!ich_info) + return -ENODEV; + + ichx_priv.dev = pdev; + + switch (ich_info->gpio_version) { + case ICH_I3100_GPIO: + ichx_priv.desc = &i3100_desc; + break; + case ICH_V5_GPIO: + ichx_priv.desc = &intel5_desc; + break; + case ICH_V6_GPIO: + ichx_priv.desc = &ich6_desc; + break; + case ICH_V7_GPIO: + ichx_priv.desc = &ich7_desc; + break; + case ICH_V9_GPIO: + ichx_priv.desc = &ich9_desc; + break; + case ICH_V10CORP_GPIO: + ichx_priv.desc = &ich10_corp_desc; + break; + case ICH_V10CONS_GPIO: + ichx_priv.desc = &ich10_cons_desc; + break; + case AVOTON_GPIO: + ichx_priv.desc = &avoton_desc; + break; + default: + return -ENODEV; + } + + spin_lock_init(&ichx_priv.lock); + res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO); + ichx_priv.use_gpio = ich_info->use_gpio; + err = ichx_gpio_request_regions(&pdev->dev, res_base, pdev->name, + ichx_priv.use_gpio); + if (err) + return err; + + ichx_priv.gpio_base = res_base; + + /* + * If necessary, determine the I/O address of ACPI/power management + * registers which are needed to read the the GPE0 register for GPI pins + * 0 - 15 on some chipsets. + */ + if (!ichx_priv.desc->uses_gpe0) + goto init; + + res_pm = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPE0); + if (!res_pm) { + pr_warn("ACPI BAR is unavailable, GPI 0 - 15 unavailable\n"); + goto init; + } + + if (!devm_request_region(&pdev->dev, res_pm->start, + resource_size(res_pm), pdev->name)) { + pr_warn("ACPI BAR is busy, GPI 0 - 15 unavailable\n"); + goto init; + } + + ichx_priv.pm_base = res_pm; + +init: + ichx_gpiolib_setup(&ichx_priv.chip); + err = gpiochip_add_data(&ichx_priv.chip, NULL); + if (err) { + pr_err("Failed to register GPIOs\n"); + return err; + } + + pr_info("GPIO from %d to %d on %s\n", ichx_priv.chip.base, + ichx_priv.chip.base + ichx_priv.chip.ngpio - 1, DRV_NAME); + + return 0; +} + +static int ichx_gpio_remove(struct platform_device *pdev) +{ + gpiochip_remove(&ichx_priv.chip); + + return 0; +} + +static struct platform_driver ichx_gpio_driver = { + .driver = { + .name = DRV_NAME, + }, + .probe = ichx_gpio_probe, + .remove = ichx_gpio_remove, +}; + +module_platform_driver(ichx_gpio_driver); + +MODULE_AUTHOR("Peter Tyser "); +MODULE_DESCRIPTION("GPIO interface for Intel ICH series"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:"DRV_NAME); diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/i2c-mux-pca9541.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/i2c-mux-pca9541.c new file mode 100644 index 000000000000..68c44dbc533f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/i2c-mux-pca9541.c @@ -0,0 +1,573 @@ +/* + * I2C multiplexer driver for PCA9541 bus master selector + * + * Copyright (c) 2010 Ericsson AB. + * + * Author: Guenter Roeck + * + * Derived from: + * pca954x.c + * + * Copyright (c) 2008-2009 Rodolfo Giometti + * Copyright (c) 2008-2009 Eurotech S.p.A. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * The PCA9541 is a bus master selector. It supports two I2C masters connected + * to a single slave bus. + * + * Before each bus transaction, a master has to acquire bus ownership. After the + * transaction is complete, bus ownership has to be released. This fits well + * into the I2C multiplexer framework, which provides select and release + * functions for this purpose. For this reason, this driver is modeled as + * single-channel I2C bus multiplexer. + * + * This driver assumes that the two bus masters are controlled by two different + * hosts. If a single host controls both masters, platform code has to ensure + * that only one of the masters is instantiated at any given time. + */ + +#define PCA9541_CONTROL 0x01 +#define PCA9541_ISTAT 0x02 + +#define PCA9541_CTL_MYBUS (1 << 0) +#define PCA9541_CTL_NMYBUS (1 << 1) +#define PCA9541_CTL_BUSON (1 << 2) +#define PCA9541_CTL_NBUSON (1 << 3) +#define PCA9541_CTL_BUSINIT (1 << 4) +#define PCA9541_CTL_TESTON (1 << 6) +#define PCA9541_CTL_NTESTON (1 << 7) + +#define PCA9541_ISTAT_INTIN (1 << 0) +#define PCA9541_ISTAT_BUSINIT (1 << 1) +#define PCA9541_ISTAT_BUSOK (1 << 2) +#define PCA9541_ISTAT_BUSLOST (1 << 3) +#define PCA9541_ISTAT_MYTEST (1 << 6) +#define PCA9541_ISTAT_NMYTEST (1 << 7) + +#define PCA9641_ID 0x00 +#define PCA9641_ID_MAGIC 0x38 + +#define PCA9641_CONTROL 0x01 +#define PCA9641_STATUS 0x02 +#define PCA9641_TIME 0x03 + +#define PCA9641_CTL_LOCK_REQ BIT(0) +#define PCA9641_CTL_LOCK_GRANT BIT(1) +#define PCA9641_CTL_BUS_CONNECT BIT(2) +#define PCA9641_CTL_BUS_INIT BIT(3) +#define PCA9641_CTL_SMBUS_SWRST BIT(4) +#define PCA9641_CTL_IDLE_TIMER_DIS BIT(5) +#define PCA9641_CTL_SMBUS_DIS BIT(6) +#define PCA9641_CTL_PRIORITY BIT(7) + +#define PCA9641_STS_OTHER_LOCK BIT(0) +#define PCA9641_STS_BUS_INIT_FAIL BIT(1) +#define PCA9641_STS_BUS_HUNG BIT(2) +#define PCA9641_STS_MBOX_EMPTY BIT(3) +#define PCA9641_STS_MBOX_FULL BIT(4) +#define PCA9641_STS_TEST_INT BIT(5) +#define PCA9641_STS_SCL_IO BIT(6) +#define PCA9641_STS_SDA_IO BIT(7) + +#define PCA9641_RES_TIME 0x03 + + +#define BUSON (PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON) +#define MYBUS (PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS) +#define mybus(x) (!((x) & MYBUS) || ((x) & MYBUS) == MYBUS) +#define busoff(x) (!((x) & BUSON) || ((x) & BUSON) == BUSON) + +#define BUSOFF(x, y) (!((x) & PCA9641_CTL_LOCK_GRANT) && \ + !((y) & PCA9641_STS_OTHER_LOCK)) +#define other_lock(x) ((x) & PCA9641_STS_OTHER_LOCK) +#define lock_grant(x) ((x) & PCA9641_CTL_LOCK_GRANT) + +/* arbitration timeouts, in jiffies */ +#define ARB_TIMEOUT (HZ / 8) /* 125 ms until forcing bus ownership */ +#define ARB2_TIMEOUT (HZ / 4) /* 250 ms until acquisition failure */ + +/* arbitration retry delays, in us */ +#define SELECT_DELAY_SHORT 50 +#define SELECT_DELAY_LONG 1000 + +struct pca9541 { + struct i2c_client *client; + unsigned long select_timeout; + unsigned long arb_timeout; +}; + +static const struct i2c_device_id pca9541_id[] = { + {"pca9541", 0}, + {"pca9641", 1}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, pca9541_id); + +#ifdef CONFIG_OF +static const struct of_device_id pca9541_of_match[] = { + { .compatible = "nxp,pca9541" }, + { .compatible = "nxp,pca9641" }, + {} +}; +#endif + +/* + * Write to chip register. Don't use i2c_transfer()/i2c_smbus_xfer() + * as they will try to lock the adapter a second time. + */ +static int pca9541_reg_write(struct i2c_client *client, u8 command, u8 val) +{ + struct i2c_adapter *adap = client->adapter; + int ret; + + if (adap->algo->master_xfer) { + struct i2c_msg msg; + char buf[2]; + + msg.addr = client->addr; + msg.flags = 0; + msg.len = 2; + buf[0] = command; + buf[1] = val; + msg.buf = buf; + ret = __i2c_transfer(adap, &msg, 1); + } else { + union i2c_smbus_data data; + + data.byte = val; + ret = adap->algo->smbus_xfer(adap, client->addr, + client->flags, + I2C_SMBUS_WRITE, + command, + I2C_SMBUS_BYTE_DATA, &data); + } + + return ret; +} + +/* + * Read from chip register. Don't use i2c_transfer()/i2c_smbus_xfer() + * as they will try to lock adapter a second time. + */ +static int pca9541_reg_read(struct i2c_client *client, u8 command) +{ + struct i2c_adapter *adap = client->adapter; + int ret; + u8 val; + + if (adap->algo->master_xfer) { + struct i2c_msg msg[2] = { + { + .addr = client->addr, + .flags = 0, + .len = 1, + .buf = &command + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = 1, + .buf = &val + } + }; + ret = __i2c_transfer(adap, msg, 2); + if (ret == 2) + ret = val; + else if (ret >= 0) + ret = -EIO; + } else { + union i2c_smbus_data data; + + ret = adap->algo->smbus_xfer(adap, client->addr, + client->flags, + I2C_SMBUS_READ, + command, + I2C_SMBUS_BYTE_DATA, &data); + if (!ret) + ret = data.byte; + } + return ret; +} + +/* + * Arbitration management functions + */ + +/* Release bus. Also reset NTESTON and BUSINIT if it was set. */ +static void pca9541_release_bus(struct i2c_client *client) +{ + int reg; + + reg = pca9541_reg_read(client, PCA9541_CONTROL); + if (reg >= 0 && !busoff(reg) && mybus(reg)) + pca9541_reg_write(client, PCA9541_CONTROL, + (reg & PCA9541_CTL_NBUSON) >> 1); +} + +/* + * Arbitration is defined as a two-step process. A bus master can only activate + * the slave bus if it owns it; otherwise it has to request ownership first. + * This multi-step process ensures that access contention is resolved + * gracefully. + * + * Bus Ownership Other master Action + * state requested access + * ---------------------------------------------------- + * off - yes wait for arbitration timeout or + * for other master to drop request + * off no no take ownership + * off yes no turn on bus + * on yes - done + * on no - wait for arbitration timeout or + * for other master to release bus + * + * The main contention point occurs if the slave bus is off and both masters + * request ownership at the same time. In this case, one master will turn on + * the slave bus, believing that it owns it. The other master will request + * bus ownership. Result is that the bus is turned on, and master which did + * _not_ own the slave bus before ends up owning it. + */ + +/* Control commands per PCA9541 datasheet */ +static const u8 pca9541_control[16] = { + 4, 0, 1, 5, 4, 4, 5, 5, 0, 0, 1, 1, 0, 4, 5, 1 +}; + +/* + * Channel arbitration + * + * Return values: + * <0: error + * 0 : bus not acquired + * 1 : bus acquired + */ +static int pca9541_arbitrate(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct pca9541 *data = i2c_mux_priv(muxc); + int reg; + + reg = pca9541_reg_read(client, PCA9541_CONTROL); + if (reg < 0) + return reg; + + if (busoff(reg)) { + int istat; + /* + * Bus is off. Request ownership or turn it on unless + * other master requested ownership. + */ + istat = pca9541_reg_read(client, PCA9541_ISTAT); + if (!(istat & PCA9541_ISTAT_NMYTEST) + || time_is_before_eq_jiffies(data->arb_timeout)) { + /* + * Other master did not request ownership, + * or arbitration timeout expired. Take the bus. + */ + pca9541_reg_write(client, + PCA9541_CONTROL, + pca9541_control[reg & 0x0f] + | PCA9541_CTL_NTESTON); + data->select_timeout = SELECT_DELAY_SHORT; + } else { + /* + * Other master requested ownership. + * Set extra long timeout to give it time to acquire it. + */ + data->select_timeout = SELECT_DELAY_LONG * 2; + } + } else if (mybus(reg)) { + /* + * Bus is on, and we own it. We are done with acquisition. + * Reset NTESTON and BUSINIT, then return success. + */ + if (reg & (PCA9541_CTL_NTESTON | PCA9541_CTL_BUSINIT)) + pca9541_reg_write(client, + PCA9541_CONTROL, + reg & ~(PCA9541_CTL_NTESTON + | PCA9541_CTL_BUSINIT)); + return 1; + } else { + /* + * Other master owns the bus. + * If arbitration timeout has expired, force ownership. + * Otherwise request it. + */ + data->select_timeout = SELECT_DELAY_LONG; + if (time_is_before_eq_jiffies(data->arb_timeout)) { + /* Time is up, take the bus and reset it. */ + pca9541_reg_write(client, + PCA9541_CONTROL, + pca9541_control[reg & 0x0f] + | PCA9541_CTL_BUSINIT + | PCA9541_CTL_NTESTON); + } else { + /* Request bus ownership if needed */ + if (!(reg & PCA9541_CTL_NTESTON)) + pca9541_reg_write(client, + PCA9541_CONTROL, + reg | PCA9541_CTL_NTESTON); + } + } + return 0; +} + +static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca9541 *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + int ret; + unsigned long timeout = jiffies + ARB2_TIMEOUT; + /* give up after this time */ + + data->arb_timeout = jiffies + ARB_TIMEOUT; + /* force bus ownership after this time */ + + do { + ret = pca9541_arbitrate(client); + if (ret) + return ret < 0 ? ret : 0; + + if (data->select_timeout == SELECT_DELAY_SHORT) + udelay(data->select_timeout); + else + msleep(data->select_timeout / 1000); + } while (time_is_after_eq_jiffies(timeout)); + + return -ETIMEDOUT; +} + +static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca9541 *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + + pca9541_release_bus(client); + return 0; +} + +/* + * Arbitration management functions + */ +static void pca9641_release_bus(struct i2c_client *client) +{ + pca9541_reg_write(client, PCA9641_CONTROL, 0); +} + +/* + * Channel arbitration + * + * Return values: + * <0: error + * 0 : bus not acquired + * 1 : bus acquired + */ +static int pca9641_arbitrate(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct pca9541 *data = i2c_mux_priv(muxc); + int reg_ctl, reg_sts; + + reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL); + if (reg_ctl < 0) + return reg_ctl; + reg_sts = pca9541_reg_read(client, PCA9641_STATUS); + + if (BUSOFF(reg_ctl, reg_sts)) { + /* + * Bus is off. Request ownership or turn it on unless + * other master requested ownership. + */ + reg_ctl |= PCA9641_CTL_LOCK_REQ; + pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl); + reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL); + + if (lock_grant(reg_ctl)) { + /* + * Other master did not request ownership, + * or arbitration timeout expired. Take the bus. + */ + reg_ctl |= PCA9641_CTL_BUS_CONNECT + | PCA9641_CTL_LOCK_REQ; + pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl); + data->select_timeout = SELECT_DELAY_SHORT; + + return 1; + } else { + /* + * Other master requested ownership. + * Set extra long timeout to give it time to acquire it. + */ + data->select_timeout = SELECT_DELAY_LONG * 2; + } + } else if (lock_grant(reg_ctl)) { + /* + * Bus is on, and we own it. We are done with acquisition. + */ + reg_ctl |= PCA9641_CTL_BUS_CONNECT | PCA9641_CTL_LOCK_REQ; + pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl); + + return 1; + } else if (other_lock(reg_sts)) { + /* + * Other master owns the bus. + * If arbitration timeout has expired, force ownership. + * Otherwise request it. + */ + data->select_timeout = SELECT_DELAY_LONG; + reg_ctl |= PCA9641_CTL_LOCK_REQ; + pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl); + } + return 0; +} + +static int pca9641_select_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca9541 *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + int ret; + unsigned long timeout = jiffies + ARB2_TIMEOUT; + /* give up after this time */ + + data->arb_timeout = jiffies + ARB_TIMEOUT; + /* force bus ownership after this time */ + + do { + ret = pca9641_arbitrate(client); + if (ret) + return ret < 0 ? ret : 0; + + if (data->select_timeout == SELECT_DELAY_SHORT) + udelay(data->select_timeout); + else + msleep(data->select_timeout / 1000); + } while (time_is_after_eq_jiffies(timeout)); + + return -ETIMEDOUT; +} + +static int pca9641_release_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca9541 *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + + pca9641_release_bus(client); + return 0; +} + +static int pca9641_detect_id(struct i2c_client *client) +{ + int reg; + + reg = pca9541_reg_read(client, PCA9641_ID); + if (reg == PCA9641_ID_MAGIC) + return 1; + else + return 0; +} + +/* + * I2C init/probing/exit functions + */ +static int pca9541_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adap = client->adapter; + struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev); + struct i2c_mux_core *muxc; + struct pca9541 *data; + int force; + int ret; + int detect_id; + + if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + detect_id = pca9641_detect_id(client); + /* + * I2C accesses are unprotected here. + * We have to lock the adapter before releasing the bus. + */ + if (detect_id == 0) { + i2c_lock_adapter(adap); + pca9541_release_bus(client); + i2c_unlock_adapter(adap); + } else { + i2c_lock_adapter(adap); + pca9641_release_bus(client); + i2c_unlock_adapter(adap); + } + + /* Create mux adapter */ + + force = 0; + if (pdata) + force = pdata->modes[0].adap_id; + if (detect_id == 0) { + muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data), + I2C_MUX_ARBITRATOR, + pca9541_select_chan, pca9541_release_chan); + } else { + muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data), + I2C_MUX_ARBITRATOR, + pca9641_select_chan, pca9641_release_chan); + } + if (!muxc) + return -ENOMEM; + + data = i2c_mux_priv(muxc); + data->client = client; + + i2c_set_clientdata(client, muxc); + + ret = i2c_mux_add_adapter(muxc, force, 0, 0); + if (ret) { + dev_err(&client->dev, "failed to register master selector\n"); + return ret; + } + + dev_info(&client->dev, "registered master selector for I2C %s\n", + client->name); + + return 0; +} + +static int pca9541_remove(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + + i2c_mux_del_adapters(muxc); + return 0; +} + +static struct i2c_driver pca9541_driver = { + .driver = { + .name = "pca9541", + .of_match_table = of_match_ptr(pca9541_of_match), + }, + .probe = pca9541_probe, + .remove = pca9541_remove, + .id_table = pca9541_id, +}; + +module_i2c_driver(pca9541_driver); + +MODULE_AUTHOR("Guenter Roeck "); +MODULE_DESCRIPTION("PCA9541 I2C master selector driver"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_cpld.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_cpld.c new file mode 100644 index 000000000000..8e2693d2e251 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_cpld.c @@ -0,0 +1,1011 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* definition */ +#define CPLD_INFO_OFFSET 0x00 +#define CPLD_BIOSCS_OFFSET 0x04 +#define CPLD_CTL_OFFSET 0x0C +#define CPLD_SYSLED_OFFSET 0x0E +#define CPLD_LED_OFFSET 0x2E +#define CPLD_INT_OFFSET 0x30 +#define CPLD_INTMASK_OFFSET 0x31 +#define CPLD_INT2_OFFSET 0x32 +#define CPLD_INTMASK2_OFFSET 0x33 +#define CPLD_PSU_OFFSET 0x40 +#define CPLD_POWERSTATUS_OFFSET 0x41 +#define CPLD_PWM_OFFSET 0x50 +#define CPLD_RPM_OFFSET 0x55 +#define CPLD_FANSTATUS_OFFSET 0x69 +#define CPLD_FANLED_OFFSET 0x6B +#define CPLD_RESETBUTTONSTATUS_OFFSET 0x75 +#define CPLD_RSTCAUSE_OFFSET 0x76 +#define CPLD_WATCHDOGCOUNTER_OFFSET 0x77 +#define CPLD_WATCHDOGCONFIG_OFFSET 0x78 +#define CPLD_WATCHDOGENABLE_OFFSET 0x79 +#define CPLD_PANICCODE_OFFSET 0x7E +#define CPLD2_ADDRESS 0x33 + +#define FAN_NUM 4 +static u8 hasCPLD2 = 1; +static struct i2c_client *client2; + +/* Each client has this additional data */ +struct cpld_data { + struct device *hwmon_dev; + struct mutex update_lock; + u8 diag; + struct task_struct *tsk; +}; + +/*-----------------------------------------------------------------------*/ +static ssize_t cpld_i2c_read(struct i2c_client *client, u8 *buf, u8 offset, size_t count) +{ + int i; + s32 temp = 0; + + for(i=0; iuser_msg_data; + + if(recv_msg->msg.data[0]==0 && recv_msg->msg.data_len>0) { + msg_result->result_length=recv_msg->msg.data_len-1; + memcpy(msg_result->result, &recv_msg->msg.data[1], recv_msg->msg.data_len-1); + } + ipmi_free_recv_msg(recv_msg); + mutex_unlock(&ipmi_mutex); + + return; +} + +int start_ipmi_command(char NetFn, char cmd,char *data,int data_length, char* result, int* result_length) +{ + int rv=0,i; + int timeout; + + //wait previous command finish at least 50msec + timeout=50; + while((mutex_is_locked(&ipmi_mutex) == 1 || (mutex_is_locked(&ipmi2_mutex) == 1)) && (--timeout)>0) { usleep_range(1000,1010); } + if(timeout==0) { return -1; } + mutex_lock(&ipmi_mutex); + mutex_lock(&ipmi2_mutex); + + if(ipmi_mh_user == NULL) { + for (i=0,rv=1; i0) { usleep_range(1000,1100);} + if(timeout==0) { + mutex_unlock(&ipmi2_mutex); + return -1; + } + else { + *result_length=ipmiresult.result_length; + memcpy(result,ipmiresult.result,*result_length); + mutex_unlock(&ipmi2_mutex); + return 0; + } + } + return 0; +} +EXPORT_SYMBOL(start_ipmi_command); + +static int cpld_thread(void *p) +{ +#ifndef XORP + struct i2c_client *client = p; + + u8 byte[9]; + uint8_t result[MAX_IPMI_RECV_LENGTH]; + int result_len=0; + + //Handle LED control by the driver + byte[0]=0x01; + cpld_i2c_write(client, byte, CPLD_CTL_OFFSET, 1); + + //Disable BMC Watchdog + byte[0]=0x04; + byte[1]=0x00; + byte[2]=0x00; + byte[3]=0x00; + byte[4]=0x2C; + byte[5]=0x01; + start_ipmi_command(0x06, 0x24, byte, 6, result, &result_len); +#endif + return 0; +} +/*-----------------------------------------------------------------------*/ +/* sysfs attributes for hwmon */ +static ssize_t show_info(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + ssize_t len = 0; + + u8 byte[4] = {0,0,0,0}; + + mutex_lock(&data->update_lock); + len = cpld_i2c_read(client, byte, CPLD_INFO_OFFSET, 4); + mutex_unlock(&data->update_lock); + if (len==0) return 0; + + sprintf (buf, "The CPLD release date is %02d/%02d/%d.\n", + byte[2] & 0xf, (byte[3] & 0x1f), 2014+(byte[2] >> 4)); /* mm/dd/yyyy*/ + sprintf (buf, "%sThe PCB version is %X\n", buf, byte[0]&0xf); + sprintf (buf, "%sThe CPLD version is %d.%d\n", buf, byte[1]>>4, byte[1]&0xf); + + if(hasCPLD2) { + mutex_lock(&data->update_lock); + cpld_i2c_read(client2, byte, CPLD_INFO_OFFSET, 4); + mutex_unlock(&data->update_lock); + + sprintf (buf, "%s\nThe CPLD2 release date is %02d/%02d/%d.\n", buf, + byte[2] & 0xf, (byte[3] & 0x1f), 2014+(byte[2] >> 4)); /* mm/dd/yyyy*/ + sprintf (buf, "%sThe CPLD2 version is %d.%d\n", buf, byte[1]>>4, byte[1]&0xf); + } + + return strlen(buf); +} + +static char* powerstatus_str[] = { + "Failed", //0 + "Good", //1 +}; + +static ssize_t show_powerstatus(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + ssize_t len = 0; + u8 byte[2] = {0,0}; + + mutex_lock(&data->update_lock); + len = cpld_i2c_read(client2, byte, CPLD_POWERSTATUS_OFFSET, 2); + mutex_unlock(&data->update_lock); + if (len==0) return 0; + + sprintf (buf, "PGD_P5V_STBY: %s\n", powerstatus_str[(byte[0]>>7) & 0x01]); + sprintf (buf, "%sPGD_P3V3_STBY: %s\n", buf, powerstatus_str[(byte[0]>>6) & 0x01]);; + sprintf (buf, "%sPGD_P1V8_A: %s\n", buf, powerstatus_str[(byte[0]>>4) & 0x01]); + sprintf (buf, "%sPGD_P3V3_SYS: %s\n", buf, powerstatus_str[(byte[0]>>3) & 0x01]); + sprintf (buf, "%sPGD_P3V3_A: %s\n", buf, powerstatus_str[(byte[0]>>2) & 0x01]); + sprintf (buf, "%sPGD_P3V3_B: %s\n", buf, powerstatus_str[(byte[0]>>1) & 0x01]); + sprintf (buf, "%sPGD_P1V2: %s\n", buf, powerstatus_str[(byte[0]>>0) & 0x01]); + sprintf (buf, "%sPGD_P0V8_A: %s\n", buf,powerstatus_str[(byte[1]>>7) & 0x01]); + sprintf (buf, "%sPGD_P0V89_ROV: %s\n", buf, powerstatus_str[(byte[1]>>6) & 0x01]); + sprintf (buf, "%sSW_PWR_READY: %s\n", buf, powerstatus_str[(byte[1]>>3) & 0x01]); + sprintf (buf, "%sCPU_STBY_PWROK: %s\n", buf, powerstatus_str[(byte[1]>>0) & 0x01]); + + return strlen(buf); +} + +static ssize_t show_diag(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + uint8_t ipmisend[]= { IPMI_DIAGFLAG_OFFSET, 1}; + uint8_t result[MAX_IPMI_RECV_LENGTH]; + int result_len=0; + start_ipmi_command(NETFN_OEM, CMD_GETDATA,ipmisend, 2, result, &result_len); + data->diag = (result[0] & 0x80) !=0; + return sprintf (buf, "%d\n", data->diag); +} + +static ssize_t set_diag(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + uint8_t ipmisend[]= { IPMI_DIAGFLAG_OFFSET, 0x80}; + uint8_t result[MAX_IPMI_RECV_LENGTH]; + int result_len=0; + u8 diag = simple_strtol(buf, NULL, 10); + data->diag = diag?1:0; + if (data->diag==0) ipmisend[1] = 0x00; + + start_ipmi_command(NETFN_OEM, CMD_SETDATA,ipmisend, 2, result, &result_len); + + return count; +} + +static ssize_t show_thermal(struct device *dev, struct device_attribute *da, + char *buf) +{ + uint8_t ipmisend[]= { IPMI_SWITCHTEMP_OFFSET, 1}; + uint8_t result[MAX_IPMI_RECV_LENGTH]; + int result_len=0; + start_ipmi_command(NETFN_OEM, CMD_GETDATA,ipmisend, 2, result, &result_len); + return sprintf(buf, "%d\n", result[0] * 1000 ); +} + +static char* interrupt_str[] = { + "CPU_SEN_ALERT_N", //0 + "EXT_USB_OC_N", //1 + "", //2 + "", //3 + "PLD_SEN5_ALERT_N", //4 + "PLD_SEN4_ALERT_N", //5 + "PLD_SEN3_ALERT_N", //6 + "UCD90160_TEMP_INT_N", //7 + "RSTBTN_INT_N", //8 + "WDT_IRQ_N", //9 +}; + +static ssize_t show_interrupt(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + ssize_t len = 0; + u8 byte[4] = {0,0,0,0}; + + mutex_lock(&data->update_lock); + len = cpld_i2c_read(client, byte, CPLD_INT_OFFSET, 4); + mutex_unlock(&data->update_lock); + if (len==0) return 0; + + sprintf (buf, "0x%02X 0x%02X:", byte[0],byte[2]); + if(byte[0]==0xff && byte[2]==0x07) sprintf (buf, "%sNone",buf); + if(!(byte[0]&0x01)) sprintf (buf, "%s%s ",buf,interrupt_str[0]); + if(!(byte[0]&0x02)) sprintf (buf, "%s%s ",buf,interrupt_str[1]); + if(!(byte[0]&0x10)) sprintf (buf, "%s%s ",buf,interrupt_str[4]); + if(!(byte[0]&0x20)) sprintf (buf, "%s%s ",buf,interrupt_str[5]); + if(!(byte[0]&0x40)) sprintf (buf, "%s%s ",buf,interrupt_str[6]); + if(!(byte[0]&0x80)) sprintf (buf, "%s%s ",buf,interrupt_str[7]); + if(!(byte[2]&0x01)) sprintf (buf, "%s%s%s ",buf,interrupt_str[8] ,(byte[3]&0x01)?"(Blocked)":""); + if(!(byte[2]&0x02)) sprintf (buf, "%s%s%s ",buf,interrupt_str[9] ,(byte[3]&0x02)?"(Blocked)":""); + + return sprintf (buf, "%s\n", buf); +} + +static char* bios_str[] = { + "BIOS1", //0 + "BIOS2", //1 +}; + +static ssize_t show_bios_cs(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + ssize_t len = 0; + u8 byte = 0; + + mutex_lock(&data->update_lock); + len = cpld_i2c_read(client, &byte, CPLD_BIOSCS_OFFSET, 1); + mutex_unlock(&data->update_lock); + if (len==0) return 0; + + byte &= 0x01; + + return sprintf (buf, "%d:%s\n", byte,bios_str[byte]); +} + +static ssize_t set_bios_cs(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte = 0; + u8 temp = simple_strtol(buf, NULL, 10); + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_BIOSCS_OFFSET, 1); + if(temp) byte |= 0x01; else byte &= ~(0x01); + cpld_i2c_write(client, &byte, CPLD_BIOSCS_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return count; +} + +static char* led_str[] = { + "OFF", //00 + "Green/Blue", //01 + "Yellow/Orange", //10 + "Red", //11 +}; + +static ssize_t show_led(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + ssize_t len = 0; + u8 byte = 0; + int shift = attr->index; + + mutex_lock(&data->update_lock); + len = cpld_i2c_read(client, &byte, CPLD_LED_OFFSET, 1); + mutex_unlock(&data->update_lock); + if (len==0) return 0; + + byte = (byte >> shift) & 0x3; + + return sprintf (buf, "%d:%s\n", byte, led_str[byte]); +} + +static ssize_t set_led(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + + u8 temp = simple_strtol(buf, NULL, 16); + u8 byte = 0; + int shift = attr->index; + temp &= 0x3; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_LED_OFFSET, 1); + byte &= ~(0x3<update_lock); + + return count; +} + +static char* sysled_str[] = { + "OFF", //000 + "0.5 Hz", //001 + "1 Hz", //010 + "2 Hz", //011 + "4 Hz", //100 + "NA", //101 + "NA", //110 + "ON", //111 +}; + +static ssize_t show_sysled(struct device *dev, struct device_attribute *da, + char *buf) +{ + u32 status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte; + int shift = (attr->index == 0)?3:0; + + mutex_lock(&data->update_lock); + status = cpld_i2c_read(client, &byte, CPLD_SYSLED_OFFSET, 1); + mutex_unlock(&data->update_lock); + + byte = (byte >> shift) & 0x7; + status = sprintf (buf, "%d:%s\n", byte, sysled_str[byte]); + + return strlen(buf); +} + +static ssize_t set_sysled(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 cpld_data *data = i2c_get_clientdata(client); + + u8 temp = simple_strtol(buf, NULL, 16); + u8 byte; + int shift = (attr->index == 0)?3:0; + + temp &= 0x7; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_SYSLED_OFFSET, 1); + byte &= ~(0x7<update_lock); + + return count; +} + +static char* psu_str[] = { + "unpowered", //00 + "normal", //01 + "not installed", //10 + "not installed", //11 +}; + +static ssize_t show_psu(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + ssize_t len = 0; + u8 byte=0; + int shift = (attr->index == 0)?0:4; + + mutex_lock(&data->update_lock); + len = cpld_i2c_read(client2, &byte, CPLD_PSU_OFFSET, 1); + mutex_unlock(&data->update_lock); + if (len==0) return 0; + + byte = (byte >> shift) & 0x3; + + return sprintf (buf, "%d:%s\n", byte, psu_str[byte]); +} + +static ssize_t show_pwm(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + ssize_t len = 0; + u8 byte=0; + u8 offset = attr->index + CPLD_PWM_OFFSET; + + mutex_lock(&data->update_lock); + len = cpld_i2c_read(client2, &byte, offset, 1); + mutex_unlock(&data->update_lock); + if (len==0) return 0; + + return sprintf(buf, "%d\n", byte); +} + +static ssize_t set_pwm(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 offset = attr->index + CPLD_PWM_OFFSET; + u8 byte = simple_strtol(buf, NULL, 10); + + mutex_lock(&data->update_lock); + cpld_i2c_write(client2, &byte, offset, 1); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_rpm(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + ssize_t len = 0; + u8 offset = attr->index*2 + CPLD_RPM_OFFSET; + u8 byte[2] = {0,0}; + + mutex_lock(&data->update_lock); + len = cpld_i2c_read(client2, byte, offset, 2); + mutex_unlock(&data->update_lock); + if (len==0) return 0; + + return sprintf(buf, "%d\n", (byte[0]<<8 | byte[1])); +} + +static char* fantype_str[] = { + "Normal Type", //00 + "REVERSAL Type", //01 + "UNPLUGGED", //10 + "UNPLUGGED", //11 +}; + +static ssize_t show_fantype(struct device *dev, struct device_attribute *da, + char *buf) +{ + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + ssize_t len = 0; + u8 offset = CPLD_FANSTATUS_OFFSET; + u8 byte[2] = {0,0}; + + mutex_lock(&data->update_lock); + len = cpld_i2c_read(client2, byte, offset, 2); + mutex_unlock(&data->update_lock); + if (len==0) return 0; + status = (((byte[0] >> attr->index) & 0x01)) | (((byte[1] >> attr->index) & 0x01)<<1); + + return sprintf(buf, "%d:%s\n",status,fantype_str[status]); +} + +static char* fanled_str[] = { + "None", //00 + "Green", //01 + "Red", //10 + "Both", //11 +}; + +static ssize_t show_fanled(struct device *dev, struct device_attribute *da, + char *buf) +{ + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + ssize_t len = 0; + u8 byte[2] = {0,0}; + + mutex_lock(&data->update_lock); + len = cpld_i2c_read(client2, byte, CPLD_FANLED_OFFSET, 2); + mutex_unlock(&data->update_lock); + if (len==0) return 0; + status = (((byte[0] >> attr->index) & 0x01)) | (((byte[1] >> attr->index) & 0x01)<<1); + + return sprintf(buf, "%d:%s\n",status,fanled_str[status]); +} + +static ssize_t set_fanled(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte[2] = {0,0}; + u8 temp = simple_strtol(buf, NULL, 16); + int shift = attr->index; + + temp &= 0x3; + mutex_lock(&data->update_lock); + cpld_i2c_read(client2, byte, CPLD_FANLED_OFFSET, 2); + byte[0] &= ~(1<> 1) & 0x01)<update_lock); + + return count; +} + +static ssize_t set_watchdog_feed(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte=0; + + mutex_lock(&data->update_lock); + cpld_i2c_read(client, &byte, CPLD_WATCHDOGENABLE_OFFSET, 1); + byte |= 0x02; + cpld_i2c_write(client, &byte, CPLD_WATCHDOGENABLE_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t set_watchdog_enable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte=0x03; + + mutex_lock(&data->update_lock); + cpld_i2c_write(client, &byte, CPLD_WATCHDOGENABLE_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_watchdog_enable(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + ssize_t len = 0; + u8 byte=0; + + mutex_lock(&data->update_lock); + len = cpld_i2c_read(client, &byte, CPLD_WATCHDOGENABLE_OFFSET, 1); + mutex_unlock(&data->update_lock); + if (len==0) return 0; + + return sprintf(buf, "%d\n",(byte&0x01)); +} + +static ssize_t set_watchdog_config(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 byte = simple_strtol(buf, NULL, 10); + + if (byte<6) byte=6; + mutex_lock(&data->update_lock); + cpld_i2c_write(client, &byte, CPLD_WATCHDOGCONFIG_OFFSET, 1); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_watchdog_config(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + ssize_t len = 0; + u8 byte=0; + + mutex_lock(&data->update_lock); + len = cpld_i2c_read(client, &byte, CPLD_WATCHDOGCONFIG_OFFSET, 1); + mutex_unlock(&data->update_lock); + if (len==0) return 0; + + return sprintf(buf, "%d seconds\n",byte); +} + +static ssize_t show_watchdog_counter(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + ssize_t len = 0; + u8 byte=0; + + mutex_lock(&data->update_lock); + len = cpld_i2c_read(client, &byte, CPLD_WATCHDOGCOUNTER_OFFSET, 1); + mutex_unlock(&data->update_lock); + if (len==0) return 0; + + return sprintf(buf, "%d seconds\n",byte); +} + +static SENSOR_DEVICE_ATTR(info, S_IRUGO, show_info, 0, 0); +static SENSOR_DEVICE_ATTR(diag, S_IWUSR|S_IRUGO, show_diag, set_diag, 0); +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_thermal, 0, 0); +static SENSOR_DEVICE_ATTR(interrupt, S_IRUGO, show_interrupt, 0, 0); + +static SENSOR_DEVICE_ATTR(fan_led, S_IWUSR|S_IRUGO, show_led, set_led, 2); +static SENSOR_DEVICE_ATTR(power_led, S_IWUSR|S_IRUGO, show_led, set_led, 4); +static SENSOR_DEVICE_ATTR(location_led, S_IWUSR|S_IRUGO, show_led, set_led, 6); + +static SENSOR_DEVICE_ATTR(grn_led, S_IWUSR|S_IRUGO, show_sysled, set_sysled, 0); +static SENSOR_DEVICE_ATTR(red_led, S_IWUSR|S_IRUGO, show_sysled, set_sysled, 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 SENSOR_DEVICE_ATTR(pwm3, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 2); +static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 3); +#if FAN_NUM>4 +static SENSOR_DEVICE_ATTR(pwm5, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 4); +#endif + +static SENSOR_DEVICE_ATTR(fanmodule1_type, S_IRUGO, show_fantype, 0, 0); +static SENSOR_DEVICE_ATTR(fanmodule2_type, S_IRUGO, show_fantype, 0, 1); +static SENSOR_DEVICE_ATTR(fanmodule3_type, S_IRUGO, show_fantype, 0, 2); +static SENSOR_DEVICE_ATTR(fanmodule4_type, S_IRUGO, show_fantype, 0, 3); +#if FAN_NUM>4 +static SENSOR_DEVICE_ATTR(fanmodule5_type, S_IRUGO, show_fantype, 0, 4); +#endif + +static SENSOR_DEVICE_ATTR(fanmodule1_led, S_IWUSR|S_IRUGO, show_fanled, set_fanled, 0); +static SENSOR_DEVICE_ATTR(fanmodule2_led, S_IWUSR|S_IRUGO, show_fanled, set_fanled, 1); +static SENSOR_DEVICE_ATTR(fanmodule3_led, S_IWUSR|S_IRUGO, show_fanled, set_fanled, 2); +static SENSOR_DEVICE_ATTR(fanmodule4_led, S_IWUSR|S_IRUGO, show_fanled, set_fanled, 3); +#if FAN_NUM>4 +static SENSOR_DEVICE_ATTR(fanmodule5_led, S_IWUSR|S_IRUGO, show_fanled, set_fanled, 4); +#endif + +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_rpm, 0, 0); +static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_rpm, 0, 1); +static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_rpm, 0, 2); +static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_rpm, 0, 3); +static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_rpm, 0, 4); +static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_rpm, 0, 5); +static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_rpm, 0, 6); +static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_rpm, 0, 7); +#if FAN_NUM>4 +static SENSOR_DEVICE_ATTR(fan9_input, S_IRUGO, show_rpm, 0, 8); +static SENSOR_DEVICE_ATTR(fan10_input,S_IRUGO, show_rpm, 0, 9); +#endif + +static SENSOR_DEVICE_ATTR(psu1, S_IRUGO, show_psu, 0, 0); +static SENSOR_DEVICE_ATTR(psu2, S_IRUGO, show_psu, 0, 1); +static SENSOR_DEVICE_ATTR(power_status, S_IRUGO, show_powerstatus, 0, 0); + +static SENSOR_DEVICE_ATTR(watchdog_feed, S_IWUSR, 0, set_watchdog_feed, 0); +static SENSOR_DEVICE_ATTR(watchdog_enable, S_IWUSR|S_IRUGO, show_watchdog_enable, set_watchdog_enable, 0); +static SENSOR_DEVICE_ATTR(watchdog_config, S_IWUSR|S_IRUGO, show_watchdog_config, set_watchdog_config, 0); +static SENSOR_DEVICE_ATTR(watchdog_counter, S_IRUGO, show_watchdog_counter, 0, 0); + +static SENSOR_DEVICE_ATTR(bios_cs, S_IWUSR|S_IRUGO, show_bios_cs, set_bios_cs, 0); + +static struct attribute *cpld_attributes[] = { + &sensor_dev_attr_info.dev_attr.attr, + &sensor_dev_attr_diag.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + + &sensor_dev_attr_fan_led.dev_attr.attr, + &sensor_dev_attr_power_led.dev_attr.attr, + &sensor_dev_attr_location_led.dev_attr.attr, + + &sensor_dev_attr_grn_led.dev_attr.attr, + &sensor_dev_attr_red_led.dev_attr.attr, + + &sensor_dev_attr_interrupt.dev_attr.attr, + + &sensor_dev_attr_psu1.dev_attr.attr, + &sensor_dev_attr_psu2.dev_attr.attr, + &sensor_dev_attr_power_status.dev_attr.attr, + + &sensor_dev_attr_pwm1.dev_attr.attr, + &sensor_dev_attr_pwm2.dev_attr.attr, + &sensor_dev_attr_pwm3.dev_attr.attr, + &sensor_dev_attr_pwm4.dev_attr.attr, +#if FAN_NUM>4 + &sensor_dev_attr_pwm5.dev_attr.attr, +#endif + &sensor_dev_attr_fanmodule1_type.dev_attr.attr, + &sensor_dev_attr_fanmodule2_type.dev_attr.attr, + &sensor_dev_attr_fanmodule3_type.dev_attr.attr, + &sensor_dev_attr_fanmodule4_type.dev_attr.attr, +#if FAN_NUM>4 + &sensor_dev_attr_fanmodule5_type.dev_attr.attr, +#endif + &sensor_dev_attr_fanmodule1_led.dev_attr.attr, + &sensor_dev_attr_fanmodule2_led.dev_attr.attr, + &sensor_dev_attr_fanmodule3_led.dev_attr.attr, + &sensor_dev_attr_fanmodule4_led.dev_attr.attr, +#if FAN_NUM>4 + &sensor_dev_attr_fanmodule5_led.dev_attr.attr, +#endif + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, + &sensor_dev_attr_fan4_input.dev_attr.attr, + &sensor_dev_attr_fan5_input.dev_attr.attr, + &sensor_dev_attr_fan6_input.dev_attr.attr, + &sensor_dev_attr_fan7_input.dev_attr.attr, + &sensor_dev_attr_fan8_input.dev_attr.attr, +#if FAN_NUM>4 + &sensor_dev_attr_fan9_input.dev_attr.attr, + &sensor_dev_attr_fan10_input.dev_attr.attr, +#endif + &sensor_dev_attr_watchdog_feed.dev_attr.attr, + &sensor_dev_attr_watchdog_enable.dev_attr.attr, + &sensor_dev_attr_watchdog_config.dev_attr.attr, + &sensor_dev_attr_watchdog_counter.dev_attr.attr, + + &sensor_dev_attr_bios_cs.dev_attr.attr, + NULL +}; + +static const struct attribute_group cpld_group = { + .attrs = cpld_attributes, +}; + +/*-----------------------------------------------------------------------*/ +/* device probe and removal */ +static int +cpld_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct cpld_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) + return -EIO; + + data = kzalloc(sizeof(struct cpld_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &cpld_group); + + if (status) + goto exit_free; + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + //Check CPLD2 exist or not + client2 = i2c_new_dummy(client->adapter, CPLD2_ADDRESS); + if(!client2) { + hasCPLD2 = 0; + client2 = client; + } else { + status = i2c_smbus_read_byte_data(client2, CPLD_INFO_OFFSET); + if(status<0) { + i2c_unregister_device(client2); + i2c_set_clientdata(client2, NULL); + hasCPLD2 = 0; + client2 = client; + } + } + + data->tsk = kthread_run(cpld_thread,client,"%s",dev_name(data->hwmon_dev)); + dev_info(&client->dev, "%s: sensor '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &cpld_group); +exit_free: + i2c_set_clientdata(client, NULL); + kfree(data); + return status; +} + +static int cpld_remove(struct i2c_client *client) +{ + struct cpld_data *data = i2c_get_clientdata(client); + + sysfs_remove_group(&client->dev.kobj, &cpld_group); + hwmon_device_unregister(data->hwmon_dev); + i2c_set_clientdata(client, NULL); + if(hasCPLD2) { + i2c_unregister_device(client2); + i2c_set_clientdata(client2, NULL); + } + + kfree(data); + return 0; +} + +static const struct i2c_device_id cpld_ids[] = { + { "inv_cpld" , 0, }, + { /* LIST END */ } +}; +MODULE_DEVICE_TABLE(i2c, cpld_ids); + +static struct i2c_driver cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "inv_cpld", + }, + .probe = cpld_probe, + .remove = cpld_remove, + .id_table = cpld_ids, +}; + +/*-----------------------------------------------------------------------*/ + +/* module glue */ + +static int __init inv_cpld_init(void) +{ + return i2c_add_driver(&cpld_driver); +} + +static void __exit inv_cpld_exit(void) +{ + i2c_del_driver(&cpld_driver); +} + +MODULE_AUTHOR("jack.ting "); +MODULE_DESCRIPTION("cpld driver"); +MODULE_LICENSE("GPL"); + +module_init(inv_cpld_init); +module_exit(inv_cpld_exit); diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_eeprom.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_eeprom.c new file mode 100644 index 000000000000..7bb167d2e74e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_eeprom.c @@ -0,0 +1,181 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + + +/* Size of EEPROM in bytes */ +#define EEPROM_SIZE 256 + +#define SLICE_BITS (6) +#define SLICE_SIZE (1 << SLICE_BITS) +#define SLICE_NUM (EEPROM_SIZE/SLICE_SIZE) + +/* Each client has this additional data */ +struct eeprom_data { + struct mutex update_lock; + u8 valid; /* bitfield, bit!=0 if slice is valid */ + unsigned long last_updated[SLICE_NUM]; /* In jiffies, 8 slices */ + u8 data[EEPROM_SIZE]; /* Register values */ +}; + + +static void inv_eeprom_update_client(struct i2c_client *client, u8 slice) +{ + struct eeprom_data *data = i2c_get_clientdata(client); + int i, j; + int ret; + int addr; + + + mutex_lock(&data->update_lock); + + if (!(data->valid & (1 << slice)) || + time_after(jiffies, data->last_updated[slice] + 300 * HZ)) { + dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice); + + addr = slice << SLICE_BITS; + + ret = i2c_smbus_write_byte_data(client, ((u8)addr >> 8) & 0xFF, (u8)addr & 0xFF); + /* select the eeprom address */ + if (ret < 0) { + dev_err(&client->dev, "address set failed\n"); + goto exit; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE)) { + goto exit; + } + + for (i = slice << SLICE_BITS; i < (slice + 1) << SLICE_BITS; i+= SLICE_SIZE) { + for (j = i; j < (i+SLICE_SIZE); j++) { + int res; + + res = i2c_smbus_read_byte(client); + if (res < 0) { + goto exit; + } + + data->data[j] = res & 0xFF; + } + } + + data->last_updated[slice] = jiffies; + data->valid |= (1 << slice); + } + +exit: + mutex_unlock(&data->update_lock); +} + +static ssize_t inv_eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct eeprom_data *data = i2c_get_clientdata(client); + u8 slice; + + + if (off > EEPROM_SIZE) { + return 0; + } + if (off + count > EEPROM_SIZE) { + count = EEPROM_SIZE - off; + } + if (count == 0) { + return 0; + } + + /* Only refresh slices which contain requested bytes */ + for (slice = off >> SLICE_BITS; slice <= (off + count - 1) >> SLICE_BITS; slice++) { + inv_eeprom_update_client(client, slice); + } + + memcpy(buf, &data->data[off], count); + + return count; +} + +static struct bin_attribute inv_eeprom_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO, + }, + .size = EEPROM_SIZE, + .read = inv_eeprom_read, +}; + +static int inv_eeprom_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct eeprom_data *data; + int err; + + if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { + err = -ENOMEM; + goto exit; + } + + memset(data->data, 0xff, EEPROM_SIZE); + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + /* create the sysfs eeprom file */ + err = sysfs_create_bin_file(&client->dev.kobj, &inv_eeprom_attr); + if (err) { + goto exit_kfree; + } + + return 0; + +exit_kfree: + kfree(data); +exit: + return err; +} + +static int inv_eeprom_remove(struct i2c_client *client) +{ + sysfs_remove_bin_file(&client->dev.kobj, &inv_eeprom_attr); + kfree(i2c_get_clientdata(client)); + + return 0; +} + +static const struct i2c_device_id inv_eeprom_id[] = { + { "inv_eeprom", 0 }, + { } +}; + +static struct i2c_driver inv_eeprom_driver = { + .driver = { + .name = "inv_eeprom", + }, + .probe = inv_eeprom_probe, + .remove = inv_eeprom_remove, + .id_table = inv_eeprom_id, +}; + +module_i2c_driver(inv_eeprom_driver); + +MODULE_AUTHOR("Inventec"); +MODULE_DESCRIPTION("Inventec D6556 Mother Board EEPROM driver"); +MODULE_LICENSE("GPL"); + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_mux.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_mux.c new file mode 100644 index 000000000000..143aee309dba --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_mux.c @@ -0,0 +1,547 @@ +#include +#include +#include +#include +#include +#include +#include "io_expander.h" +#include "inv_mux.h" + +/* For build single module using (Ex: ONL platform) */ +#include +//#include +//#include + + +static struct mux_obj_s *mux_head_p = NULL; + +/* ========== MUX object functions ========== + */ +static int +_setup_i2c_value(struct mux_obj_s *self, int offset, int value){ + + return i2c_smbus_write_byte_data(self->i2c_client_p, offset, value); +} + + +static int +_setup_i2c_client(struct mux_obj_s *self, int chan_id, int addr){ + + struct i2c_adapter *adap = NULL; + char *emsg = "ERR"; + + adap = i2c_get_adapter(chan_id); + if (!adap){ + emsg = "can't get adapter"; + goto err_setup_i2c_client; + } + self->i2c_client_p = kzalloc(sizeof(*self->i2c_client_p), GFP_KERNEL); + if (!self->i2c_client_p){ + emsg = "can't kzalloc client"; + goto err_setup_i2c_client; + } + self->i2c_client_p->adapter = adap; + self->i2c_client_p->addr = addr; + return 0; + +err_setup_i2c_client: + SWPS_ERR("%s: %s\n", __func__, emsg); + return ERR_MUX_UNEXCPT; +} + + +int +_common_force_pull_gpio(int mem_addr, + int input, + int bit_offset){ + + unsigned int val = 0; + unsigned int targ = 0; + + /* Get current value */ + val = inl(mem_addr); + if (val == 0) { + SWPS_ERR("%s: inl:%d fail!\n", __func__, val); + return -1; + } + /* Count target value */ + switch (input) { + case 0: /* Pull Low */ + targ = (val & (~(1 << bit_offset))); + break; + case 1: /* Pull high */ + targ = (val | (1 << bit_offset)); + break; + default: + SWPS_ERR("%s: input state:%d incorrect!\n", + __func__, input); + return -1; + } + /* Setup gpio */ + outl(targ, mem_addr); + if (targ != inl(mem_addr)){ + SWPS_ERR("%s: outl:%d fail!\n", __func__, targ); + return -1; + } + SWPS_DEBUG("%s: done.\n", __func__); + return 0; +} + + +int +rangeley_force_pull_high(struct mux_obj_s *self){ + SWPS_ERR("%s: not ready!\n", __func__); + return -1; +} + + +int +rangeley_force_pull_low(struct mux_obj_s *self){ + SWPS_ERR("%s: not ready!\n", __func__); + return -1; +} + + +int +hedera_force_pull_high(struct mux_obj_s *self){ + return _common_force_pull_gpio(MUX_RST_MEM_ADDR_HEDERA, 1, 5); +} + + +int +hedera_force_pull_low(struct mux_obj_s *self){ + return _common_force_pull_gpio(MUX_RST_MEM_ADDR_HEDERA, 0, 5); +} + + +int +normal_gpio_pull_high(struct mux_obj_s *self){ + return gpio_direction_output(self->gpio_num, 1); +} + + +int +normal_gpio_pull_low(struct mux_obj_s *self){ + return gpio_direction_output(self->gpio_num, 0); +} + + +int +cpld_rst_all_4_pull_low(struct mux_obj_s *self){ + + char *emsg = "ERR"; + int err = ERR_MUX_UNEXCPT; + + switch(self->gpio_num) { + case MUX_RST_CPLD_C0_A77_70_74_RST_ALL: + goto setlow_cpld_rst_all_4_c0_a77_70_74_rst_all; + + default: + break; + } + emsg = "Undefined case"; + goto err_cpld_rst_all_4_pull_low; + +setlow_cpld_rst_all_4_c0_a77_70_74_rst_all: + err = _setup_i2c_value(self, 0x70, 0x0); + if (err < 0) { + emsg = "setup 0x70 fail"; + goto err_cpld_rst_all_4_pull_low; + } + err = _setup_i2c_value(self, 0x74, 0x01); + if (err < 0) { + emsg = "setup 0x74 fail"; + goto err_cpld_rst_all_4_pull_low; + } + return 0; + +err_cpld_rst_all_4_pull_low: + SWPS_INFO("%s: %s :%d :%d\n", + __func__, emsg, self->gpio_num, err); + return ERR_MUX_UNEXCPT; +} + + +int +cpld_rst_all_4_pull_high(struct mux_obj_s *self){ + + char *emsg = "ERR"; + int err = ERR_MUX_UNEXCPT; + + switch(self->gpio_num) { + case MUX_RST_CPLD_C0_A77_70_74_RST_ALL: + goto sethigh_cpld_rst_all_4_c0_a77_70_74_rst_all; + + default: + break; + } + emsg = "Undefined case"; + goto err_cpld_rst_all_4_pull_high; + +sethigh_cpld_rst_all_4_c0_a77_70_74_rst_all: + err = _setup_i2c_value(self, 0x70, 0xfe); + if (err < 0) { + emsg = "setup 0x70 fail"; + goto err_cpld_rst_all_4_pull_high; + } + err = _setup_i2c_value(self, 0x74, 0x03); + if (err < 0) { + emsg = "setup 0x74 fail"; + goto err_cpld_rst_all_4_pull_high; + } + return 0; + +err_cpld_rst_all_4_pull_high: + SWPS_INFO("%s: %s :%d :%d\n", + __func__, emsg, self->gpio_num, err); + return ERR_MUX_UNEXCPT; +} + + +int +pca9548_reset_mux_all(struct mux_obj_s *self){ + /* [Note] Power-on reset (PCA9548A-NXP) + * When power is applied to VDD, an internal Power-On Reset (POR) + * holds the PCA9548A in a reset condition until VDD has reached + * VPOR. At this point, the reset condition is released and the + * PCA9548A register and I2C-bus state machine are initialized to + * their default states (all zeroes) causing all the channels to + * be deselected. Thereafter, VDD must be lowered below 0.2 V for + * at least 5 us in order to reset the device. + */ + if (self->_pull_low(self) < 0) { + SWPS_ERR("%s: _pull_low fail!\n", __func__); + return -1; + } + mdelay(MUX_RST_WAIT_MS_PCA9548); + if (self->_pull_high(self) < 0) { + SWPS_ERR("%s: _pull_high fail!\n", __func__); + return -1; + } + mdelay(MUX_RST_WAIT_MS_PCA9548); + return 0; +} + + +int +cpld_reset_mux_all(struct mux_obj_s *self){ + + char *emsg = "ERR"; + int err = ERR_MUX_UNEXCPT; + + switch(self->gpio_num) { + case MUX_RST_CPLD_C0_A77_70_74_RST_ALL: + goto reset_cpld_rst_all_4_c0_a77_70_74_rst_all; + + default: + break; + } + emsg = "Undefined case"; + goto err_cpld_reset_mux_all; + +reset_cpld_rst_all_4_c0_a77_70_74_rst_all: + if (self->_pull_low(self) < 0) { + emsg = "_pull_low fail"; + goto err_cpld_reset_mux_all; + } + mdelay(MUX_RST_WAIT_MS_CPLD); + return 0; + +err_cpld_reset_mux_all: + SWPS_INFO("%s: %s :%d :%d\n", + __func__, emsg, self->gpio_num, err); + return ERR_MUX_UNEXCPT; +} + + +int +common_reset_mux_all(struct mux_obj_s *self){ + SWPS_ERR("%s: not ready!\n", __func__); + return -1; +} + + +int +init_gpio_4_force(struct mux_obj_s *self){ + + if (self->_pull_high(self) < 0) { + SWPS_ERR("%s: setup default fail!\n", __func__); + return -1; + } + return 0; +} + + +int +init_gpio_4_normal(struct mux_obj_s *self){ + + int err = 0; + char *emsg = "ERR"; + + if (!gpio_is_valid(self->gpio_num)) { + emsg = "GPIO invalid"; + goto err_init_gpio_4_normal; + } + err = gpio_request(self->gpio_num, MUX_GPIO_LABEL); + if (err < 0) { + emsg = "gpio_request fail"; + goto err_init_gpio_4_normal; + } + err = self->_pull_high(self); + if (err < 0) { + emsg = "setup default fail"; + goto err_init_gpio_4_normal; + } + SWPS_DEBUG("%s: gpio_request:%d ok.\n", __func__, self->gpio_num); + return 0; + +err_init_gpio_4_normal: + SWPS_ERR("%s: %s :%d :%d\n", + __func__, emsg, self->gpio_num, err); + return -1; +} + + +int +init_cpld_4_rst_all(struct mux_obj_s *self){ + + char *emsg = "ERR"; + int err = ERR_MUX_UNEXCPT; + int chan = ERR_MUX_UNEXCPT; + int addr = ERR_MUX_UNEXCPT; + + switch(self->gpio_num) { + case MUX_RST_CPLD_C0_A77_70_74_RST_ALL: + goto init_cpld_i2c_c0_a77_70_74_rst_all; + + default: + break; + } + emsg = "Undefined case"; + goto err_init_cpld_4_rst_all; + +init_cpld_i2c_c0_a77_70_74_rst_all: + chan = 0; + addr = 0x77; + err = _setup_i2c_client(self, chan, addr); + if (err < 0) { + emsg = "_setup_i2c_client fail"; + goto err_init_cpld_4_rst_all; + } + err = self->_pull_high(self); + if (err < 0) { + emsg = "setup default value fail"; + goto err_init_cpld_4_rst_all; + } + SWPS_DEBUG("%s: init_cpld_i2c_c0_a77_70_74_rst_all ok", __func__); + return 0; + +err_init_cpld_4_rst_all: + SWPS_INFO("%s: %s :%d :%d\n", + __func__, emsg, self->gpio_num, err); + return ERR_MUX_UNEXCPT; +} + + +int +clean_gpio_4_common(struct mux_obj_s *self){ + + if (!self) return 0; + if (!gpio_is_valid(self->gpio_num)) return 0; + self->_pull_high(self); + gpio_free(mux_head_p->gpio_num); + return 0; +} + + +int +clean_cpld_4_rst_all(struct mux_obj_s *self){ + + if (!self) return 0; + self->_pull_high(self); + if (self->i2c_client_p) { + i2c_put_adapter(self->i2c_client_p->adapter); + kfree(self->i2c_client_p); + } + return 0; +} + + +static int +_setup_muxctl_cb(struct mux_obj_s *self, + unsigned gpio){ + + char mod_dsc[32] = "ERR"; + + switch (gpio) { + case MUX_RST_GPIO_FORCE_RANGELEY: + self->gpio_num = gpio; + self->_pull_low = rangeley_force_pull_low; + self->_pull_high = rangeley_force_pull_high; + self->_init = init_gpio_4_force; + self->_clean = clean_gpio_4_common; + self->reset = pca9548_reset_mux_all; + memset(mod_dsc, 0, 32); + snprintf(mod_dsc, 31, "Rangeley force mode"); + goto ok_setup_muxctl_cb; + + case MUX_RST_GPIO_FORCE_HEDERA: + self->gpio_num = gpio; + self->_pull_low = hedera_force_pull_low; + self->_pull_high = hedera_force_pull_high; + self->_init = init_gpio_4_force; + self->_clean = clean_gpio_4_common; + self->reset = pca9548_reset_mux_all; + memset(mod_dsc, 0, 32); + snprintf(mod_dsc, 31, "Hedera force mode"); + goto ok_setup_muxctl_cb; + + case MUX_RST_GPIO_48_PCA9548: + case MUX_RST_GPIO_69_PCA9548: + case MUX_RST_GPIO_249_PCA9548: + case MUX_RST_GPIO_500_PCA9548: + case MUX_RST_GPIO_505_PCA9548: + self->gpio_num = gpio; + self->_pull_low = normal_gpio_pull_low; + self->_pull_high = normal_gpio_pull_high; + self->_init = init_gpio_4_normal; + self->_clean = clean_gpio_4_common; + self->reset = pca9548_reset_mux_all; + memset(mod_dsc, 0, 32); + snprintf(mod_dsc, 31, "Normal mode :%d", (int)gpio); + goto ok_setup_muxctl_cb; + + case MUX_RST_CPLD_C0_A77_70_74_RST_ALL: + self->gpio_num = gpio; + self->_pull_low = cpld_rst_all_4_pull_low; + self->_pull_high = cpld_rst_all_4_pull_high; + self->_init = init_cpld_4_rst_all; + self->_clean = clean_cpld_4_rst_all; + self->reset = cpld_reset_mux_all; + memset(mod_dsc, 0, 32); + snprintf(mod_dsc, 31, "CPLD mode :%d", (int)gpio); + goto ok_setup_muxctl_cb; + + default: + break; + } + SWPS_ERR("%s: Unexpected GPIO:%d\n", __func__, gpio); + return -1; + +ok_setup_muxctl_cb: + SWPS_INFO("muxctl: %s.\n", mod_dsc); + return 0; +} + + +/* ========== MUX public functions ========== + */ +void +clean_mux_objs(void){ + + struct mux_obj_s *curr_p = mux_head_p; + struct mux_obj_s *next_p = NULL; + + if (!curr_p) { + SWPS_DEBUG("%s: mux_head_p is NULL\n", __func__); + return; + } + while (curr_p) { + next_p = curr_p->next; + curr_p->_clean(curr_p); + kfree(curr_p); + curr_p = next_p; + } + SWPS_DEBUG("%s: done.\n", __func__); +} +EXPORT_SYMBOL(clean_mux_objs); + + +int +reset_mux_objs(void){ + + if (!mux_head_p) { + SWPS_ERR("%s: MUX ctl object doesn't exist!\n", __func__); + return -1; + } + if (mux_head_p->reset(mux_head_p) < 0){ + SWPS_ERR("%s: reset fail!\n", __func__); + return -1; + } + return 0; +} +EXPORT_SYMBOL(reset_mux_objs); + + +struct mux_obj_s * +_create_mux_obj(unsigned gpio){ + + char *emsg = "ERR"; + struct mux_obj_s *obj_p = NULL; + + obj_p = kzalloc(sizeof(struct mux_obj_s), GFP_KERNEL); + if (!obj_p) { + emsg = "kzalloc fail!"; + goto err_create_mux_obj_1; + } + if (_setup_muxctl_cb(obj_p, gpio) < 0){ + emsg = "_setup_muxctl_cb fail!"; + goto err_create_mux_obj_2; + } + if (obj_p->_init(obj_p) < 0) { + emsg = "_init() fail!"; + goto err_create_mux_obj_2; + } + SWPS_DEBUG("%s: created MUX object :%d\n", __func__, gpio); + return obj_p; + +err_create_mux_obj_2: + kfree(obj_p); +err_create_mux_obj_1: + SWPS_ERR("%s: %s :%d\n", __func__, emsg, gpio); + return NULL; +} + + +int +init_mux_objs(unsigned gpio){ + + struct mux_obj_s *curr_p = NULL; + char *emsg = "ERR"; + + /* Create MUX control object */ + if (mux_head_p) { + SWPS_DEBUG("%s: mux_head_p is not NULL!\n", __func__); + clean_mux_objs(); + } + /* Currently, it is using single muxctl architecture. + * In the future, it may use the multi-muxctl. + * (Ex: Gulmohar's advance I2C control / Peony's reset single mux) + */ + curr_p = _create_mux_obj(gpio); + if (!curr_p) { + emsg = "_create_mux_obj fail"; + goto err_init_mux_objs; + } + curr_p->next = NULL; + mux_head_p = curr_p; + SWPS_DEBUG("%s: all done. :%d\n", __func__, gpio); + return 0; + +err_init_mux_objs: + clean_mux_objs(); + SWPS_ERR("%s: %s\n", __func__, emsg); + return -1; +} +EXPORT_SYMBOL(init_mux_objs); + + +/* For single ko module + * => You need to declare MODULE_LICENSE If you want to build single module along. + * => Ex: For ONL platform + */ +MODULE_LICENSE("GPL"); + + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_mux.h b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_mux.h new file mode 100644 index 000000000000..a913b24c6053 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_mux.h @@ -0,0 +1,51 @@ +#ifndef INV_MUX_H +#define INV_MUX_H + +#include + +/* MUX basic information */ +#define MUX_GPIO_LABEL "SWPS_RST_MUX" + +/* MUX reset GPIO define */ +#define MUX_RST_GPIO_FORCE (30100) +#define MUX_RST_GPIO_FORCE_RANGELEY (30101) +#define MUX_RST_GPIO_FORCE_HEDERA (30102) +#define MUX_RST_GPIO_48_PCA9548 (48) +#define MUX_RST_GPIO_69_PCA9548 (69) +#define MUX_RST_GPIO_249_PCA9548 (249) +#define MUX_RST_GPIO_500_PCA9548 (500) +#define MUX_RST_GPIO_505_PCA9548 (505) +#define MUX_RST_CPLD_C0_A77_70_74_RST_ALL (30201) + +/* MUX relate value define */ +#define MUX_RST_WAIT_MS_PCA9548 (1) +#define MUX_RST_WAIT_MS_CPLD (10) +#define MUX_RST_MEM_ADDR_RANGELEY (0) // TBD +#define MUX_RST_MEM_ADDR_HEDERA (0x548) + +/* MUX error code define */ +#define ERR_MUX_UNEXCPT (-399) + +struct mux_obj_s { + struct i2c_client *i2c_client_p; + struct mux_obj_s *next; + unsigned gpio_num; + int (*_pull_high)(struct mux_obj_s *self); + int (*_pull_low)(struct mux_obj_s *self); + int (*_init)(struct mux_obj_s *self); + int (*_clean)(struct mux_obj_s *self); + int (*reset)(struct mux_obj_s *self); +}; + + +void clean_mux_objs(void); +int reset_mux_objs(void); +int init_mux_objs(unsigned gpio); + + +#endif /* INV_MUX_H */ + + + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_platform.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_platform.c new file mode 100644 index 000000000000..212388c8e98d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_platform.c @@ -0,0 +1,297 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +struct inv_i2c_board_info { + int ch; + int size; + struct i2c_board_info *board_info; +}; + +#define bus_id(id) (id) +static struct pca954x_platform_mode pca9641_modes_1[] = { + {.adap_id = bus_id(2),}, +}; + +static struct pca954x_platform_mode pca9641_modes_2[] = { + {.adap_id = bus_id(5),}, +}; + +static struct pca954x_platform_mode pca9641_modes_3[] = { + {.adap_id = bus_id(3),}, +}; + +static struct pca954x_platform_mode pca9641_modes_4[] = { + {.adap_id = bus_id(4),}, +}; + +static struct pca954x_platform_mode mux_modes_0[] = { + {.adap_id = bus_id(6),}, {.adap_id = bus_id(7),}, + {.adap_id = bus_id(8),}, {.adap_id = bus_id(9),}, + {.adap_id = bus_id(10),}, {.adap_id = bus_id(11),}, + {.adap_id = bus_id(12),}, {.adap_id = bus_id(13),}, +}; +static struct pca954x_platform_mode mux_modes_0_0[] = { + {.adap_id = bus_id(14),}, {.adap_id = bus_id(15),}, + {.adap_id = bus_id(16),}, {.adap_id = bus_id(17),}, + {.adap_id = bus_id(18),}, {.adap_id = bus_id(19),}, + {.adap_id = bus_id(20),}, {.adap_id = bus_id(21),}, +}; + +static struct pca954x_platform_mode mux_modes_0_1[] = { + {.adap_id = bus_id(22),}, {.adap_id = bus_id(23),}, + {.adap_id = bus_id(24),}, {.adap_id = bus_id(25),}, + {.adap_id = bus_id(26),}, {.adap_id = bus_id(27),}, + {.adap_id = bus_id(28),}, {.adap_id = bus_id(29),}, +}; + +static struct pca954x_platform_mode mux_modes_0_2[] = { + {.adap_id = bus_id(30),}, {.adap_id = bus_id(31),}, + {.adap_id = bus_id(32),}, {.adap_id = bus_id(33),}, + {.adap_id = bus_id(34),}, {.adap_id = bus_id(35),}, + {.adap_id = bus_id(36),}, {.adap_id = bus_id(37),}, +}; + +static struct pca954x_platform_mode mux_modes_0_3[] = { + {.adap_id = bus_id(38),}, {.adap_id = bus_id(39),}, + {.adap_id = bus_id(40),}, {.adap_id = bus_id(41),}, + {.adap_id = bus_id(42),}, {.adap_id = bus_id(43),}, + {.adap_id = bus_id(44),}, {.adap_id = bus_id(45),}, +}; + +static struct pca954x_platform_mode mux_modes_0_4[] = { + {.adap_id = bus_id(46),}, {.adap_id = bus_id(47),}, + {.adap_id = bus_id(48),}, {.adap_id = bus_id(49),}, + {.adap_id = bus_id(50),}, {.adap_id = bus_id(51),}, + {.adap_id = bus_id(52),}, {.adap_id = bus_id(53),}, +}; + +static struct pca954x_platform_mode mux_modes_0_5[] = { + {.adap_id = bus_id(54),}, {.adap_id = bus_id(55),}, + {.adap_id = bus_id(56),}, {.adap_id = bus_id(57),}, + {.adap_id = bus_id(58),}, {.adap_id = bus_id(59),}, + {.adap_id = bus_id(60),}, {.adap_id = bus_id(61),}, +}; + +static struct pca954x_platform_mode mux_modes_0_6[] = { + {.adap_id = bus_id(62),}, {.adap_id = bus_id(63),}, + {.adap_id = bus_id(64),}, {.adap_id = bus_id(65),}, + {.adap_id = bus_id(66),}, {.adap_id = bus_id(67),}, + {.adap_id = bus_id(68),}, {.adap_id = bus_id(69),}, +}; + +//no i2c device driver attach to mux 7 + +static struct pca954x_platform_data pca9641_data_1 = { + .modes = pca9641_modes_1, + .num_modes = 1, +}; +static struct pca954x_platform_data pca9641_data_2 = { + .modes = pca9641_modes_2, + .num_modes = 1, +}; +static struct pca954x_platform_data pca9641_data_3 = { + .modes = pca9641_modes_3, + .num_modes = 1, +}; +static struct pca954x_platform_data pca9641_data_4 = { + .modes = pca9641_modes_4, + .num_modes = 1, +}; +static struct pca954x_platform_data mux_data_0 = { + .modes = mux_modes_0, + .num_modes = 8, +}; +static struct pca954x_platform_data mux_data_0_0 = { + .modes = mux_modes_0_0, + .num_modes = 8, +}; +static struct pca954x_platform_data mux_data_0_1 = { + .modes = mux_modes_0_1, + .num_modes = 8, +}; +static struct pca954x_platform_data mux_data_0_2 = { + .modes = mux_modes_0_2, + .num_modes = 8, +}; +static struct pca954x_platform_data mux_data_0_3 = { + .modes = mux_modes_0_3, + .num_modes = 8, +}; +static struct pca954x_platform_data mux_data_0_4 = { + .modes = mux_modes_0_4, + .num_modes = 8, +}; +static struct pca954x_platform_data mux_data_0_5 = { + .modes = mux_modes_0_5, + .num_modes = 8, +}; +static struct pca954x_platform_data mux_data_0_6 = { + .modes = mux_modes_0_6, + .num_modes = 8, +}; + +static struct i2c_board_info i2c_device_info0[] __initdata = { + {"pca9641", 0, 0x76, &pca9641_data_1, 0, 0}, //PCA9641-1 + {"pca9641", 0, 0x73, &pca9641_data_3, 0, 0}, //PCA9641-3 + {"pca9641", 0, 0x09, &pca9641_data_4, 0, 0}, //PCA9641-4 +}; +static struct i2c_board_info i2c_device_info1[] __initdata = { + {"pca9641", 0, 0x0A, &pca9641_data_2, 0, 0}, //PCA9641-2 +}; +static struct i2c_board_info i2c_device_info2[] __initdata = { + {"inv_cpld", 0, 0x77, 0, 0, 0}, //CPLD +}; +static struct i2c_board_info i2c_device_info3[] __initdata = { + {"tmp75", 0, 0x48, 0, 0, 0}, //CPU Board Temp + {"tmp75", 0, 0x4A, 0, 0, 0}, //Temp + {"tmp75", 0, 0x4D, 0, 0, 0}, //Temp + {"tmp75", 0, 0x4E, 0, 0, 0}, //Temp +}; +static struct i2c_board_info i2c_device_info4[] __initdata = { + {"pmbus", 0, 0x5B, 0, 0, 0}, //PSU1 + {"pmbus", 0, 0x5A, 0, 0, 0}, //PSU2 +}; +static struct i2c_board_info i2c_device_info5[] __initdata = { + {"pca9548", 0, 0x70, &mux_data_0, 0, 0}, //mux root +}; +static struct i2c_board_info i2c_device_info6[] __initdata = { + {"pca9548", 0, 0x72, &mux_data_0_0, 0, 0}, +}; +static struct i2c_board_info i2c_device_info7[] __initdata = { + {"pca9548", 0, 0x72, &mux_data_0_1, 0, 0}, +}; +static struct i2c_board_info i2c_device_info8[] __initdata = { + {"pca9548", 0, 0x72, &mux_data_0_2, 0, 0}, +}; +static struct i2c_board_info i2c_device_info9[] __initdata = { + {"pca9548", 0, 0x72, &mux_data_0_3, 0, 0}, +}; +static struct i2c_board_info i2c_device_info10[] __initdata = { + {"pca9548", 0, 0x72, &mux_data_0_4, 0, 0}, +}; +static struct i2c_board_info i2c_device_info11[] __initdata = { + {"pca9548", 0, 0x72, &mux_data_0_5, 0, 0}, +}; +static struct i2c_board_info i2c_device_info12[] __initdata = { + {"pca9548", 0, 0x72, &mux_data_0_6, 0, 0}, +}; + + +static struct inv_i2c_board_info i2cdev_list[] = { + {bus_id(0), ARRAY_SIZE(i2c_device_info0), i2c_device_info0 }, //SMBus + {bus_id(1), ARRAY_SIZE(i2c_device_info1), i2c_device_info1 }, //pca9641-2 + {bus_id(2), ARRAY_SIZE(i2c_device_info2), i2c_device_info2 }, //pca9641-1 + {bus_id(3), ARRAY_SIZE(i2c_device_info3), i2c_device_info3 }, //pca9641-3 + {bus_id(4), ARRAY_SIZE(i2c_device_info4), i2c_device_info4 }, //pca9641-4 + {bus_id(5), ARRAY_SIZE(i2c_device_info5), i2c_device_info5 }, //mux root + {bus_id(6), ARRAY_SIZE(i2c_device_info6), i2c_device_info6 }, //mux CH0 + {bus_id(7), ARRAY_SIZE(i2c_device_info7), i2c_device_info7 }, //mux CH1 + {bus_id(8), ARRAY_SIZE(i2c_device_info8), i2c_device_info8 }, //mux CH2 + {bus_id(9), ARRAY_SIZE(i2c_device_info9), i2c_device_info9 }, //mux CH3 + {bus_id(10),ARRAY_SIZE(i2c_device_info10), i2c_device_info10}, //mux CH4 + {bus_id(11),ARRAY_SIZE(i2c_device_info11), i2c_device_info11}, //mux CH5 + {bus_id(12),ARRAY_SIZE(i2c_device_info12), i2c_device_info12}, //mux CH6 +}; + +#define INV_PLATFORM_CLIENT_MAX_NUM 50 /*A big enough number for sum of i2cdev_list[i].size */ +static int client_list_index = 0; +static struct i2c_client *client_list[INV_PLATFORM_CLIENT_MAX_NUM] = {0}; + +///////////////////////////////////////////////////////////////////////////////////////// +static struct platform_device *device_i2c_gpio0; +static struct i2c_gpio_platform_data i2c_gpio_platdata0 = { + .scl_pin = 58, //494, + .sda_pin = 75, //511, + + .udelay = 5, //5:100kHz + .sda_is_open_drain = 0, + .scl_is_open_drain = 0, + .scl_is_output_only = 0 +}; + +static int __init inv_platform_init(void) +{ + struct i2c_adapter *adap = NULL; + struct i2c_client *e = NULL; + int ret = 0; + int i,j,k; + + //printk("%s \n", __func__); + + //use i2c-gpio + //register i2c gpio + //config gpio58,75 to gpio function 58=32+3*8+2 75=32*2+8*1+3 gpio69=32*2+8*0+5 + outl( inl(0x533) | (1<<2), 0x533); //i2c-gpio sdl (GPIO58) + outl( inl(0x541) | (1<<3), 0x541); //i2c-gpio sda (GPIO75) + outl( inl(0x540) | (1<<5), 0x540); //RST_I2C_MUX_N (GPIO69) + outl( inl(0x500) | (1<<7), 0x500); //SYS_RDY_N (GPIO7) + outl( inl(0x501) | (1<<7), 0x501); //BMC_HEART_BEAT (GPIO15) + outl( inl(0x503) | (1<<2)|(1<<3), 0x503); //PSOC_HEART_BEAT(26),CPLD_HEART_BEAT(27) + + device_i2c_gpio0 = platform_device_alloc("i2c-gpio", 1); + if (!device_i2c_gpio0) { + printk(KERN_ERR "i2c-gpio: platform_device_alloc fail\n"); + return -ENOMEM; + } + device_i2c_gpio0->name = "i2c-gpio"; + device_i2c_gpio0->id = 1; + device_i2c_gpio0->dev.platform_data = &i2c_gpio_platdata0; + + ret = platform_device_add(device_i2c_gpio0); + if (ret) { + printk(KERN_ERR "i2c-gpio: platform_device_add fail %d\n", ret); + } + msleep(10); + + for(i=0; i=0; i--) { + i2c_unregister_device(client_list[i]); + } + device_i2c_gpio0->dev.platform_data = NULL; + platform_device_unregister(device_i2c_gpio0); + printk("inv_platform_exit done\n"); +} + +module_init(inv_platform_init); +module_exit(inv_platform_exit); + +MODULE_AUTHOR("Inventec"); +MODULE_DESCRIPTION("Platform devices"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_swps.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_swps.c new file mode 100644 index 000000000000..11b60f78ae90 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_swps.c @@ -0,0 +1,3266 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "inv_swps.h" + +static int ctl_major; +static int port_major; +static int ioexp_total; +static int port_total; +static int block_polling; +static int auto_config; +static int flag_i2c_reset; +static int flag_mod_state; +static unsigned gpio_rest_mux; +static struct class *swp_class_p = NULL; +static struct inv_platform_s *platform_p = NULL; +static struct inv_ioexp_layout_s *ioexp_layout = NULL; +static struct inv_port_layout_s *port_layout = NULL; +int io_no_init = 0; +module_param(io_no_init, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); +static void swp_polling_worker(struct work_struct *work); +static DECLARE_DELAYED_WORK(swp_polling, swp_polling_worker); + +static int reset_i2c_topology(void); + + +static int +__swp_match(struct device *dev, +#ifdef SWPS_KERN_VER_AF_3_10 + + const void *data){ +#else + void *data){ +#endif + + char *name = (char *)data; + if (strcmp(dev_name(dev), name) == 0) + return 1; + return 0; +} + + +struct device * +get_swpdev_by_name(char *name){ + struct device *dev = class_find_device(swp_class_p, + NULL, + name, + __swp_match); + return dev; +} + + +static int +sscanf_2_int(const char *buf) { + + int result = -EBFONT; + char *hex_tag = "0x"; + + if (strcspn(buf, hex_tag) == 0) { + if (sscanf(buf,"%x",&result)) { + return result; + } + } else { + if (sscanf(buf,"%d",&result)) { + return result; + } + if(sscanf(buf,"-%d",&result)) { + return -result; + } + if (sscanf(buf,"%x",&result)) { + return result; + } + } + return -EBFONT; +} + + +static int +sscanf_2_binary(const char *buf) { + + int result = sscanf_2_int(buf); + + if (result < 0){ + return -EBFONT; + } + switch (result) { + case 0: + case 1: + return result; + default: + break; + } + return -EBFONT; +} + + +static int +_get_polling_period(void) { + + int retval = 0; + + if (SWP_POLLING_PERIOD == 0) { + return 0; + } + retval = ((SWP_POLLING_PERIOD * HZ) / 1000); + if (retval == 0) { + return 1; + } + return retval; +} + + +static struct transvr_obj_s * +_get_transvr_obj(char *dev_name) { + + struct device *dev_p = NULL; + struct transvr_obj_s *transvr_obj_p = NULL; + + dev_p = get_swpdev_by_name(dev_name); + if (!dev_p){ + return NULL; + } + transvr_obj_p = dev_get_drvdata(dev_p); + if (!transvr_obj_p){ + return NULL; + } + return transvr_obj_p; +} + + +static int +_is_i2c_target_exist(int chan, int addr) { + /* retval: Exist = 1 / Not exist = 0 / Error < 0 + */ + struct i2c_adapter *adap = NULL; + struct i2c_client *client = NULL; + int retval = -1; + int err = -1; + int d_offs = 0; + + adap = i2c_get_adapter(chan); + if (!adap) { + SWPS_DEBUG("%s: can't get adapter\n", __func__); + retval = 0; + goto out_is_i2c_target_exist_1; + } + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (!client) { + SWPS_ERR("%s: kzalloc fail\n", __func__); + retval = -1; + goto out_is_i2c_target_exist_2; + } + client->adapter = adap; + client->addr = addr; + err = i2c_smbus_read_byte_data(client, d_offs); + if (err < 0) { + retval = 0; + } else { + retval = 1; + } + i2c_put_adapter(adap); + kfree(client); + return retval; + +out_is_i2c_target_exist_2: + i2c_put_adapter(adap); +out_is_i2c_target_exist_1: + return retval; +} + + +static void +unlock_tobj_all(void) { + + struct transvr_obj_s *tobj_p; + char port_name[32]; + int port_id = 0; + int minor_curr = 0; + + for (minor_curr=0; minor_currauto_config = auto_config; + unlock_transvr_obj(tobj_p); + SWPS_DEBUG("%s: Set %s auto_config=%d\n", + __func__, tobj_p->swp_name, auto_config); + } + return retval; +} + + +/* ========== R/W Functions module control attribute ========== + */ +static ssize_t +show_attr_platform(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + return snprintf(buf_p, 32, "%s\n", platform_p->name); +} + + +static ssize_t +show_attr_version(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + return snprintf(buf_p, 8, "%s\n", SWP_VERSION); +} + + +static ssize_t +show_attr_status(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + return snprintf(buf_p, 8, "%d\n", flag_mod_state); +} + + +static ssize_t +show_attr_auto_config(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + return snprintf(buf_p, 8, "%d\n", auto_config); +} + + +static ssize_t +show_attr_block_poll(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + return snprintf(buf_p, 8, "%d\n", block_polling); +} +static ssize_t +show_attr_io_no_init(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + return snprintf(buf_p, 8, "%d\n", io_no_init); +} + + +static int +_check_reset_pwd(const char *buf_p, + size_t count) { + + int in_max = 64; + int in_len = (int)count; + char in_val[64] = "ERR"; + char *emsg = "ERR"; + + if (in_len >= in_max) { + emsg = "input too much"; + goto err_check_reset_pwd; + } + if (!sscanf(buf_p,"%s",in_val)) { + emsg = "format incorrect"; + goto err_check_reset_pwd; + } + if (strcmp(in_val, SWP_RESET_PWD) != 0) { + emsg = "password incorrect"; + goto err_check_reset_pwd; + } + return 0; + +err_check_reset_pwd: + SWPS_ERR("%s: %s\n", __func__, emsg); + return -1; +} + + +static ssize_t +store_attr_reset_i2c(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + if (_check_reset_pwd(buf_p, count) < 0) { + return -EBFONT; + } + /* Polling mode */ + if (SWP_POLLING_ENABLE) { + SWPS_INFO("%s: reset I2C :polling\n", __func__); + flag_i2c_reset = 1; + return count; + } + /* Direct mode */ + SWPS_INFO("%s: reset I2C go. :direct\n", __func__); + if (reset_i2c_topology() < 0) { + SWPS_ERR("%s: reset fail!\n", __func__); + return -EIO; + } + SWPS_INFO("%s: reset I2C ok. :direct\n", __func__); + return count; +} + + +static ssize_t +store_attr_reset_swps(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p; + char port_name[32] = "ERR"; + int port_id = 0; + int minor_curr = 0; + + if (_check_reset_pwd(buf_p, count) < 0) { + return -EBFONT; + } + for (minor_curr=0; minor_currstate = STATE_TRANSVR_DISCONNECTED; + unlock_transvr_obj(tobj_p); + SWPS_INFO("%s: reset:%s\n", __func__, tobj_p->swp_name); + } + return count; +} + + +static ssize_t +store_attr_auto_config(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + int input_val = sscanf_2_int(buf_p); + + if (input_val < 0){ + return -EBFONT; + } + if ((input_val != 0) && (input_val != 1)) { + return -EBFONT; + } + auto_config = input_val; + _update_auto_config_2_trnasvr(); + return count; +} + + +static ssize_t +store_attr_block_poll( struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + int input_val = sscanf_2_int(buf_p); + + if (input_val < 0){ + return -EBFONT; + } + if ((input_val != 0) && (input_val != 1)) { + return -EBFONT; + } + + if(input_val != block_polling){ + block_polling = input_val; + if(block_polling){ + cancel_delayed_work_sync(&swp_polling); + } + else{ + schedule_delayed_work(&swp_polling, _get_polling_period()); + } + } + + return count; +} + +static ssize_t +store_attr_io_no_init( struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + int input_val = sscanf_2_int(buf_p); + + if ((input_val != 0) && (input_val != 1)) { + return -EBFONT; + } + + if(input_val != io_no_init){ + io_no_init = input_val; + } + + return count; +} + +/* ========== Show functions: For transceiver attribute ========== + */ +static ssize_t +_show_transvr_hex_attr(struct transvr_obj_s* tobj_p, + int (*get_func)(struct transvr_obj_s* tobj_p), + char *buf_p) { + size_t len; + int result; + + lock_transvr_obj(tobj_p); + result = get_func(tobj_p); + unlock_transvr_obj(tobj_p); + if (result < 0){ + len = snprintf(buf_p, 8, "%d\n", result); + } else { + len = snprintf(buf_p, 8, "0x%02x\n", result); + } + return len; +} + + +static ssize_t +_show_transvr_int_attr(struct transvr_obj_s* tobj_p, + int (*get_func)(struct transvr_obj_s* tobj_p), + char *buf_p) { + size_t len; + + lock_transvr_obj(tobj_p); + len = snprintf(buf_p, 16, "%d\n", get_func(tobj_p)); + unlock_transvr_obj(tobj_p); + return len; +} + + +static ssize_t +_show_transvr_str_attr(struct transvr_obj_s* tobj_p, + int (*get_func)(struct transvr_obj_s* tobj_p, char* buf), + char *buf_p) { + size_t len; + + lock_transvr_obj(tobj_p); + len = get_func(tobj_p, buf_p); + unlock_transvr_obj(tobj_p); + return len; +} + + +static ssize_t +show_attr_id(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_id, + buf_p); +} + + +static ssize_t +show_attr_ext_id(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_ext_id, + buf_p); +} + + +static ssize_t +show_attr_connector(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_connector, + buf_p); +} + + +static ssize_t +show_attr_vendor_name(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_vendor_name, + buf_p); +} + + +static ssize_t +show_attr_vendor_pn(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_vendor_pn, + buf_p); +} + + +static ssize_t +show_attr_vendor_rev(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_vendor_rev, + buf_p); +} + + +static ssize_t +show_attr_vendor_sn(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_vendor_sn, + buf_p); +} + + +static ssize_t +show_attr_power_cls(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + size_t len; + int result; + struct transvr_obj_s *tobj_p; + + tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + lock_transvr_obj(tobj_p); + result = tobj_p->get_power_cls(tobj_p); + unlock_transvr_obj(tobj_p); + if (result < 0){ + len = snprintf(buf_p, 16, "%d\n", result); + } else { + len = snprintf(buf_p, 16, "Power Class %d\n", result); + } + return len; +} + + +static ssize_t +show_attr_br(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_br, + buf_p); +} + + +static ssize_t +show_attr_len_sm(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_len_sm, + buf_p); +} + + +static ssize_t +show_attr_len_smf(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_len_smf, + buf_p); +} + + +static ssize_t +show_attr_len_om1(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_len_om1, + buf_p); +} + + +static ssize_t +show_attr_len_om2(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_len_om2, + buf_p); +} + + +static ssize_t +show_attr_len_om3(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_len_om3, + buf_p); +} + + +static ssize_t +show_attr_len_om4(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_len_om4, + buf_p); +} + + +static ssize_t +show_attr_comp_rev(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_comp_rev, + buf_p); +} + + +static ssize_t +show_attr_comp_eth(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_comp_eth_1, + buf_p); +} + + +static ssize_t +show_attr_comp_eth_10(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_comp_eth_10, + buf_p); +} + + +static ssize_t +show_attr_comp_eth_10_40(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_comp_eth_10_40, + buf_p); +} + + +static ssize_t +show_attr_comp_extend(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_comp_extend, + buf_p); +} + + +static ssize_t +show_attr_rate_id(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_rate_id, + buf_p); +} + + +static ssize_t +show_attr_temperature(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_curr_temp, + buf_p); +} + + +static ssize_t +show_attr_voltage(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_curr_vol, + buf_p); +} + + +static ssize_t +show_attr_tx_bias(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_tx_bias, + buf_p); +} + + +static ssize_t +show_attr_tx_power(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_tx_power, + buf_p); +} + + +static ssize_t +show_attr_tx_eq(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_tx_eq, + buf_p); +} + + +static ssize_t +show_attr_rx_power(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_rx_power, + buf_p); +} + + +static ssize_t +show_attr_rx_am(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_rx_am, + buf_p); +} + + +static ssize_t +show_attr_rx_em(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_rx_em, + buf_p); +} + + +static ssize_t +show_attr_wavelength(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_wavelength, + buf_p); +} + + +static ssize_t +show_attr_extphy_offset(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_extphy_offset, + buf_p); +} + + +static ssize_t +show_attr_extphy_reg(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_extphy_reg, + buf_p); +} + + +static ssize_t +show_attr_info(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_info, + buf_p); +} + + +static ssize_t +show_attr_if_type(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_if_type, + buf_p); +} + + +static ssize_t +show_attr_if_speed(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_if_speed, + buf_p); +} + + +static ssize_t +show_attr_if_lane(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_if_lane, + buf_p); +} + + +static ssize_t +show_attr_cdr(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_hex_attr(tobj_p, + tobj_p->get_cdr, + buf_p); +} + + +static ssize_t +show_attr_soft_rs0(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_soft_rs0, + buf_p); +} + + +static ssize_t +show_attr_soft_rs1(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_int_attr(tobj_p, + tobj_p->get_soft_rs1, + buf_p); +} + + +static ssize_t +show_attr_soft_rx_los(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_soft_rx_los, + buf_p); +} + + +static ssize_t +show_attr_soft_tx_disable(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_soft_tx_disable, + buf_p); +} + + +static ssize_t +show_attr_soft_tx_fault(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_soft_tx_fault, + buf_p); +} + + +static ssize_t +show_attr_auto_tx_disable(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if(!tobj_p){ + return -ENODEV; + } + return _show_transvr_str_attr(tobj_p, + tobj_p->get_auto_tx_disable, + buf_p); +} + + +/* ========== Store functions: transceiver (R/W) attribute ========== + */ +static ssize_t +_store_transvr_int_attr(struct transvr_obj_s* tobj_p, + int (*set_func)(struct transvr_obj_s *tobj_p, int input_val), + const char *buf_p, + size_t count) { + int input, err; + + input = sscanf_2_int(buf_p); + if (input < 0){ + return -EBFONT; + } + lock_transvr_obj(tobj_p); + err = set_func(tobj_p, input); + unlock_transvr_obj(tobj_p); + if (err < 0){ + return err; + } + return count; +} + + +static ssize_t +_store_transvr_byte_hex_attr(struct transvr_obj_s* tobj_p, + int (*set_func)(struct transvr_obj_s *tobj_p, int input_val), + const char *buf_p, + size_t count) { + int input, err; + + input = sscanf_2_int(buf_p); + if ((input < 0) || (input > 0xff)){ + return -EBFONT; + } + lock_transvr_obj(tobj_p); + err = set_func(tobj_p, input); + unlock_transvr_obj(tobj_p); + if (err < 0){ + return err; + } + return count; +} + + +static ssize_t +_store_transvr_binary_attr(struct transvr_obj_s* tobj_p, + int (*set_func)(struct transvr_obj_s *tobj_p, int input_val), + const char *buf_p, + size_t count) { + int input, err; + + input = sscanf_2_binary(buf_p); + if (input < 0){ + return -EBFONT; + } + lock_transvr_obj(tobj_p); + err = set_func(tobj_p, input); + unlock_transvr_obj(tobj_p); + if (err < 0){ + return err; + } + return count; +} + + +static ssize_t +store_attr_cdr(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_byte_hex_attr(tobj_p, + tobj_p->set_cdr, + buf_p, + count); +} + + +static ssize_t +store_attr_soft_rs0(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_binary_attr(tobj_p, + tobj_p->set_soft_rs0, + buf_p, + count); +} + + +static ssize_t +store_attr_soft_rs1(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_binary_attr(tobj_p, + tobj_p->set_soft_rs1, + buf_p, + count); +} + + +static ssize_t +store_attr_soft_tx_disable(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count) { + + int check = sscanf_2_int(buf_p); + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + if ((check < 0) || (check > 0xf)){ + return -EBFONT; + } + return _store_transvr_byte_hex_attr(tobj_p, + tobj_p->set_soft_tx_disable, + buf_p, + count); +} + + +static ssize_t +store_attr_auto_tx_disable(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count) { + + int err = -EPERM; + int input = sscanf_2_int(buf_p); + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + if ((input < 0) || (input > 0xf)){ + if (input != VAL_TRANSVR_FUNCTION_DISABLE) { + return -EBFONT; + } + } + lock_transvr_obj(tobj_p); + err = tobj_p->set_auto_tx_disable(tobj_p, input); + unlock_transvr_obj(tobj_p); + if (err < 0){ + return err; + } + return count; +} + + +static ssize_t +store_attr_tx_eq(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_int_attr(tobj_p, + tobj_p->set_tx_eq, + buf_p, + count); +} + + +static ssize_t +store_attr_rx_am(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_int_attr(tobj_p, + tobj_p->set_rx_am, + buf_p, + count); +} + + +static ssize_t +store_attr_rx_em(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_int_attr(tobj_p, + tobj_p->set_rx_em, + buf_p, + count); +} + + +static ssize_t +store_attr_extphy_offset(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_int_attr(tobj_p, + tobj_p->set_extphy_offset, + buf_p, + count); +} + + +static ssize_t +store_attr_extphy_reg(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _store_transvr_int_attr(tobj_p, + tobj_p->set_extphy_reg, + buf_p, + count); +} + +/* ========== Show functions: For I/O Expander attribute ========== + */ +static ssize_t +_show_ioexp_binary_attr(struct transvr_obj_s *tobj_p, + int (*get_func)(struct ioexp_obj_s *ioexp_p, int voffset), + char *buf_p) { + size_t len; + struct ioexp_obj_s *ioexp_p = tobj_p->ioexp_obj_p; + + if (!ioexp_p) { + SWPS_ERR(" %s: data corruption! :%s\n", __func__, tobj_p->swp_name); + return -ENODATA; + } + mutex_lock(&ioexp_p->lock); + len = snprintf(buf_p, 8, "%d\n", get_func(ioexp_p, tobj_p->ioexp_virt_offset)); + mutex_unlock(&ioexp_p->lock); + return len; +} + + +static ssize_t +show_attr_present(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_present, + buf_p); +} + + +static ssize_t +show_attr_tx_fault(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_tx_fault, + buf_p); +} + + +static ssize_t +show_attr_rxlos(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_rxlos, + buf_p); +} + + +static ssize_t +show_attr_tx_disable(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_tx_disable, + buf_p); +} + + +static ssize_t +show_attr_reset(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_reset, + buf_p); +} + + +static ssize_t +show_attr_lpmod(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_lpmod, + buf_p); +} + + +static ssize_t +show_attr_modsel(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_modsel, + buf_p); +} + + +static ssize_t +show_attr_hard_rs0(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_hard_rs0, + buf_p); +} + + +static ssize_t +show_attr_hard_rs1(struct device *dev_p, + struct device_attribute *attr_p, + char *buf_p){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p){ + return -ENODEV; + } + return _show_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->get_hard_rs1, + buf_p); +} + + +/* ========== Store functions: For I/O Expander (R/W) attribute ========== + */ +static ssize_t +_store_ioexp_binary_attr(struct transvr_obj_s *tobj_p, + int (*set_func)(struct ioexp_obj_s *ioexp_p, + int virt_offset, int input_val), + const char *buf_p, + size_t count) { + + int input, err; + struct ioexp_obj_s *ioexp_p = tobj_p->ioexp_obj_p; + + if (!ioexp_p) { + SWPS_ERR("%s: data corruption! :%s\n", + __func__, tobj_p->swp_name); + return -ENODATA; + } + input = sscanf_2_binary(buf_p); + if (input < 0) { + return -EBFONT; + } + mutex_lock(&ioexp_p->lock); + err = set_func(ioexp_p, tobj_p->ioexp_virt_offset, input); + mutex_unlock(&ioexp_p->lock); + if (err < 0){ + return err; + } + return count; +} + +static ssize_t +store_attr_tx_disable(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p) { + return -ENODEV; + } + return _store_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->set_tx_disable, + buf_p, + count); +} + + +static ssize_t +store_attr_reset(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p) { + return -ENODEV; + } + return _store_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->set_reset, + buf_p, + count); +} + + +static ssize_t +store_attr_lpmod(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p) { + return -ENODEV; + } + return _store_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->set_lpmod, + buf_p, + count); +} + + +static ssize_t +store_attr_modsel(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p) { + return -ENODEV; + } + return _store_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->set_modsel, + buf_p, + count); +} + + +static ssize_t +store_attr_hard_rs0(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p) { + return -ENODEV; + } + return _store_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->set_hard_rs0, + buf_p, + count); +} + + +static ssize_t +store_attr_hard_rs1(struct device *dev_p, + struct device_attribute *attr_p, + const char *buf_p, + size_t count){ + + struct transvr_obj_s *tobj_p = dev_get_drvdata(dev_p); + if (!tobj_p) { + return -ENODEV; + } + return _store_ioexp_binary_attr(tobj_p, + tobj_p->ioexp_obj_p->set_hard_rs1, + buf_p, + count); +} + + +/* ========== SWPS attribute: For module control ========== + */ +static DEVICE_ATTR(platform, S_IRUGO, show_attr_platform, NULL); +static DEVICE_ATTR(version, S_IRUGO, show_attr_version, NULL); +static DEVICE_ATTR(status, S_IRUGO, show_attr_status, NULL); +static DEVICE_ATTR(reset_i2c, S_IWUSR, NULL, store_attr_reset_i2c); +static DEVICE_ATTR(reset_swps, S_IWUSR, NULL, store_attr_reset_swps); +static DEVICE_ATTR(auto_config, S_IRUGO|S_IWUSR, show_attr_auto_config, store_attr_auto_config); +static DEVICE_ATTR(block_poll, S_IRUGO|S_IWUSR, show_attr_block_poll, store_attr_block_poll); +static DEVICE_ATTR(io_no_init, S_IRUGO|S_IWUSR, show_attr_io_no_init, store_attr_io_no_init); + + +/* ========== Transceiver attribute: from eeprom ========== + */ +static DEVICE_ATTR(id, S_IRUGO, show_attr_id, NULL); +static DEVICE_ATTR(ext_id, S_IRUGO, show_attr_ext_id, NULL); +static DEVICE_ATTR(connector, S_IRUGO, show_attr_connector, NULL); +static DEVICE_ATTR(vendor_name, S_IRUGO, show_attr_vendor_name, NULL); +static DEVICE_ATTR(vendor_pn, S_IRUGO, show_attr_vendor_pn, NULL); +static DEVICE_ATTR(vendor_rev, S_IRUGO, show_attr_vendor_rev, NULL); +static DEVICE_ATTR(vendor_sn, S_IRUGO, show_attr_vendor_sn, NULL); +static DEVICE_ATTR(power_cls, S_IRUGO, show_attr_power_cls, NULL); +static DEVICE_ATTR(br, S_IRUGO, show_attr_br, NULL); +static DEVICE_ATTR(len_sm, S_IRUGO, show_attr_len_sm, NULL); +static DEVICE_ATTR(len_smf, S_IRUGO, show_attr_len_smf, NULL); +static DEVICE_ATTR(len_om1, S_IRUGO, show_attr_len_om1, NULL); +static DEVICE_ATTR(len_om2, S_IRUGO, show_attr_len_om2, NULL); +static DEVICE_ATTR(len_om3, S_IRUGO, show_attr_len_om3, NULL); +static DEVICE_ATTR(len_om4, S_IRUGO, show_attr_len_om4, NULL); +static DEVICE_ATTR(comp_rev, S_IRUGO, show_attr_comp_rev, NULL); +static DEVICE_ATTR(comp_eth, S_IRUGO, show_attr_comp_eth, NULL); +static DEVICE_ATTR(comp_eth_10, S_IRUGO, show_attr_comp_eth_10, NULL); +static DEVICE_ATTR(comp_eth_10_40, S_IRUGO, show_attr_comp_eth_10_40, NULL); +static DEVICE_ATTR(comp_extend, S_IRUGO, show_attr_comp_extend, NULL); +static DEVICE_ATTR(rate_id, S_IRUGO, show_attr_rate_id, NULL); +static DEVICE_ATTR(temperature, S_IRUGO, show_attr_temperature, NULL); +static DEVICE_ATTR(voltage, S_IRUGO, show_attr_voltage, NULL); +static DEVICE_ATTR(tx_bias, S_IRUGO, show_attr_tx_bias, NULL); +static DEVICE_ATTR(tx_power, S_IRUGO, show_attr_tx_power, NULL); +static DEVICE_ATTR(rx_power, S_IRUGO, show_attr_rx_power, NULL); +static DEVICE_ATTR(info, S_IRUGO, show_attr_info, NULL); +static DEVICE_ATTR(if_type, S_IRUGO, show_attr_if_type, NULL); +static DEVICE_ATTR(if_speed, S_IRUGO, show_attr_if_speed, NULL); +static DEVICE_ATTR(if_lane, S_IRUGO, show_attr_if_lane, NULL); +static DEVICE_ATTR(soft_rx_los, S_IRUGO, show_attr_soft_rx_los, NULL); +static DEVICE_ATTR(soft_tx_fault, S_IRUGO, show_attr_soft_tx_fault, NULL); +static DEVICE_ATTR(wavelength, S_IRUGO, show_attr_wavelength, NULL); +static DEVICE_ATTR(tx_eq, S_IRUGO|S_IWUSR, show_attr_tx_eq, store_attr_tx_eq); +static DEVICE_ATTR(rx_am, S_IRUGO|S_IWUSR, show_attr_rx_am, store_attr_rx_am); +static DEVICE_ATTR(rx_em, S_IRUGO|S_IWUSR, show_attr_rx_em, store_attr_rx_em); +static DEVICE_ATTR(cdr, S_IRUGO|S_IWUSR, show_attr_cdr, store_attr_cdr); +static DEVICE_ATTR(soft_rs0, S_IRUGO|S_IWUSR, show_attr_soft_rs0, store_attr_soft_rs0); +static DEVICE_ATTR(soft_rs1, S_IRUGO|S_IWUSR, show_attr_soft_rs1, store_attr_soft_rs1); +static DEVICE_ATTR(soft_tx_disable, S_IRUGO|S_IWUSR, show_attr_soft_tx_disable, store_attr_soft_tx_disable); +static DEVICE_ATTR(auto_tx_disable, S_IRUGO|S_IWUSR, show_attr_auto_tx_disable, store_attr_auto_tx_disable); +static DEVICE_ATTR(extphy_offset, S_IRUGO|S_IWUSR, show_attr_extphy_offset, store_attr_extphy_offset); +static DEVICE_ATTR(extphy_reg, S_IRUGO|S_IWUSR, show_attr_extphy_reg, store_attr_extphy_reg); + +/* ========== IO Expander attribute: from expander ========== + */ +static DEVICE_ATTR(present, S_IRUGO, show_attr_present, NULL); +static DEVICE_ATTR(tx_fault, S_IRUGO, show_attr_tx_fault, NULL); +static DEVICE_ATTR(rxlos, S_IRUGO, show_attr_rxlos, NULL); +static DEVICE_ATTR(tx_disable, S_IRUGO|S_IWUSR, show_attr_tx_disable, store_attr_tx_disable); +static DEVICE_ATTR(reset, S_IRUGO|S_IWUSR, show_attr_reset, store_attr_reset); +static DEVICE_ATTR(lpmod, S_IRUGO|S_IWUSR, show_attr_lpmod, store_attr_lpmod); +static DEVICE_ATTR(modsel, S_IRUGO|S_IWUSR, show_attr_modsel, store_attr_modsel); +static DEVICE_ATTR(hard_rs0, S_IRUGO|S_IWUSR, show_attr_hard_rs0, store_attr_hard_rs0); +static DEVICE_ATTR(hard_rs1, S_IRUGO|S_IWUSR, show_attr_hard_rs1, store_attr_hard_rs1); + +/* ========== Functions for module handling ========== + */ +static void +clean_port_objs(void){ + + dev_t dev_num; + char dev_name[32]; + struct device *device_p; + struct transvr_obj_s *tobj_p; + int minor_curr, port_id; + + for (minor_curr=0; minor_curri2c_client_p) { + i2c_put_adapter(tobj_p->i2c_client_p->adapter); + kfree(tobj_p->i2c_client_p); + } + kfree(tobj_p->vendor_name); + kfree(tobj_p->vendor_pn); + kfree(tobj_p->vendor_rev); + kfree(tobj_p->vendor_sn); + kfree(tobj_p->worker_p); + kfree(tobj_p); + } + dev_num = MKDEV(port_major, minor_curr); + device_unregister(device_p); + device_destroy(swp_class_p, dev_num); + } + SWPS_DEBUG("%s: done.\n", __func__); +} + + +static void +clean_swps_common(void){ + + dev_t dev_num; + struct device *device_p; + + device_p = get_swpdev_by_name(SWP_DEV_MODCTL); + if (device_p){ + dev_num = MKDEV(ctl_major, 1); + device_unregister(device_p); + device_destroy(swp_class_p, dev_num); + } + cancel_delayed_work_sync(&swp_polling); + if (platform_p) { + kfree(platform_p); + } + SWPS_DEBUG("%s: done.\n", __func__); +} + + +static int +get_platform_type(void){ + + int i, tmp; + int auto_chan = -1; + int auto_addr = -1; + int pf_total = ARRAY_SIZE(platform_map); + char log_msg[64] = "ERROR"; + + platform_p = kzalloc(sizeof(struct inv_platform_s), GFP_KERNEL); + if (!platform_p){ + snprintf(log_msg, sizeof(log_msg), "kzalloc fail"); + goto err_get_platform_type_1; + } + memset(platform_p->name, 0, sizeof(platform_p->name)); + + switch (PLATFORM_SETTINGS) { + case PLATFORM_TYPE_AUTO: + snprintf(platform_p->name, (sizeof(platform_p->name) - 1), + "%s", dmi_get_system_info(DMI_BOARD_NAME)); + for (i=0; iname, platform_map[i].name) == 0) { + platform_p->id = platform_map[i].id; + snprintf(log_msg, sizeof(log_msg), + "Auto detect platform: %d (%s)", + platform_p->id, platform_p->name); + goto ok_get_platform_type_1; + } + } + snprintf(log_msg, sizeof(log_msg), + "Auto detect fail! detect platform: %s", + platform_p->name); + goto err_get_platform_type_2; + + case PLATFORM_TYPE_PEONY_AUTO: +#ifdef SWPS_PEONY_SFP + auto_chan = peony_sfp_ioexp_layout[0].addr[0].chan_id; + auto_addr = peony_sfp_ioexp_layout[0].addr[0].chip_addr; +#endif + tmp = _is_i2c_target_exist(auto_chan, auto_addr); + switch (tmp) { + case 0: /* Copper SKU */ + SWPS_INFO("Auto-detected :Peony :Copper\n"); + platform_p->id = PLATFORM_TYPE_PEONY_COPPER_GA; + goto map_platform_name; + + case 1: /* SFP SKU */ + SWPS_INFO("Auto-detected :Peony :SFP\n"); + platform_p->id = PLATFORM_TYPE_PEONY_SFP_GA; + goto map_platform_name; + + default: + break; + } + snprintf(log_msg, sizeof(log_msg), + "Auto detect Peony SKU fail! :%d", tmp); + goto err_get_platform_type_2; + + case PLATFORM_TYPE_MAGNOLIA: + case PLATFORM_TYPE_MAGNOLIA_FNC: + case PLATFORM_TYPE_REDWOOD: + case PLATFORM_TYPE_REDWOOD_FSL: + case PLATFORM_TYPE_HUDSON32I_GA: + case PLATFORM_TYPE_SPRUCE: + case PLATFORM_TYPE_CYPRESS_GA1: + case PLATFORM_TYPE_CYPRESS_GA2: + case PLATFORM_TYPE_CYPRESS_BAI: + case PLATFORM_TYPE_TAHOE: + case PLATFORM_TYPE_SEQUOIA_GA: + case PLATFORM_TYPE_LAVENDER_GA: + case PLATFORM_TYPE_LAVENDER_ONL: + case PLATFORM_TYPE_COTTONWOOD_RANGELEY: + case PLATFORM_TYPE_MAPLE_GA: + case PLATFORM_TYPE_MAPLE_B: + case PLATFORM_TYPE_GULMOHAR_GA: + case PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA: + case PLATFORM_TYPE_PEONY_SFP_GA: + case PLATFORM_TYPE_PEONY_COPPER_GA: + platform_p->id = PLATFORM_SETTINGS; + goto map_platform_name; + + default: + break; + } + snprintf(log_msg, sizeof(log_msg), + "PLATFORM_SETTINGS:%d undefined", PLATFORM_SETTINGS); + goto err_get_platform_type_2; + +map_platform_name: + for (i=0; iid == platform_map[i].id) { + snprintf(platform_p->name, (sizeof(platform_p->name) - 1), + "%s", platform_map[i].name); + snprintf(log_msg, sizeof(log_msg), + "User setup platform: %d (%s)", + platform_p->id, platform_p->name); + goto ok_get_platform_type_1; + } + } + snprintf(log_msg, sizeof(log_msg), + "Internal error, can not map id:%d", + platform_p->id ); + goto err_get_platform_type_2; + +ok_get_platform_type_1: + SWPS_DEBUG("%s: %s, :%d\n", __func__, log_msg, PLATFORM_SETTINGS); + return 0; + +err_get_platform_type_2: + kfree(platform_p); +err_get_platform_type_1: + SWPS_ERR("%s: %s :%d\n", __func__, log_msg, PLATFORM_SETTINGS); + return -1; +} + + +static int +get_layout_info(void){ + + switch (platform_p->id) { +#ifdef SWPS_MAGNOLIA + case PLATFORM_TYPE_MAGNOLIA: + case PLATFORM_TYPE_MAGNOLIA_FNC: + gpio_rest_mux = magnolia_gpio_rest_mux; + ioexp_layout = magnolia_ioexp_layout; + port_layout = magnolia_port_layout; + ioexp_total = ARRAY_SIZE(magnolia_ioexp_layout); + port_total = ARRAY_SIZE(magnolia_port_layout); + break; +#endif +#ifdef SWPS_REDWOOD + case PLATFORM_TYPE_REDWOOD: + gpio_rest_mux = redwood_gpio_rest_mux; + ioexp_layout = redwood_ioexp_layout; + port_layout = redwood_port_layout; + ioexp_total = ARRAY_SIZE(redwood_ioexp_layout); + port_total = ARRAY_SIZE(redwood_port_layout); + break; +#endif +#ifdef SWPS_HUDSON32I_GA + case PLATFORM_TYPE_HUDSON32I_GA: + gpio_rest_mux = hudsin32iga_gpio_rest_mux; + ioexp_layout = hudson32iga_ioexp_layout; + port_layout = hudson32iga_port_layout; + ioexp_total = ARRAY_SIZE(hudson32iga_ioexp_layout); + port_total = ARRAY_SIZE(hudson32iga_port_layout); + break; +#endif +#ifdef SWPS_SPRUCE + case PLATFORM_TYPE_SPRUCE: + gpio_rest_mux = spruce_gpio_rest_mux; + ioexp_layout = spruce_ioexp_layout; + port_layout = spruce_port_layout; + ioexp_total = ARRAY_SIZE(spruce_ioexp_layout); + port_total = ARRAY_SIZE(spruce_port_layout); + break; +#endif +#ifdef SWPS_CYPRESS_GA1 + case PLATFORM_TYPE_CYPRESS_GA1: + gpio_rest_mux = cypress_ga1_gpio_rest_mux; + ioexp_layout = cypress_ga1_ioexp_layout; + port_layout = cypress_ga1_port_layout; + ioexp_total = ARRAY_SIZE(cypress_ga1_ioexp_layout); + port_total = ARRAY_SIZE(cypress_ga1_port_layout); + break; +#endif +#ifdef SWPS_CYPRESS_GA2 + case PLATFORM_TYPE_CYPRESS_GA2: + gpio_rest_mux = cypress_ga2_gpio_rest_mux; + ioexp_layout = cypress_ga2_ioexp_layout; + port_layout = cypress_ga2_port_layout; + ioexp_total = ARRAY_SIZE(cypress_ga2_ioexp_layout); + port_total = ARRAY_SIZE(cypress_ga2_port_layout); + break; +#endif +#ifdef SWPS_CYPRESS_BAI + case PLATFORM_TYPE_CYPRESS_BAI: + gpio_rest_mux = cypress_b_gpio_rest_mux; + ioexp_layout = cypress_b_ioexp_layout; + port_layout = cypress_b_port_layout; + ioexp_total = ARRAY_SIZE(cypress_b_ioexp_layout); + port_total = ARRAY_SIZE(cypress_b_port_layout); + break; +#endif +#ifdef SWPS_REDWOOD_FSL + case PLATFORM_TYPE_REDWOOD_FSL: + gpio_rest_mux = redwood_fsl_gpio_rest_mux; + ioexp_layout = redwood_fsl_ioexp_layout; + port_layout = redwood_fsl_port_layout; + ioexp_total = ARRAY_SIZE(redwood_fsl_ioexp_layout); + port_total = ARRAY_SIZE(redwood_fsl_port_layout); + break; +#endif +#ifdef SWPS_TAHOE + case PLATFORM_TYPE_TAHOE: + gpio_rest_mux = tahoe_gpio_rest_mux; + ioexp_layout = tahoe_ioexp_layout; + port_layout = tahoe_port_layout; + ioexp_total = ARRAY_SIZE(tahoe_ioexp_layout); + port_total = ARRAY_SIZE(tahoe_port_layout); + break; +#endif +#ifdef SWPS_SEQUOIA + case PLATFORM_TYPE_SEQUOIA_GA: + gpio_rest_mux = sequoia_gpio_rest_mux; + ioexp_layout = sequoia_ioexp_layout; + port_layout = sequoia_port_layout; + ioexp_total = ARRAY_SIZE(sequoia_ioexp_layout); + port_total = ARRAY_SIZE(sequoia_port_layout); + break; +#endif +#ifdef SWPS_LAVENDER + case PLATFORM_TYPE_LAVENDER_GA: + case PLATFORM_TYPE_LAVENDER_ONL: + gpio_rest_mux = lavender_gpio_rest_mux; + ioexp_layout = lavender_ioexp_layout; + port_layout = lavender_port_layout; + ioexp_total = ARRAY_SIZE(lavender_ioexp_layout); + port_total = ARRAY_SIZE(lavender_port_layout); + break; +#endif +#ifdef SWPS_COTTONWOOD_RANGELEY + case PLATFORM_TYPE_COTTONWOOD_RANGELEY: + gpio_rest_mux = cottonwood_rangeley_gpio_rest_mux; + ioexp_layout = cottonwood_rangeley_ioexp_layout; + port_layout = cottonwood_rangeley_port_layout; + ioexp_total = ARRAY_SIZE(cottonwood_rangeley_ioexp_layout); + port_total = ARRAY_SIZE(cottonwood_rangeley_port_layout); + break; +#endif +#ifdef SWPS_MAPLE_GA + case PLATFORM_TYPE_MAPLE_GA: + gpio_rest_mux = maple_ga_gpio_rest_mux; + ioexp_layout = maple_ga_ioexp_layout; + port_layout = maple_ga_port_layout; + ioexp_total = ARRAY_SIZE(maple_ga_ioexp_layout); + port_total = ARRAY_SIZE(maple_ga_port_layout); + break; +#endif +#ifdef SWPS_MAPLE_B + case PLATFORM_TYPE_MAPLE_B: + gpio_rest_mux = maple_b_gpio_rest_mux; + ioexp_layout = maple_b_ioexp_layout; + port_layout = maple_b_port_layout; + ioexp_total = ARRAY_SIZE(maple_b_ioexp_layout); + port_total = ARRAY_SIZE(maple_b_port_layout); + break; +#endif +#ifdef SWPS_GULMOHAR + case PLATFORM_TYPE_GULMOHAR_GA: + gpio_rest_mux = gulmohar_gpio_rest_mux; + ioexp_layout = gulmohar_ioexp_layout; + port_layout = gulmohar_port_layout; + ioexp_total = ARRAY_SIZE(gulmohar_ioexp_layout); + port_total = ARRAY_SIZE(gulmohar_port_layout); + break; +#endif +#ifdef SWPS_GULMOHAR_2T_EVT1 + case PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA: + gpio_rest_mux = gulmohar_2t_evt1_gpio_rest_mux; + ioexp_layout = gulmohar_2t_evt1_ioexp_layout; + port_layout = gulmohar_2t_evt1_port_layout; + ioexp_total = ARRAY_SIZE(gulmohar_2t_evt1_ioexp_layout); + port_total = ARRAY_SIZE(gulmohar_2t_evt1_port_layout); + break; +#endif +#ifdef SWPS_PEONY_SFP + case PLATFORM_TYPE_PEONY_SFP_GA: + gpio_rest_mux = peony_sfp_gpio_rest_mux; + ioexp_layout = peony_sfp_ioexp_layout; + port_layout = peony_sfp_port_layout; + ioexp_total = ARRAY_SIZE(peony_sfp_ioexp_layout); + port_total = ARRAY_SIZE(peony_sfp_port_layout); + break; +#endif +#ifdef SWPS_PEONY_COPPER + case PLATFORM_TYPE_PEONY_COPPER_GA: + gpio_rest_mux = peony_copper_gpio_rest_mux; + ioexp_layout = peony_copper_ioexp_layout; + port_layout = peony_copper_port_layout; + ioexp_total = ARRAY_SIZE(peony_copper_ioexp_layout); + port_total = ARRAY_SIZE(peony_copper_port_layout); + break; +#endif + + default: + SWPS_ERR(" Invalid platform: %d (%s)\n", + platform_p->id, platform_p->name); + return -1; + } + SWPS_INFO("Start to initial platform: %d (%s)\n", + platform_p->id, platform_p->name); + return 0; +} + + +/* ========== Functions for objects operations ========== + */ +static int +__detect_issues_port(int minor_num) { + + struct transvr_obj_s *tobj_p; + int port_id = port_layout[minor_num].port_id; + char port_name[32] = "ERR"; + char *i2c_emsg = "detected bad transceiver/cable"; + + memset(port_name, 0, sizeof(port_name)); + snprintf(port_name, sizeof(port_name), "%s%d", SWP_DEV_PORT, port_id); + tobj_p = _get_transvr_obj(port_name); + if (!tobj_p) { + SWPS_INFO("%s: tobj_p is NULL :%d\n", __func__, minor_num); + return -1; + } + if (resync_channel_tier_2(tobj_p) < 0) { + if (check_channel_tier_1() < 0) { + goto get_target_issues_port; + } + } + /* Re-check again for i2c-gpio special case */ + if (check_channel_tier_1() < 0) { + goto get_target_issues_port; + } + return 0; + +get_target_issues_port: + alarm_msg_2_user(tobj_p, i2c_emsg); + return -2; +} + + +static int +_detect_issues_port(void) { + /* OK : retrun -1; + * Fail: return fail at which minor number (0~N) + */ + char *emsg = "ERR"; + int minor = 0; + int minor_2st = 1; + + /* Force moving the initial channel pointer + * Filter out case of fail at minor-0 port + */ + while (minor_2st < port_total) { + minor = minor_2st; + if (__detect_issues_port(minor_2st) < 0) { + emsg = "detect minor_2st fail"; + goto err_p_detect_issues_port; + } + minor_2st += 8; + } + /* Scan all port */ + for (minor=0; minor:%d\n", __func__, emsg, minor_err); + return -1; +} + + +static int +check_transvr_obj_one(char *dev_name){ + /* [Return] + * 0 : Doesn't need to take care + * -1 : Single error + * -2 : Critical error (I2C topology die) + * -9 : Internal error + */ + struct transvr_obj_s *tobj_p = NULL; + int retval = -9; + + tobj_p = _get_transvr_obj(dev_name); + if (!tobj_p) { + SWPS_ERR("%s: %s _get_transvr_obj fail\n", + __func__, dev_name); + return -9; + } + /* Check transceiver current status */ + lock_transvr_obj(tobj_p); + retval = tobj_p->check(tobj_p); + unlock_transvr_obj(tobj_p); + switch (retval) { + case 0: + case ERR_TRANSVR_UNPLUGGED: + case ERR_TRNASVR_BE_ISOLATED: + case ERR_TRANSVR_TASK_BUSY: + return 0; + + case ERR_TRANSVR_I2C_CRASH: + default: + break; + } + /* Identify abnormal case */ + if (check_channel_tier_1() < 0) { + SWPS_DEBUG("%s: %s critical error :%d\n", + __func__, dev_name, retval); + return -2; + } + SWPS_DEBUG("%s: %s single error :%d\n", + __func__, dev_name, retval); + return -1; +} + + +static int +check_transvr_objs(void){ + + char dev_name[32]; + int port_id, err_code; + int minor_curr = 0; + + for (minor_curr=0; minor_curr:%d\n", + __func__, dev_name, err_code); + break; + } + } + return 0; + +err_check_transvr_objs: + SWPS_ERR("%s: %s reset_i2c_topology fail.\n", + __func__, dev_name); + return -1; +} + + +static void +swp_polling_worker(struct work_struct *work){ + + /* Reset I2C */ + if (flag_i2c_reset) { + goto polling_reset_i2c; + } + /* Check IOEXP */ + if (check_ioexp_objs() < 0) { + goto polling_reset_i2c; + } + /* Check transceiver */ + if (check_transvr_objs() < 0) { + SWPS_DEBUG("%s: check_transvr_objs fail.\n", __func__); + flag_i2c_reset = 1; + } + goto polling_schedule_round; + +polling_reset_i2c: + SWPS_DEBUG("%s: reset_i2c_topology start.\n", __func__); + if (reset_i2c_topology() < 0) { + SWPS_ERR("%s: reset i2c fail!\n", __func__); + flag_i2c_reset = 1; + } else { + SWPS_DEBUG("%s: reset_i2c_topology OK.\n", __func__); + flag_i2c_reset = 0; + } +polling_schedule_round: + schedule_delayed_work(&swp_polling, _get_polling_period()); +} + + +/* ========== Functions for register something ========== + */ +static int +register_transvr_common_attr(struct device *device_p){ + + char *err_attr = NULL; + + if (device_create_file(device_p, &dev_attr_id) < 0) { + err_attr = "dev_attr_id"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_ext_id) < 0) { + err_attr = "dev_attr_ext_id"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_connector) < 0) { + err_attr = "dev_attr_connector"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_vendor_name) < 0) { + err_attr = "dev_attr_vendor_name"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_vendor_pn) < 0) { + err_attr = "dev_attr_vendor_pn"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_vendor_rev) < 0) { + err_attr = "dev_attr_vendor_rev"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_vendor_sn) < 0) { + err_attr = "dev_attr_vendor_sn"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_br) < 0) { + err_attr = "dev_attr_br"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_len_smf) < 0) { + err_attr = "dev_attr_len_smf"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_len_om1) < 0) { + err_attr = "dev_attr_len_om1"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_len_om2) < 0) { + err_attr = "dev_attr_len_om2"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_len_om3) < 0) { + err_attr = "dev_attr_len_om3"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_len_om4) < 0) { + err_attr = "dev_attr_len_om4"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_comp_extend) < 0) { + err_attr = "dev_attr_comp_extend"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_comp_eth) < 0) { + err_attr = "dev_attr_comp_eth"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_comp_rev) < 0) { + err_attr = "dev_attr_comp_rev"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_info) < 0) { + err_attr = "dev_attr_info"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_if_type) < 0) { + err_attr = "dev_attr_if_type"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_if_speed) < 0) { + err_attr = "dev_attr_if_speed"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_if_lane) < 0) { + err_attr = "dev_attr_if_lane"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_temperature) < 0) { + err_attr = "dev_attr_temperature"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_voltage) < 0) { + err_attr = "dev_attr_voltage"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_tx_bias) < 0) { + err_attr = "dev_attr_tx_bias"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_tx_power) < 0) { + err_attr = "dev_attr_tx_power"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_rx_power) < 0) { + err_attr = "dev_attr_rx_power"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_tx_eq) < 0) { + err_attr = "dev_attr_tx_eq"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_rx_em) < 0) { + err_attr = "dev_attr_rx_em"; + goto err_transvr_comm_attr; + } + if (device_create_file(device_p, &dev_attr_wavelength) < 0) { + err_attr = "dev_attr_wavelength"; + goto err_transvr_comm_attr; + } + return 0; + +err_transvr_comm_attr: + SWPS_ERR("%s: %s\n", __func__, err_attr); + return -1; +} + +static int +register_transvr_sfp_attr(struct device *device_p){ + + char *err_attr = NULL; + + if (register_transvr_common_attr(device_p) < 0) { + err_attr = "register_transvr_common_attr"; + goto err_transvr_sfp_attr; + } + if (device_create_file(device_p, &dev_attr_comp_eth_10) < 0) { + err_attr = "dev_attr_comp_eth_10"; + goto err_transvr_sfp_attr; + } + if (device_create_file(device_p, &dev_attr_len_sm) < 0) { + err_attr = "dev_attr_len_sm"; + goto err_transvr_sfp_attr; + } + if (device_create_file(device_p, &dev_attr_rate_id) < 0) { + err_attr = "dev_attr_rate_id"; + goto err_transvr_sfp_attr; + } + if (device_create_file(device_p, &dev_attr_soft_rs0) < 0) { + err_attr = "dev_attr_soft_rs0"; + goto err_transvr_sfp_attr; + } + if (device_create_file(device_p, &dev_attr_soft_rs1) < 0) { + err_attr = "dev_attr_soft_rs1"; + goto err_transvr_sfp_attr; + } + if (device_create_file(device_p, &dev_attr_extphy_offset) < 0) { + err_attr = "dev_attr_extphy_offset"; + goto err_transvr_sfp_attr; + } + if (device_create_file(device_p, &dev_attr_extphy_reg) < 0) { + err_attr = "dev_attr_extphy_reg"; + goto err_transvr_sfp_attr; + } + return 0; + +err_transvr_sfp_attr: + SWPS_ERR("%s: %s\n", __func__, err_attr); + return -1; +} + + +static int +register_transvr_qsfp_attr(struct device *device_p){ + + char *err_attr = NULL; + + if (register_transvr_common_attr(device_p) < 0) { + err_attr = "register_transvr_common_attr"; + goto err_transvr_qsfp_attr; + } + if (device_create_file(device_p, &dev_attr_comp_eth_10_40) < 0) { + err_attr = "dev_attr_comp_eth_10_40"; + goto err_transvr_qsfp_attr; + } + if (device_create_file(device_p, &dev_attr_power_cls) < 0) { + err_attr = "dev_attr_power_cls"; + goto err_transvr_qsfp_attr; + } + if (device_create_file(device_p, &dev_attr_soft_rx_los) < 0) { + err_attr = "soft_rx_los"; + goto err_transvr_qsfp_attr; + } + if (device_create_file(device_p, &dev_attr_soft_tx_disable) < 0) { + err_attr = "soft_tx_disable"; + goto err_transvr_qsfp_attr; + } + if (device_create_file(device_p, &dev_attr_auto_tx_disable) < 0) { + err_attr = "auto_tx_disable"; + goto err_transvr_qsfp_attr; + } + if (device_create_file(device_p, &dev_attr_soft_tx_fault) < 0) { + err_attr = "soft_tx_fault"; + goto err_transvr_qsfp_attr; + } + return 0; + +err_transvr_qsfp_attr: + SWPS_ERR("%s: %s\n", __func__, err_attr); + return -1; +} + + +static int +register_transvr_qsfp28_attr(struct device *device_p){ + + char *err_attr = NULL; + + if (register_transvr_qsfp_attr(device_p) < 0){ + err_attr = "register_transvr_qsfp_attr"; + goto err_transvr_qsfp28_attr; + } + if (device_create_file(device_p, &dev_attr_cdr) < 0) { + err_attr = "dev_attr_cdr"; + goto err_transvr_qsfp28_attr; + } + if (device_create_file(device_p, &dev_attr_rx_am) < 0) { + err_attr = "dev_attr_rx_am"; + goto err_transvr_qsfp28_attr; + } + return 0; + +err_transvr_qsfp28_attr: + SWPS_ERR("%s: %s\n", __func__, err_attr); + return -1; +} + + +static int +register_transvr_attr(struct device *device_p, + struct transvr_obj_s *transvr_obj){ + + switch (transvr_obj->layout){ + case TRANSVR_TYPE_SFP: + if (register_transvr_sfp_attr(device_p) < 0){ + goto err_reg_tvr_attr; + } + break; + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + if (register_transvr_qsfp_attr(device_p) < 0){ + goto err_reg_tvr_attr; + } + break; + case TRANSVR_TYPE_QSFP_28: + if (register_transvr_qsfp28_attr(device_p) < 0){ + goto err_reg_tvr_attr; + } + break; + default: + goto err_reg_tvr_attr; + } + return 0; + +err_reg_tvr_attr: + SWPS_ERR("%s: fail! type=%d \n", __func__, transvr_obj->type); + return -1; +} + + +static int +register_ioexp_attr_sfp_1(struct device *device_p){ + /* Support machine type: + * - SFP : Magnolia + */ + char *err_attr = NULL; + + if (device_create_file(device_p, &dev_attr_present) < 0) { + err_attr = "dev_attr_present"; + goto err_ioexp_sfp1_attr; + } + if (device_create_file(device_p, &dev_attr_tx_fault) < 0) { + err_attr = "dev_attr_tx_fault"; + goto err_ioexp_sfp1_attr; + } + if (device_create_file(device_p, &dev_attr_rxlos) < 0) { + err_attr = "dev_attr_rxlos"; + goto err_ioexp_sfp1_attr; + } + if (device_create_file(device_p, &dev_attr_tx_disable) < 0) { + err_attr = "dev_attr_tx_disable"; + goto err_ioexp_sfp1_attr; + } + return 0; + +err_ioexp_sfp1_attr: + SWPS_ERR("Add device attribute:%s failure! \n",err_attr); + return -1; +} + + +static int +register_ioexp_attr_sfp_2(struct device *device_p){ + /* Support machine type: + * - SFP28 : Cypress + */ + char *err_attr = NULL; + + if (register_ioexp_attr_sfp_1(device_p) < 0){ + goto err_ioexp_sfp2_attr; + } + if (device_create_file(device_p, &dev_attr_hard_rs0) < 0) { + err_attr = "dev_attr_hard_rs0"; + goto err_ioexp_sfp2_attr; + } + if (device_create_file(device_p, &dev_attr_hard_rs1) < 0) { + err_attr = "dev_attr_hard_rs1"; + goto err_ioexp_sfp2_attr; + } + return 0; + +err_ioexp_sfp2_attr: + SWPS_ERR("Add device attribute:%s failure! \n",err_attr); + return -1; +} + + +static int +register_ioexp_attr_qsfp_1(struct device *device_p){ + /* Support machine type: + * - QSFP : Magnolia, Redwood, Hudson32i + * - QSFP+ : Magnolia, Redwood, Hudson32i + * - QSFP28: Redwood + */ + char *err_attr = NULL; + + if (device_create_file(device_p, &dev_attr_present) < 0) { + err_attr = "dev_attr_present"; + goto err_ioexp_qsfp1_attr; + } + if (device_create_file(device_p, &dev_attr_reset) < 0) { + err_attr = "dev_attr_reset"; + goto err_ioexp_qsfp1_attr; + } + if (device_create_file(device_p, &dev_attr_lpmod) < 0) { + err_attr = "dev_attr_lpmod"; + goto err_ioexp_qsfp1_attr; + } + if (device_create_file(device_p, &dev_attr_modsel) < 0) { + err_attr = "dev_attr_modsel"; + goto err_ioexp_qsfp1_attr; + } + return 0; + +err_ioexp_qsfp1_attr: + SWPS_ERR("Add device attribute:%s failure! \n",err_attr); + return -1; +} + + +static int +register_modctl_attr(struct device *device_p){ + + char *err_msg = NULL; + + if (device_create_file(device_p, &dev_attr_platform) < 0) { + err_msg = "dev_attr_platform"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_version) < 0) { + err_msg = "dev_attr_version"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_status) < 0) { + err_msg = "dev_attr_status"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_reset_i2c) < 0) { + err_msg = "dev_attr_reset_i2c"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_reset_swps) < 0) { + err_msg = "dev_attr_reset_swps"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_auto_config) < 0) { + err_msg = "dev_attr_auto_config"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_block_poll) < 0) { + err_msg = "dev_attr_block_poll"; + goto err_reg_modctl_attr; + } + if (device_create_file(device_p, &dev_attr_io_no_init) < 0) { + err_msg = "dev_attr_io_no_init"; + goto err_reg_modctl_attr; + } + + return 0; + +err_reg_modctl_attr: + SWPS_ERR("%s: %s\n", __func__, err_msg); + return -1; +} + + +static int +register_ioexp_attr(struct device *device_p, + struct transvr_obj_s *transvr_obj){ + + char *err_msg = "ERR"; + + switch (transvr_obj->ioexp_obj_p->ioexp_type){ + case IOEXP_TYPE_MAGINOLIA_NAB: + case IOEXP_TYPE_MAGINOLIA_4AB: + case CPLD_TYPE_COTTONWOOD: + if (register_ioexp_attr_sfp_1(device_p) < 0){ + err_msg = "register_ioexp_attr_sfp_1 fail"; + goto err_reg_ioexp_attr; + } + break; + + case IOEXP_TYPE_MAPLE_NABC: + case IOEXP_TYPE_GULMOHAR_NABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC: + case IOEXP_TYPE_SFP_8P_LAYOUT_1: + if (register_ioexp_attr_sfp_2(device_p) < 0){ + err_msg = "register_ioexp_attr_sfp_2 fail"; + goto err_reg_ioexp_attr; + } + break; + + case IOEXP_TYPE_MAGINOLIA_7AB: + case IOEXP_TYPE_SPRUCE_7AB: + case IOEXP_TYPE_CYPRESS_7ABC: + case IOEXP_TYPE_REDWOOD_P01P08: + case IOEXP_TYPE_REDWOOD_P09P16: + case IOEXP_TYPE_HUDSON32IGA_P01P08: + case IOEXP_TYPE_HUDSON32IGA_P09P16: + case IOEXP_TYPE_TAHOE_5A: + case IOEXP_TYPE_TAHOE_6ABC: + case IOEXP_TYPE_SEQUOIA_NABC: + case IOEXP_TYPE_LAVENDER_P65: + case IOEXP_TYPE_MAPLE_0ABC: + case IOEXP_TYPE_GULMOHAR_7ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC: + case IOEXP_TYPE_QSFP_6P_LAYOUT_1: + if (register_ioexp_attr_qsfp_1(device_p) < 0){ + err_msg = "register_ioexp_attr_qsfp_1 fail"; + goto err_reg_ioexp_attr; + } + break; + + default: + err_msg = "Unknow type"; + goto err_reg_ioexp_attr; + } + return 0; + +err_reg_ioexp_attr: + SWPS_ERR("%s: %s :%d \n", + __func__, err_msg, transvr_obj->ioexp_obj_p->ioexp_type); + return -1; +} + + +static int +register_modctl_device(void) { + + struct device *device_p = NULL; + int minor_comm = 0; /* Default minor number for common device */ + dev_t dev_num = MKDEV(ctl_major, minor_comm); + char *err_msg = "ERROR"; + + device_p = device_create(swp_class_p, /* struct class *cls */ + NULL, /* struct device *parent */ + dev_num, /* dev_t devt */ + NULL, /* void *private_data */ + SWP_DEV_MODCTL); /* const char *fmt */ + if (IS_ERR(device_p)){ + err_msg = "device_create fail"; + goto err_register_modctl_device_1; + } + if (register_modctl_attr(device_p) < 0) { + err_msg = "register_modctl_attr fail"; + goto err_register_modctl_device_2; + } + return 0; + +err_register_modctl_device_2: + device_unregister(device_p); + device_destroy(swp_class_p, dev_num); +err_register_modctl_device_1: + SWPS_ERR("%s: %s\n", __func__, err_msg); + return -1; +} + + +static int +register_port_device(char *dev_name, + dev_t dev_num, + struct transvr_obj_s *transvr_obj){ + + struct device *device_p = NULL; + device_p = device_create(swp_class_p, /* struct class *cls */ + NULL, /* struct device *parent */ + dev_num, /* dev_t devt */ + transvr_obj, /* void *private_data */ + dev_name); /* const char *fmt */ + if (IS_ERR(device_p)){ + goto err_regswp_create_dev; + } + if (register_transvr_attr(device_p, transvr_obj) < 0){ + goto err_regswp_reg_attr; + } + if (register_ioexp_attr(device_p, transvr_obj) < 0){ + goto err_regswp_reg_attr; + } + return 0; + +err_regswp_reg_attr: + device_unregister(device_p); + device_destroy(swp_class_p, dev_num); +err_regswp_create_dev: + SWPS_ERR("%s fail! :%s\n", __func__, dev_name); + return -1; +} + + +static int +register_swp_module(void){ + + dev_t ctl_devt = 0; + dev_t port_devt = 0; + int dev_total = port_total + 1; /* char_dev for module control */ + + /* Register device number */ + if (alloc_chrdev_region(&ctl_devt, 0, 1, SWP_DEV_MODCTL) < 0){ + SWPS_WARN("Allocate CTL MAJOR failure! \n"); + goto err_register_swp_module_1; + } + if (alloc_chrdev_region(&port_devt, 0, port_total, SWP_CLS_NAME) < 0){ + SWPS_WARN("Allocate PORT MAJOR failure! \n"); + goto err_register_swp_module_2; + } + ctl_major = MAJOR(ctl_devt); + port_major = MAJOR(port_devt); + + /* Create class object */ + swp_class_p = class_create(THIS_MODULE, SWP_CLS_NAME); + if (IS_ERR(swp_class_p)) { + SWPS_ERR("Create class failure! \n"); + goto err_register_swp_module_3; + } + return 0; + +err_register_swp_module_3: + unregister_chrdev_region(MKDEV(port_major, 0), port_total); +err_register_swp_module_2: + unregister_chrdev_region(MKDEV(ctl_major, 0), 1); +err_register_swp_module_1: + return -1; +} + + +/* ========== Module initial relate ========== + */ +static int +create_ioexp_objs(void) { + + int i, run_mod; + + /* Clean IOEXP object */ + clean_ioexp_objs(); + /* Get running mode */ + run_mod = IOEXP_MODE_DIRECT; + if (SWP_POLLING_ENABLE){ + run_mod = IOEXP_MODE_POLLING; + } + /* Create IOEXP object */ + for(i=0; i devlen_max) { + snprintf(err_msg, sizeof(err_msg), + "SWP_DEV_PORT too long!"); + goto err_initport_create_tranobj; + } + memset(dev_name, 0, sizeof(dev_name)); + snprintf(dev_name, devlen_max, "%s%d", SWP_DEV_PORT, port_id); + /* Create transceiver object */ + ioexp_obj_p = get_ioexp_obj(ioexp_id); + if (!ioexp_obj_p){ + snprintf(err_msg, sizeof(err_msg), + "IOEXP object:%d not exist", ioexp_id); + goto err_initport_create_tranobj; + } + transvr_obj_p = create_transvr_obj(dev_name, chan_id, ioexp_obj_p, + ioexp_virt_offset, transvr_type, + chipset_type, run_mod); + if (!transvr_obj_p){ + snprintf(err_msg, sizeof(err_msg), + "Create transceiver object fail :%s", dev_name); + goto err_initport_create_tranobj; + } + /* Setup Lane_ID mapping */ + i = ARRAY_SIZE(port_layout[minor_curr].lane_id); + j = ARRAY_SIZE(transvr_obj_p->lane_id); + if (i != j) { + snprintf(err_msg, sizeof(err_msg), + "Lane_id size inconsistent %d/%d", i, j); + goto err_initport_reg_device; + } + memcpy(transvr_obj_p->lane_id, port_layout[minor_curr].lane_id, i*sizeof(int)); + /* Create and register device object */ + if (register_port_device(dev_name, MKDEV(port_major, minor_curr), transvr_obj_p) < 0){ + snprintf(err_msg, sizeof(err_msg), + "register_port_device fail"); + goto err_initport_reg_device; + } + /* Setup device_ptr of transvr_obj */ + dev_p = get_swpdev_by_name(dev_name); + if (!dev_p){ + snprintf(err_msg, sizeof(err_msg), + "get_swpdev_by_name fail"); + goto err_initport_reg_device; + } + transvr_obj_p->transvr_dev_p = dev_p; + /* Success */ + ok_count++; + } + SWPS_INFO("%s: initialed %d port-dev\n",__func__, ok_count); + return 0; + +err_initport_reg_device: + kfree(transvr_obj_p); +err_initport_create_tranobj: + clean_port_objs(); + SWPS_ERR("%s: %s", __func__, err_msg); + SWPS_ERR("Dump: :%d :%d :%d :%d :%d :%d\n", + port_id, chan_id, ioexp_id, ioexp_virt_offset, transvr_type, run_mod); + return -1; +} + + +static int +init_dev_topology(void){ + + int err; + char *emsg = "ERR"; + flag_mod_state = SWP_STATE_NORMAL; + + err = init_ioexp_objs(); + switch(err){ + case 0: /* Normal */ + SWPS_DEBUG("%s: normal case\n", __func__); + break; + + case -1: /* topology error */ + SWPS_DEBUG("%s: detect tier-1 topology initial failure :%d\n", + __func__, err); + /* Reset and isolate */ + err = reset_i2c_topology(); + if (err < 0) { + emsg = "reset i2c topology fail"; + goto err_init_dev_topology; + } + /* Re-initial again */ + err = init_ioexp_objs(); + if (err < 0) { + emsg = "re-init ioexp objects fail"; + goto err_init_dev_topology; + } + break; + + case -2: /* Internal error */ + SWPS_DEBUG("%s: internal error case\n", __func__); + err = -2; + emsg = "internal error"; + goto err_init_dev_topology; + + default: + SWPS_DEBUG("%s: undefined error case\n", __func__); + emsg = "undefined error case"; + goto err_init_dev_topology; + } + SWPS_DEBUG("%s: initial I2C topology success\n", __func__); + return 0; + +err_init_dev_topology: + SWPS_ERR("%s: %s :%d\n", __func__, emsg, err); + return -1; +} + + +static int +init_polling_task(void){ + + if (SWP_POLLING_ENABLE){ + schedule_delayed_work(&swp_polling, _get_polling_period()); + } + return 0; +} + + +static int +init_swps_common(void){ + + char *err_msg = "ERR"; + + block_polling = 0; + auto_config = 0; + if ((SWP_AUTOCONFIG_ENABLE) && (SWP_POLLING_ENABLE)){ + auto_config = 1; + } + if (register_modctl_device() < 0) { + err_msg = "register_modctl_device fail"; + goto err_init_swps_common_1; + } + if (_update_auto_config_2_trnasvr() < 0) { + err_msg = "_update_auto_config_2_trnasvr fail"; + goto err_init_swps_common_1; + } + if (init_polling_task() < 0){ + err_msg = "init_polling_task fail"; + goto err_init_swps_common_1; + } + return 0; + +err_init_swps_common_1: + clean_swps_common(); + SWPS_ERR("%s: %s\n", __func__, err_msg); + return -1; +} + + +static int __init +swp_module_init(void){ + + if (get_platform_type() < 0){ + goto err_init_out; + } + if (get_layout_info() < 0){ + goto err_init_out; + } + if (register_swp_module() < 0){ + goto err_init_out; + } + if (create_ioexp_objs() < 0){ + goto err_init_ioexp; + } + if (create_port_objs() < 0){ + goto err_init_portobj; + } + if (init_mux_objs(gpio_rest_mux) < 0){ + goto err_init_mux; + } + if (init_dev_topology() < 0){ + goto err_init_topology; + } + if (init_swps_common() < 0){ + goto err_init_topology; + } + SWPS_INFO("Inventec switch-port module V.%s initial success.\n", SWP_VERSION); + return 0; + + +err_init_topology: + clean_mux_objs(); +err_init_mux: + clean_port_objs(); +err_init_portobj: + clean_ioexp_objs(); +err_init_ioexp: + class_destroy(swp_class_p); + unregister_chrdev_region(MKDEV(ctl_major, 0), 1); + unregister_chrdev_region(MKDEV(port_major, 0), port_total); +err_init_out: + SWPS_ERR("Inventec switch-port module V.%s initial failure.\n", SWP_VERSION); + return -1; +} + + +static void __exit +swp_module_exit(void){ + + clean_swps_common(); + clean_port_objs(); + clean_ioexp_objs(); + clean_mux_objs(); + class_destroy(swp_class_p); + unregister_chrdev_region(MKDEV(ctl_major, 0), 1); + unregister_chrdev_region(MKDEV(port_major, 0), port_total); + SWPS_INFO("Remove Inventec switch-port module success.\n"); +} + + +/* Module information */ +MODULE_AUTHOR(SWP_AUTHOR); +MODULE_DESCRIPTION(SWP_DESC); +MODULE_VERSION(SWP_VERSION); +MODULE_LICENSE(SWP_LICENSE); +MODULE_SOFTDEP("pre: inv_platform"); + +module_init(swp_module_init); +module_exit(swp_module_exit); + + + + + + + + + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_swps.h b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_swps.h new file mode 100644 index 000000000000..ad1f337b0c06 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/inv_swps.h @@ -0,0 +1,1621 @@ +#ifndef INV_SWPS_H +#define INV_SWPS_H + +#include "transceiver.h" +#include "io_expander.h" +#include "inv_mux.h" + +/* Module settings */ +#define SWP_CLS_NAME "swps" +#define SWP_DEV_PORT "port" +#define SWP_DEV_MODCTL "module" +#define SWP_RESET_PWD "inventec" +#define SWP_POLLING_PERIOD (300) /* msec */ +#define SWP_POLLING_ENABLE (1) +#define SWP_AUTOCONFIG_ENABLE (1) + +/* Module information */ +#define SWP_AUTHOR "Neil " +#define SWP_DESC "Inventec port and transceiver driver" +#define SWP_VERSION "C1-4.3.5" +#define SWP_LICENSE "GPL" + +/* Module status define */ +#define SWP_STATE_NORMAL (0) +#define SWP_STATE_I2C_DIE (-91) + +/* [Note]: + * Functions and mechanism for auto-detect platform type is ready, + * But HW and BIOS not ready! We need to wait them. + * So, please do not use PLATFORM_TYPE_AUTO until they are ready. + * (2016.06.13) + */ +#define PLATFORM_TYPE_AUTO (100) +#define PLATFORM_TYPE_MAGNOLIA (111) +#define PLATFORM_TYPE_MAGNOLIA_FNC (112) +#define PLATFORM_TYPE_REDWOOD (121) +#define PLATFORM_TYPE_REDWOOD_FSL (122) +#define PLATFORM_TYPE_HUDSON32I_GA (131) +#define PLATFORM_TYPE_SPRUCE (141) +#define PLATFORM_TYPE_CYPRESS_GA1 (151) /* Up -> Down */ +#define PLATFORM_TYPE_CYPRESS_GA2 (152) /* Down -> Up */ +#define PLATFORM_TYPE_CYPRESS_BAI (153) /* Down -> Up */ +#define PLATFORM_TYPE_TAHOE (161) +#define PLATFORM_TYPE_SEQUOIA_GA (171) +#define PLATFORM_TYPE_LAVENDER_GA (181) +#define PLATFORM_TYPE_LAVENDER_ONL (182) +#define PLATFORM_TYPE_COTTONWOOD_RANGELEY (191) +#define PLATFORM_TYPE_MAPLE_GA (201) +#define PLATFORM_TYPE_GULMOHAR_GA (202) +#define PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA (203) +#define PLATFORM_TYPE_PEONY_SFP_GA (204) +#define PLATFORM_TYPE_PEONY_COPPER_GA (205) +#define PLATFORM_TYPE_PEONY_AUTO (206) +#define PLATFORM_TYPE_MAPLE_B (207) +/* Current running platfrom */ +#define PLATFORM_SETTINGS PLATFORM_TYPE_MAPLE_B + +/* Define platform flag and kernel version */ +#if (PLATFORM_SETTINGS == PLATFORM_TYPE_MAGNOLIA) + #define SWPS_MAGNOLIA (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAGNOLIA_FNC) + #define SWPS_MAGNOLIA (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_REDWOOD) + #define SWPS_REDWOOD (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_REDWOOD_FSL) + #define SWPS_REDWOOD_FSL (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_HUDSON32I_GA) + #define SWPS_HUDSON32I_GA (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_SPRUCE) + #define SWPS_SPRUCE (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_CYPRESS_GA1) + #define SWPS_CYPRESS_GA1 (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_CYPRESS_GA2) + #define SWPS_CYPRESS_GA2 (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_CYPRESS_BAI) + #define SWPS_CYPRESS_BAI (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_TAHOE) + #define SWPS_TAHOE (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_SEQUOIA_GA) + #define SWPS_SEQUOIA (1) + #define SWPS_KERN_VER_BF_3_8 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_LAVENDER_GA) + #define SWPS_LAVENDER (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_LAVENDER_ONL) + #define SWPS_LAVENDER (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_COTTONWOOD_RANGELEY) + #define SWPS_COTTONWOOD_RANGELEY (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAPLE_GA) + #define SWPS_MAPLE_GA (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAPLE_B) + #define SWPS_MAPLE_B (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_GULMOHAR_GA) + #define SWPS_GULMOHAR (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA) + #define SWPS_GULMOHAR_2T_EVT1 (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_PEONY_SFP_GA) + #define SWPS_PEONY_SFP (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_PEONY_COPPER_GA) + #define SWPS_PEONY_COPPER (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_PEONY_AUTO) + #define SWPS_PEONY_SFP (1) + #define SWPS_PEONY_COPPER (1) + #define SWPS_KERN_VER_AF_3_10 (1) +#endif + +struct inv_platform_s { + int id; + char name[64]; +}; + +struct inv_ioexp_layout_s { + int ioexp_id; + int ioexp_type; + struct ioexp_addr_s addr[4]; +}; + +struct inv_port_layout_s { + int port_id; + int chan_id; + int ioexp_id; + int ioexp_offset; + int transvr_type; + int chipset_type; + int lane_id[8]; +}; + + +/* ========================================== + * Inventec Platform Settings + * ========================================== + */ +struct inv_platform_s platform_map[] = { + {PLATFORM_TYPE_AUTO, "Auto-Detect" }, + {PLATFORM_TYPE_MAGNOLIA, "Magnolia" }, + {PLATFORM_TYPE_MAGNOLIA_FNC, "Magnolia_FNC" }, + {PLATFORM_TYPE_REDWOOD, "Redwood" }, + {PLATFORM_TYPE_REDWOOD_FSL, "Redwood_FSL" }, + {PLATFORM_TYPE_HUDSON32I_GA, "Hudson32i" }, + {PLATFORM_TYPE_SPRUCE, "Spruce" }, + {PLATFORM_TYPE_CYPRESS_GA1, "Cypress_GA1" }, + {PLATFORM_TYPE_CYPRESS_GA2, "Cypress_GA2" }, + {PLATFORM_TYPE_CYPRESS_BAI, "Cypress_BAI" }, + {PLATFORM_TYPE_TAHOE, "Tahoe" }, + {PLATFORM_TYPE_SEQUOIA_GA, "Sequoia_GA" }, + {PLATFORM_TYPE_LAVENDER_GA, "Lavender_GA" }, + {PLATFORM_TYPE_LAVENDER_ONL, "Lavender_ONL" }, + {PLATFORM_TYPE_COTTONWOOD_RANGELEY, "Cottonwood_RANGELEY" }, + {PLATFORM_TYPE_MAPLE_GA, "Maple_GA" }, + {PLATFORM_TYPE_MAPLE_B, "Maple_B" }, + {PLATFORM_TYPE_GULMOHAR_GA, "Gulmohar_GA" }, + {PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA, "Gulmohar_2T_EVT1_GA" }, + {PLATFORM_TYPE_PEONY_SFP_GA, "Peony_SFP_GA" }, + {PLATFORM_TYPE_PEONY_COPPER_GA, "Peony_Copper_GA" }, + {PLATFORM_TYPE_PEONY_AUTO, "Peony_Auto_Detect" }, +}; + + +/* ========================================== + * Magnolia Layout configuration + * ========================================== + */ +#ifdef SWPS_MAGNOLIA +unsigned magnolia_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548; + +struct inv_ioexp_layout_s magnolia_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_MAGINOLIA_NAB, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */ + }, + {1, IOEXP_TYPE_MAGINOLIA_NAB, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */ + }, + {2, IOEXP_TYPE_MAGINOLIA_NAB, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */ + }, + {3, IOEXP_TYPE_MAGINOLIA_4AB, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander 4 A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf0, 0xff}, {0xf0, 0xff}, }, }, /* addr[1] = I/O Expander 4 B */ + }, + {4, IOEXP_TYPE_MAGINOLIA_NAB, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */ + }, + {5, IOEXP_TYPE_MAGINOLIA_NAB, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */ + }, + {6, IOEXP_TYPE_MAGINOLIA_7AB, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xf0, 0x33}, }, }, /* addr[1] = I/O Expander 7 B */ + }, +}; + +struct inv_port_layout_s magnolia_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + { 0, 10, 0, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 16} }, + { 1, 11, 0, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 15} }, + { 2, 12, 0, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 14} }, + { 3, 13, 0, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 13} }, + { 4, 14, 0, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 24} }, + { 5, 15, 0, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 23} }, + { 6, 16, 0, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 22} }, + { 7, 17, 0, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 21} }, + { 8, 18, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 28} }, + { 9, 19, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 27} }, + {10, 20, 1, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 26} }, + {11, 21, 1, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 25} }, + {12, 22, 1, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 32} }, + {13, 23, 1, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 31} }, + {14, 24, 1, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 30} }, + {15, 25, 1, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 29} }, + {16, 26, 2, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 48} }, + {17, 27, 2, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 47} }, + {18, 28, 2, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 46} }, + {19, 29, 2, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 45} }, + {20, 30, 2, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 52} }, + {21, 31, 2, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 51} }, + {22, 32, 2, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 50} }, + {23, 33, 2, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 49} }, + {24, 34, 3, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 56} }, + {25, 35, 3, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 55} }, + {26, 36, 3, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 54} }, + {27, 37, 3, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 53} }, + {28, 38, 3, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 60} }, + {29, 39, 3, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 59} }, + {30, 40, 3, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 58} }, + {31, 41, 3, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 57} }, + {32, 42, 4, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 64} }, + {33, 43, 4, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 63} }, + {34, 44, 4, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 62} }, + {35, 45, 4, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 61} }, + {36, 46, 4, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 68} }, + {37, 47, 4, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 67} }, + {38, 48, 4, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 66} }, + {39, 49, 4, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 65} }, + {40, 50, 5, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 72} }, + {41, 51, 5, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 71} }, + {42, 52, 5, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 70} }, + {43, 53, 5, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 69} }, + {44, 54, 5, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 76} }, + {45, 55, 5, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 75} }, + {46, 56, 5, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 74} }, + {47, 57, 5, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 73} }, + {48, 58, 6, 0, TRANSVR_TYPE_QSFP, BCM_CHIP_TYPE_TRIDENT_2, { 81, 82, 83, 84} }, + {49, 59, 6, 1, TRANSVR_TYPE_QSFP, BCM_CHIP_TYPE_TRIDENT_2, { 77, 78, 79, 80} }, + {50, 60, 6, 2, TRANSVR_TYPE_QSFP, BCM_CHIP_TYPE_TRIDENT_2, { 97, 98, 99,100} }, + {51, 61, 6, 3, TRANSVR_TYPE_QSFP, BCM_CHIP_TYPE_TRIDENT_2, {101,102,103,104} }, + {52, 62, 6, 4, TRANSVR_TYPE_QSFP, BCM_CHIP_TYPE_TRIDENT_2, {105,106,107,108} }, + {53, 63, 6, 5, TRANSVR_TYPE_QSFP, BCM_CHIP_TYPE_TRIDENT_2, {109,110,111,112} }, +}; +#endif + + +/* ========================================== + * Redwood Layout configuration + * ========================================== + */ +#ifdef SWPS_REDWOOD +unsigned redwood_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548; + +struct inv_ioexp_layout_s redwood_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_REDWOOD_P01P08, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, + {1, IOEXP_TYPE_REDWOOD_P09P16, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, + {2, IOEXP_TYPE_REDWOOD_P01P08, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, + {3, IOEXP_TYPE_REDWOOD_P09P16, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, +}; + +struct inv_port_layout_s redwood_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + { 0, 22, 0, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 1, 2, 3, 4} }, + { 1, 23, 0, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 5, 6, 7, 8} }, + { 2, 24, 0, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 9, 10, 11, 12} }, + { 3, 25, 0, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 13, 14, 15, 16} }, + { 4, 26, 0, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 17, 18, 19, 20} }, + { 5, 27, 0, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 21, 22, 23, 24} }, + { 6, 28, 0, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 25, 26, 27, 28} }, + { 7, 29, 0, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 29, 30, 31, 32} }, + { 8, 30, 1, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 33, 34, 35, 36} }, + { 9, 31, 1, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 37, 38, 39, 40} }, + {10, 32, 1, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 41, 42, 43, 44} }, + {11, 33, 1, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 45, 46, 47, 48} }, + {12, 34, 1, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 49, 50, 51, 52} }, + {13, 35, 1, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 53, 54, 55, 56} }, + {14, 36, 1, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 57, 58, 59, 60} }, + {15, 37, 1, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 61, 62, 63, 64} }, + {16, 6, 2, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 65, 66, 67, 68} }, + {17, 7, 2, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 69, 70, 71, 72} }, + {18, 8, 2, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 73, 74, 75, 76} }, + {19, 9, 2, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 77, 78, 79, 80} }, + {20, 10, 2, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 81, 82, 83, 84} }, + {21, 11, 2, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 85, 86, 87, 88} }, + {22, 12, 2, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 89, 90, 91, 92} }, + {23, 13, 2, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 93, 94, 95, 96} }, + {24, 14, 3, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 97, 98, 99,100} }, + {25, 15, 3, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {101,102,103,104} }, + {26, 16, 3, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {105,106,107,108} }, + {27, 17, 3, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {109,110,111,112} }, + {28, 18, 3, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {113,114,115,116} }, + {29, 19, 3, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {117,118,119,120} }, + {30, 20, 3, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {121,122,123,124} }, + {31, 21, 3, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {125,126,127,128} }, +}; +#endif + + +/* ========================================== + * Hudson32i Layout configuration + * ========================================== + */ +#ifdef SWPS_HUDSON32I_GA +unsigned hudsin32iga_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548; + +struct inv_ioexp_layout_s hudson32iga_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_HUDSON32IGA_P01P08, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander B */ + {0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0x24 */ + }, + {1, IOEXP_TYPE_HUDSON32IGA_P09P16, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander B */ + {0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0x24 */ + }, + {2, IOEXP_TYPE_HUDSON32IGA_P01P08, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander B */ + {0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0x25 */ + }, + {3, IOEXP_TYPE_HUDSON32IGA_P09P16, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander B */ + {0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0x25 */ + }, +}; + +struct inv_port_layout_s hudson32iga_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + { 0, 6, 0, 0, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 1, 2, 3, 4} }, + { 1, 7, 0, 1, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 5, 6, 7, 8} }, + { 2, 8, 0, 2, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 9, 10, 11, 12} }, + { 3, 9, 0, 3, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 13, 14, 15, 16} }, + { 4, 10, 0, 4, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 17, 18, 19, 20} }, + { 5, 11, 0, 5, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 21, 22, 23, 24} }, + { 6, 12, 0, 6, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 25, 26, 27, 28} }, + { 7, 13, 0, 7, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 29, 30, 31, 32} }, + { 8, 14, 1, 0, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 33, 34, 35, 36} }, + { 9, 15, 1, 1, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 37, 38, 39, 40} }, + {10, 16, 1, 2, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 41, 42, 43, 44} }, + {11, 17, 1, 3, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 45, 46, 47, 48} }, + {12, 18, 1, 4, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 49, 50, 51, 52} }, + {13, 19, 1, 5, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 53, 54, 55, 56} }, + {14, 20, 1, 6, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 57, 58, 59, 60} }, + {15, 21, 1, 7, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 61, 62, 63, 64} }, + {16, 22, 2, 0, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 65, 66, 67, 68} }, + {17, 23, 2, 1, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 69, 70, 71, 72} }, + {18, 24, 2, 2, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 73, 74, 75, 76} }, + {19, 25, 2, 3, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 77, 78, 79, 80} }, + {20, 26, 2, 4, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 81, 82, 83, 84} }, + {21, 27, 2, 5, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 85, 86, 87, 88} }, + {22, 28, 2, 6, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 89, 90, 91, 92} }, + {23, 29, 2, 7, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 93, 94, 95, 96} }, + {24, 30, 3, 0, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 97, 98, 99,100} }, + {25, 31, 3, 1, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {101,102,103,104} }, + {26, 32, 3, 2, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {105,106,107,108} }, + {27, 33, 3, 3, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {109,110,111,112} }, + {28, 34, 3, 4, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {113,114,115,116} }, + {29, 35, 3, 5, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {117,118,119,120} }, + {30, 36, 3, 6, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {121,122,123,124} }, + {31, 37, 3, 7, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {125,126,127,128} }, +}; +#endif + + +/* ========================================== + * Spruce Layout configuration + * ========================================== + */ +#ifdef SWPS_SPRUCE +unsigned spruce_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548; + +struct inv_ioexp_layout_s spruce_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_SPRUCE_7AB, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 7A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xf0, 0x33}, }, }, /* addr[2] = I/O Expander 7B */ + }, +}; + +struct inv_port_layout_s spruce_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + { 0, 6, 0, 0, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 81, 82, 83, 84} }, + { 1, 7, 0, 1, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 77, 78, 79, 80} }, + { 2, 8, 0, 2, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 97, 98, 99,100} }, + { 3, 9, 0, 3, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {101,102,103,104} }, + { 4, 10, 0, 4, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {105,106,107,108} }, + { 5, 11, 0, 5, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {109,110,111,112} }, +}; +#endif + + +/* ========================================== + * Cypress Layout configuration (Inventec version [Up->Down]) + * ========================================== + */ +#ifdef SWPS_CYPRESS_GA1 +unsigned cypress_ga1_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; + +struct inv_ioexp_layout_s cypress_ga1_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, +}; + +struct inv_port_layout_s cypress_ga1_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + { 0, 10, 0, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 1} }, + { 1, 11, 0, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 2} }, + { 2, 12, 0, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 3} }, + { 3, 13, 0, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 4} }, + { 4, 14, 0, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 5} }, + { 5, 15, 0, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 6} }, + { 6, 16, 0, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 7} }, + { 7, 17, 0, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 8} }, + { 8, 18, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 9} }, + { 9, 19, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 10} }, + {10, 20, 1, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 11} }, + {11, 21, 1, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 12} }, + {12, 22, 1, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 21} }, + {13, 23, 1, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 22} }, + {14, 24, 1, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 23} }, + {15, 25, 1, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 24} }, + {16, 26, 2, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 33} }, + {17, 27, 2, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 34} }, + {18, 28, 2, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 35} }, + {19, 29, 2, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 36} }, + {20, 30, 2, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 37} }, + {21, 31, 2, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 38} }, + {22, 32, 2, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 39} }, + {23, 33, 2, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 40} }, + {24, 34, 3, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 41} }, + {25, 35, 3, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 42} }, + {26, 36, 3, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 43} }, + {27, 37, 3, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 44} }, + {28, 38, 3, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 49} }, + {29, 39, 3, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 50} }, + {30, 40, 3, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 51} }, + {31, 41, 3, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 52} }, + {32, 42, 4, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 53} }, + {33, 43, 4, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 54} }, + {34, 44, 4, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 55} }, + {35, 45, 4, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 56} }, + {36, 46, 4, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 65} }, + {37, 47, 4, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 66} }, + {38, 48, 4, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 67} }, + {39, 49, 4, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 68} }, + {40, 50, 5, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 69} }, + {41, 51, 5, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 70} }, + {42, 52, 5, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 71} }, + {43, 53, 5, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 72} }, + {44, 54, 5, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 81} }, + {45, 55, 5, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 82} }, + {46, 56, 5, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 83} }, + {47, 57, 5, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 84} }, + {48, 58, 6, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 97, 98, 99,100} }, + {49, 59, 6, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 85, 86, 87, 88} }, + {50, 60, 6, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {101,102,103,104} }, + {51, 61, 6, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {105,106,107,108} }, + {52, 62, 6, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {109,110,111,112} }, + {53, 63, 6, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {117,118,119,120} }, +}; +#endif + + +/* ========================================== + * Cypress Layout configuration (Inventec version [Down->Up]) + * ========================================== + */ +#ifdef SWPS_CYPRESS_GA2 +unsigned cypress_ga2_gpio_rest_mux = MUX_RST_GPIO_FORCE_HEDERA; + +struct inv_ioexp_layout_s cypress_ga2_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, +}; + +struct inv_port_layout_s cypress_ga2_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + { 0, 11, 0, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 2} }, + { 1, 10, 0, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 1} }, + { 2, 13, 0, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 4} }, + { 3, 12, 0, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 3} }, + { 4, 15, 0, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 6} }, + { 5, 14, 0, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 5} }, + { 6, 17, 0, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 8} }, + { 7, 16, 0, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 7} }, + { 8, 19, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 10} }, + { 9, 18, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 9} }, + {10, 21, 1, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 12} }, + {11, 20, 1, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 11} }, + {12, 23, 1, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 22} }, + {13, 22, 1, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 21} }, + {14, 25, 1, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 24} }, + {15, 24, 1, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 23} }, + {16, 27, 2, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 34} }, + {17, 26, 2, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 33} }, + {18, 29, 2, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 36} }, + {19, 28, 2, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 35} }, + {20, 31, 2, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 38} }, + {21, 30, 2, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 37} }, + {22, 33, 2, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 40} }, + {23, 32, 2, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 39} }, + {24, 35, 3, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 42} }, + {25, 34, 3, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 41} }, + {26, 37, 3, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 44} }, + {27, 36, 3, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 43} }, + {28, 39, 3, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 50} }, + {29, 38, 3, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 49} }, + {30, 41, 3, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 52} }, + {31, 40, 3, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 51} }, + {32, 43, 4, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 54} }, + {33, 42, 4, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 53} }, + {34, 45, 4, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 56} }, + {35, 44, 4, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 55} }, + {36, 47, 4, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 66} }, + {37, 46, 4, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 65} }, + {38, 49, 4, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 68} }, + {39, 48, 4, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 67} }, + {40, 51, 5, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 70} }, + {41, 50, 5, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 69} }, + {42, 53, 5, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 72} }, + {43, 52, 5, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 71} }, + {44, 55, 5, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 82} }, + {45, 54, 5, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 81} }, + {46, 57, 5, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 84} }, + {47, 56, 5, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 83} }, + {48, 59, 6, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 85, 86, 87, 88} }, + {49, 58, 6, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 97, 98, 99,100} }, + {50, 61, 6, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {105,106,107,108} }, + {51, 60, 6, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {101,102,103,104} }, + {52, 63, 6, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {117,118,119,120} }, + {53, 62, 6, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {109,110,111,112} }, +}; +#endif + + +/* ========================================== + * Cypress Layout configuration (BaiDu version) + * ========================================== + */ +#ifdef SWPS_CYPRESS_BAI +unsigned cypress_b_gpio_rest_mux = MUX_RST_GPIO_FORCE_HEDERA; + +struct inv_ioexp_layout_s cypress_b_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, +}; + +struct inv_port_layout_s cypress_b_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + { 1, 11, 0, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 2} }, + { 2, 10, 0, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 1} }, + { 3, 13, 0, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 4} }, + { 4, 12, 0, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 3} }, + { 5, 15, 0, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 6} }, + { 6, 14, 0, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 5} }, + { 7, 17, 0, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 8} }, + { 8, 16, 0, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 7} }, + { 9, 19, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 10} }, + {10, 18, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 9} }, + {11, 21, 1, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 12} }, + {12, 20, 1, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 11} }, + {13, 23, 1, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 22} }, + {14, 22, 1, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 21} }, + {15, 25, 1, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 24} }, + {16, 24, 1, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 23} }, + {17, 27, 2, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 34} }, + {18, 26, 2, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 33} }, + {19, 29, 2, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 36} }, + {20, 28, 2, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 35} }, + {21, 31, 2, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 38} }, + {22, 30, 2, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 37} }, + {23, 33, 2, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 40} }, + {24, 32, 2, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 39} }, + {25, 35, 3, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 42} }, + {26, 34, 3, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 41} }, + {27, 37, 3, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 44} }, + {28, 36, 3, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 43} }, + {29, 39, 3, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 50} }, + {30, 38, 3, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 49} }, + {31, 41, 3, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 52} }, + {32, 40, 3, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 51} }, + {33, 43, 4, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 54} }, + {34, 42, 4, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 53} }, + {35, 45, 4, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 56} }, + {36, 44, 4, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 55} }, + {37, 47, 4, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 66} }, + {38, 46, 4, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 65} }, + {39, 49, 4, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 68} }, + {40, 48, 4, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 67} }, + {41, 51, 5, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 70} }, + {42, 50, 5, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 69} }, + {43, 53, 5, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 72} }, + {44, 52, 5, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 71} }, + {45, 55, 5, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 82} }, + {46, 54, 5, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 81} }, + {47, 57, 5, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 84} }, + {48, 56, 5, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 83} }, + {49, 59, 6, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 85, 86, 87, 88} }, + {50, 58, 6, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 97, 98, 99,100} }, + {51, 61, 6, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {105,106,107,108} }, + {52, 60, 6, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {101,102,103,104} }, + {53, 63, 6, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {117,118,119,120} }, + {54, 62, 6, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {109,110,111,112} }, +}; +#endif + + +/* ========================================== + * Redwood_fsl Layout configuration + * ========================================== + */ +#ifdef SWPS_REDWOOD_FSL +unsigned redwood_fsl_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548; + +struct inv_ioexp_layout_s redwood_fsl_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_REDWOOD_P01P08, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, + {1, IOEXP_TYPE_REDWOOD_P09P16, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, + {2, IOEXP_TYPE_REDWOOD_P01P08, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, + {3, IOEXP_TYPE_REDWOOD_P09P16, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */ + {0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */ + }, +}; + + +struct inv_port_layout_s redwood_fsl_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + { 0, 22, 0, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 1, 2, 3, 4} }, + { 1, 23, 0, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 5, 6, 7, 8} }, + { 2, 24, 0, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 9, 10, 11, 12} }, + { 3, 25, 0, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 13, 14, 15, 16} }, + { 4, 26, 0, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 17, 18, 19, 20} }, + { 5, 27, 0, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 21, 22, 23, 24} }, + { 6, 28, 0, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 25, 26, 27, 28} }, + { 7, 29, 0, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 29, 30, 31, 32} }, + { 8, 30, 1, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 33, 34, 35, 36} }, + { 9, 31, 1, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 37, 38, 39, 40} }, + {10, 32, 1, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 41, 42, 43, 44} }, + {11, 33, 1, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 45, 46, 47, 48} }, + {12, 34, 1, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 49, 50, 51, 52} }, + {13, 35, 1, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 53, 54, 55, 56} }, + {14, 36, 1, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 57, 58, 59, 60} }, + {15, 37, 1, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 61, 62, 63, 64} }, + {16, 6, 2, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 65, 66, 67, 68} }, + {17, 7, 2, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 69, 70, 71, 72} }, + {18, 8, 2, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 73, 74, 75, 76} }, + {19, 9, 2, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 77, 78, 79, 80} }, + {20, 10, 2, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 81, 82, 83, 84} }, + {21, 11, 2, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 85, 86, 87, 88} }, + {22, 12, 2, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 89, 90, 91, 92} }, + {23, 13, 2, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 93, 94, 95, 96} }, + {24, 14, 3, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 97, 98, 99,100} }, + {25, 15, 3, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {101,102,103,104} }, + {26, 16, 3, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {105,106,107,108} }, + {27, 17, 3, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {109,110,111,112} }, + {28, 18, 3, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {113,114,115,116} }, + {29, 19, 3, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {117,118,119,120} }, + {30, 20, 3, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {121,122,123,124} }, + {31, 21, 3, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {125,126,127,128} }, +}; +#endif + + +/* ========================================== + * Tahoe Layout configuration + * ========================================== + */ +#ifdef SWPS_TAHOE +unsigned tahoe_gpio_rest_mux = MUX_RST_GPIO_249_PCA9548; + +struct inv_ioexp_layout_s tahoe_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_TAHOE_6ABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xce, 0xb9}, {0x18, 0xe3}, }, /* addr[0] = I/O Expander 6 A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xce, 0xb9}, {0x18, 0xe3}, }, /* addr[1] = I/O Expander 6 B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xce, 0xb9}, {0x18, 0xe3}, }, }, /* addr[2] = I/O Expander 6 C */ + }, + {1, IOEXP_TYPE_TAHOE_5A, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xce, 0xb9}, {0x18, 0xe3}, }, }, /* addr[0] = I/O Expander 5 A */ + }, +}; + + +struct inv_port_layout_s tahoe_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + { 0, 12, 1, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 65, 66, 67, 68} }, + { 1, 11, 1, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 53, 54, 55, 56} }, + { 2, 22, 0, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 69, 70, 71, 72} }, + { 3, 21, 0, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 81, 82, 83, 84} }, + { 4, 24, 0, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 97, 98, 99, 100} }, + { 5, 23, 0, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 85, 86, 87, 88} }, + { 6, 18, 0, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {101, 102, 103, 104} }, + { 7, 17, 0, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {105, 106, 107, 108} }, + { 8, 20, 0, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {113, 114, 115, 116} }, + { 9, 19, 0, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {109, 110, 111, 112} }, +}; +#endif + + +/* ========================================== + * Sequoia Layout configuration + * ========================================== + */ +#ifdef SWPS_SEQUOIA +unsigned sequoia_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; + +struct inv_ioexp_layout_s sequoia_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_SEQUOIA_NABC, { {1, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + {1, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + {1, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {1, IOEXP_TYPE_SEQUOIA_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 1 A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 1 B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 1 C */ + }, + {2, IOEXP_TYPE_SEQUOIA_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 2 A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 2 B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 2 C */ + }, + {3, IOEXP_TYPE_SEQUOIA_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 3 A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 3 B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 3 C */ + }, + {4, IOEXP_TYPE_SEQUOIA_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 4 A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 4 B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 4 C */ + }, + {5, IOEXP_TYPE_SEQUOIA_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 5 A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 5 B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 C */ + }, + {6, IOEXP_TYPE_SEQUOIA_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 6 A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 6 B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 6 C */ + }, + {7, IOEXP_TYPE_SEQUOIA_NABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 7 B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, +}; + + +struct inv_port_layout_s sequoia_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + { 0, 9, 0, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 9, 10, 11, 12} }, + { 1, 10, 0, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 1, 2, 3, 4} }, + { 2, 11, 0, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 25, 26, 27, 28} }, + { 3, 12, 0, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 17, 18, 19, 20} }, + { 4, 13, 0, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 41, 42, 43, 44} }, + { 5, 14, 0, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 33, 34, 35, 36} }, + { 6, 15, 0, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 57, 58, 59, 60} }, + { 7, 16, 0, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 49, 50, 51, 52} }, + { 8, 17, 1, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 73, 74, 75, 76} }, + { 9, 18, 1, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 65, 66, 67, 68} }, + {10, 19, 1, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 89, 90, 91, 92} }, + {11, 20, 1, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 81, 82, 83, 84} }, + {12, 21, 1, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {105, 106, 107, 108} }, + {13, 22, 1, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 97, 98, 99, 100} }, + {14, 23, 1, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {121, 122, 123, 124} }, + {15, 24, 1, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {113, 114, 115, 116} }, + {16, 25, 2, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {137, 138, 139, 140} }, + {17, 26, 2, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {129, 130, 131, 132} }, + {18, 27, 2, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {153, 154, 155, 156} }, + {19, 28, 2, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {145, 146, 147, 148} }, + {20, 29, 2, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {169, 170, 171, 172} }, + {21, 30, 2, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {161, 162, 163, 164} }, + {22, 31, 2, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {185, 186, 187, 188} }, + {23, 32, 2, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {177, 178, 179, 180} }, + {24, 33, 3, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {201, 202, 203, 204} }, + {25, 34, 3, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {193, 194, 195, 196} }, + {26, 35, 3, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {217, 218, 219, 220} }, + {27, 36, 3, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {209, 210, 211, 212} }, + {28, 37, 3, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {233, 234, 235, 236} }, + {29, 38, 3, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {225, 226, 227, 228} }, + {30, 39, 3, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {249, 250, 251, 252} }, + {31, 40, 3, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {241, 242, 243, 244} }, + {32, 44, 4, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 13, 14, 15, 16} }, + {33, 43, 4, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 5, 6, 7, 8} }, + {34, 42, 4, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 29, 30, 31, 32} }, + {35, 41, 4, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 21, 22, 23, 24} }, + {36, 48, 4, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 45, 46, 47, 48} }, + {37, 47, 4, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 37, 38, 39, 40} }, + {38, 46, 4, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 61, 62, 63, 64} }, + {39, 45, 4, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 53, 54, 55, 56} }, + {40, 52, 5, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 77, 78, 79, 80} }, + {41, 51, 5, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 69, 70, 71, 72} }, + {42, 50, 5, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 93, 94, 95, 96} }, + {43, 49, 5, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 85, 86, 87, 88} }, + {44, 56, 5, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {109, 110, 111, 112} }, + {45, 55, 5, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {101, 102, 103, 104} }, + {46, 54, 5, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {125, 126, 127, 128} }, + {47, 53, 5, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {117, 118, 119, 120} }, + {48, 60, 6, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {141, 142, 143, 144} }, + {49, 59, 6, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {133, 134, 135, 136} }, + {50, 58, 6, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {157, 158, 159, 160} }, + {51, 57, 6, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {149, 150, 151, 152} }, + {52, 64, 6, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {173, 174, 175, 176} }, + {53, 63, 6, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {165, 166, 167, 168} }, + {54, 62, 6, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {189, 190, 191, 192} }, + {55, 61, 6, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {181, 182, 183, 184} }, + {56, 68, 7, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {205, 206, 207, 208} }, + {57, 67, 7, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {197, 198, 199, 200} }, + {58, 66, 7, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {221, 222, 223, 224} }, + {59, 65, 7, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {213, 214, 215, 216} }, + {60, 72, 7, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {237, 238, 239, 240} }, + {61, 71, 7, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {229, 230, 231, 232} }, + {62, 70, 7, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {253, 254, 255, 256} }, + {63, 69, 7, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {245, 246, 247, 248} }, +}; +#endif + + +/* ========================================== + * Lavender Layout configuration + * ========================================== + */ +#if (PLATFORM_SETTINGS == PLATFORM_TYPE_LAVENDER_GA) +unsigned lavender_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548; +#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_LAVENDER_ONL) +unsigned lavender_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; +#endif + +#ifdef SWPS_LAVENDER +struct inv_ioexp_layout_s lavender_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_SEQUOIA_NABC, { { 1, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + { 1, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + { 1, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {1, IOEXP_TYPE_SEQUOIA_NABC, { { 2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 1 A */ + { 2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 1 B */ + { 2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 1 C */ + }, + {2, IOEXP_TYPE_SEQUOIA_NABC, { { 3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 2 A */ + { 3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 2 B */ + { 3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 2 C */ + }, + {3, IOEXP_TYPE_SEQUOIA_NABC, { { 4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 3 A */ + { 4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 3 B */ + { 4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 3 C */ + }, + {4, IOEXP_TYPE_SEQUOIA_NABC, { { 9, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 4 A */ + { 9, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 4 B */ + { 9, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 4 C */ + }, + {5, IOEXP_TYPE_SEQUOIA_NABC, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 5 A */ + {10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 5 B */ + {10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 C */ + }, + {6, IOEXP_TYPE_SEQUOIA_NABC, { {11, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 6 A */ + {11, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 6 B */ + {11, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 6 C */ + }, + {7, IOEXP_TYPE_SEQUOIA_NABC, { {12, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 7 A */ + {12, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 7 B */ + {12, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, + {8, IOEXP_TYPE_LAVENDER_P65, { { 5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xF6, 0xff}, {0xF8, 0xff}, }, }, /* addr[0] = I/O Expander CPU */ + }, +}; + + +struct inv_port_layout_s lavender_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + { 0, 17, 0, 0, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {188, 189, 190, 191} }, + { 1, 18, 0, 1, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {184, 185, 186, 187} }, + { 2, 19, 0, 2, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {180, 181, 182, 183} }, + { 3, 20, 0, 3, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {176, 177, 178, 179} }, + { 4, 21, 0, 4, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {172, 173, 174, 175} }, + { 5, 22, 0, 5, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {168, 169, 170, 171} }, + { 6, 23, 0, 6, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {164, 165, 166, 167} }, + { 7, 24, 0, 7, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {160, 161, 162, 163} }, + { 8, 25, 1, 0, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {156, 157, 158, 159} }, + { 9, 26, 1, 1, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {152, 153, 154, 155} }, + {10, 27, 1, 2, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {148, 149, 150, 151} }, + {11, 28, 1, 3, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {144, 145, 146, 147} }, + {12, 29, 1, 4, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {140, 141, 142, 143} }, + {13, 30, 1, 5, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {136, 137, 138, 139} }, + {14, 31, 1, 6, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {132, 133, 134, 135} }, + {15, 32, 1, 7, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {128, 129, 130, 131} }, + {16, 33, 2, 0, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 0, 1, 2, 3} }, + {17, 34, 2, 1, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 4, 5, 6, 7} }, + {18, 35, 2, 2, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 8, 9, 10, 11} }, + {19, 36, 2, 3, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 12, 13, 14, 15} }, + {20, 37, 2, 4, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 16, 17, 18, 19} }, + {21, 38, 2, 5, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 20, 21, 22, 23} }, + {22, 39, 2, 6, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 24, 25, 26, 27} }, + {23, 40, 2, 7, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 28, 29, 30, 31} }, + {24, 41, 3, 0, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 32, 33, 34, 35} }, + {25, 42, 3, 1, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 36, 37, 38, 39} }, + {26, 43, 3, 2, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 40, 41, 42, 43} }, + {27, 44, 3, 3, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 44, 45, 46, 47} }, + {28, 45, 3, 4, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 48, 49, 50, 51} }, + {29, 46, 3, 5, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 52, 53, 54, 55} }, + {30, 47, 3, 6, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 56, 57, 58, 59} }, + {31, 48, 3, 7, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 60, 61, 62, 63} }, + {32, 49, 4, 0, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {256, 257, 258, 259} }, + {33, 50, 4, 1, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {260, 261, 262, 263} }, + {34, 51, 4, 2, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {264, 265, 266, 267} }, + {35, 52, 4, 3, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {268, 269, 270, 271} }, + {36, 53, 4, 4, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {272, 273, 274, 275} }, + {37, 54, 4, 5, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {276, 277, 278, 279} }, + {38, 55, 4, 6, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {280, 281, 282, 283} }, + {39, 56, 4, 7, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {284, 285, 286, 287} }, + {40, 57, 5, 0, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {288, 289, 290, 291} }, + {41, 58, 5, 1, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {292, 293, 294, 295} }, + {42, 59, 5, 2, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {296, 297, 298, 299} }, + {43, 60, 5, 3, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {300, 301, 302, 303} }, + {44, 61, 5, 4, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {304, 305, 306, 307} }, + {45, 62, 5, 5, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {308, 309, 310, 311} }, + {46, 63, 5, 6, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {312, 313, 314, 315} }, + {47, 64, 5, 7, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {316, 317, 318, 319} }, + {48, 65, 6, 0, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {444, 445, 446, 447} }, + {49, 66, 6, 1, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {440, 441, 442, 443} }, + {50, 67, 6, 2, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {436, 437, 438, 439} }, + {51, 68, 6, 3, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {432, 433, 434, 435} }, + {52, 69, 6, 4, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {428, 429, 430, 431} }, + {53, 70, 6, 5, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {424, 425, 426, 427} }, + {54, 71, 6, 6, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {420, 421, 422, 423} }, + {55, 72, 6, 7, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {416, 417, 418, 419} }, + {56, 73, 7, 0, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {412, 413, 414, 415} }, + {57, 74, 7, 1, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {408, 409, 410, 411} }, + {58, 75, 7, 2, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {404, 405, 406, 407} }, + {59, 76, 7, 3, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {400, 401, 402, 403} }, + {60, 77, 7, 4, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {396, 397, 398, 399} }, + {61, 78, 7, 5, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {392, 393, 394, 395} }, + {62, 79, 7, 6, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {388, 389, 390, 391} }, + {63, 80, 7, 7, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {384, 385, 386, 387} }, + {64, 5, 8, 0, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 64, 65, 66, 67} }, +}; +#endif + +/* =========================================================== + * Cottonwood Layout configuration Rangeley (Rangeley CPU board) + * =========================================================== + */ +#ifdef SWPS_COTTONWOOD_RANGELEY +unsigned cottonwood_rangeley_gpio_rest_mux = MUX_RST_GPIO_500_PCA9548; + +struct inv_ioexp_layout_s cottonwood_rangeley_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, CPLD_TYPE_COTTONWOOD,{ {1, 0x55, {22, 23, 24, 25}, {22, 23, 24, 25}, {-1, -1, -1, -1}, {0xee, 0xee, 0x99, 0x99}, {0x00, 0x00, 0x00, 0x00}, }, + }, + }, +}; + + +struct inv_port_layout_s cottonwood_rangeley_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHI_TYPE / LANE_ID */ + { 0, 2, 0, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 75} }, + { 1, 3, 0, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 77} }, + { 2, 4, 0, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 79} }, + { 3, 5, 0, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 81} }, +}; +#endif + +/* =========================================================== + * Maple Layout configuration (Old) + * =========================================================== + */ +#ifdef SWPS_MAPLE_GA +unsigned maple_ga_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548; + +struct inv_ioexp_layout_s maple_ga_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_MAPLE_0ABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {1, IOEXP_TYPE_MAPLE_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_MAPLE_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_MAPLE_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_MAPLE_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_MAPLE_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_MAPLE_NABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, +}; + +struct inv_port_layout_s maple_ga_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + { 0, 18, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 1} }, + { 1, 19, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 2} }, + { 2, 20, 1, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 3} }, + { 3, 21, 1, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 4} }, + { 4, 22, 1, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 5} }, + { 5, 23, 1, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 6} }, + { 6, 24, 1, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 7} }, + { 7, 25, 1, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 8} }, + { 8, 26, 2, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 13} }, + { 9, 27, 2, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 14} }, + {10, 28, 2, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 15} }, + {11, 29, 2, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 16} }, + {12, 30, 2, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 21} }, + {13, 31, 2, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 22} }, + {14, 32, 2, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 23} }, + {15, 33, 2, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 24} }, + {16, 34, 3, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 29} }, + {17, 35, 3, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 30} }, + {18, 36, 3, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 31} }, + {19, 37, 3, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 32} }, + {20, 38, 3, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 33} }, + {21, 39, 3, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 34} }, + {22, 40, 3, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 35} }, + {23, 41, 3, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 36} }, + {24, 42, 4, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 41} }, + {25, 43, 4, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 42} }, + {26, 44, 4, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 43} }, + {27, 45, 4, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 44} }, + {28, 46, 4, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 49} }, + {29, 47, 4, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 50} }, + {30, 48, 4, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 51} }, + {31, 49, 4, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 52} }, + {32, 50, 5, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 57} }, + {33, 51, 5, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 58} }, + {34, 52, 5, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 59} }, + {35, 53, 5, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 60} }, + {36, 54, 5, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 61} }, + {37, 55, 5, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 62} }, + {38, 56, 5, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 63} }, + {39, 57, 5, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 64} }, + {40, 58, 6, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 65} }, + {41, 59, 6, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 66} }, + {42, 60, 6, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 67} }, + {43, 61, 6, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 68} }, + {44, 62, 6, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 69} }, + {45, 63, 6, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 70} }, + {46, 64, 6, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 71} }, + {47, 65, 6, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 72} }, + {48, 10, 0, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 77, 78, 79, 80} }, + {49, 11, 0, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 85, 86, 87, 88} }, + {50, 12, 0, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 93, 94, 95, 96} }, + {51, 13, 0, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 97, 98, 99,100} }, + {52, 14, 0, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, {105,106,107,108} }, + {53, 15, 0, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, {113,114,115,116} }, + {54, 16, 0, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, {121,122,123,124} }, + {55, 17, 0, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, {125,126,127,128} }, +}; +#endif + +/* =========================================================== + * Maple Layout configuration (B version) + * =========================================================== + */ +#ifdef SWPS_MAPLE_B +unsigned maple_b_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548; + +struct inv_ioexp_layout_s maple_b_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_MAPLE_0ABC, { { 6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */ + { 6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + { 6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {1, IOEXP_TYPE_MAPLE_NABC, { { 7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + { 7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + { 7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_MAPLE_NABC, { { 8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + { 8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + { 8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_MAPLE_NABC, { { 9, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + { 9, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + { 9, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_MAPLE_NABC, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_MAPLE_NABC, { {11, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {11, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {11, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_MAPLE_NABC, { {12, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {12, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {12, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, +}; + +struct inv_port_layout_s maple_b_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + { 1, 23, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 2} }, + { 0, 22, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 1} }, + { 3, 25, 1, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 4} }, + { 2, 24, 1, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 3} }, + { 5, 27, 1, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 6} }, + { 4, 26, 1, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 5} }, + { 7, 29, 1, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 8} }, + { 6, 28, 1, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 7} }, + { 9, 31, 2, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 14} }, + { 8, 30, 2, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 13} }, + {11, 33, 2, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 16} }, + {10, 32, 2, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 15} }, + {13, 35, 2, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 22} }, + {12, 34, 2, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 21} }, + {15, 37, 2, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 24} }, + {14, 36, 2, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 23} }, + {17, 39, 3, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 30} }, + {16, 38, 3, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 29} }, + {19, 41, 3, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 32} }, + {18, 40, 3, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 31} }, + {21, 43, 3, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 34} }, + {20, 42, 3, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 33} }, + {23, 45, 3, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 36} }, + {22, 44, 3, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 35} }, + {25, 47, 4, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 42} }, + {24, 46, 4, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 41} }, + {27, 49, 4, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 44} }, + {26, 48, 4, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 43} }, + {29, 51, 4, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 50} }, + {28, 50, 4, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 49} }, + {31, 53, 4, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 52} }, + {30, 52, 4, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 51} }, + {33, 55, 5, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 58} }, + {32, 54, 5, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 57} }, + {35, 57, 5, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 60} }, + {34, 56, 5, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 59} }, + {37, 59, 5, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 62} }, + {36, 58, 5, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 61} }, + {39, 61, 5, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 64} }, + {38, 60, 5, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 63} }, + {41, 63, 6, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 66} }, + {40, 62, 6, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 65} }, + {43, 65, 6, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 68} }, + {42, 64, 6, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 67} }, + {45, 67, 6, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 70} }, + {44, 66, 6, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 69} }, + {47, 69, 6, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 72} }, + {46, 68, 6, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 71} }, + {49, 15, 0, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 77, 78, 79, 80} }, + {48, 14, 0, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 85, 86, 87, 88} }, + {51, 17, 0, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 97, 98, 99,100} }, + {50, 16, 0, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 93, 94, 95, 96} }, + {53, 19, 0, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, {105,106,107,108} }, + {52, 18, 0, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, {113,114,115,116} }, + {55, 21, 0, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, {125,126,127,128} }, + {54, 20, 0, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, {121,122,123,124} }, +}; +#endif + + +/* ========================================== + * Gulmohar Layout configuration + * ========================================== + */ +#ifdef SWPS_GULMOHAR +unsigned gulmohar_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548; + +struct inv_ioexp_layout_s gulmohar_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_GULMOHAR_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {1, IOEXP_TYPE_GULMOHAR_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_GULMOHAR_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_GULMOHAR_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_GULMOHAR_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_GULMOHAR_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_GULMOHAR_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xff}, }, /* addr[1] = I/O Expander 7 B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, +}; + + + +struct inv_port_layout_s gulmohar_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + { 0, 10, 0, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 1} }, + { 1, 11, 0, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 2} }, + { 2, 12, 0, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 3} }, + { 3, 13, 0, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 4} }, + { 4, 14, 0, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 5} }, + { 5, 15, 0, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 6} }, + { 6, 16, 0, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 7} }, + { 7, 17, 0, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 8} }, + { 8, 18, 1, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 9} }, + { 9, 19, 1, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 10} }, + {10, 20, 1, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 11} }, + {11, 21, 1, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 12} }, + {12, 22, 1, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 21} }, + {13, 23, 1, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 22} }, + {14, 24, 1, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 23} }, + {15, 25, 1, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 24} }, + {16, 26, 2, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 33} }, + {17, 27, 2, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 34} }, + {18, 28, 2, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 35} }, + {19, 29, 2, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 36} }, + {20, 30, 2, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 37} }, + {21, 31, 2, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 38} }, + {22, 32, 2, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 39} }, + {23, 33, 2, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 40} }, + {24, 34, 3, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 41} }, + {25, 35, 3, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 42} }, + {26, 36, 3, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 43} }, + {27, 37, 3, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 44} }, + {28, 38, 3, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 49} }, + {29, 39, 3, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 50} }, + {30, 40, 3, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 51} }, + {31, 41, 3, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 52} }, + {32, 42, 4, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 53} }, + {33, 43, 4, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 54} }, + {34, 44, 4, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 55} }, + {35, 45, 4, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 56} }, + {36, 46, 4, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 65} }, + {37, 47, 4, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 66} }, + {38, 48, 4, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 67} }, + {39, 49, 4, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 68} }, + {40, 50, 5, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 69} }, + {41, 51, 5, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 70} }, + {42, 52, 5, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 71} }, + {43, 53, 5, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 72} }, + {44, 54, 5, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 81} }, + {45, 55, 5, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 82} }, + {46, 56, 5, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 83} }, + {47, 57, 5, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 84} }, + {48, 58, 6, 0, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 97, 98, 99,100} }, + {49, 59, 6, 1, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 85, 86, 87, 88} }, + {50, 60, 6, 2, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {101,102,103,104} }, + {51, 61, 6, 3, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {105,106,107,108} }, + {52, 62, 6, 4, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {109,110,111,112} }, + {53, 63, 6, 5, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {109,110,111,112} }, +}; +#endif + + +/* ========================================== + * Gulmohar_2T EVT1 Layout configuration + * ========================================== + */ +#ifdef SWPS_GULMOHAR_2T_EVT1 +unsigned gulmohar_2t_evt1_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548; + +struct inv_ioexp_layout_s gulmohar_2t_evt1_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */ + {2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */ + {2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {1, IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC,{ {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */ + {3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */ + {3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC,{ {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC,{ {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xd6, 0xda}, {0x18, 0xe3}, }, /* addr[0] = I/O Expander 7 A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xd6, 0xda}, {0x18, 0xe3}, }, /* addr[1] = I/O Expander 7 B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xd6, 0xff}, {0x18, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */ + }, +}; + + + +struct inv_port_layout_s gulmohar_2t_evt1_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + { 0, 10, 0, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + { 1, 11, 0, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + { 2, 12, 0, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + { 3, 13, 0, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + { 4, 14, 0, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + { 5, 15, 0, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + { 6, 16, 0, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + { 7, 17, 0, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + { 8, 18, 1, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + { 9, 19, 1, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {10, 20, 1, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {11, 21, 1, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {12, 22, 1, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {13, 23, 1, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {14, 24, 1, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {15, 25, 1, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {16, 26, 2, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {17, 27, 2, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {18, 28, 2, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {19, 29, 2, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {20, 30, 2, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {21, 31, 2, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {22, 32, 2, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {23, 33, 2, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {24, 34, 3, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {25, 35, 3, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {26, 36, 3, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {27, 37, 3, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {28, 38, 3, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {29, 39, 3, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {30, 40, 3, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {31, 41, 3, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {32, 42, 4, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {33, 43, 4, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {34, 44, 4, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {35, 45, 4, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {36, 46, 4, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {37, 47, 4, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {38, 48, 4, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {39, 49, 4, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {40, 50, 5, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {41, 51, 5, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {42, 52, 5, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {43, 53, 5, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {44, 54, 5, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {45, 55, 5, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {46, 56, 5, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {47, 57, 5, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} }, + {48, 59, 6, 1, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} }, + {49, 58, 6, 0, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} }, + {50, 61, 6, 3, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} }, + {51, 60, 6, 2, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} }, + {52, 63, 6, 5, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} }, + {53, 62, 6, 4, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} }, + {54, 65, 6, 7, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} }, + {55, 64, 6, 6, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} }, +}; +#endif + + +/* =========================================================== + * Peony-SFP Layout configuration + * =========================================================== + */ +#ifdef SWPS_PEONY_SFP +unsigned peony_sfp_gpio_rest_mux = MUX_RST_CPLD_C0_A77_70_74_RST_ALL; + +struct inv_ioexp_layout_s peony_sfp_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_QSFP_6P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 0 A */ + {4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + {4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, + {1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {9, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {9, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {9, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, + {6, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */ + {10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */ + {10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */ + }, +}; + +struct inv_port_layout_s peony_sfp_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + { 0, 20, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 1} }, + { 1, 21, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 2} }, + { 2, 22, 1, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 3} }, + { 3, 23, 1, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 4} }, + { 4, 24, 1, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 5} }, + { 5, 25, 1, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 6} }, + { 6, 26, 1, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 7} }, + { 7, 27, 1, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 8} }, + { 8, 28, 2, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 13} }, + { 9, 29, 2, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 14} }, + {10, 30, 2, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 15} }, + {11, 31, 2, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 16} }, + {12, 32, 2, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 21} }, + {13, 33, 2, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 22} }, + {14, 34, 2, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 23} }, + {15, 35, 2, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 24} }, + {16, 36, 3, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 29} }, + {17, 37, 3, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 30} }, + {18, 38, 3, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 31} }, + {19, 39, 3, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 32} }, + {20, 40, 3, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 33} }, + {21, 41, 3, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 34} }, + {22, 42, 3, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 35} }, + {23, 43, 3, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 36} }, + {24, 44, 4, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 65} }, + {25, 45, 4, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 66} }, + {26, 46, 4, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 67} }, + {27, 47, 4, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 68} }, + {28, 48, 4, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 69} }, + {29, 49, 4, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 70} }, + {30, 50, 4, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 71} }, + {31, 51, 4, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 72} }, + {32, 52, 5, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 97} }, + {33, 53, 5, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 98} }, + {34, 54, 5, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 99} }, + {35, 55, 5, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {100} }, + {36, 56, 5, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {105} }, + {37, 57, 5, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {106} }, + {38, 58, 5, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {107} }, + {39, 59, 5, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {108} }, + {40, 60, 6, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {113} }, + {41, 61, 6, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {114} }, + {42, 62, 6, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {115} }, + {43, 63, 6, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {116} }, + {44, 64, 6, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {121} }, + {45, 65, 6, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {122} }, + {46, 66, 6, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {123} }, + {47, 67, 6, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {124} }, + {48, 12, 0, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 49, 50, 51, 52} }, + {49, 13, 0, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 57, 58, 59, 60} }, + {50, 14, 0, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 61, 62, 63, 64} }, + {51, 15, 0, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 77, 78, 79, 80} }, + {52, 16, 0, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 85, 86, 87, 88} }, + {53, 17, 0, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 93, 94, 95, 96} }, +}; +#endif + + +/* =========================================================== + * Peony-Copper Layout configuration + * =========================================================== + */ +#ifdef SWPS_PEONY_COPPER +unsigned peony_copper_gpio_rest_mux = MUX_RST_CPLD_C0_A77_70_74_RST_ALL; + +struct inv_ioexp_layout_s peony_copper_ioexp_layout[] = { + /* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */ + {0, IOEXP_TYPE_QSFP_6P_LAYOUT_1, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 0 A */ + {10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xff}, }, /* addr[1] = I/O Expander 0 B */ + {10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */ + }, +}; + +struct inv_port_layout_s peony_copper_port_layout[] = { + /* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */ + {48, 4, 0, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 49, 50, 51, 52} }, + {49, 5, 0, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 57, 58, 59, 60} }, + {50, 6, 0, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 61, 62, 63, 64} }, + {51, 7, 0, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 77, 78, 79, 80} }, + {52, 8, 0, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 85, 86, 87, 88} }, + {53, 9, 0, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 93, 94, 95, 96} }, +}; +#endif + + + +#endif /* INV_SWPS_H */ + + + + + + + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/io_expander.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/io_expander.c new file mode 100644 index 000000000000..985bfbb45eb8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/io_expander.c @@ -0,0 +1,2572 @@ +#include +#include +#include "io_expander.h" + +/* For build single module using (Ex: ONL platform) */ +#include +//#include + + +static struct ioexp_obj_s *ioexp_head_p = NULL; +static struct ioexp_obj_s *ioexp_tail_p = NULL; +extern int io_no_init; + +/* ========== Register IOEXP layout ========== + */ +struct ioexp_map_s ioexp_map_magnolia_nab = { + + .chip_amount = 2, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 0, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 0, 7}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 0, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 0, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 1, 0}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 1, 1}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 1, 0}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 1, 1}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 0, 2}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 0, 3}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 0, 2}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 0, 3}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 1, 4}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 1, 5}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 1, 4}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 1, 5}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_magnolia_4ab = { + + .chip_amount = 2, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 0, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 0, 7}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 0, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 0, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 1, 0}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 1, 1}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 0, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 0, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 0, 2}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 0, 3}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 1, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 1, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 1, 4}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 1, 5}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 1, 4}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 1, 5}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_magnolia_7ab = { + + .chip_amount = 2, + .data_width = 2, + + .map_present = { {1, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {1, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {1, 0, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {1, 0, 7}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + }, + .map_reset = { {0, 0, 0}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 0, 1}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 0, 2}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + {0, 0, 3}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */ + {1, 0, 0}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */ + {1, 0, 1}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */ + }, + .map_lpmod = { {0, 0, 4}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {0, 0, 5}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {0, 0, 6}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + {0, 0, 7}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */ + {1, 0, 2}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */ + {1, 0, 3}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */ + }, + .map_modsel = { {0, 1, 4}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {0, 1, 5}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {0, 1, 6}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + {0, 1, 7}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */ + {1, 1, 4}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */ + {1, 1, 5}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */ + }, +}; + + +struct ioexp_map_s ioexp_map_redwood_p01p08_p17p24 = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 0, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 0, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 0, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 0, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {2, 0, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {2, 0, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_reset = { {0, 0, 0}, /* map_reset[0] = QRESET_QSFP28_N_P(X) */ + {0, 0, 1}, /* map_reset[1] = QRESET_QSFP28_N_P(X+1) */ + {0, 0, 2}, /* map_reset[2] = QRESET_QSFP28_N_P(X+2) */ + {0, 0, 3}, /* map_reset[3] = QRESET_QSFP28_N_P(X+3) */ + {1, 0, 0}, /* map_reset[4] = QRESET_QSFP28_N_P(X+4) */ + {1, 0, 1}, /* map_reset[5] = QRESET_QSFP28_N_P(X+5) */ + {1, 0, 2}, /* map_reset[6] = QRESET_QSFP28_N_P(X+6) */ + {1, 0, 3}, /* map_reset[7] = QRESET_QSFP28_N_P(X+7) */ + }, + .map_lpmod = { {0, 0, 4}, /* map_lpmod[0] = LPMODE_QSFP28_P(X) */ + {0, 0, 5}, /* map_lpmod[1] = LPMODE_QSFP28_P(X+1) */ + {0, 0, 6}, /* map_lpmod[2] = LPMODE_QSFP28_P(X+2) */ + {0, 0, 7}, /* map_lpmod[3] = LPMODE_QSFP28_P(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP28_P(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP28_P(X+5) */ + {1, 0, 6}, /* map_lpmod[6] = LPMODE_QSFP28_P(X+6) */ + {1, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP28_P(X+7) */ + }, + .map_modsel = { {0, 1, 4}, /* map_modsel[0] = MODSEL_QSFP28_N_P(X) */ + {0, 1, 5}, /* map_modsel[1] = MODSEL_QSFP28_N_P(X+1) */ + {0, 1, 6}, /* map_modsel[2] = MODSEL_QSFP28_N_P(X+2) */ + {0, 1, 7}, /* map_modsel[3] = MODSEL_QSFP28_N_P(X+3) */ + {1, 1, 4}, /* map_modsel[4] = MODSEL_QSFP28_N_P(X+4) */ + {1, 1, 5}, /* map_modsel[5] = MODSEL_QSFP28_N_P(X+5) */ + {1, 1, 6}, /* map_modsel[6] = MODSEL_QSFP28_N_P(X+6) */ + {1, 1, 7}, /* map_modsel[7] = MODSEL_QSFP28_N_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_redwood_p09p16_p25p32 = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 1, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 1, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {2, 1, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {2, 1, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_reset = { {0, 0, 0}, /* map_reset[0] = QRESET_QSFP28_N_P(X) */ + {0, 0, 1}, /* map_reset[1] = QRESET_QSFP28_N_P(X+1) */ + {0, 0, 2}, /* map_reset[2] = QRESET_QSFP28_N_P(X+2) */ + {0, 0, 3}, /* map_reset[3] = QRESET_QSFP28_N_P(X+3) */ + {1, 0, 0}, /* map_reset[4] = QRESET_QSFP28_N_P(X+4) */ + {1, 0, 1}, /* map_reset[5] = QRESET_QSFP28_N_P(X+5) */ + {1, 0, 2}, /* map_reset[6] = QRESET_QSFP28_N_P(X+6) */ + {1, 0, 3}, /* map_reset[7] = QRESET_QSFP28_N_P(X+7) */ + }, + .map_lpmod = { {0, 0, 4}, /* map_lpmod[0] = LPMODE_QSFP28_P(X) */ + {0, 0, 5}, /* map_lpmod[1] = LPMODE_QSFP28_P(X+1) */ + {0, 0, 6}, /* map_lpmod[2] = LPMODE_QSFP28_P(X+2) */ + {0, 0, 7}, /* map_lpmod[3] = LPMODE_QSFP28_P(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP28_P(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP28_P(X+5) */ + {1, 0, 6}, /* map_lpmod[6] = LPMODE_QSFP28_P(X+6) */ + {1, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP28_P(X+7) */ + }, + .map_modsel = { {0, 1, 4}, /* map_modsel[0] = MODSEL_QSFP28_N_P(X) */ + {0, 1, 5}, /* map_modsel[1] = MODSEL_QSFP28_N_P(X+1) */ + {0, 1, 6}, /* map_modsel[2] = MODSEL_QSFP28_N_P(X+2) */ + {0, 1, 7}, /* map_modsel[3] = MODSEL_QSFP28_N_P(X+3) */ + {1, 1, 4}, /* map_modsel[4] = MODSEL_QSFP28_N_P(X+4) */ + {1, 1, 5}, /* map_modsel[5] = MODSEL_QSFP28_N_P(X+5) */ + {1, 1, 6}, /* map_modsel[6] = MODSEL_QSFP28_N_P(X+6) */ + {1, 1, 7}, /* map_modsel[7] = MODSEL_QSFP28_N_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_hudson32iga_p01p08_p17p24 = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 0, 0}, /* map_present[0] = MODABS_QSFP(X) */ + {2, 0, 1}, /* map_present[1] = MODABS_QSFP(X+1) */ + {2, 0, 2}, /* map_present[2] = MODABS_QSFP(X+2) */ + {2, 0, 3}, /* map_present[3] = MODABS_QSFP(X+3) */ + {2, 0, 4}, /* map_present[4] = MODABS_QSFP(X+4) */ + {2, 0, 5}, /* map_present[5] = MODABS_QSFP(X+5) */ + {2, 0, 6}, /* map_present[6] = MODABS_QSFP(X+6) */ + {2, 0, 7}, /* map_present[7] = MODABS_QSFP(X+7) */ + }, + .map_reset = { {0, 0, 0}, /* map_reset[0] = QRESET_QSFP(X) */ + {0, 0, 1}, /* map_reset[1] = QRESET_QSFP(X+1) */ + {0, 0, 2}, /* map_reset[2] = QRESET_QSFP(X+2) */ + {0, 0, 3}, /* map_reset[3] = QRESET_QSFP(X+3) */ + {1, 0, 0}, /* map_reset[4] = QRESET_QSFP(X+4) */ + {1, 0, 1}, /* map_reset[5] = QRESET_QSFP(X+5) */ + {1, 0, 2}, /* map_reset[6] = QRESET_QSFP(X+6) */ + {1, 0, 3}, /* map_reset[7] = QRESET_QSFP(X+7) */ + }, + .map_lpmod = { {0, 0, 4}, /* map_lpmod[0] = LPMODE_QSFP(X) */ + {0, 0, 5}, /* map_lpmod[1] = LPMODE_QSFP(X+1) */ + {0, 0, 6}, /* map_lpmod[2] = LPMODE_QSFP(X+2) */ + {0, 0, 7}, /* map_lpmod[3] = LPMODE_QSFP(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP(X+5) */ + {1, 0, 6}, /* map_lpmod[6] = LPMODE_QSFP(X+6) */ + {1, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP(X+7) */ + }, + .map_modsel = { {0, 1, 4}, /* map_modsel[0] = MODSEL_QSFP(X) */ + {0, 1, 5}, /* map_modsel[1] = MODSEL_QSFP(X+1) */ + {0, 1, 6}, /* map_modsel[2] = MODSEL_QSFP(X+2) */ + {0, 1, 7}, /* map_modsel[3] = MODSEL_QSFP(X+3) */ + {1, 1, 4}, /* map_modsel[4] = MODSEL_QSFP(X+4) */ + {1, 1, 5}, /* map_modsel[5] = MODSEL_QSFP(X+5) */ + {1, 1, 6}, /* map_modsel[6] = MODSEL_QSFP(X+6) */ + {1, 1, 7}, /* map_modsel[7] = MODSEL_QSFP(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_hudson32iga_p09p16_p25p32 = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 1, 0}, /* map_present[0] = MODABS_QSFP(X) */ + {2, 1, 1}, /* map_present[1] = MODABS_QSFP(X+1) */ + {2, 1, 2}, /* map_present[2] = MODABS_QSFP(X+2) */ + {2, 1, 3}, /* map_present[3] = MODABS_QSFP(X+3) */ + {2, 1, 4}, /* map_present[4] = MODABS_QSFP(X+4) */ + {2, 1, 5}, /* map_present[5] = MODABS_QSFP(X+5) */ + {2, 1, 6}, /* map_present[6] = MODABS_QSFP(X+6) */ + {2, 1, 7}, /* map_present[7] = MODABS_QSFP(X+7) */ + }, + .map_reset = { {0, 0, 0}, /* map_reset[0] = QRESET_QSFP(X) */ + {0, 0, 1}, /* map_reset[1] = QRESET_QSFP(X+1) */ + {0, 0, 2}, /* map_reset[2] = QRESET_QSFP(X+2) */ + {0, 0, 3}, /* map_reset[3] = QRESET_QSFP(X+3) */ + {1, 0, 0}, /* map_reset[4] = QRESET_QSFP(X+4) */ + {1, 0, 1}, /* map_reset[5] = QRESET_QSFP(X+5) */ + {1, 0, 2}, /* map_reset[6] = QRESET_QSFP(X+6) */ + {1, 0, 3}, /* map_reset[7] = QRESET_QSFP(X+7) */ + }, + .map_lpmod = { {0, 0, 4}, /* map_lpmod[0] = LPMODE_QSFP(X) */ + {0, 0, 5}, /* map_lpmod[1] = LPMODE_QSFP(X+1) */ + {0, 0, 6}, /* map_lpmod[2] = LPMODE_QSFP(X+2) */ + {0, 0, 7}, /* map_lpmod[3] = LPMODE_QSFP(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP(X+5) */ + {1, 0, 6}, /* map_lpmod[6] = LPMODE_QSFP(X+6) */ + {1, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP(X+7) */ + }, + .map_modsel = { {0, 1, 4}, /* map_modsel[0] = MODSEL_QSFP(X) */ + {0, 1, 5}, /* map_modsel[1] = MODSEL_QSFP(X+1) */ + {0, 1, 6}, /* map_modsel[2] = MODSEL_QSFP(X+2) */ + {0, 1, 7}, /* map_modsel[3] = MODSEL_QSFP(X+3) */ + {1, 1, 4}, /* map_modsel[4] = MODSEL_QSFP(X+4) */ + {1, 1, 5}, /* map_modsel[5] = MODSEL_QSFP(X+5) */ + {1, 1, 6}, /* map_modsel[6] = MODSEL_QSFP(X+6) */ + {1, 1, 7}, /* map_modsel[7] = MODSEL_QSFP(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_cypress_nabc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 0, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 0, 7}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 0, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 0, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 1, 0}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 1, 1}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 1, 0}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 1, 1}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 0, 2}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 0, 3}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 0, 2}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 0, 3}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 1, 4}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 1, 5}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 1, 4}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 1, 5}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_cypress_7abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 0, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 0, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 0, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 0, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + }, + .map_reset = { {0, 0, 0}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 0, 1}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 0, 2}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + {0, 0, 3}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */ + {0, 0, 4}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */ + {0, 0, 5}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */ + }, + .map_lpmod = { {0, 1, 0}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {0, 1, 1}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {0, 1, 2}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + {0, 1, 3}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */ + {0, 1, 4}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */ + {0, 1, 5}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */ + }, + .map_modsel = { {1, 1, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {1, 1, 1}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {1, 1, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + {1, 1, 3}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */ + {1, 1, 4}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */ + {1, 1, 5}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */ + }, +}; + + +struct ioexp_map_s ioexp_map_tahoe_5a = { + + .chip_amount = 1, + .data_width = 2, + + .map_present = { {0, 0, 3}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 1, 0}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 5}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + }, + .map_reset = { {0, 0, 1}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 0, 6}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 1, 3}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + }, + .map_lpmod = { {0, 0, 2}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {0, 0, 7}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {0, 1, 4}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {0, 0, 5}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {0, 1, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + }, +}; + + +struct ioexp_map_s ioexp_map_tahoe_6abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 3}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 1, 0}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 5}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {1, 0, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 1, 0}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {2, 0, 3}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {2, 1, 0}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + {2, 1, 5}, /* map_present[8] = MOD_ABS_PORT(X+8) */ + }, + .map_reset = { {0, 0, 1}, /* map_reset[0] = QRESET_QSFP28_N_P(X) */ + {0, 0, 6}, /* map_reset[1] = QRESET_QSFP28_N_P(X+1) */ + {0, 1, 3}, /* map_reset[2] = QRESET_QSFP28_N_P(X+2) */ + {1, 0, 1}, /* map_reset[3] = QRESET_QSFP28_N_P(X+3) */ + {1, 0, 6}, /* map_reset[4] = QRESET_QSFP28_N_P(X+4) */ + {1, 1, 3}, /* map_reset[5] = QRESET_QSFP28_N_P(X+5) */ + {2, 0, 1}, /* map_reset[6] = QRESET_QSFP28_N_P(X+6) */ + {2, 0, 6}, /* map_reset[7] = QRESET_QSFP28_N_P(X+7) */ + {2, 1, 3}, /* map_reset[7] = QRESET_QSFP28_N_P(X+7) */ + }, + .map_lpmod = { {0, 0, 2}, /* map_lpmod[0] = LPMODE_QSFP28_P(X) */ + {0, 0, 7}, /* map_lpmod[1] = LPMODE_QSFP28_P(X+1) */ + {0, 1, 4}, /* map_lpmod[2] = LPMODE_QSFP28_P(X+2) */ + {1, 0, 2}, /* map_lpmod[3] = LPMODE_QSFP28_P(X+3) */ + {1, 0, 7}, /* map_lpmod[4] = LPMODE_QSFP28_P(X+4) */ + {1, 1, 4}, /* map_lpmod[5] = LPMODE_QSFP28_P(X+5) */ + {2, 0, 2}, /* map_lpmod[6] = LPMODE_QSFP28_P(X+6) */ + {2, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP28_P(X+7) */ + {2, 1, 4}, /* map_lpmod[7] = LPMODE_QSFP28_P(X+8) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP28_N_P(X) */ + {0, 0, 5}, /* map_modsel[1] = MODSEL_QSFP28_N_P(X+1) */ + {0, 1, 2}, /* map_modsel[2] = MODSEL_QSFP28_N_P(X+2) */ + {1, 0, 0}, /* map_modsel[3] = MODSEL_QSFP28_N_P(X+3) */ + {1, 0, 5}, /* map_modsel[4] = MODSEL_QSFP28_N_P(X+4) */ + {1, 1, 2}, /* map_modsel[5] = MODSEL_QSFP28_N_P(X+5) */ + {2, 0, 0}, /* map_modsel[6] = MODSEL_QSFP28_N_P(X+6) */ + {2, 0, 5}, /* map_modsel[7] = MODSEL_QSFP28_N_P(X+7) */ + {2, 1, 2}, /* map_modsel[7] = MODSEL_QSFP28_N_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_sequoia_nabc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 1, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 1, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {2, 1, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {2, 1, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_reset = { {0, 1, 0}, /* map_reset[0] = QRESET_QSFP28_N_P(X) */ + {0, 1, 1}, /* map_reset[1] = QRESET_QSFP28_N_P(X+1) */ + {0, 1, 2}, /* map_reset[2] = QRESET_QSFP28_N_P(X+2) */ + {0, 1, 3}, /* map_reset[3] = QRESET_QSFP28_N_P(X+3) */ + {0, 1, 4}, /* map_reset[4] = QRESET_QSFP28_N_P(X+4) */ + {0, 1, 5}, /* map_reset[5] = QRESET_QSFP28_N_P(X+5) */ + {0, 1, 6}, /* map_reset[6] = QRESET_QSFP28_N_P(X+6) */ + {0, 1, 7}, /* map_reset[7] = QRESET_QSFP28_N_P(X+7) */ + }, + .map_lpmod = { {1, 0, 0}, /* map_lpmod[0] = LPMODE_QSFP28_P(X) */ + {1, 0, 1}, /* map_lpmod[1] = LPMODE_QSFP28_P(X+1) */ + {1, 0, 2}, /* map_lpmod[2] = LPMODE_QSFP28_P(X+2) */ + {1, 0, 3}, /* map_lpmod[3] = LPMODE_QSFP28_P(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP28_P(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP28_P(X+5) */ + {1, 0, 6}, /* map_lpmod[6] = LPMODE_QSFP28_P(X+6) */ + {1, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP28_P(X+7) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP28_N_P(X) */ + {0, 0, 1}, /* map_modsel[1] = MODSEL_QSFP28_N_P(X+1) */ + {0, 0, 2}, /* map_modsel[2] = MODSEL_QSFP28_N_P(X+2) */ + {0, 0, 3}, /* map_modsel[3] = MODSEL_QSFP28_N_P(X+3) */ + {0, 0, 4}, /* map_modsel[4] = MODSEL_QSFP28_N_P(X+4) */ + {0, 0, 5}, /* map_modsel[5] = MODSEL_QSFP28_N_P(X+5) */ + {0, 0, 6}, /* map_modsel[6] = MODSEL_QSFP28_N_P(X+6) */ + {0, 0, 7}, /* map_modsel[7] = MODSEL_QSFP28_N_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_lavender_p65 = { + + .chip_amount = 1, + .data_width = 1, + + .map_present = { {0, 0, 4}, }, /* map_present[0] = MOD_ABS_PORT(X) */ + .map_reset = { {0, 0, 1}, }, /* map_reset[0] = QRESET_QSFP28_N_P(X) */ + .map_lpmod = { {0, 0, 2}, }, /* map_lpmod[0] = LPMODE_QSFP28_P(X) */ + .map_modsel = { {0, 0, 0}, }, /* map_modsel[0] = MODSEL_QSFP28_N_P(X) */ +}; + + +struct ioexp_map_s cpld_map_cottonwood = { + + .chip_amount = 1, + .data_width = 4, + + .map_present = { {0, 2, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 2, 4}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 3, 0}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 3, 4}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + }, + .map_tx_disable = { {0, 0, 0}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 0, 4}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 0}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 4}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + }, + .map_tx_fault = { {0, 2, 2}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 2, 6}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 3, 2}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 3, 6}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + }, + .map_rxlos = { {0, 2, 1}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 2, 5}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 3, 1}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 3, 5}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + }, + .map_hard_rs0 = { {0, 0, 2}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {0, 0, 6}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {0, 1, 2}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {0, 1, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + }, + .map_hard_rs1 = { {0, 0, 2}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {0, 0, 6}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {0, 1, 2}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {0, 1, 6}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + }, +}; + + +struct ioexp_map_s ioexp_map_maple_0abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 1, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 1, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {2, 1, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {2, 1, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_reset = { {0, 1, 0}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 1, 1}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 1, 2}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + {0, 1, 3}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */ + {0, 1, 4}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */ + {0, 1, 5}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */ + {0, 1, 6}, /* map_reset[6] = QRESET_QSFP_N_P(X+6) */ + {0, 1, 7}, /* map_reset[7] = QRESET_QSFP_N_P(X+7) */ + }, + .map_lpmod = { {1, 0, 0}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {1, 0, 1}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {1, 0, 2}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + {1, 0, 3}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */ + {1, 0, 6}, /* map_lpmod[6] = LPMODE_QSFP_P(X+6) */ + {1, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP_P(X+7) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {0, 0, 1}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {0, 0, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + {0, 0, 3}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */ + {0, 0, 4}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */ + {0, 0, 5}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */ + {0, 0, 6}, /* map_modsel[6] = MODSEL_QSFP_N_P(X+6) */ + {0, 0, 7}, /* map_modsel[7] = MODSEL_QSFP_N_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_maple_nabc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 0, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 0, 7}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 0, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 0, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 1, 0}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 1, 1}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 1, 0}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 1, 1}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 0, 2}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 0, 3}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 0, 2}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 0, 3}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 1, 4}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 1, 5}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 1, 4}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 1, 5}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_gulmohar_nabc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 4}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 1, 5}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 1, 4}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 1, 5}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 0, 2}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 0, 3}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 0, 2}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 0, 3}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 1, 1}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 1, 1}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 0, 6}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 0, 6}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_gulmohar_7abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 1, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 1, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + }, + .map_reset = { {0, 1, 0}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 1, 1}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 1, 2}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + {0, 1, 3}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */ + {0, 1, 4}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */ + {0, 1, 5}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */ + }, + .map_lpmod = { {1, 0, 0}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {1, 0, 1}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {1, 0, 2}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + {1, 0, 3}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {0, 0, 1}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {0, 0, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + {0, 0, 3}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */ + {0, 0, 4}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */ + {0, 0, 5}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */ + }, +}; + + +struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_nabc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 2}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 6}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 1, 6}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 2}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 6}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 1, 2}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 1, 6}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 0, 1}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 0, 5}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 1}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 5}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 0, 1}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 0, 5}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 1}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 5}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 4}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 1, 4}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 4}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 1, 4}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 0, 3}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 3}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 0, 3}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 3}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_1abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 2}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 6}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 1, 6}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 1, 4}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 1, 5}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 0, 1}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 0, 5}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 1}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 5}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 0, 2}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 0, 3}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 4}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 1, 4}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 1, 1}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 0, 3}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 3}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 0, 6}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_3abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 4}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 1, 5}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 2}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 6}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 1, 2}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 1, 6}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 0, 2}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 0, 3}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 0, 1}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 0, 5}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 1}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 5}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 1, 1}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 4}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 1, 4}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 0, 6}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 0, 3}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 3}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + + +struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_7abc = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 1, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {1, 0, 4}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 1, 1}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 1, 6}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {2, 0, 4}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {2, 1, 1}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_reset = { {0, 0, 1}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 0, 6}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 1, 3}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + {1, 0, 1}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */ + {1, 0, 6}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */ + {1, 1, 3}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */ + {2, 0, 1}, /* map_reset[6] = QRESET_QSFP_N_P(X+6) */ + {2, 0, 6}, /* map_reset[7] = QRESET_QSFP_N_P(X+7) */ + }, + .map_lpmod = { {0, 0, 2}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {0, 0, 7}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {0, 1, 4}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + {1, 0, 2}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */ + {1, 0, 7}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */ + {1, 1, 4}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */ + {2, 0, 2}, /* map_lpmod[6] = LPMODE_QSFP_P(X+6) */ + {2, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP_P(X+7) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {0, 0, 5}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {0, 1, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + {1, 0, 0}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */ + {1, 0, 5}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */ + {1, 1, 2}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */ + {2, 0, 0}, /* map_modsel[6] = MODSEL_QSFP_N_P(X+6) */ + {2, 0, 5}, /* map_modsel[7] = MODSEL_QSFP_N_P(X+7) */ + }, +}; + + +/* PortType: SFP / 8 port + * Platform: Cypress, Peony_SFP + */ +struct ioexp_map_s ioexp_map_sfp_8p_layout_1 = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */ + {0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {0, 0, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {0, 0, 7}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + {1, 0, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */ + {1, 0, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */ + }, + .map_tx_disable = { {0, 1, 0}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */ + {0, 1, 1}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */ + {0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */ + {0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */ + {1, 1, 0}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */ + {1, 1, 1}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */ + {1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */ + {1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */ + }, + .map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */ + {0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */ + {0, 0, 2}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */ + {0, 0, 3}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */ + {1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */ + {1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */ + {1, 0, 2}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */ + {1, 0, 3}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */ + }, + .map_rxlos = { {0, 1, 4}, /* map_rxlos[0] = OPRXLOS_PORT(X) */ + {0, 1, 5}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */ + {0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */ + {0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */ + {1, 1, 4}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */ + {1, 1, 5}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */ + {1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */ + {1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */ + }, + .map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */ + {2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */ + {2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */ + {2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */ + {2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */ + {2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */ + {2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */ + {2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */ + }, + .map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */ + {2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */ + {2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */ + {2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */ + {2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */ + {2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */ + {2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */ + {2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */ + }, +}; + + +/* PortType: QSFP / 6 port + * Platform: Gulmohar, Peony_SFP, Peony_Copper + */ +struct ioexp_map_s ioexp_map_6p_qsfp_type_1 = { + + .chip_amount = 3, + .data_width = 2, + + .map_present = { {2, 1, 0}, /* map_present[0] = MOD_ABS_PORT(X) */ + {2, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */ + {2, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */ + {2, 1, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */ + {2, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */ + {2, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */ + }, + .map_reset = { {0, 1, 0}, /* map_reset[0] = QRESET_QSFP_N_P(X) */ + {0, 1, 1}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */ + {0, 1, 2}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */ + {0, 1, 3}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */ + {0, 1, 4}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */ + {0, 1, 5}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */ + }, + .map_lpmod = { {1, 0, 0}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */ + {1, 0, 1}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */ + {1, 0, 2}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */ + {1, 0, 3}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */ + {1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */ + {1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */ + }, + .map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */ + {0, 0, 1}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */ + {0, 0, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */ + {0, 0, 3}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */ + {0, 0, 4}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */ + {0, 0, 5}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */ + }, +}; + + +/* ========== Private functions ========== + */ +int check_channel_tier_1(void); + +struct i2c_client * +_get_i2c_client(struct ioexp_obj_s *self, + int chip_id){ + + struct ioexp_i2c_s *i2c_curr_p = self->i2c_head_p; + + if (!(i2c_curr_p)){ + SWPS_ERR("%s: i2c_curr_p is NULL\n", __func__); + return NULL; + } + while (i2c_curr_p){ + if ((i2c_curr_p->chip_id) == chip_id){ + return i2c_curr_p->i2c_client_p; + } + i2c_curr_p = i2c_curr_p->next; + } + SWPS_ERR("%s: not exist! :%d\n", __func__, chip_id); + return NULL; +} + + +static int +_common_ioexp_update_one(struct ioexp_obj_s *self, + struct ioexp_addr_s *ioexp_addr, + int chip_id, + int data_width, + int show_err, + char *caller_name) { + int buf = 0; + int err = 0; + int data_id = 0; + int r_offset = 0; + + for(data_id=0; data_idread_offset[data_id]; + buf = i2c_smbus_read_byte_data(_get_i2c_client(self, chip_id), r_offset); + /* Check error */ + if (buf < 0) { + err = 1; + if (show_err) { + SWPS_INFO("IOEXP-%d read fail! :%d \n", self->ioexp_id, buf); + SWPS_INFO("Dump: :%d :0x%02x :%d, :%s\n", + ioexp_addr->chan_id, ioexp_addr->chip_addr, + ioexp_addr->read_offset[data_id], caller_name); + } + continue; + } + /* Update IOEXP object */ + self->chip_data[chip_id].data[data_id] = (uint8_t)buf; + } + if (err) { + return ERR_IOEXP_UNEXCPT; + } + return 0; +} + + +static int +common_ioexp_update_all(struct ioexp_obj_s *self, + int show_err, + char *caller_name){ + + int err = 0; + int chip_id = 0; + int chip_amount = self->ioexp_map_p->chip_amount; + + for (chip_id=0; chip_idioexp_map_p->map_addr[chip_id]), + chip_id, + self->ioexp_map_p->data_width, + show_err, + caller_name) < 0) { + err = 1; + } + } + if (err) { + return ERR_IOEXP_UNEXCPT; + } + return 0; +} + + +static int +_common_check_by_mode(struct ioexp_obj_s *self){ + + switch (self->mode){ + case IOEXP_MODE_DIRECT: + return self->fsm_4_direct(self); + + case IOEXP_MODE_POLLING: + if (self->state >= 0){ + return 0; + } + switch (self->state){ + case STATE_IOEXP_INIT: + return ERR_IOEXP_UNINIT; + case STATE_IOEXP_ABNORMAL: + return ERR_IOEXP_ABNORMAL; + default: + return ERR_IOEXP_NOSTATE; + } + break; + + default: + break; + } + SWPS_ERR("%s: Exception occurs. :%d \n", __func__, self->mode); + return ERR_IOEXP_UNEXCPT; +} + + +static int +_common_get_bit(struct ioexp_obj_s *self, + struct ioexp_bitmap_s *bitmap_obj_p, + char *func_mane){ + uint8_t buf; + int err_code; + + /* Check and get address */ + err_code = _common_check_by_mode(self); + if (err_code < 0){ + return err_code; + } + if (!bitmap_obj_p){ + SWPS_ERR("Layout config incorrect! :%d :%s\n", + self->ioexp_id, func_mane); + return ERR_IOEXP_BADCONF; + } + /* Get data form cache */ + buf = self->chip_data[bitmap_obj_p->chip_id].data[bitmap_obj_p->ioexp_voffset]; + return (int)(buf >> bitmap_obj_p->bit_shift & 0x01); +} + + +static int +_common_set_bit(struct ioexp_obj_s *self, + struct ioexp_bitmap_s *bitmap_obj_p, + int input_val, + char *func_mane){ + int err_code, target_offset; + uint8_t origin_byte; + uint8_t modify_byte; + + /* Check and get address */ + err_code = _common_check_by_mode(self); + if (err_code < 0){ + return err_code; + } + if (!bitmap_obj_p){ + SWPS_ERR("Layout config incorrect! :%d :%s\n", + self->ioexp_id, func_mane); + return ERR_IOEXP_BADCONF; + } + /* Prepare write date */ + origin_byte = self->chip_data[bitmap_obj_p->chip_id].data[bitmap_obj_p->ioexp_voffset]; + switch (input_val) { + case 0: + modify_byte = origin_byte; + SWP_BIT_CLEAR(modify_byte, bitmap_obj_p->bit_shift); + break; + case 1: + modify_byte = origin_byte; + SWP_BIT_SET(modify_byte, bitmap_obj_p->bit_shift); + break; + default: + SWPS_ERR("Input value incorrect! :%d :%d :%s\n", + input_val, self->ioexp_id, func_mane); + return ERR_IOEXP_BADINPUT; + } + /* Setup i2c client */ + target_offset = self->ioexp_map_p->map_addr[bitmap_obj_p->chip_id].write_offset[bitmap_obj_p->ioexp_voffset]; + /* Write byte to chip via I2C */ + err_code = i2c_smbus_write_byte_data(_get_i2c_client(self, bitmap_obj_p->chip_id), + target_offset, + modify_byte); + /* Update or bollback object */ + if (err_code < 0){ + self->chip_data[bitmap_obj_p->chip_id].data[bitmap_obj_p->ioexp_voffset] = origin_byte; + SWPS_ERR("I2C write fail! :%d :%d :%s :%d\n", + input_val, self->ioexp_id, func_mane, err_code); + return err_code; + } + self->chip_data[bitmap_obj_p->chip_id].data[bitmap_obj_p->ioexp_voffset] = modify_byte; + return 0; +} + + +/* ========== Object public functions ========== + */ +int +common_get_present(struct ioexp_obj_s *self, + int virt_offset){ + + int UNPLUG = 1; + int retval = ERR_IOEXP_UNEXCPT; + + retval = _common_get_bit(self, + &(self->ioexp_map_p->map_present[virt_offset]), + "common_get_present"); + if (retval < 0) { + /* [Note] + * => Transceiver object does not need to handle IOEXP layer issues. + */ + return UNPLUG; + } + return retval; +} + + +int +common_get_tx_fault(struct ioexp_obj_s *self, + int virt_offset){ + /* [Transmit Fault (Tx_Fault)] + * A catastrophic laser fault will activate the transmitter signal, + * TX_FAULT, and disable the laser. This signal is an open collector + * output (pull-up required on the host board). A low signal indicates + * normal laser operation and a high signal indicates a fault. The + * TX_FAULT will be latched high when a laser fault occurs and is + * cleared by toggling the TX_DISABLE input or power cycling the + * transceiver. The transmitter fault condition can also be monitored + * via the two-wire serial interface. + * (address A2, byte 110, bit 2). + * + * 0: Normal + * 1: Abnormal + */ + return _common_get_bit(self, + &(self->ioexp_map_p->map_tx_fault[virt_offset]), + "common_get_tx_fault"); +} + + +int +common_get_rxlos(struct ioexp_obj_s *self, + int virt_offset){ + /* [Receiver Loss of Signal (Rx_LOS)] + * The post-amplification IC also includes transition detection circuitry + * which monitors the ac level of incoming optical signals and provides a + * TTL/CMOS compatible status signal to the host (pin 8). An adequate optical + * input results in a low Rx_LOS output while a high Rx_LOS output indicates + * an unusable optical input. The Rx_LOS thresholds are factory set so that + * a high output indicates a definite optical fault has occurred. Rx_LOS can + * also be monitored via the two-wire serial interface + * (address A2h, byte 110, bit 1). + * + * 0: Normal + * 1: Abnormal + */ + return _common_get_bit(self, + &(self->ioexp_map_p->map_rxlos[virt_offset]), + "common_get_rxlos"); +} + + +int +common_get_tx_disable(struct ioexp_obj_s *self, + int virt_offset){ + + return _common_get_bit(self, + &(self->ioexp_map_p->map_tx_disable[virt_offset]), + "common_get_tx_disable"); +} + + +int +common_get_reset(struct ioexp_obj_s *self, + int virt_offset){ + + return _common_get_bit(self, + &(self->ioexp_map_p->map_reset[virt_offset]), + "common_get_reset"); +} + + +int +common_get_lpmod(struct ioexp_obj_s *self, + int virt_offset){ + + return _common_get_bit(self, + &(self->ioexp_map_p->map_lpmod[virt_offset]), + "common_get_lpmod"); +} + + +int +common_get_modsel(struct ioexp_obj_s *self, + int virt_offset){ + + return _common_get_bit(self, + &(self->ioexp_map_p->map_modsel[virt_offset]), + "common_get_modsel"); +} + + +int +common_get_hard_rs0(struct ioexp_obj_s *self, + int virt_offset){ + + return _common_get_bit(self, + &(self->ioexp_map_p->map_hard_rs0[virt_offset]), + "common_get_hard_rs0"); +} + + +int +common_get_hard_rs1(struct ioexp_obj_s *self, + int virt_offset){ + + return _common_get_bit(self, + &(self->ioexp_map_p->map_hard_rs1[virt_offset]), + "common_get_hard_rs1"); +} + + +int +common_set_tx_disable(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + + return _common_set_bit(self, + &(self->ioexp_map_p->map_tx_disable[virt_offset]), + input_val, + "common_set_tx_disable"); +} + + +int +common_set_reset(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + + return _common_set_bit(self, + &(self->ioexp_map_p->map_reset[virt_offset]), + input_val, + "common_set_reset"); +} + + +int +common_set_lpmod(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + + return _common_set_bit(self, + &(self->ioexp_map_p->map_lpmod[virt_offset]), + input_val, + "common_set_lpmod"); +} + + +int +common_set_modsel(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + + return _common_set_bit(self, + &(self->ioexp_map_p->map_modsel[virt_offset]), + input_val, + "common_set_modsel"); +} + + +int +common_set_hard_rs0(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + + return _common_set_bit(self, + &(self->ioexp_map_p->map_hard_rs0[virt_offset]), + input_val, + "common_set_hard_rs0"); +} + + +int +common_set_hard_rs1(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + + return _common_set_bit(self, + &(self->ioexp_map_p->map_hard_rs1[virt_offset]), + input_val, + "common_set_hard_rs1"); +} + + +int +ioexp_get_not_support(struct ioexp_obj_s *self, + int virt_offset){ + return ERR_IOEXP_NOTSUPPORT; +} + + +int +ioexp_set_not_support(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + return ERR_IOEXP_NOTSUPPORT; +} + + +int +fake_ioexp_init(struct ioexp_obj_s *self){ + return 1; +} + +int +fake_ioexp_update(struct ioexp_obj_s *self){ + return 1; +} + + +int +fake_update_func(struct ioexp_obj_s *self){ + return 1; +} + +int +fake_get_func(struct ioexp_obj_s *self, + int virt_offset){ + SWPS_WARN("Someone called fake_get_func\n"); + return -1; +} + +int +fake_set_func(struct ioexp_obj_s *self, + int virt_offset, + int input_val){ + SWPS_WARN("Someone called fake_set_func\n"); + return -1; +} + + +/* ========== Initial functions for IO Expander ========== + */ +int +common_ioexp_init(struct ioexp_obj_s *self) { + + int chip_id, offset, err_code; + struct ioexp_addr_s *addr_p; + + if (self->mode == IOEXP_MODE_DIRECT) { + goto update_common_ioexp_init; + } + if (!io_no_init) { /*normal init*/ + + /* Setup default value to each physical IO Expander */ + for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++){ + /* Get address mapping */ + addr_p = &(self->ioexp_map_p->map_addr[chip_id]); + if (!addr_p){ + SWPS_ERR("%s: IOEXP config incorrect! :%d \n", + __func__, chip_id); + return -1; + } + /* Setup default value */ + for (offset=0; offset<(self->ioexp_map_p->data_width); offset++){ + + /* [Desc] Skip the setup default value behavior + [Note] Setup default value = -1 if you don't want to write the value to IOEXP or CPLD + */ + if(addr_p->write_offset[offset] < 0){ + SWPS_DEBUG("skip a write_offset <%d>\n", addr_p->conf_offset[offset]); + continue; + } + err_code = i2c_smbus_write_byte_data(_get_i2c_client(self, chip_id), + addr_p->write_offset[offset], + addr_p->data_default[offset]); + if (err_code < 0){ + SWPS_ERR("%s: set default fail! :%d \n", + __func__, err_code); + return ERR_IOEXP_UNEXCPT; + } + } + } + } +update_common_ioexp_init: + /* Check and update info to object */ + err_code = self->update_all(self, 1, "common_ioexp_init"); + if (err_code < 0) { + SWPS_ERR("%s: update_all() fail! :%d \n", + __func__, err_code); + return ERR_IOEXP_UNEXCPT; + } + return 0; +} + + +/* ========== Object functions for Final State Machine ========== + */ +int +_is_channel_ready(struct ioexp_obj_s *self){ + + int chip_id = 0; + int byte_id = 0; + int getval = ERR_IOEXP_UNEXCPT; + int chkval = ERR_IOEXP_UNEXCPT; + char *emsg = "ERR"; + struct ioexp_addr_s *addr_p = NULL; + + for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++) { + addr_p = &(self->ioexp_map_p->map_addr[chip_id]); + if (!addr_p){ + emsg = "IOEXP config incorrect"; + goto err_is_channel_ready; + } + for (byte_id=0; byte_id<(self->ioexp_map_p->data_width); byte_id++) { + if (addr_p->conf_offset[byte_id] < 0) { + continue; + } + if ((addr_p->conf_default[byte_id]) != 0) { + goto go_is_channel_ready; + } + } + if (chip_id == ((self->ioexp_map_p->chip_amount) - 1)) { + SWPS_DEBUG("%s: no non-zero config", __func__); + break; + } + } + chip_id = 0; + byte_id = 0; + +go_is_channel_ready: + addr_p = &(self->ioexp_map_p->map_addr[chip_id]); + chkval = addr_p->conf_default[byte_id]; + getval = i2c_smbus_read_byte_data(_get_i2c_client(self, chip_id), + addr_p->conf_offset[byte_id]); + + SWPS_DEBUG("%s: target info :%d :%d :%d :%d :%d\n", + __func__, self->ioexp_id, chip_id, byte_id, chkval, getval); + + if ((getval >= 0) && (getval == chkval)) { + return 1; + } + return 0; + +err_is_channel_ready: + SWPS_ERR("%s: %s :%d :%d :%d :%d :%d\n", + __func__, emsg, self->ioexp_id, chip_id, byte_id, chkval, getval); + return ERR_IOEXP_UNEXCPT; +} + + +int +_ioexp_init_handler(struct ioexp_obj_s *self){ + + int return_val; + + switch (self->mode) { + case IOEXP_MODE_DIRECT: + return_val = self->init(self); + if (return_val < 0){ + self->state = STATE_IOEXP_ABNORMAL; + } else { + self->state = STATE_IOEXP_NORMAL; + } + return return_val; + + case IOEXP_MODE_POLLING: + /* Check system and channel is ready */ + if (self->state == STATE_IOEXP_INIT){ + if (!_is_channel_ready(self)){ + self->state = STATE_IOEXP_INIT; + SWPS_WARN("%s: IOEXP:%d channel not ready.\n", + __func__, self->ioexp_id); + return 0; + } + } + /* Execute initial callback */ + return_val = self->init(self); + if (return_val < 0){ + self->state = STATE_IOEXP_ABNORMAL; + } else { + self->state = STATE_IOEXP_NORMAL; + } + return return_val; + + default: + break; + } + SWPS_ERR("%s: exception occur :%d\n", __func__, self->mode); + return ERR_IOEXP_UNEXCPT; +} + + +int +common_ioexp_fsm_4_direct(struct ioexp_obj_s *self){ + + int result_val; + int show_err = 1; + char *func_mane = "common_ioexp_fsm_4_direct"; + + switch (self->state){ + case STATE_IOEXP_INIT: + result_val = _ioexp_init_handler(self); + /* Exception case: terminate initial procedure */ + if(result_val < 0){ + /* Initial fail */ + return result_val; + } + if(self->state == STATE_IOEXP_INIT){ + /* Keep in INIT state, and return error */ + return ERR_IOEXP_UNINIT; + } + /* Case: Initial done */ + return 0; + + case STATE_IOEXP_NORMAL: + result_val = self->update_all(self, show_err, func_mane); + if (result_val < 0){ + SWPS_INFO("%s: NORMAL -> ABNORMAL :%d\n", + __func__, result_val); + self->state = STATE_IOEXP_ABNORMAL; + return result_val; + } + self->state = STATE_IOEXP_NORMAL; + return 0; + + case STATE_IOEXP_ABNORMAL: + result_val = self->update_all(self, show_err, func_mane); + if (result_val < 0){ + self->state = STATE_IOEXP_ABNORMAL; + return result_val; + } + SWPS_DEBUG("%s: ABNORMAL -> NORMAL :%d\n", + __func__, result_val); + self->state = STATE_IOEXP_NORMAL; + return 0; + + default: + break; + } + SWPS_ERR("%s: Exception occurs :%d\n", + __func__, self->state); + return ERR_IOEXP_UNEXCPT; +} + + +int +common_ioexp_fsm_4_polling(struct ioexp_obj_s *self){ + + int result_val, i, show_e; + int fail_retry = 3; + char *func_name = "common_ioexp_fsm_4_polling"; + +#ifdef DEBUG_SWPS + show_e = 1; +#else + show_e = 0; +#endif + + switch (self->state){ + case STATE_IOEXP_INIT: + result_val = _ioexp_init_handler(self); + /* Exception case: terminate initial procedure */ + if(result_val < 0){ + /* Initial fail */ + return result_val; + } + /* Case: System (Channel) not ready */ + if(self->state == STATE_IOEXP_INIT){ + /* Keep in INIT state, wait and retry */ + return 0; + } + /* Case: Initial done */ + SWPS_INFO("IOEXP-%d: initial done. :%d\n", + self->ioexp_id, self->ioexp_type); + return result_val; + + case STATE_IOEXP_NORMAL: + /* Retry mechanism for case of i2c topology not stable */ + for (i=0; iupdate_all(self, show_e, func_name); + if (result_val >= 0) { + self->state = STATE_IOEXP_NORMAL; + return 0; + } + if (check_channel_tier_1() < 0) { + SWPS_INFO("%s: detect I2C crash :%d\n", + __func__, self->ioexp_id); + break; + } + SWPS_DEBUG("IOEXP-%d: unstable :%d\n", + self->ioexp_id, result_val); + } + SWPS_INFO("IOEXP-%d: NORMAL -> ABNORMAL :%d\n", + self->ioexp_id, result_val); + self->state = STATE_IOEXP_ABNORMAL; + return result_val; + + case STATE_IOEXP_ABNORMAL: + result_val = self->update_all(self, show_e, func_name); + if (result_val < 0){ + self->state = STATE_IOEXP_ABNORMAL; + return result_val; + } + SWPS_INFO("IOEXP-%d: ABNORMAL -> NORMAL :%d\n", + self->ioexp_id, result_val); + self->state = STATE_IOEXP_NORMAL; + return 0; + + default: + break; + } + SWPS_ERR("IOEXP-%d: Exception occurs :%d\n", + self->ioexp_id, self->state); + return ERR_IOEXP_UNEXCPT; +} + + +/* ========== Object private functions for check & update ========== + */ +int +common_ioexp_check(struct ioexp_obj_s *self){ + + int result; + + if (self->mode != IOEXP_MODE_POLLING){ + SWPS_ERR("%s: not polling mode :%d\n", + __func__, self->mode); + return ERR_IOEXP_NOTSUPPORT; + } + mutex_lock(&self->lock); + result = self->fsm_4_polling(self); + mutex_unlock(&self->lock); + return result; +} + + +/* ========== Functions for Factory pattern ========== + */ +static struct ioexp_map_s * +get_ioexp_map(int ioexp_type){ + switch (ioexp_type){ + case IOEXP_TYPE_MAGINOLIA_NAB: + return &ioexp_map_magnolia_nab; + case IOEXP_TYPE_MAGINOLIA_4AB: + return &ioexp_map_magnolia_4ab; + case IOEXP_TYPE_MAGINOLIA_7AB: + case IOEXP_TYPE_SPRUCE_7AB: + return &ioexp_map_magnolia_7ab; + case IOEXP_TYPE_REDWOOD_P01P08: + return &ioexp_map_redwood_p01p08_p17p24; + case IOEXP_TYPE_REDWOOD_P09P16: + return &ioexp_map_redwood_p09p16_p25p32; + case IOEXP_TYPE_HUDSON32IGA_P01P08: + return &ioexp_map_hudson32iga_p01p08_p17p24; + case IOEXP_TYPE_HUDSON32IGA_P09P16: + return &ioexp_map_hudson32iga_p09p16_p25p32; + case IOEXP_TYPE_CYPRESS_7ABC: + return &ioexp_map_cypress_7abc; + case IOEXP_TYPE_TAHOE_5A: + return &ioexp_map_tahoe_5a; + case IOEXP_TYPE_TAHOE_6ABC: + return &ioexp_map_tahoe_6abc; + case IOEXP_TYPE_SEQUOIA_NABC: + return &ioexp_map_sequoia_nabc; + case IOEXP_TYPE_LAVENDER_P65: + return &ioexp_map_lavender_p65; + case CPLD_TYPE_COTTONWOOD: + return &cpld_map_cottonwood; + case IOEXP_TYPE_MAPLE_0ABC: + return &ioexp_map_maple_0abc; + case IOEXP_TYPE_MAPLE_NABC: + return &ioexp_map_maple_nabc; + case IOEXP_TYPE_GULMOHAR_NABC: + return &ioexp_map_gulmohar_nabc; + case IOEXP_TYPE_GULMOHAR_7ABC: + return &ioexp_map_gulmohar_7abc; + case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC: + return &ioexp_map_gulmohar_2t_evt1_nabc; + case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC: + return &ioexp_map_gulmohar_2t_evt1_1abc; + case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC: + return &ioexp_map_gulmohar_2t_evt1_3abc; + case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC: + return &ioexp_map_gulmohar_2t_evt1_7abc; + case IOEXP_TYPE_SFP_8P_LAYOUT_1: + return &ioexp_map_sfp_8p_layout_1; + case IOEXP_TYPE_QSFP_6P_LAYOUT_1: + return &ioexp_map_6p_qsfp_type_1; + default: + return NULL; + } +} + + +int +setup_ioexp_ssize_attr(struct ioexp_obj_s *self, + struct ioexp_map_s *ioexp_map_p, + int ioexp_id, + int ioexp_type, + int run_mode){ + switch (run_mode){ + case IOEXP_MODE_POLLING: /* Direct access device mode */ + case IOEXP_MODE_DIRECT: /* Polling mode, read from cache */ + self->mode = run_mode; + break; + default: + SWPS_ERR("%s: non-defined run_mode:%d\n", + __func__, run_mode); + self->mode = ERR_IOEXP_UNEXCPT; + return ERR_IOEXP_UNEXCPT; + } + /* Setup mapping structure */ + self->ioexp_map_p = kzalloc(sizeof(*ioexp_map_p), GFP_KERNEL); + if (!(self->ioexp_map_p)) { + SWPS_ERR("%s: kzalloc ioexp_map_p fail\n", __func__); + return -1; + } + memcpy(self->ioexp_map_p, ioexp_map_p, sizeof(*ioexp_map_p)); + /* Setup attributes */ + self->ioexp_id = ioexp_id; + self->ioexp_type = ioexp_type; + self->state = STATE_IOEXP_INIT; + mutex_init(&self->lock); + return 0; +} + + +static int +setup_addr_mapping(struct ioexp_obj_s *self, + struct ioexp_addr_s *addr_map_p, + int chip_amount){ + struct ioexp_addr_s *tmp_p; + if (!addr_map_p){ + SWPS_ERR("%s: map is null\n", __func__); + return -1; + } + tmp_p = kzalloc((sizeof(*addr_map_p) * chip_amount), GFP_KERNEL); + if (!tmp_p){ + SWPS_ERR("%s: kzalloc fail.\n", __func__); + return -1; + } + memcpy(tmp_p, addr_map_p, (sizeof(*addr_map_p) * chip_amount)); + self->ioexp_map_p->map_addr = tmp_p; + + return 0; +} + + +static int +setup_ioexp_public_cb(struct ioexp_obj_s *self, + int ioexp_type){ + + switch (ioexp_type){ + case IOEXP_TYPE_MAGINOLIA_NAB: + case IOEXP_TYPE_MAGINOLIA_4AB: + case CPLD_TYPE_COTTONWOOD: + self->get_present = common_get_present; + self->get_tx_fault = common_get_tx_fault; + self->get_rxlos = common_get_rxlos; + self->get_tx_disable = common_get_tx_disable; + self->get_reset = ioexp_get_not_support; + self->get_lpmod = ioexp_get_not_support; + self->get_modsel = ioexp_get_not_support; + self->get_hard_rs0 = ioexp_get_not_support; + self->get_hard_rs1 = ioexp_get_not_support; + self->set_tx_disable = common_set_tx_disable; + self->set_reset = ioexp_set_not_support; + self->set_lpmod = ioexp_set_not_support; + self->set_modsel = ioexp_set_not_support; + self->set_hard_rs0 = ioexp_set_not_support; + self->set_hard_rs1 = ioexp_set_not_support; + return 0; + + case IOEXP_TYPE_MAPLE_NABC: + case IOEXP_TYPE_GULMOHAR_NABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC: + case IOEXP_TYPE_SFP_8P_LAYOUT_1: + self->get_present = common_get_present; + self->get_tx_fault = common_get_tx_fault; + self->get_rxlos = common_get_rxlos; + self->get_tx_disable = common_get_tx_disable; + self->get_reset = ioexp_get_not_support; + self->get_lpmod = ioexp_get_not_support; + self->get_modsel = ioexp_get_not_support; + self->get_hard_rs0 = common_get_hard_rs0; + self->get_hard_rs1 = common_get_hard_rs1; + self->set_tx_disable = common_set_tx_disable; + self->set_reset = ioexp_set_not_support; + self->set_lpmod = ioexp_set_not_support; + self->set_modsel = ioexp_set_not_support; + self->set_hard_rs0 = common_set_hard_rs0; + self->set_hard_rs1 = common_set_hard_rs1; + return 0; + + case IOEXP_TYPE_MAGINOLIA_7AB: + case IOEXP_TYPE_SPRUCE_7AB: + case IOEXP_TYPE_REDWOOD_P01P08: + case IOEXP_TYPE_REDWOOD_P09P16: + case IOEXP_TYPE_HUDSON32IGA_P01P08: + case IOEXP_TYPE_HUDSON32IGA_P09P16: + case IOEXP_TYPE_CYPRESS_7ABC: + case IOEXP_TYPE_TAHOE_5A: + case IOEXP_TYPE_TAHOE_6ABC: + case IOEXP_TYPE_SEQUOIA_NABC: + case IOEXP_TYPE_LAVENDER_P65: + case IOEXP_TYPE_MAPLE_0ABC: + case IOEXP_TYPE_GULMOHAR_7ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC: + case IOEXP_TYPE_QSFP_6P_LAYOUT_1: + self->get_present = common_get_present; + self->get_tx_fault = ioexp_get_not_support; + self->get_rxlos = ioexp_get_not_support; + self->get_tx_disable = ioexp_get_not_support; + self->get_reset = common_get_reset; + self->get_lpmod = common_get_lpmod; + self->get_modsel = common_get_modsel; + self->get_hard_rs0 = ioexp_get_not_support; + self->get_hard_rs1 = ioexp_get_not_support; + self->set_tx_disable = ioexp_set_not_support; + self->set_reset = common_set_reset; + self->set_lpmod = common_set_lpmod; + self->set_modsel = common_set_modsel; + self->set_hard_rs0 = ioexp_set_not_support; + self->set_hard_rs1 = ioexp_set_not_support; + return 0; + + default: + SWPS_ERR("%s: type:%d incorrect!\n", __func__, ioexp_type); + break; + } + return ERR_IOEXP_UNEXCPT; +} + + +static int +setup_ioexp_private_cb(struct ioexp_obj_s *self, + int ioexp_type){ + + switch (ioexp_type){ + case IOEXP_TYPE_MAGINOLIA_NAB: + case IOEXP_TYPE_MAGINOLIA_4AB: + case IOEXP_TYPE_MAGINOLIA_7AB: + case IOEXP_TYPE_SPRUCE_7AB: + case IOEXP_TYPE_REDWOOD_P01P08: + case IOEXP_TYPE_REDWOOD_P09P16: + case IOEXP_TYPE_HUDSON32IGA_P01P08: + case IOEXP_TYPE_HUDSON32IGA_P09P16: + case IOEXP_TYPE_CYPRESS_7ABC: + case IOEXP_TYPE_TAHOE_5A: + case IOEXP_TYPE_TAHOE_6ABC: + case IOEXP_TYPE_SEQUOIA_NABC: + case IOEXP_TYPE_LAVENDER_P65: + case CPLD_TYPE_COTTONWOOD: + case IOEXP_TYPE_MAPLE_NABC: + case IOEXP_TYPE_MAPLE_0ABC: + case IOEXP_TYPE_GULMOHAR_NABC: + case IOEXP_TYPE_GULMOHAR_7ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC: + case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC: + case IOEXP_TYPE_SFP_8P_LAYOUT_1: + case IOEXP_TYPE_QSFP_6P_LAYOUT_1: + self->init = common_ioexp_init; + self->check = common_ioexp_check; + self->update_all = common_ioexp_update_all; + self->fsm_4_direct = common_ioexp_fsm_4_direct; + self->fsm_4_polling = common_ioexp_fsm_4_polling; + return 0; + + default: + SWPS_ERR("%s: type:%d incorrect!\n", __func__, ioexp_type); + break; + } + return ERR_IOEXP_UNEXCPT; +} + + +static int +setup_i2c_client_one(struct ioexp_obj_s *self, + int chip_id){ + + char *err_msg = "ERROR"; + struct i2c_adapter *adap = NULL; + struct i2c_client *client = NULL; + struct ioexp_i2c_s *i2c_obj_p = NULL; + struct ioexp_i2c_s *i2c_curr_p = NULL; + + int chan_id = self->ioexp_map_p->map_addr[chip_id].chan_id; + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (!client){ + err_msg = "Can not kzalloc client!"; + goto err_ioexp_setup_i2c_1; + } + i2c_obj_p = kzalloc(sizeof(*i2c_obj_p), GFP_KERNEL); + if (!i2c_obj_p){ + err_msg = "Can not kzalloc i2c_obj_p!"; + goto err_ioexp_setup_i2c_2; + } + adap = i2c_get_adapter(chan_id); + if(!adap){ + err_msg = "Can not get adap!"; + goto err_ioexp_setup_i2c_3; + } + client->adapter = adap; + client->addr = self->ioexp_map_p->map_addr[chip_id].chip_addr; + i2c_obj_p->i2c_client_p = client; + i2c_obj_p->chip_id = chip_id; + i2c_obj_p->next = NULL; + if (!self->i2c_head_p){ + self->i2c_head_p = i2c_obj_p; + } else { + i2c_curr_p = self->i2c_head_p; + while (i2c_curr_p->next){ + i2c_curr_p = i2c_curr_p->next; + } + i2c_curr_p->next = i2c_obj_p; + } + return 0; + +err_ioexp_setup_i2c_3: + kfree(i2c_obj_p); +err_ioexp_setup_i2c_2: + kfree(client); +err_ioexp_setup_i2c_1: + SWPS_ERR("%s: %s :%d\n", __func__, err_msg, chan_id); + return -1; +} + + +static int +setup_i2c_client(struct ioexp_obj_s* self){ + + int result; + int chip_id = 0; + + for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++){ + result = setup_i2c_client_one(self, chip_id); + if (result < 0){ + SWPS_ERR("%s fail! :%d\n", __func__, chip_id); + return -1; + } + } + return 0; +} + + +static int +setup_ioexp_config(struct ioexp_obj_s *self) { + + int chip_id, offset, err_code; + struct ioexp_addr_s *addr_p; + if (io_no_init) { + + SWPS_INFO("io_no_init:%d \n", io_no_init); + return 0; + } + + for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++){ + addr_p = &(self->ioexp_map_p->map_addr[chip_id]); + if (!addr_p){ + SWPS_ERR("IOEXP config incorrect! :%d \n",chip_id); + return -1; + } + for (offset=0; offset<(self->ioexp_map_p->data_width); offset++){ + + /* [Desc] Skip the setup config value behavior + [Note] Setup config value = -1 if you don't want to write the value to IOEXP or CPLD + */ + if(addr_p->conf_offset[offset] < 0){ + SWPS_DEBUG("skip a config_offset <%d>\n", addr_p->conf_offset[offset]); + continue; + } + err_code = i2c_smbus_write_byte_data(_get_i2c_client(self, chip_id), + addr_p->conf_offset[offset], + addr_p->conf_default[offset]); + + if (err_code < 0){ + SWPS_INFO("%s: set conf fail! :%d \n", __func__, err_code); + return -2; + } + } + } + return 0; +} + + +struct ioexp_obj_s * +_create_ioexp_obj(int ioexp_id, + int ioexp_type, + struct ioexp_addr_s *addr_map_p, + int run_mode){ + + struct ioexp_map_s* ioexp_map_p; + struct ioexp_obj_s* result_p; + struct ioexp_i2c_s *i2c_curr_p; + struct ioexp_i2c_s *i2c_next_p; + + /* Get layout */ + ioexp_map_p = get_ioexp_map(ioexp_type); + if (!ioexp_map_p){ + SWPS_ERR("%s: Invalid ioexp_type\n", __func__); + goto err_create_ioexp_fail; + } + /* Prepare IOEXP object */ + result_p = kzalloc(sizeof(*result_p), GFP_KERNEL); + if (!result_p){ + SWPS_ERR("%s: kzalloc failure!\n", __func__); + goto err_create_ioexp_fail; + } + /* Prepare static size attributes */ + if (setup_ioexp_ssize_attr(result_p, + ioexp_map_p, + ioexp_id, + ioexp_type, + run_mode) < 0){ + goto err_create_ioexp_setup_attr_fail; + } + /* Prepare address mapping */ + if (setup_addr_mapping(result_p, addr_map_p, ioexp_map_p->chip_amount) < 0){ + goto err_create_ioexp_setup_attr_fail; + } + if (setup_i2c_client(result_p) < 0){ + goto err_create_ioexp_setup_i2c_fail; + } + /* Prepare call back functions of object */ + if (setup_ioexp_public_cb(result_p, ioexp_type) < 0){ + goto err_create_ioexp_setup_i2c_fail; + } + if (setup_ioexp_private_cb(result_p, ioexp_type) < 0){ + goto err_create_ioexp_setup_i2c_fail; + } + return result_p; + +err_create_ioexp_setup_i2c_fail: + i2c_curr_p = result_p->i2c_head_p; + i2c_next_p = result_p->i2c_head_p; + while (i2c_curr_p){ + i2c_next_p = i2c_curr_p->next; + if (i2c_curr_p->i2c_client_p) { + i2c_put_adapter(i2c_curr_p->i2c_client_p->adapter); + kfree(i2c_curr_p->i2c_client_p); + } + kfree(i2c_curr_p); + i2c_curr_p = i2c_next_p; + } +err_create_ioexp_setup_attr_fail: + kfree(result_p); +err_create_ioexp_fail: + SWPS_ERR("%s: fail! :%d :%d \n", + __func__, ioexp_id, ioexp_type); + return NULL; +} + + +int +create_ioexp_obj(int ioexp_id, + int ioexp_type, + struct ioexp_addr_s *addr_map_p, + int run_mode){ + + struct ioexp_obj_s *ioexp_p = NULL; + + ioexp_p = _create_ioexp_obj(ioexp_id, ioexp_type, + addr_map_p, run_mode); + if (!ioexp_p){ + return -1; + } + if (ioexp_head_p == NULL){ + ioexp_head_p = ioexp_p; + ioexp_tail_p = ioexp_p; + return 0; + } + ioexp_tail_p->next = ioexp_p; + ioexp_tail_p = ioexp_p; + return 0; +} +EXPORT_SYMBOL(create_ioexp_obj); + + +static int +_init_ioexp_obj(struct ioexp_obj_s* self) { + + char *err_msg = "ERR"; + char *func_name = "_init_ioexp_obj"; + + /* Setup IOEXP configure byte */ + if (setup_ioexp_config(self) < 0){ + err_msg = "setup_ioexp_config fail"; + goto err_init_ioexp_obj; + } + /* Setup default data */ + if (_ioexp_init_handler(self) < 0){ + err_msg = "_ioexp_init_handler fail"; + goto err_init_ioexp_obj; + } + /* Update all */ + if (self->state == STATE_IOEXP_NORMAL){ + if (self->update_all(self, 1, func_name) < 0){ + err_msg = "update_all() fail"; + goto err_init_ioexp_obj; + } + } + return 0; + +err_init_ioexp_obj: + SWPS_DEBUG("%s: %s\n", __func__, err_msg); + return -1; +} + + +int +init_ioexp_objs(void){ + /* Return value: + * 0: Success + * -1: Detect topology error + * -2: SWPS internal error + */ + struct ioexp_obj_s *curr_p = ioexp_head_p; + + if (!curr_p) { + SWPS_ERR("%s: ioexp_head_p is NULL\n", __func__); + return -2; + } + while (curr_p) { + if (_init_ioexp_obj(curr_p) < 0) { + SWPS_DEBUG("%s: _init_ioexp_obj() fail\n", __func__); + return -1; + } + curr_p = curr_p->next; + } + SWPS_DEBUG("%s: done.\n", __func__); + return 0; +} +EXPORT_SYMBOL(init_ioexp_objs); + + +void +clean_ioexp_objs(void){ + + struct ioexp_i2c_s *i2c_curr_p = NULL; + struct ioexp_i2c_s *i2c_next_p = NULL; + struct ioexp_obj_s *ioexp_next_p = NULL; + struct ioexp_obj_s *ioexp_curr_p = ioexp_head_p; + + if (ioexp_head_p == NULL){ + ioexp_tail_p = NULL; + return; + } + while(ioexp_curr_p){ + ioexp_next_p = ioexp_curr_p->next; + if (ioexp_curr_p->ioexp_map_p) { + if (ioexp_curr_p->ioexp_map_p->map_addr) { + kfree(ioexp_curr_p->ioexp_map_p->map_addr); + } + kfree(ioexp_curr_p->ioexp_map_p); + } + + i2c_curr_p = ioexp_curr_p->i2c_head_p; + while (i2c_curr_p) { + i2c_next_p = i2c_curr_p->next; + if (i2c_curr_p->i2c_client_p) { + i2c_put_adapter(i2c_curr_p->i2c_client_p->adapter); + kfree(i2c_curr_p->i2c_client_p); + } + kfree(i2c_curr_p); + i2c_curr_p = i2c_next_p; + } + kfree(ioexp_curr_p); + ioexp_curr_p = ioexp_next_p; + } + ioexp_tail_p = NULL; + SWPS_DEBUG("%s: done.\n", __func__); +} +EXPORT_SYMBOL(clean_ioexp_objs); + + +int +check_ioexp_objs(void){ + + struct ioexp_obj_s *ioexp_curr_p = ioexp_head_p; + + while (ioexp_curr_p){ + if ( (ioexp_curr_p->check(ioexp_curr_p)) < 0){ + SWPS_INFO("check IOEXP-%d fail! :%d\n", + ioexp_curr_p->ioexp_id, ioexp_curr_p->ioexp_type); + return -1; + } + ioexp_curr_p = ioexp_curr_p->next; + } + return 0; +} +EXPORT_SYMBOL(check_ioexp_objs); + + +struct ioexp_obj_s * +get_ioexp_obj(int ioexp_id){ + + struct ioexp_obj_s *result_p = NULL; + struct ioexp_obj_s *ioexp_curr_p = ioexp_head_p; + + while(ioexp_curr_p){ + if (ioexp_curr_p->ioexp_id == ioexp_id){ + result_p = ioexp_curr_p; + break; + } + ioexp_curr_p = ioexp_curr_p->next; + } + return result_p; +} +EXPORT_SYMBOL(get_ioexp_obj); + + +void +unlock_ioexp_all(void) { + + struct ioexp_obj_s *ioexp_curr_p = ioexp_head_p; + + while(ioexp_curr_p){ + mutex_unlock(&ioexp_curr_p->lock); + ioexp_curr_p = ioexp_curr_p->next; + } +} +EXPORT_SYMBOL(unlock_ioexp_all); + +int +lock_ioexp_all(void) { + + struct ioexp_obj_s *ioexp_curr_p = ioexp_head_p; + + while(ioexp_curr_p){ + mutex_lock(&ioexp_curr_p->lock); + ioexp_curr_p = ioexp_curr_p->next; + } + return 0; +} +EXPORT_SYMBOL(lock_ioexp_all); + + +int +check_channel_tier_1(void) { + + if ( (!_is_channel_ready(ioexp_head_p)) && + (!_is_channel_ready(ioexp_tail_p)) ){ + return -1; + } + return 0; +} +EXPORT_SYMBOL(check_channel_tier_1); + + +static int +_scan_channel_tier_1(int force, + int show_err) { + + struct ioexp_obj_s *ioexp_curr_p = ioexp_head_p; + int ready = 0; + + if (!ioexp_curr_p) { + goto err_scan_tier_1_channel; + } + while(ioexp_curr_p) { + ready = _is_channel_ready(ioexp_curr_p); + if ((!ready) && (!force)) { + goto err_scan_tier_1_channel; + } + ioexp_curr_p = ioexp_curr_p->next; + } + return 0; + +err_scan_tier_1_channel: + if (show_err) { + if (ioexp_curr_p) { + SWPS_INFO("%s: IOEXP-%d fail\n", __func__, ioexp_curr_p->ioexp_id); + } else { + SWPS_INFO("%s: IOEXP is null.\n", __func__); + } + } + return -1; +} + + +static int +_scan_channel_tier_1_single(void) { + + int ret = 0; + int chan_id = 0; + int fake_cid = 0; + int fake_offs = 0; + int fake_addr = 0; + struct i2c_adapter *adap = NULL; + struct i2c_client *client = NULL; + + if (ioexp_head_p->ioexp_id != ioexp_tail_p->ioexp_id) { + return 0; + } + /* Setup i2c_client */ + chan_id = ioexp_head_p->ioexp_map_p->map_addr[fake_cid].chan_id; + fake_addr = ioexp_head_p->ioexp_map_p->map_addr[fake_cid].chip_addr; + adap = i2c_get_adapter((chan_id + 1)); + if(!adap){ + SWPS_INFO("%s: Can not get adap!\n", __func__); + return 0; + } + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (!client){ + SWPS_INFO("%s: Can not kzalloc client!\n", __func__); + return 0; + } + client->adapter = adap; + client->addr = fake_addr; + /* Fouce move ioexp ptr to next */ + ret = i2c_smbus_read_byte_data(client, fake_offs); + SWPS_DEBUG("%s: move ioexp_ptr done. :%d\n", __func__, ret); + kfree(client); + return 1; +} + + +int +resync_channel_tier_1(void) { + + char *emsg = "ERR"; + + if (!ioexp_head_p) { + emsg = "ioexp_head_p is NULL"; + goto err_resync_ioexp_status_1; + } + /* Run all */ + if (ioexp_head_p->ioexp_id == ioexp_tail_p->ioexp_id) { + _scan_channel_tier_1_single(); + } else { + _scan_channel_tier_1(1, 0); + } + /* Check all */ + if (_scan_channel_tier_1(0, 1) < 0) { + emsg = "resync tier-1 channel fail"; + goto err_resync_ioexp_status_1; + } + return 0; + +err_resync_ioexp_status_1: + SWPS_ERR("%s: %s\n", __func__, emsg); + return -1; +} +EXPORT_SYMBOL(resync_channel_tier_1); + + +/* For build single module using (Ex: ONL platform) */ +MODULE_LICENSE("GPL"); + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/io_expander.h b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/io_expander.h new file mode 100644 index 000000000000..6f9f7b46291e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/io_expander.h @@ -0,0 +1,189 @@ +#ifndef IO_EXPANDER_H +#define IO_EXPANDER_H + +#include + + +/* IOEXP type define (SFP series) */ +#define IOEXP_TYPE_MAGINOLIA_NAB (10101) +#define IOEXP_TYPE_MAGINOLIA_4AB (10102) +#define IOEXP_TYPE_MAPLE_NABC (10104) +#define IOEXP_TYPE_GULMOHAR_NABC (10105) +#define IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC (10106) +#define IOEXP_TYPE_SFP_8P_LAYOUT_1 (10107) +#define IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC (10108) +#define IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC (10109) + +/* IOEXP type define (QSFP series) */ +#define IOEXP_TYPE_MAGINOLIA_7AB (10201) +#define IOEXP_TYPE_REDWOOD_P01P08 (10202) +#define IOEXP_TYPE_REDWOOD_P09P16 (10203) +#define IOEXP_TYPE_HUDSON32IGA_P01P08 (10204) +#define IOEXP_TYPE_HUDSON32IGA_P09P16 (10205) +#define IOEXP_TYPE_SPRUCE_7AB (10206) +#define IOEXP_TYPE_CYPRESS_7ABC (10207) +#define IOEXP_TYPE_TAHOE_5A (10208) +#define IOEXP_TYPE_TAHOE_6ABC (10209) +#define IOEXP_TYPE_SEQUOIA_NABC (10210) +#define IOEXP_TYPE_LAVENDER_P65 (10211) +#define IOEXP_TYPE_MAPLE_0ABC (10212) +#define IOEXP_TYPE_GULMOHAR_7ABC (10213) +#define IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC (10214) +#define IOEXP_TYPE_QSFP_6P_LAYOUT_1 (10215) + +/* CPLD type define */ +#define CPLD_TYPE_COTTONWOOD (10301) + +/* IOEXP mode define */ +#define IOEXP_MODE_POLLING (19000) +#define IOEXP_MODE_DIRECT (19001) + +/* IOEXP state define */ +#define STATE_IOEXP_NORMAL (0) +#define STATE_IOEXP_INIT (-1) +#define STATE_IOEXP_ABNORMAL (-2) + +/* IOEXP error code define */ +#define ERR_IOEXP_NOTSUPPORT (-100) +#define ERR_IOEXP_UNINIT (-101) +#define ERR_IOEXP_BADCONF (-102) +#define ERR_IOEXP_ABNORMAL (-103) +#define ERR_IOEXP_NOSTATE (-104) +#define ERR_IOEXP_BADINPUT (-105) +#define ERR_IOEXP_UNEXCPT (-199) + +#define SWPS_INFO(fmt, args...) printk( KERN_INFO "[SWPS] " fmt, ##args) +#define SWPS_WARN(fmt, args...) printk( KERN_WARNING "[SWPS] " fmt, ##args) +#define SWPS_ERR(fmt, args...) printk( KERN_ERR "[SWPS] " fmt, ##args) + +#ifdef DEBUG_SWPS +# define SWPS_DEBUG(fmt, args...) printk( KERN_DEBUG "[SWPS] " fmt, ##args) +#else +# define SWPS_DEBUG(fmt, args...) +#endif + + +struct ioexp_addr_s { + int chan_id; + int chip_addr; + int read_offset[8]; + int write_offset[8]; + int conf_offset[8]; + uint8_t data_default[8]; + uint8_t conf_default[8]; +}; + +struct ioexp_i2c_s { + int chip_id; + struct i2c_client *i2c_client_p; + struct ioexp_i2c_s *next; +}; + + +struct ioexp_bitmap_s { + int chip_id; /* IOEXP chip id */ + int ioexp_voffset; /* IOEXP virtual offset */ + int bit_shift; +}; + +struct ioexp_map_s { + int chip_amount; /* Number of chips that IOEXP object content */ + int data_width; /* Number of (Read/Write/Config) bytes */ + struct ioexp_addr_s *map_addr; /* Chip address info */ + struct ioexp_bitmap_s map_present[10]; /* IOEXP for SFP / QSFP */ + struct ioexp_bitmap_s map_tx_disable[10]; /* IOEXP for SFP */ + struct ioexp_bitmap_s map_tx_fault[10]; /* IOEXP for SFP */ + struct ioexp_bitmap_s map_rxlos[10]; /* IOEXP for SFP */ + struct ioexp_bitmap_s map_reset[10]; /* IOEXP for QSFP */ + struct ioexp_bitmap_s map_lpmod[10]; /* IOEXP for QSFP */ + struct ioexp_bitmap_s map_modsel[10]; /* IOEXP for QSFP */ + struct ioexp_bitmap_s map_hard_rs0[10]; /* IOEXP for QSFP */ + struct ioexp_bitmap_s map_hard_rs1[10]; /* IOEXP for QSFP */ +}; + +struct ioexp_data_s { + uint8_t data[8]; +}; + +struct ioexp_obj_s { + + /* ============================ + * Object public property + * ============================ + */ + int ioexp_id; + int ioexp_type; + + /* ============================ + * Object private property + * ============================ + */ + struct ioexp_data_s chip_data[16]; /* Max: 8-ioexp in one virt-ioexp(ioexp_obj) */ + struct ioexp_map_s *ioexp_map_p; + struct ioexp_obj_s *next; + struct ioexp_i2c_s *i2c_head_p; + struct mutex lock; + int mode; + int state; + + /* =========================================== + * Object public functions + * =========================================== + */ + int (*get_present)(struct ioexp_obj_s *self, int virt_offset); + int (*get_tx_fault)(struct ioexp_obj_s *self, int virt_offset); + int (*get_rxlos)(struct ioexp_obj_s *self, int virt_offset); + int (*get_tx_disable)(struct ioexp_obj_s *self, int virt_offset); + int (*get_reset)(struct ioexp_obj_s *self, int virt_offset); + int (*get_lpmod)(struct ioexp_obj_s *self, int virt_offset); + int (*get_modsel)(struct ioexp_obj_s *self, int virt_offset); + int (*get_hard_rs0)(struct ioexp_obj_s *self, int virt_offset); + int (*get_hard_rs1)(struct ioexp_obj_s *self, int virt_offset); + int (*set_tx_disable)(struct ioexp_obj_s *self, int virt_offset, int input_val); + int (*set_reset)(struct ioexp_obj_s *self, int virt_offset, int input_val); + int (*set_lpmod)(struct ioexp_obj_s *self, int virt_offset, int input_val); + int (*set_modsel)(struct ioexp_obj_s *self, int virt_offset, int input_val); + int (*set_hard_rs0)(struct ioexp_obj_s *self, int virt_offset, int input_val); + int (*set_hard_rs1)(struct ioexp_obj_s *self, int virt_offset, int input_val); + + /* =========================================== + * Object private functions + * =========================================== + */ + int (*init)(struct ioexp_obj_s *self); + int (*check)(struct ioexp_obj_s *self); + int (*update_all)(struct ioexp_obj_s *self, int show_err, char *caller_name); + int (*fsm_4_direct)(struct ioexp_obj_s* self); + int (*fsm_4_polling)(struct ioexp_obj_s* self); +}; + + +struct ioexp_obj_s* get_ioexp_obj(int ioexp_id); +int create_ioexp_obj(int ioexp_id, + int ioexp_type, + struct ioexp_addr_s *addr_map_p, + int run_mode); +int init_ioexp_objs(void); +int check_ioexp_objs(void); +void clean_ioexp_objs(void); + +void unlock_ioexp_all(void); +int lock_ioexp_all(void); + +int check_channel_tier_1(void); +int resync_channel_tier_1(void); + +/* Macro for bit control */ +#define SWP_BIT_SET(byte_val,bit_shift) ((byte_val) |= (1<<(bit_shift))) +#define SWP_BIT_CLEAR(byte_val,bit_shift) ((byte_val) &= ~(1<<(bit_shift))) + + +#endif /* IO_EXPANDER_H */ + + + + + + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/lpc_ich.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/lpc_ich.c new file mode 100644 index 000000000000..66ff6e694d6f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/lpc_ich.c @@ -0,0 +1,1131 @@ +/* + * lpc_ich.c - LPC interface for Intel ICH + * + * LPC bridge function of the Intel ICH contains many other + * functional units, such as Interrupt controllers, Timers, + * Power Management, System Management, GPIO, RTC, and LPC + * Configuration Registers. + * + * This driver is derived from lpc_sch. + + * Copyright (c) 2011 Extreme Engineering Solution, Inc. + * Author: Aaron Sierra + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * This driver supports the following I/O Controller hubs: + * (See the intel documentation on http://developer.intel.com.) + * document number 290655-003, 290677-014: 82801AA (ICH), 82801AB (ICHO) + * document number 290687-002, 298242-027: 82801BA (ICH2) + * document number 290733-003, 290739-013: 82801CA (ICH3-S) + * document number 290716-001, 290718-007: 82801CAM (ICH3-M) + * document number 290744-001, 290745-025: 82801DB (ICH4) + * document number 252337-001, 252663-008: 82801DBM (ICH4-M) + * document number 273599-001, 273645-002: 82801E (C-ICH) + * document number 252516-001, 252517-028: 82801EB (ICH5), 82801ER (ICH5R) + * document number 300641-004, 300884-013: 6300ESB + * document number 301473-002, 301474-026: 82801F (ICH6) + * document number 313082-001, 313075-006: 631xESB, 632xESB + * document number 307013-003, 307014-024: 82801G (ICH7) + * document number 322896-001, 322897-001: NM10 + * document number 313056-003, 313057-017: 82801H (ICH8) + * document number 316972-004, 316973-012: 82801I (ICH9) + * document number 319973-002, 319974-002: 82801J (ICH10) + * document number 322169-001, 322170-003: 5 Series, 3400 Series (PCH) + * document number 320066-003, 320257-008: EP80597 (IICH) + * document number 324645-001, 324646-001: Cougar Point (CPT) + * document number TBD : Patsburg (PBG) + * document number TBD : DH89xxCC + * document number TBD : Panther Point + * document number TBD : Lynx Point + * document number TBD : Lynx Point-LP + * document number TBD : Wellsburg + * document number TBD : Avoton SoC + * document number TBD : Coleto Creek + * document number TBD : Wildcat Point-LP + * document number TBD : 9 Series + * document number TBD : Lewisburg + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ACPIBASE 0x40 +#define ACPIBASE_GPE_OFF 0x28 +#define ACPIBASE_GPE_END 0x2f +#define ACPIBASE_SMI_OFF 0x30 +#define ACPIBASE_SMI_END 0x33 +#define ACPIBASE_PMC_OFF 0x08 +#define ACPIBASE_PMC_END 0x0c +#define ACPIBASE_TCO_OFF 0x60 +#define ACPIBASE_TCO_END 0x7f +#define ACPICTRL_PMCBASE 0x44 + +#define ACPIBASE_GCS_OFF 0x3410 +#define ACPIBASE_GCS_END 0x3414 + +#define GPIOBASE_ICH0 0x58 +#define GPIOCTRL_ICH0 0x5C +#define GPIOBASE_ICH6 0x48 +#define GPIOCTRL_ICH6 0x4C + +#define RCBABASE 0xf0 + +#define wdt_io_res(i) wdt_res(0, i) +#define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i) +#define wdt_res(b, i) (&wdt_ich_res[(b) + (i)]) + +struct lpc_ich_priv { + int chipset; + + int abase; /* ACPI base */ + int actrl_pbase; /* ACPI control or PMC base */ + int gbase; /* GPIO base */ + int gctrl; /* GPIO control */ + + int abase_save; /* Cached ACPI base value */ + int actrl_pbase_save; /* Cached ACPI control or PMC base value */ + int gctrl_save; /* Cached GPIO control value */ +}; + +static struct resource wdt_ich_res[] = { + /* ACPI - TCO */ + { + .flags = IORESOURCE_IO, + }, + /* ACPI - SMI */ + { + .flags = IORESOURCE_IO, + }, + /* GCS or PMC */ + { + .flags = IORESOURCE_MEM, + }, +}; + +static struct resource gpio_ich_res[] = { + /* GPIO */ + { + .flags = IORESOURCE_IO, + }, + /* ACPI - GPE0 */ + { + .flags = IORESOURCE_IO, + }, +}; + +static struct mfd_cell lpc_ich_wdt_cell = { + .name = "iTCO_wdt", + .num_resources = ARRAY_SIZE(wdt_ich_res), + .resources = wdt_ich_res, + .ignore_resource_conflicts = true, +}; + +static struct mfd_cell lpc_ich_gpio_cell = { + .name = "gpio_ich", + .num_resources = ARRAY_SIZE(gpio_ich_res), + .resources = gpio_ich_res, + .ignore_resource_conflicts = true, +}; + +/* chipset related info */ +enum lpc_chipsets { + LPC_ICH = 0, /* ICH */ + LPC_ICH0, /* ICH0 */ + LPC_ICH2, /* ICH2 */ + LPC_ICH2M, /* ICH2-M */ + LPC_ICH3, /* ICH3-S */ + LPC_ICH3M, /* ICH3-M */ + LPC_ICH4, /* ICH4 */ + LPC_ICH4M, /* ICH4-M */ + LPC_CICH, /* C-ICH */ + LPC_ICH5, /* ICH5 & ICH5R */ + LPC_6300ESB, /* 6300ESB */ + LPC_ICH6, /* ICH6 & ICH6R */ + LPC_ICH6M, /* ICH6-M */ + LPC_ICH6W, /* ICH6W & ICH6RW */ + LPC_631XESB, /* 631xESB/632xESB */ + LPC_ICH7, /* ICH7 & ICH7R */ + LPC_ICH7DH, /* ICH7DH */ + LPC_ICH7M, /* ICH7-M & ICH7-U */ + LPC_ICH7MDH, /* ICH7-M DH */ + LPC_NM10, /* NM10 */ + LPC_ICH8, /* ICH8 & ICH8R */ + LPC_ICH8DH, /* ICH8DH */ + LPC_ICH8DO, /* ICH8DO */ + LPC_ICH8M, /* ICH8M */ + LPC_ICH8ME, /* ICH8M-E */ + LPC_ICH9, /* ICH9 */ + LPC_ICH9R, /* ICH9R */ + LPC_ICH9DH, /* ICH9DH */ + LPC_ICH9DO, /* ICH9DO */ + LPC_ICH9M, /* ICH9M */ + LPC_ICH9ME, /* ICH9M-E */ + LPC_ICH10, /* ICH10 */ + LPC_ICH10R, /* ICH10R */ + LPC_ICH10D, /* ICH10D */ + LPC_ICH10DO, /* ICH10DO */ + LPC_PCH, /* PCH Desktop Full Featured */ + LPC_PCHM, /* PCH Mobile Full Featured */ + LPC_P55, /* P55 */ + LPC_PM55, /* PM55 */ + LPC_H55, /* H55 */ + LPC_QM57, /* QM57 */ + LPC_H57, /* H57 */ + LPC_HM55, /* HM55 */ + LPC_Q57, /* Q57 */ + LPC_HM57, /* HM57 */ + LPC_PCHMSFF, /* PCH Mobile SFF Full Featured */ + LPC_QS57, /* QS57 */ + LPC_3400, /* 3400 */ + LPC_3420, /* 3420 */ + LPC_3450, /* 3450 */ + LPC_EP80579, /* EP80579 */ + LPC_CPT, /* Cougar Point */ + LPC_CPTD, /* Cougar Point Desktop */ + LPC_CPTM, /* Cougar Point Mobile */ + LPC_PBG, /* Patsburg */ + LPC_DH89XXCC, /* DH89xxCC */ + LPC_PPT, /* Panther Point */ + LPC_LPT, /* Lynx Point */ + LPC_LPT_LP, /* Lynx Point-LP */ + LPC_WBG, /* Wellsburg */ + LPC_AVN, /* Avoton SoC */ + LPC_BAYTRAIL, /* Bay Trail SoC */ + LPC_COLETO, /* Coleto Creek */ + LPC_WPT_LP, /* Wildcat Point-LP */ + LPC_BRASWELL, /* Braswell SoC */ + LPC_LEWISBURG, /* Lewisburg */ + LPC_9S, /* 9 Series */ +}; + +static struct lpc_ich_info lpc_chipset_info[] = { + [LPC_ICH] = { + .name = "ICH", + .iTCO_version = 1, + }, + [LPC_ICH0] = { + .name = "ICH0", + .iTCO_version = 1, + }, + [LPC_ICH2] = { + .name = "ICH2", + .iTCO_version = 1, + }, + [LPC_ICH2M] = { + .name = "ICH2-M", + .iTCO_version = 1, + }, + [LPC_ICH3] = { + .name = "ICH3-S", + .iTCO_version = 1, + }, + [LPC_ICH3M] = { + .name = "ICH3-M", + .iTCO_version = 1, + }, + [LPC_ICH4] = { + .name = "ICH4", + .iTCO_version = 1, + }, + [LPC_ICH4M] = { + .name = "ICH4-M", + .iTCO_version = 1, + }, + [LPC_CICH] = { + .name = "C-ICH", + .iTCO_version = 1, + }, + [LPC_ICH5] = { + .name = "ICH5 or ICH5R", + .iTCO_version = 1, + }, + [LPC_6300ESB] = { + .name = "6300ESB", + .iTCO_version = 1, + }, + [LPC_ICH6] = { + .name = "ICH6 or ICH6R", + .iTCO_version = 2, + .gpio_version = ICH_V6_GPIO, + }, + [LPC_ICH6M] = { + .name = "ICH6-M", + .iTCO_version = 2, + .gpio_version = ICH_V6_GPIO, + }, + [LPC_ICH6W] = { + .name = "ICH6W or ICH6RW", + .iTCO_version = 2, + .gpio_version = ICH_V6_GPIO, + }, + [LPC_631XESB] = { + .name = "631xESB/632xESB", + .iTCO_version = 2, + .gpio_version = ICH_V6_GPIO, + }, + [LPC_ICH7] = { + .name = "ICH7 or ICH7R", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH7DH] = { + .name = "ICH7DH", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH7M] = { + .name = "ICH7-M or ICH7-U", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH7MDH] = { + .name = "ICH7-M DH", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_NM10] = { + .name = "NM10", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH8] = { + .name = "ICH8 or ICH8R", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH8DH] = { + .name = "ICH8DH", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH8DO] = { + .name = "ICH8DO", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH8M] = { + .name = "ICH8M", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH8ME] = { + .name = "ICH8M-E", + .iTCO_version = 2, + .gpio_version = ICH_V7_GPIO, + }, + [LPC_ICH9] = { + .name = "ICH9", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH9R] = { + .name = "ICH9R", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH9DH] = { + .name = "ICH9DH", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH9DO] = { + .name = "ICH9DO", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH9M] = { + .name = "ICH9M", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH9ME] = { + .name = "ICH9M-E", + .iTCO_version = 2, + .gpio_version = ICH_V9_GPIO, + }, + [LPC_ICH10] = { + .name = "ICH10", + .iTCO_version = 2, + .gpio_version = ICH_V10CONS_GPIO, + }, + [LPC_ICH10R] = { + .name = "ICH10R", + .iTCO_version = 2, + .gpio_version = ICH_V10CONS_GPIO, + }, + [LPC_ICH10D] = { + .name = "ICH10D", + .iTCO_version = 2, + .gpio_version = ICH_V10CORP_GPIO, + }, + [LPC_ICH10DO] = { + .name = "ICH10DO", + .iTCO_version = 2, + .gpio_version = ICH_V10CORP_GPIO, + }, + [LPC_PCH] = { + .name = "PCH Desktop Full Featured", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_PCHM] = { + .name = "PCH Mobile Full Featured", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_P55] = { + .name = "P55", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_PM55] = { + .name = "PM55", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_H55] = { + .name = "H55", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_QM57] = { + .name = "QM57", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_H57] = { + .name = "H57", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_HM55] = { + .name = "HM55", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_Q57] = { + .name = "Q57", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_HM57] = { + .name = "HM57", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_PCHMSFF] = { + .name = "PCH Mobile SFF Full Featured", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_QS57] = { + .name = "QS57", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_3400] = { + .name = "3400", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_3420] = { + .name = "3420", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_3450] = { + .name = "3450", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_EP80579] = { + .name = "EP80579", + .iTCO_version = 2, + }, + [LPC_CPT] = { + .name = "Cougar Point", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_CPTD] = { + .name = "Cougar Point Desktop", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_CPTM] = { + .name = "Cougar Point Mobile", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_PBG] = { + .name = "Patsburg", + .iTCO_version = 2, + }, + [LPC_DH89XXCC] = { + .name = "DH89xxCC", + .iTCO_version = 2, + }, + [LPC_PPT] = { + .name = "Panther Point", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_LPT] = { + .name = "Lynx Point", + .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, + }, + [LPC_LPT_LP] = { + .name = "Lynx Point_LP", + .iTCO_version = 2, + }, + [LPC_WBG] = { + .name = "Wellsburg", + .iTCO_version = 2, + }, + [LPC_AVN] = { + .name = "Avoton SoC", + .iTCO_version = 3, + .gpio_version = AVOTON_GPIO, + }, + [LPC_BAYTRAIL] = { + .name = "Bay Trail SoC", + .iTCO_version = 3, + }, + [LPC_COLETO] = { + .name = "Coleto Creek", + .iTCO_version = 2, + }, + [LPC_WPT_LP] = { + .name = "Wildcat Point_LP", + .iTCO_version = 2, + }, + [LPC_BRASWELL] = { + .name = "Braswell SoC", + .iTCO_version = 3, + }, + [LPC_LEWISBURG] = { + .name = "Lewisburg", + .iTCO_version = 2, + }, + [LPC_9S] = { + .name = "9 Series", + .iTCO_version = 2, + }, +}; + +/* + * This data only exists for exporting the supported PCI ids + * via MODULE_DEVICE_TABLE. We do not actually register a + * pci_driver, because the I/O Controller Hub has also other + * functions that probably will be registered by other drivers. + */ +static const struct pci_device_id lpc_ich_ids[] = { + { PCI_VDEVICE(INTEL, 0x0f1c), LPC_BAYTRAIL}, + { PCI_VDEVICE(INTEL, 0x1c41), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c42), LPC_CPTD}, + { PCI_VDEVICE(INTEL, 0x1c43), LPC_CPTM}, + { PCI_VDEVICE(INTEL, 0x1c44), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c45), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c46), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c47), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c48), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c49), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4a), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4b), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4c), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4d), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4e), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c4f), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c50), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c51), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c52), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c53), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c54), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c55), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c56), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c57), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c58), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c59), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5a), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5b), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5c), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5d), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5e), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1c5f), LPC_CPT}, + { PCI_VDEVICE(INTEL, 0x1d40), LPC_PBG}, + { PCI_VDEVICE(INTEL, 0x1d41), LPC_PBG}, + { PCI_VDEVICE(INTEL, 0x1e40), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e41), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e42), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e43), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e44), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e45), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e46), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e47), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e48), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e49), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4a), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4b), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4c), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4d), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4e), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e4f), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e50), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e51), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e52), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e53), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e54), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e55), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e56), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e57), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e58), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e59), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5a), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5b), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5c), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5d), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5e), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1e5f), LPC_PPT}, + { PCI_VDEVICE(INTEL, 0x1f38), LPC_AVN}, + { PCI_VDEVICE(INTEL, 0x1f39), LPC_AVN}, + { PCI_VDEVICE(INTEL, 0x1f3a), LPC_AVN}, + { PCI_VDEVICE(INTEL, 0x1f3b), LPC_AVN}, + { PCI_VDEVICE(INTEL, 0x229c), LPC_BRASWELL}, + { PCI_VDEVICE(INTEL, 0x2310), LPC_DH89XXCC}, + { PCI_VDEVICE(INTEL, 0x2390), LPC_COLETO}, + { PCI_VDEVICE(INTEL, 0x2410), LPC_ICH}, + { PCI_VDEVICE(INTEL, 0x2420), LPC_ICH0}, + { PCI_VDEVICE(INTEL, 0x2440), LPC_ICH2}, + { PCI_VDEVICE(INTEL, 0x244c), LPC_ICH2M}, + { PCI_VDEVICE(INTEL, 0x2450), LPC_CICH}, + { PCI_VDEVICE(INTEL, 0x2480), LPC_ICH3}, + { PCI_VDEVICE(INTEL, 0x248c), LPC_ICH3M}, + { PCI_VDEVICE(INTEL, 0x24c0), LPC_ICH4}, + { PCI_VDEVICE(INTEL, 0x24cc), LPC_ICH4M}, + { PCI_VDEVICE(INTEL, 0x24d0), LPC_ICH5}, + { PCI_VDEVICE(INTEL, 0x25a1), LPC_6300ESB}, + { PCI_VDEVICE(INTEL, 0x2640), LPC_ICH6}, + { PCI_VDEVICE(INTEL, 0x2641), LPC_ICH6M}, + { PCI_VDEVICE(INTEL, 0x2642), LPC_ICH6W}, + { PCI_VDEVICE(INTEL, 0x2670), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2671), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2672), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2673), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2674), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2675), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2676), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2677), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2678), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x2679), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267a), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267b), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267c), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267d), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267e), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x267f), LPC_631XESB}, + { PCI_VDEVICE(INTEL, 0x27b0), LPC_ICH7DH}, + { PCI_VDEVICE(INTEL, 0x27b8), LPC_ICH7}, + { PCI_VDEVICE(INTEL, 0x27b9), LPC_ICH7M}, + { PCI_VDEVICE(INTEL, 0x27bc), LPC_NM10}, + { PCI_VDEVICE(INTEL, 0x27bd), LPC_ICH7MDH}, + { PCI_VDEVICE(INTEL, 0x2810), LPC_ICH8}, + { PCI_VDEVICE(INTEL, 0x2811), LPC_ICH8ME}, + { PCI_VDEVICE(INTEL, 0x2812), LPC_ICH8DH}, + { PCI_VDEVICE(INTEL, 0x2814), LPC_ICH8DO}, + { PCI_VDEVICE(INTEL, 0x2815), LPC_ICH8M}, + { PCI_VDEVICE(INTEL, 0x2912), LPC_ICH9DH}, + { PCI_VDEVICE(INTEL, 0x2914), LPC_ICH9DO}, + { PCI_VDEVICE(INTEL, 0x2916), LPC_ICH9R}, + { PCI_VDEVICE(INTEL, 0x2917), LPC_ICH9ME}, + { PCI_VDEVICE(INTEL, 0x2918), LPC_ICH9}, + { PCI_VDEVICE(INTEL, 0x2919), LPC_ICH9M}, + { PCI_VDEVICE(INTEL, 0x3a14), LPC_ICH10DO}, + { PCI_VDEVICE(INTEL, 0x3a16), LPC_ICH10R}, + { PCI_VDEVICE(INTEL, 0x3a18), LPC_ICH10}, + { PCI_VDEVICE(INTEL, 0x3a1a), LPC_ICH10D}, + { PCI_VDEVICE(INTEL, 0x3b00), LPC_PCH}, + { PCI_VDEVICE(INTEL, 0x3b01), LPC_PCHM}, + { PCI_VDEVICE(INTEL, 0x3b02), LPC_P55}, + { PCI_VDEVICE(INTEL, 0x3b03), LPC_PM55}, + { PCI_VDEVICE(INTEL, 0x3b06), LPC_H55}, + { PCI_VDEVICE(INTEL, 0x3b07), LPC_QM57}, + { PCI_VDEVICE(INTEL, 0x3b08), LPC_H57}, + { PCI_VDEVICE(INTEL, 0x3b09), LPC_HM55}, + { PCI_VDEVICE(INTEL, 0x3b0a), LPC_Q57}, + { PCI_VDEVICE(INTEL, 0x3b0b), LPC_HM57}, + { PCI_VDEVICE(INTEL, 0x3b0d), LPC_PCHMSFF}, + { PCI_VDEVICE(INTEL, 0x3b0f), LPC_QS57}, + { PCI_VDEVICE(INTEL, 0x3b12), LPC_3400}, + { PCI_VDEVICE(INTEL, 0x3b14), LPC_3420}, + { PCI_VDEVICE(INTEL, 0x3b16), LPC_3450}, + { PCI_VDEVICE(INTEL, 0x5031), LPC_EP80579}, + { PCI_VDEVICE(INTEL, 0x8c40), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c41), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c42), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c43), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c44), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c45), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c46), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c47), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c48), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c49), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4a), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4b), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4c), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4d), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4e), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c4f), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c50), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c51), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c52), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c53), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c54), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c55), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c56), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c57), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c58), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c59), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5a), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5b), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5c), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5d), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5e), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8c5f), LPC_LPT}, + { PCI_VDEVICE(INTEL, 0x8cc1), LPC_9S}, + { PCI_VDEVICE(INTEL, 0x8cc2), LPC_9S}, + { PCI_VDEVICE(INTEL, 0x8cc3), LPC_9S}, + { PCI_VDEVICE(INTEL, 0x8cc4), LPC_9S}, + { PCI_VDEVICE(INTEL, 0x8cc6), LPC_9S}, + { PCI_VDEVICE(INTEL, 0x8d40), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d41), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d42), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d43), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d44), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d45), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d46), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d47), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d48), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d49), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4a), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4b), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4c), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4d), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4e), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d4f), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d50), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d51), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d52), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d53), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d54), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d55), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d56), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d57), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d58), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d59), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5a), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5b), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5c), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5d), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5e), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x8d5f), LPC_WBG}, + { PCI_VDEVICE(INTEL, 0x9c40), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c41), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c42), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c43), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c44), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c45), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c46), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9c47), LPC_LPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc1), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc2), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc3), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc5), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc6), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc7), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0x9cc9), LPC_WPT_LP}, + { PCI_VDEVICE(INTEL, 0xa1c1), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c2), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c3), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c4), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c5), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c6), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa1c7), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa242), LPC_LEWISBURG}, + { PCI_VDEVICE(INTEL, 0xa243), LPC_LEWISBURG}, + { 0, }, /* End of list */ +}; +MODULE_DEVICE_TABLE(pci, lpc_ich_ids); + +static void lpc_ich_restore_config_space(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + + if (priv->abase_save >= 0) { + pci_write_config_byte(dev, priv->abase, priv->abase_save); + priv->abase_save = -1; + } + + if (priv->actrl_pbase_save >= 0) { + pci_write_config_byte(dev, priv->actrl_pbase, + priv->actrl_pbase_save); + priv->actrl_pbase_save = -1; + } + + if (priv->gctrl_save >= 0) { + pci_write_config_byte(dev, priv->gctrl, priv->gctrl_save); + priv->gctrl_save = -1; + } +} + +static void lpc_ich_enable_acpi_space(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + u8 reg_save; + + switch (lpc_chipset_info[priv->chipset].iTCO_version) { + case 3: + /* + * Some chipsets (eg Avoton) enable the ACPI space in the + * ACPI BASE register. + */ + pci_read_config_byte(dev, priv->abase, ®_save); + pci_write_config_byte(dev, priv->abase, reg_save | 0x2); + priv->abase_save = reg_save; + break; + default: + /* + * Most chipsets enable the ACPI space in the ACPI control + * register. + */ + pci_read_config_byte(dev, priv->actrl_pbase, ®_save); + pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x80); + priv->actrl_pbase_save = reg_save; + break; + } +} + +static void lpc_ich_enable_gpio_space(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + u8 reg_save; + + pci_read_config_byte(dev, priv->gctrl, ®_save); + pci_write_config_byte(dev, priv->gctrl, reg_save | 0x10); + priv->gctrl_save = reg_save; +} + +static void lpc_ich_enable_pmc_space(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + u8 reg_save; + + pci_read_config_byte(dev, priv->actrl_pbase, ®_save); + pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x2); + + priv->actrl_pbase_save = reg_save; +} + +static int lpc_ich_finalize_wdt_cell(struct pci_dev *dev) +{ + struct itco_wdt_platform_data *pdata; + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + struct lpc_ich_info *info; + struct mfd_cell *cell = &lpc_ich_wdt_cell; + + pdata = devm_kzalloc(&dev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + info = &lpc_chipset_info[priv->chipset]; + + pdata->version = info->iTCO_version; + strlcpy(pdata->name, info->name, sizeof(pdata->name)); + + cell->platform_data = pdata; + cell->pdata_size = sizeof(*pdata); + return 0; +} + +static void lpc_ich_finalize_gpio_cell(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + struct mfd_cell *cell = &lpc_ich_gpio_cell; + + cell->platform_data = &lpc_chipset_info[priv->chipset]; + cell->pdata_size = sizeof(struct lpc_ich_info); +} + +/* + * We don't check for resource conflict globally. There are 2 or 3 independent + * GPIO groups and it's enough to have access to one of these to instantiate + * the device. + */ +static int lpc_ich_check_conflict_gpio(struct resource *res) +{ + int ret; + u8 use_gpio = 0; + + if (resource_size(res) >= 0x50 && + !acpi_check_region(res->start + 0x40, 0x10, "LPC ICH GPIO3")) + use_gpio |= 1 << 2; + + if (!acpi_check_region(res->start + 0x30, 0x10, "LPC ICH GPIO2")) + use_gpio |= 1 << 1; + + ret = acpi_check_region(res->start + 0x00, 0x30, "LPC ICH GPIO1"); + if (!ret) + use_gpio |= 1 << 0; + + return use_gpio ? use_gpio : ret; +} + +static int lpc_ich_init_gpio(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + u32 base_addr_cfg; + u32 base_addr; + int ret; + bool acpi_conflict = false; + struct resource *res; + + /* Setup power management base register */ + pci_read_config_dword(dev, priv->abase, &base_addr_cfg); + base_addr = base_addr_cfg & 0x0000ff80; + if (!base_addr) { + dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); + lpc_ich_gpio_cell.num_resources--; + goto gpe0_done; + } + + res = &gpio_ich_res[ICH_RES_GPE0]; + res->start = base_addr + ACPIBASE_GPE_OFF; + res->end = base_addr + ACPIBASE_GPE_END; + ret = acpi_check_resource_conflict(res); + if (ret) { + /* + * This isn't fatal for the GPIO, but we have to make sure that + * the platform_device subsystem doesn't see this resource + * or it will register an invalid region. + */ + lpc_ich_gpio_cell.num_resources--; + acpi_conflict = true; + } else { + lpc_ich_enable_acpi_space(dev); + } + +gpe0_done: + /* Setup GPIO base register */ + pci_read_config_dword(dev, priv->gbase, &base_addr_cfg); + base_addr = base_addr_cfg & 0x0000ff80; + if (!base_addr) { + dev_notice(&dev->dev, "I/O space for GPIO uninitialized\n"); + ret = -ENODEV; + goto gpio_done; + } + + /* Older devices provide fewer GPIO and have a smaller resource size. */ + res = &gpio_ich_res[ICH_RES_GPIO]; + res->start = base_addr; + switch (lpc_chipset_info[priv->chipset].gpio_version) { + case ICH_V5_GPIO: + case ICH_V10CORP_GPIO: + res->end = res->start + 128 - 1; + break; + default: + res->end = res->start + 64 - 1; + break; + } + + ret = lpc_ich_check_conflict_gpio(res); + if (ret < 0) { + /* this isn't necessarily fatal for the GPIO */ + acpi_conflict = true; + goto gpio_done; + } + lpc_chipset_info[priv->chipset].use_gpio = ret; + lpc_ich_enable_gpio_space(dev); + + lpc_ich_finalize_gpio_cell(dev); + ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO, + &lpc_ich_gpio_cell, 1, NULL, 0, NULL); + +gpio_done: + if (acpi_conflict) + pr_warn("Resource conflict(s) found affecting %s\n", + lpc_ich_gpio_cell.name); + return ret; +} + +static int lpc_ich_init_wdt(struct pci_dev *dev) +{ + struct lpc_ich_priv *priv = pci_get_drvdata(dev); + u32 base_addr_cfg; + u32 base_addr; + int ret; + struct resource *res; + + /* If we have ACPI based watchdog use that instead */ + if (acpi_has_watchdog()) + return -ENODEV; + + /* Setup power management base register */ + pci_read_config_dword(dev, priv->abase, &base_addr_cfg); + base_addr = base_addr_cfg & 0x0000ff80; + if (!base_addr) { + dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); + ret = -ENODEV; + goto wdt_done; + } + + res = wdt_io_res(ICH_RES_IO_TCO); + res->start = base_addr + ACPIBASE_TCO_OFF; + res->end = base_addr + ACPIBASE_TCO_END; + + res = wdt_io_res(ICH_RES_IO_SMI); + res->start = base_addr + ACPIBASE_SMI_OFF; + res->end = base_addr + ACPIBASE_SMI_END; + + lpc_ich_enable_acpi_space(dev); + + /* + * iTCO v2: + * Get the Memory-Mapped GCS register. To get access to it + * we have to read RCBA from PCI Config space 0xf0 and use + * it as base. GCS = RCBA + ICH6_GCS(0x3410). + * + * iTCO v3: + * Get the Power Management Configuration register. To get access + * to it we have to read the PMC BASE from config space and address + * the register at offset 0x8. + */ + if (lpc_chipset_info[priv->chipset].iTCO_version == 1) { + /* Don't register iomem for TCO ver 1 */ + lpc_ich_wdt_cell.num_resources--; + } else if (lpc_chipset_info[priv->chipset].iTCO_version == 2) { + pci_read_config_dword(dev, RCBABASE, &base_addr_cfg); + base_addr = base_addr_cfg & 0xffffc000; + if (!(base_addr_cfg & 1)) { + dev_notice(&dev->dev, "RCBA is disabled by " + "hardware/BIOS, device disabled\n"); + ret = -ENODEV; + goto wdt_done; + } + res = wdt_mem_res(ICH_RES_MEM_GCS_PMC); + res->start = base_addr + ACPIBASE_GCS_OFF; + res->end = base_addr + ACPIBASE_GCS_END; + } else if (lpc_chipset_info[priv->chipset].iTCO_version == 3) { + lpc_ich_enable_pmc_space(dev); + pci_read_config_dword(dev, ACPICTRL_PMCBASE, &base_addr_cfg); + base_addr = base_addr_cfg & 0xfffffe00; + + res = wdt_mem_res(ICH_RES_MEM_GCS_PMC); + res->start = base_addr + ACPIBASE_PMC_OFF; + res->end = base_addr + ACPIBASE_PMC_END; + } + + ret = lpc_ich_finalize_wdt_cell(dev); + if (ret) + goto wdt_done; + + ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO, + &lpc_ich_wdt_cell, 1, NULL, 0, NULL); + +wdt_done: + return ret; +} + +static int lpc_ich_probe(struct pci_dev *dev, + const struct pci_device_id *id) +{ + struct lpc_ich_priv *priv; + int ret; + bool cell_added = false; + + priv = devm_kzalloc(&dev->dev, + sizeof(struct lpc_ich_priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->chipset = id->driver_data; + + priv->actrl_pbase_save = -1; + priv->abase_save = -1; + + priv->abase = ACPIBASE; + priv->actrl_pbase = ACPICTRL_PMCBASE; + + priv->gctrl_save = -1; + if (priv->chipset <= LPC_ICH5) { + priv->gbase = GPIOBASE_ICH0; + priv->gctrl = GPIOCTRL_ICH0; + } else { + priv->gbase = GPIOBASE_ICH6; + priv->gctrl = GPIOCTRL_ICH6; + } + + pci_set_drvdata(dev, priv); + + if (lpc_chipset_info[priv->chipset].iTCO_version) { + ret = lpc_ich_init_wdt(dev); + if (!ret) + cell_added = true; + } + + if (lpc_chipset_info[priv->chipset].gpio_version) { + ret = lpc_ich_init_gpio(dev); + if (!ret) + cell_added = true; + } + + /* + * We only care if at least one or none of the cells registered + * successfully. + */ + if (!cell_added) { + dev_warn(&dev->dev, "No MFD cells added\n"); + lpc_ich_restore_config_space(dev); + return -ENODEV; + } + + return 0; +} + +static void lpc_ich_remove(struct pci_dev *dev) +{ + mfd_remove_devices(&dev->dev); + lpc_ich_restore_config_space(dev); +} + +static struct pci_driver lpc_ich_driver = { + .name = "lpc_ich", + .id_table = lpc_ich_ids, + .probe = lpc_ich_probe, + .remove = lpc_ich_remove, +}; + +module_pci_driver(lpc_ich_driver); + +MODULE_AUTHOR("Aaron Sierra "); +MODULE_DESCRIPTION("LPC interface for Intel ICH"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/pmbus.h b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/pmbus.h new file mode 100644 index 000000000000..4efa2bd4f6d8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/pmbus.h @@ -0,0 +1,425 @@ +/* + * pmbus.h - Common defines and structures for PMBus devices + * + * Copyright (c) 2010, 2011 Ericsson AB. + * Copyright (c) 2012 Guenter Roeck + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PMBUS_H +#define PMBUS_H + +#include +#include + +/* + * Registers + */ +enum pmbus_regs { + PMBUS_PAGE = 0x00, + PMBUS_OPERATION = 0x01, + PMBUS_ON_OFF_CONFIG = 0x02, + PMBUS_CLEAR_FAULTS = 0x03, + PMBUS_PHASE = 0x04, + + PMBUS_CAPABILITY = 0x19, + PMBUS_QUERY = 0x1A, + + PMBUS_VOUT_MODE = 0x20, + PMBUS_VOUT_COMMAND = 0x21, + PMBUS_VOUT_TRIM = 0x22, + PMBUS_VOUT_CAL_OFFSET = 0x23, + PMBUS_VOUT_MAX = 0x24, + PMBUS_VOUT_MARGIN_HIGH = 0x25, + PMBUS_VOUT_MARGIN_LOW = 0x26, + PMBUS_VOUT_TRANSITION_RATE = 0x27, + PMBUS_VOUT_DROOP = 0x28, + PMBUS_VOUT_SCALE_LOOP = 0x29, + PMBUS_VOUT_SCALE_MONITOR = 0x2A, + + PMBUS_COEFFICIENTS = 0x30, + PMBUS_POUT_MAX = 0x31, + + PMBUS_FAN_CONFIG_12 = 0x3A, + PMBUS_FAN_COMMAND_1 = 0x3B, + PMBUS_FAN_COMMAND_2 = 0x3C, + PMBUS_FAN_CONFIG_34 = 0x3D, + PMBUS_FAN_COMMAND_3 = 0x3E, + PMBUS_FAN_COMMAND_4 = 0x3F, + + PMBUS_VOUT_OV_FAULT_LIMIT = 0x40, + PMBUS_VOUT_OV_FAULT_RESPONSE = 0x41, + PMBUS_VOUT_OV_WARN_LIMIT = 0x42, + PMBUS_VOUT_UV_WARN_LIMIT = 0x43, + PMBUS_VOUT_UV_FAULT_LIMIT = 0x44, + PMBUS_VOUT_UV_FAULT_RESPONSE = 0x45, + PMBUS_IOUT_OC_FAULT_LIMIT = 0x46, + PMBUS_IOUT_OC_FAULT_RESPONSE = 0x47, + PMBUS_IOUT_OC_LV_FAULT_LIMIT = 0x48, + PMBUS_IOUT_OC_LV_FAULT_RESPONSE = 0x49, + PMBUS_IOUT_OC_WARN_LIMIT = 0x4A, + PMBUS_IOUT_UC_FAULT_LIMIT = 0x4B, + PMBUS_IOUT_UC_FAULT_RESPONSE = 0x4C, + + PMBUS_OT_FAULT_LIMIT = 0x4F, + PMBUS_OT_FAULT_RESPONSE = 0x50, + PMBUS_OT_WARN_LIMIT = 0x51, + PMBUS_UT_WARN_LIMIT = 0x52, + PMBUS_UT_FAULT_LIMIT = 0x53, + PMBUS_UT_FAULT_RESPONSE = 0x54, + PMBUS_VIN_OV_FAULT_LIMIT = 0x55, + PMBUS_VIN_OV_FAULT_RESPONSE = 0x56, + PMBUS_VIN_OV_WARN_LIMIT = 0x57, + PMBUS_VIN_UV_WARN_LIMIT = 0x58, + PMBUS_VIN_UV_FAULT_LIMIT = 0x59, + + PMBUS_IIN_OC_FAULT_LIMIT = 0x5B, + PMBUS_IIN_OC_WARN_LIMIT = 0x5D, + + PMBUS_POUT_OP_FAULT_LIMIT = 0x68, + PMBUS_POUT_OP_WARN_LIMIT = 0x6A, + PMBUS_PIN_OP_WARN_LIMIT = 0x6B, + + PMBUS_STATUS_BYTE = 0x78, + PMBUS_STATUS_WORD = 0x79, + PMBUS_STATUS_VOUT = 0x7A, + PMBUS_STATUS_IOUT = 0x7B, + PMBUS_STATUS_INPUT = 0x7C, + PMBUS_STATUS_TEMPERATURE = 0x7D, + PMBUS_STATUS_CML = 0x7E, + PMBUS_STATUS_OTHER = 0x7F, + PMBUS_STATUS_MFR_SPECIFIC = 0x80, + PMBUS_STATUS_FAN_12 = 0x81, + PMBUS_STATUS_FAN_34 = 0x82, + + PMBUS_READ_VIN = 0x88, + PMBUS_READ_IIN = 0x89, + PMBUS_READ_VCAP = 0x8A, + PMBUS_READ_VOUT = 0x8B, + PMBUS_READ_IOUT = 0x8C, + PMBUS_READ_TEMPERATURE_1 = 0x8D, + PMBUS_READ_TEMPERATURE_2 = 0x8E, + PMBUS_READ_TEMPERATURE_3 = 0x8F, + PMBUS_READ_FAN_SPEED_1 = 0x90, + PMBUS_READ_FAN_SPEED_2 = 0x91, + PMBUS_READ_FAN_SPEED_3 = 0x92, + PMBUS_READ_FAN_SPEED_4 = 0x93, + PMBUS_READ_DUTY_CYCLE = 0x94, + PMBUS_READ_FREQUENCY = 0x95, + PMBUS_READ_POUT = 0x96, + PMBUS_READ_PIN = 0x97, + + PMBUS_REVISION = 0x98, + PMBUS_MFR_ID = 0x99, + PMBUS_MFR_MODEL = 0x9A, + PMBUS_MFR_REVISION = 0x9B, + PMBUS_MFR_LOCATION = 0x9C, + PMBUS_MFR_DATE = 0x9D, + PMBUS_MFR_SERIAL = 0x9E, + +/* + * Virtual registers. + * Useful to support attributes which are not supported by standard PMBus + * registers but exist as manufacturer specific registers on individual chips. + * Must be mapped to real registers in device specific code. + * + * Semantics: + * Virtual registers are all word size. + * READ registers are read-only; writes are either ignored or return an error. + * RESET registers are read/write. Reading reset registers returns zero + * (used for detection), writing any value causes the associated history to be + * reset. + * Virtual registers have to be handled in device specific driver code. Chip + * driver code returns non-negative register values if a virtual register is + * supported, or a negative error code if not. The chip driver may return + * -ENODATA or any other error code in this case, though an error code other + * than -ENODATA is handled more efficiently and thus preferred. Either case, + * the calling PMBus core code will abort if the chip driver returns an error + * code when reading or writing virtual registers. + */ + PMBUS_VIRT_BASE = 0x100, + PMBUS_VIRT_READ_TEMP_AVG, + PMBUS_VIRT_READ_TEMP_MIN, + PMBUS_VIRT_READ_TEMP_MAX, + PMBUS_VIRT_RESET_TEMP_HISTORY, + PMBUS_VIRT_READ_VIN_AVG, + PMBUS_VIRT_READ_VIN_MIN, + PMBUS_VIRT_READ_VIN_MAX, + PMBUS_VIRT_RESET_VIN_HISTORY, + PMBUS_VIRT_READ_IIN_AVG, + PMBUS_VIRT_READ_IIN_MIN, + PMBUS_VIRT_READ_IIN_MAX, + PMBUS_VIRT_RESET_IIN_HISTORY, + PMBUS_VIRT_READ_PIN_AVG, + PMBUS_VIRT_READ_PIN_MIN, + PMBUS_VIRT_READ_PIN_MAX, + PMBUS_VIRT_RESET_PIN_HISTORY, + PMBUS_VIRT_READ_POUT_AVG, + PMBUS_VIRT_READ_POUT_MIN, + PMBUS_VIRT_READ_POUT_MAX, + PMBUS_VIRT_RESET_POUT_HISTORY, + PMBUS_VIRT_READ_VOUT_AVG, + PMBUS_VIRT_READ_VOUT_MIN, + PMBUS_VIRT_READ_VOUT_MAX, + PMBUS_VIRT_RESET_VOUT_HISTORY, + PMBUS_VIRT_READ_IOUT_AVG, + PMBUS_VIRT_READ_IOUT_MIN, + PMBUS_VIRT_READ_IOUT_MAX, + PMBUS_VIRT_RESET_IOUT_HISTORY, + PMBUS_VIRT_READ_TEMP2_AVG, + PMBUS_VIRT_READ_TEMP2_MIN, + PMBUS_VIRT_READ_TEMP2_MAX, + PMBUS_VIRT_RESET_TEMP2_HISTORY, + + PMBUS_VIRT_READ_VMON, + PMBUS_VIRT_VMON_UV_WARN_LIMIT, + PMBUS_VIRT_VMON_OV_WARN_LIMIT, + PMBUS_VIRT_VMON_UV_FAULT_LIMIT, + PMBUS_VIRT_VMON_OV_FAULT_LIMIT, + PMBUS_VIRT_STATUS_VMON, +}; + +/* + * OPERATION + */ +#define PB_OPERATION_CONTROL_ON BIT(7) + +/* + * CAPABILITY + */ +#define PB_CAPABILITY_SMBALERT BIT(4) +#define PB_CAPABILITY_ERROR_CHECK BIT(7) + +/* + * VOUT_MODE + */ +#define PB_VOUT_MODE_MODE_MASK 0xe0 +#define PB_VOUT_MODE_PARAM_MASK 0x1f + +#define PB_VOUT_MODE_LINEAR 0x00 +#define PB_VOUT_MODE_VID 0x20 +#define PB_VOUT_MODE_DIRECT 0x40 + +/* + * Fan configuration + */ +#define PB_FAN_2_PULSE_MASK (BIT(0) | BIT(1)) +#define PB_FAN_2_RPM BIT(2) +#define PB_FAN_2_INSTALLED BIT(3) +#define PB_FAN_1_PULSE_MASK (BIT(4) | BIT(5)) +#define PB_FAN_1_RPM BIT(6) +#define PB_FAN_1_INSTALLED BIT(7) + +/* + * STATUS_BYTE, STATUS_WORD (lower) + */ +#define PB_STATUS_NONE_ABOVE BIT(0) +#define PB_STATUS_CML BIT(1) +#define PB_STATUS_TEMPERATURE BIT(2) +#define PB_STATUS_VIN_UV BIT(3) +#define PB_STATUS_IOUT_OC BIT(4) +#define PB_STATUS_VOUT_OV BIT(5) +#define PB_STATUS_OFF BIT(6) +#define PB_STATUS_BUSY BIT(7) + +/* + * STATUS_WORD (upper) + */ +#define PB_STATUS_UNKNOWN BIT(8) +#define PB_STATUS_OTHER BIT(9) +#define PB_STATUS_FANS BIT(10) +#define PB_STATUS_POWER_GOOD_N BIT(11) +#define PB_STATUS_WORD_MFR BIT(12) +#define PB_STATUS_INPUT BIT(13) +#define PB_STATUS_IOUT_POUT BIT(14) +#define PB_STATUS_VOUT BIT(15) + +/* + * STATUS_IOUT + */ +#define PB_POUT_OP_WARNING BIT(0) +#define PB_POUT_OP_FAULT BIT(1) +#define PB_POWER_LIMITING BIT(2) +#define PB_CURRENT_SHARE_FAULT BIT(3) +#define PB_IOUT_UC_FAULT BIT(4) +#define PB_IOUT_OC_WARNING BIT(5) +#define PB_IOUT_OC_LV_FAULT BIT(6) +#define PB_IOUT_OC_FAULT BIT(7) + +/* + * STATUS_VOUT, STATUS_INPUT + */ +#define PB_VOLTAGE_UV_FAULT BIT(4) +#define PB_VOLTAGE_UV_WARNING BIT(5) +#define PB_VOLTAGE_OV_WARNING BIT(6) +#define PB_VOLTAGE_OV_FAULT BIT(7) + +/* + * STATUS_INPUT + */ +#define PB_PIN_OP_WARNING BIT(0) +#define PB_IIN_OC_WARNING BIT(1) +#define PB_IIN_OC_FAULT BIT(2) + +/* + * STATUS_TEMPERATURE + */ +#define PB_TEMP_UT_FAULT BIT(4) +#define PB_TEMP_UT_WARNING BIT(5) +#define PB_TEMP_OT_WARNING BIT(6) +#define PB_TEMP_OT_FAULT BIT(7) + +/* + * STATUS_FAN + */ +#define PB_FAN_AIRFLOW_WARNING BIT(0) +#define PB_FAN_AIRFLOW_FAULT BIT(1) +#define PB_FAN_FAN2_SPEED_OVERRIDE BIT(2) +#define PB_FAN_FAN1_SPEED_OVERRIDE BIT(3) +#define PB_FAN_FAN2_WARNING BIT(4) +#define PB_FAN_FAN1_WARNING BIT(5) +#define PB_FAN_FAN2_FAULT BIT(6) +#define PB_FAN_FAN1_FAULT BIT(7) + +/* + * CML_FAULT_STATUS + */ +#define PB_CML_FAULT_OTHER_MEM_LOGIC BIT(0) +#define PB_CML_FAULT_OTHER_COMM BIT(1) +#define PB_CML_FAULT_PROCESSOR BIT(3) +#define PB_CML_FAULT_MEMORY BIT(4) +#define PB_CML_FAULT_PACKET_ERROR BIT(5) +#define PB_CML_FAULT_INVALID_DATA BIT(6) +#define PB_CML_FAULT_INVALID_COMMAND BIT(7) + +enum pmbus_sensor_classes { + PSC_VOLTAGE_IN = 0, + PSC_VOLTAGE_OUT, + PSC_CURRENT_IN, + PSC_CURRENT_OUT, + PSC_POWER, + PSC_TEMPERATURE, + PSC_FAN, + PSC_NUM_CLASSES /* Number of power sensor classes */ +}; + +#define PMBUS_PAGES 32 /* Per PMBus specification */ + +/* Functionality bit mask */ +#define PMBUS_HAVE_VIN BIT(0) +#define PMBUS_HAVE_VCAP BIT(1) +#define PMBUS_HAVE_VOUT BIT(2) +#define PMBUS_HAVE_IIN BIT(3) +#define PMBUS_HAVE_IOUT BIT(4) +#define PMBUS_HAVE_PIN BIT(5) +#define PMBUS_HAVE_POUT BIT(6) +#define PMBUS_HAVE_FAN12 BIT(7) +#define PMBUS_HAVE_FAN34 BIT(8) +#define PMBUS_HAVE_TEMP BIT(9) +#define PMBUS_HAVE_TEMP2 BIT(10) +#define PMBUS_HAVE_TEMP3 BIT(11) +#define PMBUS_HAVE_STATUS_VOUT BIT(12) +#define PMBUS_HAVE_STATUS_IOUT BIT(13) +#define PMBUS_HAVE_STATUS_INPUT BIT(14) +#define PMBUS_HAVE_STATUS_TEMP BIT(15) +#define PMBUS_HAVE_STATUS_FAN12 BIT(16) +#define PMBUS_HAVE_STATUS_FAN34 BIT(17) +#define PMBUS_HAVE_VMON BIT(18) +#define PMBUS_HAVE_STATUS_VMON BIT(19) + +enum pmbus_data_format { linear = 0, direct, vid }; +enum vrm_version { vr11 = 0, vr12, vr13 }; + +struct pmbus_driver_info { + int pages; /* Total number of pages */ + enum pmbus_data_format format[PSC_NUM_CLASSES]; + enum vrm_version vrm_version; + /* + * Support one set of coefficients for each sensor type + * Used for chips providing data in direct mode. + */ + int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */ + int b[PSC_NUM_CLASSES]; /* offset */ + int R[PSC_NUM_CLASSES]; /* exponent */ + + u32 func[PMBUS_PAGES]; /* Functionality, per page */ + /* + * The following functions map manufacturing specific register values + * to PMBus standard register values. Specify only if mapping is + * necessary. + * Functions return the register value (read) or zero (write) if + * successful. A return value of -ENODATA indicates that there is no + * manufacturer specific register, but that a standard PMBus register + * may exist. Any other negative return value indicates that the + * register does not exist, and that no attempt should be made to read + * the standard register. + */ + int (*read_byte_data)(struct i2c_client *client, int page, int reg); + int (*read_word_data)(struct i2c_client *client, int page, int reg); + int (*write_word_data)(struct i2c_client *client, int page, int reg, + u16 word); + int (*write_byte)(struct i2c_client *client, int page, u8 value); + /* + * The identify function determines supported PMBus functionality. + * This function is only necessary if a chip driver supports multiple + * chips, and the chip functionality is not pre-determined. + */ + int (*identify)(struct i2c_client *client, + struct pmbus_driver_info *info); + + /* Regulator functionality, if supported by this chip driver. */ + int num_regulators; + const struct regulator_desc *reg_desc; +}; + +/* Regulator ops */ + +extern const struct regulator_ops pmbus_regulator_ops; + +/* Macro for filling in array of struct regulator_desc */ +#define PMBUS_REGULATOR(_name, _id) \ + [_id] = { \ + .name = (_name # _id), \ + .id = (_id), \ + .of_match = of_match_ptr(_name # _id), \ + .regulators_node = of_match_ptr("regulators"), \ + .ops = &pmbus_regulator_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + } + +/* Function declarations */ + +void pmbus_clear_cache(struct i2c_client *client); +int pmbus_set_page(struct i2c_client *client, u8 page); +int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg); +int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word); +int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg); +int pmbus_write_byte(struct i2c_client *client, int page, u8 value); +int pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg, + u8 value); +int pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg, + u8 mask, u8 value); +void pmbus_clear_faults(struct i2c_client *client); +bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg); +bool pmbus_check_word_register(struct i2c_client *client, int page, int reg); +int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, + struct pmbus_driver_info *info); +int pmbus_do_remove(struct i2c_client *client); +const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client + *client); + +#endif /* PMBUS_H */ diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/transceiver.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/transceiver.c new file mode 100644 index 000000000000..27c45173eef5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/transceiver.c @@ -0,0 +1,8408 @@ +#include +#include +#include +#include +#include "io_expander.h" +#include "transceiver.h" + +/* For build single module using (Ex: ONL platform) */ +#include +//#include +//#include + +extern int io_no_init; +/* ========== Register EEPROM address mapping ========== + */ +struct eeprom_map_s eeprom_map_sfp = { + .addr_br =0x50, .page_br =-1, .offset_br =12, .length_br =1, + .addr_cdr =-1, .page_cdr =-1, .offset_cdr =-1, .length_cdr =-1, + .addr_comp_rev =0x50, .page_comp_rev =-1, .offset_comp_rev =94, .length_comp_rev =1, + .addr_connector =0x50, .page_connector =-1, .offset_connector =2, .length_connector =1, + .addr_diag_type =0x50, .page_diag_type =-1, .offset_diag_type =92 , .length_diag_type =1, + .addr_extbr =-1, .page_extbr =-1, .offset_extbr =-1, .length_extbr =-1, + .addr_ext_id =0x50, .page_ext_id =-1, .offset_ext_id =1, .length_ext_id =1, + .addr_id =0x50, .page_id =-1, .offset_id =0, .length_id =1, + .addr_len_sm =0x50, .page_len_sm =-1, .offset_len_sm =15, .length_len_sm =1, + .addr_len_smf =0x50, .page_len_smf =-1, .offset_len_smf =14, .length_len_smf =1, + .addr_len_om1 =0x50, .page_len_om1 =-1, .offset_len_om1 =17, .length_len_om1 =1, + .addr_len_om2 =0x50, .page_len_om2 =-1, .offset_len_om2 =16, .length_len_om2 =1, + .addr_len_om3 =0x50, .page_len_om3 =-1, .offset_len_om3 =19, .length_len_om3 =1, + .addr_len_om4 =0x50, .page_len_om4 =-1, .offset_len_om4 =18, .length_len_om4 =1, + .addr_option =0x50, .page_option =-1, .offset_option =64, .length_option =2, + .addr_rate_id =0x50, .page_rate_id =-1, .offset_rate_id =13, .length_rate_id =1, + .addr_rx_am =-1, .page_rx_am =-1, .offset_rx_am =-1, .length_rx_am =-1, + .addr_rx_em =0x51, .page_rx_em =-1, .offset_rx_em =115, .length_rx_em =1, + .addr_rx_los =-1, .page_rx_los =-1, .offset_rx_los =-1, .length_rx_los =-1, + .addr_rx_power =0x51, .page_rx_power =-1, .offset_rx_power =104, .length_rx_power =2, + .addr_soft_rs0 =0x51, .page_soft_rs0 =-1, .offset_soft_rs0 =110, .length_soft_rs0 =1, + .addr_soft_rs1 =0x51, .page_soft_rs1 =-1, .offset_soft_rs1 =118, .length_soft_rs0 =1, + .addr_temp =0x51, .page_temp =-1, .offset_temp =96, .length_temp =2, + .addr_trancomp =0x50, .page_trancomp =-1, .offset_trancomp =3, .length_trancomp =8, + .addr_trancomp_ext =0x50, .page_trancomp_ext =-1, .offset_trancomp_ext =36, .length_trancomp_ext =1, + .addr_tx_bias =0x51, .page_tx_bias =-1, .offset_tx_bias =100, .length_tx_bias =2, + .addr_tx_disable =-1, .page_tx_disable =-1, .offset_tx_disable =-1, .length_tx_disable =-1, + .addr_tx_eq =0x51, .page_tx_eq =-1, .offset_tx_eq =114, .length_tx_eq =1, + .addr_tx_fault =-1, .page_tx_fault =-1, .offset_tx_fault =-1, .length_tx_fault =-1, + .addr_tx_power =0x51, .page_tx_power =-1, .offset_tx_power =102, .length_tx_power =2, + .addr_vendor_name =0x50, .page_vendor_name =-1, .offset_vendor_name =20, .length_vendor_name =16, + .addr_vendor_pn =0x50, .page_vendor_pn =-1, .offset_vendor_pn =40, .length_vendor_pn =16, + .addr_vendor_rev =0x50, .page_vendor_rev =-1, .offset_vendor_rev =56, .length_vendor_rev =4, + .addr_vendor_sn =0x50, .page_vendor_sn =-1, .offset_vendor_sn =68, .length_vendor_sn =16, + .addr_voltage =0x51, .page_voltage =-1, .offset_voltage =98, .length_voltage =2, + .addr_wavelength =0x50, .page_wavelength =-1, .offset_wavelength =60, .length_wavelength =2, +}; + +struct eeprom_map_s eeprom_map_qsfp = { + .addr_br =0x50, .page_br =0, .offset_br =140, .length_br =1, + .addr_cdr =-1, .page_cdr =-1, .offset_cdr =-1, .length_cdr =-1, + .addr_comp_rev =0x50, .page_comp_rev =-1, .offset_comp_rev =1, .length_comp_rev =1, + .addr_connector =0x50, .page_connector =0, .offset_connector =130, .length_connector =1, + .addr_diag_type =0x50, .page_diag_type =0, .offset_diag_type =220, .length_diag_type =1, + .addr_extbr =0x50, .page_extbr =0, .offset_extbr =222, .length_extbr =1, + .addr_ext_id =0x50, .page_ext_id =0, .offset_ext_id =129, .length_ext_id =1, + .addr_id =0x50, .page_id =0, .offset_id =128, .length_id =1, + .addr_len_sm =-1, .page_len_sm =-1, .offset_len_sm =-1, .length_len_sm =-1, + .addr_len_smf =0x50, .page_len_smf =0, .offset_len_smf =142, .length_len_smf =1, + .addr_len_om1 =0x50, .page_len_om1 =0, .offset_len_om1 =145, .length_len_om1 =1, + .addr_len_om2 =0x50, .page_len_om2 =0, .offset_len_om2 =144, .length_len_om2 =1, + .addr_len_om3 =0x50, .page_len_om3 =0, .offset_len_om3 =143, .length_len_om3 =1, + .addr_len_om4 =0x50, .page_len_om4 =0, .offset_len_om4 =146, .length_len_om4 =1, + .addr_option =0x50, .page_option =0, .offset_option =193, .length_option =3, + .addr_rate_id =-1, .page_rate_id =-1, .offset_rate_id =-1, .length_rate_id =-1, + .addr_rx_am =-1, .page_rx_am =-1, .offset_rx_am =-1, .length_rx_am =-1, + .addr_rx_em =-1, .page_rx_em =-1, .offset_rx_em =-1, .length_rx_em =-1, + .addr_rx_los =0x50, .page_rx_los =-1, .offset_rx_los =3, .length_rx_los =1, + .addr_rx_power =0x50, .page_rx_power =-1, .offset_rx_power =34, .length_rx_power =8, + .addr_soft_rs0 =-1, .page_soft_rs0 =-1, .offset_soft_rs0 =-1, .length_soft_rs0 =-1, + .addr_soft_rs1 =-1, .page_soft_rs1 =-1, .offset_soft_rs1 =-1, .length_soft_rs0 =-1, + .addr_temp =0x50, .page_temp =-1, .offset_temp =22, .length_temp =2, + .addr_trancomp =0x50, .page_trancomp =0, .offset_trancomp =131, .length_trancomp =8, + .addr_trancomp_ext =0x50, .page_trancomp_ext =0, .offset_trancomp_ext =192, .length_trancomp_ext =1, + .addr_tx_bias =0x50, .page_tx_bias =-1, .offset_tx_bias =42, .length_tx_bias =8, + .addr_tx_disable =0x50, .page_tx_disable =-1, .offset_tx_disable =86, .length_tx_disable =1, + .addr_tx_eq =-1, .page_tx_eq =-1, .offset_tx_eq =-1, .length_tx_eq =-1, + .addr_tx_fault =0x50, .page_tx_fault =-1, .offset_tx_fault =4, .length_tx_fault =1, + .addr_tx_power =0x50, .page_tx_power =-1, .offset_tx_power =50, .length_tx_power =8, + .addr_vendor_name =0x50, .page_vendor_name =0, .offset_vendor_name =148, .length_vendor_name =16, + .addr_vendor_pn =0x50, .page_vendor_pn =0, .offset_vendor_pn =168, .length_vendor_pn =16, + .addr_vendor_rev =0x50, .page_vendor_rev =0, .offset_vendor_rev =184, .length_vendor_rev =2, + .addr_vendor_sn =0x50, .page_vendor_sn =0, .offset_vendor_sn =196, .length_vendor_sn =16, + .addr_voltage =0x50, .page_voltage =-1, .offset_voltage =26, .length_voltage =2, + .addr_wavelength =0x50, .page_wavelength =0, .offset_wavelength =186, .length_wavelength =2, +}; + +struct eeprom_map_s eeprom_map_qsfp28 = { + .addr_br =0x50, .page_br =0, .offset_br =140, .length_br =1, + .addr_cdr =0x50, .page_cdr =-1, .offset_cdr =98, .length_cdr =1, + .addr_comp_rev =0x50, .page_comp_rev =-1, .offset_comp_rev =1, .length_comp_rev =1, + .addr_connector =0x50, .page_connector =0, .offset_connector =130, .length_connector =1, + .addr_diag_type =0x50, .page_diag_type =0, .offset_diag_type =220, .length_diag_type =1, + .addr_extbr =0x50, .page_extbr =0, .offset_extbr =222, .length_extbr =1, + .addr_ext_id =0x50, .page_ext_id =0, .offset_ext_id =129, .length_ext_id =1, + .addr_id =0x50, .page_id =0, .offset_id =128, .length_id =1, + .addr_len_sm =-1, .page_len_sm =-1, .offset_len_sm =-1, .length_len_sm =-1, + .addr_len_smf =0x50, .page_len_smf =0, .offset_len_smf =142, .length_len_smf =1, + .addr_len_om1 =0x50, .page_len_om1 =0, .offset_len_om1 =145, .length_len_om1 =1, + .addr_len_om2 =0x50, .page_len_om2 =0, .offset_len_om2 =144, .length_len_om2 =1, + .addr_len_om3 =0x50, .page_len_om3 =0, .offset_len_om3 =143, .length_len_om3 =1, + .addr_len_om4 =0x50, .page_len_om4 =0, .offset_len_om4 =146, .length_len_om4 =1, + .addr_option =0x50, .page_option =0, .offset_option =193, .length_option =3, + .addr_rate_id =-1, .page_rate_id =-1, .offset_rate_id =-1, .length_rate_id =-1, + .addr_rx_am =0x50, .page_rx_am =3, .offset_rx_am =238, .length_rx_am =2, + .addr_rx_em =0x50, .page_rx_em =3, .offset_rx_em =236, .length_rx_em =2, + .addr_rx_los =0x50, .page_rx_los =-1, .offset_rx_los =3, .length_rx_los =1, + .addr_rx_power =0x50, .page_rx_power =-1, .offset_rx_power =34, .length_rx_power =8, + .addr_soft_rs0 =-1, .page_soft_rs0 =-1, .offset_soft_rs0 =-1, .length_soft_rs0 =-1, + .addr_soft_rs1 =-1, .page_soft_rs1 =-1, .offset_soft_rs1 =-1, .length_soft_rs0 =-1, + .addr_temp =0x50, .page_temp =-1, .offset_temp =22, .length_temp =2, + .addr_trancomp =0x50, .page_trancomp =0, .offset_trancomp =131, .length_trancomp =8, + .addr_trancomp_ext =0x50, .page_trancomp_ext =0, .offset_trancomp_ext =192, .length_trancomp_ext =1, + .addr_tx_bias =0x50, .page_tx_bias =-1, .offset_tx_bias =42, .length_tx_bias =8, + .addr_tx_disable =0x50, .page_tx_disable =-1, .offset_tx_disable =86, .length_tx_disable =1, + .addr_tx_eq =0x50, .page_tx_eq =3, .offset_tx_eq =234, .length_tx_eq =2, + .addr_tx_fault =0x50, .page_tx_fault =-1, .offset_tx_fault =4, .length_tx_fault =1, + .addr_tx_power =0x50, .page_tx_power =-1, .offset_tx_power =50, .length_tx_power =8, + .addr_vendor_name =0x50, .page_vendor_name =0, .offset_vendor_name =148, .length_vendor_name =16, + .addr_vendor_pn =0x50, .page_vendor_pn =0, .offset_vendor_pn =168, .length_vendor_pn =16, + .addr_vendor_rev =0x50, .page_vendor_rev =0, .offset_vendor_rev =184, .length_vendor_rev =2, + .addr_vendor_sn =0x50, .page_vendor_sn =0, .offset_vendor_sn =196, .length_vendor_sn =16, + .addr_voltage =0x50, .page_voltage =-1, .offset_voltage =26, .length_voltage =2, + .addr_wavelength =0x50, .page_wavelength =0, .offset_wavelength =186, .length_wavelength =2, +}; + + +/* ========== Utility Functions ========== + */ +static int +get_bit(uint8_t origin_byte, int bit_shift) { + return (int)((origin_byte >> bit_shift) & 0x1); +} + +static int +transform_word_to_int(uint8_t hight_byte, + uint8_t low_byte) { + return ((((int)hight_byte) << 8) + (int)low_byte); +} + +void +alarm_msg_2_user(struct transvr_obj_s *self, + char *emsg) { + + SWPS_ERR("%s on %s.\n", emsg, self->swp_name); +} +EXPORT_SYMBOL(alarm_msg_2_user); + +/* ========== Private functions ========== + */ +static int +_reload_transvr_obj(struct transvr_obj_s *self,int new_type); + +static int +reload_transvr_obj(struct transvr_obj_s *self,int new_type); + +static int +_is_transvr_support_ctle(struct transvr_obj_s *self); + +static int +_transvr_init_handler(struct transvr_obj_s *self); + +int +_transvr_clean_handler(struct transvr_obj_s *self); + +int +_sfp_detect_class_by_1g_ethernet(struct transvr_obj_s* self); + + +void +lock_transvr_obj(struct transvr_obj_s *self) { + + mutex_lock(&self->lock); + self->curr_page = VAL_TRANSVR_PAGE_FREE; +} +EXPORT_SYMBOL(lock_transvr_obj); + + +void +unlock_transvr_obj(struct transvr_obj_s *self) { + + self->curr_page = VAL_TRANSVR_PAGE_FREE; + mutex_unlock(&self->lock); +} +EXPORT_SYMBOL(unlock_transvr_obj); + + +static int +_check_by_mode(struct transvr_obj_s *self, + int (*attr_update_func)(struct transvr_obj_s *self, int show_err), + char *caller_name){ + + int return_val = ERR_TRANSVR_UNEXCPT; + + switch (self->mode){ + case TRANSVR_MODE_POLLING: + switch (self->state){ + case STATE_TRANSVR_CONNECTED: + goto ok_check_by_mode_1; + case STATE_TRANSVR_NEW: + case STATE_TRANSVR_INIT: + return ERR_TRANSVR_UNINIT; + case STATE_TRANSVR_DISCONNECTED: + return ERR_TRANSVR_UNPLUGGED; + case STATE_TRANSVR_UNEXCEPTED: + return ERR_TRANSVR_ABNORMAL; + case STATE_TRANSVR_ISOLATED: + return ERR_TRNASVR_BE_ISOLATED; + default: + goto err_check_by_mode_1; + } + goto ok_check_by_mode_1; + + case TRANSVR_MODE_DIRECT: + return_val = self->fsm_4_direct(self, caller_name); + if (return_val < 0){ + return return_val; + } + goto ok_check_by_mode_1; + + default: + goto err_check_by_mode_1; + } + goto ok_check_by_mode_1; + +ok_check_by_mode_1: + return attr_update_func(self, 0); + +err_check_by_mode_1: + SWPS_INFO("_check_by_mode: mode:%d state:%d\n", self->mode, self->state); + return ERR_TRANSVR_UNEXCPT; +} + + +static void +_transvr_clean_retry(struct transvr_obj_s *self) { + self->retry = 0; +} + + +static int +_transvr_handle_retry(struct transvr_obj_s *self, int retry) { + /* Return: 0: keep retry + * -1: stop retry + */ + if (self->retry == 0) { + self->retry = retry; + } + self->retry -= 1; + if (self->retry <= 0) { + _transvr_clean_retry(self); + return -1; + } + return 0; +} + + +static int +_common_setup_page(struct transvr_obj_s *self, + int addr, + int page, + int offset, + int len, + int show_e) { + /* return: + * 0 : OK + * -1 : EEPROM settings incorrect + * -2 : I2C R/W failure + * -3 : Undefined case + */ + int retval = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + /* Check */ + if ((addr < 0) || (offset < 0) || (len < 0)) { + emsg = "EEPROM settings incorrect"; + retval = -1; + goto err_common_setup_page; + } + /* Case1: continue access */ + if ((self->i2c_client_p->addr == addr) && + (self->curr_page == page)) { + return 0; + } + self->i2c_client_p->addr = addr; + /* Case2: select lower page */ + if (page == -1) { + self->curr_page = page; + return 0; + } + /* Case3: select upper page */ + if (page >= 0) { + goto upper_common_setup_page; + } + /* Unexpected case */ + show_e = 1; + emsg = "Unexpected case"; + retval = -3; + goto err_common_setup_page; + +upper_common_setup_page: + if (i2c_smbus_write_byte_data(self->i2c_client_p, + VAL_TRANSVR_PAGE_SELECT_OFFSET, + page) < 0) { + emsg = "I2C R/W failure"; + retval = -2; + goto err_common_setup_page; + } + self->curr_page = page; + mdelay(VAL_TRANSVR_PAGE_SELECT_DELAY); + return 0; + +err_common_setup_page: + if (show_e) { + SWPS_INFO("%s: %s", __func__, emsg); + SWPS_INFO("%s: :0x%02x :%d :%d :%d\n", + __func__, addr, page, offset, len); + } + return retval; +} + +/* +static int +_common_setup_password(struct transvr_obj_s *self, + int addr, + int page, + int offs, + uint8_t pwd[4], + int show_e) { + int i = 0; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + err = _common_setup_page(self, addr, page, offs, 4, show_e); + if (err < 0){ + emsg = "setup EEPROM page fail"; + goto err_common_setup_password; + } + for (i=0; i<4; i++) { + err = i2c_smbus_write_byte_data(self->i2c_client_p, + (offs + i), + pwd[i]); + if (err < 0){ + emsg = "I2C R/W fail!"; + goto err_common_setup_password; + } + } + return 0; + +err_common_setup_password: + if (show_e) { + SWPS_INFO("%s: %s :%d\n", __func__, emsg, err); + } + return ERR_TRANSVR_UPDATE_FAIL; +} +*/ + +static int +_common_update_uint8_attr(struct transvr_obj_s *self, + int addr, + int page, + int offset, + int len, + uint8_t *buf, + char *caller, + int show_e){ + + int i; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + err = _common_setup_page(self, addr, page, offset, len, show_e); + if (err < 0){ + emsg = "setup EEPROM page fail"; + goto err_common_update_uint8_attr; + } + for (i=0; ii2c_client_p, (offset + i)); + if (err < 0){ + emsg = "I2C R/W fail!"; + goto err_common_update_uint8_attr; + } + buf[i] = err; + } + return 0; + +err_common_update_uint8_attr: + if (show_e) { + SWPS_INFO("%s: %s :%s :%d\n", + __func__, emsg, caller, err); + } + buf[0] = DEBUG_TRANSVR_HEX_VAL; + return ERR_TRANSVR_UPDATE_FAIL; +} + + +static int +_common_update_int_attr(struct transvr_obj_s *self, + int addr, + int page, + int offset, + int len, + int *buf, + char *caller, + int show_e){ + + int i; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + err = _common_setup_page(self, addr, page, offset, len, show_e); + if (err < 0){ + emsg = "setup EEPROM page fail"; + goto err_common_update_int_attr; + } + for (i=0; ii2c_client_p, (offset + i)); + if (err < 0){ + emsg = "I2C R/W fail!"; + goto err_common_update_int_attr; + } + buf[i] = (int)err; + } + return 0; + +err_common_update_int_attr: + if (show_e) { + SWPS_INFO("%s: %s :%s :%d\n", + __func__, emsg, caller, err); + } + buf[0] = DEBUG_TRANSVR_INT_VAL; + return ERR_TRANSVR_UPDATE_FAIL; +} + + +static int +_common_update_string_attr(struct transvr_obj_s *self, + int addr, + int page, + int offset, + int len, + char buf[], + char *caller, + int show_e){ + + int i; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + err = _common_setup_page(self, addr, page, offset, len, show_e); + if (err < 0){ + emsg = "setup EEPROM page fail"; + goto err_common_update_string_attr; + } + for (i=0; ii2c_client_p, (offset + i)); + if (err < 0){ + emsg = "I2C R/W fail!"; + goto err_common_update_string_attr; + } + buf[i] = (char)err; + } + return 0; + +err_common_update_string_attr: + if (show_e) { + SWPS_INFO("%s: %s :%s :%d\n", + __func__, emsg, caller, err); + } + buf[0] = 'e'; + return ERR_TRANSVR_UPDATE_FAIL; +} + + +static int +_common_set_uint8_attr(struct transvr_obj_s *self, + int addr, + int page, + int offset, + uint8_t update, + uint8_t *buf, + char *caller, + int show_e){ + int len = 1; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + if ((*buf) == update){ + return 0; + } + err = _common_setup_page(self, addr, page, offset, len, show_e); + if (err < 0){ + emsg = "setup EEPROM page fail"; + goto err_common_set_uint8_attr_1; + } + err = i2c_smbus_write_byte_data(self->i2c_client_p, + offset, + update); + if (err < 0){ + emsg = "I2C R/W fail!"; + goto err_common_set_uint8_attr_1; + } + (*buf) = update; + return 0; + +err_common_set_uint8_attr_1: + if (show_e) { + SWPS_INFO("%s: %s :%s :%d\n", + __func__, emsg, caller, err); + } + return ERR_TRANSVR_UPDATE_FAIL; +} + + +static int +_common_set_uint8_array(struct transvr_obj_s *self, + int addr, + int page, + int offs, + int len, + uint8_t update[], + uint8_t buf[], + char *caller, + int show_e){ + int i = 0; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + err = _common_setup_page(self, addr, page, offs, len, show_e); + if (err < 0){ + emsg = "setup EEPROM page fail"; + goto err_common_set_uint8_attr_1; + } + for (i=0; ii2c_client_p, + (offs + i), + update[i]); + if (err < 0){ + emsg = "I2C R/W fail!"; + goto err_common_set_uint8_attr_1; + } + buf[i] = update[i]; + } + return 0; + +err_common_set_uint8_attr_1: + if (show_e) { + SWPS_INFO("%s: %s :%s :%d :%d\n", + __func__, emsg, caller, err, i); + } + return ERR_TRANSVR_UPDATE_FAIL; +} + + +static int +_common_update_attr_id(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_id, + self->eeprom_map_p->page_id, + self->eeprom_map_p->offset_id, + self->eeprom_map_p->length_id, + &(self->id), + "_common_update_attr_id", + show_err); +} + + +static int +_common_update_attr_extended_id(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_ext_id, + self->eeprom_map_p->page_ext_id, + self->eeprom_map_p->offset_ext_id, + self->eeprom_map_p->length_ext_id, + &(self->ext_id), + "_common_update_attr_extended_id", + show_err); +} + + +static int +_common_update_attr_connector(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_connector, + self->eeprom_map_p->page_connector, + self->eeprom_map_p->offset_connector, + self->eeprom_map_p->length_connector, + &(self->connector), + "_common_update_attr_connector", + show_err); +} + + +static int +_common_update_attr_transvr_comp(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_trancomp, + self->eeprom_map_p->page_trancomp, + self->eeprom_map_p->offset_trancomp, + self->eeprom_map_p->length_trancomp, + self->transvr_comp, + "_common_update_attr_transvr_comp", + show_err); +} + + +static int +_common_update_attr_transvr_comp_ext(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_trancomp_ext, + self->eeprom_map_p->page_trancomp_ext, + self->eeprom_map_p->offset_trancomp_ext, + self->eeprom_map_p->length_trancomp_ext, + &(self->transvr_comp_ext), + "_common_update_attr_transvr_comp_ext", + show_err); +} + + +static int +_common_update_attr_vendor_name(struct transvr_obj_s *self, + int show_err){ + return _common_update_string_attr(self, + self->eeprom_map_p->addr_vendor_name, + self->eeprom_map_p->page_vendor_name, + self->eeprom_map_p->offset_vendor_name, + self->eeprom_map_p->length_vendor_name, + self->vendor_name, + "_common_update_attr_vendor_name", + show_err); +} + + +static int +_common_update_attr_vendor_pn(struct transvr_obj_s *self, + int show_err){ + return _common_update_string_attr(self, + self->eeprom_map_p->addr_vendor_pn, + self->eeprom_map_p->page_vendor_pn, + self->eeprom_map_p->offset_vendor_pn, + self->eeprom_map_p->length_vendor_pn, + self->vendor_pn, + "_common_update_attr_vendor_pn", + show_err); +} + + +static int +_common_update_attr_vendor_rev(struct transvr_obj_s *self, + int show_err){ + return _common_update_string_attr(self, + self->eeprom_map_p->addr_vendor_rev, + self->eeprom_map_p->page_vendor_rev, + self->eeprom_map_p->offset_vendor_rev, + self->eeprom_map_p->length_vendor_rev, + self->vendor_rev, + "_common_update_attr_vendor_rev", + show_err); +} + + +static int +_common_update_attr_vendor_sn(struct transvr_obj_s *self, + int show_err){ + return _common_update_string_attr(self, + self->eeprom_map_p->addr_vendor_sn, + self->eeprom_map_p->page_vendor_sn, + self->eeprom_map_p->offset_vendor_sn, + self->eeprom_map_p->length_vendor_sn, + self->vendor_sn, + "_common_update_attr_vendor_sn", + show_err); +} + + +static int +_common_update_attr_br(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_br, + self->eeprom_map_p->page_br, + self->eeprom_map_p->offset_br, + self->eeprom_map_p->length_br, + &(self->br), + "_common_update_attr_br", + show_err); +} + + +static int +_common_update_attr_len_smf(struct transvr_obj_s *self, + int show_err){ + return _common_update_int_attr(self, + self->eeprom_map_p->addr_len_smf, + self->eeprom_map_p->page_len_smf, + self->eeprom_map_p->offset_len_smf, + self->eeprom_map_p->length_len_smf, + &(self->len_smf), + "_common_update_attr_len_smf", + show_err); +} + + +static int +_common_update_attr_len_om1(struct transvr_obj_s *self, + int show_err){ + return _common_update_int_attr(self, + self->eeprom_map_p->addr_len_om1, + self->eeprom_map_p->page_len_om1, + self->eeprom_map_p->offset_len_om1, + self->eeprom_map_p->length_len_om1, + &(self->len_om1), + "_common_update_attr_len_om1", + show_err); +} + +static int +_common_update_attr_len_om2(struct transvr_obj_s *self, + int show_err){ + return _common_update_int_attr(self, + self->eeprom_map_p->addr_len_om2, + self->eeprom_map_p->page_len_om2, + self->eeprom_map_p->offset_len_om2, + self->eeprom_map_p->length_len_om2, + &(self->len_om2), + "_common_update_attr_len_om2", + show_err); +} + +static int +_common_update_attr_len_om3(struct transvr_obj_s *self, + int show_err){ + return _common_update_int_attr(self, + self->eeprom_map_p->addr_len_om3, + self->eeprom_map_p->page_len_om3, + self->eeprom_map_p->offset_len_om3, + self->eeprom_map_p->length_len_om3, + &(self->len_om3), + "_common_update_attr_len_om3", + show_err); +} + + +static int +_common_update_attr_len_om4(struct transvr_obj_s *self, + int show_err){ + return _common_update_int_attr(self, + self->eeprom_map_p->addr_len_om4, + self->eeprom_map_p->page_len_om4, + self->eeprom_map_p->offset_len_om4, + self->eeprom_map_p->length_len_om4, + &(self->len_om4), + "_common_update_attr_len_om4", + show_err); +} + + +static int +_common_update_attr_option(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_option, + self->eeprom_map_p->page_option, + self->eeprom_map_p->offset_option, + self->eeprom_map_p->length_option, + self->option, + "_common_update_attr_option", + show_err); +} + + +static int +_common_update_attr_comp_rev(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_comp_rev, + self->eeprom_map_p->page_comp_rev, + self->eeprom_map_p->offset_comp_rev, + self->eeprom_map_p->length_comp_rev, + &(self->comp_rev), + "_common_update_attr_comp_rev", + show_err); +} + + +static int +_common_update_attr_diag_type(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_diag_type, + self->eeprom_map_p->page_diag_type, + self->eeprom_map_p->offset_diag_type, + self->eeprom_map_p->length_diag_type, + &(self->diag_type), + "_common_update_attr_diag_type", + show_err); +} + + +static int +_common_update_attr_wavelength(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_wavelength, + self->eeprom_map_p->page_wavelength, + self->eeprom_map_p->offset_wavelength, + self->eeprom_map_p->length_wavelength, + self->wavelength, + "_common_update_attr_wavelength", + show_err); +} + + +int +_common_get_option_value(struct transvr_obj_s *self, + int offset, + int bit_shift) { + /* SFP: + * - option[0] = A0h / 64 + * - option[1] = A0h / 65 + * QSFP: + * - option[0] = 00h / 193 + * - option[1] = 00h / 194 + * - option[2] = 00h / 195 + */ + return (self->option[offset] & (1 << bit_shift)); +} + + +static int +_sfp_update_attr_len_sm(struct transvr_obj_s *self, + int show_err){ + return _common_update_int_attr(self, + self->eeprom_map_p->addr_len_sm, + self->eeprom_map_p->page_len_sm, + self->eeprom_map_p->offset_len_sm, + self->eeprom_map_p->length_len_sm, + &(self->len_sm), + "_common_update_attr_len_sm", + show_err); +} + + +static int +_sfp_update_attr_rate_id(struct transvr_obj_s *self, + int show_err){ + return _common_update_int_attr(self, + self->eeprom_map_p->addr_rate_id, + self->eeprom_map_p->page_rate_id, + self->eeprom_map_p->offset_rate_id, + self->eeprom_map_p->length_rate_id, + &(self->rate_id), + "_sfp_update_attr_rate_id", + show_err); +} + + +static int +_sfp_update_attr_soft_rs0(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_soft_rs0, + self->eeprom_map_p->page_soft_rs0, + self->eeprom_map_p->offset_soft_rs0, + self->eeprom_map_p->length_soft_rs0, + &(self->soft_rs0), + "_sfp_update_attr_soft_rs0", + show_err); +} + + +static int +_sfp_update_attr_soft_rs1(struct transvr_obj_s *self, + int show_err){ + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_soft_rs1, + self->eeprom_map_p->page_soft_rs1, + self->eeprom_map_p->offset_soft_rs1, + self->eeprom_map_p->length_soft_rs1, + &(self->soft_rs1), + "_sfp_update_attr_soft_rs1", + show_err); +} + + +int +_sfp_is_diag_support(struct transvr_obj_s *self){ + + uint8_t bit_mask = 0xC0; /* 1100 0000 */ + uint8_t en_val = 0x40; /* 0100 0000 */ + uint8_t checkval = (self->diag_type & bit_mask); + + if (checkval == en_val) { + return 1; + } + return 0; +} + + +static int +_sfp_update_attr_curr_temp(struct transvr_obj_s *self, + int show_err){ + + if (!(_sfp_is_diag_support(self))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_temp, + self->eeprom_map_p->page_temp, + self->eeprom_map_p->offset_temp, + self->eeprom_map_p->length_temp, + self->curr_temp, + "_sfp_update_attr_curr_temp", + show_err); +} + + +static int +_sfp_update_attr_curr_voltage(struct transvr_obj_s *self, + int show_err){ + + if (!(_sfp_is_diag_support(self))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_voltage, + self->eeprom_map_p->page_voltage, + self->eeprom_map_p->offset_voltage, + self->eeprom_map_p->length_voltage, + self->curr_voltage, + "_sfp_update_attr_curr_voltage", + show_err); +} + + +static int +_sfp_update_attr_curr_tx_bias(struct transvr_obj_s *self, + int show_err){ + + if (!(_sfp_is_diag_support(self))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_bias, + self->eeprom_map_p->page_tx_bias, + self->eeprom_map_p->offset_tx_bias, + self->eeprom_map_p->length_tx_bias, + self->curr_tx_bias, + "_sfp_update_attr_curr_tx_bias", + show_err); +} + + +static int +_sfp_update_attr_curr_tx_power(struct transvr_obj_s *self, + int show_err){ + + if (!(_sfp_is_diag_support(self))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_power, + self->eeprom_map_p->page_tx_power, + self->eeprom_map_p->offset_tx_power, + self->eeprom_map_p->length_tx_power, + self->curr_tx_power, + "_sfp_update_attr_curr_tx_power", + show_err); +} + + +static int +_sfp_update_attr_curr_rx_power(struct transvr_obj_s *self, + int show_err){ + + if (!(_sfp_is_diag_support(self))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_rx_power, + self->eeprom_map_p->page_rx_power, + self->eeprom_map_p->offset_rx_power, + self->eeprom_map_p->length_rx_power, + self->curr_rx_power, + "_sfp_update_attr_curr_rx_power", + show_err); +} + + +static int +_sfp_update_attr_rx_em(struct transvr_obj_s *self, + int show_err){ + + if (!_is_transvr_support_ctle(self)) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_rx_em, + self->eeprom_map_p->page_rx_em, + self->eeprom_map_p->offset_rx_em, + self->eeprom_map_p->length_rx_em, + self->rx_em, + "_sfp_update_attr_rx_em", + show_err); +} + + +static int +_sfp_update_attr_tx_eq(struct transvr_obj_s *self, + int show_err){ + + if (!_is_transvr_support_ctle(self)) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_eq, + self->eeprom_map_p->page_tx_eq, + self->eeprom_map_p->offset_tx_eq, + self->eeprom_map_p->length_tx_eq, + self->tx_eq, + "_sfp_update_attr_tx_eq", + show_err); +} + + +static int +_qsfp_update_attr_cdr(struct transvr_obj_s *self, + int show_err){ + if (self->type != TRANSVR_TYPE_QSFP_28){ + self->cdr = DEBUG_TRANSVR_HEX_VAL; + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_cdr, + self->eeprom_map_p->page_cdr, + self->eeprom_map_p->offset_cdr, + self->eeprom_map_p->length_cdr, + &(self->cdr), + "_common_update_attr_cdr", + show_err); +} + + +static int +_qsfg_update_attr_extbr(struct transvr_obj_s *self, + int show_err) { + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_extbr, + self->eeprom_map_p->page_extbr, + self->eeprom_map_p->offset_extbr, + self->eeprom_map_p->length_extbr, + &(self->extbr), + "_common_update_attr_extbr", + show_err); +} + + +static int +_qsfp_is_diag_support(struct transvr_obj_s *self, + int diag_type) { + /* Input Parm: diag_type + * => 1 : temperature + * => 2 : voltage + * => 3 : tx relate + * => 4 : rx relate + */ + uint8_t mask_b2 = 0x04; /* 0000 0100 */ + uint8_t mask_b3 = 0x08; /* 0000 1000 */ + + switch (diag_type) { + case 1: /* temperature */ + case 2: /* voltage */ + /* Direct access target, because of spec not defined */ + return 1; + case 3: + case 4: + /* [Note] + * Due to lot of transceiver vendor defined it not rigorously and + * consider of general support, we seem it as supported if there + * are bit-2 OR bit-3 defined by transceiver vendor. + */ + if ( ((self->diag_type & mask_b2) == mask_b2 ) || + ((self->diag_type & mask_b3) == mask_b3 ) ){ + return 1; + } + return 0; + default: + SWPS_INFO("%s: undefined diag_type:%d\n", + __func__, diag_type); + break; + } + return 0; +} + + +int +_qsfp_is_implement_tx_disable(struct transvr_obj_s *self) { + /* + * 00h / Byte-195 / Bit-4 + */ + int byte = 2; + int bit = 4; + return _common_get_option_value(self, byte, bit); +} + + +int +_qsfp_is_implement_tx_fault(struct transvr_obj_s *self) { + /* + * 00h / Byte-195 / Bit-3 + */ + int byte = 2; + int bit = 3; + return _common_get_option_value(self, byte, bit); +} + + +static int +_qsfp_update_attr_curr_temp(struct transvr_obj_s *self, + int show_err){ + int diag_type = 1; + + if (!(_qsfp_is_diag_support(self, diag_type))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_temp, + self->eeprom_map_p->page_temp, + self->eeprom_map_p->offset_temp, + self->eeprom_map_p->length_temp, + self->curr_temp, + "_qsfp_update_attr_curr_temp", + show_err); +} + + +static int +_qsfp_update_attr_curr_voltage(struct transvr_obj_s *self, + int show_err){ + int diag_type = 2; + + if (!(_qsfp_is_diag_support(self, diag_type))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_voltage, + self->eeprom_map_p->page_voltage, + self->eeprom_map_p->offset_voltage, + self->eeprom_map_p->length_voltage, + self->curr_voltage, + "_qsfp_update_attr_curr_voltage", + show_err); +} + + +static int +_qsfp_update_attr_curr_tx_bias(struct transvr_obj_s *self, + int show_err){ + int diag_type = 3; + + if (!(_qsfp_is_diag_support(self, diag_type))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_bias, + self->eeprom_map_p->page_tx_bias, + self->eeprom_map_p->offset_tx_bias, + self->eeprom_map_p->length_tx_bias, + self->curr_tx_bias, + "_qsfp_update_attr_curr_tx_bias", + show_err); +} + + +static int +_qsfp_update_attr_curr_tx_power(struct transvr_obj_s *self, + int show_err){ + int diag_type = 3; + + if (!(_qsfp_is_diag_support(self, diag_type))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_power, + self->eeprom_map_p->page_tx_power, + self->eeprom_map_p->offset_tx_power, + self->eeprom_map_p->length_tx_power, + self->curr_tx_power, + "_qsfp_update_attr_curr_tx_power", + show_err); +} + + +static int +_qsfp_update_attr_curr_rx_power(struct transvr_obj_s *self, + int show_err){ + int diag_type = 4; + + if (!(_qsfp_is_diag_support(self, diag_type))) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_rx_power, + self->eeprom_map_p->page_rx_power, + self->eeprom_map_p->offset_rx_power, + self->eeprom_map_p->length_rx_power, + self->curr_rx_power, + "_qsfp_update_attr_curr_rx_power", + show_err); +} + + +static int +_qsfp_update_attr_soft_rx_los(struct transvr_obj_s *self, + int show_err){ + + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_rx_los, + self->eeprom_map_p->page_rx_los, + self->eeprom_map_p->offset_rx_los, + self->eeprom_map_p->length_rx_los, + &(self->rx_los), + "_qsfp_update_attr_soft_rx_los", + show_err); +} + + +static int +_qsfp_update_attr_soft_tx_disable(struct transvr_obj_s *self, + int show_err){ + + if (!_qsfp_is_implement_tx_disable(self)) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_disable, + self->eeprom_map_p->page_tx_disable, + self->eeprom_map_p->offset_tx_disable, + self->eeprom_map_p->length_tx_disable, + &(self->tx_disable), + "_qsfp_update_attr_soft_tx_disable", + show_err); +} + + +static int +_qsfp_update_attr_soft_tx_fault(struct transvr_obj_s *self, + int show_err){ + + if (!_qsfp_is_implement_tx_fault(self)) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_fault, + self->eeprom_map_p->page_tx_fault, + self->eeprom_map_p->offset_tx_fault, + self->eeprom_map_p->length_tx_fault, + &(self->tx_fault), + "_qsfp_update_attr_soft_tx_fault", + show_err); +} + + +static int +_qsfp_update_attr_tx_eq(struct transvr_obj_s *self, + int show_err){ + + if (!_is_transvr_support_ctle(self)) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_eq, + self->eeprom_map_p->page_tx_eq, + self->eeprom_map_p->offset_tx_eq, + self->eeprom_map_p->length_tx_eq, + self->tx_eq, + "_qsfp_update_attr_tx_eq", + show_err); +} + + +static int +_qsfp_update_attr_rx_am(struct transvr_obj_s *self, + int show_err){ + + if (!_is_transvr_support_ctle(self)) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_rx_am, + self->eeprom_map_p->page_rx_am, + self->eeprom_map_p->offset_rx_am, + self->eeprom_map_p->length_rx_am, + self->rx_am, + "_qsfp_update_attr_rx_am", + show_err); +} + + +static int +_qsfp_update_attr_rx_em(struct transvr_obj_s *self, + int show_err){ + + if (!_is_transvr_support_ctle(self)) { + return ERR_TRANSVR_NOTSUPPORT; + } + return _common_update_uint8_attr(self, + self->eeprom_map_p->addr_rx_em, + self->eeprom_map_p->page_rx_em, + self->eeprom_map_p->offset_rx_em, + self->eeprom_map_p->length_rx_em, + self->rx_em, + "_qsfp_update_attr_rx_em", + show_err); +} + + +int +_common_update_attr_all(struct transvr_obj_s *self, + int show_err){ + + char *err_str = "err"; + + if (_common_update_attr_id(self, show_err) < 0) { + err_str = "_common_update_attr_id"; + goto err_common_update_attr_all; + } + if (_common_update_attr_extended_id(self, show_err) < 0) { + err_str = "_common_update_attr_extended_id"; + goto err_common_update_attr_all; + } + if (_common_update_attr_connector(self, show_err) < 0) { + err_str = "_common_update_attr_connector"; + goto err_common_update_attr_all; + } + if (_common_update_attr_transvr_comp(self, show_err) < 0) { + err_str = "_common_update_attr_transvr_comp"; + goto err_common_update_attr_all; + } + if (_common_update_attr_transvr_comp_ext(self, show_err) < 0) { + err_str = "_common_update_attr_transvr_comp_ext"; + goto err_common_update_attr_all; + } + if (_common_update_attr_vendor_name(self, show_err) < 0) { + err_str = "_common_update_attr_vendor_name"; + goto err_common_update_attr_all; + } + if (_common_update_attr_vendor_pn(self, show_err) < 0) { + err_str = "_common_update_attr_vendor_pn"; + goto err_common_update_attr_all; + } + if (_common_update_attr_vendor_rev(self, show_err) < 0) { + err_str = "_common_update_attr_vendor_rev"; + goto err_common_update_attr_all; + } + if (_common_update_attr_vendor_sn(self, show_err) < 0) { + err_str = "_common_update_attr_vendor_sn"; + goto err_common_update_attr_all; + } + if (_common_update_attr_br(self, show_err) < 0) { + err_str = "_common_update_attr_br"; + goto err_common_update_attr_all; + } + if (_common_update_attr_len_smf(self, show_err) < 0) { + err_str = "_common_update_attr_len_smf"; + goto err_common_update_attr_all; + } + if (_common_update_attr_len_om1(self, show_err) < 0) { + err_str = "_common_update_attr_len_om1"; + goto err_common_update_attr_all; + } + if (_common_update_attr_len_om2(self, show_err) < 0) { + err_str = "_common_update_attr_len_om2"; + goto err_common_update_attr_all; + } + if (_common_update_attr_len_om3(self, show_err) < 0) { + err_str = "_common_update_attr_len_om3"; + goto err_common_update_attr_all; + } + if (_common_update_attr_len_om4(self, show_err) < 0) { + err_str = "_common_update_attr_len_om4"; + goto err_common_update_attr_all; + } + if (_common_update_attr_option(self, show_err) < 0) { + err_str = "_common_update_attr_option"; + goto err_common_update_attr_all; + } + if (_common_update_attr_comp_rev(self, show_err) < 0) { + err_str = "_common_update_attr_comp_rev"; + goto err_common_update_attr_all; + } + if (_common_update_attr_diag_type(self, show_err) < 0) { + err_str = "_common_update_attr_diag_type"; + goto err_common_update_attr_all; + } + if (_common_update_attr_wavelength(self, show_err) < 0) { + err_str = "_common_update_attr_wavelength"; + goto err_common_update_attr_all; + } + return 0; + +err_common_update_attr_all: + if (show_err){ + SWPS_INFO("%s: fail at:%s :%s\n", __func__, err_str, self->swp_name); + } + return -1; +} + + +int +_sfp_update_attr_all(struct transvr_obj_s *self, + int show_err){ + + char *err_str = DEBUG_TRANSVR_STR_VAL; + + if (_common_update_attr_all(self, show_err) < 0){ + err_str = "_common_update_attr_all"; + goto err_sfp_update_attr_all; + } + if (_sfp_update_attr_len_sm(self, show_err) < 0) { + err_str = "_sfp_update_attr_len_sm"; + goto err_sfp_update_attr_all; + } + if (_sfp_update_attr_rate_id(self, show_err) < 0) { + err_str = "_sfp_update_attr_rate_id"; + goto err_sfp_update_attr_all; + } + if ((self->rate_id) > 0) { + if (_sfp_update_attr_soft_rs0(self, show_err) < 0) { + err_str = "_sfp_update_attr_soft_rs0"; + goto err_sfp_update_attr_all; + } + if (_sfp_update_attr_soft_rs1(self, show_err) < 0) { + err_str = "_sfp_update_attr_soft_rs1"; + goto err_sfp_update_attr_all; + } + } + return 0; + +err_sfp_update_attr_all: + if (show_err){ + SWPS_INFO("%s: fail at:%s :%s\n", __func__, err_str, self->swp_name); + } + return -1; +} + + +int +_qsfp_update_attr_all(struct transvr_obj_s *self, + int show_err){ + + char *err_str = DEBUG_TRANSVR_STR_VAL; + + if (_common_update_attr_all(self, show_err) < 0){ + err_str = "_common_update_attr_all"; + goto err_qsfp_update_attr_all; + } + if (_qsfg_update_attr_extbr(self, show_err) < 0) { + err_str = "_qsfg_update_attr_extbr"; + goto err_qsfp_update_attr_all; + } + if (self->type == TRANSVR_TYPE_QSFP_28) { + if (_qsfp_update_attr_cdr(self, 1) < 0) { + err_str = "_qsfp_update_attr_cdr"; + goto err_qsfp_update_attr_all; + } + } + return 0; + +err_qsfp_update_attr_all: + if (show_err){ + SWPS_INFO("%s: fail at:%s :%s\n", __func__, err_str, self->swp_name); + } + return -1; +} + + +/* ========== Object functions for common type ========== + */ +int +_common_count_temp(uint8_t high_byte, + uint8_t low_byte, + char *buf_p) { + int sign = 0; + int high = 0; + int low = 0; + int lmax = 8; + + /* Count high */ + sign = get_bit(high_byte,7); + SWP_BIT_CLEAR(high_byte, 7); + high = (int)high_byte; + if (sign == 1) { + high = 0 - high; + } + /* Count low */ + low = (get_bit(low_byte, 7) * 500); + low += (get_bit(low_byte, 6) * 250); + low += (get_bit(low_byte, 5) * 125); + low += (get_bit(low_byte, 4) * 62); + low = (low / 100); + /* Integrate High and Low */ + return snprintf(buf_p, lmax, "%d.%d\n", high, low); +} + + +int +_common_count_voltage(uint8_t high_byte, + uint8_t low_byte, + char *buf_p) { + /* [Note]: + * Internally measured transceiver supply voltage. Represented + * as a 16 bit unsigned integer with the voltage defined as the + * full 16 bit value (0-65535) with LSB equal to 100 uVolt, + * yielding a total range of 0 to +6.55 Volts. Practical + * considerations to be defined by transceiver manufacturer will + * tend to limit the actual bounds of the supply voltage measurement. + * Accuracy is vendor specific but must be better than 3% of the + * manufacturer's nominal value over specified operating temperature + * and voltage. Note that in some transceivers, transmitter supply + * voltage and receiver supply voltage are isolated. In that case, + * only one supply is monitored. Refer to the device specification + * for more detail. + */ + int total = 0; + int lmax = 8; + int val_i = 0; + int val_f = 0; + /* unit: 100 uV (1mV=1000uV) */ + total = transform_word_to_int(high_byte, low_byte); + val_i = ((total/10) / 1000); + val_f = ((total/10) - (val_i*1000)); + /* Return Unit: 1 Volt */ + return snprintf(buf_p, lmax, "%d.%03d\n", val_i, val_f); +} + + +int +_common_count_tx_bias(uint8_t high_byte, + uint8_t low_byte, + char *buf_p) { + /* [Note] + * Measured TX bias current in uA. Represented as a 16 bit unsigned + * integer with the current defined as the full 16 bit value (0-65535) + * with LSB equal to 2 uA, yielding a total range of 0 to 131 mA. + * Accuracy is vendor specific but must be better than 10% of the + * manufacturer's nominal value over specified operating temperature + * and voltage. + */ + int total = 0; + int lmax = 8; + int val_i = 0; + int val_f = 0; + /* unit: 2 uA (1mA=1000uA) */ + total = transform_word_to_int(high_byte, low_byte); + val_i = ((total*2) / 1000); + val_f = (((total*2) - (val_i*1000)) / 100); + /* Return Unit: 1 mA */ + return snprintf(buf_p, lmax, "%d.%01d\n", val_i, val_f); +} + + +int +_common_count_tx_power(uint8_t high_byte, + uint8_t low_byte, + char *buf_p) { + /* [Note] + * Measured TX output power in mW. Represented as a 16 bit unsigned + * integer with the power defined as the full 16 bit value (0-65535) + * with LSB equal to 0.1 uW, yielding a total range of 0 to 6.5535 mW + * (~ -40 to +8.2 dBm). Data is assumed to be based on measurement of + * laser monitor photodiode current. It is factory calibrated to absolute + * units using the most representative fiber output type. Accuracy is + * vendor specific but must be better than 3dB over specified temperature + * and voltage. Data is not valid when the transmitter is disabled. + */ + int total = 0; + int lmax = 8; + int val_i = 0; + int val_f = 0; + /* unit: 0.1 uW (1mW=1000uW) */ + total = transform_word_to_int(high_byte, low_byte); + val_i = ((total/10) / 1000); + val_f = ((total/10) - (val_i*1000)); + /* Return Unit: 1 mW */ + return snprintf(buf_p, lmax, "%d.%03d\n", val_i, val_f); +} + + +int +_common_count_rx_power(uint8_t high_byte, + uint8_t low_byte, + char *buf_p) { + /* [Note] + * Measured RX received optical power in mW. Value can represent either + * average received power or OMA depending upon how bit 3 of byte 92 (A0h) + * is set. Represented as a 16 bit unsigned integer with the power defined + * as the full 16 bit value (0-65535) with LSB equal to 0.1 uW, yielding a + * total range of 0 to 6.5535 mW (~ -40 to +8.2 dBm). Absolute accuracy is + * dependent upon the exact optical wavelength. For the vendor specified + * wavelength, accuracy shall be better than 3dB over specified temperature + * and voltage. + */ + int total = 0; + int lmax = 8; + int val_i = 0; + int val_f = 0; + /* unit: 0.1 uW (1mW=1000uW) */ + total = transform_word_to_int(high_byte, low_byte); + val_i = ((total/10) / 1000); + val_f = ((total/10) - (val_i*1000)); + /* Return Unit: 1 mW */ + return snprintf(buf_p, lmax, "%d.%03d\n", val_i, val_f); +} + + +int +_common_count_wavelength(struct transvr_obj_s *self, + uint8_t high_byte, + uint8_t low_byte) { + /* [Note] + * SFP : uint 1 um. + * QSFP: unit 0.05 um. + */ + int total = 0; + + total = transform_word_to_int(high_byte, low_byte); + switch (self->type) { + case TRANSVR_TYPE_SFP: + return total; + + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + case TRANSVR_TYPE_QSFP_28: + return (total/20); + + default: + break; + } + return ERR_TRANSVR_UNDEFINED; +} + + +int +common_get_id(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_id, + "common_get_id"); + if (err_code < 0){ + return err_code; + } + /* Transform to INT to show error case */ + return (int)self->id; +} + + +int +common_get_ext_id(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_extended_id, + "common_get_ext_id"); + if (err_code < 0){ + return err_code; + } + /* Transform to INT to show error case */ + return (int)self->ext_id; +} + + +int +common_get_connector(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_connector, + "common_get_connector"); + if (err_code < 0){ + return err_code; + } + /* Transform to INT to show error case */ + return (int)self->connector; +} + + +int +common_get_vendor_name(struct transvr_obj_s *self, char *buf){ + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_name); + } + err = _check_by_mode(self, + &_common_update_attr_vendor_name, + "common_get_vendor_name"); + memset(buf, 0, LEN_TRANSVR_M_STR); + if (err < 0){ + return snprintf(buf, LEN_TRANSVR_M_STR, "%d\n", err); + } + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_name); +} + + +int +common_get_vendor_pn(struct transvr_obj_s *self, char *buf) { + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_pn); + } + err = _check_by_mode(self, + &_common_update_attr_vendor_pn, + "common_get_vendor_pn"); + memset(buf, 0, LEN_TRANSVR_M_STR); + if (err < 0){ + return snprintf(buf, LEN_TRANSVR_M_STR, "%d\n", err); + } + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_pn); +} + + +int +common_get_vendor_rev(struct transvr_obj_s *self, char *buf) { + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_rev); + } + err = _check_by_mode(self, + &_common_update_attr_vendor_rev, + "common_get_vendor_rev"); + memset(buf, 0, LEN_TRANSVR_M_STR); + if (err < 0){ + return snprintf(buf, LEN_TRANSVR_M_STR, "%d\n", err); + } + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_rev); +} + + +int +common_get_vendor_sn(struct transvr_obj_s *self, char *buf) { + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_sn); + } + err = _check_by_mode(self, + &_common_update_attr_vendor_sn, + "common_get_vendor_sn"); + memset(buf, 0, LEN_TRANSVR_M_STR); + if (err < 0){ + return snprintf(buf, LEN_TRANSVR_M_STR, "%d\n", err); + } + return snprintf(buf, LEN_TRANSVR_M_STR, "%s\n", self->vendor_sn); +} + + +int +common_get_br(struct transvr_obj_s *self){ + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return (int)self->br; + } + err = _check_by_mode(self, + &_common_update_attr_br, + "common_get_br"); + if (err < 0){ + return err; + } + /* Transform to INT to show error case */ + return (int)self->br; +} + + +int +common_get_len_smf(struct transvr_obj_s *self){ + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return self->len_smf; + } + err = _check_by_mode(self, + &_common_update_attr_len_smf, + "common_get_len_smf"); + if (err < 0){ + return err; + } + return self->len_smf; +} + + +int +common_get_len_om1(struct transvr_obj_s *self){ + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return self->len_om1; + } + err = _check_by_mode(self, + &_common_update_attr_len_om1, + "common_get_len_om1"); + if (err < 0){ + return err; + } + return self->len_om1; +} + + +int +common_get_len_om2(struct transvr_obj_s *self){ + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return self->len_om2; + } + + err = _check_by_mode(self, + &_common_update_attr_len_om2, + "common_get_len_om2"); + if (err < 0){ + return err; + } + return self->len_om2; +} + + +int +common_get_len_om3(struct transvr_obj_s *self){ + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return self->len_om3; + } + + err = _check_by_mode(self, + &_common_update_attr_len_om3, + "common_get_len_om3"); + if (err < 0){ + return err; + } + return self->len_om3; +} + + +int +common_get_len_om4(struct transvr_obj_s *self){ + + int err = DEBUG_TRANSVR_INT_VAL; + + if (self->state == STATE_TRANSVR_CONNECTED && + self->mode == TRANSVR_MODE_POLLING && + TRANSVR_INFO_CACHE_ENABLE) { + return self->len_om4; + } + err = _check_by_mode(self, + &_common_update_attr_len_om4, + "common_get_len_om4"); + if (err < 0){ + return err; + } + return self->len_om4; +} + + +int +common_get_comp_extended(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_transvr_comp_ext, + "common_get_comp_extended"); + if (err_code < 0){ + return err_code; + } + return self->transvr_comp_ext; +} + + +int +common_get_comp_rev(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_comp_rev, + "common_get_comp_rev"); + if (err_code < 0){ + return err_code; + } + return self->comp_rev; +} + + +int +common_get_info(struct transvr_obj_s *self){ + + if (self->state != STATE_TRANSVR_CONNECTED) { + return self->state; + } + return self->info; +} + + +int +_common_get_if_lane(struct transvr_obj_s *self, + char *result){ + int i = 0; + int tmp_val = 0; + char tmp_str[LEN_TRANSVR_M_STR] = DEBUG_TRANSVR_STR_VAL; + + memset(result, 0, LEN_TRANSVR_M_STR); + + for (i=0; ilane_id); i++) { + tmp_val = self->lane_id[i]; + if (tmp_val < 1) { + break; + } + memset(tmp_str, 0, LEN_TRANSVR_M_STR); + if (i == 0) { + snprintf(tmp_str, LEN_TRANSVR_M_STR, "%d", tmp_val); + } else { + snprintf(tmp_str, LEN_TRANSVR_M_STR, ",%d", tmp_val); + } + strncat(result, tmp_str, LEN_TRANSVR_M_STR); + } + if (i == 0) { + return EVENT_TRANSVR_TASK_FAIL; + } + return 0; +} + + +int +common_get_if_lane(struct transvr_obj_s *self, + char *buf_p){ + + char tmp_str[LEN_TRANSVR_M_STR] = DEBUG_TRANSVR_STR_VAL; + + if (self->ioexp_obj_p->state != STATE_IOEXP_NORMAL) { + return snprintf(buf_p, LEN_TRANSVR_M_STR, "%d\n", ERR_TRANSVR_ABNORMAL); + } + if (_common_get_if_lane(self, tmp_str) < 0) { + return snprintf(buf_p, LEN_TRANSVR_M_STR, "%d\n" ,ERR_TRANSVR_ABNORMAL); + } + return snprintf(buf_p, LEN_TRANSVR_M_STR, "%s\n" ,tmp_str); +} + + +int +sfp_get_len_sm(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_sfp_update_attr_len_sm, + "sfp_get_len_sm"); + if (err_code < 0){ + return err_code; + } + return self->len_sm; +} + + +int +sfp_get_rate_id(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_sfp_update_attr_rate_id, + "sfp_get_rate_id"); + if (err_code < 0){ + return err_code; + } + return self->rate_id; +} + + +int +sfp_get_soft_rs0(struct transvr_obj_s *self){ + /* Note: + * SFP Soft Rate_Select Select [aka. "RS(0)"] address + * A2h, offset: 110, bit 3 (begin form 0) + */ + int err_code = DEBUG_TRANSVR_INT_VAL; + int bit_shift = 3; + uint8_t result = 0x00; + uint8_t bitmask = (1 << bit_shift); + + /* Check rate identifier is supported */ + err_code = self->get_rate_id(self); + if (err_code <= 0) { + return ERR_TRANSVR_NOTSUPPORT; + } + /* Update and check */ + err_code = _check_by_mode(self, + &_sfp_update_attr_soft_rs0, + "sfp_get_soft_rs0"); + if (err_code <0){ + return err_code; + } + result = (self->soft_rs0 & bitmask); + if (result == bitmask) { + return 1; + } + if (result == 0) { + return 0; + } + return ERR_TRANSVR_UNEXCPT; +} + + +int +sfp_get_soft_rs1(struct transvr_obj_s *self){ + /* Note: + * SFP Soft RS(1) Select address + * A2h, offset: 118, bit 3 (begin form 0) + */ + int err_code = DEBUG_TRANSVR_INT_VAL; + int bit_shift = 3; + uint8_t result = 0x00; + uint8_t bitmask = (1 << bit_shift); + + /* Check rate identifier is supported */ + err_code = self->get_rate_id(self); + if (err_code <= 0) { + return ERR_TRANSVR_NOTSUPPORT; + } + /* Update and check */ + err_code = _check_by_mode(self, + &_sfp_update_attr_soft_rs1, + "sfp_get_soft_rs1"); + if (err_code <0){ + return err_code; + } + result = (self->soft_rs1 & bitmask); + if (result == bitmask) { + return 1; + } + if (result == 0) { + return 0; + } + return ERR_TRANSVR_UNEXCPT; +} + + +int +sfp_get_transvr_temp(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_sfp_update_attr_curr_temp, + "sfp_get_transvr_temp"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_temp[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + return _common_count_temp(self->curr_temp[0], + self->curr_temp[1], + buf_p); +} + + +int +sfp_get_transvr_voltage(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_sfp_update_attr_curr_voltage, + "sfp_get_transvr_voltage"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_voltage[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 Volt */ + return _common_count_voltage(self->curr_voltage[0], + self->curr_voltage[1], + buf_p); +} + + +int +sfp_get_transvr_tx_bias(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_sfp_update_attr_curr_tx_bias, + "sfp_get_transvr_tx_bias"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_tx_bias[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 mA */ + return _common_count_tx_bias(self->curr_tx_bias[0], + self->curr_tx_bias[1], + buf_p); +} + + +int +sfp_get_transvr_tx_power(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_sfp_update_attr_curr_tx_power, + "sfp_get_transvr_tx_power"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_tx_bias[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 mW */ + return _common_count_tx_power(self->curr_tx_power[0], + self->curr_tx_power[1], + buf_p); +} + + +int +sfp_get_transvr_rx_power(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_sfp_update_attr_curr_rx_power, + "sfp_get_transvr_rx_power"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_tx_bias[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 mW */ + return _common_count_rx_power(self->curr_rx_power[0], + self->curr_rx_power[0], + buf_p); +} + + +int +sfp_get_transvr_rx_em(struct transvr_obj_s *self, + char *buf_p) { + + int limt = 8; + int err = DEBUG_TRANSVR_INT_VAL; + + err = _check_by_mode(self, + &_sfp_update_attr_rx_em, + "sfp_get_transvr_rx_em"); + if (err < 0) { + return snprintf(buf_p, limt, "%d\n", err); + } + if ((self->tx_eq[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, limt, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + return snprintf(buf_p, limt, "0x%02x\n", self->rx_em[0]); +} + + +int +sfp_get_transvr_tx_eq(struct transvr_obj_s *self, + char *buf_p) { + + int limt = 8; + int err = DEBUG_TRANSVR_INT_VAL; + + err = _check_by_mode(self, + &_sfp_update_attr_tx_eq, + "sfp_get_transvr_tx_eq"); + if (err < 0) { + return snprintf(buf_p, limt, "%d\n", err); + } + if ((self->tx_eq[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, limt, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + return snprintf(buf_p, limt, "0x%02x\n", self->tx_eq[0]); +} + + +int +_sfp_get_comp_extended(struct transvr_obj_s *self) { + /* Address: A0h / 36 + * Reference: SFF-8024 TABLE 4-4 + */ + if ((self->state == STATE_TRANSVR_CONNECTED) || + (self->state == STATE_TRANSVR_INIT) ) { + return (int)(self->transvr_comp_ext); + } + return ERR_TRANSVR_ABNORMAL; +} + + +int +__sfp_get_comp_attr(struct transvr_obj_s *self, + int array_offset) { + /* SFP Specification Compliance: A0h / 3-10 + * transvr_comp[0-7] = 3 - 10 + */ + if ((self->state == STATE_TRANSVR_CONNECTED) || + (self->state == STATE_TRANSVR_INIT) ) { + return (int)(self->transvr_comp[array_offset]); + } + return ERR_TRANSVR_ABNORMAL; +} + + +int +_sfp_get_comp_10g_eth_comp(struct transvr_obj_s *self) { + /* transvr_comp[0] = address A0h / 3 + * + * 3 7: 10G Base-ER + * 3 6: 10GBASE-LRM + * 3 5: 10GBASE-LR + * 3 4: 10GBASE-SR + */ + int bitmask = 0xf0; /* 11110000 */ + return (__sfp_get_comp_attr(self, 0) & bitmask); +} + + +int +_sfp_get_comp_1g_eth_comp(struct transvr_obj_s *self) { + /* transvr_comp[3] = address A0h / 6 + * + * 6 7: BASE-PX *3 + * 6 6: BASE-BX10 *3 + * 6 5: 100BASE-FX + * 6 4: 100BASE-LX/LX10 + * 6 3: 1000BASE-T + * 6 2: 1000BASE-CX + * 6 1: 1000BASE-LX *3 + * 6 0: 1000BASE-SX + */ + return __sfp_get_comp_attr(self, 3); +} + + +int +_sfp_get_cable_tech(struct transvr_obj_s *self) { + /* transvr_comp[5] = address A0h / 8 + * + * 8 3: Active Cable *8 + * 8 2: Passive Cable *8 + */ + int bitmask = 0x0c; /* 00001100 */ + return (__sfp_get_comp_attr(self, 5) & bitmask); +} + + +int +sfp_get_comp_eth_1(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_transvr_comp, + "sfp_get_comp_eth_1"); + if (err_code < 0){ + return err_code; + } + return _sfp_get_comp_1g_eth_comp(self); +} + + +int +sfp_get_comp_eth_10(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_transvr_comp, + "sfp_get_comp_eth_10"); + if (err_code < 0){ + return err_code; + } + return _sfp_get_comp_10g_eth_comp(self); +} + + +int +_sfp_get_connector_type(struct transvr_obj_s *self) { + /* Address: A0h / 2 + * Reference: SFF-8024 TABLE 4-3 + */ + if ((self->state == STATE_TRANSVR_CONNECTED) || + (self->state == STATE_TRANSVR_INIT) ) { + return (int)(self->connector); + } + return ERR_TRANSVR_ABNORMAL; +} + + +int +sfp_get_wavelength(struct transvr_obj_s *self, + char *buf_p) { + /* [Note] Optical and Cable Variants Specification Compliance (SFF-8472) + * [Addr] A0h, Bytes 60-61 + * [Note] For optical variants, as defined by having zero's in A0h Byte 8 + * bits 2 and 3, Bytes 60 and 61 denote nominal transmitter output + * wavelength at room temperature. 16 bit value with byte 60 as high + * order byte and byte 61 as low order byte. The laser wavelength is + * equal to the 16 bit integer value in nm. This field allows the user + * to read the laser wavelength directly, so it is not necessary to + * infer it from the Transceiver Codes A0h Bytes 3 to 10 (see Table + * 5-3). This also allows specification of wavelengths not covered + * in the Transceiver Codes, such as those used in coarse WDM systems. + * + * For passive and active cable variants, a value of 00h for both A0h + * Byte 60 and Byte 61 denotes laser wavelength or cable specification + * compliance is unspecified. + */ + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_common_update_attr_wavelength, + "common_get_wavelength"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->wavelength[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* unit: 1 um */ + return snprintf(buf_p, lmax, "%d\n", + _common_count_wavelength(self, + self->wavelength[0], + self->wavelength[1])); +} + + +int +sfp_get_1g_rj45_extphy_offset(struct transvr_obj_s *self, char *buf) { + + if (self->state != STATE_TRANSVR_CONNECTED) { + return ERR_TRANSVR_UNPLUGGED; + } + if ((self->info != TRANSVR_CLASS_BASE_T_1000) && + (self->info != TRANSVR_CLASS_BASE_T_1000_up) ){ + return ERR_TRANSVR_NOTSUPPORT; + } + return snprintf(buf, LEN_TRANSVR_S_STR, "0x%02x\n", self->extphy_offset); +} + + +int +sfp_get_1g_rj45_extphy_reg(struct transvr_obj_s *self, char *buf) { + + int i = 0; + int ret = 0; + int retry = 3; + int delay = 200; + + if (self->state != STATE_TRANSVR_CONNECTED) { + return ERR_TRANSVR_UNPLUGGED; + } + if ((self->info != TRANSVR_CLASS_BASE_T_1000) && + (self->info != TRANSVR_CLASS_BASE_T_1000_up) ){ + return ERR_TRANSVR_NOTSUPPORT; + } + if (_common_setup_page(self, VAL_TRANSVR_EXTPHY_ADDR_56, + -1, self->extphy_offset, 1, 0) < 0) { + return -EIO; + } + for (i=0; ii2c_client_p, self->extphy_offset); + if (ret >=0) { + goto ok_sfp_get_1g_rj45_extphy_reg; + } + msleep(delay); + } + SWPS_INFO("%s: retry:%d fail :%s :0x%02x\n", + __func__, retry, self->swp_name, self->extphy_offset); + return -EIO; + +ok_sfp_get_1g_rj45_extphy_reg: + ret = ((ret & 0x00ff) << 8) | ((ret & 0xff00) >> 8); + return snprintf(buf, LEN_TRANSVR_S_STR, "0x%04x\n", ret); +} + + +int +__qsfp_get_power_cls(struct transvr_obj_s *self, + int direct_access){ + + int err_code; + uint8_t detect_val; + + /* Detect and Update power class attribute */ + if (direct_access){ + err_code = _check_by_mode(self, + &_common_update_attr_extended_id, + "__qsfp_get_power_cls"); + } else { + err_code = self->ext_id; + } + if (err_code <0){ + return err_code; + } + if (err_code == DEBUG_TRANSVR_HEX_VAL){ + return ERR_TRANSVR_UPDATE_FAIL; + } + /* Clean data */ + detect_val = self->ext_id; + SWP_BIT_CLEAR(detect_val, 2); /* Bit2: CDR RX present */ + SWP_BIT_CLEAR(detect_val, 3); /* Bit3: CDR TX present */ + SWP_BIT_CLEAR(detect_val, 4); /* Bit4: CLEI present */ + SWP_BIT_CLEAR(detect_val, 5); /* Bit5: reserved */ + /* Identify power class */ + switch (detect_val) { + case 0: /* Class_1: 00000000 */ + return 1; + case 64: /* Class_2: 01000000 */ + return 2; + case 128: /* Class_3: 10000000 */ + return 3; + case 192: /* Class_4: 11000000 */ + return 4; + case 1: /* Class_5: 00000001 */ + case 193: /* Class_5: 11000001 */ + return 5; + case 2: /* Class_6: 00000010 */ + case 194: /* Class_6: 11000010 */ + return 6; + case 3: /* Class_7: 00000011 */ + case 195: /* Class_7: 11000011 */ + return 7; + default: + break; + } + SWPS_INFO("%s: Detect undefined power class:%d\n", __func__, detect_val); + return ERR_TRANSVR_UNDEFINED; +} + + +int +qsfp_get_power_cls(struct transvr_obj_s *self) { + return __qsfp_get_power_cls(self, 1); +} + + +int +__qsfp_get_cdr_present(struct transvr_obj_s *self, + int direct_access){ + + int retval; + int BIT_SHIFT = 2; + int BIT_MASK = 0x3; + + /* Detect and Update power class attribute */ + if (direct_access) { + retval = _check_by_mode(self, + &_common_update_attr_extended_id, + "__qsfp_get_cdr_present"); + if (retval < 0){ + return retval; + } + } + retval = self->ext_id; + if (retval == DEBUG_TRANSVR_HEX_VAL){ + return ERR_TRANSVR_UPDATE_FAIL; + } + /* Clean data and return */ + return (int)(retval >> BIT_SHIFT & BIT_MASK); +} + + +int +qsfp_get_cdr_present(struct transvr_obj_s *self) { + return __qsfp_get_cdr_present(self, 1); +} + + +int +qsfp_get_cdr(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_qsfp_update_attr_cdr, + "qsfp_get_cdr"); + if (err_code <0){ + return err_code; + } + + return self->cdr; +} + + +int +__qsfp_get_comp_attr(struct transvr_obj_s *self, + int array_offset) { + /* QSFP Specification Compliance: 00h / 131-138 + * transvr_comp[0-7] = 131 - 138 + */ + if ((self->state == STATE_TRANSVR_CONNECTED) || + (self->state == STATE_TRANSVR_INIT) ) { + return (int)(self->transvr_comp[array_offset]); + } + return ERR_TRANSVR_ABNORMAL; +} + + +int +_qsfp_get_comp_10_40_100_ethernet(struct transvr_obj_s *self) { + /* transvr_comp[0] = address 00h / 131 + * + * 131 7: Extended: See section 6.3.23. The Extended Specification Compliance + * Codes are maintained in the Transceiver Management section of SFF- + * 8024. + * 131 6: 10GBASE-LRM + * 131 5: 10GBASE-LR + * 131 4: 10GBASE-SR + * 131 3: 40GBASE-CR4 + * 131 2: 40GBASE-SR4 + * 131 1: 40GBASE-LR4 + * 131 0: 40G Active Cable (XLPPI) + */ + return __qsfp_get_comp_attr(self, 0); +} + + +int +_qsfp_get_comp_sonet(struct transvr_obj_s *self) { + /* transvr_comp[1] = address 00h / 132 + * + * 132 7-3: Reserved + * 132 2: OC 48, long reach + * 132 1: OC 48, intermediate reach + * 132 0: OC 48 short reach + */ + return __qsfp_get_comp_attr(self, 1); +} + + +int +_qsfp_get_comp_sas_sata(struct transvr_obj_s *self) { + /* transvr_comp[1] = address 00h / 132 + * + * 133 7: SAS 24.0 Gb/s + * 133 6: SAS 12.0 Gb/s + * 133 5: SAS 6.0 Gb/s + * 133 4: SAS 3.0 Gb/s + * 133 3-0: Reserved + */ + return __qsfp_get_comp_attr(self, 2); +} + + +int +_qsfp_get_comp_ethernet(struct transvr_obj_s *self) { + /* transvr_comp[1] = address 00h / 132 + * + * 134 7-4: Reserved + * 134 3: 1000BASE-T + * 134 2: 1000BASE-CX + * 134 1: 1000BASE-LX + * 134 0: 1000BASE-SX + */ + return __qsfp_get_comp_attr(self, 3); +} + + +int +_qsfp_get_comp_fc_link_length(struct transvr_obj_s *self) { + /* transvr_comp[1] = address 00h / 132 + * + * 135 7: Very long distance (V) + * 135 6: Short distance (S) + * 135 5: Intermediate distance (I) + * 135 4: Long distance (L) + * 135 3: Medium (M) + */ + int mask = 0xFC; /* 11111100 */ + return (__qsfp_get_comp_attr(self, 4) & mask); +} + + +int +_qsfp_get_comp_fc_trans_tech(struct transvr_obj_s *self) { + /* transvr_comp[1] = address 00h / 132 + * + * 135 2: Reserved + * 135 1: Longwave laser (LC) + * 135 0: Electrical inter-enclosure (EL) + * + * 136 7: Electrical intra-enclosure + * 136 6: Shortwave laser w/o OFC (SN) + * 136 5: Shortwave laser w OFC (SL) + * 136 4: Longwave Laser (LL) + * 136 3-0: Reserved + * + * return value = [bit 8-15:addr 135][bit 0-7:addr 136] + */ + int mask_135 = 7; /* 00000111 */ + int val_135 = (__qsfp_get_comp_attr(self, 4) & mask_135); + int val_136 = __qsfp_get_comp_attr(self, 5); + return ((val_135 << 7) + val_136); +} + + +int +_qsfp_get_comp_fc_trans_media(struct transvr_obj_s *self) { + /* transvr_comp[1] = address 00h / 132 + * + * 137 7: Twin Axial Pair (TW) + * 137 6: Shielded Twisted Pair (TP) + * 137 5: Miniature Coax (MI) + * 137 4: Video Coax (TV) + * 137 3: Multi-mode 62.5 m (M6) + * 137 2: Multi-mode 50 m (M5) + * 137 1: Multi-mode 50 um (OM3) + * 137 0: Single Mode (SM) + */ + return __qsfp_get_comp_attr(self, 6); +} + + +int +_qsfp_get_comp_fc_speed(struct transvr_obj_s *self) { + /* transvr_comp[1] = address 00h / 132 + * + * 138 7: 1200 MBps (per channel) + * 138 6: 800 MBps + * 138 5: 1600 MBps (per channel) + * 138 4: 400 MBps + * 138 3: 3200 MBps (per channel) + * 138 2: 200 MBps + * 138 1: Extended: See section 6.3.23. The Extended Specification + * Compliance Codes are maintained in the Transceiver Management + * section of SFF-8024. + * 138 0: 100 MBps + */ + return __qsfp_get_comp_attr(self, 7); +} + + +int +_qsfp_get_comp_extended(struct transvr_obj_s *self) { + /* Address: 00h / 192 + * Reference: SFF-8024 TABLE 4-4 + */ + if ((self->state == STATE_TRANSVR_CONNECTED) || + (self->state == STATE_TRANSVR_INIT) ) { + return (int)(self->transvr_comp_ext); + } + return ERR_TRANSVR_ABNORMAL; +} + + +int +qsfp_get_comp_eth(struct transvr_obj_s *self){ + + int err_code = _check_by_mode(self, + &_common_update_attr_transvr_comp, + "qsfp_get_comp_eth"); + if (err_code < 0){ + return err_code; + } + return _qsfp_get_comp_ethernet(self); +} + + +int +qsfp_get_comp_10_40(struct transvr_obj_s *self) { + + int err_code = _check_by_mode(self, + &_common_update_attr_transvr_comp, + "qsfp_get_comp_10_40"); + if (err_code < 0){ + return err_code; + } + return _qsfp_get_comp_10_40_100_ethernet(self); +} + + +int +_qsfp_get_connector_type(struct transvr_obj_s *self) { + /* Address: 00h / 130 + * Reference: SFF-8024 TABLE 4-3 + */ + if ((self->state == STATE_TRANSVR_CONNECTED) || + (self->state == STATE_TRANSVR_INIT) ) { + return (int)(self->connector); + } + return ERR_TRANSVR_ABNORMAL; +} + + +int +qsfp_get_transvr_temp(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_curr_temp, + "qsfp_get_transvr_temp"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_temp[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + return _common_count_temp(self->curr_temp[0], + self->curr_temp[1], + buf_p); +} + + +int +qsfp_get_transvr_voltage(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_curr_voltage, + "qsfp_get_transvr_voltage"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_voltage[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 Volt */ + return _common_count_voltage(self->curr_voltage[0], + self->curr_voltage[1], + buf_p); +} + + +int +qsfp_get_transvr_tx_eq(struct transvr_obj_s *self, + char *buf_p) { + + int limt = 8; + int err = DEBUG_TRANSVR_INT_VAL; + + err = _check_by_mode(self, + &_qsfp_update_attr_tx_eq, + "qsfp_get_transvr_tx_eq"); + if (err < 0) { + return snprintf(buf_p, limt, "%d\n", err); + } + if ((self->tx_eq[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, limt, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + return snprintf(buf_p, limt, "0x%02x%02x\n", + self->tx_eq[0], self->tx_eq[1]); +} + + +int +qsfp_get_transvr_rx_am(struct transvr_obj_s *self, + char *buf_p) { + + int limt = 8; + int err = DEBUG_TRANSVR_INT_VAL; + + err = _check_by_mode(self, + &_qsfp_update_attr_rx_am, + "qsfp_get_transvr_rx_am"); + if (err < 0) { + return snprintf(buf_p, limt, "%d\n", err); + } + if ((self->rx_am[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, limt, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + return snprintf(buf_p, limt, "0x%02x%02x\n", + self->rx_am[0], self->rx_am[1]); +} + + +int +qsfp_get_transvr_rx_em(struct transvr_obj_s *self, + char *buf_p) { + + int limt = 8; + int err = DEBUG_TRANSVR_INT_VAL; + + err = _check_by_mode(self, + &_qsfp_update_attr_rx_em, + "qsfp_get_transvr_rx_em"); + if (err < 0) { + return snprintf(buf_p, limt, "%d\n", err); + } + if ((self->rx_em[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, limt, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + return snprintf(buf_p, limt, "0x%02x%02x\n", + self->rx_em[0], self->rx_em[1]); +} + + +int +_qsfp_get_channel_diag(uint8_t *data_array, + int (*count_func)(uint8_t high_byte, uint8_t low_byte, char *buf_p), + char *ch_name, + char *result_p) { + int i, high, low; + int len_max = 128; + char ch_buf[4][16] = { DEBUG_TRANSVR_STR_VAL, + DEBUG_TRANSVR_STR_VAL, + DEBUG_TRANSVR_STR_VAL, + DEBUG_TRANSVR_STR_VAL }; + + for (i=0; i<4; i++) { + high = (i*2); + low = ((i*2) + 1); + count_func(data_array[high], data_array[low], ch_buf[i]); + } + return snprintf(result_p, len_max, + "%s-%d:%s%s-%d:%s%s-%d:%s%s-%d:%s", + ch_name, 1, ch_buf[0], + ch_name, 2, ch_buf[1], + ch_name, 3, ch_buf[2], + ch_name, 4, ch_buf[3]); +} + + +int +qsfp_get_soft_rx_los(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int mask = 0x0f; /* Bit 0 ~ Bit 3 */ + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_soft_rx_los, + "qsfp_get_soft_rx_los"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + return snprintf(buf_p, lmax, "0x%02x\n", (self->rx_los & mask)); +} + + +int +qsfp_get_soft_tx_disable(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int mask = 0x0f; /* Bit 0 ~ Bit 3 */ + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_soft_tx_disable, + "qsfp_get_soft_tx_disable"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + return snprintf(buf_p, lmax, "0x%02x\n", (self->tx_disable & mask)); +} + + +int +qsfp_get_soft_tx_fault(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int mask = 0x0f; /* Bit 0 ~ Bit 3 */ + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_soft_tx_fault, + "qsfp_get_soft_tx_fault"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + return snprintf(buf_p, lmax, "0x%02x\n", (self->tx_fault & mask)); +} + + +int +qsfp_get_auto_tx_disable(struct transvr_obj_s *self, + char *buf_p) { + + if (self->auto_tx_disable == VAL_TRANSVR_FUNCTION_DISABLE) { + return snprintf(buf_p, LEN_TRANSVR_S_STR, + "%d\n", ERR_TRANSVR_FUNC_DISABLE); + } + return snprintf(buf_p, LEN_TRANSVR_S_STR, + "0x%02x\n", self->auto_tx_disable); +} + + +int +qsfp_get_transvr_tx_bias(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + char *ch_name = "TX"; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_curr_tx_bias, + "qsfp_get_transvr_tx_bias"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_tx_bias[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 mA */ + return _qsfp_get_channel_diag(self->curr_tx_bias, + _common_count_tx_bias, + ch_name, + buf_p); +} + + +int +qsfp_get_transvr_tx_power(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + char *ch_name = "TX"; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_curr_tx_power, + "qsfp_get_transvr_tx_power"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_tx_power[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 mW */ + return _qsfp_get_channel_diag(self->curr_tx_power, + _common_count_tx_power, + ch_name, + buf_p); +} + + +int +qsfp_get_transvr_rx_power(struct transvr_obj_s *self, + char *buf_p) { + + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + char *ch_name = "RX"; + + err_code = _check_by_mode(self, + &_qsfp_update_attr_curr_rx_power, + "qsfp_get_transvr_rx_power"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->curr_tx_power[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* Return Unit: 1 mW */ + return _qsfp_get_channel_diag(self->curr_rx_power, + _common_count_rx_power, + ch_name, + buf_p); +} + + +int +qsfp_get_wavelength(struct transvr_obj_s *self, + char *buf_p) { + /* [Desc] Wavelength or Copper Cable Attenuation (SFF-8636) + * [Addr] 00h 186-187 + * [Note] + * For optical free side devices, this parameter identifies the nominal + * transmitter output wavelength at room temperature. This parameter is + * a 16-bit hex value with Byte 186 as high order byte and Byte 187 as + * low order byte. The laser wavelength is equal to the 16-bit integer value + * divided by 20 in nm (units of 0.05 nm). This resolution should be adequate + * to cover all relevant wavelengths yet provide enough resolution for all + * expected DWDM applications. For accurate representation of controlled + * wavelength applications, this value should represent the center of the + * guaranteed wavelength range. + * If the free side device is identified as copper cable these registers will + * be used to define the cable attenuation. An indication of 0 dB attenuation + * refers to the case where the attenuation is not known or is unavailable. + * Byte 186 (00-FFh) is the copper cable attenuation at 2.5 GHz in units of 1 dB. + * Byte 187 (00-FFh) is the copper cable attenuation at 5.0 GHz in units of 1 dB. + */ + int lmax = 8; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _check_by_mode(self, + &_common_update_attr_wavelength, + "common_get_wavelength"); + if (err_code < 0) { + return snprintf(buf_p, lmax, "%d\n", err_code); + } + if ((self->wavelength[0]) == DEBUG_TRANSVR_HEX_VAL) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_UPDATE_FAIL); + } + /* unit: 1 um */ + return snprintf(buf_p, lmax, "%d\n", + _common_count_wavelength(self, + self->wavelength[0], + self->wavelength[1])); +} + + +/* Public Function for Setup Features + */ +static int +__sfp_set_soft_rs(struct transvr_obj_s *self, + int input_val, + int address, + int page, + int offset, + int bit_shift, + uint8_t *attr_p, + char *caller, + int show_err) { + + int retval = ERR_TRANSVR_UNEXCPT; + int err_code = ERR_TRANSVR_UNEXCPT; + char *err_msg = DEBUG_TRANSVR_STR_VAL; + uint8_t update_val = (*attr_p); + + switch (input_val) { + case 0: + SWP_BIT_CLEAR(update_val, bit_shift); + break; + case 1: + SWP_BIT_SET(update_val, bit_shift); + break; + default: + retval = ERR_TRANSVR_UNEXCPT; + err_code = ERR_TRANSVR_UNEXCPT; + err_msg = "Exception occurs"; + goto err_private_sfp_set_soft_rs_1; + } + err_code = _common_set_uint8_attr(self, + address, + page, + offset, + update_val, + attr_p, + caller, + show_err); + if (err_code < 0) { + retval = err_code; + err_msg = "Write data via i2c fail!"; + goto err_private_sfp_set_soft_rs_1; + } + (*attr_p) = update_val; + return 0; + +err_private_sfp_set_soft_rs_1: + if (show_err) { + SWPS_INFO("%s: %s :%d :%s\n :%d\n", + __func__, err_msg, err_code, self->swp_name, input_val); + } + return retval; +} + + +static int +_sfp_set_soft_rs(struct transvr_obj_s *self, + int input_val, + int address, + int page, + int offset, + int bit_shift, + int (*attr_update_func)(struct transvr_obj_s *self, int show_err), + uint8_t *attr_p, + char *caller, + int show_err) { + + int retval = ERR_TRANSVR_UNEXCPT; + int err_code = ERR_TRANSVR_UNEXCPT; + char *err_msg = DEBUG_TRANSVR_STR_VAL; + + /* Check input value */ + if ((input_val != 0) && (input_val != 1)){ + retval = ERR_TRANSVR_BADINPUT; + err_code = ERR_TRANSVR_BADINPUT; + err_msg = "Input range incorrect!"; + goto err_common_sfp_set_soft_rs_1; + } + /* Check rate identifier is supported */ + err_code = self->get_rate_id(self); + if (err_code <= 0) { + switch (err_code) { + case 0: + retval = ERR_TRANSVR_NOTSUPPORT; + err_msg = "Not support this feature"; + break; + case ERR_TRANSVR_UNINIT: + retval = ERR_TRANSVR_UNINIT; + err_msg = "Check CDR present fail!"; + break; + case ERR_TRANSVR_UNPLUGGED: + retval = ERR_TRANSVR_UNPLUGGED; + err_msg = "Transceiver unplugged!"; + break; + default: + retval = err_code; + err_msg = "Check Rate_ID fail!"; + break; + } + goto err_common_sfp_set_soft_rs_1; + } + /* Check and update */ + err_code = _check_by_mode(self, + attr_update_func, + caller); + if ( (err_code < 0) || + ((*attr_p) == DEBUG_TRANSVR_HEX_VAL) ){ + retval = err_code; + err_msg = "Get current value fail!"; + goto err_common_sfp_set_soft_rs_1; + } + /* Generate and update value */ + return __sfp_set_soft_rs(self, + input_val, + address, + page, + offset, + bit_shift, + attr_p, + caller, + show_err); + +err_common_sfp_set_soft_rs_1: + if (show_err) { + SWPS_INFO("%s: %s :%d :%s\n :%d\n", + __func__, err_msg, err_code, self->swp_name, input_val); + } + return retval; +} + + +int +sfp_set_soft_rs0(struct transvr_obj_s *self, + int input_val) { + /* Note: + * SFP Soft Rate_Select Select RX ["RS(0)"] address + * A2h, offset: 110, bit 3 + */ + int bit_shift = 3; + int show_err = 1; + return _sfp_set_soft_rs(self, + input_val, + self->eeprom_map_p->addr_soft_rs0, + self->eeprom_map_p->page_soft_rs0, + self->eeprom_map_p->offset_soft_rs0, + bit_shift, + &_sfp_update_attr_soft_rs0, + &(self->soft_rs0), + "sfp_set_soft_rs0", + show_err); +} + + +int +sfp_set_soft_rs1(struct transvr_obj_s *self, + int input_val) { + /* Note: + * SFP Soft Rate_Select Select RX ["RS(1)"] address + * A2h, offset: 118, bit 3 + */ + int bit_shift = 3; + int show_err = 1; + return _sfp_set_soft_rs(self, + input_val, + self->eeprom_map_p->addr_soft_rs1, + self->eeprom_map_p->page_soft_rs1, + self->eeprom_map_p->offset_soft_rs1, + bit_shift, + &_sfp_update_attr_soft_rs1, + &(self->soft_rs1), + "sfp_set_soft_rs1", + show_err); +} + + +int +__sfp_set_tx_eq(struct transvr_obj_s *self, + int input, + int show_e) { + + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + uint8_t setv = DEBUG_TRANSVR_HEX_VAL; + + if ((input < 0) || (input > 0xFF)) { + emsg = "input incorrect"; + err = ERR_TRANSVR_BADINPUT; + goto err_sfp_set_tx_eq; + } + setv = (uint8_t)input; + if (self->tx_eq[0] == setv) { + return 0; + } + err = _common_set_uint8_attr(self, + self->eeprom_map_p->addr_tx_eq, + self->eeprom_map_p->page_tx_eq, + self->eeprom_map_p->offset_tx_eq, + setv, + &(self->tx_eq[0]), + "_sfp_set_tx_eq", + show_e); + if (err < 0) { + emsg = "set_uint8_attr fail"; + goto err_sfp_set_tx_eq; + } + return 0; + +err_sfp_set_tx_eq: + if (show_e) { + SWPS_INFO("%s: %s :%d\n", __func__, emsg, input); + } + return err; +} + + +int +_sfp_set_tx_eq(struct transvr_obj_s *self, + int input, + int show_e) { + + uint8_t tmp; + int i = 0; + int retry = 3; + + for (i=0; itx_eq[0]; + if (_sfp_update_attr_tx_eq(self, show_e) < 0){ + continue; + } + if (self->tx_eq[0] == tmp){ + return 0; + } + } + return ERR_TRANSVR_UPDATE_FAIL; +} + + +int +sfp_set_tx_eq(struct transvr_obj_s *self, + int input) { + + int err = _check_by_mode(self, + &_sfp_update_attr_tx_eq, + "sfp_set_tx_eq"); + if (err < 0) { + SWPS_DEBUG("%s: check fail :%d\n", __func__, err); + return err; + } + return _sfp_set_tx_eq(self, input, 1); +} + + +int +__sfp_set_rx_em(struct transvr_obj_s *self, + int input, + int show_e) { + + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + uint8_t setv = DEBUG_TRANSVR_HEX_VAL; + + if ((input < 0) || (input > 0xFF)) { + emsg = "input incorrect"; + err = ERR_TRANSVR_BADINPUT; + goto err_sfp_set_rx_em; + } + setv = (uint8_t)input; + if (self->rx_em[0] == setv) { + return 0; + } + err = _common_set_uint8_attr(self, + self->eeprom_map_p->addr_rx_em, + self->eeprom_map_p->page_rx_em, + self->eeprom_map_p->offset_rx_em, + setv, + &(self->rx_em[0]), + "_sfp_set_rx_em", + show_e); + if (err < 0) { + emsg = "set_uint8_attr fail"; + goto err_sfp_set_rx_em; + } + return 0; + +err_sfp_set_rx_em: + if (show_e) { + SWPS_INFO("%s: %s :%d\n", __func__, emsg, input); + } + return err; +} + + +int +_sfp_set_rx_em(struct transvr_obj_s *self, + int input, + int show_e) { + + uint8_t tmp; + int i = 0; + int retry = 3; + + for (i=0; irx_em[0]; + if (_sfp_update_attr_rx_em(self, show_e) < 0){ + continue; + } + if (self->rx_em[0] == tmp){ + return 0; + } + } + return -1; +} + + +int +sfp_set_rx_em(struct transvr_obj_s *self, + int input) { + + int err = _check_by_mode(self, + &_sfp_update_attr_rx_em, + "sfp_set_rx_em"); + if (err < 0) { + SWPS_DEBUG("%s: check fail :%d\n", __func__, err); + return err; + } + return _sfp_set_rx_em(self, input, 1); +} + + +int +sfp_set_1g_rj45_extphy_offset(struct transvr_obj_s *self, + int input) { + + if (self->state != STATE_TRANSVR_CONNECTED) { + return ERR_TRANSVR_UNPLUGGED; + } + if ((self->info != TRANSVR_CLASS_BASE_T_1000) && + (self->info != TRANSVR_CLASS_BASE_T_1000_up) ){ + return ERR_TRANSVR_NOTSUPPORT; + } + if ((input < 0) || (input > 0xff)) { + return ERR_TRANSVR_BADINPUT; + } + self->extphy_offset = (uint8_t)input; + return 0; +} + + +int +sfp_set_1g_rj45_extphy_reg(struct transvr_obj_s *self, + int input) { + + int i = 0; + int retry = 3; + int delay = 200; + uint16_t tmp = 0; + + if (self->state != STATE_TRANSVR_CONNECTED) { + return ERR_TRANSVR_UNPLUGGED; + } + if ((self->info != TRANSVR_CLASS_BASE_T_1000) && + (self->info != TRANSVR_CLASS_BASE_T_1000_up) ){ + return ERR_TRANSVR_NOTSUPPORT; + } + if ((input < 0) || (input > 0xffff)) { + return ERR_TRANSVR_BADINPUT; + } + tmp = ((input & 0x00ff) << 8) | ((input & 0xff00) >> 8); + if (_common_setup_page(self, VAL_TRANSVR_EXTPHY_ADDR_56, + -1, self->extphy_offset, 1, 0) < 0) { + return -EIO; + } + for (i=0; i<=retry; i++) { + if (i2c_smbus_write_word_data(self->i2c_client_p, + self->extphy_offset, + tmp) >= 0) { + return 0; + } + msleep(delay); + } + SWPS_INFO("%s: retry:%d fail :%s :0x%02x\n", + __func__, retry, self->swp_name, self->extphy_offset); + return -EIO; +} + + +static int +__qsfp_set_cdr(struct transvr_obj_s *self, + int input_val, + int show_err) { + + uint8_t update_val; + int CDR_FEATURE_SUPPORTED = 0x3; + int retval = ERR_TRANSVR_UNEXCPT; + int err_code = ERR_TRANSVR_UNEXCPT; + char *err_msg = DEBUG_TRANSVR_STR_VAL; + char *func_name = "__qsfp_set_cdr"; + + /* Check input value */ + if ((input_val < 0) || (input_val > 0xff)){ + retval = ERR_TRANSVR_BADINPUT; + err_code = ERR_TRANSVR_BADINPUT; + err_msg = "Input range incorrect!"; + goto err_qsfp_set_cdr_1; + } + update_val = (uint8_t)input_val; + /* Check CDR supported by transceiver */ + err_code = qsfp_get_cdr_present(self); + if (err_code < 0) { + retval = err_code; + switch (err_code) { + case ERR_TRANSVR_UNINIT: + err_msg = "Check CDR present fail!"; + break; + case ERR_TRANSVR_UNPLUGGED: + err_msg = "Transceiver unplugged!"; + break; + default: + err_msg = "Check CDR present fail!"; + break; + } + goto err_qsfp_set_cdr_1; + } + if (err_code != CDR_FEATURE_SUPPORTED) { + retval = ERR_TRANSVR_NOTSUPPORT; + err_msg = "This transceiver not support CDR!"; + goto err_qsfp_set_cdr_1; + } + /* Check and update */ + err_code = _check_by_mode(self, + &_qsfp_update_attr_cdr, + func_name); + if ( (err_code < 0) || + (self->cdr == DEBUG_TRANSVR_HEX_VAL) ){ + retval = err_code; + err_msg = "Get current value fail!"; + goto err_qsfp_set_cdr_1; + } + /* Write input value to transceiver */ + return _common_set_uint8_attr(self, + self->eeprom_map_p->addr_cdr, + self->eeprom_map_p->page_cdr, + self->eeprom_map_p->offset_cdr, + update_val, + &(self->cdr), + func_name, + show_err); + +err_qsfp_set_cdr_1: + if (show_err) { + SWPS_INFO("%s: %s :%d :%s\n :%d\n", + __func__, err_msg, err_code, self->swp_name, input_val); + } + return retval; +} + + +int +qsfp_set_cdr(struct transvr_obj_s *self, + int input_val) { + return __qsfp_set_cdr(self, input_val, 1); +} + + +int +qsfp_set_soft_tx_disable(struct transvr_obj_s *self, + int input_val) { + + int show_err = 1; + int in_max = 0xf; /* 1111 */ + int in_min = 0x0; /* 0000 */ + int retval = DEBUG_TRANSVR_INT_VAL; + int update_val = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + retval = _check_by_mode(self, + &_qsfp_update_attr_soft_tx_disable, + "qsfp_set_soft_tx_disable"); + if (retval < 0) { + snprintf(err_msg, 63, "Not ready. err:%d", retval); + goto err_qsfp_set_soft_tx_disable; + } + if ((input_val > in_max) || + (input_val < in_min) ){ + retval = ERR_TRANSVR_BADINPUT; + snprintf(err_msg, 63, "Input value:%d incorrect!", input_val); + goto err_qsfp_set_soft_tx_disable; + } + if ((self->tx_disable & 0x0f) == input_val) { + return 0; + } + update_val = ((self->tx_disable & 0xf0) & input_val); + retval = _common_set_uint8_attr(self, + self->eeprom_map_p->addr_tx_disable, + self->eeprom_map_p->page_tx_disable, + self->eeprom_map_p->offset_tx_disable, + input_val, + &(self->tx_disable), + "qsfp_set_tx_disable", + show_err); + if (retval < 0) { + snprintf(err_msg, 63, "_common_set_uint8_attr:%d fail!", retval); + goto err_qsfp_set_soft_tx_disable; + } + return 0; + +err_qsfp_set_soft_tx_disable: + SWPS_INFO("%s: %s :%s\n", __func__, err_msg, self->swp_name); + return retval; +} + + +int +_qsfp_set_auto_tx_disable(struct transvr_obj_s *self, + uint8_t update) { + + uint8_t tx_enable = 0x0; + int show_e = 1; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + /* Handle timing issues */ + if (update != tx_enable) { + /* Note: + * Because there are some txvr has timing issues, + * therefore we need to execute reset cycle first. + * (enable -> other settings) + */ + err = _common_set_uint8_attr(self, + self->eeprom_map_p->addr_tx_disable, + self->eeprom_map_p->page_tx_disable, + self->eeprom_map_p->offset_tx_disable, + tx_enable, + &(self->tx_disable), + "_qsfp_set_auto_tx_disable", + show_e); + if (err < 0) { + emsg = "I2C set reset value fail"; + goto err_qsfp_set_auto_tx_disable; + } + mdelay(10); + } + /* Setup target value */ + err = _common_set_uint8_attr(self, + self->eeprom_map_p->addr_tx_disable, + self->eeprom_map_p->page_tx_disable, + self->eeprom_map_p->offset_tx_disable, + self->auto_tx_disable, + &(self->tx_disable), + "_qsfp_set_auto_tx_disable", + show_e); + if (err < 0) { + emsg = "I2C set target value fail"; + goto err_qsfp_set_auto_tx_disable; + } + /* Check and update */ + err = _common_update_uint8_attr(self, + self->eeprom_map_p->addr_tx_disable, + self->eeprom_map_p->page_tx_disable, + self->eeprom_map_p->offset_tx_disable, + self->eeprom_map_p->length_tx_disable, + &(self->tx_disable), + "_qsfp_set_auto_tx_disable", + show_e); + if (err < 0) { + emsg = "I2C get value fail"; + goto err_qsfp_set_auto_tx_disable; + } + if (self->tx_disable != update) { + emsg = "data not become effective"; + goto err_qsfp_set_auto_tx_disable; + } + return 0; + +err_qsfp_set_auto_tx_disable: + SWPS_DEBUG("%s: %s :%s\n", + __func__, emsg, self->swp_name); + return ERR_TRANSVR_UPDATE_FAIL; +} + + +int +qsfp_set_auto_tx_disable(struct transvr_obj_s *self, + int input_val) { + + int in_max = 0xf; /* 1111 */ + int in_min = 0x0; /* 0000 */ + int retval = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + + /* Update settings*/ + if (input_val == VAL_TRANSVR_FUNCTION_DISABLE) { + emsg = "User disable auto tx_disable"; + self->auto_tx_disable = VAL_TRANSVR_FUNCTION_DISABLE; + goto out_qsfp_set_auto_tx_disable; + } + if ((input_val > in_max) || (input_val < in_min) ){ + SWPS_INFO("%s: Input value:%d incorrect! :%s\n", + __func__, input_val, self->swp_name); + return ERR_TRANSVR_BADINPUT; + } + self->auto_tx_disable = input_val; + /* Check current soft tx_disable */ + retval = _check_by_mode(self, + &_qsfp_update_attr_soft_tx_disable, + "qsfp_set_auto_tx_disable"); + switch (retval) { + case 0: + break; + case ERR_TRANSVR_UNPLUGGED: + emsg = "Doesn't need to update"; + goto out_qsfp_set_auto_tx_disable; + default: + SWPS_INFO("%s: setup fail :%d :%s\n", + __func__, retval, self->swp_name); + return retval; + } + return _qsfp_set_auto_tx_disable(self, input_val); + +out_qsfp_set_auto_tx_disable: + SWPS_DEBUG("%s: %s :%s :%d\n :%d", + __func__, emsg, self->swp_name, input_val, retval); + return 0; +} + + +int +__qsfp_set_tx_eq(struct transvr_obj_s *self, + int input, + int show_e) { + /* [Note] + * 0x + */ + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + uint8_t setv[2] = {0x00, 0x00}; + + if ((input < 0) || (input > 0xFFFF)) { + emsg = "input incorrect"; + err = ERR_TRANSVR_BADINPUT; + goto err_qsfp_set_tx_eq; + } + setv[0] = (uint8_t)((input & 0xFF00) >> 8); + setv[1] = (uint8_t)(input & 0xFF); + if ((self->tx_eq[0] == setv[0]) && + (self->tx_eq[1] == setv[1]) ) { + return 0; + } + err = _common_set_uint8_array(self, + self->eeprom_map_p->addr_tx_eq, + self->eeprom_map_p->page_tx_eq, + self->eeprom_map_p->offset_tx_eq, + self->eeprom_map_p->length_tx_eq, + setv, + self->tx_eq, + "_qsfp_set_tx_eq", + show_e); + if (err < 0) { + emsg = "set_uint8_array fail"; + goto err_qsfp_set_tx_eq; + } + return 0; + +err_qsfp_set_tx_eq: + if (show_e) { + SWPS_INFO("%s: %s :%d\n", __func__, emsg, input); + } + return err; +} + + +int +_qsfp_set_tx_eq(struct transvr_obj_s *self, + int input, + int show_e) { + + int i = 0; + int retry = 3; + uint8_t tmp[2]; + + for (i=0; itx_eq[0]; + tmp[1] = self->tx_eq[1]; + if (_qsfp_update_attr_tx_eq(self, show_e) < 0){ + continue; + } + if ((self->tx_eq[0] == tmp[0]) && + (self->tx_eq[1] == tmp[1]) ){ + return 0; + } + } + return -1; +} + + +int +qsfp_set_tx_eq(struct transvr_obj_s *self, + int input) { + + int err = _check_by_mode(self, + &_qsfp_update_attr_tx_eq, + "qsfp_set_tx_eq"); + if (err < 0) { + SWPS_DEBUG("%s: check fail :%d\n", __func__, err); + return err; + } + return _qsfp_set_tx_eq(self, input, 1); +} + + +int +__qsfp_set_rx_am(struct transvr_obj_s *self, + int input, + int show_e) { + /* [Note] + * 0x + */ + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + uint8_t setv[2] = {0x00, 0x00}; + + if ((input < 0) || (input > 0xFFFF)) { + emsg = "input incorrect"; + err = ERR_TRANSVR_BADINPUT; + goto err_qsfp_set_rx_am; + } + setv[0] = (uint8_t)((input & 0xFF00) >> 8); + setv[1] = (uint8_t)(input & 0xFF); + if ((self->rx_am[0] == setv[0]) && + (self->rx_am[1] == setv[1]) ) { + return 0; + } + err = _common_set_uint8_array(self, + self->eeprom_map_p->addr_rx_am, + self->eeprom_map_p->page_rx_am, + self->eeprom_map_p->offset_rx_am, + self->eeprom_map_p->length_rx_am, + setv, + self->rx_am, + "_qsfp_set_rx_am", + show_e); + if (err < 0) { + emsg = "set_uint8_array fail"; + goto err_qsfp_set_rx_am; + } + return 0; + +err_qsfp_set_rx_am: + if (show_e) { + SWPS_INFO("%s: %s :%d\n", __func__, emsg, input); + } + return err; +} + + +int +_qsfp_set_rx_am(struct transvr_obj_s *self, + int input, + int show_e) { + + int i = 0; + int retry = 3; + uint8_t tmp[2]; + + for (i=0; irx_am[0]; + tmp[1] = self->rx_am[1]; + if (_qsfp_update_attr_rx_am(self, show_e) < 0){ + continue; + } + if ((self->rx_am[0] == tmp[0]) && + (self->rx_am[1] == tmp[1]) ){ + return 0; + } + } + return -1; +} + + +int +qsfp_set_rx_am(struct transvr_obj_s *self, + int input) { + + int err = _check_by_mode(self, + &_qsfp_update_attr_rx_am, + "qsfp_set_rx_am"); + if (err < 0) { + SWPS_DEBUG("%s: check fail :%d\n", __func__, err); + return err; + } + return _qsfp_set_rx_am(self, input, 1); +} + + +int +__qsfp_set_rx_em(struct transvr_obj_s *self, + int input, + int show_e) { + /* [Note] + * 0x + */ + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + uint8_t setv[2] = {0x00, 0x00}; + + if ((input < 0) || (input > 0xFFFF)) { + emsg = "input incorrect"; + err = ERR_TRANSVR_BADINPUT; + goto err_qsfp_set_rx_em; + } + setv[0] = (uint8_t)((input & 0xFF00) >> 8); + setv[1] = (uint8_t)(input & 0xFF); + if ((self->rx_em[0] == setv[0]) && + (self->rx_em[1] == setv[1]) ) { + return 0; + } + err = _common_set_uint8_array(self, + self->eeprom_map_p->addr_rx_em, + self->eeprom_map_p->page_rx_em, + self->eeprom_map_p->offset_rx_em, + self->eeprom_map_p->length_rx_em, + setv, + self->rx_em, + "_qsfp_set_rx_em", + show_e); + if (err < 0) { + emsg = "set_uint8_array fail"; + goto err_qsfp_set_rx_em; + } + return 0; + +err_qsfp_set_rx_em: + if (show_e) { + SWPS_INFO("%s: %s :%d\n", __func__, emsg, input); + } + return err; +} + + +int +_qsfp_set_rx_em(struct transvr_obj_s *self, + int input, + int show_e) { + + int i = 0; + int retry = 3; + uint8_t tmp[2]; + + for (i=0; irx_em[0]; + tmp[1] = self->rx_em[1]; + if (_qsfp_update_attr_rx_em(self, show_e) < 0){ + continue; + } + if ((self->rx_em[0] == tmp[0]) && + (self->rx_em[1] == tmp[1]) ){ + return 0; + } + } + return -1; +} + + +int +qsfp_set_rx_em(struct transvr_obj_s *self, + int input) { + + int err = _check_by_mode(self, + &_qsfp_update_attr_rx_em, + "qsfp_set_rx_em"); + if (err < 0) { + SWPS_DEBUG("%s: check fail :%d\n", __func__, err); + return err; + } + return _qsfp_set_rx_em(self, input, 1); +} + + +int +common_transvr_dump(struct transvr_obj_s* self){ + + char *type_name = "Undefined"; + + if (TRANSVR_INFO_DUMP_ENABLE != 1) { + return 0; + } + switch (self->type) { + case TRANSVR_TYPE_SFP: + type_name = STR_TRANSVR_SFP; + break; + case TRANSVR_TYPE_QSFP: + type_name = STR_TRANSVR_QSFP; + break; + case TRANSVR_TYPE_QSFP_PLUS: + type_name = STR_TRANSVR_QSFP_PLUS; + break; + case TRANSVR_TYPE_QSFP_28: + type_name = STR_TRANSVR_QSFP28; + break; + case TRANSVR_TYPE_FAKE: + type_name = "FAKE"; + goto ok_common_transvr_dump; + case TRANSVR_TYPE_UNPLUGGED: + type_name = "UNPLUGGED"; + goto err_common_transvr_dump; + case TRANSVR_TYPE_INCONSISTENT: + type_name = "INCONSISTENT"; + goto err_common_transvr_dump; + case TRANSVR_TYPE_ERROR: + type_name = "ERROR"; + goto err_common_transvr_dump; + + default: + type_name = "UNEXPECTED"; + goto err_common_transvr_dump; + } + printk(KERN_INFO "[SWPS] Dump %s information:\n", self->swp_name); + printk(KERN_INFO " |- :%s\n", type_name); + printk(KERN_INFO " |- :%s\n", self->vendor_name); + printk(KERN_INFO " |- :%s\n", self->vendor_pn); + printk(KERN_INFO " |- :%s\n", self->vendor_rev); + printk(KERN_INFO " |- :%s\n", self->vendor_sn); + printk(KERN_INFO " |- :0x%02x\n", self->br); + printk(KERN_INFO " |- :0x%02x\n", self->comp_rev); + printk(KERN_INFO " |- :%d\n", self->len_om1); + printk(KERN_INFO " |- :%d\n", self->len_om2); + printk(KERN_INFO " |- :%d\n", self->len_om3); + printk(KERN_INFO " |- :%d\n", self->len_om4); + return 0; + +ok_common_transvr_dump: + SWPS_INFO("%s: %s is %s\n", __func__, self->swp_name, type_name); + return 0; + +err_common_transvr_dump: + SWPS_INFO("%s: %s is %s\n", __func__, self->swp_name, type_name); + return -1; +} + + +int +sfp_transvr_dump(struct transvr_obj_s* self) { + + if (TRANSVR_INFO_DUMP_ENABLE != 1) { + return 0; + } + if (common_transvr_dump(self) < 0) { + return -1; + } + printk(KERN_INFO " |- :%d\n", self->len_sm); + printk(KERN_INFO " |- :%d\n", self->len_smf); + printk(KERN_INFO " '- :0x%02x\n", self->rate_id); + return 0; +} + + +int +qsfp_transvr_dump(struct transvr_obj_s* self) { + + if (TRANSVR_INFO_DUMP_ENABLE != 1) { + return 0; + } + if (common_transvr_dump(self) < 0) { + return -1; + } + printk(KERN_INFO " |- :%d\n", self->len_smf); + printk(KERN_INFO " '- :Class_%d\n", __qsfp_get_power_cls(self, 0)); + return 0; +} + + +int +fake_transvr_dump(struct transvr_obj_s* self) { + + printk(KERN_INFO "[SWPS] Dump transceiver information: %s\n", self->swp_name); + printk(KERN_INFO " |- :FAKE\n"); + printk(KERN_INFO " |- :FAKE_VENDER_NAME\n"); + printk(KERN_INFO " |- :FAKE_VENDER_PN\n"); + printk(KERN_INFO " |- :FAKE_VENDER_REV\n"); + printk(KERN_INFO " |- :FAKE_VENDER_SN\n"); + printk(KERN_INFO " |- :0x99\n"); + printk(KERN_INFO " |- :99\n"); + printk(KERN_INFO " |- :99\n"); + printk(KERN_INFO " |- :99\n"); + printk(KERN_INFO " |- :99\n"); + printk(KERN_INFO " |- :99\n"); + printk(KERN_INFO " |- :99\n"); + printk(KERN_INFO " '- :0x99\n"); + return 0; +} + + +/* ========== Object functions for fake type ========== + */ +int +fake_transvr_update(struct transvr_obj_s *self, + int show_err){ + self->state = STATE_TRANSVR_CONNECTED; + return 0; +} + + +int +fake_get_binary(struct transvr_obj_s *self){ + return 1; +} + +int +fake_get_int(struct transvr_obj_s *self){ + return 99; +} + + +int +fake_get_hex(struct transvr_obj_s *self){ + return 0x0f; +} + + +int +fake_get_str(struct transvr_obj_s *self, char *buf) { + return snprintf(buf, 16, "fake_get_str\n"); +} + + +int +fake_set_int(struct transvr_obj_s *self, int input){ + SWPS_INFO("%s: %d\n", __func__, input); + return 0; +} + + +int +fake_set_hex(struct transvr_obj_s *self, int input){ + SWPS_INFO("%s: 0x%02x\n", __func__, input); + return 0; +} + + +/* ========== Object functions for unsupported ========== + */ +int +unsupported_get_func(struct transvr_obj_s *self){ + return ERR_TRANSVR_NOTSUPPORT; +} + + +int +unsupported_get_func2(struct transvr_obj_s *self, + char *buf_p) { + int len = snprintf(buf_p, 8, "%d\n", ERR_TRANSVR_NOTSUPPORT); + return len; +} + + +int +unsupported_set_func(struct transvr_obj_s *self, + int input_val){ + return ERR_TRANSVR_NOTSUPPORT; +} + + + +/* ========== Object functions for long term task ========== + * + * [Note] + * SWPS transceiver worker is likely the green-thread (coroutine). + * Due to resource and performance considerations. SWPS run all + * features in one kthread at the same time, and handle by it self. + */ + +/* For Transceiver Task Handling + */ +static struct transvr_worker_s * +transvr_task_get(struct transvr_obj_s *self, + char *func_name) { + + struct transvr_worker_s *curr_p = self->worker_p; + + while(curr_p != NULL){ + if (strcmp((curr_p->func_name), func_name) == 0 ) { + return curr_p; + } + curr_p = curr_p->next_p; + } + return NULL; +} + + +static struct transvr_worker_s* +transvr_task_creat(struct transvr_obj_s *self, + int (*main_task)(struct transvr_worker_s *task), + int (*post_task)(struct transvr_worker_s *task), + char *caller) { + + struct transvr_worker_s *task_p = NULL; + struct transvr_worker_s *curr_p = NULL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + /* Check task not exist */ + task_p = transvr_task_get(self, caller); + if (task_p) { + snprintf(err_msg, sizeof(err_msg), "Task already created!"); + goto err_transvr_task_creat; + } + /* Create task worker */ + task_p = kzalloc(sizeof(struct transvr_worker_s), GFP_KERNEL); + if (!task_p){ + snprintf(err_msg, sizeof(err_msg), "kzalloc fail"); + goto err_transvr_task_creat; + } + /* Setup task data */ + task_p->transvr_p = self; + task_p->next_p = NULL; + task_p->trigger_time = 0; + task_p->retry = 1; + task_p->state = STATE_T_TASK_INIT; + task_p->main_task = main_task; + task_p->post_task = post_task; + task_p->p_data = NULL; + snprintf(task_p->func_name, sizeof(task_p->func_name), "%s", caller); + /* Setup Link List */ + if (self->worker_p) { + curr_p = self->worker_p; + while(curr_p->next_p != NULL) { + curr_p = curr_p->next_p; + } + curr_p->next_p = task_p; + task_p->pre_p = curr_p; + } else { + self->worker_p = task_p; + task_p->pre_p = NULL; + } + return task_p; + +err_transvr_task_creat: + SWPS_ERR("%s: %s :%s :%s\n", + __func__, err_msg, caller, self->swp_name); + return NULL; +} + + +static void +transvr_task_free_one(struct transvr_worker_s *task_p){ + + struct transvr_worker_s *pre_p = NULL; + struct transvr_worker_s *next_p = NULL; + + if (task_p) { + pre_p = task_p->pre_p; + next_p = task_p->next_p; + + if ((pre_p) && (next_p)) { + pre_p->next_p = next_p; + next_p->pre_p = pre_p; + + } else if ((!pre_p) && (next_p)) { + next_p->pre_p = NULL; + + } else if ((pre_p) && (!next_p)) { + pre_p->next_p = NULL; + + } else if ((!pre_p) && (!next_p)) { + task_p->transvr_p->worker_p = NULL; + } else { + SWPS_ERR("%s: Unexcept case!\n :%s", + __func__, task_p->transvr_p->swp_name); + } + kfree(task_p->p_data); + kfree(task_p); + } +} + + +static void +transvr_task_free_all(struct transvr_obj_s *self) { + + struct transvr_worker_s *curr_p = NULL; + struct transvr_worker_s *next_p = NULL; + + if (self->worker_p) { + curr_p = self->worker_p; + while(curr_p) { + next_p = curr_p->next_p; + transvr_task_free_one(curr_p); + curr_p = next_p; + } + self->worker_p = NULL; + } +} + + +static void +transvr_cache_free_all(struct transvr_obj_s *self) { + + memset(self->vendor_name, 0, (LEN_TRANSVR_M_STR * sizeof(char)) ); + memset(self->vendor_rev, 0, (LEN_TRANSVR_M_STR * sizeof(char)) ); + memset(self->vendor_pn, 0, (LEN_TRANSVR_M_STR * sizeof(char)) ); + memset(self->vendor_sn, 0, (LEN_TRANSVR_M_STR * sizeof(char)) ); + self->extphy_offset = 0; +} + +static int +_transvr_task_run_main(struct transvr_worker_s *task_p) { + + int retval = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + if (!task_p){ + snprintf(err_msg, sizeof(err_msg), "main_task is NULL!"); + goto main_transvr_task_err; + } + if ((task_p->trigger_time) == 0){ + goto main_transvr_task_run; + } + if (time_before(jiffies, task_p->trigger_time)){ + goto main_transvr_task_wait; + } + goto main_transvr_task_run; + +main_transvr_task_run: + if (task_p->retry != VAL_TRANSVR_TASK_RETRY_FOREVER) { + task_p->retry -= 1; + } + retval = task_p->main_task(task_p); + if (retval < 0) { + if (task_p->retry > 0) { + task_p->state = STATE_T_TASK_WAIT; + return EVENT_TRANSVR_TASK_WAIT; + } + snprintf(err_msg, sizeof(err_msg), "Run main_task fail!"); + goto main_transvr_task_err; + } + goto main_transvr_task_identify; + +main_transvr_task_identify: + switch (retval) { + case EVENT_TRANSVR_TASK_WAIT: + task_p->state = STATE_T_TASK_WAIT; + return EVENT_TRANSVR_TASK_WAIT; + + case EVENT_TRANSVR_TASK_DONE: + task_p->state = STATE_T_TASK_DONE; + return EVENT_TRANSVR_TASK_DONE; + + default: + break; + } + snprintf(err_msg, sizeof(err_msg), "Run main_task fail!"); + goto main_transvr_task_err; + +main_transvr_task_wait: + task_p->state = STATE_T_TASK_WAIT; + return EVENT_TRANSVR_TASK_WAIT; + +main_transvr_task_err: + task_p->state = STATE_T_TASK_FAIL; + SWPS_INFO("%s: %s :%d :%s\n", + __func__, err_msg, retval, task_p->transvr_p->swp_name); + return EVENT_TRANSVR_INIT_FAIL; +} + + +static int +_transvr_task_run_post(struct transvr_worker_s *task_p) { + + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + if ((task_p->post_task) == NULL) { + return EVENT_TRANSVR_TASK_DONE; + } + switch (task_p->state) { + case STATE_T_TASK_WAIT: + case STATE_T_TASK_INIT: + goto post_transvr_task_wait; + + case STATE_T_TASK_DONE: + case STATE_T_TASK_FAIL: + goto post_transvr_task_run; + + default: + break; + } + snprintf(err_msg, sizeof(err_msg), "Unexcept task state"); + goto post_transvr_task_err; + +post_transvr_task_run: + task_p->post_task(task_p); + return EVENT_TRANSVR_TASK_DONE; + +post_transvr_task_wait: + return EVENT_TRANSVR_TASK_WAIT; + +post_transvr_task_err: + SWPS_INFO("%s: %s :%d :%s\n", + __func__, err_msg, task_p->state, task_p->transvr_p->swp_name); + return EVENT_TRANSVR_TASK_FAIL; +} + + +static int +transvr_task_run_one(struct transvr_worker_s *task_p) { + + int retval_main = DEBUG_TRANSVR_INT_VAL; + int retval_post = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + retval_main = _transvr_task_run_main(task_p); + if (retval_main < 0) { + snprintf(err_msg, sizeof(err_msg), "Execute main_task fail!"); + goto err_transvr_task_run_one; + } + retval_post = _transvr_task_run_post(task_p); + if (retval_post < 0) { + snprintf(err_msg, sizeof(err_msg), "Execute post_task fail!"); + goto err_transvr_task_run_one; + } + return retval_main; + +err_transvr_task_run_one: + SWPS_INFO("%s: %s
:%d :%d :%s :%s\n", + __func__, err_msg, retval_main, retval_post, + task_p->func_name, task_p->transvr_p->swp_name); + return EVENT_TRANSVR_TASK_FAIL; +} + + +static int +transvr_task_run_all(struct transvr_obj_s *self) { + + int haserr = 0; + int retval = DEBUG_TRANSVR_INT_VAL; + struct transvr_worker_s *curr_p = NULL; + struct transvr_worker_s *next_p = NULL; + + if ((self->worker_p) == NULL) { + return EVENT_TRANSVR_TASK_DONE; + } + curr_p = self->worker_p; + while (curr_p != NULL) { + next_p = curr_p->next_p; + retval = transvr_task_run_one(curr_p); + if (curr_p->retry == VAL_TRANSVR_TASK_RETRY_FOREVER) { + curr_p = next_p; + continue; + } + switch (retval) { + case EVENT_TRANSVR_TASK_WAIT: + break; + case EVENT_TRANSVR_TASK_DONE: + transvr_task_free_one(curr_p); + break; + case EVENT_TRANSVR_TASK_FAIL: + + default: + haserr = 1; + transvr_task_free_one(curr_p); + break; + } + curr_p = next_p; + } + if (haserr) { + return EVENT_TRANSVR_TASK_FAIL; + } + return EVENT_TRANSVR_TASK_DONE; +} + + +static void +transvr_task_set_delay(struct transvr_worker_s *task_p, + unsigned long delay_msec) { + + task_p->trigger_time = (jiffies + (delay_msec * (HZ/1000))); +} + + +static void +transvr_task_set_retry(struct transvr_worker_s *task_p, + unsigned long retry_times) { + + task_p->retry = retry_times; +} + + +/* For Transceiver Post Task + */ +int +taskfunc_post_do_nothing(struct transvr_worker_s *task_p) { + + return EVENT_TRANSVR_TASK_DONE; +} + + +int +taskfunc_post_handle_task_state(struct transvr_worker_s *task_p) { + + struct transvr_obj_s* tp = task_p->transvr_p; + + switch (task_p->state) { + case STATE_T_TASK_INIT: + case STATE_T_TASK_WAIT: + return EVENT_TRANSVR_TASK_WAIT; + + case STATE_T_TASK_DONE: + tp->state = STATE_TRANSVR_CONNECTED; + tp->send_uevent(tp, KOBJ_ADD); + return EVENT_TRANSVR_TASK_DONE; + + case STATE_T_TASK_FAIL: + tp->state = STATE_TRANSVR_UNEXCEPTED; + return EVENT_TRANSVR_TASK_FAIL; + + default: + break; + } + return EVENT_TRANSVR_TASK_FAIL; +} + + +/* For Transceiver Main Task + */ +int +_taskfunc_sfp_setup_soft_rs(struct transvr_worker_s *task_p, + int input_val, + int address, + int page, + int offset, + int bit_shift, + uint8_t *attr_p, + char *caller) { + + int show_err = 0; + int err_code = DEBUG_TRANSVR_INT_VAL; + char *err_str = DEBUG_TRANSVR_STR_VAL; + char *func_str = "_taskfunc_sfp_setup_soft_rs"; + + err_code = _sfp_update_attr_soft_rs0(task_p->transvr_p, 0); + if (err_code < 0) { + err_str = "Get current soft_rs0 fail!"; + goto err_taskfunc_sfp_setup_soft_rs_1; + } + err_code = __sfp_set_soft_rs(task_p->transvr_p, + input_val, + address, + page, + offset, + bit_shift, + attr_p, + caller, + show_err); + if (err_code < 0) { + err_str = "Get current soft_rs0 fail!"; + goto err_taskfunc_sfp_setup_soft_rs_1; + } + return EVENT_TRANSVR_TASK_DONE; + +err_taskfunc_sfp_setup_soft_rs_1: + if ((task_p->retry) == 0) { + SWPS_INFO("%s: %s :%s :%d :%d\n", + func_str, err_str, task_p->transvr_p->swp_name, input_val, err_code); + } + return EVENT_TRANSVR_TASK_FAIL; +} + + +int +__taskfunc_sfp_setup_hard_rs(struct transvr_worker_s *task_p, + int input_val, + int (*get_func)(struct ioexp_obj_s *self, int virt_offset), + int (*set_func)(struct ioexp_obj_s *self, int virt_offset, int input_val)) { + + int err_val = EVENT_TRANSVR_EXCEP_EXCEP; + char *err_str = DEBUG_TRANSVR_STR_VAL; + + err_val = get_func(task_p->transvr_p->ioexp_obj_p, + task_p->transvr_p->ioexp_virt_offset); + + if (err_val < 0) { + if (err_val == ERR_IOEXP_NOTSUPPORT) { + return EVENT_TRANSVR_TASK_DONE; + } + err_str = "Get current hard_rs fail!"; + goto err_p_taskfunc_sfp_setup_hard_rs_1; + } + if (err_val == input_val) { + return EVENT_TRANSVR_TASK_DONE; + } + err_val = set_func(task_p->transvr_p->ioexp_obj_p, + task_p->transvr_p->ioexp_virt_offset, + input_val); + if (err_val < 0) { + err_str = "Setup hard_rs fail!"; + goto err_p_taskfunc_sfp_setup_hard_rs_1; + } + return EVENT_TRANSVR_TASK_DONE; + +err_p_taskfunc_sfp_setup_hard_rs_1: + if ((task_p->retry) == 0) { + SWPS_INFO("%s: %s :%s :%d :%d\n", + __func__, err_str, task_p->transvr_p->swp_name, input_val, err_val); + } + return EVENT_TRANSVR_TASK_FAIL; +} + + +int +_taskfunc_sfp_setup_hard_rs0(struct transvr_worker_s *task_p, + int input_val) { + + return __taskfunc_sfp_setup_hard_rs(task_p, + input_val, + task_p->transvr_p->ioexp_obj_p->get_hard_rs0, + task_p->transvr_p->ioexp_obj_p->set_hard_rs0); +} + + +int +_taskfunc_sfp_setup_hard_rs1(struct transvr_worker_s *task_p, + int input_val) { + + return __taskfunc_sfp_setup_hard_rs(task_p, + input_val, + task_p->transvr_p->ioexp_obj_p->get_hard_rs1, + task_p->transvr_p->ioexp_obj_p->set_hard_rs1); +} + + +int +_taskfunc_sfp_setup_rs0(struct transvr_worker_s *task_p, + int input_val) { + + int bit_shift = 3; + int old_val = DEBUG_TRANSVR_INT_VAL; + int err_val = EVENT_TRANSVR_EXCEP_EXCEP; + char *err_str = DEBUG_TRANSVR_STR_VAL; + char *func_str = "_taskfunc_sfp_setup_rs0"; + + err_val = _taskfunc_sfp_setup_hard_rs0(task_p, + input_val); + if (err_val < 0) { + err_str = "Setup hard_rs0 fail!"; + goto err_private_taskfunc_sfp_setup_rs0_1; + } + old_val = err_val; + err_val = _taskfunc_sfp_setup_soft_rs(task_p, + input_val, + task_p->transvr_p->eeprom_map_p->addr_soft_rs0, + task_p->transvr_p->eeprom_map_p->page_soft_rs0, + task_p->transvr_p->eeprom_map_p->offset_soft_rs0, + bit_shift, + &(task_p->transvr_p->soft_rs0), + func_str); + if (err_val < 0) { + err_str = "Setup soft_rs0 fail!"; + goto err_private_taskfunc_sfp_setup_rs0_1; + } + return EVENT_TRANSVR_TASK_DONE; + +err_private_taskfunc_sfp_setup_rs0_1: + if ((task_p->retry) == 0) { + SWPS_INFO("%s: %s :%s :%d :%d\n", + func_str, err_str, task_p->transvr_p->swp_name, input_val, err_val); + } + _taskfunc_sfp_setup_hard_rs0(task_p, old_val); + return EVENT_TRANSVR_TASK_FAIL; +} + + +int +_taskfunc_sfp_setup_rs1(struct transvr_worker_s *task_p, + int input_val) { + + int bit_shift = 3; + int old_val = DEBUG_TRANSVR_INT_VAL; + int err_val = EVENT_TRANSVR_EXCEP_EXCEP; + char *err_str = DEBUG_TRANSVR_STR_VAL; + char *func_str = "_taskfunc_sfp_setup_rs1"; + + err_val = _taskfunc_sfp_setup_hard_rs1(task_p, + input_val); + if (err_val < 0) { + err_str = "Setup hard_rs1 fail!"; + goto err_private_taskfunc_sfp_setup_rs1_1; + } + old_val = err_val; + err_val = _taskfunc_sfp_setup_soft_rs(task_p, + input_val, + task_p->transvr_p->eeprom_map_p->addr_soft_rs1, + task_p->transvr_p->eeprom_map_p->page_soft_rs1, + task_p->transvr_p->eeprom_map_p->offset_soft_rs1, + bit_shift, + &(task_p->transvr_p->soft_rs1), + func_str); + if (err_val < 0) { + err_str = "Setup soft_rs1 fail!"; + goto err_private_taskfunc_sfp_setup_rs1_1; + } + return EVENT_TRANSVR_TASK_DONE; + +err_private_taskfunc_sfp_setup_rs1_1: + if ((task_p->retry) == 0) { + SWPS_INFO("%s: %s :%s :%d :%d\n", + func_str, err_str, task_p->transvr_p->swp_name, input_val, err_val); + } + _taskfunc_sfp_setup_hard_rs1(task_p, old_val); + return EVENT_TRANSVR_TASK_FAIL; +} + + +int +taskfunc_sfp_setup_SFF8431_case1(struct transvr_worker_s *task_p) { + /* SFF-8431 (8/4/2G Rx Rate_Select only) */ + int update_val = 1; + + return _taskfunc_sfp_setup_rs0(task_p, update_val); +} + + + +int +taskfunc_sfp_setup_SFF8431_case2(struct transvr_worker_s *task_p) { + /* SFF-8431 (8/4/2G Tx Rate_Select only) */ + int update_val = 1; + + return _taskfunc_sfp_setup_rs1(task_p, update_val); +} + + +int +taskfunc_sfp_setup_SFF8431_case3(struct transvr_worker_s *task_p) { + /* SFF-8431 (8/4/2G Independent Rx & Tx Rate_select) */ + int update_rs0 = 1; + int update_rs1 = 1; + int err_code = DEBUG_TRANSVR_INT_VAL; + + err_code = _taskfunc_sfp_setup_rs0(task_p, update_rs0); + if (err_code < 0) { + return err_code; + } + return _taskfunc_sfp_setup_rs1(task_p, update_rs1); +} + + +int +taskfunc_sfp_handle_1g_rj45(struct transvr_worker_s *task_p) { + + /* Not all of platform support 0x56 for transceiver + * external PHY, Support list as below: + * => 1. Magnolia-PVT (PS: EVT & DVT not ready) + */ + int ext_phy_addr = 0x56; + int ext_phy_page = -1; + int ext_phy_offs = 0x11; + int ext_phy_len = 1; + int lstate_mask = 0x04; /* 00000100 */ + int show_err = 0; + int fail_retry = 5; + int fail_delay = 1000; /* msec */ + int err_code = DEBUG_TRANSVR_INT_VAL; + uint8_t detect_val = DEBUG_TRANSVR_HEX_VAL; + char err_str[64] = DEBUG_TRANSVR_STR_VAL; + int *tmp_p = NULL; + char *func_name = "taskfunc_sfp_handle_1g_rj45"; + + if (task_p->transvr_p->state != STATE_TRANSVR_CONNECTED) { + return EVENT_TRANSVR_TASK_DONE; + } + if ( (task_p->transvr_p->info != TRANSVR_CLASS_BASE_T_1000) && + (task_p->transvr_p->info != TRANSVR_CLASS_BASE_T_1000_up) ) { + goto err_taskfunc_sfp_handle_1g_rj45_1; + } + err_code = _common_update_uint8_attr(task_p->transvr_p, + ext_phy_addr, + ext_phy_page, + ext_phy_offs, + ext_phy_len, + &detect_val, + func_name, + show_err); + if ( (err_code < 0) || + (detect_val == DEBUG_TRANSVR_HEX_VAL) ) { + snprintf(err_str, sizeof(err_str), "Detect external link status fail"); + goto err_taskfunc_sfp_handle_1g_rj45_2; + } + if ((detect_val & lstate_mask) == lstate_mask) { + goto ok_taskfunc_sfp_handle_1g_rj45_link_up; + } + goto ok_taskfunc_sfp_handle_1g_rj45_link_down; + +ok_taskfunc_sfp_handle_1g_rj45_link_up: + /* Filter out noise */ + if (!(task_p->p_data)) { + tmp_p = kzalloc(sizeof(int), GFP_KERNEL); + if (!tmp_p) { + snprintf(err_str, sizeof(err_str), "kzalloc p_data fail"); + goto err_taskfunc_sfp_handle_1g_rj45_2; + } + *tmp_p = TRANSVR_CLASS_BASE_T_1000_up; + task_p->p_data = tmp_p; + goto ok_taskfunc_sfp_handle_1g_rj45_done; + } + if ((*(int *)(task_p->p_data)) != TRANSVR_CLASS_BASE_T_1000_up) { + kfree(task_p->p_data); + task_p->p_data = NULL; + snprintf(err_str, sizeof(err_str), "Internal error"); + goto err_taskfunc_sfp_handle_1g_rj45_2; + } + task_p->transvr_p->info = TRANSVR_CLASS_BASE_T_1000_up; + kfree(task_p->p_data); + task_p->p_data = NULL; + goto ok_taskfunc_sfp_handle_1g_rj45_done; + +ok_taskfunc_sfp_handle_1g_rj45_link_down: + if (task_p->p_data) { + kfree(task_p->p_data); + task_p->p_data = NULL; + } + task_p->transvr_p->info = TRANSVR_CLASS_BASE_T_1000; + goto ok_taskfunc_sfp_handle_1g_rj45_done; + +ok_taskfunc_sfp_handle_1g_rj45_done: + if (task_p->retry != VAL_TRANSVR_TASK_RETRY_FOREVER) { + transvr_task_set_retry(task_p, VAL_TRANSVR_TASK_RETRY_FOREVER); + } + return EVENT_TRANSVR_TASK_DONE; + +err_taskfunc_sfp_handle_1g_rj45_1: + snprintf(err_str, sizeof(err_str), "Detect transceiver:%d not Base-T, remove task.", + task_p->transvr_p->info); + SWPS_INFO("%s: %s :%s\n", __func__, err_str, task_p->transvr_p->swp_name); + transvr_task_set_retry(task_p, 0); + return EVENT_TRANSVR_TASK_DONE; + +err_taskfunc_sfp_handle_1g_rj45_2: + if (task_p->retry == VAL_TRANSVR_TASK_RETRY_FOREVER) { + transvr_task_set_retry(task_p, fail_retry); + } + if ((task_p->retry) == 0) { + /* Error case: + * => In this case, SWPS will stop external Link state monitor features + * and keeps transvr_p->info on TRANSVR_CLASS_BASE_T_1000_up. + * Upper layer will see it always Linkup that because of these type of + * transceiver has external phy, BCM chip see it as Loopback transceiver. + */ + SWPS_WARN("%s can not access external PHY of Base-T SFP transceiver\n", + task_p->transvr_p->swp_name); + task_p->transvr_p->info = TRANSVR_CLASS_BASE_T_1000_up; + return EVENT_TRANSVR_TASK_DONE; + } else { + transvr_task_set_delay(task_p, fail_delay); + } + return EVENT_TRANSVR_TASK_FAIL; +} + + +int +_taskfunc_qsfp_setup_power_mod(struct transvr_obj_s *self, + int setup_val) { + + int curr_val = DEBUG_TRANSVR_INT_VAL; + int err_val = DEBUG_TRANSVR_INT_VAL; + char *err_msg = DEBUG_TRANSVR_STR_VAL; + if (io_no_init) { + + SWPS_INFO("%s no_io_init\n",__func__); + return EVENT_TRANSVR_TASK_DONE; + } + + curr_val = self->ioexp_obj_p->get_lpmod(self->ioexp_obj_p, + self->ioexp_virt_offset); + if (curr_val < 0){ + err_msg = "Get current value fail!"; + goto err_private_taskfunc_qsfp_setup_power_mod_1; + } + if (curr_val == setup_val){ + return EVENT_TRANSVR_TASK_DONE; + } + err_val = self->ioexp_obj_p->set_lpmod(self->ioexp_obj_p, + self->ioexp_virt_offset, + setup_val); + if (err_val < 0){ + err_msg = "Setup power mode fail!"; + goto err_private_taskfunc_qsfp_setup_power_mod_1; + } + return EVENT_TRANSVR_TASK_DONE; + +err_private_taskfunc_qsfp_setup_power_mod_1: + SWPS_INFO("%s: %s :%d :%d :%d\n", + __func__, err_msg, err_val, curr_val, setup_val); + return EVENT_TRANSVR_TASK_FAIL; +} + + +int +taskfunc_qsfp_handle_tx_disable(struct transvr_worker_s *task_p) { + + int i = 0; + int retry = 5; + int delay_ms = 100; + + if (task_p->transvr_p->auto_tx_disable == VAL_TRANSVR_FUNCTION_DISABLE) { + return EVENT_TRANSVR_TASK_DONE; + } + if (!_qsfp_is_implement_tx_disable(task_p->transvr_p)) { + return EVENT_TRANSVR_TASK_DONE; + } + for (i=0; itransvr_p, + task_p->transvr_p->auto_tx_disable) + == EVENT_TRANSVR_TASK_DONE) { + goto ok_taskfunc_qsfp_handle_tx_disable; + } + mdelay(delay_ms); + } + SWPS_INFO("%s auto setup tx_disable:0x%02x fail.\n", + task_p->transvr_p->swp_name, + task_p->transvr_p->auto_tx_disable); + return EVENT_TRANSVR_INIT_FAIL; + +ok_taskfunc_qsfp_handle_tx_disable: + SWPS_INFO("%s auto setup tx_disable:0x%02x ok.\n", + task_p->transvr_p->swp_name, + task_p->transvr_p->auto_tx_disable); + return EVENT_TRANSVR_TASK_DONE; +} + + +int +taskfunc_qsfp_set_hpmod(struct transvr_worker_s *task_p) { + + int err = DEBUG_TRANSVR_INT_VAL; + int HIGH_POWER_MODE = 0; + + /* Handle power mode */ + err = _taskfunc_qsfp_setup_power_mod(task_p->transvr_p, + HIGH_POWER_MODE); + if (err < 0) { + SWPS_INFO("%s: setup hpmod fail :%d :%s\n", + __func__, err, task_p->transvr_p->swp_name); + return err; + } + /* Handle auto tx_disable + * [Note] + * => Because there are some transceiver have timing issues or + * setup sequence issues, therefore we handle auto tx_disable + * after handle power mode. + */ + mdelay(100); + return taskfunc_qsfp_handle_tx_disable(task_p); +} + + +int +taskfunc_qsfp_set_lpmod(struct transvr_worker_s *task_p) { + + int LOW_POWER_MODE = 1; + return _taskfunc_qsfp_setup_power_mod(task_p->transvr_p, + LOW_POWER_MODE); +} + + +static int +initfunc_sfp_handle_multi_rate_mode(struct transvr_obj_s *self) { + + int task_retry = 3; + int err_code = DEBUG_TRANSVR_INT_VAL; + char *err_str = DEBUG_TRANSVR_STR_VAL; + char *func_str = "sfp_handle_multi_rate_mode"; + struct transvr_worker_s *task_p = NULL; + + switch (self->rate_id) { + case 0x00: /* Unspecified */ + case 0x03: /* Unspecified */ + case 0x05: /* Unspecified */ + case 0x07: /* Unspecified */ + case 0x09: /* Unspecified */ + case 0x0B: /* Unspecified */ + case 0x0D: /* Unspecified */ + case 0x0F: /* Unspecified */ + goto sfp_handle_multi_rate_mode_4_unspecified; + + case 0x02: /* SFF-8431 (8/4/2G Rx Rate_Select only) */ + task_p = transvr_task_creat(self, + taskfunc_sfp_setup_SFF8431_case1, + taskfunc_post_handle_task_state, + func_str); + goto sfp_handle_multi_rate_mode_4_sff8431; + + case 0x04: /* SFF-8431 (8/4/2G Tx Rate_Select only) */ + task_p = transvr_task_creat(self, + taskfunc_sfp_setup_SFF8431_case2, + taskfunc_post_handle_task_state, + func_str); + goto sfp_handle_multi_rate_mode_4_sff8431; + + case 0x06: /* SFF-8431 (8/4/2G Independent Rx & Tx Rate_select) */ + task_p = transvr_task_creat(self, + taskfunc_sfp_setup_SFF8431_case3, + taskfunc_post_handle_task_state, + func_str); + goto sfp_handle_multi_rate_mode_4_sff8431; + + case 0x01: /* SFF-8079 (4/2/1G Rate_Select & AS0/AS1) */ + err_str = "SFF-8079 (4/2/1G Rate_Select & AS0/AS1)"; + goto sfp_handle_multi_rate_mode_4_not_support; + + case 0x08: /* FC-PI-5 (16/8/4G Rx Rate_select only) + * High=16G only, Low=8G/4G + */ + err_str = "FC-PI-5 (16/8/4G Rx Rate_select only)"; + goto sfp_handle_multi_rate_mode_4_not_support; + + case 0x0A: /* FC-PI-5 (16/8/4G Independent Rx, Tx Rate_select) + * High=16G only, Low=8G/4G + */ + err_str = "FC-PI-5 (16/8/4G Independent Rx, Tx Rate_select)"; + goto sfp_handle_multi_rate_mode_4_not_support; + + case 0x0C: /* FC-PI-6 (32/16/8G Independent Rx, Tx Rate_Select) + * High=32G only, Low = 16G/8G + */ + err_str = "FC-PI-6 (32/16/8G Independent Rx, Tx Rate_Select)"; + goto sfp_handle_multi_rate_mode_4_not_support; + + case 0x0E: /* 10/8G Rx and Tx Rate_Select controlling the operation or + * locking modes of the internal signal conditioner, retimer + * or CDR, according to the logic table defined in Table 10-2, + * High Bit Rate (10G) =9.95-11.3 Gb/s; Low Bit Rate (8G) = + * 8.5 Gb/s. In this mode, the default value of bit 110.3 (Soft + * Rate Select RS(0), Table 9-11) and of bit 118.3 (Soft Rate + * Select RS(1), Table 10-1) is 1. + */ + err_str = "cable type: 0x0E"; + goto sfp_handle_multi_rate_mode_4_not_support; + + default: + err_str = "cable type: UNKNOW"; + goto sfp_handle_multi_rate_mode_4_not_support; + } + +sfp_handle_multi_rate_mode_4_sff8431: + if (!task_p) { + err_str = "Create task fail!"; + goto sfp_handle_multi_rate_mode_4_fail_1; + } + transvr_task_set_retry(task_p, task_retry); + return EVENT_TRANSVR_TASK_WAIT; + +sfp_handle_multi_rate_mode_4_unspecified: + return EVENT_TRANSVR_TASK_DONE; + +sfp_handle_multi_rate_mode_4_not_support: + SWPS_INFO("%s: Does not support %s :%s :0x%02x\n", + func_str, err_str, self->swp_name, self->rate_id); + return EVENT_TRANSVR_TASK_DONE; + +sfp_handle_multi_rate_mode_4_fail_1: + SWPS_INFO("%s: %s :%s :0x%02x, :%d\n", + func_str, err_str, self->swp_name, self->rate_id, err_code); + return EVENT_TRANSVR_INIT_FAIL; +} + + +static int +initfunc_sfp_handle_1g_rj45(struct transvr_obj_s *self) { + + struct transvr_worker_s *task_p = NULL; + int detect_cls = DEBUG_TRANSVR_INT_VAL; + char err_str[64] = DEBUG_TRANSVR_STR_VAL; + char *func_str = "initfunc_sfp_handle_1g_rj45"; + + + if (self->info == TRANSVR_CLASS_BASE_T_1000) { + task_p = transvr_task_creat(self, + taskfunc_sfp_handle_1g_rj45, + taskfunc_post_do_nothing, + func_str); + if (!task_p) { + snprintf(err_str, sizeof(err_str), "Create task fail"); + goto err_initfunc_sfp_handle_1g_rj45; + } + transvr_task_set_retry(task_p, VAL_TRANSVR_TASK_RETRY_FOREVER); + } + return EVENT_TRANSVR_TASK_DONE; + +err_initfunc_sfp_handle_1g_rj45: + SWPS_INFO("%s: %s :%s :%d\n", + __func__, err_str, self->swp_name, detect_cls); + return EVENT_TRANSVR_TASK_FAIL; +} + + +static int +initfunc_qsfp_handle_power_mode(struct transvr_obj_s *self) { + + int err_code = EVENT_TRANSVR_EXCEP_INIT; + int power_class = DEBUG_TRANSVR_INT_VAL; + int hpmod_retry = 3; + int lpower_config = 1; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + unsigned long hpmod_delay = 500; /* msec */ + struct transvr_worker_s *task_p = NULL; + + /* Handle power mode for IOEXP */ + power_class = __qsfp_get_power_cls(self, 0); + switch (power_class) { + case 1: /* Case: Low power mode (Class = 1) */ + err_code = _taskfunc_qsfp_setup_power_mod(self, lpower_config); + if (err_code < 0){ + snprintf(err_msg, sizeof(err_msg), "Setup lpmod fail :%d", err_code); + goto err_initfunc_qsfp_handle_power_mode; + } + return EVENT_TRANSVR_TASK_DONE; + + case 2: /* Case: High power mode (Class > 1) */ + case 3: + case 4: + case 5: + case 6: + case 7: + task_p = transvr_task_creat(self, + taskfunc_qsfp_set_hpmod, + taskfunc_post_handle_task_state, + "transvr_init_qsfp"); + if (!task_p) { + snprintf(err_msg, sizeof(err_msg), "Setup lpmod fail :%d", err_code); + goto err_initfunc_qsfp_handle_power_mode; + } + transvr_task_set_retry(task_p, hpmod_retry); + transvr_task_set_delay(task_p, hpmod_delay); + return EVENT_TRANSVR_TASK_WAIT; + + default: + break; + } + snprintf(err_msg, sizeof(err_msg), "Exception case"); + goto err_initfunc_qsfp_handle_power_mode; + +err_initfunc_qsfp_handle_power_mode: + SWPS_INFO("%s: %s :%s \n", __func__, err_msg, self->swp_name); + return EVENT_TRANSVR_INIT_FAIL; +} + + +int +initfunc_qsfp28_handle_cdr(struct transvr_obj_s *self) { + + uint8_t DEFAULT_VAL_CDR = 0xff; + int CDR_FUNC_EXISTED = 0x3; + int show_err = 1; + int err_val = EVENT_TRANSVR_TASK_FAIL; + char *err_msg = DEBUG_TRANSVR_STR_VAL; + char *func_str = "initfunc_qsfp28_handle_cdr"; + + err_val = __qsfp_get_cdr_present(self, 0); + if ( (err_val < 0) || + (err_val == DEBUG_TRANSVR_HEX_VAL) ) { + err_msg = "detect cdr_present fail!"; + goto err_taskfunc_qsfp_handle_cdr_1; + } + if (err_val == CDR_FUNC_EXISTED) { + err_val = _common_set_uint8_attr(self, + self->eeprom_map_p->addr_cdr, + self->eeprom_map_p->addr_cdr, + self->eeprom_map_p->offset_cdr, + DEFAULT_VAL_CDR, + &(self->cdr), + func_str, + show_err); + if (err_val < 0) { + err_msg = "set CDR fail!"; + goto err_taskfunc_qsfp_handle_cdr_1; + } + } + return EVENT_TRANSVR_TASK_DONE; + +err_taskfunc_qsfp_handle_cdr_1: + SWPS_INFO("%s: %s :%d :%s\n", + func_str, err_msg, err_val, self->swp_name); + return EVENT_TRANSVR_INIT_FAIL; +} + +/* ========== Object functions for Final State Machine ========== + */ +int +is_plugged(struct transvr_obj_s *self){ + + int limit = 63; + int present = DEBUG_TRANSVR_INT_VAL; + char emsg[64] = DEBUG_TRANSVR_STR_VAL; + struct ioexp_obj_s *ioexp_p = self->ioexp_obj_p; + + if (!ioexp_p) { + snprintf(emsg, limit, "ioexp_p is null!"); + goto err_is_plugged_1; + } + present = ioexp_p->get_present(ioexp_p, self->ioexp_virt_offset); + switch (present){ + case 0: + return 1; + case 1: + return 0; + case ERR_IOEXP_UNINIT: + snprintf(emsg, limit, "ioexp_p not ready!"); + goto err_is_plugged_1; + default: + if (ioexp_p->state == STATE_IOEXP_INIT){ + snprintf(emsg, limit, "ioexp_p not ready!"); + goto err_is_plugged_1; + } + break; + } + SWPS_INFO("%s: Exception case! :%d :%d\n", + __func__, present, ioexp_p->state); + return 0; + +err_is_plugged_1: + SWPS_DEBUG("%s: %s\n", __func__, emsg); + return 0; +} + + +static int +detect_transvr_type(struct transvr_obj_s* self){ + + int type = TRANSVR_TYPE_ERROR; + + self->i2c_client_p->addr = VAL_TRANSVR_COMID_ARREESS; + type = i2c_smbus_read_byte_data(self->i2c_client_p, + VAL_TRANSVR_COMID_OFFSET); + + /* Case: 1. Wait transceiver I2C module. + * 2. Transceiver I2C module failure. + * Note: 1. SFF allow maximum transceiver initial time is 2 second. So, there + * are exist some case that we need to wait transceiver. + * For these case, we keeps status on "TRANSVR_TYPE_UNPLUGGED", than + * state machine will keep trace with it. + * 2. There exist some I2C failure case we need to handle. Such as user + * insert the failure transceiver, or any reason cause it abnormal. + */ + if (type < 0){ + switch (type) { + case -EIO: + SWPS_DEBUG("%s: %s smbus return:-5 (I/O error)\n", + __func__, self->swp_name); + return TRANSVR_TYPE_UNPLUGGED; + case -ENXIO: + SWPS_DEBUG("%s: %s smbus return:-6 (No such device or address)\n", + __func__, self->swp_name); + return TRANSVR_TYPE_UNPLUGGED; + default: + break; + } + SWPS_INFO("%s: %s unexpected smbus return:%d \n", + __func__, self->swp_name, type); + return TRANSVR_TYPE_ERROR; + } + /* Identify valid transceiver type */ + switch (type){ + case TRANSVR_TYPE_SFP: + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + case TRANSVR_TYPE_QSFP_28: + break; + case TRANSVR_TYPE_UNKNOW_1: + case TRANSVR_TYPE_UNKNOW_2: + type = TRANSVR_TYPE_UNKNOW_2; + break; + default: + SWPS_DEBUG("%s: unknow type:0x%02x \n", __func__, type); + type = TRANSVR_TYPE_ERROR; + break; + } + return type; +} + + +static int +detect_transvr_state(struct transvr_obj_s *self, + int result[2]){ + /* [return] [result-0] [result-1] + * 0 STATE_TRANSVR_CONNECTED TRANSVR_TYPE_FAKE + * 0 STATE_TRANSVR_DISCONNECTED TRANSVR_TYPE_UNPLUGGED + * 0 STATE_TRANSVR_ISOLATED TRANSVR_TYPE_ERROR + * 0 STATE_TRANSVR_INIT / + * 0 STATE_TRANSVR_SWAPPED + * 0 STATE_TRANSVR_CONNECTED + * ERR_TRNASVR_BE_ISOLATED STATE_TRANSVR_ISOLATED TRANSVR_TYPE_ERROR + * ERR_TRANSVR_I2C_CRASH STATE_TRANSVR_UNEXCEPTED TRANSVR_TYPE_ERROR + * ERR_TRANSVR_UNEXCPT STATE_TRANSVR_UNEXCEPTED TRANSVR_TYPE_UNKNOW_1/2 + */ + result[0] = STATE_TRANSVR_UNEXCEPTED; /* For return state */ + result[1] = TRANSVR_TYPE_ERROR; /* For return type */ + + /* Case1: Fake type */ + if (self->type == TRANSVR_TYPE_FAKE){ + result[0] = STATE_TRANSVR_CONNECTED; + result[1] = TRANSVR_TYPE_FAKE; + return 0; + } + /* Case2: Transceiver unplugged */ + if (!is_plugged(self)){ + result[0] = STATE_TRANSVR_DISCONNECTED; + result[1] = TRANSVR_TYPE_UNPLUGGED; + return 0; + } + /* Case3: Transceiver be isolated */ + if (self->state == STATE_TRANSVR_ISOLATED){ + result[0] = STATE_TRANSVR_ISOLATED; + result[1] = TRANSVR_TYPE_ERROR; + return ERR_TRNASVR_BE_ISOLATED; + } + /* Case4: Transceiver plugged */ + result[1] = detect_transvr_type(self); + /* Case4.1: I2C topology crash + * Note : There are some I2C issues cause by transceiver/cables. + * We need to check topology status when user insert it. + * But in this step, we can't not ensure this is the issues + * port. So, it return the ERR_TRANSVR_I2C_CRASH, then upper + * layer will diagnostic I2C topology. + */ + if (check_channel_tier_1() < 0) { + SWPS_INFO("%s: %s detect I2C crash :%d\n", + __func__, self->swp_name, self->state); + result[0] = STATE_TRANSVR_UNEXCEPTED; + result[1] = TRANSVR_TYPE_ERROR; + return ERR_TRANSVR_I2C_CRASH; + } + /* Case4.2: System initial not ready, + * Note : Sometime i2c channel or transceiver EEPROM will delay that will + * cause system in inconsistent state between EEPROM and IOEXP. + * In this case, SWP transceiver object keep state at LINK_DOWN + * to wait system ready. + * By the way, State Machine will handle these case. + */ + if (result[1] == TRANSVR_TYPE_UNPLUGGED){ + result[0] = STATE_TRANSVR_DISCONNECTED; + return 0; + } + /* Case4.3: Error transceiver type */ + if (result[1] == TRANSVR_TYPE_ERROR){ + result[0] = STATE_TRANSVR_ISOLATED; + SWPS_INFO("%s: %s detect error type\n", __func__, self->swp_name); + alarm_msg_2_user(self, "detected transceiver/cables not meet SFF standard!"); + return ERR_TRNASVR_BE_ISOLATED; + } + /* Case3.3: Unknow transceiver type */ + if ((result[1] == TRANSVR_TYPE_UNKNOW_1) || + (result[1] == TRANSVR_TYPE_UNKNOW_2) ){ + result[0] = STATE_TRANSVR_UNEXCEPTED; + return ERR_TRANSVR_UNEXCPT; + } + /* Case3.4: During initial process */ + if (self->state == STATE_TRANSVR_INIT){ + result[0] = STATE_TRANSVR_INIT; + return 0; + } + /* Case3.5: Transceiver be swapped */ + if (self->type != result[1]){ + result[0] = STATE_TRANSVR_SWAPPED; + return 0; + } + /* Case3.6: Link up state */ + result[0] = STATE_TRANSVR_CONNECTED; + return 0; +} + + +int +_sfp_detect_class_by_extend_comp(struct transvr_obj_s* self) { + /* Reference: SFF-8024 (v3.8) + */ + int detect_val = _sfp_get_comp_extended(self); + + switch(detect_val) { + case 0x00: /* Unspecified */ + return TRANSVR_CLASS_UNSPECIFIED; + + case 0x01: /* 100G AOC (Active Optical Cable) or 25GAUI C2M */ + case 0x18: /* 100G AOC or 25GAUI C2M AOC. */ + return TRANSVR_CLASS_OPTICAL_25G_AOC; + + case 0x02: /* 100GBASE-SR4 or 25GBASE-SR */ + return TRANSVR_CLASS_OPTICAL_25G_SR; + + case 0x03: /* 100GBASE-LR4 or 25GBASE-LR */ + return TRANSVR_CLASS_OPTICAL_25G_LR; + + case 0x04: /* 100GBASE-ER4 or 25GBASE-ER */ + return TRANSVR_CLASS_OPTICAL_25G_ER; + + case 0x08: /* 100G ACC (Active Copper Cable) or 25GAUI C2M ACC. */ + case 0x0b: /* 100GBASE-CR4 or 25GBASE-CR CA-L */ + case 0x0c: /* 25GBASE-CR CA-S */ + case 0x0d: /* 25GBASE-CR CA-N */ + case 0x19: /* 100G ACC or 25GAUI C2M ACC. */ + return TRANSVR_CLASS_COPPER_L1_25G; + + default: + break; + } + SWPS_INFO("%s: Unexcept value:0x%02x\n :%s", + __func__, detect_val, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +_sfp_detect_class_by_10_ethernet(struct transvr_obj_s* self) { + /* Reference: SFF-8472 (v12.2) + */ + int detect_val = DEBUG_TRANSVR_INT_VAL; + + detect_val = _sfp_get_comp_10g_eth_comp(self); + /* Case: Unspecified */ + if (detect_val == 0x00) { + return TRANSVR_CLASS_UNSPECIFIED; + } + /* Case: 10G Optical (x1) */ + if ((detect_val & 0x10) == 0x10) { /* 00010000 : 10GBASE-SR */ + return TRANSVR_CLASS_OPTICAL_10G_S_SR; + } + if ( ((detect_val & 0x20) == 0x20) || /* 00100000 : 10GBASE-LR */ + ((detect_val & 0x40) == 0x40) ){ /* 01000000 : 10GBASE-LRM */ + return TRANSVR_CLASS_OPTICAL_10G_S_LR; + } + if ((detect_val & 0x80) == 0x80) { /* 10000000 : 10GBASE-ER */ + return TRANSVR_CLASS_OPTICAL_10G_S_ER; + } + /* Case: ERROR */ + SWPS_INFO("%s: Unexcept value:0x%02x\n :%s", + __func__, detect_val, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +_sfp_detect_if_sp_by_br(struct transvr_obj_s* self) { + + int lower_bound_1g = 0x0b; + int upper_bound_1g = 0x1A; + int lower_bound_10g = 0x60; + int upper_bound_10g = 0x75; + int lower_bound_25g = 0xf0; + int upper_bound_25g = 0xff; + int notmal_br = DEBUG_TRANSVR_INT_VAL; + + notmal_br = (int)(self->br); /* updated by update_all() */ + /* Check 25G */ + if ((notmal_br >= lower_bound_25g) && + (notmal_br <= upper_bound_25g) ) { + return TRANSVR_CLASS_25G; + } + /* Check 10G */ + if ((notmal_br >= lower_bound_10g) && + (notmal_br <= upper_bound_10g) ) { + return TRANSVR_CLASS_10G; + } + /* Check 1G */ + if ((notmal_br >= lower_bound_1g) && + (notmal_br <= upper_bound_1g) ) { + return TRANSVR_CLASS_1G; + } + return TRANSVR_CLASS_UNSPECIFIED; +} + + +int +_sfp_detect_class_by_1g_ethernet(struct transvr_obj_s* self) { + /* Reference: SFF-8472 (v12.2) + */ + int detect_val = DEBUG_TRANSVR_INT_VAL; + int speed_br = DEBUG_TRANSVR_INT_VAL; + int speed_tmp = DEBUG_TRANSVR_INT_VAL; + char err_str[64] = DEBUG_TRANSVR_STR_VAL; + + speed_br = _sfp_detect_if_sp_by_br(self); + detect_val = _sfp_get_comp_1g_eth_comp(self); + + if (detect_val < 0) { + snprintf(err_str, sizeof(err_str), "Detect abnormal value:%d", detect_val); + goto err_p_sfp_detect_class_by_1g_ethernet; + } + /* Case: Unspecified */ + if (detect_val == 0x00) { + return TRANSVR_CLASS_UNSPECIFIED; + } + /* Case: 1G (x1) */ + if ((detect_val & 0x01) == 0x01) { /* 00000001 : 1000BASE-SX */ + speed_tmp = TRANSVR_CLASS_OPTICAL_1G_SX; + goto ok_sfp_detect_class_by_1g_ethernet_4_check_br_10g; + } + if ((detect_val & 0x02) == 0x02) { /* 00000010 : 1000BASE-LX *3 */ + speed_tmp = TRANSVR_CLASS_OPTICAL_1G_LX; + goto ok_sfp_detect_class_by_1g_ethernet_4_check_br_10g; + } + if ((detect_val & 0x04) == 0x04) { /* 00000100 : 1000BASE-CX */ + speed_tmp = TRANSVR_CLASS_COPPER_L1_1G; + goto ok_sfp_detect_class_by_1g_ethernet_4_check_br_10g; + } + /* Case: 1000 Base-T (x1) */ + if ((detect_val & 0x08) == 0x08) { /* 00001000 : 1000BASE-T */ + return TRANSVR_CLASS_BASE_T_1000; + } + /* Case: 100 Base */ + if ( ((detect_val & 0x10) == 0x10) || /* 00010000 : 100BASE-LX/LX10 */ + ((detect_val & 0x20) == 0x20) || /* 00100000 : 100BASE-FX */ + ((detect_val & 0x40) == 0x40) || /* 01000000 : BASE-BX10 *3 */ + ((detect_val & 0x80) == 0x80) ){ /* 10000000 : BASE-PX *3 */ + return TRANSVR_CLASS_OPTICAL_100; + } + /* Case: ERROR */ + snprintf(err_str, sizeof(err_str), "Case:ERROR, value:%d", detect_val); + goto err_p_sfp_detect_class_by_1g_ethernet; + +ok_sfp_detect_class_by_1g_ethernet_4_check_br_10g: + switch (speed_br) { + case TRANSVR_CLASS_UNSPECIFIED: + case TRANSVR_CLASS_1G: + return speed_tmp; + case TRANSVR_CLASS_10G: + goto ok_sfp_detect_class_by_1g_ethernet_4_transfer_10G; + } + +ok_sfp_detect_class_by_1g_ethernet_4_transfer_10G: + switch (speed_tmp) { + case TRANSVR_CLASS_OPTICAL_1G_SX: + return TRANSVR_CLASS_OPTICAL_10G_S_SR; + case TRANSVR_CLASS_OPTICAL_1G_LX: + return TRANSVR_CLASS_OPTICAL_10G_S_LR; + case TRANSVR_CLASS_COPPER_L1_1G: + return TRANSVR_CLASS_COPPER_L1_10G; + default: + break; + } + snprintf(err_str, sizeof(err_str), "transfer_1to10 fail, speed:%d", speed_tmp); + goto err_p_sfp_detect_class_by_1g_ethernet; + +err_p_sfp_detect_class_by_1g_ethernet: + SWPS_INFO("%s: %s :%s", __func__, err_str, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +_sfp_detect_class_by_feature(struct transvr_obj_s* self) { + /* Reference: SFF-8024 (v3.8) + */ + int is_active = 0; + int conn_val = DEBUG_TRANSVR_INT_VAL; + int check_val = DEBUG_TRANSVR_INT_VAL; + int wave_len = DEBUG_TRANSVR_INT_VAL; + int speed_val = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + speed_val = _sfp_detect_if_sp_by_br(self); + conn_val = _sfp_get_connector_type(self); + + switch(conn_val) { + case 0x00: /* Unspecified */ + goto ok_sfp_detect_class_by_feature_4_check_active_passive; + case 0x07: /* LC (Lucent Connector) */ + case 0x0b: /* Optical Pigtail */ + case 0x0c: /* MPO 1x12 */ + case 0x0d: /* MPO 2x16 */ + /* + * ToDo: Need verify Optical Pigtail + */ + goto ok_sfp_detect_class_by_feature_4_optiocal; + case 0x21: /* Copper pigtail */ + /* + * ToDo: Need check ACC use case + */ + goto ok_sfp_detect_class_by_feature_4_check_active_passive; + case 0x23: /* No separable connector */ + /* + * ToDo: Standard not clear, not all transceiver vendor + * have the same defined + */ + goto ok_sfp_detect_class_by_feature_4_check_active_passive; + default: + break; + } + goto ok_sfp_detect_class_by_feature_4_unknow; + +ok_sfp_detect_class_by_feature_4_check_active_passive: + check_val = _sfp_get_cable_tech(self); + switch(check_val) { + case 0x00: /* Unspecified */ + goto ok_sfp_detect_class_by_feature_4_unknow; + case 0x04: /* Passive */ + goto ok_sfp_detect_class_by_feature_4_copper; + case 0x08: /* Active */ + is_active = 1; + goto ok_sfp_detect_class_by_feature_4_aoc; + default: + snprintf(err_msg, sizeof(err_msg), + "_sfp_get_cable_tech return Non define value:%d", + check_val); + break; + } + goto err_sfp_detect_class_by_feature_1; + +ok_sfp_detect_class_by_feature_4_optiocal: + wave_len = _common_count_wavelength(self, + self->wavelength[0], + self->wavelength[1]); + switch(speed_val) { + case TRANSVR_CLASS_25G: + switch (wave_len) { + case VAL_OPTICAL_WAVELENGTH_SR: + return TRANSVR_CLASS_OPTICAL_25G_SR; + case VAL_OPTICAL_WAVELENGTH_LR: + return TRANSVR_CLASS_OPTICAL_25G_LR; + case VAL_OPTICAL_WAVELENGTH_ER: + return TRANSVR_CLASS_OPTICAL_25G_ER; + default: + break; + } + return TRANSVR_CLASS_OPTICAL_25G; + + case TRANSVR_CLASS_10G: + switch (wave_len) { + case VAL_OPTICAL_WAVELENGTH_SR: + return TRANSVR_CLASS_OPTICAL_10G_S_SR; + case VAL_OPTICAL_WAVELENGTH_LR: + return TRANSVR_CLASS_OPTICAL_10G_S_LR; + case VAL_OPTICAL_WAVELENGTH_ER: + return TRANSVR_CLASS_OPTICAL_10G_S_ER; + default: + break; + } + return TRANSVR_CLASS_OPTICAL_10G; + + case TRANSVR_CLASS_1G: + switch (wave_len) { + case VAL_OPTICAL_WAVELENGTH_SR: + return TRANSVR_CLASS_OPTICAL_1G_SX; + case VAL_OPTICAL_WAVELENGTH_LR: + return TRANSVR_CLASS_OPTICAL_1G_LX; + case VAL_OPTICAL_WAVELENGTH_ER: + return TRANSVR_CLASS_OPTICAL_1G_EX; + default: + break; + } + return TRANSVR_CLASS_OPTICAL_1G; + + default: + return TRANSVR_CLASS_OPTICAL; + } + +ok_sfp_detect_class_by_feature_4_aoc: + switch(speed_val) { + case TRANSVR_CLASS_25G: + return TRANSVR_CLASS_OPTICAL_25G_AOC; + case TRANSVR_CLASS_10G: + return TRANSVR_CLASS_OPTICAL_10G_S_AOC; + case TRANSVR_CLASS_1G: + return TRANSVR_CLASS_OPTICAL_1G_AOC; + default: + break; + } + goto ok_sfp_detect_class_by_feature_4_unknow; + +ok_sfp_detect_class_by_feature_4_copper: + switch(speed_val) { + case TRANSVR_CLASS_25G: + return TRANSVR_CLASS_COPPER_L1_25G; + case TRANSVR_CLASS_10G: + return TRANSVR_CLASS_COPPER_L1_10G; + case TRANSVR_CLASS_1G: + return TRANSVR_CLASS_COPPER_L1_1G; + default: + return TRANSVR_CLASS_COPPER; + } + +ok_sfp_detect_class_by_feature_4_unknow: + return TRANSVR_CLASS_UNSPECIFIED; + +err_sfp_detect_class_by_feature_1: + SWPS_INFO("%s: %s\n :%s", __func__, err_msg, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +sft_detect_transvr_class(struct transvr_obj_s* self) { + + int detect_val = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + /* Check Extended Compliance */ + detect_val = _sfp_detect_class_by_extend_comp(self); + switch(detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_OPTICAL_25G_AOC: + case TRANSVR_CLASS_OPTICAL_25G_SR: + case TRANSVR_CLASS_OPTICAL_25G_LR: + case TRANSVR_CLASS_OPTICAL_25G_ER: + case TRANSVR_CLASS_COPPER_L1_25G: + return detect_val; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined extend_comp:%d", + detect_val); + goto err_sft_detect_transceiver_class_1; + } + /* Check 10G Compliance */ + detect_val = _sfp_detect_class_by_10_ethernet(self); + switch(detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_OPTICAL_10G_S_SR: + case TRANSVR_CLASS_OPTICAL_10G_S_LR: + case TRANSVR_CLASS_OPTICAL_10G_S_ER: + return detect_val; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined 10G_eth:%d", + detect_val); + goto err_sft_detect_transceiver_class_1; + } + /* Check 1G Compliance */ + detect_val = _sfp_detect_class_by_1g_ethernet(self); + switch(detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_OPTICAL_1G_SX: + case TRANSVR_CLASS_OPTICAL_1G_LX: + case TRANSVR_CLASS_COPPER_L1_1G: + case TRANSVR_CLASS_BASE_T_1000: + case TRANSVR_CLASS_OPTICAL_100: + /* + * ToDo: Need Check 0.1G + */ + case TRANSVR_CLASS_OPTICAL_10G_S_SR: + case TRANSVR_CLASS_OPTICAL_10G_S_LR: + case TRANSVR_CLASS_COPPER_L1_10G: + /* Transfer speed case + * => Example: Raycom 10G DAC + */ + return detect_val; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined 1G_eth:%d", + detect_val); + goto err_sft_detect_transceiver_class_1; + } + /* Check by connector, br, wavelength */ + detect_val = _sfp_detect_class_by_feature(self); + switch(detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_OPTICAL: + case TRANSVR_CLASS_OPTICAL_1G: + case TRANSVR_CLASS_OPTICAL_1G_SX: + case TRANSVR_CLASS_OPTICAL_1G_LX: + case TRANSVR_CLASS_OPTICAL_1G_EX: + case TRANSVR_CLASS_OPTICAL_1G_AOC: + case TRANSVR_CLASS_OPTICAL_10G: + case TRANSVR_CLASS_OPTICAL_10G_S_SR: + case TRANSVR_CLASS_OPTICAL_10G_S_LR: + case TRANSVR_CLASS_OPTICAL_10G_S_ER: + case TRANSVR_CLASS_OPTICAL_10G_S_AOC: + case TRANSVR_CLASS_OPTICAL_25G: + case TRANSVR_CLASS_OPTICAL_25G_SR: + case TRANSVR_CLASS_OPTICAL_25G_LR: + case TRANSVR_CLASS_OPTICAL_25G_ER: + case TRANSVR_CLASS_OPTICAL_25G_AOC: + case TRANSVR_CLASS_COPPER: + case TRANSVR_CLASS_COPPER_L1_1G: + case TRANSVR_CLASS_COPPER_L1_10G: + case TRANSVR_CLASS_COPPER_L1_25G: + return detect_val; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined get_connector:%d", + detect_val); + goto err_sft_detect_transceiver_class_1; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), "Can not identify!"); + goto err_sft_detect_transceiver_class_1; + +err_sft_detect_transceiver_class_1: + SWPS_INFO("%s: %s :%s\n", __func__, err_msg, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +_sfp_set_trident2_if_type(struct transvr_obj_s* self, + int transvr_cls, + char *result){ + + int lmax = 8; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + switch(transvr_cls) { + case TRANSVR_CLASS_ERROR: + case TRANSVR_CLASS_UNSPECIFIED: + break; + /* 25G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_25G_AOC: + case TRANSVR_CLASS_OPTICAL_25G_SR: + case TRANSVR_CLASS_OPTICAL_25G_LR: + case TRANSVR_CLASS_OPTICAL_25G_ER: + case TRANSVR_CLASS_OPTICAL_25G: + return snprintf(result, lmax, TRANSVR_IF_SFI); + /* 25G COPPER */ + case TRANSVR_CLASS_COPPER_L1_25G: + return snprintf(result, lmax, TRANSVR_IF_SFI); + /* 10G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_10G_S_AOC: + case TRANSVR_CLASS_OPTICAL_10G_S_SR: + case TRANSVR_CLASS_OPTICAL_10G_S_LR: + case TRANSVR_CLASS_OPTICAL_10G_S_ER: + case TRANSVR_CLASS_OPTICAL_10G: + return snprintf(result, lmax, TRANSVR_IF_SFI); + /* 10G COPPER */ + case TRANSVR_CLASS_COPPER_L1_10G: + return snprintf(result, lmax, TRANSVR_IF_SFI); + /* 1G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_1G_AOC: + case TRANSVR_CLASS_OPTICAL_1G_SX: + case TRANSVR_CLASS_OPTICAL_1G_LX: + case TRANSVR_CLASS_OPTICAL_1G_EX: + case TRANSVR_CLASS_OPTICAL_1G: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + /* 1G COPPER */ + case TRANSVR_CLASS_COPPER_L1_1G: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + /* 1G BASE_T */ + case TRANSVR_CLASS_BASE_T_1000: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + /* 100 Base */ + case TRANSVR_CLASS_OPTICAL_100: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined value:%d", + transvr_cls); + goto err_sfp_set_trident2_if_type_1; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), "Can not identify!"); + goto err_sfp_set_trident2_if_type_1; + +err_sfp_set_trident2_if_type_1: + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + SWPS_INFO("%s: %s :%s\n", __func__, err_msg, self->swp_name); + return ERR_TRANSVR_ABNORMAL; +} + + +int +_sfp_set_tomahawk_if_type(struct transvr_obj_s* self, + int transvr_cls, + char *result) { + + int lmax = 8; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + switch(transvr_cls) { + case TRANSVR_CLASS_ERROR: + case TRANSVR_CLASS_UNSPECIFIED: + break; + /* 25G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_25G_AOC: + case TRANSVR_CLASS_OPTICAL_25G_SR: + case TRANSVR_CLASS_OPTICAL_25G_LR: + case TRANSVR_CLASS_OPTICAL_25G_ER: + case TRANSVR_CLASS_OPTICAL_25G: + return snprintf(result, lmax, TRANSVR_IF_SR); + /* 25G COPPER */ + case TRANSVR_CLASS_COPPER_L1_25G: + return snprintf(result, lmax, TRANSVR_IF_KR); + /* 10G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_10G_S_AOC: + case TRANSVR_CLASS_OPTICAL_10G_S_SR: + case TRANSVR_CLASS_OPTICAL_10G_S_LR: + case TRANSVR_CLASS_OPTICAL_10G_S_ER: + case TRANSVR_CLASS_OPTICAL_10G: + return snprintf(result, lmax, TRANSVR_IF_SFI); + /* 10G COPPER */ + case TRANSVR_CLASS_COPPER_L1_10G: + return snprintf(result, lmax, TRANSVR_IF_SFI); + /* 1G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_1G_AOC: + case TRANSVR_CLASS_OPTICAL_1G_SX: + case TRANSVR_CLASS_OPTICAL_1G_LX: + case TRANSVR_CLASS_OPTICAL_1G_EX: + case TRANSVR_CLASS_OPTICAL_1G: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + /* 1G COPPER */ + case TRANSVR_CLASS_COPPER_L1_1G: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + /* 1G BASE_T */ + case TRANSVR_CLASS_BASE_T_1000: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + /* 100 Base */ + case TRANSVR_CLASS_OPTICAL_100: + return snprintf(result, lmax, TRANSVR_IF_IF_GMII); + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined value:%d", + transvr_cls); + goto err_sfp_set_tomahawk_if_type_1; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), "Can not identify!"); + goto err_sfp_set_tomahawk_if_type_1; + +err_sfp_set_tomahawk_if_type_1: + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + SWPS_INFO("%s: %s\n :%s", __func__, err_msg, self->swp_name); + return ERR_TRANSVR_ABNORMAL; +} + + +int +_sfp_set_bf_tofino_if_type(struct transvr_obj_s* self, + int transvr_cls, + char *result) { + /* (TBD) + * Due to BF looks like doesn't have interface type. + * We bypass it currently. + */ + int lmax = 8; + return snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); +} + + +int +_sfp_detect_if_type(struct transvr_obj_s* self, + char *result){ + + int lmax = 8; + int detect_cls = DEBUG_TRANSVR_INT_VAL; + + detect_cls = sft_detect_transvr_class(self); + switch (self->chipset_type) { + case BCM_CHIP_TYPE_TRIDENT_2: + return _sfp_set_trident2_if_type(self, detect_cls, result); + + case BCM_CHIP_TYPE_TRIDENT_3: + case BCM_CHIP_TYPE_TOMAHAWK: + return _sfp_set_tomahawk_if_type(self, detect_cls, result); + + case BF_CHIP_TYPE_TOFINO: + return _sfp_set_bf_tofino_if_type(self, detect_cls, result); + + default: + SWPS_INFO("%s: non-defined chipset_type:%d :%s\n", + __func__, self->chipset_type, self->swp_name); + break; + } + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + return ERR_TRANSVR_ABNORMAL; +} + + +int +sfp_get_if_type(struct transvr_obj_s *self, + char *buf_p){ + + int lmax = 16; + char tmp_result[16] = DEBUG_TRANSVR_STR_VAL; + + if (self->state != STATE_TRANSVR_CONNECTED) { + return snprintf(buf_p, lmax, "%d\n", self->state); + } + if (_sfp_detect_if_type(self, tmp_result) < 0) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_ABNORMAL); + } + return snprintf(buf_p, lmax, "%s\n", tmp_result); +} + + +int +_sfp_detect_if_speed(struct transvr_obj_s* self, + char *result){ + + int lmax = 16; + int detect_val = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + detect_val = sft_detect_transvr_class(self); + switch(detect_val) { + case TRANSVR_CLASS_ERROR: + case TRANSVR_CLASS_UNSPECIFIED: + break; + /* 25G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_25G_AOC: + case TRANSVR_CLASS_OPTICAL_25G_SR: + case TRANSVR_CLASS_OPTICAL_25G_LR: + case TRANSVR_CLASS_OPTICAL_25G_ER: + case TRANSVR_CLASS_OPTICAL_25G: + return snprintf(result, lmax, TRANSVR_IF_SP_25G); + /* 25G COPPER */ + case TRANSVR_CLASS_COPPER_L1_25G: + return snprintf(result, lmax, TRANSVR_IF_SP_25G); + /* 10G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_10G_S_AOC: + case TRANSVR_CLASS_OPTICAL_10G_S_SR: + case TRANSVR_CLASS_OPTICAL_10G_S_LR: + case TRANSVR_CLASS_OPTICAL_10G_S_ER: + case TRANSVR_CLASS_OPTICAL_10G: + return snprintf(result, lmax, TRANSVR_IF_SP_10G); + /* 10G COPPER */ + case TRANSVR_CLASS_COPPER_L1_10G: + return snprintf(result, lmax, TRANSVR_IF_SP_10G); + /* 1G OPTICAL */ + case TRANSVR_CLASS_OPTICAL_1G_AOC: + case TRANSVR_CLASS_OPTICAL_1G_SX: + case TRANSVR_CLASS_OPTICAL_1G_LX: + case TRANSVR_CLASS_OPTICAL_1G_EX: + case TRANSVR_CLASS_OPTICAL_1G: + return snprintf(result, lmax, TRANSVR_IF_SP_1G); + /* 1G COPPER */ + case TRANSVR_CLASS_COPPER_L1_1G: + return snprintf(result, lmax, TRANSVR_IF_SP_1G); + /* 1G BASE_T */ + case TRANSVR_CLASS_BASE_T_1000: + return snprintf(result, lmax, TRANSVR_IF_SP_1G); + /* 100 Base */ + case TRANSVR_CLASS_OPTICAL_100: + return snprintf(result, lmax, TRANSVR_IF_SP_100); + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined value:%d", + detect_val); + goto err_sfp_detect_if_speed_1; + } + /* Check by BR */ + detect_val = _sfp_detect_if_sp_by_br(self); + switch (detect_val) { + case TRANSVR_CLASS_25G: + return snprintf(result, lmax, TRANSVR_IF_SP_25G); + case TRANSVR_CLASS_10G: + return snprintf(result, lmax, TRANSVR_IF_SP_10G); + case TRANSVR_CLASS_1G: + return snprintf(result, lmax, TRANSVR_IF_SP_1G); + default: + break; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), "Can not identify!"); + goto err_sfp_detect_if_speed_1; + +err_sfp_detect_if_speed_1: + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + SWPS_INFO("%s %s\n :%s", __func__, err_msg, self->swp_name); + return ERR_TRANSVR_ABNORMAL; +} + + +int +sfp_get_if_speed(struct transvr_obj_s *self, + char *buf_p){ + + int lmax = 16; + char tmp_result[16] = DEBUG_TRANSVR_STR_VAL; + + if (self->state != STATE_TRANSVR_CONNECTED) { + return snprintf(buf_p, lmax, "%d\n", self->state); + } + if (_sfp_detect_if_speed(self, tmp_result) < 0) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_ABNORMAL); + } + return snprintf(buf_p, lmax, "%s\n", tmp_result); +} + + +int +_qsfp_detect_class_by_extend_comp(struct transvr_obj_s* self) { + /* Reference: SFF-8024 (v3.8) + */ + int detect_val = DEBUG_TRANSVR_INT_VAL; + + detect_val = _qsfp_get_comp_extended(self); + switch(detect_val) { + case 0x00: /* Unspecified */ + return TRANSVR_CLASS_UNSPECIFIED; + + case 0x01: /* 100G AOC (Active Optical Cable) or 25GAUI C2M */ + case 0x18: /* 100G AOC or 25GAUI C2M AOC. */ + return TRANSVR_CLASS_OPTICAL_100G_AOC; + + case 0x06: /* 100G CWDM4 */ + case 0x09: /* Obsolete (assigned before 100G CWDM4 MSA required FEC) */ + case 0x17: /* 100G CLR4 */ + case 0x1A: /* 100GE-DWDM2 */ + return TRANSVR_CLASS_OPTICAL_100G; + + case 0x02: /* 100GBASE-SR4 or 25GBASE-SR */ + return TRANSVR_CLASS_OPTICAL_100G_SR4; + + case 0x03: /* 100GBASE-LR4 or 25GBASE-LR */ + return TRANSVR_CLASS_OPTICAL_100G_LR4; + + case 0x04: /* 100GBASE-ER4 or 25GBASE-ER */ + return TRANSVR_CLASS_OPTICAL_100G_ER4; + + case 0x07: /* 100G PSM4 Parallel SMF */ + return TRANSVR_CLASS_OPTICAL_100G_PSM4; + + case 0x12: /* 40G PSM4 Parallel SMF */ + return TRANSVR_CLASS_OPTICAL_40G; + + case 0x11: /* 4 x 10GBASE-SR */ + return TRANSVR_CLASS_OPTICAL_40G_SR4; + + case 0x10: /* 40GBASE-ER4 */ + return TRANSVR_CLASS_OPTICAL_40G_ER4; + + case 0x08: /* 100G ACC (Active Copper Cable) or 25GAUI C2M ACC. */ + case 0x0b: /* 100GBASE-CR4 or 25GBASE-CR CA-L */ + case 0x19: /* 100G ACC or 25GAUI C2M ACC. */ + return TRANSVR_CLASS_COPPER_L4_100G; + + default: + break; + } + SWPS_INFO("%s: Unexcept value:0x%02x\n :%s", + __func__, detect_val, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +_qsfp_detect_class_by_10_40_100_ethernet(struct transvr_obj_s* self) { + /* Reference: SFF-8472 (v12.2) + */ + int detect_val = DEBUG_TRANSVR_INT_VAL; + + detect_val = _qsfp_get_comp_10_40_100_ethernet(self); + /* Case: Unspecified */ + if (detect_val == 0x00) { + return TRANSVR_CLASS_UNSPECIFIED; + } + /* Case: 40G Optical */ + if ((detect_val & 0x01) == 0x01) { /* 00000001 : 40G Active Cable (XLPPI) */ + return TRANSVR_CLASS_OPTICAL_40G_AOC; + } + if ((detect_val & 0x04) == 0x04) { /* 00000100 : 40GBASE-SR4 */ + return TRANSVR_CLASS_OPTICAL_40G_SR4; + } + if ( (detect_val & 0x02) == 0x02) { /* 00000010 : 40GBASE-LR4 */ + return TRANSVR_CLASS_OPTICAL_40G_LR4; + } + if ( (detect_val & 0x08) == 0x08) { /* 00001000 : 40GBASE-CR4 */ + return TRANSVR_CLASS_COPPER_L4_40G; + } + /* Case: 10G Optical */ + if ( (detect_val & 0x10) == 0x10) { /* 00010000 : 10GBASE-SR */ + return TRANSVR_CLASS_OPTICAL_10G_Q_SR; + } + if ( ((detect_val & 0x20) == 0x20) || /* 00100000 : 10GBASE-LR */ + ((detect_val & 0x40) == 0x40) ){ /* 01000000 : 10GBASE-LRM */ + return TRANSVR_CLASS_OPTICAL_10G_Q_LR; + } + /* Case: Extend Compliance */ + if ( ((detect_val & 0x80) == 0x80) ){ /* 10000000 : Use Extend Compliance */ + return TRANSVR_CLASS_EXTEND_COMP; + } + /* Case: ERROR */ + SWPS_INFO("%s: Unexcept value:0x%02x\n :%s", + __func__, detect_val, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +_qsfp_detect_if_sp_by_br(struct transvr_obj_s* self) { + + int lower_bound_10g = 0x10; + int upper_bound_10g = 0x25; + int lower_bound_40g = 0x60; + int upper_bound_40g = 0x75; + int lower_bound_100g = 0x60; + int upper_bound_100g = 0x75; + int used_extend_br = 0xff; + int notmal_br = DEBUG_TRANSVR_INT_VAL; + int extend_br = DEBUG_TRANSVR_INT_VAL; + + notmal_br = (int)(self->br); /* updated by update_all() */ + /* Check 40G */ + if ((notmal_br >= lower_bound_40g) && + (notmal_br <= upper_bound_40g) ) { + return TRANSVR_CLASS_40G; + } + /* Check 100G */ + if (notmal_br == used_extend_br) { + extend_br = (int)(self->extbr); /* updated by update_all() */ + if ((extend_br >= lower_bound_100g) && + (extend_br <= upper_bound_100g) ) { + return TRANSVR_CLASS_100G; + } + } + /* Check 10G */ + if ((notmal_br >= lower_bound_10g) && + (notmal_br <= upper_bound_10g) ) { + return TRANSVR_CLASS_10G; + } + return TRANSVR_CLASS_UNSPECIFIED; +} + + +int +_qsfp_detect_class_by_feature(struct transvr_obj_s* self) { + /* Reference: SFF-8024 (v3.8) + */ + int conn_val = DEBUG_TRANSVR_INT_VAL; + int wave_len = DEBUG_TRANSVR_INT_VAL; + int speed_val = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + speed_val = _qsfp_detect_if_sp_by_br(self); + conn_val = _qsfp_get_connector_type(self); + + switch(conn_val) { + case 0x00: /* Unspecified */ + return TRANSVR_CLASS_UNSPECIFIED; + case 0x07: /* LC (Lucent Connector) */ + case 0x0b: /* Optical Pigtail */ + case 0x0c: /* MPO 1x12 (Multifiber Parallel Optic) */ + case 0x0d: /* MPO 2x16 */ + goto ok_qsfp_detect_class_by_feature_4_optiocal; + case 0x21: /* Copper pigtail */ + goto ok_qsfp_detect_class_by_feature_4_copper; + case 0x23: /* No separable connector */ + if ((_qsfp_get_comp_fc_link_length(self) > 0) || + (_qsfp_get_comp_fc_trans_tech(self) > 0) || + (_qsfp_get_comp_fc_trans_media(self) > 0) || + (_qsfp_get_comp_fc_speed(self) > 0) ) { + goto ok_qsfp_detect_class_by_feature_4_aoc; + } + goto ok_qsfp_detect_class_by_feature_4_copper; + default: + snprintf(err_msg, sizeof(err_msg), + "_qsfp_get_connector_type return Non define value:%d", + conn_val); + goto err_qsfp_detect_class_by_feature_1; + } + return TRANSVR_CLASS_UNSPECIFIED; + +ok_qsfp_detect_class_by_feature_4_optiocal: + wave_len = _common_count_wavelength(self, + self->wavelength[0], + self->wavelength[1]); + switch(speed_val) { + case TRANSVR_CLASS_100G: + switch (wave_len) { + case VAL_OPTICAL_WAVELENGTH_SR: + return TRANSVR_CLASS_OPTICAL_100G_SR4; + case VAL_OPTICAL_WAVELENGTH_LR: + return TRANSVR_CLASS_OPTICAL_100G_LR4; + case VAL_OPTICAL_WAVELENGTH_ER: + return TRANSVR_CLASS_OPTICAL_100G_ER4; + default: + break; + } + return TRANSVR_CLASS_OPTICAL_100G; + + case TRANSVR_CLASS_40G: + switch (wave_len) { + case VAL_OPTICAL_WAVELENGTH_SR: + return TRANSVR_CLASS_OPTICAL_40G_SR4; + case VAL_OPTICAL_WAVELENGTH_LR: + return TRANSVR_CLASS_OPTICAL_40G_LR4; + case VAL_OPTICAL_WAVELENGTH_ER: + return TRANSVR_CLASS_OPTICAL_40G_ER4; + default: + break; + } + return TRANSVR_CLASS_OPTICAL_40G; + + case TRANSVR_CLASS_10G: + switch (wave_len) { + case VAL_OPTICAL_WAVELENGTH_SR: + return TRANSVR_CLASS_OPTICAL_10G_Q_SR; + case VAL_OPTICAL_WAVELENGTH_LR: + return TRANSVR_CLASS_OPTICAL_10G_Q_LR; + case VAL_OPTICAL_WAVELENGTH_ER: + return TRANSVR_CLASS_OPTICAL_10G_Q_ER; + default: + break; + } + return TRANSVR_CLASS_OPTICAL_10G; + + default: + return TRANSVR_CLASS_OPTICAL; + } + +ok_qsfp_detect_class_by_feature_4_aoc: + switch(speed_val) { + case TRANSVR_CLASS_100G: + return TRANSVR_CLASS_OPTICAL_100G_AOC; + case TRANSVR_CLASS_40G: + return TRANSVR_CLASS_OPTICAL_40G_AOC; + case TRANSVR_CLASS_10G: + return TRANSVR_CLASS_OPTICAL_10G_Q_AOC; + default: + return TRANSVR_CLASS_OPTICAL; + } + +ok_qsfp_detect_class_by_feature_4_copper: + switch(speed_val) { + case TRANSVR_CLASS_100G: + return TRANSVR_CLASS_COPPER_L4_100G; + case TRANSVR_CLASS_40G: + return TRANSVR_CLASS_COPPER_L4_40G; + case TRANSVR_CLASS_10G: + return TRANSVR_CLASS_COPPER_L4_10G; + default: + return TRANSVR_CLASS_COPPER; + } + +err_qsfp_detect_class_by_feature_1: + SWPS_INFO("%s: %s\n :%s", + __func__, err_msg, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +qsft_detect_transvr_class(struct transvr_obj_s* self) { + + int detect_val = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + /* Check Extended Compliance */ + detect_val = _qsfp_detect_class_by_extend_comp(self); + switch (detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_OPTICAL_100G: + case TRANSVR_CLASS_OPTICAL_100G_AOC: + case TRANSVR_CLASS_OPTICAL_100G_SR4: + case TRANSVR_CLASS_OPTICAL_100G_LR4: + case TRANSVR_CLASS_OPTICAL_100G_ER4: + case TRANSVR_CLASS_OPTICAL_100G_PSM4: + case TRANSVR_CLASS_OPTICAL_40G: + case TRANSVR_CLASS_OPTICAL_40G_AOC: + case TRANSVR_CLASS_OPTICAL_40G_SR4: + case TRANSVR_CLASS_OPTICAL_40G_LR4: + case TRANSVR_CLASS_OPTICAL_40G_ER4: + case TRANSVR_CLASS_COPPER_L4_100G: + return detect_val; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined extend_comp:%d", + detect_val); + goto err_qsft_detect_transvr_class_1; + } + /* Check 10/40G/100G Ethernet Compliance */ + detect_val = _qsfp_detect_class_by_10_40_100_ethernet(self); + switch(detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_OPTICAL_40G_AOC: + case TRANSVR_CLASS_OPTICAL_40G_SR4: + case TRANSVR_CLASS_OPTICAL_40G_LR4: + case TRANSVR_CLASS_OPTICAL_10G_Q_SR: /* Need Check: SR4 or SR */ + case TRANSVR_CLASS_OPTICAL_10G_Q_LR: /* Need Check: SR4 or SR */ + case TRANSVR_CLASS_COPPER_L4_40G: + return detect_val; + case TRANSVR_CLASS_EXTEND_COMP: + /* Format incorrect case (We already checked the Extend + * Compliance is 0 + */ + snprintf(err_msg, sizeof(err_msg), + "Transceiver format incorrect"); + goto err_qsft_detect_transvr_class_1; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined 10/40/100:%d", + detect_val); + goto err_qsft_detect_transvr_class_1; + } + /* Check by Connector type, BR and wavelength */ + detect_val = _qsfp_detect_class_by_feature(self); + switch (detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_OPTICAL_100G_ER4: + case TRANSVR_CLASS_OPTICAL_100G_LR4: + case TRANSVR_CLASS_OPTICAL_100G_SR4: + case TRANSVR_CLASS_OPTICAL_100G_AOC: + case TRANSVR_CLASS_OPTICAL_100G: + case TRANSVR_CLASS_OPTICAL_40G_ER4: + case TRANSVR_CLASS_OPTICAL_40G_LR4: + case TRANSVR_CLASS_OPTICAL_40G_SR4: + case TRANSVR_CLASS_OPTICAL_40G_AOC: + case TRANSVR_CLASS_OPTICAL_40G: + case TRANSVR_CLASS_OPTICAL_10G_Q_ER: + case TRANSVR_CLASS_OPTICAL_10G_Q_LR: + case TRANSVR_CLASS_OPTICAL_10G_Q_SR: + case TRANSVR_CLASS_OPTICAL_10G_Q_AOC: + case TRANSVR_CLASS_OPTICAL_10G: + case TRANSVR_CLASS_OPTICAL: + case TRANSVR_CLASS_COPPER_L4_100G: + case TRANSVR_CLASS_COPPER_L4_40G: + case TRANSVR_CLASS_COPPER_L4_10G: + case TRANSVR_CLASS_COPPER: + return detect_val; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined connector:%d", + detect_val); + goto err_qsft_detect_transvr_class_1; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), + "Can not identify!"); + goto err_qsft_detect_transvr_class_1; + +err_qsft_detect_transvr_class_1: + SWPS_INFO("%s: %s\n :%s", __func__, err_msg, self->swp_name); + return TRANSVR_CLASS_ERROR; +} + + +int +_qsfp_set_trident2_if_type(struct transvr_obj_s* self, + int transvr_cls, + char *result){ + + int lmax = 8; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + switch (transvr_cls) { + case TRANSVR_CLASS_UNSPECIFIED: + case TRANSVR_CLASS_ERROR: + break; + /* 100G Optical */ + case TRANSVR_CLASS_OPTICAL_100G: + case TRANSVR_CLASS_OPTICAL_100G_AOC: + case TRANSVR_CLASS_OPTICAL_100G_SR4: + case TRANSVR_CLASS_OPTICAL_100G_LR4: + case TRANSVR_CLASS_OPTICAL_100G_ER4: + case TRANSVR_CLASS_OPTICAL_100G_PSM4: + return snprintf(result, lmax, TRANSVR_IF_SR4); + /* 100G Copper */ + case TRANSVR_CLASS_COPPER_L4_100G: + return snprintf(result, lmax, TRANSVR_IF_KR4); + /* 40G Optical */ + case TRANSVR_CLASS_OPTICAL_40G: + case TRANSVR_CLASS_OPTICAL_40G_AOC: + case TRANSVR_CLASS_OPTICAL_40G_SR4: + case TRANSVR_CLASS_OPTICAL_40G_LR4: + case TRANSVR_CLASS_OPTICAL_40G_ER4: + return snprintf(result, lmax, TRANSVR_IF_IF_XGMII); + /* 40G Copper */ + case TRANSVR_CLASS_COPPER_L4_40G: + return snprintf(result, lmax, TRANSVR_IF_IF_XGMII); + /* 10G Optical */ + case TRANSVR_CLASS_OPTICAL_10G: + case TRANSVR_CLASS_OPTICAL_10G_Q_AOC: + case TRANSVR_CLASS_OPTICAL_10G_Q_SR: /* Need Check: SR4 or SR */ + case TRANSVR_CLASS_OPTICAL_10G_Q_LR: /* Need Check: LR4 or LR */ + case TRANSVR_CLASS_OPTICAL_10G_Q_ER: /* Need Check: ER4 or ER */ + return snprintf(result, lmax, TRANSVR_IF_IF_XGMII); + /* Optical */ + case TRANSVR_CLASS_OPTICAL: + return snprintf(result, lmax, TRANSVR_IF_IF_XGMII); + /* Copper */ + case TRANSVR_CLASS_COPPER: + return snprintf(result, lmax, TRANSVR_IF_IF_XGMII); + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined value:%d", + transvr_cls); + goto err_qsfp_set_trident2_if_type_1; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), "Can not identify!"); + goto err_qsfp_set_trident2_if_type_1; + +err_qsfp_set_trident2_if_type_1: + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + SWPS_INFO("%s: %s\n :%s", __func__, err_msg, self->swp_name); + return ERR_TRANSVR_ABNORMAL; +} + + +int +_qsfp_set_tomahawk_if_type(struct transvr_obj_s* self, + int transvr_cls, + char *result){ + + int lmax = 8; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + switch (transvr_cls) { + case TRANSVR_CLASS_UNSPECIFIED: + case TRANSVR_CLASS_ERROR: + break; + /* 100G Optical */ + case TRANSVR_CLASS_OPTICAL_100G: + case TRANSVR_CLASS_OPTICAL_100G_AOC: + case TRANSVR_CLASS_OPTICAL_100G_SR4: + case TRANSVR_CLASS_OPTICAL_100G_LR4: + case TRANSVR_CLASS_OPTICAL_100G_ER4: + case TRANSVR_CLASS_OPTICAL_100G_PSM4: + return snprintf(result, lmax, TRANSVR_IF_SR4); + /* 100G Copper */ + case TRANSVR_CLASS_COPPER_L4_100G: + return snprintf(result, lmax, TRANSVR_IF_KR4); + /* 40G Optical */ + case TRANSVR_CLASS_OPTICAL_40G: + case TRANSVR_CLASS_OPTICAL_40G_AOC: + case TRANSVR_CLASS_OPTICAL_40G_SR4: + case TRANSVR_CLASS_OPTICAL_40G_LR4: + case TRANSVR_CLASS_OPTICAL_40G_ER4: + return snprintf(result, lmax, TRANSVR_IF_SR4); + /* 40G Copper */ + case TRANSVR_CLASS_COPPER_L4_40G: + return snprintf(result, lmax, TRANSVR_IF_KR4); + /* 10G Optical */ + case TRANSVR_CLASS_OPTICAL_10G: + case TRANSVR_CLASS_OPTICAL_10G_Q_AOC: + case TRANSVR_CLASS_OPTICAL_10G_Q_SR: /* Need Check: SR4 or SR */ + case TRANSVR_CLASS_OPTICAL_10G_Q_LR: /* Need Check: SR4 or SR */ + case TRANSVR_CLASS_OPTICAL_10G_Q_ER: + return snprintf(result, lmax, TRANSVR_IF_SR4); + /* Optical */ + case TRANSVR_CLASS_OPTICAL: + return snprintf(result, lmax, TRANSVR_IF_SR4); + /* Copper */ + case TRANSVR_CLASS_COPPER: + return snprintf(result, lmax, TRANSVR_IF_KR4); + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined value:%d", + transvr_cls); + goto err_qsfp_set_trident2_if_type_1; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), "Can not identify!"); + goto err_qsfp_set_trident2_if_type_1; + +err_qsfp_set_trident2_if_type_1: + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + SWPS_INFO("%s: %s\n :%s", __func__, err_msg, self->swp_name); + return ERR_TRANSVR_ABNORMAL; +} + + +int +_qsfp_set_bf_tofino_if_type(struct transvr_obj_s* self, + int transvr_cls, + char *result) { + /* (TBD) + * Due to BF looks like doesn't have interface type. + * We bypass it currently. + */ + int lmax = 8; + return snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); +} + + +int +_qsfp_detect_if_type(struct transvr_obj_s* self, + char *result){ + + int lmax = 8; + int detect_cls = DEBUG_TRANSVR_INT_VAL; + + detect_cls = qsft_detect_transvr_class(self); + switch (self->chipset_type) { + case BCM_CHIP_TYPE_TRIDENT_2: + return _qsfp_set_trident2_if_type(self, detect_cls, result); + + case BCM_CHIP_TYPE_TRIDENT_3: + case BCM_CHIP_TYPE_TOMAHAWK: + return _qsfp_set_tomahawk_if_type(self, detect_cls, result); + + case BF_CHIP_TYPE_TOFINO: + return _qsfp_set_bf_tofino_if_type(self, detect_cls, result); + + default: + SWPS_INFO("%s: non-defined chipset_type:%d :%s\n", + __func__, self->chipset_type, self->swp_name); + break; + } + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + return ERR_TRANSVR_ABNORMAL; +} + + +int +qsfp_get_if_type(struct transvr_obj_s *self, + char *buf_p){ + + int lmax = 8; + char tmp_result[8] = DEBUG_TRANSVR_STR_VAL; + + if (self->state != STATE_TRANSVR_CONNECTED) { + return snprintf(buf_p, lmax, "%d\n", self->state); + } + if (_qsfp_detect_if_type(self, tmp_result) < 0) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_ABNORMAL); + } + return snprintf(buf_p, lmax, "%s\n", tmp_result); +} + + +int +_qsfp_detect_if_speed(struct transvr_obj_s* self, + char *result){ + int lmax = 16; + int detect_val = DEBUG_TRANSVR_INT_VAL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + detect_val = qsft_detect_transvr_class(self); + switch (detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + case TRANSVR_CLASS_ERROR: + break; + /* 100G Optical */ + case TRANSVR_CLASS_OPTICAL_100G: + case TRANSVR_CLASS_OPTICAL_100G_AOC: + case TRANSVR_CLASS_OPTICAL_100G_SR4: + case TRANSVR_CLASS_OPTICAL_100G_LR4: + case TRANSVR_CLASS_OPTICAL_100G_ER4: + case TRANSVR_CLASS_OPTICAL_100G_PSM4: + return snprintf(result, lmax, TRANSVR_IF_SP_100G); + /* 100G Copper */ + case TRANSVR_CLASS_COPPER_L4_100G: + return snprintf(result, lmax, TRANSVR_IF_SP_100G); + /* 40G Optical */ + case TRANSVR_CLASS_OPTICAL_40G: + case TRANSVR_CLASS_OPTICAL_40G_AOC: + case TRANSVR_CLASS_OPTICAL_40G_SR4: + case TRANSVR_CLASS_OPTICAL_40G_LR4: + case TRANSVR_CLASS_OPTICAL_40G_ER4: + return snprintf(result, lmax, TRANSVR_IF_SP_40G); + /* 40G Copper */ + case TRANSVR_CLASS_COPPER_L4_40G: + return snprintf(result, lmax, TRANSVR_IF_SP_40G); + /* 10G Optical */ + case TRANSVR_CLASS_OPTICAL_10G: + case TRANSVR_CLASS_OPTICAL_10G_Q_AOC: + case TRANSVR_CLASS_OPTICAL_10G_Q_SR: /* Need Check: SR4 or SR */ + case TRANSVR_CLASS_OPTICAL_10G_Q_LR: /* Need Check: SR4 or SR */ + case TRANSVR_CLASS_OPTICAL_10G_Q_ER: + return snprintf(result, lmax, TRANSVR_IF_SP_10G); + /* 10G Copper */ + case TRANSVR_CLASS_COPPER_L4_10G: + return snprintf(result, lmax, TRANSVR_IF_SP_10G); + /* Optical */ + case TRANSVR_CLASS_OPTICAL: + break; + /* Copper */ + case TRANSVR_CLASS_COPPER: + break; + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined class case:%d", + detect_val); + goto err_qsfp_detect_if_speed_1; + } + /* Check br and extbr */ + detect_val = _qsfp_detect_if_sp_by_br(self); + switch(detect_val) { + case TRANSVR_CLASS_UNSPECIFIED: + break; + case TRANSVR_CLASS_10G: + return snprintf(result, lmax, TRANSVR_IF_SP_10G); + case TRANSVR_CLASS_40G: + return snprintf(result, lmax, TRANSVR_IF_SP_40G); + case TRANSVR_CLASS_100G: + return snprintf(result, lmax, TRANSVR_IF_SP_100G); + default: + snprintf(err_msg, sizeof(err_msg), + "Detect undefined BR case:%d", + detect_val); + goto err_qsfp_detect_if_speed_1; + } + /* Exception case: Can't verify */ + snprintf(err_msg, sizeof(err_msg), "Can not identify!"); + goto err_qsfp_detect_if_speed_1; + +err_qsfp_detect_if_speed_1: + snprintf(result, lmax, TRANSVR_UEVENT_UNKNOW); + SWPS_INFO("%s: %s :%s\n", __func__, err_msg, self->swp_name); + return ERR_TRANSVR_ABNORMAL; +} + + +int +qsfp_get_if_speed(struct transvr_obj_s *self, + char *buf_p){ + + int lmax = 16; + char tmp_result[16] = DEBUG_TRANSVR_STR_VAL; + + if (self->state != STATE_TRANSVR_CONNECTED) { + return snprintf(buf_p, lmax, "%d\n", self->state); + } + if (_qsfp_detect_if_speed(self, tmp_result) < 0) { + return snprintf(buf_p, lmax, "%d\n", ERR_TRANSVR_ABNORMAL); + } + return snprintf(buf_p, lmax, "%s\n", tmp_result); +} + + +int +_common_set_lane_map_str(struct transvr_obj_s* self, + char *result) { + int i = 0; + int tmp_val = 0; + char tmp_str[LEN_TRANSVR_L_STR] = DEBUG_TRANSVR_STR_VAL; + char err_msg[LEN_TRANSVR_L_STR] = DEBUG_TRANSVR_STR_VAL; + + memset(result, 0, LEN_TRANSVR_L_STR); + snprintf(result, LEN_TRANSVR_L_STR, "%s=", TRANSVR_UEVENT_KEY_LANE); + + for (i=0; ilane_id); i++) { + tmp_val = self->lane_id[i]; + if (tmp_val < 1) { + break; + } + if (tmp_val > 256) { + snprintf(err_msg, sizeof(err_msg), + "detect abnormal value:%d", tmp_val); + goto err_common_set_lane_map_str_1; + } + memset(tmp_str, 0, sizeof(tmp_str)); + if (i == 0) { + snprintf(tmp_str, LEN_TRANSVR_L_STR, "%d", tmp_val); + } else { + snprintf(tmp_str, LEN_TRANSVR_L_STR, ",%d", tmp_val); + } + strncat(result, tmp_str, LEN_TRANSVR_L_STR); + } + if (i == 0) { + goto err_common_set_lane_map_str_2; + } + return 0; + +err_common_set_lane_map_str_1: + SWPS_INFO("%s: %s", __func__, err_msg); +err_common_set_lane_map_str_2: + snprintf(result, LEN_TRANSVR_L_STR, "%s=%s", TRANSVR_UEVENT_KEY_LANE, TRANSVR_UEVENT_UNKNOW); + return EVENT_TRANSVR_TASK_FAIL; +} + + +int +_common_send_uevent(struct transvr_obj_s* self, + enum kobject_action u_action, + int (*detect_if_type)(struct transvr_obj_s *self, char *result), + int (*detect_if_speed)(struct transvr_obj_s *self, char *result), + int send_anyway) { + + char *uevent_envp[4]; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + char tmp_str[32] = DEBUG_TRANSVR_STR_VAL; + char tmp_str_1[32] = DEBUG_TRANSVR_STR_VAL; + char tmp_str_2[32] = DEBUG_TRANSVR_STR_VAL; + char tmp_str_3[64] = DEBUG_TRANSVR_STR_VAL; + + if (TRANSVR_UEVENT_ENABLE != 1) { + return ERR_TRANSVR_NOTSUPPORT; + } + if (_common_get_if_lane(self, tmp_str) < 0) { + snprintf(tmp_str_3, sizeof(tmp_str_3), + "%s=%s", TRANSVR_UEVENT_KEY_LANE, TRANSVR_UEVENT_UNKNOW); + } else { + snprintf(tmp_str_3, sizeof(tmp_str_3), + "%s=%s", TRANSVR_UEVENT_KEY_LANE, tmp_str); + } + switch (u_action) { + case KOBJ_ADD: + /* Detect type */ + if (detect_if_type(self, tmp_str) < 0) { + snprintf(err_msg, sizeof(err_msg), "%s", "Detect interface type fail!"); + snprintf(tmp_str_1, sizeof(tmp_str_1), "%s=%s", TRANSVR_UEVENT_KEY_IF, TRANSVR_UEVENT_UNKNOW); + snprintf(tmp_str_2, sizeof(tmp_str_2), "%s=%s", TRANSVR_UEVENT_KEY_SP, TRANSVR_UEVENT_UNKNOW); + uevent_envp[0] = tmp_str_1; + uevent_envp[1] = tmp_str_2; + uevent_envp[2] = tmp_str_3; + uevent_envp[3] = NULL; + goto private_common_send_uevent_4_fail; + } + snprintf(tmp_str_1, sizeof(tmp_str_1), "%s=%s", TRANSVR_UEVENT_KEY_IF, tmp_str); + uevent_envp[0] = tmp_str_1; + /* Detect speed */ + if (detect_if_speed(self, tmp_str) < 0) { + snprintf(err_msg, sizeof(err_msg), "%s", "Detect interface speed fail!"); + snprintf(tmp_str_2, sizeof(tmp_str_2), "%s=%s", TRANSVR_UEVENT_KEY_SP, TRANSVR_UEVENT_UNKNOW); + uevent_envp[1] = tmp_str_2; + uevent_envp[2] = tmp_str_3; + uevent_envp[3] = NULL; + goto private_common_send_uevent_4_fail; + } + snprintf(tmp_str_2, sizeof(tmp_str_2), "%s=%s", TRANSVR_UEVENT_KEY_SP, tmp_str); + uevent_envp[1] = tmp_str_2; + uevent_envp[2] = tmp_str_3; + uevent_envp[3] = NULL; + goto private_common_send_uevent_4_send; + + case KOBJ_REMOVE: + snprintf(tmp_str_1, sizeof(tmp_str_1), "%s=%s", TRANSVR_UEVENT_KEY_IF, TRANSVR_UEVENT_UNKNOW); + snprintf(tmp_str_2, sizeof(tmp_str_2), "%s=%s", TRANSVR_UEVENT_KEY_SP, TRANSVR_UEVENT_UNKNOW); + uevent_envp[0] = tmp_str_1; + uevent_envp[1] = tmp_str_2; + uevent_envp[2] = tmp_str_3; + uevent_envp[3] = NULL; + goto private_common_send_uevent_4_send; + + default: + snprintf(err_msg, sizeof(err_msg), "kobject_action:%d not support", u_action); + goto private_common_send_uevent_4_fail; + } + snprintf(err_msg, sizeof(err_msg), "%s", "Exception case"); + goto private_common_send_uevent_4_fail; + +private_common_send_uevent_4_fail: + SWPS_INFO("%s: %s :%s\n", __func__, err_msg, self->swp_name); + if (send_anyway) { + goto private_common_send_uevent_4_send; + } + return ERR_TRANSVR_UEVENT_FAIL; + +private_common_send_uevent_4_send: + return kobject_uevent_env(&(self->transvr_dev_p->kobj), + u_action, + uevent_envp); +} + +int +sfp_send_uevent(struct transvr_obj_s* self, + enum kobject_action u_action) { + int send_anyway = 1; + return _common_send_uevent(self, + u_action, + &_sfp_detect_if_type, + &_sfp_detect_if_speed, + send_anyway); +} + + +int +qsfp_send_uevent(struct transvr_obj_s* self, + enum kobject_action u_action) { + int send_anyway = 1; + return _common_send_uevent(self, + u_action, + &_qsfp_detect_if_type, + &_qsfp_detect_if_speed, + send_anyway); +} + + +int +fake_send_uevent(struct transvr_obj_s* self, + enum kobject_action u_action) { + return EVENT_TRANSVR_TASK_DONE; +} + + +int +common_fsm_4_direct_mode(struct transvr_obj_s* self, + char *caller_name){ + + int err; + int detect_result[2]; + int current_state = STATE_TRANSVR_UNEXCEPTED; + int current_type = TRANSVR_TYPE_ERROR; + + if (self->state == STATE_TRANSVR_NEW) { + if (_transvr_init_handler(self) < 0){ + return ERR_TRANSVR_INIT_FAIL; + } + } + err = detect_transvr_state(self, detect_result); + if (err < 0) { + return err; + } + /* In Direct mode, driver only detect transceiver when user call driver interface + * which on sysfs. So it only need consider the state of Transceiver. + */ + current_state = detect_result[0]; + current_type = detect_result[1]; + + switch (current_state){ + + case STATE_TRANSVR_DISCONNECTED: /* Transceiver is not plugged */ + self->state = current_state; + self->type = current_type; + return ERR_TRANSVR_UNPLUGGED; + + case STATE_TRANSVR_INIT: /* Transceiver is plugged, system not ready */ + return ERR_TRANSVR_UNINIT; + + case STATE_TRANSVR_ISOLATED: /* Transceiver is plugged, but has some issues */ + return ERR_TRNASVR_BE_ISOLATED; + + case STATE_TRANSVR_CONNECTED: /* Transceiver is plugged, system is ready */ + self->state = current_state; + self->type = current_type; + return 0; + + case STATE_TRANSVR_SWAPPED: /* Transceiver is plugged, system detect user changed */ + self->type = current_type; + if (reload_transvr_obj(self, current_type) < 0){ + self->state = STATE_TRANSVR_UNEXCEPTED; + return ERR_TRANSVR_UNEXCPT; + } + self->state = current_state; + return 0; + + case STATE_TRANSVR_UNEXCEPTED: /* Transceiver type or state is unexpected case */ + self->state = STATE_TRANSVR_UNEXCEPTED; + self->type = TRANSVR_TYPE_ERROR; + return ERR_TRANSVR_UNEXCPT; + + default: + SWPS_INFO("%s: state:%d not in define.\n", __func__, current_state); + break; + } + return ERR_TRANSVR_UNEXCPT; +} + + +static int +_is_except_happened_4_pmode(struct transvr_obj_s* self, + int new_state) { + + int event_chk = 0; + + if (self->temp == 0){ + return 0; + } + switch (new_state) { + case STATE_TRANSVR_INIT: + event_chk = EVENT_TRANSVR_EXCEP_INIT; + goto check_event_happened_4_pmode; + + case STATE_TRANSVR_CONNECTED: + event_chk = EVENT_TRANSVR_EXCEP_UP; + goto check_event_happened_4_pmode; + + case STATE_TRANSVR_DISCONNECTED: + event_chk = EVENT_TRANSVR_EXCEP_DOWN; + goto check_event_happened_4_pmode; + + case STATE_TRANSVR_SWAPPED: + event_chk = EVENT_TRANSVR_EXCEP_SWAP; + goto check_event_happened_4_pmode; + + case STATE_TRANSVR_UNEXCEPTED: + event_chk = EVENT_TRANSVR_EXCEP_EXCEP; + goto check_event_happened_4_pmode; + + case STATE_TRANSVR_ISOLATED: + event_chk = EVENT_TRANSVR_EXCEP_ISOLATED; + goto check_event_happened_4_pmode; + + default: + SWPS_INFO("%s: unexcepted case:%d\n", __func__, new_state); + break; + } + return 0; + +check_event_happened_4_pmode: + if (self->temp == event_chk){ + return 1; + } + return 0; +} + + +int +common_fsm_4_polling_mode(struct transvr_obj_s* self, + char *caller_name){ + /* [Return Value]: + * ERR_TRANSVR_UNINIT : (1) Initial not ready + * ERR_TRANSVR_UNPLUGGED : (1) Any -> Down + * ERR_TRANSVR_TASK_BUSY : (1) Wait Initial task + * ERR_TRANSVR_UNEXCPT : (1) Initial fail + * (2) Task fail + * (3) Reload fail + * ERR_TRNASVR_BE_ISOLATED : (1) Already be isolated + * OK Case (return 0) : (1) action_4_connected + * (2) action_4_nothing (initial retry) + */ + int curr_state[2]; + int old_state = self->state; + int old_type = self->type; + int new_state = STATE_TRANSVR_UNEXCEPTED; + int new_type = TRANSVR_TYPE_ERROR; + int return_val = ERR_TRANSVR_UNEXCPT; + + /* Never initial */ + if (self->state == STATE_TRANSVR_NEW) { + goto comfsm_action_4_reinit_obj; + } + /* Detect current state */ + switch (detect_transvr_state(self, curr_state)) { + case 0: + new_state = curr_state[0]; + new_type = curr_state[1]; + break; + + case ERR_TRNASVR_BE_ISOLATED: + new_state = STATE_TRANSVR_ISOLATED; + new_type = old_type; + break; + + case ERR_TRANSVR_I2C_CRASH: + goto comfsm_action_4_report_i2c_crash; + + case ERR_TRANSVR_UNEXCPT: + default: + new_state = STATE_TRANSVR_UNEXCEPTED; + new_type = old_type; + } + /* State handling */ + switch (old_state) { + case STATE_TRANSVR_INIT: /* INIT -> */ + return_val = ERR_TRANSVR_UNINIT; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_CONNECTED: + switch (new_state) { + case STATE_TRANSVR_INIT: /* Case 1-1: UP -> INIT */ + SWPS_INFO("Detect %s is present. :1-1\n",self->swp_name); + return_val = ERR_TRANSVR_UNINIT; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_CONNECTED: /* Case 1-2: UP -> UP */ + return_val = 0; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_DISCONNECTED: /* Case 1-3: UP -> DOWN */ + SWPS_INFO("Detect %s is removed. :1-3\n",self->swp_name); + goto comfsm_action_4_disconnected; + + case STATE_TRANSVR_SWAPPED: /* Case 1-4: UP -> SWAP */ + SWPS_INFO("Detect %s is swapped. :1-4\n",self->swp_name); + goto comfsm_action_4_reload_obj; + + case STATE_TRANSVR_UNEXCEPTED: /* Case 1-5: UP -> UNEXPET */ + SWPS_INFO("Detect %s has error. :1-5\n",self->swp_name); + goto comfsm_action_4_unexpected; + + case STATE_TRANSVR_ISOLATED: /* Case 1-6: UP -> ISOLATE */ + SWPS_INFO("Detect %s be isolated. :1-6\n",self->swp_name); + goto comfsm_action_4_isolate_obj; + + default: + break; + } + goto comfsm_action_4_unexpected; + + case STATE_TRANSVR_DISCONNECTED: + switch (new_state) { + case STATE_TRANSVR_INIT: /* Case 2-1: DOWN -> INIT */ + SWPS_INFO("Detect %s is present. :2-1\n",self->swp_name); + return_val = ERR_TRANSVR_UNINIT; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_CONNECTED: /* Case 2-2: DOWN -> UP */ + SWPS_INFO("Detect %s is present. :2-2\n",self->swp_name); + goto comfsm_action_4_reinit_obj; + + case STATE_TRANSVR_DISCONNECTED: /* Case 2-3: DOWN -> DOWN */ + return_val = ERR_TRANSVR_UNPLUGGED; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_SWAPPED: /* Case 2-4: DOWN -> SWAP */ + SWPS_INFO("Detect %s is swapped. :2-4\n",self->swp_name); + goto comfsm_action_4_reload_obj; + + case STATE_TRANSVR_UNEXCEPTED: /* Case 2-5: DOWN -> UNEXPET */ + SWPS_INFO("Detect %s has error. :2-5\n",self->swp_name); + goto comfsm_action_4_unexpected; + + case STATE_TRANSVR_ISOLATED: /* Case 2-6: DOWN -> ISOLATE */ + SWPS_INFO("Detect %s be isolated. :2-6\n",self->swp_name); + goto comfsm_action_4_isolate_obj; + + default: + break; + } + goto comfsm_action_4_unexpected; + + case STATE_TRANSVR_UNEXCEPTED: + /* Filter out re-action */ + if (_is_except_happened_4_pmode(self, new_state)) { + goto comfsm_action_4_keep_state; + } + /* First action */ + switch (new_state) { + case STATE_TRANSVR_INIT: /* Case 3-1: UNEXPET -> INIT */ + SWPS_INFO("Detect %s is present. :3-1\n",self->swp_name); + self->temp = EVENT_TRANSVR_EXCEP_INIT; + return_val = ERR_TRANSVR_UNINIT; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_CONNECTED: /* Case 3-2: UNEXPET -> UP */ + SWPS_INFO("Detect %s is present. :3-2\n",self->swp_name); + self->temp = EVENT_TRANSVR_EXCEP_UP; + goto comfsm_action_4_reload_obj; + + case STATE_TRANSVR_DISCONNECTED: /* Case 3-3: UNEXPET -> DOWN */ + SWPS_INFO("Detect %s is removed. :3-3\n",self->swp_name); + goto comfsm_action_4_disconnected; + + case STATE_TRANSVR_SWAPPED: /* Case 3-4: UNEXPET -> SWAP */ + SWPS_INFO("Detect %s is swapped. :3-4\n",self->swp_name); + self->temp = EVENT_TRANSVR_EXCEP_SWAP; + goto comfsm_action_4_reload_obj; + + case STATE_TRANSVR_UNEXCEPTED: /* Case 3-5: UNEXPET -> UNEXPET */ + self->temp = EVENT_TRANSVR_EXCEP_EXCEP; + return_val = ERR_TRANSVR_UNEXCPT; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_ISOLATED: /* Case 3-6: UNEXPET -> ISOLATE */ + SWPS_INFO("Detect %s be isolated. :3-6\n",self->swp_name); + goto comfsm_action_4_isolate_obj; + + default: + break; + } + goto comfsm_action_4_unexpected; + + case STATE_TRANSVR_ISOLATED: + /* Filter out re-action */ + if (_is_except_happened_4_pmode(self, new_state)) { + goto comfsm_action_4_keep_state; + } + /* First action */ + switch (new_state) { + case STATE_TRANSVR_INIT: /* Case 4-1: ISOLATE -> INIT */ + SWPS_INFO("Detect %s internal error. :4-1\n",self->swp_name); + self->temp = EVENT_TRANSVR_EXCEP_INIT; + return_val = ERR_TRNASVR_BE_ISOLATED; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_CONNECTED: /* Case 4-2: ISOLATE -> UP */ + SWPS_INFO("Detect %s internal error. :4-2\n",self->swp_name); + self->temp = EVENT_TRANSVR_EXCEP_UP; + return_val = ERR_TRNASVR_BE_ISOLATED; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_DISCONNECTED: /* Case 4-3: ISOLATE -> DOWN */ + SWPS_INFO("Detect %s is removed. :4-3\n",self->swp_name); + goto comfsm_action_4_disconnected; + + case STATE_TRANSVR_SWAPPED: /* Case 4-4: ISOLATE -> SWAP */ + SWPS_INFO("Detect %s internal error. :4-4\n",self->swp_name); + self->temp = EVENT_TRANSVR_EXCEP_SWAP; + return_val = ERR_TRNASVR_BE_ISOLATED; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_UNEXCEPTED: /* Case 4-5: ISOLATE -> UNEXPET */ + SWPS_INFO("Detect %s internal error. :4-5\n",self->swp_name); + self->temp = EVENT_TRANSVR_EXCEP_EXCEP; + return_val = ERR_TRNASVR_BE_ISOLATED; + goto comfsm_action_4_keep_state; + + case STATE_TRANSVR_ISOLATED: /* Case 4-6: ISOLATE -> ISOLATE */ + return_val = ERR_TRNASVR_BE_ISOLATED; + goto comfsm_action_4_keep_state; + + default: + break; + } + goto comfsm_action_4_unexpected; + + default: + break; + } + goto comfsm_action_4_unexpected; + + +comfsm_action_4_keep_state: + return return_val; + +comfsm_action_4_reinit_obj: + SWPS_DEBUG("FSM action: %s re-initial.\n", self->swp_name); + return_val = _transvr_init_handler(self); + goto comfsm_action_4_identify_event; + +comfsm_action_4_reload_obj: + SWPS_DEBUG("FSM action: %s reload.\n", self->swp_name); + self->type = new_type; + return_val = reload_transvr_obj(self, new_type); + goto comfsm_action_4_identify_event; + +comfsm_action_4_identify_event: + switch (return_val) { + case EVENT_TRANSVR_INIT_UP: + case EVENT_TRANSVR_TASK_DONE: + goto comfsm_action_4_connected; + + case EVENT_TRANSVR_INIT_DOWN: + goto comfsm_action_4_disconnected; + + case EVENT_TRANSVR_INIT_REINIT: + goto comfsm_action_4_nothing; + + case EVENT_TRANSVR_TASK_WAIT: + self->state = STATE_TRANSVR_INIT; + return ERR_TRANSVR_TASK_BUSY; + + case EVENT_TRANSVR_TASK_FAIL: + SWPS_INFO("%s detect EVENT_TRANSVR_TASK_FAIL.\n", self->swp_name); + goto comfsm_action_4_unexpected; + + case EVENT_TRANSVR_INIT_FAIL: + SWPS_INFO("%s detect EVENT_TRANSVR_INIT_FAIL.\n", self->swp_name); + goto comfsm_action_4_unexpected; + + case EVENT_TRANSVR_RELOAD_FAIL: + SWPS_INFO("%s detect EVENT_TRANSVR_RELOAD_FAIL.\n", self->swp_name); + goto comfsm_action_4_unexpected; + + case EVENT_TRANSVR_I2C_CRASH: + goto comfsm_action_4_report_i2c_crash; + + case EVENT_TRANSVR_EXCEP_ISOLATED: + goto comfsm_action_4_isolate_obj; + + default: + SWPS_INFO("%s detect undefined event:%d.\n", self->swp_name, return_val); + goto comfsm_action_4_unexpected; + } + +comfsm_action_4_nothing: + SWPS_DEBUG("FSM action: %s do nothing.\n", self->swp_name); + return 0; + +comfsm_action_4_connected: + SWPS_DEBUG("FSM action: %s Connected.\n", self->swp_name); + self->state = STATE_TRANSVR_CONNECTED; + self->type = new_type; + self->send_uevent(self, KOBJ_ADD); + _transvr_clean_retry(self); + return 0; + +comfsm_action_4_disconnected: + SWPS_DEBUG("FSM action: %s Disconnected. \n", self->swp_name); + self->state = STATE_TRANSVR_DISCONNECTED; + self->temp = EVENT_TRANSVR_TASK_DONE; + self->send_uevent(self, KOBJ_REMOVE); + _transvr_clean_retry(self); + _transvr_clean_handler(self); + return ERR_TRANSVR_UNPLUGGED; + +comfsm_action_4_report_i2c_crash: + SWPS_DEBUG("FSM action: %s report I2C crash.\n", self->swp_name); + self->state = STATE_TRANSVR_UNEXCEPTED; + return ERR_TRANSVR_I2C_CRASH; + +comfsm_action_4_isolate_obj: + SWPS_DEBUG("FSM action: %s isolate.\n", self->swp_name); + self->state = STATE_TRANSVR_ISOLATED; + return ERR_TRNASVR_BE_ISOLATED; + +comfsm_action_4_unexpected: + SWPS_INFO("FSM action: %s unexpected.\n", self->swp_name); + SWPS_INFO("Dump: :%d :0x%02x :%d :0x%02x\n", + old_state, old_type, new_state, new_type); + self->state = STATE_TRANSVR_UNEXCEPTED; + self->send_uevent(self, KOBJ_REMOVE); + _transvr_clean_handler(self); + return ERR_TRANSVR_UNEXCPT; +} + + +int +fake_fsm_4_direct_mode(struct transvr_obj_s* self, + char *caller_name){ + self->state = STATE_TRANSVR_CONNECTED; + self->type = TRANSVR_TYPE_FAKE; + return 0; +} + + +int +fake_fsm_4_polling_mode(struct transvr_obj_s* self, + char *caller_name){ + self->state = STATE_TRANSVR_CONNECTED; + self->type = TRANSVR_TYPE_FAKE; + return 0; +} + + +/* ========== Object functions for Initial procedure ========== + */ +int +transvr_init_common(struct transvr_obj_s *self){ + /* Nothing to update */ + return EVENT_TRANSVR_TASK_DONE; +} + + +int +transvr_init_fake(struct transvr_obj_s *self){ + return EVENT_TRANSVR_TASK_DONE; +} + + +int +transvr_init_sfp(struct transvr_obj_s *self){ + + int tmp_val = DEBUG_TRANSVR_INT_VAL; + int err_code = DEBUG_TRANSVR_INT_VAL; + char *err_msg = "ERR"; + + self->info = sft_detect_transvr_class(self); + /* Disable auto_config */ + if (!self->auto_config) { + return EVENT_TRANSVR_TASK_DONE; + } + /* Handle multi-rate */ + err_code = initfunc_sfp_handle_multi_rate_mode(self); + if (err_code < 0) { + err_msg = "initfunc_sfp_handle_multi_rate_mode fail!"; + goto err_transvr_init_sfp_1; + } + /* Handle 1G- RJ45 */ + tmp_val = err_code; + err_code = initfunc_sfp_handle_1g_rj45(self); + if (err_code < 0) { + err_msg = "initfunc_sfp_handle_1g_rj45 fail!"; + goto err_transvr_init_sfp_1; + } + tmp_val = (tmp_val > err_code ? tmp_val : err_code); + if (tmp_val > EVENT_TRANSVR_TASK_DONE) { + return tmp_val; + } + return EVENT_TRANSVR_TASK_DONE; + +err_transvr_init_sfp_1: + SWPS_INFO("%s: %s :%d :%s\n", + __func__, err_msg, err_code, self->swp_name); + return EVENT_TRANSVR_INIT_FAIL; +} + + +int +transvr_init_qsfp(struct transvr_obj_s *self){ + + int err = EVENT_TRANSVR_EXCEP_EXCEP; + char *emsg = "ERR"; + + self->info = qsft_detect_transvr_class(self); + if (!self->auto_config) { + return EVENT_TRANSVR_TASK_DONE; + } + err = initfunc_qsfp_handle_power_mode(self); + if (err < 0){ + emsg = "initfunc_qsfp_handle_tx_disable fail!"; + goto err_transvr_init_qsfp; + } + return EVENT_TRANSVR_TASK_DONE; + +err_transvr_init_qsfp: + SWPS_INFO("%s: %s :%d :%s\n", + __func__, emsg, err, self->swp_name); + return EVENT_TRANSVR_INIT_FAIL; +} + + +int +transvr_init_qsfp28(struct transvr_obj_s *self){ + + int tmp_val = EVENT_TRANSVR_EXCEP_EXCEP; + int err_val = EVENT_TRANSVR_EXCEP_EXCEP; + char *err_msg = "ERR"; + + /* Handle QSFP common */ + err_val = transvr_init_qsfp(self); + if (err_val < 0){ + err_msg = "transvr_init_qsfp fail!"; + goto err_transvr_init_qsfp28_1; + } + /* Disable auto_config */ + if (!self->auto_config) { + return err_val; + } + /* Handle CDR */ + tmp_val = err_val; + err_val = initfunc_qsfp28_handle_cdr(self); + if (err_val < 0){ + err_msg = "Handle CDR fail!"; + goto err_transvr_init_qsfp28_1; + } + tmp_val = (tmp_val > err_val ? tmp_val : err_val); + if (tmp_val > EVENT_TRANSVR_TASK_DONE) { + return tmp_val; + } + return EVENT_TRANSVR_TASK_DONE; + +err_transvr_init_qsfp28_1: + SWPS_INFO("%s: %s :%d :%s\n", + __func__, err_msg, err_val, self->swp_name); + return EVENT_TRANSVR_INIT_FAIL; +} + + +/* ========== Object Initial handler ========== + */ +static int +_is_transvr_valid(struct transvr_obj_s *self, + int type, + int state) { + /* [Return] + * 0 : OK, inserted + * EVENT_TRANSVR_INIT_DOWN : OK, removed + * EVENT_TRANSVR_INIT_FAIL : Outside error, type doesn't supported + * EVENT_TRANSVR_EXCEP_INIT : Internal error, state undefined + */ + switch (type) { + case TRANSVR_TYPE_SFP: + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + case TRANSVR_TYPE_QSFP_28: + case TRANSVR_TYPE_UNPLUGGED: + case TRANSVR_TYPE_FAKE: + break; + default: + SWPS_INFO("detect undefined type:0x%02x on %s\n", + type, self->swp_name); + return EVENT_TRANSVR_INIT_FAIL; + } + switch (state) { + case STATE_TRANSVR_DISCONNECTED: + return EVENT_TRANSVR_INIT_DOWN; + case STATE_TRANSVR_INIT: + case STATE_TRANSVR_CONNECTED: + case STATE_TRANSVR_SWAPPED: + break; + default: + SWPS_INFO("detect undefined state:%d on %s\n", + state, self->swp_name); + return EVENT_TRANSVR_EXCEP_INIT; + } + return 0; +} + + +static int +_is_transvr_hw_ready(struct transvr_obj_s *self, + int type){ + /* [Return] + * EVENT_TRANSVR_TASK_DONE : Ready + * EVENT_TRANSVR_TASK_WAIT : Not ready + * EVENT_TRANSVR_INIT_FAIL : Error + */ + int addr = DEBUG_TRANSVR_INT_VAL; + int page = DEBUG_TRANSVR_INT_VAL; + int offs = DEBUG_TRANSVR_INT_VAL; + int bit = DEBUG_TRANSVR_INT_VAL; + int ready = DEBUG_TRANSVR_INT_VAL; + int err = DEBUG_TRANSVR_INT_VAL; + char *emsg = DEBUG_TRANSVR_STR_VAL; + uint8_t ab_val = DEBUG_TRANSVR_HEX_VAL; + + switch (type) { + case TRANSVR_TYPE_SFP: + addr = VAL_TRANSVR_8472_READY_ADDR; + page = VAL_TRANSVR_8472_READY_PAGE; + offs = VAL_TRANSVR_8472_READY_OFFSET; + bit = VAL_TRANSVR_8472_READY_BIT; + ready = VAL_TRANSVR_8472_READY_VALUE; + ab_val = VAL_TRANSVR_8472_READY_ABNORMAL; + break; + + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + case TRANSVR_TYPE_QSFP_28: + addr = VAL_TRANSVR_8436_READY_ADDR; + page = VAL_TRANSVR_8436_READY_PAGE; + offs = VAL_TRANSVR_8436_READY_OFFSET; + bit = VAL_TRANSVR_8436_READY_BIT; + ready = VAL_TRANSVR_8436_READY_VALUE; + ab_val = VAL_TRANSVR_8436_READY_ABNORMAL; + break; + + case TRANSVR_TYPE_UNPLUGGED: + case TRANSVR_TYPE_FAKE: + return EVENT_TRANSVR_TASK_DONE; + + default: + emsg = "unexpected case"; + goto err_is_transvr_hw_ready; + } + /* Select target page */ + err = _common_setup_page(self, addr, page, offs, 1, 0); + if (err < 0) { + emsg = "setup page fail"; + goto err_is_transvr_hw_ready; + } + /* Check feature supported + * [Note] + * Some of transceiver/cables doesn't support "Status Indicators" + * (ex:DAC, RJ45 copper SFP ...etc). In these case, we bypass the + * step of checking Status Indicators, then state machine will take + * the following handle procedure. + */ + err = i2c_smbus_read_byte_data(self->i2c_client_p, + VAL_TRANSVR_COMID_OFFSET); + if (err < 0) { + emsg = "doesn't support Status Indicators"; + goto bypass_is_transvr_hw_ready; + } + /* Filter abnormal case */ + if (err == ab_val) { + emsg = "detect using unusual definition."; + goto bypass_is_transvr_hw_ready; + } + /* Get Status Indicators */ + err = i2c_smbus_read_byte_data(self->i2c_client_p, offs); + if (err < 0) { + emsg = "detect current value fail"; + goto err_is_transvr_hw_ready; + } + if ((err & (1<:%d\n", __func__, emsg, type); + return EVENT_TRANSVR_TASK_DONE; + +err_is_transvr_hw_ready: + SWPS_DEBUG("%s: %s :%d\n", __func__, emsg, type); + return EVENT_TRANSVR_INIT_FAIL; +} + + +static int +_is_transvr_support_ctle(struct transvr_obj_s *self) { + + switch (self->info) { + case TRANSVR_CLASS_OPTICAL_25G: + case TRANSVR_CLASS_OPTICAL_25G_AOC: + case TRANSVR_CLASS_OPTICAL_25G_SR: + case TRANSVR_CLASS_OPTICAL_25G_LR: + case TRANSVR_CLASS_OPTICAL_25G_ER: + case TRANSVR_CLASS_OPTICAL_100G: + case TRANSVR_CLASS_OPTICAL_100G_AOC: + case TRANSVR_CLASS_OPTICAL_100G_SR4: + case TRANSVR_CLASS_OPTICAL_100G_LR4: + case TRANSVR_CLASS_OPTICAL_100G_ER4: + case TRANSVR_CLASS_OPTICAL_100G_PSM4: + return 1; + default: + break; + } + return 0; +} + + +static int +_transvr_init_handler(struct transvr_obj_s *self){ + + int detect[2]; + int d_state = STATE_TRANSVR_UNEXCEPTED; + int d_type = TRANSVR_TYPE_ERROR; + int result = ERR_TRANSVR_UNINIT; + int retry = 6; /* (6+1) x 0.3 = 2.1s > spec:2.0s */ + int elimit = 63; + char emsg[64] = DEBUG_TRANSVR_STR_VAL; + + /* Clean and check callback */ + self->state = STATE_TRANSVR_INIT; + if (self->init == NULL) { + snprintf(emsg, elimit, "init() is null"); + goto initer_err_case_unexcept_0; + } + if (self->clean == NULL) { + snprintf(emsg, elimit, "clean() is null"); + goto initer_err_case_unexcept_0; + } + self->clean(self); + + /* Detect transceiver information */ + result = detect_transvr_state(self, detect); + if (result < 0) { + snprintf(emsg, elimit, "detect_transvr_state() fail"); + switch (result) { + case ERR_TRANSVR_I2C_CRASH: + goto initer_err_case_i2c_ceash; + case ERR_TRNASVR_BE_ISOLATED: + goto initer_err_case_be_isolated; + + case ERR_TRANSVR_UNEXCPT: + default: + break; + } + goto initer_err_case_retry_1; + } + d_state = detect[0]; + d_type = detect[1]; + + /* Verify transceiver type and state */ + switch (_is_transvr_valid(self, d_type, d_state)) { + case 0: + break; + case EVENT_TRANSVR_INIT_DOWN: + goto initer_ok_case_down;; + case EVENT_TRANSVR_INIT_FAIL: + snprintf(emsg, elimit, "transceiver type doesn't support"); + goto initer_err_case_alarm_to_user; + case EVENT_TRANSVR_EXCEP_INIT: + default: + goto initer_err_case_unexcept_1; + } + + /* Handle reload case */ + if (self->type != d_type){ + /* This is the protect mechanism. Normally, This case will not happen. + * When State machine detect swap event during initial, It will trigger + * reload function to ensure type correct. */ + if (_reload_transvr_obj(self, d_type) < 0){ + snprintf(emsg, elimit, "reload object fail"); + goto initer_err_case_unexcept_1; + } + } + + /* Check transceiver HW initial ready */ + switch (_is_transvr_hw_ready(self, d_type)) { + case EVENT_TRANSVR_TASK_DONE: + break; + case EVENT_TRANSVR_TASK_WAIT: + goto initer_err_case_retry_1; + case EVENT_TRANSVR_INIT_FAIL: + default: + goto initer_err_case_unexcept_1; + } + + /* Try to update all and check */ + if (self->update_all(self, 1) < 0){ + /* For some transceiver, EEPROME has lag issues during initial stage. + * In this case, we set status back to STATE_TRANSVR_NEW, than it will + * be checked in next polling cycle. */ + goto initer_err_case_retry_1; + } + + /* Execute init() call back */ + result = self->init(self); + switch (result) { + case EVENT_TRANSVR_TASK_DONE: + break; + case EVENT_TRANSVR_TASK_WAIT: + goto initer_ok_case_wait; + + default: + snprintf(emsg, elimit, "undefined init() return:%d\n", result); + goto initer_err_case_unexcept_1; + } + goto initer_ok_case_up; + + +initer_ok_case_wait: + self->dump_all(self); + return EVENT_TRANSVR_TASK_WAIT; + +initer_ok_case_up: + self->state = STATE_TRANSVR_CONNECTED; + self->temp = 0; + self->dump_all(self); + return EVENT_TRANSVR_INIT_UP; + +initer_ok_case_down: + self->temp = 0; + self->state = STATE_TRANSVR_DISCONNECTED; + return EVENT_TRANSVR_INIT_DOWN; + +initer_err_case_i2c_ceash: + SWPS_DEBUG("%s: %s :%s :I2C crash\n", + __func__, emsg, self->swp_name); + self->state = STATE_TRANSVR_UNEXCEPTED; + return EVENT_TRANSVR_I2C_CRASH; + +initer_err_case_be_isolated: + SWPS_DEBUG("%s: %s :%s :isolated\n", + __func__, emsg, self->swp_name); + self->state = STATE_TRANSVR_ISOLATED; + return EVENT_TRANSVR_EXCEP_ISOLATED; + +initer_err_case_retry_1: + SWPS_DEBUG("%s: %s :%s :retry\n", + __func__, emsg, self->swp_name); + if (_transvr_handle_retry(self, retry) == 0) { + self->state = STATE_TRANSVR_NEW; + return EVENT_TRANSVR_INIT_REINIT; + } + goto initer_err_case_alarm_to_user; + +initer_err_case_unexcept_1: + self->clean(self); +initer_err_case_unexcept_0: + self->state = STATE_TRANSVR_UNEXCEPTED; + if (_is_except_happened_4_pmode(self, d_state) && + (self->mode == TRANSVR_MODE_POLLING) ){ + SWPS_INFO("%s: %s :%s\n", __func__, emsg, self->swp_name); + SWPS_INFO("Dump: :%d :%d :%d :%d\n", + self->state, self->type, d_state, d_type); + } + return EVENT_TRANSVR_INIT_FAIL; + +initer_err_case_alarm_to_user: + SWPS_DEBUG("%s: %s :%s :alarm_to_user\n", + __func__, emsg, self->swp_name); + self->state = STATE_TRANSVR_UNEXCEPTED; + alarm_msg_2_user(self, "detected transceiver/cables not meet SFF standard"); + return EVENT_TRANSVR_INIT_FAIL; +} + + +/* ========== Object functions for Clean procedure ========== + */ +int +_transvr_clean_handler(struct transvr_obj_s *self){ + + int retval = DEBUG_TRANSVR_INT_VAL; + + if (!self->clean) { + SWPS_ERR("%s: %s clean() is NULL.\n", + __func__, self->swp_name); + return EVENT_TRANSVR_TASK_FAIL; + } + retval = self->clean(self); + if (retval != EVENT_TRANSVR_TASK_DONE){ + SWPS_ERR("%s: %s clean() fail. [ERR]:%d\n", + __func__, self->swp_name, retval); + return retval; + } + return EVENT_TRANSVR_TASK_DONE; +} + + +int +common_transvr_clean(struct transvr_obj_s *self){ + + transvr_task_free_all(self); + transvr_cache_free_all(self); + return EVENT_TRANSVR_TASK_DONE; +} + + +int +qsfp_transvr_clean(struct transvr_obj_s *self){ + + int retval; + int lpower_config = 1; + + retval = _taskfunc_qsfp_setup_power_mod(self, lpower_config); + if (retval < 0){ + SWPS_ERR("%s: Set lpmod fail! :%d\n", + __func__, retval); + return retval; + } + retval = common_transvr_clean(self); + if (retval < 0){ + SWPS_ERR("%s: common_transvr_clean fail! :%d\n", + __func__, retval); + return retval; + } + return EVENT_TRANSVR_TASK_DONE; +} + + +int +fake_transvr_clean(struct transvr_obj_s *self){ + + return EVENT_TRANSVR_TASK_DONE; +} + + +/* ========== Object functions for check and update ========== + */ +int +common_transvr_check(struct transvr_obj_s *self){ + + char fun_str[32] = "common_transvr_check"; + + if (self->mode != TRANSVR_MODE_POLLING) { + SWPS_ERR("%s: mode:%d is not TRANSVR_MODE_POLLING\n", + fun_str, self->mode); + return ERR_TRANSVR_UNEXCPT; + } + /* Trigger delay task */ + transvr_task_run_all(self); + /* Trigger state machine to check and update */ + return self->fsm_4_polling(self, fun_str); +} + + +int +fake_transvr_check(struct transvr_obj_s *self){ + return 0; +} + + +/* ========== Functions for Factory pattern ========== + */ +static int +setup_transvr_public_cb(struct transvr_obj_s *self, + int transvr_type){ + switch (transvr_type){ + case TRANSVR_TYPE_SFP: + self->get_id = common_get_id; + self->get_ext_id = common_get_ext_id; + self->get_connector = common_get_connector; + self->get_vendor_name = common_get_vendor_name; + self->get_vendor_pn = common_get_vendor_pn; + self->get_vendor_rev = common_get_vendor_rev; + self->get_vendor_sn = common_get_vendor_sn; + self->get_power_cls = unsupported_get_func; + self->get_br = common_get_br; + self->get_len_sm = sfp_get_len_sm; + self->get_len_smf = common_get_len_smf; + self->get_len_om1 = common_get_len_om1; + self->get_len_om2 = common_get_len_om2; + self->get_len_om3 = common_get_len_om3; + self->get_len_om4 = common_get_len_om4; + self->get_comp_rev = common_get_comp_rev; + self->get_comp_eth_1 = sfp_get_comp_eth_1; + self->get_comp_eth_10 = sfp_get_comp_eth_10; + self->get_comp_eth_10_40 = unsupported_get_func; + self->get_comp_extend = common_get_comp_extended; + self->get_cdr = unsupported_get_func; + self->get_rate_id = sfp_get_rate_id; + self->get_soft_rs0 = sfp_get_soft_rs0; + self->get_soft_rs1 = sfp_get_soft_rs1; + self->get_info = common_get_info; + self->get_if_type = sfp_get_if_type; + self->get_if_speed = sfp_get_if_speed; + self->get_if_lane = common_get_if_lane; + self->get_curr_temp = sfp_get_transvr_temp; + self->get_curr_vol = sfp_get_transvr_voltage; + self->get_soft_rx_los = unsupported_get_func2; + self->get_soft_tx_disable = unsupported_get_func2; + self->get_soft_tx_fault = unsupported_get_func2; + self->get_auto_tx_disable = unsupported_get_func2; + self->get_tx_bias = sfp_get_transvr_tx_bias; + self->get_tx_power = sfp_get_transvr_tx_power; + self->get_rx_power = sfp_get_transvr_rx_power; + self->get_tx_eq = sfp_get_transvr_tx_eq; + self->get_rx_am = unsupported_get_func2; + self->get_rx_em = sfp_get_transvr_rx_em; + self->get_wavelength = sfp_get_wavelength; + self->get_extphy_offset = sfp_get_1g_rj45_extphy_offset; + self->get_extphy_reg = sfp_get_1g_rj45_extphy_reg; + self->set_cdr = unsupported_set_func; + self->set_soft_rs0 = sfp_set_soft_rs0; + self->set_soft_rs1 = sfp_set_soft_rs1; + self->set_soft_tx_disable = unsupported_set_func; + self->set_auto_tx_disable = unsupported_set_func; + self->set_tx_eq = sfp_set_tx_eq; + self->set_rx_am = unsupported_set_func; + self->set_rx_em = sfp_set_rx_em; + self->set_extphy_offset = sfp_set_1g_rj45_extphy_offset; + self->set_extphy_reg = sfp_set_1g_rj45_extphy_reg; + return 0; + + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + self->get_id = common_get_id; + self->get_ext_id = common_get_ext_id; + self->get_connector = common_get_connector; + self->get_vendor_name = common_get_vendor_name; + self->get_vendor_pn = common_get_vendor_pn; + self->get_vendor_rev = common_get_vendor_rev; + self->get_vendor_sn = common_get_vendor_sn; + self->get_power_cls = qsfp_get_power_cls; + self->get_br = common_get_br; + self->get_len_sm = unsupported_get_func; + self->get_len_smf = common_get_len_smf; + self->get_len_om1 = common_get_len_om1; + self->get_len_om2 = common_get_len_om2; + self->get_len_om3 = common_get_len_om3; + self->get_len_om4 = common_get_len_om4; + self->get_comp_rev = common_get_comp_rev; + self->get_comp_eth_1 = qsfp_get_comp_eth; + self->get_comp_eth_10 = unsupported_get_func; + self->get_comp_eth_10_40 = qsfp_get_comp_10_40; + self->get_comp_extend = common_get_comp_extended; + self->get_cdr = unsupported_get_func; + self->get_rate_id = unsupported_get_func; + self->get_soft_rs0 = unsupported_get_func; /* TBD */ + self->get_soft_rs1 = unsupported_get_func; /* TBD */ + self->get_info = common_get_info; + self->get_if_type = qsfp_get_if_type; + self->get_if_speed = qsfp_get_if_speed; + self->get_if_lane = common_get_if_lane; + self->get_curr_temp = qsfp_get_transvr_temp; + self->get_curr_vol = qsfp_get_transvr_voltage; + self->get_soft_rx_los = qsfp_get_soft_rx_los; + self->get_soft_tx_disable = qsfp_get_soft_tx_disable; + self->get_soft_tx_fault = qsfp_get_soft_tx_fault; + self->get_auto_tx_disable = qsfp_get_auto_tx_disable; + self->get_tx_bias = qsfp_get_transvr_tx_bias; + self->get_tx_power = qsfp_get_transvr_tx_power; + self->get_rx_power = qsfp_get_transvr_rx_power; + self->get_tx_eq = unsupported_get_func2; + self->get_rx_am = unsupported_get_func2; + self->get_rx_em = unsupported_get_func2; + self->get_wavelength = qsfp_get_wavelength; + self->get_extphy_offset = unsupported_get_func2; + self->get_extphy_reg = unsupported_get_func2; + self->set_cdr = unsupported_set_func; + self->set_soft_rs0 = unsupported_set_func; /* TBD */ + self->set_soft_rs1 = unsupported_set_func; /* TBD */ + self->set_soft_tx_disable = qsfp_set_soft_tx_disable; + self->set_auto_tx_disable = qsfp_set_auto_tx_disable; + self->set_tx_eq = unsupported_set_func; + self->set_rx_am = unsupported_set_func; + self->set_rx_em = unsupported_set_func; + self->set_extphy_offset = unsupported_set_func; + self->set_extphy_reg = unsupported_set_func; + return 0; + + case TRANSVR_TYPE_QSFP_28: + self->get_id = common_get_id; + self->get_ext_id = common_get_ext_id; + self->get_connector = common_get_connector; + self->get_vendor_name = common_get_vendor_name; + self->get_vendor_pn = common_get_vendor_pn; + self->get_vendor_rev = common_get_vendor_rev; + self->get_vendor_sn = common_get_vendor_sn; + self->get_power_cls = qsfp_get_power_cls; + self->get_br = common_get_br; + self->get_len_sm = unsupported_get_func; + self->get_len_smf = common_get_len_smf; + self->get_len_om1 = common_get_len_om1; + self->get_len_om2 = common_get_len_om2; + self->get_len_om3 = common_get_len_om3; + self->get_len_om4 = common_get_len_om4; + self->get_comp_rev = common_get_comp_rev; + self->get_comp_eth_1 = qsfp_get_comp_eth; + self->get_comp_eth_10 = unsupported_get_func; + self->get_comp_eth_10_40 = qsfp_get_comp_10_40; + self->get_comp_extend = common_get_comp_extended; + self->get_cdr = qsfp_get_cdr; + self->get_rate_id = unsupported_get_func; + self->get_soft_rs0 = unsupported_get_func; /* TBD */ + self->get_soft_rs1 = unsupported_get_func; /* TBD */ + self->get_info = common_get_info; + self->get_if_type = qsfp_get_if_type; + self->get_if_speed = qsfp_get_if_speed; + self->get_if_lane = common_get_if_lane; + self->get_curr_temp = qsfp_get_transvr_temp; + self->get_curr_vol = qsfp_get_transvr_voltage; + self->get_soft_rx_los = qsfp_get_soft_rx_los; + self->get_soft_tx_disable = qsfp_get_soft_tx_disable; + self->get_soft_tx_fault = qsfp_get_soft_tx_fault; + self->get_auto_tx_disable = qsfp_get_auto_tx_disable; + self->get_tx_bias = qsfp_get_transvr_tx_bias; + self->get_tx_power = qsfp_get_transvr_tx_power; + self->get_rx_power = qsfp_get_transvr_rx_power; + self->get_tx_eq = qsfp_get_transvr_tx_eq; + self->get_rx_am = qsfp_get_transvr_rx_am; + self->get_rx_em = qsfp_get_transvr_rx_em; + self->get_wavelength = qsfp_get_wavelength; + self->get_extphy_offset = unsupported_get_func2; + self->get_extphy_reg = unsupported_get_func2; + self->set_cdr = qsfp_set_cdr; + self->set_soft_rs0 = unsupported_set_func; /* TBD */ + self->set_soft_rs1 = unsupported_set_func; /* TBD */ + self->set_soft_tx_disable = qsfp_set_soft_tx_disable; + self->set_auto_tx_disable = qsfp_set_auto_tx_disable; + self->set_tx_eq = qsfp_set_tx_eq; + self->set_rx_am = qsfp_set_rx_am; + self->set_rx_em = qsfp_set_rx_em; + self->set_extphy_offset = unsupported_set_func; + self->set_extphy_reg = unsupported_set_func; + return 0; + + case TRANSVR_TYPE_FAKE: + self->get_id = fake_get_hex; + self->get_ext_id = fake_get_hex; + self->get_connector = fake_get_hex; + self->get_vendor_name = fake_get_str; + self->get_vendor_pn = fake_get_str; + self->get_vendor_rev = fake_get_str; + self->get_vendor_sn = fake_get_str; + self->get_power_cls = fake_get_int; + self->get_br = fake_get_hex; + self->get_len_sm = fake_get_int; + self->get_len_smf = fake_get_int; + self->get_len_om1 = fake_get_int; + self->get_len_om2 = fake_get_int; + self->get_len_om3 = fake_get_int; + self->get_len_om4 = fake_get_int; + self->get_comp_rev = fake_get_hex; + self->get_comp_eth_1 = fake_get_hex; + self->get_comp_eth_10 = fake_get_hex; + self->get_comp_eth_10_40 = fake_get_hex; + self->get_comp_extend = fake_get_hex; + self->get_cdr = fake_get_hex; + self->get_rate_id = fake_get_hex; + self->get_soft_rs0 = fake_get_binary; + self->get_soft_rs1 = fake_get_binary; + self->get_info = fake_get_int; + self->get_if_type = fake_get_str; + self->get_if_speed = fake_get_str; + self->get_if_lane = fake_get_str; + self->get_curr_temp = fake_get_str; + self->get_curr_vol = fake_get_str; + self->get_soft_rx_los = fake_get_str; + self->get_soft_tx_disable = fake_get_str; + self->get_soft_tx_fault = fake_get_str; + self->get_auto_tx_disable = fake_get_str; + self->get_tx_bias = fake_get_str; + self->get_tx_power = fake_get_str; + self->get_rx_power = fake_get_str; + self->get_tx_eq = fake_get_str; + self->get_rx_am = fake_get_str; + self->get_rx_em = fake_get_str; + self->get_wavelength = fake_get_str; + self->get_extphy_offset = fake_get_str; + self->get_extphy_reg = fake_get_str; + self->set_cdr = fake_set_hex; + self->set_soft_rs0 = fake_set_int; + self->set_soft_rs1 = fake_set_int; + self->set_soft_tx_disable = fake_set_int; + self->set_auto_tx_disable = fake_set_int; + self->set_tx_eq = fake_set_int; + self->set_rx_am = fake_set_int; + self->set_rx_em = fake_set_int; + self->set_extphy_offset = fake_set_hex; + self->set_extphy_reg = fake_set_hex; + return 0; + + default: + break; + } + SWPS_WARN("%s: Detect non-defined type:%d\n", __func__, transvr_type); + return ERR_TRANSVR_UNEXCPT; +} + + +static int +setup_transvr_private_cb(struct transvr_obj_s *self, + int transvr_type){ + switch (transvr_type){ + case TRANSVR_TYPE_SFP: + self->init = transvr_init_sfp; + self->clean = common_transvr_clean; + self->check = common_transvr_check; + self->update_all = _sfp_update_attr_all; + self->fsm_4_direct = common_fsm_4_direct_mode; + self->fsm_4_polling = common_fsm_4_polling_mode; + self->send_uevent = sfp_send_uevent; + self->dump_all = sfp_transvr_dump; + return 0; + + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + self->init = transvr_init_qsfp; + self->clean = qsfp_transvr_clean; + self->check = common_transvr_check; + self->update_all = _qsfp_update_attr_all; + self->fsm_4_direct = common_fsm_4_direct_mode; + self->fsm_4_polling = common_fsm_4_polling_mode; + self->send_uevent = qsfp_send_uevent; + self->dump_all = qsfp_transvr_dump; + return 0; + + case TRANSVR_TYPE_QSFP_28: + self->init = transvr_init_qsfp28; + self->clean = qsfp_transvr_clean; + self->check = common_transvr_check; + self->update_all = _qsfp_update_attr_all; + self->fsm_4_direct = common_fsm_4_direct_mode; + self->fsm_4_polling = common_fsm_4_polling_mode; + self->send_uevent = qsfp_send_uevent; + self->dump_all = qsfp_transvr_dump; + return 0; + + case TRANSVR_TYPE_FAKE: + self->init = transvr_init_fake; + self->clean = fake_transvr_clean; + self->check = fake_transvr_check; + self->update_all = fake_transvr_update; + self->fsm_4_direct = fake_fsm_4_direct_mode; + self->fsm_4_polling = fake_fsm_4_polling_mode; + self->send_uevent = fake_send_uevent; + self->dump_all = fake_transvr_dump; + return 0; + + default: + break; + } + SWPS_WARN("%s: Detect non-defined type:%d\n", __func__, transvr_type); + return ERR_TRANSVR_UNEXCPT; +} + + +static struct eeprom_map_s * +get_eeprom_map(int transvr_type){ + + switch (transvr_type){ + case TRANSVR_TYPE_SFP: + return &eeprom_map_sfp; + case TRANSVR_TYPE_QSFP: + case TRANSVR_TYPE_QSFP_PLUS: + return &eeprom_map_qsfp; + case TRANSVR_TYPE_QSFP_28: + return &eeprom_map_qsfp28; + + default: + break; + } + SWPS_WARN("%s: Detect non-defined type:%d\n", __func__, transvr_type); + return NULL; +} + + +static int +setup_transvr_ssize_attr(char *swp_name, + struct transvr_obj_s *self, + struct eeprom_map_s *map_p, + struct ioexp_obj_s *ioexp_obj_p, + int ioexp_virt_offset, + int transvr_type, + int chipset_type, + int chan_id, + int run_mode){ + switch (run_mode){ + case TRANSVR_MODE_DIRECT: /* Direct access device mode */ + case TRANSVR_MODE_POLLING: /* Polling mode, read from cache */ + self->mode = run_mode; + break; + default: + SWPS_ERR("%s: non-defined run_mode:%d\n", + __func__, run_mode); + self->mode = DEBUG_TRANSVR_INT_VAL; + return -1; + } + self->eeprom_map_p = map_p; + self->ioexp_obj_p = ioexp_obj_p; + self->ioexp_virt_offset = ioexp_virt_offset; + self->chan_id = chan_id; + self->layout = transvr_type; + self->type = transvr_type; + self->chipset_type = chipset_type; + self->state = STATE_TRANSVR_NEW; + self->info = STATE_TRANSVR_NEW; + self->auto_tx_disable = VAL_TRANSVR_FUNCTION_DISABLE; + strncpy(self->swp_name, swp_name, 32); + mutex_init(&self->lock); + return 0; +} + + +static int +setup_transvr_dsize_attr(struct transvr_obj_s *self){ + + char *emsg = DEBUG_TRANSVR_STR_VAL; + + self->vendor_name = kzalloc((LEN_TRANSVR_M_STR * sizeof(char)), GFP_KERNEL); + if (!self->vendor_name){ + emsg = "vendor_name"; + goto err_setup_d_attr; + } + self->vendor_pn = kzalloc((LEN_TRANSVR_M_STR * sizeof(char)), GFP_KERNEL); + if (!self->vendor_pn){ + emsg = "vendor_pn"; + goto err_setup_d_attr; + } + self->vendor_rev = kzalloc((LEN_TRANSVR_M_STR * sizeof(char)), GFP_KERNEL); + if (!self->vendor_rev){ + emsg = "vendor_rev"; + goto err_setup_d_attr; + } + self->vendor_sn = kzalloc((LEN_TRANSVR_M_STR * sizeof(char)), GFP_KERNEL); + if (!self->vendor_sn){ + emsg = "vendor_sn"; + goto err_setup_d_attr; + } + self->worker_p = NULL; + return 0; + +err_setup_d_attr: + SWPS_ERR("%s: %s kzalloc fail!", __func__, emsg); + return ERR_TRANSVR_UNEXCPT; +} + + +static int +setup_i2c_client(struct transvr_obj_s *self){ + + struct i2c_adapter *adap = NULL; + struct i2c_client *client = NULL; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + adap = i2c_get_adapter(self->chan_id); + if(!adap){ + snprintf(err_msg, sizeof(err_msg), + "can not get adap:%d", self->chan_id); + goto err_setup_i2c_client; + } + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (!client){ + snprintf(err_msg, sizeof(err_msg), + "can not kzalloc client:%d", self->chan_id); + goto err_setup_i2c_client; + } + client->adapter = adap; + self->i2c_client_p = client; + self->i2c_client_p->addr = VAL_TRANSVR_COMID_ARREESS; + return 0; + +err_setup_i2c_client: + SWPS_ERR("%s: %s\n", __func__, err_msg); + return ERR_TRANSVR_UNEXCPT; +} + + +struct transvr_obj_s * +create_transvr_obj(char *swp_name, + int chan_id, + struct ioexp_obj_s *ioexp_obj_p, + int ioexp_virt_offset, + int transvr_type, + int chipset_type, + int run_mode){ + + struct transvr_obj_s *result_p; + struct eeprom_map_s *map_p; + char err_msg[64] = DEBUG_TRANSVR_STR_VAL; + + /* Allocate transceiver object */ + map_p = get_eeprom_map(transvr_type); + if (!map_p){ + snprintf(err_msg, sizeof(err_msg), + "Invalid transvr_type:%d", transvr_type); + goto err_create_transvr_fail; + } + result_p = kzalloc(sizeof(*result_p), GFP_KERNEL); + if (!result_p){ + snprintf(err_msg, sizeof(err_msg), "kzalloc fail"); + goto err_create_transvr_fail; + } + /* Prepare static size attributes */ + if (setup_transvr_ssize_attr(swp_name, + result_p, + map_p, + ioexp_obj_p, + ioexp_virt_offset, + transvr_type, + chipset_type, + chan_id, + run_mode) < 0){ + goto err_create_transvr_sattr_fail; + } + /* Prepare dynamic size attributes */ + if (setup_transvr_dsize_attr(result_p) < 0){ + goto err_create_transvr_dattr_fail; + } + /* Prepare call back functions of object */ + if (setup_transvr_public_cb(result_p, transvr_type) < 0){ + goto err_create_transvr_dattr_fail; + } + /* Prepare call back functions of object */ + if (setup_transvr_private_cb(result_p, transvr_type) < 0){ + goto err_create_transvr_dattr_fail; + } + /* Prepare i2c client object */ + if (setup_i2c_client(result_p) < 0){ + goto err_create_transvr_dattr_fail; + } + return result_p; + +err_create_transvr_dattr_fail: + kfree(result_p->vendor_sn); + kfree(result_p->vendor_rev); + kfree(result_p->vendor_pn); + kfree(result_p->vendor_name); +err_create_transvr_sattr_fail: + kfree(result_p); +err_create_transvr_fail: + SWPS_ERR("%s: %s :%d :%d :%d\n", + __func__, err_msg, chan_id, ioexp_virt_offset, transvr_type); + return NULL; +} +EXPORT_SYMBOL(create_transvr_obj); + + +static int +_reload_transvr_obj(struct transvr_obj_s *self, + int new_type){ + + struct eeprom_map_s *new_map_p; + struct eeprom_map_s *old_map_p = self->eeprom_map_p; + struct i2c_client *old_i2c_p = self->i2c_client_p; + int old_type = self->type; + + /* Change state to STATE_TRANSVR_INIT */ + self->state = STATE_TRANSVR_INIT; + self->type = new_type; + /* Replace EEPROME map */ + new_map_p = get_eeprom_map(new_type); + if (!new_map_p){ + goto err_private_reload_func_1; + } + self->eeprom_map_p = new_map_p; + /* Reload i2c client */ + if (setup_i2c_client(self) < 0){ + goto err_private_reload_func_2; + } + /* Replace call back functions */ + if (setup_transvr_public_cb(self, new_type) < 0){ + goto err_private_reload_func_3; + } + if (setup_transvr_private_cb(self, new_type) < 0){ + goto err_private_reload_func_3; + } + if(old_i2c_p){ + i2c_put_adapter(old_i2c_p->adapter); + } + kfree(old_i2c_p); + return 0; + +err_private_reload_func_3: + SWPS_INFO("%s: init() fail!\n", __func__); + if(old_i2c_p){ + i2c_put_adapter(old_i2c_p->adapter); + } + kfree(old_i2c_p); + self->state = STATE_TRANSVR_UNEXCEPTED; + self->type = TRANSVR_TYPE_ERROR; + return -2; + +err_private_reload_func_2: + self->eeprom_map_p = old_map_p; + self->i2c_client_p = old_i2c_p; +err_private_reload_func_1: + self->state = STATE_TRANSVR_UNEXCEPTED; + self->type = old_type; + SWPS_INFO("%s fail! :0x%02x\n", __func__, new_type); + return -1; +} + + +static int +reload_transvr_obj(struct transvr_obj_s *self, + int new_type){ + + int result_val = ERR_TRANSVR_UNEXCPT; + + /* Reload phase */ + result_val = _reload_transvr_obj(self, new_type); + if (result_val < 0){ + SWPS_INFO("%s: reload phase fail! :%d\n", + __func__, result_val); + return EVENT_TRANSVR_RELOAD_FAIL; + } + /* Initial phase */ + result_val = _transvr_init_handler(self); + if (result_val < 0){ + SWPS_INFO("%s: initial phase fail! :%d\n", + __func__, result_val); + } + return result_val; +} + + +int +isolate_transvr_obj(struct transvr_obj_s *self) { + + self->state = STATE_TRANSVR_ISOLATED; + SWPS_INFO("%s: %s be isolated\n", __func__, self->swp_name); + return 0; +} +EXPORT_SYMBOL(isolate_transvr_obj); + + +int +resync_channel_tier_2(struct transvr_obj_s *self) { + + int val = TRANSVR_TYPE_ERROR; + + if (self->state == STATE_TRANSVR_ISOLATED) { + return 0; + } + self->i2c_client_p->addr = VAL_TRANSVR_COMID_ARREESS; + val = i2c_smbus_read_byte_data(self->i2c_client_p, + VAL_TRANSVR_COMID_OFFSET); + if (val < 0) { + return -1; + } + return 0; +} +EXPORT_SYMBOL(resync_channel_tier_2); + +/* For build single module using (Ex: ONL platform) */ +MODULE_LICENSE("GPL"); + + +/* ----------------------------------------- + * ToDo List + * ----------------------------------------- + * 1. _sfp_detect_class_by_feature() + * => Need check ACC use case. + * 2. _sfp_detect_class_by_1g_ethernet() + * => Need check 0.1G use case. + * 3. Loopback transceiver use case. + * => Less much data + * 4. _qsfp_detect_class_by_extend_comp() + * => Verify 100G CWDM4 + * => Verify Obsolete (assigned before 100G CWDM4 MSA required FEC) + * => Verify 100G CLR4 + * => Verify 100GE-DWDM2 + * => Verify 40G PSM4 Parallel SMF + * => Verify 100G ACC (Active Copper Cable) or 25GAUI C2M ACC. + * => Verify 100G ACC or 25GAUI C2M ACC. + * => Verify 25GBASE-LR + * => Verify 40G Active Cable (XLPPI) + */ + + + + + + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/transceiver.h b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/transceiver.h new file mode 100644 index 000000000000..0438a351271a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/transceiver.h @@ -0,0 +1,809 @@ +#ifndef TRANSCEIVER_H +#define TRANSCEIVER_H + +#include + +/* advanced features control */ +#define TRANSVR_INFO_DUMP_ENABLE (1) +#define TRANSVR_INFO_CACHE_ENABLE (1) +#define TRANSVR_UEVENT_ENABLE (1) + +/* Transceiver type define */ +#define TRANSVR_TYPE_UNKNOW_1 (0x00) +#define TRANSVR_TYPE_UNKNOW_2 (0xff) +#define TRANSVR_TYPE_SFP (0x03) /* Define for SFP, SFP+, SFP28 */ +#define TRANSVR_TYPE_QSFP (0x0c) +#define TRANSVR_TYPE_QSFP_PLUS (0x0d) +#define TRANSVR_TYPE_QSFP_28 (0x11) +#define TRANSVR_TYPE_UNPLUGGED (0xfa) /* Define for ERROR handle */ +#define TRANSVR_TYPE_FAKE (0xfc) /* Define for ERROR handle */ +#define TRANSVR_TYPE_INCONSISTENT (0xfd) /* Define for ERROR handle */ +#define TRANSVR_TYPE_ERROR (0xfe) /* Define for ERROR handle */ + +/* Transceiver class for base info */ +#define TRANSVR_CLASS_UNSPECIFIED (0) +#define TRANSVR_CLASS_ERROR (-26001) +#define TRANSVR_CLASS_1G (26001) +#define TRANSVR_CLASS_10G (26011) +#define TRANSVR_CLASS_25G (26021) +#define TRANSVR_CLASS_40G (26041) +#define TRANSVR_CLASS_100G (26101) +#define TRANSVR_CLASS_NO_SPERARABLE (26901) +#define TRANSVR_CLASS_EXTEND_COMP (26902) +/* Transceiver class for Optical 1G */ +#define TRANSVR_CLASS_OPTICAL (27000) +#define TRANSVR_CLASS_OPTICAL_100 (27001) +#define TRANSVR_CLASS_OPTICAL_1G (27002) +#define TRANSVR_CLASS_OPTICAL_1G_AOC (27003) +#define TRANSVR_CLASS_OPTICAL_1G_SX (27004) +#define TRANSVR_CLASS_OPTICAL_1G_LX (27005) +#define TRANSVR_CLASS_OPTICAL_1G_EX (27006) +/* Transceiver class for Optical 10G */ +#define TRANSVR_CLASS_OPTICAL_10G (27010) +#define TRANSVR_CLASS_OPTICAL_10G_S_AOC (27011) +#define TRANSVR_CLASS_OPTICAL_10G_S_SR (27012) +#define TRANSVR_CLASS_OPTICAL_10G_S_LR (27013) +#define TRANSVR_CLASS_OPTICAL_10G_S_ER (27014) +#define TRANSVR_CLASS_OPTICAL_10G_Q_AOC (27015) +#define TRANSVR_CLASS_OPTICAL_10G_Q_SR (27016) +#define TRANSVR_CLASS_OPTICAL_10G_Q_LR (27017) +#define TRANSVR_CLASS_OPTICAL_10G_Q_ER (27018) +/* Transceiver class for Optical 25G */ +#define TRANSVR_CLASS_OPTICAL_25G (27020) +#define TRANSVR_CLASS_OPTICAL_25G_AOC (27021) +#define TRANSVR_CLASS_OPTICAL_25G_SR (27022) +#define TRANSVR_CLASS_OPTICAL_25G_LR (27023) +#define TRANSVR_CLASS_OPTICAL_25G_ER (27024) +/* Transceiver class for Optical 40G */ +#define TRANSVR_CLASS_OPTICAL_40G (27040) +#define TRANSVR_CLASS_OPTICAL_40G_AOC (27041) +#define TRANSVR_CLASS_OPTICAL_40G_SR4 (27042) +#define TRANSVR_CLASS_OPTICAL_40G_LR4 (27043) +#define TRANSVR_CLASS_OPTICAL_40G_ER4 (27044) +/* Transceiver class for Optical 100G */ +#define TRANSVR_CLASS_OPTICAL_100G (27100) +#define TRANSVR_CLASS_OPTICAL_100G_AOC (27101) +#define TRANSVR_CLASS_OPTICAL_100G_SR4 (27102) +#define TRANSVR_CLASS_OPTICAL_100G_LR4 (27103) +#define TRANSVR_CLASS_OPTICAL_100G_ER4 (27104) +#define TRANSVR_CLASS_OPTICAL_100G_PSM4 (27105) +/* Transceiver class for Copper */ +#define TRANSVR_CLASS_COPPER (28000) +#define TRANSVR_CLASS_COPPER_L1_1G (28001) +#define TRANSVR_CLASS_COPPER_L1_10G (28011) +#define TRANSVR_CLASS_COPPER_L4_10G (28012) +#define TRANSVR_CLASS_COPPER_L1_25G (28021) +#define TRANSVR_CLASS_COPPER_L4_40G (28041) +#define TRANSVR_CLASS_COPPER_L4_100G (28101) +/* Transceiver class for Base-T */ +#define TRANSVR_CLASS_BASE_T_1000 (29001) +#define TRANSVR_CLASS_BASE_T_1000_up (29002) +/* For uevent message */ +#define TRANSVR_UEVENT_KEY_IF "IF_TYPE" +#define TRANSVR_UEVENT_KEY_SP "IF_SPEED" +#define TRANSVR_UEVENT_KEY_LANE "IF_LANE" +#define TRANSVR_UEVENT_UNKNOW "UNKNOW" +#define TRANSVR_IF_KR "KR" +#define TRANSVR_IF_KR4 "KR4" +#define TRANSVR_IF_SR "SR" +#define TRANSVR_IF_SR4 "SR4" +#define TRANSVR_IF_SFI "SFI" +#define TRANSVR_IF_IF_GMII "GMII" +#define TRANSVR_IF_IF_XGMII "XGMII" +#define TRANSVR_IF_SP_100 "100" +#define TRANSVR_IF_SP_1G "1000" +#define TRANSVR_IF_SP_10G "10000" +#define TRANSVR_IF_SP_25G "25000" +#define TRANSVR_IF_SP_40G "40000" +#define TRANSVR_IF_SP_100G "100000" + +/* Transceiver mode define */ +#define TRANSVR_MODE_DIRECT (21000) +#define TRANSVR_MODE_POLLING (21001) + +/* Transceiver state define + * [Note] + * 1. State is used to represent the state of "Transceiver" and "Object". + * 2. State for different target has different means. The description as following: + */ +#define STATE_TRANSVR_CONNECTED (0) /* [Transvr]:Be plugged in. [Obj]:Link up, and work normally. */ +#define STATE_TRANSVR_NEW (-100) /* [Transvr]:(Not used) [Obj]:Create */ +#define STATE_TRANSVR_INIT (-101) /* [Transvr]:Be plugged in. [Obj]:Link up, and in initial process. */ +#define STATE_TRANSVR_ISOLATED (-102) /* [Transvr]:Be plugged in. [Obj]:Isolate, and not provide service. */ +#define STATE_TRANSVR_SWAPPED (-200) /* [Transvr]:Be plugged in. [Obj]:(Not used) */ +#define STATE_TRANSVR_DISCONNECTED (-300) /* [Transvr]:Un-plugged. [Obj]:Link down, and not provide service. */ +#define STATE_TRANSVR_UNEXCEPTED (-901) /* [Transvr]:Any [Obj]:Any, and not in expect case. */ + +/* Task state define */ +#define STATE_T_TASK_WAIT (110) +#define STATE_T_TASK_DONE (0) +#define STATE_T_TASK_INIT (-110) +#define STATE_T_TASK_FAIL (-410) + + +/* Event for task handling */ +#define EVENT_TRANSVR_TASK_WAIT (2101) +#define EVENT_TRANSVR_TASK_DONE (0) +#define EVENT_TRANSVR_TASK_FAIL (-2101) +/* Event for initial handling */ +#define EVENT_TRANSVR_INIT_UP (2201) +#define EVENT_TRANSVR_INIT_DOWN (1) +#define EVENT_TRANSVR_INIT_REINIT (-2201) +#define EVENT_TRANSVR_INIT_FAIL (-2202) +/* Event for others */ +#define EVENT_TRANSVR_RELOAD_FAIL (-2301) +#define EVENT_TRANSVR_EXCEP_INIT (-2401) +#define EVENT_TRANSVR_EXCEP_UP (-2402) +#define EVENT_TRANSVR_EXCEP_DOWN (-2403) +#define EVENT_TRANSVR_EXCEP_SWAP (-2404) +#define EVENT_TRANSVR_EXCEP_EXCEP (-2405) +#define EVENT_TRANSVR_EXCEP_ISOLATED (-2406) +#define EVENT_TRANSVR_I2C_CRASH (-2501) + +/* Transceiver error code define */ +#define ERR_TRANSVR_UNINIT (-201) +#define ERR_TRANSVR_UNPLUGGED (-202) +#define ERR_TRANSVR_ABNORMAL (-203) +#define ERR_TRANSVR_NOSTATE (-204) +#define ERR_TRANSVR_NOTSUPPORT (-205) +#define ERR_TRANSVR_BADINPUT (-206) +#define ERR_TRANSVR_UPDATE_FAIL (-207) +#define ERR_TRANSVR_RELOAD_FAIL (-208) +#define ERR_TRANSVR_INIT_FAIL (-209) +#define ERR_TRANSVR_UNDEFINED (-210) +#define ERR_TRANSVR_TASK_FAIL (-211) +#define ERR_TRANSVR_TASK_BUSY (-212) +#define ERR_TRANSVR_UEVENT_FAIL (-213) +#define ERR_TRANSVR_FUNC_DISABLE (-214) +#define ERR_TRANSVR_I2C_CRASH (-297) +#define ERR_TRNASVR_BE_ISOLATED (-298) +#define ERR_TRANSVR_UNEXCPT (-299) + +/* For debug */ +#define DEBUG_TRANSVR_INT_VAL (-99) +#define DEBUG_TRANSVR_HEX_VAL (0xfe) +#define DEBUG_TRANSVR_STR_VAL "ERROR" + +/* For system internal */ +#define VAL_TRANSVR_COMID_ARREESS (0x50) +#define VAL_TRANSVR_COMID_OFFSET (0x00) +#define VAL_TRANSVR_EXTPHY_ADDR_56 (0x56) +#define VAL_TRANSVR_8472_READY_ADDR (0x51) +#define VAL_TRANSVR_8472_READY_PAGE (-1) +#define VAL_TRANSVR_8472_READY_OFFSET (110) +#define VAL_TRANSVR_8472_READY_BIT (0) +#define VAL_TRANSVR_8472_READY_VALUE (0) +#define VAL_TRANSVR_8472_READY_ABNORMAL (0xff) +#define VAL_TRANSVR_8436_READY_ADDR (0x50) +#define VAL_TRANSVR_8436_READY_PAGE (-1) +#define VAL_TRANSVR_8436_READY_OFFSET (2) +#define VAL_TRANSVR_8436_READY_BIT (0) +#define VAL_TRANSVR_8436_READY_VALUE (0) +#define VAL_TRANSVR_8436_READY_ABNORMAL (0xff) +#define VAL_TRANSVR_8436_PWD_ADDR (0x50) +#define VAL_TRANSVR_8436_PWD_PAGE (-1) +#define VAL_TRANSVR_8436_PWD_OFFSET (123) +#define VAL_TRANSVR_PAGE_FREE (-99) +#define VAL_TRANSVR_PAGE_SELECT_OFFSET (127) +#define VAL_TRANSVR_PAGE_SELECT_DELAY (5) +#define VAL_TRANSVR_TASK_RETRY_FOREVER (-999) +#define VAL_TRANSVR_FUNCTION_DISABLE (-1) +#define STR_TRANSVR_SFP "SFP" +#define STR_TRANSVR_QSFP "QSFP" +#define STR_TRANSVR_QSFP_PLUS "QSFP+" +#define STR_TRANSVR_QSFP28 "QSFP28" + +/* For transvr buf len */ +#define LEN_TRANSVR_S_STR (16) +#define LEN_TRANSVR_M_STR (32) +#define LEN_TRANSVR_L_STR (64) + +/* Optical wavelength */ +#define VAL_OPTICAL_WAVELENGTH_SR (850) +#define VAL_OPTICAL_WAVELENGTH_LR (1310) +#define VAL_OPTICAL_WAVELENGTH_ER (1550) + +/* BCM chip type define */ +#define BCM_CHIP_TYPE_TRIDENT_2 (31001) /* Magnolia, Hudson32i, Spruce */ +#define BCM_CHIP_TYPE_TOMAHAWK (31002) /* Redwood, Cypress, Sequoia */ +#define BCM_CHIP_TYPE_TRIDENT_3 (31003) /* Maple */ + +#define BF_CHIP_TYPE_TOFINO (31011) /* Lavender */ + +/* Info from transceiver EEPROM */ +struct eeprom_map_s { + int addr_br; int page_br; int offset_br; int length_br; + int addr_cdr; int page_cdr; int offset_cdr; int length_cdr; + int addr_comp_rev; int page_comp_rev; int offset_comp_rev; int length_comp_rev; + int addr_connector; int page_connector; int offset_connector; int length_connector; + int addr_diag_type; int page_diag_type; int offset_diag_type; int length_diag_type; + int addr_extbr; int page_extbr; int offset_extbr; int length_extbr; + int addr_ext_id; int page_ext_id; int offset_ext_id; int length_ext_id; + int addr_id; int page_id; int offset_id; int length_id; + int addr_len_sm; int page_len_sm; int offset_len_sm; int length_len_sm; + int addr_len_smf; int page_len_smf; int offset_len_smf; int length_len_smf; + int addr_len_om1; int page_len_om1; int offset_len_om1; int length_len_om1; + int addr_len_om2; int page_len_om2; int offset_len_om2; int length_len_om2; + int addr_len_om3; int page_len_om3; int offset_len_om3; int length_len_om3; + int addr_len_om4; int page_len_om4; int offset_len_om4; int length_len_om4; + int addr_option; int page_option; int offset_option; int length_option; + int addr_rate_id; int page_rate_id; int offset_rate_id; int length_rate_id; + int addr_rx_am; int page_rx_am; int offset_rx_am; int length_rx_am; + int addr_rx_em; int page_rx_em; int offset_rx_em; int length_rx_em; + int addr_rx_los; int page_rx_los; int offset_rx_los; int length_rx_los; + int addr_rx_power; int page_rx_power; int offset_rx_power; int length_rx_power; + int addr_soft_rs0; int page_soft_rs0; int offset_soft_rs0; int length_soft_rs0; + int addr_soft_rs1; int page_soft_rs1; int offset_soft_rs1; int length_soft_rs1; + int addr_temp; int page_temp; int offset_temp; int length_temp; + int addr_trancomp; int page_trancomp; int offset_trancomp; int length_trancomp; + int addr_trancomp_ext; int page_trancomp_ext; int offset_trancomp_ext; int length_trancomp_ext; + int addr_tx_bias; int page_tx_bias; int offset_tx_bias; int length_tx_bias; + int addr_tx_disable; int page_tx_disable; int offset_tx_disable; int length_tx_disable; + int addr_tx_eq; int page_tx_eq; int offset_tx_eq; int length_tx_eq; + int addr_tx_fault; int page_tx_fault; int offset_tx_fault; int length_tx_fault; + int addr_tx_power; int page_tx_power; int offset_tx_power; int length_tx_power; + int addr_vendor_name; int page_vendor_name; int offset_vendor_name; int length_vendor_name; + int addr_vendor_pn; int page_vendor_pn; int offset_vendor_pn; int length_vendor_pn; + int addr_vendor_rev; int page_vendor_rev; int offset_vendor_rev; int length_vendor_rev; + int addr_vendor_sn; int page_vendor_sn; int offset_vendor_sn; int length_vendor_sn; + int addr_voltage; int page_voltage; int offset_voltage; int length_voltage; + int addr_wavelength; int page_wavelength; int offset_wavelength; int length_wavelength; +}; + + +struct transvr_worker_s; + +/* Class of transceiver object */ +struct transvr_obj_s { + + /* ========== Object private property ========== + * [Prop]: id + * [Desc]: Type of serial transceiver. + * [Note]: SFP:03h / QSFP:0Ch / QSPF+:0Dh /QSFP28:11h + */ + uint8_t id; + + /* [Prop]: connector + * [Desc]: Connector type. + * [Note]: SFP : A0h / 2 + * QSFP: 00h / 130 + */ + uint8_t connector; + + /* [Prop]: transvr_comp + * [Desc]: Transceiver compliance code. + * [Note]: SFP: SFF-8472 + * - Normal : A0h / offset 3-10 + * - Extended: A0h / offset 36 + * QSFP: SFF-8436 & SFF-8636 + * - Normal : 00h / offset 131-138 + * - Extended: 00h / offset 192 + */ + uint8_t transvr_comp[8]; + uint8_t transvr_comp_ext; + + /* [Prop]: vendor_name + * [Desc]: SFP vendor name (ASCII 16 byte char). + * [Note]: ex:FINISAR CORP. + */ + char *vendor_name; + + /* [Prop]: vendor_pn + * [Desc]: Part number provided by SFP vendor (ASCII 16 byte char). + * [Note]: + */ + char *vendor_pn; + + /* [Prop]: vendor_rev + * [Desc]: Revision level for part number provided by vendor (ASCII 4 byte char). + * [Note]: + */ + char *vendor_rev; + + /* [Prop]: vendor_sn + * [Desc]: Serial number provided by vendor (ASCII 16 byte char). + * [Note]: + */ + char *vendor_sn; + + /* [Prop]: Extended identifier + * [Desc]: SFP: + * => None + * + * QSFP: + * => This byte contained two information: + * (1) Power consumption class + * (2) CDR function present + * [Note]: Bit description as below: + * [SFP] + * None + * + * [QSFP] + * (1) Power consumption class: + * Class 1: 1.5W (Bit6-7 = 00:) + * Class 2: 2.0W (Bit6-7 = 01:) + * Class 3: 2.5W (Bit6-7 = 10:) + * Class 4: 3.5W (Bit6-7 = 11:) + * Class 5: 4.0W (Bit0-1 = 01:) + * Class 6: 4.5W (Bit0-1 = 10:) + * Class 7: 5.0W (Bit0-1 = 11:) + * (2) CDR function present: + * Bit2: 0 = No CDR in RX + * 1 = CDR present in RX + * Bit3: 0 = No CDR in TX + * 1 = CDR present in TX + */ + uint8_t ext_id; + + /* [Prop]: br + * [Desc]: Nominal bit rate, units of 100 MBits/sec. + * [Note]: SFP:03h / QSFP:0Ch / QSPF+:0Dh + * has val: 0x67 + * no val : + */ + uint8_t br; + + /* [Prop]: extbr + * [Desc]: Extended br (00h/222) + * [Desc]: Nominal bit rate per channel, units of 250 Mbps. + * Complements. Byte 140. See Table 32A. + */ + uint8_t extbr; + + /* [Prop]: len_sm + * [Desc]: Length (single mode)-(100's)m + * [Note]: This value specifies the link length that is supported by the transceiver + * while operating in compliance with the applicable standards using single mode + * fiber. The value is in units of 100 meters. A value of 255 means that the + * transceiver supports a link length greater than 25.4 km. A value of zero means + * that the transceiver does not support single mode fiber or that the length + * information must be determined from the transceiver technology. + */ + int len_sm; + + /* [Prop]: len_smf + * [Desc]: Length (single mode)-km + * [Note]: Addition to EEPROM data from original GBIC definition. This value specifies + * the link length that is supported by the transceiver while operating in + * compliance with the applicable standards using single mode fiber. The value + * is in units of kilometers. A value of 255 means that the transceiver supports + * a link length greater than 254 km. A value of zero means that the transceiver + * does not support single mode fiber or that the length information must be + * determined from the transceiver technology. + */ + int len_smf; + + /* [Prop]: len_om1 + * [Desc]: Link length supported for 62.5 um OM1 fiber, units of 10 m + * [Note]: The value is in units of 10 meters. A value of 255 means that the + * transceiver supports a link length greater than 2.54 km. A value of + * zero means that the transceiver does not support 50 micron multi-mode + * fiber or that the length information must be determined from the transceiver + * technology. + */ + int len_om1; + + /* [Prop]: len_om2 + * [Desc]: Link length supported for 50 um OM2 fiber, units of 10 m + * [Note]: The value is in units of 10 meters. A value of 255 means that the + * transceiver supports a link length greater than 2.54 km. A value of + * zero means that the transceiver does not support 50 micron multi-mode + * fiber or that the length information must be determined from the transceiver + * technology. + */ + int len_om2; + + /* [Prop]: len_om3 + * [Desc]: Length (50um, OM3) + * [Note]: This value specifies link length that is supported by the transceiver while + * operating in compliance with applicable standards using 50 micron multimode + * OM3 [2000 MHz*km] fiber. The value is in units of 10 meters. A value of 255 + * means that the transceiver supports a link length greater than 2.54 km. A value + * of zero means that the transceiver does not support 50 micron multimode fiber + * or that the length information must be determined from the transceiver technology. + */ + int len_om3; + + /* [Prop]: len_om4 + * [Desc]: Length (50um, OM4) and Length (Active Cable or Copper) + * [Note]: For optical links, this value specifies link length that is supported by the + * transceiver while operating in compliance with applicable standards using 50 micron + * multimode OM4 [4700 MHz*km] fiber. The value is in units of 10 meters. A value of + * 255 means that the transceiver supports a link length greater than 2.54 km. A value + * of zero means that the transceiver does not support 50 micron multimode fiber or that + * the length information must be determined from the transceiver codes specified in Table 5-3. + * + * For copper links, this value specifies minimum link length supported by the transceiver + * while operating in compliance with applicable standards using copper cable. For active + * cable, this value represents actual length. The value is in units of 1 meter. A value of 255 + * means the transceiver supports a link length greater than 254 meters. A value of zero means + * the transceiver does not support copper or active cables or the length information must be + * determined from transceiver technology. Further information about cable design, equalization, + * and connectors is usually required to guarantee meeting a particular length requirement. + */ + int len_om4; + + /* [Prop]: comp_rev + * [Desc]: SFF spec revision compliance + * [Note]: Indicates which revision of SFF SFF-8472 (SFP) / SFF-8636 (QSFP) the transceiver + * complies with. (unsigned integer) + */ + uint8_t comp_rev; + + /* [Prop]: CDR + * [Desc]: For transceivers with CDR capability, setting the CDR to ON engages the internal + * retiming function. Setting the CDR to OFF enables an internal bypassing mode ,which + * directs traffic around the internal CDR. (Reference: SFF-8636) + * [Note]: value=0xff: ON. + * value=0x00: OFF. + */ + uint8_t cdr; + + /* [Prop]: rate_id + * [Desc]: Soft Rate Select 0(RX). + * [Note]: 1. Addr: A0h / Offset: 13 + * 2. Value description: + * 00h Unspecified + * 01h SFF-8079 (4/2/1G Rate_Select & AS0/AS1) + * 02h SFF-8431 (8/4/2G Rx Rate_Select only) + * 03h Unspecified * + * 04h SFF-8431 (8/4/2G Tx Rate_Select only) + * 05h Unspecified * + * 06h SFF-8431 (8/4/2G Independent Rx & Tx Rate_select) + * 07h Unspecified * + * 08h FC-PI-5 (16/8/4G Rx Rate_select only) High=16G only, Low=8G/4G + * 09h Unspecified * + * 0Ah FC-PI-5 (16/8/4G Independent Rx, Tx Rate_select) High=16G only, + * Low=8G/4G + * 0Bh Unspecified * + * 0Ch FC-PI-6 (32/16/8G Independent Rx, Tx Rate_Select) + * High=32G only, Low = 16G/8G + * 0Dh Unspecified * + * 0Eh 10/8G Rx and Tx Rate_Select controlling the operation or locking + * modes of the internal signal conditioner, retimer or CDR, according + * to the logic table defined in Table 10-2, High Bit Rate + * (10G) =9.95-11.3 Gb/s; Low Bit Rate (8G) = 8.5 Gb/s. In this mode, + * the default value of bit 110.3 (Soft Rate Select RS(0), Table 9-11) + * and of bit 118.3 (Soft Rate Select RS(1), Table 10-1) is 1. + * 0Fh Unspecified * + * 10h-FFh Unallocated + */ + int rate_id; + + /* [Prop]: soft_rs0 + * [Desc]: Soft Rate Select 0(RX). + * [Note]: 1. Writing '1' selects full bandwidth operation. + * 2. This bit is "OR'd with the hard Rate_Select, AS(0) or RS(0) pin value. + * 3. Default at power up is logic zero/low + * 4. Addr: A2h / Offset: 110 / Bit: 3 + */ + uint8_t soft_rs0; + + /* [Prop]: soft_rs1 + * [Desc]: Soft Rate Select 1(TX). + * [Note]: 1. Writing '1' selects full bandwidth TX operation. + * 2. This bit is "OR'd with the hard Rate_Select, AS(1) or RS(1) pin value. + * 3. Default at power up is logic zero/low + * 4. Addr: A2h / Offset: 118 / Bit: 3 + */ + uint8_t soft_rs1; + + /* [Prop]: diag_type + * [Desc]: DIAGNOSTIC MONITORING TYPE (A0h/92) + * [Note]: Description in SFF-8472 as below: + * Bit7: Reserved for legacy diagnostic implementations. Must be '0' for compliance + * with this document. + * Bit6: Digital diagnostic monitoring implemented (described in this document). + * Must be '1' for compliance with this document. + * Bit5 Internally calibrated + * Bit4 Externally calibrated + * Bit3 Received power measurement type.0 = OMA, 1 = average power + * Bit2 Address change required see section above, "addressing modes" + * Bit1-0 Unallocated + */ + uint8_t diag_type; + + /* [Prop]: curr_temp + * [Desc]: Transceiver Current Temperature (A2h/96-97) + * [Note]: 1. Dependent on diag_type. + * 2. 96: High byte + * 3. 97: Low byte + * 4. This feature only for SFP + */ + uint8_t curr_temp[2]; + + /* [Prop]: curr_vol + * [Desc]: Transceiver Current Voltage (SFP:A2h/108-109; QSFP:00h/22-23) + * [Note]: 1. Dependent on diag_type. + * 2. 98: High byte + * 3. 99: Low byte + * 4. This feature only for SFP + * 5. Internally measured transceiver supply voltage. Represented + * as a 16 bit unsigned integer with the voltage defined as the + * full 16 bit value (0-65535) with LSB equal to 100 uVolt, + * yielding a total range of 0 to +6.55 Volts + */ + uint8_t curr_voltage[2]; + + /* [Prop]: curr_tx_bias + * [Desc]: Transceiver TX Bias Current (SFP:A2h/100-101; QSFP:00h/26-27) + * [Note]: 1. Dependent on diag_type. + * 2. 100: High byte + * 3. 101: Low byte + * 4. This feature only for SFP + * 5. Measured TX bias current in uA. Represented as a 16 bit unsigned + * integer with the current defined as the full 16 bit value (0-65535) + * with LSB equal to 2 uA, yielding a total range of 0 to 131 mA. + * Accuracy is vendor specific but must be better than 10% of the + * manufacturer's nominal value over specified operating temperature + * and voltage. + */ + uint8_t curr_tx_bias[8]; + + /* [Prop]: curr_tx_power + * [Desc]: Transceiver TX Output Power (A2h/102-103) + * [Note]: 1. Dependent on diag_type. + * 2. 102: High byte + * 3. 103: Low byte + * 4. This feature only for SFP + * 5. Measured TX output power in mW. Represented as a 16 bit unsigned + * integer with the power defined as the full 16 bit value (0-65535) + * with LSB equal to 0.1 uW, yielding a total range of 0 to 6.5535 mW + * (~ -40 to +8.2 dBm). Data is assumed to be based on measurement of + * laser monitor photodiode current. It is factory calibrated to absolute + * units using the most representative fiber output type. Accuracy is + * vendor specific but must be better than 3dB over specified temperature + * and voltage. Data is not valid when the transmitter is disabled. + */ + uint8_t curr_tx_power[8]; + + /* [Prop]: curr_tx_power + * [Desc]: Transceiver TX Output Power (A2h/102-103) + * [Note]: 1. Dependent on diag_type. + * 2. 102: High byte + * 3. 103: Low byte + * 4. This feature only for SFP + * 5. Measured RX received optical power in mW. Value can represent either + * average received power or OMA depending upon how bit 3 of byte 92 (A0h) + * is set. Represented as a 16 bit unsigned integer with the power defined + * as the full 16 bit value (0-65535) with LSB equal to 0.1 uW, yielding a + * total range of 0 to 6.5535 mW (~ -40 to +8.2 dBm). Absolute accuracy is + * dependent upon the exact optical wavelength. For the vendor specified + * wavelength, accuracy shall be better than 3dB over specified temperature + * and voltage. + */ + uint8_t curr_rx_power[8]; + + /* [Prop]: wavelength + * [Desc]: Wavelength or Copper Cable Attenuation + * [Note]: (Following is info from SFF-8636) + * For optical free side devices, this parameter identifies the nominal + * transmitter output wavelength at room temperature. This parameter is a + * 16-bit hex value with Byte 186 as high order byte and Byte 187 as low + * order byte. The laser wavelength is equal to the 16-bit integer value + * divided by 20 in nm (units of 0.05 nm). This resolution should be adequate + * to cover all relevant wavelengths yet provide enough resolution for all + * expected DWDM applications. For accurate representation of controlled + * wavelength applications, this value should represent the center of the + * guaranteed wavelength range. If the free side device is identified as + * copper cable these registers will be used to define the cable attenuation. + * An indication of 0 dB attenuation refers to the case where the attenuation + * is not known or is unavailable. + * Byte 186 (00-FFh) is the copper cable attenuation at 2.5 GHz in units of 1 dB. + * Byte 187 (00-FFh) is the copper cable attenuation at 5.0 GHz in units of 1 dB. + */ + uint8_t wavelength[2]; + + /* [Prop]: Amplitude control + * [Desc]: Amplitude control + * [Note]: QSFP28 => SFF-8636 03H Byte-238/239 + */ + uint8_t rx_am[2]; + + /* [Prop]: Emphasis control + * [Desc]: Emphasis control + * [Note]: SFP+/28 => SFF-8472 A2H Byte-115 + * QSFP28 => SFF-8636 03H Byte-236/237 + */ + uint8_t rx_em[2]; + + /* [Prop]: Soft Rx LOS + * [Desc]: Soft Rx LOS which provide by transceiver + * [Note]: (Following is info from SFF-8636) + * Byte 3: + * - Bit 0: L-Rx1 LOS + * - Bit 1: L-Rx2 LOS + * - Bit 2: L-Rx3 LOS + * - Bit 3: L-Rx4 LOS + */ + uint8_t rx_los; + + /* [Prop]: Soft Tx Disable + * [Desc]: Soft Tx Disable which provide by transceiver + * [Note]: (Following is info from SFF-8636) + * Byte 86: + * - Bit 0: Tx1 Disable + * - Bit 1: Tx2 Disable + * - Bit 2: Tx3 Disable + * - Bit 3: Tx4 Disable + */ + uint8_t tx_disable; + + /* [Prop]: Soft Tx Fault + * [Desc]: Soft Tx Fault which provide by transceiver + * [Note]: (Following is info from SFF-8636) + * Byte 86: + * - Bit 0: Tx1 Fault + * - Bit 1: Tx2 Fault + * - Bit 2: Tx3 Fault + * - Bit 3: Tx4 Fault + */ + uint8_t tx_fault; + + /* [Prop]: Transceiver EQUALIZATION + * [Desc]: Transceiver EQUALIZATION + * [Note]: SFP+/28 => SFF-8472 A2H Byte-114 + * QSFP28 => SFF-8636 03H Byte-234/235 + */ + uint8_t tx_eq[2]; + + /* [Prop]: OPTION VALUES + * [Desc]: The bits in the option field shall specify the options implemented in the transceiver. + * [Note]: SFP+/28 => SFF-8472 A0H Byte-64/65 + * QSFP+/28 => SFF-8636 00H Byte-193/195 + */ + uint8_t option[3]; + + /* [Prop]: External PHY offset + * [Desc]: It needs to be setup first if you want to access transceiver external phy. + * [Note]: This feature dependent on transceiver. + * Currently, only 1G-RJ45 transceiver supported it. + */ + uint8_t extphy_offset; + + /* ========== Object private property ========== + */ + struct device *transvr_dev_p; + struct eeprom_map_s *eeprom_map_p; + struct i2c_client *i2c_client_p; + struct ioexp_obj_s *ioexp_obj_p; + struct transvr_worker_s *worker_p; + struct mutex lock; + char swp_name[32]; + int auto_config; + int auto_tx_disable; + int chan_id; + int chipset_type; + int curr_page; + int info; + int ioexp_virt_offset; + int lane_id[8]; + int layout; + int mode; + int retry; + int state; + int temp; + int type; + + /* ========== Object public functions ========== + */ + int (*get_id)(struct transvr_obj_s *self); + int (*get_ext_id)(struct transvr_obj_s *self); + int (*get_connector)(struct transvr_obj_s *self); + int (*get_vendor_name)(struct transvr_obj_s *self, char *buf_p); + int (*get_vendor_pn)(struct transvr_obj_s *self, char *buf_p); + int (*get_vendor_rev)(struct transvr_obj_s *self, char *buf_p); + int (*get_vendor_sn)(struct transvr_obj_s *self, char *buf_p); + int (*get_power_cls)(struct transvr_obj_s *self); + int (*get_br)(struct transvr_obj_s *self); + int (*get_len_sm)(struct transvr_obj_s *self); + int (*get_len_smf)(struct transvr_obj_s *self); + int (*get_len_om1)(struct transvr_obj_s *self); + int (*get_len_om2)(struct transvr_obj_s *self); + int (*get_len_om3)(struct transvr_obj_s *self); + int (*get_len_om4)(struct transvr_obj_s *self); + int (*get_comp_rev)(struct transvr_obj_s *self); + int (*get_comp_eth_1)(struct transvr_obj_s *self); + int (*get_comp_eth_10)(struct transvr_obj_s *self); + int (*get_comp_eth_10_40)(struct transvr_obj_s *self); + int (*get_comp_extend)(struct transvr_obj_s *self); + int (*get_cdr)(struct transvr_obj_s *self); + int (*get_rate_id)(struct transvr_obj_s *self); + int (*get_soft_rs0)(struct transvr_obj_s *self); + int (*get_soft_rs1)(struct transvr_obj_s *self); + int (*get_info)(struct transvr_obj_s *self); + int (*get_if_type)(struct transvr_obj_s *self, char *buf_p); + int (*get_if_speed)(struct transvr_obj_s *self, char *buf_p); + int (*get_if_lane)(struct transvr_obj_s *self, char *buf_p); + int (*get_curr_temp)(struct transvr_obj_s *self, char *buf_p); + int (*get_curr_vol)(struct transvr_obj_s *self, char *buf_p); + int (*get_soft_rx_los)(struct transvr_obj_s *self, char *buf_p); + int (*get_soft_tx_disable)(struct transvr_obj_s *self, char *buf_p); + int (*get_soft_tx_fault)(struct transvr_obj_s *self, char *buf_p); + int (*get_auto_tx_disable)(struct transvr_obj_s *self, char *buf_p); + int (*get_tx_bias)(struct transvr_obj_s *self, char *buf_p); + int (*get_tx_power)(struct transvr_obj_s *self, char *buf_p); + int (*get_rx_power)(struct transvr_obj_s *self, char *buf_p); + int (*get_tx_eq)(struct transvr_obj_s *self, char *buf_p); + int (*get_rx_am)(struct transvr_obj_s *self, char *buf_p); + int (*get_rx_em)(struct transvr_obj_s *self, char *buf_p); + int (*get_wavelength)(struct transvr_obj_s *self, char *buf_p); + int (*get_extphy_offset)(struct transvr_obj_s *self, char *buf_p); + int (*get_extphy_reg)(struct transvr_obj_s *self, char *buf_p); + int (*set_cdr)(struct transvr_obj_s *self, int input_val); + int (*set_soft_rs0)(struct transvr_obj_s *self, int input_val); + int (*set_soft_rs1)(struct transvr_obj_s *self, int input_val); + int (*set_soft_tx_disable)(struct transvr_obj_s *self, int input_val); + int (*set_auto_tx_disable)(struct transvr_obj_s *self, int input_val); + int (*set_tx_eq)(struct transvr_obj_s *self, int input_val); + int (*set_rx_am)(struct transvr_obj_s *self, int input_val); + int (*set_rx_em)(struct transvr_obj_s *self, int input_val); + int (*set_extphy_offset)(struct transvr_obj_s *self, int input_val); + int (*set_extphy_reg)(struct transvr_obj_s *self, int input_val); + + /* ========== Object private functions ========== + */ + int (*init)(struct transvr_obj_s *self); + int (*clean)(struct transvr_obj_s *self); + int (*check)(struct transvr_obj_s *self); + int (*update_all)(struct transvr_obj_s *self, int show_err); + int (*fsm_4_direct)(struct transvr_obj_s* self, char *caller_name); + int (*fsm_4_polling)(struct transvr_obj_s* self, char *caller_name); + int (*send_uevent)(struct transvr_obj_s* self, enum kobject_action u_action); + int (*dump_all)(struct transvr_obj_s* self); +}; + + +/* For AVL Mapping */ +struct transvr_avl_s { + char vendor_name[32]; + char vendor_pn[32]; + int (*init)(struct transvr_obj_s *self); +}; + + +/* Worker for long term task of transceiver */ +struct transvr_worker_s { + /* Task Parameter */ + struct transvr_obj_s *transvr_p; + struct transvr_worker_s *next_p; + struct transvr_worker_s *pre_p; + unsigned long trigger_time; + char func_name[64]; + int retry; + int state; + + /* Task private data */ + void *p_data; + + /* Call back function */ + int (*main_task)(struct transvr_worker_s *task); + int (*post_task)(struct transvr_worker_s *task); +}; + + +struct transvr_obj_s * +create_transvr_obj(char *swp_name, + int chan_id, + struct ioexp_obj_s *ioexp_obj_p, + int ioexp_virt_offset, + int transvr_type, + int chipset_type, + int run_mode); + +void lock_transvr_obj(struct transvr_obj_s *self); +void unlock_transvr_obj(struct transvr_obj_s *self); +int isolate_transvr_obj(struct transvr_obj_s *self); + +int resync_channel_tier_2(struct transvr_obj_s *self); + +void alarm_msg_2_user(struct transvr_obj_s *self, char *emsg); + +#endif /* TRANSCEIVER_H */ + + + + + + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/ucd9000.c b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/ucd9000.c new file mode 100644 index 000000000000..3e3aa950277f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/modules/ucd9000.c @@ -0,0 +1,247 @@ +/* + * Hardware monitoring driver for UCD90xxx Sequencer and System Health + * Controller series + * + * Copyright (C) 2011 Ericsson AB. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "pmbus.h" + +enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd9090, ucd90910 }; + +#define UCD9000_MONITOR_CONFIG 0xd5 +#define UCD9000_NUM_PAGES 0xd6 +#define UCD9000_FAN_CONFIG_INDEX 0xe7 +#define UCD9000_FAN_CONFIG 0xe8 +#define UCD9000_DEVICE_ID 0xfd + +#define UCD9000_MON_TYPE(x) (((x) >> 5) & 0x07) +#define UCD9000_MON_PAGE(x) ((x) & 0x0f) + +#define UCD9000_MON_VOLTAGE 1 +#define UCD9000_MON_TEMPERATURE 2 +#define UCD9000_MON_CURRENT 3 +#define UCD9000_MON_VOLTAGE_HW 4 + +#define UCD9000_NUM_FAN 4 + +struct ucd9000_data { + u8 fan_data[UCD9000_NUM_FAN][I2C_SMBUS_BLOCK_MAX]; + struct pmbus_driver_info info; +}; +#define to_ucd9000_data(_info) container_of(_info, struct ucd9000_data, info) + +static int ucd9000_get_fan_config(struct i2c_client *client, int fan) +{ + int fan_config = 0; + struct ucd9000_data *data + = to_ucd9000_data(pmbus_get_driver_info(client)); + + if (data->fan_data[fan][3] & 1) + fan_config |= PB_FAN_2_INSTALLED; /* Use lower bit position */ + + /* Pulses/revolution */ + fan_config |= (data->fan_data[fan][3] & 0x06) >> 1; + + return fan_config; +} + +static int ucd9000_read_byte_data(struct i2c_client *client, int page, int reg) +{ + int ret = 0; + int fan_config; + + switch (reg) { + case PMBUS_FAN_CONFIG_12: + if (page > 0) + return -ENXIO; + + ret = ucd9000_get_fan_config(client, 0); + if (ret < 0) + return ret; + fan_config = ret << 4; + ret = ucd9000_get_fan_config(client, 1); + if (ret < 0) + return ret; + fan_config |= ret; + ret = fan_config; + break; + case PMBUS_FAN_CONFIG_34: + if (page > 0) + return -ENXIO; + + ret = ucd9000_get_fan_config(client, 2); + if (ret < 0) + return ret; + fan_config = ret << 4; + ret = ucd9000_get_fan_config(client, 3); + if (ret < 0) + return ret; + fan_config |= ret; + ret = fan_config; + break; + default: + ret = -ENODATA; + break; + } + return ret; +} + +static const struct i2c_device_id ucd9000_id[] = { + {"ucd9000", ucd9000}, + {"ucd90120", ucd90120}, + {"ucd90124", ucd90124}, + {"ucd90160", ucd90160}, + {"ucd9090", ucd9090}, + {"ucd90910", ucd90910}, + {} +}; +MODULE_DEVICE_TABLE(i2c, ucd9000_id); + +static int ucd9000_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1]; + struct ucd9000_data *data; + struct pmbus_driver_info *info; + const struct i2c_device_id *mid; + int i, ret; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_BLOCK_DATA)) + return -ENODEV; + + ret = i2c_smbus_read_block_data(client, UCD9000_DEVICE_ID, + block_buffer); + if (ret < 0) { + dev_err(&client->dev, "Failed to read device ID\n"); + return ret; + } + block_buffer[ret] = '\0'; + dev_info(&client->dev, "Device ID %s\n", block_buffer); + + for (mid = ucd9000_id; mid->name[0]; mid++) { + if (!strncasecmp(mid->name, block_buffer, strlen(mid->name))) + break; + } + if (!mid->name[0]) { + dev_err(&client->dev, "Unsupported device\n"); + return -ENODEV; + } + + if (id->driver_data != ucd9000 && id->driver_data != mid->driver_data) + dev_notice(&client->dev, + "Device mismatch: Configured %s, detected %s\n", + id->name, mid->name); + + data = devm_kzalloc(&client->dev, sizeof(struct ucd9000_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; + info = &data->info; + + ret = i2c_smbus_read_byte_data(client, UCD9000_NUM_PAGES); + if (ret < 0) { + dev_err(&client->dev, + "Failed to read number of active pages\n"); + return ret; + } + info->pages = ret; + if (!info->pages) { + dev_err(&client->dev, "No pages configured\n"); + return -ENODEV; + } + + /* The internal temperature sensor is always active */ + info->func[0] = PMBUS_HAVE_TEMP; + + /* Everything else is configurable */ + ret = i2c_smbus_read_block_data(client, UCD9000_MONITOR_CONFIG, + block_buffer); + if (ret <= 0) { + dev_err(&client->dev, "Failed to read configuration data\n"); + return -ENODEV; + } + for (i = 0; i < ret; i++) { + int page = UCD9000_MON_PAGE(block_buffer[i]); + + if (page >= info->pages) + continue; + + switch (UCD9000_MON_TYPE(block_buffer[i])) { + case UCD9000_MON_VOLTAGE: + case UCD9000_MON_VOLTAGE_HW: + info->func[page] |= PMBUS_HAVE_VOUT + | PMBUS_HAVE_STATUS_VOUT; + break; + case UCD9000_MON_TEMPERATURE: + info->func[page] |= PMBUS_HAVE_TEMP2 + | PMBUS_HAVE_STATUS_TEMP; + break; + case UCD9000_MON_CURRENT: + info->func[page] |= PMBUS_HAVE_IOUT + | PMBUS_HAVE_STATUS_IOUT; + break; + default: + break; + } + } + + /* Fan configuration */ + if (mid->driver_data == ucd90124) { + for (i = 0; i < UCD9000_NUM_FAN; i++) { + i2c_smbus_write_byte_data(client, + UCD9000_FAN_CONFIG_INDEX, i); + ret = i2c_smbus_read_block_data(client, + UCD9000_FAN_CONFIG, + data->fan_data[i]); + if (ret < 0) + return ret; + } + i2c_smbus_write_byte_data(client, UCD9000_FAN_CONFIG_INDEX, 0); + + info->read_byte_data = ucd9000_read_byte_data; + info->func[0] |= PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12 + | PMBUS_HAVE_FAN34 | PMBUS_HAVE_STATUS_FAN34; + } + + return pmbus_do_probe(client, mid, info); +} + +/* This is the driver that will be inserted */ +static struct i2c_driver ucd9000_driver = { + .driver = { + .name = "ucd9000", + }, + .probe = ucd9000_probe, + .remove = pmbus_do_remove, + .id_table = ucd9000_id, +}; + +module_i2c_driver(ucd9000_driver); + +MODULE_AUTHOR("Guenter Roeck"); +MODULE_DESCRIPTION("PMBus driver for TI UCD90xxx"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/setup.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/setup.py new file mode 100644 index 000000000000..8b45987a54ec --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='sonic_platform', + version='1.0', + description='Module to initialize Ivnetec D6356 platforms', + + packages=['sonic_platform'], +) + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/__init__.py new file mode 100644 index 000000000000..4bfefa0fb636 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/__init__.py @@ -0,0 +1,3 @@ +__all__ = ["platform", "chassis"] +from sonic_platform import * + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py new file mode 100644 index 000000000000..761d21cf46ce --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python +# +# Name: chassis.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.eeprom import Eeprom + from sonic_platform.fan import Fan + from sonic_platform.psu import Psu + from sonic_platform.sfp import Sfp + from sonic_platform.qsfp import QSfp + from sonic_platform.thermal import Thermal +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Chassis(ChassisBase): + + def __init__(self): + ChassisBase.__init__(self) + self.__num_of_fans = 8 + self.__num_of_psus = 2 + self.__num_of_sfps = 56 + self.__start_of_qsfp = 48 + self.__num_of_thermals = 5 + + # Initialize EEPROM + self._eeprom = Eeprom() + + # Initialize FAN + for index in range(1, self.__num_of_fans + 1): + fan = Fan(index, False, 0) + self._fan_list.append(fan) + + # Initialize PSU + for index in range(1, self.__num_of_psus + 1): + psu = Psu(index) + self._psu_list.append(psu) + + # Initialize SFP + for index in range(0, self.__num_of_sfps): + if index < self.__start_of_qsfp: + sfp = Sfp(index) + else: + sfp = QSfp(index) + self._sfp_list.append(sfp) + + # Initialize THERMAL + for index in range(0, self.__num_of_thermals): + thermal = Thermal(index) + self._thermal_list.append(thermal) + + +############################################## +# Device methods +############################################## + + 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 + Returns: + string: Serial number of chassis + """ + return self._eeprom.serial_number_str() + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + +############################################## +# Chassis methods +############################################## + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.base_mac_address() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.serial_number_str() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + Ex. { '0x21':'AG9064', '0x22':'V1.0', '0x23':'AG9064-0109867821', + '0x24':'001c0f000fcd0a', '0x25':'02/03/2018 16:22:00', + '0x26':'01', '0x27':'REV01', '0x28':'AG9064-C2358-16G'} + """ + return self._eeprom.system_eeprom_info() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + raise NotImplementedError diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/eeprom.py new file mode 100644 index 000000000000..5840246fddc2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/eeprom.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# +# Name: eeprom.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + 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 = "/sys/class/i2c-adapter/i2c-2/2-0055/eeprom" + super(Eeprom, self).__init__(self.__eeprom_path, 0, '', True) + self.__eeprom_tlv_dict = dict() + try: + self.__eeprom_data = self.read_eeprom() + except: + self.__eeprom_data = "N/A" + raise RuntimeError("Eeprom is not Programmed") + else: + eeprom = self.__eeprom_data + + if not self.is_valid_tlvinfo_header(eeprom): + return + + total_length = (ord(eeprom[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 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-inventec/d6356/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/fan.py new file mode 100644 index 000000000000..b9423e43dcb1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/fan.py @@ -0,0 +1,204 @@ +#!/usr/bin/env python +# +# Name: fan.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import math + import os + from sonic_platform_base.fan_base import FanBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Fan(FanBase): + + def __init__(self, index, is_psu_fan=False, psu_index=0): + self.__index = index + self.__is_psu_fan = is_psu_fan + + if self.__is_psu_fan: + self.__psu_index = psu_index + self.__presence_attr = "/sys/class/hwmon/hwmon{}/fan{}_input".format((self.__psu_index + 6), self.__index) + self.__speed_rpm_attr = "/sys/class/hwmon/hwmon{}/fan{}_input".format((self.__psu_index + 6), self.__index) + self.__pwm_attr = None + else: + self.__presence_attr = "/sys/class/hwmon/hwmon2/device/fan{}_input".format(self.__index) + self.__speed_rpm_attr = "/sys/class/hwmon/hwmon2/device/fan{}_input".format(self.__index) + self.__pwm_attr = "/sys/class/hwmon/hwmon2/device/pwm{}".format((self.__index + 1)/2) + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + if self.__is_psu_fan: + return "PSU{}-FAN{}".format(self.__psu_index, self.__index) + else: + return "FAN{}".format(self.__index) + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + presence = False + attr_path = self.__presence_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) != 0): + presence = True + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + return "N/A" + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + return "N/A" + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() + +############################################## +# FAN methods +############################################## + + def get_direction(self): + """ + Retrieves the direction of fan + + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + raise NotImplementedError + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + speed = 0 + + if self.__is_psu_fan: + attr_path = self.__speed_rpm_attr + else: + attr_path = self.__pwm_attr + + if self.get_presence() and None != attr_path: + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if self.__is_psu_fan: + fan_speed_rpm = int(attr_rv) + speed = math.ceil(float(fan_speed_rpm) * 100 / 11000) + else: + pwm = int(attr_rv) + speed = math.ceil(float(pwm * 100 / 255)) + + return speed + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + raise NotImplementedError + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + raise NotImplementedError + + def set_speed(self, speed): + """ + Sets the fan speed + + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + + Returns: + A boolean, True if speed is set successfully, False if not + """ + raise NotImplementedError + + def set_status_led(self, color): + """ + Sets the state of the fan module status LED + + Args: + color: A string representing the color with which to set the + fan module status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + raise NotImplementedError + + def get_status_led(self): + """ + Gets the state of the fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + if self.get_status() and self.get_speed() > 0: + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/platform.py new file mode 100644 index 000000000000..7d6bda4502de --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/platform.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# +# Name: platform.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/psu.py new file mode 100644 index 000000000000..3798ef9e5b80 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/psu.py @@ -0,0 +1,202 @@ +#!/usr/bin/env python +# +# Name: psu.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + from sonic_platform_base.psu_base import PsuBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Psu(PsuBase): + + def __init__(self, index): + self.__num_of_fans = 1 + self.__index = index + self.__psu_presence_attr = "/sys/class/hwmon/hwmon2/device/psu{}".format(self.__index) + self.__psu_power_in_attr = "/sys/class/hwmon/hwmon{}/power1_input".format(self.__index + 6) + self.__psu_power_out_attr = "/sys/class/hwmon/hwmon{}/power2_input".format(self.__index + 6) + self.__psu_voltage_out_attr = "/sys/class/hwmon/hwmon{}/in2_input".format(self.__index + 6) + self.__psu_current_out_attr = "/sys/class/hwmon/hwmon{}/curr2_input".format(self.__index + 6) + + # Overriding _fan_list class variable defined in PsuBase, to make it unique per Psu object + self._fan_list = [] + + # Initialize FAN + for x in range(1, self.__num_of_fans + 1): + fan = Fan(x, True, self.__index) + self._fan_list.append(fan) + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return "PSU{}".format(self.__index) + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + presence = False + attr_normal = "1:normal" + attr_path = self.__psu_presence_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (attr_rv == attr_normal): + presence = True + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + return "N/A" + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + return "N/A" + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + status = False + attr_path = self.__psu_power_in_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) != 0): + status = True + + return status + +############################################## +# PSU methods +############################################## + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + voltage_out = 0.0 + attr_path = self.__psu_voltage_out_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + voltage_out = float(attr_rv) / 1000 + + return voltage_out + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, the electric current in amperes, e.g 15.4 + """ + current_out = 0.0 + attr_path = self.__psu_current_out_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + current_out = float(attr_rv) / 1000 + + return current_out + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, e.g. 302.6 + """ + power_out = 0.0 + attr_path = self.__psu_power_out_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + power_out = float(attr_rv) / 1000000 + + return power_out + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + + Returns: + A boolean, True if PSU has stablized its output voltages and passed all + its internal self-tests, False if not. + """ + return self.get_status() + + def set_status_led(self, color): + """ + Sets the state of the PSU status LED + + Args: + color: A string representing the color with which to set the + PSU status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + raise NotImplementedError + + def get_status_led(self): + """ + Gets the state of the PSU status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + if self.get_powergood_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/qsfp.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/qsfp.py new file mode 100644 index 000000000000..f3f873be08ce --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/qsfp.py @@ -0,0 +1,925 @@ +#!/usr/bin/env python +# +# Name: qsfp.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + import sys + import time + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +INFO_OFFSET = 128 +DOM_OFFSET = 0 + +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_QSFP = 20 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 + +# Offset for values in QSFP eeprom +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_CONTROL_OFFSET = 86 +QSFP_CONTROL_WIDTH = 8 +QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 +QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 +QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_POWEROVERRIDE_OFFSET = 93 +QSFP_POWEROVERRIDE_WIDTH = 1 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNEL_THRESHOLD_OFFSET = 176 +QSFP_CHANNEL_THRESHOLD_WIDTH = 16 + +class QSfp(SfpBase): + + def __init__(self, index): + self.__index = index + + self.__platform = "x86_64-inventec_d6356-r0" + self.__hwsku = "INVENTEC-D6356" + + self.__port_to_i2c_mapping = { + 0:22, 1:23, 2:24, 3:25, 4:26, 5:27, 6:28, 7:29, + 8:30, 9:31, 10:32, 11:33, 12:34, 13:35, 14:36, 15:37, + 16:38, 17:39, 18:40, 19:41, 20:42, 21:43, 22:44, 23:45, + 24:46, 25:47, 26:48, 27:49, 28:50, 29:51, 30:52, 31:53, + 32:54, 33:55, 34:56, 35:57, 36:58, 37:59, 38:60, 39:61, + 40:62, 41:63, 42:64, 43:65, 44:66, 45:67, 46:68, 47:69, + 48:14, 49:15, 50:16, 51:17, 52:18, 53:19, 54:20, 55:21 + } + self.__port_end = len(self.__port_to_i2c_mapping) - 1; + + self.__presence_attr = None + self.__eeprom_path = None + if self.__index in range(0, self.__port_end + 1): + self.__presence_attr = "/sys/class/swps/port{}/present".format(self.__index) + self.__lpmode_attr = "/sys/class/swps/port{}/lpmod".format(self.__index) + self.__reset_attr = "/sys/class/swps/port{}/reset".format(self.__index) + self.__eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom".format(self.__port_to_i2c_mapping[self.__index]) + + #print(self.__eeprom_path) + + SfpBase.__init__(self) + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + def __is_host(self): + return os.system("docker > /dev/null 2>&1") == 0 + + def __get_path_to_port_config_file(self): + host_platform_root_path = '/usr/share/sonic/device' + docker_hwsku_path = '/usr/share/sonic/hwsku' + + host_platform_path = "/".join([host_platform_root_path, self.__platform]) + hwsku_path = "/".join([host_platform_path, self.__hwsku]) if self.__is_host() else docker_hwsku_path + + return "/".join([hwsku_path, "port_config.ini"]) + + def __read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + eeprom_raw = [] + + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + sysfs_eeprom_path = self.__eeprom_path + try: + sysfsfile_eeprom = open(sysfs_eeprom_path, mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + raw_len = len(raw) + for n in range(0, raw_len): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except: + pass + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + + return eeprom_raw + + def __convert_string_to_num(self, value_str): + if "-inf" in value_str: + return 'N/A' + elif "Unknown" in value_str: + return 'N/A' + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return 'N/A' + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + name = None + + sfputil_helper = SfpUtilHelper() + sfputil_helper.read_porttab_mappings(self.__get_path_to_port_config_file()) + name = sfputil_helper.logical[self.__index] or "Unknown" + return name + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + presence = False + attr_path = self.__presence_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) == 0): + presence = True + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + transceiver_info_dict = self.get_transceiver_info() + return transceiver_info_dict.get("modelname", "N/A") + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + transceiver_info_dict = self.get_transceiver_info() + return transceiver_info_dict.get("serialnum", "N/A") + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() and not self.get_reset_status() + +############################################## +# SFP methods +############################################## + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardwarerev |1*255VCHAR |hardware version of SFP + serialnum |1*255VCHAR |serial number of the SFP + manufacturename |1*255VCHAR |SFP vendor name + modelname |1*255VCHAR |SFP model name + Connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + mominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + ======================================================================== + """ + + transceiver_info_dict_keys = ['type', 'hardwarerev', + 'serialnum', 'manufacturename', + 'modelname', 'Connector', + 'encoding', 'ext_identifier', + 'ext_rateselect_compliance', 'cable_type', + 'cable_length', 'nominal_bit_rate', + 'specification_compliance', 'vendor_date', + 'vendor_oui'] + + qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', 'Length Cable Assembly(m)') + + qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', 'Fibre Channel transmission media', + 'Fibre Channel Speed') + + sfpi_obj = sff8436InterfaceId() + if not self.get_presence() or not sfpi_obj: + return {} + + offset = INFO_OFFSET + + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes((offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_QSFP) + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw, 0) + + sfp_vendor_name_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0) + + sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) + + sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes((offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_QSFP) + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) + + sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0) + + sfp_vendor_date_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0) + + transceiver_info_dict = dict.fromkeys(transceiver_info_dict_keys, 'N/A') + + if sfp_interface_bulk_data: + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + + transceiver_info_dict['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']) + + compliance_code_dict = dict() + for key in qsfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + + return transceiver_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + transceiver_dom_info_dict_keys = ['rx_los', 'tx_fault', + 'reset_status', 'power_lpmode', + 'tx_disable', 'tx_disable_channel', + 'temperature', 'voltage', + 'rx1power', 'rx2power', + 'rx3power', 'rx4power', + 'tx1bias', 'tx2bias', + 'tx3bias', 'tx4bias', + 'tx1power', 'tx2power', + 'tx3power', 'tx4power'] + + sfpd_obj = sff8436Dom() + sfpi_obj = sff8436InterfaceId() + + if not self.get_presence() or not sfpi_obj or not sfpd_obj: + return {} + + transceiver_dom_info_dict = dict.fromkeys(transceiver_dom_info_dict_keys, 'N/A') + offset = DOM_OFFSET + offset_xcvr = INFO_OFFSET + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes((offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0) + else: + return None + + dom_temperature_raw = self.__read_eeprom_specific_bytes((offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + + dom_voltage_raw = self.__read_eeprom_specific_bytes((offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes((offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + dom_channel_monitor_data = {} + dom_channel_monitor_raw = None + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + + else: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] + transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] + transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] + transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] + + if dom_channel_monitor_raw: + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + + for key in transceiver_dom_info_dict: + transceiver_dom_info_dict[key] = self.__convert_string_to_num(transceiver_dom_info_dict[key]) + + transceiver_dom_info_dict['rx_los'] = self.get_rx_los() + transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['tx_disable'] = self.get_tx_disable() + transceiver_dom_info_dict['tx_disable_channel'] = self.get_tx_disable_channel() + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + + + return transceiver_dom_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + transceiver_dom_threshold_info_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + + sfpd_obj = sff8436Dom() + if not self.get_presence() or not sfpd_obj: + return {} + + transceiver_dom_threshold_dict = dict.fromkeys(transceiver_dom_threshold_info_dict_keys, 'N/A') + offset = DOM_OFFSET + + dom_module_threshold_raw = self.__read_eeprom_specific_bytes((offset + QSFP_MODULE_THRESHOLD_OFFSET), QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw: + module_threshold_values = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + module_threshold_data = module_threshold_values.get('data') + if module_threshold_data: + transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['TempHighAlarm']['value'] + transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['TempLowAlarm']['value'] + transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['TempHighWarning']['value'] + transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['TempLowWarning']['value'] + transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['VccHighAlarm']['value'] + transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['VccLowAlarm']['value'] + transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['VccHighWarning']['value'] + transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['VccLowWarning']['value'] + + dom_channel_thres_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNEL_THRESHOLD_OFFSET), QSFP_CHANNEL_THRESHOLD_WIDTH) + channel_threshold_values = sfpd_obj.parse_channel_threshold_values(dom_channel_thres_raw, 0) + channel_threshold_data = channel_threshold_values.get('data') + if channel_threshold_data: + transceiver_dom_threshold_dict['rxpowerhighalarm'] = channel_threshold_data['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerlowalarm'] = channel_threshold_data['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_dict['rxpowerhighwarning'] = channel_threshold_data['RxPowerHighWarning']['value'] + transceiver_dom_threshold_dict['rxpowerlowwarning'] = channel_threshold_data['RxPowerLowWarning']['value'] + transceiver_dom_threshold_dict['txpowerhighalarm'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerlowalarm'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerhighwarning'] = "0.0dBm" + transceiver_dom_threshold_dict['txpowerlowwarning'] = "0.0dBm" + transceiver_dom_threshold_dict['txbiashighalarm'] = channel_threshold_data['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_dict['txbiaslowalarm'] = channel_threshold_data['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_dict['txbiashighwarning'] = channel_threshold_data['TxBiasHighWarning']['value'] + transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value'] + + for key in transceiver_dom_threshold_dict: + transceiver_dom_threshold_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_dict[key]) + + return transceiver_dom_threshold_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + + Returns: + A Boolean, True if reset enabled, False if disabled + """ + reset_status = False + attr_path = self.__reset_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) == 0): + reset_status = True + + return reset_status + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + rx_los = 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 dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x01 != 0) + rx_los_list.append(rx_los_data & 0x02 != 0) + rx_los_list.append(rx_los_data & 0x04 != 0) + rx_los_list.append(rx_los_data & 0x08 != 0) + rx_los = rx_los_list[0] and rx_los_list[1] and rx_los_list[2] and rx_los_list[3] + return rx_los + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + tx_fault = False + tx_fault_list = [] + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(QSFP_CHANNL_TX_FAULT_STATUS_OFFSET, QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x01 != 0) + tx_fault_list.append(tx_fault_data & 0x02 != 0) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + tx_fault_list.append(tx_fault_data & 0x08 != 0) + tx_fault = tx_fault_list[0] and tx_fault_list[1] and tx_fault_list[2] and tx_fault_list[3] + + return tx_fault + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + + Returns: + A Boolean, True if tx_disable is enabled, False if disabled + """ + tx_disable = False + tx_disable_list = [] + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return tx_disable + + dom_control_raw = self.__read_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + tx_disable_list.append('On' == dom_control_data['data']['TX1Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX2Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX3Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX4Disable']['value']) + tx_disable = tx_disable_list[0] and tx_disable_list[1] and tx_disable_list[2] and tx_disable_list[3] + + return tx_disable + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + tx_disable_channel = 0 + tx_disable_list = [] + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return tx_disable_channel + + dom_control_raw = self.__read_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + tx_disable_list.append('On' == dom_control_data['data']['TX1Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX2Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX3Disable']['value']) + tx_disable_list.append('On' == dom_control_data['data']['TX4Disable']['value']) + + for i in range(len(tx_disable_list)): + if tx_disable_list[i]: + tx_disable_channel |= 1 << i + + return tx_disable_channel + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + lpmode = False + attr_path = self.__lpmode_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) == 1): + lpmode = True + + return lpmode + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + power_override = False + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return power_override + + dom_control_raw = self.__read_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + power_override = ('On' == dom_control_data['data']['PowerOverride']['value']) + + return power_override + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + + Returns: + An integer number of current temperature in Celsius + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + return transceiver_dom_info_dict.get("temperature", "N/A") + + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + + Returns: + An integer number of supply voltage in mV + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + return transceiver_dom_info_dict.get("voltage", "N/A") + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + tx1_bs = transceiver_dom_info_dict.get("tx1bias", "N/A") + tx2_bs = transceiver_dom_info_dict.get("tx2bias", "N/A") + tx3_bs = transceiver_dom_info_dict.get("tx3bias", "N/A") + tx4_bs = transceiver_dom_info_dict.get("tx4bias", "N/A") + return [tx1_bs, tx2_bs, tx3_bs, tx4_bs] if transceiver_dom_info_dict else [] + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + rx1_pw = transceiver_dom_info_dict.get("rx1power", "N/A") + rx2_pw = transceiver_dom_info_dict.get("rx2power", "N/A") + rx3_pw = transceiver_dom_info_dict.get("rx3power", "N/A") + rx4_pw = transceiver_dom_info_dict.get("rx4power", "N/A") + return [rx1_pw, rx2_pw, rx3_pw, rx4_pw] if transceiver_dom_info_dict else [] + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + tx1_pw = transceiver_dom_info_dict.get("tx1power", "N/A") + tx2_pw = transceiver_dom_info_dict.get("tx2power", "N/A") + tx3_pw = transceiver_dom_info_dict.get("tx3power", "N/A") + tx4_pw = transceiver_dom_info_dict.get("tx4power", "N/A") + return [tx1_pw, tx2_pw, tx3_pw, tx4_pw] + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + + Returns: + A boolean, True if successful, False if not + """ + + try: + reg_file = open(self.__reset_attr, "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = 0 + reg_file.write(hex(reg_value)) + reg_file.close() + + # Sleep 2 second to allow it to settle + time.sleep(2) + + try: + reg_file = open(self.__reset_attr, "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = 1 + reg_file.write(hex(reg_value)) + reg_file.close() + + return True + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + sysfs_eeprom_path = self.__eeprom_path + 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(sysfs_eeprom_path, "r+b") + sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + + Returns: + A boolean, True if successful, False if not + """ + sysfs_eeprom_path = self.__eeprom_path + 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(sysfs_eeprom_path, "r+b") + sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + try: + reg_file = open(self.__lpmode_attr, "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = int(reg_file.readline().rstrip()) + + if lpmode is True: + reg_value = 1 + else: + reg_value = 0 + + reg_file.write(hex(reg_value)) + reg_file.close() + + return True + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + sysfs_eeprom_path = self.__eeprom_path + sysfsfile_eeprom = None + try: + power_override_bit = 0 + if power_override: + power_override_bit |= 1 << 0 + + power_set_bit = 0 + if power_set: + power_set_bit |= 1 << 1 + + buffer = create_string_buffer(1) + buffer[0] = chr(power_override_bit | power_set_bit) + # Write to eeprom + sysfsfile_eeprom = open(sysfs_eeprom_path, "r+b") + sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if sysfsfile_eeprom is not None: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/sfp.py new file mode 100644 index 000000000000..d8d88a2df2b0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/sfp.py @@ -0,0 +1,739 @@ +#!/usr/bin/env python +# +# Name: sfp.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + import sys + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sffbase + from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +INFO_OFFSET = 0 +DOM_OFFSET = 256 + +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 + +# Offset for values in SFP eeprom +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 40 +SFP_CHANNL_THRESHOLD_OFFSET = 112 +SFP_CHANNL_THRESHOLD_WIDTH = 2 +SFP_STATUS_CONTROL_OFFSET = 110 +SFP_STATUS_CONTROL_WIDTH = 1 +SFP_TX_DISABLE_HARD_BIT = 7 +SFP_TX_DISABLE_SOFT_BIT = 6 + +class Sfp(SfpBase): + + def __init__(self, index): + self.__index = index + + self.__platform = "x86_64-inventec_d6356-r0" + self.__hwsku = "INVENTEC-D6356" + + self.__port_to_i2c_mapping = { + 0:22, 1:23, 2:24, 3:25, 4:26, 5:27, 6:28, 7:29, + 8:30, 9:31, 10:32, 11:33, 12:34, 13:35, 14:36, 15:37, + 16:38, 17:39, 18:40, 19:41, 20:42, 21:43, 22:44, 23:45, + 24:46, 25:47, 26:48, 27:49, 28:50, 29:51, 30:52, 31:53, + 32:54, 33:55, 34:56, 35:57, 36:58, 37:59, 38:60, 39:61, + 40:62, 41:63, 42:64, 43:65, 44:66, 45:67, 46:68, 47:69, + 48:14, 49:15, 50:16, 51:17, 52:18, 53:19, 54:20, 55:21 + } + self.__port_end = len(self.__port_to_i2c_mapping) - 1; + + self.__presence_attr = None + self.__eeprom_path = None + if self.__index in range(0, self.__port_end + 1): + self.__presence_attr = "/sys/class/swps/port{}/present".format(self.__index) + self.__eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom".format(self.__port_to_i2c_mapping[self.__index]) + + SfpBase.__init__(self) + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + def __is_host(self): + return os.system("docker > /dev/null 2>&1") == 0 + + def __get_path_to_port_config_file(self): + host_platform_root_path = '/usr/share/sonic/device' + docker_hwsku_path = '/usr/share/sonic/hwsku' + + host_platform_path = "/".join([host_platform_root_path, self.__platform]) + hwsku_path = "/".join([host_platform_path, self.__hwsku]) if self.__is_host() else docker_hwsku_path + + return "/".join([hwsku_path, "port_config.ini"]) + + def __read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + eeprom_raw = [] + + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + sysfs_eeprom_path = self.__eeprom_path + try: + sysfsfile_eeprom = open(sysfs_eeprom_path, mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + raw_len = len(raw) + for n in range(0, raw_len): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except: + pass + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + + return eeprom_raw + + def __convert_string_to_num(self, value_str): + if "-inf" in value_str: + return 'N/A' + elif "Unknown" in value_str: + return 'N/A' + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return 'N/A' + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + name = None + + sfputil_helper = SfpUtilHelper() + sfputil_helper.read_porttab_mappings(self.__get_path_to_port_config_file()) + name = sfputil_helper.logical[self.__index] or "Unknown" + return name + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + presence = False + attr_path = self.__presence_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) == 0): + presence = True + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + transceiver_info_dict = self.get_transceiver_info() + return transceiver_info_dict.get("modelname", "N/A") + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + transceiver_info_dict = self.get_transceiver_info() + return transceiver_info_dict.get("serialnum", "N/A") + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() and not self.get_reset_status() + +############################################## +# SFP methods +############################################## + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardwarerev |1*255VCHAR |hardware version of SFP + serialnum |1*255VCHAR |serial number of the SFP + manufacturename |1*255VCHAR |SFP vendor name + modelname |1*255VCHAR |SFP model name + Connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + mominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + ======================================================================== + """ + + transceiver_info_dict_keys = ['type', 'hardwarerev', + 'serialnum', 'manufacturename', + 'modelname', 'Connector', + 'encoding', 'ext_identifier', + 'ext_rateselect_compliance', 'cable_type', + 'cable_length', 'nominal_bit_rate', + 'specification_compliance', 'vendor_date', + 'vendor_oui'] + + 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') + + sfpi_obj = sff8472InterfaceId() + 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_SFP) + 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_SFP) + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) + + sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0) + + sfp_vendor_date_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0) + + transceiver_info_dict = dict.fromkeys(transceiver_info_dict_keys, 'N/A') + + if sfp_interface_bulk_data: + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + + transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' + transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' + + transceiver_info_dict['cable_type'] = "Unknown" + transceiver_info_dict['cable_length'] = "Unknown" + for key in sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + + compliance_code_dict = dict() + 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) + + return transceiver_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + transceiver_dom_info_dict_keys = ['rx_los', 'tx_fault', + 'reset_status', 'power_lpmode', + 'tx_disable', 'tx_disable_channel', + 'temperature', 'voltage', + 'rx1power', 'rx2power', + 'rx3power', 'rx4power', + 'tx1bias', 'tx2bias', + 'tx3bias', 'tx4bias', + 'tx1power', 'tx2power', + 'tx3power', 'tx4power'] + + sfpd_obj = sff8472Dom() + if not self.get_presence() or not sfpd_obj: + return {} + + eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET) + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + cal_type = sfpi_obj.get_calibration_type() + sfpd_obj._calibration_type = cal_type + + offset = DOM_OFFSET + transceiver_dom_info_dict = dict.fromkeys(transceiver_dom_info_dict_keys, 'N/A') + + dom_temperature_raw = self.__read_eeprom_specific_bytes((offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + + dom_voltage_raw = self.__read_eeprom_specific_bytes((offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_voltage_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + transceiver_dom_info_dict['tx1power'] = dom_voltage_data['data']['TXPower']['value'] + transceiver_dom_info_dict['rx1power'] = dom_voltage_data['data']['RXPower']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_voltage_data['data']['TXBias']['value'] + + for key in transceiver_dom_info_dict: + transceiver_dom_info_dict[key] = self.__convert_string_to_num(transceiver_dom_info_dict[key]) + + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['rx_los'] = self.get_rx_los() + transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() + transceiver_dom_info_dict['tx_disable'] = self.get_tx_disable() + transceiver_dom_info_dict['tx_disable_channel'] = self.get_tx_disable_channel() + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + + return transceiver_dom_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + transceiver_dom_threshold_info_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + + sfpd_obj = sff8472Dom() + + if not self.get_presence() and not sfpd_obj: + return {} + + eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET) + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + cal_type = sfpi_obj.get_calibration_type() + sfpd_obj._calibration_type = cal_type + + offset = DOM_OFFSET + transceiver_dom_threshold_info_dict = dict.fromkeys(transceiver_dom_threshold_info_dict_keys, 'N/A') + dom_module_threshold_raw = self.__read_eeprom_specific_bytes((offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(dom_module_threshold_raw, 0) + + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + for key in transceiver_dom_threshold_info_dict: + transceiver_dom_threshold_info_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_info_dict[key]) + + return transceiver_dom_threshold_info_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + + Returns: + A Boolean, True if reset enabled, False if disabled + """ + # SFP doesn't support this feature + return False + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + rx_los = False + status_control_raw = self.__read_eeprom_specific_bytes(SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + rx_los = (sffbase().test_bit(data, 1) != 0) + + return rx_los + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + tx_fault = False + status_control_raw = self.__read_eeprom_specific_bytes(SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + tx_fault = (sffbase().test_bit(data, 2) != 0) + + return tx_fault + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + + Returns: + A Boolean, True if tx_disable is enabled, False if disabled + """ + tx_disable = False + tx_fault = False + status_control_raw = self.__read_eeprom_specific_bytes(SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + tx_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 + + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + # SFP doesn't support this feature + return 0 + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + # SFP doesn't support this feature + return False + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + # SFP doesn't support this feature + return False + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + + Returns: + An integer number of current temperature in Celsius + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + return transceiver_dom_info_dict.get("temperature", "N/A") + + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + + Returns: + An integer number of supply voltage in mV + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + return transceiver_dom_info_dict.get("voltage", "N/A") + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + tx1_bs = transceiver_dom_info_dict.get("tx1bias", "N/A") + return [tx1_bs, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else [] + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + rx1_pw = transceiver_dom_info_dict.get("rx1power", "N/A") + return [rx1_pw, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else [] + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + transceiver_dom_info_dict = self.get_transceiver_bulk_status() + tx1_pw = transceiver_dom_info_dict.get("tx1power", "N/A") + return [tx1_pw, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else [] + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + + Returns: + A boolean, True if successful, False if not + """ + # SFP doesn't support this feature + return False + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + sysfs_eeprom_path = self.__eeprom_path + status_control_raw = self.__read_eeprom_specific_bytes(SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw is not None: + # Set bit 6 for Soft TX Disable Select + # 01000000 = 64 and 10111111 = 191 + tx_disable_bit = 64 if tx_disable else 191 + status_control = int(status_control_raw[0], 16) + tx_disable_ctl = (status_control | tx_disable_bit) if tx_disable else (status_control & tx_disable_bit) + try: + sysfsfile_eeprom = open(sysfs_eeprom_path, mode="r+b", buffering=0) + buffer = create_string_buffer(1) + buffer[0] = chr(tx_disable_ctl) + # Write to eeprom + sysfsfile_eeprom.seek(SFP_STATUS_CONTROL_OFFSET) + sysfsfile_eeprom.write(buffer[0]) + except: + #print("Error: unable to open file: %s" % str(e)) + return False + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + time.sleep(0.01) + return True + return False + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + + Returns: + A boolean, True if successful, False if not + """ + # SFP doesn't support this feature + return False + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + # SFP doesn't support this feature + return False + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + # SFP doesn't support this feature + return False + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/thermal.py new file mode 100644 index 000000000000..eba7ba728de9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/thermal.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python +# +# Name: thermal.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + from sonic_platform_base.thermal_base import ThermalBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Thermal(ThermalBase): + + def __init__(self, index): + self.__index = index + + #thermal name list + self.__thermal_name_list = [ "PCH Temperature Sensor", + "CPU Board Temperature Sensor", + "FrontSide Temperature Sensor", + "NearASIC Temperature Sensor", + "RearSide Temperature Sensor" ] + + offset = 0 + if 0 != self.__index: + offset = 2 + self.__presence_attr = "/sys/class/hwmon/hwmon{}/temp1_input".format(self.__index + offset) + self.__temperature_attr = "/sys/class/hwmon/hwmon{}/temp1_input".format(self.__index + offset) + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return self.__thermal_name_list[self.__index] or "Unknown" + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + presence = False + attr_path = self.__presence_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) != 0): + presence = True + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + return "N/A" + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + return "N/A" + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() + +############################################## +# THERMAL methods +############################################## + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + temperature = 0.0 + attr_path = self.__temperature_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + temperature = float(attr_rv) / 1000 + + return temperature + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + + Returns: + A float number, the high threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + raise NotImplementedError + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of thermal + + Returns: + A float number, the low threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + raise NotImplementedError + + def set_high_threshold(self, temperature): + """ + Sets the high threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + + Returns: + A boolean, True if threshold is set successfully, False if not + """ + raise NotImplementedError + + def set_low_threshold(self, temperature): + """ + Sets the low threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + + Returns: + A boolean, True if threshold is set successfully, False if not + """ + raise NotImplementedError + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/utils/inventec_d6356_util.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/utils/inventec_d6356_util.py new file mode 100755 index 000000000000..890973cb8356 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/utils/inventec_d6356_util.py @@ -0,0 +1,248 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Inventec, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +from collections import namedtuple + +DEBUG = False +args = [] +FORCE = 0 +i2c_prefix = '/sys/bus/i2c/devices/' + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV: ', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + install() + elif arg == 'clean': + uninstall() + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_log(txt): + if DEBUG == True: + print "[D6356]"+txt + return + +def exec_cmd(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + show_log (cmd +" with result:" + str(status)) + show_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + + +instantiate = [ +'echo inv_eeprom 0x55 > /sys/bus/i2c/devices/i2c-0/i2c-2/new_device' +#'echo inv_cpld 0x33 > /sys/bus/i2c/devices/i2c-0/i2c-2/new_device', +#'echo inv_cpld 0x77 > /sys/bus/i2c/devices/i2c-0/i2c-2/new_device' +] + + +drivers =[ +#kernel-dirvers +'lpc_ich', +'i2c-i801', +'i2c-mux', +'i2c-mux-pca954x', +'i2c-mux-pca9541', +'i2c-dev', +'ucd9000', +#inv-modules +'inv_eeprom', +'inv_cpld', +'inv_platform', +#'monitor', +'swps'] + + + +def system_install(): + global FORCE + + #remove default drivers to avoid modprobe order conflicts + status, output = exec_cmd("rmmod i2c_ismt ", 1) + status, output = exec_cmd("rmmod i2c-i801 ", 1) + status, output = exec_cmd("rmmod gpio_ich ", 1) + status, output = exec_cmd("rmmod lpc_ich ", 1) + + #insert extra module + status, output = exec_cmd("insmod /lib/modules/4.9.0-9-2-amd64/kernel/drivers/gpio/gpio-ich.ko gpiobase=0",1) + + #install drivers + for i in range(0,len(drivers)): + status, output = exec_cmd("modprobe "+drivers[i], 1) + if status: + print output + if FORCE == 0: + return status + + #instantiate devices + for i in range(0,len(instantiate)): + #time.sleep(1) + status, output = exec_cmd(instantiate[i], 1) + if status: + print output + if FORCE == 0: + return status +# +# INV_FIX-4037 +# It replaces the original sff8436 driver with the optoe driver +# + #optoe map to i2c-bus + for i in range(14,22): + status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-6/i2c-"+str(i)+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + for i in range(22,30): + status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-7/i2c-"+str(i)+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + for i in range(30,38): + status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-8/i2c-"+str(i)+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + for i in range(38,46): + status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-9/i2c-"+str(i)+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + for i in range(46,54): + status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-10/i2c-"+str(i)+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + for i in range(54,62): + status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-11/i2c-"+str(i)+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + for i in range(62,70): + status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-12/i2c-"+str(i)+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + return + + +def system_ready(): + if not device_found(): + return False + return True + +def install(): + if not device_found(): + print "No device, installing...." + status = system_install() + if status: + if FORCE == 0: + return status + else: + print "D6356 devices detected...." + return + +def uninstall(): + global FORCE + #uninstall drivers + exec_cmd("rmmod gpio_ich",1) + for i in range(len(drivers)-1,-1,-1): + status, output = exec_cmd("rmmod "+drivers[i], 1) + if status: + print output + if FORCE == 0: + return status + return + +def device_found(): + ret1, log = exec_cmd("ls "+i2c_prefix+"*0072", 0) + ret2, log = exec_cmd("ls "+i2c_prefix+"i2c-5", 0) + return not(ret1 or ret2) + +if __name__ == "__main__": + main() + + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/setup.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/setup.py new file mode 100644 index 000000000000..3bd7b4825f43 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='sonic_platform', + version='1.0', + description='Module to initialize Inventec D7054Q28B platforms', + + packages=['sonic_platform'], +) + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/__init__.py new file mode 100644 index 000000000000..4bfefa0fb636 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/__init__.py @@ -0,0 +1,3 @@ +__all__ = ["platform", "chassis"] +from sonic_platform import * + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/chassis.py new file mode 100644 index 000000000000..b5053cf4e2b4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/chassis.py @@ -0,0 +1,155 @@ +#!/usr/bin/env python +# +# Name: chassis.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.eeprom import Eeprom + from sonic_platform.psu import Psu + from sonic_platform.sfp import Sfp + from sonic_platform.fan import Fan + from sonic_platform.watchdog import Watchdog + from sonic_platform.thermal import Thermal + +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Chassis(ChassisBase): + + def __init__(self): + ChassisBase.__init__(self) + self.__num_of_psus = 2 + self.__num_of_ports = 54 + self.__num_of_sfps = 48 + self.__num_of_fans = 4 + self.__num_of_thermals = 6 + + # Initialize EEPROM + self._eeprom = Eeprom() + + # Initialize watchdog + #self._watchdog = Watchdog() + + # Initialize FAN + for index in range(1, self.__num_of_fans + 1): + fan = Fan(index) + self._fan_list.append(fan) + + # Initialize thermal + for index in range(1, self.__num_of_thermals + 1): + thermal = Thermal(index) + self._thermal_list.append(thermal) + + # Initialize PSU and PSU_FAN + for index in range(1, self.__num_of_psus + 1): + psu = Psu(index) + self._psu_list.append(psu) + fan = Fan(index, True) + self._fan_list.append(fan) + + # Initialize SFP + for index in range(0, self.__num_of_ports): + if index in range(0,self.__num_of_sfps): + sfp = Sfp(index, 'SFP') + else: + sfp = Sfp(index, 'QSFP') + + self._sfp_list.append(sfp) + +############################################## +# Device methods +############################################## + + 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 + Returns: + string: Serial number of chassis + """ + return self._eeprom.serial_number_str() + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + +############################################## +# Chassis methods +############################################## + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.base_mac_addr() + + 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. + Ex. { '0x21':'AG9064', '0x22':'V1.0', '0x23':'AG9064-0109867821', + '0x24':'001c0f000fcd0a', '0x25':'02/03/2018 16:22:00', + '0x26':'01', '0x27':'REV01', '0x28':'AG9064-C2358-16G'} + """ + return self._eeprom.system_eeprom_info() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + raise NotImplementedError diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/eeprom.py new file mode 100644 index 000000000000..b0ebee54ee24 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/eeprom.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# +# Name: eeprom.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + 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 = "/sys/class/i2c-adapter/i2c-0/0-0053/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_addr(self): + (is_valid, t) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_MAC_BASE) + if not is_valid or t[1] != 6: + return super(TlvInfoDecoder, self).switchaddrstr(e) + + return ":".join([binascii.b2a_hex(T) for T in t[2]]) + + def modelstr(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PRODUCT_NAME) + if not is_valid: + return "N/A" + + return results[2] + + def part_number_str(self): + (is_valid, results) = self.get_tlv_field( + self.__eeprom_data, self._TLV_CODE_PART_NUMBER) + if not is_valid: + return "N/A" + + return results[2] + + def serial_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 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-inventec/d7054q28b/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/fan.py new file mode 100644 index 000000000000..ecfbfe2d8763 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/fan.py @@ -0,0 +1,213 @@ +#!/usr/bin/env python + +############################################################################# +# Inventec d7264 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the FAN information +# +############################################################################# + +try: + import os + from sonic_platform_base.fan_base import FanBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +############### +# Global +############### +FAN_DIR = "/sys/bus/i2c/devices/0-0066/" +MAX_PWM = 255 +class Fan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, index, is_psu_fan=False): + self.is_psu_fan = is_psu_fan + + self.fan_gpi = "fan_gpi" + self.fan_index = index + if self.is_psu_fan: + self.fan_pwm = "pwm_psu{}".format(self.fan_index) + self.psu_fan_rpm = "rpm_psu{}".format(self.fan_index) + else: + self.fan_pwm = "pwm{}".format(self.fan_index) + self.fan_status_led_green_color = "fan_led_grn{}".format(self.fan_index) + self.fan_status_led_red_color = "fan_led_red{}".format(self.fan_index) + self.fan_front_rpm = "fan{}_input".format(self.fan_index * 2 - 1) + self.fan_rear_rpm = "fan{}_input".format(self.fan_index * 2) + + +####################### +# private function +####################### + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + + #################### + # Device base + #################### + + 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.fan_index) + else: + return "FAN-{}".format(self.fan_index) + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + + Note: + fan_gpi define 8 bits + low byte means fan presense + high byte means fan direction + """ + presence = False + attr_path = FAN_DIR + self.fan_gpi + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + not_presence_bit = 1 << (self.fan_index - 1) + if not (int(attr_rv,16) and not_presence_bit): + presence = True + + return presence + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + if not self.is_psu_fan: + status = False + attr_grn_path = FAN_DIR + self.fan_status_led_green_color + + attr_grn_rv = self.__get_attr_value(attr_grn_path) + if (attr_grn_rv != 'ERR' and attr_grn_rv == '1'): + status = True + return status + + ################# + # fan base + ################# + + def get_direction(self): + """ + Retrieves the direction of fan + + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + + Note: + fan_gpi define 8 bits + low byte means fan presense + high byte means fan direction + """ + direction = self.FAN_DIRECTION_INTAKE + attr_path = FAN_DIR + self.fan_gpi + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + #attr_rv = attr_rv >> 4 + direction_bit = 1 << ((self.fan_index - 1)+4) + if not (int(attr_rv,16) and direction_bit): + direction = self.FAN_DIRECTION_EXHAUST + + return direction + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + speed = 0 + attr_path = FAN_DIR + self.fan_pwm + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + pwm = int(attr_rv,10)if attr_rv else 0 + speed = float(pwm*100/MAX_PWM) + + return int(speed) + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + speed = 0 + attr_path = FAN_DIR + self.fan_pwm + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + pwm = int(attr_rv,10)if attr_rv else 0 + speed = float(pwm*100/MAX_PWM) + + return int(speed) + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + return 20 + + def get_status_led(self): + """ + Gets the state of the fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + if self.is_psu_fan: + return self.STATUS_LED_COLOR_OFF + + attr_grn_path = FAN_DIR + self.fan_status_led_green_color + attr_red_path = FAN_DIR + self.fan_status_led_red_color + + attr_grn_rv = self.__get_attr_value(attr_grn_path) + attr_red_rv = self.__get_attr_value(attr_red_path) + if (attr_grn_rv != 'ERR' and attr_red_rv != 'ERR'): + if (attr_grn_rv == '1'): + return self.STATUS_LED_COLOR_GREEN + elif (attr_red_rv == '1'): + return self.STATUS_LED_COLOR_RED + else: + return self.STATUS_LED_COLOR_OFF diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/platform.py new file mode 100644 index 000000000000..ddad8c4c5788 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/platform.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# +# Name: platform.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/psu.py new file mode 100644 index 000000000000..52dd2b12fb20 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/psu.py @@ -0,0 +1,196 @@ +#!/usr/bin/env python +# +# Name: psu.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + from sonic_platform_base.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +PSU_DIR = "/sys/bus/i2c/devices/0-0066/" + +class Psu(PsuBase): + def __init__(self, index): + self.index = index + self.psu_presence_attr = "psu{}".format(self.index-1) + self.psu_status_attr = "psoc_psu{}_iout".format(self.index) + self.psu_power_in_attr = "power{}_input".format(self.index) + self.psu_power_out_attr = "power{}_input".format(self.index) + self.psu_voltage_out_attr = "psoc_psu{}_vin".format(self.index) + self.psu_current_out_attr = "psoc_psu{}_iout".format(self.index) + self.psu_serial_attr = "psoc_psu{}_serial".format(self.index) + self.psu_model_attr = "psoc_psu{}_vender".format(self.index) + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return "PSU{}".format(self.index) + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + presence = False + attr_path = PSU_DIR+self.psu_presence_attr + attr_normal = "0 : normal" + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (attr_rv == attr_normal): + presence = True + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + model = "N/A" + attr_path = PSU_DIR+self.psu_model_attr + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + model = attr_rv + + return model + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + serial = "N/A" + attr_path = PSU_DIR+self.psu_serial_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + serial = attr_rv + + return serial + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + status = False + attr_path = PSU_DIR+self.psu_status_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) != 0): + status = True + + return status + +############################################## +# PSU methods +############################################## + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + voltage_out = 0.0 + attr_path = PSU_DIR+self.psu_voltage_out_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + voltage_out = float(attr_rv) / 1000 + + return voltage_out + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, the electric current in amperes, e.g 15.4 + """ + current_out = 0.0 + attr_path = PSU_DIR+self.psu_current_out_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + current_out = float(attr_rv) / 1000 + + return current_out + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, e.g. 302.6 + """ + power_out = 0.0 + attr_path = PSU_DIR+self.psu_power_out_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + power_out = float(attr_rv) / 1000000 + + return power_out + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + + Returns: + A boolean, True if PSU has stablized its output voltages and passed all + its internal self-tests, False if not. + """ + return self.get_status() + + def get_status_led(self): + """ + Gets the state of the PSU status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + if self.get_powergood_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_OFF + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/sfp.py new file mode 100644 index 000000000000..47d88afa13a4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/sfp.py @@ -0,0 +1,1285 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Sfp contains an implementation of SONiC Platform Base API and +# provides the sfp device status which are available in the platform +# +############################################################################# + +import os +import time +import subprocess +import sonic_device_util +from ctypes import create_string_buffer + +try: + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_eeprom import eeprom_dts + 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 +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_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_TYPE_OFFSET = 0 +XCVR_TYPE_WIDTH = 1 +XCVR_EXT_TYPE_OFFSET = 1 +XCVR_EXT_TYPE_WIDTH = 1 +XCVR_CONNECTOR_OFFSET = 2 +XCVR_CONNECTOR_WIDTH = 1 +XCVR_COMPLIANCE_CODE_OFFSET = 3 +XCVR_COMPLIANCE_CODE_WIDTH = 8 +XCVR_ENCODING_OFFSET = 11 +XCVR_ENCODING_WIDTH = 1 +XCVR_NBR_OFFSET = 12 +XCVR_NBR_WIDTH = 1 +XCVR_EXT_RATE_SEL_OFFSET = 13 +XCVR_EXT_RATE_SEL_WIDTH = 1 +XCVR_CABLE_LENGTH_OFFSET = 14 +XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +XCVR_CABLE_LENGTH_WIDTH_SFP = 6 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 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 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_VERSION_COMPLIANCE_OFFSET = 1 +QSFP_VERSION_COMPLIANCE_WIDTH = 1 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_CHANNL_DISABLE_STATUS_OFFSET = 86 +QSFP_CHANNL_DISABLE_STATUS_WIDTH = 1 +QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 +QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 +QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_CONTROL_OFFSET = 86 +QSFP_CONTROL_WIDTH = 8 +QSFP_MODULE_MONITOR_OFFSET = 0 +QSFP_MODULE_MONITOR_WIDTH = 9 +QSFP_POWEROVERRIDE_OFFSET = 93 +QSFP_POWEROVERRIDE_WIDTH = 1 +QSFP_POWEROVERRIDE_BIT = 0 +QSFP_POWERSET_BIT = 1 +QSFP_OPTION_VALUE_OFFSET = 192 +QSFP_OPTION_VALUE_WIDTH = 4 + +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" + + +class Sfp(SfpBase): + """Platform-specific Sfp class""" + + # Port number + PORT_START = 0 + PORT_END = 53 + + # Path to QSFP sysfs + PLATFORM_ROOT_PATH = "/usr/share/sonic/device" + PMON_HWSKU_PATH = "/usr/share/sonic/hwsku" + HOST_CHK_CMD = "docker > /dev/null 2>&1" + + PLATFORM = "x86_64-inventec_d7054q28b-r0" + HWSKU = "INVENTEC-D7054Q28B-S48-Q6" + + def __init__(self, sfp_index, sfp_type): + # Init index + self.index = sfp_index + self.port_num = self.index + self.dom_supported = False + self.sfp_type = sfp_type + self.__sfp_presence_attr = "/sys/class/swps/port{}/present".format(self.index) + self.__sfp_lpmode_attr = "/sys/class/swps/port{}/lpmod".format(self.index) + self.__sfp_reset_attr = "/sys/class/swps/port{}/reset".format(self.index) + # Init eeprom path + eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' + self.port_to_eeprom_mapping = {} + self.port_to_i2c_mapping = { + 0: 10, + 1: 11, + 2: 12, + 3: 13, + 4: 14, + 5: 15, + 6: 16, + 7: 17, + 8: 18, + 9: 19, + 10: 20, + 11: 21, + 12: 22, + 13: 23, + 14: 24, + 15: 25, + 16: 26, + 17: 27, + 18: 28, + 19: 29, + 20: 30, + 21: 31, + 22: 32, + 23: 33, + 24: 34, + 25: 35, + 26: 36, + 27: 37, + 28: 38, + 29: 39, + 30: 40, + 31: 41, + 32: 42, + 33: 43, + 34: 44, + 35: 45, + 36: 46, + 37: 47, + 38: 48, + 39: 49, + 40: 50, + 41: 51, + 42: 52, + 43: 53, + 44: 54, + 45: 55, + 46: 56, + 47: 57, + 48: 58, + 49: 59, + 50: 60, + 51: 61, + 52: 62, + 53: 63 + } + + for x in range(self.PORT_START, self.PORT_END + 1): + port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) + self.port_to_eeprom_mapping[x] = port_eeprom_path + + self.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'] + + self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', + 'rx1power', 'rx2power', 'rx3power', 'rx4power', 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', 'tx1power', 'tx2power', 'tx3power', 'tx4power'] + + self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + + SfpBase.__init__(self) + + def __get_attr_value(self, attr_path): + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + def _convert_string_to_num(self, value_str): + if "-inf" in value_str: + return 'N/A' + elif "Unknown" in value_str: + return 'N/A' + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return 'N/A' + + def __read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return "" + + def __is_host(self): + return os.system(self.HOST_CHK_CMD) == 0 + + def __get_path_to_port_config_file(self): + platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.PLATFORM]) + hwsku_path = "/".join([platform_path, self.HWSKU] + ) if self.__is_host() else self.PMON_HWSKU_PATH + return "/".join([hwsku_path, "port_config.ini"]) + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + presence = False + attr_path = self.__sfp_presence_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) == 0): + presence = True + + return presence + + def __read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num] + try: + sysfsfile_eeprom = open( + sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except: + pass + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + + 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_OFFSET) + qsfp_version_compliance = int(qsfp_version_compliance_raw[0], 16) + qspf_dom_capability = int(qsfp_dom_capability_raw[0], 16) + if qsfp_version_compliance >= 0x08: + self.dom_temp_supported = (qspf_dom_capability & 0x20 != 0) + self.dom_volt_supported = (qspf_dom_capability & 0x10 != 0) + self.dom_rx_power_supported = (qspf_dom_capability & 0x08 != 0) + self.dom_tx_power_supported = (qspf_dom_capability & 0x04 != 0) + else: + self.dom_temp_supported = True + self.dom_volt_supported = True + self.dom_rx_power_supported = (qspf_dom_capability & 0x08 != 0) + self.dom_tx_power_supported = True + self.dom_supported = True + self.calibration = 1 + 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: + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + self.optional_capability = sfpd_obj.parse_option_params(qsfp_option_value_raw, 0) + self.dom_tx_disable_supported = self.optional_capability['data']['TxDisable']['value'] == 'On' + 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 + 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 + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardwarerev |1*255VCHAR |hardware version of SFP + serialnum |1*255VCHAR |serial number of the SFP + manufacturename |1*255VCHAR |SFP vendor name + modelname |1*255VCHAR |SFP model name + Connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + nominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + ======================================================================== + """ + 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 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'] = 'N/A' + transceiver_info_dict['nominal_bit_rate'] = 'N/A' + + else: + if self.sfp_type == QSFP_TYPE: + offset = 128 + vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP + cable_length_width = XCVR_CABLE_LENGTH_WIDTH_QSFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + 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 + cable_length_width = XCVR_CABLE_LENGTH_WIDTH_SFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + sfp_type = 'SFP' + + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + sfp_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'] + 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 + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. + tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. + reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. + lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. + tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. + tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 + | |to channel 3. + temperature |INT |module temperature in Celsius + voltage |INT |supply voltage in mV + txbias |INT |TX Bias Current in mA, n is the channel number, + | |for example, tx2bias stands for tx bias of channel 2. + rxpower |INT |received optical power in mW, n is the channel number, + | |for example, rx2power stands for rx power of channel 2. + txpower |INT |TX output power in mW, n is the channel number, + | |for example, tx2power stands for tx power of channel 2. + ======================================================================== + """ + # check present status + sfpd_obj = sff8436Dom() + sfpi_obj = sff8436InterfaceId() + + if not self.get_presence() or not sfpi_obj or not sfpd_obj: + return {} + + transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + offset = 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 + + dom_temperature_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature( + dom_temperature_raw, 0) + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + + dom_voltage_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + dom_channel_monitor_data = {} + dom_channel_monitor_raw = None + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( + dom_channel_monitor_raw, 0) + + else: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( + dom_channel_monitor_raw, 0) + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] + transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] + transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] + transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] + + if dom_channel_monitor_raw: + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + + for key in transceiver_dom_info_dict: + transceiver_dom_info_dict[key] = self._convert_string_to_num( + transceiver_dom_info_dict[key]) + + transceiver_dom_info_dict['rx_los'] = self.get_rx_los() + transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() + transceiver_dom_info_dict['reset_status'] = self.get_reset_status() + transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() + + return transceiver_dom_info_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + Returns: + A Boolean, True if reset enabled, False if disabled + """ + if not self.dom_supported: + return False + + if self.sfp_type == OSFP_TYPE: + return False + elif self.sfp_type == QSFP_TYPE: + offset = 0 + sfpd_obj = sff8436Dom() + dom_module_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_MODULE_MONITOR_OFFSET), QSFP_MODULE_MONITOR_WIDTH) + + if dom_module_monitor_raw is not None: + return True + else: + return False + elif self.sfp_type == SFP_TYPE: + offset = 0 + sfpd_obj = sff8472Dom() + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + + if dom_channel_monitor_raw is not None: + return True + else: + return False + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + if not self.dom_supported: + return None + + rx_los_list = [] + if self.sfp_type == OSFP_TYPE: + return None + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_RX_LOS_STATUS_OFFSET), QSFP_CHANNL_RX_LOS_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x01 != 0) + rx_los_list.append(rx_los_data & 0x02 != 0) + rx_los_list.append(rx_los_data & 0x04 != 0) + rx_los_list.append(rx_los_data & 0x08 != 0) + else: + offset = 256 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x02 != 0) + else: + return None + return rx_los_list + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + if not self.dom_supported: + return None + + tx_fault_list = [] + if self.sfp_type == OSFP_TYPE: + return None + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_TX_FAULT_STATUS_OFFSET), QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x01 != 0) + tx_fault_list.append(tx_fault_data & 0x02 != 0) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + tx_fault_list.append(tx_fault_data & 0x08 != 0) + else: + offset = 256 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + else: + return None + return tx_fault_list + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + Returns: + A Boolean, True if tx_disable is enabled, False if disabled + """ + if not self.dom_supported: + return None + + tx_disable_list = [] + if self.sfp_type == OSFP_TYPE: + return None + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_DISABLE_STATUS_OFFSET), QSFP_CHANNL_DISABLE_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list.append(tx_disable_data & 0x01 != 0) + tx_disable_list.append(tx_disable_data & 0x02 != 0) + tx_disable_list.append(tx_disable_data & 0x04 != 0) + tx_disable_list.append(tx_disable_data & 0x08 != 0) + else: + offset = 256 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list.append(tx_disable_data & 0xC0 != 0) + else: + return None + return tx_disable_list + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + tx_disable_list = self.get_tx_disable() + if tx_disable_list is None: + return 0 + tx_disabled = 0 + for i in range(len(tx_disable_list)): + if tx_disable_list[i]: + tx_disabled |= 1 << i + return tx_disabled + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + lpmode = False + attr_path = self.__sfp_lpmode_attr + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + if (int(attr_rv) == 0): + lpmode = True + + return lpmode + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + if self.sfp_type == QSFP_TYPE: + offset = 0 + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return False + + dom_control_raw = self._read_eeprom_specific_bytes((offset + QSFP_CONTROL_OFFSET), QSFP_CONTROL_WIDTH) + if dom_control_raw is not None: + dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0) + return ('On' == dom_control_data['data']['PowerOverride']) + else: + return NotImplementedError + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + Returns: + An integer number of current temperature in Celsius + """ + if not self.dom_supported: + return None + if self.sfp_type == QSFP_TYPE: + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_temp_supported: + dom_temperature_raw = self._read_eeprom_specific_bytes((offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + temp = self._convert_string_to_num(dom_temperature_data['data']['Temperature']['value']) + return temp + else: + return None + else: + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + sfpd_obj._calibration_type = 1 + + dom_temperature_raw = self._read_eeprom_specific_bytes((offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + temp = self._convert_string_to_num(dom_temperature_data['data']['Temperature']['value']) + return temp + else: + return None + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + Returns: + An integer number of supply voltage in mV + """ + if not self.dom_supported: + return None + if self.sfp_type == QSFP_TYPE: + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_volt_supported: + dom_voltage_raw = self._read_eeprom_specific_bytes((offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + voltage = self._convert_string_to_num(dom_voltage_data['data']['Vcc']['value']) + return voltage + else: + return None + else: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + sfpd_obj._calibration_type = self.calibration + + dom_voltage_raw = self._read_eeprom_specific_bytes((offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + voltage = self._convert_string_to_num(dom_voltage_data['data']['Vcc']['value']) + return voltage + else: + return None + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + tx_bias_list = [] + if self.sfp_type == QSFP_TYPE: + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX1Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX2Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX3Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX4Bias']['value'])) + else: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + sfpd_obj._calibration_type = self.calibration + + if self.dom_supported: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TXBias']['value'])) + else: + return None + else: + return None + + return tx_bias_list + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + rx_power_list = [] + if self.sfp_type == OSFP_TYPE: + # OSFP not supported on our platform yet. + return None + + elif self.sfp_type == QSFP_TYPE: + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_rx_power_supported: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + rx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['RX1Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['RX2Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['RX3Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['RX4Power']['value'])) + else: + return None + else: + return None + else: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + if self.dom_supported: + sfpd_obj._calibration_type = self.calibration + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + rx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['RXPower']['value'])) + else: + return None + else: + return None + + return rx_power_list + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + tx_power_list = [] + if self.sfp_type == OSFP_TYPE: + # OSFP not supported on our platform yet. + return None + + elif self.sfp_type == QSFP_TYPE: + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_tx_power_supported: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX1Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX2Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX3Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX4Power']['value'])) + else: + return None + else: + return None + else: + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + if self.dom_supported: + sfpd_obj._calibration_type = self.calibration + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TXPower']['value'])) + else: + return None + else: + return None + return tx_power_list + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + Returns: + A boolean, True if successful, False if not + """ + try: + reg_file = open(self.__sfp_reset_attr, "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = 0 + reg_file.write(hex(reg_value)) + reg_file.close() + + # Sleep 2 seconds to allow it to settle + time.sleep(2) + + # Flip the value back write back to the register to take port out of reset + try: + reg_file = open(self.__sfp_reset_attr, "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = 1 + reg_file.write(hex(reg_value)) + reg_file.close() + + return True + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + if self.sfp_type == SFP_TYPE: + if self.dom_tx_disable_supported: + handle = self._open_sdk() + if handle is None: + return False + + tx_disable_mask = 1 << MCIA_ADDR_TX_DISABLE_BIT + if tx_disable: + tx_disable_bit = tx_disable_mask + else: + tx_disable_bit = 0 + + return self._write_i2c_via_mcia(2, 0x51, MCIA_ADDR_TX_DISABLE, tx_disable_bit, tx_disable_mask) + else: + return False + elif self.sfp_type == QSFP_TYPE: + if self.dom_tx_disable_supported: + channel_mask = 0x0f + if tx_disable: + disable_flag = channel_mask + else: + disable_flag = 0 + + return self._write_i2c_via_mcia(0, 0x50, MCIA_ADDR_TX_CHANNEL_DISABLE, disable_flag, channel_mask) + else: + return False + else: + return NotImplementedError + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + Returns: + A boolean, True if successful, False if not + """ + 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 + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + return True + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + 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 + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + sfputil_helper = SfpUtilHelper() + sfputil_helper.read_porttab_mappings( + self.__get_path_to_port_config_file()) + #print "self.index{}".format(self.index) + name = sfputil_helper.logical[self.index] or "Unknown" + return name + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/thermal.py new file mode 100644 index 000000000000..039067428321 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d7054q28b/sonic_platform/thermal.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python + +############################################################################# +# Inventec d7264 +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Thermal information +# +############################################################################# + +import os + +try: + from sonic_platform_base.thermal_base import ThermalBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +THERMAL_PATH = "/sys/bus/i2c/devices/0-0066/" + +thermal_name_tup = ( + "FrontSide Temperature", + "FanBoard Temperature", + "NearASIC Temperature", + "Center(U10) Temperature", + "CPU Board Temperature", + "ASIC Temperature" +) + +class Thermal(ThermalBase): + """Platform-specific Thermal class""" + + def __init__(self, thermal_index): + self.index = thermal_index-1 + self.thermal_tmp = "temp{}_input".format(self.index) + + + def __get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip(' \t\n\r') + return retval + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return thermal_name_tup[self.index] + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + attr_path = THERMAL_PATH + self.thermal_tmp + return os.path.isfile(attr_path) + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + status = False + if (self.get_temperature() > 0): + status = True + + return status + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + temperature = 0.0 + attr_path = THERMAL_PATH + self.thermal_tmp + + attr_rv = self.__get_attr_value(attr_path) + if (attr_rv != 'ERR'): + temperature = float(attr_rv) / 1000 + + return temperature + diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/control b/platform/broadcom/sonic-platform-modules-inventec/debian/control index 45aa6ba10bc6..6cb61630823f 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/control +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/control @@ -25,6 +25,11 @@ Architecture: amd64 Depends: linux-image-4.9.0-9-2-amd64 Description: kernel modules for platform devices such as fan, led +Package: platform-modules-d6356 +Architecture: amd64 +Depends: linux-image-4.9.0-9-2-amd64 +Description: kernel modules for platform devices such as fan, led + Package: platform-modules-d7264q28b Architecture: amd64 Depends: linux-image-4.9.0-9-2-amd64 diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6356.init b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6356.init new file mode 100644 index 000000000000..eaeb97406a1c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6356.init @@ -0,0 +1,58 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup Inventec d6356 board. +### END INIT INFO + +PLATFORM_DIR=/usr/share/sonic/device/x86_64-inventec_d6356-r0/plugins + +PLATFORM_DAEMON=$PLATFORM_DIR/platfmgr.py +PLATFORM_DAEMON_NAME=platfmgr + +# The process ID of the script when it runs is stored here: +PLATFORM_PIDFILE=/var/run/$PLATFORM_DAEMON_NAME.pid + +do_monitor_start() { + /sbin/start-stop-daemon --quiet --oknodo --pidfile $PLATFORM_PIDFILE --make-pidfile --startas $PLATFORM_DAEMON --start --background -- $DAEMON_OPTS +} + +do_monitor_stop() { + /sbin/start-stop-daemon --quiet --oknodo --stop --pidfile $PLATFORM_PIDFILE --retry 10 +} + +case "$1" in +start) + echo -n "Setting up board... " + +# depmod -a + /usr/local/bin/inventec_d6356_util.py -f install + do_monitor_${1} + echo "done." + ;; + +stop) + + /usr/local/bin/inventec_d6356_util.py -f clean + do_monitor_${1} + echo "done." + + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-d6356.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6356.install b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6356.install new file mode 100644 index 000000000000..6f03ede72e05 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6356.install @@ -0,0 +1,3 @@ +d6356/utils/inventec_d6356_util.py usr/local/bin +d6356/utils/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-inventec_d6356-r0 +systemd/platform-modules-d6356.service lib/systemd/system diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d7054q28b.install b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d7054q28b.install index 0ffc0a4f92a3..a83009858d6d 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d7054q28b.install +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d7054q28b.install @@ -1,4 +1,5 @@ d7054q28b/utils/inventec_d7054_util.py usr/local/bin +d7054q28b/utils/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-inventec_d7054q28b-r0 common/utils/transceiver_monitor.py usr/share/sonic/device/x86_64-inventec_d7054q28b-r0/plugins common/utils/led_proc.py usr/share/sonic/device/x86_64-inventec_d7054q28b-r0/plugins common/utils/asic_monitor.py usr/share/sonic/device/x86_64-inventec_d7054q28b-r0/plugins diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/rules b/platform/broadcom/sonic-platform-modules-inventec/debian/rules index 2e396e167822..f6c1aa1b2e70 100755 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/rules +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/rules @@ -14,14 +14,20 @@ export INSTALL_MOD_DIR:=extra KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= d7032q28b d7054q28b d6254qs d6556 d7264q28b +MODULE_DIRS:= d7032q28b d7054q28b d6254qs d6556 d6356 d7264q28b %: - dh $@ --with=systemd + dh $@ --with python2,systemd override_dh_auto_build: (for mod in $(MODULE_DIRS); do \ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ + if [ $$mod = "d7054q28b" ] || [ $$mod = "d6356" ]; then \ + cd $(MOD_SRC_DIR)/$${mod}; \ + python2 setup.py build; \ + python2 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/utils; \ + cd $(MOD_SRC_DIR); \ + fi \ done) override_dh_auto_install: @@ -30,11 +36,13 @@ override_dh_auto_install: $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ cp $(MOD_SRC_DIR)/$${mod}/modules/*.ko \ debian/platform-modules-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ - dh_installdirs -pplatform-modules-$${mod} usr/local/bin; \ - cp $(MOD_SRC_DIR)/$${mod}/utils/* \ - debian/platform-modules-$${mod}/usr/local/bin; \ + if [ $$mod = "d7054q28b" ] || [ $$mod = "d6356" ]; then \ + cd $(MOD_SRC_DIR)/$${mod}; \ + python2 setup.py install --root=$(MOD_SRC_DIR)/debian/platform-modules-$${mod} --install-layout=deb; \ + cd $(MOD_SRC_DIR); \ + fi \ done) - + override_dh_usrlocal: override_dh_pysupport: diff --git a/platform/broadcom/sonic-platform-modules-inventec/systemd/platform-modules-d6356.service b/platform/broadcom/sonic-platform-modules-inventec/systemd/platform-modules-d6356.service new file mode 100644 index 000000000000..85fa47a72611 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/systemd/platform-modules-d6356.service @@ -0,0 +1,13 @@ +[Unit] +Description=Inventec d6356 Platform modules +After=local-fs.target +Before=pmon.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-d6356 start +ExecStop=-/etc/init.d/platform-modules-d6356 stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-juniper/.gitignore b/platform/broadcom/sonic-platform-modules-juniper/.gitignore new file mode 100644 index 000000000000..7f287d538227 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/.gitignore @@ -0,0 +1,50 @@ +# Object files +*.o +*.ko +*.obj +*.elf + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su + +# Kernel Module Compile Results +*.mod* +*.cmd +*.o.d +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +# Debian packaging +*.debhelper.log +*.postinst.debhelper +*.postrm.debhelper +*.prerm.debhelper +*.substvars diff --git a/platform/broadcom/sonic-platform-modules-juniper/LICENSE b/platform/broadcom/sonic-platform-modules-juniper/LICENSE new file mode 100644 index 000000000000..c819eacfeb94 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/LICENSE @@ -0,0 +1,16 @@ +Copyright (C) 2016 Microsoft, Inc +Copyright (C) 2019 Juniper Networks + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. diff --git a/platform/broadcom/sonic-platform-modules-juniper/README.md b/platform/broadcom/sonic-platform-modules-juniper/README.md new file mode 100644 index 000000000000..8d2820a74b2e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/README.md @@ -0,0 +1 @@ +platform drivers for Juniper QFX5210 for the SONiC project 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 new file mode 100644 index 000000000000..25860a6ac1f9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/common/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/common/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-juniper/common/modules/ym2651y.c new file mode 100644 index 000000000000..3ade5684107a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/common/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/debian/changelog b/platform/broadcom/sonic-platform-modules-juniper/debian/changelog new file mode 100755 index 000000000000..bc640fa563af --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/changelog @@ -0,0 +1,6 @@ +sonic-juniper-platform-modules (1.1) unstable; urgency=low + + * Initial release: Add support for QFX5210. + -- Juniper Networks + Ciju Rajan K Tue, 30 July 2019 + diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/compat b/platform/broadcom/sonic-platform-modules-juniper/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/control b/platform/broadcom/sonic-platform-modules-juniper/debian/control new file mode 100755 index 000000000000..c9310069f9f9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/control @@ -0,0 +1,11 @@ +Source: sonic-juniper-platform-modules +Section: main +Priority: extra +Maintainer: Juniper Networks +Build-Depends: debhelper (>= 9), bzip2 +Standards-Version: 3.9.3 + +Package: sonic-platform-juniper-qfx5210 +Architecture: amd64 +Description: kernel modules for platform devices such as fan, led, sfp + diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/files b/platform/broadcom/sonic-platform-modules-juniper/debian/files new file mode 100644 index 000000000000..24ef0ffef22b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/files @@ -0,0 +1,2 @@ +sonic-juniper-platform-modules_1.1_amd64.buildinfo main extra +sonic-platform-juniper-qfx5210_1.1_amd64.deb main extra diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/rules b/platform/broadcom/sonic-platform-modules-juniper/debian/rules new file mode 100755 index 000000000000..2be5594acd3d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/rules @@ -0,0 +1,86 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +include /usr/share/dpkg/pkg-info.mk + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +export INSTALL_MOD_DIR:=extra + +PYTHON ?= python2 + +PACKAGE_PRE_NAME := sonic-platform-juniper +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= qfx5210 +MODULE_DIR := modules +UTILS_DIR := utils +SERVICE_DIR := service +PLATFORM_DIR := sonic_platform +CONF_DIR := conf + +%: + dh $@ --with systemd,python2,python3 --buildsystem=pybuild + +clean: + dh_testdir + dh_testroot + dh_clean + +build: + #make modules -C $(KERNEL_SRC)/build M=$(MODULE_SRC) + (for mod in $(MODULE_DIRS); do \ + make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules || exit 1; \ + $(PYTHON) $${mod}/setup.py build; \ + done) + +binary: binary-arch binary-indep + # Nothing to do + +binary-arch: + # Nothing to do + +#install: build + #dh_testdir + #dh_testroot + #dh_clean -k + #dh_installdirs + +binary-indep: + dh_testdir + dh_installdirs + + # Custom package commands + (for mod in $(MODULE_DIRS); do \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /usr/local/bin; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /lib/systemd/system; \ + cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \ + cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \ + $(PYTHON) $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ + done) + # Resuming debhelper scripts + dh_testroot + dh_install + dh_installchangelogs + dh_installdocs + dh_systemd_enable + dh_installinit + dh_systemd_start + dh_link + dh_fixperms + dh_compress + dh_strip + dh_installdeb + dh_gencontrol + dh_md5sums + dh_builddeb +.PHONY: build binary binary-arch binary-indep clean diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.install b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.install new file mode 100644 index 000000000000..db8c036fdd0d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.install @@ -0,0 +1,4 @@ +qfx5210/utils/juniper_qfx5210_util.py usr/local/bin +qfx5210/utils/juniper_qfx5210_monitor.py usr/local/bin +qfx5210/utils/platform_poweroff usr/local/bin +qfx5210/service/qfx5210-platform-init.service etc/systemd/system diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst new file mode 100644 index 000000000000..dcff39f53799 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst @@ -0,0 +1,22 @@ +systemctl enable qfx5210-platform-init.service +systemctl start qfx5210-platform-init.service + +# There are primary and secondary bios in qfx5210 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 + efibootmgr -c -L "SONiC" -l "\EFI\BOOT\BOOTX64.EFI" > /dev/null 2>&1 +fi diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/Makefile b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/Makefile new file mode 100644 index 000000000000..2218af494da7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/Makefile @@ -0,0 +1,2 @@ +obj-m:=x86-64-juniper-qfx5210-64x-fan.o x86-64-juniper-qfx5210-64x-leds.o \ + x86-64-juniper-qfx5210-64x-psu.o juniper_i2c_cpld.o ym2651y.o 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 120000 index 000000000000..843ce05a4313 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/juniper_i2c_cpld.c @@ -0,0 +1 @@ +../../common/modules/juniper_i2c_cpld.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-fan.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-fan.c new file mode 100644 index 000000000000..3e9b67a5da63 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-fan.c @@ -0,0 +1,470 @@ +/* + * A hwmon driver for the juniper qfx5210-64x fan + * + * Modified and tested to work on Juniper QFX5210 + * Ciju Rajan K + * + * Copyright (C) 2014 juniper Technology Corporation. + * Brandon Chuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "qfx5210_64x_fan" + +static struct qfx5210_64x_fan_data *qfx5210_64x_fan_update_device(struct device *dev); +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); + +/* fan related data, the index should match sysfs_fan_attributes + */ +static const u8 fan_reg[] = { + 0x80, /* fan 1-4 present status */ + 0x81, /* fan 1-4 direction(0:F2B 1:B2F) */ + 0x87, /* fan PWM(for all fan) */ + 0x90, /* front fan 1 speed(rpm) */ + 0x91, /* front fan 2 speed(rpm) */ + 0x92, /* front fan 3 speed(rpm) */ + 0x93, /* front fan 4 speed(rpm) */ + 0x98, /* rear fan 1 speed(rpm) */ + 0x99, /* rear fan 2 speed(rpm) */ + 0x9A, /* rear fan 3 speed(rpm) */ + 0x9B, /* rear fan 4 speed(rpm) */ +}; + +/* Each client has this additional data */ +struct qfx5210_64x_fan_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[ARRAY_SIZE(fan_reg)]; /* Register value */ +}; + +enum fan_id { + FAN1_ID, + FAN2_ID, + FAN3_ID, + FAN4_ID +}; + +enum sysfs_fan_attributes { + FAN_PRESENT_REG, + FAN_DIRECTION_REG, + FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */ + FAN1_FRONT_SPEED_RPM, + FAN2_FRONT_SPEED_RPM, + FAN3_FRONT_SPEED_RPM, + FAN4_FRONT_SPEED_RPM, + FAN1_REAR_SPEED_RPM, + FAN2_REAR_SPEED_RPM, + FAN3_REAR_SPEED_RPM, + FAN4_REAR_SPEED_RPM, + FAN1_DIRECTION, + FAN2_DIRECTION, + FAN3_DIRECTION, + FAN4_DIRECTION, + FAN1_PRESENT, + FAN2_PRESENT, + FAN3_PRESENT, + FAN4_PRESENT, + FAN1_FAULT, + FAN2_FAULT, + FAN3_FAULT, + FAN4_FAULT +}; + +/* Define attributes + */ +#define DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(index, index2) \ + static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT);\ + static SENSOR_DEVICE_ATTR(fan##index2##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT) +#define DECLARE_FAN_FAULT_ATTR(index, index2) &sensor_dev_attr_fan##index##_fault.dev_attr.attr, \ + &sensor_dev_attr_fan##index2##_fault.dev_attr.attr + +#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IRUGO, fan_show_value, NULL, FAN##index##_DIRECTION) +#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr + +#define DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN_DUTY_CYCLE_PERCENTAGE);\ + static SENSOR_DEVICE_ATTR(pwm##index, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN_DUTY_CYCLE_PERCENTAGE) + +#define DECLARE_FAN_DUTY_CYCLE_ATTR(index) &sensor_dev_attr_fan_duty_cycle_percentage.dev_attr.attr, \ + &sensor_dev_attr_pwm##index.dev_attr.attr + + +#define DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_present, S_IRUGO, fan_show_value, NULL, FAN##index##_PRESENT) +#define DECLARE_FAN_PRESENT_ATTR(index) &sensor_dev_attr_fan##index##_present.dev_attr.attr + +#define DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(index, index2) \ + static SENSOR_DEVICE_ATTR(fan##index##_front_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index##_rear_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index##_input, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index2##_input, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM) +#define DECLARE_FAN_SPEED_RPM_ATTR(index, index2) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_input.dev_attr.attr, \ + &sensor_dev_attr_fan##index2##_input.dev_attr.attr + +/* 6 fan fault attributes in this platform */ +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(1,11); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(2,12); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(3,13); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(4,14); +/* 6 fan speed(rpm) attributes in this platform */ +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(1,11); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(2,12); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(3,13); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(4,14); +/* 6 fan present attributes in this platform */ +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(1); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(2); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(3); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(4); +/* 6 fan direction attribute in this platform */ +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4); +/* 1 fan duty cycle attribute in this platform */ +DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(1); + +static struct attribute *qfx5210_64x_fan_attributes[] = { + /* fan related attributes */ + DECLARE_FAN_FAULT_ATTR(1,11), + DECLARE_FAN_FAULT_ATTR(2,12), + DECLARE_FAN_FAULT_ATTR(3,13), + DECLARE_FAN_FAULT_ATTR(4,14), + DECLARE_FAN_SPEED_RPM_ATTR(1,11), + DECLARE_FAN_SPEED_RPM_ATTR(2,12), + DECLARE_FAN_SPEED_RPM_ATTR(3,13), + DECLARE_FAN_SPEED_RPM_ATTR(4,14), + DECLARE_FAN_PRESENT_ATTR(1), + DECLARE_FAN_PRESENT_ATTR(2), + DECLARE_FAN_PRESENT_ATTR(3), + DECLARE_FAN_PRESENT_ATTR(4), + DECLARE_FAN_DIRECTION_ATTR(1), + DECLARE_FAN_DIRECTION_ATTR(2), + DECLARE_FAN_DIRECTION_ATTR(3), + DECLARE_FAN_DIRECTION_ATTR(4), + DECLARE_FAN_DUTY_CYCLE_ATTR(1), + NULL +}; + +#define FAN_DUTY_CYCLE_REG_MASK 0xF +#define FAN_MAX_DUTY_CYCLE 100 +#define FAN_REG_VAL_TO_SPEED_RPM_STEP 100 + +static int qfx5210_64x_fan_read_value(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int qfx5210_64x_fan_write_value(struct i2c_client *client, u8 reg, u8 value) +{ + return i2c_smbus_write_byte_data(client, reg, value); +} + +/* fan utility functions + */ +static u32 reg_val_to_duty_cycle(u8 reg_val) +{ + reg_val &= FAN_DUTY_CYCLE_REG_MASK; + + if (!reg_val) { + return 0; + } + + if (reg_val == 0xF) { + return FAN_MAX_DUTY_CYCLE; + } + + return (reg_val * 6) + 10; +} + +static u8 duty_cycle_to_reg_val(u8 duty_cycle) +{ + if (duty_cycle < 16) { + return 0; + } + + if (duty_cycle >= 100) { + return 0xF; + } + + return (duty_cycle - 10) / 6; +} + +static u32 reg_val_to_speed_rpm(u8 reg_val) +{ + return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP; +} + +static u8 reg_val_to_direction(u8 reg_val, enum fan_id id) +{ + u8 mask = (1 << id); + return !!(reg_val & mask); +} + +static u8 reg_val_to_is_present(u8 reg_val, enum fan_id id) +{ + u8 mask = (1 << id); + return !(reg_val & mask); +} + +static u8 is_fan_fault(struct qfx5210_64x_fan_data *data, enum fan_id id) +{ + u8 ret = 1; + int front_fan_index = FAN1_FRONT_SPEED_RPM + id; + int rear_fan_index = FAN1_REAR_SPEED_RPM + id; + + /* Check if the speed of front or rear fan is ZERO, + */ + if (reg_val_to_speed_rpm(data->reg_val[front_fan_index]) && + reg_val_to_speed_rpm(data->reg_val[rear_fan_index])) { + ret = 0; + } + + return ret; +} + +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value; + struct i2c_client *client = to_i2c_client(dev); + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + if (value > FAN_MAX_DUTY_CYCLE) + value = FAN_MAX_DUTY_CYCLE; + if (value < 0) + return -EINVAL; + + qfx5210_64x_fan_write_value(client, 0x28, 0); /* Disable fan speed watch dog */ + qfx5210_64x_fan_write_value(client, fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value)); + return count; +} + +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct qfx5210_64x_fan_data *data = qfx5210_64x_fan_update_device(dev); + ssize_t ret = 0; + + if (data->valid) { + switch (attr->index) { + case FAN_DUTY_CYCLE_PERCENTAGE: + { + u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[FAN_DUTY_CYCLE_PERCENTAGE]); + ret = sprintf(buf, "%u\n", duty_cycle); + break; + } + case FAN1_FRONT_SPEED_RPM: + case FAN2_FRONT_SPEED_RPM: + case FAN3_FRONT_SPEED_RPM: + case FAN4_FRONT_SPEED_RPM: + case FAN1_REAR_SPEED_RPM: + case FAN2_REAR_SPEED_RPM: + case FAN3_REAR_SPEED_RPM: + case FAN4_REAR_SPEED_RPM: + { + ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index])); + break; + } + case FAN1_PRESENT: + case FAN2_PRESENT: + case FAN3_PRESENT: + case FAN4_PRESENT: + ret = sprintf(buf, "%d\n", + reg_val_to_is_present(data->reg_val[FAN_PRESENT_REG], + attr->index - FAN1_PRESENT)); + break; + case FAN1_FAULT: + case FAN2_FAULT: + case FAN3_FAULT: + case FAN4_FAULT: + ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT)); + break; + case FAN1_DIRECTION: + case FAN2_DIRECTION: + case FAN3_DIRECTION: + case FAN4_DIRECTION: + ret = sprintf(buf, "%d\n", + reg_val_to_direction(data->reg_val[FAN_DIRECTION_REG], + attr->index - FAN1_DIRECTION)); + break; + default: + break; + } + } + + return ret; +} + +static const struct attribute_group qfx5210_64x_fan_group = { + .attrs = qfx5210_64x_fan_attributes, +}; + +static struct qfx5210_64x_fan_data *qfx5210_64x_fan_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct qfx5210_64x_fan_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || + !data->valid) { + int i; + + dev_dbg(&client->dev, "Starting qfx5210_64x_fan update\n"); + data->valid = 0; + + /* Update fan data + */ + for (i = 0; i < ARRAY_SIZE(data->reg_val); i++) { + int status = qfx5210_64x_fan_read_value(client, fan_reg[i]); + + if (status < 0) { + data->valid = 0; + mutex_unlock(&data->update_lock); + dev_dbg(&client->dev, "reg %d, err %d\n", fan_reg[i], status); + return data; + } + else { + data->reg_val[i] = status; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int qfx5210_64x_fan_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct qfx5210_64x_fan_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct qfx5210_64x_fan_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &qfx5210_64x_fan_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: fan '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &qfx5210_64x_fan_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int qfx5210_64x_fan_remove(struct i2c_client *client) +{ + struct qfx5210_64x_fan_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &qfx5210_64x_fan_group); + + return 0; +} + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +static const struct i2c_device_id qfx5210_64x_fan_id[] = { + { "qfx5210_64x_fan", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, qfx5210_64x_fan_id); + +static struct i2c_driver qfx5210_64x_fan_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = DRVNAME, + }, + .probe = qfx5210_64x_fan_probe, + .remove = qfx5210_64x_fan_remove, + .id_table = qfx5210_64x_fan_id, + .address_list = normal_i2c, +}; + +static int __init qfx5210_64x_fan_init(void) +{ + return i2c_add_driver(&qfx5210_64x_fan_driver); +} + +static void __exit qfx5210_64x_fan_exit(void) +{ + i2c_del_driver(&qfx5210_64x_fan_driver); +} + +module_init(qfx5210_64x_fan_init); +module_exit(qfx5210_64x_fan_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("qfx5210_64x_fan 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 new file mode 100644 index 000000000000..66d097734392 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-leds.c @@ -0,0 +1,450 @@ +/* + * LED driver for the qfx5210 + * + * Modified and tested to work on Juniper QFX5210 + * Ciju Rajan K + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*#define DEBUG*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern int 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); + +#define DRVNAME "qfx5210_64x_led" + +struct qfx5210_64x_led_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[1]; /* only 1 register*/ +}; + +static struct qfx5210_64x_led_data *ledctl = NULL; + +/* + * LED related data + */ + +#define LED_CNTRLER_I2C_ADDRESS (0x60) /* CPLD1 i2c address */ + +#define LED_TYPE_ALARM_REG_MASK (0x03) +#define LED_MODE_ALARM_RED_VALUE (0x01) +#define LED_MODE_ALARM_AMBER_VALUE (0x02) +#define LED_MODE_ALARM_OFF_VALUE (0x00) + +#define LED_TYPE_SYSTEM_REG_MASK (0x0C) +#define LED_MODE_SYSTEM_GREEN_VALUE (0x04) +#define LED_MODE_SYSTEM_GREEN_BLINKING_VALUE (0x08) +#define LED_MODE_SYSTEM_OFF_VALUE (0x00) + +#define LED_TYPE_MASTER_REG_MASK (0x30) +#define LED_MODE_MASTER_GREEN_VALUE (0x10) +#define LED_MODE_MASTER_GREEN_BLINKING_VALUE (0x20) +#define LED_MODE_MASTER_OFF_VALUE (0x00) + +#define LED_TYPE_BEACON_REG_MASK (0xC0) +#define LED_MODE_BEACON_VALUE (0x40) +#define LED_MODE_BEACON_OFF_VALUE (0x00) + +enum led_type { + LED_TYPE_ALARM, + LED_TYPE_SYSTEM, + LED_TYPE_MASTER, + LED_TYPE_BEACON +}; + +struct led_reg { + u32 types; + u8 reg_addr; +}; + +static const struct led_reg led_reg_map[] = { + {(1 << LED_TYPE_ALARM) | (1 << LED_TYPE_SYSTEM) | (1 << LED_TYPE_MASTER) | (1 << LED_TYPE_BEACON), 0x30}, +}; + +enum led_light_mode { + LED_MODE_OFF = 0, + LED_MODE_RED = 1, + LED_MODE_AMBER = 2, + LED_MODE_GREEN = 1, + LED_MODE_GREEN_BLINKING = 2, + LED_MODE_BLUE_BLINKING = 1 +}; + +struct led_type_mode { + enum led_type type; + enum led_light_mode mode; + int reg_bit_mask; + int mode_value; +}; + +static struct led_type_mode led_type_mode_data[] = { + {LED_TYPE_ALARM, LED_MODE_RED, LED_TYPE_ALARM_REG_MASK, LED_MODE_ALARM_RED_VALUE}, + {LED_TYPE_ALARM, LED_MODE_AMBER, LED_TYPE_ALARM_REG_MASK, LED_MODE_ALARM_AMBER_VALUE}, + {LED_TYPE_ALARM, LED_MODE_OFF, LED_TYPE_ALARM_REG_MASK, LED_MODE_ALARM_OFF_VALUE}, + + {LED_TYPE_SYSTEM, LED_MODE_GREEN, LED_TYPE_SYSTEM_REG_MASK, LED_MODE_SYSTEM_GREEN_VALUE}, + {LED_TYPE_SYSTEM, LED_MODE_GREEN_BLINKING, LED_TYPE_SYSTEM_REG_MASK, LED_MODE_SYSTEM_GREEN_BLINKING_VALUE}, + {LED_TYPE_SYSTEM, LED_MODE_OFF, LED_TYPE_SYSTEM_REG_MASK, LED_MODE_SYSTEM_OFF_VALUE}, + + {LED_TYPE_MASTER, LED_MODE_GREEN, LED_TYPE_MASTER_REG_MASK, LED_MODE_MASTER_GREEN_VALUE}, + {LED_TYPE_MASTER, LED_MODE_GREEN_BLINKING, LED_TYPE_MASTER_REG_MASK, LED_MODE_MASTER_GREEN_BLINKING_VALUE}, + {LED_TYPE_MASTER, LED_MODE_OFF, LED_TYPE_MASTER_REG_MASK, LED_MODE_MASTER_OFF_VALUE}, + + {LED_TYPE_BEACON, LED_MODE_BLUE_BLINKING, LED_TYPE_BEACON_REG_MASK, LED_MODE_BEACON_VALUE}, + {LED_TYPE_BEACON, LED_MODE_OFF, LED_TYPE_BEACON_REG_MASK, LED_MODE_BEACON_OFF_VALUE} +}; + +static int get_led_reg(enum led_type type, u8 *reg) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(led_reg_map); i++) { + if(led_reg_map[i].types & (1 << type)) { + *reg = led_reg_map[i].reg_addr; + return 0; + } + } + + return 1; +} + +static int led_reg_val_to_light_mode(enum led_type type, u8 reg_val) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + + if (type != led_type_mode_data[i].type) + continue; + + if ((led_type_mode_data[i].reg_bit_mask & reg_val) == + led_type_mode_data[i].mode_value) + { + return led_type_mode_data[i].mode; + } + } + + return 0; +} + +static u8 led_light_mode_to_reg_val(enum led_type type, + enum led_light_mode mode, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + if (type != led_type_mode_data[i].type) + continue; + + if (mode != led_type_mode_data[i].mode) + continue; + + reg_val = led_type_mode_data[i].mode_value | + (reg_val & (~led_type_mode_data[i].reg_bit_mask)); + break; + } + + return reg_val; +} + +static int qfx5210_64x_led_read_value(u8 reg) +{ + return juniper_i2c_cpld_read(LED_CNTRLER_I2C_ADDRESS, reg); +} + +static int qfx5210_64x_led_write_value(u8 reg, u8 value) +{ + return juniper_i2c_cpld_write(LED_CNTRLER_I2C_ADDRESS, reg, value); +} + +static void qfx5210_64x_led_update(void) +{ + mutex_lock(&ledctl->update_lock); + + if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2) + || !ledctl->valid) { + int i; + + dev_dbg(&ledctl->pdev->dev, "Starting qfx5210_64x_led update\n"); + + /* Update LED data + */ + for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) { + int status = qfx5210_64x_led_read_value(led_reg_map[i].reg_addr); + + if (status < 0) { + ledctl->valid = 0; + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg_map[i].reg_addr, status); + goto exit; + } + else + { + ledctl->reg_val[i] = status; + } + } + + ledctl->last_updated = jiffies; + ledctl->valid = 1; + } + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void qfx5210_64x_led_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode, + enum led_type type) +{ + int reg_val; + u8 reg ; + mutex_lock(&ledctl->update_lock); + + if( !get_led_reg(type, ®)) { + dev_dbg(&ledctl->pdev->dev, "Not match register for %d.\n", type); + } + + reg_val = qfx5210_64x_led_read_value(reg); + if (reg_val < 0) { + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val); + goto exit; + } + + reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val); + qfx5210_64x_led_write_value(reg, reg_val); + + /* to prevent the slow-update issue */ + ledctl->valid = 0; + +exit: + mutex_unlock(&ledctl->update_lock); +} + + +static void qfx5210_64x_led_system_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + qfx5210_64x_led_set(led_cdev, led_light_mode, LED_TYPE_SYSTEM); +} + +static enum led_brightness qfx5210_64x_led_system_get(struct led_classdev *cdev) +{ + qfx5210_64x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_SYSTEM, ledctl->reg_val[0]); +} + +static void qfx5210_64x_led_master_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + qfx5210_64x_led_set(led_cdev, led_light_mode, LED_TYPE_MASTER); +} + +static enum led_brightness qfx5210_64x_led_master_get(struct led_classdev *cdev) +{ + qfx5210_64x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_MASTER, ledctl->reg_val[0]); +} + +static void qfx5210_64x_led_alarm_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + qfx5210_64x_led_set(led_cdev, led_light_mode, LED_TYPE_ALARM); +} + +static enum led_brightness qfx5210_64x_led_alarm_get(struct led_classdev *cdev) +{ + qfx5210_64x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_ALARM, ledctl->reg_val[0]); +} + +static void qfx5210_64x_led_beacon_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + qfx5210_64x_led_set(led_cdev, led_light_mode, LED_TYPE_BEACON); +} + +static enum led_brightness qfx5210_64x_led_beacon_get(struct led_classdev *cdev) +{ + qfx5210_64x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_BEACON, ledctl->reg_val[0]); +} + +static struct led_classdev qfx5210_64x_leds[] = { + [LED_TYPE_ALARM] = { + .name = "alarm", + .default_trigger = "unused", + .brightness_set = qfx5210_64x_led_alarm_set, + .brightness_get = qfx5210_64x_led_alarm_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AMBER, + }, + [LED_TYPE_SYSTEM] = { + .name = "system", + .default_trigger = "unused", + .brightness_set = qfx5210_64x_led_system_set, + .brightness_get = qfx5210_64x_led_system_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_GREEN_BLINKING, + }, + [LED_TYPE_MASTER] = { + .name = "master", + .default_trigger = "unused", + .brightness_set = qfx5210_64x_led_master_set, + .brightness_get = qfx5210_64x_led_master_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_GREEN_BLINKING, + }, + [LED_TYPE_BEACON] = { + .name = "beacon", + .default_trigger = "unused", + .brightness_set = qfx5210_64x_led_beacon_set, + .brightness_get = qfx5210_64x_led_beacon_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_BLUE_BLINKING, + }, +}; + +static int qfx5210_64x_led_suspend(struct platform_device *dev, + pm_message_t state) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(qfx5210_64x_leds); i++) { + led_classdev_suspend(&qfx5210_64x_leds[i]); + } + + return 0; +} + +static int qfx5210_64x_led_resume(struct platform_device *dev) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(qfx5210_64x_leds); i++) { + led_classdev_resume(&qfx5210_64x_leds[i]); + } + + return 0; +} + +static int qfx5210_64x_led_probe(struct platform_device *pdev) +{ + int ret, i; + + for (i = 0; i < ARRAY_SIZE(qfx5210_64x_leds); i++) { + ret = led_classdev_register(&pdev->dev, &qfx5210_64x_leds[i]); + + if (ret < 0) + break; + } + + /* Check if all LEDs were successfully registered */ + if (i != ARRAY_SIZE(qfx5210_64x_leds)){ + int j; + + /* only unregister the LEDs that were successfully registered */ + for (j = 0; j < i; j++) { + led_classdev_unregister(&qfx5210_64x_leds[i]); + } + } + + return ret; +} + +static int qfx5210_64x_led_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(qfx5210_64x_leds); i++) { + led_classdev_unregister(&qfx5210_64x_leds[i]); + } + + return 0; +} + +static struct platform_driver qfx5210_64x_led_driver = { + .probe = qfx5210_64x_led_probe, + .remove = qfx5210_64x_led_remove, + .suspend = qfx5210_64x_led_suspend, + .resume = qfx5210_64x_led_resume, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int __init qfx5210_64x_led_init(void) +{ + int ret; + + ret = platform_driver_register(&qfx5210_64x_led_driver); + if (ret < 0) { + goto exit; + } + + ledctl = kzalloc(sizeof(struct qfx5210_64x_led_data), GFP_KERNEL); + if (!ledctl) { + ret = -ENOMEM; + platform_driver_unregister(&qfx5210_64x_led_driver); + goto exit; + } + + mutex_init(&ledctl->update_lock); + + ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(ledctl->pdev)) { + ret = PTR_ERR(ledctl->pdev); + platform_driver_unregister(&qfx5210_64x_led_driver); + kfree(ledctl); + goto exit; + } + +exit: + return ret; +} + +static void __exit qfx5210_64x_led_exit(void) +{ + platform_device_unregister(ledctl->pdev); + platform_driver_unregister(&qfx5210_64x_led_driver); + kfree(ledctl); +} + +module_init(qfx5210_64x_led_init); +module_exit(qfx5210_64x_led_exit); + +MODULE_AUTHOR("Ciju Rajan K "); +MODULE_DESCRIPTION("qfx5210_64x_led driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-psu.c b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-psu.c new file mode 100644 index 000000000000..cb283d2d4a1c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/x86-64-juniper-qfx5210-64x-psu.c @@ -0,0 +1,322 @@ +/* + * An hwmon driver for juniper qfx5210_64x Power Module + * + * Modified and tested 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 +#include +#include +#include +#include + +#define PSU_STATUS_I2C_ADDR 0x60 +#define PSU_STATUS_I2C_REG_OFFSET 0x03 + +#define IS_POWER_GOOD(id, value) (!!(value & BIT(2+id))) +#define IS_PRESENT(id, value) (!(value & BIT(id))) + +static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); +static struct qfx5210_64x_psu_data *qfx5210_64x_psu_update_device(struct device *dev); +extern int juniper_i2c_cpld_read (u8 cpld_addr, u8 reg); +/* + * This function is defined in juniper_i2c_cpld.c + */ +extern int juniper_i2c_cpld_write(unsigned short, u8, u8); + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct qfx5210_64x_psu_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 index; /* PSU index */ + u8 status; /* Status(present/power_good) register read from CPLD */ +}; + +enum qfx5210_64x_psu_sysfs_attributes { + PSU_PRESENT, + PSU_POWER_GOOD +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD); + +static struct attribute *qfx5210_64x_psu_attributes[] = { + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + NULL +}; + +static int qfx5210_cpld_soft_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: qfx5210_cpld_soft_reset\n"); + ret = juniper_i2c_cpld_write(0x65, 0x04, 0x01); + if (ret) { + printk(KERN_CRIT "qfx5210_cpld_soft_reset failed\n"); + } + msleep(100); + break; + default: + /* Do Nothing */ + break; + } + return NOTIFY_DONE; +} + +static struct notifier_block qfx5210_nb = { + .notifier_call = qfx5210_cpld_soft_reset, +}; + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct qfx5210_64x_psu_data *data = qfx5210_64x_psu_update_device(dev); + u8 status = 0; + + if (!data->valid) { + return -EIO; + } + + if (attr->index == PSU_PRESENT) { + status = IS_PRESENT(data->index, data->status); + } + else { /* PSU_POWER_GOOD */ + status = IS_POWER_GOOD(data->index, data->status); + } + + return sprintf(buf, "%d\n", status); +} + +static const struct attribute_group qfx5210_64x_psu_group = { + .attrs = qfx5210_64x_psu_attributes, +}; + +/* + * QFX5210 power off sequence + */ +static void qfx5210_cpld_power_off(void) +{ + printk(KERN_ALERT "pm_power_off: qfx5210_cpld_power_off\n"); + (void) juniper_i2c_cpld_write(0x65, 0x14, 0x00); + msleep(100); + (void) juniper_i2c_cpld_write(0x77, 0x00, 0x01); + msleep(100); + (void) juniper_i2c_cpld_write(0x76, 0x00, 0x04); +} + +/* + * Default platform pm_power_off handler + */ +static void (*default_pm_power_off)(void); + +static int qfx5210_64x_psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct qfx5210_64x_psu_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct qfx5210_64x_psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + data->index = dev_id->driver_data; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &qfx5210_64x_psu_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &qfx5210_64x_psu_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int qfx5210_64x_psu_remove(struct i2c_client *client) +{ + struct qfx5210_64x_psu_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &qfx5210_64x_psu_group); + kfree(data); + + return 0; +} + +enum psu_index +{ + qfx5210_64x_psu1, + qfx5210_64x_psu2 +}; + +static const struct i2c_device_id qfx5210_64x_psu_id[] = { + { "qfx5210_64x_psu1", qfx5210_64x_psu1 }, + { "qfx5210_64x_psu2", qfx5210_64x_psu2 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, qfx5210_64x_psu_id); + +static struct i2c_driver qfx5210_64x_psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "qfx5210_64x_psu", + }, + .probe = qfx5210_64x_psu_probe, + .remove = qfx5210_64x_psu_remove, + .id_table = qfx5210_64x_psu_id, + .address_list = normal_i2c, +}; + +static struct qfx5210_64x_psu_data *qfx5210_64x_psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct qfx5210_64x_psu_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int status; + + data->valid = 0; + dev_dbg(&client->dev, "Starting qfx5210_64x update\n"); + + /* Read psu status */ + status = juniper_i2c_cpld_read(PSU_STATUS_I2C_ADDR, PSU_STATUS_I2C_REG_OFFSET); + + if (status < 0) { + dev_dbg(&client->dev, "cpld reg (0x%x) err %d\n", PSU_STATUS_I2C_ADDR, status); + goto exit; + } + else { + data->status = status; + } + + data->last_updated = jiffies; + data->valid = 1; + } + +exit: + mutex_unlock(&data->update_lock); + + return data; +} + +static int __init qfx5210_64x_psu_init(void) +{ + /* + * Store the default poweroff handler for later usage + */ + default_pm_power_off = pm_power_off; + /* + * Register the cpld poweroff handler + */ + pm_power_off = qfx5210_cpld_power_off; + /* + * Register the cpld soft reset handler + */ + if(register_reboot_notifier(&qfx5210_nb)) { + printk(KERN_ALERT "Restart handler registration failed\n"); + } + + return i2c_add_driver(&qfx5210_64x_psu_driver); +} + +static void __exit qfx5210_64x_psu_exit(void) +{ + /* + * Restore the poweroff handler + */ + pm_power_off = default_pm_power_off; + /* + * Unregister the cpld soft reset handler + */ + if (!unregister_restart_handler(&qfx5210_nb)) { + printk(KERN_CRIT "Failed to uregister restart handler\n"); + } + + i2c_del_driver(&qfx5210_64x_psu_driver); +} + +module_init(qfx5210_64x_psu_init); +module_exit(qfx5210_64x_psu_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("qfx5210_64x_psu driver"); +MODULE_LICENSE("GPL"); + 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 120000 index 000000000000..f4d67640ccc3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/modules/ym2651y.c @@ -0,0 +1 @@ +../../common/modules/ym2651y.c \ No newline at end of file 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 new file mode 100755 index 000000000000..46377aa9fdc8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/service/qfx5210-platform-init.service @@ -0,0 +1,15 @@ +[Unit] +Description=Juniper QFX5210 initialization service +Before=pmon.service +After=sysinit.target +DefaultDependencies=no + +[Service] +ExecStartPre=/usr/local/bin/juniper_qfx5210_util.py install +ExecStart=/usr/local/bin/juniper_qfx5210_monitor.py +RemainAfterExit=yes +StandardOutput=syslog+console +StandardError=syslog+console + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/setup.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/setup.py new file mode 100755 index 000000000000..536f814a3509 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/setup.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='sonic_platform', + version='1.0', + description='Module to initialize Juniper QFX5210-64X platforms', + + packages=['sonic_platform'], + package_dir={'sonic_platform': 'qfx5210/sonic_platform'}, +) + diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/__init__.py new file mode 100755 index 000000000000..9e1b2e56b1c4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/__init__.py @@ -0,0 +1 @@ +import platform diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/chassis.py new file mode 100755 index 000000000000..674d9184df3c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/chassis.py @@ -0,0 +1,277 @@ +#!/usr/bin/env python +# +# Name: chassis.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# which provide the chassis specific details +# +# Copyright (c) 2019, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. +# + +try: + import os + import commands + import sys + import time + from sonic_platform_base.chassis_base import ChassisBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Chassis(ChassisBase): + """ + JUNIPER QFX5210 Platform-specific Chassis class + """ + + # Find the last reboot reason out of following + # CPLD_WATCHDOG_RESET 0x08 + # POWER_ON_RESET 0x20 + # CPU_WATCHDOG_RESET 0x40 + # SOFTWARE_RESET 0x80 + + def __init__(self): + ChassisBase.__init__(self) + + def get_qfx5210_parameter_value(self,parameter_name): + try: + with open("/var/run/eeprom", "r") as file: + for item in file: + content = item.split('=') + if content[0] == parameter_name: + return content[1:] + return "False" + except IOError: + print "Error: File not found" + return "False" + + def get_product_name(self): + product_name_list = self.get_qfx5210_parameter_value('Product Name') + if product_name_list: + product_name = ''.join(product_name_list) + return product_name + else: + return False + + + def get_part_number(self): + part_number_list = self.get_qfx5210_parameter_value('Part Number') + if part_number_list: + part_number = ''.join(part_number_list) + return part_number + else: + return False + + + def get_serial_number(self): + serial_number_list = self.get_qfx5210_parameter_value('Serial Number') + if serial_number_list: + serial_number = ''.join(serial_number_list) + return serial_number + else: + return False + + + def get_base_mac(self): + mac_list = self.get_qfx5210_parameter_value('MAC') + if mac_list: + mac = ''.join(mac_list) + return mac + else: + return False + + + def get_mfg_date(self): + mfgdate_list = self.get_qfx5210_parameter_value('Manufacture Date') + if mfgdate_list: + mfgdate = ''.join(mfgdate_list) + return mfgdate + else: + return False + + def get_deviceversion_name(self): + device_version_list = self.get_qfx5210_parameter_value('Device Version') + if device_version_list: + deviceversion_name = ''.join(device_version_list) + return deviceversion_name + else: + return False + + def get_platform_name(self): + platform_name_list = self.get_qfx5210_parameter_value('Platform Name') + if platform_name_list: + platform_name = ''.join(platform_name_list) + return platform_name + else: + return False + + def get_MACnumber_name(self): + MACnumber_name_list = self.get_qfx5210_parameter_value('Number of MAC Addresses') + if MACnumber_name_list: + MACnumber_name = ''.join(MACnumber_name_list) + return MACnumber_name + else: + return False + + def get_vendor_name(self): + vendor_name_list = self.get_qfx5210_parameter_value('Vendor Name') + if vendor_name_list: + vendor_name = ''.join(vendor_name_list) + return vendor_name + else: + return False + + def get_mfg_name(self): + mfg_name_list = self.get_qfx5210_parameter_value('Manufacture Name') + if mfg_name_list: + mfg_name = ''.join(mfg_name_list) + return mfg_name + else: + return False + + def get_vendorext_name(self): + vendorext_list = self.get_qfx5210_parameter_value('Vendor Extension') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextIANA_name(self): + vendorext_list = self.get_qfx5210_parameter_value('IANA') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextASMREV_name(self): + vendorext_list = self.get_qfx5210_parameter_value('Assembly Part Number Rev') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextASMPartNum_name(self): + vendorext_list = self.get_qfx5210_parameter_value('Assembly Part Number') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextASMID_name(self): + vendorext_list = self.get_qfx5210_parameter_value('Assembly ID') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextASMMajNum_name(self): + vendorext_list = self.get_qfx5210_parameter_value('Assembly Major Revision') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextASMMinNum_name(self): + vendorext_list = self.get_qfx5210_parameter_value('Assembly Minor Revision') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_vendorextCLEI_name(self): + vendorext_list = self.get_qfx5210_parameter_value('CLEI code') + if vendorext_list: + vendorext = ''.join(vendorext_list) + return vendorext + else: + return False + + def get_onieversion_name(self): + onieversion_name_list = self.get_qfx5210_parameter_value('ONIE Version') + if onieversion_name_list: + onieversion_name = ''.join(onieversion_name_list) + return onieversion_name + else: + return False + + def get_crc_name(self): + crc_list = self.get_qfx5210_parameter_value('CRC') + if crc_list: + crc_name = ''.join(crc_list) + return crc_name + else: + return False + + def get_fan_type(self, fantype_path): + try: + fan_type_file = open(fantype_path) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return "-1" + else: + fan_type = fan_type_file.read() + fan_type_file.close() + return str(fan_type) + + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + """ + status, last_reboot_reason = commands.getstatusoutput("i2cget -y 0 0x65 0x24") + if (status == 0): + if last_reboot_reason == "0x80": + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) + elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08": + return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) + elif last_reboot_reason == "0x20": + return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) + elif last_reboot_reason == "0x10": + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") + else: + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") + else: + time.sleep(3) + status, last_reboot_reason = commands.getstatusoutput("i2cget -y 0 0x65 0x24") + if last_reboot_reason == "0x80": + return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None) + elif last_reboot_reason == "0x40" or last_reboot_reason == "0x08": + return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None) + elif last_reboot_reason == "0x20": + return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) + elif last_reboot_reason == "0x10": + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Swizzle Reset") + else: + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Unknown reason") diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/platform.py new file mode 100755 index 000000000000..5620fec54f65 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/sonic_platform/platform.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# +# Name: platform.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# which provide the platform specific details +# +# Copyright (c) 2019, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. +# + + +import sys + +try: + from sonic_platform_base.platform_base import PlatformBase +except ImportError as e: + raise ImportError("%s - required module not found" % e) + +platformDict = {'platform':'QFX5210-64C'} + +class Platform(PlatformBase): + def __init__(self): + self.platform = self.getPlatform() + + def getPlatformDict(self): + global platformDict + if platformDict: + return platformDict + + def readPlatformName(self): + return self.getPlatformDict().get('platform') + + def getPlatform(self): + platformCls = self.readPlatformName() + return platformCls + + def get_chassis(self): + from chassis import Chassis + chassis = Chassis() + return chassis + diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/README b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/README new file mode 100755 index 000000000000..ec9ebe97f0ee --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/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/qfx5210/utils/juniper_qfx5210_monitor.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py new file mode 100755 index 000000000000..d225400121b8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py @@ -0,0 +1,500 @@ +#!/usr/bin/env python +# +# Name: juniper_qfx5210_monitor.py version: 1.0 +# +# Description: This file contains the EM implementation for qfx5210 platform +# +# Copyright (c) 2019, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 3 or +# any later version. This code is not an official Juniper product. You can +# obtain a copy of the License at +# +# OSS License: +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Third-Party Code: This code may depend on other components under separate +# copyright notice and license terms. Your use of the source code for those +# components is subject to the terms and conditions of the respective license +# as noted in the Third-Party source code file. + +try: + import os + import commands + import sys, 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 + from tabulate import tabulate +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + +# Deafults +VERSION = '1.0' +FUNCTION_NAME = '/var/log/juniper_qfx5210_monitor' + + +global log_file +global log_level + + +global isPlatformAFI +global isFireThresholdReached +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]], + 1: [[70, 0, 41000], [70, 41000, 47000], [80, 47000, 0], [80, 47000, 52000], [100, 52000, 0], ['Yellow Alarm', 58000, 64000], ['Red Alarm', 64000, 69000], ['Fire Shut Alarm', 69000, 0]], + 2: [[70, 0, 33000], [70, 33000, 39000], [80, 39000, 0], [80, 39000, 45000], [100, 45000, 0], ['Yellow Alarm', 53000, 59000], ['Red Alarm', 59000, 64000], ['Fire Shut Alarm', 64000, 0]], + 3: [[70, 0, 31000], [70, 31000, 36000], [80, 36000, 0], [80, 36000, 42000], [100, 42000, 0], ['Yellow Alarm', 48000, 55000], ['Red Alarm', 55000, 60000], ['Fire Shut Alarm', 60000, 0]], + 4: [[70, 0, 31000], [70, 31000, 36000], [80, 36000, 0], [80, 36000, 42000], [100, 42000, 0], ['Yellow Alarm', 48000, 55000], ['Red Alarm', 55000, 60000], ['Fire Shut Alarm', 60000, 0]], + 5: [[70, 0, 31000], [70, 31000, 36000], [80, 36000, 0], [80, 36000, 43000], [100, 43000, 0], ['Yellow Alarm', 49000, 56000], ['Red Alarm', 56000, 61000], ['Fire Shut Alarm', 61000, 0]], + 6: [[70, 0, 70000], [70, 70000, 78000], [80, 78000, 0], [80, 78000, 86000], [100, 86000, 0], ['Yellow Alarm', 91000, 96000], ['Red Alarm', 96000, 102000], ['Fire Shut Alarm', 102000, 0]], + } + +temp_policy_AFO = { + 0: [[60, 0, 49000], [60, 49000, 55000], [80, 55000, 0], [80, 55000, 62000], [100, 62000, 0], ['Yellow Alarm', 68000, 74000], ['Red Alarm', 74000, 78000], ['Fire Shut Alarm', 78000, 0]], + 1: [[60, 0, 55000], [60, 55000, 60000], [80, 60000, 0], [80, 60000, 65000], [100, 65000, 0], ['Yellow Alarm', 70000, 76000], ['Red Alarm', 76000, 80000], ['Fire Shut Alarm', 80000, 0]], + 2: [[60, 0, 34000], [60, 34000, 40000], [80, 40000, 0], [80, 40000, 47000], [100, 47000, 0], ['Yellow Alarm', 54000, 60000], ['Red Alarm', 60000, 64000], ['Fire Shut Alarm', 64000, 0]], + 3: [[60, 0, 36000], [60, 36000, 41000], [80, 41000, 0], [80, 41000, 47000], [100, 47000, 0], ['Yellow Alarm', 54000, 60000], ['Red Alarm', 60000, 64000], ['Fire Shut Alarm', 64000, 0]], + 4: [[60, 0, 39000], [60, 39000, 45000], [80, 45000, 0], [80, 45000, 52000], [100, 52000, 0], ['Yellow Alarm', 59000, 65000], ['Red Alarm', 65000, 69000], ['Fire Shut Alarm', 69000, 0]], + 5: [[60, 0, 37000], [60, 37000, 43000], [80, 43000, 0], [80, 43000, 50000], [100, 50000, 0], ['Yellow Alarm', 57000, 63000], ['Red Alarm', 63000, 67000], ['Fire Shut Alarm', 67000, 0]], + 6: [[60, 0, 70000], [60, 70000, 78000], [80, 78000, 0], [80, 78000, 86000], [100, 86000, 0], ['Yellow Alarm', 91000, 96000], ['Red Alarm', 96000, 102000], ['Fire Shut Alarm', 102000, 0]], + } + +class QFX5210_FanUtil(object): + """QFX5210 Platform FanUtil class""" + + FANBASE_VAL_PATH = '/sys/bus/i2c/devices/17-0068/{0}' + FAN_DUTY_PATH = '/sys/bus/i2c/devices/17-0068/fan_duty_cycle_percentage' + + def __init__(self): + fan_path = self.FANBASE_VAL_PATH + + def get_fan_duty_cycle(self): + try: + val_file = open(self.FAN_DUTY_PATH) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = val_file.readline().rstrip() + val_file.close() + + return int(content) + + def set_fan_duty_cycle(self, val): + + try: + fan_file = open(self.FAN_DUTY_PATH, 'r+') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + fan_file.write(str(val)) + fan_file.close() + return True + +class QFX5210_ThermalUtil(object): + """QFX5210 Platform ThermalUtil class""" + + SENSOR_NUM_ON_MAIN_BOARD = 6 + SENSOR_CORETEMP_NUM_ON_MAIN_BOARD = 7 + CORETEMP_NUM_ON_MAIN_BOARD = 5 + THERMAL_NUM_RANGE = 8 + SENSOR_NUM_1_IDX = 1 + SENSORS_PATH = '/sys/bus/i2c/devices/{0}-00{1}/hwmon/hwmon*/temp1_input' + CORETEMP_PATH = '/sys/bus/platform/devices/coretemp.0/hwmon/hwmon1/temp{0}_input' + ALARM_LED_PATH = '/sys/class/leds/alarm/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 = [ + ['18', '48'], + ['18', '49'], + ['18', '4a'], + ['18', '4b'], + ['17', '4d'], + ['17', '4e'], + ] + + _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+1] = 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_1_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. unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return int(content) + + + """ 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. unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return int(content) + + + def get_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] + + + """ Function opens the alarm LED file, reads the content from the file + and returns the value.This value indicates the Brigthness level. + The value of 1 = YELLOW ALARM + The value of 2 = RED ALARM + The value of 0 = NO ALARM """ + def get_alarm_led_brightness(self): + try: + val_file = open(self.ALARM_LED_PATH) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = val_file.readline().rstrip() + val_file.close() + return int(content) + + + """ Function takes the value to set in the alarm LED file as input. + Reads the content from the file and sets the value.This value indicates the Brigthness level. + The value of 1 = YELLOW ALARM + The value of 2 = RED ALARM + The value of 0 = NO ALARM """ + def set_alarm_led_brightness(self, val): + try: + val_file = open(self.ALARM_LED_PATH, 'r+') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + val_file.write(str(val)) + val_file.close() + return True + + + + """ Function is called periodically every 20 secs. It reads the 6 Temp sensors and 1 core Temp sensor and 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 """ + def getSensorTemp(self): + sum = 0 + global isPlatformAFI + global isFireThresholdReached + global FireThresholdSecsRemaining + #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], + 1: [0,0,0,0,0,0,0,0], + 2: [0,0,0,0,0,0,0,0], + 3: [0,0,0,0,0,0,0,0], + 4: [0,0,0,0,0,0,0,0], + 5: [0,0,0,0,0,0,0,0], + 6: [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 + logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown in %s seconds', firethr) + print "Fire Threshold reached: System is going to shutdown in %s seconds\n" % firethr + FireThresholdSecsRemaining = FireThresholdSecsRemaining - 20 + if (FireThresholdSecsRemaining == 20): + isFireThresholdReached == False + time.sleep(20) + cmd = "poweroff" + returned_value = os.system(cmd) + + for x in range(self.SENSOR_CORETEMP_NUM_ON_MAIN_BOARD): + if x < self.SENSOR_NUM_ON_MAIN_BOARD: + value = self._get_sensor_node_val(x+1) + else: + value = self.get_coretempValue() + + # 60% Duty Cycle for AFO and 70% Duty Cycle for AFI + if value > temp_policy[x][0][1] and value <= temp_policy[x][0][2]: + SensorFlag[x][0] = True + + # 60% Prev Duty Cycle for AFO and 70% Prev Duty Cycle for AFI + elif value > temp_policy[x][1][1] and value < temp_policy[x][1][2]: + SensorFlag[x][1] = True + + # 80% Duty Cycle + elif value == temp_policy[x][2][1]: + SensorFlag[x][2] = True + + #80% Prev Duty Cycle + elif value > temp_policy[x][3][1] and value < temp_policy[x][3][2]: + SensorFlag[x][3] = True + + #100% Duty Cycle + elif value >= temp_policy[x][4][1]: + SensorFlag[x][4] = True + + else: + pass + + # Yellow Alarm + if value >= temp_policy[x][5][1] and value < temp_policy[x][5][2]: + SensorFlag[x][5] = True + + # Red Alarm + elif value >= temp_policy[x][6][1] and value < temp_policy[x][6][2]: + SensorFlag[x][6] = True + + # Fire Shut down + elif value >= temp_policy[x][7][1]: + SensorFlag[x][7] = True + + fan = QFX5210_FanUtil() + # CHECK IF ANY TEMPERATURE SENSORS HAS SET FIRE SHUTDOWN FLAG + if 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]: + isFireThresholdReached = True + logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown in 120 seconds') + print "CRITICAL: Fire Threshold reached: System is going to shutdown in 120 seconds\n" + value = self.get_alarm_led_brightness() + if ( value > 0): + self.set_alarm_led_brightness(0) + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 'RED' ALARM FLAG, IF YES, SET THE ALARM LED TO 'RED' + 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]: + self.set_alarm_led_brightness(2) + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 'YELLOW' ALARM FLAG, IF YES, SET THE ALARM LED TO 'YELLOW' + 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]: + self.set_alarm_led_brightness(1) + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 100% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 100% + 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]: + fan.set_fan_duty_cycle(100) + value = self.get_alarm_led_brightness() + if ( value > 0): + self.set_alarm_led_brightness(0) + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 80% DUTY CYCLE PREV FLAG, IF YES, SET THE FAN DUTY CYCLE TO 80% + 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]: + fan.set_fan_duty_cycle(80) + value = self.get_alarm_led_brightness() + if ( value > 0): + self.set_alarm_led_brightness(0) + + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 80% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 80% + 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]: + fan.set_fan_duty_cycle(80) + value = self.get_alarm_led_brightness() + if ( value > 0): + self.set_alarm_led_brightness(0) + + # FOR "AFO" Platform CHECK IF ANY TEMPERATURE SENSORS HAS SET 60% DUTY CYCLE PREV FLAG, IF YES, SET THE FAN DUTY CYCLE TO 60% + # FOR "AFI" Platform CHECK IF ANY TEMPERATURE SENSORS HAS SET 70% DUTY CYCLE PREV FLAG, IF YES, SET THE FAN DUTY CYCLE TO 70% + 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]: + if (isPlatformAFI == True): + fan.set_fan_duty_cycle(70) + else: + fan.set_fan_duty_cycle(60) + value = self.get_alarm_led_brightness() + if ( value > 0): + self.set_alarm_led_brightness(0) + + # FOR "AFO" Platform CHECK IF ANY TEMPERATURE SENSORS HAS SET 60% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 60% + # FOR "AFI" Platform CHECK IF ANY TEMPERATURE SENSORS HAS SET 70% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 70% + 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]: + if (isPlatformAFI == True): + fan.set_fan_duty_cycle(70) + else: + fan.set_fan_duty_cycle(60) + value = self.get_alarm_led_brightness() + if ( value > 0): + self.set_alarm_led_brightness(0) + + else: + pass + + + # RESET ALL THE SENSOR FLAGS + for x in range(self.SENSOR_CORETEMP_NUM_ON_MAIN_BOARD): + for y in range(self.THERMAL_NUM_RANGE): + SensorFlag[x][y] = 0 + + +class device_monitor(object): + + def __init__(self, log_file, log_level): + + global isPlatformAFI + global isFireThresholdReached + 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' + + """Needs a logger and a logger level.""" + # set up logging to file + logging.basicConfig( + filename=log_file, + filemode='w', + level=log_level, + format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', + datefmt='%H:%M:%S' + ) + + # set up logging to console + if log_level == logging.DEBUG: + console = logging.StreamHandler() + console.setLevel(log_level) + formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) + + import sonic_platform + platform = sonic_platform.platform.Platform() + chassis = platform.get_chassis() + fan_type = chassis.get_fan_type(FANTYPE_PATH) + + # 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 (fan_type == -1 or fan_type == 0): + if (fan_type == -1): + print "Error: unable to open sys file for fan handling, defaulting it to AFO" + isPlatformAFI = False + else: + isPlatformAFI = True + + isFireThresholdReached = False + + master_led_value = 1 + try: + masterLED_file = open(MASTER_LED_PATH, 'r+') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + masterLED_file.write(str(master_led_value)) + masterLED_file.close() + + system_led_value = 1 + try: + systemLED_file = open(SYSTEM_LED_PATH, 'r+') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + systemLED_file.write(str(system_led_value)) + systemLED_file.close() + pass + + def manage_device(self): + thermal = QFX5210_ThermalUtil() + thermal.getSensorTemp() + +def main(): + log_file = '%s.log' % FUNCTION_NAME + log_level = logging.DEBUG + + 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/qfx5210/utils/juniper_qfx5210_util.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py new file mode 100755 index 000000000000..b3f130af41c0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_util.py @@ -0,0 +1,697 @@ +#!/usr/bin/env python +# +# Modified to work on Juniper QFX5210 +# +# Based on accton_as7816_util.py +# +# Copyright (C) 2016 Accton Networks, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import binascii +import logging +import re +import time +import random +import optparse +from collections import namedtuple + + + + +PROJECT_NAME = 'qfx5210_64x' +version = '0.1.0' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +DEVICE_NO = {'led':4, 'fan':4,'thermal':6, 'psu':2, 'sfp':64} +FORCE = 0 +FUNCTION_NAME = '/var/log/juniper_qfx5210_util' + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + log_file = '%s.log' % FUNCTION_NAME + log_level = logging.DEBUG + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + 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: + print options + print args + print len(sys.argv) + # 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) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + device_traversal() + elif arg == 'sff': + if len(args)!=2: + show_eeprom_help() + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + show_eeprom_help() + else: + show_eeprom(args[1]) + return + elif arg == 'set': + if len(args)<3: + show_set_help() + else: + set_device(args[1:]) + return + else: + show_help() + + DisableWatchDogCmd = '/usr/sbin/i2cset -f -y 0 0x65 0x3 0x04' + # Disable watchdog + try: + os.system(DisableWatchDogCmd) + 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 + 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' + #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(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_set_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print cmd +" [led|sfp|fan]" + print " use \""+ cmd + " led 0-4 \" to set led color" + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-32 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + +def show_eeprom_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print " use \""+ cmd + " 1-32 \" to dump sfp# eeprom" + sys.exit(0) + +def my_log(txt): + if DEBUG == True: + print txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_check(): + ret, lsmod = log_os_system("lsmod| grep juniper", 0) + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + return True + + + +kos = [ +'modprobe i2c_dev', +'modprobe i2c_mux_pca954x force_deselect_on_exit=1', +'modprobe optoe', +'modprobe juniper_i2c_cpld' , +'modprobe ym2651y' , +'modprobe x86-64-juniper-qfx5210-64x-fan' , +'modprobe x86-64-juniper-qfx5210-64x-leds' , +'modprobe x86-64-juniper-qfx5210-64x-psu' ] + +def driver_install(): + global FORCE + status, output = log_os_system("depmod", 1) + for i in range(0,len(kos)): + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + +def driver_uninstall(): + global FORCE + for i in range(0,len(kos)): + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + +led_prefix ='/sys/class/leds/' +hwmon_types = {'led': ['alarm','system','master','beacon']} +hwmon_nodes = {'led': ['brightness'] } +hwmon_prefix ={'led': led_prefix} + +i2c_prefix = '/sys/bus/i2c/devices/' +i2c_bus = {'fan': ['17-0068'] , + 'thermal': ['18-0048','18-0049', '18-004a' , '18-004b', '17-004d', '17-004e'] , + 'psu': ['10-0053','9-0050'], + 'sfp': ['-0050']} +i2c_nodes = {'fan': ['present', 'front_speed_rpm', 'rear_speed_rpm'] , + 'thermal': ['hwmon/hwmon*/temp1_input'] , + 'psu': ['psu_present ', 'psu_power_good'] , + 'sfp': ['sfp_is_present ', 'module_present']} + +sfp_map = [37,38,39,40,42,41,44,43,33,34,35,36,45,46,47,48,49,50,51,52, + 61,62,63,64,53,54,55,56,57,58,59,60,69,70,71,72,77,78,79,80,65, + 66,67,68,73,74,75,76,85,86,87,88,31,32,29,30,81,82,83,84,25,26, + 27,28] + +mknod =[ +'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-2/new_device', +'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-2/new_device', +'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-2/new_device', +'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-2/new_device', +'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-2/new_device', +'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-2/new_device', +'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-2/new_device', +'echo 24c02 0x56 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo qfx5210_64x_psu1 0x53 > /sys/bus/i2c/devices/i2c-10/new_device', +'echo ym2851 0x5b > /sys/bus/i2c/devices/i2c-10/new_device', +'echo qfx5210_64x_psu2 0x50 > /sys/bus/i2c/devices/i2c-9/new_device', +'echo ym2851 0x58 > /sys/bus/i2c/devices/i2c-9/new_device', +'echo qfx5210_64x_fan 0x68 > /sys/bus/i2c/devices/i2c-17/new_device', +'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-18/new_device', +'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-18/new_device', +'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-18/new_device', +'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-18/new_device', +'echo lm75 0x4d > /sys/bus/i2c/devices/i2c-17/new_device', +'echo lm75 0x4e > /sys/bus/i2c/devices/i2c-17/new_device', +'echo cpld_qfx5210 0x60 > /sys/bus/i2c/devices/i2c-19/new_device', +'echo cpld_plain 0x62 > /sys/bus/i2c/devices/i2c-20/new_device', +'echo cpld_plain 0x64 > /sys/bus/i2c/devices/i2c-21/new_device', +'echo cpld_plain 0x66 > /sys/bus/i2c/devices/i2c-22/new_device', +'echo cpld_plain 0x65 > /sys/bus/i2c/devices/i2c-0/new_device 2>/dev/null' +] + +def i2c_order_check(): + return 0 + +def device_install(): + global FORCE + + for i in range(0,len(mknod)): + #for pca954x need times to built new i2c buses + if mknod[i].find('pca954') != -1: + time.sleep(1) + + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + + for i in range(0,len(sfp_map)): + path = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device" + status, output =log_os_system("echo optoe1 0x50 > " + path, 1) + if status: + print output + if FORCE == 0: + return status + status, output =log_os_system("echo Port"+str(i)+" > /sys/bus/i2c/devices/"+str(sfp_map[i])+"-0050/port_name", 1) + if status: + print output + if FORCE == 0: + return status + return + +def device_uninstall(): + global FORCE + + status, output =log_os_system("ls /sys/bus/i2c/devices/1-0076", 0) + + for i in range(0,len(sfp_map)): + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" + status, output =log_os_system("echo 0x50 > "+ target, 1) + if status: + print output + if FORCE == 0: + return status + + nodelist = mknod + + for i in range(len(nodelist)): + target = nodelist[-(i+1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + if status: + print output + if FORCE == 0: + return status + + return + +def system_ready(): + if driver_check() == False: + return False + if not device_exist(): + return False + return True + +def do_install(): + logging.info('Checking system....') + if driver_check() == False: + logging.info('No driver, installing....') + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" drivers detected...." + 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 do_uninstall(): + logging.info('Checking system....') + if not device_exist(): + print PROJECT_NAME.upper() +" has no device installed...." + else: + logging.info('Removing device....') + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_check()== False : + print PROJECT_NAME.upper() +" has no driver installed...." + else: + logging.info('Removing installed driver....') + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + +def devices_info(): + global DEVICE_NO + global ALL_DEVICE + global i2c_bus, hwmon_types + for key in DEVICE_NO: + ALL_DEVICE[key]= {} + for i in range(0,DEVICE_NO[key]): + ALL_DEVICE[key][key+str(i+1)] = [] + + for key in i2c_bus: + buses = i2c_bus[key] + nodes = i2c_nodes[key] + for i in range(0,len(buses)): + for j in range(0,len(nodes)): + if 'fan' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + elif 'sfp' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + fmt = i2c_prefix+"19-0060/{0}_{1}" + path = fmt.format(nodes[j], k+1) + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + else: + node = key+str(i+1) + path = i2c_prefix+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + + for key in hwmon_types: + itypes = hwmon_types[key] + nodes = hwmon_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + #show dict all in the order + if DEBUG == True: + for i in sorted(ALL_DEVICE.keys()): + print(i+": ") + for j in sorted(ALL_DEVICE[i].keys()): + print(" "+j) + for k in (ALL_DEVICE[i][j]): + print(" "+" "+k) + return + +def show_eeprom(index): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + i = int(index)-1 + node = i2c_prefix+ str(sfp_map[i])+ i2c_bus['sfp'][0]+"/"+ 'eeprom' + # check if got hexdump command in current environment + ret, log = log_os_system("which hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) + if len(log): + hex_cmd = 'hexdump' + elif len(log2): + hex_cmd = ' busybox hexdump' + else: + log = 'Failed : no hexdump cmd!!' + logging.info(log) + print log + return 1 + + print node + ":" + ret, log = log_os_system(hex_cmd +" -C "+node, 1) + if ret==0: + print log + else: + print "**********device no found**********" + return + +def set_device(args): + global DEVICE_NO + global ALL_DEVICE + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + + if args[0]=='led': + if int(args[1])>4: + show_set_help() + return + #print ALL_DEVICE['led'] + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): + ret, log = log_os_system("echo "+args[1]+" >"+k, 1) + if ret: + return ret + elif args[0]=='fan': + if int(args[1])>100: + show_set_help() + return + #print ALL_DEVICE['fan'] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan'] ['fan1'][0] + node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage') + ret, log = log_os_system("cat "+ node, 1) + if ret==0: + print ("Previous fan duty: " + log.strip() +"%") + ret, log = log_os_system("echo "+args[1]+" >"+node, 1) + if ret==0: + print ("Current fan duty: " + args[1] +"%") + return ret + elif args[0]=='sfp': + if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: + show_set_help() + return + if len(args)<2: + show_set_help() + return + + if int(args[2])>1: + show_set_help() + return + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: + ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) + if ret: + return ret + + return + +#get digits inside a string. +#Ex: 31 for "sfp31" +def get_value(input): + digit = re.findall('\d+', input) + return int(digit[0]) + +def device_traversal(): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + for i in sorted(ALL_DEVICE.keys()): + print("============================================") + print(i.upper()+": ") + print("============================================") + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + print " "+j+":", + for k in (ALL_DEVICE[i][j]): + ret, log = log_os_system("cat "+k, 0) + func = k.split("/")[-1].strip() + func = re.sub(j+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) + if ret==0: + print func+"="+log+" ", + else: + print func+"="+"X"+" ", + print + print("----------------------------------------------------------------") + + + print + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"*0076", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0) + return not(ret1 or ret2) + +if __name__ == "__main__": + main() diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/platform_poweroff b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/platform_poweroff new file mode 100755 index 000000000000..27b23cff93ab --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/platform_poweroff @@ -0,0 +1,106 @@ +#!/usr/bin/env bash +# +# Name: platform_poweroff version: 1.0 +# +# Description: This file contains the implementation of qfx5210 poweroff +# sequences +# +# Copyright (c) 2019, Juniper Networks, Inc. +# All rights reserved. +# +# Notice and Disclaimer: This code is licensed to you under the GNU General +# Public License as published by the Free Software Foundation, version 2 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 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# 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. + +LOGFILE="/var/log/poweroff_log" +TIMESTAMP=`date "+%Y-%m-%d %H:%M:%S"` + +retry() +{ + local ret_value=0 + + if [ $# -ne 3 ]; then + echo 'usage: retry ""' + exit 1 + fi + retries=$1 + wait_retry=$2 + command=$3 + for i in `seq 1 $retries`; do + echo "$TIMESTAMP $command" >> $LOGFILE + $command + ret_value=$? + [ $ret_value -eq 0 ] && break + echo "$TIMESTAMP Error: Command Execution failed with $ret_value, waiting to retry..." >> $LOGFILE + sleep $wait_retry + done + return $ret_value +} + + +if [ -f /usr/sbin/i2cset ] && [ -f /usr/sbin/i2cget ]; then + #Check if the CPU CPLD address is present on the bus or not + #0x65 - Azurite CPU CPLD I2C Addr + retry 128 1 "i2cget -y 0 0x65 0x0" + ret_val=$? + if [ $ret_val -ne 0 ]; then + echo "$TIMESTAMP CPU CPLD I2C Addr is not accessible...Terminating the halt.." >> $LOGFILE + return $ret_value + fi + #Initing Halt condition + retry 128 1 "/usr/sbin/i2cset -f -y 0 0x65 0x14 0x00" + ret_val=$? + if [ $ret_val -ne 0 ]; then + echo "$TIMESTAMP Halt Init Failed..." >> $LOGFILE + return $ret_value + fi + #Enable 0x77 MUX's First channel to access 0x76 MUX + retry 128 1 "/usr/sbin/i2cset -f -y 0 0x77 0 0x01" + ret_val=$? + if [ $ret_val -ne 0 ]; then + echo "$TIMESTAMP Mux Level1 enabling failed..." >> $LOGFILE + return $ret_value + fi + #Enable 0x76 MUX's Third channel to access Main Board CPLD @0x60 + retry 128 1 "/usr/sbin/i2cset -f -y 0 0x76 0 0x04" + ret_val=$? + if [ $ret_val -ne 0 ]; then + echo "$TIMESTAMP Mux Level2 enabling failed..." >> $LOGFILE + return $ret_value + fi + + sync + + echo "$TIMESTAMP System is going to Halt now ........" | tee $LOGFILE + #Sleeping for sometime, so that Print can reach to logger + sleep 1 + #Asserting the Halt on Azurite + retry 128 1 "/usr/sbin/i2cset -f -y 0 0x60 0x24 0x00" + ret_val=$? + if [ $ret_val -ne 0 ]; then + echo "$TIMESTAMP Halt command execution failed...Terminating the halt.." | tee $LOGFILE + return $ret_value + fi +fi diff --git a/platform/broadcom/sonic-platform-modules-quanta/debian/changelog b/platform/broadcom/sonic-platform-modules-quanta/debian/changelog index 4bed63edf9cd..fe1cfa45490b 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/debian/changelog +++ b/platform/broadcom/sonic-platform-modules-quanta/debian/changelog @@ -25,3 +25,10 @@ sonic-quanta-platform-modules (1.0) unstable; urgency=low * Initial release -- Chih-Pei Chang Jonathan Tsai Thu, 4 Jan 2018 13:50:01 +0800 + +sonic-quanta-platform-modules (1.0) unstable; urgency=low + + * Add support for Quanta IX9-32X + * Initial release + + -- Jonathan Tsai Thu, 31 Jan 2019 13:09:01 +0800 diff --git a/platform/broadcom/sonic-platform-modules-quanta/debian/control b/platform/broadcom/sonic-platform-modules-quanta/debian/control index aea2a39d6ff3..f25b0d8e3c5b 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/debian/control +++ b/platform/broadcom/sonic-platform-modules-quanta/debian/control @@ -20,3 +20,7 @@ Description: kernel modules for platform devices such as psu, led, sfp Package: sonic-platform-quanta-ix8c-56x Architecture: amd64 Description: kernel modules for platform devices such as psu, led, sfp + +Package: sonic-platform-quanta-ix9-32x +Architecture: amd64 +Description: kernel modules for platform devices such as psu, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-quanta/debian/rules b/platform/broadcom/sonic-platform-modules-quanta/debian/rules index 8ceede79196b..46b9607135a8 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/debian/rules +++ b/platform/broadcom/sonic-platform-modules-quanta/debian/rules @@ -19,7 +19,7 @@ PACKAGE_PRE_NAME := sonic-platform-quanta KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= ix1b-32x ix7-32x ix8-56x ix8c-56x +MODULE_DIRS:= ix1b-32x ix7-32x ix8-56x ix8c-56x ix9-32x MODULE_DIR := modules UTILS_DIR := utils SERVICE_DIR := service diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/Makefile b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/Makefile index fd73f274ef53..48683c54a7bc 100755 --- a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/Makefile @@ -1,3 +1 @@ -obj-m:=qci_pmbus.o qci_cpld_qsfp28.o qci_platform_ix1b.o - - +obj-m:=qci_pmbus.o qci_cpld_qsfp28.o qci_platform_ix1b.o qci_hwmon_ix1b.o diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/pmbus.h b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/pmbus.h deleted file mode 100755 index fa9beb3eb60c..000000000000 --- a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/pmbus.h +++ /dev/null @@ -1,387 +0,0 @@ -/* - * pmbus.h - Common defines and structures for PMBus devices - * - * Copyright (c) 2010, 2011 Ericsson AB. - * Copyright (c) 2012 Guenter Roeck - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef PMBUS_H -#define PMBUS_H - -/* - * Registers - */ -#define PMBUS_PAGE 0x00 -#define PMBUS_OPERATION 0x01 -#define PMBUS_ON_OFF_CONFIG 0x02 -#define PMBUS_CLEAR_FAULTS 0x03 -#define PMBUS_PHASE 0x04 - -#define PMBUS_CAPABILITY 0x19 -#define PMBUS_QUERY 0x1A - -#define PMBUS_VOUT_MODE 0x20 -#define PMBUS_VOUT_COMMAND 0x21 -#define PMBUS_VOUT_TRIM 0x22 -#define PMBUS_VOUT_CAL_OFFSET 0x23 -#define PMBUS_VOUT_MAX 0x24 -#define PMBUS_VOUT_MARGIN_HIGH 0x25 -#define PMBUS_VOUT_MARGIN_LOW 0x26 -#define PMBUS_VOUT_TRANSITION_RATE 0x27 -#define PMBUS_VOUT_DROOP 0x28 -#define PMBUS_VOUT_SCALE_LOOP 0x29 -#define PMBUS_VOUT_SCALE_MONITOR 0x2A - -#define PMBUS_COEFFICIENTS 0x30 -#define PMBUS_POUT_MAX 0x31 - -#define PMBUS_FAN_CONFIG_12 0x3A -#define PMBUS_FAN_COMMAND_1 0x3B -#define PMBUS_FAN_COMMAND_2 0x3C -#define PMBUS_FAN_CONFIG_34 0x3D -#define PMBUS_FAN_COMMAND_3 0x3E -#define PMBUS_FAN_COMMAND_4 0x3F - -#define PMBUS_VOUT_OV_FAULT_LIMIT 0x40 -#define PMBUS_VOUT_OV_FAULT_RESPONSE 0x41 -#define PMBUS_VOUT_OV_WARN_LIMIT 0x42 -#define PMBUS_VOUT_UV_WARN_LIMIT 0x43 -#define PMBUS_VOUT_UV_FAULT_LIMIT 0x44 -#define PMBUS_VOUT_UV_FAULT_RESPONSE 0x45 -#define PMBUS_IOUT_OC_FAULT_LIMIT 0x46 -#define PMBUS_IOUT_OC_FAULT_RESPONSE 0x47 -#define PMBUS_IOUT_OC_LV_FAULT_LIMIT 0x48 -#define PMBUS_IOUT_OC_LV_FAULT_RESPONSE 0x49 -#define PMBUS_IOUT_OC_WARN_LIMIT 0x4A -#define PMBUS_IOUT_UC_FAULT_LIMIT 0x4B -#define PMBUS_IOUT_UC_FAULT_RESPONSE 0x4C - -#define PMBUS_OT_FAULT_LIMIT 0x4F -#define PMBUS_OT_FAULT_RESPONSE 0x50 -#define PMBUS_OT_WARN_LIMIT 0x51 -#define PMBUS_UT_WARN_LIMIT 0x52 -#define PMBUS_UT_FAULT_LIMIT 0x53 -#define PMBUS_UT_FAULT_RESPONSE 0x54 -#define PMBUS_VIN_OV_FAULT_LIMIT 0x55 -#define PMBUS_VIN_OV_FAULT_RESPONSE 0x56 -#define PMBUS_VIN_OV_WARN_LIMIT 0x57 -#define PMBUS_VIN_UV_WARN_LIMIT 0x58 -#define PMBUS_VIN_UV_FAULT_LIMIT 0x59 - -#define PMBUS_IIN_OC_FAULT_LIMIT 0x5B -#define PMBUS_IIN_OC_WARN_LIMIT 0x5D - -#define PMBUS_POUT_OP_FAULT_LIMIT 0x68 -#define PMBUS_POUT_OP_WARN_LIMIT 0x6A -#define PMBUS_PIN_OP_WARN_LIMIT 0x6B - -#define PMBUS_STATUS_BYTE 0x78 -#define PMBUS_STATUS_WORD 0x79 -#define PMBUS_STATUS_VOUT 0x7A -#define PMBUS_STATUS_IOUT 0x7B -#define PMBUS_STATUS_INPUT 0x7C -#define PMBUS_STATUS_TEMPERATURE 0x7D -#define PMBUS_STATUS_CML 0x7E -#define PMBUS_STATUS_OTHER 0x7F -#define PMBUS_STATUS_MFR_SPECIFIC 0x80 -#define PMBUS_STATUS_FAN_12 0x81 -#define PMBUS_STATUS_FAN_34 0x82 - -#define PMBUS_READ_VIN 0x88 -#define PMBUS_READ_IIN 0x89 -#define PMBUS_READ_VCAP 0x8A -#define PMBUS_READ_VOUT 0x8B -#define PMBUS_READ_IOUT 0x8C -#define PMBUS_READ_TEMPERATURE_1 0x8D -#define PMBUS_READ_TEMPERATURE_2 0x8E -#define PMBUS_READ_TEMPERATURE_3 0x8F -#define PMBUS_READ_FAN_SPEED_1 0x90 -#define PMBUS_READ_FAN_SPEED_2 0x91 -#define PMBUS_READ_FAN_SPEED_3 0x92 -#define PMBUS_READ_FAN_SPEED_4 0x93 -#define PMBUS_READ_DUTY_CYCLE 0x94 -#define PMBUS_READ_FREQUENCY 0x95 -#define PMBUS_READ_POUT 0x96 -#define PMBUS_READ_PIN 0x97 - -#define PMBUS_REVISION 0x98 -#define PMBUS_MFR_ID 0x99 -#define PMBUS_MFR_MODEL 0x9A -#define PMBUS_MFR_REVISION 0x9B -#define PMBUS_MFR_LOCATION 0x9C -#define PMBUS_MFR_DATE 0x9D -#define PMBUS_MFR_SERIAL 0x9E - -/* - * Virtual registers. - * Useful to support attributes which are not supported by standard PMBus - * registers but exist as manufacturer specific registers on individual chips. - * Must be mapped to real registers in device specific code. - * - * Semantics: - * Virtual registers are all word size. - * READ registers are read-only; writes are either ignored or return an error. - * RESET registers are read/write. Reading reset registers returns zero - * (used for detection), writing any value causes the associated history to be - * reset. - * Virtual registers have to be handled in device specific driver code. Chip - * driver code returns non-negative register values if a virtual register is - * supported, or a negative error code if not. The chip driver may return - * -ENODATA or any other error code in this case, though an error code other - * than -ENODATA is handled more efficiently and thus preferred. Either case, - * the calling PMBus core code will abort if the chip driver returns an error - * code when reading or writing virtual registers. - */ -#define PMBUS_VIRT_BASE 0x100 -#define PMBUS_VIRT_READ_TEMP_AVG (PMBUS_VIRT_BASE + 0) -#define PMBUS_VIRT_READ_TEMP_MIN (PMBUS_VIRT_BASE + 1) -#define PMBUS_VIRT_READ_TEMP_MAX (PMBUS_VIRT_BASE + 2) -#define PMBUS_VIRT_RESET_TEMP_HISTORY (PMBUS_VIRT_BASE + 3) -#define PMBUS_VIRT_READ_VIN_AVG (PMBUS_VIRT_BASE + 4) -#define PMBUS_VIRT_READ_VIN_MIN (PMBUS_VIRT_BASE + 5) -#define PMBUS_VIRT_READ_VIN_MAX (PMBUS_VIRT_BASE + 6) -#define PMBUS_VIRT_RESET_VIN_HISTORY (PMBUS_VIRT_BASE + 7) -#define PMBUS_VIRT_READ_IIN_AVG (PMBUS_VIRT_BASE + 8) -#define PMBUS_VIRT_READ_IIN_MIN (PMBUS_VIRT_BASE + 9) -#define PMBUS_VIRT_READ_IIN_MAX (PMBUS_VIRT_BASE + 10) -#define PMBUS_VIRT_RESET_IIN_HISTORY (PMBUS_VIRT_BASE + 11) -#define PMBUS_VIRT_READ_PIN_AVG (PMBUS_VIRT_BASE + 12) -#define PMBUS_VIRT_READ_PIN_MAX (PMBUS_VIRT_BASE + 13) -#define PMBUS_VIRT_RESET_PIN_HISTORY (PMBUS_VIRT_BASE + 14) -#define PMBUS_VIRT_READ_POUT_AVG (PMBUS_VIRT_BASE + 15) -#define PMBUS_VIRT_READ_POUT_MAX (PMBUS_VIRT_BASE + 16) -#define PMBUS_VIRT_RESET_POUT_HISTORY (PMBUS_VIRT_BASE + 17) -#define PMBUS_VIRT_READ_VOUT_AVG (PMBUS_VIRT_BASE + 18) -#define PMBUS_VIRT_READ_VOUT_MIN (PMBUS_VIRT_BASE + 19) -#define PMBUS_VIRT_READ_VOUT_MAX (PMBUS_VIRT_BASE + 20) -#define PMBUS_VIRT_RESET_VOUT_HISTORY (PMBUS_VIRT_BASE + 21) -#define PMBUS_VIRT_READ_IOUT_AVG (PMBUS_VIRT_BASE + 22) -#define PMBUS_VIRT_READ_IOUT_MIN (PMBUS_VIRT_BASE + 23) -#define PMBUS_VIRT_READ_IOUT_MAX (PMBUS_VIRT_BASE + 24) -#define PMBUS_VIRT_RESET_IOUT_HISTORY (PMBUS_VIRT_BASE + 25) -#define PMBUS_VIRT_READ_TEMP2_AVG (PMBUS_VIRT_BASE + 26) -#define PMBUS_VIRT_READ_TEMP2_MIN (PMBUS_VIRT_BASE + 27) -#define PMBUS_VIRT_READ_TEMP2_MAX (PMBUS_VIRT_BASE + 28) -#define PMBUS_VIRT_RESET_TEMP2_HISTORY (PMBUS_VIRT_BASE + 29) - -#define PMBUS_VIRT_READ_VMON (PMBUS_VIRT_BASE + 30) -#define PMBUS_VIRT_VMON_UV_WARN_LIMIT (PMBUS_VIRT_BASE + 31) -#define PMBUS_VIRT_VMON_OV_WARN_LIMIT (PMBUS_VIRT_BASE + 32) -#define PMBUS_VIRT_VMON_UV_FAULT_LIMIT (PMBUS_VIRT_BASE + 33) -#define PMBUS_VIRT_VMON_OV_FAULT_LIMIT (PMBUS_VIRT_BASE + 34) -#define PMBUS_VIRT_STATUS_VMON (PMBUS_VIRT_BASE + 35) - -/* - * CAPABILITY - */ -#define PB_CAPABILITY_SMBALERT (1<<4) -#define PB_CAPABILITY_ERROR_CHECK (1<<7) - -/* - * VOUT_MODE - */ -#define PB_VOUT_MODE_MODE_MASK 0xe0 -#define PB_VOUT_MODE_PARAM_MASK 0x1f - -#define PB_VOUT_MODE_LINEAR 0x00 -#define PB_VOUT_MODE_VID 0x20 -#define PB_VOUT_MODE_DIRECT 0x40 - -/* - * Fan configuration - */ -#define PB_FAN_2_PULSE_MASK ((1 << 0) | (1 << 1)) -#define PB_FAN_2_RPM (1 << 2) -#define PB_FAN_2_INSTALLED (1 << 3) -#define PB_FAN_1_PULSE_MASK ((1 << 4) | (1 << 5)) -#define PB_FAN_1_RPM (1 << 6) -#define PB_FAN_1_INSTALLED (1 << 7) - -/* - * STATUS_BYTE, STATUS_WORD (lower) - */ -#define PB_STATUS_NONE_ABOVE (1<<0) -#define PB_STATUS_CML (1<<1) -#define PB_STATUS_TEMPERATURE (1<<2) -#define PB_STATUS_VIN_UV (1<<3) -#define PB_STATUS_IOUT_OC (1<<4) -#define PB_STATUS_VOUT_OV (1<<5) -#define PB_STATUS_OFF (1<<6) -#define PB_STATUS_BUSY (1<<7) - -/* - * STATUS_WORD (upper) - */ -#define PB_STATUS_UNKNOWN (1<<8) -#define PB_STATUS_OTHER (1<<9) -#define PB_STATUS_FANS (1<<10) -#define PB_STATUS_POWER_GOOD_N (1<<11) -#define PB_STATUS_WORD_MFR (1<<12) -#define PB_STATUS_INPUT (1<<13) -#define PB_STATUS_IOUT_POUT (1<<14) -#define PB_STATUS_VOUT (1<<15) - -/* - * STATUS_IOUT - */ -#define PB_POUT_OP_WARNING (1<<0) -#define PB_POUT_OP_FAULT (1<<1) -#define PB_POWER_LIMITING (1<<2) -#define PB_CURRENT_SHARE_FAULT (1<<3) -#define PB_IOUT_UC_FAULT (1<<4) -#define PB_IOUT_OC_WARNING (1<<5) -#define PB_IOUT_OC_LV_FAULT (1<<6) -#define PB_IOUT_OC_FAULT (1<<7) - -/* - * STATUS_VOUT, STATUS_INPUT - */ -#define PB_VOLTAGE_UV_FAULT (1<<4) -#define PB_VOLTAGE_UV_WARNING (1<<5) -#define PB_VOLTAGE_OV_WARNING (1<<6) -#define PB_VOLTAGE_OV_FAULT (1<<7) - -/* - * STATUS_INPUT - */ -#define PB_PIN_OP_WARNING (1<<0) -#define PB_IIN_OC_WARNING (1<<1) -#define PB_IIN_OC_FAULT (1<<2) - -/* - * STATUS_TEMPERATURE - */ -#define PB_TEMP_UT_FAULT (1<<4) -#define PB_TEMP_UT_WARNING (1<<5) -#define PB_TEMP_OT_WARNING (1<<6) -#define PB_TEMP_OT_FAULT (1<<7) - -/* - * STATUS_FAN - */ -#define PB_FAN_AIRFLOW_WARNING (1<<0) -#define PB_FAN_AIRFLOW_FAULT (1<<1) -#define PB_FAN_FAN2_SPEED_OVERRIDE (1<<2) -#define PB_FAN_FAN1_SPEED_OVERRIDE (1<<3) -#define PB_FAN_FAN2_WARNING (1<<4) -#define PB_FAN_FAN1_WARNING (1<<5) -#define PB_FAN_FAN2_FAULT (1<<6) -#define PB_FAN_FAN1_FAULT (1<<7) - -/* - * CML_FAULT_STATUS - */ -#define PB_CML_FAULT_OTHER_MEM_LOGIC (1<<0) -#define PB_CML_FAULT_OTHER_COMM (1<<1) -#define PB_CML_FAULT_PROCESSOR (1<<3) -#define PB_CML_FAULT_MEMORY (1<<4) -#define PB_CML_FAULT_PACKET_ERROR (1<<5) -#define PB_CML_FAULT_INVALID_DATA (1<<6) -#define PB_CML_FAULT_INVALID_COMMAND (1<<7) - -enum pmbus_sensor_classes { - PSC_VOLTAGE_IN = 0, - PSC_VOLTAGE_OUT, - PSC_CURRENT_IN, - PSC_CURRENT_OUT, - PSC_POWER, - PSC_TEMPERATURE, - PSC_FAN, - PSC_NUM_CLASSES /* Number of power sensor classes */ -}; - -#define PMBUS_PAGES 32 /* Per PMBus specification */ - -/* Functionality bit mask */ -#define PMBUS_HAVE_VIN (1 << 0) -#define PMBUS_HAVE_VCAP (1 << 1) -#define PMBUS_HAVE_VOUT (1 << 2) -#define PMBUS_HAVE_IIN (1 << 3) -#define PMBUS_HAVE_IOUT (1 << 4) -#define PMBUS_HAVE_PIN (1 << 5) -#define PMBUS_HAVE_POUT (1 << 6) -#define PMBUS_HAVE_FAN12 (1 << 7) -#define PMBUS_HAVE_FAN34 (1 << 8) -#define PMBUS_HAVE_TEMP (1 << 9) -#define PMBUS_HAVE_TEMP2 (1 << 10) -#define PMBUS_HAVE_TEMP3 (1 << 11) -#define PMBUS_HAVE_STATUS_VOUT (1 << 12) -#define PMBUS_HAVE_STATUS_IOUT (1 << 13) -#define PMBUS_HAVE_STATUS_INPUT (1 << 14) -#define PMBUS_HAVE_STATUS_TEMP (1 << 15) -#define PMBUS_HAVE_STATUS_FAN12 (1 << 16) -#define PMBUS_HAVE_STATUS_FAN34 (1 << 17) -#define PMBUS_HAVE_VMON (1 << 18) -#define PMBUS_HAVE_STATUS_VMON (1 << 19) - -enum pmbus_data_format { linear = 0, direct, vid }; - -struct pmbus_driver_info { - int pages; /* Total number of pages */ - enum pmbus_data_format format[PSC_NUM_CLASSES]; - /* - * Support one set of coefficients for each sensor type - * Used for chips providing data in direct mode. - */ - int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */ - int b[PSC_NUM_CLASSES]; /* offset */ - int R[PSC_NUM_CLASSES]; /* exponent */ - - u32 func[PMBUS_PAGES]; /* Functionality, per page */ - /* - * The following functions map manufacturing specific register values - * to PMBus standard register values. Specify only if mapping is - * necessary. - * Functions return the register value (read) or zero (write) if - * successful. A return value of -ENODATA indicates that there is no - * manufacturer specific register, but that a standard PMBus register - * may exist. Any other negative return value indicates that the - * register does not exist, and that no attempt should be made to read - * the standard register. - */ - int (*read_byte_data)(struct i2c_client *client, int page, int reg); - int (*read_word_data)(struct i2c_client *client, int page, int reg); - int (*write_word_data)(struct i2c_client *client, int page, int reg, - u16 word); - int (*write_byte)(struct i2c_client *client, int page, u8 value); - /* - * The identify function determines supported PMBus functionality. - * This function is only necessary if a chip driver supports multiple - * chips, and the chip functionality is not pre-determined. - */ - int (*identify)(struct i2c_client *client, - struct pmbus_driver_info *info); -}; - -/* Function declarations */ - -void pmbus_clear_cache(struct i2c_client *client); -int pmbus_set_page(struct i2c_client *client, u8 page); -int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg); -int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word); -int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg); -int pmbus_write_byte(struct i2c_client *client, int page, u8 value); -void pmbus_clear_faults(struct i2c_client *client); -bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg); -bool pmbus_check_word_register(struct i2c_client *client, int page, int reg); -int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, - struct pmbus_driver_info *info); -int pmbus_do_remove(struct i2c_client *client); -const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client - *client); - -#endif /* PMBUS_H */ diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_hwmon_ix1b.c b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_hwmon_ix1b.c new file mode 100644 index 000000000000..eb730cb28d0e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_hwmon_ix1b.c @@ -0,0 +1,425 @@ +/* + * A hwmon driver for Cypress PSoC fan controller and thermal sensor + * + * This PSoC is a specific customize design only for Quanta Switch + * This driver is also monitoring pca9555 which is related to + * RPSU detection and LED controll in front panel. Instead a standalone + * driver, it should be combined with gpio lib to work correctly. + * + * Copyright (C) 2014 Quanta Inc. + * + * Author: Luffy Cheng + * + * Based on: + * adt7470.c from Darrick J. Wong + * Copyright (C) 2007 IBM + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define QUANTA_IX1_PSU_GPIO_PSU1_PRSNT_N 16 +#define QUANTA_IX1_PSU_GPIO_PSU1_PWRGD 17 +#define QUANTA_IX1_PSU_GPIO_PSU2_PRSNT_N 19 +#define QUANTA_IX1_PSU_GPIO_PSU2_PWRGD 20 + +#define QUANTA_IX1_FAN_GPIO_FAN1_PRSNT_N 36 +#define QUANTA_IX1_FAN_GPIO_FAN2_PRSNT_N 37 +#define QUANTA_IX1_FAN_GPIO_FAN3_PRSNT_N 38 +#define QUANTA_IX1_FAN_GPIO_FAN4_PRSNT_N 39 + +#define AUTO_UPDATE_INTERVAL 10000 + +enum psu_nr { + PSU1 = 0, + PSU2 +}; + +enum fan_nr { + FAN1 = 0, + FAN2, + FAN3, + FAN4, +}; + +enum led_color { + LED_RED = 1, + LED_GREEN, + LED_COLOR_OFF +}; + +int hwmon_enable = 1; + +struct qci_hwmon_data { + struct device *hwmon_dev; + struct task_struct *auto_update; + struct completion auto_update_stop; + unsigned int auto_update_interval; + struct attribute_group attrs; + +}; + +static void simple_atoi(const char *buf, int *output_val) +{ + int negative = 0; + + if (buf[0] == '-') + { + negative = 1; + buf++; + } + + while (*buf >= '0' && *buf <= '9') { + *output_val = *output_val * 10 + *buf - '0'; + buf++; + } + + if (negative) + *output_val = 0 - *output_val; +} + +int read_gpio_file(int gpio) +{ + struct file *fp; + char buffer[512], file_path[255]; + int offset = 0; + int ret; + + /*open the file in read mode*/ + sprintf(file_path, "/sys/class/gpio/gpio%d/value", gpio); + fp = filp_open(file_path, O_RDONLY, 0); + if (IS_ERR(fp)) { + printk("Cannot open the file %ld\n", PTR_ERR(fp)); + return -1; + } + + /*Read the data to the end of the file*/ + while (1) { + ret = kernel_read(fp, offset, buffer, 512); + if (ret > 0) { + offset += ret; + } + else { + break; + } + } + + filp_close(fp, NULL); + + simple_atoi(buffer, &ret); + + return ret; +} + +static ssize_t get_hwmon_status(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + return sprintf(buf, "%d\n", hwmon_enable); +} + +static ssize_t set_hwmon_status(struct device *dev, + struct device_attribute *devattr, const char *buf, size_t count) +{ + long enable; + + if (kstrtol(buf, 0, &enable)) + return -EINVAL; + + if ((enable != 1) && (enable != 0)) + return -EINVAL; + + hwmon_enable = enable; + + return count; +} + +static u8 read_fan_present(u8 fan_nr) +{ + u8 value = 0; + + if (fan_nr == PSU1) + value = read_gpio_file(QUANTA_IX1_FAN_GPIO_FAN1_PRSNT_N); + else if (fan_nr == FAN2) + value = read_gpio_file(QUANTA_IX1_FAN_GPIO_FAN2_PRSNT_N); + else if (fan_nr == FAN3) + value = read_gpio_file(QUANTA_IX1_FAN_GPIO_FAN3_PRSNT_N); + else if (fan_nr == FAN4) + value = read_gpio_file(QUANTA_IX1_FAN_GPIO_FAN4_PRSNT_N); + else + return -1; + + return value; +} + +static u8 read_psu_present(u8 psu_nr) +{ + u8 value = 0; + + if (psu_nr == PSU1) + value = read_gpio_file(QUANTA_IX1_PSU_GPIO_PSU1_PRSNT_N); + else if (psu_nr == PSU2) + value = read_gpio_file(QUANTA_IX1_PSU_GPIO_PSU2_PRSNT_N); + else + return -1; + + return value; +} + +static u8 read_psu_AC_good(u8 psu_nr) +{ + u8 value = 0; + + if (psu_nr == PSU1) + value = read_gpio_file(QUANTA_IX1_PSU_GPIO_PSU1_PWRGD); + else if (psu_nr == PSU2) + value = read_gpio_file(QUANTA_IX1_PSU_GPIO_PSU2_PWRGD); + else + return -1; + + return value; +} + +static u8 front_led_set(char *name, char *value) +{ + struct file *fp; + char file_path[255]; + int ret; + mm_segment_t oldfs; + + sprintf(file_path, "/sys/class/leds/%s/brightness", name); + fp = filp_open(file_path, O_RDWR | O_CREAT, 0644); + + if (IS_ERR(fp)) { + printk("Cannot open the file %ld\n", PTR_ERR(fp)); + return -1; + } + + oldfs = get_fs(); + set_fs(get_ds()); + + ret = vfs_write(fp, value, sizeof(value), &fp->f_pos); + + set_fs(oldfs); + + filp_close(fp, NULL); + + return 0; +} + +static u8 update_led(u8 *fan_status, u8 *psu_status) +{ + u8 i = 0, fan_color = LED_GREEN; + + // Update FAN front LED + for (i = 0; i < 4; i++) + { + if (fan_status[i] == 1) + { + fan_color = LED_RED; + front_led_set("front_led_fan_red", "1"); + front_led_set("front_led_fan_green", "0"); + break; + } + } + + if (fan_color == LED_GREEN) + { + front_led_set("front_led_fan_red", "0"); + front_led_set("front_led_fan_green", "1"); + } + + // Update PSU1 front LED + if ((psu_status[0] == 0) && (psu_status[2] == 1)) + { + front_led_set("front_led_psu1_green", "1"); + front_led_set("front_led_psu1_red", "0"); + } + else if (psu_status[0] == 1) + { + front_led_set("front_led_psu1_green", "0"); + front_led_set("front_led_psu1_red", "0"); + } + else + { + front_led_set("front_led_psu1_green", "0"); + front_led_set("front_led_psu1_red", "1"); + } + + // Update PSU2 front LED + if ((psu_status[1] == 0) && (psu_status[3] == 1)) + { + front_led_set("front_led_psu2_green", "1"); + front_led_set("front_led_psu2_red", "0"); + } + else if (psu_status[1] == 1) + { + front_led_set("front_led_psu2_green", "0"); + front_led_set("front_led_psu2_red", "0"); + } + else + { + front_led_set("front_led_psu2_green", "0"); + front_led_set("front_led_psu2_red", "1"); + } + + return 0; +} + +static int led_update_thread(void *p) +{ + struct platform_device *pdev = p; + struct qci_hwmon_data *data = platform_get_drvdata(pdev); + + u8 i = 0; + u8 psu_status[4] = {0}; // {PSU1-2 present, PSU1-2 AC good} + u8 fan_status[4] = {0}; // {FAN1-4 present} + + while (!kthread_should_stop()) { + + if (hwmon_enable) + { + for (i = 0; i < 4; i++) + { + fan_status[i] = read_fan_present(i); + } + + for (i = 0; i < 2; i++) + { + psu_status[i] = read_psu_present(i); + psu_status[i+2] = read_psu_AC_good(i); + } + + update_led(fan_status, psu_status); + } + + if (kthread_should_stop()) + break; + msleep_interruptible(data->auto_update_interval); + } + + complete_all(&data->auto_update_stop); + return 0; +} + +static DEVICE_ATTR(hwmon_status, S_IWUSR | S_IRUGO, get_hwmon_status, set_hwmon_status); + +static struct attribute *qci_hwmon_attr[] = { + + &dev_attr_hwmon_status.attr, + + NULL +}; + +static int qci_hwmon_probe(struct platform_device *pdev) +{ + struct qci_hwmon_data *data; + int err; + + data = devm_kzalloc(&pdev->dev, sizeof(struct qci_hwmon_data), + GFP_KERNEL); + if (!data) + { + return -ENOMEM; + } + + data->auto_update_interval = AUTO_UPDATE_INTERVAL; + data->attrs.attrs = qci_hwmon_attr; + + platform_set_drvdata(pdev, data); + + dev_info(&pdev->dev, "%s device found\n", pdev->name); + + data->hwmon_dev = hwmon_device_register(&pdev->dev); + if (IS_ERR(data->hwmon_dev)) { + err = PTR_ERR(data->hwmon_dev); + } + + err = sysfs_create_group(&pdev->dev.kobj, &data->attrs); + if (err) + return err; + + init_completion(&data->auto_update_stop); + data->auto_update = kthread_run(led_update_thread, pdev, + dev_name(data->hwmon_dev)); + if (IS_ERR(data->auto_update)) { + err = PTR_ERR(data->auto_update); + goto exit_unregister; + } + + return 0; + +exit_unregister: + hwmon_device_unregister(data->hwmon_dev); + return err; +} + +static int qci_hwmon_remove(struct platform_device *pdev) +{ + struct qci_hwmon_data *data = platform_get_drvdata(pdev); + + kthread_stop(data->auto_update); + wait_for_completion(&data->auto_update_stop); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&pdev->dev.kobj, &data->attrs); + return 0; +} + +static struct platform_driver qci_hwmon_driver = { + .probe = qci_hwmon_probe, + .remove = qci_hwmon_remove, + .driver = { + .name = "qci-hwmon", + .owner = THIS_MODULE, + }, +}; + +static int __init qci_hwmon_init(void) +{ + platform_driver_register(&qci_hwmon_driver); + + return 0; +} + +static void __exit qci_hwmon_exit(void) +{ + platform_driver_unregister(&qci_hwmon_driver); +} + +module_init(qci_hwmon_init); +module_exit(qci_hwmon_exit); + +MODULE_AUTHOR("Quanta Computer Inc."); +MODULE_DESCRIPTION("Quanta Switch Hardware Monitor driver"); +MODULE_LICENSE("GPL"); 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 old mode 100755 new mode 100644 index f783c88fb9a1..925b46256cea --- 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 @@ -179,67 +179,67 @@ static struct pca953x_platform_data pca9555ID_data = { static struct i2c_board_info ix1b_i2c_devices[] = { { - I2C_BOARD_INFO("pca9546", 0x77), + I2C_BOARD_INFO("pca9546", 0x77), // 0 .platform_data = &pca9546_1_data, }, { - I2C_BOARD_INFO("pca9546", 0x72), + I2C_BOARD_INFO("pca9546", 0x72), // 1 .platform_data = &pca9546_2_data, }, { - I2C_BOARD_INFO("pca9555", 0x26), + I2C_BOARD_INFO("pca9555", 0x26), // 2 .platform_data = &pca9555psu1_data, }, { - I2C_BOARD_INFO("24c02", 0x54), + I2C_BOARD_INFO("24c02", 0x54), // 3 }, { - I2C_BOARD_INFO("pca9548", 0x73), + I2C_BOARD_INFO("pca9548", 0x73), // 4 .platform_data = &pca9548sfp1_data, }, { - I2C_BOARD_INFO("pca9548", 0x74), + I2C_BOARD_INFO("pca9548", 0x74), // 5 .platform_data = &pca9548sfp2_data, }, { - I2C_BOARD_INFO("pca9548", 0x75), + I2C_BOARD_INFO("pca9548", 0x75), // 6 .platform_data = &pca9548sfp3_data, }, { - I2C_BOARD_INFO("pca9548", 0x76), + I2C_BOARD_INFO("pca9548", 0x76), // 7 .platform_data = &pca9548sfp4_data, }, { - I2C_BOARD_INFO("CPLD-QSFP28", 0x38), + I2C_BOARD_INFO("CPLD-QSFP28", 0x38), // 8 }, { - I2C_BOARD_INFO("CPLD-QSFP28", 0x39), + I2C_BOARD_INFO("CPLD-QSFP28", 0x39), // 9 }, { - I2C_BOARD_INFO("pca9555", 0x23), + I2C_BOARD_INFO("pca9555", 0x23), // 10 .platform_data = &pca9555ID_data, }, { - I2C_BOARD_INFO("pca9555", 0x25), + I2C_BOARD_INFO("pca9555", 0x25), // 11 .platform_data = &pca9555fan_data, }, { - I2C_BOARD_INFO("qci_pmbus_ix1b", 0x5f), + I2C_BOARD_INFO("qci_pmbus_ix1b", 0x5f), // 12 }, { - I2C_BOARD_INFO("qci_pmbus_ix1b", 0x59), + I2C_BOARD_INFO("qci_pmbus_ix1b", 0x59), // 13 }, #if defined(QUANTA_CPU_RGL) { - I2C_BOARD_INFO("pca9546", 0x71), + I2C_BOARD_INFO("pca9546", 0x71), // 14 .platform_data = &pca9546_cpu1_data, }, { - I2C_BOARD_INFO("pca9555", 0x20), + I2C_BOARD_INFO("pca9555", 0x20), // 15 .platform_data = &pca9555_cpuled_data, }, { - I2C_BOARD_INFO("24c02", 0x50), + I2C_BOARD_INFO("optoe1", 0x50), // 16 }, #endif }; @@ -347,6 +347,13 @@ static struct platform_device system_led_dev = { }, }; +static struct platform_device qci_hwmon_device = { + .name = "qci-hwmon", + .id = 0, + .dev = { + }, +}; + static struct platform_device *ix1b_device; struct gpio_led_data { @@ -390,68 +397,68 @@ static int __init ix1b_platform_init(void) goto fail_platform_device; adapter = i2c_get_adapter(0); - client = i2c_new_device(adapter, &ix1b_i2c_devices[0]); // pca9546_1 + client = i2c_new_device(adapter, &ix1b_i2c_devices[0]); // pca9546_1 - Address: 0x77 printk("[CC] NEW device pca9546_1\n"); - client = i2c_new_device(adapter, &ix1b_i2c_devices[1]); // pca9546_2 + client = i2c_new_device(adapter, &ix1b_i2c_devices[1]); // pca9546_2 - Address: 0x72 printk("[CC] NEW device pca9546_2\n"); #if defined(QUANTA_CPU_RGL) - client = i2c_new_device(adapter, &ix1b_i2c_devices[14]); // cpu pca9546_1 + client = i2c_new_device(adapter, &ix1b_i2c_devices[14]); // cpu pca9546_1 - Address: 0x71 printk("[CC] NEW device cpu pca9546_1\n"); #endif i2c_put_adapter(adapter); adapter = i2c_get_adapter(0x14); - client = i2c_new_device(adapter, &ix1b_i2c_devices[12]); // pmbus_psu1 + client = i2c_new_device(adapter, &ix1b_i2c_devices[12]); // pmbus_psu1 - Address: 0x5f printk("[CC] NEW device pmbus_psu1\n"); i2c_put_adapter(adapter); adapter = i2c_get_adapter(0x15); - client = i2c_new_device(adapter, &ix1b_i2c_devices[13]); // pmbus_psu2 + client = i2c_new_device(adapter, &ix1b_i2c_devices[13]); // pmbus_psu2 - Address: 0x59 printk("[CC] NEW device pmbus_psu2\n"); i2c_put_adapter(adapter); adapter = i2c_get_adapter(0x16); - client = i2c_new_device(adapter, &ix1b_i2c_devices[2]); // pca9555-PSU1 + client = i2c_new_device(adapter, &ix1b_i2c_devices[2]); // pca9555-PSU1 - Address: 0x26 printk("[CC] NEW device pca9555-PSU1\n"); - client = i2c_new_device(adapter, &ix1b_i2c_devices[3]); // MB_BOARDINFO_EEPROM + client = i2c_new_device(adapter, &ix1b_i2c_devices[3]); // MB_BOARDINFO_EEPROM - Address: 0x54 printk("[CC] NEW device MB_BOARDINFO_EEPROM\n"); - client = i2c_new_device(adapter, &ix1b_i2c_devices[10]); // pca9555-ID + client = i2c_new_device(adapter, &ix1b_i2c_devices[10]); // pca9555-ID - Address: 0x23 printk("[CC] NEW device pca9555-ID\n"); i2c_put_adapter(adapter); adapter = i2c_get_adapter(0x17); - client = i2c_new_device(adapter, &ix1b_i2c_devices[11]); // pca9555-fan + client = i2c_new_device(adapter, &ix1b_i2c_devices[11]); // pca9555-fan - Address: 0x25 printk("[CC] NEW device pca9555-fan\n"); i2c_put_adapter(adapter); adapter = i2c_get_adapter(0x10); - client = i2c_new_device(adapter, &ix1b_i2c_devices[4]); // pca9548_2 SFP + client = i2c_new_device(adapter, &ix1b_i2c_devices[4]); // pca9548_1 SFP - Address: 0x73 + printk("[CC] NEW device pca9548_1 SFP\n"); + client = i2c_new_device(adapter, &ix1b_i2c_devices[5]); // pca9548_2 SFP - Address: 0x74 printk("[CC] NEW device pca9548_2 SFP\n"); - client = i2c_new_device(adapter, &ix1b_i2c_devices[5]); // pca9548_3 SFP + client = i2c_new_device(adapter, &ix1b_i2c_devices[6]); // pca9548_3 SFP - Address: 0x75 printk("[CC] NEW device pca9548_3 SFP\n"); - client = i2c_new_device(adapter, &ix1b_i2c_devices[6]); // pca9548_4 SFP - printk("[CC] NEW device pca9548_4 SFP\n"); - client = i2c_new_device(adapter, &ix1b_i2c_devices[8]); // CPLD2 + client = i2c_new_device(adapter, &ix1b_i2c_devices[8]); // CPLD2 - Address: 0x38 printk("[CC] NEW device CPLD2\n"); - client = i2c_new_device(adapter, &ix1b_i2c_devices[9]); // CPLD3 + client = i2c_new_device(adapter, &ix1b_i2c_devices[9]); // CPLD3 - Address: 0x39 printk("[CC] NEW device CPLD3\n"); i2c_put_adapter(adapter); adapter = i2c_get_adapter(0x11); - client = i2c_new_device(adapter, &ix1b_i2c_devices[7]); // pca9548_5 SFP - printk("[CC] NEW device pca9548_5 SFP\n"); + client = i2c_new_device(adapter, &ix1b_i2c_devices[7]); // pca9548_4 SFP - Address: 0x76 + printk("[CC] NEW device pca9548_4 SFP\n"); i2c_put_adapter(adapter); #if defined(QUANTA_CPU_RGL) adapter = i2c_get_adapter(0x18); - client = i2c_new_device(adapter, &ix1b_i2c_devices[15]); // cpu pca9555_1 + client = i2c_new_device(adapter, &ix1b_i2c_devices[15]); // cpu pca9555_1 - Address: 0x20 printk("[CC] NEW device cpu pca9555_1\n"); i2c_put_adapter(adapter); for(i = 0x20; i < 0x40; i++) { adapter = i2c_get_adapter(i); - client = i2c_new_device(adapter, &ix1b_i2c_devices[16]); // eeprom for loopback module + client = i2c_new_device(adapter, &ix1b_i2c_devices[16]); // eeprom for loopback module - Address: 0x50 i2c_put_adapter(adapter); } printk("[CC] NEW device eeprom\n"); @@ -466,6 +473,9 @@ static int __init ix1b_platform_init(void) } printk("[CC] NEW device led\n"); + platform_device_register(&qci_hwmon_device); + printk("[CC] NEW device hwmon\n"); + return 0; fail_platform_device: diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_pmbus.c b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_pmbus.c index f54a0f204d67..0fac27b59b6c 100755 --- a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_pmbus.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_pmbus.c @@ -27,14 +27,268 @@ #include #include #include -//#include <../drivers/hwmon/pmbus/pmbus.h> -#include "pmbus.h" #include enum projects { ly8, ix1, ix2, ix1b }; #define DELAY_TIME 1000 /* uS */ +/* Pmbus reg defines are copied from drivers/hwmon/pmbus/pmbus.h*/ +/* + * Registers + */ +enum pmbus_regs { + PMBUS_PAGE = 0x00, + PMBUS_OPERATION = 0x01, + PMBUS_ON_OFF_CONFIG = 0x02, + PMBUS_CLEAR_FAULTS = 0x03, + PMBUS_PHASE = 0x04, + + PMBUS_CAPABILITY = 0x19, + PMBUS_QUERY = 0x1A, + + PMBUS_VOUT_MODE = 0x20, + PMBUS_VOUT_COMMAND = 0x21, + PMBUS_VOUT_TRIM = 0x22, + PMBUS_VOUT_CAL_OFFSET = 0x23, + PMBUS_VOUT_MAX = 0x24, + PMBUS_VOUT_MARGIN_HIGH = 0x25, + PMBUS_VOUT_MARGIN_LOW = 0x26, + PMBUS_VOUT_TRANSITION_RATE = 0x27, + PMBUS_VOUT_DROOP = 0x28, + PMBUS_VOUT_SCALE_LOOP = 0x29, + PMBUS_VOUT_SCALE_MONITOR = 0x2A, + + PMBUS_COEFFICIENTS = 0x30, + PMBUS_POUT_MAX = 0x31, + + PMBUS_FAN_CONFIG_12 = 0x3A, + PMBUS_FAN_COMMAND_1 = 0x3B, + PMBUS_FAN_COMMAND_2 = 0x3C, + PMBUS_FAN_CONFIG_34 = 0x3D, + PMBUS_FAN_COMMAND_3 = 0x3E, + PMBUS_FAN_COMMAND_4 = 0x3F, + + PMBUS_VOUT_OV_FAULT_LIMIT = 0x40, + PMBUS_VOUT_OV_FAULT_RESPONSE = 0x41, + PMBUS_VOUT_OV_WARN_LIMIT = 0x42, + PMBUS_VOUT_UV_WARN_LIMIT = 0x43, + PMBUS_VOUT_UV_FAULT_LIMIT = 0x44, + PMBUS_VOUT_UV_FAULT_RESPONSE = 0x45, + PMBUS_IOUT_OC_FAULT_LIMIT = 0x46, + PMBUS_IOUT_OC_FAULT_RESPONSE = 0x47, + PMBUS_IOUT_OC_LV_FAULT_LIMIT = 0x48, + PMBUS_IOUT_OC_LV_FAULT_RESPONSE = 0x49, + PMBUS_IOUT_OC_WARN_LIMIT = 0x4A, + PMBUS_IOUT_UC_FAULT_LIMIT = 0x4B, + PMBUS_IOUT_UC_FAULT_RESPONSE = 0x4C, + + PMBUS_OT_FAULT_LIMIT = 0x4F, + PMBUS_OT_FAULT_RESPONSE = 0x50, + PMBUS_OT_WARN_LIMIT = 0x51, + PMBUS_UT_WARN_LIMIT = 0x52, + PMBUS_UT_FAULT_LIMIT = 0x53, + PMBUS_UT_FAULT_RESPONSE = 0x54, + PMBUS_VIN_OV_FAULT_LIMIT = 0x55, + PMBUS_VIN_OV_FAULT_RESPONSE = 0x56, + PMBUS_VIN_OV_WARN_LIMIT = 0x57, + PMBUS_VIN_UV_WARN_LIMIT = 0x58, + PMBUS_VIN_UV_FAULT_LIMIT = 0x59, + + PMBUS_IIN_OC_FAULT_LIMIT = 0x5B, + PMBUS_IIN_OC_WARN_LIMIT = 0x5D, + + PMBUS_POUT_OP_FAULT_LIMIT = 0x68, + PMBUS_POUT_OP_WARN_LIMIT = 0x6A, + PMBUS_PIN_OP_WARN_LIMIT = 0x6B, + + PMBUS_STATUS_BYTE = 0x78, + PMBUS_STATUS_WORD = 0x79, + PMBUS_STATUS_VOUT = 0x7A, + PMBUS_STATUS_IOUT = 0x7B, + PMBUS_STATUS_INPUT = 0x7C, + PMBUS_STATUS_TEMPERATURE = 0x7D, + PMBUS_STATUS_CML = 0x7E, + PMBUS_STATUS_OTHER = 0x7F, + PMBUS_STATUS_MFR_SPECIFIC = 0x80, + PMBUS_STATUS_FAN_12 = 0x81, + PMBUS_STATUS_FAN_34 = 0x82, + + PMBUS_READ_VIN = 0x88, + PMBUS_READ_IIN = 0x89, + PMBUS_READ_VCAP = 0x8A, + PMBUS_READ_VOUT = 0x8B, + PMBUS_READ_IOUT = 0x8C, + PMBUS_READ_TEMPERATURE_1 = 0x8D, + PMBUS_READ_TEMPERATURE_2 = 0x8E, + PMBUS_READ_TEMPERATURE_3 = 0x8F, + PMBUS_READ_FAN_SPEED_1 = 0x90, + PMBUS_READ_FAN_SPEED_2 = 0x91, + PMBUS_READ_FAN_SPEED_3 = 0x92, + PMBUS_READ_FAN_SPEED_4 = 0x93, + PMBUS_READ_DUTY_CYCLE = 0x94, + PMBUS_READ_FREQUENCY = 0x95, + PMBUS_READ_POUT = 0x96, + PMBUS_READ_PIN = 0x97, + + PMBUS_REVISION = 0x98, + PMBUS_MFR_ID = 0x99, + PMBUS_MFR_MODEL = 0x9A, + PMBUS_MFR_REVISION = 0x9B, + PMBUS_MFR_LOCATION = 0x9C, + PMBUS_MFR_DATE = 0x9D, + PMBUS_MFR_SERIAL = 0x9E, + +/* + * Virtual registers. + * Useful to support attributes which are not supported by standard PMBus + * registers but exist as manufacturer specific registers on individual chips. + * Must be mapped to real registers in device specific code. + * + * Semantics: + * Virtual registers are all word size. + * READ registers are read-only; writes are either ignored or return an error. + * RESET registers are read/write. Reading reset registers returns zero + * (used for detection), writing any value causes the associated history to be + * reset. + * Virtual registers have to be handled in device specific driver code. Chip + * driver code returns non-negative register values if a virtual register is + * supported, or a negative error code if not. The chip driver may return + * -ENODATA or any other error code in this case, though an error code other + * than -ENODATA is handled more efficiently and thus preferred. Either case, + * the calling PMBus core code will abort if the chip driver returns an error + * code when reading or writing virtual registers. + */ + PMBUS_VIRT_BASE = 0x100, + PMBUS_VIRT_READ_TEMP_AVG, + PMBUS_VIRT_READ_TEMP_MIN, + PMBUS_VIRT_READ_TEMP_MAX, + PMBUS_VIRT_RESET_TEMP_HISTORY, + PMBUS_VIRT_READ_VIN_AVG, + PMBUS_VIRT_READ_VIN_MIN, + PMBUS_VIRT_READ_VIN_MAX, + PMBUS_VIRT_RESET_VIN_HISTORY, + PMBUS_VIRT_READ_IIN_AVG, + PMBUS_VIRT_READ_IIN_MIN, + PMBUS_VIRT_READ_IIN_MAX, + PMBUS_VIRT_RESET_IIN_HISTORY, + PMBUS_VIRT_READ_PIN_AVG, + PMBUS_VIRT_READ_PIN_MIN, + PMBUS_VIRT_READ_PIN_MAX, + PMBUS_VIRT_RESET_PIN_HISTORY, + PMBUS_VIRT_READ_POUT_AVG, + PMBUS_VIRT_READ_POUT_MIN, + PMBUS_VIRT_READ_POUT_MAX, + PMBUS_VIRT_RESET_POUT_HISTORY, + PMBUS_VIRT_READ_VOUT_AVG, + PMBUS_VIRT_READ_VOUT_MIN, + PMBUS_VIRT_READ_VOUT_MAX, + PMBUS_VIRT_RESET_VOUT_HISTORY, + PMBUS_VIRT_READ_IOUT_AVG, + PMBUS_VIRT_READ_IOUT_MIN, + PMBUS_VIRT_READ_IOUT_MAX, + PMBUS_VIRT_RESET_IOUT_HISTORY, + PMBUS_VIRT_READ_TEMP2_AVG, + PMBUS_VIRT_READ_TEMP2_MIN, + PMBUS_VIRT_READ_TEMP2_MAX, + PMBUS_VIRT_RESET_TEMP2_HISTORY, + + PMBUS_VIRT_READ_VMON, + PMBUS_VIRT_VMON_UV_WARN_LIMIT, + PMBUS_VIRT_VMON_OV_WARN_LIMIT, + PMBUS_VIRT_VMON_UV_FAULT_LIMIT, + PMBUS_VIRT_VMON_OV_FAULT_LIMIT, + PMBUS_VIRT_STATUS_VMON, +}; + +enum pmbus_sensor_classes { + PSC_VOLTAGE_IN = 0, + PSC_VOLTAGE_OUT, + PSC_CURRENT_IN, + PSC_CURRENT_OUT, + PSC_POWER, + PSC_TEMPERATURE, + PSC_FAN, + PSC_NUM_CLASSES /* Number of power sensor classes */ +}; + +#define PMBUS_PAGES 32 /* Per PMBus specification */ + +/* Functionality bit mask */ +#define PMBUS_HAVE_VIN BIT(0) +#define PMBUS_HAVE_VCAP BIT(1) +#define PMBUS_HAVE_VOUT BIT(2) +#define PMBUS_HAVE_IIN BIT(3) +#define PMBUS_HAVE_IOUT BIT(4) +#define PMBUS_HAVE_PIN BIT(5) +#define PMBUS_HAVE_POUT BIT(6) +#define PMBUS_HAVE_FAN12 BIT(7) +#define PMBUS_HAVE_FAN34 BIT(8) +#define PMBUS_HAVE_TEMP BIT(9) +#define PMBUS_HAVE_TEMP2 BIT(10) +#define PMBUS_HAVE_TEMP3 BIT(11) +#define PMBUS_HAVE_STATUS_VOUT BIT(12) +#define PMBUS_HAVE_STATUS_IOUT BIT(13) +#define PMBUS_HAVE_STATUS_INPUT BIT(14) +#define PMBUS_HAVE_STATUS_TEMP BIT(15) +#define PMBUS_HAVE_STATUS_FAN12 BIT(16) +#define PMBUS_HAVE_STATUS_FAN34 BIT(17) +#define PMBUS_HAVE_VMON BIT(18) +#define PMBUS_HAVE_STATUS_VMON BIT(19) + +enum pmbus_data_format { linear = 0, direct, vid }; +enum vrm_version { vr11 = 0, vr12, vr13 }; + +struct pmbus_driver_info { + int pages; /* Total number of pages */ + enum pmbus_data_format format[PSC_NUM_CLASSES]; + enum vrm_version vrm_version; + /* + * Support one set of coefficients for each sensor type + * Used for chips providing data in direct mode. + */ + int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */ + int b[PSC_NUM_CLASSES]; /* offset */ + int R[PSC_NUM_CLASSES]; /* exponent */ + + u32 func[PMBUS_PAGES]; /* Functionality, per page */ + /* + * The following functions map manufacturing specific register values + * to PMBus standard register values. Specify only if mapping is + * necessary. + * Functions return the register value (read) or zero (write) if + * successful. A return value of -ENODATA indicates that there is no + * manufacturer specific register, but that a standard PMBus register + * may exist. Any other negative return value indicates that the + * register does not exist, and that no attempt should be made to read + * the standard register. + */ + int (*read_byte_data)(struct i2c_client *client, int page, int reg); + int (*read_word_data)(struct i2c_client *client, int page, int reg); + int (*write_word_data)(struct i2c_client *client, int page, int reg, + u16 word); + int (*write_byte)(struct i2c_client *client, int page, u8 value); + /* + * The identify function determines supported PMBus functionality. + * This function is only necessary if a chip driver supports multiple + * chips, and the chip functionality is not pre-determined. + */ + int (*identify)(struct i2c_client *client, + struct pmbus_driver_info *info); + + /* Regulator functionality, if supported by this chip driver. */ + int num_regulators; + const struct regulator_desc *reg_desc; +}; + +extern int pmbus_set_page(struct i2c_client *client, u8 page); +extern int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg); +extern bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg); +extern bool pmbus_check_word_register(struct i2c_client *client, int page, int reg); +extern int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, + struct pmbus_driver_info *info); +extern int pmbus_do_remove(struct i2c_client *client); + /* Needed to access the mutex. Copied from pmbus_core.c */ #define PB_STATUS_BASE 0 #define PB_STATUS_VOUT_BASE (PB_STATUS_BASE + PMBUS_PAGES) @@ -327,6 +581,7 @@ static int qci_pmbus_identify(struct i2c_client *client, break; case 1: info->format[PSC_VOLTAGE_OUT] = vid; + info->vrm_version = vr11; break; case 2: info->format[PSC_VOLTAGE_OUT] = direct; @@ -411,7 +666,7 @@ static int qci_pmbus_probe(struct i2c_client *client, { struct device *dev = &client->dev; struct pmbus_driver_info *info; - int ret, i; + int ret; dev_info(dev, "qci_pmbus_probe\n"); @@ -419,8 +674,7 @@ static int qci_pmbus_probe(struct i2c_client *client, I2C_FUNC_SMBUS_READ_WORD_DATA)) return -ENODEV; - info = devm_kzalloc(&client->dev, sizeof(struct pmbus_driver_info), - GFP_KERNEL); + info = devm_kzalloc(dev, sizeof(struct pmbus_driver_info), GFP_KERNEL); if (!info) return -ENOMEM; diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/utils/quanta_ix1b_util.py b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/utils/quanta_ix1b_util.py index f530cf3dbb7b..2135932938eb 100755 --- a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/utils/quanta_ix1b_util.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/utils/quanta_ix1b_util.py @@ -40,75 +40,96 @@ FORCE = 0 i2c_prefix = '/sys/bus/i2c/devices/' - if DEBUG == True: print sys.argv[0] - print 'ARGV :', sys.argv[1:] - + print 'ARGV :', sys.argv[1:] def main(): global DEBUG global args global FORCE - - if len(sys.argv)<2: + + if len(sys.argv) < 2: show_help() - + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', 'debug', 'force', ]) - if DEBUG == True: + if DEBUG == True: print options print args print len(sys.argv) - + for opt, arg in options: if opt in ('-h', '--help'): show_help() - elif opt in ('-d', '--debug'): + elif opt in ('-d', '--debug'): DEBUG = True - logging.basicConfig(level=logging.INFO) - elif opt in ('-f', '--force'): + logging.basicConfig(level = logging.INFO) + elif opt in ('-f', '--force'): FORCE = 1 else: - logging.info('no option') - for arg in args: + logging.info('no option') + + for arg in args: if arg == 'install': - install() + install() elif arg == 'clean': - uninstall() + uninstall() else: show_help() - - - return 0 - + + return 0 + def show_help(): print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} sys.exit(0) - + def show_log(txt): if DEBUG == True: - print "[IX1B-32X]"+txt + print "[IX1B-32X]" + txt + return - + def exec_cmd(cmd, show): - logging.info('Run :'+cmd) - status, output = commands.getstatusoutput(cmd) - show_log (cmd +"with result:" + str(status)) - show_log (" output:"+output) + logging.info('Run :' + cmd) + status, output = commands.getstatusoutput(cmd) + show_log (cmd + "with result:" + str(status)) + show_log (" output:" + output) if status: - logging.info('Failed :'+cmd) + logging.info('Failed :' + cmd) if show: - print('Failed :'+cmd) - return status, output - -instantiate =[ + print('Failed :' + cmd) + + return status, output + +instantiate = [ #turn on module power 'echo 53 > /sys/class/gpio/export', 'echo out > /sys/class/gpio/gpio53/direction', -'echo 1 >/sys/class/gpio/gpio53/value', +'echo 1 > /sys/class/gpio/gpio53/value', +#PSU1 present +'echo 16 > /sys/class/gpio/export', +'echo in > /sys/class/gpio/gpio16/direction', +#PSU1 power good signal +'echo 17 > /sys/class/gpio/export', +'echo in > /sys/class/gpio/gpio17/direction', +#PSU2 present +'echo 19 > /sys/class/gpio/export', +'echo in > /sys/class/gpio/gpio19/direction', +#PSU2 power good signal +'echo 20 > /sys/class/gpio/export', +'echo in > /sys/class/gpio/gpio20/direction', +#FAN 1-4 present +'echo 36 > /sys/class/gpio/export', +'echo in > /sys/class/gpio/gpio36/direction', +'echo 37 > /sys/class/gpio/export', +'echo in > /sys/class/gpio/gpio37/direction', +'echo 38 > /sys/class/gpio/export', +'echo in > /sys/class/gpio/gpio38/direction', +'echo 39 > /sys/class/gpio/export', +'echo in > /sys/class/gpio/gpio39/direction', #turn on 100G led by default 'i2cset -y 0x13 0x38 0x00 0xff', 'i2cset -y 0x13 0x38 0x01 0xff', @@ -124,77 +145,89 @@ def exec_cmd(cmd, show): 'gpio-pca953x', 'qci_pmbus', 'leds-gpio', +'optoe', 'qci_cpld_qsfp28', 'qci_platform_ix1b' ] - - def system_install(): global FORCE - + + time.sleep(3) #remove default drivers to avoid modprobe order conflicts status, output = exec_cmd("rmmod i2c_ismt ", 1) status, output = exec_cmd("rmmod i2c-i801 ", 1) #setup driver dependency status, output = exec_cmd("depmod -a ", 1) + #install drivers - for i in range(0,len(drivers)): - status, output = exec_cmd("modprobe "+drivers[i], 1) + for i in range(0, len(drivers)): + status, output = exec_cmd("modprobe " + drivers[i], 1) + if status: - print output - if FORCE == 0: - return status - + print output + if FORCE == 0: + return status + #instantiate devices - for i in range(0,len(instantiate)): - time.sleep(1) - status, output = exec_cmd(instantiate[i], 1) + for i in range(0, len(instantiate)): + status, output = exec_cmd(instantiate[i], 1) + if status: - print output - if FORCE == 0: - return status - - #for i in range(22,30): - # status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-0/i2c-4/i2c-"+str(i)+"/new_device", 1) - # if status: - # print output - # if FORCE == 0: - # return status - - return - - + print output + if FORCE == 0: + return status + + #Mount Quanta hardware monitor driver + status, output = exec_cmd("modprobe qci_hwmon_ix1b", 1) + + #QSFP for 1~32 port + for port_number in range(1, 33): + bus_number = port_number + 31 + os.system("echo %d >/sys/bus/i2c/devices/%d-0050/port_name" % (port_number, bus_number)) + + #Set system LED to green + status, output = exec_cmd("echo 1 > /sys/class/leds/sysled_green/brightness", 1) + + return + def system_ready(): - if not device_found(): + if not device_found(): return False + return True - -def install(): + +def install(): if not device_found(): - print "No device, installing...." - status = system_install() + print "No device, installing...." + status = system_install() + if status: - if FORCE == 0: - return status + if FORCE == 0: + return status else: - print " ix1b driver already installed...." + print " ix1b driver already installed...." + return def uninstall(): global FORCE + #uninstall drivers - for i in range(len(drivers)-1,-1,-1): - status, output = exec_cmd("rmmod "+drivers[i], 1) + for i in range(len(drivers) - 1, -1, -1): + status, output = exec_cmd("rmmod " + drivers[i], 1) + if status: - print output - if FORCE == 0: - return status + print output + if FORCE == 0: + return status + return def device_found(): - ret1, log = exec_cmd("ls "+i2c_prefix+"i2c-0", 0) - return ret1 + ret1, log = exec_cmd("ls " + i2c_prefix + "i2c-0", 0) + + return ret1 if __name__ == "__main__": main() diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/thermalutil.py b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/classes/__init__.py similarity index 100% rename from platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/thermalutil.py rename to platform/broadcom/sonic-platform-modules-quanta/ix9-32x/classes/__init__.py diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/Makefile b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/Makefile new file mode 100644 index 000000000000..929782931a47 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/Makefile @@ -0,0 +1,3 @@ +obj-m:=qci_cpld_qsfpdd.o qci_cpld_led.o qci_platform_ix9.o + + diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_cpld_led.c b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_cpld_led.c new file mode 100644 index 000000000000..d8f89240a851 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_cpld_led.c @@ -0,0 +1,277 @@ +/* + * A LED CPLD driver for Quanta Switch Platform + * + * The CPLD is customize by Quanta for decode led bit stream, + * This driver modify from Quanta CPLD I/O driver. + * + * Copyright (C) 2015 Quanta Inc. + * + * Author: Luffy Cheng + * Author: Roger Chang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static DEFINE_IDA(cpld_led_ida); + +enum platform_type { + IX7 = 0, + IX8C, + IX9, + NONE +}; + +static struct class *cpld_class = NULL; + +struct cpld_data { + struct i2c_client *cpld_client; + char name[8]; + u8 cpld_id; +}; + +struct cpld_led_data { + struct mutex lock; + struct device *port_dev; + struct cpld_data *cpld_data; +}; + +static int cpld_led_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int cpld_led_remove(struct i2c_client *client); + +static const struct i2c_device_id cpld_led_id[] = { + { "CPLDLED_IX7", IX7 }, + { "CPLDLED_IX8C", IX8C }, + { "CPLDLED_IX9", IX9 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, cpld_led_id); + +static struct i2c_driver cpld_led_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "qci_cpld_led", + }, + .probe = cpld_led_probe, + .remove = cpld_led_remove, + .id_table = cpld_led_id, +// .address_list = normal_i2c, +}; + +#define CPLD_LED_ID_PREFIX "CPLDLED-" +#define CPLD_LED_ID_FORMAT CPLD_LED_ID_PREFIX "%d" + +#define CPLD_DECODER_OFFSET 0x4 +#define CPLD_DECODER_MASK 0x1 +#define CPLD_USERCODE_START_OFFSET 0x0 + +static ssize_t get_led_decode(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->cpld_client; + u8 offset = (u8)(CPLD_DECODER_OFFSET); + s32 value; + + value = i2c_smbus_read_byte_data(client, offset); + if (value < 0) + return -ENODEV; + + dev_dbg(&client->dev, "read led decode value= %x\n", value); + + value &= CPLD_DECODER_MASK; + + return sprintf(buf, "%d\n", (value == 0) ? 1 : 0); +} + +static ssize_t get_usercode(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->cpld_client; + u8 i = 0; + s32 value = 0, reading = 0; + + for (i = 0; i < 4; i++) + { + reading = i2c_smbus_read_byte_data(client, CPLD_USERCODE_START_OFFSET + i); + if (reading < 0) + return -ENODEV; + + dev_dbg(&client->dev, "read led usercode reg %d value= %x\n", i, reading); + + value |= reading << (24 - 8 * i); + } + + return sprintf(buf, "%X\n", value); +} + +static ssize_t set_led_decode(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->cpld_client; + s32 value; + long enable; + + if (kstrtol(buf, 0, &enable)) + return -EINVAL; + + if ((enable != 1) && (enable != 0)) + return -EINVAL; + +// mutex_lock(&data->lock); + value = i2c_smbus_read_byte_data(client, CPLD_DECODER_OFFSET); + if (value < 0) + return -ENODEV; + + dev_dbg(&client->dev, "read led decode value= %x\n", value); + + value |= CPLD_DECODER_MASK; + if (enable) + value &= ~CPLD_DECODER_MASK; + + dev_dbg(&client->dev, "write led decode value= %x\n", value); + + i2c_smbus_write_byte_data(client, CPLD_DECODER_OFFSET, (u8)value); +// mutex_unlock(&data->lock); + + return count; +} + +static DEVICE_ATTR(led_decode, S_IWUSR | S_IRUGO, get_led_decode, set_led_decode); +static DEVICE_ATTR(usercode, S_IRUGO, get_usercode, NULL); + +static const struct attribute *led_attrs[] = { + &dev_attr_usercode.attr, + &dev_attr_led_decode.attr, + NULL, +}; + +static const struct attribute_group led_attr_group = { + .attrs = (struct attribute **) led_attrs, +}; + +static int cpld_led_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct cpld_led_data *data; + struct cpld_data *led_data; + struct device *port_dev; + int nr, err; + + if (!cpld_class) + { + cpld_class = class_create(THIS_MODULE, "cpld-led"); + if (IS_ERR(cpld_class)) { + pr_err("couldn't create sysfs class\n"); + return PTR_ERR(cpld_class); + } + } + + data = devm_kzalloc(&client->dev, sizeof(struct cpld_led_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; + + /* Test */ + nr = ida_simple_get(&cpld_led_ida, 1, 99, GFP_KERNEL); + if (nr < 0) + goto err_out; + + led_data = kzalloc(sizeof(struct cpld_led_data), GFP_KERNEL); + + port_dev = device_create(cpld_class, &client->dev, MKDEV(0,0), led_data, CPLD_LED_ID_FORMAT, nr); + if (IS_ERR(port_dev)) { + err = PTR_ERR(port_dev); + // printk("err_status\n"); + } + + data->port_dev = port_dev; + data->cpld_data = led_data; + + dev_info(&client->dev, "Register CPLDLED %d\n", nr); + + sprintf(led_data->name, "LED%d-data", nr); + led_data->cpld_id = nr; + dev_set_drvdata(port_dev, led_data); + port_dev->init_name = led_data->name; + led_data->cpld_client = client; + + err = sysfs_create_group(&port_dev->kobj, &led_attr_group); + // if (status) printk("err status\n"); + /* end */ + + i2c_set_clientdata(client, data); + mutex_init(&data->lock); + + dev_info(&client->dev, "%s device found\n", client->name); + + + return 0; + +err_out: + return nr; +} + +/* FIXME: for older kernel doesn't with idr_is_empty function, implement here */ +static int idr_has_entry(int id, void *p, void *data) +{ + return 1; +} + +static bool cpld_idr_is_empty(struct idr *idp) +{ + return !idr_for_each(idp, idr_has_entry, NULL); +} + +static int cpld_led_remove(struct i2c_client *client) +{ + struct cpld_led_data *data = i2c_get_clientdata(client); + + dev_info(data->port_dev, "Remove CPLDLED-%d\n", data->cpld_data->cpld_id); + device_unregister(data->port_dev); + ida_simple_remove(&cpld_led_ida, data->cpld_data->cpld_id); + kfree(data->cpld_data); + + if (cpld_idr_is_empty(&cpld_led_ida.idr)) + class_destroy(cpld_class); + + return 0; +} + +module_i2c_driver(cpld_led_driver); + +MODULE_AUTHOR("Luffy Cheng "); +MODULE_AUTHOR("Roger Chang "); +MODULE_DESCRIPTION("Quanta Switch LED CPLD driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_cpld_qsfpdd.c b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_cpld_qsfpdd.c new file mode 100644 index 000000000000..d616f887dbbf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_cpld_qsfpdd.c @@ -0,0 +1,411 @@ +/* + * A CPLD driver for monitor QSFPDD module I/O + * + * The CPLD is customize by Quanta for controlling QSFPDD module signals, + * they are RESET , INTERREPT , Module_Present, LPMODE + * Each CPLD control 16 modules, each module use 4 bits in register. + * + * Copyright (C) 2015 Quanta Inc. + * + * Author: Luffy Cheng + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static DEFINE_IDA(cpld_ida); + +enum platform_type { + QSFPDD = 0, + NONE +}; + +static struct class *cpld_class = NULL; + +struct sfp_data { + struct i2c_client *cpld_client; + char name[8]; + u8 port_id; + u8 cpld_port; +}; + +struct cpld_data { + struct mutex lock; + struct device *port_dev[16]; + struct sfp_data *port_data[16]; +}; + +static int cpld_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int cpld_remove(struct i2c_client *client); + +static const struct i2c_device_id cpld_id[] = { + { "CPLD-QSFPDD", QSFPDD }, + { } +}; +MODULE_DEVICE_TABLE(i2c, cpld_id); + +static struct i2c_driver cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "qci_cpld_qsfpdd", + }, + .probe = cpld_probe, + .remove = cpld_remove, + .id_table = cpld_id, +// .address_list = normal_i2c, +}; + +#define CPLD_ID_PREFIX "port-" +#define CPLD_ID_FORMAT CPLD_ID_PREFIX "%d" + +#define RESET_MASK 0x08 +#define INTERRUPT_MASK 0x04 +#define MODULE_PRESENT_MASK 0x02 +#define LPMODE_MASK 0x01 + +static inline u8 get_group_cmd(u8 group) +{ + //FIXME: if group cmd change + return (group + 1); +} + +static inline u8 port_remapping(u8 phy_port) +{ + /* FIXME: implement by hardware design */ + /* The CPLD register port mapping is weird : + * MSB -------- LSB (word data) + * P3 P4 P1 P2 (per port 4 bits) + * For easy coding bit shift, we treat it as hw port swap + */ + return (phy_port % 2) ? (phy_port - 1) : (phy_port + 1); +} + +static ssize_t get_reset(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sfp_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->cpld_client; + u8 group = (u8)(data->cpld_port / 4); + u8 group_port = data->cpld_port % 4; + s32 value; + + dev_dbg(&client->dev, "port_id %d => cpld_port %d, group %d(%d)\n", data->port_id, + data->cpld_port + 1, group + 1, group_port + 1); + + value = i2c_smbus_read_word_data(client, get_group_cmd(group)); + if (value < 0) + return -ENODEV; + + dev_dbg(&client->dev, "read group%d value= %x\n", group + 1, value); + + value >>= (group_port * 4); + value &= RESET_MASK; + + return sprintf(buf, "%d\n", value ? 1 : 0); +} + +static ssize_t get_interrupt(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sfp_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->cpld_client; + u8 group = (u8)(data->cpld_port / 4); + u8 group_port = data->cpld_port % 4; + s32 value; + + dev_dbg(&client->dev, "port_id %d => cpld_port %d, group %d(%d)\n", data->port_id, + data->cpld_port + 1, group + 1, group_port + 1); + + value = i2c_smbus_read_word_data(client, get_group_cmd(group)); + if (value < 0) + return -ENODEV; + + dev_dbg(&client->dev, "read group%d value= %x\n", group + 1, value); + + value >>= (group_port * 4); + value &= INTERRUPT_MASK; + + return sprintf(buf, "%d\n", value ? 1 : 0); +} + +static ssize_t get_module_present(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sfp_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->cpld_client; + u8 group = (u8)(data->cpld_port / 4); + u8 group_port = data->cpld_port % 4; + s32 value; + + dev_dbg(&client->dev, "port_id %d => cpld_port %d, group %d(%d)\n", data->port_id, + data->cpld_port + 1, group + 1, group_port + 1); + + value = i2c_smbus_read_word_data(client, get_group_cmd(group)); + if (value < 0) + return -ENODEV; + + dev_dbg(&client->dev, "read group%d value= %x\n", group + 1, value); + + value >>= (group_port * 4); + value &= MODULE_PRESENT_MASK; + + //FIXME: if present is not low active + return sprintf(buf, "%d\n", value ? 0 : 1); +} + +static ssize_t get_lpmode(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sfp_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->cpld_client; + u8 group = (u8)(data->cpld_port / 4); + u8 group_port = data->cpld_port % 4; + s32 value; + + dev_dbg(&client->dev, "port_id %d => cpld_port %d, group %d(%d)\n", data->port_id, + data->cpld_port + 1, group + 1, group_port + 1); + + value = i2c_smbus_read_word_data(client, get_group_cmd(group)); + if (value < 0) + return -ENODEV; + + dev_dbg(&client->dev, "read group%d value= %x\n", group + 1, value); + + value >>= (group_port * 4); + value &= LPMODE_MASK; + + return sprintf(buf, "%d\n", value ? 1 : 0); +} + +static ssize_t set_reset(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct sfp_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->cpld_client; + u8 group = (u8)(data->cpld_port / 4); + u8 group_port = data->cpld_port % 4; + s32 value; + long disable; + + dev_dbg(&client->dev, "port_id %d => cpld_port %d, group %d(%d)\n", data->port_id, + data->cpld_port + 1, group + 1, group_port + 1); + + if (kstrtol(buf, 0, &disable)) + return -EINVAL; + + if ((disable != 1) && (disable != 0)) + return -EINVAL; + +// mutex_lock(&data->lock); + value = i2c_smbus_read_word_data(client, get_group_cmd(group)); + if (value < 0) + return -ENODEV; + + dev_dbg(&client->dev, "read group%d value= %x\n", group + 1, value); + + value &= ~(RESET_MASK << (group_port * 4)); + if (disable) + value |= (RESET_MASK << (group_port * 4)); + + dev_dbg(&client->dev, "write group%d value= %x\n", group + 1, value); + + i2c_smbus_write_word_data(client, get_group_cmd(group), (u16)value); +// mutex_unlock(&data->lock); + + return count; +} + +static ssize_t set_lpmode(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct sfp_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->cpld_client; + u8 group = (u8)(data->cpld_port / 4); + u8 group_port = data->cpld_port % 4; + s32 value; + long disable; + + dev_dbg(&client->dev, "port_id %d => cpld_port %d, group %d(%d)\n", data->port_id, + data->cpld_port + 1, group + 1, group_port + 1); + + if (kstrtol(buf, 0, &disable)) + return -EINVAL; + + if ((disable != 1) && (disable != 0)) + return -EINVAL; + +// mutex_lock(&data->lock); + value = i2c_smbus_read_word_data(client, get_group_cmd(group)); + if (value < 0) + return -ENODEV; + + dev_dbg(&client->dev, "read group%d value= %x\n", group + 1, value); + + value &= ~(LPMODE_MASK << (group_port * 4)); + if (disable) + value |= (LPMODE_MASK << (group_port * 4)); + + dev_dbg(&client->dev, "write group%d value= %x\n", group + 1, value); + + i2c_smbus_write_word_data(client, get_group_cmd(group), (u16)value); +// mutex_unlock(&data->lock); + + return count; +} + +static DEVICE_ATTR(reset, S_IWUSR | S_IRUGO, get_reset, set_reset); +static DEVICE_ATTR(lpmode, S_IWUSR | S_IRUGO, get_lpmode, set_lpmode); +static DEVICE_ATTR(module_present, S_IRUGO, get_module_present, NULL); +static DEVICE_ATTR(interrupt, S_IRUGO, get_interrupt, NULL); + +static const struct attribute *sfp_attrs[] = { + &dev_attr_reset.attr, + &dev_attr_lpmode.attr, + &dev_attr_module_present.attr, + &dev_attr_interrupt.attr, + NULL, +}; + +static const struct attribute_group sfp_attr_group = { + .attrs = (struct attribute **) sfp_attrs, +}; + +static int cpld_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct cpld_data *data; + struct sfp_data *port_data; + struct device *port_dev; + int port_nr, i, err; + + if (!cpld_class) + { + cpld_class = class_create(THIS_MODULE, "cpld-qsfpdd"); + if (IS_ERR(cpld_class)) { + pr_err("couldn't create sysfs class\n"); + return PTR_ERR(cpld_class); + } + } + + data = devm_kzalloc(&client->dev, sizeof(struct cpld_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; + + /* register sfp port data to sysfs */ + for (i = 0; i < 16; i++) + { + port_nr = ida_simple_get(&cpld_ida, 1, 99, GFP_KERNEL); + if (port_nr < 0) + return port_nr; + + port_data = kzalloc(sizeof(struct sfp_data), GFP_KERNEL); + + port_dev = device_create(cpld_class, &client->dev, MKDEV(0,0), port_data, CPLD_ID_FORMAT, port_nr); + if (IS_ERR(port_dev)) { + err = PTR_ERR(port_dev); + // printk("err_status\n"); + } + + data->port_dev[i] = port_dev; + data->port_data[i] = port_data; + + dev_info(&client->dev, "Register qsfpdd port-%d\n", port_nr); + + /* FIXME: implement Logical/Physical port remapping */ + //port_data->cpld_port = i; + port_data->cpld_port = port_remapping(i); + sprintf(port_data->name, "port-%d", port_nr); + port_data->port_id = port_nr; + dev_set_drvdata(port_dev, port_data); + port_dev->init_name = port_data->name; + port_data->cpld_client = client; + + err = sysfs_create_group(&port_dev->kobj, &sfp_attr_group); + // if (status) printk("err status\n"); + } + + i2c_set_clientdata(client, data); + mutex_init(&data->lock); + + dev_info(&client->dev, "%s device found\n", client->name); + + + return 0; + +#if 0 +//FIXME: implement error check +exit_remove: +// sysfs_remove_group(&client->dev.kobj, &data->attrs); + return err; +#endif +} + +/* FIXME: for older kernel doesn't with idr_is_empty function, implement here */ +static int idr_has_entry(int id, void *p, void *data) +{ + return 1; +} + +static bool cpld_idr_is_empty(struct idr *idp) +{ + return !idr_for_each(idp, idr_has_entry, NULL); +} + +static int cpld_remove(struct i2c_client *client) +{ + struct cpld_data *data = i2c_get_clientdata(client); + int i; + + for (i = 15; i >= 0; i--) + { + dev_info(data->port_dev[i], "Remove qsfpdd port-%d\n", data->port_data[i]->port_id); + device_unregister(data->port_dev[i]); + ida_simple_remove(&cpld_ida, data->port_data[i]->port_id); + kfree(data->port_data[i]); + } + + if (cpld_idr_is_empty(&cpld_ida.idr)) + class_destroy(cpld_class); + + return 0; +} + +module_i2c_driver(cpld_driver); + +MODULE_AUTHOR("Luffy Cheng "); +MODULE_DESCRIPTION("Quanta Switch SFP CPLD driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_platform_ix9.c b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_platform_ix9.c new file mode 100644 index 000000000000..a927e850791f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_platform_ix9.c @@ -0,0 +1,293 @@ +/* + * Quanta IX9 platform driver + * + * + * Copyright (C) 2019 Quanta Computer inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,12,0) +#include +#else +#include +#endif +#define MUX_INFO(bus, deselect) \ + {.adap_id = bus, .deselect_on_exit = deselect} + +static struct pca954x_platform_mode pca9546_1_modes[] = { + MUX_INFO(0x10, 1), + MUX_INFO(0x11, 1), + MUX_INFO(0x12, 1), + MUX_INFO(0x13, 1), +}; + +static struct pca954x_platform_data pca9546_1_data = { + .modes = pca9546_1_modes, + .num_modes = 4, +}; + +static struct pca954x_platform_mode pca9548_1_modes[] = { + MUX_INFO(0x14, 1), + MUX_INFO(0x15, 1), + MUX_INFO(0x16, 1), + MUX_INFO(0x17, 1), +}; + +static struct pca954x_platform_data pca9548_1_data = { + .modes = pca9548_1_modes, + .num_modes = 4, +}; + +static struct pca954x_platform_mode pca9548sfp1_modes[] = { + MUX_INFO(0x20, 1), + MUX_INFO(0x21, 1), + MUX_INFO(0x22, 1), + MUX_INFO(0x23, 1), + MUX_INFO(0x24, 1), + MUX_INFO(0x25, 1), + MUX_INFO(0x26, 1), + MUX_INFO(0x27, 1), +}; + +static struct pca954x_platform_data pca9548sfp1_data = { + .modes = pca9548sfp1_modes, + .num_modes = 8, +}; + +static struct pca954x_platform_mode pca9548sfp2_modes[] = { + MUX_INFO(0x28, 1), + MUX_INFO(0x29, 1), + MUX_INFO(0x2a, 1), + MUX_INFO(0x2b, 1), + MUX_INFO(0x2c, 1), + MUX_INFO(0x2d, 1), + MUX_INFO(0x2e, 1), + MUX_INFO(0x2f, 1), +}; + +static struct pca954x_platform_data pca9548sfp2_data = { + .modes = pca9548sfp2_modes, + .num_modes = 8, +}; + +static struct pca954x_platform_mode pca9548sfp3_modes[] = { + MUX_INFO(0x30, 1), + MUX_INFO(0x31, 1), + MUX_INFO(0x32, 1), + MUX_INFO(0x33, 1), + MUX_INFO(0x34, 1), + MUX_INFO(0x35, 1), + MUX_INFO(0x36, 1), + MUX_INFO(0x37, 1), +}; + +static struct pca954x_platform_data pca9548sfp3_data = { + .modes = pca9548sfp3_modes, + .num_modes = 8, +}; + +static struct pca954x_platform_mode pca9548sfp4_modes[] = { + MUX_INFO(0x38, 1), + MUX_INFO(0x39, 1), + MUX_INFO(0x3a, 1), + MUX_INFO(0x3b, 1), + MUX_INFO(0x3c, 1), + MUX_INFO(0x3d, 1), + MUX_INFO(0x3e, 1), + MUX_INFO(0x3f, 1), +}; + +static struct pca954x_platform_data pca9548sfp4_data = { + .modes = pca9548sfp4_modes, + .num_modes = 8, +}; + +static struct pca953x_platform_data tca9539_1_data = { + .gpio_base = 0x10, +}; +//CPU Linking Board at CPU's I2C Bus +static struct pca953x_platform_data pca9555_CPU_data = { + .gpio_base = 0x20, +}; + +static struct i2c_board_info ix9_i2c_devices[] = { + { + I2C_BOARD_INFO("pca9546", 0x72), + .platform_data = &pca9546_1_data, // 0 pca9546_1 + }, + { + I2C_BOARD_INFO("pca9548", 0x77), + .platform_data = &pca9548_1_data, // 1 pca9548_1 + }, + { + I2C_BOARD_INFO("tca9539", 0x74), + .platform_data = &tca9539_1_data, // 2 Board ID and QSFP-DD PW EN/PG + }, + { + I2C_BOARD_INFO("24c02", 0x54), // 3 MB_BOARDINFO_EEPROM + }, + { + I2C_BOARD_INFO("pca9548", 0x73), + .platform_data = &pca9548sfp1_data, // 4 0x77 ch0 pca9548 #1 + }, + { + I2C_BOARD_INFO("pca9548", 0x73), + .platform_data = &pca9548sfp2_data, // 5 0x77 ch1 pca9548 #2 + }, + { + I2C_BOARD_INFO("pca9548", 0x73), + .platform_data = &pca9548sfp3_data, // 6 0x77 ch2 pca9548 #3 + }, + { + I2C_BOARD_INFO("pca9548", 0x73), + .platform_data = &pca9548sfp4_data, // 7 0x77 ch3 pca9548 #4 + }, + { + I2C_BOARD_INFO("CPLD-QSFPDD", 0x38), // 8 0x72 ch0 CPLD-IO #2, #3 + }, + { + I2C_BOARD_INFO("CPLDLED_IX9", 0x39), // 9 0x72 ch1 CPLD-LED #4, #5 + }, + { + I2C_BOARD_INFO("optoe1", 0x50), // 10 eeprom for loopback module + }, + { + I2C_BOARD_INFO("pca9555", 0x22), // 11 CPU Linking Board at CPU's I2C Bus + .platform_data = &pca9555_CPU_data, + }, +}; + +static struct platform_driver ix9_platform_driver = { + .driver = { + .name = "qci-ix9", + .owner = THIS_MODULE, + }, +}; + +static struct platform_device *ix9_device; + +static int __init ix9_platform_init(void) +{ + struct i2c_client *client; + struct i2c_adapter *adapter; + int ret, i; + + ret = platform_driver_register(&ix9_platform_driver); + if (ret < 0) + return ret; + + /* Register platform stuff */ + ix9_device = platform_device_alloc("qci-ix9", -1); + if (!ix9_device) { + ret = -ENOMEM; + goto fail_platform_driver; + } + + ret = platform_device_add(ix9_device); + if (ret) + goto fail_platform_device; + + adapter = i2c_get_adapter(0); + client = i2c_new_device(adapter, &ix9_i2c_devices[0]); // pca9546_1 - Address: 0x72 + client = i2c_new_device(adapter, &ix9_i2c_devices[1]); // pca9548_1 - Address: 0x77 + client = i2c_new_device(adapter, &ix9_i2c_devices[11]); // CPU Linking Board at CPU's I2C Bus - Address: 0x22 + i2c_put_adapter(adapter); + + adapter = i2c_get_adapter(0x10); + client = i2c_new_device(adapter, &ix9_i2c_devices[8]); // CPLD-IO #2 - Address: 0x38 + client = i2c_new_device(adapter, &ix9_i2c_devices[9]); // CPLD-LED #4 - Address: 0x39 + i2c_put_adapter(adapter); + + adapter = i2c_get_adapter(0x11); + client = i2c_new_device(adapter, &ix9_i2c_devices[8]); // CPLD-IO #3 - Address: 0x38 + client = i2c_new_device(adapter, &ix9_i2c_devices[9]); // CPLD-LED #5 - Address: 0x39 + i2c_put_adapter(adapter); + + adapter = i2c_get_adapter(0x12); + client = i2c_new_device(adapter, &ix9_i2c_devices[3]); // MB_BOARDINFO_EEPROM - Address: 0x54 + i2c_put_adapter(adapter); + + adapter = i2c_get_adapter(0x13); + client = i2c_new_device(adapter, &ix9_i2c_devices[2]); // tca9539_1 Board ID and QSFP-DD PW EN/PG - Address: 0x74 + i2c_put_adapter(adapter); + + adapter = i2c_get_adapter(0x14); + client = i2c_new_device(adapter, &ix9_i2c_devices[4]); // pca9548 #1 QSFPDD - Address: 0x73 + i2c_put_adapter(adapter); + + adapter = i2c_get_adapter(0x15); + client = i2c_new_device(adapter, &ix9_i2c_devices[5]); // pca9548 #2 QSFPDD - Address: 0x73 + i2c_put_adapter(adapter); + + adapter = i2c_get_adapter(0x16); + client = i2c_new_device(adapter, &ix9_i2c_devices[6]); // pca9548 #3 QSFPDD - Address: 0x73 + i2c_put_adapter(adapter); + + adapter = i2c_get_adapter(0x17); + client = i2c_new_device(adapter, &ix9_i2c_devices[7]); // pca9548 #4 QSFPDD - Address: 0x73 + i2c_put_adapter(adapter); + + for(i = 0x20; i < 0x40; i++) + { + adapter = i2c_get_adapter(i); + client = i2c_new_device(adapter, &ix9_i2c_devices[10]); // eeprom for loopback module - Address: 0x50 + i2c_put_adapter(adapter); + } + + return 0; + +fail_platform_device: + platform_device_put(ix9_device); + +fail_platform_driver: + platform_driver_unregister(&ix9_platform_driver); + return ret; +} + +static void __exit ix9_platform_exit(void) +{ + platform_device_unregister(ix9_device); + platform_driver_unregister(&ix9_platform_driver); +} + +module_init(ix9_platform_init); +module_exit(ix9_platform_exit); + +MODULE_AUTHOR("Jonathan Tsai "); +MODULE_VERSION("1.0"); +MODULE_DESCRIPTION("Quanta IX9 Platform Driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/service/ix9-platform-init.service b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/service/ix9-platform-init.service new file mode 100755 index 000000000000..1f33cc170118 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/service/ix9-platform-init.service @@ -0,0 +1,13 @@ +[Unit] +Description=Quanta IX9-32X Platform initialization service +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/quanta_ix9_util.py install +ExecStop=/usr/local/bin/quanta_ix9_util.py clean +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/setup.py b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/setup.py new file mode 100644 index 000000000000..b2f1b39fcd73 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/setup.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='ix9_32x', + version='1.0', + description='Module to initialize Quanta IX9-32X platforms', + + packages=['ix9_32x'], + package_dir={'ix9_32x': 'ix9-32x/classes'}, +) + diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/utils/quanta_ix9_util.py b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/utils/quanta_ix9_util.py new file mode 100755 index 000000000000..4c31aa8584b8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/utils/quanta_ix9_util.py @@ -0,0 +1,217 @@ +#!/usr/bin/env python +# +# Copyright (C) 2018 Quanta Computer Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +from collections import namedtuple + +DEBUG = False +args = [] +FORCE = 0 +i2c_prefix = '/sys/bus/i2c/devices/' + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + install() + elif arg == 'clean': + uninstall() + else: + show_help() + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_log(txt): + if DEBUG == True: + print "[IX9-32X]"+txt + return + +def exec_cmd(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + show_log (cmd +"with result:" + str(status)) + show_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +instantiate =[ +#turn on module power +'echo 21 > /sys/class/gpio/export', +'echo out > /sys/class/gpio/gpio21/direction', +'echo 1 >/sys/class/gpio/gpio21/value', +#Reset fron-ports LED CPLD +'echo 33 > /sys/class/gpio/export', +'echo out > /sys/class/gpio/gpio33/direction', +'echo 0 >/sys/class/gpio/gpio33/value', +'echo 1 >/sys/class/gpio/gpio33/value', +#Enable front-ports LED decoding +'echo 1 > /sys/class/cpld-led/CPLDLED-1/led_decode', +'echo 1 > /sys/class/cpld-led/CPLDLED-2/led_decode', +#Update System LED +'echo 39 > /sys/class/gpio/export', +'echo out > /sys/class/gpio/gpio39/direction', +'echo 0 > /sys/class/gpio/gpio39/value', +'echo 40 > /sys/class/gpio/export', +'echo out > /sys/class/gpio/gpio40/direction', +'echo 1 > /sys/class/gpio/gpio40/value', +] + +drivers =[ +'lpc_ich', +'i2c-i801', +'i2c-dev', +'i2c-mux-pca954x', +'gpio-pca953x', +'qci_cpld_qsfpdd', +'qci_cpld_led', +'qci_platform_ix9', +'ipmi_devintf' +] + + + +def system_install(): + global FORCE + + #remove default drivers to avoid modprobe order conflicts + status, output = exec_cmd("rmmod i2c_ismt ", 1) + status, output = exec_cmd("rmmod i2c-i801 ", 1) + #setup driver dependency + status, output = exec_cmd("depmod -a ", 1) + #install drivers + for i in range(0,len(drivers)): + status, output = exec_cmd("modprobe "+drivers[i], 1) + if status: + print output + if FORCE == 0: + return status + + #remove net rules for generating new net rules + status, output = exec_cmd("systemctl stop systemd-udevd.service ", 1) + status, output = exec_cmd("rm /etc/udev/rules.d/70-persistent-net.rules ", 1) + status, output = exec_cmd("rmmod ixgbe ", 1) + status, output = exec_cmd("rmmod igb ", 1) + status, output = exec_cmd("modprobe igb ", 1) + status, output = exec_cmd("modprobe ixgbe ", 1) + status, output = exec_cmd("systemctl start systemd-udevd.service ", 1) + + #instantiate devices + for i in range(0,len(instantiate)): + status, output = exec_cmd(instantiate[i], 1) + if status: + print output + if FORCE == 0: + return status + + #QSFPDD for 1~32 port + for port_number in range(1,33): + bus_number = port_number + 31 + os.system("echo %d >/sys/bus/i2c/devices/%d-0050/port_name" % (port_number, bus_number)) + + return + +def system_ready(): + if not device_found(): + return False + return True + +def install(): + if not device_found(): + print "No device, installing...." + status = system_install() + if status: + if FORCE == 0: + return status + else: + print " ix9 driver already installed...." + return + +def uninstall(): + global FORCE + #uninstall drivers + for i in range(len(drivers)-1,-1,-1): + status, output = exec_cmd("rmmod "+drivers[i], 1) + if status: + print output + if FORCE == 0: + return status + return + +def device_found(): + ret1, log = exec_cmd("ls "+i2c_prefix+"i2c-0", 0) + return ret1 + +if __name__ == "__main__": + main() + + + diff --git a/platform/cavium/docker-syncd-cavm-rpc.mk b/platform/cavium/docker-syncd-cavm-rpc.mk index cb1077c5a391..e57370fce5ca 100644 --- a/platform/cavium/docker-syncd-cavm-rpc.mk +++ b/platform/cavium/docker-syncd-cavm-rpc.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_CAVM_RPC = docker-syncd-cavm-rpc.gz $(DOCKER_SYNCD_CAVM_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-cavm-rpc $(DOCKER_SYNCD_CAVM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(CAVM_LIBSAI) $(XP_TOOLS) $(REDIS_TOOLS) +$(DOCKER_SYNCD_CAVM_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_CAVM_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/cavium/docker-syncd-cavm.mk b/platform/cavium/docker-syncd-cavm.mk index 5cec8390593f..a136828dbff1 100644 --- a/platform/cavium/docker-syncd-cavm.mk +++ b/platform/cavium/docker-syncd-cavm.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_CAVM = docker-syncd-cavm.gz $(DOCKER_SYNCD_CAVM)_PATH = $(PLATFORM_PATH)/docker-syncd-cavm $(DOCKER_SYNCD_CAVM)_DEPENDS += $(SYNCD) $(CAVM_LIBSAI) $(XP_TOOLS) $(REDIS_TOOLS) +$(DOCKER_SYNCD_CAVM)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_CAVM)_DEPENDS += $(SYNCD_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/cavium/docker-syncd-cavm/Dockerfile.j2 b/platform/cavium/docker-syncd-cavm/Dockerfile.j2 index 800be7e1bb04..0e2bc4b6bbc7 100755 --- a/platform/cavium/docker-syncd-cavm/Dockerfile.j2 +++ b/platform/cavium/docker-syncd-cavm/Dockerfile.j2 @@ -23,6 +23,8 @@ debs/{{ deb }}{{' '}} COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] COPY ["profile.ini", "/etc/ssw/AS7512/"] diff --git a/platform/cavium/docker-syncd-cavm/critical_processes b/platform/cavium/docker-syncd-cavm/critical_processes new file mode 100644 index 000000000000..6082f242b872 --- /dev/null +++ b/platform/cavium/docker-syncd-cavm/critical_processes @@ -0,0 +1 @@ +syncd diff --git a/platform/cavium/docker-syncd-cavm/supervisord.conf b/platform/cavium/docker-syncd-cavm/supervisord.conf index 1af5d70a1d0c..c823ab5680ef 100644 --- a/platform/cavium/docker-syncd-cavm/supervisord.conf +++ b/platform/cavium/docker-syncd-cavm/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/platform/centec/docker-syncd-centec-rpc.mk b/platform/centec/docker-syncd-centec-rpc.mk index 744f60a71ff1..71c8ef7753c1 100644 --- a/platform/centec/docker-syncd-centec-rpc.mk +++ b/platform/centec/docker-syncd-centec-rpc.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_CENTEC_RPC = docker-syncd-centec-rpc.gz $(DOCKER_SYNCD_CENTEC_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-centec-rpc $(DOCKER_SYNCD_CENTEC_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_CENTEC_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_CENTEC_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/centec/docker-syncd-centec.mk b/platform/centec/docker-syncd-centec.mk index 7447dd54717b..360690731a58 100644 --- a/platform/centec/docker-syncd-centec.mk +++ b/platform/centec/docker-syncd-centec.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_CENTEC = docker-syncd-centec.gz $(DOCKER_SYNCD_CENTEC)_PATH = $(PLATFORM_PATH)/docker-syncd-centec $(DOCKER_SYNCD_CENTEC)_DEPENDS += $(SYNCD) +$(DOCKER_SYNCD_CENTEC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_CENTEC)_DEPENDS += $(SYNCD_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/centec/docker-syncd-centec/Dockerfile.j2 b/platform/centec/docker-syncd-centec/Dockerfile.j2 index d5b9bc73eeca..b40103a24f28 100755 --- a/platform/centec/docker-syncd-centec/Dockerfile.j2 +++ b/platform/centec/docker-syncd-centec/Dockerfile.j2 @@ -24,6 +24,8 @@ RUN apt-get install -f kmod COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y diff --git a/platform/centec/docker-syncd-centec/critical_processes b/platform/centec/docker-syncd-centec/critical_processes new file mode 100644 index 000000000000..6082f242b872 --- /dev/null +++ b/platform/centec/docker-syncd-centec/critical_processes @@ -0,0 +1 @@ +syncd diff --git a/platform/centec/docker-syncd-centec/supervisord.conf b/platform/centec/docker-syncd-centec/supervisord.conf index 1af5d70a1d0c..c823ab5680ef 100644 --- a/platform/centec/docker-syncd-centec/supervisord.conf +++ b/platform/centec/docker-syncd-centec/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/platform/innovium/docker-ptf-invm.mk b/platform/innovium/docker-ptf-invm.mk new file mode 100755 index 000000000000..6c81734676fd --- /dev/null +++ b/platform/innovium/docker-ptf-invm.mk @@ -0,0 +1,7 @@ +# docker image for docker-ptf-invm + +DOCKER_PTF_INVM = docker-ptf-invm.gz +$(DOCKER_PTF_INVM)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift +$(DOCKER_PTF_INVM)_DEPENDS += $(PYTHON_SAITHRIFT_INVM) +$(DOCKER_PTF_INVM)_LOAD_DOCKERS += $(DOCKER_PTF) +SONIC_DOCKER_IMAGES += $(DOCKER_PTF_INVM) diff --git a/platform/innovium/docker-syncd-invm-rpc.mk b/platform/innovium/docker-syncd-invm-rpc.mk new file mode 100755 index 000000000000..313f0d12ac20 --- /dev/null +++ b/platform/innovium/docker-syncd-invm-rpc.mk @@ -0,0 +1,17 @@ +# docker image for innovium syncd with rpc + +DOCKER_SYNCD_INVM_RPC = docker-syncd-invm-rpc.gz +$(DOCKER_SYNCD_INVM_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-invm-rpc +$(DOCKER_SYNCD_INVM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(INVM_LIBSAI) +$(DOCKER_SYNCD_INVM_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BASE) +SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_INVM_RPC) +ifeq ($(ENABLE_SYNCD_RPC),y) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_INVM_RPC) +endif + +$(DOCKER_SYNCD_INVM_RPC)_CONTAINER_NAME = syncd +$(DOCKER_SYNCD_INVM_RPC)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SYNCD_INVM_RPC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf +$(DOCKER_SYNCD_INVM_RPC)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd +$(DOCKER_SYNCD_INVM_RPC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_SYNCD_INVM_RPC)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/platform/innovium/docker-syncd-invm-rpc/Dockerfile.j2 b/platform/innovium/docker-syncd-invm-rpc/Dockerfile.j2 new file mode 100755 index 000000000000..af31d587b90a --- /dev/null +++ b/platform/innovium/docker-syncd-invm-rpc/Dockerfile.j2 @@ -0,0 +1,53 @@ +FROM docker-syncd-invm + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +COPY \ +{% for deb in docker_syncd_invm_rpc_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor -%} +debs/ + +RUN dpkg -P syncd + +RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ +{% for deb in docker_syncd_invm_rpc_debs.split(' ') -%} +dpkg_apt debs/{{ deb }}{{'; '}} +{%- endfor %} + +## Pre-install the fundamental packages +RUN apt-get update \ + && apt-get -y install \ + net-tools \ + python-pip \ + build-essential \ + libssl-dev \ + libffi-dev \ + python-dev \ + libpython2.7 \ + libjansson4 \ + wget \ + cmake \ + && wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ + && tar xvfz 1.0.0.tar.gz \ + && cd nanomsg-1.0.0 \ + && mkdir -p build \ + && cmake . \ + && make install \ + && ldconfig \ + && cd .. \ + && rm -fr nanomsg-1.0.0 \ + && rm -f 1.0.0.tar.gz \ + && pip install cffi==1.7.0 \ + && pip install --upgrade cffi==1.7.0 \ + && pip install nnpy \ + && mkdir -p /opt \ + && cd /opt \ + && wget https://github.com/raw/p4lang/ptf/master/ptf_nn/ptf_nn_agent.py \ + && apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y \ + && rm -rf /root/deps + +COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] + +ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/platform/innovium/docker-syncd-invm-rpc/ptf_nn_agent.conf b/platform/innovium/docker-syncd-invm-rpc/ptf_nn_agent.conf new file mode 100755 index 000000000000..fa1ed0eb1622 --- /dev/null +++ b/platform/innovium/docker-syncd-invm-rpc/ptf_nn_agent.conf @@ -0,0 +1,10 @@ +[program:ptf_nn_agent] +command=/usr/bin/python /opt/ptf_nn_agent.py --device-socket 1@tcp://0.0.0.0:10900 -i 1-3@Ethernet12 --set-iface-rcv-buffer=109430400 +process_name=ptf_nn_agent +stdout_logfile=/tmp/ptf_nn_agent.out.log +stderr_logfile=/tmp/ptf_nn_agent.err.log +redirect_stderr=false +autostart=true +autorestart=true +startsecs=1 +numprocs=1 diff --git a/platform/innovium/docker-syncd-invm.mk b/platform/innovium/docker-syncd-invm.mk new file mode 100755 index 000000000000..3ba35c5edb97 --- /dev/null +++ b/platform/innovium/docker-syncd-invm.mk @@ -0,0 +1,13 @@ +# docker image for innovium syncd + +DOCKER_SYNCD_PLATFORM_CODE = invm +include $(PLATFORM_PATH)/../template/docker-syncd-base.mk + +$(DOCKER_SYNCD_BASE)_DEPENDS += $(SYNCD) $(PYTHON_SDK_API) $(INVM_LIBSAI) + +$(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ + $(LIBSWSSCOMMON_DBG) \ + $(LIBSAIMETADATA_DBG) \ + $(LIBSAIREDIS_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 new file mode 100755 index 000000000000..6f6f5eca9b60 --- /dev/null +++ b/platform/innovium/docker-syncd-invm/Dockerfile.j2 @@ -0,0 +1,34 @@ +FROM docker-config-engine-stretch + +ARG docker_container_name +RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update + +COPY \ +{% for deb in docker_syncd_invm_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor -%} +debs/ + +# Needed for Innovium Debug Shell +RUN apt-get install -y net-tools +RUN apt-get install -y libpython2.7 +RUN apt-get install -y libjansson4 + +RUN dpkg -i \ +{% for deb in docker_syncd_invm_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor %} + +COPY ["start.sh", "/usr/bin/"] +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] + +## Clean up +RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y +RUN rm -rf /debs + +ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/platform/innovium/docker-syncd-invm/start.sh b/platform/innovium/docker-syncd-invm/start.sh new file mode 100755 index 000000000000..623316050475 --- /dev/null +++ b/platform/innovium/docker-syncd-invm/start.sh @@ -0,0 +1,7 @@ +#!/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 new file mode 100755 index 000000000000..1af5d70a1d0c --- /dev/null +++ b/platform/innovium/docker-syncd-invm/supervisord.conf @@ -0,0 +1,28 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[program:start.sh] +command=/usr/bin/start.sh +priority=1 +autostart=true +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n +priority=2 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:syncd] +command=/usr/bin/syncd_start.sh +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog diff --git a/platform/innovium/invm-sai.mk b/platform/innovium/invm-sai.mk new file mode 100755 index 000000000000..8c236a8b68d2 --- /dev/null +++ b/platform/innovium/invm-sai.mk @@ -0,0 +1,14 @@ +# INVM SAI + +INVM_SAI_ONLINE = https://github.com/Innovium/SONiC/raw/master/debian/master + +INVM_LIBSAI = isai.deb +INVM_HSAI = saihdr.deb +INVM_DRV = ipd.deb + +$(INVM_LIBSAI)_URL = $(INVM_SAI_ONLINE)/$(INVM_LIBSAI) +$(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/libsaithrift-dev.mk b/platform/innovium/libsaithrift-dev.mk new file mode 100755 index 000000000000..5357705bac98 --- /dev/null +++ b/platform/innovium/libsaithrift-dev.mk @@ -0,0 +1,7 @@ +# libsaithrift-dev package + +LIBSAITHRIFT_DEV_INVM = libsaithrift-dev_0.9.4_$(CONFIGURED_ARCH).deb +$(LIBSAITHRIFT_DEV_INVM)_SRC_PATH = $(SRC_PATH)/sonic-sairedis/SAI +$(LIBSAITHRIFT_DEV_INVM)_DEPENDS += $(LIBTHRIFT) $(LIBTHRIFT_DEV) $(THRIFT_COMPILER) $(INVM_LIBSAI) $(INVM_HSAI) +$(LIBSAITHRIFT_DEV_INVM)_RDEPENDS += $(LIBTHRIFT) $(INVM_HSAI) +SONIC_DPKG_DEBS += $(LIBSAITHRIFT_DEV_INVM) diff --git a/platform/innovium/one-image.mk b/platform/innovium/one-image.mk new file mode 100755 index 000000000000..c88ec5e65cdf --- /dev/null +++ b/platform/innovium/one-image.mk @@ -0,0 +1,11 @@ +# sonic innovium ONE image installer + +SONIC_ONE_IMAGE = sonic-innovium.bin +$(SONIC_ONE_IMAGE)_MACHINE = innovium +$(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) +$(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CEL_MIDSTONE_200I_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELTA_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_INSTALLS += $(INVM_DRV) +$(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) +SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/innovium/platform-modules-cel.mk b/platform/innovium/platform-modules-cel.mk new file mode 100755 index 000000000000..b93bea758d71 --- /dev/null +++ b/platform/innovium/platform-modules-cel.mk @@ -0,0 +1,12 @@ +# Celestica platform modules + +CEL_PLATFORM_MODULE_VERSION = 0.2.2 + +export CEL_PLATFORM_MODULE_VERSION + +CEL_MIDSTONE_200I_PLATFORM_MODULE = platform-modules-midstone-200i_$(CEL_PLATFORM_MODULE_VERSION)_$(CONFIGURED_ARCH).deb +$(CEL_MIDSTONE_200I_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cel +$(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 new file mode 100644 index 000000000000..68e13fb8a8a4 --- /dev/null +++ b/platform/innovium/platform-modules-delta.mk @@ -0,0 +1,13 @@ +# Delta Platform modules + +DELTA_ETC032IF_PLATFORM_MODULE_VERSION = 1.1 + +export DELTA_ETC032IF_PLATFORM_MODULE_VERSION + +DELTA_PLATFORM_MODULE = platform-modules-et-c032if_$(DELTA_ETC032IF_PLATFORM_MODULE_VERSION)_$(CONFIGURED_ARCH).deb +$(DELTA_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-delta +$(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/platform.conf b/platform/innovium/platform.conf new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/innovium/python-saithrift.mk b/platform/innovium/python-saithrift.mk new file mode 100755 index 000000000000..23d7df188346 --- /dev/null +++ b/platform/innovium/python-saithrift.mk @@ -0,0 +1,6 @@ +# python-saithrift package + +PYTHON_SAITHRIFT_INVM = python-saithrift_1.2.1_$(CONFIGURED_ARCH).deb +$(PYTHON_SAITHRIFT_INVM)_SRC_PATH = $(SRC_PATH)/SAI +$(PYTHON_SAITHRIFT_INVM)_DEPENDS += $(INVM_LIBSAI) $(INVM_HSAI) $(THRIFT_COMPILER) $(PYTHON_THRIFT) $(LIBTHRIFT_DEV) +SONIC_DPKG_DEBS += $(PYTHON_SAITHRIFT_INVM) diff --git a/platform/innovium/rules.mk b/platform/innovium/rules.mk new file mode 100755 index 000000000000..68a9dbb41040 --- /dev/null +++ b/platform/innovium/rules.mk @@ -0,0 +1,20 @@ +include $(PLATFORM_PATH)/invm-sai.mk +include $(PLATFORM_PATH)/platform-modules-cel.mk +include $(PLATFORM_PATH)/platform-modules-delta.mk +include $(PLATFORM_PATH)/docker-syncd-invm.mk +include $(PLATFORM_PATH)/docker-syncd-invm-rpc.mk +include $(PLATFORM_PATH)/one-image.mk +include $(PLATFORM_PATH)/libsaithrift-dev.mk +include $(PLATFORM_PATH)/python-saithrift.mk +include $(PLATFORM_PATH)/docker-ptf-invm.mk + +SONIC_ALL += $(SONIC_INVM_ONE_IMAGE) \ + $(DOCKER_FPM) \ + $(DOCKER_PTF_INVM) \ + $(DOCKER_SYNCD_INVM_RPC) + +# Inject invm sai into sairedis +$(LIBSAIREDIS)_DEPENDS += $(INVM_HSAI) $(INVM_LIBSAI) $(LIBSAITHRIFT_DEV_INVM) + +# Runtime dependency on invm sai is set only for syncd +$(SYNCD)_RDEPENDS += $(INVM_HSAI) diff --git a/platform/innovium/sonic-platform-modules-cel/.gitignore b/platform/innovium/sonic-platform-modules-cel/.gitignore new file mode 100755 index 000000000000..f805e810e5c6 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cel/.gitignore @@ -0,0 +1,33 @@ +# Object files +*.o +*.ko +*.obj +*.elf + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su diff --git a/platform/innovium/sonic-platform-modules-cel/LICENSE b/platform/innovium/sonic-platform-modules-cel/LICENSE new file mode 100755 index 000000000000..2386a3920c07 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cel/LICENSE @@ -0,0 +1,15 @@ +Copyright (C) 2017 Celestica, Inc + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. diff --git a/platform/innovium/sonic-platform-modules-cel/README.md b/platform/innovium/sonic-platform-modules-cel/README.md new file mode 100755 index 000000000000..fbda62f91eae --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cel/README.md @@ -0,0 +1 @@ +# Platform drivers for Celestica Midstone-200i for the SONiC project diff --git a/platform/innovium/sonic-platform-modules-cel/debian/changelog b/platform/innovium/sonic-platform-modules-cel/debian/changelog new file mode 100755 index 000000000000..4a4e5ed2b0a0 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cel/debian/changelog @@ -0,0 +1,28 @@ +sonic-cel-platform-modules (0.2.2) unstable; urgency=low + + * Remove I2c mux ininitialization in init-script. + * Remapping virtual I2c ports number in sfputil. + * Fix qsfp driver, missing present status of sfp+ ports. + * Updated sfputil for decode sfp+ EEPROM. + * Add watchdog driver. + + -- Wirut Getbamrung Wed, 1 Feb 2018 16:00:00 +0700 + +sonic-cel-platform-modules (0.2.1) unstable; urgency=low + + * Fix module init-script not load CPLD virtual i2c driver properly. + + -- Pradchaya Phucharoen Mon, 9 Oct 2017 14:24:25 +0700 + +sonic-cel-platform-modules (0.2.0) unstable; urgency=low + + * Add sysfs interface to reset sfp ports. + * Fix qsfp driver, low power mode set/get incorrect bit. + + -- Pradchaya Phucharoen Tue, 26 Sep 2017 11:50:23 +0700 + +sonic-cel-platform-modules (0.1) unstable; urgency=low + + * Initial platform module. + + -- Pradchaya Phucharoen Tue, 23 Aug 2017 10:43:00 +0700 diff --git a/platform/innovium/sonic-platform-modules-cel/debian/compat b/platform/innovium/sonic-platform-modules-cel/debian/compat new file mode 100755 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cel/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/innovium/sonic-platform-modules-cel/debian/control b/platform/innovium/sonic-platform-modules-cel/debian/control new file mode 100755 index 000000000000..48ef777a99a6 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cel/debian/control @@ -0,0 +1,11 @@ +Source: sonic-cel-platform-modules +Section: main +Priority: extra +Maintainer: Wirut Getbamrung +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: platform-modules-midstone-200i +Architecture: amd64 +Depends: linux-image-4.9.0-9-2-amd64 +Description: kernel modules for platform devices diff --git a/platform/innovium/sonic-platform-modules-cel/debian/platform-modules-midstone-200i.init b/platform/innovium/sonic-platform-modules-cel/debian/platform-modules-midstone-200i.init new file mode 100755 index 000000000000..7074d2b58125 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cel/debian/platform-modules-midstone-200i.init @@ -0,0 +1,52 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: $portmap +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup 200i board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + + # Attach TLV 0x56 eeprom + echo 24lc64t 0x56 > /sys/bus/i2c/devices/i2c-0/new_device + sleep 2 + + modprobe 200i-cpld + sleep 2 + + # Turn off/down lpmod by defult (0 - Normal, 1 - Low Pow) + echo 0x00 > /sys/devices/platform/ms200i_cpld/qsfp_lpmode + + # Attach 64 instances of EEPROM driver QSFP ports + for ((n=1;n<=66;n++)); + do + echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$n/new_device + sleep 0.1 + done + + echo "done." + ;; + +stop) + echo "done." + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-200i.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/innovium/sonic-platform-modules-cel/debian/platform-modules-midstone-200i.install b/platform/innovium/sonic-platform-modules-cel/debian/platform-modules-midstone-200i.install new file mode 100644 index 000000000000..4f298feb8300 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cel/debian/platform-modules-midstone-200i.install @@ -0,0 +1,2 @@ +midstone-200i/cfg/midstone-200i-modules.conf etc/modules-load.d +midstone-200i/systemd/platform-modules-midstone-200i.service lib/systemd/system \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cel/debian/platform-modules-midstone-200i.postinst b/platform/innovium/sonic-platform-modules-cel/debian/platform-modules-midstone-200i.postinst new file mode 100644 index 000000000000..213661ea1e84 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cel/debian/platform-modules-midstone-200i.postinst @@ -0,0 +1,3 @@ +depmod -a +systemctl enable platform-modules-midstone-200i.service +systemctl start platform-modules-midstone-200i.service \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cel/debian/rules b/platform/innovium/sonic-platform-modules-cel/debian/rules new file mode 100755 index 000000000000..3b01ad7e6555 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cel/debian/rules @@ -0,0 +1,32 @@ +#!/usr/bin/make -f + +export INSTALL_MOD_DIR:=extra + +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= midstone-200i + +%: + dh $@ + +override_dh_auto_build: + (for mod in $(MODULE_DIRS); do \ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ + done) + +override_dh_auto_install: + (for mod in $(MODULE_DIRS); do \ + dh_installdirs -pplatform-modules-$${mod} \ + $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/modules/*.ko \ + debian/platform-modules-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + done) + +override_dh_usrlocal: + +override_dh_clean: + dh_clean + (for mod in $(MODULE_DIRS); do \ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \ + done) diff --git a/platform/innovium/sonic-platform-modules-cel/midstone-200i/cfg/midstone-200i-modules.conf b/platform/innovium/sonic-platform-modules-cel/midstone-200i/cfg/midstone-200i-modules.conf new file mode 100755 index 000000000000..b2a3e351c4c9 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cel/midstone-200i/cfg/midstone-200i-modules.conf @@ -0,0 +1,15 @@ +# /etc/modules: kernel modules to load at boot time. +# +# This file contains the names of kernel modules that should be loaded +# at boot time, one per line. Lines beginning with "#" are ignored. + +i2c-i801 +i2c-isch +i2c-ismt +i2c-dev +i2c-mux +i2c-smbus + +i2c-mux-gpio +i2c-mux-pca954x +ipmi-devintf diff --git a/platform/innovium/sonic-platform-modules-cel/midstone-200i/modules/200i_cpld.c b/platform/innovium/sonic-platform-modules-cel/midstone-200i/modules/200i_cpld.c new file mode 100755 index 000000000000..3a99d2304029 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cel/midstone-200i/modules/200i_cpld.c @@ -0,0 +1,854 @@ +/* + * ms200i_cpld.c - driver for MidStone's CPLD + * + * Copyright (C) 2017 Celestica Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "ms200i_cpld" + +#define RESET0102 0xA248 +#define RESET0310 0xA2DC +#define RESET1118 0xA2DD +#define RESET1926 0xA2DE +#define RESET2733 0xA2DF +#define RESET3441 0xA31C +#define RESET4249 0xA31D +#define RESET5057 0xA31E +#define RESET5864 0xA31F + +#define LPMOD0102 0xA249 +#define LPMOD0310 0xA2E0 +#define LPMOD1118 0xA2E1 +#define LPMOD1926 0xA2E2 +#define LPMOD2733 0xA2E3 +#define LPMOD3441 0xA320 +#define LPMOD4249 0xA321 +#define LPMOD5057 0xA322 +#define LPMOD5864 0xA323 + +#define ABS0102 0xA24A +#define ABS0310 0xA2E4 +#define ABS1118 0xA2E5 +#define ABS1926 0xA2E6 +#define ABS2733 0xA2E7 +#define ABS3441 0xA324 +#define ABS4249 0xA325 +#define ABS5057 0xA326 +#define ABS5864 0xA327 + +#define ABS6566 0xA244 + +#define INT0102 0xA24B +#define INT0310 0xA2E8 +#define INT1118 0xA2E9 +#define INT1926 0xA2EA +#define INT2733 0xA2EB +#define INT3441 0xA328 +#define INT4249 0xA329 +#define INT5057 0xA32A +#define INT5864 0xA32B + +#define LENGTH_PORT_CPLD 66 + +#define CPLD2_EX_CP_I2CFDR0_I2C 0xA230 +#define CPLD2_EX_CP_I2CCR0_I2C 0xA231 +#define CPLD2_EX_CP_I2CSR0_I2C 0xA232 +#define CPLD2_EX_CP_I2CDR0_I2C 0xA233 +#define CPLD2_EX_CP_I2CID0_I2C 0xA234 + +#define CPLD3_EX_CP_I2CFDR0_I2C 0xA2D0 +#define CPLD3_EX_CP_I2CCR0_I2C 0xA2D1 +#define CPLD3_EX_CP_I2CSR0_I2C 0xA2D2 +#define CPLD3_EX_CP_I2CDR0_I2C 0xA2D3 +#define CPLD3_EX_CP_I2CID0_I2C 0xA2D4 + +#define CPLD4_EX_CP_I2CFDR0_I2C 0xA310 +#define CPLD4_EX_CP_I2CCR0_I2C 0xA311 +#define CPLD4_EX_CP_I2CSR0_I2C 0xA312 +#define CPLD4_EX_CP_I2CDR0_I2C 0xA313 +#define CPLD4_EX_CP_I2CID0_I2C 0xA314 + +enum { + I2C_SR_BIT_RXAK = 0, + I2C_SR_BIT_MIF, + I2C_SR_BIT_SRW, + I2C_SR_BIT_BCSTM, + I2C_SR_BIT_MAL, + I2C_SR_BIT_MBB, + I2C_SR_BIT_MAAS, + I2C_SR_BIT_MCF +}; + +enum { + I2C_CR_BIT_BCST = 0, + I2C_CR_BIT_RSTA = 2, + I2C_CR_BIT_TXAK, + I2C_CR_BIT_MTX, + I2C_CR_BIT_MSTA, + I2C_CR_BIT_MIEN, + I2C_CR_BIT_MEN, +}; + +#ifdef DEBUG_KERN +#define info(fmt,args...) printk(KERN_INFO "line %3d : "fmt,__LINE__,##args) +#define check(REG) printk(KERN_INFO "line %3d : %-8s = %2.2X",__LINE__,#REG,inb(REG)); +#else +#define info(fmt,args...) +#define check(REG) +#endif + +#define GET_REG_BIT(REG,BIT) ((inb(REG) >> BIT) & 0x01) +#define SET_REG_BIT_H(REG,BIT) outb(inb(REG) | (0x01 << BIT),REG) +#define SET_REG_BIT_L(REG,BIT) outb(inb(REG) & ~(0x01 << BIT),REG) + +struct ms200i_i2c_data { + int portid; + unsigned REG_FDR0; + unsigned REG_CR0; + unsigned REG_SR0; + unsigned REG_DR0; + unsigned REG_ID0; +}; + +struct ms200i_cpld_data { + struct i2c_adapter *i2c_adapter[LENGTH_PORT_CPLD]; + struct mutex cpld_lock; + unsigned char sfpp_lpmode[2]; + unsigned char sfpp_reset[2]; +}; + +struct ms200i_cpld_data *cpld_data; + +int strtobp(const char* str,unsigned char *bytes){ + unsigned length = strlen(str); + if(length > 20){ + return 0; + } + int i,b=0; + memset(bytes,0,10); + for(i=0;i= '0' && c <= '9'){ + byte = c - '0'; + }else if(c >= 'a' && c <= 'f'){ + byte = c - 'a' + 0x0a; + }else if(c >= 'A' && c <= 'F'){ + byte = c - 'A' + 0x0a; + }else if(c == 'x' || c == 'X'){ + break; + }else{ + continue; + } + if(b%2==0) + bytes[b/2] = byte & 0x0F; + else + bytes[b/2] += (byte << 4) & 0xF0; + b++; + } + return (i/2) + (i%2); +} + +static ssize_t get_reset(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned long reset = 0; + + mutex_lock(&cpld_data->cpld_lock); + + reset = + ((unsigned long)(inb(RESET5864) & 0x7F) << 57 )| + ((unsigned long) inb(RESET5057) << 49 )| + ((unsigned long) inb(RESET4249) << 41 )| + ((unsigned long) inb(RESET3441) << 33 )| + ((unsigned long)(inb(RESET2733) & 0x7F) << 26 )| + ((unsigned long) inb(RESET1926) << 18 )| + ((unsigned long) inb(RESET1118) << 10 )| + ((unsigned long) inb(RESET0310) << 2 )| + ((unsigned long)(inb(RESET0102) & 0x03) ); + + mutex_unlock(&cpld_data->cpld_lock); + + return sprintf(buf,"0x%x%16.16lx\n", + cpld_data->sfpp_reset[1] << 1 | cpld_data->sfpp_reset[0], + reset & 0x3ffffffffffffffff); +} + +static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned char reset[10]; + int num; + + mutex_lock(&cpld_data->cpld_lock); + + num = strtobp(buf,reset); + if (num <= 0) + { + mutex_unlock(&cpld_data->cpld_lock); + return 22; + } + + outb (( reset[0] & 0x03 ) ,RESET0102); + outb (((reset[0] >>2) & 0x3F) | + (((reset[1] ) & 0x03) << 6),RESET0310); + outb (((reset[1] >>2) & 0x3F) | + (((reset[2] ) & 0x03) << 6),RESET1118); + outb (((reset[2] >>2) & 0x3F) | + (((reset[3] ) & 0x03) << 6),RESET1926); + outb (((reset[3] >>2) & 0x3F) | + (((reset[4] ) & 0x01) << 6),RESET2733); + outb (((reset[4] >>1) & 0x7F) | + (((reset[5] ) & 0x01) << 7),RESET3441); + outb (((reset[5] >>1) & 0x7F) | + (((reset[6] ) & 0x01) << 7),RESET4249); + outb (((reset[6] >>1) & 0x7F) | + (((reset[7] ) & 0x01) << 7),RESET5057); + outb (((reset[7] >>1) & 0x7F) ,RESET5864); + + cpld_data->sfpp_reset[0] = reset[8] & 0x01; + cpld_data->sfpp_reset[1] = (reset[8]>>1) & 0x01; + + mutex_unlock(&cpld_data->cpld_lock); + + return count; +} + +static ssize_t get_lpmode(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned long lpmod = 0; + + mutex_lock(&cpld_data->cpld_lock); + + lpmod = + ((unsigned long)(inb(LPMOD5864) & 0x7F) << 57 )| + ((unsigned long) inb(LPMOD5057) << 49 )| + ((unsigned long) inb(LPMOD4249) << 41 )| + ((unsigned long) inb(LPMOD3441) << 33 )| + ((unsigned long)(inb(LPMOD2733) & 0x7F) << 26 )| + ((unsigned long) inb(LPMOD1926) << 18 )| + ((unsigned long) inb(LPMOD1118) << 10 )| + ((unsigned long) inb(LPMOD0310) << 2 )| + ((unsigned long)(inb(LPMOD0102) & 0x03) ); + + mutex_unlock(&cpld_data->cpld_lock); + + return sprintf(buf,"0x%x%16.16lx\n", + cpld_data->sfpp_lpmode[1] << 1 | cpld_data->sfpp_lpmode[0], + lpmod & 0xffffffffffffffff); +} + +static ssize_t set_lpmode(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned char lpmod[10]; + int num; + + mutex_lock(&cpld_data->cpld_lock); + + num = strtobp(buf,lpmod); + if (num <= 0) + { + mutex_unlock(&cpld_data->cpld_lock); + return 22; + } + + outb (( lpmod[0] & 0x03 ) ,LPMOD0102); + outb (((lpmod[0] >>2) & 0x3F) | + (((lpmod[1] ) & 0x03) << 6),LPMOD0310); + outb (((lpmod[1] >>2) & 0x3F) | + (((lpmod[2] ) & 0x03) << 6),LPMOD1118); + outb (((lpmod[2] >>2) & 0x3F) | + (((lpmod[3] ) & 0x03) << 6),LPMOD1926); + outb (((lpmod[3] >>2) & 0x3F) | + (((lpmod[4] ) & 0x01) << 6),LPMOD2733); + outb (((lpmod[4] >>1) & 0x7F) | + (((lpmod[5] ) & 0x01) << 7),LPMOD3441); + outb (((lpmod[5] >>1) & 0x7F) | + (((lpmod[6] ) & 0x01) << 7),LPMOD4249); + outb (((lpmod[6] >>1) & 0x7F) | + (((lpmod[7] ) & 0x01) << 7),LPMOD5057); + outb (((lpmod[7] >>1) & 0x7F) ,LPMOD5864); + + cpld_data->sfpp_lpmode[0] = lpmod[8] & 0x01; + cpld_data->sfpp_lpmode[1] = (lpmod[8]>>1) & 0x01; + + mutex_unlock(&cpld_data->cpld_lock); + + return count; +} + +static ssize_t get_modprs(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned long present; + int present_sfp; + + mutex_lock(&cpld_data->cpld_lock); + present = + ((unsigned long)(inb(ABS5864) & 0x7F) << 57 )| + ((unsigned long) inb(ABS5057) << 49 )| + ((unsigned long) inb(ABS4249) << 41 )| + ((unsigned long) inb(ABS3441) << 33 )| + ((unsigned long)(inb(ABS2733) & 0x7F) << 26 )| + ((unsigned long) inb(ABS1926) << 18 )| + ((unsigned long) inb(ABS1118) << 10 )| + ((unsigned long) inb(ABS0310) << 2 )| + ((unsigned long)(inb(ABS0102) & 0x03) ); + + present_sfp = (inb(ABS6566) & 0x03); + mutex_unlock(&cpld_data->cpld_lock); + + return sprintf(buf,"0x%d%16.16lx\n", present_sfp, present & 0xffffffffffffffff); +} + +static ssize_t get_modirq(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned long irq; + + mutex_lock(&cpld_data->cpld_lock); + + irq = + ((unsigned long)(inb(INT5864) & 0x7F) << 57 )| + ((unsigned long) inb(INT5057) << 49 )| + ((unsigned long) inb(INT4249) << 41 )| + ((unsigned long) inb(INT3441) << 33 )| + ((unsigned long)(inb(INT2733) & 0x7F) << 26 )| + ((unsigned long) inb(INT1926) << 18 )| + ((unsigned long) inb(INT1118) << 10 )| + ((unsigned long) inb(INT0310) << 2 )| + ((unsigned long)(inb(INT0102) & 0x03) ); + + mutex_unlock(&cpld_data->cpld_lock); + + return sprintf(buf,"0x%17.17lx\n", irq & 0x3ffffffffffffffff); +} + +static DEVICE_ATTR(qsfp_reset , S_IRUGO | S_IWUSR, get_reset, set_reset); +static DEVICE_ATTR(qsfp_lpmode, S_IRUGO | S_IWUSR, get_lpmode, set_lpmode); +static DEVICE_ATTR(qsfp_modprs, S_IRUGO, get_modprs, NULL); +static DEVICE_ATTR(qsfp_modirq, S_IRUGO, get_modirq, NULL); + +static struct attribute *ms200i_lpc_attrs[] = { + &dev_attr_qsfp_reset.attr, + &dev_attr_qsfp_lpmode.attr, + &dev_attr_qsfp_modprs.attr, + &dev_attr_qsfp_modirq.attr, + NULL, +}; + +static struct attribute_group ms200i_lpc_attr_grp = { + .attrs = ms200i_lpc_attrs, +}; + +static struct resource cel_ms200i_lpc_resources[] = { + { + .flags = IORESOURCE_IO, + }, +}; + +static void cel_ms200i_lpc_dev_release( struct device * dev) +{ + return; +} + +static struct platform_device cel_ms200i_lpc_dev = { + .name = DRIVER_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(cel_ms200i_lpc_resources), + .resource = cel_ms200i_lpc_resources, + .dev = { + .release = cel_ms200i_lpc_dev_release, + } +}; + + +static int i2c_wait_ack(struct i2c_adapter *a,unsigned timeout,int writing){ + int error = 0; + unsigned tick=0; + int Status; + + struct ms200i_i2c_data *new_data = i2c_get_adapdata(a); + + check(new_data->REG_SR0); + check(new_data->REG_CR0); + + while(1){ + Status = inb(new_data->REG_SR0); + tick++; + if(tick > timeout){ + info("Status %2.2X",Status); + info("Error Timeout"); + error = -ETIMEDOUT; + break; + } + + + if(Status & (1 << I2C_SR_BIT_MIF)){ + break; + } + + if(writing == 0 && (Status & (1<REG_SR0); + outb(0, new_data->REG_SR0); + + if(error<0){ + info("Status %2.2X",Status); + return error; + } + + if(!(Status & (1 << I2C_SR_BIT_MCF))){ + info("Error Unfinish"); + return -EIO; + } + + if(Status & (1 <REG_CR0,1<cpld_lock); + + /* Write the command register */ + new_data = i2c_get_adapdata(a); + + unsigned int portid = new_data->portid; + +#ifdef DEBUG_KERN + printk(KERN_INFO "portid %2d|@ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-10s|CMD %2.2X |DAT %4.4X" + ,portid,addr,flags,rw,rw == 1 ? "READ ":"WRITE" + ,size, size == 0 ? "QUICK" : + size == 1 ? "BYTE" : + size == 2 ? "BYTE_DATA" : + size == 3 ? "WORD_DATA" : + size == 4 ? "PROC_CALL" : + size == 5 ? "BLOCK_DATA" : "ERROR" + ,cmd,data->word); +#endif + /* Map the size to what the chip understands */ + switch (size) { + case I2C_SMBUS_QUICK: + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + case I2C_SMBUS_WORD_DATA: + case I2C_SMBUS_BLOCK_DATA: + break; + default: + printk(KERN_INFO "Unsupported transaction %d\n", size); + error = -EOPNOTSUPP; + goto Done; + } + + unsigned int REG_FDR0; + unsigned int REG_CR0; + unsigned int REG_SR0; + unsigned int REG_DR0; + unsigned int REG_ID0; + + REG_FDR0 = new_data->REG_FDR0; + REG_CR0 = new_data->REG_CR0; + REG_SR0 = new_data->REG_SR0; + REG_DR0 = new_data->REG_DR0; + REG_ID0 = new_data->REG_ID0; + outb(portid,REG_ID0); + + int timeout=0; + int cnt=0; + + ////[S][ADDR/R] + //Clear status register + outb( 0 , REG_SR0); + outb( 1 << I2C_CR_BIT_MIEN | 1 << I2C_CR_BIT_MTX | 1 << I2C_CR_BIT_MSTA ,REG_CR0); + SET_REG_BIT_H(REG_CR0,I2C_CR_BIT_MEN); + + if(rw == I2C_SMBUS_READ && + (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE)){ + // sent device address with Read mode + outb(addr << 1 | 0x01,REG_DR0); + }else{ + // sent device address with Write mode + outb(addr << 1 | 0x00,REG_DR0); + } + + + + info( "MS Start"); + + //// Wait {A} + error = i2c_wait_ack(a,50000,1); + if(error<0){ + info( "get error %d",error); + goto Done; + } + + //// [CMD]{A} + if(size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA || + (size == I2C_SMBUS_BYTE && rw == I2C_SMBUS_WRITE)){ + + //sent command code to data register + outb(cmd,REG_DR0); + info( "MS Send CMD 0x%2.2X",cmd); + + // Wait {A} + error = i2c_wait_ack(a,50000,1); + if(error<0){ + info( "get error %d",error); + goto Done; + } + } + + switch(size){ + case I2C_SMBUS_BYTE_DATA: + cnt = 1; break; + case I2C_SMBUS_WORD_DATA: + cnt = 2; break; + case I2C_SMBUS_BLOCK_DATA: + // in block data mode keep number of byte in block[0] + cnt = data->block[0]; + break; + default: + cnt = 0; break; + } + + // [CNT] used only bloack data write + if(size == I2C_SMBUS_BLOCK_DATA && rw == I2C_SMBUS_WRITE){ + + outb(cnt,REG_DR0); + info( "MS Send CNT 0x%2.2X",cnt); + + // Wait {A} + error = i2c_wait_ack(a,50000,1); + if(error<0){ + info( "get error %d",error); + goto Done; + } + } + + // [DATA]{A} + if( rw == I2C_SMBUS_WRITE && ( + size == I2C_SMBUS_BYTE || + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA + )){ + int bid=0; + info( "MS prepare to sent [%d bytes]",cnt); + if(size == I2C_SMBUS_BLOCK_DATA ){ + bid=1; // block[0] is cnt; + cnt+=1; // offset from block[0] + } + for(;bidblock[bid],REG_DR0); + info( " Data > %2.2X",data->block[bid]); + // Wait {A} + error = i2c_wait_ack(a,50000,1); + if(error<0){ + goto Done; + } + } + + } + + //REPEATE START + if( rw == I2C_SMBUS_READ && ( + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA + )){ + info( "MS Repeated Start"); + + SET_REG_BIT_L(REG_CR0,I2C_CR_BIT_MEN); + outb(1 << I2C_CR_BIT_MIEN | + 1 << I2C_CR_BIT_MTX | + 1 << I2C_CR_BIT_MSTA | + 1 << I2C_CR_BIT_RSTA ,REG_CR0); + SET_REG_BIT_H(REG_CR0,I2C_CR_BIT_MEN); + + // sent Address with Read mode + outb( addr<<1 | 0x1 ,REG_DR0); + + // Wait {A} + error = i2c_wait_ack(a,50000,1); + if(error<0){ + goto Done; + } + + } + + if( rw == I2C_SMBUS_READ && ( + size == I2C_SMBUS_BYTE || + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA + )){ + + switch(size){ + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + cnt = 1; break; + case I2C_SMBUS_WORD_DATA: + cnt = 2; break; + case I2C_SMBUS_BLOCK_DATA: + //will be changed after recived first data + cnt = 3; break; + default: + cnt = 0; break; + } + + int bid = 0; + info( "MS Receive"); + + //set to Receive mode + outb(1 << I2C_CR_BIT_MEN | + 1 << I2C_CR_BIT_MIEN | + 1 << I2C_CR_BIT_MSTA , REG_CR0); + + for(bid=-1;bidblock[bid] = inb(REG_DR0); + + info( "DATA IN [%d] %2.2X",bid,data->block[bid]); + + if(size==I2C_SMBUS_BLOCK_DATA && bid == 0){ + cnt = data->block[0] + 1; + } + } + } + } + + +Stop: + //[P] + SET_REG_BIT_L(REG_CR0,I2C_CR_BIT_MSTA); + info( "MS STOP"); + +Done: + outb(1<cpld_lock); + + return error; +} + +static u32 ms200i_i2c_func(struct i2c_adapter *a) +{ + return I2C_FUNC_SMBUS_QUICK | + I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_BLOCK_DATA; +} + +static const struct i2c_algorithm ms200i_i2c_algorithm = { + .smbus_xfer = ms200i_i2c_access, + .functionality = ms200i_i2c_func, +}; + +static struct i2c_adapter * cel_ms200i_i2c_init(struct platform_device *pdev, int portid) +{ + int error; + + struct i2c_adapter *new_adapter; + struct ms200i_i2c_data *new_data; + + new_adapter = kzalloc(sizeof(*new_adapter), GFP_KERNEL); + if (!new_adapter) + return NULL; + + new_adapter->dev.parent = &pdev->dev; + new_adapter->owner = THIS_MODULE; + new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + new_adapter->algo = &ms200i_i2c_algorithm; + + snprintf(new_adapter->name, sizeof(new_adapter->name), + "SMBus ms200i i2c Adapter portid@%04x", portid); + + new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); + if (!new_data) + return NULL; + + new_data->portid = portid; + + // QSFP 1-2 and SFP 1-2 + if((portid >= 1 && portid <= 2) || (portid >= 65 && portid <= 66)){ + new_data->REG_FDR0 = CPLD2_EX_CP_I2CFDR0_I2C; + new_data->REG_CR0 = CPLD2_EX_CP_I2CCR0_I2C; + new_data->REG_SR0 = CPLD2_EX_CP_I2CSR0_I2C; + new_data->REG_DR0 = CPLD2_EX_CP_I2CDR0_I2C; + new_data->REG_ID0 = CPLD2_EX_CP_I2CID0_I2C; + + }else if((portid >= 3 && portid <= 33)){ + new_data->REG_FDR0 = CPLD3_EX_CP_I2CFDR0_I2C; + new_data->REG_CR0 = CPLD3_EX_CP_I2CCR0_I2C; + new_data->REG_SR0 = CPLD3_EX_CP_I2CSR0_I2C; + new_data->REG_DR0 = CPLD3_EX_CP_I2CDR0_I2C; + new_data->REG_ID0 = CPLD3_EX_CP_I2CID0_I2C; + + }else if((portid >= 34 && portid <= 64)){ + new_data->REG_FDR0 = CPLD4_EX_CP_I2CFDR0_I2C; + new_data->REG_CR0 = CPLD4_EX_CP_I2CCR0_I2C; + new_data->REG_SR0 = CPLD4_EX_CP_I2CSR0_I2C; + new_data->REG_DR0 = CPLD4_EX_CP_I2CDR0_I2C; + new_data->REG_ID0 = CPLD4_EX_CP_I2CID0_I2C; + } + outb(portid,new_data->REG_ID0); + outb(0x1F,new_data->REG_FDR0); // 0x1F 100kHz + + + i2c_set_adapdata(new_adapter,new_data); + + error = i2c_add_adapter(new_adapter); + if(error) + return NULL; + + return new_adapter; +}; + +static int cel_ms200i_lpc_drv_probe(struct platform_device *pdev) +{ + struct resource *res; + int ret =0; + int portid_count; + + cpld_data = devm_kzalloc(&pdev->dev, sizeof(struct ms200i_cpld_data), + GFP_KERNEL); + if (!cpld_data) + return -ENOMEM; + + mutex_init(&cpld_data->cpld_lock); + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (unlikely(!res)) { + printk(KERN_ERR " Specified Resource Not Available...\n"); + return -1; + } + + ret = sysfs_create_group(&pdev->dev.kobj, &ms200i_lpc_attr_grp); + if (ret) { + printk(KERN_ERR "Cannot create sysfs\n"); + } + + for(portid_count=1 ; portid_count<=LENGTH_PORT_CPLD ; portid_count++) + cpld_data->i2c_adapter[portid_count-1] = cel_ms200i_i2c_init(pdev, portid_count); + return 0; +} + +static int cel_ms200i_lpc_drv_remove(struct platform_device *pdev) +{ + int portid_count; + struct ms200i_i2c_data *new_data; + + sysfs_remove_group(&pdev->dev.kobj, &ms200i_lpc_attr_grp); + + for (portid_count=1 ; portid_count<=LENGTH_PORT_CPLD ; portid_count++) + i2c_del_adapter(cpld_data->i2c_adapter[portid_count-1]); + return 0; +} + +static struct platform_driver cel_ms200i_lpc_drv = { + .probe = cel_ms200i_lpc_drv_probe, + .remove = __exit_p(cel_ms200i_lpc_drv_remove), + .driver = { + .name = DRIVER_NAME, + }, +}; + +int cel_ms200i_lpc_init(void) +{ + platform_device_register(&cel_ms200i_lpc_dev); + platform_driver_register(&cel_ms200i_lpc_drv); + + return 0; +} + +void cel_ms200i_lpc_exit(void) +{ + platform_driver_unregister(&cel_ms200i_lpc_drv); + platform_device_unregister(&cel_ms200i_lpc_dev); +} + +module_init(cel_ms200i_lpc_init); +module_exit(cel_ms200i_lpc_exit); + +MODULE_AUTHOR("Pariwat Leamsumran "); +MODULE_DESCRIPTION("Celestica MidStone ms200i LPC Driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/innovium/sonic-platform-modules-cel/midstone-200i/modules/200i_wdt.c b/platform/innovium/sonic-platform-modules-cel/midstone-200i/modules/200i_wdt.c new file mode 100755 index 000000000000..9b3d79cc5a67 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cel/midstone-200i/modules/200i_wdt.c @@ -0,0 +1,363 @@ +/* + * Watchdog driver for the Midstone 200i + * + * Copyright (C) 2017 Celestica Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define DRIVER_NAME "ms200i_wdt" + +#define CONF_GPIOBASE 0x8000F848 +#define PCI_CONFIG_ADDRESS 0x0CF8 +#define PCI_CONFIG_DATA 0x0CFC + +// WDT_CTRL is GPIO 32 +// GPIOBUS: 2 ,bit: 0th +#define WDT_CTRL_ENB_REG 0x30 +#define WDT_CTRL_DIR_REG 0x34 +#define WDT_CTRL_LVL_REG 0x38 +#define WDT_CTRL_MASK (unsigned long)(1<<(32%32)) + +// WDT_FEED is GPIO 15 +// GPIOBUS: 1 ,bit: 15th +#define WDT_FEED_ENB_REG 0x00 +#define WDT_FEED_DIR_REG 0x04 +#define WDT_FEED_LVL_REG 0x0C +#define WDT_FEED_MASK (unsigned long)(1<<(15%32)) + +static bool nowayout = WATCHDOG_NOWAYOUT; + +// For enabling Debug message +//#define ENAB_DEBUG +//#define ENAB_DEBUG_GPIO + +struct ms200i_wdt_drvdata { + struct watchdog_device wdt; + struct mutex lock; + unsigned int gpiobase; +}; + +static struct resource ms200i_wdt_resources[] = { + { + .flags = IORESOURCE_IO, + }, +}; + +static void ms200i_wdt_dev_release( struct device * dev) +{ + return; +} + +static struct platform_device ms200i_wdt_dev = { + .name = DRIVER_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(ms200i_wdt_resources), + .resource = ms200i_wdt_resources, + .dev = { + .release = ms200i_wdt_dev_release, + } +}; + +static int ms200i_wdt_start(struct watchdog_device *wdt_dev) +{ + struct ms200i_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev); + unsigned char reset_ctrl = 0x00; + unsigned long enab, gpio ,dir; + unsigned int base_addr; +#ifdef ENAB_DEBUG + printk(KERN_INFO "WDT Start"); +#endif + mutex_lock(&drvdata->lock); + + base_addr = drvdata->gpiobase; + + enab = inl(base_addr + WDT_CTRL_ENB_REG); +#ifdef ENAB_DEBUG_GPIO + printk(KERN_INFO "ctrl enab %16X",enab); +#endif + enab |= WDT_CTRL_MASK; +#ifdef ENAB_DEBUG_GPIO + printk(KERN_INFO "ctrl enab %16X",enab); +#endif + outl(enab, base_addr + WDT_CTRL_ENB_REG); +#ifdef ENAB_DEBUG_GPIO + enab = inl(base_addr + WDT_CTRL_ENB_REG); + printk(KERN_INFO "ctrl enab %16X",enab); +#endif + + enab = inl(base_addr + WDT_FEED_ENB_REG); +#ifdef ENAB_DEBUG_GPIO + printk(KERN_INFO "feed enab %16X",enab); +#endif + enab |= WDT_FEED_MASK; +#ifdef ENAB_DEBUG_GPIO + printk(KERN_INFO "feed enab %16X",enab); +#endif + outl(enab, base_addr + WDT_FEED_ENB_REG); +#ifdef ENAB_DEBUG_GPIO + enab = inl(base_addr + WDT_FEED_ENB_REG); + printk(KERN_INFO "feed enab %16X",enab); +#endif + + dir = inl(base_addr + WDT_CTRL_DIR_REG); +#ifdef ENAB_DEBUG_GPIO + printk(KERN_INFO "ctrl dir %16X",dir); +#endif + dir &= ~WDT_FEED_MASK; +#ifdef ENAB_DEBUG_GPIO + printk(KERN_INFO "ctrl dir %16X",dir); +#endif + outl(dir, base_addr + WDT_CTRL_DIR_REG); +#ifdef ENAB_DEBUG_GPIO + dir = inl(base_addr + WDT_CTRL_DIR_REG); + printk(KERN_INFO "ctrl dir %16X",dir); +#endif + + dir = inl(base_addr + WDT_FEED_DIR_REG); +#ifdef ENAB_DEBUG_GPIO + printk(KERN_INFO "feed dir %16X",dir); +#endif + dir &= ~WDT_FEED_MASK; +#ifdef ENAB_DEBUG_GPIO + printk(KERN_INFO "feed dir %16X",dir); +#endif + outl(dir, base_addr + WDT_FEED_DIR_REG); +#ifdef ENAB_DEBUG_GPIO + dir = inl(base_addr + WDT_FEED_DIR_REG); + printk(KERN_INFO "feed dir %16X",dir); +#endif + + gpio = inl(base_addr + WDT_CTRL_LVL_REG); +#ifdef ENAB_DEBUG_GPIO + printk(KERN_INFO "ctrl gpio %16X",gpio); +#endif + gpio &= ~WDT_CTRL_MASK; +#ifdef ENAB_DEBUG_GPIO + printk(KERN_INFO "ctrl gpio %16X",gpio); +#endif + outl_p( gpio, base_addr + WDT_CTRL_LVL_REG); +#ifdef ENAB_DEBUG_GPIO + gpio = inl(base_addr + WDT_CTRL_LVL_REG); + printk(KERN_INFO "ctrl gpio %16X",gpio); +#endif + + mutex_unlock(&drvdata->lock); + printk(KERN_INFO "WDT Start Finish"); + return 0; +} + +static int ms200i_wdt_stop(struct watchdog_device *wdt_dev) +{ + struct ms200i_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev); + unsigned long gpio; + unsigned long base_addr; +#ifdef ENAB_DEBUG + printk(KERN_INFO "WDT Stop"); +#endif + mutex_lock(&drvdata->lock); + + base_addr = drvdata->gpiobase; + + gpio = inl(base_addr + WDT_CTRL_ENB_REG); +#ifdef ENAB_DEBUG_GPIO + printk(KERN_INFO "ctrl gpio %16X",gpio); +#endif + gpio &= ~(WDT_CTRL_MASK); +#ifdef ENAB_DEBUG_GPIO + printk(KERN_INFO "ctrl gpio %16X",gpio); +#endif + outl_p(gpio, base_addr + WDT_CTRL_ENB_REG); +#ifdef ENAB_DEBUG_GPIO + gpio = inl(base_addr + WDT_CTRL_ENB_REG); + printk(KERN_INFO "ctrl gpio %16X",gpio); +#endif + + gpio = inl(base_addr + WDT_FEED_ENB_REG); +#ifdef ENAB_DEBUG_GPIO + printk(KERN_INFO "feed gpio %16X",gpio); +#endif + gpio &= ~(WDT_CTRL_MASK); +#ifdef ENAB_DEBUG_GPIO + printk(KERN_INFO "feed gpio %16X",gpio); +#endif + outl_p(gpio, base_addr + WDT_FEED_ENB_REG); +#ifdef ENAB_DEBUG_GPIO + gpio = inl(base_addr + WDT_FEED_ENB_REG); + printk(KERN_INFO "feed gpio %16X",gpio); +#endif + + mutex_unlock(&drvdata->lock); + + return 0; +} + +static int ms200i_wdt_ping(struct watchdog_device *wdt_dev) +{ + struct ms200i_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev); + unsigned long gpio; + unsigned long base_addr; + +#ifdef ENAB_DEBUG + printk(KERN_INFO "WDT PING"); +#endif + mutex_lock(&drvdata->lock); + + base_addr = drvdata->gpiobase; + + gpio = inl(base_addr + WDT_FEED_LVL_REG); +#ifdef ENAB_DEBUG_GPIO + printk(KERN_INFO "feed gpio %16X",gpio); +#endif + gpio &= ~WDT_FEED_MASK; +#ifdef ENAB_DEBUG_GPIO + printk(KERN_INFO "feed gpio %16X",gpio); +#endif + outl_p( gpio, base_addr + WDT_FEED_LVL_REG); +#ifdef ENAB_DEBUG_GPIO + gpio = inl(base_addr + WDT_FEED_LVL_REG); + printk(KERN_INFO "feed gpio %16X",gpio); +#endif + mdelay(10); + + gpio = inl(base_addr + WDT_FEED_LVL_REG); +#ifdef ENAB_DEBUG_GPIO + printk(KERN_INFO "feed gpio %16X",gpio); +#endif + gpio |= WDT_FEED_MASK; +#ifdef ENAB_DEBUG_GPIO + printk(KERN_INFO "feed gpio %16X",gpio); +#endif + outl_p( gpio, base_addr + WDT_FEED_LVL_REG); +#ifdef ENAB_DEBUG_GPIO + gpio = inl(base_addr + WDT_FEED_LVL_REG); + printk(KERN_INFO "feed gpio %16X",gpio); +#endif + + mutex_unlock(&drvdata->lock); +#ifdef ENAB_DEBUG + printk(KERN_INFO "WDT PING FINISH"); +#endif + return 0; +} + +static const struct watchdog_info ms200i_wdt_info = { + .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, + .identity = "MS200i Watchdog", +}; + +static const struct watchdog_ops ms200i_wdt_ops = { + .owner = THIS_MODULE, + .start = ms200i_wdt_start, + .stop = ms200i_wdt_stop, + .ping = ms200i_wdt_ping, +}; + +static int ms200i_wdt_probe(struct platform_device *pdev) +{ + struct ms200i_wdt_drvdata *drvdata; + int ret; + unsigned int base_addr; + + drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), + GFP_KERNEL); + if (!drvdata) { + ret = -ENOMEM; + goto err; + } + + outl(CONF_GPIOBASE, PCI_CONFIG_ADDRESS); + base_addr = inl(PCI_CONFIG_DATA); + // remove last bit , that is hardware inditcate. + base_addr &= ~(0x01); + + if(base_addr == 0){ + printk(KERN_INFO "can't get gpio base address"); + }else{ + printk(KERN_INFO "gpio base address : %8.8X",base_addr); + } + + mutex_init(&drvdata->lock); + + drvdata->gpiobase = base_addr; + drvdata->wdt.info = &ms200i_wdt_info; + drvdata->wdt.ops = &ms200i_wdt_ops; + + watchdog_set_nowayout(&drvdata->wdt, nowayout); + watchdog_set_drvdata(&drvdata->wdt, drvdata); + + ret = watchdog_register_device(&drvdata->wdt); + if (ret != 0) { + dev_err(&pdev->dev, "watchdog_register_device() failed: %d\n", + ret); + goto err; + } + + platform_set_drvdata(pdev, drvdata); + +err: + return ret; +} + +static int ms200i_wdt_remove(struct platform_device *pdev) +{ + struct ms200i_wdt_drvdata *drvdata = platform_get_drvdata(pdev); + + watchdog_unregister_device(&drvdata->wdt); +#ifdef ENAB_DEBUG + printk(KERN_INFO "MS200i WDT Remove"); +#endif + return 0; +} + +static struct platform_driver ms200i_wdt_drv = { + .probe = ms200i_wdt_probe, + .remove = ms200i_wdt_remove, + .driver = { + .name = DRIVER_NAME, + }, +}; + +int ms200i_wdt_init(void) +{ +#ifdef ENAB_DEBUG + printk(KERN_INFO "MS200i WDT Init"); +#endif + platform_device_register(&ms200i_wdt_dev); + platform_driver_register(&ms200i_wdt_drv); + + return 0; +} + +void ms200i_wdt_exit(void) +{ +#ifdef ENAB_DEBUG + printk(KERN_INFO "MS200i WDT Exit"); +#endif + platform_driver_unregister(&ms200i_wdt_drv); + platform_device_unregister(&ms200i_wdt_dev); +} + +module_init(ms200i_wdt_init); +module_exit(ms200i_wdt_exit); + +MODULE_AUTHOR("Sittisak Sinprem "); +MODULE_DESCRIPTION("Midstone ms200i Watchdog"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ms200i-watchdog"); diff --git a/platform/innovium/sonic-platform-modules-cel/midstone-200i/modules/Makefile b/platform/innovium/sonic-platform-modules-cel/midstone-200i/modules/Makefile new file mode 100755 index 000000000000..932a13cf8253 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cel/midstone-200i/modules/Makefile @@ -0,0 +1 @@ +obj-m := 200i_cpld.o mc24lc64t.o 200i_wdt.o diff --git a/platform/innovium/sonic-platform-modules-cel/midstone-200i/modules/mc24lc64t.c b/platform/innovium/sonic-platform-modules-cel/midstone-200i/modules/mc24lc64t.c new file mode 100755 index 000000000000..a391056d09a7 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cel/midstone-200i/modules/mc24lc64t.c @@ -0,0 +1,142 @@ +/* + * mc24lc64t.c - driver for Microchip 24LC64T + * + * Copyright (C) 2017 Celestica Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct mc24lc64t_data { + struct i2c_client *fake_client; + struct mutex update_lock; +}; + +static ssize_t mc24lc64t_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = kobj_to_i2c_client(kobj); + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + unsigned long timeout, read_time, i = 0; + int status; + + mutex_lock(&drvdata->update_lock); + + if (i2c_smbus_write_byte_data(client, off>>8, off)) + { + status = -EIO; + goto exit; + } + + msleep(1); + +begin: + + if (i < count) + { + timeout = jiffies + msecs_to_jiffies(25); /* 25 mS timeout*/ + do { + read_time = jiffies; + + status = i2c_smbus_read_byte(client); + if (status >= 0) + { + buf[i++] = status; + goto begin; + } + } while (time_before(read_time, timeout)); + + status = -ETIMEDOUT; + goto exit; + } + + status = count; + +exit: + mutex_unlock(&drvdata->update_lock); + + return status; +} + +static struct bin_attribute mc24lc64t_bit_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO, + }, + .size = 65536, + .read = mc24lc64t_read, +}; + +static int mc24lc64t_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adapter = client->adapter; + struct mc24lc64t_data *drvdata; + int err; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA + | I2C_FUNC_SMBUS_READ_BYTE)) + return -EPFNOSUPPORT; + + if (!(drvdata = devm_kzalloc(&client->dev, + sizeof(struct mc24lc64t_data), GFP_KERNEL))) + return -ENOMEM; + + drvdata->fake_client = i2c_new_dummy(client->adapter, client->addr + 1); + if (!drvdata->fake_client) + return -ENOMEM; + + i2c_set_clientdata(client, drvdata); + mutex_init(&drvdata->update_lock); + + err = sysfs_create_bin_file(&client->dev.kobj, &mc24lc64t_bit_attr); + if (err) + i2c_unregister_device(drvdata->fake_client); + + return err; +} + +static int mc24lc64t_remove(struct i2c_client *client) +{ + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + + i2c_unregister_device(drvdata->fake_client); + + sysfs_remove_bin_file(&client->dev.kobj, &mc24lc64t_bit_attr); + + return 0; +} + +static const struct i2c_device_id mc24lc64t_id[] = { + { "24lc64t", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mc24lc64t_id); + +static struct i2c_driver mc24lc64t_driver = { + .driver = { + .name = "mc24lc64t", + .owner = THIS_MODULE, + }, + .probe = mc24lc64t_probe, + .remove = mc24lc64t_remove, + .id_table = mc24lc64t_id, +}; + +module_i2c_driver(mc24lc64t_driver); + +MODULE_AUTHOR("Abhisit Sangjan "); +MODULE_DESCRIPTION("Microchip 24LC64T Driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/innovium/sonic-platform-modules-cel/midstone-200i/systemd/platform-modules-midstone-200i.service b/platform/innovium/sonic-platform-modules-cel/midstone-200i/systemd/platform-modules-midstone-200i.service new file mode 100644 index 000000000000..dbb7aed39df7 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cel/midstone-200i/systemd/platform-modules-midstone-200i.service @@ -0,0 +1,13 @@ +[Unit] +Description=Celestica Midstone 200i platform modules +After=local-fs.target +Before=pmon.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-midstone-200i start +ExecStop=-/etc/init.d/platform-modules-midstone-200i stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-delta/LICENSE b/platform/innovium/sonic-platform-modules-delta/LICENSE new file mode 100644 index 000000000000..ea87fe9caabe --- /dev/null +++ b/platform/innovium/sonic-platform-modules-delta/LICENSE @@ -0,0 +1,16 @@ +Copyright (C) 2016 Microsoft, Inc +Copyright (C) 2017 Delta Networks, Inc. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You 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/innovium/sonic-platform-modules-delta/common/modules/dni_emc2305.c b/platform/innovium/sonic-platform-modules-delta/common/modules/dni_emc2305.c new file mode 100644 index 000000000000..73d9900af5b4 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-delta/common/modules/dni_emc2305.c @@ -0,0 +1,381 @@ +/* + * + * + * 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 EMC2305 fan controller + * Complete datasheet is available (6/2013) at: + * http://www.smsc.com/media/Downloads_Public/Data_Sheets/2305.pdf + */ + +#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 EMC2305_REG_DEVICE 0xFD +#define EMC2305_REG_VENDOR 0xFE + +//#define FAN_MINIMUN 0x33 /*20%*/ +#define FAN_MINIMUN 0x0 /*0%*/ +#define FAN_RPM_BASED 0xAB + +#define EMC2305_REG_FAN_DRIVE(n) (0x30 + 0x10 * n) +#define EMC2305_REG_FAN_MIN_DRIVE(n) (0x38 + 0x10 * n) +#define EMC2305_REG_FAN_TACH(n) (0x3E + 0x10 * n) +#define EMC2305_REG_FAN_CONF(n) (0x32 + 0x10 * n) +#define EMC2305_REG_FAN_REAR_H_RPM(n) (0x3D + 0x10 * n) +#define EMC2305_REG_FAN_REAR_L_RPM(n) (0x3C + 0x10 * n) + +#define EMC2305_DEVICE 0x34 +#define EMC2305_VENDOR 0x5D +#define MAX_FAN_SPEED 23000 + +struct emc2305_data +{ + struct device *hwmon_dev; + struct attribute_group attrs; + struct mutex lock; +}; + +static int emc2305_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int emc2305_detect(struct i2c_client *client, + struct i2c_board_info *info); +static int emc2305_remove(struct i2c_client *client); + +static const struct i2c_device_id emc2305_id[] = +{ + { "emc2305", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, emc2305_id); + +static struct i2c_driver emc2305_driver = +{ + .class = I2C_CLASS_HWMON, + .driver = { + .name = "emc2305", + }, + .probe = emc2305_probe, + .remove = emc2305_remove, + .id_table = emc2305_id, + .detect = emc2305_detect, + .address_list = 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(fan3_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 2); +static SENSOR_DEVICE_ATTR(fan4_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 3); +static SENSOR_DEVICE_ATTR(fan5_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 4); +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(fan3_input_percentage, S_IWUSR | S_IRUGO, show_fan_percentage, set_fan_percentage, 2); +static SENSOR_DEVICE_ATTR(fan4_input_percentage, S_IWUSR | S_IRUGO, show_fan_percentage, set_fan_percentage, 3); +static SENSOR_DEVICE_ATTR(fan5_input_percentage, S_IWUSR | S_IRUGO, show_fan_percentage, set_fan_percentage, 4); +static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0); +static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1); +static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2); +static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 3); +static SENSOR_DEVICE_ATTR(pwm5, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 4); + +static struct attribute *emc2305_attr[] = +{ + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, + &sensor_dev_attr_fan4_input.dev_attr.attr, + &sensor_dev_attr_fan5_input.dev_attr.attr, + &sensor_dev_attr_fan1_input_percentage.dev_attr.attr, + &sensor_dev_attr_fan2_input_percentage.dev_attr.attr, + &sensor_dev_attr_fan3_input_percentage.dev_attr.attr, + &sensor_dev_attr_fan4_input_percentage.dev_attr.attr, + &sensor_dev_attr_fan5_input_percentage.dev_attr.attr, + &sensor_dev_attr_pwm1.dev_attr.attr, + &sensor_dev_attr_pwm2.dev_attr.attr, + &sensor_dev_attr_pwm3.dev_attr.attr, + &sensor_dev_attr_pwm4.dev_attr.attr, + &sensor_dev_attr_pwm5.dev_attr.attr, + 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 emc2305_data *data = i2c_get_clientdata(client); + int val; + + mutex_lock(&data->lock); + val = i2c_smbus_read_word_swapped(client, + EMC2305_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 emc2305_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, EMC2305_REG_FAN_REAR_H_RPM(attr->index), hsb); + i2c_smbus_write_byte_data(client, EMC2305_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 emc2305_data *data = i2c_get_clientdata(client); + int val; + + + mutex_lock(&data->lock); + val = i2c_smbus_read_word_swapped(client, + EMC2305_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 emc2305_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, EMC2305_REG_FAN_REAR_H_RPM(attr->index), hsb); + i2c_smbus_write_byte_data(client, EMC2305_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 emc2305_data *data = i2c_get_clientdata(client); + int val; + + mutex_lock(&data->lock); + val = i2c_smbus_read_byte_data(client, + EMC2305_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 emc2305_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, + EMC2305_REG_FAN_DRIVE(attr->index), + val); + mutex_unlock(&data->lock); + return count; +} + +static int emc2305_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, EMC2305_REG_VENDOR); + if (vendor != EMC2305_VENDOR) + { + return -ENODEV; + } + + device = i2c_smbus_read_byte_data(client, EMC2305_REG_DEVICE); + if (device != EMC2305_DEVICE) + { + return -ENODEV; + } + + strlcpy(info->type, "emc2305", I2C_NAME_SIZE); + + return 0; +} + +static int emc2305_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct emc2305_data *data; + int err; + int i; + + data = devm_kzalloc(&client->dev, sizeof(struct emc2305_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 = emc2305_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 < 5; i++) + { + /* set minimum drive to 0% */ + i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_MIN_DRIVE(i), FAN_MINIMUN); + i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_CONF(i), FAN_RPM_BASED); + } + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &data->attrs); + return err; +} + +static int emc2305_remove(struct i2c_client *client) +{ + struct emc2305_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(emc2305_driver); + +MODULE_AUTHOR("Neal Tai"); +MODULE_DESCRIPTION("SMSC EMC2305 fan controller driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/innovium/sonic-platform-modules-delta/debian/changelog b/platform/innovium/sonic-platform-modules-delta/debian/changelog new file mode 100644 index 000000000000..ec8327e8ae7a --- /dev/null +++ b/platform/innovium/sonic-platform-modules-delta/debian/changelog @@ -0,0 +1,5 @@ +sonic-delta-platform-modules (1.1) unstable; urgency=low + + * Initial release + + -- Neal Tai Fri, 21 APR 2017 11:11:11 -0800 diff --git a/platform/innovium/sonic-platform-modules-delta/debian/compat b/platform/innovium/sonic-platform-modules-delta/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-delta/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/innovium/sonic-platform-modules-delta/debian/control b/platform/innovium/sonic-platform-modules-delta/debian/control new file mode 100644 index 000000000000..71c403387f80 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-delta/debian/control @@ -0,0 +1,13 @@ +Source: sonic-delta-platform-modules +Section: main +Priority: extra +Maintainer: Neal Tai +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: platform-modules-et-c032if +Architecture: amd64 +Depends: linux-image-4.9.0-9-2-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + + diff --git a/platform/innovium/sonic-platform-modules-delta/debian/platform-modules-et-c032if.init b/platform/innovium/sonic-platform-modules-delta/debian/platform-modules-et-c032if.init new file mode 100755 index 000000000000..f2d24b04a0d4 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-delta/debian/platform-modules-et-c032if.init @@ -0,0 +1,39 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup et-c032if board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + modprobe optoe + modprobe delta_et-c032if_platform + + /usr/local/bin/et-c032if_platform_init.sh + echo "done." + ;; + +stop) + echo "done." + + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-et-c032if.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/innovium/sonic-platform-modules-delta/debian/platform-modules-et-c032if.install b/platform/innovium/sonic-platform-modules-delta/debian/platform-modules-et-c032if.install new file mode 100644 index 000000000000..45886664b870 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-delta/debian/platform-modules-et-c032if.install @@ -0,0 +1,3 @@ +et-c032if/cfg/et-c032if-modules.conf etc/modules-load.d +et-c032if/scripts/et-c032if_platform_init.sh usr/local/bin +systemd/platform-modules-et-c032if.service lib/systemd/system diff --git a/platform/innovium/sonic-platform-modules-delta/debian/rules b/platform/innovium/sonic-platform-modules-delta/debian/rules new file mode 100755 index 000000000000..a84c235e5480 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-delta/debian/rules @@ -0,0 +1,33 @@ +#!/usr/bin/make -f + +export INSTALL_MOD_DIR:=extra + +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= et-c032if + +%: + dh $@ --with=systemd + +override_dh_auto_build: + (for mod in $(MODULE_DIRS); do \ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ + done) + +override_dh_auto_install: + (for mod in $(MODULE_DIRS); do \ + dh_installdirs -pplatform-modules-$${mod} \ + $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/modules/*.ko \ + debian/platform-modules-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + done) + +override_dh_usrlocal: + +override_dh_clean: + dh_clean + (for mod in $(MODULE_DIRS); do \ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \ + done) + diff --git a/platform/innovium/sonic-platform-modules-delta/et-c032if/cfg/et-c032if-modules.conf b/platform/innovium/sonic-platform-modules-delta/et-c032if/cfg/et-c032if-modules.conf new file mode 100644 index 000000000000..552b4103ed02 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-delta/et-c032if/cfg/et-c032if-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/innovium/sonic-platform-modules-delta/et-c032if/modules/Makefile b/platform/innovium/sonic-platform-modules-delta/et-c032if/modules/Makefile new file mode 100644 index 000000000000..2e8feec0b405 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-delta/et-c032if/modules/Makefile @@ -0,0 +1,2 @@ +obj-m := delta_et-c032if_platform.o + 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 new file mode 100644 index 000000000000..d4e23a166e88 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-delta/et-c032if/modules/delta_et-c032if_platform.c @@ -0,0 +1,2100 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define CPULD_ADDR 0x31 +#define SWPLD2_ADDR 0x35 +#define SWPLD3_ADDR 0x36 +#define BUS0_BASE_NUM 10 +#define BUS0_DEV_NUM 3 +#define DEFAULT_NUM 0 +#define EEPROM_VAL 0xfc +#define SWPLD_VAL 0xfe +#define QSFP_VAL 0xff +#define BUS0_MUX_REG 0x14 +#define QSFP_PRESENCE_1 0x51 +#define QSFP_PRESENCE_2 0x52 +#define QSFP_PRESENCE_3 0x51 +#define QSFP_PRESENCE_4 0x52 +#define SFP_PRESENCE 0x71 +#define QSFP_RESPONDE_1 0x31 +#define QSFP_RESPONDE_2 0x32 +#define QSFP_RESPONDE_3 0x31 +#define QSFP_RESPONDE_4 0x32 +#define QSFP_LP_MODE_1 0x21 +#define QSFP_LP_MODE_2 0x22 +#define QSFP_LP_MODE_3 0x21 +#define QSFP_LP_MODE_4 0x22 +#define QSFP_RESET_1 0x11 +#define QSFP_RESET_2 0x12 +#define QSFP_RESET_3 0x11 +#define QSFP_RESET_4 0x12 +#define QSFP_INTERRUPT_1 0x61 +#define QSFP_INTERRUPT_2 0x62 +#define QSFP_INTERRUPT_3 0x61 +#define QSFP_INTERRUPT_4 0x62 + +#define EEPROM_SIZE 256 +#define EEPROM_MASK 29 +#define ATTR_R 1 +#define ATTR_W 2 + +#define et_c032if_i2c_device_num(NUM){ \ + .name = "delta-et-c032if-i2c-device", \ + .id = NUM, \ + .dev = { \ + .platform_data = &et_c032if_i2c_device_platform_data[NUM],\ + .release = device_release, \ + }, \ +} + +struct mutex dni_lock; + +/*Define struct to get client of i2c_new_deivce */ +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; + +static struct kobject *kobj_cpld; +static struct kobject *kobj_swpld2; +static struct kobject *kobj_swpld3; +static struct kobject *kobj_sfp; + +enum{ + BUS0 = 0, + BUS1, + BUS2, + BUS3, + BUS4, + BUS5, + BUS6, + BUS7, + BUS8, + BUS9, + BUS10, + BUS11, + BUS12, + BUS13, + BUS14, + BUS15, + BUS16, + BUS17, + BUS18, + BUS19, +}; + +static struct cpld_attribute_data { + uint8_t bus; + uint8_t addr; + uint8_t reg; + uint8_t mask; + char note[350]; +}; + +unsigned char reverse_8bits(unsigned char c) +{ + unsigned char s = 0; + int i; + for (i = 0; i < 8; ++i) { + s <<= 1; + s |= c & 1; + c >>= 1; + } + return s; +} + +unsigned char dni_log2 (unsigned char num){ + unsigned char num_log2 = 0; + while(num > 0){ + num = num >> 1; + num_log2 += 1; + } + return num_log2 -1; +} + +/*---------------- I2C device - start ------------- */ +static void device_release(struct device *dev) +{ + return; +} + +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_1_mode[] = +{ + { .adap_id = 30, + .deselect_on_exit = 1, + }, + { .adap_id = 31, + .deselect_on_exit = 1, + }, + { .adap_id = 32, + .deselect_on_exit = 1, + }, + { .adap_id = 33, + .deselect_on_exit = 1, + }, + { .adap_id = 34, + .deselect_on_exit = 1, + }, + { .adap_id = 35, + .deselect_on_exit = 1, + }, + { .adap_id = 36, + .deselect_on_exit = 1, + }, + { .adap_id = 37, + .deselect_on_exit = 1, + }, +}; + +static struct pca954x_platform_mode pca954x_2_mode[] = +{ + { .adap_id = 38, + .deselect_on_exit = 1, + }, + { .adap_id = 39, + .deselect_on_exit = 1, + }, + { .adap_id = 40, + .deselect_on_exit = 1, + }, + { .adap_id = 41, + .deselect_on_exit = 1, + }, + { .adap_id = 42, + .deselect_on_exit = 1, + }, + { .adap_id = 43, + .deselect_on_exit = 1, + }, + { .adap_id = 44, + .deselect_on_exit = 1, + }, + { .adap_id = 45, + .deselect_on_exit = 1, + }, +}; + +static struct pca954x_platform_mode pca954x_3_mode[] = +{ + { .adap_id = 46, + .deselect_on_exit = 1, + }, + { .adap_id = 47, + .deselect_on_exit = 1, + }, + { .adap_id = 48, + .deselect_on_exit = 1, + }, + { .adap_id = 49, + .deselect_on_exit = 1, + }, + { .adap_id = 50, + .deselect_on_exit = 1, + }, + { .adap_id = 51, + .deselect_on_exit = 1, + }, + { .adap_id = 52, + .deselect_on_exit = 1, + }, + { .adap_id = 53, + .deselect_on_exit = 1, + }, +}; + +static struct pca954x_platform_mode pca954x_4_mode[] = +{ + { .adap_id = 54, + .deselect_on_exit = 1, + }, + { .adap_id = 55, + .deselect_on_exit = 1, + }, + { .adap_id = 56, + .deselect_on_exit = 1, + }, + { .adap_id = 57, + .deselect_on_exit = 1, + }, + { .adap_id = 58, + .deselect_on_exit = 1, + }, + { .adap_id = 59, + .deselect_on_exit = 1, + }, + { .adap_id = 60, + .deselect_on_exit = 1, + }, + { .adap_id = 61, + .deselect_on_exit = 1, + }, +}; + +static struct pca954x_platform_mode pca954x_5_mode[] = +{ + { .adap_id = 62, + .deselect_on_exit = 1, + }, + { .adap_id = 63, + .deselect_on_exit = 1, + }, + { .adap_id = 64, + .deselect_on_exit = 1, + }, + { .adap_id = 65, + .deselect_on_exit = 1, + }, + { .adap_id = 66, + .deselect_on_exit = 1, + }, + { .adap_id = 67, + .deselect_on_exit = 1, + }, + { .adap_id = 68, + .deselect_on_exit = 1, + }, + { .adap_id = 69, + .deselect_on_exit = 1, + }, +}; + +static struct pca954x_platform_data pca954x_data[] = +{ + { + .modes = pca954x_1_mode, + .num_modes = ARRAY_SIZE(pca954x_1_mode), + }, + { + .modes = pca954x_2_mode, + .num_modes = ARRAY_SIZE(pca954x_2_mode), + }, + { + .modes = pca954x_3_mode, + .num_modes = ARRAY_SIZE(pca954x_3_mode), + }, + { + .modes = pca954x_4_mode, + .num_modes = ARRAY_SIZE(pca954x_4_mode), + }, + { + .modes = pca954x_5_mode, + .num_modes = ARRAY_SIZE(pca954x_5_mode), + }, +}; + +static struct i2c_board_info __initdata i2c_info_pca9548[] = +{ + { + I2C_BOARD_INFO("pca9548", 0x71), + .platform_data = &pca954x_data[0], + }, + { + I2C_BOARD_INFO("pca9548", 0x72), + .platform_data = &pca954x_data[1], + }, + { + I2C_BOARD_INFO("pca9548", 0x73), + .platform_data = &pca954x_data[2], + }, + { + I2C_BOARD_INFO("pca9548", 0x74), + .platform_data = &pca954x_data[3], + }, + { + I2C_BOARD_INFO("pca9548", 0x76), + .platform_data = &pca954x_data[4], + }, +}; + +static struct i2c_device_platform_data et_c032if_i2c_device_platform_data[] = { + { + /* id eeprom (0x53) */ + .parent = 10, + .info = { I2C_BOARD_INFO("24c02", 0x53) }, + .client = NULL, + }, + { + /* qsfp 1 (0x50) */ + .parent = 30, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 2 (0x50) */ + .parent = 31, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 3 (0x50) */ + .parent = 32, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 4 (0x50) */ + .parent = 33, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 5 (0x50) */ + .parent = 34, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 6 (0x50) */ + .parent = 35, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 7 (0x50) */ + .parent = 36, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 8 (0x50) */ + .parent = 37, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 9 (0x50) */ + .parent = 38, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 10 (0x50) */ + .parent = 39, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 11 (0x50) */ + .parent = 40, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 12 (0x50) */ + .parent = 41, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 13 (0x50) */ + .parent = 42, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 14 (0x50) */ + .parent = 43, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 15 (0x50) */ + .parent = 44, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 16 (0x50) */ + .parent = 45, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 17 (0x50) */ + .parent = 46, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 18 (0x50) */ + .parent = 47, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 19 (0x50) */ + .parent = 48, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 20 (0x50) */ + .parent = 49, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 21 (0x50) */ + .parent = 50, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 22 (0x50) */ + .parent = 51, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 23 (0x50) */ + .parent = 52, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 24 (0x50) */ + .parent = 53, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 25 (0x50) */ + .parent = 54, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 26 (0x50) */ + .parent = 55, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 27 (0x50) */ + .parent = 56, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 28 (0x50) */ + .parent = 57, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 29 (0x50) */ + .parent = 58, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 30 (0x50) */ + .parent = 59, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 31 (0x50) */ + .parent = 60, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* qsfp 32 (0x50) */ + .parent = 61, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + /* sfp 1 (0x50) */ + .parent = 62, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + /* sfp 2 (0x50) */ + .parent = 63, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + +}; + + +static struct platform_device et_c032if_i2c_device[] = { + et_c032if_i2c_device_num(0), + et_c032if_i2c_device_num(1), + et_c032if_i2c_device_num(2), + et_c032if_i2c_device_num(3), + et_c032if_i2c_device_num(4), + et_c032if_i2c_device_num(5), + et_c032if_i2c_device_num(6), + et_c032if_i2c_device_num(7), + et_c032if_i2c_device_num(8), + et_c032if_i2c_device_num(9), + et_c032if_i2c_device_num(10), + et_c032if_i2c_device_num(11), + et_c032if_i2c_device_num(12), + et_c032if_i2c_device_num(13), + et_c032if_i2c_device_num(14), + et_c032if_i2c_device_num(15), + et_c032if_i2c_device_num(16), + et_c032if_i2c_device_num(17), + et_c032if_i2c_device_num(18), + et_c032if_i2c_device_num(19), + et_c032if_i2c_device_num(20), + et_c032if_i2c_device_num(21), + et_c032if_i2c_device_num(22), + et_c032if_i2c_device_num(23), + et_c032if_i2c_device_num(24), + et_c032if_i2c_device_num(25), + et_c032if_i2c_device_num(26), + et_c032if_i2c_device_num(27), + et_c032if_i2c_device_num(28), + et_c032if_i2c_device_num(29), + et_c032if_i2c_device_num(30), + et_c032if_i2c_device_num(31), + et_c032if_i2c_device_num(32), + et_c032if_i2c_device_num(33), + et_c032if_i2c_device_num(34), +}; + +/*---------------- I2C device - end ------------- */ + +/*---------------- I2C driver - start ------------- */ +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-et-c032if-i2c-device", + } +}; + +/*---------------- I2C driver - end ------------- */ + +/*---------------- CPLD - start ------------- */ + +unsigned char cpupld_reg_addr; +unsigned char swpld2_reg_addr; +unsigned char swpld3_reg_addr; + +/* CPLD -- device */ + +enum cpld_type { + cpu_cpld, +}; + +enum swpld2_type { + swpld2, +}; + +enum swpld3_type { + swpld3, +}; + +enum cpld_attributes { +//CPLDs address and value + CPLD_REG_ADDR, + CPLD_REG_VALUE, + SWPLD2_REG_ADDR, + SWPLD2_REG_VALUE, + SWPLD3_REG_ADDR, + SWPLD3_REG_VALUE, + SFP_SELECT_PORT, + SFP_IS_PRESENT, + SFP_IS_PRESENT_ALL, + QSFP_LP_MODE, + QSFP_RESET, + QSFP_INTERRUPT, + QSFP_RESPONDE, +}; + +struct cpld_platform_data { + int reg_addr; + struct i2c_client *client; +}; + +static struct cpld_platform_data et_c032if_cpld_platform_data[] = { + [cpu_cpld] = { + .reg_addr = CPULD_ADDR, + }, +}; + +static struct cpld_platform_data et_c032if_swpld2_platform_data[] = { + [swpld2] = { + .reg_addr = SWPLD2_ADDR, + }, +}; + +static struct cpld_platform_data et_c032if_swpld3_platform_data[] = { + [swpld3] = { + .reg_addr = SWPLD3_ADDR, + }, +}; + +static struct platform_device et_c032if_cpld = { + .name = "delta-et-c032if-cpld", + .id = 0, + .dev = { + .platform_data = et_c032if_cpld_platform_data, + .release = device_release, + }, +}; + +static struct platform_device et_c032if_swpld2 = { + .name = "delta-et-c032if-swpld2", + .id = 0, + .dev = { + .platform_data = et_c032if_swpld2_platform_data, + .release = device_release + }, +}; + +static struct platform_device et_c032if_swpld3 = { + .name = "delta-et-c032if-swpld3", + .id = 0, + .dev = { + .platform_data = et_c032if_swpld3_platform_data, + .release = device_release + }, +}; + +static ssize_t get_cpld_reg(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + int ret; + int mask; + int value; + char note[450]; + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cpld_platform_data *pdata = dev->platform_data; + + mutex_lock(&dni_lock); + switch (attr->index) { + case CPLD_REG_ADDR: + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%02x\n", cpupld_reg_addr); + case SWPLD2_REG_ADDR: + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%02x\n", swpld2_reg_addr); + case SWPLD3_REG_ADDR: + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%02x\n", swpld3_reg_addr); + case CPLD_REG_VALUE: + ret = i2c_smbus_read_byte_data(pdata[cpu_cpld].client, cpupld_reg_addr); + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%02x\n", ret); + case SWPLD2_REG_VALUE: + ret = i2c_smbus_read_byte_data(pdata[swpld2].client, swpld2_reg_addr); + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%02x\n", ret); + case SWPLD3_REG_VALUE: + ret = i2c_smbus_read_byte_data(pdata[swpld3].client, swpld3_reg_addr); + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%02x\n", ret); + default: + mutex_unlock(&dni_lock); + return sprintf(buf, "%d not found", attr->index); + } + + switch (mask) { + case 0xff: + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%02x%s", value, note); + case 0x0f: + case 0x07: + case 0x03: + break; + case 0x0c: + value = value >> 2; + break; + case 0xf0: + case 0x70: + case 0x30: + value = value >> 4; + break; + case 0xe0: + value = value >> 5; + break; + case 0xc0: + value = value >> 6; + break; + default : + value = value >> dni_log2(mask); + mutex_unlock(&dni_lock); + return sprintf(buf, "%d%s", value, note); + } + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%02x%s", value, note); +} + +static ssize_t set_cpld_reg(struct device *dev, struct device_attribute *dev_attr, + const char *buf, size_t count) +{ + int err; + int set_data; + unsigned long set_data_ul; + unsigned char mask; + unsigned char mask_out; + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cpld_platform_data *pdata = dev->platform_data; + + err = kstrtoul(buf, 0, &set_data_ul); + if (err){ + return err; + } + + mutex_lock(&dni_lock); + set_data = (int)set_data_ul; + if (set_data > 0xff){ + printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); + mutex_unlock(&dni_lock); + return count; + } + + switch (attr->index) { + case CPLD_REG_ADDR: + cpupld_reg_addr = set_data; + mutex_unlock(&dni_lock); + return count; + case SWPLD2_REG_ADDR: + swpld2_reg_addr = set_data; + mutex_unlock(&dni_lock); + return count; + case SWPLD3_REG_ADDR: + swpld3_reg_addr = set_data; + mutex_unlock(&dni_lock); + return count; + case CPLD_REG_VALUE: + i2c_smbus_write_byte_data(pdata[cpu_cpld].client, cpupld_reg_addr, set_data); + mutex_unlock(&dni_lock); + return count; + case SWPLD2_REG_VALUE: + i2c_smbus_write_byte_data(pdata[swpld2].client, swpld2_reg_addr, set_data); + mutex_unlock(&dni_lock); + return count; + case SWPLD3_REG_VALUE: + i2c_smbus_write_byte_data(pdata[swpld3].client, swpld3_reg_addr, set_data); + mutex_unlock(&dni_lock); + return count; + default: + mutex_unlock(&dni_lock); + return sprintf(buf, "%d not found", attr->index); + } + + switch (mask) { + case 0x03: + case 0x07: + case 0x0f: + case 0xff: + set_data = mask_out | (set_data & mask); + break; + case 0x0c: + set_data = set_data << 2; + set_data = mask_out | (set_data & mask); + break; + case 0xf0: + case 0x70: + case 0x30: + set_data = set_data << 4; + set_data = mask_out | (set_data & mask); + break; + case 0xe0: + set_data = set_data << 5; + set_data = mask_out | (set_data & mask); + break; + case 0xc0: + set_data = set_data << 6; + set_data = mask_out | (set_data & mask); + break; + default : + set_data = mask_out | (set_data << dni_log2(mask) ); + } + switch (attr->index) { + default: + mutex_unlock(&dni_lock); + return sprintf(buf, "cpld not found"); + } + mutex_unlock(&dni_lock); + return count; +} + +/* ---------------- SFP attribute read/write - start -------- */ + +static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf){ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct device *i2cdev_1 = kobj_to_dev(kobj_swpld2); + struct device *i2cdev_2 = kobj_to_dev(kobj_swpld3); + struct cpld_platform_data *pdata1 = i2cdev_1->platform_data; + struct cpld_platform_data *pdata2 = i2cdev_2->platform_data; + + mutex_lock(&dni_lock); + int ret; + u32 data = 0; + int data2 = 0; + u8 save_bytes = 0x00; + + switch (attr->index) { + case SFP_IS_PRESENT: + /* Report the SFP/QSFP ALL PRESENCE status + * This data information form SWPLD2 and SWPLD3. */ + + ret = i2c_smbus_read_byte_data(pdata2[swpld3].client, QSFP_PRESENCE_4); + data = (u32)(ret & 0xff); + ret = i2c_smbus_read_byte_data(pdata2[swpld3].client, QSFP_PRESENCE_3); + data |= (u32)(ret & 0xff) << 8; + ret = i2c_smbus_read_byte_data(pdata1[swpld2].client, QSFP_PRESENCE_2); + data |= (u32)(ret & 0xff) << 16; + ret = i2c_smbus_read_byte_data(pdata1[swpld2].client, QSFP_PRESENCE_1); + data |= (u32)(ret & 0xff) << 24; + ret = i2c_smbus_read_byte_data(pdata2[swpld3].client, SFP_PRESENCE); + data2 = (ret & 0x44); + save_bytes = data2 & 0x40; + save_bytes = save_bytes << 1; + data2 &= 0x04; + data2 = data2 << 4; + data2 |= save_bytes; + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%x%02x\n", data, data2); + + case QSFP_LP_MODE: + ret = i2c_smbus_read_byte_data(pdata2[swpld3].client, QSFP_LP_MODE_4); + data = (u32)(ret & 0xff); + ret = i2c_smbus_read_byte_data(pdata2[swpld3].client, QSFP_LP_MODE_3); + data |= (u32)(ret & 0xff) << 8; + ret = i2c_smbus_read_byte_data(pdata1[swpld2].client, QSFP_LP_MODE_2); + data |= (u32)(ret & 0xff) << 16; + ret = i2c_smbus_read_byte_data(pdata1[swpld2].client, QSFP_LP_MODE_1); + data |= (u32)(ret & 0xff) << 24; + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%x\n", data); + + case QSFP_RESET: + ret = i2c_smbus_read_byte_data(pdata2[swpld3].client, QSFP_RESET_4); + data = (u32)(ret & 0xff); + ret = i2c_smbus_read_byte_data(pdata2[swpld3].client, QSFP_RESET_3); + data |= (u32)(ret & 0xff) << 8; + ret = i2c_smbus_read_byte_data(pdata1[swpld2].client, QSFP_RESET_2); + data |= (u32)(ret & 0xff) << 16; + ret = i2c_smbus_read_byte_data(pdata1[swpld2].client, QSFP_RESET_1); + data |= (u32)(ret & 0xff) << 24; + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%x\n", data); + + case QSFP_INTERRUPT: + ret = i2c_smbus_read_byte_data(pdata2[swpld3].client, QSFP_INTERRUPT_4); + data = (u32)(ret & 0xff); + ret = i2c_smbus_read_byte_data(pdata2[swpld3].client, QSFP_INTERRUPT_3); + data |= (u32)(ret & 0xff) << 8; + ret = i2c_smbus_read_byte_data(pdata1[swpld2].client, QSFP_INTERRUPT_2); + data |= (u32)(ret & 0xff) << 16; + ret = i2c_smbus_read_byte_data(pdata1[swpld2].client, QSFP_INTERRUPT_1); + data |= (u32)(ret & 0xff) << 24; + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%x\n", data); + + case QSFP_RESPONDE: + ret = i2c_smbus_read_byte_data(pdata2[swpld3].client, QSFP_RESPONDE_4); + data = (u32)(ret & 0xff); + ret = i2c_smbus_read_byte_data(pdata2[swpld3].client, QSFP_RESPONDE_3); + data |= (u32)(ret & 0xff) << 8; + ret = i2c_smbus_read_byte_data(pdata1[swpld2].client, QSFP_RESPONDE_2); + data |= (u32)(ret & 0xff) << 16; + ret = i2c_smbus_read_byte_data(pdata1[swpld2].client, QSFP_RESPONDE_1); + data |= (u32)(ret & 0xff) << 24; + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%x\n", data); + + default: + mutex_unlock(&dni_lock); + return sprintf(buf, "%d not found", attr->index); + } +} + + +static ssize_t set_lpmode_data(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count) +{ + struct device *i2cdev_1 = kobj_to_dev(kobj_swpld2); + struct device *i2cdev_2 = kobj_to_dev(kobj_swpld3); + struct cpld_platform_data *pdata1 = i2cdev_1->platform_data; + struct cpld_platform_data *pdata2 = i2cdev_2->platform_data; + unsigned long long set_data; + int err; + int values = 0x00; + u8 reg_t = 0x00; + + err = kstrtoull(buf, 16, &set_data); + if (err){ + return err; + } + mutex_lock(&dni_lock); + reg_t = QSFP_LP_MODE_1; + values = ((set_data >> 24 ) & 0xff); + if (i2c_smbus_write_byte_data(pdata1[swpld2].client, reg_t, (u8)values) < 0) + { + goto ERROR; + } + + reg_t = QSFP_LP_MODE_2; + values = ((set_data >> 16 ) & 0xff); + if (i2c_smbus_write_byte_data(pdata1[swpld2].client, reg_t, (u8)values) < 0) + { + goto ERROR; + } + + reg_t = QSFP_LP_MODE_3; + values = ((set_data >> 8 ) & 0xff); + if (i2c_smbus_write_byte_data(pdata2[swpld3].client, reg_t, (u8)values) < 0) + { + goto ERROR; + } + + reg_t = QSFP_LP_MODE_4; + values = (set_data & 0xff); + if (i2c_smbus_write_byte_data(pdata2[swpld3].client, reg_t, (u8)values) < 0) + { + goto ERROR; + } + + mutex_unlock(&dni_lock); + return count; + +ERROR: + mutex_unlock(&dni_lock); + return -EIO; +} + +static ssize_t set_reset_data(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count) +{ + struct device *i2cdev_1 = kobj_to_dev(kobj_swpld2); + struct device *i2cdev_2 = kobj_to_dev(kobj_swpld3); + struct cpld_platform_data *pdata1 = i2cdev_1->platform_data; + struct cpld_platform_data *pdata2 = i2cdev_2->platform_data; + unsigned long long set_data; + int err; + int values = 0x00; + u8 reg_t = 0x00; + + err = kstrtoull(buf, 16, &set_data); + if (err){ + return err; + } + + mutex_lock(&dni_lock); + reg_t = QSFP_RESET_1; + values = ((set_data >> 24 ) & 0xff); + if (i2c_smbus_write_byte_data(pdata1[swpld2].client, reg_t, (u8)values) < 0) + { + goto ERROR; + } + reg_t = QSFP_RESET_2; + values = ((set_data >> 16 ) & 0xff); + if (i2c_smbus_write_byte_data(pdata1[swpld2].client, reg_t, (u8)values) < 0) + { + goto ERROR; + } + reg_t = QSFP_RESET_3; + values = ((set_data >> 8 ) & 0xff); + if (i2c_smbus_write_byte_data(pdata2[swpld3].client, reg_t, (u8)values) < 0) + { + goto ERROR; + } + reg_t = QSFP_RESET_4; + values = (set_data & 0xff); + if (i2c_smbus_write_byte_data(pdata2[swpld3].client, reg_t, (u8)values) < 0) + { + goto ERROR; + } + + mutex_unlock(&dni_lock); + return count; + +ERROR: + mutex_unlock(&dni_lock); + return -EIO; +} + +static ssize_t set_interrupt_data(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count) +{ + struct device *i2cdev_1 = kobj_to_dev(kobj_swpld2); + struct device *i2cdev_2 = kobj_to_dev(kobj_swpld3); + struct cpld_platform_data *pdata1 = i2cdev_1->platform_data; + struct cpld_platform_data *pdata2 = i2cdev_2->platform_data; + unsigned long long set_data; + int err; + int values = 0x00; + u8 reg_t = 0x00; + + err = kstrtoull(buf, 16, &set_data); + if (err){ + return err; + } + + mutex_lock(&dni_lock); + reg_t = QSFP_INTERRUPT_1; + values = ((set_data >> 24 ) & 0xff); + if (i2c_smbus_write_byte_data(pdata1[swpld2].client, reg_t, (u8)values) < 0) + { + goto ERROR; + } + reg_t = QSFP_INTERRUPT_2; + values = ((set_data >> 16 ) & 0xff); + if (i2c_smbus_write_byte_data(pdata1[swpld2].client, reg_t, (u8)values) < 0) + { + goto ERROR; + } + reg_t = QSFP_INTERRUPT_3; + values = ((set_data >> 8 ) & 0xff); + if (i2c_smbus_write_byte_data(pdata2[swpld3].client, reg_t, (u8)values) < 0) + { + goto ERROR; + } + reg_t = QSFP_INTERRUPT_4; + values = (set_data & 0xff); + + if (i2c_smbus_write_byte_data(pdata2[swpld3].client, reg_t, (u8)values) < 0) + { + goto ERROR; + } + + mutex_unlock(&dni_lock); + return count; + +ERROR: + mutex_unlock(&dni_lock); + return -EIO; +} + +static ssize_t set_responde_data(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count) +{ + struct device *i2cdev_1 = kobj_to_dev(kobj_swpld2); + struct device *i2cdev_2 = kobj_to_dev(kobj_swpld3); + struct cpld_platform_data *pdata1 = i2cdev_1->platform_data; + struct cpld_platform_data *pdata2 = i2cdev_2->platform_data; + unsigned long long set_data; + int err; + int values = 0x00; + u8 reg_t = 0x00; + + err = kstrtoull(buf, 16, &set_data); + if (err){ + return err; + } + + mutex_lock(&dni_lock); + reg_t = QSFP_RESPONDE_1; + values = ((set_data >> 24 ) & 0xff); + if (i2c_smbus_write_byte_data(pdata1[swpld2].client, reg_t, (u8)values) < 0) + { + goto ERROR; + } + reg_t = QSFP_RESPONDE_2; + values = ((set_data >> 16 ) & 0xff); + if (i2c_smbus_write_byte_data(pdata1[swpld2].client, reg_t, (u8)values) < 0) + { + goto ERROR; + } + reg_t = QSFP_RESPONDE_3; + values = ((set_data >> 8 ) & 0xff); + if (i2c_smbus_write_byte_data(pdata2[swpld3].client, reg_t, (u8)values) < 0) + { + goto ERROR; + } + reg_t = QSFP_RESPONDE_4; + values = (set_data & 0xff); + if (i2c_smbus_write_byte_data(pdata2[swpld3].client, reg_t, (u8)values) < 0) + { + goto ERROR; + } + + mutex_unlock(&dni_lock); + return count; + +ERROR: + mutex_unlock(&dni_lock); + return -EIO; +} + +static SENSOR_DEVICE_ATTR(cpld_reg_addr, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, CPLD_REG_ADDR); +static SENSOR_DEVICE_ATTR(cpld_reg_value, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, CPLD_REG_VALUE); +static SENSOR_DEVICE_ATTR(swpld2_reg_addr, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, SWPLD2_REG_ADDR); +static SENSOR_DEVICE_ATTR(swpld2_reg_value, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, SWPLD2_REG_VALUE); +static SENSOR_DEVICE_ATTR(swpld3_reg_addr, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, SWPLD3_REG_ADDR); +static SENSOR_DEVICE_ATTR(swpld3_reg_value, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, SWPLD3_REG_VALUE); +//SFP, QSFP +static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, for_status, NULL, SFP_IS_PRESENT); +static SENSOR_DEVICE_ATTR(sfp_lp_mode, S_IWUSR | S_IRUGO, for_status, set_lpmode_data, QSFP_LP_MODE); +static SENSOR_DEVICE_ATTR(sfp_reset, S_IWUSR | S_IRUGO, for_status, set_reset_data, QSFP_RESET); +static SENSOR_DEVICE_ATTR(sfp_interrupt, S_IWUSR | S_IRUGO, for_status, set_interrupt_data, QSFP_INTERRUPT); +static SENSOR_DEVICE_ATTR(sfp_responde, S_IWUSR | S_IRUGO, for_status, set_responde_data, QSFP_RESPONDE); + +static struct attribute *cpld_attrs[] = { + &sensor_dev_attr_cpld_reg_value.dev_attr.attr, + &sensor_dev_attr_cpld_reg_addr.dev_attr.attr, +//SFP, QSFP + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_lp_mode.dev_attr.attr, + &sensor_dev_attr_sfp_reset.dev_attr.attr, + &sensor_dev_attr_sfp_interrupt.dev_attr.attr, + &sensor_dev_attr_sfp_responde.dev_attr.attr, + NULL, +}; + +static struct attribute *swpld2_attrs[] = { + &sensor_dev_attr_swpld2_reg_value.dev_attr.attr, + &sensor_dev_attr_swpld2_reg_addr.dev_attr.attr, + NULL, +}; + +static struct attribute *swpld3_attrs[] = { + &sensor_dev_attr_swpld3_reg_value.dev_attr.attr, + &sensor_dev_attr_swpld3_reg_addr.dev_attr.attr, + NULL, +}; + +static struct attribute_group cpld_attr_grp = { + .attrs = cpld_attrs, +}; + +static struct attribute_group swpld2_attr_grp = { + .attrs = swpld2_attrs, +}; + +static struct attribute_group swpld3_attr_grp = { + .attrs = swpld3_attrs, +}; + +/* CPLD -- driver */ +static int __init cpld_probe(struct platform_device *pdev) +{ + struct cpld_platform_data *pdata; + struct i2c_adapter *parent; + int ret; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "CPLD platform data not found\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(BUS0); + if (!parent) { + printk(KERN_WARNING "Parent adapter (%d) not found\n", BUS0); + return -ENODEV; + } + + pdata[cpu_cpld].client = i2c_new_dummy(parent, pdata[cpu_cpld].reg_addr); + if (!pdata[cpu_cpld].client) { + printk(KERN_WARNING "Fail to create dummy i2c client for addr %d\n", pdata[cpu_cpld].reg_addr); + goto error; + } + + kobj_cpld = &pdev->dev.kobj; + ret = sysfs_create_group(&pdev->dev.kobj, &cpld_attr_grp); + if (ret) { + printk(KERN_WARNING "Fail to create cpld attribute group"); + goto error; + } + + return 0; +error: + kobject_put(kobj_cpld); + i2c_unregister_device(pdata[cpu_cpld].client); + i2c_put_adapter(parent); + + return -ENODEV; +} + +static int __exit cpld_remove(struct platform_device *pdev) +{ + struct i2c_adapter *parent = NULL; + struct cpld_platform_data *pdata = pdev->dev.platform_data; + sysfs_remove_group(&pdev->dev.kobj, &cpld_attr_grp); + + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + } + else { + if (pdata[cpu_cpld].client) { + if (!parent) { + parent = (pdata[cpu_cpld].client)->adapter; + } + i2c_unregister_device(pdata[cpu_cpld].client); + } + } + i2c_put_adapter(parent); + + return 0; +} + +static int __init swpld2_probe(struct platform_device *pdev) +{ + struct cpld_platform_data *pdata; + struct i2c_adapter *parent; + int ret; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "SWPLD2 platform data not found\n"); + return -ENODEV; + } + parent = i2c_get_adapter(11); + if (!parent) { + printk(KERN_WARNING "Parent adapter (%d) not found\n", 11); + return -ENODEV; + } + + pdata[swpld2].client = i2c_new_dummy(parent, pdata[swpld2].reg_addr); + if (!pdata[swpld2].client) { + printk(KERN_WARNING "Fail to create dummy i2c client for addr %d\n", pdata[swpld2].reg_addr); + goto error; + } + + kobj_swpld2 = &pdev->dev.kobj; + ret = sysfs_create_group(&pdev->dev.kobj, &swpld2_attr_grp); + if (ret) { + printk(KERN_WARNING "Fail to create swpld attribute group"); + goto error; + } + return 0; + +error: + kobject_put(kobj_swpld2); + i2c_unregister_device(pdata[swpld2].client); + i2c_put_adapter(parent); + return -ENODEV; +} + +static int __exit swpld2_remove(struct platform_device *pdev) +{ + struct i2c_adapter *parent = NULL; + struct cpld_platform_data *pdata = pdev->dev.platform_data; + sysfs_remove_group(&pdev->dev.kobj, &swpld2_attr_grp); + + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + } + else { + if (pdata[swpld2].client) { + if (!parent) { + parent = (pdata[swpld2].client)->adapter; + } + i2c_unregister_device(pdata[swpld2].client); + } + } + i2c_put_adapter(parent); + return 0; +} + + +static int __init swpld3_probe(struct platform_device *pdev) +{ + struct cpld_platform_data *pdata; + struct i2c_adapter *parent; + int ret; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "SWPLD3 platform data not found\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(11); + if (!parent) { + printk(KERN_WARNING "Parent adapter (%d) not found\n", 11); + return -ENODEV; + } + + pdata[swpld3].client = i2c_new_dummy(parent, pdata[swpld3].reg_addr); + if (!pdata[swpld3].client) { + printk(KERN_WARNING "Fail to create dummy i2c client for addr %d\n", pdata[swpld3].reg_addr); + goto error; + } + + kobj_swpld3 = &pdev->dev.kobj; + ret = sysfs_create_group(&pdev->dev.kobj, &swpld3_attr_grp); + if (ret) { + printk(KERN_WARNING "Fail to create swpld attribute group"); + goto error; + } + + return 0; + +error: + kobject_put(kobj_swpld3); + i2c_unregister_device(pdata[swpld3].client); + i2c_put_adapter(parent); + + return -ENODEV; +} + +static int __exit swpld3_remove(struct platform_device *pdev) +{ + struct i2c_adapter *parent = NULL; + struct cpld_platform_data *pdata = pdev->dev.platform_data; + sysfs_remove_group(&pdev->dev.kobj, &swpld3_attr_grp); + + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + } + else { + 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 cpld_driver = { + .probe = cpld_probe, + .remove = __exit_p(cpld_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-et-c032if-cpld", + }, +}; + +static struct platform_driver swpld2_driver = { + .probe = swpld2_probe, + .remove = __exit_p(swpld2_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-et-c032if-swpld2", + }, +}; + +static struct platform_driver swpld3_driver = { + .probe = swpld3_probe, + .remove = __exit_p(swpld3_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-et-c032if-swpld3", + }, +}; + + +/*---------------- CPLD - end ------------- */ + +/*---------------- delta ATTR - start ------------- */ + +struct delta_bin_attribute { + struct bin_attribute attr; + int index; +}; + +#define to_delta_attr(x) container_of(x, struct delta_bin_attribute, attr) + +#define BIN_ATTR(_name, _mode, _read, _write, _size, _index) { \ + .attr = { \ + .attr = {.name = __stringify(_name), .mode = _mode }, \ + .read = _read, \ + .write = _write, \ + .size = _size, \ + }, \ + .index = _index, \ +} + +#define DELTA_BIN_ATTR(_name, _mode, _read, _write, _size, _index) \ +struct delta_bin_attribute delta_attr_##_name \ + = BIN_ATTR(_name, _mode, _read, _write, _size, _index) + +static char eeprom_data[EEPROM_SIZE]; + +static ssize_t access_user_space(const char *name, char *buf, size_t len, loff_t offset, int mode) +{ + struct file *fp; + mm_segment_t fs; + loff_t pos = offset; + ssize_t vfs_ret = 0; + + fs = get_fs(); + set_fs(get_ds()); + + switch(mode) + { + case ATTR_W: + fp = filp_open(name, O_WRONLY, S_IWUSR | S_IRUGO); + if (IS_ERR(fp)){ + return -ENOENT; + } + vfs_ret = vfs_write(fp, buf, len, &pos); + break; + case ATTR_R: + fp = filp_open(name, O_RDONLY, S_IRUGO); + if (IS_ERR(fp)){ + return -ENOENT; + } + vfs_ret = vfs_read(fp, buf, len, &pos); + break; + } + + set_fs(fs); + filp_close(fp, NULL); + return vfs_ret; +} + +enum sfp_attributes{ + EEPROM_SYS, + EEPROM_SFP_1, + EEPROM_SFP_2, + EEPROM_SFP_3, + EEPROM_SFP_4, + EEPROM_SFP_5, + EEPROM_SFP_6, + EEPROM_SFP_7, + EEPROM_SFP_8, + EEPROM_SFP_9, + EEPROM_SFP_10, + EEPROM_SFP_11, + EEPROM_SFP_12, + EEPROM_SFP_13, + EEPROM_SFP_14, + EEPROM_SFP_15, + EEPROM_SFP_16, + EEPROM_SFP_17, + EEPROM_SFP_18, + EEPROM_SFP_19, + EEPROM_SFP_20, + EEPROM_SFP_21, + EEPROM_SFP_22, + EEPROM_SFP_23, + EEPROM_SFP_24, + EEPROM_SFP_25, + EEPROM_SFP_26, + EEPROM_SFP_27, + EEPROM_SFP_28, + EEPROM_SFP_29, + EEPROM_SFP_30, + EEPROM_SFP_31, + EEPROM_SFP_32, + EEPROM_SFP_33, + EEPROM_SFP_34, +}; + + +static ssize_t delta_bin_attr_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct delta_bin_attribute *delta_attr = to_delta_attr(attr); + char attr_path[100]; + + mutex_lock(&dni_lock); + memset(buf, 0, count); + switch(delta_attr->index) { + case EEPROM_SFP_1: + case EEPROM_SFP_2: + case EEPROM_SFP_3: + case EEPROM_SFP_4: + case EEPROM_SFP_5: + case EEPROM_SFP_6: + case EEPROM_SFP_7: + case EEPROM_SFP_8: + case EEPROM_SFP_9: + case EEPROM_SFP_10: + case EEPROM_SFP_11: + case EEPROM_SFP_12: + case EEPROM_SFP_13: + case EEPROM_SFP_14: + case EEPROM_SFP_15: + case EEPROM_SFP_16: + case EEPROM_SFP_17: + case EEPROM_SFP_18: + case EEPROM_SFP_19: + case EEPROM_SFP_20: + case EEPROM_SFP_21: + case EEPROM_SFP_22: + case EEPROM_SFP_23: + case EEPROM_SFP_24: + case EEPROM_SFP_25: + case EEPROM_SFP_26: + case EEPROM_SFP_27: + case EEPROM_SFP_28: + case EEPROM_SFP_29: + case EEPROM_SFP_30: + case EEPROM_SFP_31: + case EEPROM_SFP_32: + case EEPROM_SFP_33: + case EEPROM_SFP_34: + sprintf(attr_path, "/sys/bus/i2c/devices/%d-0050/eeprom", delta_attr->index + EEPROM_MASK); + if (access_user_space(attr_path, eeprom_data, EEPROM_SIZE, 0, ATTR_R) < 0) { + goto ACCESS_ERROR; + } + count = (count <= EEPROM_SIZE) ? count : EEPROM_SIZE; + memcpy(buf, eeprom_data + off, count); + break; + case EEPROM_SYS: + sprintf(attr_path, "/sys/bus/i2c/devices/10-0053/eeprom"); + if (access_user_space(attr_path, eeprom_data, EEPROM_SIZE, 0, ATTR_R) < 0) { + goto ACCESS_ERROR; + } + count = (count <= EEPROM_SIZE) ? count : EEPROM_SIZE; + memcpy(buf, eeprom_data + off, count); + break; + default: + goto ACCESS_ERROR; + } + mutex_unlock(&dni_lock); + return count; + +ACCESS_ERROR: + mutex_unlock(&dni_lock); + return -ENXIO; +} + +static ssize_t delta_bin_attr_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct delta_bin_attribute *delta_attr = to_delta_attr(attr); + char attr_path[100]; + + switch(delta_attr->index){ + case EEPROM_SFP_1: + case EEPROM_SFP_2: + case EEPROM_SFP_3: + case EEPROM_SFP_4: + case EEPROM_SFP_5: + case EEPROM_SFP_6: + case EEPROM_SFP_7: + case EEPROM_SFP_8: + case EEPROM_SFP_9: + case EEPROM_SFP_10: + case EEPROM_SFP_11: + case EEPROM_SFP_12: + case EEPROM_SFP_13: + case EEPROM_SFP_14: + case EEPROM_SFP_15: + case EEPROM_SFP_16: + case EEPROM_SFP_17: + case EEPROM_SFP_18: + case EEPROM_SFP_19: + case EEPROM_SFP_20: + case EEPROM_SFP_21: + case EEPROM_SFP_22: + case EEPROM_SFP_23: + case EEPROM_SFP_24: + case EEPROM_SFP_25: + case EEPROM_SFP_26: + case EEPROM_SFP_27: + case EEPROM_SFP_28: + case EEPROM_SFP_29: + case EEPROM_SFP_30: + case EEPROM_SFP_31: + case EEPROM_SFP_32: + case EEPROM_SFP_33: + case EEPROM_SFP_34: + sprintf(attr_path, "/sys/bus/i2c/devices/%d-0050/eeprom", delta_attr->index + EEPROM_MASK); + if (access_user_space(attr_path, buf, count, 0, ATTR_W) < 0) { + goto ACCESS_ERROR; + } + break; + case EEPROM_SYS: + sprintf(attr_path, "/sys/bus/i2c/devices/10-0053/eeprom"); + if (access_user_space(attr_path, buf, count, 0, ATTR_W) < 0) { + goto ACCESS_ERROR; + } + break; + default: + goto ACCESS_ERROR; + } + + mutex_unlock(&dni_lock); + return count; +ACCESS_ERROR: + mutex_unlock(&dni_lock); + return -ETIMEDOUT; +} + +DELTA_BIN_ATTR(eeprom_sys, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SYS); +DELTA_BIN_ATTR(eeprom_sfp_1, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_1); +DELTA_BIN_ATTR(eeprom_sfp_2, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_2); +DELTA_BIN_ATTR(eeprom_sfp_3, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_3); +DELTA_BIN_ATTR(eeprom_sfp_4, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_4); +DELTA_BIN_ATTR(eeprom_sfp_5, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_5); +DELTA_BIN_ATTR(eeprom_sfp_6, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_6); +DELTA_BIN_ATTR(eeprom_sfp_7, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_7); +DELTA_BIN_ATTR(eeprom_sfp_8, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_8); +DELTA_BIN_ATTR(eeprom_sfp_9, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_9); +DELTA_BIN_ATTR(eeprom_sfp_10, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_10); +DELTA_BIN_ATTR(eeprom_sfp_11, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_11); +DELTA_BIN_ATTR(eeprom_sfp_12, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_12); +DELTA_BIN_ATTR(eeprom_sfp_13, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_13); +DELTA_BIN_ATTR(eeprom_sfp_14, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_14); +DELTA_BIN_ATTR(eeprom_sfp_15, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_15); +DELTA_BIN_ATTR(eeprom_sfp_16, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_16); +DELTA_BIN_ATTR(eeprom_sfp_17, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_17); +DELTA_BIN_ATTR(eeprom_sfp_18, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_18); +DELTA_BIN_ATTR(eeprom_sfp_19, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_19); +DELTA_BIN_ATTR(eeprom_sfp_20, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_20); +DELTA_BIN_ATTR(eeprom_sfp_21, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_21); +DELTA_BIN_ATTR(eeprom_sfp_22, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_22); +DELTA_BIN_ATTR(eeprom_sfp_23, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_23); +DELTA_BIN_ATTR(eeprom_sfp_24, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_24); +DELTA_BIN_ATTR(eeprom_sfp_25, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_25); +DELTA_BIN_ATTR(eeprom_sfp_26, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_26); +DELTA_BIN_ATTR(eeprom_sfp_27, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_27); +DELTA_BIN_ATTR(eeprom_sfp_28, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_28); +DELTA_BIN_ATTR(eeprom_sfp_29, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_29); +DELTA_BIN_ATTR(eeprom_sfp_30, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_30); +DELTA_BIN_ATTR(eeprom_sfp_31, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_31); +DELTA_BIN_ATTR(eeprom_sfp_32, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_32); +DELTA_BIN_ATTR(eeprom_sfp_33, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_33); +DELTA_BIN_ATTR(eeprom_sfp_34, 0664, delta_bin_attr_read, delta_bin_attr_write, EEPROM_SIZE, EEPROM_SFP_34); + +static struct bin_attribute *sfp_attrs[] = { + &delta_attr_eeprom_sys.attr, + &delta_attr_eeprom_sfp_1.attr, + &delta_attr_eeprom_sfp_2.attr, + &delta_attr_eeprom_sfp_3.attr, + &delta_attr_eeprom_sfp_4.attr, + &delta_attr_eeprom_sfp_5.attr, + &delta_attr_eeprom_sfp_6.attr, + &delta_attr_eeprom_sfp_7.attr, + &delta_attr_eeprom_sfp_8.attr, + &delta_attr_eeprom_sfp_9.attr, + &delta_attr_eeprom_sfp_10.attr, + &delta_attr_eeprom_sfp_11.attr, + &delta_attr_eeprom_sfp_12.attr, + &delta_attr_eeprom_sfp_13.attr, + &delta_attr_eeprom_sfp_14.attr, + &delta_attr_eeprom_sfp_15.attr, + &delta_attr_eeprom_sfp_16.attr, + &delta_attr_eeprom_sfp_17.attr, + &delta_attr_eeprom_sfp_18.attr, + &delta_attr_eeprom_sfp_19.attr, + &delta_attr_eeprom_sfp_20.attr, + &delta_attr_eeprom_sfp_21.attr, + &delta_attr_eeprom_sfp_22.attr, + &delta_attr_eeprom_sfp_23.attr, + &delta_attr_eeprom_sfp_24.attr, + &delta_attr_eeprom_sfp_25.attr, + &delta_attr_eeprom_sfp_26.attr, + &delta_attr_eeprom_sfp_27.attr, + &delta_attr_eeprom_sfp_28.attr, + &delta_attr_eeprom_sfp_29.attr, + &delta_attr_eeprom_sfp_30.attr, + &delta_attr_eeprom_sfp_31.attr, + &delta_attr_eeprom_sfp_32.attr, + &delta_attr_eeprom_sfp_33.attr, + &delta_attr_eeprom_sfp_34.attr, + NULL, /* need to NULL terminate the list of attributes */ +}; + +static struct attribute_group sfp_attr_grp = { + .bin_attrs = sfp_attrs, +}; + +/*---------------- delta ATTR - end ------------- */ + +/*---------------- MUX - start ------------- */ + +struct cpld_mux_platform_data { + int parent; + int base_nr; + int reg_addr; + struct i2c_client *cpld; +}; + +struct cpld_mux { + struct i2c_adapter *parent; + struct i2c_adapter **child; + struct cpld_mux_platform_data data; +}; + +static struct cpld_mux_platform_data et_c032if_cpld_mux_platform_data[] = { + { + .parent = BUS0, + .base_nr = BUS0_BASE_NUM, + .cpld = NULL, + .reg_addr = BUS0_MUX_REG, + }, +}; + +static struct platform_device et_c032if_cpld_mux[] = +{ + { + .name = "delta-et-c032if-cpld-mux", + .id = 0, + .dev = { + .platform_data = &et_c032if_cpld_mux_platform_data[0], + .release = device_release, + }, + }, +}; + +static int cpld_reg_write_byte(struct i2c_client *client, u8 regaddr, u8 val) +{ + union i2c_smbus_data data; + + data.byte = val; + return client->adapter->algo->smbus_xfer(client->adapter, client->addr, + client->flags, + I2C_SMBUS_WRITE, + regaddr, I2C_SMBUS_BYTE_DATA, &data); +} + +static int cpld_mux_select(struct i2c_mux_core *muxc, u32 chan) +{ + struct cpld_mux *mux = i2c_mux_priv(muxc); + u8 cpld_mux_val=0; + + if ( mux->data.base_nr == BUS0_BASE_NUM ) + { + switch (chan) { + case 0: + cpld_mux_val = EEPROM_VAL; + break; + case 1: + cpld_mux_val = SWPLD_VAL; + break; + case 2: + cpld_mux_val = QSFP_VAL; + break; + default: + cpld_mux_val = 0x00; + break; + } + } + else + { + cpld_mux_val = 0x00; + } + return cpld_reg_write_byte(mux->data.cpld, mux->data.reg_addr, (u8)(cpld_mux_val & 0xff)); + +} + +static int __init cpld_mux_probe(struct platform_device *pdev) +{ + struct i2c_mux_core *muxc; + struct cpld_mux *mux; + struct cpld_mux_platform_data *pdata; + struct i2c_adapter *parent; + int i, ret, dev_num; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "SWPLD platform data not found\n"); + return -ENODEV; + } + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) { + printk(KERN_ERR "Failed to allocate memory for mux\n"); + return -ENOMEM; + } + mux->data = *pdata; + + parent = i2c_get_adapter(pdata->parent); + if (!parent) { + kfree(mux); + dev_err(&pdev->dev, "Parent adapter (%d) not found\n", pdata->parent); + return -ENODEV; + } + /* Judge bus number to decide how many devices*/ + switch (pdata->parent) { + case BUS0: + dev_num = BUS0_DEV_NUM; + break; + default : + dev_num = DEFAULT_NUM; + break; + } + + muxc = i2c_mux_alloc(parent, &pdev->dev, dev_num, 0, 0,cpld_mux_select, NULL); + if (!muxc) { + ret = -ENOMEM; + goto alloc_failed; + } + muxc->priv = mux; + platform_set_drvdata(pdev, muxc); + + for (i = 0; i < dev_num; i++) + { + int nr = pdata->base_nr + i; + unsigned int class = 0; + ret = i2c_mux_add_adapter(muxc, nr, i, class); + if (ret) { + dev_err(&pdev->dev, "Failed to add adapter %d\n", i); + goto add_adapter_failed; + } + } + dev_info(&pdev->dev, "%d port mux on %s adapter\n", dev_num, parent->name); + return 0; + +add_adapter_failed: + i2c_mux_del_adapters(muxc); +alloc_failed: + kfree(mux); + i2c_put_adapter(parent); + + return ret; +} + +static int __exit cpld_mux_remove(struct platform_device *pdev) +{ + struct i2c_mux_core *muxc = platform_get_drvdata(pdev); + struct i2c_adapter *parent = muxc->parent; + + i2c_mux_del_adapters(muxc); + i2c_put_adapter(parent); + + return 0; +} + +static struct platform_driver cpld_mux_driver = { + .probe = cpld_mux_probe, + .remove = __exit_p(cpld_mux_remove), /* TODO */ + .driver = { + .owner = THIS_MODULE, + .name = "delta-et-c032if-cpld-mux", + }, +}; +/*---------------- MUX - end ------------- */ + +/*---------------- module initialization ------------- */ +static int __init delta_et_c032if_platform_init(void) +{ + struct i2c_adapter *adapter; + struct cpld_platform_data *cpld_pdata; + struct cpld_mux_platform_data *cpld_mux_pdata; + int ret,i = 0; + + mutex_init(&dni_lock); + printk("c032if_platform module initialization\n"); + + // set the CPLD prob and remove + ret = platform_driver_register(&cpld_driver); + if (ret) { + printk(KERN_WARNING "Fail to register cpld driver\n"); + goto error_cpld_driver; + } + + ret = platform_driver_register(&cpld_mux_driver); + if (ret) { + printk(KERN_WARNING "Fail to register swpld mux driver\n"); + goto error_cpld_mux_driver; + } + + // set the SWPLD prob and remove + ret = platform_driver_register(&swpld2_driver); + if (ret) { + printk(KERN_WARNING "Fail to register swpld driver\n"); + goto error_swpld2_driver; + } + + // set the SWPLD prob and remove + ret = platform_driver_register(&swpld3_driver); + if (ret) { + printk(KERN_WARNING "Fail to register swpld driver\n"); + goto error_swpld3_driver; + } + + // 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; + } + + // register the CPLD + ret = platform_device_register(&et_c032if_cpld); + if (ret) { + printk(KERN_WARNING "Fail to create cpld device\n"); + goto error_et_c032if_cpld; + } + + cpld_pdata = et_c032if_cpld.dev.platform_data; + cpld_mux_pdata = et_c032if_cpld_mux[0].dev.platform_data; + cpld_mux_pdata->cpld = cpld_pdata[cpu_cpld].client; + ret = platform_device_register(&et_c032if_cpld_mux[0]); + if (ret) { + printk(KERN_WARNING "Fail to create cpld mux\n"); + goto error_et_c032if_cpld_mux; + } + + adapter = i2c_get_adapter(12); + 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); + + // register the SWPLD2 + ret = platform_device_register(&et_c032if_swpld2); + if (ret) { + printk(KERN_WARNING "Fail to create swpld2 device\n"); + goto error_swpld2_device; + } + + // register the SWPLD3 + ret = platform_device_register(&et_c032if_swpld3); + if (ret) { + printk(KERN_WARNING "Fail to create swpld3 device\n"); + goto error_swpld3_device; + } + for (i = 0; i < ARRAY_SIZE(et_c032if_i2c_device); i++) + { + ret = platform_device_register(&et_c032if_i2c_device[i]); + if (ret) { + printk(KERN_WARNING "Fail to create i2c device %d\n", i); + goto error_et_c032if_i2c_device; + } + } + + kobj_sfp = kobject_create_and_add("sfp", kernel_kobj); + if(!kobj_sfp) + { + return -ENOMEM; + } + ret = sysfs_create_group(kobj_sfp, &sfp_attr_grp); + if (ret) + { + printk(KERN_WARNING "Fail to create sysfs of sfp group\n"); + goto error_create_sfp_group; + } + if (ret) + goto error_create_sfp_group; + + return 0; + +error_create_sfp_group: + kobject_put(kobj_sfp); +error_et_c032if_i2c_device: + i--; + for (; i >= 0; i--) { + platform_device_unregister(&et_c032if_i2c_device[i]); + } + i = ARRAY_SIZE(et_c032if_cpld_mux); + platform_device_unregister(&et_c032if_swpld3); +error_swpld3_device: + platform_device_unregister(&et_c032if_swpld2); +error_swpld2_device: + i2c_unregister_device(i2c_client_9548_1); + i2c_unregister_device(i2c_client_9548_2); + i2c_unregister_device(i2c_client_9548_3); + i2c_unregister_device(i2c_client_9548_4); + i2c_unregister_device(i2c_client_9548_5); +error_et_c032if_cpld_mux: + platform_device_unregister(&et_c032if_cpld_mux[0]); + platform_device_unregister(&et_c032if_cpld); +error_et_c032if_cpld: + platform_driver_unregister(&i2c_device_driver); +error_i2c_device_driver: + platform_driver_unregister(&swpld3_driver); +error_swpld3_driver: + platform_driver_unregister(&swpld2_driver); +error_swpld2_driver: + platform_driver_unregister(&cpld_mux_driver); +error_cpld_mux_driver: + platform_driver_unregister(&cpld_driver); +error_cpld_driver: + return ret; +} + +static void __exit delta_et_c032if_platform_exit(void) +{ + int i = 0; + + kobject_put(kobj_sfp); + for (i = 0; i < ARRAY_SIZE(et_c032if_i2c_device); i++) { + platform_device_unregister(&et_c032if_i2c_device[i]); + } + platform_device_unregister(&et_c032if_swpld2); + platform_device_unregister(&et_c032if_swpld3); + i2c_unregister_device(i2c_client_9548_1); + i2c_unregister_device(i2c_client_9548_2); + i2c_unregister_device(i2c_client_9548_3); + i2c_unregister_device(i2c_client_9548_4); + i2c_unregister_device(i2c_client_9548_5); + platform_device_unregister(&et_c032if_cpld_mux[0]); + platform_device_unregister(&et_c032if_cpld); + platform_driver_unregister(&i2c_device_driver); + platform_driver_unregister(&swpld2_driver); + platform_driver_unregister(&swpld3_driver); + platform_driver_unregister(&cpld_mux_driver); + platform_driver_unregister(&cpld_driver); +} + +module_init(delta_et_c032if_platform_init); +module_exit(delta_et_c032if_platform_exit); + +MODULE_DESCRIPTION("Delta et-c032if Platform Support"); +MODULE_AUTHOR("Johnson Lu "); +MODULE_LICENSE("GPL"); diff --git a/platform/innovium/sonic-platform-modules-delta/et-c032if/scripts/et-c032if_platform_init.sh b/platform/innovium/sonic-platform-modules-delta/et-c032if/scripts/et-c032if_platform_init.sh new file mode 100644 index 000000000000..522aabea26bc --- /dev/null +++ b/platform/innovium/sonic-platform-modules-delta/et-c032if/scripts/et-c032if_platform_init.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +#platform init script for Delta et-c032if + + + +exit 0 + + diff --git a/platform/innovium/sonic-platform-modules-delta/systemd/platform-modules-et-c032if.service b/platform/innovium/sonic-platform-modules-delta/systemd/platform-modules-et-c032if.service new file mode 100644 index 000000000000..273a5ab65a4a --- /dev/null +++ b/platform/innovium/sonic-platform-modules-delta/systemd/platform-modules-et-c032if.service @@ -0,0 +1,13 @@ +[Unit] +Description=Delta et-c032if Platform modules +After=local-fs.target +Before=pmon.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-et-c032if start +ExecStop=-/etc/init.d/platform-modules-et-c032if stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/marvell-arm64/docker-ptf-mrvl.mk b/platform/marvell-arm64/docker-ptf-mrvl.mk new file mode 100644 index 000000000000..69dff4a90dd4 --- /dev/null +++ b/platform/marvell-arm64/docker-ptf-mrvl.mk @@ -0,0 +1,7 @@ +# docker image for docker-ptf-mrvl + +DOCKER_PTF_MRVL = docker-ptf-mrvl.gz +$(DOCKER_PTF_MRVL)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift +$(DOCKER_PTF_MRVL)_DEPENDS += $(PYTHON_SAITHRIFT) +$(DOCKER_PTF_MRVL)_LOAD_DOCKERS += $(DOCKER_PTF) +SONIC_DOCKER_IMAGES += $(DOCKER_PTF_MRVL) diff --git a/platform/marvell-arm64/docker-saiserver-mrvl.mk b/platform/marvell-arm64/docker-saiserver-mrvl.mk new file mode 100644 index 000000000000..398902961da8 --- /dev/null +++ b/platform/marvell-arm64/docker-saiserver-mrvl.mk @@ -0,0 +1,15 @@ +# docker image for mrvl saiserver + +DOCKER_SAISERVER_MRVL = docker-saiserver-mrvl.gz +$(DOCKER_SAISERVER_MRVL)_PATH = $(PLATFORM_PATH)/docker-saiserver-mrvl +$(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) + +$(DOCKER_SAISERVER_MRVL)_CONTAINER_NAME = saiserver +$(DOCKER_SAISERVER_MRVL)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SAISERVER_MRVL)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf +$(DOCKER_SAISERVER_MRVL)_RUN_OPT += -v /var/run/docker-saiserver:/var/run/sswsyncd +$(DOCKER_SAISERVER_MRVL)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_SAISERVER_MRVL)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/platform/marvell-arm64/docker-syncd-mrvl-rpc.mk b/platform/marvell-arm64/docker-syncd-mrvl-rpc.mk index 375c6ba91cd1..0e1b65f2fd5d 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl-rpc.mk +++ b/platform/marvell-arm64/docker-syncd-mrvl-rpc.mk @@ -3,14 +3,16 @@ DOCKER_SYNCD_MRVL_RPC = docker-syncd-mrvl-rpc.gz $(DOCKER_SYNCD_MRVL_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mrvl-rpc $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MRVL_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSWSSCOMMON_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) endif -$(DOCKER_SYNCD_MRVL_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_MRVL) +$(DOCKER_SYNCD_MRVL_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BASE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_MRVL_RPC) +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_MRVL_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_MRVL_RPC) endif @@ -19,3 +21,4 @@ $(DOCKER_SYNCD_MRVL_RPC)_CONTAINER_NAME = syncd $(DOCKER_SYNCD_MRVL_RPC)_RUN_OPT += --net=host --privileged -t $(DOCKER_SYNCD_MRVL_RPC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_MRVL_RPC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_SYNCD_MRVL_RPC)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/platform/marvell-arm64/docker-syncd-mrvl.mk b/platform/marvell-arm64/docker-syncd-mrvl.mk index 85c1bf108f69..e00769a59700 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl.mk +++ b/platform/marvell-arm64/docker-syncd-mrvl.mk @@ -1,21 +1,13 @@ # docker image for mrvl syncd -DOCKER_SYNCD_MRVL = docker-syncd-mrvl.gz -$(DOCKER_SYNCD_MRVL)_PATH = $(PLATFORM_PATH)/docker-syncd-mrvl -$(DOCKER_SYNCD_MRVL)_DEPENDS += $(SYNCD) $(MRVL_FPA) $(REDIS_TOOLS) -ifeq ($(INSTALL_DEBUG_TOOLS), y) -$(DOCKER_SYNCD_MRVL)_DEPENDS += $(SYNCD_DBG) \ +DOCKER_SYNCD_PLATFORM_CODE = mrvl +include $(PLATFORM_PATH)/../template/docker-syncd-base.mk + +$(DOCKER_SYNCD_BASE)_DEPENDS += $(SYNCD) $(PYTHON_SDK_API) + +$(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSWSSCOMMON_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) -endif -$(DOCKER_SYNCD_MRVL)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) -SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_MRVL) -ifneq ($(ENABLE_SYNCD_RPC),y) -SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_MRVL) -endif -$(DOCKER_SYNCD_MRVL)_CONTAINER_NAME = syncd -$(DOCKER_SYNCD_MRVL)_RUN_OPT += --net=host --privileged -t -$(DOCKER_SYNCD_MRVL)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf -$(DOCKER_SYNCD_MRVL)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 b/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 index 3756afbb70b2..410911e6a4f8 100755 --- a/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 @@ -26,12 +26,13 @@ RUN dpkg -i \ debs/{{ deb }}{{' '}} {%- endfor %} -COPY ["start.sh", "syncd.sh", "/usr/bin/"] +COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs ENTRYPOINT ["/usr/bin/supervisord"] - diff --git a/platform/marvell-arm64/docker-syncd-mrvl/critical_processes b/platform/marvell-arm64/docker-syncd-mrvl/critical_processes new file mode 100644 index 000000000000..6082f242b872 --- /dev/null +++ b/platform/marvell-arm64/docker-syncd-mrvl/critical_processes @@ -0,0 +1 @@ +syncd diff --git a/platform/marvell-arm64/docker-syncd-mrvl/start.sh b/platform/marvell-arm64/docker-syncd-mrvl/start.sh index 96e2a9128081..623316050475 100755 --- a/platform/marvell-arm64/docker-syncd-mrvl/start.sh +++ b/platform/marvell-arm64/docker-syncd-mrvl/start.sh @@ -5,4 +5,3 @@ 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 1e015fef931f..1af5d70a1d0c 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf @@ -26,4 +26,3 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog - diff --git a/platform/marvell-arm64/libsaithrift-dev.mk b/platform/marvell-arm64/libsaithrift-dev.mk index 36a592e694ea..e1c3da156ec2 100644 --- a/platform/marvell-arm64/libsaithrift-dev.mk +++ b/platform/marvell-arm64/libsaithrift-dev.mk @@ -12,7 +12,7 @@ PYTHON_SAITHRIFT = python-saithrift_$(SAI_VER)_$(CONFIGURED_ARCH).deb $(eval $(call add_extra_package,$(LIBSAITHRIFT_DEV),$(PYTHON_SAITHRIFT))) SAISERVER = saiserver_$(SAI_VER)_$(CONFIGURED_ARCH).deb -$(SAISERVER)_RDEPENDS += $(LIBTHRIFT) $(BRCM_SAI) +$(SAISERVER)_RDEPENDS += $(LIBTHRIFT) $(MRVL_SAI) $(eval $(call add_extra_package,$(LIBSAITHRIFT_DEV),$(SAISERVER))) SAISERVER_DBG = saiserver-dbg_$(SAI_VER)_$(CONFIGURED_ARCH).deb diff --git a/platform/marvell-arm64/linux-kernel-arm64.mk b/platform/marvell-arm64/linux-kernel-arm64.mk index 2c9cb3cf08c6..ba7638ad108c 100644 --- a/platform/marvell-arm64/linux-kernel-arm64.mk +++ b/platform/marvell-arm64/linux-kernel-arm64.mk @@ -1,8 +1,10 @@ # linux kernel package for marvell arm64 -KVERSION= 4.4.8 +KVERSION = 4.9.168 -LINUX_KERNEL= linux-image-4.4.8_4.4.8-4_arm64.deb -$(LINUX_KERNEL)_PATH = /sonic -SONIC_COPY_DEBS += $(LINUX_KERNEL) +LINUX_KERNEL = linux-image-4.9.168-arm64.deb +export LINUX_KERNEL + +$(LINUX_KERNEL)_SRC_PATH = $(PLATFORM_PATH)/linux +SONIC_MAKE_DEBS += $(LINUX_KERNEL) diff --git a/platform/marvell-arm64/linux/Makefile b/platform/marvell-arm64/linux/Makefile new file mode 100644 index 000000000000..3b43f181dc71 --- /dev/null +++ b/platform/marvell-arm64/linux/Makefile @@ -0,0 +1,10 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +LINUX_KERNEL_MRVL_URL = https://github.com/Marvell-switching/sonic-marvell-binaries/raw/master/arm64/kernel/$(LINUX_KERNEL) + +$(addprefix $(DEST)/, $(LINUX_KERNEL)): $(DEST)/% : + # get deb package + wget -O $(DEST)/$(LINUX_KERNEL) $(LINUX_KERNEL_MRVL_URL) + diff --git a/platform/marvell-arm64/one-image.mk b/platform/marvell-arm64/one-image.mk index fcac03854348..3a68f54fcdf7 100644 --- a/platform/marvell-arm64/one-image.mk +++ b/platform/marvell-arm64/one-image.mk @@ -1,7 +1,7 @@ # sonic marvell one image installer -SONIC_ONE_IMAGE = sonic-marvell.bin -$(SONIC_ONE_IMAGE)_MACHINE = marvell +SONIC_ONE_IMAGE = sonic-marvell-arm64.bin +$(SONIC_ONE_IMAGE)_MACHINE = marvell-arm64 $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) ifeq ($(INSTALL_DEBUG_TOOLS),y) diff --git a/platform/marvell-arm64/rules.mk b/platform/marvell-arm64/rules.mk index eff1081e17b0..b61a7a87c3c6 100644 --- a/platform/marvell-arm64/rules.mk +++ b/platform/marvell-arm64/rules.mk @@ -2,16 +2,21 @@ include $(PLATFORM_PATH)/sai.mk include $(PLATFORM_PATH)/docker-syncd-mrvl.mk include $(PLATFORM_PATH)/docker-syncd-mrvl-rpc.mk +include $(PLATFORM_PATH)/docker-saiserver-mrvl.mk include $(PLATFORM_PATH)/libsaithrift-dev.mk +include $(PLATFORM_PATH)/docker-ptf-mrvl.mk include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/linux-kernel-arm64.mk +ENABLE_SYSTEM_TELEMETRY = "" +ENABLE_SYNCD_RPC = "" + SONIC_ALL += $(SONIC_ONE_IMAGE) \ - $(DOCKER_FPM) \ - $(DOCKER_SYNCD_MRVL_RPC) + $(DOCKER_FPM) + #$(DOCKER_SYNCD_MRVL_RPC) # Inject mrvl sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(MRVL_FPA) $(MRVL_SAI) $(LIBSAITHRIFT_DEV_MRVL) +$(LIBSAIREDIS)_DEPENDS += $(MRVL_SAI) $(LIBSAITHRIFT_DEV_MRVL) # Runtime dependency on mrvl sai is set only for syncd $(SYNCD)_RDEPENDS += $(MRVL_SAI) diff --git a/platform/marvell-arm64/sai/Makefile b/platform/marvell-arm64/sai/Makefile index 1fad592a79ee..3e990575cb54 100644 --- a/platform/marvell-arm64/sai/Makefile +++ b/platform/marvell-arm64/sai/Makefile @@ -2,7 +2,7 @@ SHELL = /bin/bash .SHELLFLAGS += -e -MRVL_SAI_URL = https://github.com/Marvell-switching/SAI-plugin/raw/$(MRVL_SAI_TAG)/sai_deb/$(MRVL_SAI) +MRVL_SAI_URL = https://github.com/Marvell-switching/sonic-marvell-binaries/raw/master/arm64/sai-plugin/$(MRVL_SAI) $(addprefix $(DEST)/, $(MRVL_SAI)): $(DEST)/% : # get deb package diff --git a/platform/marvell-armhf/docker-syncd-mrvl-rpc.mk b/platform/marvell-armhf/docker-syncd-mrvl-rpc.mk index f5eb6d2de272..0e1b65f2fd5d 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl-rpc.mk +++ b/platform/marvell-armhf/docker-syncd-mrvl-rpc.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_MRVL_RPC = docker-syncd-mrvl-rpc.gz $(DOCKER_SYNCD_MRVL_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mrvl-rpc $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MRVL_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 b/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 index 201d52284361..410911e6a4f8 100755 --- a/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 @@ -28,6 +28,8 @@ debs/{{ deb }}{{' '}} COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y diff --git a/platform/marvell-armhf/docker-syncd-mrvl/critical_processes b/platform/marvell-armhf/docker-syncd-mrvl/critical_processes new file mode 100644 index 000000000000..6082f242b872 --- /dev/null +++ b/platform/marvell-armhf/docker-syncd-mrvl/critical_processes @@ -0,0 +1 @@ +syncd diff --git a/platform/marvell-armhf/linux-kernel-armhf.mk b/platform/marvell-armhf/linux-kernel-armhf.mk index dc5b489635c8..32e8ea3c604a 100644 --- a/platform/marvell-armhf/linux-kernel-armhf.mk +++ b/platform/marvell-armhf/linux-kernel-armhf.mk @@ -1,10 +1,7 @@ # linux kernel package for marvell armhf -KVERSION = 4.9.168 - - -LINUX_KERNEL = linux-image-4.9.168-armhf.deb -export LINUX_KERNEL - -$(LINUX_KERNEL)_SRC_PATH = $(PLATFORM_PATH)/linux -SONIC_MAKE_DEBS += $(LINUX_KERNEL) +# Add platform specific DTB +LINUX_KERNEL_DTB = linux-image-4.9.168-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/linux/Makefile b/platform/marvell-armhf/linux/Makefile index 0a616fa758d9..dba660649abf 100644 --- a/platform/marvell-armhf/linux/Makefile +++ b/platform/marvell-armhf/linux/Makefile @@ -2,9 +2,9 @@ SHELL = /bin/bash .SHELLFLAGS += -e -LINUX_KERNEL_MRVL_URL = https://github.com/Marvell-switching/sonic-marvell-binaries/raw/master/armhf/kernel/$(LINUX_KERNEL) +LINUX_KERNEL_MRVL_URL = https://github.com/Marvell-switching/sonic-marvell-binaries/raw/master/armhf/kernel/$(LINUX_KERNEL_DTB) -$(addprefix $(DEST)/, $(LINUX_KERNEL)): $(DEST)/% : +$(addprefix $(DEST)/, $(LINUX_KERNEL_DTB)): $(DEST)/% : # get deb package - wget -O $(DEST)/$(LINUX_KERNEL) $(LINUX_KERNEL_MRVL_URL) + wget -O $(DEST)/$(LINUX_KERNEL_DTB) $(LINUX_KERNEL_MRVL_URL) diff --git a/platform/marvell-armhf/one-image.mk b/platform/marvell-armhf/one-image.mk index fcac03854348..bed895d84d86 100644 --- a/platform/marvell-armhf/one-image.mk +++ b/platform/marvell-armhf/one-image.mk @@ -1,9 +1,10 @@ # sonic marvell one image installer -SONIC_ONE_IMAGE = sonic-marvell.bin -$(SONIC_ONE_IMAGE)_MACHINE = marvell +SONIC_ONE_IMAGE = sonic-marvell-armhf.bin +$(SONIC_ONE_IMAGE)_MACHINE = marvell-armhf $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) +$(SONIC_ONE_IMAGE)_INSTALLS += $(LINUX_KERNEL_DTB) ifeq ($(INSTALL_DEBUG_TOOLS),y) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) diff --git a/platform/marvell-armhf/platform.conf b/platform/marvell-armhf/platform.conf index e69de29bb2d1..e574a8d1a0cd 100644 --- a/platform/marvell-armhf/platform.conf +++ b/platform/marvell-armhf/platform.conf @@ -0,0 +1,143 @@ +# Copyright (C) Marvell Inc + +# over ride default behaviour + +echo "Preparing for installation ... " + +# global defines +kernel_addr=0x1100000 +fdt_addr=0x1000000 + +image_name="/vmlinuz" +fdt_name="/boot/armada-385-ET6448M_4G_Nand.dtb" + +# global mount defines +demo_dev=ubi0 +mtd_dev=/dev/$(cat /proc/mtd | grep "SONIC" | grep -o "mtd[0-9]") +mtd_num=$(echo $mtd_dev | grep -o "[0-9]") +demo_mount=/tmp +FW_ENV='/dev/mtd0 \t\t 0x00500000 \t 0x80000 \t 0x100000 \t 8' + +BOOTARGS='setenv bootargs root='$demo_dev' rw rootwait ubi.mtd='$mtd_num' rootfstype=ubifs panic=1 console=ttyS0,115200 ${othbootargs} ${mtdparts}' +UBI_LOAD='run ubi_sonic_boot_mount_ubi; ubifsload $kernel_addr $image_name;ubifsload $fdt_addr $fdt_name' +UBIBOOTCMD='run ubi_sonic_boot_bootargs; run ubi_sonic_boot_load; bootz $kernel_addr - $fdt_addr' + +et6448m_machine_conf() { + SYSCTL_CFG=$demo_mount/usr/share/sonic/device/armhf-marvell_et6448m_52x-r0/syncd.conf + + echo "Configure platform et6448m " + rm $demo_mount/lib/udev/rules.d/73-usb-net-by-mac.rules + rm -f $demo_mount/usr/bin/reboot || true + rm -fr $demo_mount/host/machine.conf + cp /etc/machine.conf $demo_mount/host/ + + SONIC_VERSION=$(cat $demo_mount/etc/sonic/sonic_version.yml | grep build_version | cut -f2 -d"'") + FIRST_BOOT_FILE="$demo_mount/host/image-$SONIC_VERSION/platform" + mkdir -p $FIRST_BOOT_FILE + touch $FIRST_BOOT_FILE/firsttime + + MAC_ADDR=$(fw_printenv | grep ^ethaddr= | cut -f2 -d"=") + sed -i "s/switchMacAddress=.*/switchMacAddress=$MAC_ADDR/g" $demo_mount/usr/share/sonic/device/armhf-marvell_et6448m_52x-r0/et6448m/profile.ini + + # IPv4 and IPv6 arp cache limits + echo "sysctl -w net.ipv4.neigh.default.gc_thresh1=16000" >> $SYSCTL_CFG + echo "sysctl -w net.ipv4.neigh.default.gc_thresh2=32000" >> $SYSCTL_CFG + echo "sysctl -w net.ipv4.neigh.default.gc_thresh3=48000" >> $SYSCTL_CFG + echo "sysctl -w net.ipv6.neigh.default.gc_thresh1=8000 " >> $SYSCTL_CFG + echo "sysctl -w net.ipv6.neigh.default.gc_thresh2=16000" >> $SYSCTL_CFG + echo "sysctl -w net.ipv6.neigh.default.gc_thresh3=32000" >> $SYSCTL_CFG +} + +prepare_uboot() { + echo "Setting up U-Boot environment..." + + echo -e $FW_ENV > /etc/fw_env.config + + fw_setenv -f image_name $image_name > /dev/null + fw_setenv -f fdt_name $fdt_name > /dev/null + fw_setenv -f kernel_addr $kernel_addr > /dev/null + fw_setenv -f fdt_addr $fdt_addr > /dev/null + + #make sure ubi number (0) and ubi volume name (ubi0) are set correctly in bootargs_root: + #For example, the below command creates an 3000MiB volume on UBI device 0: + #setenv bootargs_root root=ubi0:ubi0 rw ubi.mtd=2 rootfstype=ubifs + + fw_setenv -f mtdids 'nand0=armada-nand' > /dev/null + fw_setenv -f mtdparts 'mtdparts=armada-nand:10m(U-Boot)ro,20m@10m(ONIE),-(SONIC)' > /dev/null + fw_setenv -f ubi_sonic_boot_mount_ubi 'ubi part SONIC; ubifsmount ubi0' > /dev/null + + fw_setenv -f ubi_sonic_boot_bootargs $BOOTARGS > /dev/null + fw_setenv -f ubi_sonic_boot_load $UBI_LOAD > /dev/null + fw_setenv -f ubi_sonic_boot $UBIBOOTCMD > /dev/null + fw_setenv -f bootcmd 'usb start; run ubi_sonic_boot' > /dev/null + +} + +install_uimage() { + + ubidetach /dev/ubi_ctrl -m $mtd_num 2>/dev/null || true + + echo -en "Format mtd partition '$mtd_dev' " + ubiformat $mtd_dev -y -q || { + echo "Failed" + } + + #attaches MTD devices (which describe raw flash) to UBI and creates corresponding UBI devices; ('-m 2' --> mtd2) + echo -en "ubiattach mtd '$mtd_num' " + ubiattach /dev/ubi_ctrl -m $mtd_num || { + echo "Failed" + } + + #creates UBI volumes on UBI devices + ubimkvol /dev/$demo_dev -N $demo_dev -s 3900MiB + + demo_mount=$(mktemp -d) || { + echo "Error: Unable to create file sstem mount point" + exit 1 + } + + echo "Mounting $demo_dev on $demo_mount " + mount -t ubifs /dev/ubi0_0 $demo_mount || { + echo "Failed" + } + + echo "Extracting NOS " + + # Decompress the file for the file system directly to the partition + unzip -o $ONIE_INSTALLER_PAYLOAD -x "$FILESYSTEM_DOCKERFS" -d $demo_mount/ + cd $demo_mount + + if [ -f fs.cpio ]; then + cpio -id < fs.cpio + if [ $? -ne 0 ]; then + echo "cpio extraction Failed" + fi + rm fs.cpio + elif [ -f fs.squashfs ]; then + unsquashfs -f -d $demo_mount $FILESYSTEM_SQUASHFS + if [ $? -ne 0 ]; then + echo "unsquashfs extraction Failed" + fi + rm -f $FILESYSTEM_SQUASHFS + fi + + cd - + TAR_EXTRA_OPTION="--numeric-owner" + mkdir -p $demo_mount/var/lib/$DOCKERFS_DIR + unzip -op $ONIE_INSTALLER_PAYLOAD "$FILESYSTEM_DOCKERFS" | tar -xpz $TAR_EXTRA_OPTION -f - -C $demo_mount/var/lib/$DOCKERFS_DIR + + # Update uboot Environment + prepare_uboot + + # Platform configuration + et6448m_machine_conf + + # Unmounting mount path + umount $demo_mount + + echo "Reboot board to boot from installed OS" +} + +hw_load() { + echo "mtdpart default && ubi part SONIC && ubifsmount 'demo_dev' && ubifsload '$kernel_addr' 'image_name'" +} diff --git a/platform/marvell/docker-syncd-mrvl-rpc.mk b/platform/marvell/docker-syncd-mrvl-rpc.mk index 375c6ba91cd1..5b1968bde39c 100644 --- a/platform/marvell/docker-syncd-mrvl-rpc.mk +++ b/platform/marvell/docker-syncd-mrvl-rpc.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_MRVL_RPC = docker-syncd-mrvl-rpc.gz $(DOCKER_SYNCD_MRVL_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mrvl-rpc $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MRVL_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/marvell/docker-syncd-mrvl.mk b/platform/marvell/docker-syncd-mrvl.mk index 85c1bf108f69..5257bf5e68e7 100644 --- a/platform/marvell/docker-syncd-mrvl.mk +++ b/platform/marvell/docker-syncd-mrvl.mk @@ -1,21 +1,14 @@ # docker image for mrvl syncd -DOCKER_SYNCD_MRVL = docker-syncd-mrvl.gz -$(DOCKER_SYNCD_MRVL)_PATH = $(PLATFORM_PATH)/docker-syncd-mrvl -$(DOCKER_SYNCD_MRVL)_DEPENDS += $(SYNCD) $(MRVL_FPA) $(REDIS_TOOLS) -ifeq ($(INSTALL_DEBUG_TOOLS), y) -$(DOCKER_SYNCD_MRVL)_DEPENDS += $(SYNCD_DBG) \ +DOCKER_SYNCD_PLATFORM_CODE = mrvl +include $(PLATFORM_PATH)/../template/docker-syncd-base.mk + +$(DOCKER_SYNCD_BASE)_DEPENDS += $(SYNCD) + +$(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSWSSCOMMON_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) -endif -$(DOCKER_SYNCD_MRVL)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) -SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_MRVL) -ifneq ($(ENABLE_SYNCD_RPC),y) -SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_MRVL) -endif -$(DOCKER_SYNCD_MRVL)_CONTAINER_NAME = syncd -$(DOCKER_SYNCD_MRVL)_RUN_OPT += --net=host --privileged -t -$(DOCKER_SYNCD_MRVL)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf -$(DOCKER_SYNCD_MRVL)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(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/marvell/docker-syncd-mrvl/Dockerfile.j2 b/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 index 5017b305f151..40973653e8d3 100755 --- a/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell/docker-syncd-mrvl/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 @@ -23,6 +23,8 @@ debs/{{ deb }}{{' '}} COPY ["start.sh", "syncd.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y diff --git a/platform/marvell/docker-syncd-mrvl/critical_processes b/platform/marvell/docker-syncd-mrvl/critical_processes new file mode 100644 index 000000000000..6082f242b872 --- /dev/null +++ b/platform/marvell/docker-syncd-mrvl/critical_processes @@ -0,0 +1 @@ +syncd diff --git a/platform/marvell/docker-syncd-mrvl/supervisord.conf b/platform/marvell/docker-syncd-mrvl/supervisord.conf index 1e015fef931f..aea4d45b9afd 100644 --- a/platform/marvell/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell/docker-syncd-mrvl/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/platform/marvell/rules.mk b/platform/marvell/rules.mk index 93fe18eef86d..d819cfb67dae 100644 --- a/platform/marvell/rules.mk +++ b/platform/marvell/rules.mk @@ -1,4 +1,3 @@ -include $(PLATFORM_PATH)/sdk.mk include $(PLATFORM_PATH)/sai.mk include $(PLATFORM_PATH)/docker-syncd-mrvl.mk include $(PLATFORM_PATH)/docker-syncd-mrvl-rpc.mk diff --git a/platform/marvell/sai.mk b/platform/marvell/sai.mk index 5016b47f19a9..7953ad5dd82f 100644 --- a/platform/marvell/sai.mk +++ b/platform/marvell/sai.mk @@ -1,9 +1,6 @@ # Marvell SAI -export MRVL_SAI_VERSION = 1.2.1 -export MRVL_SAI_TAG = SONiC.201803 -export MRVL_SAI = mrvllibsai_$(MRVL_SAI_VERSION).deb +export MRVL_SAI = mrvllibsai_amd64_1.4.1.deb $(MRVL_SAI)_SRC_PATH = $(PLATFORM_PATH)/sai -$(MRVL_SAI)_DEPENDS += $(MRVL_FPA) SONIC_MAKE_DEBS += $(MRVL_SAI) diff --git a/platform/marvell/sai/Makefile b/platform/marvell/sai/Makefile index 1fad592a79ee..1cd6d0267fa2 100644 --- a/platform/marvell/sai/Makefile +++ b/platform/marvell/sai/Makefile @@ -2,7 +2,7 @@ SHELL = /bin/bash .SHELLFLAGS += -e -MRVL_SAI_URL = https://github.com/Marvell-switching/SAI-plugin/raw/$(MRVL_SAI_TAG)/sai_deb/$(MRVL_SAI) +MRVL_SAI_URL = https://github.com/Marvell-switching/sonic-marvell-binaries/raw/master/amd64/sai-plugin/$(MRVL_SAI) $(addprefix $(DEST)/, $(MRVL_SAI)): $(DEST)/% : # get deb package diff --git a/platform/marvell/sdk.mk b/platform/marvell/sdk.mk deleted file mode 100644 index 3d1ce8e04c88..000000000000 --- a/platform/marvell/sdk.mk +++ /dev/null @@ -1,8 +0,0 @@ -# Marvell FPA - -export MRVL_FPA_VERSION = 1.2.1 -export MRVL_FPA_TAG = SONiC.201803 -export MRVL_FPA = mrvllibfpa_$(MRVL_FPA_VERSION).deb - -$(MRVL_FPA)_SRC_PATH = $(PLATFORM_PATH)/sdk -SONIC_MAKE_DEBS += $(MRVL_FPA) diff --git a/platform/marvell/sdk/Makefile b/platform/marvell/sdk/Makefile deleted file mode 100644 index 6822c7d7d274..000000000000 --- a/platform/marvell/sdk/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -.ONESHELL: -SHELL = /bin/bash -.SHELLFLAGS += -e - -MRVL_FPA_URL = https://github.com/Marvell-switching/SAI-plugin/raw/$(MRVL_FPA_TAG)/sdk_deb/$(MRVL_FPA) - -$(addprefix $(DEST)/, $(MRVL_FPA)): $(DEST)/% : - # get deb package - wget -O $(DEST)/$(MRVL_FPA) $(MRVL_FPA_URL) diff --git a/platform/mellanox/.gitignore b/platform/mellanox/.gitignore index 74751518db24..1f3d15d640d4 100644 --- a/platform/mellanox/.gitignore +++ b/platform/mellanox/.gitignore @@ -8,6 +8,7 @@ mft/* !mft/Makefile sdk-src/*/* !sdk-src/*/Makefile +!sdk-src/sx-kernel/Switch-SDK-drivers/ !sdk-src/*/*.patch */build */deb_dist diff --git a/platform/mellanox/docker-syncd-mlnx-rpc.mk b/platform/mellanox/docker-syncd-mlnx-rpc.mk index f154f8c28d2e..608c1bb3ad20 100644 --- a/platform/mellanox/docker-syncd-mlnx-rpc.mk +++ b/platform/mellanox/docker-syncd-mlnx-rpc.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_MLNX_RPC = docker-syncd-mlnx-rpc.gz $(DOCKER_SYNCD_MLNX_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mlnx-rpc $(DOCKER_SYNCD_MLNX_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MLNX_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_MLNX_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/mellanox/docker-syncd-mlnx.mk b/platform/mellanox/docker-syncd-mlnx.mk index b46c6478cf0e..db582e517bff 100644 --- a/platform/mellanox/docker-syncd-mlnx.mk +++ b/platform/mellanox/docker-syncd-mlnx.mk @@ -4,7 +4,6 @@ DOCKER_SYNCD_PLATFORM_CODE = mlnx include $(PLATFORM_PATH)/../template/docker-syncd-base.mk $(DOCKER_SYNCD_BASE)_DEPENDS += $(SYNCD) $(PYTHON_SDK_API) -$(DOCKER_SYNCD_BASE)_PYTHON_DEBS += $(MLNX_SFPD) $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 index d3716dffcbbc..4d22335ec783 100755 --- a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 +++ b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 @@ -35,5 +35,7 @@ RUN apt-get clean -y && \ COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/platform/mellanox/docker-syncd-mlnx/critical_processes b/platform/mellanox/docker-syncd-mlnx/critical_processes new file mode 100644 index 000000000000..6082f242b872 --- /dev/null +++ b/platform/mellanox/docker-syncd-mlnx/critical_processes @@ -0,0 +1 @@ +syncd diff --git a/platform/mellanox/docker-syncd-mlnx/start.sh b/platform/mellanox/docker-syncd-mlnx/start.sh index 61ccd2db8933..96e2a9128081 100755 --- a/platform/mellanox/docker-syncd-mlnx/start.sh +++ b/platform/mellanox/docker-syncd-mlnx/start.sh @@ -6,5 +6,3 @@ supervisorctl start rsyslogd supervisorctl start syncd -supervisorctl start mlnx-sfpd - diff --git a/platform/mellanox/docker-syncd-mlnx/supervisord.conf b/platform/mellanox/docker-syncd-mlnx/supervisord.conf index 8860bd6c0205..c823ab5680ef 100644 --- a/platform/mellanox/docker-syncd-mlnx/supervisord.conf +++ b/platform/mellanox/docker-syncd-mlnx/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog @@ -26,11 +32,3 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog - -[program:mlnx-sfpd] -command=/usr/bin/mlnx-sfpd -priority=4 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index f6b2a86a7b3e..9d506c1f5bdd 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -1,16 +1,31 @@ # mellanox firmware -MLNX_FW_BASE_URL = $(MLNX_SDK_BASE_URL) +MLNX_FW_BASE_PATH = $(MLNX_SDK_BASE_PATH) -MLNX_SPC_FW_VERSION = 13.2000.1634 +# Place an URL here to FW if you want to download FW instead +MLNX_FW_BASE_URL = + +ifneq ($(MLNX_FW_BASE_URL), ) +FW_FROM_URL = y +else +FW_FROM_URL = n +endif + +MLNX_SPC_FW_VERSION = 13.2000.2602 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) -SONIC_ONLINE_FILES += $(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2000.1634 +MLNX_SPC2_FW_VERSION = 29.2000.2602 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) -SONIC_ONLINE_FILES += $(MLNX_SPC2_FW_FILE) + +ifeq ($(FW_FROM_URL),n) +SONIC_COPY_FILES += $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) +else +SONIC_ONLINE_FILES += $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) +endif export MLNX_SPC_FW_VERSION export MLNX_SPC_FW_FILE diff --git a/platform/mellanox/hw-management.mk b/platform/mellanox/hw-management.mk index 91af460c8ded..f41c2b9a25ce 100644 --- a/platform/mellanox/hw-management.mk +++ b/platform/mellanox/hw-management.mk @@ -1,6 +1,6 @@ # Mellanox HW Management -MLNX_HW_MANAGEMENT_VERSION = 2.0.0183 +MLNX_HW_MANAGEMENT_VERSION = 7.0000.2303 export MLNX_HW_MANAGEMENT_VERSION diff --git a/platform/mellanox/hw-management/hw-mgmt b/platform/mellanox/hw-management/hw-mgmt index a9ef3e5acf9a..7c26a8f6a520 160000 --- a/platform/mellanox/hw-management/hw-mgmt +++ b/platform/mellanox/hw-management/hw-mgmt @@ -1 +1 @@ -Subproject commit a9ef3e5acf9a2bc4fb4de1f80a53ca2bf3c68a66 +Subproject commit 7c26a8f6a520b06663992afe874bc56b1fcd9311 diff --git a/platform/mellanox/mlnx-platform-api.mk b/platform/mellanox/mlnx-platform-api.mk index 98a57d0090ed..4b70e59debc1 100644 --- a/platform/mellanox/mlnx-platform-api.mk +++ b/platform/mellanox/mlnx-platform-api.mk @@ -5,3 +5,4 @@ $(SONIC_PLATFORM_API_PY2)_SRC_PATH = $(PLATFORM_PATH)/mlnx-platform-api $(SONIC_PLATFORM_API_PY2)_PYTHON_VERSION = 2 SONIC_PYTHON_WHEELS += $(SONIC_PLATFORM_API_PY2) +export mlnx_platform_api_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2))" diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/__init__.py b/platform/mellanox/mlnx-platform-api/sonic_platform/__init__.py index e69de29bb2d1..d94d4c9ec820 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/__init__.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["platform", "chassis"] +from sonic_platform import * \ No newline at end of file diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 41d237143d58..44ef8981281f 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -10,15 +10,8 @@ try: from sonic_platform_base.chassis_base import ChassisBase - from sonic_platform.psu import Psu - from sonic_platform.fan import Fan - from sonic_platform.fan import FAN_PATH - from sonic_platform.sfp import SFP - from sonic_platform.thermal import Thermal, initialize_thermals - from sonic_platform.watchdog import get_watchdog + from sonic_platform_base.component_base import ComponentBase from sonic_daemon_base.daemon_base import Logger - from eeprom import Eeprom - from sfp_event import sfp_event from os import listdir from os.path import isfile, join import sys @@ -43,37 +36,15 @@ #reboot cause related definitions REBOOT_CAUSE_ROOT = HWMGMT_SYSTEM_ROOT -REBOOT_CAUSE_POWER_LOSS_FILE = 'reset_main_pwr_fail' -REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC_FILE = 'reset_asic_thermal' -REBOOT_CAUSE_WATCHDOG_FILE = 'reset_hotswap_or_wd' -REBOOT_CAUSE_MLNX_FIRMWARE_RESET = 'reset_fw_reset' - REBOOT_CAUSE_FILE_LENGTH = 1 -#version retrieving related definitions -CPLD_VERSION_ROOT = HWMGMT_SYSTEM_ROOT - -CPLD1_VERSION_FILE = 'cpld1_version' -CPLD2_VERSION_FILE = 'cpld2_version' -CPLD_VERSION_MAX_LENGTH = 4 - -FW_QUERY_VERSION_COMMAND = 'mlxfwmanager --query' -BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' - -#components definitions -COMPONENT_BIOS = "BIOS" -COMPONENT_FIRMWARE = "ASIC-FIRMWARE" -COMPONENT_CPLD1 = "CPLD1" -COMPONENT_CPLD2 = "CPLD2" - # Global logger class instance -SYSLOG_IDENTIFIER = "mlnx-chassis-api" -logger = Logger(SYSLOG_IDENTIFIER) +logger = Logger() # magic code defnition for port number, qsfp port position of each hwsku # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict_port = {'ACS-MSN2700': 0, "LS-SN2700":0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 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)] +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} +port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1)] class Chassis(ChassisBase): """Platform-specific Chassis class""" @@ -84,14 +55,33 @@ def __init__(self): # Initialize SKU name self.sku_name = self._get_sku_name() + # move the initialization of each components to their dedicated initializer + # which will be called from platform + self.sfp_module_initialized = False + self.sfp_event_initialized = False + self.reboot_cause_initialized = False + logger.log_info("Chassis loaded successfully") + + + def __del__(self): + if self.sfp_event_initialized: + self.sfp_event.deinitialize() + + + def initialize_psu(self): + from sonic_platform.psu import Psu # Initialize PSU list + self.psu_module = Psu for index in range(MLNX_NUM_PSU): psu = Psu(index, self.sku_name) self._psu_list.append(psu) - # Initialize watchdog - self._watchdog = get_watchdog() + def initialize_fan(self): + 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() @@ -104,6 +94,12 @@ def __init__(self): fan = Fan(index, index) self._fan_list.append(fan) + + def initialize_sfp(self): + from sonic_platform.sfp import SFP + + self.sfp_module = SFP + # Initialize SFP list port_position_tuple = self._get_port_position_tuple_by_sku_name() self.PORT_START = port_position_tuple[0] @@ -118,31 +114,88 @@ def __init__(self): sfp_module = SFP(index, 'SFP') self._sfp_list.append(sfp_module) + self.sfp_module_initialized = True + + + def initialize_thermals(self): + from sonic_platform.thermal import initialize_thermals # Initialize thermals initialize_thermals(self.sku_name, self._thermal_list, self._psu_list) + + def initialize_eeprom(self): + from eeprom import Eeprom # Initialize EEPROM - self.eeprom = Eeprom() + self._eeprom = Eeprom() + + def initialize_components(self): # Initialize component list - self._component_name_list.append(COMPONENT_BIOS) - self._component_name_list.append(COMPONENT_FIRMWARE) - self._component_name_list.append(COMPONENT_CPLD1) - self._component_name_list.append(COMPONENT_CPLD2) + from sonic_platform.component import ComponentBIOS, ComponentCPLD + self._component_list.append(ComponentBIOS()) + self._component_list.append(ComponentCPLD()) + + + ############################################## + # 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 (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 + """ + if not self.sfp_module_initialized: + self.initialize_sfp() + + sfp = None - # Initialize sfp-change-listening stuff - self._init_sfp_change_event() + try: + sfp = self._sfp_list[index] + except IndexError: + sys.stderr.write("SFP index {} out of range (0-{})\n".format( + index, len(self._sfp_list)-1)) + + return sfp - def _init_sfp_change_event(self): - self.sfp_event = sfp_event() - self.sfp_event.initialize() - self.MAX_SELECT_EVENT_RETURNED = self.PORT_END def _extract_num_of_fans_and_fan_drawers(self): num_of_fan = 0 num_of_drawer = 0 - for f in listdir(FAN_PATH): - if isfile(join(FAN_PATH, f)): + for f in listdir(self.fan_path): + if isfile(join(self.fan_path, f)): match_obj = re.match('fan(\d+)_speed_get', f) if match_obj != None: if int(match_obj.group(1)) > num_of_fan: @@ -154,15 +207,43 @@ def _extract_num_of_fans_and_fan_drawers(self): return num_of_fan, num_of_drawer + def _get_sku_name(self): p = subprocess.Popen(GET_HWSKU_CMD, shell=True, stdout=subprocess.PIPE) out, err = p.communicate() return out.rstrip('\n') + def _get_port_position_tuple_by_sku_name(self): position_tuple = port_position_tuple_list[hwsku_dict_port[self.sku_name]] return position_tuple + + def get_watchdog(self): + """ + Retrieves hardware watchdog device on this chassis + + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + + Note: + We overload this method to ensure that watchdog is only initialized + when it is referenced. Currently, only one daemon can open the watchdog. + To initialize watchdog in the constructor causes multiple daemon + try opening watchdog when loading and constructing a chassis object + and fail. By doing so we can eliminate that risk. + """ + try: + if self._watchdog is None: + from sonic_platform.watchdog import get_watchdog + self._watchdog = get_watchdog() + except Exception as e: + logger.log_info("Fail to load watchdog due to {}".format(repr(e))) + + return self._watchdog + + def get_base_mac(self): """ Retrieves the base MAC address for the chassis @@ -171,7 +252,8 @@ def get_base_mac(self): A string containing the MAC address in the format 'XX:XX:XX:XX:XX:XX' """ - return self.eeprom.get_base_mac() + return self._eeprom.get_base_mac() + def get_serial_number(self): """ @@ -180,7 +262,8 @@ def get_serial_number(self): Returns: A string containing the hardware serial number for this chassis. """ - return self.eeprom.get_serial_number() + return self._eeprom.get_serial_number() + def get_system_eeprom_info(self): """ @@ -191,7 +274,8 @@ def get_system_eeprom_info(self): OCP ONIE TlvInfo EEPROM format and values are their corresponding values. """ - return self.eeprom.get_system_eeprom_info() + return self._eeprom.get_system_eeprom_info() + def _read_generic_file(self, filename, len): """ @@ -205,7 +289,8 @@ def _read_generic_file(self, filename, len): return result except Exception as e: logger.log_info("Fail to read file {} due to {}".format(filename, repr(e))) - return '' + return '0' + def _verify_reboot_cause(self, filename): ''' @@ -215,6 +300,33 @@ def _verify_reboot_cause(self, filename): ''' return bool(int(self._read_generic_file(join(REBOOT_CAUSE_ROOT, filename), REBOOT_CAUSE_FILE_LENGTH).rstrip('\n'))) + + def initialize_reboot_cause(self): + self.reboot_major_cause_dict = { + 'reset_main_pwr_fail' : self.REBOOT_CAUSE_POWER_LOSS, + 'reset_aux_pwr_or_ref' : self.REBOOT_CAUSE_POWER_LOSS, + 'reset_asic_thermal' : self.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC, + 'reset_hotswap_or_wd' : self.REBOOT_CAUSE_WATCHDOG, + 'reset_swb_wd' : self.REBOOT_CAUSE_WATCHDOG, + 'reset_sff_wd' : self.REBOOT_CAUSE_WATCHDOG + } + self.reboot_minor_cause_dict = { + 'reset_fw_reset' : "Reset by ASIC firmware", + 'reset_long_pb' : "Reset by long press on power button", + 'reset_short_pb' : "Reset by short press on power button", + 'reset_comex_thermal' : "ComEx thermal shutdown", + 'reset_comex_pwr_fail' : "ComEx power fail", + 'reset_comex_wd' : "Reset requested from ComEx", + 'reset_from_asic' : "Reset requested from ASIC", + 'reset_reload_bios' : "Reset caused by BIOS reload", + 'reset_hotswap_or_halt' : "Reset caused by hotswap or halt", + 'reset_from_comex' : "Reset from ComEx", + 'reset_voltmon_upgrade_fail': "Reset due to voltage monitor devices upgrade failure" + } + self.reboot_by_software = 'reset_sw_reset' + self.reboot_cause_initialized = True + + def get_reboot_cause(self): """ Retrieves the cause of the previous reboot @@ -227,117 +339,24 @@ def get_reboot_cause(self): to pass a description of the reboot cause. """ #read reboot causes files in the following order - minor_cause = '' - if self._verify_reboot_cause(REBOOT_CAUSE_POWER_LOSS_FILE): - major_cause = self.REBOOT_CAUSE_POWER_LOSS - elif self._verify_reboot_cause(REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC_FILE): - major_cause = self.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC - elif self._verify_reboot_cause(REBOOT_CAUSE_WATCHDOG_FILE): - major_cause = self.REBOOT_CAUSE_WATCHDOG - else: - major_cause = self.REBOOT_CAUSE_HARDWARE_OTHER - if self._verify_reboot_cause(REBOOT_CAUSE_MLNX_FIRMWARE_RESET): - minor_cause = "Reset by ASIC firmware" - else: - major_cause = self.REBOOT_CAUSE_NON_HARDWARE + if not self.reboot_cause_initialized: + self.initialize_reboot_cause() - return major_cause, minor_cause + for reset_file, reset_cause in self.reboot_major_cause_dict.iteritems(): + if self._verify_reboot_cause(reset_file): + return reset_cause, '' - def _get_cpld_version(self, version_file): - cpld_version = self._read_generic_file(join(CPLD_VERSION_ROOT, version_file), CPLD_VERSION_MAX_LENGTH) - return cpld_version.rstrip('\n') + for reset_file, reset_cause in self.reboot_minor_cause_dict.iteritems(): + if self._verify_reboot_cause(reset_file): + return self.REBOOT_CAUSE_HARDWARE_OTHER, reset_cause - def _get_command_result(self, cmdline): - try: - proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) - stdout = proc.communicate()[0] - proc.wait() - result = stdout.rstrip('\n') - - except OSError, e: - result = '' - - return result - - def _get_firmware_version(self): - """ - firmware version is retrieved via command 'mlxfwmanager --query' - which should return result in the following convention - admin@mtbc-sonic-01-2410:~$ sudo mlxfwmanager --query - Querying Mellanox devices firmware ... - - Device #1: - ---------- - - Device Type: Spectrum - Part Number: MSN2410-CxxxO_Ax_Bx - Description: Spectrum based 25GbE/100GbE 1U Open Ethernet switch with ONIE; 48 SFP28 ports; 8 QSFP28 ports; x86 dual core; RoHS6 - PSID: MT_2860111033 - PCI Device Name: /dev/mst/mt52100_pci_cr0 - Base MAC: 98039bf3f500 - Versions: Current Available - FW ***13.2000.1140***N/A - - Status: No matching image found - - By using regular expression '(Versions:.*\n[\s]+FW[\s]+)([\S]+)', - we can extrace the version which is marked with *** in the above context - """ - fw_ver_str = self._get_command_result(FW_QUERY_VERSION_COMMAND) - try: - m = re.search('(Versions:.*\n[\s]+FW[\s]+)([\S]+)', fw_ver_str) - result = m.group(2) - except : - result = '' - - return result - - def _get_bios_version(self): - """ - 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. - - Handle 0x0022, DMI type 11, 5 bytes - OEM Strings - String 1:*0ABZS017_02.02.002* - String 2: To Be Filled By O.E.M. - - By using regular expression 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' - we can extrace the version string which is marked with * in the above context - """ - bios_ver_str = self._get_command_result(BIOS_QUERY_VERSION_COMMAND) - try: - m = re.search('OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)', bios_ver_str) - result = m.group(1) - except: - result = '' + if self._verify_reboot_cause(self.reboot_by_software): + logger.log_info("Hardware reboot cause: the system was rebooted due to software requesting") + else: + logger.log_info("Hardware reboot cause: no hardware reboot cause found") - return result + return self.REBOOT_CAUSE_NON_HARDWARE, '' - def get_firmware_version(self, component_name): - """ - Retrieves platform-specific hardware/firmware versions for chassis - componenets such as BIOS, CPLD, FPGA, etc. - Args: - component_name: A string, the component name. - - Returns: - A string containing platform-specific component versions - """ - if component_name in self._component_name_list : - if component_name == COMPONENT_BIOS: - return self._get_bios_version() - elif component_name == COMPONENT_CPLD1: - return self._get_cpld_version(CPLD1_VERSION_FILE) - elif component_name == COMPONENT_CPLD2: - return self._get_cpld_version(CPLD2_VERSION_FILE) - elif component_name == COMPONENT_FIRMWARE: - return self._get_firmware_version() - - return None def _show_capabilities(self): """ @@ -360,6 +379,7 @@ def _show_capabilities(self): except: print "fail to retrieve capabilities for module index {}".format(s.index) + def get_change_event(self, timeout=0): """ Returns a nested dictionary containing all devices which have @@ -383,6 +403,14 @@ def get_change_event(self, timeout=0): indicates that fan 0 has been removed, fan 2 has been inserted and sfp 11 has been removed. """ + # Initialize SFP event first + if not self.sfp_event_initialized: + from sonic_platform.sfp_event import sfp_event + self.sfp_event = sfp_event() + self.sfp_event.initialize() + self.MAX_SELECT_EVENT_RETURNED = self.PORT_END + self.sfp_event_initialized = True + wait_for_ever = (timeout == 0) port_dict = {} if wait_for_ever: @@ -410,4 +438,4 @@ def get_change_event(self, timeout=0): i = i + 1 return True, {'sfp':port_dict} else: - return True, {} + 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 new file mode 100644 index 000000000000..fd593f7bbe45 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python + +############################################################################# +# Mellanox +# +# implementation of new platform api +############################################################################# + +try: + from sonic_platform_base.component_base import ComponentBase + from glob import glob + import subprocess + import io + import re +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +#components definitions +COMPONENT_BIOS = "BIOS" +COMPONENT_CPLD = "CPLD" + +BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' +CPLD_VERSION_FILE_PATTERN = '/var/run/hw-management/system/cpld[0-9]_version' +CPLD_VERSION_MAX_LENGTH = 4 + +class Component(ComponentBase): + def get_name(self): + """ + Retrieves the name of the component + + Returns: + A string containing the name of the component + """ + return self.name + + + def _read_generic_file(self, filename, len): + """ + Read a generic file, returns the contents of the file + """ + result = '' + try: + with io.open(filename, 'r') as fileobj: + result = fileobj.read(len) + return result + except IOError as e: + raise RuntimeError("Failed to read file {} due to {}".format(filename, repr(e))) + + + def _get_command_result(self, cmdline): + try: + proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + result = stdout.rstrip('\n') + + except OSError as e: + raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) + + return result + + +class ComponentBIOS(Component): + BIOS_VERSION_PARSE_PATTERN = 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' + + + def __init__(self): + self.name = COMPONENT_BIOS + + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + return "BIOS - Basic Input/Output System" + + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + + 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. + + Handle 0x0022, DMI type 11, 5 bytes + OEM Strings + String 1:*0ABZS017_02.02.002* + String 2: To Be Filled By O.E.M. + + By using regular expression 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' + we can extrace the version string which is marked with * in the above context + """ + bios_ver_str = self._get_command_result(BIOS_QUERY_VERSION_COMMAND) + try: + m = re.search(self.BIOS_VERSION_PARSE_PATTERN, bios_ver_str) + result = m.group(1) + except AttributeError as e: + raise RuntimeError("Failed to parse BIOS version by {} from {} due to {}".format( + self.BIOS_VERSION_PARSE_PATTERN, bios_ver_str, repr(e))) + + return result + + +class ComponentCPLD(Component): + def __init__(self): + self.name = COMPONENT_CPLD + + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + return "CPLD - includes all CPLDs in the switch" + + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + cpld_version_file_list = glob(CPLD_VERSION_FILE_PATTERN) + cpld_version = '' + if cpld_version_file_list is not None and cpld_version_file_list: + cpld_version_file_list.sort() + for version_file in cpld_version_file_list: + version = self._read_generic_file(version_file, CPLD_VERSION_MAX_LENGTH) + if not cpld_version == '': + cpld_version += '.' + cpld_version += version.rstrip('\n') + else: + raise RuntimeError("Failed to get CPLD version files by matching {}".format(CPLD_VERSION_FILE_PATTERN)) + + return cpld_version + diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py new file mode 100644 index 000000000000..25461986f37a --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python + +############################################################################# +# Mellanox +# +# implementation of new platform api +############################################################################# + +try: + import subprocess + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Platform(PlatformBase): + def __init__(self): + PlatformBase.__init__(self) + if self._is_host(): + self._chassis = Chassis() + self._chassis.initialize_components() + else: + self._chassis = Chassis() + self._chassis.initialize_psu() + self._chassis.initialize_fan() + self._chassis.initialize_eeprom() + + def _is_host(self): + """ + Test whether current process is running on the host or an docker + return True for host and False for docker + """ + is_host = False + try: + proc = subprocess.Popen("docker --version 2>/dev/null", stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + result = stdout.rstrip('\n') + if result != '': + is_host = True + + except OSError, e: + pass + + return is_host diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index a6f217d82bd3..0789f67e4f09 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -17,8 +17,7 @@ raise ImportError (str(e) + "- required module not found") # Global logger class instance -SYSLOG_IDENTIFIER = "mlnx-psu-api" -logger = Logger(SYSLOG_IDENTIFIER) +logger = Logger() psu_list = [] diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py index 9ea9c21899f5..845f355e28f1 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -63,6 +63,27 @@ XCVR_VENDOR_DATE_WIDTH = 8 XCVR_DOM_CAPABILITY_OFFSET = 92 XCVR_DOM_CAPABILITY_WIDTH = 2 +# to improve performance we retrieve all eeprom data via a single ethtool command +# in function get_transceiver_info and get_transceiver_bulk_status +# XCVR_INTERFACE_DATA_SIZE stands for the max size to be read +# this variable is only used by get_transceiver_info. +# please be noted that each time some new value added to the function +# we should make sure that it falls into the area +# [XCVR_INTERFACE_DATA_START, XCVR_INTERFACE_DATA_SIZE] or +# adjust XCVR_INTERFACE_MAX_SIZE to contain the new data +# It's same for [QSFP_DOM_BULK_DATA_START, QSFP_DOM_BULK_DATA_SIZE] and +# [SFP_DOM_BULK_DATA_START, SFP_DOM_BULK_DATA_SIZE] which are used by +# get_transceiver_bulk_status +XCVR_INTERFACE_DATA_START = 0 +XCVR_INTERFACE_DATA_SIZE = 92 +SFP_MODULE_ADDRA2_OFFSET = 256 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 56 + +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 @@ -79,7 +100,7 @@ QSFP_VOLT_OFFSET = 26 QSFP_VOLT_WIDTH = 2 QSFP_VERSION_COMPLIANCE_OFFSET = 1 -QSFP_VERSION_COMPLIANCE_WIDTH = 1 +QSFP_VERSION_COMPLIANCE_WIDTH = 2 QSFP_CHANNL_MON_OFFSET = 34 QSFP_CHANNL_MON_WIDTH = 16 QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 @@ -100,6 +121,12 @@ QSFP_OPTION_VALUE_OFFSET = 192 QSFP_OPTION_VALUE_WIDTH = 4 +QSFP_MODULE_UPPER_PAGE3_START = 384 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNL_THRESHOLD_OFFSET = 176 +QSFP_CHANNL_THRESHOLD_WIDTH = 24 + SFP_TEMPE_OFFSET = 96 SFP_TEMPE_WIDTH = 2 SFP_VOLT_OFFSET = 98 @@ -170,8 +197,7 @@ NVE_MASK = PORT_TYPE_MASK & (PORT_TYPE_NVE << PORT_TYPE_OFFSET) # Global logger class instance -SYSLOG_IDENTIFIER = "mlnx-sfp" -logger = Logger(SYSLOG_IDENTIFIER) +logger = Logger() class SFP(SfpBase): """Platform-specific SFP class""" @@ -186,6 +212,7 @@ def __init__(self, sfp_index, sfp_type): self.sdk_handle = None self.sdk_index = sfp_index + #SDK initializing stuff def _initialize_sdk_handle(self): """ @@ -198,6 +225,7 @@ def _initialize_sdk_handle(self): self.mypid = os.getpid() + def _open_sdk(self): if self.sdk_handle is None: self._initialize_sdk_handle() @@ -209,18 +237,21 @@ def _open_sdk(self): return True + def _close_sdk(self): rc = sxd_access_reg_deinit() if rc != 0: logger.log_warning("Failed to deinitializing register access.") #no further actions here + def _init_sx_meta_data(self): meta = sxd_reg_meta_t() meta.dev_id = DEVICE_ID meta.swid = SWITCH_ID return meta + def get_presence(self): """ Retrieves the presence of the device @@ -229,7 +260,7 @@ def get_presence(self): bool: True if device is present, False if not """ presence = False - ethtool_cmd = "ethtool -m sfp{} 2>/dev/null".format(self.index) + ethtool_cmd = "ethtool -m sfp{} hex on offset 0 length 1 2>/dev/null".format(self.index) try: proc = subprocess.Popen(ethtool_cmd, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) stdout = proc.communicate()[0] @@ -243,6 +274,7 @@ def get_presence(self): return presence + # Read out any bytes from any offset def _read_eeprom_specific_bytes(self, offset, num_bytes): eeprom_raw = [] @@ -260,7 +292,17 @@ 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() @@ -274,28 +316,30 @@ def _dom_capability_detect(self): # 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_OFFSET) + 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) - qspf_dom_capability = int(qsfp_dom_capability_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 = (qspf_dom_capability & 0x20 != 0) - self.dom_volt_supported = (qspf_dom_capability & 0x10 != 0) - self.dom_rx_power_supported = (qspf_dom_capability & 0x08 != 0) - self.dom_tx_power_supported = (qspf_dom_capability & 0x04 != 0) + 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 = (qspf_dom_capability & 0x08 != 0) + 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: - sfpd_obj = sff8436Dom() - if sfpd_obj is None: - return None - self.optional_capability = sfpd_obj.parse_option_params(qsfp_option_value_raw, 0) - self.dom_tx_disable_supported = self.optional_capability['data']['TxDisable']['value'] == 'On' + 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 @@ -303,6 +347,7 @@ def _dom_capability_detect(self): 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: @@ -336,6 +381,7 @@ def _dom_capability_detect(self): self.dom_rx_power_supported = False self.dom_tx_power_supported = False + def _convert_string_to_num(self, value_str): if "-inf" in value_str: return 'N/A' @@ -356,6 +402,7 @@ def _convert_string_to_num(self, value_str): else: return 'N/A' + def get_transceiver_info(self): """ Retrieves transceiver info of this SFP @@ -466,47 +513,37 @@ def get_transceiver_info(self): print("Error: sfp_object open failed") return None - sfp_interface_bulk_raw = self._read_eeprom_specific_bytes((offset + XCVR_INTFACE_BULK_OFFSET), interface_info_bulk_width) - if sfp_interface_bulk_raw is not None: - sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw, 0) - else: + 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 - sfp_vendor_name_raw = self._read_eeprom_specific_bytes((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 + 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) - sfp_vendor_pn_raw = self._read_eeprom_specific_bytes((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 + 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) - sfp_vendor_rev_raw = self._read_eeprom_specific_bytes((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 + 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) - sfp_vendor_sn_raw = self._read_eeprom_specific_bytes((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 + 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) - 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) - else: - return None + 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) - sfp_vendor_date_raw = self._read_eeprom_specific_bytes((offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) - if sfp_vendor_date_raw is not None: - sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0) - else: - return None + 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'] @@ -547,6 +584,7 @@ def get_transceiver_info(self): return transceiver_info_dict + def get_transceiver_bulk_status(self): """ Retrieves transceiver bulk status of this SFP @@ -578,84 +616,63 @@ def get_transceiver_bulk_status(self): """ transceiver_dom_info_dict = {} + dom_info_dict_keys = ['temperature', 'voltage', + 'rx1power', 'rx2power', + 'rx3power', 'rx4power', + 'tx1bias', 'tx2bias', + 'tx3bias', 'tx4bias', + 'tx1power', 'tx2power', + 'tx3power', 'tx4power' + ] + transceiver_dom_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + if self.sfp_type == OSFP_TYPE: - 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' + pass elif self.sfp_type == QSFP_TYPE: if not self.dom_supported: - return None + return transceiver_dom_info_dict offset = 0 sfpd_obj = sff8436Dom() if sfpd_obj is None: - return 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: - dom_temperature_raw = self._read_eeprom_specific_bytes((offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) - if dom_temperature_raw is not None: - dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) - temp = self._convert_string_to_num(dom_temperature_data['data']['Temperature']['value']) - if temp is not None: - transceiver_dom_info_dict['temperature'] = temp - else: - transceiver_dom_info_dict['temperature'] = 'N/A' - else: - return None - else: - transceiver_dom_info_dict['temperature'] = 'N/A' + 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: - 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) - volt = self._convert_string_to_num(dom_voltage_data['data']['Vcc']['value']) - if volt is not None: - transceiver_dom_info_dict['voltage'] = volt - else: - transceiver_dom_info_dict['voltage'] = 'N/A' - else: - return None - else: - transceiver_dom_info_dict['voltage'] = 'N/A' + 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 - 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) + 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']) - else: - transceiver_dom_info_dict['tx1power'] = 'N/A' - transceiver_dom_info_dict['tx2power'] = 'N/A' - transceiver_dom_info_dict['tx3power'] = 'N/A' - transceiver_dom_info_dict['tx4power'] = 'N/A' if 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']) - else: - 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'] = dom_channel_monitor_data['data']['TX1Bias']['value'] transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] @@ -664,49 +681,173 @@ def get_transceiver_bulk_status(self): else: if not self.dom_supported: - return None + return transceiver_dom_info_dict offset = 256 sfpd_obj = sff8472Dom() if sfpd_obj is None: - return None + return transceiver_dom_info_dict sfpd_obj._calibration_type = self.calibration - - dom_temperature_raw = self._read_eeprom_specific_bytes((offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) - if dom_temperature_raw is not None: - dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) - else: - return None - dom_voltage_raw = self._read_eeprom_specific_bytes((offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) - if dom_voltage_raw is not None: - dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) - else: - return None + dom_data_raw = self._read_eeprom_specific_bytes((offset + SFP_DOM_BULK_DATA_START), SFP_DOM_BULK_DATA_SIZE) - dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) - if dom_channel_monitor_raw is not None: - dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) - else: - return None + 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['rx2power'] = 'N/A' - transceiver_dom_info_dict['rx3power'] = 'N/A' - transceiver_dom_info_dict['rx4power'] = 'N/A' transceiver_dom_info_dict['tx1bias'] = self._convert_string_to_num(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'] = self._convert_string_to_num(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_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + transceiver_dom_threshold_info_dict = {} + + dom_info_dict_keys = ['temphighalarm', 'temphighwarning', + 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', + 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', + 'txbiaslowalarm', 'txbiaslowwarning' + ] + transceiver_dom_threshold_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + + if self.sfp_type == OSFP_TYPE: + pass + + elif self.sfp_type == QSFP_TYPE: + if not self.dom_supported or not self.qsfp_page3_available: + return transceiver_dom_threshold_info_dict + + # Dom Threshold data starts from offset 384 + # Revert offset back to 0 once data is retrieved + offset = QSFP_MODULE_UPPER_PAGE3_START + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self._read_eeprom_specific_bytes((offset + QSFP_MODULE_THRESHOLD_OFFSET), QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + + dom_channel_threshold_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_THRESHOLD_OFFSET), + QSFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is None: + return transceiver_dom_threshold_info_dict + dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values(dom_channel_threshold_raw, 0) + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_channel_threshold_data['data']['TxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_channel_threshold_data['data']['TxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_channel_threshold_data['data']['TxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_channel_threshold_data['data']['TxPowerLowWarning']['value'] + + 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'] + + return transceiver_dom_threshold_info_dict + + def get_reset_status(self): """ Retrieves the reset status of SFP @@ -749,6 +890,7 @@ def get_reset_status(self): else: return False + def get_rx_los(self): """ Retrieves the RX LOS (lost-of-signal) status of SFP @@ -782,6 +924,7 @@ def get_rx_los(self): return None return rx_los_list + def get_tx_fault(self): """ Retrieves the TX fault status of SFP @@ -815,6 +958,7 @@ def get_tx_fault(self): return None return tx_fault_list + def get_tx_disable(self): """ Retrieves the tx_disable status of this SFP @@ -851,6 +995,7 @@ def get_tx_disable(self): return None return tx_disable_list + def get_tx_disable_channel(self): """ Retrieves the TX disabled channels in this SFP @@ -870,6 +1015,7 @@ def get_tx_disable_channel(self): tx_disabled |= 1 << i return tx_disabled + def get_lpmode(self): """ Retrieves the lpmode (low power mode) status of this SFP @@ -900,6 +1046,7 @@ def get_lpmode(self): else: return NotImplementedError + def get_power_override(self): """ Retrieves the power-override status of this SFP @@ -920,6 +1067,7 @@ def get_power_override(self): else: return NotImplementedError + def get_temperature(self): """ Retrieves the temperature of this SFP @@ -962,6 +1110,7 @@ def get_temperature(self): else: return None + def get_voltage(self): """ Retrieves the supply voltage of this SFP @@ -1004,7 +1153,8 @@ def get_voltage(self): return voltage else: return None - + + def get_tx_bias(self): """ Retrieves the TX bias current of this SFP @@ -1036,7 +1186,7 @@ def get_tx_bias(self): sfpd_obj = sff8472Dom() if sfpd_obj is None: return None - sfpd_obj._calibration_type = 1 + sfpd_obj._calibration_type = self.calibration if self.dom_supported: dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) @@ -1049,7 +1199,8 @@ def get_tx_bias(self): return None return tx_bias_list - + + def get_rx_power(self): """ Retrieves the received optical power for this SFP @@ -1103,7 +1254,8 @@ def get_rx_power(self): else: return None return rx_power_list - + + def get_tx_power(self): """ Retrieves the TX power of this SFP @@ -1145,7 +1297,7 @@ def get_tx_power(self): return None if self.dom_supported: - sfpd_obj._calibration_type = 1 + sfpd_obj._calibration_type = self.calibration dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) if dom_channel_monitor_raw is not None: @@ -1156,7 +1308,8 @@ def get_tx_power(self): else: return None return tx_power_list - + + def reset(self): """ Reset SFP and return all user module settings to their default state. @@ -1192,6 +1345,7 @@ def reset(self): self._close_sdk() return rc == SXD_STATUS_SUCCESS + def _write_i2c_via_mcia(self, page, i2caddr, address, data, mask): handle = self._open_sdk() if handle is None: @@ -1226,6 +1380,7 @@ def _write_i2c_via_mcia(self, page, i2caddr, address, data, mask): self._close_sdk() return rc == SXD_STATUS_SUCCESS + def tx_disable(self, tx_disable): """ Disable SFP TX for all channels @@ -1269,6 +1424,7 @@ def tx_disable(self, tx_disable): else: return NotImplementedError + def tx_disable_channel(self, channel, disable): """ Sets the tx_disable for specified SFP channels @@ -1298,9 +1454,11 @@ def tx_disable_channel(self, channel, disable): else: return NotImplementedError + def is_nve(self, port): return (port & NVE_MASK) != 0 + def is_port_admin_status_up(self, log_port): oper_state_p = new_sx_port_oper_state_t_p() admin_state_p = new_sx_port_admin_state_t_p() @@ -1314,10 +1472,12 @@ def is_port_admin_status_up(self, log_port): else: return False + def set_port_admin_status_by_log_port(self, log_port, admin_status): rc = sx_api_port_state_set(self.sdk_handle, log_port, admin_status) assert rc == SX_STATUS_SUCCESS, "sx_api_port_state_set failed, rc = %d" % rc + # Get all the ports related to the sfp, if port admin status is up, put it to list def get_log_ports(self): port_attributes_list = new_sx_port_attributes_t_arr(SX_PORT_ATTR_ARR_SIZE) @@ -1338,6 +1498,7 @@ def get_log_ports(self): return log_port_list + def _set_sfp_admin_status_raw(self, admin_status): # Get PMAOS pmaos = ku_pmaos_reg() @@ -1361,6 +1522,7 @@ def _set_sfp_admin_status_raw(self, admin_status): rc = sxd_access_reg_pmaos(pmaos, meta, REGISTER_NUM, None, None) assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc + def _set_lpmode_raw(self, lpmode): # Get PMMP pmmp = ku_pmmp_reg() @@ -1382,6 +1544,7 @@ def _set_lpmode_raw(self, lpmode): return rc + def set_lpmode(self, lpmode): """ Sets the lpmode (low power mode) of SFP @@ -1414,6 +1577,7 @@ def set_lpmode(self, lpmode): self._close_sdk() return False + def set_power_override(self, power_override, power_set): """ Sets SFP power level using power_override and power_set 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 1e57603d38ad..e92884fc3f33 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py @@ -11,8 +11,6 @@ from python_sdk_api.sx_api import * from sonic_daemon_base.daemon_base import Logger -SYSLOG_IDENTIFIER = "sfp-event" - SDK_SFP_STATE_IN = 0x1 SDK_SFP_STATE_OUT = 0x2 STATUS_PLUGIN = '1' @@ -24,54 +22,101 @@ SDK_SFP_STATE_OUT: STATUS_PLUGOUT, } +# system level event/error +EVENT_ON_ALL_SFP = '-1' +SYSTEM_NOT_READY = 'system_not_ready' +SYSTEM_READY = 'system_become_ready' +SYSTEM_FAIL = 'system_fail' + +SDK_DAEMON_READY_FILE = '/tmp/sdk_ready' + PMPE_PACKET_SIZE = 2000 -logger = Logger(SYSLOG_IDENTIFIER) +logger = Logger() class sfp_event: ''' Listen to plugin/plugout cable events ''' - SX_OPEN_RETRIES = 20 + SX_OPEN_RETRIES = 30 + SX_OPEN_TIMEOUT = 5 + SELECT_TIMEOUT = 1 def __init__(self): self.swid = 0 self.handle = None - def initialize(self): - # open SDK API handle. - # retry at most SX_OPEN_RETRIES times to wait until SDK is started during system startup - retry = 1 - while True: - rc, self.handle = sx_api_open(None) - if rc == SX_STATUS_SUCCESS: - break - - logger.log_info("failed to open SDK API handle... retrying {}".format(retry)) - - time.sleep(2 ** retry) - retry += 1 - - if retry > self.SX_OPEN_RETRIES: - raise RuntimeError("failed to open SDK API handle after {} retries".format(retry)) - # Allocate SDK fd and user channel structures self.rx_fd_p = new_sx_fd_t_p() self.user_channel_p = new_sx_user_channel_t_p() - rc = sx_api_host_ifc_open(self.handle, self.rx_fd_p) - if rc != SX_STATUS_SUCCESS: - raise RuntimeError("sx_api_host_ifc_open exited with error, rc {}".format(rc)) - - self.user_channel_p.type = SX_USER_CHANNEL_TYPE_FD - self.user_channel_p.channel.fd = self.rx_fd_p + def initialize(self): + swid_cnt_p = None - rc = sx_api_host_ifc_trap_id_register_set(self.handle, - SX_ACCESS_CMD_REGISTER, - self.swid, - SX_TRAP_ID_PMPE, - self.user_channel_p) - if rc != SX_STATUS_SUCCESS: - raise RuntimeError("sx_api_host_ifc_trap_id_register_set exited with error, rc {}".format(rc)) + try: + # Wait for SDK daemon to be started with detect the sdk_ready file + retry = 0 + while not os.path.exists(SDK_DAEMON_READY_FILE): + if retry >= self.SX_OPEN_RETRIES: + raise RuntimeError("SDK daemon failed to start after {} retries and {} seconds waiting, exiting..." + .format(retry, self.SX_OPEN_TIMEOUT * self.SX_OPEN_RETRIES)) + else: + logger.log_info("SDK daemon not started yet, retry {} times".format(retry)) + retry += 1 + time.sleep(self.SX_OPEN_TIMEOUT) + + # After SDK daemon started, sx_api_open and sx_api_host_ifc_open is ready for call + rc, self.handle = sx_api_open(None) + if rc != SX_STATUS_SUCCESS: + raise RuntimeError("failed to call sx_api_open with rc {}, exiting...".format(rc)) + + rc = sx_api_host_ifc_open(self.handle, self.rx_fd_p) + if rc != SX_STATUS_SUCCESS: + raise RuntimeError("failed to call sx_api_host_ifc_open with rc {}, exiting...".format(rc)) + + self.user_channel_p.type = SX_USER_CHANNEL_TYPE_FD + self.user_channel_p.channel.fd = self.rx_fd_p + + # Wait for switch to be created and initialized inside SDK + retry = 0 + swid_cnt_p = new_uint32_t_p() + uint32_t_p_assign(swid_cnt_p, 0) + swid_cnt = 0 + while True: + if retry >= self.SX_OPEN_RETRIES: + raise RuntimeError("switch not created after {} retries and {} seconds waiting, exiting..." + .format(retry, self.SX_OPEN_RETRIES * self.SX_OPEN_TIMEOUT)) + else: + rc = sx_api_port_swid_list_get(self.handle, None, swid_cnt_p) + if rc == SX_STATUS_SUCCESS: + swid_cnt = uint32_t_p_value(swid_cnt_p) + if swid_cnt > 0: + delete_uint32_t_p(swid_cnt_p) + swid_cnt_p = None + break + else: + logger.log_info("switch not created yet, swid_cnt {}, retry {} times and wait for {} seconds" + .format(swid_cnt, retry, self.SX_OPEN_TIMEOUT * retry)) + else: + raise RuntimeError("sx_api_port_swid_list_get fail with rc {}, retry {} times and wait for {} seconds". + format(rc, retry, self.SX_OPEN_TIMEOUT * retry)) + + retry += 1 + time.sleep(self.SX_OPEN_TIMEOUT) + + # After switch was created inside SDK, sx_api_host_ifc_trap_id_register_set is ready to call + rc = sx_api_host_ifc_trap_id_register_set(self.handle, + SX_ACCESS_CMD_REGISTER, + self.swid, + SX_TRAP_ID_PMPE, + self.user_channel_p) + + if rc != SX_STATUS_SUCCESS: + raise RuntimeError("sx_api_host_ifc_trap_id_register_set failed with rc {}, exiting...".format(rc)) + except Exception as e: + logger.log_error("sfp_event initialization failed due to {}, exiting...".format(repr(e))) + if swid_cnt_p is not None: + delete_uint32_t_p(swid_cnt_p) + self.deinitialize() def deinitialize(self): if self.handle is None: diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index 5195d378a468..6862b3fb258b 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -19,8 +19,7 @@ raise ImportError (str(e) + "- required module not found") # Global logger class instance -SYSLOG_IDENTIFIER = "mlnx-thermal-api" -logger = Logger(SYSLOG_IDENTIFIER) +logger = Logger() THERMAL_DEV_CATEGORY_CPU_CORE = "cpu_core" THERMAL_DEV_CATEGORY_CPU_PACK = "cpu_pack" @@ -49,8 +48,8 @@ THERMAL_API_GET_HIGH_THRESHOLD:"cpu_pack_max" } thermal_api_handler_module = { - THERMAL_API_GET_TEMPERATURE:"temp_input_module{}", - THERMAL_API_GET_HIGH_THRESHOLD:"temp_crit_module{}" + THERMAL_API_GET_TEMPERATURE:"module{}_temp_input", + THERMAL_API_GET_HIGH_THRESHOLD:"module{}_temp_crit" } thermal_api_handler_psu = { THERMAL_API_GET_TEMPERATURE:"psu{}_temp", diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index fd023ab9c2ed..39942111f26a 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.14.2-master +MLNX_SAI_VERSION = SAIRel1.15.2-master export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index d446176da71b..925116eb63a5 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit d446176da71b42bd0d9c5421cae24c6b255c7a5c +Subproject commit 925116eb63a5a9012dcc22a7a0682ada6e976380 diff --git a/platform/mellanox/mlnx-sfpd.mk b/platform/mellanox/mlnx-sfpd.mk deleted file mode 100644 index 416dd7d0f2cd..000000000000 --- a/platform/mellanox/mlnx-sfpd.mk +++ /dev/null @@ -1,5 +0,0 @@ -# mlnx-sfpd (SONiC MLNX platform sfp event monitoring daemon) Debian package - -MLNX_SFPD = python-mlnx-sfpd_1.0-1_all.deb -$(MLNX_SFPD)_SRC_PATH = $(PLATFORM_PATH)/mlnx-sfpd -SONIC_PYTHON_STDEB_DEBS += $(MLNX_SFPD) diff --git a/platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd b/platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd deleted file mode 100644 index b11403b31514..000000000000 --- a/platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd +++ /dev/null @@ -1,305 +0,0 @@ -#!/usr/bin/env python -''' -This code is for a mlnx platform specific daemon, mlnx-sfpd. -Which listen to the SDK for the SFP change event and post the event to DB. -''' - -from __future__ import print_function -import sys, errno -import os -import time -import syslog -import signal -import select -import json -import threading -from python_sdk_api.sx_api import * -from swsssdk import SonicV2Connector - -VERSION = '1.0' - -SYSLOG_IDENTIFIER = "mlnx-sfpd" - -REDIS_HOSTIP = "127.0.0.1" - -SDK_SFP_STATE_IN = 0x1 -SDK_SFP_STATE_OUT = 0x2 -STATUS_PLUGIN = '1' -STATUS_PLUGOUT = '0' -STATUS_UNKNOWN = '2' - -SFPD_LIVENESS_EXPIRE_SECS = 30 - -SDK_DAEMON_READY_FILE = '/tmp/sdk_ready' - -sfp_value_status_dict = { - SDK_SFP_STATE_IN: STATUS_PLUGIN, - SDK_SFP_STATE_OUT: STATUS_PLUGOUT, -} - -# ========================== Syslog wrappers ========================== -def log_info(msg, also_print_to_console=False): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_INFO, msg) - syslog.closelog() - - if also_print_to_console: - print(msg) - -def log_warning(msg, also_print_to_console=False): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_WARNING, msg) - syslog.closelog() - - if also_print_to_console: - print(msg) - -def log_error(msg, also_print_to_console=False): - syslog.openlog(SYSLOG_IDENTIFIER) - syslog.syslog(syslog.LOG_ERR, msg) - syslog.closelog() - - if also_print_to_console: - print(msg) - -# ========================== MlnxSfpd class ========================== -class MlnxSfpd: - ''' Listen to plugin/plugout cable events ''' - - SX_OPEN_RETRIES = 30 - SX_OPEN_TIMEOUT = 5 - SELECT_TIMEOUT = 1 - - def __init__(self): - self.swid = 0 - self.running = False - self.handle = None - - # Allocate SDK fd and user channel structures - self.rx_fd_p = new_sx_fd_t_p() - self.user_channel_p = new_sx_user_channel_t_p() - self.state_db = SonicV2Connector(host=REDIS_HOSTIP) - - # Register our signal handlers - signal.signal(signal.SIGHUP, self.signal_handler) - signal.signal(signal.SIGINT, self.signal_handler) - signal.signal(signal.SIGTERM, self.signal_handler) - - def signal_handler(self, signum, frame): - if signum == signal.SIGHUP: - log_info("Caught SIGHUP - ignoring...") - elif signum == signal.SIGINT: - log_info("Caught SIGINT - exiting...") - self.running = False - elif signum == signal.SIGTERM: - log_info("Caught SIGINT - exiting...") - self.running = False - else: - log_warning("Caught unhandled signal '{}'".format(signum)) - - def initialize(self): - self.state_db.connect("STATE_DB") - - swid_cnt_p = None - - try: - # Wait for SDK daemon to be started with detect the sdk_ready file - retry = 0 - while not os.path.exists(SDK_DAEMON_READY_FILE): - if retry >= self.SX_OPEN_RETRIES: - raise RuntimeError("SDK daemon failed to start after {} retries and {} seconds waiting, exiting..." - .format(retry, self.SX_OPEN_TIMEOUT * self.SX_OPEN_RETRIES)) - else: - log_info("SDK daemon not started yet, retry {} times".format(retry)) - retry = retry + 1 - time.sleep(self.SX_OPEN_TIMEOUT) - - # to make sure SDK daemon has started - time.sleep(self.SX_OPEN_TIMEOUT) - - # After SDK daemon started, sx_api_open and sx_api_host_ifc_open is ready for call - rc, self.handle = sx_api_open(None) - if rc != SX_STATUS_SUCCESS: - raise RuntimeError("failed to call sx_api_open with rc {}, exiting...".format(rc)) - - rc = sx_api_host_ifc_open(self.handle, self.rx_fd_p) - if rc != SX_STATUS_SUCCESS: - raise RuntimeError("failed to call sx_api_host_ifc_open with rc {}, exiting...".format(rc)) - - self.user_channel_p.type = SX_USER_CHANNEL_TYPE_FD - self.user_channel_p.channel.fd = self.rx_fd_p - - # Wait for switch to be created and initialized inside SDK - retry = 0 - swid_cnt_p = new_uint32_t_p() - uint32_t_p_assign(swid_cnt_p, 0) - swid_cnt = 0 - while True: - if retry >= self.SX_OPEN_RETRIES: - raise RuntimeError("switch not created after {} retries and {} seconds waiting, exiting..." - .format(retry, self.SX_OPEN_RETRIES * self.SX_OPEN_TIMEOUT)) - else: - rc = sx_api_port_swid_list_get(self.handle, None, swid_cnt_p) - if rc == SX_STATUS_SUCCESS: - swid_cnt = uint32_t_p_value(swid_cnt_p) - if swid_cnt > 0: - delete_uint32_t_p(swid_cnt_p) - swid_cnt_p = None - break - else: - log_info("switch not created yet, swid_cnt {}, retry {} times and wait for {} seconds" - .format(swid_cnt, retry, self.SX_OPEN_TIMEOUT * retry)) - else: - raise RuntimeError("sx_api_port_swid_list_get fail with rc {}, retry {} times and wait for {} seconds". - format(rc, retry, self.SX_OPEN_TIMEOUT * retry)) - - retry = retry + 1 - time.sleep(self.SX_OPEN_TIMEOUT) - - # After switch was created inside SDK, sx_api_host_ifc_trap_id_register_set is ready to call - rc = sx_api_host_ifc_trap_id_register_set(self.handle, - SX_ACCESS_CMD_REGISTER, - self.swid, - SX_TRAP_ID_PMPE, - self.user_channel_p) - - if rc != SX_STATUS_SUCCESS: - raise RuntimeError("sx_api_host_ifc_trap_id_register_set failed with rc {}, exiting...".format(rc)) - - self.running = True - except Exception as e: - log_error("mlnx-sfpd initialization failed due to {}, exiting...".format(repr(e))) - if swid_cnt_p is not None: - delete_uint32_t_p(swid_cnt_p) - self.deinitialize() - - def deinitialize(self): - # remove mlnx-sfpd liveness key in DB if not expired yet - if self.state_db.exists("STATE_DB", "MLNX_SFPD_TASK|LIVENESS"): - self.state_db.delete("STATE_DB", "MLNX_SFPD_TASK|LIVENESS") - - if self.handle is None: - return - - # unregister trap id - rc = sx_api_host_ifc_trap_id_register_set(self.handle, - SX_ACCESS_CMD_DEREGISTER, - self.swid, - SX_TRAP_ID_PMPE, - self.user_channel_p) - if rc != SX_STATUS_SUCCESS: - log_error("sx_api_host_ifc_trap_id_register_set exited with error, rc {}".format(rc)) - - rc = sx_api_host_ifc_close(self.handle, self.rx_fd_p) - if rc != SX_STATUS_SUCCESS: - log_error("sx_api_host_ifc_close exited with error, rc {}".format(rc)) - - rc = sx_api_close(self.handle) - if rc != SX_STATUS_SUCCESS: - log_error("sx_api_close exited with error, rc {}".format(rc)) - - def run(self): - - while self.running: - try: - read, _, _ = select.select([self.rx_fd_p.fd], [], [], self.SELECT_TIMEOUT) - except select.error as err: - rc, msg = err - if rc == errno.EAGAIN or rc == errno.EINTR: - continue - else: - raise - - for fd in read: - if fd == self.rx_fd_p.fd: - success, port_list, module_state = self.on_pmpe(self.rx_fd_p) - if not success: - raise RuntimeError("failed to read from {}".format(fd)) - - sfp_state = sfp_value_status_dict.get(module_state, STATUS_UNKNOWN) - if sfp_state == STATUS_UNKNOWN: - log_error("unknown module state {} on port {}".format(module_state, port)) - continue - - for port in port_list: - log_info("SFP on port {} state {}".format(port, sfp_state)) - self.send_sfp_notification(str(port), sfp_state) - - self.update_sfpd_liveness_key(SFPD_LIVENESS_EXPIRE_SECS) - - def send_sfp_notification(self, port, state): - sfp_notify = [port, state] - msg = json.dumps(sfp_notify, separators=(',', ':')) - self.state_db.publish('STATE_DB', 'TRANSCEIVER_NOTIFY', msg) - - def update_sfpd_liveness_key(self, timeout_secs): - if not self.state_db.exists('STATE_DB', 'MLNX_SFPD_TASK|LIVENESS'): - self.state_db.set('STATE_DB', 'MLNX_SFPD_TASK|LIVENESS', 'value', 'ok') - self.state_db.expire('STATE_DB', 'MLNX_SFPD_TASK|LIVENESS', timeout_secs) - - def on_pmpe(self, fd_p): - ''' on port module plug event handler ''' - - # recv parameters - pkt_size = 2000 - pkt_size_p = new_uint32_t_p() - uint32_t_p_assign(pkt_size_p, pkt_size) - pkt = new_uint8_t_arr(pkt_size) - recv_info_p = new_sx_receive_info_t_p() - pmpe_t = sx_event_pmpe_t() - port_attributes_list = new_sx_port_attributes_t_arr(64) - port_cnt_p = new_uint32_t_p() - uint32_t_p_assign(port_cnt_p,64) - label_port_list = [] - module_state = 0 - - rc = sx_lib_host_ifc_recv(fd_p, pkt, pkt_size_p, recv_info_p) - if rc != 0: - log_error("sx_lib_host_ifc_recv exited with error, rc %d" % rc) - status = False - else: - status = True - pmpe_t = recv_info_p.event_info.pmpe - port_list_size = pmpe_t.list_size - logical_port_list = pmpe_t.log_port_list - module_state = pmpe_t.module_state - - for i in xrange(port_list_size): - logical_port = sx_port_log_id_t_arr_getitem(logical_port_list, i) - rc = sx_api_port_device_get(self.handle, 1 , 0, port_attributes_list, port_cnt_p) - port_cnt = uint32_t_p_value(port_cnt_p) - - for i in xrange(port_cnt): - port_attributes = sx_port_attributes_t_arr_getitem(port_attributes_list,i) - if port_attributes.log_port == logical_port: - lable_port = port_attributes.port_mapping.module_port - break - label_port_list.append(lable_port) - - delete_uint32_t_p(pkt_size_p) - delete_uint8_t_arr(pkt) - delete_sx_receive_info_t_p(recv_info_p) - delete_sx_port_attributes_t_arr(port_attributes_list) - delete_uint32_t_p(port_cnt_p) - - return status, label_port_list, module_state, - - -# main start -def main(): - log_info("mlnx-sfpd daemon started") - - sfpd = MlnxSfpd() - try: - sfpd.initialize() - sfpd.run() - except (RuntimeError, select.error) as err: - log_error("error: {}".format(err)) - finally: - sfpd.deinitialize() - - log_info("mlnx-sfpd daemon exited") - - -if __name__ == '__main__': - main() diff --git a/platform/mellanox/mlnx-sfpd/setup.py b/platform/mellanox/mlnx-sfpd/setup.py deleted file mode 100644 index ea9b895cb1f4..000000000000 --- a/platform/mellanox/mlnx-sfpd/setup.py +++ /dev/null @@ -1,28 +0,0 @@ -from setuptools import setup - -setup( - name='mlnx-sfpd', - version='1.0', - description='SFP event mmonitoring daemon for SONiC on mellanox platform', - license='Apache 2.0', - author='SONiC Community', - url='https://github.com/Azure/sonic-buildimage/', - maintainer='Kebo Liu', - maintainer_email='kebol@mellanox.com', - scripts=[ - 'scripts/mlnx-sfpd', - ], - classifiers=[ - 'Development Status :: 4 - Beta', - 'Environment :: No Input/Output (Daemon)', - 'Intended Audience :: Developers', - 'Intended Audience :: Information Technology', - 'Intended Audience :: System Administrators', - 'License :: OSI Approved :: Apache Software License', - 'Natural Language :: English', - 'Operating System :: POSIX :: Linux', - 'Programming Language :: Python :: 2.7', - 'Topic :: System :: Hardware', - ], - keywords='sonic SONiC SFP sfp MELLANOX mellanox daemon SFPD sfpd', -) diff --git a/platform/mellanox/rules.mk b/platform/mellanox/rules.mk index c869bfc6cd3d..dd10cefda571 100644 --- a/platform/mellanox/rules.mk +++ b/platform/mellanox/rules.mk @@ -10,7 +10,6 @@ include $(PLATFORM_PATH)/docker-saiserver-mlnx.mk include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/libsaithrift-dev.mk include $(PLATFORM_PATH)/docker-ptf-mlnx.mk -include $(PLATFORM_PATH)/mlnx-sfpd.mk include $(PLATFORM_PATH)/mlnx-ffb.mk include $(PLATFORM_PATH)/issu-version.mk diff --git a/platform/mellanox/sdk-src/sx-acl-helper/Makefile b/platform/mellanox/sdk-src/sx-acl-helper/Makefile new file mode 100644 index 000000000000..d9d0aef8775b --- /dev/null +++ b/platform/mellanox/sdk-src/sx-acl-helper/Makefile @@ -0,0 +1,29 @@ +.ONESHELL: +SHELL = /bin/bash + +MAIN_TARGET = sx-acl-helper_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb +DERIVED_TARGETS = sx-acl-helper-dev_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb \ + sx-acl-helper-dev-static_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb \ + sx-acl-helper-dbgsym_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb +PACKAGE_NAME = sx_acl_helper + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + # get sources + rm -rf $(PACKAGE_NAME)-$(MLNX_SDK_VERSION)-$(MLNX_SDK_ISSU_VERSION) + + wget -c $(MLNX_SDK_SOURCE_BASE_URL)/$(PACKAGE_NAME)-$(MLNX_SDK_VERSION)-$(MLNX_SDK_ISSU_VERSION).tar.gz -O - | tar -xz + + # build + pushd $(PACKAGE_NAME)-$(MLNX_SDK_VERSION)-$(MLNX_SDK_ISSU_VERSION) + + if [ -f autogen.sh ]; then + ./autogen.sh + fi + + debuild -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + + popd + + mv $(DERIVED_TARGETS) $* $(DEST)/ + +$(addprefix $(DEST)/, $(DERIVED_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) diff --git a/platform/mellanox/sdk-src/sx-kernel/Makefile b/platform/mellanox/sdk-src/sx-kernel/Makefile index 35ce9432a37c..9e979879fef8 100644 --- a/platform/mellanox/sdk-src/sx-kernel/Makefile +++ b/platform/mellanox/sdk-src/sx-kernel/Makefile @@ -7,12 +7,18 @@ PACKAGE_NAME = sx_kernel $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # get sources - rm -rf sx_kernel-$(MLNX_SDK_VERSION)-$(MLNX_SDK_ISSU_VERSION) - wget -c $(MLNX_SDK_SOURCE_BASE_URL)/$(PACKAGE_NAME)-$(MLNX_SDK_VERSION)-$(MLNX_SDK_ISSU_VERSION).tar.gz -O - | tar -xz + if [ ! -z "$(MLNX_SDK_SOURCE_BASE_URL)" ]; then + rm -rf sx_kernel-$(MLNX_SDK_VERSION)-$(MLNX_SDK_ISSU_VERSION) + wget -c $(MLNX_SDK_SOURCE_BASE_URL)/$(PACKAGE_NAME)-$(MLNX_SDK_VERSION)-$(MLNX_SDK_ISSU_VERSION).tar.gz -O - | tar -xz + pushd sx_kernel-$(MLNX_SDK_VERSION)-$(MLNX_SDK_ISSU_VERSION) + else + pushd Switch-SDK-drivers + git reset --hard + git clean -xfd + fi # build - pushd sx_kernel-$(MLNX_SDK_VERSION)-$(MLNX_SDK_ISSU_VERSION) patch -p1 < ../sx_kernel_makefile_sonic_build.patch debuild -e KVERSION=$(KVERSION) -e KSRC_EXT=/lib/modules/$(KVERSION)/source/ -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers new file mode 160000 index 000000000000..87f7a7911275 --- /dev/null +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -0,0 +1 @@ +Subproject commit 87f7a7911275285abc63c24ba39aa4af4c4b4678 diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 1401b5f6289f..73568ce84596 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ -MLNX_SDK_BASE_URL = https://github.com/Mellanox/SAI-Implementation/raw/f4bc0f92f729cedf4d65a19563f61db23acb7763/sdk -MLNX_SDK_VERSION = 4.3.1634 +MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ +MLNX_SDK_VERSION = 4.3.2602 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) @@ -15,17 +15,17 @@ endif export MLNX_SDK_SOURCE_BASE_URL MLNX_SDK_VERSION MLNX_SDK_ISSU_VERSION MLNX_SDK_DEB_VERSION -MLNX_SDK_RDEBS += $(APPLIBS) $(IPROUTE2_MLNX) $(SX_COMPLIB) \ - $(SX_EXAMPLES) $(SX_GEN_UTILS) $(SX_SCEW) $(SXD_LIBS) $(WJH_LIBS) +MLNX_SDK_RDEBS += $(APPLIBS) $(IPROUTE2_MLNX) $(SX_COMPLIB) $(SX_EXAMPLES) \ + $(SX_GEN_UTILS) $(SX_SCEW) $(SXD_LIBS) $(WJH_LIBS) $(SX_ACL_HELPER) -MLNX_SDK_DEBS += $(APPLIBS_DEV) $(IPROUTE2_MLNX_DEV) \ - $(SX_COMPLIB_DEV) $(SX_COMPLIB_DEV_STATIC) $(SX_EXAMPLES_DEV) \ - $(SX_GEN_UTILS_DEV) $(SX_SCEW_DEV) $(SX_SCEW_DEV_STATIC) \ - $(SXD_LIBS_DEV) $(SXD_LIBS_DEV_STATIC) $(WJH_LIBS_DEV) +MLNX_SDK_DEBS += $(APPLIBS_DEV) $(IPROUTE2_MLNX_DEV) $(SX_COMPLIB_DEV) \ + $(SX_COMPLIB_DEV_STATIC) $(SX_EXAMPLES_DEV) $(SX_GEN_UTILS_DEV) \ + $(SX_SCEW_DEV) $(SX_SCEW_DEV_STATIC) $(SXD_LIBS_DEV)\ + $(SXD_LIBS_DEV_STATIC) $(WJH_LIBS_DEV) $(SX_ACL_HELPER_DEV) MLNX_SDK_DBG_DEBS += $(APPLIBS_DBGSYM) $(IPROUTE2_MLNX_DBGSYM) $(SX_COMPLIB_DBGSYM) \ $(SX_EXAMPLES_DBGSYM) $(SX_GEN_UTILS_DBGSYM) $(SX_SCEW_DBGSYM) \ - $(SXD_LIBS_DBGSYM) $(WJH_LIBS_DBGSYM) + $(SXD_LIBS_DBGSYM) $(WJH_LIBS_DBGSYM) $(SX_ACL_HELPER_DBGSYM) APPLIBS = applibs_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb $(APPLIBS)_SRC_PATH = $(PLATFORM_PATH)/sdk-src/applibs @@ -69,7 +69,7 @@ endif SX_GEN_UTILS = sx-gen-utils_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb $(SX_GEN_UTILS)_SRC_PATH += $(PLATFORM_PATH)/sdk-src/sx-gen-utils -$(SX_GEN_UTILS)_DEPENDS += $(SX_COMPLIB_DEV) $(SXD_LIBS_DEV) +$(SX_GEN_UTILS)_DEPENDS += $(SX_COMPLIB_DEV) $(SX_GEN_UTILS)_RDEPENDS += $(SX_COMPLIB) SX_GEN_UTILS_DEV = sx-gen-utils-dev_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb $(eval $(call add_derived_package,$(SX_GEN_UTILS),$(SX_GEN_UTILS_DEV))) @@ -89,7 +89,7 @@ endif SXD_LIBS = sxd-libs_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb $(SXD_LIBS)_SRC_PATH = $(PLATFORM_PATH)/sdk-src/sxd-libs -$(SXD_LIBS)_DEPENDS += $(SX_COMPLIB_DEV) +$(SXD_LIBS)_DEPENDS += $(SX_COMPLIB_DEV) $(SX_GEN_UTILS_DEV) SXD_LIBS_DEV = sxd-libs-dev_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb $(eval $(call add_derived_package,$(SXD_LIBS),$(SXD_LIBS_DEV))) SXD_LIBS_DBGSYM = sxd-libs-dbgsym_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb @@ -107,10 +107,21 @@ ifeq ($(SDK_FROM_SRC),y) $(eval $(call add_derived_package,$(PYTHON_SDK_API),$(PYTHON_SDK_API_DBGSYM))) endif +SX_ACL_HELPER = sx-acl-helper_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb +$(SX_ACL_HELPER)_SRC_PATH = $(PLATFORM_PATH)/sdk-src/sx-acl-helper +$(SX_ACL_HELPER)_DEPENDS += $(SX_COMPLIB_DEV) $(SXD_LIBS_DEV) $(APPLIBS_DEV) +$(SX_ACL_HELPER)_RDEPENDS += $(SX_COMPLIB) $(PYTHON_SDK_API) +SX_ACL_HELPER_DEV = sx-acl-helper-dev_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb +$(eval $(call add_derived_package,$(SX_ACL_HELPER),$(SX_ACL_HELPER_DEV))) +SX_ACL_HELPER_DBGSYM = sx-acl-helper-dbgsym_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb +ifeq ($(SDK_FROM_SRC),y) +$(eval $(call add_derived_package,$(SX_ACL_HELPER),$(SX_ACL_HELPER_DBGSYM))) +endif + WJH_LIBS = wjh-libs_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb $(WJH_LIBS)_SRC_PATH = $(PLATFORM_PATH)/sdk-src/wjh-libs -$(WJH_LIBS)_DEPENDS += $(SX_COMPLIB_DEV) $(SXD_LIBS_DEV) $(APPLIBS_DEV) -$(WJH_LIBS)_RDEPENDS += $(SX_COMPLIB) $(PYTHON_SDK_API) +$(WJH_LIBS)_DEPENDS += $(SX_COMPLIB_DEV) $(SXD_LIBS_DEV) $(APPLIBS_DEV) $(SX_ACL_HELPER_DEV) $(SX_SCEW_DEV) +$(WJH_LIBS)_RDEPENDS += $(SX_COMPLIB) $(PYTHON_SDK_API) $(SX_ACL_HELPER) WJH_LIBS_DEV = wjh-libs-dev_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb $(eval $(call add_derived_package,$(WJH_LIBS),$(WJH_LIBS_DEV))) WJH_LIBS_DBGSYM = wjh-libs-dbgsym_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb @@ -124,19 +135,21 @@ $(SX_KERNEL)_SRC_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel SX_KERNEL_DEV = sx-kernel-dev_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb $(eval $(call add_derived_package,$(SX_KERNEL),$(SX_KERNEL_DEV))) -define make_url - $(1)_URL = $(MLNX_SDK_BASE_URL)/$(1) +define make_path + $(1)_PATH = $(MLNX_SDK_BASE_PATH) endef -$(eval $(foreach deb,$(MLNX_SDK_DEBS),$(call make_url,$(deb)))) -$(eval $(foreach deb,$(MLNX_SDK_RDEBS),$(call make_url,$(deb)))) -$(eval $(foreach deb,$(PYTHON_SDK_API) $(SX_KERNEL) $(SX_KERNEL_DEV),$(call make_url,$(deb)))) +$(eval $(foreach deb,$(MLNX_SDK_DEBS),$(call make_path,$(deb)))) +$(eval $(foreach deb,$(MLNX_SDK_RDEBS),$(call make_path,$(deb)))) +$(eval $(foreach deb,$(PYTHON_SDK_API) $(SX_KERNEL) $(SX_KERNEL_DEV),$(call make_path,$(deb)))) + +SONIC_MAKE_DEBS += $(SX_KERNEL) ifeq ($(SDK_FROM_SRC), y) -SONIC_MAKE_DEBS += $(MLNX_SDK_RDEBS) $(PYTHON_SDK_API) $(SX_KERNEL) +SONIC_MAKE_DEBS += $(MLNX_SDK_RDEBS) $(PYTHON_SDK_API) else -SONIC_ONLINE_DEBS += $(MLNX_SDK_RDEBS) $(PYTHON_SDK_API) $(SX_KERNEL) +SONIC_COPY_DEBS += $(MLNX_SDK_RDEBS) $(PYTHON_SDK_API) endif SONIC_STRETCH_DEBS += $(SX_KERNEL) diff --git a/platform/nephos/docker-syncd-nephos-rpc.mk b/platform/nephos/docker-syncd-nephos-rpc.mk index 9ee1aeab090c..dafc43b3e7e3 100644 --- a/platform/nephos/docker-syncd-nephos-rpc.mk +++ b/platform/nephos/docker-syncd-nephos-rpc.mk @@ -10,8 +10,9 @@ $(DOCKER_SYNCD_NEPHOS_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSAIREDIS_DBG) endif $(DOCKER_SYNCD_NEPHOS_RPC)_FILES += $(DSSERVE) $(NPX_DIAG) -$(DOCKER_SYNCD_NEPHOS_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_NEPHOS) +$(DOCKER_SYNCD_NEPHOS_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BASE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_NEPHOS_RPC) +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_NEPHOS_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_NEPHOS_RPC) endif @@ -19,5 +20,6 @@ endif $(DOCKER_SYNCD_NEPHOS_RPC)_CONTAINER_NAME = syncd $(DOCKER_SYNCD_NEPHOS_RPC)_RUN_OPT += --net=host --privileged -t $(DOCKER_SYNCD_NEPHOS_RPC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf +$(DOCKER_SYNCD_NEPHOS_RPC)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_NEPHOS_RPC)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd $(DOCKER_SYNCD_NEPHOS_RPC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro diff --git a/platform/nephos/docker-syncd-nephos.mk b/platform/nephos/docker-syncd-nephos.mk index 4acd688de865..6829c91c67aa 100644 --- a/platform/nephos/docker-syncd-nephos.mk +++ b/platform/nephos/docker-syncd-nephos.mk @@ -3,7 +3,8 @@ DOCKER_SYNCD_PLATFORM_CODE = nephos include $(PLATFORM_PATH)/../template/docker-syncd-base.mk -$(DOCKER_SYNCD_BASE)_DEPENDS += $(SYNCD) $(PYTHON_SDK_API) +$(DOCKER_SYNCD_BASE)_DEPENDS += $(SYNCD) +$(DOCKER_SYNCD_BASE)_FILES += $(DSSERVE) $(NPX_DIAG) $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSWSSCOMMON_DBG) \ @@ -11,3 +12,7 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIREDIS_DBG) $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot +$(DOCKER_SYNCD_BASE)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd + +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += npx_diag:/usr/bin/npx_diag + diff --git a/platform/nephos/docker-syncd-nephos/Dockerfile.j2 b/platform/nephos/docker-syncd-nephos/Dockerfile.j2 index bb15fdd63bbb..f891ace1e8e4 100755 --- a/platform/nephos/docker-syncd-nephos/Dockerfile.j2 +++ b/platform/nephos/docker-syncd-nephos/Dockerfile.j2 @@ -32,8 +32,12 @@ debs/{{ deb }}{{' '}} ##debs/{{ deb }}{{' '}} ##{%- endfor %} -COPY ["start.sh", "/usr/bin/"] +COPY ["files/dsserve", "files/npx_diag", "start.sh", "/usr/bin/"] +RUN chmod +x /usr/bin/npx_diag /usr/bin/dsserve + COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y diff --git a/platform/nephos/docker-syncd-nephos/critical_processes b/platform/nephos/docker-syncd-nephos/critical_processes new file mode 100644 index 000000000000..489668a89e08 --- /dev/null +++ b/platform/nephos/docker-syncd-nephos/critical_processes @@ -0,0 +1,2 @@ +dsserve +syncd diff --git a/platform/nephos/docker-syncd-nephos/supervisord.conf b/platform/nephos/docker-syncd-nephos/supervisord.conf index 1af5d70a1d0c..c823ab5680ef 100644 --- a/platform/nephos/docker-syncd-nephos/supervisord.conf +++ b/platform/nephos/docker-syncd-nephos/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/platform/nephos/nephos-modules.mk b/platform/nephos/nephos-modules.mk index 565e975e0a08..b76141b40663 100644 --- a/platform/nephos/nephos-modules.mk +++ b/platform/nephos/nephos-modules.mk @@ -2,9 +2,25 @@ VERSION = 1.0.0 +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-9-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)_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/rules.mk b/platform/nephos/rules.mk index 797e2def91ce..5c115eeaf8d0 100644 --- a/platform/nephos/rules.mk +++ b/platform/nephos/rules.mk @@ -14,8 +14,9 @@ $(NPX_DIAG)_URL = "https://github.com/NephosInc/SONiC/raw/master/sdk/npx_diag" WARM_VERIFIER = warm-verifier $(WARM_VERIFIER)_URL = "https://github.com/NephosInc/SONiC/raw/master/sai/warm-verifier" + DSSERVE = dsserve -$(DSSERVE)_URL = "https://sonicstorage.blob.core.windows.net/packages/20170518/dsserve?sv=2015-04-05&sr=b&sig=gyNbgSL%2FvpMXDdpboVkIJcTKMRdGgEaOR9OukHhEsu8%3D&se=2030-03-31T23%3A06%3A35Z&sp=r" +$(DSSERVE)_URL = "https://sonicstorage.blob.core.windows.net/packages/20190307/dsserve?sv=2015-04-05&sr=b&sig=lk7BH3DtW%2F5ehc0Rkqfga%2BUCABI0UzQmDamBsZH9K6w%3D&se=2038-05-06T22%3A34%3A45Z&sp=r" SONIC_ONLINE_FILES += $(NPX_DIAG) $(WARM_VERIFIER) $(DSSERVE) diff --git a/platform/nephos/sai.mk b/platform/nephos/sai.mk index 93265dc74c56..5f7c4a23ae95 100644 --- a/platform/nephos/sai.mk +++ b/platform/nephos/sai.mk @@ -1,12 +1,35 @@ -SDK_VERSION = 2.0.8 -SAI_VERSION = 1.4.1 -SAI_COMMIT_ID = cbb99f +SDK_VERSION = 3.0.0 +SAI_VERSION = 1.5.0 +SAI_COMMIT_ID = 06a67d + +# Place here URL where SAI deb exist +NEPHOS_SAI_DEB_LOCAL_URL = +export NEPHOS_SAI_DEB_LOCAL_URL +# +ifneq ($(NEPHOS_SAI_DEB_LOCAL_URL), ) +SAI_FROM_LOCAL = y +else +SAI_FROM_LOCAL = n +endif + NEPHOS_SAI = libsainps_$(SDK_VERSION)_sai_$(SAI_VERSION)_$(SAI_COMMIT_ID)_amd64.deb +ifeq ($(SAI_FROM_LOCAL), y) +$(NEPHOS_SAI)_PATH = $(NEPHOS_SAI_DEB_LOCAL_URL) +else $(NEPHOS_SAI)_URL = "https://github.com/NephosInc/SONiC/raw/master/sai/libsainps_$(SDK_VERSION)_sai_$(SAI_VERSION)_$(SAI_COMMIT_ID)_amd64.deb" +endif NEPHOS_SAI_DEV = libsainps-dev_$(SDK_VERSION)_sai_$(SAI_VERSION)_$(SAI_COMMIT_ID)_amd64.deb $(eval $(call add_derived_package,$(NEPHOS_SAI),$(NEPHOS_SAI_DEV))) +ifeq ($(SAI_FROM_LOCAL), y) +$(NEPHOS_SAI_DEV)_PATH = $(NEPHOS_SAI_DEB_LOCAL_URL) +else $(NEPHOS_SAI_DEV)_URL = "https://github.com/NephosInc/SONiC/raw/master/sai/libsainps-dev_$(SDK_VERSION)_sai_$(SAI_VERSION)_$(SAI_COMMIT_ID)_amd64.deb" +endif +ifeq ($(SAI_FROM_LOCAL), y) +SONIC_COPY_DEBS += $(NEPHOS_SAI) $(NEPHOS_SAI_DEV) +else SONIC_ONLINE_DEBS += $(NEPHOS_SAI) $(NEPHOS_SAI_DEV) +endif $(NEPHOS_SAI_DEV)_DEPENDS += $(NEPHOS_SAI) diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/service/as7116-platform-init.service b/platform/nephos/sonic-platform-modules-accton/as7116-54x/service/as7116-platform-init.service index 4331c8828eea..6eaf4745210c 100755 --- a/platform/nephos/sonic-platform-modules-accton/as7116-54x/service/as7116-platform-init.service +++ b/platform/nephos/sonic-platform-modules-accton/as7116-54x/service/as7116-platform-init.service @@ -1,6 +1,7 @@ [Unit] Description=Accton AS7116-54X Platform initialization service Before=pmon.service +After=sysinit.target DefaultDependencies=no [Service] @@ -10,4 +11,4 @@ ExecStop=/usr/local/bin/accton_as7116_util.py clean RemainAfterExit=yes [Install] -WantedBy=multi-user.target \ No newline at end of file +WantedBy=multi-user.target diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/service/platform_api/platform_api_mgnt.sh b/platform/nephos/sonic-platform-modules-accton/as7116-54x/service/platform_api/platform_api_mgnt.sh new file mode 100755 index 000000000000..e1d330357894 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/as7116-54x/service/platform_api/platform_api_mgnt.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +PREV_REBOOT_CAUSE="/host/reboot-cause/" +DEVICE="/usr/share/sonic/device" +PLATFORM=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) +FILES=$DEVICE/$PLATFORM/api_files + +install() { + # Install sonic-platform package + if [ -e $DEVICE/$PLATFORM/sonic_platform-1.0-py2-none-any.whl ]; then + pip install $DEVICE/$PLATFORM/sonic_platform-1.0-py2-none-any.whl + fi +} + +init() { + # mount needed files for sonic-platform package + mkdir -p $FILES + + mkdir -p $FILES/reboot-cause + mount -B $PREV_REBOOT_CAUSE $FILES/reboot-cause +} + +deinit() { + # deinit sonic-platform package + umount -f $PREV_REBOOT_CAUSE $FILES/reboot-cause >/dev/null 2>/dev/null +} + +uninstall() { + # Uninstall sonic-platform package + pip uninstall -y sonic-platform >/dev/null 2>/dev/null +} + +case "$1" in +install | uninstall | init | deinit) + $1 + ;; +*) + echo "Usage: $0 {install|uninstall|init|deinit}" + exit 1 + ;; +esac diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/setup.py b/platform/nephos/sonic-platform-modules-accton/as7116-54x/setup.py index bb740409e310..088e1f30355a 100644 --- a/platform/nephos/sonic-platform-modules-accton/as7116-54x/setup.py +++ b/platform/nephos/sonic-platform-modules-accton/as7116-54x/setup.py @@ -1,15 +1,34 @@ -#!/usr/bin/env python - -import os -import sys from setuptools import setup -os.listdir -setup( - name='as7116-54x', - version='1.0.0', - description='Module to initialize Accton AS7116-54X platforms', +DEVICE_NAME = 'accton' +HW_SKU = 'x86_64-accton_as7116_54x-r0' - packages=['as7116-54x'], - package_dir={'as7116-54x': 'as7116-54x/classes'}, - ) +setup( + name='sonic-platform', + version='1.0', + description='SONiC platform API implementation on Accton Platforms', + license='Apache 2.0', + author='SONiC Team', + author_email='linuxnetdev@microsoft.com', + url='https://github.com/Azure/sonic-buildimage', + maintainer='Simon Ji', + maintainer_email='Simon.Ji@mediatek.com', + packages=[ + 'sonic_platform', + ], + package_dir={ + 'sonic_platform': '../../../device/{}/{}/sonic_platform'.format(DEVICE_NAME, HW_SKU)}, + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Plugins', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 2.7', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform PLATFORM', +) diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/utils/accton_as7116_util.py b/platform/nephos/sonic-platform-modules-accton/as7116-54x/utils/accton_as7116_util.py index 26a8a3cc8f84..2d9ea128f976 100755 --- a/platform/nephos/sonic-platform-modules-accton/as7116-54x/utils/accton_as7116_util.py +++ b/platform/nephos/sonic-platform-modules-accton/as7116-54x/utils/accton_as7116_util.py @@ -21,13 +21,13 @@ options: -h | --help : this help message -d | --debug : run with debug mode - -f | --force : ignore error during installation or clean + -f | --force : ignore error during installation or clean command: install : install drivers and generate related sysfs nodes clean : uninstall drivers and remove related sysfs nodes show : show all systen status sff : dump SFP eeprom - set : change board setting with fan|led|sfp + set : change board setting with fan|led|sfp """ import os @@ -46,7 +46,7 @@ verbose = False DEBUG = False args = [] -ALL_DEVICE = {} +ALL_DEVICE = {} DEVICE_NO = {'led':5, 'fan':1, 'thermal':3, 'psu':2, 'sfp':54} FORCE = 0 #logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) @@ -55,37 +55,37 @@ if DEBUG == True: print sys.argv[0] - print 'ARGV :', sys.argv[1:] + print 'ARGV :', sys.argv[1:] def main(): global DEBUG global args global FORCE - + if len(sys.argv)<2: show_help() - + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', 'debug', 'force', ]) - if DEBUG == True: + if DEBUG == True: print options print args print len(sys.argv) - + for opt, arg in options: if opt in ('-h', '--help'): show_help() - elif opt in ('-d', '--debug'): + elif opt in ('-d', '--debug'): DEBUG = True logging.basicConfig(level=logging.INFO) - elif opt in ('-f', '--force'): + elif opt in ('-f', '--force'): FORCE = 1 else: - logging.info('no option') - for arg in args: + logging.info('no option') + for arg in args: if arg == 'install': do_install() elif arg == 'clean': @@ -95,23 +95,23 @@ def main(): elif arg == 'sff': if len(args)!=2: show_eeprom_help() - elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: show_eeprom_help() else: - show_eeprom(args[1]) - return + show_eeprom(args[1]) + return elif arg == 'set': if len(args)<3: show_set_help() else: - set_device(args[1:]) - return + set_device(args[1:]) + return else: show_help() - - - return 0 - + + + return 0 + def show_help(): print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} sys.exit(0) @@ -120,36 +120,36 @@ def show_set_help(): cmd = sys.argv[0].split("/")[-1]+ " " + args[0] print cmd +" [led|sfp|fan]" print " use \""+ cmd + " led 0-4 \" to set led color" - print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" - print " use \""+ cmd + " sfp 1-54 {0|1}\" to set sfp# tx_disable" - sys.exit(0) - + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-54 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + def show_eeprom_help(): cmd = sys.argv[0].split("/")[-1]+ " " + args[0] - print " use \""+ cmd + " 1-54 \" to dump sfp# eeprom" - sys.exit(0) - + print " use \""+ cmd + " 1-54 \" to dump sfp# eeprom" + sys.exit(0) + def my_log(txt): if DEBUG == True: - print "[ROY]"+txt + print "[ROY]"+txt return - + def log_os_system(cmd, show): - logging.info('Run :'+cmd) - status, output = commands.getstatusoutput(cmd) + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) my_log (cmd +"with result:" + str(status)) - my_log (" output:"+output) + my_log (" output:"+output) if status: logging.info('Failed :'+cmd) if show: print('Failed :'+cmd) return status, output - + def driver_check(): ret, lsmod = log_os_system("lsmod| grep accton", 0) logging.info('mods:'+lsmod) if len(lsmod) ==0: - return False + return False return True @@ -169,19 +169,19 @@ def driver_install(): for i in range(0,len(kos)): status, output = log_os_system(kos[i], 1) if status: - if FORCE == 0: - return status + if FORCE == 0: + return status return 0 - + def driver_uninstall(): global FORCE for i in range(0,len(kos)): rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") - rm = rm.replace("insmod", "rmmod") + rm = rm.replace("insmod", "rmmod") status, output = log_os_system(rm, 1) if status: - if FORCE == 0: - return status + if FORCE == 0: + return status return 0 led_prefix ='/sys/class/leds/'+PROJECT_NAME+'_led::' @@ -192,13 +192,13 @@ def driver_uninstall(): i2c_prefix = '/sys/bus/i2c/devices/' i2c_bus = {'fan': ['1-0063'] , 'thermal': ['17-004b','19-0049', '20-004a'] , - 'psu': ['10-0050','11-0058'], + 'psu': ['10-0050','11-0058'], 'sfp': ['-0050']} i2c_nodes = {'fan': ['present', 'front_speed_rpm', 'rear_speed_rpm'] , 'thermal': ['hwmon/hwmon*/temp1_input'] , 'psu': ['psu_present ', 'psu_power_good'] , 'sfp': ['sfp_is_present ', 'sfp_tx_disable_all']} - + sfp_map = [37,38,39,40, 41,42,43,44,45,46,47,48,49,50, 51,52,53,54,55,56,57,58,59,60, @@ -234,23 +234,23 @@ def driver_uninstall(): def device_install(): global FORCE - + for i in range(0,len(mknod)): - #for pca954x need times to built new i2c buses + #for pca954x need times to built new i2c buses if mknod[i].find('pca954') != -1: time.sleep(1) - + status, output = log_os_system(mknod[i], 1) if status: print output - if FORCE == 0: + if FORCE == 0: return status - + for i in range(0,len(sfp_map)): status, output =log_os_system("echo as7116_54x_sfp"+str(i+1)+" 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) if status: print output - if FORCE == 0: + if FORCE == 0: return status if i <= 47: @@ -260,11 +260,11 @@ def device_install(): if FORCE == 0: return status - return - + return + def device_uninstall(): global FORCE - + status, output =log_os_system("ls /sys/bus/i2c/devices/1-0077", 0) for i in range(0,len(sfp_map)): @@ -272,11 +272,11 @@ def device_uninstall(): status, output =log_os_system("echo 0x50 > "+ target, 1) if status: print output - if FORCE == 0: + if FORCE == 0: return status - + nodelist = mknod - + for i in range(len(nodelist)): target = nodelist[-(i+1)] temp = target.split() @@ -285,72 +285,79 @@ def device_uninstall(): status, output = log_os_system(" ".join(temp), 1) if status: print output - if FORCE == 0: - return status - - return - + if FORCE == 0: + return status + + return + def system_ready(): if driver_check() == False: return False - if not device_exist(): + if not device_exist(): return False return True - + def do_install(): print "Checking system...." if driver_check() == False: - print "No driver, installing...." + print "No driver, installing...." status = driver_install() if status: - if FORCE == 0: + if FORCE == 0: return status else: - print PROJECT_NAME.upper()+" drivers detected...." + print PROJECT_NAME.upper()+" drivers detected...." if not device_exist(): - print "No device, installing...." - status = device_install() + print "No device, installing...." + status = device_install() if status: - if FORCE == 0: - return status + if FORCE == 0: + return status else: - print PROJECT_NAME.upper()+" devices detected...." + print PROJECT_NAME.upper()+" devices detected...." + + status, output = log_os_system( + "/bin/sh /usr/local/bin/platform_api_mgnt.sh init", 1) + if status: + print output + if FORCE == 0: + return status return - + def do_uninstall(): print "Checking system...." if not device_exist(): - print PROJECT_NAME.upper() +" has no device installed...." + print PROJECT_NAME.upper() +" has no device installed...." else: - print "Removing device...." - status = device_uninstall() + print "Removing device...." + status = device_uninstall() if status: - if FORCE == 0: - return status - + if FORCE == 0: + return status + if driver_check()== False : print PROJECT_NAME.upper() +" has no driver installed...." else: print "Removing installed driver...." status = driver_uninstall() if status: - if FORCE == 0: - return status - - return + if FORCE == 0: + return status + + return def devices_info(): global DEVICE_NO global ALL_DEVICE global i2c_bus, hwmon_types - for key in DEVICE_NO: - ALL_DEVICE[key]= {} + for key in DEVICE_NO: + ALL_DEVICE[key]= {} for i in range(0,DEVICE_NO[key]): ALL_DEVICE[key][key+str(i+1)] = [] - + for key in i2c_bus: buses = i2c_bus[key] - nodes = i2c_nodes[key] + nodes = i2c_nodes[key] for i in range(0,len(buses)): for j in range(0,len(nodes)): if 'fan' == key: @@ -358,52 +365,52 @@ def devices_info(): node = key+str(k+1) path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j] my_log(node+": "+ path) - ALL_DEVICE[key][node].append(path) + ALL_DEVICE[key][node].append(path) elif 'sfp' == key: for k in range(0,DEVICE_NO[key]): node = key+str(k+1) - path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] + path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] my_log(node+": "+ path) - ALL_DEVICE[key][node].append(path) + ALL_DEVICE[key][node].append(path) else: node = key+str(i+1) - path = i2c_prefix+ buses[i]+"/"+ nodes[j] + path = i2c_prefix+ buses[i]+"/"+ nodes[j] my_log(node+": "+ path) - ALL_DEVICE[key][node].append(path) - + ALL_DEVICE[key][node].append(path) + for key in hwmon_types: itypes = hwmon_types[key] - nodes = hwmon_nodes[key] + nodes = hwmon_nodes[key] for i in range(0,len(itypes)): - for j in range(0,len(nodes)): + for j in range(0,len(nodes)): node = key+"_"+itypes[i] - path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] my_log(node+": "+ path) - ALL_DEVICE[key][ key+str(i+1)].append(path) - + ALL_DEVICE[key][ key+str(i+1)].append(path) + #show dict all in the order if DEBUG == True: for i in sorted(ALL_DEVICE.keys()): print(i+": ") - for j in sorted(ALL_DEVICE[i].keys()): + for j in sorted(ALL_DEVICE[i].keys()): print(" "+j) - for k in (ALL_DEVICE[i][j]): + for k in (ALL_DEVICE[i][j]): print(" "+" "+k) - return - + return + def show_eeprom(index): if system_ready()==False: - print("System's not ready.") + print("System's not ready.") print("Please install first!") - return - + return + if len(ALL_DEVICE)==0: - devices_info() + devices_info() node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] node = node.replace(node.split("/")[-1], 'sfp_eeprom') # check if got hexdump command in current environment ret, log = log_os_system("which hexdump", 0) - ret, log2 = log_os_system("which busybox hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) if len(log): hex_cmd = 'hexdump' elif len(log2): @@ -412,111 +419,111 @@ def show_eeprom(index): log = 'Failed : no hexdump cmd!!' logging.info(log) print log - return 1 - + return 1 + print node + ":" ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) - if ret==0: - print log + if ret==0: + print log else: - print "**********device no found**********" - return - + print "**********device no found**********" + return + def set_device(args): global DEVICE_NO global ALL_DEVICE if system_ready()==False: - print("System's not ready.") + print("System's not ready.") print("Please install first!") - return - + return + if len(ALL_DEVICE)==0: - devices_info() - + devices_info() + if args[0]=='led': if int(args[1])>4: show_set_help() return #print ALL_DEVICE['led'] - for i in range(0,len(ALL_DEVICE['led'])): - for k in (ALL_DEVICE['led']['led'+str(i+1)]): + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): ret, log = log_os_system("echo "+args[1]+" >"+k, 1) if ret: - return ret + return ret elif args[0]=='fan': if int(args[1])>100: show_set_help() return #print ALL_DEVICE['fan'] - #fan1~6 is all fine, all fan share same setting - node = ALL_DEVICE['fan'] ['fan1'][0] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan'] ['fan1'][0] node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage') - ret, log = log_os_system("cat "+ node, 1) + ret, log = log_os_system("cat "+ node, 1) if ret==0: - print ("Previous fan duty: " + log.strip() +"%") + print ("Previous fan duty: " + log.strip() +"%") ret, log = log_os_system("echo "+args[1]+" >"+node, 1) if ret==0: - print ("Current fan duty: " + args[1] +"%") + print ("Current fan duty: " + args[1] +"%") return ret elif args[0]=='sfp': if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: show_set_help() - return + return if len(args)<2: show_set_help() - return - + return + if int(args[2])>1: show_set_help() return - - #print ALL_DEVICE[args[0]] - for i in range(0,len(ALL_DEVICE[args[0]])): - for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: - if j.find('tx_disable')!= -1: + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) if ret: - return ret - + return ret + return - -#get digits inside a string. -#Ex: 31 for "sfp31" + +#get digits inside a string. +#Ex: 31 for "sfp31" def get_value(input): digit = re.findall('\d+', input) return int(digit[0]) - + def device_traversal(): if system_ready()==False: - print("System's not ready.") + print("System's not ready.") print("Please install first!") - return - + return + if len(ALL_DEVICE)==0: devices_info() for i in sorted(ALL_DEVICE.keys()): - print("============================================") + print("============================================") print(i.upper()+": ") print("============================================") - - for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): print " "+j+":", for k in (ALL_DEVICE[i][j]): ret, log = log_os_system("cat "+k, 0) func = k.split("/")[-1].strip() func = re.sub(j+'_','',func,1) - func = re.sub(i.lower()+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) if ret==0: - print func+"="+log+" ", + print func+"="+log+" ", else: print func+"="+"X"+" ", - print + print print("----------------------------------------------------------------") - - + + print return - + def device_exist(): ret1, log = log_os_system("ls "+i2c_prefix+"*0077", 0) ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0) diff --git a/platform/nephos/sonic-platform-modules-accton/debian/rules b/platform/nephos/sonic-platform-modules-accton/debian/rules index 44caba25cfa2..de84b23d55ae 100755 --- a/platform/nephos/sonic-platform-modules-accton/debian/rules +++ b/platform/nephos/sonic-platform-modules-accton/debian/rules @@ -1,19 +1,8 @@ #!/usr/bin/make -f -# -*- makefile -*- -# Sample debian/rules that uses debhelper. -# This file was originally written by Joey Hess and Craig Small. -# As a special exception, when this file is copied by dh-make into a -# dh-make output file, you may use that output file without restriction. -# This special exception was added by Craig Small in version 0.37 of dh-make. - -include /usr/share/dpkg/pkg-info.mk - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 export INSTALL_MOD_DIR:=extra -PYTHON ?= python2 +PYTHON ?= python2.7 PACKAGE_PRE_NAME := sonic-platform-accton KVERSION ?= $(shell uname -r) @@ -27,60 +16,25 @@ CLASSES_DIR := classes CONF_DIR := conf %: - dh $@ --with systemd,python2,python3 --buildsystem=pybuild - -clean: - dh_testdir - dh_testroot - dh_clean + dh $@ -build: - #make modules -C $(KERNEL_SRC)/build M=$(MODULE_SRC) +override_dh_auto_build: (for mod in $(MODULE_DIRS); do \ make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ - $(PYTHON) $${mod}/setup.py build; \ + $(PYTHON) $${mod}/setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ done) -binary: binary-arch binary-indep - # Nothing to do - -binary-arch: - # Nothing to do - -#install: build - #dh_testdir - #dh_testroot - #dh_clean -k - #dh_installdirs +override_dh_auto_install: + (for mod in $(MODULE_DIRS); do \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko \ + debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + done) -binary-indep: - dh_testdir - dh_installdirs +override_dh_usrlocal: - # Custom package commands +override_dh_clean: + dh_clean (for mod in $(MODULE_DIRS); do \ - dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ - dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /usr/local/bin; \ - dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /lib/systemd/system; \ - cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ - cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \ - cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \ - $(PYTHON) $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \ done) - # Resuming debhelper scripts - dh_testroot - dh_install - dh_installchangelogs - dh_installdocs - dh_systemd_enable - dh_installinit - dh_systemd_start - dh_link - dh_fixperms - dh_compress - dh_strip - dh_installdeb - dh_gencontrol - dh_md5sums - dh_builddeb -.PHONY: build binary binary-arch binary-indep clean \ No newline at end of file diff --git a/platform/nephos/sonic-platform-modules-accton/debian/sonic-platform-accton-as7116-54x.install b/platform/nephos/sonic-platform-modules-accton/debian/sonic-platform-accton-as7116-54x.install new file mode 100644 index 000000000000..61423affe7ac --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/debian/sonic-platform-accton-as7116-54x.install @@ -0,0 +1,4 @@ +as7116-54x/utils/* usr/local/bin +as7116-54x/service/*.service lib/systemd/system +as7116-54x/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-accton_as7116_54x-r0 +as7116-54x/service/platform_api/platform_api_mgnt.sh usr/local/bin diff --git a/platform/nephos/sonic-platform-modules-accton/debian/sonic-platform-accton-as7116-54x.postinst b/platform/nephos/sonic-platform-modules-accton/debian/sonic-platform-accton-as7116-54x.postinst new file mode 100644 index 000000000000..a9947af877b6 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/debian/sonic-platform-accton-as7116-54x.postinst @@ -0,0 +1,5 @@ +depmod -a +systemctl enable as7116-platform-init.service +systemctl start as7116-platform-init.service + +/usr/local/bin/platform_api_mgnt.sh install diff --git a/platform/p4/docker-sonic-p4/supervisord.conf b/platform/p4/docker-sonic-p4/supervisord.conf index 008f4c82d2c9..946e4cb36e3a 100644 --- a/platform/p4/docker-sonic-p4/supervisord.conf +++ b/platform/p4/docker-sonic-p4/supervisord.conf @@ -61,7 +61,7 @@ stdout_logfile=syslog stderr_logfile=syslog [program:portsyncd] -command=/usr/bin/portsyncd -p /port_config.ini +command=/usr/bin/portsyncd priority=6 autostart=false autorestart=false diff --git a/platform/template/docker-syncd-base.mk b/platform/template/docker-syncd-base.mk index d8776d179a02..cefcf15ebd62 100644 --- a/platform/template/docker-syncd-base.mk +++ b/platform/template/docker-syncd-base.mk @@ -7,6 +7,8 @@ DOCKER_SYNCD_BASE_DBG = $(DOCKER_SYNCD_BASE_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_SYNCD_BASE)_PATH = $(PLATFORM_PATH)/docker-syncd-$(DOCKER_SYNCD_PLATFORM_CODE) +$(DOCKER_SYNCD_BASE)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) + $(DOCKER_SYNCD_BASE)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) diff --git a/platform/vs/README.gns3.md b/platform/vs/README.gns3.md new file mode 100644 index 000000000000..c434d5e9b405 --- /dev/null +++ b/platform/vs/README.gns3.md @@ -0,0 +1,17 @@ +HOWTO Create a GNS3 Appliance File (.gns3a) + + +Execute the command sonic-gns3.sh + + +For instance: + +./sonic-gns3a.sh -h + +sonic-gns3a.sh [ -r ] -b +e.g.: sonic-gns3a.sh -r 1.1 -b /sonic-vs.img + +For more information about GNS3, please refer to: + +https://gns3.com/ + diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 85db514d77bb..7cc6f98921ff 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -106,6 +106,7 @@ COPY ["files/configdb-load.sh", "/usr/bin/"] COPY ["files/arp_update", "/usr/bin/"] COPY ["files/buffers_config.j2", "files/qos_config.j2", "/usr/share/sonic/templates/"] COPY ["files/sonic_version.yml", "/etc/sonic/"] +COPY ["database_config.json", "/etc/default/sonic-db/"] # Workaround the tcpdump issue RUN mv /usr/sbin/tcpdump /usr/bin/tcpdump diff --git a/platform/vs/docker-sonic-vs/database_config.json b/platform/vs/docker-sonic-vs/database_config.json new file mode 100644 index 000000000000..b86ae11bba98 --- /dev/null +++ b/platform/vs/docker-sonic-vs/database_config.json @@ -0,0 +1,57 @@ +{ + "INSTANCES": { + "redis":{ + "hostname" : "127.0.0.1", + "port" : 6379, + "unix_socket_path" : "/var/run/redis/redis.sock" + } + }, + "DATABASES" : { + "APPL_DB" : { + "id" : 0, + "separator": ":", + "instance" : "redis" + }, + "ASIC_DB" : { + "id" : 1, + "separator": ":", + "instance" : "redis" + }, + "COUNTERS_DB" : { + "id" : 2, + "separator": ":", + "instance" : "redis" + }, + "LOGLEVEL_DB" : { + "id" : 3, + "separator": ":", + "instance" : "redis" + }, + "CONFIG_DB" : { + "id" : 4, + "separator": "|", + "instance" : "redis" + }, + "PFC_WD_DB" : { + "id" : 5, + "separator": ":", + "instance" : "redis" + }, + "FLEX_COUNTER_DB" : { + "id" : 5, + "separator": ":", + "instance" : "redis" + }, + "STATE_DB" : { + "id" : 6, + "separator": "|", + "instance" : "redis" + }, + "SNMP_OVERLAY_DB" : { + "id" : 7, + "separator": "|", + "instance" : "redis" + } + }, + "VERSION" : "1.0" +} diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index 3aaefa291fb2..614541961c87 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -18,7 +18,7 @@ if [ -f /etc/sonic/config_db.json ]; then else # generate and merge buffers configuration into config file sonic-cfggen -t /usr/share/sonic/hwsku/buffers.json.j2 > /tmp/buffers.json - sonic-cfggen -t /usr/share/sonic/hwsku/qos.json.j2 > /tmp/qos.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 fi @@ -29,7 +29,8 @@ rm -f /var/run/rsyslogd.pid supervisorctl start rsyslogd -mkdir -p /var/run/redis +mkdir -p /var/run/redis/sonic-db +cp /etc/default/sonic-db/database_config.json /var/run/redis/sonic-db/ supervisorctl start redis-server @@ -67,6 +68,8 @@ supervisorctl start nbrmgrd supervisorctl start vxlanmgrd +supervisorctl start sflowmgrd + # Start arp_update when VLAN exists VLAN=`sonic-cfggen -d -v 'VLAN.keys() | join(" ") if VLAN'` if [ "$VLAN" != "" ]; then diff --git a/platform/vs/docker-sonic-vs/supervisord.conf b/platform/vs/docker-sonic-vs/supervisord.conf index 2010dc918e0a..143fe49d44a9 100644 --- a/platform/vs/docker-sonic-vs/supervisord.conf +++ b/platform/vs/docker-sonic-vs/supervisord.conf @@ -44,7 +44,7 @@ stdout_logfile=syslog stderr_logfile=syslog [program:portsyncd] -command=/usr/bin/portsyncd -p /usr/share/sonic/hwsku/port_config.ini +command=/usr/bin/portsyncd priority=6 autostart=false autorestart=false @@ -180,3 +180,11 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog + +[program:sflowmgrd] +command=/usr/bin/sflowmgrd +priority=22 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog diff --git a/platform/vs/docker-syncd-vs/Dockerfile.j2 b/platform/vs/docker-syncd-vs/Dockerfile.j2 index 6c5e90fa877b..070d8b984f4b 100644 --- a/platform/vs/docker-syncd-vs/Dockerfile.j2 +++ b/platform/vs/docker-syncd-vs/Dockerfile.j2 @@ -8,6 +8,8 @@ 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 + COPY \ {% for deb in docker_syncd_vs_debs.split(' ') -%} debs/{{ deb }}{{' '}} diff --git a/platform/vs/sonic-gns3a.sh b/platform/vs/sonic-gns3a.sh new file mode 100644 index 000000000000..57c63fb75f32 --- /dev/null +++ b/platform/vs/sonic-gns3a.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +# This script creates a .gns3a SONiC appliance file +IMGFILE="sonic-vs.image" +RELEASE="latest" + +usage() { + echo "`basename $0` [ -r ] -b " + echo "e.g.: `basename $0` -r 1.1 -b /sonic-vs.image" + exit 0 +} + +while getopts "r:b:h" arg; do + case $arg in + h) + usage + ;; + r) + RELEASE=$OPTARG + ;; + b) + IMGFILE=$OPTARG + ;; + esac +done + +if [ ! -e ${IMGFILE} ]; then + echo "ERROR: ${IMGFILE} not found" + exit 2 +fi + + +MD5SUMIMGFILE=`md5sum ${IMGFILE} | cut -f 1 -d " "` +LENIMGFILE=`stat -c %s ${IMGFILE}` +GNS3APPNAME="SONiC-${RELEASE}.gns3a" +NAMEIMGFILE=`basename $IMGFILE` + +echo " +{ + \"name\": \"SONiC\", + \"category\": \"router\", + \"description\": \"SONiC Virtual Switch/Router\n\", + \"vendor_name\": \"SONiC\", + \"vendor_url\": \"https://azure.github.io/SONiC/\", + \"product_name\": \"SONiC\", + \"product_url\": \"https://azure.github.io/SONiC/\", + \"registry_version\": 3, + \"status\": \"experimental\", + \"maintainer\": \"SONiC\", + \"maintainer_email\": \"sonicproject@googlegroups.com\", + \"usage\": \"Supports SONiC release: ${RELEASE}\", + \"qemu\": { + \"adapter_type\": \"e1000\", + \"adapters\": 10, + \"ram\": 2048, + \"hda_disk_interface\": \"virtio\", + \"arch\": \"x86_64\", + \"console_type\": \"telnet\", + \"boot_priority\": \"d\", + \"kvm\": \"require\" + }, + \"images\": [ + { + \"filename\": \"${NAMEIMGFILE}\", + \"version\": \"${RELEASE}\", + \"md5sum\": \"${MD5SUMIMGFILE}\", + \"filesize\": ${LENIMGFILE} + } + ], + \"versions\": [ + { + \"name\": \"${RELEASE}\", + \"images\": { + \"hda_disk_image\": \"${NAMEIMGFILE}\" + } + } + ] +} + +" > ${GNS3APPNAME} + diff --git a/rules/config b/rules/config index 31e5d40ff1f9..04af59ccd818 100644 --- a/rules/config +++ b/rules/config @@ -52,9 +52,9 @@ DEFAULT_PASSWORD = YourPaSsWoRd # by default for TOR switch # ENABLE_PFCWD_ON_START = y -# SONIC_INSTALL_DEBUG_TOOLS - installs debugging tools in baseline docker +# INSTALL_DEBUG_TOOLS - installs debugging tools in baseline docker # Uncomment next line to enable: -# SONIC_INSTALL_DEBUG_TOOLS = y +# INSTALL_DEBUG_TOOLS = y # SONIC_ROUTING_STACK - specify the routing-stack being elected to drive SONiC's control-plane. # Supported routing stacks on SONiC are: @@ -95,3 +95,6 @@ FRR_USER_GID = 300 # Default VS build memory preparation DEFAULT_VS_PREPARE_MEM = yes + +# ENABLE_SYSTEM_SFLOW - build docker-sonic-sflow for sFlow support +ENABLE_SFLOW = y diff --git a/rules/docker-dhcp-relay.mk b/rules/docker-dhcp-relay.mk index 6fad19cc1998..5aae24ee33b5 100644 --- a/rules/docker-dhcp-relay.mk +++ b/rules/docker-dhcp-relay.mk @@ -25,3 +25,4 @@ SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_DHCP_RELAY_DBG) $(DOCKER_DHCP_RELAY)_CONTAINER_NAME = dhcp_relay $(DOCKER_DHCP_RELAY)_RUN_OPT += --net=host --privileged -t $(DOCKER_DHCP_RELAY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_DHCP_RELAY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-lldp-sv2.mk b/rules/docker-lldp-sv2.mk index a4bb04047bf4..91acbe58ad82 100644 --- a/rules/docker-lldp-sv2.mk +++ b/rules/docker-lldp-sv2.mk @@ -29,3 +29,5 @@ $(DOCKER_LLDP_SV2)_RUN_OPT += --net=host --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)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-platform-monitor.mk b/rules/docker-platform-monitor.mk index 8a4c9391f8aa..7a319e4bf120 100644 --- a/rules/docker-platform-monitor.mk +++ b/rules/docker-platform-monitor.mk @@ -38,6 +38,10 @@ $(DOCKER_PLATFORM_MONITOR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro # Mount Arista python library on Aboot images to be used by plugins $(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python2.7/dist-packages/arista:/usr/lib/python2.7/dist-packages/arista:ro +$(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python2.7/dist-packages/arista/utils/sonic_platform:/usr/lib/python2.7/dist-packages/sonic_platform:ro -$(DOCKER_PLATFORM_MONITOR)_BASE_IMAGE_FILES += sensors:/usr/bin/sensors -$(DOCKER_PLATFORM_MONITOR)_BASE_IMAGE_FILES += smartctl:/usr/sbin/smartctl +$(DOCKER_PLATFORM_MONITOR)_BASE_IMAGE_FILES += cmd_wrapper:/usr/bin/sensors +$(DOCKER_PLATFORM_MONITOR)_BASE_IMAGE_FILES += cmd_wrapper:/usr/sbin/smartctl +$(DOCKER_PLATFORM_MONITOR)_BASE_IMAGE_FILES += cmd_wrapper:/usr/sbin/iSmart +$(DOCKER_PLATFORM_MONITOR)_BASE_IMAGE_FILES += cmd_wrapper:/usr/sbin/SmartCmd +$(DOCKER_PLATFORM_MONITOR)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-router-advertiser.mk b/rules/docker-router-advertiser.mk index 93dc0285585c..53e0d7600ec9 100644 --- a/rules/docker-router-advertiser.mk +++ b/rules/docker-router-advertiser.mk @@ -25,3 +25,4 @@ SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_ROUTER_ADVERTISER_DBG) $(DOCKER_ROUTER_ADVERTISER)_CONTAINER_NAME = radv $(DOCKER_ROUTER_ADVERTISER)_RUN_OPT += --net=host --privileged -t $(DOCKER_ROUTER_ADVERTISER)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_ROUTER_ADVERTISER)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-sflow.mk b/rules/docker-sflow.mk new file mode 100644 index 000000000000..94b568481885 --- /dev/null +++ b/rules/docker-sflow.mk @@ -0,0 +1,35 @@ +# docker image for sFlow agent + +DOCKER_SFLOW_STEM = docker-sflow +DOCKER_SFLOW = $(DOCKER_SFLOW_STEM).gz +DOCKER_SFLOW_DBG = $(DOCKER_SFLOW_STEM)-$(DBG_IMAGE_MARK).gz + +$(DOCKER_SFLOW)_PATH = $(DOCKERS_PATH)/$(DOCKER_SFLOW_STEM) + +$(DOCKER_SFLOW)_DEPENDS += $(SWSS) $(REDIS_TOOLS) $(HSFLOWD) $(SFLOWTOOL) $(PSAMPLE) +$(DOCKER_SFLOW)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_TEAMD)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) +$(DOCKER_SFLOW)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) + +$(DOCKER_SFLOW)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) + +SONIC_DOCKER_IMAGES += $(DOCKER_SFLOW) +ifeq ($(ENABLE_SFLOW), y) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SFLOW) +SONIC_STRETCH_DOCKERS += $(DOCKER_SFLOW) +endif + +SONIC_DOCKER_DBG_IMAGES += $(DOCKER_SFLOW_DBG) +ifeq ($(ENABLE_SFLOW), y) +SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_SFLOW_DBG) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SFLOW_DBG) +endif + +$(DOCKER_SFLOW)_CONTAINER_NAME = sflow +$(DOCKER_SFLOW)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SFLOW)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_SFLOW)_RUN_OPT += -v /host/warmboot:/var/warmboot + +$(DOCKER_SFLOW)_BASE_IMAGE_FILES += psample:/usr/bin/psample +$(DOCKER_SFLOW)_BASE_IMAGE_FILES += sflowtool:/usr/bin/sflowtool +$(DOCKER_SFLOW)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-snmp-sv2.mk b/rules/docker-snmp-sv2.mk index 2a533b436191..bd34f271b861 100644 --- a/rules/docker-snmp-sv2.mk +++ b/rules/docker-snmp-sv2.mk @@ -30,3 +30,4 @@ $(DOCKER_SNMP_SV2)_RUN_OPT += --net=host --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) diff --git a/rules/docker-teamd.mk b/rules/docker-teamd.mk index a697ce6b8891..598eff97e8f1 100644 --- a/rules/docker-teamd.mk +++ b/rules/docker-teamd.mk @@ -29,3 +29,4 @@ $(DOCKER_TEAMD)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_TEAMD)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_TEAMD)_BASE_IMAGE_FILES += teamdctl:/usr/bin/teamdctl +$(DOCKER_TEAMD)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-telemetry.mk b/rules/docker-telemetry.mk index 44c835373e04..799bef1b1735 100644 --- a/rules/docker-telemetry.mk +++ b/rules/docker-telemetry.mk @@ -29,3 +29,4 @@ $(DOCKER_TELEMETRY)_RUN_OPT += --net=host --privileged -t $(DOCKER_TELEMETRY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_TELEMETRY)_RUN_OPT += --mount type=bind,source="/var/platform/",target="/mnt/platform/" +$(DOCKER_TELEMETRY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/frr.mk b/rules/frr.mk index a14d398f89a1..27391ce0cf73 100644 --- a/rules/frr.mk +++ b/rules/frr.mk @@ -1,6 +1,6 @@ # FRRouting (frr) package -FRR_VERSION = 7.0.1 +FRR_VERSION = 7.2 FRR_SUBVERSION = 0 export FRR_VERSION FRR_SUBVERSION diff --git a/rules/kdump-tools.mk b/rules/kdump-tools.mk new file mode 100644 index 000000000000..d5d2630389f3 --- /dev/null +++ b/rules/kdump-tools.mk @@ -0,0 +1,13 @@ +# kdump-tools package + +KDUMP_TOOLS_VERSION_BASE = 1.6.1 +KDUMP_TOOLS_VERSION = $(KDUMP_TOOLS_VERSION_BASE)-1 +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 2561be6b7122..d10c2ea2cc66 100644 --- a/rules/libyang.mk +++ b/rules/libyang.mk @@ -1,23 +1,32 @@ # libyang -LIBYANG_VERSION_BASE = 0.16 -LIBYANG_VERSION = $(LIBYANG_VERSION_BASE).105 +LIBYANG_VERSION_BASE = 1.0 +LIBYANG_VERSION = $(LIBYANG_VERSION_BASE).73 LIBYANG_SUBVERSION = 1 export LIBYANG_VERSION_BASE export LIBYANG_VERSION export LIBYANG_SUBVERSION -LIBYANG = libyang$(LIBYANG_VERSION_BASE)_$(LIBYANG_VERSION)-$(LIBYANG_SUBVERSION)_$(CONFIGURED_ARCH).deb +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)-$(LIBYANG_SUBVERSION)_$(CONFIGURED_ARCH).deb +LIBYANG_DEV = libyang-dev_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LIBYANG),$(LIBYANG_DEV))) -LIBYANG_DBG = libyang$(LIBYANG_VERSION_BASE)-dbgsym_$(LIBYANG_VERSION)-$(LIBYANG_SUBVERSION)_$(CONFIGURED_ARCH).deb +LIBYANG_DBG = libyang-dbg_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LIBYANG),$(LIBYANG_DBG))) -export LIBYANG LIBYANG_DEV LIBYANG_DBG +LIBYANG_CPP = libyang-cpp_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(LIBYANG),$(LIBYANG_CPP))) + +LIBYANG_PY3 = python3-yang_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(LIBYANG),$(LIBYANG_PY3))) + +LIBYANG_PY2 = python2-yang_$(LIBYANG_VERSION)_$(CONFIGURED_ARCH).deb +$(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 fd8429eb8f3b..5250f8b97e8f 100644 --- a/rules/linux-kernel.mk +++ b/rules/linux-kernel.mk @@ -3,7 +3,11 @@ KVERSION_SHORT = 4.9.0-9-2 KVERSION = $(KVERSION_SHORT)-$(CONFIGURED_ARCH) KERNEL_VERSION = 4.9.168 -KERNEL_SUBVERSION = 1+deb9u3 +KERNEL_SUBVERSION = 1+deb9u5 +ifeq ($(CONFIGURED_ARCH), armhf) +# Override kernel version for ARMHF as it uses arm MP (multi-platform) for short version +KVERSION = $(KVERSION_SHORT)-armmp +endif export KVERSION_SHORT KVERSION KERNEL_VERSION KERNEL_SUBVERSION diff --git a/rules/sflow.mk b/rules/sflow.mk new file mode 100644 index 000000000000..f267353c0f93 --- /dev/null +++ b/rules/sflow.mk @@ -0,0 +1,49 @@ +# host-sflow package + +HSFLOWD_VERSION = 2.0.26 +HSFLOWD_SUBVERSION = 1 +export HSFLOWD_VERSION HSFLOWD_SUBVERSION + +HSFLOWD = hsflowd_$(HSFLOWD_VERSION)-$(HSFLOWD_SUBVERSION)_$(CONFIGURED_ARCH).deb +$(HSFLOWD)_DEPENDS += $(LIBHIREDIS_DEV) $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(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) +$(HSFLOWD_DBG)_RDEPENDS += $(HSFLOWD) +$(eval $(call add_derived_package,$(HSFLOWD),$(HSFLOWD_DBG))) + +export HSFLOWD HSFLOWD_DBG + +# sflowtool package + +SFLOWTOOL_VERSION = 5.04 +export SFLOWTOOL_VERSION + +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 + +PSAMPLE_VERSION = 1.1 +PSAMPLE_SUBVERSION = 1 +export PSAMPLE_VERSION PSAMPLE_SUBVERSION + +PSAMPLE = psample_$(PSAMPLE_VERSION)-$(PSAMPLE_SUBVERSION)_$(CONFIGURED_ARCH).deb +$(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} +# are archived into debug one image to facilitate debugging. +# +DBG_SRC_ARCHIVE += sflow diff --git a/rules/sonic-daemon-base.mk b/rules/sonic-daemon-base.mk index dad0900e75ca..5385c18f1f12 100644 --- a/rules/sonic-daemon-base.mk +++ b/rules/sonic-daemon-base.mk @@ -5,3 +5,4 @@ $(SONIC_DAEMON_BASE_PY2)_SRC_PATH = $(SRC_PATH)/sonic-daemon-base $(SONIC_DAEMON_BASE_PY2)_PYTHON_VERSION = 2 SONIC_PYTHON_WHEELS += $(SONIC_DAEMON_BASE_PY2) +export daemon_base_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_DAEMON_BASE_PY2))" diff --git a/rules/sonic-platform-common.mk b/rules/sonic-platform-common.mk index 95789354a4da..043c820743aa 100644 --- a/rules/sonic-platform-common.mk +++ b/rules/sonic-platform-common.mk @@ -6,8 +6,9 @@ $(SONIC_PLATFORM_COMMON_PY2)_PYTHON_VERSION = 2 SONIC_PYTHON_WHEELS += $(SONIC_PLATFORM_COMMON_PY2) # Als build sonic-platform-common into python3 wheel, so we can use PSU code in SNMP docker -# Note: _DEPENDS macro is not defined SONIC_PLATFORM_COMMON_PY3 = sonic_platform_common-1.0-py3-none-any.whl $(SONIC_PLATFORM_COMMON_PY3)_SRC_PATH = $(SRC_PATH)/sonic-platform-common $(SONIC_PLATFORM_COMMON_PY3)_PYTHON_VERSION = 3 +# Synthetic dependency just to avoid race condition +$(SONIC_PLATFORM_COMMON_PY3)_DEPENDS = $(SONIC_PLATFORM_COMMON_PY2) SONIC_PYTHON_WHEELS += $(SONIC_PLATFORM_COMMON_PY3) diff --git a/build_kvm_image.sh b/scripts/build_kvm_image.sh similarity index 99% rename from build_kvm_image.sh rename to scripts/build_kvm_image.sh index bc0f54e12d5c..a8ae21c9777a 100755 --- a/build_kvm_image.sh +++ b/scripts/build_kvm_image.sh @@ -4,7 +4,7 @@ # # SPDX-License-Identifier: GPL-2.0 -MEM=2048 +MEM=3072 DISK=$1 ONIE_RECOVERY_ISO=$2 INSTALLER=$3 diff --git a/scripts/dbg_files.sh b/scripts/dbg_files.sh index 1515639bc9d7..6624fca83f34 100755 --- a/scripts/dbg_files.sh +++ b/scripts/dbg_files.sh @@ -2,8 +2,11 @@ # Provide file paths to archive for debug image as relative to src subdir # -for i in $debug_src_archive -do - find $i/ -name "*.c" -o -name "*.cpp" -o -name "*.h" -o -name "*.hpp" -type f -done +if [ "$DEBUG_IMG" == "y" ] +then + for i in $DEBUG_SRC_ARCHIVE_DIRS + do + find src/$i/ -name "*.c" -o -name "*.cpp" -o -name "*.h" -o -name "*.hpp" -type f + done | tar -czf $DEBUG_SRC_ARCHIVE_FILE -T - +fi diff --git a/slave.mk b/slave.mk index 162c167ebf82..f81895f74dd2 100644 --- a/slave.mk +++ b/slave.mk @@ -37,6 +37,7 @@ PROJECT_ROOT = $(shell pwd) STRETCH_DEBS_PATH = $(TARGET_PATH)/debs/stretch STRETCH_FILES_PATH = $(TARGET_PATH)/files/stretch DBG_IMAGE_MARK = dbg +DBG_SRC_ARCHIVE_FILE = $(TARGET_PATH)/sonic_src.tar.gz CONFIGURED_PLATFORM := $(shell [ -f .platform ] && cat .platform || echo generic) PLATFORM_PATH = platform/$(CONFIGURED_PLATFORM) @@ -107,6 +108,10 @@ ifeq ($(SONIC_INSTALL_DEBUG_TOOLS),y) INSTALL_DEBUG_TOOLS = y endif +ifeq ($(SONIC_ENABLE_SFLOW),y) +ENABLE_SFLOW = y +endif + include $(RULES_PATH)/functions include $(RULES_PATH)/*.mk ifneq ($(CONFIGURED_PLATFORM), undefined) @@ -191,6 +196,7 @@ $(info "KERNEL_PROCURE_METHOD" : "$(KERNEL_PROCURE_METHOD)") $(info "BUILD_TIMESTAMP" : "$(BUILD_TIMESTAMP)") $(info "BLDENV" : "$(BLDENV)") $(info "VS_PREPARE_MEM" : "$(VS_PREPARE_MEM)") +$(info "ENABLE_SFLOW" : "$(ENABLE_SFLOW)") $(info ) ifeq ($(SONIC_USE_DOCKER_BUILDKIT),y) @@ -608,6 +614,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(SONIC_DEVICE_DATA) \ $(PYTHON_CLICK) \ $(IFUPDOWN2) \ + $(KDUMP_TOOLS) \ $(LIBPAM_TACPLUS) \ $(LIBNSS_TACPLUS)) \ $$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \ @@ -616,7 +623,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(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)/,$(REDIS_DUMP_LOAD_PY2)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2)) $(HEADER) # Pass initramfs and linux kernel explicitly. They are used for all platforms export debs_path="$(STRETCH_DEBS_PATH)" @@ -667,9 +675,13 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ chmod +x sonic_debian_extension.sh, ) - export debug_src_archive="$(DBG_SRC_ARCHIVE)" + DEBUG_IMG="$(INSTALL_DEBUG_TOOLS)" \ + DEBUG_SRC_ARCHIVE_DIRS="$(DBG_SRC_ARCHIVE)" \ + DEBUG_SRC_ARCHIVE_FILE="$(DBG_SRC_ARCHIVE_FILE)" \ + scripts/dbg_files.sh DEBUG_IMG="$(INSTALL_DEBUG_TOOLS)" \ + DEBUG_SRC_ARCHIVE_FILE="$(DBG_SRC_ARCHIVE_FILE)" \ USERNAME="$(USERNAME)" \ PASSWORD="$(PASSWORD)" \ ./build_debian.sh $(LOG) @@ -703,7 +715,6 @@ SONIC_CLEAN_DEBS = $(addsuffix -clean,$(addprefix $(DEBS_PATH)/, \ $(SONIC_COPY_DEBS) \ $(SONIC_MAKE_DEBS) \ $(SONIC_DPKG_DEBS) \ - $(SONIC_PYTHON_STDEB_DEBS) \ $(SONIC_DERIVED_DEBS) \ $(SONIC_EXTRA_DEBS))) @@ -728,15 +739,20 @@ SONIC_CLEAN_TARGETS += $(addsuffix -clean,$(addprefix $(TARGET_PATH)/, \ $(SONIC_CLEAN_TARGETS) : $(TARGET_PATH)/%-clean : .platform @rm -f $(TARGET_PATH)/$* +SONIC_CLEAN_STDEB_DEBS = $(addsuffix -clean,$(addprefix $(PYTHON_DEBS_PATH)/, \ + $(SONIC_PYTHON_STDEB_DEBS))) +$(SONIC_CLEAN_STDEB_DEBS) : $(PYTHON_DEBS_PATH)/%-clean : .platform + @rm -f $(PYTHON_DEBS_PATH)/$* + SONIC_CLEAN_WHEELS = $(addsuffix -clean,$(addprefix $(PYTHON_WHEELS_PATH)/, \ $(SONIC_PYTHON_WHEELS))) $(SONIC_CLEAN_WHEELS) : $(PYTHON_WHEELS_PATH)/%-clean : .platform @rm -f $(PYTHON_WHEELS_PATH)/$* clean-logs : .platform - @rm -f $(TARGET_PATH)/*.log $(DEBS_PATH)/*.log $(FILES_PATH)/*.log $(PYTHON_WHEELS_PATH)/*.log + @rm -f $(TARGET_PATH)/*.log $(DEBS_PATH)/*.log $(FILES_PATH)/*.log $(PYTHON_DEBS_PATH)/*.log $(PYTHON_WHEELS_PATH)/*.log -clean : .platform clean-logs $$(SONIC_CLEAN_DEBS) $$(SONIC_CLEAN_FILES) $$(SONIC_CLEAN_TARGETS) $$(SONIC_CLEAN_WHEELS) +clean : .platform clean-logs $$(SONIC_CLEAN_DEBS) $$(SONIC_CLEAN_FILES) $$(SONIC_CLEAN_TARGETS) $$(SONIC_CLEAN_STDEB_DEBS) $$(SONIC_CLEAN_WHEELS) ############################################################################### ## all @@ -755,6 +771,6 @@ jessie : $$(addprefix $(TARGET_PATH)/,$$(SONIC_JESSIE_DOCKERS_FOR_INSTALLERS)) ## Standard targets ############################################################################### -.PHONY : $(SONIC_CLEAN_DEBS) $(SONIC_CLEAN_FILES) $(SONIC_CLEAN_TARGETS) $(SONIC_CLEAN_WHEELS) $(SONIC_PHONY_TARGETS) clean distclean configure +.PHONY : $(SONIC_CLEAN_DEBS) $(SONIC_CLEAN_FILES) $(SONIC_CLEAN_TARGETS) $(SONIC_CLEAN_STDEB_DEBS) $(SONIC_CLEAN_WHEELS) $(SONIC_PHONY_TARGETS) clean distclean configure .INTERMEDIATE : $(SONIC_INSTALL_TARGETS) $(SONIC_INSTALL_WHEELS) $(DOCKER_LOAD_TARGETS) docker-start .platform diff --git a/sonic-slave/Dockerfile.j2 b/sonic-slave-jessie/Dockerfile.j2 similarity index 99% rename from sonic-slave/Dockerfile.j2 rename to sonic-slave-jessie/Dockerfile.j2 index 91ed039a2d64..7ed7c4eb7096 100644 --- a/sonic-slave/Dockerfile.j2 +++ b/sonic-slave-jessie/Dockerfile.j2 @@ -150,7 +150,7 @@ RUN apt-get update && apt-get install -y \ zip \ {%- if CONFIGURED_ARCH == "amd64" %} # For broadcom sdk build - linux-compiler-gcc-4.8-x86 \ + linux-compiler-gcc-4.9-x86 \ {%- endif %} linux-kbuild-3.16 \ # teamd build @@ -295,7 +295,7 @@ RUN python2 -m pip install -U pip==9.0.3 # For p4 build RUN pip install \ - ctypesgen \ + ctypesgen==0.r125 \ crc16 # For sonic config engine testing diff --git a/sonic-slave/Dockerfile.user b/sonic-slave-jessie/Dockerfile.user similarity index 93% rename from sonic-slave/Dockerfile.user rename to sonic-slave-jessie/Dockerfile.user index 253475b21878..37dd7256c4e5 100644 --- a/sonic-slave/Dockerfile.user +++ b/sonic-slave-jessie/Dockerfile.user @@ -1,5 +1,5 @@ ARG slave_base_tag_ref=latest -FROM sonic-slave-base:${slave_base_tag_ref} +FROM sonic-slave-jessie:${slave_base_tag_ref} # Add user ARG user diff --git a/sonic-slave/sonic-jenkins-id_rsa.pub b/sonic-slave-jessie/sonic-jenkins-id_rsa.pub similarity index 100% rename from sonic-slave/sonic-jenkins-id_rsa.pub rename to sonic-slave-jessie/sonic-jenkins-id_rsa.pub diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 5c1739c49d50..f52bd943b0a7 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -156,6 +156,9 @@ RUN apt-get update && apt-get install -y \ # For broadcom sdk build {%- if CONFIGURED_ARCH == "amd64" %} linux-compiler-gcc-6-x86 \ +{%- endif %} +{%- if CONFIGURED_ARCH == "armhf" %} + linux-compiler-gcc-6-arm \ {%- endif %} linux-kbuild-4.9 \ # teamd build @@ -270,6 +273,8 @@ RUN apt-get update && apt-get install -y \ python3-requests \ python3-pytest \ python3-colorama \ +# For bash + texi2html \ # For initramfs bash-completion \ {%- if CONFIGURED_ARCH == "amd64" %} @@ -284,7 +289,9 @@ RUN apt-get update && apt-get install -y \ rrdtool \ # For smartmontools 6.6-1 automake1.11 \ - libselinux1-dev + libselinux1-dev \ +# For kdump-tools + liblzo2-dev # For smartmontools 6.6-1 RUN apt-get -t stretch-backports install -y debhelper @@ -310,7 +317,7 @@ RUN export VERSION=1.11.5 \ # For p4 build RUN pip install \ - ctypesgen \ + ctypesgen==0.r125 \ crc16 # For sonic config engine testing diff --git a/sonic-slave-stretch/Dockerfile.user b/sonic-slave-stretch/Dockerfile.user index 1e5b91414393..87e4d9568bb1 100644 --- a/sonic-slave-stretch/Dockerfile.user +++ b/sonic-slave-stretch/Dockerfile.user @@ -1,5 +1,5 @@ ARG slave_base_tag_ref=latest -FROM sonic-slave-stretch-base:${slave_base_tag_ref} +FROM sonic-slave-stretch:${slave_base_tag_ref} # Add user ARG user diff --git a/src/kdump-tools/Makefile b/src/kdump-tools/Makefile new file mode 100644 index 000000000000..18c2a369b5d7 --- /dev/null +++ b/src/kdump-tools/Makefile @@ -0,0 +1,32 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +MAIN_TARGET = $(KDUMP_TOOLS) + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + # Remove any stale files + rm -rf ./makedumpfile_$(KDUMP_TOOLS_VERSION_BASE).orig.tar.gz ./makedumpfile_$(KDUMP_TOOLS_VERSION).debian.tar.xz + rm -rf ./makedumpfile-$(KDUMP_TOOLS_VERSION_BASE) + + # Get makedumpfile release + wget http://deb.debian.org/debian/pool/main/m/makedumpfile/makedumpfile_$(KDUMP_TOOLS_VERSION_BASE).orig.tar.gz + wget http://deb.debian.org/debian/pool/main/m/makedumpfile/makedumpfile_$(KDUMP_TOOLS_VERSION).debian.tar.xz + tar -f makedumpfile_$(KDUMP_TOOLS_VERSION_BASE).orig.tar.gz -x + pushd ./makedumpfile-$(KDUMP_TOOLS_VERSION_BASE) + tar -f ../makedumpfile_$(KDUMP_TOOLS_VERSION).debian.tar.xz -x + + git init + git add -f * + git commit -m "unmodified kdump-tools source" + + # Apply patches + stg init + stg import -s ../patch/series + + # Build source and Debian packages + fakeroot debian/rules binary-indep + popd + + # Move the newly-built .deb packages to the destination directory + mv $* $(DEST)/ diff --git a/src/kdump-tools/patch/0001-Generate-initramfs-for-installed-kernels-in-chroot.patch b/src/kdump-tools/patch/0001-Generate-initramfs-for-installed-kernels-in-chroot.patch new file mode 100644 index 000000000000..1d994b88bd58 --- /dev/null +++ b/src/kdump-tools/patch/0001-Generate-initramfs-for-installed-kernels-in-chroot.patch @@ -0,0 +1,41 @@ +From 7e6c0d5b0c7299154f75f281c02cf02cf85fb80e Mon Sep 17 00:00:00 2001 +From: Benjamin Drung +Date: Thu, 2 Mar 2017 19:52:23 +0100 +Subject: [PATCH] Generate initramfs for installed kernels in chroot + +The postinst script from kdump-tools creates an initramfs for the +running kernel. When running inside a chroot, the running kernel (from +the host) might differ from the kernels that are available in the +chroot. + +Thus generate the initramfs only when the running kernel is installed in +the system. Otherwise generate the initramfs for all installed kernels. + +Bug-Debian: #856594 +--- + debian/kdump-tools.postinst | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/debian/kdump-tools.postinst b/debian/kdump-tools.postinst +index 4b6c6be..f604c8e 100755 +--- a/debian/kdump-tools.postinst ++++ b/debian/kdump-tools.postinst +@@ -33,7 +33,15 @@ update_param() { + case "$1" in + configure) + # create smaller initrd.img files for kdump use +- /etc/kernel/postinst.d/kdump-tools $(uname -r) > /dev/null 2>&1 ++ if test -d /lib/modules/$(uname -r); then ++ /etc/kernel/postinst.d/kdump-tools $(uname -r) > /dev/null 2>&1 ++ else ++ # Running kernel not installed. Running in chroot? ++ for kernel_release in $(ls /lib/modules/); do ++ /etc/kernel/postinst.d/kdump-tools $kernel_release > /dev/null 2>&1 ++ kdump-config symlinks $kernel_release ++ done ++ fi + + # Customize crashkernel= value according to architecture + ARCH="$(arch)" +-- +2.9.3 diff --git a/src/kdump-tools/patch/0002-core-file-prefixed-by-kdump.patch b/src/kdump-tools/patch/0002-core-file-prefixed-by-kdump.patch new file mode 100644 index 000000000000..2ed480b26175 --- /dev/null +++ b/src/kdump-tools/patch/0002-core-file-prefixed-by-kdump.patch @@ -0,0 +1,24 @@ +--- a/debian/kdump-config.orig 2019-10-24 09:38:19.006679000 -0700 ++++ b/debian/kdump-config 2019-10-24 12:16:23.791899000 -0700 +@@ -639,8 +639,8 @@ + { + KDUMP_STAMP=`date +"%Y%m%d%H%M"` + KDUMP_STAMPDIR=$(define_stampdir $KDUMP_STAMP) +- KDUMP_CORETEMP="$KDUMP_STAMPDIR/dump-incomplete" +- KDUMP_COREFILE="$KDUMP_STAMPDIR/dump.$KDUMP_STAMP" ++ KDUMP_CORETEMP="$KDUMP_STAMPDIR/kdump-incomplete" ++ KDUMP_COREFILE="$KDUMP_STAMPDIR/kdump.$KDUMP_STAMP" + KDUMP_DMESGFILE="$KDUMP_STAMPDIR/dmesg.$KDUMP_STAMP" + + # If we use NFS, verify that we can mount the FS +@@ -755,8 +755,8 @@ + KDUMP_STAMP=`date +"%Y%m%d%H%M"` + KDUMP_STAMPDIR=$(define_stampdir $KDUMP_STAMP) + +- KDUMP_CORETEMP="$KDUMP_STAMPDIR/dump-incomplete" +- KDUMP_COREFILE="$KDUMP_STAMPDIR/dump.$KDUMP_STAMP" ++ KDUMP_CORETEMP="$KDUMP_STAMPDIR/kdump-incomplete" ++ KDUMP_COREFILE="$KDUMP_STAMPDIR/kdump.$KDUMP_STAMP" + KDUMP_TMPDMESG="/tmp/dmesg.$KDUMP_STAMP" + KDUMP_DMESGFILE="$KDUMP_STAMPDIR/dmesg.$KDUMP_STAMP" + ERROR=0 diff --git a/src/kdump-tools/patch/series b/src/kdump-tools/patch/series new file mode 100644 index 000000000000..e1a26e55ca1b --- /dev/null +++ b/src/kdump-tools/patch/series @@ -0,0 +1,2 @@ +0001-Generate-initramfs-for-installed-kernels-in-chroot.patch +0002-core-file-prefixed-by-kdump.patch diff --git a/src/libteam/Makefile b/src/libteam/Makefile index cf8e382bb78c..b1ef12375416 100644 --- a/src/libteam/Makefile +++ b/src/libteam/Makefile @@ -15,7 +15,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : rm -rf ./libteam git clone https://github.com/jpirko/libteam.git pushd ./libteam - git checkout -b teamd -f 5c5e498bff9 + git checkout -b teamd -f 8c7614abf5993d92e332a800f244bdebd7c9a2c8 # Apply patch series stg init diff --git a/src/libteam/patch/0003-libteam-Add-fallback-support-for-single-member-port-.patch b/src/libteam/patch/0003-libteam-Add-fallback-support-for-single-member-port-.patch index 8559e476aec1..e1234c294fd8 100644 --- a/src/libteam/patch/0003-libteam-Add-fallback-support-for-single-member-port-.patch +++ b/src/libteam/patch/0003-libteam-Add-fallback-support-for-single-member-port-.patch @@ -1,17 +1,16 @@ -From 9b40af58575a89d06be51cfbb5a2265a59826110 Mon Sep 17 00:00:00 2001 -From: yorke -Date: Mon, 3 Jun 2019 12:02:36 +0800 -Subject: [PATCH 3/8] [libteam] Add fallback support for single-member-port LAG - From: Haiyang Zheng Date: Fri, 15 Dec - 2017 21:07:53 -0800 +commit f475746f56602a40861b8d94eac5f0979c4703f3 +Author: yorke +Date: Mon Jun 3 12:02:36 2019 +0800 -Signed-off-by: yorke ---- - teamd/teamd_runner_lacp.c | 42 ++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 40 insertions(+), 2 deletions(-) + From 9b40af58575a89d06be51cfbb5a2265a59826110 Mon Sep 17 00:00:00 2001 + Subject: [PATCH 3/8] [libteam] Add fallback support for single-member-port LAG + From: Haiyang Zheng Date: Fri, 15 Dec + 2017 21:07:53 -0800 + + Signed-off-by: yorke diff --git a/teamd/teamd_runner_lacp.c b/teamd/teamd_runner_lacp.c -index 4dbd015..9836824 100644 +index 4dbd015..f8a9e16 100644 --- a/teamd/teamd_runner_lacp.c +++ b/teamd/teamd_runner_lacp.c @@ -138,6 +138,8 @@ struct lacp { @@ -71,7 +70,27 @@ index 4dbd015..9836824 100644 return false; return true; } -@@ -1502,6 +1525,16 @@ static int lacp_state_fast_rate_get(struct teamd_context *ctx, +@@ -334,7 +357,8 @@ static int lacp_port_should_be_enabled(struct lacp_port *lacp_port) + + if (lacp_port_selected(lacp_port) && + lacp_port->agg_lead == lacp->selected_agg_lead && +- lacp_port->partner.state & INFO_STATE_SYNCHRONIZATION) ++ (lacp_port->partner.state & INFO_STATE_SYNCHRONIZATION || ++ is_lacp_fallback_eligible(lacp_port))) + return true; + return false; + } +@@ -345,7 +369,8 @@ static int lacp_port_should_be_disabled(struct lacp_port *lacp_port) + + if (!lacp_port_selected(lacp_port) || + lacp_port->agg_lead != lacp->selected_agg_lead || +- !(lacp_port->partner.state & INFO_STATE_SYNCHRONIZATION)) ++ (!(lacp_port->partner.state & INFO_STATE_SYNCHRONIZATION) && ++ !is_lacp_fallback_eligible(lacp_port))) + return true; + return false; + } +@@ -1502,6 +1527,16 @@ static int lacp_state_fast_rate_get(struct teamd_context *ctx, return 0; } @@ -88,7 +107,7 @@ index 4dbd015..9836824 100644 static int lacp_state_select_policy_get(struct teamd_context *ctx, struct team_state_gsc *gsc, void *priv) -@@ -1529,6 +1562,11 @@ static const struct teamd_state_val lacp_state_vals[] = { +@@ -1529,6 +1564,11 @@ static const struct teamd_state_val lacp_state_vals[] = { .getter = lacp_state_fast_rate_get, }, { @@ -100,6 +119,3 @@ index 4dbd015..9836824 100644 .subpath = "select_policy", .type = TEAMD_STATE_ITEM_TYPE_STRING, .getter = lacp_state_select_policy_get, --- -2.7.4 - diff --git a/src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch b/src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch index 10770b8740b5..3f428bbec19e 100644 --- a/src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch +++ b/src/libteam/patch/0008-libteam-Add-warm_reboot-mode.patch @@ -1,15 +1,16 @@ -From a21a3dec9f9b9d825a0229e2963e07862395bbba Mon Sep 17 00:00:00 2001 +From 113d482704198685fba09cd2597fd93ca9d297c5 Mon Sep 17 00:00:00 2001 From: Pavel Shirshov -Date: Fri, 14 Jun 2019 14:20:05 -0700 -Subject: [PATCH] [libteam]: Reimplement Warm-Reboot procedure +Date: Tue, 1 Oct 2019 09:23:23 -0700 +Subject: [PATCH 1/1] [libteam]: Reimplement Warm-Reboot procedure --- libteam/ifinfo.c | 6 +- - teamd/teamd.c | 42 +++- + teamd/teamd.c | 51 +++- teamd/teamd.h | 6 + teamd/teamd_events.c | 13 ++ + teamd/teamd_per_port.c | 6 + teamd/teamd_runner_lacp.c | 474 +++++++++++++++++++++++++++++++++++--- - 5 files changed, 498 insertions(+), 43 deletions(-) + 6 files changed, 512 insertions(+), 44 deletions(-) diff --git a/libteam/ifinfo.c b/libteam/ifinfo.c index 46d56a2..b86d34c 100644 @@ -34,7 +35,7 @@ index 46d56a2..b86d34c 100644 } } diff --git a/teamd/teamd.c b/teamd/teamd.c -index 9dc85b5..96794e8 100644 +index 9dc85b5..17221a9 100644 --- a/teamd/teamd.c +++ b/teamd/teamd.c @@ -117,7 +117,9 @@ static void print_help(const struct teamd_context *ctx) { @@ -90,51 +91,60 @@ index 9dc85b5..96794e8 100644 if (optind < argc) { fprintf(stderr, "Too many arguments\n"); return -1; -@@ -390,8 +410,14 @@ static int teamd_run_loop_run(struct teamd_context *ctx) +@@ -390,9 +410,18 @@ static int teamd_run_loop_run(struct teamd_context *ctx) if (err != -1) { switch(ctrl_byte) { case 'q': ++ case 'f': + case 'w': if (quit_in_progress) return -EBUSY; -+ if (ctrl_byte == 'w') { +- teamd_refresh_ports(ctx); ++ if (ctrl_byte == 'w' || ctrl_byte == 'f') { + ctx->keep_ports = true; + ctx->no_quit_destroy = true; -+ teamd_ports_flush_data(ctx); ++ teamd_refresh_ports(ctx); ++ if (ctrl_byte == 'w') ++ teamd_ports_flush_data(ctx); + } - teamd_refresh_ports(ctx); ++ err = teamd_flush_ports(ctx); if (err) -@@ -434,6 +460,12 @@ void teamd_run_loop_quit(struct teamd_context *ctx, int err) + return err; +@@ -434,6 +463,12 @@ void teamd_run_loop_quit(struct teamd_context *ctx, int err) teamd_run_loop_sent_ctrl_byte(ctx, 'q'); } -+static void teamd_run_loop_quit_w_boot(struct teamd_context *ctx, int err) ++static void teamd_run_loop_quit_a_boot(struct teamd_context *ctx, char type, int err) +{ + ctx->run_loop.err = err; -+ teamd_run_loop_sent_ctrl_byte(ctx, 'w'); ++ teamd_run_loop_sent_ctrl_byte(ctx, type); +} + void teamd_run_loop_restart(struct teamd_context *ctx) { teamd_run_loop_sent_ctrl_byte(ctx, 'r'); -@@ -700,6 +732,10 @@ static int callback_daemon_signal(struct teamd_context *ctx, int events, +@@ -700,6 +735,14 @@ static int callback_daemon_signal(struct teamd_context *ctx, int events, teamd_log_warn("Got SIGINT, SIGQUIT or SIGTERM."); teamd_run_loop_quit(ctx, 0); break; + case SIGUSR1: + teamd_log_warn("Got SIGUSR1."); -+ teamd_run_loop_quit_w_boot(ctx, 0); ++ teamd_run_loop_quit_a_boot(ctx, 'w', 0); ++ break; ++ case SIGUSR2: ++ teamd_log_warn("Got SIGUSR2."); ++ teamd_run_loop_quit_a_boot(ctx, 'f', 0); + break; } return 0; } -@@ -1531,7 +1567,7 @@ static int teamd_start(struct teamd_context *ctx, enum teamd_exit_code *p_ret) +@@ -1531,7 +1574,7 @@ static int teamd_start(struct teamd_context *ctx, enum teamd_exit_code *p_ret) return -errno; } - if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, 0) < 0) { -+ if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, SIGUSR1, 0) < 0) { ++ if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, SIGUSR1, SIGUSR2, 0) < 0) { teamd_log_err("Could not register signal handlers."); daemon_retval_send(errno); err = -errno; @@ -192,6 +202,23 @@ index 221803e..bd4dcc1 100644 int teamd_event_port_added(struct teamd_context *ctx, struct teamd_port *tdport) { +diff --git a/teamd/teamd_per_port.c b/teamd/teamd_per_port.c +index f98a90d..a87e809 100644 +--- a/teamd/teamd_per_port.c ++++ b/teamd/teamd_per_port.c +@@ -350,6 +350,12 @@ static int teamd_port_remove(struct teamd_context *ctx, + { + int err; + ++ if (ctx->keep_ports) { ++ teamd_log_dbg("%s: Keeping port (found ifindex \"%d\").", ++ tdport->ifname, tdport->ifindex); ++ return 0; ++ } ++ + teamd_log_dbg("%s: Removing port (found ifindex \"%d\").", + tdport->ifname, tdport->ifindex); + err = team_port_remove(ctx->th, tdport->ifindex); diff --git a/teamd/teamd_runner_lacp.c b/teamd/teamd_runner_lacp.c index 4016b15..81be5b7 100644 --- a/teamd/teamd_runner_lacp.c diff --git a/src/libteam/patch/0010-When-read-of-timerfd-returned-0-don-t-consider-this-.patch b/src/libteam/patch/0010-When-read-of-timerfd-returned-0-don-t-consider-this-.patch new file mode 100644 index 000000000000..e703d73e0263 --- /dev/null +++ b/src/libteam/patch/0010-When-read-of-timerfd-returned-0-don-t-consider-this-.patch @@ -0,0 +1,39 @@ +From 038bed6fe3970dc829dbf9a282f7bea7198e7826 Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Wed, 28 Aug 2019 16:39:35 -0700 +Subject: [PATCH] When read of timerfd returned 0, don't consider this an error + +Just skip this event. +--- + teamd/teamd.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/teamd/teamd.c b/teamd/teamd.c +index 96794e8..a5ce745 100644 +--- a/teamd/teamd.c ++++ b/teamd/teamd.c +@@ -285,6 +285,10 @@ static int handle_period_fd(int fd) + teamd_log_err("read() failed."); + return -errno; + } ++ if (ret == 0) { ++ teamd_log_warn("read() for timer_fd returned 0."); ++ return 1; ++ } + if (ret != sizeof(uint64_t)) { + teamd_log_err("read() returned unexpected number of bytes."); + return -EINVAL; +@@ -345,7 +349,9 @@ static int teamd_run_loop_do_callbacks(struct list_item *lcb_list, fd_set *fds, + continue; + if (lcb->is_period) { + err = handle_period_fd(lcb->fd); +- if (err) ++ if (err == 1) ++ continue; /* timerfd returned 0. Don't do anything */ ++ if (err < 0) + return err; + } + err = lcb->func(ctx, events, lcb->priv); +-- +2.7.4 + diff --git a/src/libteam/patch/series b/src/libteam/patch/series index c30bdc7dd861..7be69525d9d0 100644 --- a/src/libteam/patch/series +++ b/src/libteam/patch/series @@ -7,3 +7,4 @@ 0007-Send-LACP-PDU-immediately-if-our-state-changed.patch 0008-libteam-Add-warm_reboot-mode.patch 0009-Fix-ifinfo_link_with_port-race-condition-with-newlink.patch +0010-When-read-of-timerfd-returned-0-don-t-consider-this-.patch diff --git a/src/libyang/Makefile b/src/libyang/Makefile index cb58f7c5128b..32cabdf13bdf 100644 --- a/src/libyang/Makefile +++ b/src/libyang/Makefile @@ -3,19 +3,26 @@ SHELL = /bin/bash .SHELLFLAGS += -e MAIN_TARGET = $(LIBYANG) -DERIVED_TARGETS = $(LIBYANG_DEV) $(LIBYANG_DBG) +DERIVED_TARGETS = $(LIBYANG_DEV) $(LIBYANG_DBG) $(LIBYANG_PY2) $(LIBYANG_PY3) $(LIBYANG_CPP) $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + # Obtaining the libyang rm -fr ./libyang-$(LIBYANG_VERSION) - wget -O libyang_$(LIBYANG_VERSION).orig.tar.gz 'https://sonicstorage.blob.core.windows.net/packages/libyang_0.16.105.orig.tar.gz?sv=2015-04-05&sr=b&sig=yTWDhl6B9TTXWAQ46zpLiNxUib61W7U0%2F%2FGvhRibKOc%3D&se=2046-09-30T22%3A10%3A27Z&sp=r' - wget -O libyang_$(LIBYANG_VERSION).dsc 'https://sonicstorage.blob.core.windows.net/packages/libyang_0.16.105-1.dsc?sv=2015-04-05&sr=b&sig=eLkO5wzB1C5oKNIaUPro4gwrgEC3EygIO6eCyTzHmeI%3D&se=2046-09-30T22%3A10%3A12Z&sp=r' - wget -O libyang_$(LIBYANG_VERSION)-$(LIBYANG_SUBVERSION).debian.tar.xz 'https://sonicstorage.blob.core.windows.net/packages/libyang_0.16.105-1.debian.tar.xz?sv=2015-04-05&sr=b&sig=AH18p7pKK0xIBVxZuA8EMv9%2FhXbCFKmbWAn7Za8%2BZW4%3D&se=2046-09-30T22%3A09%3A36Z&sp=r' - dpkg-source -x libyang_$(LIBYANG_VERSION).dsc + git clone https://github.com/CESNET/libyang.git libyang-$(LIBYANG_VERSION) + pushd libyang-$(LIBYANG_VERSION) + git checkout tags/v1.0-r4 -b libyang + # Apply patch series + stg init + stg import -s ../patch/series - pushd ./libyang-$(LIBYANG_VERSION) - dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) - popd + mkdir build + pushd build + cmake .. + make build-deb - mv $(DERIVED_TARGETS) $* $(DEST)/ + pushd debs + mv $* $(DEST)/ + mv $(DERIVED_TARGETS) $(DEST)/ + popd $(addprefix $(DEST)/, $(DERIVED_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) diff --git a/src/libyang/patch/libyang.patch b/src/libyang/patch/libyang.patch new file mode 100644 index 000000000000..a950d85086ab --- /dev/null +++ b/src/libyang/patch/libyang.patch @@ -0,0 +1,134 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index fa562dd3..8635ba15 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -33,6 +33,7 @@ set(LIBYANG_MICRO_SOVERSION 2) + set(LIBYANG_SOVERSION_FULL ${LIBYANG_MAJOR_SOVERSION}.${LIBYANG_MINOR_SOVERSION}.${LIBYANG_MICRO_SOVERSION}) + set(LIBYANG_SOVERSION ${LIBYANG_MAJOR_SOVERSION}) + ++set(CMAKE_INSTALL_PREFIX /usr) + # set default build type if not specified by user + if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE debug) +diff --git a/packages/debian.control.in b/packages/debian.control.in +index da6588b9..fb3ede48 100644 +--- a/packages/debian.control.in ++++ b/packages/debian.control.in +@@ -53,3 +53,15 @@ Depends: python3-yang@PACKAGE_PART_NAME@ (=@LIBYANG_VERSION@) + Section: debug + Architecture: any + Description: Debug symbols of python3 bidings of libyang library. ++ ++Package: python2-yang@PACKAGE_PART_NAME@ ++Depends: @PACKAGE_NAME@ (=@LIBYANG_VERSION@), libyang-cpp@PACKAGE_PART_NAME@ (=@LIBYANG_VERSION@) ++Section: libs ++Architecture: any ++Description: Bindings of libyang library to python2 language. ++ ++Package: python2-yang@PACKAGE_PART_NAME@-dbg ++Depends: python2-yang@PACKAGE_PART_NAME@ (=@LIBYANG_VERSION@) ++Section: debug ++Architecture: any ++Description: Debug symbols of python2 bidings of libyang library. +diff --git a/packages/debian.python2-yang.install b/packages/debian.python2-yang.install +new file mode 100644 +index 00000000..14ce2f3c +--- /dev/null ++++ b/packages/debian.python2-yang.install +@@ -0,0 +1 @@ ++usr/lib/python2.7/dist-packages/* +diff --git a/packages/debian.rules.in b/packages/debian.rules.in +index d565819e..e92fe4a1 100644 +--- a/packages/debian.rules.in ++++ b/packages/debian.rules.in +@@ -9,10 +9,14 @@ export DH_VERBOSE=1 + override_dh_strip: + dh_strip -plibyang@PACKAGE_PART_NAME@ --dbg-package=libyang@PACKAGE_PART_NAME@-dbg + dh_strip -plibyang-cpp@PACKAGE_PART_NAME@ --dbg-package=libyang-cpp@PACKAGE_PART_NAME@-dbg ++ dh_strip -ppython2-yang@PACKAGE_PART_NAME@ --dbg-package=python2-yang@PACKAGE_PART_NAME@-dbg + dh_strip -ppython3-yang@PACKAGE_PART_NAME@ --dbg-package=python3-yang@PACKAGE_PART_NAME@-dbg + + override_dh_auto_configure: +- cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_BUILD_TYPE:String="@BUILD_TYPE@" -DGEN_LANGUAGE_BINDINGS=ON . ++ cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_BUILD_TYPE:String="@BUILD_TYPE@" -DENABLE_LYD_PRIV=ON -DGEN_LANGUAGE_BINDINGS=ON -DGEN_PYTHON_VERSION=2 . ++ ++override_dh_makeshlibs: ++ dh_makeshlibs -Xextensions -Xuser_types + + override_dh_auto_test: + ctest --output-on-failure +diff --git a/packages/libyang.dsc.in b/packages/libyang.dsc.in +index fdfa402b..f75ba184 100644 +--- a/packages/libyang.dsc.in ++++ b/packages/libyang.dsc.in +@@ -1,10 +1,10 @@ + Format: 3.0 (quilt) + Source: @PACKAGE_NAME@ +-Binary: @PACKAGE_NAME@, @PACKAGE_NAME@-dbg, @PACKAGE_NAME@-dev, libyang-cpp@PACKAGE_PART_NAME@, libyang-cpp@PACKAGE_PART_NAME@-dev, libyang-cpp@PACKAGE_PART_NAME@-dbg, python3-yang@PACKAGE_PART_NAME@, python3-yang@PACKAGE_PART_NAME@-dbg ++Binary: @PACKAGE_NAME@, @PACKAGE_NAME@-dbg, @PACKAGE_NAME@-dev, libyang-cpp@PACKAGE_PART_NAME@, libyang-cpp@PACKAGE_PART_NAME@-dev, libyang-cpp@PACKAGE_PART_NAME@-dbg, python3-yang@PACKAGE_PART_NAME@, python3-yang@PACKAGE_PART_NAME@-dbg python2-yang@PACKAGE_PART_NAME@, python2-yang@PACKAGE_PART_NAME@-dbg + Maintainer: CESNET + Version: @LIBYANG_VERSION@ + Architecture: any + Standards-Version: 3.8.2 + Homepage: https://github.com/CESNET/libyang + Vcs-Git: https://github.com/CESNET/libyang +-Build-Depends: debhelper (>= 9), make, gcc, doxygen, cmake, pkg-config, libpcre3-dev, libcmocka-dev, python3-dev, g++, swig (>= 3.0.12) ++Build-Depends: debhelper (>= 9), make, gcc, doxygen, cmake, pkg-config, libpcre3-dev, libcmocka-dev, python3-dev, python2-dev, g++, swig (>= 3.0.12) +diff --git a/packages/libyang.spec.in b/packages/libyang.spec.in +index 6a4ac615..6939f028 100644 +--- a/packages/libyang.spec.in ++++ b/packages/libyang.spec.in +@@ -46,6 +46,8 @@ BuildRequires: python3-devel + %else + BuildRequires: python34-devel + %endif ++ ++BuildRequires: python2-devel + %endif + + Conflicts: @CONFLICT_PACKAGE_NAME@ = @LIBYANG_MAJOR_VERSION@.@LIBYANG_MINOR_VERSION@ +@@ -70,6 +72,11 @@ Summary: Binding to python + Requires: libyang-cpp@PACKAGE_PART_NAME@ = %{version}-%{release} + Requires: %{name} = %{version}-%{release} + ++%package -n python2-yang@PACKAGE_PART_NAME@ ++Summary: Binding to python ++Requires: libyang-cpp@PACKAGE_PART_NAME@ = %{version}-%{release} ++Requires: %{name} = %{version}-%{release} ++ + %description -n libyang-cpp@PACKAGE_PART_NAME@ + Bindings of libyang library to C++ language. + +@@ -80,6 +87,10 @@ Headers of bindings to c++ language. + Bindings of libyang library to python language. + %endif + ++%description -n python2-yang@PACKAGE_PART_NAME@ ++Bindings of libyang library to python language. ++%endif ++ + %description devel + Headers of libyang library. + +@@ -167,4 +178,9 @@ make DESTDIR=%{buildroot} install + %{_libdir}/python* + %endif + ++%files -n python2-yang@PACKAGE_PART_NAME@ ++%defattr(-,root,root) ++%{_libdir}/python* ++%endif ++ + %changelog +diff --git a/packages/local-deb.sh.in b/packages/local-deb.sh.in +index 057bbc67..4318a49d 100755 +--- a/packages/local-deb.sh.in ++++ b/packages/local-deb.sh.in +@@ -18,6 +18,7 @@ fi + cp "@PROJECT_SOURCE_DIR@/packages/debian.libyang-dev.install" debian/@PACKAGE_NAME@-dev.install + cp "@PROJECT_SOURCE_DIR@/packages/debian.libyang-cpp.install" debian/libyang-cpp@PACKAGE_PART_NAME@.install + cp "@PROJECT_SOURCE_DIR@/packages/debian.libyang-cpp-dev.install" debian/libyang-cpp@PACKAGE_PART_NAME@-dev.install ++cp "@PROJECT_SOURCE_DIR@/packages/debian.python2-yang.install" debian/python2-yang@PACKAGE_PART_NAME@.install + cp "@PROJECT_SOURCE_DIR@/packages/debian.python3-yang.install" debian/python3-yang@PACKAGE_PART_NAME@.install + echo -e "@PACKAGE_NAME@ (@LIBYANG_VERSION@) stable; urgency=low\n" >debian/changelog + git log -10 --pretty=format:' * %s (%aN)%n' 2>/dev/null >>debian/changelog || echo -e " * unknown changes \n" >>debian/changelog diff --git a/src/libyang/patch/series b/src/libyang/patch/series new file mode 100644 index 000000000000..773245e4eed5 --- /dev/null +++ b/src/libyang/patch/series @@ -0,0 +1,2 @@ +libyang.patch +swig.patch diff --git a/src/libyang/patch/swig.patch b/src/libyang/patch/swig.patch new file mode 100644 index 000000000000..a6f798c18224 --- /dev/null +++ b/src/libyang/patch/swig.patch @@ -0,0 +1,136 @@ +diff --git a/swig/CMakeLists.txt b/swig/CMakeLists.txt +index 4cee36ec..0baa69ab 100644 +--- a/swig/CMakeLists.txt ++++ b/swig/CMakeLists.txt +@@ -20,27 +20,34 @@ endif() + + # find Python package + if(GEN_PYTHON_BINDINGS AND SWIG_FOUND) +- message(STATUS "Python version ${GEN_PYTHON_VERSION} was selected") +- unset(PYTHON_LIBRARY CACHE) +- unset(PYTHON_EXECUTABLE CACHE) +- unset(PYTHON_INCLUDE_DIR CACHE) +- unset(PYTHON_LIBRARY_DEBUG CACHE) +- if(${GEN_PYTHON_VERSION} STREQUAL "2") +- find_package(PythonLibs 2 REQUIRED) +- find_package(PythonInterp 2 REQUIRED) +- if(NOT PYTHONLIBS_FOUND) +- message(WARNING "Did not found Python version 2.x") +- message(STATUS "Sysrepo supports Python 2.x and Python 3.x") +- endif() +- elseif(${GEN_PYTHON_VERSION} STREQUAL "3") +- find_package(PythonLibs 3 REQUIRED) +- find_package(PythonInterp 3 REQUIRED) +- if(NOT PYTHONLIBS_FOUND) +- message(WARNING "Did not found Python version 3.x") +- message(STATUS "Sysrepo supports Python 2.x and Python 3.x") +- endif() ++ if(ENABLE_STATIC) ++ message(WARNING "Can't create a static Python module") + else() +- message(WARNING "Sysrepo supports Python 2.x and Python 3.x") ++ set(GEN_PYTHON_VERSION 2 3) ++ foreach(CUR_PYTHON_VERSION ${GEN_PYTHON_VERSION}) ++ message(STATUS "Python version ${CUR_PYTHON_VERSION} was selected") ++ ++ unset(PYTHON_EXECUTABLE CACHE) ++ unset(PYTHON_INCLUDE_PATH CACHE) ++ unset(PYTHON_EXT_SUFFIX CACHE) ++ unset(PYTHON_MODULE_PATH CACHE) ++ set(PYTHON_EXT_SUFFIX ".so") ++ ++ find_program(PYTHON_EXECUTABLE NAMES python${CUR_PYTHON_VERSION}) ++ execute_process(COMMAND ${PYTHON_EXECUTABLE} -c ++ "from distutils.sysconfig import get_config_var; print(get_config_var('INCLUDEPY'))" ++ OUTPUT_VARIABLE PYTHON_INCLUDE_PATH ++ OUTPUT_STRIP_TRAILING_WHITESPACE ) ++ #execute_process(COMMAND ${PYTHON_EXECUTABLE} -c ++ # "from distutils.sysconfig import get_config_var; print(get_config_var('EXT_SUFFIX'))" ++ # OUTPUT_VARIABLE PYTHON_EXT_SUFFIX ++ # OUTPUT_STRIP_TRAILING_WHITESPACE ) ++ execute_process(COMMAND ${PYTHON_EXECUTABLE} -c ++ "from distutils.sysconfig import get_python_lib; print(get_python_lib(plat_specific=True))" ++ OUTPUT_VARIABLE PYTHON_MODULE_PATH ++ OUTPUT_STRIP_TRAILING_WHITESPACE ) ++ add_subdirectory(python python${CUR_PYTHON_VERSION}) ++ endforeach(CUR_PYTHON_VERSION) + endif() + endif() + +@@ -99,12 +106,6 @@ if (GEN_CPP_BINDINGS) + endif() + endif() + +-if(ENABLE_STATIC AND PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND AND (${GEN_PYTHON_VERSION} STREQUAL "2" OR ${GEN_PYTHON_VERSION} STREQUAL "3")) +- message(WARNING "Can't create a static Python module") +-elseif(PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND AND (${GEN_PYTHON_VERSION} STREQUAL "2" OR ${GEN_PYTHON_VERSION} STREQUAL "3")) +- add_subdirectory(python) +-endif() +- + if(NOT ENABLE_STATIC AND GEN_JAVASCRIPT_BINDINGS) + message(WARNING "Can't create Javascript bindings with a shared library, please use -DENABLE_STATIC") + elseif(ENABLE_STATIC AND GEN_JAVASCRIPT_BINDINGS) +diff --git a/swig/python/CMakeLists.txt b/swig/python/CMakeLists.txt +index 994b1234..5d18b8bf 100644 +--- a/swig/python/CMakeLists.txt ++++ b/swig/python/CMakeLists.txt +@@ -1,30 +1,38 @@ + set(PYTHON_SWIG_BINDING yang) ++set(PYTHON_SWIG_TARGET yang${CUR_PYTHON_VERSION}) + include_directories(${PYTHON_INCLUDE_PATH}) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}) ++include_directories(${PROJECT_SOURCE_DIR}/cpp/src) + + set(CMAKE_SWIG_FLAGS "-c++") +-set(CMAKE_SWIG_FLAGS "-I${PROJECT_SOURCE_DIR}") ++set(CMAKE_SWIG_FLAGS "-I${PROJECT_SOURCE_DIR}" "-I${PROJECT_SOURCE_DIR}/cpp/src") + set(CMAKE_SWIG_OUTDIR ${CMAKE_CURRENT_BINARY_DIR}) + +-set_source_files_properties(${PYTHON_SWIG_BINDING}.i PROPERTIES CPLUSPLUS ON PREFIX "") ++set_source_files_properties(${PYTHON_SWIG_BINDING}.i PROPERTIES CPLUSPLUS ON PREFIX "" SWIG_MODULE_NAME ${PYTHON_SWIG_BINDING}) + + if(${CMAKE_VERSION} VERSION_LESS "3.8.0") +- swig_add_module(${PYTHON_SWIG_BINDING} python ${PYTHON_SWIG_BINDING}.i) ++ swig_add_module(${PYTHON_SWIG_TARGET} python ${PYTHON_SWIG_BINDING}.i) + else() +- swig_add_library(${PYTHON_SWIG_BINDING} LANGUAGE python SOURCES ${PYTHON_SWIG_BINDING}.i) ++ swig_add_library(${PYTHON_SWIG_TARGET} LANGUAGE python SOURCES ${PYTHON_SWIG_BINDING}.i) + endif() +-swig_link_libraries(${PYTHON_SWIG_BINDING} ${PYTHON_LIBRARIES} libyang-cpp) ++swig_link_libraries(${PYTHON_SWIG_TARGET} ${PYTHON_LIBRARIES} libyang-cpp) ++ ++set_target_properties(_${PYTHON_SWIG_TARGET} PROPERTIES OUTPUT_NAME "_yang${PYTHON_EXT_SUFFIX}" SUFFIX "") + + # Generate header with SWIG run-time functions + execute_process(COMMAND ${SWIG_EXECUTABLE} -python -external-runtime ${CMAKE_CURRENT_BINARY_DIR}/swigpyrun.h) + +-file(COPY "examples" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) ++add_custom_command(TARGET ${PYTHON_SWIG_TARGET}_swig_compilation POST_BUILD ++ COMMAND sed -e "'s/\\(inst =.*tp_new.*\\)Py_None, Py_None);/PyObject *tup = PyTuple_New(0); \\1tup, Py_None); Py_DECREF(tup);/'" < swigpyrun.h > swigpyrun.h.new ++ COMMAND sed -e "'s/\\(inst =.*tp_new.*\\)Py_None, Py_None);/PyObject *tup = PyTuple_New(0); \\1tup, Py_None); Py_DECREF(tup);/'" < yangPYTHON_wrap.cxx > yangPYTHON_wrap.cxx.new ++ COMMAND diff -q swigpyrun.h swigpyrun.h.new || mv swigpyrun.h.new swigpyrun.h ++ COMMAND diff -q yangPYTHON_wrap.cxx yangPYTHON_wrap.cxx.new || mv yangPYTHON_wrap.cxx.new yangPYTHON_wrap.cxx ++ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ++ ) + +-execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(plat_specific=True))" +- OUTPUT_VARIABLE PYTHON_MODULE_PATH +- OUTPUT_STRIP_TRAILING_WHITESPACE ) ++file(COPY "examples" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + +-install( TARGETS _${PYTHON_SWIG_BINDING} DESTINATION ${PYTHON_MODULE_PATH}) ++install( TARGETS _${PYTHON_SWIG_TARGET} DESTINATION ${PYTHON_MODULE_PATH}) + install( FILES "${CMAKE_CURRENT_BINARY_DIR}/${PYTHON_SWIG_BINDING}.py" DESTINATION ${PYTHON_MODULE_PATH}) + install( FILES "${CMAKE_CURRENT_BINARY_DIR}/swigpyrun.h" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/libyang) + +@@ -51,8 +59,8 @@ if(ENABLE_BUILD_TESTS) + ADD_PYTHON_TEST(test_tree_data) + ADD_PYTHON_TEST(test_tree_schema) + +- add_custom_command(TARGET ${SWIG_MODULE_${PYTHON_SWIG_BINDING}_REAL_NAME} POST_BUILD +- COMMAND cp "${CMAKE_CURRENT_BINARY_DIR}/_${PYTHON_SWIG_BINDING}.so" ${PY2_SWIG_DIR}/tests ++ add_custom_command(TARGET ${SWIG_MODULE_${PYTHON_SWIG_TARGET}_REAL_NAME} POST_BUILD ++ COMMAND cp "${CMAKE_CURRENT_BINARY_DIR}/_yang${PYTHON_EXT_SUFFIX}" ${PY2_SWIG_DIR}/tests/_yang.so + COMMAND cp "${CMAKE_CURRENT_BINARY_DIR}/${PYTHON_SWIG_BINDING}.py" ${PY2_SWIG_DIR}/tests + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) diff --git a/src/lldpd/patch/0003-update-tx-interval-immediately.patch b/src/lldpd/patch/0003-update-tx-interval-immediately.patch new file mode 100644 index 000000000000..b6b295001288 --- /dev/null +++ b/src/lldpd/patch/0003-update-tx-interval-immediately.patch @@ -0,0 +1,20 @@ +diff --git a/src/daemon/client.c b/src/daemon/client.c +index 8382d02..38cf3f3 100644 +--- a/src/daemon/client.c ++++ b/src/daemon/client.c +@@ -71,7 +71,6 @@ client_handle_set_configuration(struct lldpd *cfg, enum hmsg_type *type, + if (CHANGED(c_tx_interval) && config->c_tx_interval != 0) { + if (config->c_tx_interval < 0) { + log_debug("rpc", "client asked for immediate retransmission"); +- levent_send_now(cfg); + } else { + log_debug("rpc", "client change transmit interval to %d", + config->c_tx_interval); +@@ -79,6 +78,7 @@ client_handle_set_configuration(struct lldpd *cfg, enum hmsg_type *type, + LOCAL_CHASSIS(cfg)->c_ttl = cfg->g_config.c_tx_interval * + cfg->g_config.c_tx_hold; + } ++ levent_send_now(cfg); + } + if (CHANGED(c_tx_hold) && config->c_tx_hold > 0) { + log_debug("rpc", "client change transmit hold to %d", diff --git a/src/lldpd/patch/series b/src/lldpd/patch/series index 2ca46b575396..5e5e8bc99714 100644 --- a/src/lldpd/patch/series +++ b/src/lldpd/patch/series @@ -1,3 +1,4 @@ # This series applies on GIT commit 396961a038a38675d46f96eaa7b430b2a1f8701b 0001-return-error-when-port-does-not-exist.patch 0002-Let-linux-kernel-to-find-appropriate-nl_pid-automa.patch +0003-update-tx-interval-immediately.patch diff --git a/src/sflow/hsflowd/Makefile b/src/sflow/hsflowd/Makefile new file mode 100644 index 000000000000..0a8094e3b695 --- /dev/null +++ b/src/sflow/hsflowd/Makefile @@ -0,0 +1,29 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +MAIN_TARGET = $(HSFLOWD) +DERIVED_TARGET = $(HSFLOWD_DBG) + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + rm -fr ./host-sflow + git clone https://github.com/sflow/host-sflow + + pushd ./host-sflow + git checkout -b sflow tags/v2.0.26-1 + + # Apply patch series + stg init + stg import -s ../patch/series + + mkdir -p debian + cp -r DEBIAN_build/* debian + chmod u+x debian/rules + sed -i -e s/_VERSION_/$(HSFLOWD_VERSION)-$(HSFLOWD_SUBVERSION)/g debian/changelog + + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --buildinfo-option=-u. --changes-option=-u. + + mv $(DERIVED_TARGET) $* $(DEST)/ + popd + +$(addprefix $(DEST)/, $(DERIVED_TARGET)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) diff --git a/src/sflow/hsflowd/patch/0001-host_sflow_psample.patch b/src/sflow/hsflowd/patch/0001-host_sflow_psample.patch new file mode 100644 index 000000000000..d0672f80cd5b --- /dev/null +++ b/src/sflow/hsflowd/patch/0001-host_sflow_psample.patch @@ -0,0 +1,39 @@ +diff -ruN a/src/Linux/linux/psample.h b/src/Linux/linux/psample.h +--- a/src/Linux/linux/psample.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/src/Linux/linux/psample.h 2019-07-20 08:45:58.715748881 -0700 +@@ -0,0 +1,35 @@ ++#ifndef __UAPI_PSAMPLE_H ++#define __UAPI_PSAMPLE_H ++ ++enum { ++ /* sampled packet metadata */ ++ PSAMPLE_ATTR_IIFINDEX, ++ PSAMPLE_ATTR_OIFINDEX, ++ PSAMPLE_ATTR_ORIGSIZE, ++ PSAMPLE_ATTR_SAMPLE_GROUP, ++ PSAMPLE_ATTR_GROUP_SEQ, ++ PSAMPLE_ATTR_SAMPLE_RATE, ++ PSAMPLE_ATTR_DATA, ++ ++ /* commands attributes */ ++ PSAMPLE_ATTR_GROUP_REFCOUNT, ++ ++ __PSAMPLE_ATTR_MAX ++}; ++ ++enum psample_command { ++ PSAMPLE_CMD_SAMPLE, ++ PSAMPLE_CMD_GET_GROUP, ++ PSAMPLE_CMD_NEW_GROUP, ++ PSAMPLE_CMD_DEL_GROUP, ++}; ++ ++/* Can be overridden at runtime by module option */ ++#define PSAMPLE_ATTR_MAX (__PSAMPLE_ATTR_MAX - 1) ++ ++#define PSAMPLE_NL_MCGRP_CONFIG_NAME "config" ++#define PSAMPLE_NL_MCGRP_SAMPLE_NAME "packets" ++#define PSAMPLE_GENL_NAME "psample" ++#define PSAMPLE_GENL_VERSION 1 ++ ++#endif diff --git a/src/sflow/hsflowd/patch/0002-host_sflow_debian.patch b/src/sflow/hsflowd/patch/0002-host_sflow_debian.patch new file mode 100644 index 000000000000..86ebab723351 --- /dev/null +++ b/src/sflow/hsflowd/patch/0002-host_sflow_debian.patch @@ -0,0 +1,108 @@ +diff -ruN a/DEBIAN_build/changelog b/DEBIAN_build/changelog +--- a/DEBIAN_build/changelog 1969-12-31 19:00:00.000000000 -0500 ++++ b/DEBIAN_build/changelog 2019-08-19 22:52:10.171736403 -0400 +@@ -0,0 +1,6 @@ ++hsflowd (_VERSION_) stable; urgency=medium ++ ++ [ DellEMC ] ++ * Initial release : hsflowd ++ ++ -- DellEMC Mon, 29 Jul 2019 07:08:02 -0400 +diff -ruN a/DEBIAN_build/compat b/DEBIAN_build/compat +--- a/DEBIAN_build/compat 1969-12-31 19:00:00.000000000 -0500 ++++ b/DEBIAN_build/compat 2019-08-16 23:28:58.020938096 -0400 +@@ -0,0 +1 @@ ++9 +diff -ruN a/DEBIAN_build/control b/DEBIAN_build/control +--- a/DEBIAN_build/control 2019-08-16 05:11:33.974949327 -0400 ++++ b/DEBIAN_build/control 2019-08-19 21:28:07.155722725 -0400 +@@ -1,9 +1,22 @@ +-Package: _PACKAGE_ +-Version: _VERSION_ +-Section: admin ++Source: hsflowd ++Maintainer: Neil McKee [neil.mckee@inmon.com] ++Uploaders: DellEMC ++Section: net ++Priority: optional ++Build-Depends: dh-exec (>=0.3), debhelper (>= 9), autotools-dev ++Standards-Version: 1.0.0 ++ ++Package: hsflowd ++Section: admin + Priority: optional +-Architecture: all ++Architecture: any + Essential: no +-Maintainer: Neil McKee [neil.mckee@inmon.com] + Description: sFlow(R) monitoring agent + Homepage: sflow.net ++ ++Package: hsflowd-dbg ++Architecture: any ++Section: debug ++Priority: extra ++Depends: hsflowd ++Description: debugging symbols for hsflowd +diff -ruN a/DEBIAN_build/rules b/DEBIAN_build/rules +--- a/DEBIAN_build/rules 1969-12-31 19:00:00.000000000 -0500 ++++ b/DEBIAN_build/rules 2019-08-19 22:20:42.998569601 -0400 +@@ -0,0 +1,31 @@ ++#!/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 ++ ++%: ++ dh $@ ++ ++binary: ++ dh_gencontrol ++ dh_strip -phsflowd --dbg-package=hsflowd-dbg ++ dpkg-deb --build debian/hsflowd-dbg hsflowd-dbg_$(HSFLOWD_VERSION)-$(HSFLOWD_SUBVERSION)_$(CONFIGURED_ARCH).deb ++ dpkg-deb --build debian/hsflowd hsflowd_$(HSFLOWD_VERSION)-$(HSFLOWD_SUBVERSION)_$(CONFIGURED_ARCH).deb ++ ++override_dh_auto_build: ++ make sonic-deb FEATURES="SONIC" ++ ++override_dh_auto_configure: ++ ++override_dh_auto_install: ++ ++override_dh_auto_test: ++ ++override_dh_auto_clean: ++ ++override_dh_clean: +diff -ruN a/Makefile b/Makefile +--- a/Makefile 2019-08-16 21:34:25.167679297 -0400 ++++ b/Makefile 2019-08-19 22:20:23.758479002 -0400 +@@ -146,6 +146,23 @@ + cd ..; \ + dpkg-deb --build debian hsflowd_$${MYVER}-$${MYREL}_$$MYARCH.deb + ++sonic-deb: $(PROG) ++ MYARCH=`uname -m|sed 's/x86_64/amd64/'`; \ ++ MYVER=`./getVersion`; \ ++ MYREL=`./getRelease`; \ ++ PLATFORM=`uname`; \ ++ mkdir -p debian/usr/sbin; \ ++ mkdir -p debian/etc/init.d; \ ++ mkdir -p debian/etc/hsflowd/modules; \ ++ mkdir -p debian/lib/systemd/system; \ ++ mkdir -p debian/etc/dbus-1/system.d; \ ++ cd src/$$PLATFORM; $(MAKE) VERSION=$$MYVER RELEASE=$$MYREL INSTROOT="../../debian/hsflowd" install; cd ../..; \ ++ pwd; \ ++ cd debian/hsflowd; \ ++ find . -type d | xargs chmod 755; \ ++ md5sum `find usr etc -type f` > md5sums; \ ++ cd ../..; ++ + xenserver: xenrpm + cd xenserver-ddk; $(MAKE) clean; $(MAKE) + diff --git a/src/sflow/hsflowd/patch/series b/src/sflow/hsflowd/patch/series new file mode 100644 index 000000000000..90f9e47462e5 --- /dev/null +++ b/src/sflow/hsflowd/patch/series @@ -0,0 +1,2 @@ +0001-host_sflow_psample.patch +0002-host_sflow_debian.patch diff --git a/src/sflow/psample/Makefile b/src/sflow/psample/Makefile new file mode 100644 index 000000000000..3f03c249989a --- /dev/null +++ b/src/sflow/psample/Makefile @@ -0,0 +1,20 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +MAIN_TARGET = $(PSAMPLE) + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + + rm -fr ./libpsample + git clone https://github.com/Mellanox/libpsample.git + cp -r debian libpsample + + pushd ./libpsample + git checkout -b libpsample -f e48fad2 + + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + popd + + mv $* $(DEST)/ + diff --git a/src/sflow/psample/debian/changelog b/src/sflow/psample/debian/changelog new file mode 100644 index 000000000000..be9af0d6d42a --- /dev/null +++ b/src/sflow/psample/debian/changelog @@ -0,0 +1,6 @@ +psample (1.1-1) UNRELEASED; urgency=medium + + [ DellEMC ] + * Initial release : based on https://github.com/Mellanox/libpsample + + -- DellEMC Mon, 29 Jul 2019 07:08:02 -0400 diff --git a/src/sflow/psample/debian/compat b/src/sflow/psample/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/src/sflow/psample/debian/compat @@ -0,0 +1 @@ +9 diff --git a/src/sflow/psample/debian/control b/src/sflow/psample/debian/control new file mode 100644 index 000000000000..5c65e1e774a6 --- /dev/null +++ b/src/sflow/psample/debian/control @@ -0,0 +1,11 @@ +Source: psample +Maintainer: DellEMC +Section: devel +Priority: optional +Build-Depends: dh-exec (>=0.3), debhelper (>= 9), autotools-dev +Standards-Version: 1.0.0 + +Package: psample +Architecture: any +Depends: ${shlibs:Depends} +Description: This package contains psample from https://github.com/Mellanox/libpsample diff --git a/src/sflow/psample/debian/psample.install b/src/sflow/psample/debian/psample.install new file mode 100644 index 000000000000..36d4eac1a85b --- /dev/null +++ b/src/sflow/psample/debian/psample.install @@ -0,0 +1,4 @@ +bin/psample usr/bin +lib/libpsample.so.1.0 lib/x86_64-linux-gnu +lib/libpsample.so.1 lib/x86_64-linux-gnu +lib/libpsample.so lib/x86_64-linux-gnu diff --git a/src/sflow/psample/debian/rules b/src/sflow/psample/debian/rules new file mode 100755 index 000000000000..73f484d32581 --- /dev/null +++ b/src/sflow/psample/debian/rules @@ -0,0 +1,19 @@ +#!/usr/bin/make -f + +# main packaging script based on dh7 syntax +%: + dh $@ + +override_dh_auto_build: + cmake . && make + +override_dh_auto_install: + +override_dh_auto_test: + +override_dh_auto_clean: + +override_dh_strip: + +override_dh_clean: + diff --git a/src/sflow/sflowtool/Makefile b/src/sflow/sflowtool/Makefile new file mode 100644 index 000000000000..10a3f2d24dea --- /dev/null +++ b/src/sflow/sflowtool/Makefile @@ -0,0 +1,19 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +MAIN_TARGET = $(SFLOWTOOL) + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + + rm -fr ./sflowtool + git clone https://github.com/sflow/sflowtool + cp -r debian sflowtool + + pushd ./sflowtool + git checkout -b sflowtool -f 6c2963b + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + popd + + mv $* $(DEST)/ + diff --git a/src/sflow/sflowtool/debian/changelog b/src/sflow/sflowtool/debian/changelog new file mode 100644 index 000000000000..df40c7c37de1 --- /dev/null +++ b/src/sflow/sflowtool/debian/changelog @@ -0,0 +1,6 @@ +sflowtool (5.04) UNRELEASED; urgency=medium + + [ DellEMC ] + * Initial release : based on https://github.com/sflow/sflowtool + + -- DellEMC Mon, 29 Jul 2019 07:08:02 -0400 diff --git a/src/sflow/sflowtool/debian/compat b/src/sflow/sflowtool/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/src/sflow/sflowtool/debian/compat @@ -0,0 +1 @@ +9 diff --git a/src/sflow/sflowtool/debian/control b/src/sflow/sflowtool/debian/control new file mode 100644 index 000000000000..f2d971aee2bd --- /dev/null +++ b/src/sflow/sflowtool/debian/control @@ -0,0 +1,11 @@ +Source: sflowtool +Maintainer: DellEMC +Section: devel +Priority: optional +Build-Depends: dh-exec (>=0.3), debhelper (>= 9), autotools-dev +Standards-Version: 1.0.0 + +Package: sflowtool +Architecture: any +Depends: ${shlibs:Depends} +Description: This package contains sflowtool from https://github.com/sflow/sflowtool diff --git a/src/sflow/sflowtool/debian/rules b/src/sflow/sflowtool/debian/rules new file mode 100755 index 000000000000..37ee344a2a4a --- /dev/null +++ b/src/sflow/sflowtool/debian/rules @@ -0,0 +1,19 @@ +#!/usr/bin/make -f + +# main packaging script based on dh7 syntax +%: + dh $@ + +override_dh_auto_build: + ./boot.sh && ./configure && make + +override_dh_auto_install: + +override_dh_auto_test: + +override_dh_auto_clean: + +override_dh_strip: + +override_dh_clean: + diff --git a/src/sflow/sflowtool/debian/sflowtool.install b/src/sflow/sflowtool/debian/sflowtool.install new file mode 100644 index 000000000000..9b32e0709b5a --- /dev/null +++ b/src/sflow/sflowtool/debian/sflowtool.install @@ -0,0 +1 @@ +src/sflowtool usr/bin diff --git a/src/snmpd/patch-5.7.3+dfsg/0006-From-Jiri-Cervenka-snmpd-Fixed-agentx-crashing-and-or-freezing-on-timeout.patch b/src/snmpd/patch-5.7.3+dfsg/0006-From-Jiri-Cervenka-snmpd-Fixed-agentx-crashing-and-or-freezing-on-timeout.patch new file mode 100644 index 000000000000..d11a9d6d75e9 --- /dev/null +++ b/src/snmpd/patch-5.7.3+dfsg/0006-From-Jiri-Cervenka-snmpd-Fixed-agentx-crashing-and-or-freezing-on-timeout.patch @@ -0,0 +1,211 @@ +From a5782d0673044ad0c621daed7975f53238bb038e Mon Sep 17 00:00:00 2001 +From: Renuka Manavalan +Date: Tue, 10 Sep 2019 17:51:45 +0000 +Subject: [PATCH] Patch from SourceForge: net-snmp commit #793d59 Avoids snmpd + crash when sub agent timesout. + +--- + agent/mibgroup/agentx/master_admin.c | 1 + + agent/snmp_agent.c | 81 ++++++++++++++++++---------- + include/net-snmp/agent/snmp_agent.h | 5 ++ + 3 files changed, 60 insertions(+), 27 deletions(-) + +diff --git a/agent/mibgroup/agentx/master_admin.c b/agent/mibgroup/agentx/master_admin.c +index 4dc1aa7..8c1d194 100644 +--- a/agent/mibgroup/agentx/master_admin.c ++++ b/agent/mibgroup/agentx/master_admin.c +@@ -158,6 +158,7 @@ close_agentx_session(netsnmp_session * session, int sessid) + for (sp = session->subsession; sp != NULL; sp = sp->next) { + + if (sp->sessid == sessid) { ++ netsnmp_remove_delegated_requests_for_session(sp); + unregister_mibs_by_session(sp); + unregister_index_by_session(sp); + unregister_sysORTable_by_session(sp); +diff --git a/agent/snmp_agent.c b/agent/snmp_agent.c +index b96d650..7cacd1a 100644 +--- a/agent/snmp_agent.c ++++ b/agent/snmp_agent.c +@@ -1409,6 +1409,7 @@ init_agent_snmp_session(netsnmp_session * session, netsnmp_pdu *pdu) + asp->treecache_num = -1; + asp->treecache_len = 0; + asp->reqinfo = SNMP_MALLOC_TYPEDEF(netsnmp_agent_request_info); ++ asp->flags = SNMP_AGENT_FLAGS_NONE; + DEBUGMSGTL(("verbose:asp", "asp %p reqinfo %p created\n", + asp, asp->reqinfo)); + +@@ -1457,6 +1458,9 @@ netsnmp_check_for_delegated(netsnmp_agent_session *asp) + + if (NULL == asp->treecache) + return 0; ++ ++ if (asp->flags & SNMP_AGENT_FLAGS_CANCEL_IN_PROGRESS) ++ return 0; + + for (i = 0; i <= asp->treecache_num; i++) { + for (request = asp->treecache[i].requests_begin; request; +@@ -1535,39 +1539,48 @@ int + netsnmp_remove_delegated_requests_for_session(netsnmp_session *sess) + { + netsnmp_agent_session *asp; +- int count = 0; ++ int total_count = 0; + + for (asp = agent_delegated_list; asp; asp = asp->next) { + /* + * check each request + */ ++ int i; ++ int count = 0; + netsnmp_request_info *request; +- for(request = asp->requests; request; request = request->next) { +- /* +- * check session +- */ +- netsnmp_assert(NULL!=request->subtree); +- if(request->subtree->session != sess) +- continue; ++ for (i = 0; i <= asp->treecache_num; i++) { ++ for (request = asp->treecache[i].requests_begin; request; ++ request = request->next) { ++ /* ++ * check session ++ */ ++ netsnmp_assert(NULL!=request->subtree); ++ if(request->subtree->session != sess) ++ continue; + +- /* +- * matched! mark request as done +- */ +- netsnmp_request_set_error(request, SNMP_ERR_GENERR); +- ++count; ++ /* ++ * matched! mark request as done ++ */ ++ netsnmp_request_set_error(request, SNMP_ERR_GENERR); ++ ++count; ++ } ++ } ++ if (count) { ++ asp->flags |= SNMP_AGENT_FLAGS_CANCEL_IN_PROGRESS; ++ total_count += count; + } + } + + /* + * if we found any, that request may be finished now + */ +- if(count) { ++ if(total_count) { + DEBUGMSGTL(("snmp_agent", "removed %d delegated request(s) for session " +- "%8p\n", count, sess)); +- netsnmp_check_outstanding_agent_requests(); ++ "%8p\n", total_count, sess)); ++ netsnmp_check_delegated_requests(); + } + +- return count; ++ return total_count; + } + + int +@@ -2739,19 +2752,11 @@ handle_var_requests(netsnmp_agent_session *asp) + return final_status; + } + +-/* +- * loop through our sessions known delegated sessions and check to see +- * if they've completed yet. If there are no more delegated sessions, +- * check for and process any queued requests +- */ + void +-netsnmp_check_outstanding_agent_requests(void) ++netsnmp_check_delegated_requests(void) + { + netsnmp_agent_session *asp, *prev_asp = NULL, *next_asp = NULL; + +- /* +- * deal with delegated requests +- */ + for (asp = agent_delegated_list; asp; asp = next_asp) { + next_asp = asp->next; /* save in case we clean up asp */ + if (!netsnmp_check_for_delegated(asp)) { +@@ -2790,6 +2795,23 @@ netsnmp_check_outstanding_agent_requests(void) + prev_asp = asp; + } + } ++} ++ ++ ++/* ++ * loop through our sessions known delegated sessions and check to see ++ * if they've completed yet. If there are no more delegated sessions, ++ * check for and process any queued requests ++ */ ++void ++netsnmp_check_outstanding_agent_requests(void) ++{ ++ netsnmp_agent_session *asp; ++ ++ /* ++ * deal with delegated requests ++ */ ++ netsnmp_check_delegated_requests(); + + /* + * if we are processing a set and there are more delegated +@@ -2819,7 +2841,8 @@ netsnmp_check_outstanding_agent_requests(void) + + netsnmp_processing_set = netsnmp_agent_queued_list; + DEBUGMSGTL(("snmp_agent", "SET request remains queued while " +- "delegated requests finish, asp = %8p\n", asp)); ++ "delegated requests finish, asp = %8p\n", ++ agent_delegated_list)); + break; + } + #endif /* NETSNMP_NO_WRITE_SUPPORT */ +@@ -2880,6 +2903,10 @@ check_delayed_request(netsnmp_agent_session *asp) + case SNMP_MSG_GETBULK: + case SNMP_MSG_GETNEXT: + netsnmp_check_all_requests_status(asp, 0); ++ if (asp->flags & SNMP_AGENT_FLAGS_CANCEL_IN_PROGRESS) { ++ DEBUGMSGTL(("snmp_agent","canceling next walk for asp %p\n", asp)); ++ break; ++ } + handle_getnext_loop(asp); + if (netsnmp_check_for_delegated(asp) && + netsnmp_check_transaction_id(asp->pdu->transid) != +diff --git a/include/net-snmp/agent/snmp_agent.h b/include/net-snmp/agent/snmp_agent.h +index aad8837..43f4fff 100644 +--- a/include/net-snmp/agent/snmp_agent.h ++++ b/include/net-snmp/agent/snmp_agent.h +@@ -32,6 +32,9 @@ extern "C" { + #define SNMP_MAX_PDU_SIZE 64000 /* local constraint on PDU size sent by agent + * (see also SNMP_MAX_MSG_SIZE in snmp_api.h) */ + ++#define SNMP_AGENT_FLAGS_NONE 0x0 ++#define SNMP_AGENT_FLAGS_CANCEL_IN_PROGRESS 0x1 ++ + /* + * If non-zero, causes the addresses of peers to be logged when receptions + * occur. +@@ -205,6 +208,7 @@ extern "C" { + int treecache_num; /* number of current cache entries */ + netsnmp_cachemap *cache_store; + int vbcount; ++ int flags; + } netsnmp_agent_session; + + /* +@@ -240,6 +244,7 @@ extern "C" { + int init_master_agent(void); + void shutdown_master_agent(void); + int agent_check_and_process(int block); ++ void netsnmp_check_delegated_requests(void); + void netsnmp_check_outstanding_agent_requests(void); + + int netsnmp_request_set_error(netsnmp_request_info *request, +-- +2.17.1 + diff --git a/src/snmpd/patch-5.7.3+dfsg/0006-Release-all-requests-that-use-this-session.patch b/src/snmpd/patch-5.7.3+dfsg/0006-Release-all-requests-that-use-this-session.patch deleted file mode 100644 index 66a18eb17245..000000000000 --- a/src/snmpd/patch-5.7.3+dfsg/0006-Release-all-requests-that-use-this-session.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 84846206c7ee230bd7b6274af98513952c4a7a7f Mon Sep 17 00:00:00 2001 -From: Renuka Manavalan -Date: Wed, 7 Aug 2019 21:48:33 +0000 -Subject: [PATCH] Release all requests that use this session. - ---- - agent/snmp_agent.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/agent/snmp_agent.c b/agent/snmp_agent.c -index b96d650..ee3b0da 100644 ---- a/agent/snmp_agent.c -+++ b/agent/snmp_agent.c -@@ -1542,7 +1542,8 @@ netsnmp_remove_delegated_requests_for_session(netsnmp_session *sess) - * check each request - */ - netsnmp_request_info *request; -- for(request = asp->requests; request; request = request->next) { -+ int i; -+ for(i = 0, request = asp->requests; i < asp->vbcount; ++i, ++request) { - /* - * check session - */ --- -2.17.1 - diff --git a/src/snmpd/patch-5.7.3+dfsg/0007-Linux-VRF-5.7.3-Support.patch b/src/snmpd/patch-5.7.3+dfsg/0007-Linux-VRF-5.7.3-Support.patch new file mode 100755 index 000000000000..48d13d7f62d6 --- /dev/null +++ b/src/snmpd/patch-5.7.3+dfsg/0007-Linux-VRF-5.7.3-Support.patch @@ -0,0 +1,799 @@ +From 49ce7fc078dfa8c1a1688e05de4e2d151dbcd76a Mon Sep 17 00:00:00 2001 +From: Harish Venkatraman +Date: Wed, 17 Oct 2018 15:22:04 -0700 +Subject: [PATCH] Linux-VRF 5.7.3 Support from https://sourceforge.net/p/net-snmp/patches/1376/ + +Sourceforge commits related to this consolidated patch are given below. +https://sourceforge.net/p/net-snmp/code/ci/0b637fea62c7b6dc467b94206d0bd2dec6f912ca/ +https://sourceforge.net/p/net-snmp/code/ci/19ba7b0a6b56d201a8563fe6505cd82e313c1c9c/ +https://sourceforge.net/p/net-snmp/code/ci/76336fb63bb74b4dede5dda5c14fb8cf2d60be8e/ +https://sourceforge.net/p/net-snmp/code/ci/c7398de4122102b3250e6dac7c09dbc5d09f1840/ +https://sourceforge.net/p/net-snmp/code/ci/0831ed64a39a34dc040eabe39d0229b07fa2a8a5/ +https://sourceforge.net/p/net-snmp/code/ci/62f6babcc7cfc54c79b442b8a7f45662b4ddc807/ +https://sourceforge.net/p/net-snmp/code/ci/313949522c4d0ddfeac72195fa63512955d9eb28/ + + +This consolidated patch adds native support for VRFs to snmpd. NCLU patches in this same +CCR will be added shortly. The VRF is specified for both listening +addresses as well as TRAP sinks with the 'ipaddr%iface' syntax: + +agentAddress 10.0.1.7%mgmt,22.22.22.22%red +trapsink 10.0.1.9%mgmt +trap2sink 22.22.22.25%red + +The SO_BINDTODEVICE socket option is used to bind a VRF to a particular +socket. + +Testing done included VRFs as well as non-VRF functionality with traps +(v1, v2, and v3) + +--- + agent/agent_trap.c | 20 ++++++++++-- + agent/mibgroup/agentx/master.c | 2 +- + agent/mibgroup/agentx/subagent.c | 2 +- + agent/mibgroup/target/target.c | 3 +- + agent/snmp_agent.c | 21 ++++++++++++- + apps/agentxtrap.c | 2 +- + apps/snmptrap.c | 2 +- + apps/snmptrapd.c | 2 +- + include/net-snmp/library/snmpTCPDomain.h | 2 +- + include/net-snmp/library/snmpUDPBaseDomain.h | 2 +- + include/net-snmp/library/snmpUDPDomain.h | 2 +- + include/net-snmp/library/snmpUDPIPv4BaseDomain.h | 2 +- + include/net-snmp/library/snmpUDPIPv6Domain.h | 2 +- + include/net-snmp/library/snmp_transport.h | 19 +++++++----- + snmplib/snmp_api.c | 4 +-- + snmplib/snmp_transport.c | 26 ++++++++-------- + snmplib/transports/snmpAliasDomain.c | 6 ++-- + snmplib/transports/snmpTCPDomain.c | 16 +++++++--- + snmplib/transports/snmpUDPBaseDomain.c | 39 ++++++++++++++++++------ + snmplib/transports/snmpUDPDomain.c | 15 ++++----- + snmplib/transports/snmpUDPIPv4BaseDomain.c | 4 +-- + snmplib/transports/snmpUDPIPv6Domain.c | 19 ++++----- + snmplib/transports/snmpUnixDomain.c | 5 +-- + 23 files changed, 141 insertions(+), 76 deletions(-) + +diff --git a/agent/agent_trap.c b/agent/agent_trap.c +index 080b8bf..c488ac9 100644 +--- a/agent/agent_trap.c ++++ b/agent/agent_trap.c +@@ -226,6 +226,7 @@ create_trap_session2(const char *sink, const char* sinkport, + { + netsnmp_transport *t; + netsnmp_session session, *sesp; ++ char *iface; + + memset(&session, 0, sizeof(netsnmp_session)); + session.version = version; +@@ -250,7 +251,14 @@ create_trap_session2(const char *sink, const char* sinkport, + ((0 == strcmp("localhost",sink)) || (0 == strcmp("127.0.0.1",sink)))) + session.localname = strdup("localhost"); + +- t = netsnmp_tdomain_transport_full("snmptrap", sink, 0, NULL, sinkport); ++ /* ++ * if given an iface (ip%iface) in sink, send the iface too ++ */ ++ iface = strchr(sink, '%'); ++ if (iface) ++ *iface++ = '\0'; ++ ++ t = netsnmp_tdomain_transport_full("snmptrap", sink, 0, NULL, sinkport, iface); + if (t != NULL) { + sesp = snmp_add(&session, t, NULL, NULL); + +@@ -1219,6 +1227,7 @@ snmpd_parse_config_trapsess(const char *word, char *cptr) + netsnmp_session session, *ss; + netsnmp_transport *transport; + size_t len; ++ char *iface; + + /* + * inform or trap? default to trap +@@ -1240,7 +1249,14 @@ snmpd_parse_config_trapsess(const char *word, char *cptr) + NETSNMP_PARSE_ARGS_NOLOGGING | + NETSNMP_PARSE_ARGS_NOZERO); + +- transport = netsnmp_transport_open_client("snmptrap", session.peername); ++ /* ++ * if iface is given in peer, we will need to bind to that iface ++ */ ++ iface = strchr(session.peername, '%'); ++ if (iface) ++ *iface++ = '\0'; ++ ++ transport = netsnmp_transport_open_client("snmptrap", session.peername, iface); + if (transport == NULL) { + config_perror("snmpd: failed to parse this line."); + return; +diff --git a/agent/mibgroup/agentx/master.c b/agent/mibgroup/agentx/master.c +index baeebaf..6733e7f 100644 +--- a/agent/mibgroup/agentx/master.c ++++ b/agent/mibgroup/agentx/master.c +@@ -126,7 +126,7 @@ real_init_master(void) + sess.remote_port = 0; + sess.callback = handle_master_agentx_packet; + errno = 0; +- t = netsnmp_transport_open_server("agentx", sess.peername); ++ t = netsnmp_transport_open_server("agentx", sess.peername, NULL); + if (t == NULL) { + /* + * diagnose snmp_open errors with the input netsnmp_session +diff --git a/agent/mibgroup/agentx/subagent.c b/agent/mibgroup/agentx/subagent.c +index 1f9d31c..6d38a34 100644 +--- a/agent/mibgroup/agentx/subagent.c ++++ b/agent/mibgroup/agentx/subagent.c +@@ -843,7 +843,7 @@ subagent_open_master_session(void) + + agentx_socket = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, + NETSNMP_DS_AGENT_X_SOCKET); +- t = netsnmp_transport_open_client("agentx", agentx_socket); ++ t = netsnmp_transport_open_client("agentx", agentx_socket, NULL); + if (t == NULL) { + /* + * Diagnose snmp_open errors with the input +diff --git a/agent/mibgroup/target/target.c b/agent/mibgroup/target/target.c +index 5619e35..6f58817 100644 +--- a/agent/mibgroup/target/target.c ++++ b/agent/mibgroup/target/target.c +@@ -154,7 +154,8 @@ get_target_sessions(char *taglist, TargetFilterFunction * filterfunct, + tAddress, + targaddrs-> + tAddressLen, +- 0); ++ 0, ++ NULL); + if (t == NULL) { + DEBUGMSGTL(("target_sessions", + "bad dest \"")); +diff --git a/agent/snmp_agent.c b/agent/snmp_agent.c +index b96d650..281e8b2 100644 +--- a/agent/snmp_agent.c ++++ b/agent/snmp_agent.c +@@ -1270,6 +1270,7 @@ init_master_agent(void) + char *cptr; + char *buf = NULL; + char *st; ++ char *iface; + + /* default to a default cache size */ + netsnmp_set_lookup_cache_size(-1); +@@ -1318,6 +1319,9 @@ init_master_agent(void) + * AAL5PVC:itf.vpi.vci (if supported) + * IPX:[network]:node[/port] (if supported) + * ++ * ++ * New format to specify an interface for binding along with IP address ++ * address%iface + */ + + cptr = st; +@@ -1334,7 +1338,22 @@ init_master_agent(void) + "requested\n")); + break; + } +- transport = netsnmp_transport_open_server("snmp", cptr); ++ ++ /* ++ * at some point, we may want to add the special listendevice ++ * keyword support. Not sure how to interact with ip%iface ++ iface = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, ++ NETSNMP_DS_AGENT_LISTEN_DEVICE); ++ */ ++ ++ /* Look for %iface so we can send along a specific interface to ++ setsockopt SO_BINDTODEVICE later. */ ++ iface = strchr(cptr, '%'); ++ if (iface) ++ *iface++ = '\0'; ++ ++ transport = netsnmp_transport_open_server("snmp", cptr, iface); ++ + + if (transport == NULL) { + snmp_log(LOG_ERR, "Error opening specified endpoint \"%s\"\n", +diff --git a/apps/agentxtrap.c b/apps/agentxtrap.c +index 4df423c..ebd81a3 100644 +--- a/apps/agentxtrap.c ++++ b/apps/agentxtrap.c +@@ -231,7 +231,7 @@ ConnectingEntry(UNUSED tState self) + + if(!(t = netsnmp_transport_open_client( + "agentx", netsnmp_ds_get_string( +- NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET)))) { ++ NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET), NULL))) { + snmp_log(LOG_ERR, "Failed to connect to AgentX server\n"); + change_state(&Exit); + } else if(!(sess = snmp_sess_add_ex( +diff --git a/apps/snmptrap.c b/apps/snmptrap.c +index 7c086db..28d5257 100644 +--- a/apps/snmptrap.c ++++ b/apps/snmptrap.c +@@ -215,7 +215,7 @@ main(int argc, char *argv[]) + } + + ss = snmp_add(&session, +- netsnmp_transport_open_client("snmptrap", session.peername), ++ netsnmp_transport_open_client("snmptrap", session.peername, NULL), + NULL, NULL); + if (ss == NULL) { + /* +diff --git a/apps/snmptrapd.c b/apps/snmptrapd.c +index bce0d47..122a502 100644 +--- a/apps/snmptrapd.c ++++ b/apps/snmptrapd.c +@@ -1186,7 +1186,7 @@ main(int argc, char *argv[]) + *sep = 0; + } + +- transport = netsnmp_transport_open_server("snmptrap", cp); ++ transport = netsnmp_transport_open_server("snmptrap", cp, NULL); + if (transport == NULL) { + snmp_log(LOG_ERR, "couldn't open %s -- errno %d (\"%s\")\n", + cp, errno, strerror(errno)); +diff --git a/include/net-snmp/library/snmpTCPDomain.h b/include/net-snmp/library/snmpTCPDomain.h +index c45856b..3b1fef5 100644 +--- a/include/net-snmp/library/snmpTCPDomain.h ++++ b/include/net-snmp/library/snmpTCPDomain.h +@@ -25,7 +25,7 @@ extern "C" { + #define TRANSPORT_DOMAIN_TCP_IP 1,3,6,1,2,1,100,1,5 + NETSNMP_IMPORT oid netsnmp_snmpTCPDomain[]; + +-netsnmp_transport *netsnmp_tcp_transport(struct sockaddr_in *addr, int local); ++netsnmp_transport *netsnmp_tcp_transport(struct sockaddr_in *addr, int local, char *iface); + + /* + * "Constructor" for transport domain object. +diff --git a/include/net-snmp/library/snmpUDPBaseDomain.h b/include/net-snmp/library/snmpUDPBaseDomain.h +index b9d2c34..0ab2fe5 100644 +--- a/include/net-snmp/library/snmpUDPBaseDomain.h ++++ b/include/net-snmp/library/snmpUDPBaseDomain.h +@@ -18,7 +18,7 @@ extern "C" { + /* + * Prototypes + */ +- void _netsnmp_udp_sockopt_set(int fd, int local); ++ void _netsnmp_udp_sockopt_set(int fd, int local, char *iface); + int netsnmp_udpbase_recv(netsnmp_transport *t, void *buf, int size, + void **opaque, int *olength); + int netsnmp_udpbase_send(netsnmp_transport *t, void *buf, int size, +diff --git a/include/net-snmp/library/snmpUDPDomain.h b/include/net-snmp/library/snmpUDPDomain.h +index 3a09dfd..e402cd8 100644 +--- a/include/net-snmp/library/snmpUDPDomain.h ++++ b/include/net-snmp/library/snmpUDPDomain.h +@@ -18,7 +18,7 @@ extern "C" { + config_require(UDPIPv4Base) + #include + +-netsnmp_transport *netsnmp_udp_transport(struct sockaddr_in *addr, int local); ++netsnmp_transport *netsnmp_udp_transport(struct sockaddr_in *addr, int local, char*iface); + + + /* +diff --git a/include/net-snmp/library/snmpUDPIPv4BaseDomain.h b/include/net-snmp/library/snmpUDPIPv4BaseDomain.h +index 6f7f2c2..8d3e906 100644 +--- a/include/net-snmp/library/snmpUDPIPv4BaseDomain.h ++++ b/include/net-snmp/library/snmpUDPIPv4BaseDomain.h +@@ -25,7 +25,7 @@ extern "C" { + */ + + netsnmp_transport *netsnmp_udpipv4base_transport(struct sockaddr_in *addr, +- int local); ++ int local, char *iface); + + #if defined(HAVE_IP_PKTINFO) || defined(HAVE_IP_RECVDSTADDR) + int netsnmp_udpipv4_recvfrom(int s, void *buf, int len, +diff --git a/include/net-snmp/library/snmpUDPIPv6Domain.h b/include/net-snmp/library/snmpUDPIPv6Domain.h +index 83eba2c..009c510 100644 +--- a/include/net-snmp/library/snmpUDPIPv6Domain.h ++++ b/include/net-snmp/library/snmpUDPIPv6Domain.h +@@ -23,7 +23,7 @@ config_require(UDPBase) + NETSNMP_IMPORT oid netsnmp_UDPIPv6Domain[]; + + netsnmp_transport *netsnmp_udp6_transport(struct sockaddr_in6 *addr, +- int local); ++ int local, char *iface); + + + /* +diff --git a/include/net-snmp/library/snmp_transport.h b/include/net-snmp/library/snmp_transport.h +index 4162897..a3deda7 100644 +--- a/include/net-snmp/library/snmp_transport.h ++++ b/include/net-snmp/library/snmp_transport.h +@@ -206,14 +206,14 @@ typedef struct netsnmp_tdomain_s { + * The f_create_from_tstring field is deprecated, please do not use it + * for new code and try to migrate old code away from using it. + */ +- netsnmp_transport *(*f_create_from_tstring) (const char *, int); ++ netsnmp_transport *(*f_create_from_tstring) (const char *, int, char *); + +- netsnmp_transport *(*f_create_from_ostring) (const u_char *, size_t, int); ++ netsnmp_transport *(*f_create_from_ostring) (const u_char *, size_t, int, char *); + + struct netsnmp_tdomain_s *next; + + netsnmp_transport *(*f_create_from_tstring_new) (const char *, int, +- const char*); ++ const char*, char *); + + } netsnmp_tdomain; + +@@ -273,29 +273,32 @@ void netsnmp_tdomain_init(void); + NETSNMP_IMPORT + netsnmp_transport *netsnmp_tdomain_transport(const char *str, + int local, +- const char *default_domain); ++ const char *default_domain, ++ char *iface); + + NETSNMP_IMPORT + netsnmp_transport *netsnmp_tdomain_transport_full(const char *application, + const char *str, + int local, + const char *default_domain, +- const char *default_target); ++ const char *default_target, ++ char *iface); + + NETSNMP_IMPORT + netsnmp_transport *netsnmp_tdomain_transport_oid(const oid * dom, + size_t dom_len, + const u_char * o, + size_t o_len, +- int local); ++ int local, ++ char *iface); + + NETSNMP_IMPORT + netsnmp_transport* +-netsnmp_transport_open_client(const char* application, const char* str); ++netsnmp_transport_open_client(const char* application, const char* str, char *iface); + + NETSNMP_IMPORT + netsnmp_transport* +-netsnmp_transport_open_server(const char* application, const char* str); ++netsnmp_transport_open_server(const char* application, const char* str, char *iface); + + netsnmp_transport* + netsnmp_transport_open(const char* application, const char* str, int local); +diff --git a/snmplib/snmp_api.c b/snmplib/snmp_api.c +index d155c99..5128c56 100644 +--- a/snmplib/snmp_api.c ++++ b/snmplib/snmp_api.c +@@ -1557,12 +1557,12 @@ _sess_open(netsnmp_session * in_session) + transport = + netsnmp_tdomain_transport_full("snmp", in_session->peername, + in_session->local_port, "tcp,tcp6", +- NULL); ++ NULL, NULL); + } else { + transport = + netsnmp_tdomain_transport_full("snmp", in_session->peername, + in_session->local_port, "udp,udp6", +- NULL); ++ NULL, NULL); + } + + if (NULL != clientaddr_save) +diff --git a/snmplib/snmp_transport.c b/snmplib/snmp_transport.c +index ada4781..40cd631 100644 +--- a/snmplib/snmp_transport.c ++++ b/snmplib/snmp_transport.c +@@ -491,7 +491,8 @@ netsnmp_transport * + netsnmp_tdomain_transport_full(const char *application, + const char *str, int local, + const char *default_domain, +- const char *default_target) ++ const char *default_target, ++ char *iface) + { + netsnmp_tdomain *match = NULL; + const char *addr = NULL; +@@ -646,10 +647,10 @@ netsnmp_tdomain_transport_full(const char *application, + NETSNMP_LOGONCE((LOG_WARNING, + "transport domain %s uses deprecated f_create_from_tstring\n", + match->prefix[0])); +- t = match->f_create_from_tstring(addr, local); ++ t = match->f_create_from_tstring(addr, local, iface); + } + else +- t = match->f_create_from_tstring_new(addr, local, addr2); ++ t = match->f_create_from_tstring_new(addr, local, addr2, iface); + if (t) { + if (lspec) { + free(lspec[0]); +@@ -676,10 +677,11 @@ netsnmp_tdomain_transport_full(const char *application, + + netsnmp_transport * + netsnmp_tdomain_transport(const char *str, int local, +- const char *default_domain) ++ const char *default_domain, ++ char *iface) + { + return netsnmp_tdomain_transport_full("snmp", str, local, default_domain, +- NULL); ++ NULL, iface); + } + + +@@ -687,7 +689,7 @@ netsnmp_tdomain_transport(const char *str, int local, + netsnmp_transport * + netsnmp_tdomain_transport_oid(const oid * dom, + size_t dom_len, +- const u_char * o, size_t o_len, int local) ++ const u_char * o, size_t o_len, int local, char *iface) + { + netsnmp_tdomain *d; + int i; +@@ -700,7 +702,7 @@ netsnmp_tdomain_transport_oid(const oid * dom, + for (i = 0; d->prefix[i] != NULL; i++) { + if (netsnmp_oid_equals(dom, dom_len, d->name, d->name_length) == + 0) { +- return d->f_create_from_ostring(o, o_len, local); ++ return d->f_create_from_ostring(o, o_len, local, iface); + } + } + } +@@ -713,19 +715,19 @@ netsnmp_tdomain_transport_oid(const oid * dom, + netsnmp_transport* + netsnmp_transport_open(const char* application, const char* str, int local) + { +- return netsnmp_tdomain_transport_full(application, str, local, NULL, NULL); ++ return netsnmp_tdomain_transport_full(application, str, local, NULL, NULL, NULL); + } + + netsnmp_transport* +-netsnmp_transport_open_server(const char* application, const char* str) ++netsnmp_transport_open_server(const char* application, const char* str, char *iface) + { +- return netsnmp_tdomain_transport_full(application, str, 1, NULL, NULL); ++ return netsnmp_tdomain_transport_full(application, str, 1, NULL, NULL, iface); + } + + netsnmp_transport* +-netsnmp_transport_open_client(const char* application, const char* str) ++netsnmp_transport_open_client(const char* application, const char* str, char *iface) + { +- return netsnmp_tdomain_transport_full(application, str, 0, NULL, NULL); ++ return netsnmp_tdomain_transport_full(application, str, 0, NULL, NULL, iface); + } + + /** adds a transport to a linked list of transports. +diff --git a/snmplib/transports/snmpAliasDomain.c b/snmplib/transports/snmpAliasDomain.c +index eb50cad..dd7a007 100644 +--- a/snmplib/transports/snmpAliasDomain.c ++++ b/snmplib/transports/snmpAliasDomain.c +@@ -75,7 +75,7 @@ free_alias_config(void) { + + netsnmp_transport * + netsnmp_alias_create_tstring(const char *str, int local, +- const char *default_target) ++ const char *default_target, char *iface) + { + const char *aliasdata; + +@@ -85,13 +85,13 @@ netsnmp_alias_create_tstring(const char *str, int local, + return NULL; + } + +- return netsnmp_tdomain_transport(aliasdata,local,default_target); ++ return netsnmp_tdomain_transport(aliasdata,local,default_target, iface); + } + + + + netsnmp_transport * +-netsnmp_alias_create_ostring(const u_char * o, size_t o_len, int local) ++netsnmp_alias_create_ostring(const u_char * o, size_t o_len, int local, char *iface) + { + fprintf(stderr, "make ostring\n"); + return NULL; +diff --git a/snmplib/transports/snmpTCPDomain.c b/snmplib/transports/snmpTCPDomain.c +index 7feb028..6eb717e 100644 +--- a/snmplib/transports/snmpTCPDomain.c ++++ b/snmplib/transports/snmpTCPDomain.c +@@ -144,7 +144,7 @@ netsnmp_tcp_accept(netsnmp_transport *t) + */ + + netsnmp_transport * +-netsnmp_tcp_transport(struct sockaddr_in *addr, int local) ++netsnmp_tcp_transport(struct sockaddr_in *addr, int local, char *iface) + { + netsnmp_transport *t = NULL; + netsnmp_udp_addr_pair *addr_pair = NULL; +@@ -212,6 +212,11 @@ netsnmp_tcp_transport(struct sockaddr_in *addr, int local) + * We should set SO_REUSEADDR too. + */ + ++ if (iface && setsockopt(t->sock, SOL_SOCKET, SO_BINDTODEVICE, ++ iface, strlen(iface)) == -1) ++ snmp_log(LOG_ERR, "Bind interface %s to socket: %s\n", ++ iface, strerror(errno)); ++ + setsockopt(t->sock, SOL_SOCKET, SO_REUSEADDR, (void *)&opt, + sizeof(opt)); + +@@ -305,12 +310,13 @@ netsnmp_tcp_transport(struct sockaddr_in *addr, int local) + + netsnmp_transport * + netsnmp_tcp_create_tstring(const char *str, int local, +- const char *default_target) ++ const char *default_target, ++ char *iface) + { + struct sockaddr_in addr; + + if (netsnmp_sockaddr_in2(&addr, str, default_target)) { +- return netsnmp_tcp_transport(&addr, local); ++ return netsnmp_tcp_transport(&addr, local, iface); + } else { + return NULL; + } +@@ -319,7 +325,7 @@ netsnmp_tcp_create_tstring(const char *str, int local, + + + netsnmp_transport * +-netsnmp_tcp_create_ostring(const u_char * o, size_t o_len, int local) ++netsnmp_tcp_create_ostring(const u_char * o, size_t o_len, int local, char *iface) + { + struct sockaddr_in addr; + +@@ -328,7 +334,7 @@ netsnmp_tcp_create_ostring(const u_char * o, size_t o_len, int local) + addr.sin_family = AF_INET; + memcpy((u_char *) & (addr.sin_addr.s_addr), o, 4); + addr.sin_port = htons(porttmp); +- return netsnmp_tcp_transport(&addr, local); ++ return netsnmp_tcp_transport(&addr, local, iface); + } + return NULL; + } +diff --git a/snmplib/transports/snmpUDPBaseDomain.c b/snmplib/transports/snmpUDPBaseDomain.c +index 8497f71..7b415bc 100644 +--- a/snmplib/transports/snmpUDPBaseDomain.c ++++ b/snmplib/transports/snmpUDPBaseDomain.c +@@ -21,6 +21,9 @@ + #if HAVE_NETINET_IN_H + #include + #endif ++#if HAVE_NET_IF_H ++#include ++#endif + #if HAVE_ARPA_INET_H + #include + #endif +@@ -53,8 +56,14 @@ + #endif + + void +-_netsnmp_udp_sockopt_set(int fd, int local) ++_netsnmp_udp_sockopt_set(int fd, int local, char *iface) + { ++ ++ if (iface && setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, iface, strlen(iface)) == -1) ++ snmp_log(LOG_ERR, "Bind socket on interface: %s: %s\n", iface, strerror(errno)); ++ else if (iface) ++ DEBUGMSGTL(("socket:option", "setting SO_BINDTODEVICE to %s\n", iface)); ++ + #ifdef SO_BSDCOMPAT + /* + * Patch for Linux. Without this, UDP packets that fail get an ICMP +@@ -237,7 +246,10 @@ int netsnmp_udpbase_sendto(int fd, struct in_addr *srcip, int if_index, + struct msghdr m = { 0 }; + char cmsg[CMSG_SPACE(cmsg_data_size)]; + int rc; +- ++ char iface[IFNAMSIZ]; ++ socklen_t ifacelen = IFNAMSIZ; ++ ++ iface[0] = '\0'; + iov.iov_base = data; + iov.iov_len = len; + +@@ -269,14 +281,23 @@ int netsnmp_udpbase_sendto(int fd, struct in_addr *srcip, int if_index, + + memset(&ipi, 0, sizeof(ipi)); + /* +- * Except in the case of responding +- * to a broadcast, setting the ifindex +- * when responding results in incorrect +- * behavior of changing the source address +- * that the manager sees the response +- * come from. ++ * For asymmetric multihomed users, we only set ifindex to 0 ++ * to let kernel handle return if there was no iface bound to the socket. + */ +- ipi.ipi_ifindex = 0; ++ if (getsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, iface, &ifacelen) != 0) { ++ DEBUGMSGTL(("socket:option", "error getsockopt %s\n", strerror(errno))); ++ DEBUGMSGTL(("socket:option", "sendto: SO_BINDTODEVICE not set ifindex=0\n")); ++ ipi.ipi_ifindex = 0; ++ } else if (!ifacelen) { ++ DEBUGMSGTL(("socket:option", "sendto: SO_BINDTODEVICE not set ifacelen=%d ifindex=0\n", ++ ifacelen)); ++ ipi.ipi_ifindex = 0; ++ } else { ++ DEBUGMSGTL(("socket:option", "sendto: SO_BINDTODEVICE dev=%s using ifindex=%d\n", ++ iface, if_index)); ++ ipi.ipi_ifindex = if_index; ++ } ++ + #if defined(cygwin) + ipi.ipi_addr.s_addr = srcip->s_addr; + #else +diff --git a/snmplib/transports/snmpUDPDomain.c b/snmplib/transports/snmpUDPDomain.c +index a0abd8c..fc68303 100644 +--- a/snmplib/transports/snmpUDPDomain.c ++++ b/snmplib/transports/snmpUDPDomain.c +@@ -84,7 +84,7 @@ typedef netsnmp_indexed_addr_pair netsnmp_udp_addr_pair; + * not static, since snmpUDPIPv6Domain needs it, but not public, either. + * (ie don't put it in a public header.) + */ +-void _netsnmp_udp_sockopt_set(int fd, int server); ++void _netsnmp_udp_sockopt_set(int fd, int server, char *iface); + int + netsnmp_sockaddr_in2(struct sockaddr_in *addr, + const char *inpeername, const char *default_target); +@@ -125,11 +125,11 @@ int netsnmp_udp_sendto(int fd, struct in_addr *srcip, int if_index, struct socka + */ + + netsnmp_transport * +-netsnmp_udp_transport(struct sockaddr_in *addr, int local) ++netsnmp_udp_transport(struct sockaddr_in *addr, int local, char *iface) + { + netsnmp_transport *t = NULL; + +- t = netsnmp_udpipv4base_transport(addr, local); ++ t = netsnmp_udpipv4base_transport(addr, local, iface); + if (NULL == t) { + return NULL; + } +@@ -473,12 +473,13 @@ netsnmp_udp_getSecName(void *opaque, int olength, + + netsnmp_transport * + netsnmp_udp_create_tstring(const char *str, int local, +- const char *default_target) ++ const char *default_target, ++ char *iface) + { + struct sockaddr_in addr; + + if (netsnmp_sockaddr_in2(&addr, str, default_target)) { +- return netsnmp_udp_transport(&addr, local); ++ return netsnmp_udp_transport(&addr, local, iface); + } else { + return NULL; + } +@@ -486,7 +487,7 @@ netsnmp_udp_create_tstring(const char *str, int local, + + + netsnmp_transport * +-netsnmp_udp_create_ostring(const u_char * o, size_t o_len, int local) ++netsnmp_udp_create_ostring(const u_char * o, size_t o_len, int local, char *iface) + { + struct sockaddr_in addr; + +@@ -495,7 +496,7 @@ netsnmp_udp_create_ostring(const u_char * o, size_t o_len, int local) + addr.sin_family = AF_INET; + memcpy((u_char *) & (addr.sin_addr.s_addr), o, 4); + addr.sin_port = htons(porttmp); +- return netsnmp_udp_transport(&addr, local); ++ return netsnmp_udp_transport(&addr, local, iface); + } + return NULL; + } +diff --git a/snmplib/transports/snmpUDPIPv4BaseDomain.c b/snmplib/transports/snmpUDPIPv4BaseDomain.c +index 8c0fb05..7991b6a 100644 +--- a/snmplib/transports/snmpUDPIPv4BaseDomain.c ++++ b/snmplib/transports/snmpUDPIPv4BaseDomain.c +@@ -57,7 +57,7 @@ int netsnmp_udpipv4_sendto(int fd, struct in_addr *srcip, int if_index, + #endif /* HAVE_IP_PKTINFO || HAVE_IP_RECVDSTADDR */ + + netsnmp_transport * +-netsnmp_udpipv4base_transport(struct sockaddr_in *addr, int local) ++netsnmp_udpipv4base_transport(struct sockaddr_in *addr, int local, char *iface) + { + netsnmp_transport *t = NULL; + int rc = 0, rc2; +@@ -95,7 +95,7 @@ netsnmp_udpipv4base_transport(struct sockaddr_in *addr, int local) + return NULL; + } + +- _netsnmp_udp_sockopt_set(t->sock, local); ++ _netsnmp_udp_sockopt_set(t->sock, local, iface); + + if (local) { + #ifndef NETSNMP_NO_LISTEN_SUPPORT +diff --git a/snmplib/transports/snmpUDPIPv6Domain.c b/snmplib/transports/snmpUDPIPv6Domain.c +index 18de876..6b44b22 100644 +--- a/snmplib/transports/snmpUDPIPv6Domain.c ++++ b/snmplib/transports/snmpUDPIPv6Domain.c +@@ -74,12 +74,6 @@ oid netsnmp_UDPIPv6Domain[] = { TRANSPORT_DOMAIN_UDP_IPV6 }; + static netsnmp_tdomain udp6Domain; + + /* +- * from snmpUDPDomain. not static, but not public, either. +- * (ie don't put it in a public header.) +- */ +-extern void _netsnmp_udp_sockopt_set(int fd, int server); +- +-/* + * Return a string representing the address in data, or else the "far end" + * address if data is NULL. + */ +@@ -186,7 +186,7 @@ netsnmp_udp6_send(netsnmp_transport *t, void *buf, int size, + */ + + netsnmp_transport * +-netsnmp_udp6_transport(struct sockaddr_in6 *addr, int local) ++netsnmp_udp6_transport(struct sockaddr_in6 *addr, int local, char *iface) + { + netsnmp_transport *t = NULL; + int rc = 0; +@@ -223,7 +223,7 @@ netsnmp_udp6_transport(struct sockaddr_in6 *addr, int local) + return NULL; + } + +- _netsnmp_udp_sockopt_set(t->sock, local); ++ _netsnmp_udp_sockopt_set(t->sock, local, iface); + + if (local) { + #ifndef NETSNMP_NO_LISTEN_SUPPORT +@@ -724,12 +724,13 @@ netsnmp_udp6_getSecName(void *opaque, int olength, + + netsnmp_transport * + netsnmp_udp6_create_tstring(const char *str, int local, +- const char *default_target) ++ const char *default_target, ++ char *iface) + { + struct sockaddr_in6 addr; + + if (netsnmp_sockaddr_in6_2(&addr, str, default_target)) { +- return netsnmp_udp6_transport(&addr, local); ++ return netsnmp_udp6_transport(&addr, local, iface); + } else { + return NULL; + } +@@ -746,7 +747,7 @@ netsnmp_udp6_create_tstring(const char *str, int local, + */ + + netsnmp_transport * +-netsnmp_udp6_create_ostring(const u_char * o, size_t o_len, int local) ++netsnmp_udp6_create_ostring(const u_char * o, size_t o_len, int local, char *iface) + { + struct sockaddr_in6 addr; + +@@ -755,7 +756,7 @@ netsnmp_udp6_create_ostring(const u_char * o, size_t o_len, int local) + addr.sin6_family = AF_INET6; + memcpy((u_char *) & (addr.sin6_addr.s6_addr), o, 16); + addr.sin6_port = htons((o[16] << 8) + o[17]); +- return netsnmp_udp6_transport(&addr, local); ++ return netsnmp_udp6_transport(&addr, local, iface); + } + return NULL; + } +diff --git a/snmplib/transports/snmpUnixDomain.c b/snmplib/transports/snmpUnixDomain.c +index 47dffc1..af56c5d 100644 +--- a/snmplib/transports/snmpUnixDomain.c ++++ b/snmplib/transports/snmpUnixDomain.c +@@ -450,7 +450,8 @@ netsnmp_unix_transport(struct sockaddr_un *addr, int local) + + netsnmp_transport * + netsnmp_unix_create_tstring(const char *string, int local, +- const char *default_target) ++ const char *default_target, ++ char *iface) + { + struct sockaddr_un addr; + +@@ -476,7 +477,7 @@ netsnmp_unix_create_tstring(const char *string, int local, + + + netsnmp_transport * +-netsnmp_unix_create_ostring(const u_char * o, size_t o_len, int local) ++netsnmp_unix_create_ostring(const u_char * o, size_t o_len, int local, char *iface) + { + struct sockaddr_un addr; + +-- +2.7.4 + 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 new file mode 100644 index 000000000000..f3e878077ff5 --- /dev/null +++ b/src/snmpd/patch-5.7.3+dfsg/0008-Enable-macro-DEB_BUILD_ARCH_OS-in-order-to-build-ipv.patch @@ -0,0 +1,24 @@ +From 6e038423d7a3269dbfd85b3d7ada6015479f1559 Mon Sep 17 00:00:00 2001 +From: Qi Luo +Date: Fri, 20 Sep 2019 00:42:19 +0000 +Subject: [PATCH] Enable macro DEB_BUILD_ARCH_OS in order to build ipv6 feature + +--- + debian/rules | 1 + + 1 file changed, 1 insertion(+) + +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 + 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 04ee079ffe90..5cd0b06510f6 100644 --- a/src/snmpd/patch-5.7.3+dfsg/series +++ b/src/snmpd/patch-5.7.3+dfsg/series @@ -3,4 +3,6 @@ 0003-CHANGES-BUG-2743-snmpd-crashes-when-receiving-a-GetN.patch 0004-Disable-SNMPv1.patch 0005-Port-OpenSSL-1.1.0-with-support-for-1.0.2.patch -0006-Release-all-requests-that-use-this-session.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/sonic-config-engine/lazy_re.py b/src/sonic-config-engine/lazy_re.py new file mode 100644 index 000000000000..b51c385c1cc6 --- /dev/null +++ b/src/sonic-config-engine/lazy_re.py @@ -0,0 +1,22 @@ +# monkey patch re.compile to improve import time of some packages + +import re + +_orig_re_compile = re.compile + + +def __re_compile(*args, **kwargs): + class __LazyReCompile(object): + def __init__(self, *args, **kwargs): + self.args = args + self.kwargs = kwargs + self.pattern_obj = None + + def __getattr__(self, name): + if self.pattern_obj is None: + self.pattern_obj = _orig_re_compile(*self.args, **self.kwargs) + return getattr(self.pattern_obj, name) + return __LazyReCompile(*args, **kwargs) + +re.compile = __re_compile + diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 8461aad1fed5..3ba6362c6ff0 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -30,9 +30,19 @@ spine_chassis_frontend_role = 'SpineChassisFrontendRouter' chassis_backend_role = 'ChassisBackendRouter' +backend_device_types = ['BackEndToRRouter', 'BackEndLeafRouter'] +VLAN_SUB_INTERFACE_SEPARATOR = '.' +VLAN_SUB_INTERFACE_VLAN_ID = '10' + # Default Virtual Network Index (VNI) vni_default = 8000 +############################################################################### +# +# Minigraph parsing functions +# +############################################################################### + class minigraph_encoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, ( @@ -179,6 +189,14 @@ def parse_dpg(dpg, hname): ipprefix = lointf.find(str(QName(ns1, "PrefixStr"))).text lo_intfs[(intfname, ipprefix)] = {} + mvrfConfigs = child.find(str(QName(ns, "MgmtVrfConfigs"))) + mvrf = {} + if mvrfConfigs != None: + mv = mvrfConfigs.find(str(QName(ns1, "MgmtVrfGlobal"))) + if mv != None: + 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"))): @@ -266,15 +284,17 @@ def parse_dpg(dpg, hname): if member.lower().startswith('erspanv6'): is_mirror_v6 = True else: - is_mirror = True; - # Erspan session will be attached to all front panel ports, - # if panel ports is a member port of LAG, should add the LAG - # to acl table instead of the panel ports + is_mirror = True + # Erspan session will be attached to all front panel ports + # initially. If panel ports is a member port of LAG, then + # the LAG will be added to acl table instead of the panel + # ports. Non-active ports will be removed from this list + # 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: acl_intfs.append(panel_port) - break; + break if acl_intfs: acls[aclname] = {'policy_desc': aclname, 'ports': acl_intfs} @@ -305,8 +325,8 @@ def parse_dpg(dpg, hname): except: print >> sys.stderr, "Warning: Ignoring Control Plane ACL %s without type" % aclname - return intfs, lo_intfs, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni - return None, None, None, None, None, None, None, None, None + return intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni + return None, None, None, None, None, None, None, None, None, None def parse_cpg(cpg, hname): @@ -366,8 +386,8 @@ def parse_cpg(cpg, hname): 'name': name, 'ip_range': ip_range_group } - if bgpPeer.find(str(QName(ns1, "Address"))) is not None: - bgp_peers_with_range[name]['src_address'] = bgpPeer.find(str(QName(ns1, "Address"))).text + if bgpPeer.find(str(QName(ns, "Address"))) is not None: + bgp_peers_with_range[name]['src_address'] = bgpPeer.find(str(QName(ns, "Address"))).text if bgpPeer.find(str(QName(ns1, "PeerAsn"))) is not None: bgp_peers_with_range[name]['peer_asn'] = bgpPeer.find(str(QName(ns1, "PeerAsn"))).text else: @@ -375,8 +395,11 @@ def parse_cpg(cpg, hname): bgp_session = bgp_sessions[peer] if hostname.lower() == bgp_session['name'].lower(): bgp_session['asn'] = asn + + bgp_monitors = { key: bgp_sessions[key] for key in bgp_sessions if bgp_sessions[key].has_key('asn') and bgp_sessions[key]['name'] == 'BGPMonitor' } bgp_sessions = { key: bgp_sessions[key] for key in bgp_sessions if bgp_sessions[key].has_key('asn') and int(bgp_sessions[key]['asn']) != 0 } - return bgp_sessions, myasn, bgp_peers_with_range + + return bgp_sessions, myasn, bgp_peers_with_range, bgp_monitors def parse_meta(meta, hname): @@ -499,6 +522,39 @@ def parse_spine_chassis_fe(results, vni, lo_intfs, phyport_intfs, pc_intfs, pc_m # Enslave the port channel interface to a Vnet pc_intfs[pc_intf] = {'vnet_name': chassis_vnet} +############################################################################### +# +# Post-processing functions +# +############################################################################### + +def filter_acl_mirror_table_bindings(acls, neighbors, port_channels): + """ + Filters out inactive front-panel ports from the binding list for mirror + ACL tables. We define an "active" port as one that is a member of a + port channel or one that is connected to a neighboring device. + """ + + for acl_table, group_params in acls.iteritems(): + group_type = group_params.get('type', None) + + 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 ] + + 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 + + return acls + +############################################################################### +# +# Main functions +# +############################################################################### def parse_xml(filename, platform=None, port_config_file=None): root = ET.parse(filename).getroot() @@ -508,6 +564,7 @@ def parse_xml(filename, platform=None, port_config_file=None): u_devices = None hwsku = None bgp_sessions = None + bgp_monitors = [] bgp_asn = None intfs = None vlan_intfs = None @@ -516,7 +573,7 @@ def parse_xml(filename, platform=None, port_config_file=None): vlan_members = None pcs = None mgmt_intf = None - lo_intf = None + lo_intfs = None neighbors = None devices = None hostname = None @@ -549,9 +606,9 @@ def parse_xml(filename, platform=None, port_config_file=None): port_alias_map.update(alias_map) for child in root: if child.tag == str(QName(ns, "DpgDec")): - (intfs, lo_intfs, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, hostname) + (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) = parse_cpg(child, hostname) + (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")): @@ -570,8 +627,15 @@ def parse_xml(filename, platform=None, port_config_file=None): 'hostname': hostname, 'hwsku': hwsku, 'type': current_device['type'] - }} + }, + 'x509': { + 'server_crt': '/etc/sonic/telemetry/streamingtelemetryserver.cer', + 'server_key': '/etc/sonic/telemetry/streamingtelemetryserver.key', + 'ca_crt': '/etc/sonic/telemetry/dsmsroot.cer' + } + } results['BGP_NEIGHBOR'] = bgp_sessions + results['BGP_MONITORS'] = bgp_monitors results['BGP_PEER_RANGE'] = bgp_peers_with_range if mgmt_routes: # TODO: differentiate v4 and v6 @@ -592,12 +656,17 @@ def parse_xml(filename, platform=None, port_config_file=None): if alias in port_speeds_default: results['MGMT_PORT'][name]['speed'] = port_speeds_default[alias] results['MGMT_INTERFACE'][(name, key[1])] = mgmt_intf[key] - results['LOOPBACK_INTERFACE'] = lo_intfs + results['LOOPBACK_INTERFACE'] = {} + for lo_intf in lo_intfs: + results['LOOPBACK_INTERFACE'][lo_intf] = lo_intfs[lo_intf] + results['LOOPBACK_INTERFACE'][lo_intf[0]] = {} + results['MGMT_VRF_CONFIG'] = mvrf phyport_intfs = {} vlan_intfs = {} pc_intfs = {} vlan_invert_mapping = { v['alias']:k for k,v in vlans.items() if v.has_key('alias') } + vlan_sub_intfs = {} for intf in intfs: if intf[0][0:4] == 'Vlan': @@ -699,6 +768,32 @@ def parse_xml(filename, platform=None, port_config_file=None): results['PORTCHANNEL_INTERFACE'] = pc_intfs + if current_device['type'] in backend_device_types: + del results['INTERFACE'] + del results['PORTCHANNEL_INTERFACE'] + + for intf in phyport_intfs.keys(): + if isinstance(intf, tuple): + intf_info = list(intf) + intf_info[0] = intf_info[0] + VLAN_SUB_INTERFACE_SEPARATOR + VLAN_SUB_INTERFACE_VLAN_ID + sub_intf = tuple(intf_info) + vlan_sub_intfs[sub_intf] = {} + else: + sub_intf = intf + VLAN_SUB_INTERFACE_SEPARATOR + VLAN_SUB_INTERFACE_VLAN_ID + vlan_sub_intfs[sub_intf] = {"admin_status" : "up"} + + for pc_intf in pc_intfs.keys(): + if isinstance(pc_intf, tuple): + pc_intf_info = list(pc_intf) + pc_intf_info[0] = pc_intf_info[0] + VLAN_SUB_INTERFACE_SEPARATOR + VLAN_SUB_INTERFACE_VLAN_ID + sub_intf = tuple(pc_intf_info) + vlan_sub_intfs[sub_intf] = {} + else: + sub_intf = pc_intf + VLAN_SUB_INTERFACE_SEPARATOR + VLAN_SUB_INTERFACE_VLAN_ID + vlan_sub_intfs[sub_intf] = {"admin_status" : "up"} + + results['VLAN_SUB_INTERFACE'] = vlan_sub_intfs + results['VLAN'] = vlans results['VLAN_MEMBER'] = vlan_members @@ -714,21 +809,34 @@ def parse_xml(filename, platform=None, port_config_file=None): results['DHCP_SERVER'] = dict((item, {}) for item in dhcp_servers) results['NTP_SERVER'] = dict((item, {}) for item in ntp_servers) results['TACPLUS_SERVER'] = dict((item, {'priority': '1', 'tcp_port': '49'}) for item in tacacs_servers) - - results['ACL_TABLE'] = acls - mirror_sessions = {} - if erspan_dst: - lo_addr = '0.0.0.0' - for lo in lo_intfs: - lo_network = ipaddress.IPNetwork(lo[1]) - if lo_network.version == 4: - lo_addr = str(lo_network.ip) - break - count = 0 - for dst in erspan_dst: - mirror_sessions['everflow{}'.format(count)] = {"dst_ip": dst, "src_ip": lo_addr} - count += 1 - results['MIRROR_SESSION'] = mirror_sessions + results['ACL_TABLE'] = filter_acl_mirror_table_bindings(acls, neighbors, pcs) + results['FEATURE'] = { + 'telemetry': { + 'status': 'enabled' + } + } + results['TELEMETRY'] = { + 'gnmi': { + 'client_auth': 'true', + 'port': '50051', + 'log_level': '2' + } + } + + # Do not configure the minigraph's mirror session, which is currently unused + # mirror_sessions = {} + # if erspan_dst: + # lo_addr = '0.0.0.0' + # for lo in lo_intfs: + # lo_network = ipaddress.IPNetwork(lo[1]) + # if lo_network.version == 4: + # lo_addr = str(lo_network.ip) + # break + # count = 0 + # for dst in erspan_dst: + # mirror_sessions['everflow{}'.format(count)] = {"dst_ip": dst, "src_ip": lo_addr} + # count += 1 + # results['MIRROR_SESSION'] = mirror_sessions # Special parsing for spine chassis frontend routers if current_device['type'] == spine_chassis_frontend_role: diff --git a/src/sonic-config-engine/redis_bcc.py b/src/sonic-config-engine/redis_bcc.py new file mode 100644 index 000000000000..5ab59b6a6959 --- /dev/null +++ b/src/sonic-config-engine/redis_bcc.py @@ -0,0 +1,26 @@ +import jinja2 + +class RedisBytecodeCache(jinja2.BytecodeCache): + """ A bytecode cache for jinja2 template that stores bytecode in Redis """ + + REDIS_HASH = 'JINJA2_CACHE' + + def __init__(self, client): + self._client = client + try: + self._client.connect(self._client.STATE_DB, retry_on=False) + except Exception: + self._client = None + + def load_bytecode(self, bucket): + if self._client is None: + return + code = self._client.get(self._client.STATE_DB, self.REDIS_HASH, bucket.key) + if code is not None: + bucket.bytecode_from_string(code) + + def dump_bytecode(self, bucket): + if self._client is None: + return + self._client.set(self._client.STATE_DB, self.REDIS_HASH, bucket.key, bucket.bytecode_to_string()) + diff --git a/src/sonic-config-engine/setup.py b/src/sonic-config-engine/setup.py index 7ca810ce6a54..c75a5b5a03a6 100755 --- a/src/sonic-config-engine/setup.py +++ b/src/sonic-config-engine/setup.py @@ -16,7 +16,7 @@ def get_test_suite(): author='Taoyu Li', author_email='taoyl@microsoft.com', url='https://github.com/Azure/sonic-buildimage', - py_modules=['portconfig', 'minigraph', 'openconfig_acl', 'sonic_device_util', 'config_samples'], + py_modules=['portconfig', 'minigraph', 'openconfig_acl', 'sonic_device_util', 'config_samples', 'redis_bcc', 'lazy_re'], scripts=['sonic-cfggen'], install_requires=['lxml', 'jinja2>=2.10', 'netaddr', 'ipaddr', 'pyyaml', 'pyangbind==0.6.0'], test_suite='setup.get_test_suite', diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index b07172b17e75..7cff6c9fb384 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -16,6 +16,16 @@ See usage string for detail description for arguments. """ from __future__ import print_function + +# monkey patch re.compile to do lazy regular expression compilation. +# This is done to improve import time of jinja2, yaml, natsort modules, because they +# do many regexp compilation at import time, so it will speed up sonic-cfggen invocations +# that do not require template generation or yaml loading. sonic-cfggen is used in so many places +# during system boot up that importing jinja2, yaml, natsort every time +# without lazy regular expression compilation affect boot up time. +# FIXME: remove this once sonic-cfggen and templates dependencies are replaced with a faster approach +import lazy_re + import sys import os.path import argparse @@ -33,7 +43,8 @@ from sonic_device_util import get_platform_info from sonic_device_util import get_system_mac from config_samples import generate_sample_config from config_samples import get_available_config -from swsssdk import ConfigDBConnector +from swsssdk import SonicV2Connector, ConfigDBConnector +from redis_bcc import RedisBytecodeCache from collections import OrderedDict from natsort import natsorted @@ -103,6 +114,14 @@ def pfx_filter(value): table[key] = val return table +def ip_network(value): + """ Extract network for network prefix """ + try: + r_v = netaddr.IPNetwork(value) + except: + return "Invalid ip address %s" % value + return r_v.network + class FormatConverter: """Convert config DB based schema to legacy minigraph based schema for backward capability. We will move to DB schema and remove this class when the config templates are modified. @@ -229,7 +248,10 @@ def main(): for yaml_file in args.yaml: with open(yaml_file, 'r') as stream: - additional_data = yaml.load(stream) + if yaml.__version__ >= "5.1": + additional_data = yaml.full_load(stream) + else: + additional_data = yaml.load(stream) deep_update(data, FormatConverter.to_deserialized(additional_data)) for json_file in args.json: @@ -256,12 +278,14 @@ def main(): paths = ['/', '/usr/share/sonic/templates', os.path.dirname(template_file)] loader = jinja2.FileSystemLoader(paths) - env = jinja2.Environment(loader=loader, trim_blocks=True) + redis_bcc = RedisBytecodeCache(SonicV2Connector(host='127.0.0.1')) + env = jinja2.Environment(loader=loader, trim_blocks=True, bytecode_cache=redis_bcc) env.filters['sort_by_port_index'] = sort_by_port_index env.filters['ipv4'] = is_ipv4 env.filters['ipv6'] = is_ipv6 env.filters['unique_name'] = unique_name env.filters['pfx_filter'] = pfx_filter + env.filters['ip_network'] = ip_network for attr in ['ip', 'network', 'prefixlen', 'netmask']: env.filters[attr] = partial(prefix_attr, attr) template = env.get_template(template_file) diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index c7b2528194fc..34877600fd13 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -42,7 +42,10 @@ def get_sonic_version_info(): return None data = {} with open('/etc/sonic/sonic_version.yml') as stream: - data = yaml.load(stream) + if yaml.__version__ >= "5.1": + data = yaml.full_load(stream) + else: + data = yaml.load(stream) return data def valid_mac_address(mac): 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 b65cad324d27..566d6384fcfd 100644 --- a/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/bgpd_frr.conf @@ -4,12 +4,18 @@ ! file: bgpd.conf ! ! +! hostname switch-t0 password zebra +enable password zebra +! log syslog informational log facility local4 +!! agentx -! enable password ! +! +! +! ! ! bgp multiple-instance ! @@ -18,13 +24,24 @@ route-map FROM_BGP_SPEAKER_V4 permit 10 route-map TO_BGP_SPEAKER_V4 deny 10 ! ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 -ipv6 prefix-list PL_LoopbackV6 permit fc00:1::32/64 +ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 ! ! route-map TO_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V6 permit 100 ! +route-map FROM_BGPMON deny 10 +! +route-map TO_BGPMON permit 10 +! +! +route-map ISOLATE permit 10 + set as-path prepend 65100 +! +route-map set-next-hop-global-v6 permit 10 + set ipv6 next-hop prefer-global +! router bgp 65100 bgp log-neighbor-changes bgp bestpath as-path multipath-relax @@ -38,88 +55,35 @@ router bgp 65100 network fc00:1::32/64 exit-address-family network 192.168.0.1/27 - neighbor 10.0.0.57 remote-as 64600 - neighbor 10.0.0.57 description ARISTA01T1 - neighbor 10.0.0.57 route-map TO_BGP_PEER_V4 out - address-family ipv4 - neighbor 10.0.0.57 allowas-in 1 - neighbor 10.0.0.57 activate - neighbor 10.0.0.57 soft-reconfiguration inbound - maximum-paths 64 - exit-address-family - neighbor 10.0.0.59 remote-as 64600 - neighbor 10.0.0.59 description ARISTA02T1 - neighbor 10.0.0.59 route-map TO_BGP_PEER_V4 out address-family ipv4 - neighbor 10.0.0.59 allowas-in 1 - neighbor 10.0.0.59 activate - neighbor 10.0.0.59 soft-reconfiguration inbound maximum-paths 64 exit-address-family - neighbor 10.0.0.61 remote-as 64600 - neighbor 10.0.0.61 description ARISTA03T1 - neighbor 10.0.0.61 route-map TO_BGP_PEER_V4 out - address-family ipv4 - neighbor 10.0.0.61 allowas-in 1 - neighbor 10.0.0.61 activate - neighbor 10.0.0.61 soft-reconfiguration inbound - maximum-paths 64 - exit-address-family - neighbor 10.0.0.63 remote-as 64600 - neighbor 10.0.0.63 description ARISTA04T1 - neighbor 10.0.0.63 route-map TO_BGP_PEER_V4 out - address-family ipv4 - neighbor 10.0.0.63 allowas-in 1 - neighbor 10.0.0.63 activate - neighbor 10.0.0.63 soft-reconfiguration inbound - maximum-paths 64 - exit-address-family - neighbor fc00::7a remote-as 64600 - neighbor fc00::7a description ARISTA03T1 address-family ipv6 - neighbor fc00::7a allowas-in 1 - neighbor fc00::7a activate - neighbor fc00::7a soft-reconfiguration inbound - neighbor fc00::7a route-map set-next-hop-global-v6 in - neighbor fc00::7a route-map TO_BGP_PEER_V6 out maximum-paths 64 exit-address-family - neighbor fc00::7e remote-as 64600 - neighbor fc00::7e description ARISTA04T1 - address-family ipv6 - neighbor fc00::7e allowas-in 1 - neighbor fc00::7e activate - neighbor fc00::7e soft-reconfiguration inbound - neighbor fc00::7e route-map set-next-hop-global-v6 in - neighbor fc00::7e route-map TO_BGP_PEER_V6 out - maximum-paths 64 + 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 - neighbor fc00::72 remote-as 64600 - neighbor fc00::72 description ARISTA01T1 address-family ipv6 - neighbor fc00::72 allowas-in 1 - neighbor fc00::72 activate - neighbor fc00::72 soft-reconfiguration inbound - neighbor fc00::72 route-map set-next-hop-global-v6 in - neighbor fc00::72 route-map TO_BGP_PEER_V6 out - maximum-paths 64 + 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 fc00::76 remote-as 64600 - neighbor fc00::76 description ARISTA02T1 + 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 fc00::76 allowas-in 1 - neighbor fc00::76 activate - neighbor fc00::76 soft-reconfiguration inbound - neighbor fc00::76 route-map set-next-hop-global-v6 in - neighbor fc00::76 route-map TO_BGP_PEER_V6 out - maximum-paths 64 + neighbor 10.20.30.40 activate exit-address-family !! -maximum-paths 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 -! diff --git a/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json b/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json index 0b6c8cbe19a3..5cf0472f3f11 100644 --- a/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json +++ b/src/sonic-config-engine/tests/sample_output/buffers-dell6100.json @@ -96,7 +96,7 @@ "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"1518", - "static_th":"3995680" + "static_th":"15982720" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", @@ -105,19 +105,535 @@ } }, "BUFFER_PG": { - "Ethernet0,Ethernet1,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet48,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58|0": { + "Ethernet0|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet1|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet4|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet5|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet6|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet7|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet8|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet9|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet10|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet11|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet12|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet13|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet14|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet15|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet16|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet17|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet20|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet21|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet22|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet23|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet24|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet25|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet26|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet27|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet28|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet29|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet30|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet31|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet32|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet36|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet37|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet38|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet39|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet40|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet41|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet42|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet48|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet52|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet53|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet54|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet55|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet56|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet57|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "Ethernet58|0": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" } }, "BUFFER_QUEUE": { - "Ethernet0,Ethernet1,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet48,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58|3-4": { + "Ethernet0|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet1|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet4|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet5|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet6|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet7|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet8|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet9|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet10|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet11|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet12|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet13|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet14|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet15|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet16|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet17|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet20|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet21|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet22|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet23|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet24|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet25|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet26|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet27|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet28|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet29|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet30|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet31|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet32|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet36|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet37|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet38|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet39|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet40|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet41|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet42|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet48|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet52|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet53|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet54|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet55|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet56|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet57|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "Ethernet58|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "Ethernet0,Ethernet1,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet48,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58|0-2": { + "Ethernet0|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet1|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet4|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet5|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet6|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet7|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet8|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet9|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet10|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet11|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet12|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet13|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet14|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet15|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet16|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet17|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet20|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet21|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet22|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet23|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet24|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet25|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet26|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet27|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet28|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet29|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet30|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet31|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet32|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet36|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet37|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet38|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet39|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet40|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet41|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet42|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet48|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet52|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet53|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet54|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet55|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet56|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet57|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet58|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet0|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet1|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet4|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet5|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet6|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet7|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet8|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet9|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet10|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet11|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet12|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet13|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet14|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet15|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet16|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet17|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet20|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet21|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet22|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet23|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet24|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet25|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet26|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet27|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet28|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet29|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet30|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet31|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet32|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet36|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet37|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet38|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet39|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet40|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet41|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet42|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet48|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet52|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet53|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet54|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet55|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet56|5-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "Ethernet57|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "Ethernet0,Ethernet1,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet48,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58|5-6": { + "Ethernet58|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" } } diff --git a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf index d285fbfc788c..bae273eeaf81 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,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 diff --git a/src/sonic-config-engine/tests/sample_output/frr.conf b/src/sonic-config-engine/tests/sample_output/frr.conf index 8e7f97cf8c55..47855ce7c841 100644 --- a/src/sonic-config-engine/tests/sample_output/frr.conf +++ b/src/sonic-config-engine/tests/sample_output/frr.conf @@ -4,12 +4,18 @@ ! file: frr.conf ! ! +! hostname switch-t0 password zebra +enable password zebra +! log syslog informational log facility local4 +!! agentx -! enable password ! +! +! +! ! Enable link-detect (default disabled) interface PortChannel01 link-detect @@ -24,9 +30,6 @@ interface PortChannel04 link-detect ! ! -! set static default route to mgmt gateway as a backup to learned default -ip route 0.0.0.0/0 10.0.0.1 200 -! ! Set ip source to loopback for bgp learned routes route-map RM_SET_SRC permit 10 set src 10.1.0.32 @@ -39,6 +42,11 @@ ip protocol bgp route-map RM_SET_SRC ! ipv6 protocol bgp route-map RM_SET_SRC6 ! +!! +! +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.0.0.1 200 +!! ! ! ! bgp multiple-instance @@ -47,91 +55,67 @@ route-map FROM_BGP_SPEAKER_V4 permit 10 ! route-map TO_BGP_SPEAKER_V4 deny 10 ! +ip prefix-list PL_LoopbackV4 permit 10.1.0.32/32 +ipv6 prefix-list PL_LoopbackV6 permit fc00:1::/64 +! +! +route-map TO_BGP_PEER_V4 permit 100 +! +route-map TO_BGP_PEER_V6 permit 100 +! +route-map FROM_BGPMON deny 10 +! +route-map TO_BGPMON permit 10 +! +! +route-map ISOLATE permit 10 + set as-path prepend 65100 +! +route-map set-next-hop-global-v6 permit 10 + set ipv6 next-hop prefer-global +! router bgp 65100 bgp log-neighbor-changes bgp bestpath as-path multipath-relax no bgp default ipv4-unicast + bgp graceful-restart restart-time 240 bgp graceful-restart + bgp graceful-restart preserve-fw-state bgp router-id 10.1.0.32 network 10.1.0.32/32 address-family ipv6 network fc00:1::32/64 exit-address-family network 192.168.0.1/27 - neighbor 10.0.0.57 remote-as 64600 - neighbor 10.0.0.57 description ARISTA01T1 - address-family ipv4 - neighbor 10.0.0.57 allowas-in 1 - neighbor 10.0.0.57 activate - neighbor 10.0.0.57 soft-reconfiguration inbound - maximum-paths 64 - exit-address-family - neighbor 10.0.0.59 remote-as 64600 - neighbor 10.0.0.59 description ARISTA02T1 address-family ipv4 - neighbor 10.0.0.59 allowas-in 1 - neighbor 10.0.0.59 activate - neighbor 10.0.0.59 soft-reconfiguration inbound maximum-paths 64 exit-address-family - neighbor 10.0.0.61 remote-as 64600 - neighbor 10.0.0.61 description ARISTA03T1 - address-family ipv4 - neighbor 10.0.0.61 allowas-in 1 - neighbor 10.0.0.61 activate - neighbor 10.0.0.61 soft-reconfiguration inbound - maximum-paths 64 - exit-address-family - neighbor 10.0.0.63 remote-as 64600 - neighbor 10.0.0.63 description ARISTA04T1 - address-family ipv4 - neighbor 10.0.0.63 allowas-in 1 - neighbor 10.0.0.63 activate - neighbor 10.0.0.63 soft-reconfiguration inbound - maximum-paths 64 - exit-address-family - neighbor fc00::7a remote-as 64600 - neighbor fc00::7a description ARISTA03T1 address-family ipv6 - neighbor fc00::7a allowas-in 1 - neighbor fc00::7a activate - neighbor fc00::7a soft-reconfiguration inbound - neighbor fc00::7a route-map set-next-hop-global-v6 in maximum-paths 64 exit-address-family - neighbor fc00::7e remote-as 64600 - neighbor fc00::7e description ARISTA04T1 - address-family ipv6 - neighbor fc00::7e allowas-in 1 - neighbor fc00::7e activate - neighbor fc00::7e soft-reconfiguration inbound - neighbor fc00::7e route-map set-next-hop-global-v6 in - maximum-paths 64 + 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 - neighbor fc00::72 remote-as 64600 - neighbor fc00::72 description ARISTA01T1 address-family ipv6 - neighbor fc00::72 allowas-in 1 - neighbor fc00::72 activate - neighbor fc00::72 soft-reconfiguration inbound - neighbor fc00::72 route-map set-next-hop-global-v6 in - maximum-paths 64 + 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 fc00::76 remote-as 64600 - neighbor fc00::76 description ARISTA02T1 + 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 fc00::76 allowas-in 1 - neighbor fc00::76 activate - neighbor fc00::76 soft-reconfiguration inbound - neighbor fc00::76 route-map set-next-hop-global-v6 in - maximum-paths 64 + neighbor 10.20.30.40 activate exit-address-family -! -maximum-paths 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 -! +!! diff --git a/src/sonic-config-engine/tests/sample_output/interfaces b/src/sonic-config-engine/tests/sample_output/interfaces index 2c4c01b7b9b1..d3921bcbab4d 100644 --- a/src/sonic-config-engine/tests/sample_output/interfaces +++ b/src/sonic-config-engine/tests/sample_output/interfaces @@ -6,19 +6,6 @@ # The loopback network interface auto lo iface lo inet loopback -# Use command 'ip addr list dev lo' to check all addresses -iface lo inet static - address 10.1.0.32 - netmask 255.255.255.255 -# -iface lo inet6 static - address fc00:1::32 - netmask 128 -# -iface lo inet static - address 10.10.0.99 - netmask 255.255.255.255 -# # The management network interface auto eth0 diff --git a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces new file mode 100644 index 000000000000..afd0615b81e9 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces @@ -0,0 +1,56 @@ +# +# =============== Managed by SONiC Config Engine DO NOT EDIT! =============== +# generated from /usr/share/sonic/templates/interfaces.j2 using sonic-cfggen +# file: /etc/network/interfaces +# +auto mgmt +iface mgmt + vrf-table 5000 +# The loopback network interface +auto lo +iface lo inet loopback +# The loopback network interface for mgmt VRF that is required for applications like NTP + up ip link add lo-m type dummy + up ip addr add 127.0.0.1/8 dev lo-m + up ip link set lo-m up + up ip link set dev lo-m master mgmt + down ip link delete dev lo-m + +# The management network interface +auto eth0 +iface eth0 inet static + address 10.0.0.100 + netmask 255.255.255.0 + vrf mgmt + ########## management network policy routing rules + # management port up rules + up ip -4 route add default via 10.0.0.1 dev eth0 table 5000 metric 201 + up ip -4 route add 10.0.0.0/24 dev eth0 table 5000 + up ip -4 rule add from 10.0.0.100/32 table 5000 + up cgcreate -g l3mdev:mgmt + up cgset -r l3mdev.master-device=mgmt mgmt + # management port down rules + down ip -4 route delete default via 10.0.0.1 dev eth0 table 5000 + down ip -4 route delete 10.0.0.0/24 dev eth0 table 5000 + down ip -4 rule delete from 10.0.0.100/32 table 5000 + down cgdelete -g l3mdev:mgmt +iface eth0 inet6 static + address 2603:10e2:0:2902::8 + netmask 64 + vrf mgmt + ########## management network policy routing rules + # management port up rules + up ip -6 route add default via 2603:10e2:0:2902::1 dev eth0 table 5000 metric 201 + up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table 5000 + up ip -6 rule add from 2603:10e2:0:2902::8/128 table 5000 + up cgcreate -g l3mdev:mgmt + up cgset -r l3mdev.master-device=mgmt mgmt + # management port down rules + down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table 5000 + down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table 5000 + down ip -6 rule delete from 2603:10e2:0:2902::8/128 table 5000 + down cgdelete -g l3mdev:mgmt +# +source /etc/network/interfaces.d/* +# + 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 0387e10dc2f2..680ca6232e11 100644 --- a/src/sonic-config-engine/tests/sample_output/qos-dell6100.json +++ b/src/sonic-config-engine/tests/sample_output/qos-dell6100.json @@ -114,7 +114,308 @@ } }, "PORT_QOS_MAP": { - "Ethernet0,Ethernet1,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet48,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58": { + "Ethernet0": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet1": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet4": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet5": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet6": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet7": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet8": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet9": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet10": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet11": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet12": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet13": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet14": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet15": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet16": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet17": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet20": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet21": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet22": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet23": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet24": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet25": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet26": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet27": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet28": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet29": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet30": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet31": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet32": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet36": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet37": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet38": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet39": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet40": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet41": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet42": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet48": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet52": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet53": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet54": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet55": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet56": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet57": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable" : "3,4" + }, + "Ethernet58": { "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", diff --git a/src/sonic-config-engine/tests/sample_output/staticd_frr.conf b/src/sonic-config-engine/tests/sample_output/staticd_frr.conf new file mode 100644 index 000000000000..12a81de82125 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/staticd_frr.conf @@ -0,0 +1,18 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/frr/staticd.conf.j2 using config DB data +! file: staticd.conf +! +! +! +hostname switch-t0 +password zebra +enable password zebra +! +log syslog informational +log facility local4 +!! +! +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.0.0.1 200 +!! diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-bgpd.conf b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-bgpd.conf index 515e0aba8df2..b0b5e2cb1192 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 @@ -4,12 +4,17 @@ ! file: bgpd.conf ! ! +! hostname SpineFront01 password zebra +enable password zebra +! log syslog informational log facility local4 +!! agentx -! enable password ! +! +! ! Vnet BGP instance router bgp 4000 vrf VnetFE no bgp default ipv4-unicast @@ -30,7 +35,8 @@ router bgp 4000 vrf VnetFE address-family l2vpn evpn advertise ipv4 unicast exit-address-family - +!! +! ! ! bgp multiple-instance ! @@ -38,6 +44,20 @@ route-map FROM_BGP_SPEAKER_V4 permit 10 ! route-map TO_BGP_SPEAKER_V4 deny 10 ! +ip prefix-list PL_LoopbackV4 permit 4.0.0.0/32 +! +! +route-map TO_BGP_PEER_V4 permit 100 +! +route-map TO_BGP_PEER_V6 permit 100 +! +! +route-map ISOLATE permit 10 + set as-path prepend 4000 +! +route-map set-next-hop-global-v6 permit 10 + set ipv6 next-hop prefer-global +! router bgp 4000 bgp log-neighbor-changes bgp bestpath as-path multipath-relax @@ -46,37 +66,20 @@ router bgp 4000 bgp graceful-restart bgp router-id 4.0.0.0 network 4.0.0.0/32 - neighbor 4.0.0.1 remote-as 4000 - neighbor 4.0.0.1 description SpineFront02 - neighbor 4.0.0.1 timers 3 10 - address-family l2vpn evpn - neighbor 4.0.0.1 activate - advertise-all-vni - exit-address-family - neighbor 172.16.0.2 remote-as 5000 - neighbor 172.16.0.2 description SpineBack01 - neighbor 172.16.0.2 timers 3 10 - address-family ipv4 unicast - neighbor 172.16.0.2 allowas-in 1 - neighbor 172.16.0.2 activate - neighbor 172.16.0.2 soft-reconfiguration inbound + address-family ipv4 maximum-paths 64 exit-address-family - neighbor 172.16.0.10 remote-as 5000 - neighbor 172.16.0.10 description SpineBack02 - neighbor 172.16.0.10 timers 3 10 - address-family ipv4 unicast - neighbor 172.16.0.10 allowas-in 1 - neighbor 172.16.0.10 activate - neighbor 172.16.0.10 soft-reconfiguration inbound + address-family ipv6 maximum-paths 64 exit-address-family -! -maximum-paths 64 -! -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 -! + neighbor PEER_V4 peer-group + neighbor PEER_V6 peer-group + address-family ipv4 + neighbor PEER_V4 soft-reconfiguration inbound + neighbor PEER_V4 route-map TO_BGP_PEER_V4 out + exit-address-family + address-family ipv6 + neighbor PEER_V6 soft-reconfiguration inbound + neighbor PEER_V6 route-map TO_BGP_PEER_V6 out + exit-address-family +!! diff --git a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-pc-zebra.conf b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-pc-zebra.conf index 8861e6d3012f..312394bf76c9 100644 --- a/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-pc-zebra.conf +++ b/src/sonic-config-engine/tests/sample_output/t2-chassis-fe-pc-zebra.conf @@ -23,8 +23,6 @@ interface PortChannel8 link-detect ! ! -! set static default route to mgmt gateway as a backup to learned default -! ! Set ip source to loopback for bgp learned routes route-map RM_SET_SRC permit 10 set src 4.0.0.0 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 1f9dce8812bd..bd2b5c84f471 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 @@ -4,10 +4,15 @@ ! file: zebra.conf ! ! +! hostname SpineFront01 password zebra enable password zebra ! +log syslog informational +log facility local4 +!! +! vrf VnetFE vni 9000 ! @@ -23,16 +28,10 @@ interface Ethernet8 link-detect ! ! -! set static default route to mgmt gateway as a backup to learned default -! ! 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 ! -! -log syslog informational -log facility local4 -! - +!! 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 b89aeb4a382f..e047fcd64f29 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 @@ -4,10 +4,15 @@ ! file: zebra.conf ! ! +! hostname SpineFront01 password zebra enable password zebra ! +log syslog informational +log facility local4 +!! +! vrf VnetFE vni 8000 ! @@ -23,16 +28,10 @@ interface Ethernet8 link-detect ! ! -! set static default route to mgmt gateway as a backup to learned default -! ! 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 ! -! -log syslog informational -log facility local4 -! - +!! diff --git a/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh b/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh index 5f50106ff556..918f0b6e1648 100644 --- a/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh +++ b/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh @@ -2,21 +2,17 @@ STATE_DB_IDX="6" -PORT_TABLE_PREFIX="PORT_TABLE" -VLAN_TABLE_PREFIX="VLAN_TABLE" -LAG_TABLE_PREFIX="LAG_TABLE" - function wait_until_iface_ready { - TABLE_PREFIX=$1 - IFACE=$2 + IFACE_NAME=$1 + IFACE_CIDR=$2 - echo "Waiting until interface $IFACE is ready..." + echo "Waiting until interface ${IFACE_NAME} is ready..." # Wait for the interface to come up # (i.e., interface is present in STATE_DB and state is "ok") while true; do - RESULT=$(redis-cli -n ${STATE_DB_IDX} HGET "${TABLE_PREFIX}|${IFACE}" "state" 2> /dev/null) + RESULT=$(redis-cli -n ${STATE_DB_IDX} HGET "INTERFACE_TABLE|${IFACE_NAME}|${IFACE_CIDR}" "state" 2> /dev/null) if [ x"$RESULT" == x"ok" ]; then break fi @@ -24,14 +20,14 @@ function wait_until_iface_ready sleep 1 done - echo "Interface ${IFACE} is ready!" + echo "Interface ${IFACE_NAME} is ready!" } -# Wait for all interfaces to be up and ready -wait_until_iface_ready ${VLAN_TABLE_PREFIX} Vlan1000 -wait_until_iface_ready ${LAG_TABLE_PREFIX} PortChannel01 -wait_until_iface_ready ${LAG_TABLE_PREFIX} PortChannel02 -wait_until_iface_ready ${LAG_TABLE_PREFIX} PortChannel03 -wait_until_iface_ready ${LAG_TABLE_PREFIX} PortChannel04 +# Wait for all interfaces with IPv4 addresses to be up and ready +wait_until_iface_ready Vlan1000 192.168.0.1/27 +wait_until_iface_ready PortChannel01 10.0.0.56/31 +wait_until_iface_ready PortChannel02 10.0.0.58/31 +wait_until_iface_ready PortChannel03 10.0.0.60/31 +wait_until_iface_ready PortChannel04 10.0.0.62/31 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 aa3486b0163a..690f609dafcf 100644 --- a/src/sonic-config-engine/tests/sample_output/zebra_frr.conf +++ b/src/sonic-config-engine/tests/sample_output/zebra_frr.conf @@ -4,10 +4,16 @@ ! file: zebra.conf ! ! +! hostname switch-t0 password zebra enable password zebra ! +log syslog informational +log facility local4 +!! +! +! ! Enable link-detect (default disabled) interface PortChannel01 link-detect @@ -22,9 +28,6 @@ interface PortChannel04 link-detect ! ! -! set static default route to mgmt gateway as a backup to learned default -ip route 0.0.0.0/0 10.0.0.1 200 -! ! Set ip source to loopback for bgp learned routes route-map RM_SET_SRC permit 10 set src 10.1.0.32 @@ -37,8 +40,4 @@ ip protocol bgp route-map RM_SET_SRC ! ipv6 protocol bgp route-map RM_SET_SRC6 ! -! -log syslog informational -log facility local4 -! - +!! diff --git a/src/sonic-config-engine/tests/simple-sample-graph.xml b/src/sonic-config-engine/tests/simple-sample-graph.xml index e04f692729f0..5ebbaafd9671 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph.xml @@ -2,6 +2,15 @@ + + switch-t0 + 10.1.0.32 + BGPMonitor + 10.20.30.40 + 30 + 10 + 3 + false switch-t0 @@ -42,6 +51,21 @@ + + 0 + + BGPMonitor + + + BGPPeer +
10.1.0.32
+ + + +
+
+ +
65100 switch-t0 diff --git a/src/sonic-config-engine/tests/t0-sample-graph-mvrf.xml b/src/sonic-config-engine/tests/t0-sample-graph-mvrf.xml new file mode 100644 index 000000000000..5162086d9316 --- /dev/null +++ b/src/sonic-config-engine/tests/t0-sample-graph-mvrf.xml @@ -0,0 +1,408 @@ + + + + + + false + switch-t0 + 10.0.0.56 + ARISTA01T1 + 10.0.0.57 + 1 + 180 + 60 + + + switch-t0 + FC00::71 + ARISTA01T1 + FC00::72 + 1 + 180 + 60 + + + false + switch-t0 + 10.0.0.58 + ARISTA02T1 + 10.0.0.59 + 1 + 180 + 60 + + + switch-t0 + FC00::75 + ARISTA02T1 + FC00::76 + 1 + 180 + 60 + + + false + switch-t0 + 10.0.0.60 + ARISTA03T1 + 10.0.0.61 + 1 + 180 + 60 + + + switch-t0 + FC00::79 + ARISTA03T1 + FC00::7A + 1 + 180 + 60 + + + false + switch-t0 + 10.0.0.62 + ARISTA04T1 + 10.0.0.63 + 1 + 180 + 60 + + + switch-t0 + FC00::7D + ARISTA04T1 + FC00::7E + 1 + 180 + 60 + + + + + 65100 + switch-t0 + + +
10.0.0.57
+ + + +
+ +
10.0.0.59
+ + + +
+ +
10.0.0.61
+ + + +
+ +
10.0.0.63
+ + + +
+
+ +
+ + 64600 + ARISTA01T1 + + + + 64600 + ARISTA02T1 + + + + 64600 + ARISTA03T1 + + + + 64600 + ARISTA04T1 + + +
+
+ + + + + + HostIP + Loopback0 + + 10.1.0.32/32 + + 10.1.0.32/32 + + + HostIP1 + Loopback0 + + FC00:1::32/128 + + FC00:1::32/128 + + + LoopbackIP1 + Loopback1 + + 10.10.0.99/32 + + 10.10.0.99/32 + + + + + true + + + + + HostIP + eth0 + + 10.0.0.100/24 + + 10.0.0.100/24 + + + HostIP + eth0 + + 2603:10e2:0:2902::8/64 + + 2603:10e2:0:2902::8/64 + + + + + + + switch-t0 + + + PortChannel01 + fortyGigE0/112 + + + + PortChannel02 + fortyGigE0/116 + + + + PortChannel03 + fortyGigE0/120 + + + + PortChannel04 + fortyGigE0/124 + + + + + + Vlan1000 + fortyGigE0/4;fortyGigE0/8;fortyGigE0/12;fortyGigE0/16;fortyGigE0/20;fortyGigE0/24;fortyGigE0/28;fortyGigE0/32;fortyGigE0/36;fortyGigE0/40;fortyGigE0/44;fortyGigE0/48;fortyGigE0/52;fortyGigE0/56;fortyGigE0/60;fortyGigE0/64;fortyGigE0/68;fortyGigE0/72;fortyGigE0/76;fortyGigE0/80;fortyGigE0/84;fortyGigE0/88;fortyGigE0/92;fortyGigE0/96 + False + 0.0.0.0/0 + + 192.0.0.1;192.0.0.2 + 1000 + 1000 + 192.168.0.0/27 + + + + + + PortChannel01 + 10.0.0.56/31 + + + + PortChannel01 + FC00::71/126 + + + + PortChannel02 + 10.0.0.58/31 + + + + PortChannel02 + FC00::75/126 + + + + PortChannel03 + 10.0.0.60/31 + + + + PortChannel03 + FC00::79/126 + + + + PortChannel04 + 10.0.0.62/31 + + + + PortChannel04 + FC00::7D/126 + + + + Vlan1000 + 192.168.0.1/27 + + + + + + ERSPAN + everflow + Everflow + + + ERSPANv6 + everflowV6 + Everflow + + + PortChannel01;PortChannel02;PortChannel03;PortChannel04 + DataAcl + DataPlane + + + SNMP + SNMP_ACL + SNMP + + + NTP + NTP_ACL + NTP + + + SSH + SSH_ACL + SSH + + + SSH + ROUTER-PROTECT + SSH + + + SNMP + ROUTER-PROTECT + SNMP + + + NTP + NTP_ACL + + + + + + + + + + DeviceInterfaceLink + ARISTA01T1 + Ethernet1/1 + switch-t0 + fortyGigE0/112 + + + DeviceInterfaceLink + ARISTA02T1 + Ethernet1/1 + switch-t0 + fortyGigE0/116 + + + DeviceInterfaceLink + ARISTA03T1 + Ethernet1/1 + switch-t0 + fortyGigE0/120 + + + DeviceInterfaceLink + ARISTA04T1 + Ethernet1/1 + switch-t0 + fortyGigE0/124 + + + DeviceInterfaceLink + true + 10000 + switch-t0 + fortyGigE0/2 + true + ARISTA05T1 + Ethernet1/33 + true + + + + + switch-t0 + Force10-S6000 + + + ARISTA01T1 + Arista + + + ARISTA02T1 + Arista + + + ARISTA03T1 + Arista + + + ARISTA04T1 + Arista + + + + + + + switch-t0 + + + ErspanDestinationIpv4 + + 2.2.2.2 + + + + + + + switch-t0 + Force10-S6000 +
diff --git a/src/sonic-config-engine/tests/t0-sample-graph.xml b/src/sonic-config-engine/tests/t0-sample-graph.xml index bb1a4a4a22f6..0c641107da06 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph.xml @@ -2,6 +2,15 @@ + + switch-t0 + 10.1.0.32 + BGPMonitor + 10.20.30.40 + 30 + 10 + 3 + false switch-t0 @@ -80,6 +89,21 @@ + + 0 + + BGPMonitor + + + BGPPeer +
10.1.0.32
+ + + +
+
+ +
65100 switch-t0 @@ -359,6 +383,13 @@ Ethernet1/33 true + + DeviceInterfaceLink + Servers0 + eth0 + switch-t0 + fortyGigE0/4 + diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index a28e1263c475..8288b729584c 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -2,6 +2,9 @@ import subprocess import os +TOR_ROUTER = 'ToRRouter' +BACKEND_TOR_ROUTER = 'BackEndToRRouter' + class TestCfgGen(TestCase): def setUp(self): @@ -55,10 +58,12 @@ def test_print_data(self): output = self.run_script(argument) self.assertTrue(len(output.strip()) > 0) - def test_jinja_expression(self): - argument = '-m "' + self.sample_graph + '" -v "DEVICE_METADATA[\'localhost\'][\'type\']"' + def test_jinja_expression(self, graph=None, expected_router_type='LeafRouter'): + if graph is None: + graph = self.sample_graph + argument = '-m "' + graph + '" -v "DEVICE_METADATA[\'localhost\'][\'type\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), 'LeafRouter') + self.assertEqual(output.strip(), expected_router_type) def test_additional_json_data(self): argument = '-a \'{"key1":"value1"}\' -v key1' @@ -90,6 +95,9 @@ def test_render_template(self): output = self.run_script(argument) self.assertEqual(output.strip(), 'value1\nvalue2') + # FIXME: This test depends heavily on the ordering of the interfaces and + # it is not at all intuitive what that ordering should be. Could make it + # more robust by adding better parsing logic. def test_minigraph_acl(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v ACL_TABLE' output = self.run_script(argument, True) @@ -98,16 +106,17 @@ def test_minigraph_acl(self): "Warning: ignore interface 'fortyGigE0/2' in DEVICE_NEIGHBOR as it is not in the port_config.ini\n" "{'DATAACL': {'type': 'L3', 'policy_desc': 'DATAACL', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04']}, " "'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL'}, " - "'EVERFLOW': {'type': 'MIRROR', 'policy_desc': 'EVERFLOW', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet24', 'Ethernet40', 'Ethernet20', 'Ethernet44', 'Ethernet48', 'Ethernet28', 'Ethernet96', 'Ethernet92', 'Ethernet76', 'Ethernet72', 'Ethernet52', 'Ethernet80', 'Ethernet56', 'Ethernet32', 'Ethernet16', 'Ethernet36', 'Ethernet12', 'Ethernet60', 'Ethernet8', 'Ethernet4', 'Ethernet0', 'Ethernet64', 'Ethernet68', 'Ethernet84', 'Ethernet88', 'Ethernet108', 'Ethernet104', 'Ethernet100']}, " + "'EVERFLOW': {'type': 'MIRROR', 'policy_desc': 'EVERFLOW', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4']}, " "'ROUTER_PROTECT': {'services': ['SSH', 'SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'ROUTER_PROTECT'}, " "'SNMP_ACL': {'services': ['SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL'}, " "'SSH_ACL': {'services': ['SSH'], 'type': 'CTRLPLANE', 'policy_desc': 'SSH_ACL'}, " - "'EVERFLOWV6': {'type': 'MIRRORV6', 'policy_desc': 'EVERFLOWV6', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet24', 'Ethernet40', 'Ethernet20', 'Ethernet44', 'Ethernet48', 'Ethernet28', 'Ethernet96', 'Ethernet92', 'Ethernet76', 'Ethernet72', 'Ethernet52', 'Ethernet80', 'Ethernet56', 'Ethernet32', 'Ethernet16', 'Ethernet36', 'Ethernet12', 'Ethernet60', 'Ethernet8', 'Ethernet4', 'Ethernet0', 'Ethernet64', 'Ethernet68', 'Ethernet84', 'Ethernet88', 'Ethernet108', 'Ethernet104', 'Ethernet100']}}") + "'EVERFLOWV6': {'type': 'MIRRORV6', 'policy_desc': 'EVERFLOWV6', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4']}}") - def test_minigraph_everflow(self): - argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v MIRROR_SESSION' - output = self.run_script(argument) - self.assertEqual(output.strip(), "{'everflow0': {'src_ip': '10.1.0.32', 'dst_ip': '2.2.2.2'}}") +# everflow portion is not used +# def test_minigraph_everflow(self): +# argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v MIRROR_SESSION' +# output = self.run_script(argument) +# self.assertEqual(output.strip(), "{'everflow0': {'src_ip': '10.1.0.32', 'dst_ip': '2.2.2.2'}}") def test_minigraph_mgmt_ports(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v MGMT_PORT' @@ -159,6 +168,9 @@ def test_minigraph_neighbors(self): output = self.run_script(argument) self.assertEqual(output.strip(), "{'name': 'ARISTA04T1', 'port': 'Ethernet1/1'}") + # FIXME: This test depends heavily on the ordering of the interfaces and + # it is not at all intuitive what that ordering should be. Could make it + # more robust by adding better parsing logic. def test_minigraph_extra_neighbors(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v DEVICE_NEIGHBOR' output = self.run_script(argument) @@ -166,6 +178,7 @@ def test_minigraph_extra_neighbors(self): "{'Ethernet116': {'name': 'ARISTA02T1', 'port': 'Ethernet1/1'}, " "'Ethernet124': {'name': 'ARISTA04T1', 'port': 'Ethernet1/1'}, " "'Ethernet112': {'name': 'ARISTA01T1', 'port': 'Ethernet1/1'}, " + "'Ethernet4': {'name': 'Servers0', 'port': 'eth0'}, " "'Ethernet120': {'name': 'ARISTA03T1', 'port': 'Ethernet1/1'}}") def test_minigraph_port_description(self): @@ -181,7 +194,7 @@ def test_minigraph_bgp(self): def test_minigraph_peers_with_range(self): argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v BGP_PEER_RANGE.values\(\)' output = self.run_script(argument) - self.assertEqual(output.strip(), "[{'name': 'BGPSLBPassive', 'ip_range': ['10.10.10.10/26', '100.100.100.100/26']}]") + self.assertEqual(output.strip(), "[{'src_address': '10.1.0.32', 'name': 'BGPSLBPassive', 'ip_range': ['10.10.10.10/26', '100.100.100.100/26']}]") def test_minigraph_deployment_id(self): argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v "DEVICE_METADATA[\'localhost\'][\'deployment_id\']"' @@ -234,10 +247,11 @@ def test_minigraph_extra_ethernet_interfaces(self): "'Ethernet20': {'alias': 'fortyGigE0/20', 'pfc_asym': 'off', 'lanes': '45,46,47,48', 'description': 'fortyGigE0/20', 'mtu': '9100'}, " "'Ethernet24': {'alias': 'fortyGigE0/24', 'pfc_asym': 'off', 'lanes': '5,6,7,8', 'description': 'fortyGigE0/24', 'mtu': '9100'}}") - def test_metadata_everflow(self): - argument = '-m "' + self.sample_graph_metadata + '" -p "' + self.port_config + '" -v "MIRROR_SESSION"' - output = self.run_script(argument) - self.assertEqual(output.strip(), "{'everflow0': {'src_ip': '10.1.0.32', 'dst_ip': '10.0.100.1'}}") +# everflow portion is not used +# def test_metadata_everflow(self): +# argument = '-m "' + self.sample_graph_metadata + '" -p "' + self.port_config + '" -v "MIRROR_SESSION"' +# output = self.run_script(argument) +# self.assertEqual(output.strip(), "{'everflow0': {'src_ip': '10.1.0.32', 'dst_ip': '10.0.100.1'}}") def test_metadata_tacacs(self): argument = '-m "' + self.sample_graph_metadata + '" -p "' + self.port_config + '" -v "TACPLUS_SERVER"' @@ -258,3 +272,61 @@ def test_minigraph_vxlan(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "VXLAN_TUNNEL"' output = self.run_script(argument) self.assertEqual(output.strip(), "") + + def test_minigraph_bgp_mon(self): + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "BGP_MONITORS"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "{'10.20.30.40': {'rrclient': 0, 'name': 'BGPMonitor', 'local_addr': '10.1.0.32', 'nhopself': 0, 'holdtime': '10', 'asn': '0', 'keepalive': '3'}}") + + def test_minigraph_sub_port_interfaces(self, check_stderr=True): + try: + print '\n Change device type to %s' % (BACKEND_TOR_ROUTER) + if check_stderr: + output = subprocess.check_output("sed -i \'s/%s/%s/g\' %s" % (TOR_ROUTER, BACKEND_TOR_ROUTER, self.sample_graph_simple), stderr=subprocess.STDOUT, shell=True) + else: + output = subprocess.check_output("sed -i \'s/%s/%s/g\' %s" % (TOR_ROUTER, BACKEND_TOR_ROUTER, self.sample_graph_simple), shell=True) + + self.test_jinja_expression(self.sample_graph_simple, BACKEND_TOR_ROUTER) + + + # INTERFACE table does not exist + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "INTERFACE"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "") + + # PORTCHANNEL_INTERFACE table does not exist + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORTCHANNEL_INTERFACE"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "") + + # All the other tables stay unchanged + self.test_var_json_data() + self.test_minigraph_vlans() + self.test_minigraph_vlan_members() + self.test_minigraph_vlan_interfaces() + self.test_minigraph_portchannels() + self.test_minigraph_ethernet_interfaces() + self.test_minigraph_extra_ethernet_interfaces() + self.test_minigraph_vnet() + self.test_minigraph_vxlan() + + # VLAN_SUB_INTERFACE + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v VLAN_SUB_INTERFACE' + output = self.run_script(argument) + print output.strip() + self.assertEqual(output.strip(), \ + "{('PortChannel01.10', '10.0.0.56/31'): {}, " + "'Ethernet0.10': {'admin_status': 'up'}, " + "('Ethernet0.10', '10.0.0.58/31'): {}, " + "('PortChannel01.10', 'FC00::71/126'): {}, " + "'PortChannel01.10': {'admin_status': 'up'}, " + "('Ethernet0.10', 'FC00::75/126'): {}}") + + finally: + print '\n Change device type back to %s' % (TOR_ROUTER) + if check_stderr: + output = subprocess.check_output("sed -i \'s/%s/%s/g\' %s" % (BACKEND_TOR_ROUTER, TOR_ROUTER, self.sample_graph_simple), stderr=subprocess.STDOUT, shell=True) + else: + output = subprocess.check_output("sed -i \'s/%s/%s/g\' %s" % (BACKEND_TOR_ROUTER, TOR_ROUTER, self.sample_graph_simple), shell=True) + + self.test_jinja_expression(self.sample_graph_simple, TOR_ROUTER) diff --git a/src/sonic-config-engine/tests/test_frr.py b/src/sonic-config-engine/tests/test_frr.py new file mode 100644 index 000000000000..fcbff063b13b --- /dev/null +++ b/src/sonic-config-engine/tests/test_frr.py @@ -0,0 +1,62 @@ +from unittest import TestCase +import subprocess +import os +import filecmp + + +class TestCfgGen(TestCase): + def setUp(self): + self.test_dir = os.path.dirname(os.path.realpath(__file__)) + self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.t0_minigraph = os.path.join(self.test_dir, 't0-sample-graph.xml') + self.t0_port_config = os.path.join(self.test_dir, 't0-sample-port-config.ini') + self.output_file = os.path.join(self.test_dir, 'output') + + def tearDown(self): + try: + os.remove(self.output_file) + except OSError: + pass + + + 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_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 + self.run_script(cmd) + + original_filename = os.path.join(self.test_dir, 'sample_output', target) + r = filecmp.cmp(original_filename, self.output_file) + diff_output = self.run_diff(original_filename, self.output_file) if not r else "" + + return r, "Diff:\n" + diff_output + + + def test_config_frr(self): + self.assertTrue(*self.run_case('frr.conf.j2', 'frr.conf')) + + def test_bgpd_frr(self): + self.assertTrue(*self.run_case('bgpd.conf.j2', 'bgpd_frr.conf')) + + def test_zebra_frr(self): + self.assertTrue(*self.run_case('zebra.conf.j2', 'zebra_frr.conf')) + + def test_staticd_frr(self): + self.assertTrue(*self.run_case('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 01bb5d8144dc..c3585a41d44e 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -12,6 +12,7 @@ def setUp(self): self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') self.simple_minigraph = os.path.join(self.test_dir, 'simple-sample-graph.xml') self.t0_minigraph = os.path.join(self.test_dir, 't0-sample-graph.xml') + self.t0_mvrf_minigraph = os.path.join(self.test_dir, 't0-sample-graph-mvrf.xml') self.pc_minigraph = os.path.join(self.test_dir, 'pc-test-graph.xml') self.t0_port_config = os.path.join(self.test_dir, 't0-sample-port-config.ini') self.t1_mlnx_minigraph = os.path.join(self.test_dir, 't1-sample-graph-mlnx.xml') @@ -32,6 +33,10 @@ def test_interfaces(self): self.run_script(argument) self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'interfaces'), self.output_file)) + argument = '-m ' + self.t0_mvrf_minigraph + ' -a \'{\"hwaddr\":\"e4:1d:2d:a5:f3:ad\"}\' -t ' + interfaces_template + ' > ' + self.output_file + self.run_script(argument) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'mvrf_interfaces'), self.output_file)) + def test_ports_json(self): ports_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent', 'ports.json.j2') argument = '-m ' + self.simple_minigraph + ' -p ' + self.t0_port_config + ' -t ' + ports_template + ' > ' + self.output_file @@ -72,29 +77,6 @@ def test_zebra_quagga(self): self.run_script(argument) self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'zebra_quagga.conf'), self.output_file)) - def test_config_frr(self): - conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', 'frr.conf.j2') - argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + conf_template + ' > ' + self.output_file - self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'frr.conf'), self.output_file)) - - - def test_bgpd_frr(self): - conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', 'bgpd.conf.j2') - argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + conf_template + ' > ' + self.output_file - self.run_script(argument) - original_filename = os.path.join(self.test_dir, 'sample_output', 'bgpd_frr.conf') - r = filecmp.cmp(original_filename, self.output_file) - diff_output = self.run_diff(original_filename, self.output_file) if not r else "" - self.assertTrue(r, "Diff:\n" + diff_output) - - def test_zebra_frr(self): - conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-quagga', 'zebra.conf.j2') - argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + conf_template + ' > ' + self.output_file - self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'zebra_frr.conf'), self.output_file)) - - def test_ipinip(self): ipinip_file = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent', 'ipinip.json.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + ipinip_file + ' > ' + self.output_file 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 388f1b2885a6..41ac347e2b18 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 @@ -16,42 +16,39 @@ def setUp(self): self.t2_chassis_fe_port_config = os.path.join(self.test_dir, 't2-chassis-fe-port-config.ini') self.output_file = os.path.join(self.test_dir, 'output') + def tearDown(self): + try: + os.remove(self.output_file) + except OSError: + pass + def run_script(self, argument): print 'CMD: sonic-cfggen ' + argument return subprocess.check_output(self.script_file + ' ' + argument, shell=True) + def run_diff(self, file1, file2): + 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 + self.run_script(cmd) + + original_filename = os.path.join(self.test_dir, 'sample_output', target) + r = filecmp.cmp(original_filename, self.output_file) + diff_output = self.run_diff(original_filename, self.output_file) if not r else "" + + return r, "Diff:\n" + diff_output + # Test zebra.conf in FRR docker for a T2 chassis frontend (fe) def test_t2_chassis_fe_zebra_frr(self): - conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', 'zebra.conf.j2') - argument = '-m ' + self.t2_chassis_fe_minigraph + ' -p ' + self.t2_chassis_fe_port_config + ' -t ' + conf_template + ' > ' + self.output_file - self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 't2-chassis-fe-zebra.conf'), self.output_file)) - - # Test zebra.conf in FRR docker for a T2 chassis frontend (fe) switch with port channel interfaces - def test_t2_chassis_fe_pc_zebra_frr(self): - conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', 'zebra.conf.j2') - argument = '-m ' + self.t2_chassis_fe_pc_minigraph + ' -p ' + self.t2_chassis_fe_port_config + ' -t ' + conf_template + ' > ' + self.output_file - self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 't2-chassis-fe-pc-zebra.conf'), self.output_file)) + self.assertTrue(*self.run_case(self.t2_chassis_fe_minigraph, '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_pc_zebra_frr(self): - conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', 'zebra.conf.j2') - argument = '-m ' + self.t2_chassis_fe_vni_minigraph + ' -p ' + self.t2_chassis_fe_port_config + ' -t ' + conf_template + ' > ' + self.output_file - self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 't2-chassis-fe-vni-zebra.conf'), self.output_file)) + 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')) # Test bgpd.conf in FRR docker for a T2 chassis frontend (fe) def test_t2_chassis_frontend_bgpd_frr(self): - conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-frr', 'bgpd.conf.j2') - argument = '-m ' + self.t2_chassis_fe_minigraph + ' -p ' + self.t2_chassis_fe_port_config + ' -t ' + conf_template + ' > ' + self.output_file - self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 't2-chassis-fe-bgpd.conf'), self.output_file)) - - def tearDown(self): - try: - os.remove(self.output_file) - except OSError: - pass - + self.assertTrue(*self.run_case(self.t2_chassis_fe_minigraph, 'bgpd.conf.j2', 't2-chassis-fe-bgpd.conf')) diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index ded5d6182341..b77f0859584a 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -59,10 +59,11 @@ def test_render_template(self): output = self.run_script(argument) self.assertEqual(output.strip(), 'value1\nvalue2') - def test_minigraph_everflow(self): - argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v MIRROR_SESSION' - output = self.run_script(argument) - self.assertEqual(output.strip(), "{'everflow0': {'src_ip': '10.1.0.32', 'dst_ip': '10.0.100.1'}}") +# everflow portion is not used +# def test_minigraph_everflow(self): +# argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v MIRROR_SESSION' +# output = self.run_script(argument) +# self.assertEqual(output.strip(), "{'everflow0': {'src_ip': '10.1.0.32', 'dst_ip': '10.0.100.1'}}") def test_minigraph_interfaces(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v \'INTERFACE.keys()\'' @@ -104,10 +105,11 @@ def test_minigraph_neighbor_metadata(self): output = self.run_script(argument) self.assertEqual(output.strip(), "{'switch-01t1': {'lo_addr': '10.1.0.186/32', 'mgmt_addr': '10.7.0.196/26', 'hwsku': 'Force10-S6000', 'type': 'LeafRouter', 'deployment_id': '2'}}") - def test_metadata_everflow(self): - argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "MIRROR_SESSION"' - output = self.run_script(argument) - self.assertEqual(output.strip(), "{'everflow0': {'src_ip': '10.1.0.32', 'dst_ip': '10.0.100.1'}}") +# everflow portion is not used +# def test_metadata_everflow(self): +# argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "MIRROR_SESSION"' +# output = self.run_script(argument) +# self.assertEqual(output.strip(), "{'everflow0': {'src_ip': '10.1.0.32', 'dst_ip': '10.0.100.1'}}") def test_metadata_tacacs(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "TACPLUS_SERVER"' @@ -133,3 +135,9 @@ def test_minigraph_vxlan(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "VXLAN_TUNNEL"' output = self.run_script(argument) self.assertEqual(output.strip(), "") + + def test_minigraph_bgp_mon(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "BGP_MONITORS"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "{}") + 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 e238c13c22be..a0a5bff0a297 100644 --- a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py +++ b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py @@ -7,7 +7,6 @@ import os import sys import syslog - from swsscommon import swsscommon except ImportError, e: raise ImportError (str(e) + " - required module not found") @@ -38,6 +37,7 @@ # def db_connect(db): + from swsscommon import swsscommon return swsscommon.DBConnector(db, REDIS_HOSTNAME, REDIS_PORT, @@ -48,9 +48,12 @@ def db_connect(db): # class Logger(object): - def __init__(self, syslog_identifier): + def __init__(self, syslog_identifier = None): self.syslog = syslog - self.syslog.openlog(ident=syslog_identifier, logoption=self.syslog.LOG_NDELAY, facility=self.syslog.LOG_DAEMON) + if syslog_identifier is None: + self.syslog.openlog() + else: + self.syslog.openlog(ident=syslog_identifier, logoption=self.syslog.LOG_NDELAY, facility=self.syslog.LOG_DAEMON) def __del__(self): self.syslog.closelog() diff --git a/src/sonic-dbsyncd b/src/sonic-dbsyncd index fe60afa7e24a..ffb3bad2f355 160000 --- a/src/sonic-dbsyncd +++ b/src/sonic-dbsyncd @@ -1 +1 @@ -Subproject commit fe60afa7e24a7053a7bd9d7084268c1bbd203208 +Subproject commit ffb3bad2f355c28be201d5f27ac4564c46047593 diff --git a/src/sonic-device-data/tests/config_checker b/src/sonic-device-data/tests/config_checker index 29f1ba3cd74b..6cb4d029be58 100755 --- a/src/sonic-device-data/tests/config_checker +++ b/src/sonic-device-data/tests/config_checker @@ -30,10 +30,12 @@ def check_file(file_name): continue p = line.split("=", 1)[0] + # Remove trailing chip name "bcm8869x" + p = re.sub(r"\.bcm8869x(_adapter|_[a-z]\d)?$", "", p) # Remove trailing unit ".$" p = re.sub(r"\.[0-9]+$", '', p) # Remove trailing port name - p = re.sub(r"_[cxg]e(\d+)?$", '', p) + p = re.sub(r"_[cxg][de](\d+)?$", '', p) # Remove trailing port id "{id/number}" p = re.sub(r"\{.*\}", '', p) # Remove trailing port name example @@ -47,6 +49,12 @@ def check_file(file_name): p = re.sub(r"_lane\d+$", '', p) # Remove trailing "{.}$" p = re.sub(r"{[0-9]+\.[0-9]+}$", '', p) + # Remove trailing phy with number + p = re.sub(r"_phy\d+$", '', p) + # Remove trailing phase of data granularity + p = re.sub(r"_data_granularity_\w\w$", '_data_granularity', p) + # Remove trailing type of port_init_speed + p = re.sub(r"^port_init_speed_\w+$", 'port_init_speed', p) if not check_property(p): file_ok = False diff --git a/src/sonic-device-data/tests/permitted_list b/src/sonic-device-data/tests/permitted_list index 7e9adc1df318..370a920d2187 100644 --- a/src/sonic-device-data/tests/permitted_list +++ b/src/sonic-device-data/tests/permitted_list @@ -132,6 +132,7 @@ serdes_pre_driver_current serdes_preemphasis serdes_rx_los serdes_sgmii_m +serdes_tx_taps skip_L2_USER_ENTRY sram_scan_enable stable_size @@ -153,3 +154,58 @@ ifp_inports_support_enable port_flex_enable pdma_descriptor_prefetch_enable pktdma_poll_mode_channel_bitmap +ccm_dma_enable +ccmdma_intr_enable +phy_enable +init_all_modules +port_fec +appl_enable_intr_init +custom_feature_ucode_path +dma_desc_aggregator_buff_size_kb +dma_desc_aggregator_chain_length_max +dma_desc_aggregator_enable_specific_mdb_fec +dma_desc_aggregator_enable_specific_mdb_lpm +dma_desc_aggregator_timeout_usec +dram_phy_tune_mode_on_init +dtm_flow_mapping_mode_region +dtm_flow_nof_remote_cores_region +fabric_connect_mode +fabric_logical_port_base +l4_protocols_load_balancing_enable +lane_to_serdes_map_fabric +lane_to_serdes_map_nif +mdb_profile +mem_cache_enable_ecc +mem_cache_enable_parity +num_olp_tm_ports +outlif_logical_to_physical_phase_map +outlif_physical_phase_data_granularity +pmf_sexem3_stage +polled_irq_delay +polled_irq_mode +port_priorities +protocol_traps_mode +rif_id_max +sat_enable +serdes_fabric_clk_freq_in +serdes_fabric_clk_freq_out +serdes_nif_clk_freq_in +serdes_nif_clk_freq_out +soc_family +stable_filename +stable_location +suppress_unknown_prop_warnings +sw_state_max_size +system_headers_mode +tm_port_header_type_in +tm_port_header_type_out +trunk_group_max_members +ucode_port +led_fw_path +l2xlrn_thread_interval +l2xlrn_intr_en +serdes_lane_config_media_type +sai_preinit_cmd_file +sai_preinit_warmboot_cmd_file +sai_postinit_cmd_file +sai_postinit_warmboot_cmd_file diff --git a/src/sonic-frr/Makefile b/src/sonic-frr/Makefile index 1e1e198e42d7..abd9adc3fc67 100644 --- a/src/sonic-frr/Makefile +++ b/src/sonic-frr/Makefile @@ -4,17 +4,25 @@ SHELL = /bin/bash MAIN_TARGET = $(FRR) DERIVED_TARGET = $(FRR_PYTHONTOOLS) $(FRR_DBG) $(FRR_SNMP) $(FRR_SNMP_DBG) +SUFFIX = $(shell date +%Y%m%d\.%H%M%S) +FRR_BRANCH = frr/$(FRR_VERSION) +STG_BRANCH = stg_temp.$(SUFFIX) $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Build the package pushd ./frr - patch -p1 < ../patch/0001-Add-support-of-bgp-tcp-DSCP-value.patch - patch -p1 < ../patch/0002-Reduce-severity-of-Vty-connected-from-message.patch - patch -p1 < ../patch/0003-ignore-nexthop-attribute-when-NLRI-is-present.patch - patch -p1 < ../patch/0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch - patch -p1 < ../patch/0005-Support-VRF.patch + git checkout -b $(FRR_BRANCH) origin/$(FRR_BRANCH) + stg branch --create $(STG_BRANCH) $(FRR_BRANCH) + stg import -s ../patch/series tools/tarsource.sh -V -e '-sonic' dpkg-buildpackage -rfakeroot -b -us -uc -Ppkg.frr.nortrlib -j$(SONIC_CONFIG_MAKE_JOBS) + stg undo || true + git clean -xfdf + git checkout $(FRR_BRANCH) + stg branch --delete $(STG_BRANCH) + git rev-parse --short HEAD | xargs git checkout + git checkout master + git branch -D $(FRR_BRANCH) popd mv $(DERIVED_TARGET) $* $(DEST)/ diff --git a/src/sonic-frr/frr b/src/sonic-frr/frr index cd305c0973be..d49e8f75bd46 160000 --- a/src/sonic-frr/frr +++ b/src/sonic-frr/frr @@ -1 +1 @@ -Subproject commit cd305c0973be0baa1173e09f9d72e096c03e7e7e +Subproject commit d49e8f75bd46879c799375f304506dbc5d26230f diff --git a/src/sonic-frr/patch/0001-Add-support-of-bgp-tcp-DSCP-value.patch b/src/sonic-frr/patch/0001-Add-support-of-bgp-tcp-DSCP-value.patch index e9f496d7af62..9587231d8870 100644 --- a/src/sonic-frr/patch/0001-Add-support-of-bgp-tcp-DSCP-value.patch +++ b/src/sonic-frr/patch/0001-Add-support-of-bgp-tcp-DSCP-value.patch @@ -1,7 +1,7 @@ -From ef017a613691a40f32cdaa5396bbd4889b1cb647 Mon Sep 17 00:00:00 2001 +From 3ec4fa4c8377330d4e3bdbdfc453a79a7827d84d Mon Sep 17 00:00:00 2001 From: Pavel Shirshov -Date: Fri, 14 Jun 2019 17:45:31 -0700 -Subject: [PATCH] Add support of bgp tcp DSCP value +Date: Mon, 4 Nov 2019 18:09:51 -0800 +Subject: [PATCH 1/1] Add support of bgp tcp DSCP value --- bgpd/bgp_network.c | 11 ++++------- @@ -11,12 +11,12 @@ Subject: [PATCH] Add support of bgp tcp DSCP value 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c -index 4153da5a6..fed133eb7 100644 +index 1394c60b2..a70268b05 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c -@@ -569,11 +569,9 @@ int bgp_connect(struct peer *peer) +@@ -633,11 +633,9 @@ int bgp_connect(struct peer *peer) #ifdef IPTOS_PREC_INTERNETCONTROL - frr_elevate_privs(&bgpd_privs) { + frr_with_privs(&bgpd_privs) { if (sockunion_family(&peer->su) == AF_INET) - setsockopt_ipv4_tos(peer->fd, - IPTOS_PREC_INTERNETCONTROL); @@ -28,7 +28,7 @@ index 4153da5a6..fed133eb7 100644 } #endif -@@ -643,10 +641,9 @@ static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen, +@@ -713,10 +711,9 @@ static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen, #ifdef IPTOS_PREC_INTERNETCONTROL if (sa->sa_family == AF_INET) @@ -42,10 +42,10 @@ index 4153da5a6..fed133eb7 100644 sockopt_v6only(sa->sa_family, sock); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c -index 7445df883..f91b908a4 100644 +index 141d5cf30..8faa918d0 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c -@@ -1113,6 +1113,42 @@ DEFUN (no_router_bgp, +@@ -1182,6 +1182,42 @@ DEFUN (no_router_bgp, return CMD_SUCCESS; } @@ -88,7 +88,7 @@ index 7445df883..f91b908a4 100644 /* BGP router-id. */ -@@ -12798,6 +12834,10 @@ void bgp_vty_init(void) +@@ -13035,6 +13071,10 @@ void bgp_vty_init(void) /* "no router bgp" commands. */ install_element(CONFIG_NODE, &no_router_bgp_cmd); @@ -100,10 +100,10 @@ index 7445df883..f91b908a4 100644 install_element(BGP_NODE, &bgp_router_id_cmd); install_element(BGP_NODE, &no_bgp_router_id_cmd); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c -index 6fb3a70c7..503e6b4ed 100644 +index 80c6dd613..87a8ef34f 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c -@@ -2995,7 +2995,7 @@ static struct bgp *bgp_create(as_t *as, const char *name, +@@ -3050,7 +3050,7 @@ static struct bgp *bgp_create(as_t *as, const char *name, bgp->evpn_info = XCALLOC(MTYPE_BGP_EVPN_INFO, sizeof(struct bgp_evpn_info)); @@ -112,7 +112,7 @@ index 6fb3a70c7..503e6b4ed 100644 bgp_evpn_init(bgp); bgp_pbr_init(bgp); return bgp; -@@ -7516,6 +7516,9 @@ int bgp_config_write(struct vty *vty) +@@ -7564,6 +7564,9 @@ int bgp_config_write(struct vty *vty) if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) vty_out(vty, " no bgp fast-external-failover\n"); @@ -123,10 +123,10 @@ index 6fb3a70c7..503e6b4ed 100644 if (bgp->router_id_static.s_addr != 0) vty_out(vty, " bgp router-id %s\n", diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h -index df3fde840..a6546457c 100644 +index e4f4dc0b5..4d372c562 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h -@@ -553,6 +553,9 @@ struct bgp { +@@ -569,6 +569,9 @@ struct bgp { /* Count of peers in established state */ uint32_t established_peers; diff --git a/src/sonic-frr/patch/0002-Reduce-severity-of-Vty-connected-from-message.patch b/src/sonic-frr/patch/0002-Reduce-severity-of-Vty-connected-from-message.patch index ae2b3ba91223..e47544f79384 100644 --- a/src/sonic-frr/patch/0002-Reduce-severity-of-Vty-connected-from-message.patch +++ b/src/sonic-frr/patch/0002-Reduce-severity-of-Vty-connected-from-message.patch @@ -1,17 +1,17 @@ -From 87760a6a04d6ffbcc7a1093549bfb76656002b61 Mon Sep 17 00:00:00 2001 +From 63b5b14ad289f18928beac65754e7bb13183b5dc Mon Sep 17 00:00:00 2001 From: Pavel Shirshov -Date: Fri, 14 Jun 2019 17:48:50 -0700 -Subject: [PATCH] Reduce severity of 'Vty connected from' message +Date: Mon, 4 Nov 2019 18:12:54 -0800 +Subject: [PATCH 1/1] Reduce severity of 'Vty connected from' message --- lib/vty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vty.c b/lib/vty.c -index 8450922c2..f159d1b4b 100644 +index deb9391bd..743ff1c17 100644 --- a/lib/vty.c +++ b/lib/vty.c -@@ -1875,7 +1875,7 @@ static int vty_accept(struct thread *thread) +@@ -1853,7 +1853,7 @@ static int vty_accept(struct thread *thread) zlog_info("can't set sockopt to vty_sock : %s", safe_strerror(errno)); diff --git a/src/sonic-frr/patch/0003-Use-vrf_id-for-vrf-not-tabled_id.patch b/src/sonic-frr/patch/0003-Use-vrf_id-for-vrf-not-tabled_id.patch new file mode 100644 index 000000000000..c9a8c0081994 --- /dev/null +++ b/src/sonic-frr/patch/0003-Use-vrf_id-for-vrf-not-tabled_id.patch @@ -0,0 +1,35 @@ +From 9e7f1de3b79ca6ada8a3124f4cdc35530284832e Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Tue, 5 Nov 2019 06:16:51 -0800 +Subject: [PATCH 1/1] Use vrf_id for vrf, not tabled_id + +--- + zebra/zebra_fpm_netlink.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c +index f347d3955..74aab8228 100644 +--- a/zebra/zebra_fpm_netlink.c ++++ b/zebra/zebra_fpm_netlink.c +@@ -284,7 +284,6 @@ static int netlink_route_info_fill(netlink_route_info_t *ri, int cmd, + rib_dest_t *dest, struct route_entry *re) + { + struct nexthop *nexthop; +- struct zebra_vrf *zvrf; + + memset(ri, 0, sizeof(*ri)); + +@@ -292,9 +291,7 @@ static int netlink_route_info_fill(netlink_route_info_t *ri, int cmd, + ri->af = rib_dest_af(dest); + + ri->nlmsg_type = cmd; +- zvrf = rib_dest_vrf(dest); +- if (zvrf) +- ri->rtm_table = zvrf->table_id; ++ ri->rtm_table = zvrf_id(rib_dest_vrf(dest)); + ri->rtm_protocol = RTPROT_UNSPEC; + + /* +-- +2.17.1.windows.2 + diff --git a/src/sonic-frr/patch/0003-ignore-nexthop-attribute-when-NLRI-is-present.patch b/src/sonic-frr/patch/0003-ignore-nexthop-attribute-when-NLRI-is-present.patch deleted file mode 100644 index 5d55ce547fd1..000000000000 --- a/src/sonic-frr/patch/0003-ignore-nexthop-attribute-when-NLRI-is-present.patch +++ /dev/null @@ -1,156 +0,0 @@ -From 7c31178d8f1b8cc3a9627dc7c7bd1d2a51fe54ce Mon Sep 17 00:00:00 2001 -From: Pavel Shirshov -Date: Tue, 18 Jun 2019 15:27:19 -0700 -Subject: [PATCH] ignore nexthop attribute when NLRI is present - -Backport of https://github.com/FRRouting/frr/pull/4258 ---- - bgpd/bgp_attr.c | 73 ++++++++++++++++++++++++++++++----------------- - bgpd/bgp_attr.h | 3 ++ - bgpd/bgp_packet.c | 11 +++++++ - 3 files changed, 61 insertions(+), 26 deletions(-) - -diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c -index 05e103142..ea7f761ab 100644 ---- a/bgpd/bgp_attr.c -+++ b/bgpd/bgp_attr.c -@@ -1257,6 +1257,32 @@ static int bgp_attr_as4_path(struct bgp_attr_parser_args *args, - return BGP_ATTR_PARSE_PROCEED; - } - -+/* -+ * Check that the nexthop attribute is valid. -+ */ -+bgp_attr_parse_ret_t -+bgp_attr_nexthop_valid(struct peer *peer, struct attr *attr) -+{ -+ in_addr_t nexthop_h; -+ -+ nexthop_h = ntohl(attr->nexthop.s_addr); -+ if ((IPV4_NET0(nexthop_h) || IPV4_NET127(nexthop_h) -+ || IPV4_CLASS_DE(nexthop_h)) -+ && !BGP_DEBUG(allow_martians, ALLOW_MARTIANS)) { -+ char buf[INET_ADDRSTRLEN]; -+ -+ inet_ntop(AF_INET, &attr->nexthop.s_addr, buf, -+ INET_ADDRSTRLEN); -+ flog_err(EC_BGP_ATTR_MARTIAN_NH, "Martian nexthop %s", -+ buf); -+ bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR, -+ BGP_NOTIFY_UPDATE_INVAL_NEXT_HOP); -+ return BGP_ATTR_PARSE_ERROR; -+ } -+ -+ return BGP_ATTR_PARSE_PROCEED; -+} -+ - /* Nexthop attribute. */ - static bgp_attr_parse_ret_t bgp_attr_nexthop(struct bgp_attr_parser_args *args) - { -@@ -1264,8 +1290,6 @@ static bgp_attr_parse_ret_t bgp_attr_nexthop(struct bgp_attr_parser_args *args) - struct attr *const attr = args->attr; - const bgp_size_t length = args->length; - -- in_addr_t nexthop_h, nexthop_n; -- - /* Check nexthop attribute length. */ - if (length != 4) { - flog_err(EC_BGP_ATTR_LEN, -@@ -1275,30 +1299,7 @@ static bgp_attr_parse_ret_t bgp_attr_nexthop(struct bgp_attr_parser_args *args) - args->total); - } - -- /* According to section 6.3 of RFC4271, syntactically incorrect NEXT_HOP -- attribute must result in a NOTIFICATION message (this is implemented -- below). -- At the same time, semantically incorrect NEXT_HOP is more likely to -- be just -- logged locally (this is implemented somewhere else). The UPDATE -- message -- gets ignored in any of these cases. */ -- nexthop_n = stream_get_ipv4(peer->curr); -- nexthop_h = ntohl(nexthop_n); -- if ((IPV4_NET0(nexthop_h) || IPV4_NET127(nexthop_h) -- || IPV4_CLASS_DE(nexthop_h)) -- && !BGP_DEBUG( -- allow_martians, -- ALLOW_MARTIANS)) /* loopbacks may be used in testing */ -- { -- char buf[INET_ADDRSTRLEN]; -- inet_ntop(AF_INET, &nexthop_n, buf, INET_ADDRSTRLEN); -- flog_err(EC_BGP_ATTR_MARTIAN_NH, "Martian nexthop %s", buf); -- return bgp_attr_malformed( -- args, BGP_NOTIFY_UPDATE_INVAL_NEXT_HOP, args->total); -- } -- -- attr->nexthop.s_addr = nexthop_n; -+ attr->nexthop.s_addr = stream_get_ipv4(peer->curr); - attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP); - - return BGP_ATTR_PARSE_PROCEED; -@@ -2669,6 +2670,26 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr, - return BGP_ATTR_PARSE_ERROR; - } - -+ /* -+ * RFC4271: If the NEXT_HOP attribute field is syntactically incorrect, -+ * then the Error Subcode MUST be set to Invalid NEXT_HOP Attribute. -+ * This is implemented below and will result in a NOTIFICATION. If the -+ * NEXT_HOP attribute is semantically incorrect, the error SHOULD be -+ * logged, and the route SHOULD be ignored. In this case, a NOTIFICATION -+ * message SHOULD NOT be sent. This is implemented elsewhere. -+ * -+ * RFC4760: An UPDATE message that carries no NLRI, other than the one -+ * encoded in the MP_REACH_NLRI attribute, SHOULD NOT carry the NEXT_HOP -+ * attribute. If such a message contains the NEXT_HOP attribute, the BGP -+ * speaker that receives the message SHOULD ignore this attribute. -+ */ -+ if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) -+ && !CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI))) { -+ if (bgp_attr_nexthop_valid(peer, attr) < 0) { -+ return BGP_ATTR_PARSE_ERROR; -+ } -+ } -+ - /* Check all mandatory well-known attributes are present */ - if ((ret = bgp_attr_check(peer, attr)) < 0) { - if (as4_path) -diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h -index 47a4182fe..a86684583 100644 ---- a/bgpd/bgp_attr.h -+++ b/bgpd/bgp_attr.h -@@ -350,6 +350,9 @@ extern void bgp_packet_mpunreach_prefix(struct stream *s, struct prefix *p, - uint32_t, int, uint32_t, struct attr *); - extern void bgp_packet_mpunreach_end(struct stream *s, size_t attrlen_pnt); - -+extern bgp_attr_parse_ret_t bgp_attr_nexthop_valid(struct peer *peer, -+ struct attr *attr); -+ - static inline int bgp_rmap_nhop_changed(uint32_t out_rmap_flags, - uint32_t in_rmap_flags) - { -diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c -index fe8a1a256..13f4cf436 100644 ---- a/bgpd/bgp_packet.c -+++ b/bgpd/bgp_packet.c -@@ -1533,6 +1533,17 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) - nlris[NLRI_UPDATE].nlri = stream_pnt(s); - nlris[NLRI_UPDATE].length = update_len; - stream_forward_getp(s, update_len); -+ -+ if (CHECK_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI))) { -+ /* -+ * We skipped nexthop attribute validation earlier so -+ * validate the nexthop now. -+ */ -+ if (bgp_attr_nexthop_valid(peer, &attr) < 0) { -+ bgp_attr_unintern_sub(&attr); -+ return BGP_Stop; -+ } -+ } - } - - if (BGP_DEBUG(update, UPDATE_IN)) --- -2.17.1.windows.2 - diff --git a/src/sonic-frr/patch/0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch b/src/sonic-frr/patch/0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch index 22cf08b82cd4..b31da0651ae1 100644 --- a/src/sonic-frr/patch/0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch +++ b/src/sonic-frr/patch/0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch @@ -1,18 +1,18 @@ -From 4cd83e56e4f67fdc06325d92a82534fb4cb69952 Mon Sep 17 00:00:00 2001 +From fe1e544d46d721798594fcec175665e3754500a6 Mon Sep 17 00:00:00 2001 From: Pavel Shirshov -Date: Thu, 20 Jun 2019 15:35:50 -0700 -Subject: [PATCH] Allow BGP attr NEXT_HOP to be 0.0.0.0 due to alleviate the - vendor bug +Date: Mon, 4 Nov 2019 18:14:12 -0800 +Subject: [PATCH 1/1] Allow BGP attr NEXT_HOP to be 0.0.0.0 due to alleviate + the vendor bug --- bgpd/bgp_route.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c -index 38f3cad5a..55240eab8 100644 +index c122df498..3c7aa3075 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c -@@ -2873,8 +2873,7 @@ static int bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi, +@@ -2983,8 +2983,7 @@ static int bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi, /* If NEXT_HOP is present, validate it. */ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) { diff --git a/src/sonic-frr/patch/0005-Support-VRF.patch b/src/sonic-frr/patch/0005-Support-VRF.patch deleted file mode 100644 index c6de0e5ecf0e..000000000000 --- a/src/sonic-frr/patch/0005-Support-VRF.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 81990d9aafdfd459c0caa6cf07501fa628ada454 Mon Sep 17 00:00:00 2001 -From: Tyler Li -Date: Mon, 3 Jun 2019 01:48:11 -0700 -Subject: [PATCH] Support VRF - ---- - zebra/zebra_fpm_netlink.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c -index 207cbc099..b98c6886b 100644 ---- a/zebra/zebra_fpm_netlink.c -+++ b/zebra/zebra_fpm_netlink.c -@@ -327,7 +327,12 @@ static int netlink_route_info_encode(netlink_route_info_t *ri, char *in_buf, - req->n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST; - req->n.nlmsg_type = ri->nlmsg_type; - req->r.rtm_family = ri->af; -- req->r.rtm_table = ri->rtm_table; -+ if (ri->rtm_table < 256) -+ req->r.rtm_table = ri->rtm_table; -+ else { -+ req->r.rtm_table = RT_TABLE_COMPAT; -+ addattr32(&req->n, in_buf_len, RTA_TABLE, ri->rtm_table); -+ } - req->r.rtm_dst_len = ri->prefix->prefixlen; - req->r.rtm_protocol = ri->rtm_protocol; - req->r.rtm_scope = RT_SCOPE_UNIVERSE; --- -2.11.0 - diff --git a/src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch b/src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch new file mode 100644 index 000000000000..343f1b3262d9 --- /dev/null +++ b/src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch @@ -0,0 +1,73 @@ +From 2f0b5aef66316b47d2cc8ac18453600621a6a317 Mon Sep 17 00:00:00 2001 +From: Tyler Li +Date: Thu, 14 Nov 2019 23:46:52 -0800 +Subject: [PATCH] nexthops compare vrf only if ip type + +--- + lib/nexthop.c | 12 ++++++------ + lib/zclient.c | 12 ++++++------ + 2 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/lib/nexthop.c b/lib/nexthop.c +index cf5bed3d6..7d9f646c9 100644 +--- a/lib/nexthop.c ++++ b/lib/nexthop.c +@@ -105,12 +105,6 @@ static int _nexthop_cmp_no_labels(const struct nexthop *next1, + { + int ret = 0; + +- if (next1->vrf_id < next2->vrf_id) +- return -1; +- +- if (next1->vrf_id > next2->vrf_id) +- return 1; +- + if (next1->type < next2->type) + return -1; + +@@ -120,6 +114,12 @@ static int _nexthop_cmp_no_labels(const struct nexthop *next1, + switch (next1->type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV6: ++ if (next1->vrf_id < next2->vrf_id) ++ return -1; ++ ++ if (next1->vrf_id > next2->vrf_id) ++ return 1; ++ + ret = _nexthop_gateway_cmp(next1, next2); + if (ret != 0) + return ret; +diff --git a/lib/zclient.c b/lib/zclient.c +index c739af043..0d37c46d1 100644 +--- a/lib/zclient.c ++++ b/lib/zclient.c +@@ -783,12 +783,6 @@ static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1, + { + int ret = 0; + +- if (next1->vrf_id < next2->vrf_id) +- return -1; +- +- if (next1->vrf_id > next2->vrf_id) +- return 1; +- + if (next1->type < next2->type) + return -1; + +@@ -798,6 +792,12 @@ static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1, + switch (next1->type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV6: ++ if (next1->vrf_id < next2->vrf_id) ++ return -1; ++ ++ if (next1->vrf_id > next2->vrf_id) ++ return 1; ++ + ret = nexthop_g_addr_cmp(next1->type, &next1->gate, + &next2->gate); + if (ret != 0) +-- +2.11.0 + diff --git a/src/sonic-frr/patch/0006-changes-for-making-snmp-socket-non-blocking.patch b/src/sonic-frr/patch/0006-changes-for-making-snmp-socket-non-blocking.patch new file mode 100644 index 000000000000..a106eca3d831 --- /dev/null +++ b/src/sonic-frr/patch/0006-changes-for-making-snmp-socket-non-blocking.patch @@ -0,0 +1,85 @@ +From 6d43b90540c6aeda0fff001de93c88e01aacadab Mon Sep 17 00:00:00 2001 +From: sudhanshukumar22 +Date: Tue, 15 Oct 2019 02:11:01 -0700 +Subject: [PATCH] lib: changes for making snmp socket non-blocking + +Description: The changes have been done to make the snmp socket +non-blocking before calling snmp_read() +FRR Pull request: https://github.com/FRRouting/frr/pull/5134 + +Problem Description/Summary : +vtysh hangs on first try to enter after a reboot with BGP dynamic peers + +Expected Behavior : +VTYSH should not hang. +When we debug more into bgpd docker by doing gdb on its threads, we find the below thread of bgpd, which is causing the issue. +Thread 1 (Thread 0x7f1e1ec46d40 (LWP 47)): + +0x00007f1e1d762593 in recvfrom () from /lib/x86_64-linux-gnu/libpthread.so.0 +0x00007f1e1aadd09b in netsnmp_tcpbase_recv () from /usr/lib/x86_64-linux-gnu/libnetsnmp.so.30 +0x00007f1e1aad9617 in netsnmp_transport_recv () from /usr/lib/x86_64-linux-gnu/libnetsnmp.so.30 +0x00007f1e1aab2c07 in _sess_read () from /usr/lib/x86_64-linux-gnu/libnetsnmp.so.30 +0x00007f1e1aab3a29 in snmp_sess_read2 () from /usr/lib/x86_64-linux-gnu/libnetsnmp.so.30 +0x00007f1e1aab3a7b in snmp_read2 () from /usr/lib/x86_64-linux-gnu/libnetsnmp.so.30 +0x00007f1e1aab3acf in snmp_read () from /usr/lib/x86_64-linux-gnu/libnetsnmp.so.30 +0x00007f1e1b44d7ec in agentx_read (t=0x7fffa75f0080) at lib/agentx.c:63 +0x00007f1e1e7d6451 in thread_call (thread=0x7fffa75f0080) at lib/thread.c:1620 +0x00007f1e1e770699 in frr_run (master=0x559396ea60f0) at lib/libfrr.c:1011 +0x0000559395b4d953 in main (argc=5, argv=0x7fffa75f02b8) at bgpd/bgp_main.c:492 + +(gdb) bt + +0x00007f830c89d210 in __read_nocancel () from /lib/x86_64-linux-gnu/libpthread.so.0 +0x000056450e1e8238 in vtysh_client_run (vclient=0x56450e4a8b40 , line=0x56450e21add0 enable, callback=0x0, cbarg=0x0) at vtysh/vtysh.c:216 +0x000056450e1e8c6b in vtysh_client_run_all (head_client=0x56450e4a8b40 , line=0x56450e21add0 enable, continue_on_err=0, callback=0x0, cbarg=0x0) at vtysh/vtysh.c:356 +0x000056450e1e8ddb in vtysh_client_execute (head_client=0x56450e4a8b40 , line=0x56450e21add0 enable) at vtysh/vtysh.c:393 +0x000056450e1e9c82 in vtysh_execute_func (line=0x56450e21add0 enable, pager=0) at vtysh/vtysh.c:598 +0x000056450e1e9dee in vtysh_execute_no_pager (line=0x56450e21add0 enable) at vtysh/vtysh.c:619 +0x000056450e1f7d48 in vtysh_read_file (confp=0x56451000a9d0, top_cfg=1) at vtysh/vtysh_config.c:494 +0x000056450e1f7ef2 in vtysh_read_config (config_default_dir=0x56450e4edc20 /etc/frr/frr.conf, top_cfg=1) at vtysh/vtysh_config.c:522 +0x000056450e1e5de4 in vtysh_apply_top_level_config () at vtysh/vtysh_main.c:301 +0x000056450e1e7842 in main (argc=2, argv=0x7ffc81e6f598, env=0x7ffc81e6f5b0) at vtysh/vtysh_main.c:692 + +The fix has been taken from the following link. +https://sourceforge.net/p/net-snmp/patches/1348/ +--- + lib/agentx.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/lib/agentx.c b/lib/agentx.c +index 40cac722a..2c6a43d1a 100644 +--- a/lib/agentx.c ++++ b/lib/agentx.c +@@ -55,13 +55,29 @@ static int agentx_timeout(struct thread *t) + static int agentx_read(struct thread *t) + { + fd_set fds; ++ int flags; ++ int nonblock = false; + struct listnode *ln = THREAD_ARG(t); + list_delete_node(events, ln); + ++ /* fix for non blocking socket */ ++ flags = fcntl(THREAD_FD(t), F_GETFL, 0); ++ if (-1 == flags) ++ return -1; ++ ++ if (flags & O_NONBLOCK) ++ nonblock = true; ++ else ++ fcntl(THREAD_FD(t), F_SETFL, flags | O_NONBLOCK); ++ + FD_ZERO(&fds); + FD_SET(THREAD_FD(t), &fds); + snmp_read(&fds); + ++ /* Reset the flag */ ++ if (!nonblock) ++ fcntl(THREAD_FD(t), F_SETFL, flags); ++ + netsnmp_check_outstanding_agent_requests(); + agentx_events_update(); + return 0; +-- +2.18.0 + diff --git a/src/sonic-frr/patch/series b/src/sonic-frr/patch/series index 4033e555fe7f..13619c87ff65 100644 --- a/src/sonic-frr/patch/series +++ b/src/sonic-frr/patch/series @@ -1,5 +1,6 @@ 0001-Add-support-of-bgp-tcp-DSCP-value.patch 0002-Reduce-severity-of-Vty-connected-from-message.patch -0003-ignore-nexthop-attribute-when-NLRI-is-present.patch +0003-Use-vrf_id-for-vrf-not-tabled_id.patch 0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch -0005-Support-VRF.patch +0005-nexthops-compare-vrf-only-if-ip-type.patch +0006-changes-for-making-snmp-socket-non-blocking.patch diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index 1d9c69fbe1b9..feb42b05eb91 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit 1d9c69fbe1b996fd84a659bd28c91f67fe1fe044 +Subproject commit feb42b05eb912ea64f0b4ce17f4bc890929eb57e diff --git a/src/sonic-platform-common b/src/sonic-platform-common index 56b5b14dec17..d22f0a0e64f3 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 56b5b14dec179ddf445849fae2e7783ead0475b7 +Subproject commit d22f0a0e64f30e9e26064824fb11f27b2d636850 diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index 6618737230c2..a34ba131f618 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit 6618737230c27668d2ae8787f15311171262215f +Subproject commit a34ba131f618a8df6beec1f548aa08f9cedc48db diff --git a/src/sonic-quagga b/src/sonic-quagga index b1d01a2dd841..904a35010779 160000 --- a/src/sonic-quagga +++ b/src/sonic-quagga @@ -1 +1 @@ -Subproject commit b1d01a2dd841f76e73067171702f7c6321793c49 +Subproject commit 904a350107793d44be7167500fcec9087ca3243b diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 80c7e8b11057..533749062f63 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 80c7e8b110571b9dfcf58bc15286beb1eda4195b +Subproject commit 533749062f638f74ebc09c4bd0a5162b2c575564 diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent index 70a6c7dad4fc..862e51ab85d4 160000 --- a/src/sonic-snmpagent +++ b/src/sonic-snmpagent @@ -1 +1 @@ -Subproject commit 70a6c7dad4fcfa750fb4d4efbf267842d19ca8ef +Subproject commit 862e51ab85d48290082adfcbb801bfbbe3a95bf3 diff --git a/src/sonic-swss b/src/sonic-swss index 5be3963793d5..c3b8fe10b156 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 5be3963793d5d04807931f016faf1fcca87f6286 +Subproject commit c3b8fe10b1568022fa025ef4be9cb063bfe49df4 diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 036a5d36ad30..a4a1e108afb3 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 036a5d36ad307303fdd9315bb06f2240842e5999 +Subproject commit a4a1e108afb3e75717e204da49a975681d964e8c diff --git a/src/supervisor/Makefile b/src/supervisor/Makefile index cac8bc1859ef..2bd2724a39a1 100644 --- a/src/supervisor/Makefile +++ b/src/supervisor/Makefile @@ -21,7 +21,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : stg init stg import -s ../patch/series -ifeq ($(CONFIGURED_ARCH), armhf) +ifneq (,$(filter $(CONFIGURED_ARCH), armhf arm64)) stg import -s ../patch/series-armhf endif diff --git a/src/tacacs/nss/0005-libnss-Modify-parsing-of-IP-addr-and-port-number-str.patch b/src/tacacs/nss/0005-libnss-Modify-parsing-of-IP-addr-and-port-number-str.patch new file mode 100644 index 000000000000..247972b63b55 --- /dev/null +++ b/src/tacacs/nss/0005-libnss-Modify-parsing-of-IP-addr-and-port-number-str.patch @@ -0,0 +1,26 @@ +From aa8af2b2400b7bbcbe7af0cb50047a98e93660ca Mon Sep 17 00:00:00 2001 +From: SuvarnaMeenakshi +Date: Thu, 29 Aug 2019 09:44:24 -0700 +Subject: [PATCH] libnss: Modify parsing of IP addr and port number string to + support IPv6 + +--- + nss_tacplus.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/nss_tacplus.c b/nss_tacplus.c +index f2a86e1..3ff3c35 100644 +--- a/nss_tacplus.c ++++ b/nss_tacplus.c +@@ -98,7 +98,7 @@ static int parse_tac_server(char *srv_buf) + hints.ai_socktype = SOCK_STREAM; + + srv = token + 7; +- port = strchr(srv, ':'); ++ port = strrchr(srv, ':'); + if(port) { + *port = '\0'; + port++; +-- +2.17.1 + diff --git a/src/tacacs/nss/Makefile b/src/tacacs/nss/Makefile index 51a5d63ebd1b..a0c42bd2f222 100644 --- a/src/tacacs/nss/Makefile +++ b/src/tacacs/nss/Makefile @@ -5,7 +5,7 @@ SHELL = /bin/bash MAIN_TARGET = libnss-tacplus_$(NSS_TACPLUS_VERSION)_$(CONFIGURED_ARCH).deb GIT_APPLY = am -ifeq ($(CONFIGURED_ARCH), armhf) +ifneq (,$(filter $(CONFIGURED_ARCH), armhf arm64)) # Workaround git am issue "Out of memory getdelim failed" GIT_APPLY = apply endif @@ -22,6 +22,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : git $(GIT_APPLY) ../0002-Enable-modifying-local-user-permission.patch 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 dpkg-buildpackage -rfakeroot -b -us -uc popd diff --git a/src/tacacs/pam/0005-pam-Modify-parsing-of-IP-address-and-port-number-to-.patch b/src/tacacs/pam/0005-pam-Modify-parsing-of-IP-address-and-port-number-to-.patch new file mode 100644 index 000000000000..541333232b56 --- /dev/null +++ b/src/tacacs/pam/0005-pam-Modify-parsing-of-IP-address-and-port-number-to-.patch @@ -0,0 +1,31 @@ +From 264de96e8a1c411371f9fc20b0b5b00c10e7052d Mon Sep 17 00:00:00 2001 +From: SuvarnaMeenakshi +Date: Thu, 29 Aug 2019 09:51:43 -0700 +Subject: [PATCH] pam: Modify parsing of IP address and port number to support + IPv6 + +--- + support.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/support.c b/support.c +index 44efee3..7c00618 100644 +--- a/support.c ++++ b/support.c +@@ -225,11 +226,11 @@ int _pam_parse (int argc, const char **argv) { + + if (*server_buf == '[' && (close_bracket = strchr(server_buf, ']')) != NULL) { /* Check for URI syntax */ + server_name = server_buf + 1; +- port = strchr(close_bracket, ':'); ++ port = strrchr(close_bracket, ':'); + *close_bracket = '\0'; + } else { /* Fall back to traditional syntax */ + server_name = server_buf; +- port = strchr(server_buf, ':'); ++ port = strrchr(server_buf, ':'); + } + if (port != NULL) { + *port = '\0'; +-- +2.17.1 + diff --git a/src/tacacs/pam/Makefile b/src/tacacs/pam/Makefile index c35f1aff37b3..487cf975fd77 100644 --- a/src/tacacs/pam/Makefile +++ b/src/tacacs/pam/Makefile @@ -18,6 +18,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : git apply ../0002-Fix-libtac2-bin-install-directory-error.patch git apply ../0003-Obfuscate-key-before-printing-to-syslog.patch git apply ../0004-management-vrf-support.patch + git apply ../0005-pam-Modify-parsing-of-IP-address-and-port-number-to-.patch dpkg-buildpackage -rfakeroot -b -us -uc popd