diff --git a/.gitignore b/.gitignore index 1f921971d8bb..316cf974e6c1 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,11 @@ target/ # Subdirectories in src src/bash/* !src/bash/Makefile +src/dhcpmon/debian/* +!src/dhcpmon/debian/changelog +!src/dhcpmon/debian/compat +!src/dhcpmon/debian/control +!src/dhcpmon/debian/rules src/ixgbe/* !src/ixgbe/Makefile src/isc-dhcp/* @@ -50,6 +55,8 @@ src/isc-dhcp/* !src/isc-dhcp/Makefile !src/isc-dhcp/patch/ src/libnl3/* +!src/libnl3/debian +src/libnl3/debian/libnl-*/ !src/libnl3/Makefile src/libteam/* !src/libteam/Makefile @@ -104,6 +111,7 @@ src/thrift/* # Autogenerated Dockerfiles sonic-slave/Dockerfile sonic-slave-stretch/Dockerfile +sonic-slave-jessie/Dockerfile dockers/docker-base/Dockerfile dockers/docker-base-stretch/Dockerfile dockers/docker-config-engine/Dockerfile @@ -140,3 +148,17 @@ src/sonic-daemon-base/sonic_daemon_base.egg-info # Misc. files files/initramfs-tools/arista-convertfs files/initramfs-tools/union-mount + +# Debian byproduct files +src/**/debian/stamp-*/ +src/**/debian/*.log +src/**/debian/*.substvars +src/**/debian/.debhelper/ +src/**/debian/tmp/ +src/**/debian/autoreconf.* +src/**/debian/build/ +src/**/debian/files +src/**/debian/stamp-autotools-files + +# .o files +src/**/*.o diff --git a/.gitmodules b/.gitmodules index b9831ba33296..ca8b4b0098a8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -75,3 +75,10 @@ [submodule "Switch-SDK-drivers"] path = platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers url = https://github.com/Mellanox/Switch-SDK-drivers +[submodule "src/sonic-restapi"] + path = src/sonic-restapi + url = https://github.com/Azure/sonic-restapi.git + branch = master +[submodule "src/sonic-ztp"] + path = src/sonic-ztp + url = https://github.com/Azure/sonic-ztp diff --git a/Makefile.work b/Makefile.work index b81ac591246f..e4e31a134555 100644 --- a/Makefile.work +++ b/Makefile.work @@ -7,7 +7,9 @@ # * BUILD_NUMBER: Desired version-number to pass to the building-system. # * ENABLE_DHCP_GRAPH_SERVICE: Enables get-graph service to fetch minigraph files # through http. +# * ENABLE_ZTP: Enables zero touch provisioning. # * SHUTDOWN_BGP_ON_START: Sets admin-down state for all bgp peerings after restart. +# * INSTALL_KUBERNETES: Allows including Kubernetes # * ENABLE_PFCWD_ON_START: Enable PFC Watchdog (PFCWD) on server-facing ports # * by default for TOR switch. # * ENABLE_SYNCD_RPC: Enables rpc-based syncd builds. @@ -162,7 +164,12 @@ SONIC_BUILD_INSTRUCTION := make \ BUILD_NUMBER=$(BUILD_NUMBER) \ BUILD_TIMESTAMP=$(BUILD_TIMESTAMP) \ ENABLE_DHCP_GRAPH_SERVICE=$(ENABLE_DHCP_GRAPH_SERVICE) \ + ENABLE_ZTP=$(ENABLE_ZTP) \ SHUTDOWN_BGP_ON_START=$(SHUTDOWN_BGP_ON_START) \ + INSTALL_KUBERNETES=$(INSTALL_KUBERNETES) \ + KUBERNETES_VERSION=$(KUBERNETES_VERSION) \ + K8s_GCR_IO_PAUSE_VERSION=$(K8s_GCR_IO_PAUSE_VERSION) \ + K8s_CNI_CALICO_VERSION=$(K8s_CNI_CALICO_VERSION) \ SONIC_ENABLE_PFCWD_ON_START=$(ENABLE_PFCWD_ON_START) \ SONIC_ENABLE_SYNCD_RPC=$(ENABLE_SYNCD_RPC) \ SONIC_INSTALL_DEBUG_TOOLS=$(INSTALL_DEBUG_TOOLS) \ @@ -175,6 +182,7 @@ SONIC_BUILD_INSTRUCTION := make \ HTTP_PROXY=$(http_proxy) \ HTTPS_PROXY=$(https_proxy) \ SONIC_ENABLE_SYSTEM_TELEMETRY=$(ENABLE_SYSTEM_TELEMETRY) \ + SONIC_ENABLE_RESTAPI=$(ENABLE_RESTAPI) \ EXTRA_JESSIE_TARGETS=$(EXTRA_JESSIE_TARGETS) \ $(SONIC_OVERRIDE_BUILD_VARS) diff --git a/build_debian.sh b/build_debian.sh index cf545ff2fe47..fac25f18de6b 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -37,7 +37,7 @@ if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then else DOCKER_VERSION=5:18.09.8~3-0~debian-stretch fi -LINUX_KERNEL_VERSION=4.9.0-9-2 +LINUX_KERNEL_VERSION=4.9.0-11-2 ## Working directory to prepare the file system FILESYSTEM_ROOT=./fsroot @@ -139,7 +139,9 @@ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/initramfs-tools_*.deb || \ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/linux-image-${LINUX_KERNEL_VERSION}-*_${CONFIGURED_ARCH}.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install acl -[[ $CONFIGURED_ARCH == amd64 ]] && sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install dmidecode +if [[ $CONFIGURED_ARCH == amd64 ]]; then + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install dmidecode hdparm +fi ## Update initramfs for booting with squashfs+overlay cat files/initramfs-tools/modules | sudo tee -a $FILESYSTEM_ROOT/etc/initramfs-tools/modules > /dev/null @@ -201,6 +203,22 @@ sudo LANG=C chroot $FILESYSTEM_ROOT apt-get update sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install docker-ce=${DOCKER_VERSION} sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y remove software-properties-common gnupg2 +if [ "$INSTALL_KUBERNETES" == "y" ] +then + ## Install Kubernetes + echo '[INFO] Install kubernetes' + sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT curl -fsSL \ + https://packages.cloud.google.com/apt/doc/apt-key.gpg | \ + sudo LANG=C chroot $FILESYSTEM_ROOT apt-key add - + ## Check out the sources list update matches current Debian version + sudo cp files/image_config/kubernetes/kubernetes.list $FILESYSTEM_ROOT/etc/apt/sources.list.d/ + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get update + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install kubeadm=${KUBERNETES_VERSION}-00 + # kubeadm package auto install kubelet & kubectl +else + echo '[INFO] Skipping Install kubernetes' +fi + ## Add docker config drop-in to specify dockerd command line sudo mkdir -p $FILESYSTEM_ROOT/etc/systemd/system/docker.service.d/ ## Note: $_ means last argument of last command @@ -272,7 +290,8 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in cgroup-tools \ ipmitool \ ndisc6 \ - makedumpfile + makedumpfile \ + conntrack if [[ $CONFIGURED_ARCH == amd64 ]]; then @@ -314,10 +333,6 @@ fi ## Disable kexec supported reboot which was installed by default sudo sed -i 's/LOAD_KEXEC=true/LOAD_KEXEC=false/' $FILESYSTEM_ROOT/etc/default/kexec -## Modifty ntp default configuration: disable initial jump (add -x), and disable -## jump when time difference is greater than 1000 seconds (remove -g). -sudo sed -i "s/NTPD_OPTS='-g'/NTPD_OPTS='-x'/" $FILESYSTEM_ROOT/etc/default/ntp - ## Remove sshd host keys, and will regenerate on first sshd start sudo rm -f $FILESYSTEM_ROOT/etc/ssh/ssh_host_*_key* sudo cp files/sshd/host-ssh-keygen.sh $FILESYSTEM_ROOT/usr/local/bin/ @@ -374,6 +389,12 @@ set /files/etc/sysctl.conf/net.ipv4.conf.all.arp_ignore 2 set /files/etc/sysctl.conf/net.ipv4.neigh.default.base_reachable_time_ms 1800000 set /files/etc/sysctl.conf/net.ipv6.neigh.default.base_reachable_time_ms 1800000 +set /files/etc/sysctl.conf/net.ipv4.neigh.default.gc_thresh1 1024 +set /files/etc/sysctl.conf/net.ipv6.neigh.default.gc_thresh1 1024 +set /files/etc/sysctl.conf/net.ipv4.neigh.default.gc_thresh2 2048 +set /files/etc/sysctl.conf/net.ipv6.neigh.default.gc_thresh2 2048 +set /files/etc/sysctl.conf/net.ipv4.neigh.default.gc_thresh3 4096 +set /files/etc/sysctl.conf/net.ipv6.neigh.default.gc_thresh3 4096 set /files/etc/sysctl.conf/net.ipv6.conf.default.forwarding 1 set /files/etc/sysctl.conf/net.ipv6.conf.all.forwarding 1 @@ -387,9 +408,6 @@ set /files/etc/sysctl.conf/net.ipv6.conf.default.keep_addr_on_down 1 set /files/etc/sysctl.conf/net.ipv6.conf.all.keep_addr_on_down 1 set /files/etc/sysctl.conf/net.ipv6.conf.eth0.keep_addr_on_down 1 -set /files/etc/sysctl.conf/net.ipv6.conf.eth0.accept_ra_defrtr 0 -set /files/etc/sysctl.conf/net.ipv6.conf.eth0.accept_ra 0 - set /files/etc/sysctl.conf/net.ipv4.tcp_l3mdev_accept 1 set /files/etc/sysctl.conf/net.ipv4.udp_l3mdev_accept 1 @@ -424,10 +442,10 @@ EOF sudo cp files/dhcp/rfc3442-classless-routes $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d sudo cp files/dhcp/sethostname $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ +sudo cp files/dhcp/sethostname6 $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/graphserviceurl $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/snmpcommunity $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/vrf $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ -sudo cp files/dhcp/dhclient.conf $FILESYSTEM_ROOT/etc/dhcp/ if [ -f files/image_config/ntp/ntp ]; then sudo cp ./files/image_config/ntp/ntp $FILESYSTEM_ROOT/etc/init.d/ fi diff --git a/build_debug_docker_j2.sh b/build_debug_docker_j2.sh index 3655ac037bd6..0b167cf0f39e 100755 --- a/build_debug_docker_j2.sh +++ b/build_debug_docker_j2.sh @@ -28,7 +28,7 @@ debs/{{ deb }}{{' '}} {% if $3 is defined %} {% if $3|length %} -RUN apt-get install -f -y \ +RUN apt-get update && apt-get install -f -y \ {% for dbg in $3.split(' ') -%} {{ dbg }}{{' '}} {%- endfor %} diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py index 07e0649579ac..be1dbb52a79b 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py @@ -1111,7 +1111,7 @@ def get_presence(self): presence = int(sfp_presence.read(), 16) except IOError: return False - logger.log_info("debug:port_ %s sfp presence is %s" % (str(self.index)), % (str(presence)) + logger.log_info("debug:port_ %s sfp presence is %s" % (str(self.index), str(presence))) return presence def get_model(self): diff --git a/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/AS14-128H/port_config.ini b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/AS14-128H/port_config.ini new file mode 100644 index 000000000000..224418d2c15a --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/AS14-128H/port_config.ini @@ -0,0 +1,129 @@ +# name lanes alias index +Ethernet1 9,10 QSFP1 1 +Ethernet2 11,12 QSFP2 2 +Ethernet3 15,16 QSFP3 3 +Ethernet4 13,14 QSFP4 4 +Ethernet5 77,78 QSFP5 5 +Ethernet6 79,80 QSFP6 6 +Ethernet7 75,76 QSFP7 7 +Ethernet8 73,74 QSFP8 8 +Ethernet9 1,2 QSFP9 9 +Ethernet10 3,4 QSFP10 10 +Ethernet11 7,8 QSFP11 11 +Ethernet12 5,6 QSFP12 12 +Ethernet13 69,70 QSFP13 13 +Ethernet14 71,72 QSFP14 14 +Ethernet15 67,68 QSFP15 15 +Ethernet16 65,66 QSFP16 16 +Ethernet17 41,42 QSFP17 17 +Ethernet18 43,44 QSFP18 18 +Ethernet19 47,48 QSFP19 19 +Ethernet20 45,46 QSFP20 20 +Ethernet21 109,110 QSFP21 21 +Ethernet22 111,112 QSFP22 22 +Ethernet23 107,108 QSFP23 23 +Ethernet24 105,106 QSFP24 24 +Ethernet25 33,34 QSFP25 25 +Ethernet26 35,36 QSFP26 26 +Ethernet27 39,40 QSFP27 27 +Ethernet28 37,38 QSFP28 28 +Ethernet29 101,102 QSFP29 29 +Ethernet30 103,104 QSFP30 30 +Ethernet31 99,100 QSFP31 31 +Ethernet32 97,98 QSFP32 32 +Ethernet33 137,138 QSFP33 33 +Ethernet34 139,140 QSFP34 34 +Ethernet35 143,144 QSFP35 35 +Ethernet36 141,142 QSFP36 36 +Ethernet37 205,206 QSFP37 37 +Ethernet38 207,208 QSFP38 38 +Ethernet39 203,204 QSFP39 39 +Ethernet40 201,202 QSFP40 40 +Ethernet41 129,130 QSFP41 41 +Ethernet42 131,132 QSFP42 42 +Ethernet43 135,136 QSFP43 43 +Ethernet44 133,134 QSFP44 44 +Ethernet45 197,198 QSFP45 45 +Ethernet46 199,200 QSFP46 46 +Ethernet47 195,196 QSFP47 47 +Ethernet48 193,194 QSFP48 48 +Ethernet49 169,170 QSFP49 49 +Ethernet50 171,172 QSFP50 50 +Ethernet51 175,176 QSFP51 51 +Ethernet52 173,174 QSFP52 52 +Ethernet53 237,238 QSFP53 53 +Ethernet54 239,240 QSFP54 54 +Ethernet55 235,236 QSFP55 55 +Ethernet56 233,234 QSFP56 56 +Ethernet57 161,162 QSFP57 57 +Ethernet58 163,164 QSFP58 58 +Ethernet59 167,168 QSFP59 59 +Ethernet60 165,166 QSFP60 60 +Ethernet61 229,230 QSFP61 61 +Ethernet62 231,232 QSFP62 62 +Ethernet63 227,228 QSFP63 63 +Ethernet64 225,226 QSFP64 64 +Ethernet65 25,26 QSFP65 65 +Ethernet66 27,28 QSFP66 66 +Ethernet67 31,32 QSFP67 67 +Ethernet68 29,30 QSFP68 68 +Ethernet69 93,94 QSFP69 69 +Ethernet70 95,96 QSFP70 70 +Ethernet71 91,92 QSFP71 71 +Ethernet72 89,90 QSFP72 72 +Ethernet73 17,18 QSFP73 73 +Ethernet74 19,20 QSFP74 74 +Ethernet75 23,24 QSFP75 75 +Ethernet76 21,22 QSFP76 76 +Ethernet77 85,86 QSFP77 77 +Ethernet78 87,88 QSFP78 78 +Ethernet79 83,84 QSFP79 79 +Ethernet80 81,82 QSFP80 80 +Ethernet81 57,58 QSFP81 81 +Ethernet82 59,60 QSFP82 82 +Ethernet83 63,64 QSFP83 83 +Ethernet84 61,62 QSFP84 84 +Ethernet85 125,126 QSFP85 85 +Ethernet86 127,128 QSFP86 86 +Ethernet87 123,124 QSFP87 87 +Ethernet88 121,122 QSFP88 88 +Ethernet89 49,50 QSFP89 89 +Ethernet90 51,52 QSFP90 90 +Ethernet91 55,56 QSFP91 91 +Ethernet92 53,54 QSFP92 92 +Ethernet93 117,118 QSFP93 93 +Ethernet94 119,120 QSFP94 94 +Ethernet95 115,116 QSFP95 95 +Ethernet96 113,114 QSFP96 96 +Ethernet97 153,154 QSFP97 97 +Ethernet98 155,156 QSFP98 98 +Ethernet99 159,160 QSFP99 99 +Ethernet100 157,158 QSFP100 100 +Ethernet101 221,222 QSFP101 101 +Ethernet102 223,224 QSFP102 102 +Ethernet103 219,220 QSFP103 103 +Ethernet104 217,218 QSFP104 104 +Ethernet105 145,146 QSFP105 105 +Ethernet106 147,148 QSFP106 106 +Ethernet107 151,152 QSFP107 107 +Ethernet108 149,150 QSFP108 108 +Ethernet109 213,214 QSFP109 109 +Ethernet110 215,216 QSFP110 110 +Ethernet111 211,212 QSFP111 111 +Ethernet112 209,210 QSFP112 112 +Ethernet113 185,186 QSFP113 113 +Ethernet114 187,188 QSFP114 114 +Ethernet115 191,192 QSFP115 115 +Ethernet116 189,190 QSFP116 116 +Ethernet117 253,254 QSFP117 117 +Ethernet118 255,256 QSFP118 118 +Ethernet119 251,252 QSFP119 119 +Ethernet120 249,250 QSFP120 120 +Ethernet121 177,178 QSFP121 121 +Ethernet122 179,180 QSFP122 122 +Ethernet123 183,184 QSFP123 123 +Ethernet124 181,182 QSFP124 124 +Ethernet125 245,246 QSFP125 125 +Ethernet126 247,248 QSFP126 126 +Ethernet127 243,244 QSFP127 127 +Ethernet128 241,242 QSFP128 128 diff --git a/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/AS14-128H/sai.profile b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/AS14-128H/sai.profile new file mode 100644 index 000000000000..f2db109d7afc --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/AS14-128H/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/platform/th3-as14-128h.config.bcm diff --git a/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/custom_led.bin b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/custom_led.bin new file mode 100644 index 000000000000..a7f256cadee8 Binary files /dev/null and b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/custom_led.bin differ diff --git a/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/default_sku b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/default_sku new file mode 100644 index 000000000000..30e5af958eb9 --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/default_sku @@ -0,0 +1 @@ +AS23-128H t1 \ No newline at end of file diff --git a/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/installer.conf b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/installer.conf new file mode 100644 index 000000000000..dc3cf67d19e7 --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/installer.conf @@ -0,0 +1,2 @@ +CONSOLE_SPEED=9600 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="processor.max_cstate=1 intel_idle.max_cstate=0" diff --git a/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/led_proc_init.soc b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/led_proc_init.soc new file mode 100644 index 000000000000..28cd4b9bc9f7 --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/led_proc_init.soc @@ -0,0 +1,9 @@ +#Enable all ports +#port all en=1 +#sleep 6 +#linkscan 250000; port xe,ce linkscan=on + +#Load LED +#led auto on; led start + + diff --git a/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/linkscan_led_fw.bin b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/linkscan_led_fw.bin new file mode 100644 index 000000000000..c2fa94a2d8cb Binary files /dev/null and b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/linkscan_led_fw.bin differ diff --git a/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/minigraph.xml b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/minigraph.xml new file mode 100644 index 000000000000..500be59307a0 --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/minigraph.xml @@ -0,0 +1,1333 @@ + + + + + + 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 + + + + + + QSFP1 + 10.0.0.0/31 + + + + QSFP2 + 10.0.0.2/31 + + + + QSFP3 + 10.0.0.4/31 + + + + QSFP4 + 10.0.0.6/31 + + + + QSFP5 + 10.0.0.8/31 + + + + QSFP6 + 10.0.0.10/31 + + + + QSFP7 + 10.0.0.12/31 + + + + QSFP8 + 10.0.0.14/31 + + + + QSFP9 + 10.0.0.16/31 + + + + QSFP10 + 10.0.0.18/31 + + + + QSFP11 + 10.0.0.20/31 + + + + QSFP12 + 10.0.0.22/31 + + + + QSFP13 + 10.0.0.24/31 + + + + QSFP14 + 10.0.0.26/31 + + + + QSFP15 + 10.0.0.28/31 + + + + QSFP16 + 10.0.0.30/31 + + + + QSFP17 + 10.0.0.32/31 + + + + QSFP18 + 10.0.0.34/31 + + + + QSFP19 + 10.0.0.36/31 + + + + QSFP20 + 10.0.0.38/31 + + + + QSFP21 + 10.0.0.40/31 + + + + QSFP22 + 10.0.0.42/31 + + + + QSFP23 + 10.0.0.44/31 + + + + QSFP24 + 10.0.0.46/31 + + + + QSFP25 + 10.0.0.48/31 + + + + QSFP26 + 10.0.0.50/31 + + + + QSFP27 + 10.0.0.52/31 + + + + QSFP28 + 10.0.0.54/31 + + + + QSFP29 + 10.0.0.56/31 + + + + QSFP30 + 10.0.0.58/31 + + + + QSFP31 + 10.0.0.60/31 + + + + QSFP32 + 10.0.0.62/31 + + + + QSFP33 + 10.0.0.64/31 + + + + QSFP34 + 10.0.0.66/31 + + + + QSFP35 + 10.0.0.68/31 + + + + QSFP36 + 10.0.0.70/31 + + + + QSFP37 + 10.0.0.72/31 + + + + QSFP38 + 10.0.0.74/31 + + + + QSFP39 + 10.0.0.76/31 + + + + QSFP40 + 10.0.0.78/31 + + + + QSFP41 + 10.0.0.80/31 + + + + QSFP42 + 10.0.0.82/31 + + + + QSFP43 + 10.0.0.84/31 + + + + QSFP44 + 10.0.0.86/31 + + + + QSFP45 + 10.0.0.88/31 + + + + QSFP46 + 10.0.0.90/31 + + + + QSFP47 + 10.0.0.92/31 + + + + QSFP48 + 10.0.0.94/31 + + + + QSFP49 + 10.0.0.96/31 + + + + QSFP50 + 10.0.0.98/31 + + + + QSFP51 + 10.0.0.100/31 + + + + QSFP52 + 10.0.0.102/31 + + + + QSFP53 + 10.0.0.104/31 + + + + QSFP54 + 10.0.0.106/31 + + + + QSFP55 + 10.0.0.108/31 + + + + QSFP56 + 10.0.0.110/31 + + + + QSFP57 + 10.0.0.112/31 + + + + QSFP58 + 10.0.0.114/31 + + + + QSFP59 + 10.0.0.116/31 + + + + QSFP60 + 10.0.0.118/31 + + + + QSFP61 + 10.0.0.120/31 + + + + QSFP62 + 10.0.0.122/31 + + + + QSFP63 + 10.0.0.124/31 + + + + QSFP64 + 10.0.0.126/31 + + + + QSFP65 + 10.0.1.0/31 + + + + QSFP66 + 10.0.1.2/31 + + + + QSFP67 + 10.0.1.4/31 + + + + QSFP68 + 10.0.1.6/31 + + + + QSFP69 + 10.0.1.8/31 + + + + QSFP70 + 10.0.1.10/31 + + + + QSFP71 + 10.0.1.12/31 + + + + QSFP72 + 10.0.1.14/31 + + + + QSFP73 + 10.0.1.16/31 + + + + QSFP74 + 10.0.1.18/31 + + + + QSFP75 + 10.0.1.20/31 + + + + QSFP76 + 10.0.1.22/31 + + + + QSFP77 + 10.0.1.24/31 + + + + QSFP78 + 10.0.1.26/31 + + + + QSFP79 + 10.0.1.28/31 + + + + QSFP80 + 10.0.1.30/31 + + + + QSFP81 + 10.0.1.32/31 + + + + QSFP82 + 10.0.1.34/31 + + + + QSFP83 + 10.0.1.36/31 + + + + QSFP84 + 10.0.1.38/31 + + + + QSFP85 + 10.0.1.40/31 + + + + QSFP86 + 10.0.1.42/31 + + + + QSFP87 + 10.0.1.44/31 + + + + QSFP88 + 10.0.1.46/31 + + + + QSFP89 + 10.0.1.48/31 + + + + QSFP90 + 10.0.1.50/31 + + + + QSFP91 + 10.0.1.52/31 + + + + QSFP92 + 10.0.1.54/31 + + + + QSFP93 + 10.0.1.56/31 + + + + QSFP94 + 10.0.1.58/31 + + + + QSFP95 + 10.0.1.60/31 + + + + QSFP96 + 10.0.1.62/31 + + + + QSFP97 + 10.0.1.64/31 + + + + QSFP98 + 10.0.1.66/31 + + + + QSFP99 + 10.0.1.68/31 + + + + QSFP100 + 10.0.1.70/31 + + + + QSFP101 + 10.0.1.72/31 + + + + QSFP102 + 10.0.1.74/31 + + + + QSFP103 + 10.0.1.76/31 + + + + QSFP104 + 10.0.1.78/31 + + + + QSFP105 + 10.0.1.80/31 + + + + QSFP106 + 10.0.1.82/31 + + + + QSFP107 + 10.0.1.84/31 + + + + QSFP108 + 10.0.1.86/31 + + + + QSFP109 + 10.0.1.88/31 + + + + QSFP110 + 10.0.1.90/31 + + + + QSFP111 + 10.0.1.92/31 + + + + QSFP112 + 10.0.1.94/31 + + + + QSFP113 + 10.0.1.96/31 + + + + QSFP114 + 10.0.1.98/31 + + + + QSFP115 + 10.0.1.100/31 + + + + QSFP116 + 10.0.1.102/31 + + + + QSFP117 + 10.0.1.104/31 + + + + QSFP118 + 10.0.1.106/31 + + + + QSFP119 + 10.0.1.108/31 + + + + QSFP120 + 10.0.1.110/31 + + + + QSFP121 + 10.0.1.112/31 + + + + QSFP122 + 10.0.1.114/31 + + + + QSFP123 + 10.0.1.116/31 + + + + QSFP124 + 10.0.1.118/31 + + + + QSFP125 + 10.0.1.120/31 + + + + QSFP126 + 10.0.1.122/31 + + + + QSFP127 + 10.0.1.124/31 + + + + QSFP128 + 10.0.1.126/31 + + + + + + + + + + + + sonic + AS14-128H + + + + + + + sonic + + + DhcpResources + + + + + NtpResources + + 0.debian.pool.ntp.org;1.debian.pool.ntp.org;2.debian.pool.ntp.org;3.debian.pool.ntp.org + + + SyslogResources + + + + + ErspanDestinationIpv4 + + 2.2.2.2 + + + + + + + sonic + AS14-128H +
diff --git a/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/opennsl-postinit.cfg b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/opennsl-postinit.cfg new file mode 100644 index 000000000000..7008c14c0ffc --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/opennsl-postinit.cfg @@ -0,0 +1,3 @@ +linkscan 250000; port xe,ce linkscan=on +sleep 1 +led auto on; led start diff --git a/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/cputemputil.py b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/cputemputil.py new file mode 100644 index 000000000000..ac2589d044fd --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/cputemputil.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python + +# +# cputemputil.py +# +# Platform-specific CPU temperature Interface for SONiC +# + +__author__ = 'Wirut G.' +__license__ = "GPL" +__version__ = "0.1.0" +__status__ = "Development" + + +import subprocess +import requests + + +class CpuTempUtil(): + """Platform-specific CpuTempUtil class""" + + def __init__(self): + pass + + def get_cpu_temp(self): + + # Get list of temperature of CPU cores. + p = subprocess.Popen(['sensors', '-Au', 'coretemp-isa-0000'], + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = p.communicate() + raw_data_list = out.splitlines() + temp_string_list = [i for i, s in enumerate( + raw_data_list) if '_input' in s] + tmp_list = [0] + + for temp_string in temp_string_list: + tmp_list.append(float(raw_data_list[temp_string].split(":")[1])) + + return tmp_list + + def get_max_cpu_tmp(self): + # Get maximum temperature from list of temperature of CPU cores. + return max(self.get_cpu_temp()) diff --git a/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/eeprom.py b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/eeprom.py new file mode 100644 index 000000000000..46559439061d --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/eeprom.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica PHALANX +# +# 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/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/fanutil.py b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/fanutil.py new file mode 100644 index 000000000000..7c37088b927e --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/fanutil.py @@ -0,0 +1,309 @@ +#!/usr/bin/env python + +__author__ = 'Wirut G.' +__license__ = "GPL" +__version__ = "0.1.2" +__status__ = "Development" + +import requests +import re + + +class FanUtil(): + """Platform-specific FanUtil class""" + + def __init__(self): + + self.fan_fru_url = "http://240.1.1.1:8080/api/sys/fruid/fan" + self.sensor_url = "http://240.1.1.1:8080/api/sys/sensors" + self.fru_data_list = None + self.sensor_data_list = None + + def request_data(self): + # Reqest data from BMC if not exist. + if self.fru_data_list is None or self.sensor_data_list is None: + fru_data_req = requests.get(self.fan_fru_url) + sensor_data_req = requests.get(self.sensor_url) + fru_json = fru_data_req.json() + sensor_json = sensor_data_req.json() + self.fru_data_list = fru_json.get('Information') + self.sensor_data_list = sensor_json.get('Information') + return self.fru_data_list, self.sensor_data_list + + def name_to_index(self, fan_name): + # Get fan index from fan name + match = re.match(r"(FAN)([0-9]+)-(1|2)", fan_name, re.I) + fan_index = None + if match: + i_list = list(match.groups()) + fan_index = int(i_list[1])*2 - (int(i_list[2]) % 2) + return fan_index + + def get_num_fans(self): + """ + Get the number of fans + :return: int num_fans + """ + num_fans = 10 + + return num_fans + + def get_fan_speed(self, fan_name): + """ + Get the current speed of the fan, the unit is "RPM" + :return: int fan_speed + """ + + try: + # Get real fan index + index = self.name_to_index(fan_name) + + # Set key and index. + fan_speed = 0 + position_key = "Front" if index % 2 != 0 else "Rear" + index = int(round(float(index)/2)) + fan_key = "Fan " + str(index) + " " + position_key + + # Request and validate fan information. + self.fru_data_list, self.sensor_data_list = self.request_data() + + # Get fan's speed. + for sensor_data in self.sensor_data_list: + sensor_name = sensor_data.get('name') + if "fan" in str(sensor_name): + fan_data = sensor_data.get(fan_key) + fan_sp_list = map(int, re.findall(r'\d+', fan_data)) + fan_speed = fan_sp_list[0] + + except: + return 0 + + return fan_speed + + def get_fan_low_threshold(self, fan_name): + """ + Get the low speed threshold of the fan. + if the current speed < low speed threshold, + the status of the fan is not ok. + :return: int fan_low_threshold + """ + + try: + # Get real fan index + index = self.name_to_index(fan_name) + + # Set key and index. + fan_low_threshold = 0 + position_key = "Front" if index % 2 != 0 else "Rear" + index = int(round(float(index)/2)) + fan_key = "Fan " + str(index) + " " + position_key + + # Request and validate fan information. + self.fru_data_list, self.sensor_data_list = self.request_data() + + # Get fan's threshold. + for sensor_data in self.sensor_data_list: + sensor_name = sensor_data.get('name') + if "fan" in str(sensor_name): + fan_data = sensor_data.get(fan_key) + fan_sp_list = map(int, re.findall(r'\d+', fan_data)) + fan_low_threshold = fan_sp_list[1] + + except: + return "N/A" + + return fan_low_threshold + + def get_fan_high_threshold(self, fan_name): + """ + Get the hight speed threshold of the fan, + if the current speed > high speed threshold, + the status of the fan is not ok + :return: int fan_high_threshold + """ + + try: + # Get real fan index + index = self.name_to_index(fan_name) + + # Set key and index. + fan_high_threshold = 0 + position_key = "Front" if index % 2 != 0 else "Rear" + index = int(round(float(index)/2)) + fan_key = "Fan " + str(index) + " " + position_key + + # Request and validate fan information. + self.fru_data_list, self.sensor_data_list = self.request_data() + + # Get fan's threshold. + for sensor_data in self.sensor_data_list: + sensor_name = sensor_data.get('name') + if "fan" in str(sensor_name): + fan_data = sensor_data.get(fan_key) + fan_sp_list = map(int, re.findall(r'\d+', fan_data)) + fan_high_threshold = fan_sp_list[2] + + except: + return 0 + + return fan_high_threshold + + def get_fan_pn(self, fan_name): + """ + Get the product name of the fan + :return: str fan_pn + """ + + try: + # Get real fan index + index = self.name_to_index(fan_name) + + # Set key and index. + fan_pn = "N/A" + index = int(round(float(index)/2)) + fan_fru_key = "Fantray" + str(index) + + # Request and validate fan information. + self.fru_data_list, self.sensor_data_list = self.request_data() + + # Get fan's fru. + for fan_fru in self.fru_data_list: + matching_fan = [s for s in fan_fru if fan_fru_key in s] + if matching_fan: + pn = [s for s in fan_fru if "Part" in s] + fan_pn = pn[0].split()[4] + + except: + return "N/A" + + return fan_pn + + def get_fan_sn(self, fan_name): + """ + Get the serial number of the fan + :return: str fan_sn + """ + try: + # Get real fan index + index = self.name_to_index(fan_name) + + # Set key and index. + fan_sn = "N/A" + index = int(round(float(index)/2)) + fan_fru_key = "Fantray" + str(index) + + # Request and validate fan information. + self.fru_data_list, self.sensor_data_list = self.request_data() + + # Get fan's fru. + for fan_fru in self.fru_data_list: + matching_fan = [s for s in fan_fru if fan_fru_key in s] + if matching_fan: + serial = [s for s in fan_fru if "Serial" in s] + fan_sn = serial[0].split()[3] + + except: + return "N/A" + + return fan_sn + + def get_fans_name_list(self): + """ + Get list of fan name. + :return: list fan_names + """ + fan_names = [] + + # Get the number of fans + n_fan = self.get_num_fans() + + # Set fan name and add to the list. + for x in range(1, n_fan + 1): + f_index = int(round(float(x)/2)) + pos = 1 if x % 2 else 2 + fan_name = 'FAN{}_{}'.format(f_index, pos) + fan_names.append(fan_name) + + return fan_names + + def get_all(self): + """ + Get all information of system FANs, returns JSON objects in python 'DICT'. + Number, mandatory, max number of FAN, integer + FAN1_1, FAN1_2, ... mandatory, FAN name, string + Present, mandatory for each FAN, present status, boolean, True for present, False for NOT present, read directly from h/w + Running, conditional, if PRESENT is True, running status of the FAN, True for running, False for stopped, read directly from h/w + Speed, conditional, if PRESENT is True, real FAN speed, float, read directly from h/w + LowThd, conditional, if PRESENT is True, lower bound of FAN speed, float, read from h/w + HighThd, conditional, if PRESENT is True, upper bound of FAN speed, float, read from h/w + PN, conditional, if PRESENT is True, PN of the FAN, string + SN, conditional, if PRESENT is True, SN of the FAN, string) + """ + + self.fru_data_list, self.sensor_data_list = self.request_data() + all_fan_dict = dict() + + # Get the number of fans + n_fan = self.get_num_fans() + all_fan_dict["Number"] = n_fan + + # Set fan FRU data. + fan_fru_dict = dict() + fan_raw_idx = 1 + for fan_fru in self.fru_data_list: + fru_dict = dict() + fan_ps = False + + if len(fan_fru) == 0: + fan_idx = fan_raw_idx + fan_pn = "N/A" + fan_sn = "N/A" + else: + fan_key = fan_fru[0].split() + if str(fan_key[-1]).lower() == "absent": + fan_idx = int(re.findall('\d+', fan_key[0])[0]) + + else: + fan_idx = int(re.findall('\d+', fan_key[-1])[0]) + fan_ps = True + pn = [s for s in fan_fru if "Part" in s] + sn = [s for s in fan_fru if "Serial" in s] + fan_pn = pn[0].split( + ":")[-1].strip() if len(pn) > 0 else 'N/A' + fan_sn = sn[0].split( + ":")[-1].strip() if len(sn) > 0 else 'N/A' + + fru_dict["PN"] = "N/A" if not fan_pn or fan_pn == "" else fan_pn + fru_dict["SN"] = "N/A" if not fan_sn or fan_sn == "" else fan_sn + fru_dict["Present"] = fan_ps + fan_fru_dict[fan_idx] = fru_dict + fan_raw_idx += 1 + + # Set fan sensor data. + for sensor_data in self.sensor_data_list: + sensor_name = sensor_data.get('name') + if "fan" in str(sensor_name): + for x in range(1, n_fan + 1): + fan_dict = dict() + f_index = int(round(float(x)/2)) + pos = 1 if x % 2 else 2 + position_key = "Front" if x % 2 != 0 else "Rear" + fan_key = "Fan " + str(f_index) + " " + position_key + fan_data = sensor_data.get(fan_key) + fan_sp_list = map(int, re.findall(r'\d+', fan_data)) + fan_dict["Present"] = fan_fru_dict[f_index]["Present"] + if fan_dict["Present"] or fan_sp_list[0] > 0: + fan_dict["Present"] = True + fan_dict["Speed"] = fan_sp_list[0] + fan_dict["Running"] = True if fan_dict["Speed"] > 0 else False + fan_dict["LowThd"] = fan_sp_list[1] + fan_dict["HighThd"] = fan_sp_list[2] + fan_dict["PN"] = fan_fru_dict[f_index]["PN"] + fan_dict["SN"] = fan_fru_dict[f_index]["SN"] + fan_dict["AirFlow"] = "FTOB" if "R1240-G0009" in fan_dict["PN"] else "Unknown" + fan_dict["Status"] = True if fan_dict["AirFlow"] != "Unknown" else False + fan_name = 'FAN{}_{}'.format(f_index, pos) + all_fan_dict[fan_name] = fan_dict + break + + return all_fan_dict diff --git a/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/fwmgrutil.py b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/fwmgrutil.py new file mode 100644 index 000000000000..619aa7b173f3 --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/fwmgrutil.py @@ -0,0 +1,882 @@ +# fwmgrutil.py +# +# Platform-specific firmware management interface for SONiC +# + +import subprocess +import requests +import os +import pexpect +import base64 +import time +import json +import logging +import ast +from datetime import datetime + +try: + from sonic_fwmgr.fwgmr_base import FwMgrUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +class FwMgrUtil(FwMgrUtilBase): + + """Platform-specific FwMgrUtil class""" + + def __init__(self): + self.platform_name = "AS23128h" + self.onie_config_file = "/host/machine.conf" + self.bmc_info_url = "http://240.1.1.1:8080/api/sys/bmc" + self.bmc_raw_command_url = "http://240.1.1.1:8080/api/sys/raw" + self.fw_upgrade_url = "http://240.1.1.1:8080/api/sys/upgrade" + self.onie_config_file = "/host/machine.conf" + self.fw_upgrade_logger_path = "/var/log/fw_upgrade.log" + self.cpldb_version_path = "/sys/devices/platform/%s.cpldb/getreg" % self.platform_name + self.fpga_version_path = "/sys/devices/platform/%s.switchboard/FPGA/getreg" % self.platform_name + self.switchboard_cpld1_path = "/sys/devices/platform/%s.switchboard/CPLD1/getreg" % self.platform_name + self.switchboard_cpld2_path = "/sys/devices/platform/%s.switchboard/CPLD2/getreg" % self.platform_name + self.switchboard_cpld3_path = "/sys/devices/platform/%s.switchboard/CPLD3/getreg" % self.platform_name + self.switchboard_cpld4_path = "/sys/devices/platform/%s.switchboard/CPLD4/getreg" % self.platform_name + self.bmc_pwd_path = "/usr/local/etc/bmcpwd" + + def __get_register_value(self, path, register): + cmd = "echo {1} > {0}; cat {0}".format(path, register) + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err is not '': + return 'None' + else: + return raw_data.strip() + + def __update_fw_upgrade_logger(self, header, message): + if not os.path.isfile(self.fw_upgrade_logger_path): + cmd = "sudo touch %s && sudo chmod +x %s" % ( + self.fw_upgrade_logger_path, self.fw_upgrade_logger_path) + subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + logging.basicConfig(filename=self.fw_upgrade_logger_path, + filemode='a', + format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s', + datefmt='%b %d %H:%M:%S', + level=logging.INFO) + + log_message = "%s : %s" % (header, message) + if header != "last_upgrade_result": + print(log_message) + return logging.info(log_message) + + def get_bmc_pass(self): + if os.path.exists(self.bmc_pwd_path): + with open(self.bmc_pwd_path) as file: + data = file.read() + + key = "bmc" + dec = [] + enc = base64.urlsafe_b64decode(data) + for i in range(len(enc)): + key_c = key[i % len(key)] + dec_c = chr((256 + ord(enc[i]) - ord(key_c)) % 256) + dec.append(dec_c) + return "".join(dec) + return False + + def get_bmc_version(self): + """Get BMC version from SONiC + :returns: version string + + """ + bmc_version = None + + bmc_version_key = "OpenBMC Version" + bmc_info_req = requests.get(self.bmc_info_url, timeout=60) + if bmc_info_req.status_code == 200: + bmc_info_json = bmc_info_req.json() + bmc_info = bmc_info_json.get('Information') + bmc_version = bmc_info.get(bmc_version_key) + return str(bmc_version) + + def upload_file_bmc(self, fw_path): + scp_command = 'sudo scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -r %s root@240.1.1.1:/home/root/' % os.path.abspath( + fw_path) + child = pexpect.spawn(scp_command) + i = child.expect(["root@240.1.1.1's password:"], timeout=30) + bmc_pwd = self.get_bmc_pass() + if i == 0 and bmc_pwd: + child.sendline(bmc_pwd) + data = child.read() + print(data) + child.close + return os.path.isfile(fw_path) + return False + + def get_cpld_version(self): + """Get CPLD version from SONiC + :returns: dict like {'CPLD_1': version_string, 'CPLD_2': version_string} + """ + + CPLD_B = self.__get_register_value(self.cpldb_version_path, '0xA100') + CPLD_C = self.__get_register_value(self.cpldb_version_path, '0xA1E0') + CPLD_1 = self.__get_register_value(self.switchboard_cpld1_path, '0x00') + CPLD_2 = self.__get_register_value(self.switchboard_cpld2_path, '0x00') + CPLD_3 = self.__get_register_value(self.switchboard_cpld3_path, '0x00') + CPLD_4 = self.__get_register_value(self.switchboard_cpld4_path, '0x00') + + fan_cpld_key = "FanCPLD Version" + fan_cpld = None + bmc_info_req = requests.get(self.bmc_info_url) + if bmc_info_req.status_code == 200: + bmc_info_json = bmc_info_req.json() + bmc_info = bmc_info_json.get('Information') + fan_cpld = bmc_info.get(fan_cpld_key) + + CPLD_B = 'None' if CPLD_B is 'None' else "{}.{}".format( + int(CPLD_B[2], 16), int(CPLD_B[3], 16)) + CPLD_C = 'None' if CPLD_C is 'None' else "{}.{}".format( + int(CPLD_C[2], 16), int(CPLD_C[3], 16)) + CPLD_1 = 'None' if CPLD_1 is 'None' else "{}.{}".format( + int(CPLD_1[2], 16), int(CPLD_1[3], 16)) + CPLD_2 = 'None' if CPLD_2 is 'None' else "{}.{}".format( + int(CPLD_2[2], 16), int(CPLD_2[3], 16)) + CPLD_3 = 'None' if CPLD_3 is 'None' else "{}.{}".format( + int(CPLD_3[2], 16), int(CPLD_3[3], 16)) + CPLD_4 = 'None' if CPLD_4 is 'None' else "{}.{}".format( + int(CPLD_4[2], 16), int(CPLD_4[3], 16)) + FAN_CPLD = 'None' if fan_cpld is None else "{}.{}".format( + int(fan_cpld[0], 16), int(fan_cpld[1], 16)) + + cpld_version_dict = {} + cpld_version_dict.update({'CPLD_B': CPLD_B}) + cpld_version_dict.update({'CPLD_C': CPLD_C}) + cpld_version_dict.update({'CPLD_1': CPLD_1}) + cpld_version_dict.update({'CPLD_2': CPLD_2}) + cpld_version_dict.update({'CPLD_3': CPLD_3}) + cpld_version_dict.update({'CPLD_4': CPLD_4}) + cpld_version_dict.update({'CPLD_FAN': FAN_CPLD}) + + return cpld_version_dict + + def get_bios_version(self): + """Get BIOS version from SONiC + :returns: version string + + """ + bios_version = None + + p = subprocess.Popen( + ["sudo", "dmidecode", "-s", "bios-version"], stdout=subprocess.PIPE) + raw_data = str(p.communicate()[0]) + if raw_data == '': + return str(None) + raw_data_list = raw_data.split("\n") + bios_version = raw_data_list[0] if len( + raw_data_list) == 1 else raw_data_list[-2] + + return str(bios_version) + + def get_onie_version(self): + """Get ONiE version from SONiC + :returns: version string + + """ + onie_verison = None + + onie_version_keys = "onie_version" + onie_config_file = open(self.onie_config_file, "r") + for line in onie_config_file.readlines(): + if onie_version_keys in line: + onie_version_raw = line.split('=') + onie_verison = onie_version_raw[1].strip() + break + onie_config_file.close() + return str(onie_verison) + + def get_pcie_version(self): + """Get PCiE version from SONiC + :returns: version dict { "PCIE_FW_LOADER": "2.5", "PCIE_FW": "D102_08" } + + """ + cmd = "sudo bcmcmd 'pciephy fw version'" + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + + pcie_version = dict() + pcie_version["PCIE_FW_LOADER"] = 'None' + pcie_version["PCIE_FW"] = 'None' + + if err == '': + lines = raw_data.split('\n') + for line in lines: + if 'PCIe FW loader' in line: + pcie_version["PCIE_FW_LOADER"] = line.split(':')[1].strip() + elif 'PCIe FW version' in line: + pcie_version["PCIE_FW"] = line.split(':')[1].strip() + return pcie_version + + def get_fpga_version(self): + """Get FPGA version from SONiC + :returns: version string + + """ + version = self.__get_register_value(self.fpga_version_path, '0x00') + if version is not 'None': + version = "{}.{}".format( + int(version[2:][:4], 16), int(version[2:][4:], 16)) + return str(version) + + def firmware_upgrade(self, fw_type, fw_path, fw_extra=None): + """ + @fw_type MANDATORY, firmware type, should be one of the strings: 'cpld', 'fpga', 'bios', 'bmc' + @fw_path MANDATORY, target firmware file + @fw_extra OPTIONAL, extra information string, + + for fw_type 'cpld' and 'fpga': it can be used to indicate specific cpld, such as 'cpld1', 'cpld2', ... + or 'cpld_fan_come_board', etc. If None, upgrade all CPLD/FPGA firmware. for fw_type 'bios' and 'bmc', + value should be one of 'master' or 'slave' or 'both' + """ + fw_type = fw_type.lower() + bmc_pwd = self.get_bmc_pass() + if not bmc_pwd and fw_type != "fpga": + self.__update_fw_upgrade_logger( + "fw_upgrade", "fail, message=BMC credential not found") + return False + + if fw_type == 'bmc': + self.__update_fw_upgrade_logger( + "bmc_upgrade", "start BMC upgrade") + # Copy BMC image file to BMC + fw_extra_str = str(fw_extra).lower() + last_fw_upgrade = ["BMC", fw_path, fw_extra_str, "FAILED"] + upload_file = self.upload_file_bmc(fw_path) + if not upload_file: + self.__update_fw_upgrade_logger( + "fw_upgrade", "fail, message=unable to upload BMC image to BMC") + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return False + + filename_w_ext = os.path.basename(fw_path) + json_data = dict() + json_data["path"] = "root@127.0.0.1:/home/root/%s" % filename_w_ext + json_data["password"] = bmc_pwd + + # Set flash type + current_bmc = self.get_running_bmc() + flash = fw_extra_str if fw_extra_str in [ + "master", "slave", "both"] else "both" + if fw_extra_str == "pingpong": + #flash = "master" if current_bmc == "slave" else "slave" + flash = "slave" + json_data["flash"] = flash + + # Install BMC + if flash == "both": + self.__update_fw_upgrade_logger( + "bmc_upgrade", "install BMC as master mode") + json_data["flash"] = "master" + r = requests.post(self.bmc_info_url, json=json_data) + if r.status_code != 200 or 'success' not in r.json().get('result'): + self.__update_fw_upgrade_logger( + "bmc_upgrade", "fail, message=BMC API report error code %d" % r.status_code) + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return False + json_data["flash"] = "slave" + + self.__update_fw_upgrade_logger( + "bmc_upgrade", "install BMC as %s mode" % json_data["flash"]) + r = requests.post(self.bmc_info_url, json=json_data) + if r.status_code == 200 and 'success' in r.json().get('result'): + if fw_extra_str == "pingpong": + flash = "master" if current_bmc == "slave" else "slave" + self.__update_fw_upgrade_logger( + "bmc_upgrade", "switch to boot from %s" % flash) + self.set_bmc_boot_flash(flash) + self.__update_fw_upgrade_logger( + "bmc_upgrade", "reboot BMC") + if not self.reboot_bmc(): + return False + else: + self.__update_fw_upgrade_logger( + "bmc_upgrade", "reboot BMC") + reboot_dict = {} + reboot_dict["reboot"] = "yes" + r = requests.post(self.bmc_info_url, json=reboot_dict) + last_fw_upgrade[3] = "DONE" + else: + self.__update_fw_upgrade_logger( + "bmc_upgrade", "fail, message=unable to install BMC image") + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return False + + self.__update_fw_upgrade_logger( + "bmc_upgrade", "done") + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return True + + elif fw_type == 'fpga': + last_fw_upgrade = ["FPGA", fw_path, None, "FAILED"] + self.__update_fw_upgrade_logger( + "fpga_upgrade", "start FPGA upgrade") + + if not os.path.isfile(fw_path): + self.__update_fw_upgrade_logger( + "fpga_upgrade", "fail, message=FPGA image not found %s" % fw_path) + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return False + + command = 'fpga_prog ' + fw_path + print("Running command : %s" % command) + process = subprocess.Popen( + command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + while True: + output = process.stdout.readline() + if output == '' and process.poll() is not None: + break + + rc = process.returncode + if rc != 0: + self.__update_fw_upgrade_logger( + "fw_upgrade", "fail, message=unable to install FPGA") + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return False + + self.__update_fw_upgrade_logger("fpga_upgrade", "done") + last_fw_upgrade[3] = "DONE" + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + self.firmware_refresh(["FPGA"], None, None) + return True + + elif 'cpld' in fw_type: + self.__update_fw_upgrade_logger( + "cpld_upgrade", "start CPLD upgrade") + # Check input + fw_extra_str = str(fw_extra).upper() + if ":" in fw_path and ":" in fw_extra_str: + fw_path_list = fw_path.split(":") + fw_extra_str_list = fw_extra_str.split(":") + else: + fw_path_list = [fw_path] + fw_extra_str_list = [fw_extra_str] + + if len(fw_path_list) != len(fw_extra_str_list): + self.__update_fw_upgrade_logger( + "cpld_upgrade", "fail, message=invalid input") + return False + + data_list = list(zip(fw_path_list, fw_extra_str_list)) + refresh_img_path = None + cpld_result_list = ["FAILED" for i in range( + 0, len(fw_extra_str_list))] + last_fw_upgrade = ["CPLD", ":".join( + fw_path_list), ":".join(fw_extra_str_list), ":".join(cpld_result_list)] + for i in range(0, len(data_list)): + data = data_list[i] + fw_path = data[0] + fw_extra_str = data[1] + + # Set fw_extra + fw_extra_str = { + "TOP_LC_CPLD": "top_lc", + "BOT_LC_CPLD": "bottom_lc", + "FAN_CPLD": "fan", + "CPU_CPLD": "cpu", + "BASE_CPLD": "base", + "COMBO_CPLD": "combo", + "SW_CPLD1": "switch", + "SW_CPLD2": "switch", + "REFRESH_CPLD": "refresh" + }.get(fw_extra_str, None) + + if fw_extra_str == "refresh": + refresh_img_path = fw_path + del cpld_result_list[i] + del fw_extra_str_list[i] + continue + + if fw_extra_str is None: + self.__update_fw_upgrade_logger( + "cpld_upgrade", "fail, message=invalid extra information string") + continue + + # Uploading image to BMC + self.__update_fw_upgrade_logger( + "cpld_upgrade", "start %s upgrade" % data[1]) + upload_file = self.upload_file_bmc(fw_path) + if not upload_file: + self.__update_fw_upgrade_logger( + "cpld_upgrade", "fail, message=unable to upload BMC image to BMC") + continue + + filename_w_ext = os.path.basename(fw_path) + json_data = dict() + json_data["image_path"] = "root@127.0.0.1:/home/root/%s" % filename_w_ext + json_data["password"] = bmc_pwd + json_data["device"] = "cpld" + json_data["reboot"] = "no" + json_data["type"] = fw_extra_str + + # Call BMC api to install cpld image + print("Installing...") + r = requests.post(self.fw_upgrade_url, json=json_data) + if r.status_code != 200 or 'success' not in r.json().get('result'): + self.__update_fw_upgrade_logger( + "cpld_upgrade", "fail, message=invalid cpld image") + continue + + cpld_result_list[i] = "DONE" + self.__update_fw_upgrade_logger( + "cpld_upgrade", "%s upgrade done" % data[1]) + last_fw_upgrade[3] = ":".join(cpld_result_list) + self.__update_fw_upgrade_logger( + "cpld_upgrade", "done") + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + + # Refresh CPLD + refresh_img_str_list = [] + for fw_extra in fw_extra_str_list: + if "BASE_CPLD" in fw_extra or "FAN_CPLD" in fw_extra: + refresh_img_str_list.append(refresh_img_path) + else: + refresh_img_str_list.append("None") + self.firmware_refresh(None, fw_extra_str_list, + ":".join(refresh_img_str_list)) + + return True + + elif 'bios' in fw_type: + self.__update_fw_upgrade_logger( + "bios_upgrade", "start BIOS upgrade") + last_fw_upgrade = ["BIOS", fw_path, None, "FAILED"] + fw_extra_str = str(fw_extra).lower() + flash = fw_extra_str if fw_extra_str in [ + "master", "slave"] else "master" + + if not os.path.exists(fw_path): + self.__update_fw_upgrade_logger( + "bios_upgrade", "fail, message=image not found") + return False + + scp_command = 'sudo scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -r %s root@240.1.1.1:/home/root/' % os.path.abspath( + fw_path) + child = pexpect.spawn(scp_command) + i = child.expect(["root@240.1.1.1's password:"], timeout=30) + if i != 0: + self.__update_fw_upgrade_logger( + "bios_upgrade", "fail, message=unable to upload image to BMC") + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return False + + child.sendline(bmc_pwd) + data = child.read() + print(data) + child.close + + json_data = dict() + json_data["data"] = "/usr/bin/ipmitool -b 1 -t 0x2c raw 0x2e 0xdf 0x57 0x01 0x00 0x01" + r = requests.post(self.bmc_raw_command_url, json=json_data) + if r.status_code != 200: + self.__update_fw_upgrade_logger( + "bios_upgrade", "fail, message=unable to set state") + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return False + + filename_w_ext = os.path.basename(fw_path) + json_data = dict() + json_data["image_path"] = "root@127.0.0.1:/home/root/%s" % filename_w_ext + json_data["password"] = bmc_pwd + json_data["device"] = "bios" + json_data["flash"] = flash + json_data["reboot"] = "no" + + print("Installing...") + r = requests.post(self.fw_upgrade_url, json=json_data) + if r.status_code != 200 or 'success' not in r.json().get('result'): + self.__update_fw_upgrade_logger( + "bios_upgrade", "fail, message=unable install bios") + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return False + + last_fw_upgrade[3] = "DONE" + self.__update_fw_upgrade_logger( + "bios_upgrade", "done") + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + else: + self.__update_fw_upgrade_logger( + "fw_upgrade", "fail, message=invalid firmware type") + return False + + return True + + def get_last_upgrade_result(self): + """ + Get last firmware upgrade information, inlcudes: + 1) FwType: cpld/fpga/bios/bmc(passed by method 'firmware_upgrade'), string + 2) FwPath: path and file name of firmware(passed by method 'firmware_upgrade'), string + 3) FwExtra: designated string, econdings of this string is determined by vendor(passed by method 'firmware_program') + 4) Result: indicates whether the upgrade action is performed and success/failure status if performed. Values should be one of: "DONE"/"FAILED"/"NOT_PERFORMED". + list of object: + [ + { + "FwType": "cpld", + "FwPath": "cpu_cpld.vme" + "FwExtra":"CPU_CPLD" + "Result": "DONE" + }, + { + "FwType": "cpld", + "FwPath": "fan_cpld.vme" + "FwExtra": "FAN_CPLD" + "Result": "FAILED" + } + ] + """ + last_update_list = [] + + if os.path.exists(self.fw_upgrade_logger_path): + with open(self.fw_upgrade_logger_path, 'r') as file: + lines = file.read().splitlines() + + upgrade_txt = [i for i in reversed( + lines) if "last_upgrade_result" in i] + if len(upgrade_txt) > 0: + last_upgrade_txt = upgrade_txt[0].split( + "last_upgrade_result : ") + last_upgrade_list = ast.literal_eval(last_upgrade_txt[1]) + for x in range(0, len(last_upgrade_list[1].split(":"))): + upgrade_dict = {} + upgrade_dict["FwType"] = last_upgrade_list[0].lower() + upgrade_dict["FwPath"] = last_upgrade_list[1].split(":")[x] + upgrade_dict["FwExtra"] = last_upgrade_list[2].split(":")[ + x] if last_upgrade_list[2] else "None" + upgrade_dict["Result"] = last_upgrade_list[3].split(":")[x] + last_update_list.append(upgrade_dict) + + return last_update_list + + def firmware_program(self, fw_type, fw_path, fw_extra=None): + """ + Program FPGA and/or CPLD firmware only, but do not refresh them + + @param fw_type value can be: FPGA, CPLD + @param fw_path a string of firmware file path, seperated by ':', it should + match the sequence of param @fw_type + @param fw_extra a string of firmware subtype, i.e CPU_CPLD, BOARD_CPLD, + FAN_CPLD, LC_CPLD, etc. Subtypes are seperated by ':' + @return True when all required firmware is program succefully, + False otherwise. + + Example: + self.firmware_program("CPLD", "/cpu_cpld.vme:/lc_cpld", \ + "CPU_CPLD:LC_CPLD") + or + self.firmware_program("FPGA", "/fpga.bin") + """ + fw_type = fw_type.lower() + bmc_pwd = self.get_bmc_pass() + if not bmc_pwd and fw_type != "fpga": + self.__update_fw_upgrade_logger( + "fw_upgrade", "fail, message=BMC credential not found") + return False + + if fw_type == 'fpga': + last_fw_upgrade = ["FPGA", fw_path, None, "FAILED"] + self.__update_fw_upgrade_logger( + "fpga_upgrade", "start FPGA upgrade") + + if not os.path.isfile(fw_path): + self.__update_fw_upgrade_logger( + "fpga_upgrade", "fail, message=FPGA image not found %s" % fw_path) + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return False + + command = 'fpga_prog ' + fw_path + print("Running command: %s" % command) + process = subprocess.Popen( + command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + while True: + output = process.stdout.readline() + if output == '' and process.poll() is not None: + break + + rc = process.returncode + if rc != 0: + self.__update_fw_upgrade_logger( + "fw_upgrade", "fail, message=Unable to install FPGA") + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return False + + self.__update_fw_upgrade_logger("fpga_upgrade", "done") + last_fw_upgrade[3] = "DONE" + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return True + + elif 'cpld' in fw_type: + self.__update_fw_upgrade_logger( + "cpld_upgrade", "start CPLD upgrade") + + # Check input + fw_extra_str = str(fw_extra).upper() + if ":" in fw_path and ":" in fw_extra_str: + fw_path_list = fw_path.split(":") + fw_extra_str_list = fw_extra_str.split(":") + else: + fw_path_list = [fw_path] + fw_extra_str_list = [fw_extra_str] + + if len(fw_path_list) != len(fw_extra_str_list): + self.__update_fw_upgrade_logger( + "cpld_upgrade", "fail, message=Invalid input") + return False + + cpld_result_list = [] + data_list = list(zip(fw_path_list, fw_extra_str_list)) + for data in data_list: + fw_path = data[0] + fw_extra_str = data[1] + + # Set fw_extra + fw_extra_str = { + "TOP_LC_CPLD": "top_lc", + "BOT_LC_CPLD": "bottom_lc", + "FAN_CPLD": "fan", + "CPU_CPLD": "cpu", + "BASE_CPLD": "base", + "COMBO_CPLD": "combo", + "SW_CPLD1": "switch", + "SW_CPLD2": "switch" + }.get(fw_extra_str, None) + + self.__update_fw_upgrade_logger( + "cpld_upgrade", "start %s upgrade" % data[1]) + upgrade_result = "FAILED" + for x in range(1, 4): + # Set fw_extra + if x > 1: + self.__update_fw_upgrade_logger( + "cpld_upgrade", "fail, message=Retry to upgrade %s" % data[1]) + + elif fw_extra_str is None: + self.__update_fw_upgrade_logger( + "cpld_upgrade", "fail, message=Invalid extra information string %s" % data[1]) + break + elif not os.path.isfile(os.path.abspath(fw_path)): + self.__update_fw_upgrade_logger( + "cpld_upgrade", "fail, message=CPLD image not found %s" % fw_path) + break + + # Install cpld image via ispvm tool + print("Installing...") + command = 'ispvm %s' % fw_path + if fw_extra_str in ["top_lc", "bottom_lc"]: + option = 1 if fw_extra_str == "top_lc" else 2 + command = "ispvm -c %d %s" % (option, + os.path.abspath(fw_path)) + print("Running command : %s" % command) + process = subprocess.Popen( + command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + while True: + output = process.stdout.readline() + if output == '' and process.poll() is not None: + break + + rc = process.returncode + if rc != 0: + self.__update_fw_upgrade_logger( + "cpld_upgrade", "fail, message=Unable to install CPLD") + continue + + upgrade_result = "DONE" + self.__update_fw_upgrade_logger("cpld_upgrade", "done") + break + cpld_result_list.append(upgrade_result) + + last_fw_upgrade = ["CPLD", ":".join( + fw_path_list), ":".join(fw_extra_str_list), ":".join(cpld_result_list)] + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return "FAILED" not in cpld_result_list + else: + self.__update_fw_upgrade_logger( + "fw_upgrade", "fail, message=Invalid firmware type") + return False + + return True + + def firmware_refresh(self, fpga_list, cpld_list, fw_extra=None): + """ + Refresh firmware and take extra action when necessary. + @param fpga_list a list of FPGA names + @param cpld_list a list of CPLD names + @return True if refresh succefully and no power cycle action is taken. + + @Note extra action should be: power cycle the whole system(except BMC) when + CPU_CPLD or BOARD_CPLD or FPGA is refreshed. + No operation if the power cycle is not needed. + + Example: + self.firmware_refresh( + ["FPGA"], ["BASE_CPLD", "LC_CPLD"],"/tmp/fw/refresh.vme") + or + self.firmware_refresh(["FPGA"], None, None) + or + self.firmware_refresh(None, ["FAN_CPLD", "LC1_CPLD", "BASE_CPLD"], + "/tmp/fw/fan_refresh.vme:none:/tmp/fw/base_refresh.vme") + """ + + if not fpga_list and not cpld_list: + return False + + if type(cpld_list) is list and ("BASE_CPLD" in cpld_list or "FAN_CPLD" in cpld_list): + refresh_list = fpga_list + \ + cpld_list if type(fpga_list) is list else cpld_list + self.__update_fw_upgrade_logger( + "fw_refresh", "start %s refresh" % ",".join(refresh_list)) + fw_path_list = fw_extra.split(':') + command = "echo " + if len(fw_path_list) != len(cpld_list): + self.__update_fw_upgrade_logger( + "cpld_refresh", "fail, message=Invalid fw_extra") + return False + + for idx in range(0, len(cpld_list)): + fw_path = fw_path_list[idx] + refresh_type = { + "BASE_CPLD": "base", + "FAN_CPLD": "fan" + }.get(cpld_list[idx], None) + + if not refresh_type: + continue + elif not self.upload_file_bmc(fw_path): + self.__update_fw_upgrade_logger( + "cpld_refresh", "fail, message=Unable to upload refresh image to BMC") + return False + else: + filename_w_ext = os.path.basename(fw_path) + + sub_command = "%s /home/root/%s > /tmp/cpld_refresh " % ( + refresh_type, filename_w_ext) + command += sub_command + + json_data = dict() + json_data["data"] = command + r = requests.post(self.bmc_raw_command_url, json=json_data) + if r.status_code != 200: + self.__update_fw_upgrade_logger( + "cpld_refresh", "fail, message=%d Invalid refresh image" % r.status_code) + return False + elif type(cpld_list) is list: + refresh_list = fpga_list + \ + cpld_list if type(fpga_list) is list else cpld_list + self.__update_fw_upgrade_logger( + "fw_refresh", "start %s refresh" % ",".join(refresh_list)) + json_data = dict() + json_data["data"] = "echo cpu_cpld > /tmp/cpld_refresh" + r = requests.post(self.bmc_raw_command_url, json=json_data) + if r.status_code != 200: + self.__update_fw_upgrade_logger( + "cpld_refresh", "fail, message=%d Unable to load new CPLD" % r.status_code) + return False + elif type(fpga_list) is list: + self.__update_fw_upgrade_logger( + "fw_refresh", "start FPGA refresh") + json_data = dict() + json_data["data"] = "echo fpga > /tmp/cpld_refresh" + r = requests.post(self.bmc_raw_command_url, json=json_data) + if r.status_code != 200: + self.__update_fw_upgrade_logger( + "cpld_refresh", "fail, message=%d Unable to load new FPGA" % r.status_code) + return False + else: + self.__update_fw_upgrade_logger( + "fw_refresh", "fail, message=Invalid input") + return False + + self.__update_fw_upgrade_logger("fw_refresh", "done") + return True + + def get_running_bmc(self): + """ + Get booting flash of running BMC. + @return a string, "master" or "slave" + """ + json_data = dict() + json_data["data"] = "/usr/local/bin/boot_info.sh" + r = requests.post(self.bmc_raw_command_url, json=json_data) + try: + boot_info_list = r.json().get('result') + for boot_info_raw in boot_info_list: + boot_info = boot_info_raw.split(":") + if "Current Boot Code Source" in boot_info[0]: + flash = "master" if "master "in boot_info[1].lower( + ) else "slave" + return flash + raise Exception( + "Error: Unable to detect booting flash of running BMC") + except Exception as e: + raise Exception(e) + + def set_bmc_boot_flash(self, flash): + """ + Set booting flash of BMC + @param flash should be "master" or "slave" + """ + if flash.lower() not in ["master", "slave"]: + return False + json_data = dict() + json_data["data"] = "source /usr/local/bin/openbmc-utils.sh;bmc_reboot %s" % flash + r = requests.post(self.bmc_raw_command_url, json=json_data) + if r.status_code != 200: + return False + return True + + def reboot_bmc(self): + """ + Reboot BMC + """ + json_data = dict() + json_data["data"] = "source /usr/local/bin/openbmc-utils.sh;bmc_reboot reboot" + r = requests.post(self.bmc_raw_command_url, json=json_data) + if r.status_code != 200: + return False + return True + + def get_current_bios(self): + """ + # Get booting bios image of current running host OS + # @return a string, "master" or "slave" + """ + json_data = dict() + json_data["data"] = "source /usr/local/bin/openbmc-utils.sh;come_boot_info" + r = requests.post(self.bmc_raw_command_url, json=json_data) + try: + cpu_boot_info_list = r.json().get('result') + for cpu_boot_info_raw in cpu_boot_info_list: + if "COMe CPU boots from BIOS" in cpu_boot_info_raw: + bios_image = "master" if "master "in cpu_boot_info_raw.lower( + ) else "slave" + return bios_image + raise Exception( + "Error: Unable to detect current running bios image") + except Exception as e: + raise Exception(e) diff --git a/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/optictemputil.py b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/optictemputil.py new file mode 100644 index 000000000000..0e5b6a1c7109 --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/optictemputil.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python + +# +# optictemputil.py +# +# Platform-specific Optic module temperature Interface for SONiC +# + +__author__ = 'Pradchaya P.' +__author__ = 'Wirut G.' +__license__ = "GPL" +__version__ = "1.0.0" +__status__ = "Development" + +import os +import sys +import binascii +import subprocess + +class OpticTempUtil(): + """Platform-specific OpticTempUtil class""" + + def __init__(self): + pass + + def read_eeprom_specific_bytes(self, sysfsfile_eeprom, offset, num_bytes): + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + try: + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + except IOError: + return None + + try: + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except: + return None + + return eeprom_raw + + + def twos_comp(self, num, bits): + try: + if ((num & (1 << (bits - 1))) != 0): + num = num - (1 << bits) + return num + except: + return 0 + + + def calc_temperature(self, cal_type, eeprom_data, offset, size): + + msb = int(eeprom_data[offset], 16) + lsb = int(eeprom_data[offset + 1], 16) + + result = (msb << 8) | (lsb & 0xff) + result = self.twos_comp(result, 16) + + if cal_type == 1: + # Internal calibration + result = float(result / 256.0) + retval = '%.4f' %result + + # TODO: Should support external calibration in future. + else: + retval = 0 + + return retval + + ''' TODO: Change busnum to sysfs_sfp_i2c_client_eeprom_path from caller!!! + ''' + def get_optic_temp(self, sysfs_sfp_i2c_client_eeprom_path, port_type): + + EEPROM_ADDR = 0x50 + DOM_ADDR = 0x51 + EEPROM_OFFSET = 0 + DOM_OFFSET = 256 + + SFP_DMT_ADDR = 92 + SFP_DMT_WIDTH = 1 + SFP_TEMP_DATA_ADDR = 96 + SFP_TEMP_DATA_WIDTH = 2 + + QSFP_TEMP_DATA_ADDR = 22 + QSFP_TEMP_DATA_WIDTH = 2 + temperature_raw = None + + + ''' Open file here ''' + try: + sysfsfile_eeprom = open(sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % sysfs_sfp_i2c_client_eeprom_path) + return 0 + + if port_type == 'QSFP': + + # QSFP only have internal calibration mode. + cal_type = 1 + # read temperature raw value + temperature_raw = self.read_eeprom_specific_bytes(sysfsfile_eeprom,(EEPROM_OFFSET+QSFP_TEMP_DATA_ADDR),QSFP_TEMP_DATA_WIDTH) + else: + # read calibration type at bit 5 + cal_type = self.read_eeprom_specific_bytes(sysfsfile_eeprom,EEPROM_OFFSET+SFP_DMT_ADDR,SFP_DMT_WIDTH) + if cal_type is None: + return 0 + else: + cal_type = (int(cal_type[0],16) >> 5 ) & 1 + # read temperature raw value + temperature_raw = self.read_eeprom_specific_bytes(sysfsfile_eeprom,(DOM_OFFSET+SFP_TEMP_DATA_ADDR),SFP_TEMP_DATA_WIDTH) + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return 0 + + #calculate temperature + if temperature_raw is not None: + return self.calc_temperature(cal_type, temperature_raw, 0, 2) + else: + return 0 \ No newline at end of file diff --git a/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/psuutil.py b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/psuutil.py new file mode 100644 index 000000000000..55c3a41e1f68 --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/psuutil.py @@ -0,0 +1,248 @@ +#!/usr/bin/env python + +__author__ = 'Wirut G.' +__license__ = "GPL" +__version__ = "0.1.4" +__status__ = "Development" + +import requests +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): + PsuBase.__init__(self) + self.fru_status_url = "http://240.1.1.1:8080/api/sys/fruid/status" + self.psu_info_url = "http://240.1.1.1:8080/api/sys/fruid/psu" + + self.fru_status_list = None + self.psu_info_list = None + + def request_data(self): + # Reqest data from BMC if not exist. + if self.fru_status_list is None or self.psu_info_list is None: + fru_status_req = requests.get(self.fru_status_url) + psu_info_req = requests.get(self.psu_info_url) + fru_status_json = fru_status_req.json() + psu_info_json = psu_info_req.json() + self.fru_status_list = fru_status_json.get('Information') + self.psu_info_list = psu_info_json.get('Information') + return self.fru_status_list, self.psu_info_list + + def airflow_selector(self, pn): + # Set airflow type + pn = pn.upper() + if "DPS-1100FB" in pn: + airflow = "FTOB" + elif "DPS-1100AB" in pn: + airflow = "BTOF" + elif "FSJ026-A20G" in pn: + airflow = "FTOB" + elif "FSJ038-A20G" in pn: + airflow = "BTOF" + else: + airflow = "Unknown" + return airflow + + 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 + """ + + num_psus = 4 + + return num_psus + + 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 + """ + + # init data + psu_key = "PSU" + str(index) + psu_status_key = "Power Status" + psu_power_status = False + + try: + # Request and validate sensor's information + self.fru_status_list, self.psu_info_list = self.request_data() + + # Get PSU power status. + for fru_status in self.fru_status_list: + is_psu = fru_status.get(psu_key) + psu_status = str(fru_status.get(psu_status_key)).strip() + + if is_psu is not None and psu_status == "OK": + psu_power_status = True + + except: + print("Error: Unable to access PSU power status") + return False + + return psu_power_status + + 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 + """ + + # Init data + psu_key = "PSU" + str(index) + psu_presence_key = "Present" + psu_presence_status = False + + try: + # Request and validate sensor's information. + self.fru_status_list, self.psu_info_list = self.request_data() + + # Get PSU present status. + for fru_status in self.fru_status_list: + is_psu = fru_status.get(psu_key) + psu_status = str(fru_status.get(psu_presence_key)).strip() + + if is_psu is not None and psu_status == "Present": + psu_presence_status = True + + except: + print("Error: Unable to access PSU presence status") + return False + + return psu_presence_status + + def get_psu_sn(self, index): + """ + Get the serial number of the psu, + + :param index: An integer, 1-based index of the PSU. + :return: Serial number + """ + serial_number = "N/A" + psu_key = "PSU" + str(index) + " FRU" + psu_sn_key = "Serial Number" + + try: + # Request and validate sensor's information. + self.fru_status_list, self.psu_info_list = self.request_data() + + # Get PSU fru info. + for psu_fru in self.psu_info_list: + psu_sn = str(psu_fru.get(psu_sn_key)).strip() + if psu_fru.get(psu_key) is not None: + serial_number = psu_sn if psu_sn.strip() != "" else "N/A" + break + + except: + return "N/A" + + return serial_number + + def get_psu_pn(self, index): + """ + Get the product name of the psu + + :param index: An integer, 1-based index of the PSU. + :return: Product name + """ + product_name = "N/A" + psu_key = "PSU" + str(index) + " FRU" + psu_pn_key = "Product Name" + + try: + # Request and validate sensor's information + self.fru_status_list, self.psu_info_list = self.request_data() + + # Get PSU fru info. + for psu_fru in self.psu_info_list: + psu_pn = str(psu_fru.get(psu_pn_key)).strip() + if psu_fru.get(psu_key) is not None: + product_name = psu_pn if psu_pn.strip() != "" else "N/A" + break + + except: + return "N/A" + + return product_name + + def get_all(self): + """ + Number: mandatory, max number of PSU, integer + PSU1, PSU2, ...: mandatory, PSU name, string + Present: mandatory for each PSU, present status, boolean, True for present, False for NOT present + PowerStatus: conditional, if PRESENT is True, power status of PSU,boolean, True for powered, False for NOT powered + PN, conditional, if PRESENT is True, PN of the PSU, string + SN, conditional, if PRESENT is True, SN of the PSU, string + """ + + # Init data + all_psu_dict = dict() + all_psu_dict["Number"] = self.get_num_psus() + psu_sn_key_1 = "Serial Number" + psu_sn_key_2 = "Product Serial" + psu_pn_key = "Product Name" + + # Request and validate sensor's information. + self.fru_status_list, self.psu_info_list = self.request_data() + + # Set PSU FRU data. + psu_info_dict = dict() + for psu_fru in self.psu_info_list: + psu_data = dict() + pn = psu_fru.get(psu_pn_key) + sn = psu_fru.get(psu_sn_key_1) or psu_fru.get(psu_sn_key_2) + psu_data["PN"] = "N/A" if not pn or str( + pn).strip() == "" else str(pn).strip() + psu_data["SN"] = "N/A" if not pn or str( + pn).strip() == "" else str(sn).strip() + + fru_check = [psu_fru[v] for v in psu_fru.keys() if 'FRU Info' in v] + non_fru_check = [v for v in psu_fru.keys() if 'PSU' in v] + + if len(non_fru_check) > 0: + psu_idx = int(re.findall('\d+', non_fru_check[0])[0]) + psu_info_dict[psu_idx] = psu_data + elif len(fru_check) > 0: + psu_idx = int(re.findall('\d+', fru_check[0])[0]) + psu_info_dict[psu_idx] = psu_data + + # Set PSU status. + for fru_status in self.fru_status_list: + psu_status_dict = dict() + find_psu = [v for v in fru_status.keys() if "PSU" in v] + if len(find_psu) > 0: + psu_idx = int(re.findall('\d+', find_psu[0])[0]) + psu_ps_status = True if str(fru_status.get( + "Present")).strip() == "Present" else False + psu_pw_status = True if str(fru_status.get( + "Power Status")).strip() == "OK" else False + psu_pw_type = str(fru_status.get( + "Power Type")).strip() + ac_status = True if str(fru_status.get( + "AC Status")).strip().upper() == "OK" else False + + psu_status_dict["Present"] = psu_ps_status + if psu_ps_status: + psu_status_dict["PowerStatus"] = psu_pw_status + psu_status_dict["PN"] = psu_info_dict[psu_idx]["PN"] + psu_status_dict["SN"] = psu_info_dict[psu_idx]["SN"] + psu_status_dict["InputType"] = psu_pw_type + psu_status_dict["InputStatus"] = True if psu_pw_status and psu_ps_status else False + psu_status_dict["OutputStatus"] = ac_status + psu_status_dict["AirFlow"] = self.airflow_selector( + psu_status_dict["PN"]) + all_psu_dict[find_psu[0]] = psu_status_dict + + return all_psu_dict diff --git a/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/sensorutil.py b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/sensorutil.py new file mode 100644 index 000000000000..29f56e8578e6 --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/sensorutil.py @@ -0,0 +1,383 @@ +#!/usr/bin/env python + +__author__ = 'Wirut G.' +__license__ = "GPL" +__version__ = "0.2.0" +__status__ = "Development" + +import requests + + +class SensorUtil(): + """Platform-specific SensorUtil class""" + + def __init__(self): + self.sensor_url = "http://240.1.1.1:8080/api/sys/sensors" + self.sys_fruid_url = "http://240.1.1.1:8080/api/sys/fruid/sys" + self.sensor_info_list = None + + def request_data(self): + # Reqest data from BMC if not exist. + if self.sensor_info_list is None: + sensor_data_req = requests.get(self.sensor_url) + sensor_json = sensor_data_req.json() + self.sensor_info_list = sensor_json.get('Information') + sys_fruid_req = requests.get(self.sys_fruid_url) + sys_fruid_json = sys_fruid_req.json() + self.sys_fruid_list = sys_fruid_json.get('Information') + return self.sensor_info_list + + def input_type_selector(self, unit): + # Set input type. + return { + "C": "temperature", + "V": "voltage", + "RPM": "RPM", + "A": "amp", + "W": "power" + }.get(unit, unit) + + def input_name_selector(self, sensor_name, input_name): + + self.sensor_name = { + "syscpld-i2c-0-0d": "TEMPERATURE", + "dps1100-i2c-27-58": "PSU1", + "dps1100-i2c-26-58": "PSU2", + "dps1100-i2c-25-58": "PSU3", + "dps1100-i2c-24-58": "PSU4", + "fancpld-i2c-8-0d": "FAN", + "isl68137-i2c-17-60": "ISL68137" + }.get(sensor_name, sensor_name) + + if 'dps1100' in sensor_name: + input_name = { + "fan1": self.sensor_name + "_FAN", + "iin": self.sensor_name + "_CURR_I", + "iout1": self.sensor_name + "_CURR_O", + "pin": self.sensor_name + "_POWER_I", + "pout1": self.sensor_name + "_POWER_O", + "temp1": self.sensor_name + "_TEMP1", + "temp2": self.sensor_name + "_TEMP2", + "vin": self.sensor_name + "_VOL_I", + "vout1": self.sensor_name + "_VOL_O" + }.get(input_name, input_name) + + elif 'isl68137' in sensor_name: + input_name = { + "iin": self.sensor_name + "_CURR_I", + "iout2": self.sensor_name + "_CURR_O", + "pin": self.sensor_name + "_POWER_I", + "pout2": self.sensor_name + "_POWER_O", + "vin": self.sensor_name + "_VOL_I", + "vout2": self.sensor_name + "_VOL_O", + "temp1": self.sensor_name + "_TEMP1" + }.get(input_name, input_name) + + elif 'tmp75' in sensor_name or 'max31730' in sensor_name: + input_name = { + "tmp75-i2c-7-4f": "BASEBOARD_INLET_RIGHT", + "tmp75-i2c-7-4e": "BASEBOARD_INLET_CENTER", + "tmp75-i2c-7-4d": "SWITCH_OUTLET", + "tmp75-i2c-31-48": "PSU_INLET_LEFT", + "tmp75-i2c-31-49": "INLET_TEMP", + "tmp75-i2c-39-48": "FANBOARD_LEFT", + "tmp75-i2c-39-49": "FANBOARD_RIGHT", + "tmp75-i2c-42-48": "LINECARD_TOP_RIGHT", + "tmp75-i2c-42-49": "LINECARD_TOP_LEFT", + "tmp75-i2c-43-48": "LINECARD_BOTTOM_RIGHT", + "tmp75-i2c-43-49": "LINECARD_BOTTOM_LEFT", + "max31730-i2c-7-4c": "SWITCH_REMOTE_" + input_name + }.get(sensor_name, input_name) + self.sensor_name = "TEMPERATURE" + + elif 'fancpld' in sensor_name: + raw_fan_input = input_name.split() + input_name = raw_fan_input[0] + \ + raw_fan_input[1] + "_" + raw_fan_input[2] + + elif 'ir35' in sensor_name or 'ir38' in sensor_name: + sensor_name_raw = sensor_name.split("-") + sensor_name = sensor_name_raw[0] + self.sensor_name = sensor_name.upper() + + return input_name.replace(" ", "_").upper() + + def get_num_sensors(self): + """ + Get the number of sensors + :return: int num_sensors + """ + + num_sensors = 0 + try: + # Request and validate sensor's information + self.sensor_info_list = self.request_data() + + # Get number of sensors. + num_sensors = len(self.sensor_info_list) + except: + print "Error: Unable to access sensor information" + return 0 + + return num_sensors + + def get_sensor_input_num(self, index): + """ + Get the number of the input items of the specified sensor + :return: int input_num + """ + + input_num = 0 + try: + # Request and validate sensor's information. + self.sensor_info_list = self.request_data() + + # Get sensor's input number. + sensor_data = self.sensor_info_list[index-1] + input_num = len(sensor_data.keys())-2 + except: + print "Error: Unable to access sensor information" + return 0 + + return input_num + + def get_sensor_name(self, index): + """ + Get the device name of the specified sensor. + for example "coretemp-isa-0000" + :return: str sensor_name + """ + + sensor_name = "N/A" + try: + # Request and validate sensor's information. + self.sensor_info_list = self.request_data() + + # Get sensor's name. + sensor_data = self.sensor_info_list[index-1] + sensor_name = sensor_data.get('name') + + except: + return "N/A" + + return sensor_name + + def get_sensor_input_name(self, sensor_index, input_index): + """ + Get the input item name of the specified input item of the + specified sensor index, for example "Physical id 0" + :return: str sensor_input_name + """ + + sensor_input_name = "N/A" + try: + # Request and validate sensor's information. + self.sensor_info_list = self.request_data() + sensor_data = self.sensor_info_list[sensor_index-1].copy() + + # Remove none input key. + del sensor_data["name"] + del sensor_data["Adapter"] + + # Get sensor's input name. + sensor_data_key = sensor_data.keys() + sensor_input_name = sensor_data_key[input_index-1] + except: + return "N/A" + + return sensor_input_name + + def get_sensor_input_type(self, sensor_index, input_index): + """ + Get the item type of the specified input item of the specified sensor index, + The return value should among "valtage","temperature" + :return: str sensor_input_type + """ + + sensor_input_type = "N/A" + try: + # Request and validate sensor's information. + self.sensor_info_list = self.request_data() + sensor_data = self.sensor_info_list[sensor_index-1].copy() + + # Remove none input key. + del sensor_data["name"] + del sensor_data["Adapter"] + + # Get sensor's input type name. + sensor_data_key = sensor_data.keys() + sensor_input_raw = sensor_data.get(sensor_data_key[input_index-1]) + sensor_data_str = sensor_input_raw.split() + sensor_input_type = self.input_type_selector(sensor_data_str[1]) + except: + return "N/A" + + return sensor_input_type + + def get_sensor_input_value(self, sensor_index, input_index): + """ + Get the current value of the input item, the unit is "V" or "C" + :return: float sensor_input_value + """ + + sensor_input_value = 0 + try: + # Request and validate sensor's information. + self.sensor_info_list = self.request_data() + sensor_data = self.sensor_info_list[sensor_index-1].copy() + + # Remove none input key. + del sensor_data["name"] + del sensor_data["Adapter"] + + # Get sensor's input value. + sensor_data_key = sensor_data.keys() + sensor_input_raw = sensor_data.get(sensor_data_key[input_index-1]) + sensor_data_str = sensor_input_raw.split() + sensor_input_value = float( + sensor_data_str[0]) if sensor_data_str[0] != "N/A" else 0 + except: + print "Error: Unable to access sensor information" + return 0 + + return sensor_input_value + + def get_sensor_input_low_threshold(self, sensor_index, input_index): + """ + Get the low threshold of the value, + the status of this item is not ok if the current value 1: + sensor_input_low_threshold = l_thres * \ + 1000 if str(unit[0]).lower() == 'k' else l_thres + except: + print "Error: Unable to access sensor information" + return 0 + + return sensor_input_low_threshold + + def get_sensor_input_high_threshold(self, sensor_index, input_index): + """ + Get the high threshold of the value, + the status of this item is not ok if the current value > high_threshold + :return: float sensor_input_high_threshold + """ + + sensor_input_high_threshold = 0 + try: + # Request and validate sensor's information. + self.sensor_info_list = self.request_data() + sensor_data = self.sensor_info_list[sensor_index-1].copy() + + # Remove none input key. + del sensor_data["name"] + del sensor_data["Adapter"] + + # Get sensor's input high threshold. + sensor_data_key = sensor_data.keys() + sensor_input_raw = sensor_data.get(sensor_data_key[input_index-1]) + sensor_data_str = sensor_input_raw.split() + indices = [i for i, s in enumerate( + sensor_data_str) if 'max' in s or 'high' in s] + h_thres = float( + sensor_data_str[indices[0] + 2]) if len(indices) != 0 else 0 + unit = sensor_data_str[indices[0] + + 3] if len(indices) != 0 else None + if unit is not None and len(unit) > 1: + sensor_input_high_threshold = h_thres * \ + 1000 if str(unit[0]).lower() == 'k' else h_thres + + except: + print "Error: Unable to access sensor information" + return 0 + + return sensor_input_high_threshold + + def get_sys_airflow(self): + sys_air_flow = "Unknown" + sys_pn_data = [ + v.split(":") for v in self.sys_fruid_list if "Product Part Number" in v] + + if len(sys_pn_data) == 0: + return sys_air_flow + + sys_pn = sys_pn_data[0][1] + if "R1240-F0001" in sys_pn: + sys_air_flow = "FTOB" + elif"R1240-F0002" in sys_pn: + sys_air_flow = "BTOF" + + return sys_air_flow + + def get_all(self): + + all_sensor_dict = dict() + + # Request sensor's information. + self.sensor_info_list = self.request_data() + for sensor_data in self.sensor_info_list: + sensor_info = sensor_data.copy() + + # Remove none unuse key. + del sensor_info["name"] + del sensor_info["Adapter"] + + # Set sensor data. + sensor_dict = dict() + for k, v in sensor_info.items(): + sensor_i_dict = dict() + sensor_data_str = v.split() + indices_h = [i for i, s in enumerate( + sensor_data_str) if 'max' in s or 'high' in s] + indices_l = [i for i, s in enumerate( + sensor_data_str) if 'min' in s or 'low' in s] + h_thres = float( + sensor_data_str[indices_h[0] + 2]) if len(indices_h) != 0 else 0 + l_thres = float( + sensor_data_str[indices_l[0] + 2]) if len(indices_l) != 0 else 0 + thres_unit = sensor_data_str[-1] + + sensor_i_dict["Type"] = self.input_type_selector( + sensor_data_str[1]) + sensor_i_dict["Value"] = float( + sensor_data_str[0]) if sensor_data_str[0] != "N/A" else 0 + sensor_i_dict["HighThd"] = h_thres * \ + 1000 if str(thres_unit[0]).lower() == 'k' else h_thres + sensor_i_dict["LowThd"] = l_thres * \ + 1000 if str(thres_unit[0]).lower() == 'k' else l_thres + + k = self.input_name_selector(sensor_data.get('name'), k) + sensor_dict[k] = sensor_i_dict + + if all_sensor_dict.get(self.sensor_name) is None: + all_sensor_dict[self.sensor_name] = dict() + + all_sensor_dict[self.sensor_name].update(sensor_dict) + + sensor_dict = dict() + sensor_dict["Sys_AirFlow"] = self.get_sys_airflow() + all_sensor_dict["TEMPERATURE"].update(sensor_dict) + + return all_sensor_dict diff --git a/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/sfputil.py b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/sfputil.py new file mode 100755 index 000000000000..2831a75af545 --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/plugins/sfputil.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python +# +# 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 = 1 + PORT_END = 128 + QSFP_PORT_START = 1 + QSFP_PORT_END = 128 + + EEPROM_OFFSET = 9 + PORT_INFO_PATH = '/sys/class/phalanx_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 range(self.QSFP_PORT_START, self.QSFP_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.qsfp_ports: + self._port_name = "QSFP" + str(port_num - self.QSFP_PORT_START + 1) + else: + self._port_name = "SFP" + str(port_num) + return self._port_name + + 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 __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.qsfp_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): + return NotImplementedError + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid QSFP port_num + if port_num not in self.qsfp_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.qsfp_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 + """ + return NotImplementedError + + def tx_disable(self, port_num, disable): + """ + @param port_num index of physical port + @param disable, True -- disable port tx signal + False -- enable port tx signal + @return True when operation success, False on failure. + """ + TX_DISABLE_BYTE_OFFSET = 86 + if port_num not in range(self.port_start, self.port_end + 1) or type(disable) != bool: + return False + + # QSFP, set eeprom to disable tx + if port_num in self.qsfp_ports: + presence = self.get_presence(port_num) + if not presence: + return True + + disable = b'\x0f' if disable else b'\x00' + # open eeprom + try: + with open(self.port_to_eeprom_mapping[port_num], mode="wb", buffering=0) as sysfsfile: + sysfsfile.seek(TX_DISABLE_BYTE_OFFSET) + sysfsfile.write(bytearray(disable)) + except IOError: + return False + except: + return False + + # SFP, set tx_disable pin + else: + try: + disable = hex(1) if disable else hex(0) + port_name = self.get_port_name(port_num) + reg_file = open( + "/".join([self.PORT_INFO_PATH, port_name, "sfp_txdisable"]), "w") + reg_file.write(disable) + reg_file.close() + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + return True diff --git a/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/th3-as14-128h.config.bcm b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/th3-as14-128h.config.bcm new file mode 100644 index 000000000000..354e0f2fad00 --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-128h-cl-r0/th3-as14-128h.config.bcm @@ -0,0 +1,631 @@ +pbmp_xport_xe.0=0x0ffff0ffff0ffff0ffff0ffff0ffff0ffff1fffe +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 +port_fec=3 +serdes_tx_taps_ce=pam4:0:140:0:0:0:0 + +init_all_modules=0 +mdio_output_delay=64 + +#BC1 +portmap_5=9:100:2 +portmap_6=11:100:2 +portmap_7=13:100:2 +portmap_8=15:100:2 + +dport_map_port_5=1 +dport_map_port_6=2 +dport_map_port_7=4 +dport_map_port_8=3 + +#BC9 +portmap_44=73:100:2 +portmap_45=75:100:2 +portmap_46=77:100:2 +portmap_47=79:100:2 + +dport_map_port_44=8 +dport_map_port_45=7 +dport_map_port_46=5 +dport_map_port_47=6 + +#BC0 +portmap_1=1:100:2 +portmap_2=3:100:2 +portmap_3=5:100:2 +portmap_4=7:100:2 + +dport_map_port_1=9 +dport_map_port_2=10 +dport_map_port_3=12 +dport_map_port_4=11 + +#BC8 +portmap_40=65:100:2 +portmap_41=67:100:2 +portmap_42=69:100:2 +portmap_43=71:100:2 + +dport_map_port_40=16 +dport_map_port_41=15 +dport_map_port_42=13 +dport_map_port_43=14 + +#BC5 +portmap_24=41:100:2 +portmap_25=43:100:2 +portmap_26=45:100:2 +portmap_27=47:100:2 + +dport_map_port_24=17 +dport_map_port_25=18 +dport_map_port_26=20 +dport_map_port_27=19 + +#BC13 +portmap_64=105:100:2 +portmap_65=107:100:2 +portmap_66=109:100:2 +portmap_67=111:100:2 + +dport_map_port_64=24 +dport_map_port_65=23 +dport_map_port_66=21 +dport_map_port_67=22 + +#BC4 +portmap_20=33:100:2 +portmap_21=35:100:2 +portmap_22=37:100:2 +portmap_23=39:100:2 + +dport_map_port_20=25 +dport_map_port_21=26 +dport_map_port_22=28 +dport_map_port_23=27 + +#BC12 +portmap_60=97:100:2 +portmap_61=99:100:2 +portmap_62=101:100:2 +portmap_63=103:100:2 + +dport_map_port_60=32 +dport_map_port_61=31 +dport_map_port_62=29 +dport_map_port_63=30 + +#BC17 +portmap_84=137:100:2 +portmap_85=139:100:2 +portmap_86=141:100:2 +portmap_87=143:100:2 + +dport_map_port_84=33 +dport_map_port_85=34 +dport_map_port_86=36 +dport_map_port_87=35 + +#BC25 +portmap_124=201:100:2 +portmap_125=203:100:2 +portmap_126=205:100:2 +portmap_127=207:100:2 + +dport_map_port_124=40 +dport_map_port_125=39 +dport_map_port_126=37 +dport_map_port_127=38 + +#BC16 +portmap_80=129:100:2 +portmap_81=131:100:2 +portmap_82=133:100:2 +portmap_83=135:100:2 + +dport_map_port_80=41 +dport_map_port_81=42 +dport_map_port_82=44 +dport_map_port_83=43 + +#BC24 +portmap_120=193:100:2 +portmap_121=195:100:2 +portmap_122=197:100:2 +portmap_123=199:100:2 + +dport_map_port_120=48 +dport_map_port_121=47 +dport_map_port_122=45 +dport_map_port_123=46 + +#BC21 +portmap_104=169:100:2 +portmap_105=171:100:2 +portmap_106=173:100:2 +portmap_107=175:100:2 + +dport_map_port_104=49 +dport_map_port_105=50 +dport_map_port_106=52 +dport_map_port_107=51 + +#BC29 +portmap_144=233:100:2 +portmap_145=235:100:2 +portmap_146=237:100:2 +portmap_147=239:100:2 + +dport_map_port_144=56 +dport_map_port_145=55 +dport_map_port_146=53 +dport_map_port_147=54 + +#BC20 +portmap_100=161:100:2 +portmap_101=163:100:2 +portmap_102=165:100:2 +portmap_103=167:100:2 + +dport_map_port_100=57 +dport_map_port_101=58 +dport_map_port_102=60 +dport_map_port_103=59 + +#BC28 +portmap_140=225:100:2 +portmap_141=227:100:2 +portmap_142=229:100:2 +portmap_143=231:100:2 + +dport_map_port_140=64 +dport_map_port_141=63 +dport_map_port_142=61 +dport_map_port_143=62 + +#BC3 +portmap_13=25:100:2 +portmap_14=27:100:2 +portmap_15=29:100:2 +portmap_16=31:100:2 + +dport_map_port_13=65 +dport_map_port_14=66 +dport_map_port_15=68 +dport_map_port_16=67 + +#BC11 +portmap_52=89:100:2 +portmap_53=91:100:2 +portmap_54=93:100:2 +portmap_55=95:100:2 + +dport_map_port_52=72 +dport_map_port_53=71 +dport_map_port_54=69 +dport_map_port_55=70 + +#BC2 +portmap_9=17:100:2 +portmap_10=19:100:2 +portmap_11=21:100:2 +portmap_12=23:100:2 + +dport_map_port_9=73 +dport_map_port_10=74 +dport_map_port_11=76 +dport_map_port_12=75 + +#BC10 +portmap_48=81:100:2 +portmap_49=83:100:2 +portmap_50=85:100:2 +portmap_51=87:100:2 + +dport_map_port_48=80 +dport_map_port_49=79 +dport_map_port_50=77 +dport_map_port_51=78 + +#BC7 +portmap_32=57:100:2 +portmap_33=59:100:2 +portmap_34=61:100:2 +portmap_35=63:100:2 + +dport_map_port_32=81 +dport_map_port_33=82 +dport_map_port_34=84 +dport_map_port_35=83 + +#BC15 +portmap_72=121:100:2 +portmap_73=123:100:2 +portmap_74=125:100:2 +portmap_75=127:100:2 + +dport_map_port_72=88 +dport_map_port_73=87 +dport_map_port_74=85 +dport_map_port_75=86 + +#BC6 +portmap_28=49:100:2 +portmap_29=51:100:2 +portmap_30=53:100:2 +portmap_31=55:100:2 + +dport_map_port_28=89 +dport_map_port_29=90 +dport_map_port_30=92 +dport_map_port_31=91 + +#BC14 +portmap_68=113:100:2 +portmap_69=115:100:2 +portmap_70=117:100:2 +portmap_71=119:100:2 + +dport_map_port_68=96 +dport_map_port_69=95 +dport_map_port_70=93 +dport_map_port_71=94 + +#BC19 +portmap_92=153:100:2 +portmap_93=155:100:2 +portmap_94=157:100:2 +portmap_95=159:100:2 + +dport_map_port_92=97 +dport_map_port_93=98 +dport_map_port_94=100 +dport_map_port_95=99 + +#BC27 +portmap_132=217:100:2 +portmap_133=219:100:2 +portmap_134=221:100:2 +portmap_135=223:100:2 + +dport_map_port_132=104 +dport_map_port_133=103 +dport_map_port_134=101 +dport_map_port_135=102 + +#BC18 +portmap_88=145:100:2 +portmap_89=147:100:2 +portmap_90=149:100:2 +portmap_91=151:100:2 + +dport_map_port_88=105 +dport_map_port_89=106 +dport_map_port_90=108 +dport_map_port_91=107 + +#BC26 +portmap_128=209:100:2 +portmap_129=211:100:2 +portmap_130=213:100:2 +portmap_131=215:100:2 + +dport_map_port_128=112 +dport_map_port_129=111 +dport_map_port_130=109 +dport_map_port_131=110 + +#BC23 +portmap_112=185:100:2 +portmap_113=187:100:2 +portmap_114=189:100:2 +portmap_115=191:100:2 + +dport_map_port_112=113 +dport_map_port_113=114 +dport_map_port_114=116 +dport_map_port_115=115 + +#BC31 +portmap_152=249:100:2 +portmap_153=251:100:2 +portmap_154=253:100:2 +portmap_155=255:100:2 + +dport_map_port_152=120 +dport_map_port_153=119 +dport_map_port_154=117 +dport_map_port_155=118 + +#BC22 +portmap_108=177:100:2 +portmap_109=179:100:2 +portmap_110=181:100:2 +portmap_111=183:100:2 + +dport_map_port_108=121 +dport_map_port_109=122 +dport_map_port_110=124 +dport_map_port_111=123 + +#BC30 +portmap_148=241:100:2 +portmap_149=243:100:2 +portmap_150=245:100:2 +portmap_151=247:100:2 + +dport_map_port_148=128 +dport_map_port_149=127 +dport_map_port_150=125 +dport_map_port_151=126 + +#BC1 +phy_chain_rx_lane_map_physical{9.0}=0x13026475 +phy_chain_tx_lane_map_physical{9.0}=0x21340756 + +#BC9 +phy_chain_rx_lane_map_physical{73.0}=0x47560213 +phy_chain_tx_lane_map_physical{73.0}=0x76540132 + +#BC0 +phy_chain_rx_lane_map_physical{1.0}=0x20314657 +phy_chain_tx_lane_map_physical{1.0}=0x32014567 + +#BC8 +phy_chain_rx_lane_map_physical{65.0}=0x13025647 +phy_chain_tx_lane_map_physical{65.0}=0x13204675 + +#BC5 +phy_chain_rx_lane_map_physical{41.0}=0x31207564 +phy_chain_tx_lane_map_physical{41.0}=0x23104567 + +#BC13 +phy_chain_rx_lane_map_physical{105.0}=0x63725140 +phy_chain_tx_lane_map_physical{105.0}=0x76541032 + +#BC4 +phy_chain_rx_lane_map_physical{33.0}=0x76452031 +phy_chain_tx_lane_map_physical{33.0}=0x67450123 + +#BC12 +phy_chain_rx_lane_map_physical{97.0}=0x31206574 +phy_chain_tx_lane_map_physical{97.0}=0x31025467 + +#BC17 +phy_chain_rx_lane_map_physical{137.0}=0x13025746 +phy_chain_tx_lane_map_physical{137.0}=0x23410576 + +#BC25 +phy_chain_rx_lane_map_physical{201.0}=0x47560213 +phy_chain_tx_lane_map_physical{201.0}=0x67450231 + +#BC16 +phy_chain_rx_lane_map_physical{129.0}=0x30214657 +phy_chain_tx_lane_map_physical{129.0}=0x13427065 + +#BC24 +phy_chain_rx_lane_map_physical{193.0}=0x13025647 +phy_chain_tx_lane_map_physical{193.0}=0x23104675 + +#BC21 +phy_chain_rx_lane_map_physical{169.0}=0x31206574 +phy_chain_tx_lane_map_physical{169.0}=0x13205476 + +#BC29 +phy_chain_rx_lane_map_physical{233.0}=0x65741302 +phy_chain_tx_lane_map_physical{233.0}=0x57610423 + +#BC20 +phy_chain_rx_lane_map_physical{161.0}=0x74652031 +phy_chain_tx_lane_map_physical{161.0}=0x57640132 + +#BC28 +phy_chain_rx_lane_map_physical{225.0}=0x16072435 +phy_chain_tx_lane_map_physical{225.0}=0x43127065 + +#BC3 laneswap +phy_chain_rx_lane_map_physical{25.0}=0x36271504 +phy_chain_tx_lane_map_physical{25.0}=0x13204576 + +#BC11 +phy_chain_rx_lane_map_physical{89.0}=0x47560213 +phy_chain_tx_lane_map_physical{89.0}=0x76540132 + +#BC2 +phy_chain_rx_lane_map_physical{17.0}=0x43507162 +phy_chain_tx_lane_map_physical{17.0}=0x46570123 + +#BC10 +phy_chain_rx_lane_map_physical{81.0}=0x13025647 +phy_chain_tx_lane_map_physical{81.0}=0x13204675 + +#BC7 +phy_chain_rx_lane_map_physical{57.0}=0x31207564 +phy_chain_tx_lane_map_physical{57.0}=0x23406175 + +#BC15 +phy_chain_rx_lane_map_physical{121.0}=0x13026475 +phy_chain_tx_lane_map_physical{121.0}=0x23507614 + +#BC6 +phy_chain_rx_lane_map_physical{49.0}=0x65742031 +phy_chain_tx_lane_map_physical{49.0}=0x57640231 + +#BC14 +phy_chain_rx_lane_map_physical{113.0}=0x02136574 +phy_chain_tx_lane_map_physical{113.0}=0x12436075 + +#BC19 +phy_chain_rx_lane_map_physical{153.0}=0x40516273 +phy_chain_tx_lane_map_physical{153.0}=0x32045671 + +#BC27 +phy_chain_rx_lane_map_physical{217.0}=0x64570213 +phy_chain_tx_lane_map_physical{217.0}=0x67054123 + +#BC18 +phy_chain_rx_lane_map_physical{145.0}=0x46570213 +phy_chain_tx_lane_map_physical{145.0}=0x57063421 + +#BC26 +phy_chain_rx_lane_map_physical{209.0}=0x13025647 +phy_chain_tx_lane_map_physical{209.0}=0x23104675 + +#BC23 +phy_chain_rx_lane_map_physical{185.0}=0x31207564 +phy_chain_tx_lane_map_physical{185.0}=0x13245076 + +#BC31 +phy_chain_rx_lane_map_physical{249.0}=0x02137564 +phy_chain_tx_lane_map_physical{249.0}=0x32106457 + +#BC22 +phy_chain_rx_lane_map_physical{177.0}=0x64752031 +phy_chain_tx_lane_map_physical{177.0}=0x57640132 + +#BC30 +phy_chain_rx_lane_map_physical{241.0}=0x31204657 +phy_chain_tx_lane_map_physical{241.0}=0x32016457 + +#BC1 +serdes_core_rx_polarity_flip_physical{9}=0x33 +serdes_core_tx_polarity_flip_physical{9}=0x71 + +#BC9 +serdes_core_rx_polarity_flip_physical{73}=0x93 +serdes_core_tx_polarity_flip_physical{73}=0xa9 + +#BC0 +serdes_core_rx_polarity_flip_physical{1}=0xc3 +serdes_core_tx_polarity_flip_physical{1}=0xdf + +#BC8 +serdes_core_rx_polarity_flip_physical{65}=0x39 +serdes_core_tx_polarity_flip_physical{65}=0xbe + +#BC5 +serdes_core_rx_polarity_flip_physical{41}=0x3c +serdes_core_tx_polarity_flip_physical{41}=0x6a + +#BC13 +serdes_core_rx_polarity_flip_physical{105}=0xc6 +serdes_core_tx_polarity_flip_physical{105}=0xaf + +#BC4 +serdes_core_rx_polarity_flip_physical{33}=0x63 +serdes_core_tx_polarity_flip_physical{33}=0x1c + +#BC12 +serdes_core_rx_polarity_flip_physical{97}=0x36 +serdes_core_tx_polarity_flip_physical{97}=0x7f + +#BC17 +serdes_core_rx_polarity_flip_physical{137}=0x3c +serdes_core_tx_polarity_flip_physical{137}=0x71 + +#BC25 +serdes_core_rx_polarity_flip_physical{201}=0x93 +serdes_core_tx_polarity_flip_physical{201}=0x5c + +#BC16 +serdes_core_rx_polarity_flip_physical{129}=0x63 +serdes_core_tx_polarity_flip_physical{129}=0x6f + +#BC24 +serdes_core_rx_polarity_flip_physical{193}=0x39 +serdes_core_tx_polarity_flip_physical{193}=0x1e + +#BC21 +serdes_core_rx_polarity_flip_physical{169}=0x32 +serdes_core_tx_polarity_flip_physical{169}=0xc5 + +#BC29 +serdes_core_rx_polarity_flip_physical{233}=0x9c +serdes_core_tx_polarity_flip_physical{233}=0xca + +#BC20 +serdes_core_rx_polarity_flip_physical{161}=0x63 +serdes_core_tx_polarity_flip_physical{161}=0x87 + +#BC28 +serdes_core_rx_polarity_flip_physical{225}=0x21 +serdes_core_tx_polarity_flip_physical{225}=0xca + +#Polarity BC3 +serdes_core_rx_polarity_flip_physical{25}=0x89 +serdes_core_tx_polarity_flip_physical{25}=0xcb + +#BC11 +serdes_core_rx_polarity_flip_physical{89}=0x93 +serdes_core_tx_polarity_flip_physical{89}=0xb9 + +#BC2 +serdes_core_rx_polarity_flip_physical{17}=0xc2 +serdes_core_tx_polarity_flip_physical{17}=0x8a +#BC10 +serdes_core_rx_polarity_flip_physical{81}=0x39 +serdes_core_tx_polarity_flip_physical{81}=0xbe + +#BC7 +serdes_core_rx_polarity_flip_physical{57}=0x3c +serdes_core_tx_polarity_flip_physical{57}=0x6c + +#BC15 +serdes_core_rx_polarity_flip_physical{121}=0x33 +serdes_core_tx_polarity_flip_physical{121}=0x47 + +#BC6 +serdes_core_rx_polarity_flip_physical{49}=0x93 +serdes_core_tx_polarity_flip_physical{49}=0x82 + +#BC14 +serdes_core_rx_polarity_flip_physical{113}=0x86 +serdes_core_tx_polarity_flip_physical{113}=0x08 + +#BC19 +serdes_core_rx_polarity_flip_physical{153}=0x66 +serdes_core_tx_polarity_flip_physical{153}=0xc6 + +#BC27 +serdes_core_rx_polarity_flip_physical{217}=0xc3 +serdes_core_tx_polarity_flip_physical{217}=0x52 + +#BC18 +serdes_core_rx_polarity_flip_physical{145}=0xc3 +serdes_core_tx_polarity_flip_physical{145}=0xef + +#BC26 +serdes_core_rx_polarity_flip_physical{209}=0x39 +serdes_core_tx_polarity_flip_physical{209}=0x3e + +#BC23 +serdes_core_rx_polarity_flip_physical{185}=0x3c +serdes_core_tx_polarity_flip_physical{185}=0xd5 + +#BC31 +serdes_core_rx_polarity_flip_physical{249}=0xcc +serdes_core_tx_polarity_flip_physical{249}=0xac + +#BC22 +serdes_core_rx_polarity_flip_physical{177}=0xc3 +serdes_core_tx_polarity_flip_physical{177}=0x83 + +#BC30 +serdes_core_rx_polarity_flip_physical{241}=0x33 +serdes_core_tx_polarity_flip_physical{241}=0x2d + +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/alibaba/x86_64-alibaba_as14-40d-cl-r0/.installer.conf.swp b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/.installer.conf.swp new file mode 100644 index 000000000000..e85feb00996a Binary files /dev/null and b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/.installer.conf.swp differ diff --git a/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/AS14-40D/port_config.ini b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/AS14-40D/port_config.ini new file mode 100644 index 000000000000..5c6ca5db0a7b --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/AS14-40D/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index +Ethernet1 1,2,3,4 QSFP1 1 +Ethernet2 5,6,7,8 QSFP2 2 +Ethernet3 9,10,11,12 QSFP3 3 +Ethernet4 13,14,15,16 QSFP4 4 +Ethernet5 17,18,19,20 QSFP5 5 +Ethernet6 21,22,23,24 QSFP6 6 +Ethernet7 25,26,27,28 QSFP7 7 +Ethernet8 29,30,31,32 QSFP8 8 +Ethernet9 33,34,35,36 QSFP9 9 +Ethernet10 37,38,39,40 QSFP10 10 +Ethernet11 41,42,43,44 QSFP11 11 +Ethernet12 45,46,47,48 QSFP12 12 +Ethernet13 49,50,51,52 QSFP13 13 +Ethernet14 53,54,55,56 QSFP14 14 +Ethernet15 57,58,59,60 QSFP15 15 +Ethernet16 61,62,63,64 QSFP16 16 +Ethernet17 65,66,67,68 QSFP17 17 +Ethernet18 69,70,71,72 QSFP18 18 +Ethernet19 73,74,75,76 QSFP19 19 +Ethernet20 77,78,79,80 QSFP20 20 +Ethernet21 81,82,83,84 QSFP21 21 +Ethernet22 85,86,87,88 QSFP22 22 +Ethernet23 89,90,91,92 QSFP23 23 +Ethernet24 93,94,95,96 QSFP24 24 +Ethernet25 97,98,99,100 QSFP25 25 +Ethernet26 101,102,103,104 QSFP26 26 +Ethernet27 105,106,107,108 QSFP27 27 +Ethernet28 109,110,111,112 QSFP28 28 +Ethernet29 113,114,115,116 QSFP29 29 +Ethernet30 117,118,119,120 QSFP30 30 +Ethernet31 121,122,123,124 QSFP31 31 +Ethernet32 125,126,127,128 QSFP32 32 diff --git a/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/AS14-40D/sai.profile b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/AS14-40D/sai.profile new file mode 100644 index 000000000000..a4240891e387 --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/AS14-40D/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/platform/td3-as14-40d.config.bcm diff --git a/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/custom_led.bin b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/custom_led.bin new file mode 100644 index 000000000000..91552022dc6f Binary files /dev/null and b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/custom_led.bin differ diff --git a/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/default_sku b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/default_sku new file mode 100644 index 000000000000..93cd11afaefb --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/default_sku @@ -0,0 +1 @@ +AS14-40D t1 diff --git a/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/installer.conf b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/installer.conf new file mode 100644 index 000000000000..3f23040c648f --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_SPEED=9600 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="processor.max_cstate=1 intel_idle.max_cstate=0 + processor.max_pstate=1 intel_idle.max_pstate=0" diff --git a/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/led_proc_init.soc b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/led_proc_init.soc new file mode 100644 index 000000000000..28cd4b9bc9f7 --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/led_proc_init.soc @@ -0,0 +1,9 @@ +#Enable all ports +#port all en=1 +#sleep 6 +#linkscan 250000; port xe,ce linkscan=on + +#Load LED +#led auto on; led start + + diff --git a/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/linkscan_led_fw.bin b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/linkscan_led_fw.bin new file mode 100644 index 000000000000..a6a4794ecc2b Binary files /dev/null and b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/linkscan_led_fw.bin differ diff --git a/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/minigraph.xml b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/minigraph.xml new file mode 100644 index 000000000000..5e95b6ecafe9 --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/minigraph.xml @@ -0,0 +1,854 @@ + + + + + + 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 + + + + + + QSFP1 + 10.0.0.0/31 + + + + QSFP2 + 10.0.0.2/31 + + + + QSFP3 + 10.0.0.4/31 + + + + QSFP4 + 10.0.0.6/31 + + + + QSFP5 + 10.0.0.8/31 + + + + QSFP6 + 10.0.0.10/31 + + + + QSFP7 + 10.0.0.12/31 + + + + QSFP8 + 10.0.0.14/31 + + + + QSFP9 + 10.0.0.16/31 + + + + QSFP10 + 10.0.0.18/31 + + + + QSFP11 + 10.0.0.20/31 + + + + QSFP12 + 10.0.0.22/31 + + + + QSFP13 + 10.0.0.24/31 + + + + QSFP14 + 10.0.0.26/31 + + + + QSFP15 + 10.0.0.28/31 + + + + QSFP16 + 10.0.0.30/31 + + + + QSFP17 + 10.0.0.32/31 + + + + QSFP18 + 10.0.0.34/31 + + + + QSFP19 + 10.0.0.36/31 + + + + QSFP20 + 10.0.0.38/31 + + + + QSFP21 + 10.0.0.40/31 + + + + QSFP22 + 10.0.0.42/31 + + + + QSFP23 + 10.0.0.44/31 + + + + QSFP24 + 10.0.0.46/31 + + + + QSFP25 + 10.0.0.48/31 + + + + QSFP26 + 10.0.0.50/31 + + + + QSFP27 + 10.0.0.52/31 + + + + QSFP28 + 10.0.0.54/31 + + + + QSFP29 + 10.0.0.56/31 + + + + QSFP30 + 10.0.0.58/31 + + + + QSFP31 + 10.0.0.60/31 + + + + QSFP32 + 10.0.0.62/31 + + + + + + + + + + + + + sonic + AS14-40D + + + + + + + sonic + + + DhcpResources + + + + + NtpResources + + 0.debian.pool.ntp.org;1.debian.pool.ntp.org;2.debian.pool.ntp.org;3.debian.pool.ntp.org + + + SyslogResources + + + + + ErspanDestinationIpv4 + + 2.2.2.2 + + + + + + + sonic + AS14-40D +
diff --git a/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/opennsl-postinit.cfg b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/opennsl-postinit.cfg new file mode 100644 index 000000000000..7008c14c0ffc --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/opennsl-postinit.cfg @@ -0,0 +1,3 @@ +linkscan 250000; port xe,ce linkscan=on +sleep 1 +led auto on; led start diff --git a/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/cputemputil.py b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/cputemputil.py new file mode 100644 index 000000000000..ac2589d044fd --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/cputemputil.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python + +# +# cputemputil.py +# +# Platform-specific CPU temperature Interface for SONiC +# + +__author__ = 'Wirut G.' +__license__ = "GPL" +__version__ = "0.1.0" +__status__ = "Development" + + +import subprocess +import requests + + +class CpuTempUtil(): + """Platform-specific CpuTempUtil class""" + + def __init__(self): + pass + + def get_cpu_temp(self): + + # Get list of temperature of CPU cores. + p = subprocess.Popen(['sensors', '-Au', 'coretemp-isa-0000'], + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = p.communicate() + raw_data_list = out.splitlines() + temp_string_list = [i for i, s in enumerate( + raw_data_list) if '_input' in s] + tmp_list = [0] + + for temp_string in temp_string_list: + tmp_list.append(float(raw_data_list[temp_string].split(":")[1])) + + return tmp_list + + def get_max_cpu_tmp(self): + # Get maximum temperature from list of temperature of CPU cores. + return max(self.get_cpu_temp()) diff --git a/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/eeprom.py b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/eeprom.py new file mode 100644 index 000000000000..9f42b56ce7c2 --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/eeprom.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica 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: + 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/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/fanutil.py b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/fanutil.py new file mode 100644 index 000000000000..dab2f64dd5e0 --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/fanutil.py @@ -0,0 +1,310 @@ +#!/usr/bin/env python + +__author__ = 'Wirut G.' +__license__ = "GPL" +__version__ = "0.1.2" +__status__ = "Development" + +import requests +import re + + +class FanUtil(): + """Platform-specific FanUtil class""" + + def __init__(self): + + self.fan_fru_url = "http://240.1.1.1:8080/api/sys/fruid/fan" + self.sensor_url = "http://240.1.1.1:8080/api/sys/sensors" + self.fru_data_list = None + self.sensor_data_list = None + + def request_data(self): + # Reqest data from BMC if not exist. + if self.fru_data_list is None or self.sensor_data_list is None: + fru_data_req = requests.get(self.fan_fru_url) + sensor_data_req = requests.get(self.sensor_url) + fru_json = fru_data_req.json() + sensor_json = sensor_data_req.json() + self.fru_data_list = fru_json.get('Information') + self.sensor_data_list = sensor_json.get('Information') + return self.fru_data_list, self.sensor_data_list + + def name_to_index(self, fan_name): + # Get fan index from fan name + match = re.match(r"(FAN)([0-9]+)-(1|2)", fan_name, re.I) + fan_index = None + if match: + i_list = list(match.groups()) + fan_index = int(i_list[1])*2 - (int(i_list[2]) % 2) + return fan_index + + def get_num_fans(self): + """ + Get the number of fans + :return: int num_fans + """ + num_fans = 8 + + return num_fans + + def get_fan_speed(self, fan_name): + """ + Get the current speed of the fan, the unit is "RPM" + :return: int fan_speed + """ + + try: + # Get real fan index + index = self.name_to_index(fan_name) + + # Set key and index. + fan_speed = 0 + position_key = "Front" if index % 2 != 0 else "Rear" + index = int(round(float(index)/2)) + fan_key = "Fan " + str(index) + " " + position_key + + # Request and validate fan information. + self.fru_data_list, self.sensor_data_list = self.request_data() + + # Get fan's speed. + for sensor_data in self.sensor_data_list: + sensor_name = sensor_data.get('name') + if "fan" in str(sensor_name): + fan_data = sensor_data.get(fan_key) + fan_sp_list = map(int, re.findall(r'\d+', fan_data)) + fan_speed = fan_sp_list[0] + + except: + return 0 + + return fan_speed + + def get_fan_low_threshold(self, fan_name): + """ + Get the low speed threshold of the fan. + if the current speed < low speed threshold, + the status of the fan is not ok. + :return: int fan_low_threshold + """ + + try: + # Get real fan index + index = self.name_to_index(fan_name) + + # Set key and index. + fan_low_threshold = 0 + position_key = "Front" if index % 2 != 0 else "Rear" + index = int(round(float(index)/2)) + fan_key = "Fan " + str(index) + " " + position_key + + # Request and validate fan information. + self.fru_data_list, self.sensor_data_list = self.request_data() + + # Get fan's threshold. + for sensor_data in self.sensor_data_list: + sensor_name = sensor_data.get('name') + if "fan" in str(sensor_name): + fan_data = sensor_data.get(fan_key) + fan_sp_list = map(int, re.findall(r'\d+', fan_data)) + fan_low_threshold = fan_sp_list[1] + + except: + return "N/A" + + return fan_low_threshold + + def get_fan_high_threshold(self, fan_name): + """ + Get the hight speed threshold of the fan, + if the current speed > high speed threshold, + the status of the fan is not ok + :return: int fan_high_threshold + """ + + try: + # Get real fan index + index = self.name_to_index(fan_name) + + # Set key and index. + fan_high_threshold = 0 + position_key = "Front" if index % 2 != 0 else "Rear" + index = int(round(float(index)/2)) + fan_key = "Fan " + str(index) + " " + position_key + + # Request and validate fan information. + self.fru_data_list, self.sensor_data_list = self.request_data() + + # Get fan's threshold. + for sensor_data in self.sensor_data_list: + sensor_name = sensor_data.get('name') + if "fan" in str(sensor_name): + fan_data = sensor_data.get(fan_key) + fan_sp_list = map(int, re.findall(r'\d+', fan_data)) + fan_high_threshold = fan_sp_list[2] + + except: + return 0 + + return fan_high_threshold + + def get_fan_pn(self, fan_name): + """ + Get the product name of the fan + :return: str fan_pn + """ + + try: + # Get real fan index + index = self.name_to_index(fan_name) + + # Set key and index. + fan_pn = "N/A" + index = int(round(float(index)/2)) + fan_fru_key = "Fantray" + str(index) + + # Request and validate fan information. + self.fru_data_list, self.sensor_data_list = self.request_data() + + # Get fan's fru. + for fan_fru in self.fru_data_list: + matching_fan = [s for s in fan_fru if fan_fru_key in s] + if matching_fan: + pn = [s for s in fan_fru if "Part" in s] + fan_pn = pn[0].split()[4] + + except: + return "N/A" + + return fan_pn + + def get_fan_sn(self, fan_name): + """ + Get the serial number of the fan + :return: str fan_sn + """ + try: + # Get real fan index + index = self.name_to_index(fan_name) + + # Set key and index. + fan_sn = "N/A" + index = int(round(float(index)/2)) + fan_fru_key = "Fantray" + str(index) + + # Request and validate fan information. + self.fru_data_list, self.sensor_data_list = self.request_data() + + # Get fan's fru. + for fan_fru in self.fru_data_list: + matching_fan = [s for s in fan_fru if fan_fru_key in s] + if matching_fan: + serial = [s for s in fan_fru if "Serial" in s] + fan_sn = serial[0].split()[3] + + except: + return "N/A" + + return fan_sn + + def get_fans_name_list(self): + """ + Get list of fan name. + :return: list fan_names + """ + fan_names = [] + + # Get the number of fans + n_fan = self.get_num_fans() + + # Set fan name and add to the list. + for x in range(1, n_fan + 1): + f_index = int(round(float(x)/2)) + pos = 1 if x % 2 else 2 + fan_name = 'FAN{}_{}'.format(f_index, pos) + fan_names.append(fan_name) + + return fan_names + + def get_all(self): + """ + Get all information of system FANs, returns JSON objects in python 'DICT'. + Number, mandatory, max number of FAN, integer + FAN1_1, FAN1_2, ... mandatory, FAN name, string + Present, mandatory for each FAN, present status, boolean, True for present, False for NOT present, read directly from h/w + Running, conditional, if PRESENT is True, running status of the FAN, True for running, False for stopped, read directly from h/w + Speed, conditional, if PRESENT is True, real FAN speed, float, read directly from h/w + LowThd, conditional, if PRESENT is True, lower bound of FAN speed, float, read from h/w + HighThd, conditional, if PRESENT is True, upper bound of FAN speed, float, read from h/w + PN, conditional, if PRESENT is True, PN of the FAN, string + SN, conditional, if PRESENT is True, SN of the FAN, string) + """ + + self.fru_data_list, self.sensor_data_list = self.request_data() + all_fan_dict = dict() + + # Get the number of fans + n_fan = self.get_num_fans() + all_fan_dict["Number"] = n_fan + + # Set fan FRU data. + fan_fru_dict = dict() + fan_raw_idx = 1 + for fan_fru in self.fru_data_list: + fru_dict = dict() + fan_ps = False + + if len(fan_fru) == 0: + fan_idx = fan_raw_idx + fan_pn = "N/A" + fan_sn = "N/A" + else: + fan_key = fan_fru[0].split() + if str(fan_key[-1]).lower() == "absent": + fan_idx = int(re.findall('\d+', fan_key[0])[0]) + + else: + fan_idx = int(re.findall('\d+', fan_key[-1])[0]) + fan_ps = True + pn = [s for s in fan_fru if "Part" in s] + sn = [s for s in fan_fru if "Serial" in s] + fan_pn = pn[0].split( + ":")[-1].strip() if len(pn) > 0 else 'N/A' + fan_sn = sn[0].split( + ":")[-1].strip() if len(sn) > 0 else 'N/A' + + fru_dict["PN"] = "N/A" if not fan_pn or fan_pn == "" else fan_pn + fru_dict["SN"] = "N/A" if not fan_sn or fan_sn == "" else fan_sn + fru_dict["Present"] = fan_ps + fan_fru_dict[fan_idx] = fru_dict + fan_raw_idx += 1 + + # Set fan sensor data. + for sensor_data in self.sensor_data_list: + sensor_name = sensor_data.get('name') + if "fan" in str(sensor_name): + for x in range(1, n_fan + 1): + fan_dict = dict() + f_index = int(round(float(x)/2)) + pos = 1 if x % 2 else 2 + position_key = "Front" if x % 2 != 0 else "Rear" + fan_key = "Fan " + str(f_index) + " " + position_key + fan_data = sensor_data.get(fan_key) + fan_sp_list = map(int, re.findall(r'\d+', fan_data)) + fan_dict["Present"] = fan_fru_dict[f_index]["Present"] + if fan_dict["Present"] or fan_sp_list[0] > 0: + fan_dict["Present"] = True + fan_dict["Speed"] = fan_sp_list[0] + fan_dict["Running"] = True if fan_dict["Speed"] > 0 else False + fan_dict["LowThd"] = fan_sp_list[1] + fan_dict["HighThd"] = fan_sp_list[2] + fan_dict["PN"] = fan_fru_dict[f_index]["PN"] + fan_dict["SN"] = fan_fru_dict[f_index]["SN"] + fan_dict["AirFlow"] = "FTOB" if "R1241-F9001" in fan_dict["PN"] else "Unknown" + fan_dict["AirFlow"] = "BTOF" if "R1241-F9002" in fan_dict["PN"] else fan_dict["AirFlow"] + fan_dict["Status"] = True if fan_dict["AirFlow"] != "Unknown" else False + fan_name = 'FAN{}_{}'.format(f_index, pos) + all_fan_dict[fan_name] = fan_dict + break + + return all_fan_dict diff --git a/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/fwmgrutil.py b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/fwmgrutil.py new file mode 100644 index 000000000000..c1fb40cebfb8 --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/fwmgrutil.py @@ -0,0 +1,882 @@ +# fwmgrutil.py +# +# Platform-specific firmware management interface for SONiC +# + +import subprocess +import requests +import os +import pexpect +import base64 +import time +import json +import logging +import ast +from datetime import datetime + +try: + from sonic_fwmgr.fwgmr_base import FwMgrUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +class FwMgrUtil(FwMgrUtilBase): + + """Platform-specific FwMgrUtil class""" + + def __init__(self): + self.platform_name = "AS1332h" + self.onie_config_file = "/host/machine.conf" + self.bmc_info_url = "http://240.1.1.1:8080/api/sys/bmc" + self.bmc_raw_command_url = "http://240.1.1.1:8080/api/sys/raw" + self.fw_upgrade_url = "http://240.1.1.1:8080/api/sys/upgrade" + self.onie_config_file = "/host/machine.conf" + self.fw_upgrade_logger_path = "/var/log/fw_upgrade.log" + self.cpldb_version_path = "/sys/devices/platform/%s.cpldb/getreg" % self.platform_name + self.fpga_version_path = "/sys/devices/platform/%s.switchboard/FPGA/getreg" % self.platform_name + self.switchboard_cpld1_path = "/sys/devices/platform/%s.switchboard/CPLD1/getreg" % self.platform_name + self.switchboard_cpld2_path = "/sys/devices/platform/%s.switchboard/CPLD2/getreg" % self.platform_name + self.switchboard_cpld3_path = "/sys/devices/platform/%s.switchboard/CPLD3/getreg" % self.platform_name + self.switchboard_cpld4_path = "/sys/devices/platform/%s.switchboard/CPLD4/getreg" % self.platform_name + self.bmc_pwd_path = "/usr/local/etc/bmcpwd" + + def __get_register_value(self, path, register): + cmd = "echo {1} > {0}; cat {0}".format(path, register) + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err is not '': + return 'None' + else: + return raw_data.strip() + + def __update_fw_upgrade_logger(self, header, message): + if not os.path.isfile(self.fw_upgrade_logger_path): + cmd = "sudo touch %s && sudo chmod +x %s" % ( + self.fw_upgrade_logger_path, self.fw_upgrade_logger_path) + subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + logging.basicConfig(filename=self.fw_upgrade_logger_path, + filemode='a', + format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s', + datefmt='%b %d %H:%M:%S', + level=logging.INFO) + + log_message = "%s : %s" % (header, message) + if header != "last_upgrade_result": + print(log_message) + return logging.info(log_message) + + def get_bmc_pass(self): + if os.path.exists(self.bmc_pwd_path): + with open(self.bmc_pwd_path) as file: + data = file.read() + + key = "bmc" + dec = [] + enc = base64.urlsafe_b64decode(data) + for i in range(len(enc)): + key_c = key[i % len(key)] + dec_c = chr((256 + ord(enc[i]) - ord(key_c)) % 256) + dec.append(dec_c) + return "".join(dec) + return False + + def get_bmc_version(self): + """Get BMC version from SONiC + :returns: version string + + """ + bmc_version = None + + bmc_version_key = "OpenBMC Version" + bmc_info_req = requests.get(self.bmc_info_url, timeout=60) + if bmc_info_req.status_code == 200: + bmc_info_json = bmc_info_req.json() + bmc_info = bmc_info_json.get('Information') + bmc_version = bmc_info.get(bmc_version_key) + return str(bmc_version) + + def upload_file_bmc(self, fw_path): + scp_command = 'sudo scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -r %s root@240.1.1.1:/home/root/' % os.path.abspath( + fw_path) + child = pexpect.spawn(scp_command) + i = child.expect(["root@240.1.1.1's password:"], timeout=30) + bmc_pwd = self.get_bmc_pass() + if i == 0 and bmc_pwd: + child.sendline(bmc_pwd) + data = child.read() + print(data) + child.close + return os.path.isfile(fw_path) + return False + + def get_cpld_version(self): + """Get CPLD version from SONiC + :returns: dict like {'CPLD_1': version_string, 'CPLD_2': version_string} + """ + + CPLD_B = self.__get_register_value(self.cpldb_version_path, '0xA100') + CPLD_C = self.__get_register_value(self.cpldb_version_path, '0xA1E0') + CPLD_1 = self.__get_register_value(self.switchboard_cpld1_path, '0x00') + CPLD_2 = self.__get_register_value(self.switchboard_cpld2_path, '0x00') + CPLD_3 = self.__get_register_value(self.switchboard_cpld3_path, '0x00') + CPLD_4 = self.__get_register_value(self.switchboard_cpld4_path, '0x00') + + fan_cpld_key = "FanCPLD Version" + fan_cpld = None + bmc_info_req = requests.get(self.bmc_info_url) + if bmc_info_req.status_code == 200: + bmc_info_json = bmc_info_req.json() + bmc_info = bmc_info_json.get('Information') + fan_cpld = bmc_info.get(fan_cpld_key) + + CPLD_B = 'None' if CPLD_B is 'None' else "{}.{}".format( + int(CPLD_B[2], 16), int(CPLD_B[3], 16)) + CPLD_C = 'None' if CPLD_C is 'None' else "{}.{}".format( + int(CPLD_C[2], 16), int(CPLD_C[3], 16)) + CPLD_1 = 'None' if CPLD_1 is 'None' else "{}.{}".format( + int(CPLD_1[2], 16), int(CPLD_1[3], 16)) + CPLD_2 = 'None' if CPLD_2 is 'None' else "{}.{}".format( + int(CPLD_2[2], 16), int(CPLD_2[3], 16)) + CPLD_3 = 'None' if CPLD_3 is 'None' else "{}.{}".format( + int(CPLD_3[2], 16), int(CPLD_3[3], 16)) + CPLD_4 = 'None' if CPLD_4 is 'None' else "{}.{}".format( + int(CPLD_4[2], 16), int(CPLD_4[3], 16)) + FAN_CPLD = 'None' if fan_cpld is None else "{}.{}".format( + int(fan_cpld[0], 16), int(fan_cpld[1], 16)) + + cpld_version_dict = {} + cpld_version_dict.update({'CPLD_B': CPLD_B}) + cpld_version_dict.update({'CPLD_C': CPLD_C}) + cpld_version_dict.update({'CPLD_1': CPLD_1}) + cpld_version_dict.update({'CPLD_2': CPLD_2}) + cpld_version_dict.update({'CPLD_3': CPLD_3}) + cpld_version_dict.update({'CPLD_4': CPLD_4}) + cpld_version_dict.update({'CPLD_FAN': FAN_CPLD}) + + return cpld_version_dict + + def get_bios_version(self): + """Get BIOS version from SONiC + :returns: version string + + """ + bios_version = None + + p = subprocess.Popen( + ["sudo", "dmidecode", "-s", "bios-version"], stdout=subprocess.PIPE) + raw_data = str(p.communicate()[0]) + if raw_data == '': + return str(None) + raw_data_list = raw_data.split("\n") + bios_version = raw_data_list[0] if len( + raw_data_list) == 1 else raw_data_list[-2] + + return str(bios_version) + + def get_onie_version(self): + """Get ONiE version from SONiC + :returns: version string + + """ + onie_verison = None + + onie_version_keys = "onie_version" + onie_config_file = open(self.onie_config_file, "r") + for line in onie_config_file.readlines(): + if onie_version_keys in line: + onie_version_raw = line.split('=') + onie_verison = onie_version_raw[1].strip() + break + onie_config_file.close() + return str(onie_verison) + + def get_pcie_version(self): + """Get PCiE version from SONiC + :returns: version dict { "PCIE_FW_LOADER": "2.5", "PCIE_FW": "D102_08" } + + """ + cmd = "sudo bcmcmd 'pciephy fw version'" + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + + pcie_version = dict() + pcie_version["PCIE_FW_LOADER"] = 'None' + pcie_version["PCIE_FW"] = 'None' + + if err == '': + lines = raw_data.split('\n') + for line in lines: + if 'PCIe FW loader' in line: + pcie_version["PCIE_FW_LOADER"] = line.split(':')[1].strip() + elif 'PCIe FW version' in line: + pcie_version["PCIE_FW"] = line.split(':')[1].strip() + return pcie_version + + def get_fpga_version(self): + """Get FPGA version from SONiC + :returns: version string + + """ + version = self.__get_register_value(self.fpga_version_path, '0x00') + if version is not 'None': + version = "{}.{}".format( + int(version[2:][:4], 16), int(version[2:][4:], 16)) + return str(version) + + def firmware_upgrade(self, fw_type, fw_path, fw_extra=None): + """ + @fw_type MANDATORY, firmware type, should be one of the strings: 'cpld', 'fpga', 'bios', 'bmc' + @fw_path MANDATORY, target firmware file + @fw_extra OPTIONAL, extra information string, + + for fw_type 'cpld' and 'fpga': it can be used to indicate specific cpld, such as 'cpld1', 'cpld2', ... + or 'cpld_fan_come_board', etc. If None, upgrade all CPLD/FPGA firmware. for fw_type 'bios' and 'bmc', + value should be one of 'master' or 'slave' or 'both' + """ + fw_type = fw_type.lower() + bmc_pwd = self.get_bmc_pass() + if not bmc_pwd and fw_type != "fpga": + self.__update_fw_upgrade_logger( + "fw_upgrade", "fail, message=BMC credential not found") + return False + + if fw_type == 'bmc': + self.__update_fw_upgrade_logger( + "bmc_upgrade", "start BMC upgrade") + # Copy BMC image file to BMC + fw_extra_str = str(fw_extra).lower() + last_fw_upgrade = ["BMC", fw_path, fw_extra_str, "FAILED"] + upload_file = self.upload_file_bmc(fw_path) + if not upload_file: + self.__update_fw_upgrade_logger( + "fw_upgrade", "fail, message=unable to upload BMC image to BMC") + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return False + + filename_w_ext = os.path.basename(fw_path) + json_data = dict() + json_data["path"] = "root@127.0.0.1:/home/root/%s" % filename_w_ext + json_data["password"] = bmc_pwd + + # Set flash type + current_bmc = self.get_running_bmc() + flash = fw_extra_str if fw_extra_str in [ + "master", "slave", "both"] else "both" + if fw_extra_str == "pingpong": + # flash = "master" if current_bmc == "slave" else "slave" + flash = "slave" + json_data["flash"] = flash + + # Install BMC + if flash == "both": + self.__update_fw_upgrade_logger( + "bmc_upgrade", "install BMC as master mode") + json_data["flash"] = "master" + r = requests.post(self.bmc_info_url, json=json_data) + if r.status_code != 200 or 'success' not in r.json().get('result'): + self.__update_fw_upgrade_logger( + "bmc_upgrade", "fail, message=BMC API report error code %d" % r.status_code) + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return False + json_data["flash"] = "slave" + + self.__update_fw_upgrade_logger( + "bmc_upgrade", "install BMC as %s mode" % json_data["flash"]) + r = requests.post(self.bmc_info_url, json=json_data) + if r.status_code == 200 and 'success' in r.json().get('result'): + if fw_extra_str == "pingpong": + flash = "master" if current_bmc == "slave" else "slave" + self.__update_fw_upgrade_logger( + "bmc_upgrade", "switch to boot from %s" % flash) + self.set_bmc_boot_flash(flash) + self.__update_fw_upgrade_logger( + "bmc_upgrade", "reboot BMC") + if not self.reboot_bmc(): + return False + else: + self.__update_fw_upgrade_logger( + "bmc_upgrade", "reboot BMC") + reboot_dict = {} + reboot_dict["reboot"] = "yes" + r = requests.post(self.bmc_info_url, json=reboot_dict) + last_fw_upgrade[3] = "DONE" + else: + self.__update_fw_upgrade_logger( + "bmc_upgrade", "fail, message=unable to install BMC image") + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return False + + self.__update_fw_upgrade_logger( + "bmc_upgrade", "done") + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return True + + elif fw_type == 'fpga': + last_fw_upgrade = ["FPGA", fw_path, None, "FAILED"] + self.__update_fw_upgrade_logger( + "fpga_upgrade", "start FPGA upgrade") + + if not os.path.isfile(fw_path): + self.__update_fw_upgrade_logger( + "fpga_upgrade", "fail, message=FPGA image not found %s" % fw_path) + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return False + + command = 'fpga_prog ' + fw_path + print("Running command : %s" % command) + process = subprocess.Popen( + command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + while True: + output = process.stdout.readline() + if output == '' and process.poll() is not None: + break + + rc = process.returncode + if rc != 0: + self.__update_fw_upgrade_logger( + "fw_upgrade", "fail, message=unable to install FPGA") + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return False + + self.__update_fw_upgrade_logger("fpga_upgrade", "done") + last_fw_upgrade[3] = "DONE" + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + self.firmware_refresh(["FPGA"], None, None) + return True + + elif 'cpld' in fw_type: + self.__update_fw_upgrade_logger( + "cpld_upgrade", "start CPLD upgrade") + # Check input + fw_extra_str = str(fw_extra).upper() + if ":" in fw_path and ":" in fw_extra_str: + fw_path_list = fw_path.split(":") + fw_extra_str_list = fw_extra_str.split(":") + else: + fw_path_list = [fw_path] + fw_extra_str_list = [fw_extra_str] + + if len(fw_path_list) != len(fw_extra_str_list): + self.__update_fw_upgrade_logger( + "cpld_upgrade", "fail, message=invalid input") + return False + + data_list = list(zip(fw_path_list, fw_extra_str_list)) + refresh_img_path = None + cpld_result_list = ["FAILED" for i in range( + 0, len(fw_extra_str_list))] + last_fw_upgrade = ["CPLD", ":".join( + fw_path_list), ":".join(fw_extra_str_list), ":".join(cpld_result_list)] + for i in range(0, len(data_list)): + data = data_list[i] + fw_path = data[0] + fw_extra_str = data[1] + + # Set fw_extra + fw_extra_str = { + "TOP_LC_CPLD": "top_lc", + "BOT_LC_CPLD": "bottom_lc", + "FAN_CPLD": "fan", + "CPU_CPLD": "cpu", + "BASE_CPLD": "base", + "COMBO_CPLD": "combo", + "SW_CPLD1": "switch", + "SW_CPLD2": "switch", + "REFRESH_CPLD": "refresh" + }.get(fw_extra_str, None) + + if fw_extra_str == "refresh": + refresh_img_path = fw_path + del cpld_result_list[i] + del fw_extra_str_list[i] + continue + + if fw_extra_str is None: + self.__update_fw_upgrade_logger( + "cpld_upgrade", "fail, message=invalid extra information string") + continue + + # Uploading image to BMC + self.__update_fw_upgrade_logger( + "cpld_upgrade", "start %s upgrade" % data[1]) + upload_file = self.upload_file_bmc(fw_path) + if not upload_file: + self.__update_fw_upgrade_logger( + "cpld_upgrade", "fail, message=unable to upload BMC image to BMC") + continue + + filename_w_ext = os.path.basename(fw_path) + json_data = dict() + json_data["image_path"] = "root@127.0.0.1:/home/root/%s" % filename_w_ext + json_data["password"] = bmc_pwd + json_data["device"] = "cpld" + json_data["reboot"] = "no" + json_data["type"] = fw_extra_str + + # Call BMC api to install cpld image + print("Installing...") + r = requests.post(self.fw_upgrade_url, json=json_data) + if r.status_code != 200 or 'success' not in r.json().get('result'): + self.__update_fw_upgrade_logger( + "cpld_upgrade", "fail, message=invalid cpld image") + continue + + cpld_result_list[i] = "DONE" + self.__update_fw_upgrade_logger( + "cpld_upgrade", "%s upgrade done" % data[1]) + last_fw_upgrade[3] = ":".join(cpld_result_list) + self.__update_fw_upgrade_logger( + "cpld_upgrade", "done") + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + + # Refresh CPLD + refresh_img_str_list = [] + for fw_extra in fw_extra_str_list: + if "BASE_CPLD" in fw_extra or "FAN_CPLD" in fw_extra: + refresh_img_str_list.append(refresh_img_path) + else: + refresh_img_str_list.append("None") + self.firmware_refresh(None, fw_extra_str_list, + ":".join(refresh_img_str_list)) + + return True + + elif 'bios' in fw_type: + self.__update_fw_upgrade_logger( + "bios_upgrade", "start BIOS upgrade") + last_fw_upgrade = ["BIOS", fw_path, None, "FAILED"] + fw_extra_str = str(fw_extra).lower() + flash = fw_extra_str if fw_extra_str in [ + "master", "slave"] else "master" + + if not os.path.exists(fw_path): + self.__update_fw_upgrade_logger( + "bios_upgrade", "fail, message=image not found") + return False + + scp_command = 'sudo scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -r %s root@240.1.1.1:/home/root/' % os.path.abspath( + fw_path) + child = pexpect.spawn(scp_command) + i = child.expect(["root@240.1.1.1's password:"], timeout=30) + if i != 0: + self.__update_fw_upgrade_logger( + "bios_upgrade", "fail, message=unable to upload image to BMC") + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return False + + child.sendline(bmc_pwd) + data = child.read() + print(data) + child.close + + json_data = dict() + json_data["data"] = "/usr/bin/ipmitool -b 1 -t 0x2c raw 0x2e 0xdf 0x57 0x01 0x00 0x01" + r = requests.post(self.bmc_raw_command_url, json=json_data) + if r.status_code != 200: + self.__update_fw_upgrade_logger( + "bios_upgrade", "fail, message=unable to set state") + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return False + + filename_w_ext = os.path.basename(fw_path) + json_data = dict() + json_data["image_path"] = "root@127.0.0.1:/home/root/%s" % filename_w_ext + json_data["password"] = bmc_pwd + json_data["device"] = "bios" + json_data["flash"] = flash + json_data["reboot"] = "no" + + print("Installing...") + r = requests.post(self.fw_upgrade_url, json=json_data) + if r.status_code != 200 or 'success' not in r.json().get('result'): + self.__update_fw_upgrade_logger( + "bios_upgrade", "fail, message=unable install bios") + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return False + + last_fw_upgrade[3] = "DONE" + self.__update_fw_upgrade_logger( + "bios_upgrade", "done") + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + else: + self.__update_fw_upgrade_logger( + "fw_upgrade", "fail, message=invalid firmware type") + return False + + return True + + def get_last_upgrade_result(self): + """ + Get last firmware upgrade information, inlcudes: + 1) FwType: cpld/fpga/bios/bmc(passed by method 'firmware_upgrade'), string + 2) FwPath: path and file name of firmware(passed by method 'firmware_upgrade'), string + 3) FwExtra: designated string, econdings of this string is determined by vendor(passed by method 'firmware_program') + 4) Result: indicates whether the upgrade action is performed and success/failure status if performed. Values should be one of: "DONE"/"FAILED"/"NOT_PERFORMED". + list of object: + [ + { + "FwType": "cpld", + "FwPath": "cpu_cpld.vme" + "FwExtra":"CPU_CPLD" + "Result": "DONE" + }, + { + "FwType": "cpld", + "FwPath": "fan_cpld.vme" + "FwExtra": "FAN_CPLD" + "Result": "FAILED" + } + ] + """ + last_update_list = [] + + if os.path.exists(self.fw_upgrade_logger_path): + with open(self.fw_upgrade_logger_path, 'r') as file: + lines = file.read().splitlines() + + upgrade_txt = [i for i in reversed( + lines) if "last_upgrade_result" in i] + if len(upgrade_txt) > 0: + last_upgrade_txt = upgrade_txt[0].split( + "last_upgrade_result : ") + last_upgrade_list = ast.literal_eval(last_upgrade_txt[1]) + for x in range(0, len(last_upgrade_list[1].split(":"))): + upgrade_dict = {} + upgrade_dict["FwType"] = last_upgrade_list[0].lower() + upgrade_dict["FwPath"] = last_upgrade_list[1].split(":")[x] + upgrade_dict["FwExtra"] = last_upgrade_list[2].split(":")[ + x] if last_upgrade_list[2] else "None" + upgrade_dict["Result"] = last_upgrade_list[3].split(":")[x] + last_update_list.append(upgrade_dict) + + return last_update_list + + def firmware_program(self, fw_type, fw_path, fw_extra=None): + """ + Program FPGA and/or CPLD firmware only, but do not refresh them + + @param fw_type value can be: FPGA, CPLD + @param fw_path a string of firmware file path, seperated by ':', it should + match the sequence of param @fw_type + @param fw_extra a string of firmware subtype, i.e CPU_CPLD, BOARD_CPLD, + FAN_CPLD, LC_CPLD, etc. Subtypes are seperated by ':' + @return True when all required firmware is program succefully, + False otherwise. + + Example: + self.firmware_program("CPLD", "/cpu_cpld.vme:/lc_cpld", \ + "CPU_CPLD:LC_CPLD") + or + self.firmware_program("FPGA", "/fpga.bin") + """ + fw_type = fw_type.lower() + bmc_pwd = self.get_bmc_pass() + if not bmc_pwd and fw_type != "fpga": + self.__update_fw_upgrade_logger( + "fw_upgrade", "fail, message=BMC credential not found") + return False + + if fw_type == 'fpga': + last_fw_upgrade = ["FPGA", fw_path, None, "FAILED"] + self.__update_fw_upgrade_logger( + "fpga_upgrade", "start FPGA upgrade") + + if not os.path.isfile(fw_path): + self.__update_fw_upgrade_logger( + "fpga_upgrade", "fail, message=FPGA image not found %s" % fw_path) + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return False + + command = 'fpga_prog ' + fw_path + print("Running command: %s" % command) + process = subprocess.Popen( + command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + while True: + output = process.stdout.readline() + if output == '' and process.poll() is not None: + break + + rc = process.returncode + if rc != 0: + self.__update_fw_upgrade_logger( + "fw_upgrade", "fail, message=Unable to install FPGA") + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return False + + self.__update_fw_upgrade_logger("fpga_upgrade", "done") + last_fw_upgrade[3] = "DONE" + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return True + + elif 'cpld' in fw_type: + self.__update_fw_upgrade_logger( + "cpld_upgrade", "start CPLD upgrade") + + # Check input + fw_extra_str = str(fw_extra).upper() + if ":" in fw_path and ":" in fw_extra_str: + fw_path_list = fw_path.split(":") + fw_extra_str_list = fw_extra_str.split(":") + else: + fw_path_list = [fw_path] + fw_extra_str_list = [fw_extra_str] + + if len(fw_path_list) != len(fw_extra_str_list): + self.__update_fw_upgrade_logger( + "cpld_upgrade", "fail, message=Invalid input") + return False + + cpld_result_list = [] + data_list = list(zip(fw_path_list, fw_extra_str_list)) + for data in data_list: + fw_path = data[0] + fw_extra_str = data[1] + + # Set fw_extra + fw_extra_str = { + "TOP_LC_CPLD": "top_lc", + "BOT_LC_CPLD": "bottom_lc", + "FAN_CPLD": "fan", + "CPU_CPLD": "cpu", + "BASE_CPLD": "base", + "COMBO_CPLD": "combo", + "SW_CPLD1": "switch", + "SW_CPLD2": "switch" + }.get(fw_extra_str, None) + + self.__update_fw_upgrade_logger( + "cpld_upgrade", "start %s upgrade" % data[1]) + upgrade_result = "FAILED" + for x in range(1, 4): + # Set fw_extra + if x > 1: + self.__update_fw_upgrade_logger( + "cpld_upgrade", "fail, message=Retry to upgrade %s" % data[1]) + + elif fw_extra_str is None: + self.__update_fw_upgrade_logger( + "cpld_upgrade", "fail, message=Invalid extra information string %s" % data[1]) + break + elif not os.path.isfile(os.path.abspath(fw_path)): + self.__update_fw_upgrade_logger( + "cpld_upgrade", "fail, message=CPLD image not found %s" % fw_path) + break + + # Install cpld image via ispvm tool + print("Installing...") + command = 'ispvm %s' % fw_path + if fw_extra_str in ["top_lc", "bottom_lc"]: + option = 1 if fw_extra_str == "top_lc" else 2 + command = "ispvm -c %d %s" % (option, + os.path.abspath(fw_path)) + print("Running command : %s" % command) + process = subprocess.Popen( + command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + while True: + output = process.stdout.readline() + if output == '' and process.poll() is not None: + break + + rc = process.returncode + if rc != 0: + self.__update_fw_upgrade_logger( + "cpld_upgrade", "fail, message=Unable to install CPLD") + continue + + upgrade_result = "DONE" + self.__update_fw_upgrade_logger("cpld_upgrade", "done") + break + cpld_result_list.append(upgrade_result) + + last_fw_upgrade = ["CPLD", ":".join( + fw_path_list), ":".join(fw_extra_str_list), ":".join(cpld_result_list)] + self.__update_fw_upgrade_logger( + "last_upgrade_result", str(last_fw_upgrade)) + return "FAILED" not in cpld_result_list + else: + self.__update_fw_upgrade_logger( + "fw_upgrade", "fail, message=Invalid firmware type") + return False + + return True + + def firmware_refresh(self, fpga_list, cpld_list, fw_extra=None): + """ + Refresh firmware and take extra action when necessary. + @param fpga_list a list of FPGA names + @param cpld_list a list of CPLD names + @return True if refresh succefully and no power cycle action is taken. + + @Note extra action should be: power cycle the whole system(except BMC) when + CPU_CPLD or BOARD_CPLD or FPGA is refreshed. + No operation if the power cycle is not needed. + + Example: + self.firmware_refresh( + ["FPGA"], ["BASE_CPLD", "LC_CPLD"],"/tmp/fw/refresh.vme") + or + self.firmware_refresh(["FPGA"], None, None) + or + self.firmware_refresh(None, ["FAN_CPLD", "LC1_CPLD", "BASE_CPLD"], + "/tmp/fw/fan_refresh.vme:none:/tmp/fw/base_refresh.vme") + """ + + if not fpga_list and not cpld_list: + return False + + if type(cpld_list) is list and ("BASE_CPLD" in cpld_list or "FAN_CPLD" in cpld_list): + refresh_list = fpga_list + \ + cpld_list if type(fpga_list) is list else cpld_list + self.__update_fw_upgrade_logger( + "fw_refresh", "start %s refresh" % ",".join(refresh_list)) + fw_path_list = fw_extra.split(':') + command = "echo " + if len(fw_path_list) != len(cpld_list): + self.__update_fw_upgrade_logger( + "cpld_refresh", "fail, message=Invalid fw_extra") + return False + + for idx in range(0, len(cpld_list)): + fw_path = fw_path_list[idx] + refresh_type = { + "BASE_CPLD": "base", + "FAN_CPLD": "fan" + }.get(cpld_list[idx], None) + + if not refresh_type: + continue + elif not self.upload_file_bmc(fw_path): + self.__update_fw_upgrade_logger( + "cpld_refresh", "fail, message=Unable to upload refresh image to BMC") + return False + else: + filename_w_ext = os.path.basename(fw_path) + + sub_command = "%s /home/root/%s > /tmp/cpld_refresh " % ( + refresh_type, filename_w_ext) + command += sub_command + + json_data = dict() + json_data["data"] = command + r = requests.post(self.bmc_raw_command_url, json=json_data) + if r.status_code != 200: + self.__update_fw_upgrade_logger( + "cpld_refresh", "fail, message=%d Invalid refresh image" % r.status_code) + return False + elif type(cpld_list) is list: + refresh_list = fpga_list + \ + cpld_list if type(fpga_list) is list else cpld_list + self.__update_fw_upgrade_logger( + "fw_refresh", "start %s refresh" % ",".join(refresh_list)) + json_data = dict() + json_data["data"] = "echo cpu_cpld > /tmp/cpld_refresh" + r = requests.post(self.bmc_raw_command_url, json=json_data) + if r.status_code != 200: + self.__update_fw_upgrade_logger( + "cpld_refresh", "fail, message=%d Unable to load new CPLD" % r.status_code) + return False + elif type(fpga_list) is list: + self.__update_fw_upgrade_logger( + "fw_refresh", "start FPGA refresh") + json_data = dict() + json_data["data"] = "echo fpga > /tmp/cpld_refresh" + r = requests.post(self.bmc_raw_command_url, json=json_data) + if r.status_code != 200: + self.__update_fw_upgrade_logger( + "cpld_refresh", "fail, message=%d Unable to load new FPGA" % r.status_code) + return False + else: + self.__update_fw_upgrade_logger( + "fw_refresh", "fail, message=Invalid input") + return False + + self.__update_fw_upgrade_logger("fw_refresh", "done") + return True + + def get_running_bmc(self): + """ + Get booting flash of running BMC. + @return a string, "master" or "slave" + """ + json_data = dict() + json_data["data"] = "/usr/local/bin/boot_info.sh" + r = requests.post(self.bmc_raw_command_url, json=json_data) + try: + boot_info_list = r.json().get('result') + for boot_info_raw in boot_info_list: + boot_info = boot_info_raw.split(":") + if "Current Boot Code Source" in boot_info[0]: + flash = "master" if "master "in boot_info[1].lower( + ) else "slave" + return flash + raise Exception( + "Error: Unable to detect booting flash of running BMC") + except Exception as e: + raise Exception(e) + + def set_bmc_boot_flash(self, flash): + """ + Set booting flash of BMC + @param flash should be "master" or "slave" + """ + if flash.lower() not in ["master", "slave"]: + return False + json_data = dict() + json_data["data"] = "source /usr/local/bin/openbmc-utils.sh;bmc_reboot %s" % flash + r = requests.post(self.bmc_raw_command_url, json=json_data) + if r.status_code != 200: + return False + return True + + def reboot_bmc(self): + """ + Reboot BMC + """ + json_data = dict() + json_data["data"] = "source /usr/local/bin/openbmc-utils.sh;bmc_reboot reboot" + r = requests.post(self.bmc_raw_command_url, json=json_data) + if r.status_code != 200: + return False + return True + + def get_current_bios(self): + """ + # Get booting bios image of current running host OS + # @return a string, "master" or "slave" + """ + json_data = dict() + json_data["data"] = "source /usr/local/bin/openbmc-utils.sh;come_boot_info" + r = requests.post(self.bmc_raw_command_url, json=json_data) + try: + cpu_boot_info_list = r.json().get('result') + for cpu_boot_info_raw in cpu_boot_info_list: + if "COMe CPU boots from BIOS" in cpu_boot_info_raw: + bios_image = "master" if "master "in cpu_boot_info_raw.lower( + ) else "slave" + return bios_image + raise Exception( + "Error: Unable to detect current running bios image") + except Exception as e: + raise Exception(e) diff --git a/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/optictemputil.py b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/optictemputil.py new file mode 100644 index 000000000000..0e5b6a1c7109 --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/optictemputil.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python + +# +# optictemputil.py +# +# Platform-specific Optic module temperature Interface for SONiC +# + +__author__ = 'Pradchaya P.' +__author__ = 'Wirut G.' +__license__ = "GPL" +__version__ = "1.0.0" +__status__ = "Development" + +import os +import sys +import binascii +import subprocess + +class OpticTempUtil(): + """Platform-specific OpticTempUtil class""" + + def __init__(self): + pass + + def read_eeprom_specific_bytes(self, sysfsfile_eeprom, offset, num_bytes): + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + try: + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + except IOError: + return None + + try: + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except: + return None + + return eeprom_raw + + + def twos_comp(self, num, bits): + try: + if ((num & (1 << (bits - 1))) != 0): + num = num - (1 << bits) + return num + except: + return 0 + + + def calc_temperature(self, cal_type, eeprom_data, offset, size): + + msb = int(eeprom_data[offset], 16) + lsb = int(eeprom_data[offset + 1], 16) + + result = (msb << 8) | (lsb & 0xff) + result = self.twos_comp(result, 16) + + if cal_type == 1: + # Internal calibration + result = float(result / 256.0) + retval = '%.4f' %result + + # TODO: Should support external calibration in future. + else: + retval = 0 + + return retval + + ''' TODO: Change busnum to sysfs_sfp_i2c_client_eeprom_path from caller!!! + ''' + def get_optic_temp(self, sysfs_sfp_i2c_client_eeprom_path, port_type): + + EEPROM_ADDR = 0x50 + DOM_ADDR = 0x51 + EEPROM_OFFSET = 0 + DOM_OFFSET = 256 + + SFP_DMT_ADDR = 92 + SFP_DMT_WIDTH = 1 + SFP_TEMP_DATA_ADDR = 96 + SFP_TEMP_DATA_WIDTH = 2 + + QSFP_TEMP_DATA_ADDR = 22 + QSFP_TEMP_DATA_WIDTH = 2 + temperature_raw = None + + + ''' Open file here ''' + try: + sysfsfile_eeprom = open(sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % sysfs_sfp_i2c_client_eeprom_path) + return 0 + + if port_type == 'QSFP': + + # QSFP only have internal calibration mode. + cal_type = 1 + # read temperature raw value + temperature_raw = self.read_eeprom_specific_bytes(sysfsfile_eeprom,(EEPROM_OFFSET+QSFP_TEMP_DATA_ADDR),QSFP_TEMP_DATA_WIDTH) + else: + # read calibration type at bit 5 + cal_type = self.read_eeprom_specific_bytes(sysfsfile_eeprom,EEPROM_OFFSET+SFP_DMT_ADDR,SFP_DMT_WIDTH) + if cal_type is None: + return 0 + else: + cal_type = (int(cal_type[0],16) >> 5 ) & 1 + # read temperature raw value + temperature_raw = self.read_eeprom_specific_bytes(sysfsfile_eeprom,(DOM_OFFSET+SFP_TEMP_DATA_ADDR),SFP_TEMP_DATA_WIDTH) + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return 0 + + #calculate temperature + if temperature_raw is not None: + return self.calc_temperature(cal_type, temperature_raw, 0, 2) + else: + return 0 \ No newline at end of file diff --git a/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/optictemputil_lp.py b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/optictemputil_lp.py new file mode 100644 index 000000000000..0e5b6a1c7109 --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/optictemputil_lp.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python + +# +# optictemputil.py +# +# Platform-specific Optic module temperature Interface for SONiC +# + +__author__ = 'Pradchaya P.' +__author__ = 'Wirut G.' +__license__ = "GPL" +__version__ = "1.0.0" +__status__ = "Development" + +import os +import sys +import binascii +import subprocess + +class OpticTempUtil(): + """Platform-specific OpticTempUtil class""" + + def __init__(self): + pass + + def read_eeprom_specific_bytes(self, sysfsfile_eeprom, offset, num_bytes): + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + try: + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + except IOError: + return None + + try: + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except: + return None + + return eeprom_raw + + + def twos_comp(self, num, bits): + try: + if ((num & (1 << (bits - 1))) != 0): + num = num - (1 << bits) + return num + except: + return 0 + + + def calc_temperature(self, cal_type, eeprom_data, offset, size): + + msb = int(eeprom_data[offset], 16) + lsb = int(eeprom_data[offset + 1], 16) + + result = (msb << 8) | (lsb & 0xff) + result = self.twos_comp(result, 16) + + if cal_type == 1: + # Internal calibration + result = float(result / 256.0) + retval = '%.4f' %result + + # TODO: Should support external calibration in future. + else: + retval = 0 + + return retval + + ''' TODO: Change busnum to sysfs_sfp_i2c_client_eeprom_path from caller!!! + ''' + def get_optic_temp(self, sysfs_sfp_i2c_client_eeprom_path, port_type): + + EEPROM_ADDR = 0x50 + DOM_ADDR = 0x51 + EEPROM_OFFSET = 0 + DOM_OFFSET = 256 + + SFP_DMT_ADDR = 92 + SFP_DMT_WIDTH = 1 + SFP_TEMP_DATA_ADDR = 96 + SFP_TEMP_DATA_WIDTH = 2 + + QSFP_TEMP_DATA_ADDR = 22 + QSFP_TEMP_DATA_WIDTH = 2 + temperature_raw = None + + + ''' Open file here ''' + try: + sysfsfile_eeprom = open(sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % sysfs_sfp_i2c_client_eeprom_path) + return 0 + + if port_type == 'QSFP': + + # QSFP only have internal calibration mode. + cal_type = 1 + # read temperature raw value + temperature_raw = self.read_eeprom_specific_bytes(sysfsfile_eeprom,(EEPROM_OFFSET+QSFP_TEMP_DATA_ADDR),QSFP_TEMP_DATA_WIDTH) + else: + # read calibration type at bit 5 + cal_type = self.read_eeprom_specific_bytes(sysfsfile_eeprom,EEPROM_OFFSET+SFP_DMT_ADDR,SFP_DMT_WIDTH) + if cal_type is None: + return 0 + else: + cal_type = (int(cal_type[0],16) >> 5 ) & 1 + # read temperature raw value + temperature_raw = self.read_eeprom_specific_bytes(sysfsfile_eeprom,(DOM_OFFSET+SFP_TEMP_DATA_ADDR),SFP_TEMP_DATA_WIDTH) + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return 0 + + #calculate temperature + if temperature_raw is not None: + return self.calc_temperature(cal_type, temperature_raw, 0, 2) + else: + return 0 \ No newline at end of file diff --git a/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/optictemputil_rl.py b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/optictemputil_rl.py new file mode 100644 index 000000000000..9f679799aeec --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/optictemputil_rl.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python + +# +# optictemputil.py +# +# Platform-specific Optic module temperature Interface for SONiC +# + +__author__ = 'Pradchaya P.' +__author__ = 'Wirut G.' +__license__ = "GPL" +__version__ = "1.0.0" +__status__ = "Development" + +import os +import sys +import binascii +import subprocess + +class OpticTempUtil(): + """Platform-specific OpticTempUtil class""" + + def __init__(self): + pass + + def read_eeprom_specific_bytes(self, sysfsfile_eeprom, offset, num_bytes): + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + try: + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + except IOError: + return None + + try: + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except: + return None + + return eeprom_raw + + + def twos_comp(self, num, bits): + try: + if ((num & (1 << (bits - 1))) != 0): + num = num - (1 << bits) + return num + except: + return 0 + + + def calc_temperature(self, cal_type, eeprom_data, offset, size): + + msb = int(eeprom_data[offset], 16) + lsb = int(eeprom_data[offset + 1], 16) + + thousand_digit_int = (msb >> 4) & 0x0f + hundred_digit_int = msb & 0x0f + tens_digit_int = (lsb >> 4) & 0x0f + single_digit_int = lsb & 0x0f + + result = thousand_digit_int * 16 * 16 * 16 + hundred_digit_int * 16 * 16 + + tens_digit_int * 16 + single_digit_int + + #result = self.twos_comp(result, 16) + + if cal_type == 1: + # Internal calibration + result = float(result / 256.0) + retval = '%.4f' %result + + # TODO: Should support external calibration in future. + else: + retval = 0 + + return retval + + ''' TODO: Change busnum to sysfs_sfp_i2c_client_eeprom_path from caller!!! + ''' + def get_optic_temp(self, sysfs_sfp_i2c_client_eeprom_path, port_type): + + EEPROM_ADDR = 0x50 + DOM_ADDR = 0x51 + EEPROM_OFFSET = 0 + DOM_OFFSET = 256 + + SFP_DMT_ADDR = 92 + SFP_DMT_WIDTH = 1 + SFP_TEMP_DATA_ADDR = 96 + SFP_TEMP_DATA_WIDTH = 2 + + QSFP_TEMP_DATA_ADDR = 14 + QSFP_TEMP_DATA_WIDTH = 2 + temperature_raw = None + + + ''' Open file here ''' + try: + sysfsfile_eeprom = open(sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % sysfs_sfp_i2c_client_eeprom_path) + return 0 + + if port_type == 'QSFP': + + # QSFP only have internal calibration mode. + cal_type = 1 + # read temperature raw value + temperature_raw = self.read_eeprom_specific_bytes(sysfsfile_eeprom,(EEPROM_OFFSET+QSFP_TEMP_DATA_ADDR),QSFP_TEMP_DATA_WIDTH) + else: + # read calibration type at bit 5 + cal_type = self.read_eeprom_specific_bytes(sysfsfile_eeprom,EEPROM_OFFSET+SFP_DMT_ADDR,SFP_DMT_WIDTH) + if cal_type is None: + return 0 + else: + cal_type = (int(cal_type[0],16) >> 5 ) & 1 + # read temperature raw value + temperature_raw = self.read_eeprom_specific_bytes(sysfsfile_eeprom,(DOM_OFFSET+SFP_TEMP_DATA_ADDR),SFP_TEMP_DATA_WIDTH) + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return 0 + + #calculate temperature + if temperature_raw is not None: + return self.calc_temperature(cal_type, temperature_raw, 0, 2) + else: + return 0 diff --git a/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/psuutil.py b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/psuutil.py new file mode 100644 index 000000000000..d3a27117f5a2 --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/psuutil.py @@ -0,0 +1,248 @@ +#!/usr/bin/env python + +__author__ = 'Wirut G.' +__license__ = "GPL" +__version__ = "0.1.4" +__status__ = "Development" + +import requests +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): + PsuBase.__init__(self) + self.fru_status_url = "http://240.1.1.1:8080/api/sys/fruid/status" + self.psu_info_url = "http://240.1.1.1:8080/api/sys/fruid/psu" + + self.fru_status_list = None + self.psu_info_list = None + + def request_data(self): + # Reqest data from BMC if not exist. + if self.fru_status_list is None or self.psu_info_list is None: + fru_status_req = requests.get(self.fru_status_url) + psu_info_req = requests.get(self.psu_info_url) + fru_status_json = fru_status_req.json() + psu_info_json = psu_info_req.json() + self.fru_status_list = fru_status_json.get('Information') + self.psu_info_list = psu_info_json.get('Information') + return self.fru_status_list, self.psu_info_list + + def airflow_selector(self, pn): + # Set airflow type + pn = pn.upper() + if "DPS-1100FB" in pn: + airflow = "FTOB" + elif "DPS-1100AB" in pn: + airflow = "BTOF" + elif "FSJ026-A20G" in pn: + airflow = "FTOB" + elif "FSJ038-A20G" in pn: + airflow = "BTOF" + else: + airflow = "Unknown" + return airflow + + 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 + """ + + num_psus = 2 + + return num_psus + + 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 + """ + + # init data + psu_key = "PSU" + str(index) + psu_status_key = "Power Status" + psu_power_status = False + + try: + # Request and validate sensor's information + self.fru_status_list, self.psu_info_list = self.request_data() + + # Get PSU power status. + for fru_status in self.fru_status_list: + is_psu = fru_status.get(psu_key) + psu_status = str(fru_status.get(psu_status_key)).strip() + + if is_psu is not None and psu_status == "OK": + psu_power_status = True + + except: + print("Error: Unable to access PSU power status") + return False + + return psu_power_status + + 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 + """ + + # Init data + psu_key = "PSU" + str(index) + psu_presence_key = "Present" + psu_presence_status = False + + try: + # Request and validate sensor's information. + self.fru_status_list, self.psu_info_list = self.request_data() + + # Get PSU present status. + for fru_status in self.fru_status_list: + is_psu = fru_status.get(psu_key) + psu_status = str(fru_status.get(psu_presence_key)).strip() + + if is_psu is not None and psu_status == "Present": + psu_presence_status = True + + except: + print("Error: Unable to access PSU presence status") + return False + + return psu_presence_status + + def get_psu_sn(self, index): + """ + Get the serial number of the psu, + + :param index: An integer, 1-based index of the PSU. + :return: Serial number + """ + serial_number = "N/A" + psu_key = "PSU" + str(index) + " FRU" + psu_sn_key = "Serial Number" + + try: + # Request and validate sensor's information. + self.fru_status_list, self.psu_info_list = self.request_data() + + # Get PSU fru info. + for psu_fru in self.psu_info_list: + psu_sn = str(psu_fru.get(psu_sn_key)).strip() + if psu_fru.get(psu_key) is not None: + serial_number = psu_sn if psu_sn.strip() != "" else "N/A" + break + + except: + return "N/A" + + return serial_number + + def get_psu_pn(self, index): + """ + Get the product name of the psu + + :param index: An integer, 1-based index of the PSU. + :return: Product name + """ + product_name = "N/A" + psu_key = "PSU" + str(index) + " FRU" + psu_pn_key = "Product Name" + + try: + # Request and validate sensor's information + self.fru_status_list, self.psu_info_list = self.request_data() + + # Get PSU fru info. + for psu_fru in self.psu_info_list: + psu_pn = str(psu_fru.get(psu_pn_key)).strip() + if psu_fru.get(psu_key) is not None: + product_name = psu_pn if psu_pn.strip() != "" else "N/A" + break + + except: + return "N/A" + + return product_name + + def get_all(self): + """ + Number: mandatory, max number of PSU, integer + PSU1, PSU2, ...: mandatory, PSU name, string + Present: mandatory for each PSU, present status, boolean, True for present, False for NOT present + PowerStatus: conditional, if PRESENT is True, power status of PSU,boolean, True for powered, False for NOT powered + PN, conditional, if PRESENT is True, PN of the PSU, string + SN, conditional, if PRESENT is True, SN of the PSU, string + """ + + # Init data + all_psu_dict = dict() + all_psu_dict["Number"] = self.get_num_psus() + psu_sn_key_1 = "Serial Number" + psu_sn_key_2 = "Product Serial" + psu_pn_key = "Product Name" + + # Request and validate sensor's information. + self.fru_status_list, self.psu_info_list = self.request_data() + + # Set PSU FRU data. + psu_info_dict = dict() + for psu_fru in self.psu_info_list: + psu_data = dict() + pn = psu_fru.get(psu_pn_key) + sn = psu_fru.get(psu_sn_key_1) or psu_fru.get(psu_sn_key_2) + psu_data["PN"] = "N/A" if not pn or str( + pn).strip() == "" else str(pn).strip() + psu_data["SN"] = "N/A" if not pn or str( + pn).strip() == "" else str(sn).strip() + + fru_check = [psu_fru[v] for v in psu_fru.keys() if 'FRU Info' in v] + non_fru_check = [v for v in psu_fru.keys() if 'PSU' in v] + + if len(non_fru_check) > 0: + psu_idx = int(re.findall('\d+', non_fru_check[0])[0]) + psu_info_dict[psu_idx] = psu_data + elif len(fru_check) > 0: + psu_idx = int(re.findall('\d+', fru_check[0])[0]) + psu_info_dict[psu_idx] = psu_data + + # Set PSU status. + for fru_status in self.fru_status_list: + psu_status_dict = dict() + find_psu = [v for v in fru_status.keys() if "PSU" in v] + if len(find_psu) > 0: + psu_idx = int(re.findall('\d+', find_psu[0])[0]) + psu_ps_status = True if str(fru_status.get( + "Present")).strip() == "Present" else False + psu_pw_status = True if str(fru_status.get( + "Power Status")).strip() == "OK" else False + psu_pw_type = str(fru_status.get( + "Power Type")).strip() + ac_status = True if str(fru_status.get( + "AC Status")).strip().upper() == "OK" else False + + psu_status_dict["Present"] = psu_ps_status + if psu_ps_status: + psu_status_dict["PowerStatus"] = psu_pw_status + psu_status_dict["PN"] = psu_info_dict[psu_idx]["PN"] + psu_status_dict["SN"] = psu_info_dict[psu_idx]["SN"] + psu_status_dict["InputType"] = psu_pw_type + psu_status_dict["InputStatus"] = True if psu_pw_status and psu_ps_status else False + psu_status_dict["OutputStatus"] = ac_status + psu_status_dict["AirFlow"] = self.airflow_selector( + psu_status_dict["PN"]) + all_psu_dict[find_psu[0]] = psu_status_dict + + return all_psu_dict diff --git a/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/sensorutil.py b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/sensorutil.py new file mode 100644 index 000000000000..796949126ccc --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/sensorutil.py @@ -0,0 +1,369 @@ +#!/usr/bin/env python + +__author__ = 'Wirut G.' +__license__ = "GPL" +__version__ = "0.2.0" +__status__ = "Development" + +import requests + + +class SensorUtil(): + """Platform-specific SensorUtil class""" + + def __init__(self): + self.sensor_url = "http://240.1.1.1:8080/api/sys/sensors" + self.sys_fruid_url = "http://240.1.1.1:8080/api/sys/fruid/sys" + self.sensor_info_list = None + + def request_data(self): + # Reqest data from BMC if not exist. + if self.sensor_info_list is None: + sensor_data_req = requests.get(self.sensor_url) + sensor_json = sensor_data_req.json() + self.sensor_info_list = sensor_json.get('Information') + sys_fruid_req = requests.get(self.sys_fruid_url) + sys_fruid_json = sys_fruid_req.json() + self.sys_fruid_list = sys_fruid_json.get('Information') + return self.sensor_info_list + + def input_type_selector(self, unit): + # Set input type. + return { + "C": "temperature", + "V": "voltage", + "RPM": "RPM", + "A": "amp", + "W": "power" + }.get(unit, unit) + + def input_name_selector(self, sensor_name, input_name): + + self.sensor_name = { + "syscpld-i2c-0-0d": "TEMPERATURE", + "dps1100-i2c-24-58": "PSU1", + "dps1100-i2c-25-59": "PSU2", + "fancpld-i2c-8-0d": "FAN" + }.get(sensor_name, sensor_name) + + if 'dps1100' in sensor_name: + input_name = { + "fan1": self.sensor_name + "_FAN", + "iin": self.sensor_name + "_CURR_I", + "iout1": self.sensor_name + "_CURR_O", + "pin": self.sensor_name + "_POWER_I", + "pout1": self.sensor_name + "_POWER_O", + "temp1": self.sensor_name + "_TEMP1", + "temp2": self.sensor_name + "_TEMP2", + "vin": self.sensor_name + "_VOL_I", + "vout1": self.sensor_name + "_VOL_O" + }.get(input_name, input_name) + + elif 'tmp75' in sensor_name: + input_name = { + "tmp75-i2c-7-4d": "FTB_INLET_RIGHT", + "tmp75-i2c-7-4c": "FTB_INLET_LEFT", + "tmp75-i2c-7-4b": "FTB_SWITCH_OUTLET", + "tmp75-i2c-7-4a": "BTF_SWITCH_OUTLET", + "tmp75-i2c-39-48": "BTF_INLET_RIGHT", + "tmp75-i2c-39-49": "BTF_INLET_LEFT" + }.get(sensor_name, input_name) + if self.get_sys_airflow() == "FTOB" and sensor_name == "tmp75-i2c-7-4d": + input_name = "INLET_TEMP" + + if self.get_sys_airflow() == "BTOF" and sensor_name == "tmp75-i2c-39-48": + input_name = "INLET_TEMP" + + self.sensor_name = "TEMPERATURE" + + elif 'fancpld' in sensor_name: + raw_fan_input = input_name.split() + input_name = raw_fan_input[0] + \ + raw_fan_input[1] + "_" + raw_fan_input[2] + + elif 'ir35' in sensor_name or 'ir38' in sensor_name: + sensor_name_raw = sensor_name.split("-") + sensor_name = sensor_name_raw[0] + self.sensor_name = sensor_name.upper() + + return input_name.replace(" ", "_").upper() + + def get_num_sensors(self): + """ + Get the number of sensors + :return: int num_sensors + """ + + num_sensors = 0 + try: + # Request and validate sensor's information + self.sensor_info_list = self.request_data() + + # Get number of sensors. + num_sensors = len(self.sensor_info_list) + except: + print "Error: Unable to access sensor information" + return 0 + + return num_sensors + + def get_sensor_input_num(self, index): + """ + Get the number of the input items of the specified sensor + :return: int input_num + """ + + input_num = 0 + try: + # Request and validate sensor's information. + self.sensor_info_list = self.request_data() + + # Get sensor's input number. + sensor_data = self.sensor_info_list[index-1] + input_num = len(sensor_data.keys())-2 + except: + print "Error: Unable to access sensor information" + return 0 + + return input_num + + def get_sensor_name(self, index): + """ + Get the device name of the specified sensor. + for example "coretemp-isa-0000" + :return: str sensor_name + """ + + sensor_name = "N/A" + try: + # Request and validate sensor's information. + self.sensor_info_list = self.request_data() + + # Get sensor's name. + sensor_data = self.sensor_info_list[index-1] + sensor_name = sensor_data.get('name') + + except: + return "N/A" + + return sensor_name + + def get_sensor_input_name(self, sensor_index, input_index): + """ + Get the input item name of the specified input item of the + specified sensor index, for example "Physical id 0" + :return: str sensor_input_name + """ + + sensor_input_name = "N/A" + try: + # Request and validate sensor's information. + self.sensor_info_list = self.request_data() + sensor_data = self.sensor_info_list[sensor_index-1].copy() + + # Remove none input key. + del sensor_data["name"] + del sensor_data["Adapter"] + + # Get sensor's input name. + sensor_data_key = sensor_data.keys() + sensor_input_name = sensor_data_key[input_index-1] + except: + return "N/A" + + return sensor_input_name + + def get_sensor_input_type(self, sensor_index, input_index): + """ + Get the item type of the specified input item of the specified sensor index, + The return value should among "valtage","temperature" + :return: str sensor_input_type + """ + + sensor_input_type = "N/A" + try: + # Request and validate sensor's information. + self.sensor_info_list = self.request_data() + sensor_data = self.sensor_info_list[sensor_index-1].copy() + + # Remove none input key. + del sensor_data["name"] + del sensor_data["Adapter"] + + # Get sensor's input type name. + sensor_data_key = sensor_data.keys() + sensor_input_raw = sensor_data.get(sensor_data_key[input_index-1]) + sensor_data_str = sensor_input_raw.split() + sensor_input_type = self.input_type_selector(sensor_data_str[1]) + except: + return "N/A" + + return sensor_input_type + + def get_sensor_input_value(self, sensor_index, input_index): + """ + Get the current value of the input item, the unit is "V" or "C" + :return: float sensor_input_value + """ + + sensor_input_value = 0 + try: + # Request and validate sensor's information. + self.sensor_info_list = self.request_data() + sensor_data = self.sensor_info_list[sensor_index-1].copy() + + # Remove none input key. + del sensor_data["name"] + del sensor_data["Adapter"] + + # Get sensor's input value. + sensor_data_key = sensor_data.keys() + sensor_input_raw = sensor_data.get(sensor_data_key[input_index-1]) + sensor_data_str = sensor_input_raw.split() + sensor_input_value = float( + sensor_data_str[0]) if sensor_data_str[0] != "N/A" else 0 + except: + print "Error: Unable to access sensor information" + return 0 + + return sensor_input_value + + def get_sensor_input_low_threshold(self, sensor_index, input_index): + """ + Get the low threshold of the value, + the status of this item is not ok if the current value 1: + sensor_input_low_threshold = l_thres * \ + 1000 if str(unit[0]).lower() == 'k' else l_thres + except: + print "Error: Unable to access sensor information" + return 0 + + return sensor_input_low_threshold + + def get_sensor_input_high_threshold(self, sensor_index, input_index): + """ + Get the high threshold of the value, + the status of this item is not ok if the current value > high_threshold + :return: float sensor_input_high_threshold + """ + + sensor_input_high_threshold = 0 + try: + # Request and validate sensor's information. + self.sensor_info_list = self.request_data() + sensor_data = self.sensor_info_list[sensor_index-1].copy() + + # Remove none input key. + del sensor_data["name"] + del sensor_data["Adapter"] + + # Get sensor's input high threshold. + sensor_data_key = sensor_data.keys() + sensor_input_raw = sensor_data.get(sensor_data_key[input_index-1]) + sensor_data_str = sensor_input_raw.split() + indices = [i for i, s in enumerate( + sensor_data_str) if 'max' in s or 'high' in s] + h_thres = float( + sensor_data_str[indices[0] + 2]) if len(indices) != 0 else 0 + unit = sensor_data_str[indices[0] + + 3] if len(indices) != 0 else None + if unit is not None and len(unit) > 1: + sensor_input_high_threshold = h_thres * \ + 1000 if str(unit[0]).lower() == 'k' else h_thres + + except: + print "Error: Unable to access sensor information" + return 0 + + return sensor_input_high_threshold + + def get_sys_airflow(self): + sys_air_flow = "Unknown" + sys_pn_data = [ + v.split(":") for v in self.sys_fruid_list if "Product Part Number" in v] + + if len(sys_pn_data) == 0: + return sys_air_flow + + sys_pn = sys_pn_data[0][1] + if "R1241-F0001" in sys_pn: + sys_air_flow = "FTOB" + elif"R1241-F0002" in sys_pn: + sys_air_flow = "BTOF" + + return sys_air_flow + + def get_all(self): + + all_sensor_dict = dict() + + # Request sensor's information. + self.sensor_info_list = self.request_data() + for sensor_data in self.sensor_info_list: + sensor_info = sensor_data.copy() + + # Remove none unuse key. + del sensor_info["name"] + del sensor_info["Adapter"] + + # Set sensor data. + sensor_dict = dict() + for k, v in sensor_info.items(): + sensor_i_dict = dict() + sensor_data_str = v.split() + indices_h = [i for i, s in enumerate( + sensor_data_str) if 'max' in s or 'high' in s] + indices_l = [i for i, s in enumerate( + sensor_data_str) if 'min' in s or 'low' in s] + h_thres = float( + sensor_data_str[indices_h[0] + 2]) if len(indices_h) != 0 else 0 + l_thres = float( + sensor_data_str[indices_l[0] + 2]) if len(indices_l) != 0 else 0 + thres_unit = sensor_data_str[-1] + + sensor_i_dict["Type"] = self.input_type_selector( + sensor_data_str[1]) + sensor_i_dict["Value"] = float( + sensor_data_str[0]) if sensor_data_str[0] != "N/A" else 0 + sensor_i_dict["HighThd"] = h_thres * \ + 1000 if str(thres_unit[0]).lower() == 'k' else h_thres + sensor_i_dict["LowThd"] = l_thres * \ + 1000 if str(thres_unit[0]).lower() == 'k' else l_thres + + k = self.input_name_selector(sensor_data.get('name'), k) + sensor_dict[k] = sensor_i_dict + + if all_sensor_dict.get(self.sensor_name) is None: + all_sensor_dict[self.sensor_name] = dict() + + all_sensor_dict[self.sensor_name].update(sensor_dict) + + sensor_dict = dict() + sensor_dict["Sys_AirFlow"] = self.get_sys_airflow() + all_sensor_dict["TEMPERATURE"].update(sensor_dict) + + return all_sensor_dict diff --git a/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/sfputil.py b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/sfputil.py new file mode 100755 index 000000000000..f0187acb4eb6 --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/plugins/sfputil.py @@ -0,0 +1,234 @@ +#!/usr/bin/env python +# +# 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 = 1 + PORT_END = 40 + QSFP_PORT_START = 1 + QSFP_PORT_END = 40 + + EEPROM_OFFSET = 9 + PORT_INFO_PATH = '/sys/class/fishbone2_fpga' + + _port_name = "" + _port_to_eeprom_mapping = { + 1: "/sys/bus/i2c/devices/i2c-42/42-0050/eeprom", 21: "/sys/bus/i2c/devices/i2c-46/46-0050/eeprom", + 2: "/sys/bus/i2c/devices/i2c-43/43-0050/eeprom", 22: "/sys/bus/i2c/devices/i2c-47/47-0050/eeprom", + 3: "/sys/bus/i2c/devices/i2c-10/10-0050/eeprom", 23: "/sys/bus/i2c/devices/i2c-26/26-0050/eeprom", + 4: "/sys/bus/i2c/devices/i2c-11/11-0050/eeprom", 24: "/sys/bus/i2c/devices/i2c-27/27-0050/eeprom", + 5: "/sys/bus/i2c/devices/i2c-12/12-0050/eeprom", 25: "/sys/bus/i2c/devices/i2c-28/28-0050/eeprom", + 6: "/sys/bus/i2c/devices/i2c-13/13-0050/eeprom", 26: "/sys/bus/i2c/devices/i2c-29/29-0050/eeprom", + 7: "/sys/bus/i2c/devices/i2c-14/14-0050/eeprom", 27: "/sys/bus/i2c/devices/i2c-30/30-0050/eeprom", + 8: "/sys/bus/i2c/devices/i2c-15/15-0050/eeprom", 28: "/sys/bus/i2c/devices/i2c-31/31-0050/eeprom", + 9: "/sys/bus/i2c/devices/i2c-16/16-0050/eeprom", 29: "/sys/bus/i2c/devices/i2c-32/32-0050/eeprom", + 10: "/sys/bus/i2c/devices/i2c-17/17-0050/eeprom", 30: "/sys/bus/i2c/devices/i2c-33/33-0050/eeprom", + 11: "/sys/bus/i2c/devices/i2c-18/18-0050/eeprom", 31: "/sys/bus/i2c/devices/i2c-34/34-0050/eeprom", + 12: "/sys/bus/i2c/devices/i2c-19/19-0050/eeprom", 32: "/sys/bus/i2c/devices/i2c-35/35-0050/eeprom", + 13: "/sys/bus/i2c/devices/i2c-20/20-0050/eeprom", 33: "/sys/bus/i2c/devices/i2c-36/36-0050/eeprom", + 14: "/sys/bus/i2c/devices/i2c-21/21-0050/eeprom", 34: "/sys/bus/i2c/devices/i2c-37/37-0050/eeprom", + 15: "/sys/bus/i2c/devices/i2c-22/22-0050/eeprom", 35: "/sys/bus/i2c/devices/i2c-38/38-0050/eeprom", + 16: "/sys/bus/i2c/devices/i2c-23/23-0050/eeprom", 36: "/sys/bus/i2c/devices/i2c-39/39-0050/eeprom", + 17: "/sys/bus/i2c/devices/i2c-24/24-0050/eeprom", 37: "/sys/bus/i2c/devices/i2c-40/40-0050/eeprom", + 18: "/sys/bus/i2c/devices/i2c-25/25-0050/eeprom", 38: "/sys/bus/i2c/devices/i2c-41/41-0050/eeprom", + 19: "/sys/bus/i2c/devices/i2c-44/44-0050/eeprom", 39: "/sys/bus/i2c/devices/i2c-48/48-0050/eeprom", + 20: "/sys/bus/i2c/devices/i2c-45/45-0050/eeprom", 40: "/sys/bus/i2c/devices/i2c-49/49-0050/eeprom", + } + _port_to_i2cbus_mapping = { + 1: 42, 2: 43, 3: 10, 4: 11, 5: 12, 6: 13, 7: 14, 8: 15, 9: 16, 10: 17, + 11: 18, 12: 19, 13: 20, 14: 21, 15: 22, 16: 23, 17: 24, 18: 25, 19: 44, 20: 45, + 21: 46, 22: 47, 23: 26, 24: 27, 25: 28, 26: 29, 27: 30, 28: 31, 29: 32, 30: 33, + 31: 34, 32: 35, 33: 36, 34: 37, 35: 38, 36: 39, 37: 40, 38: 41, 39: 48, 40: 49, + } + + @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 + + @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.qsfp_ports: + self._port_name = "QSFP" + str(port_num - self.QSFP_PORT_START + 1) + else: + self._port_name = "SFP" + str(port_num) + return self._port_name + + 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 __init__(self): + # Override port_to_eeprom_mapping for class initialization + eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' + # the following scheme is not correct,use 'i2cdetect -y -l' to detect # + #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) + print("self.port_to_i2cbus_mapping: "+str(self.port_to_i2cbus_mapping)+"\n") + print("self.port_to_eeprom_mapping: "+str(self.port_to_eeprom_mapping)+"\n") + + 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.qsfp_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): + return NotImplementedError + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid QSFP port_num + if port_num not in self.qsfp_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.qsfp_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 + """ + return NotImplementedError + + def tx_disable(self, port_num, disable): + """ + @param port_num index of physical port + @param disable, True -- disable port tx signal + False -- enable port tx signal + @return True when operation success, False on failure. + """ + TX_DISABLE_BYTE_OFFSET = 86 + if port_num not in range(self.port_start, self.port_end + 1) or type(disable) != bool: + return False + + # QSFP, set eeprom to disable tx + if port_num in self.qsfp_ports: + presence = self.get_presence(port_num) + if not presence: + return True + + disable = b'\x0f' if disable else b'\x00' + # open eeprom + try: + with open(self.port_to_eeprom_mapping[port_num], mode="wb", buffering=0) as sysfsfile: + sysfsfile.seek(TX_DISABLE_BYTE_OFFSET) + sysfsfile.write(bytearray(disable)) + except IOError: + return False + except: + return False + + # SFP, set tx_disable pin + else: + try: + disable = hex(1) if disable else hex(0) + port_name = self.get_port_name(port_num) + reg_file = open( + "/".join([self.PORT_INFO_PATH, port_name, "sfp_txdisable"]), "w") + reg_file.write(disable) + reg_file.close() + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + return True diff --git a/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/td3-as14-40d.config.bcm b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/td3-as14-40d.config.bcm new file mode 100644 index 000000000000..2aaef4ea27ea --- /dev/null +++ b/device/alibaba/x86_64-alibaba_as14-40d-cl-r0/td3-as14-40d.config.bcm @@ -0,0 +1,590 @@ +ifp_inports_support_enable=1 +ipv6_lpm_128b_enable=0x1 +l2_mem_entries=32768 +l2xmsg_mode=1 +l3_max_ecmp_mode=1 +l3_mem_entries=16384 +lpm_scaling_enable=1 +max_vp_lags=0 +mem_cache_enable=0 +miim_intr_enable=0 +module_64ports=1 +oversubscribe_mode=1 +parity_enable=0 +serdes_if_type_ce=14 +#pbmp_xport_xe=0x48878787f8787808dfe1e0203e1e1e022 +pbmp_xport_xe=0x88888888888888882222222222222222 + +#ptp_ts_pll_fref=50000000 +#ptp_bs_fref_0=50000000 +#ptp_bs_fref_1=50000000 +portmap_1.0=1:100 +portmap_5.0=5:100 +portmap_9.0=9:100 +portmap_13.0=13:100 +portmap_17.0=17:100 +portmap_21.0=21:100 +portmap_25.0=25:100 +portmap_29.0=29:100 +portmap_33.0=33:100 +portmap_37.0=37:100 +portmap_41.0=41:100 +portmap_45.0=45:100 +portmap_49.0=49:100 +portmap_53.0=53:100 +portmap_57.0=57:100 +portmap_61.0=61:100 +portmap_67.0=65:100 +portmap_71.0=69:100 +portmap_75.0=73:100 +portmap_79.0=77:100 +portmap_83.0=81:100 +portmap_87.0=85:100 +portmap_91.0=89:100 +portmap_95.0=93:100 +portmap_99.0=97:100 +portmap_103.0=101:100 +portmap_107.0=105:100 +portmap_111.0=109:100 +portmap_115.0=113:100 +portmap_119.0=117:100 +portmap_123.0=121:100 +portmap_127.0=125:100 +portmap_66.0=129:10:m +portmap_130.0=128:10:m + +#wc0 lane swap +phy_chain_tx_lane_map_physical{1.0}=0x0132 +phy_chain_rx_lane_map_physical{1.0}=0x3210 + +#wc1 lane swap +phy_chain_tx_lane_map_physical{5.0}=0x2301 +phy_chain_rx_lane_map_physical{5.0}=0x2031 + +#wc2 lane swap +phy_chain_tx_lane_map_physical{9.0}=0x0132 +phy_chain_rx_lane_map_physical{9.0}=0x3210 + +#wc3 lane swap +phy_chain_tx_lane_map_physical{13.0}=0x3201 +phy_chain_rx_lane_map_physical{13.0}=0x2031 + +#wc4 lane swap +phy_chain_tx_lane_map_physical{17.0}=0x0123 +phy_chain_rx_lane_map_physical{17.0}=0x3210 + +#wc5 lane swap +phy_chain_tx_lane_map_physical{21.0}=0x2301 +phy_chain_rx_lane_map_physical{21.0}=0x2031 + +#wc6 lane swap +phy_chain_tx_lane_map_physical{25.0}=0x0123 +phy_chain_rx_lane_map_physical{25.0}=0x3210 + +#wc7 lane swap +phy_chain_tx_lane_map_physical{29.0}=0x3201 +phy_chain_rx_lane_map_physical{29.0}=0x2031 + +#wc8 lane swap +phy_chain_tx_lane_map_physical{33.0}=0x0213 +phy_chain_rx_lane_map_physical{33.0}=0x1302 + +#wc9 lane swap +phy_chain_tx_lane_map_physical{37.0}=0x1302 +phy_chain_rx_lane_map_physical{37.0}=0x2031 + +#wc10 lane swap +phy_chain_tx_lane_map_physical{41.0}=0x0231 +phy_chain_rx_lane_map_physical{41.0}=0x3120 + +#wc11 lane swap +phy_chain_tx_lane_map_physical{45.0}=0x1302 +phy_chain_rx_lane_map_physical{45.0}=0x2031 + +#wc12 lane swap +phy_chain_tx_lane_map_physical{49.0}=0x2103 +phy_chain_rx_lane_map_physical{49.0}=0x3120 + +#wc13 lane swap +phy_chain_tx_lane_map_physical{53.0}=0x2301 +phy_chain_rx_lane_map_physical{53.0}=0x2031 + +#wc14 lane swap +phy_chain_tx_lane_map_physical{57.0}=0x0123 +phy_chain_rx_lane_map_physical{57.0}=0x2301 + +#wc15 lane swap +phy_chain_tx_lane_map_physical{61.0}=0x3210 +phy_chain_rx_lane_map_physical{61.0}=0x1032 + +#wc16 lane swap +phy_chain_tx_lane_map_physical{65.0}=0x3210 +phy_chain_rx_lane_map_physical{65.0}=0x1023 + +#wc17 lane swap +phy_chain_tx_lane_map_physical{69.0}=0x0123 +phy_chain_rx_lane_map_physical{69.0}=0x1302 + +#wc18 lane swap +phy_chain_tx_lane_map_physical{73.0}=0x2301 +phy_chain_rx_lane_map_physical{73.0}=0x1032 + +#wc19 lane swap +phy_chain_tx_lane_map_physical{77.0}=0x2013 +phy_chain_rx_lane_map_physical{77.0}=0x3120 + +#wc20 lane swap +phy_chain_tx_lane_map_physical{81.0}=0x1302 +phy_chain_rx_lane_map_physical{81.0}=0x2031 + +#wc21 lane swap +phy_chain_tx_lane_map_physical{85.0}=0x0123 +phy_chain_rx_lane_map_physical{85.0}=0x2130 + +#wc22 lane swap +phy_chain_tx_lane_map_physical{89.0}=0x2301 +phy_chain_rx_lane_map_physical{89.0}=0x2031 + +#wc23 lane swap +phy_chain_tx_lane_map_physical{93.0}=0x0312 +phy_chain_rx_lane_map_physical{93.0}=0x2310 + +#wc24 lane swap +phy_chain_tx_lane_map_physical{97.0}=0x2301 +phy_chain_rx_lane_map_physical{97.0}=0x1032 + +#wc25 lane swap +phy_chain_tx_lane_map_physical{101.0}=0x0123 +phy_chain_rx_lane_map_physical{101.0}=0x3210 + +#wc26 lane swap +phy_chain_tx_lane_map_physical{105.0}=0x2301 +phy_chain_rx_lane_map_physical{105.0}=0x1032 + +#wc27 lane swap +phy_chain_tx_lane_map_physical{109.0}=0x0123 +phy_chain_rx_lane_map_physical{109.0}=0x3210 + +#wc28 lane swap +phy_chain_tx_lane_map_physical{113.0}=0x2301 +phy_chain_rx_lane_map_physical{113.0}=0x2031 + +#wc29 lane swap +phy_chain_tx_lane_map_physical{117.0}=0x0123 +phy_chain_rx_lane_map_physical{117.0}=0x3210 + +#wc30 lane swap +phy_chain_tx_lane_map_physical{121.0}=0x2301 +phy_chain_rx_lane_map_physical{121.0}=0x1032 + +#wc31 lane swap +phy_chain_tx_lane_map_physical{125.0}=0x0123 +phy_chain_rx_lane_map_physical{125.0}=0x3210 + +#MC lane swap +phy_chain_tx_lane_map_physical{129.0}=0x3210 +phy_chain_rx_lane_map_physical{129.0}=0x3210 + + +#wc0 P/N flip +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{4.0}=0x1 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 + +#wc1 P/N flip +phy_chain_tx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{5.0}=0x0 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x1 +phy_chain_tx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{7.0}=0x1 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x1 + +#wc2 P/N flip +phy_chain_tx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_tx_polarity_flip_physical{10.0}=0x0 +phy_chain_rx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x1 + +#wc3 P/N flip +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{13.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_tx_polarity_flip_physical{16.0}=0x0 +phy_chain_rx_polarity_flip_physical{16.0}=0x1 + +#wc4 P/N flip +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{17.0}=0x0 +phy_chain_tx_polarity_flip_physical{18.0}=0x1 +phy_chain_rx_polarity_flip_physical{18.0}=0x1 +phy_chain_tx_polarity_flip_physical{19.0}=0x0 +phy_chain_rx_polarity_flip_physical{19.0}=0x0 +phy_chain_tx_polarity_flip_physical{20.0}=0x1 +phy_chain_rx_polarity_flip_physical{20.0}=0x1 + +#wc5 P/N flip +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_tx_polarity_flip_physical{24.0}=0x1 +phy_chain_rx_polarity_flip_physical{24.0}=0x1 + +#wc6 P/N flip +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_rx_polarity_flip_physical{25.0}=0x1 +phy_chain_tx_polarity_flip_physical{26.0}=0x1 +phy_chain_rx_polarity_flip_physical{26.0}=0x0 +phy_chain_tx_polarity_flip_physical{27.0}=0x0 +phy_chain_rx_polarity_flip_physical{27.0}=0x1 +phy_chain_tx_polarity_flip_physical{28.0}=0x1 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 + +#wc7 P/N flip +phy_chain_tx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{29.0}=0x1 +phy_chain_tx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_tx_polarity_flip_physical{32.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 + +#wc8 P/N flip +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{33.0}=0x1 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x0 +phy_chain_tx_polarity_flip_physical{35.0}=0x0 +phy_chain_rx_polarity_flip_physical{35.0}=0x0 +phy_chain_tx_polarity_flip_physical{36.0}=0x1 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 + +#wc9 P/N flip +phy_chain_tx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_tx_polarity_flip_physical{38.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x0 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_rx_polarity_flip_physical{39.0}=0x0 +phy_chain_tx_polarity_flip_physical{40.0}=0x0 +phy_chain_rx_polarity_flip_physical{40.0}=0x1 + +#wc10 P/N flip +phy_chain_tx_polarity_flip_physical{41.0}=0x1 +phy_chain_rx_polarity_flip_physical{41.0}=0x1 +phy_chain_tx_polarity_flip_physical{42.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x0 +phy_chain_tx_polarity_flip_physical{44.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x1 + +#wc11 P/N flip +phy_chain_tx_polarity_flip_physical{45.0}=0x1 +phy_chain_rx_polarity_flip_physical{45.0}=0x0 +phy_chain_tx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x0 +phy_chain_tx_polarity_flip_physical{47.0}=0x1 +phy_chain_rx_polarity_flip_physical{47.0}=0x1 +phy_chain_tx_polarity_flip_physical{48.0}=0x0 +phy_chain_rx_polarity_flip_physical{48.0}=0x1 + +#wc12 P/N flip +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{49.0}=0x0 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x0 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x1 + +#wc13 P/N flip +phy_chain_tx_polarity_flip_physical{53.0}=0x0 +phy_chain_rx_polarity_flip_physical{53.0}=0x0 +phy_chain_tx_polarity_flip_physical{54.0}=0x1 +phy_chain_rx_polarity_flip_physical{54.0}=0x1 +phy_chain_tx_polarity_flip_physical{55.0}=0x0 +phy_chain_rx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x1 +phy_chain_rx_polarity_flip_physical{56.0}=0x1 + +#wc14 P/N flip +phy_chain_tx_polarity_flip_physical{57.0}=0x1 +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x1 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x0 +phy_chain_rx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x1 +phy_chain_rx_polarity_flip_physical{60.0}=0x1 + +#wc15 P/N flip +phy_chain_tx_polarity_flip_physical{61.0}=0x0 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x1 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x0 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x0 +phy_chain_rx_polarity_flip_physical{64.0}=0x0 + +#wc16 P/N flip +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{65.0}=0x0 +phy_chain_tx_polarity_flip_physical{66.0}=0x0 +phy_chain_rx_polarity_flip_physical{66.0}=0x0 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x1 +phy_chain_tx_polarity_flip_physical{68.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x0 + +#wc17 P/N flip +phy_chain_tx_polarity_flip_physical{69.0}=0x1 +phy_chain_rx_polarity_flip_physical{69.0}=0x1 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{71.0}=0x0 +phy_chain_tx_polarity_flip_physical{72.0}=0x0 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 + +#wc18 P/N flip +phy_chain_tx_polarity_flip_physical{73.0}=0x0 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x0 +phy_chain_tx_polarity_flip_physical{75.0}=0x0 +phy_chain_rx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x1 +phy_chain_rx_polarity_flip_physical{76.0}=0x0 + +#wc19 P/N flip +phy_chain_tx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{77.0}=0x0 +phy_chain_tx_polarity_flip_physical{78.0}=0x0 +phy_chain_rx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_rx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x1 +phy_chain_rx_polarity_flip_physical{80.0}=0x1 + +#wc20 P/N flip +phy_chain_tx_polarity_flip_physical{81.0}=0x0 +phy_chain_rx_polarity_flip_physical{81.0}=0x0 +phy_chain_tx_polarity_flip_physical{82.0}=0x0 +phy_chain_rx_polarity_flip_physical{82.0}=0x0 +phy_chain_tx_polarity_flip_physical{83.0}=0x1 +phy_chain_rx_polarity_flip_physical{83.0}=0x1 +phy_chain_tx_polarity_flip_physical{84.0}=0x1 +phy_chain_rx_polarity_flip_physical{84.0}=0x0 + +#wc21 P/N flip +phy_chain_tx_polarity_flip_physical{85.0}=0x1 +phy_chain_rx_polarity_flip_physical{85.0}=0x1 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_rx_polarity_flip_physical{86.0}=0x1 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_rx_polarity_flip_physical{87.0}=0x0 +phy_chain_tx_polarity_flip_physical{88.0}=0x0 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 + +#wc22 P/N flip +phy_chain_tx_polarity_flip_physical{89.0}=0x1 +phy_chain_rx_polarity_flip_physical{89.0}=0x0 +phy_chain_tx_polarity_flip_physical{90.0}=0x0 +phy_chain_rx_polarity_flip_physical{90.0}=0x0 +phy_chain_tx_polarity_flip_physical{91.0}=0x1 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x0 +phy_chain_rx_polarity_flip_physical{92.0}=0x1 + +#wc23 P/N flip +phy_chain_tx_polarity_flip_physical{93.0}=0x1 +phy_chain_rx_polarity_flip_physical{93.0}=0x1 +phy_chain_tx_polarity_flip_physical{94.0}=0x1 +phy_chain_rx_polarity_flip_physical{94.0}=0x1 +phy_chain_tx_polarity_flip_physical{95.0}=0x0 +phy_chain_rx_polarity_flip_physical{95.0}=0x0 +phy_chain_tx_polarity_flip_physical{96.0}=0x0 +phy_chain_rx_polarity_flip_physical{96.0}=0x1 + +#wc24 P/N flip +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 + +#wc25 P/N flip +phy_chain_tx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{101.0}=0x0 +phy_chain_tx_polarity_flip_physical{102.0}=0x0 +phy_chain_rx_polarity_flip_physical{102.0}=0x1 +phy_chain_tx_polarity_flip_physical{103.0}=0x1 +phy_chain_rx_polarity_flip_physical{103.0}=0x0 +phy_chain_tx_polarity_flip_physical{104.0}=0x0 +phy_chain_rx_polarity_flip_physical{104.0}=0x0 + +#wc26 P/N flip +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 + +#wc27 P/N flip +phy_chain_tx_polarity_flip_physical{109.0}=0x1 +phy_chain_rx_polarity_flip_physical{109.0}=0x1 +phy_chain_tx_polarity_flip_physical{110.0}=0x0 +phy_chain_rx_polarity_flip_physical{110.0}=0x0 +phy_chain_tx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_tx_polarity_flip_physical{112.0}=0x0 +phy_chain_rx_polarity_flip_physical{112.0}=0x0 + +#wc28 P/N flip +phy_chain_tx_polarity_flip_physical{113.0}=0x1 +phy_chain_rx_polarity_flip_physical{113.0}=0x1 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_rx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x0 +phy_chain_tx_polarity_flip_physical{116.0}=0x0 +phy_chain_rx_polarity_flip_physical{116.0}=0x0 + +#wc29 P/N flip +phy_chain_tx_polarity_flip_physical{117.0}=0x1 +phy_chain_rx_polarity_flip_physical{117.0}=0x1 +phy_chain_tx_polarity_flip_physical{118.0}=0x0 +phy_chain_rx_polarity_flip_physical{118.0}=0x0 +phy_chain_tx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_tx_polarity_flip_physical{120.0}=0x0 +phy_chain_rx_polarity_flip_physical{120.0}=0x0 + +#wc30 P/N flip +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{121.0}=0x0 +phy_chain_tx_polarity_flip_physical{122.0}=0x0 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x0 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 +phy_chain_rx_polarity_flip_physical{124.0}=0x1 + +#wc31 P/N flip +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_rx_polarity_flip_physical{125.0}=0x1 +phy_chain_tx_polarity_flip_physical{126.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x0 +phy_chain_tx_polarity_flip_physical{127.0}=0x1 +phy_chain_rx_polarity_flip_physical{127.0}=0x1 +phy_chain_tx_polarity_flip_physical{128.0}=0x0 +phy_chain_rx_polarity_flip_physical{128.0}=0x0 + +#MC P/N flip +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 + +dport_map_port_1=1 +dport_map_port_5=2 +dport_map_port_9=3 +dport_map_port_13=4 +dport_map_port_17=5 +dport_map_port_21=6 +dport_map_port_25=7 +dport_map_port_29=8 +dport_map_port_33=9 +dport_map_port_37=10 +dport_map_port_41=11 +dport_map_port_45=12 +dport_map_port_49=13 +dport_map_port_53=14 +dport_map_port_57=15 +dport_map_port_61=16 +dport_map_port_67=17 +dport_map_port_71=18 +dport_map_port_75=19 +dport_map_port_79=20 +dport_map_port_83=21 +dport_map_port_87=22 +dport_map_port_91=23 +dport_map_port_95=24 +dport_map_port_99=25 +dport_map_port_103=26 +dport_map_port_107=27 +dport_map_port_111=28 +dport_map_port_115=29 +dport_map_port_119=30 +dport_map_port_123=31 +dport_map_port_127=32 +dport_map_port_66=33 +dport_map_port_130=34 + +# configuration for 100G optical module +serdes_preemphasis_1=0x164608 +serdes_preemphasis_5=0x164608 +serdes_preemphasis_9=0x164608 +serdes_preemphasis_13=0x134908 +serdes_preemphasis_17=0x134908 +serdes_preemphasis_21=0x134908 +serdes_preemphasis_25=0x124a08 +serdes_preemphasis_29=0x124a08 +serdes_preemphasis_33=0x114b08 +serdes_preemphasis_37=0x114b08 +serdes_preemphasis_41=0x0f4d08 +serdes_preemphasis_45=0x0f4d08 +serdes_preemphasis_49=0x0d4f08 +serdes_preemphasis_53=0x0d4f08 +serdes_preemphasis_57=0x0d4f08 +serdes_preemphasis_61=0x0d4f08 +serdes_preemphasis_67=0x0d4f08 +serdes_preemphasis_71=0x0d4f08 +serdes_preemphasis_75=0x0d4f08 +serdes_preemphasis_79=0x0d4f08 +serdes_preemphasis_83=0x0d4f08 +serdes_preemphasis_87=0x0f4d08 +serdes_preemphasis_91=0x0f4d08 +serdes_preemphasis_95=0x0f4d08 +serdes_preemphasis_99=0x114b08 +serdes_preemphasis_103=0x114b08 +serdes_preemphasis_107=0x114b08 +serdes_preemphasis_111=0x124a08 +serdes_preemphasis_115=0x134908 +serdes_preemphasis_119=0x134908 +serdes_preemphasis_123=0x134908 +serdes_preemphasis_127=0x164608 + +schan_intr_enable=0 +stable_size=0x5500000 +tdma_timeout_usec=3000000 diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/port_config.ini b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/port_config.ini new file mode 100644 index 000000000000..d3d339076a59 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/port_config.ini @@ -0,0 +1,35 @@ +# name lanes alias index +Ethernet0 1,2,3,4 Ethernet1/1 1 +Ethernet4 5,6,7,8 Ethernet2/1 2 +Ethernet8 9,10,11,12 Ethernet3/1 3 +Ethernet12 13,14,15,16 Ethernet4/1 4 +Ethernet16 21,22,23,24 Ethernet5/1 5 +Ethernet20 17,18,19,20 Ethernet6/1 6 +Ethernet24 25,26,27,28 Ethernet7/1 7 +Ethernet28 29,30,31,32 Ethernet8/1 8 +Ethernet32 37,38,39,40 Ethernet9/1 9 +Ethernet36 33,34,35,36 Ethernet10/1 10 +Ethernet40 41,42,43,44 Ethernet11/1 11 +Ethernet44 45,46,47,48 Ethernet12/1 12 +Ethernet48 53,54,55,56 Ethernet13/1 13 +Ethernet52 49,50,51,52 Ethernet14/1 14 +Ethernet56 57,58,59,60 Ethernet15/1 15 +Ethernet60 61,62,63,64 Ethernet16/1 16 +Ethernet64 69,70,71,72 Ethernet17/1 17 +Ethernet68 65,66,67,68 Ethernet18/1 18 +Ethernet72 73,74,75,76 Ethernet19/1 19 +Ethernet76 77,78,79,80 Ethernet20/1 20 +Ethernet80 85,86,87,88 Ethernet21/1 21 +Ethernet84 81,82,83,84 Ethernet22/1 22 +Ethernet88 89,90,91,92 Ethernet23/1 23 +Ethernet92 93,94,95,96 Ethernet24/1 24 +Ethernet96 101,102,103,104 Ethernet25/1 25 +Ethernet100 97,98,99,100 Ethernet26/1 26 +Ethernet104 105,106,107,108 Ethernet27/1 27 +Ethernet108 109,110,111,112 Ethernet28/1 28 +Ethernet112 117,118,119,120 Ethernet29/1 29 +Ethernet116 113,114,115,116 Ethernet30/1 30 +Ethernet120 121,122,123,124 Ethernet31/1 31 +Ethernet124 125,126,127,128 Ethernet32/1 32 +Ethernet128 129 Ethernet33 33 +Ethernet132 128 Ethernet34 34 diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/sai.profile b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/sai.profile new file mode 100644 index 000000000000..d359ffc15cba --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-a7050cx3-32s-32x100G.config.bcm diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/td3-a7050cx3-32s-32x100G.config.bcm b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/td3-a7050cx3-32s-32x100G.config.bcm new file mode 100644 index 000000000000..217d15b4e579 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/td3-a7050cx3-32s-32x100G.config.bcm @@ -0,0 +1,503 @@ +arl_clean_timeout_usec=15000000 +asf_mem_profile=2 +bcm_num_cos=8 +bcm_stat_flags=1 +bcm_stat_jumbo=9236 +bcm_tunnel_term_compatible_mode=1 +cdma_timeout_usec=15000000 +core_clock_frequency=1525 +dma_desc_timeout_usec=15000000 +dpp_clock_ratio=2:3 +fpem_mem_entries=0 +higig2_hdr_mode=1 +ifp_inports_support_enable=1 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l2xmsg_mode=1 +l3_alpm_enable=2 +l3_max_ecmp_mode=1 +l3_mem_entries=16384 +max_vp_lags=0 +miim_intr_enable=0 +module_64ports=1 +multicast_l2_range=16383 +multicast_l3_range=0 +os=unix +oversubscribe_mode=1 +pbmp_xport_xe=0x4888888888888888c2222222222222222 +PHY_AN_ALLOW_PLL_CHANGE=1 +phy_an_c37_130=2 +phy_an_c37_66=2 +phy_an_c73=1 +port_flex_enable=1 +port_init_autoneg=0 +port_phy_addr=0xff +robust_hash_disable_egress_vlan=1 +robust_hash_disable_mpls=1 +robust_hash_disable_vlan=1 +sram_scan_enable=0 +stable_size=0x5500000 +tdma_timeout_usec=15000000 +tslam_timeout_usec=15000000 +phy_chain_rx_lane_map_physical{1.0}=0x1302 +phy_chain_rx_lane_map_physical{101.0}=0x0213 +phy_chain_rx_lane_map_physical{105.0}=0x2031 +phy_chain_rx_lane_map_physical{109.0}=0x0213 +phy_chain_rx_lane_map_physical{113.0}=0x2130 +phy_chain_rx_lane_map_physical{117.0}=0x0213 +phy_chain_rx_lane_map_physical{121.0}=0x2031 +phy_chain_rx_lane_map_physical{125.0}=0x0213 +phy_chain_rx_lane_map_physical{129.0}=0x3210 +phy_chain_rx_lane_map_physical{13.0}=0x3120 +phy_chain_rx_lane_map_physical{17.0}=0x1203 +phy_chain_rx_lane_map_physical{21.0}=0x3120 +phy_chain_rx_lane_map_physical{25.0}=0x3120 +phy_chain_rx_lane_map_physical{29.0}=0x3120 +phy_chain_rx_lane_map_physical{33.0}=0x1203 +phy_chain_rx_lane_map_physical{37.0}=0x3120 +phy_chain_rx_lane_map_physical{41.0}=0x3120 +phy_chain_rx_lane_map_physical{45.0}=0x3120 +phy_chain_rx_lane_map_physical{49.0}=0x1203 +phy_chain_rx_lane_map_physical{5.0}=0x3120 +phy_chain_rx_lane_map_physical{53.0}=0x3120 +phy_chain_rx_lane_map_physical{57.0}=0x3120 +phy_chain_rx_lane_map_physical{61.0}=0x3120 +phy_chain_rx_lane_map_physical{65.0}=0x2130 +phy_chain_rx_lane_map_physical{69.0}=0x0213 +phy_chain_rx_lane_map_physical{73.0}=0x2031 +phy_chain_rx_lane_map_physical{77.0}=0x0213 +phy_chain_rx_lane_map_physical{81.0}=0x2130 +phy_chain_rx_lane_map_physical{85.0}=0x0213 +phy_chain_rx_lane_map_physical{89.0}=0x2031 +phy_chain_rx_lane_map_physical{9.0}=0x3120 +phy_chain_rx_lane_map_physical{93.0}=0x0213 +phy_chain_rx_lane_map_physical{97.0}=0x2130 +phy_chain_rx_polarity_flip_physical{100.0}=0x1 +phy_chain_rx_polarity_flip_physical{10.0}=0x0 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{102.0}=0x0 +phy_chain_rx_polarity_flip_physical{103.0}=0x0 +phy_chain_rx_polarity_flip_physical{104.0}=0x1 +phy_chain_rx_polarity_flip_physical{105.0}=0x1 +phy_chain_rx_polarity_flip_physical{106.0}=0x1 +phy_chain_rx_polarity_flip_physical{107.0}=0x1 +phy_chain_rx_polarity_flip_physical{108.0}=0x0 +phy_chain_rx_polarity_flip_physical{109.0}=0x0 +phy_chain_rx_polarity_flip_physical{110.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x1 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{112.0}=0x1 +phy_chain_rx_polarity_flip_physical{113.0}=0x1 +phy_chain_rx_polarity_flip_physical{114.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x0 +phy_chain_rx_polarity_flip_physical{116.0}=0x1 +phy_chain_rx_polarity_flip_physical{117.0}=0x0 +phy_chain_rx_polarity_flip_physical{118.0}=0x0 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{120.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x1 +phy_chain_rx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{124.0}=0x0 +phy_chain_rx_polarity_flip_physical{125.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x0 +phy_chain_rx_polarity_flip_physical{127.0}=0x1 +phy_chain_rx_polarity_flip_physical{128.0}=0x1 +phy_chain_rx_polarity_flip_physical{129.0}=0x0 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +phy_chain_rx_polarity_flip_physical{131.0}=0x0 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{16.0}=0x0 +phy_chain_rx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{18.0}=0x0 +phy_chain_rx_polarity_flip_physical{19.0}=0x1 +phy_chain_rx_polarity_flip_physical{20.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{23.0}=0x0 +phy_chain_rx_polarity_flip_physical{24.0}=0x0 +phy_chain_rx_polarity_flip_physical{25.0}=0x0 +phy_chain_rx_polarity_flip_physical{26.0}=0x1 +phy_chain_rx_polarity_flip_physical{27.0}=0x1 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 +phy_chain_rx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 +phy_chain_rx_polarity_flip_physical{33.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x1 +phy_chain_rx_polarity_flip_physical{39.0}=0x0 +phy_chain_rx_polarity_flip_physical{40.0}=0x0 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_rx_polarity_flip_physical{41.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x0 +phy_chain_rx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x1 +phy_chain_rx_polarity_flip_physical{45.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{47.0}=0x0 +phy_chain_rx_polarity_flip_physical{48.0}=0x0 +phy_chain_rx_polarity_flip_physical{49.0}=0x0 +phy_chain_rx_polarity_flip_physical{50.0}=0x0 +phy_chain_rx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x0 +phy_chain_rx_polarity_flip_physical{53.0}=0x1 +phy_chain_rx_polarity_flip_physical{54.0}=0x1 +phy_chain_rx_polarity_flip_physical{55.0}=0x0 +phy_chain_rx_polarity_flip_physical{56.0}=0x0 +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_rx_polarity_flip_physical{58.0}=0x0 +phy_chain_rx_polarity_flip_physical{59.0}=0x1 +phy_chain_rx_polarity_flip_physical{60.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_rx_polarity_flip_physical{62.0}=0x1 +phy_chain_rx_polarity_flip_physical{63.0}=0x0 +phy_chain_rx_polarity_flip_physical{64.0}=0x0 +phy_chain_rx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{66.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x1 +phy_chain_rx_polarity_flip_physical{69.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{72.0}=0x1 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{75.0}=0x1 +phy_chain_rx_polarity_flip_physical{76.0}=0x0 +phy_chain_rx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{78.0}=0x0 +phy_chain_rx_polarity_flip_physical{79.0}=0x1 +phy_chain_rx_polarity_flip_physical{80.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 +phy_chain_rx_polarity_flip_physical{81.0}=0x1 +phy_chain_rx_polarity_flip_physical{82.0}=0x1 +phy_chain_rx_polarity_flip_physical{83.0}=0x0 +phy_chain_rx_polarity_flip_physical{84.0}=0x1 +phy_chain_rx_polarity_flip_physical{85.0}=0x0 +phy_chain_rx_polarity_flip_physical{86.0}=0x0 +phy_chain_rx_polarity_flip_physical{87.0}=0x1 +phy_chain_rx_polarity_flip_physical{88.0}=0x1 +phy_chain_rx_polarity_flip_physical{89.0}=0x1 +phy_chain_rx_polarity_flip_physical{90.0}=0x1 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_rx_polarity_flip_physical{92.0}=0x0 +phy_chain_rx_polarity_flip_physical{93.0}=0x0 +phy_chain_rx_polarity_flip_physical{94.0}=0x0 +phy_chain_rx_polarity_flip_physical{95.0}=0x1 +phy_chain_rx_polarity_flip_physical{96.0}=0x1 +phy_chain_rx_polarity_flip_physical{97.0}=0x1 +phy_chain_rx_polarity_flip_physical{98.0}=0x1 +phy_chain_rx_polarity_flip_physical{99.0}=0x0 +phy_chain_tx_lane_map_physical{1.0}=0x3021 +phy_chain_tx_lane_map_physical{101.0}=0x3120 +phy_chain_tx_lane_map_physical{105.0}=0x1302 +phy_chain_tx_lane_map_physical{109.0}=0x2130 +phy_chain_tx_lane_map_physical{113.0}=0x1302 +phy_chain_tx_lane_map_physical{117.0}=0x3120 +phy_chain_tx_lane_map_physical{121.0}=0x1302 +phy_chain_tx_lane_map_physical{125.0}=0x3120 +phy_chain_tx_lane_map_physical{129.0}=0x3210 +phy_chain_tx_lane_map_physical{13.0}=0x0213 +phy_chain_tx_lane_map_physical{17.0}=0x2031 +phy_chain_tx_lane_map_physical{21.0}=0x0213 +phy_chain_tx_lane_map_physical{25.0}=0x2031 +phy_chain_tx_lane_map_physical{29.0}=0x1203 +phy_chain_tx_lane_map_physical{33.0}=0x2031 +phy_chain_tx_lane_map_physical{37.0}=0x0213 +phy_chain_tx_lane_map_physical{41.0}=0x2031 +phy_chain_tx_lane_map_physical{45.0}=0x1203 +phy_chain_tx_lane_map_physical{49.0}=0x2031 +phy_chain_tx_lane_map_physical{5.0}=0x1203 +phy_chain_tx_lane_map_physical{53.0}=0x0213 +phy_chain_tx_lane_map_physical{57.0}=0x2031 +phy_chain_tx_lane_map_physical{61.0}=0x1203 +phy_chain_tx_lane_map_physical{65.0}=0x1302 +phy_chain_tx_lane_map_physical{69.0}=0x1302 +phy_chain_tx_lane_map_physical{73.0}=0x1302 +phy_chain_tx_lane_map_physical{77.0}=0x2130 +phy_chain_tx_lane_map_physical{81.0}=0x1302 +phy_chain_tx_lane_map_physical{85.0}=0x3120 +phy_chain_tx_lane_map_physical{89.0}=0x1302 +phy_chain_tx_lane_map_physical{9.0}=0x0213 +phy_chain_tx_lane_map_physical{93.0}=0x2130 +phy_chain_tx_lane_map_physical{97.0}=0x1302 +phy_chain_tx_polarity_flip_physical{100.0}=0x1 +phy_chain_tx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{1.0}=0x1 +phy_chain_tx_polarity_flip_physical{101.0}=0x0 +phy_chain_tx_polarity_flip_physical{102.0}=0x1 +phy_chain_tx_polarity_flip_physical{103.0}=0x1 +phy_chain_tx_polarity_flip_physical{104.0}=0x0 +phy_chain_tx_polarity_flip_physical{105.0}=0x1 +phy_chain_tx_polarity_flip_physical{106.0}=0x0 +phy_chain_tx_polarity_flip_physical{107.0}=0x0 +phy_chain_tx_polarity_flip_physical{108.0}=0x0 +phy_chain_tx_polarity_flip_physical{109.0}=0x1 +phy_chain_tx_polarity_flip_physical{110.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{111.0}=0x0 +phy_chain_tx_polarity_flip_physical{112.0}=0x0 +phy_chain_tx_polarity_flip_physical{113.0}=0x0 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x0 +phy_chain_tx_polarity_flip_physical{116.0}=0x0 +phy_chain_tx_polarity_flip_physical{117.0}=0x1 +phy_chain_tx_polarity_flip_physical{118.0}=0x1 +phy_chain_tx_polarity_flip_physical{119.0}=0x0 +phy_chain_tx_polarity_flip_physical{120.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x0 +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_tx_polarity_flip_physical{122.0}=0x0 +phy_chain_tx_polarity_flip_physical{123.0}=0x0 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_tx_polarity_flip_physical{126.0}=0x1 +phy_chain_tx_polarity_flip_physical{127.0}=0x0 +phy_chain_tx_polarity_flip_physical{128.0}=0x0 +phy_chain_tx_polarity_flip_physical{129.0}=0x0 +phy_chain_tx_polarity_flip_physical{13.0}=0x1 +phy_chain_tx_polarity_flip_physical{131.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_tx_polarity_flip_physical{16.0}=0x1 +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_tx_polarity_flip_physical{18.0}=0x0 +phy_chain_tx_polarity_flip_physical{19.0}=0x0 +phy_chain_tx_polarity_flip_physical{20.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{21.0}=0x1 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_tx_polarity_flip_physical{24.0}=0x0 +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_tx_polarity_flip_physical{26.0}=0x0 +phy_chain_tx_polarity_flip_physical{27.0}=0x1 +phy_chain_tx_polarity_flip_physical{28.0}=0x0 +phy_chain_tx_polarity_flip_physical{29.0}=0x0 +phy_chain_tx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x1 +phy_chain_tx_polarity_flip_physical{32.0}=0x1 +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_tx_polarity_flip_physical{34.0}=0x1 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_tx_polarity_flip_physical{36.0}=0x1 +phy_chain_tx_polarity_flip_physical{37.0}=0x0 +phy_chain_tx_polarity_flip_physical{38.0}=0x0 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_tx_polarity_flip_physical{40.0}=0x1 +phy_chain_tx_polarity_flip_physical{4.0}=0x0 +phy_chain_tx_polarity_flip_physical{41.0}=0x0 +phy_chain_tx_polarity_flip_physical{42.0}=0x1 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_tx_polarity_flip_physical{44.0}=0x1 +phy_chain_tx_polarity_flip_physical{45.0}=0x0 +phy_chain_tx_polarity_flip_physical{46.0}=0x0 +phy_chain_tx_polarity_flip_physical{47.0}=0x1 +phy_chain_tx_polarity_flip_physical{48.0}=0x1 +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_tx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{51.0}=0x1 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 +phy_chain_tx_polarity_flip_physical{53.0}=0x0 +phy_chain_tx_polarity_flip_physical{54.0}=0x0 +phy_chain_tx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x1 +phy_chain_tx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x1 +phy_chain_tx_polarity_flip_physical{60.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_tx_polarity_flip_physical{61.0}=0x0 +phy_chain_tx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x1 +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_tx_polarity_flip_physical{66.0}=0x1 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_tx_polarity_flip_physical{68.0}=0x1 +phy_chain_tx_polarity_flip_physical{69.0}=0x0 +phy_chain_tx_polarity_flip_physical{70.0}=0x1 +phy_chain_tx_polarity_flip_physical{7.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_tx_polarity_flip_physical{72.0}=0x1 +phy_chain_tx_polarity_flip_physical{73.0}=0x0 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_tx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x1 +phy_chain_tx_polarity_flip_physical{77.0}=0x0 +phy_chain_tx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x1 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_tx_polarity_flip_physical{81.0}=0x1 +phy_chain_tx_polarity_flip_physical{82.0}=0x1 +phy_chain_tx_polarity_flip_physical{83.0}=0x1 +phy_chain_tx_polarity_flip_physical{84.0}=0x1 +phy_chain_tx_polarity_flip_physical{85.0}=0x0 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_tx_polarity_flip_physical{88.0}=0x1 +phy_chain_tx_polarity_flip_physical{89.0}=0x0 +phy_chain_tx_polarity_flip_physical{90.0}=0x1 +phy_chain_tx_polarity_flip_physical{9.0}=0x1 +phy_chain_tx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x1 +phy_chain_tx_polarity_flip_physical{93.0}=0x0 +phy_chain_tx_polarity_flip_physical{94.0}=0x0 +phy_chain_tx_polarity_flip_physical{95.0}=0x1 +phy_chain_tx_polarity_flip_physical{96.0}=0x1 +phy_chain_tx_polarity_flip_physical{97.0}=0x1 +phy_chain_tx_polarity_flip_physical{98.0}=0x1 +phy_chain_tx_polarity_flip_physical{99.0}=0x1 +portmap_103=101:100 +portmap_107=105:100 +portmap_1=1:100 +portmap_111=109:100 +portmap_115=113:100 +portmap_119=117:100 +portmap_123=121:100 +portmap_127=125:100 +portmap_130=128:10:m +portmap_13=13:100 +portmap_17=17:100 +portmap_21=21:100 +portmap_25=25:100 +portmap_29=29:100 +portmap_33=33:100 +portmap_37=37:100 +portmap_41=41:100 +portmap_45=45:100 +portmap_49=49:100 +portmap_53=53:100 +portmap_5=5:100 +portmap_57=57:100 +portmap_61=61:100 +portmap_66=129:10:m +portmap_67=65:100 +portmap_71=69:100 +portmap_75=73:100 +portmap_79=77:100 +portmap_83=81:100 +portmap_87=85:100 +portmap_91=89:100 +portmap_95=93:100 +portmap_9=9:100 +portmap_99=97:100 +serdes_core_rx_polarity_flip_physical{101}=0x9 +serdes_core_rx_polarity_flip_physical{105}=0x7 +serdes_core_rx_polarity_flip_physical{109}=0xc +serdes_core_rx_polarity_flip_physical{1}=0x8 +serdes_core_rx_polarity_flip_physical{113}=0xb +serdes_core_rx_polarity_flip_physical{117}=0xc +serdes_core_rx_polarity_flip_physical{121}=0x7 +serdes_core_rx_polarity_flip_physical{125}=0xc +serdes_core_rx_polarity_flip_physical{129}=0x0 +serdes_core_rx_polarity_flip_physical{13}=0x3 +serdes_core_rx_polarity_flip_physical{17}=0x4 +serdes_core_rx_polarity_flip_physical{21}=0x3 +serdes_core_rx_polarity_flip_physical{25}=0x6 +serdes_core_rx_polarity_flip_physical{29}=0x3 +serdes_core_rx_polarity_flip_physical{33}=0x4 +serdes_core_rx_polarity_flip_physical{37}=0x3 +serdes_core_rx_polarity_flip_physical{41}=0xc +serdes_core_rx_polarity_flip_physical{45}=0x3 +serdes_core_rx_polarity_flip_physical{49}=0x4 +serdes_core_rx_polarity_flip_physical{5}=0x2 +serdes_core_rx_polarity_flip_physical{53}=0x3 +serdes_core_rx_polarity_flip_physical{57}=0xc +serdes_core_rx_polarity_flip_physical{61}=0x3 +serdes_core_rx_polarity_flip_physical{65}=0xb +serdes_core_rx_polarity_flip_physical{69}=0xc +serdes_core_rx_polarity_flip_physical{73}=0x7 +serdes_core_rx_polarity_flip_physical{77}=0xc +serdes_core_rx_polarity_flip_physical{81}=0xb +serdes_core_rx_polarity_flip_physical{85}=0xc +serdes_core_rx_polarity_flip_physical{89}=0x7 +serdes_core_rx_polarity_flip_physical{9}=0xc +serdes_core_rx_polarity_flip_physical{93}=0xc +serdes_core_rx_polarity_flip_physical{97}=0xb +serdes_core_tx_polarity_flip_physical{101}=0x6 +serdes_core_tx_polarity_flip_physical{105}=0x1 +serdes_core_tx_polarity_flip_physical{109}=0x3 +serdes_core_tx_polarity_flip_physical{1}=0x3 +serdes_core_tx_polarity_flip_physical{113}=0x0 +serdes_core_tx_polarity_flip_physical{117}=0x3 +serdes_core_tx_polarity_flip_physical{121}=0x1 +serdes_core_tx_polarity_flip_physical{125}=0x3 +serdes_core_tx_polarity_flip_physical{129}=0x0 +serdes_core_tx_polarity_flip_physical{13}=0xb +serdes_core_tx_polarity_flip_physical{17}=0x0 +serdes_core_tx_polarity_flip_physical{21}=0x3 +serdes_core_tx_polarity_flip_physical{25}=0x4 +serdes_core_tx_polarity_flip_physical{29}=0xc +serdes_core_tx_polarity_flip_physical{33}=0xf +serdes_core_tx_polarity_flip_physical{37}=0xc +serdes_core_tx_polarity_flip_physical{41}=0xe +serdes_core_tx_polarity_flip_physical{45}=0xc +serdes_core_tx_polarity_flip_physical{49}=0xf +serdes_core_tx_polarity_flip_physical{5}=0xb +serdes_core_tx_polarity_flip_physical{53}=0xc +serdes_core_tx_polarity_flip_physical{57}=0xe +serdes_core_tx_polarity_flip_physical{61}=0xc +serdes_core_tx_polarity_flip_physical{65}=0xf +serdes_core_tx_polarity_flip_physical{69}=0xe +serdes_core_tx_polarity_flip_physical{73}=0xe +serdes_core_tx_polarity_flip_physical{77}=0xc +serdes_core_tx_polarity_flip_physical{81}=0xf +serdes_core_tx_polarity_flip_physical{85}=0xc +serdes_core_tx_polarity_flip_physical{89}=0xe +serdes_core_tx_polarity_flip_physical{9}=0x3 +serdes_core_tx_polarity_flip_physical{93}=0xc +serdes_core_tx_polarity_flip_physical{97}=0xf +serdes_preemphasis_1=0x14410a +serdes_preemphasis_5=0x14410a +serdes_preemphasis_9=0x14410a +serdes_preemphasis_13=0x14410a +serdes_preemphasis_17=0x14410a +serdes_preemphasis_21=0x14410a +serdes_preemphasis_25=0x14410a +serdes_preemphasis_29=0x14410a +serdes_preemphasis_33=0x14410a +serdes_preemphasis_37=0x14410a +serdes_preemphasis_41=0x14410a +serdes_preemphasis_45=0x14410a +serdes_preemphasis_49=0xf5005 +serdes_preemphasis_53=0xf5005 +serdes_preemphasis_57=0xf5005 +serdes_preemphasis_61=0xf5005 +serdes_driver_current_66=0xe +serdes_preemphasis_66=0x102804 +serdes_preemphasis_67=0xf5005 +serdes_preemphasis_71=0xf5005 +serdes_preemphasis_75=0xf5005 +serdes_preemphasis_79=0xf5005 +serdes_preemphasis_83=0x14410a +serdes_preemphasis_87=0x14410a +serdes_preemphasis_91=0x14410a +serdes_preemphasis_95=0x14410a +serdes_preemphasis_99=0x14410a +serdes_preemphasis_103=0x14410a +serdes_preemphasis_107=0x14410a +serdes_preemphasis_111=0x14410a +serdes_preemphasis_115=0x14410a +serdes_preemphasis_119=0x14410a +serdes_preemphasis_123=0x14410a +serdes_preemphasis_127=0x14410a +serdes_driver_current_130=0xe +serdes_preemphasis_130=0x102804 diff --git a/device/arista/x86_64-arista_7050cx3_32s/default_sku b/device/arista/x86_64-arista_7050cx3_32s/default_sku new file mode 100644 index 000000000000..bff7a549cb2c --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/default_sku @@ -0,0 +1 @@ +Arista-7050CX3-32S-C32 t1 diff --git a/device/arista/x86_64-arista_7050cx3_32s/fancontrol b/device/arista/x86_64-arista_7050cx3_32s/fancontrol new file mode 100644 index 000000000000..913075f73d12 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/fancontrol @@ -0,0 +1,10 @@ +INTERVAL=5 +DEVPATH=hwmon4=devices/pci0000:00/0000:00:02.2/0000:02:00.0/i2c-11/11-004c hwmon3=devices/pci0000:00/0000:00:02.2/0000:02:00.0/i2c-2/2-0060 +DEVNAME=hwmon4=max6658 hwmon3=crow_cpld +FCTEMPS=hwmon3/pwm4=hwmon4/temp1_input hwmon3/pwm3=hwmon4/temp1_input hwmon3/pwm2=hwmon4/temp1_input hwmon3/pwm1=hwmon4/temp1_input +FCFANS=hwmon3/pwm4=hwmon3/fan4_input hwmon3/pwm3=hwmon3/fan3_input hwmon3/pwm2=hwmon3/fan2_input hwmon3/pwm1=hwmon3/fan1_input +MINTEMP=hwmon3/pwm4=40 hwmon3/pwm3=40 hwmon3/pwm2=40 hwmon3/pwm1=40 +MINPWM=hwmon3/pwm4=179 hwmon3/pwm3=179 hwmon3/pwm2=179 hwmon3/pwm1=179 +MAXTEMP=hwmon3/pwm4=50 hwmon3/pwm3=50 hwmon3/pwm2=50 hwmon3/pwm1=50 +MINSTART=hwmon3/pwm4=179 hwmon3/pwm3=179 hwmon3/pwm2=179 hwmon3/pwm1=179 +MINSTOP=hwmon3/pwm4=179 hwmon3/pwm3=179 hwmon3/pwm2=179 hwmon3/pwm1=179 diff --git a/device/arista/x86_64-arista_7050cx3_32s/platform_reboot b/device/arista/x86_64-arista_7050cx3_32s/platform_reboot new file mode 120000 index 000000000000..7f94a49e38b0 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/platform_reboot @@ -0,0 +1 @@ +../x86_64-arista_common/platform_reboot \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins b/device/arista/x86_64-arista_7050cx3_32s/plugins new file mode 120000 index 000000000000..789a45fcace9 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/plugins @@ -0,0 +1 @@ +../x86_64-arista_common/plugins \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/sensors.conf b/device/arista/x86_64-arista_7050cx3_32s/sensors.conf new file mode 100644 index 000000000000..c63a526124d0 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/sensors.conf @@ -0,0 +1,39 @@ +# libsensors configuration file for DCS-7050CX3-32S +# ------------------------------------------------ +# + +bus "i2c-2" "SCD 0000:02:00.0 SMBus master 0 bus 0" +bus "i2c-11" "SCD 0000:02:00.0 SMBus master 1 bus 1" +bus "i2c-13" "SCD 0000:02:00.0 SMBus master 1 bus 3" +bus "i2c-14" "SCD 0000:02:00.0 SMBus master 1 bus 4" + +chip "k10temp-pci-00c3" + label temp1 "Cpu temp sensor" + +chip "max6658-i2c-2-4c" + label temp1 "Cpu board temp sensor" + set temp1_max 75 + set temp1_crit 80 + + label temp2 "Back panel temp sensor" + set temp2_max 75 + set temp2_crit 85 + +chip "max6658-i2c-11-4c" + label temp1 "Board temp sensor" + set temp1_max 75 + set temp1_crit 85 + + label temp2 "Front panel temp sensor" + set temp2_max 60 + set temp2_crit 65 + +chip "pmbus-i2c-13-58" + label temp1 "Power supply 1 hotspot sensor" + label temp2 "Power supply 1 inlet temp sensor" + label temp3 "Power supply 1 sensor" + +chip "pmbus-i2c-14-58" + label temp1 "Power supply 2 hotspot sensor" + label temp2 "Power supply 2 inlet temp sensor" + label temp3 "Power supply 2 sensor" diff --git a/device/arista/x86_64-arista_7060cx2_32s/Arista-7060CX2-32S-C32 b/device/arista/x86_64-arista_7060cx2_32s/Arista-7060CX2-32S-C32 new file mode 120000 index 000000000000..3ba3c5721b19 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/Arista-7060CX2-32S-C32 @@ -0,0 +1 @@ +../x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32 \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060cx2_32s/default_sku b/device/arista/x86_64-arista_7060cx2_32s/default_sku new file mode 100644 index 000000000000..fb5071866c25 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/default_sku @@ -0,0 +1 @@ +Arista-7060CX2-32S-C32 t1 diff --git a/device/arista/x86_64-arista_7060cx2_32s/fancontrol b/device/arista/x86_64-arista_7060cx2_32s/fancontrol new file mode 120000 index 000000000000..c37f83f5ffb5 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/fancontrol @@ -0,0 +1 @@ +../x86_64-arista_7060_cx32s/fancontrol \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060cx2_32s/platform_reboot b/device/arista/x86_64-arista_7060cx2_32s/platform_reboot new file mode 120000 index 000000000000..7f94a49e38b0 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/platform_reboot @@ -0,0 +1 @@ +../x86_64-arista_common/platform_reboot \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060cx2_32s/plugins b/device/arista/x86_64-arista_7060cx2_32s/plugins new file mode 120000 index 000000000000..5fbbf98a6284 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/plugins @@ -0,0 +1 @@ +../x86_64-arista_common/plugins/ \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060cx2_32s/sensors.conf b/device/arista/x86_64-arista_7060cx2_32s/sensors.conf new file mode 120000 index 000000000000..10be0183e3a7 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/sensors.conf @@ -0,0 +1 @@ +../x86_64-arista_7060_cx32s/sensors.conf \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/board_lane_map.json b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/board_lane_map.json new file mode 100644 index 000000000000..6ab72e55ab47 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/board_lane_map.json @@ -0,0 +1,1734 @@ +{ + "board_name": "7170-32C", + "enable_debug_log": 0, + "board_lane_map_entry": [ + { + "connector": 1, + "device_id": 0, + "mac_block": 14, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 2, + "device_id": 0, + "mac_block": 12, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 3, + "device_id": 0, + "mac_block": 10, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 4, + "device_id": 0, + "mac_block": 8, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 5, + "device_id": 0, + "mac_block": 6, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 6, + "device_id": 0, + "mac_block": 4, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 7, + "device_id": 0, + "mac_block": 2, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 8, + "device_id": 0, + "mac_block": 0, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 9, + "device_id": 0, + "mac_block": 62, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 10, + "device_id": 0, + "mac_block": 60, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 11, + "device_id": 0, + "mac_block": 58, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 12, + "device_id": 0, + "mac_block": 56, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 13, + "device_id": 0, + "mac_block": 54, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 14, + "device_id": 0, + "mac_block": 52, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 15, + "device_id": 0, + "mac_block": 50, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 16, + "device_id": 0, + "mac_block": 48, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 17, + "device_id": 0, + "mac_block": 46, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 18, + "device_id": 0, + "mac_block": 44, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 19, + "device_id": 0, + "mac_block": 42, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 20, + "device_id": 0, + "mac_block": 40, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 21, + "device_id": 0, + "mac_block": 38, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 22, + "device_id": 0, + "mac_block": 36, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 23, + "device_id": 0, + "mac_block": 34, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 24, + "device_id": 0, + "mac_block": 32, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 25, + "device_id": 0, + "mac_block": 30, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 26, + "device_id": 0, + "mac_block": 28, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 27, + "device_id": 0, + "mac_block": 26, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 28, + "device_id": 0, + "mac_block": 24, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 29, + "device_id": 0, + "mac_block": 22, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 30, + "device_id": 0, + "mac_block": 20, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 31, + "device_id": 0, + "mac_block": 18, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 32, + "device_id": 0, + "mac_block": 16, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + } + ] +} diff --git a/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/port_config.ini b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/port_config.ini new file mode 100644 index 000000000000..d983617f1891 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias speed index +Ethernet0 0,1,2,3 Ethernet1/1 100000 1 +Ethernet4 4,5,6,7 Ethernet2/1 100000 2 +Ethernet8 8,9,10,11 Ethernet3/1 100000 3 +Ethernet12 12,13,14,15 Ethernet4/1 100000 4 +Ethernet16 16,17,18,19 Ethernet5/1 100000 5 +Ethernet20 20,21,22,23 Ethernet6/1 100000 6 +Ethernet24 24,25,26,27 Ethernet7/1 100000 7 +Ethernet28 28,29,30,31 Ethernet8/1 100000 8 +Ethernet32 32,33,34,35 Ethernet9/1 100000 9 +Ethernet36 36,37,38,39 Ethernet10/1 100000 10 +Ethernet40 40,41,42,43 Ethernet11/1 100000 11 +Ethernet44 44,45,46,47 Ethernet12/1 100000 12 +Ethernet48 48,49,50,51 Ethernet13/1 100000 13 +Ethernet52 52,53,54,55 Ethernet14/1 100000 14 +Ethernet56 56,57,58,59 Ethernet15/1 100000 15 +Ethernet60 60,61,62,63 Ethernet16/1 100000 16 +Ethernet64 64,65,66,67 Ethernet17/1 100000 17 +Ethernet68 68,69,70,71 Ethernet18/1 100000 18 +Ethernet72 72,73,74,75 Ethernet19/1 100000 19 +Ethernet76 76,77,78,79 Ethernet20/1 100000 20 +Ethernet80 80,81,82,83 Ethernet21/1 100000 21 +Ethernet84 84,85,86,87 Ethernet22/1 100000 22 +Ethernet88 88,89,90,91 Ethernet23/1 100000 23 +Ethernet92 92,93,94,95 Ethernet24/1 100000 24 +Ethernet96 96,97,98,99 Ethernet25/1 100000 25 +Ethernet100 100,101,102,103 Ethernet26/1 100000 26 +Ethernet104 104,105,106,107 Ethernet27/1 100000 27 +Ethernet108 108,109,110,111 Ethernet28/1 100000 28 +Ethernet112 112,113,114,115 Ethernet29/1 100000 29 +Ethernet116 116,117,118,119 Ethernet30/1 100000 30 +Ethernet120 120,121,122,123 Ethernet31/1 100000 31 +Ethernet124 124,125,126,127 Ethernet32/1 100000 32 diff --git a/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-sai.conf b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-sai.conf new file mode 100644 index 000000000000..0a807b1c9ea7 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-sai.conf @@ -0,0 +1,33 @@ +{ + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:1c.4/0000:07:00.0", + "pcie_domain": 0, + "pcie_bus": 7, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "instance": 0, + "p4_program_list": [ + { + "id": "pgm-0", + "instance": 0, + "path": "switch", + "program-name": "switch", + "pd": "lib/tofinopd/switch/libpd.so", + "pd-thrift": "lib/tofinopd/switch/libpdthrift.so", + "table-config": "share/tofinopd/switch/context.json", + "tofino-bin": "share/tofinopd/switch/tofino.bin", + "switchapi": "lib/libswitchapi.so", + "sai": "lib/libsai.so", + "switchapi_port_add": false, + "non_default_port_ppgs": 5 + } + ] +} diff --git a/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-tna-sai.conf b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-tna-sai.conf new file mode 100644 index 000000000000..ece3fcbe6a90 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-tna-sai.conf @@ -0,0 +1,39 @@ +{ + "instance": 0, + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0", + "pcie_domain": 0, + "pcie_bus": 5, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "p4_devices": [ + { + "device-id": 0, + "p4_programs": [ + { + "p4_pipelines": [ + { + "p4_pipeline_name": "pipe", + "config": "share/switch/pipe/tofino.bin", + "context": "share/switch/pipe/context.json" + } + ], + "program-name": "switch", + "sai": "lib/libsai.so", + "bfrt-config": "share/switch/bf-rt.json", + "model_json_path" : "share/switch/aug_model.json", + "switchapi_port_add": false, + "non_default_port_ppgs": 5 + } + ] + } + ] +} diff --git a/device/arista/x86_64-arista_7170_32c/default_sku b/device/arista/x86_64-arista_7170_32c/default_sku new file mode 100644 index 000000000000..536bad44f086 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/default_sku @@ -0,0 +1 @@ +Arista-7170-32CD-C32 t1 diff --git a/device/arista/x86_64-arista_7170_32c/platform_reboot b/device/arista/x86_64-arista_7170_32c/platform_reboot new file mode 120000 index 000000000000..7f94a49e38b0 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/platform_reboot @@ -0,0 +1 @@ +../x86_64-arista_common/platform_reboot \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32c/plugins b/device/arista/x86_64-arista_7170_32c/plugins new file mode 120000 index 000000000000..789a45fcace9 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/plugins @@ -0,0 +1 @@ +../x86_64-arista_common/plugins \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32c/sensors.conf b/device/arista/x86_64-arista_7170_32c/sensors.conf new file mode 120000 index 000000000000..1ab9e0f47704 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/sensors.conf @@ -0,0 +1 @@ +../x86_64-arista_7170_64c/sensors.conf \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/board_lane_map.json b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/board_lane_map.json new file mode 100644 index 000000000000..58a78c5fc4c9 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/board_lane_map.json @@ -0,0 +1,1734 @@ +{ + "board_name": "7170-32CD", + "enable_debug_log": 0, + "board_lane_map_entry": [ + { + "connector": 1, + "device_id": 0, + "mac_block": 7, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 2, + "device_id": 0, + "mac_block": 6, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 3, + "device_id": 0, + "mac_block": 5, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 4, + "device_id": 0, + "mac_block": 4, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 5, + "device_id": 0, + "mac_block": 3, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 6, + "device_id": 0, + "mac_block": 2, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 7, + "device_id": 0, + "mac_block": 1, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 8, + "device_id": 0, + "mac_block": 0, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 9, + "device_id": 0, + "mac_block": 31, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 10, + "device_id": 0, + "mac_block": 30, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 11, + "device_id": 0, + "mac_block": 29, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 12, + "device_id": 0, + "mac_block": 28, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 13, + "device_id": 0, + "mac_block": 27, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 14, + "device_id": 0, + "mac_block": 26, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 15, + "device_id": 0, + "mac_block": 25, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 16, + "device_id": 0, + "mac_block": 24, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 17, + "device_id": 0, + "mac_block": 23, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 18, + "device_id": 0, + "mac_block": 22, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 19, + "device_id": 0, + "mac_block": 21, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 20, + "device_id": 0, + "mac_block": 20, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 21, + "device_id": 0, + "mac_block": 19, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 22, + "device_id": 0, + "mac_block": 18, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 23, + "device_id": 0, + "mac_block": 17, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 24, + "device_id": 0, + "mac_block": 16, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 25, + "device_id": 0, + "mac_block": 15, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 26, + "device_id": 0, + "mac_block": 14, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 27, + "device_id": 0, + "mac_block": 13, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 28, + "device_id": 0, + "mac_block": 12, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 29, + "device_id": 0, + "mac_block": 11, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 30, + "device_id": 0, + "mac_block": 10, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 31, + "device_id": 0, + "mac_block": 9, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 32, + "device_id": 0, + "mac_block": 8, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + } + ] +} diff --git a/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/port_config.ini b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/port_config.ini new file mode 100644 index 000000000000..d983617f1891 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias speed index +Ethernet0 0,1,2,3 Ethernet1/1 100000 1 +Ethernet4 4,5,6,7 Ethernet2/1 100000 2 +Ethernet8 8,9,10,11 Ethernet3/1 100000 3 +Ethernet12 12,13,14,15 Ethernet4/1 100000 4 +Ethernet16 16,17,18,19 Ethernet5/1 100000 5 +Ethernet20 20,21,22,23 Ethernet6/1 100000 6 +Ethernet24 24,25,26,27 Ethernet7/1 100000 7 +Ethernet28 28,29,30,31 Ethernet8/1 100000 8 +Ethernet32 32,33,34,35 Ethernet9/1 100000 9 +Ethernet36 36,37,38,39 Ethernet10/1 100000 10 +Ethernet40 40,41,42,43 Ethernet11/1 100000 11 +Ethernet44 44,45,46,47 Ethernet12/1 100000 12 +Ethernet48 48,49,50,51 Ethernet13/1 100000 13 +Ethernet52 52,53,54,55 Ethernet14/1 100000 14 +Ethernet56 56,57,58,59 Ethernet15/1 100000 15 +Ethernet60 60,61,62,63 Ethernet16/1 100000 16 +Ethernet64 64,65,66,67 Ethernet17/1 100000 17 +Ethernet68 68,69,70,71 Ethernet18/1 100000 18 +Ethernet72 72,73,74,75 Ethernet19/1 100000 19 +Ethernet76 76,77,78,79 Ethernet20/1 100000 20 +Ethernet80 80,81,82,83 Ethernet21/1 100000 21 +Ethernet84 84,85,86,87 Ethernet22/1 100000 22 +Ethernet88 88,89,90,91 Ethernet23/1 100000 23 +Ethernet92 92,93,94,95 Ethernet24/1 100000 24 +Ethernet96 96,97,98,99 Ethernet25/1 100000 25 +Ethernet100 100,101,102,103 Ethernet26/1 100000 26 +Ethernet104 104,105,106,107 Ethernet27/1 100000 27 +Ethernet108 108,109,110,111 Ethernet28/1 100000 28 +Ethernet112 112,113,114,115 Ethernet29/1 100000 29 +Ethernet116 116,117,118,119 Ethernet30/1 100000 30 +Ethernet120 120,121,122,123 Ethernet31/1 100000 31 +Ethernet124 124,125,126,127 Ethernet32/1 100000 32 diff --git a/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-sai.conf b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-sai.conf new file mode 100644 index 000000000000..0a807b1c9ea7 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-sai.conf @@ -0,0 +1,33 @@ +{ + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:1c.4/0000:07:00.0", + "pcie_domain": 0, + "pcie_bus": 7, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "instance": 0, + "p4_program_list": [ + { + "id": "pgm-0", + "instance": 0, + "path": "switch", + "program-name": "switch", + "pd": "lib/tofinopd/switch/libpd.so", + "pd-thrift": "lib/tofinopd/switch/libpdthrift.so", + "table-config": "share/tofinopd/switch/context.json", + "tofino-bin": "share/tofinopd/switch/tofino.bin", + "switchapi": "lib/libswitchapi.so", + "sai": "lib/libsai.so", + "switchapi_port_add": false, + "non_default_port_ppgs": 5 + } + ] +} diff --git a/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-tna-sai.conf b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-tna-sai.conf new file mode 100644 index 000000000000..ece3fcbe6a90 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-tna-sai.conf @@ -0,0 +1,39 @@ +{ + "instance": 0, + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0", + "pcie_domain": 0, + "pcie_bus": 5, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "p4_devices": [ + { + "device-id": 0, + "p4_programs": [ + { + "p4_pipelines": [ + { + "p4_pipeline_name": "pipe", + "config": "share/switch/pipe/tofino.bin", + "context": "share/switch/pipe/context.json" + } + ], + "program-name": "switch", + "sai": "lib/libsai.so", + "bfrt-config": "share/switch/bf-rt.json", + "model_json_path" : "share/switch/aug_model.json", + "switchapi_port_add": false, + "non_default_port_ppgs": 5 + } + ] + } + ] +} diff --git a/device/arista/x86_64-arista_7170_32cd/default_sku b/device/arista/x86_64-arista_7170_32cd/default_sku new file mode 100644 index 000000000000..536bad44f086 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/default_sku @@ -0,0 +1 @@ +Arista-7170-32CD-C32 t1 diff --git a/device/arista/x86_64-arista_7170_32cd/platform_reboot b/device/arista/x86_64-arista_7170_32cd/platform_reboot new file mode 120000 index 000000000000..7f94a49e38b0 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/platform_reboot @@ -0,0 +1 @@ +../x86_64-arista_common/platform_reboot \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32cd/plugins b/device/arista/x86_64-arista_7170_32cd/plugins new file mode 120000 index 000000000000..789a45fcace9 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/plugins @@ -0,0 +1 @@ +../x86_64-arista_common/plugins \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32cd/sensors.conf b/device/arista/x86_64-arista_7170_32cd/sensors.conf new file mode 120000 index 000000000000..1ab9e0f47704 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/sensors.conf @@ -0,0 +1 @@ +../x86_64-arista_7170_64c/sensors.conf \ No newline at end of file diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/pltfm_mgr_rpc/__init__.py b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/pltfm_mgr_rpc/__init__.py index 09cb959f2d46..414c3d6389c5 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/pltfm_mgr_rpc/__init__.py +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/pltfm_mgr_rpc/__init__.py @@ -1 +1 @@ -__all__ = ['ttypes', 'constants', 'pltfm_mgr_rpc'] +__all__ = ['ttypes', 'pltfm_mgr_rpc'] diff --git a/device/celestica/x86_64-cel_e1031-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_e1031-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/celestica/x86_64-cel_e1031-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py index 99eb49ce53e0..719170d831b7 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py @@ -19,7 +19,6 @@ from sonic_platform.fan import Fan from sonic_platform.psu import Psu from sonic_platform.component import Component - from sonic_platform.watchdog import Watchdog from sonic_platform.thermal import Thermal from sonic_platform.sfp import Sfp from sonic_platform.eeprom import Tlv @@ -54,7 +53,9 @@ def __init__(self): for index in range(0, NUM_THERMAL): thermal = Thermal(index) self._thermal_list.append(thermal) - for index in range(0, NUM_SFP): + # sfp index start from 1 + self._sfp_list.append(None) + for index in range(1, NUM_SFP+1): sfp = Sfp(index) self._sfp_list.append(sfp) for index in range(0, NUM_COMPONENT): @@ -63,7 +64,6 @@ def __init__(self): self._reboot_cause_path = HOST_REBOOT_CAUSE_PATH if self.__is_host( ) else PMON_REBOOT_CAUSE_PATH - self._watchdog = Watchdog() self._eeprom = Tlv() def __is_host(self): @@ -134,3 +134,16 @@ def get_reboot_cause(self): description = 'Unknown reason' return (reboot_cause, description) + + def get_watchdog(self): + """ + Retreives hardware watchdog device on this chassis + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + """ + if self._watchdog is None: + from sonic_platform.watchdog import Watchdog + self._watchdog = Watchdog() + + return self._watchdog diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py index ad6810b14c38..fe34bc45c670 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py @@ -140,7 +140,7 @@ def install_firmware(self, image_path): new_image_path = os.path.join("/tmp", (root.lower() + ext)) shutil.copy(image_path, new_image_path) install_command = "ispvm %s" % new_image_path - elif self.name == "BIOS": - install_command = "afulnx_64 %s /p /b /n /x /r" % image_path + # elif self.name == "BIOS": + # install_command = "afulnx_64 %s /p /b /n /x /r" % image_path return self.__run_command(install_command) diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py index 4cfdcf50b66d..6ef8838ba8af 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py @@ -94,7 +94,7 @@ class Sfp(SfpBase): def __init__(self, sfp_index): # Init index self.index = sfp_index - self.port_num = self.index + 1 + self.port_num = self.index # Init eeprom path eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' diff --git a/device/celestica/x86_64-cel_midstone-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_midstone-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/port_config.ini b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/port_config.ini new file mode 100644 index 000000000000..4bc2ce344039 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed +Ethernet0 65,66 Eth1/1 1 50000 +Ethernet2 67,68 Eth1/2 1 50000 +Ethernet4 69,70 Eth2/1 2 50000 +Ethernet6 71,72 Eth2/2 2 50000 +Ethernet8 73,74 Eth3/1 3 50000 +Ethernet10 75,76 Eth3/2 3 50000 +Ethernet12 77,78 Eth4/1 4 50000 +Ethernet14 79,80 Eth4/2 4 50000 +Ethernet16 33,34 Eth5/1 5 50000 +Ethernet18 35,36 Eth5/2 5 50000 +Ethernet20 37,38 Eth6/1 6 50000 +Ethernet22 39,40 Eth6/2 6 50000 +Ethernet24 41,42 Eth7/1 7 50000 +Ethernet26 43,44 Eth7/2 7 50000 +Ethernet28 45,46 Eth8/1 8 50000 +Ethernet30 47,48 Eth8/2 8 50000 +Ethernet32 49,50 Eth9/1 9 50000 +Ethernet34 51,52 Eth9/2 9 50000 +Ethernet36 53,54 Eth10/1 10 50000 +Ethernet38 55,56 Eth10/2 10 50000 +Ethernet40 57,58 Eth11/1 11 50000 +Ethernet42 59,60 Eth11/2 11 50000 +Ethernet44 61,62 Eth12/1 12 50000 +Ethernet46 63,64 Eth12/2 12 50000 +Ethernet48 81,82 Eth13/1 13 50000 +Ethernet50 83,84 Eth13/2 13 50000 +Ethernet52 85,86 Eth14/1 14 50000 +Ethernet54 87,88 Eth14/2 14 50000 +Ethernet56 89,90 Eth15/1 15 50000 +Ethernet58 91,92 Eth15/2 15 50000 +Ethernet60 93,94 Eth16/1 16 50000 +Ethernet62 95,96 Eth16/2 16 50000 +Ethernet64 97,98 Eth17/1 17 50000 +Ethernet66 99,100 Eth17/2 17 50000 +Ethernet68 101,102 Eth18/1 18 50000 +Ethernet70 103,104 Eth18/2 18 50000 +Ethernet72 105,106 Eth19/1 19 50000 +Ethernet74 107,108 Eth19/2 19 50000 +Ethernet76 109,110 Eth20/1 20 50000 +Ethernet78 111,112 Eth20/2 20 50000 +Ethernet80 1,2 Eth21/1 21 50000 +Ethernet82 3,4 Eth21/2 21 50000 +Ethernet84 5,6 Eth22/1 22 50000 +Ethernet86 7,8 Eth22/2 22 50000 +Ethernet88 9,10 Eth23/1 23 50000 +Ethernet90 11,12 Eth23/2 23 50000 +Ethernet92 13,14 Eth24/1 24 50000 +Ethernet94 15,16 Eth24/2 24 50000 +Ethernet96 17,18,19,20 Eth25 25 40000 +Ethernet100 21,22,23,24 Eth26 26 40000 +Ethernet104 25,26,27,28 Eth27 27 40000 +Ethernet108 29,30,31,32 Eth28 28 40000 +Ethernet112 113,114,115,116 Eth29 29 40000 +Ethernet116 117,118,119,120 Eth30 30 40000 +Ethernet120 121,122,123,124 Eth31 31 40000 +Ethernet124 125,126,127,128 Eth32 32 40000 diff --git a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/sai.profile b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/sai.profile new file mode 100644 index 000000000000..7342ae8002e8 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/platform/th-seastone-dx010-config-flex-all.bcm diff --git a/device/celestica/x86_64-cel_seastone-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_seastone-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py index c9447b56a2fe..7db46e55bd8c 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py @@ -19,7 +19,6 @@ from sonic_platform.fan import Fan from sonic_platform.psu import Psu from sonic_platform.component import Component - from sonic_platform.watchdog import Watchdog from sonic_platform.thermal import Thermal from sonic_platform.sfp import Sfp from sonic_platform.eeprom import Tlv @@ -56,14 +55,15 @@ def __init__(self): for index in range(0, NUM_THERMAL): thermal = Thermal(index) self._thermal_list.append(thermal) - for index in range(0, NUM_SFP): + # sfp index start from 1 + self._sfp_list.append(None) + for index in range(1, NUM_SFP+1): sfp = Sfp(index) self._sfp_list.append(sfp) for index in range(0, NUM_COMPONENT): component = Component(index) self._component_list.append(component) - self._watchdog = Watchdog() self._eeprom = Tlv() def __is_host(self): @@ -146,3 +146,16 @@ def get_reboot_cause(self): description = 'Unknown reason' return (reboot_cause, description) + + def get_watchdog(self): + """ + Retreives hardware watchdog device on this chassis + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + """ + if self._watchdog is None: + from sonic_platform.watchdog import Watchdog + self._watchdog = Watchdog() + + return self._watchdog diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py index 67c7a9c46341..d94a93474452 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py @@ -141,7 +141,7 @@ def install_firmware(self, image_path): new_image_path = os.path.join("/tmp", (root.lower() + ext)) shutil.copy(image_path, new_image_path) install_command = "ispvm %s" % new_image_path - elif self.name == "BIOS": - install_command = "afulnx_64 %s /p /b /n /x /r" % image_path + # elif self.name == "BIOS": + # install_command = "afulnx_64 %s /p /b /n /x /r" % image_path return self.__run_command(install_command) diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py index 3a02be39df6e..04fb36b72b8f 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py @@ -100,7 +100,7 @@ class Sfp(SfpBase): def __init__(self, sfp_index): # Init index self.index = sfp_index - self.port_num = self.index + 1 if self.PORT_START == 1 else index + self.port_num = self.index # Init eeprom path eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' diff --git a/device/celestica/x86_64-cel_silverstone-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_silverstone-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/buffers.json.j2 b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/buffers.json.j2 new file mode 100644 index 000000000000..2c391214fa65 --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/buffers.json.j2 @@ -0,0 +1,111 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} +{% set default_speed = '10G' %} +{% set default_ports_num = 54 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + }, + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "20971328", + "type": "ingress", + "mode": "static" + }, + "ingress_lossy_pool": { + "size": "20971328", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "20971328", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xon":"78400", + "xoff":"132160", + "size":"3584", + "static_th":"82880" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"3584", + "dynamic_th":"-1" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"3584", + "dynamic_th":"-4" + } + }, + "BUFFER_PG": { + }, + "BUFFER_QUEUE": { + } +} + \ No newline at end of file diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/led.bin b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/led.bin new file mode 100644 index 000000000000..201662a1c605 Binary files /dev/null and b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/led.bin differ diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/pg_profile_lookup.ini b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/pg_profile_lookup.ini new file mode 100644 index 000000000000..d98b0eca6d19 --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 3584 32256 59136 36736 + 25000 5m 3584 41216 68096 45696 + 40000 5m 3584 47488 74368 51968 + 50000 5m 3584 52864 79744 57344 + 100000 5m 3584 78400 132160 82880 + 10000 40m 3584 32256 59136 36736 + 25000 40m 3584 41216 68096 45696 + 40000 40m 3584 47488 74368 51968 + 50000 40m 3584 52864 79744 57344 + 100000 40m 3584 78400 132160 82880 + 10000 300m 3584 32256 65856 36736 + 25000 300m 3584 41216 84672 45696 + 40000 300m 3584 47488 101024 51968 + 50000 300m 3584 52864 113120 57344 + 100000 300m 3584 78400 198688 82880 \ No newline at end of file diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.ini b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.ini new file mode 100644 index 000000000000..ab29b7bed9ff --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.ini @@ -0,0 +1,55 @@ +# name lanes alias index speed +Ethernet0 8 Ethernet1/1 1 10000 +Ethernet1 9 Ethernet2/1 2 10000 +Ethernet2 10 Ethernet3/1 3 10000 +Ethernet3 11 Ethernet4/1 4 10000 +Ethernet4 12 Ethernet5/1 5 10000 +Ethernet5 13 Ethernet6/1 6 10000 +Ethernet6 14 Ethernet7/1 7 10000 +Ethernet7 15 Ethernet8/1 8 10000 +Ethernet8 16 Ethernet9/1 9 10000 +Ethernet9 17 Ethernet10/1 10 10000 +Ethernet10 18 Ethernet11/1 11 10000 +Ethernet11 19 Ethernet12/1 12 10000 +Ethernet12 20 Ethernet13/1 13 10000 +Ethernet13 21 Ethernet14/1 14 10000 +Ethernet14 22 Ethernet15/1 15 10000 +Ethernet15 23 Ethernet16/1 16 10000 +Ethernet16 32 Ethernet17/1 17 10000 +Ethernet17 33 Ethernet18/1 18 10000 +Ethernet18 34 Ethernet19/1 19 10000 +Ethernet19 35 Ethernet20/1 20 10000 +Ethernet20 40 Ethernet21/1 21 10000 +Ethernet21 41 Ethernet22/1 22 10000 +Ethernet22 42 Ethernet23/1 23 10000 +Ethernet23 43 Ethernet24/1 24 10000 +Ethernet24 48 Ethernet25/1 25 10000 +Ethernet25 49 Ethernet26/1 26 10000 +Ethernet26 50 Ethernet27/1 27 10000 +Ethernet27 51 Ethernet28/1 28 10000 +Ethernet28 56 Ethernet29/1 29 10000 +Ethernet29 57 Ethernet30/1 30 10000 +Ethernet30 58 Ethernet31/1 31 10000 +Ethernet31 59 Ethernet32/1 32 10000 +Ethernet32 64 Ethernet33/1 33 10000 +Ethernet33 65 Ethernet34/1 34 10000 +Ethernet34 66 Ethernet35/1 35 10000 +Ethernet35 67 Ethernet36/1 36 10000 +Ethernet36 68 Ethernet37/1 37 10000 +Ethernet37 69 Ethernet38/1 38 10000 +Ethernet38 70 Ethernet39/1 39 10000 +Ethernet39 71 Ethernet40/1 40 10000 +Ethernet40 72 Ethernet41/1 41 10000 +Ethernet41 73 Ethernet42/1 42 10000 +Ethernet42 74 Ethernet43/1 43 10000 +Ethernet43 75 Ethernet44/1 44 10000 +Ethernet44 76 Ethernet45/1 45 10000 +Ethernet45 77 Ethernet46/1 46 10000 +Ethernet46 78 Ethernet47/1 47 10000 +Ethernet47 79 Ethernet48/1 48 10000 +Ethernet48 84,85,86,87 Ethernet49/1 49 100000 +Ethernet49 80,81,82,83 Ethernet50/1 50 100000 +Ethernet50 108,109,110,111 Ethernet51/1 51 100000 +Ethernet51 104,105,106,107 Ethernet52/1 52 100000 +Ethernet52 116,117,118,119 Ethernet53/1 53 100000 +Ethernet53 112,113,114,115 Ethernet54/1 54 100000 diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.DAC.R0B b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.nps old mode 100755 new mode 100644 similarity index 82% rename from device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.DAC.R0B rename to device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.nps index 857e5f1ede5f..9c6a5af8e5f0 --- a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.DAC.R0B +++ b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.nps @@ -1,60 +1,58 @@ init start stage unit=0 low-level -init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true -init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true -init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true -init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true -init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true -init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true -init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true -init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true -init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true -init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true -init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true -init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true -init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true -init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true -init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true -init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true -init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true -init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true -init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true -init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true -init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=25g active=true -init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=25g active=true -init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=25g active=true -init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=25g active=true -init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=25g active=true -init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=25g active=true -init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=25g active=true -init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=25g active=true -init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=25g active=true -init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=25g active=true -init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=25g active=true -init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=25g active=true -init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=25g active=true -init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=25g active=true -init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=25g active=true -init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=25g active=true -init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=25g active=true -init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=25g active=true -init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=25g active=true -init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=25g active=true -init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=25g active=true -init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=25g active=true -init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=25g active=true -init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=25g active=true -init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=25g active=true -init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=25g active=true -init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=25g active=true -init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=25g active=true +init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=10g active=true +init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=10g active=true +init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=10g active=true +init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=10g active=true +init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=10g active=true +init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=10g active=true +init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=10g active=true +init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=10g active=true +init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=10g active=true +init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=10g active=true +init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=10g active=true +init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=10g active=true +init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=10g active=true +init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=10g active=true +init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=10g active=true +init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=10g active=true +init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=10g active=true +init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=10g active=true +init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=10g active=true +init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=10g active=true +init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=10g active=true +init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=10g active=true +init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=10g active=true +init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=10g active=true +init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=10g active=true +init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=10g active=true +init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=10g active=true +init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=10g active=true +init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=10g active=true +init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=10g active=true +init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=10g active=true +init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=10g active=true +init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=10g active=true +init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=10g active=true +init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=10g active=true +init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=10g active=true +init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=10g active=true +init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=10g active=true +init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=10g active=true +init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=10g active=true +init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=10g active=true +init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=10g active=true +init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=10g active=true +init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=10g active=true +init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=10g active=true +init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=10g active=true +init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=10g active=true +init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=10g active=true init set port-map unit=0 port=48 eth-macro=21 lane=0 max-speed=100g active=true init set port-map unit=0 port=49 eth-macro=20 lane=0 max-speed=100g active=true -init set port-map unit=0 port=50 eth-macro=23 lane=0 max-speed=100g active=true -init set port-map unit=0 port=51 eth-macro=22 lane=0 max-speed=100g active=true -init set port-map unit=0 port=52 eth-macro=27 lane=0 max-speed=100g active=true -init set port-map unit=0 port=53 eth-macro=26 lane=0 max-speed=100g active=true -init set port-map unit=0 port=54 eth-macro=29 lane=0 max-speed=100g active=true -init set port-map unit=0 port=55 eth-macro=28 lane=0 max-speed=100g active=true +init set port-map unit=0 port=50 eth-macro=27 lane=0 max-speed=100g active=true +init set port-map unit=0 port=51 eth-macro=26 lane=0 max-speed=100g active=true +init set port-map unit=0 port=52 eth-macro=29 lane=0 max-speed=100g active=true +init set port-map unit=0 port=53 eth-macro=28 lane=0 max-speed=100g active=true init set port-map unit=0 port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true init set port-map unit=0 port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true init start stage unit=0 task-rsrc @@ -110,12 +108,10 @@ phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=tx data=0x2 phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=tx data=0x3 phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=tx data=0x3.0.1.2 phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x3.2.0.1 +phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x3.2.1.0 +phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x3.2.1.0 phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=tx data=0x3.2.1.0 phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=54 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=55 lane-cnt=4 property=tx data=0x3.2.1.0 phy set lane-swap unit=0 portlist=129 lane-cnt=1 property=tx data=0x1 phy set lane-swap unit=0 portlist=130 lane-cnt=1 property=tx data=0x0 phy set lane-swap unit=0 portlist=0 lane-cnt=1 property=rx data=0x0 @@ -168,12 +164,10 @@ phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=rx data=0x0 phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=rx data=0x3 phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=rx data=0x3.1.0.2 phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=rx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x3.0.1.2 -phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.0.3.2 +phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x2.0.1.3 phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=rx data=0x1.0.3.2 -phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x2.0.1.3 -phy set lane-swap unit=0 portlist=54 lane-cnt=4 property=rx data=0x1.0.3.2 -phy set lane-swap unit=0 portlist=55 lane-cnt=4 property=rx data=0x1.0.3.2 +phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x1.0.3.2 phy set lane-swap unit=0 portlist=129 lane-cnt=1 property=rx data=0x1 phy set lane-swap unit=0 portlist=130 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=tx data=0x0 @@ -230,8 +224,6 @@ phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=54 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=55 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=129 lane-cnt=1 property=tx data=0x0 phy set polarity-rev unit=0 portlist=130 lane-cnt=1 property=tx data=0x0 phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=rx data=0x0 @@ -284,12 +276,10 @@ phy set polarity-rev unit=0 portlist=46 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=47 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=rx data=0x0.1.1.0 phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.1.1.1 +phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.1.1.0 phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=rx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=rx data=0x1.1.1.0 phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=54 lane-cnt=4 property=rx data=0x1.1.1.0 -phy set polarity-rev unit=0 portlist=55 lane-cnt=4 property=rx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=129 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=130 lane-cnt=1 property=rx data=0x0 phy set pre-emphasis unit=0 portlist=0 lane-cnt=1 property=c2 data=0x2 @@ -508,14 +498,6 @@ phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=cn1 data=0x0.0.0.0 phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=c2 data=0x1 phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=cn1 data=0x1 phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=c0 data=0x2 @@ -524,62 +506,60 @@ phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=c2 data=0x1 phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=cn1 data=0x0 phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=c0 data=0x2 phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=c1 data=0x3 -port set property unit=0 portlist=0 speed=25g -port set property unit=0 portlist=1 speed=25g -port set property unit=0 portlist=2 speed=25g -port set property unit=0 portlist=3 speed=25g -port set property unit=0 portlist=4 speed=25g -port set property unit=0 portlist=5 speed=25g -port set property unit=0 portlist=6 speed=25g -port set property unit=0 portlist=7 speed=25g -port set property unit=0 portlist=8 speed=25g -port set property unit=0 portlist=9 speed=25g -port set property unit=0 portlist=10 speed=25g -port set property unit=0 portlist=11 speed=25g -port set property unit=0 portlist=12 speed=25g -port set property unit=0 portlist=13 speed=25g -port set property unit=0 portlist=14 speed=25g -port set property unit=0 portlist=15 speed=25g -port set property unit=0 portlist=16 speed=25g -port set property unit=0 portlist=17 speed=25g -port set property unit=0 portlist=18 speed=25g -port set property unit=0 portlist=19 speed=25g -port set property unit=0 portlist=20 speed=25g -port set property unit=0 portlist=21 speed=25g -port set property unit=0 portlist=22 speed=25g -port set property unit=0 portlist=23 speed=25g -port set property unit=0 portlist=24 speed=25g -port set property unit=0 portlist=25 speed=25g -port set property unit=0 portlist=26 speed=25g -port set property unit=0 portlist=27 speed=25g -port set property unit=0 portlist=28 speed=25g -port set property unit=0 portlist=29 speed=25g -port set property unit=0 portlist=30 speed=25g -port set property unit=0 portlist=31 speed=25g -port set property unit=0 portlist=32 speed=25g -port set property unit=0 portlist=33 speed=25g -port set property unit=0 portlist=34 speed=25g -port set property unit=0 portlist=35 speed=25g -port set property unit=0 portlist=36 speed=25g -port set property unit=0 portlist=37 speed=25g -port set property unit=0 portlist=38 speed=25g -port set property unit=0 portlist=39 speed=25g -port set property unit=0 portlist=40 speed=25g -port set property unit=0 portlist=41 speed=25g -port set property unit=0 portlist=42 speed=25g -port set property unit=0 portlist=43 speed=25g -port set property unit=0 portlist=44 speed=25g -port set property unit=0 portlist=45 speed=25g -port set property unit=0 portlist=46 speed=25g -port set property unit=0 portlist=47 speed=25g +port set property unit=0 portlist=0 speed=10g +port set property unit=0 portlist=1 speed=10g +port set property unit=0 portlist=2 speed=10g +port set property unit=0 portlist=3 speed=10g +port set property unit=0 portlist=4 speed=10g +port set property unit=0 portlist=5 speed=10g +port set property unit=0 portlist=6 speed=10g +port set property unit=0 portlist=7 speed=10g +port set property unit=0 portlist=8 speed=10g +port set property unit=0 portlist=9 speed=10g +port set property unit=0 portlist=10 speed=10g +port set property unit=0 portlist=11 speed=10g +port set property unit=0 portlist=12 speed=10g +port set property unit=0 portlist=13 speed=10g +port set property unit=0 portlist=14 speed=10g +port set property unit=0 portlist=15 speed=10g +port set property unit=0 portlist=16 speed=10g +port set property unit=0 portlist=17 speed=10g +port set property unit=0 portlist=18 speed=10g +port set property unit=0 portlist=19 speed=10g +port set property unit=0 portlist=20 speed=10g +port set property unit=0 portlist=21 speed=10g +port set property unit=0 portlist=22 speed=10g +port set property unit=0 portlist=23 speed=10g +port set property unit=0 portlist=24 speed=10g +port set property unit=0 portlist=25 speed=10g +port set property unit=0 portlist=26 speed=10g +port set property unit=0 portlist=27 speed=10g +port set property unit=0 portlist=28 speed=10g +port set property unit=0 portlist=29 speed=10g +port set property unit=0 portlist=30 speed=10g +port set property unit=0 portlist=31 speed=10g +port set property unit=0 portlist=32 speed=10g +port set property unit=0 portlist=33 speed=10g +port set property unit=0 portlist=34 speed=10g +port set property unit=0 portlist=35 speed=10g +port set property unit=0 portlist=36 speed=10g +port set property unit=0 portlist=37 speed=10g +port set property unit=0 portlist=38 speed=10g +port set property unit=0 portlist=39 speed=10g +port set property unit=0 portlist=40 speed=10g +port set property unit=0 portlist=41 speed=10g +port set property unit=0 portlist=42 speed=10g +port set property unit=0 portlist=43 speed=10g +port set property unit=0 portlist=44 speed=10g +port set property unit=0 portlist=45 speed=10g +port set property unit=0 portlist=46 speed=10g +port set property unit=0 portlist=47 speed=10g port set property unit=0 portlist=48 speed=100g port set property unit=0 portlist=49 speed=100g port set property unit=0 portlist=50 speed=100g port set property unit=0 portlist=51 speed=100g port set property unit=0 portlist=52 speed=100g port set property unit=0 portlist=53 speed=100g -port set property unit=0 portlist=54 speed=100g -port set property unit=0 portlist=55 speed=100g port set property unit=0 portlist=129 speed=10g port set property unit=0 portlist=130 speed=1g port set property unit=0 portlist=0 medium-type=sr @@ -636,8 +616,6 @@ port set property unit=0 portlist=50 medium-type=sr4 port set property unit=0 portlist=51 medium-type=sr4 port set property unit=0 portlist=52 medium-type=sr4 port set property unit=0 portlist=53 medium-type=sr4 -port set property unit=0 portlist=54 medium-type=sr4 -port set property unit=0 portlist=55 medium-type=sr4 port set property unit=0 portlist=129 medium-type=kr port set property unit=0 portlist=130 medium-type=x port advertise unit=0 portlist=129 speed-10g-kr @@ -696,7 +674,5 @@ port set property unit=0 portlist=50 admin=enable port set property unit=0 portlist=51 admin=enable port set property unit=0 portlist=52 admin=enable port set property unit=0 portlist=53 admin=enable -port set property unit=0 portlist=54 admin=enable -port set property unit=0 portlist=55 admin=enable -port set property unit=0 portlist=129 admin=enable -port set property unit=0 portlist=130 admin=enable +port set property unit=0 portlist=129 admin=disable +port set property unit=0 portlist=130 admin=disable diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/qos.json.j2 b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/sai.profile b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/sai.profile new file mode 100644 index 000000000000..e7b5f90ac88a --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/sai.profile @@ -0,0 +1,3 @@ +SAI_INIT_LED_CONFIG_FILE=/usr/share/sonic/hwsku/led.bin +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/proc_init.nps +SAI_DSH_CONFIG_FILE=/usr/share/sonic/hwsku/port_config.nps diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/default_sku b/device/cig/x86_64-cig_cs5435_54p-r0/default_sku new file mode 100644 index 000000000000..66b35b61e09b --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/default_sku @@ -0,0 +1 @@ +Cig-CS5435-54P t1 diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/installer.conf b/device/cig/x86_64-cig_cs5435_54p-r0/installer.conf new file mode 100644 index 000000000000..ea6b4f6ebe31 --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/installer.conf @@ -0,0 +1,4 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="pci=noaer" diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/plugins/eeprom.py b/device/cig/x86_64-cig_cs5435_54p-r0/plugins/eeprom.py new file mode 100755 index 000000000000..5019b9c40a9a --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/plugins/eeprom.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +try: + import exceptions + import binascii + import time + import optparse + import warnings + import os + import sys + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + import subprocess +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/bus/i2c/devices/7-0057/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/plugins/psuutil.py b/device/cig/x86_64-cig_cs5435_54p-r0/plugins/psuutil.py new file mode 100755 index 000000000000..70d50e6c3458 --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/plugins/psuutil.py @@ -0,0 +1,93 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + + +import os.path +import logging + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + SYSFS_PSU_DIR = ["/sys/bus/i2c/devices/5-005a", + "/sys/bus/i2c/devices/5-005b"] + + def __init__(self): + PsuBase.__init__(self) + + + # Get sysfs attribute + def get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open %s file !", attr_path) + + retval = retval.rstrip('\r\n') + return retval + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + MAX_PSUS = 2 + return MAX_PSUS + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is\ + faulty + """ + status = 0 + attr_file = 'psu_power_good' + attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + + attr_value = self.get_attr_value(attr_path) + + if (attr_value != 'ERR'): + attr_value = int(attr_value, 16) + # Check for PSU status + if (attr_value == 1): + status = 1 + + return status + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + psu_absent = 0 + attr_file ='psu_present' + attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + + attr_value = self.get_attr_value(attr_path) + + if (attr_value != 'ERR'): + attr_value = int(attr_value, 16) + # Check for PSU presence + if (attr_value == 1): + status = 1 + + return status + diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/plugins/sfputil.py b/device/cig/x86_64-cig_cs5435_54p-r0/plugins/sfputil.py new file mode 100755 index 000000000000..2863b80c9950 --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/plugins/sfputil.py @@ -0,0 +1,250 @@ +#!/usr/bin/env python + +try: + import time + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class SfpUtil(SfpUtilBase): + """Platform specific SfpUtill class""" + + _port_start = 1 + _port_end = 54 + _qsfp_port_start = 49 + _ports_in_block = 54 + + _port_to_eeprom_mapping = {} + _global_port_pres_dict = {} + + _port_to_i2c_mapping = { + 1 : 8, + 2 : 9, + 3 : 10, + 4 : 11, + 5 : 12, + 6 : 13, + 7 : 14, + 8 : 15, + 9 : 16, + 10: 17, + 11 : 18, + 12 : 19, + 13 : 20, + 14 : 21, + 15 : 22, + 16 : 23, + 17 : 24, + 18 : 25, + 19 : 26, + 20 : 27, + 21 : 28, + 22 : 29, + 23 : 30, + 24 : 31, + 25 : 32, + 26 : 33, + 27 : 34, + 28 : 35, + 29 : 36, + 30 : 37, + 31 : 38, + 32 : 39, + 33 : 40, + 34 : 41, + 35 : 42, + 36 : 43, + 37 : 44, + 38 : 45, + 39 : 46, + 40 : 47, + 41 : 48, + 42 : 49, + 43 : 50, + 44 : 51, + 45 : 52, + 46 : 53, + 47 : 54, + 48 : 55, + 49 : 56, + 50 : 57, + 51 : 60, + 52 : 61, + 53 : 62, + 54 : 63, + } + + _qsfp_ports = range(_qsfp_port_start, _ports_in_block + 1) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + + try: + reg_file = open(port_ps) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + time.sleep(1) + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + print "Error:try again to read file failed: %s %s" % (str(e), port_ps) + reg_file.close() + return False + + reg_file.close() + if reg_value == '1': + return True + + reg_file.close() + if reg_value == '1': + return True + + return False + + def init_global_port_presence(self): + for port_num in range(self.port_start, (self.port_end + 1)): + self._global_port_pres_dict[port_num] = '0' + + + def __init__(self): + eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp_eeprom' + for x in range(self._port_start, self._port_end + 1): + port_eeprom_path = eeprom_path.format(self._port_to_i2c_mapping[x]) + self._port_to_eeprom_mapping[x] = port_eeprom_path + + self.init_global_port_presence() + SfpUtilBase.__init__(self) + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_port_reset" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps, 'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + #toggle reset + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self._qsfp_port_start or port_num > self._port_end: + return False + + pre_value = self.get_presence(port_num) + if pre_value == False: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps,'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_file.seek(0) + + if lpmode == 1: + reg_file.write('1') + elif lpmode == 0: + reg_file.write('0') + reg_file.close() + + return True + + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + + if port_num < self._qsfp_port_start or port_num > self._port_end: + return False + + pre_value = self.get_presence(port_num) + if pre_value == False: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps) + except IOError as e: + print "Error: unable to open file:%s %s" % (str(e), port_ps) + return False + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + print "Error: unable to open file:%s %s" % (str(e), port_ps) + reg_file.close() + return False + + reg_file.close() + + if reg_value == '1': + return True + + return False + + def get_transceiver_change_event(self): + port_dict = {} + while True: + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + + if(presence and self._global_port_pres_dict[port_num] == '0'): + self._global_port_pres_dict[port_num] = '1' + port_dict[port_num] = '1' + elif(not presence and + self._global_port_pres_dict[port_num] == '1'): + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + + if(len(port_dict) > 0): + return True, port_dict + + time.sleep(0.5) + + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return self._qsfp_ports + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/sensors.conf b/device/cig/x86_64-cig_cs5435_54p-r0/sensors.conf new file mode 100644 index 000000000000..f0964c87dae7 --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/sensors.conf @@ -0,0 +1,13 @@ +# libsensors configuration file + +chip "cs5435_54p_fan-*" + label fan1 "front fan 1" + label fan2 "front fan 2" + label fan3 "front fan 3" + label fan4 "front fan 4" + label fan5 "front fan 5" + label fan6 "rear fan 1" + label fan7 "rear fan 2" + label fan8 "rear fan 3" + label fan9 "rear fan 4" + label fan10 "rear fan 5" diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/buffers.json.j2 b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/buffers.json.j2 new file mode 100644 index 000000000000..2c391214fa65 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/buffers.json.j2 @@ -0,0 +1,111 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} +{% set default_speed = '10G' %} +{% set default_ports_num = 54 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + }, + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "20971328", + "type": "ingress", + "mode": "static" + }, + "ingress_lossy_pool": { + "size": "20971328", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "20971328", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xon":"78400", + "xoff":"132160", + "size":"3584", + "static_th":"82880" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"3584", + "dynamic_th":"-1" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"3584", + "dynamic_th":"-4" + } + }, + "BUFFER_PG": { + }, + "BUFFER_QUEUE": { + } +} + \ No newline at end of file diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/led.bin b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/led.bin new file mode 100644 index 000000000000..201662a1c605 Binary files /dev/null and b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/led.bin differ diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/pg_profile_lookup.ini b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/pg_profile_lookup.ini new file mode 100644 index 000000000000..d98b0eca6d19 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 3584 32256 59136 36736 + 25000 5m 3584 41216 68096 45696 + 40000 5m 3584 47488 74368 51968 + 50000 5m 3584 52864 79744 57344 + 100000 5m 3584 78400 132160 82880 + 10000 40m 3584 32256 59136 36736 + 25000 40m 3584 41216 68096 45696 + 40000 40m 3584 47488 74368 51968 + 50000 40m 3584 52864 79744 57344 + 100000 40m 3584 78400 132160 82880 + 10000 300m 3584 32256 65856 36736 + 25000 300m 3584 41216 84672 45696 + 40000 300m 3584 47488 101024 51968 + 50000 300m 3584 52864 113120 57344 + 100000 300m 3584 78400 198688 82880 \ No newline at end of file diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.ini b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.ini new file mode 100644 index 000000000000..165b5204c2f8 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.ini @@ -0,0 +1,55 @@ +# name lanes alias index speed +Ethernet0 8 Ethernet1/1 1 25000 +Ethernet1 9 Ethernet2/1 2 25000 +Ethernet2 10 Ethernet3/1 3 25000 +Ethernet3 11 Ethernet4/1 4 25000 +Ethernet4 12 Ethernet5/1 5 25000 +Ethernet5 13 Ethernet6/1 6 25000 +Ethernet6 14 Ethernet7/1 7 25000 +Ethernet7 15 Ethernet8/1 8 25000 +Ethernet8 16 Ethernet9/1 9 25000 +Ethernet9 17 Ethernet10/1 10 25000 +Ethernet10 18 Ethernet11/1 11 25000 +Ethernet11 19 Ethernet12/1 12 25000 +Ethernet12 20 Ethernet13/1 13 25000 +Ethernet13 21 Ethernet14/1 14 25000 +Ethernet14 22 Ethernet15/1 15 25000 +Ethernet15 23 Ethernet16/1 16 25000 +Ethernet16 32 Ethernet17/1 17 25000 +Ethernet17 33 Ethernet18/1 18 25000 +Ethernet18 34 Ethernet19/1 19 25000 +Ethernet19 35 Ethernet20/1 20 25000 +Ethernet20 40 Ethernet21/1 21 25000 +Ethernet21 41 Ethernet22/1 22 25000 +Ethernet22 42 Ethernet23/1 23 25000 +Ethernet23 43 Ethernet24/1 24 25000 +Ethernet24 48 Ethernet25/1 25 25000 +Ethernet25 49 Ethernet26/1 26 25000 +Ethernet26 50 Ethernet27/1 27 25000 +Ethernet27 51 Ethernet28/1 28 25000 +Ethernet28 56 Ethernet29/1 29 25000 +Ethernet29 57 Ethernet30/1 30 25000 +Ethernet30 58 Ethernet31/1 31 25000 +Ethernet31 59 Ethernet32/1 32 25000 +Ethernet32 64 Ethernet33/1 33 25000 +Ethernet33 65 Ethernet34/1 34 25000 +Ethernet34 66 Ethernet35/1 35 25000 +Ethernet35 67 Ethernet36/1 36 25000 +Ethernet36 68 Ethernet37/1 37 25000 +Ethernet37 69 Ethernet38/1 38 25000 +Ethernet38 70 Ethernet39/1 39 25000 +Ethernet39 71 Ethernet40/1 40 25000 +Ethernet40 72 Ethernet41/1 41 25000 +Ethernet41 73 Ethernet42/1 42 25000 +Ethernet42 74 Ethernet43/1 43 25000 +Ethernet43 75 Ethernet44/1 44 25000 +Ethernet44 76 Ethernet45/1 45 25000 +Ethernet45 77 Ethernet46/1 46 25000 +Ethernet46 78 Ethernet47/1 47 25000 +Ethernet47 79 Ethernet48/1 48 25000 +Ethernet48 84,85,86,87 Ethernet49/1 49 100000 +Ethernet49 80,81,82,83 Ethernet50/1 50 100000 +Ethernet50 108,109,110,111 Ethernet51/1 51 100000 +Ethernet51 104,105,106,107 Ethernet52/1 52 100000 +Ethernet52 116,117,118,119 Ethernet53/1 53 100000 +Ethernet53 112,113,114,115 Ethernet54/1 54 100000 diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.AOC.R0B b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.nps old mode 100755 new mode 100644 similarity index 92% rename from device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.AOC.R0B rename to device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.nps index 857e5f1ede5f..aca222f5962d --- a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.AOC.R0B +++ b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.nps @@ -1,24 +1,24 @@ init start stage unit=0 low-level -init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true -init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true -init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true -init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true -init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true -init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true -init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true -init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true -init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true -init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true -init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true -init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true -init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true -init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true -init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true -init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true -init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true -init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true -init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true -init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true +init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true +init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true +init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true +init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true +init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true +init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true +init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true +init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true +init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true +init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true +init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true +init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true +init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true +init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true +init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true +init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true +init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true +init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true +init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true +init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=25g active=true init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=25g active=true init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=25g active=true @@ -49,12 +49,10 @@ init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=25g active=true init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=25g active=true init set port-map unit=0 port=48 eth-macro=21 lane=0 max-speed=100g active=true init set port-map unit=0 port=49 eth-macro=20 lane=0 max-speed=100g active=true -init set port-map unit=0 port=50 eth-macro=23 lane=0 max-speed=100g active=true -init set port-map unit=0 port=51 eth-macro=22 lane=0 max-speed=100g active=true -init set port-map unit=0 port=52 eth-macro=27 lane=0 max-speed=100g active=true -init set port-map unit=0 port=53 eth-macro=26 lane=0 max-speed=100g active=true -init set port-map unit=0 port=54 eth-macro=29 lane=0 max-speed=100g active=true -init set port-map unit=0 port=55 eth-macro=28 lane=0 max-speed=100g active=true +init set port-map unit=0 port=50 eth-macro=27 lane=0 max-speed=100g active=true +init set port-map unit=0 port=51 eth-macro=26 lane=0 max-speed=100g active=true +init set port-map unit=0 port=52 eth-macro=29 lane=0 max-speed=100g active=true +init set port-map unit=0 port=53 eth-macro=28 lane=0 max-speed=100g active=true init set port-map unit=0 port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true init set port-map unit=0 port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true init start stage unit=0 task-rsrc @@ -110,12 +108,10 @@ phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=tx data=0x2 phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=tx data=0x3 phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=tx data=0x3.0.1.2 phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x3.2.0.1 +phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x3.2.1.0 +phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x3.2.1.0 phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=tx data=0x3.2.1.0 phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=54 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=55 lane-cnt=4 property=tx data=0x3.2.1.0 phy set lane-swap unit=0 portlist=129 lane-cnt=1 property=tx data=0x1 phy set lane-swap unit=0 portlist=130 lane-cnt=1 property=tx data=0x0 phy set lane-swap unit=0 portlist=0 lane-cnt=1 property=rx data=0x0 @@ -168,12 +164,10 @@ phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=rx data=0x0 phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=rx data=0x3 phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=rx data=0x3.1.0.2 phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=rx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x3.0.1.2 -phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.0.3.2 +phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x2.0.1.3 phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=rx data=0x1.0.3.2 -phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x2.0.1.3 -phy set lane-swap unit=0 portlist=54 lane-cnt=4 property=rx data=0x1.0.3.2 -phy set lane-swap unit=0 portlist=55 lane-cnt=4 property=rx data=0x1.0.3.2 +phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x1.0.3.2 phy set lane-swap unit=0 portlist=129 lane-cnt=1 property=rx data=0x1 phy set lane-swap unit=0 portlist=130 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=tx data=0x0 @@ -230,8 +224,6 @@ phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=54 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=55 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=129 lane-cnt=1 property=tx data=0x0 phy set polarity-rev unit=0 portlist=130 lane-cnt=1 property=tx data=0x0 phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=rx data=0x0 @@ -284,12 +276,10 @@ phy set polarity-rev unit=0 portlist=46 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=47 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=rx data=0x0.1.1.0 phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.1.1.1 +phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.1.1.0 phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=rx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=rx data=0x1.1.1.0 phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=54 lane-cnt=4 property=rx data=0x1.1.1.0 -phy set polarity-rev unit=0 portlist=55 lane-cnt=4 property=rx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=129 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=130 lane-cnt=1 property=rx data=0x0 phy set pre-emphasis unit=0 portlist=0 lane-cnt=1 property=c2 data=0x2 @@ -508,14 +498,6 @@ phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=cn1 data=0x0.0.0.0 phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=c2 data=0x1 phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=cn1 data=0x1 phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=c0 data=0x2 @@ -578,8 +560,6 @@ port set property unit=0 portlist=50 speed=100g port set property unit=0 portlist=51 speed=100g port set property unit=0 portlist=52 speed=100g port set property unit=0 portlist=53 speed=100g -port set property unit=0 portlist=54 speed=100g -port set property unit=0 portlist=55 speed=100g port set property unit=0 portlist=129 speed=10g port set property unit=0 portlist=130 speed=1g port set property unit=0 portlist=0 medium-type=sr @@ -636,8 +616,6 @@ port set property unit=0 portlist=50 medium-type=sr4 port set property unit=0 portlist=51 medium-type=sr4 port set property unit=0 portlist=52 medium-type=sr4 port set property unit=0 portlist=53 medium-type=sr4 -port set property unit=0 portlist=54 medium-type=sr4 -port set property unit=0 portlist=55 medium-type=sr4 port set property unit=0 portlist=129 medium-type=kr port set property unit=0 portlist=130 medium-type=x port advertise unit=0 portlist=129 speed-10g-kr @@ -696,7 +674,5 @@ port set property unit=0 portlist=50 admin=enable port set property unit=0 portlist=51 admin=enable port set property unit=0 portlist=52 admin=enable port set property unit=0 portlist=53 admin=enable -port set property unit=0 portlist=54 admin=enable -port set property unit=0 portlist=55 admin=enable -port set property unit=0 portlist=129 admin=enable -port set property unit=0 portlist=130 admin=enable +port set property unit=0 portlist=129 admin=disable +port set property unit=0 portlist=130 admin=disable diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/qos.json.j2 b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/sai.profile b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/sai.profile new file mode 100644 index 000000000000..e7b5f90ac88a --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/sai.profile @@ -0,0 +1,3 @@ +SAI_INIT_LED_CONFIG_FILE=/usr/share/sonic/hwsku/led.bin +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/proc_init.nps +SAI_DSH_CONFIG_FILE=/usr/share/sonic/hwsku/port_config.nps diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/default_sku b/device/cig/x86_64-cig_cs6436_54p-r0/default_sku new file mode 100644 index 000000000000..24afbb73b770 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/default_sku @@ -0,0 +1 @@ +Cig-CS6436-54P t1 diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/installer.conf b/device/cig/x86_64-cig_cs6436_54p-r0/installer.conf new file mode 100644 index 000000000000..ea6b4f6ebe31 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/installer.conf @@ -0,0 +1,4 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="pci=noaer" diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/plugins/eeprom.py b/device/cig/x86_64-cig_cs6436_54p-r0/plugins/eeprom.py new file mode 100755 index 000000000000..5019b9c40a9a --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/plugins/eeprom.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +try: + import exceptions + import binascii + import time + import optparse + import warnings + import os + import sys + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + import subprocess +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/bus/i2c/devices/7-0057/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/plugins/psuutil.py b/device/cig/x86_64-cig_cs6436_54p-r0/plugins/psuutil.py new file mode 100755 index 000000000000..70d50e6c3458 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/plugins/psuutil.py @@ -0,0 +1,93 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + + +import os.path +import logging + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + SYSFS_PSU_DIR = ["/sys/bus/i2c/devices/5-005a", + "/sys/bus/i2c/devices/5-005b"] + + def __init__(self): + PsuBase.__init__(self) + + + # Get sysfs attribute + def get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open %s file !", attr_path) + + retval = retval.rstrip('\r\n') + return retval + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + MAX_PSUS = 2 + return MAX_PSUS + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is\ + faulty + """ + status = 0 + attr_file = 'psu_power_good' + attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + + attr_value = self.get_attr_value(attr_path) + + if (attr_value != 'ERR'): + attr_value = int(attr_value, 16) + # Check for PSU status + if (attr_value == 1): + status = 1 + + return status + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + psu_absent = 0 + attr_file ='psu_present' + attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + + attr_value = self.get_attr_value(attr_path) + + if (attr_value != 'ERR'): + attr_value = int(attr_value, 16) + # Check for PSU presence + if (attr_value == 1): + status = 1 + + return status + diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/plugins/sfputil.py b/device/cig/x86_64-cig_cs6436_54p-r0/plugins/sfputil.py new file mode 100755 index 000000000000..2863b80c9950 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/plugins/sfputil.py @@ -0,0 +1,250 @@ +#!/usr/bin/env python + +try: + import time + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class SfpUtil(SfpUtilBase): + """Platform specific SfpUtill class""" + + _port_start = 1 + _port_end = 54 + _qsfp_port_start = 49 + _ports_in_block = 54 + + _port_to_eeprom_mapping = {} + _global_port_pres_dict = {} + + _port_to_i2c_mapping = { + 1 : 8, + 2 : 9, + 3 : 10, + 4 : 11, + 5 : 12, + 6 : 13, + 7 : 14, + 8 : 15, + 9 : 16, + 10: 17, + 11 : 18, + 12 : 19, + 13 : 20, + 14 : 21, + 15 : 22, + 16 : 23, + 17 : 24, + 18 : 25, + 19 : 26, + 20 : 27, + 21 : 28, + 22 : 29, + 23 : 30, + 24 : 31, + 25 : 32, + 26 : 33, + 27 : 34, + 28 : 35, + 29 : 36, + 30 : 37, + 31 : 38, + 32 : 39, + 33 : 40, + 34 : 41, + 35 : 42, + 36 : 43, + 37 : 44, + 38 : 45, + 39 : 46, + 40 : 47, + 41 : 48, + 42 : 49, + 43 : 50, + 44 : 51, + 45 : 52, + 46 : 53, + 47 : 54, + 48 : 55, + 49 : 56, + 50 : 57, + 51 : 60, + 52 : 61, + 53 : 62, + 54 : 63, + } + + _qsfp_ports = range(_qsfp_port_start, _ports_in_block + 1) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + + try: + reg_file = open(port_ps) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + time.sleep(1) + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + print "Error:try again to read file failed: %s %s" % (str(e), port_ps) + reg_file.close() + return False + + reg_file.close() + if reg_value == '1': + return True + + reg_file.close() + if reg_value == '1': + return True + + return False + + def init_global_port_presence(self): + for port_num in range(self.port_start, (self.port_end + 1)): + self._global_port_pres_dict[port_num] = '0' + + + def __init__(self): + eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp_eeprom' + for x in range(self._port_start, self._port_end + 1): + port_eeprom_path = eeprom_path.format(self._port_to_i2c_mapping[x]) + self._port_to_eeprom_mapping[x] = port_eeprom_path + + self.init_global_port_presence() + SfpUtilBase.__init__(self) + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_port_reset" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps, 'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + #toggle reset + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self._qsfp_port_start or port_num > self._port_end: + return False + + pre_value = self.get_presence(port_num) + if pre_value == False: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps,'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_file.seek(0) + + if lpmode == 1: + reg_file.write('1') + elif lpmode == 0: + reg_file.write('0') + reg_file.close() + + return True + + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + + if port_num < self._qsfp_port_start or port_num > self._port_end: + return False + + pre_value = self.get_presence(port_num) + if pre_value == False: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps) + except IOError as e: + print "Error: unable to open file:%s %s" % (str(e), port_ps) + return False + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + print "Error: unable to open file:%s %s" % (str(e), port_ps) + reg_file.close() + return False + + reg_file.close() + + if reg_value == '1': + return True + + return False + + def get_transceiver_change_event(self): + port_dict = {} + while True: + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + + if(presence and self._global_port_pres_dict[port_num] == '0'): + self._global_port_pres_dict[port_num] = '1' + port_dict[port_num] = '1' + elif(not presence and + self._global_port_pres_dict[port_num] == '1'): + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + + if(len(port_dict) > 0): + return True, port_dict + + time.sleep(0.5) + + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return self._qsfp_ports + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/sensors.conf b/device/cig/x86_64-cig_cs6436_54p-r0/sensors.conf new file mode 100644 index 000000000000..22cd3ccda958 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/sensors.conf @@ -0,0 +1,13 @@ +# libsensors configuration file + +chip "cs6436_54p_fan-*" + label fan1 "front fan 1" + label fan2 "front fan 2" + label fan3 "front fan 3" + label fan4 "front fan 4" + label fan5 "front fan 5" + label fan6 "rear fan 1" + label fan7 "rear fan 2" + label fan8 "rear fan 3" + label fan9 "rear fan 4" + label fan10 "rear fan 5" diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/buffers.json.j2 b/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/buffers.json.j2 old mode 100755 new mode 100644 diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/led.bin b/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/led.bin new file mode 100644 index 000000000000..8b3490ca3b7c Binary files /dev/null and b/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/led.bin differ diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/pg_profile_lookup.ini b/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/pg_profile_lookup.ini old mode 100755 new mode 100644 diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.ini b/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.ini old mode 100755 new mode 100644 index 0a25fc0a3454..f7914a5c4ab0 --- a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.ini +++ b/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.ini @@ -1,57 +1,57 @@ # name lanes alias index speed -Ethernet0 8 Ethernet1/1 0 25000 -Ethernet1 9 Ethernet2/1 1 25000 -Ethernet2 10 Ethernet3/1 2 25000 -Ethernet3 11 Ethernet4/1 3 25000 -Ethernet4 12 Ethernet5/1 4 25000 -Ethernet5 13 Ethernet6/1 5 25000 -Ethernet6 14 Ethernet7/1 6 25000 -Ethernet7 15 Ethernet8/1 7 25000 -Ethernet8 16 Ethernet9/1 8 25000 -Ethernet9 17 Ethernet10/1 9 25000 -Ethernet10 18 Ethernet11/1 10 25000 -Ethernet11 19 Ethernet12/1 11 25000 -Ethernet12 20 Ethernet13/1 12 25000 -Ethernet13 21 Ethernet14/1 13 25000 -Ethernet14 22 Ethernet15/1 14 25000 -Ethernet15 23 Ethernet16/1 15 25000 -Ethernet16 32 Ethernet17/1 16 25000 -Ethernet17 33 Ethernet18/1 17 25000 -Ethernet18 34 Ethernet19/1 18 25000 -Ethernet19 35 Ethernet20/1 19 25000 -Ethernet20 40 Ethernet21/1 20 25000 -Ethernet21 41 Ethernet22/1 21 25000 -Ethernet22 42 Ethernet23/1 22 25000 -Ethernet23 43 Ethernet24/1 23 25000 -Ethernet24 48 Ethernet25/1 24 25000 -Ethernet25 49 Ethernet26/1 25 25000 -Ethernet26 50 Ethernet27/1 26 25000 -Ethernet27 51 Ethernet28/1 27 25000 -Ethernet28 56 Ethernet29/1 28 25000 -Ethernet29 57 Ethernet30/1 29 25000 -Ethernet30 58 Ethernet31/1 30 25000 -Ethernet31 59 Ethernet32/1 31 25000 -Ethernet32 64 Ethernet33/1 32 25000 -Ethernet33 65 Ethernet34/1 33 25000 -Ethernet34 66 Ethernet35/1 34 25000 -Ethernet35 67 Ethernet36/1 35 25000 -Ethernet36 68 Ethernet37/1 36 25000 -Ethernet37 69 Ethernet38/1 37 25000 -Ethernet38 70 Ethernet39/1 38 25000 -Ethernet39 71 Ethernet40/1 39 25000 -Ethernet40 72 Ethernet41/1 40 25000 -Ethernet41 73 Ethernet42/1 41 25000 -Ethernet42 74 Ethernet43/1 42 25000 -Ethernet43 75 Ethernet44/1 43 25000 -Ethernet44 76 Ethernet45/1 44 25000 -Ethernet45 77 Ethernet46/1 45 25000 -Ethernet46 78 Ethernet47/1 46 25000 -Ethernet47 79 Ethernet48/1 47 25000 -Ethernet48 84,85,86,87 Ethernet49/1 48 100000 -Ethernet49 80,81,82,83 Ethernet50/1 49 100000 -Ethernet50 92,93,94,95 Ethernet51/1 50 100000 -Ethernet51 88,89,90,91 Ethernet52/1 51 100000 -Ethernet52 108,109,110,111 Ethernet53/1 52 100000 -Ethernet53 104,105,106,107 Ethernet54/1 53 100000 -Ethernet54 116,117,118,119 Ethernet55/1 54 100000 -Ethernet55 112,113,114,115 Ethernet56/1 55 100000 +Ethernet0 8 Ethernet1/1 1 25000 +Ethernet1 9 Ethernet2/1 2 25000 +Ethernet2 10 Ethernet3/1 3 25000 +Ethernet3 11 Ethernet4/1 4 25000 +Ethernet4 12 Ethernet5/1 5 25000 +Ethernet5 13 Ethernet6/1 6 25000 +Ethernet6 14 Ethernet7/1 7 25000 +Ethernet7 15 Ethernet8/1 8 25000 +Ethernet8 16 Ethernet9/1 9 25000 +Ethernet9 17 Ethernet10/1 10 25000 +Ethernet10 18 Ethernet11/1 11 25000 +Ethernet11 19 Ethernet12/1 12 25000 +Ethernet12 20 Ethernet13/1 13 25000 +Ethernet13 21 Ethernet14/1 14 25000 +Ethernet14 22 Ethernet15/1 15 25000 +Ethernet15 23 Ethernet16/1 16 25000 +Ethernet16 32 Ethernet17/1 17 25000 +Ethernet17 33 Ethernet18/1 18 25000 +Ethernet18 34 Ethernet19/1 19 25000 +Ethernet19 35 Ethernet20/1 20 25000 +Ethernet20 40 Ethernet21/1 21 25000 +Ethernet21 41 Ethernet22/1 22 25000 +Ethernet22 42 Ethernet23/1 23 25000 +Ethernet23 43 Ethernet24/1 24 25000 +Ethernet24 48 Ethernet25/1 25 25000 +Ethernet25 49 Ethernet26/1 26 25000 +Ethernet26 50 Ethernet27/1 27 25000 +Ethernet27 51 Ethernet28/1 28 25000 +Ethernet28 56 Ethernet29/1 29 25000 +Ethernet29 57 Ethernet30/1 30 25000 +Ethernet30 58 Ethernet31/1 31 25000 +Ethernet31 59 Ethernet32/1 32 25000 +Ethernet32 64 Ethernet33/1 33 25000 +Ethernet33 65 Ethernet34/1 34 25000 +Ethernet34 66 Ethernet35/1 35 25000 +Ethernet35 67 Ethernet36/1 36 25000 +Ethernet36 68 Ethernet37/1 37 25000 +Ethernet37 69 Ethernet38/1 38 25000 +Ethernet38 70 Ethernet39/1 39 25000 +Ethernet39 71 Ethernet40/1 40 25000 +Ethernet40 72 Ethernet41/1 41 25000 +Ethernet41 73 Ethernet42/1 42 25000 +Ethernet42 74 Ethernet43/1 43 25000 +Ethernet43 75 Ethernet44/1 44 25000 +Ethernet44 76 Ethernet45/1 45 25000 +Ethernet45 77 Ethernet46/1 46 25000 +Ethernet46 78 Ethernet47/1 47 25000 +Ethernet47 79 Ethernet48/1 48 25000 +Ethernet48 84,85,86,87 Ethernet49/1 49 100000 +Ethernet49 80,81,82,83 Ethernet50/1 50 100000 +Ethernet50 92,93,94,95 Ethernet51/1 51 100000 +Ethernet51 88,89,90,91 Ethernet52/1 52 100000 +Ethernet52 108,109,110,111 Ethernet53/1 53 100000 +Ethernet53 104,105,106,107 Ethernet54/1 54 100000 +Ethernet54 116,117,118,119 Ethernet55/1 55 100000 +Ethernet55 112,113,114,115 Ethernet56/1 56 100000 \ No newline at end of file diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps b/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps old mode 100755 new mode 100644 index 857e5f1ede5f..ec5f0273b9b5 --- a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps +++ b/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps @@ -698,5 +698,5 @@ port set property unit=0 portlist=52 admin=enable port set property unit=0 portlist=53 admin=enable port set property unit=0 portlist=54 admin=enable port set property unit=0 portlist=55 admin=enable -port set property unit=0 portlist=129 admin=enable -port set property unit=0 portlist=130 admin=enable +port set property unit=0 portlist=129 admin=disable +port set property unit=0 portlist=130 admin=disable diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/led_proc_init.nps b/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/proc_init.nps old mode 100755 new mode 100644 similarity index 90% rename from device/cig/x86_64-cig_cs6436_56p-r0/led_proc_init.nps rename to device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/proc_init.nps index 3ba2f35e5517..e55ceb0fda3f --- a/device/cig/x86_64-cig_cs6436_56p-r0/led_proc_init.nps +++ b/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/proc_init.nps @@ -1,7 +1,7 @@ #unit NPS_CFG_TYPE_XXX param0 param1 value #---- ---------------- ------ ------ ----- 0 NPS_CFG_TYPE_USE_UNIT_PORT 0 0 1 -0 NPS_CFG_TYPE_LED_CFG 0 0 7 +0 NPS_CFG_TYPE_LED_CFG 0 0 9 0 NPS_CFG_TYPE_CPI_PORT_MODE 129 0 1 0 NPS_CFG_TYPE_CPI_PORT_MODE 130 0 1 0 NPS_CFG_TYPE_USER_BUF_CTRL 0 0 1 diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/qos.json.j2 b/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/qos.json.j2 old mode 100755 new mode 100644 diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/sai.profile b/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/sai.profile old mode 100755 new mode 100644 index 880f47910ac1..e7b5f90ac88a --- a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/sai.profile +++ b/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/sai.profile @@ -1,2 +1,3 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/platform/led_proc_init.nps +SAI_INIT_LED_CONFIG_FILE=/usr/share/sonic/hwsku/led.bin +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/proc_init.nps SAI_DSH_CONFIG_FILE=/usr/share/sonic/hwsku/port_config.nps diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/default_sku b/device/cig/x86_64-cig_cs6436_56p-r0/default_sku old mode 100755 new mode 100644 diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/installer.conf b/device/cig/x86_64-cig_cs6436_56p-r0/installer.conf old mode 100755 new mode 100644 index 01b639138116..ea6b4f6ebe31 --- a/device/cig/x86_64-cig_cs6436_56p-r0/installer.conf +++ b/device/cig/x86_64-cig_cs6436_56p-r0/installer.conf @@ -1,4 +1,4 @@ -CONSOLE_PORT=0x3e8 -CONSOLE_DEV=2 +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 CONSOLE_SPEED=115200 ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="pci=noaer" diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/plugins/psuutil.py b/device/cig/x86_64-cig_cs6436_56p-r0/plugins/psuutil.py index 137531c36e16..70d50e6c3458 100755 --- a/device/cig/x86_64-cig_cs6436_56p-r0/plugins/psuutil.py +++ b/device/cig/x86_64-cig_cs6436_56p-r0/plugins/psuutil.py @@ -5,6 +5,7 @@ import os.path +import logging try: from sonic_psu.psu_base import PsuBase @@ -33,7 +34,7 @@ def get_attr_value(self, attr_path): with open(attr_path, 'r') as fd: retval = fd.read() except Exception as error: - logging.error("Unable to open ", attr_path, " file !") + logging.error("Unable to open %s file !", attr_path) retval = retval.rstrip('\r\n') return retval diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/plugins/sfputil.py b/device/cig/x86_64-cig_cs6436_56p-r0/plugins/sfputil.py index f5fe6c93142e..1e15c0e886f7 100755 --- a/device/cig/x86_64-cig_cs6436_56p-r0/plugins/sfputil.py +++ b/device/cig/x86_64-cig_cs6436_56p-r0/plugins/sfputil.py @@ -2,7 +2,7 @@ try: import time - from sonic_sfp.sfputilbase import SfpUtilBase + from sonic_sfp.sfputilbase import SfpUtilBase except ImportError, e: raise ImportError (str(e) + "- required module not found") @@ -10,80 +10,125 @@ class SfpUtil(SfpUtilBase): """Platform specific SfpUtill class""" - _port_start = 0 - _port_end = 55 - _qsfp_port_start = 48 - _ports_in_block = 55 + _port_start = 1 + _port_end = 56 + _qsfp_port_start = 49 + _ports_in_block = 56 _port_to_eeprom_mapping = {} + _global_port_pres_dict = {} + _port_to_i2c_mapping = { - 0 : 8, - 1 : 9, - 2 : 10, - 3 : 11, - 4 : 12, - 5 : 13, - 6 : 14, - 7 : 15, - 8 : 16, - 9 : 17, - 10 : 18, - 11 : 19, - 12 : 20, - 13 : 21, - 14 : 22, - 15 : 23, - 16 : 24, - 17 : 25, - 18 : 26, - 19 : 27, - 20 : 28, - 21 : 29, - 22 : 30, - 23 : 31, - 24 : 32, - 25 : 33, - 26 : 34, - 27 : 35, - 28 : 36, - 29 : 37, - 30 : 38, - 31 : 39, - 32 : 40, - 33 : 41, - 34 : 42, - 35 : 43, - 36 : 44, - 37 : 45, - 38 : 46, - 39 : 47, - 40 : 48, - 41 : 49, - 42 : 50, - 43 : 51, - 44 : 52, - 45 : 53, - 46 : 54, - 47 : 55, - 48 : 56, - 49 : 57, - 50 : 58, - 51 : 59, - 52 : 60, - 53 : 61, - 54 : 62, - 55 : 63, + 1 : 8, + 2 : 9, + 3 : 10, + 4 : 11, + 5 : 12, + 6 : 13, + 7 : 14, + 8 : 15, + 9 : 16, + 10: 17, + 11 : 18, + 12 : 19, + 13 : 20, + 14 : 21, + 15 : 22, + 16 : 23, + 17 : 24, + 18 : 25, + 19 : 26, + 20 : 27, + 21 : 28, + 22 : 29, + 23 : 30, + 24 : 31, + 25 : 32, + 26 : 33, + 27 : 34, + 28 : 35, + 29 : 36, + 30 : 37, + 31 : 38, + 32 : 39, + 33 : 40, + 34 : 41, + 35 : 42, + 36 : 43, + 37 : 44, + 38 : 45, + 39 : 46, + 40 : 47, + 41 : 48, + 42 : 49, + 43 : 50, + 44 : 51, + 45 : 52, + 46 : 53, + 47 : 54, + 48 : 55, + 49 : 56, + 50 : 57, + 51 : 58, + 52 : 59, + 53 : 60, + 54 : 61, + 55 : 62, + 56 : 63, } _qsfp_ports = range(_qsfp_port_start, _ports_in_block + 1) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + + try: + reg_file = open(port_ps) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + time.sleep(1) + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + print "Error:try again to read file failed: %s %s" % (str(e), port_ps) + reg_file.close() + return False + + reg_file.close() + if reg_value == '1': + return True + + reg_file.close() + if reg_value == '1': + return True + + return False + + def init_global_port_presence(self): + for port_num in range(self.port_start, (self.port_end + 1)): + self._global_port_pres_dict[port_num] = '0' + + def __init__(self): eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp_eeprom' for x in range(self._port_start, self._port_end + 1): port_eeprom_path = eeprom_path.format(self._port_to_i2c_mapping[x]) self._port_to_eeprom_mapping[x] = port_eeprom_path - - SfpUtilBase.__init__(self) + + self.init_global_port_presence() + SfpUtilBase.__init__(self) def reset(self, port_num): # Check for invalid port_num @@ -107,41 +152,88 @@ def reset(self, port_num): reg_file.write('0') reg_file.close() return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self._qsfp_port_start or port_num > self._port_end: + return False + + pre_value = self.get_presence(port_num) + if pre_value == False: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps,'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_file.seek(0) + + if lpmode == 1: + reg_file.write('1') + elif lpmode == 0: + reg_file.write('0') + reg_file.close() + + return True - def set_low_power_mode(self, port_nuM, lpmode): - raise NotImplementedError def get_low_power_mode(self, port_num): - raise NotImplementedError - - def get_presence(self, port_num): # Check for invalid port_num - if port_num < self._port_start or port_num > self._port_end: - return False - path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present" + if port_num < self._qsfp_port_start or port_num > self._port_end: + return False + + pre_value = self.get_presence(port_num) + if pre_value == False: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode" port_ps = path.format(self._port_to_i2c_mapping[port_num]) - try: reg_file = open(port_ps) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to open file:%s %s" % (str(e), port_ps) + return False + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + print "Error: unable to open file:%s %s" % (str(e), port_ps) + reg_file.close() return False + + reg_file.close() - reg_value = reg_file.readline().rstrip() if reg_value == '1': return True return False - + def get_transceiver_change_event(self): - """ - TODO: This function need to be implemented - when decide to support monitoring SFP(Xcvrd) - on this platform. - """ - raise NotImplementedError + port_dict = {} + while True: + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + + if(presence and self._global_port_pres_dict[port_num] == '0'): + self._global_port_pres_dict[port_num] = '1' + port_dict[port_num] = '1' + elif(not presence and + self._global_port_pres_dict[port_num] == '1'): + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + + if(len(port_dict) > 0): + return True, port_dict + + time.sleep(0.5) + @property def port_start(self): diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/sensors.conf b/device/cig/x86_64-cig_cs6436_56p-r0/sensors.conf old mode 100755 new mode 100644 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/port_config.ini b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/port_config.ini index 55c8fb3dcf64..2b24bea93107 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/port_config.ini +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/port_config.ini @@ -31,5 +31,5 @@ Ethernet112 113,114,115,116 hundredGigE1/29 29 100000 Ethernet116 117,118,119,120 hundredGigE1/30 30 100000 Ethernet120 121,122,123,124 hundredGigE1/31 31 100000 Ethernet124 125,126,127,128 hundredGigE1/32 32 100000 -Ethernet128 128 tenGigE1/33 33 10000 -Ethernet129 129 tenGigE1/34 34 10000 +Ethernet128 129 tenGigE1/33 33 10000 +Ethernet129 128 tenGigE1/34 34 10000 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai_preinit_cmd.soc @@ -0,0 +1,2 @@ +m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/td3-s5232f-32x100G.config.bcm b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/td3-s5232f-32x100G.config.bcm index e5b61b7f1b58..9b1035a942b3 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/td3-s5232f-32x100G.config.bcm +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/td3-s5232f-32x100G.config.bcm @@ -542,3 +542,5 @@ dport_map_port_66=127 dport_map_port_130=128 mmu_init_config="TD3-DEFAULT-LOSSLESS-P3P4" +sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc + diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai_preinit_cmd.soc @@ -0,0 +1,2 @@ +m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/td3-s5232f-32x100G.config.bcm b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/td3-s5232f-32x100G.config.bcm index 533e19aca1c2..e2735ded69e8 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/td3-s5232f-32x100G.config.bcm +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/td3-s5232f-32x100G.config.bcm @@ -542,3 +542,4 @@ dport_map_port_66=127 dport_map_port_130=128 mmu_init_config="TD3-DEFAULT" +sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai_preinit_cmd.soc @@ -0,0 +1,2 @@ +m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/td3-s5232f-96x10G+8x100G.config.bcm b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/td3-s5232f-96x10G+8x100G.config.bcm index 0da20afc2203..0346c47749cb 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/td3-s5232f-96x10G+8x100G.config.bcm +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/td3-s5232f-96x10G+8x100G.config.bcm @@ -615,3 +615,4 @@ dport_map_port_66=127 dport_map_port_130=128 mmu_init_config="TD3-DEFAULT" +sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai_preinit_cmd.soc @@ -0,0 +1,2 @@ +m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/td3-s5232f-96x25G+8x100G.config.bcm b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/td3-s5232f-96x25G+8x100G.config.bcm index 47cbb41f4073..ca81379ae512 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/td3-s5232f-96x25G+8x100G.config.bcm +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/td3-s5232f-96x25G+8x100G.config.bcm @@ -615,3 +615,4 @@ dport_map_port_66=127 dport_map_port_130=128 mmu_init_config="TD3-DEFAULT" +sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/installer.conf b/device/dell/x86_64-dellemc_s5232f_c3538-r0/installer.conf index 925a32fc0c3a..924e0fb81963 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/installer.conf +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/installer.conf @@ -1,3 +1,2 @@ CONSOLE_PORT=0x3f8 CONSOLE_DEV=0 -CONSOLE_SPEED=115200 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/led_proc_init.soc b/device/dell/x86_64-dellemc_s5232f_c3538-r0/led_proc_init.soc index 7105381ecdbc..098d5d4fd131 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/led_proc_init.soc +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/led_proc_init.soc @@ -2,8 +2,8 @@ # # #Led0 -#led stop -m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +led stop +#m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin #led auto on led start diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/psuutil.py b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/psuutil.py index bf10ef129626..c3e2a6d73bd0 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/psuutil.py +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/psuutil.py @@ -11,12 +11,13 @@ S5232F_MAX_PSUS = 2 -IPMI_PSU_DATA = "docker exec -it pmon ipmitool sdr list" -IPMI_PSU_DATA_DOCKER = "ipmitool sdr list" +IPMI_PSU1_DATA = "docker exec -it pmon ipmitool raw 0x04 0x2d 0x31 | awk '{print substr($0,9,1)}'" +IPMI_PSU1_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x31 | awk '{print substr($0,9,1)}'" +IPMI_PSU2_DATA = "docker exec -it pmon ipmitool raw 0x04 0x2d 0x32 | awk '{print substr($0,9,1)}'" +IPMI_PSU2_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x32 | awk '{print substr($0,9,1)}'" PSU_PRESENCE = "PSU{0}_stat" # Use this for older firmware # PSU_PRESENCE="PSU{0}_prsnt" -ipmi_sdr_list = "" try: @@ -42,30 +43,26 @@ def isDockerEnv(self): def get_pmc_register(self, reg_name): status = 1 - global ipmi_sdr_list - ipmi_dev_node = "/dev/pmi0" - ipmi_cmd = IPMI_PSU_DATA + ipmi_cmd_1 = IPMI_PSU1_DATA + ipmi_cmd_2 = IPMI_PSU1_DATA dockerenv = self.isDockerEnv() if dockerenv == True: - ipmi_cmd = IPMI_PSU_DATA_DOCKER - - status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) + if index == 1: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + else: + if index == 1: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA) + elif index == 2: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA) if status: - logging.error('Failed to execute:' + ipmi_sdr_list) - sys.exit(0) - - for item in ipmi_sdr_list.split("\n"): - if reg_name in item: - output = item.strip() - - if not output: - print('\nFailed to fetch: ' + reg_name + ' sensor ') + logging.error('Failed to execute ipmitool') sys.exit(0) - output = output.split('|')[1] + output = ipmi_sdr_list - logging.basicConfig(level=logging.DEBUG) return output def get_num_psus(self): @@ -86,8 +83,26 @@ def get_psu_status(self, index): """ # Until psu_status is implemented this is hardcoded temporarily - status = 1 - return status + psu_status = 'f' + ret_status = 1 + dockerenv = self.isDockerEnv() + if dockerenv == True: + if index == 1: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + else: + if index == 1: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA) + elif index == 2: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA) + + if ret_status: + logging.error('Failed to execute ipmitool : ') + sys.exit(0) + + psu_status = ipmi_sdr_list + return (not int(psu_status, 16) > 1) def get_psu_presence(self, index): """ @@ -96,12 +111,23 @@ def get_psu_presence(self, index): :param index: An integer, index of the PSU of which to query status :return: Boolean, True if PSU is plugged, False if not """ - status = 0 - psu_reg_name = PSU_PRESENCE.format(index) - psu_status = int(self.get_pmc_register(psu_reg_name), 16) - if (psu_status != 'ERR'): - # Check for PSU presence - if (psu_status == 0x00): - status = 1 - return status + psu_status = '0' + ret_status = 1 + dockerenv = self.isDockerEnv() + if dockerenv == True: + if index == 1: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + else: + if index == 1: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA) + elif index == 2: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA) + + if ret_status: + logging.error('Failed to execute ipmitool : ') + sys.exit(0) + psu_status = ipmi_sdr_list + return (int(psu_status, 16) & 1) diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py index 192fb80f6c56..62dc5cb9c34b 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py @@ -8,20 +8,48 @@ import sys import getopt import time + import io from sonic_sfp.sfputilbase import SfpUtilBase from os import * from mmap import * - + from sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_sfp.sff8436 import sff8436Dom + from sonic_sfp.sff8472 import sff8472Dom except ImportError as e: raise ImportError("%s - required module not found" % str(e)) +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNL_THRESHOLD_OFFSET = 176 +QSFP_CHANNL_THRESHOLD_WIDTH = 16 +QSFP_CHANNL_MON_MASK_OFFSET = 242 +QSFP_CHANNL_MON_MASK_WIDTH = 4 + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 56 + +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" PORT_START = 1 - PORT_END = 64 - PORTS_IN_BLOCK = 64 + PORT_END = 34 + PORTS_IN_BLOCK = 32 BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" @@ -112,6 +140,11 @@ def get_presence(self, port_num): # Mask off 4th bit for presence mask = (1 << 4) + # Mask off 1st bit for presence 33,34 + if (port_num > 32): + mask = (1 << 0) + + # ModPrsL is active low if reg_value & mask == 0: return True @@ -208,8 +241,11 @@ def reset(self, port_num): return True - def get_transceiver_change_event(self): + def get_transceiver_change_event(self, timeout=0): port_dict = {} + sleep_time_ms = 500 # Poll interval, in milliseconds + sleep_time = sleep_time_ms / 1000.0 + elapsed_time_ms = 0 while True: for port_num in range(self.port_start, (self.port_end + 1)): presence = self.get_presence(port_num) @@ -222,6 +258,312 @@ def get_transceiver_change_event(self): port_dict[port_num] = '0' if(len(port_dict) > 0): - return True, port_dict + break + + if len(port_dict) > 0: + break + if timeout != 0: + elapsed_time_ms += sleep_time_ms + if elapsed_time_ms > timeout: + break + time.sleep(sleep_time) + + return True, port_dict + + + def get_transceiver_dom_info_dict(self, port_num): + transceiver_dom_info_dict = {} + + dom_info_dict_keys = ['temperature', 'voltage', 'rx1power', + 'rx2power', 'rx3power', 'rx4power', + 'tx1bias', 'tx2bias', 'tx3bias', + 'tx4bias', 'tx1power', 'tx2power', + 'tx3power', 'tx4power', + ] + transceiver_dom_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + + if port_num in self.qsfp_ports: + offset = 0 + offset_xcvr = 128 + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + return transceiver_dom_info_dict + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_dom_capability_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0) + else: + return transceiver_dom_info_dict + + dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return transceiver_dom_info_dict + + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return transceiver_dom_info_dict + + qsfp_dom_rev_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + else: + return transceiver_dom_info_dict + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + dom_channel_monitor_data = {} + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return transceiver_dom_info_dict + + transceiver_dom_info_dict['tx1power'] = 'N/A' + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + else: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + else: + return None + + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] + transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] + transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] + transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + + else: + offset = 256 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path,"rb",0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom(None,1) + if sfpd_obj is None: + return transceiver_dom_info_dict + + dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET), + SFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return transceiver_dom_info_dict + + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VOLT_OFFSET), + SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return transceiver_dom_info_dict + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_MODULE_THRESHOLD_OFFSET), + SFP_MODULE_THRESHOLD_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return transceiver_dom_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value'] + transceiver_dom_info_dict['rx2power'] = 'N/A' + transceiver_dom_info_dict['rx3power'] = 'N/A' + transceiver_dom_info_dict['rx4power'] = 'N/A' + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] + transceiver_dom_info_dict['tx2bias'] = 'N/A' + transceiver_dom_info_dict['tx3bias'] = 'N/A' + transceiver_dom_info_dict['tx4bias'] = 'N/A' + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + + return transceiver_dom_info_dict + + def get_transceiver_dom_threshold_info_dict(self, port_num): + transceiver_dom_threshold_info_dict = {} + dom_info_dict_keys = ['temphighalarm', 'temphighwarning', + 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', + 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', + 'txbiaslowalarm', 'txbiaslowwarning' + ] + transceiver_dom_threshold_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + + if port_num in self.qsfp_ports: + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + # Dom Threshold data starts from offset 384 + # Revert offset back to 0 once data is retrieved + offset = 384 + dom_module_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_MODULE_THRESHOLD_OFFSET), + QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + dom_channel_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_CHANNL_THRESHOLD_OFFSET), + QSFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is not None: + dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values(dom_channel_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value'] - time.sleep(0.5) + else: + offset = 256 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path,"rb",0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom(None,1) + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, + (offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH) + + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(dom_module_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + #Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + return transceiver_dom_threshold_info_dict diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/pmon_daemon_control.json b/device/dell/x86_64-dellemc_s5232f_c3538-r0/pmon_daemon_control.json index 94592fa8cebc..44871c057e82 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/pmon_daemon_control.json +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/pmon_daemon_control.json @@ -1,3 +1,4 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json new file mode 100644 index 000000000000..775c6e22cf5c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn2010-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json new file mode 100644 index 000000000000..6a6a74301cbc --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn2100-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json new file mode 100644 index 000000000000..77da35ce5818 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn2410-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 index 8c3cac4b80b8..5529ee3d8598 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 @@ -1,8 +1,8 @@ {% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '4194304' %} -{% set ingress_lossy_pool_size = '7340032' %} -{% set egress_lossless_pool_size = '16777152' %} -{% set egress_lossy_pool_size = '7340032' %} +{% set ingress_lossless_pool_size = '5029836' %} +{% set ingress_lossy_pool_size = '5029836' %} +{% set egress_lossless_pool_size = '14024599' %} +{% set egress_lossy_pool_size = '5029836' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 index 45433b1b2641..f418e2ffa1db 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 @@ -1,8 +1,8 @@ {% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '2097152' %} -{% set ingress_lossy_pool_size = '5242880' %} -{% set egress_lossless_pool_size = '16777152' %} -{% set egress_lossy_pool_size = '5242880' %} +{% set ingress_lossless_pool_size = '2097100' %} +{% set ingress_lossy_pool_size = '2097100' %} +{% set egress_lossless_pool_size = '14024599' %} +{% set egress_lossy_pool_size = '2097100' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini index 345e6a206731..8bc48269d163 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini @@ -1,37 +1,37 @@ -# name lanes speed alias index -Ethernet0 0,1,2,3 100000 etp1 1 -Ethernet4 4,5,6,7 100000 etp2 2 -Ethernet8 8,9,10,11 100000 etp3 3 -Ethernet12 12,13,14,15 100000 etp4 4 -Ethernet16 16,17,18,19 100000 etp5 5 -Ethernet20 20,21,22,23 100000 etp6 6 -Ethernet24 24,25,26,27 100000 etp7 7 -Ethernet28 28,29,30,31 100000 etp8 8 -Ethernet32 32,33,34,35 100000 etp9 9 -Ethernet36 36,37,38,39 100000 etp10 10 -Ethernet40 40,41,42,43 100000 etp11 11 -Ethernet44 44,45,46,47 100000 etp12 12 -Ethernet48 48,49,50,51 100000 etp13 13 -Ethernet52 52,53,54,55 100000 etp14 14 -Ethernet56 56,57,58,59 100000 etp15 15 -Ethernet60 60,61,62,63 100000 etp16 16 -Ethernet64 64,65,66,67 100000 etp17 17 -Ethernet68 68,69,70,71 100000 etp18 18 -Ethernet72 72,73,74,75 100000 etp19 19 -Ethernet76 76,77,78,79 100000 etp20 20 -Ethernet80 80,81,82,83 100000 etp21 21 -Ethernet84 84,85,86,87 100000 etp22 22 -Ethernet88 88,89,90,91 100000 etp23 23 -Ethernet92 92,93,94,95 100000 etp24 24 -Ethernet96 96,97,98,99 100000 etp25 25 -Ethernet100 100,101,102,103 100000 etp26 26 -Ethernet104 104,105,106,107 100000 etp27 27 -Ethernet108 108,109,110,111 100000 etp28 28 -Ethernet112 112,113 50000 etp29a 29 -Ethernet114 114,115 50000 etp29b 29 -Ethernet116 116,117 50000 etp30a 30 -Ethernet118 118,119 50000 etp30b 30 -Ethernet120 120,121 50000 etp31a 31 -Ethernet122 122,123 50000 etp31b 31 -Ethernet124 124,125 50000 etp32a 32 -Ethernet126 126,127 50000 etp32b 32 \ No newline at end of file +# name lanes alias index speed +Ethernet0 0,1,2,3 etp1 0 100000 +Ethernet4 4,5,6,7 etp2 1 100000 +Ethernet8 8,9,10,11 etp3 2 100000 +Ethernet12 12,13,14,15 etp4 3 100000 +Ethernet16 16,17,18,19 etp5 4 100000 +Ethernet20 20,21,22,23 etp6 5 100000 +Ethernet24 24,25,26,27 etp7 6 100000 +Ethernet28 28,29,30,31 etp8 7 100000 +Ethernet32 32,33,34,35 etp9 8 100000 +Ethernet36 36,37,38,39 etp10 9 100000 +Ethernet40 40,41,42,43 etp11 10 100000 +Ethernet44 44,45,46,47 etp12 11 100000 +Ethernet48 48,49,50,51 etp13 12 100000 +Ethernet52 52,53,54,55 etp14 13 100000 +Ethernet56 56,57,58,59 etp15 14 100000 +Ethernet60 60,61,62,63 etp16 15 100000 +Ethernet64 64,65,66,67 etp17 16 100000 +Ethernet68 68,69,70,71 etp18 17 100000 +Ethernet72 72,73,74,75 etp19 18 100000 +Ethernet76 76,77,78,79 etp20 19 100000 +Ethernet80 80,81,82,83 etp21 20 100000 +Ethernet84 84,85,86,87 etp22 21 100000 +Ethernet88 88,89,90,91 etp23 22 100000 +Ethernet92 92,93,94,95 etp24 23 100000 +Ethernet96 96,97,98,99 etp25 24 100000 +Ethernet100 100,101,102,103 etp26 25 100000 +Ethernet104 104,105,106,107 etp27 26 100000 +Ethernet108 108,109,110,111 etp28 27 100000 +Ethernet112 112,113 etp29a 28 50000 +Ethernet114 114,115 etp29b 28 50000 +Ethernet116 116,117 etp30a 29 50000 +Ethernet118 118,119 etp30b 29 50000 +Ethernet120 120,121 etp31a 30 50000 +Ethernet122 122,123 etp31b 30 50000 +Ethernet124 124,125 etp32a 31 50000 +Ethernet126 126,127 etp32b 31 50000 diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini index 9e01da79f449..f9f465f1a3ea 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini @@ -1,57 +1,57 @@ -# name lanes speed alias index -Ethernet0 0,1 50000 etp1a 1 -Ethernet2 2,3 50000 etp1b 1 -Ethernet4 4,5 50000 etp2a 2 -Ethernet6 6,7 50000 etp2b 2 -Ethernet8 8,9 50000 etp3a 3 -Ethernet10 10,11 50000 etp3b 3 -Ethernet12 12,13 50000 etp4a 4 -Ethernet14 14,15 50000 etp4b 4 -Ethernet16 16,17 50000 etp5a 5 -Ethernet18 18,19 50000 etp5b 5 -Ethernet20 20,21 50000 etp6a 6 -Ethernet22 22,23 50000 etp6b 6 -Ethernet24 24,25,26,27 100000 etp7 7 -Ethernet28 28,29,30,31 100000 etp8 8 -Ethernet32 32,33,34,35 100000 etp9 9 -Ethernet36 36,37,38,39 100000 etp10 10 -Ethernet40 40,41 50000 etp11a 11 -Ethernet42 42,43 50000 etp11b 11 -Ethernet44 44,45 50000 etp12a 12 -Ethernet46 46,47 50000 etp12b 12 -Ethernet48 48,49 50000 etp13a 13 -Ethernet50 50,51 50000 etp13b 13 -Ethernet52 52,53 50000 etp14a 14 -Ethernet54 54,55 50000 etp14b 14 -Ethernet56 56,57 50000 etp15a 15 -Ethernet58 58,59 50000 etp15b 15 -Ethernet60 60,61 50000 etp16a 16 -Ethernet62 62,63 50000 etp16b 16 -Ethernet64 64,65 50000 etp17a 17 -Ethernet66 66,67 50000 etp17b 17 -Ethernet68 68,69 50000 etp18a 18 -Ethernet70 70,71 50000 etp18b 18 -Ethernet72 72,73 50000 etp19a 19 -Ethernet74 74,75 50000 etp19b 19 -Ethernet76 76,77 50000 etp20a 20 -Ethernet78 78,79 50000 etp20b 20 -Ethernet80 80,81 50000 etp21a 21 -Ethernet82 82,83 50000 etp21b 21 -Ethernet84 84,85 50000 etp22a 22 -Ethernet86 86,87 50000 etp22b 22 -Ethernet88 88,89,90,91 100000 etp23 23 -Ethernet92 92,93,94,95 100000 etp24 24 -Ethernet96 96,97,98,99 100000 etp25 25 -Ethernet100 100,101,102,103 100000 etp26 26 -Ethernet104 104,105 50000 etp27a 27 -Ethernet106 106,107 50000 etp27b 27 -Ethernet108 108,109 50000 etp28a 28 -Ethernet110 110,111 50000 etp28b 28 -Ethernet112 112,113 50000 etp29a 29 -Ethernet114 114,115 50000 etp29b 29 -Ethernet116 116,117 50000 etp30a 30 -Ethernet118 118,119 50000 etp30b 30 -Ethernet120 120,121 50000 etp31a 31 -Ethernet122 122,123 50000 etp31b 31 -Ethernet124 124,125 50000 etp32a 32 -Ethernet126 126,127 50000 etp32b 32 +# name lanes alias index speed +Ethernet0 0,1 etp1a 0 50000 +Ethernet2 2,3 etp1b 0 50000 +Ethernet4 4,5 etp2a 1 50000 +Ethernet6 6,7 etp2b 1 50000 +Ethernet8 8,9 etp3a 2 50000 +Ethernet10 10,11 etp3b 2 50000 +Ethernet12 12,13 etp4a 3 50000 +Ethernet14 14,15 etp4b 3 50000 +Ethernet16 16,17 etp5a 4 50000 +Ethernet18 18,19 etp5b 4 50000 +Ethernet20 20,21 etp6a 5 50000 +Ethernet22 22,23 etp6b 5 50000 +Ethernet24 24,25,26,27 etp7 6 100000 +Ethernet28 28,29,30,31 etp8 7 100000 +Ethernet32 32,33,34,35 etp9 8 100000 +Ethernet36 36,37,38,39 etp10 9 100000 +Ethernet40 40,41 etp11a 10 50000 +Ethernet42 42,43 etp11b 10 50000 +Ethernet44 44,45 etp12a 11 50000 +Ethernet46 46,47 etp12b 11 50000 +Ethernet48 48,49 etp13a 12 50000 +Ethernet50 50,51 etp13b 12 50000 +Ethernet52 52,53 etp14a 13 50000 +Ethernet54 54,55 etp14b 13 50000 +Ethernet56 56,57 etp15a 14 50000 +Ethernet58 58,59 etp15b 14 50000 +Ethernet60 60,61 etp16a 15 50000 +Ethernet62 62,63 etp16b 15 50000 +Ethernet64 64,65 etp17a 16 50000 +Ethernet66 66,67 etp17b 16 50000 +Ethernet68 68,69 etp18a 17 50000 +Ethernet70 70,71 etp18b 17 50000 +Ethernet72 72,73 etp19a 18 50000 +Ethernet74 74,75 etp19b 18 50000 +Ethernet76 76,77 etp20a 19 50000 +Ethernet78 78,79 etp20b 19 50000 +Ethernet80 80,81 etp21a 20 50000 +Ethernet82 82,83 etp21b 20 50000 +Ethernet84 84,85 etp22a 21 50000 +Ethernet86 86,87 etp22b 21 50000 +Ethernet88 88,89,90,91 etp23 22 100000 +Ethernet92 92,93,94,95 etp24 23 100000 +Ethernet96 96,97,98,99 etp25 24 100000 +Ethernet100 100,101,102,103 etp26 25 100000 +Ethernet104 104,105 etp27a 26 50000 +Ethernet106 106,107 etp27b 26 50000 +Ethernet108 108,109 etp28a 27 50000 +Ethernet110 110,111 etp28b 27 50000 +Ethernet112 112,113 etp29a 28 50000 +Ethernet114 114,115 etp29b 28 50000 +Ethernet116 116,117 etp30a 29 50000 +Ethernet118 118,119 etp30b 29 50000 +Ethernet120 120,121 etp31a 30 50000 +Ethernet122 122,123 etp31b 30 50000 +Ethernet124 124,125 etp32a 31 50000 +Ethernet126 126,127 etp32b 31 50000 diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json new file mode 100644 index 000000000000..2a6069414786 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn2700-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/eeprom.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/eeprom.py index 63303c13a244..c9ae1a335421 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/eeprom.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/eeprom.py @@ -21,6 +21,7 @@ from cStringIO import StringIO from sonic_eeprom import eeprom_base from sonic_eeprom import eeprom_tlvinfo + from sonic_device_util import get_machine_info import subprocess except ImportError, e: raise ImportError (str(e) + "- required module not found") @@ -34,6 +35,14 @@ def log_error(msg): syslog.syslog(syslog.LOG_ERR, msg) syslog.closelog() + +machine_info = get_machine_info() +onie_platform = machine_info['onie_platform'] +if 'simx' in onie_platform: + platform_path = os.path.join('/usr/share/sonic/device', onie_platform) + subprocess.check_call(['/usr/bin/xxd', '-r', '-p', 'syseeprom.hex', 'syseeprom.bin'], cwd=platform_path) + CACHE_FILE = os.path.join(platform_path, 'syseeprom.bin') + class board(eeprom_tlvinfo.TlvInfoDecoder): _TLV_INFO_MAX_LEN = 256 @@ -45,12 +54,12 @@ def __init__(self, name, path, cpld_root, ro): time.sleep(1) else: break - + if not (os.path.exists(EEPROM_SYMLINK) or os.path.isfile(CACHE_FILE)): log_error("Nowhere to read syseeprom from! No symlink or cache file found") raise RuntimeError("No syseeprom symlink or cache file found") - self.eeprom_path = EEPROM_SYMLINK + self.eeprom_path = EEPROM_SYMLINK if 'simx' not in onie_platform else CACHE_FILE super(board, self).__init__(self.eeprom_path, 0, '', True) def decode_eeprom(self, e): @@ -60,3 +69,4 @@ def decode_eeprom(self, e): decode_output = sys.stdout.getvalue() sys.stdout = original_stdout print(decode_output.replace('\0', '')) + diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py index c11675766d3f..f9b35b8e74e7 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py @@ -18,14 +18,19 @@ PMAOS_ENABLE = 1 PMAOS_DISABLE = 2 +PORT_TYPE_CPU = 4 PORT_TYPE_NVE = 8 PORT_TYPE_OFFSET = 28 PORT_TYPE_MASK = 0xF0000000 NVE_MASK = PORT_TYPE_MASK & (PORT_TYPE_NVE << PORT_TYPE_OFFSET) +CPU_MASK = PORT_TYPE_MASK & (PORT_TYPE_CPU << PORT_TYPE_OFFSET) def is_nve(port): return (port & NVE_MASK) != 0 +def is_cpu(port): + return (port & CPU_MASK) != 0 + def is_port_admin_status_up(log_port): oper_state_p = new_sx_port_oper_state_t_p() admin_state_p = new_sx_port_admin_state_t_p() @@ -57,6 +62,7 @@ def get_log_ports(handle, sfp_module): for i in range(0, port_cnt): port_attributes = sx_port_attributes_t_arr_getitem(port_attributes_list, i) if is_nve(int(port_attributes.log_port)) == False \ + and is_cpu(int(port_attributes.log_port)) == False \ and port_attributes.port_mapping.module_port == sfp_module \ and is_port_admin_status_up(port_attributes.log_port): log_port_list.append(port_attributes.log_port) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index e41ac2924da2..b5f2a335b09c 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -22,8 +22,6 @@ SFP_I2C_PAGE_SIZE = 256 # parameters for DB connection -REDIS_HOSTNAME = "localhost" -REDIS_PORT = 6379 REDIS_TIMEOUT_USECS = 0 # parameters for SFP presence @@ -43,7 +41,7 @@ # magic code defnition for port number, qsfp port position of each hwsku # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict = {'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, "LS-SN2700":0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4} +hwsku_dict = {'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700': 0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0} port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1)] def log_info(msg, also_print_to_console=False): @@ -190,10 +188,9 @@ def get_transceiver_change_event(self, timeout=0): if self.db_sel == None: from swsscommon import swsscommon - self.state_db = swsscommon.DBConnector(swsscommon.STATE_DB, - REDIS_HOSTNAME, - REDIS_PORT, - REDIS_TIMEOUT_USECS) + self.state_db = swsscommon.DBConnector("STATE_DB", + REDIS_TIMEOUT_USECS, + True) # Subscribe to state table for SFP change notifications self.db_sel = swsscommon.Select() diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json new file mode 100644 index 000000000000..7964d9cb8713 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn2740-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 index d40bc03fbb59..e26ad28b9f0e 100644 --- a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 @@ -1,8 +1,8 @@ {% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '8224768' %} -{% set ingress_lossy_pool_size = '8224768' %} -{% set egress_lossless_pool_size = '35966016' %} -{% set egress_lossy_pool_size = '8224768' %} +{% set ingress_lossless_pool_size = '14983147' %} +{% set ingress_lossy_pool_size = '14983147' %} +{% set egress_lossless_pool_size = '34340822' %} +{% set egress_lossy_pool_size = '14983147' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 index fe8c27b9d364..b5e4ff8d1747 100644 --- a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 @@ -1,8 +1,8 @@ {% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '12042240' %} -{% set ingress_lossy_pool_size = '12042240' %} -{% set egress_lossless_pool_size = '35966016' %} -{% set egress_lossy_pool_size = '12042240' %} +{% set ingress_lossless_pool_size = '9158635' %} +{% set ingress_lossy_pool_size = '9158635' %} +{% set egress_lossless_pool_size = '34340822' %} +{% set egress_lossy_pool_size = '9158635' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/sai_3700.xml b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/sai_3700.xml index 8f6c427888b1..a7ac42950668 100644 --- a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/sai_3700.xml +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/sai_3700.xml @@ -5,6 +5,9 @@ 00:02:03:04:05:00 + + 1 + 32 diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json new file mode 100644 index 000000000000..7c0b7598aff7 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn3700-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json new file mode 100644 index 000000000000..c55b9feab7cb --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn3700c-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t0.j2 deleted file mode 120000 index 85f0b6b6b354..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t0.j2 +++ /dev/null @@ -1 +0,0 @@ -../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..d69a0cc13835 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t0.j2 @@ -0,0 +1,104 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '28196784' %} +{% set ingress_lossy_pool_size = '28196784' %} +{% set egress_lossless_pool_size = '34340832' %} +{% set egress_lossy_pool_size = '28196784' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"0" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t1.j2 deleted file mode 120000 index 3bb496a5103b..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t1.j2 +++ /dev/null @@ -1 +0,0 @@ -../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..78d43455a424 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t1.j2 @@ -0,0 +1,104 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '17891280' %} +{% set ingress_lossy_pool_size = '17891280' %} +{% set egress_lossless_pool_size = '34340832' %} +{% set egress_lossy_pool_size = '17891280' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"0" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/pg_profile_lookup.ini deleted file mode 120000 index 252ae8d4149b..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/pg_profile_lookup.ini +++ /dev/null @@ -1 +0,0 @@ -../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/pg_profile_lookup.ini new file mode 100644 index 000000000000..7c28e4c0d500 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/pg_profile_lookup.ini @@ -0,0 +1,23 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 1000 5m 32768 18432 14336 0 + 10000 5m 34816 18432 16384 0 + 25000 5m 38912 18432 20480 0 + 40000 5m 41984 18432 23552 0 + 50000 5m 44032 18432 25600 0 + 100000 5m 55296 18432 36864 0 + 200000 5m 77824 18432 59392 0 + 1000 40m 33792 18432 15360 0 + 10000 40m 36864 18432 18432 0 + 25000 40m 43008 18432 24576 0 + 40000 40m 49152 18432 30720 0 + 50000 40m 53248 18432 34816 0 + 100000 40m 72704 18432 54272 0 + 200000 40m 112640 18432 94208 0 + 1000 300m 34816 18432 16384 0 + 10000 300m 50176 18432 31744 0 + 25000 300m 75776 18432 57344 0 + 40000 300m 101376 18432 82944 0 + 50000 300m 117760 18432 99328 0 + 100000 300m 202752 18432 184320 0 + 200000 300m 373760 18432 355328 0 diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/sai_3800.xml b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/sai_3800.xml index 2d4c0f93d100..1b3c77ce381c 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/sai_3800.xml +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/sai_3800.xml @@ -5,6 +5,9 @@ 00:02:03:04:05:00 + + 1 + 64 diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers.json.j2 new file mode 120000 index 000000000000..add8bf8bb7c2 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 new file mode 120000 index 000000000000..0987f6724863 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 @@ -0,0 +1 @@ +../ACS-MSN3800/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 new file mode 120000 index 000000000000..119460bfa556 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 @@ -0,0 +1 @@ +../ACS-MSN3800/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/pg_profile_lookup.ini new file mode 120000 index 000000000000..db2f74508aad --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/pg_profile_lookup.ini @@ -0,0 +1 @@ +../ACS-MSN3800/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/port_config.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/port_config.ini new file mode 100644 index 000000000000..9559119c7e38 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/port_config.ini @@ -0,0 +1,105 @@ +# name lanes alias index speed fec +Ethernet0 0,1 etp1a 0 50000 none +Ethernet2 2,3 etp1b 0 50000 none +Ethernet4 4,5 etp2a 1 50000 none +Ethernet6 6,7 etp2b 1 50000 none +Ethernet8 8,9 etp3a 2 50000 none +Ethernet10 10,11 etp3b 2 50000 none +Ethernet12 12,13,14,15 etp4 3 50000 none +Ethernet16 16,17 etp5a 4 50000 none +Ethernet18 18,19 etp5b 4 50000 none +Ethernet20 20,21 etp6a 5 50000 none +Ethernet22 22,23 etp6b 5 50000 none +Ethernet24 24,25 etp7a 6 50000 none +Ethernet26 26,27 etp7b 6 50000 none +Ethernet28 28,29,30,31 etp8 7 50000 none +Ethernet32 32,33 etp9a 8 50000 none +Ethernet34 34,35 etp9b 8 50000 none +Ethernet36 36,37 etp10a 9 50000 none +Ethernet38 38,39 etp10b 9 50000 none +Ethernet40 40,41 etp11a 10 50000 none +Ethernet42 42,43 etp11b 10 50000 none +Ethernet44 44,45,46,47 etp12 11 50000 none +Ethernet48 48,49 etp13a 12 50000 none +Ethernet50 50,51 etp13b 12 50000 none +Ethernet52 52,53 etp14a 13 50000 none +Ethernet54 54,55 etp14b 13 50000 none +Ethernet56 56,57 etp15a 14 50000 none +Ethernet58 58,59 etp15b 14 50000 none +Ethernet60 60,61,62,63 etp16 15 50000 none +Ethernet64 64,65 etp17a 16 50000 none +Ethernet66 66,67 etp17b 16 50000 none +Ethernet68 68,69 etp18a 17 50000 none +Ethernet70 70,71 etp18b 17 50000 none +Ethernet72 72,73 etp19a 18 50000 none +Ethernet74 74,75 etp19b 18 50000 none +Ethernet76 76,77,78,79 etp20 19 50000 none +Ethernet80 80,81 etp21a 20 50000 none +Ethernet82 82,83 etp21b 20 50000 none +Ethernet84 84,85 etp22a 21 50000 none +Ethernet86 86,87 etp22b 21 50000 none +Ethernet88 88,89 etp23a 22 50000 none +Ethernet90 90,91 etp23b 22 50000 none +Ethernet92 92,93,94,95 etp24 23 50000 none +Ethernet96 96,97,98,99 etp25 24 100000 rs +Ethernet100 100,101,102,103 etp26 25 100000 rs +Ethernet104 104,105 etp27a 26 50000 none +Ethernet106 106,107 etp27b 26 50000 none +Ethernet108 108,109,110,111 etp28 27 50000 none +Ethernet112 112,113,114,115 etp29 28 100000 rs +Ethernet116 116,117,118,119 etp30 29 100000 rs +Ethernet120 120,121 etp31a 30 50000 none +Ethernet122 122,123 etp31b 30 50000 none +Ethernet124 124,125,126,127 etp32 31 50000 none +Ethernet128 128,129,130,131 etp33 32 100000 rs +Ethernet132 132,133,134,135 etp34 33 100000 rs +Ethernet136 136,137 etp35a 34 50000 none +Ethernet138 138,139 etp35b 34 50000 none +Ethernet140 140,141,142,143 etp36 35 50000 none +Ethernet144 144,145,146,147 etp37 36 100000 rs +Ethernet148 148,149,150,151 etp38 37 100000 rs +Ethernet152 152,153 etp39a 38 50000 none +Ethernet154 154,155 etp39b 38 50000 none +Ethernet156 156,157,158,159 etp40 39 50000 none +Ethernet160 160,161 etp41a 40 50000 none +Ethernet162 162,163 etp41b 40 50000 none +Ethernet164 164,165 etp42a 41 50000 none +Ethernet166 166,167 etp42b 41 50000 none +Ethernet168 168,169 etp43a 42 50000 none +Ethernet170 170,171 etp43b 42 50000 none +Ethernet172 172,173,174,175 etp44 43 50000 none +Ethernet176 176,177 etp45a 44 50000 none +Ethernet178 178,179 etp45b 44 50000 none +Ethernet180 180,181 etp46a 45 50000 none +Ethernet182 182,183 etp46b 45 50000 none +Ethernet184 184,185 etp47a 46 50000 none +Ethernet186 186,187 etp47b 46 50000 none +Ethernet188 188,189,190,191 etp48 47 50000 none +Ethernet192 192,193 etp49a 48 50000 none +Ethernet194 194,195 etp49b 48 50000 none +Ethernet196 196,197 etp50a 49 50000 none +Ethernet198 198,199 etp50b 49 50000 none +Ethernet200 200,201 etp51a 50 50000 none +Ethernet202 202,203 etp51b 50 50000 none +Ethernet204 204,205,206,207 etp52 51 50000 none +Ethernet208 208,209 etp53a 52 50000 none +Ethernet210 210,211 etp53b 52 50000 none +Ethernet212 212,213 etp54a 53 50000 none +Ethernet214 214,215 etp54b 53 50000 none +Ethernet216 216,217 etp55a 54 50000 none +Ethernet218 218,219 etp55b 54 50000 none +Ethernet220 220,221,222,223 etp56 55 50000 none +Ethernet224 224,225 etp57a 56 50000 none +Ethernet226 226,227 etp57b 56 50000 none +Ethernet228 228,229 etp58a 57 50000 none +Ethernet230 230,231 etp58b 57 50000 none +Ethernet232 232,233 etp59a 58 50000 none +Ethernet234 234,235 etp59b 58 50000 none +Ethernet236 236,237,238,239 etp60 59 50000 none +Ethernet240 240,241 etp61a 60 50000 none +Ethernet242 242,243 etp61b 60 50000 none +Ethernet244 244,245 etp62a 61 50000 none +Ethernet246 246,247 etp62b 61 50000 none +Ethernet248 248,249 etp63a 62 50000 none +Ethernet250 250,251 etp63b 62 50000 none +Ethernet252 252,253,254,255 etp64 63 50000 none diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/qos.json.j2 new file mode 120000 index 000000000000..eccf286dc879 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/qos.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai.profile b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai.profile new file mode 100644 index 000000000000..c5bb0c90f3d7 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_3800_112x50g_8x100g.xml diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml new file mode 100644 index 000000000000..102842d72275 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml @@ -0,0 +1,507 @@ + + + + + + 00:02:03:04:05:00 + + + 64 + + + + + 1 + 4 + 48 + + + 3 + 2 + + + 384 + + + 3 + 4 + 49 + 3 + 2 + 384 + + + 5 + 4 + 50 + 3 + 2 + 384 + + + 7 + 4 + 51 + 3 + 384 + + + 9 + 4 + 52 + 3 + 2 + 384 + + + 11 + 4 + 53 + 3 + 2 + 384 + + + 13 + 4 + 54 + 3 + 2 + 384 + + + 15 + 4 + 55 + 3 + 384 + + + 17 + 4 + 56 + 3 + 2 + 384 + + + 19 + 4 + 57 + 3 + 2 + 384 + + + 21 + 4 + 58 + 3 + 2 + 384 + + + 23 + 4 + 59 + 3 + 384 + + + 25 + 4 + 60 + 3 + 2 + 384 + + + 27 + 4 + 61 + 3 + 2 + 384 + + + 29 + 4 + 62 + 3 + 2 + 384 + + + 31 + 4 + 63 + 3 + 384 + + + 33 + 4 + 12 + 3 + 2 + 384 + + + 35 + 4 + 13 + 3 + 2 + 384 + + + 37 + 4 + 14 + 3 + 2 + 384 + + + 39 + 4 + 15 + 3 + 384 + + + 41 + 4 + 8 + 3 + 2 + 384 + + + 43 + 4 + 9 + 3 + 2 + 384 + + + 45 + 4 + 10 + 3 + 2 + 384 + + + 47 + 4 + 11 + 3 + 384 + + + 49 + 4 + 4 + 3 + 2 + 384 + + + 51 + 4 + 5 + 3 + 2 + 384 + + + 53 + 4 + 6 + 3 + 2 + 384 + + + 55 + 4 + 7 + 3 + 384 + + + 57 + 4 + 0 + 3 + 2 + 384 + + + 59 + 4 + 1 + 3 + 2 + 384 + + + 61 + 4 + 2 + 3 + 2 + 384 + + + 63 + 4 + 3 + 3 + 384 + + + 65 + 4 + 44 + 3 + 2 + 384 + + + 67 + 4 + 45 + 3 + 2 + 384 + + + 69 + 4 + 46 + 3 + 2 + 384 + + + 71 + 4 + 47 + 3 + 384 + + + 73 + 4 + 40 + 3 + 2 + 384 + + + 75 + 4 + 41 + 3 + 2 + 384 + + + 77 + 4 + 42 + 3 + 2 + 384 + + + 79 + 4 + 43 + 3 + 384 + + + 81 + 4 + 36 + 3 + 1536 + + + 83 + 4 + 37 + 3 + 1536 + + + 85 + 4 + 38 + 3 + 2 + 384 + + + 87 + 4 + 39 + 3 + 384 + + + 89 + 4 + 32 + 3 + 1536 + + + 91 + 4 + 33 + 3 + 1536 + + + 93 + 4 + 34 + 3 + 2 + 384 + + + 95 + 4 + 35 + 3 + 384 + + + 97 + 4 + 16 + 3 + 2 + 384 + + + 99 + 4 + 17 + 3 + 2 + 384 + + + 101 + 4 + 18 + 3 + 2 + 384 + + + 103 + 4 + 19 + 3 + 384 + + + 105 + 4 + 20 + 3 + 2 + 384 + + + 107 + 4 + 21 + 3 + 2 + 384 + + + 109 + 4 + 22 + 3 + 2 + 384 + + + 111 + 4 + 23 + 3 + 384 + + + 113 + 4 + 24 + 3 + 1536 + + + 115 + 4 + 25 + 3 + 1536 + + + 117 + 4 + 26 + 3 + 2 + 384 + + + 119 + 4 + 27 + 3 + 384 + + + 121 + 4 + 28 + 3 + 1536 + + + 123 + 4 + 29 + 3 + 1536 + + + 125 + 4 + 30 + 3 + 2 + 384 + + + 127 + 4 + 31 + 3 + 384 + + + + diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json new file mode 100644 index 000000000000..fa3b172b763e --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn3800-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers.json.j2 new file mode 120000 index 000000000000..add8bf8bb7c2 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..b71e6b35fa2e --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t0.j2 @@ -0,0 +1,106 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '56623104' %} +{% set ingress_lossy_pool_size = '56623104' %} +{% set egress_lossless_pool_size = '60817392' %} +{% set egress_lossy_pool_size = '56623104' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"0" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + + diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..87e55d5a46e0 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t1.j2 @@ -0,0 +1,106 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '36011952' %} +{% set ingress_lossy_pool_size = '36011952' %} +{% set egress_lossless_pool_size = '60817392' %} +{% set egress_lossy_pool_size = '36011952' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"0" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + + diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/pg_profile_lookup.ini new file mode 100644 index 000000000000..950cf9434967 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/pg_profile_lookup.ini @@ -0,0 +1,25 @@ +# speed cable size xon xoff threshold +1000 5m 32768 18432 14336 0 +10000 5m 32768 18432 14336 0 +25000 5m 33792 18432 15360 0 +40000 5m 33792 18432 15360 0 +50000 5m 33792 18432 15360 0 +100000 5m 35840 18432 17408 0 +200000 5m 37888 18432 19456 0 +400000 5m 43008 18432 24576 0 +1000 40m 32768 18432 14336 0 +10000 40m 34816 18432 16384 0 +25000 40m 37888 18432 19456 0 +40000 40m 40960 18432 22528 0 +50000 40m 43008 18432 24576 0 +100000 40m 53248 18432 34816 0 +200000 40m 72704 18432 54272 0 +400000 40m 112640 18432 94208 0 +1000 300m 34816 18432 16384 0 +10000 300m 48128 18432 29696 0 +25000 300m 70656 18432 52224 0 +40000 300m 93184 18432 74752 0 +50000 300m 108544 18432 90112 0 +100000 300m 183296 18432 164864 0 +200000 300m 333824 18432 315392 0 +400000 300m 634880 18432 616448 0 diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini new file mode 100644 index 000000000000..1e1906ff0ef5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias +Ethernet0 0,1,2,3 etp1 +Ethernet4 4,5,6,7 etp2 +Ethernet8 8,9,10,11 etp3 +Ethernet12 12,13,14,15 etp4 +Ethernet16 16,17,18,19 etp5 +Ethernet20 20,21,22,23 etp6 +Ethernet24 24,25,26,27 etp7 +Ethernet28 28,29,30,31 etp8 +Ethernet32 32,33,34,35 etp9 +Ethernet36 36,37,38,39 etp10 +Ethernet40 40,41,42,43 etp11 +Ethernet44 44,45,46,47 etp12 +Ethernet48 48,49,50,51 etp13 +Ethernet52 52,53,54,55 etp14 +Ethernet56 56,57,58,59 etp15 +Ethernet60 60,61,62,63 etp16 +Ethernet64 64,65,66,67 etp17 +Ethernet68 68,69,70,71 etp18 +Ethernet72 72,73,74,75 etp19 +Ethernet76 76,77,78,79 etp20 +Ethernet80 80,81,82,83 etp21 +Ethernet84 84,85,86,87 etp22 +Ethernet88 88,89,90,91 etp23 +Ethernet92 92,93,94,95 etp24 +Ethernet96 96,97,98,99 etp25 +Ethernet100 100,101,102,103 etp26 +Ethernet104 104,105,106,107 etp27 +Ethernet108 108,109,110,111 etp28 +Ethernet112 112,113,114,115 etp29 +Ethernet116 116,117,118,119 etp30 +Ethernet120 120,121,122,123 etp31 +Ethernet124 124,125,126,127 etp32 diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/qos.json.j2 new file mode 120000 index 000000000000..eccf286dc879 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/qos.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai.profile b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai.profile new file mode 100644 index 000000000000..31b3fd09ddd9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_4700_100G.xml diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700_100G.xml b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700_100G.xml new file mode 100644 index 000000000000..a76e23d5d119 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700_100G.xml @@ -0,0 +1,244 @@ + + + + + + 00:02:03:04:05:00 + + + 32 + + + + + 1 + 4 + 17 + 3 + 1536 + + + 5 + 4 + 16 + 3 + 1536 + + + 9 + 4 + 19 + 3 + 1536 + + + 13 + 4 + 18 + 3 + 1536 + + + 17 + 4 + 21 + 3 + 1536 + + + 21 + 4 + 20 + 3 + 1536 + + + 25 + 4 + 23 + 3 + 1536 + + + 29 + 4 + 22 + 3 + 1536 + + + 33 + 4 + 29 + 3 + 1536 + + + 37 + 4 + 28 + 3 + 1536 + + + 41 + 4 + 31 + 3 + 1536 + + + 45 + 4 + 30 + 3 + 1536 + + + 49 + 4 + 25 + 3 + 1536 + + + 53 + 4 + 24 + 3 + 1536 + + + 57 + 4 + 27 + 3 + 1536 + + + 61 + 4 + 26 + 3 + 1536 + + + 65 + 4 + 14 + 3 + 1536 + + + 69 + 4 + 15 + 3 + 1536 + + + 73 + 4 + 12 + 3 + 1536 + + + 77 + 4 + 13 + 3 + 1536 + + + 81 + 4 + 10 + 3 + 1536 + + + 85 + 4 + 11 + 3 + 1536 + + + 89 + 4 + 8 + 3 + 1536 + + + 93 + 4 + 9 + 3 + 1536 + + + 97 + 4 + 2 + 3 + 1536 + + + 101 + 4 + 3 + 3 + 1536 + + + 105 + 4 + 0 + + + 3 + + + 1536 + + + 109 + 4 + 1 + 3 + 1536 + + + 113 + 4 + 6 + 3 + 1536 + + + 117 + 4 + 7 + 3 + 1536 + + + 121 + 4 + 4 + 3 + 1536 + + + 125 + 4 + 5 + 3 + 1536 + + + + + diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/default_sku b/device/mellanox/x86_64-mlnx_msn4700-r0/default_sku new file mode 100644 index 000000000000..80e541477f79 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/default_sku @@ -0,0 +1 @@ +ACS-MSN4700 t1 diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_components.json new file mode 100644 index 000000000000..2804e29e11b1 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn4700-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/platform_reboot b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_reboot new file mode 120000 index 000000000000..43c8ea567493 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_reboot @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/platform_reboot \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/platform_wait b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_wait new file mode 120000 index 000000000000..4b30bd429854 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_wait @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/platform_wait \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/eeprom.py b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/eeprom.py new file mode 120000 index 000000000000..b4e2a6a61671 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/eeprom.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/eeprom.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/psuutil.py new file mode 120000 index 000000000000..9f724238a8d5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/psuutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/psuutil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmget.py b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmget.py new file mode 120000 index 000000000000..2e84f435abd9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmget.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfplpmget.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmset.py b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmset.py new file mode 120000 index 000000000000..6a88bac30467 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmset.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfpreset.py b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfpreset.py new file mode 120000 index 000000000000..fef2063e3496 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfpreset.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfpreset.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfputil.py new file mode 120000 index 000000000000..45909b880fc9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfputil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfputil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn4700-r0/pmon_daemon_control.json new file mode 120000 index 000000000000..435a2ce7c0ba --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/pmon_daemon_control.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf new file mode 100644 index 000000000000..b4eaf76f2ec0 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf @@ -0,0 +1,162 @@ +################################################################################ +# Copyright (c) 2019 Mellanox Technologies +# +# Platform specific sensors config for SN4700 +################################################################################ + +# Temperature sensors +bus "i2c-2" "i2c-1-mux (chan_id 1)" + chip "mlxsw-i2c-*-48" + label temp1 "Ambient ASIC Temp" + +bus "i2c-7" "i2c-1-mux (chan_id 6)" + chip "tmp102-i2c-*-49" + label temp1 "Ambient Fan Side Temp (air intake)" + chip "tmp102-i2c-*-4a" + label temp1 "Ambient Port Side Temp (air exhaust)" + +bus "i2c-15" "i2c-1-mux (chan_id 6)" + chip "tmp102-i2c-15-49" + label temp1 "Ambient COMEX Temp" + +# Power controllers +bus "i2c-5" "i2c-1-mux (chan_id 4)" + chip "tps53679-i2c-*-62" + label in1 "PMIC-1 PSU 12V Rail (in)" + label in2 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail (out)" + ignore in3 + label temp1 "PMIC-1 Temp 1" + label temp2 "PMIC-1 Temp 2" + label power1 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail Pwr (out)" + ignore power2 + label curr1 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail Curr (out)" + ignore curr2 + chip "tps53679-i2c-*-64" + label in1 "PMIC-2 PSU 12V Rail (in)" + label in2 "PMIC-2 ASIC 1.8V MAIN Rail (out)" + compute in2 (1.5)*@, @/(1.5) + label in3 "PMIC-2 ASIC 1.2V MAIN Rail (out)" + label temp1 "PMIC-2 Temp 1" + label temp2 "PMIC-2 Temp 2" + label power1 "PMIC-2 ASIC 1.8V MAIN Rail Pwr (out)" + label power2 "PMIC-2 ASIC 1.2V MAIN Rail Pwr (out)" + label curr1 "PMIC-2 ASIC 1.8V MAIN Rail Curr (out)" + label curr2 "PMIC-2 ASIC 1.2V MAIN Rail Curr (out)" + chip "tps53679-i2c-*-66" + label in1 "PMIC-3 PSU 12V Rail (in)" + label in2 "PMIC-3 ASIC 0.85V VCORE_T0_1 Rail (out)" + label in3 "PMIC-3 ASIC 1.8V T0_1 Rail (out)" + label temp1 "PMIC-3 Temp 1" + label temp2 "PMIC-3 Temp 2" + label power1 "PMIC-3 ASIC 0.85V VCORE_T0_1 Rail Pwr (out)" + label power2 "PMIC-3 ASIC 1.8V T0_1 Rail Pwr (out)" + label curr1 "PMIC-3 ASIC 0.85V VCORE_T0_1 Rail Curr (out)" + label curr2 "PMIC-3 ASIC 1.8V T0_1 Rail Curr (out)" + chip "tps53679-i2c-*-68" + label in1 "PMIC-4 PSU 12V Rail (in)" + label in2 "PMIC-4 ASIC 0.85V VCORE_T2_3 Rail (out)" + label in3 "PMIC-4 ASIC 1.8V T2_3 Rail (out)" + label temp1 "PMIC-4 Temp 1" + label temp2 "PMIC-4 Temp 2" + label power1 "PMIC-4 ASIC 0.85V VCORE_T2_3 Rail Pwr (out)" + label power2 "PMIC-4 ASIC 1.8V T2_3 Rail Pwr (out)" + label curr1 "PMIC-4 ASIC 0.85V VCORE_T2_3 Rail Curr (out)" + label curr2 "PMIC-4 ASIC 1.8V T2_3 Rail Curr (out)" + chip "tps53679-i2c-*-6a" + label in1 "PMIC-5 PSU 12V Rail (in)" + label in2 "PMIC-5 ASIC 0.85V VCORE_T4_5 Rail (out)" + label in3 "PMIC-5 ASIC 1.8V T4_5 Rail (out)" + label temp1 "PMIC-5 Temp 1" + label temp2 "PMIC-5 Temp 2" + label power1 "PMIC-5 ASIC 0.85V VCORE_T4_5 Rail Pwr (out)" + label power2 "PMIC-5 ASIC 1.8V T4_5 Rail Pwr (out)" + label curr1 "PMIC-5 ASIC 0.85V VCORE_T4_5 Rail Curr (out)" + label curr2 "PMIC-5 ASIC 1.8V T4_5 Rail Curr (out)" + chip "tps53679-i2c-*-6c" + label in1 "PMIC-6 PSU 12V Rail (in)" + label in2 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail (out)" + label in3 "PMIC-6 ASIC 1.8V T6_7 Rail (out)" + label temp1 "PMIC-6 Temp 1" + label temp2 "PMIC-6 Temp 2" + label power1 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power2 "PMIC-6 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr2 "PMIC-6 ASIC 1.8V T6_7 Rail Curr (out)" + chip "tps53679-i2c-*-6e" + label in1 "PMIC-7 PSU 12V Rail (in)" + label in2 "PMIC-7 ASIC 1.2V T0_3 Rail (out)" + label in3 "PMIC-7 ASIC 1.2V T4_7 Rail (out)" + label temp1 "PMIC-7 Temp 1" + label temp2 "PMIC-7 Temp 2" + label power1 "PMIC-7 ASIC 1.2V T0_3 Rail Pwr (out)" + label power2 "PMIC-7 ASIC 1.2V T4_7 Rail Pwr (out)" + label curr1 "PMIC-7 ASIC 1.2V T0_3 Rail Curr (out)" + label curr2 "PMIC-7 ASIC 1.2V T4_7 Rail Curr (out)" + +bus "i2c-15" "i2c-1-mux (chan_id 6)" + chip "tps53679-i2c-*-58" + label in1 "PMIC-8 PSU 12V Rail (in)" + label in2 "PMIC-8 COMEX 1.8V Rail (out)" + label in3 "PMIC-8 COMEX 1.05V Rail (out)" + label temp1 "PMIC-8 Temp 1" + label temp2 "PMIC-8 Temp 2" + label power1 "PMIC-8 COMEX 1.8V Rail Pwr (out)" + label power2 "PMIC-8 COMEX 1.05V Rail Pwr (out)" + label curr1 "PMIC-8 COMEX 1.8V Rail Curr (out)" + label curr2 "PMIC-8 COMEX 1.05V Rail Curr (out)" + chip "tps53679-i2c-*-61" + label in1 "PMIC-9 PSU 12V Rail (in)" + label in2 "PMIC-9 COMEX 1.2V Rail (out)" + ignore in3 + label temp1 "PMIC-9 Temp 1" + label temp2 "PMIC-9 Temp 2" + label power1 "PMIC-9 COMEX 1.2V Rail Pwr (out)" + ignore power2 + label curr1 "PMIC-9 COMEX 1.2V Rail Curr (out)" + ignore curr2 + +# Power supplies +bus "i2c-4" "i2c-1-mux (chan_id 3)" + chip "dps460-i2c-*-58" + label in1 "PSU-1(L) 220V Rail (in)" + ignore in2 + label in3 "PSU-1(L) 12V Rail (out)" + label fan1 "PSU-1(L) Fan 1" + label temp1 "PSU-1(L) Temp 1" + label temp2 "PSU-1(L) Temp 2" + label temp3 "PSU-1(L) Temp 3" + label power1 "PSU-1(L) 220V Rail Pwr (in)" + label power2 "PSU-1(L) 12V Rail Pwr (out)" + label curr1 "PSU-1(L) 220V Rail Curr (in)" + label curr2 "PSU-1(L) 12V Rail Curr (out)" + chip "dps460-i2c-*-59" + label in1 "PSU-2(R) 220V Rail (in)" + ignore in2 + label in3 "PSU-2(R) 12V Rail (out)" + label fan1 "PSU-2(R) Fan 1" + label temp1 "PSU-2(R) Temp 1" + label temp2 "PSU-2(R) Temp 2" + label temp3 "PSU-2(R) Temp 3" + label power1 "PSU-2(R) 220V Rail Pwr (in)" + label power2 "PSU-2(R) 12V Rail Pwr (out)" + label curr1 "PSU-2(R) 220V Rail Curr (in)" + label curr2 "PSU-2(R) 12V Rail Curr (out)" + +# Chassis fans +chip "mlxreg_fan-isa-*" + label fan1 "Chassis Fan Drawer-1 Tach 1" + label fan2 "Chassis Fan Drawer-1 Tach 2" + label fan3 "Chassis Fan Drawer-2 Tach 1" + label fan4 "Chassis Fan Drawer-2 Tach 2" + label fan5 "Chassis Fan Drawer-3 Tach 1" + label fan6 "Chassis Fan Drawer-3 Tach 2" + label fan7 "Chassis Fan Drawer-4 Tach 1" + label fan8 "Chassis Fan Drawer-4 Tach 2" + label fan9 "Chassis Fan Drawer-5 Tach 1" + label fan10 "Chassis Fan Drawer-5 Tach 2" + label fan11 "Chassis Fan Drawer-6 Tach 1" + label fan12 "Chassis Fan Drawer-6 Tach 2" + +# Miscellaneous +chip "*-virtual-*" + ignore temp1 diff --git a/device/mellanox/x86_64-mlnx_msn4700_simx-r0/ACS-MSN4700 b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/ACS-MSN4700 new file mode 120000 index 000000000000..3f61c9909a65 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/ACS-MSN4700 @@ -0,0 +1 @@ +../x86_64-mlnx_msn4700-r0/ACS-MSN4700 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700_simx-r0/default_sku b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/default_sku new file mode 120000 index 000000000000..6f72f84de680 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/default_sku @@ -0,0 +1 @@ +../x86_64-mlnx_msn4700-r0/default_sku \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700_simx-r0/platform_reboot b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/platform_reboot new file mode 120000 index 000000000000..dfaf53417665 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/platform_reboot @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700_simx-r0/platform_reboot \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700_simx-r0/plugins b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/plugins new file mode 120000 index 000000000000..e98a1d3fbaeb --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/plugins @@ -0,0 +1 @@ +../x86_64-mlnx_msn4700-r0/plugins \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700_simx-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..40fc367acf32 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/pmon_daemon_control.json @@ -0,0 +1,5 @@ +{ + "skip_ledd": true, + "skip_xcvrd": true, + "skip_psud": true +} diff --git a/device/mellanox/x86_64-mlnx_msn4700_simx-r0/syseeprom.hex b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/syseeprom.hex new file mode 100644 index 000000000000..b50ffa5a0231 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/syseeprom.hex @@ -0,0 +1,256 @@ +54 6c 76 49 6e 66 6f 00 01 02 53 21 40 4d 53 4e +33 37 30 30 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 22 14 4d +53 4e 33 37 30 30 2d 56 53 32 46 00 00 00 00 00 +00 00 00 23 18 4d 54 31 38 35 31 58 30 32 39 36 +31 00 00 00 00 00 00 00 00 00 00 00 00 24 06 98 +03 9b 94 d4 80 25 13 31 32 2f 32 38 2f 32 30 31 +38 20 30 34 3a 34 32 3a 31 38 26 01 00 2a 02 00 +fe 2b 08 4d 65 6c 6c 61 6e 6f 78 fd 24 00 00 81 +19 00 16 01 01 00 56 00 00 4d 4c 4e 58 02 01 0c +05 0e 02 10 06 12 07 00 00 00 00 00 00 00 00 00 +00 fd a4 00 00 81 19 00 92 00 03 01 01 00 00 4d +54 31 38 35 31 58 30 32 39 36 31 00 00 00 00 00 +00 00 00 00 00 00 00 4d 53 4e 33 37 30 30 2d 56 +53 32 46 00 00 00 00 00 00 00 00 41 32 00 00 00 +3a 82 b8 41 6e 61 63 6f 6e 64 61 20 45 74 68 20 +32 30 30 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 70 00 00 00 0e 74 4d 53 4e 33 37 +30 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 fd 24 00 00 81 19 00 10 00 +03 05 e8 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 fd 24 00 +00 81 19 00 1e 00 11 02 85 00 00 0d 00 00 00 00 +00 00 00 98 03 9b 94 d4 80 00 fe 98 03 9b 03 00 +94 d4 80 fd 24 00 00 81 19 00 12 00 01 06 81 00 +00 00 46 00 00 08 00 06 06 06 06 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 fd 14 00 00 81 19 00 +0e 00 02 07 99 00 00 30 00 20 00 00 00 00 00 28 +40 78 38 36 5f 36 34 2d 6d 6c 6e 78 5f 6d 73 6e +33 37 30 30 2d 72 30 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 29 15 32 30 31 38 2e 31 31 2d 35 2e 32 2e 30 +30 30 38 2d 39 36 30 30 fe 04 89 cb 82 5b 00 00 +00 00 00 fe 04 72 60 7f 13 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/asic.conf b/device/virtual/x86_64-kvm_x86_64-r0/asic.conf new file mode 100644 index 000000000000..58c5d5348bb9 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/asic.conf @@ -0,0 +1 @@ +NUM_ASIC=1 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers.json.j2 new file mode 100644 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_def.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_def.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_def.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t0.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t1.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/pg_profile_lookup.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/port_config.ini new file mode 100644 index 000000000000..95cf5eec9e4e --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 25,26,27,28 fortyGigE0/0 0 40000 +Ethernet4 29,30,31,32 fortyGigE0/4 1 40000 +Ethernet8 33,34,35,36 fortyGigE0/8 2 40000 +Ethernet12 37,38,39,40 fortyGigE0/12 3 40000 +Ethernet16 45,46,47,48 fortyGigE0/16 4 40000 +Ethernet20 41,42,43,44 fortyGigE0/20 5 40000 +Ethernet24 1,2,3,4 fortyGigE0/24 6 40000 +Ethernet28 5,6,7,8 fortyGigE0/28 7 40000 +Ethernet32 13,14,15,16 fortyGigE0/32 8 40000 +Ethernet36 9,10,11,12 fortyGigE0/36 9 40000 +Ethernet40 17,18,19,20 fortyGigE0/40 10 40000 +Ethernet44 21,22,23,24 fortyGigE0/44 11 40000 +Ethernet48 53,54,55,56 fortyGigE0/48 12 40000 +Ethernet52 49,50,51,52 fortyGigE0/52 13 40000 +Ethernet56 57,58,59,60 fortyGigE0/56 14 40000 +Ethernet60 61,62,63,64 fortyGigE0/60 15 40000 +Ethernet64 69,70,71,72 fortyGigE0/64 16 40000 +Ethernet68 65,66,67,68 fortyGigE0/68 17 40000 +Ethernet72 73,74,75,76 fortyGigE0/72 18 40000 +Ethernet76 77,78,79,80 fortyGigE0/76 19 40000 +Ethernet80 109,110,111,112 fortyGigE0/80 20 40000 +Ethernet84 105,106,107,108 fortyGigE0/84 21 40000 +Ethernet88 113,114,115,116 fortyGigE0/88 22 40000 +Ethernet92 117,118,119,120 fortyGigE0/92 23 40000 +Ethernet96 125,126,127,128 fortyGigE0/96 24 40000 +Ethernet100 121,122,123,124 fortyGigE0/100 25 40000 +Ethernet104 81,82,83,84 fortyGigE0/104 26 40000 +Ethernet108 85,86,87,88 fortyGigE0/108 27 40000 +Ethernet112 93,94,95,96 fortyGigE0/112 28 40000 +Ethernet116 89,90,91,92 fortyGigE0/116 29 40000 +Ethernet120 101,102,103,104 fortyGigE0/120 30 40000 +Ethernet124 97,98,99,100 fortyGigE0/124 31 40000 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/qos.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile new file mode 100644 index 000000000000..bfc466f27e54 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile @@ -0,0 +1,5 @@ +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/td2-s6000-32x40G.config.bcm new file mode 100644 index 000000000000..4c94db7107c7 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/td2-s6000-32x40G.config.bcm @@ -0,0 +1,646 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000007fffffffffffffffffffffffffe +pbmp_xport_xe=0x000007fffffffffffffffffffffffffe + +# Ports configuration +# xe0 (40G) +portmap_1=25:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x2031 +phy_xaui_rx_polarity_flip_1=0xe +phy_xaui_tx_polarity_flip_1=0x2 +serdes_driver_current_lane0_xe0=0x5 +serdes_driver_current_lane1_xe0=0x5 +serdes_driver_current_lane2_xe0=0x5 +serdes_driver_current_lane3_xe0=0x5 +serdes_pre_driver_current_lane0_xe0=0x5 +serdes_pre_driver_current_lane1_xe0=0x5 +serdes_pre_driver_current_lane2_xe0=0x5 +serdes_pre_driver_current_lane3_xe0=0x5 +serdes_preemphasis_lane0_xe0=0xcad0 +serdes_preemphasis_lane1_xe0=0xc6e0 +serdes_preemphasis_lane2_xe0=0xc6e0 +serdes_preemphasis_lane3_xe0=0xd2b0 + +# xe1 (40G) +portmap_2=29:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x213 +phy_xaui_rx_polarity_flip_2=0xc +phy_xaui_tx_polarity_flip_2=0x9 +serdes_driver_current_lane0_xe1=0x6 +serdes_driver_current_lane1_xe1=0x7 +serdes_driver_current_lane2_xe1=0x6 +serdes_driver_current_lane3_xe1=0x6 +serdes_pre_driver_current_lane0_xe1=0x6 +serdes_pre_driver_current_lane1_xe1=0x7 +serdes_pre_driver_current_lane2_xe1=0x6 +serdes_pre_driver_current_lane3_xe1=0x6 +serdes_preemphasis_lane0_xe1=0xc2f0 +serdes_preemphasis_lane1_xe1=0xd2b0 +serdes_preemphasis_lane2_xe1=0xc6e0 +serdes_preemphasis_lane3_xe1=0xc2f0 + +# xe2 (40G) +portmap_3=33:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x132 +phy_xaui_rx_polarity_flip_3=0xe +phy_xaui_tx_polarity_flip_3=0x2 +serdes_driver_current_lane0_xe2=0x4 +serdes_driver_current_lane1_xe2=0x4 +serdes_driver_current_lane2_xe2=0x4 +serdes_driver_current_lane3_xe2=0x4 +serdes_pre_driver_current_lane0_xe2=0x4 +serdes_pre_driver_current_lane1_xe2=0x4 +serdes_pre_driver_current_lane2_xe2=0x4 +serdes_pre_driver_current_lane3_xe2=0x4 +serdes_preemphasis_lane0_xe2=0xc6e0 +serdes_preemphasis_lane1_xe2=0xc6e0 +serdes_preemphasis_lane2_xe2=0xc6e0 +serdes_preemphasis_lane3_xe2=0xc6e0 + +# xe3 (40G) +portmap_4=37:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x1203 +phy_xaui_rx_polarity_flip_4=0x3 +phy_xaui_tx_polarity_flip_4=0xe +serdes_driver_current_lane0_xe3=0x4 +serdes_driver_current_lane1_xe3=0x4 +serdes_driver_current_lane2_xe3=0x4 +serdes_driver_current_lane3_xe3=0x4 +serdes_pre_driver_current_lane0_xe3=0x4 +serdes_pre_driver_current_lane1_xe3=0x4 +serdes_pre_driver_current_lane2_xe3=0x4 +serdes_pre_driver_current_lane3_xe3=0x4 +serdes_preemphasis_lane0_xe3=0xcad0 +serdes_preemphasis_lane1_xe3=0xcad0 +serdes_preemphasis_lane2_xe3=0xc2f0 +serdes_preemphasis_lane3_xe3=0xc2f0 + +# xe4 (40G) +portmap_5=45:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x213 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x8 +serdes_driver_current_lane0_xe4=0x4 +serdes_driver_current_lane1_xe4=0x4 +serdes_driver_current_lane2_xe4=0x4 +serdes_driver_current_lane3_xe4=0x4 +serdes_pre_driver_current_lane0_xe4=0x4 +serdes_pre_driver_current_lane1_xe4=0x4 +serdes_pre_driver_current_lane2_xe4=0x4 +serdes_pre_driver_current_lane3_xe4=0x4 +serdes_preemphasis_lane0_xe4=0xc2f0 +serdes_preemphasis_lane1_xe4=0xc2f0 +serdes_preemphasis_lane2_xe4=0xc2f0 +serdes_preemphasis_lane3_xe4=0xc2f0 + +# xe5 (40G) +portmap_6=41:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x3021 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xb +serdes_driver_current_lane0_xe5=0x4 +serdes_driver_current_lane1_xe5=0x4 +serdes_driver_current_lane2_xe5=0x4 +serdes_driver_current_lane3_xe5=0x4 +serdes_pre_driver_current_lane0_xe5=0x4 +serdes_pre_driver_current_lane1_xe5=0x4 +serdes_pre_driver_current_lane2_xe5=0x4 +serdes_pre_driver_current_lane3_xe5=0x4 +serdes_preemphasis_lane0_xe5=0xc6e0 +serdes_preemphasis_lane1_xe5=0xc2f0 +serdes_preemphasis_lane2_xe5=0xc2f0 +serdes_preemphasis_lane3_xe5=0xcad0 + +# xe6 (40G) +portmap_7=1:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x2031 +phy_xaui_rx_polarity_flip_7=0xe +phy_xaui_tx_polarity_flip_7=0xd +serdes_driver_current_lane0_xe6=0x5 +serdes_driver_current_lane1_xe6=0x5 +serdes_driver_current_lane2_xe6=0x5 +serdes_driver_current_lane3_xe6=0x5 +serdes_pre_driver_current_lane0_xe6=0x5 +serdes_pre_driver_current_lane1_xe6=0x5 +serdes_pre_driver_current_lane2_xe6=0x5 +serdes_pre_driver_current_lane3_xe6=0x5 +serdes_preemphasis_lane0_xe6=0xc6e0 +serdes_preemphasis_lane1_xe6=0xcad0 +serdes_preemphasis_lane2_xe6=0xc6e0 +serdes_preemphasis_lane3_xe6=0xcad0 + +# xe7 (40G) +portmap_8=5:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x1203 +phy_xaui_rx_polarity_flip_8=0xc +phy_xaui_tx_polarity_flip_8=0x1 +serdes_driver_current_lane0_xe7=0x4 +serdes_driver_current_lane1_xe7=0x4 +serdes_driver_current_lane2_xe7=0x4 +serdes_driver_current_lane3_xe7=0x4 +serdes_pre_driver_current_lane0_xe7=0x4 +serdes_pre_driver_current_lane1_xe7=0x4 +serdes_pre_driver_current_lane2_xe7=0x4 +serdes_pre_driver_current_lane3_xe7=0x4 +serdes_preemphasis_lane0_xe7=0xc6e0 +serdes_preemphasis_lane1_xe7=0xc6e0 +serdes_preemphasis_lane2_xe7=0xc6e0 +serdes_preemphasis_lane3_xe7=0xc6e0 + +# xe8 (40G) +portmap_9=13:40 +xgxs_rx_lane_map_9=0x213 +xgxs_tx_lane_map_9=0x132 +phy_xaui_rx_polarity_flip_9=0xe +phy_xaui_tx_polarity_flip_9=0x0 +serdes_driver_current_lane0_xe8=0x2 +serdes_driver_current_lane1_xe8=0x3 +serdes_driver_current_lane2_xe8=0x2 +serdes_driver_current_lane3_xe8=0x2 +serdes_pre_driver_current_lane0_xe8=0x2 +serdes_pre_driver_current_lane1_xe8=0x3 +serdes_pre_driver_current_lane2_xe8=0x2 +serdes_pre_driver_current_lane3_xe8=0x2 +serdes_preemphasis_lane0_xe8=0xb270 +serdes_preemphasis_lane1_xe8=0xbb10 +serdes_preemphasis_lane2_xe8=0xb720 +serdes_preemphasis_lane3_xe8=0xb720 + +# xe9 (40G) +portmap_10=9:40 +xgxs_rx_lane_map_10=0x3120 +xgxs_tx_lane_map_10=0x3021 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x4 +serdes_driver_current_lane0_xe9=0x3 +serdes_driver_current_lane1_xe9=0x3 +serdes_driver_current_lane2_xe9=0x3 +serdes_driver_current_lane3_xe9=0x3 +serdes_pre_driver_current_lane0_xe9=0x3 +serdes_pre_driver_current_lane1_xe9=0x3 +serdes_pre_driver_current_lane2_xe9=0x3 +serdes_pre_driver_current_lane3_xe9=0x3 +serdes_preemphasis_lane0_xe9=0xc2f0 +serdes_preemphasis_lane1_xe9=0xc6e0 +serdes_preemphasis_lane2_xe9=0xbf00 +serdes_preemphasis_lane3_xe9=0xc2f0 + +# xe10 (40G) +portmap_11=17:40 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x132 +phy_xaui_rx_polarity_flip_11=0xe +phy_xaui_tx_polarity_flip_11=0x0 +serdes_driver_current_lane0_xe10=0x2 +serdes_driver_current_lane1_xe10=0x2 +serdes_driver_current_lane2_xe10=0x2 +serdes_driver_current_lane3_xe10=0x2 +serdes_pre_driver_current_lane0_xe10=0x2 +serdes_pre_driver_current_lane1_xe10=0x2 +serdes_pre_driver_current_lane2_xe10=0x2 +serdes_pre_driver_current_lane3_xe10=0x2 +serdes_preemphasis_lane0_xe10=0xb330 +serdes_preemphasis_lane1_xe10=0xbb10 +serdes_preemphasis_lane2_xe10=0xbb10 +serdes_preemphasis_lane3_xe10=0xbb10 + +# xe11 (40G) +portmap_12=21:40 +xgxs_rx_lane_map_12=0x123 +xgxs_tx_lane_map_12=0x1203 +phy_xaui_rx_polarity_flip_12=0xc +phy_xaui_tx_polarity_flip_12=0xe +serdes_driver_current_lane0_xe11=0x2 +serdes_driver_current_lane1_xe11=0x2 +serdes_driver_current_lane2_xe11=0x2 +serdes_driver_current_lane3_xe11=0x2 +serdes_pre_driver_current_lane0_xe11=0x2 +serdes_pre_driver_current_lane1_xe11=0x2 +serdes_pre_driver_current_lane2_xe11=0x2 +serdes_pre_driver_current_lane3_xe11=0x2 +serdes_preemphasis_lane0_xe11=0xb330 +serdes_preemphasis_lane1_xe11=0xb330 +serdes_preemphasis_lane2_xe11=0xb330 +serdes_preemphasis_lane3_xe11=0xb330 + +# xe12 (40G) +portmap_13=53:40 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x231 +phy_xaui_rx_polarity_flip_13=0x1 +phy_xaui_tx_polarity_flip_13=0x0 +serdes_driver_current_lane0_xe12=0x2 +serdes_driver_current_lane1_xe12=0x2 +serdes_driver_current_lane2_xe12=0x2 +serdes_driver_current_lane3_xe12=0x2 +serdes_pre_driver_current_lane0_xe12=0x2 +serdes_pre_driver_current_lane1_xe12=0x2 +serdes_pre_driver_current_lane2_xe12=0x2 +serdes_pre_driver_current_lane3_xe12=0x2 +serdes_preemphasis_lane0_xe12=0xaf40 +serdes_preemphasis_lane1_xe12=0xaf40 +serdes_preemphasis_lane2_xe12=0xaf40 +serdes_preemphasis_lane3_xe12=0xaf40 + +# xe13 (40G) +portmap_14=49:40 +xgxs_rx_lane_map_14=0x1302 +xgxs_tx_lane_map_14=0x2031 +phy_xaui_rx_polarity_flip_14=0xb +phy_xaui_tx_polarity_flip_14=0x3 +serdes_driver_current_lane0_xe13=0x2 +serdes_driver_current_lane1_xe13=0x2 +serdes_driver_current_lane2_xe13=0x2 +serdes_driver_current_lane3_xe13=0x2 +serdes_pre_driver_current_lane0_xe13=0x2 +serdes_pre_driver_current_lane1_xe13=0x2 +serdes_pre_driver_current_lane2_xe13=0x2 +serdes_pre_driver_current_lane3_xe13=0x2 +serdes_preemphasis_lane0_xe13=0xa760 +serdes_preemphasis_lane1_xe13=0xa760 +serdes_preemphasis_lane2_xe13=0xa760 +serdes_preemphasis_lane3_xe13=0xa760 + +# xe14 (40G) +portmap_15=57:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x2031 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_xe14=0x1 +serdes_driver_current_lane1_xe14=0x1 +serdes_driver_current_lane2_xe14=0x1 +serdes_driver_current_lane3_xe14=0x1 +serdes_pre_driver_current_lane0_xe14=0x1 +serdes_pre_driver_current_lane1_xe14=0x1 +serdes_pre_driver_current_lane2_xe14=0x1 +serdes_pre_driver_current_lane3_xe14=0x1 +serdes_preemphasis_lane0_xe14=0xa760 +serdes_preemphasis_lane1_xe14=0xa760 +serdes_preemphasis_lane2_xe14=0xa760 +serdes_preemphasis_lane3_xe14=0xa760 + +# xe15 (40G) +portmap_16=61:40 +xgxs_rx_lane_map_16=0x132 +xgxs_tx_lane_map_16=0x213 +phy_xaui_rx_polarity_flip_16=0x0 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_xe15=0x2 +serdes_driver_current_lane1_xe15=0x2 +serdes_driver_current_lane2_xe15=0x2 +serdes_driver_current_lane3_xe15=0x2 +serdes_pre_driver_current_lane0_xe15=0x2 +serdes_pre_driver_current_lane1_xe15=0x2 +serdes_pre_driver_current_lane2_xe15=0x2 +serdes_pre_driver_current_lane3_xe15=0x2 +serdes_preemphasis_lane0_xe15=0xa760 +serdes_preemphasis_lane1_xe15=0xa760 +serdes_preemphasis_lane2_xe15=0xa760 +serdes_preemphasis_lane3_xe15=0xa760 + +# xe16 (40G) +portmap_17=69:40 +xgxs_rx_lane_map_17=0x213 +xgxs_tx_lane_map_17=0x2130 +phy_xaui_rx_polarity_flip_17=0x1 +phy_xaui_tx_polarity_flip_17=0xf +serdes_driver_current_lane0_xe16=0x1 +serdes_driver_current_lane1_xe16=0x1 +serdes_driver_current_lane2_xe16=0x1 +serdes_driver_current_lane3_xe16=0x1 +serdes_pre_driver_current_lane0_xe16=0x1 +serdes_pre_driver_current_lane1_xe16=0x1 +serdes_pre_driver_current_lane2_xe16=0x1 +serdes_pre_driver_current_lane3_xe16=0x1 +serdes_preemphasis_lane0_xe16=0xa760 +serdes_preemphasis_lane1_xe16=0xa760 +serdes_preemphasis_lane2_xe16=0xa760 +serdes_preemphasis_lane3_xe16=0xa760 + +# xe17 (40G) +portmap_18=65:40 +xgxs_rx_lane_map_18=0x132 +xgxs_tx_lane_map_18=0x2031 +phy_xaui_rx_polarity_flip_18=0x3 +phy_xaui_tx_polarity_flip_18=0x9 +serdes_driver_current_lane0_xe17=0x1 +serdes_driver_current_lane1_xe17=0x1 +serdes_driver_current_lane2_xe17=0x1 +serdes_driver_current_lane3_xe17=0x1 +serdes_pre_driver_current_lane0_xe17=0x1 +serdes_pre_driver_current_lane1_xe17=0x1 +serdes_pre_driver_current_lane2_xe17=0x1 +serdes_pre_driver_current_lane3_xe17=0x1 +serdes_preemphasis_lane0_xe17=0xa370 +serdes_preemphasis_lane1_xe17=0xa370 +serdes_preemphasis_lane2_xe17=0xa370 +serdes_preemphasis_lane3_xe17=0xa370 + +# xe18 (40G) +portmap_19=73:40 +xgxs_rx_lane_map_19=0x213 +xgxs_tx_lane_map_19=0x2031 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_xe18=0x2 +serdes_driver_current_lane1_xe18=0x2 +serdes_driver_current_lane2_xe18=0x2 +serdes_driver_current_lane3_xe18=0x2 +serdes_pre_driver_current_lane0_xe18=0x2 +serdes_pre_driver_current_lane1_xe18=0x2 +serdes_pre_driver_current_lane2_xe18=0x2 +serdes_pre_driver_current_lane3_xe18=0x2 +serdes_preemphasis_lane0_xe18=0xa760 +serdes_preemphasis_lane1_xe18=0xa760 +serdes_preemphasis_lane2_xe18=0xa760 +serdes_preemphasis_lane3_xe18=0xa760 + +# xe19 (40G) +portmap_20=77:40 +xgxs_rx_lane_map_20=0x123 +xgxs_tx_lane_map_20=0x1203 +phy_xaui_rx_polarity_flip_20=0x3 +phy_xaui_tx_polarity_flip_20=0xe +serdes_driver_current_lane0_xe19=0x2 +serdes_driver_current_lane1_xe19=0x2 +serdes_driver_current_lane2_xe19=0x2 +serdes_driver_current_lane3_xe19=0x2 +serdes_pre_driver_current_lane0_xe19=0x2 +serdes_pre_driver_current_lane1_xe19=0x2 +serdes_pre_driver_current_lane2_xe19=0x2 +serdes_pre_driver_current_lane3_xe19=0x2 +serdes_preemphasis_lane0_xe19=0xaf40 +serdes_preemphasis_lane1_xe19=0xaf40 +serdes_preemphasis_lane2_xe19=0xaf40 +serdes_preemphasis_lane3_xe19=0xaf40 + +# xe20 (40G) +portmap_21=109:40 +xgxs_rx_lane_map_21=0x132 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0x8 +phy_xaui_tx_polarity_flip_21=0x0 +serdes_driver_current_lane0_xe20=0x1 +serdes_driver_current_lane1_xe20=0x1 +serdes_driver_current_lane2_xe20=0x1 +serdes_driver_current_lane3_xe20=0x2 +serdes_pre_driver_current_lane0_xe20=0x1 +serdes_pre_driver_current_lane1_xe20=0x1 +serdes_pre_driver_current_lane2_xe20=0x1 +serdes_pre_driver_current_lane3_xe20=0x2 +serdes_preemphasis_lane0_xe20=0xb330 +serdes_preemphasis_lane1_xe20=0xb330 +serdes_preemphasis_lane2_xe20=0xb330 +serdes_preemphasis_lane3_xe20=0xbff0 + +# xe21 (40G) +portmap_22=105:40 +xgxs_rx_lane_map_22=0x1320 +xgxs_tx_lane_map_22=0x3021 +phy_xaui_rx_polarity_flip_22=0xd +phy_xaui_tx_polarity_flip_22=0xb +serdes_driver_current_lane0_xe21=0x1 +serdes_driver_current_lane1_xe21=0x1 +serdes_driver_current_lane2_xe21=0x1 +serdes_driver_current_lane3_xe21=0x1 +serdes_pre_driver_current_lane0_xe21=0x1 +serdes_pre_driver_current_lane1_xe21=0x1 +serdes_pre_driver_current_lane2_xe21=0x1 +serdes_pre_driver_current_lane3_xe21=0x1 +serdes_preemphasis_lane0_xe21=0xb330 +serdes_preemphasis_lane1_xe21=0xb330 +serdes_preemphasis_lane2_xe21=0xb330 +serdes_preemphasis_lane3_xe21=0xb330 + +# xe22 (40G) +portmap_23=113:40 +xgxs_rx_lane_map_23=0x132 +xgxs_tx_lane_map_23=0x132 +phy_xaui_rx_polarity_flip_23=0x8 +phy_xaui_tx_polarity_flip_23=0x0 +serdes_driver_current_lane0_xe22=0x1 +serdes_driver_current_lane1_xe22=0x1 +serdes_driver_current_lane2_xe22=0x1 +serdes_driver_current_lane3_xe22=0x1 +serdes_pre_driver_current_lane0_xe22=0x1 +serdes_pre_driver_current_lane1_xe22=0x1 +serdes_pre_driver_current_lane2_xe22=0x1 +serdes_pre_driver_current_lane3_xe22=0x1 +serdes_preemphasis_lane0_xe22=0xbb10 +serdes_preemphasis_lane1_xe22=0xbb10 +serdes_preemphasis_lane2_xe22=0xbb10 +serdes_preemphasis_lane3_xe22=0xc2f0 + +# xe23 (40G) +portmap_24=117:40 +xgxs_rx_lane_map_24=0x231 +xgxs_tx_lane_map_24=0x1203 +phy_xaui_rx_polarity_flip_24=0x3 +phy_xaui_tx_polarity_flip_24=0xe +serdes_driver_current_lane0_xe23=0x3 +serdes_driver_current_lane1_xe23=0x5 +serdes_driver_current_lane2_xe23=0x3 +serdes_driver_current_lane3_xe23=0x3 +serdes_pre_driver_current_lane0_xe23=0x3 +serdes_pre_driver_current_lane1_xe23=0x5 +serdes_pre_driver_current_lane2_xe23=0x3 +serdes_pre_driver_current_lane3_xe23=0x3 +serdes_preemphasis_lane0_xe23=0xc6e0 +serdes_preemphasis_lane1_xe23=0xc6e0 +serdes_preemphasis_lane2_xe23=0xc6e0 +serdes_preemphasis_lane3_xe23=0xc6e0 + +# xe24 (40G) +portmap_25=125:40 +xgxs_rx_lane_map_25=0x132 +xgxs_tx_lane_map_25=0x132 +phy_xaui_rx_polarity_flip_25=0x8 +phy_xaui_tx_polarity_flip_25=0x0 +serdes_driver_current_lane0_xe24=0x4 +serdes_driver_current_lane1_xe24=0x4 +serdes_driver_current_lane2_xe24=0x4 +serdes_driver_current_lane3_xe24=0x4 +serdes_pre_driver_current_lane0_xe24=0x4 +serdes_pre_driver_current_lane1_xe24=0x4 +serdes_pre_driver_current_lane2_xe24=0x4 +serdes_pre_driver_current_lane3_xe24=0x4 +serdes_preemphasis_lane0_xe24=0xc6e0 +serdes_preemphasis_lane1_xe24=0xc6e0 +serdes_preemphasis_lane2_xe24=0xc6e0 +serdes_preemphasis_lane3_xe24=0xcec0 + +# xe25 (40G) +portmap_26=121:40 +xgxs_rx_lane_map_26=0x1320 +xgxs_tx_lane_map_26=0x3021 +phy_xaui_rx_polarity_flip_26=0xd +phy_xaui_tx_polarity_flip_26=0xb +serdes_driver_current_lane0_xe25=0x4 +serdes_driver_current_lane1_xe25=0x4 +serdes_driver_current_lane2_xe25=0x4 +serdes_driver_current_lane3_xe25=0x4 +serdes_pre_driver_current_lane0_xe25=0x4 +serdes_pre_driver_current_lane1_xe25=0x4 +serdes_pre_driver_current_lane2_xe25=0x4 +serdes_pre_driver_current_lane3_xe25=0x4 +serdes_preemphasis_lane0_xe25=0xc6e0 +serdes_preemphasis_lane1_xe25=0xc6e0 +serdes_preemphasis_lane2_xe25=0xc6e0 +serdes_preemphasis_lane3_xe25=0xc6e0 + +# xe26 (40G) +portmap_27=81:40 +xgxs_rx_lane_map_27=0x1320 +xgxs_tx_lane_map_27=0x2031 +phy_xaui_rx_polarity_flip_27=0x1 +phy_xaui_tx_polarity_flip_27=0x2 +serdes_driver_current_lane0_xe26=0x2 +serdes_driver_current_lane1_xe26=0x2 +serdes_driver_current_lane2_xe26=0x2 +serdes_driver_current_lane3_xe26=0x2 +serdes_pre_driver_current_lane0_xe26=0x2 +serdes_pre_driver_current_lane1_xe26=0x2 +serdes_pre_driver_current_lane2_xe26=0x2 +serdes_pre_driver_current_lane3_xe26=0x2 +serdes_preemphasis_lane0_xe26=0xbb10 +serdes_preemphasis_lane1_xe26=0xbb10 +serdes_preemphasis_lane2_xe26=0xbf00 +serdes_preemphasis_lane3_xe26=0xbb10 + +# xe27 (40G) +portmap_28=85:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x1203 +phy_xaui_rx_polarity_flip_28=0xc +phy_xaui_tx_polarity_flip_28=0xe +serdes_driver_current_lane0_xe27=0x4 +serdes_driver_current_lane1_xe27=0x5 +serdes_driver_current_lane2_xe27=0x4 +serdes_driver_current_lane3_xe27=0x5 +serdes_pre_driver_current_lane0_xe27=0x4 +serdes_pre_driver_current_lane1_xe27=0x5 +serdes_pre_driver_current_lane2_xe27=0x4 +serdes_pre_driver_current_lane3_xe27=0x5 +serdes_preemphasis_lane0_xe27=0xc2f0 +serdes_preemphasis_lane1_xe27=0xc6e0 +serdes_preemphasis_lane2_xe27=0xc6e0 +serdes_preemphasis_lane3_xe27=0xc6e0 + +# xe28 (40G) +portmap_29=93:40 +xgxs_rx_lane_map_29=0x1320 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x2 +serdes_driver_current_lane0_xe28=0x4 +serdes_driver_current_lane1_xe28=0x4 +serdes_driver_current_lane2_xe28=0x4 +serdes_driver_current_lane3_xe28=0x4 +serdes_pre_driver_current_lane0_xe28=0x4 +serdes_pre_driver_current_lane1_xe28=0x4 +serdes_pre_driver_current_lane2_xe28=0x4 +serdes_pre_driver_current_lane3_xe28=0x4 +serdes_preemphasis_lane0_xe28=0xc2f0 +serdes_preemphasis_lane1_xe28=0xc2f0 +serdes_preemphasis_lane2_xe28=0xc2f0 +serdes_preemphasis_lane3_xe28=0xc2f0 + +# xe29 (40G) +portmap_30=89:40 +xgxs_rx_lane_map_30=0x1320 +xgxs_tx_lane_map_30=0x3021 +phy_xaui_rx_polarity_flip_30=0x2 +phy_xaui_tx_polarity_flip_30=0xb +serdes_driver_current_lane0_xe29=0x4 +serdes_driver_current_lane1_xe29=0x4 +serdes_driver_current_lane2_xe29=0x4 +serdes_driver_current_lane3_xe29=0x4 +serdes_pre_driver_current_lane0_xe29=0x4 +serdes_pre_driver_current_lane1_xe29=0x4 +serdes_pre_driver_current_lane2_xe29=0x4 +serdes_pre_driver_current_lane3_xe29=0x4 +serdes_preemphasis_lane0_xe29=0xcad0 +serdes_preemphasis_lane1_xe29=0xc6e0 +serdes_preemphasis_lane2_xe29=0xc6e0 +serdes_preemphasis_lane3_xe29=0xc6e0 + +# xe30 (40G) +portmap_31=101:40 +xgxs_rx_lane_map_31=0x1320 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x1 +phy_xaui_tx_polarity_flip_31=0x6 +serdes_driver_current_lane0_xe30=0x6 +serdes_driver_current_lane1_xe30=0x6 +serdes_driver_current_lane2_xe30=0x6 +serdes_driver_current_lane3_xe30=0x7 +serdes_pre_driver_current_lane0_xe30=0x6 +serdes_pre_driver_current_lane1_xe30=0x6 +serdes_pre_driver_current_lane2_xe30=0x6 +serdes_pre_driver_current_lane3_xe30=0x7 +serdes_preemphasis_lane0_xe30=0xcec0 +serdes_preemphasis_lane1_xe30=0xcec0 +serdes_preemphasis_lane2_xe30=0xcad0 +serdes_preemphasis_lane3_xe30=0xc6e0 + +# xe31 (40G) +portmap_32=97:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0xc +phy_xaui_tx_polarity_flip_32=0x3 +serdes_driver_current_lane0_xe31=0x5 +serdes_driver_current_lane1_xe31=0x5 +serdes_driver_current_lane2_xe31=0x5 +serdes_driver_current_lane3_xe31=0x5 +serdes_pre_driver_current_lane0_xe31=0x5 +serdes_pre_driver_current_lane1_xe31=0x5 +serdes_pre_driver_current_lane2_xe31=0x5 +serdes_pre_driver_current_lane3_xe31=0x5 +serdes_preemphasis_lane0_xe31=0xcad0 +serdes_preemphasis_lane1_xe31=0xcad0 +serdes_preemphasis_lane2_xe31=0xcad0 +serdes_preemphasis_lane3_xe31=0xcad0 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers.json.j2 new file mode 100644 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_def.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_def.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_def.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t0.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t1.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/pg_profile_lookup.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/port_config.ini new file mode 100644 index 000000000000..95cf5eec9e4e --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 25,26,27,28 fortyGigE0/0 0 40000 +Ethernet4 29,30,31,32 fortyGigE0/4 1 40000 +Ethernet8 33,34,35,36 fortyGigE0/8 2 40000 +Ethernet12 37,38,39,40 fortyGigE0/12 3 40000 +Ethernet16 45,46,47,48 fortyGigE0/16 4 40000 +Ethernet20 41,42,43,44 fortyGigE0/20 5 40000 +Ethernet24 1,2,3,4 fortyGigE0/24 6 40000 +Ethernet28 5,6,7,8 fortyGigE0/28 7 40000 +Ethernet32 13,14,15,16 fortyGigE0/32 8 40000 +Ethernet36 9,10,11,12 fortyGigE0/36 9 40000 +Ethernet40 17,18,19,20 fortyGigE0/40 10 40000 +Ethernet44 21,22,23,24 fortyGigE0/44 11 40000 +Ethernet48 53,54,55,56 fortyGigE0/48 12 40000 +Ethernet52 49,50,51,52 fortyGigE0/52 13 40000 +Ethernet56 57,58,59,60 fortyGigE0/56 14 40000 +Ethernet60 61,62,63,64 fortyGigE0/60 15 40000 +Ethernet64 69,70,71,72 fortyGigE0/64 16 40000 +Ethernet68 65,66,67,68 fortyGigE0/68 17 40000 +Ethernet72 73,74,75,76 fortyGigE0/72 18 40000 +Ethernet76 77,78,79,80 fortyGigE0/76 19 40000 +Ethernet80 109,110,111,112 fortyGigE0/80 20 40000 +Ethernet84 105,106,107,108 fortyGigE0/84 21 40000 +Ethernet88 113,114,115,116 fortyGigE0/88 22 40000 +Ethernet92 117,118,119,120 fortyGigE0/92 23 40000 +Ethernet96 125,126,127,128 fortyGigE0/96 24 40000 +Ethernet100 121,122,123,124 fortyGigE0/100 25 40000 +Ethernet104 81,82,83,84 fortyGigE0/104 26 40000 +Ethernet108 85,86,87,88 fortyGigE0/108 27 40000 +Ethernet112 93,94,95,96 fortyGigE0/112 28 40000 +Ethernet116 89,90,91,92 fortyGigE0/116 29 40000 +Ethernet120 101,102,103,104 fortyGigE0/120 30 40000 +Ethernet124 97,98,99,100 fortyGigE0/124 31 40000 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/qos.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile new file mode 100644 index 000000000000..bfc466f27e54 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile @@ -0,0 +1,5 @@ +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/td2-s6000-32x40G.config.bcm new file mode 100644 index 000000000000..4c94db7107c7 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/td2-s6000-32x40G.config.bcm @@ -0,0 +1,646 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000007fffffffffffffffffffffffffe +pbmp_xport_xe=0x000007fffffffffffffffffffffffffe + +# Ports configuration +# xe0 (40G) +portmap_1=25:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x2031 +phy_xaui_rx_polarity_flip_1=0xe +phy_xaui_tx_polarity_flip_1=0x2 +serdes_driver_current_lane0_xe0=0x5 +serdes_driver_current_lane1_xe0=0x5 +serdes_driver_current_lane2_xe0=0x5 +serdes_driver_current_lane3_xe0=0x5 +serdes_pre_driver_current_lane0_xe0=0x5 +serdes_pre_driver_current_lane1_xe0=0x5 +serdes_pre_driver_current_lane2_xe0=0x5 +serdes_pre_driver_current_lane3_xe0=0x5 +serdes_preemphasis_lane0_xe0=0xcad0 +serdes_preemphasis_lane1_xe0=0xc6e0 +serdes_preemphasis_lane2_xe0=0xc6e0 +serdes_preemphasis_lane3_xe0=0xd2b0 + +# xe1 (40G) +portmap_2=29:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x213 +phy_xaui_rx_polarity_flip_2=0xc +phy_xaui_tx_polarity_flip_2=0x9 +serdes_driver_current_lane0_xe1=0x6 +serdes_driver_current_lane1_xe1=0x7 +serdes_driver_current_lane2_xe1=0x6 +serdes_driver_current_lane3_xe1=0x6 +serdes_pre_driver_current_lane0_xe1=0x6 +serdes_pre_driver_current_lane1_xe1=0x7 +serdes_pre_driver_current_lane2_xe1=0x6 +serdes_pre_driver_current_lane3_xe1=0x6 +serdes_preemphasis_lane0_xe1=0xc2f0 +serdes_preemphasis_lane1_xe1=0xd2b0 +serdes_preemphasis_lane2_xe1=0xc6e0 +serdes_preemphasis_lane3_xe1=0xc2f0 + +# xe2 (40G) +portmap_3=33:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x132 +phy_xaui_rx_polarity_flip_3=0xe +phy_xaui_tx_polarity_flip_3=0x2 +serdes_driver_current_lane0_xe2=0x4 +serdes_driver_current_lane1_xe2=0x4 +serdes_driver_current_lane2_xe2=0x4 +serdes_driver_current_lane3_xe2=0x4 +serdes_pre_driver_current_lane0_xe2=0x4 +serdes_pre_driver_current_lane1_xe2=0x4 +serdes_pre_driver_current_lane2_xe2=0x4 +serdes_pre_driver_current_lane3_xe2=0x4 +serdes_preemphasis_lane0_xe2=0xc6e0 +serdes_preemphasis_lane1_xe2=0xc6e0 +serdes_preemphasis_lane2_xe2=0xc6e0 +serdes_preemphasis_lane3_xe2=0xc6e0 + +# xe3 (40G) +portmap_4=37:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x1203 +phy_xaui_rx_polarity_flip_4=0x3 +phy_xaui_tx_polarity_flip_4=0xe +serdes_driver_current_lane0_xe3=0x4 +serdes_driver_current_lane1_xe3=0x4 +serdes_driver_current_lane2_xe3=0x4 +serdes_driver_current_lane3_xe3=0x4 +serdes_pre_driver_current_lane0_xe3=0x4 +serdes_pre_driver_current_lane1_xe3=0x4 +serdes_pre_driver_current_lane2_xe3=0x4 +serdes_pre_driver_current_lane3_xe3=0x4 +serdes_preemphasis_lane0_xe3=0xcad0 +serdes_preemphasis_lane1_xe3=0xcad0 +serdes_preemphasis_lane2_xe3=0xc2f0 +serdes_preemphasis_lane3_xe3=0xc2f0 + +# xe4 (40G) +portmap_5=45:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x213 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x8 +serdes_driver_current_lane0_xe4=0x4 +serdes_driver_current_lane1_xe4=0x4 +serdes_driver_current_lane2_xe4=0x4 +serdes_driver_current_lane3_xe4=0x4 +serdes_pre_driver_current_lane0_xe4=0x4 +serdes_pre_driver_current_lane1_xe4=0x4 +serdes_pre_driver_current_lane2_xe4=0x4 +serdes_pre_driver_current_lane3_xe4=0x4 +serdes_preemphasis_lane0_xe4=0xc2f0 +serdes_preemphasis_lane1_xe4=0xc2f0 +serdes_preemphasis_lane2_xe4=0xc2f0 +serdes_preemphasis_lane3_xe4=0xc2f0 + +# xe5 (40G) +portmap_6=41:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x3021 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xb +serdes_driver_current_lane0_xe5=0x4 +serdes_driver_current_lane1_xe5=0x4 +serdes_driver_current_lane2_xe5=0x4 +serdes_driver_current_lane3_xe5=0x4 +serdes_pre_driver_current_lane0_xe5=0x4 +serdes_pre_driver_current_lane1_xe5=0x4 +serdes_pre_driver_current_lane2_xe5=0x4 +serdes_pre_driver_current_lane3_xe5=0x4 +serdes_preemphasis_lane0_xe5=0xc6e0 +serdes_preemphasis_lane1_xe5=0xc2f0 +serdes_preemphasis_lane2_xe5=0xc2f0 +serdes_preemphasis_lane3_xe5=0xcad0 + +# xe6 (40G) +portmap_7=1:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x2031 +phy_xaui_rx_polarity_flip_7=0xe +phy_xaui_tx_polarity_flip_7=0xd +serdes_driver_current_lane0_xe6=0x5 +serdes_driver_current_lane1_xe6=0x5 +serdes_driver_current_lane2_xe6=0x5 +serdes_driver_current_lane3_xe6=0x5 +serdes_pre_driver_current_lane0_xe6=0x5 +serdes_pre_driver_current_lane1_xe6=0x5 +serdes_pre_driver_current_lane2_xe6=0x5 +serdes_pre_driver_current_lane3_xe6=0x5 +serdes_preemphasis_lane0_xe6=0xc6e0 +serdes_preemphasis_lane1_xe6=0xcad0 +serdes_preemphasis_lane2_xe6=0xc6e0 +serdes_preemphasis_lane3_xe6=0xcad0 + +# xe7 (40G) +portmap_8=5:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x1203 +phy_xaui_rx_polarity_flip_8=0xc +phy_xaui_tx_polarity_flip_8=0x1 +serdes_driver_current_lane0_xe7=0x4 +serdes_driver_current_lane1_xe7=0x4 +serdes_driver_current_lane2_xe7=0x4 +serdes_driver_current_lane3_xe7=0x4 +serdes_pre_driver_current_lane0_xe7=0x4 +serdes_pre_driver_current_lane1_xe7=0x4 +serdes_pre_driver_current_lane2_xe7=0x4 +serdes_pre_driver_current_lane3_xe7=0x4 +serdes_preemphasis_lane0_xe7=0xc6e0 +serdes_preemphasis_lane1_xe7=0xc6e0 +serdes_preemphasis_lane2_xe7=0xc6e0 +serdes_preemphasis_lane3_xe7=0xc6e0 + +# xe8 (40G) +portmap_9=13:40 +xgxs_rx_lane_map_9=0x213 +xgxs_tx_lane_map_9=0x132 +phy_xaui_rx_polarity_flip_9=0xe +phy_xaui_tx_polarity_flip_9=0x0 +serdes_driver_current_lane0_xe8=0x2 +serdes_driver_current_lane1_xe8=0x3 +serdes_driver_current_lane2_xe8=0x2 +serdes_driver_current_lane3_xe8=0x2 +serdes_pre_driver_current_lane0_xe8=0x2 +serdes_pre_driver_current_lane1_xe8=0x3 +serdes_pre_driver_current_lane2_xe8=0x2 +serdes_pre_driver_current_lane3_xe8=0x2 +serdes_preemphasis_lane0_xe8=0xb270 +serdes_preemphasis_lane1_xe8=0xbb10 +serdes_preemphasis_lane2_xe8=0xb720 +serdes_preemphasis_lane3_xe8=0xb720 + +# xe9 (40G) +portmap_10=9:40 +xgxs_rx_lane_map_10=0x3120 +xgxs_tx_lane_map_10=0x3021 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x4 +serdes_driver_current_lane0_xe9=0x3 +serdes_driver_current_lane1_xe9=0x3 +serdes_driver_current_lane2_xe9=0x3 +serdes_driver_current_lane3_xe9=0x3 +serdes_pre_driver_current_lane0_xe9=0x3 +serdes_pre_driver_current_lane1_xe9=0x3 +serdes_pre_driver_current_lane2_xe9=0x3 +serdes_pre_driver_current_lane3_xe9=0x3 +serdes_preemphasis_lane0_xe9=0xc2f0 +serdes_preemphasis_lane1_xe9=0xc6e0 +serdes_preemphasis_lane2_xe9=0xbf00 +serdes_preemphasis_lane3_xe9=0xc2f0 + +# xe10 (40G) +portmap_11=17:40 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x132 +phy_xaui_rx_polarity_flip_11=0xe +phy_xaui_tx_polarity_flip_11=0x0 +serdes_driver_current_lane0_xe10=0x2 +serdes_driver_current_lane1_xe10=0x2 +serdes_driver_current_lane2_xe10=0x2 +serdes_driver_current_lane3_xe10=0x2 +serdes_pre_driver_current_lane0_xe10=0x2 +serdes_pre_driver_current_lane1_xe10=0x2 +serdes_pre_driver_current_lane2_xe10=0x2 +serdes_pre_driver_current_lane3_xe10=0x2 +serdes_preemphasis_lane0_xe10=0xb330 +serdes_preemphasis_lane1_xe10=0xbb10 +serdes_preemphasis_lane2_xe10=0xbb10 +serdes_preemphasis_lane3_xe10=0xbb10 + +# xe11 (40G) +portmap_12=21:40 +xgxs_rx_lane_map_12=0x123 +xgxs_tx_lane_map_12=0x1203 +phy_xaui_rx_polarity_flip_12=0xc +phy_xaui_tx_polarity_flip_12=0xe +serdes_driver_current_lane0_xe11=0x2 +serdes_driver_current_lane1_xe11=0x2 +serdes_driver_current_lane2_xe11=0x2 +serdes_driver_current_lane3_xe11=0x2 +serdes_pre_driver_current_lane0_xe11=0x2 +serdes_pre_driver_current_lane1_xe11=0x2 +serdes_pre_driver_current_lane2_xe11=0x2 +serdes_pre_driver_current_lane3_xe11=0x2 +serdes_preemphasis_lane0_xe11=0xb330 +serdes_preemphasis_lane1_xe11=0xb330 +serdes_preemphasis_lane2_xe11=0xb330 +serdes_preemphasis_lane3_xe11=0xb330 + +# xe12 (40G) +portmap_13=53:40 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x231 +phy_xaui_rx_polarity_flip_13=0x1 +phy_xaui_tx_polarity_flip_13=0x0 +serdes_driver_current_lane0_xe12=0x2 +serdes_driver_current_lane1_xe12=0x2 +serdes_driver_current_lane2_xe12=0x2 +serdes_driver_current_lane3_xe12=0x2 +serdes_pre_driver_current_lane0_xe12=0x2 +serdes_pre_driver_current_lane1_xe12=0x2 +serdes_pre_driver_current_lane2_xe12=0x2 +serdes_pre_driver_current_lane3_xe12=0x2 +serdes_preemphasis_lane0_xe12=0xaf40 +serdes_preemphasis_lane1_xe12=0xaf40 +serdes_preemphasis_lane2_xe12=0xaf40 +serdes_preemphasis_lane3_xe12=0xaf40 + +# xe13 (40G) +portmap_14=49:40 +xgxs_rx_lane_map_14=0x1302 +xgxs_tx_lane_map_14=0x2031 +phy_xaui_rx_polarity_flip_14=0xb +phy_xaui_tx_polarity_flip_14=0x3 +serdes_driver_current_lane0_xe13=0x2 +serdes_driver_current_lane1_xe13=0x2 +serdes_driver_current_lane2_xe13=0x2 +serdes_driver_current_lane3_xe13=0x2 +serdes_pre_driver_current_lane0_xe13=0x2 +serdes_pre_driver_current_lane1_xe13=0x2 +serdes_pre_driver_current_lane2_xe13=0x2 +serdes_pre_driver_current_lane3_xe13=0x2 +serdes_preemphasis_lane0_xe13=0xa760 +serdes_preemphasis_lane1_xe13=0xa760 +serdes_preemphasis_lane2_xe13=0xa760 +serdes_preemphasis_lane3_xe13=0xa760 + +# xe14 (40G) +portmap_15=57:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x2031 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_xe14=0x1 +serdes_driver_current_lane1_xe14=0x1 +serdes_driver_current_lane2_xe14=0x1 +serdes_driver_current_lane3_xe14=0x1 +serdes_pre_driver_current_lane0_xe14=0x1 +serdes_pre_driver_current_lane1_xe14=0x1 +serdes_pre_driver_current_lane2_xe14=0x1 +serdes_pre_driver_current_lane3_xe14=0x1 +serdes_preemphasis_lane0_xe14=0xa760 +serdes_preemphasis_lane1_xe14=0xa760 +serdes_preemphasis_lane2_xe14=0xa760 +serdes_preemphasis_lane3_xe14=0xa760 + +# xe15 (40G) +portmap_16=61:40 +xgxs_rx_lane_map_16=0x132 +xgxs_tx_lane_map_16=0x213 +phy_xaui_rx_polarity_flip_16=0x0 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_xe15=0x2 +serdes_driver_current_lane1_xe15=0x2 +serdes_driver_current_lane2_xe15=0x2 +serdes_driver_current_lane3_xe15=0x2 +serdes_pre_driver_current_lane0_xe15=0x2 +serdes_pre_driver_current_lane1_xe15=0x2 +serdes_pre_driver_current_lane2_xe15=0x2 +serdes_pre_driver_current_lane3_xe15=0x2 +serdes_preemphasis_lane0_xe15=0xa760 +serdes_preemphasis_lane1_xe15=0xa760 +serdes_preemphasis_lane2_xe15=0xa760 +serdes_preemphasis_lane3_xe15=0xa760 + +# xe16 (40G) +portmap_17=69:40 +xgxs_rx_lane_map_17=0x213 +xgxs_tx_lane_map_17=0x2130 +phy_xaui_rx_polarity_flip_17=0x1 +phy_xaui_tx_polarity_flip_17=0xf +serdes_driver_current_lane0_xe16=0x1 +serdes_driver_current_lane1_xe16=0x1 +serdes_driver_current_lane2_xe16=0x1 +serdes_driver_current_lane3_xe16=0x1 +serdes_pre_driver_current_lane0_xe16=0x1 +serdes_pre_driver_current_lane1_xe16=0x1 +serdes_pre_driver_current_lane2_xe16=0x1 +serdes_pre_driver_current_lane3_xe16=0x1 +serdes_preemphasis_lane0_xe16=0xa760 +serdes_preemphasis_lane1_xe16=0xa760 +serdes_preemphasis_lane2_xe16=0xa760 +serdes_preemphasis_lane3_xe16=0xa760 + +# xe17 (40G) +portmap_18=65:40 +xgxs_rx_lane_map_18=0x132 +xgxs_tx_lane_map_18=0x2031 +phy_xaui_rx_polarity_flip_18=0x3 +phy_xaui_tx_polarity_flip_18=0x9 +serdes_driver_current_lane0_xe17=0x1 +serdes_driver_current_lane1_xe17=0x1 +serdes_driver_current_lane2_xe17=0x1 +serdes_driver_current_lane3_xe17=0x1 +serdes_pre_driver_current_lane0_xe17=0x1 +serdes_pre_driver_current_lane1_xe17=0x1 +serdes_pre_driver_current_lane2_xe17=0x1 +serdes_pre_driver_current_lane3_xe17=0x1 +serdes_preemphasis_lane0_xe17=0xa370 +serdes_preemphasis_lane1_xe17=0xa370 +serdes_preemphasis_lane2_xe17=0xa370 +serdes_preemphasis_lane3_xe17=0xa370 + +# xe18 (40G) +portmap_19=73:40 +xgxs_rx_lane_map_19=0x213 +xgxs_tx_lane_map_19=0x2031 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_xe18=0x2 +serdes_driver_current_lane1_xe18=0x2 +serdes_driver_current_lane2_xe18=0x2 +serdes_driver_current_lane3_xe18=0x2 +serdes_pre_driver_current_lane0_xe18=0x2 +serdes_pre_driver_current_lane1_xe18=0x2 +serdes_pre_driver_current_lane2_xe18=0x2 +serdes_pre_driver_current_lane3_xe18=0x2 +serdes_preemphasis_lane0_xe18=0xa760 +serdes_preemphasis_lane1_xe18=0xa760 +serdes_preemphasis_lane2_xe18=0xa760 +serdes_preemphasis_lane3_xe18=0xa760 + +# xe19 (40G) +portmap_20=77:40 +xgxs_rx_lane_map_20=0x123 +xgxs_tx_lane_map_20=0x1203 +phy_xaui_rx_polarity_flip_20=0x3 +phy_xaui_tx_polarity_flip_20=0xe +serdes_driver_current_lane0_xe19=0x2 +serdes_driver_current_lane1_xe19=0x2 +serdes_driver_current_lane2_xe19=0x2 +serdes_driver_current_lane3_xe19=0x2 +serdes_pre_driver_current_lane0_xe19=0x2 +serdes_pre_driver_current_lane1_xe19=0x2 +serdes_pre_driver_current_lane2_xe19=0x2 +serdes_pre_driver_current_lane3_xe19=0x2 +serdes_preemphasis_lane0_xe19=0xaf40 +serdes_preemphasis_lane1_xe19=0xaf40 +serdes_preemphasis_lane2_xe19=0xaf40 +serdes_preemphasis_lane3_xe19=0xaf40 + +# xe20 (40G) +portmap_21=109:40 +xgxs_rx_lane_map_21=0x132 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0x8 +phy_xaui_tx_polarity_flip_21=0x0 +serdes_driver_current_lane0_xe20=0x1 +serdes_driver_current_lane1_xe20=0x1 +serdes_driver_current_lane2_xe20=0x1 +serdes_driver_current_lane3_xe20=0x2 +serdes_pre_driver_current_lane0_xe20=0x1 +serdes_pre_driver_current_lane1_xe20=0x1 +serdes_pre_driver_current_lane2_xe20=0x1 +serdes_pre_driver_current_lane3_xe20=0x2 +serdes_preemphasis_lane0_xe20=0xb330 +serdes_preemphasis_lane1_xe20=0xb330 +serdes_preemphasis_lane2_xe20=0xb330 +serdes_preemphasis_lane3_xe20=0xbff0 + +# xe21 (40G) +portmap_22=105:40 +xgxs_rx_lane_map_22=0x1320 +xgxs_tx_lane_map_22=0x3021 +phy_xaui_rx_polarity_flip_22=0xd +phy_xaui_tx_polarity_flip_22=0xb +serdes_driver_current_lane0_xe21=0x1 +serdes_driver_current_lane1_xe21=0x1 +serdes_driver_current_lane2_xe21=0x1 +serdes_driver_current_lane3_xe21=0x1 +serdes_pre_driver_current_lane0_xe21=0x1 +serdes_pre_driver_current_lane1_xe21=0x1 +serdes_pre_driver_current_lane2_xe21=0x1 +serdes_pre_driver_current_lane3_xe21=0x1 +serdes_preemphasis_lane0_xe21=0xb330 +serdes_preemphasis_lane1_xe21=0xb330 +serdes_preemphasis_lane2_xe21=0xb330 +serdes_preemphasis_lane3_xe21=0xb330 + +# xe22 (40G) +portmap_23=113:40 +xgxs_rx_lane_map_23=0x132 +xgxs_tx_lane_map_23=0x132 +phy_xaui_rx_polarity_flip_23=0x8 +phy_xaui_tx_polarity_flip_23=0x0 +serdes_driver_current_lane0_xe22=0x1 +serdes_driver_current_lane1_xe22=0x1 +serdes_driver_current_lane2_xe22=0x1 +serdes_driver_current_lane3_xe22=0x1 +serdes_pre_driver_current_lane0_xe22=0x1 +serdes_pre_driver_current_lane1_xe22=0x1 +serdes_pre_driver_current_lane2_xe22=0x1 +serdes_pre_driver_current_lane3_xe22=0x1 +serdes_preemphasis_lane0_xe22=0xbb10 +serdes_preemphasis_lane1_xe22=0xbb10 +serdes_preemphasis_lane2_xe22=0xbb10 +serdes_preemphasis_lane3_xe22=0xc2f0 + +# xe23 (40G) +portmap_24=117:40 +xgxs_rx_lane_map_24=0x231 +xgxs_tx_lane_map_24=0x1203 +phy_xaui_rx_polarity_flip_24=0x3 +phy_xaui_tx_polarity_flip_24=0xe +serdes_driver_current_lane0_xe23=0x3 +serdes_driver_current_lane1_xe23=0x5 +serdes_driver_current_lane2_xe23=0x3 +serdes_driver_current_lane3_xe23=0x3 +serdes_pre_driver_current_lane0_xe23=0x3 +serdes_pre_driver_current_lane1_xe23=0x5 +serdes_pre_driver_current_lane2_xe23=0x3 +serdes_pre_driver_current_lane3_xe23=0x3 +serdes_preemphasis_lane0_xe23=0xc6e0 +serdes_preemphasis_lane1_xe23=0xc6e0 +serdes_preemphasis_lane2_xe23=0xc6e0 +serdes_preemphasis_lane3_xe23=0xc6e0 + +# xe24 (40G) +portmap_25=125:40 +xgxs_rx_lane_map_25=0x132 +xgxs_tx_lane_map_25=0x132 +phy_xaui_rx_polarity_flip_25=0x8 +phy_xaui_tx_polarity_flip_25=0x0 +serdes_driver_current_lane0_xe24=0x4 +serdes_driver_current_lane1_xe24=0x4 +serdes_driver_current_lane2_xe24=0x4 +serdes_driver_current_lane3_xe24=0x4 +serdes_pre_driver_current_lane0_xe24=0x4 +serdes_pre_driver_current_lane1_xe24=0x4 +serdes_pre_driver_current_lane2_xe24=0x4 +serdes_pre_driver_current_lane3_xe24=0x4 +serdes_preemphasis_lane0_xe24=0xc6e0 +serdes_preemphasis_lane1_xe24=0xc6e0 +serdes_preemphasis_lane2_xe24=0xc6e0 +serdes_preemphasis_lane3_xe24=0xcec0 + +# xe25 (40G) +portmap_26=121:40 +xgxs_rx_lane_map_26=0x1320 +xgxs_tx_lane_map_26=0x3021 +phy_xaui_rx_polarity_flip_26=0xd +phy_xaui_tx_polarity_flip_26=0xb +serdes_driver_current_lane0_xe25=0x4 +serdes_driver_current_lane1_xe25=0x4 +serdes_driver_current_lane2_xe25=0x4 +serdes_driver_current_lane3_xe25=0x4 +serdes_pre_driver_current_lane0_xe25=0x4 +serdes_pre_driver_current_lane1_xe25=0x4 +serdes_pre_driver_current_lane2_xe25=0x4 +serdes_pre_driver_current_lane3_xe25=0x4 +serdes_preemphasis_lane0_xe25=0xc6e0 +serdes_preemphasis_lane1_xe25=0xc6e0 +serdes_preemphasis_lane2_xe25=0xc6e0 +serdes_preemphasis_lane3_xe25=0xc6e0 + +# xe26 (40G) +portmap_27=81:40 +xgxs_rx_lane_map_27=0x1320 +xgxs_tx_lane_map_27=0x2031 +phy_xaui_rx_polarity_flip_27=0x1 +phy_xaui_tx_polarity_flip_27=0x2 +serdes_driver_current_lane0_xe26=0x2 +serdes_driver_current_lane1_xe26=0x2 +serdes_driver_current_lane2_xe26=0x2 +serdes_driver_current_lane3_xe26=0x2 +serdes_pre_driver_current_lane0_xe26=0x2 +serdes_pre_driver_current_lane1_xe26=0x2 +serdes_pre_driver_current_lane2_xe26=0x2 +serdes_pre_driver_current_lane3_xe26=0x2 +serdes_preemphasis_lane0_xe26=0xbb10 +serdes_preemphasis_lane1_xe26=0xbb10 +serdes_preemphasis_lane2_xe26=0xbf00 +serdes_preemphasis_lane3_xe26=0xbb10 + +# xe27 (40G) +portmap_28=85:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x1203 +phy_xaui_rx_polarity_flip_28=0xc +phy_xaui_tx_polarity_flip_28=0xe +serdes_driver_current_lane0_xe27=0x4 +serdes_driver_current_lane1_xe27=0x5 +serdes_driver_current_lane2_xe27=0x4 +serdes_driver_current_lane3_xe27=0x5 +serdes_pre_driver_current_lane0_xe27=0x4 +serdes_pre_driver_current_lane1_xe27=0x5 +serdes_pre_driver_current_lane2_xe27=0x4 +serdes_pre_driver_current_lane3_xe27=0x5 +serdes_preemphasis_lane0_xe27=0xc2f0 +serdes_preemphasis_lane1_xe27=0xc6e0 +serdes_preemphasis_lane2_xe27=0xc6e0 +serdes_preemphasis_lane3_xe27=0xc6e0 + +# xe28 (40G) +portmap_29=93:40 +xgxs_rx_lane_map_29=0x1320 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x2 +serdes_driver_current_lane0_xe28=0x4 +serdes_driver_current_lane1_xe28=0x4 +serdes_driver_current_lane2_xe28=0x4 +serdes_driver_current_lane3_xe28=0x4 +serdes_pre_driver_current_lane0_xe28=0x4 +serdes_pre_driver_current_lane1_xe28=0x4 +serdes_pre_driver_current_lane2_xe28=0x4 +serdes_pre_driver_current_lane3_xe28=0x4 +serdes_preemphasis_lane0_xe28=0xc2f0 +serdes_preemphasis_lane1_xe28=0xc2f0 +serdes_preemphasis_lane2_xe28=0xc2f0 +serdes_preemphasis_lane3_xe28=0xc2f0 + +# xe29 (40G) +portmap_30=89:40 +xgxs_rx_lane_map_30=0x1320 +xgxs_tx_lane_map_30=0x3021 +phy_xaui_rx_polarity_flip_30=0x2 +phy_xaui_tx_polarity_flip_30=0xb +serdes_driver_current_lane0_xe29=0x4 +serdes_driver_current_lane1_xe29=0x4 +serdes_driver_current_lane2_xe29=0x4 +serdes_driver_current_lane3_xe29=0x4 +serdes_pre_driver_current_lane0_xe29=0x4 +serdes_pre_driver_current_lane1_xe29=0x4 +serdes_pre_driver_current_lane2_xe29=0x4 +serdes_pre_driver_current_lane3_xe29=0x4 +serdes_preemphasis_lane0_xe29=0xcad0 +serdes_preemphasis_lane1_xe29=0xc6e0 +serdes_preemphasis_lane2_xe29=0xc6e0 +serdes_preemphasis_lane3_xe29=0xc6e0 + +# xe30 (40G) +portmap_31=101:40 +xgxs_rx_lane_map_31=0x1320 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x1 +phy_xaui_tx_polarity_flip_31=0x6 +serdes_driver_current_lane0_xe30=0x6 +serdes_driver_current_lane1_xe30=0x6 +serdes_driver_current_lane2_xe30=0x6 +serdes_driver_current_lane3_xe30=0x7 +serdes_pre_driver_current_lane0_xe30=0x6 +serdes_pre_driver_current_lane1_xe30=0x6 +serdes_pre_driver_current_lane2_xe30=0x6 +serdes_pre_driver_current_lane3_xe30=0x7 +serdes_preemphasis_lane0_xe30=0xcec0 +serdes_preemphasis_lane1_xe30=0xcec0 +serdes_preemphasis_lane2_xe30=0xcad0 +serdes_preemphasis_lane3_xe30=0xc6e0 + +# xe31 (40G) +portmap_32=97:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0xc +phy_xaui_tx_polarity_flip_32=0x3 +serdes_driver_current_lane0_xe31=0x5 +serdes_driver_current_lane1_xe31=0x5 +serdes_driver_current_lane2_xe31=0x5 +serdes_driver_current_lane3_xe31=0x5 +serdes_pre_driver_current_lane0_xe31=0x5 +serdes_pre_driver_current_lane1_xe31=0x5 +serdes_pre_driver_current_lane2_xe31=0x5 +serdes_pre_driver_current_lane3_xe31=0x5 +serdes_preemphasis_lane0_xe31=0xcad0 +serdes_preemphasis_lane1_xe31=0xcad0 +serdes_preemphasis_lane2_xe31=0xcad0 +serdes_preemphasis_lane3_xe31=0xcad0 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers.json.j2 new file mode 100644 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_def.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_def.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_def.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t0.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t1.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/pg_profile_lookup.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/port_config.ini new file mode 100644 index 000000000000..95cf5eec9e4e --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 25,26,27,28 fortyGigE0/0 0 40000 +Ethernet4 29,30,31,32 fortyGigE0/4 1 40000 +Ethernet8 33,34,35,36 fortyGigE0/8 2 40000 +Ethernet12 37,38,39,40 fortyGigE0/12 3 40000 +Ethernet16 45,46,47,48 fortyGigE0/16 4 40000 +Ethernet20 41,42,43,44 fortyGigE0/20 5 40000 +Ethernet24 1,2,3,4 fortyGigE0/24 6 40000 +Ethernet28 5,6,7,8 fortyGigE0/28 7 40000 +Ethernet32 13,14,15,16 fortyGigE0/32 8 40000 +Ethernet36 9,10,11,12 fortyGigE0/36 9 40000 +Ethernet40 17,18,19,20 fortyGigE0/40 10 40000 +Ethernet44 21,22,23,24 fortyGigE0/44 11 40000 +Ethernet48 53,54,55,56 fortyGigE0/48 12 40000 +Ethernet52 49,50,51,52 fortyGigE0/52 13 40000 +Ethernet56 57,58,59,60 fortyGigE0/56 14 40000 +Ethernet60 61,62,63,64 fortyGigE0/60 15 40000 +Ethernet64 69,70,71,72 fortyGigE0/64 16 40000 +Ethernet68 65,66,67,68 fortyGigE0/68 17 40000 +Ethernet72 73,74,75,76 fortyGigE0/72 18 40000 +Ethernet76 77,78,79,80 fortyGigE0/76 19 40000 +Ethernet80 109,110,111,112 fortyGigE0/80 20 40000 +Ethernet84 105,106,107,108 fortyGigE0/84 21 40000 +Ethernet88 113,114,115,116 fortyGigE0/88 22 40000 +Ethernet92 117,118,119,120 fortyGigE0/92 23 40000 +Ethernet96 125,126,127,128 fortyGigE0/96 24 40000 +Ethernet100 121,122,123,124 fortyGigE0/100 25 40000 +Ethernet104 81,82,83,84 fortyGigE0/104 26 40000 +Ethernet108 85,86,87,88 fortyGigE0/108 27 40000 +Ethernet112 93,94,95,96 fortyGigE0/112 28 40000 +Ethernet116 89,90,91,92 fortyGigE0/116 29 40000 +Ethernet120 101,102,103,104 fortyGigE0/120 30 40000 +Ethernet124 97,98,99,100 fortyGigE0/124 31 40000 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/qos.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile new file mode 100644 index 000000000000..bfc466f27e54 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile @@ -0,0 +1,5 @@ +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/td2-s6000-32x40G.config.bcm new file mode 100644 index 000000000000..4c94db7107c7 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/td2-s6000-32x40G.config.bcm @@ -0,0 +1,646 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000007fffffffffffffffffffffffffe +pbmp_xport_xe=0x000007fffffffffffffffffffffffffe + +# Ports configuration +# xe0 (40G) +portmap_1=25:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x2031 +phy_xaui_rx_polarity_flip_1=0xe +phy_xaui_tx_polarity_flip_1=0x2 +serdes_driver_current_lane0_xe0=0x5 +serdes_driver_current_lane1_xe0=0x5 +serdes_driver_current_lane2_xe0=0x5 +serdes_driver_current_lane3_xe0=0x5 +serdes_pre_driver_current_lane0_xe0=0x5 +serdes_pre_driver_current_lane1_xe0=0x5 +serdes_pre_driver_current_lane2_xe0=0x5 +serdes_pre_driver_current_lane3_xe0=0x5 +serdes_preemphasis_lane0_xe0=0xcad0 +serdes_preemphasis_lane1_xe0=0xc6e0 +serdes_preemphasis_lane2_xe0=0xc6e0 +serdes_preemphasis_lane3_xe0=0xd2b0 + +# xe1 (40G) +portmap_2=29:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x213 +phy_xaui_rx_polarity_flip_2=0xc +phy_xaui_tx_polarity_flip_2=0x9 +serdes_driver_current_lane0_xe1=0x6 +serdes_driver_current_lane1_xe1=0x7 +serdes_driver_current_lane2_xe1=0x6 +serdes_driver_current_lane3_xe1=0x6 +serdes_pre_driver_current_lane0_xe1=0x6 +serdes_pre_driver_current_lane1_xe1=0x7 +serdes_pre_driver_current_lane2_xe1=0x6 +serdes_pre_driver_current_lane3_xe1=0x6 +serdes_preemphasis_lane0_xe1=0xc2f0 +serdes_preemphasis_lane1_xe1=0xd2b0 +serdes_preemphasis_lane2_xe1=0xc6e0 +serdes_preemphasis_lane3_xe1=0xc2f0 + +# xe2 (40G) +portmap_3=33:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x132 +phy_xaui_rx_polarity_flip_3=0xe +phy_xaui_tx_polarity_flip_3=0x2 +serdes_driver_current_lane0_xe2=0x4 +serdes_driver_current_lane1_xe2=0x4 +serdes_driver_current_lane2_xe2=0x4 +serdes_driver_current_lane3_xe2=0x4 +serdes_pre_driver_current_lane0_xe2=0x4 +serdes_pre_driver_current_lane1_xe2=0x4 +serdes_pre_driver_current_lane2_xe2=0x4 +serdes_pre_driver_current_lane3_xe2=0x4 +serdes_preemphasis_lane0_xe2=0xc6e0 +serdes_preemphasis_lane1_xe2=0xc6e0 +serdes_preemphasis_lane2_xe2=0xc6e0 +serdes_preemphasis_lane3_xe2=0xc6e0 + +# xe3 (40G) +portmap_4=37:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x1203 +phy_xaui_rx_polarity_flip_4=0x3 +phy_xaui_tx_polarity_flip_4=0xe +serdes_driver_current_lane0_xe3=0x4 +serdes_driver_current_lane1_xe3=0x4 +serdes_driver_current_lane2_xe3=0x4 +serdes_driver_current_lane3_xe3=0x4 +serdes_pre_driver_current_lane0_xe3=0x4 +serdes_pre_driver_current_lane1_xe3=0x4 +serdes_pre_driver_current_lane2_xe3=0x4 +serdes_pre_driver_current_lane3_xe3=0x4 +serdes_preemphasis_lane0_xe3=0xcad0 +serdes_preemphasis_lane1_xe3=0xcad0 +serdes_preemphasis_lane2_xe3=0xc2f0 +serdes_preemphasis_lane3_xe3=0xc2f0 + +# xe4 (40G) +portmap_5=45:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x213 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x8 +serdes_driver_current_lane0_xe4=0x4 +serdes_driver_current_lane1_xe4=0x4 +serdes_driver_current_lane2_xe4=0x4 +serdes_driver_current_lane3_xe4=0x4 +serdes_pre_driver_current_lane0_xe4=0x4 +serdes_pre_driver_current_lane1_xe4=0x4 +serdes_pre_driver_current_lane2_xe4=0x4 +serdes_pre_driver_current_lane3_xe4=0x4 +serdes_preemphasis_lane0_xe4=0xc2f0 +serdes_preemphasis_lane1_xe4=0xc2f0 +serdes_preemphasis_lane2_xe4=0xc2f0 +serdes_preemphasis_lane3_xe4=0xc2f0 + +# xe5 (40G) +portmap_6=41:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x3021 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xb +serdes_driver_current_lane0_xe5=0x4 +serdes_driver_current_lane1_xe5=0x4 +serdes_driver_current_lane2_xe5=0x4 +serdes_driver_current_lane3_xe5=0x4 +serdes_pre_driver_current_lane0_xe5=0x4 +serdes_pre_driver_current_lane1_xe5=0x4 +serdes_pre_driver_current_lane2_xe5=0x4 +serdes_pre_driver_current_lane3_xe5=0x4 +serdes_preemphasis_lane0_xe5=0xc6e0 +serdes_preemphasis_lane1_xe5=0xc2f0 +serdes_preemphasis_lane2_xe5=0xc2f0 +serdes_preemphasis_lane3_xe5=0xcad0 + +# xe6 (40G) +portmap_7=1:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x2031 +phy_xaui_rx_polarity_flip_7=0xe +phy_xaui_tx_polarity_flip_7=0xd +serdes_driver_current_lane0_xe6=0x5 +serdes_driver_current_lane1_xe6=0x5 +serdes_driver_current_lane2_xe6=0x5 +serdes_driver_current_lane3_xe6=0x5 +serdes_pre_driver_current_lane0_xe6=0x5 +serdes_pre_driver_current_lane1_xe6=0x5 +serdes_pre_driver_current_lane2_xe6=0x5 +serdes_pre_driver_current_lane3_xe6=0x5 +serdes_preemphasis_lane0_xe6=0xc6e0 +serdes_preemphasis_lane1_xe6=0xcad0 +serdes_preemphasis_lane2_xe6=0xc6e0 +serdes_preemphasis_lane3_xe6=0xcad0 + +# xe7 (40G) +portmap_8=5:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x1203 +phy_xaui_rx_polarity_flip_8=0xc +phy_xaui_tx_polarity_flip_8=0x1 +serdes_driver_current_lane0_xe7=0x4 +serdes_driver_current_lane1_xe7=0x4 +serdes_driver_current_lane2_xe7=0x4 +serdes_driver_current_lane3_xe7=0x4 +serdes_pre_driver_current_lane0_xe7=0x4 +serdes_pre_driver_current_lane1_xe7=0x4 +serdes_pre_driver_current_lane2_xe7=0x4 +serdes_pre_driver_current_lane3_xe7=0x4 +serdes_preemphasis_lane0_xe7=0xc6e0 +serdes_preemphasis_lane1_xe7=0xc6e0 +serdes_preemphasis_lane2_xe7=0xc6e0 +serdes_preemphasis_lane3_xe7=0xc6e0 + +# xe8 (40G) +portmap_9=13:40 +xgxs_rx_lane_map_9=0x213 +xgxs_tx_lane_map_9=0x132 +phy_xaui_rx_polarity_flip_9=0xe +phy_xaui_tx_polarity_flip_9=0x0 +serdes_driver_current_lane0_xe8=0x2 +serdes_driver_current_lane1_xe8=0x3 +serdes_driver_current_lane2_xe8=0x2 +serdes_driver_current_lane3_xe8=0x2 +serdes_pre_driver_current_lane0_xe8=0x2 +serdes_pre_driver_current_lane1_xe8=0x3 +serdes_pre_driver_current_lane2_xe8=0x2 +serdes_pre_driver_current_lane3_xe8=0x2 +serdes_preemphasis_lane0_xe8=0xb270 +serdes_preemphasis_lane1_xe8=0xbb10 +serdes_preemphasis_lane2_xe8=0xb720 +serdes_preemphasis_lane3_xe8=0xb720 + +# xe9 (40G) +portmap_10=9:40 +xgxs_rx_lane_map_10=0x3120 +xgxs_tx_lane_map_10=0x3021 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x4 +serdes_driver_current_lane0_xe9=0x3 +serdes_driver_current_lane1_xe9=0x3 +serdes_driver_current_lane2_xe9=0x3 +serdes_driver_current_lane3_xe9=0x3 +serdes_pre_driver_current_lane0_xe9=0x3 +serdes_pre_driver_current_lane1_xe9=0x3 +serdes_pre_driver_current_lane2_xe9=0x3 +serdes_pre_driver_current_lane3_xe9=0x3 +serdes_preemphasis_lane0_xe9=0xc2f0 +serdes_preemphasis_lane1_xe9=0xc6e0 +serdes_preemphasis_lane2_xe9=0xbf00 +serdes_preemphasis_lane3_xe9=0xc2f0 + +# xe10 (40G) +portmap_11=17:40 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x132 +phy_xaui_rx_polarity_flip_11=0xe +phy_xaui_tx_polarity_flip_11=0x0 +serdes_driver_current_lane0_xe10=0x2 +serdes_driver_current_lane1_xe10=0x2 +serdes_driver_current_lane2_xe10=0x2 +serdes_driver_current_lane3_xe10=0x2 +serdes_pre_driver_current_lane0_xe10=0x2 +serdes_pre_driver_current_lane1_xe10=0x2 +serdes_pre_driver_current_lane2_xe10=0x2 +serdes_pre_driver_current_lane3_xe10=0x2 +serdes_preemphasis_lane0_xe10=0xb330 +serdes_preemphasis_lane1_xe10=0xbb10 +serdes_preemphasis_lane2_xe10=0xbb10 +serdes_preemphasis_lane3_xe10=0xbb10 + +# xe11 (40G) +portmap_12=21:40 +xgxs_rx_lane_map_12=0x123 +xgxs_tx_lane_map_12=0x1203 +phy_xaui_rx_polarity_flip_12=0xc +phy_xaui_tx_polarity_flip_12=0xe +serdes_driver_current_lane0_xe11=0x2 +serdes_driver_current_lane1_xe11=0x2 +serdes_driver_current_lane2_xe11=0x2 +serdes_driver_current_lane3_xe11=0x2 +serdes_pre_driver_current_lane0_xe11=0x2 +serdes_pre_driver_current_lane1_xe11=0x2 +serdes_pre_driver_current_lane2_xe11=0x2 +serdes_pre_driver_current_lane3_xe11=0x2 +serdes_preemphasis_lane0_xe11=0xb330 +serdes_preemphasis_lane1_xe11=0xb330 +serdes_preemphasis_lane2_xe11=0xb330 +serdes_preemphasis_lane3_xe11=0xb330 + +# xe12 (40G) +portmap_13=53:40 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x231 +phy_xaui_rx_polarity_flip_13=0x1 +phy_xaui_tx_polarity_flip_13=0x0 +serdes_driver_current_lane0_xe12=0x2 +serdes_driver_current_lane1_xe12=0x2 +serdes_driver_current_lane2_xe12=0x2 +serdes_driver_current_lane3_xe12=0x2 +serdes_pre_driver_current_lane0_xe12=0x2 +serdes_pre_driver_current_lane1_xe12=0x2 +serdes_pre_driver_current_lane2_xe12=0x2 +serdes_pre_driver_current_lane3_xe12=0x2 +serdes_preemphasis_lane0_xe12=0xaf40 +serdes_preemphasis_lane1_xe12=0xaf40 +serdes_preemphasis_lane2_xe12=0xaf40 +serdes_preemphasis_lane3_xe12=0xaf40 + +# xe13 (40G) +portmap_14=49:40 +xgxs_rx_lane_map_14=0x1302 +xgxs_tx_lane_map_14=0x2031 +phy_xaui_rx_polarity_flip_14=0xb +phy_xaui_tx_polarity_flip_14=0x3 +serdes_driver_current_lane0_xe13=0x2 +serdes_driver_current_lane1_xe13=0x2 +serdes_driver_current_lane2_xe13=0x2 +serdes_driver_current_lane3_xe13=0x2 +serdes_pre_driver_current_lane0_xe13=0x2 +serdes_pre_driver_current_lane1_xe13=0x2 +serdes_pre_driver_current_lane2_xe13=0x2 +serdes_pre_driver_current_lane3_xe13=0x2 +serdes_preemphasis_lane0_xe13=0xa760 +serdes_preemphasis_lane1_xe13=0xa760 +serdes_preemphasis_lane2_xe13=0xa760 +serdes_preemphasis_lane3_xe13=0xa760 + +# xe14 (40G) +portmap_15=57:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x2031 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_xe14=0x1 +serdes_driver_current_lane1_xe14=0x1 +serdes_driver_current_lane2_xe14=0x1 +serdes_driver_current_lane3_xe14=0x1 +serdes_pre_driver_current_lane0_xe14=0x1 +serdes_pre_driver_current_lane1_xe14=0x1 +serdes_pre_driver_current_lane2_xe14=0x1 +serdes_pre_driver_current_lane3_xe14=0x1 +serdes_preemphasis_lane0_xe14=0xa760 +serdes_preemphasis_lane1_xe14=0xa760 +serdes_preemphasis_lane2_xe14=0xa760 +serdes_preemphasis_lane3_xe14=0xa760 + +# xe15 (40G) +portmap_16=61:40 +xgxs_rx_lane_map_16=0x132 +xgxs_tx_lane_map_16=0x213 +phy_xaui_rx_polarity_flip_16=0x0 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_xe15=0x2 +serdes_driver_current_lane1_xe15=0x2 +serdes_driver_current_lane2_xe15=0x2 +serdes_driver_current_lane3_xe15=0x2 +serdes_pre_driver_current_lane0_xe15=0x2 +serdes_pre_driver_current_lane1_xe15=0x2 +serdes_pre_driver_current_lane2_xe15=0x2 +serdes_pre_driver_current_lane3_xe15=0x2 +serdes_preemphasis_lane0_xe15=0xa760 +serdes_preemphasis_lane1_xe15=0xa760 +serdes_preemphasis_lane2_xe15=0xa760 +serdes_preemphasis_lane3_xe15=0xa760 + +# xe16 (40G) +portmap_17=69:40 +xgxs_rx_lane_map_17=0x213 +xgxs_tx_lane_map_17=0x2130 +phy_xaui_rx_polarity_flip_17=0x1 +phy_xaui_tx_polarity_flip_17=0xf +serdes_driver_current_lane0_xe16=0x1 +serdes_driver_current_lane1_xe16=0x1 +serdes_driver_current_lane2_xe16=0x1 +serdes_driver_current_lane3_xe16=0x1 +serdes_pre_driver_current_lane0_xe16=0x1 +serdes_pre_driver_current_lane1_xe16=0x1 +serdes_pre_driver_current_lane2_xe16=0x1 +serdes_pre_driver_current_lane3_xe16=0x1 +serdes_preemphasis_lane0_xe16=0xa760 +serdes_preemphasis_lane1_xe16=0xa760 +serdes_preemphasis_lane2_xe16=0xa760 +serdes_preemphasis_lane3_xe16=0xa760 + +# xe17 (40G) +portmap_18=65:40 +xgxs_rx_lane_map_18=0x132 +xgxs_tx_lane_map_18=0x2031 +phy_xaui_rx_polarity_flip_18=0x3 +phy_xaui_tx_polarity_flip_18=0x9 +serdes_driver_current_lane0_xe17=0x1 +serdes_driver_current_lane1_xe17=0x1 +serdes_driver_current_lane2_xe17=0x1 +serdes_driver_current_lane3_xe17=0x1 +serdes_pre_driver_current_lane0_xe17=0x1 +serdes_pre_driver_current_lane1_xe17=0x1 +serdes_pre_driver_current_lane2_xe17=0x1 +serdes_pre_driver_current_lane3_xe17=0x1 +serdes_preemphasis_lane0_xe17=0xa370 +serdes_preemphasis_lane1_xe17=0xa370 +serdes_preemphasis_lane2_xe17=0xa370 +serdes_preemphasis_lane3_xe17=0xa370 + +# xe18 (40G) +portmap_19=73:40 +xgxs_rx_lane_map_19=0x213 +xgxs_tx_lane_map_19=0x2031 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_xe18=0x2 +serdes_driver_current_lane1_xe18=0x2 +serdes_driver_current_lane2_xe18=0x2 +serdes_driver_current_lane3_xe18=0x2 +serdes_pre_driver_current_lane0_xe18=0x2 +serdes_pre_driver_current_lane1_xe18=0x2 +serdes_pre_driver_current_lane2_xe18=0x2 +serdes_pre_driver_current_lane3_xe18=0x2 +serdes_preemphasis_lane0_xe18=0xa760 +serdes_preemphasis_lane1_xe18=0xa760 +serdes_preemphasis_lane2_xe18=0xa760 +serdes_preemphasis_lane3_xe18=0xa760 + +# xe19 (40G) +portmap_20=77:40 +xgxs_rx_lane_map_20=0x123 +xgxs_tx_lane_map_20=0x1203 +phy_xaui_rx_polarity_flip_20=0x3 +phy_xaui_tx_polarity_flip_20=0xe +serdes_driver_current_lane0_xe19=0x2 +serdes_driver_current_lane1_xe19=0x2 +serdes_driver_current_lane2_xe19=0x2 +serdes_driver_current_lane3_xe19=0x2 +serdes_pre_driver_current_lane0_xe19=0x2 +serdes_pre_driver_current_lane1_xe19=0x2 +serdes_pre_driver_current_lane2_xe19=0x2 +serdes_pre_driver_current_lane3_xe19=0x2 +serdes_preemphasis_lane0_xe19=0xaf40 +serdes_preemphasis_lane1_xe19=0xaf40 +serdes_preemphasis_lane2_xe19=0xaf40 +serdes_preemphasis_lane3_xe19=0xaf40 + +# xe20 (40G) +portmap_21=109:40 +xgxs_rx_lane_map_21=0x132 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0x8 +phy_xaui_tx_polarity_flip_21=0x0 +serdes_driver_current_lane0_xe20=0x1 +serdes_driver_current_lane1_xe20=0x1 +serdes_driver_current_lane2_xe20=0x1 +serdes_driver_current_lane3_xe20=0x2 +serdes_pre_driver_current_lane0_xe20=0x1 +serdes_pre_driver_current_lane1_xe20=0x1 +serdes_pre_driver_current_lane2_xe20=0x1 +serdes_pre_driver_current_lane3_xe20=0x2 +serdes_preemphasis_lane0_xe20=0xb330 +serdes_preemphasis_lane1_xe20=0xb330 +serdes_preemphasis_lane2_xe20=0xb330 +serdes_preemphasis_lane3_xe20=0xbff0 + +# xe21 (40G) +portmap_22=105:40 +xgxs_rx_lane_map_22=0x1320 +xgxs_tx_lane_map_22=0x3021 +phy_xaui_rx_polarity_flip_22=0xd +phy_xaui_tx_polarity_flip_22=0xb +serdes_driver_current_lane0_xe21=0x1 +serdes_driver_current_lane1_xe21=0x1 +serdes_driver_current_lane2_xe21=0x1 +serdes_driver_current_lane3_xe21=0x1 +serdes_pre_driver_current_lane0_xe21=0x1 +serdes_pre_driver_current_lane1_xe21=0x1 +serdes_pre_driver_current_lane2_xe21=0x1 +serdes_pre_driver_current_lane3_xe21=0x1 +serdes_preemphasis_lane0_xe21=0xb330 +serdes_preemphasis_lane1_xe21=0xb330 +serdes_preemphasis_lane2_xe21=0xb330 +serdes_preemphasis_lane3_xe21=0xb330 + +# xe22 (40G) +portmap_23=113:40 +xgxs_rx_lane_map_23=0x132 +xgxs_tx_lane_map_23=0x132 +phy_xaui_rx_polarity_flip_23=0x8 +phy_xaui_tx_polarity_flip_23=0x0 +serdes_driver_current_lane0_xe22=0x1 +serdes_driver_current_lane1_xe22=0x1 +serdes_driver_current_lane2_xe22=0x1 +serdes_driver_current_lane3_xe22=0x1 +serdes_pre_driver_current_lane0_xe22=0x1 +serdes_pre_driver_current_lane1_xe22=0x1 +serdes_pre_driver_current_lane2_xe22=0x1 +serdes_pre_driver_current_lane3_xe22=0x1 +serdes_preemphasis_lane0_xe22=0xbb10 +serdes_preemphasis_lane1_xe22=0xbb10 +serdes_preemphasis_lane2_xe22=0xbb10 +serdes_preemphasis_lane3_xe22=0xc2f0 + +# xe23 (40G) +portmap_24=117:40 +xgxs_rx_lane_map_24=0x231 +xgxs_tx_lane_map_24=0x1203 +phy_xaui_rx_polarity_flip_24=0x3 +phy_xaui_tx_polarity_flip_24=0xe +serdes_driver_current_lane0_xe23=0x3 +serdes_driver_current_lane1_xe23=0x5 +serdes_driver_current_lane2_xe23=0x3 +serdes_driver_current_lane3_xe23=0x3 +serdes_pre_driver_current_lane0_xe23=0x3 +serdes_pre_driver_current_lane1_xe23=0x5 +serdes_pre_driver_current_lane2_xe23=0x3 +serdes_pre_driver_current_lane3_xe23=0x3 +serdes_preemphasis_lane0_xe23=0xc6e0 +serdes_preemphasis_lane1_xe23=0xc6e0 +serdes_preemphasis_lane2_xe23=0xc6e0 +serdes_preemphasis_lane3_xe23=0xc6e0 + +# xe24 (40G) +portmap_25=125:40 +xgxs_rx_lane_map_25=0x132 +xgxs_tx_lane_map_25=0x132 +phy_xaui_rx_polarity_flip_25=0x8 +phy_xaui_tx_polarity_flip_25=0x0 +serdes_driver_current_lane0_xe24=0x4 +serdes_driver_current_lane1_xe24=0x4 +serdes_driver_current_lane2_xe24=0x4 +serdes_driver_current_lane3_xe24=0x4 +serdes_pre_driver_current_lane0_xe24=0x4 +serdes_pre_driver_current_lane1_xe24=0x4 +serdes_pre_driver_current_lane2_xe24=0x4 +serdes_pre_driver_current_lane3_xe24=0x4 +serdes_preemphasis_lane0_xe24=0xc6e0 +serdes_preemphasis_lane1_xe24=0xc6e0 +serdes_preemphasis_lane2_xe24=0xc6e0 +serdes_preemphasis_lane3_xe24=0xcec0 + +# xe25 (40G) +portmap_26=121:40 +xgxs_rx_lane_map_26=0x1320 +xgxs_tx_lane_map_26=0x3021 +phy_xaui_rx_polarity_flip_26=0xd +phy_xaui_tx_polarity_flip_26=0xb +serdes_driver_current_lane0_xe25=0x4 +serdes_driver_current_lane1_xe25=0x4 +serdes_driver_current_lane2_xe25=0x4 +serdes_driver_current_lane3_xe25=0x4 +serdes_pre_driver_current_lane0_xe25=0x4 +serdes_pre_driver_current_lane1_xe25=0x4 +serdes_pre_driver_current_lane2_xe25=0x4 +serdes_pre_driver_current_lane3_xe25=0x4 +serdes_preemphasis_lane0_xe25=0xc6e0 +serdes_preemphasis_lane1_xe25=0xc6e0 +serdes_preemphasis_lane2_xe25=0xc6e0 +serdes_preemphasis_lane3_xe25=0xc6e0 + +# xe26 (40G) +portmap_27=81:40 +xgxs_rx_lane_map_27=0x1320 +xgxs_tx_lane_map_27=0x2031 +phy_xaui_rx_polarity_flip_27=0x1 +phy_xaui_tx_polarity_flip_27=0x2 +serdes_driver_current_lane0_xe26=0x2 +serdes_driver_current_lane1_xe26=0x2 +serdes_driver_current_lane2_xe26=0x2 +serdes_driver_current_lane3_xe26=0x2 +serdes_pre_driver_current_lane0_xe26=0x2 +serdes_pre_driver_current_lane1_xe26=0x2 +serdes_pre_driver_current_lane2_xe26=0x2 +serdes_pre_driver_current_lane3_xe26=0x2 +serdes_preemphasis_lane0_xe26=0xbb10 +serdes_preemphasis_lane1_xe26=0xbb10 +serdes_preemphasis_lane2_xe26=0xbf00 +serdes_preemphasis_lane3_xe26=0xbb10 + +# xe27 (40G) +portmap_28=85:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x1203 +phy_xaui_rx_polarity_flip_28=0xc +phy_xaui_tx_polarity_flip_28=0xe +serdes_driver_current_lane0_xe27=0x4 +serdes_driver_current_lane1_xe27=0x5 +serdes_driver_current_lane2_xe27=0x4 +serdes_driver_current_lane3_xe27=0x5 +serdes_pre_driver_current_lane0_xe27=0x4 +serdes_pre_driver_current_lane1_xe27=0x5 +serdes_pre_driver_current_lane2_xe27=0x4 +serdes_pre_driver_current_lane3_xe27=0x5 +serdes_preemphasis_lane0_xe27=0xc2f0 +serdes_preemphasis_lane1_xe27=0xc6e0 +serdes_preemphasis_lane2_xe27=0xc6e0 +serdes_preemphasis_lane3_xe27=0xc6e0 + +# xe28 (40G) +portmap_29=93:40 +xgxs_rx_lane_map_29=0x1320 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x2 +serdes_driver_current_lane0_xe28=0x4 +serdes_driver_current_lane1_xe28=0x4 +serdes_driver_current_lane2_xe28=0x4 +serdes_driver_current_lane3_xe28=0x4 +serdes_pre_driver_current_lane0_xe28=0x4 +serdes_pre_driver_current_lane1_xe28=0x4 +serdes_pre_driver_current_lane2_xe28=0x4 +serdes_pre_driver_current_lane3_xe28=0x4 +serdes_preemphasis_lane0_xe28=0xc2f0 +serdes_preemphasis_lane1_xe28=0xc2f0 +serdes_preemphasis_lane2_xe28=0xc2f0 +serdes_preemphasis_lane3_xe28=0xc2f0 + +# xe29 (40G) +portmap_30=89:40 +xgxs_rx_lane_map_30=0x1320 +xgxs_tx_lane_map_30=0x3021 +phy_xaui_rx_polarity_flip_30=0x2 +phy_xaui_tx_polarity_flip_30=0xb +serdes_driver_current_lane0_xe29=0x4 +serdes_driver_current_lane1_xe29=0x4 +serdes_driver_current_lane2_xe29=0x4 +serdes_driver_current_lane3_xe29=0x4 +serdes_pre_driver_current_lane0_xe29=0x4 +serdes_pre_driver_current_lane1_xe29=0x4 +serdes_pre_driver_current_lane2_xe29=0x4 +serdes_pre_driver_current_lane3_xe29=0x4 +serdes_preemphasis_lane0_xe29=0xcad0 +serdes_preemphasis_lane1_xe29=0xc6e0 +serdes_preemphasis_lane2_xe29=0xc6e0 +serdes_preemphasis_lane3_xe29=0xc6e0 + +# xe30 (40G) +portmap_31=101:40 +xgxs_rx_lane_map_31=0x1320 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x1 +phy_xaui_tx_polarity_flip_31=0x6 +serdes_driver_current_lane0_xe30=0x6 +serdes_driver_current_lane1_xe30=0x6 +serdes_driver_current_lane2_xe30=0x6 +serdes_driver_current_lane3_xe30=0x7 +serdes_pre_driver_current_lane0_xe30=0x6 +serdes_pre_driver_current_lane1_xe30=0x6 +serdes_pre_driver_current_lane2_xe30=0x6 +serdes_pre_driver_current_lane3_xe30=0x7 +serdes_preemphasis_lane0_xe30=0xcec0 +serdes_preemphasis_lane1_xe30=0xcec0 +serdes_preemphasis_lane2_xe30=0xcad0 +serdes_preemphasis_lane3_xe30=0xc6e0 + +# xe31 (40G) +portmap_32=97:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0xc +phy_xaui_tx_polarity_flip_32=0x3 +serdes_driver_current_lane0_xe31=0x5 +serdes_driver_current_lane1_xe31=0x5 +serdes_driver_current_lane2_xe31=0x5 +serdes_driver_current_lane3_xe31=0x5 +serdes_pre_driver_current_lane0_xe31=0x5 +serdes_pre_driver_current_lane1_xe31=0x5 +serdes_pre_driver_current_lane2_xe31=0x5 +serdes_pre_driver_current_lane3_xe31=0x5 +serdes_preemphasis_lane0_xe31=0xcad0 +serdes_preemphasis_lane1_xe31=0xcad0 +serdes_preemphasis_lane2_xe31=0xcad0 +serdes_preemphasis_lane3_xe31=0xcad0 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers.json.j2 new file mode 100644 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_def.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_def.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_def.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t0.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t1.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/pg_profile_lookup.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/port_config.ini new file mode 100644 index 000000000000..95cf5eec9e4e --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 25,26,27,28 fortyGigE0/0 0 40000 +Ethernet4 29,30,31,32 fortyGigE0/4 1 40000 +Ethernet8 33,34,35,36 fortyGigE0/8 2 40000 +Ethernet12 37,38,39,40 fortyGigE0/12 3 40000 +Ethernet16 45,46,47,48 fortyGigE0/16 4 40000 +Ethernet20 41,42,43,44 fortyGigE0/20 5 40000 +Ethernet24 1,2,3,4 fortyGigE0/24 6 40000 +Ethernet28 5,6,7,8 fortyGigE0/28 7 40000 +Ethernet32 13,14,15,16 fortyGigE0/32 8 40000 +Ethernet36 9,10,11,12 fortyGigE0/36 9 40000 +Ethernet40 17,18,19,20 fortyGigE0/40 10 40000 +Ethernet44 21,22,23,24 fortyGigE0/44 11 40000 +Ethernet48 53,54,55,56 fortyGigE0/48 12 40000 +Ethernet52 49,50,51,52 fortyGigE0/52 13 40000 +Ethernet56 57,58,59,60 fortyGigE0/56 14 40000 +Ethernet60 61,62,63,64 fortyGigE0/60 15 40000 +Ethernet64 69,70,71,72 fortyGigE0/64 16 40000 +Ethernet68 65,66,67,68 fortyGigE0/68 17 40000 +Ethernet72 73,74,75,76 fortyGigE0/72 18 40000 +Ethernet76 77,78,79,80 fortyGigE0/76 19 40000 +Ethernet80 109,110,111,112 fortyGigE0/80 20 40000 +Ethernet84 105,106,107,108 fortyGigE0/84 21 40000 +Ethernet88 113,114,115,116 fortyGigE0/88 22 40000 +Ethernet92 117,118,119,120 fortyGigE0/92 23 40000 +Ethernet96 125,126,127,128 fortyGigE0/96 24 40000 +Ethernet100 121,122,123,124 fortyGigE0/100 25 40000 +Ethernet104 81,82,83,84 fortyGigE0/104 26 40000 +Ethernet108 85,86,87,88 fortyGigE0/108 27 40000 +Ethernet112 93,94,95,96 fortyGigE0/112 28 40000 +Ethernet116 89,90,91,92 fortyGigE0/116 29 40000 +Ethernet120 101,102,103,104 fortyGigE0/120 30 40000 +Ethernet124 97,98,99,100 fortyGigE0/124 31 40000 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/qos.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile new file mode 100644 index 000000000000..bfc466f27e54 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile @@ -0,0 +1,5 @@ +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/td2-s6000-32x40G.config.bcm new file mode 100644 index 000000000000..4c94db7107c7 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/td2-s6000-32x40G.config.bcm @@ -0,0 +1,646 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000007fffffffffffffffffffffffffe +pbmp_xport_xe=0x000007fffffffffffffffffffffffffe + +# Ports configuration +# xe0 (40G) +portmap_1=25:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x2031 +phy_xaui_rx_polarity_flip_1=0xe +phy_xaui_tx_polarity_flip_1=0x2 +serdes_driver_current_lane0_xe0=0x5 +serdes_driver_current_lane1_xe0=0x5 +serdes_driver_current_lane2_xe0=0x5 +serdes_driver_current_lane3_xe0=0x5 +serdes_pre_driver_current_lane0_xe0=0x5 +serdes_pre_driver_current_lane1_xe0=0x5 +serdes_pre_driver_current_lane2_xe0=0x5 +serdes_pre_driver_current_lane3_xe0=0x5 +serdes_preemphasis_lane0_xe0=0xcad0 +serdes_preemphasis_lane1_xe0=0xc6e0 +serdes_preemphasis_lane2_xe0=0xc6e0 +serdes_preemphasis_lane3_xe0=0xd2b0 + +# xe1 (40G) +portmap_2=29:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x213 +phy_xaui_rx_polarity_flip_2=0xc +phy_xaui_tx_polarity_flip_2=0x9 +serdes_driver_current_lane0_xe1=0x6 +serdes_driver_current_lane1_xe1=0x7 +serdes_driver_current_lane2_xe1=0x6 +serdes_driver_current_lane3_xe1=0x6 +serdes_pre_driver_current_lane0_xe1=0x6 +serdes_pre_driver_current_lane1_xe1=0x7 +serdes_pre_driver_current_lane2_xe1=0x6 +serdes_pre_driver_current_lane3_xe1=0x6 +serdes_preemphasis_lane0_xe1=0xc2f0 +serdes_preemphasis_lane1_xe1=0xd2b0 +serdes_preemphasis_lane2_xe1=0xc6e0 +serdes_preemphasis_lane3_xe1=0xc2f0 + +# xe2 (40G) +portmap_3=33:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x132 +phy_xaui_rx_polarity_flip_3=0xe +phy_xaui_tx_polarity_flip_3=0x2 +serdes_driver_current_lane0_xe2=0x4 +serdes_driver_current_lane1_xe2=0x4 +serdes_driver_current_lane2_xe2=0x4 +serdes_driver_current_lane3_xe2=0x4 +serdes_pre_driver_current_lane0_xe2=0x4 +serdes_pre_driver_current_lane1_xe2=0x4 +serdes_pre_driver_current_lane2_xe2=0x4 +serdes_pre_driver_current_lane3_xe2=0x4 +serdes_preemphasis_lane0_xe2=0xc6e0 +serdes_preemphasis_lane1_xe2=0xc6e0 +serdes_preemphasis_lane2_xe2=0xc6e0 +serdes_preemphasis_lane3_xe2=0xc6e0 + +# xe3 (40G) +portmap_4=37:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x1203 +phy_xaui_rx_polarity_flip_4=0x3 +phy_xaui_tx_polarity_flip_4=0xe +serdes_driver_current_lane0_xe3=0x4 +serdes_driver_current_lane1_xe3=0x4 +serdes_driver_current_lane2_xe3=0x4 +serdes_driver_current_lane3_xe3=0x4 +serdes_pre_driver_current_lane0_xe3=0x4 +serdes_pre_driver_current_lane1_xe3=0x4 +serdes_pre_driver_current_lane2_xe3=0x4 +serdes_pre_driver_current_lane3_xe3=0x4 +serdes_preemphasis_lane0_xe3=0xcad0 +serdes_preemphasis_lane1_xe3=0xcad0 +serdes_preemphasis_lane2_xe3=0xc2f0 +serdes_preemphasis_lane3_xe3=0xc2f0 + +# xe4 (40G) +portmap_5=45:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x213 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x8 +serdes_driver_current_lane0_xe4=0x4 +serdes_driver_current_lane1_xe4=0x4 +serdes_driver_current_lane2_xe4=0x4 +serdes_driver_current_lane3_xe4=0x4 +serdes_pre_driver_current_lane0_xe4=0x4 +serdes_pre_driver_current_lane1_xe4=0x4 +serdes_pre_driver_current_lane2_xe4=0x4 +serdes_pre_driver_current_lane3_xe4=0x4 +serdes_preemphasis_lane0_xe4=0xc2f0 +serdes_preemphasis_lane1_xe4=0xc2f0 +serdes_preemphasis_lane2_xe4=0xc2f0 +serdes_preemphasis_lane3_xe4=0xc2f0 + +# xe5 (40G) +portmap_6=41:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x3021 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xb +serdes_driver_current_lane0_xe5=0x4 +serdes_driver_current_lane1_xe5=0x4 +serdes_driver_current_lane2_xe5=0x4 +serdes_driver_current_lane3_xe5=0x4 +serdes_pre_driver_current_lane0_xe5=0x4 +serdes_pre_driver_current_lane1_xe5=0x4 +serdes_pre_driver_current_lane2_xe5=0x4 +serdes_pre_driver_current_lane3_xe5=0x4 +serdes_preemphasis_lane0_xe5=0xc6e0 +serdes_preemphasis_lane1_xe5=0xc2f0 +serdes_preemphasis_lane2_xe5=0xc2f0 +serdes_preemphasis_lane3_xe5=0xcad0 + +# xe6 (40G) +portmap_7=1:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x2031 +phy_xaui_rx_polarity_flip_7=0xe +phy_xaui_tx_polarity_flip_7=0xd +serdes_driver_current_lane0_xe6=0x5 +serdes_driver_current_lane1_xe6=0x5 +serdes_driver_current_lane2_xe6=0x5 +serdes_driver_current_lane3_xe6=0x5 +serdes_pre_driver_current_lane0_xe6=0x5 +serdes_pre_driver_current_lane1_xe6=0x5 +serdes_pre_driver_current_lane2_xe6=0x5 +serdes_pre_driver_current_lane3_xe6=0x5 +serdes_preemphasis_lane0_xe6=0xc6e0 +serdes_preemphasis_lane1_xe6=0xcad0 +serdes_preemphasis_lane2_xe6=0xc6e0 +serdes_preemphasis_lane3_xe6=0xcad0 + +# xe7 (40G) +portmap_8=5:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x1203 +phy_xaui_rx_polarity_flip_8=0xc +phy_xaui_tx_polarity_flip_8=0x1 +serdes_driver_current_lane0_xe7=0x4 +serdes_driver_current_lane1_xe7=0x4 +serdes_driver_current_lane2_xe7=0x4 +serdes_driver_current_lane3_xe7=0x4 +serdes_pre_driver_current_lane0_xe7=0x4 +serdes_pre_driver_current_lane1_xe7=0x4 +serdes_pre_driver_current_lane2_xe7=0x4 +serdes_pre_driver_current_lane3_xe7=0x4 +serdes_preemphasis_lane0_xe7=0xc6e0 +serdes_preemphasis_lane1_xe7=0xc6e0 +serdes_preemphasis_lane2_xe7=0xc6e0 +serdes_preemphasis_lane3_xe7=0xc6e0 + +# xe8 (40G) +portmap_9=13:40 +xgxs_rx_lane_map_9=0x213 +xgxs_tx_lane_map_9=0x132 +phy_xaui_rx_polarity_flip_9=0xe +phy_xaui_tx_polarity_flip_9=0x0 +serdes_driver_current_lane0_xe8=0x2 +serdes_driver_current_lane1_xe8=0x3 +serdes_driver_current_lane2_xe8=0x2 +serdes_driver_current_lane3_xe8=0x2 +serdes_pre_driver_current_lane0_xe8=0x2 +serdes_pre_driver_current_lane1_xe8=0x3 +serdes_pre_driver_current_lane2_xe8=0x2 +serdes_pre_driver_current_lane3_xe8=0x2 +serdes_preemphasis_lane0_xe8=0xb270 +serdes_preemphasis_lane1_xe8=0xbb10 +serdes_preemphasis_lane2_xe8=0xb720 +serdes_preemphasis_lane3_xe8=0xb720 + +# xe9 (40G) +portmap_10=9:40 +xgxs_rx_lane_map_10=0x3120 +xgxs_tx_lane_map_10=0x3021 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x4 +serdes_driver_current_lane0_xe9=0x3 +serdes_driver_current_lane1_xe9=0x3 +serdes_driver_current_lane2_xe9=0x3 +serdes_driver_current_lane3_xe9=0x3 +serdes_pre_driver_current_lane0_xe9=0x3 +serdes_pre_driver_current_lane1_xe9=0x3 +serdes_pre_driver_current_lane2_xe9=0x3 +serdes_pre_driver_current_lane3_xe9=0x3 +serdes_preemphasis_lane0_xe9=0xc2f0 +serdes_preemphasis_lane1_xe9=0xc6e0 +serdes_preemphasis_lane2_xe9=0xbf00 +serdes_preemphasis_lane3_xe9=0xc2f0 + +# xe10 (40G) +portmap_11=17:40 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x132 +phy_xaui_rx_polarity_flip_11=0xe +phy_xaui_tx_polarity_flip_11=0x0 +serdes_driver_current_lane0_xe10=0x2 +serdes_driver_current_lane1_xe10=0x2 +serdes_driver_current_lane2_xe10=0x2 +serdes_driver_current_lane3_xe10=0x2 +serdes_pre_driver_current_lane0_xe10=0x2 +serdes_pre_driver_current_lane1_xe10=0x2 +serdes_pre_driver_current_lane2_xe10=0x2 +serdes_pre_driver_current_lane3_xe10=0x2 +serdes_preemphasis_lane0_xe10=0xb330 +serdes_preemphasis_lane1_xe10=0xbb10 +serdes_preemphasis_lane2_xe10=0xbb10 +serdes_preemphasis_lane3_xe10=0xbb10 + +# xe11 (40G) +portmap_12=21:40 +xgxs_rx_lane_map_12=0x123 +xgxs_tx_lane_map_12=0x1203 +phy_xaui_rx_polarity_flip_12=0xc +phy_xaui_tx_polarity_flip_12=0xe +serdes_driver_current_lane0_xe11=0x2 +serdes_driver_current_lane1_xe11=0x2 +serdes_driver_current_lane2_xe11=0x2 +serdes_driver_current_lane3_xe11=0x2 +serdes_pre_driver_current_lane0_xe11=0x2 +serdes_pre_driver_current_lane1_xe11=0x2 +serdes_pre_driver_current_lane2_xe11=0x2 +serdes_pre_driver_current_lane3_xe11=0x2 +serdes_preemphasis_lane0_xe11=0xb330 +serdes_preemphasis_lane1_xe11=0xb330 +serdes_preemphasis_lane2_xe11=0xb330 +serdes_preemphasis_lane3_xe11=0xb330 + +# xe12 (40G) +portmap_13=53:40 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x231 +phy_xaui_rx_polarity_flip_13=0x1 +phy_xaui_tx_polarity_flip_13=0x0 +serdes_driver_current_lane0_xe12=0x2 +serdes_driver_current_lane1_xe12=0x2 +serdes_driver_current_lane2_xe12=0x2 +serdes_driver_current_lane3_xe12=0x2 +serdes_pre_driver_current_lane0_xe12=0x2 +serdes_pre_driver_current_lane1_xe12=0x2 +serdes_pre_driver_current_lane2_xe12=0x2 +serdes_pre_driver_current_lane3_xe12=0x2 +serdes_preemphasis_lane0_xe12=0xaf40 +serdes_preemphasis_lane1_xe12=0xaf40 +serdes_preemphasis_lane2_xe12=0xaf40 +serdes_preemphasis_lane3_xe12=0xaf40 + +# xe13 (40G) +portmap_14=49:40 +xgxs_rx_lane_map_14=0x1302 +xgxs_tx_lane_map_14=0x2031 +phy_xaui_rx_polarity_flip_14=0xb +phy_xaui_tx_polarity_flip_14=0x3 +serdes_driver_current_lane0_xe13=0x2 +serdes_driver_current_lane1_xe13=0x2 +serdes_driver_current_lane2_xe13=0x2 +serdes_driver_current_lane3_xe13=0x2 +serdes_pre_driver_current_lane0_xe13=0x2 +serdes_pre_driver_current_lane1_xe13=0x2 +serdes_pre_driver_current_lane2_xe13=0x2 +serdes_pre_driver_current_lane3_xe13=0x2 +serdes_preemphasis_lane0_xe13=0xa760 +serdes_preemphasis_lane1_xe13=0xa760 +serdes_preemphasis_lane2_xe13=0xa760 +serdes_preemphasis_lane3_xe13=0xa760 + +# xe14 (40G) +portmap_15=57:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x2031 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_xe14=0x1 +serdes_driver_current_lane1_xe14=0x1 +serdes_driver_current_lane2_xe14=0x1 +serdes_driver_current_lane3_xe14=0x1 +serdes_pre_driver_current_lane0_xe14=0x1 +serdes_pre_driver_current_lane1_xe14=0x1 +serdes_pre_driver_current_lane2_xe14=0x1 +serdes_pre_driver_current_lane3_xe14=0x1 +serdes_preemphasis_lane0_xe14=0xa760 +serdes_preemphasis_lane1_xe14=0xa760 +serdes_preemphasis_lane2_xe14=0xa760 +serdes_preemphasis_lane3_xe14=0xa760 + +# xe15 (40G) +portmap_16=61:40 +xgxs_rx_lane_map_16=0x132 +xgxs_tx_lane_map_16=0x213 +phy_xaui_rx_polarity_flip_16=0x0 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_xe15=0x2 +serdes_driver_current_lane1_xe15=0x2 +serdes_driver_current_lane2_xe15=0x2 +serdes_driver_current_lane3_xe15=0x2 +serdes_pre_driver_current_lane0_xe15=0x2 +serdes_pre_driver_current_lane1_xe15=0x2 +serdes_pre_driver_current_lane2_xe15=0x2 +serdes_pre_driver_current_lane3_xe15=0x2 +serdes_preemphasis_lane0_xe15=0xa760 +serdes_preemphasis_lane1_xe15=0xa760 +serdes_preemphasis_lane2_xe15=0xa760 +serdes_preemphasis_lane3_xe15=0xa760 + +# xe16 (40G) +portmap_17=69:40 +xgxs_rx_lane_map_17=0x213 +xgxs_tx_lane_map_17=0x2130 +phy_xaui_rx_polarity_flip_17=0x1 +phy_xaui_tx_polarity_flip_17=0xf +serdes_driver_current_lane0_xe16=0x1 +serdes_driver_current_lane1_xe16=0x1 +serdes_driver_current_lane2_xe16=0x1 +serdes_driver_current_lane3_xe16=0x1 +serdes_pre_driver_current_lane0_xe16=0x1 +serdes_pre_driver_current_lane1_xe16=0x1 +serdes_pre_driver_current_lane2_xe16=0x1 +serdes_pre_driver_current_lane3_xe16=0x1 +serdes_preemphasis_lane0_xe16=0xa760 +serdes_preemphasis_lane1_xe16=0xa760 +serdes_preemphasis_lane2_xe16=0xa760 +serdes_preemphasis_lane3_xe16=0xa760 + +# xe17 (40G) +portmap_18=65:40 +xgxs_rx_lane_map_18=0x132 +xgxs_tx_lane_map_18=0x2031 +phy_xaui_rx_polarity_flip_18=0x3 +phy_xaui_tx_polarity_flip_18=0x9 +serdes_driver_current_lane0_xe17=0x1 +serdes_driver_current_lane1_xe17=0x1 +serdes_driver_current_lane2_xe17=0x1 +serdes_driver_current_lane3_xe17=0x1 +serdes_pre_driver_current_lane0_xe17=0x1 +serdes_pre_driver_current_lane1_xe17=0x1 +serdes_pre_driver_current_lane2_xe17=0x1 +serdes_pre_driver_current_lane3_xe17=0x1 +serdes_preemphasis_lane0_xe17=0xa370 +serdes_preemphasis_lane1_xe17=0xa370 +serdes_preemphasis_lane2_xe17=0xa370 +serdes_preemphasis_lane3_xe17=0xa370 + +# xe18 (40G) +portmap_19=73:40 +xgxs_rx_lane_map_19=0x213 +xgxs_tx_lane_map_19=0x2031 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_xe18=0x2 +serdes_driver_current_lane1_xe18=0x2 +serdes_driver_current_lane2_xe18=0x2 +serdes_driver_current_lane3_xe18=0x2 +serdes_pre_driver_current_lane0_xe18=0x2 +serdes_pre_driver_current_lane1_xe18=0x2 +serdes_pre_driver_current_lane2_xe18=0x2 +serdes_pre_driver_current_lane3_xe18=0x2 +serdes_preemphasis_lane0_xe18=0xa760 +serdes_preemphasis_lane1_xe18=0xa760 +serdes_preemphasis_lane2_xe18=0xa760 +serdes_preemphasis_lane3_xe18=0xa760 + +# xe19 (40G) +portmap_20=77:40 +xgxs_rx_lane_map_20=0x123 +xgxs_tx_lane_map_20=0x1203 +phy_xaui_rx_polarity_flip_20=0x3 +phy_xaui_tx_polarity_flip_20=0xe +serdes_driver_current_lane0_xe19=0x2 +serdes_driver_current_lane1_xe19=0x2 +serdes_driver_current_lane2_xe19=0x2 +serdes_driver_current_lane3_xe19=0x2 +serdes_pre_driver_current_lane0_xe19=0x2 +serdes_pre_driver_current_lane1_xe19=0x2 +serdes_pre_driver_current_lane2_xe19=0x2 +serdes_pre_driver_current_lane3_xe19=0x2 +serdes_preemphasis_lane0_xe19=0xaf40 +serdes_preemphasis_lane1_xe19=0xaf40 +serdes_preemphasis_lane2_xe19=0xaf40 +serdes_preemphasis_lane3_xe19=0xaf40 + +# xe20 (40G) +portmap_21=109:40 +xgxs_rx_lane_map_21=0x132 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0x8 +phy_xaui_tx_polarity_flip_21=0x0 +serdes_driver_current_lane0_xe20=0x1 +serdes_driver_current_lane1_xe20=0x1 +serdes_driver_current_lane2_xe20=0x1 +serdes_driver_current_lane3_xe20=0x2 +serdes_pre_driver_current_lane0_xe20=0x1 +serdes_pre_driver_current_lane1_xe20=0x1 +serdes_pre_driver_current_lane2_xe20=0x1 +serdes_pre_driver_current_lane3_xe20=0x2 +serdes_preemphasis_lane0_xe20=0xb330 +serdes_preemphasis_lane1_xe20=0xb330 +serdes_preemphasis_lane2_xe20=0xb330 +serdes_preemphasis_lane3_xe20=0xbff0 + +# xe21 (40G) +portmap_22=105:40 +xgxs_rx_lane_map_22=0x1320 +xgxs_tx_lane_map_22=0x3021 +phy_xaui_rx_polarity_flip_22=0xd +phy_xaui_tx_polarity_flip_22=0xb +serdes_driver_current_lane0_xe21=0x1 +serdes_driver_current_lane1_xe21=0x1 +serdes_driver_current_lane2_xe21=0x1 +serdes_driver_current_lane3_xe21=0x1 +serdes_pre_driver_current_lane0_xe21=0x1 +serdes_pre_driver_current_lane1_xe21=0x1 +serdes_pre_driver_current_lane2_xe21=0x1 +serdes_pre_driver_current_lane3_xe21=0x1 +serdes_preemphasis_lane0_xe21=0xb330 +serdes_preemphasis_lane1_xe21=0xb330 +serdes_preemphasis_lane2_xe21=0xb330 +serdes_preemphasis_lane3_xe21=0xb330 + +# xe22 (40G) +portmap_23=113:40 +xgxs_rx_lane_map_23=0x132 +xgxs_tx_lane_map_23=0x132 +phy_xaui_rx_polarity_flip_23=0x8 +phy_xaui_tx_polarity_flip_23=0x0 +serdes_driver_current_lane0_xe22=0x1 +serdes_driver_current_lane1_xe22=0x1 +serdes_driver_current_lane2_xe22=0x1 +serdes_driver_current_lane3_xe22=0x1 +serdes_pre_driver_current_lane0_xe22=0x1 +serdes_pre_driver_current_lane1_xe22=0x1 +serdes_pre_driver_current_lane2_xe22=0x1 +serdes_pre_driver_current_lane3_xe22=0x1 +serdes_preemphasis_lane0_xe22=0xbb10 +serdes_preemphasis_lane1_xe22=0xbb10 +serdes_preemphasis_lane2_xe22=0xbb10 +serdes_preemphasis_lane3_xe22=0xc2f0 + +# xe23 (40G) +portmap_24=117:40 +xgxs_rx_lane_map_24=0x231 +xgxs_tx_lane_map_24=0x1203 +phy_xaui_rx_polarity_flip_24=0x3 +phy_xaui_tx_polarity_flip_24=0xe +serdes_driver_current_lane0_xe23=0x3 +serdes_driver_current_lane1_xe23=0x5 +serdes_driver_current_lane2_xe23=0x3 +serdes_driver_current_lane3_xe23=0x3 +serdes_pre_driver_current_lane0_xe23=0x3 +serdes_pre_driver_current_lane1_xe23=0x5 +serdes_pre_driver_current_lane2_xe23=0x3 +serdes_pre_driver_current_lane3_xe23=0x3 +serdes_preemphasis_lane0_xe23=0xc6e0 +serdes_preemphasis_lane1_xe23=0xc6e0 +serdes_preemphasis_lane2_xe23=0xc6e0 +serdes_preemphasis_lane3_xe23=0xc6e0 + +# xe24 (40G) +portmap_25=125:40 +xgxs_rx_lane_map_25=0x132 +xgxs_tx_lane_map_25=0x132 +phy_xaui_rx_polarity_flip_25=0x8 +phy_xaui_tx_polarity_flip_25=0x0 +serdes_driver_current_lane0_xe24=0x4 +serdes_driver_current_lane1_xe24=0x4 +serdes_driver_current_lane2_xe24=0x4 +serdes_driver_current_lane3_xe24=0x4 +serdes_pre_driver_current_lane0_xe24=0x4 +serdes_pre_driver_current_lane1_xe24=0x4 +serdes_pre_driver_current_lane2_xe24=0x4 +serdes_pre_driver_current_lane3_xe24=0x4 +serdes_preemphasis_lane0_xe24=0xc6e0 +serdes_preemphasis_lane1_xe24=0xc6e0 +serdes_preemphasis_lane2_xe24=0xc6e0 +serdes_preemphasis_lane3_xe24=0xcec0 + +# xe25 (40G) +portmap_26=121:40 +xgxs_rx_lane_map_26=0x1320 +xgxs_tx_lane_map_26=0x3021 +phy_xaui_rx_polarity_flip_26=0xd +phy_xaui_tx_polarity_flip_26=0xb +serdes_driver_current_lane0_xe25=0x4 +serdes_driver_current_lane1_xe25=0x4 +serdes_driver_current_lane2_xe25=0x4 +serdes_driver_current_lane3_xe25=0x4 +serdes_pre_driver_current_lane0_xe25=0x4 +serdes_pre_driver_current_lane1_xe25=0x4 +serdes_pre_driver_current_lane2_xe25=0x4 +serdes_pre_driver_current_lane3_xe25=0x4 +serdes_preemphasis_lane0_xe25=0xc6e0 +serdes_preemphasis_lane1_xe25=0xc6e0 +serdes_preemphasis_lane2_xe25=0xc6e0 +serdes_preemphasis_lane3_xe25=0xc6e0 + +# xe26 (40G) +portmap_27=81:40 +xgxs_rx_lane_map_27=0x1320 +xgxs_tx_lane_map_27=0x2031 +phy_xaui_rx_polarity_flip_27=0x1 +phy_xaui_tx_polarity_flip_27=0x2 +serdes_driver_current_lane0_xe26=0x2 +serdes_driver_current_lane1_xe26=0x2 +serdes_driver_current_lane2_xe26=0x2 +serdes_driver_current_lane3_xe26=0x2 +serdes_pre_driver_current_lane0_xe26=0x2 +serdes_pre_driver_current_lane1_xe26=0x2 +serdes_pre_driver_current_lane2_xe26=0x2 +serdes_pre_driver_current_lane3_xe26=0x2 +serdes_preemphasis_lane0_xe26=0xbb10 +serdes_preemphasis_lane1_xe26=0xbb10 +serdes_preemphasis_lane2_xe26=0xbf00 +serdes_preemphasis_lane3_xe26=0xbb10 + +# xe27 (40G) +portmap_28=85:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x1203 +phy_xaui_rx_polarity_flip_28=0xc +phy_xaui_tx_polarity_flip_28=0xe +serdes_driver_current_lane0_xe27=0x4 +serdes_driver_current_lane1_xe27=0x5 +serdes_driver_current_lane2_xe27=0x4 +serdes_driver_current_lane3_xe27=0x5 +serdes_pre_driver_current_lane0_xe27=0x4 +serdes_pre_driver_current_lane1_xe27=0x5 +serdes_pre_driver_current_lane2_xe27=0x4 +serdes_pre_driver_current_lane3_xe27=0x5 +serdes_preemphasis_lane0_xe27=0xc2f0 +serdes_preemphasis_lane1_xe27=0xc6e0 +serdes_preemphasis_lane2_xe27=0xc6e0 +serdes_preemphasis_lane3_xe27=0xc6e0 + +# xe28 (40G) +portmap_29=93:40 +xgxs_rx_lane_map_29=0x1320 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x2 +serdes_driver_current_lane0_xe28=0x4 +serdes_driver_current_lane1_xe28=0x4 +serdes_driver_current_lane2_xe28=0x4 +serdes_driver_current_lane3_xe28=0x4 +serdes_pre_driver_current_lane0_xe28=0x4 +serdes_pre_driver_current_lane1_xe28=0x4 +serdes_pre_driver_current_lane2_xe28=0x4 +serdes_pre_driver_current_lane3_xe28=0x4 +serdes_preemphasis_lane0_xe28=0xc2f0 +serdes_preemphasis_lane1_xe28=0xc2f0 +serdes_preemphasis_lane2_xe28=0xc2f0 +serdes_preemphasis_lane3_xe28=0xc2f0 + +# xe29 (40G) +portmap_30=89:40 +xgxs_rx_lane_map_30=0x1320 +xgxs_tx_lane_map_30=0x3021 +phy_xaui_rx_polarity_flip_30=0x2 +phy_xaui_tx_polarity_flip_30=0xb +serdes_driver_current_lane0_xe29=0x4 +serdes_driver_current_lane1_xe29=0x4 +serdes_driver_current_lane2_xe29=0x4 +serdes_driver_current_lane3_xe29=0x4 +serdes_pre_driver_current_lane0_xe29=0x4 +serdes_pre_driver_current_lane1_xe29=0x4 +serdes_pre_driver_current_lane2_xe29=0x4 +serdes_pre_driver_current_lane3_xe29=0x4 +serdes_preemphasis_lane0_xe29=0xcad0 +serdes_preemphasis_lane1_xe29=0xc6e0 +serdes_preemphasis_lane2_xe29=0xc6e0 +serdes_preemphasis_lane3_xe29=0xc6e0 + +# xe30 (40G) +portmap_31=101:40 +xgxs_rx_lane_map_31=0x1320 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x1 +phy_xaui_tx_polarity_flip_31=0x6 +serdes_driver_current_lane0_xe30=0x6 +serdes_driver_current_lane1_xe30=0x6 +serdes_driver_current_lane2_xe30=0x6 +serdes_driver_current_lane3_xe30=0x7 +serdes_pre_driver_current_lane0_xe30=0x6 +serdes_pre_driver_current_lane1_xe30=0x6 +serdes_pre_driver_current_lane2_xe30=0x6 +serdes_pre_driver_current_lane3_xe30=0x7 +serdes_preemphasis_lane0_xe30=0xcec0 +serdes_preemphasis_lane1_xe30=0xcec0 +serdes_preemphasis_lane2_xe30=0xcad0 +serdes_preemphasis_lane3_xe30=0xc6e0 + +# xe31 (40G) +portmap_32=97:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0xc +phy_xaui_tx_polarity_flip_32=0x3 +serdes_driver_current_lane0_xe31=0x5 +serdes_driver_current_lane1_xe31=0x5 +serdes_driver_current_lane2_xe31=0x5 +serdes_driver_current_lane3_xe31=0x5 +serdes_pre_driver_current_lane0_xe31=0x5 +serdes_pre_driver_current_lane1_xe31=0x5 +serdes_pre_driver_current_lane2_xe31=0x5 +serdes_pre_driver_current_lane3_xe31=0x5 +serdes_preemphasis_lane0_xe31=0xcad0 +serdes_preemphasis_lane1_xe31=0xcad0 +serdes_preemphasis_lane2_xe31=0xcad0 +serdes_preemphasis_lane3_xe31=0xcad0 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers.json.j2 new file mode 100644 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_def.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_def.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_def.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t0.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t1.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/pg_profile_lookup.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/port_config.ini new file mode 100644 index 000000000000..95cf5eec9e4e --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 25,26,27,28 fortyGigE0/0 0 40000 +Ethernet4 29,30,31,32 fortyGigE0/4 1 40000 +Ethernet8 33,34,35,36 fortyGigE0/8 2 40000 +Ethernet12 37,38,39,40 fortyGigE0/12 3 40000 +Ethernet16 45,46,47,48 fortyGigE0/16 4 40000 +Ethernet20 41,42,43,44 fortyGigE0/20 5 40000 +Ethernet24 1,2,3,4 fortyGigE0/24 6 40000 +Ethernet28 5,6,7,8 fortyGigE0/28 7 40000 +Ethernet32 13,14,15,16 fortyGigE0/32 8 40000 +Ethernet36 9,10,11,12 fortyGigE0/36 9 40000 +Ethernet40 17,18,19,20 fortyGigE0/40 10 40000 +Ethernet44 21,22,23,24 fortyGigE0/44 11 40000 +Ethernet48 53,54,55,56 fortyGigE0/48 12 40000 +Ethernet52 49,50,51,52 fortyGigE0/52 13 40000 +Ethernet56 57,58,59,60 fortyGigE0/56 14 40000 +Ethernet60 61,62,63,64 fortyGigE0/60 15 40000 +Ethernet64 69,70,71,72 fortyGigE0/64 16 40000 +Ethernet68 65,66,67,68 fortyGigE0/68 17 40000 +Ethernet72 73,74,75,76 fortyGigE0/72 18 40000 +Ethernet76 77,78,79,80 fortyGigE0/76 19 40000 +Ethernet80 109,110,111,112 fortyGigE0/80 20 40000 +Ethernet84 105,106,107,108 fortyGigE0/84 21 40000 +Ethernet88 113,114,115,116 fortyGigE0/88 22 40000 +Ethernet92 117,118,119,120 fortyGigE0/92 23 40000 +Ethernet96 125,126,127,128 fortyGigE0/96 24 40000 +Ethernet100 121,122,123,124 fortyGigE0/100 25 40000 +Ethernet104 81,82,83,84 fortyGigE0/104 26 40000 +Ethernet108 85,86,87,88 fortyGigE0/108 27 40000 +Ethernet112 93,94,95,96 fortyGigE0/112 28 40000 +Ethernet116 89,90,91,92 fortyGigE0/116 29 40000 +Ethernet120 101,102,103,104 fortyGigE0/120 30 40000 +Ethernet124 97,98,99,100 fortyGigE0/124 31 40000 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/qos.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile new file mode 100644 index 000000000000..bfc466f27e54 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile @@ -0,0 +1,5 @@ +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/td2-s6000-32x40G.config.bcm new file mode 100644 index 000000000000..4c94db7107c7 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/td2-s6000-32x40G.config.bcm @@ -0,0 +1,646 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000007fffffffffffffffffffffffffe +pbmp_xport_xe=0x000007fffffffffffffffffffffffffe + +# Ports configuration +# xe0 (40G) +portmap_1=25:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x2031 +phy_xaui_rx_polarity_flip_1=0xe +phy_xaui_tx_polarity_flip_1=0x2 +serdes_driver_current_lane0_xe0=0x5 +serdes_driver_current_lane1_xe0=0x5 +serdes_driver_current_lane2_xe0=0x5 +serdes_driver_current_lane3_xe0=0x5 +serdes_pre_driver_current_lane0_xe0=0x5 +serdes_pre_driver_current_lane1_xe0=0x5 +serdes_pre_driver_current_lane2_xe0=0x5 +serdes_pre_driver_current_lane3_xe0=0x5 +serdes_preemphasis_lane0_xe0=0xcad0 +serdes_preemphasis_lane1_xe0=0xc6e0 +serdes_preemphasis_lane2_xe0=0xc6e0 +serdes_preemphasis_lane3_xe0=0xd2b0 + +# xe1 (40G) +portmap_2=29:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x213 +phy_xaui_rx_polarity_flip_2=0xc +phy_xaui_tx_polarity_flip_2=0x9 +serdes_driver_current_lane0_xe1=0x6 +serdes_driver_current_lane1_xe1=0x7 +serdes_driver_current_lane2_xe1=0x6 +serdes_driver_current_lane3_xe1=0x6 +serdes_pre_driver_current_lane0_xe1=0x6 +serdes_pre_driver_current_lane1_xe1=0x7 +serdes_pre_driver_current_lane2_xe1=0x6 +serdes_pre_driver_current_lane3_xe1=0x6 +serdes_preemphasis_lane0_xe1=0xc2f0 +serdes_preemphasis_lane1_xe1=0xd2b0 +serdes_preemphasis_lane2_xe1=0xc6e0 +serdes_preemphasis_lane3_xe1=0xc2f0 + +# xe2 (40G) +portmap_3=33:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x132 +phy_xaui_rx_polarity_flip_3=0xe +phy_xaui_tx_polarity_flip_3=0x2 +serdes_driver_current_lane0_xe2=0x4 +serdes_driver_current_lane1_xe2=0x4 +serdes_driver_current_lane2_xe2=0x4 +serdes_driver_current_lane3_xe2=0x4 +serdes_pre_driver_current_lane0_xe2=0x4 +serdes_pre_driver_current_lane1_xe2=0x4 +serdes_pre_driver_current_lane2_xe2=0x4 +serdes_pre_driver_current_lane3_xe2=0x4 +serdes_preemphasis_lane0_xe2=0xc6e0 +serdes_preemphasis_lane1_xe2=0xc6e0 +serdes_preemphasis_lane2_xe2=0xc6e0 +serdes_preemphasis_lane3_xe2=0xc6e0 + +# xe3 (40G) +portmap_4=37:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x1203 +phy_xaui_rx_polarity_flip_4=0x3 +phy_xaui_tx_polarity_flip_4=0xe +serdes_driver_current_lane0_xe3=0x4 +serdes_driver_current_lane1_xe3=0x4 +serdes_driver_current_lane2_xe3=0x4 +serdes_driver_current_lane3_xe3=0x4 +serdes_pre_driver_current_lane0_xe3=0x4 +serdes_pre_driver_current_lane1_xe3=0x4 +serdes_pre_driver_current_lane2_xe3=0x4 +serdes_pre_driver_current_lane3_xe3=0x4 +serdes_preemphasis_lane0_xe3=0xcad0 +serdes_preemphasis_lane1_xe3=0xcad0 +serdes_preemphasis_lane2_xe3=0xc2f0 +serdes_preemphasis_lane3_xe3=0xc2f0 + +# xe4 (40G) +portmap_5=45:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x213 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x8 +serdes_driver_current_lane0_xe4=0x4 +serdes_driver_current_lane1_xe4=0x4 +serdes_driver_current_lane2_xe4=0x4 +serdes_driver_current_lane3_xe4=0x4 +serdes_pre_driver_current_lane0_xe4=0x4 +serdes_pre_driver_current_lane1_xe4=0x4 +serdes_pre_driver_current_lane2_xe4=0x4 +serdes_pre_driver_current_lane3_xe4=0x4 +serdes_preemphasis_lane0_xe4=0xc2f0 +serdes_preemphasis_lane1_xe4=0xc2f0 +serdes_preemphasis_lane2_xe4=0xc2f0 +serdes_preemphasis_lane3_xe4=0xc2f0 + +# xe5 (40G) +portmap_6=41:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x3021 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xb +serdes_driver_current_lane0_xe5=0x4 +serdes_driver_current_lane1_xe5=0x4 +serdes_driver_current_lane2_xe5=0x4 +serdes_driver_current_lane3_xe5=0x4 +serdes_pre_driver_current_lane0_xe5=0x4 +serdes_pre_driver_current_lane1_xe5=0x4 +serdes_pre_driver_current_lane2_xe5=0x4 +serdes_pre_driver_current_lane3_xe5=0x4 +serdes_preemphasis_lane0_xe5=0xc6e0 +serdes_preemphasis_lane1_xe5=0xc2f0 +serdes_preemphasis_lane2_xe5=0xc2f0 +serdes_preemphasis_lane3_xe5=0xcad0 + +# xe6 (40G) +portmap_7=1:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x2031 +phy_xaui_rx_polarity_flip_7=0xe +phy_xaui_tx_polarity_flip_7=0xd +serdes_driver_current_lane0_xe6=0x5 +serdes_driver_current_lane1_xe6=0x5 +serdes_driver_current_lane2_xe6=0x5 +serdes_driver_current_lane3_xe6=0x5 +serdes_pre_driver_current_lane0_xe6=0x5 +serdes_pre_driver_current_lane1_xe6=0x5 +serdes_pre_driver_current_lane2_xe6=0x5 +serdes_pre_driver_current_lane3_xe6=0x5 +serdes_preemphasis_lane0_xe6=0xc6e0 +serdes_preemphasis_lane1_xe6=0xcad0 +serdes_preemphasis_lane2_xe6=0xc6e0 +serdes_preemphasis_lane3_xe6=0xcad0 + +# xe7 (40G) +portmap_8=5:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x1203 +phy_xaui_rx_polarity_flip_8=0xc +phy_xaui_tx_polarity_flip_8=0x1 +serdes_driver_current_lane0_xe7=0x4 +serdes_driver_current_lane1_xe7=0x4 +serdes_driver_current_lane2_xe7=0x4 +serdes_driver_current_lane3_xe7=0x4 +serdes_pre_driver_current_lane0_xe7=0x4 +serdes_pre_driver_current_lane1_xe7=0x4 +serdes_pre_driver_current_lane2_xe7=0x4 +serdes_pre_driver_current_lane3_xe7=0x4 +serdes_preemphasis_lane0_xe7=0xc6e0 +serdes_preemphasis_lane1_xe7=0xc6e0 +serdes_preemphasis_lane2_xe7=0xc6e0 +serdes_preemphasis_lane3_xe7=0xc6e0 + +# xe8 (40G) +portmap_9=13:40 +xgxs_rx_lane_map_9=0x213 +xgxs_tx_lane_map_9=0x132 +phy_xaui_rx_polarity_flip_9=0xe +phy_xaui_tx_polarity_flip_9=0x0 +serdes_driver_current_lane0_xe8=0x2 +serdes_driver_current_lane1_xe8=0x3 +serdes_driver_current_lane2_xe8=0x2 +serdes_driver_current_lane3_xe8=0x2 +serdes_pre_driver_current_lane0_xe8=0x2 +serdes_pre_driver_current_lane1_xe8=0x3 +serdes_pre_driver_current_lane2_xe8=0x2 +serdes_pre_driver_current_lane3_xe8=0x2 +serdes_preemphasis_lane0_xe8=0xb270 +serdes_preemphasis_lane1_xe8=0xbb10 +serdes_preemphasis_lane2_xe8=0xb720 +serdes_preemphasis_lane3_xe8=0xb720 + +# xe9 (40G) +portmap_10=9:40 +xgxs_rx_lane_map_10=0x3120 +xgxs_tx_lane_map_10=0x3021 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x4 +serdes_driver_current_lane0_xe9=0x3 +serdes_driver_current_lane1_xe9=0x3 +serdes_driver_current_lane2_xe9=0x3 +serdes_driver_current_lane3_xe9=0x3 +serdes_pre_driver_current_lane0_xe9=0x3 +serdes_pre_driver_current_lane1_xe9=0x3 +serdes_pre_driver_current_lane2_xe9=0x3 +serdes_pre_driver_current_lane3_xe9=0x3 +serdes_preemphasis_lane0_xe9=0xc2f0 +serdes_preemphasis_lane1_xe9=0xc6e0 +serdes_preemphasis_lane2_xe9=0xbf00 +serdes_preemphasis_lane3_xe9=0xc2f0 + +# xe10 (40G) +portmap_11=17:40 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x132 +phy_xaui_rx_polarity_flip_11=0xe +phy_xaui_tx_polarity_flip_11=0x0 +serdes_driver_current_lane0_xe10=0x2 +serdes_driver_current_lane1_xe10=0x2 +serdes_driver_current_lane2_xe10=0x2 +serdes_driver_current_lane3_xe10=0x2 +serdes_pre_driver_current_lane0_xe10=0x2 +serdes_pre_driver_current_lane1_xe10=0x2 +serdes_pre_driver_current_lane2_xe10=0x2 +serdes_pre_driver_current_lane3_xe10=0x2 +serdes_preemphasis_lane0_xe10=0xb330 +serdes_preemphasis_lane1_xe10=0xbb10 +serdes_preemphasis_lane2_xe10=0xbb10 +serdes_preemphasis_lane3_xe10=0xbb10 + +# xe11 (40G) +portmap_12=21:40 +xgxs_rx_lane_map_12=0x123 +xgxs_tx_lane_map_12=0x1203 +phy_xaui_rx_polarity_flip_12=0xc +phy_xaui_tx_polarity_flip_12=0xe +serdes_driver_current_lane0_xe11=0x2 +serdes_driver_current_lane1_xe11=0x2 +serdes_driver_current_lane2_xe11=0x2 +serdes_driver_current_lane3_xe11=0x2 +serdes_pre_driver_current_lane0_xe11=0x2 +serdes_pre_driver_current_lane1_xe11=0x2 +serdes_pre_driver_current_lane2_xe11=0x2 +serdes_pre_driver_current_lane3_xe11=0x2 +serdes_preemphasis_lane0_xe11=0xb330 +serdes_preemphasis_lane1_xe11=0xb330 +serdes_preemphasis_lane2_xe11=0xb330 +serdes_preemphasis_lane3_xe11=0xb330 + +# xe12 (40G) +portmap_13=53:40 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x231 +phy_xaui_rx_polarity_flip_13=0x1 +phy_xaui_tx_polarity_flip_13=0x0 +serdes_driver_current_lane0_xe12=0x2 +serdes_driver_current_lane1_xe12=0x2 +serdes_driver_current_lane2_xe12=0x2 +serdes_driver_current_lane3_xe12=0x2 +serdes_pre_driver_current_lane0_xe12=0x2 +serdes_pre_driver_current_lane1_xe12=0x2 +serdes_pre_driver_current_lane2_xe12=0x2 +serdes_pre_driver_current_lane3_xe12=0x2 +serdes_preemphasis_lane0_xe12=0xaf40 +serdes_preemphasis_lane1_xe12=0xaf40 +serdes_preemphasis_lane2_xe12=0xaf40 +serdes_preemphasis_lane3_xe12=0xaf40 + +# xe13 (40G) +portmap_14=49:40 +xgxs_rx_lane_map_14=0x1302 +xgxs_tx_lane_map_14=0x2031 +phy_xaui_rx_polarity_flip_14=0xb +phy_xaui_tx_polarity_flip_14=0x3 +serdes_driver_current_lane0_xe13=0x2 +serdes_driver_current_lane1_xe13=0x2 +serdes_driver_current_lane2_xe13=0x2 +serdes_driver_current_lane3_xe13=0x2 +serdes_pre_driver_current_lane0_xe13=0x2 +serdes_pre_driver_current_lane1_xe13=0x2 +serdes_pre_driver_current_lane2_xe13=0x2 +serdes_pre_driver_current_lane3_xe13=0x2 +serdes_preemphasis_lane0_xe13=0xa760 +serdes_preemphasis_lane1_xe13=0xa760 +serdes_preemphasis_lane2_xe13=0xa760 +serdes_preemphasis_lane3_xe13=0xa760 + +# xe14 (40G) +portmap_15=57:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x2031 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_xe14=0x1 +serdes_driver_current_lane1_xe14=0x1 +serdes_driver_current_lane2_xe14=0x1 +serdes_driver_current_lane3_xe14=0x1 +serdes_pre_driver_current_lane0_xe14=0x1 +serdes_pre_driver_current_lane1_xe14=0x1 +serdes_pre_driver_current_lane2_xe14=0x1 +serdes_pre_driver_current_lane3_xe14=0x1 +serdes_preemphasis_lane0_xe14=0xa760 +serdes_preemphasis_lane1_xe14=0xa760 +serdes_preemphasis_lane2_xe14=0xa760 +serdes_preemphasis_lane3_xe14=0xa760 + +# xe15 (40G) +portmap_16=61:40 +xgxs_rx_lane_map_16=0x132 +xgxs_tx_lane_map_16=0x213 +phy_xaui_rx_polarity_flip_16=0x0 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_xe15=0x2 +serdes_driver_current_lane1_xe15=0x2 +serdes_driver_current_lane2_xe15=0x2 +serdes_driver_current_lane3_xe15=0x2 +serdes_pre_driver_current_lane0_xe15=0x2 +serdes_pre_driver_current_lane1_xe15=0x2 +serdes_pre_driver_current_lane2_xe15=0x2 +serdes_pre_driver_current_lane3_xe15=0x2 +serdes_preemphasis_lane0_xe15=0xa760 +serdes_preemphasis_lane1_xe15=0xa760 +serdes_preemphasis_lane2_xe15=0xa760 +serdes_preemphasis_lane3_xe15=0xa760 + +# xe16 (40G) +portmap_17=69:40 +xgxs_rx_lane_map_17=0x213 +xgxs_tx_lane_map_17=0x2130 +phy_xaui_rx_polarity_flip_17=0x1 +phy_xaui_tx_polarity_flip_17=0xf +serdes_driver_current_lane0_xe16=0x1 +serdes_driver_current_lane1_xe16=0x1 +serdes_driver_current_lane2_xe16=0x1 +serdes_driver_current_lane3_xe16=0x1 +serdes_pre_driver_current_lane0_xe16=0x1 +serdes_pre_driver_current_lane1_xe16=0x1 +serdes_pre_driver_current_lane2_xe16=0x1 +serdes_pre_driver_current_lane3_xe16=0x1 +serdes_preemphasis_lane0_xe16=0xa760 +serdes_preemphasis_lane1_xe16=0xa760 +serdes_preemphasis_lane2_xe16=0xa760 +serdes_preemphasis_lane3_xe16=0xa760 + +# xe17 (40G) +portmap_18=65:40 +xgxs_rx_lane_map_18=0x132 +xgxs_tx_lane_map_18=0x2031 +phy_xaui_rx_polarity_flip_18=0x3 +phy_xaui_tx_polarity_flip_18=0x9 +serdes_driver_current_lane0_xe17=0x1 +serdes_driver_current_lane1_xe17=0x1 +serdes_driver_current_lane2_xe17=0x1 +serdes_driver_current_lane3_xe17=0x1 +serdes_pre_driver_current_lane0_xe17=0x1 +serdes_pre_driver_current_lane1_xe17=0x1 +serdes_pre_driver_current_lane2_xe17=0x1 +serdes_pre_driver_current_lane3_xe17=0x1 +serdes_preemphasis_lane0_xe17=0xa370 +serdes_preemphasis_lane1_xe17=0xa370 +serdes_preemphasis_lane2_xe17=0xa370 +serdes_preemphasis_lane3_xe17=0xa370 + +# xe18 (40G) +portmap_19=73:40 +xgxs_rx_lane_map_19=0x213 +xgxs_tx_lane_map_19=0x2031 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_xe18=0x2 +serdes_driver_current_lane1_xe18=0x2 +serdes_driver_current_lane2_xe18=0x2 +serdes_driver_current_lane3_xe18=0x2 +serdes_pre_driver_current_lane0_xe18=0x2 +serdes_pre_driver_current_lane1_xe18=0x2 +serdes_pre_driver_current_lane2_xe18=0x2 +serdes_pre_driver_current_lane3_xe18=0x2 +serdes_preemphasis_lane0_xe18=0xa760 +serdes_preemphasis_lane1_xe18=0xa760 +serdes_preemphasis_lane2_xe18=0xa760 +serdes_preemphasis_lane3_xe18=0xa760 + +# xe19 (40G) +portmap_20=77:40 +xgxs_rx_lane_map_20=0x123 +xgxs_tx_lane_map_20=0x1203 +phy_xaui_rx_polarity_flip_20=0x3 +phy_xaui_tx_polarity_flip_20=0xe +serdes_driver_current_lane0_xe19=0x2 +serdes_driver_current_lane1_xe19=0x2 +serdes_driver_current_lane2_xe19=0x2 +serdes_driver_current_lane3_xe19=0x2 +serdes_pre_driver_current_lane0_xe19=0x2 +serdes_pre_driver_current_lane1_xe19=0x2 +serdes_pre_driver_current_lane2_xe19=0x2 +serdes_pre_driver_current_lane3_xe19=0x2 +serdes_preemphasis_lane0_xe19=0xaf40 +serdes_preemphasis_lane1_xe19=0xaf40 +serdes_preemphasis_lane2_xe19=0xaf40 +serdes_preemphasis_lane3_xe19=0xaf40 + +# xe20 (40G) +portmap_21=109:40 +xgxs_rx_lane_map_21=0x132 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0x8 +phy_xaui_tx_polarity_flip_21=0x0 +serdes_driver_current_lane0_xe20=0x1 +serdes_driver_current_lane1_xe20=0x1 +serdes_driver_current_lane2_xe20=0x1 +serdes_driver_current_lane3_xe20=0x2 +serdes_pre_driver_current_lane0_xe20=0x1 +serdes_pre_driver_current_lane1_xe20=0x1 +serdes_pre_driver_current_lane2_xe20=0x1 +serdes_pre_driver_current_lane3_xe20=0x2 +serdes_preemphasis_lane0_xe20=0xb330 +serdes_preemphasis_lane1_xe20=0xb330 +serdes_preemphasis_lane2_xe20=0xb330 +serdes_preemphasis_lane3_xe20=0xbff0 + +# xe21 (40G) +portmap_22=105:40 +xgxs_rx_lane_map_22=0x1320 +xgxs_tx_lane_map_22=0x3021 +phy_xaui_rx_polarity_flip_22=0xd +phy_xaui_tx_polarity_flip_22=0xb +serdes_driver_current_lane0_xe21=0x1 +serdes_driver_current_lane1_xe21=0x1 +serdes_driver_current_lane2_xe21=0x1 +serdes_driver_current_lane3_xe21=0x1 +serdes_pre_driver_current_lane0_xe21=0x1 +serdes_pre_driver_current_lane1_xe21=0x1 +serdes_pre_driver_current_lane2_xe21=0x1 +serdes_pre_driver_current_lane3_xe21=0x1 +serdes_preemphasis_lane0_xe21=0xb330 +serdes_preemphasis_lane1_xe21=0xb330 +serdes_preemphasis_lane2_xe21=0xb330 +serdes_preemphasis_lane3_xe21=0xb330 + +# xe22 (40G) +portmap_23=113:40 +xgxs_rx_lane_map_23=0x132 +xgxs_tx_lane_map_23=0x132 +phy_xaui_rx_polarity_flip_23=0x8 +phy_xaui_tx_polarity_flip_23=0x0 +serdes_driver_current_lane0_xe22=0x1 +serdes_driver_current_lane1_xe22=0x1 +serdes_driver_current_lane2_xe22=0x1 +serdes_driver_current_lane3_xe22=0x1 +serdes_pre_driver_current_lane0_xe22=0x1 +serdes_pre_driver_current_lane1_xe22=0x1 +serdes_pre_driver_current_lane2_xe22=0x1 +serdes_pre_driver_current_lane3_xe22=0x1 +serdes_preemphasis_lane0_xe22=0xbb10 +serdes_preemphasis_lane1_xe22=0xbb10 +serdes_preemphasis_lane2_xe22=0xbb10 +serdes_preemphasis_lane3_xe22=0xc2f0 + +# xe23 (40G) +portmap_24=117:40 +xgxs_rx_lane_map_24=0x231 +xgxs_tx_lane_map_24=0x1203 +phy_xaui_rx_polarity_flip_24=0x3 +phy_xaui_tx_polarity_flip_24=0xe +serdes_driver_current_lane0_xe23=0x3 +serdes_driver_current_lane1_xe23=0x5 +serdes_driver_current_lane2_xe23=0x3 +serdes_driver_current_lane3_xe23=0x3 +serdes_pre_driver_current_lane0_xe23=0x3 +serdes_pre_driver_current_lane1_xe23=0x5 +serdes_pre_driver_current_lane2_xe23=0x3 +serdes_pre_driver_current_lane3_xe23=0x3 +serdes_preemphasis_lane0_xe23=0xc6e0 +serdes_preemphasis_lane1_xe23=0xc6e0 +serdes_preemphasis_lane2_xe23=0xc6e0 +serdes_preemphasis_lane3_xe23=0xc6e0 + +# xe24 (40G) +portmap_25=125:40 +xgxs_rx_lane_map_25=0x132 +xgxs_tx_lane_map_25=0x132 +phy_xaui_rx_polarity_flip_25=0x8 +phy_xaui_tx_polarity_flip_25=0x0 +serdes_driver_current_lane0_xe24=0x4 +serdes_driver_current_lane1_xe24=0x4 +serdes_driver_current_lane2_xe24=0x4 +serdes_driver_current_lane3_xe24=0x4 +serdes_pre_driver_current_lane0_xe24=0x4 +serdes_pre_driver_current_lane1_xe24=0x4 +serdes_pre_driver_current_lane2_xe24=0x4 +serdes_pre_driver_current_lane3_xe24=0x4 +serdes_preemphasis_lane0_xe24=0xc6e0 +serdes_preemphasis_lane1_xe24=0xc6e0 +serdes_preemphasis_lane2_xe24=0xc6e0 +serdes_preemphasis_lane3_xe24=0xcec0 + +# xe25 (40G) +portmap_26=121:40 +xgxs_rx_lane_map_26=0x1320 +xgxs_tx_lane_map_26=0x3021 +phy_xaui_rx_polarity_flip_26=0xd +phy_xaui_tx_polarity_flip_26=0xb +serdes_driver_current_lane0_xe25=0x4 +serdes_driver_current_lane1_xe25=0x4 +serdes_driver_current_lane2_xe25=0x4 +serdes_driver_current_lane3_xe25=0x4 +serdes_pre_driver_current_lane0_xe25=0x4 +serdes_pre_driver_current_lane1_xe25=0x4 +serdes_pre_driver_current_lane2_xe25=0x4 +serdes_pre_driver_current_lane3_xe25=0x4 +serdes_preemphasis_lane0_xe25=0xc6e0 +serdes_preemphasis_lane1_xe25=0xc6e0 +serdes_preemphasis_lane2_xe25=0xc6e0 +serdes_preemphasis_lane3_xe25=0xc6e0 + +# xe26 (40G) +portmap_27=81:40 +xgxs_rx_lane_map_27=0x1320 +xgxs_tx_lane_map_27=0x2031 +phy_xaui_rx_polarity_flip_27=0x1 +phy_xaui_tx_polarity_flip_27=0x2 +serdes_driver_current_lane0_xe26=0x2 +serdes_driver_current_lane1_xe26=0x2 +serdes_driver_current_lane2_xe26=0x2 +serdes_driver_current_lane3_xe26=0x2 +serdes_pre_driver_current_lane0_xe26=0x2 +serdes_pre_driver_current_lane1_xe26=0x2 +serdes_pre_driver_current_lane2_xe26=0x2 +serdes_pre_driver_current_lane3_xe26=0x2 +serdes_preemphasis_lane0_xe26=0xbb10 +serdes_preemphasis_lane1_xe26=0xbb10 +serdes_preemphasis_lane2_xe26=0xbf00 +serdes_preemphasis_lane3_xe26=0xbb10 + +# xe27 (40G) +portmap_28=85:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x1203 +phy_xaui_rx_polarity_flip_28=0xc +phy_xaui_tx_polarity_flip_28=0xe +serdes_driver_current_lane0_xe27=0x4 +serdes_driver_current_lane1_xe27=0x5 +serdes_driver_current_lane2_xe27=0x4 +serdes_driver_current_lane3_xe27=0x5 +serdes_pre_driver_current_lane0_xe27=0x4 +serdes_pre_driver_current_lane1_xe27=0x5 +serdes_pre_driver_current_lane2_xe27=0x4 +serdes_pre_driver_current_lane3_xe27=0x5 +serdes_preemphasis_lane0_xe27=0xc2f0 +serdes_preemphasis_lane1_xe27=0xc6e0 +serdes_preemphasis_lane2_xe27=0xc6e0 +serdes_preemphasis_lane3_xe27=0xc6e0 + +# xe28 (40G) +portmap_29=93:40 +xgxs_rx_lane_map_29=0x1320 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x2 +serdes_driver_current_lane0_xe28=0x4 +serdes_driver_current_lane1_xe28=0x4 +serdes_driver_current_lane2_xe28=0x4 +serdes_driver_current_lane3_xe28=0x4 +serdes_pre_driver_current_lane0_xe28=0x4 +serdes_pre_driver_current_lane1_xe28=0x4 +serdes_pre_driver_current_lane2_xe28=0x4 +serdes_pre_driver_current_lane3_xe28=0x4 +serdes_preemphasis_lane0_xe28=0xc2f0 +serdes_preemphasis_lane1_xe28=0xc2f0 +serdes_preemphasis_lane2_xe28=0xc2f0 +serdes_preemphasis_lane3_xe28=0xc2f0 + +# xe29 (40G) +portmap_30=89:40 +xgxs_rx_lane_map_30=0x1320 +xgxs_tx_lane_map_30=0x3021 +phy_xaui_rx_polarity_flip_30=0x2 +phy_xaui_tx_polarity_flip_30=0xb +serdes_driver_current_lane0_xe29=0x4 +serdes_driver_current_lane1_xe29=0x4 +serdes_driver_current_lane2_xe29=0x4 +serdes_driver_current_lane3_xe29=0x4 +serdes_pre_driver_current_lane0_xe29=0x4 +serdes_pre_driver_current_lane1_xe29=0x4 +serdes_pre_driver_current_lane2_xe29=0x4 +serdes_pre_driver_current_lane3_xe29=0x4 +serdes_preemphasis_lane0_xe29=0xcad0 +serdes_preemphasis_lane1_xe29=0xc6e0 +serdes_preemphasis_lane2_xe29=0xc6e0 +serdes_preemphasis_lane3_xe29=0xc6e0 + +# xe30 (40G) +portmap_31=101:40 +xgxs_rx_lane_map_31=0x1320 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x1 +phy_xaui_tx_polarity_flip_31=0x6 +serdes_driver_current_lane0_xe30=0x6 +serdes_driver_current_lane1_xe30=0x6 +serdes_driver_current_lane2_xe30=0x6 +serdes_driver_current_lane3_xe30=0x7 +serdes_pre_driver_current_lane0_xe30=0x6 +serdes_pre_driver_current_lane1_xe30=0x6 +serdes_pre_driver_current_lane2_xe30=0x6 +serdes_pre_driver_current_lane3_xe30=0x7 +serdes_preemphasis_lane0_xe30=0xcec0 +serdes_preemphasis_lane1_xe30=0xcec0 +serdes_preemphasis_lane2_xe30=0xcad0 +serdes_preemphasis_lane3_xe30=0xc6e0 + +# xe31 (40G) +portmap_32=97:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0xc +phy_xaui_tx_polarity_flip_32=0x3 +serdes_driver_current_lane0_xe31=0x5 +serdes_driver_current_lane1_xe31=0x5 +serdes_driver_current_lane2_xe31=0x5 +serdes_driver_current_lane3_xe31=0x5 +serdes_pre_driver_current_lane0_xe31=0x5 +serdes_pre_driver_current_lane1_xe31=0x5 +serdes_pre_driver_current_lane2_xe31=0x5 +serdes_pre_driver_current_lane3_xe31=0x5 +serdes_preemphasis_lane0_xe31=0xcad0 +serdes_preemphasis_lane1_xe31=0xcad0 +serdes_preemphasis_lane2_xe31=0xcad0 +serdes_preemphasis_lane3_xe31=0xcad0 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers.json.j2 new file mode 100644 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_def.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_def.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_def.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t0.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t1.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/pg_profile_lookup.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/port_config.ini new file mode 100644 index 000000000000..95cf5eec9e4e --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 25,26,27,28 fortyGigE0/0 0 40000 +Ethernet4 29,30,31,32 fortyGigE0/4 1 40000 +Ethernet8 33,34,35,36 fortyGigE0/8 2 40000 +Ethernet12 37,38,39,40 fortyGigE0/12 3 40000 +Ethernet16 45,46,47,48 fortyGigE0/16 4 40000 +Ethernet20 41,42,43,44 fortyGigE0/20 5 40000 +Ethernet24 1,2,3,4 fortyGigE0/24 6 40000 +Ethernet28 5,6,7,8 fortyGigE0/28 7 40000 +Ethernet32 13,14,15,16 fortyGigE0/32 8 40000 +Ethernet36 9,10,11,12 fortyGigE0/36 9 40000 +Ethernet40 17,18,19,20 fortyGigE0/40 10 40000 +Ethernet44 21,22,23,24 fortyGigE0/44 11 40000 +Ethernet48 53,54,55,56 fortyGigE0/48 12 40000 +Ethernet52 49,50,51,52 fortyGigE0/52 13 40000 +Ethernet56 57,58,59,60 fortyGigE0/56 14 40000 +Ethernet60 61,62,63,64 fortyGigE0/60 15 40000 +Ethernet64 69,70,71,72 fortyGigE0/64 16 40000 +Ethernet68 65,66,67,68 fortyGigE0/68 17 40000 +Ethernet72 73,74,75,76 fortyGigE0/72 18 40000 +Ethernet76 77,78,79,80 fortyGigE0/76 19 40000 +Ethernet80 109,110,111,112 fortyGigE0/80 20 40000 +Ethernet84 105,106,107,108 fortyGigE0/84 21 40000 +Ethernet88 113,114,115,116 fortyGigE0/88 22 40000 +Ethernet92 117,118,119,120 fortyGigE0/92 23 40000 +Ethernet96 125,126,127,128 fortyGigE0/96 24 40000 +Ethernet100 121,122,123,124 fortyGigE0/100 25 40000 +Ethernet104 81,82,83,84 fortyGigE0/104 26 40000 +Ethernet108 85,86,87,88 fortyGigE0/108 27 40000 +Ethernet112 93,94,95,96 fortyGigE0/112 28 40000 +Ethernet116 89,90,91,92 fortyGigE0/116 29 40000 +Ethernet120 101,102,103,104 fortyGigE0/120 30 40000 +Ethernet124 97,98,99,100 fortyGigE0/124 31 40000 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/qos.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile new file mode 100644 index 000000000000..bfc466f27e54 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile @@ -0,0 +1,5 @@ +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/td2-s6000-32x40G.config.bcm new file mode 100644 index 000000000000..4c94db7107c7 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/td2-s6000-32x40G.config.bcm @@ -0,0 +1,646 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000007fffffffffffffffffffffffffe +pbmp_xport_xe=0x000007fffffffffffffffffffffffffe + +# Ports configuration +# xe0 (40G) +portmap_1=25:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x2031 +phy_xaui_rx_polarity_flip_1=0xe +phy_xaui_tx_polarity_flip_1=0x2 +serdes_driver_current_lane0_xe0=0x5 +serdes_driver_current_lane1_xe0=0x5 +serdes_driver_current_lane2_xe0=0x5 +serdes_driver_current_lane3_xe0=0x5 +serdes_pre_driver_current_lane0_xe0=0x5 +serdes_pre_driver_current_lane1_xe0=0x5 +serdes_pre_driver_current_lane2_xe0=0x5 +serdes_pre_driver_current_lane3_xe0=0x5 +serdes_preemphasis_lane0_xe0=0xcad0 +serdes_preemphasis_lane1_xe0=0xc6e0 +serdes_preemphasis_lane2_xe0=0xc6e0 +serdes_preemphasis_lane3_xe0=0xd2b0 + +# xe1 (40G) +portmap_2=29:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x213 +phy_xaui_rx_polarity_flip_2=0xc +phy_xaui_tx_polarity_flip_2=0x9 +serdes_driver_current_lane0_xe1=0x6 +serdes_driver_current_lane1_xe1=0x7 +serdes_driver_current_lane2_xe1=0x6 +serdes_driver_current_lane3_xe1=0x6 +serdes_pre_driver_current_lane0_xe1=0x6 +serdes_pre_driver_current_lane1_xe1=0x7 +serdes_pre_driver_current_lane2_xe1=0x6 +serdes_pre_driver_current_lane3_xe1=0x6 +serdes_preemphasis_lane0_xe1=0xc2f0 +serdes_preemphasis_lane1_xe1=0xd2b0 +serdes_preemphasis_lane2_xe1=0xc6e0 +serdes_preemphasis_lane3_xe1=0xc2f0 + +# xe2 (40G) +portmap_3=33:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x132 +phy_xaui_rx_polarity_flip_3=0xe +phy_xaui_tx_polarity_flip_3=0x2 +serdes_driver_current_lane0_xe2=0x4 +serdes_driver_current_lane1_xe2=0x4 +serdes_driver_current_lane2_xe2=0x4 +serdes_driver_current_lane3_xe2=0x4 +serdes_pre_driver_current_lane0_xe2=0x4 +serdes_pre_driver_current_lane1_xe2=0x4 +serdes_pre_driver_current_lane2_xe2=0x4 +serdes_pre_driver_current_lane3_xe2=0x4 +serdes_preemphasis_lane0_xe2=0xc6e0 +serdes_preemphasis_lane1_xe2=0xc6e0 +serdes_preemphasis_lane2_xe2=0xc6e0 +serdes_preemphasis_lane3_xe2=0xc6e0 + +# xe3 (40G) +portmap_4=37:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x1203 +phy_xaui_rx_polarity_flip_4=0x3 +phy_xaui_tx_polarity_flip_4=0xe +serdes_driver_current_lane0_xe3=0x4 +serdes_driver_current_lane1_xe3=0x4 +serdes_driver_current_lane2_xe3=0x4 +serdes_driver_current_lane3_xe3=0x4 +serdes_pre_driver_current_lane0_xe3=0x4 +serdes_pre_driver_current_lane1_xe3=0x4 +serdes_pre_driver_current_lane2_xe3=0x4 +serdes_pre_driver_current_lane3_xe3=0x4 +serdes_preemphasis_lane0_xe3=0xcad0 +serdes_preemphasis_lane1_xe3=0xcad0 +serdes_preemphasis_lane2_xe3=0xc2f0 +serdes_preemphasis_lane3_xe3=0xc2f0 + +# xe4 (40G) +portmap_5=45:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x213 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x8 +serdes_driver_current_lane0_xe4=0x4 +serdes_driver_current_lane1_xe4=0x4 +serdes_driver_current_lane2_xe4=0x4 +serdes_driver_current_lane3_xe4=0x4 +serdes_pre_driver_current_lane0_xe4=0x4 +serdes_pre_driver_current_lane1_xe4=0x4 +serdes_pre_driver_current_lane2_xe4=0x4 +serdes_pre_driver_current_lane3_xe4=0x4 +serdes_preemphasis_lane0_xe4=0xc2f0 +serdes_preemphasis_lane1_xe4=0xc2f0 +serdes_preemphasis_lane2_xe4=0xc2f0 +serdes_preemphasis_lane3_xe4=0xc2f0 + +# xe5 (40G) +portmap_6=41:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x3021 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xb +serdes_driver_current_lane0_xe5=0x4 +serdes_driver_current_lane1_xe5=0x4 +serdes_driver_current_lane2_xe5=0x4 +serdes_driver_current_lane3_xe5=0x4 +serdes_pre_driver_current_lane0_xe5=0x4 +serdes_pre_driver_current_lane1_xe5=0x4 +serdes_pre_driver_current_lane2_xe5=0x4 +serdes_pre_driver_current_lane3_xe5=0x4 +serdes_preemphasis_lane0_xe5=0xc6e0 +serdes_preemphasis_lane1_xe5=0xc2f0 +serdes_preemphasis_lane2_xe5=0xc2f0 +serdes_preemphasis_lane3_xe5=0xcad0 + +# xe6 (40G) +portmap_7=1:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x2031 +phy_xaui_rx_polarity_flip_7=0xe +phy_xaui_tx_polarity_flip_7=0xd +serdes_driver_current_lane0_xe6=0x5 +serdes_driver_current_lane1_xe6=0x5 +serdes_driver_current_lane2_xe6=0x5 +serdes_driver_current_lane3_xe6=0x5 +serdes_pre_driver_current_lane0_xe6=0x5 +serdes_pre_driver_current_lane1_xe6=0x5 +serdes_pre_driver_current_lane2_xe6=0x5 +serdes_pre_driver_current_lane3_xe6=0x5 +serdes_preemphasis_lane0_xe6=0xc6e0 +serdes_preemphasis_lane1_xe6=0xcad0 +serdes_preemphasis_lane2_xe6=0xc6e0 +serdes_preemphasis_lane3_xe6=0xcad0 + +# xe7 (40G) +portmap_8=5:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x1203 +phy_xaui_rx_polarity_flip_8=0xc +phy_xaui_tx_polarity_flip_8=0x1 +serdes_driver_current_lane0_xe7=0x4 +serdes_driver_current_lane1_xe7=0x4 +serdes_driver_current_lane2_xe7=0x4 +serdes_driver_current_lane3_xe7=0x4 +serdes_pre_driver_current_lane0_xe7=0x4 +serdes_pre_driver_current_lane1_xe7=0x4 +serdes_pre_driver_current_lane2_xe7=0x4 +serdes_pre_driver_current_lane3_xe7=0x4 +serdes_preemphasis_lane0_xe7=0xc6e0 +serdes_preemphasis_lane1_xe7=0xc6e0 +serdes_preemphasis_lane2_xe7=0xc6e0 +serdes_preemphasis_lane3_xe7=0xc6e0 + +# xe8 (40G) +portmap_9=13:40 +xgxs_rx_lane_map_9=0x213 +xgxs_tx_lane_map_9=0x132 +phy_xaui_rx_polarity_flip_9=0xe +phy_xaui_tx_polarity_flip_9=0x0 +serdes_driver_current_lane0_xe8=0x2 +serdes_driver_current_lane1_xe8=0x3 +serdes_driver_current_lane2_xe8=0x2 +serdes_driver_current_lane3_xe8=0x2 +serdes_pre_driver_current_lane0_xe8=0x2 +serdes_pre_driver_current_lane1_xe8=0x3 +serdes_pre_driver_current_lane2_xe8=0x2 +serdes_pre_driver_current_lane3_xe8=0x2 +serdes_preemphasis_lane0_xe8=0xb270 +serdes_preemphasis_lane1_xe8=0xbb10 +serdes_preemphasis_lane2_xe8=0xb720 +serdes_preemphasis_lane3_xe8=0xb720 + +# xe9 (40G) +portmap_10=9:40 +xgxs_rx_lane_map_10=0x3120 +xgxs_tx_lane_map_10=0x3021 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x4 +serdes_driver_current_lane0_xe9=0x3 +serdes_driver_current_lane1_xe9=0x3 +serdes_driver_current_lane2_xe9=0x3 +serdes_driver_current_lane3_xe9=0x3 +serdes_pre_driver_current_lane0_xe9=0x3 +serdes_pre_driver_current_lane1_xe9=0x3 +serdes_pre_driver_current_lane2_xe9=0x3 +serdes_pre_driver_current_lane3_xe9=0x3 +serdes_preemphasis_lane0_xe9=0xc2f0 +serdes_preemphasis_lane1_xe9=0xc6e0 +serdes_preemphasis_lane2_xe9=0xbf00 +serdes_preemphasis_lane3_xe9=0xc2f0 + +# xe10 (40G) +portmap_11=17:40 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x132 +phy_xaui_rx_polarity_flip_11=0xe +phy_xaui_tx_polarity_flip_11=0x0 +serdes_driver_current_lane0_xe10=0x2 +serdes_driver_current_lane1_xe10=0x2 +serdes_driver_current_lane2_xe10=0x2 +serdes_driver_current_lane3_xe10=0x2 +serdes_pre_driver_current_lane0_xe10=0x2 +serdes_pre_driver_current_lane1_xe10=0x2 +serdes_pre_driver_current_lane2_xe10=0x2 +serdes_pre_driver_current_lane3_xe10=0x2 +serdes_preemphasis_lane0_xe10=0xb330 +serdes_preemphasis_lane1_xe10=0xbb10 +serdes_preemphasis_lane2_xe10=0xbb10 +serdes_preemphasis_lane3_xe10=0xbb10 + +# xe11 (40G) +portmap_12=21:40 +xgxs_rx_lane_map_12=0x123 +xgxs_tx_lane_map_12=0x1203 +phy_xaui_rx_polarity_flip_12=0xc +phy_xaui_tx_polarity_flip_12=0xe +serdes_driver_current_lane0_xe11=0x2 +serdes_driver_current_lane1_xe11=0x2 +serdes_driver_current_lane2_xe11=0x2 +serdes_driver_current_lane3_xe11=0x2 +serdes_pre_driver_current_lane0_xe11=0x2 +serdes_pre_driver_current_lane1_xe11=0x2 +serdes_pre_driver_current_lane2_xe11=0x2 +serdes_pre_driver_current_lane3_xe11=0x2 +serdes_preemphasis_lane0_xe11=0xb330 +serdes_preemphasis_lane1_xe11=0xb330 +serdes_preemphasis_lane2_xe11=0xb330 +serdes_preemphasis_lane3_xe11=0xb330 + +# xe12 (40G) +portmap_13=53:40 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x231 +phy_xaui_rx_polarity_flip_13=0x1 +phy_xaui_tx_polarity_flip_13=0x0 +serdes_driver_current_lane0_xe12=0x2 +serdes_driver_current_lane1_xe12=0x2 +serdes_driver_current_lane2_xe12=0x2 +serdes_driver_current_lane3_xe12=0x2 +serdes_pre_driver_current_lane0_xe12=0x2 +serdes_pre_driver_current_lane1_xe12=0x2 +serdes_pre_driver_current_lane2_xe12=0x2 +serdes_pre_driver_current_lane3_xe12=0x2 +serdes_preemphasis_lane0_xe12=0xaf40 +serdes_preemphasis_lane1_xe12=0xaf40 +serdes_preemphasis_lane2_xe12=0xaf40 +serdes_preemphasis_lane3_xe12=0xaf40 + +# xe13 (40G) +portmap_14=49:40 +xgxs_rx_lane_map_14=0x1302 +xgxs_tx_lane_map_14=0x2031 +phy_xaui_rx_polarity_flip_14=0xb +phy_xaui_tx_polarity_flip_14=0x3 +serdes_driver_current_lane0_xe13=0x2 +serdes_driver_current_lane1_xe13=0x2 +serdes_driver_current_lane2_xe13=0x2 +serdes_driver_current_lane3_xe13=0x2 +serdes_pre_driver_current_lane0_xe13=0x2 +serdes_pre_driver_current_lane1_xe13=0x2 +serdes_pre_driver_current_lane2_xe13=0x2 +serdes_pre_driver_current_lane3_xe13=0x2 +serdes_preemphasis_lane0_xe13=0xa760 +serdes_preemphasis_lane1_xe13=0xa760 +serdes_preemphasis_lane2_xe13=0xa760 +serdes_preemphasis_lane3_xe13=0xa760 + +# xe14 (40G) +portmap_15=57:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x2031 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_xe14=0x1 +serdes_driver_current_lane1_xe14=0x1 +serdes_driver_current_lane2_xe14=0x1 +serdes_driver_current_lane3_xe14=0x1 +serdes_pre_driver_current_lane0_xe14=0x1 +serdes_pre_driver_current_lane1_xe14=0x1 +serdes_pre_driver_current_lane2_xe14=0x1 +serdes_pre_driver_current_lane3_xe14=0x1 +serdes_preemphasis_lane0_xe14=0xa760 +serdes_preemphasis_lane1_xe14=0xa760 +serdes_preemphasis_lane2_xe14=0xa760 +serdes_preemphasis_lane3_xe14=0xa760 + +# xe15 (40G) +portmap_16=61:40 +xgxs_rx_lane_map_16=0x132 +xgxs_tx_lane_map_16=0x213 +phy_xaui_rx_polarity_flip_16=0x0 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_xe15=0x2 +serdes_driver_current_lane1_xe15=0x2 +serdes_driver_current_lane2_xe15=0x2 +serdes_driver_current_lane3_xe15=0x2 +serdes_pre_driver_current_lane0_xe15=0x2 +serdes_pre_driver_current_lane1_xe15=0x2 +serdes_pre_driver_current_lane2_xe15=0x2 +serdes_pre_driver_current_lane3_xe15=0x2 +serdes_preemphasis_lane0_xe15=0xa760 +serdes_preemphasis_lane1_xe15=0xa760 +serdes_preemphasis_lane2_xe15=0xa760 +serdes_preemphasis_lane3_xe15=0xa760 + +# xe16 (40G) +portmap_17=69:40 +xgxs_rx_lane_map_17=0x213 +xgxs_tx_lane_map_17=0x2130 +phy_xaui_rx_polarity_flip_17=0x1 +phy_xaui_tx_polarity_flip_17=0xf +serdes_driver_current_lane0_xe16=0x1 +serdes_driver_current_lane1_xe16=0x1 +serdes_driver_current_lane2_xe16=0x1 +serdes_driver_current_lane3_xe16=0x1 +serdes_pre_driver_current_lane0_xe16=0x1 +serdes_pre_driver_current_lane1_xe16=0x1 +serdes_pre_driver_current_lane2_xe16=0x1 +serdes_pre_driver_current_lane3_xe16=0x1 +serdes_preemphasis_lane0_xe16=0xa760 +serdes_preemphasis_lane1_xe16=0xa760 +serdes_preemphasis_lane2_xe16=0xa760 +serdes_preemphasis_lane3_xe16=0xa760 + +# xe17 (40G) +portmap_18=65:40 +xgxs_rx_lane_map_18=0x132 +xgxs_tx_lane_map_18=0x2031 +phy_xaui_rx_polarity_flip_18=0x3 +phy_xaui_tx_polarity_flip_18=0x9 +serdes_driver_current_lane0_xe17=0x1 +serdes_driver_current_lane1_xe17=0x1 +serdes_driver_current_lane2_xe17=0x1 +serdes_driver_current_lane3_xe17=0x1 +serdes_pre_driver_current_lane0_xe17=0x1 +serdes_pre_driver_current_lane1_xe17=0x1 +serdes_pre_driver_current_lane2_xe17=0x1 +serdes_pre_driver_current_lane3_xe17=0x1 +serdes_preemphasis_lane0_xe17=0xa370 +serdes_preemphasis_lane1_xe17=0xa370 +serdes_preemphasis_lane2_xe17=0xa370 +serdes_preemphasis_lane3_xe17=0xa370 + +# xe18 (40G) +portmap_19=73:40 +xgxs_rx_lane_map_19=0x213 +xgxs_tx_lane_map_19=0x2031 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_xe18=0x2 +serdes_driver_current_lane1_xe18=0x2 +serdes_driver_current_lane2_xe18=0x2 +serdes_driver_current_lane3_xe18=0x2 +serdes_pre_driver_current_lane0_xe18=0x2 +serdes_pre_driver_current_lane1_xe18=0x2 +serdes_pre_driver_current_lane2_xe18=0x2 +serdes_pre_driver_current_lane3_xe18=0x2 +serdes_preemphasis_lane0_xe18=0xa760 +serdes_preemphasis_lane1_xe18=0xa760 +serdes_preemphasis_lane2_xe18=0xa760 +serdes_preemphasis_lane3_xe18=0xa760 + +# xe19 (40G) +portmap_20=77:40 +xgxs_rx_lane_map_20=0x123 +xgxs_tx_lane_map_20=0x1203 +phy_xaui_rx_polarity_flip_20=0x3 +phy_xaui_tx_polarity_flip_20=0xe +serdes_driver_current_lane0_xe19=0x2 +serdes_driver_current_lane1_xe19=0x2 +serdes_driver_current_lane2_xe19=0x2 +serdes_driver_current_lane3_xe19=0x2 +serdes_pre_driver_current_lane0_xe19=0x2 +serdes_pre_driver_current_lane1_xe19=0x2 +serdes_pre_driver_current_lane2_xe19=0x2 +serdes_pre_driver_current_lane3_xe19=0x2 +serdes_preemphasis_lane0_xe19=0xaf40 +serdes_preemphasis_lane1_xe19=0xaf40 +serdes_preemphasis_lane2_xe19=0xaf40 +serdes_preemphasis_lane3_xe19=0xaf40 + +# xe20 (40G) +portmap_21=109:40 +xgxs_rx_lane_map_21=0x132 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0x8 +phy_xaui_tx_polarity_flip_21=0x0 +serdes_driver_current_lane0_xe20=0x1 +serdes_driver_current_lane1_xe20=0x1 +serdes_driver_current_lane2_xe20=0x1 +serdes_driver_current_lane3_xe20=0x2 +serdes_pre_driver_current_lane0_xe20=0x1 +serdes_pre_driver_current_lane1_xe20=0x1 +serdes_pre_driver_current_lane2_xe20=0x1 +serdes_pre_driver_current_lane3_xe20=0x2 +serdes_preemphasis_lane0_xe20=0xb330 +serdes_preemphasis_lane1_xe20=0xb330 +serdes_preemphasis_lane2_xe20=0xb330 +serdes_preemphasis_lane3_xe20=0xbff0 + +# xe21 (40G) +portmap_22=105:40 +xgxs_rx_lane_map_22=0x1320 +xgxs_tx_lane_map_22=0x3021 +phy_xaui_rx_polarity_flip_22=0xd +phy_xaui_tx_polarity_flip_22=0xb +serdes_driver_current_lane0_xe21=0x1 +serdes_driver_current_lane1_xe21=0x1 +serdes_driver_current_lane2_xe21=0x1 +serdes_driver_current_lane3_xe21=0x1 +serdes_pre_driver_current_lane0_xe21=0x1 +serdes_pre_driver_current_lane1_xe21=0x1 +serdes_pre_driver_current_lane2_xe21=0x1 +serdes_pre_driver_current_lane3_xe21=0x1 +serdes_preemphasis_lane0_xe21=0xb330 +serdes_preemphasis_lane1_xe21=0xb330 +serdes_preemphasis_lane2_xe21=0xb330 +serdes_preemphasis_lane3_xe21=0xb330 + +# xe22 (40G) +portmap_23=113:40 +xgxs_rx_lane_map_23=0x132 +xgxs_tx_lane_map_23=0x132 +phy_xaui_rx_polarity_flip_23=0x8 +phy_xaui_tx_polarity_flip_23=0x0 +serdes_driver_current_lane0_xe22=0x1 +serdes_driver_current_lane1_xe22=0x1 +serdes_driver_current_lane2_xe22=0x1 +serdes_driver_current_lane3_xe22=0x1 +serdes_pre_driver_current_lane0_xe22=0x1 +serdes_pre_driver_current_lane1_xe22=0x1 +serdes_pre_driver_current_lane2_xe22=0x1 +serdes_pre_driver_current_lane3_xe22=0x1 +serdes_preemphasis_lane0_xe22=0xbb10 +serdes_preemphasis_lane1_xe22=0xbb10 +serdes_preemphasis_lane2_xe22=0xbb10 +serdes_preemphasis_lane3_xe22=0xc2f0 + +# xe23 (40G) +portmap_24=117:40 +xgxs_rx_lane_map_24=0x231 +xgxs_tx_lane_map_24=0x1203 +phy_xaui_rx_polarity_flip_24=0x3 +phy_xaui_tx_polarity_flip_24=0xe +serdes_driver_current_lane0_xe23=0x3 +serdes_driver_current_lane1_xe23=0x5 +serdes_driver_current_lane2_xe23=0x3 +serdes_driver_current_lane3_xe23=0x3 +serdes_pre_driver_current_lane0_xe23=0x3 +serdes_pre_driver_current_lane1_xe23=0x5 +serdes_pre_driver_current_lane2_xe23=0x3 +serdes_pre_driver_current_lane3_xe23=0x3 +serdes_preemphasis_lane0_xe23=0xc6e0 +serdes_preemphasis_lane1_xe23=0xc6e0 +serdes_preemphasis_lane2_xe23=0xc6e0 +serdes_preemphasis_lane3_xe23=0xc6e0 + +# xe24 (40G) +portmap_25=125:40 +xgxs_rx_lane_map_25=0x132 +xgxs_tx_lane_map_25=0x132 +phy_xaui_rx_polarity_flip_25=0x8 +phy_xaui_tx_polarity_flip_25=0x0 +serdes_driver_current_lane0_xe24=0x4 +serdes_driver_current_lane1_xe24=0x4 +serdes_driver_current_lane2_xe24=0x4 +serdes_driver_current_lane3_xe24=0x4 +serdes_pre_driver_current_lane0_xe24=0x4 +serdes_pre_driver_current_lane1_xe24=0x4 +serdes_pre_driver_current_lane2_xe24=0x4 +serdes_pre_driver_current_lane3_xe24=0x4 +serdes_preemphasis_lane0_xe24=0xc6e0 +serdes_preemphasis_lane1_xe24=0xc6e0 +serdes_preemphasis_lane2_xe24=0xc6e0 +serdes_preemphasis_lane3_xe24=0xcec0 + +# xe25 (40G) +portmap_26=121:40 +xgxs_rx_lane_map_26=0x1320 +xgxs_tx_lane_map_26=0x3021 +phy_xaui_rx_polarity_flip_26=0xd +phy_xaui_tx_polarity_flip_26=0xb +serdes_driver_current_lane0_xe25=0x4 +serdes_driver_current_lane1_xe25=0x4 +serdes_driver_current_lane2_xe25=0x4 +serdes_driver_current_lane3_xe25=0x4 +serdes_pre_driver_current_lane0_xe25=0x4 +serdes_pre_driver_current_lane1_xe25=0x4 +serdes_pre_driver_current_lane2_xe25=0x4 +serdes_pre_driver_current_lane3_xe25=0x4 +serdes_preemphasis_lane0_xe25=0xc6e0 +serdes_preemphasis_lane1_xe25=0xc6e0 +serdes_preemphasis_lane2_xe25=0xc6e0 +serdes_preemphasis_lane3_xe25=0xc6e0 + +# xe26 (40G) +portmap_27=81:40 +xgxs_rx_lane_map_27=0x1320 +xgxs_tx_lane_map_27=0x2031 +phy_xaui_rx_polarity_flip_27=0x1 +phy_xaui_tx_polarity_flip_27=0x2 +serdes_driver_current_lane0_xe26=0x2 +serdes_driver_current_lane1_xe26=0x2 +serdes_driver_current_lane2_xe26=0x2 +serdes_driver_current_lane3_xe26=0x2 +serdes_pre_driver_current_lane0_xe26=0x2 +serdes_pre_driver_current_lane1_xe26=0x2 +serdes_pre_driver_current_lane2_xe26=0x2 +serdes_pre_driver_current_lane3_xe26=0x2 +serdes_preemphasis_lane0_xe26=0xbb10 +serdes_preemphasis_lane1_xe26=0xbb10 +serdes_preemphasis_lane2_xe26=0xbf00 +serdes_preemphasis_lane3_xe26=0xbb10 + +# xe27 (40G) +portmap_28=85:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x1203 +phy_xaui_rx_polarity_flip_28=0xc +phy_xaui_tx_polarity_flip_28=0xe +serdes_driver_current_lane0_xe27=0x4 +serdes_driver_current_lane1_xe27=0x5 +serdes_driver_current_lane2_xe27=0x4 +serdes_driver_current_lane3_xe27=0x5 +serdes_pre_driver_current_lane0_xe27=0x4 +serdes_pre_driver_current_lane1_xe27=0x5 +serdes_pre_driver_current_lane2_xe27=0x4 +serdes_pre_driver_current_lane3_xe27=0x5 +serdes_preemphasis_lane0_xe27=0xc2f0 +serdes_preemphasis_lane1_xe27=0xc6e0 +serdes_preemphasis_lane2_xe27=0xc6e0 +serdes_preemphasis_lane3_xe27=0xc6e0 + +# xe28 (40G) +portmap_29=93:40 +xgxs_rx_lane_map_29=0x1320 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x2 +serdes_driver_current_lane0_xe28=0x4 +serdes_driver_current_lane1_xe28=0x4 +serdes_driver_current_lane2_xe28=0x4 +serdes_driver_current_lane3_xe28=0x4 +serdes_pre_driver_current_lane0_xe28=0x4 +serdes_pre_driver_current_lane1_xe28=0x4 +serdes_pre_driver_current_lane2_xe28=0x4 +serdes_pre_driver_current_lane3_xe28=0x4 +serdes_preemphasis_lane0_xe28=0xc2f0 +serdes_preemphasis_lane1_xe28=0xc2f0 +serdes_preemphasis_lane2_xe28=0xc2f0 +serdes_preemphasis_lane3_xe28=0xc2f0 + +# xe29 (40G) +portmap_30=89:40 +xgxs_rx_lane_map_30=0x1320 +xgxs_tx_lane_map_30=0x3021 +phy_xaui_rx_polarity_flip_30=0x2 +phy_xaui_tx_polarity_flip_30=0xb +serdes_driver_current_lane0_xe29=0x4 +serdes_driver_current_lane1_xe29=0x4 +serdes_driver_current_lane2_xe29=0x4 +serdes_driver_current_lane3_xe29=0x4 +serdes_pre_driver_current_lane0_xe29=0x4 +serdes_pre_driver_current_lane1_xe29=0x4 +serdes_pre_driver_current_lane2_xe29=0x4 +serdes_pre_driver_current_lane3_xe29=0x4 +serdes_preemphasis_lane0_xe29=0xcad0 +serdes_preemphasis_lane1_xe29=0xc6e0 +serdes_preemphasis_lane2_xe29=0xc6e0 +serdes_preemphasis_lane3_xe29=0xc6e0 + +# xe30 (40G) +portmap_31=101:40 +xgxs_rx_lane_map_31=0x1320 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x1 +phy_xaui_tx_polarity_flip_31=0x6 +serdes_driver_current_lane0_xe30=0x6 +serdes_driver_current_lane1_xe30=0x6 +serdes_driver_current_lane2_xe30=0x6 +serdes_driver_current_lane3_xe30=0x7 +serdes_pre_driver_current_lane0_xe30=0x6 +serdes_pre_driver_current_lane1_xe30=0x6 +serdes_pre_driver_current_lane2_xe30=0x6 +serdes_pre_driver_current_lane3_xe30=0x7 +serdes_preemphasis_lane0_xe30=0xcec0 +serdes_preemphasis_lane1_xe30=0xcec0 +serdes_preemphasis_lane2_xe30=0xcad0 +serdes_preemphasis_lane3_xe30=0xc6e0 + +# xe31 (40G) +portmap_32=97:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0xc +phy_xaui_tx_polarity_flip_32=0x3 +serdes_driver_current_lane0_xe31=0x5 +serdes_driver_current_lane1_xe31=0x5 +serdes_driver_current_lane2_xe31=0x5 +serdes_driver_current_lane3_xe31=0x5 +serdes_pre_driver_current_lane0_xe31=0x5 +serdes_pre_driver_current_lane1_xe31=0x5 +serdes_pre_driver_current_lane2_xe31=0x5 +serdes_pre_driver_current_lane3_xe31=0x5 +serdes_preemphasis_lane0_xe31=0xcad0 +serdes_preemphasis_lane1_xe31=0xcad0 +serdes_preemphasis_lane2_xe31=0xcad0 +serdes_preemphasis_lane3_xe31=0xcad0 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh new file mode 100755 index 000000000000..cf70f3063189 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh @@ -0,0 +1,82 @@ +#!/bin/bash +#topolgy script for 6 ASIC PLATFORM +FIRST_FRONTEND_ASIC=0 +LAST_FRONTEND_ASIC=3 +FIRST_BACKEND_ASIC=4 +LAST_BACKEND_ASIC=5 +NUM_INTERFACES_PER_ASIC=32 + +start () { + # Move external links into assigned frontend namespaces + # eth0 - eth15: asic2 + # eth16 - eth31: asic3 + # eth32 - eth47: asic4 + # eth48 - eth63: asic5 + for ASIC in `seq $FIRST_FRONTEND_ASIC $LAST_FRONTEND_ASIC`; do + for NUM in `seq 1 16`; do + ORIG="eth$((16 * $ASIC + $NUM))" + TEMP="ethTemp999" + NEW="eth$(($NUM))" + echo "$ASIC : $NEW old $ORIG" + ip link set dev $ORIG down + ip link set dev $ORIG name $TEMP # rename to prevent conflicts before renaming in new namespace + ip link set dev $TEMP netns asic$ASIC + sudo ip netns exec asic$ASIC ip link set $TEMP name $NEW # rename to final interface name + sudo ip netns exec asic$ASIC ip link set $NEW up + done + done + + # Connect all backend namespaces to frontend namespaces + for BACKEND in `seq $FIRST_BACKEND_ASIC $LAST_BACKEND_ASIC`; do + for FRONTEND in `seq $FIRST_FRONTEND_ASIC $LAST_FRONTEND_ASIC`; do + for LINK in `seq 1 8`; do + FRONT_NAME="eth$((8 * $(($BACKEND - $FIRST_BACKEND_ASIC)) + $LINK + 16))" + BACK_NAME="eth$((8 * $FRONTEND + $LINK))" + echo "$FRONTEND:$FRONT_NAME - $BACKEND:$BACK_NAME" + TEMP_BACK="ethBack999" + TEMP_FRONT="ethFront999" + + ip link add $TEMP_BACK type veth peer name $TEMP_FRONT # temporary name to prevent conflicts between interfaces + ip link set dev $TEMP_BACK netns asic$BACKEND + ip link set dev $TEMP_FRONT netns asic$FRONTEND + + sudo ip netns exec asic$BACKEND ip link set $TEMP_BACK name $BACK_NAME + sudo ip netns exec asic$FRONTEND ip link set $TEMP_FRONT name $FRONT_NAME + + sudo ip netns exec asic$BACKEND ip link set $BACK_NAME up + sudo ip netns exec asic$FRONTEND ip link set $FRONT_NAME up + done + done + done +} + +stop() { + for ASIC in `seq $FIRST_FRONTEND_ASIC $LAST_FRONTEND_ASIC`; do + for NUM in `seq 1 16`; do + TEMP="eth999" + OLD="eth$((16 * $ASIC + $NUM))" + NAME="eth$((16 * $ASIC + $NUM - 1))" + sudo ip netns exec asic$ASIC ip link set dev $OLD down + sudo ip netns exec asic$ASIC ip link set dev $OLD name $TEMP + sudo ip netns exec asic$ASIC ip link set dev $TEMP netns 1 + ip link set dev $TEMP name $NAME + ip link set dev $NAME up + done + done + + for ASIC in `seq $FIRST_BACKEND_ASIC $LAST_BACKEND_ASIC`; do + for NUM in `seq 1 $NUM_INTERFACES_PER_ASIC`; do + sudo ip netns exec asic$ASIC ip link set dev eth$NUM down + sudo ip netns exec asic$ASIC ip link delete dev eth$NUM + done + done +} + +case "$1" in + start|stop) + $1 + ;; + *) + echo "Usage: $0 {start|stop}" + ;; +esac diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index d8188a06afd6..dea58a210f89 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -34,7 +34,7 @@ COPY ["sources.list.arm64", "/etc/apt/sources.list"] COPY ["sources.list", "/etc/apt/sources.list"] {% endif %} COPY ["no_install_recommend_suggest", "/etc/apt/apt.conf.d"] -COPY ["aptconf_archive_expired_release", "/etc/apt/apt.conf.d"] +COPY ["no-check-valid-until", "/etc/apt/apt.conf.d"] # Update apt cache and # pre-install fundamental packages diff --git a/dockers/docker-base-stretch/aptconf_archive_expired_release b/dockers/docker-base-stretch/aptconf_archive_expired_release deleted file mode 100644 index 67bc409b2174..000000000000 --- a/dockers/docker-base-stretch/aptconf_archive_expired_release +++ /dev/null @@ -1,3 +0,0 @@ -# Instruct apt-get to override expired releases repo list for jessie archives - -Acquire::Check-Valid-Until "0"; diff --git a/dockers/docker-base-stretch/dpkg_01_drop b/dockers/docker-base-stretch/dpkg_01_drop index e75ef3147158..d749943797d9 100644 --- a/dockers/docker-base-stretch/dpkg_01_drop +++ b/dockers/docker-base-stretch/dpkg_01_drop @@ -20,3 +20,11 @@ path-exclude /usr/share/pyshared/twisted/test* path-exclude /usr/lib/python*/dist-packages/twisted/test* path-exclude /usr/share/pyshared/twisted/*/test* path-exclude /usr/lib/python*/dist-packages/twisted/*/test* + +## install the configuration file if it’s currently missing +force-confmiss +## combined with confold: overwrite configuration files that you have not modified +force-confdef +## do not modify the current configuration file, the new version is installed with a .dpkg-dist suffix +force-confold + diff --git a/dockers/docker-base-stretch/no-check-valid-until b/dockers/docker-base-stretch/no-check-valid-until new file mode 100644 index 000000000000..c7c25d017f7f --- /dev/null +++ b/dockers/docker-base-stretch/no-check-valid-until @@ -0,0 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + +Acquire::Check-Valid-Until "false"; diff --git a/dockers/docker-base/Dockerfile.j2 b/dockers/docker-base/Dockerfile.j2 index cb2ff80186a3..e45235a1e139 100644 --- a/dockers/docker-base/Dockerfile.j2 +++ b/dockers/docker-base/Dockerfile.j2 @@ -32,7 +32,7 @@ COPY ["dpkg_01_drop", "/etc/dpkg/dpkg.cfg.d/01_drop"] COPY ["sources.list.armhf", "/etc/apt/sources.list"] {% elif CONFIGURED_ARCH == "arm64" %} COPY ["sources.list.arm64", "/etc/apt/sources.list"] -COPY ["aptconf_archive_expired_release", "/etc/apt/apt.conf.d"] +COPY ["no-check-valid-until", "/etc/apt/apt.conf.d"] {% else %} COPY ["sources.list", "/etc/apt/sources.list"] {% endif %} diff --git a/dockers/docker-base/aptconf_archive_expired_release b/dockers/docker-base/aptconf_archive_expired_release deleted file mode 100644 index 67bc409b2174..000000000000 --- a/dockers/docker-base/aptconf_archive_expired_release +++ /dev/null @@ -1,3 +0,0 @@ -# Instruct apt-get to override expired releases repo list for jessie archives - -Acquire::Check-Valid-Until "0"; diff --git a/dockers/docker-base/dpkg_01_drop b/dockers/docker-base/dpkg_01_drop index e75ef3147158..d749943797d9 100644 --- a/dockers/docker-base/dpkg_01_drop +++ b/dockers/docker-base/dpkg_01_drop @@ -20,3 +20,11 @@ path-exclude /usr/share/pyshared/twisted/test* path-exclude /usr/lib/python*/dist-packages/twisted/test* path-exclude /usr/share/pyshared/twisted/*/test* path-exclude /usr/lib/python*/dist-packages/twisted/*/test* + +## install the configuration file if it’s currently missing +force-confmiss +## combined with confold: overwrite configuration files that you have not modified +force-confdef +## do not modify the current configuration file, the new version is installed with a .dpkg-dist suffix +force-confold + diff --git a/dockers/docker-base/no-check-valid-until b/dockers/docker-base/no-check-valid-until new file mode 100644 index 000000000000..c7c25d017f7f --- /dev/null +++ b/dockers/docker-base/no-check-valid-until @@ -0,0 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + +Acquire::Check-Valid-Until "false"; diff --git a/dockers/docker-database/Dockerfile.j2 b/dockers/docker-database/Dockerfile.j2 index acb5e013fb84..8cd181614672 100644 --- a/dockers/docker-database/Dockerfile.j2 +++ b/dockers/docker-database/Dockerfile.j2 @@ -36,5 +36,7 @@ COPY ["supervisord.conf.j2", "/usr/share/sonic/templates/"] COPY ["docker-database-init.sh", "/usr/local/bin/"] COPY ["ping_pong_db_insts", "/usr/local/bin/"] COPY ["database_config.json", "/etc/default/sonic-db/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/local/bin/docker-database-init.sh"] diff --git a/dockers/docker-database/base_image_files/monit_database b/dockers/docker-database/base_image_files/monit_database new file mode 100644 index 000000000000..c5508922864e --- /dev/null +++ b/dockers/docker-database/base_image_files/monit_database @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for database container +## process list: +## redis_server +############################################################################### +check process redis_server matching "/usr/bin/redis-server" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-database/critical_processes b/dockers/docker-database/critical_processes new file mode 100644 index 000000000000..7800f0fad3ff --- /dev/null +++ b/dockers/docker-database/critical_processes @@ -0,0 +1 @@ +redis diff --git a/dockers/docker-database/supervisord.conf.j2 b/dockers/docker-database/supervisord.conf.j2 index 110619f762be..9e855527edba 100644 --- a/dockers/docker-database/supervisord.conf.j2 +++ b/dockers/docker-database/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 --container-name database +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:rsyslogd] command=/bin/bash -c "rm -f /var/run/rsyslogd.pid && /usr/sbin/rsyslogd -n" priority=1 diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 index e738e8699e6c..d52400480775 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name dhcp_relay events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected @@ -85,5 +85,53 @@ stderr_logfile=syslog {% endif %} {% endif %} {% endfor %} + +[group:dhcpmon] +programs= +{%- set add_preceding_comma = { 'flag': False } %} +{% for vlan_name in VLAN %} +{% if VLAN[vlan_name]['dhcp_servers'] %} +{% if add_preceding_comma.flag %},{% endif %} +{% set _dummy = add_preceding_comma.update({'flag': True}) %} +dhcpmon-{{ vlan_name }} +{%- endif %} +{% endfor %} + + +{# Create a program entry for each DHCP MONitor instance #} +{% set relay_for_ipv4 = { 'flag': False } %} +{% for vlan_name in VLAN %} +{% if VLAN[vlan_name]['dhcp_servers'] %} +{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %} +{% if dhcp_server | ipv4 %} +{% set _dummy = relay_for_ipv4.update({'flag': True}) %} +{% endif %} +{% endfor %} +{% if relay_for_ipv4.flag %} +{% set _dummy = relay_for_ipv4.update({'flag': False}) %} +[program:dhcpmon-{{ vlan_name }}] +{# We treat this VLAN as a downstream interface (-id), as we only want to listen for requests #} +command=/usr/sbin/dhcpmon -id {{ vlan_name }} +{#- We treat all other interfaces as upstream interfaces (-iu), as we only want to listen for replies #} +{% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} +{% if prefix | ipv4 and name != vlan_name %} -iu {{ name }}{% endif -%} +{% endfor %} +{% for (name, prefix) in INTERFACE|pfx_filter %} +{% if prefix | ipv4 %} -iu {{ name }}{% endif -%} +{% endfor %} +{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %} +{% if prefix | ipv4 %} -iu {{ name }}{% endif -%} +{% endfor %} + +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +{% endif %} +{% endif %} +{% endfor %} + {% endif %} {% endif %} diff --git a/dockers/docker-dhcp-relay/start.sh b/dockers/docker-dhcp-relay/start.sh index 0ac5ea1a10ec..dbbf32251080 100755 --- a/dockers/docker-dhcp-relay/start.sh +++ b/dockers/docker-dhcp-relay/start.sh @@ -19,3 +19,9 @@ if [ $(supervisorctl status | grep -c "^isc-dhcp-relay:") -gt 0 ]; then # Start all DHCP relay agent(s) supervisorctl start isc-dhcp-relay:* fi + +# If our supervisor config has entries in the "dhcpmon" group... +if [ $(supervisorctl status | grep -c "^dhcpmon:") -gt 0 ]; then + # Start all DHCP Monitor daemon(s) + supervisorctl start dhcpmon:* +fi diff --git a/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 b/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 index 0488799a4c81..568f128b3772 100644 --- a/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 +++ b/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 @@ -1,7 +1,5 @@ #!/usr/bin/env bash -STATE_DB_IDX="6" - function wait_until_iface_ready { IFACE_NAME=$1 @@ -12,7 +10,7 @@ function wait_until_iface_ready # Wait for the interface to come up # (i.e., interface is present in STATE_DB and state is "ok") while true; do - RESULT=$(redis-cli -n ${STATE_DB_IDX} HGET "INTERFACE_TABLE|${IFACE_NAME}|${IFACE_CIDR}" "state" 2> /dev/null) + RESULT=$(sonic-db-cli STATE_DB HGET "INTERFACE_TABLE|${IFACE_NAME}|${IFACE_CIDR}" "state" 2> /dev/null) if [ x"$RESULT" == x"ok" ]; then break fi diff --git a/dockers/docker-fpm-frr/Dockerfile.j2 b/dockers/docker-fpm-frr/Dockerfile.j2 index 418676c18329..1c670682a342 100644 --- a/dockers/docker-fpm-frr/Dockerfile.j2 +++ b/dockers/docker-fpm-frr/Dockerfile.j2 @@ -50,6 +50,8 @@ COPY ["snmp.conf", "/etc/snmp/frr.conf"] COPY ["TSA", "/usr/bin/TSA"] COPY ["TSB", "/usr/bin/TSB"] COPY ["TSC", "/usr/bin/TSC"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] RUN chmod a+x /usr/bin/TSA && \ chmod a+x /usr/bin/TSB && \ chmod a+x /usr/bin/TSC diff --git a/dockers/docker-fpm-frr/base_image_files/monit_bgp b/dockers/docker-fpm-frr/base_image_files/monit_bgp new file mode 100644 index 000000000000..5b943ea7c0bb --- /dev/null +++ b/dockers/docker-fpm-frr/base_image_files/monit_bgp @@ -0,0 +1,23 @@ +############################################################################### +## Monit configuration for BGP container +## process list: +## zebra +## fpmsyncd +## bgpd +## staticd +## bgpcfgd +############################################################################### +check process zebra matching "/usr/lib/frr/zebra" + if does not exist for 5 times within 5 cycles then alert + +check process fpmsyncd matching "fpmsyncd" + if does not exist for 5 times within 5 cycles then alert + +check process bgpd matching "/usr/lib/frr/bgpd" + if does not exist for 5 times within 5 cycles then alert + +check process staticd matching "/usr/lib/frr/staticd" + if does not exist for 5 times within 5 cycles then alert + +check process bgpcfgd matching "python /usr/bin/bgpcfgd" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-fpm-frr/bgpcfgd b/dockers/docker-fpm-frr/bgpcfgd index 4211f49d2272..4e638def47b7 100755 --- a/dockers/docker-fpm-frr/bgpcfgd +++ b/dockers/docker-fpm-frr/bgpcfgd @@ -86,9 +86,10 @@ class Daemon(object): self.callbacks = defaultdict(lambda : defaultdict(list)) # db -> table -> [] self.subscribers = set() - def add_manager(self, db, table_name, callback): + def add_manager(self, db_name, table_name, callback): + db = swsscommon.SonicDBConfig.getDbId(db_name) if db not in self.db_connectors: - self.db_connectors[db] = swsscommon.DBConnector(db, swsscommon.DBConnector.DEFAULT_UNIXSOCKET, 0) + self.db_connectors[db] = swsscommon.DBConnector(db_name, 0) if table_name not in self.callbacks[db]: conn = self.db_connectors[db] @@ -203,6 +204,8 @@ class Manager(object): syslog.syslog(syslog.LOG_ERR, 'Invalid operation "%s" for key "%s"' % (op, key)) def on_deps_change(self): + if not self.directory.available_deps(self.deps): + return new_queue = [] for key, data in self.set_queue: res = self.set_handler(key, data) @@ -223,7 +226,7 @@ class BGPDeviceMetaMgr(Manager): daemon, directory, [], - swsscommon.CONFIG_DB, + "CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME ) @@ -248,7 +251,7 @@ class BGPNeighborMetaMgr(Manager): daemon, directory, [], - swsscommon.CONFIG_DB, + "CONFIG_DB", swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME ) @@ -269,8 +272,10 @@ class BGPPeerMgr(Manager): [ ("meta", "localhost/bgp_asn"), ("neigmeta", ""), + ("local_addresses", ""), + ("interfaces", ""), ], - swsscommon.CONFIG_DB, + "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME ) self.peers = self.load_peers() @@ -287,8 +292,42 @@ class BGPPeerMgr(Manager): vrf, nbr = key.split('|', 1) if key not in self.peers: cmd = None + + if "local_addr" not in data: + syslog.syslog(syslog.LOG_WARNING, 'Peer {}. Error in missing required attribute "local_addr"'.format(key)) + else: + # The bgp session that belongs to a vnet cannot be advertised as the default BGP session. + # So we need to check whether this bgp session belongs to a vnet. + interface = InterfaceMgr.get_local_interface(self.directory, data["local_addr"]) + if not interface: + syslog.syslog(syslog.LOG_INFO, + 'Peer {} with local address {} wait for the corresponding interface to be set'.format( + key, + data["local_addr"] + ) + ) + return False + vnet = InterfaceMgr.get_vnet(interface) + if vnet: + # Ignore the bgp session that is in a vnet + syslog.syslog( + syslog.LOG_INFO, + 'Ignore the BGP peer {} as the interface {} is in vnet {}'.format( + key, + interface, + vnet + ) + ) + return True + neigmeta = self.directory.get_slot("neigmeta") if 'name' in data and data["name"] not in neigmeta: + syslog.syslog(syslog.LOG_INFO, + 'Peer {} with neighbor name {} wait for the corresponding neighbor metadata to be set'.format( + key, + data["name"] + ) + ) return False try: cmd = self.templates["add"].render( @@ -387,6 +426,121 @@ class BGPPeerMgr(Manager): return peers +class InterfaceMgr(Manager): + def __init__(self, daemon, directory, interface_table = swsscommon.CFG_INTF_TABLE_NAME): + super(InterfaceMgr, self).__init__( + daemon, + directory, + [], + "CONFIG_DB", + interface_table + ) + + def set_handler(self, key, data): + # Interface table can have two keys, + # one with ip prefix and one without ip prefix + if '|' in key: + data = {} + data["interface"], network = key.split('|', 1) + try: + network = netaddr.IPNetwork(str(network)) + except: + syslog.syslog( + syslog.LOG_WARNING, + 'Subnet {} format is wrong for interface {}'.format( + network, + data["interface"] + ) + ) + return False + data["prefixlen"] = str(network.prefixlen) + ip = str(network.ip) + self.directory.put("local_addresses", ip, data) + else: + self.directory.put("interfaces", key, data) + return True + + def del_handler(self, key): + if '|' in key: + interface, network = key.split('|', 1) + try: + network = netaddr.IPNetwork(str(network)) + except: + syslog.syslog( + syslog.LOG_WARNING, + 'Subnet {} format is wrong for interface {}'.format( + network, + interface + ) + ) + return False + ip = str(network.ip) + self.directory.remove("local_addresses", ip) + else: + self.directory.remove("interfaces", key) + + @staticmethod + def get_local_interface(directory, local_addr): + """ + @summary: Get interface according to the local address from the directory + @param directory: Directory object that stored metadata of interfaces + @param local_addr: Local address of the interface + @return: Return the metadata of the interface with the local address + If the interface has not been set, return None + """ + local_addresses = directory.get_slot("local_addresses") + # Check if the local address of this bgp session has been set + if local_addr not in local_addresses: + return None + local_address = local_addresses[local_addr] + interfaces = directory.get_slot("interfaces") + # Check if the information for the interface of this local address has been set + if local_address.has_key("interface") and local_address["interface"] in interfaces: + return interfaces[local_address["interface"]] + else: + return None + + @staticmethod + def get_vnet(interface): + """ + @summary: Get the VNet name of the interface + @param interface: The metadata of the interface + @return: Return the vnet name of the interface if this interface belongs to a vnet, + Otherwise return None + """ + if interface.has_key("vnet_name") and interface["vnet_name"]: + return interface["vnet_name"] + else: + return None + + +class LoopbackInterfaceMgr(InterfaceMgr): + def __init__(self, daemon, directory): + super(LoopbackInterfaceMgr, self).__init__( + daemon, + directory, + swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME + ) + + +class VlanInterfaceMgr(InterfaceMgr): + def __init__(self, daemon, directory): + super(VlanInterfaceMgr, self).__init__( + daemon, + directory, + swsscommon.CFG_VLAN_INTF_TABLE_NAME + ) + + +class PortChannelInterfaceMgr(InterfaceMgr): + def __init__(self, daemon, directory): + super(PortChannelInterfaceMgr, self).__init__( + daemon, + directory, + swsscommon.CFG_LAG_INTF_TABLE_NAME + ) + + def wait_for_bgpd(): # wait for 20 seconds stop_time = datetime.datetime.now() + datetime.timedelta(seconds=20) @@ -405,6 +559,10 @@ def main(): BGPDeviceMetaMgr, BGPNeighborMetaMgr, BGPPeerMgr, + InterfaceMgr, + LoopbackInterfaceMgr, + VlanInterfaceMgr, + PortChannelInterfaceMgr, ] wait_for_bgpd() daemon = Daemon() diff --git a/dockers/docker-fpm-frr/bgpd.conf.default.j2 b/dockers/docker-fpm-frr/bgpd.conf.default.j2 index e12782b035aa..2bf80b80a787 100644 --- a/dockers/docker-fpm-frr/bgpd.conf.default.j2 +++ b/dockers/docker-fpm-frr/bgpd.conf.default.j2 @@ -23,6 +23,20 @@ route-map TO_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V6 permit 100 ! +{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} +route-map HIDE_INTERNAL permit 10 + set community local-AS +! +{% endif %} +{% if DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} +route-map OVERRIDE_ORIGINATOR_ID permit 10 +{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} +{% if prefix | ipv4 and name == 'Loopback0' %} + set originator-id {{ prefix | ip }} +{% endif %} +{% endfor %} +! +{% endif %} {% if BGP_MONITORS is defined and BGP_MONITORS|length > 0 %} route-map FROM_BGPMON deny 10 ! @@ -37,6 +51,9 @@ route-map set-next-hop-global-v6 permit 10 set ipv6 next-hop prefer-global ! router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} +{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} + redistribute connected route-map HIDE_INTERNAL +{% endif %} bgp log-neighbor-changes bgp bestpath as-path multipath-relax no bgp default ipv4-unicast @@ -151,6 +168,9 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} neighbor {{ neighbor_addr }} peer-group BGPMON neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} neighbor {{ neighbor_addr }} activate +{% if DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} + neighbor {{ neighbor_addr }} route-map OVERRIDE_ORIGINATOR_ID in +{% endif %} address-family ipv6 neighbor {{ neighbor_addr }} activate exit-address-family diff --git a/dockers/docker-fpm-frr/bgpd.peer.conf.j2 b/dockers/docker-fpm-frr/bgpd.peer.conf.j2 old mode 100644 new mode 100755 index c3dc50449d35..bcc520f6b2df --- a/dockers/docker-fpm-frr/bgpd.peer.conf.j2 +++ b/dockers/docker-fpm-frr/bgpd.peer.conf.j2 @@ -26,8 +26,7 @@ neighbor {{ neighbor_addr }} next-hop-self {% endif %} {% if bgp_session["asn"] == DEVICE_METADATA['localhost']['bgp_asn'] - and DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" - and (not bgp_session.has_key("local_addr") or bgp_session["local_addr"] not in interfaces_in_vnets) %} + and DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" %} address-family l2vpn evpn neighbor {{ neighbor_addr }} activate advertise-all-vni diff --git a/dockers/docker-fpm-frr/critical_processes b/dockers/docker-fpm-frr/critical_processes new file mode 100644 index 000000000000..8ea09e1bb538 --- /dev/null +++ b/dockers/docker-fpm-frr/critical_processes @@ -0,0 +1,5 @@ +zebra +staticd +bgpd +fpmsyncd +bgpcfgd diff --git a/dockers/docker-fpm-frr/supervisord.conf b/dockers/docker-fpm-frr/supervisord.conf index fe0ce6eda1a4..3e544b64b296 100644 --- a/dockers/docker-fpm-frr/supervisord.conf +++ b/dockers/docker-fpm-frr/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name bgp +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -25,7 +31,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=3 autostart=false -autorestart=false +autorestart=unexpected startsecs=0 stdout_logfile=syslog stderr_logfile=syslog diff --git a/dockers/docker-fpm-gobgp/Dockerfile.j2 b/dockers/docker-fpm-gobgp/Dockerfile.j2 index 1e333d9026c0..b9b969edeb09 100644 --- a/dockers/docker-fpm-gobgp/Dockerfile.j2 +++ b/dockers/docker-fpm-gobgp/Dockerfile.j2 @@ -24,5 +24,7 @@ COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["*.j2", "/usr/share/sonic/templates/"] COPY ["daemons", "/etc/quagga/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-fpm-gobgp/critical_processes b/dockers/docker-fpm-gobgp/critical_processes new file mode 100644 index 000000000000..2a9e47831e0d --- /dev/null +++ b/dockers/docker-fpm-gobgp/critical_processes @@ -0,0 +1,2 @@ +gobgpd +fpmsyncd diff --git a/dockers/docker-fpm-gobgp/supervisord.conf b/dockers/docker-fpm-gobgp/supervisord.conf index 4e635f4093d4..b814dc024fa3 100644 --- a/dockers/docker-fpm-gobgp/supervisord.conf +++ b/dockers/docker-fpm-gobgp/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name bgp +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/dockers/docker-fpm-quagga/Dockerfile.j2 b/dockers/docker-fpm-quagga/Dockerfile.j2 index f048e2789429..9d1312d073ee 100644 --- a/dockers/docker-fpm-quagga/Dockerfile.j2 +++ b/dockers/docker-fpm-quagga/Dockerfile.j2 @@ -33,5 +33,7 @@ RUN rm -rf /debs ~/.cache COPY ["bgpcfgd", "start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["*.j2", "/usr/share/sonic/templates/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-fpm-quagga/critical_processes b/dockers/docker-fpm-quagga/critical_processes new file mode 100644 index 000000000000..f151af9c4bdd --- /dev/null +++ b/dockers/docker-fpm-quagga/critical_processes @@ -0,0 +1,4 @@ +zebra +bgpd +fpmsyncd +bgpcfgd diff --git a/dockers/docker-fpm-quagga/supervisord.conf b/dockers/docker-fpm-quagga/supervisord.conf index c4351fafefe9..7397a7428a08 100644 --- a/dockers/docker-fpm-quagga/supervisord.conf +++ b/dockers/docker-fpm-quagga/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name bgp +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -25,7 +31,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=3 autostart=false -autorestart=false +autorestart=unexpected startsecs=0 stdout_logfile=syslog stderr_logfile=syslog diff --git a/dockers/docker-lldp-sv2/base_image_files/monit_lldp b/dockers/docker-lldp-sv2/base_image_files/monit_lldp new file mode 100644 index 000000000000..200c52c7d332 --- /dev/null +++ b/dockers/docker-lldp-sv2/base_image_files/monit_lldp @@ -0,0 +1,15 @@ +############################################################################### +## Monit configuration for lldp container +## process list: +## lldpd +## lldp-syncd +## lldpmgrd +############################################################################### +check process lldpd_monitor matching "lldpd: " + if does not exist for 5 times within 5 cycles then alert + +check process lldp_syncd matching "python2 -m lldp_syncd" + if does not exist for 5 times within 5 cycles then alert + +check process lldpmgrd matching "python /usr/bin/lldpmgrd" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-lldp-sv2/lldpmgrd b/dockers/docker-lldp-sv2/lldpmgrd index edcdc5c42e47..7e9ef1642a06 100755 --- a/dockers/docker-lldp-sv2/lldpmgrd +++ b/dockers/docker-lldp-sv2/lldpmgrd @@ -84,22 +84,18 @@ class LldpManager(object): pending_cmds: Dictionary where key is port name, value is pending LLDP configuration command to run """ - REDIS_HOSTNAME = "localhost" - REDIS_PORT = 6379 REDIS_TIMEOUT_MS = 0 def __init__(self): # Open a handle to the Config database - self.config_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, - self.REDIS_HOSTNAME, - self.REDIS_PORT, - self.REDIS_TIMEOUT_MS) + self.config_db = swsscommon.DBConnector("CONFIG_DB", + self.REDIS_TIMEOUT_MS, + True) # Open a handle to the Application database - self.appl_db = swsscommon.DBConnector(swsscommon.APPL_DB, - self.REDIS_HOSTNAME, - self.REDIS_PORT, - self.REDIS_TIMEOUT_MS) + self.appl_db = swsscommon.DBConnector("APPL_DB", + self.REDIS_TIMEOUT_MS, + True) self.pending_cmds = {} @@ -157,7 +153,7 @@ class LldpManager(object): # if there is a description available, also configure that if port_desc: - lldpcli_cmd += " description {}".format(port_desc) + lldpcli_cmd += " description '{}'".format(port_desc) else: log_info("Unable to retrieve description for port '{}'. Not adding port description".format(port_name)) diff --git a/dockers/docker-lldp-sv2/supervisord.conf b/dockers/docker-lldp-sv2/supervisord.conf index 3f3f5beabc8d..73ff52f4420e 100644 --- a/dockers/docker-lldp-sv2/supervisord.conf +++ b/dockers/docker-lldp-sv2/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name lldp events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/dockers/docker-nat/Dockerfile.j2 b/dockers/docker-nat/Dockerfile.j2 new file mode 100644 index 000000000000..a74147cc26fd --- /dev/null +++ b/dockers/docker-nat/Dockerfile.j2 @@ -0,0 +1,48 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, copy_files %} +FROM docker-config-engine-stretch + +ARG docker_container_name +RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf + +RUN echo + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +## Install redis-tools dependencies +## TODO: implicitly install dependencies +RUN apt-get update \ +&& apt-get install -f -y \ + libdbus-1-3 \ + libdaemon0 \ + libjansson4 \ + libpython2.7 \ + libatomic1 \ + libjemalloc1 \ + liblua5.1-0 \ + lua-bitop \ + lua-cjson \ + libelf1 \ + libmnl0 \ + bridge-utils \ + conntrack + +{% if docker_nat_debs.strip() -%} +# Copy locally-built Debian package dependencies +{{copy_files ("debs/", docker_nat_debs.split(' '), "/debs/") }} + +# Install locally-built Debian packages and implicitly install their dependencies +{{ install_debian_packages(docker_nat_debs.split(' ')) }} +{%- endif %} + +COPY ["start.sh", "/usr/bin/"] +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["restore_nat_entries.py", "/usr/bin/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] + +RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y +RUN rm -rf /debs + +ENTRYPOINT ["/usr/bin/supervisord"] + diff --git a/dockers/docker-nat/base_image_files/natctl b/dockers/docker-nat/base_image_files/natctl new file mode 100644 index 000000000000..6cba3c86be70 --- /dev/null +++ b/dockers/docker-nat/base_image_files/natctl @@ -0,0 +1,5 @@ +#!/bin/bash + +# -t option needed only for shell, not for commands + +docker exec -i nat natctl "$@" diff --git a/dockers/docker-nat/critical_processes b/dockers/docker-nat/critical_processes new file mode 100644 index 000000000000..d442976143f1 --- /dev/null +++ b/dockers/docker-nat/critical_processes @@ -0,0 +1,2 @@ +natmgrd +natsyncd diff --git a/dockers/docker-nat/restore_nat_entries.py b/dockers/docker-nat/restore_nat_entries.py new file mode 100755 index 000000000000..9fb62e82f573 --- /dev/null +++ b/dockers/docker-nat/restore_nat_entries.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python + +"""" +Description: restore_nat_entries.py -- restoring nat entries table into kernel during system warm reboot. + The script is started by supervisord in nat docker when the docker is started. + It does not do anything in case neither system nor nat warm restart is enabled. + In case nat warm restart enabled only, it sets the stateDB flag so natsyncd can continue + the reconciation process. + In case system warm reboot is enabled, it will try to restore the nat entries table into kernel + , then it sets the stateDB flag for natsyncd to continue the + reconciliation process. +""" + +import sys +import subprocess +from swsscommon import swsscommon +import logging +import logging.handlers +import re +import os + +WARM_BOOT_FILE_DIR = '/var/warmboot/nat/' +NAT_WARM_BOOT_FILE = 'nat_entries.dump' +IP_PROTO_TCP = '6' + +MATCH_CONNTRACK_ENTRY = '^(\w+)\s+(\d+).*src=([\d.]+)\s+dst=([\d.]+)\s+sport=(\d+)\s+dport=(\d+).*src=([\d.]+)\s+dst=([\d.]+)\s+sport=(\d+)\s+dport=(\d+)' +REDIS_SOCK = "/var/run/redis/redis.sock" + +logger = logging.getLogger(__name__) +logger.setLevel(logging.INFO) +handler = logging.handlers.SysLogHandler(address = '/dev/log') +logger.addHandler(handler) + +def add_nat_conntrack_entry_in_kernel(ipproto, srcip, dstip, srcport, dstport, natsrcip, natdstip, natsrcport, natdstport): + # pyroute2 doesn't have support for adding conntrack entries via netlink yet. So, invoking the conntrack utility to add the entries. + state = '' + if (ipproto == IP_PROTO_TCP): + state = ' --state ESTABLISHED ' + ctcmd = 'conntrack -I -n ' + natdstip + ':' + natdstport + ' -g ' + natsrcip + ':' + natsrcport + \ + ' --protonum ' + ipproto + state + ' --timeout 600 --src ' + srcip + ' --sport ' + srcport + \ + ' --dst ' + dstip + ' --dport ' + dstport + ' -u ASSURED' + subprocess.call(ctcmd, shell=True) + logger.info("Restored NAT entry: {}".format(ctcmd)) + +# Set the statedb "NAT_RESTORE_TABLE|Flags", so natsyncd can start reconciliation +def set_statedb_nat_restore_done(): + statedb = swsscommon.DBConnector(swsscommon.STATE_DB, REDIS_SOCK, 0) + tbl = swsscommon.Table(statedb, "NAT_RESTORE_TABLE") + fvs = swsscommon.FieldValuePairs([("restored", "true")]) + tbl.set("Flags", fvs) + return + +# This function is to restore the kernel nat entries based on the saved nat entries. +def restore_update_kernel_nat_entries(filename): + # Read the entries from nat_entries.dump file and add them to kernel + conntrack_match_pattern = re.compile(r'{}'.format(MATCH_CONNTRACK_ENTRY)) + with open(filename, 'r') as fp: + for line in fp: + ctline = conntrack_match_pattern.findall(line) + if not ctline: + continue + cmdargs = list(ctline.pop(0)) + proto = cmdargs.pop(0) + if proto not in ('tcp', 'udp'): + continue + add_nat_conntrack_entry_in_kernel(*cmdargs) + +def main(): + logger.info("restore_nat_entries service is started") + + # Use warmstart python binding to check warmstart information + warmstart = swsscommon.WarmStart() + warmstart.initialize("natsyncd", "nat") + warmstart.checkWarmStart("natsyncd", "nat", False) + + # if swss or system warm reboot not enabled, don't run + if not warmstart.isWarmStart(): + logger.info("restore_nat_entries service is skipped as warm restart not enabled") + return + + # NAT restart not system warm reboot, set statedb directly + if not warmstart.isSystemWarmRebootEnabled(): + set_statedb_nat_restore_done() + logger.info("restore_nat_entries service is done as system warm reboot not enabled") + return + + # Program the nat conntrack entries in the kernel by reading the + # entries from nat_entries.dump + try: + restore_update_kernel_nat_entries(WARM_BOOT_FILE_DIR + NAT_WARM_BOOT_FILE) + except Exception as e: + logger.exception(str(e)) + sys.exit(1) + + # Remove the dump file after restoration + os.remove(WARM_BOOT_FILE_DIR + NAT_WARM_BOOT_FILE) + + # set statedb to signal other processes like natsyncd + set_statedb_nat_restore_done() + logger.info("restore_nat_entries service is done for system warmreboot") + return + +if __name__ == '__main__': + main() diff --git a/dockers/docker-nat/start.sh b/dockers/docker-nat/start.sh new file mode 100755 index 000000000000..e1f303fee6f2 --- /dev/null +++ b/dockers/docker-nat/start.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +rm -f /var/run/rsyslogd.pid +rm -f /var/run/nat/* + +mkdir -p /var/warmboot/nat + +supervisorctl start rsyslogd + +supervisorctl start natmgrd + +supervisorctl start natsyncd + +supervisorctl start restore_nat_entries + diff --git a/dockers/docker-nat/supervisord.conf b/dockers/docker-nat/supervisord.conf new file mode 100644 index 000000000000..839d6f59ab3c --- /dev/null +++ b/dockers/docker-nat/supervisord.conf @@ -0,0 +1,53 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name nat +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + +[program:start.sh] +command=/usr/bin/start.sh +priority=1 +autostart=true +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n +priority=2 +autostart=false +autorestart=unexpected +stdout_logfile=syslog +stderr_logfile=syslog + +[program:natmgrd] +command=/usr/bin/natmgrd +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:natsyncd] +command=/usr/bin/natsyncd +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:restore_nat_entries] +command=/usr/bin/restore_nat_entries.py +priority=5 +autostart=false +autorestart=false +startsecs=0 +startretries=0 +stdout_logfile=syslog +stderr_logfile=syslog + diff --git a/dockers/docker-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2 index 8a66e2adbe43..f95acd48fdbd 100755 --- a/dockers/docker-orchagent/Dockerfile.j2 +++ b/dockers/docker-orchagent/Dockerfile.j2 @@ -20,7 +20,8 @@ RUN apt-get update && \ tcpdump \ libelf1 \ libmnl0 \ - bridge-utils + bridge-utils \ + conntrack {% if ( CONFIGURED_ARCH == "armhf" or CONFIGURED_ARCH == "arm64" ) %} ## Fix for gcc/python not found in arm docker diff --git a/dockers/docker-orchagent/base_image_files/monit_swss b/dockers/docker-orchagent/base_image_files/monit_swss new file mode 100644 index 000000000000..5928dbd4ddb0 --- /dev/null +++ b/dockers/docker-orchagent/base_image_files/monit_swss @@ -0,0 +1,43 @@ +############################################################################### +## Monit configuration for swss container +## process list: +## orchagent +## portsyncd +## neighsyncd +## vrfmgrd +## vlanmgrd +## intfmgrd +## portmgrd +## buffermgrd +## nbrmgrd +## vxlanmgrd +############################################################################### +check process orchagent matching "/usr/bin/orchagent -d /var/log/swss" + if does not exist for 5 times within 5 cycles then alert + +check process portsyncd matching "/usr/bin/portsyncd" + if does not exist for 5 times within 5 cycles then alert + +check process neighsyncd matching "/usr/bin/neighsyncd" + if does not exist for 5 times within 5 cycles then alert + +check process vrfmgrd matching "/usr/bin/vrfmgrd" + if does not exist for 5 times within 5 cycles then alert + +check process vlanmgrd matching "/usr/bin/vlanmgrd" + if does not exist for 5 times within 5 cycles then alert + +check process intfmgrd matching "/usr/bin/intfmgrd" + if does not exist for 5 times within 5 cycles then alert + +check process portmgrd matching "/usr/bin/portmgrd" + if does not exist for 5 times within 5 cycles then alert + +check process buffermgrd matching "/usr/bin/buffermgrd -l" + if does not exist for 5 times within 5 cycles then alert + +check process nbrmgrd matching "/usr/bin/nbrmgrd" + if does not exist for 5 times within 5 cycles then alert + +check process vxlanmgrd matching "/usr/bin/vxlanmgrd" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh index 5e01cd480f52..3352e5fbb7ec 100755 --- a/dockers/docker-orchagent/orchagent.sh +++ b/dockers/docker-orchagent/orchagent.sh @@ -4,7 +4,11 @@ # vendor specific code. export platform=`sonic-cfggen -y /etc/sonic/sonic_version.yml -v asic_type` -MAC_ADDRESS=`ip link show eth0 | grep ether | awk '{print $2}'` +MAC_ADDRESS=$(sonic-cfggen -d -v 'DEVICE_METADATA.localhost.mac') +if [ "$MAC_ADDRESS" == "None" ] || [ -z "$MAC_ADDRESS" ]; then + MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') + logger "Mac address not found in Device Metadata, Falling back to eth0" +fi # Create a folder for SwSS record files mkdir -p /var/log/swss diff --git a/dockers/docker-orchagent/supervisord.conf b/dockers/docker-orchagent/supervisord.conf index 9ae2776f6d26..6b21d73f3c81 100644 --- a/dockers/docker-orchagent/supervisord.conf +++ b/dockers/docker-orchagent/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name swss events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/dockers/docker-orchagent/swssconfig.sh b/dockers/docker-orchagent/swssconfig.sh index c521fadf0a49..856b3bcd0e41 100755 --- a/dockers/docker-orchagent/swssconfig.sh +++ b/dockers/docker-orchagent/swssconfig.sh @@ -43,11 +43,11 @@ HWSKU=`sonic-cfggen -d -v "DEVICE_METADATA['localhost']['hwsku']"` # Don't load json config if system warm start or # swss docker warm start is enabled, the data already exists in appDB. -SYSTEM_WARM_START=`redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` -SWSS_WARM_START=`redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|swss" enable` +SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` +SWSS_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|swss" enable` if [[ "$SYSTEM_WARM_START" == "true" ]] || [[ "$SWSS_WARM_START" == "true" ]]; then # We have to make sure db data has not been flushed. - RESTORE_COUNT=`redis-cli -n 6 hget "WARM_RESTART_TABLE|orchagent" restore_count` + RESTORE_COUNT=`sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` if [[ -n "$RESTORE_COUNT" ]] && [[ "$RESTORE_COUNT" != "0" ]]; then exit 0 fi diff --git a/dockers/docker-platform-monitor/Dockerfile.j2 b/dockers/docker-platform-monitor/Dockerfile.j2 index fd11f628559c..61374af7d544 100755 --- a/dockers/docker-platform-monitor/Dockerfile.j2 +++ b/dockers/docker-platform-monitor/Dockerfile.j2 @@ -18,7 +18,8 @@ RUN apt-get update && \ rrdtool \ python-smbus \ ethtool \ - dmidecode + dmidecode && \ + pip install enum34 {% if docker_platform_monitor_debs.strip() -%} # Copy locally-built Debian package dependencies diff --git a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 index 9a2414c30d05..13ae0e767ab2 100644 --- a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 +++ b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name pmon events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf index 4ea84ab11c92..bf9320acc776 100644 --- a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf +++ b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-script] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name radv events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/dockers/docker-router-advertiser/wait_for_intf.sh.j2 b/dockers/docker-router-advertiser/wait_for_intf.sh.j2 index a044df0fc996..980b472b3e0a 100644 --- a/dockers/docker-router-advertiser/wait_for_intf.sh.j2 +++ b/dockers/docker-router-advertiser/wait_for_intf.sh.j2 @@ -1,7 +1,5 @@ #!/usr/bin/env bash -STATE_DB_IDX="6" - VLAN_TABLE_PREFIX="VLAN_TABLE" function wait_until_iface_ready @@ -14,7 +12,7 @@ function wait_until_iface_ready # Wait for the interface to come up # (i.e., interface is present in STATE_DB and state is "ok") while true; do - RESULT=$(redis-cli -n ${STATE_DB_IDX} HGET "${TABLE_PREFIX}|${IFACE}" "state" 2> /dev/null) + RESULT=$(sonic-db-cli STATE_DB HGET "${TABLE_PREFIX}|${IFACE}" "state" 2> /dev/null) if [ x"$RESULT" == x"ok" ]; then break fi diff --git a/dockers/docker-sflow/base_image_files/monit_sflow b/dockers/docker-sflow/base_image_files/monit_sflow new file mode 100644 index 000000000000..d041f81001ea --- /dev/null +++ b/dockers/docker-sflow/base_image_files/monit_sflow @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for sflow container +## process list: +## sflowmgrd +############################################################################### +check process sflowmgrd matching "/usr/bin/sflowmgrd" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-sflow/supervisord.conf b/dockers/docker-sflow/supervisord.conf index 50986f197d88..8eb1bdc05e57 100644 --- a/dockers/docker-sflow/supervisord.conf +++ b/dockers/docker-sflow/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name sflow events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/dockers/docker-snmp-sv2/base_image_files/monit_snmp b/dockers/docker-snmp-sv2/base_image_files/monit_snmp new file mode 100644 index 000000000000..811f9d14b3d4 --- /dev/null +++ b/dockers/docker-snmp-sv2/base_image_files/monit_snmp @@ -0,0 +1,11 @@ +############################################################################### +## Monit configuration for snmp container +## process list: +## snmpd +## snmpd_subagent +############################################################################### +check process snmpd matching "/usr/sbin/snmpd -f" + if does not exist for 5 times within 5 cycles then alert + +check process snmp_subagent matching "python3.6 -m sonic_ax_impl" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-snmp-sv2/snmpd.conf.j2 b/dockers/docker-snmp-sv2/snmpd.conf.j2 index 16d7e5bff79c..7d4022501fbb 100644 --- a/dockers/docker-snmp-sv2/snmpd.conf.j2 +++ b/dockers/docker-snmp-sv2/snmpd.conf.j2 @@ -15,16 +15,10 @@ # Listen for connections on all ip addresses, including eth0, ipv4 lo # -{% if snmp_agent_address_1 or snmp_agent_address_2 or snmp_agent_address_3 %} -{% if snmp_agent_address_1 %} -agentAddress {{ snmp_agent_address_1 }} -{% endif %} -{% if snmp_agent_address_2 %} -agentAddress {{ snmp_agent_address_2 }} -{% endif %} -{% if snmp_agent_address_3 %} -agentAddress {{ snmp_agent_address_3 }} -{% endif %} +{% if SNMP_AGENT_ADDRESS_CONFIG %} +{% for (agentip, port, vrf) in SNMP_AGENT_ADDRESS_CONFIG %} +agentAddress {{ agentip }}{% if port %}:{{ port }}{% endif %}{% if vrf %}%{{ vrf }}{% endif %}{{ "" }} +{% endfor %} {% else %} agentAddress udp:161 agentAddress udp6:161 @@ -105,20 +99,32 @@ load 12 10 5 # Note: disabled snmp traps due to side effect of causing snmpd to listen on all ports (0.0.0.0) # # send SNMPv1 traps -{%if v1_trap_dest and v1_trap_dest != 'NotConfigured' %} -trapsink {{ v1_trap_dest }} +{% if SNMP_TRAP_CONFIG and SNMP_TRAP_CONFIG['v1TrapDest'] %} +{% set v1SnmpTrapIp = SNMP_TRAP_CONFIG['v1TrapDest']['DestIp'] %} +{% set v1SnmpTrapPort = SNMP_TRAP_CONFIG['v1TrapDest']['DestPort'] %} +{% set v1SnmpTrapVrf = SNMP_TRAP_CONFIG['v1TrapDest']['vrf'] %} +{% set v1SnmpTrapComm = SNMP_TRAP_CONFIG['v1TrapDest']['Community'] %} +trapsink {{ v1SnmpTrapIp }}:{{ v1SnmpTrapPort }}{% if v1SnmpTrapVrf != 'None' %}%{{ v1SnmpTrapVrf }}{% endif %} {{ v1SnmpTrapComm }}{{ "" }} {% else %} #trapsink localhost public {% endif %} # send SNMPv2c traps -{%if v2_trap_dest and v2_trap_dest != 'NotConfigured' %} -trap2sink {{ v2_trap_dest }} +{% if SNMP_TRAP_CONFIG and SNMP_TRAP_CONFIG['v2TrapDest'] %} +{% set v2SnmpTrapIp = SNMP_TRAP_CONFIG['v2TrapDest']['DestIp'] %} +{% set v2SnmpTrapPort = SNMP_TRAP_CONFIG['v2TrapDest']['DestPort'] %} +{% set v2SnmpTrapVrf = SNMP_TRAP_CONFIG['v2TrapDest']['vrf'] %} +{% set v2SnmpTrapComm = SNMP_TRAP_CONFIG['v2TrapDest']['Community'] %} +trap2sink {{ v2SnmpTrapIp }}:{{ v2SnmpTrapPort }}{% if v2SnmpTrapVrf != 'None' %}%{{ v2SnmpTrapVrf }}{% endif %} {{ v2SnmpTrapComm }}{{ "" }} {% else %} #trap2sink localhost public {% endif %} # send SNMPv2c INFORMs -{%if v3_trap_dest and v3_trap_dest != 'NotConfigured' %} -informsink {{ v3_trap_dest }} +{% if SNMP_TRAP_CONFIG and SNMP_TRAP_CONFIG['v3TrapDest'] %} +{% set v3SnmpTrapIp = SNMP_TRAP_CONFIG['v3TrapDest']['DestIp'] %} +{% set v3SnmpTrapPort = SNMP_TRAP_CONFIG['v3TrapDest']['DestPort'] %} +{% set v3SnmpTrapVrf = SNMP_TRAP_CONFIG['v3TrapDest']['vrf'] %} +{% set v3SnmpTrapComm = SNMP_TRAP_CONFIG['v3TrapDest']['Community'] %} +trapsink {{ v3SnmpTrapIp }}:{{ v3SnmpTrapPort }}{% if v3SnmpTrapVrf != 'None' %}%{{ v3SnmpTrapVrf }}{% endif %} {{ v3SnmpTrapComm }}{{ "" }} {% else %} #informsink localhost public {% endif %} diff --git a/dockers/docker-snmp-sv2/start.sh b/dockers/docker-snmp-sv2/start.sh index 786968cf9d90..6ec3379df58f 100755 --- a/dockers/docker-snmp-sv2/start.sh +++ b/dockers/docker-snmp-sv2/start.sh @@ -9,17 +9,6 @@ sonic-cfggen -d -y /etc/sonic/snmp.yml -t /usr/share/sonic/templates/snmpd.conf. mkdir -p /var/sonic echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status -CURRENT_HOSTNAME=`hostname` -HOSTNAME=`sonic-cfggen -d -v DEVICE_METADATA[\'localhost\'][\'hostname\']` - -if [ "$?" == "0" ] && [ "$HOSTNAME" != "" ]; then - echo $HOSTNAME > /etc/hostname - hostname -F /etc/hostname - - sed -i "/\s$CURRENT_HOSTNAME$/d" /etc/hosts - echo "127.0.0.1 $HOSTNAME" >> /etc/hosts -fi - rm -f /var/run/rsyslogd.pid supervisorctl start rsyslogd diff --git a/dockers/docker-snmp-sv2/supervisord.conf b/dockers/docker-snmp-sv2/supervisord.conf index 7fd16eec5bbe..992292330552 100644 --- a/dockers/docker-snmp-sv2/supervisord.conf +++ b/dockers/docker-snmp-sv2/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name snmp events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/dockers/docker-sonic-mgmt-framework/rest-server.sh b/dockers/docker-sonic-mgmt-framework/rest-server.sh index f2a29c9b1ed2..e450f707dfd1 100755 --- a/dockers/docker-sonic-mgmt-framework/rest-server.sh +++ b/dockers/docker-sonic-mgmt-framework/rest-server.sh @@ -46,7 +46,5 @@ echo "REST_SERVER_ARGS = $REST_SERVER_ARGS" export CVL_SCHEMA_PATH=/usr/sbin/schema -export LIBYANG_EXTENSIONS_PLUGINS_DIR=/usr/lib/x86_64-linux-gnu/libyang/extensions -export LIBYANG_USER_TYPES_PLUGINS_DIR=/usr/lib/x86_64-linux-gnu/libyang/user_types exec /usr/sbin/rest_server ${REST_SERVER_ARGS} diff --git a/dockers/docker-sonic-restapi/Dockerfile.j2 b/dockers/docker-sonic-restapi/Dockerfile.j2 new file mode 100644 index 000000000000..32904531f1fc --- /dev/null +++ b/dockers/docker-sonic-restapi/Dockerfile.j2 @@ -0,0 +1,28 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} +FROM docker-config-engine-stretch + +ARG docker_container_name +RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update + +{% if docker_sonic_restapi_debs.strip() -%} +# Copy locally-built Debian package dependencies +{{ copy_files("debs/", docker_sonic_restapi_debs.split(' '), "/debs/") }} + +# Install locally-built Debian packages and implicitly install their dependencies +{{ install_debian_packages( docker_sonic_restapi_debs.split(' ')) }} +{%- endif %} + +## Clean up +RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y + +COPY ["start.sh", "restapi.sh", "/usr/bin/"] +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] + +ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-sonic-restapi/base_image_files/monit_restapi b/dockers/docker-sonic-restapi/base_image_files/monit_restapi new file mode 100644 index 000000000000..2e90baf30d57 --- /dev/null +++ b/dockers/docker-sonic-restapi/base_image_files/monit_restapi @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for restapi container +## process list: +## restapi +############################################################################### +check process restapi matching "/usr/sbin/go-server-server" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-sonic-restapi/critical_processes b/dockers/docker-sonic-restapi/critical_processes new file mode 100644 index 000000000000..3106eaa9410a --- /dev/null +++ b/dockers/docker-sonic-restapi/critical_processes @@ -0,0 +1 @@ +restapi diff --git a/dockers/docker-sonic-restapi/restapi.sh b/dockers/docker-sonic-restapi/restapi.sh new file mode 100755 index 000000000000..61778e3245d6 --- /dev/null +++ b/dockers/docker-sonic-restapi/restapi.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +RESTAPI_ARGS="" +while true +do + client_auth=`sonic-cfggen -d -v "RESTAPI['config']['client_auth']"` + if [[ $client_auth == 'true' ]]; then + certs=`sonic-cfggen -d -v "RESTAPI['certs']"` + allow_insecure=`sonic-cfggen -d -v "RESTAPI['config']['allow_insecure']"` + if [[ $allow_insecure == 'true' ]]; then + RESTAPI_ARGS=" -enablehttp=true" + else + RESTAPI_ARGS=" -enablehttp=false" + fi + if [[ -n "$certs" ]]; then + SERVER_CRT=`sonic-cfggen -d -v "RESTAPI['certs']['server_crt']"` + SERVER_KEY=`sonic-cfggen -d -v "RESTAPI['certs']['server_key']"` + CLIENT_CA_CRT=`sonic-cfggen -d -v "RESTAPI['certs']['client_ca_crt']"` + CLIENT_CRT_CNAME=`sonic-cfggen -d -v "RESTAPI['certs']['client_crt_cname']"` + if [[ -f $SERVER_CRT && -f $SERVER_KEY && -f $CLIENT_CA_CRT ]]; then + RESTAPI_ARGS+=" -enablehttps=true -servercert=$SERVER_CRT -serverkey=$SERVER_KEY -clientcert=$CLIENT_CA_CRT -clientcertcommonname=$CLIENT_CRT_CNAME" + break + fi + fi + fi + logger "Waiting for certificates..." + sleep 60 +done + +LOG_LEVEL=`sonic-cfggen -d -v "RESTAPI['config']['log_level']"` +if [ ! -z $LOG_LEVEL ]; then + RESTAPI_ARGS+=" -loglevel=$LOG_LEVEL" +else + RESTAPI_ARGS+=" -loglevel=trace" +fi + +logger "RESTAPI_ARGS: $RESTAPI_ARGS" +exec /usr/sbin/go-server-server ${RESTAPI_ARGS} diff --git a/dockers/docker-sonic-restapi/start.sh b/dockers/docker-sonic-restapi/start.sh new file mode 100755 index 000000000000..bff56a8864c1 --- /dev/null +++ b/dockers/docker-sonic-restapi/start.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +mkdir -p /var/sonic +echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status + +rm -f /var/run/rsyslogd.pid + +supervisorctl start rsyslogd +supervisorctl start restapi diff --git a/dockers/docker-sonic-restapi/supervisord.conf b/dockers/docker-sonic-restapi/supervisord.conf new file mode 100644 index 000000000000..58afc6dcd7de --- /dev/null +++ b/dockers/docker-sonic-restapi/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 --container-name restapi +events=PROCESS_STATE_EXITED +autostart=true +autorestart=false + +[program:start.sh] +command=/usr/bin/start.sh +priority=1 +autostart=true +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:restapi] +command=/usr/bin/restapi.sh +priority=1 +autostart=false +autorestart=true +stdout_logfile=syslog +stderr_logfile=syslog + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n +priority=2 +autostart=false +autorestart=true +stdout_logfile=syslog +stderr_logfile=syslog diff --git a/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry b/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry new file mode 100644 index 000000000000..555822c57f80 --- /dev/null +++ b/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry @@ -0,0 +1,11 @@ +############################################################################### +## Monit configuration for telemetry container +## process list: +## telemetry +## dialout_client +############################################################################### +check process telemetry matching "/usr/sbin/telemetry -logtostderr --insecure" + if does not exist for 5 times within 5 cycles then alert + +check process dialout_client matching "/usr/sbin/dialout_client_cli -insecure -logtostderr" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-sonic-telemetry/supervisord.conf b/dockers/docker-sonic-telemetry/supervisord.conf index e1346fe7db4e..54f4c5b2348d 100644 --- a/dockers/docker-sonic-telemetry/supervisord.conf +++ b/dockers/docker-sonic-telemetry/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name telemetry events=PROCESS_STATE_EXITED autostart=true autorestart=false diff --git a/dockers/docker-sonic-telemetry/telemetry.sh b/dockers/docker-sonic-telemetry/telemetry.sh index 8b29b4d616a5..b8f7fffb3ebb 100755 --- a/dockers/docker-sonic-telemetry/telemetry.sh +++ b/dockers/docker-sonic-telemetry/telemetry.sh @@ -1,35 +1,47 @@ #!/usr/bin/env bash -# Try to read telemetry and x509 config from ConfigDB. +# Try to read telemetry and certs config from ConfigDB. # Use default value if no valid config exists X509=`sonic-cfggen -d -v "DEVICE_METADATA['x509']"` -TELEMETRY=`sonic-cfggen -d -v 'TELEMETRY.keys() | join(" ") if TELEMETRY'` +gnmi=`sonic-cfggen -d -v "TELEMETRY['gnmi']"` +certs=`sonic-cfggen -d -v "TELEMETRY['certs']"` TELEMETRY_ARGS=" -logtostderr" export CVL_SCHEMA_PATH=/usr/sbin/schema -if [ -n "$X509" ]; then - SERVER_CRT=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_crt']"` - SERVER_KEY=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_key']"` - if [ -z $SERVER_CRT ] || [ -z $SERVER_KEY ]; then - TELEMETRY_ARGS+=" --insecure" - else +if [ -n "$certs" ]; then + SERVER_CRT=`sonic-cfggen -d -v "TELEMETRY['certs']['server_crt']"` + SERVER_KEY=`sonic-cfggen -d -v "TELEMETRY['certs']['server_key']"` + if [ -z $SERVER_CRT ] || [ -z $SERVER_KEY ]; then + TELEMETRY_ARGS+=" --insecure" + else + TELEMETRY_ARGS+=" --server_crt $SERVER_CRT --server_key $SERVER_KEY " + fi + + CA_CRT=`sonic-cfggen -d -v "TELEMETRY['certs']['ca_crt']"` + if [ ! -z $CA_CRT ]; then + TELEMETRY_ARGS+=" --ca_crt $CA_CRT" + fi +elif [ -n "$X509" ]; then + SERVER_CRT=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_crt']"` + SERVER_KEY=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_key']"` + if [ -z $SERVER_CRT ] || [ -z $SERVER_KEY ]; then + TELEMETRY_ARGS+=" --insecure" + else TELEMETRY_ARGS+=" --server_crt $SERVER_CRT --server_key $SERVER_KEY " fi -else - TELEMETRY_ARGS+=" --insecure" -fi -if [ -n "$X509" ]; then - CA_CRT=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['ca_crt']"` - if [ ! -z $CA_CRT ]; then - TELEMETRY_ARGS+=" --ca_crt $CA_CRT" - fi + CA_CRT=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['ca_crt']"` + if [ ! -z $CA_CRT ]; then + TELEMETRY_ARGS+=" --ca_crt $CA_CRT" + fi +else + TELEMETRY_ARGS+=" --insecure" fi # If no configuration entry exists for TELEMETRY, create one default port -if [ -z $TELEMETRY ]; then - redis-cli -n 4 hset "TELEMETRY|gnmi" port 8080 +if [ -z "$gnmi" ]; then + sonic-db-cli CONFIG_DB hset "TELEMETRY|gnmi" port 8080 fi PORT=`sonic-cfggen -d -v "TELEMETRY['gnmi']['port']"` @@ -37,14 +49,14 @@ TELEMETRY_ARGS+=" --port $PORT" CLIENT_AUTH=`sonic-cfggen -d -v "TELEMETRY['gnmi']['client_auth']"` if [ -z $CLIENT_AUTH ] || [ $CLIENT_AUTH == "false" ]; then - TELEMETRY_ARGS+=" --allow_no_client_auth" + TELEMETRY_ARGS+=" --allow_no_client_auth" fi LOG_LEVEL=`sonic-cfggen -d -v "TELEMETRY['gnmi']['log_level']"` if [ ! -z $LOG_LEVEL ]; then - TELEMETRY_ARGS+=" -v=$LOG_LEVEL" + TELEMETRY_ARGS+=" -v=$LOG_LEVEL" else - TELEMETRY_ARGS+=" -v=2" + TELEMETRY_ARGS+=" -v=2" fi exec /usr/sbin/telemetry ${TELEMETRY_ARGS} diff --git a/dockers/docker-teamd/supervisord.conf b/dockers/docker-teamd/supervisord.conf index 3a420e0fcdcf..0c3071bbfdda 100644 --- a/dockers/docker-teamd/supervisord.conf +++ b/dockers/docker-teamd/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name teamd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected @@ -36,6 +36,7 @@ stderr_logfile=syslog [program:teamsyncd] command=/usr/bin/teamsyncd priority=3 +startsecs=5 autostart=false autorestart=false stdout_logfile=syslog diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index 66e86774e766..3c61c631af93 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -216,9 +216,31 @@ EOF chmod a+r "${target_path}/machine.conf" } +in_array() { + local value="$1" + shift + + for other in $@; do + if [ "$value" = "$other" ]; then + return 0 + fi + done + + return 1 +} + +read_system_eeprom() { + if [ -x /bin/readprefdl ]; then + readprefdl -f /tmp/.system-prefdl -d > $target_path/.system-prefdl + elif [ -f /etc/prefdl ]; then + cp /etc/prefdl $target_path/.system-prefdl + chmod a+r $target_path/.system-prefdl + fi +} + platform_specific() { - local platform="$(grep -Eo 'platform=[^ ]+' "$cmdline_base" | cut -f2 -d=)" - local sid="$(grep -Eo 'sid=[^ ]+' "$cmdline_base" | cut -f2 -d=)" + local platform="$(sed -nr 's/.*platform=([^ ]+).*/\1/p' "$cmdline_base")" + local sid="$(sed -nr 's/.*sid=([^ ]+).*/\1/p' "$cmdline_base" | sed 's/Ssd$//')" # set varlog size to 100MB local varlog_size=100 @@ -227,31 +249,49 @@ platform_specific() { local flash_size=$(($(df | grep -E "$flash_re" | tr -s ' ' | cut -f2 -d' ') / 1000)) if [ "$platform" = "raven" ]; then + # Assuming sid=Cloverdale aboot_machine=arista_7050_qx32 flash_size=2000 docker_inram=on echo "modprobe.blacklist=radeon,sp5100_tco acpi=off docker_inram=on" >>/tmp/append fi if [ "$platform" = "crow" ]; then + # Assuming sid=Clearlake aboot_machine=arista_7050_qx32s flash_size=3700 echo "modprobe.blacklist=radeon,sp5100_tco" >>/tmp/append fi - if [ "$sid" = "Upperlake" ] || [ "$sid" = "UpperlakeES" ] || - [ "$sid" = "UpperlakeSsd" ]; then + if [ "$sid" = "Upperlake" ] || [ "$sid" = "UpperlakeES" ]; then aboot_machine=arista_7060_cx32s flash_size=3700 - echo "amd_iommu=off" >> /tmp/append fi - if [ "$sid" = "Gardena" ] || [ "$sid" = "GardenaSsd" ]; then + if [ "$sid" = "UpperlakePlus" ]; then + aboot_machine=arista_7060cx2_32s + flash_size=3700 + fi + if [ "$sid" = "Gardena" ] || [ "$sid" = "GardenaE" ]; then aboot_machine=arista_7260cx3_64 flash_size=28000 fi - if [ "$sid" = "Alhambra" ] || [ "$sid" = "AlhambraSsd" ]; then + if [ "$sid" = "Alhambra" ]; then aboot_machine=arista_7170_64c flash_size=28000 echo "hugepages=128" >> /tmp/append fi + if [ "$sid" = "Mineral" ]; then + aboot_machine=arista_7170_32c + flash_size=28000 + echo "hugepages=128" >> /tmp/append + fi + if [ "$sid" = "MineralD" ]; then + aboot_machine=arista_7170_32cd + flash_size=28000 + echo "hugepages=128" >> /tmp/append + fi + if [ "$sid" = "Lodoga" ]; then + aboot_machine=arista_7050cx3_32s + flash_size=3700 + fi if [ "$sid" = "BlackhawkO" ]; then aboot_machine=arista_7060px4_32 flash_size=28000 @@ -260,35 +300,30 @@ platform_specific() { aboot_machine=arista_7060dx4_32 flash_size=28000 fi - if [ "$sid" = "Smartsville" ] || [ "$sid" = "SmartsvilleSsd" ]; then + if [ "$sid" = "Smartsville" ]; then aboot_machine=arista_7280cr3_32p4 flash_size=7382 fi - if [ "$sid" = "SmartsvilleBK" ] || [ "$sid" = "SmartsvilleBKSsd" ]; then + if [ "$sid" = "SmartsvilleBK" ]; then aboot_machine=arista_7280cr3k_32p4 flash_size=7382 fi - if [ "$sid" = "SmartsvilleDD" ] || [ "$sid" = "SmartsvilleDDSsd" ]; then + if [ "$sid" = "SmartsvilleDD" ]; then aboot_machine=arista_7280cr3_32d4 flash_size=7382 fi - if [ "$platform" = "rook" ] || [ "$platform" = "magpie" ] || - [ "$platform" = "woodpecker" ]; then + if in_array "$platform" "rook" "magpie" "woodpecker"; then echo "tsc=reliable pcie_ports=native" >>/tmp/append echo "rhash_entries=1 usb-storage.delay_use=0" >>/tmp/append - if [ -x /bin/readprefdl ]; then - readprefdl -f /tmp/.system-prefdl -d > /mnt/flash/.system-prefdl - elif [ -f /etc/prefdl ]; then - cp /etc/prefdl /mnt/flash/.system-prefdl - chmod a+r /mnt/flash/.system-prefdl - fi echo "reassign_prefmem" >> /tmp/append fi - if [ "$platform" = "rook" ] || [ "$platform" = "magpie" ]; then + if in_array "$platform" "rook"; then echo "iommu=on intel_iommu=on" >>/tmp/append + read_system_eeprom fi - if [ "$platform" = "woodpecker" ]; then + if in_array "$platform" "crow" "woodpecker" "magpie"; then echo "amd_iommu=off modprobe.blacklist=snd_hda_intel,hdaudio" >> /tmp/append + read_system_eeprom fi if [ $flash_size -ge 28000 ]; then @@ -358,11 +393,12 @@ write_boot_configs() { mkdir -p "$image_path" cat /tmp/append > $cmdline_image - [ -e ${target_path}/machine.conf ] || write_machine_config + [ -s ${target_path}/machine.conf ] || write_machine_config + sync } run_kexec() { - local cmdline="$(cat $cmdline_image | tr '\n' ' ')" + local cmdline="$(cat $cmdline_image | tr '\n' ' ') $ENV_EXTRA_CMDLINE" local kernel="${KERNEL:-$(find $image_path/boot -name 'vmlinuz-*' -type f | head -n 1)}" local initrd="${INITRD:-$(find $image_path/boot -name 'initrd.img-*' -type f | head -n 1)}" diff --git a/files/apt/apt.conf.d/no-check-valid-until b/files/apt/apt.conf.d/no-check-valid-until index 97b9c9005181..c7c25d017f7f 100644 --- a/files/apt/apt.conf.d/no-check-valid-until +++ b/files/apt/apt.conf.d/no-check-valid-until @@ -1 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + Acquire::Check-Valid-Until "false"; diff --git a/files/build_templates/config-setup.service.j2 b/files/build_templates/config-setup.service.j2 new file mode 100644 index 000000000000..a4b614a5f7fb --- /dev/null +++ b/files/build_templates/config-setup.service.j2 @@ -0,0 +1,18 @@ +[Unit] +Description=Config initialization and migration service +After=rc-local.service +After=database.service +Requires=database.service +{% if sonic_asic_platform == 'mellanox' -%} +Requires=hw-management.service +{% endif -%} + + +[Service] +Type=oneshot +ExecStart=/usr/bin/config-setup boot +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target + diff --git a/files/build_templates/database.service.j2 b/files/build_templates/database.service.j2 deleted file mode 100644 index 472b9d328b7d..000000000000 --- a/files/build_templates/database.service.j2 +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description=Database container -Requires=docker.service -After=docker.service -After=rc-local.service - -[Service] -User=root -ExecStartPre=/usr/bin/{{docker_container_name}}.sh start -ExecStart=/usr/bin/{{docker_container_name}}.sh wait -ExecStop=/usr/bin/{{docker_container_name}}.sh stop - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/database.service.j2 b/files/build_templates/database.service.j2 new file mode 120000 index 000000000000..63340abef881 --- /dev/null +++ b/files/build_templates/database.service.j2 @@ -0,0 +1 @@ +per_namespace/database.service.j2 \ No newline at end of file diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 167a392730e4..297c9dd1c2bd 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -1,34 +1,35 @@ #!/bin/bash -function getMountPoint() -{ - echo $1 | python -c "import sys, json, os; mnts = [x for x in json.load(sys.stdin)[0]['Mounts'] if x['Destination'] == '/usr/share/sonic/hwsku']; print '' if len(mnts) == 0 else os.path.basename(mnts[0]['Source'])" 2>/dev/null -} +# single instance containers are still supported (even though it might not look like it) +# if no instance number is passed to this script, $DEV will simply be unset, resulting in docker +# commands being sent to the base container name. E.g. `docker start database$DEV` simply starts +# the container `database` if no instance number is passed since `$DEV` is not defined -function updateHostName() -{ - HOSTS=/etc/hosts - HOSTS_TMP=/etc/hosts.tmp - EXEC="docker exec -i {{docker_container_name}} bash -c" +{%- if docker_container_name == "database" %} +link_namespace() { + # Makes namespace of a docker container available in + # /var/run/netns so it can be managed with iproute2 + + mkdir -p /var/run/netns + PID="$(docker inspect -f {{"'{{.State.Pid}}'"}} "{{docker_container_name}}$DEV")" - NEW_HOSTNAME="$1" - HOSTNAME=`$EXEC "hostname"` - if ! [[ $HOSTNAME =~ ^[a-zA-Z0-9.\-]*$ ]]; then - HOSTNAME=`hostname` + PIDS=`ip netns pids "$NET_NS" 2>/dev/null` + if [ "$?" -eq "0" ]; then # namespace exists + if `echo $PIDS | grep --quiet -w $PID`; then # namespace is correctly linked + return 0 + else # if it's incorrectly linked remove it + ip netns delete $NET_NS + fi fi - # copy HOSTS to HOSTS_TMP - $EXEC "cp $HOSTS $HOSTS_TMP" - # remove entry with hostname - $EXEC "sed -i \"/$HOSTNAME$/d\" $HOSTS_TMP" - # add entry with new hostname - $EXEC "echo -e \"127.0.0.1\t$NEW_HOSTNAME\" >> $HOSTS_TMP" + ln -s /proc/$PID/ns/net /var/run/netns/$NET_NS +} +{%- endif %} - echo "Set hostname in {{docker_container_name}} container" - $EXEC "hostname '$NEW_HOSTNAME'" - $EXEC "cat $HOSTS_TMP > $HOSTS" - $EXEC "rm -f $HOSTS_TMP" +function getMountPoint() +{ + echo $1 | python -c "import sys, json, os; mnts = [x for x in json.load(sys.stdin)[0]['Mounts'] if x['Destination'] == '/usr/share/sonic/hwsku']; print '' if len(mnts) == 0 else os.path.basename(mnts[0]['Source'])" 2>/dev/null } function getBootType() @@ -56,81 +57,14 @@ function preStartAction() WARM_DIR=/host/warmboot if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then # Load redis content from /host/warmboot/dump.rdb - docker cp $WARM_DIR/dump.rdb database:/var/lib/redis/dump.rdb + docker cp $WARM_DIR/dump.rdb database$DEV:/var/lib/redis/dump.rdb else # Create an emtpy file and overwrite any RDB if already there echo -n > /tmp/dump.rdb - docker cp /tmp/dump.rdb database:/var/lib/redis/ + docker cp /tmp/dump.rdb database$DEV:/var/lib/redis/ fi {%- elif docker_container_name == "snmp" %} - 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 + sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) {%- else %} : # nothing {%- endif %} @@ -139,22 +73,29 @@ function preStartAction() function postStartAction() { {%- if docker_container_name == "database" %} + if [ "$DEV" ]; then + link_namespace $DEV + fi # Wait until redis starts - /usr/bin/docker exec database ping_pong_db_insts + /usr/bin/docker exec database$DEV ping_pong_db_insts if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then rm -f $WARM_DIR/dump.rdb else - # If there is a config db dump file, load it - if [ -r /etc/sonic/config_db.json ]; then - sonic-cfggen -j /etc/sonic/config_db.json --write-to-db + # If there is a config_db.json dump file, load it. + if [ -r /etc/sonic/config_db$DEV.json ]; then + if [ -r /etc/sonic/init_cfg.json ]; then + sonic-netns-exec "$NET_NS" sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db$DEV.json --write-to-db + else + sonic-netns-exec "$NET_NS" sonic-cfggen -j /etc/sonic/config_db$DEV.json --write-to-db + fi fi if [[ "$BOOT_TYPE" == "fast" ]]; then # set the key to expire in 3 minutes - redis-cli -n 6 SET "FAST_REBOOT|system" "1" "EX" "180" + /usr/bin/sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180" fi - redis-cli -n 4 SET "CONFIG_DB_INITIALIZED" "1" + /usr/bin/sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" fi if [[ -x /usr/bin/db_migrator.py ]]; then @@ -162,14 +103,14 @@ function postStartAction() /usr/bin/db_migrator.py -o migrate fi {%- elif docker_container_name == "swss" %} - docker exec swss rm -f /ready # remove cruft + docker exec swss$DEV rm -f /ready # remove cruft if [[ "$BOOT_TYPE" == "fast" ]] && [[ -d /host/fast-reboot ]]; then - test -e /host/fast-reboot/fdb.json && docker cp /host/fast-reboot/fdb.json swss:/ - test -e /host/fast-reboot/arp.json && docker cp /host/fast-reboot/arp.json swss:/ - test -e /host/fast-reboot/default_routes.json && docker cp /host/fast-reboot/default_routes.json swss:/ + test -e /host/fast-reboot/fdb.json && docker cp /host/fast-reboot/fdb.json swss$DEV:/ + test -e /host/fast-reboot/arp.json && docker cp /host/fast-reboot/arp.json swss$DEV:/ + test -e /host/fast-reboot/default_routes.json && docker cp /host/fast-reboot/default_routes.json swss$DEV:/ rm -fr /host/fast-reboot fi - docker exec swss touch /ready # signal swssconfig.sh to go + docker exec swss$DEV touch /ready # signal swssconfig.sh to go {%- elif docker_container_name == "pmon" %} DEVPATH="/usr/share/sonic/device" @@ -191,21 +132,17 @@ start() { BOOT_TYPE=`getBootType` # Obtain our platform as we will mount directories with these names in each docker - PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + PLATFORM=`sonic-netns-exec "$NET_NS" sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` {%- if docker_container_name == "database" %} # Don't mount HWSKU in {{docker_container_name}} container. HWSKU="" {%- else %} # Obtain our HWSKU as we will mount directories with these names in each docker - HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` - HOSTNAME=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hostname"]'` + HWSKU=`sonic-netns-exec "$NET_NS" sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` {%- endif %} - if [ -z "$HOSTNAME" ] || ! [[ $HOSTNAME =~ ^[a-zA-Z0-9.\-]*$ ]]; then - HOSTNAME=`hostname` - fi - DOCKERCHECK=`docker inspect --type container {{docker_container_name}} 2>/dev/null` + DOCKERCHECK=`docker inspect --type container {{docker_container_name}}$DEV 2>/dev/null` if [ "$?" -eq "0" ]; then {%- if docker_container_name == "database" %} DOCKERMOUNT="" @@ -214,39 +151,55 @@ start() { {%- endif %} if [ x"$DOCKERMOUNT" == x"$HWSKU" ]; then {%- if docker_container_name == "database" %} - echo "Starting existing {{docker_container_name}} container" + echo "Starting existing {{docker_container_name}}$DEV container" {%- else %} - echo "Starting existing {{docker_container_name}} container with HWSKU $HWSKU" + echo "Starting existing {{docker_container_name}}$DEV container with HWSKU $HWSKU" {%- endif %} preStartAction - docker start {{docker_container_name}} - CURRENT_HOSTNAME="$(docker exec {{docker_container_name}} hostname)" - if [ x"$HOSTNAME" != x"$CURRENT_HOSTNAME" ]; then - updateHostName "$HOSTNAME" - fi + docker start {{docker_container_name}}$DEV postStartAction exit $? fi # docker created with a different HWSKU, remove and recreate - echo "Removing obsolete {{docker_container_name}} container with HWSKU $DOCKERMOUNT" - docker rm -f {{docker_container_name}} + echo "Removing obsolete {{docker_container_name}}$DEV container with HWSKU $DOCKERMOUNT" + docker rm -f {{docker_container_name}}$DEV fi -{%- if docker_container_name == "database" %} - echo "Creating new {{docker_container_name}} container" + {%- if docker_container_name == "database" %} + echo "Creating new {{docker_container_name}}$DEV container" # if database_config exists in old_config, use it; otherwise use the default one in new image if [ -f /etc/sonic/old_config/database_config.json ]; then echo "Use database_config.json from old system..." mv /etc/sonic/old_config/database_config.json /etc/sonic/ fi -{%- else %} - echo "Creating new {{docker_container_name}} container with HWSKU $HWSKU" + {%- else %} + echo "Creating new {{docker_container_name}}$DEV container with HWSKU $HWSKU" + {%- endif %} + + if [ -z "$DEV" ]; then + NET="host" + else + {%- if docker_container_name == "database" %} + NET="bridge" + {%- else %} + NET="container:database$DEV" + {%- endif %} + fi +{%- if docker_container_name == "bgp" %} + if [ "$DEV" ]; then + if [ ! -d "/etc/sonic/frr/$DEV" ]; then + mkdir /etc/sonic/frr/$DEV + cp -r /etc/sonic/frr/*.conf /etc/sonic/frr/$DEV + fi + fi {%- endif %} {%- if sonic_asic_platform == "mellanox" %} # TODO: Mellanox will remove the --tmpfs exception after SDK socket path changed in new SDK version {%- endif %} docker create {{docker_image_run_opt}} \ + --net=$NET \ + --uts=host \{# W/A: this should be set per-docker, for those dockers which really need host's UTS namespace #} {%- if install_debug_image == "y" %} -v /src:/src:ro -v /debug:/debug:rw \ {%- endif %} @@ -256,52 +209,69 @@ start() { {%- if sonic_asic_platform == "mellanox" %} {%- if docker_container_name == "syncd" %} -v /var/log/mellanox/sniffer:/var/log/mellanox/sniffer:rw \ - -v mlnx_sdk_socket:/tmp \ + -v mlnx_sdk_socket:/var/run/sx_sdk \ + -v mlnx_sdk_ready:/tmp \ -v /dev/shm:/dev/shm:rw \ + -e SX_API_SOCKET_FILE=/var/run/sx_sdk/sx_api.sock \ {%- elif docker_container_name == "pmon" %} -v /var/run/hw-management:/var/run/hw-management:rw \ - -v mlnx_sdk_socket:/tmp \ + -v mlnx_sdk_socket:/var/run/sx_sdk \ + -v mlnx_sdk_ready:/tmp \ + -e SX_API_SOCKET_FILE=/var/run/sx_sdk/sx_api.sock \ -v /dev/shm:/dev/shm:rw \ {%- else %} --tmpfs /tmp \ {%- endif %} {%- endif %} - -v /var/run/redis:/var/run/redis:rw \ +{%- if docker_container_name == "bgp" %} + -v /etc/sonic/frr/$DEV:/etc/frr:rw \ +{%- endif %} + -v /var/run/redis$DEV:/var/run/redis:rw \ -v /usr/share/sonic/device/$PLATFORM:/usr/share/sonic/platform:ro \ {%- if docker_container_name != "database" %} - -v /usr/share/sonic/device/$PLATFORM/$HWSKU:/usr/share/sonic/hwsku:ro \ + -v /usr/share/sonic/device/$PLATFORM/$HWSKU/$DEV:/usr/share/sonic/hwsku:ro \ {%- endif %} {%- if sonic_asic_platform != "mellanox" %} --tmpfs /tmp \ {%- endif %} --tmpfs /var/tmp \ - --hostname "$HOSTNAME" \ - --name={{docker_container_name}} {{docker_image_name}}:latest || { + --name={{docker_container_name}}$DEV {{docker_image_name}}:latest || { echo "Failed to docker run" >&1 exit 4 } preStartAction - docker start {{docker_container_name}} + docker start {{docker_container_name}}$DEV postStartAction } wait() { - docker wait {{docker_container_name}} + docker wait {{docker_container_name}}$DEV } stop() { - docker stop {{docker_container_name}} + docker stop {{docker_container_name}}$DEV +{%- if docker_container_name == "database" %} + if [ "$DEV" ]; then + ip netns delete "$NET_NS" + fi +{%- endif %} } +OP=$1 +DEV=$2 # namespace/device number to operate on +if [ "$DEV" ]; then + NET_NS="asic$DEV" #name of the network namespace +else + NET_NS="" +fi + case "$1" in - start|wait|stop|updateHostName) - cmd=$1 - shift - $cmd $@ + start|wait|stop) + $1 ;; *) - echo "Usage: $0 {start|wait|stop|updateHostName new_hostname}" + echo "Usage: $0 {start namespace(optional)|wait namespace(optional)|stop namespace(optional)}" exit 1 ;; esac diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 new file mode 100644 index 000000000000..c187e02762b8 --- /dev/null +++ b/files/build_templates/init_cfg.json.j2 @@ -0,0 +1,36 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "default_bgp_status": {% if shutdown_bgp_on_start == "y" %}"down"{% else %}"up"{% endif %}, + "default_pfcwd_status": {% if enable_pfcwd_on_start == "y" %}"enable"{% else %}"disable"{% endif %} + } + }, + "CRM": { + "Config": { + "polling_interval": "300", +{%- for crm_res in ["ipv4_route", "ipv6_route", "ipv4_nexthop", "ipv6_nexthop", "ipv4_neighbor", + "ipv6_neighbor", "nexthop_group_member", "nexthop_group", "acl_table", + "acl_group", "acl_entry", "acl_counter", "fdb_entry"] %} + "{{crm_res}}_threshold_type": "percentage", + "{{crm_res}}_low_threshold": "70", + "{{crm_res}}_high_threshold": "85"{% if not loop.last %},{% endif -%} +{% endfor %} + } + }, + "FEATURE": { +{%- for feature in ["sflow", "telemetry"] %} + "{{feature}}": { + "status": "disabled" + }{% if not loop.last %},{% endif -%} +{% endfor %} + }, + "CONTAINER_FEATURE": { +{%- for container in ["bgp", "database", "dhcp_relay", "lldp", "nat", "pmon", "radv", "restapi", "sflow", + "snmp", "swss", "syncd", "teamd", "telemetry"] %} + "{{container}}": { + "auto_restart": "disabled", + "high_mem_alert": "disabled" + }{% if not loop.last %},{% endif -%} +{% endfor %} + } +} diff --git a/files/build_templates/mgmt-framework.service.j2 b/files/build_templates/mgmt-framework.service.j2 index d0a030347b51..acc938c13d90 100644 --- a/files/build_templates/mgmt-framework.service.j2 +++ b/files/build_templates/mgmt-framework.service.j2 @@ -1,7 +1,7 @@ [Unit] Description=Management Framework container Requires=swss.service -After=swss.service +After=swss.service syncd.service Before=ntp-config.service [Service] diff --git a/files/build_templates/lldp.service.j2 b/files/build_templates/nat.service.j2 similarity index 77% rename from files/build_templates/lldp.service.j2 rename to files/build_templates/nat.service.j2 index 2599fc5c5bdc..79a56f67ca89 100644 --- a/files/build_templates/lldp.service.j2 +++ b/files/build_templates/nat.service.j2 @@ -1,6 +1,6 @@ [Unit] -Description=LLDP container -Requires=updategraph.service +Description=NAT container +Requires=updategraph.service swss.service After=updategraph.service swss.service syncd.service Before=ntp-config.service StartLimitIntervalSec=1200 @@ -15,4 +15,5 @@ Restart=always RestartSec=30 [Install] -WantedBy=multi-user.target +WantedBy=multi-user.target swss.service + diff --git a/files/build_templates/per_namespace/bgp.service.j2 b/files/build_templates/per_namespace/bgp.service.j2 new file mode 100644 index 000000000000..79e9afc4ebc1 --- /dev/null +++ b/files/build_templates/per_namespace/bgp.service.j2 @@ -0,0 +1,21 @@ +[Unit] +Description=BGP container +Requires=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=database{% if multi_instance == 'true' %}@%i{% endif %}.service +Requires=updategraph.service +After=updategraph.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} + +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/database.service.j2 b/files/build_templates/per_namespace/database.service.j2 new file mode 100644 index 000000000000..396fdc6678c2 --- /dev/null +++ b/files/build_templates/per_namespace/database.service.j2 @@ -0,0 +1,22 @@ +[Unit] +Description=Database container +{% if multi_instance == 'true' %} +Requires=database.service +After=database.service +{% endif %} +Requires=docker.service +After=docker.service +After=rc-local.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User=root +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/lldp.service.j2 b/files/build_templates/per_namespace/lldp.service.j2 new file mode 100644 index 000000000000..b48675b03202 --- /dev/null +++ b/files/build_templates/per_namespace/lldp.service.j2 @@ -0,0 +1,22 @@ +[Unit] +Description=LLDP container +Requires=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=swss{% if multi_instance == 'true' %}@%i{% endif %}.service +After=syncd{% if multi_instance == 'true' %}@%i{% endif %}.service +Requires=updategraph.service +After=updategraph.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/swss.service.j2 b/files/build_templates/per_namespace/swss.service.j2 new file mode 100644 index 000000000000..53d6b4497df7 --- /dev/null +++ b/files/build_templates/per_namespace/swss.service.j2 @@ -0,0 +1,31 @@ +[Unit] +Description=switch state service +Requires=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=database{% if multi_instance == 'true' %}@%i{% endif %}.service +{% if multi_instance == 'true' and sonic_asic_platform == 'vs' %} +Requires=topology.service +After=topology.service +{% endif %} +{% if sonic_asic_platform == 'broadcom' %} +Requires=opennsl-modules.service +{% elif sonic_asic_platform == 'nephos' %} +Requires=nps-modules-4.9.0-11-2-amd64.service +{% endif %} +Requires=updategraph.service +After=updategraph.service +After=interfaces-config.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User=root +Environment=sonic_asic_platform={{ sonic_asic_platform }} +ExecStartPre=/usr/local/bin/swss.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/local/bin/swss.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/local/bin/swss.sh stop{% if multi_instance == 'true' %} %i{% endif %} +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/syncd.service.j2 b/files/build_templates/per_namespace/syncd.service.j2 new file mode 100644 index 000000000000..b2922e0d12b6 --- /dev/null +++ b/files/build_templates/per_namespace/syncd.service.j2 @@ -0,0 +1,33 @@ +[Unit] +Description=syncd service +Requires=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=swss{% if multi_instance == 'true' %}@%i{% endif %}.service +{% if multi_instance == 'true' and sonic_asic_platform == 'vs' %} +Requires=topology.service +After=topology.service +{% endif %} +{% if sonic_asic_platform == 'broadcom' %} +Requires=opennsl-modules.service +After=opennsl-modules.service +{% elif sonic_asic_platform == 'nephos' %} +Requires=nps-modules-4.9.0-11-2-amd64.service +After=nps-modules-4.9.0-11-2-amd64.service +{% endif %} +Requires=updategraph.service +After=updategraph.service +After=interfaces-config.service +Before=ntp-config.service + +[Service] +User=root +Environment=sonic_asic_platform={{ sonic_asic_platform }} +ExecStartPre=/usr/local/bin/syncd.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/local/bin/syncd.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/local/bin/syncd.sh stop{% if multi_instance == 'true' %} %i{% endif %} +{% if sonic_asic_platform == 'mellanox' %} +TimeoutStartSec=150 +{% endif %} + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/teamd.service.j2 b/files/build_templates/per_namespace/teamd.service.j2 new file mode 100644 index 000000000000..092f9d2ebde2 --- /dev/null +++ b/files/build_templates/per_namespace/teamd.service.j2 @@ -0,0 +1,19 @@ +[Unit] +Description=TEAMD container +After=swss{% if multi_instance == 'true' %}@%i{% endif %}.service +Requires=updategraph.service +After=updategraph.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/process-reboot-cause.timer b/files/build_templates/process-reboot-cause.timer new file mode 100644 index 000000000000..222c51a79a03 --- /dev/null +++ b/files/build_templates/process-reboot-cause.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Delays process-reboot-cause until network is stably connected + +[Timer] +OnBootSec=1min 30 sec +Unit=process-reboot-cause.service + +[Install] +WantedBy=timers.target diff --git a/files/build_templates/bgp.service.j2 b/files/build_templates/restapi.service.j2 similarity index 77% rename from files/build_templates/bgp.service.j2 rename to files/build_templates/restapi.service.j2 index 7200a0e3ecf2..df1a50eb56c7 100644 --- a/files/build_templates/bgp.service.j2 +++ b/files/build_templates/restapi.service.j2 @@ -1,5 +1,5 @@ [Unit] -Description=BGP container +Description=RestAPI container Requires=updategraph.service After=updategraph.service Before=ntp-config.service @@ -9,6 +9,8 @@ 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 +WantedBy=multi-user.target \ No newline at end of file diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 0e6d07fb001a..68cab2feb9cd 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -81,6 +81,10 @@ sudo mkdir -p $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/ifupdown2_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f +# Install ipables (and its dependencies via 'apt-get -y install -f') +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/iptables_*.deb || \ + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f + # Install dependencies for SONiC config engine sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install \ python-dev \ @@ -143,6 +147,12 @@ sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install tabulat sudo dpkg --root=$FILESYSTEM_ROOT -i $python_debs_path/python-sonic-utilities_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f +{% if enable_ztp == "y" %} +# Install ZTP (and its dependencies via 'apt-get -y install -f') +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/sonic-ztp_*.deb || \ + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f +{% endif %} + # SONiC utilities installs bash-completion as a dependency. However, it is disabled by default # in bash.bashrc, so we copy a version of the file with it enabled here. sudo cp -f $IMAGE_CONFIGS/bash/bash.bashrc $FILESYSTEM_ROOT/etc/ @@ -163,8 +173,10 @@ sudo LANG=C chroot $FILESYSTEM_ROOT pam-auth-update --remove tacplus sudo sed -i -e '/^passwd/s/ tacplus//' $FILESYSTEM_ROOT/etc/nsswitch.conf # Install a custom version of kdump-tools (and its dependencies via 'apt-get -y install -f') +if [[ $CONFIGURED_ARCH == amd64 ]]; then sudo DEBIAN_FRONTEND=noninteractive dpkg --root=$FILESYSTEM_ROOT -i $debs_path/kdump-tools_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=truechroot $FILESYSTEM_ROOT apt-get -q --no-install-suggests --no-install-recommends --force-no install +fi # Install custom-built monit package and SONiC configuration files sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/monit_*.deb || \ @@ -207,6 +219,12 @@ sudo cp $IMAGE_CONFIGS/interfaces/interfaces-config.sh $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/interfaces/*.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ echo "interfaces-config.service" | sudo tee -a $GENERATED_SERVICE_FILE +# Copy dhcp client configuration template and create an initial configuration +sudo cp files/dhcp/dhclient.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ +j2 files/dhcp/dhclient.conf.j2 | sudo tee $FILESYSTEM_ROOT/etc/dhcp/dhclient.conf +sudo cp files/dhcp/ifupdown2_policy.json $FILESYSTEM_ROOT/etc/network/ifupdown2/policy.d +sudo cp files/dhcp/90-dhcp6-systcl.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ + # Copy initial interfaces configuration file, will be overwritten on first boot sudo cp $IMAGE_CONFIGS/interfaces/init_interfaces $FILESYSTEM_ROOT/etc/network/interfaces sudo mkdir -p $FILESYSTEM_ROOT/etc/network/interfaces.d @@ -223,10 +241,25 @@ sudo LANG=C chroot $FILESYSTEM_ROOT systemctl disable core_uploader.service sudo cp $IMAGE_CONFIGS/corefile_uploader/core_uploader.py $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/corefile_uploader/core_analyzer.rc.json $FILESYSTEM_ROOT_ETC_SONIC/ sudo chmod og-rw $FILESYSTEM_ROOT_ETC_SONIC/core_analyzer.rc.json -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install azure-storage + +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install azure-storage-blob + +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install azure-storage-file-share + +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install azure-storage-file-datalake + +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install azure-storage-queue + sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install watchdog sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install futures +{% if install_kubernetes == "y" %} +# Copy kubelet service files +# Keep it disabled until join, else it continuously restart and as well spew too many +# non-required log lines wasting syslog resources. +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl disable kubelet.service +{% endif %} + # Copy the buffer configuration template sudo cp $BUILD_TEMPLATES/buffers_config.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ @@ -241,6 +274,13 @@ sudo cp $IMAGE_CONFIGS/hostname/hostname-config.sh $FILESYSTEM_ROOT/usr/bin/ # Copy miscellaneous scripts sudo cp $IMAGE_CONFIGS/misc/docker-wait-any $FILESYSTEM_ROOT/usr/bin/ +# Copy internal topology configuration scripts +{%- if sonic_asic_platform == "vs" %} +sudo cp $IMAGE_CONFIGS/topology/topology.service $FILESYSTEM_ROOT/etc/systemd/system/ +echo "topology.service" | sudo tee -a $GENERATED_SERVICE_FILE +sudo cp $IMAGE_CONFIGS/topology/topology.sh $FILESYSTEM_ROOT/usr/bin +{%- endif %} + # Copy updategraph script and service file j2 files/build_templates/updategraph.service.j2 | sudo tee $FILESYSTEM_ROOT/etc/systemd/system/updategraph.service sudo cp $IMAGE_CONFIGS/updategraph/updategraph $FILESYSTEM_ROOT/usr/bin/ @@ -252,11 +292,15 @@ sudo bash -c "echo dhcp_as_static=true >> $FILESYSTEM_ROOT/etc/sonic/updategraph {% else %} sudo bash -c "echo enabled=false > $FILESYSTEM_ROOT/etc/sonic/updategraph.conf" {% endif %} -sudo bash -c "echo '{ \"DEVICE_METADATA\": { \"localhost\": { \"default_bgp_status\": {% if shutdown_bgp_on_start == "y" %}\"down\"{% else %}\"up\"{% endif %}, \"default_pfcwd_status\": {% if enable_pfcwd_on_start == "y" %}\"enable\"{% else %}\"disable\"{% endif %} } }, -{%- print ' \\"CRM\\": { \\"Config\\": { \\"polling_interval\\": \\"300\\", ' %} -{%- for crm_res in ["ipv4_route", "ipv6_route", "ipv4_nexthop", "ipv6_nexthop", "ipv4_neighbor", "ipv6_neighbor", "nexthop_group_member", "nexthop_group", "acl_table", "acl_group", "acl_entry", "acl_counter", "fdb_entry"] -%} -\"{{crm_res}}_threshold_type\": \"percentage\", \"{{crm_res}}_low_threshold\": \"70\", \"{{crm_res}}_high_threshold\": \"85\"{% if not loop.last %}, {% endif %} -{%- endfor %} } } }' >> $FILESYSTEM_ROOT/etc/sonic/init_cfg.json" + +# Generate initial SONiC configuration file +j2 files/build_templates/init_cfg.json.j2 | sudo tee $FILESYSTEM_ROOT/etc/sonic/init_cfg.json + +# Copy config-setup script and service file +j2 files/build_templates/config-setup.service.j2 | sudo tee $FILESYSTEM_ROOT/etc/systemd/system/config-setup.service +sudo cp $IMAGE_CONFIGS/config-setup/config-setup $FILESYSTEM_ROOT/usr/bin/config-setup +echo "config-setup.service" | sudo tee -a $GENERATED_SERVICE_FILE +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable config-setup.service # Copy SNMP configuration files sudo cp $IMAGE_CONFIGS/snmp/snmp.yml $FILESYSTEM_ROOT/etc/sonic/ @@ -278,6 +322,11 @@ sudo cp $IMAGE_CONFIGS/procdockerstatsd/procdockerstatsd.service $FILESYSTEM_RO echo "procdockerstatsd.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/procdockerstatsd/procdockerstatsd $FILESYSTEM_ROOT/usr/bin/ +# Copy systemd timer configuration +# It implements delayed start of services +sudo cp $BUILD_TEMPLATES/process-reboot-cause.timer $FILESYSTEM_ROOT/etc/systemd/system/ +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable process-reboot-cause.timer + # Copy process-reboot-cause service files sudo cp $IMAGE_CONFIGS/process-reboot-cause/process-reboot-cause.service $FILESYSTEM_ROOT/etc/systemd/system/ echo "process-reboot-cause.service" | sudo tee -a $GENERATED_SERVICE_FILE @@ -365,6 +414,18 @@ sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS ta sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS tag {{imagename}}:latest {{imagebasename}}:latest {% endif %} {% endfor %} + +{% if install_kubernetes == "y" %} +## Pull in kubernetes docker images +echo "pulling universal k8s images ..." +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull k8s.gcr.io/pause:${K8s_GCR_IO_PAUSE_VERSION} +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull k8s.gcr.io/kube-proxy:v${KUBERNETES_VERSION} +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull calico/node:v${K8s_CNI_CALICO_VERSION} +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull calico/pod2daemon-flexvol:v${K8s_CNI_CALICO_VERSION} +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull calico/cni:v${K8s_CNI_CALICO_VERSION} +echo "docker images pull complete" +{% endif %} + if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then sudo umount $FILESYSTEM_ROOT/dockerfs sudo rm -fr $FILESYSTEM_ROOT/dockerfs @@ -379,6 +440,13 @@ sudo cp {{script}} $FILESYSTEM_ROOT/usr/bin/ {% for service in installer_services.split(' ') -%} if [ -f {{service}} ]; then sudo cp {{service}} $FILESYSTEM_ROOT/etc/systemd/system/ + + {% if "@" in service %} + MULTI_INSTANCE="{{service}}" + SINGLE_INSTANCE=${MULTI_INSTANCE/"@"} + sudo cp $SINGLE_INSTANCE $FILESYSTEM_ROOT/etc/systemd/system/ + {% endif %} + echo "{{service}}" | sudo tee -a $GENERATED_SERVICE_FILE fi {% endfor %} @@ -390,6 +458,9 @@ sudo LANG=C chroot $FILESYSTEM_ROOT umount -lf /sys sudo LANG=C cp $SCRIPTS_DIR/swss.sh $FILESYSTEM_ROOT/usr/local/bin/swss.sh sudo LANG=C cp $SCRIPTS_DIR/syncd.sh $FILESYSTEM_ROOT/usr/local/bin/syncd.sh +# Copy sonic-netns-exec script +sudo LANG=C cp $SCRIPTS_DIR/sonic-netns-exec $FILESYSTEM_ROOT/usr/bin/sonic-netns-exec + # Copy systemd timer configuration # It implements delayed start of services sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT/etc/systemd/system/ @@ -415,8 +486,11 @@ sudo cp {{src}} $FILESYSTEM_ROOT/{{dst}} sudo mkdir -p $FILESYSTEM_ROOT/etc/mlnx/ sudo cp $files_path/$MLNX_SPC_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC.mfa sudo cp $files_path/$MLNX_SPC2_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC2.mfa +sudo cp $files_path/$MLNX_SPC3_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC3.mfa sudo cp $files_path/$ISSU_VERSION_FILE $FILESYSTEM_ROOT/etc/mlnx/issu-version sudo cp $files_path/$MLNX_FFB_SCRIPT $FILESYSTEM_ROOT/usr/bin/mlnx-ffb.sh +sudo cp $files_path/$MLNX_ONIE_FW_UPDATE $FILESYSTEM_ROOT/usr/bin/$MLNX_ONIE_FW_UPDATE +sudo cp $files_path/$MLNX_SSD_FW_UPDATE $FILESYSTEM_ROOT/usr/bin/$MLNX_SSD_FW_UPDATE j2 platform/mellanox/mlnx-fw-upgrade.j2 | sudo tee $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh diff --git a/files/build_templates/swss.service.j2 b/files/build_templates/swss.service.j2 deleted file mode 100644 index b7a6396749bd..000000000000 --- a/files/build_templates/swss.service.j2 +++ /dev/null @@ -1,25 +0,0 @@ -[Unit] -Description=switch state service -Requires=database.service updategraph.service -{% if sonic_asic_platform == 'broadcom' %} -Requires=opennsl-modules.service -{% elif sonic_asic_platform == 'nephos' %} -Requires=nps-modules-4.9.0-9-2-amd64.service -{% endif %} -After=database.service updategraph.service -After=interfaces-config.service -Before=ntp-config.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User=root -Environment=sonic_asic_platform={{ sonic_asic_platform }} -ExecStartPre=/usr/local/bin/swss.sh start -ExecStart=/usr/local/bin/swss.sh wait -ExecStop=/usr/local/bin/swss.sh stop -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/syncd.service.j2 b/files/build_templates/syncd.service.j2 deleted file mode 100644 index b52772e9b114..000000000000 --- a/files/build_templates/syncd.service.j2 +++ /dev/null @@ -1,30 +0,0 @@ -[Unit] -Description=syncd service -Requires=database.service updategraph.service -{% if sonic_asic_platform == 'broadcom' %} -Requires=opennsl-modules.service -{% elif sonic_asic_platform == 'nephos' %} -Requires=nps-modules-4.9.0-9-2-amd64.service -{% endif %} -After=database.service updategraph.service -After=interfaces-config.service -{% if sonic_asic_platform == 'broadcom' %} -After=opennsl-modules.service -{% elif sonic_asic_platform == 'nephos' %} -After=nps-modules-4.9.0-9-2-amd64.service -{% endif %} -After=swss.service -Before=ntp-config.service - -[Service] -User=root -Environment=sonic_asic_platform={{ sonic_asic_platform }} -ExecStartPre=/usr/local/bin/syncd.sh start -ExecStart=/usr/local/bin/syncd.sh wait -ExecStop=/usr/local/bin/syncd.sh stop -{% if sonic_asic_platform == 'mellanox' %} -TimeoutStartSec=150 -{% endif %} - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/teamd.service.j2 b/files/build_templates/teamd.service.j2 deleted file mode 100644 index be0521a4fbec..000000000000 --- a/files/build_templates/teamd.service.j2 +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=TEAMD container -Requires=updategraph.service -After=updategraph.service swss.service -Before=ntp-config.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User={{ sonicadmin_user }} -ExecStartPre=/usr/bin/{{docker_container_name}}.sh start -ExecStart=/usr/bin/{{docker_container_name}}.sh wait -ExecStop=/usr/bin/{{docker_container_name}}.sh stop -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/updategraph.service.j2 b/files/build_templates/updategraph.service.j2 index 8039f42531cd..0e05cbf147d6 100644 --- a/files/build_templates/updategraph.service.j2 +++ b/files/build_templates/updategraph.service.j2 @@ -1,12 +1,7 @@ [Unit] Description=Update minigraph and set configuration based on minigraph -After=rc-local.service -After=database.service -Requires=database.service -{% if sonic_asic_platform == 'mellanox' -%} -Requires=hw-management.service -{% endif -%} - +After=config-setup.service +Requires=config-setup.service [Service] Type=oneshot diff --git a/files/dhcp/90-dhcp6-systcl.conf.j2 b/files/dhcp/90-dhcp6-systcl.conf.j2 new file mode 100644 index 000000000000..addb94675258 --- /dev/null +++ b/files/dhcp/90-dhcp6-systcl.conf.j2 @@ -0,0 +1,7 @@ +{% if MGMT_INTERFACE %} +net.ipv6.conf.eth0.accept_ra_defrtr = 0 +net.ipv6.conf.eth0.accept_ra = 0 +{% else %} +net.ipv6.conf.eth0.accept_ra_defrtr = 1 +net.ipv6.conf.eth0.accept_ra = 1 +{% endif %} diff --git a/files/dhcp/dhclient.conf b/files/dhcp/dhclient.conf deleted file mode 100644 index 6a542e069fab..000000000000 --- a/files/dhcp/dhclient.conf +++ /dev/null @@ -1,24 +0,0 @@ -# Configuration file for /sbin/dhclient, which is included in Debian's -# dhcp3-client package. -# -# This is a sample configuration file for dhclient. See dhclient.conf's -# man page for more information about the syntax of this file -# and a more comprehensive list of the parameters understood by -# dhclient. -# -# Normally, if the DHCP server provides reasonable information and does -# not leave anything out (like the domain name, for example), then -# few changes must be made to this file, if any. -# - -option rfc3442-classless-static-routes code 121 = array of unsigned integer 8; -option snmp-community code 224 = text; -option minigraph-url code 225 = text; -option acl-url code 226 = text; - -send host-name = gethostname(); -request subnet-mask, broadcast-address, time-offset, routers, - domain-name, domain-name-servers, domain-search, host-name, - dhcp6.name-servers, dhcp6.domain-search, interface-mtu, - rfc3442-classless-static-routes, ntp-servers, - snmp-community, minigraph-url, acl-url; diff --git a/files/dhcp/dhclient.conf.j2 b/files/dhcp/dhclient.conf.j2 new file mode 100644 index 000000000000..2a6f6fa84fbd --- /dev/null +++ b/files/dhcp/dhclient.conf.j2 @@ -0,0 +1,45 @@ +{% block banner %} +# =============== Managed by SONiC Config Engine DO NOT EDIT! =============== +# generated from /usr/share/sonic/templates/dhclient.conf.j2 using sonic-cfggen +# file: /etc/dhcp/dhclient.conf +# +{% endblock banner %} +# Configuration file for /sbin/dhclient, which is included in Debian's +# dhcp3-client package. +# +# This is a sample configuration file for dhclient. See dhclient.conf's +# man page for more information about the syntax of this file +# and a more comprehensive list of the parameters understood by +# dhclient. +# +# Normally, if the DHCP server provides reasonable information and does +# not leave anything out (like the domain name, for example), then +# few changes must be made to this file, if any. +# + +option rfc3442-classless-static-routes code 121 = array of unsigned integer 8; +option snmp-community code 224 = text; +option minigraph-url code 225 = text; +option acl-url code 226 = text; +option tftp-server-name code 66 = text; +option bootfile-name code 67 = text; +option user-class code 77 = text; +option provisioning-script-url code 239 = text; +option dhcp6.user-class code 15 = text; +option dhcp6.provisioning-script-url code 239 = text; +option dhcp6.boot-file-url code 59 = text; + +send host-name = gethostname(); +request subnet-mask, broadcast-address, time-offset, routers, + domain-name, domain-name-servers, domain-search, host-name, + dhcp6.name-servers, dhcp6.domain-search, interface-mtu, dhcp6.fqdn, + rfc3442-classless-static-routes, ntp-servers, log-servers, +{%- if ZTP is defined and ZTP_DHCP_DISABLED is not defined -%}bootfile-name, provisioning-script-url, tftp-server-name, + dhcp6.provisioning-script-url, dhcp6.boot-file-url,{%- endif -%} + snmp-community, minigraph-url, acl-url; +{% if ZTP is defined and ZTP_DHCP_DISABLED is not defined %} +send user-class "SONiC-ZTP"; +send dhcp6.user-class "SONiC-ZTP"; +send dhcp-client-identifier "SONiC##{{ ZTP['mode']['product-name'] }}##{{ ZTP['mode']['serial-no'] }}"; +retry 60; +{% endif %} diff --git a/files/dhcp/graphserviceurl b/files/dhcp/graphserviceurl index f255cdff9877..9bd5fded4b8f 100644 --- a/files/dhcp/graphserviceurl +++ b/files/dhcp/graphserviceurl @@ -1,12 +1,14 @@ -case $reason in - BOUND|RENEW|REBIND|REBOOT) - if [ -n "$new_minigraph_url" ]; then - echo $new_minigraph_url > /tmp/dhcp_graph_url - else - echo "N/A" > /tmp/dhcp_graph_url - fi - if [ -n "$new_acl_url" ]; then - echo $new_acl_url > /tmp/dhcp_acl_url - fi - ;; -esac +if [ ! -e /usr/bin/ztp ] || [ "$(ztp status -c)" = "0:DISABLED" ]; then + case $reason in + BOUND|RENEW|REBIND|REBOOT) + if [ -n "$new_minigraph_url" ]; then + echo $new_minigraph_url > /tmp/dhcp_graph_url + else + echo "N/A" > /tmp/dhcp_graph_url + fi + if [ -n "$new_acl_url" ]; then + echo $new_acl_url > /tmp/dhcp_acl_url + fi + ;; + esac +fi diff --git a/files/dhcp/ifupdown2_policy.json b/files/dhcp/ifupdown2_policy.json new file mode 100644 index 000000000000..9a5010dead8a --- /dev/null +++ b/files/dhcp/ifupdown2_policy.json @@ -0,0 +1,12 @@ +{ + "dhcp" : { + "defaults" : { + "dhcp-wait" : "no" + }, + "iface_defaults" : { + "eth0" : { + "dhcp6-duid" : "LL" + } + } + } +} diff --git a/files/dhcp/rfc3442-classless-routes b/files/dhcp/rfc3442-classless-routes index 64e24192816b..797a0d24429f 100644 --- a/files/dhcp/rfc3442-classless-routes +++ b/files/dhcp/rfc3442-classless-routes @@ -55,8 +55,13 @@ if [ "$RUN" = "yes" ]; then fi # set route (ip detects host routes automatically) - ip -4 route add "${net_address}/${net_length}" \ + if echo $interface | grep -v Ethernet ; then + ip -4 route add "${net_address}/${net_length}" \ ${via_arg} dev "${interface}" table default >/dev/null 2>&1 + else + ip -4 route add "${net_address}/${net_length}" \ + ${via_arg} dev "${interface}" >/dev/null 2>&1 + fi done fi fi diff --git a/files/dhcp/sethostname6 b/files/dhcp/sethostname6 new file mode 100644 index 000000000000..6ca5d8dbc995 --- /dev/null +++ b/files/dhcp/sethostname6 @@ -0,0 +1,14 @@ +case $reason in + BOUND6|RENEW6|REBIND6|REBOOT) + current_dhcp6_fqdn=`hostname` + if [ "$current_dhcp6_fqdn" != "$new_dhcp6_fqdn" ] && [ -n "$new_dhcp6_fqdn" ] + then + echo $new_dhcp6_fqdn > /etc/hostname + hostname -F /etc/hostname + sed -i "/\s$current_dhcp6_fqdn$/d" /etc/hosts + sed -i "/\s$new_dhcp6_fqdn$/d" /etc/hosts + echo "127.0.0.1 $new_dhcp6_fqdn" >> /etc/hosts + echo ":: $new_dhcp6_fqdn" >> /etc/hosts + fi + ;; +esac diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index 6226bb16768f..e5744c7ca65b 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -225,7 +225,9 @@ class ControlPlaneAclManager(object): rule_cmd = "ip6tables" if table_ip_version == 6 else "iptables" rule_cmd += " -A INPUT -p {}".format(ip_protocol) - if "SRC_IP" in rule_props and rule_props["SRC_IP"]: + if "SRC_IPV6" in rule_props and rule_props["SRC_IPV6"]: + rule_cmd += " -s {}".format(rule_props["SRC_IPV6"]) + elif "SRC_IP" in rule_props and rule_props["SRC_IP"]: rule_cmd += " -s {}".format(rule_props["SRC_IP"]) rule_cmd += " --dport {}".format(dst_port) diff --git a/files/image_config/config-setup/config-setup b/files/image_config/config-setup/config-setup new file mode 100755 index 000000000000..afff97806518 --- /dev/null +++ b/files/image_config/config-setup/config-setup @@ -0,0 +1,398 @@ +#!/bin/bash +########################################################################### +# Copyright 2019 Broadcom. The term "Broadcom" refers to Broadcom Inc. # +# and/or its subsidiaries. # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# +# See the License for the specific language governing permissions and # +# limitations under the License. # +# # +########################################################################### +# SONiC Configuration Setup # +# # +# This script is used to initialize configuration used # +# by SONiC SWSS. It also performs configuration # +# migration. # +# # +########################################################################### + +# Initialize constants +UPDATEGRAPH_CONF=/etc/sonic/updategraph.conf +CONFIG_DB_JSON=/etc/sonic/config_db.json +MINGRAPH_FILE=/etc/sonic/minigraph.xml +TMP_ZTP_CONFIG_DB_JSON=/tmp/ztp_config_db.json +FACTORY_DEFAULT_HOOKS=/etc/config-setup/factory-default-hooks.d +CONFIG_PRE_MIGRATION_HOOKS=/etc/config-setup/config-migration-pre-hooks.d +CONFIG_POST_MIGRATION_HOOKS=/etc/config-setup/config-migration-post-hooks.d +CONFIG_SETUP_VAR_DIR=/var/lib/config-setup +CONFIG_SETUP_PRE_MIGRATION_FLAG=${CONFIG_SETUP_VAR_DIR}/pending_pre_migration +CONFIG_SETUP_POST_MIGRATION_FLAG=${CONFIG_SETUP_VAR_DIR}/pending_post_migration +CONFIG_SETUP_INITIALIZATION_FLAG=${CONFIG_SETUP_VAR_DIR}/pending_initialization + +# Command usage and help +usage() +{ + cat << EOF + Usage: config-setup < backup | boot | factory > + + backup - Take a backup copy of SONiC configuration. + boot - Initialize/migrate SONiC configuration during system boot. + factory - Create factory default SONiC configuration and save it to + to ${CONFIG_DB_JSON}. +EOF +} + +# run given script +run_hook() { + local script="$1" + local exit_status=0 + + if [ -f $script ]; then + # Check hook for syntactical correctness before executing it + /bin/bash -n $script + exit_status=$? + if [ "$exit_status" -eq 0 ]; then + . $script + fi + exit_status=$? + fi + + if [ -n "$exit_status" ] && [ "$exit_status" -ne 0 ]; then + echo "$script returned non-zero exit status $exit_status" + fi + + return $exit_status +} + +# run scripts in given directory +run_hookdir() { + local dir="$1" + local progress_file="$2" + local exit_status=0 + + if [ -d "$dir" ]; then + if [ -n $progress_file ]; then + [ ! -d $(dirname $progress_file) ] && mkdir -p $(dirname $progress_file) + [ ! -e $progress_file ] && run-parts --list $dir > $progress_file + SCRIPT_LIST=$(cat $progress_file) + else + SCRIPT_LIST=$(run-parts --list $dir) + fi + + for script in $SCRIPT_LIST; do + run_hook $script + exit_status=$((exit_status|$?)) + script_name=$(basename $script) + sed -i "/$script_name/d" $progress_file + done + [ -n $progress_file ] && [ "$(cat ${progress_file})" = "" ] && rm -f ${progress_file} + fi + + return $exit_status +} + +# Reload minigraph.xml file on disk +reload_minigraph() +{ + echo "Reloading minigraph..." + if [ ! -f /etc/sonic/init_cfg.json ]; then + echo "{}" > /etc/sonic/init_cfg.json + fi + sonic-db-cli CONFIG_DB FLUSHDB + sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --write-to-db + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" + if [ -f /etc/sonic/acl.json ]; then + acl-loader update full /etc/sonic/acl.json + fi + config qos reload + pfcwd start_default + + if [[ -x /usr/bin/db_migrator.py ]]; then + # Set latest version number + /usr/bin/db_migrator.py -o set_version + fi +} + +# Restore SONiC configuration from a backup copy +function copy_config_files_and_directories() +{ + for file_dir in $@; do + if [ -f /etc/sonic/old_config/${file_dir} ] || [ -d /etc/sonic/old_config/${file_dir} ]; then + echo "Copying SONiC configuration ${file_dir} ..." + cp -ar /etc/sonic/old_config/${file_dir} /etc/sonic/ + else + echo "Missing SONiC configuration ${file_dir} ..." + fi + done +} + +# Check if SONiC swich has booted after a warm reboot request +check_system_warm_boot() +{ + SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. + if [[ x"$SYSTEM_WARM_START" == x"true" ]]; then + WARM_BOOT="true" + else + WARM_BOOT="false" + fi +} + +# Check if updategraph service is administratively enabled +updategraph_is_enabled() +{ + rv=1 + if [ -e ${UPDATEGRAPH_CONF} ]; then + updategraph_mode=$(grep enabled ${UPDATEGRAPH_CONF} | head -n 1 | cut -f2 -d=) + [ "${updategraph_mode}" = "true" ] && rv = 0 + fi + return $rv +} + +# Disable updategraph admininistratively +disable_updategraph() +{ + sed -i "/enabled=/d" ${UPDATEGRAPH_CONF} + echo "enabled=false" >> ${UPDATEGRAPH_CONF} +} + +# Check if Zero Touch Provisioning is available and is administratively enabled +ztp_is_enabled() +{ + rv=1 + if [ -e /usr/bin/ztp ]; then + status=$(ztp status -c) + [ "$status" != "0:DISABLED" ] && [ "$status" != "" ] && rv=0 + fi + return $rv +} + +# Load requested SONiC configuration into config DB and initialize it +# Usage: load_config +# +# +load_config() +{ + CONFIG_FILE=${1} + if [ "${CONFIG_FILE}" = "" ]; then + return 1 + fi + + sonic-db-cli CONFIG_DB FLUSHDB + sonic-cfggen -j ${CONFIG_FILE} --write-to-db + if [ $? -ne 0 ]; then + return $? + fi + + if [[ -x /usr/bin/db_migrator.py ]]; then + # Migrate the DB to the latest schema version if needed + /usr/bin/db_migrator.py -o migrate + fi + + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" + return 0 +} + + +# Generate requested SONiC configuration and save it as destination file +# Usage: generate_config < factory | ztp > +# +# factory - Create factory default configuration +# ztp - Create Zero Touch Provisioning Configuration +# used for provisioning data discovery. +# +generate_config() +{ + # Collect all information needed to generate configuration + PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + PRESET=(`head -n 1 /usr/share/sonic/device/$PLATFORM/default_sku`) + HW_KEY=${PRESET[0]} + DEFAULT_PRESET=${PRESET[1]} + + # Parse arguments passed + CONFIG_TYPE=$1 + DEST_FILE=$2 + + if [ "$1" = "ztp" ]; then + /usr/lib/ztp/ztp-profile.sh create ${DEST_FILE} + elif [ "$1" = "factory" ]; then + rv=1 + + # Execute config initialization hooks + run_hookdir ${FACTORY_DEFAULT_HOOKS} ${CONFIG_SETUP_INITIALIZATION_FLAG} + + # Use preset defined in default_sku + if [ ! -e ${DEST_FILE} ]; then + sonic-cfggen -H -k ${HW_KEY} --preset ${DEFAULT_PRESET} > ${DEST_FILE} + rv=$? + if [ $rv -ne 0 ]; then + return $rv + fi + fi + fi + return 0 +} + +# Create SONiC configuration for first time bootup +# - If ZTP is enabled, ZTP configuraion is created +# - If ZTP is disabled and updategraph is disabled, factory default configuration +# is created +# - If updategraph is enabled and ZTP is disabled, updategraph initializes +# configuration +do_config_initialization() +{ + if ! updategraph_is_enabled ; then + if ! ztp_is_enabled ; then + echo "No configuration detected, generating factory default configuration..." + generate_config factory ${CONFIG_DB_JSON} + load_config ${CONFIG_DB_JSON} + fi + fi + + if ztp_is_enabled ; then + echo "No configuration detected, initiating zero touch provisioning..." + generate_config ztp ${TMP_ZTP_CONFIG_DB_JSON} + load_config ${TMP_ZTP_CONFIG_DB_JSON} + rm -f ${TMP_ZTP_CONFIG_DB_JSON} + fi + + rm -f /tmp/pending_config_initialization +} + +# Restore config-setup post migration hooks from a backup copy +copy_post_migration_hooks() +{ + BACKUP_DIR=/etc/sonic/old_config/config-migration-post-hooks.d + if [ -d ${BACKUP_DIR} ]; then + [ -d ${CONFIG_POST_MIGRATION_HOOKS} ] || mkdir -p ${CONFIG_POST_MIGRATION_HOOKS} + for hook in $(ls -1 ${BACKUP_DIR}) ; do + if [ ! -e ${CONFIG_POST_MIGRATION_HOOKS}/$hook ]; then + cp -ar ${BACKUP_DIR}/$hook ${CONFIG_POST_MIGRATION_HOOKS} + fi + done + fi +} + +# Perform configuration migration from backup copy. +# - This step is performed when a new image is installed and SONiC switch boots into it +do_config_migration() +{ + # Identify list of files to migrate + copy_list="minigraph.xml snmp.yml acl.json config_db.json frr" + + # Migrate all configuration files from old to new + copy_config_files_and_directories $copy_list + + # Migrate post-migration hooks + copy_post_migration_hooks + + # Execute custom hooks if present + run_hookdir ${CONFIG_POST_MIGRATION_HOOKS} ${CONFIG_SETUP_POST_MIGRATION_FLAG} + + if [ x"${WARM_BOOT}" == x"true" ]; then + echo "Warm reboot detected..." + disable_updategraph + rm -f /tmp/pending_config_migration + exit 0 + elif [ -r ${CONFIG_DB_JSON} ]; then + echo "Use config_db.json from old system..." + sonic-cfggen -j ${CONFIG_DB_JSON} --write-to-db + + if [[ -x /usr/bin/db_migrator.py ]]; then + # Migrate the DB to the latest schema version if needed + /usr/bin/db_migrator.py -o migrate + fi + elif [ -r ${MINGRAPH_FILE} ]; then + echo "Use minigraph.xml from old system..." + reload_minigraph + sonic-cfggen -d --print-data > ${CONFIG_DB_JSON} + + # Disable updategraph + disable_updategraph + else + echo "Didn't found neither config_db.json nor minigraph.xml ..." + fi + + rm -f /tmp/pending_config_migration +} + +# Take a backup of current SONiC configuration +do_config_backup() +{ + echo "Taking backup of curent configuration" + rm -rf /host/old_config + cp -ar /etc/sonic /host/old_config + [ -d ${CONFIG_POST_MIGRATION_HOOKS} ] && cp -arL ${CONFIG_POST_MIGRATION_HOOKS} /host/old_config + + # Execute custom hooks if present + run_hookdir ${CONFIG_PRE_MIGRATION_HOOKS} ${CONFIG_SETUP_PRE_MIGRATION_FLAG} +} + +# Process switch bootup event +# - Check if it is warm boot and take no further action +# - Perform configuration migration if requested +# - Perform configuration initialization if requested +# - If no saved SONiC configuration is found and ZTP is enabled, +# start ZTP +boot_config() +{ + check_system_warm_boot + if [ -e /tmp/pending_config_migration ] || [ -e ${CONFIG_SETUP_POST_MIGRATION_FLAG} ]; then + do_config_migration + fi + + if [ -e /tmp/pending_config_initialization ] || [ -e ${CONFIG_SETUP_INITIALIZATION_FLAG} ]; then + do_config_initialization + fi + + # If no startup configuration is found, create a configuration to be used + if [ ! -e ${CONFIG_DB_JSON} ]; then + do_config_initialization + # force ZTP to restart + if ztp_is_enabled ; then + ztp_status=$(ztp status -c) + if [ "$ztp_status" = "5:SUCCESS" ] || \ + [ "$ztp_status" = "6:FAILED" ]; then + # Clear completed ztp information, before starting a new one + ztp erase -y + else + touch /tmp/pending_ztp_restart + fi + fi + fi +} + +### Execution starts here ### + +CMD=$1 +# Default command is boot +if [ "$CMD" = "" ] || [ "$CMD" = "help" ] || \ + [ "$CMD" = "-h" ] || [ "$CMD" = "--help" ]; then + usage + exit 1 +fi + +# Process switch bootup event +if [ "$CMD" = "boot" ]; then + boot_config +fi + +# Process factory default configuration creation request +if [ "$CMD" = "factory" ]; then + generate_config factory ${CONFIG_DB_JSON} +fi + +# Take a backup of current configuration +if [ "$CMD" = "backup" ]; then + do_config_backup +fi + +exit 0 diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index e10288c0dd37..4ac3be83d06e 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -2,7 +2,6 @@ # -*- coding: utf-8 -*- import os -import re import sys import subprocess import syslog @@ -24,13 +23,6 @@ TACPLUS_SERVER_TIMEOUT_DEFAULT = "5" TACPLUS_SERVER_AUTH_TYPE_DEFAULT = "pap" -def is_valid_hostname(hostname): - if hostname[-1] == "." or len(hostname) > 253: - return False - allowed = re.compile("(?!-)[A-Z\d-]{1,63}(? /etc/network/interfaces +# Check if ZTP DHCP policy has been installed +if [ -e /etc/network/ifupdown2/policy.d/ztp_dhcp.json ]; then + # Obtain port operational state information + redis-dump -d 0 -k "PORT_TABLE:Ethernet*" -y > /tmp/ztp_port_data.json + + if [ $? -ne 0 ] || [ ! -e /tmp/ztp_port_data.json ] || [ "$(cat /tmp/ztp_port_data.json)" = "" ]; then + echo "{}" > /tmp/ztp_port_data.json + fi + + # Create an input file with ztp input information + echo "{ \"PORT_DATA\" : $(cat /tmp/ztp_port_data.json) }" > \ + /tmp/ztp_input.json +else + echo "{ \"ZTP_DHCP_DISABLED\" : \"true\" }" > /tmp/ztp_input.json +fi + +# Create /e/n/i file for existing and active interfaces +sonic-cfggen -d -j /tmp/ztp_input.json -t /usr/share/sonic/templates/interfaces.j2 > /etc/network/interfaces [ -f /var/run/dhclient.eth0.pid ] && kill `cat /var/run/dhclient.eth0.pid` && rm -f /var/run/dhclient.eth0.pid +[ -f /var/run/dhclient6.eth0.pid ] && kill `cat /var/run/dhclient6.eth0.pid` && rm -f /var/run/dhclient6.eth0.pid +for intf_pid in $(ls -1 /var/run/dhclient*.Ethernet*.pid 2> /dev/null); do + [ -f ${intf_pid} ] && kill `cat ${intf_pid}` && rm -f ${intf_pid} +done + +sonic-cfggen -d -j /tmp/ztp_input.json -t /usr/share/sonic/templates/90-dhcp6-systcl.conf.j2 > /etc/sysctl.d/90-dhcp6-systcl.conf +# Read sysctl conf files again +sysctl -p /etc/sysctl.d/90-dhcp6-systcl.conf + +sonic-cfggen -d -j /tmp/ztp_input.json -t /usr/share/sonic/templates/dhclient.conf.j2 > /etc/dhcp/dhclient.conf systemctl restart networking -ifdown lo && ifup lo +# Clean-up created files +rm -f /tmp/ztp_input.json /tmp/ztp_port_data.json + diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index 91be4437fc06..dbb2b1f3418a 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -5,28 +5,60 @@ # file: /etc/network/interfaces # {% endblock banner %} +{% block mgmt_vrf %} {% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} auto mgmt iface mgmt vrf-table 5000 -{% endif %} -{% block loopback %} -# The loopback network interface -auto lo -iface lo inet loopback -{% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} # The loopback network interface for mgmt VRF that is required for applications like NTP up ip link add lo-m type dummy + up ip link set dev lo-m master mgmt up ip addr add 127.0.0.1/8 dev lo-m up ip link set lo-m up - up ip link set dev lo-m master mgmt - down ip link delete dev lo-m + down ip link delete dev lo-m {% endif %} +{% endblock mgmt_vrf %} +{% block loopback %} +# The loopback network interface +auto lo +iface lo inet loopback {% endblock loopback %} {% block mgmt_interface %} # The management network interface auto eth0 +{% if (ZTP_DHCP_DISABLED is not defined) and (ZTP is defined) and (ZTP['mode'] is defined and ZTP['mode']['profile'] == 'active') %} + + +# ZTP out-of-band interface +allow-hotplug eth0 +{% if ZTP['mode']['ipv4'] == 'true' %} +iface eth0 inet dhcp +{% endif %} +{% if ZTP['mode']['ipv6'] == 'true' %} +iface eth0 inet6 dhcp + up sysctl net.ipv6.conf.eth0.accept_ra=1 + down sysctl net.ipv6.conf.eth0.accept_ra=0 +{% endif %} + +{% if ZTP['mode']['inband'] == 'true' %} +{% for port in PORT %} + +# ZTP in-band interface {{ port }} +auto {{ port }} +allow-hotplug {{ port }} +{% if PORT_DATA['PORT_TABLE:'+port] is defined and PORT_DATA['PORT_TABLE:'+port]['value']['oper_status'] == 'up' %} +{% if ZTP['mode']['ipv4'] == 'true' %} +iface {{ port }} inet dhcp +{% endif %} +{% if ZTP['mode']['ipv6'] == 'true' %} +iface {{ port }} inet6 dhcp +{% endif %} +{% endif %} +{% endfor %} +{% endif %} + +{% else %} {% if MGMT_INTERFACE %} {% for (name, prefix) in MGMT_INTERFACE|pfx_filter %} iface eth0 {{ 'inet' if prefix | ipv4 else 'inet6' }} static @@ -50,14 +82,14 @@ iface eth0 {{ 'inet' if prefix | ipv4 else 'inet6' }} static up ip rule add to {{ route }} table {{ vrf_table }} {% endfor %} # management port down rules - down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete default via {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} dev eth0 table {{ vrf_table }} - down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete {{ prefix | network }}/{{ prefix | prefixlen }} dev eth0 table {{ vrf_table }} - down ip {{ '-4' if prefix | ipv4 else '-6' }} rule delete from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} + pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete default via {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} dev eth0 table {{ vrf_table }} + pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete {{ prefix | network }}/{{ prefix | prefixlen }} dev eth0 table {{ vrf_table }} + pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} rule delete from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} {% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} down cgdelete -g l3mdev:mgmt {% endif %} {% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %} - down ip rule delete to {{ route }} table {{ vrf_table }} + pre-down ip rule delete to {{ route }} table {{ vrf_table }} {% endfor %} {# TODO: COPP policy type rules #} {% endfor %} @@ -70,6 +102,10 @@ iface eth0 inet dhcp up cgset -r l3mdev.master-device=mgmt mgmt down cgdelete -g l3mdev:mgmt {% endif %} +iface eth0 inet6 dhcp + up sysctl net.ipv6.conf.eth0.accept_ra=1 + down sysctl net.ipv6.conf.eth0.accept_ra=0 +{% endif %} {% endif %} # source /etc/network/interfaces.d/* diff --git a/files/image_config/kubernetes/kubernetes.list b/files/image_config/kubernetes/kubernetes.list new file mode 100644 index 000000000000..5c888b830623 --- /dev/null +++ b/files/image_config/kubernetes/kubernetes.list @@ -0,0 +1,4 @@ +# The following is as recommended by https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/ +# Whenever an OS update from Debian stretch is done, make sure to find the matching k8s sources list +# +deb https://apt.kubernetes.io/ kubernetes-xenial main diff --git a/files/image_config/monit/conf.d/sonic-host b/files/image_config/monit/conf.d/sonic-host index 8eaa1671d821..5a67f7a9909b 100644 --- a/files/image_config/monit/conf.d/sonic-host +++ b/files/image_config/monit/conf.d/sonic-host @@ -6,17 +6,17 @@ ############################################################################### check filesystem root-overlay with path / - if space usage > 90% for 5 times within 10 cycles then alert + if space usage > 90% for 10 times within 20 cycles then alert check filesystem var-log with path /var/log - if space usage > 90% for 5 times within 10 cycles then alert + if space usage > 90% for 10 times within 20 cycles then alert check system $HOST - if memory usage > 90% for 5 times within 10 cycles then alert - if cpu usage (user) > 90% for 5 times within 10 cycles then alert - if cpu usage (system) > 90% for 5 times within 10 cycles then alert + if memory usage > 90% for 10 times within 20 cycles then alert + if cpu usage (user) > 90% for 10 times within 20 cycles then alert + if cpu usage (system) > 90% for 10 times within 20 cycles then alert check process rsyslog with pidfile /var/run/rsyslogd.pid start program = "/bin/systemctl start rsyslog.service" stop program = "/bin/systemctl stop rsyslog.service" - if totalmem > 800 MB for 5 times within 10 cycles then restart + if totalmem > 800 MB for 10 times within 20 cycles then restart diff --git a/files/image_config/monit/monitrc b/files/image_config/monit/monitrc index 7864069e3af1..74068f12d3f8 100644 --- a/files/image_config/monit/monitrc +++ b/files/image_config/monit/monitrc @@ -16,9 +16,10 @@ ## ## 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 daemon 60 # check services at 1-minute intervals + with start delay 300 # we delay Monit to start monitoring for 5 minutes + # intentionally such that all containers and processes + # have ample time to start up. # # ## Set syslog logging. If you want to log to a standalone log file instead, diff --git a/files/image_config/ntp/ntp.conf.j2 b/files/image_config/ntp/ntp.conf.j2 index cef6527fc28f..dbde694432e6 100644 --- a/files/image_config/ntp/ntp.conf.j2 +++ b/files/image_config/ntp/ntp.conf.j2 @@ -5,6 +5,10 @@ # /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help +# To avoid ntpd from panic and exit if the drift between new time and +# current system time is large. +tinker panic 0 + driftfile /var/lib/ntp/ntp.drift diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index d64ec1bb7916..e36b20950b42 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -328,10 +328,10 @@ if [ -f $FIRST_BOOT_FILE ]; then mv /host/grub.cfg /host/grub/grub.cfg fi + # Create dir where following scripts put their output files + mkdir -p /var/platform + firsttime_exit fi -# Create dir where following scripts put their output files -mkdir -p /var/platform - exit 0 diff --git a/files/image_config/procdockerstatsd/procdockerstatsd b/files/image_config/procdockerstatsd/procdockerstatsd old mode 100644 new mode 100755 index 66d2d45009d5..65d4b029b0ff --- a/files/image_config/procdockerstatsd/procdockerstatsd +++ b/files/image_config/procdockerstatsd/procdockerstatsd @@ -1,4 +1,4 @@ -# !/usr/bin/env python +#!/usr/bin/env python ''' procdockerstatsd Daemon which periodically gathers process and docker statistics and pushes the data to STATE_DB @@ -41,8 +41,8 @@ class ProcDockerStats: def __init__(self): self.state_db = swsssdk.SonicV2Connector(host=REDIS_HOSTIP) - self.state_db.connect("STATE_DB") - + self.state_db.connect("STATE_DB") + def run_command(self, cmd): proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) (stdout, stderr) = proc.communicate() @@ -75,7 +75,7 @@ class ProcDockerStats: # To remove extra space before UID val = list(filter(None, values1)) # Merging extra columns created due to space in cmd ouput - val[8:] = [''.join(val[8:])] + val[8:] = [' '.join(val[8:])] process_data = dict(zip(keylist, val)) process_data_list.append(process_data) return process_data_list @@ -109,10 +109,10 @@ class ProcDockerStats: for row in dict_list[0:]: cid = row.get('CONTAINER ID') if cid: - key = 'DOCKER_STATS|' + str(cid) + key = 'DOCKER_STATS|' + str(cid) dockerdict[key] = {} dockerdict[key]['NAME'] = row.get('NAME') - + splitcol = row.get('CPU %') cpu = re.split("%", str(splitcol)) dockerdict[key]['CPU%'] = str(cpu[0]) @@ -131,7 +131,7 @@ class ProcDockerStats: netio = re.split(" / ", str(splitcol)) dockerdict[key]['NET_IN_BYTES'] = str(self.convert_to_bytes(netio[0])) dockerdict[key]['NET_OUT_BYTES'] = str(self.convert_to_bytes(netio[1])) - + splitcol = row.get('BLOCK I/O') blockio = re.split(" / ", str(splitcol)) dockerdict[key]['BLOCK_IN_BYTES'] = str(self.convert_to_bytes(blockio[0])) diff --git a/files/image_config/procdockerstatsd/procdockerstatsd.service b/files/image_config/procdockerstatsd/procdockerstatsd.service index 4e38c350a577..010dac15b2e6 100644 --- a/files/image_config/procdockerstatsd/procdockerstatsd.service +++ b/files/image_config/procdockerstatsd/procdockerstatsd.service @@ -6,7 +6,7 @@ After=database.service updategraph.service [Service] Type=simple ExecStart=/usr/bin/procdockerstatsd -Restart=Always +Restart=always [Install] WantedBy=multi-user.target diff --git a/files/image_config/process-reboot-cause/process-reboot-cause b/files/image_config/process-reboot-cause/process-reboot-cause index e5d228b4c6b6..409deb7d6859 100755 --- a/files/image_config/process-reboot-cause/process-reboot-cause +++ b/files/image_config/process-reboot-cause/process-reboot-cause @@ -62,10 +62,10 @@ def parse_warmfast_reboot_from_proc_cmdline(): if os.path.isfile(REBOOT_TYPE_KEXEC_FILE): with open(REBOOT_TYPE_KEXEC_FILE, "r") as cause_file: cause_file_kexec = cause_file.readline() - m = re.match(REBOOT_TYPE_KEXEC_PATTERN_WARM, cause_file_kexec) + m = re.search(REBOOT_TYPE_KEXEC_PATTERN_WARM, cause_file_kexec) if m and m.group(1): return 'warm-reboot' - m = re.match(REBOOT_TYPE_KEXEC_PATTERN_FAST, cause_file_kexec) + m = re.search(REBOOT_TYPE_KEXEC_PATTERN_FAST, cause_file_kexec) if m and m.group(1): return 'fast-reboot' return None @@ -77,13 +77,61 @@ def find_software_reboot_cause(): if os.path.isfile(REBOOT_CAUSE_FILE): with open(REBOOT_CAUSE_FILE, "r") as cause_file: software_reboot_cause = cause_file.readline().rstrip('\n') + log_info("{} indicates the reboot cause: {}".format(REBOOT_CAUSE_FILE, software_reboot_cause)) + else: + log_info("Reboot cause file {} not found".format(REBOOT_CAUSE_FILE)) if os.path.isfile(FIRST_BOOT_PLATFORM_FILE): os.remove(FIRST_BOOT_PLATFORM_FILE) return software_reboot_cause + + +def find_proc_cmdline_reboot_cause(): + proc_cmdline_reboot_cause = parse_warmfast_reboot_from_proc_cmdline() + if proc_cmdline_reboot_cause: + log_info("/proc/cmdline indicates reboot type: {}".format(proc_cmdline_reboot_cause)) + else: + log_info("No reboot cause found from /proc/cmdline") + return proc_cmdline_reboot_cause + + +def find_hardware_reboot_cause(): + hardware_reboot_cause = None + + # Until all platform vendors have provided sonic_platform packages, + # if there is no sonic_platform package installed, we only provide + # software-related reboot causes. + try: + import sonic_platform + + platform = sonic_platform.platform.Platform() + + chassis = platform.get_chassis() + + hardware_reboot_cause_major, hardware_reboot_cause_minor = chassis.get_reboot_cause() + + if hardware_reboot_cause_major == chassis.REBOOT_CAUSE_NON_HARDWARE: + # The reboot was not caused by hardware. If there is a REBOOT_CAUSE_FILE, it will + # contain any software-related reboot info. We will use it as the previous cause. + pass + elif hardware_reboot_cause_major == chassis.REBOOT_CAUSE_HARDWARE_OTHER: + hardware_reboot_cause = "{} ({})".format(hardware_reboot_cause_major, hardware_reboot_cause_minor) + else: + hardware_reboot_cause = hardware_reboot_cause_major + except ImportError as err: + log_warning("sonic_platform package not installed. Unable to detect hardware reboot causes.") + + if hardware_reboot_cause: + log_info("Platform api indicates reboot cause {}".format(hardware_reboot_cause)) + else: + log_info("No reboot cause found from platform api") + + return hardware_reboot_cause + + def main(): log_info("Starting up...") @@ -99,54 +147,33 @@ def main(): if os.path.exists(PREVIOUS_REBOOT_CAUSE_FILE): os.remove(PREVIOUS_REBOOT_CAUSE_FILE) - # Set a default previous reboot cause previous_reboot_cause = UNKNOWN_REBOOT_CAUSE - # Until all platform vendors have provided sonic_platform packages, - # if there is no sonic_platform package installed, we only provide - # software-related reboot causes. - try: - import sonic_platform - - # 1. Check if the previous reboot was warm/fast reboot by testing whether there is "fast|fastfast|warm" in /proc/cmdline - # If yes, the content of /hosts/reboot-cause/reboot-cause.txt will be treated as the reboot cause - proc_cmdline_reboot_cause = parse_warmfast_reboot_from_proc_cmdline() - if proc_cmdline_reboot_cause: - log_info("/proc/cmdline indicates reboot type: {}".format(proc_cmdline_reboot_cause)) - if os.path.isfile(REBOOT_CAUSE_FILE): - with open(REBOOT_CAUSE_FILE, "r") as cause_file: - proc_cmdline_reboot_cause = cause_file.readline().rstrip('\n') - else: - # /proc/cmdline says it's a warm/fast reboot but /host/reboot-cause.txt doesn't exist. - # This could happen when upgrading from a version doesn't support reboot cause. - log_info("Reboot cause file {} doesn't exist".format(REBOOT_CAUSE_DIR)) - - if proc_cmdline_reboot_cause is not None: - previous_reboot_cause = proc_cmdline_reboot_cause - else: - # 2. Check if the previous reboot was caused by hardware - # If yes, the hardware reboot cause will be treated as the reboot cause - platform = sonic_platform.platform.Platform() - - chassis = platform.get_chassis() - - hardware_reboot_cause, optional_details = chassis.get_reboot_cause() - - if hardware_reboot_cause == chassis.REBOOT_CAUSE_NON_HARDWARE: - # The reboot was not caused by hardware. If there is a REBOOT_CAUSE_FILE, it will - # contain any software-related reboot info. We will use it as the previous cause. - previous_reboot_cause = find_software_reboot_cause() - elif hardware_reboot_cause == chassis.REBOOT_CAUSE_HARDWARE_OTHER: - previous_reboot_cause = "{} ({})".format(hardware_reboot_cause, optional_details) - else: - previous_reboot_cause = hardware_reboot_cause - except ImportError as err: - log_warning("sonic_platform package not installed. Unable to detect hardware reboot causes.") - - # If there is a REBOOT_CAUSE_FILE, it will contain any software-related - # reboot info. We will use it as the previous cause. - previous_reboot_cause = find_software_reboot_cause() + # 1. Check if the previous reboot was warm/fast reboot by testing whether there is "fast|fastfast|warm" in /proc/cmdline + proc_cmdline_reboot_cause = find_proc_cmdline_reboot_cause() + + # 2. Check if the previous reboot was caused by hardware + # If yes, the hardware reboot cause will be treated as the reboot cause + hardware_reboot_cause = find_hardware_reboot_cause() + + # 3. If there is a REBOOT_CAUSE_FILE, it will contain any software-related + # reboot info. We will use it as the previous cause. + software_reboot_cause = find_software_reboot_cause() + + # The main decision logic of the reboot cause: + # If there is a reboot cause indicated by /proc/cmdline, it should be warmreboot/fastreboot + # the software_reboot_cause which is the content of /hosts/reboot-cause/reboot-cause.txt + # will be treated as the reboot cause + # Elif there is a reboot cause indicated by platform API, + # the hardware_reboot_cause will be treated as the reboot cause + # Else the software_reboot_cause will be treated as the reboot cause + if proc_cmdline_reboot_cause is not None: + previous_reboot_cause = software_reboot_cause + elif hardware_reboot_cause is not None: + previous_reboot_cause = hardware_reboot_cause + else: + previous_reboot_cause = software_reboot_cause # Write the previous reboot cause to PREVIOUS_REBOOT_CAUSE_FILE with open(PREVIOUS_REBOOT_CAUSE_FILE, "w") as prev_cause_file: diff --git a/files/image_config/process-reboot-cause/process-reboot-cause.service b/files/image_config/process-reboot-cause/process-reboot-cause.service index a429339dbe58..b9821f60c420 100644 --- a/files/image_config/process-reboot-cause/process-reboot-cause.service +++ b/files/image_config/process-reboot-cause/process-reboot-cause.service @@ -5,6 +5,3 @@ After=rc-local.service [Service] Type=simple ExecStart=/usr/bin/process-reboot-cause - -[Install] -WantedBy=multi-user.target diff --git a/files/image_config/snmp/snmp.yml b/files/image_config/snmp/snmp.yml index b200670f0d94..117619975fbb 100644 --- a/files/image_config/snmp/snmp.yml +++ b/files/image_config/snmp/snmp.yml @@ -1,5 +1,2 @@ snmp_rocommunity: public snmp_location: public -v1_trap_dest: NotConfigured -v2_trap_dest: NotConfigured -v3_trap_dest: NotConfigured diff --git a/files/image_config/topology/topology.service b/files/image_config/topology/topology.service new file mode 100644 index 000000000000..eea4bf65230a --- /dev/null +++ b/files/image_config/topology/topology.service @@ -0,0 +1,16 @@ +[Unit] +Description=Internal topology service +Requires=database.service +After=database.service +PartOf=database.service + +[Service] +Type=oneshot +User=root +RemainAfterExit=yes +ExecStart=/usr/bin/topology.sh start +ExecStop=/usr/bin/topology.sh stop + +[Install] +WantedBy=multi-user.target + diff --git a/files/image_config/topology/topology.sh b/files/image_config/topology/topology.sh new file mode 100755 index 000000000000..dde7da247484 --- /dev/null +++ b/files/image_config/topology/topology.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# This script is invoked by topology.service only +# for multi-asic virtual platform. For multi-asic platform +# multiple Database instances are present +# and HWKSU information is retrieved from first database instance. +# + +start() { + TOPOLOGY_SCRIPT="topology.sh" + PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` + /usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT start +} +stop() { + TOPOLOGY_SCRIPT="topology.sh" + PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` + usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT stop +} + +case "$1" in + start|stop) + $1 + ;; + *) + echo "Usage: $0 {start|stop}" + ;; +esac diff --git a/files/image_config/updategraph/updategraph b/files/image_config/updategraph/updategraph index 2eb510afa4e1..a24d452b1ad2 100755 --- a/files/image_config/updategraph/updategraph +++ b/files/image_config/updategraph/updategraph @@ -1,16 +1,14 @@ #!/bin/bash -CONFIG_DB_INDEX=4 - reload_minigraph() { echo "Reloading minigraph..." if [ ! -f /etc/sonic/init_cfg.json ]; then echo "{}" > /etc/sonic/init_cfg.json fi - redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-db-cli CONFIG_DB FLUSHDB sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --write-to-db - redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" if [ -f /etc/sonic/acl.json ]; then acl-loader update full /etc/sonic/acl.json fi @@ -26,32 +24,6 @@ reload_minigraph() fi } -function copy_config_files_and_directories() -{ - for file_dir in $@; do - if [ -f /etc/sonic/old_config/${file_dir} ] || [ -d /etc/sonic/old_config/${file_dir} ]; then - logger "Copying SONiC configuration ${file_dir} ..." - cp -ar /etc/sonic/old_config/${file_dir} /etc/sonic/ - else - logger "Missing SONiC configuration ${file_dir} ..." - fi - done - - sync -} - -function check_system_warm_boot() -{ - SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` - # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. - if [[ x"$SYSTEM_WARM_START" == x"true" ]]; then - WARM_BOOT="true" - else - WARM_BOOT="false" - fi -} - - if [ ! -f /etc/sonic/updategraph.conf ]; then echo "No updategraph.conf found, generating a default one." echo "enabled=false" >/etc/sonic/updategraph.conf @@ -59,46 +31,6 @@ fi . /etc/sonic/updategraph.conf -check_system_warm_boot -copy_list="minigraph.xml snmp.yml acl.json config_db.json frr" -if [ -f /tmp/pending_config_migration ]; then - copy_config_files_and_directories $copy_list - if [ x"${WARM_BOOT}" == x"true" ]; then - echo "Warm reboot detected..." - elif [ -r /etc/sonic/config_db.json ]; then - echo "Use config_db.json from old system..." - sonic-cfggen -j /etc/sonic/config_db.json --write-to-db - - if [[ -x /usr/bin/db_migrator.py ]]; then - # Migrate the DB to the latest schema version if needed - /usr/bin/db_migrator.py -o migrate - fi - elif [ -r /etc/sonic/minigraph.xml ]; then - echo "Use minigraph.xml from old system..." - reload_minigraph - sonic-cfggen -d --print-data > /etc/sonic/config_db.json - else - echo "Didn't found neither config_db.json nor minigraph.xml ..." - fi - rm -f /tmp/pending_config_migration - sed -i "/enabled=/d" /etc/sonic/updategraph.conf - echo "enabled=false" >> /etc/sonic/updategraph.conf - exit 0 -fi - -if [ -f /tmp/pending_config_initialization ]; then - rm -f /tmp/pending_config_initialization - if [ "$enabled" != "true" ]; then - PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` - PRESET=(`head -n 1 /usr/share/sonic/device/$PLATFORM/default_sku`) - sonic-cfggen -H -k ${PRESET[0]} --preset ${PRESET[1]} > /etc/sonic/config_db.json - redis-cli -n $CONFIG_DB_INDEX FLUSHDB - sonic-cfggen -j /etc/sonic/config_db.json --write-to-db - redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" - exit 0 - fi -fi - if [ "$enabled" = "reload_only" ]; then reload_minigraph sed -i "/enabled=/d" /etc/sonic/updategraph.conf @@ -111,6 +43,12 @@ if [ "$enabled" != "true" ]; then exit 0 fi +# If ZTP package is available and enabled, use ZTP to download and load the graph. +if [ -e /usr/bin/ztp ] && [ "$(ztp status -c)" != "0:DISABLED" ]; then + echo "ZTP is available and enabled. Skipping graph update." + exit 0 +fi + ACL_URL=$acl_src if [ "$src" = "dhcp" ]; then @@ -137,9 +75,9 @@ if [ "$src" = "dhcp" ]; then else cp -f /tmp/device_meta.json /etc/sonic/config_db.json fi - redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-db-cli CONFIG_DB FLUSHDB sonic-cfggen -j /etc/sonic/config_db.json --write-to-db - redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" if [ "$dhcp_as_static" = "true" ]; then sed -i "/enabled=/d" /etc/sonic/updategraph.conf echo "enabled=false" >> /etc/sonic/updategraph.conf diff --git a/files/image_config/warmboot-finalizer/finalize-warmboot.sh b/files/image_config/warmboot-finalizer/finalize-warmboot.sh index 32c9c8444cc3..0f9e0f7da299 100755 --- a/files/image_config/warmboot-finalizer/finalize-warmboot.sh +++ b/files/image_config/warmboot-finalizer/finalize-warmboot.sh @@ -3,7 +3,7 @@ VERBOSE=no # Check components -COMP_LIST="orchagent neighsyncd bgp" +COMP_LIST="orchagent neighsyncd bgp natsyncd" EXP_STATE="reconciled" ASSISTANT_SCRIPT="/usr/bin/neighbor_advertiser" @@ -20,7 +20,7 @@ function debug() function check_warm_boot() { - WARM_BOOT=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` + WARM_BOOT=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` } @@ -29,12 +29,10 @@ function wait_for_database_service() debug "Wait for database to become ready..." # Wait for redis server start before database clean - until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; - do sleep 1; - done + /usr/bin/docker exec database ping_pong_db_insts # Wait for configDB initialization - until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done @@ -44,7 +42,7 @@ function wait_for_database_service() function get_component_state() { - /usr/bin/redis-cli -n 6 hget "WARM_RESTART_TABLE|$1" state + sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|$1" state } diff --git a/files/initramfs-tools/arista-convertfs.j2 b/files/initramfs-tools/arista-convertfs.j2 index 535bb441f117..56616d2ba04a 100644 --- a/files/initramfs-tools/arista-convertfs.j2 +++ b/files/initramfs-tools/arista-convertfs.j2 @@ -18,6 +18,8 @@ flash_dev='' block_flash='' aboot_flag='' backup_file='' +prev_os='' +sonic_fast_reboot='' # Wait until get the fullpath of flash device, e.g., /dev/sda wait_get_flash_dev() { @@ -133,9 +135,11 @@ for x in "$@"; do docker_inram=*) docker_inram="${x#docker_inram=}" ;; + prev_os=*) + prev_os="${x#prev_os=}" + ;; SONIC_BOOT_TYPE=warm*|SONIC_BOOT_TYPE=fast*) - # Skip this script for warm-reboot and fast-reboot - exit 0 + sonic_fast_reboot=true ;; esac done @@ -143,6 +147,9 @@ done # Check aboot [ -z "$aboot_flag" ] && exit 0 +# Skip this script for warm-reboot/fast-reboot from sonic +[ "$sonic_fast_reboot" == true ] && [ "$prev_os" != eos ] && exit 0 + # Get flash dev name if [ -z "$block_flash" ]; then echo "Error: flash device info is not provided" diff --git a/files/initramfs-tools/union-mount.j2 b/files/initramfs-tools/union-mount.j2 index f6f1deff4220..39a514b0669e 100644 --- a/files/initramfs-tools/union-mount.j2 +++ b/files/initramfs-tools/union-mount.j2 @@ -21,6 +21,7 @@ set_tmpfs_log_partition_size() [ X"$aboot_platform" = X"x86_64-arista_7050_qx32" ] && return [ X"$aboot_platform" = X"x86_64-arista_7050_qx32s" ] && return [ X"$aboot_platform" = X"x86_64-arista_7060_cx32s" ] && return + [ X"$aboot_platform" = X"x86_64-arista_7060cx2_32s" ] && return # set varlogsize to existing var-log.ext4 size if [ -f ${rootmnt}/host/disk-img/var-log.ext4 ]; then diff --git a/files/scripts/arp_update b/files/scripts/arp_update index 055aa98baf5d..3cc9cd267985 100755 --- a/files/scripts/arp_update +++ b/files/scripts/arp_update @@ -46,5 +46,28 @@ while /bin/true; do ip6cmd="ip -6 neigh show | grep -v fe80 | grep $vlan | cut -d ' ' -f 1,3 | $ndisc6cmd" eval `eval $ip6cmd` done + + # sleep here before handling the mismatch as it is not required during startup sleep 300 + + # refresh neighbor entries from APP_DB in case of mismatch with kernel + DBNEIGH=$(sonic-db-cli APPL_DB keys NEIGH_TABLE*) + KERNEIGH4=$(ip -4 neigh show | grep Vlan | cut -d ' ' -f 1,3 --output-delimiter=',') + KERNEIGH6=$(ip -6 neigh show | grep -v fe80 | grep Vlan | cut -d ' ' -f 1,3 --output-delimiter=',') + for neigh in $DBNEIGH; do + intf="$( cut -d ':' -f 2 <<< "$neigh" )" + ip="$( cut -d ':' -f 3- <<< "$neigh" )" + if [[ $intf == *"Vlan"* ]]; then + if [[ $ip == *"."* ]] && [[ ! $KERNEIGH4 =~ "${ip},${intf}" ]]; then + pingcmd="timeout 0.2 ping -I $intf -n -q -i 0 -c 1 -W 1 $ip >/dev/null" + eval $pingcmd + logger "arp_update: mismatch arp entry, pinging ${ip} on ${intf}" + elif [[ $ip == *":"* ]] && [[ ! $KERNEIGH6 =~ "${ip},${intf}" ]]; then + ping6cmd="timeout 0.2 ping6 -I $intf -n -q -i 0 -c 1 -W 1 $ip >/dev/null" + eval $ping6cmd + logger "arp_update: mismatch v6 nbr entry, pinging ${ip} on ${intf}" + fi + fi + done + done diff --git a/files/scripts/configdb-load.sh b/files/scripts/configdb-load.sh index 5ba2e0e0bc7f..b1bf761371bf 100755 --- a/files/scripts/configdb-load.sh +++ b/files/scripts/configdb-load.sh @@ -5,9 +5,13 @@ until [[ $(redis-cli ping | grep -c PONG) -gt 0 ]]; do sleep 1; done -# If there is a config db dump file, load it +# If there is a config_db.json dump file, load it. if [ -r /etc/sonic/config_db.json ]; then - sonic-cfggen -j /etc/sonic/config_db.json --write-to-db + if [ -r /etc/sonic/init_cfg.json ]; then + sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db.json --write-to-db + else + sonic-cfggen -j /etc/sonic/config_db.json --write-to-db + fi fi -redis-cli -n 4 SET "CONFIG_DB_INITIALIZED" "1" +sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" diff --git a/files/scripts/sonic-netns-exec b/files/scripts/sonic-netns-exec new file mode 100755 index 000000000000..a0dfc6f9ab07 --- /dev/null +++ b/files/scripts/sonic-netns-exec @@ -0,0 +1,12 @@ +#!/bin/bash +# Wrapper to execute any command in a specific +# network namespace. +# Usage: +# sonic-netns-exec +NS="$1" +shift +if [ ! -z "$NS" ]; then + ip netns exec $NS "$@" +else + "$@" +fi diff --git a/files/scripts/supervisor-proc-exit-listener b/files/scripts/supervisor-proc-exit-listener index 8d1735cd2b0c..cf154b3a5c10 100755 --- a/files/scripts/supervisor-proc-exit-listener +++ b/files/scripts/supervisor-proc-exit-listener @@ -1,17 +1,34 @@ #!/usr/bin/env python +import getopt import os import signal import sys import syslog +import swsssdk + from supervisor import childutils # Contents of file should be the names of critical processes (as defined in # supervisor.conf file), one per line CRITICAL_PROCESSES_FILE = '/etc/supervisor/critical_processes' -def main(): +# This table in databse contains the features for container and each +# feature for a row will be configured a state or number. +CONTAINER_FEATURE_TABLE_NAME = 'CONTAINER_FEATURE' + +def main(argv): + container_name = None + opts, args = getopt.getopt(argv, "c:", ["container-name="]) + for opt, arg in opts: + if opt in ("-c", "--container-name"): + container_name = arg + + if not container_name: + syslog.syslog(syslog.LOG_ERR, "Container name not specified. Exiting...") + sys.exit(1) + # Read the list of critical processes from a file with open(CRITICAL_PROCESSES_FILE, 'r') as f: critical_processes = [line.rstrip('\n') for line in f] @@ -35,12 +52,33 @@ def main(): processname = payload_headers['processname'] groupname = payload_headers['groupname'] - # If a critical process exited unexpectedly, terminate supervisor - if expected == 0 and processname in critical_processes or groupname in critical_processes: + # Read the status of auto-restart feature from Config_DB. + if container_name != 'database': + config_db = swsssdk.ConfigDBConnector() + config_db.connect() + container_features_table = config_db.get_table(CONTAINER_FEATURE_TABLE_NAME) + if not container_features_table: + syslog.syslog(syslog.LOG_ERR, "Unable to retrieve container features table from Config DB. Exiting...") + sys.exit(2) + + if not container_features_table.has_key(container_name): + syslog.syslog(syslog.LOG_ERR, "Unable to retrieve features for container '{}'. Exiting...".format(container_name)) + sys.exit(3) + + restart_feature = container_features_table[container_name].get('auto_restart') + if not restart_feature: + syslog.syslog(syslog.LOG_ERR, "Unable to determine auto-restart feature status for container '{}'. Exiting...".format(container_name)) + sys.exit(4) + + # If container is database or auto-restart feature is enabled and at the same time + # a critical process exited unexpectedly, terminate supervisor + if ((container_name == 'database' or restart_feature == 'enabled') and expected == 0 and + (processname in critical_processes or groupname in critical_processes)): MSG_FORMAT_STR = "Process {} exited unxepectedly. Terminating supervisor..." msg = MSG_FORMAT_STR.format(payload_headers['processname']) syslog.syslog(syslog.LOG_INFO, msg) os.kill(os.getppid(), signal.SIGTERM) + if __name__ == "__main__": - main() + main(sys.argv[1:]) diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index 93f311019d66..360e331f3636 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -1,10 +1,7 @@ #!/bin/bash -SERVICE="swss" -PEER="syncd" -DEPENDENT="teamd radv dhcp_relay" -DEBUGLOG="/tmp/swss-syncd-debug.log" -LOCKFILE="/tmp/swss-syncd-lock" +DEPENDENT="radv dhcp_relay" +MULTI_INST_DEPENDENT="teamd" function debug() { @@ -14,25 +11,25 @@ function debug() function lock_service_state_change() { - debug "Locking ${LOCKFILE} from ${SERVICE} service" + debug "Locking ${LOCKFILE} from ${SERVICE}$DEV service" exec {LOCKFD}>${LOCKFILE} /usr/bin/flock -x ${LOCKFD} trap "/usr/bin/flock -u ${LOCKFD}" 0 2 3 15 - debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE} service" + debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" } function unlock_service_state_change() { - debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE} service" + debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" /usr/bin/flock -u ${LOCKFD} } function check_warm_boot() { - SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" else @@ -43,7 +40,7 @@ function check_warm_boot() function validate_restore_count() { if [[ x"$WARM_BOOT" == x"true" ]]; then - RESTORE_COUNT=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_TABLE|orchagent" restore_count` + RESTORE_COUNT=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` # We have to make sure db data has not been flushed. if [[ -z "$RESTORE_COUNT" ]]; then WARM_BOOT="false" @@ -54,12 +51,10 @@ function validate_restore_count() function wait_for_database_service() { # Wait for redis server start before database clean - until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; - do sleep 1; - done + /usr/bin/docker exec database$DEV ping_pong_db_insts # Wait for configDB initialization - until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -69,7 +64,7 @@ function wait_for_database_service() # $2 the string of a list of table prefixes function clean_up_tables() { - redis-cli -n $1 EVAL " + sonic-netns-exec "$NET_NS" sonic-db-cli $1 EVAL " local tables = {$2} for i = 1, table.getn(tables) do local matches = redis.call('KEYS', tables[i]) @@ -83,25 +78,48 @@ start_peer_and_dependent_services() { check_warm_boot if [[ x"$WARM_BOOT" != x"true" ]]; then - /bin/systemctl start ${PEER} + if [[ ! -z $DEV ]]; then + /bin/systemctl start ${PEER}@$DEV + else + /bin/systemctl start ${PEER} + fi for dep in ${DEPENDENT}; do /bin/systemctl start ${dep} done + for dep in ${MULTI_INST_DEPENDENT}; do + if [[ ! -z $DEV ]]; then + /bin/systemctl start ${dep}@$DEV + else + /bin/systemctl start ${dep} + fi + done fi } stop_peer_and_dependent_services() { # if warm start enabled or peer lock exists, don't stop peer service docker if [[ x"$WARM_BOOT" != x"true" ]]; then - /bin/systemctl stop ${PEER} + if [[ ! -z $DEV ]]; then + /bin/systemctl stop ${PEER}@$DEV + else + /bin/systemctl stop ${PEER} + fi for dep in ${DEPENDENT}; do /bin/systemctl stop ${dep} done + for dep in ${MULTI_INST_DEPENDENT}; do + if [[ ! -z $DEV ]]; then + /bin/systemctl stop ${dep}@$DEV + else + /bin/systemctl stop ${dep} + fi + done + fi } start() { - debug "Starting ${SERVICE} service..." + debug "Starting ${SERVICE}$DEV service..." lock_service_state_change @@ -109,21 +127,21 @@ start() { check_warm_boot validate_restore_count - debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." # Don't flush DB during warm boot if [[ x"$WARM_BOOT" != x"true" ]]; then debug "Flushing APP, ASIC, COUNTER, CONFIG, and partial STATE databases ..." - /usr/bin/docker exec database redis-cli -n 0 FLUSHDB - /usr/bin/docker exec database redis-cli -n 1 FLUSHDB - /usr/bin/docker exec database redis-cli -n 2 FLUSHDB - /usr/bin/docker exec database redis-cli -n 5 FLUSHDB - clean_up_tables 6 "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" + sonic-netns-exec "$NET_NS" sonic-db-cli APPL_DB FLUSHDB + sonic-netns-exec "$NET_NS" sonic-db-cli ASIC_DB FLUSHDB + sonic-netns-exec "$NET_NS" sonic-db-cli COUNTERS_DB FLUSHDB + sonic-netns-exec "$NET_NS" sonic-db-cli FLEX_COUNTER_DB FLUSHDB + clean_up_tables STATE_DB "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" fi # start service docker - /usr/bin/${SERVICE}.sh start - debug "Started ${SERVICE} service..." + /usr/bin/${SERVICE}.sh start $DEV + debug "Started ${SERVICE}$DEV service..." # Unlock has to happen before reaching out to peer service unlock_service_state_change @@ -136,7 +154,11 @@ wait() { # NOTE: This assumes Docker containers share the same names as their # corresponding services for SECS in {1..60}; do - RUNNING=$(docker inspect -f '{{.State.Running}}' ${PEER}) + if [[ ! -z $DEV ]]; then + RUNNING=$(docker inspect -f '{{.State.Running}}' ${PEER}$DEV) + else + RUNNING=$(docker inspect -f '{{.State.Running}}' ${PEER}) + fi if [[ x"$RUNNING" == x"true" ]]; then break else @@ -146,27 +168,31 @@ wait() { # NOTE: This assumes Docker containers share the same names as their # corresponding services - /usr/bin/docker-wait-any ${SERVICE} ${PEER} + if [[ ! -z $DEV ]]; then + /usr/bin/docker-wait-any ${SERVICE}$DEV ${PEER}$DEV + else + /usr/bin/docker-wait-any ${SERVICE} ${PEER} + fi } stop() { - debug "Stopping ${SERVICE} service..." + debug "Stopping ${SERVICE}$DEV service..." [[ -f ${LOCKFILE} ]] || /usr/bin/touch ${LOCKFILE} lock_service_state_change check_warm_boot - debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." - /usr/bin/${SERVICE}.sh stop - debug "Stopped ${SERVICE} service..." + /usr/bin/${SERVICE}.sh stop $DEV + debug "Stopped ${SERVICE}$DEV service..." # Flush FAST_REBOOT table when swss needs to stop. The only # time when this would take effect is when fast-reboot # encountered error, e.g. syncd crashed. And swss needs to # be restarted. debug "Clearing FAST_REBOOT flag..." - clean_up_tables 6 "'FAST_REBOOT*'" + clean_up_tables STATE_DB "'FAST_REBOOT*'" # Unlock has to happen before reaching out to peer service unlock_service_state_change @@ -174,6 +200,18 @@ stop() { stop_peer_and_dependent_services } +DEV=$2 + +SERVICE="swss" +PEER="syncd" +DEBUGLOG="/tmp/swss-syncd-debug$DEV.log" +LOCKFILE="/tmp/swss-syncd-lock$DEV" +if [ "$DEV" ]; then + NET_NS="asic$DEV" #name of the network namespace +else + NET_NS="" +fi + case "$1" in start|wait|stop) $1 diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 05e5552a64b1..9847cfec9406 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -1,9 +1,5 @@ #!/bin/bash -SERVICE="syncd" -PEER="swss" -DEBUGLOG="/tmp/swss-syncd-debug.log" -LOCKFILE="/tmp/swss-syncd-lock" function debug() { @@ -13,25 +9,25 @@ function debug() function lock_service_state_change() { - debug "Locking ${LOCKFILE} from ${SERVICE} service" + debug "Locking ${LOCKFILE} from ${SERVICE}$DEV service" exec {LOCKFD}>${LOCKFILE} /usr/bin/flock -x ${LOCKFD} trap "/usr/bin/flock -u ${LOCKFD}" 0 2 3 15 - debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE} service" + debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" } function unlock_service_state_change() { - debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE} service" + debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" /usr/bin/flock -u ${LOCKFD} } function check_warm_boot() { - SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" @@ -43,12 +39,10 @@ function check_warm_boot() function wait_for_database_service() { # Wait for redis server start before database clean - until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; - do sleep 1; - done + /usr/bin/docker exec database$DEV ping_pong_db_insts # Wait for configDB initialization - until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -65,7 +59,7 @@ function getBootType() ;; *SONIC_BOOT_TYPE=fast*|*fast-reboot*) # check that the key exists - if [[ $(redis-cli -n 6 GET "FAST_REBOOT|system") == "1" ]]; then + if [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then TYPE='fast' else TYPE='cold' @@ -78,7 +72,7 @@ function getBootType() } start() { - debug "Starting ${SERVICE} service..." + debug "Starting ${SERVICE}$DEV service..." lock_service_state_change @@ -87,7 +81,7 @@ start() { wait_for_database_service check_warm_boot - debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." if [[ x"$WARM_BOOT" == x"true" ]]; then # Leave a mark for syncd scripts running inside docker. @@ -129,7 +123,7 @@ start() { fi # start service docker - /usr/bin/${SERVICE}.sh start + /usr/bin/${SERVICE}.sh start $DEV debug "Started ${SERVICE} service..." unlock_service_state_change @@ -141,15 +135,15 @@ wait() { /bin/systemctl start pmon debug "Started pmon service" fi - /usr/bin/${SERVICE}.sh wait + /usr/bin/${SERVICE}.sh wait $DEV } stop() { - debug "Stopping ${SERVICE} service..." + debug "Stopping ${SERVICE}$DEV service..." lock_service_state_change check_warm_boot - debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." if [[ x"$WARM_BOOT" == x"true" ]]; then TYPE=warm @@ -165,19 +159,19 @@ stop() { if [[ x$sonic_asic_platform != x"mellanox" ]] || [[ x$TYPE != x"cold" ]]; then debug "${TYPE} shutdown syncd process ..." - /usr/bin/docker exec -i syncd /usr/bin/syncd_request_shutdown --${TYPE} + /usr/bin/docker exec -i syncd$DEV /usr/bin/syncd_request_shutdown --${TYPE} # wait until syncd quits gracefully - while docker top syncd | grep -q /usr/bin/syncd; do + while docker top syncd$DEV | grep -q /usr/bin/syncd; do sleep 0.1 done - /usr/bin/docker exec -i syncd /bin/sync + /usr/bin/docker exec -i syncd$DEV /bin/sync debug "Finished ${TYPE} shutdown syncd process ..." fi - /usr/bin/${SERVICE}.sh stop - debug "Stopped ${SERVICE} service..." + /usr/bin/${SERVICE}.sh stop $DEV + debug "Stopped ${SERVICE}$DEV service..." # platform specific tasks @@ -194,6 +188,19 @@ stop() { unlock_service_state_change } +OP=$1 +DEV=$2 + +SERVICE="syncd" +PEER="swss" +DEBUGLOG="/tmp/swss-syncd-debug$DEV.log" +LOCKFILE="/tmp/swss-syncd-lock$DEV" +if [ "$DEV" ]; then + NET_NS="asic$DEV" #name of the network namespace +else + NET_NS="" +fi + case "$1" in start|wait|stop) $1 diff --git a/installer/x86_64/install.sh b/installer/x86_64/install.sh index 2cd579e28b29..6a347c78db73 100755 --- a/installer/x86_64/install.sh +++ b/installer/x86_64/install.sh @@ -555,15 +555,21 @@ EOF # Add the logic to support grub-reboot and grub-set-default cat <> $grub_cfg if [ -s \$prefix/grubenv ]; then - load_env + load_env fi -if [ "\${saved_entry}" ] ; then - set default="\${saved_entry}" +if [ "\${saved_entry}" ]; then + set default="\${saved_entry}" fi -if [ "\${next_entry}" ] ; then - set default="\${next_entry}" - set next_entry= - save_env next_entry +if [ "\${next_entry}" ]; then + set default="\${next_entry}" + unset next_entry + save_env next_entry +fi +if [ "\${onie_entry}" ]; then + set next_entry="\${default}" + set default="\${onie_entry}" + unset onie_entry + save_env onie_entry next_entry fi EOF @@ -577,19 +583,22 @@ EOF $onie_root_dir/tools/bin/onie-boot-mode -q -o install fi -# Add a menu entry for the DEMO OS +# Add a menu entry for the SONiC OS # Note: assume that apparmor is supported in the kernel demo_grub_entry="$demo_volume_revision_label" if [ "$install_env" = "sonic" ]; then old_sonic_menuentry=$(cat /host/grub/grub.cfg | sed "/$running_sonic_revision/,/}/!d") - demo_dev=$(echo $old_sonic_menuentry | sed -e "s/.*root\=\(.*\)rw.*/\1/") + grub_cfg_root=$(echo $old_sonic_menuentry | sed -e "s/.*root\=\(.*\)rw.*/\1/") onie_menuentry=$(cat /host/grub/grub.cfg | sed "/menuentry ONIE/,/}/!d") -fi - -if [ "$install_env" = "build" ]; then +elif [ "$install_env" = "build" ]; then grub_cfg_root=%%SONIC_ROOT%% -else - grub_cfg_root=$demo_dev +else # install_env = "onie" + uuid=$(blkid "$demo_dev" | sed -ne 's/.* UUID=\"\([^"]*\)\".*/\1/p') + if [ -z "$uuid" ]; then + grub_cfg_root=$demo_dev + else + grub_cfg_root=UUID=$uuid + fi fi cat <> $grub_cfg @@ -600,12 +609,12 @@ menuentry '$demo_grub_entry' { if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi insmod part_msdos insmod ext2 - linux /$image_dir/boot/vmlinuz-4.9.0-9-2-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \ + linux /$image_dir/boot/vmlinuz-4.9.0-11-2-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \ net.ifnames=0 biosdevname=0 \ loop=$image_dir/$FILESYSTEM_SQUASHFS loopfstype=squashfs \ apparmor=1 security=apparmor varlog_size=$VAR_LOG_SIZE usbcore.autosuspend=-1 $ONIE_PLATFORM_EXTRA_CMDLINE_LINUX echo 'Loading $demo_volume_label $demo_type initial ramdisk ...' - initrd /$image_dir/boot/initrd.img-4.9.0-9-2-amd64 + initrd /$image_dir/boot/initrd.img-4.9.0-11-2-amd64 } EOF diff --git a/platform/barefoot/bfn-modules/debian/control b/platform/barefoot/bfn-modules/debian/control index c9a53ec1d08b..d6f7a991107d 100644 --- a/platform/barefoot/bfn-modules/debian/control +++ b/platform/barefoot/bfn-modules/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: bfn-modules Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for bfn asic for mmap diff --git a/platform/barefoot/bfn-modules/modules/bf_ioctl.h b/platform/barefoot/bfn-modules/modules/bf_ioctl.h index e14716f50fa3..0644feb7c8c1 100644 --- a/platform/barefoot/bfn-modules/modules/bf_ioctl.h +++ b/platform/barefoot/bfn-modules/modules/bf_ioctl.h @@ -1,25 +1,28 @@ /******************************************************************************* - * BAREFOOT NETWORKS CONFIDENTIAL & PROPRIETARY - * - * Copyright (c) 2018-2018 Barefoot Networks, Inc. - * - * NOTICE: All information contained herein is, and remains the property of - * Barefoot Networks, Inc. and its suppliers, if any. The intellectual and - * technical concepts contained herein are proprietary to Barefoot Networks, - * Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, patents in - * process, and are protected by trade secret or copyright law. - * Dissemination of this information or reproduction of this material is - * strictly forbidden unless prior written permission is obtained from - * Barefoot Networks, Inc. - * - * No warranty, explicit or implicit is provided, unless granted under a - * written agreement with Barefoot Networks, Inc. - * - * $Id: $ - * - ******************************************************************************/ + Barefoot Networks Switch ASIC Linux driver + Copyright(c) 2015 - 2019 Barefoot Networks, Inc. + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + info@barefootnetworks.com + Barefoot Networks, 4750 Patrick Henry Drive, Santa Clara CA 95054 + +*******************************************************************************/ #ifndef _BF_IOCTL_H_ #define _BF_IOCTL_H_ @@ -35,15 +38,35 @@ typedef uint64_t phys_addr_t; #endif /* __KERNEL__ */ #define BF_IOC_MAGIC 'b' +#define BF_TBUS_MSIX_INDICES_MAX 3 -typedef struct bf_dma_bus_map_s +typedef struct bf_dma_bus_map_s { phys_addr_t phy_addr; void *dma_addr; size_t size; } bf_dma_bus_map_t; +typedef struct bf_tbus_msix_indices_s +{ + int cnt; + int indices[BF_TBUS_MSIX_INDICES_MAX]; +} bf_tbus_msix_indices_t; + +enum bf_intr_mode { + BF_INTR_MODE_NONE = 0, + BF_INTR_MODE_LEGACY, + BF_INTR_MODE_MSI, + BF_INTR_MODE_MSIX, +}; + +typedef struct bf_intr_mode_s { + enum bf_intr_mode intr_mode; +} bf_intr_mode_t; + #define BF_IOCMAPDMAADDR _IOWR(BF_IOC_MAGIC, 0, bf_dma_bus_map_t) -#define BF_IOCUNMAPDMAADDR _IOW(BF_IOC_MAGIC, 0, bf_dma_bus_map_t) +#define BF_IOCUNMAPDMAADDR _IOW(BF_IOC_MAGIC, 1, bf_dma_bus_map_t) +#define BF_TBUS_MSIX_INDEX _IOW(BF_IOC_MAGIC, 2, bf_tbus_msix_indices_t) +#define BF_GET_INTR_MODE _IOR(BF_IOC_MAGIC, 3, bf_intr_mode_t) #endif /* _BF_IOCTL_H_ */ diff --git a/platform/barefoot/bfn-modules/modules/bf_kdrv.c b/platform/barefoot/bfn-modules/modules/bf_kdrv.c index a9e8e65f968b..d4c786c56b75 100644 --- a/platform/barefoot/bfn-modules/modules/bf_kdrv.c +++ b/platform/barefoot/bfn-modules/modules/bf_kdrv.c @@ -1,49 +1,31 @@ /******************************************************************************* - * BAREFOOT NETWORKS CONFIDENTIAL & PROPRIETARY - * - * Copyright (c) 2015-2016 Barefoot Networks, Inc. + Barefoot Networks Switch ASIC Linux driver + Copyright(c) 2015 - 2019 Barefoot Networks, Inc. - * All Rights Reserved. - * - * NOTICE: All information contained herein is, and remains the property of - * Barefoot Networks, Inc. and its suppliers, if any. The intellectual and - * technical concepts contained herein are proprietary to Barefoot Networks, - * Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, patents in - * process, and are protected by trade secret or copyright law. - * Dissemination of this information or reproduction of this material is - * strictly forbidden unless prior written permission is obtained from - * Barefoot Networks, Inc. - * - * No warranty, explicit or implicit is provided, unless granted under a - * written agreement with Barefoot Networks, Inc. - * - * $Id: $ - * - ******************************************************************************/ -/** - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2015 Barefoot Networks. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the... - * - **/ + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + info@barefootnetworks.com + Barefoot Networks, 4750 Patrick Henry Drive, Santa Clara CA 95054 + +*******************************************************************************/ /* bf_drv kernel module * - * This is kernel mode driver for Tofino chip. + * This is kernel mode driver for Tofino chip. * Provides user space mmap service and user space "wait for interrupt" * and "enable interrupt" services. */ @@ -52,21 +34,18 @@ #include #include #include -#include #include -#include -#include #include #include #include #include "bf_ioctl.h" +#include "bf_kdrv.h" #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) #include #else - #include + #include #endif - #include #include #include @@ -75,104 +54,26 @@ //#error unsupported linux kernel version #endif -/* TBD: Need to build with CONFIG_PCI_MSI */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) -extern int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec); -extern int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec); -#else -extern int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec); -extern int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int minvec, int maxvec); -#endif - -#define PCI_VENDOR_ID_BF 0x1d1c -#define TOFINO_DEV_ID_A0 0x01 -#define TOFINO_DEV_ID_B0 0x10 -#define TOFINO2_DEV_ID_A0 0x0100 - -#ifndef PCI_MSIX_ENTRY_SIZE -#define PCI_MSIX_ENTRY_SIZE 16 -#define PCI_MSIX_ENTRY_LOWER_ADDR 0 -#define PCI_MSIX_ENTRY_UPPER_ADDR 4 -#define PCI_MSIX_ENTRY_DATA 8 -#define PCI_MSIX_ENTRY_VECTOR_CTRL 12 -#define PCI_MSIX_ENTRY_CTRL_MASKBIT 1 +#ifdef BF_INCLUDE_KPKT +/* kernel pkt driver entry/exit APIs */ +extern int bf_kpkt_init(struct pci_dev *pdev, + u8 *bar0_vaddr, + void **adapter_ptr, + int dev_id, + int pci_use_highmem, + unsigned long head_room, + int kpkt_dr_int_en, + unsigned long rx_desc_countp); +extern void bf_kpkt_remove(void *adapter_ptr); +extern void bf_kpkt_irqhandler(int irq, void *adapter_ptr); +extern void bf_kpkt_set_pci_error(void *adapter_ptr, u8 pci_error); #endif -#define BF_CLASS_NAME "bf" -#define BF_MAX_DEVICE_CNT 256 -#define BF_INTR_MODE_NONE_NAME "none" -#define BF_INTR_MODE_LEGACY_NAME "legacy" -#define BF_INTR_MODE_MSI_NAME "msi" -#define BF_INTR_MODE_MSIX_NAME "msix" -#define BF_MAX_BAR_MAPS 6 -#define BF_MSIX_ENTRY_CNT 128 /* TBD make it 512 */ -#define BF_MSI_ENTRY_CNT 2 - -/* interrupt mode */ -enum bf_intr_mode { - BF_INTR_MODE_NONE = 0, - BF_INTR_MODE_LEGACY, - BF_INTR_MODE_MSI, - BF_INTR_MODE_MSIX -}; - -/* device memory */ -struct bf_dev_mem { - const char *name; - phys_addr_t addr; - resource_size_t size; - void __iomem *internal_addr; -}; - -struct bf_listener { - struct bf_pci_dev *bfdev; - s32 event_count[BF_MSIX_ENTRY_CNT]; - int minor; - struct bf_listener *next; -}; - -/* device information */ -struct bf_dev_info { - struct module *owner; - struct device *dev; - int minor; - atomic_t event[BF_MSIX_ENTRY_CNT]; - wait_queue_head_t wait; - const char *version; - struct bf_dev_mem mem[BF_MAX_BAR_MAPS]; - struct msix_entry *msix_entries; - long irq; /* first irq vector */ - int num_irq; /* number of irq vectors */ - unsigned long irq_flags;/* sharable ?? */ - int pci_error_state; /* was there a pci bus error */ -}; - -/* cookie to be passed to IRQ handler, useful especially with MSIX */ -struct bf_int_vector { - struct bf_pci_dev *bf_dev; - int int_vec_offset; -}; - - -/** - * A structure describing the private information for a BF pcie device. - */ -struct bf_pci_dev { - struct bf_dev_info info; - struct pci_dev *pdev; - enum bf_intr_mode mode; - u8 instance; - char name[16]; - struct bf_int_vector bf_int_vec[BF_MSIX_ENTRY_CNT]; - struct bf_listener *listener_head; /* head of a singly linked list of - listeners */ -}; - /* Keep any global information here that must survive even after the * bf_pci_dev is free-ed up. */ struct bf_global { - struct bf_pci_dev *bfdev ; + struct bf_pci_dev *bfdev; struct cdev *bf_cdev; struct fasync_struct *async_queue; }; @@ -181,14 +82,19 @@ static int bf_major; static int bf_minor[BF_MAX_DEVICE_CNT] = {0}; static struct class *bf_class = NULL; static char *intr_mode = NULL; +static int kpkt_mode = 0; +static int kpkt_hd_room = 32; +static int kpkt_rx_count = 256; +static int kpkt_dr_int_en = 1; + static enum bf_intr_mode bf_intr_mode_default = BF_INTR_MODE_MSI; static spinlock_t bf_nonisr_lock; + /* dev->minor should index into this array */ static struct bf_global bf_global[BF_MAX_DEVICE_CNT]; static void bf_add_listener(struct bf_pci_dev *bfdev, - struct bf_listener *listener) -{ + struct bf_listener *listener) { struct bf_listener **cur_listener = &bfdev->listener_head; if (!listener) { @@ -197,7 +103,7 @@ static void bf_add_listener(struct bf_pci_dev *bfdev, spin_lock(&bf_nonisr_lock); while (*cur_listener) { - cur_listener = &((*cur_listener)->next); + cur_listener = &((*cur_listener)->next); } *cur_listener = listener; listener->next = NULL; @@ -206,12 +112,12 @@ static void bf_add_listener(struct bf_pci_dev *bfdev, } static void bf_remove_listener(struct bf_pci_dev *bfdev, - struct bf_listener *listener) -{ + struct bf_listener *listener) { struct bf_listener **cur_listener = &bfdev->listener_head; - /* in case of certain error conditions, this function might be called after bf_pci_remove() - */ + /* in case of certain error conditions, this function might be called after + * bf_pci_remove() + */ if (!bfdev || !listener) { return; } @@ -235,12 +141,11 @@ static void bf_remove_listener(struct bf_pci_dev *bfdev, /* a pool of minor numbers is maintained */ /* return the first available minor number */ -static int bf_get_next_minor_no(int *minor) -{ +static int bf_get_next_minor_no(int *minor) { int i; spin_lock(&bf_nonisr_lock); - for(i = 0; i < BF_MAX_DEVICE_CNT; i++) { + for (i = 0; i < BF_MAX_DEVICE_CNT; i++) { if (bf_minor[i] == 0) { *minor = i; bf_minor[i] = 1; /* mark it as taken */ @@ -254,13 +159,12 @@ static int bf_get_next_minor_no(int *minor) } /* return a minor number back to the pool for recycling */ -static int bf_return_minor_no(int minor) -{ +static int bf_return_minor_no(int minor) { int err; spin_lock(&bf_nonisr_lock); if (bf_minor[minor] == 0) { /* was already returned */ - err = -1; /* don't change anything, but return error */ + err = -1; /* don't change anything, but return error */ } else { bf_minor[minor] = 0; /* mark it as available */ err = 0; @@ -269,31 +173,29 @@ static int bf_return_minor_no(int minor) return err; } -static inline struct bf_pci_dev *bf_get_pci_dev(struct bf_dev_info *info) -{ - return container_of(info, struct bf_pci_dev, info); +static inline struct bf_pci_dev *bf_get_pci_dev(struct bf_dev_info *info) { + return container_of(info, struct bf_pci_dev, info); } /* * It masks the msix on/off of generating MSI-X messages. */ -static void -bf_msix_mask_irq(struct msi_desc *desc, int32_t state) -{ - u32 mask_bits = desc->masked; - unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + - PCI_MSIX_ENTRY_VECTOR_CTRL; - - if (state != 0) - mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; - else - mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; - - if (mask_bits != desc->masked) { - writel(mask_bits, desc->mask_base + offset); - readl(desc->mask_base); - desc->masked = mask_bits; - } +static void bf_msix_mask_irq(struct msi_desc *desc, int32_t state) { + u32 mask_bits = desc->masked; + unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_VECTOR_CTRL; + + if (state != 0) { + mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; + } else { + mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; + } + + if (mask_bits != desc->masked) { + writel(mask_bits, desc->mask_base + offset); + readl(desc->mask_base); + desc->masked = mask_bits; + } } /** @@ -308,179 +210,217 @@ bf_msix_mask_irq(struct msi_desc *desc, int32_t state) * - On success, 0. * - On failure, a negative value. */ -static int -bf_pci_irqcontrol(struct bf_pci_dev *bfdev, s32 irq_state) -{ - struct pci_dev *pdev = bfdev->pdev; - - pci_cfg_access_lock(pdev); - if (bfdev->mode == BF_INTR_MODE_LEGACY) - pci_intx(pdev, !!irq_state); - - else if (bfdev->mode == BF_INTR_MODE_MSIX) { - struct msi_desc *desc; -#if LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0) - list_for_each_entry(desc, &pdev->msi_list, list) - bf_msix_mask_irq(desc, irq_state); +static int bf_pci_irqcontrol(struct bf_pci_dev *bfdev, s32 irq_state) { + struct pci_dev *pdev = bfdev->pdev; + + pci_cfg_access_lock(pdev); + if (bfdev->mode == BF_INTR_MODE_LEGACY) { + pci_intx(pdev, !!irq_state); + } else if (bfdev->mode == BF_INTR_MODE_MSIX) { + struct msi_desc *desc; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) + list_for_each_entry(desc, &pdev->msi_list, list) + bf_msix_mask_irq(desc, irq_state); #else - for_each_pci_msi_entry(desc, pdev) - bf_msix_mask_irq(desc, irq_state); + for_each_pci_msi_entry(desc, pdev) bf_msix_mask_irq(desc, irq_state); #endif - } - pci_cfg_access_unlock(pdev); + } + pci_cfg_access_unlock(pdev); - return 0; + return 0; } +#ifdef BF_INCLUDE_KPKT +/* there are three TBUS MSIX vectors */ +static int bf_irq_is_tbus_msix(struct bf_pci_dev *bfdev, int irq) { + struct bf_dev_info *info = &bfdev->info; + + if (!info->tbus_msix_map_enable) { + return 0; + } + if (irq == info->msix_entries[info->tbus_msix_ind[0]].vector || + irq == info->msix_entries[info->tbus_msix_ind[1]].vector) { + return 1; + } else if (irq == info->msix_entries[info->tbus_msix_ind[2]].vector) { + /* log error */ + printk(KERN_ALERT "bf_tbus error msix\n"); + return 1; + } + return 0; +} +#endif + /** * interrupt handler which will check if the interrupt is from the right * device. If so, disable it here and will be enabled later. */ -static irqreturn_t bf_pci_irqhandler(int irq, struct bf_pci_dev *bfdev) -{ - /* Legacy mode need to mask in hardware */ - if (bfdev->mode == BF_INTR_MODE_LEGACY && - !pci_check_and_mask_intx(bfdev->pdev)) - return IRQ_NONE; - - /* NOTE : if bfdev->info.pci_error_state == 1, then do not access the - * device and return IRQ_NOTHANDLED. - */ - /* Message signal mode, no share IRQ and automasked */ - return IRQ_HANDLED; +static irqreturn_t bf_pci_irqhandler(int irq, struct bf_pci_dev *bfdev) { + /* Legacy mode need to mask in hardware */ + if (bfdev->mode == BF_INTR_MODE_LEGACY && + !pci_check_and_mask_intx(bfdev->pdev)) { + return IRQ_NONE; + } + + /* NOTE : if bfdev->info.pci_error_state == 1, then do not access the + * device and return IRQ_NOTHANDLED. + */ +#ifdef BF_INCLUDE_KPKT + /* handle pkt DR interrpt (MSI vect-1) if it has to be in kernel */ + if (kpkt_dr_int_en && bfdev->info.irq != 0) { + if (bfdev->mode == BF_INTR_MODE_LEGACY) { + bf_kpkt_irqhandler(irq, bfdev->adapter_ptr); + } else if (bfdev->mode == BF_INTR_MODE_MSI) { + /* do not process packet unless the MSI interrupt is from tbus */ + /* all BF interrupts arrive on one single MSI if "1" MSI is configured */ + if (bfdev->info.num_irq == 1 || (irq == (bfdev->info.irq + BF_MSI_INT_TBUS))) { + bf_kpkt_irqhandler(irq, bfdev->adapter_ptr); + } + } else if (bfdev->mode == BF_INTR_MODE_MSIX) { + if (bfdev->info.tof_type == BF_TOFINO_2 && bf_irq_is_tbus_msix(bfdev,irq)) { + bf_kpkt_irqhandler(irq, bfdev->adapter_ptr); + } + } + } +#endif + /* Message signal mode, no share IRQ and automasked */ + return IRQ_HANDLED; } /* Remap pci resources described by bar #pci_bar */ -static int -bf_pci_setup_iomem(struct pci_dev *dev, struct bf_dev_info *info, - int n, int pci_bar, const char *name) -{ - unsigned long addr, len; - void *internal_addr; - - if (sizeof(info->mem) / sizeof(info->mem[0]) <= n) - return -EINVAL; - - addr = pci_resource_start(dev, pci_bar); - len = pci_resource_len(dev, pci_bar); - if (addr == 0 || len == 0) - return -1; - internal_addr = pci_ioremap_bar(dev, pci_bar); - if (internal_addr == NULL) - return -1; - info->mem[n].name = name; - info->mem[n].addr = addr; - info->mem[n].internal_addr = internal_addr; - info->mem[n].size = len; - return 0; +static int bf_pci_setup_iomem(struct pci_dev *dev, + struct bf_dev_info *info, + int n, + int pci_bar, + const char *name) { + unsigned long addr, len; + void *internal_addr; + + if (sizeof(info->mem) / sizeof(info->mem[0]) <= n) { + return -EINVAL; + } + + addr = pci_resource_start(dev, pci_bar); + len = pci_resource_len(dev, pci_bar); + if (addr == 0 || len == 0) { + return -1; + } + internal_addr = pci_ioremap_bar(dev, pci_bar); + if (internal_addr == NULL) { + return -1; + } + info->mem[n].name = name; + info->mem[n].addr = addr; + info->mem[n].internal_addr = internal_addr; + info->mem[n].size = len; + return 0; } /* Unmap previously ioremap'd resources */ -static void -bf_pci_release_iomem(struct bf_dev_info *info) -{ - int i; +static void bf_pci_release_iomem(struct bf_dev_info *info) { + int i; - for (i = 0; i < BF_MAX_BAR_MAPS; i++) { - if (info->mem[i].internal_addr) - iounmap(info->mem[i].internal_addr); - } + for (i = 0; i < BF_MAX_BAR_MAPS; i++) { + if (info->mem[i].internal_addr) { + iounmap(info->mem[i].internal_addr); + } + } } -static int -bf_setup_bars(struct pci_dev *dev, struct bf_dev_info *info) -{ - int i, iom, ret; - unsigned long flags; - static const char *bar_names[BF_MAX_BAR_MAPS] = { - "BAR0", "BAR1", "BAR2", "BAR3", "BAR4", "BAR5", - }; - - iom = 0; - - for (i = 0; i < BF_MAX_BAR_MAPS; i++) { - if (pci_resource_len(dev, i) != 0 && - pci_resource_start(dev, i) != 0) { - flags = pci_resource_flags(dev, i); - if (flags & IORESOURCE_MEM) { - ret = bf_pci_setup_iomem(dev, info, iom, i, bar_names[i]); - if (ret != 0) - return ret; - iom++; - } - } - } - return (iom != 0) ? ret : -ENOENT; +static int bf_setup_bars(struct pci_dev *dev, struct bf_dev_info *info) { + int i, iom, ret; + unsigned long flags; + static const char *bar_names[BF_MAX_BAR_MAPS] = { + "BAR0", "BAR1", "BAR2", "BAR3", "BAR4", "BAR5", + }; + + iom = 0; + + for (i = 0; i < BF_MAX_BAR_MAPS; i++) { + if (pci_resource_len(dev, i) != 0 && pci_resource_start(dev, i) != 0) { + flags = pci_resource_flags(dev, i); + if (flags & IORESOURCE_MEM) { + ret = bf_pci_setup_iomem(dev, info, iom, i, bar_names[i]); + if (ret != 0) { + return ret; + } + iom++; + } + } + } + return (iom != 0) ? ret : -ENOENT; } -static irqreturn_t bf_interrupt(int irq, void *bfdev_id) -{ +static irqreturn_t bf_interrupt(int irq, void *bfdev_id) { struct bf_pci_dev *bfdev = ((struct bf_int_vector *)bfdev_id)->bf_dev; int vect_off = ((struct bf_int_vector *)bfdev_id)->int_vec_offset; irqreturn_t ret = bf_pci_irqhandler(irq, bfdev); - if (ret == IRQ_HANDLED) + if (ret == IRQ_HANDLED) { atomic_inc(&(bfdev->info.event[vect_off])); - + } return ret; } -static unsigned int bf_poll(struct file *filep, poll_table *wait) -{ +static unsigned int bf_poll(struct file *filep, poll_table *wait) { struct bf_listener *listener = (struct bf_listener *)filep->private_data; struct bf_pci_dev *bfdev = listener->bfdev; int i; - + if (!bfdev) { return -ENODEV; } - if (!bfdev->info.irq) + if (!bfdev->info.irq) { return -EIO; - + } + poll_wait(filep, &bfdev->info.wait, wait); - for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) - if (listener->event_count[i] != atomic_read(&bfdev->info.event[i])) + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { + if (listener->event_count[i] != atomic_read(&bfdev->info.event[i])) { return POLLIN | POLLRDNORM; + } + } return 0; } -static int bf_find_mem_index(struct vm_area_struct *vma) -{ +static int bf_find_mem_index(struct vm_area_struct *vma) { struct bf_pci_dev *bfdev = vma->vm_private_data; if (vma->vm_pgoff < BF_MAX_BAR_MAPS) { - if (bfdev->info.mem[vma->vm_pgoff].size == 0) + if (bfdev->info.mem[vma->vm_pgoff].size == 0) { return -1; + } return (int)vma->vm_pgoff; } return -1; } - + static const struct vm_operations_struct bf_physical_vm_ops = { #ifdef CONFIG_HAVE_IOREMAP_PROT - .access = generic_access_phys, + .access = generic_access_phys, #endif }; -static int bf_mmap_physical(struct vm_area_struct *vma) -{ +static int bf_mmap_physical(struct vm_area_struct *vma) { struct bf_pci_dev *bfdev = vma->vm_private_data; int bar = bf_find_mem_index(vma); struct bf_dev_mem *mem; - if (bar < 0) + if (bar < 0) { return -EINVAL; + } mem = bfdev->info.mem + bar; - - if (mem->addr & ~PAGE_MASK) + + if (mem->addr & ~PAGE_MASK) { return -ENODEV; - if (vma->vm_end - vma->vm_start > mem->size) + } + if (vma->vm_end - vma->vm_start > mem->size) { return -EINVAL; - + } + vma->vm_ops = &bf_physical_vm_ops; - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + /* * We cannot use the vm_iomap_memory() helper here, * because vma->vm_pgoff is the map index we looked @@ -490,40 +430,45 @@ static int bf_mmap_physical(struct vm_area_struct *vma) * So we just do the physical mmap without a page * offset. */ - return remap_pfn_range(vma, vma->vm_start, mem->addr >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, vma->vm_page_prot); + return remap_pfn_range(vma, + vma->vm_start, + mem->addr >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot); } -static int bf_mmap(struct file *filep, struct vm_area_struct *vma) -{ +static int bf_mmap(struct file *filep, struct vm_area_struct *vma) { struct bf_listener *listener = filep->private_data; struct bf_pci_dev *bfdev = listener->bfdev; int bar; unsigned long requested_pages, actual_pages; - + if (!bfdev) { return -ENODEV; } - if (vma->vm_end < vma->vm_start) + if (vma->vm_end < vma->vm_start) { return -EINVAL; - + } + vma->vm_private_data = bfdev; - + bar = bf_find_mem_index(vma); - if (bar < 0) + if (bar < 0) { return -EINVAL; - + } + requested_pages = vma_pages(vma); - actual_pages = ((bfdev->info.mem[bar].addr & ~PAGE_MASK) - + bfdev->info.mem[bar].size + PAGE_SIZE -1) >> PAGE_SHIFT; - if (requested_pages > actual_pages) + actual_pages = ((bfdev->info.mem[bar].addr & ~PAGE_MASK) + + bfdev->info.mem[bar].size + PAGE_SIZE - 1) >> + PAGE_SHIFT; + if (requested_pages > actual_pages) { return -EINVAL; - + } + return bf_mmap_physical(vma); } -static int bf_fasync(int fd, struct file *filep, int mode) -{ +static int bf_fasync(int fd, struct file *filep, int mode) { int minor; if (!filep->private_data) { @@ -539,8 +484,7 @@ static int bf_fasync(int fd, struct file *filep, int mode) return (fasync_helper(fd, filep, mode, &bf_global[minor].async_queue)); } -static int bf_open(struct inode *inode, struct file *filep) -{ +static int bf_open(struct inode *inode, struct file *filep) { struct bf_pci_dev *bfdev; struct bf_listener *listener; int i; @@ -550,19 +494,19 @@ static int bf_open(struct inode *inode, struct file *filep) if (listener) { listener->bfdev = bfdev; listener->minor = bfdev->info.minor; - listener->next = NULL; + listener->next = NULL; bf_add_listener(bfdev, listener); - for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { listener->event_count[i] = atomic_read(&bfdev->info.event[i]); + } filep->private_data = listener; return 0; } else { - return(-ENOMEM); + return (-ENOMEM); } } -static int bf_release(struct inode *inode, struct file *filep) -{ +static int bf_release(struct inode *inode, struct file *filep) { struct bf_listener *listener = filep->private_data; bf_fasync(-1, filep, 0); /* empty any process id in the notification list */ @@ -574,42 +518,47 @@ static int bf_release(struct inode *inode, struct file *filep) } /* user space support: make read() system call after poll() of select() */ -static ssize_t bf_read(struct file *filep, char __user *buf, - size_t count, loff_t *ppos) -{ +static ssize_t bf_read(struct file *filep, + char __user *buf, + size_t count, + loff_t *ppos) { struct bf_listener *listener = filep->private_data; struct bf_pci_dev *bfdev = listener->bfdev; int retval, event_count[BF_MSIX_ENTRY_CNT]; - int i, mismatch_found = 0; /* OR of per vector mismatch */ + int i, mismatch_found = 0; /* OR of per vector mismatch */ unsigned char cnt_match[BF_MSIX_ENTRY_CNT]; /* per vector mismatch */ if (!bfdev) { return -ENODEV; } /* irq must be setup for read() to work */ - if (!bfdev->info.irq) + if (!bfdev->info.irq) { return -EIO; + } /* ensure that there is enough space on user buffer for the given interrupt * mode */ if (bfdev->mode == BF_INTR_MODE_MSIX) { - if (count < sizeof(s32)*BF_MSIX_ENTRY_CNT) + if (count < sizeof(s32) * BF_MSIX_ENTRY_CNT) { return -EINVAL; - count = sizeof(s32)*BF_MSIX_ENTRY_CNT; + } + count = sizeof(s32) * BF_MSIX_ENTRY_CNT; } else if (bfdev->mode == BF_INTR_MODE_MSI) { - if (count < sizeof(s32)*BF_MSI_ENTRY_CNT) + if (count < sizeof(s32) * BF_MSI_ENTRY_CNT) { return -EINVAL; - count = sizeof(s32)*BF_MSI_ENTRY_CNT; + } + count = sizeof(s32) * BF_MSI_ENTRY_CNT; } else { - if (count < sizeof(s32)) + if (count < sizeof(s32)) { return -EINVAL; + } count = sizeof(s32); } do { set_current_state(TASK_INTERRUPTIBLE); - for (i = 0; i < (count/sizeof(s32)); i++) { + for (i = 0; i < (count / sizeof(s32)); i++) { event_count[i] = atomic_read(&(bfdev->info.event[i])); if (event_count[i] != listener->event_count[i]) { mismatch_found |= 1; @@ -621,10 +570,10 @@ static ssize_t bf_read(struct file *filep, char __user *buf, } if (mismatch_found) { __set_current_state(TASK_RUNNING); - if (copy_to_user(buf, &event_count, count)) + if (copy_to_user(buf, &event_count, count)) { retval = -EFAULT; - else { /* adjust the listener->event_count; */ - for (i = 0 ; i < (count/sizeof(s32)); i++) { + } else { /* adjust the listener->event_count; */ + for (i = 0; i < (count / sizeof(s32)); i++) { if (cnt_match[i]) { listener->event_count[i] = event_count[i]; } @@ -651,25 +600,29 @@ static ssize_t bf_read(struct file *filep, char __user *buf, return retval; } -/* user space is supposed to call this after it is done with interrupt +/* user space is supposed to call this after it is done with interrupt * processing */ -static ssize_t bf_write(struct file *filep, const char __user *buf, - size_t count, loff_t *ppos) -{ +static ssize_t bf_write(struct file *filep, + const char __user *buf, + size_t count, + loff_t *ppos) { struct bf_listener *listener = filep->private_data; struct bf_pci_dev *bfdev = listener->bfdev; ssize_t ret; s32 int_en; - if (!bfdev || !bfdev->info.irq) + if (!bfdev || !bfdev->info.irq) { return -EIO; - - if (count != sizeof(s32)) + } + + if (count != sizeof(s32)) { return -EINVAL; + } - if (copy_from_user(&int_en, buf, count)) + if (copy_from_user(&int_en, buf, count)) { return -EFAULT; + } /* clear pci_error_state */ bfdev->info.pci_error_state = 0; @@ -692,7 +645,11 @@ static long bf_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) } switch(cmd) { case BF_IOCMAPDMAADDR: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) + if (access_ok(addr, sizeof(bf_dma_bus_map_t))) { +#else if (access_ok(VERIFY_WRITE, addr, sizeof(bf_dma_bus_map_t))) { +#endif if (copy_from_user(&dma_map, addr, sizeof(bf_dma_bus_map_t))) { return EFAULT; } @@ -703,7 +660,7 @@ static long bf_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) if (dma_mapping_error(&bfdev->pdev->dev, dma_hndl)) { return EFAULT; } - dma_map.dma_addr = (void *)dma_hndl; + dma_map.dma_addr = (void *)(uintptr_t)dma_hndl; if (copy_to_user(addr, &dma_map, sizeof(bf_dma_bus_map_t))) { return EFAULT; } @@ -712,18 +669,55 @@ static long bf_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) } break; case BF_IOCUNMAPDMAADDR: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) + if (access_ok(addr, sizeof(bf_dma_bus_map_t))) { +#else if (access_ok(VERIFY_READ, addr, sizeof(bf_dma_bus_map_t))) { +#endif if (copy_from_user(&dma_map, addr, sizeof(bf_dma_bus_map_t))) { return EFAULT; } if (!dma_map.dma_addr || !dma_map.size) { return EFAULT; } - dma_unmap_single(&bfdev->pdev->dev, (dma_addr_t)dma_map.dma_addr, dma_map.size, DMA_BIDIRECTIONAL); + dma_unmap_single(&bfdev->pdev->dev, (dma_addr_t)(uintptr_t)(dma_map.dma_addr), dma_map.size, DMA_BIDIRECTIONAL); } else { return EFAULT; } break; + case BF_TBUS_MSIX_INDEX: + /* not supported for Tofino-1 */ + if (bfdev->info.tof_type == BF_TOFINO_1) { + return EINVAL; + } else { + int i; + bf_tbus_msix_indices_t msix_ind; + if (copy_from_user(&msix_ind, addr, sizeof(bf_tbus_msix_indices_t))) { + return EFAULT; + } + if (msix_ind.cnt > BF_TBUS_MSIX_INDICES_MAX) { + return EINVAL; + } + for (i = 0; i < msix_ind.cnt; i++) { + if (msix_ind.indices[i] >= BF_MSIX_ENTRY_CNT) { + return EINVAL; + } + } + for (i = 0; i < msix_ind.cnt; i++) { + bfdev->info.tbus_msix_ind[i] = msix_ind.indices[i]; + } + bfdev->info.tbus_msix_map_enable = 1; + } + break; + case BF_GET_INTR_MODE: + { + bf_intr_mode_t i_mode; + i_mode.intr_mode = bfdev->mode; + if (copy_to_user(addr, &i_mode, sizeof(bf_intr_mode_t))) { + return EFAULT; + } + } + break; default: return EINVAL; } @@ -731,27 +725,27 @@ static long bf_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) } static const struct file_operations bf_fops = { - .owner = THIS_MODULE, - .open = bf_open, - .release = bf_release, - .unlocked_ioctl = bf_ioctl, - .read = bf_read, - .write = bf_write, - .mmap = bf_mmap, - .poll = bf_poll, - .fasync = bf_fasync, + .owner = THIS_MODULE, + .open = bf_open, + .release = bf_release, + .unlocked_ioctl = bf_ioctl, + .read = bf_read, + .write = bf_write, + .mmap = bf_mmap, + .poll = bf_poll, + .fasync = bf_fasync, }; -static int bf_major_init(struct bf_pci_dev *bfdev, int minor) -{ +static int bf_major_init(struct bf_pci_dev *bfdev, int minor) { struct cdev *cdev; static const char name[] = "bf"; dev_t bf_dev = 0; int result; result = alloc_chrdev_region(&bf_dev, 0, BF_MAX_DEVICE_CNT, name); - if (result) + if (result) { return result; + } result = -ENOMEM; cdev = cdev_alloc(); @@ -763,8 +757,9 @@ static int bf_major_init(struct bf_pci_dev *bfdev, int minor) kobject_set_name(&cdev->kobj, "%s", name); result = cdev_add(cdev, bf_dev, BF_MAX_DEVICE_CNT); - if (result) + if (result) { goto fail_dev_add; + } bf_major = MAJOR(bf_dev); bf_global[minor].bf_cdev = cdev; @@ -775,19 +770,16 @@ static int bf_major_init(struct bf_pci_dev *bfdev, int minor) return result; } -static void bf_major_cleanup(struct bf_pci_dev *bfdev, int minor) -{ +static void bf_major_cleanup(struct bf_pci_dev *bfdev, int minor) { unregister_chrdev_region(MKDEV(bf_major, 0), BF_MAX_DEVICE_CNT); cdev_del(bf_global[minor].bf_cdev); } -static int bf_init_cdev(struct bf_pci_dev *bfdev, int minor) -{ +static int bf_init_cdev(struct bf_pci_dev *bfdev, int minor) { int ret; ret = bf_major_init(bfdev, minor); - if (ret) - return ret; - + if (ret) return ret; + bf_class = class_create(THIS_MODULE, BF_CLASS_NAME); if (!bf_class) { printk(KERN_ERR "create_class failed for bf_dev\n"); @@ -801,28 +793,26 @@ static int bf_init_cdev(struct bf_pci_dev *bfdev, int minor) return ret; } -static void bf_remove_cdev(struct bf_pci_dev *bfdev) -{ +static void bf_remove_cdev(struct bf_pci_dev *bfdev) { class_destroy(bf_class); bf_major_cleanup(bfdev, bfdev->info.minor); } - /** * bf_register_device - register a new userspace mem device * @parent: parent device - * @bfdev: bf pci device + * @bfdev: bf pci device * * returns zero on success or a negative error code. */ -int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) -{ +int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) { struct bf_dev_info *info = &bfdev->info; int i, j, ret = 0; int minor; - if (!parent || !info || !info->version) + if (!parent || !info || !info->version) { return -EINVAL; + } init_waitqueue_head(&info->wait); @@ -840,9 +830,8 @@ int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) return ret; } - info->dev = device_create(bf_class, parent, - MKDEV(bf_major, minor), bfdev, - "bf%d", minor); + info->dev = device_create( + bf_class, parent, MKDEV(bf_major, minor), bfdev, "bf%d", minor); if (!info->dev) { printk(KERN_ERR "BF: device creation failed\n"); return -ENODEV; @@ -861,19 +850,24 @@ int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) * freed until they are released. */ if (bfdev->mode == BF_INTR_MODE_LEGACY) { - ret = request_irq(info->irq, bf_interrupt, - info->irq_flags, bfdev->name, + ret = request_irq(info->irq, + bf_interrupt, + info->irq_flags, + bfdev->name, (void *)&(bfdev->bf_int_vec[0])); if (ret) { printk(KERN_ERR "bf failed to request legacy irq %ld error %d\n", - info->irq, ret); + info->irq, + ret); return ret; } printk(KERN_NOTICE "BF allocating legacy int vector %ld\n", info->irq); } else if (bfdev->mode == BF_INTR_MODE_MSIX) { for (i = 0; i < info->num_irq; i++) { - ret = request_irq(info->msix_entries[i].vector, bf_interrupt, - info->irq_flags, bfdev->name, + ret = request_irq(info->msix_entries[i].vector, + bf_interrupt, + info->irq_flags, + bfdev->name, (void *)&(bfdev->bf_int_vec[i])); if (ret) { /* undo all other previous bindings */ @@ -883,14 +877,17 @@ int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) (void *)&(bfdev->bf_int_vec[j])); } return ret; - } + } } printk(KERN_NOTICE "BF allocating %d MSIx vectors from %ld\n", - info->num_irq, info->irq); + info->num_irq, + info->irq); } else if (bfdev->mode == BF_INTR_MODE_MSI) { for (i = 0; i < info->num_irq; i++) { - ret = request_irq(info->irq + i, bf_interrupt, - info->irq_flags, bfdev->name, + ret = request_irq(info->irq + i, + bf_interrupt, + info->irq_flags, + bfdev->name, (void *)&(bfdev->bf_int_vec[i])); if (ret) { /* undo all other previous bindings */ @@ -899,10 +896,11 @@ int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) free_irq(info->irq + j, (void *)&(bfdev->bf_int_vec[j])); } return ret; - } + } } printk(KERN_NOTICE "BF allocating %d MSI vectors from %ld\n", - info->num_irq, info->irq); + info->num_irq, + info->irq); } } return 0; @@ -910,12 +908,11 @@ int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) /** * bf_unregister_device - register a new userspace mem device - * @bfdev: bf pci device + * @bfdev: bf pci device * * returns none */ -void bf_unregister_device(struct bf_pci_dev *bfdev) -{ +void bf_unregister_device(struct bf_pci_dev *bfdev) { struct bf_dev_info *info = &bfdev->info; int i; @@ -938,8 +935,7 @@ void bf_unregister_device(struct bf_pci_dev *bfdev) return; } -static inline struct device *pci_dev_to_dev(struct pci_dev *pdev) -{ +static inline struct device *pci_dev_to_dev(struct pci_dev *pdev) { return &pdev->dev; } @@ -957,7 +953,7 @@ static void bf_disable_int_dma(struct bf_pci_dev *bfdev) { /* mask interrupt at shadow level */ bf_addr = (u32 *)((u8 *)bf_base_addr + 0xc0); for (i = 0; i < 16; i++) { - *bf_addr = 0xffffffff; + *bf_addr = 0xffffffffUL; bf_addr++; } /* mask DMA */ @@ -967,18 +963,17 @@ static void bf_disable_int_dma(struct bf_pci_dev *bfdev) { *bf_addr = val; } -static int -bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) -{ +static int bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct bf_pci_dev *bfdev; - int err; + int err, pci_use_highmem; int i, num_irq; memset(bf_global, 0, sizeof(bf_global)); bfdev = kzalloc(sizeof(struct bf_pci_dev), GFP_KERNEL); - if (!bfdev) + if (!bfdev) { return -ENOMEM; + } /* init the cookies to be passed to ISRs */ for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { @@ -992,12 +987,32 @@ bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* clear pci_error_state */ bfdev->info.pci_error_state = 0; + /* mark pci device_id type */ + bfdev->info.pci_dev_id = pdev->device; + switch (pdev->device) { + case TOFINO2_DEV_ID_A0: + case TOFINO2_DEV_ID_A00: + case TOFINO2_DEV_ID_B0: + bfdev->info.tof_type = BF_TOFINO_2; + break; + default: + bfdev->info.tof_type = BF_TOFINO_1; + break; + } + /* intialize TBUS MSIX indices */ + for (i = 0; i < BF_TBUS_MSIX_INDICES_MAX; i++) { + if (bfdev->info.tof_type == BF_TOFINO_1) { + bfdev->info.tbus_msix_ind[i] = BF_TBUS_MSIX_BASE_INDEX_TOF1 + i; + } else if (bfdev->info.tof_type == BF_TOFINO_2) { + bfdev->info.tbus_msix_ind[i] = BF_TBUS_MSIX_INDEX_INVALID; + } + } /* * enable device */ err = pci_enable_device(pdev); if (err != 0) { - dev_err(&pdev->dev, "Cannot enable PCI device\n"); + printk(KERN_ERR "bf cannot enable PCI device\n"); goto fail_free; } @@ -1007,27 +1022,29 @@ bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) */ err = pci_request_regions(pdev, "bf_umem"); if (err != 0) { - dev_err(&pdev->dev, "Cannot request regions\n"); + printk(KERN_ERR "bf Cannot request regions\n"); goto fail_pci_disable; } /* remap IO memory */ err = bf_setup_bars(pdev, &bfdev->info); - if (err != 0) + if (err != 0) { + printk(KERN_ERR "bf Cannot setup BARs\n"); goto fail_release_iomem; + } if (!dma_set_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(64)) && !dma_set_coherent_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(64))) { + pci_use_highmem = 1; } else { err = dma_set_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(32)); if (err) { - err = dma_set_coherent_mask(pci_dev_to_dev(pdev), - DMA_BIT_MASK(32)); + err = dma_set_coherent_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(32)); if (err) { - dev_err(pci_dev_to_dev(pdev), "No usable DMA " - "configuration, aborting\n"); - goto fail_release_iomem; + printk(KERN_ERR "bf no usable DMA configuration, aborting\n"); + goto fail_release_iomem; } } + pci_use_highmem = 0; } /* enable pci error reporting */ @@ -1054,126 +1071,142 @@ bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) switch (bf_intr_mode_default) { #ifdef CONFIG_PCI_MSI - case BF_INTR_MODE_MSIX: - /* Only 1 msi-x vector needed */ - bfdev->info.msix_entries = kcalloc(BF_MSIX_ENTRY_CNT, - sizeof(struct msix_entry), GFP_KERNEL); - if (!bfdev->info.msix_entries) { - err = -ENOMEM; - goto fail_clear_pci_master; - } - for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { - bfdev->info.msix_entries[i].entry= i; - } + case BF_INTR_MODE_MSIX: + /* Only 1 msi-x vector needed */ + bfdev->info.msix_entries = + kcalloc(BF_MSIX_ENTRY_CNT, sizeof(struct msix_entry), GFP_KERNEL); + if (!bfdev->info.msix_entries) { + err = -ENOMEM; + goto fail_clear_pci_master; + } + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { + bfdev->info.msix_entries[i].entry = i; + } #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) - num_irq = pci_enable_msix(pdev, bfdev->info.msix_entries, - BF_MSIX_ENTRY_CNT); - if (num_irq == 0) { - dev_dbg(&pdev->dev, "using MSI-X"); - bfdev->info.num_irq = BF_MSIX_ENTRY_CNT; - bfdev->info.irq = bfdev->info.msix_entries[0].vector; - bfdev->mode = BF_INTR_MODE_MSIX; - printk(KERN_DEBUG "bf using %d MSIX irq from %ld\n", num_irq, - bfdev->info.irq); - break; - } + num_irq = pci_enable_msix(pdev, bfdev->info.msix_entries, + BF_MSIX_ENTRY_CNT); + if (num_irq == 0) { + bfdev->info.num_irq = BF_MSIX_ENTRY_CNT; + bfdev->info.irq = bfdev->info.msix_entries[0].vector; + bfdev->mode = BF_INTR_MODE_MSIX; + printk(KERN_DEBUG "bf using %d MSIX irq from %ld\n", num_irq, + bfdev->info.irq); + break; + } #else - num_irq = pci_enable_msix_range(pdev, bfdev->info.msix_entries, - BF_MSIX_ENTRY_CNT, BF_MSIX_ENTRY_CNT); - if (num_irq == BF_MSIX_ENTRY_CNT) { - dev_dbg(&pdev->dev, "using MSI-X"); - bfdev->info.num_irq = num_irq; - bfdev->info.irq = bfdev->info.msix_entries[0].vector; - bfdev->mode = BF_INTR_MODE_MSIX; - printk(KERN_DEBUG "bf using %d MSIX irq from %ld\n", num_irq, - bfdev->info.irq); - break; - } else { - if (num_irq) - pci_disable_msix(pdev); - kfree(bfdev->info.msix_entries); - bfdev->info.msix_entries = NULL; - printk(KERN_ERR "bf error allocating MSIX vectors. Trying MSI...\n"); - /* and, fall back to MSI */ - } + num_irq = pci_enable_msix_range( + pdev, bfdev->info.msix_entries, BF_MSIX_ENTRY_CNT, BF_MSIX_ENTRY_CNT); + if (num_irq == BF_MSIX_ENTRY_CNT) { + bfdev->info.num_irq = num_irq; + bfdev->info.irq = bfdev->info.msix_entries[0].vector; + bfdev->mode = BF_INTR_MODE_MSIX; + printk(KERN_DEBUG "bf using %d MSIX irq from %ld\n", + num_irq, + bfdev->info.irq); + break; + } else { + if (num_irq) pci_disable_msix(pdev); + kfree(bfdev->info.msix_entries); + bfdev->info.msix_entries = NULL; + printk(KERN_ERR "bf error allocating MSIX vectors. Trying MSI...\n"); + /* and, fall back to MSI */ + } #endif /* LINUX_VERSION_CODE */ /* ** intentional no-break */ - case BF_INTR_MODE_MSI: + case BF_INTR_MODE_MSI: #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) - num_irq = pci_enable_msi_block(pdev, BF_MSI_ENTRY_CNT); - /* we must get requested number of MSI vectors enabled */ - if (num_irq == 0) { - dev_dbg(&pdev->dev, "using MSI"); - bfdev->info.num_irq = BF_MSI_ENTRY_CNT; - bfdev->info.irq = pdev->irq; - bfdev->mode = BF_INTR_MODE_MSI; - printk(KERN_DEBUG "bf using %d MSI irq from %ld\n", bfdev->info.num_irq, + num_irq = pci_enable_msi_block(pdev, BF_MSI_ENTRY_CNT); + /* we must get requested number of MSI vectors enabled */ + if (num_irq == 0) { + bfdev->info.num_irq = BF_MSI_ENTRY_CNT; + bfdev->info.irq = pdev->irq; + bfdev->mode = BF_INTR_MODE_MSI; + printk(KERN_DEBUG "bf using %d MSI irq from %ld\n", bfdev->info.num_irq, bfdev->info.irq); - break; - } + break; + } #elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) - num_irq = pci_enable_msi_range(pdev, BF_MSI_ENTRY_CNT, BF_MSI_ENTRY_CNT); - if (num_irq > 0) { - dev_dbg(&pdev->dev, "using MSI"); - bfdev->info.num_irq = num_irq; - bfdev->info.irq = pdev->irq; - bfdev->mode = BF_INTR_MODE_MSI; - printk(KERN_DEBUG "bf using %d MSI irq from %ld\n", bfdev->info.num_irq, - bfdev->info.irq); - break; - } + num_irq = pci_enable_msi_range(pdev, BF_MSI_ENTRY_CNT, BF_MSI_ENTRY_CNT); + if (num_irq > 0) { + bfdev->info.num_irq = num_irq; + bfdev->info.irq = pdev->irq; + bfdev->mode = BF_INTR_MODE_MSI; + printk(KERN_DEBUG "bf using %d MSI irq from %ld\n", + bfdev->info.num_irq, + bfdev->info.irq); + break; + } #else - num_irq = pci_alloc_irq_vectors_affinity(pdev, BF_MSI_ENTRY_CNT, - BF_MSI_ENTRY_CNT, PCI_IRQ_MSI | PCI_IRQ_AFFINITY, NULL); - if (num_irq > 0) { - dev_dbg(&pdev->dev, "using MSI"); - bfdev->info.num_irq = num_irq; - bfdev->info.irq = pci_irq_vector(pdev, 0); - bfdev->mode = BF_INTR_MODE_MSI; - printk(KERN_DEBUG "bf using %d MSI irq from %ld\n", bfdev->info.num_irq, + num_irq = pci_alloc_irq_vectors_affinity(pdev, BF_MSI_ENTRY_CNT, + BF_MSI_ENTRY_CNT, PCI_IRQ_MSI | PCI_IRQ_AFFINITY, NULL); + if (num_irq > 0) { + bfdev->info.num_irq = num_irq; + bfdev->info.irq = pci_irq_vector(pdev, 0); + bfdev->mode = BF_INTR_MODE_MSI; + printk(KERN_DEBUG "bf using %d MSI irq from %ld\n", bfdev->info.num_irq, bfdev->info.irq); - break; - } + break; + } #endif /* LINUX_VERSION_CODE */ #endif /* CONFIG_PCI_MSI */ /* fall back to Legacy Interrupt, intentional no-break */ - case BF_INTR_MODE_LEGACY: - if (pci_intx_mask_supported(pdev)) { - dev_dbg(&pdev->dev, "using INTX"); - bfdev->info.irq_flags = IRQF_SHARED; - bfdev->info.irq = pdev->irq; - bfdev->mode = BF_INTR_MODE_LEGACY; - printk(KERN_DEBUG "bf using LEGACY irq %ld\n", bfdev->info.irq); - break; - } - dev_notice(&pdev->dev, "PCI INTx mask not supported\n"); + case BF_INTR_MODE_LEGACY: + if (pci_intx_mask_supported(pdev)) { + bfdev->info.irq_flags = IRQF_SHARED; + bfdev->info.irq = pdev->irq; + bfdev->mode = BF_INTR_MODE_LEGACY; + printk(KERN_DEBUG "bf using LEGACY irq %ld\n", bfdev->info.irq); + break; + } + printk(KERN_NOTICE " bf PCI INTx mask not supported\n"); /* fall back to no Interrupt, intentional no-break */ - case BF_INTR_MODE_NONE: - bfdev->info.irq = 0; - bfdev->info.num_irq = 0; - bfdev->mode = BF_INTR_MODE_NONE; - break; + case BF_INTR_MODE_NONE: + bfdev->info.irq = 0; + bfdev->info.num_irq = 0; + bfdev->mode = BF_INTR_MODE_NONE; + break; - default: - dev_err(&pdev->dev, "invalid IRQ mode %u", bf_intr_mode_default); - err = -EINVAL; - goto fail_clear_pci_master; + default: + printk(KERN_DEBUG "bf invalid IRQ mode %u", bf_intr_mode_default); + err = -EINVAL; + goto fail_clear_pci_master; } pci_set_drvdata(pdev, bfdev); sprintf(bfdev->name, "bf_%d", bfdev->info.minor); /* register bf driver */ err = bf_register_device(&pdev->dev, bfdev); - if (err != 0) + if (err != 0) { goto fail_release_irq; + } bf_global[bfdev->info.minor].async_queue = NULL; bf_global[bfdev->info.minor].bfdev = bfdev; - dev_info(&pdev->dev, "bf device %d registered with irq %ld\n", - bfdev->instance, bfdev->info.irq); + dev_info(&pdev->dev, + "bf device %d registered with irq %ld\n", + bfdev->instance, + bfdev->info.irq); printk(KERN_ALERT "bf probe ok\n"); +#ifdef BF_INCLUDE_KPKT + if (kpkt_mode) { + err = bf_kpkt_init(pdev, + bfdev->info.mem[0].internal_addr, + &bfdev->adapter_ptr, + bfdev->info.minor, + pci_use_highmem, + kpkt_hd_room, + kpkt_dr_int_en, + kpkt_rx_count); + if (err == 0) { + printk(KERN_ALERT "bf_kpkt kernel processing enabled\n"); + } else { + printk(KERN_ALERT "error starting bf_kpkt kernel processing\n"); + bfdev->adapter_ptr = NULL; + } + } +#endif return 0; fail_release_irq: @@ -1182,11 +1215,11 @@ bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) pci_disable_msix(bfdev->pdev); kfree(bfdev->info.msix_entries); bfdev->info.msix_entries = NULL; - } - else if (bfdev->mode == BF_INTR_MODE_MSI) + } else if (bfdev->mode == BF_INTR_MODE_MSI) { pci_disable_msi(bfdev->pdev); + } fail_clear_pci_master: - pci_clear_master(pdev); + pci_clear_master(pdev); fail_release_iomem: bf_pci_release_iomem(&bfdev->info); pci_release_regions(pdev); @@ -1199,22 +1232,24 @@ bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) return err; } - -static void -bf_pci_remove(struct pci_dev *pdev) -{ +static void bf_pci_remove(struct pci_dev *pdev) { struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); struct bf_listener *cur_listener; +#ifdef BF_INCLUDE_KPKT + if (kpkt_mode) { + bf_kpkt_remove(bfdev->adapter_ptr); + } +#endif bf_disable_int_dma(bfdev); bf_unregister_device(bfdev); if (bfdev->mode == BF_INTR_MODE_MSIX) { pci_disable_msix(pdev); kfree(bfdev->info.msix_entries); bfdev->info.msix_entries = NULL; - } - else if (bfdev->mode == BF_INTR_MODE_MSI) + } else if (bfdev->mode == BF_INTR_MODE_MSI) { pci_disable_msi(pdev); + } pci_clear_master(pdev); bf_pci_release_iomem(&bfdev->info); pci_release_regions(pdev); @@ -1234,6 +1269,17 @@ bf_pci_remove(struct pci_dev *pdev) kfree(bfdev); } +/* AER support callbacks. Refer to: + * https://www.kernel.org/doc/Documentation/PCI/pcieaer-howto.txt + * and + * https://www.kernel.org/doc/Documentation/PCI/pci-error-recovery.txt + * + * from bf_kdrv point of view, AER uncorrected errors (fatal and non-fatal) + * should not cause pci link reset (upstream port AER callbacks must also + * support this requirements of bf_kdrv) + * Device, however, is not expected to function after uncorrected errors + * but, application has chance to perform diags without resetting pci link + */ /** * bf_pci_error_detected - called when PCI error is detected * @pdev: Pointer to PCI device @@ -1242,10 +1288,8 @@ bf_pci_remove(struct pci_dev *pdev) * called when root complex detects pci error associated with the device */ static pci_ers_result_t bf_pci_error_detected(struct pci_dev *pdev, - pci_channel_state_t state) -{ + pci_channel_state_t state) { struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); - int minor; if (!bfdev) { return PCI_ERS_RESULT_NONE; @@ -1253,15 +1297,35 @@ static pci_ers_result_t bf_pci_error_detected(struct pci_dev *pdev, printk(KERN_ERR "pci_err_detected state %d\n", state); if (state == pci_channel_io_perm_failure || state == pci_channel_io_frozen) { bfdev->info.pci_error_state = 1; +#ifdef BF_INCLUDE_KPKT + if (kpkt_mode) { + bf_kpkt_set_pci_error(bfdev->adapter_ptr, 1); + } +#endif + /* we do not want pci link to go down. The user space application + * should collect the diag info, terminate the application and unload the + * kernel module + */ + return PCI_ERS_RESULT_CAN_RECOVER; /* to prevent pci link down */ + } else { + return PCI_ERS_RESULT_CAN_RECOVER; + } +} + +static pci_ers_result_t bf_pci_mmio_enabled(struct pci_dev *dev) { + struct bf_pci_dev *bfdev = pci_get_drvdata(dev); + + printk(KERN_ERR "BF pci_mmio_enabled invoked after pci error\n"); + pci_cleanup_aer_uncorrect_error_status(dev); + + if (bfdev) { /* send a signal to the user space program of the error */ - minor = bfdev->info.minor; + int minor = bfdev->info.minor; if (minor < BF_MAX_DEVICE_CNT && bf_global[minor].async_queue) { kill_fasync(&bf_global[minor].async_queue, SIGIO, POLL_ERR); } - return PCI_ERS_RESULT_DISCONNECT; - } else { - return PCI_ERS_RESULT_NONE; } + return PCI_ERS_RESULT_RECOVERED; } /** @@ -1270,13 +1334,13 @@ static pci_ers_result_t bf_pci_error_detected(struct pci_dev *pdev, * * Restart the card from scratch, as if from a cold-boot. */ -static pci_ers_result_t bf_pci_slot_reset(struct pci_dev *pdev) -{ +static pci_ers_result_t bf_pci_slot_reset(struct pci_dev *pdev) { /* nothing to do for now as we do not expect to get backto normal after - * a pcie link reset + * a pcie link reset. Not expected to be invoked. * TBD: fill in this function if tofino can recover after an error */ - return PCI_ERS_RESULT_DISCONNECT; + printk(KERN_ERR "BF pci_slot_reset invoked after pci error\n"); + return PCI_ERS_RESULT_RECOVERED; } /** @@ -1286,22 +1350,13 @@ static pci_ers_result_t bf_pci_slot_reset(struct pci_dev *pdev) * This callback is called when the error recovery driver tells us that * its OK to resume normal operation. */ -static void bf_pci_resume(struct pci_dev *pdev) -{ - /* this function should never be called for Tofinoi */ - struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); - +static void bf_pci_resume(struct pci_dev *pdev) { printk(KERN_ERR "BF io_resume invoked after pci error\n"); - if (bfdev) { - bfdev->info.pci_error_state = 0; - } } -static int -bf_config_intr_mode(char *intr_str) -{ +static int bf_config_intr_mode(char *intr_str) { if (!intr_str) { - pr_info("Use MSIX interrupt by default\n"); + pr_info("Use MSI interrupt by default\n"); return 0; } @@ -1314,67 +1369,108 @@ bf_config_intr_mode(char *intr_str) } else if (!strcmp(intr_str, BF_INTR_MODE_LEGACY_NAME)) { bf_intr_mode_default = BF_INTR_MODE_LEGACY; pr_info("Use legacy interrupt\n"); - } else { + } else if (!strcmp(intr_str, BF_INTR_MODE_NONE_NAME)) { bf_intr_mode_default = BF_INTR_MODE_NONE; - pr_info(" No Interrupt \n"); + pr_info("BF interrupt disabled\n"); + } else { + pr_info("Error: bad intr_mode parameter - %s\n", intr_str); + return -EINVAL; } - return 0; } static const struct pci_device_id bf_pci_tbl[] = { - {PCI_VDEVICE(BF, TOFINO_DEV_ID_A0), 0}, - {PCI_VDEVICE(BF, TOFINO_DEV_ID_B0), 0}, - {PCI_VDEVICE(BF, TOFINO2_DEV_ID_A0), 0}, - /* required last entry */ - { .device = 0 } -}; + {PCI_VDEVICE(BF, TOFINO_DEV_ID_A0), 0}, + {PCI_VDEVICE(BF, TOFINO_DEV_ID_B0), 0}, + {PCI_VDEVICE(BF, TOFINO2_DEV_ID_A0), 0}, + {PCI_VDEVICE(BF, TOFINO2_DEV_ID_A00), 0}, + {PCI_VDEVICE(BF, TOFINO2_DEV_ID_B0), 0}, + /* required last entry */ + {.device = 0}}; /* PCI bus error handlers */ static struct pci_error_handlers bf_pci_err_handler = { - .error_detected = bf_pci_error_detected, - .slot_reset = bf_pci_slot_reset, - .resume = bf_pci_resume, + .error_detected = bf_pci_error_detected, + .mmio_enabled = bf_pci_mmio_enabled, + .slot_reset = bf_pci_slot_reset, + .resume = bf_pci_resume, }; -static struct pci_driver bf_pci_driver = { - .name = "bf", - .id_table = bf_pci_tbl, - .probe = bf_pci_probe, - .remove = bf_pci_remove, - .err_handler = &bf_pci_err_handler -}; +static struct pci_driver bf_pci_driver = {.name = "bf", + .id_table = bf_pci_tbl, + .probe = bf_pci_probe, + .remove = bf_pci_remove, + .err_handler = &bf_pci_err_handler}; -static int __init -bfdrv_init(void) -{ +static int __init bfdrv_init(void) { int ret; ret = bf_config_intr_mode(intr_mode); - if (ret < 0) + /* do not enable DR interrupt if not using MSI or not in kpkt mode */ + if ((bf_intr_mode_default != BF_INTR_MODE_MSI && + bf_intr_mode_default != BF_INTR_MODE_LEGACY) || kpkt_mode == 0) { + kpkt_dr_int_en = 0; + } + if (kpkt_mode) { + printk(KERN_NOTICE "kpkt_mode %d hd_room %d dr_int_en %d rx_count %d\n", + kpkt_mode, + kpkt_hd_room, + kpkt_dr_int_en, + kpkt_rx_count); + } + if (ret < 0) { return ret; - + } spin_lock_init(&bf_nonisr_lock); return pci_register_driver(&bf_pci_driver); } -static void __exit -bfdrv_exit(void) -{ +static void __exit bfdrv_exit(void) { pci_unregister_driver(&bf_pci_driver); + intr_mode = NULL; + kpkt_mode = 0; } module_init(bfdrv_init); module_exit(bfdrv_exit); +module_param(kpkt_mode, int, S_IRUGO); +MODULE_PARM_DESC(kpkt_mode, + "bf kernel mode pkt processing (default=off):\n" + " 1 Use kernel mode bf_pkt processing\n" + " 0 Do not use kernel mode bf_pkt processing\n" + "\n"); + +module_param(kpkt_hd_room, int, S_IRUGO); +MODULE_PARM_DESC(kpkt_hd_room, + "head room to reserve when receiving packets (default=32):\n" + "\n"); + +module_param(kpkt_rx_count, int, S_IRUGO); +MODULE_PARM_DESC(kpkt_rx_count, + "number of buffers per rx pkt ring (default=256):\n" + "\n"); +/* dr_int_en is applicable only if MSI interrupt mode is selected */ +module_param(kpkt_dr_int_en, int, S_IRUGO); +MODULE_PARM_DESC(kpkt_dr_int_en, + "bf pkt Interrupt enable (default=1):\n" + " 1 use interrupt\n" + " 0 Do not use interrupt\n" + "\n"); + module_param(intr_mode, charp, S_IRUGO); MODULE_PARM_DESC(intr_mode, -"bf interrupt mode (default=msix):\n" -" " BF_INTR_MODE_MSIX_NAME " Use MSIX interrupt\n" -" " BF_INTR_MODE_MSI_NAME " Use MSI interrupt\n" -" " BF_INTR_MODE_LEGACY_NAME " Use Legacy interrupt\n" -"\n"); + "bf interrupt mode (default=msix):\n" + " " BF_INTR_MODE_MSIX_NAME + " Use MSIX interrupt\n" + " " BF_INTR_MODE_MSI_NAME + " Use MSI interrupt\n" + " " BF_INTR_MODE_LEGACY_NAME + " Use Legacy interrupt\n" + " " BF_INTR_MODE_NONE_NAME + " Use no interrupt\n" + "\n"); MODULE_DEVICE_TABLE(pci, bf_pci_tbl); MODULE_DESCRIPTION("Barefoot Tofino PCI device"); diff --git a/platform/barefoot/bfn-modules/modules/bf_kdrv.h b/platform/barefoot/bfn-modules/modules/bf_kdrv.h new file mode 100644 index 000000000000..de5ca4bbc71c --- /dev/null +++ b/platform/barefoot/bfn-modules/modules/bf_kdrv.h @@ -0,0 +1,146 @@ +/******************************************************************************* + Barefoot Networks Switch ASIC Linux driver + Copyright(c) 2015 - 2019 Barefoot Networks, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + info@barefootnetworks.com + Barefoot Networks, 4750 Patrick Henry Drive, Santa Clara CA 95054 + +*******************************************************************************/ +#ifndef _BF_KDRV_H_ +#define _BF_KDRV_H_ + +#include +#include +#include + +#ifndef phys_addr_t +typedef uint64_t phys_addr_t; +#endif + +#define PCI_VENDOR_ID_BF 0x1d1c +#define TOFINO_DEV_ID_A0 0x01 +#define TOFINO_DEV_ID_B0 0x10 +#define TOFINO2_DEV_ID_A0 0x0100 +#define TOFINO2_DEV_ID_A00 0x0000 +#define TOFINO2_DEV_ID_B0 0x0110 + +#ifndef PCI_MSIX_ENTRY_SIZE +#define PCI_MSIX_ENTRY_SIZE 16 +#define PCI_MSIX_ENTRY_LOWER_ADDR 0 +#define PCI_MSIX_ENTRY_UPPER_ADDR 4 +#define PCI_MSIX_ENTRY_DATA 8 +#define PCI_MSIX_ENTRY_VECTOR_CTRL 12 +#define PCI_MSIX_ENTRY_CTRL_MASKBIT 1 +#endif + +#define BF_CLASS_NAME "bf" +#define BF_MAX_DEVICE_CNT 256 +#define BF_INTR_MODE_NONE_NAME "none" +#define BF_INTR_MODE_LEGACY_NAME "legacy" +#define BF_INTR_MODE_MSI_NAME "msi" +#define BF_INTR_MODE_MSIX_NAME "msix" +#define BF_MAX_BAR_MAPS 6 +#define BF_MSIX_ENTRY_CNT 32 /* 512 for tofino-1 */ +#define BF_MSI_ENTRY_CNT 2 +#define BF_MSI_INT_TBUS 1 + +#define BF_TBUS_MSIX_INDEX_INVALID (0) +#define BF_TBUS_MSIX_BASE_INDEX_TOF1 (32) + +/* Tofino generation type */ +typedef enum { + BF_TOFINO_NONE = 0, + BF_TOFINO_1, + BF_TOFINO_2, +} bf_tof_type; + +/* device memory */ +struct bf_dev_mem { + const char *name; + phys_addr_t addr; + resource_size_t size; + void __iomem *internal_addr; +}; + +struct bf_listener { + struct bf_pci_dev *bfdev; + s32 event_count[BF_MSIX_ENTRY_CNT]; + int minor; + struct bf_listener *next; +}; + +/* device information */ +struct bf_dev_info { + struct module *owner; + struct device *dev; + int minor; + atomic_t event[BF_MSIX_ENTRY_CNT]; + wait_queue_head_t wait; + const char *version; + struct bf_dev_mem mem[BF_MAX_BAR_MAPS]; + struct msix_entry *msix_entries; + long irq; /* first irq vector */ + int num_irq; /* number of irq vectors */ + unsigned long irq_flags; /* sharable ?? */ + uint16_t pci_dev_id; /* generation type of BF ASIC */ + bf_tof_type tof_type; /* Tofino generation type */ + /* msix index assigned to tbus MSIX for Tofino-2 only */ + int tbus_msix_ind[BF_TBUS_MSIX_INDICES_MAX]; + int tbus_msix_map_enable; + int pci_error_state; /* was there a pci bus error */ +}; + +/* cookie to be passed to IRQ handler, useful especially with MSIX */ +struct bf_int_vector { + struct bf_pci_dev *bf_dev; + int int_vec_offset; +}; + +/** + * A structure describing the private information for a BF pcie device. + */ +struct bf_pci_dev { + struct bf_dev_info info; + struct pci_dev *pdev; + enum bf_intr_mode mode; + u8 instance; + char name[16]; + struct bf_int_vector bf_int_vec[BF_MSIX_ENTRY_CNT]; + struct bf_listener * + listener_head; /* head of a singly linked list of listeners */ + void *adapter_ptr; /* pkt processing adapter */ +}; + +/* TBD: Need to build with CONFIG_PCI_MSI */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) +#if defined(RHEL_RELEASE_CODE) +#else +extern int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec); +#endif /* defined(RHEL_RELEASE_CODE) */ +extern int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec); +#else +extern int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec); +extern int pci_enable_msix_range(struct pci_dev *dev, + struct msix_entry *entries, + int minvec, + int maxvec); +#endif + +#endif /* _BF_KDRV_H_ */ diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 854026b52949..1abbedffd6c6 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,5 +1,5 @@ -BFN_PLATFORM = bfnplatform_20191115_deb9.deb -$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/bfnplatform_20191115_deb9.deb" +BFN_PLATFORM = bfnplatform_20200407_deb9.deb +$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_PLATFORM)" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) $(BFN_SAI_DEV)_DEPENDS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 6f413d50c11e..b58cce6fcf47 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,5 +1,8 @@ -BFN_SAI = bfnsdk_20191115_deb9.deb -$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/bfnsdk_20191115_deb9.deb" +BFN_SAI = bfnsdk_20200407_deb9.deb +$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_SAI)" + +$(BFN_SAI)_DEPENDS += $(LIBNL_GENL3_DEV) +$(BFN_SAI)_RDEPENDS += $(LIBNL_GENL3) SONIC_ONLINE_DEBS += $(BFN_SAI) $(BFN_SAI_DEV)_DEPENDS += $(BFN_SAI) diff --git a/platform/barefoot/docker-syncd-bfn-rpc.mk b/platform/barefoot/docker-syncd-bfn-rpc.mk index d9cb0b5d6172..11b70a3a774f 100644 --- a/platform/barefoot/docker-syncd-bfn-rpc.mk +++ b/platform/barefoot/docker-syncd-bfn-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_BFN_RPC = docker-syncd-bfn-rpc.gz $(DOCKER_SYNCD_BFN_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-bfn-rpc -$(DOCKER_SYNCD_BFN_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_BFN_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) $(DOCKER_SYNCD_BFN_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_BFN_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ diff --git a/platform/barefoot/docker-syncd-bfn.mk b/platform/barefoot/docker-syncd-bfn.mk index 6f3ed59ad285..3a5c693e2fa8 100644 --- a/platform/barefoot/docker-syncd-bfn.mk +++ b/platform/barefoot/docker-syncd-bfn.mk @@ -11,4 +11,4 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIREDIS_DBG) $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot - +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd b/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd new file mode 100644 index 000000000000..3079618990ed --- /dev/null +++ b/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/barefoot/docker-syncd-bfn/supervisord.conf b/platform/barefoot/docker-syncd-bfn/supervisord.conf index 1e015fef931f..1744d6ffefb5 100644 --- a/platform/barefoot/docker-syncd-bfn/supervisord.conf +++ b/platform/barefoot/docker-syncd-bfn/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 diff --git a/platform/barefoot/platform-modules-arista.mk b/platform/barefoot/platform-modules-arista.mk index 480aa0cf8396..28c893b80713 100644 --- a/platform/barefoot/platform-modules-arista.mk +++ b/platform/barefoot/platform-modules-arista.mk @@ -7,7 +7,7 @@ export ARISTA_PLATFORM_MODULE_VERSION ARISTA_PLATFORM_MODULE = sonic-platform-arista_$(ARISTA_PLATFORM_MODULE_VERSION)_amd64.deb $(ARISTA_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-arista $(ARISTA_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) -SONIC_MAKE_DEBS += $(ARISTA_PLATFORM_MODULE) +SONIC_DPKG_DEBS += $(ARISTA_PLATFORM_MODULE) ARISTA_PLATFORM_MODULE_PYTHON2 = python-sonic-platform-arista_$(ARISTA_PLATFORM_MODULE_VERSION)_all.deb $(eval $(call add_extra_package,$(ARISTA_PLATFORM_MODULE),$(ARISTA_PLATFORM_MODULE_PYTHON2))) diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index 10750325b6cf..39860a109853 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 10750325b6cfc7a1dc1a8b0734008bde1bb3ac06 +Subproject commit 39860a109853b2f37367dfe68905e019b509d5bf diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control index 192da9dab95c..e3f5356f22db 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn-montara Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control index edbc5b890c58..bc6c990efebb 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn-newport Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel module for bfn platform fpga and scripts for the devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/control b/platform/barefoot/sonic-platform-modules-bfn/debian/control index 04d4c598e9d9..cca87831f1f1 100644 --- a/platform/barefoot/sonic-platform-modules-bfn/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh index 249f179216a6..7776493bc20a 100755 --- a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh index 23a3fd066bee..9213d115f656 100755 --- a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh @@ -66,7 +66,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/docker-syncd-brcm-rpc.mk b/platform/broadcom/docker-syncd-brcm-rpc.mk index bd2ef01c5eed..355d7e0f1f8c 100644 --- a/platform/broadcom/docker-syncd-brcm-rpc.mk +++ b/platform/broadcom/docker-syncd-brcm-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_BRCM_RPC = docker-syncd-brcm-rpc.gz $(DOCKER_SYNCD_BRCM_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-brcm-rpc -$(DOCKER_SYNCD_BRCM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_BRCM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_BRCM_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/broadcom/docker-syncd-brcm.mk b/platform/broadcom/docker-syncd-brcm.mk index 29727dbb2260..d3a6d67c5cbc 100644 --- a/platform/broadcom/docker-syncd-brcm.mk +++ b/platform/broadcom/docker-syncd-brcm.mk @@ -16,3 +16,4 @@ $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += bcmcmd:/usr/bin/bcmcmd $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += bcmsh:/usr/bin/bcmsh +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd b/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd new file mode 100644 index 000000000000..0b9ec741cd57 --- /dev/null +++ b/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd @@ -0,0 +1,11 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +## dsserve +############################################################################### +check process syncd matching "/usr/bin/syncd" + if does not exist for 5 times within 5 cycles then alert + +check process dsserve matching "/usr/bin/dsserve /usr/bin/syncd" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/broadcom/docker-syncd-brcm/supervisord.conf b/platform/broadcom/docker-syncd-brcm/supervisord.conf index cd6712acbf22..3fa8febb85d8 100644 --- a/platform/broadcom/docker-syncd-brcm/supervisord.conf +++ b/platform/broadcom/docker-syncd-brcm/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/platform/broadcom/platform-modules-arista.mk b/platform/broadcom/platform-modules-arista.mk index 480aa0cf8396..28c893b80713 100644 --- a/platform/broadcom/platform-modules-arista.mk +++ b/platform/broadcom/platform-modules-arista.mk @@ -7,7 +7,7 @@ export ARISTA_PLATFORM_MODULE_VERSION ARISTA_PLATFORM_MODULE = sonic-platform-arista_$(ARISTA_PLATFORM_MODULE_VERSION)_amd64.deb $(ARISTA_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-arista $(ARISTA_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) -SONIC_MAKE_DEBS += $(ARISTA_PLATFORM_MODULE) +SONIC_DPKG_DEBS += $(ARISTA_PLATFORM_MODULE) ARISTA_PLATFORM_MODULE_PYTHON2 = python-sonic-platform-arista_$(ARISTA_PLATFORM_MODULE_VERSION)_all.deb $(eval $(call add_extra_package,$(ARISTA_PLATFORM_MODULE),$(ARISTA_PLATFORM_MODULE_PYTHON2))) diff --git a/platform/broadcom/platform-modules-cel.mk b/platform/broadcom/platform-modules-cel.mk index b7371e3282de..f36dae1073a0 100644 --- a/platform/broadcom/platform-modules-cel.mk +++ b/platform/broadcom/platform-modules-cel.mk @@ -3,10 +3,12 @@ CEL_DX010_PLATFORM_MODULE_VERSION = 0.9 CEL_HALIBURTON_PLATFORM_MODULE_VERSION = 0.9 CEL_SILVERSTONE_PLATFORM_MODULE_VERSION = 0.9 +CEL_SHAMU_PLATFORM_MODULE_VERSION = 0.9 export CEL_DX010_PLATFORM_MODULE_VERSION export CEL_HALIBURTON_PLATFORM_MODULE_VERSION export CEL_SILVERSTONE_PLATFORM_MODULE_VERSION +export CEL_SHAMU_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 @@ -14,12 +16,19 @@ $(CEL_DX010_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(CEL_DX010_PLATFORM_MODULE)_PLATFORM = x86_64-cel_seastone-r0 SONIC_DPKG_DEBS += $(CEL_DX010_PLATFORM_MODULE) -CEL_HALIBURTON_PLATFORM_MODULE = platform-modules-haliburton_$(CEL_HALIBURTON_PLATFORM_MODULE_VERSION)_amd64.deb -$(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))) +CEL_SHAMU_PLATFORM_MODULE = platform-modules-shamu_$(CEL_SHAMU_PLATFORM_MODULE_VERSION)_amd64.deb +$(CEL_SHAMU_PLATFORM_MODULE)_PLATFORM = x86_64-alibaba_as14-40d-cl-r0 +$(eval $(call add_extra_package,$(CEL_DX010_PLATFORM_MODULE),$(CEL_SHAMU_PLATFORM_MODULE))) + +#CEL_HALIBURTON_PLATFORM_MODULE = platform-modules-haliburton_$(CEL_HALIBURTON_PLATFORM_MODULE_VERSION)_amd64.deb +#$(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/sai-modules.mk b/platform/broadcom/sai-modules.mk index 1d559d0ad320..93132c2287bd 100644 --- a/platform/broadcom/sai-modules.mk +++ b/platform/broadcom/sai-modules.mk @@ -1,6 +1,6 @@ # Broadcom SAI modules -KVERSION = 4.9.0-9-2-amd64 +KVERSION = 4.9.0-11-2-amd64 BRCM_OPENNSL_KERNEL_VERSION = 3.7.3.3-1 BRCM_OPENNSL_KERNEL = opennsl-modules_$(BRCM_OPENNSL_KERNEL_VERSION)_amd64.deb diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 63c1e21ec7fc..e6e40039caf0 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,8 @@ -BRCM_SAI = libsaibcm_3.7.3.3_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.3.3_amd64.deb?sv=2015-04-05&sr=b&sig=Y66VSRUEl4PDf5kHRo%2FS3DBBE9tONSyCzNJvi8IP9n8%3D&se=2033-08-25T01%3A22%3A08Z&sp=r" - -BRCM_SAI_DEV = libsaibcm-dev_3.7.3.3_amd64.deb +BRCM_SAI = libsaibcm_3.7.3.3-4_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.3.3-4_amd64.deb?sv=2015-04-05&sr=b&sig=9z7vLhweD%2B%2FZylkr9XsDAJ3DdE5NJlcPTslFYyBuAXU%3D&se=2033-12-25T14%3A52%3A25Z&sp=r" +BRCM_SAI_DEV = libsaibcm-dev_3.7.3.3-4_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.3.3_amd64.deb?sv=2015-04-05&sr=b&sig=6%2BWzgFL845H9lKE0COsN53P4MO4UWfSo0z%2FmUMFbYVk%3D&se=2033-08-25T01%3A21%3A50Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.3.3-4_amd64.deb?sv=2015-04-05&sr=b&sig=SAOoGh2zdljiPuKeDoa%2B1lSJzZ8uXh2Irl2RZX1uAiA%3D&se=2033-12-25T14%3A53%3A44Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) -$(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) \ No newline at end of file +$(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) diff --git a/platform/broadcom/saibcm-modules/debian/control b/platform/broadcom/saibcm-modules/debian/control index 75b77c8a2f00..fafe7dfb9299 100644 --- a/platform/broadcom/saibcm-modules/debian/control +++ b/platform/broadcom/saibcm-modules/debian/control @@ -10,5 +10,5 @@ Standards-Version: 3.9.3 Package: opennsl-modules Architecture: amd64 Section: main -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for broadcom SAI diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs b/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs index 38af58a5c5ee..a32540eadcf5 100644 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs @@ -1 +1 @@ -lib/modules/4.9.0-9-2-amd64/extra +lib/modules/4.9.0-11-2-amd64/extra diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install index e16980dc2c0d..9802d2f2443a 100644 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install @@ -1,6 +1,6 @@ -systems/linux/user/x86-smp_generic_64-2_6/linux-bcm-knet.ko lib/modules/4.9.0-9-2-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/linux-kernel-bde.ko lib/modules/4.9.0-9-2-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/linux-user-bde.ko lib/modules/4.9.0-9-2-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/linux-knet-cb.ko lib/modules/4.9.0-9-2-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/psample.ko lib/modules/4.9.0-9-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-bcm-knet.ko lib/modules/4.9.0-11-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-kernel-bde.ko lib/modules/4.9.0-11-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-user-bde.ko lib/modules/4.9.0-11-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-knet-cb.ko lib/modules/4.9.0-11-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/psample.ko lib/modules/4.9.0-11-2-amd64/extra systemd/opennsl-modules.service lib/systemd/system diff --git a/platform/broadcom/saibcm-modules/debian/rules b/platform/broadcom/saibcm-modules/debian/rules index 0092cc1a1027..636874251aa9 100755 --- a/platform/broadcom/saibcm-modules/debian/rules +++ b/platform/broadcom/saibcm-modules/debian/rules @@ -60,7 +60,7 @@ kdist_config: prep-deb-files kdist_clean: clean dh_testdir dh_clean - SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean + SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-11-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-11-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean # rm -f driver/*.o driver/*.ko # ### end KERNEL SETUP @@ -78,7 +78,7 @@ build-arch-stamp: dh_testdir # Add here command to compile/build the package. - SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 + SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-11-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-11-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 touch $@ @@ -103,7 +103,7 @@ clean: rm -f build-arch-stamp build-indep-stamp configure-stamp # Add here commands to clean up after the build process. - SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean + SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-11-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-11-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean dh_clean diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control index 9a53b9823222..beba5b5f4e62 100644 --- a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control @@ -7,11 +7,11 @@ Standards-Version: 3.9.3 Package: sonic-platform-alphanetworks-snh60a0-320fv2 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-alphanetworks-snh60b0-640f Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index 390d5e22f9c6..39860a109853 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 390d5e22f9c6c1a007ed325f6b0bd050a79aa5b1 +Subproject commit 39860a109853b2f37367dfe68905e019b509d5bf diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/control b/platform/broadcom/sonic-platform-modules-cel/debian/control index 2e9b578872fa..009f5bbcc63b 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/control +++ b/platform/broadcom/sonic-platform-modules-cel/debian/control @@ -7,16 +7,22 @@ Standards-Version: 3.9.3 Package: platform-modules-dx010 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp -Package: platform-modules-haliburton -Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 -Description: kernel modules for platform devices such as fan, led, sfp +#Package: platform-modules-haliburton +#Architecture: amd64 +#Depends: linux-image-4.9.0-11-2-amd64 +#Description: kernel modules for platform devices such as fan, led, sfp + +#Package: platform-modules-silverstone +#Architecture: amd64 +#Depends: linux-image-4.9.0-11-2-amd64 +#Description: kernel modules for platform devices such as led, sfp. -Package: platform-modules-silverstone + +Package: platform-modules-shamu Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 -Description: kernel modules for platform devices such as led, sfp. +Depends: linux-image-4.9.0-11-2-amd64 +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install index 2ab53302a9bf..8570fa1eae84 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install @@ -3,4 +3,3 @@ dx010/cfg/dx010-modules.conf etc/modules-load.d dx010/systemd/platform-modules-dx010.service lib/systemd/system dx010/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_seastone-r0 services/platform_api/platform_api_mgnt.sh usr/local/bin -tools/afulnx_64 usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install index d50306304cd5..df78b7a34ea4 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install @@ -5,4 +5,3 @@ services/fancontrol/fancontrol.service lib/systemd/system services/fancontrol/fancontrol usr/local/bin haliburton/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_e1031-r0 services/platform_api/platform_api_mgnt.sh usr/local/bin -tools/afulnx_64 usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-jaws.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-jaws.init new file mode 100644 index 000000000000..b8f079cf111b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-jaws.init @@ -0,0 +1,45 @@ +#!/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 Jaws board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + + # Add driver to support HW + modprobe i2c-dev + modprobe dimm-bus + modprobe i2c-imc allow_unsafe_access=1 + modprobe baseboard_cpld + modprobe switchboard_fpga + modprobe mc24lc64t + + # Add driver to support TLV - EEPROM + echo 24lc64t 0x56 > /sys/bus/i2c/devices/i2c-0/new_device + echo "done." + ;; + +stop) + echo "done." + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-jaws.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-jaws.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-jaws.install new file mode 100644 index 000000000000..cdc1e9c0c255 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-jaws.install @@ -0,0 +1,15 @@ +jaws/cfg/jaws-modules.conf etc/modules-load.d +jaws/systemd/platform-modules-jaws.service lib/systemd/system +tools/sync_bmc/bmc_vlan.service etc/systemd/system +tools/sync_bmc/sync_bmc.service etc/systemd/system +tools/sync_bmc/sync_bmc.timer etc/systemd/system +tools/sync_bmc/bmc_vlan.sh /usr/local/etc/ +tools/sync_bmc/sync_bmc.py /usr/local/etc/ +tools/platformutil.py /usr/local/etc/ +tools/read_optic_temp.py /usr/local/etc/ +tools/bmcutil/bmcpwd /usr/local/etc/ +tools/bmcutil/bmcutil.py /usr/local/etc/ +tools/bmcutil/bmc-exec /usr/local/bin +tools/bmc_wdt/bmc_wdt.service etc/systemd/system +tools/bmc_wdt/bmc_wdt.py /usr/local/etc/ +tools/power_utils/power /usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-jaws.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-jaws.postinst new file mode 100644 index 000000000000..4dc1e15f3f9a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-jaws.postinst @@ -0,0 +1,15 @@ +depmod -a + +# Enable bmc vlan_ip service +systemctl enable bmc_vlan.service + +systemctl enable platform-modules-jaws.service +systemctl start platform-modules-jaws.service + +# Enable platform-sync_bmc-timer +# systemctl enable sync_bmc.timer +# systemctl start sync_bmc.timer + +# Enable heartbeat timer +systemctl enable bmc_wdt.service +systemctl start bmc_wdt.service diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-shamu.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-shamu.init new file mode 100644 index 000000000000..0bb69268b743 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-shamu.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 Shamu board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + + # Add driver to support HW + modprobe dimm-bus + modprobe i2c-imc allow_unsafe_access=1 + modprobe i2c-dev + modprobe baseboard_cpld + modprobe switchboard_fpga + modprobe mc24lc64t + + # Add driver to support TLV - EEPROM + echo 24lc64t 0x56 > /sys/bus/i2c/devices/i2c-0/new_device + decode-syseeprom --init 2> /dev/null & + + /bin/sh /usr/local/bin/platform_api_mgnt.sh init + + echo 0x108 0xFF > /sys/devices/platform/AS1440D.switchboard/FPGA/setreg + + echo "done." + ;; + +stop) + echo "done." + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-shamu.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-shamu.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-shamu.install new file mode 100644 index 000000000000..220e18165445 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-shamu.install @@ -0,0 +1,20 @@ +shamu/scripts/sensors usr/bin +shamu/scripts/platform_sensors.py usr/local/bin +shamu/cfg/shamu-modules.conf etc/modules-load.d +shamu/systemd/platform-modules-shamu.service lib/systemd/system +shamu/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-alibaba_as14-40d-cl-r0 +services/platform_api/platform_api_mgnt.sh usr/local/bin + +tools/sync_bmc/bmc_vlan.service etc/systemd/system +tools/sync_bmc/sync_bmc.service etc/systemd/system +tools/sync_bmc/sync_bmc.timer etc/systemd/system +tools/sync_bmc/bmc_vlan.sh /usr/local/etc/ +tools/sync_bmc/sync_bmc.py /usr/local/etc/ +tools/platformutil.py /usr/local/etc/ +tools/read_optic_temp.py /usr/local/etc/ +tools/bmcutil/bmcpwd /usr/local/etc/ +tools/bmcutil/bmcutil.py /usr/local/etc/ +tools/bmcutil/bmc-exec /usr/local/bin +tools/bmc_wdt/bmc_wdt.service etc/systemd/system +tools/bmc_wdt/bmc_wdt.py /usr/local/etc/ +tools/power_utils/power /usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-shamu.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-shamu.postinst new file mode 100644 index 000000000000..de84287b5b7f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-shamu.postinst @@ -0,0 +1,17 @@ +depmod -a + +# Enable bmc vlan_ip service +systemctl enable bmc_vlan.service + +systemctl enable platform-modules-shamu.service +systemctl start platform-modules-shamu.service + +/usr/local/bin/platform_api_mgnt.sh install + +# Enable platform-sync_bmc-timer +# systemctl enable sync_bmc.timer +# systemctl start sync_bmc.timer + +# Enable heartbeat timer +systemctl enable bmc_wdt.service +systemctl start bmc_wdt.service diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/rules b/platform/broadcom/sonic-platform-modules-cel/debian/rules index dd5452ccaa11..5277c0b8ba76 100755 --- a/platform/broadcom/sonic-platform-modules-cel/debian/rules +++ b/platform/broadcom/sonic-platform-modules-cel/debian/rules @@ -5,7 +5,10 @@ export INSTALL_MOD_DIR:=extra KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= dx010 haliburton silverstone +MODULE_DIRS:= dx010 shamu +# +++ add by maxwill to disable unneccessory pkg +++ # +#MODULE_DIRS:= dx010 haliburton silverstone +# --- add by maxwill to disable unneccessory pkg --- # %: dh $@ @@ -17,13 +20,21 @@ override_dh_auto_build: python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ cd $(MOD_SRC_DIR); \ done) + make -C $(MOD_SRC_DIR)/tools/ispvme_12.2; + gcc -std=c99 $(MOD_SRC_DIR)/tools/fpga_prog/fpga_prog.c -o $(MOD_SRC_DIR)/tools/fpga_prog/fpga_prog; override_dh_auto_install: (for mod in $(MODULE_DIRS); do \ dh_installdirs -pplatform-modules-$${mod} \ $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + dh_installdirs -pplatform-modules-$${mod} \ + /usr/local/bin; \ cp $(MOD_SRC_DIR)/$${mod}/modules/*.ko \ debian/platform-modules-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/tools/ispvme_12.2/ispvm \ + debian/platform-modules-$${mod}/usr/local/bin/; \ + cp $(MOD_SRC_DIR)/tools/fpga_prog/fpga_prog \ + debian/platform-modules-$${mod}/usr/local/bin/; \ done) override_dh_usrlocal: @@ -33,4 +44,5 @@ override_dh_clean: (for mod in $(MODULE_DIRS); do \ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \ done) + make -C $(MOD_SRC_DIR)/tools/ispvme_12.2 clean; diff --git a/platform/broadcom/sonic-platform-modules-cel/jaws/cfg/jaws-modules.conf b/platform/broadcom/sonic-platform-modules-cel/jaws/cfg/jaws-modules.conf new file mode 100644 index 000000000000..574c48f7a66f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/jaws/cfg/jaws-modules.conf @@ -0,0 +1,16 @@ +# /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 +8021q + diff --git a/platform/broadcom/sonic-platform-modules-cel/jaws/modules/Makefile b/platform/broadcom/sonic-platform-modules-cel/jaws/modules/Makefile new file mode 100644 index 000000000000..f1777c8c5db9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/jaws/modules/Makefile @@ -0,0 +1 @@ +obj-m := mc24lc64t.o baseboard_cpld.o switchboard_fpga.o i2c-imc.o dimm-bus.o diff --git a/platform/broadcom/sonic-platform-modules-cel/jaws/modules/baseboard_cpld.c b/platform/broadcom/sonic-platform-modules-cel/jaws/modules/baseboard_cpld.c new file mode 100644 index 000000000000..951eb774a5f6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/jaws/modules/baseboard_cpld.c @@ -0,0 +1,417 @@ +/* + * baseboard_cpld.c - The CPLD driver for the Base Board of Phalanxp + * The driver implement sysfs to access CPLD register on the baseboard of Phalanxp 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 "AS14128H.cpldb" +/** + * CPLD register address for read and write. + */ +#define VERSION_ADDR 0xA100 +#define SCRATCH_ADDR 0xA101 +#define SYS_LED_ADDR 0xA162 + +#define CPLD_REGISTER_SIZE 0x7C + +struct cpld_b_data { + struct mutex cpld_lock; + uint16_t read_addr; +}; + +struct cpld_b_data *cpld_data; + +/** + * Read the value from scratch register as hex string. + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer for get value + * @return Hex string read from scratch register. + */ + + +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); +} + +/** + * Set scratch register with specific hex string. + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer of set value + * @param count number of bytes in buffer + * @return number of bytes written, or error code < 0. + */ +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) +{ + int len = 0; + // CPLD register is one byte + mutex_lock(&cpld_data->cpld_lock); + len = sprintf(buf, "0x%2.2x\n",inb(VERSION_ADDR)); + mutex_unlock(&cpld_data->cpld_lock); + return len; +} +static DEVICE_ATTR_RO(version); + + +static ssize_t getreg_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + // CPLD register is one byte + 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; + // CPLD register is one byte + 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) +{ + // CPLD register is one byte + 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. + * @return number of byte read. + */ +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/1k/4k + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer for get value + * @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 ? "4k" : data ==0x01 ? "1k": "on"); +} + +/** + * Set the status of system led - on/off/1k/4k + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer of set value + * @param count number of bytes in buffer + * @return number of bytes written, or error code < 0. + */ +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, "4k")){ + led_status = 0x02; + }else if(sysfs_streq(buf, "1k")){ + 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 + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer for get value + * @return Hex string read from scratch register. + */ +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 + * When both color is selected, only blink 1K or 4K is supported. + * + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer of set value + * @param count number of bytes in buffer + * @return number of bytes written, or error code < 0. + */ +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 struct attribute *cpld_b_attrs[] = { + &dev_attr_version.attr, + &dev_attr_scratch.attr, + &dev_attr_getreg.attr, + &dev_attr_setreg.attr, + &dev_attr_sys_led.attr, + &dev_attr_sys_led_color.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 = 0xA175, + .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("Pradchaya P. "); +MODULE_DESCRIPTION("Celestica Phalanxp CPLD baseboard driver"); +MODULE_VERSION("0.0.2"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/jaws/modules/dimm-bus.c b/platform/broadcom/sonic-platform-modules-cel/jaws/modules/dimm-bus.c new file mode 100644 index 000000000000..9f30945e1d1c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/jaws/modules/dimm-bus.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2016 Andrew Lutomirski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include "dimm-bus.h" +static bool probe_addr(struct i2c_adapter *adapter, int addr) +{ + /* + * So far, all known devices that live on DIMMs can be safely + * and reliably detected by trying to read a byte at address + * zero. (The exception is the SPD write protection control, + * which can't be probed and requires special hardware and/or + * quick writes to access, and has no driver.) + */ + union i2c_smbus_data dummy; + return i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_READ, 0, + I2C_SMBUS_BYTE_DATA, &dummy) >= 0; +} +/** + * i2c_scan_dimm_bus() - Scans an SMBUS segment known to contain DIMMs + * @adapter: The SMBUS adapter to scan + * + * This function tells the DIMM-bus code that the adapter is known to + * contain DIMMs. i2c_scan_dimm_bus will probe for devices known to + * live on DIMMs. + * + * Do NOT call this function on general-purpose system SMBUS segments + * unless you know that the only things on the bus are DIMMs. + * Otherwise is it very likely to mis-identify other things on the + * bus. + * + * Callers are advised not to set adapter->class = I2C_CLASS_SPD to + * avoid having two separate mechanisms trying to automatically claim + * devices on the bus. + */ +void i2c_scan_dimm_bus(struct i2c_adapter *adapter) +{ + struct i2c_board_info info = {}; + int slot; + /* + * We probe with "read byte data". If any DIMM SMBUS driver can't + * support that access type, this function should be updated. + */ + if (WARN_ON(!i2c_check_functionality(adapter, + I2C_FUNC_SMBUS_READ_BYTE_DATA))) + return; + /* + * Addresses on DIMMs use the three low bits to identify the slot + * and the four high bits to identify the device type. Known + * devices include: + * + * - 0x10 - 0x17: NVDIMM controller (pre-standard) + * - 0x18 - 0x1f: TSOD (Temperature Sensor on DIMM) + * - 0x40 - 0x47: JESD245 Byte Addressable Energy Backed Interface + * - 0x50 - 0x57: SPD (Serial Presence Detect) EEPROM + * - 0x30 - 0x37: SPD WP control -- not easy to probe + * + * There's no point in trying to probe the SPD WP control: we'd + * want to probe using quick reads, which i2c-imc doesn't + * support, we don't have a driver for it, we can't really use + * it without special hardware (it's not a normal i2c slave -- + * see the JEDEC docs), and using it risks bricking the DIMM + * it's on anyway. + * + * NB: There's no need to save the return value from + * i2c_new_device, as the core code will unregister it for us + * when the adapter is removed. If users want to bind a + * different driver, nothing stops them from unbinding the + * drivers we request here. + */ + for (slot = 0; slot < 8; slot++) { + /* If there's no SPD, then assume there's no DIMM here. */ + if (!probe_addr(adapter, 0x50 | slot)) + continue; + strcpy(info.type, "ee1004"); + info.addr = 0x50 | slot; + i2c_new_device(adapter, &info); + if (probe_addr(adapter, 0x18 | slot)) { + /* + * This is a temperature sensor. The interface is + * defined in the JEDEC TSE2004av specification. + * Linux's driver for this is called "jc42", which + * is a bit nonsensical (JC-42 is the name of the + * committee, not the sensor). + */ + strcpy(info.type, "jc42"); + info.addr = 0x18 | slot; + i2c_new_device(adapter, &info); + } + } +} +EXPORT_SYMBOL(i2c_scan_dimm_bus); +MODULE_AUTHOR("Andrew Lutomirski "); +MODULE_DESCRIPTION("i2c DIMM bus support"); +MODULE_LICENSE("GPL v2"); + diff --git a/platform/broadcom/sonic-platform-modules-cel/jaws/modules/dimm-bus.h b/platform/broadcom/sonic-platform-modules-cel/jaws/modules/dimm-bus.h new file mode 100644 index 000000000000..8f14d5fb973f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/jaws/modules/dimm-bus.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2013-2016 Andrew Lutomirski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef _I2C_DIMM_BUS +#define _I2C_DIMM_BUS +struct i2c_adapter; +void i2c_scan_dimm_bus(struct i2c_adapter *adapter); +#endif /* _I2C_DIMM_BUS */ + diff --git a/platform/broadcom/sonic-platform-modules-cel/jaws/modules/i2c-imc.c b/platform/broadcom/sonic-platform-modules-cel/jaws/modules/i2c-imc.c new file mode 100644 index 000000000000..7b053f43916e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/jaws/modules/i2c-imc.c @@ -0,0 +1,556 @@ +/* + * Copyright (c) 2013-2016 Andrew Lutomirski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include "dimm-bus.h" + +/* + * The datasheet can be found here, for example: + * http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/xeon-e5-1600-2600-vol-2-datasheet.pdf + * + * There seem to be quite a few bugs or spec errors, though: + * + * - A successful transaction sets WOD and RDO. + * + * - The docs for TSOD_POLL_EN make no sense (see imc_channel_claim). + * + * - Erratum BT109, which says: + * + * The processor may not complete SMBus (System Management Bus) + * transactions targeting the TSOD (Temperature Sensor On DIMM) + * when Package C-States are enabled. Due to this erratum, if the + * processor transitions into a Package C-State while an SMBus + * transaction with the TSOD is in process, the processor will + * suspend receipt of the transaction. The transaction completes + * while the processor is in a Package C-State. Upon exiting + * Package C-State, the processor will attempt to resume the + * SMBus transaction, detect a protocol violation, and log an + * error. + * + * The description notwithstanding, I've seen difficult-to-reproduce + * issues when the system goes completely idle (so package C-states can + * be entered) while software-initiated SMBUS transactions are in + * progress. + */ + +/* Register offsets (in PCI configuration space) */ +#define SMBSTAT(i) (0x180 + 0x10*(i)) +#define SMBCMD(i) (0x184 + 0x10*(i)) +#define SMBCNTL(i) (0x188 + 0x10*(i)) +#define SMB_TSOD_POLL_RATE_CNTR(i) (0x18C + 0x10*(i)) +#define SMB_TSOD_POLL_RATE (0x1A8) + +/* SMBSTAT fields */ +#define SMBSTAT_RDO (1U << 31) /* Read Data Valid */ +#define SMBSTAT_WOD (1U << 30) /* Write Operation Done */ +#define SMBSTAT_SBE (1U << 29) /* SMBus Error */ +#define SMBSTAT_SMB_BUSY (1U << 28) /* SMBus Busy State */ +/* 26:24 is the last automatically polled TSOD address */ +#define SMBSTAT_RDATA_MASK 0xffff /* result of a read */ + +/* SMBCMD fields */ +#define SMBCMD_TRIGGER (1U << 31) /* CMD Trigger */ +#define SMBCMD_PNTR_SEL (1U << 30) /* HW polls TSOD with pointer */ +#define SMBCMD_WORD_ACCESS (1U << 29) /* word (vs byte) access */ +#define SMBCMD_TYPE_MASK (3U << 27) /* Mask for access type */ +#define SMBCMD_TYPE_READ (0U << 27) /* Read */ +#define SMBCMD_TYPE_WRITE (1U << 27) /* Write */ +#define SMBCMD_TYPE_PNTR_WRITE (3U << 27) /* Write to pointer */ +#define SMBCMD_SA_MASK (7U << 24) /* Slave Address high bits */ +#define SMBCMD_SA_SHIFT 24 +#define SMBCMD_BA_MASK 0xff0000 /* Bus Txn address */ +#define SMBCMD_BA_SHIFT 16 +#define SMBCMD_WDATA_MASK 0xffff /* data to write */ + +/* SMBCNTL fields */ +#define SMBCNTL_DTI_MASK 0xf0000000 /* Slave Address low bits */ +#define SMBCNTL_DTI_SHIFT 28 /* Slave Address low bits */ +#define SMBCNTL_CKOVRD (1U << 27) /* # Clock Override */ +#define SMBCNTL_DIS_WRT (1U << 26) /* Disable Write (sadly) */ +#define SMBCNTL_SOFT_RST (1U << 10) /* Soft Reset */ +#define SMBCNTL_TSOD_POLL_EN (1U << 8) /* TSOD Polling Enable */ +/* Bits 0-3 and 4-6 indicate TSOD presence in various slots */ + +/* Bits that might randomly change if we race with something. */ +#define SMBCMD_OUR_BITS (~(u32)SMBCMD_TRIGGER) +#define SMBCNTL_OUR_BITS (SMBCNTL_DTI_MASK | SMBCNTL_TSOD_POLL_EN) + +/* System Address Controller, PCI dev 13 fn 6, 8086.3cf5 */ +#define SAD_CONTROL 0xf4 + +#define PCI_DEVICE_ID_INTEL_SBRIDGE_BR 0x3cf5 /* 13.6 */ +#define PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TA 0x3ca8 /* 15.0 */ + +#define PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TA 0x6fa8 +#define PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TM 0x6f71 +#define PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA1_TA 0x6f68 +#define PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA1_TM 0x6f79 + +static atomic_t imc_raced; /* Set permanently to 1 if we screw up. */ + +static bool allow_unsafe_access; + +struct imc_channel { + struct i2c_adapter adapter; + struct mutex mutex; /* protects access to regs and prev_tsod_poll */ + bool can_write, suspended; + bool prev_tsod_poll; +}; + +struct imc_priv { + struct pci_dev *pci_dev; + struct imc_channel channels[2]; +}; + +static bool imc_wait_not_busy(struct imc_priv *priv, int chan, u32 *stat) +{ + /* + * The clock is around 100kHz, and transactions are nine cycles + * per byte plus a few start/stop cycles, plus whatever clock + * streching is involved. This means that polling every 70us + * or so will give decent performance. + * + * Ideally we would calculate a good estimate for the + * transaction time and sleep, but busy-waiting is an effective + * workaround for an apparent Sandy Bridge bug that causes bogus + * output if the system enters a package C-state. (NB: these + * states are systemwide -- we don't need be running on the + * right package for this to work.) + * + * When Ivy Bridge and Haswell support are added, we could + * consider making the busy-wait depend on the platform. + */ + + int i; + + for (i = 0; i < 50; i++) { + pci_read_config_dword(priv->pci_dev, SMBSTAT(chan), stat); + if (!(*stat & SMBSTAT_SMB_BUSY)) + return true; + udelay(70); /* see comment above -- we need to busy-wait */ + } + + return false; +} + +static void imc_channel_release(struct imc_priv *priv, int chan) +{ + /* Return to HW control. */ + if (priv->channels[chan].prev_tsod_poll) { + u32 cntl; + + pci_read_config_dword(priv->pci_dev, SMBCNTL(chan), &cntl); + cntl |= SMBCNTL_TSOD_POLL_EN; + pci_write_config_dword(priv->pci_dev, SMBCNTL(chan), cntl); + } +} + +static int imc_channel_claim(struct imc_priv *priv, int chan) +{ + /* + * The docs are a bit confused here. We're supposed to disable TSOD + * polling, then wait for busy to be cleared, then set + * SMBCNTL_TSOD_POLL_EN to zero to switch to software control. But + * SMBCNTL_TSOD_POLL_EN is the only documented way to turn off polling. + */ + + u32 cntl, stat; + + if (priv->channels[chan].suspended) + return -EIO; + + pci_read_config_dword(priv->pci_dev, SMBCNTL(chan), &cntl); + priv->channels[chan].prev_tsod_poll = !!(cntl & SMBCNTL_TSOD_POLL_EN); + cntl &= ~SMBCNTL_TSOD_POLL_EN; + pci_write_config_dword(priv->pci_dev, SMBCNTL(chan), cntl); + + /* Sometimes the hardware won't let go. */ + pci_read_config_dword(priv->pci_dev, SMBCNTL(chan), &cntl); + if (cntl & SMBCNTL_TSOD_POLL_EN) + return -EBUSY; + + if (!imc_wait_not_busy(priv, chan, &stat)) { + imc_channel_release(priv, chan); + return -EBUSY; /* Someone else is controlling the bus. */ + } + + return 0; /* The channel is ours. */ +} + +static bool imc_channel_can_claim(struct imc_priv *priv, int chan) +{ + u32 orig_cntl, cntl; + + /* See if we can turn off TSOD_POLL_EN. */ + + pci_read_config_dword(priv->pci_dev, SMBCNTL(chan), &orig_cntl); + pci_write_config_dword(priv->pci_dev, SMBCNTL(chan), + orig_cntl & ~SMBCNTL_TSOD_POLL_EN); + + pci_read_config_dword(priv->pci_dev, SMBCNTL(chan), &cntl); + if (cntl & SMBCNTL_TSOD_POLL_EN) + return false; /* Failed. */ + + pci_write_config_dword(priv->pci_dev, SMBCNTL(chan), orig_cntl); + return true; +} + +/* + * The iMC supports five access types. The terminology is rather + * inconsistent. These are the types: + * + * "Write to pointer register SMBus": I2C_SMBUS_WRITE, I2C_SMBUS_BYTE + * + * Read byte/word: I2C_SMBUS_READ, I2C_SMBUS_{BYTE|WORD}_DATA + * + * Write byte/word: I2C_SMBUS_WRITE, I2C_SMBUS_{BYTE|WORD}_DATA + * + * The pointer write operations is AFAICT completely useless for + * software control, for two reasons. First, HW periodically polls any + * TSODs on the bus, so it will corrupt the pointer in between SW + * transactions. More importantly, the matching "read byte"/"receive + * byte" (the address-less single-byte read) is not available for SW + * control. Therefore, this driver doesn't implement pointer writes + * + * There is no PEC support. + */ + +static u32 imc_func(struct i2c_adapter *adapter) +{ + int chan; + struct imc_channel *ch; + struct imc_priv *priv = i2c_get_adapdata(adapter); + + chan = (adapter == &priv->channels[0].adapter ? 0 : 1); + ch = &priv->channels[chan]; + + if (ch->can_write) + return I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA; + else + return I2C_FUNC_SMBUS_READ_BYTE_DATA | + I2C_FUNC_SMBUS_READ_WORD_DATA; +} + +static s32 imc_smbus_xfer(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, u8 command, + int size, union i2c_smbus_data *data) +{ + int ret, chan; + u32 cmd = 0, cntl, final_cmd, final_cntl, stat; + struct imc_channel *ch; + struct imc_priv *priv = i2c_get_adapdata(adap); + + if (atomic_read(&imc_raced)) + return -EIO; /* Minimize damage. */ + + chan = (adap == &priv->channels[0].adapter ? 0 : 1); + ch = &priv->channels[chan]; + + /* Encode CMD part of addresses and access size */ + cmd |= ((u32)addr & 0x7) << SMBCMD_SA_SHIFT; + cmd |= ((u32)command) << SMBCMD_BA_SHIFT; + if (size == I2C_SMBUS_WORD_DATA) + cmd |= SMBCMD_WORD_ACCESS; + + /* Encode read/write and data to write */ + if (read_write == I2C_SMBUS_READ) { + cmd |= SMBCMD_TYPE_READ; + } else { + cmd |= SMBCMD_TYPE_WRITE; + cmd |= (size == I2C_SMBUS_WORD_DATA + ? swab16(data->word) + : data->byte); + } + + mutex_lock(&ch->mutex); + + ret = imc_channel_claim(priv, chan); + if (ret) + goto out_unlock; + + pci_read_config_dword(priv->pci_dev, SMBCNTL(chan), &cntl); + cntl &= ~SMBCNTL_DTI_MASK; + cntl |= ((u32)addr >> 3) << SMBCNTL_DTI_SHIFT; + pci_write_config_dword(priv->pci_dev, SMBCNTL(chan), cntl); + + /* + * This clears SMBCMD_PNTR_SEL. We leave it cleared so that we don't + * need to think about keeping the TSOD pointer state consistent with + * the hardware's expectation. This probably has some miniscule + * power cost, as TSOD polls will take 9 extra cycles. + */ + cmd |= SMBCMD_TRIGGER; + pci_write_config_dword(priv->pci_dev, SMBCMD(chan), cmd); + + if (!imc_wait_not_busy(priv, chan, &stat)) { + /* Timeout. TODO: Reset the controller? */ + ret = -ETIMEDOUT; + dev_dbg(&priv->pci_dev->dev, "controller is wedged\n"); + goto out_release; + } + + /* + * Be paranoid: try to detect races. This will only detect races + * against BIOS, not against hardware. (I've never seen this happen.) + */ + pci_read_config_dword(priv->pci_dev, SMBCMD(chan), &final_cmd); + pci_read_config_dword(priv->pci_dev, SMBCNTL(chan), &final_cntl); + if (((cmd ^ final_cmd) & SMBCMD_OUR_BITS) || + ((cntl ^ final_cntl) & SMBCNTL_OUR_BITS)) { + WARN(1, "iMC SMBUS raced against firmware"); + dev_err(&priv->pci_dev->dev, + "Access to channel %d raced: cmd 0x%08X->0x%08X, cntl 0x%08X->0x%08X\n", + chan, cmd, final_cmd, cntl, final_cntl); + atomic_set(&imc_raced, 1); + ret = -EIO; + goto out_release; + } + + if (stat & SMBSTAT_SBE) { + /* + * Clear the error to re-enable TSOD polling. The docs say + * that, as long as SBE is set, TSOD polling won't happen. + * The docs also say that writing zero to this bit (which is + * the only writable bit in the whole register) will clear + * the error. Empirically, writing 0 does not clear SBE, but + * it's probably still good to do the write in compliance with + * the spec. (TSOD polling still happens and seems to + * clear SBE on its own.) + */ + pci_write_config_dword(priv->pci_dev, SMBSTAT(chan), 0); + ret = -ENXIO; + goto out_release; + } + + if (read_write == I2C_SMBUS_READ) { + if (!(stat & SMBSTAT_RDO)) { + dev_dbg(&priv->pci_dev->dev, + "Unexpected read status 0x%08X\n", stat); + ret = -EIO; + goto out_release; + } + + /* + * The iMC SMBUS controller thinks of SMBUS words as + * being big-endian (MSB first). Linux treats them as + * little-endian, so we need to swap them. + * + * Note: the controller will often (always?) set WOD + * here. This is probably a hardware bug. + */ + if (size == I2C_SMBUS_WORD_DATA) + data->word = swab16(stat & SMBSTAT_RDATA_MASK); + else + data->byte = stat & 0xFF; + } else { + /* + * Note: the controller will often (always?) set RDO here. + * This is probably a hardware bug. + */ + if (!(stat & SMBSTAT_WOD)) { + dev_dbg(&priv->pci_dev->dev, + "Unexpected write status 0x%08X\n", stat); + ret = -EIO; + } + } + +out_release: + imc_channel_release(priv, chan); + +out_unlock: + mutex_unlock(&ch->mutex); + + return ret; +} + +static const struct i2c_algorithm imc_smbus_algorithm = { + .smbus_xfer = imc_smbus_xfer, + .functionality = imc_func, +}; + +static int imc_init_channel(struct imc_priv *priv, int i, int socket) +{ + int err; + u32 val; + struct imc_channel *ch = &priv->channels[i]; + + /* + * With CLTT enabled, the hardware won't let us turn + * off TSOD polling. The device is completely useless + * when this happens (at least without help from Intel), + * but we can at least minimize confusion. + */ + if (!imc_channel_can_claim(priv, i)) { + dev_warn(&priv->pci_dev->dev, + "iMC channel %d: we cannot control the HW. Is CLTT on?\n", + i); + return -EBUSY; + } + + i2c_set_adapdata(&ch->adapter, priv); + ch->adapter.owner = THIS_MODULE; + ch->adapter.algo = &imc_smbus_algorithm; + ch->adapter.dev.parent = &priv->pci_dev->dev; + + pci_read_config_dword(priv->pci_dev, SMBCNTL(i), &val); + ch->can_write = !(val & SMBCNTL_DIS_WRT); + + mutex_init(&ch->mutex); + + snprintf(ch->adapter.name, sizeof(ch->adapter.name), + "iMC socket %d channel %d", socket, i); + err = i2c_add_adapter(&ch->adapter); + if (err) { + mutex_destroy(&ch->mutex); + return err; + } + + i2c_scan_dimm_bus(&ch->adapter); + + return 0; +} + +static void imc_free_channel(struct imc_priv *priv, int i) +{ + struct imc_channel *ch = &priv->channels[i]; + + i2c_del_adapter(&ch->adapter); + mutex_destroy(&ch->mutex); +} + +static struct pci_dev *imc_get_related_device(struct pci_bus *bus, + unsigned int devfn, u16 devid) +{ + struct pci_dev *dev = pci_get_slot(bus, devfn); + + if (!dev) + return NULL; + if (dev->vendor != PCI_VENDOR_ID_INTEL || dev->device != devid) { + pci_dev_put(dev); + return NULL; + } + return dev; +} + +static int imc_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + int i, j, err; + struct imc_priv *priv; + + priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + priv->pci_dev = dev; + + pci_set_drvdata(dev, priv); + + for (i = 0; i < 1; i++) { + err = imc_init_channel(priv, i, 0); + if (err) + goto exit_free_channels; + printk(KERN_INFO "IMC: Create IMC SMBus OK.\n"); + } + + return 0; + +exit_free_channels: + printk(KERN_INFO "IMC: Free chennel I2C.\n"); + for (j = 0; j < i; j++) + imc_free_channel(priv, j); + return err; +} + +static void imc_remove(struct pci_dev *dev) +{ + int i; + struct imc_priv *priv = pci_get_drvdata(dev); + + for (i = 0; i < 1; i++) + imc_free_channel(priv, i); +} + +static int imc_suspend(struct pci_dev *dev, pm_message_t mesg) +{ + int i; + struct imc_priv *priv = pci_get_drvdata(dev); + + /* BIOS is in charge. We should finish any pending transaction */ + for (i = 0; i < 1; i++) { + mutex_lock(&priv->channels[i].mutex); + priv->channels[i].suspended = true; + mutex_unlock(&priv->channels[i].mutex); + } + + return 0; +} + +static int imc_resume(struct pci_dev *dev) +{ + int i; + struct imc_priv *priv = pci_get_drvdata(dev); + + for (i = 0; i < 1; i++) { + mutex_lock(&priv->channels[i].mutex); + priv->channels[i].suspended = false; + mutex_unlock(&priv->channels[i].mutex); + } + + return 0; +} + +static const struct pci_device_id imc_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TA) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TA) }, + { 0, } +}; +MODULE_DEVICE_TABLE(pci, imc_ids); + +static struct pci_driver imc_pci_driver = { + .name = "imc_smbus", + .id_table = imc_ids, + .probe = imc_probe, + .remove = imc_remove, + .suspend = imc_suspend, + .resume = imc_resume, +}; + +static int __init i2c_imc_init(void) +{ + if (!allow_unsafe_access) + return -ENODEV; + + pr_warn("using this driver is dangerous unless your firmware is specifically designed for it; use at your own risk\n"); + return pci_register_driver(&imc_pci_driver); +} +module_init(i2c_imc_init); + +static void __exit i2c_imc_exit(void) +{ + pci_unregister_driver(&imc_pci_driver); +} +module_exit(i2c_imc_exit); + +module_param(allow_unsafe_access, bool, 0400); +MODULE_PARM_DESC(allow_unsafe_access, "enable i2c_imc despite potential races against BIOS/hardware bus access"); + +MODULE_AUTHOR("Andrew Lutomirski "); +MODULE_DESCRIPTION("iMC SMBus driver"); +MODULE_LICENSE("GPL v2"); + diff --git a/platform/broadcom/sonic-platform-modules-cel/jaws/modules/mc24lc64t.c b/platform/broadcom/sonic-platform-modules-cel/jaws/modules/mc24lc64t.c new file mode 100644 index 000000000000..ae79770a4d8e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/jaws/modules/mc24lc64t.c @@ -0,0 +1,173 @@ +/* + * 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; + 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"); diff --git a/platform/broadcom/sonic-platform-modules-cel/jaws/modules/switchboard_fpga.c b/platform/broadcom/sonic-platform-modules-cel/jaws/modules/switchboard_fpga.c new file mode 100644 index 000000000000..13afba861088 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/jaws/modules/switchboard_fpga.c @@ -0,0 +1,2997 @@ +/* + * switchboard.c - Driver for Phalanxp Switch 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 + * \--AS23128h.switchboard + * |--FPGA + * |--CPLD[1..4] + * \--SFF + * \--QSFP[1..128] + * + */ + +#ifndef TEST_MODE +#define MOD_VERSION "0.5.1" +#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 "phalanxp_fpga" +#define DRIVER_NAME "AS14128H.switchboard" +#define FPGA_PCI_NAME "phalanxp_fpga_pci" +#define DEVICE_NAME "fwupgrade" + +static bool allow_unsafe_i2c_access; + +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 i2c_core_init(unsigned int master_bus, unsigned int freq_div,void __iomem *pci_bar); +static void i2c_core_deinit(unsigned int master_bus, void __iomem *pci_bar); +static int i2c_xcvr_access(u8 register_address, unsigned int portid, u8 *data, char rw); + +static int fpgafw_init(void); +static void fpgafw_exit(void); + +/* +======================================== +FPGA PCIe BAR 0 Registers +======================================== +Misc Control 0x00000000 – 0x000000FF +I2C_CH1 0x00000800 - 0x0000081C +I2C_CH2 0x00000820 - 0x0000083C +I2C_CH3 0x00000840 - 0x0000085C +I2C_CH4 0x00000860 - 0x0000087C +I2C_CH5 0x00000880 - 0x0000089C +I2C_CH6 0x000008A0 - 0x000008BC +I2C_CH7 0x000008C0 - 0x000008DC +I2C_CH8 0x000008E0 - 0x000008FC +I2C_CH9 0x00000900 - 0x0000091C +I2C_CH10 0x00000920 - 0x0000093C +I2C_CH11 0x00000940 - 0x0000095C +I2C_CH12 0x00000960 - 0x0000097C +I2C_CH13 0x00000980 - 0x0000099C +I2C_CH14 0x000009A0 - 0x000009BC +SPI Master 0x00000A00 - 0x00000BFC +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 BMC_I2C_SCRATCH 0x0020 +#define FPGA_SLAVE_CPLD_REST 0x0100 +#define FPGA_SWITCH_RESET_CTRL 0x0104 +#define FPAG_PRH_RESER_CTRL 0x0108 +#define FPGA_INT_STATUS 0x0200 +#define FPGA_INT_SRC_STATUS 0x0204 +#define FPGA_INT_FLAG 0x0208 +#define FPGA_INT_MASK 0x020c +#define FPGA_MISC_CTRL 0x0300 +#define FPGA_MISC_STATUS 0x0304 + +/* I2C_MASTER BASE ADDR */ +#define I2C_MASTER_FREQ_L 0x0800 +#define I2C_MASTER_FREQ_H 0x0804 +#define I2C_MASTER_CTRL 0x0808 +#define I2C_MASTER_DATA 0x080c +#define I2C_MASTER_CMD 0x0810 /* Write-Only Register */ +#define I2C_MASTER_STATUS 0x0810 /* Read-Only Register */ +#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_14 14 + +#define I2C_MASTER_CH_TOTAL I2C_MASTER_CH_14 + +/* 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] RSVD +[5] MODSEL 5 +[4] RST 4 +[3:1] RSVD +[0] TXDIS 0 +*/ +#define CTRL_MODSEL 5 +#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 + + +/** + * Switchboard CPLD XCVR registers + */ + +/* PORT SEL REGISTER +[7:5] RSVD +[4:0] ID +*/ +#define I2C_XCVR_SEL 0x10 +#define I2C_SEL_ID 0 + +/* PORT CTRL REGISTER +[7:5] RSVD +[4] RST +[3:1] RSVD +[0] TXDIS/MODSEL +*/ +#define I2C_XCVR_CTRL 0x11 +#define I2C_CTRL_RST 4 +#define I2C_CTRL_MODSEL 0 +#define I2C_CTRL_TXDIS 0 + +/* PORT STATUS REGISTER +[7:5] RSVD +[4] PRESENT/ABS +[3:2] RSVD +[1] TXFAULT +[0] RXLOS/INT_N +*/ +#define I2C_XCVR_STAT 0x12 +#define I2C_STAT_PRESENT 4 +#define I2C_STAT_MODABS 4 +#define I2C_STAT_TXFAULT 1 +#define I2C_STAT_INT_N 0 +#define I2C_STAT_RXLOS 0 + +/* PORT INTRPT REGISTER +[7:5] RSVD +[4] PRESENT/ABS +[3:2] RSVD +[1] TXFAULT +[0] RXLOS/INT_N +*/ +#define I2C_XCVR_INRT 0x13 +#define I2C_INTR_PRESENT 4 +#define I2C_INTR_MODABS 4 +#define I2C_INTR_TXFAULT 1 +#define I2C_INTR_INT_N 0 +#define I2C_INTR_RXLOS 0 + +/* PORT INTR MASK REGISTER +[31:6] RSVD +[5] INT_N 5 +[4] PRESENT 4 +[3] RSVD +[2] RSVD +[1] RXLOS_INT 1 +[0] MODABS 0 +*/ +#define I2C_XCVR_MASK 0x14 +#define I2C_MASK_PRESENT 4 +#define I2C_MASK_MODABS 4 +#define I2C_MASK_TXFAULT 1 +#define I2C_MASK_INT_N 0 +#define I2C_MASK_RXLOS 0 + + +/* I2C master clock speed */ +// NOTE: Only I2C clock in normal mode is support here. +enum { + I2C_DIV_100K = 0x71, +}; + +/* I2C Master control register */ +enum { + I2C_CTRL_IEN = 6, + I2C_CTRL_EN +}; + +/* I2C Master command register */ +enum { + I2C_CMD_IACK = 0, + I2C_CMD_ACK = 3, + I2C_CMD_WR, + I2C_CMD_RD, + I2C_CMD_STO, + I2C_CMD_STA, +}; + +/* I2C Master status register */ +enum { + I2C_STAT_IF = 0, + I2C_STAT_TIP, + I2C_STAT_AL = 5, + I2C_STAT_BUSY, + I2C_STAT_RxACK, +}; + +/** + * + * 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_SFP_PORT 0 +#define VIRTUAL_I2C_QSFP_PORT 128 + +#define SFF_PORT_TOTAL VIRTUAL_I2C_QSFP_PORT + VIRTUAL_I2C_SFP_PORT + +#define VIRTUAL_I2C_BUS_OFFSET 10 +#define BB_CPLD_SLAVE_ADDR 0x0d +#define FAN_CPLD_SLAVE_ADDR 0x0d +#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 + +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]; +static int nack_retry[I2C_MASTER_CH_TOTAL]; +static int need_retry[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[] = { + /* SFP and QSFP front panel I2C */ + {I2C_MASTER_CH_11, 0x70, 0, QSFP, "QSFP1"}, {I2C_MASTER_CH_11, 0x70, 1, QSFP, "QSFP2"}, + {I2C_MASTER_CH_11, 0x70, 2, QSFP, "QSFP3"}, {I2C_MASTER_CH_11, 0x70, 3, QSFP, "QSFP4"}, + {I2C_MASTER_CH_14, 0x73, 7, QSFP, "QSFP5"}, {I2C_MASTER_CH_14, 0x73, 6, QSFP, "QSFP6"}, + {I2C_MASTER_CH_14, 0x73, 5, QSFP, "QSFP7"}, {I2C_MASTER_CH_14, 0x73, 4, QSFP, "QSFP8"}, + {I2C_MASTER_CH_11, 0x70, 4, QSFP, "QSFP9"}, {I2C_MASTER_CH_11, 0x70, 5, QSFP, "QSFP10"}, + {I2C_MASTER_CH_11, 0x70, 6, QSFP, "QSFP11"}, {I2C_MASTER_CH_11, 0x70, 7, QSFP, "QSFP12"}, + {I2C_MASTER_CH_14, 0x73, 3, QSFP, "QSFP13"}, {I2C_MASTER_CH_14, 0x73, 2, QSFP, "QSFP14"}, + {I2C_MASTER_CH_14, 0x73, 1, QSFP, "QSFP15"}, {I2C_MASTER_CH_14, 0x73, 0, QSFP, "QSFP16"}, + + {I2C_MASTER_CH_11, 0x71, 0, QSFP, "QSFP17"}, {I2C_MASTER_CH_11, 0x71, 1, QSFP, "QSFP18"}, + {I2C_MASTER_CH_11, 0x71, 2, QSFP, "QSFP19"}, {I2C_MASTER_CH_11, 0x71, 3, QSFP, "QSFP20"}, + {I2C_MASTER_CH_14, 0x72, 7, QSFP, "QSFP21"}, {I2C_MASTER_CH_14, 0x72, 6, QSFP, "QSFP22"}, + {I2C_MASTER_CH_14, 0x72, 5, QSFP, "QSFP23"}, {I2C_MASTER_CH_14, 0x72, 4, QSFP, "QSFP24"}, + {I2C_MASTER_CH_11, 0x71, 4, QSFP, "QSFP25"}, {I2C_MASTER_CH_11, 0x71, 5, QSFP, "QSFP26"}, + {I2C_MASTER_CH_11, 0x71, 6, QSFP, "QSFP27"}, {I2C_MASTER_CH_11, 0x71, 7, QSFP, "QSFP28"}, + {I2C_MASTER_CH_14, 0x72, 3, QSFP, "QSFP29"}, {I2C_MASTER_CH_14, 0x72, 2, QSFP, "QSFP30"}, + {I2C_MASTER_CH_14, 0x72, 1, QSFP, "QSFP31"}, {I2C_MASTER_CH_14, 0x72, 0, QSFP, "QSFP32"}, + + {I2C_MASTER_CH_11, 0x72, 0, QSFP, "QSFP33"}, {I2C_MASTER_CH_11, 0x72, 1, QSFP, "QSFP34"}, + {I2C_MASTER_CH_11, 0x72, 2, QSFP, "QSFP35"}, {I2C_MASTER_CH_11, 0x72, 3, QSFP, "QSFP36"}, + {I2C_MASTER_CH_14, 0x71, 7, QSFP, "QSFP37"}, {I2C_MASTER_CH_14, 0x71, 6, QSFP, "QSFP38"}, + {I2C_MASTER_CH_14, 0x71, 5, QSFP, "QSFP39"}, {I2C_MASTER_CH_14, 0x71, 4, QSFP, "QSFP40"}, + {I2C_MASTER_CH_11, 0x72, 4, QSFP, "QSFP41"}, {I2C_MASTER_CH_11, 0x72, 5, QSFP, "QSFP42"}, + {I2C_MASTER_CH_11, 0x72, 6, QSFP, "QSFP43"}, {I2C_MASTER_CH_11, 0x72, 7, QSFP, "QSFP44"}, + {I2C_MASTER_CH_14, 0x71, 3, QSFP, "QSFP45"}, {I2C_MASTER_CH_14, 0x71, 2, QSFP, "QSFP46"}, + {I2C_MASTER_CH_14, 0x71, 1, QSFP, "QSFP47"}, {I2C_MASTER_CH_14, 0x71, 0, QSFP, "QSFP48"}, + + {I2C_MASTER_CH_11, 0x73, 0, QSFP, "QSFP49"}, {I2C_MASTER_CH_11, 0x73, 1, QSFP, "QSFP50"}, + {I2C_MASTER_CH_11, 0x73, 2, QSFP, "QSFP51"}, {I2C_MASTER_CH_11, 0x73, 3, QSFP, "QSFP52"}, + {I2C_MASTER_CH_14, 0x70, 7, QSFP, "QSFP53"}, {I2C_MASTER_CH_14, 0x70, 6, QSFP, "QSFP54"}, + {I2C_MASTER_CH_14, 0x70, 5, QSFP, "QSFP55"}, {I2C_MASTER_CH_14, 0x70, 4, QSFP, "QSFP56"}, + {I2C_MASTER_CH_11, 0x73, 4, QSFP, "QSFP57"}, {I2C_MASTER_CH_11, 0x73, 5, QSFP, "QSFP58"}, + {I2C_MASTER_CH_11, 0x73, 6, QSFP, "QSFP59"}, {I2C_MASTER_CH_11, 0x73, 7, QSFP, "QSFP60"}, + {I2C_MASTER_CH_14, 0x70, 3, QSFP, "QSFP61"}, {I2C_MASTER_CH_14, 0x70, 2, QSFP, "QSFP62"}, + {I2C_MASTER_CH_14, 0x70, 1, QSFP, "QSFP63"}, {I2C_MASTER_CH_14, 0x70, 0, QSFP, "QSFP64"}, + + {I2C_MASTER_CH_12, 0x70, 0, QSFP, "QSFP65"}, {I2C_MASTER_CH_12, 0x70, 1, QSFP, "QSFP66"}, + {I2C_MASTER_CH_12, 0x70, 2, QSFP, "QSFP67"}, {I2C_MASTER_CH_12, 0x70, 3, QSFP, "QSFP68"}, + {I2C_MASTER_CH_13, 0x73, 7, QSFP, "QSFP69"}, {I2C_MASTER_CH_13, 0x73, 6, QSFP, "QSFP70"}, + {I2C_MASTER_CH_13, 0x73, 5, QSFP, "QSFP71"}, {I2C_MASTER_CH_13, 0x73, 4, QSFP, "QSFP72"}, + {I2C_MASTER_CH_12, 0x70, 4, QSFP, "QSFP73"}, {I2C_MASTER_CH_12, 0x70, 5, QSFP, "QSFP74"}, + {I2C_MASTER_CH_12, 0x70, 6, QSFP, "QSFP75"}, {I2C_MASTER_CH_12, 0x70, 7, QSFP, "QSFP76"}, + {I2C_MASTER_CH_13, 0x73, 3, QSFP, "QSFP77"}, {I2C_MASTER_CH_13, 0x73, 2, QSFP, "QSFP78"}, + {I2C_MASTER_CH_13, 0x73, 1, QSFP, "QSFP79"}, {I2C_MASTER_CH_13, 0x73, 0, QSFP, "QSFP80"}, + + {I2C_MASTER_CH_12, 0x71, 0, QSFP, "QSFP81"}, {I2C_MASTER_CH_12, 0x71, 1, QSFP, "QSFP82"}, + {I2C_MASTER_CH_12, 0x71, 2, QSFP, "QSFP83"}, {I2C_MASTER_CH_12, 0x71, 3, QSFP, "QSFP84"}, + {I2C_MASTER_CH_13, 0x72, 7, QSFP, "QSFP85"}, {I2C_MASTER_CH_13, 0x72, 6, QSFP, "QSFP86"}, + {I2C_MASTER_CH_13, 0x72, 5, QSFP, "QSFP87"}, {I2C_MASTER_CH_13, 0x72, 4, QSFP, "QSFP88"}, + {I2C_MASTER_CH_12, 0x71, 4, QSFP, "QSFP89"}, {I2C_MASTER_CH_12, 0x71, 5, QSFP, "QSFP90"}, + {I2C_MASTER_CH_12, 0x71, 6, QSFP, "QSFP91"}, {I2C_MASTER_CH_12, 0x71, 7, QSFP, "QSFP92"}, + {I2C_MASTER_CH_13, 0x72, 3, QSFP, "QSFP93"}, {I2C_MASTER_CH_13, 0x72, 2, QSFP, "QSFP94"}, + {I2C_MASTER_CH_13, 0x72, 1, QSFP, "QSFP95"}, {I2C_MASTER_CH_13, 0x72, 0, QSFP, "QSFP96"}, + + {I2C_MASTER_CH_12, 0x72, 0, QSFP, "QSFP97"}, {I2C_MASTER_CH_12, 0x72, 1, QSFP, "QSFP98"}, + {I2C_MASTER_CH_12, 0x72, 2, QSFP, "QSFP99"}, {I2C_MASTER_CH_12, 0x72, 3, QSFP, "QSFP100"}, + {I2C_MASTER_CH_13, 0x71, 7, QSFP, "QSFP101"}, {I2C_MASTER_CH_13, 0x71, 6, QSFP, "QSFP102"}, + {I2C_MASTER_CH_13, 0x71, 5, QSFP, "QSFP103"}, {I2C_MASTER_CH_13, 0x71, 4, QSFP, "QSFP104"}, + {I2C_MASTER_CH_12, 0x72, 4, QSFP, "QSFP105"}, {I2C_MASTER_CH_12, 0x72, 5, QSFP, "QSFP106"}, + {I2C_MASTER_CH_12, 0x72, 6, QSFP, "QSFP107"}, {I2C_MASTER_CH_12, 0x72, 7, QSFP, "QSFP108"}, + {I2C_MASTER_CH_13, 0x71, 3, QSFP, "QSFP109"}, {I2C_MASTER_CH_13, 0x71, 2, QSFP, "QSFP110"}, + {I2C_MASTER_CH_13, 0x71, 1, QSFP, "QSFP111"}, {I2C_MASTER_CH_13, 0x71, 0, QSFP, "QSFP112"}, + + {I2C_MASTER_CH_12, 0x73, 0, QSFP, "QSFP113"}, {I2C_MASTER_CH_12, 0x73, 1, QSFP, "QSFP114"}, + {I2C_MASTER_CH_12, 0x73, 2, QSFP, "QSFP115"}, {I2C_MASTER_CH_12, 0x73, 3, QSFP, "QSFP116"}, + {I2C_MASTER_CH_13, 0x70, 7, QSFP, "QSFP117"}, {I2C_MASTER_CH_13, 0x70, 6, QSFP, "QSFP118"}, + {I2C_MASTER_CH_13, 0x70, 5, QSFP, "QSFP119"}, {I2C_MASTER_CH_13, 0x70, 4, QSFP, "QSFP120"}, + {I2C_MASTER_CH_12, 0x73, 4, QSFP, "QSFP121"}, {I2C_MASTER_CH_12, 0x73, 5, QSFP, "QSFP122"}, + {I2C_MASTER_CH_12, 0x73, 6, QSFP, "QSFP123"}, {I2C_MASTER_CH_12, 0x73, 7, QSFP, "QSFP124"}, + {I2C_MASTER_CH_13, 0x70, 3, QSFP, "QSFP125"}, {I2C_MASTER_CH_13, 0x70, 2, QSFP, "QSFP126"}, + {I2C_MASTER_CH_13, 0x70, 1, QSFP, "QSFP127"}, {I2C_MASTER_CH_13, 0x70, 0, QSFP, "QSFP128"}, + + /* Vritual I2C adapters */ + {I2C_MASTER_CH_1, 0xFF, 0, NONE, "I2C_1"}, // FAN + {I2C_MASTER_CH_2, 0xFF, 0, NONE, "I2C_2"}, + {I2C_MASTER_CH_3, 0xFF, 0, NONE, "I2C_3"}, + {I2C_MASTER_CH_4, 0xFF, 0, NONE, "I2C_4"}, + {I2C_MASTER_CH_5, 0xFF, 0, NONE, "I2C_5"}, // BB + {I2C_MASTER_CH_6, 0xFF, 0, NONE, "I2C_6"}, + {I2C_MASTER_CH_7, 0xFF, 0, NONE, "I2C_7"}, // SW[1-2] + {I2C_MASTER_CH_8, 0xFF, 0, NONE, "I2C_8"}, // SW[3-4] + + // NOTE: Buses below are for front panel port debug + {I2C_MASTER_CH_11, 0xFF, 0, NONE, "I2C_11"}, + {I2C_MASTER_CH_12, 0xFF, 0, NONE, "I2C_12"}, + {I2C_MASTER_CH_13, 0xFF, 0, NONE, "I2C_13"}, + {I2C_MASTER_CH_14, 0xFF, 0, NONE, "I2C_14"}, +}; + +#define VIRTUAL_I2C_PORT_LENGTH ARRAY_SIZE(fpga_i2c_bus_dev) +#define FAN_I2C_CPLD_INDEX SFF_PORT_TOTAL +#define BB_I2C_CPLD_INDEX SFF_PORT_TOTAL + 4 +#define SW1_I2C_CPLD_INDEX SFF_PORT_TOTAL + 6 +#define SW2_I2C_CPLD_INDEX SFF_PORT_TOTAL + 7 + +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 phalanxp_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; + uint8_t cpld3_read_addr; + uint8_t cpld4_read_addr; + uint8_t fancpld_read_addr; +}; + +struct sff_device_data { + int portid; + enum PORT_TYPE port_type; +}; + +struct phalanxp_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; +static struct kobject *cpld3 = NULL; +static struct kobject *cpld4 = NULL; +static struct kobject *fancpld = NULL; + +/** + * Device node in sysfs tree. + */ +static struct device *sff_dev = NULL; + +/** + * 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; +} + +/* 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 struct attribute *fpga_attrs[] = { + &dev_attr_getreg.attr, + &dev_attr_scratch.attr, + &dev_attr_setreg.attr, + NULL, +}; + +static struct attribute_group fpga_attr_grp = { + .attrs = fpga_attrs, +}; + +/* 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[SW1_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[SW1_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[SW1_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[SW1_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_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_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[SW1_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[SW1_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[SW1_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[SW1_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_getreg.attr, + &dev_attr_cpld2_scratch.attr, + &dev_attr_cpld2_setreg.attr, + NULL, +}; + +static struct attribute_group cpld2_attr_grp = { + .attrs = cpld2_attrs, +}; + +static ssize_t cpld3_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[SW2_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, fpga_data->cpld3_read_addr, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t cpld3_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->cpld3_read_addr = addr; + return size; +} +struct device_attribute dev_attr_cpld3_getreg = __ATTR(getreg, 0600, cpld3_getreg_show, cpld3_getreg_store); + +static ssize_t cpld3_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[SW2_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 cpld3_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[SW2_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_cpld3_scratch = __ATTR(scratch, 0600, cpld3_scratch_show, cpld3_scratch_store); + +static ssize_t cpld3_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[SW2_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_cpld3_setreg = __ATTR(setreg, 0200, NULL, cpld3_setreg_store); + +static struct attribute *cpld3_attrs[] = { + &dev_attr_cpld3_getreg.attr, + &dev_attr_cpld3_scratch.attr, + &dev_attr_cpld3_setreg.attr, + NULL, +}; + +static struct attribute_group cpld3_attr_grp = { + .attrs = cpld3_attrs, +}; + +static ssize_t cpld4_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[SW2_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, fpga_data->cpld4_read_addr, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t cpld4_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->cpld4_read_addr = addr; + return size; +} +struct device_attribute dev_attr_cpld4_getreg = __ATTR(getreg, 0600, cpld4_getreg_show, cpld4_getreg_store); + +static ssize_t cpld4_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[SW2_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 cpld4_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[SW2_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_cpld4_scratch = __ATTR(scratch, 0600, cpld4_scratch_show, cpld4_scratch_store); + +static ssize_t cpld4_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[SW2_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_cpld4_setreg = __ATTR(setreg, 0200, NULL, cpld4_setreg_store); + +static struct attribute *cpld4_attrs[] = { + &dev_attr_cpld4_getreg.attr, + &dev_attr_cpld4_scratch.attr, + &dev_attr_cpld4_setreg.attr, + NULL, +}; + +static struct attribute_group cpld4_attr_grp = { + .attrs = cpld4_attrs, +}; + +/* FAN CPLD */ +static ssize_t fancpld_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[FAN_I2C_CPLD_INDEX], FAN_CPLD_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, fpga_data->fancpld_read_addr, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + return sprintf(buf, "0x%2.2x\n", data); +} +static ssize_t fancpld_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->fancpld_read_addr = addr; + return size; +} +struct device_attribute dev_attr_fancpld_getreg = __ATTR(getreg, 0600, fancpld_getreg_show, fancpld_getreg_store); + +static ssize_t fancpld_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[FAN_I2C_CPLD_INDEX], FAN_CPLD_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x04, 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 fancpld_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[FAN_I2C_CPLD_INDEX], FAN_CPLD_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, 0x04, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) + return err; + return size; +} +struct device_attribute dev_attr_fancpld_scratch = __ATTR(scratch, 0600, fancpld_scratch_show, fancpld_scratch_store); + +static ssize_t fancpld_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[FAN_I2C_CPLD_INDEX], FAN_CPLD_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_fancpld_setreg = __ATTR(setreg, 0200, NULL, fancpld_setreg_store); + +static struct attribute *fancpld_attrs[] = { + &dev_attr_fancpld_getreg.attr, + &dev_attr_fancpld_scratch.attr, + &dev_attr_fancpld_setreg.attr, + NULL, +}; + +static struct attribute_group fancpld_attr_grp = { + .attrs = fancpld_attrs, +}; + +static struct attribute *fancpld_no_attrs[] = { + NULL, +}; + +static struct attribute_group fancpld_no_attr_grp = { + .attrs = fancpld_no_attrs, +}; + +/* QSFP/SFP+ attributes */ +static ssize_t qsfp_modirq_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 data; + int err; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + err = i2c_xcvr_access(I2C_XCVR_STAT,portid,&data,I2C_SMBUS_READ); + if(err < 0){ + return err; + } + return sprintf(buf, "%d\n", (data >> I2C_STAT_INT_N) & 1U); +} +DEVICE_ATTR_RO(qsfp_modirq); + +static ssize_t qsfp_modprs_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 data; + int err; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + err = i2c_xcvr_access(I2C_XCVR_STAT,portid,&data,I2C_SMBUS_READ); + if(err < 0){ + return err; + } + return sprintf(buf, "%d\n", (data >> I2C_STAT_MODABS) & 1U); +} +DEVICE_ATTR_RO(qsfp_modprs); + +static ssize_t sfp_txfault_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 data; + int err; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + err = i2c_xcvr_access(I2C_XCVR_STAT,portid,&data,I2C_SMBUS_READ); + if(err < 0){ + return err; + } + return sprintf(buf, "%d\n", (data >> I2C_STAT_TXFAULT) & 1U); +} +DEVICE_ATTR_RO(sfp_txfault); + +static ssize_t sfp_rxlos_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 data; + int err; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + err = i2c_xcvr_access(I2C_XCVR_STAT,portid,&data,I2C_SMBUS_READ); + if(err < 0){ + return err; + } + return sprintf(buf, "%d\n", (data >> I2C_STAT_RXLOS) & 1U); +} +DEVICE_ATTR_RO(sfp_rxlos); + +static ssize_t sfp_modabs_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 data; + int err; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + err = i2c_xcvr_access(I2C_XCVR_STAT,portid,&data,I2C_SMBUS_READ); + if(err < 0){ + return err; + } + return sprintf(buf, "%d\n", (data >> I2C_STAT_MODABS) & 1U); +} +DEVICE_ATTR_RO(sfp_modabs); + +static ssize_t qsfp_modsel_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 data; + int err; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + err = i2c_xcvr_access(I2C_XCVR_CTRL,portid,&data,I2C_SMBUS_READ); + if(err < 0){ + return err; + } + return sprintf(buf, "%d\n", (data >> I2C_CTRL_MODSEL) & 1U); +} +static ssize_t qsfp_modsel_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + ssize_t status; + long value; + u8 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + + status = kstrtol(buf, 0, &value); + if (status == 0) { + // if value is 0, clear bit. + i2c_xcvr_access(I2C_XCVR_CTRL,portid,&data,I2C_SMBUS_READ); + if (!value) + data = data & ~( 1U << I2C_CTRL_MODSEL ); + else + data = data | ( 1U << I2C_CTRL_MODSEL ); + i2c_xcvr_access(I2C_XCVR_CTRL,portid,&data,I2C_SMBUS_WRITE); + status = size; + } + return status; +} +DEVICE_ATTR_RW(qsfp_modsel); + +static ssize_t qsfp_reset_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 data; + int err; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + err = i2c_xcvr_access(I2C_XCVR_CTRL,portid,&data,I2C_SMBUS_READ); + if(err < 0){ + return err; + } + return sprintf(buf, "%d\n", (data >> I2C_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; + u8 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + + status = kstrtol(buf, 0, &value); + if (status == 0) { + // if value is 0, reset signal is low + i2c_xcvr_access(I2C_XCVR_CTRL,portid,&data,I2C_SMBUS_READ); + if (!value) + data = data & ~((u8)0x1 << I2C_CTRL_RST); + else + data = data | ((u8)0x1 << I2C_CTRL_RST); + i2c_xcvr_access(I2C_XCVR_CTRL,portid,&data,I2C_SMBUS_WRITE); + status = size; + } + return status; +} +DEVICE_ATTR_RW(qsfp_reset); + +static ssize_t sfp_txdisable_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 data; + int err; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + err = i2c_xcvr_access(I2C_XCVR_CTRL,portid,&data,I2C_SMBUS_READ); + if(err < 0){ + return err; + } + return sprintf(buf, "%d\n", (data >> I2C_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; + u8 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtol(buf, 0, &value); + if (status == 0) { + // check if value is 0 clear + i2c_xcvr_access(I2C_XCVR_CTRL,portid,&data,I2C_SMBUS_READ); + if (!value) + data = data & ~((u8)0x1 << I2C_CTRL_TXDIS); + else + data = data | ((u8)0x1 << I2C_CTRL_TXDIS); + i2c_xcvr_access(I2C_XCVR_CTRL,portid,&data,I2C_SMBUS_WRITE); + 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_modsel.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, led_mode_3, led_mode_4; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW1_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[SW1_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; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW2_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_3); + if (err < 0) + return err; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW2_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_4); + if (err < 0) + return err; + return sprintf(buf, "%s %s %s %s\n", + led_mode_1 ? "test" : "normal", + led_mode_2 ? "test" : "normal", + led_mode_3 ? "test" : "normal", + led_mode_4 ? "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[SW1_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[SW1_I2C_CPLD_INDEX], CPLD2_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[SW2_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[SW2_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 green/amber/both/alt-blink/OFF + __u8 led_color1, led_color2, led_color3, led_color4; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW1_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[SW1_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; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW2_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_color3); + if (err < 0) + return err; + err = fpga_i2c_access(fpga_data->i2c_adapter[SW2_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_color4); + if (err < 0) + return err; + return sprintf(buf, "%s %s %s %s\n", + led_color1 == 0x07 ? "off" : led_color1 == 0x06 ? "green" : led_color1 == 0x05 ? "amber" : led_color1 == 0x04 ? + "both" : "alt-blink", + led_color1 == 0x07 ? "off" : led_color1 == 0x06 ? "green" : led_color1 == 0x05 ? "amber" : led_color1 == 0x04 ? + "both" : "alt-blink", + led_color1 == 0x07 ? "off" : led_color1 == 0x06 ? "green" : led_color1 == 0x05 ? "amber" : led_color1 == 0x04 ? + "both" : "alt-blink", + led_color1 == 0x07 ? "off" : led_color1 == 0x06 ? "green" : led_color1 == 0x05 ? "amber" : led_color1 == 0x04 ? + "both" : "alt-blink"); +} + +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, "amber")) { + led_color = 0x05; + } else if (sysfs_streq(buf, "both")) { + led_color = 0x04; + } else if (sysfs_streq(buf, "alt-blink")) { + led_color = 0x03; + } else { + status = -EINVAL; + return status; + } + status = fpga_i2c_access(fpga_data->i2c_adapter[SW1_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[SW1_I2C_CPLD_INDEX], CPLD2_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[SW2_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[SW2_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 * phalanxp_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_core_init(unsigned int master_bus, unsigned int freq_div,void __iomem *pci_bar){ + + unsigned int ctrl; + unsigned int REG_FREQ_L; + unsigned int REG_FREQ_H; + unsigned int REG_CTRL; + unsigned int REG_CMD; + + REG_FREQ_L = I2C_MASTER_FREQ_L + (master_bus - 1) * 0x20; + REG_FREQ_H = I2C_MASTER_FREQ_H + (master_bus - 1) * 0x20; + REG_CTRL = I2C_MASTER_CTRL + (master_bus - 1) * 0x20; + REG_CMD = I2C_MASTER_CMD + (master_bus - 1) * 0x20; + + if ( freq_div != I2C_DIV_100K ) { + printk(KERN_ERR "FPGA I2C core: Unsupported clock divider: %x\n", freq_div); + return -EINVAL; + } + + // Makes sure core is disable + ctrl = ioread8(pci_bar + REG_CTRL); + iowrite8( ctrl & ~(1 << I2C_CTRL_EN | 1 << I2C_CTRL_IEN), pci_bar + REG_CTRL); + + iowrite8( freq_div & 0xFF , pci_bar + REG_FREQ_L); + iowrite8( freq_div >> 8, pci_bar + REG_FREQ_H); + + /* Only enable EN bit, we only use polling mode */ + iowrite8(1 << I2C_CMD_IACK, pci_bar + REG_CMD); + iowrite8(1 << I2C_CTRL_EN, pci_bar + REG_CTRL); + + return 0; +} + +static void i2c_core_deinit(unsigned int master_bus,void __iomem *pci_bar){ + + unsigned int REG_CTRL; + REG_CTRL = I2C_MASTER_CTRL + (master_bus - 1) * 0x20; + // Disable core + iowrite8( ioread8(pci_bar + REG_CTRL) & ~(1 << I2C_CTRL_EN| 1 << I2C_CTRL_IEN), pci_bar + REG_CTRL); +} + +/** + * We have 2 line cards and each with 2 cplds here. + * Each line card have 64 ports. Each cpld manage 32 ports. + * protid start from 1. + * +---+------------------+------------------+ + * |LC1|1 CPLD1 57|65 CPLD2 121| + * | |4 60|68 124| + * +---+------------------+------------------+ + * |LC2|5 CPLD1 61|69 CPLD2 125| + * | |8 64|72 128| + * +---+------------------+------------------+ + */ +static int i2c_xcvr_access(u8 register_address, unsigned int portid, u8 *data, char rw){ + + u16 dev_addr = 0; + int err; + int lci, cpldi, i2c_adapter_index; + int row, col; + + /* check for portid valid length */ + if(portid < 1 || portid > SFF_PORT_TOTAL){ + return -EINVAL; + } + + lci = ( portid -1 ) % 8; + cpldi = (portid -1 ) / 8; + + /* Normalize the port xposition into 4 x 8 metric. + * Then calculate the cpld's port index from matrix. + */ + row = (portid -1 ) % 4; + col = (portid -1 ) / 8; + + // Line card select top/buttom + if( lci < 4 ){ + i2c_adapter_index = SW1_I2C_CPLD_INDEX; + }else{ + i2c_adapter_index = SW2_I2C_CPLD_INDEX; + } + + // CPLD select left/right + if( cpldi < 8 ){ + dev_addr = CPLD1_SLAVE_ADDR; + }else{ + col -= 8; + dev_addr = CPLD2_SLAVE_ADDR; + } + + // Calculate cpld portid + portid = ( 4 * col ) + row + 1; + + // Select port + err = fpga_i2c_access(fpga_data->i2c_adapter[i2c_adapter_index], dev_addr, 0x00, I2C_SMBUS_WRITE, + I2C_XCVR_SEL, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&portid); + if(err < 0){ + return err; + } + // Read/write port xcvr register + err = fpga_i2c_access(fpga_data->i2c_adapter[i2c_adapter_index], dev_addr, 0x00, rw, + register_address , I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)data); + if(err < 0){ + return err; + } + return 0; +} + +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_FREQ_L; + unsigned int REG_FREQ_H; + unsigned int REG_CMD; + unsigned int REG_CTRL; + unsigned int REG_STAT; + unsigned int REG_DATA; + + 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_FREQ_L = I2C_MASTER_FREQ_L + (master_bus - 1) * 0x20; + REG_FREQ_H = I2C_MASTER_FREQ_H + (master_bus - 1) * 0x20; + REG_CTRL = I2C_MASTER_CTRL + (master_bus - 1) * 0x20; + REG_CMD = I2C_MASTER_CMD + (master_bus - 1) * 0x20; + REG_STAT = I2C_MASTER_STATUS + (master_bus - 1) * 0x20; + REG_DATA = I2C_MASTER_DATA + (master_bus - 1) * 0x20; + + check(pci_bar + REG_STAT); + check(pci_bar + REG_CTRL); + + /* + * We wait for the data to be transferred (8bit), + * then we start polling on the ACK/NACK bit + * udelay((8 * 1000) / 100); + */ + udelay(80); + dev_dbg(&a->dev,"Wait for 0x%2.2X\n", 1 << I2C_STAT_TIP); + + timeout = jiffies + msecs_to_jiffies(timeout); + while (1) { + Status = ioread8(pci_bar + REG_STAT); + dev_dbg(&a->dev, "ST:%2.2X\n", Status); + + /* Wait for the TIP bit to be cleared before timeout */ + if ( (Status & ( 1 << I2C_STAT_TIP )) == 0 ) { + dev_dbg(&a->dev, " TIP cleared:0x%2.2X\n", Status); + break; + } + + if (time_after(jiffies, timeout)) { + info("Status %2.2X", Status); + info("Error Timeout"); + error = -ETIMEDOUT; + break; + } + + cpu_relax(); + cond_resched(); + } + info("Status %2.2X", Status); + info("STA:%x",Status); + + if (error < 0) { + dev_dbg(&a->dev, "%s TIMEOUT bit 0x%x not clear in specific time\n", + __func__, (1 << I2C_STAT_TIP)); + return error; + } + + /** There is only one master in each bus. If this error happen something is + * not normal in i2c transfer refer to: + * https://www.i2c-bus.org/i2c-primer/analysing-obscure-problems/master-reports-arbitration-lost + */ + // Arbitration lost + if (Status & (1 << I2C_STAT_AL)) { + info("Error arbitration lost"); + nack_retry[master_bus - 1] = 1; + return -EBUSY; + } + + // Ack not received + if (Status & (1 << I2C_STAT_RxACK)) { + info( "SL No ACK"); + if (writing) { + info("Error No ACK"); + nack_retry[master_bus - 1] = 1; + return -EIO; + } + } else { + info( "SL ACK"); + } + + return error; +} + +static int i2c_wait_stop(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_FREQ_L; + unsigned int REG_FREQ_H; + unsigned int REG_CMD; + unsigned int REG_CTRL; + unsigned int REG_STAT; + unsigned int REG_DATA; + + 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_FREQ_L = I2C_MASTER_FREQ_L + (master_bus - 1) * 0x20; + REG_FREQ_H = I2C_MASTER_FREQ_H + (master_bus - 1) * 0x20; + REG_CTRL = I2C_MASTER_CTRL + (master_bus - 1) * 0x20; + REG_CMD = I2C_MASTER_CMD + (master_bus - 1) * 0x20; + REG_STAT = I2C_MASTER_STATUS + (master_bus - 1) * 0x20; + REG_DATA = I2C_MASTER_DATA + (master_bus - 1) * 0x20; + + check(pci_bar + REG_STAT); + check(pci_bar + REG_CTRL); + + dev_dbg(&a->dev,"Wait for 0x%2.2X\n", 1 << I2C_STAT_BUSY); + timeout = jiffies + msecs_to_jiffies(timeout); + while (1) { + Status = ioread8(pci_bar + REG_STAT); + dev_dbg(&a->dev, "ST:%2.2X\n", Status); + if (time_after(jiffies, timeout)) { + info("Status %2.2X", Status); + info("Error Timeout"); + error = -ETIMEDOUT; + break; + } + + /* Wait for the BUSY bit to be cleared before timeout */ + if ( (Status & ( 1 << I2C_STAT_BUSY )) == 0 ) { + dev_dbg(&a->dev, " BUSY cleared:0x%2.2X\n", Status); + break; + } + + cpu_relax(); + cond_resched(); + } + info("Status %2.2X", Status); + info("STA:%x",Status); + + if (error < 0) { + dev_dbg(&a->dev, "%s TIMEOUT bit 0x%x not clear in specific time\n", + __func__, (1 << I2C_STAT_BUSY)); + return error; + } + return 0; +} + +/* SMBUS Xfer for opencore I2C with polling */ +// TODO: Change smbus_xfer to master_xfer - This will support i2c and all smbus emu functions. +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; + int error_stop = 0; + + unsigned int REG_FREQ_L; + unsigned int REG_FREQ_H; + unsigned int REG_CMD; + unsigned int REG_CTRL; + unsigned int REG_STAT; + unsigned int REG_DATA; + + REG_FREQ_L = 0; + REG_FREQ_H = 0; + REG_CTRL = 0; + REG_CMD = 0; + REG_STAT = 0; + REG_DATA = 0; + + /* Write the command register */ + dev_data = i2c_get_adapdata(adapter); + portid = dev_data->portid; + pci_bar = fpga_dev.data_base_addr; + +#ifdef DEBUG_KERN + printk(KERN_INFO "portid %2d|@ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-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" : + size == 8 ? "I2C_BLOCK_DATA" : "ERROR" + , cmd); +#endif + + master_bus = dev_data->pca9548.master_bus; + error = i2c_core_init(master_bus, I2C_DIV_100K, fpga_dev.data_base_addr); + + /* Map the size to what the chip understands */ + switch (size) { + case I2C_SMBUS_QUICK: + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + case I2C_SMBUS_WORD_DATA: + case I2C_SMBUS_BLOCK_DATA: + case I2C_SMBUS_I2C_BLOCK_DATA: + break; + default: + printk(KERN_INFO "Unsupported transaction %d\n", size); + error = -EOPNOTSUPP; + goto Done; + } + + master_bus = dev_data->pca9548.master_bus; + + if (master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL) { + error = -EINVAL; + goto Done; + } + + REG_FREQ_L = I2C_MASTER_FREQ_L + (master_bus - 1) * 0x20; + REG_FREQ_H = I2C_MASTER_FREQ_H + (master_bus - 1) * 0x20; + REG_CTRL = I2C_MASTER_CTRL + (master_bus - 1) * 0x20; + REG_CMD = I2C_MASTER_CMD + (master_bus - 1) * 0x20; + REG_STAT = I2C_MASTER_STATUS + (master_bus - 1) * 0x20; + REG_DATA = I2C_MASTER_DATA + (master_bus - 1) * 0x20; + + ////[S][ADDR/R] + 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_DATA); + } else { + // sent device address with Write mode + iowrite8( (addr << 1) & 0xFE, pci_bar + REG_DATA); + } + iowrite8( 1 << I2C_CMD_STA | 1 << I2C_CMD_WR | 1 << I2C_CMD_IACK, pci_bar + REG_CMD); + + info( "MS Start"); + + //// Wait {A} + // + IACK + error = i2c_wait_ack(adapter, 30, 1); + if (error < 0) { + info( "get error %d", error); + dev_dbg(&adapter->dev,"START Error: %d\n", error); + goto Done; + } + + //// [CMD]{A} + if (size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA || + size == I2C_SMBUS_I2C_BLOCK_DATA || + (size == I2C_SMBUS_BYTE && rw == I2C_SMBUS_WRITE)) { + + // sent command code to data register + iowrite8(cmd, pci_bar + REG_DATA); + // Start the transfer + iowrite8(1 << I2C_CMD_WR | 1 << I2C_CMD_IACK, pci_bar + REG_CMD); + info( "MS Send CMD 0x%2.2X", cmd); + + // Wait {A} + // IACK + error = i2c_wait_ack(adapter, 30, 1); + if (error < 0) { + info( "get error %d", error); + dev_dbg(&adapter->dev,"CMD Error: %d\n", 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: + case I2C_SMBUS_I2C_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 block data write + if (size == I2C_SMBUS_BLOCK_DATA && rw == I2C_SMBUS_WRITE) { + + iowrite8(cnt, pci_bar + REG_DATA); + //Start the transfer + iowrite8(1 << I2C_CMD_WR | 1 << I2C_CMD_IACK, pci_bar + REG_CMD); + info( "MS Send CNT 0x%2.2X", cnt); + + // Wait {A} + // IACK + error = i2c_wait_ack(adapter, 30, 1); + if (error < 0) { + info( "get error %d", error); + dev_dbg(&adapter->dev,"CNT Error: %d\n", 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 || + size == I2C_SMBUS_I2C_BLOCK_DATA + )) { + int bid = 0; + info( "MS prepare to sent [%d bytes]", cnt); + if (size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA) { + bid = 1; // block[0] is cnt; + cnt += 1; // offset from block[0] + } + for (; bid < cnt; bid++) { + info("STA:%x", ioread8(pci_bar + REG_STAT) ); + info( " Data > %2.2X", data->block[bid]); + iowrite8(data->block[bid], pci_bar + REG_DATA); + iowrite8(1 << I2C_CMD_WR | 1 << I2C_CMD_IACK, pci_bar + REG_CMD); + + // Wait {A} + // IACK + error = i2c_wait_ack(adapter, 30, 1); + if (error < 0) { + dev_dbg(&adapter->dev,"Send DATA Error: %d\n", error); + goto Done; + } + } + } + + //REPEATE START + if ( rw == I2C_SMBUS_READ && ( + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA || + size == I2C_SMBUS_I2C_BLOCK_DATA + )) { + info( "MS Repeated Start"); + + // sent Address with Read mode + iowrite8( addr << 1 | 0x1 , pci_bar + REG_DATA); + // SET START | WRITE + iowrite8( 1 << I2C_CMD_STA | 1 << I2C_CMD_WR | 1 << I2C_CMD_IACK, pci_bar + REG_CMD); + + // Wait {A} + error = i2c_wait_ack(adapter, 30, 1); + if (error < 0) { + dev_dbg(&adapter->dev,"Repeat START Error: %d\n", error); + 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 || + size == I2C_SMBUS_I2C_BLOCK_DATA + )) { + + switch (size) { + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + cnt = 1; break; + case I2C_SMBUS_WORD_DATA: + cnt = 2; break; + case I2C_SMBUS_BLOCK_DATA: + /* will be changed after recived first data */ + cnt = 3; break; + case I2C_SMBUS_I2C_BLOCK_DATA: + cnt = data->block[0]; break; + default: + cnt = 0; break; + } + + info( "MS Receive"); + + for (bid = 0; bid < cnt; bid++) { + + // Start receive FSM + if (bid == cnt - 1) { + info( "READ NACK"); + iowrite8(1 << I2C_CMD_RD | 1 << I2C_CMD_ACK | 1 << I2C_CMD_IACK, pci_bar + REG_CMD); + }else{ + + iowrite8(1 << I2C_CMD_RD, pci_bar + REG_CMD); + } + + // Wait {A} + error = i2c_wait_ack(adapter, 30, 0); + if(nack_retry[master_bus - 1] == 1) + { + need_retry[master_bus - 1] = 1; + } + if (error < 0) { + dev_dbg(&adapter->dev,"Receive DATA Error: %d\n", error); + goto Done; + } + if(size == I2C_SMBUS_I2C_BLOCK_DATA){ + /* block[0] is read length */ + data->block[bid+1] = ioread8(pci_bar + REG_DATA); + info( "DATA IN [%d] %2.2X", bid+1, data->block[bid+1]); + }else { + data->block[bid] = ioread8(pci_bar + REG_DATA); + info( "DATA IN [%d] %2.2X", bid, data->block[bid]); + } + if (size == I2C_SMBUS_BLOCK_DATA && bid == 0) { + cnt = data->block[0] + 1; + } + } + } + +Done: + info( "MS STOP"); + // SET STOP + iowrite8( 1 << I2C_CMD_STO | 1 << I2C_CMD_IACK, pci_bar + REG_CMD); + // Wait for the STO to finish. + error_stop = i2c_wait_stop(adapter, 30, 0); + if (error_stop < 0) { + dev_dbg(&adapter->dev,"STOP Error: %d\n", error_stop); + } + check(pci_bar + REG_CTRL); + check(pci_bar + REG_STAT); +#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, retval = 0; + struct i2c_dev_data *dev_data; + unsigned char master_bus; + unsigned char switch_addr; + unsigned char channel; + unsigned char *calling_name; + uint16_t prev_port = 0; + unsigned char prev_switch; + unsigned char prev_ch; + uint8_t read_channel; + int retry = 0; + + 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; + calling_name = dev_data->pca9548.calling_name; + + // 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 + // Only select new channel of a switch if they are difference from last channel of a switch + 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", prev_ch, prev_switch, error); + } + + } + if(retry < 0){ + goto release_unlock; + } + // update lasted port + fpga_i2c_lasted_access_port[master_bus - 1] = switch_addr << 8 | channel; + + } 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", prev_ch, prev_switch, error); + } + + } + if(retry < 0){ + goto release_unlock; + } + // update lasted port + fpga_i2c_lasted_access_port[master_bus - 1] = switch_addr << 8 | channel; + } + } + } + + // Do SMBus communication + nack_retry[master_bus - 1] = 0; + need_retry[master_bus - 1] = 0; + error = smbus_access(adapter, addr, flags, rw, cmd, size, data); + if((nack_retry[master_bus - 1]==1)&&(need_retry[master_bus - 1]==1)) + retry = 2000; + else + retry = 5; + // If the first access failed, do retry. + while((nack_retry[master_bus - 1]==1)&&retry) + { + retry--; + nack_retry[master_bus - 1] = 0; + dev_dbg(&adapter->dev,"error = %d\n",error); + error = smbus_access(adapter, addr, flags, rw, cmd, size, data); + dev_dbg(&adapter->dev,"nack retry = %d\n",retry); + } + nack_retry[master_bus - 1] = 0; + need_retry[master_bus - 1] = 0; + + retval = error; + + 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); + }else{ + goto release_unlock; + } + + /** For the bus with PCA9548, try to read PCA9548 one more time. + * For the bus w/o PCA9548 just check the return from last time. + */ + if (switch_addr != 0xFF) { + error = smbus_access(adapter, switch_addr, flags, I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE, (union i2c_smbus_data*)&read_channel); + dev_dbg(&adapter->dev,"Try access I2C switch device at %2.2x\n", switch_addr); + if(error < 0){ + dev_dbg(&adapter->dev,"Unbale to access switch device.\n"); + }else{ + dev_dbg(&adapter->dev,"Read success, register val %2.2x\n", read_channel); + } + } + + // If retry was used up(retry = 0) and the last transfer result is -EBUSY + if(retry <= 0 && error == -EBUSY ){ + retval = error; + // raise device error message + dev_err(&adapter->dev, "I2C bus hangup detected on %s port.\n", calling_name); + + /** + * Phalanxp: Device specific I2C reset topology + */ + if( master_bus == I2C_MASTER_CH_11 || master_bus == I2C_MASTER_CH_12 || + master_bus == I2C_MASTER_CH_13 || master_bus == I2C_MASTER_CH_14 ){ + dev_notice(&adapter->dev, "Trying bus recovery...\n"); + dev_notice(&adapter->dev, "Reset I2C switch device.\n"); + + // reset PCA9548 on the current BUS. + if(master_bus == I2C_MASTER_CH_11){ + // LC1_I2C3_RST_N .. LC1_I2C0_RST_N + iowrite8( ioread8(fpga_dev.data_base_addr + 0x0108) & 0xF0, fpga_dev.data_base_addr + 0x0108); + udelay(1); + iowrite8( ioread8(fpga_dev.data_base_addr + 0x0108) | 0x0F, fpga_dev.data_base_addr + 0x0108); + }else if(master_bus == I2C_MASTER_CH_12){ + // LC1_I2C7_RST_N .. LC1_I2C4_RST_N + iowrite8( ioread8(fpga_dev.data_base_addr + 0x0108) & 0x8F, fpga_dev.data_base_addr + 0x0108); + udelay(1); + iowrite8( ioread8(fpga_dev.data_base_addr + 0x0108) | 0x70, fpga_dev.data_base_addr + 0x0108); + }else if(master_bus == I2C_MASTER_CH_13){ + // LC2_I2C3_RST_N .. LC2_I2C0_RST_N + iowrite8( ioread8(fpga_dev.data_base_addr + 0x010c) & 0xF0, fpga_dev.data_base_addr + 0x010c); + udelay(1); + iowrite8( ioread8(fpga_dev.data_base_addr + 0x010c) | 0x0F, fpga_dev.data_base_addr + 0x010c); + }else if(master_bus == I2C_MASTER_CH_14){ + // LC2_I2C7_RST_N .. LC2_I2C4_RST_N + iowrite8( ioread8(fpga_dev.data_base_addr + 0x010c) & 0x8F, fpga_dev.data_base_addr + 0x010c); + udelay(1); + iowrite8( ioread8(fpga_dev.data_base_addr + 0x010c) | 0x70, fpga_dev.data_base_addr + 0x010c); + } + // clear the last access port + fpga_i2c_lasted_access_port[master_bus - 1] = 0; + }else{ + dev_crit(&adapter->dev, "I2C bus unrecoverable.\n"); + } + } + + +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 retval; +} + +/** + * 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| + I2C_FUNC_SMBUS_I2C_BLOCK; +} + +static const struct i2c_algorithm phalanxp_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 * phalanxp_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; + + 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 = &phalanxp_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_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; +}; + +// I/O resource need. +static struct resource phalanxp_resources[] = { + { + .start = 0x10000000, + .end = 0x10001000, + .flags = IORESOURCE_MEM, + }, +}; + +static void phalanxp_dev_release( struct device * dev) +{ + return; +} + +static struct platform_device phalanxp_dev = { + .name = DRIVER_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(phalanxp_resources), + .resource = phalanxp_resources, + .dev = { + .release = phalanxp_dev_release, + } +}; + +/** + * Board info for QSFP/SFP+ eeprom. + * Note: Using OOM optoe as transceiver 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 phalanxp_drv_probe(struct platform_device *pdev) +{ + struct resource *res; + int ret = 0; + int portid_count; + uint8_t cpld1_version, cpld2_version, cpld3_version, cpld4_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 phalanxp_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]); + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (unlikely(!res)) { + printk(KERN_ERR "Specified Resource Not Available...\n"); + kzfree(fpga_data); + return -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; + } + + cpld3 = kobject_create_and_add("CPLD3", &pdev->dev.kobj); + if (!cpld3) { + 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 -ENOMEM; + } + ret = sysfs_create_group(cpld3, &cpld3_attr_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create CPLD3 sysfs attributes\n"); + kobject_put(cpld3); + 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; + } + + cpld4 = kobject_create_and_add("CPLD4", &pdev->dev.kobj); + if (!cpld4) { + sysfs_remove_group(cpld3, &cpld3_attr_grp); + kobject_put(cpld3); + 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 -ENOMEM; + } + ret = sysfs_create_group(cpld4, &cpld4_attr_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create CPLD4 sysfs attributes\n"); + kobject_put(cpld4); + sysfs_remove_group(cpld3, &cpld3_attr_grp); + kobject_put(cpld3); + 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; + } + + fancpld = kobject_create_and_add("FAN_CPLD", &pdev->dev.kobj); + if (!fancpld) { + sysfs_remove_group(cpld4, &cpld4_attr_grp); + kobject_put(cpld4); + sysfs_remove_group(cpld3, &cpld3_attr_grp); + kobject_put(cpld3); + 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 -ENOMEM; + } + if(!allow_unsafe_i2c_access) + ret = sysfs_create_group(fancpld, &fancpld_no_attr_grp); + else + ret = sysfs_create_group(fancpld, &fancpld_attr_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create FAN_CPLD sysfs attributes\n"); + kobject_put(fancpld); + sysfs_remove_group(cpld4, &cpld4_attr_grp); + kobject_put(cpld4); + sysfs_remove_group(cpld3, &cpld3_attr_grp); + kobject_put(cpld3); + 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; + } + + 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(fancpld, &fancpld_attr_grp); + kobject_put(fancpld); + sysfs_remove_group(cpld4, &cpld4_attr_grp); + kobject_put(cpld4); + sysfs_remove_group(cpld3, &cpld3_attr_grp); + kobject_put(cpld3); + 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(fancpld, &fancpld_attr_grp); + kobject_put(fancpld); + sysfs_remove_group(cpld4, &cpld4_attr_grp); + kobject_put(cpld4); + sysfs_remove_group(cpld3, &cpld3_attr_grp); + kobject_put(cpld3); + 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(fancpld, &fancpld_attr_grp); + kobject_put(fancpld); + sysfs_remove_group(cpld4, &cpld4_attr_grp); + kobject_put(cpld4); + sysfs_remove_group(cpld3, &cpld3_attr_grp); + kobject_put(cpld3); + 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 = I2C_MASTER_CH_1; portid_count <= I2C_MASTER_CH_TOTAL; portid_count++){ + + if(!allow_unsafe_i2c_access){ + if( portid_count < I2C_MASTER_CH_7 || + portid_count == I2C_MASTER_CH_9 || portid_count == I2C_MASTER_CH_10 ) + continue; + } + ret = i2c_core_init(portid_count, I2C_DIV_100K, fpga_dev.data_base_addr); + if (ret < 0) { + dev_err(&pdev->dev, "Unable to init I2C core %d\n", portid_count); + sysfs_remove_group(&sff_dev->kobj, &sff_led_test_grp); + device_destroy(fpgafwclass, MKDEV(0, 0)); + sysfs_remove_group(fancpld, &fancpld_attr_grp); + kobject_put(fancpld); + sysfs_remove_group(cpld4, &cpld4_attr_grp); + kobject_put(cpld4); + sysfs_remove_group(cpld3, &cpld3_attr_grp); + kobject_put(cpld3); + 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++) { + if(!allow_unsafe_i2c_access){ + if( portid_count >= FAN_I2C_CPLD_INDEX && portid_count < SW1_I2C_CPLD_INDEX ){ + fpga_data->i2c_adapter[portid_count] = NULL; + continue; + } + } + fpga_data->i2c_adapter[portid_count] = phalanxp_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] = phalanxp_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"); + } + } + + printk(KERN_INFO "Virtual I2C buses created\n"); + +#ifdef TEST_MODE + return 0; +#endif + fpga_i2c_access(fpga_data->i2c_adapter[SW1_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[SW1_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, + I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&cpld2_version); + fpga_i2c_access(fpga_data->i2c_adapter[SW2_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, + I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&cpld3_version); + fpga_i2c_access(fpga_data->i2c_adapter[SW2_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, + I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&cpld4_version); + + printk(KERN_INFO "Switch CPLD1 Version: %2.2x\n", cpld1_version); + printk(KERN_INFO "Switch CPLD2 Version: %2.2x\n", cpld2_version); + printk(KERN_INFO "Switch CPLD3 Version: %2.2x\n", cpld3_version); + printk(KERN_INFO "Switch CPLD4 Version: %2.2x\n", cpld4_version); + + + /* Init I2C buses that has PCA9548 switch device. */ + for (portid_count = 0; portid_count < VIRTUAL_I2C_PORT_LENGTH; portid_count++) { + + if(!allow_unsafe_i2c_access){ + if( portid_count >= FAN_I2C_CPLD_INDEX && portid_count < SW1_I2C_CPLD_INDEX ){ + continue; + } + } + + 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 phalanxp_drv_remove(struct platform_device *pdev) +{ + int portid_count; + struct sff_device_data *rem_data; + struct i2c_dev_data *adap_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]); + adap_data = i2c_get_adapdata(fpga_data->i2c_adapter[portid_count]); + i2c_del_adapter(fpga_data->i2c_adapter[portid_count]); + } + } + + for (portid_count = I2C_MASTER_CH_1; portid_count <= I2C_MASTER_CH_TOTAL; portid_count++){ + if(!allow_unsafe_i2c_access){ + if( portid_count < I2C_MASTER_CH_7 || + portid_count == I2C_MASTER_CH_9 || portid_count == I2C_MASTER_CH_10 ) + continue; + } + i2c_core_deinit(portid_count, fpga_dev.data_base_addr); + } + + 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(cpld3, &cpld3_attr_grp); + sysfs_remove_group(cpld4, &cpld4_attr_grp); + sysfs_remove_group(fancpld, &fancpld_attr_grp); + sysfs_remove_group(&sff_dev->kobj, &sff_led_test_grp); + kobject_put(fpga); + kobject_put(cpld1); + kobject_put(cpld2); + kobject_put(cpld3); + kobject_put(cpld4); + kobject_put(fancpld); + device_destroy(fpgafwclass, MKDEV(0, 0)); + devm_kfree(&pdev->dev, fpga_data); + return 0; +} + +static struct platform_driver phalanxp_drv = { + .probe = phalanxp_drv_probe, + .remove = __exit_p(phalanxp_drv_remove), + .driver = { + .name = DRIVER_NAME, + }, +}; + +#ifdef TEST_MODE +#define FPGA_PCI_BAR_NUM 2 +#else +#define FPGA_PCI_BAR_NUM 0 +#endif + + + +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 = ioremap_nocache(fpga_dev.data_mmio_start, fpga_dev.data_mmio_len); + 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(&phalanxp_dev); + platform_driver_register(&phalanxp_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(&phalanxp_drv); + platform_device_unregister(&phalanxp_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 phalanxp_init(void) +{ + int rc; + rc = pci_register_driver(&pci_dev_ops); + if (rc) + return rc; + return 0; +} + +void phalanxp_exit(void) +{ + pci_unregister_driver(&pci_dev_ops); +} + +module_init(phalanxp_init); +module_exit(phalanxp_exit); + +module_param(allow_unsafe_i2c_access, bool, 0400); +MODULE_PARM_DESC(allow_unsafe_i2c_access, "enable i2c busses despite potential races against BMC bus access"); + +MODULE_AUTHOR("Pradchaya P. "); +MODULE_DESCRIPTION("Celestica phalanxp switchboard platform driver"); +MODULE_VERSION(MOD_VERSION); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/jaws/systemd/platform-modules-jaws.service b/platform/broadcom/sonic-platform-modules-cel/jaws/systemd/platform-modules-jaws.service new file mode 100644 index 000000000000..a99d550e0f3c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/jaws/systemd/platform-modules-jaws.service @@ -0,0 +1,14 @@ + +[ Unit] +Description=Celestica Jaws platform modules +After=local-fs.target +Before=pmon.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-jaws start +ExecStop=-/etc/init.d/platform-modules-jaws stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-cel/shamu/build/lib.linux-x86_64-2.7/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-cel/shamu/build/lib.linux-x86_64-2.7/sonic_platform/__init__.py new file mode 100644 index 000000000000..d82f3749319c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/build/lib.linux-x86_64-2.7/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["platform", "chassis"] +from sonic_platform import * diff --git a/platform/broadcom/sonic-platform-modules-cel/shamu/build/lib.linux-x86_64-2.7/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-cel/shamu/build/lib.linux-x86_64-2.7/sonic_platform/chassis.py new file mode 100644 index 000000000000..dc622016cbb2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/build/lib.linux-x86_64-2.7/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/platform/broadcom/sonic-platform-modules-cel/shamu/build/lib.linux-x86_64-2.7/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-cel/shamu/build/lib.linux-x86_64-2.7/sonic_platform/eeprom.py new file mode 100644 index 000000000000..dd0c9332b54e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/build/lib.linux-x86_64-2.7/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/platform/broadcom/sonic-platform-modules-cel/shamu/build/lib.linux-x86_64-2.7/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-cel/shamu/build/lib.linux-x86_64-2.7/sonic_platform/fan.py new file mode 100644 index 000000000000..902de261f8cb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/build/lib.linux-x86_64-2.7/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/platform/broadcom/sonic-platform-modules-cel/shamu/build/lib.linux-x86_64-2.7/sonic_platform/helper.py b/platform/broadcom/sonic-platform-modules-cel/shamu/build/lib.linux-x86_64-2.7/sonic_platform/helper.py new file mode 100644 index 000000000000..1132b5b06785 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/build/lib.linux-x86_64-2.7/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/platform/broadcom/sonic-platform-modules-cel/shamu/build/lib.linux-x86_64-2.7/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-cel/shamu/build/lib.linux-x86_64-2.7/sonic_platform/platform.py new file mode 100644 index 000000000000..a632de87e742 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/build/lib.linux-x86_64-2.7/sonic_platform/platform.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + """Platform-specific Platform class""" + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/broadcom/sonic-platform-modules-cel/shamu/cfg/shamu-modules.conf b/platform/broadcom/sonic-platform-modules-cel/shamu/cfg/shamu-modules.conf new file mode 100644 index 000000000000..66f002a5fc94 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/cfg/shamu-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 + diff --git a/platform/broadcom/sonic-platform-modules-cel/shamu/modules/Makefile b/platform/broadcom/sonic-platform-modules-cel/shamu/modules/Makefile new file mode 100644 index 000000000000..99b818ea21fb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/modules/Makefile @@ -0,0 +1 @@ +obj-m := mc24lc64t.o baseboard_cpld.o switchboard_fpga.o dimm-bus.o i2c-imc.o diff --git a/platform/broadcom/sonic-platform-modules-cel/shamu/modules/baseboard_cpld.c b/platform/broadcom/sonic-platform-modules-cel/shamu/modules/baseboard_cpld.c new file mode 100644 index 000000000000..a4dfed2ac18a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/modules/baseboard_cpld.c @@ -0,0 +1,409 @@ +/* + * baseboard_cpld.c - driver for Fishbone2 Base Board CPLD + * This driver implement sysfs for CPLD register access using 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 "AS1440D.cpldb" +/** + * CPLD register address for read and write. + */ +#define VERSION_ADDR 0xA100 +#define SCRATCH_ADDR 0xA101 +#define SYS_LED_ADDR 0xA162 + +#define CPLD_REGISTER_SIZE 0x77 + +struct baseboard_cpld_data { + struct mutex cpld_lock; + uint16_t read_addr; +}; + +struct baseboard_cpld_data *cpld_data; + +/** + * Read the value from scratch register as hex string. + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer for get value + * @return Hex string read from scratch register. + */ +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); +} + +/** + * Set scratch register with specific hex string. + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer of set value + * @param count number of bytes in buffer + * @return number of bytes written, or error code < 0. + */ +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) +{ + // CPLD register is one byte + mutex_lock(&cpld_data->cpld_lock); + int len = sprintf(buf, "0x%2.2x\n",inb(VERSION_ADDR)); + mutex_unlock(&cpld_data->cpld_lock); + return len; +} +static DEVICE_ATTR_RO(version); + + +static ssize_t getreg_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + // CPLD register is one byte + 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) +{ + // CPLD register is one byte + mutex_lock(&cpld_data->cpld_lock); + int 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) +{ + // CPLD register is one byte + 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. + * @return number of byte read. + */ +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; +exit: + mutex_unlock(&cpld_data->cpld_lock); + return status; +} +static BIN_ATTR_RO(dump, CPLD_REGISTER_SIZE); + +/** + * Show system led status - on/off/1k/4k + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer for get value + * @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 ? "4k" : data ==0x01 ? "1k": "on"); +} + +/** + * Set the status of system led - on/off/1k/4k + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer of set value + * @param count number of bytes in buffer + * @return number of bytes written, or error code < 0. + */ +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, "4k")){ + led_status = 0x02; + }else if(sysfs_streq(buf, "1k")){ + 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 + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer for get value + * @return Hex string read from scratch register. + */ +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 + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer of set value + * @param count number of bytes in buffer + * @return number of bytes written, or error code < 0. + */ +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 struct attribute *baseboard_cpld_attrs[] = { + &dev_attr_version.attr, + &dev_attr_scratch.attr, + &dev_attr_getreg.attr, + &dev_attr_setreg.attr, + &dev_attr_sys_led.attr, + &dev_attr_sys_led_color.attr, + NULL, +}; + +static struct bin_attribute *baseboard_cpld_bin_attrs[] = { + &bin_attr_dump, + NULL, +}; + +static struct attribute_group baseboard_cpld_attrs_grp = { + .attrs = baseboard_cpld_attrs, + .bin_attrs = baseboard_cpld_bin_attrs, +}; + +static struct resource baseboard_cpld_resources[] = { + { + .start = 0xA100, + .end = 0xA1FF, + .flags = IORESOURCE_IO, + }, +}; + +static void baseboard_cpld_dev_release( struct device * dev) +{ + return; +} + +static struct platform_device baseboard_cpld_dev = { + .name = DRIVER_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(baseboard_cpld_resources), + .resource = baseboard_cpld_resources, + .dev = { + .release = baseboard_cpld_dev_release, + } +}; + +static int baseboard_cpld_drv_probe(struct platform_device *pdev) +{ + struct resource *res; + int ret =0; + int portid_count; + + cpld_data = devm_kzalloc(&pdev->dev, sizeof(struct baseboard_cpld_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 -1; + } + + ret = sysfs_create_group(&pdev->dev.kobj, &baseboard_cpld_attrs_grp); + if (ret) { + printk(KERN_ERR "Cannot create sysfs for baseboard CPLD\n"); + } + return 0; +} + +static int baseboard_cpld_drv_remove(struct platform_device *pdev) +{ + sysfs_remove_group(&pdev->dev.kobj, &baseboard_cpld_attrs_grp); + return 0; +} + +static struct platform_driver baseboard_cpld_drv = { + .probe = baseboard_cpld_drv_probe, + .remove = __exit_p(baseboard_cpld_drv_remove), + .driver = { + .name = DRIVER_NAME, + }, +}; + +int baseboard_cpld_init(void) +{ + // Register platform device and platform driver + platform_device_register(&baseboard_cpld_dev); + platform_driver_register(&baseboard_cpld_drv); + return 0; +} + +void baseboard_cpld_exit(void) +{ + // Unregister platform device and platform driver + platform_driver_unregister(&baseboard_cpld_drv); + platform_device_unregister(&baseboard_cpld_dev); +} + +module_init(baseboard_cpld_init); +module_exit(baseboard_cpld_exit); + +MODULE_AUTHOR("Pradchaya Phucharoen "); +MODULE_DESCRIPTION("Celestica Fishbone2 Baseboard CPLD Driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/shamu/modules/dimm-bus.c b/platform/broadcom/sonic-platform-modules-cel/shamu/modules/dimm-bus.c new file mode 100644 index 000000000000..9f30945e1d1c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/modules/dimm-bus.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2016 Andrew Lutomirski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include "dimm-bus.h" +static bool probe_addr(struct i2c_adapter *adapter, int addr) +{ + /* + * So far, all known devices that live on DIMMs can be safely + * and reliably detected by trying to read a byte at address + * zero. (The exception is the SPD write protection control, + * which can't be probed and requires special hardware and/or + * quick writes to access, and has no driver.) + */ + union i2c_smbus_data dummy; + return i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_READ, 0, + I2C_SMBUS_BYTE_DATA, &dummy) >= 0; +} +/** + * i2c_scan_dimm_bus() - Scans an SMBUS segment known to contain DIMMs + * @adapter: The SMBUS adapter to scan + * + * This function tells the DIMM-bus code that the adapter is known to + * contain DIMMs. i2c_scan_dimm_bus will probe for devices known to + * live on DIMMs. + * + * Do NOT call this function on general-purpose system SMBUS segments + * unless you know that the only things on the bus are DIMMs. + * Otherwise is it very likely to mis-identify other things on the + * bus. + * + * Callers are advised not to set adapter->class = I2C_CLASS_SPD to + * avoid having two separate mechanisms trying to automatically claim + * devices on the bus. + */ +void i2c_scan_dimm_bus(struct i2c_adapter *adapter) +{ + struct i2c_board_info info = {}; + int slot; + /* + * We probe with "read byte data". If any DIMM SMBUS driver can't + * support that access type, this function should be updated. + */ + if (WARN_ON(!i2c_check_functionality(adapter, + I2C_FUNC_SMBUS_READ_BYTE_DATA))) + return; + /* + * Addresses on DIMMs use the three low bits to identify the slot + * and the four high bits to identify the device type. Known + * devices include: + * + * - 0x10 - 0x17: NVDIMM controller (pre-standard) + * - 0x18 - 0x1f: TSOD (Temperature Sensor on DIMM) + * - 0x40 - 0x47: JESD245 Byte Addressable Energy Backed Interface + * - 0x50 - 0x57: SPD (Serial Presence Detect) EEPROM + * - 0x30 - 0x37: SPD WP control -- not easy to probe + * + * There's no point in trying to probe the SPD WP control: we'd + * want to probe using quick reads, which i2c-imc doesn't + * support, we don't have a driver for it, we can't really use + * it without special hardware (it's not a normal i2c slave -- + * see the JEDEC docs), and using it risks bricking the DIMM + * it's on anyway. + * + * NB: There's no need to save the return value from + * i2c_new_device, as the core code will unregister it for us + * when the adapter is removed. If users want to bind a + * different driver, nothing stops them from unbinding the + * drivers we request here. + */ + for (slot = 0; slot < 8; slot++) { + /* If there's no SPD, then assume there's no DIMM here. */ + if (!probe_addr(adapter, 0x50 | slot)) + continue; + strcpy(info.type, "ee1004"); + info.addr = 0x50 | slot; + i2c_new_device(adapter, &info); + if (probe_addr(adapter, 0x18 | slot)) { + /* + * This is a temperature sensor. The interface is + * defined in the JEDEC TSE2004av specification. + * Linux's driver for this is called "jc42", which + * is a bit nonsensical (JC-42 is the name of the + * committee, not the sensor). + */ + strcpy(info.type, "jc42"); + info.addr = 0x18 | slot; + i2c_new_device(adapter, &info); + } + } +} +EXPORT_SYMBOL(i2c_scan_dimm_bus); +MODULE_AUTHOR("Andrew Lutomirski "); +MODULE_DESCRIPTION("i2c DIMM bus support"); +MODULE_LICENSE("GPL v2"); + diff --git a/platform/broadcom/sonic-platform-modules-cel/shamu/modules/dimm-bus.h b/platform/broadcom/sonic-platform-modules-cel/shamu/modules/dimm-bus.h new file mode 100644 index 000000000000..8f14d5fb973f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/modules/dimm-bus.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2013-2016 Andrew Lutomirski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef _I2C_DIMM_BUS +#define _I2C_DIMM_BUS +struct i2c_adapter; +void i2c_scan_dimm_bus(struct i2c_adapter *adapter); +#endif /* _I2C_DIMM_BUS */ + diff --git a/platform/broadcom/sonic-platform-modules-cel/shamu/modules/i2c-imc.c b/platform/broadcom/sonic-platform-modules-cel/shamu/modules/i2c-imc.c new file mode 100644 index 000000000000..7b053f43916e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/modules/i2c-imc.c @@ -0,0 +1,556 @@ +/* + * Copyright (c) 2013-2016 Andrew Lutomirski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include "dimm-bus.h" + +/* + * The datasheet can be found here, for example: + * http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/xeon-e5-1600-2600-vol-2-datasheet.pdf + * + * There seem to be quite a few bugs or spec errors, though: + * + * - A successful transaction sets WOD and RDO. + * + * - The docs for TSOD_POLL_EN make no sense (see imc_channel_claim). + * + * - Erratum BT109, which says: + * + * The processor may not complete SMBus (System Management Bus) + * transactions targeting the TSOD (Temperature Sensor On DIMM) + * when Package C-States are enabled. Due to this erratum, if the + * processor transitions into a Package C-State while an SMBus + * transaction with the TSOD is in process, the processor will + * suspend receipt of the transaction. The transaction completes + * while the processor is in a Package C-State. Upon exiting + * Package C-State, the processor will attempt to resume the + * SMBus transaction, detect a protocol violation, and log an + * error. + * + * The description notwithstanding, I've seen difficult-to-reproduce + * issues when the system goes completely idle (so package C-states can + * be entered) while software-initiated SMBUS transactions are in + * progress. + */ + +/* Register offsets (in PCI configuration space) */ +#define SMBSTAT(i) (0x180 + 0x10*(i)) +#define SMBCMD(i) (0x184 + 0x10*(i)) +#define SMBCNTL(i) (0x188 + 0x10*(i)) +#define SMB_TSOD_POLL_RATE_CNTR(i) (0x18C + 0x10*(i)) +#define SMB_TSOD_POLL_RATE (0x1A8) + +/* SMBSTAT fields */ +#define SMBSTAT_RDO (1U << 31) /* Read Data Valid */ +#define SMBSTAT_WOD (1U << 30) /* Write Operation Done */ +#define SMBSTAT_SBE (1U << 29) /* SMBus Error */ +#define SMBSTAT_SMB_BUSY (1U << 28) /* SMBus Busy State */ +/* 26:24 is the last automatically polled TSOD address */ +#define SMBSTAT_RDATA_MASK 0xffff /* result of a read */ + +/* SMBCMD fields */ +#define SMBCMD_TRIGGER (1U << 31) /* CMD Trigger */ +#define SMBCMD_PNTR_SEL (1U << 30) /* HW polls TSOD with pointer */ +#define SMBCMD_WORD_ACCESS (1U << 29) /* word (vs byte) access */ +#define SMBCMD_TYPE_MASK (3U << 27) /* Mask for access type */ +#define SMBCMD_TYPE_READ (0U << 27) /* Read */ +#define SMBCMD_TYPE_WRITE (1U << 27) /* Write */ +#define SMBCMD_TYPE_PNTR_WRITE (3U << 27) /* Write to pointer */ +#define SMBCMD_SA_MASK (7U << 24) /* Slave Address high bits */ +#define SMBCMD_SA_SHIFT 24 +#define SMBCMD_BA_MASK 0xff0000 /* Bus Txn address */ +#define SMBCMD_BA_SHIFT 16 +#define SMBCMD_WDATA_MASK 0xffff /* data to write */ + +/* SMBCNTL fields */ +#define SMBCNTL_DTI_MASK 0xf0000000 /* Slave Address low bits */ +#define SMBCNTL_DTI_SHIFT 28 /* Slave Address low bits */ +#define SMBCNTL_CKOVRD (1U << 27) /* # Clock Override */ +#define SMBCNTL_DIS_WRT (1U << 26) /* Disable Write (sadly) */ +#define SMBCNTL_SOFT_RST (1U << 10) /* Soft Reset */ +#define SMBCNTL_TSOD_POLL_EN (1U << 8) /* TSOD Polling Enable */ +/* Bits 0-3 and 4-6 indicate TSOD presence in various slots */ + +/* Bits that might randomly change if we race with something. */ +#define SMBCMD_OUR_BITS (~(u32)SMBCMD_TRIGGER) +#define SMBCNTL_OUR_BITS (SMBCNTL_DTI_MASK | SMBCNTL_TSOD_POLL_EN) + +/* System Address Controller, PCI dev 13 fn 6, 8086.3cf5 */ +#define SAD_CONTROL 0xf4 + +#define PCI_DEVICE_ID_INTEL_SBRIDGE_BR 0x3cf5 /* 13.6 */ +#define PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TA 0x3ca8 /* 15.0 */ + +#define PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TA 0x6fa8 +#define PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TM 0x6f71 +#define PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA1_TA 0x6f68 +#define PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA1_TM 0x6f79 + +static atomic_t imc_raced; /* Set permanently to 1 if we screw up. */ + +static bool allow_unsafe_access; + +struct imc_channel { + struct i2c_adapter adapter; + struct mutex mutex; /* protects access to regs and prev_tsod_poll */ + bool can_write, suspended; + bool prev_tsod_poll; +}; + +struct imc_priv { + struct pci_dev *pci_dev; + struct imc_channel channels[2]; +}; + +static bool imc_wait_not_busy(struct imc_priv *priv, int chan, u32 *stat) +{ + /* + * The clock is around 100kHz, and transactions are nine cycles + * per byte plus a few start/stop cycles, plus whatever clock + * streching is involved. This means that polling every 70us + * or so will give decent performance. + * + * Ideally we would calculate a good estimate for the + * transaction time and sleep, but busy-waiting is an effective + * workaround for an apparent Sandy Bridge bug that causes bogus + * output if the system enters a package C-state. (NB: these + * states are systemwide -- we don't need be running on the + * right package for this to work.) + * + * When Ivy Bridge and Haswell support are added, we could + * consider making the busy-wait depend on the platform. + */ + + int i; + + for (i = 0; i < 50; i++) { + pci_read_config_dword(priv->pci_dev, SMBSTAT(chan), stat); + if (!(*stat & SMBSTAT_SMB_BUSY)) + return true; + udelay(70); /* see comment above -- we need to busy-wait */ + } + + return false; +} + +static void imc_channel_release(struct imc_priv *priv, int chan) +{ + /* Return to HW control. */ + if (priv->channels[chan].prev_tsod_poll) { + u32 cntl; + + pci_read_config_dword(priv->pci_dev, SMBCNTL(chan), &cntl); + cntl |= SMBCNTL_TSOD_POLL_EN; + pci_write_config_dword(priv->pci_dev, SMBCNTL(chan), cntl); + } +} + +static int imc_channel_claim(struct imc_priv *priv, int chan) +{ + /* + * The docs are a bit confused here. We're supposed to disable TSOD + * polling, then wait for busy to be cleared, then set + * SMBCNTL_TSOD_POLL_EN to zero to switch to software control. But + * SMBCNTL_TSOD_POLL_EN is the only documented way to turn off polling. + */ + + u32 cntl, stat; + + if (priv->channels[chan].suspended) + return -EIO; + + pci_read_config_dword(priv->pci_dev, SMBCNTL(chan), &cntl); + priv->channels[chan].prev_tsod_poll = !!(cntl & SMBCNTL_TSOD_POLL_EN); + cntl &= ~SMBCNTL_TSOD_POLL_EN; + pci_write_config_dword(priv->pci_dev, SMBCNTL(chan), cntl); + + /* Sometimes the hardware won't let go. */ + pci_read_config_dword(priv->pci_dev, SMBCNTL(chan), &cntl); + if (cntl & SMBCNTL_TSOD_POLL_EN) + return -EBUSY; + + if (!imc_wait_not_busy(priv, chan, &stat)) { + imc_channel_release(priv, chan); + return -EBUSY; /* Someone else is controlling the bus. */ + } + + return 0; /* The channel is ours. */ +} + +static bool imc_channel_can_claim(struct imc_priv *priv, int chan) +{ + u32 orig_cntl, cntl; + + /* See if we can turn off TSOD_POLL_EN. */ + + pci_read_config_dword(priv->pci_dev, SMBCNTL(chan), &orig_cntl); + pci_write_config_dword(priv->pci_dev, SMBCNTL(chan), + orig_cntl & ~SMBCNTL_TSOD_POLL_EN); + + pci_read_config_dword(priv->pci_dev, SMBCNTL(chan), &cntl); + if (cntl & SMBCNTL_TSOD_POLL_EN) + return false; /* Failed. */ + + pci_write_config_dword(priv->pci_dev, SMBCNTL(chan), orig_cntl); + return true; +} + +/* + * The iMC supports five access types. The terminology is rather + * inconsistent. These are the types: + * + * "Write to pointer register SMBus": I2C_SMBUS_WRITE, I2C_SMBUS_BYTE + * + * Read byte/word: I2C_SMBUS_READ, I2C_SMBUS_{BYTE|WORD}_DATA + * + * Write byte/word: I2C_SMBUS_WRITE, I2C_SMBUS_{BYTE|WORD}_DATA + * + * The pointer write operations is AFAICT completely useless for + * software control, for two reasons. First, HW periodically polls any + * TSODs on the bus, so it will corrupt the pointer in between SW + * transactions. More importantly, the matching "read byte"/"receive + * byte" (the address-less single-byte read) is not available for SW + * control. Therefore, this driver doesn't implement pointer writes + * + * There is no PEC support. + */ + +static u32 imc_func(struct i2c_adapter *adapter) +{ + int chan; + struct imc_channel *ch; + struct imc_priv *priv = i2c_get_adapdata(adapter); + + chan = (adapter == &priv->channels[0].adapter ? 0 : 1); + ch = &priv->channels[chan]; + + if (ch->can_write) + return I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA; + else + return I2C_FUNC_SMBUS_READ_BYTE_DATA | + I2C_FUNC_SMBUS_READ_WORD_DATA; +} + +static s32 imc_smbus_xfer(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, u8 command, + int size, union i2c_smbus_data *data) +{ + int ret, chan; + u32 cmd = 0, cntl, final_cmd, final_cntl, stat; + struct imc_channel *ch; + struct imc_priv *priv = i2c_get_adapdata(adap); + + if (atomic_read(&imc_raced)) + return -EIO; /* Minimize damage. */ + + chan = (adap == &priv->channels[0].adapter ? 0 : 1); + ch = &priv->channels[chan]; + + /* Encode CMD part of addresses and access size */ + cmd |= ((u32)addr & 0x7) << SMBCMD_SA_SHIFT; + cmd |= ((u32)command) << SMBCMD_BA_SHIFT; + if (size == I2C_SMBUS_WORD_DATA) + cmd |= SMBCMD_WORD_ACCESS; + + /* Encode read/write and data to write */ + if (read_write == I2C_SMBUS_READ) { + cmd |= SMBCMD_TYPE_READ; + } else { + cmd |= SMBCMD_TYPE_WRITE; + cmd |= (size == I2C_SMBUS_WORD_DATA + ? swab16(data->word) + : data->byte); + } + + mutex_lock(&ch->mutex); + + ret = imc_channel_claim(priv, chan); + if (ret) + goto out_unlock; + + pci_read_config_dword(priv->pci_dev, SMBCNTL(chan), &cntl); + cntl &= ~SMBCNTL_DTI_MASK; + cntl |= ((u32)addr >> 3) << SMBCNTL_DTI_SHIFT; + pci_write_config_dword(priv->pci_dev, SMBCNTL(chan), cntl); + + /* + * This clears SMBCMD_PNTR_SEL. We leave it cleared so that we don't + * need to think about keeping the TSOD pointer state consistent with + * the hardware's expectation. This probably has some miniscule + * power cost, as TSOD polls will take 9 extra cycles. + */ + cmd |= SMBCMD_TRIGGER; + pci_write_config_dword(priv->pci_dev, SMBCMD(chan), cmd); + + if (!imc_wait_not_busy(priv, chan, &stat)) { + /* Timeout. TODO: Reset the controller? */ + ret = -ETIMEDOUT; + dev_dbg(&priv->pci_dev->dev, "controller is wedged\n"); + goto out_release; + } + + /* + * Be paranoid: try to detect races. This will only detect races + * against BIOS, not against hardware. (I've never seen this happen.) + */ + pci_read_config_dword(priv->pci_dev, SMBCMD(chan), &final_cmd); + pci_read_config_dword(priv->pci_dev, SMBCNTL(chan), &final_cntl); + if (((cmd ^ final_cmd) & SMBCMD_OUR_BITS) || + ((cntl ^ final_cntl) & SMBCNTL_OUR_BITS)) { + WARN(1, "iMC SMBUS raced against firmware"); + dev_err(&priv->pci_dev->dev, + "Access to channel %d raced: cmd 0x%08X->0x%08X, cntl 0x%08X->0x%08X\n", + chan, cmd, final_cmd, cntl, final_cntl); + atomic_set(&imc_raced, 1); + ret = -EIO; + goto out_release; + } + + if (stat & SMBSTAT_SBE) { + /* + * Clear the error to re-enable TSOD polling. The docs say + * that, as long as SBE is set, TSOD polling won't happen. + * The docs also say that writing zero to this bit (which is + * the only writable bit in the whole register) will clear + * the error. Empirically, writing 0 does not clear SBE, but + * it's probably still good to do the write in compliance with + * the spec. (TSOD polling still happens and seems to + * clear SBE on its own.) + */ + pci_write_config_dword(priv->pci_dev, SMBSTAT(chan), 0); + ret = -ENXIO; + goto out_release; + } + + if (read_write == I2C_SMBUS_READ) { + if (!(stat & SMBSTAT_RDO)) { + dev_dbg(&priv->pci_dev->dev, + "Unexpected read status 0x%08X\n", stat); + ret = -EIO; + goto out_release; + } + + /* + * The iMC SMBUS controller thinks of SMBUS words as + * being big-endian (MSB first). Linux treats them as + * little-endian, so we need to swap them. + * + * Note: the controller will often (always?) set WOD + * here. This is probably a hardware bug. + */ + if (size == I2C_SMBUS_WORD_DATA) + data->word = swab16(stat & SMBSTAT_RDATA_MASK); + else + data->byte = stat & 0xFF; + } else { + /* + * Note: the controller will often (always?) set RDO here. + * This is probably a hardware bug. + */ + if (!(stat & SMBSTAT_WOD)) { + dev_dbg(&priv->pci_dev->dev, + "Unexpected write status 0x%08X\n", stat); + ret = -EIO; + } + } + +out_release: + imc_channel_release(priv, chan); + +out_unlock: + mutex_unlock(&ch->mutex); + + return ret; +} + +static const struct i2c_algorithm imc_smbus_algorithm = { + .smbus_xfer = imc_smbus_xfer, + .functionality = imc_func, +}; + +static int imc_init_channel(struct imc_priv *priv, int i, int socket) +{ + int err; + u32 val; + struct imc_channel *ch = &priv->channels[i]; + + /* + * With CLTT enabled, the hardware won't let us turn + * off TSOD polling. The device is completely useless + * when this happens (at least without help from Intel), + * but we can at least minimize confusion. + */ + if (!imc_channel_can_claim(priv, i)) { + dev_warn(&priv->pci_dev->dev, + "iMC channel %d: we cannot control the HW. Is CLTT on?\n", + i); + return -EBUSY; + } + + i2c_set_adapdata(&ch->adapter, priv); + ch->adapter.owner = THIS_MODULE; + ch->adapter.algo = &imc_smbus_algorithm; + ch->adapter.dev.parent = &priv->pci_dev->dev; + + pci_read_config_dword(priv->pci_dev, SMBCNTL(i), &val); + ch->can_write = !(val & SMBCNTL_DIS_WRT); + + mutex_init(&ch->mutex); + + snprintf(ch->adapter.name, sizeof(ch->adapter.name), + "iMC socket %d channel %d", socket, i); + err = i2c_add_adapter(&ch->adapter); + if (err) { + mutex_destroy(&ch->mutex); + return err; + } + + i2c_scan_dimm_bus(&ch->adapter); + + return 0; +} + +static void imc_free_channel(struct imc_priv *priv, int i) +{ + struct imc_channel *ch = &priv->channels[i]; + + i2c_del_adapter(&ch->adapter); + mutex_destroy(&ch->mutex); +} + +static struct pci_dev *imc_get_related_device(struct pci_bus *bus, + unsigned int devfn, u16 devid) +{ + struct pci_dev *dev = pci_get_slot(bus, devfn); + + if (!dev) + return NULL; + if (dev->vendor != PCI_VENDOR_ID_INTEL || dev->device != devid) { + pci_dev_put(dev); + return NULL; + } + return dev; +} + +static int imc_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + int i, j, err; + struct imc_priv *priv; + + priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + priv->pci_dev = dev; + + pci_set_drvdata(dev, priv); + + for (i = 0; i < 1; i++) { + err = imc_init_channel(priv, i, 0); + if (err) + goto exit_free_channels; + printk(KERN_INFO "IMC: Create IMC SMBus OK.\n"); + } + + return 0; + +exit_free_channels: + printk(KERN_INFO "IMC: Free chennel I2C.\n"); + for (j = 0; j < i; j++) + imc_free_channel(priv, j); + return err; +} + +static void imc_remove(struct pci_dev *dev) +{ + int i; + struct imc_priv *priv = pci_get_drvdata(dev); + + for (i = 0; i < 1; i++) + imc_free_channel(priv, i); +} + +static int imc_suspend(struct pci_dev *dev, pm_message_t mesg) +{ + int i; + struct imc_priv *priv = pci_get_drvdata(dev); + + /* BIOS is in charge. We should finish any pending transaction */ + for (i = 0; i < 1; i++) { + mutex_lock(&priv->channels[i].mutex); + priv->channels[i].suspended = true; + mutex_unlock(&priv->channels[i].mutex); + } + + return 0; +} + +static int imc_resume(struct pci_dev *dev) +{ + int i; + struct imc_priv *priv = pci_get_drvdata(dev); + + for (i = 0; i < 1; i++) { + mutex_lock(&priv->channels[i].mutex); + priv->channels[i].suspended = false; + mutex_unlock(&priv->channels[i].mutex); + } + + return 0; +} + +static const struct pci_device_id imc_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TA) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TA) }, + { 0, } +}; +MODULE_DEVICE_TABLE(pci, imc_ids); + +static struct pci_driver imc_pci_driver = { + .name = "imc_smbus", + .id_table = imc_ids, + .probe = imc_probe, + .remove = imc_remove, + .suspend = imc_suspend, + .resume = imc_resume, +}; + +static int __init i2c_imc_init(void) +{ + if (!allow_unsafe_access) + return -ENODEV; + + pr_warn("using this driver is dangerous unless your firmware is specifically designed for it; use at your own risk\n"); + return pci_register_driver(&imc_pci_driver); +} +module_init(i2c_imc_init); + +static void __exit i2c_imc_exit(void) +{ + pci_unregister_driver(&imc_pci_driver); +} +module_exit(i2c_imc_exit); + +module_param(allow_unsafe_access, bool, 0400); +MODULE_PARM_DESC(allow_unsafe_access, "enable i2c_imc despite potential races against BIOS/hardware bus access"); + +MODULE_AUTHOR("Andrew Lutomirski "); +MODULE_DESCRIPTION("iMC SMBus driver"); +MODULE_LICENSE("GPL v2"); + diff --git a/platform/broadcom/sonic-platform-modules-cel/shamu/modules/mc24lc64t.c b/platform/broadcom/sonic-platform-modules-cel/shamu/modules/mc24lc64t.c new file mode 100644 index 000000000000..ae79770a4d8e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/modules/mc24lc64t.c @@ -0,0 +1,173 @@ +/* + * 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; + 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"); diff --git a/platform/broadcom/sonic-platform-modules-cel/shamu/modules/sonic_platform-1.0-py2-none-any.whl b/platform/broadcom/sonic-platform-modules-cel/shamu/modules/sonic_platform-1.0-py2-none-any.whl new file mode 100644 index 000000000000..75d574b5a123 Binary files /dev/null and b/platform/broadcom/sonic-platform-modules-cel/shamu/modules/sonic_platform-1.0-py2-none-any.whl differ diff --git a/platform/broadcom/sonic-platform-modules-cel/shamu/modules/switchboard_fpga.c b/platform/broadcom/sonic-platform-modules-cel/shamu/modules/switchboard_fpga.c new file mode 100644 index 000000000000..e537eb7955c3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/modules/switchboard_fpga.c @@ -0,0 +1,2431 @@ +/* + * switchboard_fpga.c - Driver for Fishbone2 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 + * \--AS1440DF.switchboard + * |--FPGA + * |--CPLD1 + * |--CPLD2 + * \--SFF + * \--QSFP[1..32] + * + */ + +#ifndef TEST_MODE +#define MOD_VERSION "0.5.2" +#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 "fishbone2_fpga" +#define DRIVER_NAME "AS1440D.switchboard" +#define FPGA_PCI_NAME "fishbone2_fpga_pci" +#define DEVICE_NAME "fwupgrade" + +static bool allow_unsafe_i2c_access; + +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 i2c_core_init(unsigned int master_bus, unsigned int freq_div,void __iomem *pci_bar); +static void i2c_core_deinit(unsigned int master_bus, void __iomem *pci_bar); +static int i2c_xcvr_access(u8 register_address, unsigned int portid, u8 *data, char rw); + +static int fpgafw_init(void); +static void fpgafw_exit(void); + +/* +======================================== +FPGA PCIe BAR 0 Registers +======================================== +Misc Control 0x00000000 – 0x000000FF +I2C_CH1 0x00000800 - 0x0000081C +I2C_CH2 0x00000820 - 0x0000083C +I2C_CH3 0x00000840 - 0x0000085C +I2C_CH4 0x00000860 - 0x0000087C +I2C_CH5 0x00000880 - 0x0000089C +I2C_CH6 0x000008A0 - 0x000008BC +I2C_CH7 0x000008C0 - 0x000008DC +I2C_CH8 0x000008E0 - 0x000008FC +I2C_CH9 0x00000900 - 0x0000091C +I2C_CH10 0x00000920 - 0x0000093C +I2C_CH11 0x00000940 - 0x0000095C +I2C_CH12 0x00000960 - 0x0000097C +I2C_CH13 0x00000980 - 0x0000099C +I2C_CH14 0x000009A0 - 0x000009BC +SPI Master 0x00000A00 - 0x00000BFC +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 BMC_I2C_SCRATCH 0x0020 +#define FPGA_SLAVE_CPLD_REST 0x0100 +#define FPGA_SWITCH_RESET_CTRL 0x0104 +#define FPAG_PRH_RESER_CTRL 0x0108 +#define FPGA_INT_STATUS 0x0200 +#define FPGA_INT_SRC_STATUS 0x0204 +#define FPGA_INT_FLAG 0x0208 +#define FPGA_INT_MASK 0x020c +#define FPGA_MISC_CTRL 0x0300 +#define FPGA_MISC_STATUS 0x0304 + +/* I2C_MASTER BASE ADDR */ +#define I2C_MASTER_FREQ_L 0x0800 +#define I2C_MASTER_FREQ_H 0x0804 +#define I2C_MASTER_CTRL 0x0808 +#define I2C_MASTER_DATA 0x080c +#define I2C_MASTER_CMD 0x0810 /* Write-Only Register */ +#define I2C_MASTER_STATUS 0x0810 /* Read-Only Register */ +#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_14 14 + +#define I2C_MASTER_CH_TOTAL I2C_MASTER_CH_14 + +/* 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] RSVD +[5] MODSEL 5 +[4] RST 4 +[3:1] RSVD +[0] TXDIS 0 +*/ +#define CTRL_MODSEL 5 +#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 + + +/** + * Switchboard CPLD XCVR registers + */ + +/* PORT SEL REGISTER +[7:5] RSVD +[4:0] ID +*/ +#define I2C_XCVR_SEL 0x10 +#define I2C_SEL_ID 0 + +/* PORT CTRL REGISTER +[7:5] RSVD +[4] RST +[3:1] RSVD +[0] TXDIS/MODSEL +*/ +#define I2C_XCVR_CTRL 0x11 +#define I2C_CTRL_RST 4 +#define I2C_CTRL_MODSEL 0 +#define I2C_CTRL_TXDIS 0 + +/* PORT STATUS REGISTER +[7:5] RSVD +[4] PRESENT/ABS +[3:2] RSVD +[1] TXFAULT +[0] RXLOS/INT_N +*/ +#define I2C_XCVR_STAT 0x12 +#define I2C_STAT_PRESENT 4 +#define I2C_STAT_MODABS 4 +#define I2C_STAT_TXFAULT 1 +#define I2C_STAT_INT_N 0 +#define I2C_STAT_RXLOS 0 + +/* PORT INTRPT REGISTER +[7:5] RSVD +[4] PRESENT/ABS +[3:2] RSVD +[1] TXFAULT +[0] RXLOS/INT_N +*/ +#define I2C_XCVR_INRT 0x13 +#define I2C_INTR_PRESENT 4 +#define I2C_INTR_MODABS 4 +#define I2C_INTR_TXFAULT 1 +#define I2C_INTR_INT_N 0 +#define I2C_INTR_RXLOS 0 + +/* PORT INTR MASK REGISTER +[31:6] RSVD +[5] INT_N 5 +[4] PRESENT 4 +[3] RSVD +[2] RSVD +[1] RXLOS_INT 1 +[0] MODABS 0 +*/ +#define I2C_XCVR_MASK 0x14 +#define I2C_MASK_PRESENT 4 +#define I2C_MASK_MODABS 4 +#define I2C_MASK_TXFAULT 1 +#define I2C_MASK_INT_N 0 +#define I2C_MASK_RXLOS 0 + + +/* I2C master clock speed */ +// NOTE: Only I2C clock in normal mode is support here. +enum { + I2C_DIV_100K = 0x71, +}; + +/* I2C Master control register */ +enum { + I2C_CTRL_IEN = 6, + I2C_CTRL_EN +}; + +/* I2C Master command register */ +enum { + I2C_CMD_IACK = 0, + I2C_CMD_ACK = 3, + I2C_CMD_WR, + I2C_CMD_RD, + I2C_CMD_STO, + I2C_CMD_STA, +}; + +/* I2C Master status register */ +enum { + I2C_STAT_IF = 0, + I2C_STAT_TIP, + I2C_STAT_AL = 5, + I2C_STAT_BUSY, + I2C_STAT_RxACK, +}; + +/** + * + * 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_SFP_PORT 0 +#define VIRTUAL_I2C_QSFP_PORT 40 + +#define SFF_PORT_TOTAL VIRTUAL_I2C_QSFP_PORT + VIRTUAL_I2C_SFP_PORT + +#define VIRTUAL_I2C_BUS_OFFSET 10 +#define BB_CPLD_SLAVE_ADDR 0x0d +#define FAN_CPLD_SLAVE_ADDR 0x0d +#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 + +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]; +static int nack_retry[I2C_MASTER_CH_TOTAL]; +static int need_retry[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[] = { + /* SFP and QSFP front panel I2C */ + {I2C_MASTER_CH_11, 0x70, 0, QSFP, "QSFP3"}, {I2C_MASTER_CH_11, 0x70, 1, QSFP, "QSFP4"}, + {I2C_MASTER_CH_11, 0x70, 2, QSFP, "QSFP5"}, {I2C_MASTER_CH_11, 0x70, 3, QSFP, "QSFP6"}, + {I2C_MASTER_CH_11, 0x70, 4, QSFP, "QSFP7"}, {I2C_MASTER_CH_11, 0x70, 5, QSFP, "QSFP8"}, + {I2C_MASTER_CH_11, 0x70, 6, QSFP, "QSFP9"}, {I2C_MASTER_CH_11, 0x70, 7, QSFP, "QSFP10"}, + + {I2C_MASTER_CH_11, 0x71, 0, QSFP, "QSFP11"}, {I2C_MASTER_CH_11, 0x71, 1, QSFP, "QSFP12"}, + {I2C_MASTER_CH_11, 0x71, 2, QSFP, "QSFP13"}, {I2C_MASTER_CH_11, 0x71, 3, QSFP, "QSFP14"}, + {I2C_MASTER_CH_11, 0x71, 4, QSFP, "QSFP15"}, {I2C_MASTER_CH_11, 0x71, 5, QSFP, "QSFP16"}, + {I2C_MASTER_CH_11, 0x71, 6, QSFP, "QSFP17"}, {I2C_MASTER_CH_11, 0x71, 7, QSFP, "QSFP18"}, + + {I2C_MASTER_CH_11, 0x72, 0, QSFP, "QSFP23"}, {I2C_MASTER_CH_11, 0x72, 1, QSFP, "QSFP24"}, + {I2C_MASTER_CH_11, 0x72, 2, QSFP, "QSFP25"}, {I2C_MASTER_CH_11, 0x72, 3, QSFP, "QSFP26"}, + {I2C_MASTER_CH_11, 0x72, 4, QSFP, "QSFP27"}, {I2C_MASTER_CH_11, 0x72, 5, QSFP, "QSFP28"}, + {I2C_MASTER_CH_11, 0x72, 6, QSFP, "QSFP29"}, {I2C_MASTER_CH_11, 0x72, 7, QSFP, "QSFP30"}, + + {I2C_MASTER_CH_11, 0x73, 0, QSFP, "QSFP31"}, {I2C_MASTER_CH_11, 0x73, 1, QSFP, "QSFP32"}, + {I2C_MASTER_CH_11, 0x73, 2, QSFP, "QSFP33"}, {I2C_MASTER_CH_11, 0x73, 3, QSFP, "QSFP34"}, + {I2C_MASTER_CH_11, 0x73, 4, QSFP, "QSFP35"}, {I2C_MASTER_CH_11, 0x73, 5, QSFP, "QSFP36"}, + {I2C_MASTER_CH_11, 0x73, 6, QSFP, "QSFP37"}, {I2C_MASTER_CH_11, 0x73, 7, QSFP, "QSFP38"}, + + {I2C_MASTER_CH_11, 0x74, 0, QSFP, "QSFP1"}, {I2C_MASTER_CH_11, 0x74, 1, QSFP, "QSFP2"}, + {I2C_MASTER_CH_11, 0x74, 2, QSFP, "QSFP19"}, {I2C_MASTER_CH_11, 0x74, 3, QSFP, "QSFP20"}, + {I2C_MASTER_CH_11, 0x74, 4, QSFP, "QSFP21"}, {I2C_MASTER_CH_11, 0x74, 5, QSFP, "QSFP22"}, + {I2C_MASTER_CH_11, 0x74, 6, QSFP, "QSFP39"}, {I2C_MASTER_CH_11, 0x74, 7, QSFP, "QSFP40"}, + + /* Vritual I2C adapters */ + {I2C_MASTER_CH_1, 0xFF, 0, NONE, "I2C_1"}, // FAN + {I2C_MASTER_CH_2, 0xFF, 0, NONE, "I2C_2"}, + {I2C_MASTER_CH_3, 0xFF, 0, NONE, "I2C_3"}, + {I2C_MASTER_CH_4, 0xFF, 0, NONE, "I2C_4"}, + {I2C_MASTER_CH_5, 0xFF, 0, NONE, "I2C_5"}, // BB + {I2C_MASTER_CH_6, 0xFF, 0, NONE, "I2C_6"}, + {I2C_MASTER_CH_7, 0xFF, 0, NONE, "I2C_7"}, // SW + + // NOTE: The bus below are for front panel port debug + {I2C_MASTER_CH_11, 0xFF, 0, NONE, "I2C_11"}, // SFF + +}; + +#define VIRTUAL_I2C_PORT_LENGTH ARRAY_SIZE(fpga_i2c_bus_dev) +#define FAN_I2C_CPLD_INDEX SFF_PORT_TOTAL +#define BB_I2C_CPLD_INDEX SFF_PORT_TOTAL + 4 +#define SW_I2C_CPLD_INDEX SFF_PORT_TOTAL + 6 + +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 fishbone2_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 fishbone2_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; + +/** + * 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; +} + +/* 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 struct attribute *fpga_attrs[] = { + &dev_attr_getreg.attr, + &dev_attr_scratch.attr, + &dev_attr_setreg.attr, + NULL, +}; + +static struct attribute_group fpga_attr_grp = { + .attrs = fpga_attrs, +}; + +/* 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_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_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_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) +{ + u8 data; + int err; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + err = i2c_xcvr_access(I2C_XCVR_STAT,portid,&data,I2C_SMBUS_READ); + if(err < 0){ + return err; + } + return sprintf(buf, "%d\n", (data >> I2C_STAT_INT_N) & 1U); +} +DEVICE_ATTR_RO(qsfp_modirq); + +static ssize_t qsfp_modprs_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 data; + int err; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + err = i2c_xcvr_access(I2C_XCVR_STAT,portid,&data,I2C_SMBUS_READ); + if(err < 0){ + return err; + } + return sprintf(buf, "%d\n", (data >> I2C_STAT_MODABS) & 1U); +} +DEVICE_ATTR_RO(qsfp_modprs); + +static ssize_t sfp_txfault_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 data; + int err; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + err = i2c_xcvr_access(I2C_XCVR_STAT,portid,&data,I2C_SMBUS_READ); + if(err < 0){ + return err; + } + return sprintf(buf, "%d\n", (data >> I2C_STAT_TXFAULT) & 1U); +} +DEVICE_ATTR_RO(sfp_txfault); + +static ssize_t sfp_rxlos_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 data; + int err; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + err = i2c_xcvr_access(I2C_XCVR_STAT,portid,&data,I2C_SMBUS_READ); + if(err < 0){ + return err; + } + return sprintf(buf, "%d\n", (data >> I2C_STAT_RXLOS) & 1U); +} +DEVICE_ATTR_RO(sfp_rxlos); + +static ssize_t sfp_modabs_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 data; + int err; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + err = i2c_xcvr_access(I2C_XCVR_STAT,portid,&data,I2C_SMBUS_READ); + if(err < 0){ + return err; + } + return sprintf(buf, "%d\n", (data >> I2C_STAT_MODABS) & 1U); +} +DEVICE_ATTR_RO(sfp_modabs); + +static ssize_t qsfp_modsel_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 data; + int err; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + err = i2c_xcvr_access(I2C_XCVR_CTRL,portid,&data,I2C_SMBUS_READ); + if(err < 0){ + return err; + } + return sprintf(buf, "%d\n", (data >> I2C_CTRL_MODSEL) & 1U); +} +static ssize_t qsfp_modsel_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + ssize_t status; + long value; + u8 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + + status = kstrtol(buf, 0, &value); + if (status == 0) { + // if value is 0, clear bit. + i2c_xcvr_access(I2C_XCVR_CTRL,portid,&data,I2C_SMBUS_READ); + if (!value) + data = data & ~( 1U << I2C_CTRL_MODSEL ); + else + data = data | ( 1U << I2C_CTRL_MODSEL ); + i2c_xcvr_access(I2C_XCVR_CTRL,portid,&data,I2C_SMBUS_WRITE); + status = size; + } + return status; +} +DEVICE_ATTR_RW(qsfp_modsel); + +static ssize_t qsfp_reset_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 data; + int err; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + err = i2c_xcvr_access(I2C_XCVR_CTRL,portid,&data,I2C_SMBUS_READ); + if(err < 0){ + return err; + } + return sprintf(buf, "%d\n", (data >> I2C_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; + u8 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + + status = kstrtol(buf, 0, &value); + if (status == 0) { + // if value is 0, reset signal is low + i2c_xcvr_access(I2C_XCVR_CTRL,portid,&data,I2C_SMBUS_READ); + if (!value) + data = data & ~((u8)0x1 << I2C_CTRL_RST); + else + data = data | ((u8)0x1 << I2C_CTRL_RST); + i2c_xcvr_access(I2C_XCVR_CTRL,portid,&data,I2C_SMBUS_WRITE); + status = size; + } + return status; +} +DEVICE_ATTR_RW(qsfp_reset); + +static ssize_t sfp_txdisable_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 data; + int err; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + err = i2c_xcvr_access(I2C_XCVR_CTRL,portid,&data,I2C_SMBUS_READ); + if(err < 0){ + return err; + } + return sprintf(buf, "%d\n", (data >> I2C_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; + u8 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtol(buf, 0, &value); + if (status == 0) { + // check if value is 0 clear + i2c_xcvr_access(I2C_XCVR_CTRL,portid,&data,I2C_SMBUS_READ); + if (!value) + data = data & ~((u8)0x1 << I2C_CTRL_TXDIS); + else + data = data | ((u8)0x1 << I2C_CTRL_TXDIS); + i2c_xcvr_access(I2C_XCVR_CTRL,portid,&data,I2C_SMBUS_WRITE); + 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_modsel.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 green/amber/both/alt-blink/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 ? "amber" : led_color1 == 0x04 ? + "both" : "alt-blink", + led_color1 == 0x07 ? "off" : led_color1 == 0x06 ? "green" : led_color1 == 0x05 ? "amber" : led_color1 == 0x04 ? + "both" : "alt-blink"); +} + +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, "amber")) { + led_color = 0x05; + } else if (sysfs_streq(buf, "both")) { + led_color = 0x04; + } else if (sysfs_streq(buf, "alt-blink")) { + led_color = 0x03; + } 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 * fishbone2_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_core_init(unsigned int master_bus, unsigned int freq_div,void __iomem *pci_bar){ + + unsigned int ctrl; + unsigned int REG_FREQ_L; + unsigned int REG_FREQ_H; + unsigned int REG_CTRL; + unsigned int REG_CMD; + + REG_FREQ_L = I2C_MASTER_FREQ_L + (master_bus - 1) * 0x20; + REG_FREQ_H = I2C_MASTER_FREQ_H + (master_bus - 1) * 0x20; + REG_CTRL = I2C_MASTER_CTRL + (master_bus - 1) * 0x20; + REG_CMD = I2C_MASTER_CMD + (master_bus - 1) * 0x20; + + if ( freq_div != I2C_DIV_100K ) { + printk(KERN_ERR "FPGA I2C core: Unsupported clock divider: %x\n", freq_div); + return -EINVAL; + } + + // Makes sure core is disable + ctrl = ioread8(pci_bar + REG_CTRL); + iowrite8( ctrl & ~(1 << I2C_CTRL_EN | 1 << I2C_CTRL_IEN), pci_bar + REG_CTRL); + + iowrite8( freq_div & 0xFF , pci_bar + REG_FREQ_L); + iowrite8( freq_div >> 8, pci_bar + REG_FREQ_H); + + /* Only enable EN bit, we only use polling mode */ + iowrite8(1 << I2C_CMD_IACK, pci_bar + REG_CMD); + iowrite8(1 << I2C_CTRL_EN, pci_bar + REG_CTRL); + + return 0; +} + +static void i2c_core_deinit(unsigned int master_bus,void __iomem *pci_bar){ + + unsigned int REG_CTRL; + REG_CTRL = I2C_MASTER_CTRL + (master_bus - 1) * 0x20; + // Disable core + iowrite8( ioread8(pci_bar + REG_CTRL) & ~(1 << I2C_CTRL_EN| 1 << I2C_CTRL_IEN), pci_bar + REG_CTRL); +} + +//FIXME: The hard code seperater below will causing bug! +//Should pass configuration args into function. +static int i2c_xcvr_access(u8 register_address, unsigned int portid, u8 *data, char rw){ + + u16 dev_addr = 0; + int err; + /* check for portid valid length */ + if(portid < 0 || portid > SFF_PORT_TOTAL){ + return -EINVAL; + } + if (portid <= 16 ){ + dev_addr = CPLD1_SLAVE_ADDR; + }else{ + dev_addr = CPLD2_SLAVE_ADDR; + portid = portid - 16; + } + // Select port + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], dev_addr, 0x00, I2C_SMBUS_WRITE, + I2C_XCVR_SEL, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&portid); + if(err < 0){ + return err; + } + // Read/write port xcvr register + err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], dev_addr, 0x00, rw, + register_address , I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)data); + if(err < 0){ + return err; + } + return 0; +} + +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_FREQ_L; + unsigned int REG_FREQ_H; + unsigned int REG_CMD; + unsigned int REG_CTRL; + unsigned int REG_STAT; + unsigned int REG_DATA; + + 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_FREQ_L = I2C_MASTER_FREQ_L + (master_bus - 1) * 0x20; + REG_FREQ_H = I2C_MASTER_FREQ_H + (master_bus - 1) * 0x20; + REG_CTRL = I2C_MASTER_CTRL + (master_bus - 1) * 0x20; + REG_CMD = I2C_MASTER_CMD + (master_bus - 1) * 0x20; + REG_STAT = I2C_MASTER_STATUS + (master_bus - 1) * 0x20; + REG_DATA = I2C_MASTER_DATA + (master_bus - 1) * 0x20; + + check(pci_bar + REG_STAT); + check(pci_bar + REG_CTRL); + + /* + * We wait for the data to be transferred (8bit), + * then we start polling on the ACK/NACK bit + * udelay((8 * 1000) / 100); + */ + udelay(80); + dev_dbg(&a->dev,"Wait for 0x%2.2X\n", 1 << I2C_STAT_TIP); + + timeout = jiffies + msecs_to_jiffies(timeout); + while (1) { + Status = ioread8(pci_bar + REG_STAT); + dev_dbg(&a->dev, "ST:%2.2X\n", Status); + + /* Wait for the TIP bit to be cleared before timeout */ + if ( (Status & ( 1 << I2C_STAT_TIP )) == 0 ) { + dev_dbg(&a->dev, " TIP cleared:0x%2.2X\n", Status); + break; + } + + if (time_after(jiffies, timeout)) { + info("Status %2.2X", Status); + info("Error Timeout"); + error = -ETIMEDOUT; + break; + } + + cpu_relax(); + cond_resched(); + } + info("Status %2.2X", Status); + info("STA:%x",Status); + + if (error < 0) { + dev_dbg(&a->dev, "%s TIMEOUT bit 0x%x not clear in specific time\n", + __func__, (1 << I2C_STAT_TIP)); + return error; + } + + /** There is only one master in each bus. If this error happen something is + * not normal in i2c transfer refer to: + * https://www.i2c-bus.org/i2c-primer/analysing-obscure-problems/master-reports-arbitration-lost + */ + // Arbitration lost + if (Status & (1 << I2C_STAT_AL)) { + info("Error arbitration lost"); + nack_retry[master_bus - 1] = 1; + return -EBUSY; + } + + // Ack not received + if (Status & (1 << I2C_STAT_RxACK)) { + info( "SL No ACK"); + if (writing) { + info("Error No ACK"); + nack_retry[master_bus - 1] = 1; + return -EIO; + } + } else { + info( "SL ACK"); + } + + return error; +} + +static int i2c_wait_stop(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_FREQ_L; + unsigned int REG_FREQ_H; + unsigned int REG_CMD; + unsigned int REG_CTRL; + unsigned int REG_STAT; + unsigned int REG_DATA; + + 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_FREQ_L = I2C_MASTER_FREQ_L + (master_bus - 1) * 0x20; + REG_FREQ_H = I2C_MASTER_FREQ_H + (master_bus - 1) * 0x20; + REG_CTRL = I2C_MASTER_CTRL + (master_bus - 1) * 0x20; + REG_CMD = I2C_MASTER_CMD + (master_bus - 1) * 0x20; + REG_STAT = I2C_MASTER_STATUS + (master_bus - 1) * 0x20; + REG_DATA = I2C_MASTER_DATA + (master_bus - 1) * 0x20; + + check(pci_bar + REG_STAT); + check(pci_bar + REG_CTRL); + + dev_dbg(&a->dev,"Wait for 0x%2.2X\n", 1 << I2C_STAT_BUSY); + timeout = jiffies + msecs_to_jiffies(timeout); + while (1) { + Status = ioread8(pci_bar + REG_STAT); + dev_dbg(&a->dev, "ST:%2.2X\n", Status); + if (time_after(jiffies, timeout)) { + info("Status %2.2X", Status); + info("Error Timeout"); + error = -ETIMEDOUT; + break; + } + + /* Wait for the BUSY bit to be cleared before timeout */ + if ( (Status & ( 1 << I2C_STAT_BUSY )) == 0 ) { + dev_dbg(&a->dev, " BUSY cleared:0x%2.2X\n", Status); + break; + } + + cpu_relax(); + cond_resched(); + } + info("Status %2.2X", Status); + info("STA:%x",Status); + + if (error < 0) { + dev_dbg(&a->dev, "%s TIMEOUT bit 0x%x not clear in specific time\n", + __func__, (1 << I2C_STAT_BUSY)); + return error; + } + return 0; +} + +/* SMBUS Xfer for opencore I2C with polling */ +// TODO: Change smbus_xfer to master_xfer - This will support i2c and all smbus emu functions. +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; + int error_stop = 0; + + unsigned int REG_FREQ_L; + unsigned int REG_FREQ_H; + unsigned int REG_CMD; + unsigned int REG_CTRL; + unsigned int REG_STAT; + unsigned int REG_DATA; + + REG_FREQ_L = 0; + REG_FREQ_H = 0; + REG_CTRL = 0; + REG_CMD = 0; + REG_STAT = 0; + REG_DATA = 0; + + /* Write the command register */ + dev_data = i2c_get_adapdata(adapter); + portid = dev_data->portid; + pci_bar = fpga_dev.data_base_addr; + +#ifdef DEBUG_KERN + printk(KERN_INFO "portid %2d|@ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-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" : + size == 8 ? "I2C_BLOCK_DATA" : "ERROR" + , cmd); +#endif + + master_bus = dev_data->pca9548.master_bus; + error = i2c_core_init(master_bus, I2C_DIV_100K, fpga_dev.data_base_addr); + + /* Map the size to what the chip understands */ + switch (size) { + case I2C_SMBUS_QUICK: + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + case I2C_SMBUS_WORD_DATA: + case I2C_SMBUS_BLOCK_DATA: + case I2C_SMBUS_I2C_BLOCK_DATA: + break; + default: + printk(KERN_INFO "Unsupported transaction %d\n", size); + error = -EOPNOTSUPP; + goto Done; + } + + master_bus = dev_data->pca9548.master_bus; + + if (master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL) { + error = -EINVAL; + goto Done; + } + + REG_FREQ_L = I2C_MASTER_FREQ_L + (master_bus - 1) * 0x20; + REG_FREQ_H = I2C_MASTER_FREQ_H + (master_bus - 1) * 0x20; + REG_CTRL = I2C_MASTER_CTRL + (master_bus - 1) * 0x20; + REG_CMD = I2C_MASTER_CMD + (master_bus - 1) * 0x20; + REG_STAT = I2C_MASTER_STATUS + (master_bus - 1) * 0x20; + REG_DATA = I2C_MASTER_DATA + (master_bus - 1) * 0x20; + + ////[S][ADDR/R] + 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_DATA); + } else { + // sent device address with Write mode + iowrite8( (addr << 1) & 0xFE, pci_bar + REG_DATA); + } + iowrite8( 1 << I2C_CMD_STA | 1 << I2C_CMD_WR | 1 << I2C_CMD_IACK, pci_bar + REG_CMD); + + info( "MS Start"); + + //// Wait {A} + // + IACK + error = i2c_wait_ack(adapter, 30, 1); + if (error < 0) { + info( "get error %d", error); + dev_dbg(&adapter->dev,"START Error: %d\n", error); + goto Done; + } + + //// [CMD]{A} + if (size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA || + size == I2C_SMBUS_I2C_BLOCK_DATA || + (size == I2C_SMBUS_BYTE && rw == I2C_SMBUS_WRITE)) { + + // sent command code to data register + iowrite8(cmd, pci_bar + REG_DATA); + // Start the transfer + iowrite8(1 << I2C_CMD_WR | 1 << I2C_CMD_IACK, pci_bar + REG_CMD); + info( "MS Send CMD 0x%2.2X", cmd); + + // Wait {A} + // IACK + error = i2c_wait_ack(adapter, 30, 1); + if (error < 0) { + info( "get error %d", error); + dev_dbg(&adapter->dev,"CMD Error: %d\n", 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: + case I2C_SMBUS_I2C_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 block data write + if (size == I2C_SMBUS_BLOCK_DATA && rw == I2C_SMBUS_WRITE) { + + iowrite8(cnt, pci_bar + REG_DATA); + //Start the transfer + iowrite8(1 << I2C_CMD_WR | 1 << I2C_CMD_IACK, pci_bar + REG_CMD); + info( "MS Send CNT 0x%2.2X", cnt); + + // Wait {A} + // IACK + error = i2c_wait_ack(adapter, 30, 1); + if (error < 0) { + info( "get error %d", error); + dev_dbg(&adapter->dev,"CNT Error: %d\n", 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 || + size == I2C_SMBUS_I2C_BLOCK_DATA + )) { + int bid = 0; + info( "MS prepare to sent [%d bytes]", cnt); + if (size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA) { + bid = 1; // block[0] is cnt; + cnt += 1; // offset from block[0] + } + for (; bid < cnt; bid++) { + info("STA:%x", ioread8(pci_bar + REG_STAT) ); + info( " Data > %2.2X", data->block[bid]); + iowrite8(data->block[bid], pci_bar + REG_DATA); + iowrite8(1 << I2C_CMD_WR | 1 << I2C_CMD_IACK, pci_bar + REG_CMD); + + // Wait {A} + // IACK + error = i2c_wait_ack(adapter, 30, 1); + if (error < 0) { + dev_dbg(&adapter->dev,"Send DATA Error: %d\n", error); + goto Done; + } + } + } + + //REPEATE START + if ( rw == I2C_SMBUS_READ && ( + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA || + size == I2C_SMBUS_I2C_BLOCK_DATA + )) { + info( "MS Repeated Start"); + + // sent Address with Read mode + iowrite8( addr << 1 | 0x1 , pci_bar + REG_DATA); + // SET START | WRITE + iowrite8( 1 << I2C_CMD_STA | 1 << I2C_CMD_WR | 1 << I2C_CMD_IACK, pci_bar + REG_CMD); + + // Wait {A} + error = i2c_wait_ack(adapter, 30, 1); + if (error < 0) { + dev_dbg(&adapter->dev,"Repeat START Error: %d\n", error); + 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 || + size == I2C_SMBUS_I2C_BLOCK_DATA + )) { + + switch (size) { + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + cnt = 1; break; + case I2C_SMBUS_WORD_DATA: + cnt = 2; break; + case I2C_SMBUS_BLOCK_DATA: + /* will be changed after recived first data */ + cnt = 3; break; + case I2C_SMBUS_I2C_BLOCK_DATA: + cnt = data->block[0]; break; + default: + cnt = 0; break; + } + + info( "MS Receive"); + + for (bid = 0; bid < cnt; bid++) { + + // Start receive FSM + if (bid == cnt - 1) { + info( "READ NACK"); + iowrite8(1 << I2C_CMD_RD | 1 << I2C_CMD_ACK | 1 << I2C_CMD_IACK, pci_bar + REG_CMD); + }else{ + + iowrite8(1 << I2C_CMD_RD, pci_bar + REG_CMD); + } + + // Wait {A} + error = i2c_wait_ack(adapter, 30, 0); + if(nack_retry[master_bus - 1] == 1) + { + need_retry[master_bus - 1] = 1; + } + if (error < 0) { + dev_dbg(&adapter->dev,"Receive DATA Error: %d\n", error); + goto Done; + } + if(size == I2C_SMBUS_I2C_BLOCK_DATA){ + /* block[0] is read length */ + data->block[bid+1] = ioread8(pci_bar + REG_DATA); + info( "DATA IN [%d] %2.2X", bid+1, data->block[bid+1]); + }else { + data->block[bid] = ioread8(pci_bar + REG_DATA); + info( "DATA IN [%d] %2.2X", bid, data->block[bid]); + } + if (size == I2C_SMBUS_BLOCK_DATA && bid == 0) { + cnt = data->block[0] + 1; + } + } + } + +Done: + info( "MS STOP"); + // SET STOP + iowrite8( 1 << I2C_CMD_STO | 1 << I2C_CMD_IACK, pci_bar + REG_CMD); + // Wait for the STO to finish. + error_stop = i2c_wait_stop(adapter, 30, 0); + if (error_stop < 0) { + dev_dbg(&adapter->dev,"STOP Error: %d\n", error_stop); + } + check(pci_bar + REG_CTRL); + check(pci_bar + REG_STAT); +#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, retval = 0; + struct i2c_dev_data *dev_data; + unsigned char master_bus; + unsigned char switch_addr; + unsigned char channel; + unsigned char *calling_name; + uint16_t prev_port = 0; + unsigned char prev_switch; + unsigned char prev_ch; + uint8_t read_channel; + int retry = 0; + + 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; + calling_name = dev_data->pca9548.calling_name; + + // 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 + // Only select new channel of a switch if they are difference from last channel of a switch + 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", prev_ch, prev_switch, error); + } + + } + if(retry < 0){ + goto release_unlock; + } + // update lasted port + fpga_i2c_lasted_access_port[master_bus - 1] = switch_addr << 8 | channel; + + } 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", prev_ch, prev_switch, error); + } + } + if(retry < 0){ + goto release_unlock; + } + // update lasted port + fpga_i2c_lasted_access_port[master_bus - 1] = switch_addr << 8 | channel; + } + } + } + + // Do SMBus communication + nack_retry[master_bus - 1] = 0; + need_retry[master_bus - 1] = 0; + error = smbus_access(adapter, addr, flags, rw, cmd, size, data); + if((nack_retry[master_bus - 1]==1)&&(need_retry[master_bus - 1]==1)) + retry = 2000; + else + retry = 5; + // If the first access failed, do retry. + while((nack_retry[master_bus - 1]==1)&&retry) + { + retry--; + nack_retry[master_bus - 1] = 0; + dev_dbg(&adapter->dev,"error = %d\n",error); + error = smbus_access(adapter, addr, flags, rw, cmd, size, data); + dev_dbg(&adapter->dev,"nack retry = %d\n",retry); + } + nack_retry[master_bus - 1] = 0; + need_retry[master_bus - 1] = 0; + + retval = error; + + 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); + }else{ + goto release_unlock; + } + + /** For the bus with PCA9548, try to read PCA9548 one more time. + * For the bus w/o PCA9548 just check the return from last time. + */ + if (switch_addr != 0xFF) { + error = smbus_access(adapter, switch_addr, flags, I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE, (union i2c_smbus_data*)&read_channel); + dev_dbg(&adapter->dev,"Try access I2C switch device at %2.2x\n", switch_addr); + if(error < 0){ + dev_dbg(&adapter->dev,"Unbale to access switch device.\n"); + }else{ + dev_dbg(&adapter->dev,"Read success, register val %2.2x\n", read_channel); + } + } + + // If retry was used up(retry = 0) and the last transfer result is -EBUSY + if(retry <= 0 && error == -EBUSY ){ + retval = error; + // raise device error message + dev_err(&adapter->dev, "I2C bus hangup detected on %s port.\n", calling_name); + + /** + * Fishbone2: Device specific I2C reset topology + */ + if( master_bus == I2C_MASTER_CH_11 ){ + dev_notice(&adapter->dev, "Trying bus recovery...\n"); + dev_notice(&adapter->dev, "Reset I2C switch device.\n"); + + // reset PCA9548 on the current BUS. + iowrite8( ioread8(fpga_dev.data_base_addr + 0x0108) & 0xF0, fpga_dev.data_base_addr + 0x0108); + udelay(1); + iowrite8( ioread8(fpga_dev.data_base_addr + 0x0108) | 0x0F, fpga_dev.data_base_addr + 0x0108); + // clear the last access port + fpga_i2c_lasted_access_port[master_bus - 1] = 0; + }else{ + dev_crit(&adapter->dev, "I2C bus unrecoverable.\n"); + } + } + + +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 retval; +} + +/** + * 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| + I2C_FUNC_SMBUS_I2C_BLOCK; +} + +static const struct i2c_algorithm fishbone2_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 * fishbone2_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; + + 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 = &fishbone2_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_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; +}; + +// I/O resource need. +static struct resource fishbone2_resources[] = { + { + .start = 0x10000000, + .end = 0x10001000, + .flags = IORESOURCE_MEM, + }, +}; + +static void fishbone2_dev_release( struct device * dev) +{ + return; +} + +static struct platform_device fishbone2_dev = { + .name = DRIVER_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(fishbone2_resources), + .resource = fishbone2_resources, + .dev = { + .release = fishbone2_dev_release, + } +}; + +/** + * Board info for QSFP/SFP+ eeprom. + * Note: Using OOM optoe as transceiver 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 fishbone2_drv_probe(struct platform_device *pdev) +{ + struct resource *res; + 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 fishbone2_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]); + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (unlikely(!res)) { + printk(KERN_ERR "Specified Resource Not Available...\n"); + kzfree(fpga_data); + return -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 = I2C_MASTER_CH_1; portid_count <= I2C_MASTER_CH_TOTAL; portid_count++){ + if(!allow_unsafe_i2c_access){ + if( portid_count < I2C_MASTER_CH_7 || + portid_count == I2C_MASTER_CH_9 || portid_count == I2C_MASTER_CH_10 ) + continue; + } + ret = i2c_core_init(portid_count, I2C_DIV_100K, fpga_dev.data_base_addr); + if (ret < 0) { + dev_err(&pdev->dev, "Unable to init I2C core %d\n", portid_count); + 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++) { + if(!allow_unsafe_i2c_access){ + if( portid_count >= FAN_I2C_CPLD_INDEX && portid_count < SW_I2C_CPLD_INDEX ){ + fpga_data->i2c_adapter[portid_count] = NULL; + continue; + } + } + fpga_data->i2c_adapter[portid_count] = fishbone2_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] = fishbone2_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"); + } + } + + printk(KERN_INFO "Virtual I2C buses created\n"); + +#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++) { + + if(!allow_unsafe_i2c_access){ + if( portid_count >= FAN_I2C_CPLD_INDEX && portid_count < SW_I2C_CPLD_INDEX ){ + continue; + } + } + + 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 fishbone2_drv_remove(struct platform_device *pdev) +{ + int portid_count; + struct sff_device_data *rem_data; + struct i2c_dev_data *adap_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]); + adap_data = i2c_get_adapdata(fpga_data->i2c_adapter[portid_count]); + i2c_del_adapter(fpga_data->i2c_adapter[portid_count]); + } + } + + for (portid_count = I2C_MASTER_CH_1; portid_count <= I2C_MASTER_CH_TOTAL; portid_count++){ + if(!allow_unsafe_i2c_access){ + if( portid_count < I2C_MASTER_CH_7 || + portid_count == I2C_MASTER_CH_9 || portid_count == I2C_MASTER_CH_10 ) + continue; + } + i2c_core_deinit(portid_count, fpga_dev.data_base_addr); + } + + 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; +} + +static struct platform_driver fishbone2_drv = { + .probe = fishbone2_drv_probe, + .remove = __exit_p(fishbone2_drv_remove), + .driver = { + .name = DRIVER_NAME, + }, +}; + +#ifdef TEST_MODE +#define FPGA_PCI_BAR_NUM 2 +#else +#define FPGA_PCI_BAR_NUM 0 +#endif + + + +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 = ioremap_nocache(fpga_dev.data_mmio_start, fpga_dev.data_mmio_len); + 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(&fishbone2_dev); + platform_driver_register(&fishbone2_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(&fishbone2_drv); + platform_device_unregister(&fishbone2_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 fishbone2_init(void) +{ + int rc; + rc = pci_register_driver(&pci_dev_ops); + if (rc) + return rc; + return 0; +} + +void fishbone2_exit(void) +{ + pci_unregister_driver(&pci_dev_ops); +} + +module_init(fishbone2_init); +module_exit(fishbone2_exit); + +module_param(allow_unsafe_i2c_access, bool, 0400); +MODULE_PARM_DESC(allow_unsafe_i2c_access, "enable i2c busses despite potential races against BMC bus access"); + +MODULE_AUTHOR("Pradchaya P. "); +MODULE_DESCRIPTION("Celestica Fishbone2 switchboard platform driver"); +MODULE_VERSION(MOD_VERSION); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/shamu/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-cel/shamu/scripts/platform_sensors.py new file mode 100755 index 000000000000..186ee6c5450e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/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/platform/broadcom/sonic-platform-modules-cel/shamu/scripts/sensors b/platform/broadcom/sonic-platform-modules-cel/shamu/scripts/sensors new file mode 100755 index 000000000000..405d92c2b3cc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/scripts/sensors @@ -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 pmon sensors "$@" +docker exec -$DOCKER_EXEC_FLAGS pmon platform_sensors.py "$@" diff --git a/platform/broadcom/sonic-platform-modules-cel/shamu/setup.py b/platform/broadcom/sonic-platform-modules-cel/shamu/setup.py new file mode 100644 index 000000000000..20a2b6d1063a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/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/shamu/sonic_platform.egg-info/PKG-INFO b/platform/broadcom/sonic-platform-modules-cel/shamu/sonic_platform.egg-info/PKG-INFO new file mode 100644 index 000000000000..48ce1ea303bb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/sonic_platform.egg-info/PKG-INFO @@ -0,0 +1,23 @@ +Metadata-Version: 1.2 +Name: sonic-platform +Version: 1.0 +Summary: SONiC platform API implementation on Celestica Platforms +Home-page: https://github.com/Azure/sonic-buildimage +Author: SONiC Team +Author-email: linuxnetdev@microsoft.com +Maintainer: Wirut Getbamrung +Maintainer-email: wgetbumr@celestica.com +License: Apache 2.0 +Description: UNKNOWN +Keywords: sonic SONiC platform PLATFORM +Platform: UNKNOWN +Classifier: Development Status :: 3 - Alpha +Classifier: Environment :: Plugins +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: Information Technology +Classifier: Intended Audience :: System Administrators +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Natural Language :: English +Classifier: Operating System :: POSIX :: Linux +Classifier: Programming Language :: Python :: 2.7 +Classifier: Topic :: Utilities diff --git a/platform/broadcom/sonic-platform-modules-cel/shamu/sonic_platform.egg-info/SOURCES.txt b/platform/broadcom/sonic-platform-modules-cel/shamu/sonic_platform.egg-info/SOURCES.txt new file mode 100644 index 000000000000..f14add75ab6f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/sonic_platform.egg-info/SOURCES.txt @@ -0,0 +1,11 @@ +setup.py +../../../../device/celestica/x86_64-cel_silverstone-r0/sonic_platform/__init__.py +../../../../device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py +../../../../device/celestica/x86_64-cel_silverstone-r0/sonic_platform/eeprom.py +../../../../device/celestica/x86_64-cel_silverstone-r0/sonic_platform/fan.py +../../../../device/celestica/x86_64-cel_silverstone-r0/sonic_platform/helper.py +../../../../device/celestica/x86_64-cel_silverstone-r0/sonic_platform/platform.py +sonic_platform.egg-info/PKG-INFO +sonic_platform.egg-info/SOURCES.txt +sonic_platform.egg-info/dependency_links.txt +sonic_platform.egg-info/top_level.txt \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/shamu/sonic_platform.egg-info/dependency_links.txt b/platform/broadcom/sonic-platform-modules-cel/shamu/sonic_platform.egg-info/dependency_links.txt new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/sonic_platform.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/platform/broadcom/sonic-platform-modules-cel/shamu/sonic_platform.egg-info/top_level.txt b/platform/broadcom/sonic-platform-modules-cel/shamu/sonic_platform.egg-info/top_level.txt new file mode 100644 index 000000000000..82b4b6958796 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/sonic_platform.egg-info/top_level.txt @@ -0,0 +1 @@ +sonic_platform diff --git a/platform/broadcom/sonic-platform-modules-cel/shamu/systemd/platform-modules-shamu.service b/platform/broadcom/sonic-platform-modules-cel/shamu/systemd/platform-modules-shamu.service new file mode 100644 index 000000000000..236eba0bd5ec --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/shamu/systemd/platform-modules-shamu.service @@ -0,0 +1,14 @@ + +[Unit] +Description=Celestica shamu platform modules +After=local-fs.target +Before=pmon.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-shamu start +ExecStop=-/etc/init.d/platform-modules-shamu stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/afulnx_64 b/platform/broadcom/sonic-platform-modules-cel/tools/afulnx_64 deleted file mode 100755 index c32823393c08..000000000000 Binary files a/platform/broadcom/sonic-platform-modules-cel/tools/afulnx_64 and /dev/null differ diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/bmc_wdt/bmc_wdt.py b/platform/broadcom/sonic-platform-modules-cel/tools/bmc_wdt/bmc_wdt.py new file mode 100644 index 000000000000..e22d96326b76 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/tools/bmc_wdt/bmc_wdt.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python + +############################################################################# +# # +# Service to control CPU watchdog # +# # +############################################################################# + +import os +import time +import logging +import logging.handlers +import requests +import argparse +import subprocess + +HEARTBEAT_TIME = 20 +MAX_FILE_COUNT = 3 +WDT_TIMEOUT = 60 +MAX_LOG_BYTES = 20 * 1000000 +HOSTNAME = "240.1.1.1" +WDT_URL = "http://240.1.1.1:8080/api/sys/watchdog" +BMC_WDT_LOG = '/var/log/bmc_feed_watchdog.log' + + +lh = logging.handlers.RotatingFileHandler( + filename=BMC_WDT_LOG, maxBytes=MAX_LOG_BYTES, backupCount=MAX_FILE_COUNT) +formatter = logging.Formatter( + fmt='%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%b %d %H:%M:%S') +lh.setFormatter(formatter) +logger = logging.getLogger('bmc_feed_watchdog') +logger.addHandler(lh) +logger.setLevel(logging.INFO) + + +def set_wdt_timeout(timeout): + data = dict() + data["wdt"] = str(timeout) + status_code = -1 + message = None + try: + res = requests.post(WDT_URL, json=data, timeout=5) + status_code = res.status_code + message = res.json().get('result') + except: + message = "Unable set watchdog timeout" + + return status_code, message + + +def ping(): + try: + response = subprocess.check_output( + ['ping', '-c', '3', HOSTNAME], + stderr=subprocess.STDOUT, + universal_newlines=True + ) + except subprocess.CalledProcessError: + response = None + return response != None + + +def start(): + logger.info("Started CPU watchdog") + error_flag = 1 + status_code = -1 + while True: + status_code, message = set_wdt_timeout(WDT_TIMEOUT) + + # Error checking + if status_code == 200 and message != 'success': + logger.error(message) + error_flag = 1 + elif status_code != 200 and not ping(): + logger.error("Unable to connect to BMC") + error_flag = 1 + elif status_code != 200 and ping(): + if not error_flag: + logger.error(message) + time.sleep(1) + error_flag = 1 + continue + + # Pass error + if error_flag and status_code == 200 and message == 'success': + error_flag = 0 + logger.info("BMC connection successful") + + time.sleep(HEARTBEAT_TIME) + + +def stop(): + logger.info("Stopping CPU watchdog") + status_code = -1 + while status_code != 200: + status_code, message = set_wdt_timeout(0) + if status_code == 200 and message != 'success': + logger.error(message) + elif status_code != 200 and not ping(): + logger.error("Unable to connect to BMC") + elif ping(): + time.sleep(1) + continue + + logger.info("Stopped CPU watchdog") + + +def main(): + parser = argparse.ArgumentParser(description='') + parser.add_argument('option', choices=["start", "stop"]) + args = parser.parse_args() + if args.option == "start": + start() + stop() + + +if __name__ == "__main__": + main() diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/bmc_wdt/bmc_wdt.service b/platform/broadcom/sonic-platform-modules-cel/tools/bmc_wdt/bmc_wdt.service new file mode 100755 index 000000000000..88c3b5ceb44b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/tools/bmc_wdt/bmc_wdt.service @@ -0,0 +1,10 @@ +[Unit] +Description=Service for enable BMC watchdog. +After=bmc_vlan.service + +[Service] +ExecStart=/usr/bin/python /usr/local/etc/bmc_wdt.py start +ExecStop=/usr/bin/python /usr/local/etc/bmc_wdt.py stop + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/bmcutil/bmc-exec b/platform/broadcom/sonic-platform-modules-cel/tools/bmcutil/bmc-exec new file mode 100755 index 000000000000..14435e857ff9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/tools/bmcutil/bmc-exec @@ -0,0 +1,45 @@ +#!/bin/bash +# +# Copyright 2019-present Celestica. All Rights Reserved. +# +# This program file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# + +PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin + +command="$@" + +usage() { + echo "Usage: bmc-exec " + echo +} + +run_cmd() { + echo "Run command: "$command + echo + ret=$(curl -m 5 --silent --header "Content-Type:application/json" -d "{\"data\": \"${command}\"}" http://240.1.1.1:8080/api/sys/raw) + if [ -z "$ret" ]; + then + echo "Failed to connect on BMC" + else + echo $ret | python -c "import sys, json; k = json.load(sys.stdin)['result']; print k if type(k) is not list else '\n'.join(k);" + fi + return 0 +} + +if [ $# -lt 1 ]; then + usage + exit -1 +else + run_cmd +fi + +exit $? diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/bmcutil/bmcpwd b/platform/broadcom/sonic-platform-modules-cel/tools/bmcutil/bmcpwd new file mode 100644 index 000000000000..3e24c6b13536 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/tools/bmcutil/bmcpwd @@ -0,0 +1 @@ +kt3I0K_QxQ== \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/bmcutil/bmcutil.py b/platform/broadcom/sonic-platform-modules-cel/tools/bmcutil/bmcutil.py new file mode 100644 index 000000000000..7edc55ac8862 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/tools/bmcutil/bmcutil.py @@ -0,0 +1,296 @@ +#!/usr/bin/python + +""" +bmcutil.py +BMC utility, implements management functions provided by BMC RESTful APIs. +""" + +import requests +import re +import hashlib +import binascii +import os +import base64 + + +# Base class of BmcUtil +class BmcUtilBase(object): + def __init__(self): + self.bmc_info_url = "http://240.1.1.1:8080/api/sys/bmc" + self.bmc_eth_info_url = "http://240.1.1.1:8080/api/sys/eth" + self.bmc_raw_command_url = "http://240.1.1.1:8080/api/sys/raw" + self.bmc_pwd_url = "http://240.1.1.1:8080/api/sys/userpassword" + self.bmc_pwd_path = "/usr/local/etc/bmcpwd" + self.bmc_syslog_url = "http://240.1.1.1:8080/api/sys/syslog" + + def request_data(self, url): + # Reqest data from BMC if not exist. + data_req = requests.get(url) + data_json = data_req.json() + data_list = data_json.get('Information') + return data_list + + def save_bmc_password(self, clear_pwd): + enc = [] + key = "bmc" + for i in range(len(clear_pwd)): + key_c = key[i % len(key)] + enc_c = chr((ord(clear_pwd[i]) + ord(key_c)) % 256) + enc.append(enc_c) + enc_pwd = base64.urlsafe_b64encode("".join(enc)) + + with open(self.bmc_pwd_path, 'w') as file: + file.write(enc_pwd) + + def get_bmc_pass(self): + with open(self.bmc_pwd_path) as file: + data = file.read() + + key = "bmc" + dec = [] + enc = base64.urlsafe_b64decode(data) + for i in range(len(enc)): + key_c = key[i % len(key)] + dec_c = chr((256 + ord(enc[i]) - ord(key_c)) % 256) + dec.append(dec_c) + return "".join(dec) + + def version(self): + """ + Return version information string + @return version string of BMC OS + """ + bmc_version = None + + bmc_version_key = "OpenBMC Version" + bmc_info = self.request_data(self.bmc_info_url) + bmc_version = bmc_info.get(bmc_version_key) + + return str(bmc_version) + + def set_eth0_addr(self, ip_addr, mask): + """ + Set eth0 IPv4 address + @ip_addr MANDATORY, IPv4 ip address string + @mask MANDATORY, IPv4 network mask string + """ + + json_data = dict() + json_data["data"] = "ifconfig eth0 %s netmask %s up" % (ip_addr, mask) + r = requests.post(self.bmc_raw_command_url, json=json_data) + if r.status_code != 200: + return False + return True + + def get_eth0_addr_list(self): + """ + Get eth0 IPv4 address + @return a list of (IPv4 ip address/mask string) + """ + ipv4_adress = [] + eth_data_list = self.request_data(self.bmc_eth_info_url) + + for eth_data in eth_data_list: + if 'inet addr' in eth_data: + ipv4_list = re.findall(r'[0-9]+(?:\.[0-9]+){3}', eth_data) + if len(ipv4_list) == 3: + ipv4 = ipv4_list[0] + "/" + ipv4_list[2] + ipv4_adress.append(ipv4) + + return str(ipv4_adress) + + def set_gateway_ip(self, gw_ip): + """ + Set gateway IPv4 address string + @gw_ip MANATORY, IPv4 address of gateway + """ + + json_data = dict() + json_data["data"] = "route del default" + + r = requests.post(self.bmc_raw_command_url, json=json_data) + if r.status_code != 200: + return False + + json_data["data"] = "route add default gw %s" % gw_ip + r = requests.post(self.bmc_raw_command_url, json=json_data) + if r.status_code != 200: + return False + + return True + + def get_gateway_ip(self): + """ + Get gateway IPv4 address string + @return IPv4 address of gateway + """ + + default_gw = None + + json_data = dict() + json_data["data"] = "route" + + r = requests.post(self.bmc_raw_command_url, json=json_data) + if r.status_code == 200: + data_list = r.json().get('result') + for raw_data in data_list: + if 'default' in raw_data: + route_data = raw_data.split() + default_gw = route_data[1] if len(route_data) > 0 else None + + return str(default_gw) + + def set_user_and_passwd(self, user_name, password): + """ + Set BMC user name and password + @user_name MANDATORY, BMC user + @password MANDATORY, BMC user's password + """ + json_data = dict() + json_data["user"] = str(user_name) + json_data["oldpassword"] = self.get_bmc_pass() + json_data["newpassword"] = password + r = requests.post(self.bmc_pwd_url, json=json_data) + return_data = r.json() + + if r.status_code != 200 or 'success' not in return_data.get('result'): + return False + + self.save_bmc_password(password) + return True + + def add_syslog_server(self, svr_ip, svr_port): + """ + Add syslog server for BMC + @svr_ip MANDATORY, syslog server IP string + @svr_port MANDATORY, syslog server destination port + """ + json_data = dict() + json_data["addr"] = str(svr_ip) + json_data["port"] = str(svr_port) + r = requests.post(self.bmc_syslog_url, json=json_data) + if r.status_code != 200 or 'success' not in r.json().get('result'): + return False + return True + + def get_syslog_server_list(self): + """ + # Get syslog server list of BMC + # @return a list of syslog server ip and destination port pair + """ + syslog_ip = None + syslog_port = None + + json_data = dict() + json_data["data"] = "tail -n 1 /etc/rsyslog.conf" + r = requests.post(self.bmc_raw_command_url, json=json_data) + if r.status_code != 200: + return False + + return_data = r.json() + result = return_data.get("result") + ip = re.findall(r'[0-9]+(?:\.[0-9]+){3}', result[0]) + port = str(result[0]).split(":") + syslog_ip = ip[0] if len(ip) > 0 else None + syslog_port = port[1] if len(port) > 1 else None + + return [syslog_ip, syslog_port] + + def del_syslog_server(self, svr_ip, svr_port): + """ + Delete syslog server for BMC + @svr_ip MANDATORY, syslog server IP string + @svr_port MANDATORY, syslog server destination port + """ + json_data = dict() + json_data["addr"] = "127.0.0.1" + json_data["port"] = str(svr_port) + r = requests.post(self.bmc_syslog_url, json=json_data) + if r.status_code != 200 or 'success' not in r.json().get('result'): + return False + return True + + def get_bmc_system_state(self): + """ + Get BMC system state, includes CPU, memory, storage + MUST contains status of: CPU, memory, disk + dict object: + { + "CPU": { + "StateOutputs": "output of command 'top -bn 1'" + "Usage": "10.0" + }, + "MEMORY": { + "StateOutputs": "output of command 'free -m'" + "Usage": "15.0" # caculate: "free -t | grep \"buffers/cache\" | awk '{ printf \"mem usage : %.1f%%\\n\",$3/($3+$4) * 100}'" + }, + "DISK": { + "StateOutput": "output of command 'df -h'" + "Usage": "12.5" + } + } + """ + + state_data = dict() + bmc_info = self.request_data(self.bmc_info_url) + + cpu_key = "CPU Usage" + cpu_data_raw = bmc_info.get(cpu_key) + cpu_usage = cpu_data_raw.split()[1].strip('%') + cpu_data = dict() + cpu_data["StateOutputs"] = "output of command 'top -bn 1'" + cpu_data["Usage"] = "{:.1f}".format(float(cpu_usage)) + state_data["CPU"] = cpu_data + + disk_key = "Disk Usage" + disk_data_raw = bmc_info.get(disk_key) + disk_usage = disk_data_raw.split()[7].strip('%') + disk_data = dict() + disk_data["StateOutputs"] = "output of command 'df -h'" + disk_data["Usage"] = "{:.1f}".format(float(disk_usage)) + state_data["DISK"] = disk_data + + json_data = dict() + json_data["data"] = "free -t" + mem_usage = "None" + r = requests.post(self.bmc_raw_command_url, json=json_data) + if r.status_code == 200: + mem_data_raw = r.json().get('result')[2] + mem_u = float(mem_data_raw.split()[2]) + mem_f = float(mem_data_raw.split()[3]) + mem_usage = (mem_u/(mem_u+mem_f)) * 100 + mem_data = dict() + mem_data["StateOutputs"] = "output of command 'free -t'" + mem_data["Usage"] = "{:.1f}".format(mem_usage) + state_data["MEMORY"] = mem_data + + return state_data + + def reboot_bmc(self): + """ + Reboot BMC + """ + json_data = dict() + json_data["data"] = "reboot" + r = requests.post(self.bmc_raw_command_url, json=json_data) + if r.status_code != 200: + return False + + return True + + def set_location_led(self, admin_state): + """ + Enable/disable location LED + @admin_state MANDATORY, should be string "on" or "off" + """ + + json_data = dict() + if str(admin_state).lower() not in ["on", "off"]: + return False + + json_data["data"] = "led_location.sh %s" % admin_state + r = requests.post(self.bmc_raw_command_url, json=json_data) + if r.status_code != 200: + return False + + return True diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/fpga_prog/fpga_prog b/platform/broadcom/sonic-platform-modules-cel/tools/fpga_prog/fpga_prog new file mode 100755 index 000000000000..edf7916e58b7 Binary files /dev/null and b/platform/broadcom/sonic-platform-modules-cel/tools/fpga_prog/fpga_prog differ diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/fpga_prog/fpga_prog.c b/platform/broadcom/sonic-platform-modules-cel/tools/fpga_prog/fpga_prog.c new file mode 100644 index 000000000000..c640c8ad0064 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/tools/fpga_prog/fpga_prog.c @@ -0,0 +1,282 @@ +/******************************************************************** +Author: Sittisak Sinprem + flash_spi_fpga + + user-space appliction to flash SPI FLASH + + As a "root" previledge, this program can run well + while other user group would report system errors under Linux OS. + +*********************************************************************/ + +#include +#include +#include +#include //for open() +#include //for close() +#include +#include + +/** + * The FPGA SPI Flash update application + * This application read the binary image file and program + * into flash memory. The erasing time can be long the + * the WAIT_WRITE_READY_SEC should be more than 30 seconds. + */ + +#define WAIT_WRITE_READY_SEC 180 +#define WAIT_WRITE_CONTINUE_CYCLE 100000 + +#define REG_SPI_WR_EN 0x1200 +#define REG_SPI_WR_DAT 0x1204 +#define REG_SPI_CHK_ID 0x1208 +#define REG_SPI_VERIFY 0x120C +#define REG_SPI_STAT 0x1210 +#define REG_SPI_RESET 0x1214 + +#define SPI_STAT_MARK_READY (1 << 15) +#define SPI_STAT_MARK_DONE (1 << 14) +#define SPI_STAT_MARK_ERROR_ANY (1 << 13) +#define SPI_STAT_MARK_ERROR_CHKID (1 << 12) +#define SPI_STAT_MARK_ERROR_ERASE (1 << 11) +#define SPI_STAT_MARK_ERROR_PROG (1 << 10) +#define SPI_STAT_MARK_ERROR_TOUT (1 << 9) +#define SPI_STAT_MARK_ERROR_CRC (1 << 8) +#define SPI_STAT_MARK_STG_STARTED (1 << 7) +#define SPI_STAT_MARK_STG_INITED (1 << 6) +#define SPI_STAT_MARK_STG_CHECKED_ID (1 << 5) +#define SPI_STAT_MARK_STG_ERSD_SW (1 << 4) +#define SPI_STAT_MARK_STG_UP_ERSD_IMG (1 << 3) +#define SPI_STAT_MARK_STG_UP_PRG_IMG (1 << 2) +#define SPI_STAT_MARK_STG_VERIFIED (1 << 1) +#define SPI_STAT_MARK_STG_PRG_CMPT (1 << 0) + +#define debug(fmt,args...) printf("debug : "fmt"\n",##args) +#define reg_write(reg,value) func_write(reg,value) +#define reg_read(reg,value) value = func_read(reg) + +#define DEV_CHAR_FILENAME "/dev/fwupgrade" + +struct fpga_reg_data { + uint32_t reg; + uint32_t value; +}; + +enum{ + READREG, + WRITEREG +}; + +unsigned int func_write(int addr,unsigned long value){ + int fd; + int ret; + struct fpga_reg_data fpga_reg; + + fd = open(DEV_CHAR_FILENAME, O_RDWR); + + fpga_reg.reg = addr; + fpga_reg.value = value; + + ioctl(fd, WRITEREG, (void *)&fpga_reg); + + close(fd); + return 0; +} + +unsigned int func_read(int addr){ + int fd; + int ret; + + struct fpga_reg_data fpga_reg; + + fd = open(DEV_CHAR_FILENAME, O_RDWR); + + fpga_reg.reg = addr; + + ioctl(fd, READREG, (void *)&fpga_reg); + + close(fd); + return fpga_reg.value; +} + +void dump_status(int Stat){ + debug("#########################"); + debug("%d ready(1)/busy(0)", (Stat&SPI_STAT_MARK_READY)!=0); + debug("%d done", (Stat&SPI_STAT_MARK_DONE)!=0); + debug("%d error any", (Stat&SPI_STAT_MARK_ERROR_ANY)!=0); + debug("%d error checkId", (Stat&SPI_STAT_MARK_ERROR_CHKID)!=0); + debug("%d error erase", (Stat&SPI_STAT_MARK_ERROR_ERASE)!=0); + debug("%d error program", (Stat&SPI_STAT_MARK_ERROR_PROG)!=0); + debug("%d error timeout", (Stat&SPI_STAT_MARK_ERROR_TOUT)!=0); + debug("%d error crc", (Stat&SPI_STAT_MARK_ERROR_CRC)!=0); + debug("%d stage started", (Stat&SPI_STAT_MARK_STG_STARTED)!=0); + debug("%d stage inited", (Stat&SPI_STAT_MARK_STG_INITED)!=0); + debug("%d stage checked id", (Stat&SPI_STAT_MARK_STG_CHECKED_ID)!=0); + debug("%d stage erasred", (Stat&SPI_STAT_MARK_STG_ERSD_SW)!=0); + debug("%d stage upload erase img", (Stat&SPI_STAT_MARK_STG_UP_ERSD_IMG)!=0); + debug("%d stage upload program img",(Stat&SPI_STAT_MARK_STG_UP_PRG_IMG)!=0); + debug("%d stage verified", (Stat&SPI_STAT_MARK_STG_VERIFIED)!=0); + debug("%d stage completed", (Stat&SPI_STAT_MARK_STG_PRG_CMPT)!=0); +} + +int flash_program(char *data,int lens){ + int ctimeout; + int error =0; + unsigned long Stat = 0; + + reg_read(REG_SPI_RESET,Stat); + printf("Read Reset is %x\n",Stat); + printf("Reset Module \n"); + reg_write(REG_SPI_RESET,0x1); // reset + sleep(1); + reg_write(REG_SPI_RESET,0x0); // normal mode + ctimeout=0; + do{ // wait for done flag + reg_read(REG_SPI_STAT,Stat); + if(Stat & SPI_STAT_MARK_ERROR_ANY){ + dump_status(Stat); + error = Stat; + break; + } + if(ctimeout++ > WAIT_WRITE_READY_SEC){ + error = Stat| SPI_STAT_MARK_ERROR_TOUT; + debug("wait ready timeout . . ."); + break; + } + printf(" waiting status to ready ... %d s. status = %x\n",ctimeout,Stat); + sleep(1); + }while((Stat & 0x80F8) != 0x80F8); + if(error){ + return -1; + } + printf("Ready\n"); + + + for(int i=0;i WAIT_WRITE_CONTINUE_CYCLE){ + error = Stat| SPI_STAT_MARK_ERROR_TOUT; + debug("wait ready timeout . . ."); + break; + } + }while((Stat & 0x80F8) != 0x80F8); + + if(error){ + printf("FPGA programing fail at %d/%d\n",i,lens); + debug("Status = %4.4X",error); + break; + } + + i +=4; + + if(i%(lens/40*4)==0){ + printf("FPGA programing . . . %d/%d\n",i,lens); + } + } + + dump_status(Stat); + printf("Status = %4.4X\n",Stat); + + reg_write(REG_SPI_WR_EN,0x0); // write protect + reg_write(REG_SPI_RESET,0x1); // module reset + + return error; +} + +int main(int argc,char **argv){ + FILE *pFILE; + int filesize; + char *filename; + char *fpga_buff; + int status; + int max_size = 128; + int current_size = max_size; + int i = 0; + int c = EOF; + + printf(" FPGA PROGRAMMNG version 0.1.1 \n"); + printf(" build date : %s %s\n",__DATE__,__TIME__); + + filename = NULL; + filename = malloc(max_size); + if(!filename){ + exit(-12); /* Out of memory */ + } + + if(argc<2){ + printf("please enter filename : "); + while((c = getchar()) != '\n' && c != EOF ){ + + filename[i++] = (char)c; + if(i == current_size){ + current_size += max_size; + filename = realloc(filename, current_size); + } + } + filename[i] = '\0'; + }else{ + i = strlen(argv[1]) + 1; + filename = realloc(filename, i); + strcpy(filename, argv[1]); + } + + pFILE = fopen(filename,"rb"); + free(filename); + if (pFILE == NULL) + { + printf("Could not open the file %s, exit\n",filename); + return -5; + } + + fseek(pFILE , 0 , SEEK_END); + filesize = ftell (pFILE); + rewind(pFILE); + fpga_buff = malloc(filesize); + if(fpga_buff==NULL){ + printf("Can't Allocate memory \n"); + return -5; + } + + fread(fpga_buff,1,filesize,pFILE); + fclose(pFILE); + + printf(" Start FPGA Flash ... \n"); + + status = flash_program(fpga_buff,filesize); + + if(status == 0){ + printf(" Programing finish \n"); + }else{ + printf(" Program Error : error code %4.4x \n",status); + } + + return status; +} diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/ispvme_12.2/Makefile b/platform/broadcom/sonic-platform-modules-cel/tools/ispvme_12.2/Makefile new file mode 100644 index 000000000000..022bcc566c6d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/tools/ispvme_12.2/Makefile @@ -0,0 +1,25 @@ +CC = gcc +AR = ar +CFLAGS = -Wall -W -Wunused -lpthread -g -O2 -ggdb +#LFLAGS = -lm -pthread -DVME_DEBUG +LFLAGS = -lm -pthread +DEL_FILE = rm -f +MV_FILE = mv -f +OBJ_FILE_NODE = ./*.o +#VPATH = +INCPATH = -I../include/ +TARGET = ispvm + +OBJECTS += hardware.o ispvm_ui.o ivm_core.o + + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< +$(TARGET):$(OBJECTS) + $(CC) $(LFLAGS) -o $(TARGET) $(OBJECTS) + +clean: + -$(DEL_FILE) $(TARGET) + -$(DEL_FILE) $(OBJ_FILE_NODE) + + diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/ispvme_12.2/hardware.c b/platform/broadcom/sonic-platform-modules-cel/tools/ispvme_12.2/hardware.c new file mode 100644 index 000000000000..7a4d5f5456d3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/tools/ispvme_12.2/hardware.c @@ -0,0 +1,409 @@ +/********************************************************************************* +* Lattice Semiconductor Corp. Copyright 2000-2008 +* +* This is the hardware.c of ispVME V12.1 for JTAG programmable devices. +* All the functions requiring customization are organized into this file for +* the convinience of porting. +*********************************************************************************/ +/********************************************************************************* + * Revision History: + * + * 09/11/07 NN Type cast mismatch variables + * 09/24/07 NN Added calibration function. + * Calibration will help to determine the system clock frequency + * and the count value for one micro-second delay of the target + * specific hardware. + * Modified the ispVMDelay function + * Removed Delay Percent support + * Moved the sclock() function from ivm_core.c to hardware.c + *********************************************************************************/ +#include "vmopcode.h" +#include +#include +#include //for open() +#include //for close() +#include +#include +#include + +/******************************************************************************** +* Declaration of global variables +* +*********************************************************************************/ +static int devmem_c2, devmem_c5; +static void *portC2, *portC5; + +/** + * NOTE: Using only core GPIO here + * FIXME: This should move to config section and support both CORE and SUS region. + */ + +// unsigned long g_siIspPins = 0x00000000; /*Keeper of JTAG pin state*/ +unsigned short g_usCpu_Frequency = CPU_FREQ_MH_CONFIG; /*Enter your CPU frequency here, unit in MHz.*/ + +/********************************************************************************* +* This is the definition of the bit locations of each respective +* signal in the global variable g_siIspPins. +* +* NOTE: Users must add their own implementation here to define +* the bit location of the signal to target their hardware. +* The example below is for the Lattice download cable on +* on the parallel port. +* +*********************************************************************************/ + + +unsigned long g_ucPinTDI = GPIO_TDI_CONFIG; /* Pin nummber of TDI */ +unsigned long g_ucPinTCK = GPIO_TCK_CONFIG; /* Pin nummber of TCK */ +unsigned long g_ucPinTMS = GPIO_TMS_CONFIG; /* Pin nummber of TMS */ +unsigned long g_ucPinENABLE = GPIO_ENABLE_CONFIG; /* Pin nummber of ENABLE */ +unsigned long g_ucPinTRST = GPIO_TRST_CONFIG; /* Pin nummber of TRST */ +unsigned long g_ucPinTDO = GPIO_TDO_CONFIG; /* Pin nummber of TDO */ +unsigned long g_ucInPort = GP_LVL; /* All TCI,TDO,TMS,TCK are on same register */ +unsigned long g_ucOutPort = GP_LVL; /* All TCI,TDO,TMS,TCK are on same register */ + +/* For Denverton CPU */ +// const unsigned long g_ucPinTDI = DNV_GPIO_TDI_CONFIG; +// const unsigned long g_ucPinTCK = DNV_GPIO_TCK_CONFIG; +// const unsigned long g_ucPinTMS = DNV_GPIO_TMS_CONFIG; +// const unsigned long g_ucPinTDO = DNV_GPIO_TDO_CONFIG; + +/*************************************************************** +* +* Functions declared in hardware.c module. +* +***************************************************************/ +void writePort( unsigned long a_ucPins, unsigned char a_ucValue ); +unsigned char readPort(); +void sclock(); +void ispVMDelay( unsigned short a_usTimeDelay ); +void calibration(void); + +/******************************************************************************** +* writePort +* To apply the specified value to the pins indicated. This routine will +* be modified for specific systems. +* As an example, this code uses the IBM-PC standard Parallel port, along with the +* schematic shown in Lattice documentation, to apply the signals to the +* JTAG pins. +* +* PC Parallel port pin Signal name Port bit address +* 2 g_ucPinTDI 1 +* 3 g_ucPinTCK 2 +* 4 g_ucPinTMS 4 +* 5 g_ucPinENABLE 8 +* 6 g_ucPinTRST 16 +* 10 g_ucPinTDO 64 +* +* Parameters: +* - a_ucPins, which is actually a set of bit flags (defined above) +* that correspond to the bits of the data port. Each of the I/O port +* bits that drives an isp programming pin is assigned a flag +* (through a #define) corresponding to the signal it drives. To +* change the value of more than one pin at once, the flags are added +* together, much like file access flags are. +* +* The bit flags are only set if the pin is to be changed. Bits that +* do not have their flags set do not have their levels changed. The +* state of the port is always manintained in the static global +* variable g_siIspPins, so that each pin can be addressed individually +* without disturbing the others. +* +* - a_ucValue, which is either HIGH (0x01 ) or LOW (0x00 ). Only these two +* values are valid. Any non-zero number sets the pin(s) high. +* +*********************************************************************************/ + +void writePort( unsigned long a_ucPins, unsigned char a_ucValue ) +{ + + unsigned long siIspPins = 0; + + /* For Denverton */ + // isp_dnv_gpio_write(a_ucPins, (unsigned int) a_ucValue); + + /* TODO: Convert to bit read/write function */ + siIspPins = inl_p( g_ucOutPort ); + if( a_ucValue ){ + siIspPins |= (1U << a_ucPins); + }else{ + siIspPins &= ~(1U << a_ucPins); + } + outl_p(siIspPins, g_ucOutPort); +} + +/********************************************************************************* +* +* readPort +* +* Returns the value of the TDO from the device. +* +**********************************************************************************/ +unsigned char readPort() +{ + unsigned char ucRet = 0; + + /* For Denverton */ + // if ( isp_dnv_gpio_read(DNV_GPIO_TDO_CONFIG) ) { + // ucRet = 0x01; + // } + // else { + // ucRet = 0x00; + // } + + /* TODO: Convert to bit read/write function */ + if ( inl_p( g_ucInPort ) & (1U << g_ucPinTDO)) { + ucRet = 0x01; + } + else { + ucRet = 0x00; + } + return ( ucRet ); +} + +/********************************************************************************* +* sclock +* +* Apply a pulse to TCK. +* +* This function is located here so that users can modify to slow down TCK if +* it is too fast (> 25MHZ). Users can change the IdleTime assignment from 0 to +* 1, 2... to effectively slowing down TCK by half, quarter... +* +*********************************************************************************/ +void sclock() +{ + unsigned short IdleTime = 0; //change to > 0 if need to slow down TCK + unsigned short usIdleIndex = 0; + IdleTime++; + for ( usIdleIndex = 0; usIdleIndex < IdleTime; usIdleIndex++ ) { + writePort( g_ucPinTCK, 0x01 ); + } + for ( usIdleIndex = 0; usIdleIndex < IdleTime; usIdleIndex++ ) { + writePort( g_ucPinTCK, 0x00 ); + } +} +/******************************************************************************** +* +* ispVMDelay +* +* +* Users must implement a delay to observe a_usTimeDelay, where +* bit 15 of the a_usTimeDelay defines the unit. +* 1 = milliseconds +* 0 = microseconds +* Example: +* a_usTimeDelay = 0x0001 = 1 microsecond delay. +* a_usTimeDelay = 0x8001 = 1 millisecond delay. +* +* This subroutine is called upon to provide a delay from 1 millisecond to a few +* hundreds milliseconds each time. +* It is understood that due to a_usTimeDelay is defined as unsigned short, a 16 bits +* integer, this function is restricted to produce a delay to 64000 micro-seconds +* or 32000 milli-second maximum. The VME file will never pass on to this function +* a delay time > those maximum number. If it needs more than those maximum, the VME +* file will launch the delay function several times to realize a larger delay time +* cummulatively. +* It is perfectly alright to provide a longer delay than required. It is not +* acceptable if the delay is shorter. +* +* Delay function example--using the machine clock signal of the native CPU------ +* When porting ispVME to a native CPU environment, the speed of CPU or +* the system clock that drives the CPU is usually known. +* The speed or the time it takes for the native CPU to execute one for loop +* then can be calculated as follows: +* The for loop usually is compiled into the ASSEMBLY code as shown below: +* LOOP: DEC RA; +* JNZ LOOP; +* If each line of assembly code needs 4 machine cycles to execute, +* the total number of machine cycles to execute the loop is 2 x 4 = 8. +* Usually system clock = machine clock (the internal CPU clock). +* Note: Some CPU has a clock multiplier to double the system clock for + the machine clock. +* +* Let the machine clock frequency of the CPU be F, or 1 machine cycle = 1/F. +* The time it takes to execute one for loop = (1/F ) x 8. +* Or one micro-second = F(MHz)/8; +* +* Example: The CPU internal clock is set to 100Mhz, then one micro-second = 100/8 = 12 +* +* The C code shown below can be used to create the milli-second accuracy. +* Users only need to enter the speed of the cpu. +* +**********************************************************************************/ +void ispVMDelay( unsigned short a_usTimeDelay ) +{ + unsigned short loop_index = 0; + unsigned short ms_index = 0; + unsigned short us_index = 0; + + if ( a_usTimeDelay & 0x8000 ) /*Test for unit*/ + { + a_usTimeDelay &= ~0x8000; /*unit in milliseconds*/ + } + else { /*unit in microseconds*/ + a_usTimeDelay = (unsigned short) (a_usTimeDelay/1000); /*convert to milliseconds*/ + if ( a_usTimeDelay <= 0 ) { + a_usTimeDelay = 1; /*delay is 1 millisecond minimum*/ + } + } + /*Users can replace the following section of code by their own*/ + for( ms_index = 0; ms_index < a_usTimeDelay; ms_index++) + { + /*Loop 1000 times to produce the milliseconds delay*/ + for (us_index = 0; us_index < 1000; us_index++) + { /*each loop should delay for 1 microsecond or more.*/ + loop_index = 0; + do { + /*The NOP fakes the optimizer out so that it doesn't toss out the loop code entirely*/ + asm("nop"); + }while (loop_index++ < ((g_usCpu_Frequency/8)+(+ ((g_usCpu_Frequency % 8) ? 1 : 0))));/*use do loop to force at least one loop*/ + } + } +} + +/********************************************************************************* +* +* calibration +* +* It is important to confirm if the delay function is indeed providing +* the accuracy required. Also one other important parameter needed +* checking is the clock frequency. +* Calibration will help to determine the system clock frequency +* and the loop_per_micro value for one micro-second delay of the target +* specific hardware. +* +**********************************************************************************/ +void calibration(void) +{ + /*Apply 2 pulses to TCK.*/ + writePort( g_ucPinTCK, 0x00 ); + writePort( g_ucPinTCK, 0x01 ); + writePort( g_ucPinTCK, 0x00 ); + writePort( g_ucPinTCK, 0x01 ); + writePort( g_ucPinTCK, 0x00 ); + + /*Delay for 1 millisecond. Pass on 1000 or 0x8001 both = 1ms delay.*/ + ispVMDelay(0x8001); + + /*Apply 2 pulses to TCK*/ + writePort( g_ucPinTCK, 0x01 ); + writePort( g_ucPinTCK, 0x00 ); + writePort( g_ucPinTCK, 0x01 ); + writePort( g_ucPinTCK, 0x00 ); + + ispVMDelay(0x8001); +} + +void port_test(void) +{ + int siRetCode; + unsigned char cbit; + + printf("TDI set HIGH.\n"); + if(scanf("%d",&siRetCode)){} + writePort( g_ucPinTDI, 0x01); + printf("TDI set LOW.\n"); + if(scanf("%d",&siRetCode)){} + writePort( g_ucPinTDI, 0x00); + printf("TMS set HIGH.\n"); + if(scanf("%d",&siRetCode)){} + writePort(g_ucPinTMS, 0x01); + printf("TMS set LOW.\n"); + if(scanf("%d",&siRetCode)){} + writePort(g_ucPinTMS, 0x00); + printf("TCK set HIGH.\n"); + if(scanf("%d",&siRetCode)){} + writePort(g_ucPinTCK, 0x01); + printf("TCK set LOW.\n"); + if(scanf("%d",&siRetCode)){} + writePort(g_ucPinTCK, 0x00); + printf("write finished.read begin:\n"); + if(scanf("%d",&siRetCode)){} + cbit = readPort(); + printf("Read date is %d\n", cbit); + printf("read begin:\n"); + if(scanf("%d",&siRetCode)){} + cbit = readPort(); + printf("Read date is %d\n", cbit); + printf("read finished.\n"); + if(scanf("%d",&siRetCode)){} +} + + +void isp_dnv_gpio_config(unsigned int gpio, unsigned int dir) +{ + volatile unsigned int *buffer; + // Select community + if(GET_PORT(gpio) == 0xC5){ + buffer = (volatile unsigned int *)(portC5 + OFFSET_ADDR(gpio)); + }else{ + buffer = (volatile unsigned int *)(portC2 + OFFSET_ADDR(gpio)); + } + // set mode to GPIO, set pin direction. + *buffer &= (~((unsigned int)7)) << 10; // clear [12:10] + *buffer &= (~((unsigned int)3)) << 8; // clear [9:8] + *buffer |= ((unsigned int)dir & 0x3) << 8; // set [9:8] +} + +void isp_dnv_gpio_write(unsigned int gpio, unsigned int value) +{ + volatile unsigned char *buffer; + // Select community + if(GET_PORT(gpio) == 0xC5){ + buffer = (volatile unsigned char *)(portC5 + OFFSET_ADDR(gpio)); + }else{ + buffer = (volatile unsigned char *)(portC2 + OFFSET_ADDR(gpio)); + } + if(value) { + *buffer = DNV_GPIO_LVL_HIGH; + } else { + *buffer = DNV_GPIO_LVL_LOW; + } +} + +int isp_dnv_gpio_read(unsigned int gpio) +{ + volatile unsigned int *buffer; + // Select community + if(GET_PORT(gpio) == 0xC5){ + buffer = (volatile unsigned int *)(portC5 + OFFSET_ADDR(gpio)); + }else{ + buffer = (volatile unsigned int *)(portC2 + OFFSET_ADDR(gpio)); + } + return (int)((*buffer & 0x2) >> 1); +} + + +void isp_dnv_gpio_init(void){ + + devmem_c2 = open("/dev/mem", O_RDWR | O_SYNC); + if (devmem_c2 == -1){ + perror("Can't open /dev/mem."); + return; + } + + devmem_c5 = open("/dev/mem", O_RDWR | O_SYNC); + if (devmem_c5 == -1){ + perror("Can't open /dev/mem."); + return; + } + + portC2 = mmap(NULL, MAP_SIZE(g_ucPinTCK) , PROT_READ | PROT_WRITE, MAP_SHARED, devmem_c2, g_ucPinTCK & ~MAP_MASK); + if (portC2 == MAP_FAILED) { + perror("Can't map memory: "); + return; + } + portC5 = mmap(NULL, MAP_SIZE(g_ucPinTDO) , PROT_READ | PROT_WRITE, MAP_SHARED, devmem_c5, g_ucPinTDO & ~MAP_MASK); + if (portC2 == MAP_FAILED) { + perror("Can't map memory: "); + return; + } +} + +void isp_dnv_gpio_deinit(void){ + munmap(portC2, MAP_SIZE(g_ucPinTCK)); + munmap(portC5, MAP_SIZE(g_ucPinTDO)); + close(devmem_c2); + close(devmem_c5); +} diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/ispvme_12.2/ispvm b/platform/broadcom/sonic-platform-modules-cel/tools/ispvme_12.2/ispvm new file mode 100755 index 000000000000..202103900f69 Binary files /dev/null and b/platform/broadcom/sonic-platform-modules-cel/tools/ispvme_12.2/ispvm differ diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/ispvme_12.2/ispvm_ui.c b/platform/broadcom/sonic-platform-modules-cel/tools/ispvme_12.2/ispvm_ui.c new file mode 100644 index 000000000000..6180007d74d0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/tools/ispvme_12.2/ispvm_ui.c @@ -0,0 +1,1043 @@ +/************************************************************** +* +* Lattice Semiconductor Corp. Copyright 2008 +* +* ispVME Embedded allows programming of Lattice's suite of FPGA +* devices on embedded systems through the JTAG port. The software +* is distributed in source code form and is open to re - distribution +* and modification where applicable. +* +* ispVME Embedded C Source comprised with 3 modules: +* ispvm_ui.c is the module provides input and output support. +* ivm_core.c is the module interpret the VME file(s). +* hardware.c is the module access the JTAG port of the device(s). +* +* The optional module cable.c is for supporting Lattice's parallel +* port ispDOWNLOAD cable on DOS and Windows 95/98 O/S. It can be +* requested from Lattice's ispVMSupport. +* +***************************************************************/ + + +/************************************************************** +* +* Revision History of ispvm_ui.c +* +* 3/6/07 ht Added functions vme_out_char(),vme_out_hex(), +* vme_out_string() to provide output resources. +* Consolidate all printf() calls into the added output +* functions. +* +* 09/11/07 NN Added Global variables initialization +* 09/24/07 NN Added a switch allowing users to do calibration. +* Calibration will help to determine the system clock frequency +* and the count value for one micro-second delay of the target +* specific hardware. +* Removed Delay Percent support +* 11/15/07 NN moved the checking of the File CRC to the end of processing +* 08/28/08 NN Added Calculate checksum support. +***************************************************************/ + + +#include +#include +#include +#include +#include +#include +#include "vmopcode.h" + +/*************************************************************** +* +* File pointer to the VME file. +* +***************************************************************/ + +FILE * g_pVMEFile = NULL; + +#define VME_DEBUG + +#define DEBUG +#ifdef DEBUG +#define Debug_printf(fmt, args...) printf(fmt, ##args); +#else +#define Debug_printf(fmt, args...) +#endif + +/*************************************************************** +* +* Functions declared in this ispvm_ui.c module +* +***************************************************************/ +unsigned char GetByte(void); +void vme_out_char(unsigned char charOut); +void vme_out_hex(unsigned char hexOut); +void vme_out_string(char *stringOut); +void ispVMMemManager( signed char cTarget, unsigned short usSize ); +void ispVMFreeMem(void); +void error_handler( short a_siRetCode, char * pszMessage ); +signed char ispVM( const char * a_pszFilename ); +long isp_vme_file_size_get(void); +int isp_vme_file_size_set(char *file_name); +int isp_print_progess_bar(long pec); +void print_usage(char *app_name); +/*************************************************************** +* +* Global variables. +* +***************************************************************/ +unsigned short g_usPreviousSize = 0; +unsigned short g_usExpectedCRC = 0; +static unsigned long vme_file_size = 0; + +/*************************************************************** +* +* External variables and functions declared in ivm_core.c module. +* +***************************************************************/ +extern signed char ispVMCode(); +extern void ispVMCalculateCRC32( unsigned char a_ucData ); +extern void ispVMStart(); +extern void ispVMEnd(); +extern unsigned short g_usCalculatedCRC; +extern unsigned short g_usDataType; +extern unsigned char * g_pucOutMaskData, + * g_pucInData, + * g_pucOutData, + * g_pucHIRData, + * g_pucTIRData, + * g_pucHDRData, + * g_pucTDRData, + * g_pucOutDMaskData, + * g_pucIntelBuffer; +extern unsigned char * g_pucHeapMemory; +extern unsigned short g_iHeapCounter; +extern unsigned short g_iHEAPSize; +extern unsigned short g_usIntelDataIndex; +extern unsigned short g_usIntelBufferSize; +extern LVDSPair * g_pLVDSList; +//08/28/08 NN Added Calculate checksum support. +extern unsigned long g_usChecksum; +extern unsigned int g_uiChecksumIndex; +/*************************************************************** +* +* External variables and functions declared in hardware.c module. +* +***************************************************************/ +extern void calibration(void); +extern void writePort( unsigned long a_ucPins, unsigned char a_ucValue ); +extern unsigned short g_usCpu_Frequency; +extern unsigned long g_ucInPort; +extern unsigned long g_ucOutPort; + +#define SYS_CMD_LEN (100) +#define PCA9536_INPUT_REG (0) +#define PCA9536_OUTPUT_REG (1) +#define PCA9536_POL_INV_REG (2) +#define PCA9536_CFG_REG (3) +#define PCA9536_I2C_BUS (0) +#define PCA9536_I2C_ADDR (0x41) +enum cel_error{ +CEL_NO_ERR = 0, +CEL_ERR_INVALID_DATA, +}; +enum IOx_index { +CPLD_BB_INDEX = 0, +CPLD_CB_INDEX, +CPLD_FCB_INDEX, +CPLD_SWB_INDEX, +CPLD_TOTAL_NUM, + +}; +char IOx_map[] = { +1,//IOx index of pca9536 corresponding to CPLD_BB +2,//IOx index of pca9536 corresponding to CPLD_CB +0,//IOx index of pca9536 corresponding to CPLD_FCB +3,//IOx index of pca9536 corresponding to CPLD_SWB +}; +/*************************************************************** +* +* Supported VME versions. +* +***************************************************************/ + +const char * const g_szSupportedVersions[] = { "__VME2.0", "__VME3.0", "____12.0", "____12.1", 0 }; + + +/*************************************************************** +* +* GetByte +* +* Returns a byte to the caller. The returned byte depends on the +* g_usDataType register. If the HEAP_IN bit is set, then the byte +* is returned from the HEAP. If the LHEAP_IN bit is set, then +* the byte is returned from the intelligent buffer. Otherwise, +* the byte is returned directly from the VME file. +* +***************************************************************/ + +unsigned char GetByte() +{ + unsigned char ucData = 0; + /* Prepare progress bar calculation */ + static long offset = 0; + int pec = 0; + long file_size = isp_vme_file_size_get(); + int bytes_pec = (file_size + 99) / 100; + + if ( g_usDataType & HEAP_IN ) { + + /*************************************************************** + * + * Get data from repeat buffer. + * + ***************************************************************/ + + if ( g_iHeapCounter > g_iHEAPSize ) { + + /*************************************************************** + * + * Data over-run. + * + ***************************************************************/ + + return 0xFF; + } + + ucData = g_pucHeapMemory[ g_iHeapCounter++ ]; + } + else if ( g_usDataType & LHEAP_IN ) { + + /*************************************************************** + * + * Get data from intel buffer. + * + ***************************************************************/ + + if ( g_usIntelDataIndex >= g_usIntelBufferSize ) { + + /*************************************************************** + * + * Data over-run. + * + ***************************************************************/ + + return 0xFF; + } + + ucData = g_pucIntelBuffer[ g_usIntelDataIndex++ ]; + } + else { + + /*************************************************************** + * + * Get data from file. + * + ***************************************************************/ + + ucData = (unsigned char)fgetc( g_pVMEFile ); + /* Update the progress bar */ + pec = ++offset / bytes_pec; + if(offset <= (pec * bytes_pec)) + isp_print_progess_bar(pec); + else if(offset >= (file_size - 2)) + isp_print_progess_bar(100); + if ( feof( g_pVMEFile ) ) { + + /*************************************************************** + * + * Reached EOF. + * + ***************************************************************/ + + return 0xFF; + } + /*************************************************************** + * + * Calculate the 32-bit CRC if the expected CRC exist. + * + ***************************************************************/ + if( g_usExpectedCRC != 0) + { + ispVMCalculateCRC32(ucData); + } + } + + return ( ucData ); +} + +/*************************************************************** +* +* vme_out_char +* +* Send a character out to the output resource if available. +* The monitor is the default output resource. +* +* +***************************************************************/ +void vme_out_char(unsigned char charOut) +{ + printf("%c",charOut); +} +/*************************************************************** +* +* vme_out_hex +* +* Send a character out as in hex format to the output resource +* if available. The monitor is the default output resource. +* +* +***************************************************************/ +void vme_out_hex(unsigned char hexOut) +{ + printf("%.2X",hexOut); +} +/*************************************************************** +* +* vme_out_string +* +* Send a text string out to the output resource if available. +* The monitor is the default output resource. +* +* +***************************************************************/ +void vme_out_string(char *stringOut) +{ + if(stringOut) + { + printf("%s",stringOut); + } + +} +/*************************************************************** +* +* ispVMMemManager +* +* Allocate memory based on cTarget. The memory size is specified +* by usSize. +* +***************************************************************/ + +void ispVMMemManager( signed char cTarget, unsigned short usSize ) +{ + switch ( cTarget ) { + case XTDI: + case TDI: + if ( g_pucInData != NULL ) { + if ( g_usPreviousSize == usSize ) {/*memory exist*/ + break; + } + else { + free( g_pucInData ); + g_pucInData = NULL; + } + } + g_pucInData = ( unsigned char * ) malloc( usSize / 8 + 2 ); + g_usPreviousSize = usSize; + /* FALLTHRU */ + case XTDO: + case TDO: + if ( g_pucOutData!= NULL ) { + if ( g_usPreviousSize == usSize ) { /*already exist*/ + break; + } + else { + free( g_pucOutData ); + g_pucOutData = NULL; + } + } + g_pucOutData = ( unsigned char * ) malloc( usSize / 8 + 2 ); + g_usPreviousSize = usSize; + break; + case MASK: + if ( g_pucOutMaskData != NULL ) { + if ( g_usPreviousSize == usSize ) {/*already allocated*/ + break; + } + else { + free( g_pucOutMaskData ); + g_pucOutMaskData = NULL; + } + } + g_pucOutMaskData = ( unsigned char * ) malloc( usSize / 8 + 2 ); + g_usPreviousSize = usSize; + break; + case HIR: + if ( g_pucHIRData != NULL ) { + free( g_pucHIRData ); + g_pucHIRData = NULL; + } + g_pucHIRData = ( unsigned char * ) malloc( usSize / 8 + 2 ); + break; + case TIR: + if ( g_pucTIRData != NULL ) { + free( g_pucTIRData ); + g_pucTIRData = NULL; + } + g_pucTIRData = ( unsigned char * ) malloc( usSize / 8 + 2 ); + break; + case HDR: + if ( g_pucHDRData != NULL ) { + free( g_pucHDRData ); + g_pucHDRData = NULL; + } + g_pucHDRData = ( unsigned char * ) malloc( usSize / 8 + 2 ); + break; + case TDR: + if ( g_pucTDRData != NULL ) { + free( g_pucTDRData ); + g_pucTDRData = NULL; + } + g_pucTDRData = ( unsigned char * ) malloc( usSize / 8 + 2 ); + break; + case HEAP: + if ( g_pucHeapMemory != NULL ) { + free( g_pucHeapMemory ); + g_pucHeapMemory = NULL; + } + g_pucHeapMemory = ( unsigned char * ) malloc( usSize + 2 ); + break; + case DMASK: + if ( g_pucOutDMaskData != NULL ) { + if ( g_usPreviousSize == usSize ) { /*already allocated*/ + break; + } + else { + free( g_pucOutDMaskData ); + g_pucOutDMaskData = NULL; + } + } + g_pucOutDMaskData = ( unsigned char * ) malloc( usSize / 8 + 2 ); + g_usPreviousSize = usSize; + break; + case LHEAP: + if ( g_pucIntelBuffer != NULL ) { + free( g_pucIntelBuffer ); + g_pucIntelBuffer = NULL; + } + g_pucIntelBuffer = ( unsigned char * ) malloc( usSize + 2 ); + break; + case LVDS: + if ( g_pLVDSList != NULL ) { + free( g_pLVDSList ); + g_pLVDSList = NULL; + } + g_pLVDSList = ( LVDSPair * ) calloc( usSize, sizeof( LVDSPair ) ); + break; + default: + return; + } +} + +/*************************************************************** +* +* ispVMFreeMem +* +* Free memory that were dynamically allocated. +* +***************************************************************/ + +void ispVMFreeMem() +{ + if ( g_pucHeapMemory != NULL ) { + free( g_pucHeapMemory ); + g_pucHeapMemory = NULL; + } + + if ( g_pucOutMaskData != NULL ) { + free( g_pucOutMaskData ); + g_pucOutMaskData = NULL; + } + + if ( g_pucInData != NULL ) { + free( g_pucInData ); + g_pucInData = NULL; + } + + if ( g_pucOutData != NULL ) { + free( g_pucOutData ); + g_pucOutData = NULL; + } + + if ( g_pucHIRData != NULL ) { + free( g_pucHIRData ); + g_pucHIRData = NULL; + } + + if ( g_pucTIRData != NULL ) { + free( g_pucTIRData ); + g_pucTIRData = NULL; + } + + if ( g_pucHDRData != NULL ) { + free( g_pucHDRData ); + g_pucHDRData = NULL; + } + + if ( g_pucTDRData != NULL ) { + free( g_pucTDRData ); + g_pucTDRData = NULL; + } + + if ( g_pucOutDMaskData != NULL ) { + free( g_pucOutDMaskData ); + g_pucOutDMaskData = NULL; + } + + if ( g_pucIntelBuffer != NULL ) { + free( g_pucIntelBuffer ); + g_pucIntelBuffer = NULL; + } + + if ( g_pLVDSList != NULL ) { + free( g_pLVDSList ); + g_pLVDSList = NULL; + } +} + +/*************************************************************** +* +* error_handler +* +* Reports the error message. +* +***************************************************************/ + +void error_handler( short a_siRetCode, char * pszMessage ) +{ + const char * pszErrorMessage[] = { "pass", + "verification fail", + "can't find the file", + "wrong file type", + "file error", + "option error", + "crc verification error" }; + + strcpy( pszMessage, pszErrorMessage[ -a_siRetCode ] ); +} +/*************************************************************** +* +* ispVM +* +* The entry point of the ispVM embedded. If the version and CRC +* are verified, then the VME will be processed. +* +***************************************************************/ + +signed char ispVM( const char * a_pszFilename ) +{ + char szFileVersion[ 9 ] = { 0 }; + signed char cRetCode = 0; + signed char cIndex = 0; + signed char cVersionIndex = 0; + unsigned char ucReadByte = 0; + + /*************************************************************** + * + * Global variables initialization. + * + * 09/11/07 NN Added + ***************************************************************/ + g_pucHeapMemory = NULL; + g_iHeapCounter = 0; + g_iHEAPSize = 0; + g_usIntelDataIndex = 0; + g_usIntelBufferSize = 0; + g_usPreviousSize = 0; + + /*************************************************************** + * + * Open a file pointer to the VME file. + * + ***************************************************************/ + + if ( ( g_pVMEFile = fopen( a_pszFilename, "rb" ) ) == NULL ) { + return VME_FILE_READ_FAILURE; + } + g_usCalculatedCRC = 0; + g_usExpectedCRC = 0; + ucReadByte = GetByte(); + switch( ucReadByte ) { + case FILE_CRC: + + /*************************************************************** + * + * Read and store the expected CRC to do the comparison at the end. + * Only versions 3.0 and higher support CRC protection. + * + ***************************************************************/ + + g_usExpectedCRC = (unsigned char ) fgetc( g_pVMEFile ); + g_usExpectedCRC <<= 8; + g_usExpectedCRC |= fgetc( g_pVMEFile ); + + + /*************************************************************** + * + * Read and store the version of the VME file. + * + ***************************************************************/ + + for ( cIndex = 0; cIndex < 8; cIndex++ ) { + szFileVersion[ cIndex ] = GetByte(); + } + + break; + default: + + /*************************************************************** + * + * Read and store the version of the VME file. Must be version 2.0. + * + ***************************************************************/ + + szFileVersion[ 0 ] = ( signed char ) ucReadByte; + for ( cIndex = 1; cIndex < 8; cIndex++ ) { + szFileVersion[ cIndex ] = GetByte(); + } + + break; + } + + /*************************************************************** + * + * Compare the VME file version against the supported version. + * + ***************************************************************/ + for ( cVersionIndex = 0; g_szSupportedVersions[ cVersionIndex ] != 0; cVersionIndex++ ) { + for ( cIndex = 0; cIndex < 8; cIndex++ ) { + if ( szFileVersion[ cIndex ] != g_szSupportedVersions[ cVersionIndex ][ cIndex ] ) { + cRetCode = VME_VERSION_FAILURE; + break; + } + cRetCode = 0; + } + + if ( cRetCode == 0 ) { + + /*************************************************************** + * + * Found matching version, break. + * + ***************************************************************/ + + break; + } + } + + if ( cRetCode < 0 ) { + + /*************************************************************** + * + * VME file version failed to match the supported versions. + * + ***************************************************************/ + + fclose( g_pVMEFile ); + g_pVMEFile = NULL; + return VME_VERSION_FAILURE; + } + + /*************************************************************** + * + * Enable the JTAG port to communicate with the device. + * Set the JTAG state machine to the Test-Logic/Reset State. + * + ***************************************************************/ + + ispVMStart(); + + /*************************************************************** + * + * Process the VME file. + * + ***************************************************************/ + + cRetCode = ispVMCode(); + + /*************************************************************** + * + * Set the JTAG State Machine to Test-Logic/Reset state then disable + * the communication with the JTAG port. + * + ***************************************************************/ + + ispVMEnd(); + + fclose( g_pVMEFile ); + g_pVMEFile = NULL; + + + ispVMFreeMem(); + + /*************************************************************** + * + * Compare the expected CRC versus the calculated CRC. + * + ***************************************************************/ + + if ( cRetCode == 0 && g_usExpectedCRC != 0 && ( g_usExpectedCRC != g_usCalculatedCRC ) ) { + printf( "Expected CRC: 0x%.4X\n", g_usExpectedCRC ); + printf( "Calculated CRC: 0x%.4X\n", g_usCalculatedCRC ); + return VME_CRC_FAILURE; + } + + return ( cRetCode ); +} + +// inline char *strlwr(char *str) +// { +// char *orig = str; + +// for (; *str != '\0'; str++) +// *str = tolower(*str); + +// return orig; +// } + +int isp_vme_file_size_set(char *file_name) +{ + struct stat statbuf; + + stat(file_name, &statbuf); + vme_file_size = statbuf.st_size; + + return 0; +} + +long isp_vme_file_size_get(void) +{ + return vme_file_size; +} + +int isp_print_progess_bar(long pec) +{ + int i = 0; + + printf("["); + for(i = 0; i < (pec / 2); i++) { + printf("="); + } + for(i = pec / 2; i < 50; i++) { + printf(" "); + } + printf("]"); + printf(" [%ld%%]\r", pec); + fflush(stdout); + if(pec == 100) + printf("\n"); + + return 0; +} + +void print_usage(char *app_name){ + printf(" usage: %s [options] [filename]\n", app_name); + printf(" Options:\n"); + printf(" -h : to print this message.\n"); + printf(" -c : to select the JTAG chain 0,1,2\n"); + printf(" default is at 0.\n"); + printf(" -f : to specify CPU clock frequency in MHz.\n"); + printf(" -i : set output channel of pca9536, range:\n"); + printf(" 0 - CPLD_BB \n"); + printf(" 1 - CPLD_CB \n"); + printf(" 2 - CPLD_FCB \n"); + printf(" 3 - CPLD_SWB \n"); +} + +/*Description: execute a system command contained in a string +*param_in: tmp - system command string +*param_out: NONE +*ret_val: 0 - on successful +* 1 - on failed +*/ +int exec_cmd (char * tmp) +{ + int status; + status = system(tmp); + if (-1 ==status){ + return CEL_ERR_INVALID_DATA; + }else{ + if (WIFEXITED(status)){ + if (0 == WEXITSTATUS(status)){ + return CEL_NO_ERR; + }else{ + return CEL_ERR_INVALID_DATA; + } + }else{ + return CEL_ERR_INVALID_DATA; + } + } + return CEL_NO_ERR; +} +/*Description: set pca9536 IO0~IO3 output level +*param_in: io_index - index of IO pin +*param_out:NONE +*ret_val: 0 - on successful +* -1 - on failed +*/ +int set_pca9536_output(int io_index) +{ + int sys_cmd_rc = 0; + char sys_cmd[SYS_CMD_LEN] = {0}; + char reg_val = 0xFF & (~(1 << IOx_map[io_index])); + printf("set pca9536 IO%d to level 0 \n", IOx_map[io_index]); + memset(sys_cmd, 0, SYS_CMD_LEN); + sprintf(sys_cmd, "i2cset -y %d 0x%x 0x%x 0x%x", PCA9536_I2C_BUS, + PCA9536_I2C_ADDR, PCA9536_OUTPUT_REG, reg_val); + sys_cmd_rc = exec_cmd(sys_cmd); + if (sys_cmd_rc != 0) { + printf("set pca9536 IO%d to level 0 failed!\n", IOx_map[io_index]); + return -1; + } + return sys_cmd_rc; +} + +/*************************************************************** +* +* main +* +***************************************************************/ +int main( int argc, char * argv[] ) +{ + short siRetCode = 0; + short sicalibrate = 1; + short setCpuFrequency = 0; + /* ChannelIndex: indicate which channel on PCA9536 is selected */ + int ChannelIndex = -1; + char sys_cmd[SYS_CMD_LEN] = {0}; + int setChannel = 0; + int sys_cmd_rc = 0; + + char *cpld_img = "cpld.vme"; + int JTAG_chain = 0; + int option; + //08/28/08 NN Added Calculate checksum support. + g_usChecksum = 0; + g_uiChecksumIndex = 0; + + vme_out_string( " Lattice Semiconductor Corp.\n" ); + vme_out_string( "\n ispVME(tm) V"); + vme_out_string( VME_VERSION_NUMBER ); + vme_out_string(" Copyright 1998-2011.\n"); + vme_out_string( "\nFor daisy chain programming of all in-system programmable devices\n" ); + vme_out_string( "\nCLS internal version 1.1.0 for Phalanx, Fishbone48, and Fishbone32.\n\n" ); + + while( ( option = getopt(argc, argv, "i:f:c:h")) != -1 ){ + switch (option){ + case 'h': + print_usage(argv[0]); + return 0; + case 'c': + // set JTAG chain number + JTAG_chain = atoi(optarg); + break; + case 'f': + // set CPU frequency + g_usCpu_Frequency = atoi(optarg); + setCpuFrequency = 1; + break; + case 'i': + ChannelIndex = atoi(optarg); + /* printf("channel_index=%d\n", ChannelIndex); */ + break; + case '?': + print_usage(argv[0]); + return -1; + } + } + + if( argc - optind ) + cpld_img = argv[optind]; + + if( JTAG_chain < 0 || JTAG_chain > 2 ){ + //print usage and return error + printf("Invalid JTAG chain specify: %d\n", JTAG_chain); + print_usage(argv[0]); + return -1; + } + + if( g_usCpu_Frequency <= 0 && setCpuFrequency ){ + //print usage and return error + printf("Invalid CPU frequency specify: %d\n", g_usCpu_Frequency); + print_usage(argv[0]); + return -1; + } + + if (ChannelIndex != -1) { + if (ChannelIndex < 0 || ChannelIndex > 3) { + printf("Invalid pca9536 channel index! \n"); + print_usage(argv[0]); + return -1; + } else { + printf("pca9536 channel index: %d \n", ChannelIndex); + setChannel = 1; + } + } else { + printf("pca9536 output channel not set,use default value 0 ! \n"); + ChannelIndex = 0; + setChannel = 1; + } + /*printf("exit programm 1 \n"); + * exit(1); + */ + if (iopl(3)) + { + perror("iopl"); + exit(1);/* reminder here: do not use "return", I warned */ + } + else + { + + /* For Denvertion CPU */ + // isp_dnv_gpio_init(); + // isp_dnv_gpio_config(GPIO_TCK_CONFIG, GPIO_DIR_OUTPUT); + // isp_dnv_gpio_config(GPIO_TMS_CONFIG, GPIO_DIR_OUTPUT); + // isp_dnv_gpio_config(GPIO_TDI_CONFIG, GPIO_DIR_OUTPUT); + // isp_dnv_gpio_config(GPIO_TDO_CONFIG, GPIO_DIR_INPUT); + + + /* TODO: Convert to bit read/write function */ + // Set ICHx GPIO_USE_SEL of TDI,TDO,TMS,TCK,GPIO14 + unsigned long data = 0; + data = inl_p(GPIO_USE_SEL); + data |= (1U << GPIO_TCK_CONFIG); + data |= (1U << GPIO_TMS_CONFIG); + data |= (1U << GPIO_TDI_CONFIG); + data |= (1U << GPIO_TDO_CONFIG); + data |= (1U << 14); + outl_p(data, GPIO_USE_SEL); + // Set ICHx GP_IO_SEL of TDI,TDO,TMS,TCK,GPIO14 + data = inl_p(GP_IO_SEL); + data &= ~(1U << GPIO_TCK_CONFIG); + data &= ~(1U << GPIO_TMS_CONFIG); + data &= ~(1U << GPIO_TDI_CONFIG); + data &= ~(1U << 14); + data |= (1U << GPIO_TDO_CONFIG); + outl_p(data, GP_IO_SEL); + + // Set ICHx GPIO_USE_SEL of GPIO70 + data = inl_p(GPIO_USE_SEL3); + data |= (1U << 6); + outl_p(data, GPIO_USE_SEL3); + // Set ICHx GP_IO_SEL of GPIO70 + data = inl_p(GP_IO_SEL3); + data &= ~(1U << 6); + outl_p(data, GP_IO_SEL3); + } + + /* FIXME: export and setting GPIO register bank on the fly could cause a bug. + * Plan to add the function to set/clear GPIO register bit for more sucure. + */ + /* Switch to control JTAG chain muxes */ + switch (JTAG_chain){ + case 0: + printf("Select main JTAG chain\n"); + // Set GPIO70 to Low + g_ucOutPort = GP_LVL3; + writePort( 6, 0x00 ); + break; + case 1: + printf("Select Top line card JTAG chain\n"); + // Ste GPIO70 to High + g_ucOutPort = GP_LVL3; + writePort( 6, 0x01 ); + // Ste GPIO14 to Low + g_ucOutPort = GP_LVL; + writePort( 14, 0x00 ); + break; + case 2: + printf("Select Buttom line card JTAG chain\n"); + // Ste GPIO70 to High + g_ucOutPort = GP_LVL3; + writePort( 6, 0x01 ); + // Ste GPIO14 to High + g_ucOutPort = GP_LVL; + writePort( 14, 0x01 ); + break; + } + + /* FIXME: This line is very important for TDI,TMS,TCK,TDO */ + // Set the register back to first bank! + g_ucOutPort = GP_LVL; + + printf("Set CPU frequency to %d MHz\n", g_usCpu_Frequency); + + if (setChannel) { + printf("Set pca9536 output channel index to %d \n", ChannelIndex); + /* exit(0); */ + memset(sys_cmd, 0, SYS_CMD_LEN); + sprintf(sys_cmd, "sudo su"); + sys_cmd_rc = exec_cmd(sys_cmd); + if (sys_cmd_rc != 0) { + printf("sudo su failed!\n"); + return -1; + } + memset(sys_cmd, 0, SYS_CMD_LEN); + sprintf(sys_cmd, "echo jtag_sel 0x41 > /sys/bus/i2c/devices/i2c-0/new_device"); + sys_cmd_rc = exec_cmd(sys_cmd); + if (sys_cmd_rc != 0) { + printf("add pca9536 to i2c-0 failed!\n"); + return -1; + } + memset(sys_cmd, 0, SYS_CMD_LEN); + sprintf(sys_cmd, "i2cset -y %d 0x%x 0x%x 0xf0", PCA9536_I2C_BUS, PCA9536_I2C_ADDR, PCA9536_CFG_REG); + sys_cmd_rc = exec_cmd(sys_cmd); + if (sys_cmd_rc != 0) { + printf("set pca9536 IO0~IO3 to output mode failed!\n"); + return -1; + } + sys_cmd_rc = set_pca9536_output(ChannelIndex); + if (sys_cmd_rc != 0) { + printf("set pca9536 IO%d output 0 failed!\n", IOx_map[ChannelIndex]); + return -1; + } + } + + siRetCode = 0; + if(sicalibrate) + { + vme_out_string ("calibration ....\n\n"); + calibration(); + } + + printf( "Processing virtual machine file ("); + printf( "%s",cpld_img); + printf(")......\n\n"); + isp_vme_file_size_set(cpld_img); + siRetCode = ispVM(cpld_img); + + /* Set JTAG chain muxes to default chain. */ + // Set GPIO70 to Low + g_ucOutPort = GP_LVL3; + writePort( 6, 0x00 ); + + /* For Denverton CPU */ + // isp_dnv_gpio_deinit(); + + if ( siRetCode < 0 ) { + vme_out_string( "Failed due to "); + printf( " return code %d\n\n", siRetCode); + vme_out_string( "+=======+\n" ); + vme_out_string( "| FAIL! |\n" ); + vme_out_string( "+=======+\n\n" ); + }else { + vme_out_string( "+=======+\n" ); + vme_out_string( "| PASS! |\n" ); + vme_out_string( "+=======+\n\n" ); + //08/28/08 NN Added Calculate checksum support. + if(g_usChecksum != 0) + { + g_usChecksum &= 0xFFFF; + printf("Data Checksum: %.4lx\n\n",g_usChecksum); + g_usChecksum = 0; + } + } + + if (iopl(0)) + { + perror("iopl"); + exit(1);/* reminder here: do not use "return", I warned */ + } + exit( siRetCode ); +} + diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/ispvme_12.2/ivm_core.c b/platform/broadcom/sonic-platform-modules-cel/tools/ispvme_12.2/ivm_core.c new file mode 100644 index 000000000000..fd6fa7b987c2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/tools/ispvme_12.2/ivm_core.c @@ -0,0 +1,3081 @@ +/*************************************************************** + * + * Lattice Semiconductor Corp. Copyright 2009 + * + * ispVME Embedded allows programming of Lattice's suite of FPGA + * devices on embedded systems through the JTAG port. The software + * is distributed in source code form and is open to re - distribution + * and modification where applicable. + * + * Revision History of ivm_core.c module: + * 4/25/06 ht Change some variables from unsigned short or int + * to long int to make the code compiler independent. + * 5/24/06 ht Support using RESET (TRST) pin as a special purpose + * control pin such as triggering the loading of known + * state exit. + * 3/6/07 ht added functions to support output to terminals + * + * 09/24/07 NN Type cast mismatch variables + * Moved the sclock() function to hardware.c + * 08/28/08 NN Added Calculate checksum support. + * 4/1/09 Nguyen replaced the recursive function call codes on + * the ispVMLCOUNT function + * + ***************************************************************/ + +#include +#include +#include "vmopcode.h" + +/*************************************************************** + * + * Global variables used to specify the flow control and data type. + * + * g_usFlowControl: flow control register. Each bit in the + * register can potentially change the + * personality of the embedded engine. + * g_usDataType: holds the data type of the current row. + * + ***************************************************************/ + +unsigned short g_usFlowControl = 0x0000; +unsigned short g_usDataType = 0x0000; + +/*************************************************************** + * + * Global variables used to specify the ENDDR and ENDIR. + * + * g_ucEndDR: the state that the device goes to after SDR. + * g_ucEndIR: the state that the device goes to after SIR. + * + ***************************************************************/ + +unsigned char g_ucEndDR = DRPAUSE; +unsigned char g_ucEndIR = IRPAUSE; + +/*************************************************************** + * + * Global variables used to support header/trailer. + * + * g_usHeadDR: the number of lead devices in bypass. + * g_usHeadIR: the sum of IR length of lead devices. + * g_usTailDR: the number of tail devices in bypass. + * g_usTailIR: the sum of IR length of tail devices. + * + ***************************************************************/ + +unsigned short g_usHeadDR = 0; +unsigned short g_usHeadIR = 0; +unsigned short g_usTailDR = 0; +unsigned short g_usTailIR = 0; + +/*************************************************************** + * + * Global variable to store the number of bits of data or instruction + * to be shifted into or out from the device. + * + ***************************************************************/ + +unsigned short g_usiDataSize = 0; + +/*************************************************************** + * + * Stores the frequency. Default to 1 MHz. + * + ***************************************************************/ + +int g_iFrequency = 1000; + +/*************************************************************** + * + * Stores the maximum amount of ram needed to hold a row of data. + * + ***************************************************************/ + +unsigned short g_usMaxSize = 0; + +/*************************************************************** + * + * Stores the LSH or RSH value. + * + ***************************************************************/ + +unsigned short g_usShiftValue = 0; + +/*************************************************************** + * + * Stores the current repeat loop value. + * + ***************************************************************/ + +unsigned short g_usRepeatLoops = 0; + +/*************************************************************** + * + * Stores the current vendor. + * + ***************************************************************/ + +signed char g_cVendor = LATTICE; + +/*************************************************************** + * + * Stores the VME file CRC. + * + ***************************************************************/ + +unsigned short g_usCalculatedCRC = 0; + +/*************************************************************** + * + * Stores the Device Checksum. + * + ***************************************************************/ +//08/28/08 NN Added Calculate checksum support. +unsigned long g_usChecksum = 0; +unsigned int g_uiChecksumIndex = 0; + +/*************************************************************** + * + * Stores the current state of the JTAG state machine. + * + ***************************************************************/ + +signed char g_cCurrentJTAGState = 0; + +/*************************************************************** + * + * Global variables used to support looping. + * + * g_pucHeapMemory: holds the entire repeat loop. + * g_iHeapCounter: points to the current byte in the repeat loop. + * g_iHEAPSize: the current size of the repeat in bytes. + * + ***************************************************************/ + +unsigned char * g_pucHeapMemory = NULL; +unsigned short g_iHeapCounter = 0; +unsigned short g_iHEAPSize = 0; + +/*************************************************************** + * + * Global variables used to support intelligent programming. + * + * g_usIntelDataIndex: points to the current byte of the + * intelligent buffer. + * g_usIntelBufferSize: holds the size of the intelligent + * buffer. + * + ***************************************************************/ + +unsigned short g_usIntelDataIndex = 0; +unsigned short g_usIntelBufferSize = 0; + +/**************************************************************************** + * + * Holds the maximum size of each respective buffer. These variables are used + * to write the HEX files when converting VME to HEX. + * + *****************************************************************************/ + +unsigned short g_usTDOSize = 0; +unsigned short g_usMASKSize = 0; +unsigned short g_usTDISize = 0; +unsigned short g_usDMASKSize = 0; +unsigned short g_usLCOUNTSize = 0; +unsigned short g_usHDRSize = 0; +unsigned short g_usTDRSize = 0; +unsigned short g_usHIRSize = 0; +unsigned short g_usTIRSize = 0; +unsigned short g_usHeapSize = 0; + +/*************************************************************** + * + * Global variables used to store data. + * + * g_pucOutMaskData: local RAM to hold one row of MASK data. + * g_pucInData: local RAM to hold one row of TDI data. + * g_pucOutData: local RAM to hold one row of TDO data. + * g_pucHIRData: local RAM to hold the current SIR header. + * g_pucTIRData: local RAM to hold the current SIR trailer. + * g_pucHDRData: local RAM to hold the current SDR header. + * g_pucTDRData: local RAM to hold the current SDR trailer. + * g_pucIntelBuffer: local RAM to hold the current intelligent buffer. + * g_pucOutDMaskData: local RAM to hold one row of DMASK data. + * + ***************************************************************/ + +unsigned char * g_pucOutMaskData = NULL, + * g_pucInData = NULL, + * g_pucOutData = NULL, + * g_pucHIRData = NULL, + * g_pucTIRData = NULL, + * g_pucHDRData = NULL, + * g_pucTDRData = NULL, + * g_pucIntelBuffer = NULL, + * g_pucOutDMaskData = NULL; + +/*************************************************************** + * + * JTAG state machine transition table. + * + ***************************************************************/ + +struct { + unsigned char CurState; /* From this state */ + unsigned char NextState; /* Step to this state */ + unsigned char Pattern; /* The tragetory of TMS */ + unsigned char Pulses; /* The number of steps */ +} g_JTAGTransistions[ 25 ] = { + { RESET, RESET, 0xFC, 6 }, /* Transitions from RESET */ + { RESET, IDLE, 0x00, 1 }, + { RESET, DRPAUSE, 0x50, 5 }, + { RESET, IRPAUSE, 0x68, 6 }, + { IDLE, RESET, 0xE0, 3 }, /* Transitions from IDLE */ + { IDLE, DRPAUSE, 0xA0, 4 }, + { IDLE, IRPAUSE, 0xD0, 5 }, + { DRPAUSE, RESET, 0xF8, 5 }, /* Transitions from DRPAUSE */ + { DRPAUSE, IDLE, 0xC0, 3 }, + { DRPAUSE, IRPAUSE, 0xF4, 7 }, + { DRPAUSE, DRPAUSE, 0xE8, 6 }, /* 06/14/06 Support POLING STATUS LOOP*/ + { IRPAUSE, RESET, 0xF8, 5 }, /* Transitions from IRPAUSE */ + { IRPAUSE, IDLE, 0xC0, 3 }, + { IRPAUSE, DRPAUSE, 0xE8, 6 }, + { DRPAUSE, SHIFTDR, 0x80, 2 }, /* Extra transitions using SHIFTDR */ + { IRPAUSE, SHIFTDR, 0xE0, 5 }, + { SHIFTDR, DRPAUSE, 0x80, 2 }, + { SHIFTDR, IDLE, 0xC0, 3 }, + { IRPAUSE, SHIFTIR, 0x80, 2 }, /* Extra transitions using SHIFTIR */ + { SHIFTIR, IRPAUSE, 0x80, 2 }, + { SHIFTIR, IDLE, 0xC0, 3 }, + { DRPAUSE, DRCAPTURE, 0xE0, 4 }, /* 11/15/05 Support DRCAPTURE*/ + { DRCAPTURE, DRPAUSE, 0x80, 2 }, + { IDLE, DRCAPTURE, 0x80, 2 }, + { IRPAUSE, DRCAPTURE, 0xE0, 4 } +}; + +/*************************************************************** + * + * List to hold all LVDS pairs. + * + ***************************************************************/ + +LVDSPair * g_pLVDSList = NULL; +unsigned short g_usLVDSPairCount = 0; + +/*************************************************************** + * + * Function prototypes. + * + ***************************************************************/ + +signed char ispVMCode(); +signed char ispVMDataCode(); +long int ispVMDataSize(); +void ispVMData( unsigned char * Data ); +signed char ispVMShift( signed char Code ); +signed char ispVMAmble( signed char Code ); +signed char ispVMLoop( unsigned short a_usLoopCount ); +signed char ispVMBitShift( signed char mode, unsigned short bits ); +void ispVMComment( unsigned short a_usCommentSize ); +void ispVMHeader( unsigned short a_usHeaderSize ); +signed char ispVMLCOUNT( unsigned short a_usCountSize ); +void ispVMClocks( unsigned short Clocks ); +void ispVMBypass( signed char ScanType, unsigned short Bits ); +void ispVMStateMachine( signed char NextState ); +void ispVMStart(); +void ispVMEnd(); +signed char ispVMSend(unsigned short int); +signed char ispVMRead(unsigned short int); +signed char ispVMReadandSave(unsigned short int); +signed char ispVMProcessLVDS( unsigned short a_usLVDSCount ); + + +/*************************************************************** + * + * External variables and functions in ispvm_ui.c module + * + ***************************************************************/ +extern void vme_out_char(unsigned char charOut); +extern void vme_out_hex(unsigned char hexOut); +extern void vme_out_string(char *stringOut); +extern unsigned char GetByte(); +extern void ispVMMemManager( signed char types, unsigned short size ); + +/*************************************************************** + * + * External variables and functions in hardware.c module + * + ***************************************************************/ +extern void ispVMDelay( unsigned short int a_usMicroSecondDelay ); +extern unsigned char readPort(); +extern void writePort( unsigned long pins, unsigned char value ); +extern void sclock(); +extern signed char g_cCurrentJTAGState; +extern const unsigned long g_ucPinTDI; +extern const unsigned long g_ucPinTCK; +extern const unsigned long g_ucPinTMS; +extern const unsigned long g_ucPinENABLE; +extern const unsigned long g_ucPinTRST; +extern const unsigned long g_ucPinTDO; + +#ifdef VME_DEBUG + +/*************************************************************** + * + * GetState + * + * Returns the state as a string based on the opcode. Only used + * for debugging purposes. + * + ***************************************************************/ + +const char * GetState( unsigned char a_ucState ) +{ + switch( a_ucState ) { + case RESET: + return( "RESET" ); + case IDLE: + return( "IDLE" ); + case IRPAUSE: + return( "IRPAUSE" ); + case DRPAUSE: + return( "DRPAUSE" ); + case SHIFTIR: + return( "SHIFTIR" ); + case SHIFTDR: + return( "SHIFTDR" ); + case DRCAPTURE:/* 11/15/05 support DRCAPTURE*/ + return( "DRCAPTURE" ); + default: + break; + } + + return 0; +} + +/*************************************************************** + * + * PrintData + * + * Prints the data. Only used for debugging purposes. + * + ***************************************************************/ + +void PrintData( unsigned short a_iDataSize, unsigned char * a_pucData ) +{ + //09/11/07 NN added local variables initialization + unsigned short usByteSize = 0; + unsigned short usBitIndex = 0; + signed short usByteIndex = 0; + unsigned char ucByte = 0; + unsigned char ucFlipByte = 0; + + if ( a_iDataSize % 8 ) { + //09/11/07 NN Type cast mismatch variables + usByteSize = (unsigned short)(a_iDataSize / 8 + 1); + } + else { + //09/11/07 NN Type cast mismatch variables + usByteSize = (unsigned short)(a_iDataSize / 8); + } + printf( "(" ); + //09/11/07 NN Type cast mismatch variables + for ( usByteIndex = (signed short)(usByteSize - 1); usByteIndex >= 0; usByteIndex-- ) { + ucByte = a_pucData[ usByteIndex ]; + ucFlipByte = 0x00; + + /*************************************************************** + * + * Flip each byte. + * + ***************************************************************/ + + for ( usBitIndex = 0; usBitIndex < 8; usBitIndex++ ) { + ucFlipByte <<= 1; + if ( ucByte & 0x1) { + ucFlipByte |= 0x1; + } + + ucByte >>= 1; + } + + /*************************************************************** + * + * Print the flipped byte. + * + ***************************************************************/ + + printf( "%.02X", ucFlipByte ); + if ( ( usByteSize - usByteIndex ) % 40 == 39 ) { + printf( "\n\t\t" ); + } + if(usByteIndex < 0) + break; + } + printf( ")" ); +} +#endif //VME_DEBUG + +/*************************************************************** + * + * ispVMDataSize + * + * Returns a VME-encoded number, usually used to indicate the + * bit length of an SIR/SDR command. + * + ***************************************************************/ + +long int ispVMDataSize() +{ + //09/11/07 NN added local variables initialization + long int iSize = 0; + signed char cCurrentByte = 0; + signed char cIndex = 0; + cIndex = 0; + while ( ( cCurrentByte = GetByte() ) & 0x80 ) { + iSize |= ( ( long int ) ( cCurrentByte & 0x7F ) ) << cIndex; + cIndex += 7; + } + iSize |= ( ( long int ) ( cCurrentByte & 0x7F ) ) << cIndex; + return iSize; +} + +/*************************************************************** + * + * ispVMCode + * + * This is the heart of the embedded engine. All the high-level opcodes + * are extracted here. Once they have been identified, then it + * will call other functions to handle the processing. + * + ***************************************************************/ + +signed char ispVMCode() +{ + //09/11/07 NN added local variables initialization + unsigned short iRepeatSize = 0; + signed char cOpcode = 0; + signed char cRetCode = 0; + unsigned char ucState = 0; + unsigned short usDelay = 0; + unsigned short usToggle = 0; + unsigned char usByte = 0; + + /*************************************************************** + * + * Check the compression flag only if this is the first time + * this function is entered. Do not check the compression flag if + * it is being called recursively from other functions within + * the embedded engine. + * + ***************************************************************/ + + if ( !( g_usDataType & LHEAP_IN ) && !( g_usDataType & HEAP_IN ) ) { + usByte = GetByte(); + if ( usByte == 0xf1 ) { + g_usDataType |= COMPRESS; + } + else if ( usByte == 0xf2 ) { + g_usDataType &= ~COMPRESS; + } + else { + return VME_INVALID_FILE; + } + } + + /*************************************************************** + * + * Begin looping through all the VME opcodes. + * + ***************************************************************/ + + while ( ( cOpcode = GetByte() ) >= 0 ) { + + switch ( cOpcode ) { + case STATE: + + /*************************************************************** + * + * Step the JTAG state machine. + * + ***************************************************************/ + + ucState = GetByte(); + + /*************************************************************** + * + * Step the JTAG state machine to DRCAPTURE to support Looping. + * + ***************************************************************/ + + if ( (g_usDataType & LHEAP_IN) && + (ucState == DRPAUSE ) && + ( g_cCurrentJTAGState == ucState )) + { + ispVMStateMachine( DRCAPTURE ); + } + + ispVMStateMachine( ucState ); + +#ifdef VME_DEBUG + if ( g_usDataType & LHEAP_IN ) { + printf( "LDELAY %s ", GetState( ucState ) ); + } + else { + printf( "STATE %s;\n", GetState( ucState ) ); + } +#endif //VME_DEBUG + break; + case SIR: + case SDR: + case XSDR: + +#ifdef VME_DEBUG + switch( cOpcode ) { + case SIR: + printf( "SIR " ); + break; + case SDR: + case XSDR: + if ( g_usDataType & LHEAP_IN ) { + printf( "LSDR " ); + } + else { + printf( "SDR " ); + } + break; + } +#endif //VME_DEBUG + /*************************************************************** + * + * Shift in data into the device. + * + ***************************************************************/ + + cRetCode = ispVMShift( cOpcode ); + if ( cRetCode != 0 ) { + return ( cRetCode ); + } + break; + case WAIT: + + /*************************************************************** + * + * Observe delay. + * + ***************************************************************/ + + //09/11/07 NN Type cast mismatch variables + usDelay = (unsigned short) ispVMDataSize(); + ispVMDelay( usDelay ); + +#ifdef VME_DEBUG + if ( usDelay & 0x8000 ) { + + /*************************************************************** + * + * Since MSB is set, the delay time must be decoded to + * millisecond. The SVF2VME encodes the MSB to represent + * millisecond. + * + ***************************************************************/ + + usDelay &= ~0x8000; + if ( g_usDataType & LHEAP_IN ) { + printf( "%.2E SEC;\n", ( float ) usDelay / 1000 ); + } + else { + printf( "RUNTEST %.2E SEC;\n", ( float ) usDelay / 1000 ); + } + } + else { + + /*************************************************************** + * + * Since MSB is not set, the delay time is given as microseconds. + * + ***************************************************************/ + + if ( g_usDataType & LHEAP_IN ) { + printf( "%.2E SEC;\n", ( float ) usDelay / 1000000 ); + } + else { + printf( "RUNTEST %.2E SEC;\n", ( float ) usDelay / 1000000 ); + } + } +#endif //VME_DEBUG + break; + case TCK: + + /*************************************************************** + * + * Issue clock toggles. + * + ***************************************************************/ + + //09/11/07 NN Type cast mismatch variables + usToggle = (unsigned short) ispVMDataSize(); + ispVMClocks( usToggle ); + +#ifdef VME_DEBUG + printf( "RUNTEST %d TCK;\n", usToggle ); +#endif //VME_DEBUG + break; + case ENDDR: + + /*************************************************************** + * + * Set the ENDDR. + * + ***************************************************************/ + + g_ucEndDR = GetByte(); + +#ifdef VME_DEBUG + printf( "ENDDR %s;\n", GetState( g_ucEndDR ) ); +#endif //VME_DEBUG + break; + case ENDIR: + + /*************************************************************** + * + * Set the ENDIR. + * + ***************************************************************/ + + g_ucEndIR = GetByte(); + +#ifdef VME_DEBUG + printf( "ENDIR %s;\n", GetState( g_ucEndIR ) ); +#endif //VME_DEBUG + break; + case HIR: + case TIR: + case HDR: + case TDR: + +#ifdef VME_DEBUG + switch( cOpcode ) { + case HIR: + printf( "HIR " ); + break; + case TIR: + printf( "TIR " ); + break; + case HDR: + printf( "HDR " ); + break; + case TDR: + printf( "TDR " ); + break; + } +#endif //VME_DEBUG + + /*************************************************************** + * + * Set the header/trailer of the device in order to bypass + * successfully. + * + ***************************************************************/ + + cRetCode = ispVMAmble( cOpcode ); + if ( cRetCode != 0 ) { + return ( cRetCode ); + } + +#ifdef VME_DEBUG + printf( ";\n" ); +#endif //VME_DEBUG + break; + case MEM: + + /*************************************************************** + * + * The maximum RAM required to support processing one row of the + * VME file. + * + ***************************************************************/ + + //09/11/07 NN Type cast mismatch variables + g_usMaxSize = (unsigned short) ispVMDataSize(); + +#ifdef VME_DEBUG + printf( "// MEMSIZE %d\n", g_usMaxSize ); +#endif //VME_DEBUG + break; + case VENDOR: + + /*************************************************************** + * + * Set the VENDOR type. + * + ***************************************************************/ + + cOpcode = GetByte(); + switch ( cOpcode ) { + case LATTICE: +#ifdef VME_DEBUG + printf( "// VENDOR LATTICE\n" ); +#endif //VME_DEBUG + g_cVendor = LATTICE; + break; + case ALTERA: +#ifdef VME_DEBUG + printf( "// VENDOR ALTERA\n" ); +#endif //VME_DEBUG + g_cVendor = ALTERA; + break; + case XILINX: +#ifdef VME_DEBUG + printf( "// VENDOR XILINX\n" ); +#endif //VME_DEBUG + g_cVendor = XILINX; + break; + default: + break; + } + break; + case SETFLOW: + + /*************************************************************** + * + * Set the flow control. Flow control determines the personality + * of the embedded engine. + * + ***************************************************************/ + + //09/11/07 NN Type cast mismatch variables + g_usFlowControl |= (unsigned short) ispVMDataSize(); + break; + case RESETFLOW: + + /*************************************************************** + * + * Unset the flow control. + * + ***************************************************************/ + + //09/11/07 NN Type cast mismatch variables + g_usFlowControl &= (unsigned short) ~( ispVMDataSize() ); + break; + case HEAP: + + /*************************************************************** + * + * Allocate heap size to store loops. + * + ***************************************************************/ + + cRetCode = GetByte(); + if ( cRetCode != SECUREHEAP ) { + return VME_INVALID_FILE; + } + //09/11/07 NN Type cast mismatch variables + g_iHEAPSize = (unsigned short) ispVMDataSize(); + + /**************************************************************************** + * + * Store the maximum size of the HEAP buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if ( g_iHEAPSize > g_usHeapSize ) { + g_usHeapSize = g_iHEAPSize; + } + + ispVMMemManager( HEAP, ( unsigned short ) g_iHEAPSize ); + break; + case REPEAT: + + /*************************************************************** + * + * Execute loops. + * + ***************************************************************/ + + g_usRepeatLoops = 0; + + //09/11/07 NN Type cast mismatch variables + iRepeatSize = (unsigned short) ispVMDataSize(); + + cRetCode = ispVMLoop( ( unsigned short ) iRepeatSize ); + if ( cRetCode != 0 ) { + return ( cRetCode ); + } + break; + case ENDLOOP: + + /*************************************************************** + * + * Exit point from processing loops. + * + ***************************************************************/ + + return ( cRetCode ); + case ENDVME: + + /*************************************************************** + * + * The only valid exit point that indicates end of programming. + * + ***************************************************************/ + + return ( cRetCode ); + case SHR: + + /*************************************************************** + * + * Right-shift address. + * + ***************************************************************/ + + g_usFlowControl |= SHIFTRIGHT; + + //09/11/07 NN Type cast mismatch variables + g_usShiftValue = (unsigned short) (g_usRepeatLoops * (unsigned short)GetByte()); + break; + case SHL: + + /*************************************************************** + * + * Left-shift address. + * + ***************************************************************/ + + g_usFlowControl |= SHIFTLEFT; + + //09/11/07 NN Type cast mismatch variables + g_usShiftValue = (unsigned short)(g_usRepeatLoops * (unsigned short)GetByte()); + break; + case FREQUENCY: + + /*************************************************************** + * + * Set the frequency. + * + ***************************************************************/ + + //09/11/07 NN Type cast mismatch variables + g_iFrequency = (int) (ispVMDataSize() ); + //10/23/08 NN changed to check if the frequency smaller than 1000 + if(g_iFrequency >= 1000) + { + g_iFrequency = g_iFrequency / 1000; + if(g_iFrequency == 1) + g_iFrequency = 1000; +#ifdef VME_DEBUG + printf( "FREQUENCY %.2E HZ;\n", ( float ) g_iFrequency * 1000 ); +#endif //VME_DEBUG + } + else + { + if(g_iFrequency == 0) + g_iFrequency = 1000; +#ifdef VME_DEBUG + printf( "FREQUENCY %.2E HZ;\n", ( float ) g_iFrequency ); +#endif //VME_DEBUG + } + break; + case LCOUNT: + + /*************************************************************** + * + * Process LCOUNT command. + * + ***************************************************************/ + + cRetCode = ispVMLCOUNT( ( unsigned short ) ispVMDataSize() ); + if ( cRetCode != 0 ) { + return ( cRetCode ); + } + break; + case VUES: + + /*************************************************************** + * + * Set the flow control to verify USERCODE. + * + ***************************************************************/ + + g_usFlowControl |= VERIFYUES; + break; + case COMMENT: + + /*************************************************************** + * + * Display comment. + * + ***************************************************************/ + + ispVMComment( ( unsigned short ) ispVMDataSize() ); + break; + case LVDS: + + /*************************************************************** + * + * Process LVDS command. + * + ***************************************************************/ + + ispVMProcessLVDS( ( unsigned short ) ispVMDataSize() ); + break; + case HEADER: + + /*************************************************************** + * + * Discard header. + * + ***************************************************************/ + + ispVMHeader( ( unsigned short ) ispVMDataSize() ); + break; + /* 03/14/06 Support Toggle ispENABLE signal*/ + case ispEN: + ucState = GetByte(); + if((ucState == ON)||(ucState == 0x01)) + writePort( g_ucPinENABLE, 0x01 ); + else + writePort( g_ucPinENABLE, 0x00 ); + ispVMDelay( 1 ); + break; + /* 05/24/06 support Toggle TRST pin*/ + case TRST: + ucState = GetByte(); + if(ucState == 0x01) + writePort( g_ucPinTRST, 0x01 ); + else + writePort( g_ucPinTRST, 0x00 ); + ispVMDelay( 1 ); + break; + default: + + /*************************************************************** + * + * Invalid opcode encountered. + * + ***************************************************************/ + +#ifdef VME_DEBUG + printf( "\nINVALID OPCODE: 0x%.2X\n", cOpcode ); +#endif //VME_DEBUG + + return VME_INVALID_FILE; + } + } + + /*************************************************************** + * + * Invalid exit point. Processing the token 'ENDVME' is the only + * valid way to exit the embedded engine. + * + ***************************************************************/ + + return ( VME_INVALID_FILE ); +} + +/*************************************************************** + * + * ispVMDataCode + * + * Processes the TDI/TDO/MASK/DMASK etc of an SIR/SDR command. + * + ***************************************************************/ + +signed char ispVMDataCode() +{ + //09/11/07 NN added local variables initialization + signed char cDataByte = 0; + signed char siDataSource = 0; /*source of data from file by default*/ + + if ( g_usDataType & HEAP_IN ) { + siDataSource = 1; /*the source of data from memory*/ + } + + /**************************************************************************** + * + * Clear the data type register. + * + *****************************************************************************/ + + g_usDataType &= ~( MASK_DATA + TDI_DATA + TDO_DATA + DMASK_DATA + CMASK_DATA ); + + /**************************************************************************** + * + * Iterate through SIR/SDR command and look for TDI, TDO, MASK, etc. + * + *****************************************************************************/ + + while ( ( cDataByte = GetByte() ) >= 0 ) { + + ispVMMemManager( cDataByte, g_usMaxSize ); + switch ( cDataByte ) { + case TDI: + + /**************************************************************************** + * + * Store the maximum size of the TDI buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if ( g_usiDataSize > g_usTDISize ) { + g_usTDISize = g_usiDataSize; + } + /**************************************************************************** + * + * Updated data type register to indicate that TDI data is currently being + * used. Process the data in the VME file into the TDI buffer. + * + *****************************************************************************/ + + g_usDataType |= TDI_DATA; + ispVMData( g_pucInData ); + break; + case XTDO: + + /**************************************************************************** + * + * Store the maximum size of the TDO buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if ( g_usiDataSize > g_usTDOSize ) { + g_usTDOSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Updated data type register to indicate that TDO data is currently being + * used. + * + *****************************************************************************/ + + g_usDataType |= TDO_DATA; + break; + case TDO: + + /**************************************************************************** + * + * Store the maximum size of the TDO buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if ( g_usiDataSize > g_usTDOSize ) { + g_usTDOSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Updated data type register to indicate that TDO data is currently being + * used. Process the data in the VME file into the TDO buffer. + * + *****************************************************************************/ + + g_usDataType |= TDO_DATA; + ispVMData( g_pucOutData ); + break; + case MASK: + + /**************************************************************************** + * + * Store the maximum size of the MASK buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if ( g_usiDataSize > g_usMASKSize ) { + g_usMASKSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Updated data type register to indicate that MASK data is currently being + * used. Process the data in the VME file into the MASK buffer. + * + *****************************************************************************/ + + g_usDataType |= MASK_DATA; + ispVMData( g_pucOutMaskData ); + break; + case DMASK: + + /**************************************************************************** + * + * Store the maximum size of the DMASK buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if ( g_usiDataSize > g_usDMASKSize ) { + g_usDMASKSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Updated data type register to indicate that DMASK data is currently being + * used. Process the data in the VME file into the DMASK buffer. + * + *****************************************************************************/ + + g_usDataType |= DMASK_DATA; + ispVMData( g_pucOutDMaskData ); + break; + case CMASK: + + /**************************************************************************** + * + * Updated data type register to indicate that CMASK data is currently being + * used. Process the data in the VME file into the CMASK buffer. + * + *****************************************************************************/ + + g_usDataType |= CMASK_DATA; + ispVMData( g_pucOutMaskData ); + break; + case CONTINUE: + return ( 0 ); + default: + + /**************************************************************************** + * + * Encountered invalid opcode. + * + *****************************************************************************/ + + return ( VME_INVALID_FILE ); + } + + switch ( cDataByte ) { + case TDI: + + /**************************************************************************** + * + * Left bit shift. Used when performing algorithm looping. + * + *****************************************************************************/ + + if ( g_usFlowControl & SHIFTLEFT ) { + ispVMBitShift( SHL, g_usShiftValue ); + g_usFlowControl &= ~SHIFTLEFT; + } + + /**************************************************************************** + * + * Right bit shift. Used when performing algorithm looping. + * + *****************************************************************************/ + + if ( g_usFlowControl & SHIFTRIGHT ) { + ispVMBitShift( SHR, g_usShiftValue ); + g_usFlowControl &= ~SHIFTRIGHT; + } + default: + break; + } + + if ( siDataSource ) { + g_usDataType |= HEAP_IN; /*restore data from memory*/ + } + } + + if ( siDataSource ) { /*fetch data from heap memory upon return*/ + g_usDataType |= HEAP_IN; + } + + if ( cDataByte < 0 ) { + + /**************************************************************************** + * + * Encountered invalid opcode. + * + *****************************************************************************/ + + return ( VME_INVALID_FILE ); + } + else { + return ( 0 ); + } +} + +/*************************************************************** + * + * ispVMData + * Extract one row of data operand from the current data type opcode. Perform + * the decompression if necessary. Extra RAM is not required for the + * decompression process. The decompression scheme employed in this module + * is on row by row basis. The format of the data stream: + * [compression code][compressed data stream] + * 0x00 --No compression + * 0x01 --Compress by 0x00. + * Example: + * Original stream: 0x000000000000000000000001 + * Compressed stream: 0x01000901 + * Detail: 0x01 is the code, 0x00 is the key, + * 0x09 is the count of 0x00 bytes, + * 0x01 is the uncompressed byte. + * 0x02 --Compress by 0xFF. + * Example: + * Original stream: 0xFFFFFFFFFFFFFFFFFFFFFF01 + * Compressed stream: 0x02FF0901 + * Detail: 0x02 is the code, 0xFF is the key, + * 0x09 is the count of 0xFF bytes, + * 0x01 is the uncompressed byte. + * 0x03 + * : : + * 0xFE -- Compress by nibble blocks. + * Example: + * Original stream: 0x84210842108421084210 + * Compressed stream: 0x0584210 + * Detail: 0x05 is the code, means 5 nibbles block. + * 0x84210 is the 5 nibble blocks. + * The whole row is 80 bits given by g_usiDataSize. + * The number of times the block repeat itself + * is found by g_usiDataSize/(4*0x05) which is 4. + * 0xFF -- Compress by the most frequently happen byte. + * Example: + * Original stream: 0x04020401030904040404 + * Compressed stream: 0xFF04(0,1,0x02,0,1,0x01,1,0x03,1,0x09,0,0,0) + * or: 0xFF044090181C240 + * Detail: 0xFF is the code, 0x04 is the key. + * a bit of 0 represent the key shall be put into + * the current bit position and a bit of 1 + * represent copying the next of 8 bits of data + * in. + * + ***************************************************************/ + +void ispVMData( unsigned char * ByteData ) +{ + //09/11/07 NN added local variables initialization + unsigned short size = 0; + unsigned short i, j, m, getData = 0; + unsigned char cDataByte = 0; + unsigned char compress = 0; + unsigned short FFcount = 0; + unsigned char compr_char = 0xFF; + unsigned short index = 0; + signed char compression = 0; + + /*convert number in bits to bytes*/ + if (g_usiDataSize%8>0) { + //09/11/07 NN Type cast mismatch variables + size = (unsigned short)(g_usiDataSize/8 + 1); + } + else { + //09/11/07 NN Type cast mismatch variables + size = (unsigned short)(g_usiDataSize/8); + } + + /* If there is compression, then check if compress by key of 0x00 or 0xFF + or by other keys or by nibble blocks*/ + + if ( g_usDataType & COMPRESS ) { + compression = 1; + if ( ( ( compress = GetByte() ) == VAR ) && ( g_usDataType & HEAP_IN ) ) { + getData = 1; + g_usDataType &= ~(HEAP_IN); + compress = GetByte(); + } + + switch (compress){ + case 0x00: + /* No compression */ + compression = 0; + break; + case 0x01: + /* Compress by byte 0x00 */ + compr_char = 0x00; + break; + case 0x02: + /* Compress by byte 0xFF */ + compr_char = 0xFF; + break; + case 0xFF: + /* Huffman encoding */ + compr_char = GetByte(); + i = 8; + for ( index = 0; index < size; index++ ) { + ByteData[ index ] = 0x00; + if ( i > 7 ) { + cDataByte = GetByte(); + i = 0; + } + if ((cDataByte << i++) & 0x80) + m = 8; + else { + ByteData[index] = compr_char; + m = 0; + } + + for (j = 0; j < m; j++) { + if (i > 7) { + cDataByte = GetByte(); + i = 0; + } + ByteData[index] |=((cDataByte << i++)&0x80) >> j; + } + } + size = 0; + break; + default: + for (index = 0; index < size; index++) + ByteData[index] = 0x00; + for (index = 0; index < compress; index++) { + if (index%2 == 0) + cDataByte = GetByte(); + for (i = 0; i < size*2/compress; i++){ + //09/11/07 NN Type cast mismatch variables + j = (unsigned short)(index + (i*(unsigned short)compress)); + /*clear the nibble to zero first*/ + if (j%2) { + if (index%2) + ByteData[j/2] |= cDataByte & 0x0F; + else + ByteData[j/2] |= cDataByte >> 4; + } + else { + if (index%2) + ByteData[j/2] |= cDataByte << 4; + else + ByteData[j/2] |= cDataByte & 0xF0; + } + } + } + size = 0; + break; + } + } + + FFcount = 0; + + /* Decompress by byte 0x00 or 0xFF */ + for (index = 0; index < size; index++) { + if (FFcount <= 0) { + cDataByte = GetByte(); + if ((cDataByte == VAR) && (g_usDataType&HEAP_IN) && !getData && !(g_usDataType&COMPRESS)) { + getData = 1; + g_usDataType &= ~(HEAP_IN); + cDataByte = GetByte(); + } + ByteData[index] = cDataByte; + if ((compression) &&(cDataByte == compr_char)) /*decompression is on*/ + //09/11/07 NN Type cast mismatch variables + FFcount = (unsigned short) ispVMDataSize(); /*The number of 0xFF or 0x00 bytes*/ + } + else { + FFcount--; /*Use up the 0xFF chain first*/ + ByteData[index] = compr_char; + } + } + + if (getData) { + g_usDataType |= HEAP_IN; + getData = 0; + } +} + +/*************************************************************** + * + * ispVMShift + * + * Processes the SDR/XSDR/SIR commands. + * + ***************************************************************/ + +signed char ispVMShift( signed char a_cCode ) +{ + //09/11/07 NN added local variables initialization + unsigned short iDataIndex = 0; + unsigned short iReadLoop = 0; + signed char cRetCode = 0; + + cRetCode=0; + //09/11/07 NN Type cast mismatch variables + g_usiDataSize = (unsigned short) ispVMDataSize(); + + g_usDataType &= ~( SIR_DATA + EXPRESS + SDR_DATA ); /*clear the flags first*/ + switch ( a_cCode ) { + case SIR: + g_usDataType |= SIR_DATA; + /* 1/15/04 If performing cascading, then go directly to SHIFTIR. Else, + go to IRPAUSE before going to SHIFTIR */ + if ( g_usFlowControl & CASCADE ) { + ispVMStateMachine( SHIFTIR ); + } + else { + ispVMStateMachine( IRPAUSE ); + ispVMStateMachine( SHIFTIR ); + if ( g_usHeadIR > 0 ){ + ispVMBypass( HIR, g_usHeadIR ); + sclock(); + } + } + break; + case XSDR: + g_usDataType |= EXPRESS; /*mark simultaneous in and out*/ + /* FALLTHRU */ + case SDR: + g_usDataType |= SDR_DATA; + /* 1/15/04 If already in SHIFTDR, then do not move state or shift in header. + This would imply that the previously shifted frame was a cascaded frame. */ + if ( g_cCurrentJTAGState != SHIFTDR ) { + /* 1/15/04 If performing cascading, then go directly to SHIFTDR. Else, + go to DRPAUSE before going to SHIFTDR */ + if ( g_usFlowControl & CASCADE ) { + if ( g_cCurrentJTAGState == DRPAUSE ) { + ispVMStateMachine( SHIFTDR ); + /* 1/15/04 If cascade flag has been set and the current state is + DRPAUSE, this implies that the first cascaded frame is about to + be shifted in. The header must be shifted prior to shifting + the first cascaded frame. */ + if ( g_usHeadDR > 0 ) { + ispVMBypass( HDR, g_usHeadDR ); + sclock(); + } + } + else { + ispVMStateMachine( SHIFTDR ); + } + } + else { + ispVMStateMachine( DRPAUSE ); + ispVMStateMachine( SHIFTDR ); + if ( g_usHeadDR > 0 ) { + ispVMBypass( HDR, g_usHeadDR ); + sclock(); + } + } + } + break; + default: + return ( VME_INVALID_FILE ); + } + + cRetCode = ispVMDataCode(); + + if ( cRetCode != 0 ) { + return ( VME_INVALID_FILE ); + } + +#ifdef VME_DEBUG + printf( "%d ", g_usiDataSize ); + + if ( g_usDataType & TDI_DATA ) { + printf( "TDI " ); + PrintData( g_usiDataSize, g_pucInData ); + } + + if ( g_usDataType & TDO_DATA ) { + printf( "\n\t\tTDO " ); + PrintData( g_usiDataSize, g_pucOutData ); + } + + if ( g_usDataType & MASK_DATA ) { + printf( "\n\t\tMASK " ); + PrintData( g_usiDataSize, g_pucOutMaskData ); + } + + if ( g_usDataType & DMASK_DATA ) { + printf( "\n\t\tDMASK " ); + PrintData( g_usiDataSize, g_pucOutDMaskData ); + } + + printf( ";\n" ); +#endif //VME_DEBUG + + if ( g_usDataType & TDO_DATA || g_usDataType & DMASK_DATA ) { + if(g_usDataType & DMASK_DATA){ + cRetCode = ispVMReadandSave( g_usiDataSize ); + if(!cRetCode){ + if ( g_usTailDR > 0 ) { + sclock(); + ispVMBypass( TDR, g_usTailDR ); + } + ispVMStateMachine( DRPAUSE ); + ispVMStateMachine( SHIFTDR ); + if( g_usHeadDR > 0 ){ + ispVMBypass( HDR, g_usHeadDR ); + sclock(); + } + for ( iDataIndex=0; iDataIndex < g_usiDataSize / 8 + 1; iDataIndex++ ) + g_pucInData[ iDataIndex ] = g_pucOutData[ iDataIndex ]; + g_usDataType &= ~( TDO_DATA+ DMASK_DATA ); + cRetCode = ispVMSend( g_usiDataSize ); + } + } + else{ + cRetCode = ispVMRead( g_usiDataSize ); + if ( cRetCode == -1 && g_cVendor == XILINX ) { + for( iReadLoop = 0; iReadLoop < 30; iReadLoop++ ){ + cRetCode = ispVMRead( g_usiDataSize ); + if( !cRetCode ) { + break; + } + else { + ispVMStateMachine( DRPAUSE ); /*Always DRPAUSE*/ + /*Bypass other devices when appropriate*/ + ispVMBypass( TDR, g_usTailDR ); + ispVMStateMachine( g_ucEndDR ); + ispVMStateMachine( IDLE ); + ispVMDelay( 0x8001 ); + } + } + } + } + } + else { /*TDI only*/ + cRetCode = ispVMSend( g_usiDataSize ); + } + + /*transfer the input data to the output buffer for the next verify*/ + if ( ( g_usDataType & EXPRESS ) || ( a_cCode == SDR ) ) { + if ( g_pucOutData ) { + for ( iDataIndex=0; iDataIndex < g_usiDataSize / 8 + 1; iDataIndex++ ) + g_pucOutData[ iDataIndex ] = g_pucInData[ iDataIndex ]; + } + } + + switch( a_cCode ) { + case SIR: + /* 1/15/04 If not performing cascading, then shift ENDIR */ + if ( !( g_usFlowControl & CASCADE ) ) { + if ( g_usTailIR > 0 ) { + sclock(); + ispVMBypass( TIR, g_usTailIR ); + } + ispVMStateMachine( g_ucEndIR ); + } + break; + case XSDR: + case SDR: + /* 1/15/04 If not performing cascading, then shift ENDDR */ + if ( !( g_usFlowControl & CASCADE ) ) { + if ( g_usTailDR > 0 ) { + sclock(); + ispVMBypass( TDR, g_usTailDR ); + } + ispVMStateMachine( g_ucEndDR ); + } + break; + default: + break; + } + + return ( cRetCode ); +} + +/*************************************************************** + * + * ispVMAmble + * + * This routine is to extract Header and Trailer parameter for SIR and + * SDR operations. + * + * The Header and Trailer parameter are the pre-amble and post-amble bit + * stream need to be shifted into TDI or out of TDO of the devices. Mostly + * is for the purpose of bypassing the leading or trailing devices. ispVM + * supports only shifting data into TDI to bypass the devices. + * + * For a single device, the header and trailer parameters are all set to 0 + * as default by ispVM. If it is for multiple devices, the header and trailer + * value will change as specified by the VME file. + * + ***************************************************************/ + +signed char ispVMAmble( signed char Code ) +{ + signed char compress = 0; + //09/11/07 NN Type cast mismatch variables + g_usiDataSize = (unsigned short)ispVMDataSize(); + +#ifdef VME_DEBUG + printf( "%d", g_usiDataSize ); +#endif //VME_DEBUG + + if ( g_usiDataSize ) { + + /**************************************************************************** + * + * Discard the TDI byte and set the compression bit in the data type register + * to false if compression is set because TDI data after HIR/HDR/TIR/TDR is not + * compressed. + * + *****************************************************************************/ + + GetByte(); + if ( g_usDataType & COMPRESS ) { + g_usDataType &= ~( COMPRESS ); + compress = 1; + } + } + + switch ( Code ) { + case HIR: + + /**************************************************************************** + * + * Store the maximum size of the HIR buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if ( g_usiDataSize > g_usHIRSize ) { + g_usHIRSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Assign the HIR value and allocate memory. + * + *****************************************************************************/ + + g_usHeadIR = g_usiDataSize; + if ( g_usHeadIR ) { + ispVMMemManager( HIR, g_usHeadIR ); + ispVMData( g_pucHIRData ); + +#ifdef VME_DEBUG + printf( " TDI " ); + PrintData( g_usHeadIR, g_pucHIRData ); +#endif //VME_DEBUG + } + break; + case TIR: + + /**************************************************************************** + * + * Store the maximum size of the TIR buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if ( g_usiDataSize > g_usTIRSize ) { + g_usTIRSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Assign the TIR value and allocate memory. + * + *****************************************************************************/ + + g_usTailIR = g_usiDataSize; + if ( g_usTailIR ) { + ispVMMemManager( TIR, g_usTailIR ); + ispVMData( g_pucTIRData ); + +#ifdef VME_DEBUG + printf( " TDI " ); + PrintData( g_usTailIR, g_pucTIRData ); +#endif //VME_DEBUG + } + break; + case HDR: + + /**************************************************************************** + * + * Store the maximum size of the HDR buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if ( g_usiDataSize > g_usHDRSize ) { + g_usHDRSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Assign the HDR value and allocate memory. + * + *****************************************************************************/ + + g_usHeadDR = g_usiDataSize; + if ( g_usHeadDR ) { + ispVMMemManager( HDR, g_usHeadDR ); + ispVMData( g_pucHDRData ); + +#ifdef VME_DEBUG + printf( " TDI " ); + PrintData( g_usHeadDR, g_pucHDRData ); +#endif //VME_DEBUG + } + break; + case TDR: + + /**************************************************************************** + * + * Store the maximum size of the TDR buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if ( g_usiDataSize > g_usTDRSize ) { + g_usTDRSize = g_usiDataSize; + } + + /**************************************************************************** + * + * Assign the TDR value and allocate memory. + * + *****************************************************************************/ + + g_usTailDR = g_usiDataSize; + if ( g_usTailDR ) { + ispVMMemManager( TDR, g_usTailDR ); + ispVMData( g_pucTDRData ); + +#ifdef VME_DEBUG + printf( " TDI " ); + PrintData( g_usTailDR, g_pucTDRData ); +#endif //VME_DEBUG + } + break; + default: + break; + } + + /**************************************************************************** + * + * Re-enable compression if it was previously set. + * + *****************************************************************************/ + + if ( compress ) { + g_usDataType |= COMPRESS; + } + + if ( g_usiDataSize ) { + Code = GetByte(); + if ( Code == CONTINUE ) { + return 0; + } + else { + + /**************************************************************************** + * + * Encountered invalid opcode. + * + *****************************************************************************/ + + return VME_INVALID_FILE; + } + } + + return 0; +} + +/*************************************************************** + * + * ispVMLoop + * + * Perform the function call upon by the REPEAT opcode. + * Memory is to be allocated to store the entire loop from REPEAT to ENDLOOP. + * After the loop is stored then execution begin. The REPEATLOOP flag is set + * on the g_usFlowControl register to indicate the repeat loop is in session + * and therefore fetch opcode from the memory instead of from the file. + * + ***************************************************************/ + +signed char ispVMLoop(unsigned short a_usLoopCount) +{ + //09/11/07 NN added local variables initialization + signed char cRetCode = 0; + unsigned short iHeapIndex = 0; + unsigned short iLoopIndex = 0; + + g_usShiftValue = 0; + for ( iHeapIndex = 0; iHeapIndex < g_iHEAPSize; iHeapIndex++ ) { + g_pucHeapMemory[ iHeapIndex ] = GetByte(); + } + + if ( g_pucHeapMemory[ iHeapIndex - 1 ] != ENDLOOP ) { + return( VME_INVALID_FILE ); + } + + g_usFlowControl |= REPEATLOOP; + g_usDataType |= HEAP_IN; + + for ( iLoopIndex = 0; iLoopIndex < a_usLoopCount; iLoopIndex++ ) { + g_iHeapCounter = 0; + cRetCode = ispVMCode(); + g_usRepeatLoops++; + if ( cRetCode < 0 ) { + break; + } + } + + g_usDataType &= ~( HEAP_IN ); + g_usFlowControl &= ~( REPEATLOOP ); + return ( cRetCode ); +} + +/*************************************************************** + * + * ispVMBitShift + * + * Shift the TDI stream left or right by the number of bits. The data in + * *g_pucInData is of the VME format, so the actual shifting is the reverse of + * IEEE 1532 or SVF format. + * + ***************************************************************/ + +signed char ispVMBitShift(signed char mode, unsigned short bits) +{ + //09/11/07 NN added local variables initialization + unsigned short i = 0; + unsigned short size = 0; + unsigned short tmpbits = 0; + + if (g_usiDataSize%8>0) { + //09/11/07 NN Type cast mismatch variables + size = (unsigned short)(g_usiDataSize/8 + 1); + } + else { + //09/11/07 NN Type cast mismatch variables + size = (unsigned short)(g_usiDataSize/8); + } + + switch(mode) { + case SHR: + for (i = 0; i < size; i++) { + if (g_pucInData[i] != 0) { + tmpbits = bits; + while (tmpbits > 0) { + g_pucInData[i] <<= 1; + if (g_pucInData[i] == 0) { + i--; + g_pucInData[i] = 1; + } + tmpbits--; + } + } + } + break; + case SHL: + for (i = 0; i < size; i++) { + if (g_pucInData[i] != 0) { + tmpbits = bits; + while (tmpbits > 0) { + g_pucInData[i] >>= 1; + if (g_pucInData[i] == 0) { + i--; + g_pucInData[i] = 8; + } + tmpbits--; + } + } + } + break; + default: + return ( VME_INVALID_FILE ); + } + + return (0); +} + +/*************************************************************** + * + * ispVMComment + * + * Displays the SVF comments. + * + ***************************************************************/ + +void ispVMComment( unsigned short a_usCommentSize ) +{ + char cCurByte = 0; + for ( ; a_usCommentSize > 0; a_usCommentSize-- ) { + /**************************************************************************** + * + * Print character to the terminal. + * + *****************************************************************************/ + cCurByte = GetByte(); + vme_out_char( cCurByte ); + } + cCurByte = '\n'; + vme_out_char(cCurByte ); +} + +/*************************************************************** + * + * ispVMHeader + * + * Iterate the length of the header and discard it. + * + ***************************************************************/ + +void ispVMHeader( unsigned short a_usHeaderSize ) +{ + for ( ; a_usHeaderSize > 0; a_usHeaderSize-- ) { + GetByte(); + } +} + +/*************************************************************** + * + * ispVMCalculateCRC32 + * + * Calculate the 32-bit CRC. + * + ***************************************************************/ + +void ispVMCalculateCRC32( unsigned char a_ucData ) +{ + //09/11/07 NN added local variables initialization + unsigned char ucIndex = 0; + unsigned char ucFlipData = 0; + unsigned short usCRCTableEntry = 0; + unsigned int crc_table[ 16 ] = { + 0x0000, 0xCC01, 0xD801, + 0x1400, 0xF001, 0x3C00, + 0x2800, 0xE401, 0xA001, + 0x6C00, 0x7800, 0xB401, + 0x5000, 0x9C01, 0x8801, + 0x4400 + }; + + for ( ucIndex = 0; ucIndex < 8; ucIndex++ ) { + ucFlipData <<= 1; + if ( a_ucData & 0x01 ) { + ucFlipData |= 0x01; + } + a_ucData >>= 1; + } + + //09/11/07 NN Type cast mismatch variables + usCRCTableEntry = (unsigned short)(crc_table[ g_usCalculatedCRC & 0xF ]); + g_usCalculatedCRC = (unsigned short)(( g_usCalculatedCRC >> 4 ) & 0x0FFF); + g_usCalculatedCRC = (unsigned short)(g_usCalculatedCRC ^ usCRCTableEntry ^ crc_table[ ucFlipData & 0xF ]); + usCRCTableEntry = (unsigned short)(crc_table[ g_usCalculatedCRC & 0xF ]); + g_usCalculatedCRC = (unsigned short)(( g_usCalculatedCRC >> 4 ) & 0x0FFF); + g_usCalculatedCRC = (unsigned short)(g_usCalculatedCRC ^ usCRCTableEntry ^ crc_table[ ( ucFlipData >> 4 ) & 0xF ]); +} + +/*************************************************************** + * + * ispVMLCOUNT + * + * Process the intelligent programming loops. + * + ***************************************************************/ + +signed char ispVMLCOUNT( unsigned short a_usCountSize ) +{ + unsigned short usContinue = 1; + unsigned short usIntelBufferIndex = 0; + unsigned short usCountIndex = 0; + signed char cRetCode = 0; + signed char cRepeatHeap = 0; + signed char cOpcode = 0; + unsigned char ucState = 0; + unsigned short usDelay = 0; + unsigned short usToggle = 0; + // unsigned char usByte = 0; + + g_usIntelBufferSize = (unsigned short)ispVMDataSize(); + + /**************************************************************************** + * + * Allocate memory for intel buffer. + * + *****************************************************************************/ + + ispVMMemManager( LHEAP, g_usIntelBufferSize ); + + /**************************************************************************** + * + * Store the maximum size of the intelligent buffer. Used to convert VME to HEX. + * + *****************************************************************************/ + + if ( g_usIntelBufferSize > g_usLCOUNTSize ) { + g_usLCOUNTSize = g_usIntelBufferSize; + } + + /**************************************************************************** + * + * Copy intel data to the buffer. + * + *****************************************************************************/ + + for ( usIntelBufferIndex = 0; usIntelBufferIndex < g_usIntelBufferSize; usIntelBufferIndex++ ) { + g_pucIntelBuffer[ usIntelBufferIndex ] = GetByte(); + } + + /**************************************************************************** + * + * Set the data type register to get data from the intelligent data buffer. + * + *****************************************************************************/ + + g_usDataType |= LHEAP_IN; + + /**************************************************************************** + * + * If the HEAP_IN flag is set, temporarily unset the flag so data will be + * retrieved from the status buffer. + * + *****************************************************************************/ + + if ( g_usDataType & HEAP_IN ) { + g_usDataType &= ~HEAP_IN; + cRepeatHeap = 1; + } + +#ifdef VME_DEBUG + printf( "LCOUNT %d;\n", a_usCountSize ); +#endif //VME_DEBUG + + /**************************************************************************** + * + * Iterate through the intelligent programming command. + * + *****************************************************************************/ + + for ( usCountIndex = 0; usCountIndex < a_usCountSize; usCountIndex++ ) { + + /**************************************************************************** + * + * Initialize the intel data index to 0 before each iteration. + * + *****************************************************************************/ + + g_usIntelDataIndex = 0; + cOpcode = 0; + ucState = 0; + usDelay = 0; + usToggle = 0; + // usByte = 0; + usContinue = 1; + + /*************************************************************** + * + * Begin looping through all the VME opcodes. + * + ***************************************************************/ + /*************************************************************** + * 4/1/09 Nguyen replaced the recursive function call codes on + * the ispVMLCOUNT function + * + ***************************************************************/ + while ( usContinue ) + { + cOpcode = GetByte(); + switch ( cOpcode ) { + case HIR: + case TIR: + case HDR: + case TDR: + /*************************************************************** + * + * Set the header/trailer of the device in order to bypass + * successfully. + * + ***************************************************************/ + + ispVMAmble( cOpcode ); + break; + case STATE: + + /*************************************************************** + * + * Step the JTAG state machine. + * + ***************************************************************/ + + ucState = GetByte(); + /*************************************************************** + * + * Step the JTAG state machine to DRCAPTURE to support Looping. + * + ***************************************************************/ + + if ( (g_usDataType & LHEAP_IN) && + (ucState == DRPAUSE ) && + ( g_cCurrentJTAGState == ucState )) + { + ispVMStateMachine( DRCAPTURE ); + } + ispVMStateMachine( ucState ); +#ifdef VME_DEBUG + printf( "LDELAY %s ", GetState( ucState ) ); +#endif //VME_DEBUG + break; + case SIR: +#ifdef VME_DEBUG + printf( "SIR " ); +#endif //VME_DEBUG + /*************************************************************** + * + * Shift in data into the device. + * + ***************************************************************/ + + cRetCode = ispVMShift( cOpcode ); + break; + case SDR: + +#ifdef VME_DEBUG + printf( "LSDR " ); +#endif //VME_DEBUG + /*************************************************************** + * + * Shift in data into the device. + * + ***************************************************************/ + + cRetCode = ispVMShift( cOpcode ); + break; + case WAIT: + + /*************************************************************** + * + * Observe delay. + * + ***************************************************************/ + + usDelay = (unsigned short)ispVMDataSize(); + ispVMDelay( usDelay ); + +#ifdef VME_DEBUG + if ( usDelay & 0x8000 ) { + + /*************************************************************** + * + * Since MSB is set, the delay time must be decoded to + * millisecond. The SVF2VME encodes the MSB to represent + * millisecond. + * + ***************************************************************/ + + usDelay &= ~0x8000; + printf( "%.2E SEC;\n", ( float ) usDelay / 1000 ); + } + else { + + /*************************************************************** + * + * Since MSB is not set, the delay time is given as microseconds. + * + ***************************************************************/ + + printf( "%.2E SEC;\n", ( float ) usDelay / 1000000 ); + } +#endif //VME_DEBUG + break; + case TCK: + + /*************************************************************** + * + * Issue clock toggles. + * + ***************************************************************/ + + usToggle = (unsigned short)ispVMDataSize(); + ispVMClocks( usToggle ); + +#ifdef VME_DEBUG + printf( "RUNTEST %d TCK;\n", usToggle ); +#endif //VME_DEBUG + break; + case ENDLOOP: + + /*************************************************************** + * + * Exit point from processing loops. + * + ***************************************************************/ + usContinue = 0; + break; + + case COMMENT: + + /*************************************************************** + * + * Display comment. + * + ***************************************************************/ + + ispVMComment( ( unsigned short ) ispVMDataSize() ); + break; + case ispEN: + ucState = GetByte(); + if((ucState == ON)||(ucState == 0x01)) + writePort( g_ucPinENABLE, 0x01 ); + else + writePort( g_ucPinENABLE, 0x00 ); + ispVMDelay( 1 ); + break; + case TRST: + if(GetByte() == 0x01) + writePort( g_ucPinTRST, 0x01 ); + else + writePort( g_ucPinTRST, 0x00 ); + ispVMDelay( 1 ); + break; + default: + + /*************************************************************** + * + * Invalid opcode encountered. + * + ***************************************************************/ + +#ifdef VME_DEBUG + printf( "\nINVALID OPCODE: 0x%.2X\n", cOpcode ); +#endif //VME_DEBUG + + return VME_INVALID_FILE; + } + } + if ( cRetCode >= 0 ) { + /**************************************************************************** + * + * Break if intelligent programming is successful. + * + *****************************************************************************/ + + break; + } + + } + /**************************************************************************** + * + * If HEAP_IN flag was temporarily disabled, re-enable it before exiting. + * + *****************************************************************************/ + + if ( cRepeatHeap ) { + g_usDataType |= HEAP_IN; + } + + /**************************************************************************** + * + * Set the data type register to not get data from the intelligent data buffer. + * + *****************************************************************************/ + + g_usDataType &= ~LHEAP_IN; + return cRetCode; +} + +/*************************************************************** + * + * ispVMClocks + * + * Applies the specified number of pulses to TCK. + * + ***************************************************************/ + +void ispVMClocks( unsigned short Clocks ) +{ + unsigned short iClockIndex = 0; + for ( iClockIndex = 0; iClockIndex < Clocks; iClockIndex++ ) { + sclock(); + } +} + +/*************************************************************** + * + * ispVMBypass + * + * This procedure takes care of the HIR, HDR, TIR, TDR for the + * purpose of putting the other devices into Bypass mode. The + * current state is checked to find out if it is at DRPAUSE or + * IRPAUSE. If it is at DRPAUSE, perform bypass register scan. + * If it is at IRPAUSE, scan into instruction registers the bypass + * instruction. + * + ***************************************************************/ + +void ispVMBypass( signed char ScanType, unsigned short Bits ) +{ + //09/11/07 NN added local variables initialization + unsigned short iIndex = 0; + unsigned short iSourceIndex = 0; + unsigned char cBitState = 0; + unsigned char cCurByte = 0; + unsigned char * pcSource = NULL; + + if ( Bits <= 0 ) { + return; + } + + switch ( ScanType ) { + case HIR: + pcSource = g_pucHIRData; + break; + case TIR: + pcSource = g_pucTIRData; + break; + case HDR: + pcSource = g_pucHDRData; + break; + case TDR: + pcSource = g_pucTDRData; + break; + default: + break; + } + if(pcSource) + { + iSourceIndex = 0; + cBitState = 0; + for ( iIndex = 0; iIndex < Bits - 1; iIndex++ ) { + /* Scan instruction or bypass register */ + if ( iIndex % 8 == 0 ) { + cCurByte = pcSource[ iSourceIndex++ ]; + } + cBitState = ( unsigned char ) ( ( ( cCurByte << iIndex % 8 ) & 0x80 ) ? 0x01 : 0x00 ); + writePort( g_ucPinTDI, cBitState ); + sclock(); + } + + if ( iIndex % 8 == 0 ) { + cCurByte = pcSource[ iSourceIndex++ ]; + } + + cBitState = ( unsigned char ) ( ( ( cCurByte << iIndex % 8 ) & 0x80 ) ? 0x01 : 0x00 ); + writePort( g_ucPinTDI, cBitState ); + } +} + +/*************************************************************** + * + * ispVMStateMachine + * + * This procedure steps all devices in the daisy chain from a given + * JTAG state to the next desirable state. If the next state is TLR, + * the JTAG state machine is brute forced into TLR by driving TMS + * high and pulse TCK 6 times. + * + ***************************************************************/ + +void ispVMStateMachine( signed char cNextJTAGState ) +{ + //09/11/07 NN added local variables initialization + signed char cPathIndex = 0; + signed char cStateIndex = 0; + short int found = 0; + + if ( ( g_cCurrentJTAGState == cNextJTAGState ) && ( cNextJTAGState != RESET ) ) { + return; + } + + for ( cStateIndex = 0; cStateIndex < 25; cStateIndex++ ) { + if ( ( g_cCurrentJTAGState == g_JTAGTransistions[ cStateIndex ].CurState ) && ( cNextJTAGState == g_JTAGTransistions[cStateIndex].NextState ) ) { + found = 1; + break; + } + } + if(found) + { + g_cCurrentJTAGState = cNextJTAGState; + for ( cPathIndex = 0; cPathIndex < g_JTAGTransistions[ cStateIndex ].Pulses; cPathIndex++ ) { + if ( ( g_JTAGTransistions[ cStateIndex ].Pattern << cPathIndex ) & 0x80 ) { + writePort( g_ucPinTMS, ( unsigned char ) 0x01 ); + } + else { + writePort( g_ucPinTMS, ( unsigned char ) 0x00 ); + } + sclock(); + } + + writePort( g_ucPinTDI, 0x00 ); + writePort( g_ucPinTMS, 0x00 ); + } +} + +/*************************************************************** + * + * ispVMStart + * + * Enable the port to the device and set the state to RESET (TLR). + * + ***************************************************************/ + +void ispVMStart() +{ +#ifdef VME_DEBUG + printf( "// ISPVM EMBEDDED ADDED\n" ); + printf( "STATE RESET;\n" ); +#endif + + ispVMStateMachine( RESET ); /*step devices to RESET state*/ +} + +/*************************************************************** + * + * ispVMEnd + * + * Set the state of devices to RESET to enable the devices and disable + * the port. + * + ***************************************************************/ + +void ispVMEnd() +{ +#ifdef VME_DEBUG + printf( "// ISPVM EMBEDDED ADDED\n" ); + printf( "STATE RESET;\n" ); + printf( "RUNTEST 1.00E-001 SEC;\n" ); +#endif + + ispVMStateMachine( RESET ); /*step devices to RESET state */ + ispVMDelay( 0x8001 ); /*wake up devices*/ +} + +/*************************************************************** + * + * ispVMSend + * + * Send the TDI data stream to devices. The data stream can be + * instructions or data. + * + ***************************************************************/ + +signed char ispVMSend( unsigned short a_usiDataSize ) +{ + //09/11/07 NN added local variables initialization + unsigned short iIndex = 0; + unsigned short iInDataIndex = 0; + unsigned char cCurByte = 0; + unsigned char cBitState = 0; + + for ( iIndex = 0; iIndex < a_usiDataSize - 1; iIndex++ ) { + if ( iIndex % 8 == 0 ) { + cCurByte = g_pucInData[ iInDataIndex++ ]; + } + cBitState = ( unsigned char ) ( ( ( cCurByte << iIndex % 8 ) & 0x80 ) ? 0x01 : 0x00 ); + writePort( g_ucPinTDI, cBitState ); + sclock(); + } + + if ( iIndex % 8 == 0 ) { + /* Take care of the last bit */ + cCurByte = g_pucInData[ iInDataIndex ]; + } + + cBitState = ( unsigned char ) ( ( ( cCurByte << iIndex % 8 ) & 0x80 ) ? 0x01 : 0x00 ); + + writePort( g_ucPinTDI, cBitState ); + if ( g_usFlowControl & CASCADE ) { + /* 1/15/04 Clock in last bit for the first n-1 cascaded frames */ + sclock(); + } + + return 0; +} + +/*************************************************************** + * + * ispVMRead + * + * Read the data stream from devices and verify. + * + ***************************************************************/ + +signed char ispVMRead( unsigned short a_usiDataSize ) +{ + //09/11/07 NN added local variables initialization + unsigned short usDataSizeIndex = 0; + unsigned short usErrorCount = 0; + unsigned short usLastBitIndex = 0; + unsigned char cDataByte = 0; + unsigned char cMaskByte = 0; + unsigned char cInDataByte = 0; + unsigned char cCurBit = 0; + unsigned char cByteIndex = 0; + unsigned short usBufferIndex = 0; + unsigned char ucDisplayByte = 0x00; + unsigned char ucDisplayFlag = 0x01; + char StrChecksum[256] = {0}; + unsigned char g_usCalculateChecksum = 0x00; + + //09/11/07 NN Type cast mismatch variables + usLastBitIndex = (unsigned short)(a_usiDataSize - 1); + +#ifndef VME_DEBUG + /**************************************************************************** + * + * If mask is not all zeros, then set the display flag to 0x00, otherwise + * it shall be set to 0x01 to indicate that data read from the device shall + * be displayed. If VME_DEBUG is defined, always display data. + * + *****************************************************************************/ + + for ( usDataSizeIndex = 0; usDataSizeIndex < ( a_usiDataSize + 7 ) / 8; usDataSizeIndex++ ) { + if ( g_usDataType & MASK_DATA ) { + if ( g_pucOutMaskData[ usDataSizeIndex ] != 0x00 ) { + ucDisplayFlag = 0x00; + break; + } + } + else if ( g_usDataType & CMASK_DATA ) { + g_usCalculateChecksum = 0x01; + ucDisplayFlag = 0x00; + break; + } + else { + ucDisplayFlag = 0x00; + break; + } + } +#endif //VME_DEBUG + + /**************************************************************************** + * + * Begin shifting data in and out of the device. + * + *****************************************************************************/ + + for ( usDataSizeIndex = 0; usDataSizeIndex < a_usiDataSize; usDataSizeIndex++ ) { + if ( cByteIndex == 0 ) { + + /*************************************************************** + * + * Grab byte from TDO buffer. + * + ***************************************************************/ + + if ( g_usDataType & TDO_DATA ) { + cDataByte = g_pucOutData[ usBufferIndex ]; + } + + /*************************************************************** + * + * Grab byte from MASK buffer. + * + ***************************************************************/ + + if ( g_usDataType & MASK_DATA ) { + cMaskByte = g_pucOutMaskData[ usBufferIndex ]; + } + else { + cMaskByte = 0xFF; + } + + /*************************************************************** + * + * Grab byte from CMASK buffer. + * + ***************************************************************/ + + if ( g_usDataType & CMASK_DATA ) { + cMaskByte = 0x00; + g_usCalculateChecksum = 0x01; + } + + /*************************************************************** + * + * Grab byte from TDI buffer. + * + ***************************************************************/ + + if ( g_usDataType & TDI_DATA ) { + cInDataByte = g_pucInData[ usBufferIndex ]; + } + + usBufferIndex++; + } + + cCurBit = readPort(); + + if ( ucDisplayFlag ) { + ucDisplayByte <<= 1; + ucDisplayByte |= cCurBit; + } + + /**************************************************************************** + * + * Check if data read from port matches with expected TDO. + * + *****************************************************************************/ + + if ( g_usDataType & TDO_DATA ) { + //08/28/08 NN Added Calculate checksum support. + if( g_usCalculateChecksum ) + { + if(cCurBit == 0x01) + g_usChecksum += (1 << (g_uiChecksumIndex % 8)); + g_uiChecksumIndex++; + } + else + { + if ( ( ( ( cMaskByte << cByteIndex ) & 0x80 ) ? 0x01 : 0x00 ) ) { + if ( cCurBit != ( unsigned char ) ( ( ( cDataByte << cByteIndex ) & 0x80 ) ? 0x01 : 0x00 ) ) { + usErrorCount++; + } + } + } + } + + /**************************************************************************** + * + * Write TDI data to the port. + * + *****************************************************************************/ + + writePort( g_ucPinTDI, ( unsigned char ) ( ( ( cInDataByte << cByteIndex ) & 0x80 ) ? 0x01 : 0x00 ) ); + + if ( usDataSizeIndex < usLastBitIndex ) { + + /**************************************************************************** + * + * Clock data out from the data shift register. + * + *****************************************************************************/ + + sclock(); + } + else if ( g_usFlowControl & CASCADE ) { + + /**************************************************************************** + * + * Clock in last bit for the first N - 1 cascaded frames. + * + *****************************************************************************/ + + sclock(); + } + + /*************************************************************** + * + * Increment the byte index. If it exceeds 7, then reset it back + * to zero. + * + ***************************************************************/ + + cByteIndex++; + if ( cByteIndex >= 8 ) { + if ( ucDisplayFlag ) { + + /*************************************************************** + * + * Store displayed data in the TDO buffer. By reusing the TDO + * buffer to store displayed data, there is no need to allocate + * a buffer simply to hold display data. This will not cause any + * false verification errors because the true TDO byte has already + * been consumed. + * + ***************************************************************/ + + g_pucOutData[ usBufferIndex - 1 ] = ucDisplayByte; + ucDisplayByte = 0; + } + + cByteIndex = 0; + } + //09/12/07 Nguyen changed to display the 1 bit expected data + else if(a_usiDataSize == 1) + { + if ( ucDisplayFlag ) { + + /*************************************************************** + * + * Store displayed data in the TDO buffer. By reusing the TDO + * buffer to store displayed data, there is no need to allocate + * a buffer simply to hold display data. This will not cause any + * false verification errors because the true TDO byte has already + * been consumed. + * + ***************************************************************/ + + /**************************************************************************** + * + * Flip ucDisplayByte and store it in cDataByte. + * + *****************************************************************************/ + cDataByte = 0x00; + for ( usBufferIndex = 0; usBufferIndex < 8; usBufferIndex++ ) { + cDataByte <<= 1; + if ( ucDisplayByte & 0x01 ) { + cDataByte |= 0x01; + } + ucDisplayByte >>= 1; + } + g_pucOutData[ 0 ] = cDataByte; + ucDisplayByte = 0; + } + + cByteIndex = 0; + } + } + if ( ucDisplayFlag ) { + + /**************************************************************************** + * + * Display data read from the device. + * + *****************************************************************************/ + +#ifdef VME_DEBUG + printf( "RECIEVED TDO (" ); +#else + vme_out_string( "Display Data: 0x" ); +#endif //VME_DEBUG + + //09/11/07 NN Type cast mismatch variables + for ( usDataSizeIndex = (unsigned short)( ( a_usiDataSize + 7 ) / 8 ); usDataSizeIndex > 0 ; usDataSizeIndex-- ) { + cMaskByte = g_pucOutData[ usDataSizeIndex - 1 ]; + cDataByte = 0x00; + + /**************************************************************************** + * + * Flip cMaskByte and store it in cDataByte. + * + *****************************************************************************/ + + for ( usBufferIndex = 0; usBufferIndex < 8; usBufferIndex++ ) { + cDataByte <<= 1; + if ( cMaskByte & 0x01 ) { + cDataByte |= 0x01; + } + cMaskByte >>= 1; + } +#ifdef VME_DEBUG + printf( "%.2X", cDataByte ); + if ( ( ( ( a_usiDataSize + 7 ) / 8 ) - usDataSizeIndex ) % 40 == 39 ) { + printf( "\n\t\t" ); + } +#else + vme_out_hex( cDataByte ); +#endif //VME_DEBUG + } + +#ifdef VME_DEBUG + printf( ")\n\n" ); +#else + vme_out_string( "\n\n" ); +#endif //VME_DEBUG + //09/02/08 Nguyen changed to display the data Checksum + if(g_usChecksum != 0) + { + g_usChecksum &= 0xFFFF; + sprintf(StrChecksum,"Data Checksum: %04lx\n\n",g_usChecksum); + vme_out_string(StrChecksum); + g_usChecksum = 0; + } + } + + if ( usErrorCount > 0 ) { + if ( g_usFlowControl & VERIFYUES ) { + vme_out_string( "USERCODE verification failed. Continue programming......\n\n" ); + g_usFlowControl &= ~( VERIFYUES ); + return 0; + } + else { + +#ifdef VME_DEBUG + printf( "TOTAL ERRORS: %d\n", usErrorCount ); +#endif //VME_DEBUG + + return VME_VERIFICATION_FAILURE; + } + } + else { + if ( g_usFlowControl & VERIFYUES ) { + vme_out_string( "USERCODE verification passed. Programming aborted. \n\n" ); + g_usFlowControl &= ~( VERIFYUES ); + return 1; + } + else { + return 0; + } + } +} + +/*************************************************************** + * + * ispVMReadandSave + * + * Support dynamic I/O. + * + ***************************************************************/ + +signed char ispVMReadandSave( unsigned short int a_usiDataSize ) +{ + //09/11/07 NN added local variables initialization + unsigned short int usDataSizeIndex = 0; + unsigned short int usLastBitIndex = 0; + unsigned short int usBufferIndex = 0; + unsigned short int usOutBitIndex = 0; + unsigned short int usLVDSIndex = 0; + unsigned char cDataByte = 0; + unsigned char cDMASKByte = 0; + unsigned char cInDataByte = 0; + unsigned char cCurBit = 0; + unsigned char cByteIndex = 0; + signed char cLVDSByteIndex = 0; + + //09/11/07 NN Type cast mismatch variables + usLastBitIndex = (unsigned short) (a_usiDataSize - 1); + + /*************************************************************** + * + * Iterate through the data bits. + * + ***************************************************************/ + + for ( usDataSizeIndex = 0; usDataSizeIndex < a_usiDataSize; usDataSizeIndex++ ) { + if ( cByteIndex == 0 ) { + + /*************************************************************** + * + * Grab byte from DMASK buffer. + * + ***************************************************************/ + + if ( g_usDataType & DMASK_DATA ) { + cDMASKByte = g_pucOutDMaskData[ usBufferIndex ]; + } + else { + cDMASKByte = 0x00; + } + + /*************************************************************** + * + * Grab byte from TDI buffer. + * + ***************************************************************/ + + if ( g_usDataType & TDI_DATA ) { + cInDataByte = g_pucInData[ usBufferIndex ]; + } + + usBufferIndex++; + } + + cCurBit = readPort(); + cDataByte = ( unsigned char ) ( ( ( cInDataByte << cByteIndex ) & 0x80 ) ? 0x01 : 0x00 ); + + /*************************************************************** + * + * Initialize the byte to be zero. + * + ***************************************************************/ + + if ( usOutBitIndex % 8 == 0 ) { + g_pucOutData[ usOutBitIndex / 8 ] = 0x00; + } + + /*************************************************************** + * + * Use TDI, DMASK, and device TDO to create new TDI (actually + * stored in g_pucOutData). + * + ***************************************************************/ + + if ( ( ( ( cDMASKByte << cByteIndex ) & 0x80 ) ? 0x01 : 0x00 ) ) { + + if ( g_pLVDSList ) { + for ( usLVDSIndex = 0; usLVDSIndex < g_usLVDSPairCount; usLVDSIndex++ ) { + if ( g_pLVDSList[ usLVDSIndex ].usNegativeIndex == usDataSizeIndex ) { + g_pLVDSList[ usLVDSIndex ].ucUpdate = 0x01; + break; + } + } + } + + /*************************************************************** + * + * DMASK bit is 1, use TDI. + * + ***************************************************************/ + + g_pucOutData[ usOutBitIndex / 8 ] |= ( unsigned char ) ( ( ( cDataByte & 0x1 ) ? 0x01 : 0x00 ) << ( 7 - usOutBitIndex % 8 ) ); + } + else { + + /*************************************************************** + * + * DMASK bit is 0, use device TDO. + * + ***************************************************************/ + + g_pucOutData[ usOutBitIndex / 8 ] |= ( unsigned char ) ( ( ( cCurBit & 0x1 ) ? 0x01 : 0x00 ) << ( 7 - usOutBitIndex % 8 ) ); + } + + /*************************************************************** + * + * Shift in TDI in order to get TDO out. + * + ***************************************************************/ + + usOutBitIndex++; + writePort( g_ucPinTDI, cDataByte ); + if ( usDataSizeIndex < usLastBitIndex ) { + sclock(); + } + + /*************************************************************** + * + * Increment the byte index. If it exceeds 7, then reset it back + * to zero. + * + ***************************************************************/ + + cByteIndex++; + if ( cByteIndex >= 8 ) { + cByteIndex = 0; + } + } + + /*************************************************************** + * + * If g_pLVDSList exists and pairs need updating, then update + * the negative-pair to receive the flipped positive-pair value. + * + ***************************************************************/ + + if ( g_pLVDSList ) { + for ( usLVDSIndex = 0; usLVDSIndex < g_usLVDSPairCount; usLVDSIndex++ ) { + if ( g_pLVDSList[ usLVDSIndex ].ucUpdate ) { + + /*************************************************************** + * + * Read the positive value and flip it. + * + ***************************************************************/ + + cDataByte = ( unsigned char ) ( ( ( g_pucOutData[ g_pLVDSList[ usLVDSIndex ].usPositiveIndex / 8 ] << ( g_pLVDSList[ usLVDSIndex ].usPositiveIndex % 8 ) ) & 0x80 ) ? 0x01 : 0x00 ); + //09/11/07 NN Type cast mismatch variables + cDataByte = ( unsigned char ) (!cDataByte); + + /*************************************************************** + * + * Get the byte that needs modification. + * + ***************************************************************/ + + cInDataByte = g_pucOutData[ g_pLVDSList[ usLVDSIndex ].usNegativeIndex / 8 ]; + + if ( cDataByte ) { + + /*************************************************************** + * + * Copy over the current byte and set the negative bit to 1. + * + ***************************************************************/ + + cDataByte = 0x00; + for ( cLVDSByteIndex = 7; cLVDSByteIndex >= 0; cLVDSByteIndex-- ) { + cDataByte <<= 1; + if ( 7 - ( g_pLVDSList[ usLVDSIndex ].usNegativeIndex % 8 ) == cLVDSByteIndex ) { + + /*************************************************************** + * + * Set negative bit to 1. + * + ***************************************************************/ + + cDataByte |= 0x01; + } + else if ( cInDataByte & 0x80 ) { + cDataByte |= 0x01; + } + + cInDataByte <<= 1; + } + + /*************************************************************** + * + * Store the modified byte. + * + ***************************************************************/ + + g_pucOutData[ g_pLVDSList[ usLVDSIndex ].usNegativeIndex / 8 ] = cDataByte; + } + else { + + /*************************************************************** + * + * Copy over the current byte and set the negative bit to 0. + * + ***************************************************************/ + + cDataByte = 0x00; + for ( cLVDSByteIndex = 7; cLVDSByteIndex >= 0; cLVDSByteIndex-- ) { + cDataByte <<= 1; + if ( 7 - ( g_pLVDSList[ usLVDSIndex ].usNegativeIndex % 8 ) == cLVDSByteIndex ) { + + /*************************************************************** + * + * Set negative bit to 0. + * + ***************************************************************/ + + cDataByte |= 0x00; + } + else if ( cInDataByte & 0x80 ) { + cDataByte |= 0x01; + } + + cInDataByte <<= 1; + } + + /*************************************************************** + * + * Store the modified byte. + * + ***************************************************************/ + + g_pucOutData[ g_pLVDSList[ usLVDSIndex ].usNegativeIndex / 8 ] = cDataByte; + } + + break; + } + } + } + + return( 0 ); +} + +signed char ispVMProcessLVDS( unsigned short a_usLVDSCount ) +{ + unsigned short usLVDSIndex = 0; + + /*************************************************************** + * + * Allocate memory to hold LVDS pairs. + * + ***************************************************************/ + + ispVMMemManager( LVDS, a_usLVDSCount ); + g_usLVDSPairCount = a_usLVDSCount; + +#ifdef VME_DEBUG + printf( "LVDS %d (", a_usLVDSCount ); +#endif //VME_DEBUG + + /*************************************************************** + * + * Iterate through each given LVDS pair. + * + ***************************************************************/ + + for ( usLVDSIndex = 0; usLVDSIndex < g_usLVDSPairCount; usLVDSIndex++ ) { + + /*************************************************************** + * + * Assign the positive and negative indices of the LVDS pair. + * + ***************************************************************/ + + //09/11/07 NN Type cast mismatch variables + g_pLVDSList[ usLVDSIndex ].usPositiveIndex = (unsigned short) ispVMDataSize(); + //09/11/07 NN Type cast mismatch variables + g_pLVDSList[ usLVDSIndex ].usNegativeIndex = (unsigned short)ispVMDataSize(); + +#ifdef VME_DEBUG + if ( usLVDSIndex < g_usLVDSPairCount - 1 ) { + printf( "%d:%d, ", g_pLVDSList[ usLVDSIndex ].usPositiveIndex, g_pLVDSList[ usLVDSIndex ].usNegativeIndex ); + } + else { + printf( "%d:%d", g_pLVDSList[ usLVDSIndex ].usPositiveIndex, g_pLVDSList[ usLVDSIndex ].usNegativeIndex ); + } +#endif //VME_DEBUG + + } + +#ifdef VME_DEBUG + printf( ");\n", a_usLVDSCount ); +#endif //VME_DEBUG + + return( 0 ); +} diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/ispvme_12.2/origi_ispvm_ui.c b/platform/broadcom/sonic-platform-modules-cel/tools/ispvme_12.2/origi_ispvm_ui.c new file mode 100644 index 000000000000..112633de87c6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/tools/ispvme_12.2/origi_ispvm_ui.c @@ -0,0 +1,908 @@ +/************************************************************** +* +* Lattice Semiconductor Corp. Copyright 2008 +* +* ispVME Embedded allows programming of Lattice's suite of FPGA +* devices on embedded systems through the JTAG port. The software +* is distributed in source code form and is open to re - distribution +* and modification where applicable. +* +* ispVME Embedded C Source comprised with 3 modules: +* ispvm_ui.c is the module provides input and output support. +* ivm_core.c is the module interpret the VME file(s). +* hardware.c is the module access the JTAG port of the device(s). +* +* The optional module cable.c is for supporting Lattice's parallel +* port ispDOWNLOAD cable on DOS and Windows 95/98 O/S. It can be +* requested from Lattice's ispVMSupport. +* +***************************************************************/ + + +/************************************************************** +* +* Revision History of ispvm_ui.c +* +* 3/6/07 ht Added functions vme_out_char(),vme_out_hex(), +* vme_out_string() to provide output resources. +* Consolidate all printf() calls into the added output +* functions. +* +* 09/11/07 NN Added Global variables initialization +* 09/24/07 NN Added a switch allowing users to do calibration. +* Calibration will help to determine the system clock frequency +* and the count value for one micro-second delay of the target +* specific hardware. +* Removed Delay Percent support +* 11/15/07 NN moved the checking of the File CRC to the end of processing +* 08/28/08 NN Added Calculate checksum support. +***************************************************************/ + + +#include +#include +#include +#include +#include +#include +#include "vmopcode.h" + +/*************************************************************** +* +* File pointer to the VME file. +* +***************************************************************/ + +FILE * g_pVMEFile = NULL; + +#define VME_DEBUG + +#define DEBUG +#ifdef DEBUG +#define Debug_printf(fmt, args...) printf(fmt, ##args); +#else +#define Debug_printf(fmt, args...) +#endif + +/*************************************************************** +* +* Functions declared in this ispvm_ui.c module +* +***************************************************************/ +unsigned char GetByte(void); +void vme_out_char(unsigned char charOut); +void vme_out_hex(unsigned char hexOut); +void vme_out_string(char *stringOut); +void ispVMMemManager( signed char cTarget, unsigned short usSize ); +void ispVMFreeMem(void); +void error_handler( short a_siRetCode, char * pszMessage ); +signed char ispVM( const char * a_pszFilename ); +long isp_vme_file_size_get(void); +int isp_vme_file_size_set(char *file_name); +int isp_print_progess_bar(long pec); +void print_usage(char *app_name); +/*************************************************************** +* +* Global variables. +* +***************************************************************/ +unsigned short g_usPreviousSize = 0; +unsigned short g_usExpectedCRC = 0; +static unsigned long vme_file_size = 0; + +/*************************************************************** +* +* External variables and functions declared in ivm_core.c module. +* +***************************************************************/ +extern signed char ispVMCode(); +extern void ispVMCalculateCRC32( unsigned char a_ucData ); +extern void ispVMStart(); +extern void ispVMEnd(); +extern unsigned short g_usCalculatedCRC; +extern unsigned short g_usDataType; +extern unsigned char * g_pucOutMaskData, + * g_pucInData, + * g_pucOutData, + * g_pucHIRData, + * g_pucTIRData, + * g_pucHDRData, + * g_pucTDRData, + * g_pucOutDMaskData, + * g_pucIntelBuffer; +extern unsigned char * g_pucHeapMemory; +extern unsigned short g_iHeapCounter; +extern unsigned short g_iHEAPSize; +extern unsigned short g_usIntelDataIndex; +extern unsigned short g_usIntelBufferSize; +extern LVDSPair * g_pLVDSList; +//08/28/08 NN Added Calculate checksum support. +extern unsigned long g_usChecksum; +extern unsigned int g_uiChecksumIndex; +/*************************************************************** +* +* External variables and functions declared in hardware.c module. +* +***************************************************************/ +extern void calibration(void); +extern void writePort( unsigned long a_ucPins, unsigned char a_ucValue ); +extern unsigned short g_usCpu_Frequency; +extern unsigned long g_ucInPort; +extern unsigned long g_ucOutPort; + +/*************************************************************** +* +* Supported VME versions. +* +***************************************************************/ + +const char * const g_szSupportedVersions[] = { "__VME2.0", "__VME3.0", "____12.0", "____12.1", 0 }; + + +/*************************************************************** +* +* GetByte +* +* Returns a byte to the caller. The returned byte depends on the +* g_usDataType register. If the HEAP_IN bit is set, then the byte +* is returned from the HEAP. If the LHEAP_IN bit is set, then +* the byte is returned from the intelligent buffer. Otherwise, +* the byte is returned directly from the VME file. +* +***************************************************************/ + +unsigned char GetByte() +{ + unsigned char ucData = 0; + /* Prepare progress bar calculation */ + static long offset = 0; + int pec = 0; + long file_size = isp_vme_file_size_get(); + int bytes_pec = (file_size + 99) / 100; + + if ( g_usDataType & HEAP_IN ) { + + /*************************************************************** + * + * Get data from repeat buffer. + * + ***************************************************************/ + + if ( g_iHeapCounter > g_iHEAPSize ) { + + /*************************************************************** + * + * Data over-run. + * + ***************************************************************/ + + return 0xFF; + } + + ucData = g_pucHeapMemory[ g_iHeapCounter++ ]; + } + else if ( g_usDataType & LHEAP_IN ) { + + /*************************************************************** + * + * Get data from intel buffer. + * + ***************************************************************/ + + if ( g_usIntelDataIndex >= g_usIntelBufferSize ) { + + /*************************************************************** + * + * Data over-run. + * + ***************************************************************/ + + return 0xFF; + } + + ucData = g_pucIntelBuffer[ g_usIntelDataIndex++ ]; + } + else { + + /*************************************************************** + * + * Get data from file. + * + ***************************************************************/ + + ucData = (unsigned char)fgetc( g_pVMEFile ); + /* Update the progress bar */ + pec = ++offset / bytes_pec; + if(offset <= (pec * bytes_pec)) + isp_print_progess_bar(pec); + else if(offset >= (file_size - 2)) + isp_print_progess_bar(100); + if ( feof( g_pVMEFile ) ) { + + /*************************************************************** + * + * Reached EOF. + * + ***************************************************************/ + + return 0xFF; + } + /*************************************************************** + * + * Calculate the 32-bit CRC if the expected CRC exist. + * + ***************************************************************/ + if( g_usExpectedCRC != 0) + { + ispVMCalculateCRC32(ucData); + } + } + + return ( ucData ); +} + +/*************************************************************** +* +* vme_out_char +* +* Send a character out to the output resource if available. +* The monitor is the default output resource. +* +* +***************************************************************/ +void vme_out_char(unsigned char charOut) +{ + printf("%c",charOut); +} +/*************************************************************** +* +* vme_out_hex +* +* Send a character out as in hex format to the output resource +* if available. The monitor is the default output resource. +* +* +***************************************************************/ +void vme_out_hex(unsigned char hexOut) +{ + printf("%.2X",hexOut); +} +/*************************************************************** +* +* vme_out_string +* +* Send a text string out to the output resource if available. +* The monitor is the default output resource. +* +* +***************************************************************/ +void vme_out_string(char *stringOut) +{ + if(stringOut) + { + printf("%s",stringOut); + } + +} +/*************************************************************** +* +* ispVMMemManager +* +* Allocate memory based on cTarget. The memory size is specified +* by usSize. +* +***************************************************************/ + +void ispVMMemManager( signed char cTarget, unsigned short usSize ) +{ + switch ( cTarget ) { + case XTDI: + case TDI: + if ( g_pucInData != NULL ) { + if ( g_usPreviousSize == usSize ) {/*memory exist*/ + break; + } + else { + free( g_pucInData ); + g_pucInData = NULL; + } + } + g_pucInData = ( unsigned char * ) malloc( usSize / 8 + 2 ); + g_usPreviousSize = usSize; + /* FALLTHRU */ + case XTDO: + case TDO: + if ( g_pucOutData!= NULL ) { + if ( g_usPreviousSize == usSize ) { /*already exist*/ + break; + } + else { + free( g_pucOutData ); + g_pucOutData = NULL; + } + } + g_pucOutData = ( unsigned char * ) malloc( usSize / 8 + 2 ); + g_usPreviousSize = usSize; + break; + case MASK: + if ( g_pucOutMaskData != NULL ) { + if ( g_usPreviousSize == usSize ) {/*already allocated*/ + break; + } + else { + free( g_pucOutMaskData ); + g_pucOutMaskData = NULL; + } + } + g_pucOutMaskData = ( unsigned char * ) malloc( usSize / 8 + 2 ); + g_usPreviousSize = usSize; + break; + case HIR: + if ( g_pucHIRData != NULL ) { + free( g_pucHIRData ); + g_pucHIRData = NULL; + } + g_pucHIRData = ( unsigned char * ) malloc( usSize / 8 + 2 ); + break; + case TIR: + if ( g_pucTIRData != NULL ) { + free( g_pucTIRData ); + g_pucTIRData = NULL; + } + g_pucTIRData = ( unsigned char * ) malloc( usSize / 8 + 2 ); + break; + case HDR: + if ( g_pucHDRData != NULL ) { + free( g_pucHDRData ); + g_pucHDRData = NULL; + } + g_pucHDRData = ( unsigned char * ) malloc( usSize / 8 + 2 ); + break; + case TDR: + if ( g_pucTDRData != NULL ) { + free( g_pucTDRData ); + g_pucTDRData = NULL; + } + g_pucTDRData = ( unsigned char * ) malloc( usSize / 8 + 2 ); + break; + case HEAP: + if ( g_pucHeapMemory != NULL ) { + free( g_pucHeapMemory ); + g_pucHeapMemory = NULL; + } + g_pucHeapMemory = ( unsigned char * ) malloc( usSize + 2 ); + break; + case DMASK: + if ( g_pucOutDMaskData != NULL ) { + if ( g_usPreviousSize == usSize ) { /*already allocated*/ + break; + } + else { + free( g_pucOutDMaskData ); + g_pucOutDMaskData = NULL; + } + } + g_pucOutDMaskData = ( unsigned char * ) malloc( usSize / 8 + 2 ); + g_usPreviousSize = usSize; + break; + case LHEAP: + if ( g_pucIntelBuffer != NULL ) { + free( g_pucIntelBuffer ); + g_pucIntelBuffer = NULL; + } + g_pucIntelBuffer = ( unsigned char * ) malloc( usSize + 2 ); + break; + case LVDS: + if ( g_pLVDSList != NULL ) { + free( g_pLVDSList ); + g_pLVDSList = NULL; + } + g_pLVDSList = ( LVDSPair * ) calloc( usSize, sizeof( LVDSPair ) ); + break; + default: + return; + } +} + +/*************************************************************** +* +* ispVMFreeMem +* +* Free memory that were dynamically allocated. +* +***************************************************************/ + +void ispVMFreeMem() +{ + if ( g_pucHeapMemory != NULL ) { + free( g_pucHeapMemory ); + g_pucHeapMemory = NULL; + } + + if ( g_pucOutMaskData != NULL ) { + free( g_pucOutMaskData ); + g_pucOutMaskData = NULL; + } + + if ( g_pucInData != NULL ) { + free( g_pucInData ); + g_pucInData = NULL; + } + + if ( g_pucOutData != NULL ) { + free( g_pucOutData ); + g_pucOutData = NULL; + } + + if ( g_pucHIRData != NULL ) { + free( g_pucHIRData ); + g_pucHIRData = NULL; + } + + if ( g_pucTIRData != NULL ) { + free( g_pucTIRData ); + g_pucTIRData = NULL; + } + + if ( g_pucHDRData != NULL ) { + free( g_pucHDRData ); + g_pucHDRData = NULL; + } + + if ( g_pucTDRData != NULL ) { + free( g_pucTDRData ); + g_pucTDRData = NULL; + } + + if ( g_pucOutDMaskData != NULL ) { + free( g_pucOutDMaskData ); + g_pucOutDMaskData = NULL; + } + + if ( g_pucIntelBuffer != NULL ) { + free( g_pucIntelBuffer ); + g_pucIntelBuffer = NULL; + } + + if ( g_pLVDSList != NULL ) { + free( g_pLVDSList ); + g_pLVDSList = NULL; + } +} + +/*************************************************************** +* +* error_handler +* +* Reports the error message. +* +***************************************************************/ + +void error_handler( short a_siRetCode, char * pszMessage ) +{ + const char * pszErrorMessage[] = { "pass", + "verification fail", + "can't find the file", + "wrong file type", + "file error", + "option error", + "crc verification error" }; + + strcpy( pszMessage, pszErrorMessage[ -a_siRetCode ] ); +} +/*************************************************************** +* +* ispVM +* +* The entry point of the ispVM embedded. If the version and CRC +* are verified, then the VME will be processed. +* +***************************************************************/ + +signed char ispVM( const char * a_pszFilename ) +{ + char szFileVersion[ 9 ] = { 0 }; + signed char cRetCode = 0; + signed char cIndex = 0; + signed char cVersionIndex = 0; + unsigned char ucReadByte = 0; + + /*************************************************************** + * + * Global variables initialization. + * + * 09/11/07 NN Added + ***************************************************************/ + g_pucHeapMemory = NULL; + g_iHeapCounter = 0; + g_iHEAPSize = 0; + g_usIntelDataIndex = 0; + g_usIntelBufferSize = 0; + g_usPreviousSize = 0; + + /*************************************************************** + * + * Open a file pointer to the VME file. + * + ***************************************************************/ + + if ( ( g_pVMEFile = fopen( a_pszFilename, "rb" ) ) == NULL ) { + return VME_FILE_READ_FAILURE; + } + g_usCalculatedCRC = 0; + g_usExpectedCRC = 0; + ucReadByte = GetByte(); + switch( ucReadByte ) { + case FILE_CRC: + + /*************************************************************** + * + * Read and store the expected CRC to do the comparison at the end. + * Only versions 3.0 and higher support CRC protection. + * + ***************************************************************/ + + g_usExpectedCRC = (unsigned char ) fgetc( g_pVMEFile ); + g_usExpectedCRC <<= 8; + g_usExpectedCRC |= fgetc( g_pVMEFile ); + + + /*************************************************************** + * + * Read and store the version of the VME file. + * + ***************************************************************/ + + for ( cIndex = 0; cIndex < 8; cIndex++ ) { + szFileVersion[ cIndex ] = GetByte(); + } + + break; + default: + + /*************************************************************** + * + * Read and store the version of the VME file. Must be version 2.0. + * + ***************************************************************/ + + szFileVersion[ 0 ] = ( signed char ) ucReadByte; + for ( cIndex = 1; cIndex < 8; cIndex++ ) { + szFileVersion[ cIndex ] = GetByte(); + } + + break; + } + + /*************************************************************** + * + * Compare the VME file version against the supported version. + * + ***************************************************************/ + for ( cVersionIndex = 0; g_szSupportedVersions[ cVersionIndex ] != 0; cVersionIndex++ ) { + for ( cIndex = 0; cIndex < 8; cIndex++ ) { + if ( szFileVersion[ cIndex ] != g_szSupportedVersions[ cVersionIndex ][ cIndex ] ) { + cRetCode = VME_VERSION_FAILURE; + break; + } + cRetCode = 0; + } + + if ( cRetCode == 0 ) { + + /*************************************************************** + * + * Found matching version, break. + * + ***************************************************************/ + + break; + } + } + + if ( cRetCode < 0 ) { + + /*************************************************************** + * + * VME file version failed to match the supported versions. + * + ***************************************************************/ + + fclose( g_pVMEFile ); + g_pVMEFile = NULL; + return VME_VERSION_FAILURE; + } + + /*************************************************************** + * + * Enable the JTAG port to communicate with the device. + * Set the JTAG state machine to the Test-Logic/Reset State. + * + ***************************************************************/ + + ispVMStart(); + + /*************************************************************** + * + * Process the VME file. + * + ***************************************************************/ + + cRetCode = ispVMCode(); + + /*************************************************************** + * + * Set the JTAG State Machine to Test-Logic/Reset state then disable + * the communication with the JTAG port. + * + ***************************************************************/ + + ispVMEnd(); + + fclose( g_pVMEFile ); + g_pVMEFile = NULL; + + + ispVMFreeMem(); + + /*************************************************************** + * + * Compare the expected CRC versus the calculated CRC. + * + ***************************************************************/ + + if ( cRetCode == 0 && g_usExpectedCRC != 0 && ( g_usExpectedCRC != g_usCalculatedCRC ) ) { + printf( "Expected CRC: 0x%.4X\n", g_usExpectedCRC ); + printf( "Calculated CRC: 0x%.4X\n", g_usCalculatedCRC ); + return VME_CRC_FAILURE; + } + + return ( cRetCode ); +} + +// inline char *strlwr(char *str) +// { +// char *orig = str; + +// for (; *str != '\0'; str++) +// *str = tolower(*str); + +// return orig; +// } + +int isp_vme_file_size_set(char *file_name) +{ + struct stat statbuf; + + stat(file_name, &statbuf); + vme_file_size = statbuf.st_size; + + return 0; +} + +long isp_vme_file_size_get(void) +{ + return vme_file_size; +} + +int isp_print_progess_bar(long pec) +{ + int i = 0; + + printf("["); + for(i = 0; i < (pec / 2); i++) { + printf("="); + } + for(i = pec / 2; i < 50; i++) { + printf(" "); + } + printf("]"); + printf(" [%ld%%]\r", pec); + fflush(stdout); + if(pec == 100) + printf("\n"); + + return 0; +} + +void print_usage(char *app_name){ + printf(" usage: %s [options] [filename]\n", app_name); + printf(" Options:\n"); + printf(" -h : to print this message.\n"); + printf(" -c : to select the JTAG chain 0,1,2\n"); + printf(" default is at 0.\n"); + printf(" -f : to specify CPU clock frequency in MHz.\n"); +} + +/*************************************************************** +* +* main +* +***************************************************************/ +int main( int argc, char * argv[] ) +{ + short siRetCode = 0; + short sicalibrate = 1; + short setCpuFrequency = 0; + + char *cpld_img = "cpld.vme"; + int JTAG_chain = 0; + int option; + //08/28/08 NN Added Calculate checksum support. + g_usChecksum = 0; + g_uiChecksumIndex = 0; + + vme_out_string( " Lattice Semiconductor Corp.\n" ); + vme_out_string( "\n ispVME(tm) V"); + vme_out_string( VME_VERSION_NUMBER ); + vme_out_string(" Copyright 1998-2011.\n"); + vme_out_string( "\nFor daisy chain programming of all in-system programmable devices\n" ); + vme_out_string( "\nCLS internal version 1.1.0 for Phalanx, Fishbone48, and Fishbone32.\n\n" ); + + while( ( option = getopt(argc, argv, "f:c:h")) != -1 ){ + switch (option){ + case 'h': + print_usage(argv[0]); + return 0; + case 'c': + // set JTAG chain number + JTAG_chain = atoi(optarg); + break; + case 'f': + // set CPU frequency + g_usCpu_Frequency = atoi(optarg); + setCpuFrequency = 1; + break; + case '?': + print_usage(argv[0]); + return -1; + } + } + + if( argc - optind ) + cpld_img = argv[optind]; + + if( JTAG_chain < 0 || JTAG_chain > 2 ){ + //print usage and return error + printf("Invalid JTAG chain specify: %d\n", JTAG_chain); + print_usage(argv[0]); + return -1; + } + + if( g_usCpu_Frequency <= 0 && setCpuFrequency ){ + //print usage and return error + printf("Invalid CPU frequency specify: %d\n", g_usCpu_Frequency); + print_usage(argv[0]); + return -1; + } + + if (iopl(3)) + { + perror("iopl"); + exit(1);/* reminder here: do not use "return", I warned */ + } + else + { + + /* For Denvertion CPU */ + // isp_dnv_gpio_init(); + // isp_dnv_gpio_config(GPIO_TCK_CONFIG, GPIO_DIR_OUTPUT); + // isp_dnv_gpio_config(GPIO_TMS_CONFIG, GPIO_DIR_OUTPUT); + // isp_dnv_gpio_config(GPIO_TDI_CONFIG, GPIO_DIR_OUTPUT); + // isp_dnv_gpio_config(GPIO_TDO_CONFIG, GPIO_DIR_INPUT); + + + /* TODO: Convert to bit read/write function */ + // Set ICHx GPIO_USE_SEL of TDI,TDO,TMS,TCK,GPIO14 + unsigned long data = 0; + data = inl_p(GPIO_USE_SEL); + data |= (1U << GPIO_TCK_CONFIG); + data |= (1U << GPIO_TMS_CONFIG); + data |= (1U << GPIO_TDI_CONFIG); + data |= (1U << GPIO_TDO_CONFIG); + data |= (1U << 14); + outl_p(data, GPIO_USE_SEL); + // Set ICHx GP_IO_SEL of TDI,TDO,TMS,TCK,GPIO14 + data = inl_p(GP_IO_SEL); + data &= ~(1U << GPIO_TCK_CONFIG); + data &= ~(1U << GPIO_TMS_CONFIG); + data &= ~(1U << GPIO_TDI_CONFIG); + data &= ~(1U << 14); + data |= (1U << GPIO_TDO_CONFIG); + outl_p(data, GP_IO_SEL); + + // Set ICHx GPIO_USE_SEL of GPIO70 + data = inl_p(GPIO_USE_SEL3); + data |= (1U << 6); + outl_p(data, GPIO_USE_SEL3); + // Set ICHx GP_IO_SEL of GPIO70 + data = inl_p(GP_IO_SEL3); + data &= ~(1U << 6); + outl_p(data, GP_IO_SEL3); + } + + /* FIXME: export and setting GPIO register bank on the fly could cause a bug. + * Plan to add the function to set/clear GPIO register bit for more sucure. + */ + /* Switch to control JTAG chain muxes */ + switch (JTAG_chain){ + case 0: + printf("Select main JTAG chain\n"); + // Set GPIO70 to Low + g_ucOutPort = GP_LVL3; + writePort( 6, 0x00 ); + break; + case 1: + printf("Select Top line card JTAG chain\n"); + // Ste GPIO70 to High + g_ucOutPort = GP_LVL3; + writePort( 6, 0x01 ); + // Ste GPIO14 to Low + g_ucOutPort = GP_LVL; + writePort( 14, 0x00 ); + break; + case 2: + printf("Select Buttom line card JTAG chain\n"); + // Ste GPIO70 to High + g_ucOutPort = GP_LVL3; + writePort( 6, 0x01 ); + // Ste GPIO14 to High + g_ucOutPort = GP_LVL; + writePort( 14, 0x01 ); + break; + } + + /* FIXME: This line is very important for TDI,TMS,TCK,TDO */ + // Set the register back to first bank! + g_ucOutPort = GP_LVL; + + printf("Set CPU frequency to %d MHz\n", g_usCpu_Frequency); + + siRetCode = 0; + if(sicalibrate) + { + vme_out_string ("calibration ....\n\n"); + calibration(); + } + + printf( "Processing virtual machine file ("); + printf( "%s",cpld_img); + printf(")......\n\n"); + isp_vme_file_size_set(cpld_img); + siRetCode = ispVM(cpld_img); + + /* Set JTAG chain muxes to default chain. */ + // Set GPIO70 to Low + g_ucOutPort = GP_LVL3; + writePort( 6, 0x00 ); + + /* For Denverton CPU */ + // isp_dnv_gpio_deinit(); + + if ( siRetCode < 0 ) { + vme_out_string( "Failed due to "); + printf( " return code %d\n\n", siRetCode); + vme_out_string( "+=======+\n" ); + vme_out_string( "| FAIL! |\n" ); + vme_out_string( "+=======+\n\n" ); + }else { + vme_out_string( "+=======+\n" ); + vme_out_string( "| PASS! |\n" ); + vme_out_string( "+=======+\n\n" ); + //08/28/08 NN Added Calculate checksum support. + if(g_usChecksum != 0) + { + g_usChecksum &= 0xFFFF; + printf("Data Checksum: %.4lx\n\n",g_usChecksum); + g_usChecksum = 0; + } + } + + if (iopl(0)) + { + perror("iopl"); + exit(1);/* reminder here: do not use "return", I warned */ + } + exit( siRetCode ); +} + diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/ispvme_12.2/vmopcode.h b/platform/broadcom/sonic-platform-modules-cel/tools/ispvme_12.2/vmopcode.h new file mode 100644 index 000000000000..6b2c94d510f7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/tools/ispvme_12.2/vmopcode.h @@ -0,0 +1,233 @@ +/*************************************************************** +* +* This is the include file for Lattice Semiconductor's ispVM +* Embedded software application. +* +***************************************************************/ + +/*************************************************************** +* +* VME version. +* +* History: +* +***************************************************************/ +#define VME_VERSION_NUMBER "12.2" + +/*************************************************************** +* +* Maximum declarations. +* +***************************************************************/ + +#define VMEHEXMAX 60000L /* The hex file is split 60K per file. */ +#define SCANMAX 64000L /* The maximum SDR/SIR burst. */ + +/*************************************************************** +* +* Supported JTAG state transitions. +* +***************************************************************/ + +#define RESET 0x00 +#define IDLE 0x01 +#define IRPAUSE 0x02 +#define DRPAUSE 0x03 +#define SHIFTIR 0x04 +#define SHIFTDR 0x05 +#define DRCAPTURE 0x06 + +/*************************************************************** +* +* Flow control register bit definitions. A set bit indicates +* that the register currently exhibits the corresponding mode. +* +***************************************************************/ + +#define INTEL_PRGM 0x0001 /* Intelligent programming is in effect. */ +#define CASCADE 0x0002 /* Currently splitting large SDR. */ +#define REPEATLOOP 0x0008 /* Currently executing a repeat loop. */ +#define SHIFTRIGHT 0x0080 /* The next data stream needs a right shift. */ +#define SHIFTLEFT 0x0100 /* The next data stream needs a left shift. */ +#define VERIFYUES 0x0200 /* Continue if fail is in effect. */ + +/*************************************************************** +* +* DataType register bit definitions. A set bit indicates +* that the register currently holds the corresponding type of data. +* +***************************************************************/ + +#define EXPRESS 0x0001 /* Simultaneous program and verify. */ +#define SIR_DATA 0x0002 /* SIR is the active SVF command. */ +#define SDR_DATA 0x0004 /* SDR is the active SVF command. */ +#define COMPRESS 0x0008 /* Data is compressed. */ +#define TDI_DATA 0x0010 /* TDI data is present. */ +#define TDO_DATA 0x0020 /* TDO data is present. */ +#define MASK_DATA 0x0040 /* MASK data is present. */ +#define HEAP_IN 0x0080 /* Data is from the heap. */ +#define LHEAP_IN 0x0200 /* Data is from intel data buffer. */ +#define VARIABLE 0x0400 /* Data is from a declared variable. */ +#define CRC_DATA 0x0800 /* CRC data is pressent. */ +#define CMASK_DATA 0x1000 /* CMASK data is pressent. */ +#define RMASK_DATA 0x2000 /* RMASK data is pressent. */ +#define READ_DATA 0x4000 /* READ data is pressent. */ +#define DMASK_DATA 0x8000 /* DMASK data is pressent. */ + +/*************************************************************** +* +* Pin opcodes. +* +***************************************************************/ + +#define signalENABLE 0x1C /* ispENABLE pin. */ +#define signalTMS 0x1D /* TMS pin. */ +#define signalTCK 0x1E /* TCK pin. */ +#define signalTDI 0x1F /* TDI pin. */ +#define signalTRST 0x20 /* TRST pin. */ + +/*************************************************************** +* +* Supported vendors. +* +***************************************************************/ + +#define VENDOR 0x56 +#define LATTICE 0x01 +#define ALTERA 0x02 +#define XILINX 0x03 + +/*************************************************************** +* +* Opcode definitions. +* +* Note: opcodes must be unique. +* +***************************************************************/ + +#define ENDDATA 0x00 /* The end of the current SDR data stream. */ +#define RUNTEST 0x01 /* The duration to stay at the stable state. */ +#define ENDDR 0x02 /* The stable state after SDR. */ +#define ENDIR 0x03 /* The stable state after SIR. */ +#define ENDSTATE 0x04 /* The stable state after RUNTEST. */ +#define TRST 0x05 /* Assert the TRST pin. */ +#define HIR 0x06 /* The sum of the IR bits of the leading devices. */ +#define TIR 0x07 /* The sum of the IR bits of the trailing devices. */ +#define HDR 0x08 /* The number of leading devices. */ +#define TDR 0x09 /* The number of trailing devices. */ +#define ispEN 0x0A /* Assert the ispEN pin. */ +#define FREQUENCY 0x0B /* The maximum clock rate to run the JTAG state machine. */ +#define STATE 0x10 /* Move to the next stable state. */ +#define SIR 0x11 /* The instruction stream follows. */ +#define SDR 0x12 /* The data stream follows. */ +#define TDI 0x13 /* The following data stream feeds into the device. */ +#define TDO 0x14 /* The following data stream is compared against the device. */ +#define MASK 0x15 /* The following data stream is used as mask. */ +#define XSDR 0x16 /* The following data stream is for simultaneous program and verify. */ +#define XTDI 0x17 /* The following data stream is for shift in only. It must be stored for the next XSDR. */ +#define XTDO 0x18 /* There is not data stream. The data stream was stored from the previous XTDI. */ +#define MEM 0x19 /* The maximum memory needed to allocate in order hold one row of data. */ +#define WAIT 0x1A /* The duration of delay to observe. */ +#define TCK 0x1B /* The number of TCK pulses. */ +#define SHR 0x23 /* Set the flow control register for right shift. */ +#define SHL 0x24 /* Set the flow control register for left shift. */ +#define HEAP 0x32 /* The memory size needed to hold one loop. */ +#define REPEAT 0x33 /* The beginning of the loop. */ +#define LEFTPAREN 0x35 /* The beginning of data following the loop. */ +#define VAR 0x55 /* Plac holder for loop data. */ +#define SEC 0x1C /* The delay time in seconds that must be observed. */ +#define SMASK 0x1D /* The mask for TDI data. */ +#define MAX 0x1E /* The absolute maximum wait time. */ +#define ON 0x1F /* Assert the targeted pin. */ +#define OFF 0x20 /* Dis-assert the targeted pin. */ +#define SETFLOW 0x30 /* Change the flow control register. */ +#define RESETFLOW 0x31 /* Clear the flow control register. */ +#define CRC 0x47 /* The following data stream is used for CRC calculation. */ +#define CMASK 0x48 /* The following data stream is used as mask for CRC calculation. */ +#define RMASK 0x49 /* The following data stream is used as mask for read and save. */ +#define READ 0x50 /* The following data stream is used for read and save. */ +#define ENDLOOP 0x59 /* The end of the repeat loop. */ +#define SECUREHEAP 0x60 /* Used to secure the HEAP opcode. */ +#define VUES 0x61 /* Support continue if fail. */ +#define DMASK 0x62 /* The following data stream is used for dynamic I/O. */ +#define COMMENT 0x63 /* Support SVF comments in the VME file. */ +#define HEADER 0x64 /* Support header in VME file. */ +#define FILE_CRC 0x65 /* Support crc-protected VME file. */ +#define LCOUNT 0x66 /* Support intelligent programming. */ +#define LDELAY 0x67 /* Support intelligent programming. */ +#define LSDR 0x68 /* Support intelligent programming. */ +#define LHEAP 0x69 /* Memory needed to hold intelligent data buffer */ +#define CONTINUE 0x70 /* Allow continuation. */ +#define LVDS 0x71 /* Support LVDS. */ +#define ENDVME 0x7F /* End of the VME file. */ +#define HIGH 0x80 /* Assert the targeted pin. */ +#define LOW 0x81 /* Dis-assert the targeted pin. */ +#define ENDFILE 0xFF /* End of file. */ + +/* Denverton GPIO MAPPING */ +#define MAP_MASK (sysconf(_SC_PAGE_SIZE)-1) +#define MAP_SIZE(addr) ( (addr & MAP_MASK) + 8 ) +#define OFFSET_ADDR(addr) (addr & MAP_MASK) +#define GET_PORT(addr) ( (addr >> 16) & 0xFF ) +#define DNV_BAR 0xFD000000 +#define DNV_GPIO_TCK_CONFIG 0xFDC20510 +#define DNV_GPIO_TMS_CONFIG 0xFDC20508 +#define DNV_GPIO_TDI_CONFIG 0xFDC204D8 +#define DNV_GPIO_TDO_CONFIG 0xFDC50570 +#define DNV_GPIO_DIR_INPUT 1 +#define DNV_GPIO_DIR_OUTPUT 0 +#define DNV_GPIO_LVL_HIGH 1 +#define DNV_GPIO_LVL_LOW 0 + +// FIXME: This only works on Fishbone/Phalanx +#define CPU_FREQ_MH_CONFIG 2200 /* in MHz */ +#define GPIO_USE_SEL 0x500 +#define GP_IO_SEL 0x504 +#define GP_LVL 0x50C +#define GPIO_USE_SEL2 0x530 +#define GP_IO_SEL2 0x534 +#define GP_LVL2 0x538 +#define GPIO_USE_SEL3 0x540 +#define GP_IO_SEL3 0x544 +#define GP_LVL3 0x548 + +#define GPIO_TCK_CONFIG 18 +#define GPIO_TMS_CONFIG 9 +#define GPIO_TDI_CONFIG 8 +#define GPIO_TDO_CONFIG 10 +#define GPIO_ENABLE_CONFIG 13 /* GPIO 13 is unused */ +#define GPIO_TRST_CONFIG 13 /* GPIO 13 is unused */ + +/*************************************************************** +* +* ispVM Embedded Return Codes. +* +***************************************************************/ + +#define VME_VERIFICATION_FAILURE -1 +#define VME_FILE_READ_FAILURE -2 +#define VME_VERSION_FAILURE -3 +#define VME_INVALID_FILE -4 +#define VME_ARGUMENT_FAILURE -5 +#define VME_CRC_FAILURE -6 + + +/*************************************************************** +* +* Type definitions. +* +***************************************************************/ + +/* Support LVDS */ +typedef struct { + unsigned short usPositiveIndex; + unsigned short usNegativeIndex; + unsigned char ucUpdate; +} LVDSPair; + +void isp_dnv_gpio_config( unsigned int gpio, unsigned int dir ); +void isp_dnv_gpio_write( unsigned int gpio, unsigned int value); +int isp_dnv_gpio_read( unsigned int gpio); + +void isp_dnv_gpio_init(void); +void isp_dnv_gpio_deinit(void); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/platformutil.py b/platform/broadcom/sonic-platform-modules-cel/tools/platformutil.py new file mode 100644 index 000000000000..5c73dd9870f3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/tools/platformutil.py @@ -0,0 +1,642 @@ +#!/usr/bin/env python +# +# platformutil/main.py +# +# Command-line utility for interacting with PSU in SONiC +# +# example output +# platformutil psu status +# PSU Presence Status PN SN +# PSU 1 PRESENT OK CSU550AP-3-300 M623TW004ZAAL +# PSU 2 NOT_PRESENT N/A N/A N/A +# +# platformutil fan status +# FAN Status Speed Low_thd High_thd PN SN +# FAN 1 OK 10169 RPM 300 RPM 16000 RPM M6510-FAN-F 1000000000014 +# FAN 2 NOT_OK 20000 RPM 300 RPM 16000 RPM M6510-FAN-F 1000000000014 +# +# platformutil sensor status +#Sensor InputName State Value Low_thd High_thd +#----------------- ------------------- ------- -------- --------- ---------- +#syscpld-i2c-0-0d CPU temp NOT_OK 41.0 C 0 C 0.0 C +#syscpld-i2c-0-0d Optical temp NOT_OK 26.0 C 0 C 0.0 C +#syscpld-i2c-0-0d Switch temp NOT_OK 35.0 C 0 C 0.0 C +# +# should implenmet the below classes in the specified plugin +# +# class PsuUtil: +# int get_num_psus(); //get the number of power supply units +# bool get_psu_presence(int index) //get the power status of the psu, index:1,2 +# bool get_psu_status(int index) //get the running status of the psu,index:1,2 +# str get_psu_sn(int index) //get the serial number of the psu, return value example: "M623TW004ZAAL" +# str get_psu_pn(int index) //get the product name of the psu, return value example: "CSU550AP-3-300" +# +# // Get all information of PSUs, returns JSON objects in python 'DICT'. +# // return value of get_all(): +# // Number: mandatory, max number of PSU, integer +# // PSU1, PSU2, ...: mandatory, PSU name, string +# // Present: mandatory for each PSU, present status, boolean, True for present, False for NOT present +# // PowerStatus: conditional, if PRESENT is True, power status of PSU, +# // boolean, True for powered, False for NOT powered +# // PN, conditional, if PRESENT is True, PN of the PSU, string +# // SN, conditional, if PRESENT is True, SN of the PSU, string +# // example: +# // { +# // "Number": 2, +# // "PSU1": { +# // "Present": True, +# // "PowerStatus": True, +# // "PN": "PN-EXAMPLE-123", +# // "SN": "SN-EXAMPLE-123", +# // "InputStatus": True, +# // "OutputStatus": True, +# // "InputType": "DC" +# // "AirFlow": "BTOF" +# // }, +# // "PSU2": { +# // "Present": False +# // } +# // } +# dict get_all() + +# class FanUtil: +# int get_fans_name_list(); //get the names of all the fans(FAN1-1,FAN1-2,FAN2-1,FAN2-2...) +# int get_fan_speed(int index); //get the current speed of the fan, the unit is "RPM" +# int get_fan_low_threshold(int index); //get the low speed threshold of the fan, if the current speed < low speed threshold, the status of the fan is ok. +# int get_fan_high_threshold(int index); //get the hight speed threshold of the fan, if the current speed > high speed threshold, the status of the fan is not ok +# str get_fan_pn(int index);//get the product name of the fan +# str get_fan_sn(int index);//get the serial number of the fan +# // Get all information of system FANs, returns JSON objects in python 'DICT'. +# // Number, mandatory, max number of FAN, integer +# // FAN1_1, FAN1_2, ... mandatory, FAN name, string +# // Present, mandatory for each FAN, present status, boolean, True for present, False for NOT present, read directly from h/w +# // Running, conditional, if PRESENT is True, running status of the FAN, True for running, False for stopped, read directly from h/w +# // Speed, conditional, if PRESENT is True, real FAN speed, float, read directly from h/w +# // LowThd, conditional, if PRESENT is True, lower bound of FAN speed, float, read from h/w +# // HighThd, conditional, if PRESENT is True, upper bound of FAN speed, float, read from h/w +# // PN, conditional, if PRESENT is True, PN of the FAN, string +# // SN, conditional, if PRESENT is True, SN of the FAN, string +# // Return value python 'dict' object example: +# // { +# // "Number": 3, +# // "FAN1_1": { +# // "Present": True, +# // "Running": True, +# // "Speed": 2000.0, +# // "LowThd": 1000.0, +# // "HighThd": 15000.0, +# // "PN": "PN-EXAMPLE-123", +# // "SN": "SN-EXAMPLE-123" +# // "Status": True, +# // "AirFlow": "FTOB" +# // }, +# // "FAN1_2": { +# // "Present": True, +# // "Running": True, +# // "Speed": 2500.0, +# // "LowThd": 1000.0, +# // "HighThd": 15000.0, +# // "PN": "PN-EXAMPLE-456", +# // "SN": "SN-EXAMPLE-456" +# // "Status": True, +# // "AirFlow": "BTOF" +# // }, +# // "FAN2_1": { +# // "Present": True, +# // "Running": False +# // }, +# // "FAN2_2": { +# // "Present": True, +# // "Running": False +# // }, +# // "FAN3_1": { +# // "Present": False +# // }, +# // "FAN3_2": { +# // "Present": False +# // } +# // } +# dict get_all() +# +# class SensorUtil: +# int get_num_sensors(); //get the number of sensors +# int get_sensor_input_num(int index); //get the number of the input items of the specified sensor +# str get_sensor_name(int index);// get the device name of the specified sensor.for example "coretemp-isa-0000" +# str get_sensor_input_name(int sensor_index, int input_index); //get the input item name of the specified input item of the specified sensor index, for example "Physical id 0" +# str get_sensor_input_type(int sensor_index, int input_index); //get the item type of the specified input item of the specified sensor index, the return value should +# //among "voltage","temperature"... +# float get_sensor_input_value(int sensor_index, int input_index);//get the current value of the input item, the unit is "V" or "C"... +# float get_sensor_input_low_threshold(int sensor_index, int input_index); //get the low threshold of the value, the status of this item is not ok if the current +# //value high_threshold +# // Get all information of system sensors, returns JSON objects in python 'DICT'. +# // SensorName1, SensorName2, ... optional, string +# // SensorInput1, SensorInput2, ... optional, string +# // Type, mandatory in SensorInput$INDEX, should be on of { "temperature", "voltage", "power", "amp", "RPM" } +# // Value, mandatory in SensorInput$INDEX, float , real value +# // LowThd, mandatory in SensorInput$INDEX, float , lower bound of value +# // HighThd, mandatory in SensorInput$INDEX, float , upper bound of value +# // Return python 'dict' objects, example: +# // { +# // "SensorName1": { +# // "CPU_TEMP": +# // "Type": "temperature", +# // "Value": 37.3, +# // "LowThd": 0.0, +# // "HighThd": 110.0 +# // }, +# // "SWITCH_TEMP": { +# // "Type": "temperature", +# // "Value": 45.2, +# // "LowThd": 0.0, +# // "HighThd": 108.0 +# // }, +# // "INLET_TEMP": { +# // "Type": "temperature", +# // "Value": 22.0, +# // "LowThd": 0.0, +# // "HighThd": 70.0 +# // }, +# // "Sys_AirFlow": "BTOF", +# // "Switch_VDDCore_0.8v": { +# // "Type": "voltage", +# // "Value": 0.75, +# // "LowThd": 0.7, +# // "HighThd": 0.85 +# // }, +# // "Cpu_VDDCore_0.8v": { +# // "Type": "voltage", +# // "Value": 0.75, +# // "LowThd": 0.7, +# // "HighThd": 0.85 +# // }, +# // "SensorInput1": { +# // "Type": "temperature", +# // "Value": 30.0, +# // "LowThd": 0.0, +# // "HighThd": 100.0" +# // }, +# // "SensorInput2": { +# // "Type": "voltage", +# // "Value": 0.5, +# // "LowThd": 0.0, +# // "HighThd": 1.5 +# // }, +# // "SensorInput3": { +# // "Type": "power", +# // "Value": 2.5, +# // "LowThd": 0.0, +# // "HighThd": 5.0 +# // } +# // }, +# // "SensorName2": { +# // "SensorInput1": { +# // "Type": "RPM", +# // "Value": 2000.0, +# // "LowThd": 1000.0, +# // "HighThd": 15000.0 +# // }, +# // "SensorInputName2": { +# // "Type": "amp", +# // "Value": 0.1, +# // "LowThd": 0.0, +# // "HighThd": 0.3 +# // } +# // } +# // } + +try: + import sys + import os + import subprocess + import click + import imp + import syslog + import types + import traceback + from tabulate import tabulate +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +VERSION = '1.2' + +SYSLOG_IDENTIFIER = "platformutil" +PLATFORM_PSU_MODULE_NAME = "psuutil" +PLATFORM_PSU_CLASS_NAME = "PsuUtil" + +#gongjian add +PLATFORM_SENSOR_MODULE_NAME = "sensorutil" +PLATFORM_SENSOR_CLASS_NAME = "SensorUtil" + +PLATFORM_FAN_MODULE_NAME = "fanutil" +PLATFORM_FAN_CLASS_NAME = "FanUtil" +#end gongjian add + +PLATFORM_ROOT_PATH = '/usr/share/sonic/device' +PLATFORM_ROOT_PATH_DOCKER = '/usr/share/sonic/platform' +SONIC_CFGGEN_PATH = '/usr/local/bin/sonic-cfggen' +MINIGRAPH_PATH = '/etc/sonic/minigraph.xml' +HWSKU_KEY = "DEVICE_METADATA['localhost']['hwsku']" +PLATFORM_KEY = "DEVICE_METADATA['localhost']['platform']" + +# Global platform-specific psuutil class instance +platform_psuutil = None + +#gongjian add +platform_sensorutil = None +Platform_fanutil = None +#end gongjian add + +# ========================== 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: + click.echo(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: + click.echo(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: + click.echo(msg) + + +# ==================== Methods for initialization ==================== + +# Returns platform and HW SKU +def get_platform_and_hwsku(): + try: + proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-H', '-v', PLATFORM_KEY], + stdout=subprocess.PIPE, + shell=False, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + platform = stdout.rstrip('\n') + + proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-d', '-v', HWSKU_KEY], + stdout=subprocess.PIPE, + shell=False, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + hwsku = stdout.rstrip('\n') + except OSError, e: + raise OSError("Cannot detect platform") + + return (platform, hwsku) + + +# Loads platform specific psuutil module from source +def load_platform_util(): + global platform_psuutil + #gongjian add + global platform_sensorutil + global platform_fanutil + + # Get platform and hwsku + (platform, hwsku) = get_platform_and_hwsku() + + # Load platform module from source + platform_path = '' + if len(platform) != 0: + platform_path = "/".join([PLATFORM_ROOT_PATH, platform]) + else: + platform_path = PLATFORM_ROOT_PATH_DOCKER + hwsku_path = "/".join([platform_path, hwsku]) + + try: + module_file_psu = "/".join([platform_path, "plugins", PLATFORM_PSU_MODULE_NAME + ".py"]) + module_psu = imp.load_source(PLATFORM_PSU_MODULE_NAME, module_file_psu) + except IOError, e: + log_error("Failed to load platform module '%s': %s" % (PLATFORM_PSU_MODULE_NAME, str(e)), True) + return -1 + + try: + platform_psuutil_class = getattr(module_psu, PLATFORM_PSU_CLASS_NAME) + platform_psuutil = platform_psuutil_class() + except AttributeError, e: + log_error("Failed to instantiate '%s' class: %s" % (PLATFORM_PSU_CLASS_NAME, str(e)), True) + return -2 + + + #gongjian add + try: + module_file_sensor = "/".join([platform_path, "plugins", PLATFORM_SENSOR_MODULE_NAME + ".py"]) + module_sensor = imp.load_source(PLATFORM_SENSOR_MODULE_NAME, module_file_sensor) + except IOError, e: + log_error("Failed to load platform module '%s': %s" % (PLATFORM_SENSOR_MODULE_NAME, str(e)), True) + return -1 + + try: + platform_sensorutil_class = getattr(module_sensor, PLATFORM_SENSOR_CLASS_NAME) + platform_sensorutil = platform_sensorutil_class() + except AttributeError, e: + log_error("Failed to instantiate '%s' class: %s" % (PLATFORM_SENSOR_CLASS_NAME, str(e)), True) + return -2 + + try: + module_file_fan = "/".join([platform_path, "plugins", PLATFORM_FAN_MODULE_NAME + ".py"]) + module_fan = imp.load_source(PLATFORM_FAN_MODULE_NAME, module_file_fan) + except IOError, e: + log_error("Failed to load platform module '%s': %s" % (PLATFORM_FAN_MODULE_NAME, str(e)), True) + return -1 + + try: + platform_fanutil_class = getattr(module_fan, PLATFORM_FAN_CLASS_NAME) + platform_fanutil = platform_fanutil_class() + except AttributeError, e: + log_error("Failed to instantiate '%s' class: %s" % (PLATFORM_FAN_CLASS_NAME, str(e)), True) + return -2 + #end gongjian add + return 0 + + +# ==================== CLI commands and groups ==================== + + +# This is our main entrypoint - the main 'psuutil' command +@click.group() +def cli(): + """platformutil - Command line utility for providing platform status""" + + if os.geteuid() != 0: + click.echo("Root privileges are required for this operation") + sys.exit(1) + + # Load platform-specific psuutil, fanutil and sensorutil class + err = load_platform_util() + if err != 0: + sys.exit(2) + +#'fan' subcommand +@cli.group() +@click.pass_context +def fan(ctx): + """fan state""" + ctx.obj = "fan" + +# 'sensor' subcommand +@cli.group() +@click.pass_context +def sensor(ctx): + """sensor state""" + ctx.obj = "sensor" + +# 'psu' subcommand +@cli.group() +@click.pass_context +def psu(ctx): + """psu state""" + ctx.obj = "psu" + +# 'version' subcommand +@cli.command() +def version(): + """Display version info""" + click.echo("platformutil version {0}".format(VERSION)) + + +# 'num' subcommand +@click.command() +@click.pass_context +def num(ctx): + """Display number of supported sensor/fan/psu device""" + if ctx.obj == "psu": + click.echo(str(platform_psuutil.get_num_psus())) + if ctx.obj == "fan": + click.echo(str(len(platform_fanutil.get_fans_name_list()))) + if ctx.obj == "sensor": + click.echo(str(platform_sensorutil.get_num_sensors())) + +psu.add_command(num) +sensor.add_command(num) +fan.add_command(num) + +# 'status' subcommand +#all API should return "N/A" or float("-intf") if not supported +@click.command() +@click.pass_context +def status(ctx): + if ctx.obj == 'psu': + psu_dict = platform_psuutil.get_all() + if psu_dict == None: + print 'Error: psuutil.get_all() failed' + return + + psu_nr = psu_dict.get('Number') + if psu_nr == None: + print 'Error: PSU get all format invalid, prop "Number" missing.' + return + + psu_names = [ k for k in psu_dict.keys() if cmp('Number', k) != 0 ] + psu_names.sort() + header = ['PSU', 'Presence', 'InputStatus', 'InputType', 'OutputStatus', 'PN', 'SN', 'AirFlow'] + status_table = [] + for psu_name in psu_names: + psu = psu_dict[psu_name] + presence = psu.get('Present') + pn = psu.get('PN') + sn = psu.get('SN') + in_status = psu.get('InputStatus') + out_status = psu.get('OutputStatus') + in_type = psu.get('InputType') + airflow = psu.get('AirFlow') + + if presence == None: + print 'Error: PSU get all format invaid, prop "Present" is missing.' + continue + elif presence == False: + presence = 'NOT_PRESENT' + in_status = 'N/A' + out_status = 'N/A' + in_type = 'N/A' + pn = 'N/A' + pn = 'N/A' + else: + presence = 'PRESENT' + if in_status == None: + in_status = 'N/A' + elif in_status == True: + in_status = 'OK' + else: + in_status = 'NOT_OK' + + if in_type == None: + in_type = 'N/A' + + if out_status == None: + out_status = 'N/A' + elif out_status == True: + out_status = 'OK' + else: + out_status = 'NOT_OK' + + if pn == None: + pn = 'N/A' + if sn == None: + sn = 'N/A' + if airflow == None: + airflow = 'N/A' + status_table.append([psu_name, presence, in_status, in_type, out_status, pn, sn, airflow]) + + if len(status_table) != psu_nr: + print 'Error: PSU get all missing some PSU information.' + + if len(status_table) > 0: + click.echo(tabulate(status_table, header, tablefmt='simple')) + + if ctx.obj == 'fan': + fan_dict = platform_fanutil.get_all() + if fan_dict == None: + print 'Error: fanutil.get_all() failed' + return + + fan_nr = fan_dict.get('Number') + if fan_nr == None: + print 'Error: FAN get all format invalid, prop "Number" missing.' + return + + header = [ 'FAN', 'Presence', 'Status', 'Speed', 'LowThd', 'HighThd', 'PN', 'SN', 'AirFlow' ] + status_table = [] + fan_names = [ k for k in fan_dict.keys() if cmp('Number', k) != 0 ] + fan_names.sort() + for fan_name in fan_names: + fan = fan_dict[fan_name] + presence = fan.get('Present') + speed = fan.get('Speed') + low = fan.get('LowThd') + high = fan.get('HighThd') + pn = fan.get('PN') + sn = fan.get('SN') + status = fan.get('Status') + airflow = fan.get('AirFlow') + + if presence == None: + print 'Error: FAN get all format invaid, prop "Present" missing.' + continue + elif presence == False: + presence = 'NOT_PRESENT' + status = 'N/A' + speed = 'N/A' + low = 'N/A' + high = 'N/A' + pn = 'N/A' + sn = 'N/A' + airflow = 'N/A' + else: + presence = 'PRESENT' + if status == None: + status = 'N/A' + elif status == True: + status = 'OK' + else: + status = 'NOT_OK' + if airflow == None: + airflow = 'N/A' + if speed == None: + speed = 'N/A' + if low == None: + low = 'N/A' + if high == None: + high = 'N/A' + if pn == None: + pn = 'N/A' + if sn == None: + sn = 'N/A' + + status_table.append([fan_name, presence, status, speed, low, high, pn, sn, airflow]) + + if len(status_table) != fan_nr: + print 'Error: FAN get all missing some FAN information.' + + if len(status_table) > 0: + click.echo(tabulate(status_table, header, tablefmt='simple')) + + if ctx.obj == 'sensor': + sensor_dict = platform_sensorutil.get_all() + if sensor_dict == None: + print 'Error: sensors.get_all() failed' + return + + header = [ 'Sensor', 'InputName', 'State', 'Value', 'LowThd', 'HighThd' ] + status_table = [] + type2unit = { 'temperature' : ' C', 'voltage' : ' V', 'RPM' : ' RPM', 'amp' : ' A', 'power' : ' W'} + type_keys = type2unit.keys() + for sensor_name, sensor_obj in sensor_dict.items(): + if cmp(sensor_name, 'Number') == 0: + continue + + si_names = [ k for k in sensor_obj.keys() ] + si_names.sort() + for si_name in si_names: + si = sensor_obj[si_name] + if si_name == "Sys_AirFlow": + status = 'OK' + airflow = si + status_table.append([sensor_name, si_name, status, airflow, airflow, airflow]) + continue + + stype = si.get('Type') + sval = si.get('Value') + slow = si.get('LowThd') + shigh = si.get('HighThd') + sunit = ' ' + fault = False + if stype != None: + sunit = type2unit.get(stype) + if sunit == None: + sunit = ' ' + try: + sval = float(sval) + except: + sval = 0.0 + fault = True + + try: + slow = float(slow) + except: + slow = 0.0 + fault = True + + try: + shigh = float(shigh) + except: + shigh = 0.0 + fault = True + + status = 'NOT_OK' + if fault == False and sval > slow and sval < shigh: + status = 'OK' + + status_table.append([sensor_name, si_name, status, (str(sval)+sunit), (str(slow)+sunit), (str(shigh)+sunit)]) + + if len(status_table) > 0: + click.echo(tabulate(status_table, header, tablefmt="simple")) + + return + +psu.add_command(status) +sensor.add_command(status) +fan.add_command(status) + + +if __name__ == '__main__': + cli() diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/power_utils/power b/platform/broadcom/sonic-platform-modules-cel/tools/power_utils/power new file mode 100755 index 000000000000..e3d42d5c0353 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/tools/power_utils/power @@ -0,0 +1,86 @@ +#!/bin/bash +# +# Copyright 2019-present Celestica. All Rights Reserved. +# +# This program file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# + +PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin + +prog="$0" + +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root" + exit 1 +fi + +usage() { + echo "Usage: power " + echo + echo "Commands:" + echo + echo " cycle cpu: To power cycle the CPU" + echo + echo " cycle system : To reboot the whole system" + echo +} + +cpu_cycle() { + echo "Power cycling CPU..." + curl -m 5 -d '{"data":"/usr/local/bin/wedge_power.sh off;/usr/local/bin/wedge_power.sh on"}' http://240.1.1.1:8080/api/sys/raw + ret=$? + if [ $ret -ne 0 ]; then + echo "Failed to power cycle the CPU" + fi + return 0 +} + +system_cycle() { + echo "Power cycling system..." + curl -m 5 -d '{"data":"/usr/local/bin/wedge_power.sh off;/usr/local/bin/wedge_power.sh on;reboot"}' http://240.1.1.1:8080/api/sys/raw + ret=$? + if [ $ret -ne 0 ]; then + echo "Failed to power cycle the system" + fi + return 0 +} + +if [ $# -lt 1 ]; then + usage + exit -1 +fi + +command="$1" +component="$2" +shift + +case "$command" in +cycle) + case "$component" in + cpu) + cpu_cycle + ;; + system) + system_cycle + ;; + *) + usage + exit -1 + ;; + esac + ;; +*) + usage + exit -1 + ;; +esac + +exit $? diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/read_optic_temp.py b/platform/broadcom/sonic-platform-modules-cel/tools/read_optic_temp.py new file mode 100644 index 000000000000..97e4641066ba --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/tools/read_optic_temp.py @@ -0,0 +1,189 @@ +#!/usr/bin/env python +# +# read_optic_temp.py +# +# Command-line utility for read the temperature of optic modules. +# + +try: + import sys + import os + import subprocess + import click + import imp + import multiprocessing.pool + import threading +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +PLATFORM_ROOT_PATH = '/usr/share/sonic/device' +SONIC_CFGGEN_PATH = '/usr/local/bin/sonic-cfggen' +HWSKU_KEY = 'DEVICE_METADATA.localhost.hwsku' +PLATFORM_KEY = 'DEVICE_METADATA.localhost.platform' + +PLATFORM_SPECIFIC_SFP_MODULE_NAME = "sfputil" +PLATFORM_SPECIFIC_SFP_CLASS_NAME = "SfpUtil" + +PLATFORM_SPECIFIC_OPTICTEMP_MODULE_NAME = "optictemputil" +PLATFORM_SPECIFIC_OPTICTEMP_CLASS_NAME = "OpticTempUtil" + +# Global platform-specific psuutil class instance +platform_optictemputil = None +platform_sfputil = None + + +# ==================== Methods for initialization ==================== + +# Returns platform and HW SKU +def get_platform_and_hwsku(): + try: + proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-H', '-v', PLATFORM_KEY], + stdout=subprocess.PIPE, + shell=False, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + platform = stdout.rstrip('\n') + + proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-d', '-v', HWSKU_KEY], + stdout=subprocess.PIPE, + shell=False, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + hwsku = stdout.rstrip('\n') + except OSError, e: + raise OSError("Cannot detect platform") + + return (platform, hwsku) + + +# Returns path to port config file +def get_path_to_port_config_file(): + # Get platform and hwsku + (platform, hwsku) = get_platform_and_hwsku() + + # Load platform module from source + platform_path = "/".join([PLATFORM_ROOT_PATH, platform]) + hwsku_path = "/".join([platform_path, hwsku]) + + # First check for the presence of the new 'port_config.ini' file + port_config_file_path = "/".join([hwsku_path, "port_config.ini"]) + if not os.path.isfile(port_config_file_path): + # port_config.ini doesn't exist. Try loading the legacy 'portmap.ini' file + port_config_file_path = "/".join([hwsku_path, "portmap.ini"]) + + return port_config_file_path + + +def load_platform_util(module_name, class_name): + + # Get platform and hwsku + (platform, hwsku) = get_platform_and_hwsku() + + # Load platform module from source + platform_path = "/".join([PLATFORM_ROOT_PATH, platform]) + hwsku_path = "/".join([platform_path, hwsku]) + + try: + module_file = "/".join([platform_path, "plugins", module_name + ".py"]) + module = imp.load_source(module_name, module_file) + except IOError, e: + print("Failed to load platform module '%s': %s" % (module_name, str(e))) + sys.exit(1) + + try: + platform_util_class = getattr(module, class_name) + platform_util = platform_util_class() + except AttributeError, e: + print("Failed to instantiate '%s' class: %s" % (class_name, str(e))) + sys.exit(1) + + return platform_util + + +def get_optic_temp(port_list): + temp_list = [] + for idx, port_num in enumerate(port_list[0]): + temp = platform_optictemputil.get_optic_temp( + port_num, port_list[1][idx]) + temp_list.append(round(float(temp), 2)) + return temp_list + + +# ========================= CLI commands ========================= + +# This is our main entrypoint - the main 'opticutil' command +@click.command() +@click.option('--port_num', '-p', type=int, help='Specific port number') +def cli(port_num): + """optictemputil - Command line utility for providing platform status""" + + # Check root privileges + if os.geteuid() != 0: + click.echo("Root privileges are required for this operation") + sys.exit(1) + + global platform_optictemputil + global platform_sfputil + + # Load platform-specific class + platform_sfputil = load_platform_util( + PLATFORM_SPECIFIC_SFP_MODULE_NAME, PLATFORM_SPECIFIC_SFP_CLASS_NAME) + platform_optictemputil = load_platform_util( + PLATFORM_SPECIFIC_OPTICTEMP_MODULE_NAME, PLATFORM_SPECIFIC_OPTICTEMP_CLASS_NAME) + + # Load port config + port_config_file_path = get_path_to_port_config_file() + platform_sfputil.read_porttab_mappings(port_config_file_path) + port_list = platform_sfputil.port_to_i2cbus_mapping + port_eeprom_list = platform_sfputil.port_to_eeprom_mapping + qsfp_port_list = platform_sfputil.qsfp_ports + + port_dict = {} + temp_list = [0] + i2c_block_size = 32 + concurrent = 10 + + port_data_list = [] + port_bus_list = [] + port_type_list = [] + + # Read port temperature + if port_num: + if port_num not in port_list: + click.echo("Invalid port") + sys.exit(1) + port_list = {port_num: port_list.get(port_num)} + + for port_num, bus_num in port_list.items(): + port_type = "QSFP" if port_num in qsfp_port_list else "SFP" + port_bus_list.append(port_eeprom_list[port_num]) + port_type_list.append(port_type) + if len(port_bus_list) >= i2c_block_size: + port_tub = (port_bus_list, port_type_list) + port_data_list.append(port_tub) + port_bus_list = [] + port_type_list = [] + + if port_bus_list != []: + port_tub = (port_bus_list, port_type_list) + port_data_list.append(port_tub) + + pool = multiprocessing.pool.ThreadPool(processes=concurrent) + temp_list = pool.map(get_optic_temp, port_data_list, chunksize=1) + pool.close() + + flat_list = [item for sublist in temp_list for item in sublist] + click.echo("| PORT_NO\t| PORT_TYPE\t| TEMPERATURE\t|") + for port_num, bus_num in port_list.items(): + port_type = "QSFP" if port_num in qsfp_port_list else "SFP" + temp_idx = port_list.keys().index(port_num) + temp = flat_list[temp_idx] + click.echo('| {}\t\t| {}\t\t| {}\t\t|'.format( + port_num, port_type, temp)) + + +if __name__ == '__main__': + cli() diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/sync_bmc/bmc_vlan.service b/platform/broadcom/sonic-platform-modules-cel/tools/sync_bmc/bmc_vlan.service new file mode 100644 index 000000000000..9aeeead72394 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/tools/sync_bmc/bmc_vlan.service @@ -0,0 +1,12 @@ +[Unit] +Description="Service for add vlan for rsyslog" +After=network.target +Before=rsyslog-config.service +Before=ntp.service + +[Service] +Type=forking +ExecStart=/bin/sh /usr/local/etc/bmc_vlan.sh + +[Install] +WantedBy=rsyslog.service \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/sync_bmc/bmc_vlan.sh b/platform/broadcom/sonic-platform-modules-cel/tools/sync_bmc/bmc_vlan.sh new file mode 100644 index 000000000000..1d439915efb0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/tools/sync_bmc/bmc_vlan.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Add vlan +ip link add link eth0 name eth0.4088 type vlan id 4088 +ip addr add 240.1.1.2/30 dev eth0.4088 +ip link set eth0.4088 up +exit 0 \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/sync_bmc/sync_bmc.py b/platform/broadcom/sonic-platform-modules-cel/tools/sync_bmc/sync_bmc.py new file mode 100644 index 000000000000..3065e8a21ebf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/tools/sync_bmc/sync_bmc.py @@ -0,0 +1,203 @@ +#!/usr/bin/env python + +############################################################################# +# # +# Platform and model specific service for send data to BMC # +# # +# # +############################################################################# + +import subprocess +import requests +import os +import imp +import multiprocessing.pool +import threading + + +PLATFORM_ROOT_PATH = '/usr/share/sonic/device' +SONIC_CFGGEN_PATH = '/usr/local/bin/sonic-cfggen' +HWSKU_KEY = 'DEVICE_METADATA.localhost.hwsku' +PLATFORM_KEY = 'DEVICE_METADATA.localhost.platform' +TEMP_URL = 'http://240.1.1.1:8080/api/sys/temp' + +PLATFORM_SPECIFIC_SFP_MODULE_NAME = "sfputil" +PLATFORM_SPECIFIC_SFP_CLASS_NAME = "SfpUtil" + +PLATFORM_SPECIFIC_OPTICTEMP_MODULE_NAME = "optictemputil" +PLATFORM_SPECIFIC_OPTICTEMP_CLASS_NAME = "OpticTempUtil" + +PLATFORM_SPECIFIC_CPUTEMP_MODULE_NAME = "cputemputil" +PLATFORM_SPECIFIC_CPUTEMP_CLASS_NAME = "CpuTempUtil" + +platform_sfputil = None +platform_optictemputil = None +platform_cputemputil = None + + +# Returns platform and HW SKU +def get_platform_and_hwsku(): + try: + proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-H', '-v', PLATFORM_KEY], + stdout=subprocess.PIPE, + shell=False, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + platform = stdout.rstrip('\n') + + proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-d', '-v', HWSKU_KEY], + stdout=subprocess.PIPE, + shell=False, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + hwsku = stdout.rstrip('\n') + except OSError, e: + raise OSError("Cannot detect platform") + + return (platform, hwsku) + + +# Returns path to port config file +def get_path_to_port_config_file(): + # Get platform and hwsku + (platform, hwsku) = get_platform_and_hwsku() + + # Load platform module from source + platform_path = "/".join([PLATFORM_ROOT_PATH, platform]) + hwsku_path = "/".join([platform_path, hwsku]) + + # First check for the presence of the new 'port_config.ini' file + port_config_file_path = "/".join([hwsku_path, "port_config.ini"]) + if not os.path.isfile(port_config_file_path): + # port_config.ini doesn't exist. Try loading the legacy 'portmap.ini' file + port_config_file_path = "/".join([hwsku_path, "portmap.ini"]) + + return port_config_file_path + + +def load_platform_util(module_name, class_name): + + # Get platform and hwsku + (platform, hwsku) = get_platform_and_hwsku() + + # Load platform module from source + platform_path = "/".join([PLATFORM_ROOT_PATH, platform]) + hwsku_path = "/".join([platform_path, hwsku]) + + try: + module_file = "/".join([platform_path, "plugins", module_name + ".py"]) + module = imp.load_source(module_name, module_file) + except IOError, e: + print("Failed to load platform module '%s': %s" % ( + module_name, str(e)), True) + return -1 + + try: + platform_util_class = getattr(module, class_name) + platform_util = platform_util_class() + except AttributeError, e: + print("Failed to instantiate '%s' class: %s" % + (class_name, str(e)), True) + return -2 + + return platform_util + + +def get_optic_temp(port_list): + temp_list = [] + for idx, port_eeprom in enumerate(port_list[0]): + temp = platform_optictemputil.get_optic_temp( + port_eeprom, port_list[1][idx]) if port_list[2][idx] else 0 + temp_list.append(round(float(temp), 2)) + return max(temp_list) + + +def get_max_optic_temp(): + port_config_file_path = get_path_to_port_config_file() + platform_sfputil.read_porttab_mappings(port_config_file_path) + port_list = platform_sfputil.port_to_i2cbus_mapping + port_eeprom_list = platform_sfputil.port_to_eeprom_mapping + qsfp_port_list = platform_sfputil.qsfp_ports + + port_data_list = [] + temp_list = [0] + i2c_block_size = 32 + concurrent = 10 + + port_bus_list = [] + port_type_list = [] + port_presence_list = [] + + for port_num, bus_num in port_list.items(): + port_type = "QSFP" if port_num in qsfp_port_list else "SFP" + port_bus_list.append(port_eeprom_list[port_num]) + port_type_list.append(port_type) + status = platform_sfputil.get_presence(port_num) + port_presence_list.append(status) + if len(port_bus_list) >= i2c_block_size: + port_tub = (port_bus_list, port_type_list, port_presence_list) + port_data_list.append(port_tub) + port_bus_list = [] + port_type_list = [] + port_presence_list = [] + + if port_bus_list != []: + port_tub = (port_bus_list, port_type_list, port_presence_list) + port_data_list.append(port_tub) + + pool = multiprocessing.pool.ThreadPool(processes=concurrent) + temp_list = pool.map(get_optic_temp, port_data_list, chunksize=1) + pool.close() + return max(temp_list) + + +# Send CPU temperature to BMC. +def send_cpu_temp(): + max_cpu_tmp = platform_cputemputil.get_max_cpu_tmp() + json_input = { + "chip": "cpu", + "option": "input", + "value": str(int(max_cpu_tmp)) + } + print "send ", json_input + requests.post(TEMP_URL, json=json_input) + + +# Send maximum optic module temperature to BMC. +def send_optic_temp(): + max_optic_temp = get_max_optic_temp() + json_input = { + "chip": "optical", + "option": "input", + "value": str(int(max_optic_temp)) + } + print "send ", json_input + requests.post(TEMP_URL, json=json_input) + + +def main(): + global platform_sfputil + global platform_cputemputil + global platform_optictemputil + + try: + platform_sfputil = load_platform_util( + PLATFORM_SPECIFIC_SFP_MODULE_NAME, PLATFORM_SPECIFIC_SFP_CLASS_NAME) + platform_cputemputil = load_platform_util( + PLATFORM_SPECIFIC_CPUTEMP_MODULE_NAME, PLATFORM_SPECIFIC_CPUTEMP_CLASS_NAME) + platform_optictemputil = load_platform_util( + PLATFORM_SPECIFIC_OPTICTEMP_MODULE_NAME, PLATFORM_SPECIFIC_OPTICTEMP_CLASS_NAME) + + t1 = threading.Thread(target=send_cpu_temp) + t2 = threading.Thread(target=send_optic_temp) + t1.start() + t2.start() + except Exception, e: + print e + pass + + +if __name__ == "__main__": + main() diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/sync_bmc/sync_bmc.service b/platform/broadcom/sonic-platform-modules-cel/tools/sync_bmc/sync_bmc.service new file mode 100644 index 000000000000..334485342510 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/tools/sync_bmc/sync_bmc.service @@ -0,0 +1,10 @@ +[Unit] +Description=Service for send sensor data value to BMC. +After=multi-user.target + +[Service] +Type=idle +ExecStart=/usr/bin/python /usr/local/etc/sync_bmc.py + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/sync_bmc/sync_bmc.timer b/platform/broadcom/sonic-platform-modules-cel/tools/sync_bmc/sync_bmc.timer new file mode 100644 index 000000000000..71666cc99887 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/tools/sync_bmc/sync_bmc.timer @@ -0,0 +1,10 @@ +[Unit] +Description=Timer send sensor data value to BMC. + +[Timer] +OnUnitActiveSec=5s +OnBootSec=5s +AccuracySec=1us + +[Install] +WantedBy=timers.target \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c index 7c258cdfeab7..e8cddf4fad11 100644 --- a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c +++ b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c @@ -631,7 +631,7 @@ static ssize_t show_fan(struct device *dev, ret = smf_read_reg16(data, PSU_2_FAN_SPEED); break; case 12: - ret = ~smf_read_reg(data, FAN_TRAY_PRESENCE); + ret = (~smf_read_reg(data, FAN_TRAY_PRESENCE) & 0xff); export_hex = 1; break; @@ -682,14 +682,26 @@ static ssize_t show_fan_alarm(struct device *dev, struct smf_data *data = dev_get_drvdata(dev); int ret, psu_fan_status=0; - if(index < 2) - psu_fan_status = smf_read_reg(data, FAN_STATUS_GROUP_B); + if (data->kind == z9100smf) { + if ((index % 2) == 0) + index = index / 2; + else + index = (index / 2) + 5; + } + + if (data->kind == s6100smf) + index = index / 2; + + if (index > 7) { + psu_fan_status = ~smf_read_reg(data, FAN_STATUS_GROUP_A); + index = index % 8; + } else + psu_fan_status = ~smf_read_reg(data, FAN_STATUS_GROUP_B); if (psu_fan_status & (1 << (index))) ret=0; - - if (ret < 0) - return ret; + else + ret=1; return sprintf(buf, "%d\n", ret); } @@ -726,12 +738,12 @@ static ssize_t show_psu_fan(struct device *dev, if (index < FAN_601_FAULT){ fan_status = smf_read_reg(data, PSU_1_FAN_STATUS); - ret = fan_status & (1 << index); + ret = (fan_status >> index) & 1; } else{ fan_status = smf_read_reg(data, PSU_2_FAN_STATUS); - ret = fan_status & (1 << (index - 3)); + ret = (fan_status >> (index - 3)) & 1; } if (ret < 0) @@ -1319,17 +1331,15 @@ static ssize_t show_current(struct device *dev, else ret = smf_read_reg16(data, SWITCH_CURRENT_Z9100 + index * 2); else if (index < CURR602_INPUT) - curr = smf_read_reg16(data, PSU_1_INPUT_CURRENT + (index % 4) * 2); + ret = smf_read_reg16(data, PSU_1_INPUT_CURRENT + (index % 2) * 2); else - curr = smf_read_reg16(data, PSU_2_INPUT_CURRENT + (index % 4) * 2); + ret = smf_read_reg16(data, PSU_2_INPUT_CURRENT + (index % 4) * 2); if (ret < 0) return ret; - /* TODO: docs say 10mA, value look like A? */ - if(index < 2) - curr = ret*1000; + curr = ret*10; return sprintf(buf, "%d\n", curr); } diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/control b/platform/broadcom/sonic-platform-modules-dell/debian/control index f32fa7244acc..0b9514687ce8 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/control +++ b/platform/broadcom/sonic-platform-modules-dell/debian/control @@ -7,30 +7,30 @@ Standards-Version: 3.9.3 Package: platform-modules-s6000 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9100 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s6100 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9264f Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s5232f Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s5248f Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.install index c2dcb5dc03a9..f662e751a3f8 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.install @@ -1,6 +1,8 @@ s6000/scripts/s6000_platform.sh usr/local/bin s6000/scripts/reset-qsfp usr/local/bin s6000/scripts/set-fan-speed usr/local/bin +s6000/scripts/fancontrol.sh usr/local/bin s6000/systemd/platform-modules-s6000.service etc/systemd/system +s6000/systemd/fancontrol.service etc/systemd/system common/io_rd_wr.py usr/local/bin s6000/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-dell_s6000_s1220-r0 diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.postinst b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.postinst index a9b90fa86f3a..052e5a6f574e 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.postinst +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.postinst @@ -4,4 +4,9 @@ depmod -a systemctl enable platform-modules-s6000.service systemctl start platform-modules-s6000.service + +systemctl enable fancontrol.service +systemctl start fancontrol.service + + #DEBHELPER# diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/modules/dell_s5232f_fpga_ocores.c b/platform/broadcom/sonic-platform-modules-dell/s5232f/modules/dell_s5232f_fpga_ocores.c index f66f5f18a708..c50d07a05a53 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/modules/dell_s5232f_fpga_ocores.c +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/modules/dell_s5232f_fpga_ocores.c @@ -1,25 +1,25 @@ /* - * Copyright (C) 2018 Dell Inc - * - * Licensed under the GNU General Public License Version 2 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ +* Copyright (C) 2018 Dell Inc +* +* Licensed under the GNU General Public License Version 2 +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +*/ -/********************************************************************** - * @file fpga_ocores.c - * @brief This is a driver to interface with Linux Open Cores driver for FPGA i2c access - * - ************************************************************************/ +/** +* @file fpga_i2ccore.c +* @brief This is a driver to interface with Linux Open Cores drivber for FPGA i2c access +* +************************************************************************/ #include #include #include @@ -67,30 +67,29 @@ static const size_t BUF_SIZE = PAGE_SIZE; /* Device data used by this driver. */ struct fpgapci_dev { - /* the kernel pci device data structure */ - struct pci_dev *pci_dev; - - /* upstream root node */ - struct pci_dev *upstream; + /* the kernel pci device data structure */ + struct pci_dev *pci_dev; - /* kernels virtual addr. for the mapped BARs */ - void * __iomem bar[PCI_NUM_BARS]; + /* upstream root node */ + struct pci_dev *upstream; - /* length of each memory region. Used for error checking. */ - size_t bar_length[PCI_NUM_BARS]; + /* kernels virtual addr. for the mapped BARs */ + void * __iomem bar[PCI_NUM_BARS]; - /* Debug data */ - /* number of hw interrupts handled. */ - int num_handled_interrupts; - int num_undelivered_signals; - int pci_gen; - int pci_num_lanes; + /* length of each memory region. Used for error checking. */ + size_t bar_length[PCI_NUM_BARS]; - unsigned int irq_first; - unsigned int irq_length; - unsigned int irq_assigned; - unsigned int xcvr_intr_count; + /* Debug data */ + /* number of hw interrupts handled. */ + int num_handled_interrupts; + int num_undelivered_signals; + int pci_gen; + int pci_num_lanes; + unsigned int irq_first; + unsigned int irq_length; + unsigned int irq_assigned; + unsigned int xcvr_intr_count; }; static int use_irq = 1; @@ -100,7 +99,7 @@ MODULE_PARM_DESC(use_irq, "Get an use_irq value from user...\n"); static uint32_t num_bus = 0; module_param(num_bus, int, 0); MODULE_PARM_DESC(num_bus, - "Number of i2c busses supported by the FPGA on this platform."); + "Number of i2c busses supported by the FPGA on this platform."); /* Xilinx FPGA PCIE info: */ @@ -125,14 +124,14 @@ typedef unsigned long long u64; /* struct to hold data related to the pcie device */ struct pci_data_struct{ - struct pci_dev* dev; - unsigned long long phy_addr_bar0; - unsigned long long phy_len_bar0; - unsigned long long phy_flags_bar0; - unsigned int irq_first; - unsigned int irq_length; - unsigned int irq_assigned; - void * kvirt_addr_bar0; + struct pci_dev* dev; + unsigned long long phy_addr_bar0; + unsigned long long phy_len_bar0; + unsigned long long phy_flags_bar0; + unsigned int irq_first; + unsigned int irq_length; + unsigned int irq_assigned; + void * kvirt_addr_bar0; }; /* global variable declarations */ @@ -147,55 +146,55 @@ static void free_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev); struct fpgalogic_i2c { - void __iomem *base; - u32 reg_shift; - u32 reg_io_width; - wait_queue_head_t wait; - struct i2c_msg *msg; - int pos; - int nmsgs; - int state; /* see STATE_ */ - int ip_clock_khz; - int bus_clock_khz; - void (*reg_set)(struct fpgalogic_i2c *i2c, int reg, u8 value); - u8 (*reg_get)(struct fpgalogic_i2c *i2c, int reg); - u32 timeout; - struct mutex lock; + void __iomem *base; + u32 reg_shift; + u32 reg_io_width; + wait_queue_head_t wait; + struct i2c_msg *msg; + int pos; + int nmsgs; + int state; /* see STATE_ */ + int ip_clock_khz; + int bus_clock_khz; + void (*reg_set)(struct fpgalogic_i2c *i2c, int reg, u8 value); + u8 (*reg_get)(struct fpgalogic_i2c *i2c, int reg); + u32 timeout; + struct mutex lock; }; /* registers */ -#define FPGAI2C_REG_PRELOW 0 -#define FPGAI2C_REG_PREHIGH 1 -#define FPGAI2C_REG_CONTROL 2 -#define FPGAI2C_REG_DATA 3 -#define FPGAI2C_REG_CMD 4 /* write only */ -#define FPGAI2C_REG_STATUS 4 /* read only, same address as FPGAI2C_REG_CMD */ -#define FPGAI2C_REG_VER 5 +#define FPGAI2C_REG_PRELOW 0 +#define FPGAI2C_REG_PREHIGH 1 +#define FPGAI2C_REG_CONTROL 2 +#define FPGAI2C_REG_DATA 3 +#define FPGAI2C_REG_CMD 4 /* write only */ +#define FPGAI2C_REG_STATUS 4 /* read only, same address as FPGAI2C_REG_CMD */ +#define FPGAI2C_REG_VER 5 -#define FPGAI2C_REG_CTRL_IEN 0x40 -#define FPGAI2C_REG_CTRL_EN 0x80 +#define FPGAI2C_REG_CTRL_IEN 0x40 +#define FPGAI2C_REG_CTRL_EN 0x80 -#define FPGAI2C_REG_CMD_START 0x91 -#define FPGAI2C_REG_CMD_STOP 0x41 -#define FPGAI2C_REG_CMD_READ 0x21 -#define FPGAI2C_REG_CMD_WRITE 0x11 -#define FPGAI2C_REG_CMD_READ_ACK 0x21 -#define FPGAI2C_REG_CMD_READ_NACK 0x29 -#define FPGAI2C_REG_CMD_IACK 0x01 +#define FPGAI2C_REG_CMD_START 0x91 +#define FPGAI2C_REG_CMD_STOP 0x41 +#define FPGAI2C_REG_CMD_READ 0x21 +#define FPGAI2C_REG_CMD_WRITE 0x11 +#define FPGAI2C_REG_CMD_READ_ACK 0x21 +#define FPGAI2C_REG_CMD_READ_NACK 0x29 +#define FPGAI2C_REG_CMD_IACK 0x01 -#define FPGAI2C_REG_STAT_IF 0x01 -#define FPGAI2C_REG_STAT_TIP 0x02 -#define FPGAI2C_REG_STAT_ARBLOST 0x20 -#define FPGAI2C_REG_STAT_BUSY 0x40 -#define FPGAI2C_REG_STAT_NACK 0x80 +#define FPGAI2C_REG_STAT_IF 0x01 +#define FPGAI2C_REG_STAT_TIP 0x02 +#define FPGAI2C_REG_STAT_ARBLOST 0x20 +#define FPGAI2C_REG_STAT_BUSY 0x40 +#define FPGAI2C_REG_STAT_NACK 0x80 /* SR[7:0] - Status register */ -#define FPGAI2C_REG_SR_RXACK (1 << 7) /* Receive acknowledge from slave �1� = No acknowledge received*/ -#define FPGAI2C_REG_SR_BUSY (1 << 6) /* Busy, I2C bus busy (as defined by start / stop bits) */ -#define FPGAI2C_REG_SR_AL (1 << 5) /* Arbitration lost - fpga i2c logic lost arbitration */ -#define FPGAI2C_REG_SR_TIP (1 << 1) /* Transfer in progress */ -#define FPGAI2C_REG_SR_IF (1 << 0) /* Interrupt flag */ +#define FPGAI2C_REG_SR_RXACK (1 << 7) /* Receive acknowledge from slave .1. = No acknowledge received*/ +#define FPGAI2C_REG_SR_BUSY (1 << 6) /* Busy, I2C bus busy (as defined by start / stop bits) */ +#define FPGAI2C_REG_SR_AL (1 << 5) /* Arbitration lost - fpga i2c logic lost arbitration */ +#define FPGAI2C_REG_SR_TIP (1 << 1) /* Transfer in progress */ +#define FPGAI2C_REG_SR_IF (1 << 0) /* Interrupt flag */ enum { STATE_DONE = 0, @@ -205,15 +204,16 @@ enum { STATE_START, STATE_WRITE, STATE_READ, + STATE_STOP, STATE_ERROR, }; -#define TYPE_FPGALOGIC 0 -#define TYPE_GRLIB 1 +#define TYPE_FPGALOGIC 0 +#define TYPE_GRLIB 1 /*I2C_CH1 Offset address from PCIE BAR 0*/ -#define FPGALOGIC_I2C_BASE 0x00006000 -#define FPGALOGIC_CH_OFFSET 0x10 +#define FPGALOGIC_I2C_BASE 0x00006000 +#define FPGALOGIC_CH_OFFSET 0x10 #define i2c_bus_controller_numb 1 #define I2C_PCI_MAX_BUS (16) @@ -316,58 +316,58 @@ enum { static int total_i2c_pci_bus = 0; static uint32_t board_rev_type = 0; -static struct fpgalogic_i2c fpgalogic_i2c[I2C_PCI_MAX_BUS]; -static struct i2c_adapter i2c_pci_adap[I2C_PCI_MAX_BUS]; -static struct mutex i2c_xfer_lock[I2C_PCI_MAX_BUS]; +static struct fpgalogic_i2c fpgalogic_i2c[I2C_PCI_MAX_BUS]; +static struct i2c_adapter i2c_pci_adap[I2C_PCI_MAX_BUS]; +static struct mutex i2c_xfer_lock[I2C_PCI_MAX_BUS]; static void fpgai2c_reg_set_8(struct fpgalogic_i2c *i2c, int reg, u8 value) { - iowrite8(value, i2c->base + (reg << i2c->reg_shift)); + iowrite8(value, i2c->base + (reg << i2c->reg_shift)); } static void fpgai2c_reg_set_16(struct fpgalogic_i2c *i2c, int reg, u8 value) { - iowrite16(value, i2c->base + (reg << i2c->reg_shift)); + iowrite16(value, i2c->base + (reg << i2c->reg_shift)); } static void fpgai2c_reg_set_32(struct fpgalogic_i2c *i2c, int reg, u8 value) { - iowrite32(value, i2c->base + (reg << i2c->reg_shift)); + iowrite32(value, i2c->base + (reg << i2c->reg_shift)); } static void fpgai2c_reg_set_16be(struct fpgalogic_i2c *i2c, int reg, u8 value) { - iowrite16be(value, i2c->base + (reg << i2c->reg_shift)); + iowrite16be(value, i2c->base + (reg << i2c->reg_shift)); } static void fpgai2c_reg_set_32be(struct fpgalogic_i2c *i2c, int reg, u8 value) { - iowrite32be(value, i2c->base + (reg << i2c->reg_shift)); + iowrite32be(value, i2c->base + (reg << i2c->reg_shift)); } static inline u8 fpgai2c_reg_get_8(struct fpgalogic_i2c *i2c, int reg) { - return ioread8(i2c->base + (reg << i2c->reg_shift)); + return ioread8(i2c->base + (reg << i2c->reg_shift)); } static inline u8 fpgai2c_reg_get_16(struct fpgalogic_i2c *i2c, int reg) { - return ioread16(i2c->base + (reg << i2c->reg_shift)); + return ioread16(i2c->base + (reg << i2c->reg_shift)); } static inline u8 fpgai2c_reg_get_32(struct fpgalogic_i2c *i2c, int reg) { - return ioread32(i2c->base + (reg << i2c->reg_shift)); + return ioread32(i2c->base + (reg << i2c->reg_shift)); } static inline u8 fpgai2c_reg_get_16be(struct fpgalogic_i2c *i2c, int reg) { - return ioread16be(i2c->base + (reg << i2c->reg_shift)); + return ioread16be(i2c->base + (reg << i2c->reg_shift)); } static inline u8 fpgai2c_reg_get_32be(struct fpgalogic_i2c *i2c, int reg) { - return ioread32be(i2c->base + (reg << i2c->reg_shift)); + return ioread32be(i2c->base + (reg << i2c->reg_shift)); } static inline void fpgai2c_reg_set(struct fpgalogic_i2c *i2c, int reg, u8 value) @@ -384,29 +384,29 @@ static inline u8 fpgai2c_reg_get(struct fpgalogic_i2c *i2c, int reg) static void fpgai2c_dump(struct fpgalogic_i2c *i2c) { - u8 tmp; + u8 tmp; - PRINT("Logic register dump:\n"); + PRINT("Logic register dump:\n"); - tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_PRELOW); - PRINT("FPGAI2C_REG_PRELOW (%d) = 0x%x\n",FPGAI2C_REG_PRELOW,tmp); + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_PRELOW); + PRINT("FPGAI2C_REG_PRELOW (%d) = 0x%x\n",FPGAI2C_REG_PRELOW,tmp); - tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_PREHIGH); - PRINT("FPGAI2C_REG_PREHIGH(%d) = 0x%x\n",FPGAI2C_REG_PREHIGH,tmp); + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_PREHIGH); + PRINT("FPGAI2C_REG_PREHIGH(%d) = 0x%x\n",FPGAI2C_REG_PREHIGH,tmp); - tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_CONTROL); - PRINT("FPGAI2C_REG_CONTROL(%d) = 0x%x\n",FPGAI2C_REG_CONTROL,tmp); + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_CONTROL); + PRINT("FPGAI2C_REG_CONTROL(%d) = 0x%x\n",FPGAI2C_REG_CONTROL,tmp); - tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); - PRINT("FPGAI2C_REG_DATA (%d) = 0x%x\n",FPGAI2C_REG_DATA,tmp); + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); + PRINT("FPGAI2C_REG_DATA (%d) = 0x%x\n",FPGAI2C_REG_DATA,tmp); - tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_CMD); - PRINT("FPGAI2C_REG_CMD (%d) = 0x%x\n",FPGAI2C_REG_CMD,tmp); + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_CMD); + PRINT("FPGAI2C_REG_CMD (%d) = 0x%x\n",FPGAI2C_REG_CMD,tmp); } static void fpgai2c_stop(struct fpgalogic_i2c *i2c) { - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); } /* @@ -414,117 +414,117 @@ static void fpgai2c_stop(struct fpgalogic_i2c *i2c) */ static int fpgai2c_poll(struct fpgalogic_i2c *i2c) { - u8 stat = fpgai2c_reg_get(i2c, FPGAI2C_REG_STATUS); - struct i2c_msg *msg = i2c->msg; - u8 addr; - - /* Ready? */ - if (stat & FPGAI2C_REG_STAT_TIP) - return -EBUSY; - - if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) { - /* Stop has been sent */ - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); - if (i2c->state == STATE_ERROR) - return -EIO; - return 0; - } - - /* Error? */ - if (stat & FPGAI2C_REG_STAT_ARBLOST) { - i2c->state = STATE_ERROR; - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); - return -EAGAIN; - } - - if (i2c->state == STATE_INIT) { - if (stat & FPGAI2C_REG_STAT_BUSY) - return -EBUSY; - - i2c->state = STATE_ADDR; - } - - if (i2c->state == STATE_ADDR) { - /* 10 bit address? */ - if (i2c->msg->flags & I2C_M_TEN) { - addr = 0xf0 | ((i2c->msg->addr >> 7) & 0x6); - i2c->state = STATE_ADDR10; - } else { - addr = (i2c->msg->addr << 1); - i2c->state = STATE_START; - } + u8 stat = fpgai2c_reg_get(i2c, FPGAI2C_REG_STATUS); + struct i2c_msg *msg = i2c->msg; + u8 addr; + + /* Ready? */ + if (stat & FPGAI2C_REG_STAT_TIP) + return -EBUSY; + + if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) { + /* Stop has been sent */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + if (i2c->state == STATE_ERROR) + return -EIO; + return 0; + } + + /* Error? */ + if (stat & FPGAI2C_REG_STAT_ARBLOST) { + i2c->state = STATE_ERROR; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return -EAGAIN; + } + + if (i2c->state == STATE_INIT) { + if (stat & FPGAI2C_REG_STAT_BUSY) + return -EBUSY; + + i2c->state = STATE_ADDR; + } + + if (i2c->state == STATE_ADDR) { + /* 10 bit address? */ + if (i2c->msg->flags & I2C_M_TEN) { + addr = 0xf0 | ((i2c->msg->addr >> 7) & 0x6); + i2c->state = STATE_ADDR10; + } else { + addr = (i2c->msg->addr << 1); + i2c->state = STATE_START; + } - /* Set read bit if necessary */ - addr |= (i2c->msg->flags & I2C_M_RD) ? 1 : 0; + /* Set read bit if necessary */ + addr |= (i2c->msg->flags & I2C_M_RD) ? 1 : 0; - fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, addr); - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_START); + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, addr); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_START); - return 0; - } + return 0; + } - /* Second part of 10 bit addressing */ - if (i2c->state == STATE_ADDR10) { - fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, i2c->msg->addr & 0xff); - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); + /* Second part of 10 bit addressing */ + if (i2c->state == STATE_ADDR10) { + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, i2c->msg->addr & 0xff); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); - i2c->state = STATE_START; - return 0; - } + i2c->state = STATE_START; + return 0; + } - if (i2c->state == STATE_START || i2c->state == STATE_WRITE) { - i2c->state = (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; + if (i2c->state == STATE_START || i2c->state == STATE_WRITE) { + i2c->state = (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; - if (stat & FPGAI2C_REG_STAT_NACK) { - i2c->state = STATE_ERROR; - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); - return -ENXIO; - } - } else { - msg->buf[i2c->pos++] = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); - } - - if (i2c->pos >= msg->len) { - i2c->nmsgs--; - i2c->msg++; - i2c->pos = 0; - msg = i2c->msg; - - if (i2c->nmsgs) { - if (!(msg->flags & I2C_M_NOSTART)) { - i2c->state = STATE_ADDR; - return 0; - } else { - i2c->state = (msg->flags & I2C_M_RD) - ? STATE_READ : STATE_WRITE; - } - } else { - i2c->state = STATE_DONE; - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); - return 0; - } - } + if (stat & FPGAI2C_REG_STAT_NACK) { + i2c->state = STATE_ERROR; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return -ENXIO; + } + } else { + msg->buf[i2c->pos++] = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); + } + + if (i2c->pos >= msg->len) { + i2c->nmsgs--; + i2c->msg++; + i2c->pos = 0; + msg = i2c->msg; + + if (i2c->nmsgs) { + if (!(msg->flags & I2C_M_NOSTART)) { + i2c->state = STATE_ADDR; + return 0; + } else { + i2c->state = (msg->flags & I2C_M_RD) + ? STATE_READ : STATE_WRITE; + } + } else { + i2c->state = STATE_DONE; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return 0; + } + } - if (i2c->state == STATE_READ) { - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, i2c->pos == (msg->len - 1) ? - FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); - } else { - fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, msg->buf[i2c->pos++]); - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); - } + if (i2c->state == STATE_READ) { + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, i2c->pos == (msg->len - 1) ? + FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); + } else { + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, msg->buf[i2c->pos++]); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); + } - return 0; + return 0; } static ssize_t get_mod_msi(struct device *dev, struct device_attribute *devattr, char *buf) { int ind = 0, port_status=0, port_irq_status=0; - struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(dev); + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(dev); PRINT("%s:xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); for(ind=0;ind<64;ind++) { - port_status = ioread32(fpga_ctl_addr + PORT_STS_OFFSET + (ind*16)); - port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + port_status = ioread32(fpga_ctl_addr + PORT_STS_OFFSET + (ind*16)); + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); } return sprintf(buf,"0x%04x\n",fpgapci->xcvr_intr_count); @@ -532,31 +532,31 @@ static ssize_t get_mod_msi(struct device *dev, struct device_attribute *devattr, static DEVICE_ATTR(port_msi, S_IRUGO, get_mod_msi, NULL); static struct attribute *port_attrs[] = { - &dev_attr_port_msi.attr, - NULL, + &dev_attr_port_msi.attr, + NULL, }; static struct attribute_group port_attr_grp = { - .attrs = port_attrs, + .attrs = port_attrs, }; static irqreturn_t fpgaport_1_32_isr(int irq, void *dev) { struct pci_dev *pdev = dev; - struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); int ind = 0, port_status=0, port_irq_status=0; for(ind=0;ind<32;ind++) { - port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); if(port_irq_status&(IRQ_LTCH_STS|PRSNT_LTCH_STS)) { PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); - //write on clear - iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + //write on clear + iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); } } - fpgapci->xcvr_intr_count++; + fpgapci->xcvr_intr_count++; PRINT("%s: xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); sysfs_notify(&pdev->dev.kobj, NULL, "port_msi"); return IRQ_HANDLED; @@ -565,19 +565,18 @@ static irqreturn_t fpgaport_1_32_isr(int irq, void *dev) static irqreturn_t fpgaport_33_64_isr(int irq, void *dev) { struct pci_dev *pdev = dev; - struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); int ind = 0, port_status=0, port_irq_status=0; for(ind=32;ind<64;ind++) { - port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); if(port_irq_status| (IRQ_LTCH_STS|PRSNT_LTCH_STS)) { PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); - //write on clear - iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); } } - fpgapci->xcvr_intr_count++; + fpgapci->xcvr_intr_count++; PRINT("%s: xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); sysfs_notify(&pdev->dev.kobj, NULL, "port_msi"); return IRQ_HANDLED; @@ -590,10 +589,14 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) PRINT("fpgai2c_process in. status reg :0x%x\n", stat); - if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) { + if ((i2c->state == STATE_STOP) || (i2c->state == STATE_ERROR)) { /* stop has been sent */ - PRINT("fpgai2c_process FPGAI2C_REG_CMD_IACK stat = 0x%x Set FPGAI2C_REG_CMD(0%x) FPGAI2C_REG_CMD_IACK = 0x%x\n",stat, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + PRINT("fpgai2c_process FPGAI2C_REG_CMD_IACK stat = 0x%x Set FPGAI2C_REG_CMD(0%x) FPGAI2C_REG_CMD_IACK = 0x%x\n" \ + ,stat, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + if(i2c->state == STATE_STOP) { + i2c->state = STATE_DONE; + } wake_up(&i2c->wait); return; } @@ -628,7 +631,7 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) i2c->pos = 0; msg = i2c->msg; - if (i2c->nmsgs) { /* end? */ + if (i2c->nmsgs) { /* end? */ /* send start? */ if (!(msg->flags & I2C_M_NOSTART)) { @@ -647,7 +650,7 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) ? STATE_READ : STATE_WRITE; } } else { - i2c->state = STATE_DONE; + i2c->state = STATE_STOP; fpgai2c_stop(i2c); return; } @@ -655,9 +658,9 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) if (i2c->state == STATE_READ) { PRINT("fpgai2c_poll STATE_READ i2c->pos=%d msg->len-1 = 0x%x set FPGAI2C_REG_CMD = 0x%x\n",i2c->pos, msg->len-1, - i2c->pos == (msg->len-1) ? FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); + i2c->pos == (msg->len-1) ? FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, i2c->pos == (msg->len-1) ? - FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); + FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); } else { PRINT("fpgai2c_process set FPGAI2C_REG_DATA(0x%x)\n",FPGAI2C_REG_DATA); fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, msg->buf[i2c->pos++]); @@ -667,14 +670,14 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) static irqreturn_t fpgai2c_isr(int irq, void *dev_id) { - struct fpgalogic_i2c *i2c = dev_id; - fpgai2c_process(i2c); + struct fpgalogic_i2c *i2c = dev_id; + fpgai2c_process(i2c); - return IRQ_HANDLED; + return IRQ_HANDLED; } void dell_get_mutex(struct fpgalogic_i2c *i2c) { - mutex_lock(&i2c->lock); + mutex_lock(&i2c->lock); } /** @@ -682,7 +685,7 @@ void dell_get_mutex(struct fpgalogic_i2c *i2c) */ void dell_release_mutex(struct fpgalogic_i2c *i2c) { - mutex_unlock(&i2c->lock); + mutex_unlock(&i2c->lock); } static int fpgai2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) @@ -721,8 +724,9 @@ static int fpgai2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) } else { + ret = -ETIMEDOUT; PRINT("Set FPGAI2C_REG_DATA(0%x) val = 0x%x\n",FPGAI2C_REG_DATA, - (i2c->msg->addr << 1) | ((i2c->msg->flags & I2C_M_RD) ? 1:0)); + (i2c->msg->addr << 1) | ((i2c->msg->flags & I2C_M_RD) ? 1:0)); fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, (i2c->msg->addr << 1) | @@ -731,136 +735,135 @@ static int fpgai2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) /* Interrupt mode */ if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) || - (i2c->state == STATE_DONE), HZ)) - return (i2c->state == STATE_DONE) ? num : -EIO; - else - return -ETIMEDOUT; + (i2c->state == STATE_DONE), HZ)) + ret = (i2c->state == STATE_DONE) ? num : -EIO; + return ret; } } static int fpgai2c_init(struct fpgalogic_i2c *i2c) { - int prescale; - int diff; - u8 ctrl; - - if (i2c->reg_io_width == 0) - i2c->reg_io_width = 1; /* Set to default value */ - - if (!i2c->reg_set || !i2c->reg_get) { - bool be = 0; //1:big_endian 0:little_endian - - switch (i2c->reg_io_width) { - case 1: - i2c->reg_set = fpgai2c_reg_set_8; - i2c->reg_get = fpgai2c_reg_get_8; - break; - - case 2: - i2c->reg_set = be ? fpgai2c_reg_set_16be : fpgai2c_reg_set_16; - i2c->reg_get = be ? fpgai2c_reg_get_16be : fpgai2c_reg_get_16; - break; - - case 4: - i2c->reg_set = be ? fpgai2c_reg_set_32be : fpgai2c_reg_set_32; - i2c->reg_get = be ? fpgai2c_reg_get_32be : fpgai2c_reg_get_32; - break; - - default: - PRINT("Unsupported I/O width (%d)\n", - i2c->reg_io_width); - return -EINVAL; - } - } + int prescale; + int diff; + u8 ctrl; + + if (i2c->reg_io_width == 0) + i2c->reg_io_width = 1; /* Set to default value */ + + if (!i2c->reg_set || !i2c->reg_get) { + bool be = 0; //1:big_endian 0:little_endian + + switch (i2c->reg_io_width) { + case 1: + i2c->reg_set = fpgai2c_reg_set_8; + i2c->reg_get = fpgai2c_reg_get_8; + break; + + case 2: + i2c->reg_set = be ? fpgai2c_reg_set_16be : fpgai2c_reg_set_16; + i2c->reg_get = be ? fpgai2c_reg_get_16be : fpgai2c_reg_get_16; + break; + + case 4: + i2c->reg_set = be ? fpgai2c_reg_set_32be : fpgai2c_reg_set_32; + i2c->reg_get = be ? fpgai2c_reg_get_32be : fpgai2c_reg_get_32; + break; + + default: + PRINT("Unsupported I/O width (%d)\n", + i2c->reg_io_width); + return -EINVAL; + } + } - ctrl = fpgai2c_reg_get(i2c, FPGAI2C_REG_CONTROL); + ctrl = fpgai2c_reg_get(i2c, FPGAI2C_REG_CONTROL); - PRINT("%s(), line:%d\n", __func__, __LINE__); - PRINT("i2c->base = 0x%p\n",i2c->base); - - PRINT("ctrl = 0x%x\n",ctrl); - PRINT("set ctrl = 0x%x\n",ctrl & ~(FPGAI2C_REG_CTRL_EN|FPGAI2C_REG_CTRL_IEN)); - - /* make sure the device is disabled */ - fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl & ~(FPGAI2C_REG_CTRL_EN|FPGAI2C_REG_CTRL_IEN)); - - /* - * I2C Frequency depends on host clock - * input clock of 100MHz - * prescale to 100MHz / ( 5*100kHz) -1 = 199 = 0x4F 100000/(5*100)-1=199=0xc7 - */ - prescale = (i2c->ip_clock_khz / (5 * i2c->bus_clock_khz)) - 1; - prescale = clamp(prescale, 0, 0xffff); - - diff = i2c->ip_clock_khz / (5 * (prescale + 1)) - i2c->bus_clock_khz; - if (abs(diff) > i2c->bus_clock_khz / 10) { - PRINT("Unsupported clock settings: core: %d KHz, bus: %d KHz\n", - i2c->ip_clock_khz, i2c->bus_clock_khz); - return -EINVAL; - } + PRINT("%s(), line:%d\n", __func__, __LINE__); + PRINT("i2c->base = 0x%p\n",i2c->base); - fpgai2c_reg_set(i2c, FPGAI2C_REG_PRELOW, prescale & 0xff); - fpgai2c_reg_set(i2c, FPGAI2C_REG_PREHIGH, prescale >> 8); + PRINT("ctrl = 0x%x\n",ctrl); + PRINT("set ctrl = 0x%x\n",ctrl & ~(FPGAI2C_REG_CTRL_EN|FPGAI2C_REG_CTRL_IEN)); - /* Init the device */ - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); - if (!use_irq) - fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_EN); - else - fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_IEN | FPGAI2C_REG_CTRL_EN); + /* make sure the device is disabled */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl & ~(FPGAI2C_REG_CTRL_EN|FPGAI2C_REG_CTRL_IEN)); - fpgai2c_dump(i2c); + /* + * I2C Frequency depends on host clock + * input clock of 100MHz + * prescale to 100MHz / ( 5*100kHz) -1 = 199 = 0x4F 100000/(5*100)-1=199=0xc7 + */ + prescale = (i2c->ip_clock_khz / (5 * i2c->bus_clock_khz)) - 1; + prescale = clamp(prescale, 0, 0xffff); - /* Initialize interrupt handlers if not already done */ - init_waitqueue_head(&i2c->wait); + diff = i2c->ip_clock_khz / (5 * (prescale + 1)) - i2c->bus_clock_khz; + if (abs(diff) > i2c->bus_clock_khz / 10) { + PRINT("Unsupported clock settings: core: %d KHz, bus: %d KHz\n", + i2c->ip_clock_khz, i2c->bus_clock_khz); + return -EINVAL; + } - return 0; + fpgai2c_reg_set(i2c, FPGAI2C_REG_PRELOW, prescale & 0xff); + fpgai2c_reg_set(i2c, FPGAI2C_REG_PREHIGH, prescale >> 8); + + /* Init the device */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + if (!use_irq) + fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_EN); + else + fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_IEN | FPGAI2C_REG_CTRL_EN); + + fpgai2c_dump(i2c); + + /* Initialize interrupt handlers if not already done */ + init_waitqueue_head(&i2c->wait); + + return 0; } static u32 fpgai2c_func(struct i2c_adapter *adap) { - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; } static const struct i2c_algorithm fpgai2c_algorithm = { - .master_xfer = fpgai2c_xfer, - .functionality = fpgai2c_func, + .master_xfer = fpgai2c_xfer, + .functionality = fpgai2c_func, }; static int i2c_pci_add_bus (struct i2c_adapter *adap) { - int ret = 0; - /* Register new adapter */ - adap->algo = &fpgai2c_algorithm; - ret = i2c_add_numbered_adapter(adap); - return ret; + int ret = 0; + /* Register new adapter */ + adap->algo = &fpgai2c_algorithm; + ret = i2c_add_numbered_adapter(adap); + return ret; } static int i2c_init_internal_data(void) { - int i; + int i; PRINT("%s(), line:%d\n", __func__, __LINE__); - for( i = 0; i < total_i2c_pci_bus; i++ ) - { - fpgalogic_i2c[i].reg_shift = 0; /* 8 bit registers */ - fpgalogic_i2c[i].reg_io_width = 1; /* 8 bit read/write */ - fpgalogic_i2c[i].timeout = 500;//1000;//1ms - fpgalogic_i2c[i].ip_clock_khz = 100000;//100000;/* input clock of 100MHz */ - fpgalogic_i2c[i].bus_clock_khz = 100; - fpgalogic_i2c[i].base = fpga_base_addr + i*FPGALOGIC_CH_OFFSET; - mutex_init(&fpgalogic_i2c[i].lock); - fpgai2c_init(&fpgalogic_i2c[i]); - } - - return 0; + for( i = 0; i < total_i2c_pci_bus; i++ ) + { + fpgalogic_i2c[i].reg_shift = 0; /* 8 bit registers */ + fpgalogic_i2c[i].reg_io_width = 1; /* 8 bit read/write */ + fpgalogic_i2c[i].timeout = 500;//1000;//1ms + fpgalogic_i2c[i].ip_clock_khz = 100000;//100000;/* input clock of 100MHz */ + fpgalogic_i2c[i].bus_clock_khz = 100; + fpgalogic_i2c[i].base = fpga_base_addr + i*FPGALOGIC_CH_OFFSET; + mutex_init(&fpgalogic_i2c[i].lock); + fpgai2c_init(&fpgalogic_i2c[i]); + } + + return 0; } static int i2c_pci_init (void) { - int i; + int i; if (num_bus == 0) { board_rev_type = ioread32(fpga_ctl_addr + MB_BRD_REV_TYPE); @@ -868,8 +871,8 @@ static int i2c_pci_init (void) if ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_00) { num_bus = I2C_PCI_MAX_BUS_REV00; } else if (((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_01) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { switch (board_rev_type & MB_BRD_TYPE_MASK){ case BRD_TYPE_S5212_NON_NEBS: case BRD_TYPE_S5212_NEBS: @@ -907,46 +910,46 @@ static int i2c_pci_init (void) } } - printk("board_rev_type 0x%x, num_bus 0x%x\n", board_rev_type, num_bus); - total_i2c_pci_bus = num_bus; + printk("board_rev_type 0x%x, num_bus 0x%x\n", board_rev_type, num_bus); + total_i2c_pci_bus = num_bus; - memset (&i2c_pci_adap, 0, sizeof(i2c_pci_adap)); - memset (&fpgalogic_i2c, 0, sizeof(fpgalogic_i2c)); - for(i=0; i < i2c_bus_controller_numb; i++) - mutex_init(&i2c_xfer_lock[i]); + memset (&i2c_pci_adap, 0, sizeof(i2c_pci_adap)); + memset (&fpgalogic_i2c, 0, sizeof(fpgalogic_i2c)); + for(i=0; i < i2c_bus_controller_numb; i++) + mutex_init(&i2c_xfer_lock[i]); - /* Initialize driver's itnernal data structures */ - i2c_init_internal_data(); + /* Initialize driver's itnernal data structures */ + i2c_init_internal_data(); - for (i = 0 ; i < total_i2c_pci_bus; i ++) { + for (i = 0 ; i < total_i2c_pci_bus; i ++) { - i2c_pci_adap[i].owner = THIS_MODULE; - i2c_pci_adap[i].class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + i2c_pci_adap[i].owner = THIS_MODULE; + i2c_pci_adap[i].class = I2C_CLASS_HWMON | I2C_CLASS_SPD; - i2c_pci_adap[i].algo_data = &fpgalogic_i2c[i]; - /* /dev/i2c-600 ~ /dev/i2c-615 for FPGA LOGIC I2C channel controller 1-7 */ - i2c_pci_adap[i].nr = i+600; - sprintf( i2c_pci_adap[ i ].name, "i2c-pci-%d", i ); - /* Add the bus via the algorithm code */ - if( i2c_pci_add_bus( &i2c_pci_adap[ i ] ) != 0 ) - { - PRINT("Cannot add bus %d to algorithm layer\n", i ); - return( -ENODEV ); - } - i2c_set_adapdata(&i2c_pci_adap[i], &fpgalogic_i2c[i]); + i2c_pci_adap[i].algo_data = &fpgalogic_i2c[i]; + /* /dev/i2c-600 ~ /dev/i2c-615 for FPGA LOGIC I2C channel controller 1-7 */ + i2c_pci_adap[i].nr = i+600; + sprintf( i2c_pci_adap[ i ].name, "i2c-pci-%d", i ); + /* Add the bus via the algorithm code */ + if( i2c_pci_add_bus( &i2c_pci_adap[ i ] ) != 0 ) + { + PRINT("Cannot add bus %d to algorithm layer\n", i ); + return( -ENODEV ); + } + i2c_set_adapdata(&i2c_pci_adap[i], &fpgalogic_i2c[i]); - PRINT( "Registered bus id: %s\n", kobject_name(&i2c_pci_adap[ i ].dev.kobj)); - } + PRINT( "Registered bus id: %s\n", kobject_name(&i2c_pci_adap[ i ].dev.kobj)); + } - return 0; + return 0; } static void i2c_pci_deinit(void) { - int i; - for( i = 0; i < total_i2c_pci_bus; i++ ){ - i2c_del_adapter(&i2c_pci_adap[i]); - } + int i; + for( i = 0; i < total_i2c_pci_bus; i++ ){ + i2c_del_adapter(&i2c_pci_adap[i]); + } } @@ -954,61 +957,61 @@ static void i2c_pci_deinit(void) * Used for re-training and disabling AER. */ static struct pci_dev* find_upstream_dev (struct pci_dev *dev) { - struct pci_bus *bus = 0; - struct pci_dev *bridge = 0; - struct pci_dev *cur = 0; - int found_dev = 0; - - bus = dev->bus; - if (bus == 0) { - PRINT ( "Device doesn't have an associated bus!\n"); - return 0; - } - - bridge = bus->self; - if (bridge == 0) { - PRINT ( "Can't get the bridge for the bus!\n"); - return 0; - } - - PRINT ( "Upstream device %x/%x, bus:slot.func %02x:%02x.%02x\n", - bridge->vendor, bridge->device, - bridge->bus->number, PCI_SLOT(bridge->devfn), PCI_FUNC(bridge->devfn)); - - PRINT ( "List of downstream devices:"); - list_for_each_entry (cur, &bus->devices, bus_list) { - if (cur != 0) { - PRINT ( " %x/%x", cur->vendor, cur->device); - if (cur == dev) { - found_dev = 1; - } - } - } - PRINT ( "\n"); - if (found_dev) { - return bridge; - } else { - PRINT ( "Couldn't find upstream device!\n"); - return 0; - } + struct pci_bus *bus = 0; + struct pci_dev *bridge = 0; + struct pci_dev *cur = 0; + int found_dev = 0; + + bus = dev->bus; + if (bus == 0) { + PRINT ( "Device doesn't have an associated bus!\n"); + return 0; + } + + bridge = bus->self; + if (bridge == 0) { + PRINT ( "Can't get the bridge for the bus!\n"); + return 0; + } + + PRINT ( "Upstream device %x/%x, bus:slot.func %02x:%02x.%02x\n", + bridge->vendor, bridge->device, + bridge->bus->number, PCI_SLOT(bridge->devfn), PCI_FUNC(bridge->devfn)); + + PRINT ( "List of downstream devices:"); + list_for_each_entry (cur, &bus->devices, bus_list) { + if (cur != 0) { + PRINT ( " %x/%x", cur->vendor, cur->device); + if (cur == dev) { + found_dev = 1; + } + } + } + PRINT ( "\n"); + if (found_dev) { + return bridge; + } else { + PRINT ( "Couldn't find upstream device!\n"); + return 0; + } } static int scan_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) { - int i; - - for (i = 0; i < PCI_NUM_BARS; i++) { - unsigned long bar_start = pci_resource_start(dev, i); - if (bar_start) { - unsigned long bar_end = pci_resource_end(dev, i); - unsigned long bar_flags = pci_resource_flags(dev, i); - PRINT ( "BAR[%d] 0x%08lx-0x%08lx flags 0x%08lx", - i, bar_start, bar_end, bar_flags); - } - } + int i; + + for (i = 0; i < PCI_NUM_BARS; i++) { + unsigned long bar_start = pci_resource_start(dev, i); + if (bar_start) { + unsigned long bar_end = pci_resource_end(dev, i); + unsigned long bar_flags = pci_resource_flags(dev, i); + PRINT ( "BAR[%d] 0x%08lx-0x%08lx flags 0x%08lx", + i, bar_start, bar_end, bar_flags); + } + } - return 0; + return 0; } @@ -1019,64 +1022,64 @@ static int scan_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) */ static int map_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) { - int i; + int i; - for (i = 0; i < PCI_NUM_BARS; i++){ - phys_addr_t bar_start = pci_resource_start(dev, i); - phys_addr_t bar_end = pci_resource_end(dev, i); - unsigned long bar_length = bar_end - bar_start + 1; - fpgapci->bar_length[i] = bar_length; + for (i = 0; i < PCI_NUM_BARS; i++){ + phys_addr_t bar_start = pci_resource_start(dev, i); + phys_addr_t bar_end = pci_resource_end(dev, i); + unsigned long bar_length = bar_end - bar_start + 1; + fpgapci->bar_length[i] = bar_length; - if (!bar_start || !bar_end) { - fpgapci->bar_length[i] = 0; - continue; - } + if (!bar_start || !bar_end) { + fpgapci->bar_length[i] = 0; + continue; + } - if (bar_length < 1) { - PRINT ( "BAR #%d length is less than 1 byte\n", i); - continue; - } + if (bar_length < 1) { + PRINT ( "BAR #%d length is less than 1 byte\n", i); + continue; + } - PRINT ( "bar_start=%llx, bar_end=%llx, bar_length=%lx, flag=%lx\n", bar_start, - bar_end, bar_length, pci_resource_flags(dev, i)); + PRINT ( "bar_start=%llx, bar_end=%llx, bar_length=%lx, flag=%lx\n", bar_start, + bar_end, bar_length, pci_resource_flags(dev, i)); - /* map the device memory or IO region into kernel virtual - * address space */ - fpgapci->bar[i] = ioremap_nocache (bar_start + FPGALOGIC_I2C_BASE, I2C_PCI_MAX_BUS * FPGALOGIC_CH_OFFSET); + /* map the device memory or IO region into kernel virtual + * address space */ + fpgapci->bar[i] = ioremap_nocache (bar_start + FPGALOGIC_I2C_BASE, I2C_PCI_MAX_BUS * FPGALOGIC_CH_OFFSET); - if (!fpgapci->bar[i]) { - PRINT ( "Could not map BAR #%d.\n", i); - return -1; - } + if (!fpgapci->bar[i]) { + PRINT ( "Could not map BAR #%d.\n", i); + return -1; + } - PRINT ( "BAR[%d] mapped at 0x%p with length %lu.", i, - fpgapci->bar[i], bar_length); + PRINT ( "BAR[%d] mapped at 0x%p with length %lu.", i, + fpgapci->bar[i], bar_length); - if(i == 0) //FPGA register is in the BAR[0] - { + if(i == 0) //FPGA register is in the BAR[0] + { fpga_phys_addr = bar_start; fpga_ctl_addr = ioremap_nocache (bar_start, FPGA_CTL_REG_SIZE); fpga_base_addr = fpgapci->bar[i]; - } + } - PRINT ( "BAR[%d] mapped at 0x%p with length %lu.\n", i, - fpgapci->bar[i], bar_length); - } - return 0; + PRINT ( "BAR[%d] mapped at 0x%p with length %lu.\n", i, + fpgapci->bar[i], bar_length); + } + return 0; } static void free_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) { - int i; + int i; - for (i = 0; i < PCI_NUM_BARS; i++) { - if (fpgapci->bar[i]) { - pci_iounmap(dev, fpgapci->bar[i]); - fpgapci->bar[i] = NULL; - } - } + for (i = 0; i < PCI_NUM_BARS; i++) { + if (fpgapci->bar[i]) { + pci_iounmap(dev, fpgapci->bar[i]); + fpgapci->bar[i] = NULL; + } + } } #define FPGA_PCI_NAME "FPGA_PCI" @@ -1089,206 +1092,206 @@ static void free_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) * */ static int register_intr_handler(struct pci_dev *dev, int irq_num_id) { - int err = 0; - struct fpgapci_dev *fpgapci = 0; + int err = 0; + struct fpgapci_dev *fpgapci = 0; - fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&dev->dev); - if (fpgapci == 0) { - PRINT ( ": fpgapci_dev is 0\n"); - return err; - } + fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&dev->dev); + if (fpgapci == 0) { + PRINT ( ": fpgapci_dev is 0\n"); + return err; + } if ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_00) { - /* Request interrupt line for unique function - * alternatively function will be called from free_irq as well + /* Request interrupt line for unique function + * alternatively function will be called from free_irq as well * with flag IRQF_SHARED */ - switch(irq_num_id) { - /* Currently we only support test vector 2 for FPGA Logic I2C channel - * controller 1-7 interrupt*/ - case FPGA_MSI_VECTOR_ID_4: - err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, dev); - PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_5: - err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, dev); - PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_8: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[0]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_9: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[1]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_10: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[2]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_11: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[3]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_12: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[4]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_13: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[5]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_14: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[6]); - fpgapci->irq_assigned++; - break; - - default: - PRINT("No more interrupt handler for number (%d)\n", - dev->irq + irq_num_id); - break; - } + switch(irq_num_id) { + /* Currently we only support test vector 2 for FPGA Logic I2C channel + * controller 1-7 interrupt*/ + case FPGA_MSI_VECTOR_ID_4: + err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_5: + err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_8: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[0]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_9: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[1]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_10: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[2]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_11: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[3]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_12: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[4]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_13: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[5]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_14: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[6]); + fpgapci->irq_assigned++; + break; + + default: + PRINT("No more interrupt handler for number (%d)\n", + dev->irq + irq_num_id); + break; + } } else if (((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_01) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { - /* FPGA SPEC 4.3.1.34, First i2c channel mapped to vector 8 */ + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { + /* FPGA SPEC 4.3.1.34, First i2c channel mapped to vector 8 */ switch (irq_num_id) { - case FPGA_MSI_VECTOR_ID_4: - err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, dev); - PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_5: - err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, dev); - PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_8: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[0]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_9: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[1]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_10: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[2]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_11: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[3]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_12: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[4]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_13: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[5]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_14: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[6]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_15: - /*it is an external interrupt number. Ignore this case */ - break; - case FPGA_MSI_VECTOR_ID_16: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_7) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[7]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_17: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[8]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_18: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[9]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_19: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[10]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_20: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[11]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_21: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[12]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_22: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[13]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_23: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[14]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_24: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[15]); - fpgapci->irq_assigned++; - } - break; - - default: - PRINT("No more interrupt handler for number (%d)\n", - dev->irq + irq_num_id); - break; + case FPGA_MSI_VECTOR_ID_4: + err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_5: + err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_8: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[0]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_9: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[1]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_10: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[2]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_11: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[3]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_12: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[4]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_13: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[5]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_14: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[6]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_15: + /*it is an external interrupt number. Ignore this case */ + break; + case FPGA_MSI_VECTOR_ID_16: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_7) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[7]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_17: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[8]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_18: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[9]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_19: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[10]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_20: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[11]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_21: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[12]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_22: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[13]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_23: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[14]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_24: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[15]); + fpgapci->irq_assigned++; + } + break; + + default: + PRINT("No more interrupt handler for number (%d)\n", + dev->irq + irq_num_id); + break; } } - return err; + return err; } /* Mask for MSI Multi message enable bits */ #define MSI_MME 0x70 @@ -1348,33 +1351,33 @@ enum fpga_irq_type { #define CAP_REG 0x34 static void msi_set_enable(struct pci_dev *dev, int enable) { - int pos,maxvec; - u16 control; - int request_private_bits = 4; + int pos,maxvec; + u16 control; + int request_private_bits = 4; - pos = pci_find_capability(dev, PCI_CAP_ID_MSI); + pos = pci_find_capability(dev, PCI_CAP_ID_MSI); - if (pos) { - pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); - maxvec = 1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1); - PRINT("control = 0x%x maxvec = 0x%x\n", control, maxvec); - control &= ~PCI_MSI_FLAGS_ENABLE; + if (pos) { + pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); + maxvec = 1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1); + PRINT("control = 0x%x maxvec = 0x%x\n", control, maxvec); + control &= ~PCI_MSI_FLAGS_ENABLE; - /* - * The PCI 2.3 spec mandates that there are at most 32 - * interrupts. If this device asks for more, only give it one. - */ - if (request_private_bits > 5) { - request_private_bits = 0; - } + /* + * The PCI 2.3 spec mandates that there are at most 32 + * interrupts. If this device asks for more, only give it one. + */ + if (request_private_bits > 5) { + request_private_bits = 0; + } - /* Update the number of IRQs the device has available to it */ - control &= ~PCI_MSI_FLAGS_QSIZE; - control |= (request_private_bits << 4); + /* Update the number of IRQs the device has available to it */ + control &= ~PCI_MSI_FLAGS_QSIZE; + control |= (request_private_bits << 4); - pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); - } + pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); + } } /** * @brief Enables pcie-device and claims/remaps neccessary bar resources @@ -1383,211 +1386,212 @@ static void msi_set_enable(struct pci_dev *dev, int enable) * */ static int fpgapci_setup_device(struct fpgapci_dev *fpgapci,struct pci_dev *dev) { - int err = 0; + int err = 0; - /* wake up the pci device */ - err = pci_enable_device(dev); - if(err) { - PRINT("failed to enable pci device %d\n", err); - goto error_pci_en; - } + /* wake up the pci device */ + err = pci_enable_device(dev); + if(err) { + PRINT("failed to enable pci device %d\n", err); + goto error_pci_en; + } - /* on platforms with buggy ACPI, pdev->msi_enabled may be set to - * allow pci_enable_device to work. This indicates INTx was not routed - * and only MSI should be used - */ + /* on platforms with buggy ACPI, pdev->msi_enabled may be set to + * allow pci_enable_device to work. This indicates INTx was not routed + * and only MSI should be used + */ - pci_set_master(dev); + pci_set_master(dev); - /* Setup the BAR memory regions */ - err = pci_request_regions(dev, DRIVER_NAME); - if (err) { - PRINT("failed to enable pci device %d\n", err); - goto error_pci_req; - } + /* Setup the BAR memory regions */ + err = pci_request_regions(dev, DRIVER_NAME); + if (err) { + PRINT("failed to enable pci device %d\n", err); + goto error_pci_req; + } - scan_bars(fpgapci, dev); + scan_bars(fpgapci, dev); - if (map_bars(fpgapci, dev)) { - goto fail_map_bars; - } + if (map_bars(fpgapci, dev)) { + goto fail_map_bars; + } i2c_pci_init(); - return 0; - /* ERROR HANDLING */ + return 0; + /* ERROR HANDLING */ fail_map_bars: - pci_release_regions(dev); + pci_release_regions(dev); error_pci_req: - pci_disable_device(dev); + pci_disable_device(dev); error_pci_en: - return -ENODEV; + return -ENODEV; } static int fpgapci_configure_msi(struct fpgapci_dev *fpgapci,struct pci_dev *dev) { - int err = 0, i; - int request_vec; + int err = 0, i; + int request_vec; - msi_set_enable(dev,1); - PRINT("Check MSI capability after msi_set_enable\n"); + msi_set_enable(dev,1); + PRINT("Check MSI capability after msi_set_enable\n"); - /*Above 4.1.12*/ - request_vec = total_i2c_pci_bus; - err = pci_alloc_irq_vectors(dev, request_vec, pci_msi_vec_count(dev), - PCI_IRQ_MSI);//PCI_IRQ_AFFINITY | PCI_IRQ_MSI); + /*Above 4.1.12*/ + request_vec = total_i2c_pci_bus; + err = pci_alloc_irq_vectors(dev, request_vec, pci_msi_vec_count(dev), + PCI_IRQ_MSI);//PCI_IRQ_AFFINITY | PCI_IRQ_MSI); - if (err <= 0) { - PRINT("Cannot set MSI vector (%d)\n", err); - goto error_no_msi; - } else { - PRINT("Got %d MSI vectors starting at %d\n", err, dev->irq); + if (err <= 0) { + PRINT("Cannot set MSI vector (%d)\n", err); + goto error_no_msi; + } else { + PRINT("Got %d MSI vectors starting at %d\n", err, dev->irq); if ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_00) { if (err < MSI_VECTOR_REV_00) { goto error_disable_msi; } } else if (((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_01) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { if (err < MSI_VECTOR_REV_01) { goto error_disable_msi; } } - } - fpgapci->irq_first = dev->irq; - fpgapci->irq_length = err; - fpgapci->irq_assigned = 0; + } + fpgapci->irq_first = dev->irq; + fpgapci->irq_length = err; + fpgapci->irq_assigned = 0; - for(i = 0; i < fpgapci->irq_length; i++) { - err = register_intr_handler(dev, i); - if (err) { - PRINT("Cannot request Interrupt number %d\n", i); - goto error_pci_req_irq; - } - } + for(i = 0; i < fpgapci->irq_length; i++) { + err = register_intr_handler(dev, i); + if (err) { + PRINT("Cannot request Interrupt number %d\n", i); + goto error_pci_req_irq; + } + } - return 0; + return 0; error_pci_req_irq: - for(i = 0; i < fpgapci->irq_assigned; i++) - { - PRINT("free_irq %d i =%d\n",fpgapci->irq_first + i,i); + for(i = 0; i < fpgapci->irq_assigned; i++) + { + PRINT("free_irq %d i =%d\n",fpgapci->irq_first + i,i); if (i < 7) free_irq(fpgapci->irq_first + 8 + i, &fpgalogic_i2c[i]); else free_irq(fpgapci->irq_first + 8 + i + 1, &fpgalogic_i2c[i]); - } + } error_disable_msi: - pci_disable_msi(fpgapci->pci_dev); + pci_disable_msi(fpgapci->pci_dev); error_no_msi: - return -ENOSPC; + return -ENOSPC; } static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id) { - struct fpgapci_dev *fpgapci = 0; - int status = 0; + struct fpgapci_dev *fpgapci = 0; + int status = 0; #ifdef TEST - PRINT ( " vendor = 0x%x, device = 0x%x, class = 0x%x, bus:slot.func = %02x:%02x.%02x\n", - dev->vendor, dev->device, dev->class, - dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + PRINT ( " vendor = 0x%x, device = 0x%x, class = 0x%x, bus:slot.func = %02x:%02x.%02x\n", + dev->vendor, dev->device, dev->class, + dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); #endif - fpgapci = kzalloc(sizeof(struct fpgapci_dev), GFP_KERNEL); + fpgapci = kzalloc(sizeof(struct fpgapci_dev), GFP_KERNEL); - if (!fpgapci) { - PRINT( "Couldn't allocate memory!\n"); - goto fail_kzalloc; - } + if (!fpgapci) { + PRINT( "Couldn't allocate memory!\n"); + goto fail_kzalloc; + } - fpgapci->pci_dev = dev; - dev_set_drvdata(&dev->dev, (void*)fpgapci); + fpgapci->pci_dev = dev; + dev_set_drvdata(&dev->dev, (void*)fpgapci); - fpgapci->upstream = find_upstream_dev (dev); - status = sysfs_create_group(&dev->dev.kobj, &port_attr_grp); - if (status) { - printk(KERN_INFO "%s:Cannot create sysfs\n", __FUNCTION__); - } + status = sysfs_create_group(&dev->dev.kobj, &port_attr_grp); + if (status) { + printk(KERN_INFO "%s:Cannot create sysfs\n", __FUNCTION__); + } - if(fpgapci_setup_device(fpgapci,dev)) { - goto error_no_device; - } + fpgapci->upstream = find_upstream_dev (dev); - if (use_irq) { - if(fpgapci_configure_msi(fpgapci,dev)) { - goto error_cannot_configure; - } - } + if(fpgapci_setup_device(fpgapci,dev)) { + goto error_no_device; + } + if (use_irq) { + if(fpgapci_configure_msi(fpgapci,dev)) { + goto error_cannot_configure; + } + } - return 0; - /* ERROR HANDLING */ + + return 0; + /* ERROR HANDLING */ error_cannot_configure: - printk("error_cannot_configure\n"); - free_bars (fpgapci, dev); - pci_release_regions(dev); - pci_disable_device(dev); + printk("error_cannot_configure\n"); + free_bars (fpgapci, dev); + pci_release_regions(dev); + pci_disable_device(dev); error_no_device: - i2c_pci_deinit(); - printk("error_no_device\n"); + i2c_pci_deinit(); + printk("error_no_device\n"); fail_kzalloc: - return -1; + return -1; } static void fpgapci_remove(struct pci_dev *dev) { - struct fpgapci_dev *fpgapci = 0; - int i; - PRINT (": dev is %p\n", dev); - - if (dev == 0) { - PRINT ( ": dev is 0\n"); - return; - } - - fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&dev->dev); - if (fpgapci == 0) { - PRINT ( ": fpgapci_dev is 0\n"); - return; - } - i2c_pci_deinit(); - // - if (use_irq) - { - for(i = 0; i < fpgapci->irq_assigned; i++) - { - PRINT("free_irq %d i =%d\n",fpgapci->irq_first + i,i); + struct fpgapci_dev *fpgapci = 0; + int i; + PRINT (": dev is %p\n", dev); + + if (dev == 0) { + PRINT ( ": dev is 0\n"); + return; + } + + fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&dev->dev); + if (fpgapci == 0) { + PRINT ( ": fpgapci_dev is 0\n"); + return; + } + i2c_pci_deinit(); + // + if (use_irq) + { + for(i = 0; i < fpgapci->irq_assigned; i++) + { + PRINT("free_irq %d i =%d\n",fpgapci->irq_first + i,i); if (i < 7) - free_irq(fpgapci->irq_first + 8 + i, &fpgalogic_i2c[i]); + free_irq(fpgapci->irq_first + 8 + i, &fpgalogic_i2c[i]); else free_irq(fpgapci->irq_first + 8 + i + 1, &fpgalogic_i2c[i]); - } - } - pci_disable_msi(fpgapci->pci_dev); - free_bars (fpgapci, dev); - pci_disable_device(dev); - pci_release_regions(dev); + } + } + pci_disable_msi(fpgapci->pci_dev); + free_bars (fpgapci, dev); + pci_disable_device(dev); + pci_release_regions(dev); - kfree (fpgapci); + kfree (fpgapci); } static const struct pci_device_id fpgapci_ids[] = { - {PCI_DEVICE(PCI_VENDOR_ID_XILINX, DEVICE)}, - {0, }, + {PCI_DEVICE(PCI_VENDOR_ID_XILINX, DEVICE)}, + {0, }, }; MODULE_DEVICE_TABLE(pci, fpgapci_ids); static struct pci_driver fpgapci_driver = { - .name = DRIVER_NAME, - .id_table = fpgapci_ids, - .probe = fpgapci_probe, - .remove = fpgapci_remove, - /* resume, suspend are optional */ + .name = DRIVER_NAME, + .id_table = fpgapci_ids, + .probe = fpgapci_probe, + .remove = fpgapci_remove, + /* resume, suspend are optional */ }; /* Initialize the driver module (but not any device) and register @@ -1595,21 +1599,21 @@ static struct pci_driver fpgapci_driver = { static int __init fpgapci_init(void) { - if (pci_register_driver(&fpgapci_driver)) { - PRINT("pci_unregister_driver\n"); - pci_unregister_driver(&fpgapci_driver); - return -ENODEV; - } + if (pci_register_driver(&fpgapci_driver)) { + PRINT("pci_unregister_driver\n"); + pci_unregister_driver(&fpgapci_driver); + return -ENODEV; + } - return 0; + return 0; } static void __exit fpgapci_exit(void) { - PRINT ("fpgapci_exit"); + PRINT ("fpgapci_exit"); - /* unregister this driver from the PCI bus driver */ - pci_unregister_driver(&fpgapci_driver); + /* unregister this driver from the PCI bus driver */ + pci_unregister_driver(&fpgapci_driver); } @@ -1620,3 +1624,4 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("joyce_yu@dell.com"); MODULE_DESCRIPTION ("Driver for FPGA Logic I2C bus"); MODULE_SUPPORTED_DEVICE ("FPGA Logic I2C bus"); + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/platform_sensors.py index 3091d1c9ed44..039a34e5b69b 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/platform_sensors.py @@ -22,11 +22,15 @@ IPMI_SENSOR_DATA = "ipmitool sdr list" IPMI_SENSOR_DUMP = "/tmp/sdr" -FAN_PRESENCE = "FAN{0}_prsnt" PSU_PRESENCE = "PSU{0}_stat" # Use this for older firmware # PSU_PRESENCE="PSU{0}_prsnt" +IPMI_FAN_PRESENCE = "ipmitool sensor get FAN{0}_prsnt" +IPMI_PSU1_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x31 | awk '{print substr($0,9,1)}'" +IPMI_PSU2_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x32 | awk '{print substr($0,9,1)}'" +IPMI_RAW_STORAGE_READ = "ipmitool raw 0x0a 0x11 {0} 0 0 0xa0" +IPMI_FRU = "ipmitool fru" ipmi_sdr_list = "" # Dump sensor registers @@ -40,9 +44,18 @@ def ipmi_sensor_dump(): status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) if status: - logging.error('Failed to execute:' + ipmi_sdr_list) + logging.error('Failed to execute: ' + ipmi_sdr_list) sys.exit(0) +# Fetch a Fan Status + +def get_fan_status(fan_id): + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_FAN_PRESENCE.format(fan_id)) + if ret_status: + logging.error('Failed to execute : %s'%IPMI_FAN_PRESENCE.format(fan_id)) + sys.exit(0) + return(' ' + ipmi_cmd_ret.splitlines()[5].strip(' ').strip('[]')) + # Fetch a BMC register @@ -62,6 +75,35 @@ def get_pmc_register(reg_name): logging.basicConfig(level=logging.DEBUG) return output +#Fetch FRU Data for given fruid +def get_psu_airflow(psu_id): + fru_id = 'PSU' + str(psu_id) + '_fru' + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_FRU) + if ret_status: + logging.error('Failed to execute ipmitool: '+ IPMI_FRU) + sys.exit(0) + found_fru = False + for line in ipmi_cmd_ret.splitlines(): + if line.startswith('FRU Device Description') and fru_id in line.split(':')[1] : + found_fru = True + if found_fru and line.startswith(' Board Product '): + return ' B2F' if 'PS/IO' in line else ' F2B' + return '' + +# Fetch FRU on given offset +def fetch_raw_fru(dev_id, offset): + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_RAW_STORAGE_READ.format(dev_id)) + if ret_status: + logging.error('Failed to execute ipmitool :' + IPMI_RAW_STORAGE_READ.format(dev_id)) + sys.exit(0) + return int((ipmi_cmd_ret.splitlines()[offset/16]).split(' ')[(offset%16+1)]) + + + + +def get_fan_airflow(fan_id): + Airflow_Direction = [' F2B', ' B2F'] + return Airflow_Direction[fetch_raw_fru(fan_id+2, 0x46)] # Print the information for temperature sensors @@ -93,7 +135,6 @@ def print_temperature_sensors(): def print_fan_tray(tray): Fan_Status = [' Normal', ' Abnormal'] - Airflow_Direction = ['B2F', 'F2B'] print ' Fan Tray ' + str(tray) + ':' @@ -152,16 +193,62 @@ def print_fan_tray(tray): Fan_Status[fan1_status] print ' Fan2 State: ',\ Fan_Status[fan2_status] + print ' Airflow: ',\ + get_fan_airflow(tray) print('\nFan Trays:') for tray in range(1, S5232F_MAX_FAN_TRAYS + 1): - fan_presence = FAN_PRESENCE.format(tray) - if (get_pmc_register(fan_presence)): + if (get_fan_status(tray) == ' Present'): print_fan_tray(tray) else: - print '\n Fan Tray ' + str(tray + 1) + ': Not present' + print ' Fan Tray {}: NOT PRESENT'.format(str(tray)) + + def get_psu_presence(index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + ret_status = 1 + + if index == 1: + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + + if ret_status: + logging.error('Failed to execute ipmitool :' + IPMI_PSU1_DATA_DOCKER) + sys.exit(0) + + psu_status = ipmi_cmd_ret + return (int(psu_status, 16) & 1) + + def get_psu_status(index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + ret_status = 1 + ipmi_cmd_ret = 'f' + + if index == 1: + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + + if ret_status: + logging.error('Failed to execute ipmitool : ' + IPMI_PSU2_DATA_DOCKER) + sys.exit(0) + + psu_status = ipmi_cmd_ret + + return (not int(psu_status, 16) > 1) # Print the information for PSU1, PSU2 @@ -175,7 +262,6 @@ def print_psu(psu): PSU_FAN_AIR_FLOW_BIT = 0 Psu_Fan_Presence = ['Present', 'Absent'] Psu_Fan_Status = ['Normal', 'Abnormal'] - Psu_Fan_Airflow = ['B2F', 'F2B'] # print ' Input: ', Psu_Input_Type[psu_input_type] # print ' Type: ', Psu_Type[psu_type] @@ -233,15 +319,19 @@ def print_psu(psu): get_pmc_register('PSU2_In_amp') print ' Output Current: ',\ get_pmc_register('PSU2_Out_amp') + print ' Airflow: ',\ + get_psu_airflow(psu) print('\nPSUs:') for psu in range(1, S5232F_MAX_PSUS + 1): - psu_presence = PSU_PRESENCE.format(psu) - if (get_pmc_register(psu_presence)): - print_psu(psu) + #psu_presence = PSU_PRESENCE.format(psu) + if not get_psu_presence(psu): + print ' PSU{}: NOT PRESENT'.format(psu) + elif not get_psu_status(psu) : + print ' PSU{}: NOT OK'.format(psu) else: - print '\n PSU ', psu, 'Not present' + print_psu(psu) print '\n Total Power: ',\ get_pmc_register('PSU_Total_watt') diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh index 18e5ca2d5159..6f9282a604f2 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh @@ -91,6 +91,48 @@ switch_board_led_default() { resource="/sys/bus/pci/devices/0000:04:00.0/resource0" python /usr/bin/pcisysfs.py --set --offset 0x24 --val 0x194 --res $resource > /dev/null 2>&1 } + +# Readout firmware version of the system and +# store in /var/log/firmware_versions +platform_firmware_versions() { + FIRMWARE_VERSION_FILE=/var/log/firmware_versions + rm -rf ${FIRMWARE_VERSION_FILE} + echo "BIOS: `dmidecode -s system-version `" > $FIRMWARE_VERSION_FILE + ## Get FPGA version + r=`/usr/bin/pcisysfs.py --get --offset 0x00 --res /sys/bus/pci/devices/0000\:04\:00.0/resource0 | sed '1d; s/.*\(....\)$/\1/; s/\(..\{1\}\)/\1./'` + r_min=$(echo $r | sed 's/.*\(..\)$/0x\1/') + r_maj=$(echo $r | sed 's/^\(..\).*/0x\1/') + echo "FPGA: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + ## Get BMC Firmware Revision + r=`cat /sys/class/ipmi/ipmi0/device/bmc/firmware_revision` + echo "BMC: $r" >> $FIRMWARE_VERSION_FILE + + #System CPLD 0x31 on i2c bus 601 ( physical FPGA I2C-2) + r_min=`/usr/sbin/i2cget -y 601 0x31 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 601 0x31 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "System CPLD: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 1 0x30 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x30 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x30 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 1: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 2 0x31 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x31 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x31 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 2: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 3 0x32 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x32 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x32 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 3: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 3 0x32 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x33 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x33 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 4: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE +} init_devnum if [ "$1" == "init" ]; then @@ -106,10 +148,12 @@ if [ "$1" == "init" ]; then switch_board_modsel switch_board_led_default python /usr/bin/qsfp_irq_enable.py + platform_firmware_versions elif [ "$1" == "deinit" ]; then sys_eeprom "delete_device" switch_board_qsfp "delete_device" + switch_board_sfp "delete_device" switch_board_qsfp_mux "delete_device" modprobe -r i2c-mux-pca954x diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/fancontrol.sh b/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/fancontrol.sh new file mode 100755 index 000000000000..43315e06c930 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/fancontrol.sh @@ -0,0 +1,189 @@ +#!/bin/bash + +LEVEL=99 +INTERVAL=5 +FAULTY_FANTRAY1=1 +FAULTY_FANTRAY2=1 +FAULTY_FANTRAY3=1 + +# FAN RPM Speed +IDLE=7000 +LEVEL1=10000 +LEVEL2=13000 +LEVEL3=16000 +LEVEL4=19000 +LEVEL5=19000 + +I2C_ADAPTER="/sys/class/i2c-adapter/i2c-2/i2c-11" +SENSOR1="$I2C_ADAPTER/11-004c/hwmon/hwmon*/temp1_input" +SENSOR2="$I2C_ADAPTER/11-004d/hwmon/hwmon*/temp1_input" +SENSOR3="$I2C_ADAPTER/11-004e/hwmon/hwmon*/temp1_input" + +# Three fan trays with each contains two separate fans +# fan1-fan4 fan2-fan5 fan3-fan6 +FANTRAY1_FAN1=$I2C_ADAPTER/11-0029/fan1_target +FANTRAY1_FAN2=$I2C_ADAPTER/11-0029/fan2_target +FANTRAY2_FAN1=$I2C_ADAPTER/11-0029/fan3_target +FANTRAY2_FAN2=$I2C_ADAPTER/11-0029/fan4_target +FANTRAY3_FAN1=$I2C_ADAPTER/11-002a/fan1_target +FANTRAY3_FAN2=$I2C_ADAPTER/11-002a/fan2_target + +FANTRAY1_FAN1_RPM=$I2C_ADAPTER/11-0029/fan1_input +FANTRAY1_FAN2_RPM=$I2C_ADAPTER/11-0029/fan2_input +FANTRAY2_FAN1_RPM=$I2C_ADAPTER/11-0029/fan3_input +FANTRAY2_FAN2_RPM=$I2C_ADAPTER/11-0029/fan4_input +FANTRAY3_FAN1_RPM=$I2C_ADAPTER/11-002a/fan1_input +FANTRAY3_FAN2_RPM=$I2C_ADAPTER/11-002a/fan2_input + +function check_module +{ + MODULE=$1 + lsmod | grep "$MODULE" > /dev/null + ret=$? + if [[ $ret = "1" ]]; then + echo "$MODULE is not loaded!" + exit 1 + fi +} + +function check_faulty_fan +{ + + # Assume fans in FanTray spins less than 1000 RPM is faulty. + # To Maintain temperature assign max speed 16200 RPM to all other fans. + # This RPM speed handle temperature upto 75C degrees + + fan1=$(cat $FANTRAY1_FAN1_RPM) + fan2=$(cat $FANTRAY1_FAN2_RPM) + fan3=$(cat $FANTRAY2_FAN1_RPM) + fan4=$(cat $FANTRAY2_FAN2_RPM) + fan5=$(cat $FANTRAY3_FAN1_RPM) + fan6=$(cat $FANTRAY3_FAN2_RPM) + + # FanTray1 + if [ "$fan1" -le "1000" ] || [ "$fan2" -le "1000" ]; then + + # First time detecting failure + if [ $FAULTY_FANTRAY1 -lt "2" ]; then + FAULTY_FANTRAY1=2 + /usr/local/bin/set-fan-speed 16200 2 > /dev/null + logger "Faulty Fans in Fantray1 $fan1 $fan2 Please check." + fi + + elif [ "$fan1" -ge "1000" ] || [ "$fan2" -ge "1000" ]; then + FAULTY_FANTRAY1=0 + fi + + + # FanTray2 + if [ "$fan3" -le "1000" ] || [ "$fan4" -le "1000" ]; then + + # First time detecting failure + if [ $FAULTY_FANTRAY2 -lt "2" ]; then + + FAULTY_FANTRAY2=2 + /usr/local/bin/set-fan-speed 16200 2 > /dev/null + logger "Faulty Fans in FanTray2: $fan3 $fan4. Please check." + fi + + elif [ "$fan3" -ge "1000" ] || [ "$fan4" -ge "1000" ]; then + FAULTY_FANTRAY2=0 + fi + + # FanTray3 + if [ "$fan5" -le "1000" ] || [ "$fan6" -le "1000" ]; then + + # First time detecting failure + if [ $FAULTY_FANTRAY3 -lt "2" ]; then + + FAULTY_FANTRAY3=2 + /usr/local/bin/set-fan-speed 16200 2 > /dev/null + logger "FanTray3 Fans are Faulty.. $fan5 $fan6. Please check." + fi + + elif [ "$fan5" -ge "1000" ] || [ "$fan6" -ge "1000" ]; then + + FAULTY_FANTRAY3=0 + fi + +} + +function update_fan_speed +{ + local fan_speed=$1 + + echo $fan_speed > $FANTRAY1_FAN1 + echo $fan_speed > $FANTRAY1_FAN2 + echo $fan_speed > $FANTRAY2_FAN1 + echo $fan_speed > $FANTRAY2_FAN2 + echo $fan_speed > $FANTRAY3_FAN1 + echo $fan_speed > $FANTRAY3_FAN2 + +} + +function monitor_temp_sensors +{ + + while true # go through all temp sensor outputs + do + sensor1=$(expr `echo $(cat $SENSOR1)` / 1000) + sensor2=$(expr `echo $(cat $SENSOR2)` / 1000) + sensor3=$(expr `echo $(cat $SENSOR3)` / 1000) + sum=$(($sensor1 + $sensor2 + $sensor3)) + sensor_temp=$(($sum/3)) + + if [ "$sensor_temp" -le "25" ] && [ "$LEVEL" -ne "0" ] + then + # Set Fan Speed to 7000 RPM" + LEVEL=0 + update_fan_speed $IDLE + logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" + + elif [ "$sensor_temp" -ge "26" ] && [ "$sensor_temp" -le "44" ] && [ "$LEVEL" -ne "1" ] + then + # Set Fan Speed to 10000 RPM" + LEVEL=1 + update_fan_speed $LEVEL1 + logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" + + elif [ "$sensor_temp" -ge "45" ] && [ "$sensor_temp" -le "59" ] && [ "$LEVEL" -ne "2" ] + then + # Set Fan Speed to 13000 RPM" + LEVEL=2 + update_fan_speed $LEVEL2 + logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" + + elif [ "$sensor_temp" -ge "60" ] && [ "$sensor_temp" -le "79" ] && [ "$LEVEL" -ne "3" ] + then + # Set Fan Speed to 16000 RPM" + LEVEL=3 + update_fan_speed $LEVEL3 + logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" + + elif [ "$sensor_temp" -ge "80" ] && [ "$LEVEL" -ne "4" ] + then + # Set Fan Speed to 19000 RPM" + LEVEL=4 + update_fan_speed $LEVEL4 + logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" + fi + + # Check for faulty fan + check_faulty_fan + + done + +} + +# Check drivers for sysfs attributes +check_module "dell_s6000_platform" +check_module "max6620" + +# main loop calling the main function at specified intervals +while true +do + monitor_temp_sensors + # Sleep while still handling signals + sleep $INTERVAL & + wait +done diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py index 005fdd15b269..e94a7d1210f5 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py @@ -43,6 +43,7 @@ class Chassis(ChassisBase): reset_reason_dict[0x6] = ChassisBase.REBOOT_CAUSE_NON_HARDWARE def __init__(self): + ChassisBase.__init__(self) # Initialize SFP list self.PORT_START = 0 self.PORT_END = 31 @@ -65,7 +66,7 @@ def __init__(self): # Get Transceiver status self.modprs_register = self._get_transceiver_status() - self.sys_eeprom = Eeprom() + self._eeprom = Eeprom() for i in range(MAX_S6000_FAN): fan = Fan(i) self._fan_list.append(fan) @@ -105,7 +106,7 @@ def get_name(self): Returns: string: The name of the chassis """ - return self.sys_eeprom.modelstr() + return self._eeprom.modelstr() def get_presence(self): """ @@ -121,7 +122,7 @@ def get_model(self): Returns: string: Model/part number of chassis """ - return self.sys_eeprom.part_number_str() + return self._eeprom.part_number_str() def get_serial(self): """ @@ -129,7 +130,7 @@ def get_serial(self): Returns: string: Serial number of chassis """ - return self.sys_eeprom.serial_str() + return self._eeprom.serial_str() def get_status(self): """ @@ -148,7 +149,7 @@ def get_base_mac(self): A string containing the MAC address in the format 'XX:XX:XX:XX:XX:XX' """ - return self.sys_eeprom.base_mac_addr() + return self._eeprom.base_mac_addr() def get_serial_number(self): """ @@ -158,7 +159,7 @@ def get_serial_number(self): A string containing the hardware serial number for this chassis. """ - return self.sys_eeprom.serial_number_str() + return self._eeprom.serial_number_str() def get_system_eeprom_info(self): """ @@ -170,7 +171,7 @@ def get_system_eeprom_info(self): OCP ONIE TlvInfo EEPROM format and values are their corresponding values. """ - return self.sys_eeprom.system_eeprom_info() + return self._eeprom.system_eeprom_info() def get_reboot_cause(self): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py index 3d824ba28268..a82fd6a70201 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py @@ -28,14 +28,15 @@ psu_eeprom_format = [ ('PPID', 's', 20), ('DPN Rev', 's', 3), ('Service Tag', 's', 7), ('Part Number', 's', 10), ('Part Num Revision', 's', 3), - ('Mfg Test', 's', 2), ('PSU Type', 's', 1), ('Fab Rev', 's', 2) + ('Mfg Test', 's', 2), ('Redundant copy', 's', 83), ('PSU Type', 's', 1), + ('Fab Rev', 's', 2) ] # Fan eeprom fields in format required by EepromDecoder fan_eeprom_format = [ ('PPID', 's', 20), ('DPN Rev', 's', 3), ('Service Tag', 's', 7), ('Part Number', 's', 10), ('Part Num Revision', 's', 3), - ('Mfg Test', 's', 2), ('Redundant copy', 's', 82), + ('Mfg Test', 's', 2), ('Redundant copy', 's', 83), ('Number of Fans', 's', 1), ('Fan Type', 's', 1), ('Fab Rev', 's', 2) ] @@ -149,6 +150,10 @@ def _load_device_eeprom(self): except: self.serial_number = 'NA' self.part_number = 'NA' + if self.is_psu_eeprom: + self.psu_type = 'NA' + else: + self.fan_type = 'NA' else: (valid, data) = self._get_eeprom_field("PPID") if valid: @@ -168,11 +173,18 @@ def _load_device_eeprom(self): else: self.part_number = 'NA' - (valid, data) = self._get_eeprom_field("Fan Type") - if valid: - self.fan_type = data + if self.is_psu_eeprom: + (valid, data) = self._get_eeprom_field("PSU Type") + if valid: + self.psu_type = data + else: + self.psu_type = 'NA' else: - self.fan_type = 'NA' + (valid, data) = self._get_eeprom_field("Fan Type") + if valid: + self.fan_type = data + else: + self.fan_type = 'NA' def _get_eeprom_field(self, field_name): """ @@ -204,7 +216,10 @@ def airflow_fan_type(self): """ Returns the airflow fan type. """ - return int(self.fan_type.encode('hex'), 16) + if self.is_psu_eeprom: + return int(self.psu_type.encode('hex'), 16) + else: + return int(self.fan_type.encode('hex'), 16) # System EEPROM specific methods def base_mac_addr(self): diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py index 3350b4818401..92f83c8fbc79 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py @@ -11,12 +11,14 @@ try: import os + import glob 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_PSU_FAN_SPEED = 18000 MAX_S6000_FAN_SPEED = 19000 @@ -26,12 +28,13 @@ class Fan(FanBase): CPLD_DIR = "/sys/devices/platform/dell-s6000-cpld.0/" I2C_DIR = "/sys/class/i2c-adapter/" - def __init__(self, fan_index, psu_fan=False): - # Fan is 1-based in DellEMC platforms - self.index = fan_index + 1 + def __init__(self, fan_index, psu_fan=False, dependency=None): self.is_psu_fan = psu_fan + self.is_driver_initialized = True if not self.is_psu_fan: + # Fan is 1-based in DellEMC platforms + self.index = fan_index + 1 self.fan_presence_reg = "fan_prs" self.fan_led_reg = "fan{}_led".format(fan_index) self.get_fan_speed_reg = self.I2C_DIR + "i2c-11/11-0029/" +\ @@ -42,8 +45,21 @@ def __init__(self, fan_index, psu_fan=False): self.max_fan_speed = MAX_S6000_FAN_SPEED self.supported_led_color = ['off', 'green', 'amber'] else: - self.get_fan_speed_reg = self.I2C_DIR + "i2c-1/1-005{}/" +\ - "fan1_input".format(10 - self.index) + self.index = fan_index + self.dependency = dependency + self.set_fan_speed_reg = self.I2C_DIR +\ + "i2c-1/1-005{}/fan1_target".format(10 - self.index) + + hwmon_dir = self.I2C_DIR +\ + "i2c-1/1-005{}/hwmon/".format(10 - self.index) + try: + hwmon_node = os.listdir(hwmon_dir)[0] + except OSError: + hwmon_node = "hwmon*" + self.is_driver_initialized = False + + self.get_fan_speed_reg = hwmon_dir + hwmon_node + '/fan1_input' + self.max_fan_speed = MAX_S6000_PSU_FAN_SPEED def _get_cpld_register(self, reg_name): # On successful read, returns the value read from given @@ -87,6 +103,14 @@ def _get_i2c_register(self, reg_file): # reg_name and on failure returns 'ERR' rv = 'ERR' + if not self.is_driver_initialized: + reg_file_path = glob.glob(reg_file) + if len(reg_file_path): + reg_file = reg_file_path[0] + self._get_sysfs_path() + else: + return rv + if (not os.path.isfile(reg_file)): return rv @@ -116,6 +140,13 @@ def _set_i2c_register(self, reg_file, value): return rv + def _get_sysfs_path(self): + fan_speed_reg = glob.glob(self.get_fan_speed_reg) + + if len(fan_speed_reg): + self.get_fan_speed_reg = fan_speed_reg[0] + self.is_driver_initialized = True + def get_name(self): """ Retrieves the name of the Fan @@ -136,6 +167,9 @@ def get_presence(self): bool: True if Fan is present, False if not """ status = False + if self.is_psu_fan: + return self.dependency.get_presence() + fan_presence = self._get_cpld_register(self.fan_presence_reg) if (fan_presence != 'ERR'): fan_presence = int(fan_presence,16) & self.index @@ -151,7 +185,10 @@ def get_model(self): Returns: string: Part number of Fan """ - return self.eeprom.part_number_str() + if not self.is_psu_fan: + return self.eeprom.part_number_str() + else: + return 'NA' def get_serial(self): """ @@ -161,7 +198,10 @@ def get_serial(self): string: Serial number of Fan """ # Sample Serial number format "US-01234D-54321-25A-0123-A00" - return self.eeprom.serial_number_str() + if not self.is_psu_fan: + return self.eeprom.serial_number_str() + else: + return 'NA' def get_status(self): """ @@ -185,11 +225,21 @@ def get_direction(self): Returns: A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction + + Notes: + In DellEMC platforms, + - Forward/Exhaust : Air flows from Port side to Fan side. + - Reverse/Intake : Air flows from Fan side to Port side. """ - direction = {1: 'FAN_DIRECTION_INTAKE', 2: 'FAN_DIRECTION_EXHAUST'} - fan_direction = self.eeprom.airflow_fan_type() + if self.is_psu_fan: + direction = {1: self.FAN_DIRECTION_EXHAUST, 2: self.FAN_DIRECTION_INTAKE, + 3: self.FAN_DIRECTION_EXHAUST, 4: self.FAN_DIRECTION_INTAKE} + fan_direction = self.dependency.eeprom.airflow_fan_type() + else: + direction = {1: self.FAN_DIRECTION_EXHAUST, 2: self.FAN_DIRECTION_INTAKE} + fan_direction = self.eeprom.airflow_fan_type() - return direction.get(fan_direction,'NA') + return direction.get(fan_direction, self.FAN_DIRECTION_NOT_APPLICABLE) def get_speed(self): """ @@ -248,7 +298,7 @@ def set_status_led(self, color): Returns: bool: True if set success, False if fail. """ - if color not in self.supported_led_color: + if self.is_psu_fan or (color not in self.supported_led_color): return False if(color == self.STATUS_LED_COLOR_AMBER): color = 'yellow' @@ -266,6 +316,10 @@ def get_status_led(self): Returns: A string, one of the predefined STATUS_LED_COLOR_* strings. """ + if self.is_psu_fan: + # No LED available for PSU Fan + return None + fan_led = self._get_cpld_register(self.fan_led_reg) if (fan_led != 'ERR'): if (fan_led == 'yellow'): diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py index dfbd2a87eb5d..24200f1c7d39 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py @@ -11,8 +11,10 @@ try: import os + import glob from sonic_platform_base.psu_base import PsuBase from sonic_platform.eeprom import Eeprom + from sonic_platform.fan import Fan except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -28,12 +30,20 @@ def __init__(self, psu_index): self.index = psu_index + 1 self.psu_presence_reg = "psu{}_prs".format(psu_index) self.psu_status_reg = "powersupply_status" + self.is_driver_initialized = False if self.index == 1: ltc_dir = self.I2C_DIR + "i2c-11/11-0042/hwmon/" else: ltc_dir = self.I2C_DIR + "i2c-11/11-0040/hwmon/" - hwmon_node = os.listdir(ltc_dir)[0] + + try: + hwmon_node = os.listdir(ltc_dir)[0] + except OSError: + hwmon_node = "hwmon*" + else: + self.is_driver_initialized = True + self.HWMON_DIR = ltc_dir + hwmon_node + '/' self.psu_voltage_reg = self.HWMON_DIR + "in1_input" @@ -46,6 +56,8 @@ def __init__(self, psu_index): # make it unique per Psu object self._fan_list = [] + self._fan_list.append(Fan(self.index, psu_fan=True, dependency=self)) + def _get_cpld_register(self, reg_name): # On successful read, returns the value read from given # reg_name and on failure returns 'ERR' @@ -70,6 +82,14 @@ def _get_i2c_register(self, reg_file): # reg_name and on failure returns 'ERR' rv = 'ERR' + if not self.is_driver_initialized: + reg_file_path = glob.glob(reg_file) + if len(reg_file_path): + reg_file = reg_file_path[0] + self._get_sysfs_path() + else: + return rv + if (not os.path.isfile(reg_file)): return rv @@ -83,6 +103,17 @@ def _get_i2c_register(self, reg_file): rv = rv.lstrip(" ") return rv + def _get_sysfs_path(self): + voltage_reg = glob.glob(self.psu_voltage_reg) + current_reg = glob.glob(self.psu_current_reg) + power_reg = glob.glob(self.psu_power_reg) + + if len(voltage_reg) and len(current_reg) and len(power_reg): + self.psu_voltage_reg = voltage_reg_path[0] + self.psu_current_reg = current_reg_path[0] + self.psu_power_reg = power_reg_path[0] + self.is_driver_initialized = True + def get_name(self): """ Retrieves the name of the device diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py index 70bac0c729d2..a54336d40f1c 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py @@ -11,6 +11,7 @@ try: import os + import glob from sonic_platform_base.thermal_base import ThermalBase from sonic_platform.psu import Psu except ImportError as e: @@ -36,13 +37,19 @@ class Thermal(ThermalBase): def __init__(self, thermal_index): self.index = thermal_index + 1 self.is_psu_thermal = False + self.is_driver_initialized = True self.dependency = None if self.index < 9: i2c_path = self.I2C_DIR + self.I2C_DEV_MAPPING[self.index - 1][0] hwmon_temp_index = self.I2C_DEV_MAPPING[self.index - 1][1] hwmon_temp_suffix = "max" - hwmon_node = os.listdir(i2c_path)[0] + try: + hwmon_node = os.listdir(i2c_path)[0] + except OSError: + hwmon_node = "hwmon*" + self.is_driver_initialized = False + self.HWMON_DIR = i2c_path + hwmon_node + '/' if self.index == 4: @@ -55,7 +62,12 @@ def __init__(self, thermal_index): dev_path = "/sys/devices/platform/coretemp.0/hwmon/" hwmon_temp_index = self.index - 7 hwmon_temp_suffix = "crit" - hwmon_node = os.listdir(dev_path)[0] + try: + hwmon_node = os.listdir(dev_path)[0] + except OSError: + hwmon_node = "hwmon*" + self.is_driver_initialized = False + self.HWMON_DIR = dev_path + hwmon_node + '/' self.thermal_temperature_file = self.HWMON_DIR \ @@ -70,6 +82,14 @@ def _read_sysfs_file(self, sysfs_file): # sysfs_file and on failure returns 'ERR' rv = 'ERR' + if not self.is_driver_initialized: + sysfs_file_path = glob.glob(sysfs_file) + if len(sysfs_file_path): + sysfs_file = sysfs_file_path[0] + self._get_sysfs_path() + else: + return rv + if (not os.path.isfile(sysfs_file)): return rv @@ -83,6 +103,19 @@ def _read_sysfs_file(self, sysfs_file): rv = rv.lstrip(" ") return rv + def _get_sysfs_path(self): + temperature_path = glob.glob(self.thermal_temperature_file) + high_threshold_path = glob.glob(self.thermal_high_threshold_file) + low_threshold_path = glob.glob(self.thermal_low_threshold_file) + + if len(temperature_path) and len(high_threshold_path): + self.thermal_temperature_file = temperature_path[0] + self.thermal_high_threshold_file = high_threshold_path[0] + if len(low_threshold_path): + self.thermal_low_threshold_file = low_threshold_path + + self.is_driver_initialized = True + def get_name(self): """ Retrieves the name of the thermal diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/systemd/fancontrol.service b/platform/broadcom/sonic-platform-modules-dell/s6000/systemd/fancontrol.service new file mode 100644 index 000000000000..75cc977b9935 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/systemd/fancontrol.service @@ -0,0 +1,13 @@ +[Unit] +Description=Dell S6000 fan speed regulator +After=platform-modules-s6000.service +Before=pmon.service + +[Service] +ExecStart=-/usr/local/bin/fancontrol.sh +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target + diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_sensors.py index a0231bc507cf..b94b69388300 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_sensors.py @@ -255,8 +255,8 @@ def print_psu(psu): psu_fan_present = int(get_pmc_register('fan11_fault')) input_voltage = float(get_pmc_register('in29_input')) / 1000 output_voltage = float(get_pmc_register('in30_input')) / 1000 - input_current = float(get_pmc_register('curr601_input')) / 100 - output_current = float(get_pmc_register('curr602_input')) / 100 + input_current = float(get_pmc_register('curr601_input')) / 1000 + output_current = float(get_pmc_register('curr602_input')) / 1000 input_power = float(get_pmc_register('power1_input')) / 1000000 output_power = float(get_pmc_register('power2_input')) / 1000000 if (input_power != 0): @@ -268,8 +268,8 @@ def print_psu(psu): psu_fan_present = int(get_pmc_register('fan12_fault')) input_voltage = float(get_pmc_register('in31_input')) / 1000 output_voltage = float(get_pmc_register('in32_input')) / 1000 - input_current = float(get_pmc_register('curr701_input')) / 100 - output_current = float(get_pmc_register('curr702_input')) / 100 + input_current = float(get_pmc_register('curr701_input')) / 1000 + output_current = float(get_pmc_register('curr702_input')) / 1000 input_power = float(get_pmc_register('power3_input')) / 1000000 output_power = float(get_pmc_register('power4_input')) / 1000000 if (input_power != 0): diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh index d8b13ca02c1e..8533d9a198e2 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh @@ -54,6 +54,26 @@ sys_eeprom() { esac } +#Attach/Detach eeprom on each IOM +switch_board_eeprom() { + case $1 in + "new_device") + for ((i=14;i<=17;i++)); + do + i2c_config "echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + "delete_device") + for ((i=14;i<=17;i++)); + do + i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + *) echo "s6100_platform: switch_board_eeprom : invalid command !" + ;; + esac +} + #Attach/Detach CPLD devices to drivers for each IOM switch_board_cpld() { case $1 in @@ -245,7 +265,7 @@ install_python_api_package() { remove_python_api_package() { rv=$(pip show sonic-platform > /dev/null 2>/dev/null) if [ $? -eq 0 ]; then - rv = $(pip uninstall -y sonic-platform > /dev/null 2>/dev/null) + rv=$(pip uninstall -y sonic-platform > /dev/null 2>/dev/null) fi } @@ -267,6 +287,7 @@ if [[ "$1" == "init" ]]; then cpu_board_mux "new_device" switch_board_mux "new_device" sys_eeprom "new_device" + switch_board_eeprom "new_device" switch_board_cpld "new_device" switch_board_qsfp_mux "new_device" switch_board_sfp "new_device" @@ -280,6 +301,7 @@ elif [[ "$1" == "deinit" ]]; then xcvr_presence_interrupts "disable" switch_board_sfp "delete_device" switch_board_cpld "delete_device" + switch_board_eeprom "delete_device" switch_board_mux "delete_device" sys_eeprom "delete_device" switch_board_qsfp "delete_device" diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py index e39e8480e2c7..ec1848fc8dca 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py @@ -54,10 +54,11 @@ def __init__(self): ChassisBase.__init__(self) # Initialize EEPROM - self.sys_eeprom = Eeprom() + self._eeprom = Eeprom() for i in range(MAX_S6100_MODULE): module = Module(i) self._module_list.append(module) + self._sfp_list.extend(module._sfp_list) for i in range(MAX_S6100_FAN): fan = Fan(i) @@ -107,7 +108,7 @@ def get_name(self): Returns: string: The name of the chassis """ - return self.sys_eeprom.modelstr() + return self._eeprom.modelstr() def get_presence(self): """ @@ -123,7 +124,7 @@ def get_model(self): Returns: string: Model/part number of chassis """ - return self.sys_eeprom.part_number_str() + return self._eeprom.part_number_str() def get_serial(self): """ @@ -131,7 +132,7 @@ def get_serial(self): Returns: string: Serial number of chassis """ - return self.sys_eeprom.serial_str() + return self._eeprom.serial_str() def get_status(self): """ @@ -150,7 +151,7 @@ def get_base_mac(self): A string containing the MAC address in the format 'XX:XX:XX:XX:XX:XX' """ - return self.sys_eeprom.base_mac_addr() + return self._eeprom.base_mac_addr() def get_serial_number(self): """ @@ -160,7 +161,7 @@ def get_serial_number(self): A string containing the hardware serial number for this chassis. """ - return self.sys_eeprom.serial_number_str() + return self._eeprom.serial_number_str() def get_system_eeprom_info(self): """ @@ -170,7 +171,7 @@ def get_system_eeprom_info(self): OCP ONIE TlvInfo EEPROM format and values are their corresponding values. """ - return self.sys_eeprom.system_eeprom_info() + return self._eeprom.system_eeprom_info() def get_reboot_cause(self): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py index 4e683e1e511b..8bd900b6c26b 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py @@ -18,15 +18,26 @@ class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): - def __init__(self): - self.eeprom_path = "/sys/class/i2c-adapter/i2c-2/2-0050/eeprom" + def __init__(self, i2c_line=0, iom_eeprom=False): + self.is_module = iom_eeprom + if self.is_module: + self.eeprom_path = ("/sys/class/i2c-adapter" + "/i2c-{0}/{0}-0050/eeprom").format(i2c_line) + else: + self.eeprom_path = "/sys/class/i2c-adapter/i2c-2/2-0050/eeprom" super(Eeprom, self).__init__(self.eeprom_path, 0, '', True) self.eeprom_tlv_dict = dict() + try: - self.eeprom_data = self.read_eeprom() + if self.is_module: + self.write_eeprom("\x00\x00") + self.eeprom_data = self.read_eeprom_bytes(256) + else: + self.eeprom_data = self.read_eeprom() except: self.eeprom_data = "N/A" - raise RuntimeError("Eeprom is not Programmed") + if not self.is_module: + raise RuntimeError("Eeprom is not Programmed") else: eeprom = self.eeprom_data @@ -76,8 +87,12 @@ def base_mac_addr(self): return ":".join([binascii.b2a_hex(T) for T in results[2]]) def modelstr(self): - (is_valid, results) = self.get_tlv_field( - self.eeprom_data, self._TLV_CODE_PRODUCT_NAME) + if self.is_module: + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_PLATFORM_NAME) + else: + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_PRODUCT_NAME) if not is_valid: return "N/A" diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py index 2aef71b756e7..49e95357b6f1 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py @@ -33,6 +33,10 @@ def __init__(self, fantray_index=1, fan_index=1, psu_fan=False): # from 1 self.fantrayindex = fantray_index + 1 self.fanindex = fan_index + 1 + self.fan_presence_reg = "fan{}_fault".format( + 2 * self.fantrayindex - 1) + self.fan_status_reg = "fan{}_alarm".format( + 2 * self.fantrayindex - 1) self.get_fan_speed_reg = "fan{}_input".format( 2 * self.fantrayindex - 1) self.get_fan_dir_reg = "fan{}_airflow".format( @@ -43,7 +47,9 @@ def __init__(self, fantray_index=1, fan_index=1, psu_fan=False): else: # PSU Fan index starts from 11 self.fanindex = fan_index + 10 + self.fan_presence_reg = "fan{}_fault".format(self.fanindex) self.get_fan_speed_reg = "fan{}_input".format(self.fanindex) + self.get_fan_dir_reg = "fan{}_airflow".format(self.fanindex) self.max_fan_speed = MAX_S6100_PSU_FAN_SPEED def _get_pmc_register(self, reg_name): @@ -84,6 +90,9 @@ def get_model(self): """ # For Serial number "US-01234D-54321-25A-0123-A00", the part # number is "01234D" + if self.is_psu_fan: + return 'NA' + fan_serialno = self._get_pmc_register(self.fan_serialno_reg) if (fan_serialno != 'ERR') and self.get_presence(): if (len(fan_serialno.split('-')) > 1): @@ -102,6 +111,9 @@ def get_serial(self): string: Serial number of FAN """ # Sample Serial number format "US-01234D-54321-25A-0123-A00" + if self.is_psu_fan: + return 'NA' + fan_serialno = self._get_pmc_register(self.fan_serialno_reg) if (fan_serialno == 'ERR') or not self.get_presence(): fan_serialno = 'NA' @@ -115,11 +127,11 @@ def get_presence(self): bool: True if fan is present, False if not """ status = False - fantray_presence = self._get_pmc_register(self.get_fan_speed_reg) + fantray_presence = self._get_pmc_register(self.fan_presence_reg) if (fantray_presence != 'ERR'): fantray_presence = int(fantray_presence, 10) - if (fantray_presence > 0): - status = True + if (~fantray_presence & 0b1): + status = True return status @@ -130,11 +142,18 @@ def get_status(self): bool: True if FAN is operating properly, False if not """ status = False - fantray_status = self._get_pmc_register(self.get_fan_speed_reg) - if (fantray_status != 'ERR'): - fantray_status = int(fantray_status, 10) - if (fantray_status > 5000): - status = True + if self.is_psu_fan: + fantray_status = self._get_pmc_register(self.get_fan_speed_reg) + if (fantray_status != 'ERR'): + fantray_status = int(fantray_status, 10) + if (fantray_status > 1000): + status = True + else: + fantray_status = self._get_pmc_register(self.fan_status_reg) + if (fantray_status != 'ERR'): + fantray_status = int(fantray_status, 10) + if (~fantray_status & 0b1): + status = True return status @@ -144,13 +163,18 @@ def get_direction(self): Returns: A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction + + Notes: + In DellEMC platforms, + - Forward/Exhaust : Air flows from Port side to Fan side. + - Reverse/Intake : Air flows from Fan side to Port side. """ - direction = ['FAN_DIRECTION_INTAKE', 'FAN_DIRECTION_EXHAUST'] + direction = [self.FAN_DIRECTION_INTAKE, self.FAN_DIRECTION_EXHAUST] fan_direction = self._get_pmc_register(self.get_fan_dir_reg) if (fan_direction != 'ERR') and self.get_presence(): fan_direction = int(fan_direction, 10) else: - return 'N/A' + return self.FAN_DIRECTION_NOT_APPLICABLE return direction[fan_direction] def get_speed(self): @@ -216,10 +240,17 @@ def get_status_led(self): Returns: A string, one of the predefined STATUS_LED_COLOR_* strings. """ - if self.get_status(): - return self.STATUS_LED_COLOR_GREEN + if self.is_psu_fan: + # No LED available for PSU Fan + return None else: - return self.STATUS_LED_COLOR_OFF + if self.get_presence(): + if self.get_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_AMBER + else: + return self.STATUS_LED_COLOR_OFF def get_target_speed(self): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py index 265dc206ad0c..19198098dfd7 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py @@ -14,6 +14,7 @@ from sonic_platform_base.module_base import ModuleBase from sonic_platform.sfp import Sfp from sonic_platform.component import Component + from sonic_platform.eeprom import Eeprom except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -55,7 +56,7 @@ def __init__(self, module_index): self.port_start = (self.index - 1) * 16 self.port_end = (self.index * 16) - 1 self.port_i2c_line = self.IOM_I2C_MAPPING[self.index] - self.eeprom_tlv_dict = dict() + self._eeprom = Eeprom(iom_eeprom=True, i2c_line=self.port_i2c_line) self.iom_status_reg = "iom_status" self.iom_presence_reg = "iom_presence" @@ -108,7 +109,7 @@ def get_name(self): Returns: string: The name of the device """ - return "IOM{}: 16xQSFP+".format(self.index) + return "IOM{}: {}".format(self.index, self._eeprom.modelstr()) def get_presence(self): """ @@ -133,7 +134,7 @@ def get_model(self): Returns: string: part number of module """ - return 'NA' + return self._eeprom.part_number_str() def get_serial(self): """ @@ -142,7 +143,7 @@ def get_serial(self): Returns: string: Serial number of module """ - return 'NA' + return self._eeprom.serial_str() def get_status(self): """ @@ -178,7 +179,7 @@ def get_serial_number(self): Returns: A string containing the hardware serial number for this module. """ - return 'NA' + return self._eeprom.serial_number_str() def get_system_eeprom_info(self): """ @@ -192,4 +193,4 @@ def get_system_eeprom_info(self): ‘0x24’:’001c0f000fcd0a’, ‘0x25’:’02/03/2018 16:22:00’, ‘0x26’:’01’, ‘0x27’:’REV01’, ‘0x28’:’AG9064-C2358-16G’} """ - return self.eeprom_tlv_dict + return self._eeprom.system_eeprom_info() diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_sensors.py index 76e527e13d73..05cbb3a1a4c1 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_sensors.py @@ -262,8 +262,8 @@ def print_psu(psu): psu_fan_present = int(get_pmc_register('fan11_fault')) input_voltage = float(get_pmc_register('in29_input')) / 1000 output_voltage = float(get_pmc_register('in30_input')) / 1000 - input_current = float(get_pmc_register('curr601_input')) / 100 - output_current = float(get_pmc_register('curr602_input')) /100 + input_current = float(get_pmc_register('curr601_input')) / 1000 + output_current = float(get_pmc_register('curr602_input')) / 1000 input_power = float(get_pmc_register('power1_input')) / 1000000 output_power = float(get_pmc_register('power2_input')) / 1000000 if (input_power != 0): @@ -275,8 +275,8 @@ def print_psu(psu): psu_fan_present = int(get_pmc_register('fan12_fault')) input_voltage = float(get_pmc_register('in31_input')) / 1000 output_voltage = float(get_pmc_register('in32_input')) / 1000 - input_current = float(get_pmc_register('curr701_input')) / 100 - output_current = float(get_pmc_register('curr702_input')) / 100 + input_current = float(get_pmc_register('curr701_input')) / 1000 + output_current = float(get_pmc_register('curr702_input')) / 1000 input_power = float(get_pmc_register('power3_input')) / 1000000 output_power = float(get_pmc_register('power4_input')) / 1000000 if (input_power != 0): diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py index 3472bb3e7fb0..3e070d54004e 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py @@ -73,6 +73,7 @@ class Chassis(ChassisBase): power_reason_dict[44] = ChassisBase.REBOOT_CAUSE_INSUFFICIENT_FAN_SPEED def __init__(self): + ChassisBase.__init__(self) PORT_START = 0 PORT_END = 31 PORTS_IN_BLOCK = (PORT_END + 1) @@ -92,9 +93,8 @@ def __init__(self): self.PORT_I2C_MAPPING[index][1]) self._sfp_list.append(sfp_node) - ChassisBase.__init__(self) # Initialize EEPROM - self.sys_eeprom = Eeprom() + self._eeprom = Eeprom() for i in range(MAX_Z9100_FANTRAY): for j in range(MAX_Z9100_FAN): fan = Fan(i, j) @@ -137,7 +137,7 @@ def get_name(self): Returns: string: The name of the chassis """ - return self.sys_eeprom.modelstr() + return self._eeprom.modelstr() def get_presence(self): """ @@ -153,7 +153,7 @@ def get_model(self): Returns: string: Model/part number of chassis """ - return self.sys_eeprom.part_number_str() + return self._eeprom.part_number_str() def get_serial(self): """ @@ -161,7 +161,29 @@ def get_serial(self): Returns: string: Serial number of chassis """ - return self.sys_eeprom.serial_str() + return self._eeprom.serial_str() + + def get_sfp(self, index): + """ + Retrieves sfp represented by (1-based) index + + Args: + index: An integer, the index (1-based) of the sfp to retrieve. + The index should be the sequence of a physical port in a chassis, + starting from 1. + For example, 0 for Ethernet0, 1 for Ethernet4 and so on. + + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + + try: + sfp = self._sfp_list[index-1] + except IndexError: + sys.stderr.write("SFP index {} out of range (1-{})\n".format( + index, len(self._sfp_list)-1)) + return sfp def get_status(self): """ @@ -180,7 +202,7 @@ def get_base_mac(self): A string containing the MAC address in the format 'XX:XX:XX:XX:XX:XX' """ - return self.sys_eeprom.base_mac_addr() + return self._eeprom.base_mac_addr() def get_serial_number(self): """ @@ -189,7 +211,7 @@ def get_serial_number(self): Returns: A string containing the hardware serial number for this chassis. """ - return self.sys_eeprom.serial_number_str() + return self._eeprom.serial_number_str() def get_system_eeprom_info(self): """ @@ -200,7 +222,7 @@ def get_system_eeprom_info(self): OCP ONIE TlvInfo EEPROM format and values are their corresponding values. """ - return self.sys_eeprom.system_eeprom_info() + return self._eeprom.system_eeprom_info() def get_reboot_cause(self): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py index ae3c5e9fbcab..6ff688fa3a1e 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py @@ -33,6 +33,10 @@ def __init__(self, fantray_index=1, fan_index=1, psu_fan=False): # from 1 self.fantrayindex = fantray_index + 1 self.fanindex = fan_index + 1 + self.fan_presence_reg = "fan{}_fault".format( + 2 * (self.fantrayindex - 1) + (self.fanindex - 1) + 1 ) + self.fan_status_reg = "fan{}_alarm".format( + 2 * (self.fantrayindex - 1) + (self.fanindex - 1) + 1 ) self.get_fan_speed_reg = "fan{}_input".format( 2 * (self.fantrayindex - 1) + (self.fanindex - 1) + 1 ) self.get_fan_dir_reg = "fan{}_airflow".format( @@ -43,7 +47,9 @@ def __init__(self, fantray_index=1, fan_index=1, psu_fan=False): else: # PSU Fan index starts from 11 self.fanindex = fan_index + 10 + self.fan_presence_reg = "fan{}_fault".format(self.fanindex) self.get_fan_speed_reg = "fan{}_input".format(self.fanindex) + self.get_fan_dir_reg = "fan{}_airflow".format(self.fanindex) self.max_fan_speed = MAX_Z9100_PSU_FAN_SPEED def _get_pmc_register(self, reg_name): @@ -83,6 +89,9 @@ def get_model(self): """ # For Serial number "US-01234D-54321-25A-0123-A00", the part # number is "01234D" + if self.is_psu_fan: + return 'NA' + fan_serialno = self._get_pmc_register(self.fan_serialno_reg) if (fan_serialno != 'ERR') and self.get_presence(): if (len(fan_serialno.split('-')) > 1): @@ -101,6 +110,9 @@ def get_serial(self): string: Serial number of FAN """ # Sample Serial number format "US-01234D-54321-25A-0123-A00" + if self.is_psu_fan: + return 'NA' + fan_serialno = self._get_pmc_register(self.fan_serialno_reg) if (fan_serialno == 'ERR') or not self.get_presence(): fan_serialno = 'NA' @@ -114,11 +126,11 @@ def get_presence(self): bool: True if fan is present, False if not """ status = False - fantray_presence = self._get_pmc_register(self.get_fan_speed_reg) + fantray_presence = self._get_pmc_register(self.fan_presence_reg) if (fantray_presence != 'ERR'): fantray_presence = int(fantray_presence, 10) - if (fantray_presence > 0): - status = True + if (~fantray_presence & 0b1): + status = True return status @@ -129,11 +141,18 @@ def get_status(self): bool: True if FAN is operating properly, False if not """ status = False - fantray_status = self._get_pmc_register(self.get_fan_speed_reg) - if (fantray_status != 'ERR'): - fantray_status = int(fantray_status, 10) - if (fantray_status > 5000): - status = True + if self.is_psu_fan: + fantray_status = self._get_pmc_register(self.get_fan_speed_reg) + if (fantray_status != 'ERR'): + fantray_status = int(fantray_status, 10) + if (fantray_status > 1000): + status = True + else: + fantray_status = self._get_pmc_register(self.fan_status_reg) + if (fantray_status != 'ERR'): + fantray_status = int(fantray_status, 10) + if (~fantray_status & 0b1): + status = True return status @@ -143,13 +162,18 @@ def get_direction(self): Returns: A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction + + Notes: + In DellEMC platforms, + - Forward/Exhaust : Air flows from Port side to Fan side. + - Reverse/Intake : Air flows from Fan side to Port side. """ - direction = ['FAN_DIRECTION_INTAKE', 'FAN_DIRECTION_EXHAUST'] + direction = [self.FAN_DIRECTION_INTAKE, self.FAN_DIRECTION_EXHAUST] fan_direction = self._get_pmc_register(self.get_fan_dir_reg) if (fan_direction != 'ERR') and self.get_presence(): fan_direction = int(fan_direction, 10) else: - return 'N/A' + return self.FAN_DIRECTION_NOT_APPLICABLE return direction[fan_direction] def get_speed(self): @@ -215,10 +239,17 @@ def get_status_led(self): Returns: A string, one of the predefined STATUS_LED_COLOR_* strings. """ - if self.get_status(): - return self.STATUS_LED_COLOR_GREEN + if self.is_psu_fan: + # No LED available for PSU Fan + return None else: - return self.STATUS_LED_COLOR_OFF + if self.get_presence(): + if self.get_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_AMBER + else: + return self.STATUS_LED_COLOR_OFF def get_target_speed(self): """ diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/control b/platform/broadcom/sonic-platform-modules-delta/debian/control index 65b01234b4ec..e2e9883f9b2b 100644 --- a/platform/broadcom/sonic-platform-modules-delta/debian/control +++ b/platform/broadcom/sonic-platform-modules-delta/debian/control @@ -7,25 +7,25 @@ Standards-Version: 3.9.3 Package: platform-modules-ag9032v1 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag9064 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag5648 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-et-6248brb Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag9032v2a Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as syseeprom, sfp diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-et-6248brb.init b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-et-6248brb.init index 64361ced6b6c..58681208ef6c 100755 --- a/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-et-6248brb.init +++ b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-et-6248brb.init @@ -25,7 +25,7 @@ start) modprobe dni_gpio modprobe delta_et-6248brb_platform - if [ `uname -a | awk '{print $3}'` = "4.9.0-9-2-amd64" ]; then + if [ `uname -a | awk '{print $3}'` = "4.9.0-11-2-amd64" ]; then echo "453" > "/sys/class/gpio/export" echo "454" > "/sys/class/gpio/export" echo "455" > "/sys/class/gpio/export" diff --git a/platform/broadcom/sonic-platform-modules-delta/et-6248brb/scripts/led_status.sh b/platform/broadcom/sonic-platform-modules-delta/et-6248brb/scripts/led_status.sh index 734a44a6ca95..573af2156661 100644 --- a/platform/broadcom/sonic-platform-modules-delta/et-6248brb/scripts/led_status.sh +++ b/platform/broadcom/sonic-platform-modules-delta/et-6248brb/scripts/led_status.sh @@ -7,7 +7,7 @@ FAN2_RPM="/sys/bus/i2c/devices/0-002e/fan2_input" FAN_TRAY1_LED="/sys/devices/platform/delta-et6248brb-gpio.0/FAN/fan1_led_ag" FAN_TRAY2_LED="/sys/devices/platform/delta-et6248brb-gpio.0/FAN/fan2_led_ag" -if [ `uname -a | awk '{print $3}'` = "4.9.0-9-2-amd64" ]; then +if [ `uname -a | awk '{print $3}'` = "4.9.0-11-2-amd64" ]; then SYS_LED_G="/sys/class/gpio/gpio453/value" SYS_LED_R="/sys/class/gpio/gpio454/value" PWR_LED_G="/sys/class/gpio/gpio455/value" diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh index 249f179216a6..7776493bc20a 100755 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh index 7f50d137bcb7..0a4ba20ab767 100644 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh @@ -67,7 +67,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh index 36f9e53ef108..b3192f2efb7a 100644 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh @@ -67,7 +67,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh index 249f179216a6..7776493bc20a 100755 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh index 51c49c1152f5..47cfbb3ea008 100755 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh @@ -66,7 +66,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/utils/inventec_d6356_util.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/utils/inventec_d6356_util.py index 890973cb8356..10fcb001b0c2 100755 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/utils/inventec_d6356_util.py +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/utils/inventec_d6356_util.py @@ -141,7 +141,7 @@ def system_install(): status, output = exec_cmd("rmmod lpc_ich ", 1) #insert extra module - status, output = exec_cmd("insmod /lib/modules/4.9.0-9-2-amd64/kernel/drivers/gpio/gpio-ich.ko gpiobase=0",1) + status, output = exec_cmd("insmod /lib/modules/4.9.0-11-2-amd64/kernel/drivers/gpio/gpio-ich.ko gpiobase=0",1) #install drivers for i in range(0,len(drivers)): diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/control b/platform/broadcom/sonic-platform-modules-inventec/debian/control index 6cb61630823f..86f7e7b20f65 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/control +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/control @@ -7,30 +7,30 @@ Standards-Version: 3.9.3 Package: platform-modules-d7032q28b Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d7054q28b Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6254qs Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6556 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6356 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d7264q28b Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py index d225400121b8..ec83499c5c7b 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py @@ -468,7 +468,7 @@ def __init__(self, log_file, log_level): masterLED_file = open(MASTER_LED_PATH, 'r+') except IOError as e: print "Error: unable to open file: %s" % str(e) - return False + return masterLED_file.write(str(master_led_value)) masterLED_file.close() @@ -477,10 +477,9 @@ def __init__(self, log_file, log_level): systemLED_file = open(SYSTEM_LED_PATH, 'r+') except IOError as e: print "Error: unable to open file: %s" % str(e) - return False + return systemLED_file.write(str(system_led_value)) systemLED_file.close() - pass def manage_device(self): thermal = QFX5210_ThermalUtil() diff --git a/platform/broadcom/sonic-platform-modules-quanta/debian/rules b/platform/broadcom/sonic-platform-modules-quanta/debian/rules old mode 100644 new mode 100755 diff --git a/platform/cavium/docker-syncd-cavm-rpc.mk b/platform/cavium/docker-syncd-cavm-rpc.mk index e57370fce5ca..ebe614b3c183 100644 --- a/platform/cavium/docker-syncd-cavm-rpc.mk +++ b/platform/cavium/docker-syncd-cavm-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_CAVM_RPC = docker-syncd-cavm-rpc.gz $(DOCKER_SYNCD_CAVM_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-cavm-rpc -$(DOCKER_SYNCD_CAVM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(CAVM_LIBSAI) $(XP_TOOLS) $(REDIS_TOOLS) +$(DOCKER_SYNCD_CAVM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(CAVM_LIBSAI) $(XP_TOOLS) $(REDIS_TOOLS) $(PTF) $(DOCKER_SYNCD_CAVM_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_CAVM_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ diff --git a/platform/cavium/docker-syncd-cavm.mk b/platform/cavium/docker-syncd-cavm.mk index a136828dbff1..ad43d6f1196f 100644 --- a/platform/cavium/docker-syncd-cavm.mk +++ b/platform/cavium/docker-syncd-cavm.mk @@ -20,3 +20,4 @@ $(DOCKER_SYNCD_CAVM)_CONTAINER_NAME = syncd $(DOCKER_SYNCD_CAVM)_RUN_OPT += --net=host --privileged -t $(DOCKER_SYNCD_CAVM)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_CAVM)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_SYNCD_CAVM)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd b/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd new file mode 100644 index 000000000000..3079618990ed --- /dev/null +++ b/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/cavium/docker-syncd-cavm/supervisord.conf b/platform/cavium/docker-syncd-cavm/supervisord.conf index c823ab5680ef..0c6285d46ae0 100644 --- a/platform/cavium/docker-syncd-cavm/supervisord.conf +++ b/platform/cavium/docker-syncd-cavm/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/platform/centec/docker-syncd-centec-rpc.mk b/platform/centec/docker-syncd-centec-rpc.mk index 71c8ef7753c1..47c672dd93de 100644 --- a/platform/centec/docker-syncd-centec-rpc.mk +++ b/platform/centec/docker-syncd-centec-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_CENTEC_RPC = docker-syncd-centec-rpc.gz $(DOCKER_SYNCD_CENTEC_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-centec-rpc -$(DOCKER_SYNCD_CENTEC_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_CENTEC_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) $(DOCKER_SYNCD_CENTEC_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_CENTEC_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ diff --git a/platform/centec/docker-syncd-centec.mk b/platform/centec/docker-syncd-centec.mk index 360690731a58..a0dbcc629dee 100644 --- a/platform/centec/docker-syncd-centec.mk +++ b/platform/centec/docker-syncd-centec.mk @@ -21,3 +21,4 @@ $(DOCKER_SYNCD_CENTEC)_RUN_OPT += --net=host --privileged -t $(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd $(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_SYNCD_CENTEC)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/centec/docker-syncd-centec/base_image_files/monit_syncd b/platform/centec/docker-syncd-centec/base_image_files/monit_syncd new file mode 100644 index 000000000000..3079618990ed --- /dev/null +++ b/platform/centec/docker-syncd-centec/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/centec/docker-syncd-centec/supervisord.conf b/platform/centec/docker-syncd-centec/supervisord.conf index c823ab5680ef..0c6285d46ae0 100644 --- a/platform/centec/docker-syncd-centec/supervisord.conf +++ b/platform/centec/docker-syncd-centec/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/platform/centec/sonic-platform-modules-e582/debian/control b/platform/centec/sonic-platform-modules-e582/debian/control index ba30e04f0388..c449246b2823 100644 --- a/platform/centec/sonic-platform-modules-e582/debian/control +++ b/platform/centec/sonic-platform-modules-e582/debian/control @@ -7,11 +7,11 @@ Standards-Version: 3.9.3 Package: platform-modules-e582-48x2q4z Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-e582-48x6q Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/innovium/docker-syncd-invm-rpc.mk b/platform/innovium/docker-syncd-invm-rpc.mk index 313f0d12ac20..62d6891bbc21 100755 --- a/platform/innovium/docker-syncd-invm-rpc.mk +++ b/platform/innovium/docker-syncd-invm-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_INVM_RPC = docker-syncd-invm-rpc.gz $(DOCKER_SYNCD_INVM_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-invm-rpc -$(DOCKER_SYNCD_INVM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(INVM_LIBSAI) +$(DOCKER_SYNCD_INVM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(INVM_LIBSAI) $(PTF) $(DOCKER_SYNCD_INVM_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BASE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_INVM_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) diff --git a/platform/innovium/invm-sai.mk b/platform/innovium/invm-sai.mk index 8c236a8b68d2..2d89ef71e3b4 100755 --- a/platform/innovium/invm-sai.mk +++ b/platform/innovium/invm-sai.mk @@ -1,6 +1,6 @@ # INVM SAI -INVM_SAI_ONLINE = https://github.com/Innovium/SONiC/raw/master/debian/master +INVM_SAI_ONLINE = https://github.com/Innovium/SONiC/raw/master/debian/201911 INVM_LIBSAI = isai.deb INVM_HSAI = saihdr.deb diff --git a/platform/innovium/sonic-platform-modules-cel/debian/control b/platform/innovium/sonic-platform-modules-cel/debian/control index 48ef777a99a6..543d381ab6f7 100755 --- a/platform/innovium/sonic-platform-modules-cel/debian/control +++ b/platform/innovium/sonic-platform-modules-cel/debian/control @@ -7,5 +7,5 @@ Standards-Version: 3.9.3 Package: platform-modules-midstone-200i Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices diff --git a/platform/innovium/sonic-platform-modules-delta/debian/control b/platform/innovium/sonic-platform-modules-delta/debian/control index 71c403387f80..3fe3ffc9f526 100644 --- a/platform/innovium/sonic-platform-modules-delta/debian/control +++ b/platform/innovium/sonic-platform-modules-delta/debian/control @@ -7,7 +7,7 @@ Standards-Version: 3.9.3 Package: platform-modules-et-c032if Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/marvell-arm64/docker-syncd-mrvl-rpc.mk b/platform/marvell-arm64/docker-syncd-mrvl-rpc.mk index 0e1b65f2fd5d..c3ce6c10119c 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl-rpc.mk +++ b/platform/marvell-arm64/docker-syncd-mrvl-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_MRVL_RPC = docker-syncd-mrvl-rpc.gz $(DOCKER_SYNCD_MRVL_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mrvl-rpc -$(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) $(DOCKER_SYNCD_MRVL_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ diff --git a/platform/marvell-arm64/docker-syncd-mrvl.mk b/platform/marvell-arm64/docker-syncd-mrvl.mk index e00769a59700..841e3b4b165f 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl.mk +++ b/platform/marvell-arm64/docker-syncd-mrvl.mk @@ -11,3 +11,4 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIREDIS_DBG) $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd new file mode 100644 index 000000000000..3079618990ed --- /dev/null +++ b/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf b/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf index 1af5d70a1d0c..b11e045fac7e 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 diff --git a/platform/marvell-armhf/docker-syncd-mrvl-rpc.mk b/platform/marvell-armhf/docker-syncd-mrvl-rpc.mk index 0e1b65f2fd5d..c3ce6c10119c 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl-rpc.mk +++ b/platform/marvell-armhf/docker-syncd-mrvl-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_MRVL_RPC = docker-syncd-mrvl-rpc.gz $(DOCKER_SYNCD_MRVL_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mrvl-rpc -$(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) $(DOCKER_SYNCD_MRVL_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ diff --git a/platform/marvell-armhf/docker-syncd-mrvl.mk b/platform/marvell-armhf/docker-syncd-mrvl.mk index e00769a59700..841e3b4b165f 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl.mk +++ b/platform/marvell-armhf/docker-syncd-mrvl.mk @@ -11,3 +11,4 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIREDIS_DBG) $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd new file mode 100644 index 000000000000..3079618990ed --- /dev/null +++ b/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf b/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf index 1af5d70a1d0c..b11e045fac7e 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 diff --git a/platform/marvell-armhf/linux-kernel-armhf.mk b/platform/marvell-armhf/linux-kernel-armhf.mk index 32e8ea3c604a..4d52beac49d9 100644 --- a/platform/marvell-armhf/linux-kernel-armhf.mk +++ b/platform/marvell-armhf/linux-kernel-armhf.mk @@ -1,7 +1,7 @@ # linux kernel package for marvell armhf # Add platform specific DTB -LINUX_KERNEL_DTB = linux-image-4.9.168-armhf.deb +LINUX_KERNEL_DTB = linux-image-4.9.189-armhf.deb $(LINUX_KERNEL_DTB)_URL = https://github.com/Marvell-switching/sonic-marvell-binaries/raw/master/armhf/kernel/$(LINUX_KERNEL_DTB) SONIC_ONLINE_DEBS += $(LINUX_KERNEL_DTB) SONIC_STRETCH_DEBS += $(LINUX_KERNEL_DTB) diff --git a/platform/marvell/docker-syncd-mrvl-rpc.mk b/platform/marvell/docker-syncd-mrvl-rpc.mk index 5b1968bde39c..92d616fa2cab 100644 --- a/platform/marvell/docker-syncd-mrvl-rpc.mk +++ b/platform/marvell/docker-syncd-mrvl-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_MRVL_RPC = docker-syncd-mrvl-rpc.gz $(DOCKER_SYNCD_MRVL_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mrvl-rpc -$(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) $(DOCKER_SYNCD_MRVL_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ diff --git a/platform/marvell/docker-syncd-mrvl.mk b/platform/marvell/docker-syncd-mrvl.mk index 5257bf5e68e7..97b7eab19895 100644 --- a/platform/marvell/docker-syncd-mrvl.mk +++ b/platform/marvell/docker-syncd-mrvl.mk @@ -12,3 +12,4 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd new file mode 100644 index 000000000000..3079618990ed --- /dev/null +++ b/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/marvell/docker-syncd-mrvl/supervisord.conf b/platform/marvell/docker-syncd-mrvl/supervisord.conf index aea4d45b9afd..43de2426f981 100644 --- a/platform/marvell/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell/docker-syncd-mrvl/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/platform/mellanox/docker-syncd-mlnx-rpc.mk b/platform/mellanox/docker-syncd-mlnx-rpc.mk index 608c1bb3ad20..ef2aec3333ac 100644 --- a/platform/mellanox/docker-syncd-mlnx-rpc.mk +++ b/platform/mellanox/docker-syncd-mlnx-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_MLNX_RPC = docker-syncd-mlnx-rpc.gz $(DOCKER_SYNCD_MLNX_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mlnx-rpc -$(DOCKER_SYNCD_MLNX_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MLNX_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) $(DOCKER_SYNCD_MLNX_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_MLNX_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ @@ -20,7 +20,7 @@ SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_MLNX_RPC) endif $(DOCKER_SYNCD_MLNX_RPC)_CONTAINER_NAME = syncd -$(DOCKER_SYNCD_MLNX_RPC)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SYNCD_MLNX_RPC)_RUN_OPT += --privileged -t $(DOCKER_SYNCD_MLNX_RPC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_MLNX_RPC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_SYNCD_MLNX_RPC)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 b/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 index d9b86e782531..3f6225c96bd3 100644 --- a/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 +++ b/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 @@ -4,6 +4,8 @@ FROM docker-syncd-mlnx ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive +RUN mkdir -p /var/run/sx_sdk + RUN apt-get purge -y syncd {% if docker_syncd_mlnx_rpc_debs.strip() -%} diff --git a/platform/mellanox/docker-syncd-mlnx.mk b/platform/mellanox/docker-syncd-mlnx.mk index db582e517bff..9bdc5a8ad8ec 100644 --- a/platform/mellanox/docker-syncd-mlnx.mk +++ b/platform/mellanox/docker-syncd-mlnx.mk @@ -15,4 +15,4 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(MLNX_SDK_DBG_DEBS) $(MLNX_SAI_DBGSYM) endif $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot - +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 index 4d22335ec783..6953933735fa 100755 --- a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 +++ b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 @@ -4,6 +4,8 @@ FROM docker-config-engine-stretch ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf +RUN mkdir -p /var/run/sx_sdk + ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd b/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd new file mode 100644 index 000000000000..3079618990ed --- /dev/null +++ b/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/mellanox/docker-syncd-mlnx/supervisord.conf b/platform/mellanox/docker-syncd-mlnx/supervisord.conf index c823ab5680ef..0c6285d46ae0 100644 --- a/platform/mellanox/docker-syncd-mlnx/supervisord.conf +++ b/platform/mellanox/docker-syncd-mlnx/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index eb1a58cfda9d..faa3b3f239b6 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -1,4 +1,4 @@ -# mellanox firmware +# mellanox asic firmware MLNX_FW_BASE_PATH = $(MLNX_SDK_BASE_PATH) @@ -11,24 +11,36 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2000.2696 +MLNX_SPC_FW_VERSION = 13.2007.0872 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2000.2696 +MLNX_SPC2_FW_VERSION = 29.2007.0872 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) +MLNX_SPC3_FW_VERSION = 30.2007.0872 +MLNX_SPC3_FW_FILE = fw-SPC3-rel-$(subst .,_,$(MLNX_SPC3_FW_VERSION))-EVB.mfa +$(MLNX_SPC3_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) +$(MLNX_SPC3_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC3_FW_FILE) + +MLNX_FW_FILES = $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) $(MLNX_SPC3_FW_FILE) + ifeq ($(FW_FROM_URL),n) -SONIC_COPY_FILES += $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) +SONIC_COPY_FILES += $(MLNX_FW_FILES) else -SONIC_ONLINE_FILES += $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) +SONIC_ONLINE_FILES += $(MLNX_FW_FILES) endif +MLNX_FILES += $(MLNX_FW_FILES) + export MLNX_SPC_FW_VERSION export MLNX_SPC_FW_FILE export MLNX_SPC2_FW_VERSION export MLNX_SPC2_FW_FILE + +export MLNX_SPC3_FW_VERSION +export MLNX_SPC3_FW_FILE diff --git a/platform/mellanox/hw-management.mk b/platform/mellanox/hw-management.mk index ff1ea207572d..692a816a0f4f 100644 --- a/platform/mellanox/hw-management.mk +++ b/platform/mellanox/hw-management.mk @@ -1,6 +1,6 @@ # Mellanox HW Management -MLNX_HW_MANAGEMENT_VERSION = 7.0000.2308 +MLNX_HW_MANAGEMENT_VERSION = 7.0000.3012 export MLNX_HW_MANAGEMENT_VERSION diff --git a/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch b/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch index 31a85434fb49..a72c94473e88 100644 --- a/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch +++ b/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch @@ -1,7 +1,7 @@ -From 051938b7c49cc18aaddd699939353f591554d635 Mon Sep 17 00:00:00 2001 +From ebb17bd1f6996f73cb67313846a63c789e74c4f4 Mon Sep 17 00:00:00 2001 From: Mykola Faryma -Date: Wed, 3 Apr 2019 14:09:26 +0000 -Subject: [PATCH] Make hw-mgmt SimX compatiable. +Date: Fri, 21 Feb 2020 12:28:54 +0200 +Subject: [PATCH 1/1] Make hw-mgmt SimX compatiable Signed-off-by: Mykola Faryma --- @@ -9,45 +9,45 @@ Signed-off-by: Mykola Faryma 1 file changed, 29 insertions(+) diff --git a/usr/usr/bin/hw-management.sh b/usr/usr/bin/hw-management.sh -index fdb3013..68da9bc 100755 +index 1b5b18a..3dfd4b1 100755 --- a/usr/usr/bin/hw-management.sh +++ b/usr/usr/bin/hw-management.sh -@@ -646,6 +646,35 @@ do_chip_down() +@@ -943,6 +943,35 @@ do_chip_down() /usr/bin/hw-management-thermal-events.sh change hotplug_asic down %S %p } +handle_simx() +{ -+ local -r onie_platform="$(cat /host/machine.conf | grep onie_platform | cut -d= -f2)" ++ local -r onie_platform="$(cat /host/machine.conf | grep onie_platform | cut -d= -f2)" + -+ local -r syseeprom_cache_path="/var/cache/sonic/decode-syseeprom/syseeprom_cache" -+ local -r syseeprom_hex_path="/usr/share/sonic/device/${onie_platform}/syseeprom.hex" -+ local -r syseeprom_vpd_path="/var/run/hw-management/eeprom/vpd_info" ++ local -r syseeprom_cache_path="/var/cache/sonic/decode-syseeprom/syseeprom_cache" ++ local -r syseeprom_hex_path="/usr/share/sonic/device/${onie_platform}/syseeprom.hex" ++ local -r syseeprom_vpd_path="/var/run/hw-management/eeprom/vpd_info" + -+ case $ACTION in -+ start) -+ /bin/bash -c "/bin/rm -f ${syseeprom_cache_path}" -+ /bin/bash -c "/bin/mkdir -p ${eeprom_path}" -+ /bin/bash -c "/usr/bin/xxd -r -p ${syseeprom_hex_path} ${syseeprom_vpd_path}" -+ ;; -+ stop) -+ /bin/bash -c "/bin/rm -fr ${hw_management_path}" -+ ;; -+ *) -+ echo "Usage: `basename $0` {start|stop}" -+ exit 1 -+ ;; -+ esac ++ case $ACTION in ++ start) ++ /bin/bash -c "/bin/rm -f ${syseeprom_cache_path}" ++ /bin/bash -c "/bin/mkdir -p ${eeprom_path}" ++ /bin/bash -c "/usr/bin/xxd -r -p ${syseeprom_hex_path} ${syseeprom_vpd_path}" ++ ;; ++ stop) ++ /bin/bash -c "/bin/rm -fr ${hw_management_path}" ++ ;; ++ *) ++ echo "Usage: `basename $0` {start|stop}" ++ exit 1 ++ ;; ++ esac +} + -+if [[ "$(cat /sys/devices/virtual/dmi/id/chassis_vendor)" = "QEMU" ]]; then -+ handle_simx -+ exit 0 ++if [[ "$(cat /sys/devices/virtual/dmi/id/sys_vendor)" = "QEMU" ]]; then ++ handle_simx ++ exit 0 +fi + case $ACTION in start) - do_start + if [ -d /var/run/hw-management ]; then -- 1.9.1 diff --git a/platform/mellanox/hw-management/hw-mgmt b/platform/mellanox/hw-management/hw-mgmt index 28d83cdb3565..2f659142ab3b 160000 --- a/platform/mellanox/hw-management/hw-mgmt +++ b/platform/mellanox/hw-management/hw-mgmt @@ -1 +1 @@ -Subproject commit 28d83cdb3565d3b0352cc718fe82a14cacd1d4a5 +Subproject commit 2f659142ab3b4deb58989a2ca38b0b1671600509 diff --git a/platform/mellanox/issu-version.mk b/platform/mellanox/issu-version.mk index c7ae4296ab7a..db368ffd8c10 100644 --- a/platform/mellanox/issu-version.mk +++ b/platform/mellanox/issu-version.mk @@ -5,5 +5,6 @@ $(ISSU_VERSION_FILE)_SRC_PATH = $(PLATFORM_PATH)/issu-version $(ISSU_VERSION_FILE)_DEPENDS += $(APPLIBS) SONIC_MAKE_FILES += $(ISSU_VERSION_FILE) -export ISSU_VERSION_FILE +MLNX_FILES += $(ISSU_VERSION_FILE) +export ISSU_VERSION_FILE diff --git a/platform/mellanox/mft.mk b/platform/mellanox/mft.mk index ae2c92e0ac18..229ba86b4a7b 100644 --- a/platform/mellanox/mft.mk +++ b/platform/mellanox/mft.mk @@ -1,7 +1,7 @@ # Mellanox SAI -MFT_VERSION = 4.12.0 -MFT_REVISION = 104 +MFT_VERSION = 4.14.0 +MFT_REVISION = 500 export MFT_VERSION MFT_REVISION diff --git a/platform/mellanox/mlnx-ffb.mk b/platform/mellanox/mlnx-ffb.mk index dabb995a3658..82d50b7ae3e3 100755 --- a/platform/mellanox/mlnx-ffb.mk +++ b/platform/mellanox/mlnx-ffb.mk @@ -4,4 +4,6 @@ MLNX_FFB_SCRIPT = mlnx-ffb.sh $(MLNX_FFB_SCRIPT)_PATH = platform/mellanox/ SONIC_COPY_FILES += $(MLNX_FFB_SCRIPT) +MLNX_FILES += $(MLNX_FFB_SCRIPT) + export MLNX_FFB_SCRIPT diff --git a/platform/mellanox/mlnx-fw-upgrade.j2 b/platform/mellanox/mlnx-fw-upgrade.j2 index 3857244a1504..d0f69c35e0bc 100755 --- a/platform/mellanox/mlnx-fw-upgrade.j2 +++ b/platform/mellanox/mlnx-fw-upgrade.j2 @@ -25,15 +25,18 @@ declare -r QUERY_FILE="/tmp/mlxfwmanager-query.log" declare -r SPC1_ASIC="spc1" declare -r SPC2_ASIC="spc2" +declare -r SPC3_ASIC="spc3" declare -r UNKN_ASIC="unknown" declare -rA FW_FILE_MAP=( \ [$SPC1_ASIC]="/etc/mlnx/fw-SPC.mfa" \ [$SPC2_ASIC]="/etc/mlnx/fw-SPC2.mfa" \ + [$SPC3_ASIC]="/etc/mlnx/fw-SPC3.mfa" \ ) declare -rA FW_REQUIRED_MAP=( \ [$SPC1_ASIC]="{{ MLNX_SPC_FW_VERSION }}" \ [$SPC2_ASIC]="{{ MLNX_SPC2_FW_VERSION }}" \ + [$SPC3_ASIC]="{{ MLNX_SPC3_FW_VERSION }}" \ ) IMAGE_UPGRADE="${NO_PARAM}" @@ -135,6 +138,7 @@ function GetAsicType() { local -r SPC1_PRODUCT_ID="cb84" local -r SPC2_PRODUCT_ID="cf6c" + local -r SPC3_PRODUCT_ID="cf70" if lspci -n | grep "${VENDOR_ID}:${SPC1_PRODUCT_ID}" &>/dev/null; then echo "${SPC1_ASIC}" @@ -142,6 +146,9 @@ function GetAsicType() { elif lspci -n | grep "${VENDOR_ID}:${SPC2_PRODUCT_ID}" &>/dev/null; then echo "${SPC2_ASIC}" exit "${EXIT_SUCCESS}" + elif lspci -n | grep "${VENDOR_ID}:${SPC3_PRODUCT_ID}" &>/dev/null; then + echo "${SPC3_ASIC}" + exit "${EXIT_SUCCESS}" fi echo "${UNKN_ASIC}" diff --git a/platform/mellanox/mlnx-onie-fw-update.mk b/platform/mellanox/mlnx-onie-fw-update.mk new file mode 100644 index 000000000000..825c12c30ba4 --- /dev/null +++ b/platform/mellanox/mlnx-onie-fw-update.mk @@ -0,0 +1,9 @@ +# onie update tool + +MLNX_ONIE_FW_UPDATE = mlnx-onie-fw-update.sh +$(MLNX_ONIE_FW_UPDATE)_PATH = platform/mellanox/ +SONIC_COPY_FILES += $(MLNX_ONIE_FW_UPDATE) + +MLNX_FILES += $(MLNX_ONIE_FW_UPDATE) + +export MLNX_ONIE_FW_UPDATE diff --git a/platform/mellanox/mlnx-onie-fw-update.sh b/platform/mellanox/mlnx-onie-fw-update.sh new file mode 100755 index 000000000000..314f4ed70268 --- /dev/null +++ b/platform/mellanox/mlnx-onie-fw-update.sh @@ -0,0 +1,120 @@ +#!/bin/sh + +# Copyright (C) 2019 Mellanox Technologies Ltd. +# Copyright (C) 2019 Michael Shych +# +# SPDX-License-Identifier: GPL-2.0 + +this_script=${ONIE_FWPKG_PROGRAM_NAME:-$(basename $(realpath $0))} + +onie_mount=/mnt/onie-boot +os_boot=/host +onie_partition= + +export ONIE_FWPKG_PROGRAM_NAME=$(basename $(realpath $0)) + +usage() +{ +cat < before update." + clean_onie_access + exit 1 + fi + ;; + purge | show | show-results | show-log | show-pending | help) + ;; + *) + echo "Unknown command: $cmd" + exit 1 + ;; +esac + +enable_onie_access +$onie_mount/onie/tools/bin/onie-fwpkg "$@" +rc=$? +if [ $cmd = "help" ]; then + usage +fi +clean_onie_access + +exit $rc diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 44ef8981281f..5edb82bfe517 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -11,6 +11,7 @@ try: from sonic_platform_base.chassis_base import ChassisBase from sonic_platform_base.component_base import ComponentBase + from sonic_device_util import get_machine_info from sonic_daemon_base.daemon_base import Logger from os import listdir from os.path import isfile, join @@ -43,7 +44,7 @@ # magic code defnition for port number, qsfp port position of each hwsku # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict_port = {'ACS-MSN2010': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4} +hwsku_dict_port = {'ACS-MSN2010': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0} port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1)] class Chassis(ChassisBase): @@ -54,6 +55,11 @@ def __init__(self): # Initialize SKU name self.sku_name = self._get_sku_name() + mi = get_machine_info() + if mi is not None: + self.name = mi['onie_platform'] + else: + self.name = self.sku_name # move the initialization of each components to their dedicated initializer # which will be called from platform @@ -133,7 +139,17 @@ def initialize_components(self): # Initialize component list from sonic_platform.component import ComponentBIOS, ComponentCPLD self._component_list.append(ComponentBIOS()) - self._component_list.append(ComponentCPLD()) + self._component_list.extend(ComponentCPLD.get_component_list()) + + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return self.name ############################################## @@ -417,25 +433,12 @@ def get_change_event(self, timeout=0): timeout = MAX_SELECT_DELAY while True: status = self.sfp_event.check_sfp_status(port_dict, timeout) - if not port_dict == {}: + if bool(port_dict): break else: status = self.sfp_event.check_sfp_status(port_dict, timeout) if status: - # get_change_event has the meaning of retrieving all the notifications through a single call. - # Typically this is implemented via a select framework which requires the underlay file-reading - # interface able to retrieve all notifications without blocking once the fd has been selected. - # However, sdk doesn't provide any interface satisfied the requirement. as a result, - # check_sfp_status returns only one notification may indicate more notifications in its queue. - # In this sense, we have to iterate in a loop to get all the notifications in case that - # the first call returns at least one. - i = 0 - while i < self.MAX_SELECT_EVENT_RETURNED: - status = self.sfp_event.check_sfp_status(port_dict, 0) - if not status: - break - i = i + 1 return True, {'sfp':port_dict} else: return True, {'sfp':{}} diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index fd593f7bbe45..13e3953a03ad 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -5,25 +5,28 @@ # # implementation of new platform api ############################################################################# - +from __future__ import print_function try: from sonic_platform_base.component_base import ComponentBase + from sonic_device_util import get_machine_info from glob import glob import subprocess import io + import os import re 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 +ZERO = '0' +NEWLINE = '\n' class Component(ComponentBase): + def __init__(self): + self.name = None + self.description = None + self.image_ext_name = None + + def get_name(self): """ Retrieves the name of the component @@ -34,25 +37,42 @@ def get_name(self): return self.name - def _read_generic_file(self, filename, len): + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + return self.description + + + @staticmethod + def _read_generic_file(filename, len, ignore_errors=False): """ Read a generic file, returns the contents of the file """ - result = '' + result = None + try: with io.open(filename, 'r') as fileobj: result = fileobj.read(len) - return result except IOError as e: - raise RuntimeError("Failed to read file {} due to {}".format(filename, repr(e))) + if not ignore_errors: + raise RuntimeError("Failed to read file {} due to {}".format(filename, repr(e))) + + return result - def _get_command_result(self, cmdline): + @staticmethod + def _get_command_result(cmdline): try: proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) stdout = proc.communicate()[0] - proc.wait() + rc = proc.wait() result = stdout.rstrip('\n') + if rc != 0: + raise RuntimeError("Failed to execute command {}, return code {}, message {}".format(cmdline, rc, stdout)) except OSError as e: raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) @@ -60,22 +80,50 @@ def _get_command_result(self, cmdline): return result -class ComponentBIOS(Component): - BIOS_VERSION_PARSE_PATTERN = 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' + def _check_file_validity(self, image_path): + # check whether the image file exists + if not os.path.isfile(image_path): + print("ERROR: File {} doesn't exist or is not a file".format(image_path)) + return False + if self.image_ext_name is not None: + name_list = os.path.splitext(image_path) + if name_list[1] != self.image_ext_name: + print("ERROR: Extend name of file {} is wrong. Image for {} should have extend name {}".format(image_path, self.name, self.image_ext_name)) + return False - def __init__(self): - self.name = COMPONENT_BIOS + return True - 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" +class ComponentBIOS(Component): + COMPONENT_NAME = 'BIOS' + COMPONENT_DESCRIPTION = 'BIOS - Basic Input/Output System' + COMPONENT_FIRMWARE_EXTENSION = '.rom' + + # To update BIOS requires the ONIE with version 5.2.0016 or upper + ONIE_VERSION_PARSE_PATTERN = '[0-9]{4}\.[0-9]{2}-([0-9]+)\.([0-9]+)\.([0-9]+)' + ONIE_VERSION_MAJOR_OFFSET = 1 + ONIE_VERSION_MINOR_OFFSET = 2 + ONIE_VERSION_RELEASE_OFFSET = 3 + ONIE_REQUIRED_MAJOR = '5' + ONIE_REQUIRED_MINOR = '2' + ONIE_REQUIRED_RELEASE = '0016' + + BIOS_VERSION_PARSE_PATTERN = 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' + BIOS_PENDING_UPDATE_PATTERN = '([0-9A-Za-z_]*.rom)[\s]*\|[\s]*bios_update' + + ONIE_FW_UPDATE_CMD_ADD = '/usr/bin/mlnx-onie-fw-update.sh add {}' + ONIE_FW_UPDATE_CMD_REMOVE = '/usr/bin/mlnx-onie-fw-update.sh remove {}' + ONIE_FW_UPDATE_CMD_UPDATE = '/usr/bin/mlnx-onie-fw-update.sh update' + ONIE_FW_UPDATE_CMD_SHOW = '/usr/bin/mlnx-onie-fw-update.sh show-pending' + + BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' + + def __init__(self): + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + self.image_ext_name = self.COMPONENT_FIRMWARE_EXTENSION def get_firmware_version(self): @@ -99,30 +147,110 @@ def get_firmware_version(self): By using regular expression 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' we can extrace the version string which is marked with * in the above context """ - bios_ver_str = self._get_command_result(BIOS_QUERY_VERSION_COMMAND) try: + bios_ver_str = self._get_command_result(self.BIOS_QUERY_VERSION_COMMAND) m = re.search(self.BIOS_VERSION_PARSE_PATTERN, bios_ver_str) result = m.group(1) - except AttributeError as e: - raise RuntimeError("Failed to parse BIOS version by {} from {} due to {}".format( - self.BIOS_VERSION_PARSE_PATTERN, bios_ver_str, repr(e))) + except (AttributeError, RuntimeError) as e: + raise RuntimeError("Failed to parse BIOS version due to {}".format(repr(e))) return result -class ComponentCPLD(Component): - def __init__(self): - self.name = COMPONENT_CPLD + def _check_onie_version(self): + # check ONIE version. To update ONIE requires version 5.2.0016 or later. + try: + machine_info = get_machine_info() + onie_version_string = machine_info['onie_version'] + m = re.search(self.ONIE_VERSION_PARSE_PATTERN, onie_version_string) + onie_major = m.group(self.ONIE_VERSION_MAJOR_OFFSET) + onie_minor = m.group(self.ONIE_VERSION_MINOR_OFFSET) + onie_release = m.group(self.ONIE_VERSION_RELEASE_OFFSET) + except AttributeError as e: + print("ERROR: Failed to parse ONIE version by {} from {} due to {}".format( + self.ONIE_VERSION_PARSE_PATTERN, machine_conf, repr(e))) + return False + if onie_major < self.ONIE_REQUIRED_MAJOR or onie_minor < self.ONIE_REQUIRED_MINOR or onie_release < self.ONIE_REQUIRED_RELEASE: + print("ERROR: ONIE {}.{}.{} or later is required".format(self.ONIE_REQUIRED_MAJOR, self.ONIE_REQUIRED_MINOR, self.ONIE_REQUIRED_RELEASE)) + return False - def get_description(self): + return True + + + def install_firmware(self, image_path): """ - Retrieves the description of the component + Installs firmware to the component + + Args: + image_path: A string, path to firmware image Returns: - A string containing the description of the component + A boolean, True if install was successful, False if not """ - return "CPLD - includes all CPLDs in the switch" + # check ONIE version requirement + if not self._check_onie_version(): + return False + + # check whether the file exists + if not self._check_file_validity(image_path): + return False + + # do the real work + try: + # check whether there has already been some images pending + # if yes, remove them + result = self._get_command_result(self.ONIE_FW_UPDATE_CMD_SHOW) + pending_list = result.split("\n") + for pending in pending_list: + m = re.match(self.BIOS_PENDING_UPDATE_PATTERN, pending) + if m is not None: + pending_image = m.group(1) + self._get_command_result(self.ONIE_FW_UPDATE_CMD_REMOVE.format(pending_image)) + print("WARNING: Image {} which is already pending to upgrade has been removed".format(pending_image)) + + result = subprocess.check_call(self.ONIE_FW_UPDATE_CMD_ADD.format(image_path).split()) + if result: + return False + result = subprocess.check_call(self.ONIE_FW_UPDATE_CMD_UPDATE.split()) + if result: + return False + except Exception as e: + print("ERROR: Installing BIOS failed due to {}".format(repr(e))) + return False + + print("INFO: Reboot is required to finish BIOS installation") + return True + + + +class ComponentCPLD(Component): + COMPONENT_NAME = 'CPLD{}' + COMPONENT_DESCRIPTION = 'CPLD - Complex Programmable Logic Device' + COMPONENT_FIRMWARE_EXTENSION = '.vme' + + CPLD_NUMBER_FILE = '/var/run/hw-management/config/cpld_num' + CPLD_PART_NUMBER_FILE = '/var/run/hw-management/system/cpld{}_pn' + CPLD_VERSION_FILE = '/var/run/hw-management/system/cpld{}_version' + CPLD_VERSION_MINOR_FILE = '/var/run/hw-management/system/cpld{}_version_minor' + + CPLD_NUMBER_MAX_LENGTH = 1 + CPLD_PART_NUMBER_MAX_LENGTH = 6 + CPLD_VERSION_MAX_LENGTH = 2 + CPLD_VERSION_MINOR_MAX_LENGTH = 2 + + CPLD_PART_NUMBER_DEFAULT = ZERO + CPLD_VERSION_MINOR_DEFAULT = ZERO + + CPLD_UPDATE_COMMAND = 'cpldupdate --dev {} --print-progress {}' + + MST_DEVICE_PATTERN = '/dev/mst/mt[0-9]*_pci_cr0' + + def __init__(self, idx): + self.idx = idx + self.name = self.COMPONENT_NAME.format(self.idx) + self.description = self.COMPONENT_DESCRIPTION + self.image_ext_name = self.COMPONENT_FIRMWARE_EXTENSION def get_firmware_version(self): @@ -132,17 +260,92 @@ def get_firmware_version(self): Returns: A string containing the firmware version of the component """ - cpld_version_file_list = glob(CPLD_VERSION_FILE_PATTERN) - cpld_version = '' - 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 + part_number_file = self.CPLD_PART_NUMBER_FILE.format(self.idx) + version_file = self.CPLD_VERSION_FILE.format(self.idx) + version_minor_file = self.CPLD_VERSION_MINOR_FILE.format(self.idx) + + part_number = self._read_generic_file(part_number_file, self.CPLD_PART_NUMBER_MAX_LENGTH, True) + version = self._read_generic_file(version_file, self.CPLD_VERSION_MAX_LENGTH) + version_minor = self._read_generic_file(version_minor_file, self.CPLD_VERSION_MINOR_MAX_LENGTH, True) + + if part_number is None: + part_number = self.CPLD_PART_NUMBER_DEFAULT + + if version_minor is None: + version_minor = self.CPLD_VERSION_MINOR_DEFAULT + + part_number = part_number.rstrip(NEWLINE).zfill(self.CPLD_PART_NUMBER_MAX_LENGTH) + version = version.rstrip(NEWLINE).zfill(self.CPLD_VERSION_MAX_LENGTH) + version_minor = version_minor.rstrip(NEWLINE).zfill(self.CPLD_VERSION_MINOR_MAX_LENGTH) + + return "CPLD{}_REV{}{}".format(part_number, version, version_minor) + + + def _get_mst_device(self): + mst_dev_list = glob(self.MST_DEVICE_PATTERN) + if mst_dev_list is None or len(mst_dev_list) != 1: + return None + return mst_dev_list + + + def install_firmware(self, image_path): + """ + Installs firmware to the component + + Args: + image_path: A string, path to firmware image + + Returns: + A boolean, True if install was successful, False if not + + Details: + The command "cpldupdate" is provided to install CPLD. There are two ways to do it: + 1. To burn CPLD via gpio, which is faster but only supported on new systems, like SN3700, ... + 2. To install CPLD via firmware, which is slower but supported on older systems. + This also requires the mst device designated. + "cpldupdate --dev " has the logic of testing whether to update via gpio is supported, + and if so then go this way, otherwise tries updating software via fw. So we take advantage of it to update the CPLD. + By doing so we don't have to mind whether to update via gpio supported, which belongs to hardware details. + + So the procedure should be: + 1. Test whether the file exists + 2. Fetch the mst device name + 3. Update CPLD via executing "cpldupdate --dev " + 4. Check the result + """ + # check whether the image file exists + if not self._check_file_validity(image_path): + return False + + mst_dev_list = self._get_mst_device() + if mst_dev_list is None: + print("ERROR: Failed to get mst device which is required for CPLD updating or multiple device files matched") + return False + + cmdline = self.CPLD_UPDATE_COMMAND.format(mst_dev_list[0], image_path) + success_flag = False + + try: + subprocess.check_call(cmdline, stderr=subprocess.STDOUT, shell=True) + success_flag = True + except subprocess.CalledProcessError as e: + print("ERROR: Failed to upgrade CPLD: rc={}".format(e.returncode)) + + if success_flag: + print("INFO: Refresh or power cycle is required to finish CPLD installation") + + return success_flag + + + @classmethod + def get_component_list(cls): + component_list = [ ] + + cpld_number = cls._read_generic_file(cls.CPLD_NUMBER_FILE, cls.CPLD_NUMBER_MAX_LENGTH) + cpld_number = cpld_number.rstrip(NEWLINE) + + for cpld_idx in xrange(1, int(cpld_number) + 1): + component_list.append(cls(cpld_idx)) + + return component_list diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index 0789f67e4f09..045e5a842993 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -32,7 +32,7 @@ # in most SKUs the file psuX_curr, psuX_volt and psuX_power contain current, voltage and power data respectively. # but there are exceptions which will be handled by the following dictionary -hwsku_dict_psu = {'ACS-MSN3700': 1, 'ACS-MSN3700C': 1, 'ACS-MSN3800': 1} +hwsku_dict_psu = {'ACS-MSN3700': 1, 'ACS-MSN3700C': 1, 'ACS-MSN3800': 1, 'Mellanox-SN3800-D112C8': 1, 'ACS-MSN4700': 1} psu_profile_list = [ # default filename convention { @@ -40,7 +40,7 @@ PSU_VOLTAGE : "power/psu{}_volt", PSU_POWER : "power/psu{}_power" }, - # for 3700, 3700c, 3800 + # for 3700, 3700c, 3800, 4700 { PSU_CURRENT : "power/psu{}_curr", PSU_VOLTAGE : "power/psu{}_volt_out2", diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py index e92884fc3f33..0ed75c26c63a 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py @@ -11,15 +11,69 @@ from python_sdk_api.sx_api import * from sonic_daemon_base.daemon_base import Logger -SDK_SFP_STATE_IN = 0x1 +# SFP status from PMAOS register +# 0x1 plug in +# 0x2 plug out +# 0x3 plug in with error +# 0x4 disabled, at this status SFP eeprom is not accessible, +# and presence status also will be not present, +# so treate it as plug out. +SDK_SFP_STATE_IN = 0x1 SDK_SFP_STATE_OUT = 0x2 +SDK_SFP_STATE_ERR = 0x3 +SDK_SFP_STATE_DIS = 0x4 + +# SFP status that will be handled by XCVRD STATUS_PLUGIN = '1' STATUS_PLUGOUT = '0' -STATUS_UNKNOWN = '2' +STATUS_ERR_I2C_STUCK = '2' +STATUS_ERR_BAD_EEPROM = '3' +STATUS_ERR_UNSUPPORTED_CABLE = '4' +STATUS_ERR_HIGH_TEMP = '5' +STATUS_ERR_BAD_CABLE = '6' + +# SFP status used in this file only, will not expose to XCVRD +# STATUS_ERROR will be mapped to different status according to the error code +STATUS_UNKNOWN = '-1' +STATUS_ERROR = '-2' + +# SFP error code, only valid when SFP at SDK_SFP_STATE_ERR status +# Only 0x2, 0x3, 0x5, 0x6 and 0x7 will block the eeprom access, +# so will only report above errors to XCVRD and other errors will be +# printed to syslog. + +''' +0x0: "Power_Budget_Exceeded", +0x1: "Long_Range_for_non_MLNX_cable_or_module", +0x2: "Bus_stuck", +0x3: "bad_or_unsupported_EEPROM", +0x4: "Enforce_part_number_list", +0x5: "unsupported_cable", +0x6: "High_Temperature", +0x7: "bad_cable", +0x8: "PMD_type_is_not_enabled", +0x9: "[internal]Laster_TEC_failure", +0xa: "[internal]High_current", +0xb: "[internal]High_voltage", +0xd: "[internal]High_power", +0xe: "[internal]Module_state_machine_fault", +0xc: "pcie_system_power_slot_Exceeded" +''' + +# SFP errors that will block eeprom accessing +sdk_sfp_err_type_dict = { + 0x2: STATUS_ERR_I2C_STUCK, + 0x3: STATUS_ERR_BAD_EEPROM, + 0x5: STATUS_ERR_UNSUPPORTED_CABLE, + 0x6: STATUS_ERR_HIGH_TEMP, + 0x7: STATUS_ERR_BAD_CABLE +} sfp_value_status_dict = { - SDK_SFP_STATE_IN: STATUS_PLUGIN, - SDK_SFP_STATE_OUT: STATUS_PLUGOUT, + SDK_SFP_STATE_IN: STATUS_PLUGIN, + SDK_SFP_STATE_OUT: STATUS_PLUGOUT, + SDK_SFP_STATE_ERR: STATUS_ERROR, + SDK_SFP_STATE_DIS: STATUS_PLUGOUT, } # system level event/error @@ -174,7 +228,7 @@ def check_sfp_status(self, port_change, timeout): for fd in read: if fd == self.rx_fd_p.fd: - success, port_list, module_state = self.on_pmpe(self.rx_fd_p) + success, port_list, module_state, error_type = self.on_pmpe(self.rx_fd_p) if not success: logger.log_error("failed to read from {}".format(fd)) break @@ -192,15 +246,23 @@ def check_sfp_status(self, port_change, timeout): found += 1 continue + # If get SFP status error(0x3) from SDK, then need to read the error_type to get the detailed error + if sfp_state == STATUS_ERROR: + if error_type in sdk_sfp_err_type_dict.keys(): + # In SFP at error status case, need to overwrite the sfp_state with the exact error code + sfp_state = sdk_sfp_err_type_dict[error_type] + else: + # For errors don't block the eeprom accessing, we don't report it to XCVRD + logger.log_info("SFP error on port but not blocking eeprom read, error_type {}".format(error_type)) + found +=1 + continue + for port in port_list: logger.log_info("SFP on port {} state {}".format(port, sfp_state)) port_change[port] = sfp_state found += 1 - if found == 0: - return False - else: - return True + return found != 0 def on_pmpe(self, fd_p): ''' on port module plug event handler ''' @@ -228,7 +290,17 @@ def on_pmpe(self, fd_p): port_list_size = pmpe_t.list_size logical_port_list = pmpe_t.log_port_list module_state = pmpe_t.module_state - + error_type = pmpe_t.error_type + module_id = pmpe_t.module_id + + if module_state == SDK_SFP_STATE_ERR: + logger.log_error("Receive PMPE error event on module {}: status {} error type {}".format(module_id, module_state, error_type)) + elif module_state == SDK_SFP_STATE_DIS: + logger.log_info("Receive PMPE disable event on module {}: status {}".format(module_id, module_state)) + elif module_state == SDK_SFP_STATE_IN or module_state == SDK_SFP_STATE_OUT: + logger.log_info("Receive PMPE plug in/out event on module {}: status {}".format(module_id, module_state)) + else: + logger.log_error("Receive PMPE unknown event on module {}: status {}".format(module_id, module_state)) for i in xrange(port_list_size): logical_port = sx_port_log_id_t_arr_getitem(logical_port_list, i) rc = sx_api_port_device_get(self.handle, 1 , 0, port_attributes_list, port_cnt_p) @@ -247,4 +319,4 @@ def on_pmpe(self, fd_p): delete_sx_port_attributes_t_arr(port_attributes_list) delete_uint32_t_p(port_cnt_p) - return status, label_port_list, module_state, + return status, label_port_list, module_state, error_type diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index 6862b3fb258b..903b55404bb3 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -106,7 +106,7 @@ THERMAL_API_GET_HIGH_THRESHOLD ] -hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7} +hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7, 'Mellanox-SN3800-D112C8': 7, 'ACS-MSN4700': 8} thermal_profile_list = [ # 2700 { @@ -231,6 +231,22 @@ ] ) }, + # 4700 + { + THERMAL_DEV_CATEGORY_CPU_CORE:(0, 4), + THERMAL_DEV_CATEGORY_MODULE:(1, 32), + THERMAL_DEV_CATEGORY_PSU:(1, 2), + THERMAL_DEV_CATEGORY_CPU_PACK:(0,1), + THERMAL_DEV_CATEGORY_GEARBOX:(0,0), + THERMAL_DEV_CATEGORY_AMBIENT:(0, + [ + THERMAL_DEV_ASIC_AMBIENT, + THERMAL_DEV_COMEX_AMBIENT, + THERMAL_DEV_PORT_AMBIENT, + THERMAL_DEV_FAN_AMBIENT + ] + ) + } ] def initialize_thermals(sku, thermal_list, psu_list): diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 39942111f26a..275445bd80e0 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.15.2-master +MLNX_SAI_VERSION = SAIRel1.16.2-master export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index d878245e364c..5eb3e143e3da 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit d878245e364ce8d5edd08bbd7120c44c92362235 +Subproject commit 5eb3e143e3da934b30fd9b66126a6ab626f1b15e diff --git a/platform/mellanox/mlnx-ssd-fw-update.mk b/platform/mellanox/mlnx-ssd-fw-update.mk new file mode 100644 index 000000000000..f932e57d2521 --- /dev/null +++ b/platform/mellanox/mlnx-ssd-fw-update.mk @@ -0,0 +1,9 @@ +# ssd update tool + +MLNX_SSD_FW_UPDATE = mlnx-ssd-fw-update.sh +$(MLNX_SSD_FW_UPDATE)_PATH = platform/mellanox/ +SONIC_COPY_FILES += $(MLNX_SSD_FW_UPDATE) + +MLNX_FILES += $(MLNX_SSD_FW_UPDATE) + +export MLNX_SSD_FW_UPDATE diff --git a/platform/mellanox/mlnx-ssd-fw-update.sh b/platform/mellanox/mlnx-ssd-fw-update.sh new file mode 100755 index 000000000000..5163c8e7f8f7 --- /dev/null +++ b/platform/mellanox/mlnx-ssd-fw-update.sh @@ -0,0 +1,727 @@ +#!/bin/bash +######################################################################## +# Copyright (c) 2020 Mellanox Technologies. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the names of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# Alternatively, this software may be distributed under the terms of the +# GNU General Public License ("GPL") version 2 as published by the Free +# Software Foundation. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +#==============================================================================# +#= Global variable # +#= +#===== +VERSION="1.3" +#===== +SWITCH_SSD_DEV="/dev/sda" +UTIL_TITLE="This is MLNX SSD firmware update utility to read and write SSD FW. Version ${VERSION}" +DEPENDECIES=("smartctl" "sha256sum" "tar" "/bin/bash" "gpg" "sed" "realpath" "dirname") +TRUE="0" +FALSE="1" +ERR_MSG="ERR_MSG" +INI_PREFIX="ini_section_" +PUBLIC_CERT_NAME="trusted.gpg" +CHECKSUM_NAME="checksum" +SCRIPT_MODE="RELESE" # RELESE -or- DEBUG +DEBUG_MSG="DEBUG" # remove all instance after script is ready. +#===== +PKG_EXTRACTED=$FALSE +LOGGER_UTIL=$FALSE +SSD_FW_VER="" +SSD_DEVICE_MODEL="" +SSD_SERIAL="" +SSD_SIZE="" +SECTIONS=() +#===== +ARG_IMAGE_FLAG=$FALSE +ARG_IMAGE_VAL="" +ARG_QUERY_FLAG=$FALSE +ARG_YES_FLAG=$FALSE +ARG_POWER_CYCLE_FLAG=$FALSE +ARG_HELP_FLAG=$FALSE +ARG_VERSION_FLAG=$FALSE +ARG_PACKAGE_INFO_FLAG=$FALSE +ARG_UPDATE_FLAG=$FALSE + + + +#==============================================================================# +#= usage function. # +#= +function init_script() { +# check if logger utility supported + if [ -x "$(command -v logger)" ]; then + LOGGER_UTIL=$TRUE + else + LOGGER_UTIL=$FALSE + fi +} + +#==============================================================================# +#= usage function. # +#= +function usage() { + echo + echo -e "$UTIL_TITLE" + echo + echo -e "Usage:" + echo -e "\tmlnx_ssd_fw_update.sh [OPTION]" + echo -e "Commands:" + echo -e "\t-i, --image\t\t Path to SSD FW package" + echo -e "\t-q, --query\t\t Print SSD information (SSD model, serial number, version and size)" + echo -e "\t\t\t\t Combined with image, comparison is made if update is required" + echo -e "\t-p, --package-info\t Get package info" + echo -e "\t-u, --update\t\t Upgrade firmware" + echo -e "\t-y --yes\t\t Assume \"yes\" to all questions" + echo -e "\t-V, --version\t\t Print utility version" + echo -e "\t-h, --help\t\t Show this usage" + echo -e "\t --power-cycle\t Execute power cycle at completion, even if not required" + echo + echo -e "Example:" + echo -e "\tmlnx_ssd_fw_update.sh -q" + echo -e "\tmlnx_ssd_fw_update.sh -q -i mlnx_ssd_fw_package.pkg" + echo -e "\tmlnx_ssd_fw_update.sh -p -i mlnx_ssd_fw_package.pkg" + echo -e "\tmlnx_ssd_fw_update.sh -u -i mlnx_ssd_fw_package.pkg" + echo +} + +#==============================================================================# +#= Log function. # +#= +function LOG_MSG() { + if [ $# -gt 0 ]; then + LOG_STR=$1 + if [[ $# -eq 1 ]]; then + [[ "$LOGGER_UTIL" == "$TRUE" && "$LOG_STR" != "" ]] && logger -t mlnx_ssd_fw_update.sh -p user.notice $(echo "$LOG_STR" | sed 's/\\t//g') + echo -e "$LOG_STR" + elif [[ $# -eq 2 && "$2" == "$ERR_MSG" ]]; then + [[ "$LOGGER_UTIL" == "$TRUE" && "$LOG_STR" != "" ]] && logger -t mlnx_ssd_fw_update.sh -p user.err $(echo "$LOG_STR" | sed 's/\\t//g') + echo -e "$LOG_STR" + elif [[ $# -eq 2 && "$2" == "$SCRIPT_MODE" ]]; then + echo -e "DBG: $LOG_STR" + fi + fi +} + +#==============================================================================# +#= Log function. # +#= +function LOG_MSG_AND_EXIT() { + LOG_MSG "$@" "$ERR_MSG" + erase_extract_package "$extraction_path" + LOG_MSG "Exiting..." + exit 1 +} + +#==============================================================================# +#= This function check if given argument is valid and return boolean result. # +#= +function check_usage() { + local argument_count=$# + + LOG_MSG "Number of argument:$argument_count" ${DEBUG_MSG} + + if [ $# -eq 0 ]; then + LOG_MSG "Error: false usage given." + usage + exit 1 + fi + + while [[ $# -gt 0 ]] + do + key="$1" + + case $key in + -i|--image) + ARG_IMAGE_FLAG=$TRUE + ARG_IMAGE_VAL="$2" + shift # past argument + shift # past value + ;; + -q|--query) + ARG_QUERY_FLAG=$TRUE + shift # past argument + ;; + -y|--yes) + ARG_YES_FLAG=$TRUE + shift # past argument + ;; + -h|--help) + ARG_HELP_FLAG=$TRUE + shift # past argument + ;; + -V|--version) + ARG_VERSION_FLAG=$TRUE + shift # past argument + ;; + -u|--update) + ARG_UPDATE_FLAG=$TRUE + shift # past argument + ;; + -p|--package-info) + ARG_PACKAGE_INFO_FLAG=$TRUE + shift # past argument + ;; + --power-cycle) + ARG_POWER_CYCLE_FLAG=$TRUE + shift # past argument + ;; + *) + LOG_MSG "Error: false usage given." + usage + exit 1 + ;; + esac + done + + if [[ ("$ARG_IMAGE_FLAG" == "$TRUE" && ( $argument_count -lt 3 )) || + ("$ARG_IMAGE_FLAG" == "$TRUE" && ( $argument_count -gt 5 )) || + ("$ARG_PACKAGE_INFO_FLAG" == "$TRUE" && ( $argument_count -ne 3 )) || + ("$ARG_QUERY_FLAG" == "$TRUE" && ( $argument_count -lt 1 )) || + ("$ARG_QUERY_FLAG" == "$TRUE" && ( $argument_count -gt 3 )) || + ("$ARG_HELP_FLAG" == "$TRUE" && ( $argument_count -gt 1 )) || + ("$ARG_VERSION_FLAG" == "$TRUE" && ( $argument_count -gt 1 )) || + ("$ARG_IMAGE_FLAG" == "$TRUE" && "$ARG_IMAGE_VAL" == "") || + ("$ARG_UPDATE_FLAG" == "$TRUE" && "$ARG_IMAGE_FLAG" == "$FALSE") || + ("$ARG_PACKAGE_INFO_FLAG" == "$TRUE" && "$ARG_IMAGE_FLAG" == "$FALSE") || + ("$ARG_POWER_CYCLE_FLAG" == "$TRUE" && "$ARG_UPDATE_FLAG" == "$FALSE") || + ("$ARG_UPDATE_FLAG" == "$TRUE" && "$ARG_PACKAGE_INFO_FLAG" == "$TRUE") ]]; then + + LOG_MSG "Error: false usage given." + usage + exit 1 + fi + +### Debug message remove when script is done. + LOG_MSG "ARG_IMAGE_FLAG = ${ARG_IMAGE_FLAG}" ${DEBUG_MSG} + LOG_MSG "ARG_IMAGE_VAL = ${ARG_IMAGE_VAL}" ${DEBUG_MSG} + LOG_MSG "ARG_QUERY_FLAG = ${ARG_QUERY_FLAG}" ${DEBUG_MSG} + LOG_MSG "ARG_YES_FLAG = ${ARG_YES_FLAG}" ${DEBUG_MSG} + LOG_MSG "ARG_HELP_FLAG = ${ARG_HELP_FLAG}" ${DEBUG_MSG} + LOG_MSG "ARG_VERSION_FLAG = ${ARG_VERSION_FLAG}" ${DEBUG_MSG} + LOG_MSG "ARG_PACKAGE_INFO_FLAG = ${ARG_PACKAGE_INFO_FLAG}" ${DEBUG_MSG} + LOG_MSG "ARG_POWER_CYCLE_FLAG = ${ARG_POWER_CYCLE_FLAG}" ${DEBUG_MSG} + +} + +#==============================================================================# +# This function return SSD fw version using hdparm utility # +# +function get_ssd_fw_version() { + [ $1 ] || { LOG_MSG_AND_EXIT "Wrong usage - ${FUNCNAME[0]}()"; } + + local device_fw_version + device_fw_version=$(smartctl -i $SWITCH_SSD_DEV | grep -Po "Firmware Version: +\K[^,]+") + LOG_MSG "device_fw_version: $device_fw_version" ${DEBUG_MSG} + eval $1='$device_fw_version' +} + +#==============================================================================# +# This function return SSD device model using hdparm utility # +# +function get_ssd_device_model() { + [ $1 ] || { LOG_MSG_AND_EXIT "Wrong usage - ${FUNCNAME[0]}()"; } + + local device_model_name + device_model_name=$(smartctl -i $SWITCH_SSD_DEV | grep -Po "Device Model: +\K[^,]+") + LOG_MSG "device_model_name: $device_model_name" ${DEBUG_MSG} + eval $1='$device_model_name' +} + +#==============================================================================# +# This function return SSD size using hdparm utility # +# +function get_ssd_size() { + [ $1 ] || { LOG_MSG_AND_EXIT "Wrong usage - ${FUNCNAME[0]}()"; } + + local device_size + device_size=$(smartctl -i $SWITCH_SSD_DEV | grep -Po "User Capacity:.+bytes \[\K[^ ]+") + LOG_MSG "device_size: $device_size" ${DEBUG_MSG} + eval $1='$device_size' +} + +#==============================================================================# +# This function return SSD serial using hdparm utility # +# +function get_ssd_serial() { + [ $1 ] || { LOG_MSG_AND_EXIT "Wrong usage - ${FUNCNAME[0]}()"; } + + local device_serial + device_serial=$(smartctl -i $SWITCH_SSD_DEV | grep -Po "Serial Number: +\K[^,]+") + LOG_MSG "device_serial: $device_serial" ${DEBUG_MSG} + eval $1='$device_serial' +} + +#==============================================================================# +#= This function check if given argument is valid and return boolean result. # +#= +function get_ssd_info() { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + get_ssd_fw_version SSD_FW_VER + get_ssd_device_model SSD_DEVICE_MODEL + get_ssd_serial SSD_SERIAL + get_ssd_size SSD_SIZE +} + +#==============================================================================# +#= This function check if given argument is valid and return boolean result. # +#= +function check_tool_dependencies() { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + for i in "${!DEPENDECIES[@]}" + do + if [ ! -x "$(command -v ${DEPENDECIES[$i]})" ]; then + LOG_MSG_AND_EXIT "Error: This tool require the following utils to be installed ${DEPENDECIES[$i]}" + fi + done +} + +#==============================================================================# +#= This function parse package ini file and declare it attributes # +#= +function ini_parser { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + + local filename="$1" + LOG_MSG "filename:$filename" ${DEBUG_MSG} + + shopt -p extglob &> /dev/null + CHANGE_EXTGLOB=$? + if [ $CHANGE_EXTGLOB = 1 ] + then + shopt -s extglob + fi + ini="$(<$filename)" # read the file + ini=${ini//$'\r'/} # remove linefeed i.e dos2unix + ini="${ini//[/\\[}" + ini="${ini//]/\\]}" + IFS=$'\n' && ini=( ${ini} ) # convert to line-array + ini=( ${ini[*]//\)/\\\)} ) # append / before any parenthesis + ini=( ${ini[*]//\(/\\\(} ) # append / before any parenthesis + ini=( ${ini[*]/#*([[:space:]]);*/} ) + ini=( ${ini[*]/#*([[:space:]])\#*/} ) + ini=( ${ini[*]/#+([[:space:]])/} ) # remove init whitespace + ini=( ${ini[*]/%+([[:space:]])/} ) # remove ending whitespace + ini=( ${ini[*]/*([[:space:]])=*([[:space:]])/=} ) # remove whitespace around = + ini=( ${ini[*]/#\\[/\}$'\n'"$INI_PREFIX"} ) # set section prefix + ini=( ${ini[*]/%\\]/ \(} ) # convert text2function (1) + ini=( ${ini[*]/=/=\( } ) # convert item to array + ini=( ${ini[*]/%/ \)} ) # close array parenthesis + ini=( ${ini[*]/%\\ \)/ \\} ) # the multiline trick + ini=( ${ini[*]/%\( \)/\(\) \{} ) # convert text2function (2) + ini=( ${ini[*]/%\} \)/\}} ) # remove extra parenthesis + ini=( ${ini[*]/%\{/\{$'\n''ini_unset ${FUNCNAME/#'$INI_PREFIX'}'$'\n'} ) # clean previous definition of section + ini[0]="" # remove first element + ini[${#ini[*]} + 1]='}' # add the last brace + eval "$(echo "${ini[*]}")" # eval the result + [ $? -ne 0 ] && LOG_MSG_AND_EXIT "Error: failed to parse package content." + SECTIONS="$(echo ${ini[*]} | grep -Po "$INI_PREFIX+\K[\w]+")" + if [ $CHANGE_EXTGLOB = 1 ] + then + shopt -u extglob + fi +} + +#==============================================================================# +#= This function unset parse ini section and variables # +#= +function ini_unset { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + SECTION=$1 + OLDIFS="$IFS" + IFS=' '$'\n' + if [ -z "$SECTION" ] + then + fun="$(declare -F)" + else + fun="$(declare -F $INI_PREFIX$SECTION)" + if [ -z "$fun" ] + then + echo "section $SECTION not found" 1>&2 + return + fi + fi + fun="${fun//declare -f/}" + for f in $fun; do + [ "${f#$INI_PREFIX}" == "${f}" ] && continue + item="$(declare -f ${f})" + item="${item##*\{}" # remove function definition + item="${item##*FUNCNAME*$INI_PREFIX\};}" # remove clear section + item="${item/\}}" # remove function close + item="${item%)*}" # remove everything after parenthesis + item="${item});" # add close parenthesis + vars="" + while [ "$item" != "" ] + do + newvar="${item%%=*}" # get item name + vars="$vars $newvar" # add name to collection + item="${item#*;}" # remove readed line + done + for var in $vars; do + unset $var + done + done + IFS="$OLDIFS" +} + +#==============================================================================# +#= This function check package signing and returns back true or false # +#= +function check_package_signing() { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + + [ $1 ] || { LOG_MSG_AND_EXIT "Wrong usage - ${FUNCNAME[0]}()"; } + + local package_path=$1 + local checksum_unsigned_file="$package_path/$CHECKSUM_NAME" + local checksum_signed_file="$package_path/$CHECKSUM_NAME.sig" + local public_cert_file="$package_path/$PUBLIC_CERT_NAME" + +### Check if unsigned checksum file exists + [ ! -f "$checksum_unsigned_file" ] && LOG_MSG_AND_EXIT "Error: fail to find unsigned checksum file to verify package signing." + +### Check if signed checksum file exists + [ ! -f "$checksum_signed_file" ] && LOG_MSG_AND_EXIT "Error: fail to find sign checksum file to verify package signing." + +### Check if public key exists + [ ! -f "$public_cert_file" ] && LOG_MSG_AND_EXIT "Error: fail to find public certificate to verify package signing." + + + LOG_MSG "public_cert_file: ${public_cert_file}" ${DEBUG_MSG} + LOG_MSG "checksum_signed_file: ${checksum_signed_file}" ${DEBUG_MSG} + LOG_MSG "checksum_unsigned_file: ${checksum_unsigned_file}" ${DEBUG_MSG} + + gpg --keyring "$public_cert_file" --verify "$checksum_signed_file" "$checksum_unsigned_file" > /dev/null 2>&1 + [ $? -ne 0 ] && LOG_MSG_AND_EXIT "Error: fault package signing." + + LOG_MSG "cd into: ${package_path}" ${DEBUG_MSG} + cd $package_path > /dev/null 2>&1 + sha256sum -c $CHECKSUM_NAME > /dev/null 2>&1 + [ $? -ne 0 ] && LOG_MSG_AND_EXIT "Error: fault package SHA signing, file has been compromised" + LOG_MSG "backing back:" ${DEBUG_MSG} + cd - > /dev/null 2>&1 + LOG_MSG "exiting:" ${DEBUG_MSG} + +} + +#==============================================================================# +#= This function prints supported SSD from package ini # +#= +function string_supported_model() { + + local section=$1 + + if [[ ! -z "${Vendor[*]}" ]] && [[ ! -z "${SSD_FW_Model[*]}" ]] && [[ ! -z "${SSD_FW_Version[*]}" ]] \ + && [[ ! -z "${SSD_Size[*]}" ]] && [[ ! -z ${Shutdown_Policy[*]} ]]; then + printf 'o %-10s | %-30s | %-12s | %-6sGB | %-7s |\n' \ + "$( IFS=$'\n'; echo "${Vendor[@]}" )" "$( IFS=$'\n'; echo "${SSD_FW_Model[@]}" )" \ + "${SSD_FW_Version[@]}" "${SSD_Size[@]}" "${Shutdown_Policy[@],,}" + fi + +} + +#==============================================================================# +#= This function extract SSD FW package into /tmp # +#= +function extract_package() { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + + local filename=$1 + LOG_MSG "filename:$filename" ${DEBUG_MSG} +### Check if file exists + [ ! -f $filename ] && LOG_MSG_AND_EXIT "Error: given file ($filename) not found." +### Check if tmp available + [ ! -d "/tmp" ] && LOG_MSG_AND_EXIT "Error: directory /tmp DOES NOT exists." + + local base_filename="${filename##*/}" + local folder_name="/tmp/""${base_filename%%.*}" + +### Check if full path available + if [ -d $folder_name ]; then + LOG_MSG "Path:$folder_name already exists, removing folder." ${DEBUG_MSG} + rm -rf ${folder_name} + [ $? -ne 0 ] && LOG_MSG_AND_EXIT "Error: folder:$folder_name is already in use and can't be overwrite, please remove it and retry." + fi + + mkdir ${folder_name} && tar xf ${filename} -C ${folder_name} --strip-components 1 --warning=no-timestamp > /dev/null 2>&1 + #tar -xf $filename --directory /tmp/ --warning=no-timestamp > /dev/null 2>&1 +### Check if untar succeed. + [ $? -ne 0 ] && LOG_MSG_AND_EXIT "Error: fail to extract given package ($filename)." + +### return the path file extraction is + # local base_filename="${filename##*/}" + # local folder_name="/tmp/""${base_filename%%.*}" + eval $2="$folder_name" + + PKG_EXTRACTED=$TRUE + + check_package_signing $folder_name + + LOG_MSG "successfully untar file." ${DEBUG_MSG} +} + +#==============================================================================# +#= This function extract SSD FW package into /tmp # +#= +function erase_extract_package() { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + + [[ "$PKG_EXTRACTED" == "$FALSE" ]] && return + + local folder_name=$1 + + LOG_MSG "folder_name: $folder_name" ${DEBUG_MSG} + +### Check if folder exists + if [ ! -d "$folder_name" ]; then + LOG_MSG "Error: directory $folder_name DOES NOT exists." "$ERR_MSG" + LOG_MSG "Exiting..." + exit 1 + fi + rm -rf $folder_name +### Check if untar succeed. + if [ $? -ne 0 ]; then + LOG_MSG "Error: fail to delete $folder_name folder." "$ERR_MSG" + LOG_MSG "Exiting..." + exit 1 + fi + + PKG_EXTRACTED=$FALSE + LOG_MSG "successfully removed folder:$folder_name" ${DEBUG_MSG} +} + + +#==============================================================================# +#= This function returns back ini section array. +#= +function call_ini_section() { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + + local ini_section=$1 + LOG_MSG "ini_section:$ini_section" ${DEBUG_MSG} + + [[ -z "$ini_section" ]] && LOG_MSG_AND_EXIT "Error: given INI section is null." + [[ -z "$(declare -F "$INI_PREFIX$ini_section")" ]] && LOG_MSG_AND_EXIT "Error: $ini_section section is missing in INI file." + + eval "$(echo "$INI_PREFIX$ini_section")" # call given section function. +} + +#==============================================================================# +#= This function prints ssd info +#= +function print_ssd_info() { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + + local argument_count=$# + + if [ $argument_count -eq 2 ]; then + local newer_fw_version=$1 + local power_policy=$2 + LOG_MSG "Device Model\t\t : $SSD_DEVICE_MODEL" + LOG_MSG "Serial Number\t\t : $SSD_SERIAL" + LOG_MSG "User Capacity\t\t : $SSD_SIZE GB" + LOG_MSG "Current Firmware Version : $SSD_FW_VER" + LOG_MSG "Available Firmware Version : $Newer_FW_Version" + LOG_MSG "Power Cycle Required\t : $power_policy" + LOG_MSG "Upgrade Required\t : yes" + elif [ $argument_count -eq 1 ]; then + local _upgrade_require=$1 + LOG_MSG "Device Model\t : $SSD_DEVICE_MODEL" + LOG_MSG "Serial Number\t : $SSD_SERIAL" + LOG_MSG "User Capacity\t : $SSD_SIZE GB" + LOG_MSG "Firmware Version : $SSD_FW_VER" + LOG_MSG "Upgrade Required : $_upgrade_require" + else + LOG_MSG "Device Model\t : $SSD_DEVICE_MODEL" + LOG_MSG "Serial Number\t : $SSD_SERIAL" + LOG_MSG "User Capacity\t : $SSD_SIZE GB" + LOG_MSG "Firmware Version : $SSD_FW_VER" + fi +} + +# Main +# ------------------------------------------------------------------------------ +init_script +check_usage "$@" + +# show help +if [ $ARG_HELP_FLAG == $TRUE ]; then + usage + exit 0 +# show version +elif [ $ARG_VERSION_FLAG == $TRUE ]; then + echo $UTIL_TITLE + exit 0 +# show SSD info +elif [ $ARG_QUERY_FLAG == $TRUE ]; then + match_found=$FALSE + check_tool_dependencies + get_ssd_info + + if [ $ARG_IMAGE_FLAG == $TRUE ]; then + extract_package $ARG_IMAGE_VAL extraction_path + ini_parser "$extraction_path/list.ini" + + for section in $SECTIONS; do + if [[ $section != "main" ]]; then + call_ini_section $section + if [[ "$SSD_DEVICE_MODEL" == "$( IFS=$'\n'; echo "${SSD_FW_Model[@]}" )" ]] && \ + [[ "$SSD_FW_VER" == "${SSD_FW_Version[@]}" ]] && \ + [[ "$SSD_SIZE" == "${SSD_Size[@]}" ]]; then + + match_found=$TRUE + break + fi + ini_unset $section + fi + done + + erase_extract_package "$extraction_path" + if [[ "$match_found" == "$FALSE" ]]; then + #LOG_MSG "SSD FW upgrade not require, based on given package latest version is in used." + print_ssd_info "no" + echo -e "" + exit 0 + fi + fi + + if [[ "$match_found" == "$TRUE" ]]; then + print_ssd_info $Newer_FW_Version ${Shutdown_Policy[0],,} + erase_extract_package "$extraction_path" + else + print_ssd_info + fi + + echo -e "" + + exit 0 +# show package version +elif [ $ARG_PACKAGE_INFO_FLAG == $TRUE ]; then + check_tool_dependencies + extract_package $ARG_IMAGE_VAL extraction_path + # 2. check signing + ini_parser "$extraction_path/list.ini" + + call_ini_section "main" + LOG_MSG "Package Name: $ARG_IMAGE_VAL" + [[ ! -z ${description[@]} ]] && LOG_MSG "Description: ${description[@]}" + [[ ! -z ${version[@]} ]] && LOG_MSG "Version: ${version[@]}" + [[ ! -z ${release_date[@]} ]] && LOG_MSG "Release Date: ${release_date[@]}" + LOG_MSG "Supported SSDs:" + LOG_MSG " Vendor | Model | FW ver | Size | Pwr Cyc Req |" + LOG_MSG "=============|================================|==============|==========|=============|" + for section in $SECTIONS; do + if [[ "$section" != "main" ]]; then + call_ini_section $section + supported_model=$(string_supported_model $section) + LOG_MSG "$supported_model" + ini_unset $section + fi + done + echo -e "" + erase_extract_package "$extraction_path" + exit 0 +# operate SSD fw update +elif [ $ARG_UPDATE_FLAG == $TRUE ]; then + check_tool_dependencies + get_ssd_info + extract_package $ARG_IMAGE_VAL extraction_path + # 2. check signing + UPDATE_DONE=$FALSE + ini_parser "$extraction_path/list.ini" + for section in $SECTIONS; do + if [[ $section != "main" ]]; then + call_ini_section $section + if [[ "$SSD_DEVICE_MODEL" == "$( IFS=$'\n'; echo "${SSD_FW_Model[@]}" )" ]] && \ + [[ "$SSD_FW_VER" == "${SSD_FW_Version[@]}" ]] && \ + [[ "$SSD_SIZE" == "${SSD_Size[@]}" ]]; then + UPDATE_DONE=$TRUE + + power_policy=${Shutdown_Policy[0],,} + LOG_MSG "Power policy:$power_policy" ${DEBUG_MSG} + print_ssd_info $Newer_FW_Version ${Shutdown_Policy[0],,} + echo -e "" + #[[ "yes" == "$power_policy" ]] && LOG_MSG "PLEASE NOTE: System will power-cycle automatically once SSD FW Update complete!" + [[ "yes" == "$power_policy" || "$ARG_POWER_CYCLE_FLAG" == "$TRUE" ]] && LOG_MSG "Please note: Once SSD FW Update process ends, system will power-cycle automaticly and it will take up to 1 minute to access it back." + + # Prompt approval for FW update if ignore in case "yes" flag is on. + if [[ "$ARG_YES_FLAG" == "$FALSE" ]]; then + read -p "Do you want to continue? [Y/N]" -n 1 -r + echo # (optional) move to a new line + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + LOG_MSG_AND_EXIT "Aborting..." + exit 0 + fi + fi + + # Check FWUpgrade scripts exists & if so call it. + ssd_script_name=$Update_Script + ssd_script_path="${extraction_path}/${section}/${ssd_script_name}" + LOG_MSG "ssd_script_path: $ssd_script_path" ${DEBUG_MSG} + if [ ! -f $ssd_script_path ]; then + LOG_MSG_AND_EXIT "Error: fail to call upgrade script ($ssd_script_path)!" + fi + ( + cd "${extraction_path}/${section}" > /dev/null 2>&1 || exit + /bin/bash "$ssd_script_path" "${extraction_path}/${section}" + #cd - > /dev/null 2>&1 || exit + ) + if [ $? -ne 0 ]; then + LOG_MSG_AND_EXIT "Error: SSD FW update failed." + else + LOG_MSG "SSD FW update completed successfully." + + if [ $ARG_POWER_CYCLE_FLAG == $TRUE ]; then + LOG_MSG "Execute power cycle..." + sleep 1 + sync + power_cycle_script="${extraction_path}/common/mlnx_shutdown.sh" + [ ! -f $power_cycle_script ]&& LOG_MSG_AND_EXIT "Error: failed to initiate power cycle." + ($power_cycle_script "-s") + [ $? -ne 0 ] && LOG_MSG_AND_EXIT "Error: failed to power cycle the system automatically." + erase_extract_package "$extraction_path" + + fi + + fi + + break # Exit the for loop + fi + ini_unset $section + fi + done + if [ $UPDATE_DONE == $FALSE ]; then + LOG_MSG "SSD FW upgrade not require, based on given package latest version is in used." + print_ssd_info "no" + fi + + echo -e "" + erase_extract_package "$extraction_path" + exit 0 +fi + +exit 0 diff --git a/platform/mellanox/one-image.mk b/platform/mellanox/one-image.mk index 2946ae53f47b..0f69b7335bf1 100644 --- a/platform/mellanox/one-image.mk +++ b/platform/mellanox/one-image.mk @@ -11,5 +11,5 @@ $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.g else $(SONIC_ONE_IMAGE)_DOCKERS = $(SONIC_INSTALL_DOCKER_IMAGES) endif -$(SONIC_ONE_IMAGE)_FILES += $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) $(MLNX_FFB_SCRIPT) $(ISSU_VERSION_FILE) +$(SONIC_ONE_IMAGE)_FILES += $(MLNX_FILES) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/mellanox/rules.mk b/platform/mellanox/rules.mk index dd10cefda571..bdb4e955c2d4 100644 --- a/platform/mellanox/rules.mk +++ b/platform/mellanox/rules.mk @@ -12,6 +12,8 @@ include $(PLATFORM_PATH)/libsaithrift-dev.mk include $(PLATFORM_PATH)/docker-ptf-mlnx.mk include $(PLATFORM_PATH)/mlnx-ffb.mk include $(PLATFORM_PATH)/issu-version.mk +include $(PLATFORM_PATH)/mlnx-onie-fw-update.mk +include $(PLATFORM_PATH)/mlnx-ssd-fw-update.mk SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index c08b5bb3810f..1d7da850581f 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit c08b5bb3810fe7da2811622aa7003ac9cc95344b +Subproject commit 1d7da850581ff0dd79990ae1c5bcb174d4272267 diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 55a5b08bba31..3b2e9a8f30c8 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ -MLNX_SDK_VERSION = 4.3.2904 +MLNX_SDK_VERSION = 4.4.0880 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) diff --git a/platform/nephos/docker-syncd-nephos-rpc.mk b/platform/nephos/docker-syncd-nephos-rpc.mk index dafc43b3e7e3..39240c1913e4 100644 --- a/platform/nephos/docker-syncd-nephos-rpc.mk +++ b/platform/nephos/docker-syncd-nephos-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_NEPHOS_RPC = docker-syncd-nephos-rpc.gz $(DOCKER_SYNCD_NEPHOS_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-nephos-rpc -$(DOCKER_SYNCD_NEPHOS_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_NEPHOS_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_NEPHOS_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/nephos/docker-syncd-nephos.mk b/platform/nephos/docker-syncd-nephos.mk index 6829c91c67aa..67bad252870a 100644 --- a/platform/nephos/docker-syncd-nephos.mk +++ b/platform/nephos/docker-syncd-nephos.mk @@ -15,4 +15,4 @@ $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += npx_diag:/usr/bin/npx_diag - +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd b/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd new file mode 100644 index 000000000000..0b9ec741cd57 --- /dev/null +++ b/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd @@ -0,0 +1,11 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +## dsserve +############################################################################### +check process syncd matching "/usr/bin/syncd" + if does not exist for 5 times within 5 cycles then alert + +check process dsserve matching "/usr/bin/dsserve /usr/bin/syncd" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/nephos/docker-syncd-nephos/supervisord.conf b/platform/nephos/docker-syncd-nephos/supervisord.conf index c823ab5680ef..0c6285d46ae0 100644 --- a/platform/nephos/docker-syncd-nephos/supervisord.conf +++ b/platform/nephos/docker-syncd-nephos/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/platform/nephos/nephos-modules.mk b/platform/nephos/nephos-modules.mk index b76141b40663..50a2d0e5c080 100644 --- a/platform/nephos/nephos-modules.mk +++ b/platform/nephos/nephos-modules.mk @@ -1,6 +1,6 @@ # Nephos Platform modules -VERSION = 1.0.0 +VERSION = 1.0.1 ifneq ($(NEPHOS_SAI_DEB_LOCAL_URL), ) SDK_FROM_LOCAL = y @@ -9,7 +9,7 @@ SDK_FROM_LOCAL = n endif SDK_VERSION = 3.0.0 -LINUX_VER = 4.9.0-9-2 +LINUX_VER = 4.9.0-11-2 SDK_COMMIT_ID = 529202 ifeq ($(SAI_FROM_LOCAL), y) diff --git a/platform/nephos/nephos-modules/debian/changelog b/platform/nephos/nephos-modules/debian/changelog index 3de2bd045efd..94c7aa7d3915 100644 --- a/platform/nephos/nephos-modules/debian/changelog +++ b/platform/nephos/nephos-modules/debian/changelog @@ -1,5 +1,11 @@ +nephos-modules (1.0.1) unstable; urgency=low + + * Upgrade ko version to 3.0.0 + +-- Support Tue, 17 Mar 2020 15:54:00 +0800 + nephos-modules (1.0.0) unstable; urgency=low * Initial release - -- Support Fri, 15 Mar 2019 15:54:00 +0800 +-- Support Fri, 15 Mar 2019 15:54:00 +0800 diff --git a/platform/nephos/nephos-modules/debian/control b/platform/nephos/nephos-modules/debian/control index f5e6e00d13c0..3d06ca971f89 100644 --- a/platform/nephos/nephos-modules/debian/control +++ b/platform/nephos/nephos-modules/debian/control @@ -1,12 +1,12 @@ Source: nephos-modules Section: main Priority: extra -Maintainer: support +Maintainer: support Build-Depends: debhelper (>= 8.0.0), bzip2 Standards-Version: 3.9.3 Package: nephos-modules Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for nephos asic diff --git a/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9.0-9-2-amd64 b/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9-amd64 similarity index 92% rename from platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9.0-9-2-amd64 rename to platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9-amd64 index 366ca6b08456..a6deb4217a95 100755 --- a/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9.0-9-2-amd64 +++ b/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9-amd64 @@ -45,7 +45,7 @@ force-reload|restart) ;; *) - echo "Usage: /etc/init.d/nps-modules-4.9.0-9-2-amd64.init {start|stop}" + echo "Usage: /etc/init.d/nps-modules-4.9.0-11-2-amd64.init {start|stop}" exit 1 ;; esac diff --git a/platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-9-2-amd64.service b/platform/nephos/nephos-modules/modules/service/nps-modules-4.9-amd64.service similarity index 60% rename from platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-9-2-amd64.service rename to platform/nephos/nephos-modules/modules/service/nps-modules-4.9-amd64.service index 246226ea9d40..fc45a597d74c 100644 --- a/platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-9-2-amd64.service +++ b/platform/nephos/nephos-modules/modules/service/nps-modules-4.9-amd64.service @@ -5,8 +5,8 @@ Before=syncd.service [Service] Type=oneshot -ExecStart=-/etc/init.d/nps-modules-4.9.0-9-2-amd64 start -ExecStop=-/etc/init.d/nps-modules-4.9.0-9-2-amd64 stop +ExecStart=-/etc/init.d/nps-modules-4.9-amd64 start +ExecStop=-/etc/init.d/nps-modules-4.9-amd64 stop RemainAfterExit=yes [Install] diff --git a/platform/nephos/nephos-modules/modules/src/hal_tau_pkt_knl.c b/platform/nephos/nephos-modules/modules/src/hal_tau_pkt_knl.c index b386da63e247..a67b1d5f8868 100755 --- a/platform/nephos/nephos-modules/modules/src/hal_tau_pkt_knl.c +++ b/platform/nephos/nephos-modules/modules/src/hal_tau_pkt_knl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -45,6 +45,9 @@ /* netif */ #include #include +#if defined(NETIF_EN_NETLINK) +#include +#endif #include /* nps_sdk */ @@ -69,19 +72,20 @@ /* This flag value will be specified when user inserts kernel module. */ -#define HAL_TAU_PKT_DBG_ERR (0x1 << 0) -#define HAL_TAU_PKT_DBG_TX (0x1 << 1) -#define HAL_TAU_PKT_DBG_RX (0x1 << 2) -#define HAL_TAU_PKT_DBG_INTF (0x1 << 3) -#define HAL_TAU_PKT_DBG_PROFILE (0x1 << 4) -#define HAL_TAU_PKT_DBG_COMMON (0x1 << 5) +#define HAL_TAU_PKT_DBG_ERR (0x1UL << 0) +#define HAL_TAU_PKT_DBG_TX (0x1UL << 1) +#define HAL_TAU_PKT_DBG_RX (0x1UL << 2) +#define HAL_TAU_PKT_DBG_INTF (0x1UL << 3) +#define HAL_TAU_PKT_DBG_PROFILE (0x1UL << 4) +#define HAL_TAU_PKT_DBG_COMMON (0x1UL << 5) +#define HAL_TAU_PKT_DBG_NETLINK (0x1UL << 6) /* Will be set when inserting kernel module */ -static UI32_T dbg_flag = 0; +UI32_T ext_dbg_flag = 0; #define HAL_TAU_PKT_DBG(__flag__, ...) do \ { \ - if (0 != ((__flag__) & (dbg_flag))) \ + if (0 != ((__flag__) & (ext_dbg_flag))) \ { \ osal_printf(__VA_ARGS__); \ } \ @@ -113,15 +117,15 @@ typedef struct static HAL_TAU_PKT_INTR_VEC_T _hal_tau_pkt_intr_vec[] = { - { /* 0: PDMA_ERR */ 1 << 0, 0x0, 0 }, - { /* 1: TX_CH0 */ 1 << 28, 0x0, 0 }, - { /* 2: TX_CH1 */ 1 << 29, 0x0, 0 }, - { /* 3: TX_CH2 */ 1 << 30, 0x0, 0 }, - { /* 4: TX_CH3 */ 1 << 31, 0x0, 0 }, - { /* 5: RX_CH0 */ 1 << 12, 0x0, 0 }, - { /* 6: RX_CH1 */ 1 << 13, 0x0, 0 }, - { /* 7: RX_CH2 */ 1 << 14, 0x0, 0 }, - { /* 8: RX_CH3 */ 1 << 15, 0x0, 0 }, + { /* 0: PDMA_ERR */ 1UL << 0, 0x0, 0 }, + { /* 1: TX_CH0 */ 1UL << 28, 0x0, 0 }, + { /* 2: TX_CH1 */ 1UL << 29, 0x0, 0 }, + { /* 3: TX_CH2 */ 1UL << 30, 0x0, 0 }, + { /* 4: TX_CH3 */ 1UL << 31, 0x0, 0 }, + { /* 5: RX_CH0 */ 1UL << 12, 0x0, 0 }, + { /* 6: RX_CH1 */ 1UL << 13, 0x0, 0 }, + { /* 7: RX_CH2 */ 1UL << 14, 0x0, 0 }, + { /* 8: RX_CH3 */ 1UL << 15, 0x0, 0 }, }; /***************************************************************************** @@ -136,9 +140,10 @@ static HAL_TAU_PKT_INTR_VEC_T _hal_tau_pkt_intr_vec[] = #define HAL_TAU_PKT_ALLOC_MEM_RETRY_SLEEP() osal_sleepThread(1000) /* us */ /* Network Device Definitions */ -#define HAL_TAU_PKT_TX_TIMEOUT (6*HZ) +/* In case that the watchdog alarm during warm-boot if intf isn't killed */ +#define HAL_TAU_PKT_TX_TIMEOUT (30*HZ) #define HAL_TAU_PKT_MAX_ETH_FRAME_SIZE (HAL_TAU_PKT_RX_MAX_LEN) -#define HAL_TAU_PKT_MAX_PORT_NUM (HAL_TAU_PORT_NUM + 1) /* CPU port */ +#define HAL_TAU_PKT_MAX_PORT_NUM (HAL_PORT_NUM + 1) /* CPU port */ #define HAL_TAU_PKT_NET_PROFILE_NUM_MAX (256) @@ -199,10 +204,10 @@ typedef struct NPS_ISRLOCK_ID_T intr_lock; UI32_T intr_bitmap; -#define HAL_TAU_PKT_INIT_DRV (1 << 0) -#define HAL_TAU_PKT_INIT_TASK (1 << 1) -#define HAL_TAU_PKT_INIT_INTR (1 << 2) -#define HAL_TAU_PKT_INIT_RX_START (1 << 3) +#define HAL_TAU_PKT_INIT_DRV (1UL << 0) +#define HAL_TAU_PKT_INIT_TASK (1UL << 1) +#define HAL_TAU_PKT_INIT_INTR (1UL << 2) +#define HAL_TAU_PKT_INIT_RX_START (1UL << 3) /* a bitmap to record the init status */ UI32_T init_flag; @@ -255,6 +260,10 @@ typedef struct BOOL_T running; /* TRUE when Init txTask * FALSE when Destroy txTask */ + /* to block net intf Tx in driver level since netif_tx_disable() + * cannot always prevent intf from Tx in time + */ + BOOL_T net_tx_allowed; } HAL_TAU_PKT_TX_CB_T; @@ -312,6 +321,9 @@ typedef enum { HAL_TAU_PKT_DEST_NETDEV = 0, HAL_TAU_PKT_DEST_SDK, +#if defined(NETIF_EN_NETLINK) + HAL_TAU_PKT_DEST_NETLINK, +#endif HAL_TAU_PKT_DEST_DROP, HAL_TAU_PKT_DEST_LAST } HAL_TAU_PKT_DEST_T; @@ -1215,7 +1227,158 @@ hal_tau_pkt_setPortAttr( return (NPS_E_OK); } +static void +_hal_tau_pkt_lockRxChannelAll( + const UI32_T unit) +{ + UI32_T rch; + HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma; + + for (rch = 0; rch < HAL_TAU_PKT_RX_CHANNEL_LAST; rch++) + { + ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, rch); + osal_takeSemaphore(&ptr_rx_pdma->sema, NPS_SEMAPHORE_WAIT_FOREVER); + } +} + +static void +_hal_tau_pkt_unlockRxChannelAll( + const UI32_T unit) +{ + UI32_T rch; + HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma; + + for (rch = 0; rch < HAL_TAU_PKT_RX_CHANNEL_LAST; rch++) + { + ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, rch); + osal_giveSemaphore(&ptr_rx_pdma->sema); + } +} + +#if defined(NETIF_EN_NETLINK) + +static NPS_ERROR_NO_T +_hal_tau_pkt_setIntfProperty( + const UI32_T unit, + HAL_TAU_PKT_NL_IOCTL_COOKIE_T *ptr_cookie) +{ + UI32_T intf_id; + NETIF_NL_INTF_PROPERTY_T property; + UI32_T param0; + UI32_T param1; + NPS_ERROR_NO_T rc; + + osal_io_copyFromUser(&intf_id, &ptr_cookie->intf_id, sizeof(UI32_T)); + osal_io_copyFromUser(&property, &ptr_cookie->property, sizeof(NETIF_NL_INTF_PROPERTY_T)); + osal_io_copyFromUser(¶m0, &ptr_cookie->param0, sizeof(UI32_T)); + osal_io_copyFromUser(¶m1, &ptr_cookie->param1, sizeof(UI32_T)); + + _hal_tau_pkt_lockRxChannelAll(unit); + + rc = netif_nl_setIntfProperty(unit, intf_id, property, param0, param1); + + _hal_tau_pkt_unlockRxChannelAll(unit); + + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + return (rc); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_getIntfProperty( + const UI32_T unit, + HAL_TAU_PKT_NL_IOCTL_COOKIE_T *ptr_cookie) +{ + UI32_T intf_id; + NETIF_NL_INTF_PROPERTY_T property; + UI32_T param0; + UI32_T param1; + NPS_ERROR_NO_T rc; + + osal_io_copyFromUser(&intf_id, &ptr_cookie->intf_id, sizeof(UI32_T)); + osal_io_copyFromUser(&property, &ptr_cookie->property, sizeof(NETIF_NL_INTF_PROPERTY_T)); + osal_io_copyFromUser(¶m0, &ptr_cookie->param0, sizeof(UI32_T)); + + rc = netif_nl_getIntfProperty(unit, intf_id, property, ¶m0, ¶m1); + + osal_io_copyToUser(&ptr_cookie->param0, ¶m0, sizeof(UI32_T)); + osal_io_copyToUser(&ptr_cookie->param1, ¶m1, sizeof(UI32_T)); + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + return (rc); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_createNetlink( + const UI32_T unit, + HAL_TAU_PKT_NL_IOCTL_COOKIE_T *ptr_cookie) +{ + NETIF_NL_NETLINK_T netlink; + UI32_T netlink_id; + NPS_ERROR_NO_T rc; + + osal_io_copyFromUser(&netlink, &ptr_cookie->netlink, sizeof(NETIF_NL_NETLINK_T)); + + _hal_tau_pkt_lockRxChannelAll(unit); + + rc = netif_nl_createNetlink(unit, &netlink, &netlink_id); + + _hal_tau_pkt_unlockRxChannelAll(unit); + + osal_io_copyToUser(&ptr_cookie->netlink.id, &netlink_id, sizeof(UI32_T)); + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + return (rc); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_destroyNetlink( + const UI32_T unit, + HAL_TAU_PKT_NL_IOCTL_COOKIE_T *ptr_cookie) +{ + UI32_T netlink_id; + NPS_ERROR_NO_T rc; + + osal_io_copyFromUser(&netlink_id, &ptr_cookie->netlink.id, sizeof(UI32_T)); + + _hal_tau_pkt_lockRxChannelAll(unit); + + rc = netif_nl_destroyNetlink(unit, netlink_id); + + _hal_tau_pkt_unlockRxChannelAll(unit); + + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + return (rc); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_getNetlink( + const UI32_T unit, + HAL_TAU_PKT_NL_IOCTL_COOKIE_T *ptr_cookie) +{ + UI32_T id; + NETIF_NL_NETLINK_T netlink; + NPS_ERROR_NO_T rc; + osal_io_copyFromUser(&id, &ptr_cookie->netlink.id, sizeof(UI32_T)); + + rc = netif_nl_getNetlink(unit, id, &netlink); + if (NPS_E_OK == rc) + { + osal_io_copyToUser(&ptr_cookie->netlink, &netlink, sizeof(NETIF_NL_NETLINK_T)); + } + else + { + rc = NPS_E_ENTRY_NOT_FOUND; + } + + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + return (NPS_E_OK); +} + +#endif /* ----------------------------------------------------------------------------------- independent func */ /* FUNCTION NAME: _hal_tau_pkt_enQueue * PURPOSE: @@ -1877,7 +2040,7 @@ _hal_tau_pkt_rxCheckReason( HAL_TAU_PKT_NETIF_PROFILE_T *ptr_profile, BOOL_T *ptr_hit_prof) { - HAL_TAU_PKT_RX_REASON_BITMAP_T *ptr_reason_bitmap = &ptr_profile->reason_bitmap; + HAL_PKT_RX_REASON_BITMAP_T *ptr_reason_bitmap = &ptr_profile->reason_bitmap; UI32_T bitval = 0; UI32_T bitmap = 0x0; @@ -1888,10 +2051,10 @@ _hal_tau_pkt_rxCheckReason( return; } -#define HAL_TAU_PKT_DI_NON_L3_CPU_MIN (HAL_TAU_EXCPT_CPU_BASE_ID + HAL_TAU_EXCPT_CPU_NON_L3_MIN) -#define HAL_TAU_PKT_DI_NON_L3_CPU_MAX (HAL_TAU_EXCPT_CPU_BASE_ID + HAL_TAU_EXCPT_CPU_NON_L3_MAX) -#define HAL_TAU_PKT_DI_L3_CPU_MIN (HAL_TAU_EXCPT_CPU_BASE_ID + HAL_TAU_EXCPT_CPU_L3_MIN) -#define HAL_TAU_PKT_DI_L3_CPU_MAX (HAL_TAU_EXCPT_CPU_BASE_ID + HAL_TAU_EXCPT_CPU_L3_MAX) +#define HAL_TAU_PKT_DI_NON_L3_CPU_MIN (HAL_EXCPT_CPU_BASE_ID + HAL_EXCPT_CPU_NON_L3_MIN) +#define HAL_TAU_PKT_DI_NON_L3_CPU_MAX (HAL_EXCPT_CPU_BASE_ID + HAL_EXCPT_CPU_NON_L3_MAX) +#define HAL_TAU_PKT_DI_L3_CPU_MIN (HAL_EXCPT_CPU_BASE_ID + HAL_EXCPT_CPU_L3_MIN) +#define HAL_TAU_PKT_DI_L3_CPU_MAX (HAL_EXCPT_CPU_BASE_ID + HAL_EXCPT_CPU_L3_MAX) switch (ptr_rx_gpd->itmh_eth.typ) { @@ -1902,7 +2065,7 @@ _hal_tau_pkt_rxCheckReason( ptr_rx_gpd->itmh_eth.dst_idx <= HAL_TAU_PKT_DI_NON_L3_CPU_MAX) { bitval = ptr_rx_gpd->itmh_eth.dst_idx - HAL_TAU_PKT_DI_NON_L3_CPU_MIN; - bitmap = 1 << (bitval % 32); + bitmap = 1UL << (bitval % 32); if (0 != (ptr_reason_bitmap->ipp_excpt_bitmap[bitval / 32] & bitmap)) { *ptr_hit_prof = TRUE; @@ -1932,7 +2095,7 @@ _hal_tau_pkt_rxCheckReason( /* IPP cp_to_cpu_rsn */ bitval = ptr_rx_gpd->itmh_eth.cp_to_cpu_code; - bitmap = 1 << (bitval % 32); + bitmap = 1UL << (bitval % 32); if (0 != (ptr_reason_bitmap->ipp_rsn_bitmap[bitval / 32] & bitmap)) { *ptr_hit_prof = TRUE; @@ -1950,7 +2113,7 @@ _hal_tau_pkt_rxCheckReason( if (1 == ptr_rx_gpd->etmh_eth.redir) { bitval = ptr_rx_gpd->etmh_eth.excpt_code_mir_bmap; - bitmap = 1 << (bitval % 32); + bitmap = 1UL << (bitval % 32); if (0 != (ptr_reason_bitmap->epp_excpt_bitmap[bitval / 32] & bitmap)) { *ptr_hit_prof = TRUE; @@ -2059,25 +2222,30 @@ static void _hal_tau_pkt_matchUserProfile( volatile HAL_TAU_PKT_RX_GPD_T *ptr_rx_gpd, HAL_TAU_PKT_PROFILE_NODE_T *ptr_profile_list, - BOOL_T *ptr_hit_prof) + HAL_TAU_PKT_NETIF_PROFILE_T **pptr_profile_hit) { HAL_TAU_PKT_PROFILE_NODE_T *ptr_curr_node = ptr_profile_list; + BOOL_T hit; + + *pptr_profile_hit = NULL; while (NULL != ptr_curr_node) { /* 1st match reason */ - _hal_tau_pkt_rxCheckReason(ptr_rx_gpd, ptr_curr_node->ptr_profile, ptr_hit_prof); - if (TRUE == *ptr_hit_prof) + _hal_tau_pkt_rxCheckReason(ptr_rx_gpd, ptr_curr_node->ptr_profile, &hit); + if (TRUE == hit) { HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, "rx prof matched by reason\n"); /* Then, check pattern */ - _hal_tau_pkt_rxCheckPattern(ptr_rx_gpd, ptr_curr_node->ptr_profile, ptr_hit_prof); - if (TRUE == *ptr_hit_prof) + _hal_tau_pkt_rxCheckPattern(ptr_rx_gpd, ptr_curr_node->ptr_profile, &hit); + if (TRUE == hit) { HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, "rx prof matched by pattern\n"); + + *pptr_profile_hit = ptr_curr_node->ptr_profile; break; } } @@ -2090,19 +2258,34 @@ _hal_tau_pkt_matchUserProfile( static void _hal_tau_pkt_getPacketDest( volatile HAL_TAU_PKT_RX_GPD_T *ptr_rx_gpd, - HAL_TAU_PKT_DEST_T *ptr_dest) + HAL_TAU_PKT_DEST_T *ptr_dest, + void **pptr_cookie) { - BOOL_T hit_prof = FALSE; UI32_T port; HAL_TAU_PKT_PROFILE_NODE_T *ptr_profile_list; + HAL_TAU_PKT_NETIF_PROFILE_T *ptr_profile_hit; port = ptr_rx_gpd->itmh_eth.igr_phy_port; ptr_profile_list = HAL_TAU_PKT_GET_PORT_PROFILE_LIST(port); - _hal_tau_pkt_matchUserProfile(ptr_rx_gpd, ptr_profile_list, &hit_prof); - if (TRUE == hit_prof) + _hal_tau_pkt_matchUserProfile(ptr_rx_gpd, + ptr_profile_list, + &ptr_profile_hit); + if (NULL != ptr_profile_hit) { +#if defined(NETIF_EN_NETLINK) + if (HAL_TAU_PKT_NETIF_RX_DST_NETLINK == ptr_profile_hit->dst_type) + { + *ptr_dest = HAL_TAU_PKT_DEST_NETLINK; + *pptr_cookie = (void *)&ptr_profile_hit->netlink; + } + else + { + *ptr_dest = HAL_TAU_PKT_DEST_SDK; + } +#else *ptr_dest = HAL_TAU_PKT_DEST_SDK; +#endif } else { @@ -2134,7 +2317,7 @@ _hal_tau_pkt_rxEnQueue( HAL_TAU_PKT_RX_SW_GPD_T *ptr_sw_first_gpd = ptr_sw_gpd; void *ptr_virt_addr = NULL; NPS_ADDR_T phy_addr = 0; - HAL_TAU_PKT_DEST_T pkt_dest; + HAL_TAU_PKT_DEST_T dest_type; /* skb meta */ UI32_T port = 0, len = 0, total_len = 0; @@ -2142,6 +2325,7 @@ _hal_tau_pkt_rxEnQueue( struct net_device_priv *ptr_priv = NULL; struct sk_buff *ptr_skb = NULL, *ptr_merge_skb = NULL; UI32_T copy_offset; + void *ptr_dest; #if defined(PERF_EN_TEST) /* To verify kernel Rx performance */ @@ -2166,9 +2350,16 @@ _hal_tau_pkt_rxEnQueue( } #endif - _hal_tau_pkt_getPacketDest(&ptr_sw_gpd->rx_gpd, &pkt_dest); - if (HAL_TAU_PKT_DEST_NETDEV == pkt_dest) + _hal_tau_pkt_getPacketDest(&ptr_sw_gpd->rx_gpd, &dest_type, &ptr_dest); + +#if defined(NETIF_EN_NETLINK) + if ((HAL_TAU_PKT_DEST_NETDEV == dest_type) || + (HAL_TAU_PKT_DEST_NETLINK == dest_type)) +#else + if (HAL_TAU_PKT_DEST_NETDEV == dest_type) +#endif { + /* need to encap the packet as skb */ ptr_sw_gpd = ptr_sw_first_gpd; while (NULL != ptr_sw_gpd) { @@ -2205,6 +2396,9 @@ _hal_tau_pkt_rxEnQueue( ptr_sw_gpd = ptr_sw_gpd->ptr_next; } + port = ptr_sw_first_gpd->rx_gpd.itmh_eth.igr_phy_port; + ptr_net_dev = HAL_TAU_PKT_GET_PORT_NETDEV(port); + /* if the packet is composed of multiple gpd (skb), need to merge it into a single skb */ if (NULL != ptr_sw_first_gpd->ptr_next) { @@ -2247,10 +2441,6 @@ _hal_tau_pkt_rxEnQueue( _hal_tau_pkt_freeRxGpdList(unit, ptr_sw_first_gpd, FALSE); } - /* get port and net_device */ - port = ptr_sw_first_gpd->rx_gpd.itmh_eth.igr_phy_port; - ptr_net_dev = HAL_TAU_PKT_GET_PORT_NETDEV(port); - /* if NULL netdev, drop the skb */ if (NULL == ptr_net_dev) { @@ -2265,19 +2455,33 @@ _hal_tau_pkt_rxEnQueue( /* skb handling */ ptr_skb->dev = ptr_net_dev; ptr_skb->pkt_type = PACKET_HOST; /* this packet is for me */ - ptr_skb->protocol = eth_type_trans(ptr_skb, ptr_net_dev); /* skip ethernet header */ ptr_skb->ip_summed = CHECKSUM_UNNECESSARY; /* skip checksum */ /* send to linux */ - osal_skb_recv(ptr_skb); + if (dest_type == HAL_TAU_PKT_DEST_NETDEV) + { + /* skip ethernet header only for Linux net interface*/ + ptr_skb->protocol = eth_type_trans(ptr_skb, ptr_net_dev); + osal_skb_recv(ptr_skb); #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) - ptr_net_dev->last_rx = jiffies; + ptr_net_dev->last_rx = jiffies; +#endif + ptr_priv = netdev_priv(ptr_net_dev); + ptr_priv->stats.rx_packets++; + ptr_priv->stats.rx_bytes += total_len; + } +#if defined(NETIF_EN_NETLINK) + else + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, + "hit profile dest=netlink, name=%s, mcgrp=%s\n", + ((NETIF_NL_RX_DST_NETLINK_T *)ptr_dest)->name, + ((NETIF_NL_RX_DST_NETLINK_T *)ptr_dest)->mc_group_name); + netif_nl_rxSkb(unit, ptr_skb, ptr_dest); + } #endif - ptr_priv = netdev_priv(ptr_net_dev); - ptr_priv->stats.rx_packets++; - ptr_priv->stats.rx_bytes += total_len; } - else if (HAL_TAU_PKT_DEST_SDK == pkt_dest) + else if (HAL_TAU_PKT_DEST_SDK == dest_type) { while (0 != _hal_tau_pkt_enQueue(&ptr_rx_cb->sw_queue[channel], ptr_sw_gpd)) { @@ -2289,7 +2493,7 @@ _hal_tau_pkt_rxEnQueue( osal_triggerEvent(&ptr_rx_cb->sync_sema); ptr_rx_cb->cnt.channel[channel].trig_event++; } - else if (HAL_TAU_PKT_DEST_DROP == pkt_dest) + else if (HAL_TAU_PKT_DEST_DROP == dest_type) { _hal_tau_pkt_freeRxGpdList(unit, ptr_sw_first_gpd, TRUE); } @@ -2297,10 +2501,34 @@ _hal_tau_pkt_rxEnQueue( { HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_RX), "u=%u, rxch=%u, invalid pkt dest=%d\n", - unit, channel, pkt_dest); + unit, channel, dest_type); } } +static NPS_ERROR_NO_T +_hal_tau_pkt_flushRxQueue( + const UI32_T unit, + HAL_TAU_PKT_SW_QUEUE_T *ptr_que) +{ + HAL_TAU_PKT_RX_SW_GPD_T *ptr_sw_gpd_knl = NULL; + NPS_ERROR_NO_T rc; + + while (1) + { + rc = _hal_tau_pkt_deQueue(ptr_que, (void **)&ptr_sw_gpd_knl); + if (NPS_E_OK == rc) + { + _hal_tau_pkt_freeRxGpdList(unit, ptr_sw_gpd_knl, TRUE); + } + else + { + break; + } + } + + return (NPS_E_OK); +} + /* FUNCTION NAME: _hal_tau_pkt_schedRxDeQueue * PURPOSE: * To dequeue the packets based on the configured algorithm. @@ -2335,33 +2563,14 @@ _hal_tau_pkt_schedRxDeQueue( UI32_T buf_len = 0; NPS_ERROR_NO_T rc = NPS_E_OK; - /* get queue and count */ - for (idx = 0; idx < HAL_TAU_PKT_RX_QUEUE_NUM; idx++) - { - /* to gurantee the opportunity where each queue can be handler */ - queue = ((ptr_rx_cb->deque_idx + idx) % HAL_TAU_PKT_RX_QUEUE_NUM); - _hal_tau_pkt_getQueueCount(&ptr_rx_cb->sw_queue[queue], &que_cnt); - if (que_cnt > 0) - { - ptr_rx_cb->deque_idx = ((queue + 1) % HAL_TAU_PKT_RX_QUEUE_NUM); - break; - } - } - - /* If all of the queues are empty, wait rxTask event */ - if (0 == que_cnt) + /* normal process */ + if (TRUE == ptr_rx_cb->running) { - osal_waitEvent(&ptr_rx_cb->sync_sema); - if (FALSE == ptr_rx_cb->running) - { - return (NPS_E_OTHERS); /* deinit */ - } - - ptr_rx_cb->cnt.wait_event++; - - /* re-get queue and count */ - for (queue = 0; queue < HAL_TAU_PKT_RX_QUEUE_NUM; queue++) + /* get queue and count */ + for (idx = 0; idx < HAL_TAU_PKT_RX_QUEUE_NUM; idx++) { + /* to gurantee the opportunity where each queue can be handler */ + queue = ((ptr_rx_cb->deque_idx + idx) % HAL_TAU_PKT_RX_QUEUE_NUM); _hal_tau_pkt_getQueueCount(&ptr_rx_cb->sw_queue[queue], &que_cnt); if (que_cnt > 0) { @@ -2369,68 +2578,87 @@ _hal_tau_pkt_schedRxDeQueue( break; } } - } - /* deque */ - if ((que_cnt > 0) && (queue < HAL_TAU_PKT_RX_QUEUE_NUM)) - { - rc = _hal_tau_pkt_deQueue(&ptr_rx_cb->sw_queue[queue], (void **)&ptr_sw_gpd_knl); - if (NPS_E_OK == rc) + /* If all of the queues are empty, wait rxTask event */ + if (0 == que_cnt) { - ptr_rx_cb->cnt.channel[queue].deque_ok++; - ptr_sw_first_gpd_knl = ptr_sw_gpd_knl; + osal_waitEvent(&ptr_rx_cb->sync_sema); - osal_io_copyFromUser(&ioctl_data, ptr_cookie, sizeof(HAL_TAU_PKT_IOCTL_RX_COOKIE_T)); + ptr_rx_cb->cnt.wait_event++; - while (NULL != ptr_sw_gpd_knl) + /* re-get queue and count */ + for (queue = 0; queue < HAL_TAU_PKT_RX_QUEUE_NUM; queue++) { - /* get the IOCTL GPD from user */ - osal_io_copyFromUser(&ioctl_gpd, - ((void *)((NPS_HUGE_T)ioctl_data.ioctl_gpd_addr)) - + gpd_idx*sizeof(HAL_TAU_PKT_IOCTL_RX_GPD_T), - sizeof(HAL_TAU_PKT_IOCTL_RX_GPD_T)); + _hal_tau_pkt_getQueueCount(&ptr_rx_cb->sw_queue[queue], &que_cnt); + if (que_cnt > 0) + { + ptr_rx_cb->deque_idx = ((queue + 1) % HAL_TAU_PKT_RX_QUEUE_NUM); + break; + } + } + } - /* get knl buf addr */ - ptr_rx_gpd = &ptr_sw_gpd_knl->rx_gpd; - phy_addr = NPS_ADDR_32_TO_64(ptr_rx_gpd->data_buf_addr_hi, ptr_rx_gpd->data_buf_addr_lo); + /* deque */ + if ((que_cnt > 0) && (queue < HAL_TAU_PKT_RX_QUEUE_NUM)) + { + rc = _hal_tau_pkt_deQueue(&ptr_rx_cb->sw_queue[queue], (void **)&ptr_sw_gpd_knl); + if (NPS_E_OK == rc) + { + ptr_rx_cb->cnt.channel[queue].deque_ok++; + ptr_sw_first_gpd_knl = ptr_sw_gpd_knl; - ptr_virt_addr = ptr_sw_gpd_knl->ptr_cookie; - osal_skb_unmapDma(phy_addr, ((struct sk_buff *)ptr_virt_addr)->len, DMA_FROM_DEVICE); + osal_io_copyFromUser(&ioctl_data, ptr_cookie, sizeof(HAL_TAU_PKT_IOCTL_RX_COOKIE_T)); - buf_len = (HAL_TAU_PKT_CH_LAST_GPD == ptr_rx_gpd->ch)? - ptr_rx_gpd->cnsm_buf_len : ptr_rx_gpd->avbl_buf_len; + while (NULL != ptr_sw_gpd_knl) + { + /* get the IOCTL GPD from user */ + osal_io_copyFromUser(&ioctl_gpd, + ((void *)((NPS_HUGE_T)ioctl_data.ioctl_gpd_addr)) + + gpd_idx*sizeof(HAL_TAU_PKT_IOCTL_RX_GPD_T), + sizeof(HAL_TAU_PKT_IOCTL_RX_GPD_T)); + + /* get knl buf addr */ + ptr_rx_gpd = &ptr_sw_gpd_knl->rx_gpd; + phy_addr = NPS_ADDR_32_TO_64(ptr_rx_gpd->data_buf_addr_hi, ptr_rx_gpd->data_buf_addr_lo); + + ptr_virt_addr = ptr_sw_gpd_knl->ptr_cookie; + osal_skb_unmapDma(phy_addr, ((struct sk_buff *)ptr_virt_addr)->len, DMA_FROM_DEVICE); + + buf_len = (HAL_TAU_PKT_CH_LAST_GPD == ptr_rx_gpd->ch)? + ptr_rx_gpd->cnsm_buf_len : ptr_rx_gpd->avbl_buf_len; + + /* overwrite whole rx_gpd to user + * the user should re-assign the correct value to data_buf_addr_hi, data_buf_addr_low + * after this IOCTL returns + */ + osal_io_copyToUser((void *)((NPS_HUGE_T)ioctl_gpd.hw_gpd_addr), + &ptr_sw_gpd_knl->rx_gpd, + sizeof(HAL_TAU_PKT_RX_GPD_T)); + /* copy buf */ + /* DMA buf address allocated by the user is store in ptr_ioctl_data->gpd[idx].cookie */ + osal_io_copyToUser((void *)((NPS_HUGE_T)ioctl_gpd.dma_buf_addr), + ((struct sk_buff *)ptr_virt_addr)->data, buf_len); + ptr_sw_gpd_knl->ptr_cookie = ptr_virt_addr; + + /* next */ + ptr_sw_gpd_knl = ptr_sw_gpd_knl->ptr_next; + gpd_idx++; + } - /* overwrite whole rx_gpd to user - * the user should re-assign the correct value to data_buf_addr_hi, data_buf_addr_low - * after this IOCTL returns - */ - osal_io_copyToUser((void *)((NPS_HUGE_T)ioctl_gpd.hw_gpd_addr), - &ptr_sw_gpd_knl->rx_gpd, - sizeof(HAL_TAU_PKT_RX_GPD_T)); - /* copy buf */ - /* DMA buf address allocated by the user is store in ptr_ioctl_data->gpd[idx].cookie */ - osal_io_copyToUser((void *)((NPS_HUGE_T)ioctl_gpd.dma_buf_addr), - ((struct sk_buff *)ptr_virt_addr)->data, buf_len); - ptr_sw_gpd_knl->ptr_cookie = ptr_virt_addr; - - /* next */ - ptr_sw_gpd_knl = ptr_sw_gpd_knl->ptr_next; - gpd_idx++; + /* Must free kernel sw_gpd */ + _hal_tau_pkt_freeRxGpdList(unit, ptr_sw_first_gpd_knl, TRUE); + } + else + { + ptr_rx_cb->cnt.channel[queue].deque_fail++; } - - /* Must free kernel sw_gpd */ - _hal_tau_pkt_freeRxGpdList(unit, ptr_sw_first_gpd_knl, TRUE); } else { - ptr_rx_cb->cnt.channel[queue].deque_fail++; + /* it means that all queue's are flush -> rx stop flow */ + rc = NPS_E_OTHERS; } } - else - { - /* It may happen at last gpd, return error and do not invoke callback. */ - rc = NPS_E_OTHERS; - } return (rc); } @@ -2547,6 +2775,26 @@ _hal_tau_pkt_suspendAllIntf( return (NPS_E_OK); } +static NPS_ERROR_NO_T +_hal_tau_pkt_stopAllIntf( + const UI32_T unit) +{ + struct net_device *ptr_net_dev = NULL; + UI32_T port; + + /* Unregister net devices by id */ + for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) + { + ptr_net_dev = HAL_TAU_PKT_GET_PORT_NETDEV(port); + if (NULL != ptr_net_dev) + { + netif_tx_disable(ptr_net_dev); + } + } + + return (NPS_E_OK); +} + /* FUNCTION NAME: hal_tau_pkt_sendGpd * PURPOSE: * To perform the packet transmission form CPU to the switch. @@ -2572,85 +2820,94 @@ hal_tau_pkt_sendGpd( HAL_TAU_PKT_TX_PDMA_T *ptr_tx_pdma = HAL_TAU_PKT_GET_TX_PDMA_PTR(unit, channel); volatile HAL_TAU_PKT_TX_GPD_T *ptr_tx_gpd = NULL; HAL_TAU_PKT_TX_SW_GPD_T *ptr_sw_first_gpd = ptr_sw_gpd; - UI32_T used_idx = 0; UI32_T used_gpd_num = ptr_sw_gpd->gpd_num; NPS_IRQ_FLAGS_T irq_flags; + HAL_TAU_PKT_DRV_CB_T *ptr_cb = HAL_TAU_PKT_GET_DRV_CB_PTR(unit); - osal_takeIsrLock(&ptr_tx_pdma->ring_lock, &irq_flags); - - /* If not PDMA error */ - if (FALSE == ptr_tx_pdma->err_flag) + if (0 != (ptr_cb->init_flag & HAL_TAU_PKT_INIT_TASK)) { - /* Make Sure GPD is enough */ - if (ptr_tx_pdma->free_gpd_num >= used_gpd_num) + osal_takeIsrLock(&ptr_tx_pdma->ring_lock, &irq_flags); + + /* If not PDMA error */ + if (FALSE == ptr_tx_pdma->err_flag) { - used_idx = ptr_tx_pdma->used_idx; - while (NULL != ptr_sw_gpd) + /* Make Sure GPD is enough */ + if (ptr_tx_pdma->free_gpd_num >= used_gpd_num) { - ptr_tx_gpd = HAL_TAU_PKT_GET_TX_GPD_PTR(unit, channel, used_idx); - osal_dma_invalidateCache((void *)ptr_tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); - - if (HAL_TAU_PKT_HWO_HW_OWN == ptr_tx_gpd->hwo) + used_idx = ptr_tx_pdma->used_idx; + while (NULL != ptr_sw_gpd) { - HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), - "u=%u, txch=%u, free gpd idx out-of-sync\n", - unit, channel); - rc = NPS_E_TABLE_FULL; - break; - } + ptr_tx_gpd = HAL_TAU_PKT_GET_TX_GPD_PTR(unit, channel, used_idx); + osal_dma_invalidateCache((void *)ptr_tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); - /* Fill in HW-GPD Ring */ - osal_memcpy((void *)ptr_tx_gpd, &ptr_sw_gpd->tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); - osal_dma_flushCache((void *)ptr_tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); + if (HAL_TAU_PKT_HWO_HW_OWN == ptr_tx_gpd->hwo) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), + "u=%u, txch=%u, free gpd idx out-of-sync\n", + unit, channel); + rc = NPS_E_TABLE_FULL; + break; + } - /* next */ - used_idx++; - used_idx %= ptr_tx_pdma->gpd_num; - ptr_sw_gpd = ptr_sw_gpd->ptr_next; - } + /* Fill in HW-GPD Ring */ + osal_memcpy((void *)ptr_tx_gpd, &ptr_sw_gpd->tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); + osal_dma_flushCache((void *)ptr_tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); - if (HAL_TAU_PKT_TX_WAIT_ASYNC == ptr_tx_cb->wait_mode) - { - /* Fill 1st GPD in SW-GPD Ring */ - ptr_tx_pdma->pptr_sw_gpd_ring[ptr_tx_pdma->used_idx] = ptr_sw_first_gpd; - } + /* next */ + used_idx++; + used_idx %= ptr_tx_pdma->gpd_num; + ptr_sw_gpd = ptr_sw_gpd->ptr_next; + } - /* update Tx PDMA */ - ptr_tx_pdma->used_idx = used_idx; - ptr_tx_pdma->used_gpd_num += used_gpd_num; - ptr_tx_pdma->free_gpd_num -= used_gpd_num; + if (HAL_TAU_PKT_TX_WAIT_ASYNC == ptr_tx_cb->wait_mode) + { + /* Fill 1st GPD in SW-GPD Ring */ + ptr_tx_pdma->pptr_sw_gpd_ring[ptr_tx_pdma->used_idx] = ptr_sw_first_gpd; + } + + /* update Tx PDMA */ + ptr_tx_pdma->used_idx = used_idx; + ptr_tx_pdma->used_gpd_num += used_gpd_num; + ptr_tx_pdma->free_gpd_num -= used_gpd_num; - _hal_tau_pkt_resumeTxChannelReg(unit, channel, used_gpd_num); - ptr_tx_cb->cnt.channel[channel].send_ok++; + _hal_tau_pkt_resumeTxChannelReg(unit, channel, used_gpd_num); + ptr_tx_cb->cnt.channel[channel].send_ok++; - _hal_tau_pkt_waitTxDone(unit, channel, ptr_sw_first_gpd); + _hal_tau_pkt_waitTxDone(unit, channel, ptr_sw_first_gpd); - /* reserve 1 packet buffer for each port in case that the suspension is too late */ -#define HAL_TAU_PKT_KNL_TX_RING_AVBL_GPD_LOW (HAL_TAU_PORT_NUM) - if (ptr_tx_pdma->free_gpd_num < HAL_TAU_PKT_KNL_TX_RING_AVBL_GPD_LOW) + /* reserve 1 packet buffer for each port in case that the suspension is too late */ +#define HAL_TAU_PKT_KNL_TX_RING_AVBL_GPD_LOW (HAL_PORT_NUM) + if (ptr_tx_pdma->free_gpd_num < HAL_TAU_PKT_KNL_TX_RING_AVBL_GPD_LOW) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_TX, + "u=%u, txch=%u, tx avbl gpd < %d, suspend all netdev\n", + unit, channel, HAL_TAU_PKT_KNL_TX_RING_AVBL_GPD_LOW); + _hal_tau_pkt_suspendAllIntf(unit); + } + } + else { - HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_TX, - "u=%u, txch=%u, tx avbl gpd < %d, suspend all netdev\n", - unit, channel, HAL_TAU_PKT_KNL_TX_RING_AVBL_GPD_LOW); - _hal_tau_pkt_suspendAllIntf(unit); + rc = NPS_E_TABLE_FULL; } } else { - rc = NPS_E_TABLE_FULL; + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), + "u=%u, txch=%u, pdma hw err\n", + unit, channel); + rc = NPS_E_OTHERS; } + + osal_giveIsrLock(&ptr_tx_pdma->ring_lock, &irq_flags); } else { - HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), - "u=%u, txch=%u, pdma hw err\n", - unit, channel); + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_ERR, + "Tx failed, task already deinit\n"); rc = NPS_E_OTHERS; } - osal_giveIsrLock(&ptr_tx_pdma->ring_lock, &irq_flags); - return (rc); } @@ -2662,6 +2919,7 @@ _hal_tau_pkt_rxStop( { NPS_ERROR_NO_T rc = NPS_E_OK; HAL_TAU_PKT_RX_CHANNEL_T channel = 0; + UI32_T idx; HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); HAL_TAU_PKT_DRV_CB_T *ptr_cb = HAL_TAU_PKT_GET_DRV_CB_PTR(unit); HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma = NULL; @@ -2695,6 +2953,14 @@ _hal_tau_pkt_rxStop( osal_giveSemaphore(&ptr_rx_pdma->sema); } + /* flush packets in all queues since Rx task may be blocked in user space + * in this case it won't do ioctl to kernel to handle remaining packets + */ + for (idx = 0; idx < HAL_TAU_PKT_RX_QUEUE_NUM; idx++) + { + _hal_tau_pkt_flushRxQueue(unit, &ptr_rx_cb->sw_queue[idx]); + } + /* Return user thread */ ptr_rx_cb->running = FALSE; ptr_cb->init_flag &= (~HAL_TAU_PKT_INIT_RX_START); @@ -2848,6 +3114,12 @@ hal_tau_pkt_deinitTask( HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); UI32_T channel = 0; + /* to prevent net intf from Tx packet */ + ptr_tx_cb->net_tx_allowed = FALSE; + + /* In case that some undestroyed net intf keep Tx after task deinit */ + _hal_tau_pkt_stopAllIntf(unit); + if (0 == (ptr_cb->init_flag & HAL_TAU_PKT_INIT_TASK)) { HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_RX | HAL_TAU_PKT_DBG_ERR), @@ -2926,13 +3198,10 @@ _hal_tau_pkt_deinitTxPdma( { HAL_TAU_PKT_TX_CB_T *ptr_tx_cb = HAL_TAU_PKT_GET_TX_CB_PTR(unit); HAL_TAU_PKT_TX_PDMA_T *ptr_tx_pdma = HAL_TAU_PKT_GET_TX_PDMA_PTR(unit, channel); - NPS_IRQ_FLAGS_T irg_flags; _hal_tau_pkt_stopTxChannelReg(unit, channel); /* Free DMA and flush queue */ - osal_takeIsrLock(&ptr_tx_pdma->ring_lock, &irg_flags); - osal_dma_free(ptr_tx_pdma->ptr_gpd_start_addr); if (HAL_TAU_PKT_TX_WAIT_ASYNC == ptr_tx_cb->wait_mode) @@ -2945,8 +3214,6 @@ _hal_tau_pkt_deinitTxPdma( osal_destroySemaphore(&ptr_tx_pdma->sync_intr_sema); } - osal_giveIsrLock(&ptr_tx_pdma->ring_lock, &irg_flags); - osal_destroyIsrLock(&ptr_tx_pdma->ring_lock); return (NPS_E_OK); @@ -3919,6 +4186,7 @@ _hal_tau_pkt_handleRxDoneTask( ptr_sw_gpd->ptr_next = NULL; ptr_sw_first_gpd->rx_complete = FALSE; _hal_tau_pkt_rxEnQueue(unit, channel, ptr_sw_first_gpd); + ptr_sw_first_gpd = NULL; } /* do error recover */ @@ -3956,7 +4224,7 @@ _hal_tau_pkt_handleRxDoneTask( { ptr_rx_cb->cnt.no_memory++; HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_RX | HAL_TAU_PKT_DBG_ERR), - "u=%u, rxch=%u, alloc 1st sw gpd failed, size=%d\n", + "u=%u, rxch=%u, alloc 1st sw gpd failed, size=%zu\n", unit, channel, sizeof(HAL_TAU_PKT_RX_SW_GPD_T)); break; } @@ -3973,7 +4241,7 @@ _hal_tau_pkt_handleRxDoneTask( { ptr_rx_cb->cnt.no_memory++; HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_RX | HAL_TAU_PKT_DBG_ERR), - "u=%u, rxch=%u, alloc mid sw gpd failed, size=%d\n", + "u=%u, rxch=%u, alloc mid sw gpd failed, size=%zu\n", unit, channel, sizeof(HAL_TAU_PKT_RX_SW_GPD_T)); break; } @@ -4003,6 +4271,7 @@ _hal_tau_pkt_handleRxDoneTask( ptr_sw_gpd->ptr_next = NULL; ptr_sw_first_gpd->rx_complete = TRUE; _hal_tau_pkt_rxEnQueue(unit, channel, ptr_sw_first_gpd); + ptr_sw_first_gpd = NULL; /* To rebuild the SW GPD link list */ first = TRUE; @@ -4085,8 +4354,8 @@ hal_tau_pkt_initTask( } /* Init handleErrorTask */ - rc = osal_createThread("ERROR", HAL_TAU_PKT_ERROR_ISR_STACK_SIZE, - HAL_TAU_PKT_ERROR_ISR_THREAD_PRI, _hal_tau_pkt_handleErrorTask, + rc = osal_createThread("ERROR", HAL_DFLT_CFG_PKT_ERROR_ISR_THREAD_STACK, + HAL_DFLT_CFG_PKT_ERROR_ISR_THREAD_PRI, _hal_tau_pkt_handleErrorTask, (void *)((NPS_HUGE_T)unit), &ptr_cb->err_task_id); /* Init handleTxDoneTask */ @@ -4095,8 +4364,8 @@ hal_tau_pkt_initTask( ptr_tx_cb->isr_task_cookie[channel].unit = unit; ptr_tx_cb->isr_task_cookie[channel].channel = channel; - rc = osal_createThread("TX_ISR", HAL_TAU_PKT_TX_ISR_STACK_SIZE, - HAL_TAU_PKT_TX_ISR_THREAD_PRI, _hal_tau_pkt_handleTxDoneTask, + rc = osal_createThread("TX_ISR", HAL_DFLT_CFG_PKT_TX_ISR_THREAD_STACK, + HAL_DFLT_CFG_PKT_TX_ISR_THREAD_PRI, _hal_tau_pkt_handleTxDoneTask, (void *)&ptr_tx_cb->isr_task_cookie[channel], &ptr_tx_cb->isr_task_id[channel]); } @@ -4107,8 +4376,8 @@ hal_tau_pkt_initTask( ptr_rx_cb->isr_task_cookie[channel].unit = unit; ptr_rx_cb->isr_task_cookie[channel].channel = channel; - rc = osal_createThread("RX_ISR", HAL_TAU_PKT_RX_ISR_STACK_SIZE, - HAL_TAU_PKT_RX_ISR_THREAD_PRI, _hal_tau_pkt_handleRxDoneTask, + rc = osal_createThread("RX_ISR", HAL_DFLT_CFG_PKT_RX_ISR_THREAD_STACK, + HAL_DFLT_CFG_PKT_RX_ISR_THREAD_PRI, _hal_tau_pkt_handleRxDoneTask, (void *)&ptr_rx_cb->isr_task_cookie[channel], &ptr_rx_cb->isr_task_id[channel]); } @@ -4124,6 +4393,13 @@ hal_tau_pkt_initTask( HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_COMMON, "u=%u, pkt task init done, init flag=0x%x\n", unit, ptr_cb->init_flag); + /* For some specail case in warmboot, the netifs are not destroyed during sdk deinit + * but stopped, here we need to resume them with the original carrier status + */ + _hal_tau_pkt_resumeAllIntf(unit); + + ptr_tx_cb->net_tx_allowed = TRUE; + return (rc); } @@ -4165,8 +4441,8 @@ _hal_tau_pkt_initTxPdma( ptr_tx_pdma->used_idx = 0; ptr_tx_pdma->free_idx = 0; ptr_tx_pdma->used_gpd_num = 0; - ptr_tx_pdma->free_gpd_num = HAL_TAU_PKT_PDMA_TX_GPD_NUM; - ptr_tx_pdma->gpd_num = HAL_TAU_PKT_PDMA_TX_GPD_NUM; + ptr_tx_pdma->free_gpd_num = HAL_DFLT_CFG_PKT_TX_GPD_NUM; + ptr_tx_pdma->gpd_num = HAL_DFLT_CFG_PKT_TX_GPD_NUM; /* Prepare the HW-GPD ring */ ptr_tx_pdma->ptr_gpd_start_addr = (HAL_TAU_PKT_TX_GPD_T *)osal_dma_alloc( @@ -4263,7 +4539,7 @@ _hal_tau_pkt_initRxPdma( /* Reset Rx PDMA */ osal_takeSemaphore(&ptr_rx_pdma->sema, NPS_SEMAPHORE_WAIT_FOREVER); ptr_rx_pdma->cur_idx = 0; - ptr_rx_pdma->gpd_num = HAL_TAU_PKT_PDMA_RX_GPD_NUM; + ptr_rx_pdma->gpd_num = HAL_DFLT_CFG_PKT_RX_GPD_NUM; /* Prepare the HW-GPD ring */ ptr_rx_pdma->ptr_gpd_start_addr = (HAL_TAU_PKT_RX_GPD_T *)osal_dma_alloc( @@ -4374,7 +4650,7 @@ _hal_tau_pkt_initPktTxCb( osal_createEvent("TX_SYNC", &ptr_tx_cb->sync_sema); /* Initialize Tx GPD-queue (of first SW-GPD) from handleTxDoneTask to txTask */ - ptr_tx_cb->sw_queue.len = HAL_TAU_PKT_TX_QUEUE_LEN; + ptr_tx_cb->sw_queue.len = HAL_DFLT_CFG_PKT_TX_QUEUE_LEN; ptr_tx_cb->sw_queue.weight = 0; osal_createSemaphore("TX_QUE", NPS_SEMAPHORE_BINARY, &ptr_tx_cb->sw_queue.sema); @@ -4422,7 +4698,7 @@ _hal_tau_pkt_initPktRxCb( osal_memset(ptr_rx_cb, 0x0, sizeof(HAL_TAU_PKT_RX_CB_T)); - ptr_rx_cb->sched_mode = HAL_TAU_PKT_RX_SCHED_MODE; + ptr_rx_cb->sched_mode = HAL_DFLT_CFG_PKT_RX_SCHED_MODE; /* Sync semaphore to signal rxTask */ osal_createEvent("RX_SYNC", &ptr_rx_cb->sync_sema); @@ -4430,8 +4706,8 @@ _hal_tau_pkt_initPktRxCb( /* Initialize Rx GPD-queue (of first SW-GPD) from handleRxDoneTask to rxTask */ for (queue = 0; ((queue < HAL_TAU_PKT_RX_QUEUE_NUM) && (NPS_E_OK == rc)); queue++) { - ptr_rx_cb->sw_queue[queue].len = HAL_TAU_PKT_RX_QUEUE_LEN; - ptr_rx_cb->sw_queue[queue].weight = HAL_TAU_PKT_RX_QUEUE_WEIGHT; + ptr_rx_cb->sw_queue[queue].len = HAL_DFLT_CFG_PKT_RX_QUEUE_LEN; + ptr_rx_cb->sw_queue[queue].weight = HAL_DFLT_CFG_PKT_RX_QUEUE_WEIGHT; osal_createSemaphore("RX_QUE", NPS_SEMAPHORE_BINARY, &ptr_rx_cb->sw_queue[queue].sema); osal_que_create(&ptr_rx_cb->sw_queue[queue].que_id, ptr_rx_cb->sw_queue[queue].len); @@ -4530,12 +4806,12 @@ _hal_tau_pkt_resetIosCreditCfg( osal_mdc_readPciReg(unit, HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_CREDIT_CFG), &credit_cfg, sizeof(credit_cfg)); - credit_cfg |= (0x1 << HAL_TAU_PKT_PDMA_CREDIT_CFG_RESET_OFFSET); + credit_cfg |= (0x1UL << HAL_TAU_PKT_PDMA_CREDIT_CFG_RESET_OFFSET); osal_mdc_writePciReg(unit, HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_CREDIT_CFG), &credit_cfg, sizeof(UI32_T)); - credit_cfg &= ~(0x1 << HAL_TAU_PKT_PDMA_CREDIT_CFG_RESET_OFFSET); + credit_cfg &= ~(0x1UL << HAL_TAU_PKT_PDMA_CREDIT_CFG_RESET_OFFSET); osal_mdc_writePciReg(unit, HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_CREDIT_CFG), &credit_cfg, sizeof(UI32_T)); @@ -4544,27 +4820,6 @@ _hal_tau_pkt_resetIosCreditCfg( return (NPS_E_OK); } -static NPS_ERROR_NO_T -_hal_tau_pkt_stopAllIntf( - const UI32_T unit) -{ - struct net_device *ptr_net_dev = NULL; - UI32_T port; - - /* Unregister net devices by id */ - for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) - { - ptr_net_dev = HAL_TAU_PKT_GET_PORT_NETDEV(port); - if (NULL != ptr_net_dev) - { - netif_carrier_off(ptr_net_dev); - netif_stop_queue(ptr_net_dev); - } - } - - return (NPS_E_OK); -} - static NPS_ERROR_NO_T _hal_tau_pkt_addProfToList( HAL_TAU_PKT_NETIF_PROFILE_T *ptr_new_profile, @@ -4668,8 +4923,8 @@ _hal_tau_pkt_addProfToAllIntf( for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) { ptr_port_db = HAL_TAU_PKT_GET_PORT_DB(port); - /* Shall we check if the interface is ever created in the port?? */ - //if (NULL != ptr_port_db->ptr_net_dev) + /* Shall we check if the interface is ever created on the port?? */ + /* if (NULL != ptr_port_db->ptr_net_dev) */ if (1) { _hal_tau_pkt_addProfToList(ptr_new_profile, &ptr_port_db->ptr_profile_list); @@ -4759,8 +5014,8 @@ _hal_tau_pkt_delProfFromAllIntfById( for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) { ptr_port_db = HAL_TAU_PKT_GET_PORT_DB(port); - /* Shall we check if the interface is ever created in the port?? */ - //if (NULL != ptr_port_db->ptr_net_dev) + /* Shall we check if the interface is ever created on the port?? */ + /* if (NULL != ptr_port_db->ptr_net_dev) */ if (1) { _hal_tau_pkt_delProfFromListById(id, &ptr_port_db->ptr_profile_list); @@ -4824,7 +5079,7 @@ _hal_tau_pkt_destroyAllIntf( ptr_port_db->meta.port, ptr_port_db->meta.port); - netif_stop_queue(ptr_port_db->ptr_net_dev); + netif_tx_disable(ptr_port_db->ptr_net_dev); unregister_netdev(ptr_port_db->ptr_net_dev); free_netdev(ptr_port_db->ptr_net_dev); @@ -5072,7 +5327,7 @@ hal_tau_pkt_prepareGpd( */ ptr_sw_gpd->tx_gpd.itmh_eth.dst_idx = port; - /* [Taurus] we should set all-1 for the following fields to skip some tm-logic */ + /* [NP8360] we should set all-1 for the following fields to skip some tm-logic */ /* TM header */ ptr_sw_gpd->tx_gpd.itmh_eth.src_idx = 0x7fff; @@ -5083,8 +5338,8 @@ hal_tau_pkt_prepareGpd( ptr_sw_gpd->tx_gpd.itmh_eth.nvo3_src_supp_tag_w1 = 0xf; /* PP header */ - ptr_sw_gpd->tx_gpd.pph_l2.nvo3_encap_idx = HAL_TAU_INVALID_NVO3_ENCAP_IDX; - ptr_sw_gpd->tx_gpd.pph_l2.nvo3_adj_idx = HAL_TAU_INVALID_NVO3_ADJ_IDX; + ptr_sw_gpd->tx_gpd.pph_l2.nvo3_encap_idx = HAL_INVALID_NVO3_ENCAP_IDX; + ptr_sw_gpd->tx_gpd.pph_l2.nvo3_adj_idx = HAL_INVALID_NVO3_ADJ_IDX; return (NPS_E_OK); } @@ -5157,6 +5412,7 @@ _hal_tau_pkt_net_dev_tx( struct net_device *ptr_net_dev) { struct net_device_priv *ptr_priv = netdev_priv(ptr_net_dev); + HAL_TAU_PKT_TX_CB_T *ptr_tx_cb; /* chip meta */ unsigned int unit; unsigned int channel = 0; @@ -5180,6 +5436,17 @@ _hal_tau_pkt_net_dev_tx( unit = ptr_priv->unit; + ptr_tx_cb = HAL_TAU_PKT_GET_TX_CB_PTR(unit); + /* for warm de-init procedure, if any net intf not destroyed, it is possible + * that kernel still has packets to send causing segmentation fault + */ + if (FALSE == ptr_tx_cb->net_tx_allowed) { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_ERR, "net tx during sdk de-init\n"); + ptr_priv->stats.tx_dropped++; + osal_skb_free(ptr_skb); + return NETDEV_TX_OK; + } + /* pad to 60-bytes if skb_len < 60, see: eth_skb_pad(skb) */ if (ptr_skb->len < ETH_ZLEN) { @@ -5245,8 +5512,6 @@ _hal_tau_pkt_net_dev_tx( osal_skb_unmapDma(phy_addr, ptr_skb->len, DMA_TO_DEVICE); osal_skb_free(ptr_skb); osal_free(ptr_sw_gpd); - - return NETDEV_TX_OK; } } } @@ -5374,34 +5639,6 @@ _hal_tau_pkt_setup( memset(&ptr_priv->stats, 0, sizeof(struct net_device_stats)); } -static void -_hal_tau_pkt_lockRxChannelAll( - const UI32_T unit) -{ - UI32_T rch; - HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma; - - for (rch = 0; rch < HAL_TAU_PKT_RX_CHANNEL_LAST; rch++) - { - ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, rch); - osal_takeSemaphore(&ptr_rx_pdma->sema, NPS_SEMAPHORE_WAIT_FOREVER); - } -} - -static void -_hal_tau_pkt_unlockRxChannelAll( - const UI32_T unit) -{ - UI32_T rch; - HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma; - - for (rch = 0; rch < HAL_TAU_PKT_RX_CHANNEL_LAST; rch++) - { - ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, rch); - osal_giveSemaphore(&ptr_rx_pdma->sema); - } -} - static NPS_ERROR_NO_T _hal_tau_pkt_createIntf( const UI32_T unit, @@ -5435,7 +5672,7 @@ _hal_tau_pkt_createIntf( #if defined(HAL_TAU_PKT_FORCR_REMOVE_DUPLICATE_NETDEV) ptr_net_dev->operstate = IF_OPER_DOWN; netif_carrier_off(ptr_net_dev); - netif_stop_queue(ptr_net_dev); + netif_tx_disable(ptr_net_dev); unregister_netdev(ptr_net_dev); free_netdev(ptr_net_dev); #endif @@ -5466,6 +5703,8 @@ _hal_tau_pkt_createIntf( register_netdev(ptr_net_dev); + netif_carrier_off(ptr_net_dev); + net_intf.id = net_intf.port; /* Currently, id is 1-to-1 mapped to port */ osal_memcpy(&ptr_port_db->meta, &net_intf, sizeof(HAL_TAU_PKT_NETIF_INTF_T)); @@ -5518,10 +5757,11 @@ _hal_tau_pkt_destroyIntf( "u=%u, find intf %s (id=%d) on phy port=%d, destroy done\n", unit, ptr_port_db->meta.name, + ptr_port_db->meta.id, ptr_port_db->meta.port); netif_carrier_off(ptr_port_db->ptr_net_dev); - netif_stop_queue(ptr_port_db->ptr_net_dev); + netif_tx_disable(ptr_port_db->ptr_net_dev); unregister_netdev(ptr_port_db->ptr_net_dev); free_netdev(ptr_port_db->ptr_net_dev); @@ -5553,7 +5793,7 @@ _hal_tau_pkt_traverseProfList( ptr_curr_node = ptr_prof_list; - HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_INTF, "intf id=%d, prof list=\n", intf_id); + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_INTF, "intf id=%d, prof list=", intf_id); while(NULL != ptr_curr_node) { HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_INTF, "%s (%d) => ", @@ -6043,6 +6283,24 @@ _hal_tau_pkt_dev_ioctl( ret = hal_tau_pkt_setPortAttr(unit, (HAL_TAU_PKT_IOCTL_PORT_COOKIE_T *)arg); break; +#if defined(NETIF_EN_NETLINK) + case HAL_TAU_PKT_IOCTL_TYPE_NL_SET_INTF_PROPERTY: + ret = _hal_tau_pkt_setIntfProperty(unit, (HAL_TAU_PKT_NL_IOCTL_COOKIE_T *)arg); + break; + case HAL_TAU_PKT_IOCTL_TYPE_NL_GET_INTF_PROPERTY: + ret = _hal_tau_pkt_getIntfProperty(unit, (HAL_TAU_PKT_NL_IOCTL_COOKIE_T *)arg); + break; + case HAL_TAU_PKT_IOCTL_TYPE_NL_CREATE_NETLINK: + ret = _hal_tau_pkt_createNetlink(unit, (HAL_TAU_PKT_NL_IOCTL_COOKIE_T *)arg); + break; + case HAL_TAU_PKT_IOCTL_TYPE_NL_DESTROY_NETLINK: + ret = _hal_tau_pkt_destroyNetlink(unit, (HAL_TAU_PKT_NL_IOCTL_COOKIE_T *)arg); + break; + case HAL_TAU_PKT_IOCTL_TYPE_NL_GET_NETLINK: + ret = _hal_tau_pkt_getNetlink(unit, (HAL_TAU_PKT_NL_IOCTL_COOKIE_T *)arg); + break; +#endif + default: ret = -1; break; @@ -6102,6 +6360,10 @@ _hal_tau_pkt_init(void) osal_memset(_hal_tau_pkt_drv_cb, 0x0, NPS_CFG_MAXIMUM_CHIPS_PER_SYSTEM*sizeof(HAL_TAU_PKT_DRV_CB_T)); +#if defined(NETIF_EN_NETLINK) + netif_nl_init(); +#endif + return (0); } @@ -6110,16 +6372,16 @@ _hal_tau_pkt_exit(void) { UI32_T unit = 0; - /* 1st. Stop Rx HW DMA and free all the DMA buffer hooked on the ring */ + /* 1st. Stop all netdev (if any) to prevent kernel from Tx new packets */ + _hal_tau_pkt_stopAllIntf(unit); + + /* 2nd. Stop Rx HW DMA and free all the DMA buffer hooked on the ring */ _hal_tau_pkt_rxStop(unit); - /* 2nd. Need to wait Rx done task process all the availavle packets on GPD ring */ + /* 3rd. Need to wait Rx done task process all the availavle packets on GPD ring */ #define HAL_TAU_PKT_MODULE_EXIT_HOLD_TIME_US (1000000) osal_sleepThread(HAL_TAU_PKT_MODULE_EXIT_HOLD_TIME_US); - /* 3rd. Stop all netdev (if any) to prevent kernel from Tx new packets */ - _hal_tau_pkt_stopAllIntf(unit); - /* 4th. Stop all the internal tasks (if any) */ hal_tau_pkt_deinitTask(unit); @@ -6139,9 +6401,9 @@ _hal_tau_pkt_exit(void) module_init(_hal_tau_pkt_init); module_exit(_hal_tau_pkt_exit); -module_param(dbg_flag, uint, S_IRUGO); -MODULE_PARM_DESC(dbg_flag, "bit0:Error, bit1:Tx, bit2:Rx, bit3:Intf, bit4:Profile"); +module_param(ext_dbg_flag, uint, S_IRUGO); +MODULE_PARM_DESC(ext_dbg_flag, "bit0:Error, bit1:Tx, bit2:Rx, bit3:Intf, bit4:Profile"); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Nephos"); +MODULE_AUTHOR("MediaTek"); MODULE_DESCRIPTION("NETIF Kernel Module"); diff --git a/platform/nephos/nephos-modules/modules/src/inc/aml.h b/platform/nephos/nephos-modules/modules/src/inc/aml.h index 658aa6e56f46..682eaa5ea318 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/aml.h +++ b/platform/nephos/nephos-modules/modules/src/inc/aml.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/inc/hal_dev.h b/platform/nephos/nephos-modules/modules/src/inc/hal_dev.h index edd582adc197..e8d491358c77 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/hal_dev.h +++ b/platform/nephos/nephos-modules/modules/src/inc/hal_dev.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/inc/hal_tau_pkt_knl.h b/platform/nephos/nephos-modules/modules/src/inc/hal_tau_pkt_knl.h index 96a8cf6441f0..3605323a5955 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/hal_tau_pkt_knl.h +++ b/platform/nephos/nephos-modules/modules/src/inc/hal_tau_pkt_knl.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -104,15 +104,15 @@ typedef enum /* hal_tau_const.h */ -#define HAL_TAU_PORT_NUM (128) -#define HAL_TAU_EXCPT_CPU_NUM (256) -#define HAL_TAU_INVALID_NVO3_ENCAP_IDX (0x3FFF) -#define HAL_TAU_INVALID_NVO3_ADJ_IDX (0xFF) -#define HAL_TAU_EXCPT_CPU_BASE_ID (28 * 1024) -#define HAL_TAU_EXCPT_CPU_NON_L3_MIN (0) -#define HAL_TAU_EXCPT_CPU_NON_L3_MAX (HAL_TAU_EXCPT_CPU_NON_L3_MIN + HAL_TAU_EXCPT_CPU_NUM - 1) -#define HAL_TAU_EXCPT_CPU_L3_MIN (HAL_TAU_EXCPT_CPU_NON_L3_MIN + HAL_TAU_EXCPT_CPU_NUM) -#define HAL_TAU_EXCPT_CPU_L3_MAX (HAL_TAU_EXCPT_CPU_L3_MIN + HAL_TAU_EXCPT_CPU_NUM - 1) +#define HAL_PORT_NUM (128) +#define HAL_EXCPT_CPU_NUM (256) +#define HAL_INVALID_NVO3_ENCAP_IDX (0x3FFF) +#define HAL_INVALID_NVO3_ADJ_IDX (0xFF) +#define HAL_EXCPT_CPU_BASE_ID (28 * 1024) +#define HAL_EXCPT_CPU_NON_L3_MIN (0) +#define HAL_EXCPT_CPU_NON_L3_MAX (HAL_EXCPT_CPU_NON_L3_MIN + HAL_EXCPT_CPU_NUM - 1) +#define HAL_EXCPT_CPU_L3_MIN (HAL_EXCPT_CPU_NON_L3_MIN + HAL_EXCPT_CPU_NUM) +#define HAL_EXCPT_CPU_L3_MAX (HAL_EXCPT_CPU_L3_MIN + HAL_EXCPT_CPU_NUM - 1) /* hal_tau_pkt_rsrc.h */ #define HAL_TAU_PKT_IPP_EXCPT_LAST (256) @@ -238,7 +238,7 @@ typedef struct HAL_TAU_PKT_IPP_COPY2CPU_BITMAP_T ipp_copy2cpu_bitmap; HAL_TAU_PKT_EPP_COPY2CPU_BITMAP_T epp_copy2cpu_bitmap; -} HAL_TAU_PKT_RX_REASON_BITMAP_T; +} HAL_PKT_RX_REASON_BITMAP_T; /* hal_tau_pkt.h */ @@ -246,23 +246,23 @@ typedef struct /* NAMING DECLARATIONS */ /* PKT related configurable parameters */ -#define HAL_TAU_PKT_RX_FREE_STACK_SIZE (64 * 1024) -#define HAL_TAU_PKT_RX_FREE_THREAD_PRI (80) +#define HAL_DFLT_CFG_PKT_RX_FREE_STACK_SIZE (64 * 1024) +#define HAL_DFLT_CFG_PKT_RX_FREE_THREAD_PRI (80) -#define HAL_TAU_PKT_RX_ISR_STACK_SIZE (64 * 1024) -#define HAL_TAU_PKT_RX_ISR_THREAD_PRI (80) +#define HAL_DFLT_CFG_PKT_RX_ISR_THREAD_STACK (64 * 1024) +#define HAL_DFLT_CFG_PKT_RX_ISR_THREAD_PRI (80) -#define HAL_TAU_PKT_TX_FREE_STACK_SIZE (64 * 1024) -#define HAL_TAU_PKT_TX_FREE_THREAD_PRI (80) +#define HAL_DFLT_CFG_PKT_TX_FREE_STACK_SIZE (64 * 1024) +#define HAL_DFLT_CFG_PKT_TX_FREE_THREAD_PRI (80) -#define HAL_TAU_PKT_TX_ISR_STACK_SIZE (64 * 1024) -#define HAL_TAU_PKT_TX_ISR_THREAD_PRI (80) +#define HAL_DFLT_CFG_PKT_TX_ISR_THREAD_STACK (64 * 1024) +#define HAL_DFLT_CFG_PKT_TX_ISR_THREAD_PRI (80) -#define HAL_TAU_PKT_TX_NET_STACK_SIZE (64 * 1024) -#define HAL_TAU_PKT_TX_NET_THREAD_PRI (80) +#define HAL_DFLT_CFG_PKT_TX_NET_STACK_SIZE (64 * 1024) +#define HAL_DFLT_CFG_PKT_TX_NET_THREAD_PRI (80) -#define HAL_TAU_PKT_ERROR_ISR_STACK_SIZE (64 * 1024) -#define HAL_TAU_PKT_ERROR_ISR_THREAD_PRI (80) +#define HAL_DFLT_CFG_PKT_ERROR_ISR_THREAD_STACK (64 * 1024) +#define HAL_DFLT_CFG_PKT_ERROR_ISR_THREAD_PRI (80) /* PKT definitions */ #define HAL_TAU_PKT_TX_MAX_LEN (9216) @@ -300,29 +300,29 @@ typedef struct /* PDMA Definitions */ #define HAL_TAU_PKT_PDMA_MAX_GPD_PER_PKT (10) /* <= 256 */ -#define HAL_TAU_PKT_PDMA_TX_GPD_NUM (1024) /* <= 65535 */ -#define HAL_TAU_PKT_PDMA_RX_GPD_NUM (1024) /* <= 65535 */ +#define HAL_DFLT_CFG_PKT_TX_GPD_NUM (1024) /* <= 65535 */ +#define HAL_DFLT_CFG_PKT_RX_GPD_NUM (1024) /* <= 65535 */ #define HAL_TAU_PKT_PDMA_TX_INTR_TIMEOUT (10 * 1000) /* us */ #define HAL_TAU_PKT_PDMA_TX_POLL_MAX_LOOP (10 * 1000) /* int */ /* Mode */ #define HAL_TAU_PKT_TX_WAIT_MODE (HAL_TAU_PKT_TX_WAIT_ASYNC) -#define HAL_TAU_PKT_RX_SCHED_MODE (HAL_TAU_PKT_RX_SCHED_RR) +#define HAL_DFLT_CFG_PKT_RX_SCHED_MODE (HAL_TAU_PKT_RX_SCHED_RR) /* TX Queue */ -#define HAL_TAU_PKT_TX_QUEUE_LEN (HAL_TAU_PKT_PDMA_TX_GPD_NUM * 10) -#define HAL_TAU_PKT_TX_TASK_MAX_LOOP (HAL_TAU_PKT_TX_QUEUE_LEN) +#define HAL_DFLT_CFG_PKT_TX_QUEUE_LEN (HAL_DFLT_CFG_PKT_TX_GPD_NUM * 10) +#define HAL_TAU_PKT_TX_TASK_MAX_LOOP (HAL_DFLT_CFG_PKT_TX_QUEUE_LEN) /* RX Queue */ #define HAL_TAU_PKT_RX_QUEUE_NUM (HAL_TAU_PKT_RX_CHANNEL_LAST) -#define HAL_TAU_PKT_RX_QUEUE_WEIGHT (10) -#define HAL_TAU_PKT_RX_QUEUE_LEN (HAL_TAU_PKT_PDMA_RX_GPD_NUM * 10) -#define HAL_TAU_PKT_RX_TASK_MAX_LOOP (HAL_TAU_PKT_RX_QUEUE_LEN) +#define HAL_DFLT_CFG_PKT_RX_QUEUE_WEIGHT (10) +#define HAL_DFLT_CFG_PKT_RX_QUEUE_LEN (HAL_DFLT_CFG_PKT_RX_GPD_NUM * 10) +#define HAL_TAU_PKT_RX_TASK_MAX_LOOP (HAL_DFLT_CFG_PKT_RX_QUEUE_LEN) /* MACRO FUNCTION DECLARATIONS */ /*---------------------------------------------------------------------------*/ -/* [Taurus] Alignment to 64-bytes */ +/* [NP8360] Alignment to 64-bytes */ #if defined(NPS_EN_HOST_64_BIT_BIG_ENDIAN) || defined(NPS_EN_HOST_64_BIT_LITTLE_ENDIAN) #define HAL_TAU_PKT_PDMA_ALIGN_ADDR(pdma_addr, align_sz) (((pdma_addr) + (align_sz)) & 0xFFFFFFFFFFFFFFC0) #else @@ -1120,77 +1120,77 @@ typedef struct /* ----------------------------------------------------------------------------------- Reg Type */ typedef enum { - HAL_TAU_PKT_L2_ISR_RCH0 = (0x1 << 0), - HAL_TAU_PKT_L2_ISR_RCH1 = (0x1 << 1), - HAL_TAU_PKT_L2_ISR_RCH2 = (0x1 << 2), - HAL_TAU_PKT_L2_ISR_RCH3 = (0x1 << 3), - HAL_TAU_PKT_L2_ISR_TCH0 = (0x1 << 4), - HAL_TAU_PKT_L2_ISR_TCH1 = (0x1 << 5), - HAL_TAU_PKT_L2_ISR_TCH2 = (0x1 << 6), - HAL_TAU_PKT_L2_ISR_TCH3 = (0x1 << 7), - HAL_TAU_PKT_L2_ISR_RX_QID_MAP_ERR = (0x1 << 8), - HAL_TAU_PKT_L2_ISR_RX_FRAME_ERR = (0x1 << 9) + HAL_TAU_PKT_L2_ISR_RCH0 = (0x1UL << 0), + HAL_TAU_PKT_L2_ISR_RCH1 = (0x1UL << 1), + HAL_TAU_PKT_L2_ISR_RCH2 = (0x1UL << 2), + HAL_TAU_PKT_L2_ISR_RCH3 = (0x1UL << 3), + HAL_TAU_PKT_L2_ISR_TCH0 = (0x1UL << 4), + HAL_TAU_PKT_L2_ISR_TCH1 = (0x1UL << 5), + HAL_TAU_PKT_L2_ISR_TCH2 = (0x1UL << 6), + HAL_TAU_PKT_L2_ISR_TCH3 = (0x1UL << 7), + HAL_TAU_PKT_L2_ISR_RX_QID_MAP_ERR = (0x1UL << 8), + HAL_TAU_PKT_L2_ISR_RX_FRAME_ERR = (0x1UL << 9) } HAL_TAU_PKT_L2_ISR_T; typedef enum { - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_HWO_ERROR = (0x1 << 0), /* Tx GPD.hwo = 0 */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR = (0x1 << 1), /* Tx GPD.chksm is error */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_NO_OVFL_ERROR = (0x1 << 2), /* S/W push too much GPD */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_DMA_READ_ERROR = (0x1 << 3), /* AXI Rd Error when do GPD read */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_BUF_SIZE_ERROR = (0x1 << 4), /* Tx GPD.data_buf_size = 0 */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_RUNT_ERROR = (0x1 << 5), /* Tx GPD.pkt_len < 64 */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_OVSZ_ERROR = (0x1 << 6), /* Tx GPD.pkt_len = 9217 */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_LEN_MISMATCH_ERROR = (0x1 << 7), /* Tx GPD.pkt_len != sum of data_buf_size */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PKTPL_DMA_READ_ERROR = (0x1 << 8), /* AXI Rd Error when do Payload read */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_COS_ERROR = (0x1 << 9), /* Tx GPD.cos is not match cos_to_tch_map */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_GT255_ERROR = (0x1 << 10), /* Multi-GPD packet's GPD# > 255 */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PFC = (0x1 << 11), /* */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_CREDIT_UDFL_ERROR = (0x1 << 12), /* Credit Underflow (count down to 0) */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_DMA_WRITE_ERROR = (0x1 << 13), /* AXI Wr Error (GPD Write-Back) */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_STOP_CMD_CPLT = (0x1 << 14) + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_HWO_ERROR = (0x1UL << 0), /* Tx GPD.hwo = 0 */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR = (0x1UL << 1), /* Tx GPD.chksm is error */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_NO_OVFL_ERROR = (0x1UL << 2), /* S/W push too much GPD */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_DMA_READ_ERROR = (0x1UL << 3), /* AXI Rd Error when do GPD read */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_BUF_SIZE_ERROR = (0x1UL << 4), /* Tx GPD.data_buf_size = 0 */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_RUNT_ERROR = (0x1UL << 5), /* Tx GPD.pkt_len < 64 */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_OVSZ_ERROR = (0x1UL << 6), /* Tx GPD.pkt_len = 9217 */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_LEN_MISMATCH_ERROR = (0x1UL << 7), /* Tx GPD.pkt_len != sum of data_buf_size */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PKTPL_DMA_READ_ERROR = (0x1UL << 8), /* AXI Rd Error when do Payload read */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_COS_ERROR = (0x1UL << 9), /* Tx GPD.cos is not match cos_to_tch_map */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_GT255_ERROR = (0x1UL << 10), /* Multi-GPD packet's GPD# > 255 */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PFC = (0x1UL << 11), /* */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_CREDIT_UDFL_ERROR = (0x1UL << 12), /* Credit Underflow (count down to 0) */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_DMA_WRITE_ERROR = (0x1UL << 13), /* AXI Wr Error (GPD Write-Back) */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_STOP_CMD_CPLT = (0x1UL << 14) } HAL_TAU_PKT_TX_CHANNEL_L2_ISR_T; typedef enum { - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_LOW = (0x1 << 0), /* Rx GPD.avbl_gpd_num < threshold */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_EMPTY = (0x1 << 1), /* Rx GPD.avbl_gpd_num = 0 */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_ERROR = (0x1 << 2), /* Rx GPD.hwo = 0 */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR = (0x1 << 3), /* Rx GPD.chksm is error */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_READ_ERROR = (0x1 << 4), /* DMAR error occurs in PCIE */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_WRITE_ERROR = (0x1 << 5), /* DMAW error occurs in PCIE */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_STOP_CMD_CPLT = (0x1 << 6), /* Stop Completion Acknowledge */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_GT255_ERROR = (0x1 << 7), /* Multi-GPD packet's GPD# > 255 */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_TOD_UNINIT = (0x1 << 8), /* */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_PKT_ERROR_DROP = (0x1 << 9), /* */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_UDSZ_DROP = (0x1 << 10), /* */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_OVSZ_DROP = (0x1 << 11), /* */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_CMDQ_OVF_DROP = (0x1 << 12), /* */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_FIFO_OVF_DROP = (0x1 << 13) + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_LOW = (0x1UL << 0), /* Rx GPD.avbl_gpd_num < threshold */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_EMPTY = (0x1UL << 1), /* Rx GPD.avbl_gpd_num = 0 */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_ERROR = (0x1UL << 2), /* Rx GPD.hwo = 0 */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR = (0x1UL << 3), /* Rx GPD.chksm is error */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_READ_ERROR = (0x1UL << 4), /* DMAR error occurs in PCIE */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_WRITE_ERROR = (0x1UL << 5), /* DMAW error occurs in PCIE */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_STOP_CMD_CPLT = (0x1UL << 6), /* Stop Completion Acknowledge */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_GT255_ERROR = (0x1UL << 7), /* Multi-GPD packet's GPD# > 255 */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_TOD_UNINIT = (0x1UL << 8), /* */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_PKT_ERROR_DROP = (0x1UL << 9), /* */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_UDSZ_DROP = (0x1UL << 10), /* */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_OVSZ_DROP = (0x1UL << 11), /* */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_CMDQ_OVF_DROP = (0x1UL << 12), /* */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_FIFO_OVF_DROP = (0x1UL << 13) } HAL_TAU_PKT_RX_CHANNEL_L2_ISR_T; typedef enum { - HAL_TAU_PKT_TX_CHANNEL_CFG_IOC = (0x1 << 0), - HAL_TAU_PKT_TX_CHANNEL_CFG_CHKSUM = (0x1 << 1), - HAL_TAU_PKT_TX_CHANNEL_CFG_PFC = (0x1 << 2), - HAL_TAU_PKT_TX_CHANNEL_CFG_PKT_LEN_CHK = (0x1 << 3), - HAL_TAU_PKT_TX_CHANNEL_CFG_EARLY_DONE_IRQ = (0x1 << 4), - HAL_TAU_PKT_TX_CHANNEL_CFG_CHK_COS = (0x1 << 5), - HAL_TAU_PKT_TX_CHANNEL_CFG_ADV_GPD_WRBK = (0x1 << 6), - HAL_TAU_PKT_TX_CHANNEL_CFG_GPD_WRBK_FULL_PKT_LEN = (0x1 << 7), - HAL_TAU_PKT_TX_CHANNEL_CFG_LAST = (0x1 << 8) + HAL_TAU_PKT_TX_CHANNEL_CFG_IOC = (0x1UL << 0), + HAL_TAU_PKT_TX_CHANNEL_CFG_CHKSUM = (0x1UL << 1), + HAL_TAU_PKT_TX_CHANNEL_CFG_PFC = (0x1UL << 2), + HAL_TAU_PKT_TX_CHANNEL_CFG_PKT_LEN_CHK = (0x1UL << 3), + HAL_TAU_PKT_TX_CHANNEL_CFG_EARLY_DONE_IRQ = (0x1UL << 4), + HAL_TAU_PKT_TX_CHANNEL_CFG_CHK_COS = (0x1UL << 5), + HAL_TAU_PKT_TX_CHANNEL_CFG_ADV_GPD_WRBK = (0x1UL << 6), + HAL_TAU_PKT_TX_CHANNEL_CFG_GPD_WRBK_FULL_PKT_LEN = (0x1UL << 7), + HAL_TAU_PKT_TX_CHANNEL_CFG_LAST = (0x1UL << 8) } HAL_TAU_PKT_TX_CHANNEL_CFG_T; typedef enum { - HAL_TAU_PKT_RX_CHANNEL_CFG_IOC = (0x1 << 0), - HAL_TAU_PKT_RX_CHANNEL_CFG_CHKSUM = (0x1 << 1), - HAL_TAU_PKT_RX_CHANNEL_CFG_LAST = (0x1 << 2) + HAL_TAU_PKT_RX_CHANNEL_CFG_IOC = (0x1UL << 0), + HAL_TAU_PKT_RX_CHANNEL_CFG_CHKSUM = (0x1UL << 1), + HAL_TAU_PKT_RX_CHANNEL_CFG_LAST = (0x1UL << 2) } HAL_TAU_PKT_RX_CHANNEL_CFG_T; @@ -2079,34 +2079,56 @@ typedef struct /* metadata */ UI8_T mac[6]; -#define HAL_TAU_PKT_NETIF_INTF_FLAGS_MAC (1 << 0) +#define HAL_TAU_PKT_NETIF_INTF_FLAGS_MAC (1UL << 0) UI32_T flags; } HAL_TAU_PKT_NETIF_INTF_T; +#if defined(NETIF_EN_NETLINK) +typedef struct +{ + C8_T name[NPS_NETIF_NAME_LEN]; + C8_T mc_group_name[NPS_NETIF_NAME_LEN]; +} HAL_TAU_PKT_NETIF_RX_DST_NETLINK_T; +#endif + +typedef enum +{ + HAL_TAU_PKT_NETIF_RX_DST_SDK = 0, +#if defined(NETIF_EN_NETLINK) + HAL_TAU_PKT_NETIF_RX_DST_NETLINK, +#endif + HAL_TAU_PKT_NETIF_RX_DST_LAST +} HAL_TAU_PKT_NETIF_RX_DST_TYPE_T; + typedef struct { /* unique key */ - UI32_T id; - C8_T name[NPS_NETIF_NAME_LEN]; - UI32_T priority; + UI32_T id; + C8_T name[NPS_NETIF_NAME_LEN]; + UI32_T priority; /* match fields */ - UI32_T port; /* only support unit port and local port */ - HAL_TAU_PKT_RX_REASON_BITMAP_T reason_bitmap; - UI8_T pattern[NPS_NETIF_PROFILE_PATTERN_NUM][NPS_NETIF_PROFILE_PATTERN_LEN]; - UI8_T mask[NPS_NETIF_PROFILE_PATTERN_NUM][NPS_NETIF_PROFILE_PATTERN_LEN]; - UI32_T offset[NPS_NETIF_PROFILE_PATTERN_NUM]; + UI32_T port; /* only support unit port and local port */ + HAL_PKT_RX_REASON_BITMAP_T reason_bitmap; + UI8_T pattern[NPS_NETIF_PROFILE_PATTERN_NUM][NPS_NETIF_PROFILE_PATTERN_LEN]; + UI8_T mask[NPS_NETIF_PROFILE_PATTERN_NUM][NPS_NETIF_PROFILE_PATTERN_LEN]; + UI32_T offset[NPS_NETIF_PROFILE_PATTERN_NUM]; /* for each flag 1:must hit, 0:don't care */ -#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PORT (1 << 0) -#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_REASON (1 << 1) -#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_0 (1 << 2) -#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_1 (1 << 3) -#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_2 (1 << 4) -#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_3 (1 << 5) - UI32_T flags; +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PORT (1UL << 0) +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_REASON (1UL << 1) +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_0 (1UL << 2) +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_1 (1UL << 3) +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_2 (1UL << 4) +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_3 (1UL << 5) + UI32_T flags; + + HAL_TAU_PKT_NETIF_RX_DST_TYPE_T dst_type; +#if defined(NETIF_EN_NETLINK) + HAL_TAU_PKT_NETIF_RX_DST_NETLINK_T netlink; +#endif } HAL_TAU_PKT_NETIF_PROFILE_T; @@ -2141,6 +2163,13 @@ typedef enum HAL_TAU_PKT_IOCTL_TYPE_CLEAR_RX_CNT, /* port attribute */ HAL_TAU_PKT_IOCTL_TYPE_SET_PORT_ATTR, +#if defined(NETIF_EN_NETLINK) + HAL_TAU_PKT_IOCTL_TYPE_NL_SET_INTF_PROPERTY, + HAL_TAU_PKT_IOCTL_TYPE_NL_GET_INTF_PROPERTY, + HAL_TAU_PKT_IOCTL_TYPE_NL_CREATE_NETLINK, + HAL_TAU_PKT_IOCTL_TYPE_NL_DESTROY_NETLINK, + HAL_TAU_PKT_IOCTL_TYPE_NL_GET_NETLINK, +#endif HAL_TAU_PKT_IOCTL_TYPE_LAST } HAL_TAU_PKT_IOCTL_TYPE_T; @@ -2219,6 +2248,51 @@ typedef struct } HAL_TAU_PKT_IOCTL_PORT_COOKIE_T; +#if defined(NETIF_EN_NETLINK) + +#define NPS_NETIF_NETLINK_NUM_MAX (256) +#define NPS_NETIF_NETLINK_MC_GROUP_NUM_MAX (32) + +typedef enum +{ + NPS_NETIF_INTF_PROPERTY_IGR_SAMPLING_RATE, + NPS_NETIF_INTF_PROPERTY_EGR_SAMPLING_RATE, + NPS_NETIF_INTF_PROPERTY_LAST +} NPS_NETIF_INTF_PROPERTY_T; + +typedef struct +{ + C8_T name[NPS_NETIF_NAME_LEN]; + +} NPS_NETIF_NETLINK_MC_GROUP_T; + +typedef struct +{ + UI32_T id; + C8_T name[NPS_NETIF_NAME_LEN]; + NPS_NETIF_NETLINK_MC_GROUP_T mc_group[NPS_NETIF_NETLINK_MC_GROUP_NUM_MAX]; + UI32_T mc_group_num; + +} NPS_NETIF_NETLINK_T; + +typedef struct +{ + /* intf property */ + UI32_T intf_id; + NPS_NETIF_INTF_PROPERTY_T property; + UI32_T param0; + UI32_T param1; + + /* netlink */ + NPS_NETIF_NETLINK_T netlink; + + NPS_ERROR_NO_T rc; + +} HAL_TAU_PKT_NL_IOCTL_COOKIE_T; + + +#endif /* End of NETIF_EN_NETLINK */ + typedef union { UI32_T value; @@ -2231,6 +2305,7 @@ typedef union } HAL_TAU_PKT_IOCTL_CMD_T; + #endif /* End of NPS_EN_NETIF */ NPS_ERROR_NO_T diff --git a/platform/nephos/nephos-modules/modules/src/inc/netif_nl.h b/platform/nephos/nephos-modules/modules/src/inc/netif_nl.h new file mode 100755 index 000000000000..4b31ceef1620 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/inc/netif_nl.h @@ -0,0 +1,104 @@ +/* Copyright (C) 2020 MediaTek, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program. + */ + + /* FILE NAME: netif_nl.h + * PURPOSE: + * It provide xxx API. + * NOTES: + */ + +#ifndef NETIF_NL_H +#define NETIF_NL_H + +#include + +#define NETIF_NL_NETLINK_MC_GROUP_NUM (32) +#define NETIF_NL_NETLINK_NAME_LEN (16) + +typedef enum +{ + NETIF_NL_INTF_PROPERTY_IGR_SAMPLING_RATE, + NETIF_NL_INTF_PROPERTY_EGR_SAMPLING_RATE, + NETIF_NL_INTF_PROPERTY_LAST +} NETIF_NL_INTF_PROPERTY_T; + +/* must be the same with NPS_NETIF_RX_DST_NETLINK_T */ +typedef struct +{ + C8_T name[NETIF_NL_NETLINK_NAME_LEN]; + C8_T mc_group_name[NETIF_NL_NETLINK_NAME_LEN]; +} NETIF_NL_RX_DST_NETLINK_T; + +/* must be the same with NPS_NETIF_NETLINK_MC_GROUP_T */ +typedef struct +{ + C8_T name[NETIF_NL_NETLINK_NAME_LEN]; + +} NETIF_NL_NETLINK_MC_GROUP_T; + +/* must be the same with NPS_NETIF_NETLINK_T */ +typedef struct +{ + UI32_T id; + C8_T name[NETIF_NL_NETLINK_NAME_LEN]; + NETIF_NL_NETLINK_MC_GROUP_T mc_group[NETIF_NL_NETLINK_MC_GROUP_NUM]; + UI32_T mc_group_num; + +} NETIF_NL_NETLINK_T; + +NPS_ERROR_NO_T +netif_nl_rxSkb( + const UI32_T unit, + struct sk_buff *ptr_skb, + void *ptr_cookie); + +NPS_ERROR_NO_T +netif_nl_setIntfProperty( + const UI32_T unit, + const UI32_T id, + const NETIF_NL_INTF_PROPERTY_T property, + const UI32_T param0, + const UI32_T param1); + +NPS_ERROR_NO_T +netif_nl_getIntfProperty( + const UI32_T unit, + const UI32_T port, + const NETIF_NL_INTF_PROPERTY_T property, + UI32_T *ptr_param0, + UI32_T *ptr_param1); + +NPS_ERROR_NO_T +netif_nl_createNetlink( + const UI32_T unit, + NETIF_NL_NETLINK_T *ptr_netlink, + UI32_T *ptr_netlink_id); + +NPS_ERROR_NO_T +netif_nl_destroyNetlink( + const UI32_T unit, + const UI32_T group_id); + +NPS_ERROR_NO_T +netif_nl_getNetlink( + const UI32_T unit, + const UI32_T netlink_id, + NETIF_NL_NETLINK_T *ptr_netlink); + + +NPS_ERROR_NO_T +netif_nl_init(void); + +#endif /* end of NETIF_NL_H */ diff --git a/platform/nephos/nephos-modules/modules/src/inc/netif_osal.h b/platform/nephos/nephos-modules/modules/src/inc/netif_osal.h index 40c8c9ebc358..93f30fc61ce1 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/netif_osal.h +++ b/platform/nephos/nephos-modules/modules/src/inc/netif_osal.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/inc/netif_perf.h b/platform/nephos/nephos-modules/modules/src/inc/netif_perf.h index 35596668ba9d..5309f01b62d8 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/netif_perf.h +++ b/platform/nephos/nephos-modules/modules/src/inc/netif_perf.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/inc/nps_cfg.h b/platform/nephos/nephos-modules/modules/src/inc/nps_cfg.h index 34306344c55a..36de3cc70863 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/nps_cfg.h +++ b/platform/nephos/nephos-modules/modules/src/inc/nps_cfg.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/inc/nps_error.h b/platform/nephos/nephos-modules/modules/src/inc/nps_error.h index 261878abf3cb..3cf0a14adc0b 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/nps_error.h +++ b/platform/nephos/nephos-modules/modules/src/inc/nps_error.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/inc/nps_types.h b/platform/nephos/nephos-modules/modules/src/inc/nps_types.h index 5630b521404e..88100f69738f 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/nps_types.h +++ b/platform/nephos/nephos-modules/modules/src/inc/nps_types.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/inc/osal_mdc.h b/platform/nephos/nephos-modules/modules/src/inc/osal_mdc.h index 47971bb38c8d..0add2c8216b1 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/osal_mdc.h +++ b/platform/nephos/nephos-modules/modules/src/inc/osal_mdc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -134,6 +134,8 @@ typedef enum OSAL_MDC_IOCTL_TYPE_MDC_FREE_SYS_DMA_MEM, OSAL_MDC_IOCTL_TYPE_MDC_CONNECT_ISR, OSAL_MDC_IOCTL_TYPE_MDC_DISCONNECT_ISR, + OSAL_MDC_IOCTL_TYPE_MDC_SAVE_PCI_CONFIG, + OSAL_MDC_IOCTL_TYPE_MDC_RESTORE_PCI_CONFIG, OSAL_MDC_IOCTL_TYPE_LAST } OSAL_MDC_IOCTL_TYPE_T; @@ -238,4 +240,12 @@ osal_mdc_invalidateCache( void *ptr_virt_addr, const UI32_T size); +NPS_ERROR_NO_T +osal_mdc_savePciConfig( + const UI32_T unit); + +NPS_ERROR_NO_T +osal_mdc_restorePciConfig( + const UI32_T unit); + #endif /* OSAL_MDC_H */ diff --git a/platform/nephos/nephos-modules/modules/src/inc/osal_types.h b/platform/nephos/nephos-modules/modules/src/inc/osal_types.h index 48ac58aba335..59fd3df1260d 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/osal_types.h +++ b/platform/nephos/nephos-modules/modules/src/inc/osal_types.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/make.mk b/platform/nephos/nephos-modules/modules/src/make.mk index e556ea10d765..b49da8b43cdf 100755 --- a/platform/nephos/nephos-modules/modules/src/make.mk +++ b/platform/nephos/nephos-modules/modules/src/make.mk @@ -1,5 +1,5 @@ ################################################################################ -# Copyright (C) 2019 Nephos, Inc. +# Copyright (C) 2020 MediaTek, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -17,7 +17,7 @@ DEV_MODULE_NAME := nps_dev NETIF_MODULE_NAME := nps_netif ################################################################################ DEV_OBJS_TOTAL := ./src/osal_mdc.o ./src/osal_isymbol.o -NETIF_OBJS_TOTAL := ./src/hal_tau_pkt_knl.o ./src/netif_perf.o ./src/netif_osal.o +NETIF_OBJS_TOTAL := ./src/hal_tau_pkt_knl.o ./src/netif_perf.o ./src/netif_osal.o ./src/netif_nl.o obj-m := $(DEV_MODULE_NAME).o $(NETIF_MODULE_NAME).o $(DEV_MODULE_NAME)-objs := $(DEV_OBJS_TOTAL) diff --git a/platform/nephos/nephos-modules/modules/src/netif_nl.c b/platform/nephos/nephos-modules/modules/src/netif_nl.c new file mode 100755 index 000000000000..c112e4b6dd80 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/netif_nl.c @@ -0,0 +1,811 @@ +/* Copyright (C) 2020 MediaTek, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program. + */ + + /* FILE NAME: netif_xxx.c + * PURPOSE: + * It provide xxx API. + * NOTES: + */ +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +extern UI32_T ext_dbg_flag; + +#define NETIF_NL_DBG(__flag__, ...) do \ +{ \ + if (0 != ((__flag__) & (ext_dbg_flag))) \ + { \ + osal_printf(__VA_ARGS__); \ + } \ +}while (0) + +#define NETIF_NL_DBG_NETLINK (0x1UL << 6) + +#define NETIF_NL_FAMILY_NUM_MAX (256) +#define NETIF_NL_INTF_NUM_MAX (256) + +#define NETIF_NL_GET_FAMILY_META(__idx__) &(_netif_nl_cb.fam_entry[__idx__].meta) +#define NETIF_NL_GET_INTF_IGR_SAMPLE_RATE(__inft_id__) (_netif_nl_cb.intf_entry[__inft_id__].igr_sample_rate) + +#define NETIF_NL_FAMILY_IS_PSAMPLE(__ptr_family__) (0 == strncmp(__ptr_family__->name, \ + NETIF_NL_PSAMPLE_FAMILY_NAME, \ + NETIF_NL_NETLINK_NAME_LEN)) ? 1 : 0 + +/* porting part */ +#define NETIF_NL_VER_NUM (1) +#define NETIF_NL_PSAMPLE_MAX_ATTR_NUM (NETIF_NL_PSAMPLE_ATTR_LAST) +#define NETIF_NL_REGISTER_FAMILY(__family__) genl_register_family(__family__) + +#define NETIF_NL_UNREGISTER_FAMILY(__family__) genl_unregister_family(__family__) +#define NETIF_NL_ALLOC_SKB(__len__) genlmsg_new(__len__, GFP_ATOMIC) +#define NETIF_NL_FREE_SKB(__ptr_skb__) nlmsg_free(__ptr_skb__) + +#define NETIF_NL_SEND_PKT(__ptr_family__, __mcgrp_id__, __ptr_skb__) \ + genlmsg_multicast_netns(__ptr_family__, \ + &init_net, \ + __ptr_skb__, \ + 0, /* pid, avoid loop */ \ + __mcgrp_id__, \ + GFP_ATOMIC) +#define NETIF_NL_SET_SKB_ATTR_HDR(__skb__, __family__, __hdr_len__, __cmd__) \ + genlmsg_put(__skb__, 0, 0, __family__, \ + __hdr_len__, __cmd__) +#define NETIF_NL_END_SKB_ATTR_HDR(__skb__, __hdr__) genlmsg_end(__skb__, __hdr__) + +#define NETIF_NL_SET_16_BIT_ATTR(__skb__, __attr__, __data__) nla_put_u16(__skb__, __attr__, __data__) +#define NETIF_NL_SET_32_BIT_ATTR(__skb__, __attr__, __data__) nla_put_u32(__skb__, __attr__, __data__) + + +/* + * <----------- nla_total_size(payload) -------------> + * +------------------+- - -+- - - - - - - - - +- - -+ + * | Attribute Header | Pad | Payload | Pad | + * +------------------+- - -+- - - - - - - - - +- - -+ + * + * + * <-------- nla_attr_size(payload) ----------> + * +------------------+- - -+- - - - - - - - - +- - -+ + * | Attribute Header | Pad | Payload | Pad | + * +------------------+- - -+- - - - - - - - - +- - -+ + * + */ +/* total size = attr data size + attr header size */ +#define NETIF_NL_GET_ATTR_TOTAL_SIZE(__data_size__) nla_total_size(__data_size__) +#define NETIF_NL_GET_ATTR_SIZE(__data_size__) nla_attr_size(__data_size__) /* without padding */ + + +/* psample's family and group parameter */ +#define NETIF_NL_PSAMPLE_FAMILY_NAME "psample" +#define NETIF_NL_PSAMPLE_MC_GROUP_NAME_DATA "packets" +#define NETIF_NL_PSAMPLE_MC_GROUP_NAME_CFG "config" +#define NETIF_NL_PSAMPLE_MC_GROUP_NUM (NETIF_NL_PSAMPLE_MC_GROUP_ID_LAST) +#define NETIF_NL_DEFAULT_MC_GROUP_NUM (1) + +#define NETIF_NL_PSAMPLE_PKT_LEN_MAX (9216) +#define NETIF_NL_PSAMPLE_DFLT_USR_GROUP_ID (1) + +typedef enum +{ + NETIF_NL_PSAMPLE_MC_GROUP_ID_CONFIG = 0, + NETIF_NL_PSAMPLE_MC_GROUP_ID_SAMPLE, + NETIF_NL_PSAMPLE_MC_GROUP_ID_LAST, +} NETIF_NL_PSAMPLE_MC_GROUP_ID_T; + +typedef enum +{ + NETIF_NL_PSAMPLE_ATTR_IIFINDEX = 0, + NETIF_NL_PSAMPLE_ATTR_OIFINDEX, + NETIF_NL_PSAMPLE_ATTR_ORIGSIZE, + NETIF_NL_PSAMPLE_ATTR_SAMPLE_GROUP, + NETIF_NL_PSAMPLE_ATTR_GROUP_SEQ, + NETIF_NL_PSAMPLE_ATTR_SAMPLE_RATE, + NETIF_NL_PSAMPLE_ATTR_DATA, + NETIF_NL_PSAMPLE_ATTR_LAST +} NETIF_NL_PSAMPLE_ATTR_ID_T; + + +typedef struct genl_multicast_group NETIF_NL_MC_GROUP_T; +typedef struct genl_family NETIF_NL_FAMILY_T; + +static NETIF_NL_MC_GROUP_T _netif_nl_psample_mc_group[NETIF_NL_PSAMPLE_MC_GROUP_ID_LAST]; +static C8_T *_ptr_netif_nl_psample_mc_group_name[NETIF_NL_PSAMPLE_MC_GROUP_ID_LAST] = + { + NETIF_NL_PSAMPLE_MC_GROUP_NAME_CFG, + NETIF_NL_PSAMPLE_MC_GROUP_NAME_DATA + }; + +static NETIF_NL_MC_GROUP_T _netif_nl_default_mc_group[NETIF_NL_DEFAULT_MC_GROUP_NUM]; +static C8_T *_ptr_netif_nl_default_mc_group_name[NETIF_NL_DEFAULT_MC_GROUP_NUM] = + { + "default", + }; + +typedef struct +{ + NETIF_NL_FAMILY_T meta; + BOOL_T valid; + +} NETIF_NL_FAMILY_ENTRY_T; + +typedef struct +{ + UI32_T igr_sample_rate; + UI32_T egr_sample_rate; + UI32_T trunc_size; +} NETIF_NL_INTF_ENTRY_T; + +typedef struct +{ + NETIF_NL_FAMILY_ENTRY_T fam_entry[NETIF_NL_FAMILY_NUM_MAX]; + NETIF_NL_INTF_ENTRY_T intf_entry[NETIF_NL_INTF_NUM_MAX]; /* sorted in intf_id */ + UI32_T seq_num; +} NETIF_NL_CB_T; + +static NETIF_NL_CB_T _netif_nl_cb; + +/* should extract to common */ +struct net_device_priv +{ + struct net_device *ptr_net_dev; + struct net_device_stats stats; + UI32_T unit; + UI32_T id; + UI32_T port; + UI16_T vlan; + UI32_T speed; +}; + +static NPS_ERROR_NO_T +_netif_nl_setIntfIgrSampleRate( + const UI32_T unit, + const UI32_T id, + const UI32_T rate) +{ + NETIF_NL_CB_T *ptr_cb = &_netif_nl_cb; + + ptr_cb->intf_entry[id].igr_sample_rate = rate; + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_netif_nl_setIntfEgrSampleRate( + const UI32_T unit, + const UI32_T id, + const UI32_T rate) +{ + NETIF_NL_CB_T *ptr_cb = &_netif_nl_cb; + + ptr_cb->intf_entry[id].egr_sample_rate = rate; + + return (NPS_E_OK); +} + + +NPS_ERROR_NO_T +netif_nl_setIntfProperty( + const UI32_T unit, + const UI32_T id, + const NETIF_NL_INTF_PROPERTY_T property, + const UI32_T param0, + const UI32_T param1) +{ + NPS_ERROR_NO_T rc = NPS_E_BAD_PARAMETER; + + if (NETIF_NL_INTF_PROPERTY_IGR_SAMPLING_RATE == property) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "receive set igr sample rate req, id=%d, property=%d, param0=%d, param=%d\n", + id, property, param0, param1); + rc = _netif_nl_setIntfIgrSampleRate(unit, id, param0); + } + else if (NETIF_NL_INTF_PROPERTY_EGR_SAMPLING_RATE == property) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "receive set egr sample rate req, id=%d, property=%d, param0=%d, param=%d\n", + id, property, param0, param1); + rc = _netif_nl_setIntfEgrSampleRate(unit, id, param0); + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[error] unknown property, property=%d\n", property); + } + + return (rc); +} + +static NPS_ERROR_NO_T +_netif_nl_getIntfIgrSampleRate( + const UI32_T unit, + const UI32_T id, + UI32_T *ptr_rate) +{ + NETIF_NL_CB_T *ptr_cb = &_netif_nl_cb; + + *ptr_rate = ptr_cb->intf_entry[id].igr_sample_rate; + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_netif_nl_getIntfEgrSampleRate( + const UI32_T unit, + const UI32_T id, + UI32_T *ptr_rate) +{ + NETIF_NL_CB_T *ptr_cb = &_netif_nl_cb; + + *ptr_rate = ptr_cb->intf_entry[id].egr_sample_rate; + + return (NPS_E_OK); +} + + +NPS_ERROR_NO_T +netif_nl_getIntfProperty( + const UI32_T unit, + const UI32_T id, + const NETIF_NL_INTF_PROPERTY_T property, + UI32_T *ptr_param0, + UI32_T *ptr_param1) +{ + NPS_ERROR_NO_T rc = NPS_E_BAD_PARAMETER; + + if (NETIF_NL_INTF_PROPERTY_IGR_SAMPLING_RATE == property) + { + rc = _netif_nl_getIntfIgrSampleRate(unit, id, ptr_param0); + } + else if (NETIF_NL_INTF_PROPERTY_EGR_SAMPLING_RATE == property) + { + rc = _netif_nl_getIntfEgrSampleRate(unit, id, ptr_param0); + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[error] unknown property, property=%d\n", + property); + } + + return (rc); +} + +NPS_ERROR_NO_T +_netif_nl_allocNlFamilyEntry( + NETIF_NL_CB_T *ptr_cb, + UI32_T *ptr_index) +{ + UI32_T idx; + NPS_ERROR_NO_T rc = NPS_E_TABLE_FULL; + + for (idx = 0; idx < NETIF_NL_FAMILY_NUM_MAX; idx++) + { + if (FALSE == ptr_cb->fam_entry[idx].valid) + { + *ptr_index = idx; + ptr_cb->fam_entry[idx].valid = TRUE; + rc = NPS_E_OK; + break; + } + } + + return (rc); +} + +void +_netif_nl_freeNlFamilyEntry( + NETIF_NL_CB_T *ptr_cb, + const UI32_T index) +{ + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] free netlink family entry, idx=%d\n", + index); + ptr_cb->fam_entry[index].valid = FALSE; +} + +NPS_ERROR_NO_T +_netif_nl_setNlMcgroupPsample( + NETIF_NL_FAMILY_T *ptr_nl_family) +{ + NETIF_NL_MC_GROUP_T *ptr_nl_mc_group = _netif_nl_psample_mc_group; + UI32_T idx; + + /* init the mc group and hook the group to family */ + osal_memset(ptr_nl_mc_group, 0x0, + (NETIF_NL_PSAMPLE_MC_GROUP_NUM * sizeof(NETIF_NL_MC_GROUP_T))); + + for (idx = 0; idx < NETIF_NL_PSAMPLE_MC_GROUP_ID_LAST; idx++) + { + osal_memcpy(ptr_nl_mc_group[idx].name, + _ptr_netif_nl_psample_mc_group_name[idx], + osal_strlen(_ptr_netif_nl_psample_mc_group_name[idx])); + } + ptr_nl_family->n_mcgrps = NETIF_NL_PSAMPLE_MC_GROUP_NUM; + ptr_nl_family->mcgrps = ptr_nl_mc_group; + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +_netif_nl_setNlMcgroupDefault( + NETIF_NL_FAMILY_T *ptr_nl_family) +{ + NETIF_NL_MC_GROUP_T *ptr_nl_mc_group = _netif_nl_default_mc_group; + UI32_T idx; + + /* init the mc group and hook the group to family */ + osal_memset(ptr_nl_mc_group, 0x0, + (NETIF_NL_DEFAULT_MC_GROUP_NUM * sizeof(NETIF_NL_MC_GROUP_T))); + + for (idx = 0; idx < NETIF_NL_DEFAULT_MC_GROUP_NUM; idx++) + { + osal_memcpy(ptr_nl_mc_group[idx].name, + _ptr_netif_nl_default_mc_group_name[idx], + osal_strlen(_ptr_netif_nl_default_mc_group_name[idx])); + } + ptr_nl_family->n_mcgrps = NETIF_NL_DEFAULT_MC_GROUP_NUM; + ptr_nl_family->mcgrps = ptr_nl_mc_group; + + return (NPS_E_OK); +} + +#define NETIF_NL_IS_FAMILY_ENTRY_VALID(__idx__) \ + (TRUE == _netif_nl_cb.fam_entry[__idx__].valid) ? (TRUE) : (FALSE) +NPS_ERROR_NO_T +netif_nl_createNetlink( + const UI32_T unit, + NETIF_NL_NETLINK_T *ptr_netlink, + UI32_T *ptr_netlink_id) +{ + NETIF_NL_CB_T *ptr_cb = &_netif_nl_cb; + UI32_T entry_id; + NETIF_NL_FAMILY_T *ptr_nl_family; + NETIF_NL_MC_GROUP_T *ptr_nl_mcgrp; + UI32_T idx; + int ret; + NPS_ERROR_NO_T rc; + + rc = _netif_nl_allocNlFamilyEntry(ptr_cb, &entry_id); + if (NPS_E_OK == rc) + { + ptr_nl_family = NETIF_NL_GET_FAMILY_META(entry_id); + + /* fill in the meta data for that netlink family */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) + ptr_nl_family->id = GENL_ID_GENERATE; /* family id can be ignored since linux 4.10 */ +#endif + ptr_nl_family->version = NETIF_NL_VER_NUM; + ptr_nl_family->maxattr = NETIF_NL_PSAMPLE_MAX_ATTR_NUM; + ptr_nl_family->netnsok = true; + osal_memcpy(ptr_nl_family->name, ptr_netlink->name, NETIF_NL_NETLINK_NAME_LEN); + + /* fill in the mc group info */ + ptr_nl_mcgrp = osal_alloc(sizeof(NETIF_NL_MC_GROUP_T)*ptr_netlink->mc_group_num); + if (NULL != ptr_nl_mcgrp) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, "[DBG] create mc group:\n"); + for (idx = 0; idx < ptr_netlink->mc_group_num; idx++) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] - mcgrp%d: %s\n", idx, ptr_netlink->mc_group[idx].name); + osal_memcpy(ptr_nl_mcgrp[idx].name, ptr_netlink->mc_group[idx].name, + NETIF_NL_NETLINK_NAME_LEN); + } + ptr_nl_family->n_mcgrps = ptr_netlink->mc_group_num; + ptr_nl_family->mcgrps = ptr_nl_mcgrp; + + /* register the family to kernel */ + ret = NETIF_NL_REGISTER_FAMILY(ptr_nl_family); + if (0 == ret) + { + *ptr_netlink_id = entry_id; + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] create netlink family, name=%s, entry_idx=%d, mcgrp_num=%d\n", + ptr_netlink->name, entry_id, ptr_nl_family->n_mcgrps); + rc = NPS_E_OK; + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] register netlink family failed, name=%s, ret=%d\n", + ptr_netlink->name, ret); + osal_free(ptr_nl_mcgrp); + _netif_nl_freeNlFamilyEntry(ptr_cb, entry_id); + rc = NPS_E_OTHERS; + } + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, "[DBG] alloc mcgrp failed\n"); + rc = NPS_E_NO_MEMORY; + } + } + + return (rc); +} + +NPS_ERROR_NO_T +netif_nl_destroyNetlink( + const UI32_T unit, + const UI32_T netlink_id) +{ + NETIF_NL_CB_T *ptr_cb = &_netif_nl_cb; + UI32_T entry_idx = netlink_id; + NETIF_NL_FAMILY_T *ptr_nl_family; + int ret; + NPS_ERROR_NO_T rc; + + if (TRUE == NETIF_NL_IS_FAMILY_ENTRY_VALID(entry_idx)) + { + ptr_nl_family = NETIF_NL_GET_FAMILY_META(entry_idx); + ret = NETIF_NL_UNREGISTER_FAMILY(ptr_nl_family); + if (0 == ret) + { + osal_free(ptr_nl_family->mcgrps); + _netif_nl_freeNlFamilyEntry(ptr_cb, entry_idx); + rc = NPS_E_OK; + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] unregister netlink family failed, name=%s, ret=%d\n", + ptr_nl_family->name, ret); + rc = NPS_E_OTHERS; + } + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] destroy netlink failed, invalid netlink_id %d\n", + netlink_id); + rc = NPS_E_ENTRY_NOT_FOUND; + } + + return (rc); +} + +NPS_ERROR_NO_T +netif_nl_getNetlink( + const UI32_T unit, + const UI32_T netlink_id, + NETIF_NL_NETLINK_T *ptr_netlink) +{ + UI32_T entry_idx = netlink_id; + NETIF_NL_FAMILY_T *ptr_meta; + UI32_T grp_idx; + NPS_ERROR_NO_T rc = NPS_E_OK; + + if (TRUE == NETIF_NL_IS_FAMILY_ENTRY_VALID(entry_idx)) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] get valid netlink, id=%d\n", netlink_id); + + ptr_netlink->id = netlink_id; + ptr_meta = NETIF_NL_GET_FAMILY_META(entry_idx); + + ptr_netlink->mc_group_num = ptr_meta->n_mcgrps; + osal_memcpy(ptr_netlink->name, ptr_meta->name, NETIF_NL_NETLINK_NAME_LEN); + + for (grp_idx = 0; grp_idx < ptr_meta->n_mcgrps; grp_idx++) + { + osal_memcpy(ptr_netlink->mc_group[grp_idx].name, + ptr_meta->mcgrps[grp_idx].name, + NETIF_NL_NETLINK_NAME_LEN); + } + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] get netlink failed, invalid netlink_id %d\n", + netlink_id); + rc = NPS_E_ENTRY_NOT_FOUND; + } + + return (rc); +} + + +NPS_ERROR_NO_T +_netif_nl_getFamilyByName( + NETIF_NL_CB_T *ptr_cb, + const C8_T *ptr_name, + NETIF_NL_FAMILY_T **pptr_nl_family) +{ + UI32_T idx; + NPS_ERROR_NO_T rc = NPS_E_ENTRY_NOT_FOUND; + + for (idx = 0; idx < NETIF_NL_FAMILY_NUM_MAX; idx++) + { + if ((TRUE == ptr_cb->fam_entry[idx].valid) && + (0 == strncmp(ptr_cb->fam_entry[idx].meta.name, + ptr_name, + NETIF_NL_NETLINK_NAME_LEN))) + { + *pptr_nl_family = &(ptr_cb->fam_entry[idx].meta); + rc = NPS_E_OK; + break; + } + } + + if (NPS_E_ENTRY_NOT_FOUND == rc) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] find family failed, name=%s\n", + ptr_name); + } + + return (rc); +} + +NPS_ERROR_NO_T +_netif_nl_getMcgrpIdByName( + NETIF_NL_FAMILY_T *ptr_nl_family, + const C8_T *ptr_mcgrp_name, + UI32_T *ptr_mcgrp_id) +{ + UI32_T idx; + NPS_ERROR_NO_T rc = NPS_E_ENTRY_NOT_FOUND; + + for (idx = 0; idx < ptr_nl_family->n_mcgrps; idx++) + { + if ((0 == strncmp(ptr_nl_family->mcgrps[idx].name, + ptr_mcgrp_name, + NETIF_NL_NETLINK_NAME_LEN))) + { + *ptr_mcgrp_id = idx; + rc = NPS_E_OK; + break; + } + } + + if (NPS_E_OK != rc) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] find mcgrp %s failed in family %s\n", + ptr_mcgrp_name, ptr_nl_family->name); + } + + return (rc); +} + +NPS_ERROR_NO_T +_netif_nl_allocPsampleSkb( + NETIF_NL_CB_T *ptr_cb, + NETIF_NL_FAMILY_T *ptr_nl_family, + struct sk_buff *ptr_ori_skb, + struct sk_buff **pptr_nl_skb) +{ + UI32_T msg_hdr_len; + UI32_T data_len; + struct sk_buff *ptr_nl_skb; + UI16_T igr_intf_idx; + struct net_device_priv *ptr_priv; + UI32_T rate; + UI32_T intf_id; + void *ptr_nl_hdr = NULL; + struct nlattr *ptr_nl_attr; + NPS_ERROR_NO_T rc = NPS_E_OK; + + /* make sure the total len (original pkt len + hdr msg) < PSAMPLE_MAX_PACKET_SIZE */ + + msg_hdr_len = NETIF_NL_GET_ATTR_TOTAL_SIZE(sizeof(UI16_T)) + /* PSAMPLE_ATTR_IIFINDEX */ + NETIF_NL_GET_ATTR_TOTAL_SIZE(sizeof(UI32_T)) + /* PSAMPLE_ATTR_SAMPLE_RATE */ + NETIF_NL_GET_ATTR_TOTAL_SIZE(sizeof(UI32_T)) + /* PSAMPLE_ATTR_ORIGSIZE */ + NETIF_NL_GET_ATTR_TOTAL_SIZE(sizeof(UI32_T)) + /* PSAMPLE_ATTR_SAMPLE_GROUP */ + NETIF_NL_GET_ATTR_TOTAL_SIZE(sizeof(UI32_T)); /* PSAMPLE_ATTR_GROUP_SEQ */ + + data_len = NETIF_NL_GET_ATTR_TOTAL_SIZE(ptr_ori_skb->len); + + if ((msg_hdr_len + NETIF_NL_GET_ATTR_TOTAL_SIZE(ptr_ori_skb->len)) > NETIF_NL_PSAMPLE_PKT_LEN_MAX) + { + data_len = NETIF_NL_PSAMPLE_PKT_LEN_MAX - msg_hdr_len - NLA_HDRLEN - NLA_ALIGNTO; + } + else + { + data_len = ptr_ori_skb->len; + } + + ptr_nl_skb = NETIF_NL_ALLOC_SKB(NETIF_NL_GET_ATTR_TOTAL_SIZE(data_len) + msg_hdr_len); + if (NULL != ptr_nl_skb) + { + /* to create a netlink msg header (cmd=0) */ + ptr_nl_hdr = NETIF_NL_SET_SKB_ATTR_HDR(ptr_nl_skb, ptr_nl_family, 0, 0); + if (NULL != ptr_nl_hdr) + { + /* obtain the intf index for the igr_port */ + igr_intf_idx = ptr_ori_skb->dev->ifindex; + NETIF_NL_SET_16_BIT_ATTR(ptr_nl_skb, NETIF_NL_PSAMPLE_ATTR_IIFINDEX, + (UI16_T)igr_intf_idx); + + /* meta header */ + /* use the igr port id as the index for the database to get sample rate */ + ptr_priv = netdev_priv(ptr_ori_skb->dev); + intf_id = ptr_priv->port; + rate = NETIF_NL_GET_INTF_IGR_SAMPLE_RATE(intf_id); + NETIF_NL_SET_32_BIT_ATTR(ptr_nl_skb, NETIF_NL_PSAMPLE_ATTR_SAMPLE_RATE, rate); + NETIF_NL_SET_32_BIT_ATTR(ptr_nl_skb, NETIF_NL_PSAMPLE_ATTR_ORIGSIZE, data_len); + NETIF_NL_SET_32_BIT_ATTR(ptr_nl_skb, NETIF_NL_PSAMPLE_ATTR_SAMPLE_GROUP, + NETIF_NL_PSAMPLE_DFLT_USR_GROUP_ID); + NETIF_NL_SET_32_BIT_ATTR(ptr_nl_skb, NETIF_NL_PSAMPLE_ATTR_GROUP_SEQ, ptr_cb->seq_num); + ptr_cb->seq_num++; + + /* data */ + ptr_nl_attr = (struct nlattr *)skb_put(ptr_nl_skb, NETIF_NL_GET_ATTR_TOTAL_SIZE(data_len)); + ptr_nl_attr->nla_type = NETIF_NL_PSAMPLE_ATTR_DATA; + /* get the attr size without padding, since it's the last one */ + ptr_nl_attr->nla_len = NETIF_NL_GET_ATTR_SIZE(data_len); + skb_copy_bits(ptr_ori_skb, 0, nla_data(ptr_nl_attr), data_len); + + NETIF_NL_END_SKB_ATTR_HDR(ptr_nl_skb, ptr_nl_hdr); + } + else + { + rc = NPS_E_OTHERS; + } + } + else + { + rc = NPS_E_OTHERS; + } + + *pptr_nl_skb = ptr_nl_skb; + + return (rc); +} + +NPS_ERROR_NO_T +_netif_nl_allocNetlinkSkb( + NETIF_NL_CB_T *ptr_cb, + NETIF_NL_FAMILY_T *ptr_nl_family, + struct sk_buff *ptr_ori_skb, + struct sk_buff **pptr_nl_skb) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + + /* need to fill specific skb header format */ + if (NETIF_NL_FAMILY_IS_PSAMPLE(ptr_nl_family)) + { + rc = _netif_nl_allocPsampleSkb(ptr_cb, ptr_nl_family, + ptr_ori_skb, pptr_nl_skb); + if (NPS_E_OK != rc) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] alloc netlink skb failed\n"); + } + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] unknown netlink family\n"); + rc = NPS_E_OTHERS; + } + + return (rc); +} + +NPS_ERROR_NO_T +_netif_nl_sendNetlinkSkb( + NETIF_NL_FAMILY_T *ptr_nl_family, + UI32_T nl_mcgrp_id, + struct sk_buff *ptr_nl_skb) +{ + int ret; + NPS_ERROR_NO_T rc; + + ret = NETIF_NL_SEND_PKT(ptr_nl_family, nl_mcgrp_id, ptr_nl_skb); + if (0 == ret) + { + rc = NPS_E_OK; + } + else + { + /* in errno_base.h, #define ESRCH 3 : No such process */ + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "send skb to mc group failed, ret=%d\n", ret); + rc = NPS_E_OTHERS; + } + + return (rc); +} + +void +_netif_nl_freeNetlinkSkb( + struct sk_buff *ptr_nl_skb) +{ + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, "[DBG] free nl skb\n"); + NETIF_NL_FREE_SKB(ptr_nl_skb); +} + +NPS_ERROR_NO_T +_netif_nl_forwardPkt( + NETIF_NL_CB_T *ptr_cb, + NETIF_NL_RX_DST_NETLINK_T *ptr_nl_dest, + struct sk_buff *ptr_ori_skb) +{ + struct sk_buff *ptr_nl_skb = NULL; + NETIF_NL_FAMILY_T *ptr_nl_family; + UI32_T nl_mcgrp_id; + NPS_ERROR_NO_T rc; + + rc = _netif_nl_getFamilyByName(ptr_cb, ptr_nl_dest->name, + &ptr_nl_family); + if (NPS_E_OK == rc) + { + rc = _netif_nl_getMcgrpIdByName(ptr_nl_family, ptr_nl_dest->mc_group_name, + &nl_mcgrp_id); + if (NPS_E_OK == rc) + { + rc = _netif_nl_allocNetlinkSkb(ptr_cb, ptr_nl_family, + ptr_ori_skb, &ptr_nl_skb); + if (NPS_E_OK == rc) + { + rc = _netif_nl_sendNetlinkSkb(ptr_nl_family, nl_mcgrp_id, + ptr_nl_skb); + if (NPS_E_OK != rc) + { + /* _netif_nl_freeNetlinkSkb(ptr_nl_skb); */ + } + } + } + } + + return (rc); +} + +NPS_ERROR_NO_T +netif_nl_rxSkb( + const UI32_T unit, + struct sk_buff *ptr_skb, + void *ptr_cookie) +{ + NETIF_NL_CB_T *ptr_cb = &_netif_nl_cb; + + NETIF_NL_RX_DST_NETLINK_T *ptr_nl_dest; + NPS_ERROR_NO_T rc; + + ptr_nl_dest = (NETIF_NL_RX_DST_NETLINK_T *)ptr_cookie; + + /* send the packet to netlink mcgroup */ + rc = _netif_nl_forwardPkt(ptr_cb, ptr_nl_dest, ptr_skb); + + /* need to free the original skb anyway */ + osal_skb_free(ptr_skb); + + return (rc); +} + +NPS_ERROR_NO_T +netif_nl_init(void) +{ + osal_memset(&_netif_nl_cb, 0x0, sizeof(NETIF_NL_CB_T)); + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +netif_nl_deinit(void) +{ + return (NPS_E_OK); +} + diff --git a/platform/nephos/nephos-modules/modules/src/netif_osal.c b/platform/nephos/nephos-modules/modules/src/netif_osal.c index 15599e3a0aa0..51af7fcb3ad9 100755 --- a/platform/nephos/nephos-modules/modules/src/netif_osal.c +++ b/platform/nephos/nephos-modules/modules/src/netif_osal.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/netif_perf.c b/platform/nephos/nephos-modules/modules/src/netif_perf.c index 18606d6d25d4..11dd03b58eb5 100755 --- a/platform/nephos/nephos-modules/modules/src/netif_perf.c +++ b/platform/nephos/nephos-modules/modules/src/netif_perf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/osal_isymbol.c b/platform/nephos/nephos-modules/modules/src/osal_isymbol.c index c23cc70bed23..f908c2325966 100755 --- a/platform/nephos/nephos-modules/modules/src/osal_isymbol.c +++ b/platform/nephos/nephos-modules/modules/src/osal_isymbol.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/osal_mdc.c b/platform/nephos/nephos-modules/modules/src/osal_mdc.c index 3dad3173ac79..d0a25e48fc32 100755 --- a/platform/nephos/nephos-modules/modules/src/osal_mdc.c +++ b/platform/nephos/nephos-modules/modules/src/osal_mdc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -37,7 +37,7 @@ #include #include #include - +#include #include #include @@ -685,6 +685,7 @@ _osal_mdc_removePciCallback( iounmap(ptr_dev->ptr_mmio_virt_addr); pci_release_region(pdev, OSAL_MDC_PCI_BAR0_OFFSET); pci_disable_device(pdev); + _osal_mdc_cb.dev_num--; } static struct pci_device_id _osal_mdc_id_table[] = @@ -708,6 +709,7 @@ _osal_mdc_probePciDevice(void) if (pci_register_driver(&_osal_mdc_pci_driver) < 0) { + OSAL_MDC_ERR("Cannot find PCI device\n"); rc = NPS_E_OTHERS; } return (rc); @@ -720,6 +722,119 @@ _osal_mdc_removePciDevice(void) return (NPS_E_OK); } +static NPS_ERROR_NO_T +_osal_mdc_maskStatus( + const UI32_T unit) +{ + struct pci_dev *ptr_ep_dev = _osal_mdc_cb.dev[unit].ptr_pci_dev; + struct pci_dev *ptr_rc_dev = ptr_ep_dev->bus->self; + int ext_cap = 0; + UI32_T data_32 = 0; + + ext_cap = pci_find_ext_capability(ptr_rc_dev, 0x1); + if (0 != ext_cap) + { + /* Mask */ + pci_read_config_dword(ptr_rc_dev, ext_cap + 0x8, &data_32); + data_32 |= 0x20; + pci_write_config_dword(ptr_rc_dev, ext_cap + 0x8, data_32); + } + + return NPS_E_OK; +} + +static NPS_ERROR_NO_T +_osal_mdc_clearStatus( + const UI32_T unit) +{ + struct pci_dev *ptr_ep_dev = _osal_mdc_cb.dev[unit].ptr_pci_dev; + struct pci_dev *ptr_rc_dev = ptr_ep_dev->bus->self; + int ext_cap = 0; + UI32_T data_32 = 0; + + ext_cap = pci_find_ext_capability(ptr_rc_dev, 0x1); + if (0 != ext_cap) + { + /* Clear */ + pci_write_config_word(ptr_rc_dev, ptr_rc_dev->pcie_cap + 0xa, 0x04); + pci_write_config_word(ptr_rc_dev, ptr_rc_dev->pcie_cap + 0x12, 0x8000); + pci_write_config_dword(ptr_rc_dev, ext_cap + 0x4, 0x20); + + /* UnMask */ + pci_read_config_dword(ptr_rc_dev, ext_cap + 0x8, &data_32); + data_32 &= ~0x20; + pci_write_config_dword(ptr_rc_dev, ext_cap + 0x8, data_32); + } + + return NPS_E_OK; +} + +static NPS_ERROR_NO_T +_osal_mdc_savePciConfig( + const UI32_T unit) +{ + struct pci_dev *ptr_dev = _osal_mdc_cb.dev[unit].ptr_pci_dev; + NPS_ERROR_NO_T rc = NPS_E_OK; + + rc = _osal_mdc_maskStatus(unit); + + if (NPS_E_OK == rc) + { + pci_save_state(ptr_dev); + } + + return rc; +} + +static NPS_ERROR_NO_T +_osal_mdc_restorePciConfig( + const UI32_T unit) +{ +#define OSAL_MDC_PCI_PRESENT_POLL_CNT (100) +#define OSAL_MDC_PCI_PRESENT_POLL_INTERVAL (10) /* ms */ + + struct pci_dev *ptr_dev = _osal_mdc_cb.dev[unit].ptr_pci_dev; + UI32_T poll_cnt = 0; + NPS_ERROR_NO_T rc = NPS_E_OK; + + /* standard: at least 100ms for link recovery */ + msleep(100); + + /* make sure pci device is there before restoring the config space */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) + while ((0 == pci_device_is_present(ptr_dev)) && +#else + while ((0 == pci_dev_present(_osal_mdc_id_table)) && +#endif + (poll_cnt < OSAL_MDC_PCI_PRESENT_POLL_CNT)) + { + msleep(OSAL_MDC_PCI_PRESENT_POLL_INTERVAL); + poll_cnt++; + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) + if (1 == pci_device_is_present(ptr_dev)) +#else + if (1 == pci_dev_present(_osal_mdc_id_table)) +#endif + { + pci_restore_state(ptr_dev); + rc = NPS_E_OK; + } + else + { + OSAL_MDC_ERR("detect pci device failed\n"); + rc = NPS_E_OTHERS; + } + + if (NPS_E_OK == rc) + { + rc = _osal_mdc_clearStatus(unit); + } + + return (rc); +} + #endif /* End of AML_EN_I2C */ /* --------------------------------------------------------------------------- DMA */ @@ -1415,6 +1530,20 @@ osal_mdc_invalidateCache( return (NPS_E_OK); } +NPS_ERROR_NO_T +osal_mdc_savePciConfig( + const UI32_T unit) +{ + return _osal_mdc_savePciConfig(unit); +} + +NPS_ERROR_NO_T +osal_mdc_restorePciConfig( + const UI32_T unit) +{ + return _osal_mdc_restorePciConfig(unit); +} + #endif /* End of NPS_LINUX_KERNEL_MODE */ /* --------------------------------------------------------------------------- Interrupt */ @@ -1458,7 +1587,7 @@ _osal_mdc_notifyUserProcess( /* set the device bitmap. */ spin_lock_irqsave(&_osal_mdc_isr_dev_bitmap_lock, flags); - _osal_mdc_isr_dev_bitmap |= (1 << unit); + _osal_mdc_isr_dev_bitmap |= (1U << unit); spin_unlock_irqrestore(&_osal_mdc_isr_dev_bitmap_lock, flags); /* notify user process. */ @@ -2045,12 +2174,12 @@ _osal_mdc_ioctl_connectIsrCallback( { NPS_ERROR_NO_T rc = NPS_E_OK; - if (0 == (_osal_mdc_isr_init_bitmap & (1 << unit))) + if (0 == (_osal_mdc_isr_init_bitmap & (1U << unit))) { rc = osal_mdc_connectIsr(unit, NULL, ptr_data); if (NPS_E_OK == rc) { - _osal_mdc_isr_init_bitmap |= (1 << unit); + _osal_mdc_isr_init_bitmap |= (1U << unit); } } return (rc); @@ -2065,11 +2194,27 @@ _osal_mdc_ioctl_disconnectIsrCallback( _osal_mdc_notifyUserProcess(unit); osal_mdc_disconnectIsr(unit); - _osal_mdc_isr_init_bitmap &= ~(1 << unit); + _osal_mdc_isr_init_bitmap &= ~(1U << unit); return (NPS_E_OK); } +static NPS_ERROR_NO_T +_osal_mdc_ioctl_savePciConfigCallback( + const UI32_T unit, + void *ptr_data) +{ + return _osal_mdc_savePciConfig(unit); +} + +static NPS_ERROR_NO_T +_osal_mdc_ioctl_restorePciConfigCallback( + const UI32_T unit, + void *ptr_data) +{ + return _osal_mdc_restorePciConfig(unit); +} + static NPS_ERROR_NO_T _osal_mdc_registerIoctlCallback( const OSAL_MDC_IOCTL_TYPE_T type, @@ -2126,6 +2271,12 @@ _osal_mdc_initIoctl(void) _osal_mdc_registerIoctlCallback(OSAL_MDC_IOCTL_TYPE_MDC_DISCONNECT_ISR, _osal_mdc_ioctl_disconnectIsrCallback); + + _osal_mdc_registerIoctlCallback(OSAL_MDC_IOCTL_TYPE_MDC_SAVE_PCI_CONFIG, + _osal_mdc_ioctl_savePciConfigCallback); + + _osal_mdc_registerIoctlCallback(OSAL_MDC_IOCTL_TYPE_MDC_RESTORE_PCI_CONFIG, + _osal_mdc_ioctl_restorePciConfigCallback); return (NPS_E_OK); } @@ -2221,6 +2372,8 @@ _osal_mdc_ioctl( /* type: DEINIT_DEV * DEINIT_RSRV_DMA_MEM * DISCONNECT_ISR + * SAVE_PCI_CONFIG + * RESTORE_PCI_CONFIG */ if (NPS_E_OK != ptr_cb->callback[type](unit, (void *)ptr_temp_buf)) { @@ -2308,10 +2461,10 @@ osal_mdc_module_exit(void) /* ref: _osal_mdc_ioctl_disconnectIsrCallback */ for (unit = 0; unit < NPS_CFG_MAXIMUM_CHIPS_PER_SYSTEM; unit++) { - if (0 != (_osal_mdc_isr_init_bitmap & (1 << unit))) + if (0 != (_osal_mdc_isr_init_bitmap & (1U << unit))) { osal_mdc_disconnectIsr(unit); - _osal_mdc_isr_init_bitmap &= ~(1 << unit); + _osal_mdc_isr_init_bitmap &= ~(1U << unit); } } @@ -2355,5 +2508,5 @@ osal_mdc_module_exit(void) module_init(osal_mdc_module_init); module_exit(osal_mdc_module_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Nephos"); +MODULE_AUTHOR("MediaTek"); MODULE_DESCRIPTION("SDK Kernel Module"); diff --git a/platform/nephos/one-image.mk b/platform/nephos/one-image.mk index 3651325456c7..60254051c5b5 100644 --- a/platform/nephos/one-image.mk +++ b/platform/nephos/one-image.mk @@ -8,7 +8,10 @@ $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9130_32X_PLATFORM_MODULE) \ $(INGRASYS_S9230_64X_PLATFORM_MODULE) \ $(ACCTON_AS7116_54X_PLATFORM_MODULE) \ - $(CIG_CS6436_56P_PLATFORM_MODULE) + $(CIG_CS6436_56P_PLATFORM_MODULE) \ + $(CIG_CS6436_54P_PLATFORM_MODULE) \ + $(CIG_CS5435_54P_PLATFORM_MODULE) + ifeq ($(INSTALL_DEBUG_TOOLS),y) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) diff --git a/platform/nephos/platform-modules-cig.mk b/platform/nephos/platform-modules-cig.mk index 98bbadf9ce3c..5cccf1692550 100644 --- a/platform/nephos/platform-modules-cig.mk +++ b/platform/nephos/platform-modules-cig.mk @@ -1,12 +1,26 @@ -# Cig CS6436 56P Platform modules +# Cig Nephos Switch Platform modules -CIG_CS6436_56P_PLATFORM_MODULE_VERSION = 1.0.0 +CIG_MTK_PLATFORM_MODULE_VERSION = 1.0.0 -export CIG_CS6436_56P_PLATFORM_MODULE_VERSION +export CIG_MTK_PLATFORM_MODULE_VERSION -CIG_CS6436_56P_PLATFORM_MODULE = sonic-platform-cig-cs6436-56p_$(CIG_CS6436_56P_PLATFORM_MODULE_VERSION)_amd64.deb +CIG_CS6436_56P_PLATFORM_MODULE = sonic-platform-cig-cs6436-56p_$(CIG_MTK_PLATFORM_MODULE_VERSION)_amd64.deb $(CIG_CS6436_56P_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cig $(CIG_CS6436_56P_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(CIG_CS6436_56P_PLATFORM_MODULE)_PLATFORM = x86_64-cig_cs6436_56p-r0 SONIC_DPKG_DEBS += $(CIG_CS6436_56P_PLATFORM_MODULE) -SONIC_STRETCH_DEBS += $(CIG_CS6436_56P_PLATFORM_MODULE) \ No newline at end of file +SONIC_STRETCH_DEBS += $(CIG_CS6436_56P_PLATFORM_MODULE) + +CIG_CS6436_54P_PLATFORM_MODULE = sonic-platform-cig-cs6436-54p_$(CIG_MTK_PLATFORM_MODULE_VERSION)_amd64.deb +$(CIG_CS6436_54P_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cig +$(CIG_CS6436_54P_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(CIG_CS6436_54P_PLATFORM_MODULE)_PLATFORM = x86_64-cig_cs6436_54p-r0 +SONIC_DPKG_DEBS += $(CIG_CS6436_54P_PLATFORM_MODULE) +SONIC_STRETCH_DEBS += $(CIG_CS6436_54P_PLATFORM_MODULE) + +CIG_CS5435_54P_PLATFORM_MODULE = sonic-platform-cig-cs5435-54p_$(CIG_MTK_PLATFORM_MODULE_VERSION)_amd64.deb +$(CIG_CS5435_54P_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cig +$(CIG_CS5435_54P_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(CIG_CS5435_54P_PLATFORM_MODULE)_PLATFORM = x86_64-cig_cs5435_54p-r0 +SONIC_DPKG_DEBS += $(CIG_CS5435_54P_PLATFORM_MODULE) +SONIC_STRETCH_DEBS += $(CIG_CS5435_54P_PLATFORM_MODULE) diff --git a/platform/nephos/sonic-platform-modules-accton/debian/control b/platform/nephos/sonic-platform-modules-accton/debian/control index 8f7258ebdd6a..639534f3edcc 100755 --- a/platform/nephos/sonic-platform-modules-accton/debian/control +++ b/platform/nephos/sonic-platform-modules-accton/debian/control @@ -7,5 +7,5 @@ Standards-Version: 3.9.3 Package: sonic-platform-accton-as7116-54x Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 -Description: kernel modules for platform devices such as fan, led, sfp \ No newline at end of file +Depends: linux-image-4.9.0-11-2-amd64 +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/__init__.py b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/__init__.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/fanutil.py b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/fanutil.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/thermalutil.py b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/thermalutil.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/Makefile b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/Makefile new file mode 100644 index 000000000000..446fde4b0a70 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/Makefile @@ -0,0 +1,6 @@ +obj-m :=x86-64-cig-cs5435-54p-sysfs.o \ + x86-64-cig-cs5435-54p-cpld.o \ + x86-64-cig-cs5435-54p-fan.o \ + x86-64-cig-cs5435-54p-led.o \ + x86-64-cig-cs5435-54p-psu.o \ + x86-64-cig-cs5435-54p-sfp.o diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/i2c-algo-lpc.h b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/i2c-algo-lpc.h new file mode 100644 index 000000000000..dc9e30d16ddd --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/i2c-algo-lpc.h @@ -0,0 +1,222 @@ +/* -------------------------------------------------------------------- + + * A hwmon driver for the CIG cs5435-54P + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* -------------------------------------------------------------------- */ + +#ifndef I2C_LPC_H +#define I2C_LPC_H 1 + +/* ----- Control register bits ---------------------------------------- */ +#define I2C_LPC_PIN 0x80 +#define I2C_LPC_ESO 0x40 +#define I2C_LPC_ES1 0x20 +#define I2C_LPC_ES2 0x10 +#define I2C_LPC_ENI 0x08 + +#define I2C_LPC_STO 0x40 +#define I2C_LPC_ACK 0x01 + +/*command register*/ +#define I2C_LPC_STA 0x80 +#define I2C_LPC_ABT 0x40 + +/*status register*/ +#define I2C_LPC_TBE 0x02 +#define I2C_LPC_IBB 0x80 +#define I2C_LPC_RBF 0x01 +#define I2C_LPC_TD 0x08 + +#define I2C_LPC_START I2C_LPC_STA +#define I2C_LPC_STOP I2C_LPC_STO +#define I2C_LPC_REPSTART I2C_LPC_STA +#define I2C_LPC_IDLE + +/* ----- Status register bits ----------------------------------------- */ +/*#define I2C_LPC_PIN 0x80 as above*/ + +#define I2C_LPC_INI 0x40 /* 1 if not initialized */ +#define I2C_LPC_STS 0x20 +#define I2C_LPC_BER 0x10 +#define I2C_LPC_AD0 0x08 +#define I2C_LPC_LRB 0x08 +#define I2C_LPC_AAS 0x04 +#define I2C_LPC_LAB 0x02 +#define I2C_LPC_BB 0x80 + +/* ----- Chip clock frequencies --------------------------------------- */ +#define I2C_LPC_CLK3 0x00 +#define I2C_LPC_CLK443 0x10 +#define I2C_LPC_CLK6 0x14 +#define I2C_LPC_CLK 0x18 +#define I2C_LPC_CLK12 0x1c + +/* ----- transmission frequencies ------------------------------------- */ +#define I2C_LPC_TRNS90 0x00 /* 90 kHz */ +#define I2C_LPC_TRNS45 0x01 /* 45 kHz */ +#define I2C_LPC_TRNS11 0x02 /* 11 kHz */ +#define I2C_LPC_TRNS15 0x03 /* 1.5 kHz */ + + +#define I2C_LPC_OWNADR 0 +#define I2C_LPC_INTREG I2C_LPC_ES2 +#define I2C_LPC_CLKREG I2C_LPC_ES1 + +#define I2C_LPC_REG_TEST 0x01 +#define I2C_LPC_REG_BUS_SEL 0x80 +#define I2C_LPC_REG_DEVICE_ADDR 0x81 +#define I2C_LPC_REG_BYTE_COUNT 0x83 +#define I2C_LPC_REG_COMMAND 0x84 +#define I2C_LPC_REG_STATUS 0x85 +#define I2C_LPC_REG_DATA_RX1 0x86 +#define I2C_LPC_REG_DATA_RX2 0x87 +#define I2C_LPC_REG_DATA_RX3 0x88 +#define I2C_LPC_REG_DATA_RX4 0x89 +#define I2C_LPC_REG_DATA_TX1 0x8a +#define I2C_LPC_REG_DATA_TX2 0x8b +#define I2C_LPC_REG_DATA_TX3 0x8c +#define I2C_LPC_REG_DATA_TX4 0x8d + + +#define ADDR_REG_SFP_STATUS_ADDR 0X62 //reg addr +R/W# //1031 +#define ADDR_REG_SFP_STATUS_TX 0X63 // write data +#define ADDR_REG_SFP_STATUS_RX 0X64 //read data +#define ADDR_REG_SFP_STATUS_COMMAND 0X65 //cmd bit7=1,go +#define ADDR_REG_SFP_STATUS_STATUS 0X66 //status + +#define CPLD_MASTER_INTERRUPT_STATUS_REG 0x20 +#define CPLD_MASTER_INTERRUPT_MASK_REG 0x21 +#define CPLD_MASTER_INTERRUPT_ALL 0x3f +#define CPLD_MASTER_INTERRUPT_CPLD2 0x20 +#define CPLD_MASTER_INTERRUPT_CPLD1 0x10 +#define CPLD_MASTER_INTERRUPT_PSU2 0x08 +#define CPLD_MASTER_INTERRUPT_PSU1 0x04 +#define CPLD_MASTER_INTERRUPT_6320 0x02 +#define CPLD_MASTER_INTERRUPT_LSW 0x01 + + + +#define CPLD_SLAVE1_INTERRUPT_STATUS_L_REG 0x20 +#define CPLD_SLAVE1_INTERRUPT_STATUS_H_REG 0x21 +#define CPLD_SLAVE2_INTERRUPT_STATUS_L_REG 0x22 +#define CPLD_SLAVE2_INTERRUPT_STATUS_H_REG 0x23 +#define CPLD_SLAVE1_INTERRUPT_MASK_REG 0x24 +#define CPLD_SLAVE2_INTERRUPT_MASK_REG 0x25 + + +#define CPLD_SLAVE1_PRESENT08_REG 0x01 +#define CPLD_SLAVE1_PRESENT16_REG 0x02 +#define CPLD_SLAVE1_PRESENT24_REG 0x03 +#define CPLD_SLAVE2_PRESENT32_REG 0x04 +#define CPLD_SLAVE2_PRESENT40_REG 0x05 +#define CPLD_SLAVE2_PRESENT48_REG 0x06 + +#define CPLD_SLAVE1_RX_LOST08_REG 0x07 +#define CPLD_SLAVE1_RX_LOST16_REG 0x08 +#define CPLD_SLAVE1_RX_LOST24_REG 0x09 +#define CPLD_SLAVE2_RX_LOST32_REG 0x0a +#define CPLD_SLAVE2_RX_LOST40_REG 0x0b +#define CPLD_SLAVE2_RX_LOST48_REG 0x0c + +#define CPLD_SLAVE1_TX_FAULT08_REG 0x0d +#define CPLD_SLAVE1_TX_FAULT16_REG 0x0e +#define CPLD_SLAVE1_TX_FAULT24_REG 0x0f +#define CPLD_SLAVE2_TX_FAULT32_REG 0x10 +#define CPLD_SLAVE2_TX_FAULT40_REG 0x11 +#define CPLD_SLAVE2_TX_FAULT48_REG 0x12 + +#define CPLD_SLAVE2_PRESENT56_REG 0x19 +#define CPLD_SLAVE2_QSFP_CR56_REG 0x1a + + +#define CPLD_SLAVE1_INTERRUPT_PRESENT08 0x0001 +#define CPLD_SLAVE1_INTERRUPT_PRESENT16 0x0002 +#define CPLD_SLAVE1_INTERRUPT_PRESENT24 0x0004 +#define CPLD_SLAVE2_INTERRUPT_PRESENT32 0x0001 +#define CPLD_SLAVE2_INTERRUPT_PRESENT40 0x0002 +#define CPLD_SLAVE2_INTERRUPT_PRESENT48 0x0004 + +#define CPLD_SLAVE2_INTERRUPT_QSFP_CR56 0x0200 +#define CPLD_SLAVE2_INTERRUPT_PRESENT56 0x0400 + +#define CPLD_SLAVE1_INTERRUPT_RX_LOST08 0x0008 +#define CPLD_SLAVE1_INTERRUPT_RX_LOST16 0x0010 +#define CPLD_SLAVE1_INTERRUPT_RX_LOST24 0x0020 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST32 0x0008 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST40 0x0010 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST48 0x0020 + +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT08 0x0040 +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT16 0x0080 +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT24 0x0100 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT32 0x0040 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT40 0x0080 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT48 0x0100 + + + + + + + +#define WAIT_TIME_OUT_COUNT 100 + + +struct i2c_algo_lpc_data { + void *data; /* private data for lolevel routines */ + void (*setlpc) (void *data, int ctl, int val); + int (*getlpc) (void *data, int ctl); + int (*getown) (void *data); + int (*getclock) (void *data); + void (*waitforpin) (void *data); + + int (*xfer_begin) (void *data); + int (*xfer_end) (void *data); + + /* Multi-master lost arbitration back-off delay (msecs) + * This should be set by the bus adapter or knowledgable client + * if bus is multi-mastered, else zero + */ + unsigned long lab_mdelay; +}; + + +struct subsys_private { + struct kset subsys; + struct kset *devices_kset; + struct list_head interfaces; + struct mutex mutex; + + struct kset *drivers_kset; + struct klist klist_devices; + struct klist klist_drivers; + struct blocking_notifier_head bus_notifier; + unsigned int drivers_autoprobe:1; + struct bus_type *bus; + + struct kset glue_dirs; + struct class *class; +}; + +void cs5435_54p_sysfs_add_client(struct i2c_client *client); +void cs5435_54p_sysfs_remove_client(struct i2c_client *client); + + +#endif /* I2C_LPC8584_H */ diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-cpld.c b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-cpld.c new file mode 100644 index 000000000000..68f1192e58b1 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-cpld.c @@ -0,0 +1,2209 @@ +/* + * A hwmon driver for the CIG cs5435-54P CPLD + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "i2c-algo-lpc.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef CPLD_USER +# include +#else +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + + + + + +/********************************************** Start ********************************************************/ + +/* + * ISA bus. + */ + +static void platform_isa_bus_release(struct device * dev) +{ + return ; +} + + +static struct device isa_bus = { + .init_name = "lpc-isa", + .release = platform_isa_bus_release, +}; + +struct isa_dev { + struct device dev; + struct device *next; + unsigned int id; +}; + +#define to_isa_dev(x) container_of((x), struct isa_dev, dev) + +static int isa_bus_match(struct device *dev, struct device_driver *driver) +{ + struct isa_driver *isa_driver = to_isa_driver(driver); + + if (dev->platform_data == isa_driver) { + if (!isa_driver->match || + isa_driver->match(dev, to_isa_dev(dev)->id)) + return 1; + dev->platform_data = NULL; + } + return 0; +} + +static int isa_bus_probe(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->probe) + return isa_driver->probe(dev, to_isa_dev(dev)->id); + + return 0; +} + +static int isa_bus_remove(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->remove) + return isa_driver->remove(dev, to_isa_dev(dev)->id); + + return 0; +} + +static void isa_bus_shutdown(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->shutdown) + isa_driver->shutdown(dev, to_isa_dev(dev)->id); +} + +static int isa_bus_suspend(struct device *dev, pm_message_t state) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->suspend) + return isa_driver->suspend(dev, to_isa_dev(dev)->id, state); + + return 0; +} + +static int isa_bus_resume(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->resume) + return isa_driver->resume(dev, to_isa_dev(dev)->id); + + return 0; +} + +static struct bus_type isa_bus_type = { + .name = "lpc-isa", + .match = isa_bus_match, + .probe = isa_bus_probe, + .remove = isa_bus_remove, + .shutdown = isa_bus_shutdown, + .suspend = isa_bus_suspend, + .resume = isa_bus_resume +}; + +static void isa_dev_release(struct device *dev) +{ + kfree(to_isa_dev(dev)); +} + +void lpc_unregister_driver(struct isa_driver *isa_driver) +{ + struct device *dev = isa_driver->devices; + + while (dev) { + struct device *tmp = to_isa_dev(dev)->next; + device_unregister(dev); + dev = tmp; + } + driver_unregister(&isa_driver->driver); +} + + +int lpc_register_driver(struct isa_driver *isa_driver, unsigned int ndev) +{ + int error; + unsigned int id; + + isa_driver->driver.bus = &isa_bus_type; + isa_driver->devices = NULL; + + error = driver_register(&isa_driver->driver); + if (error) + return error; + + for (id = 0; id < ndev; id++) { + struct isa_dev *isa_dev; + + isa_dev = kzalloc(sizeof *isa_dev, GFP_KERNEL); + if (!isa_dev) { + error = -ENOMEM; + break; + } + + isa_dev->dev.parent = &isa_bus; + isa_dev->dev.bus = &isa_bus_type; + + dev_set_name(&isa_dev->dev, "%s.%u", + isa_driver->driver.name, id); + isa_dev->dev.platform_data = isa_driver; + isa_dev->dev.release = isa_dev_release; + isa_dev->id = id; + + isa_dev->dev.coherent_dma_mask = DMA_BIT_MASK(24); + isa_dev->dev.dma_mask = &isa_dev->dev.coherent_dma_mask; + + error = device_register(&isa_dev->dev); + if (error) { + put_device(&isa_dev->dev); + break; + } + + if (isa_dev->dev.platform_data) { + isa_dev->next = isa_driver->devices; + isa_driver->devices = &isa_dev->dev; + } else + device_unregister(&isa_dev->dev); + } + + if (!error && !isa_driver->devices) + error = -ENODEV; + + if (error) + isa_unregister_driver(isa_driver); + + return error; +} + + +int lpc_bus_init(void) +{ + int error; + + error = bus_register(&isa_bus_type); + if (!error) { + error = device_register(&isa_bus); + if (error) + bus_unregister(&isa_bus_type); + } + return error; +} + +void lpc_bus_exit(void) +{ + + device_unregister(&isa_bus); + + bus_unregister(&isa_bus_type); +} + + +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ +/* + * module parameters: + */ +static int i2c_debug = 0; +static struct mutex lpc_lock; + + +#define DEB2(x) if (i2c_debug == 2) x +#define DEB3(x) if (i2c_debug == 3) x + /* print several statistical values */ +#define DEBPROTO(x) if (i2c_debug == 9) x; + /* debug the protocol by showing transferred bits */ +#define DEF_TIMEOUT 160 + + + +/* setting states on the bus with the right timing: */ + +#define set_lpc(adap, ctl, val) adap->setlpc(adap->data, ctl, val) +#define get_lpc(adap, ctl) adap->getlpc(adap->data, ctl) +#define get_own(adap) adap->getown(adap->data) +#define get_clock(adap) adap->getclock(adap->data) +#define i2c_outaddr(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DEVICE_ADDR, val) + +#define i2c_outbyte1(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX1, val) +#define i2c_outbyte2(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX2, val) +#define i2c_outbyte3(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX3, val) +#define i2c_outbyte4(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX4, val) +#define i2c_inbyte1(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX1) +#define i2c_inbyte2(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX2) +#define i2c_inbyte3(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX3) +#define i2c_inbyte4(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX4) + + + +#define LPC_FPRINTF_LOG_PATH "/tmp/file.log" +struct file *lpc_fprintf_file = NULL; + +static int lpc_fprintf_debug(const char *fmt, ...) +{ + char lpc_fprintf_buf[256]={0}; + struct va_format vaf; + va_list args; + int r; + mm_segment_t old_fs; + struct timeval tv; + struct rtc_time tm; + + do_gettimeofday(&tv); + + rtc_time_to_tm(tv.tv_sec,&tm); + + va_start(args, fmt); + vaf.fmt = fmt; + vaf.va = &args; + r=snprintf(lpc_fprintf_buf,sizeof(lpc_fprintf_buf),"[%04d.%08d] %pV\n",tm.tm_sec, (int)tv.tv_usec, &vaf); + va_end(args); + old_fs = get_fs(); + set_fs(KERNEL_DS); + vfs_write(lpc_fprintf_file, (char *)&lpc_fprintf_buf, strlen(lpc_fprintf_buf), &lpc_fprintf_file->f_pos); + set_fs(old_fs); + memset(lpc_fprintf_buf,0x0,sizeof(lpc_fprintf_buf)); + return r; + +} + + + +static int lpc_fprintf_init(void) +{ + printk("lpc_fprintf_init.\n"); + + if(lpc_fprintf_file == NULL) + lpc_fprintf_file = filp_open(LPC_FPRINTF_LOG_PATH, O_RDWR | O_APPEND | O_CREAT, 0644); + + if (IS_ERR(lpc_fprintf_file)) { + printk("Error occured while opening file %s, exiting...\n", LPC_FPRINTF_LOG_PATH); + return -1; + } + + return 0; +} + +static int lpc_fprintf_exit(void) +{ + printk("lpc_fprintf_exit.\n"); + + if(lpc_fprintf_file != NULL) + filp_close(lpc_fprintf_file, NULL); + + return 0; +} + + +/* other auxiliary functions */ + + +void print_reg(struct i2c_algo_lpc_data *adap) +{ + unsigned char status; + DEBPROTO(lpc_fprintf_debug("================================================\n");) + status = get_lpc(adap, I2C_LPC_REG_BUS_SEL); + DEBPROTO(lpc_fprintf_debug("%s select reg %x : %x\n",__func__,I2C_LPC_REG_BUS_SEL, status);) + status = get_lpc(adap, I2C_LPC_REG_BYTE_COUNT); + DEBPROTO(lpc_fprintf_debug("%s count reg %x : %x\n",__func__,I2C_LPC_REG_BYTE_COUNT, status);) + + status = get_lpc(adap, I2C_LPC_REG_COMMAND); + DEBPROTO(lpc_fprintf_debug("%s command reg %x : %x\n",__func__,I2C_LPC_REG_COMMAND, status);) + status = get_lpc(adap, I2C_LPC_REG_DEVICE_ADDR); + DEBPROTO(lpc_fprintf_debug("%s address reg %x : %x\n",__func__,I2C_LPC_REG_DEVICE_ADDR, status);) + + status = get_lpc(adap, I2C_LPC_REG_STATUS); + DEBPROTO(lpc_fprintf_debug("%s status reg %x : %x\n",__func__,I2C_LPC_REG_STATUS, status);) +} + + + +static void i2c_repstart(struct i2c_algo_lpc_data *adap) +{ + DEBPROTO(lpc_fprintf_debug("%s :\n",__func__);) + set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_REPSTART); +} + +static void i2c_stop(struct i2c_algo_lpc_data *adap) +{ + DEBPROTO(lpc_fprintf_debug("%s :\n",__func__);) + set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_STOP); + udelay(60); + set_lpc(adap, I2C_LPC_REG_COMMAND, 0x00); +} + + + + +static void i2c_start(struct i2c_algo_lpc_data *adap) +{ + print_reg(adap); + + set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_START); + + print_reg(adap); +} + + + + +static int wait_for_bb(struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + int status; + + while (--timeout) { + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus free status : %x\n",__func__,status);) + + if(status == I2C_LPC_TD) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is free status : %x\n",__func__,status);) + break; + } + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout for free busy status : %x\n",__func__,status);) + return -ETIMEDOUT; + } + + + + return 0; +} + + +static int wait_for_be(int mode,struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + unsigned char status; + + + while (--timeout) { + + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus empty status : %x\n",__func__,status);) + + if(mode == 1) + { + if((status & I2C_LPC_IBB) && (status & I2C_LPC_TBE)) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is empty status : %x\n",__func__,status);) + break; + } + } + else + { + if(status & I2C_LPC_TD) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is empty status : %x\n",__func__,status);) + break; + } + } + + status = get_lpc(adap, I2C_LPC_REG_TEST); + + DEBPROTO(lpc_fprintf_debug("%s : The test register data : %x\n",__func__,status);) + udelay(1); /* wait for 100 us */ + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Empty\n",__func__);) + return -ETIMEDOUT; + } + + return 0; +} + + +static int wait_for_bf(struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + int status; + + + while (--timeout) { + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus full status : %x\n",__func__,status);) + + if(status & I2C_LPC_RBF) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is full status : %x\n",__func__,status);) + break; + } + + status = get_lpc(adap, I2C_LPC_REG_TEST); + + DEBPROTO(lpc_fprintf_debug("%s : The test register data : %x\n",__func__,status);) + udelay(1); /* wait for 100 us */ + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Full\n",__func__);) + return -ETIMEDOUT; + } + + return 0; +} + +static int wait_for_td(struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + int status=0; + + while (--timeout) { + udelay(4); + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus done status : %x\n",__func__,status);) + + if(status == I2C_LPC_TD) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is done status : %x\n",__func__,status);) + break; + } + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Done\n",__func__);) + return -ETIMEDOUT; + } + + return 0; +} + + + +static int wait_for_pin(struct i2c_algo_lpc_data *adap, int *status) +{ + int timeout = DEF_TIMEOUT; + *status = get_lpc(adap, I2C_LPC_REG_STATUS); + + while ((*status & I2C_LPC_TBE) && --timeout) { + *status = get_lpc(adap, I2C_LPC_REG_STATUS); + } + + if (timeout == 0) + return -ETIMEDOUT; + + + return 0; +} + + +static int lpc_doAddress(struct i2c_algo_lpc_data *adap,struct i2c_msg *msg) +{ + unsigned short flags = msg->flags; + unsigned char addr; + + addr = msg->addr << 1; + if (flags & I2C_M_RD) + { + addr |= 1; + DEBPROTO(lpc_fprintf_debug("step 7 : read mode then write device address 0x%x\n",addr);) + } + else + { + DEBPROTO(lpc_fprintf_debug("step 2 : write mode then write device address 0x%x\n",addr);) + } + + if (flags & I2C_M_REV_DIR_ADDR) + { + addr ^= 1; + + } + i2c_outaddr(adap, addr); + return 0; + +} + + +static int lpc_sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; + int i = 0,timeout=0; + + unsigned int count = msg->len; + unsigned char *buf = msg->buf; + + do{ + lpc_doAddress(adap,msg); + set_lpc(adap, I2C_LPC_REG_BYTE_COUNT, (count-i) >= 4 ? 4:(count - i)); + DEBPROTO(lpc_fprintf_debug("step 3 : write register count %x\n",count);) + + if((count -i) >= 4) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + i2c_outbyte2(adap, buf[i+1] & 0xff); + i2c_outbyte3(adap, buf[i+2] & 0xff); + i2c_outbyte4(adap, buf[i+3] & 0xff); + + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+2,buf[i+2]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+3,buf[i+3]);) + i += 4; + } + else if((count -i) == 3) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + i2c_outbyte2(adap, buf[i+1] & 0xff); + i2c_outbyte3(adap, buf[i+2] & 0xff); + + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+2,buf[i+2]);) + + i += 3; + } + else if((count -i) == 2) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + i2c_outbyte2(adap, buf[i+1] & 0xff); + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+1,buf[i+1]);) + i += 2; + } + else if((count -i) == 1) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + i += 1; + } + + /* Send START */ + DEBPROTO(lpc_fprintf_debug("step 5-1 : Delay 6mS \n");) + udelay(6000); + DEBPROTO(lpc_fprintf_debug("step 5-2 : Start to transfrom \n");) + i2c_stop(adap); + i2c_start(adap); + DEBPROTO(lpc_fprintf_debug("step 5-3 : Start done\n");) + + udelay(400); + DEBPROTO(lpc_fprintf_debug("step 6 : Waiting for BE\n");) + timeout = wait_for_td(adap); + if (timeout) { + DEBPROTO(lpc_fprintf_debug("step 6 : Timeout waiting for BE \n");) + return -EREMOTEIO; + } + }while (i < count); + + if(i == count) + { + DEBPROTO(lpc_fprintf_debug("Writen %d bytes successd !\n",count);) + return i; + } + else + { + DEBPROTO(lpc_fprintf_debug("Writen %d bytes failed \n",count);) + return -EIO; + } +} + +static int lpc_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + int i=0,timeout=0; + struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; + + unsigned int count = msg->len; + unsigned char *buf = msg->buf; + + do{ + lpc_doAddress(adap,msg); + set_lpc(adap, I2C_LPC_REG_BYTE_COUNT, (count-i) >= 4 ? 4:(count - i)); + DEBPROTO(lpc_fprintf_debug("step 8 : write register count %d\n",count);) + + /* Send START */ + DEBPROTO(lpc_fprintf_debug("step 9-1 : Delay 6mS\n");) + udelay(6000); + DEBPROTO(lpc_fprintf_debug("step 9-2 : Start to receive data\n");) + i2c_stop(adap); + i2c_start(adap); + DEBPROTO(lpc_fprintf_debug("step 9-3 : Start done\n");) + + udelay(400); + DEBPROTO(lpc_fprintf_debug("step 10 : Waiting for TD\n");) + timeout = wait_for_td(adap); + if (timeout) { + DEBPROTO(lpc_fprintf_debug("step 10 : Timeout waiting for TD \n");) + return -EREMOTEIO; + } + + if((count -i) >= 4) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + buf[i+1] = 0xff & i2c_inbyte2(adap); + buf[i+2] = 0xff & i2c_inbyte3(adap); + buf[i+3] = 0xff & i2c_inbyte4(adap); + + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+2,buf[i+2]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+3,buf[i+3]);) + + i += 4; + } + else if((count -i) == 3) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + buf[i+1] = 0xff & i2c_inbyte2(adap); + buf[i+2] = 0xff & i2c_inbyte3(adap); + + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+2,buf[i+2]);) + + i += 3; + } + else if((count -i) == 2) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + buf[i+1] = 0xff & i2c_inbyte2(adap); + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+1,buf[i+1]);) + i += 2; + } + else if((count -i) == 1) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + i += 1; + } + + + }while(i < count); + + if(i == count) + { + DEBPROTO(lpc_fprintf_debug("Read %d bytes successd !\n",count);) + return i; + } + else + { + DEBPROTO(lpc_fprintf_debug("Read %d bytes failed \n",count);) + return -EIO; + } +} + + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; +#define LPC_I2C_MAX_NCHANS 6 + + +struct lpc_iic { + struct i2c_adapter *virt_adaps[LPC_I2C_MAX_NCHANS]; + u8 last_chan; /* last register value */ +}; + + +static int lpc_master_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg *msgs, + int num) +{ + struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; + struct i2c_msg *pmsg; + int i; + int ret=0; + + mutex_lock(&lpc_lock); + + if (adap->xfer_begin) + adap->xfer_begin(&i2c_adap->nr); + + + for (i = 0;ret >= 0 && i < num; i++) { + pmsg = &msgs[i]; + + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n", + pmsg->flags & I2C_M_RD ? "read" : "write", + pmsg->len, pmsg->addr, i + 1, num);) + + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n", + i, msgs[i].addr, msgs[i].flags, msgs[i].len);) + + if (pmsg->flags & I2C_M_RD) { + ret = lpc_readbytes(i2c_adap, pmsg); + + if (ret != pmsg->len) { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: fail: " + "only read %d bytes.\n",ret)); + } else { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: read %d bytes.\n",ret)); + } + } else { + + ret = lpc_sendbytes(i2c_adap, pmsg); + + if (ret != pmsg->len) { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: fail: " + "only wrote %d bytes.\n",ret)); + } else { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: wrote %d bytes.\n",ret)); + } + } + } + + if (adap->xfer_end) + adap->xfer_end(&i2c_adap->nr); + + mutex_unlock(&lpc_lock); + + DEBPROTO(lpc_fprintf_debug("ret = 0x%x num = 0x%x i = 0x%x.\n",ret,num,i)); + + return ret = (ret < 0) ? ret : num; +} + + +static u32 lpc_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_QUICK; +} + +/* exported algorithm data: */ +static const struct i2c_algorithm lpc_algo = { + .master_xfer = lpc_master_xfer, + //.smbus_xfer = lpc_smbus_xfer, + .functionality = lpc_func, +}; + + +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ +#define DEFAULT_BASE 0x0a00 + +static int lpc_base= 0x0a00; +static u8 __iomem *lpc_base_iomem; + +static int lpc_irq; +static int lpc_clock = 0x1c; +static int lpc_own = 0x55; +static int lpc_mmapped; + +static unsigned long lpc_base_addr = 0x0a00; +static unsigned int lpc_io_space_size = 2; + +static unsigned long LPC_INDEX_REG; +static unsigned long LPC_DATA_REG; + + +/* notice : removed static struct i2c_lpc_iic gpi; code - + this module in real supports only one device, due to missing arguments + in some functions, called from the algo-lpc module. Sometimes it's + need to be rewriten - but for now just remove this for simpler reading */ + +static wait_queue_head_t lpc_wait; +static int lpc_pending; +static spinlock_t lock; +static spinlock_t lpc_slock; + +static struct i2c_adapter lpc_iic_ops; + +struct cpld_dev_type { + struct resource *io_resource; + struct semaphore sem; + struct cdev cdev; +}; + +struct cpld_dev_type *cpld_device; + + +/* ----- local functions ---------------------------------------------- */ + +static void lpc_cpld_setbyte(void *data, int ctl, int val) +{ + outb(ctl, LPC_INDEX_REG); + mb(); + + outb(val, LPC_DATA_REG); + mb(); +} + +static int lpc_cpld_getbyte(void *data, int ctl) +{ + u8 val = 0; + + outb(ctl, LPC_INDEX_REG); + mb(); + + val = inb(LPC_DATA_REG); + mb(); + + return val; +} + +static void lpc_iic_setbyte(void *data, int ctl, int val) +{ + if (!cpld_device) + { + return ; + } + + if (down_interruptible(&cpld_device->sem)) + { + return ; + } + + + lpc_cpld_setbyte(data,ctl,val); + + up(&cpld_device->sem); + DEBPROTO(lpc_fprintf_debug("%s REG[%x] = %x\n",__func__,ctl,val);) +} + + +static int lpc_iic_getbyte(void *data, int ctl) +{ + u8 val = 0; + if (!cpld_device) + return -ENOTTY; + + if (down_interruptible(&cpld_device->sem)) + return -ERESTARTSYS; + + val = lpc_cpld_getbyte(data,ctl); + + up(&cpld_device->sem); + DEBPROTO(lpc_fprintf_debug("%s REG[%x] = %x\n",__func__,ctl,val);) + return val; +} + +int cig_cpld_read_register(u8 reg_off, u8 *val) +{ + if (!cpld_device) + return -ENOTTY; + + if (down_interruptible(&cpld_device->sem)) + return -ERESTARTSYS; + + *val = lpc_cpld_getbyte(cpld_device, reg_off); + + up(&cpld_device->sem); + + return 0; +} +EXPORT_SYMBOL(cig_cpld_read_register); + +int cig_cpld_write_register(u8 reg_off, u8 val) +{ + if (!cpld_device) + return -ENOTTY; + + if (down_interruptible(&cpld_device->sem)) + return -ERESTARTSYS; + + lpc_cpld_setbyte(cpld_device, reg_off, val); + up(&cpld_device->sem); + return 0; +} +EXPORT_SYMBOL(cig_cpld_write_register); + + + +static int lpc_iic_getown(void *data) +{ + return (lpc_own); +} + + +static int lpc_iic_getclock(void *data) +{ + return (lpc_clock); +} + +static void lpc_iic_waitforpin(void *data) +{ + DEFINE_WAIT(wait); + int timeout = 2; + unsigned long flags; + + if (lpc_irq > 0) { + spin_lock_irqsave(&lock, flags); + if (lpc_pending == 0) { + spin_unlock_irqrestore(&lock, flags); + prepare_to_wait(&lpc_wait, &wait, TASK_INTERRUPTIBLE); + if (schedule_timeout(timeout*HZ)) { + spin_lock_irqsave(&lock, flags); + if (lpc_pending == 1) { + lpc_pending = 0; + } + spin_unlock_irqrestore(&lock, flags); + } + finish_wait(&lpc_wait, &wait); + } else { + lpc_pending = 0; + spin_unlock_irqrestore(&lock, flags); + } + } else { + udelay(100); + } +} + + +static irqreturn_t lpc_iic_handler(int this_irq, void *dev_id) { + spin_lock(&lock); + lpc_pending = 1; + spin_unlock(&lock); + wake_up_interruptible(&lpc_wait); + return IRQ_HANDLED; +} + +static int board_id = 0; + + +static int lpc_iic_select(void *data) +{ + unsigned int chan_id=0; + chan_id = *(unsigned int *)data; + chan_id -= 2; + DEBPROTO(lpc_fprintf_debug("step 1 : selest channel id = %d\n",chan_id);) + lpc_iic_setbyte(data,I2C_LPC_REG_BUS_SEL,chan_id); + + return 0; +} + +static int lpc_iic_deselect(void *data) +{ + + unsigned int chan_id=0; + chan_id = *(unsigned int *)data; + chan_id -= 2; + DEBPROTO(lpc_fprintf_debug("step last :deselect channel id = %d\n",chan_id);) + + return 0; +} + + +/* ------------------------------------------------------------------------ + * Encapsulate the above functions in the correct operations structure. + * This is only done when more than one hardware adapter is supported. + */ +static struct i2c_algo_lpc_data lpc_iic_data = { + .setlpc = lpc_iic_setbyte, + .getlpc = lpc_iic_getbyte, + .getown = lpc_iic_getown, + .getclock = lpc_iic_getclock, + .waitforpin = lpc_iic_waitforpin, + .xfer_begin = lpc_iic_select, + .xfer_end = lpc_iic_deselect, +}; + +#include + +static struct i2c_adapter lpc_iic_arr_ops[LPC_I2C_MAX_NCHANS] = {0}; + +static void dummy_setscl(void *data, int state) +{ + return; +} + +static void dummy_setsda(void *data, int state) +{ + return; + +} + +static int dummy_getscl(void *data) +{ + return 1; + +} + +static int dummy_getsda(void *data) +{ + return 1; +} + + +static struct i2c_algo_bit_data dummy_algo_data = { + .setsda = dummy_setsda, + .setscl = dummy_setscl, + .getsda = dummy_getsda, + .getscl = dummy_getscl, + .udelay = 50, + .timeout = HZ, +}; + + +static int dummy_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg *msgs, + int num) +{ + return 1; +} + +static u32 dummy_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_QUICK; +} + + +static const struct i2c_algorithm dummy_algo = { + .master_xfer = dummy_xfer, + .functionality = dummy_func, +}; + + + +static struct i2c_adapter i2c_dummy = { + .owner = THIS_MODULE, + .class = I2C_CLASS_HWMON, + .algo_data = &dummy_algo_data, + .algo = &dummy_algo, + .name = "i2c_dummy", +}; + + +static int lpc_iic_match(struct device *dev, unsigned int id) +{ + /* sanity checks for lpc_mmapped I/O */ + + DEB2(printk("lpc_iic_match\n");) + + + if (lpc_base < DEFAULT_BASE) { + dev_err(dev, "incorrect lpc_base address (%#x) specified " + "for lpc_mmapped I/O\n", lpc_base); + return 0; + } + + if (lpc_base == 0) { + lpc_base = DEFAULT_BASE; + } + return 1; +} + +static int lpc_iic_probe(struct device *dev, unsigned int id) +{ + int rval,num; + + lpc_fprintf_init(); + + DEB2(printk("lpc_iic_probe\n");) + + mutex_init(&lpc_lock); + + for(num = 0; num < LPC_I2C_MAX_NCHANS;num++) + { + lpc_iic_arr_ops[num].dev.parent = dev; + lpc_iic_arr_ops[num].owner = THIS_MODULE; + lpc_iic_arr_ops[num].class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + lpc_iic_arr_ops[num].algo = &lpc_algo; + lpc_iic_arr_ops[num].algo_data = &lpc_iic_data, + lpc_iic_arr_ops[num].nr=num; + snprintf(lpc_iic_arr_ops[num].name, sizeof(lpc_iic_arr_ops[num].name), "i2c-%d-lpc", i2c_adapter_id(&lpc_iic_arr_ops[num])); + rval |= i2c_add_adapter(&lpc_iic_arr_ops[num]); + DEB2(printk("%s\n",lpc_iic_arr_ops[num].name);) + } + + return 0; +} + +static int lpc_iic_remove(struct device *dev, unsigned int id) +{ + int num; + DEB2(printk("lpc_iic_remove\n")); + + lpc_fprintf_exit(); + for(num = LPC_I2C_MAX_NCHANS - 1; num >= 0 ;num--) + i2c_del_adapter(&lpc_iic_arr_ops[num]); + + + return 0; +} + +static struct isa_driver i2c_lpc_driver = { + .match = lpc_iic_match, + .probe = lpc_iic_probe, + .remove = lpc_iic_remove, + .driver = { + .owner = THIS_MODULE, + .name = "lpc-iic", + }, +}; + +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ + +static int cpld_major = 0; +static int cpld_minor = 0; + +struct cpld_rw_msg { + unsigned char addr; + unsigned char data; +}; + + +static struct cpld_rw_msg param_read = {-1}; +static struct cpld_rw_msg param_write = {-1}; +static struct cpld_rw_msg param_reads = {-1}; +static struct cpld_rw_msg param_writes = {-1}; + +void cpld_sysfs_kobj_release(struct kobject *kobj) +{ + return; +} + +int cpld_sysfs_add_attr(struct kobject* kobj, char* attr_name) +{ + + struct attribute *attr; + + attr = kmalloc(sizeof(struct attribute), GFP_KERNEL); + attr->name = attr_name; + attr->mode = 0644; + + return sysfs_create_file(kobj, attr); +} + +static int cig_cpld_write_slave_cpld_register(u8 reg_addr, u8 reg_data); +static int cig_cpld_read_slave_cpld_register(u8 reg_addr, u8 *reg_data); + + +static ssize_t cpld_sysfs_show(struct kobject *kobj, struct attribute *attr, char *buffer) +{ + u8 val=0,ret=0,year=0,month=0,day=0,cpld_m=0,cpld_1=0,cpld_2=0; + + if (0 == strcmp(attr->name, "read")) + { + val = lpc_iic_getbyte(NULL,param_read.addr); + ret = sprintf(buffer,"read : addr = 0x%x val = 0x%x\n",param_read.addr, val); + + } + else if (0 == strcmp(attr->name, "write")) + { + lpc_iic_setbyte(NULL, param_write.addr,param_write.data); + ret = sprintf(buffer,"write : addr = 0x%x val = 0x%x\n",param_write.addr, param_write.data); + } + else if (0 == strcmp(attr->name, "version")) + { + cpld_m = lpc_iic_getbyte(NULL, 0x02); + year = lpc_iic_getbyte(NULL, 0x03); + month = lpc_iic_getbyte(NULL, 0x04); + day = lpc_iic_getbyte(NULL, 0x05); + + cig_cpld_read_slave_cpld_register(0x1d,&cpld_1); + cig_cpld_read_slave_cpld_register(0x1e,&cpld_2); + + ret = sprintf(buffer,"Main CPLD version : V%02x\n"\ + "Main CPLD date : 20%02x-%02x-%02x\n"\ + "Slave 1 CPLD version : V%02x\n"\ + "Slave 2 CPLD version : V%02x\n",cpld_m,year,month,day,cpld_1,cpld_2); + } + if (0 == strcmp(attr->name, "reads")) + { + ret = cig_cpld_read_slave_cpld_register(param_reads.addr,&val); + if (ret < 0) + printk("ERROR:Failed to read slave cpld.\n"); + ret = sprintf(buffer,"reads : addr = 0x%x val = 0x%x\n",param_reads.addr, val); + + } + else if (0 == strcmp(attr->name, "writes")) + { + ret = cig_cpld_write_slave_cpld_register(param_writes.addr,param_writes.data); + if (ret < 0) + printk("ERROR:Failed to read slave cpld.\n"); + ret = sprintf(buffer,"writes : addr = 0x%x val = 0x%x\n",param_writes.addr, param_writes.data); + } + + + return ret; + +} + +static ssize_t cpld_sysfs_store(struct kobject *kobj, struct attribute *attr, const char *buffer, size_t count) +{ + int param[3]; + + if (0 == strcmp(attr->name, "read")) + { + sscanf(buffer, "0x%02x", ¶m[0]); + param_read.addr = param[0]; + } + else if (0 == strcmp(attr->name, "write")) + { + sscanf(buffer, "0x%2x 0x%02x", ¶m[0], ¶m[1]); + param_write.addr = param[0]; + param_write.data = param[1]; + } + if (0 == strcmp(attr->name, "reads")) + { + sscanf(buffer, "0x%02x", ¶m[0]); + param_reads.addr = param[0]; + } + else if (0 == strcmp(attr->name, "writes")) + { + sscanf(buffer, "0x%2x 0x%02x", ¶m[0], ¶m[1]); + param_writes.addr = param[0]; + param_writes.data = param[1]; + } + return count; +} + + + +static struct sysfs_ops cpld_sysfs_ops = +{ + .show = cpld_sysfs_show, + .store = cpld_sysfs_store, +}; + +static struct kobj_type cpld_kobj_type = +{ + .release = cpld_sysfs_kobj_release, + .sysfs_ops = &cpld_sysfs_ops, + .default_attrs = NULL, +}; + + +static const char driver_name[] = "cpld_drv"; +static atomic_t cpld_available = ATOMIC_INIT(1); +static struct class *cpld_class; +static struct device *cpld_dev; + + + +#define CPLD_IOC_MAGIC '[' + +#define CPLD_IOC_RDREG _IOR(CPLD_IOC_MAGIC, 0, struct cpld_rw_msg) +#define CPLD_IOC_WRREG _IOW(CPLD_IOC_MAGIC, 1, struct cpld_rw_msg) + +#define CPLD_IOC_MAXNR 2 + + +int cpld_open(struct inode *inode, struct file *filp) +{ + struct cpld_dev_type *dev; + + if (! atomic_dec_and_test(&cpld_available)) { + atomic_inc(&cpld_available); + return -EBUSY; + } + + dev = container_of(inode->i_cdev, struct cpld_dev_type, cdev); + filp->private_data = dev; + + return 0; +} + +int cpld_release(struct inode *inode, struct file *flip) +{ + atomic_inc(&cpld_available); + return 0; +} + + +long cpld_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int rc = 0; + int err = 0; + struct cpld_dev_type *dev = (struct cpld_dev_type *)filp->private_data; + struct cpld_rw_msg msg; + + if (_IOC_TYPE(cmd) != CPLD_IOC_MAGIC) + return -ENOTTY; + if (_IOC_NR(cmd) > CPLD_IOC_MAXNR) + return -ENOTTY; + + if (_IOC_DIR(cmd) & _IOC_READ) + err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); + if (_IOC_DIR(cmd) & _IOC_WRITE) + err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); + if (err) + return -EFAULT; + + if (down_interruptible(&dev->sem)) + return -ERESTARTSYS; + + switch(cmd){ + case CPLD_IOC_RDREG: + rc = copy_from_user(&msg, (void __user *)arg, sizeof(msg)); + if (!rc) { + msg.data = lpc_cpld_getbyte(dev, msg.addr); + rc = copy_to_user((void __user *)arg, &msg, sizeof(msg)); + } + break; + + case CPLD_IOC_WRREG: + rc = copy_from_user(&msg, (void __user *)arg, sizeof(msg)); + if (!rc) { + lpc_cpld_setbyte(dev, msg.addr, msg.data); + } + break; + default: + rc = -ENOTTY; + break; + } + up(&dev->sem); + + return rc; +} + +struct file_operations cpld_fops = { + .owner = THIS_MODULE, + .open = cpld_open, + .unlocked_ioctl = cpld_ioctl, + .release = cpld_release, +}; + + +static void cpld_setup_cdev(struct cpld_dev_type *dev) +{ + int err, devno = MKDEV(cpld_major, cpld_minor); + + cdev_init(&dev->cdev, &cpld_fops); + dev->cdev.owner = THIS_MODULE; + dev->cdev.ops = &cpld_fops; + err = cdev_add(&dev->cdev, devno, 1); + + if (err) + DEB2(printk(KERN_NOTICE "Error %d adding cpld", err);) +} +/********************************************** End ********************************************************/ + + + + +/********************************************** Start ********************************************************/ +#include +#include +#include + +static spinlock_t irq_inter_lock; +static struct delayed_work irq_inter_work; +static unsigned long irq_inter_delay; + + +static int cig_cpld_write_slave_cpld_register(u8 reg_addr, u8 reg_data) +{ + u8 read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + DEB2(printk("<=======write=========>")); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, reg_addr << 1); + DEB2(printk("[62]=%x\n",reg_addr << 1)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_TX, reg_data); + DEB2(printk("[63]=%x\n",reg_data)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + DEB2(printk("[65]=%x\n",0x80)); + do{ + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &read_status); + DEB2(printk("[66]=%x\n",read_status)); + udelay(60); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(read_status != 0x02); + DEB2(printk("<=======write=========>")); + + + if(wait_time_out == 0) + return -1; + + return 1; +} + + +static int cig_cpld_read_slave_cpld_register(u8 reg_addr, u8 *reg_data) +{ + u8 read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + DEB2(printk("<========read=========>")); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, reg_addr << 1 | 1); + DEB2(printk("[62]=%x\n",reg_addr << 1 | 1)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + DEB2(printk("[65]=%x\n",0x80)); + do{ + udelay(60); + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &read_status); + DEB2(printk("[66]=%x\n",read_status)); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(read_status != 0x01); + + cig_cpld_read_register(ADDR_REG_SFP_STATUS_RX,reg_data); + DEB2(printk("[64]=%x\n",*reg_data)); + DEB2(printk("<========read=========>")); + + if(wait_time_out == 0) + return -1; + + return 1; +} + + + +struct sock *nlsk = NULL; +extern struct net init_net; +#define NETLINK_TEST 26 +#define MSG_LEN 125 +#define USER_PORT 100 +static u32 irq_present_status_low_current,irq_present_status_low_next; +static u32 irq_present_status_high_current,irq_present_status_high_next; +static u32 irq_tx_fault_status_low_current,irq_tx_fault_status_low_next; +static u32 irq_tx_fault_status_high_current,irq_tx_fault_status_high_next; +static u32 irq_rx_lost_status_low_current,irq_rx_lost_status_low_next; +static u32 irq_rx_lost_status_high_current,irq_rx_lost_status_high_next; + +static u8 irq_present_qsfp_current,irq_present_qsfp_next; +static u8 irq_interrupt_qsfp_current,irq_interrupt_qsfp_next; + +struct input_dev *cpld_input_dev; + + + +int send_usrmsg(char *pbuf, uint16_t len) +{ + struct sk_buff *nl_skb; + struct nlmsghdr *nlh; + + int ret; + + + nl_skb = nlmsg_new(len, GFP_ATOMIC); + if(!nl_skb) + { + printk("netlink alloc failure\n"); + return -1; + } + + + nlh = nlmsg_put(nl_skb, 0, 0, NETLINK_TEST, len, 0); + if(nlh == NULL) + { + printk("nlmsg_put failaure \n"); + nlmsg_free(nl_skb); + return -1; + } + + memcpy(nlmsg_data(nlh), pbuf, len); + ret = netlink_unicast(nlsk, nl_skb, USER_PORT, MSG_DONTWAIT); + + return ret; +} + +static void netlink_rcv_msg(struct sk_buff *skb) +{ + + struct nlmsghdr *nlh = NULL; + char *umsg = NULL; + char kmsg[1024] = {0}; + char kmsg_tmp[16] = {0}; + u8 i = 0; + u8 tmp[3]={0}; + + if(skb->len >= nlmsg_total_size(0)) + { + nlh = nlmsg_hdr(skb); + umsg = NLMSG_DATA(nlh); + if(umsg) + { + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_low_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_rx_lost_status_low_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_low_current & (0x1 << i))) + { + tmp[2] = 1; + } + else + { + tmp[2] = 0; + } + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"sfp%02d:%1d:%1d:%1d ",i+1,tmp[0],tmp[1],tmp[2]); + strcat(kmsg,kmsg_tmp); + } + + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_high_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_rx_lost_status_high_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_high_current & (0x1 << i))) + { + tmp[2] = 1; + } + else + { + tmp[2] = 0; + } + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"sfp%02d:%1d:%1d:%1d ",i+25,tmp[0],tmp[1],tmp[2]); + strcat(kmsg,kmsg_tmp); + } + + + for(i = 0;i < 8;i++) + { + if(!(irq_present_qsfp_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_interrupt_qsfp_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"qsfp%02d:%1d:%1d:%1d ",i+49,tmp[0],tmp[1],0); + strcat(kmsg,kmsg_tmp); + } + + printk("kernel recv from user: %s\n", umsg); + send_usrmsg(kmsg, strlen(kmsg)); + } + } + + return ; +} + + + +struct netlink_kernel_cfg cfg = { + .input = netlink_rcv_msg, /* set recv callback */ +}; + + + +#define RANGE_OF_BYTE_SHIFT(to_arg,shift,from_arg) {to_arg &= ~(0xff << shift); to_arg |= from_arg << shift;} + + +static void irq_inter_wapper(struct work_struct * work) +{ + + u8 m_data = 0; + u8 data_high8 = 0,data_low8 = 0; + u16 data_16 = 0; + u8 status = 0; + u8 i = 0; + char kmsg[64]={0}; + u8 tmp[3] = {0}; + + DEB2(printk("CPLD_MASTER_INTERRUPT\r\n")); + + m_data = lpc_iic_getbyte(NULL,CPLD_MASTER_INTERRUPT_STATUS_REG); + lpc_iic_setbyte(NULL,CPLD_MASTER_INTERRUPT_STATUS_REG,0xff); + + cig_cpld_write_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_MASK_REG,0xff); + cig_cpld_write_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_MASK_REG,0xff); + if(!(m_data & CPLD_MASTER_INTERRUPT_CPLD1)) + { + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_STATUS_H_REG,&data_high8); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_STATUS_L_REG,&data_low8); + data_16 = data_low8 | data_high8 << 8; + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT24) + ) + { + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,16,status); + } + DEB2(printk("irq_present_status_low_next = %08x irq_present_status_low_current = %08x \n",irq_present_status_low_next,irq_present_status_low_current)); + } + + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24) + ) + { + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_RX_LOST08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,16,status); + } + DEB2(printk("irq_rx_lost_status_low_next = %08x irq_rx_lost_status_low_current = %08x \n",irq_rx_lost_status_low_next,irq_rx_lost_status_low_current)); + } + + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24) + ) + { + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,16,status); + } + DEB2(printk("irq_tx_fault_status_low_next = %08x irq_tx_fault_status_low_current = %08x \n",irq_tx_fault_status_low_next,irq_tx_fault_status_low_current)); + + } + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_CPLD2)) + { + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_STATUS_H_REG,&data_high8); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_STATUS_L_REG,&data_low8); + data_16 = data_low8 | data_high8 << 8; + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT32)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT32_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT40)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT40_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,16,status); + } + } + + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST32)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_RX_LOST32\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST40)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT40\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,16,status); + } + + } + + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT32)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_RX_LOST32\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT40)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT40\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,16,status); + } + } + + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT56)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT56_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT56_REG,&status); + irq_present_qsfp_current = status; + } + + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_QSFP_CR56)) + { + DEB2(printk("CPLD_SLAVE2_QSFP_CR56_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_QSFP_CR56_REG,&status); + irq_interrupt_qsfp_current = status; + } + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_LSW)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_LSW\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_PSU1)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_PSU1\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_PSU2)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_PSU2\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_6320)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_6320\r\n")); + } + cig_cpld_write_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_MASK_REG,0x0); + cig_cpld_write_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_MASK_REG,0x0); + + memset(tmp,0xff,sizeof(tmp)); + + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_low_current & (0x1 << i)) && (irq_present_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+1)); + tmp[0] = 1; + } + else if((irq_present_status_low_current & (0x1 << i)) && !(irq_present_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+1)); + tmp[0] = 0; + } + + if(!(irq_tx_fault_status_low_current & (0x1 << i)) && (irq_tx_fault_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is right\r\n",i+1)); + tmp[1] = 1; + } + else if((irq_tx_fault_status_low_current & (0x1 << i)) && !(irq_tx_fault_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is fault\r\n",i+1)); + tmp[1] = 0; + } + + if(!(irq_rx_lost_status_low_current & (0x1 << i)) && (irq_rx_lost_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is meet\r\n",i+1)); + tmp[2] = 1; + } + else if((irq_rx_lost_status_low_current & (0x1 << i)) && !(irq_rx_lost_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is lost\r\n",i+1)); + tmp[2] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff) || (tmp[2] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"sfp%02d:%1d:%1d:%1d ",i+1,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],(tmp[2] == 0xff) ? 0:tmp[2]); + break; + } + } + + memset(tmp,0xff,sizeof(tmp)); + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_high_current & (0x1 << i)) && (irq_present_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+25)); + tmp[0] = 1; + } + else if((irq_present_status_high_current & (0x1 << i)) && !(irq_present_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+25)); + tmp[0] = 0; + + } + + if(!(irq_rx_lost_status_high_current & (0x1 << i)) && (irq_rx_lost_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is meet\r\n",i+25)); + tmp[1] = 1; + } + else if((irq_rx_lost_status_high_current & (0x1 << i)) && !(irq_rx_lost_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is lost\r\n",i+25)); + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_high_current & (0x1 << i)) && (irq_tx_fault_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is right\r\n",i+25)); + tmp[2] = 1; + } + else if((irq_tx_fault_status_high_current & (0x1 << i)) && !(irq_tx_fault_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is fault\r\n",i+25)); + tmp[2] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff) || (tmp[2] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"sfp%02d:%1d:%1d:%1d ",i+25,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],(tmp[2] == 0xff) ? 0:tmp[2]); + break; + } + } + + memset(tmp,0xff,sizeof(tmp)); + for(i = 0 ; i < 8; i++) + { + if(!(irq_present_qsfp_current & (0x1 << i)) && (irq_present_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+49)); + tmp[0] = 1; + } + else if((irq_present_qsfp_current & (0x1 << i)) && !(irq_present_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+49)); + tmp[0] = 0; + } + + if(!(irq_interrupt_qsfp_current & (0x1 << i)) && (irq_interrupt_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d interrupt is occured \r\n",i+49)); + tmp[1] = 1; + } + else if((irq_interrupt_qsfp_current & (0x1 << i)) && !(irq_interrupt_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d interrupt is cleaned\r\n",i+49)); + tmp[1] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"qsfp%02d:%1d:%1d:%1d ",i+49,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],0); + break; + } + } + + + irq_present_status_low_next = irq_present_status_low_current; + irq_rx_lost_status_low_next = irq_rx_lost_status_low_current; + irq_tx_fault_status_low_next = irq_tx_fault_status_low_current; + irq_present_status_high_next = irq_present_status_high_current; + irq_rx_lost_status_high_next = irq_rx_lost_status_high_current; + irq_tx_fault_status_high_next = irq_tx_fault_status_high_current; + irq_present_qsfp_next = irq_present_qsfp_current; + irq_interrupt_qsfp_next = irq_interrupt_qsfp_current; + + send_usrmsg(kmsg, strlen(kmsg)); +} + +static void disableIrq(unsigned short maskReg, unsigned short mask) +{ + u8 data = 0; + + data = lpc_iic_getbyte(NULL,maskReg); + data |= mask; + lpc_iic_setbyte(NULL,maskReg, data); +} + +static void enableIrq(unsigned short maskReg, unsigned short mask) +{ + unsigned short data; + + data = lpc_iic_getbyte(NULL,maskReg); + data &= ~mask; + lpc_iic_setbyte(NULL,maskReg, data); +} + + +static irqreturn_t irq_inter_isr(int irq, void *handle) +{ + + /* + * use keventd context to read the event fifo registers + * Schedule readout at least 25ms after notification for + * REVID < 4 + */ + + schedule_delayed_work(&irq_inter_work, irq_inter_delay); + + return IRQ_HANDLED; +} + + +#define CIG_CPLD_CHR_NAME "cpld" + + +static int __init cpld_init(void) +{ + int rval,rc=0; + dev_t dev; + u8 s_data; + int isr_GPIO_num = 289; + + DEB2(printk("cpld_init\n");) + +/**************************************************************************************/ + + LPC_INDEX_REG = lpc_base_addr; + LPC_DATA_REG = lpc_base_addr + 1; + + cpld_device = kzalloc(sizeof(struct cpld_dev_type), GFP_KERNEL); + if (!cpld_device) + goto error3; + cpld_device->io_resource = request_region(lpc_base_addr, + lpc_io_space_size, "lpc-i2c"); + if (!cpld_device->io_resource) { + printk("lpc: claim I/O resource fail\n"); + goto error2; + } + sema_init(&cpld_device->sem, 1); + + if (cpld_major) { + dev = MKDEV(cpld_major, cpld_minor); + rc = register_chrdev_region(dev, 1, CIG_CPLD_CHR_NAME); + } else { + rc = alloc_chrdev_region(&dev, cpld_major, 1, CIG_CPLD_CHR_NAME); + cpld_major = MAJOR(dev); + } + + cpld_setup_cdev(cpld_device); + + cpld_class = class_create(THIS_MODULE,CIG_CPLD_CHR_NAME); + if (!cpld_class) { + DEB2(printk("failed to create class\n");) + goto error1; + } + + cpld_class->p->subsys.kobj.ktype= &cpld_kobj_type; + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "read"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "write"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "reads"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "writes"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "version"); + + cpld_dev = device_create(cpld_class, NULL, dev, NULL, CIG_CPLD_CHR_NAME); + +/**************************************************************************************/ + + rval = lpc_bus_init(); + rval = lpc_register_driver(&i2c_lpc_driver, 1); + +/**************************************************************************************/ + return 0; +error1: + cdev_del(&cpld_device->cdev); + unregister_chrdev_region(dev, 1); +error2: + release_resource(cpld_device->io_resource); +error3: + kfree(cpld_device); + + return rc; +} + +static void __exit cpld_exit(void) +{ + DEB2(printk("cpld_exit\n")); + + if (nlsk){ + netlink_kernel_release(nlsk); /* release ..*/ + nlsk = NULL; + } + + + lpc_unregister_driver(&i2c_lpc_driver); + lpc_bus_exit(); + dev_t devno = MKDEV(cpld_major, cpld_minor); + + cdev_del(&cpld_device->cdev); + if (cpld_class) { + device_destroy(cpld_class, devno); + class_destroy(cpld_class); + } + + if (cpld_device) { + if (cpld_device->io_resource) + release_resource(cpld_device->io_resource); + + kfree(cpld_device); + } + unregister_chrdev_region(devno, 1); + + +} + +module_param(cpld_major, int, S_IRUGO); +module_param(cpld_minor, int, S_IRUGO); +module_param(i2c_debug, int, S_IRUGO); +module_param(board_id, int, S_IRUGO); + +module_init(cpld_init); +module_exit(cpld_exit); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs5435-54p-cpld driver"); +MODULE_LICENSE("GPL"); + + +/********************************************** End ********************************************************/ + + + diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-fan.c b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-fan.c new file mode 100644 index 000000000000..a254dae33c2c --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-fan.c @@ -0,0 +1,521 @@ +/* + * A hwmon driver for the CIG cs5435-54p fan + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#define FAN_SPEED_DUTY_TO_CPLD_STEP 10 + +static struct cs5435_54p_fan_data *cs5435_54p_fan_update_device(struct device *dev); +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); + + +extern int cig_cpld_write_register(u8 reg_off, u8 val); +extern int cig_cpld_read_register(u8 reg_off, u8 *val); + +/* fan related data, the index should match sysfs_fan_attributes + */ +static const u8 fan_reg[] = { + 0x41, /* fan enable/disable */ + 0x40, /* fan PWM(for all fan) */ + 0x42, /* front fan 1 speed(rpm) */ + 0x44, /* front fan 2 speed(rpm) */ + 0x46, /* front fan 3 speed(rpm) */ + 0x48, /* front fan 4 speed(rpm) */ + 0x4a, /* front fan 5 speed(rpm) */ + 0x43, /* rear fan 1 speed(rpm) */ + 0x45, /* rear fan 2 speed(rpm) */ + 0x47, /* rear fan 3 speed(rpm) */ + 0x49, /* rear fan 4 speed(rpm) */ + 0x4b, /* rear fan 5 speed(rpm) */ + 0x4c, /* fan direction rear to front or front to rear */ +}; + + +/* Each client has this additional data */ +struct cs5435_54p_fan_data { + struct platform_device *pdev; + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[ARRAY_SIZE(fan_reg)]; /* Register value */ +}; + +static struct cs5435_54p_fan_data *fan_data = NULL; + +enum fan_id { + FAN1_ID, + FAN2_ID, + FAN3_ID, + FAN4_ID, + FAN5_ID, +}; + +enum sysfs_fan_attributes { + FAN_STATE_REG, + FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */ + FAN1_FRONT_SPEED_RPM, + FAN2_FRONT_SPEED_RPM, + FAN3_FRONT_SPEED_RPM, + FAN4_FRONT_SPEED_RPM, + FAN5_FRONT_SPEED_RPM, + FAN1_REAR_SPEED_RPM, + FAN2_REAR_SPEED_RPM, + FAN3_REAR_SPEED_RPM, + FAN4_REAR_SPEED_RPM, + FAN5_REAR_SPEED_RPM, + FAN_DIRECTION, + FAN1_STATE, + FAN2_STATE, + FAN3_STATE, + FAN4_STATE, + FAN5_STATE, + FAN1_FAULT, + FAN2_FAULT, + FAN3_FAULT, + FAN4_FAULT, + FAN5_FAULT, + FAN1_DIRECTION, + FAN2_DIRECTION, + FAN3_DIRECTION, + FAN4_DIRECTION, + FAN5_DIRECTION, +}; + +/* Define attributes + */ +#define DECLARE_FAN_STATE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_state, S_IRUGO, fan_show_value, NULL, FAN##index##_STATE) +#define DECLARE_FAN_STATE_ATTR(index) &sensor_dev_attr_fan##index##_state.dev_attr.attr + +#define DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT) +#define DECLARE_FAN_FAULT_ATTR(index) &sensor_dev_attr_fan##index##_fault.dev_attr.attr + +#define DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN##index##_DUTY_CYCLE_PERCENTAGE) +#define DECLARE_FAN_DUTY_CYCLE_ATTR(index) &sensor_dev_attr_fan##index##_duty_cycle_percentage.dev_attr.attr + +#define DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_front_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index##_rear_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM) +#define DECLARE_FAN_SPEED_RPM_ATTR(index) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr + +#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IWUSR | S_IRUGO, fan_show_value, set_fan_direction, FAN##index##_DIRECTION) +#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr + + +/* 5 fan state attributes in this platform */ +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(1); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(2); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(3); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(4); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(5); + + +/* 5 fan fault attributes in this platform */ +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(1); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(2); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(3); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(4); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(5); + +/* 5 fan speed(rpm) attributes in this platform */ +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(1); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(2); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(3); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(4); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(5); + +/* 1 fan duty cycle attribute in this platform */ +DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(); + +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(5); + + +static struct attribute *cs5435_54p_fan_attributes[] = { + /* fan related attributes */ + DECLARE_FAN_STATE_ATTR(1), + DECLARE_FAN_STATE_ATTR(2), + DECLARE_FAN_STATE_ATTR(3), + DECLARE_FAN_STATE_ATTR(4), + DECLARE_FAN_STATE_ATTR(5), + DECLARE_FAN_FAULT_ATTR(1), + DECLARE_FAN_FAULT_ATTR(2), + DECLARE_FAN_FAULT_ATTR(3), + DECLARE_FAN_FAULT_ATTR(4), + DECLARE_FAN_FAULT_ATTR(5), + DECLARE_FAN_SPEED_RPM_ATTR(1), + DECLARE_FAN_SPEED_RPM_ATTR(2), + DECLARE_FAN_SPEED_RPM_ATTR(3), + DECLARE_FAN_SPEED_RPM_ATTR(4), + DECLARE_FAN_SPEED_RPM_ATTR(5), + DECLARE_FAN_DUTY_CYCLE_ATTR(), + DECLARE_FAN_DIRECTION_ATTR(1), + DECLARE_FAN_DIRECTION_ATTR(2), + DECLARE_FAN_DIRECTION_ATTR(3), + DECLARE_FAN_DIRECTION_ATTR(4), + DECLARE_FAN_DIRECTION_ATTR(5), + NULL +}; + +#define FAN_MAX_DUTY_CYCLE 100 +#define FAN_REG_VAL_TO_SPEED_RPM_STEP 100 + +/* fan utility functions + */ +static u32 reg_val_to_duty_cycle(u8 reg_val) +{ + if (reg_val +== 0xFF) { + return 100; + } + return ((u32)(reg_val) * 100)/ 255; +} + +static u8 duty_cycle_to_reg_val(u8 duty_cycle) +{ + if (duty_cycle >= FAN_MAX_DUTY_CYCLE) { + return 0xFF; + } + + return 255 / 10 * (duty_cycle / 10); +} + +static u32 reg_val_to_speed_rpm(u8 reg_val) +{ + return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP; +} + +static u8 reg_val_to_is_state(u8 reg_val, enum fan_id id) +{ + u8 mask = (1 << id); + + reg_val &= mask; + + return reg_val ? 0 : 1; +} + +static u8 is_fan_fault(struct cs5435_54p_fan_data *data, enum fan_id id) +{ + u8 ret = 1; + int front_fan_index = FAN1_FRONT_SPEED_RPM + id; + int rear_fan_index = FAN1_REAR_SPEED_RPM + id; + + /* Check if the speed of front or rear fan is ZERO, + */ + if (reg_val_to_speed_rpm(data->reg_val[front_fan_index]) && + reg_val_to_speed_rpm(data->reg_val[rear_fan_index])) { + ret = 0; + } + + return ret; +} + + +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value; + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value <= 0 || value > FAN_MAX_DUTY_CYCLE) + return -EINVAL; + + cig_cpld_write_register(fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value)); + + return count; +} + +static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value,fan_index; + u8 mask,reg_val; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + fan_index = attr->index - FAN1_DIRECTION; + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (!(value == 0 || value == 1)) + return -EINVAL; + + + cig_cpld_read_register(fan_reg[FAN_DIRECTION],®_val); + + if(value == 1) + { + reg_val |= (1 << fan_index); + } + else + { + reg_val &= ~(1 << fan_index); + } + + cig_cpld_write_register(fan_reg[FAN_DIRECTION], reg_val); + + return count; +} + + + + + +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + cs5435_54p_fan_update_device(dev); + + struct cs5435_54p_fan_data *data = fan_data; + + ssize_t ret = 0; + + if (data->valid) { + switch (attr->index) { + + case FAN1_STATE: + case FAN2_STATE: + case FAN3_STATE: + case FAN4_STATE: + case FAN5_STATE: + //printk("FAN_STATE_REG: 0x%x\n", data->reg_val[FAN_STATE_REG]); + //printk("index: %d\n", attr->index); + ret = sprintf(buf, "%d\n", + reg_val_to_is_state(data->reg_val[FAN_STATE_REG], + attr->index - FAN1_STATE)); + break; + case FAN_DUTY_CYCLE_PERCENTAGE: + { + u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[FAN_DUTY_CYCLE_PERCENTAGE]); + ret = sprintf(buf, "%u\n", duty_cycle); + break; + } + case FAN1_FRONT_SPEED_RPM: + case FAN2_FRONT_SPEED_RPM: + case FAN3_FRONT_SPEED_RPM: + case FAN4_FRONT_SPEED_RPM: + case FAN5_FRONT_SPEED_RPM: + case FAN1_REAR_SPEED_RPM: + case FAN2_REAR_SPEED_RPM: + case FAN3_REAR_SPEED_RPM: + case FAN4_REAR_SPEED_RPM: + case FAN5_REAR_SPEED_RPM: +// printk("FAN_seed_REG: 0x%x\n", data->reg_val[attr->index]); +// printk("index: %d\n", attr->index); + ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index])); + break; + + case FAN1_FAULT: + case FAN2_FAULT: + case FAN3_FAULT: + case FAN4_FAULT: + case FAN5_FAULT: + ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT)); + break; + case FAN1_DIRECTION: + case FAN2_DIRECTION: + case FAN3_DIRECTION: + case FAN4_DIRECTION: + case FAN5_DIRECTION: + ret = sprintf(buf, "%d\n",reg_val_to_is_state(data->reg_val[FAN_DIRECTION],attr->index - FAN1_DIRECTION)); + break; + default: + break; + } + } + + return ret; +} + +static const struct attribute_group cs5435_54p_fan_group = { + .attrs = cs5435_54p_fan_attributes, +}; + +static struct cs5435_54p_fan_data *cs5435_54p_fan_update_device(struct device *dev) +{ + struct cs5435_54p_fan_data *data = fan_data; + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || + !data->valid) { + int i; + + data->valid = 0; + + /* Update fan data + */ + for (i = 0; i < ARRAY_SIZE(data->reg_val); i++) { + u8 status; + (void)cig_cpld_read_register(fan_reg[i], &status); + + if (status < 0) { + data->valid = 0; + mutex_unlock(&data->update_lock); + return data; + } + else { + data->reg_val[i] = status; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int cs5435_54p_fan_probe(struct platform_device *pdev) +{ + int status = -1; + /* Register sysfs hooks */ + status = sysfs_create_group(&pdev->dev.kobj, &cs5435_54p_fan_group); + if (status) { + goto exit; + + } + + fan_data->hwmon_dev = hwmon_device_register(&pdev->dev); + if (IS_ERR(fan_data->hwmon_dev)) { + status = PTR_ERR(fan_data->hwmon_dev); + goto exit_remove; + } + + dev_info(&pdev->dev, "cs5435_54p_fan\n"); + + return 0; + +exit_remove: + sysfs_remove_group(&pdev->dev.kobj, &cs5435_54p_fan_group); +exit: + return status; +} + +static int cs5435_54p_fan_remove(struct platform_device *pdev) +{ + hwmon_device_unregister(fan_data->hwmon_dev); + sysfs_remove_group(&fan_data->pdev->dev.kobj, &cs5435_54p_fan_group); + + return 0; +} + +#define DRVNAME "cs5435_54p_fan" + +static struct platform_driver cs5435_54p_fan_driver = { + .probe = cs5435_54p_fan_probe, + .remove = cs5435_54p_fan_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + + + + + +static int __init cs5435_54p_fan_init(void) +{ + int ret; + + cig_cpld_write_register(0x40, duty_cycle_to_reg_val(50)); + + ret = platform_driver_register(&cs5435_54p_fan_driver); + if (ret < 0) { + goto exit; + } + + fan_data = kzalloc(sizeof(struct cs5435_54p_fan_data), GFP_KERNEL); + if (!fan_data) { + ret = -ENOMEM; + platform_driver_unregister(&cs5435_54p_fan_driver); + goto exit; + } + + mutex_init(&fan_data->update_lock); + fan_data->valid = 0; + + fan_data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(fan_data->pdev)) { + ret = PTR_ERR(fan_data->pdev); + platform_driver_unregister(&cs5435_54p_fan_driver); + kfree(fan_data); + goto exit; + } + +exit: + return ret; +} + +static void __exit cs5435_54p_fan_exit(void) +{ + platform_device_unregister(fan_data->pdev); + platform_driver_unregister(&cs5435_54p_fan_driver); + kfree(fan_data); +} + +MODULE_AUTHOR("CIG"); +MODULE_DESCRIPTION("cs5435_54p_fan driver"); +MODULE_LICENSE("GPL"); + +module_init(cs5435_54p_fan_init); +module_exit(cs5435_54p_fan_exit); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs5435_54p_fan driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-led.c b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-led.c new file mode 100644 index 000000000000..dae49967592e --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-led.c @@ -0,0 +1,594 @@ +/* + * A hwmon driver for the CIG cs5435-54P LED + * + * Copyright (C) 2018 Cambridge, Inc. + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*#define DEBUG*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern int cig_cpld_write_register(u8 reg_off, u8 val); + +extern int cig_cpld_read_register(u8 reg_off, u8 *val); + +extern void led_classdev_unregister(struct led_classdev *led_cdev); +extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); +extern void led_classdev_resume(struct led_classdev *led_cdev); +extern void led_classdev_suspend(struct led_classdev *led_cdev); + +#define DRVNAME "cs5435_54p_led" + +struct cs5435_54p_led_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[6]; /* 0: system & location + 1: PSU1 &PSU12 + 2: fan & management + 3: console & ToD + 4-5 : fan1-fan5*/ +}; + +static struct cs5435_54p_led_data *ledctl = NULL; + +/* LED related data + */ +#define LED_TYPE_PSU1_REG_MASK 0x0C +#define LED_MODE_PSU1_GREEN_MASK 0x08 +#define LED_MODE_PSU1_RED_MASK 0x04 +#define LED_MODE_PSU1_AMBER_MASK 0x0C +#define LED_MODE_PSU1_OFF_MASK 0x00 + +#define LED_TYPE_PSU2_REG_MASK 0x30 +#define LED_MODE_PSU2_GREEN_MASK 0x20 +#define LED_MODE_PSU2_RED_MASK 0x10 +#define LED_MODE_PSU2_AMBER_MASK 0x30 +#define LED_MODE_PSU2_OFF_MASK 0x00 + +#define LED_TYPE_SYS_REG_MASK 0xF0 +#define LED_MODE_SYS_GREEN_MASK 0x40 +#define LED_MODE_SYS_RED_MASK 0x20 +#define LED_MODE_SYS_AMBER_MASK 0x60 +#define LED_MODE_SYS_AMBER_FLASHING_MASK 0x70 +#define LED_MODE_SYS_OFF_MASK 0x00 + +#define LED_TYPE_RES_REG_MASK 0x0F +#define LED_MODE_RES_GREEN_MASK 0x04 +#define LED_MODE_RES_RED_MASK 0x02 +#define LED_MODE_RES_AMBER_MASK 0x06 +#define LED_MODE_RES_AMBER_FLASHING_MASK 0x07 +#define LED_MODE_RES_OFF_MASK 0x00 + +#define LED_TYPE_FAN_REG_MASK 0x03 +#define LED_MODE_FAN_GREEN_MASK 0x02 +#define LED_MODE_FAN_RED_MASK 0x01 +#define LED_MODE_FAN_AMBER_MASK 0x03 +#define LED_MODE_FAN_OFF_MASK 0x00 + +#define LED_TYPE_FAN1_REG_MASK 0x03 +#define LED_TYPE_FAN2_REG_MASK 0x0C +#define LED_TYPE_FAN3_REG_MASK 0x30 +#define LED_TYPE_FAN4_REG_MASK 0xC0 +#define LED_TYPE_FAN5_REG_MASK 0x03 + +#define LED_MODE_FANX_GREEN_MASK 0x02 +#define LED_MODE_FANX_RED_MASK 0x01 +#define LED_MODE_FANX_AMBER_MASK 0x03 +#define LED_MODE_FANX_OFF_MASK 0x00 + +enum led_type { + LED_TYPE_SYS, + LED_TYPE_PSU2, + LED_TYPE_PSU1, + LED_TYPE_FAN, + LED_TYPE_FAN1, + LED_TYPE_FAN2, + LED_TYPE_FAN3, + LED_TYPE_FAN4, + LED_TYPE_FAN5, +}; + +static const u8 led_reg[] = { + 0x30, /* system & reserved*/ + 0x31, /* fan & PSU1 & PSU2 */ + 0x32, /* FAN5 LED */ + 0x33, /* FAN1-4 LED */ +}; + + +enum led_light_mode { + LED_MODE_OFF = 0, + LED_MODE_GREEN, + LED_MODE_AMBER, + LED_MODE_RED, + LED_MODE_GREEN_BLINK, + LED_MODE_AMBER_BLINK, + LED_MODE_RED_BLINK, + LED_MODE_GREEN_FLASHING, + LED_MODE_AMBER_FLASHING, + LED_MODE_RED_FLASHING, + LED_MODE_AUTO, + LED_MODE_UNKNOWN +}; + +struct led_type_mode { + enum led_type type; + int type_mask; + enum led_light_mode mode; + int mode_mask; +}; + +static struct led_type_mode led_type_mode_data[] = { +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU1_GREEN_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU1_AMBER_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_RED, LED_MODE_PSU1_RED_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_OFF, LED_MODE_PSU1_OFF_MASK}, + +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU2_GREEN_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU2_AMBER_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_RED, LED_MODE_PSU2_RED_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_OFF, LED_MODE_PSU2_OFF_MASK}, + +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_GREEN, LED_MODE_SYS_GREEN_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_AMBER, LED_MODE_SYS_AMBER_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_RED, LED_MODE_SYS_RED_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_AMBER_FLASHING, LED_MODE_SYS_AMBER_FLASHING_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_OFF, LED_MODE_SYS_OFF_MASK}, + +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_GREEN, LED_MODE_FAN_GREEN_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_AMBER, LED_MODE_FAN_AMBER_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_RED, LED_MODE_FAN_RED_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_OFF, LED_MODE_FAN_OFF_MASK}, + +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 2}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 4}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 6}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0}, +}; + +struct fanx_info_s { + u8 cname; /* device name */ + enum led_type type; + u8 reg_id; /* map to led_reg & reg_val */ +}; + +static struct fanx_info_s fanx_info[] = { + {'1', LED_TYPE_FAN1, 3}, + {'2', LED_TYPE_FAN2, 3}, + {'3', LED_TYPE_FAN3, 3}, + {'4', LED_TYPE_FAN4, 3}, + {'5', LED_TYPE_FAN5, 2}, +}; + + +static int led_reg_val_to_light_mode(enum led_type type, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + + if (type != led_type_mode_data[i].type) + continue; + + if ((led_type_mode_data[i].type_mask & reg_val) == + led_type_mode_data[i].mode_mask) + { + return led_type_mode_data[i].mode; + } + } + + return 0; +} + +static u8 led_light_mode_to_reg_val(enum led_type type, + enum led_light_mode mode, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + if (type != led_type_mode_data[i].type) + continue; + + if (mode != led_type_mode_data[i].mode) + continue; + + reg_val = led_type_mode_data[i].mode_mask | + (reg_val & (~led_type_mode_data[i].type_mask)); + break; + } + + return reg_val; +} + +static void cs5435_54p_led_update(void) +{ + mutex_lock(&ledctl->update_lock); + + if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2) + || !ledctl->valid) { + int i; + + dev_dbg(&ledctl->pdev->dev, "Starting cs5435_54p_led update\n"); + + /* Update LED data + */ + for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) { + u8 status; + cig_cpld_read_register(led_reg[i], &status); + + if (status < 0) { + ledctl->valid = 0; + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg[i], status); + goto exit; + } + else + { + ledctl->reg_val[i] = status; + } + } + + ledctl->last_updated = jiffies; + ledctl->valid = 1; + } + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void cs5435_54p_led_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode, + u8 reg, enum led_type type) +{ + u8 reg_val; + mutex_lock(&ledctl->update_lock); + + cig_cpld_read_register(reg, ®_val); + if (reg_val < 0) { + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val); + goto exit; + } + + reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val); + + cig_cpld_write_register(reg, reg_val); + + /* to prevent the slow-update issue */ + ledctl->valid = 0; + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void cs5435_54p_led_fanx_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + enum led_type led_type1; + int reg_id; + int i, nsize; + int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s); + + for(i=0;iname); + + if (led_cdev->name[nsize-1] == fanx_info[i].cname) + { + led_type1 = fanx_info[i].type; + reg_id = fanx_info[i].reg_id; + + cs5435_54p_led_set(led_cdev, led_light_mode, led_reg[reg_id], led_type1); + return; + } + } +} + + +static enum led_brightness cs5435_54p_led_fanx_get(struct led_classdev *cdev) +{ + enum led_type led_type1; + int reg_id; + int i, nsize; + int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s); + + for(i=0;iname); + + if (cdev->name[nsize-1] == fanx_info[i].cname) + { + led_type1 = fanx_info[i].type; + reg_id = fanx_info[i].reg_id; + cs5435_54p_led_update(); + return led_reg_val_to_light_mode(led_type1, ledctl->reg_val[reg_id]); + } + } + + return led_reg_val_to_light_mode(LED_TYPE_FAN1, ledctl->reg_val[5]); +} + + +static void cs5435_54p_led_psu1_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs5435_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU1); +} + +static enum led_brightness cs5435_54p_led_psu1_get(struct led_classdev *cdev) +{ + cs5435_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU1, ledctl->reg_val[1]); +} + +static void cs5435_54p_led_psu2_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs5435_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU2); +} + +static enum led_brightness cs5435_54p_led_psu2_get(struct led_classdev *cdev) +{ + cs5435_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU2, ledctl->reg_val[1]); +} + +static void cs5435_54p_led_sys_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs5435_54p_led_set(led_cdev, led_light_mode,led_reg[0], LED_TYPE_SYS); +} + +static enum led_brightness cs5435_54p_led_sys_get(struct led_classdev *cdev) +{ + cs5435_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_SYS, ledctl->reg_val[0]); +} + + +static enum led_brightness cs5435_54p_led_fan_get(struct led_classdev *cdev) +{ + cs5435_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_FAN, ledctl->reg_val[1]); +} + +static void cs5435_54p_led_fan_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs5435_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_FAN); +} + + +static struct led_classdev cs5435_54p_leds[] = { + [LED_TYPE_SYS] = { + .name = "cs5435_54p_led::sys", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_sys_set, + .brightness_get = cs5435_54p_led_sys_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN] = { + .name = "cs5435_54p_led::fan", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_fan_set, + .brightness_get = cs5435_54p_led_fan_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + + [LED_TYPE_PSU1] = { + .name = "cs5435_54p_led::psu1", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_psu1_set, + .brightness_get = cs5435_54p_led_psu1_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU2] = { + .name = "cs5435_54p_led::psu2", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_psu2_set, + .brightness_get = cs5435_54p_led_psu2_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + + [LED_TYPE_FAN1] = { + .name = "cs5435_54p_led::fan1", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_fanx_set, + .brightness_get = cs5435_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN2] = { + .name = "cs5435_54p_led::fan2", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_fanx_set, + .brightness_get = cs5435_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN3] = { + .name = "cs5435_54p_led::fan3", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_fanx_set, + .brightness_get = cs5435_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN4] = { + .name = "cs5435_54p_led::fan4", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_fanx_set, + .brightness_get = cs5435_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN5] = { + .name = "cs5435_54p_led::fan5", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_fanx_set, + .brightness_get = cs5435_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + } +}; + +static int cs5435_54p_led_suspend(struct platform_device *dev, + pm_message_t state) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(cs5435_54p_leds); i++) { + led_classdev_suspend(&cs5435_54p_leds[i]); + } + + return 0; +} + +static int cs5435_54p_led_resume(struct platform_device *dev) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(cs5435_54p_leds); i++) { + led_classdev_resume(&cs5435_54p_leds[i]); + } + + return 0; +} + +static int cs5435_54p_led_probe(struct platform_device *pdev) +{ + int ret, i; + + for (i = 0; i < ARRAY_SIZE(cs5435_54p_leds); i++) { + ret = led_classdev_register(&pdev->dev, &cs5435_54p_leds[i]); + + if (ret < 0) + break; + } + + /* Check if all LEDs were successfully registered */ + if (i != ARRAY_SIZE(cs5435_54p_leds)) { + int j; + + /* only unregister the LEDs that were successfully registered */ + for (j = 0; j < i; j++) { + led_classdev_unregister(&cs5435_54p_leds[i]); + } + } + + return ret; +} + +static int cs5435_54p_led_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cs5435_54p_leds); i++) { + led_classdev_unregister(&cs5435_54p_leds[i]); + } + + return 0; +} + +static struct platform_driver cs5435_54p_led_driver = { + .probe = cs5435_54p_led_probe, + .remove = cs5435_54p_led_remove, + .suspend = cs5435_54p_led_suspend, + .resume = cs5435_54p_led_resume, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int cs5435_54p_led_default(void) +{ + cig_cpld_write_register(0x30, 0x40);// system green led solid on +} + +static int __init cs5435_54p_led_init(void) +{ + int ret; + + ret = platform_driver_register(&cs5435_54p_led_driver); + if (ret < 0) { + goto exit; + } + + ledctl = kzalloc(sizeof(struct cs5435_54p_led_data), GFP_KERNEL); + if (!ledctl) { + ret = -ENOMEM; + platform_driver_unregister(&cs5435_54p_led_driver); + goto exit; + } + + mutex_init(&ledctl->update_lock); + + ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(ledctl->pdev)) { + ret = PTR_ERR(ledctl->pdev); + platform_driver_unregister(&cs5435_54p_led_driver); + kfree(ledctl); + goto exit; + } + + cs5435_54p_led_default(); + +exit: + return ret; +} + +static void __exit cs5435_54p_led_exit(void) +{ + platform_device_unregister(ledctl->pdev); + platform_driver_unregister(&cs5435_54p_led_driver); + kfree(ledctl); +} + +module_init(cs5435_54p_led_init); +module_exit(cs5435_54p_led_exit); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs5435_54p_led driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-psu.c b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-psu.c new file mode 100644 index 000000000000..5a7942653fc3 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-psu.c @@ -0,0 +1,946 @@ +/* + * A hwmon driver for the CIG cs5435-54P Power Module + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "i2c-algo-lpc.h" + + + +#define MAX_FAN_DUTY_CYCLE 100 + +/* Address scanned */ +static const unsigned short normal_i2c[] = {I2C_CLIENT_END }; + +/* This is additional data */ +struct cs5435_54p_psu_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; + unsigned long last_updated; /* In jiffies */ + + /* Registers value */ + u8 vout_mode; + u16 v_in; + u16 v_out; + u16 i_in; + u16 i_out; + u16 p_in; + u16 p_out; + u16 temp_input[3]; + u8 temp_fault; + u8 fan_fault; + u16 fan_duty_cycle[2]; + u16 fan_speed[2]; + u8 mfr_id[8]; + u8 mfr_model[20]; + u8 mfr_serial[20]; + u8 psu_is_present; + u8 psu_is_good; + struct i2c_client *client; + struct bin_attribute *bin; /* eeprom data */ +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask); +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count); +static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_fan_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_fan_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_temp_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_temp_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_vout_data(struct device *dev, struct device_attribute *dev_attr, char *buf); +static int cs5435_54p_psu_read_byte(struct i2c_client *client, u8 reg); +static int cs5435_54p_psu_read_word(struct i2c_client *client, u8 reg); +static int cs5435_54p_psu_write_word(struct i2c_client *client, u8 reg, u16 value); +static int cs5435_54p_psu_read_block(struct i2c_client *client, u8 command, u8 *data, int data_len); +static struct cs5435_54p_psu_data *cs5435_54p_psu_update_device(struct device *dev); +static ssize_t for_ascii(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf); + +enum cs5435_54p_psu_sysfs_attributes { + PSU_V_IN, + PSU_V_OUT, + PSU_I_IN, + PSU_I_OUT, + PSU_P_IN, + PSU_P_OUT, + PSU_TEMP1_INPUT, + PSU_TEMP2_INPUT, + PSU_TEMP3_INPUT, + PSU_TEMP_FAULT, + PSU_TEMP_WARN, + PSU_FAN1_FAULT, + PSU_FAN1_WARN, + PSU_FAN1_DUTY_CYCLE, + PSU_FAN1_SPEED, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_SERIAL, + PSU_PRESENT, + PSU_P_GOOD, +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + + bool is_negative = valid_data >> (valid_bit - 1); + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute \ + *dev_attr, const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct i2c_client *client = to_i2c_client(dev); + struct cs5435_54p_psu_data *data = i2c_get_clientdata(client); + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + if (data->valid != 1) + { + return -ENODEV; + } + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; + cs5435_54p_psu_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + if (data->valid != 1) + { + return -ENODEV; + } + + switch (attr->index) { + case PSU_V_IN: + value = data->v_in; + break; + case PSU_I_IN: + value = data->i_in; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_IN: + value = data->p_in; + break; + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp_input[0]; + break; + case PSU_TEMP2_INPUT: + value = data->temp_input[1]; + break; + case PSU_TEMP3_INPUT: + value = data->temp_input[2]; + break; + case PSU_FAN1_DUTY_CYCLE: + multiplier = 1; + value = data->fan_duty_cycle[0]; + break; + case PSU_FAN1_SPEED: + multiplier = 1; + value = data->fan_speed[0]; + break; + default: + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + + return (exponent >= 0) ? sprintf(buf, "%d\n", \ + (mantissa << exponent) * multiplier) : \ + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t for_fan_fault(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t for_fan_warning(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + u8 shift = (attr->index == PSU_FAN1_WARN) ? 5 : 4; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t for_temp_fault(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + + + return sprintf(buf, "%d\n", data->temp_fault >> 7); +} + +static ssize_t for_temp_warning(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + if (data->valid != 1) + { + return -ENODEV; + } + + + return sprintf(buf, "%d\n", data->temp_fault >> 6); +} +static ssize_t for_vout_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + int exponent, mantissa; + int multiplier = 1000; + if (data->valid != 1) + { + return -ENODEV; + } + + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + mantissa = data->v_out; + + return (exponent > 0) ? sprintf(buf, "%d\n", \ + (mantissa << exponent) * multiplier) : \ + sprintf(buf, "%d\n", ((mantissa * multiplier) >> (-exponent))); +} + +static ssize_t for_ascii(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + u8 *ptr = NULL; + + if (data->valid != 1) + { + return -ENODEV; + } + + switch (attr->index) { + case PSU_MFR_ID: + ptr = data->mfr_id + 1; + break; + case PSU_MFR_MODEL: + ptr = data->mfr_model + 1; + break; + case PSU_MFR_SERIAL: + ptr = data->mfr_serial + 1; + break; + default: + return 0; + } + return sprintf(buf, "%s\n", ptr); +} + + +static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + u8 *ptr = NULL; + + u8 status = 0; + + if (attr->index == PSU_PRESENT) { + status = data->psu_is_present; + } + else { /* PSU_POWER_GOOD */ + if (!data->valid) { + return -ENODEV; + } + + status = data->psu_is_good; + } + + return sprintf(buf, "%d\n", status); +} + + +static int cs5435_54p_psu_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int cs5435_54p_psu_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int cs5435_54p_psu_write_word(struct i2c_client *client, u8 reg, \ + u16 value) +{ + union i2c_smbus_data data; + data.word = value; + return i2c_smbus_xfer(client->adapter, client->addr, + client->flags |= I2C_CLIENT_PEC, + I2C_SMBUS_WRITE, reg, + I2C_SMBUS_WORD_DATA, &data); + +} + +static int cs5435_54p_psu_read_block(struct i2c_client *client, u8 command, \ + u8 *data, int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, + data); + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; +abort: + return result; + +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + + + +#define EEPROM_NAME "psu_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ + +/* Platform dependent --- */ +static ssize_t psu_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ + int status, retry = 3; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(100); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return data_len; + +} + + +static ssize_t psu_page_write(struct i2c_client *client,const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + + + while (count) { + ssize_t status; + + status = psu_eeprom_write(client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + + return retval; +} + + + +static ssize_t psu_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct cs5435_54p_psu_data *data; + ssize_t retval = 0; + struct i2c_client *client; + + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + client = to_i2c_client(container_of(kobj, struct device, kobj)); + + mutex_lock(&data->update_lock); + retval = psu_page_write(client, buf, off, count); + mutex_unlock(&data->update_lock); + return retval; +} + + +static ssize_t psu_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int status, retry = 3; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(100); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + goto abort; + } + if (unlikely(status != data_len)) { + status = -EIO; + goto abort; + } + +abort: + return status; +} + + + +static ssize_t psu_page_read(struct i2c_client *client,char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + printk("Count = 0, return"); + return count; + } + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + + + while (count) { + ssize_t status; + + status = psu_eeprom_read(client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + + return retval; + +} + + +static ssize_t psu_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct cs5435_54p_psu_data *data; + struct i2c_client *client; + ssize_t retval = 0; + + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + client = to_i2c_client(container_of(kobj, struct device, kobj)); + mutex_lock(&data->update_lock); + retval = psu_page_read(client, buf, off, count); + mutex_unlock(&data->update_lock); + + return retval; +} + + + +static int psu_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = psu_bin_read; + eeprom->write = psu_bin_write; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + + +static int psu_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + + +static int psu_i2c_check_functionality(struct i2c_client *client) +{ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_I2C_BLOCK); +} + + + +static int psu_eeprom_probe(struct i2c_client *client, const struct i2c_device_id *dev_id) +{ + int status; + + struct cs5435_54p_psu_data *data; + + if (!psu_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + data->bin = kzalloc(sizeof(struct bin_attribute), GFP_KERNEL); + if (!data->bin) { + status = -ENOMEM; + goto eeprom_bin_error; + } + + /* init eeprom */ + status = psu_sysfs_eeprom_init(&client->dev.kobj, data->bin); + if (status) { + status = -ENOMEM; + goto sys_init_error; + } + + dev_info(&client->dev, "psu eeprom '%s'\n", client->name); + + return 0; + + sys_init_error: + kfree(data->bin); + + eeprom_bin_error: + kfree(data); + + exit: + return status; +} + + + + +static struct cs5435_54p_psu_data *cs5435_54p_psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cs5435_54p_psu_data *data = i2c_get_clientdata(client); + + + mutex_lock(&data->update_lock); + + + if (time_after(jiffies, data->last_updated)) { + int i, status; + u8 command; + struct reg_data_byte regs_byte[] = { + {0x20, &data->vout_mode}, + {0x81, &data->fan_fault}, + {0x7d, &data->temp_fault}, + }; + struct reg_data_word regs_word[] = { + {0x88, &data->v_in}, + {0x8b, &data->v_out}, + {0x89, &data->i_in}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x97, &data->p_in}, + {0x8d, &(data->temp_input[0])}, + {0x8e, &(data->temp_input[1])}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x90, &(data->fan_speed[0])}, + }; + data->valid = 1; + + dev_dbg(&client->dev, "start data update\n"); + + /* one milliseconds from now */ + data->last_updated = jiffies + HZ / 1000; + + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = cs5435_54p_psu_read_byte(client, + regs_byte[i].reg); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + *(regs_byte[i].value) = 0; + data->valid = 0; + } else { + *(regs_byte[i].value) = status; + } + } + + for (i = 0; i < ARRAY_SIZE(regs_word); i++) + { + status = cs5435_54p_psu_read_word(client,regs_word[i].reg); + if (status < 0) + { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + *(regs_word[i].value) = 0; + data->valid = 0; + } + else + { + *(regs_word[i].value) = status; + } + } + + command = 0x99; /* PSU mfr_id */ + status = cs5435_54p_psu_read_block(client, command, + data->mfr_id, ARRAY_SIZE(data->mfr_id) - 1); + data->mfr_id[ARRAY_SIZE(data->mfr_id) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_id, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + command = 0x9a; /* PSU mfr_model */ + status = cs5435_54p_psu_read_block(client, command, + data->mfr_model, ARRAY_SIZE(data->mfr_model) - 1); + data->mfr_model[ARRAY_SIZE(data->mfr_model) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_model, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + command = 0x9e; /* PSU mfr_serial */ + status = cs5435_54p_psu_read_block(client, command, + data->mfr_serial, ARRAY_SIZE(data->mfr_serial) - 1); + data->mfr_serial[ARRAY_SIZE(data->mfr_serial) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_serial, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + data->psu_is_present = strlen(data->mfr_id) > 1 ? 1:0; + if(data->psu_is_present) + { + data->psu_is_good = ((data->fan_fault) || (data->temp_fault))? 0:1; + } + else + { + data->valid = 0; + data->psu_is_good = 0; + } + } + + mutex_unlock(&data->update_lock); + + return data; + +} + +/* sysfs attributes for hwmon */ +static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, for_linear_data, NULL, PSU_V_IN); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, for_vout_data, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, for_linear_data, NULL, PSU_I_IN); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, for_linear_data, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, for_linear_data, NULL, PSU_P_IN); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, for_linear_data, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp2_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP2_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp3_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP3_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, for_temp_fault, NULL, PSU_TEMP_FAULT); +static SENSOR_DEVICE_ATTR(psu_temp_warning, S_IRUGO, for_temp_warning, NULL, PSU_TEMP_WARN); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, for_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_fan1_warning, S_IRUGO, for_fan_warning, NULL, PSU_FAN1_WARN); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, for_linear_data, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, for_linear_data, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, for_ascii, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, for_ascii, NULL, PSU_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu_mfr_serial, S_IRUGO, for_ascii, NULL, PSU_MFR_SERIAL); +static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, for_status, NULL, PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, for_status, NULL, PSU_P_GOOD); + + + +static struct attribute *cs5435_54p_psu_attributes[] = { + &sensor_dev_attr_psu_v_in.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_in.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_in.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_temp2_input.dev_attr.attr, + &sensor_dev_attr_psu_temp3_input.dev_attr.attr, + &sensor_dev_attr_psu_temp_fault.dev_attr.attr, + &sensor_dev_attr_psu_temp_warning.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_fan1_warning.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_mfr_serial.dev_attr.attr, + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + NULL +}; + +static const struct attribute_group cs5435_54p_psu_group = { + .attrs = cs5435_54p_psu_attributes, +}; + + +static int psu_register_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int status; + + + struct cs5435_54p_psu_data *data; + + if (!psu_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &cs5435_54p_psu_group); + if (status) + goto exit_sysfs_create_group; + + cs5435_54p_sysfs_add_client(client); + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_hwmon_device_register; + } + + /* init eeprom */ + + return 0; + + exit_hwmon_device_register: + sysfs_remove_group(&client->dev.kobj, &cs5435_54p_psu_group); + exit_sysfs_create_group: + kfree(data); + exit: + return status; + +} + + +static int cs5435_54p_psu_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int status; + + if((client->addr == 0x52) ||(client->addr == 0x53)) + { + status = psu_eeprom_probe(client, id); + } + else if((client->addr == 0x5a) ||(client->addr == 0x5b)) + { + status = psu_register_probe(client, id); + } + return status; +} + +static int cs5435_54p_psu_remove(struct i2c_client *client) +{ + cs5435_54p_sysfs_remove_client(client); + + if((client->addr == 0x52) ||(client->addr == 0x53)) + { + struct cs5435_54p_psu_data *data; + data = i2c_get_clientdata(client); + psu_sysfs_eeprom_cleanup(&client->dev.kobj,data->bin); + kfree(data); + } + else if((client->addr == 0x5a) ||(client->addr == 0x5b)) + { + struct cs5435_54p_psu_data *data; + data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &cs5435_54p_psu_group); + kfree(data); + } + + return 0; +} + +enum psu_index +{ + cs5435_54p_psu1, + cs5435_54p_psu2 +}; + +static const struct i2c_device_id cs5435_54p_psu_id[] = { + { "cs5435_54p_psu1", cs5435_54p_psu1 }, + { "cs5435_54p_psu2", cs5435_54p_psu2 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, cs5435_54p_psu_id); + +static struct i2c_driver cs5435_54p_psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "cs5435_54p_psu", + }, + .probe = cs5435_54p_psu_probe, + .remove = cs5435_54p_psu_remove, + .id_table = cs5435_54p_psu_id, + .address_list = normal_i2c, +}; + +module_i2c_driver(cs5435_54p_psu_driver); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs5435_54p_psu driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sfp.c b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sfp.c new file mode 100644 index 000000000000..3bdb3d2de791 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sfp.c @@ -0,0 +1,1713 @@ +/* + * A hwmon driver for the CIG cs5435-54P SFP Module + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "i2c-algo-lpc.h" + +#define DRIVER_NAME "cs5435_54p_sfp" /* Platform dependent */ + +#define DEBUG_MODE 0 + +#if (DEBUG_MODE == 1) + #define DEBUG_PRINT(fmt, args...) \ + printk (KERN_INFO "%s:%s[%d]: " fmt "\r\n", __FILE__, __FUNCTION__, __LINE__, ##args) +#else + #define DEBUG_PRINT(fmt, args...) +#endif + +#define EEPROM_NAME "sfp_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ +#define BIT_INDEX(i) (1ULL << (i)) +#define USE_I2C_BLOCK_READ 1 /* Platform dependent */ +#define I2C_RW_RETRY_COUNT 3 +#define I2C_RW_RETRY_INTERVAL 100 /* ms */ + +#define SFP_EEPROM_A0_I2C_ADDR (0xA0 >> 1) +#define SFP_EEPROM_A2_I2C_ADDR (0xA2 >> 1) + +#define SFF8024_PHYSICAL_DEVICE_ID_ADDR 0x0 +#define SFF8024_DEVICE_ID_SFP 0x3 +#define SFF8024_DEVICE_ID_QSFP 0xC +#define SFF8024_DEVICE_ID_QSFP_PLUS 0xD +#define SFF8024_DEVICE_ID_QSFP28 0x11 + +#define SFF8472_DIAG_MON_TYPE_ADDR 92 +#define SFF8472_DIAG_MON_TYPE_DDM_MASK 0x40 +#define SFF8472_10G_ETH_COMPLIANCE_ADDR 0x3 +#define SFF8472_10G_BASE_MASK 0xF0 + +#define SFF8436_RX_LOS_ADDR 3 +#define SFF8436_TX_FAULT_ADDR 4 +#define SFF8436_TX_DISABLE_ADDR 86 +#define QSFP_RESET_ADDR 0x1b +#define QSFP_INTER_ADDR 0x1a +#define QSFP_LPMODE_ADDR 0x1c + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_port_type(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_present(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count);; +static ssize_t sfp_show_ddm_implemented(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_eeprom_read(struct i2c_client *, u8, u8 *,int); +static ssize_t sfp_eeprom_write(struct i2c_client *, u8 , const char *,int); +extern int cig_cpld_read_register(u8 reg_off, u8 *val); +extern int cig_cpld_write_register(u8 reg_off, u8 val); + +static ssize_t qsfp_reset_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_reset_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_inter_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_lpmode_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_lpmode_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + +enum sfp_sysfs_attributes { + PRESENT, + PRESENT_ALL, + PORT_NUMBER, + PORT_TYPE, + DDM_IMPLEMENTED, + TX_FAULT, + TX_FAULT1, + TX_FAULT2, + TX_FAULT3, + TX_FAULT4, + TX_DISABLE, + TX_DISABLE1, + TX_DISABLE2, + TX_DISABLE3, + TX_DISABLE4, + RX_LOS, + RX_LOS1, + RX_LOS2, + RX_LOS3, + RX_LOS4, + RX_LOS_ALL, + QSFPRESET, + QSFPINT, + QSFPLPMODE +}; + +/* SFP/QSFP common attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, PORT_NUMBER); +static SENSOR_DEVICE_ATTR(sfp_port_type, S_IRUGO, show_port_type, NULL, PORT_TYPE); +static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_present, NULL, PRESENT); +static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_present, NULL, PRESENT_ALL); +static SENSOR_DEVICE_ATTR(sfp_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS); +static SENSOR_DEVICE_ATTR(sfp_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, TX_DISABLE); +static SENSOR_DEVICE_ATTR(sfp_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, TX_FAULT); + +/* QSFP attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_rx_los1, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS1); +static SENSOR_DEVICE_ATTR(sfp_rx_los2, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS2); +static SENSOR_DEVICE_ATTR(sfp_rx_los3, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS3); +static SENSOR_DEVICE_ATTR(sfp_rx_los4, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS4); +static SENSOR_DEVICE_ATTR(sfp_tx_disable1, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE1); +static SENSOR_DEVICE_ATTR(sfp_tx_disable2, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE2); +static SENSOR_DEVICE_ATTR(sfp_tx_disable3, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE3); +static SENSOR_DEVICE_ATTR(sfp_tx_disable4, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE4); +static SENSOR_DEVICE_ATTR(sfp_tx_fault1, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT1); +static SENSOR_DEVICE_ATTR(sfp_tx_fault2, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT2); +static SENSOR_DEVICE_ATTR(sfp_tx_fault3, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT3); +static SENSOR_DEVICE_ATTR(sfp_tx_fault4, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT4); +static SENSOR_DEVICE_ATTR(sfp_reset, S_IWUSR | S_IRUGO, qsfp_reset_read, qsfp_reset_write, QSFPRESET); +static SENSOR_DEVICE_ATTR(sfp_inter, S_IRUGO, qsfp_inter_read, NULL, QSFPINT); +static SENSOR_DEVICE_ATTR(sfp_lpmode, S_IWUSR | S_IRUGO, qsfp_lpmode_read, qsfp_lpmode_write, QSFPLPMODE); +static struct attribute *qsfp_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_port_type.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los1.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los2.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los3.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault4.dev_attr.attr, + &sensor_dev_attr_sfp_reset.dev_attr.attr, + &sensor_dev_attr_sfp_inter.dev_attr.attr, + &sensor_dev_attr_sfp_lpmode.dev_attr.attr, + NULL +}; + +/* SFP msa attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_ddm_implemented, S_IRUGO, sfp_show_ddm_implemented, NULL, DDM_IMPLEMENTED); +static SENSOR_DEVICE_ATTR(sfp_rx_los_all, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS_ALL); +static struct attribute *sfp_msa_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_port_type.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_ddm_implemented.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los_all.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + NULL +}; + +/* SFP ddm attributes for sysfs */ +static struct attribute *sfp_ddm_attributes[] = { + NULL +}; + +/* Platform dependent +++ */ +#define CPLD_PORT_TO_FRONT_PORT(port) (port+1) + +enum port_numbers { +cs5435_54p_sfp1, cs5435_54p_sfp2, cs5435_54p_sfp3, cs5435_54p_sfp4, +cs5435_54p_sfp5, cs5435_54p_sfp6, cs5435_54p_sfp7, cs5435_54p_sfp8, +cs5435_54p_sfp9, cs5435_54p_sfp10, cs5435_54p_sfp11, cs5435_54p_sfp12, +cs5435_54p_sfp13, cs5435_54p_sfp14, cs5435_54p_sfp15, cs5435_54p_sfp16, +cs5435_54p_sfp17, cs5435_54p_sfp18, cs5435_54p_sfp19, cs5435_54p_sfp20, +cs5435_54p_sfp21, cs5435_54p_sfp22, cs5435_54p_sfp23, cs5435_54p_sfp24, +cs5435_54p_sfp25, cs5435_54p_sfp26, cs5435_54p_sfp27, cs5435_54p_sfp28, +cs5435_54p_sfp29, cs5435_54p_sfp30, cs5435_54p_sfp31, cs5435_54p_sfp32, +cs5435_54p_sfp33, cs5435_54p_sfp34, cs5435_54p_sfp35, cs5435_54p_sfp36, +cs5435_54p_sfp37, cs5435_54p_sfp38, cs5435_54p_sfp39, cs5435_54p_sfp40, +cs5435_54p_sfp41, cs5435_54p_sfp42, cs5435_54p_sfp43, cs5435_54p_sfp44, +cs5435_54p_sfp45, cs5435_54p_sfp46, cs5435_54p_sfp47, cs5435_54p_sfp48, +cs5435_54p_sfp49, cs5435_54p_sfp50, cs5435_54p_sfp51, cs5435_54p_sfp52, +cs5435_54p_sfp53, cs5435_54p_sfp54, cs5435_54p_sfp55, cs5435_54p_sfp56 +}; + +#define I2C_DEV_ID(x) { #x, x} + +static const struct i2c_device_id sfp_device_id[] = { +I2C_DEV_ID(cs5435_54p_sfp1), +I2C_DEV_ID(cs5435_54p_sfp2), +I2C_DEV_ID(cs5435_54p_sfp3), +I2C_DEV_ID(cs5435_54p_sfp4), +I2C_DEV_ID(cs5435_54p_sfp5), +I2C_DEV_ID(cs5435_54p_sfp6), +I2C_DEV_ID(cs5435_54p_sfp7), +I2C_DEV_ID(cs5435_54p_sfp8), +I2C_DEV_ID(cs5435_54p_sfp9), +I2C_DEV_ID(cs5435_54p_sfp10), +I2C_DEV_ID(cs5435_54p_sfp11), +I2C_DEV_ID(cs5435_54p_sfp12), +I2C_DEV_ID(cs5435_54p_sfp13), +I2C_DEV_ID(cs5435_54p_sfp14), +I2C_DEV_ID(cs5435_54p_sfp15), +I2C_DEV_ID(cs5435_54p_sfp16), +I2C_DEV_ID(cs5435_54p_sfp17), +I2C_DEV_ID(cs5435_54p_sfp18), +I2C_DEV_ID(cs5435_54p_sfp19), +I2C_DEV_ID(cs5435_54p_sfp20), +I2C_DEV_ID(cs5435_54p_sfp21), +I2C_DEV_ID(cs5435_54p_sfp22), +I2C_DEV_ID(cs5435_54p_sfp23), +I2C_DEV_ID(cs5435_54p_sfp24), +I2C_DEV_ID(cs5435_54p_sfp25), +I2C_DEV_ID(cs5435_54p_sfp26), +I2C_DEV_ID(cs5435_54p_sfp27), +I2C_DEV_ID(cs5435_54p_sfp28), +I2C_DEV_ID(cs5435_54p_sfp29), +I2C_DEV_ID(cs5435_54p_sfp30), +I2C_DEV_ID(cs5435_54p_sfp31), +I2C_DEV_ID(cs5435_54p_sfp32), +I2C_DEV_ID(cs5435_54p_sfp33), +I2C_DEV_ID(cs5435_54p_sfp34), +I2C_DEV_ID(cs5435_54p_sfp35), +I2C_DEV_ID(cs5435_54p_sfp36), +I2C_DEV_ID(cs5435_54p_sfp37), +I2C_DEV_ID(cs5435_54p_sfp38), +I2C_DEV_ID(cs5435_54p_sfp39), +I2C_DEV_ID(cs5435_54p_sfp40), +I2C_DEV_ID(cs5435_54p_sfp41), +I2C_DEV_ID(cs5435_54p_sfp42), +I2C_DEV_ID(cs5435_54p_sfp43), +I2C_DEV_ID(cs5435_54p_sfp44), +I2C_DEV_ID(cs5435_54p_sfp45), +I2C_DEV_ID(cs5435_54p_sfp46), +I2C_DEV_ID(cs5435_54p_sfp47), +I2C_DEV_ID(cs5435_54p_sfp48), +I2C_DEV_ID(cs5435_54p_sfp49), +I2C_DEV_ID(cs5435_54p_sfp50), +I2C_DEV_ID(cs5435_54p_sfp51), +I2C_DEV_ID(cs5435_54p_sfp52), +I2C_DEV_ID(cs5435_54p_sfp53), +I2C_DEV_ID(cs5435_54p_sfp54), +I2C_DEV_ID(cs5435_54p_sfp55), +I2C_DEV_ID(cs5435_54p_sfp56), +{ /* LIST END */ } +}; +MODULE_DEVICE_TABLE(i2c, sfp_device_id); + +/* + * list of valid port types + * note OOM_PORT_TYPE_NOT_PRESENT to indicate no + * module is present in this port + */ +typedef enum oom_driver_port_type_e { + OOM_DRIVER_PORT_TYPE_INVALID, + OOM_DRIVER_PORT_TYPE_NOT_PRESENT, + OOM_DRIVER_PORT_TYPE_SFP, + OOM_DRIVER_PORT_TYPE_SFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP, + OOM_DRIVER_PORT_TYPE_QSFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP28 +} oom_driver_port_type_t; + +enum driver_type_e { + DRIVER_TYPE_SFP_MSA, + DRIVER_TYPE_SFP_DDM, + DRIVER_TYPE_QSFP +}; + +/* Each client has this additional data + */ +struct eeprom_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + struct bin_attribute bin; /* eeprom data */ +}; + +struct sfp_msa_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u64 status[6]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss + 3 => device id + 4 => 10G Ethernet Compliance Codes + to distinguish SFP or SFP+ + 5 => DIAGNOSTIC MONITORING TYPE */ + struct eeprom_data eeprom; +}; + +struct sfp_ddm_data { + struct eeprom_data eeprom; +}; + +struct qsfp_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status[3]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss */ + + u8 device_id; + struct eeprom_data eeprom; +}; + +struct sfp_port_data { + struct mutex update_lock; + enum driver_type_e driver_type; + int port; /* CPLD port index */ + oom_driver_port_type_t port_type; + u64 present; /* present status, bit0:port0, bit1:port1 and so on */ + + struct sfp_msa_data *msa; + struct sfp_ddm_data *ddm; + struct qsfp_data *qsfp; + + struct i2c_client *client; +}; + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port)); +} + + + +static int cig_cpld_write_sfp_register(u8 sfp_reg_addr, u8 sfp_write_reg_data) +{ + u8 sfp_read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, sfp_reg_addr << 1); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_TX, sfp_write_reg_data); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + do{ + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &sfp_read_status); + udelay(60); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(sfp_read_status != 0x02); + + if(wait_time_out == 0) + return -1; + + return 1; +} + + +static int cig_cpld_read_sfp_register(u8 sfp_reg_addr, u8 *sfp_read_reg_data) +{ + u8 sfp_read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, sfp_reg_addr << 1 | 1); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + do{ + udelay(60); + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &sfp_read_status); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(sfp_read_status != 0x01); + + cig_cpld_read_register(ADDR_REG_SFP_STATUS_RX,sfp_read_reg_data); + + if(wait_time_out == 0) + return -1; + + return 1; +} + + + + + + +/* Platform dependent +++ */ +static struct sfp_port_data *sfp_update_present(struct i2c_client *client) +{ + int i = 0, j = 0, status = -1; + unsigned char cpld_reg_data = 0,cpld_reg_addr = 0; + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT("Starting sfp present status update"); + mutex_lock(&data->update_lock); + data->present = 0; + + udelay(6000); + + /* Read present status of port 1~48(SFP port) */ + for (i = 0; i < 6; i++) { + cpld_reg_addr = 1 + i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->present |= (u64)cpld_reg_data << (i*8); + + DEBUG_PRINT("Present status = 0x%lx\r\n", data->present); + } + + /* Read present status of port 49-56(QSFP port) */ + cpld_reg_addr = 25; + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + else { + data->present |= (u64)cpld_reg_data << 48; + } + + DEBUG_PRINT("Present status = 0x%lx", data->present); +exit: + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0, j = 0; + int status = -1; + unsigned char cpld_reg_data = 0,cpld_reg_addr = 0; + + if (time_before(jiffies, data->msa->last_updated + HZ + HZ / 2) && data->msa->valid) { + return data; + } + + DEBUG_PRINT("Starting cs5435_54p sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->msa->valid = 0; + memset(data->msa->status, 0, sizeof(data->msa->status)); + + udelay(6000); + + /* Read status of port 1~48(SFP port) */ + for (i = 0; i < 6; i++) { + cpld_reg_addr = 13+i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->msa->status[0] |= (u64)cpld_reg_data << (i * 8); + + DEBUG_PRINT("tx rx status[0] = 0x%lx\r\n", data->msa->status[0]); + } + + + for (i = 0; i < 6; i++) { + cpld_reg_addr = 19+i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->msa->status[1] |= (u64)cpld_reg_data << (i * 8); + + DEBUG_PRINT("tx rx status[1] = 0x%lx\r\n", data->msa->status[1]); + } + + for (i = 0; i < 6; i++) { + cpld_reg_addr = 7+i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->msa->status[2] |= (u64)cpld_reg_data << (i * 8); + + DEBUG_PRINT("tx rx status[2] = 0x%lx\r\n", data->msa->status[2]); + } + + data->msa->valid = 1; + data->msa->last_updated = jiffies; + +exit: + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + unsigned char cpld_reg_data = 0,cpld_reg_addr = 0,cpld_reg_bit = 0,cpld_reg_val = 0; + long disable; + int error; + + if (data->driver_type == DRIVER_TYPE_QSFP) { + return qsfp_set_tx_disable(dev, da, buf, count); + } + + error = kstrtol(buf, 10, &disable); + if (error) { + return error; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + + if(data->port <= 48) { + cpld_reg_addr = 19 + data->port / 8; + cpld_reg_bit = 1 << ((data->port) % 8); + } + + /* Read current status */ + error = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + + /* Update tx_disable status */ + if (disable) { + data->msa->status[1] |= BIT_INDEX(data->port); + cpld_reg_data |= cpld_reg_bit; + } + else { + data->msa->status[1] &= ~ BIT_INDEX(data->port); + cpld_reg_data &= ~cpld_reg_bit; + } + + error = cig_cpld_write_sfp_register(cpld_reg_addr,cpld_reg_data); + + mutex_unlock(&data->update_lock); + return count; +} +/* Platform dependent --- */ + +static int sfp_is_port_present(struct i2c_client *client, int port) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + + data = sfp_update_present(client); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + return !(data->present & BIT_INDEX(data->port)); /* Platform dependent */ +} + +/* Platform dependent +++ */ +static ssize_t show_present(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + + if (PRESENT_ALL == attr->index) { + int i; + u8 values[7] = {0}; + struct sfp_port_data *data = sfp_update_present(client); + + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + for (i = 0; i < ARRAY_SIZE(values); i++) { + values[i] = ~(u8)(data->present >> (i * 8)); + } + + /* Return values 1 -> 56 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5], + values[6]); + } + else { + struct sfp_port_data *data = i2c_get_clientdata(client); + int present = sfp_is_port_present(client, data->port); + + if (IS_ERR_VALUE(present)) { + return present; + } + + /* PRESENT */ + return sprintf(buf, "%d\n", present); + } +} +/* Platform dependent --- */ + +static struct sfp_port_data *sfp_update_port_type(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + u8 buf = 0; + int status; + + mutex_lock(&data->update_lock); + + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + { + status = sfp_eeprom_read(client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + if (buf != SFF8024_DEVICE_ID_SFP) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + status = sfp_eeprom_read(client, SFF8472_10G_ETH_COMPLIANCE_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("sfp port type (0x3) data = (0x%x)", buf); + data->port_type = buf & SFF8472_10G_BASE_MASK ? OOM_DRIVER_PORT_TYPE_SFP_PLUS : OOM_DRIVER_PORT_TYPE_SFP; + break; + } + case DRIVER_TYPE_QSFP: + { + status = sfp_eeprom_read(client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("qsfp port type (0x0) buf = (0x%x)", buf); + switch (buf) { + case SFF8024_DEVICE_ID_QSFP: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP; + break; + case SFF8024_DEVICE_ID_QSFP_PLUS: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; + break; + case SFF8024_DEVICE_ID_QSFP28: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; + break; + default: + data->port_type = buf; + break; + } + + break; + } + default: + break; + } + + mutex_unlock(&data->update_lock); + return data; +} + +static ssize_t show_port_type(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int present = sfp_is_port_present(client, data->port); + + if (IS_ERR_VALUE(present)) { + return present; + } + + if (!present) { + /* port is not present */ + return sprintf(buf, "%d\n", OOM_DRIVER_PORT_TYPE_NOT_PRESENT); + } + + sfp_update_port_type(dev); + return sprintf(buf, "%d\n", data->port_type); +} + +static struct sfp_port_data *qsfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i, status = -1; + u8 buf = 0; + u8 reg[] = {SFF8436_TX_FAULT_ADDR, SFF8436_TX_DISABLE_ADDR, SFF8436_RX_LOS_ADDR}; + + DEBUG_PRINT(""); + if (time_before(jiffies, data->qsfp->last_updated + HZ + HZ / 2) && data->qsfp->valid) { + return data; + } + + DEBUG_PRINT("Starting sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->qsfp->valid = 0; + memset(data->qsfp->status, 0, sizeof(data->qsfp->status)); + + DEBUG_PRINT(""); + /* Notify device to update tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); + if (unlikely(status < 0)) { + DEBUG_PRINT(""); + goto exit; + } + } + msleep(200); + DEBUG_PRINT(""); + + /* Read actual tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); + if (unlikely(status < 0)) { + DEBUG_PRINT(""); + goto exit; + } + + DEBUG_PRINT("qsfp reg(0x%x) status = (0x%x)", reg[i], data->qsfp->status[i]); + data->qsfp->status[i] = (buf & 0xF); + } + + DEBUG_PRINT(""); + data->qsfp->valid = 1; + data->qsfp->last_updated = jiffies; + +exit: + DEBUG_PRINT(""); + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static ssize_t qsfp_inter_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_INTER_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("inter read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + + +static ssize_t qsfp_reset_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_RESET_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("reset read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_reset_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + long usrdata; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + ret = kstrtol(buf, 10, &usrdata); + if (ret) { + return ret; + } + + usrdata = usrdata > 0 ? 1 : 0; + index = data->port - 48; + + DEBUG_PRINT("usrdata = %u, index = %hhu\n", usrdata, index); + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_RESET_ADDR, &cpld_reg_data); + if (ret == 1) + { + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + cpld_reg_data &= ~(1 << index); + cpld_reg_data |= usrdata << index; + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + ret = cig_cpld_write_sfp_register(QSFP_RESET_ADDR, cpld_reg_data); + if (1 != ret) + { + DEBUG_PRINT("write failed\n"); + } + } + else + { + DEBUG_PRINT("read failed\n"); + } + + mutex_unlock(&data->update_lock); + + if (ret != 1) + return -1; + + return count; +} + + + + +static ssize_t qsfp_lpmode_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_LPMODE_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("lpmode read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_lpmode_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + long usrdata; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + ret = kstrtol(buf, 10, &usrdata); + if (ret) { + return ret; + } + + usrdata = usrdata > 0 ? 1 : 0; + index = data->port - 48; + + DEBUG_PRINT("usrdata = %u, index = %hhu\n", usrdata, index); + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_LPMODE_ADDR, &cpld_reg_data); + if (ret == 1) + { + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + cpld_reg_data &= ~(1 << index); + cpld_reg_data |= usrdata << index; + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + ret = cig_cpld_write_sfp_register(QSFP_LPMODE_ADDR, cpld_reg_data); + if (1 != ret) + { + DEBUG_PRINT("write failed\n"); + } + } + else + { + DEBUG_PRINT("read failed\n"); + } + + mutex_unlock(&data->update_lock); + + if (ret != 1) + return -1; + + return count; +} + + + +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + int present; + u8 val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT(""); + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + DEBUG_PRINT(""); + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + DEBUG_PRINT(""); + data = qsfp_update_tx_rx_status(dev); + DEBUG_PRINT(""); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + DEBUG_PRINT(""); + switch (attr->index) { + case TX_FAULT: + val = !!(data->qsfp->status[2] & 0xF); + break; + case TX_FAULT1: + case TX_FAULT2: + case TX_FAULT3: + case TX_FAULT4: + val = !!(data->qsfp->status[2] & BIT_INDEX(attr->index - TX_FAULT1)); + break; + case TX_DISABLE: + val = data->qsfp->status[1] & 0xF; + break; + case TX_DISABLE1: + case TX_DISABLE2: + case TX_DISABLE3: + case TX_DISABLE4: + val = !!(data->qsfp->status[1] & BIT_INDEX(attr->index - TX_DISABLE1)); + break; + case RX_LOS: + val = !!(data->qsfp->status[0] & 0xF); + break; + case RX_LOS1: + case RX_LOS2: + case RX_LOS3: + case RX_LOS4: + val = !!(data->qsfp->status[0] & BIT_INDEX(attr->index - RX_LOS1)); + break; + default: + break; + } + + DEBUG_PRINT(""); + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + long disable; + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + status = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(status)) { + return status; + } + + if (!status) { + /* port is not present */ + return -ENXIO; + } + + status = kstrtol(buf, 10, &disable); + if (status) { + return status; + } + + data = qsfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + mutex_lock(&data->update_lock); + + if (attr->index == TX_DISABLE) { + data->qsfp->status[1] = disable & 0xF; + } + else {/* TX_DISABLE1 ~ TX_DISABLE4*/ + if (disable) { + data->qsfp->status[1] |= (1 << (attr->index - TX_DISABLE1)); + } + else { + data->qsfp->status[1] &= ~(1 << (attr->index - TX_DISABLE1)); + } + } + + DEBUG_PRINT("index = (%d), status = (0x%x)", attr->index, data->qsfp->status[1]); + status = sfp_eeprom_write(data->client, SFF8436_TX_DISABLE_ADDR, &data->qsfp->status[1], sizeof(data->qsfp->status[1])); + if (unlikely(status < 0)) { + count = status; + } + + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t sfp_show_ddm_implemented(struct device *dev, struct device_attribute *da, + char *buf) +{ + int status; + char ddm; + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + status = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(status)) { + return status; + } + + if (status == 0) { + /* port is not present */ + return -ENODEV; + } + + status = sfp_eeprom_read(client, SFF8472_DIAG_MON_TYPE_ADDR, &ddm, sizeof(ddm)); + if (unlikely(status < 0)) { + return status; + } + + return sprintf(buf, "%d\n", !!(ddm & SFF8472_DIAG_MON_TYPE_DDM_MASK)); +} + +/* Platform dependent +++ */ +static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + u8 val = 0, index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT("driver type = (%d)", data->driver_type); + if (data->driver_type == DRIVER_TYPE_QSFP) { + DEBUG_PRINT(""); + return qsfp_show_tx_rx_status(dev, da, buf); + } + + DEBUG_PRINT(""); + data = sfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + if(attr->index == RX_LOS_ALL) { + int i = 0; + u8 values[6] = {0}; + + for (i = 0; i < ARRAY_SIZE(values); i++) { + values[i] = (u8)(data->msa->status[2] >> (i * 8)); + } + + /** Return values 1 -> 48 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5]); + } + + switch (attr->index) { + case TX_FAULT: + index = 0; + break; + case TX_DISABLE: + index = 1; + break; + case RX_LOS: + index = 2; + break; + default: + break; + } + + val = !!(data->msa->status[index] & BIT_INDEX(data->port)); + return sprintf(buf, "%d\n", val); +} +/* Platform dependent --- */ +static ssize_t sfp_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int status, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return data_len; +#else + int status, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, command, *data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return 1; +#endif + + +} + +static ssize_t sfp_port_write(struct sfp_port_data *data, + const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_write(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; +} + + +static ssize_t sfp_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct sfp_port_data *data; + DEBUG_PRINT("%s(%d) offset = (%d), count = (%d)", off, count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + present = sfp_is_port_present(data->client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + return sfp_port_write(data, buf, off, count); +} + +static ssize_t sfp_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int status, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + goto abort; + } + if (unlikely(status != data_len)) { + status = -EIO; + goto abort; + } + + //result = data_len; + +abort: + return status; +#else + int status, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, command); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, status); + goto abort; + } + + *data = (u8)status; + status = 1; + +abort: + return status; +#endif +} + +static ssize_t sfp_port_read(struct sfp_port_data *data, + char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + DEBUG_PRINT("Count = 0, return"); + return count; + } + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_read(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; + +} + +static ssize_t sfp_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct sfp_port_data *data; + DEBUG_PRINT("offset = (%d), count = (%d)", off, count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + present = sfp_is_port_present(data->client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + return sfp_port_read(data, buf, off, count); +} + +static int sfp_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = sfp_bin_read; + eeprom->write = sfp_bin_write; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + +static int sfp_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + +static const struct attribute_group sfp_msa_group = { + .attrs = sfp_msa_attributes, +}; + +static int sfp_i2c_check_functionality(struct i2c_client *client) +{ +#if USE_I2C_BLOCK_READ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK); +#else + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA); +#endif +} + +static int sfp_msa_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_msa_data **data) +{ + int status; + struct sfp_msa_data *msa; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + msa = kzalloc(sizeof(struct sfp_msa_data), GFP_KERNEL); + if (!msa) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_msa_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &msa->eeprom.bin); + if (status) { + goto exit_remove; + } + + *data = msa; + dev_info(&client->dev, "sfp msa '%s'\n", client->name); + + cs5435_54p_sysfs_add_client(client); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); +exit_free: + kfree(msa); +exit: + + return status; +} + +static const struct attribute_group sfp_ddm_group = { + .attrs = sfp_ddm_attributes, +}; + +static int sfp_ddm_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_ddm_data **data) +{ + int status; + struct sfp_ddm_data *ddm; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + ddm = kzalloc(sizeof(struct sfp_ddm_data), GFP_KERNEL); + if (!ddm) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_ddm_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &ddm->eeprom.bin); + if (status) { + goto exit_remove; + } + + *data = ddm; + dev_info(&client->dev, "sfp ddm '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); +exit_free: + kfree(ddm); +exit: + + return status; +} + +static const struct attribute_group qsfp_group = { + .attrs = qsfp_attributes, +}; + +static int qsfp_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct qsfp_data **data) +{ + int status; + struct qsfp_data *qsfp; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + qsfp = kzalloc(sizeof(struct qsfp_data), GFP_KERNEL); + if (!qsfp) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &qsfp_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &qsfp->eeprom.bin); + if (status) { + goto exit_remove; + } + + /* Bring QSFPs out of reset */ + //cig_lpc_write(0x62, 0x15, 0x3F); + + *data = qsfp; + dev_info(&client->dev, "qsfp '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &qsfp_group); +exit_free: + kfree(qsfp); +exit: + + return status; +} + +/* Platform dependent +++ */ +static int sfp_device_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct sfp_port_data *data = NULL; + + data = kzalloc(sizeof(struct sfp_port_data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->port = dev_id->driver_data; + data->client = client; + + if (dev_id->driver_data >= cs5435_54p_sfp1 && dev_id->driver_data <= cs5435_54p_sfp48) { + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_SFP_MSA; + return sfp_msa_probe(client, dev_id, &data->msa); + } + else if (client->addr == SFP_EEPROM_A2_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_SFP_DDM; + return sfp_ddm_probe(client, dev_id, &data->ddm); + } + } + else { /* cs5435_54p_sfp49 ~ cs5435_54p_sfp56 */ + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_QSFP; + return qsfp_probe(client, dev_id, &data->qsfp); + } + } + + return -ENODEV; +} +/* Platform dependent --- */ + +static int sfp_msa_remove(struct i2c_client *client, struct sfp_msa_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); + kfree(data); + return 0; +} + +static int sfp_ddm_remove(struct i2c_client *client, struct sfp_ddm_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); + kfree(data); + return 0; +} + +static int qfp_remove(struct i2c_client *client, struct qsfp_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &qsfp_group); + kfree(data); + return 0; +} + +static int sfp_device_remove(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + + cs5435_54p_sysfs_remove_client(client); + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + return sfp_msa_remove(client, data->msa); + case DRIVER_TYPE_SFP_DDM: + return sfp_ddm_remove(client, data->ddm); + case DRIVER_TYPE_QSFP: + return qfp_remove(client, data->qsfp); + } + + return 0; +} + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +static struct i2c_driver cs5435_54p_sfp_driver = { + .driver = { + .name = DRIVER_NAME, + }, + .probe = sfp_device_probe, + .remove = sfp_device_remove, + .id_table = sfp_device_id, + .address_list = normal_i2c, +}; + +module_i2c_driver(cs5435_54p_sfp_driver); + + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs5435_54p_sfp driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sysfs.c b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sysfs.c new file mode 100644 index 000000000000..0ba8836cf33a --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sysfs.c @@ -0,0 +1,335 @@ +/* + * A hwmon driver for the CIG cs5435-54P sysfs Module + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "i2c-algo-lpc.h" + + +static LIST_HEAD(sysfs_client_list); +static struct mutex list_lock; + +struct sysfs_client_node { + struct i2c_client *client; + struct list_head list; +}; + +#define DEVICE_NAME "cigfs" +static int dev_major; +static struct class *dev_class; +static struct cdev *dev_cdev; +static struct device *dev_device; +static struct class *psu_class; +static struct class *sfp_class; + + +void cs5435_54p_sysfs_add_client(struct i2c_client *client) +{ + struct sysfs_client_node *node = kzalloc(sizeof(struct sysfs_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate sysfs_client_node (0x%x)\n", client->addr); + return; + } + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &sysfs_client_list); + mutex_unlock(&list_lock); +} + +EXPORT_SYMBOL(cs5435_54p_sysfs_add_client); + +void cs5435_54p_sysfs_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (IS_ERR(sysfs_node)) + { + break; + } + if (sysfs_node->client == client) { + found = 1; + break; + } + } + if (found) { + list_del(list_node); + kfree(sysfs_node); + } + + mutex_unlock(&list_lock); +} + +EXPORT_SYMBOL(cs5435_54p_sysfs_remove_client); + +struct class * cs5435_54p_sysfs_create_symclass(char *cls_name) +{ + int rc = 0; + struct class *my_class; +/**************************************************************************************/ + my_class = class_create(THIS_MODULE,cls_name); + if (IS_ERR(my_class)) { + pr_err("failed to create my class\n"); + } + return my_class; + +/**************************************************************************************/ +} + +void cs5435_54p_sysfs_delete_symclass(struct class *my_class) +{ +/**************************************************************************************/ + + if (IS_ERR(my_class)) { + pr_err("Pointer is invaild\n"); + } + class_destroy(my_class); + +/**************************************************************************************/ +} + + + + + +int cs5435_54p_sysfs_create_symlink(struct class *my_class,char * driver_name,char *device_name) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int ret = -EPERM; + int rc = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (!strcmp(sysfs_node->client->name,driver_name)) { + rc = sysfs_create_link(&my_class->p->subsys.kobj, &sysfs_node->client->dev.kobj,device_name); + if(rc) + { + pr_err("failed to create symlink %d\n",rc); + } + break; + } + } + mutex_unlock(&list_lock); + return ret; +} + + +int cs5435_54p_sysfs_delete_symlink(struct class *my_class,char * driver_name,char *device_name) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int ret = -EPERM; + int rc = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (!strcmp(sysfs_node->client->name,driver_name)) { + sysfs_remove_link(&my_class->p->subsys.kobj,device_name); + break; + } + } + mutex_unlock(&list_lock); + return ret; +} + + +static int cs5435_54p_sysfs_open(struct inode *inode, struct file *file) +{ + return 0; +} + + + +static ssize_t cs5435_54p_sysfs_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) +{ + char str[10],name[18],port[8]; + int ret; + int i; + memset(str, 0, sizeof(str)); + ret = copy_from_user(str, buf, count); + if (ret) + { + printk(KERN_ERR "copy_from_user fail\n"); + return -EINVAL; + } + + if(!strncmp(str,"start",5)) + { + psu_class = cs5435_54p_sysfs_create_symclass("psu"); + cs5435_54p_sysfs_create_symlink(psu_class,"cs5435_54p_psu1","psu1"); + cs5435_54p_sysfs_create_symlink(psu_class,"cs5435_54p_psu2","psu2"); + sfp_class = cs5435_54p_sysfs_create_symclass("swps"); + for(i = 1; i <= 48;i++) + { + memset(name,0xff,sizeof(name)); + memset(port,0xff,sizeof(port)); + snprintf(name,sizeof(name),"cs5435_54p_sfp%d",i); + snprintf(port,sizeof(port),"port%d",i); + cs5435_54p_sysfs_create_symlink(sfp_class,name,port); + } + } + else if(!strncmp(str,"stop",4)) + { + cs5435_54p_sysfs_delete_symlink(psu_class,"cs5435_54p_psu1","psu1"); + cs5435_54p_sysfs_delete_symlink(psu_class,"cs5435_54p_psu2","psu2"); + cs5435_54p_sysfs_delete_symclass(psu_class); + + for(i = 1; i <= 48;i++) + { + memset(name,0xff,sizeof(name)); + memset(port,0xff,sizeof(port)); + snprintf(name,sizeof(name),"cs5435_54p_sfp%d",i); + snprintf(port,sizeof(port),"port%d",i); + cs5435_54p_sysfs_delete_symlink(sfp_class,name,port); + } + cs5435_54p_sysfs_delete_symclass(sfp_class); + } + return count; +} + + +static struct file_operations cs5435_54p_sysfs_fops = { + .owner = THIS_MODULE, + .open = cs5435_54p_sysfs_open, + .write = cs5435_54p_sysfs_write, +}; + + +static int __init cs5435_54p_sysfs_init(void) +{ + int result = 0; + int err = 0; + dev_t dev = MKDEV(dev_major, 0); + + if (dev_major) + result = register_chrdev_region(dev, 1, DEVICE_NAME); + else { + result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME); + dev_major = MAJOR(dev); + } + if (result < 0) + { + printk("unable to get major %d\n", dev_major); + err= -EINVAL; + } + printk("get major is %d\n", dev_major); + if (dev_major == 0) + dev_major = result; + + dev_cdev= kmalloc(sizeof(struct cdev), GFP_KERNEL); + if(IS_ERR(dev_cdev)) { + err= -ENOMEM; + } + + cdev_init(dev_cdev, &cs5435_54p_sysfs_fops); + dev_cdev->owner = THIS_MODULE; + dev_cdev->ops = &cs5435_54p_sysfs_fops; + err = cdev_add(dev_cdev, dev, 1); + if (err) + { + printk("error %d add fpga ", err); + goto err_malloc; + } + + dev_class = class_create(THIS_MODULE, DEVICE_NAME); + if (IS_ERR(dev_class)) + { + printk("Err:failed in creating class.\n"); + goto err_cdev_add; + } + + dev_device = device_create(dev_class, NULL, MKDEV(dev_major, 0), NULL, DEVICE_NAME); + if (IS_ERR(dev_device)) + { + printk("Err:failed in creating device.\n"); + goto err_class_crt; + } + + mutex_init(&list_lock); + + return err; + + err_class_crt: + cdev_del(dev_cdev); + err_cdev_add: + kfree(dev_cdev); + err_malloc: + unregister_chrdev_region(MKDEV(dev_major,0), 1); + + return err; + +} + +static void __exit cs5435_54p_sysfs_exit(void) +{ + cdev_del(dev_cdev); + printk("cdev_del ok\n"); + device_destroy(dev_class, MKDEV(dev_major, 0)); + + class_destroy(dev_class); + + if(dev_cdev != NULL) + kfree(dev_cdev); + + unregister_chrdev_region(MKDEV(dev_major, 0), 1); + printk("cs5435_54p_sysfs_exit...\r\n"); +} + + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs5435-54p-sysfs driver"); +MODULE_LICENSE("GPL"); + +module_init(cs5435_54p_sysfs_init); +module_exit(cs5435_54p_sysfs_exit); + + diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-init.service b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-init.service new file mode 100644 index 000000000000..b609a2be45c7 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-init.service @@ -0,0 +1,13 @@ +[Unit] +Description=Cig CS5435-54P Platform initialization service +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/cig_cs5435_util.py install +ExecStop=/usr/local/bin/cig_cs5435_util.py clean +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-misc.service b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-misc.service new file mode 100644 index 000000000000..852ab5689a70 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-misc.service @@ -0,0 +1,15 @@ +[Unit] +Description=Cig CS5435-54P Platform miscellaneous service +After=cs5435-platform-init.service +DefaultDependencies=no + +[Service] +ExecStart=/usr/local/bin/cig_cs5435_misc.py +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/setup.py b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/setup.py new file mode 100755 index 000000000000..1d4fa7f36452 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='cs5435-54p', + version='1.0.0', + description='Module to initialize Cig CS5435-54P platforms', + + packages=['cs5435-54p'], + package_dir={'cs5435-54p': 'cs5435-54p/classes'}, + ) diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_misc.py b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_misc.py new file mode 100755 index 000000000000..0a78085fd49b --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_misc.py @@ -0,0 +1,574 @@ +#!/usr/bin/env python +# +# Copyright (C) 2018 Cambridge, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import os +import commands +import sys, getopt +import logging +import re +import time +import datetime +from collections import namedtuple +from threading import Thread + +DEBUG = False +i2c_prefix = '/sys/bus/i2c/devices/' +leds_prefix = '/sys/devices/platform/cs5435_54p_led/leds/' +fans_prefix = '/sys/devices/platform/cs5435_54p_fan/' +fansdir_prefix = fans_prefix + 'fan{}_direction' + +ageing_controlfile = '/etc/sonic/agcontrol' +AGFlag = 0 + + +platform_misc_log = '/var/log/platform_misc.log' +misclogger = logging.getLogger('platform_misc') +misclogger.setLevel(logging.INFO) +miscformatter = logging.Formatter('%(asctime)s-%(levelname)s-%(message)s') + +if not os.path.isfile(platform_misc_log): + try: + os.mknod(platform_misc_log) + except: + print 'Failed to creat platform_misc.log' + +fileHandler = logging.FileHandler(platform_misc_log) +fileHandler.setLevel(logging.INFO) +fileHandler.setFormatter(miscformatter) +misclogger.addHandler(fileHandler) + + +starttime = datetime.datetime.now() +IsGetlswt = 0 +coretemp_prefix = '/sys/class/hwmon/hwmon1/' +coretemp_ps = [] +psu1_p = '/sys/bus/i2c/devices/5-005a/psu_present' +psu2_p = '/sys/bus/i2c/devices/5-005b/psu_present' +psu1_d = '/sys/bus/i2c/devices/5-0052/psu_eeprom' +psu2_d = '/sys/bus/i2c/devices/5-0053/psu_eeprom' +psu1led_d = leds_prefix + 'cs5435_54p_led::psu1/brightness' +psu2led_d = leds_prefix + 'cs5435_54p_led::psu2/brightness' +cs5435_ledpath = {'fan':leds_prefix + 'cs5435_54p_led::fan/brightness', + 'fan1':leds_prefix + 'cs5435_54p_led::fan1/brightness', + 'fan2':leds_prefix + 'cs5435_54p_led::fan2/brightness', + 'fan3':leds_prefix + 'cs5435_54p_led::fan3/brightness', + 'fan4':leds_prefix + 'cs5435_54p_led::fan4/brightness', + 'fan5':leds_prefix + 'cs5435_54p_led::fan5/brightness', + 'psu1':leds_prefix + 'cs5435_54p_led::psu1/brightness', + 'psu2':leds_prefix + 'cs5435_54p_led::psu2/brightness', + 'sys':leds_prefix + 'cs5435_54p_led::sys/brightness'} + + +def system_read_filestr(node): + with open(node, 'r') as f: + try: + str = f.read() + except IOError as e: + misclogger.error('Failed to get node, str={}'.format(node)) + return "0" + return str + + +def system_bright_leds(dev, colour): + global AGFlag + + if AGFlag == 1: + return + + cmd = 'echo {} > {}'.format(colour, dev) + log_os_system(cmd, 1) + return + +''' +1: front in tail out +0: front out tail in +''' +def system_getpsu_direction(dev): + try: + with open(dev) as f: + f.seek(0x30) + str = f.read(2) + except IOError as e: + misclogger.error('Failed to get psu eep') + return 1 + if str == 'AA': ## front in tail out + return 1 + elif str == 'RA':## tail in front out + return 0 + else: + misclogger.error('Failed to get psu eep, str={}'.format(str)) + return -1 + + +def system_get_cputype(): + cmdretfd = os.popen("lscpu | grep 'Model name'") + retstring = cmdretfd.read() + endindex = retstring.find('@') - 1 + startindex = retstring[:endindex].rfind(' ') + 1 + cputype = retstring[startindex:endindex] + + return cputype + + +def system_init_coretemppath(): + global coretemp_ps + + cmdstr = "ls {} | grep 'input'".format(coretemp_prefix) + cmdretfd = os.popen(cmdstr) + + coretemppss = cmdretfd.read().splitlines() + if len(coretemppss) < 3: + cputype = system_get_cputype() + misclogger.error('Failed to init core temperature path.' + ' cpu type = {}, num thermal = {}'.format(cputype, len(coretemp_ps))) + return 1 + + for i in range(0,3): + coretemp_ps.append(coretemp_prefix + coretemppss[i]) + + print coretemp_ps + + return 0 + + +class cs5435_fanattr: + def __init__(self, name): + self.name = name + self.direction = 0 + self.direction_p = '' + self.rear = 0 + self.rear_p = '' + self.front = 0 + self.front_p = '' + self.fault = 0 + self.fault_p = '' + self.status = 0 + self.setpath() + self.updatedevice() + + return + + def setpath(self): + self.direction_p = fans_prefix + '{}_direction'.format(self.name) + self.rear_p = fans_prefix + '{}_rear_speed_rpm'.format(self.name) + self.front_p = fans_prefix + '{}_front_speed_rpm'.format(self.name) + self.fault_p = fans_prefix + '{}_fault'.format(self.name) + + return + + def updatedevice(self): + self.direction = int(system_read_filestr(self.direction_p)) + self.rear = int(system_read_filestr(self.rear_p)) + self.front = int(system_read_filestr(self.front_p)) + self.fault = int(system_read_filestr(self.fault_p)) + + return + + def checkspeedrpm(self, speedrpm): + frontrpmexp = speedrpm * 21000 / 100 + rearrpmexp = speedrpm * 19000 / 100 + deviationfront = abs(frontrpmexp - self.front) / float(frontrpmexp) + deviationrear = abs(rearrpmexp - self.rear) / float(rearrpmexp) + + if deviationfront < 0.3 and deviationrear < 0.3: + return 0 + else: + misclogger.error(':{} speed wrong. frontexp is {}, but rpm is {}.rearexp is {}, but rpm is {}'.format(self.name, frontrpmexp, self.front, rearrpmexp, self.rear)) + return 1 + + def checkstatus(self, speedrpm, totaldirct): + speedstatus = self.checkspeedrpm(speedrpm) + if self.direction != totaldirct: + self.status = 1 + misclogger.error(':{} direction = {}.fan direction is not ok.'.format(self.name, self.direction)) + elif speedstatus != 0: + self.status = 1 + elif self.fault != 0: + misclogger.error(':{} fault.'.format(self.name)) + self.status = 1 + else: + self.status = 0 + + if self.status == 1: + system_bright_leds(cs5435_ledpath[self.name], 3) + else: + system_bright_leds(cs5435_ledpath[self.name], 1) + + return self.status + +cs5435_fanattrnodes = [] + + +class cs5435_psuattr: + def __init__(self, name): + self.name = name + self.direction = 0 + self.direction_p = '' + self.present = 0 + self.present_p = '' + self.status = 0 + + self.setpath() + self.updatepresent() + self.updatedirection() + + return + + def setpath(self): + if self.name == 'psu1': + self.present_p = psu1_p + self.direction_p = psu1_d + if self.name == 'psu2': + self.present_p = psu2_p + self.direction_p = psu2_d + + return + + def updatepresent(self): + self.present = int(system_read_filestr(self.present_p)) + + return + + def updatedirection(self): + if self.present == 1: + self.direction = system_getpsu_direction(self.direction_p) + else: + self.direction = 2 + + return + + def checkstatus(self, totaldirct): + if self.present != 1: + self.status = 1 + misclogger.error(':{} not present.'.format(self.name)) + elif self.direction == 2: + self.status = 0 + misclogger.info(':{} direction need to be update.'.format(self.name)) + elif self.direction != totaldirct: + self.status = 1 + misclogger.info(':{} direction is wrong.'.format(self.name)) + else: + self.status = 0 + + if self.status == 1: + system_bright_leds(cs5435_ledpath[self.name], 3) + else: + system_bright_leds(cs5435_ledpath[self.name], 1) + + return self.status + +cs5435_psuattrnodes = [] + + + +def my_log(txt): + if DEBUG == True: + print "[ROY]"+txt + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"5-005a", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"5-005b", 0) + ret3, log = log_os_system("ls "+leds_prefix+"cs5435_54p_led*", 0) + return not(ret1 or ret2 or ret3) + + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + + +def system_get_coretemp(): + temp1 = system_read_filestr(coretemp_ps[0]).strip() + temp2 = system_read_filestr(coretemp_ps[1]).strip() + temp3 = system_read_filestr(coretemp_ps[2]).strip() + + return int(temp1), int(temp2), int(temp3) + +def system_get_boardtemp(): + for i in range(0,16): + temp1path = "/sys/bus/i2c/devices/5-004a/hwmon/hwmon%d/temp1_input" % i + if os.access(temp1path, os.F_OK): + break + for i in range(0,16): + temp2path = "/sys/bus/i2c/devices/5-004b/hwmon/hwmon%d/temp1_input" % i + if os.access(temp2path, os.F_OK): + break + temp1 = system_read_filestr(temp1path).strip() + temp2 = system_read_filestr(temp2path).strip() + + return int(temp1), int(temp2) + + +def system_get_lswtemp(): + global IsGetlswt + global starttime + if IsGetlswt == 0: + now = datetime.datetime.now() + misclogger.info("time wait.") + misclogger.info("start = {}, now = {}.".format(starttime, now)) + if (now - starttime).seconds > 150: + misclogger.info("time = ".format((now - starttime).seconds)) + IsGetlswt = 1 + + return 25 + +# chp = subprocess.Popen("docker ps --filter name=syncd", shell=True, stdout=subprocess.PIPE) +# if chp.poll() == None: +# misclogger.info("No subp.") +# chp.kill() +# +# return 25 + +# retstring = chp.stdout.read() +# chp.kill() +# if 'Up' not in retstring: +# misclogger.info("lsw not up.") +# +# return 25 + + status, output = log_os_system('npx_diag swc show temperature', 1) + if status: + misclogger.error('failed to show lsw temperature') + + return 25 + + output = output.strip() + if output.find("it 0, temperature ") > 0: + startindex = output.find('temperature') + len('temperature') + 1 + endindex = output[startindex:].find(" ") + endindex = startindex + endindex + temp = output[startindex:endindex] + b = temp.find('.') + if b > 0: + temp=temp[:b] + temp = int(temp) + else: + misclogger.error("Failed to get temperature.") + temp = 0 + + return int(temp) + +def system_monitor_temperature(): + + ctemp1, ctemp2, ctemp3 = system_get_coretemp() + btemp1, btemp2 = system_get_boardtemp() + ltemp = system_get_lswtemp() + fan_speed_str = system_cs5435_getfanexspeed() + fan_speed = int(fan_speed_str) + policy = 'stay' + pos = 0 + #speed c1 c2 c3 b1 b2 lsw + fan_policy_up = ([30, 40000, 40000, 40000, 42000, 35000, 95], + [40, 44000, 44000, 44000, 44000, 39000, 96], + [50, 49000, 49000, 49000, 47000, 44000, 91], + [60, 52000, 52000, 52000, 51500, 47500, 92], + [70, 53000, 53000, 53000, 52000, 49000, 93], + [100,999999,999999,999999,999999,999999,999]) + + fan_policy_down=([30, 0, 0, 0, 0, 0, 0], + [40, 34000, 34000, 34000, 34000, 30000, 80], + [50, 38000, 38000, 38000, 37000, 33000, 81], + [60, 44000, 44000, 44000, 43000, 39000, 84], + [70, 44000, 44000, 44000, 43000, 40000, 84], + [100, 48000, 48000, 48000, 46000, 42000, 85],) + + for policytable in fan_policy_up: + if fan_speed <= policytable[0]: + break + pos = pos + 1 + fan_speed = policytable[0] + if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]): + policy = 'stay' + policytable = fan_policy_down[pos] + if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]): + policy = 'down' + else: + policy = 'up' + + if policy == 'up': + misclogger.info("speed = %d." % fan_speed) + misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3)) + misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2)) + misclogger.info("lsw = %d" % ltemp) + fan_speed = fan_policy_down[pos + 1][0] + misclogger.info("fan policy: up. speedexp = {}".format(fan_speed)) + + if policy == 'stay': + fan_speed = fan_policy_down[pos] + return + + if policy == 'down': + misclogger.info("speed = %d." % fan_speed) + misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3)) + misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2)) + misclogger.info("lsw = %d" % ltemp) + fan_speed = fan_policy_down[pos - 1][0] + misclogger.info("fan policy: down.speedexp = {}".format(fan_speed)) + + cmd = "echo %d > /sys/devices/platform/cs5435_54p_fan/fan_duty_cycle_percentage" % fan_speed + status, output = log_os_system(cmd, 1) + if status: + misclogger.error("set fan speed fault") + + return + + +def system_cs5435_setfanexspeed(num): + fanspeednode = fans_prefix + 'fan_duty_cycle_percentage' + numstr = str(num) + with open(fanspeednode, 'w') as f: + f.write(numstr) + + +def system_cs5435_getfanexspeed(): + fanspeednode = fans_prefix + 'fan_duty_cycle_percentage' + fanspeedstr = system_read_filestr(fanspeednode) + fanspeedexp = int(fanspeedstr) + + return fanspeedexp + + +def system_cs5435_getdirection(): + global cs5435_fanattrnodes + direction = 0 + + for fan in cs5435_fanattrnodes: + direction = direction + fan.direction + + if direction > 2: + direction = 1 + else: + direction = 0 + + return direction + + +def system_check_psusdirection(): + global cs5435_psuattrnodes + cs5435totaldirct = system_cs5435_getdirection() + psutatus = 0 + + for psu in cs5435_psuattrnodes: + psu.updatedirection() + psu.checkstatus(cs5435totaldirct) + psutatus = psu.status + psutatus + + return (psutatus != 0) + + +def system_check_psuspresent(): + global cs5435_psuattrnodes + cs5435totaldirct = system_cs5435_getdirection() + psutatus = 0 + + for psu in cs5435_psuattrnodes: + psu.updatepresent() + psu.checkstatus(cs5435totaldirct) + psutatus = psu.status + psutatus + + return (psutatus != 0) + + +def system_check_fansstate(): + global cs5435_fanattrnodes + global cs5435_ledpath + cs5435totaldirct = system_cs5435_getdirection() + fanstatus = 0 + fanexspeed = 0 + + fanexspeed = system_cs5435_getfanexspeed() + + for fan in cs5435_fanattrnodes: + fan.updatedevice() + fan.checkstatus(fanexspeed, cs5435totaldirct) + fanstatus = fanstatus + fan.status + + if fanstatus > 0: + misclogger.error(':fan error.set fans speed 100.') + system_cs5435_setfanexspeed(100) + system_bright_leds(cs5435_ledpath['fan'], 3) + else: + system_bright_leds(cs5435_ledpath['fan'], 1) + + return (fanstatus != 0) + + +def system_misc_polling(threadName,delay): + for count in range(1,5): + if device_exist() == False: + time.sleep(delay+3) + print "%s: %s, count=%d" % ( threadName, time.ctime(time.time()), count) + else: + break + + if count == 4: + return + + status, output = log_os_system("echo 1 > /sys/devices/platform/cs5435_54p_led/leds/cs5435_54p_led::sys/brightness", 1) + status, output = log_os_system("hwconfig -cfp 1", 1) + + global AGFlag + if os.access(ageing_controlfile, os.F_OK): + AGFlag = 1 + else: + AGFlag = 0 + + os.system('csw_daemon &') + + + global cs5435_fanattrnodes + global cs5435_psuattrnodes + + for num in range(1,6): + name = 'fan{}'.format(num) + fannode = cs5435_fanattr(name) + cs5435_fanattrnodes.append(fannode) + for num in range(1,3): + name = 'psu{}'.format(num) + psunode = cs5435_psuattr(name) + cs5435_psuattrnodes.append(psunode) + + tempcontrol = system_init_coretemppath() + + misclogger.info("%s: %s misc start." % ( threadName, time.ctime(time.time()))) + count = 0 + while 1: + count = count + 1 + ret = system_check_psuspresent() + ret = system_check_fansstate() + + if count % 10 == 0: + misclogger.info(": adjust fans and check psu direction.") + system_check_psusdirection() + if tempcontrol == 0: + system_monitor_temperature() + count = 0 + time.sleep(delay) + + return + +if __name__ == '__main__': + target=system_misc_polling("Thread-misc",10) + diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_util.py b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_util.py new file mode 100755 index 000000000000..03302592257c --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_util.py @@ -0,0 +1,563 @@ +#!/usr/bin/env python +# +# Copyright (C) 2018 Cambridge, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +from collections import namedtuple + + + + +PROJECT_NAME = 'cs5435_54p' +version = '0.1.1' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +DEVICE_NO = {'led':9, 'fan':5, 'thermal':4, 'psu':2, 'sfp':54} +FORCE = 0 +CPU_TYPE = 'C3308' + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + device_traversal() + elif arg == 'sff': + if len(args)!=2: + show_eeprom_help() + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + show_eeprom_help() + else: + show_eeprom(args[1]) + return + elif arg == 'set': + if len(args)<3: + show_set_help() + else: + set_device(args[1:]) + return + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_set_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print cmd +" [led|sfp|fan]" + print " use \""+ cmd + " led 0-4 \" to set led color" + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-54 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + +def show_eeprom_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print " use \""+ cmd + " 1-54 \" to dump sfp# eeprom" + sys.exit(0) + +def my_log(txt): + if DEBUG == True: + print "[ROY]"+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_check(): + for count in range(1,5): + time.sleep(1) + ret, lsmod = log_os_system("lsmod| grep i2c_i801", 0) + if len(lsmod) > 2: + log_os_system("rmmod i2c_i801", 0) + break + + ret, lsmod = log_os_system("lsmod| grep i2c_designware_platform", 0) + if len(lsmod) > 2: + log_os_system("rmmod i2c_designware_platform", 0) + log_os_system("modprobe i2c-designware-platform", 0) + + ret, lsmod = log_os_system("lsmod| grep cig", 0) + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + return True + + + +kos = [ + 'depmod', + 'modprobe i2c_dev', + 'modprobe i2c_mux_pca954x force_deselect_on_exit=1', + 'modprobe x86-64-cig-cs5435-54p-sysfs ' , + 'modprobe x86-64-cig-cs5435-54p-cpld ' , + 'modprobe x86-64-cig-cs5435-54p-fan' , + 'modprobe x86-64-cig-cs5435-54p-psu' , + 'modprobe x86-64-cig-cs5435-54p-sfp' , + 'modprobe x86-64-cig-cs5435-54p-led' ] + +def driver_install(): + global FORCE + + for i in range(0,len(kos)): + if i == 4: + ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 32-39 | head -n 1", 0) + if CPU_TYPE=='i3-6100U': + kos[i] =kos[i] + 'board_id=1' + ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 36-40 | head -n 1", 0) + if CPU_TYPE=='C3758' or CPU_TYPE=='C3308': + kos[i] =kos[i] + 'board_id=2' + + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + +def driver_uninstall(): + global FORCE + for i in range(0,len(kos)): + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + +led_prefix ='/sys/class/leds/'+PROJECT_NAME+'_led::' +hwmon_types = {'led': ['sys','fan','fan1','fan2','fan3','fan4','fan5','psu1','psu2']} +hwmon_nodes = {'led': ['brightness'] } +hwmon_prefix ={'led': led_prefix} + +i2c_prefix = '/sys/bus/i2c/devices/' +i2c_bus = {'thermal': ['4-0048','4-0049', '5-004a', '5-004b'] , + 'psu': ['5-005a','5-005b'], + 'sfp': ['-0050']} +i2c_nodes = {'thermal': ['hwmon/hwmon*/temp1_input'] , + 'psu': ['psu_present ', 'psu_power_good'] , + 'sfp': ['sfp_is_present ', 'sfp_tx_disable']} + +fan_prefix ='/sys/bus/platform/devices/'+PROJECT_NAME+'_fan' +fan_types = {'fan': ['fan1','fan2', 'fan3', 'fan4', 'fan5']} +fan_nodes = {'fan': ['state', 'front_speed_rpm', 'rear_speed_rpm', 'fault']} + + +sfp_map = [8,9,10,11,12,13,14,15,16, + 17,18,19,20,21,22,23,24,25,26, + 27,28,29,30,31,32,33,34,35,36, + 37,38,39,40,41,42,43,44,45,46, + 47,48,49,50,51,52,53,54,55,56, + 57,60,61,62,63] + +mknod =[ + 'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-4/new_device', + 'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-4/new_device', + 'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs5435_54p_psu1 0x5a > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs5435_54p_psu2 0x5b > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs5435_54p_psu1 0x52 > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs5435_54p_psu2 0x53 > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo 24c128 0x57 > /sys/bus/i2c/devices/i2c-7/new_device'] + +port = 0 + +def device_install(): + global FORCE + global port + for i in range(0,len(mknod)): + #all nodes need times to built new i2c buses + time.sleep(1) + + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + + for i in range(0,len(sfp_map)): + if (i == 50): + port = port + 3 + else: + port = port + 1 + + + status, output =log_os_system("echo cs5435_54p_sfp"+str(port)+" 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + + if port <= 48: + status, output =log_os_system("echo cs5435_54p_sfp"+str(port)+" 0x51 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + + return + +def device_uninstall(): + global FORCE + + for i in range(0,len(sfp_map)): + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" + status, output =log_os_system("echo 0x50 > "+ target, 1) + if status: + print output + if FORCE == 0: + return status + + nodelist = mknod + + for i in range(len(nodelist)): + target = nodelist[-(i+1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + if status: + print output + if FORCE == 0: + return status + + return + +def system_ready(): + if driver_check() == False: + return False + if not device_exist(): + return False + return True + +def do_install(): + print "Checking system...." + if driver_check() == False: + print "No driver, installing...." + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" drivers detected...." + if not device_exist(): + print "No device, installing...." + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" devices detected...." + return + +def do_uninstall(): + print "Checking system...." + if not device_exist(): + print PROJECT_NAME.upper() +" has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_check()== False : + print PROJECT_NAME.upper() +" has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + +def devices_info(): + global DEVICE_NO + global ALL_DEVICE + global i2c_bus, hwmon_types, fan_types + for key in DEVICE_NO: + ALL_DEVICE[key]= {} + for i in range(0,DEVICE_NO[key]): + ALL_DEVICE[key][key+str(i+1)] = [] + + for key in i2c_bus: + buses = i2c_bus[key] + nodes = i2c_nodes[key] + for i in range(0,len(buses)): + for j in range(0,len(nodes)): + if 'sfp' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + else: + node = key+str(i+1) + path = i2c_prefix+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + + for key in hwmon_types: + itypes = hwmon_types[key] + nodes = hwmon_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + for key in fan_types: + itypes = fan_types[key] + nodes = fan_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = fan_prefix+"/"+ itypes[i]+"_"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + #show dict all in the order + if DEBUG == True: + for i in sorted(ALL_DEVICE.keys()): + print(i+": ") + for j in sorted(ALL_DEVICE[i].keys()): + print(" "+j) + for k in (ALL_DEVICE[i][j]): + print(" "+" "+k) + return + +def show_eeprom(index): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] + node = node.replace(node.split("/")[-1], 'sfp_eeprom') + # check if got hexdump command in current environment + ret, log = log_os_system("which hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) + if len(log): + hex_cmd = 'hexdump' + elif len(log2): + hex_cmd = ' busybox hexdump' + else: + log = 'Failed : no hexdump cmd!!' + logging.info(log) + print log + return 1 + + print node + ":" + ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) + if ret==0: + print log + else: + print "**********device no found**********" + return + +def set_device(args): + global DEVICE_NO + global ALL_DEVICE + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + + if args[0]=='led': + if int(args[1])>4: + show_set_help() + return + #print ALL_DEVICE['led'] + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): + ret, log = log_os_system("echo "+args[1]+" >"+k, 1) + if ret: + return ret + elif args[0]=='fan': + if int(args[1])>100: + show_set_help() + return + #print ALL_DEVICE['fan'] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan'] ['fan1'][0] + node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage') + ret, log = log_os_system("cat "+ node, 1) + if ret==0: + print ("Previous fan duty: " + log.strip() +"%") + ret, log = log_os_system("echo "+args[1]+" >"+node, 1) + if ret==0: + print ("Current fan duty: " + args[1] +"%") + return ret + elif args[0]=='sfp': + if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: + show_set_help() + return + if len(args)<2: + show_set_help() + return + + if int(args[2])>1: + show_set_help() + return + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: + ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) + if ret: + return ret + + return + +def get_value(input): + digit = re.findall('\d+', input) + return int(digit[0]) + + +def get_ledname(ledx): + name_table={'led1':'SYS','led2':'FSTUS','led3':'FAN1','led4':'FAN2','led5':'FAN3','led6':'FAN4','led7':'FAN5','led8':'PSU1','led9':'PSU2'} + if name_table.has_key(ledx): + name = name_table[ledx] + else: + name = ledx + return name + + +def device_traversal(): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + for i in sorted(ALL_DEVICE.keys()): + print("============================================") + print(i.upper()+": ") + print("============================================") + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + nwnamex = get_ledname(j) + if nwnamex == j: + print " "+j+":", + else: + print " "+nwnamex+":", + for k in (ALL_DEVICE[i][j]): + ret, log = log_os_system("cat "+k, 0) + func = k.split("/")[-1].strip() + func = re.sub(j+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) + if ret==0: + print func+"="+log+" ", + else: + print func+"="+"X"+" ", + print + print("----------------------------------------------------------------") + + + print + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"*0077", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"i2c-3", 0) + return not(ret1 or ret2) + + +if __name__ == "__main__": + main() diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/__init__.py b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/__init__.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/fanutil.py b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/fanutil.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/thermalutil.py b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/thermalutil.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/Makefile b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/Makefile new file mode 100644 index 000000000000..e37e985a2147 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/Makefile @@ -0,0 +1,6 @@ +obj-m :=x86-64-cig-cs6436-54p-sysfs.o \ + x86-64-cig-cs6436-54p-cpld.o \ + x86-64-cig-cs6436-54p-fan.o \ + x86-64-cig-cs6436-54p-led.o \ + x86-64-cig-cs6436-54p-psu.o \ + x86-64-cig-cs6436-54p-sfp.o diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/i2c-algo-lpc.h b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/i2c-algo-lpc.h new file mode 100644 index 000000000000..749aa94ef934 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/i2c-algo-lpc.h @@ -0,0 +1,222 @@ +/* -------------------------------------------------------------------- + + * A hwmon driver for the CIG cs6436-54P + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* -------------------------------------------------------------------- */ + +#ifndef I2C_LPC_H +#define I2C_LPC_H 1 + +/* ----- Control register bits ---------------------------------------- */ +#define I2C_LPC_PIN 0x80 +#define I2C_LPC_ESO 0x40 +#define I2C_LPC_ES1 0x20 +#define I2C_LPC_ES2 0x10 +#define I2C_LPC_ENI 0x08 + +#define I2C_LPC_STO 0x40 +#define I2C_LPC_ACK 0x01 + +/*command register*/ +#define I2C_LPC_STA 0x80 +#define I2C_LPC_ABT 0x40 + +/*status register*/ +#define I2C_LPC_TBE 0x02 +#define I2C_LPC_IBB 0x80 +#define I2C_LPC_RBF 0x01 +#define I2C_LPC_TD 0x08 + +#define I2C_LPC_START I2C_LPC_STA +#define I2C_LPC_STOP I2C_LPC_STO +#define I2C_LPC_REPSTART I2C_LPC_STA +#define I2C_LPC_IDLE + +/* ----- Status register bits ----------------------------------------- */ +/*#define I2C_LPC_PIN 0x80 as above*/ + +#define I2C_LPC_INI 0x40 /* 1 if not initialized */ +#define I2C_LPC_STS 0x20 +#define I2C_LPC_BER 0x10 +#define I2C_LPC_AD0 0x08 +#define I2C_LPC_LRB 0x08 +#define I2C_LPC_AAS 0x04 +#define I2C_LPC_LAB 0x02 +#define I2C_LPC_BB 0x80 + +/* ----- Chip clock frequencies --------------------------------------- */ +#define I2C_LPC_CLK3 0x00 +#define I2C_LPC_CLK443 0x10 +#define I2C_LPC_CLK6 0x14 +#define I2C_LPC_CLK 0x18 +#define I2C_LPC_CLK12 0x1c + +/* ----- transmission frequencies ------------------------------------- */ +#define I2C_LPC_TRNS90 0x00 /* 90 kHz */ +#define I2C_LPC_TRNS45 0x01 /* 45 kHz */ +#define I2C_LPC_TRNS11 0x02 /* 11 kHz */ +#define I2C_LPC_TRNS15 0x03 /* 1.5 kHz */ + + +#define I2C_LPC_OWNADR 0 +#define I2C_LPC_INTREG I2C_LPC_ES2 +#define I2C_LPC_CLKREG I2C_LPC_ES1 + +#define I2C_LPC_REG_TEST 0x01 +#define I2C_LPC_REG_BUS_SEL 0x80 +#define I2C_LPC_REG_DEVICE_ADDR 0x81 +#define I2C_LPC_REG_BYTE_COUNT 0x83 +#define I2C_LPC_REG_COMMAND 0x84 +#define I2C_LPC_REG_STATUS 0x85 +#define I2C_LPC_REG_DATA_RX1 0x86 +#define I2C_LPC_REG_DATA_RX2 0x87 +#define I2C_LPC_REG_DATA_RX3 0x88 +#define I2C_LPC_REG_DATA_RX4 0x89 +#define I2C_LPC_REG_DATA_TX1 0x8a +#define I2C_LPC_REG_DATA_TX2 0x8b +#define I2C_LPC_REG_DATA_TX3 0x8c +#define I2C_LPC_REG_DATA_TX4 0x8d + + +#define ADDR_REG_SFP_STATUS_ADDR 0X62 //reg addr +R/W# //1031 +#define ADDR_REG_SFP_STATUS_TX 0X63 // write data +#define ADDR_REG_SFP_STATUS_RX 0X64 //read data +#define ADDR_REG_SFP_STATUS_COMMAND 0X65 //cmd bit7=1,go +#define ADDR_REG_SFP_STATUS_STATUS 0X66 //status + +#define CPLD_MASTER_INTERRUPT_STATUS_REG 0x20 +#define CPLD_MASTER_INTERRUPT_MASK_REG 0x21 +#define CPLD_MASTER_INTERRUPT_ALL 0x3f +#define CPLD_MASTER_INTERRUPT_CPLD2 0x20 +#define CPLD_MASTER_INTERRUPT_CPLD1 0x10 +#define CPLD_MASTER_INTERRUPT_PSU2 0x08 +#define CPLD_MASTER_INTERRUPT_PSU1 0x04 +#define CPLD_MASTER_INTERRUPT_6320 0x02 +#define CPLD_MASTER_INTERRUPT_LSW 0x01 + + + +#define CPLD_SLAVE1_INTERRUPT_STATUS_L_REG 0x20 +#define CPLD_SLAVE1_INTERRUPT_STATUS_H_REG 0x21 +#define CPLD_SLAVE2_INTERRUPT_STATUS_L_REG 0x22 +#define CPLD_SLAVE2_INTERRUPT_STATUS_H_REG 0x23 +#define CPLD_SLAVE1_INTERRUPT_MASK_REG 0x24 +#define CPLD_SLAVE2_INTERRUPT_MASK_REG 0x25 + + +#define CPLD_SLAVE1_PRESENT08_REG 0x01 +#define CPLD_SLAVE1_PRESENT16_REG 0x02 +#define CPLD_SLAVE1_PRESENT24_REG 0x03 +#define CPLD_SLAVE2_PRESENT32_REG 0x04 +#define CPLD_SLAVE2_PRESENT40_REG 0x05 +#define CPLD_SLAVE2_PRESENT48_REG 0x06 + +#define CPLD_SLAVE1_RX_LOST08_REG 0x07 +#define CPLD_SLAVE1_RX_LOST16_REG 0x08 +#define CPLD_SLAVE1_RX_LOST24_REG 0x09 +#define CPLD_SLAVE2_RX_LOST32_REG 0x0a +#define CPLD_SLAVE2_RX_LOST40_REG 0x0b +#define CPLD_SLAVE2_RX_LOST48_REG 0x0c + +#define CPLD_SLAVE1_TX_FAULT08_REG 0x0d +#define CPLD_SLAVE1_TX_FAULT16_REG 0x0e +#define CPLD_SLAVE1_TX_FAULT24_REG 0x0f +#define CPLD_SLAVE2_TX_FAULT32_REG 0x10 +#define CPLD_SLAVE2_TX_FAULT40_REG 0x11 +#define CPLD_SLAVE2_TX_FAULT48_REG 0x12 + +#define CPLD_SLAVE2_PRESENT56_REG 0x19 +#define CPLD_SLAVE2_QSFP_CR56_REG 0x1a + + +#define CPLD_SLAVE1_INTERRUPT_PRESENT08 0x0001 +#define CPLD_SLAVE1_INTERRUPT_PRESENT16 0x0002 +#define CPLD_SLAVE1_INTERRUPT_PRESENT24 0x0004 +#define CPLD_SLAVE2_INTERRUPT_PRESENT32 0x0001 +#define CPLD_SLAVE2_INTERRUPT_PRESENT40 0x0002 +#define CPLD_SLAVE2_INTERRUPT_PRESENT48 0x0004 + +#define CPLD_SLAVE2_INTERRUPT_QSFP_CR56 0x0200 +#define CPLD_SLAVE2_INTERRUPT_PRESENT56 0x0400 + +#define CPLD_SLAVE1_INTERRUPT_RX_LOST08 0x0008 +#define CPLD_SLAVE1_INTERRUPT_RX_LOST16 0x0010 +#define CPLD_SLAVE1_INTERRUPT_RX_LOST24 0x0020 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST32 0x0008 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST40 0x0010 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST48 0x0020 + +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT08 0x0040 +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT16 0x0080 +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT24 0x0100 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT32 0x0040 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT40 0x0080 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT48 0x0100 + + + + + + + +#define WAIT_TIME_OUT_COUNT 100 + + +struct i2c_algo_lpc_data { + void *data; /* private data for lolevel routines */ + void (*setlpc) (void *data, int ctl, int val); + int (*getlpc) (void *data, int ctl); + int (*getown) (void *data); + int (*getclock) (void *data); + void (*waitforpin) (void *data); + + int (*xfer_begin) (void *data); + int (*xfer_end) (void *data); + + /* Multi-master lost arbitration back-off delay (msecs) + * This should be set by the bus adapter or knowledgable client + * if bus is multi-mastered, else zero + */ + unsigned long lab_mdelay; +}; + + +struct subsys_private { + struct kset subsys; + struct kset *devices_kset; + struct list_head interfaces; + struct mutex mutex; + + struct kset *drivers_kset; + struct klist klist_devices; + struct klist klist_drivers; + struct blocking_notifier_head bus_notifier; + unsigned int drivers_autoprobe:1; + struct bus_type *bus; + + struct kset glue_dirs; + struct class *class; +}; + +void cs6436_54p_sysfs_add_client(struct i2c_client *client); +void cs6436_54p_sysfs_remove_client(struct i2c_client *client); + + +#endif /* I2C_LPC8584_H */ diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-cpld.c b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-cpld.c new file mode 100644 index 000000000000..1c7930b3d268 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-cpld.c @@ -0,0 +1,2202 @@ +/* + * A hwmon driver for the CIG cs6436-54P CPLD + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "i2c-algo-lpc.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef CPLD_USER +# include +#else +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + + + + + +/********************************************** Start ********************************************************/ + +/* + * ISA bus. + */ + +static void platform_isa_bus_release(struct device * dev) +{ + return ; +} + + +static struct device isa_bus = { + .init_name = "lpc-isa", + .release = platform_isa_bus_release, +}; + +struct isa_dev { + struct device dev; + struct device *next; + unsigned int id; +}; + +#define to_isa_dev(x) container_of((x), struct isa_dev, dev) + +static int isa_bus_match(struct device *dev, struct device_driver *driver) +{ + struct isa_driver *isa_driver = to_isa_driver(driver); + + if (dev->platform_data == isa_driver) { + if (!isa_driver->match || + isa_driver->match(dev, to_isa_dev(dev)->id)) + return 1; + dev->platform_data = NULL; + } + return 0; +} + +static int isa_bus_probe(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->probe) + return isa_driver->probe(dev, to_isa_dev(dev)->id); + + return 0; +} + +static int isa_bus_remove(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->remove) + return isa_driver->remove(dev, to_isa_dev(dev)->id); + + return 0; +} + +static void isa_bus_shutdown(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->shutdown) + isa_driver->shutdown(dev, to_isa_dev(dev)->id); +} + +static int isa_bus_suspend(struct device *dev, pm_message_t state) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->suspend) + return isa_driver->suspend(dev, to_isa_dev(dev)->id, state); + + return 0; +} + +static int isa_bus_resume(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->resume) + return isa_driver->resume(dev, to_isa_dev(dev)->id); + + return 0; +} + +static struct bus_type isa_bus_type = { + .name = "lpc-isa", + .match = isa_bus_match, + .probe = isa_bus_probe, + .remove = isa_bus_remove, + .shutdown = isa_bus_shutdown, + .suspend = isa_bus_suspend, + .resume = isa_bus_resume +}; + +static void isa_dev_release(struct device *dev) +{ + kfree(to_isa_dev(dev)); +} + +void lpc_unregister_driver(struct isa_driver *isa_driver) +{ + struct device *dev = isa_driver->devices; + + while (dev) { + struct device *tmp = to_isa_dev(dev)->next; + device_unregister(dev); + dev = tmp; + } + driver_unregister(&isa_driver->driver); +} + + +int lpc_register_driver(struct isa_driver *isa_driver, unsigned int ndev) +{ + int error; + unsigned int id; + + isa_driver->driver.bus = &isa_bus_type; + isa_driver->devices = NULL; + + error = driver_register(&isa_driver->driver); + if (error) + return error; + + for (id = 0; id < ndev; id++) { + struct isa_dev *isa_dev; + + isa_dev = kzalloc(sizeof *isa_dev, GFP_KERNEL); + if (!isa_dev) { + error = -ENOMEM; + break; + } + + isa_dev->dev.parent = &isa_bus; + isa_dev->dev.bus = &isa_bus_type; + + dev_set_name(&isa_dev->dev, "%s.%u", + isa_driver->driver.name, id); + isa_dev->dev.platform_data = isa_driver; + isa_dev->dev.release = isa_dev_release; + isa_dev->id = id; + + isa_dev->dev.coherent_dma_mask = DMA_BIT_MASK(24); + isa_dev->dev.dma_mask = &isa_dev->dev.coherent_dma_mask; + + error = device_register(&isa_dev->dev); + if (error) { + put_device(&isa_dev->dev); + break; + } + + if (isa_dev->dev.platform_data) { + isa_dev->next = isa_driver->devices; + isa_driver->devices = &isa_dev->dev; + } else + device_unregister(&isa_dev->dev); + } + + if (!error && !isa_driver->devices) + error = -ENODEV; + + if (error) + isa_unregister_driver(isa_driver); + + return error; +} + + +int lpc_bus_init(void) +{ + int error; + + error = bus_register(&isa_bus_type); + if (!error) { + error = device_register(&isa_bus); + if (error) + bus_unregister(&isa_bus_type); + } + return error; +} + +void lpc_bus_exit(void) +{ + + device_unregister(&isa_bus); + + bus_unregister(&isa_bus_type); +} + + +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ +/* + * module parameters: + */ +static int i2c_debug = 0; +static struct mutex lpc_lock; + + +#define DEB2(x) if (i2c_debug == 2) x +#define DEB3(x) if (i2c_debug == 3) x + /* print several statistical values */ +#define DEBPROTO(x) if (i2c_debug == 9) x; + /* debug the protocol by showing transferred bits */ +#define DEF_TIMEOUT 160 + + + +/* setting states on the bus with the right timing: */ + +#define set_lpc(adap, ctl, val) adap->setlpc(adap->data, ctl, val) +#define get_lpc(adap, ctl) adap->getlpc(adap->data, ctl) +#define get_own(adap) adap->getown(adap->data) +#define get_clock(adap) adap->getclock(adap->data) +#define i2c_outaddr(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DEVICE_ADDR, val) + +#define i2c_outbyte1(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX1, val) +#define i2c_outbyte2(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX2, val) +#define i2c_outbyte3(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX3, val) +#define i2c_outbyte4(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX4, val) +#define i2c_inbyte1(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX1) +#define i2c_inbyte2(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX2) +#define i2c_inbyte3(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX3) +#define i2c_inbyte4(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX4) + + + +#define LPC_FPRINTF_LOG_PATH "/tmp/file.log" +struct file *lpc_fprintf_file = NULL; + +static int lpc_fprintf_debug(const char *fmt, ...) +{ + char lpc_fprintf_buf[256]={0}; + struct va_format vaf; + va_list args; + int r; + mm_segment_t old_fs; + struct timeval tv; + struct rtc_time tm; + + do_gettimeofday(&tv); + + rtc_time_to_tm(tv.tv_sec,&tm); + + va_start(args, fmt); + vaf.fmt = fmt; + vaf.va = &args; + r=snprintf(lpc_fprintf_buf,sizeof(lpc_fprintf_buf),"[%04d.%08d] %pV\n",tm.tm_sec, (int)tv.tv_usec, &vaf); + va_end(args); + old_fs = get_fs(); + set_fs(KERNEL_DS); + vfs_write(lpc_fprintf_file, (char *)&lpc_fprintf_buf, strlen(lpc_fprintf_buf), &lpc_fprintf_file->f_pos); + set_fs(old_fs); + memset(lpc_fprintf_buf,0x0,sizeof(lpc_fprintf_buf)); + return r; + +} + + + +static int lpc_fprintf_init(void) +{ + printk("lpc_fprintf_init.\n"); + + if(lpc_fprintf_file == NULL) + lpc_fprintf_file = filp_open(LPC_FPRINTF_LOG_PATH, O_RDWR | O_APPEND | O_CREAT, 0644); + + if (IS_ERR(lpc_fprintf_file)) { + printk("Error occured while opening file %s, exiting...\n", LPC_FPRINTF_LOG_PATH); + return -1; + } + + return 0; +} + +static int lpc_fprintf_exit(void) +{ + printk("lpc_fprintf_exit.\n"); + + if(lpc_fprintf_file != NULL) + filp_close(lpc_fprintf_file, NULL); + + return 0; +} + + +/* other auxiliary functions */ + + +void print_reg(struct i2c_algo_lpc_data *adap) +{ + unsigned char status; + DEBPROTO(lpc_fprintf_debug("================================================\n");) + status = get_lpc(adap, I2C_LPC_REG_BUS_SEL); + DEBPROTO(lpc_fprintf_debug("%s select reg %x : %x\n",__func__,I2C_LPC_REG_BUS_SEL, status);) + status = get_lpc(adap, I2C_LPC_REG_BYTE_COUNT); + DEBPROTO(lpc_fprintf_debug("%s count reg %x : %x\n",__func__,I2C_LPC_REG_BYTE_COUNT, status);) + + status = get_lpc(adap, I2C_LPC_REG_COMMAND); + DEBPROTO(lpc_fprintf_debug("%s command reg %x : %x\n",__func__,I2C_LPC_REG_COMMAND, status);) + status = get_lpc(adap, I2C_LPC_REG_DEVICE_ADDR); + DEBPROTO(lpc_fprintf_debug("%s address reg %x : %x\n",__func__,I2C_LPC_REG_DEVICE_ADDR, status);) + + status = get_lpc(adap, I2C_LPC_REG_STATUS); + DEBPROTO(lpc_fprintf_debug("%s status reg %x : %x\n",__func__,I2C_LPC_REG_STATUS, status);) +} + + + +static void i2c_repstart(struct i2c_algo_lpc_data *adap) +{ + DEBPROTO(lpc_fprintf_debug("%s :\n",__func__);) + set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_REPSTART); +} + +static void i2c_stop(struct i2c_algo_lpc_data *adap) +{ + DEBPROTO(lpc_fprintf_debug("%s :\n",__func__);) + set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_STOP); + udelay(60); + set_lpc(adap, I2C_LPC_REG_COMMAND, 0x00); +} + + + + +static void i2c_start(struct i2c_algo_lpc_data *adap) +{ + print_reg(adap); + + set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_START); + + print_reg(adap); +} + + + + +static int wait_for_bb(struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + int status; + + while (--timeout) { + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus free status : %x\n",__func__,status);) + + if(status == I2C_LPC_TD) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is free status : %x\n",__func__,status);) + break; + } + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout for free busy status : %x\n",__func__,status);) + return -ETIMEDOUT; + } + + + + return 0; +} + + +static int wait_for_be(int mode,struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + unsigned char status; + + + while (--timeout) { + + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus empty status : %x\n",__func__,status);) + + if(mode == 1) + { + if((status & I2C_LPC_IBB) && (status & I2C_LPC_TBE)) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is empty status : %x\n",__func__,status);) + break; + } + } + else + { + if(status & I2C_LPC_TD) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is empty status : %x\n",__func__,status);) + break; + } + } + + status = get_lpc(adap, I2C_LPC_REG_TEST); + + DEBPROTO(lpc_fprintf_debug("%s : The test register data : %x\n",__func__,status);) + udelay(1); /* wait for 100 us */ + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Empty\n",__func__);) + return -ETIMEDOUT; + } + + return 0; +} + + +static int wait_for_bf(struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + int status; + + + while (--timeout) { + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus full status : %x\n",__func__,status);) + + if(status & I2C_LPC_RBF) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is full status : %x\n",__func__,status);) + break; + } + + status = get_lpc(adap, I2C_LPC_REG_TEST); + + DEBPROTO(lpc_fprintf_debug("%s : The test register data : %x\n",__func__,status);) + udelay(1); /* wait for 100 us */ + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Full\n",__func__);) + return -ETIMEDOUT; + } + + return 0; +} + +static int wait_for_td(struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + int status=0; + + while (--timeout) { + udelay(4); + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus done status : %x\n",__func__,status);) + + if(status == I2C_LPC_TD) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is done status : %x\n",__func__,status);) + break; + } + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Done\n",__func__);) + return -ETIMEDOUT; + } + + return 0; +} + + + +static int wait_for_pin(struct i2c_algo_lpc_data *adap, int *status) +{ + int timeout = DEF_TIMEOUT; + *status = get_lpc(adap, I2C_LPC_REG_STATUS); + + while ((*status & I2C_LPC_TBE) && --timeout) { + *status = get_lpc(adap, I2C_LPC_REG_STATUS); + } + + if (timeout == 0) + return -ETIMEDOUT; + + + return 0; +} + + +static int lpc_doAddress(struct i2c_algo_lpc_data *adap,struct i2c_msg *msg) +{ + unsigned short flags = msg->flags; + unsigned char addr; + + addr = msg->addr << 1; + if (flags & I2C_M_RD) + { + addr |= 1; + DEBPROTO(lpc_fprintf_debug("step 7 : read mode then write device address 0x%x\n",addr);) + } + else + { + DEBPROTO(lpc_fprintf_debug("step 2 : write mode then write device address 0x%x\n",addr);) + } + + if (flags & I2C_M_REV_DIR_ADDR) + { + addr ^= 1; + + } + i2c_outaddr(adap, addr); + return 0; + +} + + +static int lpc_sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; + int i = 0,timeout=0; + + unsigned int count = msg->len; + unsigned char *buf = msg->buf; + + do{ + lpc_doAddress(adap,msg); + set_lpc(adap, I2C_LPC_REG_BYTE_COUNT, (count-i) >= 4 ? 4:(count - i)); + DEBPROTO(lpc_fprintf_debug("step 3 : write register count %x\n",count);) + + if((count -i) >= 4) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + i2c_outbyte2(adap, buf[i+1] & 0xff); + i2c_outbyte3(adap, buf[i+2] & 0xff); + i2c_outbyte4(adap, buf[i+3] & 0xff); + + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+2,buf[i+2]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+3,buf[i+3]);) + i += 4; + } + else if((count -i) == 3) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + i2c_outbyte2(adap, buf[i+1] & 0xff); + i2c_outbyte3(adap, buf[i+2] & 0xff); + + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+2,buf[i+2]);) + + i += 3; + } + else if((count -i) == 2) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + i2c_outbyte2(adap, buf[i+1] & 0xff); + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+1,buf[i+1]);) + i += 2; + } + else if((count -i) == 1) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + i += 1; + } + + /* Send START */ + DEBPROTO(lpc_fprintf_debug("step 5-1 : Delay 6mS \n");) + udelay(6000); + DEBPROTO(lpc_fprintf_debug("step 5-2 : Start to transfrom \n");) + i2c_stop(adap); + i2c_start(adap); + DEBPROTO(lpc_fprintf_debug("step 5-3 : Start done\n");) + + udelay(400); + DEBPROTO(lpc_fprintf_debug("step 6 : Waiting for BE\n");) + timeout = wait_for_td(adap); + if (timeout) { + DEBPROTO(lpc_fprintf_debug("step 6 : Timeout waiting for BE \n");) + return -EREMOTEIO; + } + }while (i < count); + + if(i == count) + { + DEBPROTO(lpc_fprintf_debug("Writen %d bytes successd !\n",count);) + return i; + } + else + { + DEBPROTO(lpc_fprintf_debug("Writen %d bytes failed \n",count);) + return -EIO; + } +} + +static int lpc_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + int i=0,timeout=0; + struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; + + unsigned int count = msg->len; + unsigned char *buf = msg->buf; + + do{ + lpc_doAddress(adap,msg); + set_lpc(adap, I2C_LPC_REG_BYTE_COUNT, (count-i) >= 4 ? 4:(count - i)); + DEBPROTO(lpc_fprintf_debug("step 8 : write register count %d\n",count);) + + /* Send START */ + DEBPROTO(lpc_fprintf_debug("step 9-1 : Delay 6mS\n");) + udelay(6000); + DEBPROTO(lpc_fprintf_debug("step 9-2 : Start to receive data\n");) + i2c_stop(adap); + i2c_start(adap); + DEBPROTO(lpc_fprintf_debug("step 9-3 : Start done\n");) + + udelay(400); + DEBPROTO(lpc_fprintf_debug("step 10 : Waiting for TD\n");) + timeout = wait_for_td(adap); + if (timeout) { + DEBPROTO(lpc_fprintf_debug("step 10 : Timeout waiting for TD \n");) + return -EREMOTEIO; + } + + if((count -i) >= 4) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + buf[i+1] = 0xff & i2c_inbyte2(adap); + buf[i+2] = 0xff & i2c_inbyte3(adap); + buf[i+3] = 0xff & i2c_inbyte4(adap); + + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+2,buf[i+2]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+3,buf[i+3]);) + + i += 4; + } + else if((count -i) == 3) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + buf[i+1] = 0xff & i2c_inbyte2(adap); + buf[i+2] = 0xff & i2c_inbyte3(adap); + + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+2,buf[i+2]);) + + i += 3; + } + else if((count -i) == 2) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + buf[i+1] = 0xff & i2c_inbyte2(adap); + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+1,buf[i+1]);) + i += 2; + } + else if((count -i) == 1) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + i += 1; + } + + + }while(i < count); + + if(i == count) + { + DEBPROTO(lpc_fprintf_debug("Read %d bytes successd !\n",count);) + return i; + } + else + { + DEBPROTO(lpc_fprintf_debug("Read %d bytes failed \n",count);) + return -EIO; + } +} + + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; +#define LPC_I2C_MAX_NCHANS 6 + + +struct lpc_iic { + struct i2c_adapter *virt_adaps[LPC_I2C_MAX_NCHANS]; + u8 last_chan; /* last register value */ +}; + + +static int lpc_master_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg *msgs, + int num) +{ + struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; + struct i2c_msg *pmsg; + int i; + int ret=0; + + mutex_lock(&lpc_lock); + + if (adap->xfer_begin) + adap->xfer_begin(&i2c_adap->nr); + + + for (i = 0;ret >= 0 && i < num; i++) { + pmsg = &msgs[i]; + + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n", + pmsg->flags & I2C_M_RD ? "read" : "write", + pmsg->len, pmsg->addr, i + 1, num);) + + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n", + i, msgs[i].addr, msgs[i].flags, msgs[i].len);) + + if (pmsg->flags & I2C_M_RD) { + ret = lpc_readbytes(i2c_adap, pmsg); + + if (ret != pmsg->len) { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: fail: " + "only read %d bytes.\n",ret)); + } else { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: read %d bytes.\n",ret)); + } + } else { + + ret = lpc_sendbytes(i2c_adap, pmsg); + + if (ret != pmsg->len) { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: fail: " + "only wrote %d bytes.\n",ret)); + } else { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: wrote %d bytes.\n",ret)); + } + } + } + + if (adap->xfer_end) + adap->xfer_end(&i2c_adap->nr); + + mutex_unlock(&lpc_lock); + + DEBPROTO(lpc_fprintf_debug("ret = 0x%x num = 0x%x i = 0x%x.\n",ret,num,i)); + + return ret = (ret < 0) ? ret : num; +} + + +static u32 lpc_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_QUICK; +} + +/* exported algorithm data: */ +static const struct i2c_algorithm lpc_algo = { + .master_xfer = lpc_master_xfer, + //.smbus_xfer = lpc_smbus_xfer, + .functionality = lpc_func, +}; + + +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ +#define DEFAULT_BASE 0x0a00 + +static int lpc_base= 0x0a00; +static u8 __iomem *lpc_base_iomem; + +static int lpc_irq; +static int lpc_clock = 0x1c; +static int lpc_own = 0x55; +static int lpc_mmapped; + +static unsigned long lpc_base_addr = 0x0a00; +static unsigned int lpc_io_space_size = 2; + +static unsigned long LPC_INDEX_REG; +static unsigned long LPC_DATA_REG; + + +/* notice : removed static struct i2c_lpc_iic gpi; code - + this module in real supports only one device, due to missing arguments + in some functions, called from the algo-lpc module. Sometimes it's + need to be rewriten - but for now just remove this for simpler reading */ + +static wait_queue_head_t lpc_wait; +static int lpc_pending; +static spinlock_t lock; +static spinlock_t lpc_slock; + +static struct i2c_adapter lpc_iic_ops; + +struct cpld_dev_type { + struct resource *io_resource; + struct semaphore sem; + struct cdev cdev; +}; + +struct cpld_dev_type *cpld_device; + + +/* ----- local functions ---------------------------------------------- */ + +static void lpc_cpld_setbyte(void *data, int ctl, int val) +{ + outb(ctl, LPC_INDEX_REG); + mb(); + + outb(val, LPC_DATA_REG); + mb(); +} + +static int lpc_cpld_getbyte(void *data, int ctl) +{ + u8 val = 0; + + outb(ctl, LPC_INDEX_REG); + mb(); + + val = inb(LPC_DATA_REG); + mb(); + + return val; +} + +static void lpc_iic_setbyte(void *data, int ctl, int val) +{ + if (!cpld_device) + { + return ; + } + + if (down_interruptible(&cpld_device->sem)) + { + return ; + } + + + lpc_cpld_setbyte(data,ctl,val); + + up(&cpld_device->sem); + DEBPROTO(lpc_fprintf_debug("%s REG[%x] = %x\n",__func__,ctl,val);) +} + + +static int lpc_iic_getbyte(void *data, int ctl) +{ + u8 val = 0; + if (!cpld_device) + return -ENOTTY; + + if (down_interruptible(&cpld_device->sem)) + return -ERESTARTSYS; + + val = lpc_cpld_getbyte(data,ctl); + + up(&cpld_device->sem); + DEBPROTO(lpc_fprintf_debug("%s REG[%x] = %x\n",__func__,ctl,val);) + return val; +} + +int cig_cpld_read_register(u8 reg_off, u8 *val) +{ + if (!cpld_device) + return -ENOTTY; + + if (down_interruptible(&cpld_device->sem)) + return -ERESTARTSYS; + + *val = lpc_cpld_getbyte(cpld_device, reg_off); + + up(&cpld_device->sem); + + return 0; +} +EXPORT_SYMBOL(cig_cpld_read_register); + +int cig_cpld_write_register(u8 reg_off, u8 val) +{ + if (!cpld_device) + return -ENOTTY; + + if (down_interruptible(&cpld_device->sem)) + return -ERESTARTSYS; + + lpc_cpld_setbyte(cpld_device, reg_off, val); + up(&cpld_device->sem); + return 0; +} +EXPORT_SYMBOL(cig_cpld_write_register); + + + +static int lpc_iic_getown(void *data) +{ + return (lpc_own); +} + + +static int lpc_iic_getclock(void *data) +{ + return (lpc_clock); +} + +static void lpc_iic_waitforpin(void *data) +{ + DEFINE_WAIT(wait); + int timeout = 2; + unsigned long flags; + + if (lpc_irq > 0) { + spin_lock_irqsave(&lock, flags); + if (lpc_pending == 0) { + spin_unlock_irqrestore(&lock, flags); + prepare_to_wait(&lpc_wait, &wait, TASK_INTERRUPTIBLE); + if (schedule_timeout(timeout*HZ)) { + spin_lock_irqsave(&lock, flags); + if (lpc_pending == 1) { + lpc_pending = 0; + } + spin_unlock_irqrestore(&lock, flags); + } + finish_wait(&lpc_wait, &wait); + } else { + lpc_pending = 0; + spin_unlock_irqrestore(&lock, flags); + } + } else { + udelay(100); + } +} + + +static irqreturn_t lpc_iic_handler(int this_irq, void *dev_id) { + spin_lock(&lock); + lpc_pending = 1; + spin_unlock(&lock); + wake_up_interruptible(&lpc_wait); + return IRQ_HANDLED; +} + +static int board_id = 0; + + +static int lpc_iic_select(void *data) +{ + unsigned int chan_id=0; + chan_id = *(unsigned int *)data; + chan_id -= 2; + DEBPROTO(lpc_fprintf_debug("step 1 : selest channel id = %d\n",chan_id);) + lpc_iic_setbyte(data,I2C_LPC_REG_BUS_SEL,chan_id); + + return 0; +} + +static int lpc_iic_deselect(void *data) +{ + + unsigned int chan_id=0; + chan_id = *(unsigned int *)data; + chan_id -= 2; + DEBPROTO(lpc_fprintf_debug("step last :deselect channel id = %d\n",chan_id);) + + return 0; +} + + +/* ------------------------------------------------------------------------ + * Encapsulate the above functions in the correct operations structure. + * This is only done when more than one hardware adapter is supported. + */ +static struct i2c_algo_lpc_data lpc_iic_data = { + .setlpc = lpc_iic_setbyte, + .getlpc = lpc_iic_getbyte, + .getown = lpc_iic_getown, + .getclock = lpc_iic_getclock, + .waitforpin = lpc_iic_waitforpin, + .xfer_begin = lpc_iic_select, + .xfer_end = lpc_iic_deselect, +}; + +#include + +static struct i2c_adapter lpc_iic_arr_ops[LPC_I2C_MAX_NCHANS] = {0}; + +static void dummy_setscl(void *data, int state) +{ + return; +} + +static void dummy_setsda(void *data, int state) +{ + return; + +} + +static int dummy_getscl(void *data) +{ + return 1; + +} + +static int dummy_getsda(void *data) +{ + return 1; +} + + +static struct i2c_algo_bit_data dummy_algo_data = { + .setsda = dummy_setsda, + .setscl = dummy_setscl, + .getsda = dummy_getsda, + .getscl = dummy_getscl, + .udelay = 50, + .timeout = HZ, +}; + + +static int dummy_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg *msgs, + int num) +{ + return 1; +} + +static u32 dummy_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_QUICK; +} + + +static const struct i2c_algorithm dummy_algo = { + .master_xfer = dummy_xfer, + .functionality = dummy_func, +}; + + + +static struct i2c_adapter i2c_dummy = { + .owner = THIS_MODULE, + .class = I2C_CLASS_HWMON, + .algo_data = &dummy_algo_data, + .algo = &dummy_algo, + .name = "i2c_dummy", +}; + + +static int lpc_iic_match(struct device *dev, unsigned int id) +{ + /* sanity checks for lpc_mmapped I/O */ + + DEB2(printk("lpc_iic_match\n");) + + + if (lpc_base < DEFAULT_BASE) { + dev_err(dev, "incorrect lpc_base address (%#x) specified " + "for lpc_mmapped I/O\n", lpc_base); + return 0; + } + + if (lpc_base == 0) { + lpc_base = DEFAULT_BASE; + } + return 1; +} + +static int lpc_iic_probe(struct device *dev, unsigned int id) +{ + int rval,num; + + lpc_fprintf_init(); + + DEB2(printk("lpc_iic_probe\n");) + + mutex_init(&lpc_lock); + + for(num = 0; num < LPC_I2C_MAX_NCHANS;num++) + { + lpc_iic_arr_ops[num].dev.parent = dev; + lpc_iic_arr_ops[num].owner = THIS_MODULE; + lpc_iic_arr_ops[num].class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + lpc_iic_arr_ops[num].algo = &lpc_algo; + lpc_iic_arr_ops[num].algo_data = &lpc_iic_data, + lpc_iic_arr_ops[num].nr=num; + snprintf(lpc_iic_arr_ops[num].name, sizeof(lpc_iic_arr_ops[num].name), "i2c-%d-lpc", i2c_adapter_id(&lpc_iic_arr_ops[num])); + rval |= i2c_add_adapter(&lpc_iic_arr_ops[num]); + DEB2(printk("%s\n",lpc_iic_arr_ops[num].name);) + } + + return 0; +} + +static int lpc_iic_remove(struct device *dev, unsigned int id) +{ + int num; + DEB2(printk("lpc_iic_remove\n")); + + lpc_fprintf_exit(); + for(num = LPC_I2C_MAX_NCHANS - 1; num >= 0 ;num--) + i2c_del_adapter(&lpc_iic_arr_ops[num]); + + + return 0; +} + +static struct isa_driver i2c_lpc_driver = { + .match = lpc_iic_match, + .probe = lpc_iic_probe, + .remove = lpc_iic_remove, + .driver = { + .owner = THIS_MODULE, + .name = "lpc-iic", + }, +}; + +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ + +static int cpld_major = 0; +static int cpld_minor = 0; + +struct cpld_rw_msg { + unsigned char addr; + unsigned char data; +}; + + +static struct cpld_rw_msg param_read = {-1}; +static struct cpld_rw_msg param_write = {-1}; +static struct cpld_rw_msg param_reads = {-1}; +static struct cpld_rw_msg param_writes = {-1}; + +void cpld_sysfs_kobj_release(struct kobject *kobj) +{ + return; +} + +int cpld_sysfs_add_attr(struct kobject* kobj, char* attr_name) +{ + + struct attribute *attr; + + attr = kmalloc(sizeof(struct attribute), GFP_KERNEL); + attr->name = attr_name; + attr->mode = 0644; + + return sysfs_create_file(kobj, attr); +} + +static int cig_cpld_write_slave_cpld_register(u8 reg_addr, u8 reg_data); +static int cig_cpld_read_slave_cpld_register(u8 reg_addr, u8 *reg_data); + + +static ssize_t cpld_sysfs_show(struct kobject *kobj, struct attribute *attr, char *buffer) +{ + u8 val=0,ret=0,year=0,month=0,day=0,cpld_m=0,cpld_1=0,cpld_2=0; + + if (0 == strcmp(attr->name, "read")) + { + val = lpc_iic_getbyte(NULL,param_read.addr); + ret = sprintf(buffer,"read : addr = 0x%x val = 0x%x\n",param_read.addr, val); + + } + else if (0 == strcmp(attr->name, "write")) + { + lpc_iic_setbyte(NULL, param_write.addr,param_write.data); + ret = sprintf(buffer,"write : addr = 0x%x val = 0x%x\n",param_write.addr, param_write.data); + } + else if (0 == strcmp(attr->name, "version")) + { + cpld_m = lpc_iic_getbyte(NULL, 0x02); + year = lpc_iic_getbyte(NULL, 0x03); + month = lpc_iic_getbyte(NULL, 0x04); + day = lpc_iic_getbyte(NULL, 0x05); + + cig_cpld_read_slave_cpld_register(0x1d,&cpld_1); + cig_cpld_read_slave_cpld_register(0x1e,&cpld_2); + + ret = sprintf(buffer,"Main CPLD version : V%02x\n"\ + "Main CPLD date : 20%02x-%02x-%02x\n"\ + "Slave 1 CPLD version : V%02x\n"\ + "Slave 2 CPLD version : V%02x\n",cpld_m,year,month,day,cpld_1,cpld_2); + } + if (0 == strcmp(attr->name, "reads")) + { + ret = cig_cpld_read_slave_cpld_register(param_reads.addr,&val); + if (ret < 0) + printk("ERROR:Failed to read slave cpld.\n"); + ret = sprintf(buffer,"reads : addr = 0x%x val = 0x%x\n",param_reads.addr, val); + + } + else if (0 == strcmp(attr->name, "writes")) + { + ret = cig_cpld_write_slave_cpld_register(param_writes.addr,param_writes.data); + if (ret < 0) + printk("ERROR:Failed to read slave cpld.\n"); + ret = sprintf(buffer,"writes : addr = 0x%x val = 0x%x\n",param_writes.addr, param_writes.data); + } + + + return ret; + +} + +static ssize_t cpld_sysfs_store(struct kobject *kobj, struct attribute *attr, const char *buffer, size_t count) +{ + int param[3]; + + if (0 == strcmp(attr->name, "read")) + { + sscanf(buffer, "0x%02x", ¶m[0]); + param_read.addr = param[0]; + } + else if (0 == strcmp(attr->name, "write")) + { + sscanf(buffer, "0x%2x 0x%02x", ¶m[0], ¶m[1]); + param_write.addr = param[0]; + param_write.data = param[1]; + } + if (0 == strcmp(attr->name, "reads")) + { + sscanf(buffer, "0x%02x", ¶m[0]); + param_reads.addr = param[0]; + } + else if (0 == strcmp(attr->name, "writes")) + { + sscanf(buffer, "0x%2x 0x%02x", ¶m[0], ¶m[1]); + param_writes.addr = param[0]; + param_writes.data = param[1]; + } + return count; +} + + + +static struct sysfs_ops cpld_sysfs_ops = +{ + .show = cpld_sysfs_show, + .store = cpld_sysfs_store, +}; + +static struct kobj_type cpld_kobj_type = +{ + .release = cpld_sysfs_kobj_release, + .sysfs_ops = &cpld_sysfs_ops, + .default_attrs = NULL, +}; + + +static const char driver_name[] = "cpld_drv"; +static atomic_t cpld_available = ATOMIC_INIT(1); +static struct class *cpld_class; +static struct device *cpld_dev; + + + +#define CPLD_IOC_MAGIC '[' + +#define CPLD_IOC_RDREG _IOR(CPLD_IOC_MAGIC, 0, struct cpld_rw_msg) +#define CPLD_IOC_WRREG _IOW(CPLD_IOC_MAGIC, 1, struct cpld_rw_msg) + +#define CPLD_IOC_MAXNR 2 + + +int cpld_open(struct inode *inode, struct file *filp) +{ + struct cpld_dev_type *dev; + + if (! atomic_dec_and_test(&cpld_available)) { + atomic_inc(&cpld_available); + return -EBUSY; + } + + dev = container_of(inode->i_cdev, struct cpld_dev_type, cdev); + filp->private_data = dev; + + return 0; +} + +int cpld_release(struct inode *inode, struct file *flip) +{ + atomic_inc(&cpld_available); + return 0; +} + + +long cpld_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int rc = 0; + int err = 0; + struct cpld_dev_type *dev = (struct cpld_dev_type *)filp->private_data; + struct cpld_rw_msg msg; + + if (_IOC_TYPE(cmd) != CPLD_IOC_MAGIC) + return -ENOTTY; + if (_IOC_NR(cmd) > CPLD_IOC_MAXNR) + return -ENOTTY; + + if (_IOC_DIR(cmd) & _IOC_READ) + err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); + if (_IOC_DIR(cmd) & _IOC_WRITE) + err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); + if (err) + return -EFAULT; + + if (down_interruptible(&dev->sem)) + return -ERESTARTSYS; + + switch(cmd){ + case CPLD_IOC_RDREG: + rc = copy_from_user(&msg, (void __user *)arg, sizeof(msg)); + if (!rc) { + msg.data = lpc_cpld_getbyte(dev, msg.addr); + rc = copy_to_user((void __user *)arg, &msg, sizeof(msg)); + } + break; + + case CPLD_IOC_WRREG: + rc = copy_from_user(&msg, (void __user *)arg, sizeof(msg)); + if (!rc) { + lpc_cpld_setbyte(dev, msg.addr, msg.data); + } + break; + default: + rc = -ENOTTY; + break; + } + up(&dev->sem); + + return rc; +} + +struct file_operations cpld_fops = { + .owner = THIS_MODULE, + .open = cpld_open, + .unlocked_ioctl = cpld_ioctl, + .release = cpld_release, +}; + + +static void cpld_setup_cdev(struct cpld_dev_type *dev) +{ + int err, devno = MKDEV(cpld_major, cpld_minor); + + cdev_init(&dev->cdev, &cpld_fops); + dev->cdev.owner = THIS_MODULE; + dev->cdev.ops = &cpld_fops; + err = cdev_add(&dev->cdev, devno, 1); + + if (err) + DEB2(printk(KERN_NOTICE "Error %d adding cpld", err);) +} +/********************************************** End ********************************************************/ + + + + +/********************************************** Start ********************************************************/ +#include +#include +#include + +static spinlock_t irq_inter_lock; +static struct delayed_work irq_inter_work; +static unsigned long irq_inter_delay; + + +static int cig_cpld_write_slave_cpld_register(u8 reg_addr, u8 reg_data) +{ + u8 read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + DEB2(printk("<=======write=========>")); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, reg_addr << 1); + DEB2(printk("[62]=%x\n",reg_addr << 1)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_TX, reg_data); + DEB2(printk("[63]=%x\n",reg_data)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + DEB2(printk("[65]=%x\n",0x80)); + do{ + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &read_status); + DEB2(printk("[66]=%x\n",read_status)); + udelay(60); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(read_status != 0x02); + DEB2(printk("<=======write=========>")); + + + if(wait_time_out == 0) + return -1; + + return 1; +} + + +static int cig_cpld_read_slave_cpld_register(u8 reg_addr, u8 *reg_data) +{ + u8 read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + DEB2(printk("<========read=========>")); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, reg_addr << 1 | 1); + DEB2(printk("[62]=%x\n",reg_addr << 1 | 1)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + DEB2(printk("[65]=%x\n",0x80)); + do{ + udelay(60); + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &read_status); + DEB2(printk("[66]=%x\n",read_status)); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(read_status != 0x01); + + cig_cpld_read_register(ADDR_REG_SFP_STATUS_RX,reg_data); + DEB2(printk("[64]=%x\n",*reg_data)); + DEB2(printk("<========read=========>")); + + if(wait_time_out == 0) + return -1; + + return 1; +} + + + +struct sock *nlsk = NULL; +extern struct net init_net; +#define NETLINK_TEST 26 +#define MSG_LEN 125 +#define USER_PORT 100 +static u32 irq_present_status_low_current,irq_present_status_low_next; +static u32 irq_present_status_high_current,irq_present_status_high_next; +static u32 irq_tx_fault_status_low_current,irq_tx_fault_status_low_next; +static u32 irq_tx_fault_status_high_current,irq_tx_fault_status_high_next; +static u32 irq_rx_lost_status_low_current,irq_rx_lost_status_low_next; +static u32 irq_rx_lost_status_high_current,irq_rx_lost_status_high_next; + +static u8 irq_present_qsfp_current,irq_present_qsfp_next; +static u8 irq_interrupt_qsfp_current,irq_interrupt_qsfp_next; + +struct input_dev *cpld_input_dev; + + + +int send_usrmsg(char *pbuf, uint16_t len) +{ + struct sk_buff *nl_skb; + struct nlmsghdr *nlh; + + int ret; + + + nl_skb = nlmsg_new(len, GFP_ATOMIC); + if(!nl_skb) + { + printk("netlink alloc failure\n"); + return -1; + } + + + nlh = nlmsg_put(nl_skb, 0, 0, NETLINK_TEST, len, 0); + if(nlh == NULL) + { + printk("nlmsg_put failaure \n"); + nlmsg_free(nl_skb); + return -1; + } + + memcpy(nlmsg_data(nlh), pbuf, len); + ret = netlink_unicast(nlsk, nl_skb, USER_PORT, MSG_DONTWAIT); + + return ret; +} + +static void netlink_rcv_msg(struct sk_buff *skb) +{ + + struct nlmsghdr *nlh = NULL; + char *umsg = NULL; + char kmsg[1024] = {0}; + char kmsg_tmp[16] = {0}; + u8 i = 0; + u8 tmp[3]={0}; + + if(skb->len >= nlmsg_total_size(0)) + { + nlh = nlmsg_hdr(skb); + umsg = NLMSG_DATA(nlh); + if(umsg) + { + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_low_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_rx_lost_status_low_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_low_current & (0x1 << i))) + { + tmp[2] = 1; + } + else + { + tmp[2] = 0; + } + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"sfp%02d:%1d:%1d:%1d ",i+1,tmp[0],tmp[1],tmp[2]); + strcat(kmsg,kmsg_tmp); + } + + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_high_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_rx_lost_status_high_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_high_current & (0x1 << i))) + { + tmp[2] = 1; + } + else + { + tmp[2] = 0; + } + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"sfp%02d:%1d:%1d:%1d ",i+25,tmp[0],tmp[1],tmp[2]); + strcat(kmsg,kmsg_tmp); + } + + + for(i = 0;i < 8;i++) + { + if(!(irq_present_qsfp_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_interrupt_qsfp_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"qsfp%02d:%1d:%1d:%1d ",i+49,tmp[0],tmp[1],0); + strcat(kmsg,kmsg_tmp); + } + + printk("kernel recv from user: %s\n", umsg); + send_usrmsg(kmsg, strlen(kmsg)); + } + } + + return ; +} + + + +struct netlink_kernel_cfg cfg = { + .input = netlink_rcv_msg, /* set recv callback */ +}; + + + +#define RANGE_OF_BYTE_SHIFT(to_arg,shift,from_arg) {to_arg &= ~(0xff << shift); to_arg |= from_arg << shift;} + + +static void irq_inter_wapper(struct work_struct * work) +{ + + u8 m_data = 0; + u8 data_high8 = 0,data_low8 = 0; + u16 data_16 = 0; + u8 status = 0; + u8 i = 0; + char kmsg[64]={0}; + u8 tmp[3] = {0}; + + DEB2(printk("CPLD_MASTER_INTERRUPT\r\n")); + + m_data = lpc_iic_getbyte(NULL,CPLD_MASTER_INTERRUPT_STATUS_REG); + lpc_iic_setbyte(NULL,CPLD_MASTER_INTERRUPT_STATUS_REG,0xff); + + cig_cpld_write_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_MASK_REG,0xff); + cig_cpld_write_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_MASK_REG,0xff); + if(!(m_data & CPLD_MASTER_INTERRUPT_CPLD1)) + { + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_STATUS_H_REG,&data_high8); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_STATUS_L_REG,&data_low8); + data_16 = data_low8 | data_high8 << 8; + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT24) + ) + { + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,16,status); + } + DEB2(printk("irq_present_status_low_next = %08x irq_present_status_low_current = %08x \n",irq_present_status_low_next,irq_present_status_low_current)); + } + + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24) + ) + { + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_RX_LOST08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,16,status); + } + DEB2(printk("irq_rx_lost_status_low_next = %08x irq_rx_lost_status_low_current = %08x \n",irq_rx_lost_status_low_next,irq_rx_lost_status_low_current)); + } + + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24) + ) + { + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,16,status); + } + DEB2(printk("irq_tx_fault_status_low_next = %08x irq_tx_fault_status_low_current = %08x \n",irq_tx_fault_status_low_next,irq_tx_fault_status_low_current)); + + } + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_CPLD2)) + { + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_STATUS_H_REG,&data_high8); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_STATUS_L_REG,&data_low8); + data_16 = data_low8 | data_high8 << 8; + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT32)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT32_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT40)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT40_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,16,status); + } + } + + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST32)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_RX_LOST32\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST40)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT40\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,16,status); + } + + } + + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT32)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_RX_LOST32\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT40)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT40\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,16,status); + } + } + + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT56)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT56_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT56_REG,&status); + irq_present_qsfp_current = status; + } + + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_QSFP_CR56)) + { + DEB2(printk("CPLD_SLAVE2_QSFP_CR56_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_QSFP_CR56_REG,&status); + irq_interrupt_qsfp_current = status; + } + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_LSW)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_LSW\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_PSU1)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_PSU1\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_PSU2)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_PSU2\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_6320)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_6320\r\n")); + } + cig_cpld_write_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_MASK_REG,0x0); + cig_cpld_write_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_MASK_REG,0x0); + + memset(tmp,0xff,sizeof(tmp)); + + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_low_current & (0x1 << i)) && (irq_present_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+1)); + tmp[0] = 1; + } + else if((irq_present_status_low_current & (0x1 << i)) && !(irq_present_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+1)); + tmp[0] = 0; + } + + if(!(irq_tx_fault_status_low_current & (0x1 << i)) && (irq_tx_fault_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is right\r\n",i+1)); + tmp[1] = 1; + } + else if((irq_tx_fault_status_low_current & (0x1 << i)) && !(irq_tx_fault_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is fault\r\n",i+1)); + tmp[1] = 0; + } + + if(!(irq_rx_lost_status_low_current & (0x1 << i)) && (irq_rx_lost_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is meet\r\n",i+1)); + tmp[2] = 1; + } + else if((irq_rx_lost_status_low_current & (0x1 << i)) && !(irq_rx_lost_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is lost\r\n",i+1)); + tmp[2] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff) || (tmp[2] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"sfp%02d:%1d:%1d:%1d ",i+1,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],(tmp[2] == 0xff) ? 0:tmp[2]); + break; + } + } + + memset(tmp,0xff,sizeof(tmp)); + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_high_current & (0x1 << i)) && (irq_present_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+25)); + tmp[0] = 1; + } + else if((irq_present_status_high_current & (0x1 << i)) && !(irq_present_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+25)); + tmp[0] = 0; + + } + + if(!(irq_rx_lost_status_high_current & (0x1 << i)) && (irq_rx_lost_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is meet\r\n",i+25)); + tmp[1] = 1; + } + else if((irq_rx_lost_status_high_current & (0x1 << i)) && !(irq_rx_lost_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is lost\r\n",i+25)); + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_high_current & (0x1 << i)) && (irq_tx_fault_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is right\r\n",i+25)); + tmp[2] = 1; + } + else if((irq_tx_fault_status_high_current & (0x1 << i)) && !(irq_tx_fault_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is fault\r\n",i+25)); + tmp[2] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff) || (tmp[2] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"sfp%02d:%1d:%1d:%1d ",i+25,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],(tmp[2] == 0xff) ? 0:tmp[2]); + break; + } + } + + memset(tmp,0xff,sizeof(tmp)); + for(i = 0 ; i < 8; i++) + { + if(!(irq_present_qsfp_current & (0x1 << i)) && (irq_present_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+49)); + tmp[0] = 1; + } + else if((irq_present_qsfp_current & (0x1 << i)) && !(irq_present_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+49)); + tmp[0] = 0; + } + + if(!(irq_interrupt_qsfp_current & (0x1 << i)) && (irq_interrupt_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d interrupt is occured \r\n",i+49)); + tmp[1] = 1; + } + else if((irq_interrupt_qsfp_current & (0x1 << i)) && !(irq_interrupt_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d interrupt is cleaned\r\n",i+49)); + tmp[1] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"qsfp%02d:%1d:%1d:%1d ",i+49,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],0); + break; + } + } + + + irq_present_status_low_next = irq_present_status_low_current; + irq_rx_lost_status_low_next = irq_rx_lost_status_low_current; + irq_tx_fault_status_low_next = irq_tx_fault_status_low_current; + irq_present_status_high_next = irq_present_status_high_current; + irq_rx_lost_status_high_next = irq_rx_lost_status_high_current; + irq_tx_fault_status_high_next = irq_tx_fault_status_high_current; + irq_present_qsfp_next = irq_present_qsfp_current; + irq_interrupt_qsfp_next = irq_interrupt_qsfp_current; + + send_usrmsg(kmsg, strlen(kmsg)); +} + +static void disableIrq(unsigned short maskReg, unsigned short mask) +{ + u8 data = 0; + + data = lpc_iic_getbyte(NULL,maskReg); + data |= mask; + lpc_iic_setbyte(NULL,maskReg, data); +} + +static void enableIrq(unsigned short maskReg, unsigned short mask) +{ + unsigned short data; + + data = lpc_iic_getbyte(NULL,maskReg); + data &= ~mask; + lpc_iic_setbyte(NULL,maskReg, data); +} + + +static irqreturn_t irq_inter_isr(int irq, void *handle) +{ + + /* + * use keventd context to read the event fifo registers + * Schedule readout at least 25ms after notification for + * REVID < 4 + */ + + schedule_delayed_work(&irq_inter_work, irq_inter_delay); + + return IRQ_HANDLED; +} + + +#define CIG_CPLD_CHR_NAME "cpld" + + +static int __init cpld_init(void) +{ + int rval,rc=0; + dev_t dev; + u8 s_data; + + DEB2(printk("cpld_init\n");) + +/**************************************************************************************/ + + LPC_INDEX_REG = lpc_base_addr; + LPC_DATA_REG = lpc_base_addr + 1; + + cpld_device = kzalloc(sizeof(struct cpld_dev_type), GFP_KERNEL); + if (!cpld_device) + goto error3; + cpld_device->io_resource = request_region(lpc_base_addr, + lpc_io_space_size, "lpc-i2c"); + if (!cpld_device->io_resource) { + printk("lpc: claim I/O resource fail\n"); + goto error2; + } + sema_init(&cpld_device->sem, 1); + + if (cpld_major) { + dev = MKDEV(cpld_major, cpld_minor); + rc = register_chrdev_region(dev, 1, CIG_CPLD_CHR_NAME); + } else { + rc = alloc_chrdev_region(&dev, cpld_major, 1, CIG_CPLD_CHR_NAME); + cpld_major = MAJOR(dev); + } + + cpld_setup_cdev(cpld_device); + + cpld_class = class_create(THIS_MODULE,CIG_CPLD_CHR_NAME); + if (!cpld_class) { + DEB2(printk("failed to create class\n");) + goto error1; + } + + cpld_class->p->subsys.kobj.ktype= &cpld_kobj_type; + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "read"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "write"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "reads"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "writes"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "version"); + + cpld_dev = device_create(cpld_class, NULL, dev, NULL, CIG_CPLD_CHR_NAME); + +/**************************************************************************************/ + + rval = lpc_bus_init(); + rval = lpc_register_driver(&i2c_lpc_driver, 1); + +/**************************************************************************************/ + return 0; +error1: + cdev_del(&cpld_device->cdev); + unregister_chrdev_region(dev, 1); +error2: + release_resource(cpld_device->io_resource); +error3: + kfree(cpld_device); + + return rc; +} + +static void __exit cpld_exit(void) +{ + DEB2(printk("cpld_exit\n")); + + lpc_unregister_driver(&i2c_lpc_driver); + lpc_bus_exit(); + dev_t devno = MKDEV(cpld_major, cpld_minor); + + cdev_del(&cpld_device->cdev); + if (cpld_class) { + device_destroy(cpld_class, devno); + class_destroy(cpld_class); + } + + if (cpld_device) { + if (cpld_device->io_resource) + release_resource(cpld_device->io_resource); + + kfree(cpld_device); + } + unregister_chrdev_region(devno, 1); + + +} + +module_param(cpld_major, int, S_IRUGO); +module_param(cpld_minor, int, S_IRUGO); +module_param(i2c_debug, int, S_IRUGO); +module_param(board_id, int, S_IRUGO); + +module_init(cpld_init); +module_exit(cpld_exit); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs6436-54p-cpld driver"); +MODULE_LICENSE("GPL"); + + +/********************************************** End ********************************************************/ + + + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-fan.c b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-fan.c new file mode 100644 index 000000000000..881cb7304b06 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-fan.c @@ -0,0 +1,521 @@ +/* + * A hwmon driver for the CIG cs6436-54p fan + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#define FAN_SPEED_DUTY_TO_CPLD_STEP 10 + +static struct cs6436_54p_fan_data *cs6436_54p_fan_update_device(struct device *dev); +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); + + +extern int cig_cpld_write_register(u8 reg_off, u8 val); +extern int cig_cpld_read_register(u8 reg_off, u8 *val); + +/* fan related data, the index should match sysfs_fan_attributes + */ +static const u8 fan_reg[] = { + 0x41, /* fan enable/disable */ + 0x40, /* fan PWM(for all fan) */ + 0x42, /* front fan 1 speed(rpm) */ + 0x44, /* front fan 2 speed(rpm) */ + 0x46, /* front fan 3 speed(rpm) */ + 0x48, /* front fan 4 speed(rpm) */ + 0x4a, /* front fan 5 speed(rpm) */ + 0x43, /* rear fan 1 speed(rpm) */ + 0x45, /* rear fan 2 speed(rpm) */ + 0x47, /* rear fan 3 speed(rpm) */ + 0x49, /* rear fan 4 speed(rpm) */ + 0x4b, /* rear fan 5 speed(rpm) */ + 0x4c, /* fan direction rear to front or front to rear */ +}; + + +/* Each client has this additional data */ +struct cs6436_54p_fan_data { + struct platform_device *pdev; + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[ARRAY_SIZE(fan_reg)]; /* Register value */ +}; + +static struct cs6436_54p_fan_data *fan_data = NULL; + +enum fan_id { + FAN1_ID, + FAN2_ID, + FAN3_ID, + FAN4_ID, + FAN5_ID, +}; + +enum sysfs_fan_attributes { + FAN_STATE_REG, + FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */ + FAN1_FRONT_SPEED_RPM, + FAN2_FRONT_SPEED_RPM, + FAN3_FRONT_SPEED_RPM, + FAN4_FRONT_SPEED_RPM, + FAN5_FRONT_SPEED_RPM, + FAN1_REAR_SPEED_RPM, + FAN2_REAR_SPEED_RPM, + FAN3_REAR_SPEED_RPM, + FAN4_REAR_SPEED_RPM, + FAN5_REAR_SPEED_RPM, + FAN_DIRECTION, + FAN1_STATE, + FAN2_STATE, + FAN3_STATE, + FAN4_STATE, + FAN5_STATE, + FAN1_FAULT, + FAN2_FAULT, + FAN3_FAULT, + FAN4_FAULT, + FAN5_FAULT, + FAN1_DIRECTION, + FAN2_DIRECTION, + FAN3_DIRECTION, + FAN4_DIRECTION, + FAN5_DIRECTION, +}; + +/* Define attributes + */ +#define DECLARE_FAN_STATE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_state, S_IRUGO, fan_show_value, NULL, FAN##index##_STATE) +#define DECLARE_FAN_STATE_ATTR(index) &sensor_dev_attr_fan##index##_state.dev_attr.attr + +#define DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT) +#define DECLARE_FAN_FAULT_ATTR(index) &sensor_dev_attr_fan##index##_fault.dev_attr.attr + +#define DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN##index##_DUTY_CYCLE_PERCENTAGE) +#define DECLARE_FAN_DUTY_CYCLE_ATTR(index) &sensor_dev_attr_fan##index##_duty_cycle_percentage.dev_attr.attr + +#define DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_front_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index##_rear_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM) +#define DECLARE_FAN_SPEED_RPM_ATTR(index) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr + +#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IWUSR | S_IRUGO, fan_show_value, set_fan_direction, FAN##index##_DIRECTION) +#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr + + +/* 5 fan state attributes in this platform */ +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(1); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(2); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(3); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(4); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(5); + + +/* 5 fan fault attributes in this platform */ +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(1); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(2); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(3); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(4); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(5); + +/* 5 fan speed(rpm) attributes in this platform */ +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(1); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(2); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(3); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(4); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(5); + +/* 1 fan duty cycle attribute in this platform */ +DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(); + +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(5); + + +static struct attribute *cs6436_54p_fan_attributes[] = { + /* fan related attributes */ + DECLARE_FAN_STATE_ATTR(1), + DECLARE_FAN_STATE_ATTR(2), + DECLARE_FAN_STATE_ATTR(3), + DECLARE_FAN_STATE_ATTR(4), + DECLARE_FAN_STATE_ATTR(5), + DECLARE_FAN_FAULT_ATTR(1), + DECLARE_FAN_FAULT_ATTR(2), + DECLARE_FAN_FAULT_ATTR(3), + DECLARE_FAN_FAULT_ATTR(4), + DECLARE_FAN_FAULT_ATTR(5), + DECLARE_FAN_SPEED_RPM_ATTR(1), + DECLARE_FAN_SPEED_RPM_ATTR(2), + DECLARE_FAN_SPEED_RPM_ATTR(3), + DECLARE_FAN_SPEED_RPM_ATTR(4), + DECLARE_FAN_SPEED_RPM_ATTR(5), + DECLARE_FAN_DUTY_CYCLE_ATTR(), + DECLARE_FAN_DIRECTION_ATTR(1), + DECLARE_FAN_DIRECTION_ATTR(2), + DECLARE_FAN_DIRECTION_ATTR(3), + DECLARE_FAN_DIRECTION_ATTR(4), + DECLARE_FAN_DIRECTION_ATTR(5), + NULL +}; + +#define FAN_MAX_DUTY_CYCLE 100 +#define FAN_REG_VAL_TO_SPEED_RPM_STEP 100 + +/* fan utility functions + */ +static u32 reg_val_to_duty_cycle(u8 reg_val) +{ + if (reg_val +== 0xFF) { + return 100; + } + return ((u32)(reg_val) * 100)/ 255; +} + +static u8 duty_cycle_to_reg_val(u8 duty_cycle) +{ + if (duty_cycle >= FAN_MAX_DUTY_CYCLE) { + return 0xFF; + } + + return 255 / 10 * (duty_cycle / 10); +} + +static u32 reg_val_to_speed_rpm(u8 reg_val) +{ + return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP; +} + +static u8 reg_val_to_is_state(u8 reg_val, enum fan_id id) +{ + u8 mask = (1 << id); + + reg_val &= mask; + + return reg_val ? 0 : 1; +} + +static u8 is_fan_fault(struct cs6436_54p_fan_data *data, enum fan_id id) +{ + u8 ret = 1; + int front_fan_index = FAN1_FRONT_SPEED_RPM + id; + int rear_fan_index = FAN1_REAR_SPEED_RPM + id; + + /* Check if the speed of front or rear fan is ZERO, + */ + if (reg_val_to_speed_rpm(data->reg_val[front_fan_index]) && + reg_val_to_speed_rpm(data->reg_val[rear_fan_index])) { + ret = 0; + } + + return ret; +} + + +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value; + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value <= 0 || value > FAN_MAX_DUTY_CYCLE) + return -EINVAL; + + cig_cpld_write_register(fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value)); + + return count; +} + +static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value,fan_index; + u8 mask,reg_val; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + fan_index = attr->index - FAN1_DIRECTION; + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (!(value == 0 || value == 1)) + return -EINVAL; + + + cig_cpld_read_register(fan_reg[FAN_DIRECTION],®_val); + + if(value == 1) + { + reg_val |= (1 << fan_index); + } + else + { + reg_val &= ~(1 << fan_index); + } + + cig_cpld_write_register(fan_reg[FAN_DIRECTION], reg_val); + + return count; +} + + + + + +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + cs6436_54p_fan_update_device(dev); + + struct cs6436_54p_fan_data *data = fan_data; + + ssize_t ret = 0; + + if (data->valid) { + switch (attr->index) { + + case FAN1_STATE: + case FAN2_STATE: + case FAN3_STATE: + case FAN4_STATE: + case FAN5_STATE: + //printk("FAN_STATE_REG: 0x%x\n", data->reg_val[FAN_STATE_REG]); + //printk("index: %d\n", attr->index); + ret = sprintf(buf, "%d\n", + reg_val_to_is_state(data->reg_val[FAN_STATE_REG], + attr->index - FAN1_STATE)); + break; + case FAN_DUTY_CYCLE_PERCENTAGE: + { + u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[FAN_DUTY_CYCLE_PERCENTAGE]); + ret = sprintf(buf, "%u\n", duty_cycle); + break; + } + case FAN1_FRONT_SPEED_RPM: + case FAN2_FRONT_SPEED_RPM: + case FAN3_FRONT_SPEED_RPM: + case FAN4_FRONT_SPEED_RPM: + case FAN5_FRONT_SPEED_RPM: + case FAN1_REAR_SPEED_RPM: + case FAN2_REAR_SPEED_RPM: + case FAN3_REAR_SPEED_RPM: + case FAN4_REAR_SPEED_RPM: + case FAN5_REAR_SPEED_RPM: +// printk("FAN_seed_REG: 0x%x\n", data->reg_val[attr->index]); +// printk("index: %d\n", attr->index); + ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index])); + break; + + case FAN1_FAULT: + case FAN2_FAULT: + case FAN3_FAULT: + case FAN4_FAULT: + case FAN5_FAULT: + ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT)); + break; + case FAN1_DIRECTION: + case FAN2_DIRECTION: + case FAN3_DIRECTION: + case FAN4_DIRECTION: + case FAN5_DIRECTION: + ret = sprintf(buf, "%d\n",reg_val_to_is_state(data->reg_val[FAN_DIRECTION],attr->index - FAN1_DIRECTION)); + break; + default: + break; + } + } + + return ret; +} + +static const struct attribute_group cs6436_54p_fan_group = { + .attrs = cs6436_54p_fan_attributes, +}; + +static struct cs6436_54p_fan_data *cs6436_54p_fan_update_device(struct device *dev) +{ + struct cs6436_54p_fan_data *data = fan_data; + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || + !data->valid) { + int i; + + data->valid = 0; + + /* Update fan data + */ + for (i = 0; i < ARRAY_SIZE(data->reg_val); i++) { + u8 status; + (void)cig_cpld_read_register(fan_reg[i], &status); + + if (status < 0) { + data->valid = 0; + mutex_unlock(&data->update_lock); + return data; + } + else { + data->reg_val[i] = status; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int cs6436_54p_fan_probe(struct platform_device *pdev) +{ + int status = -1; + /* Register sysfs hooks */ + status = sysfs_create_group(&pdev->dev.kobj, &cs6436_54p_fan_group); + if (status) { + goto exit; + + } + + fan_data->hwmon_dev = hwmon_device_register(&pdev->dev); + if (IS_ERR(fan_data->hwmon_dev)) { + status = PTR_ERR(fan_data->hwmon_dev); + goto exit_remove; + } + + dev_info(&pdev->dev, "cs6436_54p_fan\n"); + + return 0; + +exit_remove: + sysfs_remove_group(&pdev->dev.kobj, &cs6436_54p_fan_group); +exit: + return status; +} + +static int cs6436_54p_fan_remove(struct platform_device *pdev) +{ + hwmon_device_unregister(fan_data->hwmon_dev); + sysfs_remove_group(&fan_data->pdev->dev.kobj, &cs6436_54p_fan_group); + + return 0; +} + +#define DRVNAME "cs6436_54p_fan" + +static struct platform_driver cs6436_54p_fan_driver = { + .probe = cs6436_54p_fan_probe, + .remove = cs6436_54p_fan_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + + + + + +static int __init cs6436_54p_fan_init(void) +{ + int ret; + + cig_cpld_write_register(0x40, duty_cycle_to_reg_val(50)); + + ret = platform_driver_register(&cs6436_54p_fan_driver); + if (ret < 0) { + goto exit; + } + + fan_data = kzalloc(sizeof(struct cs6436_54p_fan_data), GFP_KERNEL); + if (!fan_data) { + ret = -ENOMEM; + platform_driver_unregister(&cs6436_54p_fan_driver); + goto exit; + } + + mutex_init(&fan_data->update_lock); + fan_data->valid = 0; + + fan_data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(fan_data->pdev)) { + ret = PTR_ERR(fan_data->pdev); + platform_driver_unregister(&cs6436_54p_fan_driver); + kfree(fan_data); + goto exit; + } + +exit: + return ret; +} + +static void __exit cs6436_54p_fan_exit(void) +{ + platform_device_unregister(fan_data->pdev); + platform_driver_unregister(&cs6436_54p_fan_driver); + kfree(fan_data); +} + +MODULE_AUTHOR("CIG"); +MODULE_DESCRIPTION("cs6436_54p_fan driver"); +MODULE_LICENSE("GPL"); + +module_init(cs6436_54p_fan_init); +module_exit(cs6436_54p_fan_exit); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs6436_54p_fan driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-led.c b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-led.c new file mode 100644 index 000000000000..74c8b6d0b10e --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-led.c @@ -0,0 +1,594 @@ +/* + * A hwmon driver for the CIG cs6436-54P LED + * + * Copyright (C) 2018 Cambridge, Inc. + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*#define DEBUG*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern int cig_cpld_write_register(u8 reg_off, u8 val); + +extern int cig_cpld_read_register(u8 reg_off, u8 *val); + +extern void led_classdev_unregister(struct led_classdev *led_cdev); +extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); +extern void led_classdev_resume(struct led_classdev *led_cdev); +extern void led_classdev_suspend(struct led_classdev *led_cdev); + +#define DRVNAME "cs6436_54p_led" + +struct cs6436_54p_led_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[6]; /* 0: system & location + 1: PSU1 &PSU12 + 2: fan & management + 3: console & ToD + 4-5 : fan1-fan5*/ +}; + +static struct cs6436_54p_led_data *ledctl = NULL; + +/* LED related data + */ +#define LED_TYPE_PSU1_REG_MASK 0x0C +#define LED_MODE_PSU1_GREEN_MASK 0x08 +#define LED_MODE_PSU1_RED_MASK 0x04 +#define LED_MODE_PSU1_AMBER_MASK 0x0C +#define LED_MODE_PSU1_OFF_MASK 0x00 + +#define LED_TYPE_PSU2_REG_MASK 0x30 +#define LED_MODE_PSU2_GREEN_MASK 0x20 +#define LED_MODE_PSU2_RED_MASK 0x10 +#define LED_MODE_PSU2_AMBER_MASK 0x30 +#define LED_MODE_PSU2_OFF_MASK 0x00 + +#define LED_TYPE_SYS_REG_MASK 0xF0 +#define LED_MODE_SYS_GREEN_MASK 0x40 +#define LED_MODE_SYS_RED_MASK 0x20 +#define LED_MODE_SYS_AMBER_MASK 0x60 +#define LED_MODE_SYS_AMBER_FLASHING_MASK 0x70 +#define LED_MODE_SYS_OFF_MASK 0x00 + +#define LED_TYPE_RES_REG_MASK 0x0F +#define LED_MODE_RES_GREEN_MASK 0x04 +#define LED_MODE_RES_RED_MASK 0x02 +#define LED_MODE_RES_AMBER_MASK 0x06 +#define LED_MODE_RES_AMBER_FLASHING_MASK 0x07 +#define LED_MODE_RES_OFF_MASK 0x00 + +#define LED_TYPE_FAN_REG_MASK 0x03 +#define LED_MODE_FAN_GREEN_MASK 0x02 +#define LED_MODE_FAN_RED_MASK 0x01 +#define LED_MODE_FAN_AMBER_MASK 0x03 +#define LED_MODE_FAN_OFF_MASK 0x00 + +#define LED_TYPE_FAN1_REG_MASK 0x03 +#define LED_TYPE_FAN2_REG_MASK 0x0C +#define LED_TYPE_FAN3_REG_MASK 0x30 +#define LED_TYPE_FAN4_REG_MASK 0xC0 +#define LED_TYPE_FAN5_REG_MASK 0x03 + +#define LED_MODE_FANX_GREEN_MASK 0x02 +#define LED_MODE_FANX_RED_MASK 0x01 +#define LED_MODE_FANX_AMBER_MASK 0x03 +#define LED_MODE_FANX_OFF_MASK 0x00 + +enum led_type { + LED_TYPE_SYS, + LED_TYPE_PSU2, + LED_TYPE_PSU1, + LED_TYPE_FAN, + LED_TYPE_FAN1, + LED_TYPE_FAN2, + LED_TYPE_FAN3, + LED_TYPE_FAN4, + LED_TYPE_FAN5, +}; + +static const u8 led_reg[] = { + 0x30, /* system & reserved*/ + 0x31, /* fan & PSU1 & PSU2 */ + 0x32, /* FAN5 LED */ + 0x33, /* FAN1-4 LED */ +}; + + +enum led_light_mode { + LED_MODE_OFF = 0, + LED_MODE_GREEN, + LED_MODE_AMBER, + LED_MODE_RED, + LED_MODE_GREEN_BLINK, + LED_MODE_AMBER_BLINK, + LED_MODE_RED_BLINK, + LED_MODE_GREEN_FLASHING, + LED_MODE_AMBER_FLASHING, + LED_MODE_RED_FLASHING, + LED_MODE_AUTO, + LED_MODE_UNKNOWN +}; + +struct led_type_mode { + enum led_type type; + int type_mask; + enum led_light_mode mode; + int mode_mask; +}; + +static struct led_type_mode led_type_mode_data[] = { +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU1_GREEN_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU1_AMBER_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_RED, LED_MODE_PSU1_RED_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_OFF, LED_MODE_PSU1_OFF_MASK}, + +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU2_GREEN_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU2_AMBER_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_RED, LED_MODE_PSU2_RED_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_OFF, LED_MODE_PSU2_OFF_MASK}, + +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_GREEN, LED_MODE_SYS_GREEN_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_AMBER, LED_MODE_SYS_AMBER_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_RED, LED_MODE_SYS_RED_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_AMBER_FLASHING, LED_MODE_SYS_AMBER_FLASHING_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_OFF, LED_MODE_SYS_OFF_MASK}, + +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_GREEN, LED_MODE_FAN_GREEN_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_AMBER, LED_MODE_FAN_AMBER_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_RED, LED_MODE_FAN_RED_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_OFF, LED_MODE_FAN_OFF_MASK}, + +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 2}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 4}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 6}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0}, +}; + +struct fanx_info_s { + u8 cname; /* device name */ + enum led_type type; + u8 reg_id; /* map to led_reg & reg_val */ +}; + +static struct fanx_info_s fanx_info[] = { + {'1', LED_TYPE_FAN1, 3}, + {'2', LED_TYPE_FAN2, 3}, + {'3', LED_TYPE_FAN3, 3}, + {'4', LED_TYPE_FAN4, 3}, + {'5', LED_TYPE_FAN5, 2}, +}; + + +static int led_reg_val_to_light_mode(enum led_type type, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + + if (type != led_type_mode_data[i].type) + continue; + + if ((led_type_mode_data[i].type_mask & reg_val) == + led_type_mode_data[i].mode_mask) + { + return led_type_mode_data[i].mode; + } + } + + return 0; +} + +static u8 led_light_mode_to_reg_val(enum led_type type, + enum led_light_mode mode, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + if (type != led_type_mode_data[i].type) + continue; + + if (mode != led_type_mode_data[i].mode) + continue; + + reg_val = led_type_mode_data[i].mode_mask | + (reg_val & (~led_type_mode_data[i].type_mask)); + break; + } + + return reg_val; +} + +static void cs6436_54p_led_update(void) +{ + mutex_lock(&ledctl->update_lock); + + if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2) + || !ledctl->valid) { + int i; + + dev_dbg(&ledctl->pdev->dev, "Starting cs6436_54p_led update\n"); + + /* Update LED data + */ + for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) { + u8 status; + cig_cpld_read_register(led_reg[i], &status); + + if (status < 0) { + ledctl->valid = 0; + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg[i], status); + goto exit; + } + else + { + ledctl->reg_val[i] = status; + } + } + + ledctl->last_updated = jiffies; + ledctl->valid = 1; + } + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void cs6436_54p_led_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode, + u8 reg, enum led_type type) +{ + u8 reg_val; + mutex_lock(&ledctl->update_lock); + + cig_cpld_read_register(reg, ®_val); + if (reg_val < 0) { + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val); + goto exit; + } + + reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val); + + cig_cpld_write_register(reg, reg_val); + + /* to prevent the slow-update issue */ + ledctl->valid = 0; + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void cs6436_54p_led_fanx_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + enum led_type led_type1; + int reg_id; + int i, nsize; + int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s); + + for(i=0;iname); + + if (led_cdev->name[nsize-1] == fanx_info[i].cname) + { + led_type1 = fanx_info[i].type; + reg_id = fanx_info[i].reg_id; + + cs6436_54p_led_set(led_cdev, led_light_mode, led_reg[reg_id], led_type1); + return; + } + } +} + + +static enum led_brightness cs6436_54p_led_fanx_get(struct led_classdev *cdev) +{ + enum led_type led_type1; + int reg_id; + int i, nsize; + int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s); + + for(i=0;iname); + + if (cdev->name[nsize-1] == fanx_info[i].cname) + { + led_type1 = fanx_info[i].type; + reg_id = fanx_info[i].reg_id; + cs6436_54p_led_update(); + return led_reg_val_to_light_mode(led_type1, ledctl->reg_val[reg_id]); + } + } + + return led_reg_val_to_light_mode(LED_TYPE_FAN1, ledctl->reg_val[5]); +} + + +static void cs6436_54p_led_psu1_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs6436_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU1); +} + +static enum led_brightness cs6436_54p_led_psu1_get(struct led_classdev *cdev) +{ + cs6436_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU1, ledctl->reg_val[1]); +} + +static void cs6436_54p_led_psu2_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs6436_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU2); +} + +static enum led_brightness cs6436_54p_led_psu2_get(struct led_classdev *cdev) +{ + cs6436_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU2, ledctl->reg_val[1]); +} + +static void cs6436_54p_led_sys_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs6436_54p_led_set(led_cdev, led_light_mode,led_reg[0], LED_TYPE_SYS); +} + +static enum led_brightness cs6436_54p_led_sys_get(struct led_classdev *cdev) +{ + cs6436_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_SYS, ledctl->reg_val[0]); +} + + +static enum led_brightness cs6436_54p_led_fan_get(struct led_classdev *cdev) +{ + cs6436_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_FAN, ledctl->reg_val[1]); +} + +static void cs6436_54p_led_fan_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs6436_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_FAN); +} + + +static struct led_classdev cs6436_54p_leds[] = { + [LED_TYPE_SYS] = { + .name = "cs6436_54p_led::sys", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_sys_set, + .brightness_get = cs6436_54p_led_sys_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN] = { + .name = "cs6436_54p_led::fan", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_fan_set, + .brightness_get = cs6436_54p_led_fan_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + + [LED_TYPE_PSU1] = { + .name = "cs6436_54p_led::psu1", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_psu1_set, + .brightness_get = cs6436_54p_led_psu1_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU2] = { + .name = "cs6436_54p_led::psu2", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_psu2_set, + .brightness_get = cs6436_54p_led_psu2_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + + [LED_TYPE_FAN1] = { + .name = "cs6436_54p_led::fan1", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_fanx_set, + .brightness_get = cs6436_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN2] = { + .name = "cs6436_54p_led::fan2", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_fanx_set, + .brightness_get = cs6436_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN3] = { + .name = "cs6436_54p_led::fan3", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_fanx_set, + .brightness_get = cs6436_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN4] = { + .name = "cs6436_54p_led::fan4", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_fanx_set, + .brightness_get = cs6436_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN5] = { + .name = "cs6436_54p_led::fan5", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_fanx_set, + .brightness_get = cs6436_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + } +}; + +static int cs6436_54p_led_suspend(struct platform_device *dev, + pm_message_t state) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(cs6436_54p_leds); i++) { + led_classdev_suspend(&cs6436_54p_leds[i]); + } + + return 0; +} + +static int cs6436_54p_led_resume(struct platform_device *dev) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(cs6436_54p_leds); i++) { + led_classdev_resume(&cs6436_54p_leds[i]); + } + + return 0; +} + +static int cs6436_54p_led_probe(struct platform_device *pdev) +{ + int ret, i; + + for (i = 0; i < ARRAY_SIZE(cs6436_54p_leds); i++) { + ret = led_classdev_register(&pdev->dev, &cs6436_54p_leds[i]); + + if (ret < 0) + break; + } + + /* Check if all LEDs were successfully registered */ + if (i != ARRAY_SIZE(cs6436_54p_leds)) { + int j; + + /* only unregister the LEDs that were successfully registered */ + for (j = 0; j < i; j++) { + led_classdev_unregister(&cs6436_54p_leds[i]); + } + } + + return ret; +} + +static int cs6436_54p_led_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cs6436_54p_leds); i++) { + led_classdev_unregister(&cs6436_54p_leds[i]); + } + + return 0; +} + +static struct platform_driver cs6436_54p_led_driver = { + .probe = cs6436_54p_led_probe, + .remove = cs6436_54p_led_remove, + .suspend = cs6436_54p_led_suspend, + .resume = cs6436_54p_led_resume, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int cs6436_54p_led_default(void) +{ + cig_cpld_write_register(0x30, 0x40);// system green led solid on +} + +static int __init cs6436_54p_led_init(void) +{ + int ret; + + ret = platform_driver_register(&cs6436_54p_led_driver); + if (ret < 0) { + goto exit; + } + + ledctl = kzalloc(sizeof(struct cs6436_54p_led_data), GFP_KERNEL); + if (!ledctl) { + ret = -ENOMEM; + platform_driver_unregister(&cs6436_54p_led_driver); + goto exit; + } + + mutex_init(&ledctl->update_lock); + + ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(ledctl->pdev)) { + ret = PTR_ERR(ledctl->pdev); + platform_driver_unregister(&cs6436_54p_led_driver); + kfree(ledctl); + goto exit; + } + + cs6436_54p_led_default(); + +exit: + return ret; +} + +static void __exit cs6436_54p_led_exit(void) +{ + platform_device_unregister(ledctl->pdev); + platform_driver_unregister(&cs6436_54p_led_driver); + kfree(ledctl); +} + +module_init(cs6436_54p_led_init); +module_exit(cs6436_54p_led_exit); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs6436_54p_led driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-psu.c b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-psu.c new file mode 100644 index 000000000000..e8fc896ea13a --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-psu.c @@ -0,0 +1,943 @@ +/* + * A hwmon driver for the CIG cs6436-54P Power Module + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "i2c-algo-lpc.h" + + + +#define MAX_FAN_DUTY_CYCLE 100 + +/* Address scanned */ +static const unsigned short normal_i2c[] = {I2C_CLIENT_END }; + +/* This is additional data */ +struct cs6436_54p_psu_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; + unsigned long last_updated; /* In jiffies */ + + /* Registers value */ + u8 vout_mode; + u16 v_in; + u16 v_out; + u16 i_in; + u16 i_out; + u16 p_in; + u16 p_out; + u16 temp_input[3]; + u8 temp_fault; + u8 fan_fault; + u16 fan_duty_cycle[2]; + u16 fan_speed[2]; + u8 mfr_id[8]; + u8 mfr_model[20]; + u8 mfr_serial[20]; + u8 psu_is_present; + u8 psu_is_good; + struct i2c_client *client; + struct bin_attribute *bin; /* eeprom data */ +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask); +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count); +static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_fan_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_fan_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_temp_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_temp_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_vout_data(struct device *dev, struct device_attribute *dev_attr, char *buf); +static int cs6436_54p_psu_read_byte(struct i2c_client *client, u8 reg); +static int cs6436_54p_psu_read_word(struct i2c_client *client, u8 reg); +static int cs6436_54p_psu_write_word(struct i2c_client *client, u8 reg, u16 value); +static int cs6436_54p_psu_read_block(struct i2c_client *client, u8 command, u8 *data, int data_len); +static struct cs6436_54p_psu_data *cs6436_54p_psu_update_device(struct device *dev); +static ssize_t for_ascii(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf); + +enum cs6436_54p_psu_sysfs_attributes { + PSU_V_IN, + PSU_V_OUT, + PSU_I_IN, + PSU_I_OUT, + PSU_P_IN, + PSU_P_OUT, + PSU_TEMP1_INPUT, + PSU_TEMP2_INPUT, + PSU_TEMP3_INPUT, + PSU_TEMP_FAULT, + PSU_TEMP_WARN, + PSU_FAN1_FAULT, + PSU_FAN1_WARN, + PSU_FAN1_DUTY_CYCLE, + PSU_FAN1_SPEED, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_SERIAL, + PSU_PRESENT, + PSU_P_GOOD, +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + + bool is_negative = valid_data >> (valid_bit - 1); + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute \ + *dev_attr, const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct i2c_client *client = to_i2c_client(dev); + struct cs6436_54p_psu_data *data = i2c_get_clientdata(client); + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + if (data->valid != 1) + { + return -ENODEV; + } + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; + cs6436_54p_psu_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + if (data->valid != 1) + { + return -ENODEV; + } + + switch (attr->index) { + case PSU_V_IN: + value = data->v_in; + break; + case PSU_I_IN: + value = data->i_in; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_IN: + value = data->p_in; + break; + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp_input[0]; + break; + case PSU_TEMP2_INPUT: + value = data->temp_input[1]; + break; + case PSU_TEMP3_INPUT: + value = data->temp_input[2]; + break; + case PSU_FAN1_DUTY_CYCLE: + multiplier = 1; + value = data->fan_duty_cycle[0]; + break; + case PSU_FAN1_SPEED: + multiplier = 1; + value = data->fan_speed[0]; + break; + default: + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + + return (exponent >= 0) ? sprintf(buf, "%d\n", \ + (mantissa << exponent) * multiplier) : \ + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t for_fan_fault(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t for_fan_warning(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + u8 shift = (attr->index == PSU_FAN1_WARN) ? 5 : 4; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t for_temp_fault(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + + + return sprintf(buf, "%d\n", data->temp_fault >> 7); +} + +static ssize_t for_temp_warning(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + if (data->valid != 1) + { + return -ENODEV; + } + + + return sprintf(buf, "%d\n", data->temp_fault >> 6); +} +static ssize_t for_vout_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + int exponent, mantissa; + int multiplier = 1000; + if (data->valid != 1) + { + return -ENODEV; + } + + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + mantissa = data->v_out; + + return (exponent > 0) ? sprintf(buf, "%d\n", \ + (mantissa << exponent) * multiplier) : \ + sprintf(buf, "%d\n", ((mantissa * multiplier) >> (-exponent))); +} + +static ssize_t for_ascii(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + u8 *ptr = NULL; + + if (data->valid != 1) + { + return -ENODEV; + } + + switch (attr->index) { + case PSU_MFR_ID: + ptr = data->mfr_id + 1; + break; + case PSU_MFR_MODEL: + ptr = data->mfr_model + 1; + break; + case PSU_MFR_SERIAL: + ptr = data->mfr_serial + 1; + break; + default: + return 0; + } + return sprintf(buf, "%s\n", ptr); +} + + +static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + u8 *ptr = NULL; + + u8 status = 0; + + if (attr->index == PSU_PRESENT) { + status = data->psu_is_present; + } + else { /* PSU_POWER_GOOD */ + if (!data->valid) { + return -ENODEV; + } + + status = data->psu_is_good; + } + + return sprintf(buf, "%d\n", status); +} + + +static int cs6436_54p_psu_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int cs6436_54p_psu_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int cs6436_54p_psu_write_word(struct i2c_client *client, u8 reg, \ + u16 value) +{ + union i2c_smbus_data data; + data.word = value; + return i2c_smbus_xfer(client->adapter, client->addr, + client->flags |= I2C_CLIENT_PEC, + I2C_SMBUS_WRITE, reg, + I2C_SMBUS_WORD_DATA, &data); + +} + +static int cs6436_54p_psu_read_block(struct i2c_client *client, u8 command, \ + u8 *data, int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, + data); + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; +abort: + return result; + +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + + + +#define EEPROM_NAME "psu_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ + +/* Platform dependent --- */ +static ssize_t psu_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ + int status, retry = 3; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(100); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return data_len; + +} + + +static ssize_t psu_page_write(struct i2c_client *client,const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + + + while (count) { + ssize_t status; + + status = psu_eeprom_write(client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + + return retval; +} + + + +static ssize_t psu_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct cs6436_54p_psu_data *data; + ssize_t retval = 0; + struct i2c_client *client; + + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + client = to_i2c_client(container_of(kobj, struct device, kobj)); + + mutex_lock(&data->update_lock); + retval = psu_page_write(client, buf, off, count); + mutex_unlock(&data->update_lock); + return retval; +} + + +static ssize_t psu_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int status, retry = 3; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(100); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + goto abort; + } + if (unlikely(status != data_len)) { + status = -EIO; + goto abort; + } + +abort: + return status; +} + + + +static ssize_t psu_page_read(struct i2c_client *client,char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + printk("Count = 0, return"); + return count; + } + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + + + while (count) { + ssize_t status; + + status = psu_eeprom_read(client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + + return retval; + +} + + +static ssize_t psu_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct cs6436_54p_psu_data *data; + struct i2c_client *client; + ssize_t retval = 0; + + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + client = to_i2c_client(container_of(kobj, struct device, kobj)); + mutex_lock(&data->update_lock); + retval = psu_page_read(client, buf, off, count); + mutex_unlock(&data->update_lock); + + return retval; +} + + + +static int psu_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = psu_bin_read; + eeprom->write = psu_bin_write; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + + +static int psu_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + + +static int psu_i2c_check_functionality(struct i2c_client *client) +{ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_I2C_BLOCK); +} + + + +static int psu_eeprom_probe(struct i2c_client *client, const struct i2c_device_id *dev_id) +{ + int status; + + struct cs6436_54p_psu_data *data; + + if (!psu_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + data->bin = kzalloc(sizeof(struct bin_attribute), GFP_KERNEL); + if (!data->bin) { + status = -ENOMEM; + goto eeprom_bin_error; + } + + /* init eeprom */ + status = psu_sysfs_eeprom_init(&client->dev.kobj, data->bin); + if (status) { + status = -ENOMEM; + goto sys_init_error; + } + + dev_info(&client->dev, "psu eeprom '%s'\n", client->name); + + return 0; + + sys_init_error: + kfree(data->bin); + + eeprom_bin_error: + kfree(data); + + exit: + return status; +} + + + + +static struct cs6436_54p_psu_data *cs6436_54p_psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cs6436_54p_psu_data *data = i2c_get_clientdata(client); + + + mutex_lock(&data->update_lock); + + + if (time_after(jiffies, data->last_updated)) { + int i, status; + u8 command; + struct reg_data_byte regs_byte[] = { + {0x20, &data->vout_mode}, + {0x81, &data->fan_fault}, + {0x7d, &data->temp_fault}, + }; + struct reg_data_word regs_word[] = { + {0x88, &data->v_in}, + {0x8b, &data->v_out}, + {0x89, &data->i_in}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x97, &data->p_in}, + {0x8d, &(data->temp_input[0])}, + {0x8e, &(data->temp_input[1])}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x90, &(data->fan_speed[0])}, + }; + data->valid = 1; + + dev_dbg(&client->dev, "start data update\n"); + + /* one milliseconds from now */ + data->last_updated = jiffies + HZ / 1000; + + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = cs6436_54p_psu_read_byte(client, + regs_byte[i].reg); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + *(regs_byte[i].value) = 0; + data->valid = 0; + } else { + *(regs_byte[i].value) = status; + } + } + + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + status = cs6436_54p_psu_read_word(client, + regs_word[i].reg); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + *(regs_word[i].value) = 0; + data->valid = 0; + } else { + *(regs_word[i].value) = status; + } + } + + command = 0x99; /* PSU mfr_id */ + status = cs6436_54p_psu_read_block(client, command, + data->mfr_id, ARRAY_SIZE(data->mfr_id) - 1); + data->mfr_id[ARRAY_SIZE(data->mfr_id) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_id, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + command = 0x9a; /* PSU mfr_model */ + status = cs6436_54p_psu_read_block(client, command, + data->mfr_model, ARRAY_SIZE(data->mfr_model) - 1); + data->mfr_model[ARRAY_SIZE(data->mfr_model) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_model, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + command = 0x9e; /* PSU mfr_serial */ + status = cs6436_54p_psu_read_block(client, command, + data->mfr_serial, ARRAY_SIZE(data->mfr_serial) - 1); + data->mfr_serial[ARRAY_SIZE(data->mfr_serial) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_serial, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + data->psu_is_present = strlen(data->mfr_id) > 1 ? 1:0; + if(data->psu_is_present) + { + data->psu_is_good = ((data->fan_fault) || (data->temp_fault))? 0:1; + } + else + { + data->valid = 0; + data->psu_is_good = 0; + } + } + + mutex_unlock(&data->update_lock); + + return data; + +} + +/* sysfs attributes for hwmon */ +static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, for_linear_data, NULL, PSU_V_IN); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, for_vout_data, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, for_linear_data, NULL, PSU_I_IN); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, for_linear_data, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, for_linear_data, NULL, PSU_P_IN); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, for_linear_data, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp2_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP2_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp3_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP3_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, for_temp_fault, NULL, PSU_TEMP_FAULT); +static SENSOR_DEVICE_ATTR(psu_temp_warning, S_IRUGO, for_temp_warning, NULL, PSU_TEMP_WARN); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, for_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_fan1_warning, S_IRUGO, for_fan_warning, NULL, PSU_FAN1_WARN); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, for_linear_data, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, for_linear_data, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, for_ascii, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, for_ascii, NULL, PSU_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu_mfr_serial, S_IRUGO, for_ascii, NULL, PSU_MFR_SERIAL); +static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, for_status, NULL, PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, for_status, NULL, PSU_P_GOOD); + + + +static struct attribute *cs6436_54p_psu_attributes[] = { + &sensor_dev_attr_psu_v_in.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_in.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_in.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_temp2_input.dev_attr.attr, + &sensor_dev_attr_psu_temp3_input.dev_attr.attr, + &sensor_dev_attr_psu_temp_fault.dev_attr.attr, + &sensor_dev_attr_psu_temp_warning.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_fan1_warning.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_mfr_serial.dev_attr.attr, + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + NULL +}; + +static const struct attribute_group cs6436_54p_psu_group = { + .attrs = cs6436_54p_psu_attributes, +}; + + +static int psu_register_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int status; + + + struct cs6436_54p_psu_data *data; + + if (!psu_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &cs6436_54p_psu_group); + if (status) + goto exit_sysfs_create_group; + + cs6436_54p_sysfs_add_client(client); + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_hwmon_device_register; + } + + /* init eeprom */ + + return 0; + + exit_hwmon_device_register: + sysfs_remove_group(&client->dev.kobj, &cs6436_54p_psu_group); + exit_sysfs_create_group: + kfree(data); + exit: + return status; + +} + + +static int cs6436_54p_psu_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int status; + + if((client->addr == 0x52) ||(client->addr == 0x53)) + { + status = psu_eeprom_probe(client, id); + } + else if((client->addr == 0x5a) ||(client->addr == 0x5b)) + { + status = psu_register_probe(client, id); + } + return status; +} + +static int cs6436_54p_psu_remove(struct i2c_client *client) +{ + cs6436_54p_sysfs_remove_client(client); + + if((client->addr == 0x52) ||(client->addr == 0x53)) + { + struct cs6436_54p_psu_data *data; + data = i2c_get_clientdata(client); + psu_sysfs_eeprom_cleanup(&client->dev.kobj,data->bin); + kfree(data); + } + else if((client->addr == 0x5a) ||(client->addr == 0x5b)) + { + struct cs6436_54p_psu_data *data; + data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &cs6436_54p_psu_group); + kfree(data); + } + + return 0; +} + +enum psu_index +{ + cs6436_54p_psu1, + cs6436_54p_psu2 +}; + +static const struct i2c_device_id cs6436_54p_psu_id[] = { + { "cs6436_54p_psu1", cs6436_54p_psu1 }, + { "cs6436_54p_psu2", cs6436_54p_psu2 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, cs6436_54p_psu_id); + +static struct i2c_driver cs6436_54p_psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "cs6436_54p_psu", + }, + .probe = cs6436_54p_psu_probe, + .remove = cs6436_54p_psu_remove, + .id_table = cs6436_54p_psu_id, + .address_list = normal_i2c, +}; + +module_i2c_driver(cs6436_54p_psu_driver); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs6436_54p_psu driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sfp.c b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sfp.c new file mode 100644 index 000000000000..5d02bd849a5f --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sfp.c @@ -0,0 +1,1713 @@ +/* + * A hwmon driver for the CIG cs6436-54P SFP Module + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "i2c-algo-lpc.h" + +#define DRIVER_NAME "cs6436_54p_sfp" /* Platform dependent */ + +#define DEBUG_MODE 0 + +#if (DEBUG_MODE == 1) + #define DEBUG_PRINT(fmt, args...) \ + printk (KERN_INFO "%s:%s[%d]: " fmt "\r\n", __FILE__, __FUNCTION__, __LINE__, ##args) +#else + #define DEBUG_PRINT(fmt, args...) +#endif + +#define EEPROM_NAME "sfp_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ +#define BIT_INDEX(i) (1ULL << (i)) +#define USE_I2C_BLOCK_READ 1 /* Platform dependent */ +#define I2C_RW_RETRY_COUNT 3 +#define I2C_RW_RETRY_INTERVAL 100 /* ms */ + +#define SFP_EEPROM_A0_I2C_ADDR (0xA0 >> 1) +#define SFP_EEPROM_A2_I2C_ADDR (0xA2 >> 1) + +#define SFF8024_PHYSICAL_DEVICE_ID_ADDR 0x0 +#define SFF8024_DEVICE_ID_SFP 0x3 +#define SFF8024_DEVICE_ID_QSFP 0xC +#define SFF8024_DEVICE_ID_QSFP_PLUS 0xD +#define SFF8024_DEVICE_ID_QSFP28 0x11 + +#define SFF8472_DIAG_MON_TYPE_ADDR 92 +#define SFF8472_DIAG_MON_TYPE_DDM_MASK 0x40 +#define SFF8472_10G_ETH_COMPLIANCE_ADDR 0x3 +#define SFF8472_10G_BASE_MASK 0xF0 + +#define SFF8436_RX_LOS_ADDR 3 +#define SFF8436_TX_FAULT_ADDR 4 +#define SFF8436_TX_DISABLE_ADDR 86 +#define QSFP_RESET_ADDR 0x1b +#define QSFP_INTER_ADDR 0x1a +#define QSFP_LPMODE_ADDR 0x1c + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_port_type(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_present(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count);; +static ssize_t sfp_show_ddm_implemented(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_eeprom_read(struct i2c_client *, u8, u8 *,int); +static ssize_t sfp_eeprom_write(struct i2c_client *, u8 , const char *,int); +extern int cig_cpld_read_register(u8 reg_off, u8 *val); +extern int cig_cpld_write_register(u8 reg_off, u8 val); + +static ssize_t qsfp_reset_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_reset_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_inter_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_lpmode_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_lpmode_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + +enum sfp_sysfs_attributes { + PRESENT, + PRESENT_ALL, + PORT_NUMBER, + PORT_TYPE, + DDM_IMPLEMENTED, + TX_FAULT, + TX_FAULT1, + TX_FAULT2, + TX_FAULT3, + TX_FAULT4, + TX_DISABLE, + TX_DISABLE1, + TX_DISABLE2, + TX_DISABLE3, + TX_DISABLE4, + RX_LOS, + RX_LOS1, + RX_LOS2, + RX_LOS3, + RX_LOS4, + RX_LOS_ALL, + QSFPRESET, + QSFPINT, + QSFPLPMODE +}; + +/* SFP/QSFP common attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, PORT_NUMBER); +static SENSOR_DEVICE_ATTR(sfp_port_type, S_IRUGO, show_port_type, NULL, PORT_TYPE); +static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_present, NULL, PRESENT); +static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_present, NULL, PRESENT_ALL); +static SENSOR_DEVICE_ATTR(sfp_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS); +static SENSOR_DEVICE_ATTR(sfp_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, TX_DISABLE); +static SENSOR_DEVICE_ATTR(sfp_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, TX_FAULT); + +/* QSFP attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_rx_los1, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS1); +static SENSOR_DEVICE_ATTR(sfp_rx_los2, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS2); +static SENSOR_DEVICE_ATTR(sfp_rx_los3, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS3); +static SENSOR_DEVICE_ATTR(sfp_rx_los4, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS4); +static SENSOR_DEVICE_ATTR(sfp_tx_disable1, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE1); +static SENSOR_DEVICE_ATTR(sfp_tx_disable2, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE2); +static SENSOR_DEVICE_ATTR(sfp_tx_disable3, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE3); +static SENSOR_DEVICE_ATTR(sfp_tx_disable4, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE4); +static SENSOR_DEVICE_ATTR(sfp_tx_fault1, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT1); +static SENSOR_DEVICE_ATTR(sfp_tx_fault2, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT2); +static SENSOR_DEVICE_ATTR(sfp_tx_fault3, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT3); +static SENSOR_DEVICE_ATTR(sfp_tx_fault4, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT4); +static SENSOR_DEVICE_ATTR(sfp_reset, S_IWUSR | S_IRUGO, qsfp_reset_read, qsfp_reset_write, QSFPRESET); +static SENSOR_DEVICE_ATTR(sfp_inter, S_IRUGO, qsfp_inter_read, NULL, QSFPINT); +static SENSOR_DEVICE_ATTR(sfp_lpmode, S_IWUSR | S_IRUGO, qsfp_lpmode_read, qsfp_lpmode_write, QSFPLPMODE); +static struct attribute *qsfp_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_port_type.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los1.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los2.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los3.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault4.dev_attr.attr, + &sensor_dev_attr_sfp_reset.dev_attr.attr, + &sensor_dev_attr_sfp_inter.dev_attr.attr, + &sensor_dev_attr_sfp_lpmode.dev_attr.attr, + NULL +}; + +/* SFP msa attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_ddm_implemented, S_IRUGO, sfp_show_ddm_implemented, NULL, DDM_IMPLEMENTED); +static SENSOR_DEVICE_ATTR(sfp_rx_los_all, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS_ALL); +static struct attribute *sfp_msa_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_port_type.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_ddm_implemented.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los_all.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + NULL +}; + +/* SFP ddm attributes for sysfs */ +static struct attribute *sfp_ddm_attributes[] = { + NULL +}; + +/* Platform dependent +++ */ +#define CPLD_PORT_TO_FRONT_PORT(port) (port+1) + +enum port_numbers { +cs6436_54p_sfp1, cs6436_54p_sfp2, cs6436_54p_sfp3, cs6436_54p_sfp4, +cs6436_54p_sfp5, cs6436_54p_sfp6, cs6436_54p_sfp7, cs6436_54p_sfp8, +cs6436_54p_sfp9, cs6436_54p_sfp10, cs6436_54p_sfp11, cs6436_54p_sfp12, +cs6436_54p_sfp13, cs6436_54p_sfp14, cs6436_54p_sfp15, cs6436_54p_sfp16, +cs6436_54p_sfp17, cs6436_54p_sfp18, cs6436_54p_sfp19, cs6436_54p_sfp20, +cs6436_54p_sfp21, cs6436_54p_sfp22, cs6436_54p_sfp23, cs6436_54p_sfp24, +cs6436_54p_sfp25, cs6436_54p_sfp26, cs6436_54p_sfp27, cs6436_54p_sfp28, +cs6436_54p_sfp29, cs6436_54p_sfp30, cs6436_54p_sfp31, cs6436_54p_sfp32, +cs6436_54p_sfp33, cs6436_54p_sfp34, cs6436_54p_sfp35, cs6436_54p_sfp36, +cs6436_54p_sfp37, cs6436_54p_sfp38, cs6436_54p_sfp39, cs6436_54p_sfp40, +cs6436_54p_sfp41, cs6436_54p_sfp42, cs6436_54p_sfp43, cs6436_54p_sfp44, +cs6436_54p_sfp45, cs6436_54p_sfp46, cs6436_54p_sfp47, cs6436_54p_sfp48, +cs6436_54p_sfp49, cs6436_54p_sfp50, cs6436_54p_sfp51, cs6436_54p_sfp52, +cs6436_54p_sfp53, cs6436_54p_sfp54, cs6436_54p_sfp55, cs6436_54p_sfp56 +}; + +#define I2C_DEV_ID(x) { #x, x} + +static const struct i2c_device_id sfp_device_id[] = { +I2C_DEV_ID(cs6436_54p_sfp1), +I2C_DEV_ID(cs6436_54p_sfp2), +I2C_DEV_ID(cs6436_54p_sfp3), +I2C_DEV_ID(cs6436_54p_sfp4), +I2C_DEV_ID(cs6436_54p_sfp5), +I2C_DEV_ID(cs6436_54p_sfp6), +I2C_DEV_ID(cs6436_54p_sfp7), +I2C_DEV_ID(cs6436_54p_sfp8), +I2C_DEV_ID(cs6436_54p_sfp9), +I2C_DEV_ID(cs6436_54p_sfp10), +I2C_DEV_ID(cs6436_54p_sfp11), +I2C_DEV_ID(cs6436_54p_sfp12), +I2C_DEV_ID(cs6436_54p_sfp13), +I2C_DEV_ID(cs6436_54p_sfp14), +I2C_DEV_ID(cs6436_54p_sfp15), +I2C_DEV_ID(cs6436_54p_sfp16), +I2C_DEV_ID(cs6436_54p_sfp17), +I2C_DEV_ID(cs6436_54p_sfp18), +I2C_DEV_ID(cs6436_54p_sfp19), +I2C_DEV_ID(cs6436_54p_sfp20), +I2C_DEV_ID(cs6436_54p_sfp21), +I2C_DEV_ID(cs6436_54p_sfp22), +I2C_DEV_ID(cs6436_54p_sfp23), +I2C_DEV_ID(cs6436_54p_sfp24), +I2C_DEV_ID(cs6436_54p_sfp25), +I2C_DEV_ID(cs6436_54p_sfp26), +I2C_DEV_ID(cs6436_54p_sfp27), +I2C_DEV_ID(cs6436_54p_sfp28), +I2C_DEV_ID(cs6436_54p_sfp29), +I2C_DEV_ID(cs6436_54p_sfp30), +I2C_DEV_ID(cs6436_54p_sfp31), +I2C_DEV_ID(cs6436_54p_sfp32), +I2C_DEV_ID(cs6436_54p_sfp33), +I2C_DEV_ID(cs6436_54p_sfp34), +I2C_DEV_ID(cs6436_54p_sfp35), +I2C_DEV_ID(cs6436_54p_sfp36), +I2C_DEV_ID(cs6436_54p_sfp37), +I2C_DEV_ID(cs6436_54p_sfp38), +I2C_DEV_ID(cs6436_54p_sfp39), +I2C_DEV_ID(cs6436_54p_sfp40), +I2C_DEV_ID(cs6436_54p_sfp41), +I2C_DEV_ID(cs6436_54p_sfp42), +I2C_DEV_ID(cs6436_54p_sfp43), +I2C_DEV_ID(cs6436_54p_sfp44), +I2C_DEV_ID(cs6436_54p_sfp45), +I2C_DEV_ID(cs6436_54p_sfp46), +I2C_DEV_ID(cs6436_54p_sfp47), +I2C_DEV_ID(cs6436_54p_sfp48), +I2C_DEV_ID(cs6436_54p_sfp49), +I2C_DEV_ID(cs6436_54p_sfp50), +I2C_DEV_ID(cs6436_54p_sfp51), +I2C_DEV_ID(cs6436_54p_sfp52), +I2C_DEV_ID(cs6436_54p_sfp53), +I2C_DEV_ID(cs6436_54p_sfp54), +I2C_DEV_ID(cs6436_54p_sfp55), +I2C_DEV_ID(cs6436_54p_sfp56), +{ /* LIST END */ } +}; +MODULE_DEVICE_TABLE(i2c, sfp_device_id); + +/* + * list of valid port types + * note OOM_PORT_TYPE_NOT_PRESENT to indicate no + * module is present in this port + */ +typedef enum oom_driver_port_type_e { + OOM_DRIVER_PORT_TYPE_INVALID, + OOM_DRIVER_PORT_TYPE_NOT_PRESENT, + OOM_DRIVER_PORT_TYPE_SFP, + OOM_DRIVER_PORT_TYPE_SFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP, + OOM_DRIVER_PORT_TYPE_QSFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP28 +} oom_driver_port_type_t; + +enum driver_type_e { + DRIVER_TYPE_SFP_MSA, + DRIVER_TYPE_SFP_DDM, + DRIVER_TYPE_QSFP +}; + +/* Each client has this additional data + */ +struct eeprom_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + struct bin_attribute bin; /* eeprom data */ +}; + +struct sfp_msa_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u64 status[6]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss + 3 => device id + 4 => 10G Ethernet Compliance Codes + to distinguish SFP or SFP+ + 5 => DIAGNOSTIC MONITORING TYPE */ + struct eeprom_data eeprom; +}; + +struct sfp_ddm_data { + struct eeprom_data eeprom; +}; + +struct qsfp_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status[3]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss */ + + u8 device_id; + struct eeprom_data eeprom; +}; + +struct sfp_port_data { + struct mutex update_lock; + enum driver_type_e driver_type; + int port; /* CPLD port index */ + oom_driver_port_type_t port_type; + u64 present; /* present status, bit0:port0, bit1:port1 and so on */ + + struct sfp_msa_data *msa; + struct sfp_ddm_data *ddm; + struct qsfp_data *qsfp; + + struct i2c_client *client; +}; + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port)); +} + + + +static int cig_cpld_write_sfp_register(u8 sfp_reg_addr, u8 sfp_write_reg_data) +{ + u8 sfp_read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, sfp_reg_addr << 1); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_TX, sfp_write_reg_data); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + do{ + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &sfp_read_status); + udelay(60); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(sfp_read_status != 0x02); + + if(wait_time_out == 0) + return -1; + + return 1; +} + + +static int cig_cpld_read_sfp_register(u8 sfp_reg_addr, u8 *sfp_read_reg_data) +{ + u8 sfp_read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, sfp_reg_addr << 1 | 1); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + do{ + udelay(60); + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &sfp_read_status); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(sfp_read_status != 0x01); + + cig_cpld_read_register(ADDR_REG_SFP_STATUS_RX,sfp_read_reg_data); + + if(wait_time_out == 0) + return -1; + + return 1; +} + + + + + + +/* Platform dependent +++ */ +static struct sfp_port_data *sfp_update_present(struct i2c_client *client) +{ + int i = 0, j = 0, status = -1; + unsigned char cpld_reg_data = 0,cpld_reg_addr = 0; + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT("Starting sfp present status update"); + mutex_lock(&data->update_lock); + data->present = 0; + + udelay(6000); + + /* Read present status of port 1~48(SFP port) */ + for (i = 0; i < 6; i++) { + cpld_reg_addr = 1 + i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->present |= (u64)cpld_reg_data << (i*8); + + DEBUG_PRINT("Present status = 0x%lx\r\n", data->present); + } + + /* Read present status of port 49-56(QSFP port) */ + cpld_reg_addr = 25; + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + else { + data->present |= (u64)cpld_reg_data << 48; + } + + DEBUG_PRINT("Present status = 0x%lx", data->present); +exit: + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0, j = 0; + int status = -1; + unsigned char cpld_reg_data = 0,cpld_reg_addr = 0; + + if (time_before(jiffies, data->msa->last_updated + HZ + HZ / 2) && data->msa->valid) { + return data; + } + + DEBUG_PRINT("Starting cs6436_54p sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->msa->valid = 0; + memset(data->msa->status, 0, sizeof(data->msa->status)); + + udelay(6000); + + /* Read status of port 1~48(SFP port) */ + for (i = 0; i < 6; i++) { + cpld_reg_addr = 13+i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->msa->status[0] |= (u64)cpld_reg_data << (i * 8); + + DEBUG_PRINT("tx rx status[0] = 0x%lx\r\n", data->msa->status[0]); + } + + + for (i = 0; i < 6; i++) { + cpld_reg_addr = 19+i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->msa->status[1] |= (u64)cpld_reg_data << (i * 8); + + DEBUG_PRINT("tx rx status[1] = 0x%lx\r\n", data->msa->status[1]); + } + + for (i = 0; i < 6; i++) { + cpld_reg_addr = 7+i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->msa->status[2] |= (u64)cpld_reg_data << (i * 8); + + DEBUG_PRINT("tx rx status[2] = 0x%lx\r\n", data->msa->status[2]); + } + + data->msa->valid = 1; + data->msa->last_updated = jiffies; + +exit: + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + unsigned char cpld_reg_data = 0,cpld_reg_addr = 0,cpld_reg_bit = 0,cpld_reg_val = 0; + long disable; + int error; + + if (data->driver_type == DRIVER_TYPE_QSFP) { + return qsfp_set_tx_disable(dev, da, buf, count); + } + + error = kstrtol(buf, 10, &disable); + if (error) { + return error; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + + if(data->port <= 48) { + cpld_reg_addr = 19 + data->port / 8; + cpld_reg_bit = 1 << ((data->port) % 8); + } + + /* Read current status */ + error = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + + /* Update tx_disable status */ + if (disable) { + data->msa->status[1] |= BIT_INDEX(data->port); + cpld_reg_data |= cpld_reg_bit; + } + else { + data->msa->status[1] &= ~ BIT_INDEX(data->port); + cpld_reg_data &= ~cpld_reg_bit; + } + + error = cig_cpld_write_sfp_register(cpld_reg_addr,cpld_reg_data); + + mutex_unlock(&data->update_lock); + return count; +} +/* Platform dependent --- */ + +static int sfp_is_port_present(struct i2c_client *client, int port) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + + data = sfp_update_present(client); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + return !(data->present & BIT_INDEX(data->port)); /* Platform dependent */ +} + +/* Platform dependent +++ */ +static ssize_t show_present(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + + if (PRESENT_ALL == attr->index) { + int i; + u8 values[7] = {0}; + struct sfp_port_data *data = sfp_update_present(client); + + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + for (i = 0; i < ARRAY_SIZE(values); i++) { + values[i] = ~(u8)(data->present >> (i * 8)); + } + + /* Return values 1 -> 56 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5], + values[6]); + } + else { + struct sfp_port_data *data = i2c_get_clientdata(client); + int present = sfp_is_port_present(client, data->port); + + if (IS_ERR_VALUE(present)) { + return present; + } + + /* PRESENT */ + return sprintf(buf, "%d\n", present); + } +} +/* Platform dependent --- */ + +static struct sfp_port_data *sfp_update_port_type(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + u8 buf = 0; + int status; + + mutex_lock(&data->update_lock); + + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + { + status = sfp_eeprom_read(client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + if (buf != SFF8024_DEVICE_ID_SFP) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + status = sfp_eeprom_read(client, SFF8472_10G_ETH_COMPLIANCE_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("sfp port type (0x3) data = (0x%x)", buf); + data->port_type = buf & SFF8472_10G_BASE_MASK ? OOM_DRIVER_PORT_TYPE_SFP_PLUS : OOM_DRIVER_PORT_TYPE_SFP; + break; + } + case DRIVER_TYPE_QSFP: + { + status = sfp_eeprom_read(client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("qsfp port type (0x0) buf = (0x%x)", buf); + switch (buf) { + case SFF8024_DEVICE_ID_QSFP: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP; + break; + case SFF8024_DEVICE_ID_QSFP_PLUS: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; + break; + case SFF8024_DEVICE_ID_QSFP28: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; + break; + default: + data->port_type = buf; + break; + } + + break; + } + default: + break; + } + + mutex_unlock(&data->update_lock); + return data; +} + +static ssize_t show_port_type(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int present = sfp_is_port_present(client, data->port); + + if (IS_ERR_VALUE(present)) { + return present; + } + + if (!present) { + /* port is not present */ + return sprintf(buf, "%d\n", OOM_DRIVER_PORT_TYPE_NOT_PRESENT); + } + + sfp_update_port_type(dev); + return sprintf(buf, "%d\n", data->port_type); +} + +static struct sfp_port_data *qsfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i, status = -1; + u8 buf = 0; + u8 reg[] = {SFF8436_TX_FAULT_ADDR, SFF8436_TX_DISABLE_ADDR, SFF8436_RX_LOS_ADDR}; + + DEBUG_PRINT(""); + if (time_before(jiffies, data->qsfp->last_updated + HZ + HZ / 2) && data->qsfp->valid) { + return data; + } + + DEBUG_PRINT("Starting sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->qsfp->valid = 0; + memset(data->qsfp->status, 0, sizeof(data->qsfp->status)); + + DEBUG_PRINT(""); + /* Notify device to update tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); + if (unlikely(status < 0)) { + DEBUG_PRINT(""); + goto exit; + } + } + msleep(200); + DEBUG_PRINT(""); + + /* Read actual tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); + if (unlikely(status < 0)) { + DEBUG_PRINT(""); + goto exit; + } + + DEBUG_PRINT("qsfp reg(0x%x) status = (0x%x)", reg[i], data->qsfp->status[i]); + data->qsfp->status[i] = (buf & 0xF); + } + + DEBUG_PRINT(""); + data->qsfp->valid = 1; + data->qsfp->last_updated = jiffies; + +exit: + DEBUG_PRINT(""); + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static ssize_t qsfp_inter_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_INTER_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("inter read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + + +static ssize_t qsfp_reset_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_RESET_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("reset read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_reset_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + long usrdata; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + ret = kstrtol(buf, 10, &usrdata); + if (ret) { + return ret; + } + + usrdata = usrdata > 0 ? 1 : 0; + index = data->port - 48; + + DEBUG_PRINT("usrdata = %u, index = %hhu\n", usrdata, index); + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_RESET_ADDR, &cpld_reg_data); + if (ret == 1) + { + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + cpld_reg_data &= ~(1 << index); + cpld_reg_data |= usrdata << index; + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + ret = cig_cpld_write_sfp_register(QSFP_RESET_ADDR, cpld_reg_data); + if (1 != ret) + { + DEBUG_PRINT("write failed\n"); + } + } + else + { + DEBUG_PRINT("read failed\n"); + } + + mutex_unlock(&data->update_lock); + + if (ret != 1) + return -1; + + return count; +} + + + + +static ssize_t qsfp_lpmode_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_LPMODE_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("lpmode read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_lpmode_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + long usrdata; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + ret = kstrtol(buf, 10, &usrdata); + if (ret) { + return ret; + } + + usrdata = usrdata > 0 ? 1 : 0; + index = data->port - 48; + + DEBUG_PRINT("usrdata = %u, index = %hhu\n", usrdata, index); + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_LPMODE_ADDR, &cpld_reg_data); + if (ret == 1) + { + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + cpld_reg_data &= ~(1 << index); + cpld_reg_data |= usrdata << index; + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + ret = cig_cpld_write_sfp_register(QSFP_LPMODE_ADDR, cpld_reg_data); + if (1 != ret) + { + DEBUG_PRINT("write failed\n"); + } + } + else + { + DEBUG_PRINT("read failed\n"); + } + + mutex_unlock(&data->update_lock); + + if (ret != 1) + return -1; + + return count; +} + + + +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + int present; + u8 val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT(""); + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + DEBUG_PRINT(""); + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + DEBUG_PRINT(""); + data = qsfp_update_tx_rx_status(dev); + DEBUG_PRINT(""); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + DEBUG_PRINT(""); + switch (attr->index) { + case TX_FAULT: + val = !!(data->qsfp->status[2] & 0xF); + break; + case TX_FAULT1: + case TX_FAULT2: + case TX_FAULT3: + case TX_FAULT4: + val = !!(data->qsfp->status[2] & BIT_INDEX(attr->index - TX_FAULT1)); + break; + case TX_DISABLE: + val = data->qsfp->status[1] & 0xF; + break; + case TX_DISABLE1: + case TX_DISABLE2: + case TX_DISABLE3: + case TX_DISABLE4: + val = !!(data->qsfp->status[1] & BIT_INDEX(attr->index - TX_DISABLE1)); + break; + case RX_LOS: + val = !!(data->qsfp->status[0] & 0xF); + break; + case RX_LOS1: + case RX_LOS2: + case RX_LOS3: + case RX_LOS4: + val = !!(data->qsfp->status[0] & BIT_INDEX(attr->index - RX_LOS1)); + break; + default: + break; + } + + DEBUG_PRINT(""); + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + long disable; + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + status = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(status)) { + return status; + } + + if (!status) { + /* port is not present */ + return -ENXIO; + } + + status = kstrtol(buf, 10, &disable); + if (status) { + return status; + } + + data = qsfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + mutex_lock(&data->update_lock); + + if (attr->index == TX_DISABLE) { + data->qsfp->status[1] = disable & 0xF; + } + else {/* TX_DISABLE1 ~ TX_DISABLE4*/ + if (disable) { + data->qsfp->status[1] |= (1 << (attr->index - TX_DISABLE1)); + } + else { + data->qsfp->status[1] &= ~(1 << (attr->index - TX_DISABLE1)); + } + } + + DEBUG_PRINT("index = (%d), status = (0x%x)", attr->index, data->qsfp->status[1]); + status = sfp_eeprom_write(data->client, SFF8436_TX_DISABLE_ADDR, &data->qsfp->status[1], sizeof(data->qsfp->status[1])); + if (unlikely(status < 0)) { + count = status; + } + + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t sfp_show_ddm_implemented(struct device *dev, struct device_attribute *da, + char *buf) +{ + int status; + char ddm; + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + status = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(status)) { + return status; + } + + if (status == 0) { + /* port is not present */ + return -ENODEV; + } + + status = sfp_eeprom_read(client, SFF8472_DIAG_MON_TYPE_ADDR, &ddm, sizeof(ddm)); + if (unlikely(status < 0)) { + return status; + } + + return sprintf(buf, "%d\n", !!(ddm & SFF8472_DIAG_MON_TYPE_DDM_MASK)); +} + +/* Platform dependent +++ */ +static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + u8 val = 0, index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT("driver type = (%d)", data->driver_type); + if (data->driver_type == DRIVER_TYPE_QSFP) { + DEBUG_PRINT(""); + return qsfp_show_tx_rx_status(dev, da, buf); + } + + DEBUG_PRINT(""); + data = sfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + if(attr->index == RX_LOS_ALL) { + int i = 0; + u8 values[6] = {0}; + + for (i = 0; i < ARRAY_SIZE(values); i++) { + values[i] = (u8)(data->msa->status[2] >> (i * 8)); + } + + /** Return values 1 -> 48 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5]); + } + + switch (attr->index) { + case TX_FAULT: + index = 0; + break; + case TX_DISABLE: + index = 1; + break; + case RX_LOS: + index = 2; + break; + default: + break; + } + + val = !!(data->msa->status[index] & BIT_INDEX(data->port)); + return sprintf(buf, "%d\n", val); +} +/* Platform dependent --- */ +static ssize_t sfp_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int status, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return data_len; +#else + int status, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, command, *data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return 1; +#endif + + +} + +static ssize_t sfp_port_write(struct sfp_port_data *data, + const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_write(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; +} + + +static ssize_t sfp_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct sfp_port_data *data; + DEBUG_PRINT("%s(%d) offset = (%d), count = (%d)", off, count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + present = sfp_is_port_present(data->client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + return sfp_port_write(data, buf, off, count); +} + +static ssize_t sfp_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int status, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + goto abort; + } + if (unlikely(status != data_len)) { + status = -EIO; + goto abort; + } + + //result = data_len; + +abort: + return status; +#else + int status, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, command); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, status); + goto abort; + } + + *data = (u8)status; + status = 1; + +abort: + return status; +#endif +} + +static ssize_t sfp_port_read(struct sfp_port_data *data, + char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + DEBUG_PRINT("Count = 0, return"); + return count; + } + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_read(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; + +} + +static ssize_t sfp_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct sfp_port_data *data; + DEBUG_PRINT("offset = (%d), count = (%d)", off, count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + present = sfp_is_port_present(data->client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + return sfp_port_read(data, buf, off, count); +} + +static int sfp_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = sfp_bin_read; + eeprom->write = sfp_bin_write; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + +static int sfp_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + +static const struct attribute_group sfp_msa_group = { + .attrs = sfp_msa_attributes, +}; + +static int sfp_i2c_check_functionality(struct i2c_client *client) +{ +#if USE_I2C_BLOCK_READ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK); +#else + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA); +#endif +} + +static int sfp_msa_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_msa_data **data) +{ + int status; + struct sfp_msa_data *msa; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + msa = kzalloc(sizeof(struct sfp_msa_data), GFP_KERNEL); + if (!msa) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_msa_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &msa->eeprom.bin); + if (status) { + goto exit_remove; + } + + *data = msa; + dev_info(&client->dev, "sfp msa '%s'\n", client->name); + + cs6436_54p_sysfs_add_client(client); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); +exit_free: + kfree(msa); +exit: + + return status; +} + +static const struct attribute_group sfp_ddm_group = { + .attrs = sfp_ddm_attributes, +}; + +static int sfp_ddm_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_ddm_data **data) +{ + int status; + struct sfp_ddm_data *ddm; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + ddm = kzalloc(sizeof(struct sfp_ddm_data), GFP_KERNEL); + if (!ddm) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_ddm_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &ddm->eeprom.bin); + if (status) { + goto exit_remove; + } + + *data = ddm; + dev_info(&client->dev, "sfp ddm '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); +exit_free: + kfree(ddm); +exit: + + return status; +} + +static const struct attribute_group qsfp_group = { + .attrs = qsfp_attributes, +}; + +static int qsfp_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct qsfp_data **data) +{ + int status; + struct qsfp_data *qsfp; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + qsfp = kzalloc(sizeof(struct qsfp_data), GFP_KERNEL); + if (!qsfp) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &qsfp_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &qsfp->eeprom.bin); + if (status) { + goto exit_remove; + } + + /* Bring QSFPs out of reset */ + //cig_lpc_write(0x62, 0x15, 0x3F); + + *data = qsfp; + dev_info(&client->dev, "qsfp '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &qsfp_group); +exit_free: + kfree(qsfp); +exit: + + return status; +} + +/* Platform dependent +++ */ +static int sfp_device_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct sfp_port_data *data = NULL; + + data = kzalloc(sizeof(struct sfp_port_data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->port = dev_id->driver_data; + data->client = client; + + if (dev_id->driver_data >= cs6436_54p_sfp1 && dev_id->driver_data <= cs6436_54p_sfp48) { + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_SFP_MSA; + return sfp_msa_probe(client, dev_id, &data->msa); + } + else if (client->addr == SFP_EEPROM_A2_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_SFP_DDM; + return sfp_ddm_probe(client, dev_id, &data->ddm); + } + } + else { /* cs6436_54p_sfp49 ~ cs6436_54p_sfp56 */ + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_QSFP; + return qsfp_probe(client, dev_id, &data->qsfp); + } + } + + return -ENODEV; +} +/* Platform dependent --- */ + +static int sfp_msa_remove(struct i2c_client *client, struct sfp_msa_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); + kfree(data); + return 0; +} + +static int sfp_ddm_remove(struct i2c_client *client, struct sfp_ddm_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); + kfree(data); + return 0; +} + +static int qfp_remove(struct i2c_client *client, struct qsfp_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &qsfp_group); + kfree(data); + return 0; +} + +static int sfp_device_remove(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + + cs6436_54p_sysfs_remove_client(client); + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + return sfp_msa_remove(client, data->msa); + case DRIVER_TYPE_SFP_DDM: + return sfp_ddm_remove(client, data->ddm); + case DRIVER_TYPE_QSFP: + return qfp_remove(client, data->qsfp); + } + + return 0; +} + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +static struct i2c_driver cs6436_54p_sfp_driver = { + .driver = { + .name = DRIVER_NAME, + }, + .probe = sfp_device_probe, + .remove = sfp_device_remove, + .id_table = sfp_device_id, + .address_list = normal_i2c, +}; + +module_i2c_driver(cs6436_54p_sfp_driver); + + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs6436_54p_sfp driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sysfs.c b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sysfs.c new file mode 100644 index 000000000000..1383fcfd40f3 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sysfs.c @@ -0,0 +1,335 @@ +/* + * A hwmon driver for the CIG cs6436-54P sysfs Module + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "i2c-algo-lpc.h" + + +static LIST_HEAD(sysfs_client_list); +static struct mutex list_lock; + +struct sysfs_client_node { + struct i2c_client *client; + struct list_head list; +}; + +#define DEVICE_NAME "cigfs" +static int dev_major; +static struct class *dev_class; +static struct cdev *dev_cdev; +static struct device *dev_device; +static struct class *psu_class; +static struct class *sfp_class; + + +void cs6436_54p_sysfs_add_client(struct i2c_client *client) +{ + struct sysfs_client_node *node = kzalloc(sizeof(struct sysfs_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate sysfs_client_node (0x%x)\n", client->addr); + return; + } + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &sysfs_client_list); + mutex_unlock(&list_lock); +} + +EXPORT_SYMBOL(cs6436_54p_sysfs_add_client); + +void cs6436_54p_sysfs_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (IS_ERR(sysfs_node)) + { + break; + } + if (sysfs_node->client == client) { + found = 1; + break; + } + } + if (found) { + list_del(list_node); + kfree(sysfs_node); + } + + mutex_unlock(&list_lock); +} + +EXPORT_SYMBOL(cs6436_54p_sysfs_remove_client); + +struct class * cs6436_54p_sysfs_create_symclass(char *cls_name) +{ + int rc = 0; + struct class *my_class; +/**************************************************************************************/ + my_class = class_create(THIS_MODULE,cls_name); + if (IS_ERR(my_class)) { + pr_err("failed to create my class\n"); + } + return my_class; + +/**************************************************************************************/ +} + +void cs6436_54p_sysfs_delete_symclass(struct class *my_class) +{ +/**************************************************************************************/ + + if (IS_ERR(my_class)) { + pr_err("Pointer is invaild\n"); + } + class_destroy(my_class); + +/**************************************************************************************/ +} + + + + + +int cs6436_54p_sysfs_create_symlink(struct class *my_class,char * driver_name,char *device_name) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int ret = -EPERM; + int rc = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (!strcmp(sysfs_node->client->name,driver_name)) { + rc = sysfs_create_link(&my_class->p->subsys.kobj, &sysfs_node->client->dev.kobj,device_name); + if(rc) + { + pr_err("failed to create symlink %d\n",rc); + } + break; + } + } + mutex_unlock(&list_lock); + return ret; +} + + +int cs6436_54p_sysfs_delete_symlink(struct class *my_class,char * driver_name,char *device_name) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int ret = -EPERM; + int rc = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (!strcmp(sysfs_node->client->name,driver_name)) { + sysfs_remove_link(&my_class->p->subsys.kobj,device_name); + break; + } + } + mutex_unlock(&list_lock); + return ret; +} + + +static int cs6436_54p_sysfs_open(struct inode *inode, struct file *file) +{ + return 0; +} + + + +static ssize_t cs6436_54p_sysfs_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) +{ + char str[10],name[18],port[8]; + int ret; + int i; + memset(str, 0, sizeof(str)); + ret = copy_from_user(str, buf, count); + if (ret) + { + printk(KERN_ERR "copy_from_user fail\n"); + return -EINVAL; + } + + if(!strncmp(str,"start",5)) + { + psu_class = cs6436_54p_sysfs_create_symclass("psu"); + cs6436_54p_sysfs_create_symlink(psu_class,"cs6436_54p_psu1","psu1"); + cs6436_54p_sysfs_create_symlink(psu_class,"cs6436_54p_psu2","psu2"); + sfp_class = cs6436_54p_sysfs_create_symclass("swps"); + for(i = 1; i <= 48;i++) + { + memset(name,0xff,sizeof(name)); + memset(port,0xff,sizeof(port)); + snprintf(name,sizeof(name),"cs6436_54p_sfp%d",i); + snprintf(port,sizeof(port),"port%d",i); + cs6436_54p_sysfs_create_symlink(sfp_class,name,port); + } + } + else if(!strncmp(str,"stop",4)) + { + cs6436_54p_sysfs_delete_symlink(psu_class,"cs6436_54p_psu1","psu1"); + cs6436_54p_sysfs_delete_symlink(psu_class,"cs6436_54p_psu2","psu2"); + cs6436_54p_sysfs_delete_symclass(psu_class); + + for(i = 1; i <= 48;i++) + { + memset(name,0xff,sizeof(name)); + memset(port,0xff,sizeof(port)); + snprintf(name,sizeof(name),"cs6436_54p_sfp%d",i); + snprintf(port,sizeof(port),"port%d",i); + cs6436_54p_sysfs_delete_symlink(sfp_class,name,port); + } + cs6436_54p_sysfs_delete_symclass(sfp_class); + } + return count; +} + + +static struct file_operations cs6436_54p_sysfs_fops = { + .owner = THIS_MODULE, + .open = cs6436_54p_sysfs_open, + .write = cs6436_54p_sysfs_write, +}; + + +static int __init cs6436_54p_sysfs_init(void) +{ + int result = 0; + int err = 0; + dev_t dev = MKDEV(dev_major, 0); + + if (dev_major) + result = register_chrdev_region(dev, 1, DEVICE_NAME); + else { + result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME); + dev_major = MAJOR(dev); + } + if (result < 0) + { + printk("unable to get major %d\n", dev_major); + err= -EINVAL; + } + printk("get major is %d\n", dev_major); + if (dev_major == 0) + dev_major = result; + + dev_cdev= kmalloc(sizeof(struct cdev), GFP_KERNEL); + if(IS_ERR(dev_cdev)) { + err= -ENOMEM; + } + + cdev_init(dev_cdev, &cs6436_54p_sysfs_fops); + dev_cdev->owner = THIS_MODULE; + dev_cdev->ops = &cs6436_54p_sysfs_fops; + err = cdev_add(dev_cdev, dev, 1); + if (err) + { + printk("error %d add fpga ", err); + goto err_malloc; + } + + dev_class = class_create(THIS_MODULE, DEVICE_NAME); + if (IS_ERR(dev_class)) + { + printk("Err:failed in creating class.\n"); + goto err_cdev_add; + } + + dev_device = device_create(dev_class, NULL, MKDEV(dev_major, 0), NULL, DEVICE_NAME); + if (IS_ERR(dev_device)) + { + printk("Err:failed in creating device.\n"); + goto err_class_crt; + } + + mutex_init(&list_lock); + + return err; + + err_class_crt: + cdev_del(dev_cdev); + err_cdev_add: + kfree(dev_cdev); + err_malloc: + unregister_chrdev_region(MKDEV(dev_major,0), 1); + + return err; + +} + +static void __exit cs6436_54p_sysfs_exit(void) +{ + cdev_del(dev_cdev); + printk("cdev_del ok\n"); + device_destroy(dev_class, MKDEV(dev_major, 0)); + + class_destroy(dev_class); + + if(dev_cdev != NULL) + kfree(dev_cdev); + + unregister_chrdev_region(MKDEV(dev_major, 0), 1); + printk("cs6436_54p_sysfs_exit...\r\n"); +} + + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs6436-54p-sysfs driver"); +MODULE_LICENSE("GPL"); + +module_init(cs6436_54p_sysfs_init); +module_exit(cs6436_54p_sysfs_exit); + + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-init.service b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-init.service new file mode 100644 index 000000000000..ad18c2c2703a --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-init.service @@ -0,0 +1,13 @@ +[Unit] +Description=Cig CS6436-54P Platform initialization service +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/cig_cs6436_util.py install +ExecStop=/usr/local/bin/cig_cs6436_util.py clean +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-misc.service b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-misc.service new file mode 100644 index 000000000000..33f99935cd95 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-misc.service @@ -0,0 +1,15 @@ +[Unit] +Description=Cig CS6436-54P Platform miscellaneous service +After=cs6436-platform-init.service +DefaultDependencies=no + +[Service] +ExecStart=/usr/local/bin/cig_cs6436_misc.py +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/setup.py b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/setup.py new file mode 100755 index 000000000000..05ee2c6e36ac --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='cs6436-54p', + version='1.0.0', + description='Module to initialize Cig CS6436-54P platforms', + + packages=['cs6436-54p'], + package_dir={'cs6436-54p': 'cs6436-54p/classes'}, + ) diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_misc.py b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_misc.py new file mode 100755 index 000000000000..c186676cbf3f --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_misc.py @@ -0,0 +1,574 @@ +#!/usr/bin/env python +# +# Copyright (C) 2018 Cambridge, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import os +import commands +import sys, getopt +import logging +import re +import time +import datetime +from collections import namedtuple +from threading import Thread + +DEBUG = False +i2c_prefix = '/sys/bus/i2c/devices/' +leds_prefix = '/sys/devices/platform/cs6436_54p_led/leds/' +fans_prefix = '/sys/devices/platform/cs6436_54p_fan/' +fansdir_prefix = fans_prefix + 'fan{}_direction' + +ageing_controlfile = '/etc/sonic/agcontrol' +AGFlag = 0 + + +platform_misc_log = '/var/log/platform_misc.log' +misclogger = logging.getLogger('platform_misc') +misclogger.setLevel(logging.INFO) +miscformatter = logging.Formatter('%(asctime)s-%(levelname)s-%(message)s') + +if not os.path.isfile(platform_misc_log): + try: + os.mknod(platform_misc_log) + except: + print 'Failed to creat platform_misc.log' + +fileHandler = logging.FileHandler(platform_misc_log) +fileHandler.setLevel(logging.INFO) +fileHandler.setFormatter(miscformatter) +misclogger.addHandler(fileHandler) + + +starttime = datetime.datetime.now() +IsGetlswt = 0 +coretemp_prefix = '/sys/class/hwmon/hwmon1/' +coretemp_ps = [] +psu1_p = '/sys/bus/i2c/devices/5-005a/psu_present' +psu2_p = '/sys/bus/i2c/devices/5-005b/psu_present' +psu1_d = '/sys/bus/i2c/devices/5-0052/psu_eeprom' +psu2_d = '/sys/bus/i2c/devices/5-0053/psu_eeprom' +psu1led_d = leds_prefix + 'cs6436_54p_led::psu1/brightness' +psu2led_d = leds_prefix + 'cs6436_54p_led::psu2/brightness' +cs6436_ledpath = {'fan':leds_prefix + 'cs6436_54p_led::fan/brightness', + 'fan1':leds_prefix + 'cs6436_54p_led::fan1/brightness', + 'fan2':leds_prefix + 'cs6436_54p_led::fan2/brightness', + 'fan3':leds_prefix + 'cs6436_54p_led::fan3/brightness', + 'fan4':leds_prefix + 'cs6436_54p_led::fan4/brightness', + 'fan5':leds_prefix + 'cs6436_54p_led::fan5/brightness', + 'psu1':leds_prefix + 'cs6436_54p_led::psu1/brightness', + 'psu2':leds_prefix + 'cs6436_54p_led::psu2/brightness', + 'sys':leds_prefix + 'cs6436_54p_led::sys/brightness'} + + +def system_read_filestr(node): + with open(node, 'r') as f: + try: + str = f.read() + except IOError as e: + misclogger.error('Failed to get node, str={}'.format(node)) + return "0" + return str + + +def system_bright_leds(dev, colour): + global AGFlag + + if AGFlag == 1: + return + + cmd = 'echo {} > {}'.format(colour, dev) + log_os_system(cmd, 1) + return + +''' +1: front in tail out +0: front out tail in +''' +def system_getpsu_direction(dev): + try: + with open(dev) as f: + f.seek(0x30) + str = f.read(2) + except IOError as e: + misclogger.error('Failed to get psu eep') + return 1 + if str == 'AA': ## front in tail out + return 1 + elif str == 'RA':## tail in front out + return 0 + else: + misclogger.error('Failed to get psu eep, str={}'.format(str)) + return -1 + + +def system_get_cputype(): + cmdretfd = os.popen("lscpu | grep 'Model name'") + retstring = cmdretfd.read() + endindex = retstring.find('@') - 1 + startindex = retstring[:endindex].rfind(' ') + 1 + cputype = retstring[startindex:endindex] + + return cputype + + +def system_init_coretemppath(): + global coretemp_ps + + cmdstr = "ls {} | grep 'input'".format(coretemp_prefix) + cmdretfd = os.popen(cmdstr) + + coretemppss = cmdretfd.read().splitlines() + if len(coretemppss) < 3: + cputype = system_get_cputype() + misclogger.error('Failed to init core temperature path.' + ' cpu type = {}, num thermal = {}'.format(cputype, len(coretemp_ps))) + return 1 + + for i in range(0,3): + coretemp_ps.append(coretemp_prefix + coretemppss[i]) + + print coretemp_ps + + return 0 + + +class cs6436_fanattr: + def __init__(self, name): + self.name = name + self.direction = 0 + self.direction_p = '' + self.rear = 0 + self.rear_p = '' + self.front = 0 + self.front_p = '' + self.fault = 0 + self.fault_p = '' + self.status = 0 + self.setpath() + self.updatedevice() + + return + + def setpath(self): + self.direction_p = fans_prefix + '{}_direction'.format(self.name) + self.rear_p = fans_prefix + '{}_rear_speed_rpm'.format(self.name) + self.front_p = fans_prefix + '{}_front_speed_rpm'.format(self.name) + self.fault_p = fans_prefix + '{}_fault'.format(self.name) + + return + + def updatedevice(self): + self.direction = int(system_read_filestr(self.direction_p)) + self.rear = int(system_read_filestr(self.rear_p)) + self.front = int(system_read_filestr(self.front_p)) + self.fault = int(system_read_filestr(self.fault_p)) + + return + + def checkspeedrpm(self, speedrpm): + frontrpmexp = speedrpm * 21000 / 100 + rearrpmexp = speedrpm * 19000 / 100 + deviationfront = abs(frontrpmexp - self.front) / float(frontrpmexp) + deviationrear = abs(rearrpmexp - self.rear) / float(rearrpmexp) + + if deviationfront < 0.3 and deviationrear < 0.3: + return 0 + else: + misclogger.error(':{} speed wrong. frontexp is {}, but rpm is {}.rearexp is {}, but rpm is {}'.format(self.name, frontrpmexp, self.front, rearrpmexp, self.rear)) + return 1 + + def checkstatus(self, speedrpm, totaldirct): + speedstatus = self.checkspeedrpm(speedrpm) + if self.direction != totaldirct: + self.status = 1 + misclogger.error(':{} direction = {}.fan direction is not ok.'.format(self.name, self.direction)) + elif speedstatus != 0: + self.status = 1 + elif self.fault != 0: + misclogger.error(':{} fault.'.format(self.name)) + self.status = 1 + else: + self.status = 0 + + if self.status == 1: + system_bright_leds(cs6436_ledpath[self.name], 3) + else: + system_bright_leds(cs6436_ledpath[self.name], 1) + + return self.status + +cs6436_fanattrnodes = [] + + +class cs6436_psuattr: + def __init__(self, name): + self.name = name + self.direction = 0 + self.direction_p = '' + self.present = 0 + self.present_p = '' + self.status = 0 + + self.setpath() + self.updatepresent() + self.updatedirection() + + return + + def setpath(self): + if self.name == 'psu1': + self.present_p = psu1_p + self.direction_p = psu1_d + if self.name == 'psu2': + self.present_p = psu2_p + self.direction_p = psu2_d + + return + + def updatepresent(self): + self.present = int(system_read_filestr(self.present_p)) + + return + + def updatedirection(self): + if self.present == 1: + self.direction = system_getpsu_direction(self.direction_p) + else: + self.direction = 2 + + return + + def checkstatus(self, totaldirct): + if self.present != 1: + self.status = 1 + misclogger.error(':{} not present.'.format(self.name)) + elif self.direction == 2: + self.status = 0 + misclogger.info(':{} direction need to be update.'.format(self.name)) + elif self.direction != totaldirct: + self.status = 1 + misclogger.info(':{} direction is wrong.'.format(self.name)) + else: + self.status = 0 + + if self.status == 1: + system_bright_leds(cs6436_ledpath[self.name], 3) + else: + system_bright_leds(cs6436_ledpath[self.name], 1) + + return self.status + +cs6436_psuattrnodes = [] + + + +def my_log(txt): + if DEBUG == True: + print "[ROY]"+txt + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"5-005a", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"5-005b", 0) + ret3, log = log_os_system("ls "+leds_prefix+"cs6436_54p_led*", 0) + return not(ret1 or ret2 or ret3) + + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + + +def system_get_coretemp(): + temp1 = system_read_filestr(coretemp_ps[0]).strip() + temp2 = system_read_filestr(coretemp_ps[1]).strip() + temp3 = system_read_filestr(coretemp_ps[2]).strip() + + return int(temp1), int(temp2), int(temp3) + +def system_get_boardtemp(): + for i in range(0,16): + temp1path = "/sys/bus/i2c/devices/5-004a/hwmon/hwmon%d/temp1_input" % i + if os.access(temp1path, os.F_OK): + break + for i in range(0,16): + temp2path = "/sys/bus/i2c/devices/5-004b/hwmon/hwmon%d/temp1_input" % i + if os.access(temp2path, os.F_OK): + break + temp1 = system_read_filestr(temp1path).strip() + temp2 = system_read_filestr(temp2path).strip() + + return int(temp1), int(temp2) + + +def system_get_lswtemp(): + global IsGetlswt + global starttime + if IsGetlswt == 0: + now = datetime.datetime.now() + misclogger.info("time wait.") + misclogger.info("start = {}, now = {}.".format(starttime, now)) + if (now - starttime).seconds > 150: + misclogger.info("time = ".format((now - starttime).seconds)) + IsGetlswt = 1 + + return 25 + +# chp = subprocess.Popen("docker ps --filter name=syncd", shell=True, stdout=subprocess.PIPE) +# if chp.poll() == None: +# misclogger.info("No subp.") +# chp.kill() +# +# return 25 + +# retstring = chp.stdout.read() +# chp.kill() +# if 'Up' not in retstring: +# misclogger.info("lsw not up.") +# +# return 25 + + status, output = log_os_system('npx_diag swc show temperature', 1) + if status: + misclogger.error('failed to show lsw temperature') + + return 25 + + output = output.strip() + if output.find("it 0, temperature ") > 0: + startindex = output.find('temperature') + len('temperature') + 1 + endindex = output[startindex:].find(" ") + endindex = startindex + endindex + temp = output[startindex:endindex] + b = temp.find('.') + if b > 0: + temp=temp[:b] + temp = int(temp) + else: + misclogger.error("Failed to get temperature.") + temp = 0 + + return int(temp) + +def system_monitor_temperature(): + + ctemp1, ctemp2, ctemp3 = system_get_coretemp() + btemp1, btemp2 = system_get_boardtemp() + ltemp = system_get_lswtemp() + fan_speed_str = system_cs6436_getfanexspeed() + fan_speed = int(fan_speed_str) + policy = 'stay' + pos = 0 + #speed c1 c2 c3 b1 b2 lsw + fan_policy_up = ([30, 40000, 40000, 40000, 42000, 35000, 95], + [40, 44000, 44000, 44000, 44000, 39000, 96], + [50, 49000, 49000, 49000, 47000, 44000, 91], + [60, 52000, 52000, 52000, 51500, 47500, 92], + [70, 53000, 53000, 53000, 52000, 49000, 93], + [100,999999,999999,999999,999999,999999,999]) + + fan_policy_down=([30, 0, 0, 0, 0, 0, 0], + [40, 34000, 34000, 34000, 34000, 30000, 80], + [50, 38000, 38000, 38000, 37000, 33000, 81], + [60, 44000, 44000, 44000, 43000, 39000, 84], + [70, 44000, 44000, 44000, 43000, 40000, 84], + [100, 48000, 48000, 48000, 46000, 42000, 85],) + + for policytable in fan_policy_up: + if fan_speed <= policytable[0]: + break + pos = pos + 1 + fan_speed = policytable[0] + if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]): + policy = 'stay' + policytable = fan_policy_down[pos] + if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]): + policy = 'down' + else: + policy = 'up' + + if policy == 'up': + misclogger.info("speed = %d." % fan_speed) + misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3)) + misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2)) + misclogger.info("lsw = %d" % ltemp) + fan_speed = fan_policy_down[pos + 1][0] + misclogger.info("fan policy: up. speedexp = {}".format(fan_speed)) + + if policy == 'stay': + fan_speed = fan_policy_down[pos] + return + + if policy == 'down': + misclogger.info("speed = %d." % fan_speed) + misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3)) + misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2)) + misclogger.info("lsw = %d" % ltemp) + fan_speed = fan_policy_down[pos - 1][0] + misclogger.info("fan policy: down.speedexp = {}".format(fan_speed)) + + cmd = "echo {} > /sys/devices/platform/cs6436_54p_fan/fan_duty_cycle_percentage".format(fan_speed) + status, output = log_os_system(cmd, 1) + if status: + misclogger.error("set fan speed fault") + + return + + +def system_cs6436_setfanexspeed(num): + fanspeednode = fans_prefix + 'fan_duty_cycle_percentage' + numstr = str(num) + with open(fanspeednode, 'w') as f: + f.write(numstr) + + +def system_cs6436_getfanexspeed(): + fanspeednode = fans_prefix + 'fan_duty_cycle_percentage' + fanspeedstr = system_read_filestr(fanspeednode) + fanspeedexp = int(fanspeedstr) + + return fanspeedexp + + +def system_cs6436_getdirection(): + global cs6436_fanattrnodes + direction = 0 + + for fan in cs6436_fanattrnodes: + direction = direction + fan.direction + + if direction > 2: + direction = 1 + else: + direction = 0 + + return direction + + +def system_check_psusdirection(): + global cs6436_psuattrnodes + cs6436totaldirct = system_cs6436_getdirection() + psutatus = 0 + + for psu in cs6436_psuattrnodes: + psu.updatedirection() + psu.checkstatus(cs6436totaldirct) + psutatus = psu.status + psutatus + + return (psutatus != 0) + + +def system_check_psuspresent(): + global cs6436_psuattrnodes + cs6436totaldirct = system_cs6436_getdirection() + psutatus = 0 + + for psu in cs6436_psuattrnodes: + psu.updatepresent() + psu.checkstatus(cs6436totaldirct) + psutatus = psu.status + psutatus + + return (psutatus != 0) + + +def system_check_fansstate(): + global cs6436_fanattrnodes + global cs6436_ledpath + cs6436totaldirct = system_cs6436_getdirection() + fanstatus = 0 + fanexspeed = 0 + + fanexspeed = system_cs6436_getfanexspeed() + + for fan in cs6436_fanattrnodes: + fan.updatedevice() + fan.checkstatus(fanexspeed, cs6436totaldirct) + fanstatus = fanstatus + fan.status + + if fanstatus > 0: + misclogger.error(':fan error.set fans speed 100.') + system_cs6436_setfanexspeed(100) + system_bright_leds(cs6436_ledpath['fan'], 3) + else: + system_bright_leds(cs6436_ledpath['fan'], 1) + + return (fanstatus != 0) + + +def system_misc_polling(threadName,delay): + for count in range(1,5): + if device_exist() == False: + time.sleep(delay+3) + print "%s: %s, count=%d" % ( threadName, time.ctime(time.time()), count) + else: + break + + if count == 4: + return + + status, output = log_os_system("echo 1 > /sys/devices/platform/cs6436_54p_led/leds/cs6436_54p_led::sys/brightness", 1) + status, output = log_os_system("hwconfig -cfp 1", 1) + + global AGFlag + if os.access(ageing_controlfile, os.F_OK): + AGFlag = 1 + else: + AGFlag = 0 + + os.system('csw_daemon &') + + + global cs6436_fanattrnodes + global cs6436_psuattrnodes + + for num in range(1,6): + name = 'fan{}'.format(num) + fannode = cs6436_fanattr(name) + cs6436_fanattrnodes.append(fannode) + for num in range(1,3): + name = 'psu{}'.format(num) + psunode = cs6436_psuattr(name) + cs6436_psuattrnodes.append(psunode) + + tempcontrol = system_init_coretemppath() + + misclogger.info("%s: %s misc start." % ( threadName, time.ctime(time.time()))) + count = 0 + while 1: + count = count + 1 + ret = system_check_psuspresent() + ret = system_check_fansstate() + + if count % 10 == 0: + misclogger.info(": adjust fans and check psu direction.") + system_check_psusdirection() + if tempcontrol == 0: + system_monitor_temperature() + count = 0 + time.sleep(delay) + + return + +if __name__ == '__main__': + target=system_misc_polling("Thread-misc",10) + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_util.py b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_util.py new file mode 100755 index 000000000000..81e6bb7c0b6b --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_util.py @@ -0,0 +1,565 @@ +#!/usr/bin/env python +# +# Copyright (C) 2018 Cambridge, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +from collections import namedtuple + + + + +PROJECT_NAME = 'cs6436_54p' +version = '0.1.1' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +DEVICE_NO = {'led':9, 'fan':5, 'thermal':4, 'psu':2, 'sfp':54} +FORCE = 0 +CPU_TYPE = 'C3308' + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + device_traversal() + elif arg == 'sff': + if len(args)!=2: + show_eeprom_help() + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + show_eeprom_help() + else: + show_eeprom(args[1]) + return + elif arg == 'set': + if len(args)<3: + show_set_help() + else: + set_device(args[1:]) + return + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_set_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print cmd +" [led|sfp|fan]" + print " use \""+ cmd + " led 0-4 \" to set led color" + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-54 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + +def show_eeprom_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print " use \""+ cmd + " 1-54 \" to dump sfp# eeprom" + sys.exit(0) + +def my_log(txt): + if DEBUG == True: + print "[ROY]"+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_check(): + for count in range(1,5): + time.sleep(1) + ret, lsmod = log_os_system("lsmod| grep i2c_i801", 0) + if len(lsmod) > 2: + log_os_system("rmmod i2c_i801", 0) + break + + ret, lsmod = log_os_system("lsmod| grep i2c_designware_platform", 0) + if len(lsmod) > 2: + log_os_system("rmmod i2c_designware_platform", 0) + log_os_system("modprobe i2c-designware-platform", 0) + + ret, lsmod = log_os_system("lsmod| grep cig", 0) + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + return True + + + +kos = [ + 'depmod', + 'modprobe i2c_dev', + 'modprobe i2c_mux_pca954x force_deselect_on_exit=1', + 'modprobe x86-64-cig-cs6436-54p-sysfs ' , + 'modprobe x86-64-cig-cs6436-54p-cpld ' , + 'modprobe x86-64-cig-cs6436-54p-fan' , + 'modprobe x86-64-cig-cs6436-54p-psu' , + 'modprobe x86-64-cig-cs6436-54p-sfp' , + 'modprobe x86-64-cig-cs6436-54p-led' ] + +def driver_install(): + global FORCE + + for i in range(0,len(kos)): + if i == 4: + ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 32-39 | head -n 1", 0) + if CPU_TYPE=='i3-6100U': + kos[i] =kos[i] + 'board_id=1' + ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 36-40 | head -n 1", 0) + if CPU_TYPE=='C3758' or CPU_TYPE=='C3308': + kos[i] =kos[i] + 'board_id=2' + + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + +def driver_uninstall(): + global FORCE + for i in range(0,len(kos)): + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + +led_prefix ='/sys/class/leds/'+PROJECT_NAME+'_led::' +hwmon_types = {'led': ['sys','fan','fan1','fan2','fan3','fan4','fan5','psu1','psu2']} +hwmon_nodes = {'led': ['brightness'] } +hwmon_prefix ={'led': led_prefix} + +i2c_prefix = '/sys/bus/i2c/devices/' +i2c_bus = {'thermal': ['4-0048','4-0049', '5-004a', '5-004b'] , + 'psu': ['5-005a','5-005b'], + 'sfp': ['-0050']} +i2c_nodes = {'thermal': ['hwmon/hwmon*/temp1_input'] , + 'psu': ['psu_present ', 'psu_power_good'] , + 'sfp': ['sfp_is_present ', 'sfp_tx_disable']} + +fan_prefix ='/sys/bus/platform/devices/'+PROJECT_NAME+'_fan' +fan_types = {'fan': ['fan1','fan2', 'fan3', 'fan4', 'fan5']} +fan_nodes = {'fan': ['state', 'front_speed_rpm', 'rear_speed_rpm', 'fault']} + + +sfp_map = [8,9,10,11,12,13,14,15,16, + 17,18,19,20,21,22,23,24,25,26, + 27,28,29,30,31,32,33,34,35,36, + 37,38,39,40,41,42,43,44,45,46, + 47,48,49,50,51,52,53,54,55,56, + 57,60,61,62,63] + +mknod =[ + 'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-4/new_device', + 'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-4/new_device', + 'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs6436_54p_psu1 0x5a > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs6436_54p_psu2 0x5b > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs6436_54p_psu1 0x52 > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs6436_54p_psu2 0x53 > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo 24c128 0x57 > /sys/bus/i2c/devices/i2c-7/new_device'] + +port = 0 + +def device_install(): + global FORCE + global port + + for i in range(0,len(mknod)): + #all nodes need times to built new i2c buses + time.sleep(1) + + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + + for i in range(0,len(sfp_map)): + if (i == 50): + port = port + 3 + else: + port = port + 1 + + + status, output =log_os_system("echo cs6436_54p_sfp"+str(port)+" 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + + if port <= 48: + status, output =log_os_system("echo cs6436_54p_sfp"+str(port)+" 0x51 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + + return + +def device_uninstall(): + global FORCE + + for i in range(0,len(sfp_map)): + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" + status, output =log_os_system("echo 0x50 > "+ target, 1) + if status: + print output + if FORCE == 0: + return status + + nodelist = mknod + + for i in range(len(nodelist)): + target = nodelist[-(i+1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + if status: + print output + if FORCE == 0: + return status + + return + +def system_ready(): + if driver_check() == False: + return False + if not device_exist(): + return False + return True + +def do_install(): + print "Checking system...." + if driver_check() == False: + print "No driver, installing...." + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" drivers detected...." + if not device_exist(): + print "No device, installing...." + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" devices detected...." + return + +def do_uninstall(): + print "Checking system...." + if not device_exist(): + print PROJECT_NAME.upper() +" has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_check()== False : + print PROJECT_NAME.upper() +" has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + +def devices_info(): + global DEVICE_NO + global ALL_DEVICE + global i2c_bus, hwmon_types, fan_types + for key in DEVICE_NO: + ALL_DEVICE[key]= {} + for i in range(0,DEVICE_NO[key]): + ALL_DEVICE[key][key+str(i+1)] = [] + + for key in i2c_bus: + buses = i2c_bus[key] + nodes = i2c_nodes[key] + for i in range(0,len(buses)): + for j in range(0,len(nodes)): + if 'sfp' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + else: + node = key+str(i+1) + path = i2c_prefix+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + + for key in hwmon_types: + itypes = hwmon_types[key] + nodes = hwmon_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + for key in fan_types: + itypes = fan_types[key] + nodes = fan_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = fan_prefix+"/"+ itypes[i]+"_"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + #show dict all in the order + if DEBUG == True: + for i in sorted(ALL_DEVICE.keys()): + print(i+": ") + for j in sorted(ALL_DEVICE[i].keys()): + print(" "+j) + for k in (ALL_DEVICE[i][j]): + print(" "+" "+k) + return + +def show_eeprom(index): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] + node = node.replace(node.split("/")[-1], 'sfp_eeprom') + # check if got hexdump command in current environment + ret, log = log_os_system("which hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) + if len(log): + hex_cmd = 'hexdump' + elif len(log2): + hex_cmd = ' busybox hexdump' + else: + log = 'Failed : no hexdump cmd!!' + logging.info(log) + print log + return 1 + + print node + ":" + ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) + if ret==0: + print log + else: + print "**********device no found**********" + return + +def set_device(args): + global DEVICE_NO + global ALL_DEVICE + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + + if args[0]=='led': + if int(args[1])>4: + show_set_help() + return + #print ALL_DEVICE['led'] + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): + ret, log = log_os_system("echo "+args[1]+" >"+k, 1) + if ret: + return ret + elif args[0]=='fan': + if int(args[1])>100: + show_set_help() + return + #print ALL_DEVICE['fan'] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan'] ['fan1'][0] + node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage') + ret, log = log_os_system("cat "+ node, 1) + if ret==0: + print ("Previous fan duty: " + log.strip() +"%") + ret, log = log_os_system("echo "+args[1]+" >"+node, 1) + if ret==0: + print ("Current fan duty: " + args[1] +"%") + return ret + elif args[0]=='sfp': + if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: + show_set_help() + return + if len(args)<2: + show_set_help() + return + + if int(args[2])>1: + show_set_help() + return + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: + ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) + if ret: + return ret + + return + +def get_value(input): + digit = re.findall('\d+', input) + return int(digit[0]) + + +def get_ledname(ledx): + name_table={'led1':'SYS','led2':'FSTUS','led3':'FAN1','led4':'FAN2','led5':'FAN3','led6':'FAN4','led7':'FAN5','led8':'PSU1','led9':'PSU2'} + if name_table.has_key(ledx): + name = name_table[ledx] + else: + name = ledx + return name + + +def device_traversal(): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + for i in sorted(ALL_DEVICE.keys()): + print("============================================") + print(i.upper()+": ") + print("============================================") + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + nwnamex = get_ledname(j) + if nwnamex == j: + print " "+j+":", + else: + print " "+nwnamex+":", + for k in (ALL_DEVICE[i][j]): + ret, log = log_os_system("cat "+k, 0) + func = k.split("/")[-1].strip() + func = re.sub(j+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) + if ret==0: + print func+"="+log+" ", + else: + print func+"="+"X"+" ", + print + print("----------------------------------------------------------------") + + + print + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"*0077", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"i2c-3", 0) + return not(ret1 or ret2) + + +if __name__ == "__main__": + main() diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/Makefile b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/Makefile old mode 100755 new mode 100644 index cdb114aad510..b0b4f1f7df06 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/Makefile +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/Makefile @@ -1,4 +1,5 @@ -obj-m := x86-64-cig-cs6436-56p-cpld.o \ +obj-m :=x86-64-cig-cs6436-56p-sysfs.o \ + x86-64-cig-cs6436-56p-cpld.o \ x86-64-cig-cs6436-56p-fan.o \ x86-64-cig-cs6436-56p-led.o \ x86-64-cig-cs6436-56p-psu.o \ diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc.h b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc.h old mode 100755 new mode 100644 index 7ce6ae378596..9f1acd52ea68 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc.h +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc.h @@ -65,7 +65,7 @@ #define I2C_LPC_CLK3 0x00 #define I2C_LPC_CLK443 0x10 #define I2C_LPC_CLK6 0x14 -#define I2C_LPC_CLK 0x18 +#define I2C_LPC_CLK 0x18 #define I2C_LPC_CLK12 0x1c /* ----- transmission frequencies ------------------------------------- */ @@ -94,4 +94,129 @@ #define I2C_LPC_REG_DATA_TX3 0x8c #define I2C_LPC_REG_DATA_TX4 0x8d -#endif /* I2C_LPC_H */ + +#define ADDR_REG_SFP_STATUS_ADDR 0X62 //reg addr +R/W# //1031 +#define ADDR_REG_SFP_STATUS_TX 0X63 // write data +#define ADDR_REG_SFP_STATUS_RX 0X64 //read data +#define ADDR_REG_SFP_STATUS_COMMAND 0X65 //cmd bit7=1,go +#define ADDR_REG_SFP_STATUS_STATUS 0X66 //status + +#define CPLD_MASTER_INTERRUPT_STATUS_REG 0x20 +#define CPLD_MASTER_INTERRUPT_MASK_REG 0x21 +#define CPLD_MASTER_INTERRUPT_ALL 0x3f +#define CPLD_MASTER_INTERRUPT_CPLD2 0x20 +#define CPLD_MASTER_INTERRUPT_CPLD1 0x10 +#define CPLD_MASTER_INTERRUPT_PSU2 0x08 +#define CPLD_MASTER_INTERRUPT_PSU1 0x04 +#define CPLD_MASTER_INTERRUPT_6320 0x02 +#define CPLD_MASTER_INTERRUPT_LSW 0x01 + + + +#define CPLD_SLAVE1_INTERRUPT_STATUS_L_REG 0x20 +#define CPLD_SLAVE1_INTERRUPT_STATUS_H_REG 0x21 +#define CPLD_SLAVE2_INTERRUPT_STATUS_L_REG 0x22 +#define CPLD_SLAVE2_INTERRUPT_STATUS_H_REG 0x23 +#define CPLD_SLAVE1_INTERRUPT_MASK_REG 0x24 +#define CPLD_SLAVE2_INTERRUPT_MASK_REG 0x25 + + +#define CPLD_SLAVE1_PRESENT08_REG 0x01 +#define CPLD_SLAVE1_PRESENT16_REG 0x02 +#define CPLD_SLAVE1_PRESENT24_REG 0x03 +#define CPLD_SLAVE2_PRESENT32_REG 0x04 +#define CPLD_SLAVE2_PRESENT40_REG 0x05 +#define CPLD_SLAVE2_PRESENT48_REG 0x06 + +#define CPLD_SLAVE1_RX_LOST08_REG 0x07 +#define CPLD_SLAVE1_RX_LOST16_REG 0x08 +#define CPLD_SLAVE1_RX_LOST24_REG 0x09 +#define CPLD_SLAVE2_RX_LOST32_REG 0x0a +#define CPLD_SLAVE2_RX_LOST40_REG 0x0b +#define CPLD_SLAVE2_RX_LOST48_REG 0x0c + +#define CPLD_SLAVE1_TX_FAULT08_REG 0x0d +#define CPLD_SLAVE1_TX_FAULT16_REG 0x0e +#define CPLD_SLAVE1_TX_FAULT24_REG 0x0f +#define CPLD_SLAVE2_TX_FAULT32_REG 0x10 +#define CPLD_SLAVE2_TX_FAULT40_REG 0x11 +#define CPLD_SLAVE2_TX_FAULT48_REG 0x12 + +#define CPLD_SLAVE2_PRESENT56_REG 0x19 +#define CPLD_SLAVE2_QSFP_CR56_REG 0x1a + + +#define CPLD_SLAVE1_INTERRUPT_PRESENT08 0x0001 +#define CPLD_SLAVE1_INTERRUPT_PRESENT16 0x0002 +#define CPLD_SLAVE1_INTERRUPT_PRESENT24 0x0004 +#define CPLD_SLAVE2_INTERRUPT_PRESENT32 0x0001 +#define CPLD_SLAVE2_INTERRUPT_PRESENT40 0x0002 +#define CPLD_SLAVE2_INTERRUPT_PRESENT48 0x0004 + +#define CPLD_SLAVE2_INTERRUPT_QSFP_CR56 0x0200 +#define CPLD_SLAVE2_INTERRUPT_PRESENT56 0x0400 + +#define CPLD_SLAVE1_INTERRUPT_RX_LOST08 0x0008 +#define CPLD_SLAVE1_INTERRUPT_RX_LOST16 0x0010 +#define CPLD_SLAVE1_INTERRUPT_RX_LOST24 0x0020 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST32 0x0008 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST40 0x0010 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST48 0x0020 + +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT08 0x0040 +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT16 0x0080 +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT24 0x0100 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT32 0x0040 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT40 0x0080 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT48 0x0100 + + + + + + + +#define WAIT_TIME_OUT_COUNT 100 + + +struct i2c_algo_lpc_data { + void *data; /* private data for lolevel routines */ + void (*setlpc) (void *data, int ctl, int val); + int (*getlpc) (void *data, int ctl); + int (*getown) (void *data); + int (*getclock) (void *data); + void (*waitforpin) (void *data); + + int (*xfer_begin) (void *data); + int (*xfer_end) (void *data); + + /* Multi-master lost arbitration back-off delay (msecs) + * This should be set by the bus adapter or knowledgable client + * if bus is multi-mastered, else zero + */ + unsigned long lab_mdelay; +}; + + +struct subsys_private { + struct kset subsys; + struct kset *devices_kset; + struct list_head interfaces; + struct mutex mutex; + + struct kset *drivers_kset; + struct klist klist_devices; + struct klist klist_drivers; + struct blocking_notifier_head bus_notifier; + unsigned int drivers_autoprobe:1; + struct bus_type *bus; + + struct kset glue_dirs; + struct class *class; +}; + +void cs6436_56p_sysfs_add_client(struct i2c_client *client); +void cs6436_56p_sysfs_remove_client(struct i2c_client *client); + + +#endif /* I2C_LPC8584_H */ diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc2iic.h b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc2iic.h old mode 100755 new mode 100644 diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-cpld.c b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-cpld.c old mode 100755 new mode 100644 index a3c6e2db54eb..dcff94085f09 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-cpld.c +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-cpld.c @@ -17,8 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - #include #include #include @@ -32,7 +30,6 @@ #include #include #include "i2c-algo-lpc.h" -#include "i2c-algo-lpc2iic.h" #include #include #include @@ -41,11 +38,9 @@ #include #include #include -#include #include #include #include -#include #include #include #include @@ -56,6 +51,20 @@ # include #endif +#include +#include +#include +#include +#include +#include +#include + + + + + +/********************************************** Start ********************************************************/ + /* * ISA bus. */ @@ -65,7 +74,7 @@ static void platform_isa_bus_release(struct device * dev) return ; } - + static struct device isa_bus = { .init_name = "lpc-isa", .release = platform_isa_bus_release, @@ -76,9 +85,9 @@ struct isa_dev { struct device *next; unsigned int id; }; - -#define to_isa_dev(x) container_of((x), struct isa_dev, dev) - + +#define to_isa_dev(x) container_of((x), struct isa_dev, dev) + static int isa_bus_match(struct device *dev, struct device_driver *driver) { struct isa_driver *isa_driver = to_isa_driver(driver); @@ -223,7 +232,7 @@ int lpc_register_driver(struct isa_driver *isa_driver, unsigned int ndev) return error; } - + int lpc_bus_init(void) { int error; @@ -246,28 +255,36 @@ void lpc_bus_exit(void) } +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ /* * module parameters: */ static int i2c_debug = 0; static struct mutex lpc_lock; - -#define DEB2(x) if (i2c_debug >= 2) x -#define DEB3(x) if (i2c_debug >= 3) x + +#define DEB2(x) if (i2c_debug == 2) x +#define DEB3(x) if (i2c_debug == 3) x /* print several statistical values */ -#define DEBPROTO(x) if (i2c_debug >= 9) x; - /* debug the protocol by showing transferred bits */ +#define DEBPROTO(x) if (i2c_debug == 9) x; + /* debug the protocol by showing transferred bits */ #define DEF_TIMEOUT 160 - - - -/* setting states on the bus with the right timing: */ - + + + +/* setting states on the bus with the right timing: */ + #define set_lpc(adap, ctl, val) adap->setlpc(adap->data, ctl, val) #define get_lpc(adap, ctl) adap->getlpc(adap->data, ctl) -#define get_own(adap) adap->getown(adap->data) -#define get_clock(adap) adap->getclock(adap->data) +#define get_own(adap) adap->getown(adap->data) +#define get_clock(adap) adap->getclock(adap->data) #define i2c_outaddr(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DEVICE_ADDR, val) #define i2c_outbyte1(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX1, val) @@ -278,54 +295,52 @@ static struct mutex lpc_lock; #define i2c_inbyte2(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX2) #define i2c_inbyte3(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX3) #define i2c_inbyte4(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX4) - + #define LPC_FPRINTF_LOG_PATH "/tmp/file.log" struct file *lpc_fprintf_file = NULL; - static int lpc_fprintf_debug(const char *fmt, ...) { char lpc_fprintf_buf[256]={0}; - struct va_format vaf; va_list args; int r; - unsigned int file_size = 0; mm_segment_t old_fs; struct timeval tv; + struct rtc_time tm; + do_gettimeofday(&tv); + rtc_time_to_tm(tv.tv_sec,&tm); + va_start(args, fmt); vaf.fmt = fmt; vaf.va = &args; - r=snprintf(lpc_fprintf_buf,"[%012d.%012d] %pV\n",sizeof(lpc_fprintf_buf),tv.tv_sec, tv.tv_usec, &vaf); + r=snprintf(lpc_fprintf_buf,sizeof(lpc_fprintf_buf),"[%04d.%08d] %pV\n",tm.tm_sec, (int)tv.tv_usec, &vaf); va_end(args); - old_fs = get_fs(); set_fs(KERNEL_DS); - lpc_fprintf_file->f_op->write(lpc_fprintf_file, (char *)lpc_fprintf_buf, strlen(lpc_fprintf_buf), &lpc_fprintf_file->f_pos); + vfs_write(lpc_fprintf_file, (char *)&lpc_fprintf_buf, strlen(lpc_fprintf_buf), &lpc_fprintf_file->f_pos); set_fs(old_fs); - memset(lpc_fprintf_buf,0x0,sizeof(lpc_fprintf_buf)); return r; } + static int lpc_fprintf_init(void) { - mm_segment_t old_fs; - - DEB2(printk("lpc_fprintf_init.\n");) - + printk("lpc_fprintf_init.\n"); if(lpc_fprintf_file == NULL) lpc_fprintf_file = filp_open(LPC_FPRINTF_LOG_PATH, O_RDWR | O_APPEND | O_CREAT, 0644); + if (IS_ERR(lpc_fprintf_file)) { - DEB2(printk("error occured while opening file %s, exiting...\n", LPC_FPRINTF_LOG_PATH);) - return 0; + printk("Error occured while opening file %s, exiting...\n", LPC_FPRINTF_LOG_PATH); + return -1; } return 0; @@ -333,10 +348,11 @@ static int lpc_fprintf_init(void) static int lpc_fprintf_exit(void) { - DEB2(printk("lpc_fprintf_exit.\n");) + printk("lpc_fprintf_exit.\n"); if(lpc_fprintf_file != NULL) filp_close(lpc_fprintf_file, NULL); + return 0; } @@ -366,14 +382,13 @@ void print_reg(struct i2c_algo_lpc_data *adap) static void i2c_repstart(struct i2c_algo_lpc_data *adap) { - DEBPROTO(lpc_fprintf_debug(" Sr\n")); + DEBPROTO(lpc_fprintf_debug("%s :\n",__func__);) set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_REPSTART); } static void i2c_stop(struct i2c_algo_lpc_data *adap) { DEBPROTO(lpc_fprintf_debug("%s :\n",__func__);) - set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_STOP); udelay(60); set_lpc(adap, I2C_LPC_REG_COMMAND, 0x00); @@ -384,60 +399,56 @@ static void i2c_stop(struct i2c_algo_lpc_data *adap) static void i2c_start(struct i2c_algo_lpc_data *adap) { - unsigned char status; - int timeout = DEF_TIMEOUT; - print_reg(adap); set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_START); print_reg(adap); - } static int wait_for_bb(struct i2c_algo_lpc_data *adap) -{ - - int timeout = DEF_TIMEOUT; - int status; - +{ + + int timeout = DEF_TIMEOUT; + int status; + while (--timeout) { status = get_lpc(adap, I2C_LPC_REG_STATUS); - + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus free status : %x\n",__func__,status);) - + if(status == I2C_LPC_TD) { DEBPROTO(lpc_fprintf_debug("%s : Bus is free status : %x\n",__func__,status);) break; } - } - - if (timeout == 0) { + } + + if (timeout == 0) { DEBPROTO(lpc_fprintf_debug("%s : Timeout for free busy status : %x\n",__func__,status);) - return -ETIMEDOUT; - } + return -ETIMEDOUT; + } + - - - return 0; + + return 0; } static int wait_for_be(int mode,struct i2c_algo_lpc_data *adap) -{ - - int timeout = DEF_TIMEOUT; - unsigned char status; - +{ + + int timeout = DEF_TIMEOUT; + unsigned char status; + while (--timeout) { - + status = get_lpc(adap, I2C_LPC_REG_STATUS); - + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus empty status : %x\n",__func__,status);) if(mode == 1) @@ -446,42 +457,42 @@ static int wait_for_be(int mode,struct i2c_algo_lpc_data *adap) { DEBPROTO(lpc_fprintf_debug("%s : Bus is empty status : %x\n",__func__,status);) break; - } + } } else - { + { if(status & I2C_LPC_TD) { DEBPROTO(lpc_fprintf_debug("%s : Bus is empty status : %x\n",__func__,status);) break; } } - + status = get_lpc(adap, I2C_LPC_REG_TEST); - + DEBPROTO(lpc_fprintf_debug("%s : The test register data : %x\n",__func__,status);) udelay(1); /* wait for 100 us */ } - if (timeout == 0) { + if (timeout == 0) { DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Empty\n",__func__);) - return -ETIMEDOUT; - } - - return 0; + return -ETIMEDOUT; + } + + return 0; } static int wait_for_bf(struct i2c_algo_lpc_data *adap) -{ - - int timeout = DEF_TIMEOUT; - int status; - +{ + + int timeout = DEF_TIMEOUT; + int status; + while (--timeout) { status = get_lpc(adap, I2C_LPC_REG_STATUS); - + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus full status : %x\n",__func__,status);) if(status & I2C_LPC_RBF) @@ -491,29 +502,29 @@ static int wait_for_bf(struct i2c_algo_lpc_data *adap) } status = get_lpc(adap, I2C_LPC_REG_TEST); - + DEBPROTO(lpc_fprintf_debug("%s : The test register data : %x\n",__func__,status);) udelay(1); /* wait for 100 us */ } - - if (timeout == 0) { + + if (timeout == 0) { DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Full\n",__func__);) - return -ETIMEDOUT; - } - - return 0; + return -ETIMEDOUT; + } + + return 0; } static int wait_for_td(struct i2c_algo_lpc_data *adap) -{ - - int timeout = DEF_TIMEOUT; - int status=0; - +{ + + int timeout = DEF_TIMEOUT; + int status=0; + while (--timeout) { - udelay(4); + udelay(4); status = get_lpc(adap, I2C_LPC_REG_STATUS); - + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus done status : %x\n",__func__,status);) if(status == I2C_LPC_TD) @@ -521,18 +532,18 @@ static int wait_for_td(struct i2c_algo_lpc_data *adap) DEBPROTO(lpc_fprintf_debug("%s : Bus is done status : %x\n",__func__,status);) break; } - } - - if (timeout == 0) { + } + + if (timeout == 0) { DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Done\n",__func__);) - return -ETIMEDOUT; - } - - return 0; + return -ETIMEDOUT; + } + + return 0; } - + static int wait_for_pin(struct i2c_algo_lpc_data *adap, int *status) { int timeout = DEF_TIMEOUT; @@ -545,7 +556,7 @@ static int wait_for_pin(struct i2c_algo_lpc_data *adap, int *status) if (timeout == 0) return -ETIMEDOUT; - + return 0; } @@ -565,7 +576,7 @@ static int lpc_doAddress(struct i2c_algo_lpc_data *adap,struct i2c_msg *msg) { DEBPROTO(lpc_fprintf_debug("step 2 : write mode then write device address 0x%x\n",addr);) } - + if (flags & I2C_M_REV_DIR_ADDR) { addr ^= 1; @@ -629,33 +640,33 @@ static int lpc_sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) i += 1; } - + /* Send START */ DEBPROTO(lpc_fprintf_debug("step 5-1 : Delay 6mS \n");) - udelay(6000); + udelay(6000); DEBPROTO(lpc_fprintf_debug("step 5-2 : Start to transfrom \n");) i2c_stop(adap); i2c_start(adap); DEBPROTO(lpc_fprintf_debug("step 5-3 : Start done\n");) - udelay(400); + udelay(400); DEBPROTO(lpc_fprintf_debug("step 6 : Waiting for BE\n");) timeout = wait_for_td(adap); if (timeout) { DEBPROTO(lpc_fprintf_debug("step 6 : Timeout waiting for BE \n");) - return -1; + return -EREMOTEIO; } }while (i < count); - + if(i == count) { DEBPROTO(lpc_fprintf_debug("Writen %d bytes successd !\n",count);) return i; } else - { + { DEBPROTO(lpc_fprintf_debug("Writen %d bytes failed \n",count);) - return -1; + return -EIO; } } @@ -663,7 +674,6 @@ static int lpc_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) { int i=0,timeout=0; struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; - int wfp; unsigned int count = msg->len; unsigned char *buf = msg->buf; @@ -675,27 +685,27 @@ static int lpc_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) /* Send START */ DEBPROTO(lpc_fprintf_debug("step 9-1 : Delay 6mS\n");) - udelay(6000); + udelay(6000); DEBPROTO(lpc_fprintf_debug("step 9-2 : Start to receive data\n");) i2c_stop(adap); i2c_start(adap); DEBPROTO(lpc_fprintf_debug("step 9-3 : Start done\n");) - udelay(400); + udelay(400); DEBPROTO(lpc_fprintf_debug("step 10 : Waiting for TD\n");) timeout = wait_for_td(adap); if (timeout) { DEBPROTO(lpc_fprintf_debug("step 10 : Timeout waiting for TD \n");) - return -1; + return -EREMOTEIO; } - + if((count -i) >= 4) { buf[i+0] = 0xff & i2c_inbyte1(adap); buf[i+1] = 0xff & i2c_inbyte2(adap); buf[i+2] = 0xff & i2c_inbyte3(adap); buf[i+3] = 0xff & i2c_inbyte4(adap); - + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+1,buf[i+1]);) DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+2,buf[i+2]);) @@ -732,19 +742,17 @@ static int lpc_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) }while(i < count); - + if(i == count) { DEBPROTO(lpc_fprintf_debug("Read %d bytes successd !\n",count);) return i; } else - { + { DEBPROTO(lpc_fprintf_debug("Read %d bytes failed \n",count);) - return -1; + return -EIO; } - - return i; } @@ -768,7 +776,7 @@ static int lpc_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; struct i2c_msg *pmsg; int i; - int ret=0, timeout, status; + int ret=0; mutex_lock(&lpc_lock); @@ -810,11 +818,12 @@ static int lpc_master_xfer(struct i2c_adapter *i2c_adap, if (adap->xfer_end) adap->xfer_end(&i2c_adap->nr); - + mutex_unlock(&lpc_lock); - return i; + DEBPROTO(lpc_fprintf_debug("ret = 0x%x num = 0x%x i = 0x%x.\n",ret,num,i)); + return ret = (ret < 0) ? ret : num; } @@ -831,38 +840,14 @@ static const struct i2c_algorithm lpc_algo = { }; -/* - * registering functions to load algorithms at runtime - */ -int lpc_add_iic_bus(struct i2c_adapter *adap,unsigned int id) -{ - //struct i2c_algo_lpc_data *lpc_adap = adap->3; - int rval,num; +/********************************************** End ********************************************************/ + + - DEB2(dev_dbg(&adap->dev, "hw routines registered.\n")); - /* register new adapter to i2c module... */ - adap->algo = &lpc_algo; - - for(num = 0; num < LPC_I2C_MAX_NCHANS;num++) - { - adap->nr = num; - snprintf(adap->name, sizeof(adap->name), - "i2c-%d-lpc (chan_id %d)", i2c_adapter_id(adap), num); - if(num) - { - rval = i2c_add_numbered_adapter(adap); - } - else - { - rval = i2c_add_adapter(adap); - } - } - return rval; -} -EXPORT_SYMBOL(lpc_add_iic_bus); +/********************************************** Start ********************************************************/ #define DEFAULT_BASE 0x0a00 static int lpc_base= 0x0a00; @@ -905,7 +890,6 @@ struct cpld_dev_type *cpld_device; static void lpc_cpld_setbyte(void *data, int ctl, int val) { - //udelay(2); outb(ctl, LPC_INDEX_REG); mb(); @@ -916,7 +900,7 @@ static void lpc_cpld_setbyte(void *data, int ctl, int val) static int lpc_cpld_getbyte(void *data, int ctl) { u8 val = 0; - //udelay(2); + outb(ctl, LPC_INDEX_REG); mb(); @@ -929,17 +913,23 @@ static int lpc_cpld_getbyte(void *data, int ctl) static void lpc_iic_setbyte(void *data, int ctl, int val) { if (!cpld_device) - return -ENOTTY; + { + return ; + } if (down_interruptible(&cpld_device->sem)) - return -ERESTARTSYS; - + { + return ; + } + + lpc_cpld_setbyte(data,ctl,val); - + up(&cpld_device->sem); - DEB2(printk("%s REG[%x] = %x\n",__func__,ctl,val);) + DEBPROTO(lpc_fprintf_debug("%s REG[%x] = %x\n",__func__,ctl,val);) } + static int lpc_iic_getbyte(void *data, int ctl) { u8 val = 0; @@ -950,9 +940,9 @@ static int lpc_iic_getbyte(void *data, int ctl) return -ERESTARTSYS; val = lpc_cpld_getbyte(data,ctl); - + up(&cpld_device->sem); - DEB2(printk("%s REG[%x] = %x\n",__func__,ctl,val);) + DEBPROTO(lpc_fprintf_debug("%s REG[%x] = %x\n",__func__,ctl,val);) return val; } @@ -964,7 +954,7 @@ int cig_cpld_read_register(u8 reg_off, u8 *val) if (down_interruptible(&cpld_device->sem)) return -ERESTARTSYS; - *val = lpc_cpld_getbyte(cpld_device, reg_off); + *val = lpc_cpld_getbyte(cpld_device, reg_off); up(&cpld_device->sem); @@ -1039,24 +1029,24 @@ static irqreturn_t lpc_iic_handler(int this_irq, void *dev_id) { static int board_id = 0; -static int lpc_select_chan(void *data) +static int lpc_iic_select(void *data) { unsigned int chan_id=0; chan_id = *(unsigned int *)data; - chan_id -= 1; - DEB2(printk("step 1 : selest channel id = %d\n",chan_id);) + chan_id -= 2; + DEBPROTO(lpc_fprintf_debug("step 1 : selest channel id = %d\n",chan_id);) lpc_iic_setbyte(data,I2C_LPC_REG_BUS_SEL,chan_id); return 0; } -static int lpc_deselect_chan(void *data) +static int lpc_iic_deselect(void *data) { unsigned int chan_id=0; chan_id = *(unsigned int *)data; - chan_id -= 1; - DEB2(printk("step last :deselect channel id = %d\n",chan_id);) + chan_id -= 2; + DEBPROTO(lpc_fprintf_debug("step last :deselect channel id = %d\n",chan_id);) return 0; } @@ -1072,8 +1062,8 @@ static struct i2c_algo_lpc_data lpc_iic_data = { .getown = lpc_iic_getown, .getclock = lpc_iic_getclock, .waitforpin = lpc_iic_waitforpin, - .xfer_begin = lpc_select_chan, - .xfer_end = lpc_deselect_chan, + .xfer_begin = lpc_iic_select, + .xfer_end = lpc_iic_deselect, }; #include @@ -1082,12 +1072,12 @@ static struct i2c_adapter lpc_iic_arr_ops[LPC_I2C_MAX_NCHANS] = {0}; static void dummy_setscl(void *data, int state) { - return 1; + return; } static void dummy_setsda(void *data, int state) { - return 1; + return; } @@ -1170,9 +1160,7 @@ static int lpc_iic_probe(struct device *dev, unsigned int id) DEB2(printk("lpc_iic_probe\n");) mutex_init(&lpc_lock); - if(board_id == 1) - i2c_add_adapter(&i2c_dummy); - + for(num = 0; num < LPC_I2C_MAX_NCHANS;num++) { lpc_iic_arr_ops[num].dev.parent = dev; @@ -1181,11 +1169,11 @@ static int lpc_iic_probe(struct device *dev, unsigned int id) lpc_iic_arr_ops[num].algo = &lpc_algo; lpc_iic_arr_ops[num].algo_data = &lpc_iic_data, lpc_iic_arr_ops[num].nr=num; - snprintf(lpc_iic_arr_ops[num].name, sizeof(lpc_iic_arr_ops[num].name), "i2c-%d-lpc", i2c_adapter_id(&lpc_iic_arr_ops[num]), num); + snprintf(lpc_iic_arr_ops[num].name, sizeof(lpc_iic_arr_ops[num].name), "i2c-%d-lpc", i2c_adapter_id(&lpc_iic_arr_ops[num])); rval |= i2c_add_adapter(&lpc_iic_arr_ops[num]); DEB2(printk("%s\n",lpc_iic_arr_ops[num].name);) } - + return 0; } @@ -1198,8 +1186,6 @@ static int lpc_iic_remove(struct device *dev, unsigned int id) for(num = LPC_I2C_MAX_NCHANS - 1; num >= 0 ;num--) i2c_del_adapter(&lpc_iic_arr_ops[num]); - if(board_id == 1) - i2c_del_adapter(&i2c_dummy); return 0; } @@ -1214,8 +1200,15 @@ static struct isa_driver i2c_lpc_driver = { }, }; +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ -struct kset cpld_kset; static int cpld_major = 0; static int cpld_minor = 0; @@ -1227,6 +1220,8 @@ struct cpld_rw_msg { static struct cpld_rw_msg param_read = {-1}; static struct cpld_rw_msg param_write = {-1}; +static struct cpld_rw_msg param_reads = {-1}; +static struct cpld_rw_msg param_writes = {-1}; void cpld_sysfs_kobj_release(struct kobject *kobj) { @@ -1245,28 +1240,57 @@ int cpld_sysfs_add_attr(struct kobject* kobj, char* attr_name) return sysfs_create_file(kobj, attr); } +static int cig_cpld_write_slave_cpld_register(u8 reg_addr, u8 reg_data); +static int cig_cpld_read_slave_cpld_register(u8 reg_addr, u8 *reg_data); + static ssize_t cpld_sysfs_show(struct kobject *kobj, struct attribute *attr, char *buffer) { - u8 val,ret; + u8 val=0,ret=0,year=0,month=0,day=0,cpld_m=0,cpld_1=0,cpld_2=0; if (0 == strcmp(attr->name, "read")) { - val = lpc_iic_getbyte(NULL,param_read.addr); - ret = sprintf(buffer,"read : addr = %x val = %x\n",param_read.addr, val); + val = lpc_iic_getbyte(NULL,param_read.addr); + ret = sprintf(buffer,"read : addr = 0x%x val = 0x%x\n",param_read.addr, val); } else if (0 == strcmp(attr->name, "write")) { lpc_iic_setbyte(NULL, param_write.addr,param_write.data); - ret = sprintf(buffer,"write : addr = %x val = %x\n",param_write.addr, param_write.data); + ret = sprintf(buffer,"write : addr = 0x%x val = 0x%x\n",param_write.addr, param_write.data); } else if (0 == strcmp(attr->name, "version")) { - val = lpc_iic_getbyte(NULL, 0x02); - ret = sprintf(buffer,"CPLD version : V%02x\n",val); + cpld_m = lpc_iic_getbyte(NULL, 0x02); + year = lpc_iic_getbyte(NULL, 0x03); + month = lpc_iic_getbyte(NULL, 0x04); + day = lpc_iic_getbyte(NULL, 0x05); + + cig_cpld_read_slave_cpld_register(0x1d,&cpld_1); + cig_cpld_read_slave_cpld_register(0x1e,&cpld_2); + + ret = sprintf(buffer,"Main CPLD version : V%02x\n"\ + "Main CPLD date : 20%02x-%02x-%02x\n"\ + "Slave 1 CPLD version : V%02x\n"\ + "Slave 2 CPLD version : V%02x\n",cpld_m,year,month,day,cpld_1,cpld_2); + } + if (0 == strcmp(attr->name, "reads")) + { + ret = cig_cpld_read_slave_cpld_register(param_reads.addr,&val); + if (ret < 0) + printk("ERROR:Failed to read slave cpld.\n"); + ret = sprintf(buffer,"reads : addr = 0x%x val = 0x%x\n",param_reads.addr, val); + + } + else if (0 == strcmp(attr->name, "writes")) + { + ret = cig_cpld_write_slave_cpld_register(param_writes.addr,param_writes.data); + if (ret < 0) + printk("ERROR:Failed to read slave cpld.\n"); + ret = sprintf(buffer,"writes : addr = 0x%x val = 0x%x\n",param_writes.addr, param_writes.data); } - + + return ret; } @@ -1274,7 +1298,7 @@ static ssize_t cpld_sysfs_show(struct kobject *kobj, struct attribute *attr, cha static ssize_t cpld_sysfs_store(struct kobject *kobj, struct attribute *attr, const char *buffer, size_t count) { int param[3]; - + if (0 == strcmp(attr->name, "read")) { sscanf(buffer, "0x%02x", ¶m[0]); @@ -1285,19 +1309,30 @@ static ssize_t cpld_sysfs_store(struct kobject *kobj, struct attribute *attr, co sscanf(buffer, "0x%2x 0x%02x", ¶m[0], ¶m[1]); param_write.addr = param[0]; param_write.data = param[1]; + } + if (0 == strcmp(attr->name, "reads")) + { + sscanf(buffer, "0x%02x", ¶m[0]); + param_reads.addr = param[0]; + } + else if (0 == strcmp(attr->name, "writes")) + { + sscanf(buffer, "0x%2x 0x%02x", ¶m[0], ¶m[1]); + param_writes.addr = param[0]; + param_writes.data = param[1]; } return count; } -static struct sysfs_ops cpld_sysfs_ops = -{ +static struct sysfs_ops cpld_sysfs_ops = +{ .show = cpld_sysfs_show, .store = cpld_sysfs_store, }; -static struct kobj_type cpld_kobj_type = +static struct kobj_type cpld_kobj_type = { .release = cpld_sysfs_kobj_release, .sysfs_ops = &cpld_sysfs_ops, @@ -1308,6 +1343,10 @@ static struct kobj_type cpld_kobj_type = static const char driver_name[] = "cpld_drv"; static atomic_t cpld_available = ATOMIC_INIT(1); static struct class *cpld_class; +static struct device *cpld_dev; + + + #define CPLD_IOC_MAGIC '[' #define CPLD_IOC_RDREG _IOR(CPLD_IOC_MAGIC, 0, struct cpld_rw_msg) @@ -1340,7 +1379,7 @@ int cpld_release(struct inode *inode, struct file *flip) long cpld_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { - int rc = 0; + int rc = 0; int err = 0; struct cpld_dev_type *dev = (struct cpld_dev_type *)filp->private_data; struct cpld_rw_msg msg; @@ -1390,7 +1429,7 @@ struct file_operations cpld_fops = { .unlocked_ioctl = cpld_ioctl, .release = cpld_release, }; - + static void cpld_setup_cdev(struct cpld_dev_type *dev) { @@ -1404,166 +1443,710 @@ static void cpld_setup_cdev(struct cpld_dev_type *dev) if (err) DEB2(printk(KERN_NOTICE "Error %d adding cpld", err);) } -//#define CPLD_KTHREAD_TEST -#ifdef CPLD_KTHREAD_TEST -#include -#include -#include -#include -#include -#include -static struct task_struct *test_TaskStruct; -void get_random_bytes(void *buf, int nbytes); +/********************************************** End ********************************************************/ + + + -#define LM75_REAR_LEFT_PATH "/sys/class/hwmon/hwmon5/temp1_input" -#define LM75_REAR_RIGHT_PATH "/sys/class/hwmon/hwmon6/temp1_input" +/********************************************** Start ********************************************************/ +#include +#include +#include + +static spinlock_t irq_inter_lock; +static struct delayed_work irq_inter_work; +static unsigned long irq_inter_delay; -static int threadTask(void* arg) +static int cig_cpld_write_slave_cpld_register(u8 reg_addr, u8 reg_data) { - static int count =0; - unsigned char lpc_read_data=0; - unsigned char lpc_write_data=0; - unsigned char lpc_random_data=0; - - struct file *temp1_file = NULL,*temp2_file = NULL; - unsigned char temp1_buffer[8]={0},temp2_buffer[8]={0}; - - mm_segment_t old_fs; - while(1) + u8 read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + DEB2(printk("<=======write=========>")); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, reg_addr << 1); + DEB2(printk("[62]=%x\n",reg_addr << 1)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_TX, reg_data); + DEB2(printk("[63]=%x\n",reg_data)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + DEB2(printk("[65]=%x\n",0x80)); + do{ + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &read_status); + DEB2(printk("[66]=%x\n",read_status)); + udelay(60); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(read_status != 0x02); + DEB2(printk("<=======write=========>")); + + + if(wait_time_out == 0) + return -1; + + return 1; +} + + +static int cig_cpld_read_slave_cpld_register(u8 reg_addr, u8 *reg_data) +{ + u8 read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + DEB2(printk("<========read=========>")); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, reg_addr << 1 | 1); + DEB2(printk("[62]=%x\n",reg_addr << 1 | 1)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + DEB2(printk("[65]=%x\n",0x80)); + do{ + udelay(60); + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &read_status); + DEB2(printk("[66]=%x\n",read_status)); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(read_status != 0x01); + + cig_cpld_read_register(ADDR_REG_SFP_STATUS_RX,reg_data); + DEB2(printk("[64]=%x\n",*reg_data)); + DEB2(printk("<========read=========>")); + + if(wait_time_out == 0) + return -1; + + return 1; +} + + + +struct sock *nlsk = NULL; +extern struct net init_net; +#define NETLINK_TEST 26 +#define MSG_LEN 125 +#define USER_PORT 100 +static u32 irq_present_status_low_current,irq_present_status_low_next; +static u32 irq_present_status_high_current,irq_present_status_high_next; +static u32 irq_tx_fault_status_low_current,irq_tx_fault_status_low_next; +static u32 irq_tx_fault_status_high_current,irq_tx_fault_status_high_next; +static u32 irq_rx_lost_status_low_current,irq_rx_lost_status_low_next; +static u32 irq_rx_lost_status_high_current,irq_rx_lost_status_high_next; + +static u8 irq_present_qsfp_current,irq_present_qsfp_next; +static u8 irq_interrupt_qsfp_current,irq_interrupt_qsfp_next; + +struct input_dev *cpld_input_dev; + + + +int send_usrmsg(char *pbuf, uint16_t len) +{ + struct sk_buff *nl_skb; + struct nlmsghdr *nlh; + + int ret; + + + nl_skb = nlmsg_new(len, GFP_ATOMIC); + if(!nl_skb) + { + printk("netlink alloc failure\n"); + return -1; + } + + + nlh = nlmsg_put(nl_skb, 0, 0, NETLINK_TEST, len, 0); + if(nlh == NULL) + { + printk("nlmsg_put failaure \n"); + nlmsg_free(nl_skb); + return -1; + } + + memcpy(nlmsg_data(nlh), pbuf, len); + ret = netlink_unicast(nlsk, nl_skb, USER_PORT, MSG_DONTWAIT); + + return ret; +} + +static void netlink_rcv_msg(struct sk_buff *skb) +{ + + struct nlmsghdr *nlh = NULL; + char *umsg = NULL; + char kmsg[1024] = {0}; + char kmsg_tmp[16] = {0}; + u8 i = 0; + u8 tmp[3]={0}; + + if(skb->len >= nlmsg_total_size(0)) + { + nlh = nlmsg_hdr(skb); + umsg = NLMSG_DATA(nlh); + if(umsg) + { + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_low_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_rx_lost_status_low_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_low_current & (0x1 << i))) + { + tmp[2] = 1; + } + else + { + tmp[2] = 0; + } + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"sfp%02d:%1d:%1d:%1d ",i+1,tmp[0],tmp[1],tmp[2]); + strcat(kmsg,kmsg_tmp); + } + + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_high_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_rx_lost_status_high_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_high_current & (0x1 << i))) + { + tmp[2] = 1; + } + else + { + tmp[2] = 0; + } + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"sfp%02d:%1d:%1d:%1d ",i+25,tmp[0],tmp[1],tmp[2]); + strcat(kmsg,kmsg_tmp); + } + + + for(i = 0;i < 8;i++) + { + if(!(irq_present_qsfp_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_interrupt_qsfp_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"qsfp%02d:%1d:%1d:%1d ",i+49,tmp[0],tmp[1],0); + strcat(kmsg,kmsg_tmp); + } + + printk("kernel recv from user: %s\n", umsg); + send_usrmsg(kmsg, strlen(kmsg)); + } + } + + return ; +} + + + +struct netlink_kernel_cfg cfg = { + .input = netlink_rcv_msg, /* set recv callback */ +}; + + + +#define RANGE_OF_BYTE_SHIFT(to_arg,shift,from_arg) {to_arg &= ~(0xff << shift); to_arg |= from_arg << shift;} + + +static void irq_inter_wapper(struct work_struct * work) +{ + + u8 m_data = 0; + u8 data_high8 = 0,data_low8 = 0; + u16 data_16 = 0; + u8 status = 0; + u8 i = 0; + char kmsg[64]={0}; + u8 tmp[3] = {0}; + + DEB2(printk("CPLD_MASTER_INTERRUPT\r\n")); + + m_data = lpc_iic_getbyte(NULL,CPLD_MASTER_INTERRUPT_STATUS_REG); + lpc_iic_setbyte(NULL,CPLD_MASTER_INTERRUPT_STATUS_REG,0xff); + + cig_cpld_write_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_MASK_REG,0xff); + cig_cpld_write_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_MASK_REG,0xff); + if(!(m_data & CPLD_MASTER_INTERRUPT_CPLD1)) { - if(kthread_should_stop()) + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_STATUS_H_REG,&data_high8); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_STATUS_L_REG,&data_low8); + data_16 = data_low8 | data_high8 << 8; + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT24) + ) { - DEB2(printk("threadTask: kthread_should_stop\n")); - break; - } - -#if 1 - get_random_bytes(&lpc_random_data,1); - - lpc_write_data = lpc_random_data; - - lpc_iic_setbyte(NULL,I2C_LPC_REG_TEST,lpc_write_data); - //DEB2(printk("threadTask: lpc write reg[01] data : %02x\n",lpc_write_data)); - - lpc_read_data = lpc_iic_getbyte(NULL,I2C_LPC_REG_TEST); - //DEB2(printk("threadTask: lpc read reg[01] data : %02x\n",lpc_read_data)); - udelay(10000); - if(lpc_write_data != lpc_read_data) + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,16,status); + } + DEB2(printk("irq_present_status_low_next = %08x irq_present_status_low_current = %08x \n",irq_present_status_low_next,irq_present_status_low_current)); + } + + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24) + ) { - printk("Error : WRITE %02x != READ %02x\n",lpc_write_data,lpc_read_data); + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_RX_LOST08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,16,status); + } + DEB2(printk("irq_rx_lost_status_low_next = %08x irq_rx_lost_status_low_current = %08x \n",irq_rx_lost_status_low_next,irq_rx_lost_status_low_current)); } - msleep(10); -#else - if(temp1_file != NULL) - temp1_file = filp_open(LM75_REAR_LEFT_PATH, O_RDONLY , 0); - if (IS_ERR(temp1_file)) { - printk("error occured while opening file %s, exiting...\n", LM75_REAR_LEFT_PATH); + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24) + ) + { + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,16,status); + } + DEB2(printk("irq_tx_fault_status_low_next = %08x irq_tx_fault_status_low_current = %08x \n",irq_tx_fault_status_low_next,irq_tx_fault_status_low_current)); + + } + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_CPLD2)) + { + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_STATUS_H_REG,&data_high8); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_STATUS_L_REG,&data_low8); + data_16 = data_low8 | data_high8 << 8; + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT32)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT32_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT40)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT40_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,16,status); + } } - if(temp2_file != NULL) - temp2_file = filp_open(LM75_REAR_RIGHT_PATH, O_RDONLY ,0); - if (IS_ERR(temp2_file)) { - printk("error occured while opening file %s, exiting...\n", LM75_REAR_RIGHT_PATH); + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST32)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_RX_LOST32\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST40)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT40\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,16,status); + } + } + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT32)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_RX_LOST32\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT40)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT40\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,16,status); + } + } - old_fs = get_fs(); - set_fs(KERNEL_DS); + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT56)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT56_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT56_REG,&status); + irq_present_qsfp_current = status; + } - temp1_file->f_op->read(temp1_file, (char *)temp1_buffer, strlen(temp1_buffer), &temp1_file->f_pos); + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_QSFP_CR56)) + { + DEB2(printk("CPLD_SLAVE2_QSFP_CR56_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_QSFP_CR56_REG,&status); + irq_interrupt_qsfp_current = status; + } + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_LSW)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_LSW\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_PSU1)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_PSU1\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_PSU2)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_PSU2\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_6320)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_6320\r\n")); + } + cig_cpld_write_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_MASK_REG,0x0); + cig_cpld_write_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_MASK_REG,0x0); - temp2_file->f_op->read(temp2_file, (char *)temp2_buffer, strlen(temp2_buffer), &temp2_file->f_pos); - - set_fs(old_fs); + memset(tmp,0xff,sizeof(tmp)); - if((simple_strtoul(temp1_buffer,NULL,10) >=30000) || (simple_strtoul(temp2_buffer,NULL,10) >=30000)) + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_low_current & (0x1 << i)) && (irq_present_status_low_next & (0x1 << i))) { - lpc_iic_setbyte(NULL,0x40,0xff); - printk("Full speed\n"); + DEB2(printk("SFP%d is present\r\n",i+1)); + tmp[0] = 1; + } + else if((irq_present_status_low_current & (0x1 << i)) && !(irq_present_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+1)); + tmp[0] = 0; } - msleep(1000); -#endif + if(!(irq_tx_fault_status_low_current & (0x1 << i)) && (irq_tx_fault_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is right\r\n",i+1)); + tmp[1] = 1; + } + else if((irq_tx_fault_status_low_current & (0x1 << i)) && !(irq_tx_fault_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is fault\r\n",i+1)); + tmp[1] = 0; + } + + if(!(irq_rx_lost_status_low_current & (0x1 << i)) && (irq_rx_lost_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is meet\r\n",i+1)); + tmp[2] = 1; + } + else if((irq_rx_lost_status_low_current & (0x1 << i)) && !(irq_rx_lost_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is lost\r\n",i+1)); + tmp[2] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff) || (tmp[2] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"sfp%02d:%1d:%1d:%1d ",i+1,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],(tmp[2] == 0xff) ? 0:tmp[2]); + break; + } } -} - -static int init_kernel_Thread(void) -{ - test_TaskStruct=kthread_create(threadTask,NULL,"KernelThead",0); - if(IS_ERR(test_TaskStruct)) + + memset(tmp,0xff,sizeof(tmp)); + for(i = 0;i < 24;i++) { - printk("kthread_create error\n"); + if(!(irq_present_status_high_current & (0x1 << i)) && (irq_present_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+25)); + tmp[0] = 1; + } + else if((irq_present_status_high_current & (0x1 << i)) && !(irq_present_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+25)); + tmp[0] = 0; + + } + + if(!(irq_rx_lost_status_high_current & (0x1 << i)) && (irq_rx_lost_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is meet\r\n",i+25)); + tmp[1] = 1; + } + else if((irq_rx_lost_status_high_current & (0x1 << i)) && !(irq_rx_lost_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is lost\r\n",i+25)); + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_high_current & (0x1 << i)) && (irq_tx_fault_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is right\r\n",i+25)); + tmp[2] = 1; + } + else if((irq_tx_fault_status_high_current & (0x1 << i)) && !(irq_tx_fault_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is fault\r\n",i+25)); + tmp[2] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff) || (tmp[2] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"sfp%02d:%1d:%1d:%1d ",i+25,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],(tmp[2] == 0xff) ? 0:tmp[2]); + break; + } } - else + + memset(tmp,0xff,sizeof(tmp)); + for(i = 0 ; i < 8; i++) { - wake_up_process(test_TaskStruct); + if(!(irq_present_qsfp_current & (0x1 << i)) && (irq_present_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+49)); + tmp[0] = 1; + } + else if((irq_present_qsfp_current & (0x1 << i)) && !(irq_present_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+49)); + tmp[0] = 0; + } + + if(!(irq_interrupt_qsfp_current & (0x1 << i)) && (irq_interrupt_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d interrupt is occured \r\n",i+49)); + tmp[1] = 1; + } + else if((irq_interrupt_qsfp_current & (0x1 << i)) && !(irq_interrupt_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d interrupt is cleaned\r\n",i+49)); + tmp[1] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"qsfp%02d:%1d:%1d:%1d ",i+49,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],0); + break; + } } - return 0; + + + irq_present_status_low_next = irq_present_status_low_current; + irq_rx_lost_status_low_next = irq_rx_lost_status_low_current; + irq_tx_fault_status_low_next = irq_tx_fault_status_low_current; + irq_present_status_high_next = irq_present_status_high_current; + irq_rx_lost_status_high_next = irq_rx_lost_status_high_current; + irq_tx_fault_status_high_next = irq_tx_fault_status_high_current; + irq_present_qsfp_next = irq_present_qsfp_current; + irq_interrupt_qsfp_next = irq_interrupt_qsfp_current; + + send_usrmsg(kmsg, strlen(kmsg)); } -static void exit_kernel_Thread(void) +static void disableIrq(unsigned short maskReg, unsigned short mask) { - kthread_stop(test_TaskStruct); - test_TaskStruct = NULL; + u8 data = 0; + + data = lpc_iic_getbyte(NULL,maskReg); + data |= mask; + lpc_iic_setbyte(NULL,maskReg, data); } -#endif +static void enableIrq(unsigned short maskReg, unsigned short mask) +{ + unsigned short data; + + data = lpc_iic_getbyte(NULL,maskReg); + data &= ~mask; + lpc_iic_setbyte(NULL,maskReg, data); +} + + +static irqreturn_t irq_inter_isr(int irq, void *handle) +{ + + /* + * use keventd context to read the event fifo registers + * Schedule readout at least 25ms after notification for + * REVID < 4 + */ + + schedule_delayed_work(&irq_inter_work, irq_inter_delay); + + return IRQ_HANDLED; +} + + +#define CIG_CPLD_CHR_NAME "cpld" static int __init cpld_init(void) { - int rval,rc; + int rval,rc=0; dev_t dev; - + u8 s_data; + int isr_GPIO_num = 289; + DEB2(printk("cpld_init\n");) +/**************************************************************************************/ + + LPC_INDEX_REG = lpc_base_addr; + LPC_DATA_REG = lpc_base_addr + 1; + cpld_device = kzalloc(sizeof(struct cpld_dev_type), GFP_KERNEL); if (!cpld_device) goto error3; - cpld_device->io_resource = request_region(lpc_base_addr, + cpld_device->io_resource = request_region(lpc_base_addr, lpc_io_space_size, "lpc-i2c"); if (!cpld_device->io_resource) { - DEB2(printk("lpc: claim I/O resource fail\n");) + printk("lpc: claim I/O resource fail\n"); goto error2; } sema_init(&cpld_device->sem, 1); - LPC_INDEX_REG = lpc_base_addr; - LPC_DATA_REG = lpc_base_addr + 1; - - rval = lpc_bus_init(); - rval = lpc_register_driver(&i2c_lpc_driver, 1); - - kobject_set_name(&cpld_kset.kobj, "cpld"); - cpld_kset.kobj.ktype= &cpld_kobj_type; - kset_register(&cpld_kset); - cpld_sysfs_add_attr(&cpld_kset.kobj, "read"); - cpld_sysfs_add_attr(&cpld_kset.kobj, "write"); - cpld_sysfs_add_attr(&cpld_kset.kobj, "version"); - if (cpld_major) { dev = MKDEV(cpld_major, cpld_minor); - rc = register_chrdev_region(dev, 1, "cpld"); + rc = register_chrdev_region(dev, 1, CIG_CPLD_CHR_NAME); } else { - rc = alloc_chrdev_region(&dev, cpld_major, 1, "cpld"); + rc = alloc_chrdev_region(&dev, cpld_major, 1, CIG_CPLD_CHR_NAME); cpld_major = MAJOR(dev); } cpld_setup_cdev(cpld_device); - cpld_class = class_create(THIS_MODULE, KBUILD_MODNAME); + cpld_class = class_create(THIS_MODULE,CIG_CPLD_CHR_NAME); if (!cpld_class) { DEB2(printk("failed to create class\n");) goto error1; } - device_create(cpld_class, NULL, dev, NULL, "cpld"); -#ifdef CPLD_KTHREAD_TEST - init_kernel_Thread(); -#endif - + cpld_class->p->subsys.kobj.ktype= &cpld_kobj_type; + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "read"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "write"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "reads"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "writes"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "version"); + + cpld_dev = device_create(cpld_class, NULL, dev, NULL, CIG_CPLD_CHR_NAME); + +/**************************************************************************************/ + + rval = lpc_bus_init(); + rval = lpc_register_driver(&i2c_lpc_driver, 1); + +/**************************************************************************************/ return 0; error1: cdev_del(&cpld_device->cdev); @@ -1572,20 +2155,18 @@ static int __init cpld_init(void) release_resource(cpld_device->io_resource); error3: kfree(cpld_device); - + return rc; } static void __exit cpld_exit(void) { - DEB2(printk("cpld_exit\n")); - - lpc_unregister_driver(&i2c_lpc_driver); - lpc_bus_exit(); -#ifdef CPLD_KTHREAD_TEST - exit_kernel_Thread(); -#endif - dev_t devno = MKDEV(cpld_major, cpld_minor); + + DEB2(printk("cpld_exit\n")); + + lpc_unregister_driver(&i2c_lpc_driver); + lpc_bus_exit(); + dev_t devno = MKDEV(cpld_major, cpld_minor); cdev_del(&cpld_device->cdev); if (cpld_class) { @@ -1593,11 +2174,6 @@ static void __exit cpld_exit(void) class_destroy(cpld_class); } - kobject_put(&cpld_kset.kobj); - - if(cpld_kset.kobj.ktype) - kset_unregister(&cpld_kset); - if (cpld_device) { if (cpld_device->io_resource) release_resource(cpld_device->io_resource); @@ -1622,11 +2198,7 @@ MODULE_DESCRIPTION("cs6436-56p-cpld driver"); MODULE_LICENSE("GPL"); - - - - - +/********************************************** End ********************************************************/ diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-fan.c b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-fan.c old mode 100755 new mode 100644 index 09beb6912c32..33eaaa840305 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-fan.c +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-fan.c @@ -44,6 +44,9 @@ static struct cs6436_56p_fan_data *cs6436_56p_fan_update_device(struct device *d static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); + extern int cig_cpld_write_register(u8 reg_off, u8 val); extern int cig_cpld_read_register(u8 reg_off, u8 *val); @@ -63,6 +66,7 @@ static const u8 fan_reg[] = { 0x47, /* rear fan 3 speed(rpm) */ 0x49, /* rear fan 4 speed(rpm) */ 0x4b, /* rear fan 5 speed(rpm) */ + 0x4c, /* fan direction rear to front or front to rear */ }; @@ -99,6 +103,7 @@ enum sysfs_fan_attributes { FAN3_REAR_SPEED_RPM, FAN4_REAR_SPEED_RPM, FAN5_REAR_SPEED_RPM, + FAN_DIRECTION, FAN1_STATE, FAN2_STATE, FAN3_STATE, @@ -109,6 +114,11 @@ enum sysfs_fan_attributes { FAN3_FAULT, FAN4_FAULT, FAN5_FAULT, + FAN1_DIRECTION, + FAN2_DIRECTION, + FAN3_DIRECTION, + FAN4_DIRECTION, + FAN5_DIRECTION, }; /* Define attributes @@ -131,6 +141,11 @@ enum sysfs_fan_attributes { #define DECLARE_FAN_SPEED_RPM_ATTR(index) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \ &sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr +#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IWUSR | S_IRUGO, fan_show_value, set_fan_direction, FAN##index##_DIRECTION) +#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr + + /* 5 fan state attributes in this platform */ DECLARE_FAN_STATE_SENSOR_DEV_ATTR(1); DECLARE_FAN_STATE_SENSOR_DEV_ATTR(2); @@ -156,6 +171,13 @@ DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(5); /* 1 fan duty cycle attribute in this platform */ DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(5); + + static struct attribute *cs6436_56p_fan_attributes[] = { /* fan related attributes */ DECLARE_FAN_STATE_ATTR(1), @@ -174,6 +196,11 @@ static struct attribute *cs6436_56p_fan_attributes[] = { DECLARE_FAN_SPEED_RPM_ATTR(4), DECLARE_FAN_SPEED_RPM_ATTR(5), DECLARE_FAN_DUTY_CYCLE_ATTR(), + DECLARE_FAN_DIRECTION_ATTR(1), + DECLARE_FAN_DIRECTION_ATTR(2), + DECLARE_FAN_DIRECTION_ATTR(3), + DECLARE_FAN_DIRECTION_ATTR(4), + DECLARE_FAN_DIRECTION_ATTR(5), NULL }; @@ -230,6 +257,7 @@ static u8 is_fan_fault(struct cs6436_56p_fan_data *data, enum fan_id id) return ret; } + static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { @@ -247,6 +275,41 @@ static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, return count; } +static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value,fan_index; + u8 mask,reg_val; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + fan_index = attr->index - FAN1_DIRECTION; + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (!(value == 0 || value == 1)) + return -EINVAL; + + + cig_cpld_read_register(fan_reg[FAN_DIRECTION],®_val); + + if(value == 1) + { + reg_val |= (1 << fan_index); + } + else + { + reg_val &= ~(1 << fan_index); + } + + cig_cpld_write_register(fan_reg[FAN_DIRECTION], reg_val); + + return count; +} + + + + + static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf) { @@ -300,6 +363,13 @@ static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, case FAN5_FAULT: ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT)); break; + case FAN1_DIRECTION: + case FAN2_DIRECTION: + case FAN3_DIRECTION: + case FAN4_DIRECTION: + case FAN5_DIRECTION: + ret = sprintf(buf, "%d\n",reg_val_to_is_state(data->reg_val[FAN_DIRECTION],attr->index - FAN1_DIRECTION)); + break; default: break; } diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-led.c b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-led.c old mode 100755 new mode 100644 diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-psu.c b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-psu.c old mode 100755 new mode 100644 index 8754007408c7..1a4734d4ba25 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-psu.c +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-psu.c @@ -17,265 +17,306 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - - -#define MAX_FAN_DUTY_CYCLE 100 - -/* Address scanned */ -static const unsigned short normal_i2c[] = {I2C_CLIENT_END }; - -/* This is additional data */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "i2c-algo-lpc.h" + + + +#define MAX_FAN_DUTY_CYCLE 100 + +/* Address scanned */ +static const unsigned short normal_i2c[] = {I2C_CLIENT_END }; + +/* This is additional data */ struct cs6436_56p_psu_data { - struct device *hwmon_dev; - struct mutex update_lock; - char valid; - unsigned long last_updated; /* In jiffies */ - - /* Registers value */ - u8 vout_mode; - u16 v_in; - u16 v_out; - u16 i_in; - u16 i_out; - u16 p_in; - u16 p_out; - u16 temp_input[3]; - u8 temp_fault; - u8 fan_fault; - u16 fan_duty_cycle[2]; - u16 fan_speed[2]; - u8 mfr_id[8]; - u8 mfr_model[20]; - u8 mfr_serial[20]; + struct device *hwmon_dev; + struct mutex update_lock; + char valid; + unsigned long last_updated; /* In jiffies */ + + /* Registers value */ + u8 vout_mode; + u16 v_in; + u16 v_out; + u16 i_in; + u16 i_out; + u16 p_in; + u16 p_out; + u16 temp_input[3]; + u8 temp_fault; + u8 fan_fault; + u16 fan_duty_cycle[2]; + u16 fan_speed[2]; + u8 mfr_id[8]; + u8 mfr_model[20]; + u8 mfr_serial[20]; u8 psu_is_present; u8 psu_is_good; -}; - -static int two_complement_to_int(u16 data, u8 valid_bit, int mask); -static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count); -static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf); -static ssize_t for_fan_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); -static ssize_t for_fan_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); -static ssize_t for_temp_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); -static ssize_t for_temp_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); -static ssize_t for_vout_data(struct device *dev, struct device_attribute *dev_attr, char *buf); + struct i2c_client *client; + struct bin_attribute *bin; /* eeprom data */ +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask); +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count); +static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_fan_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_fan_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_temp_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_temp_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_vout_data(struct device *dev, struct device_attribute *dev_attr, char *buf); static int cs6436_56p_psu_read_byte(struct i2c_client *client, u8 reg); static int cs6436_56p_psu_read_word(struct i2c_client *client, u8 reg); static int cs6436_56p_psu_write_word(struct i2c_client *client, u8 reg, u16 value); static int cs6436_56p_psu_read_block(struct i2c_client *client, u8 command, u8 *data, int data_len); static struct cs6436_56p_psu_data *cs6436_56p_psu_update_device(struct device *dev); -static ssize_t for_ascii(struct device *dev, struct device_attribute *dev_attr, char *buf); -static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_ascii(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf); enum cs6436_56p_psu_sysfs_attributes { - PSU_V_IN, - PSU_V_OUT, - PSU_I_IN, - PSU_I_OUT, - PSU_P_IN, - PSU_P_OUT, - PSU_TEMP1_INPUT, - PSU_TEMP2_INPUT, - PSU_TEMP3_INPUT, - PSU_TEMP_FAULT, - PSU_TEMP_WARN, - PSU_FAN1_FAULT, - PSU_FAN1_WARN, - PSU_FAN1_DUTY_CYCLE, - PSU_FAN1_SPEED, - PSU_MFR_ID, - PSU_MFR_MODEL, - PSU_MFR_SERIAL, + PSU_V_IN, + PSU_V_OUT, + PSU_I_IN, + PSU_I_OUT, + PSU_P_IN, + PSU_P_OUT, + PSU_TEMP1_INPUT, + PSU_TEMP2_INPUT, + PSU_TEMP3_INPUT, + PSU_TEMP_FAULT, + PSU_TEMP_WARN, + PSU_FAN1_FAULT, + PSU_FAN1_WARN, + PSU_FAN1_DUTY_CYCLE, + PSU_FAN1_SPEED, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_SERIAL, PSU_PRESENT, PSU_P_GOOD, -}; - -static int two_complement_to_int(u16 data, u8 valid_bit, int mask) -{ - u16 valid_data = data & mask; - - bool is_negative = valid_data >> (valid_bit - 1); - return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; -} - -static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute \ - *dev_attr, const char *buf, size_t count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); - struct i2c_client *client = to_i2c_client(dev); +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + + bool is_negative = valid_data >> (valid_bit - 1); + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute \ + *dev_attr, const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct i2c_client *client = to_i2c_client(dev); struct cs6436_56p_psu_data *data = i2c_get_clientdata(client); - int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; - long speed; - int error; - - error = kstrtol(buf, 10, &speed); - if (error) - return error; - - if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) - return -EINVAL; - - - mutex_lock(&data->update_lock); - data->fan_duty_cycle[nr] = speed; + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + if (data->valid != 1) + { + return -ENODEV; + } + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; cs6436_56p_psu_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); - - u16 value = 0; - int exponent, mantissa; - int multiplier = 1000; - - switch (attr->index) { - case PSU_V_IN: - value = data->v_in; - break; - case PSU_I_IN: - value = data->i_in; - break; - case PSU_I_OUT: - value = data->i_out; - break; - case PSU_P_IN: - value = data->p_in; - break; - case PSU_P_OUT: - value = data->p_out; - break; - case PSU_TEMP1_INPUT: - value = data->temp_input[0]; - break; - case PSU_TEMP2_INPUT: - value = data->temp_input[1]; - break; - case PSU_TEMP3_INPUT: - value = data->temp_input[2]; - break; - case PSU_FAN1_DUTY_CYCLE: - multiplier = 1; - value = data->fan_duty_cycle[0]; - break; - case PSU_FAN1_SPEED: - multiplier = 1; - value = data->fan_speed[0]; - break; - default: - break; - } - - exponent = two_complement_to_int(value >> 11, 5, 0x1f); - mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); - - return (exponent >= 0) ? sprintf(buf, "%d\n", \ - (mantissa << exponent) * multiplier) : \ - sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); -} - -static ssize_t for_fan_fault(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); - struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); - - u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; - - return sprintf(buf, "%d\n", data->fan_fault >> shift); -} - -static ssize_t for_fan_warning(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); - struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); - - u8 shift = (attr->index == PSU_FAN1_WARN) ? 5 : 4; - - return sprintf(buf, "%d\n", data->fan_fault >> shift); -} - -static ssize_t for_temp_fault(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); - struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); - - - return sprintf(buf, "%d\n", data->temp_fault >> 7); -} - -static ssize_t for_temp_warning(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); - struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); - - return sprintf(buf, "%d\n", data->temp_fault >> 6); -} -static ssize_t for_vout_data(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + if (data->valid != 1) + { + return -ENODEV; + } + + switch (attr->index) { + case PSU_V_IN: + value = data->v_in; + break; + case PSU_I_IN: + value = data->i_in; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_IN: + value = data->p_in; + break; + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp_input[0]; + break; + case PSU_TEMP2_INPUT: + value = data->temp_input[1]; + break; + case PSU_TEMP3_INPUT: + value = data->temp_input[2]; + break; + case PSU_FAN1_DUTY_CYCLE: + multiplier = 1; + value = data->fan_duty_cycle[0]; + break; + case PSU_FAN1_SPEED: + multiplier = 1; + value = data->fan_speed[0]; + break; + default: + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + + return (exponent >= 0) ? \ + sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) :\ + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t for_fan_fault(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t for_fan_warning(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + u8 shift = (attr->index == PSU_FAN1_WARN) ? 5 : 4; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t for_temp_fault(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + + + return sprintf(buf, "%d\n", data->temp_fault >> 7); +} + +static ssize_t for_temp_warning(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); + if (data->valid != 1) + { + return -ENODEV; + } + + + return sprintf(buf, "%d\n", data->temp_fault >> 6); +} +static ssize_t for_vout_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); - int exponent, mantissa; - int multiplier = 1000; - - exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); - mantissa = data->v_out; - - return (exponent > 0) ? sprintf(buf, "%d\n", \ - (mantissa << exponent) * multiplier) : \ - sprintf(buf, "%d\n", ((mantissa * multiplier) >> (-exponent))); -} - -static ssize_t for_ascii(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + int exponent, mantissa; + int multiplier = 1000; + if (data->valid != 1) + { + return -ENODEV; + } + + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + mantissa = data->v_out; + + return (exponent > 0) ? sprintf(buf, "%d\n", \ + (mantissa << exponent) * multiplier) : \ + sprintf(buf, "%d\n", ((mantissa * multiplier) >> (-exponent))); +} + +static ssize_t for_ascii(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); - u8 *ptr = NULL; - - if (!data->valid) - return 0; - - switch (attr->index) { - case PSU_MFR_ID: - ptr = data->mfr_id + 1; - break; - case PSU_MFR_MODEL: - ptr = data->mfr_model + 1; - break; - case PSU_MFR_SERIAL: - ptr = data->mfr_serial + 1; - break; - default: - return 0; - } - return sprintf(buf, "%s\n", ptr); -} + u8 *ptr = NULL; + + if (data->valid != 1) + { + return -ENODEV; + } + + switch (attr->index) { + case PSU_MFR_ID: + ptr = data->mfr_id + 1; + break; + case PSU_MFR_MODEL: + ptr = data->mfr_model + 1; + break; + case PSU_MFR_SERIAL: + ptr = data->mfr_serial + 1; + break; + default: + return 0; + } + return sprintf(buf, "%s\n", ptr); +} static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf) @@ -286,14 +327,14 @@ static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, u8 status = 0; - if (!data->valid) { - return -EIO; - } - if (attr->index == PSU_PRESENT) { status = data->psu_is_present; } else { /* PSU_POWER_GOOD */ + if (!data->valid) { + return -ENODEV; + } + status = data->psu_is_good; } @@ -301,286 +342,602 @@ static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, } - static int cs6436_56p_psu_read_byte(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_byte_data(client, reg); -} - +{ + return i2c_smbus_read_byte_data(client, reg); +} + static int cs6436_56p_psu_read_word(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_word_data(client, reg); -} - +{ + return i2c_smbus_read_word_data(client, reg); +} + static int cs6436_56p_psu_write_word(struct i2c_client *client, u8 reg, \ - u16 value) -{ - union i2c_smbus_data data; - data.word = value; - return i2c_smbus_xfer(client->adapter, client->addr, - client->flags |= I2C_CLIENT_PEC, - I2C_SMBUS_WRITE, reg, - I2C_SMBUS_WORD_DATA, &data); - -} - + u16 value) +{ + union i2c_smbus_data data; + data.word = value; + return i2c_smbus_xfer(client->adapter, client->addr, + client->flags |= I2C_CLIENT_PEC, + I2C_SMBUS_WRITE, reg, + I2C_SMBUS_WORD_DATA, &data); + +} + static int cs6436_56p_psu_read_block(struct i2c_client *client, u8 command, \ - u8 *data, int data_len) -{ - int result = i2c_smbus_read_i2c_block_data(client, command, data_len, - data); - if (unlikely(result < 0)) - goto abort; - if (unlikely(result != data_len)) { - result = -EIO; - goto abort; - } - - result = 0; -abort: - return result; - -} - -struct reg_data_byte { - u8 reg; - u8 *value; -}; - -struct reg_data_word { - u8 reg; - u16 *value; -}; - -static struct cs6436_56p_psu_data *cs6436_56p_psu_update_device( \ - struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); + u8 *data, int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, + data); + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; +abort: + return result; + +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + + + +#define EEPROM_NAME "psu_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ + +/* Platform dependent --- */ +static ssize_t psu_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ + int status, retry = 3; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(100); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return data_len; + +} + + +static ssize_t psu_page_write(struct i2c_client *client,const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + + + while (count) { + ssize_t status; + + status = psu_eeprom_write(client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + + return retval; +} + + + +static ssize_t psu_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct cs6436_56p_psu_data *data; + ssize_t retval = 0; + struct i2c_client *client; + + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + client = to_i2c_client(container_of(kobj, struct device, kobj)); + + mutex_lock(&data->update_lock); + retval = psu_page_write(client, buf, off, count); + mutex_unlock(&data->update_lock); + return retval; +} + + +static ssize_t psu_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int status, retry = 3; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(100); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + goto abort; + } + if (unlikely(status != data_len)) { + status = -EIO; + goto abort; + } + +abort: + return status; +} + + + +static ssize_t psu_page_read(struct i2c_client *client,char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + printk("Count = 0, return"); + return count; + } + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + + + while (count) { + ssize_t status; + + status = psu_eeprom_read(client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + + return retval; + +} + + +static ssize_t psu_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct cs6436_56p_psu_data *data; + struct i2c_client *client; + ssize_t retval = 0; + + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + client = to_i2c_client(container_of(kobj, struct device, kobj)); + mutex_lock(&data->update_lock); + retval = psu_page_read(client, buf, off, count); + mutex_unlock(&data->update_lock); + + return retval; +} + + + +static int psu_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = psu_bin_read; + eeprom->write = psu_bin_write; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + + +static int psu_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + + +static int psu_i2c_check_functionality(struct i2c_client *client) +{ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_I2C_BLOCK); +} + + + +static int psu_eeprom_probe(struct i2c_client *client, const struct i2c_device_id *dev_id) +{ + int status; + + struct cs6436_56p_psu_data *data; + + if (!psu_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + data->bin = kzalloc(sizeof(struct bin_attribute), GFP_KERNEL); + if (!data->bin) { + status = -ENOMEM; + goto eeprom_bin_error; + } + + /* init eeprom */ + status = psu_sysfs_eeprom_init(&client->dev.kobj, data->bin); + if (status) { + status = -ENOMEM; + goto sys_init_error; + } + + dev_info(&client->dev, "psu eeprom '%s'\n", client->name); + + return 0; + + sys_init_error: + kfree(data->bin); + + eeprom_bin_error: + kfree(data); + + exit: + return status; +} + + + + +static struct cs6436_56p_psu_data *cs6436_56p_psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); struct cs6436_56p_psu_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->update_lock); - - - if (time_after(jiffies, data->last_updated)) { - int i, status; - u8 command; - struct reg_data_byte regs_byte[] = { - {0x20, &data->vout_mode}, - {0x81, &data->fan_fault}, - {0x7d, &data->temp_fault}, - }; - struct reg_data_word regs_word[] = { - {0x88, &data->v_in}, - {0x8b, &data->v_out}, - {0x89, &data->i_in}, - {0x8c, &data->i_out}, - {0x96, &data->p_out}, - {0x97, &data->p_in}, - {0x8d, &(data->temp_input[0])}, - {0x8e, &(data->temp_input[1])}, - {0x8f, &(data->temp_input[2])}, - {0x3b, &(data->fan_duty_cycle[0])}, - {0x90, &(data->fan_speed[0])}, - }; - - dev_dbg(&client->dev, "start data update\n"); - - /* one milliseconds from now */ - data->last_updated = jiffies + HZ / 1000; - - for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { - status = cs6436_56p_psu_read_byte(client, - regs_byte[i].reg); - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_byte[i].reg, status); - } else { - *(regs_byte[i].value) = status; - } - } - - for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + + + mutex_lock(&data->update_lock); + + + if (time_after(jiffies, data->last_updated)) { + int i, status; + u8 command; + struct reg_data_byte regs_byte[] = { + {0x20, &data->vout_mode}, + {0x81, &data->fan_fault}, + {0x7d, &data->temp_fault}, + }; + struct reg_data_word regs_word[] = { + {0x88, &data->v_in}, + {0x8b, &data->v_out}, + {0x89, &data->i_in}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x97, &data->p_in}, + {0x8d, &(data->temp_input[0])}, + {0x8e, &(data->temp_input[1])}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x90, &(data->fan_speed[0])}, + }; + data->valid = 1; + + dev_dbg(&client->dev, "start data update\n"); + + /* one milliseconds from now */ + data->last_updated = jiffies + HZ / 1000; + + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = cs6436_56p_psu_read_byte(client, + regs_byte[i].reg); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + *(regs_byte[i].value) = 0; + data->valid = 0; + } else { + *(regs_byte[i].value) = status; + } + } + + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { status = cs6436_56p_psu_read_word(client, - regs_word[i].reg); - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_word[i].reg, status); - } else { - *(regs_word[i].value) = status; - } - } - - command = 0x99; /* PSU mfr_id */ - status = cs6436_56p_psu_read_block(client, command, - data->mfr_id, ARRAY_SIZE(data->mfr_id) - 1); - data->mfr_id[ARRAY_SIZE(data->mfr_id) - 1] = '\0'; - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - } - - command = 0x9a; /* PSU mfr_model */ - status = cs6436_56p_psu_read_block(client, command, - data->mfr_model, ARRAY_SIZE(data->mfr_model) - 1); - data->mfr_model[ARRAY_SIZE(data->mfr_model) - 1] = '\0'; - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - } - - command = 0x9e; /* PSU mfr_serial */ - status = cs6436_56p_psu_read_block(client, command, - data->mfr_serial, ARRAY_SIZE(data->mfr_serial) - 1); - data->mfr_serial[ARRAY_SIZE(data->mfr_serial) - 1] = '\0'; - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - } - data->valid = 1; + regs_word[i].reg); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + *(regs_word[i].value) = 0; + data->valid = 0; + } else { + *(regs_word[i].value) = status; + } + } + + command = 0x99; /* PSU mfr_id */ + status = cs6436_56p_psu_read_block(client, command, + data->mfr_id, ARRAY_SIZE(data->mfr_id) - 1); + data->mfr_id[ARRAY_SIZE(data->mfr_id) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_id, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + command = 0x9a; /* PSU mfr_model */ + status = cs6436_56p_psu_read_block(client, command, + data->mfr_model, ARRAY_SIZE(data->mfr_model) - 1); + data->mfr_model[ARRAY_SIZE(data->mfr_model) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_model, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + command = 0x9e; /* PSU mfr_serial */ + status = cs6436_56p_psu_read_block(client, command, + data->mfr_serial, ARRAY_SIZE(data->mfr_serial) - 1); + data->mfr_serial[ARRAY_SIZE(data->mfr_serial) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_serial, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + data->psu_is_present = strlen(data->mfr_id) > 1 ? 1:0; if(data->psu_is_present) + { data->psu_is_good = ((data->fan_fault) || (data->temp_fault))? 0:1; - else + } + else + { + data->valid = 0; data->psu_is_good = 0; - } - - mutex_unlock(&data->update_lock); - - return data; - -} - -/* sysfs attributes for hwmon */ -static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, for_linear_data, NULL, PSU_V_IN); -static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, for_vout_data, NULL, PSU_V_OUT); -static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, for_linear_data, NULL, PSU_I_IN); -static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, for_linear_data, NULL, PSU_I_OUT); -static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, for_linear_data, NULL, PSU_P_IN); -static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, for_linear_data, NULL, PSU_P_OUT); -static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP1_INPUT); -static SENSOR_DEVICE_ATTR(psu_temp2_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP2_INPUT); -static SENSOR_DEVICE_ATTR(psu_temp3_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP3_INPUT); -static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, for_temp_fault, NULL, PSU_TEMP_FAULT); -static SENSOR_DEVICE_ATTR(psu_temp_warning, S_IRUGO, for_temp_warning, NULL, PSU_TEMP_WARN); -static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, for_fan_fault, NULL, PSU_FAN1_FAULT); -static SENSOR_DEVICE_ATTR(psu_fan1_warning, S_IRUGO, for_fan_warning, NULL, PSU_FAN1_WARN); -static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, for_linear_data, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); -static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, for_linear_data, NULL, PSU_FAN1_SPEED); -static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, for_ascii, NULL, PSU_MFR_ID); -static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, for_ascii, NULL, PSU_MFR_MODEL); -static SENSOR_DEVICE_ATTR(psu_mfr_serial, S_IRUGO, for_ascii, NULL, PSU_MFR_SERIAL); + } + } + + mutex_unlock(&data->update_lock); + + return data; + +} + +/* sysfs attributes for hwmon */ +static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, for_linear_data, NULL, PSU_V_IN); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, for_vout_data, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, for_linear_data, NULL, PSU_I_IN); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, for_linear_data, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, for_linear_data, NULL, PSU_P_IN); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, for_linear_data, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp2_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP2_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp3_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP3_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, for_temp_fault, NULL, PSU_TEMP_FAULT); +static SENSOR_DEVICE_ATTR(psu_temp_warning, S_IRUGO, for_temp_warning, NULL, PSU_TEMP_WARN); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, for_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_fan1_warning, S_IRUGO, for_fan_warning, NULL, PSU_FAN1_WARN); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, for_linear_data, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, for_linear_data, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, for_ascii, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, for_ascii, NULL, PSU_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu_mfr_serial, S_IRUGO, for_ascii, NULL, PSU_MFR_SERIAL); static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, for_status, NULL, PSU_PRESENT); static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, for_status, NULL, PSU_P_GOOD); - + static struct attribute *cs6436_56p_psu_attributes[] = { - &sensor_dev_attr_psu_v_in.dev_attr.attr, - &sensor_dev_attr_psu_v_out.dev_attr.attr, - &sensor_dev_attr_psu_i_in.dev_attr.attr, - &sensor_dev_attr_psu_i_out.dev_attr.attr, - &sensor_dev_attr_psu_p_in.dev_attr.attr, - &sensor_dev_attr_psu_p_out.dev_attr.attr, - &sensor_dev_attr_psu_temp1_input.dev_attr.attr, - &sensor_dev_attr_psu_temp2_input.dev_attr.attr, - &sensor_dev_attr_psu_temp3_input.dev_attr.attr, - &sensor_dev_attr_psu_temp_fault.dev_attr.attr, - &sensor_dev_attr_psu_temp_warning.dev_attr.attr, - &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, - &sensor_dev_attr_psu_fan1_warning.dev_attr.attr, - &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, - &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, - &sensor_dev_attr_psu_mfr_id.dev_attr.attr, - &sensor_dev_attr_psu_mfr_model.dev_attr.attr, - &sensor_dev_attr_psu_mfr_serial.dev_attr.attr, + &sensor_dev_attr_psu_v_in.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_in.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_in.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_temp2_input.dev_attr.attr, + &sensor_dev_attr_psu_temp3_input.dev_attr.attr, + &sensor_dev_attr_psu_temp_fault.dev_attr.attr, + &sensor_dev_attr_psu_temp_warning.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_fan1_warning.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_mfr_serial.dev_attr.attr, &sensor_dev_attr_psu_present.dev_attr.attr, &sensor_dev_attr_psu_power_good.dev_attr.attr, - NULL -}; - + NULL +}; + static const struct attribute_group cs6436_56p_psu_group = { .attrs = cs6436_56p_psu_attributes, -}; - -static int cs6436_56p_psu_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ +}; + + +static int psu_register_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int status; + + struct cs6436_56p_psu_data *data; - int status; - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) { - status = -EIO; - goto exit; - } - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) { - status = -ENOMEM; - goto exit; - } - - i2c_set_clientdata(client, data); - data->valid = 0; - mutex_init(&data->update_lock); - - dev_info(&client->dev, "new chip found\n"); - - /* Register sysfs hooks */ + + if (!psu_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + /* Register sysfs hooks */ status = sysfs_create_group(&client->dev.kobj, &cs6436_56p_psu_group); - if (status) - goto exit_sysfs_create_group; - - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - status = PTR_ERR(data->hwmon_dev); - goto exit_hwmon_device_register; - } - - return 0; - -exit_hwmon_device_register: - sysfs_remove_group(&client->dev.kobj, &cs6436_56p_psu_group); -exit_sysfs_create_group: - kfree(data); -exit: - return status; -} - + if (status) + goto exit_sysfs_create_group; + + cs6436_56p_sysfs_add_client(client); + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_hwmon_device_register; + } + + /* init eeprom */ + + return 0; + + exit_hwmon_device_register: + sysfs_remove_group(&client->dev.kobj, &cs6436_56p_psu_group); + exit_sysfs_create_group: + kfree(data); + exit: + return status; + +} + + +static int cs6436_56p_psu_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int status; + + if((client->addr == 0x52) ||(client->addr == 0x53)) + { + status = psu_eeprom_probe(client, id); + } + else if((client->addr == 0x5a) ||(client->addr == 0x5b)) + { + status = psu_register_probe(client, id); + } + return status; +} + static int cs6436_56p_psu_remove(struct i2c_client *client) -{ - struct cs6436_56p_psu_data *data = i2c_get_clientdata(client); - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &cs6436_56p_psu_group); - kfree(data); - - return 0; -} - -enum psu_index -{ +{ + cs6436_56p_sysfs_remove_client(client); + + if((client->addr == 0x52) ||(client->addr == 0x53)) + { + struct cs6436_56p_psu_data *data; + data = i2c_get_clientdata(client); + psu_sysfs_eeprom_cleanup(&client->dev.kobj,data->bin); + kfree(data); + } + else if((client->addr == 0x5a) ||(client->addr == 0x5b)) + { + struct cs6436_56p_psu_data *data; + data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &cs6436_56p_psu_group); + kfree(data); + } + + return 0; +} + +enum psu_index +{ cs6436_56p_psu1, cs6436_56p_psu2 -}; - +}; + static const struct i2c_device_id cs6436_56p_psu_id[] = { { "cs6436_56p_psu1", cs6436_56p_psu1 }, { "cs6436_56p_psu2", cs6436_56p_psu2 }, - {} -}; + {} +}; MODULE_DEVICE_TABLE(i2c, cs6436_56p_psu_id); - + static struct i2c_driver cs6436_56p_psu_driver = { - .class = I2C_CLASS_HWMON, - .driver = { + .class = I2C_CLASS_HWMON, + .driver = { .name = "cs6436_56p_psu", - }, + }, .probe = cs6436_56p_psu_probe, .remove = cs6436_56p_psu_remove, .id_table = cs6436_56p_psu_id, - .address_list = normal_i2c, -}; + .address_list = normal_i2c, +}; module_i2c_driver(cs6436_56p_psu_driver); - -MODULE_AUTHOR("Zhang Peng "); + +MODULE_AUTHOR("Zhang Peng "); MODULE_DESCRIPTION("cs6436_56p_psu driver"); MODULE_LICENSE("GPL"); diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sfp.c b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sfp.c old mode 100755 new mode 100644 index f2b54a260fcb..5665fa33048b --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sfp.c +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sfp.c @@ -28,6 +28,7 @@ #include #include #include +#include "i2c-algo-lpc.h" #define DRIVER_NAME "cs6436_56p_sfp" /* Platform dependent */ @@ -64,15 +65,9 @@ #define SFF8436_RX_LOS_ADDR 3 #define SFF8436_TX_FAULT_ADDR 4 #define SFF8436_TX_DISABLE_ADDR 86 - - -#define ADDR_REG_SFP_STATUS_ADDR 0X62 //reg addr +R/W# //1031 -#define ADDR_REG_SFP_STATUS_TX 0X63 // write data -#define ADDR_REG_SFP_STATUS_RX 0X64 //read data -#define ADDR_REG_SFP_STATUS_COMMAND 0X65 //cmd bit7=1,go -#define ADDR_REG_SFP_STATUS_STATUS 0X66 //status - - +#define QSFP_RESET_ADDR 0x1b +#define QSFP_INTER_ADDR 0x1a +#define QSFP_LPMODE_ADDR 0x1c static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); static ssize_t show_port_type(struct device *dev, struct device_attribute *da, char *buf); @@ -87,6 +82,11 @@ static ssize_t sfp_eeprom_write(struct i2c_client *, u8 , const char *,int); extern int cig_cpld_read_register(u8 reg_off, u8 *val); extern int cig_cpld_write_register(u8 reg_off, u8 val); +static ssize_t qsfp_reset_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_reset_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_inter_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_lpmode_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_lpmode_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count); enum sfp_sysfs_attributes { PRESENT, @@ -109,7 +109,10 @@ enum sfp_sysfs_attributes { RX_LOS2, RX_LOS3, RX_LOS4, - RX_LOS_ALL + RX_LOS_ALL, + QSFPRESET, + QSFPINT, + QSFPLPMODE }; /* SFP/QSFP common attributes for sysfs */ @@ -134,6 +137,9 @@ static SENSOR_DEVICE_ATTR(sfp_tx_fault1, S_IRUGO, qsfp_show_tx_rx_status, NULL, static SENSOR_DEVICE_ATTR(sfp_tx_fault2, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT2); static SENSOR_DEVICE_ATTR(sfp_tx_fault3, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT3); static SENSOR_DEVICE_ATTR(sfp_tx_fault4, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT4); +static SENSOR_DEVICE_ATTR(sfp_reset, S_IWUSR | S_IRUGO, qsfp_reset_read, qsfp_reset_write, QSFPRESET); +static SENSOR_DEVICE_ATTR(sfp_inter, S_IRUGO, qsfp_inter_read, NULL, QSFPINT); +static SENSOR_DEVICE_ATTR(sfp_lpmode, S_IWUSR | S_IRUGO, qsfp_lpmode_read, qsfp_lpmode_write, QSFPLPMODE); static struct attribute *qsfp_attributes[] = { &sensor_dev_attr_sfp_port_number.dev_attr.attr, &sensor_dev_attr_sfp_port_type.dev_attr.attr, @@ -154,6 +160,9 @@ static struct attribute *qsfp_attributes[] = { &sensor_dev_attr_sfp_tx_fault2.dev_attr.attr, &sensor_dev_attr_sfp_tx_fault3.dev_attr.attr, &sensor_dev_attr_sfp_tx_fault4.dev_attr.attr, + &sensor_dev_attr_sfp_reset.dev_attr.attr, + &sensor_dev_attr_sfp_inter.dev_attr.attr, + &sensor_dev_attr_sfp_lpmode.dev_attr.attr, NULL }; @@ -342,13 +351,13 @@ static ssize_t show_port_number(struct device *dev, struct device_attribute *da, return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port)); } -#define WAIT_TIME_OUT_COUNT 100 + static int cig_cpld_write_sfp_register(u8 sfp_reg_addr, u8 sfp_write_reg_data) { u8 sfp_read_status = 0; u8 wait_time_out = WAIT_TIME_OUT_COUNT; - + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, sfp_reg_addr << 1); cig_cpld_write_register(ADDR_REG_SFP_STATUS_TX, sfp_write_reg_data); cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); @@ -371,7 +380,7 @@ static int cig_cpld_read_sfp_register(u8 sfp_reg_addr, u8 *sfp_read_reg_data) { u8 sfp_read_status = 0; u8 wait_time_out = WAIT_TIME_OUT_COUNT; - + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, sfp_reg_addr << 1 | 1); cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); do{ @@ -393,7 +402,7 @@ static int cig_cpld_read_sfp_register(u8 sfp_reg_addr, u8 *sfp_read_reg_data) - + /* Platform dependent +++ */ static struct sfp_port_data *sfp_update_present(struct i2c_client *client) @@ -411,7 +420,7 @@ static struct sfp_port_data *sfp_update_present(struct i2c_client *client) /* Read present status of port 1~48(SFP port) */ for (i = 0; i < 6; i++) { cpld_reg_addr = 1 + i; - + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); if (unlikely(status < 0)) { @@ -420,8 +429,8 @@ static struct sfp_port_data *sfp_update_present(struct i2c_client *client) } data->present |= (u64)cpld_reg_data << (i*8); - - DEBUG_PRINT("Present status = 0x%lx\r\n", data->present); + + DEBUG_PRINT("Present status = 0x%lx\r\n", data->present); } /* Read present status of port 49-56(QSFP port) */ @@ -433,7 +442,7 @@ static struct sfp_port_data *sfp_update_present(struct i2c_client *client) } else { data->present |= (u64)cpld_reg_data << 48; - } + } DEBUG_PRINT("Present status = 0x%lx", data->present); exit: @@ -463,7 +472,7 @@ static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) /* Read status of port 1~48(SFP port) */ for (i = 0; i < 6; i++) { cpld_reg_addr = 13+i; - + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); if (unlikely(status < 0)) { dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); @@ -471,14 +480,14 @@ static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) } data->msa->status[0] |= (u64)cpld_reg_data << (i * 8); - - DEBUG_PRINT("tx rx status[0] = 0x%lx\r\n", data->msa->status[0]); + + DEBUG_PRINT("tx rx status[0] = 0x%lx\r\n", data->msa->status[0]); } - + for (i = 0; i < 6; i++) { cpld_reg_addr = 19+i; - + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); if (unlikely(status < 0)) { dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); @@ -486,13 +495,13 @@ static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) } data->msa->status[1] |= (u64)cpld_reg_data << (i * 8); - - DEBUG_PRINT("tx rx status[1] = 0x%lx\r\n", data->msa->status[1]); + + DEBUG_PRINT("tx rx status[1] = 0x%lx\r\n", data->msa->status[1]); } for (i = 0; i < 6; i++) { cpld_reg_addr = 7+i; - + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); if (unlikely(status < 0)) { dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); @@ -500,8 +509,8 @@ static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) } data->msa->status[2] |= (u64)cpld_reg_data << (i * 8); - - DEBUG_PRINT("tx rx status[2] = 0x%lx\r\n", data->msa->status[2]); + + DEBUG_PRINT("tx rx status[2] = 0x%lx\r\n", data->msa->status[2]); } data->msa->valid = 1; @@ -531,12 +540,12 @@ static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *d } mutex_lock(&data->update_lock); - + udelay(6000); if(data->port <= 48) { cpld_reg_addr = 19 + data->port / 8; - cpld_reg_bit = 1 << (data->port); + cpld_reg_bit = 1 << ((data->port) % 8); } /* Read current status */ @@ -548,10 +557,10 @@ static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *d cpld_reg_data |= cpld_reg_bit; } else { - data->msa->status[1] &= ~BIT_INDEX(data->port); + data->msa->status[1] &= ~ BIT_INDEX(data->port); cpld_reg_data &= ~cpld_reg_bit; } - + error = cig_cpld_write_sfp_register(cpld_reg_addr,cpld_reg_data); mutex_unlock(&data->update_lock); @@ -582,7 +591,7 @@ static ssize_t show_present(struct device *dev, struct device_attribute *da, int i; u8 values[7] = {0}; struct sfp_port_data *data = sfp_update_present(client); - + if (IS_ERR(data)) { return PTR_ERR(data); } @@ -682,7 +691,7 @@ static ssize_t show_port_type(struct device *dev, struct device_attribute *da, char *buf) { struct i2c_client *client = to_i2c_client(dev); - struct sfp_port_data *data = i2c_get_clientdata(client); + struct sfp_port_data *data = i2c_get_clientdata(client); int present = sfp_is_port_present(client, data->port); if (IS_ERR_VALUE(present)) { @@ -750,6 +759,253 @@ static struct sfp_port_data *qsfp_update_tx_rx_status(struct device *dev) return (status < 0) ? ERR_PTR(status) : data; } +static ssize_t qsfp_inter_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_INTER_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("inter read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + + +static ssize_t qsfp_reset_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_RESET_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("reset read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_reset_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + long usrdata; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + ret = kstrtol(buf, 10, &usrdata); + if (ret) { + return ret; + } + + usrdata = usrdata > 0 ? 1 : 0; + index = data->port - 48; + + DEBUG_PRINT("usrdata = %u, index = %hhu\n", usrdata, index); + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_RESET_ADDR, &cpld_reg_data); + if (ret == 1) + { + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + cpld_reg_data &= ~(1 << index); + cpld_reg_data |= usrdata << index; + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + ret = cig_cpld_write_sfp_register(QSFP_RESET_ADDR, cpld_reg_data); + if (1 != ret) + { + DEBUG_PRINT("write failed\n"); + } + } + else + { + DEBUG_PRINT("read failed\n"); + } + + mutex_unlock(&data->update_lock); + + if (ret != 1) + return -1; + + return count; +} + + + + +static ssize_t qsfp_lpmode_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_LPMODE_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("lpmode read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_lpmode_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + long usrdata; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + ret = kstrtol(buf, 10, &usrdata); + if (ret) { + return ret; + } + + usrdata = usrdata > 0 ? 1 : 0; + index = data->port - 48; + + DEBUG_PRINT("usrdata = %u, index = %hhu\n", usrdata, index); + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_LPMODE_ADDR, &cpld_reg_data); + if (ret == 1) + { + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + cpld_reg_data &= ~(1 << index); + cpld_reg_data |= usrdata << index; + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + ret = cig_cpld_write_sfp_register(QSFP_LPMODE_ADDR, cpld_reg_data); + if (1 != ret) + { + DEBUG_PRINT("write failed\n"); + } + } + else + { + DEBUG_PRINT("read failed\n"); + } + + mutex_unlock(&data->update_lock); + + if (ret != 1) + return -1; + + return count; +} + + + static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf) { @@ -822,7 +1078,7 @@ static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute * int status; struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct i2c_client *client = to_i2c_client(dev); - struct sfp_port_data *data = i2c_get_clientdata(client); + struct sfp_port_data *data = i2c_get_clientdata(client); status = sfp_is_port_present(client, data->port); if (IS_ERR_VALUE(status)) { @@ -922,13 +1178,13 @@ static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute for (i = 0; i < ARRAY_SIZE(values); i++) { values[i] = (u8)(data->msa->status[2] >> (i * 8)); } - + /** Return values 1 -> 48 in order */ return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x\n", values[0], values[1], values[2], - values[3], values[4], values[5]); + values[3], values[4], values[5]); } - + switch (attr->index) { case TX_FAULT: index = 0; @@ -938,7 +1194,7 @@ static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute break; case RX_LOS: index = 2; - break; + break; default: break; } @@ -1246,6 +1502,8 @@ static int sfp_msa_probe(struct i2c_client *client, const struct i2c_device_id * *data = msa; dev_info(&client->dev, "sfp msa '%s'\n", client->name); + cs6436_56p_sysfs_add_client(client); + return 0; exit_remove: @@ -1386,7 +1644,7 @@ static int sfp_device_probe(struct i2c_client *client, return qsfp_probe(client, dev_id, &data->qsfp); } } - + return -ENODEV; } /* Platform dependent --- */ @@ -1419,6 +1677,7 @@ static int sfp_device_remove(struct i2c_client *client) { struct sfp_port_data *data = i2c_get_clientdata(client); + cs6436_56p_sysfs_remove_client(client); switch (data->driver_type) { case DRIVER_TYPE_SFP_MSA: return sfp_msa_remove(client, data->msa); diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sysfs.c b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sysfs.c new file mode 100644 index 000000000000..89f6bba3aab2 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sysfs.c @@ -0,0 +1,335 @@ +/* + * A hwmon driver for the CIG cs6436-56P sysfs Module + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "i2c-algo-lpc.h" + + +static LIST_HEAD(sysfs_client_list); +static struct mutex list_lock; + +struct sysfs_client_node { + struct i2c_client *client; + struct list_head list; +}; + +#define DEVICE_NAME "cigfs" +static int dev_major; +static struct class *dev_class; +static struct cdev *dev_cdev; +static struct device *dev_device; +static struct class *psu_class; +static struct class *sfp_class; + + +void cs6436_56p_sysfs_add_client(struct i2c_client *client) +{ + struct sysfs_client_node *node = kzalloc(sizeof(struct sysfs_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate sysfs_client_node (0x%x)\n", client->addr); + return; + } + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &sysfs_client_list); + mutex_unlock(&list_lock); +} + +EXPORT_SYMBOL(cs6436_56p_sysfs_add_client); + +void cs6436_56p_sysfs_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (IS_ERR(sysfs_node)) + { + break; + } + if (sysfs_node->client == client) { + found = 1; + break; + } + } + if (found) { + list_del(list_node); + kfree(sysfs_node); + } + + mutex_unlock(&list_lock); +} + +EXPORT_SYMBOL(cs6436_56p_sysfs_remove_client); + +struct class * cs6436_56p_sysfs_create_symclass(char *cls_name) +{ + int rc = 0; + struct class *my_class; +/**************************************************************************************/ + my_class = class_create(THIS_MODULE,cls_name); + if (IS_ERR(my_class)) { + pr_err("failed to create my class\n"); + } + return my_class; + +/**************************************************************************************/ +} + +void cs6436_56p_sysfs_delete_symclass(struct class *my_class) +{ +/**************************************************************************************/ + + if (IS_ERR(my_class)) { + pr_err("Pointer is invaild\n"); + } + class_destroy(my_class); + +/**************************************************************************************/ +} + + + + + +int cs6436_56p_sysfs_create_symlink(struct class *my_class,char * driver_name,char *device_name) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int ret = -EPERM; + int rc = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (!strcmp(sysfs_node->client->name,driver_name)) { + rc = sysfs_create_link(&my_class->p->subsys.kobj, &sysfs_node->client->dev.kobj,device_name); + if(rc) + { + pr_err("failed to create symlink %d\n",rc); + } + break; + } + } + mutex_unlock(&list_lock); + return ret; +} + + +int cs6436_56p_sysfs_delete_symlink(struct class *my_class,char * driver_name,char *device_name) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int ret = -EPERM; + int rc = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (!strcmp(sysfs_node->client->name,driver_name)) { + sysfs_remove_link(&my_class->p->subsys.kobj,device_name); + break; + } + } + mutex_unlock(&list_lock); + return ret; +} + + +static int cs6436_56p_sysfs_open(struct inode *inode, struct file *file) +{ + return 0; +} + + + +static ssize_t cs6436_56p_sysfs_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) +{ + char str[10],name[18],port[8]; + int ret; + int i; + memset(str, 0, sizeof(str)); + ret = copy_from_user(str, buf, count); + if (ret) + { + printk(KERN_ERR "copy_from_user fail\n"); + return -EINVAL; + } + + if(!strncmp(str,"start",5)) + { + psu_class = cs6436_56p_sysfs_create_symclass("psu"); + cs6436_56p_sysfs_create_symlink(psu_class,"cs6436_56p_psu1","psu1"); + cs6436_56p_sysfs_create_symlink(psu_class,"cs6436_56p_psu2","psu2"); + sfp_class = cs6436_56p_sysfs_create_symclass("swps"); + for(i = 1; i <= 48;i++) + { + memset(name,0xff,sizeof(name)); + memset(port,0xff,sizeof(port)); + snprintf(name,sizeof(name),"cs6436_56p_sfp%d",i); + snprintf(port,sizeof(port),"port%d",i); + cs6436_56p_sysfs_create_symlink(sfp_class,name,port); + } + } + else if(!strncmp(str,"stop",4)) + { + cs6436_56p_sysfs_delete_symlink(psu_class,"cs6436_56p_psu1","psu1"); + cs6436_56p_sysfs_delete_symlink(psu_class,"cs6436_56p_psu2","psu2"); + cs6436_56p_sysfs_delete_symclass(psu_class); + + for(i = 1; i <= 48;i++) + { + memset(name,0xff,sizeof(name)); + memset(port,0xff,sizeof(port)); + snprintf(name,sizeof(name),"cs6436_56p_sfp%d",i); + snprintf(port,sizeof(port),"port%d",i); + cs6436_56p_sysfs_delete_symlink(sfp_class,name,port); + } + cs6436_56p_sysfs_delete_symclass(sfp_class); + } + return count; +} + + +static struct file_operations cs6436_56p_sysfs_fops = { + .owner = THIS_MODULE, + .open = cs6436_56p_sysfs_open, + .write = cs6436_56p_sysfs_write, +}; + + +static int __init cs6436_56p_sysfs_init(void) +{ + int result = 0; + int err = 0; + dev_t dev = MKDEV(dev_major, 0); + + if (dev_major) + result = register_chrdev_region(dev, 1, DEVICE_NAME); + else { + result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME); + dev_major = MAJOR(dev); + } + if (result < 0) + { + printk("unable to get major %d\n", dev_major); + err= -EINVAL; + } + printk("get major is %d\n", dev_major); + if (dev_major == 0) + dev_major = result; + + dev_cdev= kmalloc(sizeof(struct cdev), GFP_KERNEL); + if(IS_ERR(dev_cdev)) { + err= -ENOMEM; + } + + cdev_init(dev_cdev, &cs6436_56p_sysfs_fops); + dev_cdev->owner = THIS_MODULE; + dev_cdev->ops = &cs6436_56p_sysfs_fops; + err = cdev_add(dev_cdev, dev, 1); + if (err) + { + printk("error %d add fpga ", err); + goto err_malloc; + } + + dev_class = class_create(THIS_MODULE, DEVICE_NAME); + if (IS_ERR(dev_class)) + { + printk("Err:failed in creating class.\n"); + goto err_cdev_add; + } + + dev_device = device_create(dev_class, NULL, MKDEV(dev_major, 0), NULL, DEVICE_NAME); + if (IS_ERR(dev_device)) + { + printk("Err:failed in creating device.\n"); + goto err_class_crt; + } + + mutex_init(&list_lock); + + return err; + + err_class_crt: + cdev_del(dev_cdev); + err_cdev_add: + kfree(dev_cdev); + err_malloc: + unregister_chrdev_region(MKDEV(dev_major,0), 1); + + return err; + +} + +static void __exit cs6436_56p_sysfs_exit(void) +{ + cdev_del(dev_cdev); + printk("cdev_del ok\n"); + device_destroy(dev_class, MKDEV(dev_major, 0)); + + class_destroy(dev_class); + + if(dev_cdev != NULL) + kfree(dev_cdev); + + unregister_chrdev_region(MKDEV(dev_major, 0), 1); + printk("cs6436_56p_sysfs_exit...\r\n"); +} + + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs6436-56p-sysfs driver"); +MODULE_LICENSE("GPL"); + +module_init(cs6436_56p_sysfs_init); +module_exit(cs6436_56p_sysfs_exit); + + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-init.service b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-init.service old mode 100755 new mode 100644 diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-misc.service b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-misc.service old mode 100755 new mode 100644 index 7ff410cbb3c1..ed44bc0b3438 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-misc.service +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-misc.service @@ -4,7 +4,7 @@ After=cs6436-platform-init.service DefaultDependencies=no [Service] -ExecStart=/usr/local/bin/cig_cs6436_misc.py +ExecStart=/usr/local/bin/cig_cs6436_misc.py KillSignal=SIGKILL SuccessExitStatus=SIGKILL diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_misc.py b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_misc.py index 08decef98ad0..3b685236a075 100755 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_misc.py +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_misc.py @@ -21,12 +21,259 @@ import logging import re import time +import datetime from collections import namedtuple from threading import Thread DEBUG = False i2c_prefix = '/sys/bus/i2c/devices/' -cs6436__prefix = '/sys/devices/platform/cs6436_56p_led/leds/' +leds_prefix = '/sys/devices/platform/cs6436_56p_led/leds/' +fans_prefix = '/sys/devices/platform/cs6436_56p_fan/' +fansdir_prefix = fans_prefix + 'fan{}_direction' + +ageing_controlfile = '/etc/sonic/agcontrol' +AGFlag = 0 + + +platform_misc_log = '/var/log/platform_misc.log' +misclogger = logging.getLogger('platform_misc') +misclogger.setLevel(logging.INFO) +miscformatter = logging.Formatter('%(asctime)s-%(levelname)s-%(message)s') + +if not os.path.isfile(platform_misc_log): + try: + os.mknod(platform_misc_log) + except: + print 'Failed to creat platform_misc.log' + +fileHandler = logging.FileHandler(platform_misc_log) +fileHandler.setLevel(logging.INFO) +fileHandler.setFormatter(miscformatter) +misclogger.addHandler(fileHandler) + + +starttime = datetime.datetime.now() +IsGetlswt = 0 +coretemp_prefix = '/sys/class/hwmon/hwmon1/' +coretemp_ps = [] +psu1_p = '/sys/bus/i2c/devices/5-005a/psu_present' +psu2_p = '/sys/bus/i2c/devices/5-005b/psu_present' +psu1_d = '/sys/bus/i2c/devices/5-0052/psu_eeprom' +psu2_d = '/sys/bus/i2c/devices/5-0053/psu_eeprom' +psu1led_d = leds_prefix + 'cs6436_56p_led::psu1/brightness' +psu2led_d = leds_prefix + 'cs6436_56p_led::psu2/brightness' +cs6436_ledpath = {'fan':leds_prefix + 'cs6436_56p_led::fan/brightness', + 'fan1':leds_prefix + 'cs6436_56p_led::fan1/brightness', + 'fan2':leds_prefix + 'cs6436_56p_led::fan2/brightness', + 'fan3':leds_prefix + 'cs6436_56p_led::fan3/brightness', + 'fan4':leds_prefix + 'cs6436_56p_led::fan4/brightness', + 'fan5':leds_prefix + 'cs6436_56p_led::fan5/brightness', + 'psu1':leds_prefix + 'cs6436_56p_led::psu1/brightness', + 'psu2':leds_prefix + 'cs6436_56p_led::psu2/brightness', + 'sys':leds_prefix + 'cs6436_56p_led::sys/brightness'} + + +def system_read_filestr(node): + with open(node, 'r') as f: + try: + str = f.read() + except IOError as e: + misclogger.error('Failed to get node, str={}'.format(node)) + return "0" + return str + + +def system_bright_leds(dev, colour): + global AGFlag + + if AGFlag == 1: + return + + cmd = 'echo {} > {}'.format(colour, dev) + log_os_system(cmd, 1) + return + +''' +1: front in tail out +0: front out tail in +''' +def system_getpsu_direction(dev): + try: + with open(dev) as f: + f.seek(0x30) + str = f.read(2) + except IOError as e: + misclogger.error('Failed to get psu eep') + return 1 + if str == 'AA': ## front in tail out + return 1 + elif str == 'RA':## tail in front out + return 0 + else: + misclogger.error('Failed to get psu eep, str={}'.format(str)) + return -1 + + +def system_get_cputype(): + cmdretfd = os.popen("lscpu | grep 'Model name'") + retstring = cmdretfd.read() + endindex = retstring.find('@') - 1 + startindex = retstring[:endindex].rfind(' ') + 1 + cputype = retstring[startindex:endindex] + + return cputype + + +def system_init_coretemppath(): + global coretemp_ps + + cmdstr = "ls {} | grep 'input'".format(coretemp_prefix) + cmdretfd = os.popen(cmdstr) + + coretemppss = cmdretfd.read().splitlines() + if len(coretemppss) < 3: + cputype = system_get_cputype() + misclogger.error('Failed to init core temperature path.' + ' cpu type = {}, num thermal = {}'.format(cputype, len(coretemp_ps))) + return 1 + + for i in range(0,3): + coretemp_ps.append(coretemp_prefix + coretemppss[i]) + + print coretemp_ps + + return 0 + + +class cs6436_fanattr: + def __init__(self, name): + self.name = name + self.direction = 0 + self.direction_p = '' + self.rear = 0 + self.rear_p = '' + self.front = 0 + self.front_p = '' + self.fault = 0 + self.fault_p = '' + self.status = 0 + self.setpath() + self.updatedevice() + + return + + def setpath(self): + self.direction_p = fans_prefix + '{}_direction'.format(self.name) + self.rear_p = fans_prefix + '{}_rear_speed_rpm'.format(self.name) + self.front_p = fans_prefix + '{}_front_speed_rpm'.format(self.name) + self.fault_p = fans_prefix + '{}_fault'.format(self.name) + + return + + def updatedevice(self): + self.direction = int(system_read_filestr(self.direction_p)) + self.rear = int(system_read_filestr(self.rear_p)) + self.front = int(system_read_filestr(self.front_p)) + self.fault = int(system_read_filestr(self.fault_p)) + + return + + def checkspeedrpm(self, speedrpm): + frontrpmexp = speedrpm * 21000 / 100 + rearrpmexp = speedrpm * 19000 / 100 + deviationfront = abs(frontrpmexp - self.front) / float(frontrpmexp) + deviationrear = abs(rearrpmexp - self.rear) / float(rearrpmexp) + + if deviationfront < 0.3 and deviationrear < 0.3: + return 0 + else: + misclogger.error(':{} speed wrong. frontexp is {}, but rpm is {}.rearexp is {}, but rpm is {}'.format(self.name, frontrpmexp, self.front, rearrpmexp, self.rear)) + return 1 + + def checkstatus(self, speedrpm, totaldirct): + speedstatus = self.checkspeedrpm(speedrpm) + if self.direction != totaldirct: + self.status = 1 + misclogger.error(':{} direction = {}.fan direction is not ok.'.format(self.name, self.direction)) + elif speedstatus != 0: + self.status = 1 + elif self.fault != 0: + misclogger.error(':{} fault.'.format(self.name)) + self.status = 1 + else: + self.status = 0 + + if self.status == 1: + system_bright_leds(cs6436_ledpath[self.name], 3) + else: + system_bright_leds(cs6436_ledpath[self.name], 1) + + return self.status + +cs6436_fanattrnodes = [] + + +class cs6436_psuattr: + def __init__(self, name): + self.name = name + self.direction = 0 + self.direction_p = '' + self.present = 0 + self.present_p = '' + self.status = 0 + + self.setpath() + self.updatepresent() + self.updatedirection() + + return + + def setpath(self): + if self.name == 'psu1': + self.present_p = psu1_p + self.direction_p = psu1_d + if self.name == 'psu2': + self.present_p = psu2_p + self.direction_p = psu2_d + + return + + def updatepresent(self): + self.present = int(system_read_filestr(self.present_p)) + + return + + def updatedirection(self): + if self.present == 1: + self.direction = system_getpsu_direction(self.direction_p) + else: + self.direction = 2 + + return + + def checkstatus(self, totaldirct): + if self.present != 1: + self.status = 1 + misclogger.error(':{} not present.'.format(self.name)) + elif self.direction == 2: + self.status = 0 + misclogger.info(':{} direction need to be update.'.format(self.name)) + elif self.direction != totaldirct: + self.status = 1 + misclogger.info(':{} direction is wrong.'.format(self.name)) + else: + self.status = 0 + + if self.status == 1: + system_bright_leds(cs6436_ledpath[self.name], 3) + else: + system_bright_leds(cs6436_ledpath[self.name], 1) + + return self.status + +cs6436_psuattrnodes = [] + + def my_log(txt): if DEBUG == True: @@ -36,15 +283,15 @@ def my_log(txt): def device_exist(): ret1, log = log_os_system("ls "+i2c_prefix+"5-005a", 0) ret2, log = log_os_system("ls "+i2c_prefix+"5-005b", 0) - ret3, log = log_os_system("ls "+cs6436__prefix+"cs6436_56p_led*", 0) + ret3, log = log_os_system("ls "+leds_prefix+"cs6436_56p_led*", 0) return not(ret1 or ret2 or ret3) - + def log_os_system(cmd, show): - logging.info('Run :'+cmd) - status, output = commands.getstatusoutput(cmd) + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) my_log (cmd +"with result:" + str(status)) - my_log (" output:"+output) + my_log (" output:"+output) if status: logging.info('Failed :'+cmd) if show: @@ -52,7 +299,223 @@ def log_os_system(cmd, show): return status, output -def system_misc_polling(threadName,delay): +def system_get_coretemp(): + temp1 = system_read_filestr(coretemp_ps[0]).strip() + temp2 = system_read_filestr(coretemp_ps[1]).strip() + temp3 = system_read_filestr(coretemp_ps[2]).strip() + + return int(temp1), int(temp2), int(temp3) + +def system_get_boardtemp(): + for i in range(0,16): + temp1path = "/sys/bus/i2c/devices/5-004a/hwmon/hwmon%d/temp1_input" % i + if os.access(temp1path, os.F_OK): + break + for i in range(0,16): + temp2path = "/sys/bus/i2c/devices/5-004b/hwmon/hwmon%d/temp1_input" % i + if os.access(temp2path, os.F_OK): + break + temp1 = system_read_filestr(temp1path).strip() + temp2 = system_read_filestr(temp2path).strip() + + return int(temp1), int(temp2) + + +def system_get_lswtemp(): + global IsGetlswt + global starttime + if IsGetlswt == 0: + now = datetime.datetime.now() + misclogger.info("time wait.") + misclogger.info("start = {}, now = {}.".format(starttime, now)) + if (now - starttime).seconds > 150: + misclogger.info("time = ".format((now - starttime).seconds)) + IsGetlswt = 1 + + return 25 + +# chp = subprocess.Popen("docker ps --filter name=syncd", shell=True, stdout=subprocess.PIPE) +# if chp.poll() == None: +# misclogger.info("No subp.") +# chp.kill() +# +# return 25 + +# retstring = chp.stdout.read() +# chp.kill() +# if 'Up' not in retstring: +# misclogger.info("lsw not up.") +# +# return 25 + + status, output = log_os_system('npx_diag swc show temperature', 1) + if status: + misclogger.error('failed to show lsw temperature') + + return 25 + + output = output.strip() + if output.find("it 0, temperature ") > 0: + startindex = output.find('temperature') + len('temperature') + 1 + endindex = output[startindex:].find(" ") + endindex = startindex + endindex + temp = output[startindex:endindex] + b = temp.find('.') + if b > 0: + temp=temp[:b] + temp = int(temp) + else: + misclogger.error("Failed to get temperature.") + temp = 0 + + return int(temp) + +def system_monitor_temperature(): + + ctemp1, ctemp2, ctemp3 = system_get_coretemp() + btemp1, btemp2 = system_get_boardtemp() + ltemp = system_get_lswtemp() + fan_speed_str = system_cs6436_getfanexspeed() + fan_speed = int(fan_speed_str) + policy = 'stay' + pos = 0 + #speed c1 c2 c3 b1 b2 lsw + fan_policy_up = ([30, 40000, 40000, 40000, 42000, 35000, 95], + [40, 44000, 44000, 44000, 44000, 39000, 96], + [50, 49000, 49000, 49000, 47000, 44000, 91], + [60, 52000, 52000, 52000, 51500, 47500, 92], + [70, 53000, 53000, 53000, 52000, 49000, 93], + [100,999999,999999,999999,999999,999999,999]) + + fan_policy_down=([30, 0, 0, 0, 0, 0, 0], + [40, 34000, 34000, 34000, 34000, 30000, 80], + [50, 38000, 38000, 38000, 37000, 33000, 81], + [60, 44000, 44000, 44000, 43000, 39000, 84], + [70, 44000, 44000, 44000, 43000, 40000, 84], + [100, 48000, 48000, 48000, 46000, 42000, 85],) + + for policytable in fan_policy_up: + if fan_speed <= policytable[0]: + break + pos = pos + 1 + fan_speed = policytable[0] + if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]): + policy = 'stay' + policytable = fan_policy_down[pos] + if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]): + policy = 'down' + else: + policy = 'up' + + if policy == 'up': + misclogger.info("speed = %d." % fan_speed) + misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3)) + misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2)) + misclogger.info("lsw = %d" % ltemp) + fan_speed = fan_policy_down[pos + 1][0] + misclogger.info("fan policy: up. speedexp = {}".format(fan_speed)) + + if policy == 'stay': + fan_speed = fan_policy_down[pos] + return + + if policy == 'down': + misclogger.info("speed = %d." % fan_speed) + misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3)) + misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2)) + misclogger.info("lsw = %d" % ltemp) + fan_speed = fan_policy_down[pos - 1][0] + misclogger.info("fan policy: down.speedexp = {}".format(fan_speed)) + + cmd = "echo %d > /sys/devices/platform/cs6436_56p_fan/fan_duty_cycle_percentage" % fan_speed + status, output = log_os_system(cmd, 1) + if status: + misclogger.error("set fan speed fault") + + return + + +def system_cs6436_setfanexspeed(num): + fanspeednode = fans_prefix + 'fan_duty_cycle_percentage' + numstr = str(num) + with open(fanspeednode, 'w') as f: + f.write(numstr) + + +def system_cs6436_getfanexspeed(): + fanspeednode = fans_prefix + 'fan_duty_cycle_percentage' + fanspeedstr = system_read_filestr(fanspeednode) + fanspeedexp = int(fanspeedstr) + + return fanspeedexp + + +def system_cs6436_getdirection(): + global cs6436_fanattrnodes + direction = 0 + + for fan in cs6436_fanattrnodes: + direction = direction + fan.direction + + if direction > 2: + direction = 1 + else: + direction = 0 + + return direction + + +def system_check_psusdirection(): + global cs6436_psuattrnodes + cs6436totaldirct = system_cs6436_getdirection() + psutatus = 0 + + for psu in cs6436_psuattrnodes: + psu.updatedirection() + psu.checkstatus(cs6436totaldirct) + psutatus = psu.status + psutatus + + return (psutatus != 0) + + +def system_check_psuspresent(): + global cs6436_psuattrnodes + cs6436totaldirct = system_cs6436_getdirection() + psutatus = 0 + + for psu in cs6436_psuattrnodes: + psu.updatepresent() + psu.checkstatus(cs6436totaldirct) + psutatus = psu.status + psutatus + + return (psutatus != 0) + + +def system_check_fansstate(): + global cs6436_fanattrnodes + global cs6436_ledpath + cs6436totaldirct = system_cs6436_getdirection() + fanstatus = 0 + fanexspeed = 0 + + fanexspeed = system_cs6436_getfanexspeed() + + for fan in cs6436_fanattrnodes: + fan.updatedevice() + fan.checkstatus(fanexspeed, cs6436totaldirct) + fanstatus = fanstatus + fan.status + + if fanstatus > 0: + misclogger.error(':fan error.set fans speed 100.') + system_cs6436_setfanexspeed(100) + system_bright_leds(cs6436_ledpath['fan'], 3) + else: + system_bright_leds(cs6436_ledpath['fan'], 1) + + return (fanstatus != 0) + + +def system_misc_polling(threadName,delay): for count in range(1,5): if device_exist() == False: time.sleep(delay+3) @@ -62,93 +525,50 @@ def system_misc_polling(threadName,delay): if count == 4: return - + status, output = log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::sys/brightness", 1) status, output = log_os_system("hwconfig -cfp 1", 1) + global AGFlag + if os.access(ageing_controlfile, os.F_OK): + AGFlag = 1 + else: + AGFlag = 0 + + os.system('csw_daemon &') + + + global cs6436_fanattrnodes + global cs6436_psuattrnodes + + for num in range(1,6): + name = 'fan{}'.format(num) + fannode = cs6436_fanattr(name) + cs6436_fanattrnodes.append(fannode) + for num in range(1,3): + name = 'psu{}'.format(num) + psunode = cs6436_psuattr(name) + cs6436_psuattrnodes.append(psunode) + + tempcontrol = system_init_coretemppath() + + misclogger.info("%s: %s misc start." % ( threadName, time.ctime(time.time()))) + count = 0 while 1: - status, output = log_os_system("cat /sys/bus/i2c/devices/5-005a/psu_present", 1) - if status: - print "failed to check status for 5-005a/psu_present" - continue - - if output=='1': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::psu1/brightness", 1) - else: - log_os_system("echo 0 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::psu1/brightness", 1) - - status, output = log_os_system("cat /sys/bus/i2c/devices/5-005b/psu_present", 1) - if status: - print "failed to check status for 5-005b/psu_present" - continue - - if output=='1': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::psu2/brightness", 1) - else: - log_os_system("echo 0 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::psu2/brightness", 1) - - status, fan1 = log_os_system(" cat /sys/devices/platform/cs6436_56p_fan/fan1_fault",1) - if status: - print "failed to check status for cs6436_56p_fan/fan1_fault" - continue - - if fan1=='0': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan1/brightness", 1) - else: - log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan1/brightness", 1) - - status, fan2 = log_os_system(" cat /sys/devices/platform/cs6436_56p_fan/fan2_fault",1) - - if status: - print "failed to check status for cs6436_56p_fan/fan2_fault" - continue - - if fan2=='0': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan2/brightness", 1) - else: - log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan2/brightness", 1) - - status, fan3 = log_os_system(" cat /sys/devices/platform/cs6436_56p_fan/fan3_fault",1) - if status: - print "failed to check status for cs6436_56p_fan/fan3_fault" - continue - - if fan3=='0': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan3/brightness", 1) - else: - log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan3/brightness", 1) - - status, fan4 = log_os_system(" cat /sys/devices/platform/cs6436_56p_fan/fan4_fault",1) - if status: - print "failed to check status for cs6436_56p_fan/fan4_fault" - continue - - if fan4=='0': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan4/brightness", 1) - else: - log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan4/brightness", 1) - - status, fan5 = log_os_system(" cat /sys/devices/platform/cs6436_56p_fan/fan5_fault",1) - if status: - print "failed to check status for cs6436_56p_fan/fan5_fault" - continue - - if fan5=='0': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan5/brightness", 1) - else: - log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan5/brightness", 1) - - if fan1=='0' or fan2=='0' or fan3=='0' or fan4=='0' or fan5=='0': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan/brightness", 1) - else: - log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan/brightness", 1) + count = count + 1 + ret = system_check_psuspresent() + ret = system_check_fansstate() + + if count % 10 == 0: + misclogger.info(": adjust fans and check psu direction.") + system_check_psusdirection() + if tempcontrol == 0: + system_monitor_temperature() + count = 0 time.sleep(delay) - print "%s: %s" % ( threadName, time.ctime(time.time())) + return if __name__ == '__main__': - target=system_misc_polling("Thread-misc",3) - - - + target=system_misc_polling("Thread-misc",10) diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_util.py b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_util.py index 2b64d2e107b9..86285c7e4106 100755 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_util.py +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_util.py @@ -21,13 +21,13 @@ options: -h | --help : this help message -d | --debug : run with debug mode - -f | --force : ignore error during installation or clean + -f | --force : ignore error during installation or clean command: install : install drivers and generate related sysfs nodes clean : uninstall drivers and remove related sysfs nodes show : show all systen status sff : dump SFP eeprom - set : change board setting with fan|led|sfp + set : change board setting with fan|led|sfp """ import os @@ -42,47 +42,48 @@ PROJECT_NAME = 'cs6436_56p' -version = '0.1.0' +version = '0.1.1' verbose = False DEBUG = False args = [] -ALL_DEVICE = {} +ALL_DEVICE = {} DEVICE_NO = {'led':9, 'fan':5, 'thermal':4, 'psu':2, 'sfp':56} FORCE = 0 +CPU_TYPE = 'C3308' if DEBUG == True: print sys.argv[0] - print 'ARGV :', sys.argv[1:] + print 'ARGV :', sys.argv[1:] def main(): global DEBUG global args global FORCE - + if len(sys.argv)<2: show_help() - + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', 'debug', 'force', ]) - if DEBUG == True: + if DEBUG == True: print options print args print len(sys.argv) - + for opt, arg in options: if opt in ('-h', '--help'): show_help() - elif opt in ('-d', '--debug'): + elif opt in ('-d', '--debug'): DEBUG = True logging.basicConfig(level=logging.INFO) - elif opt in ('-f', '--force'): + elif opt in ('-f', '--force'): FORCE = 1 else: - logging.info('no option') - for arg in args: + logging.info('no option') + for arg in args: if arg == 'install': do_install() elif arg == 'clean': @@ -92,23 +93,23 @@ def main(): elif arg == 'sff': if len(args)!=2: show_eeprom_help() - elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: show_eeprom_help() else: - show_eeprom(args[1]) - return + show_eeprom(args[1]) + return elif arg == 'set': if len(args)<3: show_set_help() else: - set_device(args[1:]) - return + set_device(args[1:]) + return else: show_help() - - - return 0 - + + + return 0 + def show_help(): print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} sys.exit(0) @@ -117,31 +118,31 @@ def show_set_help(): cmd = sys.argv[0].split("/")[-1]+ " " + args[0] print cmd +" [led|sfp|fan]" print " use \""+ cmd + " led 0-4 \" to set led color" - print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" - print " use \""+ cmd + " sfp 1-56 {0|1}\" to set sfp# tx_disable" - sys.exit(0) - + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-56 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + def show_eeprom_help(): cmd = sys.argv[0].split("/")[-1]+ " " + args[0] - print " use \""+ cmd + " 1-56 \" to dump sfp# eeprom" - sys.exit(0) - + print " use \""+ cmd + " 1-56 \" to dump sfp# eeprom" + sys.exit(0) + def my_log(txt): if DEBUG == True: - print "[ROY]"+txt + print "[ROY]"+txt return - + def log_os_system(cmd, show): - logging.info('Run :'+cmd) - status, output = commands.getstatusoutput(cmd) + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) my_log (cmd +"with result:" + str(status)) - my_log (" output:"+output) + my_log (" output:"+output) if status: logging.info('Failed :'+cmd) if show: print('Failed :'+cmd) return status, output - + def driver_check(): for count in range(1,5): time.sleep(1) @@ -154,11 +155,11 @@ def driver_check(): if len(lsmod) > 2: log_os_system("rmmod i2c_designware_platform", 0) log_os_system("modprobe i2c-designware-platform", 0) - + ret, lsmod = log_os_system("lsmod| grep cig", 0) logging.info('mods:'+lsmod) if len(lsmod) ==0: - return False + return False return True @@ -167,6 +168,7 @@ def driver_check(): 'depmod', 'modprobe i2c_dev', 'modprobe i2c_mux_pca954x force_deselect_on_exit=1', + 'modprobe x86-64-cig-cs6436-56p-sysfs ' , 'modprobe x86-64-cig-cs6436-56p-cpld ' , 'modprobe x86-64-cig-cs6436-56p-fan' , 'modprobe x86-64-cig-cs6436-56p-psu' , @@ -175,28 +177,31 @@ def driver_check(): def driver_install(): global FORCE - + for i in range(0,len(kos)): - if i == 3: - ret, board_type = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 32-39 | head -n 1", 0) - if board_type=='i3-6100U': - kos[i] =kos[i] + 'board_id=1' - + if i == 4: + ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 32-39 | head -n 1", 0) + if CPU_TYPE=='i3-6100U': + kos[i] =kos[i] + 'board_id=1' + ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 36-40 | head -n 1", 0) + if CPU_TYPE=='C3758' or CPU_TYPE=='C3308': + kos[i] =kos[i] + 'board_id=2' + status, output = log_os_system(kos[i], 1) if status: - if FORCE == 0: - return status + if FORCE == 0: + return status return 0 - + def driver_uninstall(): global FORCE for i in range(0,len(kos)): rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") - rm = rm.replace("insmod", "rmmod") + rm = rm.replace("insmod", "rmmod") status, output = log_os_system(rm, 1) if status: - if FORCE == 0: - return status + if FORCE == 0: + return status return 0 led_prefix ='/sys/class/leds/'+PROJECT_NAME+'_led::' @@ -245,23 +250,22 @@ def driver_uninstall(): def device_install(): global FORCE - + for i in range(0,len(mknod)): - #for pca954x need times to built new i2c buses - if mknod[i].find('pca954') != -1: - time.sleep(1) - + #all nodes need times to built new i2c buses + time.sleep(1) + status, output = log_os_system(mknod[i], 1) if status: print output - if FORCE == 0: + if FORCE == 0: return status - + for i in range(0,len(sfp_map)): status, output =log_os_system("echo cs6436_56p_sfp"+str(i+1)+" 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) if status: print output - if FORCE == 0: + if FORCE == 0: return status if i <= 47: @@ -271,21 +275,21 @@ def device_install(): if FORCE == 0: return status - return - + return + def device_uninstall(): global FORCE - + for i in range(0,len(sfp_map)): target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" status, output =log_os_system("echo 0x50 > "+ target, 1) if status: print output - if FORCE == 0: + if FORCE == 0: return status - + nodelist = mknod - + for i in range(len(nodelist)): target = nodelist[-(i+1)] temp = target.split() @@ -294,129 +298,129 @@ def device_uninstall(): status, output = log_os_system(" ".join(temp), 1) if status: print output - if FORCE == 0: - return status - - return - + if FORCE == 0: + return status + + return + def system_ready(): if driver_check() == False: return False - if not device_exist(): + if not device_exist(): return False return True - + def do_install(): print "Checking system...." if driver_check() == False: - print "No driver, installing...." + print "No driver, installing...." status = driver_install() if status: - if FORCE == 0: + if FORCE == 0: return status else: - print PROJECT_NAME.upper()+" drivers detected...." + print PROJECT_NAME.upper()+" drivers detected...." if not device_exist(): - print "No device, installing...." - status = device_install() + print "No device, installing...." + status = device_install() if status: - if FORCE == 0: - return status + if FORCE == 0: + return status else: - print PROJECT_NAME.upper()+" devices detected...." + print PROJECT_NAME.upper()+" devices detected...." return - + def do_uninstall(): print "Checking system...." if not device_exist(): - print PROJECT_NAME.upper() +" has no device installed...." + print PROJECT_NAME.upper() +" has no device installed...." else: - print "Removing device...." - status = device_uninstall() + print "Removing device...." + status = device_uninstall() if status: - if FORCE == 0: - return status - + if FORCE == 0: + return status + if driver_check()== False : print PROJECT_NAME.upper() +" has no driver installed...." else: print "Removing installed driver...." status = driver_uninstall() if status: - if FORCE == 0: - return status - - return + if FORCE == 0: + return status + + return def devices_info(): global DEVICE_NO global ALL_DEVICE global i2c_bus, hwmon_types, fan_types - for key in DEVICE_NO: - ALL_DEVICE[key]= {} + for key in DEVICE_NO: + ALL_DEVICE[key]= {} for i in range(0,DEVICE_NO[key]): ALL_DEVICE[key][key+str(i+1)] = [] - + for key in i2c_bus: buses = i2c_bus[key] - nodes = i2c_nodes[key] + nodes = i2c_nodes[key] for i in range(0,len(buses)): for j in range(0,len(nodes)): if 'sfp' == key: for k in range(0,DEVICE_NO[key]): node = key+str(k+1) - path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] + path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] my_log(node+": "+ path) - ALL_DEVICE[key][node].append(path) + ALL_DEVICE[key][node].append(path) else: node = key+str(i+1) - path = i2c_prefix+ buses[i]+"/"+ nodes[j] + path = i2c_prefix+ buses[i]+"/"+ nodes[j] my_log(node+": "+ path) - ALL_DEVICE[key][node].append(path) - + ALL_DEVICE[key][node].append(path) + for key in hwmon_types: itypes = hwmon_types[key] - nodes = hwmon_nodes[key] + nodes = hwmon_nodes[key] for i in range(0,len(itypes)): - for j in range(0,len(nodes)): + for j in range(0,len(nodes)): node = key+"_"+itypes[i] - path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] my_log(node+": "+ path) - ALL_DEVICE[key][ key+str(i+1)].append(path) + ALL_DEVICE[key][ key+str(i+1)].append(path) for key in fan_types: itypes = fan_types[key] - nodes = fan_nodes[key] + nodes = fan_nodes[key] for i in range(0,len(itypes)): - for j in range(0,len(nodes)): + for j in range(0,len(nodes)): node = key+"_"+itypes[i] - path = fan_prefix+"/"+ itypes[i]+"_"+ nodes[j] + path = fan_prefix+"/"+ itypes[i]+"_"+ nodes[j] my_log(node+": "+ path) ALL_DEVICE[key][ key+str(i+1)].append(path) - + #show dict all in the order if DEBUG == True: for i in sorted(ALL_DEVICE.keys()): print(i+": ") - for j in sorted(ALL_DEVICE[i].keys()): + for j in sorted(ALL_DEVICE[i].keys()): print(" "+j) - for k in (ALL_DEVICE[i][j]): + for k in (ALL_DEVICE[i][j]): print(" "+" "+k) - return - + return + def show_eeprom(index): if system_ready()==False: - print("System's not ready.") + print("System's not ready.") print("Please install first!") - return - + return + if len(ALL_DEVICE)==0: - devices_info() + devices_info() node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] node = node.replace(node.split("/")[-1], 'sfp_eeprom') # check if got hexdump command in current environment ret, log = log_os_system("which hexdump", 0) - ret, log2 = log_os_system("which busybox hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) if len(log): hex_cmd = 'hexdump' elif len(log2): @@ -425,109 +429,123 @@ def show_eeprom(index): log = 'Failed : no hexdump cmd!!' logging.info(log) print log - return 1 - + return 1 + print node + ":" ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) - if ret==0: - print log + if ret==0: + print log else: - print "**********device no found**********" - return - + print "**********device no found**********" + return + def set_device(args): global DEVICE_NO global ALL_DEVICE if system_ready()==False: - print("System's not ready.") + print("System's not ready.") print("Please install first!") - return - + return + if len(ALL_DEVICE)==0: - devices_info() - + devices_info() + if args[0]=='led': if int(args[1])>4: show_set_help() return #print ALL_DEVICE['led'] - for i in range(0,len(ALL_DEVICE['led'])): - for k in (ALL_DEVICE['led']['led'+str(i+1)]): + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): ret, log = log_os_system("echo "+args[1]+" >"+k, 1) if ret: - return ret + return ret elif args[0]=='fan': if int(args[1])>100: show_set_help() return #print ALL_DEVICE['fan'] - #fan1~6 is all fine, all fan share same setting - node = ALL_DEVICE['fan'] ['fan1'][0] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan'] ['fan1'][0] node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage') - ret, log = log_os_system("cat "+ node, 1) + ret, log = log_os_system("cat "+ node, 1) if ret==0: - print ("Previous fan duty: " + log.strip() +"%") + print ("Previous fan duty: " + log.strip() +"%") ret, log = log_os_system("echo "+args[1]+" >"+node, 1) if ret==0: - print ("Current fan duty: " + args[1] +"%") + print ("Current fan duty: " + args[1] +"%") return ret elif args[0]=='sfp': if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: show_set_help() - return + return if len(args)<2: show_set_help() - return - + return + if int(args[2])>1: show_set_help() return - - #print ALL_DEVICE[args[0]] - for i in range(0,len(ALL_DEVICE[args[0]])): - for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: - if j.find('tx_disable')!= -1: + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) if ret: - return ret - + return ret + return def get_value(input): digit = re.findall('\d+', input) return int(digit[0]) - + + +def get_ledname(ledx): + name_table={'led1':'SYS','led2':'FSTUS','led3':'FAN1','led4':'FAN2','led5':'FAN3','led6':'FAN4','led7':'FAN5','led8':'PSU1','led9':'PSU2'} + if name_table.has_key(ledx): + name = name_table[ledx] + else: + name = ledx + return name + + def device_traversal(): if system_ready()==False: - print("System's not ready.") + print("System's not ready.") print("Please install first!") - return - + return + if len(ALL_DEVICE)==0: devices_info() for i in sorted(ALL_DEVICE.keys()): - print("============================================") + print("============================================") print(i.upper()+": ") print("============================================") - - for j in sorted(ALL_DEVICE[i].keys(), key=get_value): - print " "+j+":", + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + nwnamex = get_ledname(j) + if nwnamex == j: + print " "+j+":", + else: + print " "+nwnamex+":", for k in (ALL_DEVICE[i][j]): ret, log = log_os_system("cat "+k, 0) func = k.split("/")[-1].strip() func = re.sub(j+'_','',func,1) - func = re.sub(i.lower()+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) if ret==0: - print func+"="+log+" ", + print func+"="+log+" ", else: print func+"="+"X"+" ", - print + print print("----------------------------------------------------------------") - - + + print return - + def device_exist(): ret1, log = log_os_system("ls "+i2c_prefix+"*0077", 0) ret2, log = log_os_system("ls "+i2c_prefix+"i2c-3", 0) diff --git a/platform/nephos/sonic-platform-modules-cig/debian/changelog b/platform/nephos/sonic-platform-modules-cig/debian/changelog old mode 100755 new mode 100644 diff --git a/platform/nephos/sonic-platform-modules-cig/debian/compat b/platform/nephos/sonic-platform-modules-cig/debian/compat old mode 100755 new mode 100644 diff --git a/platform/nephos/sonic-platform-modules-cig/debian/control b/platform/nephos/sonic-platform-modules-cig/debian/control old mode 100755 new mode 100644 index 356ce313ab63..bf40791b24e0 --- a/platform/nephos/sonic-platform-modules-cig/debian/control +++ b/platform/nephos/sonic-platform-modules-cig/debian/control @@ -7,5 +7,15 @@ Standards-Version: 3.9.3 Package: sonic-platform-cig-cs6436-56p Architecture: amd64 -Depends: linux-image-4.9.0-9-amd64 +Depends: linux-image-4.9.0-11-2-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + +Package: sonic-platform-cig-cs6436-54p +Architecture: amd64 +Depends: linux-image-4.9.0-11-2-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + +Package: sonic-platform-cig-cs5435-54p +Architecture: amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/sonic-platform-modules-cig/debian/rules b/platform/nephos/sonic-platform-modules-cig/debian/rules index 3192948cc08d..b9ca7642b8bd 100755 --- a/platform/nephos/sonic-platform-modules-cig/debian/rules +++ b/platform/nephos/sonic-platform-modules-cig/debian/rules @@ -19,7 +19,7 @@ PACKAGE_PRE_NAME := sonic-platform-cig KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= cs6436-56p +MODULE_DIRS:= cs6436-56p cs6436-54p cs5435-54p MODULE_DIR := modules UTILS_DIR := utils SERVICE_DIR := service @@ -59,11 +59,12 @@ binary-indep: # Custom package commands (for mod in $(MODULE_DIRS); do \ - dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin; \ dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/etc/sonic; \ cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ - cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \ + cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/*.py debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \ cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \ $(PYTHON) $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ done) diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh index 249f179216a6..7776493bc20a 100755 --- a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh index 23a3fd066bee..9213d115f656 100755 --- a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh @@ -66,7 +66,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/p4/docker-sonic-p4/orchagent.sh b/platform/p4/docker-sonic-p4/orchagent.sh index 7e250dfa20e9..9abfc22c967e 100755 --- a/platform/p4/docker-sonic-p4/orchagent.sh +++ b/platform/p4/docker-sonic-p4/orchagent.sh @@ -1,6 +1,10 @@ #!/usr/bin/env bash -MAC_ADDRESS=`ip link show eth0 | grep ether | awk '{print $2}'` +MAC_ADDRESS=$(sonic-cfggen -d -v 'DEVICE_METADATA.localhost.mac') +if [ "$MAC_ADDRESS" == "None" ] || [ -z "$MAC_ADDRESS" ]; then + MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') + logger "Mac address not found in Device Metadata, Falling back to eth0" +fi # Create a folder for SsWW record files mkdir -p /var/log/swss diff --git a/platform/p4/docker-sonic-p4/start.sh b/platform/p4/docker-sonic-p4/start.sh index c9cf4528bedd..e3251bb2f4e5 100755 --- a/platform/p4/docker-sonic-p4/start.sh +++ b/platform/p4/docker-sonic-p4/start.sh @@ -11,7 +11,7 @@ SYSTEM_MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') sonic-cfggen -a '{"DEVICE_METADATA":{"localhost": {"mac": "'$SYSTEM_MAC_ADDRESS'"}}}' --print-data > /etc/sonic/init_cfg.json if [ -f /etc/sonic/config_db.json ]; then - sonic-cfggen -j /etc/sonic/config_db.json -j /etc/sonic/init_cfg.json --print-data > /tmp/config_db.json + sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db.json --print-data > /tmp/config_db.json mv /tmp/config_db.json /etc/sonic/config_db.json else sonic-cfggen -j /etc/sonic/init_cfg.json --print-data > /etc/sonic/config_db.json diff --git a/platform/template/docker-syncd-base.mk b/platform/template/docker-syncd-base.mk index cefcf15ebd62..d0407beee8a0 100644 --- a/platform/template/docker-syncd-base.mk +++ b/platform/template/docker-syncd-base.mk @@ -29,7 +29,7 @@ endif $(DOCKER_SYNCD_BASE)_CONTAINER_NAME = syncd -$(DOCKER_SYNCD_BASE)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SYNCD_BASE)_RUN_OPT += --privileged -t $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro diff --git a/platform/vs/README.vsvm.md b/platform/vs/README.vsvm.md index d627859578b4..68f7d0244017 100644 --- a/platform/vs/README.vsvm.md +++ b/platform/vs/README.vsvm.md @@ -6,10 +6,10 @@ HOWTO Use Virtual Switch (VM) sudo apt-get install libvirt-clients qemu-kvm libvirt-bin ``` -2. Create SONiC VM +2. Create SONiC VM for single ASIC HWSKU ``` -$ virsh +$ sudo virsh Welcome to virsh, the virtualization interactive terminal. Type: 'help' for help with commands @@ -22,14 +22,54 @@ Domain sonic created from sonic.xml virsh # ``` -2. Connect SONiC VM via console +2. Create SONiC VM for multi-ASIC HWSKU +Update sonic_multiasic.xml with the external interfaces +required for HWSKU. ``` -$ telnet 127.0.0.1 7000 -``` +$ sudo virsh +Welcome to virsh, the virtualization interactive terminal. -3. Connect SONiC VM via SSH +Type: 'help' for help with commands + 'quit' to quit -``` -$ ssh -p 3040 admin@127.0.0.1 -``` +virsh # +virsh # create sonic_multiasic.xml +Domain sonic created from sonic.xml + +virsh # + +Once booted up, create a file "asic.conf" with the content: +NUM_ASIC= +under /usr/share/sonic/device/x86_64-kvm_x86_64-r0/ +Also, create a "topology.sh" file which will simulate the internal +asic connectivity of the hardware under +/usr/share/sonic/device/x86_64-kvm_x86_64-r0/ +The HWSKU directory will have the required files like port_config.ini +for each ASIC. + +Having done this, a new service "topology.service" will be started +during bootup which will invoke topology.sh script. + +3. Access virtual switch: + + 1. Connect SONiC VM via console + ``` + $ telnet 127.0.0.1 7000 + ``` + + OR + + 2. Connect SONiC VM via SSH + + 1. Connect via console (see 3.1 above) + + 2. Request a new DHCP address + ``` + sudo dhclient -v + ``` + + 3. Connect via SSH + ``` + $ ssh -p 3040 admin@127.0.0.1 + ``` diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 7cc6f98921ff..ee3858aca647 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -51,7 +51,9 @@ RUN apt-get install -y net-tools \ apt-utils \ psmisc \ tcpdump \ - python-scapy + python-scapy \ + conntrack \ + iptables RUN pip install setuptools RUN pip install py2_ipaddress diff --git a/platform/vs/docker-sonic-vs/orchagent.sh b/platform/vs/docker-sonic-vs/orchagent.sh index d9bebf117346..2acd709a8e94 100755 --- a/platform/vs/docker-sonic-vs/orchagent.sh +++ b/platform/vs/docker-sonic-vs/orchagent.sh @@ -6,7 +6,11 @@ else export platform=$fake_platform fi -MAC_ADDRESS=`ip link show eth0 | grep ether | awk '{print $2}'` +MAC_ADDRESS=$(sonic-cfggen -d -v 'DEVICE_METADATA.localhost.mac') +if [ "$MAC_ADDRESS" == "None" ] || [ -z "$MAC_ADDRESS" ]; then + MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') + logger "Mac address not found in Device Metadata, Falling back to eth0" +fi # Create a folder for SwSS record files mkdir -p /var/log/swss diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index 614541961c87..f8fcf974b65c 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -13,7 +13,7 @@ SYSTEM_MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') sonic-cfggen -a '{"DEVICE_METADATA":{"localhost": {"mac": "'$SYSTEM_MAC_ADDRESS'"}}}' --print-data > /etc/sonic/init_cfg.json if [ -f /etc/sonic/config_db.json ]; then - sonic-cfggen -j /etc/sonic/config_db.json -j /etc/sonic/init_cfg.json --print-data > /tmp/config_db.json + sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db.json --print-data > /tmp/config_db.json mv /tmp/config_db.json /etc/sonic/config_db.json else # generate and merge buffers configuration into config file @@ -70,6 +70,10 @@ supervisorctl start vxlanmgrd supervisorctl start sflowmgrd +supervisorctl start natmgrd + +supervisorctl start natsyncd + # Start arp_update when VLAN exists VLAN=`sonic-cfggen -d -v 'VLAN.keys() | join(" ") if VLAN'` if [ "$VLAN" != "" ]; then diff --git a/platform/vs/docker-sonic-vs/supervisord.conf b/platform/vs/docker-sonic-vs/supervisord.conf index 143fe49d44a9..3a7acfd20bbe 100644 --- a/platform/vs/docker-sonic-vs/supervisord.conf +++ b/platform/vs/docker-sonic-vs/supervisord.conf @@ -188,3 +188,19 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog + +[program:natmgrd] +command=/usr/bin/natmgrd +priority=23 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:natsyncd] +command=/usr/bin/natsyncd +priority=24 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog diff --git a/platform/vs/sonic_multiasic.xml b/platform/vs/sonic_multiasic.xml new file mode 100644 index 000000000000..b571b5122a52 --- /dev/null +++ b/platform/vs/sonic_multiasic.xml @@ -0,0 +1,110 @@ + + sonic + 8 + 8 + + /machine + + + hvm + + + + + + + + destroy + restart + restart + + /usr/bin/qemu-system-x86_64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + diff --git a/push_docker.sh b/push_docker.sh index 3ba9abfae5bf..3e2da08d0b83 100755 --- a/push_docker.sh +++ b/push_docker.sh @@ -1,42 +1,79 @@ +#! /bin/bash + +sonic_version="" +sonic_platform="" + +while getopts ":v:p:" opt +do + case ${opt} in + v ) # SONiC image version + sonic_version=${OPTARG} + ;; + p ) # Platform info + sonic_platform=${OPTARG} + ;; + \? ) echo "\ +Usage: [-v ] [ -p ] \ + []" + ;; + esac +done + +shift $((OPTIND -1)) + DOCKER_IMAGE_FILE=$1 REGISTRY_SERVER=$2 REGISTRY_PORT=$3 REGISTRY_USERNAME=$4 REGISTRY_PASSWD=$5 DOCKER_IMAGE_TAG=$6 +REGISTRY_SERVER_WITH_PORT=${REGISTRY_SERVER}${REGISTRY_PORT:+:$REGISTRY_PORT} -set -e -docker load < $DOCKER_IMAGE_FILE +push_it() { + # $1 - Given image name + # $2 - Remote image name -## Fetch the Jenkins build number if inside it -[ ${BUILD_NUMBER} ] || { - echo "No BUILD_NUMBER found, setting to 0." - BUILD_NUMBER="0" + docker tag $1 $2 + echo "Pushing $2" + image_sha=$(docker push $2 | sed -n "s/.*: digest: sha256:\([0-9a-f]*\).*/\\1/p") + echo "Remove $2" + docker rmi $2 || true + echo "Image sha256: $image_sha" } -## Prepare tag -docker_image_name=$(basename $DOCKER_IMAGE_FILE | cut -d. -f1) -remote_image_name=$REGISTRY_SERVER:$REGISTRY_PORT/$docker_image_name:$DOCKER_IMAGE_TAG -timestamp="$(date -u +%Y%m%d)" -build_version="${timestamp}.bld-${BUILD_NUMBER}" -build_remote_image_name=$REGISTRY_SERVER:$REGISTRY_PORT/$docker_image_name:$build_version +set -e -## Add registry information as tag, so will push as latest -## Add additional tag with build information -docker tag $docker_image_name $remote_image_name -docker tag $docker_image_name $build_remote_image_name +echo "Loading image ${DOCKER_IMAGE_FILE}" +docker load < ${DOCKER_IMAGE_FILE} ## Login the docker image registry server ## Note: user name and password are passed from command line -docker login -u $REGISTRY_USERNAME -p "$REGISTRY_PASSWD" $REGISTRY_SERVER:$REGISTRY_PORT - -## Push image to registry server -## And get the image digest SHA256 -echo "Pushing $remote_image_name" -image_sha=$(docker push $remote_image_name | sed -n "s/.*: digest: sha256:\([0-9a-f]*\).*/\\1/p") -docker rmi $remote_image_name || true -echo "Image sha256: $image_sha" -echo "Pushing $build_remote_image_name" -docker push $build_remote_image_name -docker rmi $build_remote_image_name || true +docker login -u ${REGISTRY_USERNAME} -p "${REGISTRY_PASSWD}" ${REGISTRY_SERVER_WITH_PORT} + +## Get Docker image name +docker_image_name=$(basename ${DOCKER_IMAGE_FILE} | cut -d. -f1) +remote_image_name=${REGISTRY_SERVER_WITH_PORT}/${docker_image_name} + +[ -z "${DOCKER_IMAGE_TAG}" ] || { + push_it ${docker_image_name} ${remote_image_name}:${DOCKER_IMAGE_TAG} +} + +if [ -n "${sonic_version}" ] && [ -n "${sonic_platform}" ] +then + remote_image_name=${REGISTRY_SERVER_WITH_PORT}/sonic-dockers/${sonic_platform}/${docker_image_name}:${sonic_version} + push_it ${docker_image_name} ${remote_image_name} +else + ## Fetch the Jenkins build number if inside it + [ ${BUILD_NUMBER} ] || { + echo "No BUILD_NUMBER found, setting to 0." + BUILD_NUMBER="0" + } + + timestamp="$(date -u +%Y%m%d)" + build_version="${timestamp}.bld-${BUILD_NUMBER}" + push_it ${docker_image_name} ${remote_image_name}:${build_version} +fi + docker rmi $docker_image_name || true +echo "Job completed" + diff --git a/rules/config b/rules/config index b9dba045fa91..0c2f07cd2648 100644 --- a/rules/config +++ b/rules/config @@ -44,6 +44,9 @@ DEFAULT_PASSWORD = YourPaSsWoRd # If not set (default behavior) the default minigraph built into the image will be used. # ENABLE_DHCP_GRAPH_SERVICE = y +# ENABLE_ZTP - installs Zero Touch Provisioning support. +# ENABLE_ZTP = y + # SHUTDOWN_BGP_ON_START - if set to y all bgp sessions will be in admin down state when # bgp service starts. # SHUTDOWN_BGP_ON_START = y @@ -101,3 +104,24 @@ ENABLE_SFLOW = y # ENABLE_MGMT_FRAMEWORK - build docker-sonic-mgt-framework for CLI and REST server support ENABLE_MGMT_FRAMEWORK = y + +# ENABLE_RESTAPI - build docker-sonic-restapi for configuring the switch using REST APIs +ENABLE_RESTAPI = n + +# ENABLE_NAT - build docker-sonic-nat for nat support +ENABLE_NAT = y + +# INSTALL_KUBERNETES - if set to y kubernetes packages are installed to be able to +# run as worker node in kubernetes cluster. +INSTALL_KUBERNETES = n + +# KUBERNETES_VERSION - Set to the required version. +# K8s_GCR_IO_PAUSE_VERSION - Version of k8s universal pause container image +# K8s_CNI_CALICO_VERSION - Calico used as CNI; Appropriate version for this Kubernetes version +# These are Used *only* when INSTALL_KUBERNETES=y +# NOTE: As a worker node it has to run version compatible to kubernetes master. +# +KUBERNETES_VERSION = 1.18.0 +K8s_GCR_IO_PAUSE_VERSION = 3.2 +K8s_CNI_CALICO_VERSION = 3.12.1 + diff --git a/rules/dhcpmon.mk b/rules/dhcpmon.mk new file mode 100644 index 000000000000..3d80d227c156 --- /dev/null +++ b/rules/dhcpmon.mk @@ -0,0 +1,8 @@ +# SONiC DHCP MONitor package + +SONIC_DHCPMON_VERSION = 1.0.0-0 +SONIC_DHCPMON_PKG_NAME = dhcpmon + +SONIC_DHCPMON = sonic-$(SONIC_DHCPMON_PKG_NAME)_$(SONIC_DHCPMON_VERSION)_$(CONFIGURED_ARCH).deb +$(SONIC_DHCPMON)_SRC_PATH = $(SRC_PATH)/$(SONIC_DHCPMON_PKG_NAME) +SONIC_DPKG_DEBS += $(SONIC_DHCPMON) diff --git a/rules/docker-database.mk b/rules/docker-database.mk index 43dc2ed5d446..7e372048afab 100644 --- a/rules/docker-database.mk +++ b/rules/docker-database.mk @@ -23,7 +23,9 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_DATABASE_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_DATABASE_DBG) $(DOCKER_DATABASE)_CONTAINER_NAME = database -$(DOCKER_DATABASE)_RUN_OPT += --net=host --privileged -t +$(DOCKER_DATABASE)_RUN_OPT += --privileged -t $(DOCKER_DATABASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_DATABASE)_BASE_IMAGE_FILES += redis-cli:/usr/bin/redis-cli +$(DOCKER_DATABASE)_BASE_IMAGE_FILES += monit_database:/etc/monit/conf.d +$(DOCKER_DATABASE)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-dhcp-relay.mk b/rules/docker-dhcp-relay.mk index 5aae24ee33b5..4c044d5e05a0 100644 --- a/rules/docker-dhcp-relay.mk +++ b/rules/docker-dhcp-relay.mk @@ -6,7 +6,7 @@ DOCKER_DHCP_RELAY_DBG = $(DOCKER_DHCP_RELAY_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_DHCP_RELAY)_PATH = $(DOCKERS_PATH)/$(DOCKER_DHCP_RELAY_STEM) -$(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_RELAY) $(REDIS_TOOLS) +$(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_RELAY) $(REDIS_TOOLS) $(SONIC_DHCPMON) $(DOCKER_DHCP_RELAY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) $(DOCKER_DHCP_RELAY)_DBG_DEPENDS += $(ISC_DHCP_RELAY_DBG) @@ -23,6 +23,6 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_DHCP_RELAY_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_DHCP_RELAY_DBG) $(DOCKER_DHCP_RELAY)_CONTAINER_NAME = dhcp_relay -$(DOCKER_DHCP_RELAY)_RUN_OPT += --net=host --privileged -t +$(DOCKER_DHCP_RELAY)_RUN_OPT += --privileged -t $(DOCKER_DHCP_RELAY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_DHCP_RELAY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-fpm-frr.mk b/rules/docker-fpm-frr.mk index 1d158effe7ff..45a755a9289f 100644 --- a/rules/docker-fpm-frr.mk +++ b/rules/docker-fpm-frr.mk @@ -22,11 +22,13 @@ SONIC_DOCKER_DBG_IMAGES += $(DOCKER_FPM_FRR_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_FPM_FRR_DBG) $(DOCKER_FPM_FRR)_CONTAINER_NAME = bgp -$(DOCKER_FPM_FRR)_RUN_OPT += --net=host --privileged -t +$(DOCKER_FPM_FRR)_RUN_OPT += --privileged -t $(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro -$(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic/frr:/etc/frr:rw + +$(DOCKER_FPM_FRR)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += vtysh:/usr/bin/vtysh $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSA:/usr/bin/TSA $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSB:/usr/bin/TSB $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSC:/usr/bin/TSC +$(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += monit_bgp:/etc/monit/conf.d diff --git a/rules/docker-fpm-gobgp.mk b/rules/docker-fpm-gobgp.mk index 12fa37dc1d97..03ec88e85b56 100644 --- a/rules/docker-fpm-gobgp.mk +++ b/rules/docker-fpm-gobgp.mk @@ -7,5 +7,6 @@ $(DOCKER_FPM_GOBGP)_LOAD_DOCKERS += $(DOCKER_FPM_QUAGGA) SONIC_DOCKER_IMAGES += $(DOCKER_FPM_GOBGP) $(DOCKER_FPM_GOBGP)_CONTAINER_NAME = bgp -$(DOCKER_FPM_GOBGP)_RUN_OPT += --net=host --privileged -t +$(DOCKER_FPM_GOBGP)_RUN_OPT += --privileged -t $(DOCKER_FPM_GOBGP)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_FPM_GOBPG)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-fpm-quagga.mk b/rules/docker-fpm-quagga.mk index a9c0511ba173..5a384eedab2c 100644 --- a/rules/docker-fpm-quagga.mk +++ b/rules/docker-fpm-quagga.mk @@ -7,7 +7,9 @@ $(DOCKER_FPM_QUAGGA)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) SONIC_DOCKER_IMAGES += $(DOCKER_FPM_QUAGGA) $(DOCKER_FPM_QUAGGA)_CONTAINER_NAME = bgp -$(DOCKER_FPM_QUAGGA)_RUN_OPT += --net=host --privileged -t +$(DOCKER_FPM_QUAGGA)_RUN_OPT += --privileged -t $(DOCKER_FPM_QUAGGA)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_FPM_QUAGGA)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) + $(DOCKER_FPM_QUAGGA)_BASE_IMAGE_FILES += vtysh:/usr/bin/vtysh diff --git a/rules/docker-lldp-sv2.mk b/rules/docker-lldp-sv2.mk index 91acbe58ad82..a39b307d5063 100644 --- a/rules/docker-lldp-sv2.mk +++ b/rules/docker-lldp-sv2.mk @@ -25,9 +25,10 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_LLDP_SV2_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_LLDP_SV2_DBG) $(DOCKER_LLDP_SV2)_CONTAINER_NAME = lldp -$(DOCKER_LLDP_SV2)_RUN_OPT += --net=host --privileged -t +$(DOCKER_LLDP_SV2)_RUN_OPT += --privileged -t $(DOCKER_LLDP_SV2)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_LLDP_SV2)_BASE_IMAGE_FILES += lldpctl:/usr/bin/lldpctl $(DOCKER_LLDP_SV2)_BASE_IMAGE_FILES += lldpcli:/usr/bin/lldpcli +$(DOCKER_LLDP_SV2)_BASE_IMAGE_FILES += monit_lldp:/etc/monit/conf.d $(DOCKER_LLDP_SV2)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-nat.mk b/rules/docker-nat.mk new file mode 100644 index 000000000000..eb6bd16ccd46 --- /dev/null +++ b/rules/docker-nat.mk @@ -0,0 +1,35 @@ +# docker image for nat + +DOCKER_NAT_STEM = docker-nat +DOCKER_NAT = $(DOCKER_NAT_STEM).gz +DOCKER_NAT_DBG = $(DOCKER_NAT_STEM)-$(DBG_IMAGE_MARK).gz + +$(DOCKER_NAT)_PATH = $(DOCKERS_PATH)/$(DOCKER_NAT_STEM) + +$(DOCKER_NAT)_DEPENDS += $(SWSS) $(REDIS_TOOLS) $(IPTABLESIP4TC) $(IPTABLESIP6TC) $(IPTABLESIPTC) $(IPXTABLES12) $(IPTABLES) +$(DOCKER_NAT)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_NAT)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) +$(DOCKER_NAT)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) + +$(DOCKER_NAT)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) + +ifeq ($(ENABLE_NAT), y) +SONIC_DOCKER_IMAGES += $(DOCKER_NAT) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_NAT) +SONIC_STRETCH_DOCKERS += $(DOCKER_NAT) +endif + +ifeq ($(ENABLE_NAT), y) +SONIC_DOCKER_DBG_IMAGES += $(DOCKER_NAT_DBG) +SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_NAT_DBG) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_NAT_DBG) +endif + +$(DOCKER_NAT)_CONTAINER_NAME = nat +$(DOCKER_NAT)_RUN_OPT += --privileged -t +$(DOCKER_NAT)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_NAT)_RUN_OPT += -v /host/warmboot:/var/warmboot + +$(DOCKER_NAT)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) + +$(DOCKER_NAT)_BASE_IMAGE_FILES += natctl:/usr/bin/natctl diff --git a/rules/docker-orchagent.mk b/rules/docker-orchagent.mk index 20536adc2520..bab1a3a29920 100644 --- a/rules/docker-orchagent.mk +++ b/rules/docker-orchagent.mk @@ -26,7 +26,7 @@ SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_ORCHAGENT_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_ORCHAGENT_DBG) $(DOCKER_ORCHAGENT)_CONTAINER_NAME = swss -$(DOCKER_ORCHAGENT)_RUN_OPT += --net=host --privileged -t +$(DOCKER_ORCHAGENT)_RUN_OPT += --privileged -t $(DOCKER_ORCHAGENT)_RUN_OPT += -v /etc/network/interfaces:/etc/network/interfaces:ro $(DOCKER_ORCHAGENT)_RUN_OPT += -v /etc/network/interfaces.d/:/etc/network/interfaces.d/:ro $(DOCKER_ORCHAGENT)_RUN_OPT += -v /host/machine.conf:/host/machine.conf:ro @@ -34,4 +34,5 @@ $(DOCKER_ORCHAGENT)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_ORCHAGENT)_RUN_OPT += -v /var/log/swss:/var/log/swss:rw $(DOCKER_ORCHAGENT)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel +$(DOCKER_ORCHAGENT)_BASE_IMAGE_FILES += monit_swss:/etc/monit/conf.d $(DOCKER_ORCHAGENT)_FILES += $(ARP_UPDATE_SCRIPT) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-platform-monitor.mk b/rules/docker-platform-monitor.mk index 7a319e4bf120..a37f4d2e9ee7 100644 --- a/rules/docker-platform-monitor.mk +++ b/rules/docker-platform-monitor.mk @@ -33,7 +33,7 @@ SONIC_DOCKER_DBG_IMAGES += $(DOCKER_PLATFORM_MONITOR_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_PLATFORM_MONITOR_DBG) $(DOCKER_PLATFORM_MONITOR)_CONTAINER_NAME = pmon -$(DOCKER_PLATFORM_MONITOR)_RUN_OPT += --net=host --privileged -t +$(DOCKER_PLATFORM_MONITOR)_RUN_OPT += --privileged -t $(DOCKER_PLATFORM_MONITOR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro # Mount Arista python library on Aboot images to be used by plugins diff --git a/rules/docker-restapi.mk b/rules/docker-restapi.mk new file mode 100644 index 000000000000..09bbd03d8fd8 --- /dev/null +++ b/rules/docker-restapi.mk @@ -0,0 +1,28 @@ +# docker image for rest-api + +DOCKER_RESTAPI_STEM = docker-sonic-restapi +DOCKER_RESTAPI = $(DOCKER_RESTAPI_STEM).gz + +$(DOCKER_RESTAPI)_DEPENDS += $(LIBHIREDIS) $(LIBNL3) $(LIBNL_GENL3) \ + $(LIBNL_ROUTE3) $(LIBSWSSCOMMON) $(RESTAPI) + +$(DOCKER_RESTAPI)_PATH = $(DOCKERS_PATH)/$(DOCKER_RESTAPI_STEM) + +$(DOCKER_RESTAPI)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) + +ifeq ($(ENABLE_RESTAPI), y) +SONIC_DOCKER_IMAGES += $(DOCKER_RESTAPI) +SONIC_STRETCH_DOCKERS += $(DOCKER_RESTAPI) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_RESTAPI) +endif + +$(DOCKER_RESTAPI)_CONTAINER_NAME = restapi +$(DOCKER_RESTAPI)_RUN_OPT += --cap-add NET_ADMIN --privileged -t +$(DOCKER_RESTAPI)_RUN_OPT += --network="host" +$(DOCKER_RESTAPI)_RUN_OPT += -v /var/run/redis/redis.sock:/var/run/redis/redis.sock +$(DOCKER_RESTAPI)_RUN_OPT += -v /etc/sonic/certificates:/etc/sonic/certificates:ro +$(DOCKER_RESTAPI)_RUN_OPT += -p=8081:8081/tcp +$(DOCKER_RESTAPI)_RUN_OPT += -p=8090:8090/tcp + +$(DOCKER_RESTAPI)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_RESTAPI)_BASE_IMAGE_FILES += monit_restapi:/etc/monit/conf.d diff --git a/rules/docker-router-advertiser.mk b/rules/docker-router-advertiser.mk index 53e0d7600ec9..ec3fcf6e1fa3 100644 --- a/rules/docker-router-advertiser.mk +++ b/rules/docker-router-advertiser.mk @@ -23,6 +23,6 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_ROUTER_ADVERTISER_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_ROUTER_ADVERTISER_DBG) $(DOCKER_ROUTER_ADVERTISER)_CONTAINER_NAME = radv -$(DOCKER_ROUTER_ADVERTISER)_RUN_OPT += --net=host --privileged -t +$(DOCKER_ROUTER_ADVERTISER)_RUN_OPT += --privileged -t $(DOCKER_ROUTER_ADVERTISER)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_ROUTER_ADVERTISER)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-sflow.mk b/rules/docker-sflow.mk index 94b568481885..67724ad7c548 100644 --- a/rules/docker-sflow.mk +++ b/rules/docker-sflow.mk @@ -26,10 +26,11 @@ SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SFLOW_DBG) endif $(DOCKER_SFLOW)_CONTAINER_NAME = sflow -$(DOCKER_SFLOW)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SFLOW)_RUN_OPT += --privileged -t $(DOCKER_SFLOW)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_SFLOW)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SFLOW)_BASE_IMAGE_FILES += psample:/usr/bin/psample $(DOCKER_SFLOW)_BASE_IMAGE_FILES += sflowtool:/usr/bin/sflowtool +$(DOCKER_SFLOW)_BASE_IMAGE_FILES += monit_sflow:/etc/monit/conf.d $(DOCKER_SFLOW)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-snmp-sv2.mk b/rules/docker-snmp-sv2.mk index bd34f271b861..59f99ac78bc7 100644 --- a/rules/docker-snmp-sv2.mk +++ b/rules/docker-snmp-sv2.mk @@ -26,8 +26,9 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_SNMP_SV2_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SNMP_SV2_DBG) $(DOCKER_SNMP_SV2)_CONTAINER_NAME = snmp -$(DOCKER_SNMP_SV2)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SNMP_SV2)_RUN_OPT += --privileged -t $(DOCKER_SNMP_SV2)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro # mount Arista platform python libraries to support corresponding platforms SNMP power status query $(DOCKER_SNMP_SV2)_RUN_OPT += -v /usr/lib/python3/dist-packages/arista:/usr/lib/python3/dist-packages/arista:ro $(DOCKER_SNMP_SV2)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_SNMP_SV2)_BASE_IMAGE_FILES += monit_snmp:/etc/monit/conf.d diff --git a/rules/docker-sonic-mgmt-framework.mk b/rules/docker-sonic-mgmt-framework.mk index eb99f37875fc..f07b8d023d2d 100644 --- a/rules/docker-sonic-mgmt-framework.mk +++ b/rules/docker-sonic-mgmt-framework.mk @@ -26,7 +26,7 @@ SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_MGMT_FRAMEWORK_DBG) endif $(DOCKER_MGMT_FRAMEWORK)_CONTAINER_NAME = mgmt-framework -$(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += --net=host --privileged -t +$(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += --privileged -t $(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += -v /etc:/host_etc:ro $(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += --mount type=bind,source="/var/platform/",target="/mnt/platform/" diff --git a/rules/docker-teamd.mk b/rules/docker-teamd.mk index 598eff97e8f1..ce7b5bbab1f5 100644 --- a/rules/docker-teamd.mk +++ b/rules/docker-teamd.mk @@ -24,7 +24,7 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_TEAMD_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_TEAMD_DBG) $(DOCKER_TEAMD)_CONTAINER_NAME = teamd -$(DOCKER_TEAMD)_RUN_OPT += --net=host --privileged -t +$(DOCKER_TEAMD)_RUN_OPT += --privileged -t $(DOCKER_TEAMD)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_TEAMD)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/rules/docker-telemetry.mk b/rules/docker-telemetry.mk index 799bef1b1735..04f1871f334b 100644 --- a/rules/docker-telemetry.mk +++ b/rules/docker-telemetry.mk @@ -25,8 +25,9 @@ SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_TELEMETRY_DBG) endif $(DOCKER_TELEMETRY)_CONTAINER_NAME = telemetry -$(DOCKER_TELEMETRY)_RUN_OPT += --net=host --privileged -t +$(DOCKER_TELEMETRY)_RUN_OPT += --privileged -t $(DOCKER_TELEMETRY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_TELEMETRY)_RUN_OPT += --mount type=bind,source="/var/platform/",target="/mnt/platform/" $(DOCKER_TELEMETRY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_TELEMETRY)_BASE_IMAGE_FILES += monit_telemetry:/etc/monit/conf.d diff --git a/rules/frr.mk b/rules/frr.mk index 27391ce0cf73..6dc25b30dfff 100644 --- a/rules/frr.mk +++ b/rules/frr.mk @@ -1,8 +1,10 @@ # FRRouting (frr) package -FRR_VERSION = 7.2 +FRR_VERSION = 7.2.1 FRR_SUBVERSION = 0 -export FRR_VERSION FRR_SUBVERSION +FRR_BRANCH = frr/7.2 +FRR_TAG = frr-7.2.1-s2 +export FRR_VERSION FRR_SUBVERSION FRR_BRANCH FRR = frr_$(FRR_VERSION)-sonic-$(FRR_SUBVERSION)_$(CONFIGURED_ARCH).deb diff --git a/rules/iptables.mk b/rules/iptables.mk new file mode 100644 index 000000000000..4d88c0a224b2 --- /dev/null +++ b/rules/iptables.mk @@ -0,0 +1,27 @@ +# iptables package + +IPTABLES_VERSION = 1.6.0+snapshot20161117 +IPTABLES_VERSION_SUFFIX = 6 +IPTABLES_VERSION_FULL = $(IPTABLES_VERSION)-$(IPTABLES_VERSION_SUFFIX) + +IPTABLES = iptables_$(IPTABLES_VERSION_FULL)_amd64.deb +$(IPTABLES)_SRC_PATH = $(SRC_PATH)/iptables +SONIC_MAKE_DEBS += $(IPTABLES) +SONIC_STRETCH_DEBS += $(IPTABLES) + +IPTABLESIP4TC = libip4tc0_$(IPTABLES_VERSION_FULL)_amd64.deb +$(eval $(call add_derived_package,$(IPTABLES),$(IPTABLESIP4TC))) + +IPTABLESIP6TC = libip6tc0_$(IPTABLES_VERSION_FULL)_amd64.deb +$(eval $(call add_derived_package,$(IPTABLES),$(IPTABLESIP6TC))) + +IPTABLESIPTC = libiptc0_$(IPTABLES_VERSION_FULL)_amd64.deb +$(eval $(call add_derived_package,$(IPTABLES),$(IPTABLESIPTC))) + +IPXTABLES12 = libxtables12_$(IPTABLES_VERSION_FULL)_amd64.deb +$(eval $(call add_derived_package,$(IPTABLES),$(IPXTABLES12))) + +# Export these variables so they can be used in a sub-make +export IPTABLES_VERSION +export IPTABLES_VERSION_FULL +export IPTABLES diff --git a/rules/libnl3.mk b/rules/libnl3.mk index 897b6c34482f..cdd807b2f5c8 100644 --- a/rules/libnl3.mk +++ b/rules/libnl3.mk @@ -1,7 +1,7 @@ # libnl3 -LIBNL3_VERSION_BASE = 3.2.27 -LIBNL3_VERSION = $(LIBNL3_VERSION_BASE)-2 +LIBNL3_VERSION_BASE = 3.5.0 +LIBNL3_VERSION = $(LIBNL3_VERSION_BASE)-1 export LIBNL3_VERSION_BASE export LIBNL3_VERSION diff --git a/rules/linux-kernel.mk b/rules/linux-kernel.mk index 5250f8b97e8f..e6742bdf14cf 100644 --- a/rules/linux-kernel.mk +++ b/rules/linux-kernel.mk @@ -1,9 +1,9 @@ # linux kernel package -KVERSION_SHORT = 4.9.0-9-2 +KVERSION_SHORT = 4.9.0-11-2 KVERSION = $(KVERSION_SHORT)-$(CONFIGURED_ARCH) -KERNEL_VERSION = 4.9.168 -KERNEL_SUBVERSION = 1+deb9u5 +KERNEL_VERSION = 4.9.189 +KERNEL_SUBVERSION = 3+deb9u2 ifeq ($(CONFIGURED_ARCH), armhf) # Override kernel version for ARMHF as it uses arm MP (multi-platform) for short version KVERSION = $(KVERSION_SHORT)-armmp diff --git a/rules/restapi.mk b/rules/restapi.mk new file mode 100644 index 000000000000..e66b4a1d976a --- /dev/null +++ b/rules/restapi.mk @@ -0,0 +1,9 @@ +# sonic-rest-api package + +RESTAPI = sonic-rest-api_1.0.1_amd64.deb +$(RESTAPI)_SRC_PATH = $(SRC_PATH)/sonic-restapi +$(RESTAPI)_DEPENDS += $(LIBHIREDIS_DEV) $(LIBNL3_DEV) $(LIBNL_GENL3_DEV) \ + $(LIBNL_ROUTE3_DEV) $(LIBSWSSCOMMON_DEV) $(LIBSWSSCOMMON) +$(RESTAPI)_RDEPENDS += $(LIBHIREDIS) $(LIBNL3) $(LIBNL_GENL3) \ + $(LIBNL_ROUTE3) $(LIBSWSSCOMMON) +SONIC_DPKG_DEBS += $(RESTAPI) diff --git a/rules/sonic-ztp.mk b/rules/sonic-ztp.mk new file mode 100644 index 000000000000..43615b7dcc8a --- /dev/null +++ b/rules/sonic-ztp.mk @@ -0,0 +1,17 @@ +# SONiC ztp package +# + +ifeq ($(ENABLE_ZTP), y) + +SONIC_ZTP_VERSION = 1.0.0 + +SONIC_ZTP = sonic-ztp_$(SONIC_ZTP_VERSION)_all.deb +$(SONIC_ZTP)_SRC_PATH = $(SRC_PATH)/sonic-ztp +SONIC_DPKG_DEBS += $(SONIC_ZTP) +SONIC_STRETCH_DEBS += $(SONIC_ZTP) + +export SONIC_ZTP_VERSION +export SONIC_ZTP + +endif + diff --git a/slave.mk b/slave.mk index 147b2a95a793..0c4f2c70b392 100644 --- a/slave.mk +++ b/slave.mk @@ -100,6 +100,10 @@ ifneq (,$(filter $(CONFIGURED_ARCH), armhf arm64)) ENABLE_SYSTEM_TELEMETRY = N endif +ifeq ($(SONIC_ENABLE_RESTAPI),y) +ENABLE_RESTAPI = y +endif + ifeq ($(SONIC_ENABLE_SYNCD_RPC),y) ENABLE_SYNCD_RPC = y endif @@ -112,6 +116,11 @@ ifeq ($(SONIC_ENABLE_SFLOW),y) ENABLE_SFLOW = y endif +ifeq ($(SONIC_ENABLE_NAT),y) +ENABLE_NAT = y +endif + + include $(RULES_PATH)/functions include $(RULES_PATH)/*.mk ifneq ($(CONFIGURED_PLATFORM), undefined) @@ -178,6 +187,7 @@ $(info "USERNAME" : "$(USERNAME)") $(info "PASSWORD" : "$(PASSWORD)") $(info "ENABLE_DHCP_GRAPH_SERVICE" : "$(ENABLE_DHCP_GRAPH_SERVICE)") $(info "SHUTDOWN_BGP_ON_START" : "$(SHUTDOWN_BGP_ON_START)") +$(info "INSTALL_KUBERNETES" : "$(INSTALL_KUBERNETES)") $(info "ENABLE_PFCWD_ON_START" : "$(ENABLE_PFCWD_ON_START)") $(info "INSTALL_DEBUG_TOOLS" : "$(INSTALL_DEBUG_TOOLS)") $(info "ROUTING_STACK" : "$(SONIC_ROUTING_STACK)") @@ -190,6 +200,8 @@ $(info "ENABLE_ORGANIZATION_EXTENSIONS" : "$(ENABLE_ORGANIZATION_EXTENSIONS)") $(info "HTTP_PROXY" : "$(HTTP_PROXY)") $(info "HTTPS_PROXY" : "$(HTTPS_PROXY)") $(info "ENABLE_SYSTEM_TELEMETRY" : "$(ENABLE_SYSTEM_TELEMETRY)") +$(info "ENABLE_RESTAPI" : "$(ENABLE_RESTAPI)") +$(info "ENABLE_ZTP" : "$(ENABLE_ZTP)") $(info "SONIC_DEBUGGING_ON" : "$(SONIC_DEBUGGING_ON)") $(info "SONIC_PROFILING_ON" : "$(SONIC_PROFILING_ON)") $(info "KERNEL_PROCURE_METHOD" : "$(KERNEL_PROCURE_METHOD)") @@ -197,6 +209,7 @@ $(info "BUILD_TIMESTAMP" : "$(BUILD_TIMESTAMP)") $(info "BLDENV" : "$(BLDENV)") $(info "VS_PREPARE_MEM" : "$(VS_PREPARE_MEM)") $(info "ENABLE_SFLOW" : "$(ENABLE_SFLOW)") +$(info "ENABLE_NAT" : "$(ENABLE_NAT)") $(info ) ifeq ($(SONIC_USE_DOCKER_BUILDKIT),y) @@ -620,6 +633,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(MONIT)) \ $$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \ $$(addprefix $(FILES_PATH)/,$$($$*_FILES)) \ + $(if $(findstring y,$(ENABLE_ZTP)),$(addprefix $(DEBS_PATH)/,$(SONIC_ZTP))) \ $(addprefix $(STRETCH_FILES_PATH)/, $(if $(filter $(CONFIGURED_ARCH),amd64), $(IXGBE_DRIVER))) \ $(addprefix $(PYTHON_DEBS_PATH)/,$(SONIC_UTILS)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE)) \ @@ -641,7 +655,11 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export enable_organization_extensions="$(ENABLE_ORGANIZATION_EXTENSIONS)" export enable_dhcp_graph_service="$(ENABLE_DHCP_GRAPH_SERVICE)" export enable_system_telemetry="$(ENABLE_SYSTEM_TELEMETRY)" + export enable_restapi="$(ENABLE_RESTAPI)" + export enable_ztp="$(ENABLE_ZTP)" + export enable_nat="$(ENABLE_NAT)" export shutdown_bgp_on_start="$(SHUTDOWN_BGP_ON_START)" + export install_kubernetes="$(INSTALL_KUBERNETES)" export enable_pfcwd_on_start="$(ENABLE_PFCWD_ON_START)" export installer_debs="$(addprefix $(STRETCH_DEBS_PATH)/,$($*_INSTALLS))" export lazy_installer_debs="$(foreach deb, $($*_LAZY_INSTALLS),$(foreach device, $($(deb)_PLATFORM),$(addprefix $(device)@, $(STRETCH_DEBS_PATH)/$(deb))))" @@ -651,6 +669,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export platform_common_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2))" export redis_dump_load_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2))" export install_debug_image="$(INSTALL_DEBUG_TOOLS)" + export multi_instance="false" $(foreach docker, $($*_DOCKERS),\ export docker_image="$(docker)" @@ -658,15 +677,46 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export docker_container_name="$($(docker:-dbg.gz=.gz)_CONTAINER_NAME)" $(eval $(docker:-dbg.gz=.gz)_RUN_OPT += $($(docker:-dbg.gz=.gz)_$($*_IMAGE_TYPE)_RUN_OPT)) export docker_image_run_opt="$($(docker:-dbg.gz=.gz)_RUN_OPT)" - j2 files/build_templates/docker_image_ctl.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh + if [ -f files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then j2 files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service + + # Set the flag GLOBAL for all the global system-wide dockers. + $(if $(shell ls files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 2>/dev/null),\ + $(eval $(docker:-dbg.gz=.gz)_GLOBAL = yes) + ) + fi + # Any service template, inside instance directory, will be used to generate .service and @.service file. + if [ -f files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then + export multi_instance="true" + j2 files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service + $(if $(shell ls files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 2>/dev/null),\ + $(eval $(docker:-dbg.gz=.gz)_TEMPLATE = yes) + ) + export multi_instance="false" + j2 files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service fi + j2 files/build_templates/docker_image_ctl.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh chmod +x $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh ) + # Exported variables are used by sonic_debian_extension.sh export installer_start_scripts="$(foreach docker, $($*_DOCKERS),$(addsuffix .sh, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)))" - export installer_services="$(foreach docker, $($*_DOCKERS),$(addsuffix .service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)))" + + # Marks template services with an "@" according to systemd convention + # If the $($docker)_TEMPLATE) variable is set, the service will be treated as a template + # If the $($docker)_GLOBAL) and $($docker)_TEMPLATE) variables are set the service will be added both as a global and template service. + $(foreach docker, $($*_DOCKERS),\ + $(if $($(docker:-dbg.gz=.gz)_TEMPLATE),\ + $(if $($(docker:-dbg.gz=.gz)_GLOBAL),\ + $(eval SERVICES += "$(addsuffix .service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))")\ + )\ + $(eval SERVICES += "$(addsuffix @.service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))"),\ + $(eval SERVICES += "$(addsuffix .service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))") + ) + ) + export installer_services="$(SERVICES)" + export installer_extra_files="$(foreach docker, $($*_DOCKERS), $(foreach file, $($(docker:-dbg.gz=.gz)_BASE_IMAGE_FILES), $($(docker:-dbg.gz=.gz)_PATH)/base_image_files/$(file)))" j2 -f env files/initramfs-tools/union-mount.j2 onie-image.conf > files/initramfs-tools/union-mount @@ -686,6 +736,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ DEBUG_SRC_ARCHIVE_FILE="$(DBG_SRC_ARCHIVE_FILE)" \ USERNAME="$(USERNAME)" \ PASSWORD="$(PASSWORD)" \ + IMAGE_TYPE=$($*_IMAGE_TYPE) \ ./build_debian.sh $(LOG) USERNAME="$(USERNAME)" \ @@ -697,6 +748,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(foreach docker, $($*_DOCKERS), \ rm -f $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh rm -f $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service + rm -f $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service ) $(if $($*_DOCKERS), diff --git a/sonic-slave-jessie/Dockerfile.j2 b/sonic-slave-jessie/Dockerfile.j2 index 7ed7c4eb7096..dce30193420c 100644 --- a/sonic-slave-jessie/Dockerfile.j2 +++ b/sonic-slave-jessie/Dockerfile.j2 @@ -8,6 +8,8 @@ FROM debian:jessie MAINTAINER johnar@microsoft.com +COPY ["no-check-valid-until", "/etc/apt/apt.conf.d/"] + ## Remove retired jessie-updates repo RUN sed -i '/http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list diff --git a/sonic-slave-jessie/no-check-valid-until b/sonic-slave-jessie/no-check-valid-until new file mode 100644 index 000000000000..c7c25d017f7f --- /dev/null +++ b/sonic-slave-jessie/no-check-valid-until @@ -0,0 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + +Acquire::Check-Valid-Until "false"; diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 17da5ba9cf19..f9e96791464d 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -8,6 +8,8 @@ FROM debian:stretch MAINTAINER gulv@microsoft.com +COPY ["no-check-valid-until", "/etc/apt/apt.conf.d/"] + RUN echo "deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ stretch main contrib non-free" >> /etc/apt/sources.list && \ echo "deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian/ stretch main contrib non-free" >> /etc/apt/sources.list && \ echo "deb [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ stretch/updates main contrib non-free" >> /etc/apt/sources.list && \ @@ -247,9 +249,6 @@ RUN apt-get update && apt-get install -y \ python3-yaml \ # For lockfile procmail \ -# For gtest - libgtest-dev \ - cmake \ # For pam_tacplus build autoconf-archive \ # For iproute2 @@ -292,8 +291,22 @@ RUN apt-get update && apt-get install -y \ libselinux1-dev \ # For kdump-tools liblzo2-dev \ +# For iptables + libnetfilter-conntrack-dev \ + libnftnl-dev \ # For SAI3.7 - libprotobuf-dev + libprotobuf-dev \ +# For DHCP Monitor tool + libexplain-dev \ + libevent-dev + +## Config dpkg +## install the configuration file if it’s currently missing +RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confmiss" +## combined with confold: overwrite configuration files that you have not modified +RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confdef" +## do not modify the current configuration file, the new version is installed with a .dpkg-dist suffix +RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confold" # For smartmontools 6.6-1 RUN apt-get -t stretch-backports install -y debhelper @@ -366,6 +379,23 @@ RUN apt-get install -y vim # Install rsyslog RUN apt-get install -y rsyslog +RUN apt-get install -y libgtest-dev +RUN apt-get install -y libarchive13 librhash0 +RUN apt-get -t stretch-backports install -y libuv1 +# Install cmake/cmake-data 3.13.2-1_bpo9+1 +# latest cmake 3.16.3 break the build libyang 1.0.73 +RUN wget -O cmake-data_3.13.2-1_bpo9+1_all.deb "https://sonicstorage.blob.core.windows.net/packages/cmake/cmake-data_3.13.2-1_bpo9%2B1_all.deb?st=2020-03-27T02%3A22%3A24Z&se=2100-03-26T19%3A00%3A00Z&sp=rl&sv=2018-03-28&sr=b&sig=Xby%2Bm3OZOjPB%2FSlDbHD65yDcPzAgoys%2FA3vK8RB4BzA%3D" +RUN dpkg -i cmake-data_3.13.2-1_bpo9+1_all.deb || apt-get install -f +{% if CONFIGURED_ARCH == "armhf" %} +RUN wget -O cmake_3.13.2-1_bpo9+1_armhf.deb "https://sonicstorage.blob.core.windows.net/packages/cmake/cmake_3.13.2-1_bpo9%2B1_armhf.deb?st=2020-03-27T02%3A29%3A41Z&se=2100-03-26T19%3A00%3A00Z&sp=rl&sv=2018-03-28&sr=b&sig=sWt7kxrFumn020d2GeutGJ716cuQsFwmAmgU%2BJ0kqnk%3D" +RUN dpkg -i cmake_3.13.2-1_bpo9+1_armhf.deb || apt-get install -f +{% elif CONFIGURED_ARCH == "arm64" %} +RUN wget -O cmake_3.13.2-1_bpo9+1_arm64.deb "https://sonicstorage.blob.core.windows.net/packages/cmake/cmake_3.13.2-1_bpo9%2B1_arm64.deb?st=2020-03-27T02%3A28%3A38Z&se=2100-03-26T19%3A00%3A00Z&sp=rl&sv=2018-03-28&sr=b&sig=rrHMkLi29aI8yH6s52ILCY8VcEbNFrzYT2DmC5RwOgs%3D" +RUN dpkg -i cmake_3.13.2-1_bpo9+1_arm64.deb || apt-get install -f +{% else %} +RUN wget -O cmake_3.13.2-1_bpo9+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/cmake/cmake_3.13.2-1_bpo9%2B1_amd64.deb?st=2020-03-27T02%3A27%3A21Z&se=2100-03-26T19%3A00%3A00Z&sp=rl&sv=2018-03-28&sr=b&sig=4MvmmDBQuicFEJYakLm7xCNU19yJ8GIP4ankFSnITKY%3D" +RUN dpkg -i cmake_3.13.2-1_bpo9+1_amd64.deb || apt-get install -f +{% endif %} RUN cd /usr/src/gtest && cmake . && make -C /usr/src/gtest RUN mkdir /var/run/sshd diff --git a/sonic-slave-stretch/no-check-valid-until b/sonic-slave-stretch/no-check-valid-until new file mode 100644 index 000000000000..c7c25d017f7f --- /dev/null +++ b/sonic-slave-stretch/no-check-valid-until @@ -0,0 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + +Acquire::Check-Valid-Until "false"; diff --git a/src/dhcpmon/Makefile b/src/dhcpmon/Makefile new file mode 100644 index 000000000000..61cde376730b --- /dev/null +++ b/src/dhcpmon/Makefile @@ -0,0 +1,44 @@ +RM := rm -rf +DHCPMON_TARGET := dhcpmon +CP := cp +MKDIR := mkdir +CC := gcc +MV := mv + +# All of the sources participating in the build are defined here +-include src/subdir.mk +-include objects.mk + +ifneq ($(MAKECMDGOALS),clean) +ifneq ($(strip $(C_DEPS)),) +-include $(C_DEPS) +endif +endif + +# Add inputs and outputs from these tool invocations to the build variables + +# All Target +all: sonic-dhcpmon + +# Tool invocations +sonic-dhcpmon: $(OBJS) $(USER_OBJS) + @echo 'Building target: $@' + @echo 'Invoking: GCC C Linker' + $(CC) -o "$(DHCPMON_TARGET)" $(OBJS) $(USER_OBJS) $(LIBS) + @echo 'Finished building target: $@' + @echo ' ' + +# Other Targets +install: + $(MKDIR) -p $(DESTDIR)/usr/sbin + $(MV) $(DHCPMON_TARGET) $(DESTDIR)/usr/sbin + +deinstall: + $(RM) $(DESTDIR)/usr/sbin/$(DHCPMON_TARGET) + $(RM) -rf $(DESTDIR)/usr/sbin + +clean: + -$(RM) $(EXECUTABLES)$(OBJS)$(C_DEPS) $(DHCPMON_TARGET) + -@echo ' ' + +.PHONY: all clean dependents diff --git a/src/dhcpmon/debian/changelog b/src/dhcpmon/debian/changelog new file mode 100644 index 000000000000..83b79d6d93bd --- /dev/null +++ b/src/dhcpmon/debian/changelog @@ -0,0 +1,5 @@ +sonic-dhcpmon (1.0.0-0) UNRELEASED; urgency=medium + + * Initial release. + + -- Tamer Ahmed Mon, 09 Dec 2019 12:00:00 -0700 diff --git a/src/dhcpmon/debian/compat b/src/dhcpmon/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/src/dhcpmon/debian/compat @@ -0,0 +1 @@ +9 diff --git a/src/dhcpmon/debian/control b/src/dhcpmon/debian/control new file mode 100644 index 000000000000..2f05fda79963 --- /dev/null +++ b/src/dhcpmon/debian/control @@ -0,0 +1,16 @@ +Source: sonic-dhcpmon +Section: devel +Priority: optional +Maintainer: Tamer Ahmed +Build-Depends: debhelper (>= 8.0.0), + dh-systemd +Standards-Version: 3.9.3 +Homepage: https://github.com/Azure/sonic-buildimage +XS-Go-Import-Path: github.com/Azure/sonic-buildimage + +Package: sonic-dhcpmon +Architecture: any +Built-Using: ${misc:Built-Using} +Depends: libexplain51, + libevent-2.0-5 +Description: SONiC DHCP Monitor diff --git a/src/dhcpmon/debian/rules b/src/dhcpmon/debian/rules new file mode 100755 index 000000000000..3995a26d7fcd --- /dev/null +++ b/src/dhcpmon/debian/rules @@ -0,0 +1,3 @@ +#!/usr/bin/make -f +%: + dh $@ --with systemd diff --git a/src/dhcpmon/objects.mk b/src/dhcpmon/objects.mk new file mode 100644 index 000000000000..c9b774a53921 --- /dev/null +++ b/src/dhcpmon/objects.mk @@ -0,0 +1,4 @@ +USER_OBJS := + +LIBS := -levent -lexplain + diff --git a/src/dhcpmon/src/dhcp_device.c b/src/dhcpmon/src/dhcp_device.c new file mode 100644 index 000000000000..aa0c0f835cbd --- /dev/null +++ b/src/dhcpmon/src/dhcp_device.c @@ -0,0 +1,460 @@ +/** + * @file dhcp_device.c + * + * device (interface) module + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dhcp_device.h" + +/** Start of Ether header of a captured frame */ +#define ETHER_START_OFFSET 0 +/** Start of IP header of a captured frame */ +#define IP_START_OFFSET (ETHER_START_OFFSET + ETHER_HDR_LEN) +/** Start of UDP header of a captured frame */ +#define UDP_START_OFFSET (IP_START_OFFSET + sizeof(struct ip)) +/** Start of DHCP header of a captured frame */ +#define DHCP_START_OFFSET (UDP_START_OFFSET + sizeof(struct udphdr)) +/** Start of DHCP Options segment of a captured frame */ +#define DHCP_OPTIONS_HEADER_SIZE 240 + +#define OP_LDHA (BPF_LD | BPF_H | BPF_ABS) /** bpf ldh Abs */ +#define OP_LDHI (BPF_LD | BPF_H | BPF_IND) /** bpf ldh Ind */ +#define OP_LDB (BPF_LD | BPF_B | BPF_ABS) /** bpf ldb Abs*/ +#define OP_JEQ (BPF_JMP | BPF_JEQ | BPF_K) /** bpf jeq */ +#define OP_JGT (BPF_JMP | BPF_JGT | BPF_K) /** bpf jgt */ +#define OP_RET (BPF_RET | BPF_K) /** bpf ret */ +#define OP_JSET (BPF_JMP | BPF_JSET | BPF_K) /** bpf jset */ +#define OP_LDXB (BPF_LDX | BPF_B | BPF_MSH) /** bpf ldxb */ + +/** Berkley Packet Fitler program for "udp and (port 67 or port 68)". This program is obtained suing the following + * tcpdump command: 'tcpdump -dd "udp and (port 67 or port 68)"' + */ +static struct sock_filter dhcp_bpf_code[] = { + {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x0000000c}, // (000) ldh [12] + {.code = OP_JEQ, .jt = 0, .jf = 7, .k = 0x000086dd}, // (001) jeq #0x86dd jt 2 jf 9 + {.code = OP_LDB, .jt = 0, .jf = 0, .k = 0x00000014}, // (002) ldb [20] + {.code = OP_JEQ, .jt = 0, .jf = 18, .k = 0x00000011}, // (003) jeq #0x11 jt 4 jf 22 + {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x00000036}, // (004) ldh [54] + {.code = OP_JEQ, .jt = 15, .jf = 0, .k = 0x00000043}, // (005) jeq #0x43 jt 21 jf 6 + {.code = OP_JEQ, .jt = 14, .jf = 0, .k = 0x00000044}, // (006) jeq #0x44 jt 21 jf 7 + {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x00000038}, // (007) ldh [56] + {.code = OP_JEQ, .jt = 12, .jf = 11, .k = 0x00000043}, // (008) jeq #0x43 jt 21 jf 20 + {.code = OP_JEQ, .jt = 0, .jf = 12, .k = 0x00000800}, // (009) jeq #0x800 jt 10 jf 22 + {.code = OP_LDB, .jt = 0, .jf = 0, .k = 0x00000017}, // (010) ldb [23] + {.code = OP_JEQ, .jt = 0, .jf = 10, .k = 0x00000011}, // (011) jeq #0x11 jt 12 jf 22 + {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x00000014}, // (012) ldh [20] + {.code = OP_JSET, .jt = 8, .jf = 0, .k = 0x00001fff}, // (013) jset #0x1fff jt 22 jf 14 + {.code = OP_LDXB, .jt = 0, .jf = 0, .k = 0x0000000e}, // (014) ldxb 4*([14]&0xf) + {.code = OP_LDHI, .jt = 0, .jf = 0, .k = 0x0000000e}, // (015) ldh [x + 14] + {.code = OP_JEQ, .jt = 4, .jf = 0, .k = 0x00000043}, // (016) jeq #0x43 jt 21 jf 17 + {.code = OP_JEQ, .jt = 3, .jf = 0, .k = 0x00000044}, // (017) jeq #0x44 jt 21 jf 18 + {.code = OP_LDHI, .jt = 0, .jf = 0, .k = 0x00000010}, // (018) ldh [x + 16] + {.code = OP_JEQ, .jt = 1, .jf = 0, .k = 0x00000043}, // (019) jeq #0x43 jt 21 jf 20 + {.code = OP_JEQ, .jt = 0, .jf = 1, .k = 0x00000044}, // (020) jeq #0x44 jt 21 jf 22 + {.code = OP_RET, .jt = 0, .jf = 0, .k = 0x00040000}, // (021) ret #262144 + {.code = OP_RET, .jt = 0, .jf = 0, .k = 0x00000000}, // (022) ret #0 +}; + +/** Filter program socket struct */ +static struct sock_fprog dhcp_sock_bfp = { + .len = sizeof(dhcp_bpf_code) / sizeof(*dhcp_bpf_code), .filter = dhcp_bpf_code +}; + +/** global aggregate counter for DHCP interfaces */ +static dhcp_device_counters_t glob_counters[DHCP_DIR_COUNT] = { + [DHCP_RX] = {.discover = 0, .offer = 0, .request = 0, .ack = 0}, + [DHCP_TX] = {.discover = 0, .offer = 0, .request = 0, .ack = 0}, +}; + +/** global aggregate counter snapshot for DHCP interfaces */ +static dhcp_device_counters_t glob_counters_snapshot[DHCP_DIR_COUNT] = { + [DHCP_RX] = {.discover = 0, .offer = 0, .request = 0, .ack = 0}, + [DHCP_TX] = {.discover = 0, .offer = 0, .request = 0, .ack = 0}, +}; + +/** + * @code handle_dhcp_option_53(context, dhcp_option, dir); + * + * @brief handle the logic related to DHCP option 53 + * + * @param context Device (interface) context + * @param dhcp_option pointer to DHCP option buffer space + * @param dir packet direction + * + * @return none + */ +static void handle_dhcp_option_53(dhcp_device_context_t *context, const u_char *dhcp_option, dhcp_packet_direction_t dir) +{ + switch (dhcp_option[2]) + { + case 1: + context->counters[dir].discover++; + if ((context->is_uplink && dir == DHCP_TX) || (!context->is_uplink && dir == DHCP_RX)) { + glob_counters[dir].discover++; + } + break; + case 2: + context->counters[dir].offer++; + if ((!context->is_uplink && dir == DHCP_TX) || (context->is_uplink && dir == DHCP_RX)) { + glob_counters[dir].offer++; + } + break; + case 3: + context->counters[dir].request++; + if ((context->is_uplink && dir == DHCP_TX) || (!context->is_uplink && dir == DHCP_RX)) { + glob_counters[dir].request++; + } + break; + case 5: + context->counters[dir].ack++; + if ((!context->is_uplink && dir == DHCP_TX) || (context->is_uplink && dir == DHCP_RX)) { + glob_counters[dir].ack++; + } + break; + case 4: // type: Decline + case 6 ... 8: + // type: NAK, Release, Inform + break; + default: + syslog(LOG_WARNING, "handle_dhcp_option_53(%s): Unknown DHCP option 53 type %d", context->intf, dhcp_option[2]); + break; + } +} + +/** + * @code read_callback(fd, event, arg); + * + * @brief callback for libevent which is called every time out in order to read queued packet capture + * + * @param fd socket to read from + * @param event libevent triggered event + * @param arg user provided argument for callback (interface context) + * @param packet pointer to packet data + * + * @return none + */ +static void read_callback(int fd, short event, void *arg) +{ + dhcp_device_context_t *context = (dhcp_device_context_t*) arg; + ssize_t buffer_sz; + + while ((event == EV_READ) && + ((buffer_sz = recv(fd, context->buffer, context->snaplen, MSG_DONTWAIT)) > 0)) { + struct ether_header *ethhdr = (struct ether_header*) context->buffer; + struct udphdr *udp = (struct udphdr*) (context->buffer + UDP_START_OFFSET); + int dhcp_option_offset = DHCP_START_OFFSET + DHCP_OPTIONS_HEADER_SIZE; + + if ((buffer_sz > UDP_START_OFFSET + sizeof(struct udphdr) + DHCP_OPTIONS_HEADER_SIZE) && + (ntohs(udp->len) > DHCP_OPTIONS_HEADER_SIZE)) { + int dhcp_sz = ntohs(udp->len) < buffer_sz - UDP_START_OFFSET - sizeof(struct udphdr) ? + ntohs(udp->len) : buffer_sz - UDP_START_OFFSET - sizeof(struct udphdr); + int dhcp_option_sz = dhcp_sz - DHCP_OPTIONS_HEADER_SIZE; + const u_char *dhcp_option = context->buffer + dhcp_option_offset; + dhcp_packet_direction_t dir = (ethhdr->ether_shost[0] == context->mac[0] && + ethhdr->ether_shost[1] == context->mac[1] && + ethhdr->ether_shost[2] == context->mac[2] && + ethhdr->ether_shost[3] == context->mac[3] && + ethhdr->ether_shost[4] == context->mac[4] && + ethhdr->ether_shost[5] == context->mac[5]) ? + DHCP_TX : DHCP_RX; + int offset = 0; + int stop_dhcp_processing = 0; + while ((offset < (dhcp_option_sz + 1)) && dhcp_option[offset] != 255) { + switch (dhcp_option[offset]) + { + case 53: + if (offset < (dhcp_option_sz + 2)) { + handle_dhcp_option_53(context, &dhcp_option[offset], dir); + } + stop_dhcp_processing = 1; // break while loop since we are only interested in Option 53 + break; + default: + break; + } + + if (stop_dhcp_processing == 1) { + break; + } + + if (dhcp_option[offset] == 0) { // DHCP Option Padding + offset++; + } else { + offset += dhcp_option[offset + 1] + 2; + } + } + } else { + syslog(LOG_WARNING, "read_callback(%s): read length (%ld) is too small to capture DHCP options", + context->intf, buffer_sz); + } + } +} + +/** + * @code dhcp_device_validate(counters, counters_snapshot); + * + * @brief validate current interface counters by comparing aggregate counter with snapshot counters. + * + * @param counters recent interface counter + * @param counters_snapshot snapshot counters + * + * @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE + */ +static dhcp_mon_status_t dhcp_device_validate(dhcp_device_counters_t *counters, + dhcp_device_counters_t *counters_snapshot) +{ + dhcp_mon_status_t rv = DHCP_MON_STATUS_HEALTHY; + + if ((counters[DHCP_RX].discover == counters_snapshot[DHCP_RX].discover) && + (counters[DHCP_RX].offer == counters_snapshot[DHCP_RX].offer ) && + (counters[DHCP_RX].request == counters_snapshot[DHCP_RX].request ) && + (counters[DHCP_RX].ack == counters_snapshot[DHCP_RX].ack ) ) { + rv = DHCP_MON_STATUS_INDETERMINATE; + } else { + // if we have rx DORA then we should have corresponding tx DORA (DORA being relayed) + if (((counters[DHCP_RX].discover > counters_snapshot[DHCP_RX].discover) && + (counters[DHCP_TX].discover <= counters_snapshot[DHCP_TX].discover) ) || + ((counters[DHCP_RX].offer > counters_snapshot[DHCP_RX].offer ) && + (counters[DHCP_TX].offer <= counters_snapshot[DHCP_TX].offer ) ) || + ((counters[DHCP_RX].request > counters_snapshot[DHCP_RX].request ) && + (counters[DHCP_TX].request <= counters_snapshot[DHCP_TX].request ) ) || + ((counters[DHCP_RX].ack > counters_snapshot[DHCP_RX].ack ) && + (counters[DHCP_TX].ack <= counters_snapshot[DHCP_TX].ack ) ) ) { + rv = DHCP_MON_STATUS_UNHEALTHY; + } + } + + return rv; +} + +/** + * @code dhcp_print_counters(counters); + * + * @brief prints DHCP counters to sylsog. + * + * @param counters interface counter + */ +static void dhcp_print_counters(dhcp_device_counters_t *counters) +{ + syslog(LOG_NOTICE, "DHCP Discover rx: %lu, tx:%lu, Offer rx: %lu, tx:%lu, Request rx: %lu, tx:%lu, ACK rx: %lu, tx:%lu\n", + counters[DHCP_RX].discover, counters[DHCP_TX].discover, + counters[DHCP_RX].offer, counters[DHCP_TX].offer, + counters[DHCP_RX].request, counters[DHCP_TX].request, + counters[DHCP_RX].ack, counters[DHCP_TX].ack); +} + +/** + * @code init_socket(context, intf, snaplen, base); + * + * @brief initializes socket, bind it to interface and bpf prgram, and + * associate with libevent base + * + * @param context pointer to device (interface) context + * @param intf interface name + * @param snaplen length of packet capture + * @param base libevent base + * + * @return 0 on success, otherwise for failure + */ +static int init_socket(dhcp_device_context_t *context, + const char *intf, + size_t snaplen, + struct event_base *base) +{ + int rv = -1; + + do { + if (snaplen < UDP_START_OFFSET + sizeof(struct udphdr) + DHCP_OPTIONS_HEADER_SIZE) { + syslog(LOG_ALERT, "init_socket(%s): snap length is too low to capture DHCP options", intf); + break; + } + + context->sock = socket(AF_PACKET, SOCK_RAW | SOCK_NONBLOCK, htons(ETH_P_ALL)); + if (context->sock < 0) { + syslog(LOG_ALERT, "socket: failed to open socket with '%s'\n", strerror(errno)); + break; + } + + struct sockaddr_ll addr; + memset(&addr, 0, sizeof(addr)); + addr.sll_ifindex = if_nametoindex(intf); + addr.sll_family = AF_PACKET; + addr.sll_protocol = htons(ETH_P_ALL); + if (bind(context->sock, (struct sockaddr *) &addr, sizeof(addr))) { + syslog(LOG_ALERT, "bind: failed to bind to interface '%s' with '%s'\n", intf, strerror(errno)); + break; + } + + if (setsockopt(context->sock, SOL_SOCKET, SO_ATTACH_FILTER, &dhcp_sock_bfp, sizeof(dhcp_sock_bfp)) != 0) { + syslog(LOG_ALERT, "setsockopt: failed to attach filter with '%s'\n", strerror(errno)); + break; + } + + context->buffer = (uint8_t *) malloc(snaplen); + if (context->buffer == NULL) { + syslog(LOG_ALERT, "malloc: failed to allocate memory for socket buffer '%s'\n", strerror(errno)); + break; + } + context->snaplen = snaplen; + + struct event *ev = event_new(base, context->sock, EV_READ | EV_PERSIST, read_callback, context); + if (ev == NULL) { + syslog(LOG_ALERT, "event_new: failed to allocate memory for libevent event '%s'\n", strerror(errno)); + break; + } + event_add(ev, NULL); + + strncpy(context->intf, intf, sizeof(context->intf) - 1); + context->intf[sizeof(context->intf) - 1] = '\0'; + + rv = 0; + } while (0); + + return rv; +} + +/** + * @code initialize_intf_mac_and_ip_addr(context); + * + * @brief initializes device (interface) mac/ip addresses + * + * @param context pointer to device (interface) context + * + * @return 0 on success, otherwise for failure + */ +static int initialize_intf_mac_and_ip_addr(dhcp_device_context_t *context) +{ + int rv = -1; + + do { + int fd; + struct ifreq ifr; + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + syslog(LOG_ALERT, "socket: %s", strerror(errno)); + break; + } + + ifr.ifr_addr.sa_family = AF_INET; + strncpy(ifr.ifr_name, context->intf, sizeof(ifr.ifr_name) - 1); + ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; + + // Get network address + if (ioctl(fd, SIOCGIFADDR, &ifr) == -1) { + syslog(LOG_ALERT, "ioctl: %s", explain_ioctl(fd, SIOCGIFADDR, &ifr)); + break; + } + context->ip = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr; + + // Get mac address + if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) { + syslog(LOG_ALERT, "ioctl: %s", explain_ioctl(fd, SIOCGIFHWADDR, &ifr)); + break; + } + memcpy(context->mac, ifr.ifr_hwaddr.sa_data, sizeof(context->mac)); + + close(fd); + + rv = 0; + } while (0); + + return rv; +} + +/** + * @code dhcp_device_init(context, intf, snaplen, is_uplink, base); + * + * @brief initializes device (interface) that handles packet capture per interface. + */ +int dhcp_device_init(dhcp_device_context_t **context, + const char *intf, + int snaplen, + uint8_t is_uplink, + struct event_base *base) +{ + int rv = -1; + dhcp_device_context_t *dev_context = NULL; + + if ((context != NULL) && (strlen(intf) < sizeof(dev_context->intf))) { + + dev_context = (dhcp_device_context_t *) malloc(sizeof(dhcp_device_context_t)); + if (dev_context != NULL) { + if ((init_socket(dev_context, intf, snaplen, base) == 0) && + (initialize_intf_mac_and_ip_addr(dev_context) == 0 ) ) { + + dev_context->is_uplink = is_uplink; + + memset(&dev_context->counters, 0, sizeof(dev_context->counters)); + memset(&dev_context->counters_snapshot, 0, sizeof(dev_context->counters_snapshot)); + + *context = dev_context; + rv = 0; + } + } + else { + syslog(LOG_ALERT, "malloc: failed to allocated device context memory for '%s'", dev_context->intf); + } + } + + return rv; +} + +/** + * @code dhcp_device_shutdown(context); + * + * @brief shuts down device (interface). Also, stops packet capture on interface and cleans up any allocated memory + */ +void dhcp_device_shutdown(dhcp_device_context_t *context) +{ + free(context); +} + +/** + * @code dhcp_device_get_status(context); + * + * @brief collects DHCP relay status info for a given interface. If context is null, it will report aggregate + * status + */ +dhcp_mon_status_t dhcp_device_get_status(dhcp_device_context_t *context) +{ + dhcp_mon_status_t rv = 0; + + if (context != NULL) { + rv = dhcp_device_validate(context->counters, context->counters_snapshot); + memcpy(context->counters_snapshot, context->counters, sizeof(context->counters_snapshot)); + } else { + rv = dhcp_device_validate(glob_counters, glob_counters_snapshot); + memcpy(glob_counters_snapshot, glob_counters, sizeof(glob_counters_snapshot)); + } + + return rv; +} + +/** + * @code dhcp_device_print_status(); + * + * @brief prints status counters to syslog. If context is null, it will print aggregate status + */ +void dhcp_device_print_status(dhcp_device_context_t *context) +{ + if (context != NULL) { + dhcp_print_counters(context->counters); + } else { + dhcp_print_counters(glob_counters); + } +} diff --git a/src/dhcpmon/src/dhcp_device.h b/src/dhcpmon/src/dhcp_device.h new file mode 100644 index 000000000000..04113eeabdc0 --- /dev/null +++ b/src/dhcpmon/src/dhcp_device.h @@ -0,0 +1,113 @@ +/** + * @file dhcp_device.h + * + * device (interface) module + */ + +#ifndef DHCP_DEVICE_H_ +#define DHCP_DEVICE_H_ + +#include +#include +#include +#include + +#include +#include +#include + + +/** packet direction */ +typedef enum +{ + DHCP_RX, /** RX DHCP packet */ + DHCP_TX, /** TX DHCP packet */ + + DHCP_DIR_COUNT +} dhcp_packet_direction_t; + +/** dhcp health status */ +typedef enum +{ + DHCP_MON_STATUS_HEALTHY, /** DHCP relay is healthy */ + DHCP_MON_STATUS_UNHEALTHY, /** DHCP relay is unhealthy and is missing out on some packets */ + DHCP_MON_STATUS_INDETERMINATE, /** DHCP relay health could not be determined */ +} dhcp_mon_status_t; + +/** DHCP device (interface) health counters */ +typedef struct +{ + uint64_t discover; /** DHCP discover packets */ + uint64_t offer; /** DHCP offer packets */ + uint64_t request; /** DHCP request packets */ + uint64_t ack; /** DHCP ack packets */ +} dhcp_device_counters_t; + +/** DHCP device (interface) context */ +typedef struct +{ + int sock; /** Raw socket associated with this device/interface */ + in_addr_t ip; /** network address of this device (interface) */ + uint8_t mac[ETHER_ADDR_LEN]; /** hardware address of this device (interface) */ + uint8_t is_uplink; /** north interface? */ + char intf[IF_NAMESIZE]; /** device (interface) name */ + uint8_t *buffer; /** buffer used to read socket data */ + size_t snaplen; /** snap length or buffer size */ + dhcp_device_counters_t counters[DHCP_DIR_COUNT]; + /** current coutners of DORA packets */ + dhcp_device_counters_t counters_snapshot[DHCP_DIR_COUNT]; + /** counter snapshot */ +} dhcp_device_context_t; + +/** + * @code dhcp_device_init(context, intf, snaplen, timeout_ms, is_uplink, base); + * + * @brief initializes device (interface) that handles packet capture per interface. + * + * @param context(inout) pointer to device (interface) context + * @param intf interface name + * @param snaplen length of packet capture + * @param is_uplink uplink interface + * @param base pointer to libevent base + * + * @return 0 on success, otherwise for failure + */ +int dhcp_device_init(dhcp_device_context_t **context, + const char *intf, + int snaplen, + uint8_t is_uplink, + struct event_base *base); + +/** + * @code dhcp_device_shutdown(context); + * + * @brief shuts down device (interface). Also, stops packet capture on interface and cleans up any allocated memory + * + * @param context Device (interface) context + * + * @return nonedhcp_device_shutdown + */ +void dhcp_device_shutdown(dhcp_device_context_t *context); + +/** + * @code dhcp_device_get_status(context); + * + * @brief collects DHCP relay status info for a given interface. If context is null, it will report aggregate + * status + * + * @param context Device (interface) context + * + * @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE + */ +dhcp_mon_status_t dhcp_device_get_status(dhcp_device_context_t *context); + +/** + * @code dhcp_device_print_status(); + * + * @brief prints status counters to syslog. If context is null, it will print aggregate status + * + * @return none + */ +void dhcp_device_print_status(dhcp_device_context_t *context); + +#endif /* DHCP_DEVICE_H_ */ diff --git a/src/dhcpmon/src/dhcp_devman.c b/src/dhcpmon/src/dhcp_devman.c new file mode 100644 index 000000000000..c19cbde591b8 --- /dev/null +++ b/src/dhcpmon/src/dhcp_devman.c @@ -0,0 +1,149 @@ +/** + * @file dhcp_devman.c + * + * Device (interface) manager + */ +#include +#include +#include +#include +#include +#include + +#include "dhcp_devman.h" + +/** struct for interface information */ +struct intf +{ + const char *name; /** interface name */ + uint8_t is_uplink; /** is uplink (north) interface */ + dhcp_device_context_t *dev_context; /** device (interface_ context */ + LIST_ENTRY(intf) entry; /** list link/pointers entries */ +}; + +/** intfs list of interfaces */ +static LIST_HEAD(intf_list, intf) intfs; +/** dhcp_num_south_intf number of south interfaces */ +static uint32_t dhcp_num_south_intf = 0; +/** dhcp_num_north_intf number of north interfaces */ +static uint32_t dhcp_num_north_intf = 0; + +/** + * @code dhcp_devman_init(); + * + * initializes device (interface) manager that keeps track of interfaces and assert that there is one south + * interface and as many north interfaces + */ +void dhcp_devman_init() +{ + LIST_INIT(&intfs); +} + +/** + * @code dhcp_devman_shutdown(); + * + * shuts down device (interface) manager. Also, stops packet capture on interface and cleans up any allocated + * memory + */ +void dhcp_devman_shutdown() +{ + struct intf *int_ptr, *prev_intf = NULL; + + LIST_FOREACH(int_ptr, &intfs, entry) { + dhcp_device_shutdown(int_ptr->dev_context); + if (prev_intf) { + LIST_REMOVE(prev_intf, entry); + free(prev_intf); + prev_intf = int_ptr; + } + } + + if (prev_intf) { + LIST_REMOVE(prev_intf, entry); + free(prev_intf); + } +} + +/** + * @code dhcp_devman_add_intf(name, uplink); + * + * @brief adds interface to the device manager. + */ +int dhcp_devman_add_intf(const char *name, uint8_t is_uplink) +{ + int rv = -1; + struct intf *dev = malloc(sizeof(struct intf)); + + if (dev != NULL) { + dev->name = name; + dev->is_uplink = is_uplink; + if (is_uplink) { + dhcp_num_north_intf++; + } else { + dhcp_num_south_intf++; + assert(dhcp_num_south_intf <= 1); + } + + LIST_INSERT_HEAD(&intfs, dev, entry); + + rv = 0; + } + else { + syslog(LOG_ALERT, "malloc: failed to allocate memory for intf '%s'\n", name); + } + + return rv; +} + +/** + * @code dhcp_devman_start_capture(snaplen, base); + * + * @brief start packet capture on the devman interface list + */ +int dhcp_devman_start_capture(int snaplen, struct event_base *base) +{ + int rv = -1; + struct intf *int_ptr; + + if ((dhcp_num_south_intf == 1) && (dhcp_num_north_intf >= 1)) { + LIST_FOREACH(int_ptr, &intfs, entry) { + rv = dhcp_device_init(&int_ptr->dev_context, int_ptr->name, snaplen, int_ptr->is_uplink, base); + if (rv == 0) { + syslog(LOG_INFO, + "Capturing DHCP packets on interface %s, ip: 0x%08x, mac [%02x:%02x:%02x:%02x:%02x:%02x] \n", + int_ptr->name, int_ptr->dev_context->ip, int_ptr->dev_context->mac[0], + int_ptr->dev_context->mac[1], int_ptr->dev_context->mac[2], int_ptr->dev_context->mac[3], + int_ptr->dev_context->mac[4], int_ptr->dev_context->mac[5]); + } + else { + break; + } + } + } + else { + syslog(LOG_ERR, "Invalid number of interfaces, downlink/south %d, uplink/north %d\n", + dhcp_num_south_intf, dhcp_num_north_intf); + } + + return rv; +} + +/** + * @code dhcp_devman_get_status(); + * + * @brief collects DHCP relay status info. + */ +dhcp_mon_status_t dhcp_devman_get_status() +{ + return dhcp_device_get_status(NULL); +} + +/** + * @code dhcp_devman_print_status(); + * + * @brief prints status counters to syslog + */ +void dhcp_devman_print_status() +{ + dhcp_device_print_status(NULL); +} diff --git a/src/dhcpmon/src/dhcp_devman.h b/src/dhcpmon/src/dhcp_devman.h new file mode 100644 index 000000000000..a0753b4b93a1 --- /dev/null +++ b/src/dhcpmon/src/dhcp_devman.h @@ -0,0 +1,76 @@ +/** + * @file dhcp_devman.h + * + * Device (interface) manager + */ + +#ifndef DHCP_DEVMAN_H_ +#define DHCP_DEVMAN_H_ + +#include + +#include "dhcp_device.h" + +/** + * @code dhcp_devman_init(); + * + * @brief initializes device (interface) manager that keeps track of interfaces and assert that there is one south + * interface and as many north interfaces + * + * @return none + */ +void dhcp_devman_init(); + +/** + * @code dhcp_devman_shutdown(); + * + * @brief shuts down device (interface) manager. Also, stops packet capture on interface and cleans up any allocated + * memory + * + * @return none + */ +void dhcp_devman_shutdown(); + +/** + * @code dhcp_devman_add_intf(name, uplink); + * + * @brief adds interface to the device manager. + * + * @param name interface name + * @param is_uplink true for uplink (north) interface + * + * @return 0 on success, nonzero otherwise + */ +int dhcp_devman_add_intf(const char *name, uint8_t is_uplink); + +/** + * @code dhcp_devman_start_capture(snaplen, timeout_ms); + * + * @brief start packet capture on the devman interface list + * + * @param snaplen packet capture snap length + * @param base libevent base + * + * @return 0 on success, nonzero otherwise + */ +int dhcp_devman_start_capture(int snaplen, struct event_base *base); + +/** + * @code dhcp_devman_get_status(); + * + * @brief collects DHCP relay status info. + * + * @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE + */ +dhcp_mon_status_t dhcp_devman_get_status(); + +/** + * @code dhcp_devman_print_status(); + * + * @brief prints status counters to syslog + * + * @return none + */ +void dhcp_devman_print_status(); + +#endif /* DHCP_DEVMAN_H_ */ diff --git a/src/dhcpmon/src/dhcp_mon.c b/src/dhcpmon/src/dhcp_mon.c new file mode 100644 index 000000000000..dc0a7d94f149 --- /dev/null +++ b/src/dhcpmon/src/dhcp_mon.c @@ -0,0 +1,199 @@ +/** + * @file dhcp_mon.c + * + * @brief dhcp relay monitor module + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dhcp_mon.h" +#include "dhcp_devman.h" + +/** window_interval_sec monitoring window for dhcp relay health checks */ +static int window_interval_sec = 12; +/** dhcp_unhealthy_max_count max count of consecutive unhealthy statuses before reporting to syslog */ +static int dhcp_unhealthy_max_count = 10; +/** libevent base struct */ +static struct event_base *base; +/** libevent timeout event struct */ +static struct event *ev_timeout = NULL; +/** libevent SIGINT signal event struct */ +static struct event *ev_sigint; +/** libevent SIGTERM signal event struct */ +static struct event *ev_sigterm; + +/** + * @code signal_callback(fd, event, arg); + * + * @brief signal handler for dhcpmon. It will initiate shutdown when signal is caught + * + * @param fd libevent socket + * @param event event triggered + * @param arg pointer user provided context (libevent base) + * + * @return none + */ +static void signal_callback(evutil_socket_t fd, short event, void *arg) +{ + syslog(LOG_ALERT, "Received signal %d\n", event); + dhcp_devman_print_status(); + dhcp_mon_stop(); +} + +/** + * @code timeout_callback(fd, event, arg); + * + * @brief periodic timer call back + * + * @param fd libevent socket + * @param event event triggered + * @param arg pointer user provided context (libevent base) + * + * @return none + */ +static void timeout_callback(evutil_socket_t fd, short event, void *arg) +{ + static int count = 0; + dhcp_mon_status_t dhcp_mon_status = dhcp_devman_get_status(); + + switch (dhcp_mon_status) + { + case DHCP_MON_STATUS_UNHEALTHY: + if (++count > dhcp_unhealthy_max_count) { + syslog(LOG_ALERT, "DHCP Relay is not healthy after %d health checks\n", count); + } + break; + case DHCP_MON_STATUS_HEALTHY: + if (count > 0) { + count = 0; + } + break; + case DHCP_MON_STATUS_INDETERMINATE: + break; + default: + syslog(LOG_ERR, "DHCP Relay returned unknown status %d\n", dhcp_mon_status); + break; + } +} + +/** + * @code dhcp_mon_init(window_sec, max_count); + * + * initializes event base and periodic timer event that continuously collects dhcp relay health status every window_sec + * seconds. It also writes to syslog when dhcp relay has been unhealthy for consecutive max_count checks. + * + */ +int dhcp_mon_init(int window_sec, int max_count) +{ + int rv = -1; + + do { + window_interval_sec = window_sec; + dhcp_unhealthy_max_count = max_count; + + base = event_base_new(); + if (base == NULL) { + syslog(LOG_ERR, "Could not initialize libevent!\n"); + break; + } + + ev_sigint = evsignal_new(base, SIGINT, signal_callback, base); + if (ev_sigint == NULL) { + syslog(LOG_ERR, "Could not create SIGINT libevent signal!\n"); + break; + } + + ev_sigterm = evsignal_new(base, SIGTERM, signal_callback, base); + if (ev_sigterm == NULL) { + syslog(LOG_ERR, "Could not create SIGTERM libevent signal!\n"); + break; + } + + ev_timeout = event_new(base, -1, EV_PERSIST, timeout_callback, base); + if (ev_timeout == NULL) { + syslog(LOG_ERR, "Could not create libevent timer!\n"); + break; + } + + rv = 0; + } while (0); + + return rv; +} + +/** + * @code dhcp_mon_shutdown(); + * + * @brief shuts down libevent loop + */ +void dhcp_mon_shutdown() +{ + event_del(ev_timeout); + event_del(ev_sigint); + event_del(ev_sigterm); + + event_free(ev_timeout); + event_free(ev_sigint); + event_free(ev_sigterm); + + event_base_free(base); +} + +/** + * @code dhcp_mon_start(snaplen); + * + * @brief start monitoring DHCP Relay + */ +int dhcp_mon_start(int snaplen) +{ + int rv = -1; + + do + { + if (dhcp_devman_start_capture(snaplen, base) != 0) { + break; + } + + if (evsignal_add(ev_sigint, NULL) != 0) { + syslog(LOG_ERR, "Could not add SIGINT libevent signal!\n"); + break; + } + + if (evsignal_add(ev_sigterm, NULL) != 0) { + syslog(LOG_ERR, "Could not add SIGTERM libevent signal!\n"); + break; + } + + struct timeval event_time = {.tv_sec = window_interval_sec, .tv_usec = 0}; + if (evtimer_add(ev_timeout, &event_time) != 0) { + syslog(LOG_ERR, "Could not add event timer to libevent!\n"); + break; + } + + if (event_base_dispatch(base) != 0) { + syslog(LOG_ERR, "Could not start libevent dispatching loop!\n"); + break; + } + + rv = 0; + } while (0); + + return rv; +} + +/** + * @code dhcp_mon_stop(); + * + * @brief stop monitoring DHCP Relay + */ +void dhcp_mon_stop() +{ + event_base_loopexit(base, NULL); +} diff --git a/src/dhcpmon/src/dhcp_mon.h b/src/dhcpmon/src/dhcp_mon.h new file mode 100644 index 000000000000..44d361b32ec0 --- /dev/null +++ b/src/dhcpmon/src/dhcp_mon.h @@ -0,0 +1,54 @@ +/** + * @file dhcp_mon.h + * + * @brief dhcp relay monitor module + * + */ + +#ifndef DHCP_MON_H_ +#define DHCP_MON_H_ + +/** + * @code dhcp_mon_init(window_ssec, max_count); + * + * @brief initializes event base and periodic timer event that continuously collects dhcp relay health status every + * window_sec seconds. It also writes to syslog when dhcp relay has been unhealthy for consecutive max_count + * checks. + * + * @param window_sec time interval between health checks + * @param max_count max count of consecutive unhealthy statuses before reporting to syslog + * + * @return 0 upon success, otherwise upon failure + */ +int dhcp_mon_init(int window_sec, int max_count); + +/** + * @code dhcp_mon_shutdown(); + * + * @brief shuts down libevent loop + * + * @return none + */ +void dhcp_mon_shutdown(); + +/** + * @code dhcp_mon_start(snaplen); + * + * @brief start monitoring DHCP Relay + * + * @param snaplen packet capture length + * + * @return 0 upon success, otherwise upon failure + */ +int dhcp_mon_start(int snaplen); + +/** + * @code dhcp_mon_stop(); + * + * @brief stop monitoring DHCP Relay + * + * @return none + */ +void dhcp_mon_stop(); + +#endif /* DHCP_MON_H_ */ diff --git a/src/dhcpmon/src/main.c b/src/dhcpmon/src/main.c new file mode 100644 index 000000000000..11eab6ee9ea1 --- /dev/null +++ b/src/dhcpmon/src/main.c @@ -0,0 +1,174 @@ +/** + * @file main.c + * + * @brief: Main entry point for dhcpmon utility. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dhcp_mon.h" +#include "dhcp_devman.h" + +/** dhcpmon_default_snaplen: default snap length of packet being captured */ +static const uint32_t dhcpmon_default_snaplen = 65535; +/** dhcpmon_default_health_check_window: default value for a time window, during which DHCP DORA packet counts are being + * collected */ +static const uint32_t dhcpmon_default_health_check_window = 12; +/** dhcpmon_default_unhealthy_max_count: default max consecutive unhealthy status reported before reporting an issue + * with DHCP relay */ +static const uint32_t dhcpmon_default_unhealthy_max_count = 10; + +/** + * @code usage(prog); + * + * @brief prints help message about how to use dhcpmon utility + * + * @param prog program name + * + * @return none + */ +static void usage(const char *prog) +{ + printf("Usage: %s -id {-iu }+ [-w ]" + "[-c ] [-s ] [-d]\n", prog); + printf("where\n"); + printf("\tsouth interface: is a vlan interface,\n"); + printf("\tnorth interface: is a TOR-T1 interface,\n"); + printf("\tsnapshot window: during which DHCP counters are gathered and DHCP status is validated (default %d),\n", + dhcpmon_default_health_check_window); + printf("\tunhealthy status count: count of consecutive unhealthy status before writing an alert to syslog " + "(default %d),\n", + dhcpmon_default_unhealthy_max_count); + printf("\tsnap length: snap length of packet capture (default %d),\n", dhcpmon_default_snaplen); + printf("\t-d: daemonize %s.\n", prog); + + exit(EXIT_SUCCESS); +} + +/** + * @code dhcpmon_daemonize(); + * + * @brief make this utility run as a daemon. + * + * @return none + */ +static void dhcpmon_daemonize() +{ + pid_t pid, sid; + pid = fork(); + if (pid < 0) { + syslog(LOG_ALERT, "fork: %s", strerror(errno)); + exit(EXIT_FAILURE); + } + + if (pid > 0) { + exit(EXIT_SUCCESS); + } + + // this is the daemon running now + umask(0); + // Create a new SID for the child process + sid = setsid(); + if (sid < 0) { + syslog(LOG_ALERT, "setsid: %s", strerror(errno)); + exit(EXIT_FAILURE); + } + + // Change the current working directory + if ((chdir("/")) < 0) { + syslog(LOG_ALERT, "chdir: %s", strerror(errno)); + exit(EXIT_FAILURE); + } + + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); +} + +/** + * @code main(argc, argv); + * + * @brief main entry point of dhcpmon utility + * + * @return int 0 on success, otherwise on failure + */ +int main(int argc, char **argv) +{ + int rv = EXIT_FAILURE; + int i; + int window_interval = dhcpmon_default_health_check_window; + int max_unhealthy_count = dhcpmon_default_unhealthy_max_count; + uint32_t snaplen = dhcpmon_default_snaplen; + int make_daemon = 0; + + setlogmask(LOG_UPTO(LOG_INFO)); + openlog(basename(argv[0]), LOG_CONS | LOG_PID | LOG_NDELAY, LOG_DAEMON); + + dhcp_devman_init(); + + for (i = 1; i < argc;) { + if ((argv[i] == NULL) || (argv[i][0] != '-')) { + break; + } + switch (argv[i][1]) + { + case 'h': + usage(basename(argv[0])); + break; + case 'i': + if (dhcp_devman_add_intf(argv[i + 1], argv[i][2] == 'u') != 0) { + usage(basename(argv[0])); + } + i += 2; + break; + case 'd': + make_daemon = 1; + i++; + break; + case 's': + snaplen = atoi(argv[i + 1]); + i += 2; + break; + case 'w': + window_interval = atoi(argv[i + 1]); + i += 2; + break; + case 'c': + max_unhealthy_count = atoi(argv[i + 1]); + i += 2; + break; + default: + fprintf(stderr, "%s: %c: Unknown option\n", basename(argv[0]), argv[i][1]); + usage(basename(argv[0])); + } + } + + if (make_daemon) { + dhcpmon_daemonize(); + } + + if ((dhcp_mon_init(window_interval, max_unhealthy_count) == 0) && + (dhcp_mon_start(snaplen) == 0)) { + + rv = EXIT_SUCCESS; + + dhcp_mon_shutdown(); + } + + dhcp_devman_shutdown(); + + closelog(); + + return rv; +} diff --git a/src/dhcpmon/src/subdir.mk b/src/dhcpmon/src/subdir.mk new file mode 100644 index 000000000000..324977aa39f7 --- /dev/null +++ b/src/dhcpmon/src/subdir.mk @@ -0,0 +1,29 @@ +# Add inputs and outputs from these tool invocations to the build variables +CC := gcc + +C_SRCS += \ +../src/dhcp_device.c \ +../src/dhcp_devman.c \ +../src/dhcp_mon.c \ +../src/main.c + +OBJS += \ +./src/dhcp_device.o \ +./src/dhcp_devman.o \ +./src/dhcp_mon.o \ +./src/main.o + +C_DEPS += \ +./src/dhcp_device.d \ +./src/dhcp_devman.d \ +./src/dhcp_mon.d \ +./src/main.d + + +# Each subdirectory must supply rules for building sources it contributes +src/%.o: ../src/%.c + @echo 'Building file: $<' + @echo 'Invoking: GCC C Compiler' + $(CC) -O3 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' diff --git a/src/iptables/Makefile b/src/iptables/Makefile new file mode 100644 index 000000000000..60154c19ddb1 --- /dev/null +++ b/src/iptables/Makefile @@ -0,0 +1,47 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +MAIN_TARGET = $(IPTABLES) +DERIVED_TARGETS = libip4tc0_$(IPTABLES_VERSION_FULL)_amd64.deb \ + libip6tc0_$(IPTABLES_VERSION_FULL)_amd64.deb \ + libiptc0_$(IPTABLES_VERSION_FULL)_amd64.deb \ + libxtables12_$(IPTABLES_VERSION_FULL)_amd64.deb + +IPTABLES_URL = http://deb.debian.org/debian/pool/main/i/iptables + +DSC_FILE = iptables_$(IPTABLES_VERSION_FULL).dsc +ORIG_FILE = iptables_$(IPTABLES_VERSION).orig.tar.bz2 +DEBIAN_FILE = iptables_$(IPTABLES_VERSION_FULL).debian.tar.xz + +DSC_FILE_URL = $(IPTABLES_URL)/$(DSC_FILE) +ORIG_FILE_URL = $(IPTABLES_URL)/$(ORIG_FILE) +DEBIAN_FILE_URL = $(IPTABLES_URL)/$(DEBIAN_FILE) + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + # Remove any stale files + rm -rf ./iptables-$(IPTABLES_VERSION) + + # Get iptables release + wget -NO "$(DSC_FILE)" $(DSC_FILE_URL) + wget -NO "$(ORIG_FILE)" $(ORIG_FILE_URL) + wget -NO "$(DEBIAN_FILE)" $(DEBIAN_FILE_URL) + dpkg-source -x iptables_$(IPTABLES_VERSION_FULL).dsc + + pushd iptables-$(IPTABLES_VERSION) + git init + git add -f * + git commit -m "unmodified iptables source" + + # Apply patches + stg init + stg import -s ../patch/series + + # Build source and Debian packages + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + popd + + # Move the newly-built .deb packages to the destination directory + mv $(DERIVED_TARGETS) $* $(DEST)/ + +$(addprefix $(DEST)/, $(DERIVED_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) diff --git a/src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch b/src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch new file mode 100644 index 000000000000..f7fba85a270b --- /dev/null +++ b/src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch @@ -0,0 +1,267 @@ +From 92f5aee7372748845f11b7a10d880f968769e860 Mon Sep 17 00:00:00 2001 +From: Kiran Kella +Date: Wed, 7 Aug 2019 07:22:42 -0700 +Subject: [PATCH] Passing fullcone option for SNAT and DNAT + +--- + extensions/libipt_DNAT.c | 22 +++++++++++++++++++++- + extensions/libipt_MASQUERADE.c | 21 ++++++++++++++++++++- + extensions/libipt_SNAT.c | 22 +++++++++++++++++++++- + 3 files changed, 62 insertions(+), 3 deletions(-) + +diff --git a/extensions/libipt_DNAT.c b/extensions/libipt_DNAT.c +index a14d16f..4bfab98 100644 +--- a/extensions/libipt_DNAT.c ++++ b/extensions/libipt_DNAT.c +@@ -8,14 +8,20 @@ + #include + #include + ++/* Temporarily defining here, need to be picked up from the ++ * new kernel header linux/netfilter/nf_nat.h */ ++#define NF_NAT_RANGE_FULLCONE (1 << 5) ++ + enum { + O_TO_DEST = 0, + O_RANDOM, + O_PERSISTENT, + O_X_TO_DEST, /* hidden flag */ ++ O_FULLCONE, + F_TO_DEST = 1 << O_TO_DEST, + F_RANDOM = 1 << O_RANDOM, + F_X_TO_DEST = 1 << O_X_TO_DEST, ++ F_FULLCONE = 1 << O_FULLCONE + }; + + /* Dest NAT data consists of a multi-range, indicating where to map +@@ -32,7 +38,7 @@ static void DNAT_help(void) + "DNAT target options:\n" + " --to-destination [[-]][:port[-port]]\n" + " Address to map destination to.\n" +-"[--random] [--persistent]\n"); ++"[--random] [--persistent] [--fullcone]\n"); + } + + static const struct xt_option_entry DNAT_opts[] = { +@@ -40,6 +46,7 @@ static const struct xt_option_entry DNAT_opts[] = { + .flags = XTOPT_MAND | XTOPT_MULTI}, + {.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE}, + {.name = "persistent", .id = O_PERSISTENT, .type = XTTYPE_NONE}, ++ {.name = "fullcone", .id = O_FULLCONE, .type = XTTYPE_NONE}, + XTOPT_TABLEEND, + }; + +@@ -185,10 +192,14 @@ static void DNAT_parse(struct xt_option_call *cb) + static void DNAT_fcheck(struct xt_fcheck_call *cb) + { + static const unsigned int f = F_TO_DEST | F_RANDOM; ++ static const unsigned int c = F_FULLCONE; + struct nf_nat_ipv4_multi_range_compat *mr = cb->data; + + if ((cb->xflags & f) == f) + mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM; ++ ++ if ((cb->xflags & c) == c) ++ mr->range[0].flags |= NF_NAT_RANGE_FULLCONE; + } + + static void print_range(const struct nf_nat_ipv4_range *r) +@@ -224,6 +235,8 @@ static void DNAT_print(const void *ip, const struct xt_entry_target *target, + printf(" random"); + if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT) + printf(" persistent"); ++ if (info->mr.range[i].flags & NF_NAT_RANGE_FULLCONE) ++ printf(" fullcone"); + } + } + +@@ -239,6 +252,8 @@ static void DNAT_save(const void *ip, const struct xt_entry_target *target) + printf(" --random"); + if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT) + printf(" --persistent"); ++ if (info->mr.range[i].flags & NF_NAT_RANGE_FULLCONE) ++ printf(" --fullcone"); + } + } + +@@ -282,6 +297,11 @@ static int DNAT_xlate(struct xt_xlate *xl, + sep = ","; + xt_xlate_add(xl, "%spersistent", sep); + } ++ if (info->mr.range[i].flags & NF_NAT_RANGE_FULLCONE) { ++ if (sep_need) ++ sep = ","; ++ xt_xlate_add(xl, "%sfullcone", sep); ++ } + } + + return 1; +diff --git a/extensions/libipt_MASQUERADE.c b/extensions/libipt_MASQUERADE.c +index b7b5fc7..88ff650 100644 +--- a/extensions/libipt_MASQUERADE.c ++++ b/extensions/libipt_MASQUERADE.c +@@ -8,9 +8,15 @@ + #include + #include + ++/* Temporarily defining here, need to be picked up from the ++ * new kernel header linux/netfilter/nf_nat.h */ ++#define NF_NAT_RANGE_FULLCONE (1 << 5) ++ + enum { + O_TO_PORTS = 0, + O_RANDOM, ++ O_RANDOM_FULLY, ++ O_FULLCONE + }; + + static void MASQUERADE_help(void) +@@ -20,12 +26,15 @@ static void MASQUERADE_help(void) + " --to-ports [-]\n" + " Port (range) to map to.\n" + " --random\n" +-" Randomize source port.\n"); ++" Randomize source port.\n" ++" --fullcone\n" ++" Do fullcone NAT mapping.\n"); + } + + static const struct xt_option_entry MASQUERADE_opts[] = { + {.name = "to-ports", .id = O_TO_PORTS, .type = XTTYPE_STRING}, + {.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE}, ++ {.name = "fullcone", .id = O_FULLCONE, .type = XTTYPE_NONE}, + XTOPT_TABLEEND, + }; + +@@ -97,6 +106,9 @@ static void MASQUERADE_parse(struct xt_option_call *cb) + case O_RANDOM: + mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM; + break; ++ case O_FULLCONE: ++ mr->range[0].flags |= NF_NAT_RANGE_FULLCONE; ++ break; + } + } + +@@ -116,6 +128,8 @@ MASQUERADE_print(const void *ip, const struct xt_entry_target *target, + + if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) + printf(" random"); ++ if (r->flags & NF_NAT_RANGE_FULLCONE) ++ printf(" fullcone"); + } + + static void +@@ -132,6 +146,8 @@ MASQUERADE_save(const void *ip, const struct xt_entry_target *target) + + if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) + printf(" --random"); ++ if (r->flags & NF_NAT_RANGE_FULLCONE) ++ printf(" --fullcone"); + } + + static int MASQUERADE_xlate(struct xt_xlate *xl, +@@ -153,6 +169,9 @@ static int MASQUERADE_xlate(struct xt_xlate *xl, + if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) + xt_xlate_add(xl, "random "); + ++ if (r->flags & NF_NAT_RANGE_FULLCONE) ++ xt_xlate_add(xl, "fullcone "); ++ + return 1; + } + +diff --git a/extensions/libipt_SNAT.c b/extensions/libipt_SNAT.c +index e92d811..9634ba9 100644 +--- a/extensions/libipt_SNAT.c ++++ b/extensions/libipt_SNAT.c +@@ -8,16 +8,22 @@ + #include + #include + ++/* Temporarily defining here, need to be picked up from the ++ * new kernel header linux/netfilter/nf_nat.h */ ++#define NF_NAT_RANGE_FULLCONE (1 << 5) ++ + enum { + O_TO_SRC = 0, + O_RANDOM, + O_RANDOM_FULLY, + O_PERSISTENT, + O_X_TO_SRC, ++ O_FULLCONE, + F_TO_SRC = 1 << O_TO_SRC, + F_RANDOM = 1 << O_RANDOM, + F_RANDOM_FULLY = 1 << O_RANDOM_FULLY, + F_X_TO_SRC = 1 << O_X_TO_SRC, ++ F_FULLCONE = 1 << O_FULLCONE + }; + + /* Source NAT data consists of a multi-range, indicating where to map +@@ -34,7 +40,7 @@ static void SNAT_help(void) + "SNAT target options:\n" + " --to-source [[-]][:port[-port]]\n" + " Address to map source to.\n" +-"[--random] [--random-fully] [--persistent]\n"); ++"[--random] [--random-fully] [--persistent] [--fullcone]\n"); + } + + static const struct xt_option_entry SNAT_opts[] = { +@@ -43,6 +49,7 @@ static const struct xt_option_entry SNAT_opts[] = { + {.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE}, + {.name = "random-fully", .id = O_RANDOM_FULLY, .type = XTTYPE_NONE}, + {.name = "persistent", .id = O_PERSISTENT, .type = XTTYPE_NONE}, ++ {.name = "fullcone", .id = O_FULLCONE, .type = XTTYPE_NONE}, + XTOPT_TABLEEND, + }; + +@@ -189,12 +196,15 @@ static void SNAT_fcheck(struct xt_fcheck_call *cb) + { + static const unsigned int f = F_TO_SRC | F_RANDOM; + static const unsigned int r = F_TO_SRC | F_RANDOM_FULLY; ++ static const unsigned int c = F_TO_SRC | F_FULLCONE; + struct nf_nat_ipv4_multi_range_compat *mr = cb->data; + + if ((cb->xflags & f) == f) + mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM; + if ((cb->xflags & r) == r) + mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY; ++ if ((cb->xflags & c) == c) ++ mr->range[0].flags |= NF_NAT_RANGE_FULLCONE; + } + + static void print_range(const struct nf_nat_ipv4_range *r) +@@ -232,6 +242,8 @@ static void SNAT_print(const void *ip, const struct xt_entry_target *target, + printf(" random-fully"); + if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT) + printf(" persistent"); ++ if (info->mr.range[i].flags & NF_NAT_RANGE_FULLCONE) ++ printf(" fullcone"); + } + } + +@@ -249,6 +261,8 @@ static void SNAT_save(const void *ip, const struct xt_entry_target *target) + printf(" --random-fully"); + if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT) + printf(" --persistent"); ++ if (info->mr.range[i].flags & NF_NAT_RANGE_FULLCONE) ++ printf(" --fullcone"); + } + } + +@@ -299,6 +313,12 @@ static int SNAT_xlate(struct xt_xlate *xl, + sep = ","; + xt_xlate_add(xl, "%spersistent", sep); + } ++ if (info->mr.range[i].flags & NF_NAT_RANGE_FULLCONE) { ++ if (sep_need) ++ sep = ","; ++ xt_xlate_add(xl, "%sfullcone", sep); ++ sep_need = true; ++ } + } + + return 1; +-- +2.18.0 + diff --git a/src/iptables/patch/series b/src/iptables/patch/series new file mode 100644 index 000000000000..df084ed96ed3 --- /dev/null +++ b/src/iptables/patch/series @@ -0,0 +1 @@ +0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch diff --git a/src/libnl3/Makefile b/src/libnl3/Makefile index c9fc72f50f74..a0e9891c9efc 100644 --- a/src/libnl3/Makefile +++ b/src/libnl3/Makefile @@ -16,12 +16,11 @@ DERIVED_TARGETS = libnl-3-dev_$(LIBNL3_VERSION)_$(CONFIGURED_ARCH).deb \ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Obtaining the libnl3 rm -rf ./libnl3-$(LIBNL3_VERSION_BASE) - wget -O libnl3_$(LIBNL3_VERSION_BASE).orig.tar.gz -N "https://sonicstorage.blob.core.windows.net/packages/libnl3_$(LIBNL3_VERSION_BASE).orig.tar.gz?sv=2015-04-05&sr=b&sig=b4DnqrIsyVBDLmYhw7qwfaUJWqGCX2lDVMmmx7ihfrU%3D&se=2028-06-16T21%3A06%3A00Z&sp=r" - wget -O libnl3_$(LIBNL3_VERSION).dsc -N "https://sonicstorage.blob.core.windows.net/packages/libnl3_$(LIBNL3_VERSION).dsc?sv=2015-04-05&sr=b&sig=AWTX45oDbeGA%2BRJZyiCcHmeIfCAgSeNV3IqopOBaRDg%3D&se=2028-06-16T21%3A05%3A30Z&sp=r" - wget -O libnl3_$(LIBNL3_VERSION).debian.tar.xz -N "https://sonicstorage.blob.core.windows.net/packages/libnl3_$(LIBNL3_VERSION).debian.tar.xz?sv=2015-04-05&sr=b&sig=upIZ9dp5WEcLqp3ODeWKJXq5pJWCfeT0TIM0bx76wxM%3D&se=2028-06-16T21%3A04%3A44Z&sp=r" - dpkg-source -x libnl3_$(LIBNL3_VERSION).dsc + git clone https://github.com/thom311/libnl libnl3-$(LIBNL3_VERSION_BASE) + pushd libnl3-$(LIBNL3_VERSION_BASE) + git checkout tags/libnl$(subst .,_,$(LIBNL3_VERSION_BASE)) - pushd ./libnl3-$(LIBNL3_VERSION_BASE) + ln -s ../debian debian dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) popd diff --git a/src/libnl3/debian/README.Debian b/src/libnl3/debian/README.Debian new file mode 100644 index 000000000000..002e249bbfcb --- /dev/null +++ b/src/libnl3/debian/README.Debian @@ -0,0 +1,17 @@ + +libnl versions explained +======================== + +Once libnl3 hits the archive there will exist 3 versions of libnl. +libnl1 with libnl-dev - up until March 2011 the stable version +libnl2 with libnl2-dev - development version that resulted in +libnl3 with libnl3-dev - the new stable (API and ABI wise) version + +libnl1 has currently a lot of users in the archive and a lot of changes +happened since its last upstream release in 2008-01. + +The plan is therefore to introduce libnl3, port the two users of libnl2 +(freesmartphone.org libs and powertop) to it, remove libnl2 and don't touch +libnl1 and libnl-dev for now. + + -- Heiko Stuebner Sat, 21 May 2011 19:25:13 +0200 diff --git a/src/libnl3/debian/README.source b/src/libnl3/debian/README.source new file mode 100644 index 000000000000..f6e8ee70da94 --- /dev/null +++ b/src/libnl3/debian/README.source @@ -0,0 +1,10 @@ +This package uses the simple-patchsys of cdbs. + +The following patches are used: +0001: Fixes the header inclusion in the Makefiles. + This for example make distcheck +0002: Includes all generated libraries as linktargets in the pkg-config file. + Reason: Currently libnl3 generates a bunch of child libraries. + These don't get individual .pc files from upstream at the moment but + programs linking against libnl3 using the .pc file mostly need these + additional libraries too. diff --git a/src/libnl3/debian/changelog b/src/libnl3/debian/changelog new file mode 100644 index 000000000000..c51ae1121796 --- /dev/null +++ b/src/libnl3/debian/changelog @@ -0,0 +1,1043 @@ +libnl3 (3.5.0-1) unstable; urgency=low + + [ skuklinski ] + * route/link: IFLA_VLAN_PROTOCOL added to vlan_put_attrs + + [ Thomas Haller ] + * rtnl/link: indicate capability NL_CAPABILITY_RTNL_LINK_VLAN_PROTOCOL_SERIALZE + + [ David Ahern ] + * route/vrf: add VRF support + * neigh: add support for NTF_SELF + + [ Beniamino Galvani ] + * route/link: fix parsing of 'remote' attribute for GRE links + + [ Thomas Haller ] + * route/vlan: allow clearing vlan ingress map + + [ David Ahern ] + * link/neigh: add flags option to link and neighbor caches + + [ Thomas Haller ] + * gitignore: ignore test binaries in "tests/" + + [ Beniamino Galvani ] + * route/link: add macvtap support + * route/link: fix dump of parent link for some link types + * route/link: add ipv6 support to vxlan links + + [ Tobias Jungel ] + * route/link: corrected array size for inet_policy + + [ David Ahern ] + * route/link: add link info compare operation + * route/link/vxlan: trivial rename VXLAN_HAS_ prefix and vxi_mask + * route/link/vxlan: add support for link_info compare + + [ Andrew Vagin ] + * libnl: don't use out-of-scope buffer in nl_send_iovec() + + [ David Ahern ] + * link: add AF operation to append attributes to a GETLINK message + * lib: handle family-based parsing of IFLA_AF_SPEC attribute + + [ Thomas Haller ] + * include/linux: update copy of kernel headers + + [ David Ahern ] + * bridge: add support for VLANs + + [ Tobias Jungel ] + * route/link: handle RTEXT_FILTER_BRVLAN_COMPRESSED + * route/link/bridge: fixed return type + + [ Quentin Armitage ] + * route/link: add support for IN6_ADDR_GEN_MODE_STABLE_PRIVACY + + [ Amit Khatri ] + * lib/route: potential memory leak in pktloc.c + + [ Nick Lewycky ] + * remove null dereference from netlink/link.h + + [ David Ahern ] + * lib: update ce-mask to uint64_t + + [ Thomas Haller ] + * libnl: add nl_object_diff64() to libnl-3.sym + * lib/utils: add NL_CAPABILITY_NL_OBJECT_DIFF64 capability + + [ Przemyslaw Szczerbik ] + * lib: add type casting for nla_for_each_nested macro + + [ Tobias Klauser ] + * build: move -rdynamic from CPPFLAGS to LDFLAGS + + [ Thomas Haller ] + * route: sort entries in libnl-route-3.sym by name + + [ Haishuang Yan ] + * ipgre: add support for gretap tunnel + + [ Thadeu Lima de Souza Cascardo ] + * sit: add 6RD support + + [ Thomas Haller ] + * sit/trivial: whitespace + * sit: don't print ip6rd_prefix as integer in sit_dump_details() + * sit: refactor IS_SIT_LINK_ASSERT() + * sit: fix invalid declaration of rtnl_link_sit_get_proto() in sit.h + * sit: add public API for sit 6RD support + + [ Jonas Johansson ] + * neigh: support neighbour flag NTF_SELF + * neigh: add function to look up neighbour (fdb) by ifindex, mac and vlan + + [ Jef Oliver ] + * link: support RTEXT_FILTER_VF + + [ Thomas Haller ] + * link: allow overwriting IFLA_EXT_MASK flag in ao_get_af() function + + [ Przemyslaw Szczerbik ] + * lib: return error on Netlink attribute length overflow + + [ Thomas Egerer ] + * xfrm: fix buffer overflow when copying keys + * xfrm: check length of alg_name before strcpying it + * xfrm: make character pointers in setters const + * xfrm: fix segfault when using encapsulation templates + + [ Thomas Haller ] + * xfrm: reuse encap data in xfrmnl_sa_set_encap_tmpl() + + [ Thomas Egerer ] + * xfrm: fix memory leak for encap original address + * xfrm: attach only one xfrm alg attribute to netlink message + + [ Thomas Haller ] + * xfrm: fix memleak in build_xfrm_sa_message() error-path + + [ Sabrina Dubroca ] + * pass flags through ->io_compare op + * vxlan: properly handle LOOSE_COMPARISON in ->io_compare + * import macsec uapi headers + * lib/route: add macsec support + + [ Thomas Haller ] + * xfrm: allow avoiding buffer overflow for key in xfrmnl_sa_get_*_params() + * route/addr: fix ID comparison for AF_INET and AF_INET6 addresses + * route/addr: fix handling peer addresses for IPv4 addresses + * route/addr: add capability NL_CAPABILITY_RTNL_ADDR_PEER_FIX to indicate address fixes + * build: fix adding macsec files to include/Makefile.am + * libnl-3.2.28-rc1 release + * libnl-3.2.28 release + + [ Craig Gallek ] + * build: fixup headers for C++ inclusion + + [ Peter Wu ] + * trivial: whitespace-only fixes for src and lib + * cli: add noreturn attributes + * xfrm: fix memleak in another error path of build_xfrm_sa_message + * exp: fix a GCC 6 -Wmisleading-indentation warning + * doc: fix URLs and typo + + [ Tobias Jungel ] + * route/addr: address attributes based on object + + [ Thomas Haller ] + * lib: capability NL_CAPABILITY_RTNL_ADDR_PEER_ID_FIX for ID comparison of v4 addresses + * nl-addr: avoid read-out-of-bound in nl_addr_fill_sockaddr() + + [ André Draszik ] + * lib: add utility function nl_strerror_l() + * lib: switch to using strerror_l() instead of strerror_r() + * src: switch to using strerror_l() instead of strerror_r() + + [ Jeff Squyres ] + * compat: add linux/socket.h for __kernel_sa_family_t + + [ Jef Oliver ] + * lib/route: allow override of message type during link change + * lib/route: set IFLA_PROTINFO attribute in request message + * lib/route: modify link/bridge to set attributes + + [ Davide Caratti ] + * macsec: fix endianness of 'sci' parameter + * macsec: fix maximum ICV length + * remove multiple implementations of htonll(), ntohll() + + [ Jef Oliver ] + * lib/route: Fix appending IFLA_BRPORT_FASTLEAVE + * lib/route: Add port state translation functions + * lib/route: Extend Bridge Flags + * lib/route: Allow override of IFLA_AF_SPEC nesting + * lib/route: Support IFLA_BRIDGE_MODE + + [ Thomas Haller ] + * trivial: whitespace + * bridge: change return values for rtnl_link_bridge_get_hwmode() + + [ Michael Braun ] + * macvlan: add support for "source" mode + + [ Thomas Haller ] + * macvlan: adjust types and merge MACVLAN_HAS_MACCOUNT and MACVLAN_HAS_MACDATA + + [ Brandon Carpenter ] + * vxlan: add support for additional VXLAN attributes. + + [ Thomas Haller ] + * vxlan: fix exporting new symbols + * vxlan: remove redundant enable/disable API from vxlan + * vxlan: restore previous VXLAN_ATTR flag values + * vxlan: don't store vxlan flags as ce_mask + * vxlan: refactor setting/getting vxlan flags + * vxlan: fix error code for missing attribute + + [ Jef Oliver ] + * lib/route: Export correct ipgre functionality + + [ Thomas Haller ] + * lib/route: preserve old ABI for rtnl_link_get_pmtudisc() + + [ Thomas Egerer ] + * xfrm: fix xfrm security context management + * xfrm: add capability reference to xfrmnl_sa_set_* + + [ Thomas Haller ] + * xfrm: remove unused struct xfrmnl_sec_ctx from header files + + [ Jef Oliver ] + * lib/route: SRIOV Parse and Read support + * lib/route: SRIOV Clone Support + * lib/route: SRIOV Utility Functions + * lib/route: SRIOV Info Dump Functions + * lib/route: SRIOV Set Functionality + + [ Thomas Haller ] + * route: remove symbols of internal API from ABI + + [ Tobias Klauser ] + * lib/route: keep link stats minlen compatible with kernel < 4.6 + + [ Thomas Haller ] + * utils: add internal _nl_offset_plus_sizeof() macro + * lib/route: use _nl_offset_plus_sizeof() macro for minlen field for rtln_link_policy + + [ Jonas Johansson ] + * Add PPP support + * ppp: update code after review + * ppp: rename local struct ppp_info* variables; pi -> info + * ppp: fix type of file descriptor; uint32_t -> int32_t + + [ Thomas Haller ] + * ppp: fix API in ppp.h header + + [ Sushma Sitaram ] + * route/cls: support setting of selector fields + + [ Tobias Klauser ] + * src: nl-link-stats: use correct rtnl link stats maximum + * lib/route: add rx_nohandler link stats field + + [ Thomas Haller ] + * nl-link-stats: prefer RTNL_LINK_STATS_MAX over __RTNL_LINK_STATS_MAX + * lib/route: pass sizeof() argument to nl_memcpy() + * link: set ifi_change flags for rtnl_link_build_add_request() + * lib: use MSG_PEEK by default for nl_recvmsgs() + + [ Tobias Jungel ] + * cache_mngr: add include callback v2 + + [ Tobias Klauser ] + * cache: fix GCC warning and avoid variable shadowing + + [ Sushma Sitaram ] + * route/act: add gact tc action + + [ Tobias Klauser ] + * link: add support for IFLA_CARRIER_CHANGES + * link: add support for IFLA_PHYS_PORT_NAME + * link: add support for IFLA_PHYS_SWITCH_ID + * link: add support for IFLA_GSO_MAX_SEGS and IFLA_GSO_MAX_SIZE + * link: fix documentation for rtnl_link_get_carrier_changes + + [ Thomas Haller ] + * libnl-3.2.29-rc1 release + * utils/trivial: rename internal _nl_offset_plus_sizeof() macro to _nl_offsetofend() + + [ Beniamino Galvani ] + * Revert "macsec: fix endianness of 'sci' parameter" + * macsec: document byte order for the SCI and port attributes + + [ Thomas Haller ] + * macsec: fix endianness of sci during dump() + * libnl-3.2.29 release + + [ Tobias Klauser ] + * route/tc: Remove unused function tca_set_kind() + + [ Laine Stump ] + * sriov: fix crash in rtnl_link_sriov_parse_vflist + + [ Thomas Haller ] + * sriov: avoid buffer overrun in rtnl_link_sriov_parse_vflist() + + [ Nick Kralevich ] + * lib/utils.c: lazy initialize user_hz and psched_hz + + [ Thomas Haller ] + * lib/utils.c: ensure calling get_psched_settings() for nl_us2ticks()/nl_ticks2us() + * lib/utils.c: add mutex to get_psched_settings() + + [ Nick Kralevich ] + * fopen: add O_CLOEXEC + + [ Thomas Haller ] + * lib/attr.c: check for valid length argument in nla_reserve() + + [ Tobias Klauser ] + * sit: Fix invalid function prototypes in public header + * sriov: Add missing prototype for rtnl_link_vf_vlan_free() + * qdisc/red: Add missing prototypes for rtnl_red_set_limit() and rtnl_red_get_limit() + * fib_lookup: Add missing prototypes to public header + * link/inet6: Include own public header for function prototypes + * link/ipip: Include own public header for function prototypes + * link/ipip: Add missing prototype for rtnl_link_is_ipip() + * link/ipvti: Include own public header for function prototypes + * link/ipvti: Fix and add function prototypes in public header + * link/macsec: Include own public header for function prototypes + * link/sit: Add missing prototype for rtnl_link_is_sit() + * link/ipgre: Add prototype for ABI-preserving wrapper rtnl_link_get_pmtudisc() + * netfilter/queue: Add missing prototype for nfnl_queue_msg_build_verdict_batch() + * netfilter/exp: Add missing function prototypes + * idiag/req: Add missing function prototype + * xfrm/ae: Include own public header for function prototypes + * xfrm/lifetime: Include own public header for function prototypes + * xfrm/sa: Include own public header for function prototypes + * xfrm/selector: Include own public header for function prototypes + * xfrm/template: Include own public header for function prototypes + * pktloc: Add missing function prototypes + * ematch: Add missing function prototypes + * build: Add -Wmissing-prototypes to CPPFLAGS + + [ Jeroen Roovers ] + * build: distribute in.h in6.h libc-compat.h + + [ Thomas Haller ] + * lib: fix comment for nl_recv() about return value for non-blocking read + * lib: check for integer-overflow in nlmsg_reserve() + * build: cleanup top-level Makefile.am + * build: merge include/Makefile.am into top-level makefile + * build: merge lib/Makefile.am into top-level makefile + * build: merge man/Makefile.am into top-level makefile + * build: merge python/Makefile.am into top-level makefile + * build: merge tests/Makefile.am into top-level makefile + * build: merge src/lib/Makefile.am into top-level makefile + * build: merge src/Makefile.am into top-level makefile + * build: enable building cli during tests + * build: move compiler warning flags to separate autoconf variable + * all: enable -Wmissing-prototype warning for all components + * build: enable more warnings + + [ Roopa Prabhu ] + * route: neigh: use NDA_MASTER for neigh->n_master if available + + [ Simon Buttgereit ] + * fix build_xfrm_sp_message index condition + * fix xfrmnl_sp_set_sec_ctx length attributes + * little style fixes. + * update sp_attr condition in build_xfrm_sp_message + * add possibity to delete policy without index + * update documentation of xfrmnl_sp_get_sec_ctx + * fix of boolean operators + + [ Thomas Haller ] + * xfrm: allow quering optional arguments from xfrmnl_sp_get_sec_ctx() + * xfrm: NUL terminate the ctx_str buffer in xfrmnl_sa_set_sec_ctx() + * build: ensure build directory for generated sources exist + * build: pass --disable-dependency-tracking to `make distcheck` + * build: fix creating directories for generated sources + * build: style cleanup in doc/Makefile.am + * build: reorder checks in configure.ac + * build: add tools/build_release.sh script + * include: don't include kernel headers in public libnl3 headers + * include: restore linux header includes in public headers + * libnl-3.3.0-rc1 release + + [ Alexey Brodkin ] + * lib: escape usage of strerror_l() if it doesn't exist in libc + + [ Thomas Haller ] + * all: don't use math.h or link with libm.so + * libnl-3.3.0 release + * tools: fix building doc in build_release.sh + + [ Markus Trapp ] + * route/link: add accessor API for IPv6 flags + + [ Santhosh Kumar ] + * Provide accessors for actions (rtnl_act). + * Do not increment refcount in rtnl_*_get_action APIs. + + [ Thomas Haller ] + * route: fix symbol versioning + + [ David Ahern ] + * route: Add support for netconf + * nl-monitor: All user to specify line format + * nl-monitor: Add support for netconf caches + * route: Add support for MPLS to netconf + * Update fib_rules.h to latest kernel + * rule: Add support for l3mdev in FIB rules + + [ Thomas Haller ] + * rule: change API for setting/getting l3mdev rule property + + [ Tobias Klauser ] + * addr: add AF_VSOCK to translation table + + [ Thomas Haller ] + * build: don't build cli libraries by default + * build: allow building cli without dynamic librarires support + + [ Tobias Klauser ] + * genl: drop usage of GENL_ID_GENERATE + + [ Rasmus Villemoes ] + * lib/cache_mngr.c: avoid memleak if realloc fails + * lib/cache_mgr.c: remove pointless goto + * lib/data.c: avoid memleak if realloc fails + * lib/route/cls/u32.c: remove pointless nl_data_append calls + * lib/route/cls/u32.c: avoid overflowing an unsigned char + * lib/route/cls/u32.c: let the compiler do pointer arithmetic + * lib/route/cls/u32.c: remove bogus comment + * lib/route/qdisc/netem.c: avoid memory leak if realloc fails + + [ Thomas Haller ] + * lib/route/cls/u32.c: use UCHAR_MAX define instead of numeric 255 + * lib/route/qdisc/netem.c/trivial: fix whitespace and indentation in netem_msg_fill_raw() + * lib/route/qdisc/netem.c/trivial: don't use braces for one-line blocks + + [ Rasmus Villemoes ] + * lib/xfrm/ae.c: fix memcpy(dst, dst) bug + * lib/genl/family.c: fix if (x) y; else y; + + [ Thomas Haller ] + * all: avoid compiler warnings -Wimplicit-fallthrough + * lib/route: add /usr/lib64/tc/ search path for netem dist file + + [ David Ahern ] + * Update rtnetlink.h from kernel tree + * Import mpls header from kernel tree + + [ Thomas Haller ] + * build: add include/linux-private/linux/mpls.h to Makefile.am + + [ David Ahern ] + * addr: Add implementations for mpls_ntop and mpls_pton + * addr: Add support for AF_MPLS + * route: Add support for MPLS address family + * route: Add support for ttl propagation in MPLS routes + * Add support for label stack in nl-route commands + * Import lwtunnel encap files from kernel + * route: Add support for lwtunnel encapsulations + * route: Add support for MPLS encap + + [ Thomas Haller ] + * build: add new include/netlink-private/route/*.h files to Makefile.am + + [ Amit Khatri ] + * Potential memory leak becaue of wrong variable check. + + [ Tobias Klauser ] + * cli: include sys/select.h for select(2) + + [ Thomas Haller ] + * libnl-3.4.0-rc1 release + + [ David Ahern ] + * netconf: Put nc reference in msg_parser + + [ Jeroen Roovers ] + * build: add missing headers for issue #152 + + [ Thomas Haller ] + * libnl-3.4.0 release + * nl: add "const" specifier for nla_policy argument of parse functions [ Roopa Prabhu ] + * route: link: add family to dump messages + * route: neigh: print family in neigh dumps + + [ Sebastian Bixl ] + * route/vlan: fix memory corruption in rtnl_link_vlan_set_egress_map + + [ Thomas Haller ] + * route/vlan: fix cloning vlan link in vlan_clone() + * route/vlan: grow buffer exponentially in rtnl_link_vlan_set_egress_map() + * route/vlan: add capability to indicate heap overflow fix in rtnl_link_vlan_set_egress_map() + * route: fix handling old_nh in rtnl_route_parse() and avoid leak + + [ Jef Oliver ] + * Change rtnl_link_af_ops.ao_override_rtm behavior + + [ Chris Grahn ] + * tests: fix bug in test-create-bridge.c + + [ Steffen Vogel ] + * route: add separate function to set netem qdisc delay distribution + + [ Thomas Haller ] + * all: declare all variables at the beginning of scope (-Wdeclaration-after-statement) + * route: add rtnl_netem_set_delay_distribution_data() to linker script + * route: mark data argument for rtnl_netem_set_delay_distribution_data() as const + * route: fix memleak in rtnl_netem_set_delay_distribution_data() + * route: free previous data in rtnl_netem_set_delay_distribution_data() + * travis: enable more warnings during build + + [ Marcos Paulo de Souza ] + * tests: Add test to {de}activate loopback interface + * lib/veth.c: Disassociate link name of peer name + + [ d0u9 ] + * Coding style format + * Add new function for setting ifindex and parent of a classifier cache. + + [ Thomas Haller ] + * route: rename rtnl_cls_cache_set_tcm_params() and fix symbol versioning + + [ d0u9 ] + * Fix for cgroup filter addition problem. + + [ Thomas Haller ] + * lib: merge implementations of nl_attr_end() and nl_attr_keep_empty() + + [ Wang Jian ] + * link: add Geneve support. + + [ Thomas Haller ] + * lib/rtnl: rename public define RTNL_GENEVE_ID_MAX + + [ Roopa Prabhu ] + * lib: route: rule: add rule_groups to cache ops + + [ Jonas Johansson ] + * route/vrf: initalize clone destination with NULL in vrf_clone() + + [ David Ahern ] + * Update fib_rules.h to latest kernel + * rule: Add support for protocol and port ranges + + [ Lukáš Karas ] + * add demo program for listen conntrack events + * nf-ct-add typo + + [ Thomas Haller ] + * build: sort entries in Makefile.am and .gitignore by name + * build: indent libnl-route-3.sym with tabs + + [ Tobias Jungel ] + * neigh: set correct AF for NDA_DST + * neigh: support bridge entries for vxlan interfaces + + [ Tuetuopay ] + * cache: make "result" output argument for nl_cache_mngr_add() optional + + [ Volodymyr Bendiuga ] + * include: copy entire pkt_cls.h from linux + * route:cls: add matchall classifier + + [ Thomas Haller ] + * route/mall: fix deep cloning mall + + [ Tuetuopay ] + * route/link: fix sequence number handling in rtnl_link_change() + + [ Thomas Haller ] + * route/link: assert in rtnl_link_change() that the sequence number is set as expected + * nl-msg: explicitly initialize nlmsg_seq and nlmsg_pid field in nlmsg_alloc_simple() + + [ d0u9 ] + * route/class: add new api rtnl_class_get_by_parent() + + [ Tobias Jungel ] + * neigh: correct symbol exposed + + [ Matthieu Baerts ] + * nl: fix function name in debug msg + + [ Tobias Jungel ] + * neigh: cache updates as well query AF_BRIDGE neigh + * whitespace cleanup + * nl-neigh-list: free allocated items + * neigh: add get/set functions for NEIGH_ATTR_MASTER + * neigh_dump_line: dump master as well + + [ d0u9 ] + * Add support for cloning cgroup filter object. + + [ Tuetuopay ] + * route/link/vxlan: Fix IPv4 set_local resetting ce_mask + + [ Tobias Jungel ] + * neigh: update neighbour.h and add missing flags + + [ Thomas Winter ] + * ipgre: Fix wrong array size initialization + * ipvti: Fix wrong array size initialization + * if_tunnel: Update IFLA defines up to FWMARK + + [ Thomas Haller ] + * include/linux: update copy of kernel headers + + [ Volodymyr Bendiuga ] + * include: import linux header pkt_sched.h + * route:qdisc: add MQPRIO Qdisc + + [ Thomas Haller ] + * build: cleanup Makefile.am + * lib/tc: ensure correct error code in rtnl_tc_msg_build() + * lib/qdisc: style fixes in "lib/route/qdisc/mqprio.c" + * lib/qdisc: avoid BUG() in "lib/route/qdisc/mqprio.c" + * build: sort entries in libnl-route-3.sym + * lib/tc: fix uninitalized err variable in rtnl_tc_msg_build() + + [ Volodymyr Bendiuga ] + * route:tc: allow to set chain index for tc objects + + [ Thomas Haller ] + * route/tc: return error code from rtnl_tc_get_chain() + + [ Volodymyr Bendiuga ] + * include: import tc_vlan.h + * route:act: add vlan action + + [ Thomas Haller ] + * route/act: style fixes in "lib/route/act/vlan.c" + * route/act: return error code from act-vlan getters + + [ Ilya Pronin ] + * route/cls: fix potential memory leak + + [ Patrick Havelange ] + * nla_ok: fix overrun in attribute iteration. + + [ Wang Jian ] + * link: macvlan fixes + + [ Thomas Haller ] + * route/macvlan: style fixes in "lib/route/link/macvlan.c" + + [ Tobias Jungel ] + * route/link: expose IFLA_INFO_SLAVE_KIND + + [ Thomas Haller ] + * route/link: avoid dangling pointer in rtnl_link_set_slave_type() + + [ Byeonggon Lee ] + * tests: use nl_send_auto() instead of deprecated nl_send_auto_complete() in test-genl.c + + [ Thomas Haller ] + * doc: fix typos in example in documentation + * attr: mark nested attributes as NLA_F_NESTED + + [ xinbao ] + * Add CTA_LABELS and CTA_LABELS_MASK to ctattr_type according to the new kernel + + [ Thomas Haller ] + * route: fix strncpy() warning from coverity about unterminated string + * link/sriov: fix memleak in rtnl_link_sriov_clone() + * utils: add internal helper macros for cleanup + * lib/genl: avoid VLA in cmd_msg_parser() + * travis: enable -Wvla compiler warning in tests + * travis: build tests with NL_MORE_ASSERTS enabled + * xfrm: fix memory corruption (dangling pointer) when when setting xfrmnl_sa + * route/inet6: fix strncpy() in inet6_dump_details() + * route/tc: ensure not string truncation in rtnl_tc_set_kind() + * genl: reject invalid group names in genl_family_add_grp() + + [ Yegor Yefremov ] + * Add SPDX identifiers + + [ Thomas Haller ] + * lib/genl: fix allocating buffer of too small size in cmd_msg_parser() + + [ Michael Forney ] + * dbg: Use __func__ instead of __PRETTY_FUNCTION__ + * all: Avoid pointer arithmetic on `void *` + * lib: Don't return expression in function returning void + * lib: Don't omit second operand to `?` operator + * all: Use __typeof__ instead of typeof + * route: Remove stray `;` at top-level + * Sync linux headers to 4.19.66 + + [ Thomas Haller ] + * idiag: workaround and add comment about idiagnl_send_simple() only handling 8 bit flags + * lib: accept %NULL arguments for nl_addr_cmp() + * lib: fix error code from nfnl_exp_build_message() + + [ Eyal Birger ] + * doc/route: fix example code comments + * xfrmi: introduce XFRM interfaces support + + [ Thomas Haller ] + * xfrmi: return error code from getters for XFRM links + * route/trivial: sort entries in "libnl-route-3.sym" asciibetically + + [ d0u9 ] + * Add 64bit rate/ceil support for htb class + + [ Thomas Haller ] + * route/qdisc: adjust API for 64 bit rate/ceil support for htb class + * libnl-3.5.0 release + + -- Tamer Ahmed Thu, 02 Jan 2020 10:25:18 -0800 + +libnl3 (3.2.27-2) unstable; urgency=low + + * Add upstream fix for CVE-2017-0553 (Closes: #859948) + + -- Heiko Stuebner Mon, 10 Apr 2017 11:48:23 +0200 + +libnl3 (3.2.27-1) unstable; urgency=low + + * New upstream release + Including fixes for unusable sockets after a failed portid + generation (Closes: #808213) + + -- Heiko Stuebner Sun, 24 Jan 2016 23:54:47 +0100 + +libnl3 (3.2.26-1) unstable; urgency=low + + * New upstream release + * Provide Multiarch:same dev packages + * Add new libnl-xfrm library handling packet transformations + * Update standards to 3.9.6 + + -- Heiko Stuebner Mon, 13 Jul 2015 14:16:22 +0200 + +libnl3 (3.2.24-2) unstable; urgency=low + + * Backport two upstream fixes to prevent issues with older kernels: + - dfd0a80ec845 (route: don't enforce minlen in inet6_parse_protinfo() + (IFLA_PROTINFO) and inet_parse_af() (IFLA_AF_SPEC) + - 5206c050504f (route/addr: only sent IFA_FLAGS when needed to workaround + picky older kernels) + + -- Heiko Stuebner Fri, 18 Apr 2014 17:19:37 +0200 + +libnl3 (3.2.24-1) unstable; urgency=low + + * New upstream release + * Add new libnl-idiag library handling inetdiag requests + + -- Heiko Stuebner Sun, 16 Feb 2014 14:23:26 +0100 + +libnl3 (3.2.21-1) unstable; urgency=low + + * New upstream release (Closes: #707081) + Including CAN support (Closes: #698954) + * Add symbols files (Closes: #654758) + * Provide static libraries (Closes: #693939, #693940) + * Update standards to 3.9.4 + * Removed doc package. Libnl3 documentation is released + separately now. + + -- Heiko Stuebner Tue, 21 May 2013 11:39:13 +0200 + +libnl3 (3.2.7-4) unstable; urgency=low + + * Add watch file (Closes: #679473) + * Use dh-autoreconf to update the build system (Closes: 679474) + + -- Heiko Stuebner Sat, 30 Jun 2012 15:54:25 +0200 + +libnl3 (3.2.7-3) unstable; urgency=low + + * Fix FTBFS due to failing gen-tags.sh (Closes: #674322) + * Convert to Multi-Arch (Closes: #676611) + * Update standards to 3.9.3 - no changes + * Switch to dpkg-source format 3.0 (quilt) + + -- Heiko Stuebner Mon, 18 Jun 2012 21:19:30 +0200 + +libnl3 (3.2.7-2) unstable; urgency=low + + * Force doxygen dot-threads to 1 to circumvent segfaults on armel + * Add missing build-dependency on ghostscript + + -- Heiko Stuebner Mon, 05 Mar 2012 23:29:10 +0100 + +libnl3 (3.2.7-1) unstable; urgency=low + + * New upstream release + * Build-depend on source-highlight (Closes: #657254) + + -- Heiko Stuebner Mon, 13 Feb 2012 18:59:30 +0100 + +libnl3 (3.2.3-2) unstable; urgency=low + + * Upload to unstable + * Split split udeb to be in line with regular packages + * Move libnl and libnl-genl to /lib for iw and wpa_supplicant. + + -- Heiko Stuebner Mon, 19 Dec 2011 20:43:21 +0100 + +libnl3 (3.2.3-1) experimental; urgency=low + + * Upload to experimental to not break debian-installer + * Split library and dev packages for the individual libraries + * Add utils package + + [Mathieu Trudel-Lapierre ] + * New upstream release (Closes: #648819) + * debian/patches/0001-fix-headers.patch, + debian/patches/0002-link-sub-libs.patch, + debian/patches/0003-fix-out-of-tree-build.patch: dropped. + * debian/patches/0004-more-out-of-tree-build-fixes.patch: new patch; adjust + Makefiles some more to properly deal with the out-of-tree build when + generating headers and documentation. + * debian/control: + - rename packages to follow upstream soname. + - add python-pygments, xmlstarlet, texlive-latex-base and asciidoc to + Build-Depends. + * debian/rules: update due to upstream soname changes. + * debian/*.install: rename and update due to upstream soname changes. + * debian/libnl-3-200.install: netlink config files should be installed to + /etc/libnl, not /etc/libnl3. + * debian/libnl-3-doc.install, + debian/libnl-3-doc.doc-base: update to take into account new paths. + + -- Heiko Stuebner Tue, 06 Nov 2011 21:23:12 +0200 + +libnl3 (3.0-2) unstable; urgency=low + + * Acknowledge NMU + * Install config-files to /etc/libnl3 (Closes: #632790) + + -- Heiko Stuebner Mon, 26 Sep 2011 20:27:45 +0200 + +libnl3 (3.0-1.1) unstable; urgency=low + + * Non-maintainer upload with agreement from Heiko Stuebner + * Add libnl3-udeb package with seperate build for + debian-installer (Closes: #635962). + + -- Gaudenz Steinlin Fri, 29 Jul 2011 23:25:48 +0200 + +libnl3 (3.0-1) unstable; urgency=low + + * New upstream release (Closes: #626098) + see README.Debian for version explanation. + * Update standards to 3.9.2 + + -- Heiko Stuebner Sat, 21 May 2011 19:25:13 +0200 + +libnl2 (2.0-1) unstable; urgency=low + + * New upstream release (Closes: #603765) + * Fix compilation with binutils-gold or ld --no-add-needed + (Closes: #615745) + * Update standards + * Update build dependencies - tetex-live is not necessary + anymore (Closes: #616260) + + -- Heiko Stuebner Sun, 06 Mar 2011 18:20:47 +0100 + +libnl2 (1.99+git20091216-2) unstable; urgency=low + + * add README.source describing the patches in use. + * remove libnl*-provides - libnl2 should stay sepparate + from libnl1 for now + + -- Heiko Stuebner Wed, 10 Mar 2010 18:03:35 +0100 + +libnl2 (1.99+git20091216-1) unstable; urgency=low + + * New upstream snapshot + * New source name to enable installing libnl and libnl2 side by side + * Set myself as new maintainer for libnl2 according to agreement + with Michael Biebl + * Add debug package + * README.Debian warns of possible breakage in this snapshot + * Add Patch 0001 which fixes some errors in the build system + * Add Patch 0002 which adds libnl-?? libs to linker statement + until I can resolve this with upstream + + -- Heiko Stuebner Mon, 15 Feb 2010 21:50:35 +0100 + +libnl (1.1-5) unstable; urgency=low + + * Add symbols file for libnl1. + + -- Michael Biebl Wed, 25 Feb 2009 00:26:05 +0100 + +libnl (1.1-4) unstable; urgency=low + + * debian/control + - Add ${misc:Depends} to all binary packages. + - Bump Build-Depends on debhelper to (>= 7). + * debian/compat + - Bump debhelper compat level to 7. + * debian/rules + - Include debhelper.mk before other files as recommended by the cdbs + documentation. + + -- Michael Biebl Wed, 18 Feb 2009 13:26:53 +0100 + +libnl (1.1-3) unstable; urgency=low + + * debian/control + - Bump Standards-Version to 3.8.0. + * Switch to quilt for patch management. + * Add README.source which refers to the quilt documentation. + * debian/patches/limits.patch + - Add missing include to limits.h. This is required when compiling against + glibc 2.8. Thanks to Kees Cook for the patch. Closes: #501485 + + -- Michael Biebl Wed, 08 Oct 2008 21:34:34 +0200 + +libnl (1.1-2) unstable; urgency=low + + * debian/libnl-doc.doc-base + - Register the API documentation with doc-base. + * debian/control + - Add Suggests: doc-base to libnl-doc. + + -- Michael Biebl Wed, 05 Mar 2008 00:42:54 +0100 + +libnl (1.1-1) unstable; urgency=low + + * New stable upstream release. + * debian/patches/01-ip_mg_alg_internal_only.patch + - Removed, merged upstream. + * debian/control + - Rename binary package libnl1-pre8 to libnl1. + - [libnl1] Add Conflicts/Replaces: libnl1-pre8. + - [libnl-dev] Change Depends to libnl1. + * Rename debian/libnl1-pre8.install to debian/libnl1.install + * debian/copyright + - Minor updates and additions. + + -- Michael Biebl Thu, 10 Jan 2008 16:58:12 +0100 + +libnl (1.0~pre8-1) unstable; urgency=low + + * New upstream release. Closes: #456175 + * debian/control + - Bump Standards-Version to 3.7.3. No further changes required. + - The Vcs-* fields are now officially supported, so remove the XS- prefix. + - Rename binary package libnl1-pre6 to libnl1-pre8. + - [libnl1-pre8] Add Conflicts/Replaces: libnl1-pre6. The two versions are + not coinstallable. + - [libnl-dev] Change Depends to libnl1-pre8. + * Rename debian/libnl1-pre6.install to debian/libnl1-pre8.install. + * debian/patches/10-amd64-linux-types.patch + - Removed, merged upstream. + * debian/patches/01-ip_mg_alg_internal_only.patch + - Pull a fix from upstream. The header linux/ip_mp_alg.h is no longer part + of the linux kernel headers (i.e. linux-libc-dev) so remove it from + netlink/netlink.h. + + -- Michael Biebl Thu, 20 Dec 2007 07:45:03 +0100 + +libnl (1.0~pre6-6) unstable; urgency=low + + * debian/control + - Use the new "Homepage:" field to specify the upstream URL. + - Replace deprecated ${Source-Version} substvar with ${binary:Version}. + - Change Build-Depends: gs-gpl | gs-esp to Build-Depends: ghostscript. + + -- Michael Biebl Mon, 22 Oct 2007 07:15:29 +0200 + +libnl (1.0~pre6-5) unstable; urgency=low + + * debian/control + - Add XS-Vcs-* fields. + - Replace Build-Depends: tetex-bin with texlive-latex-base. teTeX is now + gone, superseded by texlive. + - Add Build-Depends: graphviz, gs-gpl | gs-esp. + The "dot" program is needed for generating the diagram image and "gs" + for the ps to png conversion. + + -- Michael Biebl Sun, 15 Apr 2007 15:45:48 +0200 + +libnl (1.0~pre6-4) unstable; urgency=medium + + * Autobuilders do not distinguish between build-arch and build-indep, they + simply run build. So we have to move doxygen and tetex-bin from + Build-Depends-Indep to Build-Depends. Closes: #408719 + * Urgency medium, as it fixes a FTBFS bug. + + -- Michael Biebl Fri, 12 Jan 2007 11:23:52 +0100 + +libnl (1.0~pre6-3) unstable; urgency=low + + * Build and package the API documentation. Closes: #406497 + * debian/control + - Add Build-Depends-Indep on doxygen and tetex-bin (dvips). + - Add new package libnl-doc. + - Add a "Suggests: libnl-doc" to libnl-dev. + * debian/rules + - Call "make gendoc" to build the API documentation. + * debian/libnl-doc.install + - Added. List the files that should be installed. + + -- Michael Biebl Fri, 12 Jan 2007 10:30:40 +0100 + +libnl (1.0~pre6-2) unstable; urgency=low + + * Update maintainer email address to biebl@debian.org. + + -- Michael Biebl Thu, 19 Oct 2006 20:16:09 +0200 + +libnl (1.0~pre6-1) unstable; urgency=low + + * New upstream release. + * Removed 20-autoconf-dirs.patch, merged upstream. + * Updated debian/copyright, libnl is now licensed under the LGPL 2.1. + * Updated debian/watch. + + -- Michael Biebl Fri, 18 Aug 2006 00:40:34 +0200 + +libnl (1.0~pre6~svn30-1) unstable; urgency=low + + * Updated to svn revision 30. + * Bumped Standards-Version to 3.7.2, no further changes required. + * Now that dak officially supports ~ in the version number, let's make use + of it. + * Some install directories were not set correctly, 20-autoconf-dirs.patch + fixes that. + + -- Michael Biebl Thu, 10 Aug 2006 19:51:42 +0200 + +libnl (0.99+1.0.svn21-4) unstable; urgency=low + + * Do not create bogus /usr/lib/pkg-config directory. Closes: #364601 + + -- Michael Biebl Mon, 24 Apr 2006 15:40:23 +0200 + +libnl (0.99+1.0.svn21-3) unstable; urgency=low + + * Include simple-patchsys.mk in debian/rules. + * Merged debian/patches/10-amd64-linux-types.patch from Ubuntu which fixes + the FTBFS error on AMD64. Closes: #358887 + Thanks to Scott James Remnant for this patch. + + -- Michael Biebl Sat, 1 Apr 2006 04:52:13 +0200 + +libnl (0.99+1.0.svn21-2) unstable; urgency=low + + * Initial upload to unstable. + * Renamed libnl1 to libnl1-pre6 to match the currently used so-name. + Otherwise dependent packages like NM will break on upgrades of libnl. + + -- Michael Biebl Tue, 7 Mar 2006 21:22:09 +0100 + +libnl (0.99+1.0.svn21-1) experimental; urgency=low + + * Initial release. Closes: #286847 + + -- Michael Biebl Tue, 21 Feb 2006 18:36:35 +0100 diff --git a/src/libnl3/debian/compat b/src/libnl3/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/src/libnl3/debian/compat @@ -0,0 +1 @@ +9 diff --git a/src/libnl3/debian/control b/src/libnl3/debian/control new file mode 100644 index 000000000000..ba5062607bc1 --- /dev/null +++ b/src/libnl3/debian/control @@ -0,0 +1,245 @@ +Source: libnl3 +Section: net +Priority: optional +Maintainer: Heiko Stuebner +Build-Depends: debhelper (>= 9), dh-exec (>= 0.3), cdbs (>= 0.4.93~), bison, flex, + automake, autoconf, dh-autoreconf, linux-libc-dev (>= 3.2.41), pkg-config +Standards-Version: 3.9.6 +Homepage: http://www.infradead.org/~tgr/libnl/ +#Vcs-Git: https://github.com/thom311/libnl/ +#Vcs-Browser: https://github.com/thom311/libnl/ + +Package: libnl-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + +Package: libnl-cli-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), libnl-genl-3-200 (= ${binary:Version}), libnl-nf-3-200 (= ${binary:Version}), libnl-route-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - cli helpers + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + Library for cli helpers in libnl-utils. + +Package: libnl-utils +Architecture: linux-any +Section: libs +Depends: libnl-cli-3-200 (= ${binary:Version}), libnl-idiag-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Description: Utilities for dealing with netlink sockets + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + These utilities help dealing with netlink sockets. + +Package: libnl-genl-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - generic netlink + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + API to the generic netlink protocol, an extended version of the netlink + protocol. + +Package: libnl-idiag-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - inetdiag interface + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + API to the inetdiag netlink protocol, handling inetdiag requests + +Package: libnl-nf-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), libnl-route-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - netfilter interface + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + API to netlink based netfilter configuration and monitoring interfaces. + +Package: libnl-route-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - route interface + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + API to the configuration interfaces of the NETLINK_ROUTE family. + +Package: libnl-xfrm-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - package transformations + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + API to netlink based package transformations (such as encrypting + their payloads). + +Package: libnl-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends} +Conflicts: libnl-dev, libnl2-dev +Breaks: libnl3-dev +Replaces: libnl3-dev +Multi-Arch: same +Description: development library and headers for libnl-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the headers needed by all libraries and the files + that are needed to build applications using libnl3. + +Package: libnl-cli-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-genl-3-dev (= ${binary:Version}), libnl-nf-3-dev (= ${binary:Version}), libnl-route-3-dev (= ${binary:Version}), libnl-cli-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-cli-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-cli-3. + +Package: libnl-genl-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-genl-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-genl-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-genl-3. + +Package: libnl-idiag-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-idiag-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-genl-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-idiag-3. + +Package: libnl-nf-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-route-3-dev (= ${binary:Version}), libnl-nf-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-nf-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-nf-3. + +Package: libnl-route-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-route-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-route-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-route-3. + +Package: libnl-xfrm-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-xfrm-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-xfrm-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-xfrm-3. + +Package: libnl-3-200-dbg +Architecture: linux-any +Section: debug +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends} +Priority: extra +Description: debug symbols for libnl3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains unstripped shared libraries. It is provided primarily + to provide a backtrace with names in a debugger, this makes it somewhat easier + to interpret core dumps. The libraries are installed in /usr/lib/debug and + are automatically used by gdb. + +Package: libnl-3-200-udeb +Architecture: linux-any +XC-Package-Type: udeb +Section: debian-installer +Depends: ${misc:Depends}, ${shlibs:Depends} +Description: library for dealing with netlink sockets + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package is a udeb. It's only useful inside of debian-installer. + +Package: libnl-genl-3-200-udeb +Architecture: linux-any +XC-Package-Type: udeb +Section: debian-installer +Depends: libnl-3-200-udeb (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Description: library for dealing with netlink sockets - generic netlink + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package is a udeb. It's only useful inside of debian-installer. diff --git a/src/libnl3/debian/copyright b/src/libnl3/debian/copyright new file mode 100644 index 000000000000..07457363bf67 --- /dev/null +++ b/src/libnl3/debian/copyright @@ -0,0 +1,160 @@ +This package was debianized by Tamer Ahmed on +Tue, 31 Decn 2019 12:00:46 +0000. +The packaging is based on Heiko Stuebner's original packaging +of libnl1. + +It was downloaded from https://github.com/thom311/libnl/releases + +Upstream Author: + Thomas Graf + + +Copyright: + +lib/route/addr.c +include/netlink/route/addr.h + + Copyright (c) Thomas Graf + Baruch Even + + +lib/route/cls/u32.c +lib/route/cls/fw.c +lib/route/sch/htb.c +include/netlink/route/cls/fw.h +include/netlink/route/sch/htb.h + + Copyright (c) Thomas Graf + Copyright (c) Petr Gotthard + Copyright (c) Siemens AG Oesterreich + + + +lib/netfilter/log_msg.c +lib/netfilter/ct.c +include/netlink/netfilter/log_msg.h +include/netlink/netfilter/log.h +lib/netfilter/log_obj.c + + Copyright (c) Thomas Graf + Copyright (c) Philip Craig + Copyright (c) Patrick McHardy + Copyright (c) Secure Computing Corporation + + + +include/netlink/netfilter/queue_msg.h +lib/netfilter/queue_msg_obj.c +lib/netfilter/queue_msg.c +lib/netfilter/queue.c +lib/netfilter/netfilter.c +lib/netfilter/queue_obj.c +include/netlink/netfilter/netfilter.h +include/netlink/netfilter/queue.h +src/nf-queue.c + + Copyright (c) Patrick McHardy + + + +include/netlink/xfrm/selector.h +include/netlink/xfrm/sa.h +include/netlink/xfrm/ae.h +include/netlink/xfrm/sp.h +include/netlink/xfrm/template.h +include/netlink/xfrm/lifetime.h +lib/xfrm/sa.c +lib/xfrm/template.c +lib/xfrm/ae.c +lib/xfrm/sp.c +lib/xfrm/selector.c +lib/xfrm/lifetime.c + + Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + + +All other *.c and *.h files not mentioned above are copyright of: + + Copyright (c) 2003-2006 Thomas Graf + + +License: + +src/nl-addr-add.c +src/nl-addr-list.c +src/nl-cls-add.c +src/cls/utils.c +src/cls/cgroup.c +src/cls/utils.h +src/cls/basic.c +src/nl-addr-delete.c: + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation version 2 of the License. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + +On Debian GNU/Linux systems, the complete text of the GNU General +Public License can be found in /usr/share/common-licenses/GPL-2 + + +include/netlink/xfrm/selector.h +include/netlink/xfrm/sa.h +include/netlink/xfrm/ae.h +include/netlink/xfrm/sp.h +include/netlink/xfrm/template.h +include/netlink/xfrm/lifetime.h +lib/xfrm/sa.c +lib/xfrm/template.c +lib/xfrm/ae.c +lib/xfrm/sp.c +lib/xfrm/selector.c +lib/xfrm/lifetime.c + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the + distribution. + + Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +All other *.c and *.h files not mentioned above: + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation version 2.1 of the License. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + +On Debian GNU/Linux systems, the complete text of the GNU Lesser General +Public License can be found in /usr/share/common-licenses/LGPL-2.1 + diff --git a/src/libnl3/debian/gbp.conf b/src/libnl3/debian/gbp.conf new file mode 100644 index 000000000000..a504bacc7748 --- /dev/null +++ b/src/libnl3/debian/gbp.conf @@ -0,0 +1,16 @@ +# Configuration file for git-buildpackage and friends + +[DEFAULT] +# the default build command: +#builder = debuild -i -I +# the default clean command: +#cleaner = debuild clean +# the default branch for upstream sources: +upstream-branch = upstream-dist +# the default branch for the debian patch: +#debian-branch = master +# the default tag formats used: +#upstream-tag = upstream/%(version)s +#debian-tag = debian/%(version)s +# use pristine-tar: +pristine-tar = true diff --git a/src/libnl3/debian/libnl-3-200-udeb.install b/src/libnl3/debian/libnl-3-200-udeb.install new file mode 100644 index 000000000000..4b3a77ce011d --- /dev/null +++ b/src/libnl3/debian/libnl-3-200-udeb.install @@ -0,0 +1 @@ +usr/lib/*/libnl-3.so.* lib diff --git a/src/libnl3/debian/libnl-3-200.install b/src/libnl3/debian/libnl-3-200.install new file mode 100755 index 000000000000..0a6aa3850b2c --- /dev/null +++ b/src/libnl3/debian/libnl-3-200.install @@ -0,0 +1,3 @@ +#!/usr/bin/dh-exec +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-3*.so.* lib/${DEB_HOST_MULTIARCH}/ +debian/tmp/etc/libnl/* etc/libnl-3 diff --git a/src/libnl3/debian/libnl-3-200.symbols b/src/libnl3/debian/libnl-3-200.symbols new file mode 100644 index 000000000000..119e0554920f --- /dev/null +++ b/src/libnl3/debian/libnl-3-200.symbols @@ -0,0 +1,661 @@ +libnl-3.so.200 libnl-3-200 #MINVER# + __flags2str@Base 3.5.0-1 + __flags2str@libnl_3 3.5.0-1 + __list_str2type@Base 3.5.0-1 + __list_str2type@libnl_3 3.5.0-1 + __list_type2str@Base 3.5.0-1 + __list_type2str@libnl_3 3.5.0-1 + __nl_cache_mngt_require@Base 3.5.0-1 + __nl_cache_mngt_require@libnl_3 3.5.0-1 + __nl_cache_ops_lookup@Base 3.5.0-1 + __nl_read_num_str_file@Base 3.5.0-1 + __nl_read_num_str_file@libnl_3 3.5.0-1 + __str2flags@Base 3.5.0-1 + __str2flags@libnl_3 3.5.0-1 + __str2type@Base 3.5.0-1 + __str2type@libnl_3 3.5.0-1 + __trans_list_add@Base 3.5.0-1 + __trans_list_add@libnl_3 3.5.0-1 + __trans_list_clear@Base 3.5.0-1 + __trans_list_clear@libnl_3 3.5.0-1 + __type2str@Base 3.5.0-1 + __type2str@libnl_3 3.5.0-1 + _nl_socket_generate_local_port_no_release@Base 3.5.0-1 + _nl_socket_is_local_port_unspecified@Base 3.5.0-1 + _nl_socket_set_local_port_no_release@Base 3.5.0-1 + _nl_socket_used_ports_release_all@Base 3.5.0-1 + _nl_socket_used_ports_set@Base 3.5.0-1 + dump_from_ops@Base 3.5.0-1 + libnl_3@libnl_3 3.5.0-1 + libnl_3_2_26@libnl_3_2_26 3.5.0-1 + libnl_3_2_27@libnl_3_2_27 3.5.0-1 + libnl_3_2_28@libnl_3_2_28 3.5.0-1 + libnl_3_2_29@libnl_3_2_29 3.5.0-1 + libnl_3_5@libnl_3_5 3.5.0-1 + nl_addr2str@Base 3.5.0-1 + nl_addr2str@libnl_3 3.5.0-1 + nl_addr_alloc@Base 3.5.0-1 + nl_addr_alloc@libnl_3 3.5.0-1 + nl_addr_alloc_attr@Base 3.5.0-1 + nl_addr_alloc_attr@libnl_3 3.5.0-1 + nl_addr_build@Base 3.5.0-1 + nl_addr_build@libnl_3 3.5.0-1 + nl_addr_clone@Base 3.5.0-1 + nl_addr_clone@libnl_3 3.5.0-1 + nl_addr_cmp@Base 3.5.0-1 + nl_addr_cmp@libnl_3 3.5.0-1 + nl_addr_cmp_prefix@Base 3.5.0-1 + nl_addr_cmp_prefix@libnl_3 3.5.0-1 + nl_addr_fill_sockaddr@Base 3.5.0-1 + nl_addr_fill_sockaddr@libnl_3 3.5.0-1 + nl_addr_get@Base 3.5.0-1 + nl_addr_get@libnl_3 3.5.0-1 + nl_addr_get_binary_addr@Base 3.5.0-1 + nl_addr_get_binary_addr@libnl_3 3.5.0-1 + nl_addr_get_family@Base 3.5.0-1 + nl_addr_get_family@libnl_3 3.5.0-1 + nl_addr_get_len@Base 3.5.0-1 + nl_addr_get_len@libnl_3 3.5.0-1 + nl_addr_get_prefixlen@Base 3.5.0-1 + nl_addr_get_prefixlen@libnl_3 3.5.0-1 + nl_addr_guess_family@Base 3.5.0-1 + nl_addr_guess_family@libnl_3 3.5.0-1 + nl_addr_info@Base 3.5.0-1 + nl_addr_info@libnl_3 3.5.0-1 + nl_addr_iszero@Base 3.5.0-1 + nl_addr_iszero@libnl_3 3.5.0-1 + nl_addr_parse@Base 3.5.0-1 + nl_addr_parse@libnl_3 3.5.0-1 + nl_addr_put@Base 3.5.0-1 + nl_addr_put@libnl_3 3.5.0-1 + nl_addr_resolve@Base 3.5.0-1 + nl_addr_resolve@libnl_3 3.5.0-1 + nl_addr_set_binary_addr@Base 3.5.0-1 + nl_addr_set_binary_addr@libnl_3 3.5.0-1 + nl_addr_set_family@Base 3.5.0-1 + nl_addr_set_family@libnl_3 3.5.0-1 + nl_addr_set_prefixlen@Base 3.5.0-1 + nl_addr_set_prefixlen@libnl_3 3.5.0-1 + nl_addr_shared@Base 3.5.0-1 + nl_addr_shared@libnl_3 3.5.0-1 + nl_addr_valid@Base 3.5.0-1 + nl_addr_valid@libnl_3 3.5.0-1 + nl_af2str@Base 3.5.0-1 + nl_af2str@libnl_3 3.5.0-1 + nl_auto_complete@Base 3.5.0-1 + nl_auto_complete@libnl_3 3.5.0-1 + nl_cache_add@Base 3.5.0-1 + nl_cache_add@libnl_3 3.5.0-1 + nl_cache_alloc@Base 3.5.0-1 + nl_cache_alloc@libnl_3 3.5.0-1 + nl_cache_alloc_and_fill@Base 3.5.0-1 + nl_cache_alloc_and_fill@libnl_3 3.5.0-1 + nl_cache_alloc_name@Base 3.5.0-1 + nl_cache_alloc_name@libnl_3 3.5.0-1 + nl_cache_clear@Base 3.5.0-1 + nl_cache_clear@libnl_3 3.5.0-1 + nl_cache_clone@Base 3.5.0-1 + nl_cache_clone@libnl_3 3.5.0-1 + nl_cache_dump@Base 3.5.0-1 + nl_cache_dump@libnl_3 3.5.0-1 + nl_cache_dump_filter@Base 3.5.0-1 + nl_cache_dump_filter@libnl_3 3.5.0-1 + nl_cache_find@Base 3.5.0-1 + nl_cache_find@libnl_3 3.5.0-1 + nl_cache_foreach@Base 3.5.0-1 + nl_cache_foreach@libnl_3 3.5.0-1 + nl_cache_foreach_filter@Base 3.5.0-1 + nl_cache_foreach_filter@libnl_3 3.5.0-1 + nl_cache_free@Base 3.5.0-1 + nl_cache_free@libnl_3 3.5.0-1 + nl_cache_get@Base 3.5.0-1 + nl_cache_get@libnl_3 3.5.0-1 + nl_cache_get_first@Base 3.5.0-1 + nl_cache_get_first@libnl_3 3.5.0-1 + nl_cache_get_last@Base 3.5.0-1 + nl_cache_get_last@libnl_3 3.5.0-1 + nl_cache_get_next@Base 3.5.0-1 + nl_cache_get_next@libnl_3 3.5.0-1 + nl_cache_get_ops@Base 3.5.0-1 + nl_cache_get_ops@libnl_3 3.5.0-1 + nl_cache_get_prev@Base 3.5.0-1 + nl_cache_get_prev@libnl_3 3.5.0-1 + nl_cache_include@Base 3.5.0-1 + nl_cache_include@libnl_3 3.5.0-1 + nl_cache_include_v2@libnl_3_2_29 3.5.0-1 + nl_cache_is_empty@Base 3.5.0-1 + nl_cache_is_empty@libnl_3 3.5.0-1 + nl_cache_mark_all@Base 3.5.0-1 + nl_cache_mark_all@libnl_3 3.5.0-1 + nl_cache_mngr_add@Base 3.5.0-1 + nl_cache_mngr_add@libnl_3 3.5.0-1 + nl_cache_mngr_add_cache@Base 3.5.0-1 + nl_cache_mngr_add_cache@libnl_3 3.5.0-1 + nl_cache_mngr_add_cache_v2@libnl_3_2_29 3.5.0-1 + nl_cache_mngr_alloc@Base 3.5.0-1 + nl_cache_mngr_alloc@libnl_3 3.5.0-1 + nl_cache_mngr_data_ready@Base 3.5.0-1 + nl_cache_mngr_data_ready@libnl_3 3.5.0-1 + nl_cache_mngr_free@Base 3.5.0-1 + nl_cache_mngr_free@libnl_3 3.5.0-1 + nl_cache_mngr_get_fd@Base 3.5.0-1 + nl_cache_mngr_get_fd@libnl_3 3.5.0-1 + nl_cache_mngr_info@Base 3.5.0-1 + nl_cache_mngr_info@libnl_3 3.5.0-1 + nl_cache_mngr_poll@Base 3.5.0-1 + nl_cache_mngr_poll@libnl_3 3.5.0-1 + nl_cache_mngt_provide@Base 3.5.0-1 + nl_cache_mngt_provide@libnl_3 3.5.0-1 + nl_cache_mngt_register@Base 3.5.0-1 + nl_cache_mngt_register@libnl_3 3.5.0-1 + nl_cache_mngt_require@Base 3.5.0-1 + nl_cache_mngt_require@libnl_3 3.5.0-1 + nl_cache_mngt_require_safe@Base 3.5.0-1 + nl_cache_mngt_require_safe@libnl_3 3.5.0-1 + nl_cache_mngt_unprovide@Base 3.5.0-1 + nl_cache_mngt_unprovide@libnl_3 3.5.0-1 + nl_cache_mngt_unregister@Base 3.5.0-1 + nl_cache_mngt_unregister@libnl_3 3.5.0-1 + nl_cache_move@Base 3.5.0-1 + nl_cache_move@libnl_3 3.5.0-1 + nl_cache_nitems@Base 3.5.0-1 + nl_cache_nitems@libnl_3 3.5.0-1 + nl_cache_nitems_filter@Base 3.5.0-1 + nl_cache_nitems_filter@libnl_3 3.5.0-1 + nl_cache_ops_associate@Base 3.5.0-1 + nl_cache_ops_associate@libnl_3 3.5.0-1 + nl_cache_ops_associate_safe@Base 3.5.0-1 + nl_cache_ops_associate_safe@libnl_3 3.5.0-1 + nl_cache_ops_foreach@Base 3.5.0-1 + nl_cache_ops_foreach@libnl_3 3.5.0-1 + nl_cache_ops_get@Base 3.5.0-1 + nl_cache_ops_get@libnl_3 3.5.0-1 + nl_cache_ops_lookup@Base 3.5.0-1 + nl_cache_ops_lookup@libnl_3 3.5.0-1 + nl_cache_ops_lookup_safe@Base 3.5.0-1 + nl_cache_ops_lookup_safe@libnl_3 3.5.0-1 + nl_cache_ops_put@Base 3.5.0-1 + nl_cache_ops_put@libnl_3 3.5.0-1 + nl_cache_ops_set_flags@Base 3.5.0-1 + nl_cache_ops_set_flags@libnl_3 3.5.0-1 + nl_cache_parse@Base 3.5.0-1 + nl_cache_parse@libnl_3 3.5.0-1 + nl_cache_parse_and_add@Base 3.5.0-1 + nl_cache_parse_and_add@libnl_3 3.5.0-1 + nl_cache_pickup@Base 3.5.0-1 + nl_cache_pickup@libnl_3 3.5.0-1 + nl_cache_pickup_checkdup@Base 3.5.0-1 + nl_cache_pickup_checkdup@libnl_3 3.5.0-1 + nl_cache_put@Base 3.5.0-1 + nl_cache_put@libnl_3 3.5.0-1 + nl_cache_refill@Base 3.5.0-1 + nl_cache_refill@libnl_3 3.5.0-1 + nl_cache_remove@Base 3.5.0-1 + nl_cache_remove@libnl_3 3.5.0-1 + nl_cache_resync@Base 3.5.0-1 + nl_cache_resync@libnl_3 3.5.0-1 + nl_cache_search@Base 3.5.0-1 + nl_cache_search@libnl_3 3.5.0-1 + nl_cache_set_arg1@Base 3.5.0-1 + nl_cache_set_arg1@libnl_3 3.5.0-1 + nl_cache_set_arg2@Base 3.5.0-1 + nl_cache_set_arg2@libnl_3 3.5.0-1 + nl_cache_set_flags@Base 3.5.0-1 + nl_cache_set_flags@libnl_3 3.5.0-1 + nl_cache_subset@Base 3.5.0-1 + nl_cache_subset@libnl_3 3.5.0-1 + nl_cancel_down_bits@Base 3.5.0-1 + nl_cancel_down_bits@libnl_3 3.5.0-1 + nl_cancel_down_bytes@Base 3.5.0-1 + nl_cancel_down_bytes@libnl_3 3.5.0-1 + nl_cancel_down_us@Base 3.5.0-1 + nl_cancel_down_us@libnl_3 3.5.0-1 + nl_cb_active_type@Base 3.5.0-1 + nl_cb_active_type@libnl_3 3.5.0-1 + nl_cb_alloc@Base 3.5.0-1 + nl_cb_alloc@libnl_3 3.5.0-1 + nl_cb_clone@Base 3.5.0-1 + nl_cb_clone@libnl_3 3.5.0-1 + nl_cb_err@Base 3.5.0-1 + nl_cb_err@libnl_3 3.5.0-1 + nl_cb_get@Base 3.5.0-1 + nl_cb_get@libnl_3 3.5.0-1 + nl_cb_overwrite_recv@Base 3.5.0-1 + nl_cb_overwrite_recv@libnl_3 3.5.0-1 + nl_cb_overwrite_recvmsgs@Base 3.5.0-1 + nl_cb_overwrite_recvmsgs@libnl_3 3.5.0-1 + nl_cb_overwrite_send@Base 3.5.0-1 + nl_cb_overwrite_send@libnl_3 3.5.0-1 + nl_cb_put@Base 3.5.0-1 + nl_cb_put@libnl_3 3.5.0-1 + nl_cb_set@Base 3.5.0-1 + nl_cb_set@libnl_3 3.5.0-1 + nl_cb_set_all@Base 3.5.0-1 + nl_cb_set_all@libnl_3 3.5.0-1 + nl_close@Base 3.5.0-1 + nl_close@libnl_3 3.5.0-1 + nl_complete_msg@Base 3.5.0-1 + nl_complete_msg@libnl_3 3.5.0-1 + nl_connect@Base 3.5.0-1 + nl_connect@libnl_3 3.5.0-1 + nl_data_alloc@Base 3.5.0-1 + nl_data_alloc@libnl_3 3.5.0-1 + nl_data_alloc_attr@Base 3.5.0-1 + nl_data_alloc_attr@libnl_3 3.5.0-1 + nl_data_append@Base 3.5.0-1 + nl_data_append@libnl_3 3.5.0-1 + nl_data_clone@Base 3.5.0-1 + nl_data_clone@libnl_3 3.5.0-1 + nl_data_cmp@Base 3.5.0-1 + nl_data_cmp@libnl_3 3.5.0-1 + nl_data_free@Base 3.5.0-1 + nl_data_free@libnl_3 3.5.0-1 + nl_data_get@Base 3.5.0-1 + nl_data_get@libnl_3 3.5.0-1 + nl_data_get_size@Base 3.5.0-1 + nl_data_get_size@libnl_3 3.5.0-1 + nl_debug@Base 3.5.0-1 + nl_debug@libnl_3 3.5.0-1 + nl_debug_dp@Base 3.5.0-1 + nl_debug_dp@libnl_3 3.5.0-1 + nl_dump@Base 3.5.0-1 + nl_dump@libnl_3 3.5.0-1 + nl_dump_line@Base 3.5.0-1 + nl_dump_line@libnl_3 3.5.0-1 + nl_ether_proto2str@Base 3.5.0-1 + nl_ether_proto2str@libnl_3 3.5.0-1 + nl_get_psched_hz@Base 3.5.0-1 + nl_get_psched_hz@libnl_3 3.5.0-1 + nl_get_user_hz@Base 3.5.0-1 + nl_get_user_hz@libnl_3 3.5.0-1 + nl_geterror@Base 3.5.0-1 + nl_geterror@libnl_3 3.5.0-1 + nl_has_capability@Base 3.5.0-1 + nl_has_capability@libnl_3 3.5.0-1 + nl_hash@Base 3.5.0-1 + nl_hash@libnl_3 3.5.0-1 + nl_hash_any@Base 3.5.0-1 + nl_hash_any@libnl_3 3.5.0-1 + nl_hash_table_add@Base 3.5.0-1 + nl_hash_table_add@libnl_3 3.5.0-1 + nl_hash_table_alloc@Base 3.5.0-1 + nl_hash_table_alloc@libnl_3 3.5.0-1 + nl_hash_table_del@Base 3.5.0-1 + nl_hash_table_del@libnl_3 3.5.0-1 + nl_hash_table_free@Base 3.5.0-1 + nl_hash_table_free@libnl_3 3.5.0-1 + nl_hash_table_lookup@Base 3.5.0-1 + nl_hash_table_lookup@libnl_3 3.5.0-1 + nl_ip_proto2str@Base 3.5.0-1 + nl_ip_proto2str@libnl_3 3.5.0-1 + nl_join_groups@Base 3.5.0-1 + nl_join_groups@libnl_3 3.5.0-1 + nl_llproto2str@Base 3.5.0-1 + nl_llproto2str@libnl_3 3.5.0-1 + nl_msec2str@Base 3.5.0-1 + nl_msec2str@libnl_3 3.5.0-1 + nl_msg_dump@Base 3.5.0-1 + nl_msg_dump@libnl_3 3.5.0-1 + nl_msg_parse@Base 3.5.0-1 + nl_msg_parse@libnl_3 3.5.0-1 + nl_msgtype_lookup@Base 3.5.0-1 + nl_msgtype_lookup@libnl_3 3.5.0-1 + nl_new_line@Base 3.5.0-1 + nl_new_line@libnl_3 3.5.0-1 + nl_nlfamily2str@Base 3.5.0-1 + nl_nlfamily2str@libnl_3 3.5.0-1 + nl_nlmsg_flags2str@Base 3.5.0-1 + nl_nlmsg_flags2str@libnl_3 3.5.0-1 + nl_nlmsgtype2str@Base 3.5.0-1 + nl_nlmsgtype2str@libnl_3 3.5.0-1 + nl_object_alloc@Base 3.5.0-1 + nl_object_alloc@libnl_3 3.5.0-1 + nl_object_alloc_name@Base 3.5.0-1 + nl_object_alloc_name@libnl_3 3.5.0-1 + nl_object_attr_list@Base 3.5.0-1 + nl_object_attr_list@libnl_3 3.5.0-1 + nl_object_attrs2str@Base 3.5.0-1 + nl_object_attrs2str@libnl_3 3.5.0-1 + nl_object_clone@Base 3.5.0-1 + nl_object_clone@libnl_3 3.5.0-1 + nl_object_diff64@libnl_3_2_28 3.5.0-1 + nl_object_diff@Base 3.5.0-1 + nl_object_diff@libnl_3 3.5.0-1 + nl_object_dump@Base 3.5.0-1 + nl_object_dump@libnl_3 3.5.0-1 + nl_object_dump_buf@Base 3.5.0-1 + nl_object_dump_buf@libnl_3 3.5.0-1 + nl_object_free@Base 3.5.0-1 + nl_object_free@libnl_3 3.5.0-1 + nl_object_get@Base 3.5.0-1 + nl_object_get@libnl_3 3.5.0-1 + nl_object_get_cache@Base 3.5.0-1 + nl_object_get_cache@libnl_3 3.5.0-1 + nl_object_get_id_attrs@Base 3.5.0-1 + nl_object_get_id_attrs@libnl_3 3.5.0-1 + nl_object_get_msgtype@Base 3.5.0-1 + nl_object_get_msgtype@libnl_3 3.5.0-1 + nl_object_get_ops@Base 3.5.0-1 + nl_object_get_ops@libnl_3 3.5.0-1 + nl_object_get_refcnt@Base 3.5.0-1 + nl_object_get_refcnt@libnl_3 3.5.0-1 + nl_object_get_type@Base 3.5.0-1 + nl_object_get_type@libnl_3 3.5.0-1 + nl_object_identical@Base 3.5.0-1 + nl_object_identical@libnl_3 3.5.0-1 + nl_object_is_marked@Base 3.5.0-1 + nl_object_is_marked@libnl_3 3.5.0-1 + nl_object_keygen@Base 3.5.0-1 + nl_object_keygen@libnl_3 3.5.0-1 + nl_object_mark@Base 3.5.0-1 + nl_object_mark@libnl_3 3.5.0-1 + nl_object_match_filter@Base 3.5.0-1 + nl_object_match_filter@libnl_3 3.5.0-1 + nl_object_put@Base 3.5.0-1 + nl_object_put@libnl_3 3.5.0-1 + nl_object_shared@Base 3.5.0-1 + nl_object_shared@libnl_3 3.5.0-1 + nl_object_unmark@Base 3.5.0-1 + nl_object_unmark@libnl_3 3.5.0-1 + nl_object_update@Base 3.5.0-1 + nl_object_update@libnl_3 3.5.0-1 + nl_perror@Base 3.5.0-1 + nl_perror@libnl_3 3.5.0-1 + nl_pickup@Base 3.5.0-1 + nl_pickup@libnl_3 3.5.0-1 + nl_pickup_keep_syserr@Base 3.5.0-1 + nl_pickup_keep_syserr@libnl_3 3.5.0-1 + nl_prob2int@Base 3.5.0-1 + nl_prob2int@libnl_3 3.5.0-1 + nl_rate2str@Base 3.5.0-1 + nl_rate2str@libnl_3 3.5.0-1 + nl_recv@Base 3.5.0-1 + nl_recv@libnl_3 3.5.0-1 + nl_recvmsgs@Base 3.5.0-1 + nl_recvmsgs@libnl_3 3.5.0-1 + nl_recvmsgs_default@Base 3.5.0-1 + nl_recvmsgs_default@libnl_3 3.5.0-1 + nl_recvmsgs_report@Base 3.5.0-1 + nl_recvmsgs_report@libnl_3 3.5.0-1 + nl_send@Base 3.5.0-1 + nl_send@libnl_3 3.5.0-1 + nl_send_auto@Base 3.5.0-1 + nl_send_auto@libnl_3 3.5.0-1 + nl_send_auto_complete@Base 3.5.0-1 + nl_send_auto_complete@libnl_3 3.5.0-1 + nl_send_iovec@Base 3.5.0-1 + nl_send_iovec@libnl_3 3.5.0-1 + nl_send_simple@Base 3.5.0-1 + nl_send_simple@libnl_3 3.5.0-1 + nl_send_sync@Base 3.5.0-1 + nl_send_sync@libnl_3 3.5.0-1 + nl_sendmsg@Base 3.5.0-1 + nl_sendmsg@libnl_3 3.5.0-1 + nl_sendto@Base 3.5.0-1 + nl_sendto@libnl_3 3.5.0-1 + nl_size2int@Base 3.5.0-1 + nl_size2int@libnl_3 3.5.0-1 + nl_size2str@Base 3.5.0-1 + nl_size2str@libnl_3 3.5.0-1 + nl_socket_add_membership@Base 3.5.0-1 + nl_socket_add_membership@libnl_3 3.5.0-1 + nl_socket_add_memberships@Base 3.5.0-1 + nl_socket_add_memberships@libnl_3 3.5.0-1 + nl_socket_alloc@Base 3.5.0-1 + nl_socket_alloc@libnl_3 3.5.0-1 + nl_socket_alloc_cb@Base 3.5.0-1 + nl_socket_alloc_cb@libnl_3 3.5.0-1 + nl_socket_disable_auto_ack@Base 3.5.0-1 + nl_socket_disable_auto_ack@libnl_3 3.5.0-1 + nl_socket_disable_msg_peek@Base 3.5.0-1 + nl_socket_disable_msg_peek@libnl_3 3.5.0-1 + nl_socket_disable_seq_check@Base 3.5.0-1 + nl_socket_disable_seq_check@libnl_3 3.5.0-1 + nl_socket_drop_membership@Base 3.5.0-1 + nl_socket_drop_membership@libnl_3 3.5.0-1 + nl_socket_drop_memberships@Base 3.5.0-1 + nl_socket_drop_memberships@libnl_3 3.5.0-1 + nl_socket_enable_auto_ack@Base 3.5.0-1 + nl_socket_enable_auto_ack@libnl_3 3.5.0-1 + nl_socket_enable_msg_peek@Base 3.5.0-1 + nl_socket_enable_msg_peek@libnl_3 3.5.0-1 + nl_socket_free@Base 3.5.0-1 + nl_socket_free@libnl_3 3.5.0-1 + nl_socket_get_cb@Base 3.5.0-1 + nl_socket_get_cb@libnl_3 3.5.0-1 + nl_socket_get_fd@Base 3.5.0-1 + nl_socket_get_fd@libnl_3 3.5.0-1 + nl_socket_get_local_port@Base 3.5.0-1 + nl_socket_get_local_port@libnl_3 3.5.0-1 + nl_socket_get_msg_buf_size@Base 3.5.0-1 + nl_socket_get_msg_buf_size@libnl_3 3.5.0-1 + nl_socket_get_peer_groups@Base 3.5.0-1 + nl_socket_get_peer_groups@libnl_3 3.5.0-1 + nl_socket_get_peer_port@Base 3.5.0-1 + nl_socket_get_peer_port@libnl_3 3.5.0-1 + nl_socket_modify_cb@Base 3.5.0-1 + nl_socket_modify_cb@libnl_3 3.5.0-1 + nl_socket_modify_err_cb@Base 3.5.0-1 + nl_socket_modify_err_cb@libnl_3 3.5.0-1 + nl_socket_recv_pktinfo@Base 3.5.0-1 + nl_socket_recv_pktinfo@libnl_3 3.5.0-1 + nl_socket_set_buffer_size@Base 3.5.0-1 + nl_socket_set_buffer_size@libnl_3 3.5.0-1 + nl_socket_set_cb@Base 3.5.0-1 + nl_socket_set_cb@libnl_3 3.5.0-1 + nl_socket_set_fd@Base 3.5.0-1 + nl_socket_set_fd@libnl_3_2_26 3.5.0-1 + nl_socket_set_local_port@Base 3.5.0-1 + nl_socket_set_local_port@libnl_3 3.5.0-1 + nl_socket_set_msg_buf_size@Base 3.5.0-1 + nl_socket_set_msg_buf_size@libnl_3 3.5.0-1 + nl_socket_set_nonblocking@Base 3.5.0-1 + nl_socket_set_nonblocking@libnl_3 3.5.0-1 + nl_socket_set_passcred@Base 3.5.0-1 + nl_socket_set_passcred@libnl_3 3.5.0-1 + nl_socket_set_peer_groups@Base 3.5.0-1 + nl_socket_set_peer_groups@libnl_3 3.5.0-1 + nl_socket_set_peer_port@Base 3.5.0-1 + nl_socket_set_peer_port@libnl_3 3.5.0-1 + nl_socket_use_seq@Base 3.5.0-1 + nl_socket_use_seq@libnl_3 3.5.0-1 + nl_str2af@Base 3.5.0-1 + nl_str2af@libnl_3 3.5.0-1 + nl_str2ether_proto@Base 3.5.0-1 + nl_str2ether_proto@libnl_3 3.5.0-1 + nl_str2ip_proto@Base 3.5.0-1 + nl_str2ip_proto@libnl_3 3.5.0-1 + nl_str2llproto@Base 3.5.0-1 + nl_str2llproto@libnl_3 3.5.0-1 + nl_str2msec@Base 3.5.0-1 + nl_str2msec@libnl_3 3.5.0-1 + nl_str2nlfamily@Base 3.5.0-1 + nl_str2nlfamily@libnl_3 3.5.0-1 + nl_str2nlmsgtype@Base 3.5.0-1 + nl_str2nlmsgtype@libnl_3 3.5.0-1 + nl_strerror_l@libnl_3_2_29 3.5.0-1 + nl_syserr2nlerr@Base 3.5.0-1 + nl_syserr2nlerr@libnl_3 3.5.0-1 + nl_ticks2us@Base 3.5.0-1 + nl_ticks2us@libnl_3 3.5.0-1 + nl_us2ticks@Base 3.5.0-1 + nl_us2ticks@libnl_3 3.5.0-1 + nl_ver_maj@Base 3.5.0-1 + nl_ver_maj@libnl_3 3.5.0-1 + nl_ver_mic@Base 3.5.0-1 + nl_ver_mic@libnl_3 3.5.0-1 + nl_ver_min@Base 3.5.0-1 + nl_ver_min@libnl_3 3.5.0-1 + nl_ver_num@Base 3.5.0-1 + nl_ver_num@libnl_3 3.5.0-1 + nl_wait_for_ack@Base 3.5.0-1 + nl_wait_for_ack@libnl_3 3.5.0-1 + nla_attr_size@Base 3.5.0-1 + nla_attr_size@libnl_3 3.5.0-1 + nla_data@Base 3.5.0-1 + nla_data@libnl_3 3.5.0-1 + nla_find@Base 3.5.0-1 + nla_find@libnl_3 3.5.0-1 + nla_get_flag@Base 3.5.0-1 + nla_get_flag@libnl_3 3.5.0-1 + nla_get_msecs@Base 3.5.0-1 + nla_get_msecs@libnl_3 3.5.0-1 + nla_get_s16@Base 3.5.0-1 + nla_get_s16@libnl_3_2_27 3.5.0-1 + nla_get_s32@Base 3.5.0-1 + nla_get_s32@libnl_3_2_27 3.5.0-1 + nla_get_s64@Base 3.5.0-1 + nla_get_s64@libnl_3_2_27 3.5.0-1 + nla_get_s8@Base 3.5.0-1 + nla_get_s8@libnl_3_2_27 3.5.0-1 + nla_get_string@Base 3.5.0-1 + nla_get_string@libnl_3 3.5.0-1 + nla_get_u16@Base 3.5.0-1 + nla_get_u16@libnl_3 3.5.0-1 + nla_get_u32@Base 3.5.0-1 + nla_get_u32@libnl_3 3.5.0-1 + nla_get_u64@Base 3.5.0-1 + nla_get_u64@libnl_3 3.5.0-1 + nla_get_u8@Base 3.5.0-1 + nla_get_u8@libnl_3 3.5.0-1 + nla_is_nested@Base 3.5.0-1 + nla_is_nested@libnl_3 3.5.0-1 + nla_len@Base 3.5.0-1 + nla_len@libnl_3 3.5.0-1 + nla_memcmp@Base 3.5.0-1 + nla_memcmp@libnl_3 3.5.0-1 + nla_memcpy@Base 3.5.0-1 + nla_memcpy@libnl_3 3.5.0-1 + nla_nest_cancel@Base 3.5.0-1 + nla_nest_cancel@libnl_3 3.5.0-1 + nla_nest_end@Base 3.5.0-1 + nla_nest_end@libnl_3 3.5.0-1 + nla_nest_end_keep_empty@libnl_3_5 3.5.0-1 + nla_nest_start@Base 3.5.0-1 + nla_nest_start@libnl_3 3.5.0-1 + nla_next@Base 3.5.0-1 + nla_next@libnl_3 3.5.0-1 + nla_ok@Base 3.5.0-1 + nla_ok@libnl_3 3.5.0-1 + nla_padlen@Base 3.5.0-1 + nla_padlen@libnl_3 3.5.0-1 + nla_parse@Base 3.5.0-1 + nla_parse@libnl_3 3.5.0-1 + nla_parse_nested@Base 3.5.0-1 + nla_parse_nested@libnl_3 3.5.0-1 + nla_put@Base 3.5.0-1 + nla_put@libnl_3 3.5.0-1 + nla_put_addr@Base 3.5.0-1 + nla_put_addr@libnl_3 3.5.0-1 + nla_put_data@Base 3.5.0-1 + nla_put_data@libnl_3 3.5.0-1 + nla_put_flag@Base 3.5.0-1 + nla_put_flag@libnl_3 3.5.0-1 + nla_put_msecs@Base 3.5.0-1 + nla_put_msecs@libnl_3 3.5.0-1 + nla_put_nested@Base 3.5.0-1 + nla_put_nested@libnl_3 3.5.0-1 + nla_put_s16@Base 3.5.0-1 + nla_put_s16@libnl_3_2_27 3.5.0-1 + nla_put_s32@Base 3.5.0-1 + nla_put_s32@libnl_3_2_27 3.5.0-1 + nla_put_s64@Base 3.5.0-1 + nla_put_s64@libnl_3_2_27 3.5.0-1 + nla_put_s8@Base 3.5.0-1 + nla_put_s8@libnl_3_2_27 3.5.0-1 + nla_put_string@Base 3.5.0-1 + nla_put_string@libnl_3 3.5.0-1 + nla_put_u16@Base 3.5.0-1 + nla_put_u16@libnl_3 3.5.0-1 + nla_put_u32@Base 3.5.0-1 + nla_put_u32@libnl_3 3.5.0-1 + nla_put_u64@Base 3.5.0-1 + nla_put_u64@libnl_3 3.5.0-1 + nla_put_u8@Base 3.5.0-1 + nla_put_u8@libnl_3 3.5.0-1 + nla_reserve@Base 3.5.0-1 + nla_reserve@libnl_3 3.5.0-1 + nla_strcmp@Base 3.5.0-1 + nla_strcmp@libnl_3 3.5.0-1 + nla_strdup@Base 3.5.0-1 + nla_strdup@libnl_3 3.5.0-1 + nla_strlcpy@Base 3.5.0-1 + nla_strlcpy@libnl_3 3.5.0-1 + nla_total_size@Base 3.5.0-1 + nla_total_size@libnl_3 3.5.0-1 + nla_type@Base 3.5.0-1 + nla_type@libnl_3 3.5.0-1 + nla_validate@Base 3.5.0-1 + nla_validate@libnl_3 3.5.0-1 + nlmsg_alloc@Base 3.5.0-1 + nlmsg_alloc@libnl_3 3.5.0-1 + nlmsg_alloc_simple@Base 3.5.0-1 + nlmsg_alloc_simple@libnl_3 3.5.0-1 + nlmsg_alloc_size@Base 3.5.0-1 + nlmsg_alloc_size@libnl_3 3.5.0-1 + nlmsg_append@Base 3.5.0-1 + nlmsg_append@libnl_3 3.5.0-1 + nlmsg_attrdata@Base 3.5.0-1 + nlmsg_attrdata@libnl_3 3.5.0-1 + nlmsg_attrlen@Base 3.5.0-1 + nlmsg_attrlen@libnl_3 3.5.0-1 + nlmsg_convert@Base 3.5.0-1 + nlmsg_convert@libnl_3 3.5.0-1 + nlmsg_data@Base 3.5.0-1 + nlmsg_data@libnl_3 3.5.0-1 + nlmsg_datalen@Base 3.5.0-1 + nlmsg_datalen@libnl_3 3.5.0-1 + nlmsg_expand@Base 3.5.0-1 + nlmsg_expand@libnl_3 3.5.0-1 + nlmsg_find_attr@Base 3.5.0-1 + nlmsg_find_attr@libnl_3 3.5.0-1 + nlmsg_free@Base 3.5.0-1 + nlmsg_free@libnl_3 3.5.0-1 + nlmsg_get@Base 3.5.0-1 + nlmsg_get@libnl_3 3.5.0-1 + nlmsg_get_creds@Base 3.5.0-1 + nlmsg_get_creds@libnl_3 3.5.0-1 + nlmsg_get_dst@Base 3.5.0-1 + nlmsg_get_dst@libnl_3 3.5.0-1 + nlmsg_get_max_size@Base 3.5.0-1 + nlmsg_get_max_size@libnl_3 3.5.0-1 + nlmsg_get_proto@Base 3.5.0-1 + nlmsg_get_proto@libnl_3 3.5.0-1 + nlmsg_get_src@Base 3.5.0-1 + nlmsg_get_src@libnl_3 3.5.0-1 + nlmsg_hdr@Base 3.5.0-1 + nlmsg_hdr@libnl_3 3.5.0-1 + nlmsg_inherit@Base 3.5.0-1 + nlmsg_inherit@libnl_3 3.5.0-1 + nlmsg_next@Base 3.5.0-1 + nlmsg_next@libnl_3 3.5.0-1 + nlmsg_ok@Base 3.5.0-1 + nlmsg_ok@libnl_3 3.5.0-1 + nlmsg_padlen@Base 3.5.0-1 + nlmsg_padlen@libnl_3 3.5.0-1 + nlmsg_parse@Base 3.5.0-1 + nlmsg_parse@libnl_3 3.5.0-1 + nlmsg_put@Base 3.5.0-1 + nlmsg_put@libnl_3 3.5.0-1 + nlmsg_reserve@Base 3.5.0-1 + nlmsg_reserve@libnl_3 3.5.0-1 + nlmsg_set_creds@Base 3.5.0-1 + nlmsg_set_creds@libnl_3 3.5.0-1 + nlmsg_set_default_size@Base 3.5.0-1 + nlmsg_set_default_size@libnl_3 3.5.0-1 + nlmsg_set_dst@Base 3.5.0-1 + nlmsg_set_dst@libnl_3 3.5.0-1 + nlmsg_set_proto@Base 3.5.0-1 + nlmsg_set_proto@libnl_3 3.5.0-1 + nlmsg_set_src@Base 3.5.0-1 + nlmsg_set_src@libnl_3 3.5.0-1 + nlmsg_size@Base 3.5.0-1 + nlmsg_size@libnl_3 3.5.0-1 + nlmsg_tail@Base 3.5.0-1 + nlmsg_tail@libnl_3 3.5.0-1 + nlmsg_total_size@Base 3.5.0-1 + nlmsg_total_size@libnl_3 3.5.0-1 + nlmsg_valid_hdr@Base 3.5.0-1 + nlmsg_valid_hdr@libnl_3 3.5.0-1 + nlmsg_validate@Base 3.5.0-1 + nlmsg_validate@libnl_3 3.5.0-1 diff --git a/src/libnl3/debian/libnl-3-dev.install b/src/libnl3/debian/libnl-3-dev.install new file mode 100755 index 000000000000..3715b8b22bbd --- /dev/null +++ b/src/libnl3/debian/libnl-3-dev.install @@ -0,0 +1,5 @@ +#!/usr/bin/dh-exec +debian/tmp/usr/include/* +debian/tmp/usr/lib/*/pkgconfig/libnl-3* +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-3.so lib/${DEB_HOST_MULTIARCH}/ +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-3.a lib/${DEB_HOST_MULTIARCH}/ diff --git a/src/libnl3/debian/libnl-cli-3-200.install b/src/libnl3/debian/libnl-cli-3-200.install new file mode 100755 index 000000000000..6735ec9d14b1 --- /dev/null +++ b/src/libnl3/debian/libnl-cli-3-200.install @@ -0,0 +1,4 @@ +#!/usr/bin/dh-exec +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-cli-3*.so.* +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl/cli/cls/*.so usr/lib/${DEB_HOST_MULTIARCH}/libnl-3/cli/cls +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl/cli/qdisc/*.so usr/lib/${DEB_HOST_MULTIARCH}/libnl-3/cli/qdisc diff --git a/src/libnl3/debian/libnl-cli-3-200.symbols b/src/libnl3/debian/libnl-cli-3-200.symbols new file mode 100644 index 000000000000..2d21c139623c --- /dev/null +++ b/src/libnl3/debian/libnl-cli-3-200.symbols @@ -0,0 +1,226 @@ +basic.so libnl-cli-3-200 #MINVER# +bfifo.so libnl-cli-3-200 #MINVER# +blackhole.so libnl-cli-3-200 #MINVER# +cgroup.so libnl-cli-3-200 #MINVER# +fq_codel.so libnl-cli-3-200 #MINVER# +hfsc.so libnl-cli-3-200 #MINVER# +htb.so libnl-cli-3-200 #MINVER# +ingress.so libnl-cli-3-200 #MINVER# +libnl-cli-3.so.200 libnl-cli-3-200 #MINVER# + libnl_3@libnl_3 3.5.0-1 + libnl_3_2_28@libnl_3_2_28 3.5.0-1 + nl_cli_addr_alloc@Base 3.5.0-1 + nl_cli_addr_alloc@libnl_3 3.5.0-1 + nl_cli_addr_parse@Base 3.5.0-1 + nl_cli_addr_parse@libnl_3 3.5.0-1 + nl_cli_addr_parse_broadcast@Base 3.5.0-1 + nl_cli_addr_parse_broadcast@libnl_3 3.5.0-1 + nl_cli_addr_parse_dev@Base 3.5.0-1 + nl_cli_addr_parse_dev@libnl_3 3.5.0-1 + nl_cli_addr_parse_family@Base 3.5.0-1 + nl_cli_addr_parse_family@libnl_3 3.5.0-1 + nl_cli_addr_parse_label@Base 3.5.0-1 + nl_cli_addr_parse_label@libnl_3 3.5.0-1 + nl_cli_addr_parse_local@Base 3.5.0-1 + nl_cli_addr_parse_local@libnl_3 3.5.0-1 + nl_cli_addr_parse_peer@Base 3.5.0-1 + nl_cli_addr_parse_peer@libnl_3 3.5.0-1 + nl_cli_addr_parse_preferred@Base 3.5.0-1 + nl_cli_addr_parse_preferred@libnl_3 3.5.0-1 + nl_cli_addr_parse_scope@Base 3.5.0-1 + nl_cli_addr_parse_scope@libnl_3 3.5.0-1 + nl_cli_addr_parse_valid@Base 3.5.0-1 + nl_cli_addr_parse_valid@libnl_3 3.5.0-1 + nl_cli_alloc_cache@Base 3.5.0-1 + nl_cli_alloc_cache@libnl_3 3.5.0-1 + nl_cli_alloc_cache_flags@libnl_3_2_28 3.5.0-1 + nl_cli_alloc_socket@Base 3.5.0-1 + nl_cli_alloc_socket@libnl_3 3.5.0-1 + nl_cli_class_alloc@Base 3.5.0-1 + nl_cli_class_alloc@libnl_3 3.5.0-1 + nl_cli_class_alloc_cache@Base 3.5.0-1 + nl_cli_class_alloc_cache@libnl_3 3.5.0-1 + nl_cli_cls_alloc@Base 3.5.0-1 + nl_cli_cls_alloc@libnl_3 3.5.0-1 + nl_cli_cls_alloc_cache@Base 3.5.0-1 + nl_cli_cls_alloc_cache@libnl_3 3.5.0-1 + nl_cli_cls_parse_ematch@Base 3.5.0-1 + nl_cli_cls_parse_ematch@libnl_3 3.5.0-1 + nl_cli_cls_parse_proto@Base 3.5.0-1 + nl_cli_cls_parse_proto@libnl_3 3.5.0-1 + nl_cli_confirm@Base 3.5.0-1 + nl_cli_confirm@libnl_3 3.5.0-1 + nl_cli_connect@Base 3.5.0-1 + nl_cli_connect@libnl_3 3.5.0-1 + nl_cli_ct_alloc@Base 3.5.0-1 + nl_cli_ct_alloc@libnl_3 3.5.0-1 + nl_cli_ct_alloc_cache@Base 3.5.0-1 + nl_cli_ct_alloc_cache@libnl_3 3.5.0-1 + nl_cli_ct_parse_dst@Base 3.5.0-1 + nl_cli_ct_parse_dst@libnl_3 3.5.0-1 + nl_cli_ct_parse_dst_port@Base 3.5.0-1 + nl_cli_ct_parse_dst_port@libnl_3 3.5.0-1 + nl_cli_ct_parse_family@Base 3.5.0-1 + nl_cli_ct_parse_family@libnl_3 3.5.0-1 + nl_cli_ct_parse_id@Base 3.5.0-1 + nl_cli_ct_parse_id@libnl_3 3.5.0-1 + nl_cli_ct_parse_mark@Base 3.5.0-1 + nl_cli_ct_parse_mark@libnl_3 3.5.0-1 + nl_cli_ct_parse_protocol@Base 3.5.0-1 + nl_cli_ct_parse_protocol@libnl_3 3.5.0-1 + nl_cli_ct_parse_src@Base 3.5.0-1 + nl_cli_ct_parse_src@libnl_3 3.5.0-1 + nl_cli_ct_parse_src_port@Base 3.5.0-1 + nl_cli_ct_parse_src_port@libnl_3 3.5.0-1 + nl_cli_ct_parse_status@Base 3.5.0-1 + nl_cli_ct_parse_status@libnl_3 3.5.0-1 + nl_cli_ct_parse_tcp_state@Base 3.5.0-1 + nl_cli_ct_parse_tcp_state@libnl_3 3.5.0-1 + nl_cli_ct_parse_timeout@Base 3.5.0-1 + nl_cli_ct_parse_timeout@libnl_3 3.5.0-1 + nl_cli_ct_parse_use@Base 3.5.0-1 + nl_cli_ct_parse_use@libnl_3 3.5.0-1 + nl_cli_ct_parse_zone@Base 3.5.0-1 + nl_cli_ct_parse_zone@libnl_3 3.5.0-1 + nl_cli_exp_alloc@Base 3.5.0-1 + nl_cli_exp_alloc@libnl_3 3.5.0-1 + nl_cli_exp_alloc_cache@Base 3.5.0-1 + nl_cli_exp_alloc_cache@libnl_3 3.5.0-1 + nl_cli_exp_parse_class@Base 3.5.0-1 + nl_cli_exp_parse_class@libnl_3 3.5.0-1 + nl_cli_exp_parse_dst@Base 3.5.0-1 + nl_cli_exp_parse_dst@libnl_3 3.5.0-1 + nl_cli_exp_parse_dst_port@Base 3.5.0-1 + nl_cli_exp_parse_dst_port@libnl_3 3.5.0-1 + nl_cli_exp_parse_family@Base 3.5.0-1 + nl_cli_exp_parse_family@libnl_3 3.5.0-1 + nl_cli_exp_parse_flags@Base 3.5.0-1 + nl_cli_exp_parse_flags@libnl_3 3.5.0-1 + nl_cli_exp_parse_fn@Base 3.5.0-1 + nl_cli_exp_parse_fn@libnl_3 3.5.0-1 + nl_cli_exp_parse_helper_name@Base 3.5.0-1 + nl_cli_exp_parse_helper_name@libnl_3 3.5.0-1 + nl_cli_exp_parse_icmp_code@Base 3.5.0-1 + nl_cli_exp_parse_icmp_code@libnl_3 3.5.0-1 + nl_cli_exp_parse_icmp_id@Base 3.5.0-1 + nl_cli_exp_parse_icmp_id@libnl_3 3.5.0-1 + nl_cli_exp_parse_icmp_type@Base 3.5.0-1 + nl_cli_exp_parse_icmp_type@libnl_3 3.5.0-1 + nl_cli_exp_parse_id@Base 3.5.0-1 + nl_cli_exp_parse_id@libnl_3 3.5.0-1 + nl_cli_exp_parse_l4protonum@Base 3.5.0-1 + nl_cli_exp_parse_l4protonum@libnl_3 3.5.0-1 + nl_cli_exp_parse_nat_dir@Base 3.5.0-1 + nl_cli_exp_parse_nat_dir@libnl_3 3.5.0-1 + nl_cli_exp_parse_src@Base 3.5.0-1 + nl_cli_exp_parse_src@libnl_3 3.5.0-1 + nl_cli_exp_parse_src_port@Base 3.5.0-1 + nl_cli_exp_parse_src_port@libnl_3 3.5.0-1 + nl_cli_exp_parse_timeout@Base 3.5.0-1 + nl_cli_exp_parse_timeout@libnl_3 3.5.0-1 + nl_cli_exp_parse_zone@Base 3.5.0-1 + nl_cli_exp_parse_zone@libnl_3 3.5.0-1 + nl_cli_fatal@Base 3.5.0-1 + nl_cli_fatal@libnl_3 3.5.0-1 + nl_cli_link_alloc@Base 3.5.0-1 + nl_cli_link_alloc@libnl_3 3.5.0-1 + nl_cli_link_alloc_cache@Base 3.5.0-1 + nl_cli_link_alloc_cache@libnl_3 3.5.0-1 + nl_cli_link_alloc_cache_family@Base 3.5.0-1 + nl_cli_link_alloc_cache_family@libnl_3 3.5.0-1 + nl_cli_link_alloc_cache_family_flags@libnl_3_2_28 3.5.0-1 + nl_cli_link_alloc_cache_flags@libnl_3_2_28 3.5.0-1 + nl_cli_link_parse_family@Base 3.5.0-1 + nl_cli_link_parse_family@libnl_3 3.5.0-1 + nl_cli_link_parse_ifalias@Base 3.5.0-1 + nl_cli_link_parse_ifalias@libnl_3 3.5.0-1 + nl_cli_link_parse_ifindex@Base 3.5.0-1 + nl_cli_link_parse_ifindex@libnl_3 3.5.0-1 + nl_cli_link_parse_mtu@Base 3.5.0-1 + nl_cli_link_parse_mtu@libnl_3 3.5.0-1 + nl_cli_link_parse_name@Base 3.5.0-1 + nl_cli_link_parse_name@libnl_3 3.5.0-1 + nl_cli_link_parse_txqlen@Base 3.5.0-1 + nl_cli_link_parse_txqlen@libnl_3 3.5.0-1 + nl_cli_link_parse_weight@Base 3.5.0-1 + nl_cli_link_parse_weight@libnl_3 3.5.0-1 + nl_cli_load_module@Base 3.5.0-1 + nl_cli_load_module@libnl_3 3.5.0-1 + nl_cli_neigh_alloc@Base 3.5.0-1 + nl_cli_neigh_alloc@libnl_3 3.5.0-1 + nl_cli_neigh_parse_dev@Base 3.5.0-1 + nl_cli_neigh_parse_dev@libnl_3 3.5.0-1 + nl_cli_neigh_parse_dst@Base 3.5.0-1 + nl_cli_neigh_parse_dst@libnl_3 3.5.0-1 + nl_cli_neigh_parse_family@Base 3.5.0-1 + nl_cli_neigh_parse_family@libnl_3 3.5.0-1 + nl_cli_neigh_parse_lladdr@Base 3.5.0-1 + nl_cli_neigh_parse_lladdr@libnl_3 3.5.0-1 + nl_cli_neigh_parse_state@Base 3.5.0-1 + nl_cli_neigh_parse_state@libnl_3 3.5.0-1 + nl_cli_parse_dumptype@Base 3.5.0-1 + nl_cli_parse_dumptype@libnl_3 3.5.0-1 + nl_cli_parse_u32@Base 3.5.0-1 + nl_cli_parse_u32@libnl_3 3.5.0-1 + nl_cli_print_version@Base 3.5.0-1 + nl_cli_print_version@libnl_3 3.5.0-1 + nl_cli_qdisc_alloc@Base 3.5.0-1 + nl_cli_qdisc_alloc@libnl_3 3.5.0-1 + nl_cli_route_alloc@Base 3.5.0-1 + nl_cli_route_alloc@libnl_3 3.5.0-1 + nl_cli_route_alloc_cache@Base 3.5.0-1 + nl_cli_route_alloc_cache@libnl_3 3.5.0-1 + nl_cli_route_parse_dst@Base 3.5.0-1 + nl_cli_route_parse_dst@libnl_3 3.5.0-1 + nl_cli_route_parse_family@Base 3.5.0-1 + nl_cli_route_parse_family@libnl_3 3.5.0-1 + nl_cli_route_parse_iif@Base 3.5.0-1 + nl_cli_route_parse_iif@libnl_3 3.5.0-1 + nl_cli_route_parse_metric@Base 3.5.0-1 + nl_cli_route_parse_metric@libnl_3 3.5.0-1 + nl_cli_route_parse_nexthop@Base 3.5.0-1 + nl_cli_route_parse_nexthop@libnl_3 3.5.0-1 + nl_cli_route_parse_pref_src@Base 3.5.0-1 + nl_cli_route_parse_pref_src@libnl_3 3.5.0-1 + nl_cli_route_parse_prio@Base 3.5.0-1 + nl_cli_route_parse_prio@libnl_3 3.5.0-1 + nl_cli_route_parse_protocol@Base 3.5.0-1 + nl_cli_route_parse_protocol@libnl_3 3.5.0-1 + nl_cli_route_parse_scope@Base 3.5.0-1 + nl_cli_route_parse_scope@libnl_3 3.5.0-1 + nl_cli_route_parse_src@Base 3.5.0-1 + nl_cli_route_parse_src@libnl_3 3.5.0-1 + nl_cli_route_parse_table@Base 3.5.0-1 + nl_cli_route_parse_table@libnl_3 3.5.0-1 + nl_cli_route_parse_type@Base 3.5.0-1 + nl_cli_route_parse_type@libnl_3 3.5.0-1 + nl_cli_rule_alloc@Base 3.5.0-1 + nl_cli_rule_alloc@libnl_3 3.5.0-1 + nl_cli_rule_alloc_cache@Base 3.5.0-1 + nl_cli_rule_alloc_cache@libnl_3 3.5.0-1 + nl_cli_rule_parse_family@Base 3.5.0-1 + nl_cli_rule_parse_family@libnl_3 3.5.0-1 + nl_cli_tc_lookup@Base 3.5.0-1 + nl_cli_tc_lookup@libnl_3 3.5.0-1 + nl_cli_tc_parse_dev@Base 3.5.0-1 + nl_cli_tc_parse_dev@libnl_3 3.5.0-1 + nl_cli_tc_parse_handle@Base 3.5.0-1 + nl_cli_tc_parse_handle@libnl_3 3.5.0-1 + nl_cli_tc_parse_kind@Base 3.5.0-1 + nl_cli_tc_parse_kind@libnl_3 3.5.0-1 + nl_cli_tc_parse_linktype@Base 3.5.0-1 + nl_cli_tc_parse_linktype@libnl_3 3.5.0-1 + nl_cli_tc_parse_mpu@Base 3.5.0-1 + nl_cli_tc_parse_mpu@libnl_3 3.5.0-1 + nl_cli_tc_parse_mtu@Base 3.5.0-1 + nl_cli_tc_parse_mtu@libnl_3 3.5.0-1 + nl_cli_tc_parse_overhead@Base 3.5.0-1 + nl_cli_tc_parse_overhead@libnl_3 3.5.0-1 + nl_cli_tc_parse_parent@Base 3.5.0-1 + nl_cli_tc_parse_parent@libnl_3 3.5.0-1 + nl_cli_tc_register@Base 3.5.0-1 + nl_cli_tc_register@libnl_3 3.5.0-1 + nl_cli_tc_unregister@Base 3.5.0-1 + nl_cli_tc_unregister@libnl_3 3.5.0-1 +pfifo.so libnl-cli-3-200 #MINVER# +plug.so libnl-cli-3-200 #MINVER# diff --git a/src/libnl3/debian/libnl-cli-3-dev.install b/src/libnl3/debian/libnl-cli-3-dev.install new file mode 100644 index 000000000000..66aa3b3d9457 --- /dev/null +++ b/src/libnl3/debian/libnl-cli-3-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/*/pkgconfig/libnl-cli-3* +debian/tmp/usr/lib/*/libnl-cli-3*.so +debian/tmp/usr/lib/*/libnl-cli-3*.a diff --git a/src/libnl3/debian/libnl-genl-3-200-udeb.install b/src/libnl3/debian/libnl-genl-3-200-udeb.install new file mode 100755 index 000000000000..cb5597bf74da --- /dev/null +++ b/src/libnl3/debian/libnl-genl-3-200-udeb.install @@ -0,0 +1,2 @@ +#!/usr/bin/dh-exec +usr/lib/${DEB_HOST_MULTIARCH}/libnl-genl-3.so.* lib/${DEB_HOST_MULTIARCH}/ diff --git a/src/libnl3/debian/libnl-genl-3-200.install b/src/libnl3/debian/libnl-genl-3-200.install new file mode 100755 index 000000000000..d9d6fae40b21 --- /dev/null +++ b/src/libnl3/debian/libnl-genl-3-200.install @@ -0,0 +1,2 @@ +#!/usr/bin/dh-exec +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-genl-3*.so.* lib/${DEB_HOST_MULTIARCH}/ diff --git a/src/libnl3/debian/libnl-genl-3-200.symbols b/src/libnl3/debian/libnl-genl-3-200.symbols new file mode 100644 index 000000000000..0eb2e3be4460 --- /dev/null +++ b/src/libnl3/debian/libnl-genl-3-200.symbols @@ -0,0 +1,88 @@ +libnl-genl-3.so.200 libnl-genl-3-200 #MINVER# + genl_connect@Base 3.5.0-1 + genl_connect@libnl_3 3.5.0-1 + genl_ctrl_alloc_cache@Base 3.5.0-1 + genl_ctrl_alloc_cache@libnl_3 3.5.0-1 + genl_ctrl_resolve@Base 3.5.0-1 + genl_ctrl_resolve@libnl_3 3.5.0-1 + genl_ctrl_resolve_grp@Base 3.5.0-1 + genl_ctrl_resolve_grp@libnl_3 3.5.0-1 + genl_ctrl_search@Base 3.5.0-1 + genl_ctrl_search@libnl_3 3.5.0-1 + genl_ctrl_search_by_name@Base 3.5.0-1 + genl_ctrl_search_by_name@libnl_3 3.5.0-1 + genl_family_add_grp@Base 3.5.0-1 + genl_family_add_grp@libnl_3 3.5.0-1 + genl_family_add_op@Base 3.5.0-1 + genl_family_add_op@libnl_3 3.5.0-1 + genl_family_alloc@Base 3.5.0-1 + genl_family_alloc@libnl_3 3.5.0-1 + genl_family_get_hdrsize@Base 3.5.0-1 + genl_family_get_hdrsize@libnl_3 3.5.0-1 + genl_family_get_id@Base 3.5.0-1 + genl_family_get_id@libnl_3 3.5.0-1 + genl_family_get_maxattr@Base 3.5.0-1 + genl_family_get_maxattr@libnl_3 3.5.0-1 + genl_family_get_name@Base 3.5.0-1 + genl_family_get_name@libnl_3 3.5.0-1 + genl_family_get_version@Base 3.5.0-1 + genl_family_get_version@libnl_3 3.5.0-1 + genl_family_ops@Base 3.5.0-1 + genl_family_ops@libnl_3 3.5.0-1 + genl_family_put@Base 3.5.0-1 + genl_family_put@libnl_3 3.5.0-1 + genl_family_set_hdrsize@Base 3.5.0-1 + genl_family_set_hdrsize@libnl_3 3.5.0-1 + genl_family_set_id@Base 3.5.0-1 + genl_family_set_id@libnl_3 3.5.0-1 + genl_family_set_maxattr@Base 3.5.0-1 + genl_family_set_maxattr@libnl_3 3.5.0-1 + genl_family_set_name@Base 3.5.0-1 + genl_family_set_name@libnl_3 3.5.0-1 + genl_family_set_version@Base 3.5.0-1 + genl_family_set_version@libnl_3 3.5.0-1 + genl_handle_msg@Base 3.5.0-1 + genl_handle_msg@libnl_3 3.5.0-1 + genl_mngt_resolve@Base 3.5.0-1 + genl_mngt_resolve@libnl_3 3.5.0-1 + genl_op2name@Base 3.5.0-1 + genl_op2name@libnl_3 3.5.0-1 + genl_ops_resolve@Base 3.5.0-1 + genl_ops_resolve@libnl_3 3.5.0-1 + genl_register@Base 3.5.0-1 + genl_register@libnl_3 3.5.0-1 + genl_register_family@Base 3.5.0-1 + genl_register_family@libnl_3 3.5.0-1 + genl_resolve_id@Base 3.5.0-1 + genl_resolve_id@libnl_3 3.5.0-1 + genl_send_simple@Base 3.5.0-1 + genl_send_simple@libnl_3 3.5.0-1 + genl_unregister@Base 3.5.0-1 + genl_unregister@libnl_3 3.5.0-1 + genl_unregister_family@Base 3.5.0-1 + genl_unregister_family@libnl_3 3.5.0-1 + genlmsg_attrdata@Base 3.5.0-1 + genlmsg_attrdata@libnl_3 3.5.0-1 + genlmsg_attrlen@Base 3.5.0-1 + genlmsg_attrlen@libnl_3 3.5.0-1 + genlmsg_data@Base 3.5.0-1 + genlmsg_data@libnl_3 3.5.0-1 + genlmsg_hdr@Base 3.5.0-1 + genlmsg_hdr@libnl_3 3.5.0-1 + genlmsg_len@Base 3.5.0-1 + genlmsg_len@libnl_3 3.5.0-1 + genlmsg_parse@Base 3.5.0-1 + genlmsg_parse@libnl_3 3.5.0-1 + genlmsg_put@Base 3.5.0-1 + genlmsg_put@libnl_3 3.5.0-1 + genlmsg_user_data@Base 3.5.0-1 + genlmsg_user_data@libnl_3 3.5.0-1 + genlmsg_user_datalen@Base 3.5.0-1 + genlmsg_user_datalen@libnl_3 3.5.0-1 + genlmsg_user_hdr@Base 3.5.0-1 + genlmsg_user_hdr@libnl_3 3.5.0-1 + genlmsg_valid_hdr@Base 3.5.0-1 + genlmsg_valid_hdr@libnl_3 3.5.0-1 + genlmsg_validate@Base 3.5.0-1 + genlmsg_validate@libnl_3 3.5.0-1 + libnl_3@libnl_3 3.5.0-1 diff --git a/src/libnl3/debian/libnl-genl-3-dev.install b/src/libnl3/debian/libnl-genl-3-dev.install new file mode 100755 index 000000000000..cbc6b51ef474 --- /dev/null +++ b/src/libnl3/debian/libnl-genl-3-dev.install @@ -0,0 +1,4 @@ +#!/usr/bin/dh-exec +debian/tmp/usr/lib/*/pkgconfig/libnl-genl-3* +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-genl-3*.so lib/${DEB_HOST_MULTIARCH}/ +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-genl-3*.a lib/${DEB_HOST_MULTIARCH}/ diff --git a/src/libnl3/debian/libnl-idiag-3-200.install b/src/libnl3/debian/libnl-idiag-3-200.install new file mode 100644 index 000000000000..f6d6b8064e5f --- /dev/null +++ b/src/libnl3/debian/libnl-idiag-3-200.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/*/libnl-idiag-3*.so.* diff --git a/src/libnl3/debian/libnl-idiag-3-200.symbols b/src/libnl3/debian/libnl-idiag-3-200.symbols new file mode 100644 index 000000000000..13cf27c7c8ac --- /dev/null +++ b/src/libnl3/debian/libnl-idiag-3-200.symbols @@ -0,0 +1,206 @@ +libnl-idiag-3.so.200 libnl-idiag-3-200 #MINVER# + idiagnl_attrs2str@Base 3.5.0-1 + idiagnl_attrs2str@libnl_3 3.5.0-1 + idiagnl_connect@Base 3.5.0-1 + idiagnl_connect@libnl_3 3.5.0-1 + idiagnl_exts2str@Base 3.5.0-1 + idiagnl_exts2str@libnl_3 3.5.0-1 + idiagnl_meminfo_alloc@Base 3.5.0-1 + idiagnl_meminfo_alloc@libnl_3 3.5.0-1 + idiagnl_meminfo_get@Base 3.5.0-1 + idiagnl_meminfo_get@libnl_3 3.5.0-1 + idiagnl_meminfo_get_fmem@Base 3.5.0-1 + idiagnl_meminfo_get_fmem@libnl_3 3.5.0-1 + idiagnl_meminfo_get_rmem@Base 3.5.0-1 + idiagnl_meminfo_get_rmem@libnl_3 3.5.0-1 + idiagnl_meminfo_get_tmem@Base 3.5.0-1 + idiagnl_meminfo_get_tmem@libnl_3 3.5.0-1 + idiagnl_meminfo_get_wmem@Base 3.5.0-1 + idiagnl_meminfo_get_wmem@libnl_3 3.5.0-1 + idiagnl_meminfo_obj_ops@Base 3.5.0-1 + idiagnl_meminfo_obj_ops@libnl_3 3.5.0-1 + idiagnl_meminfo_put@Base 3.5.0-1 + idiagnl_meminfo_put@libnl_3 3.5.0-1 + idiagnl_meminfo_set_fmem@Base 3.5.0-1 + idiagnl_meminfo_set_fmem@libnl_3 3.5.0-1 + idiagnl_meminfo_set_rmem@Base 3.5.0-1 + idiagnl_meminfo_set_rmem@libnl_3 3.5.0-1 + idiagnl_meminfo_set_tmem@Base 3.5.0-1 + idiagnl_meminfo_set_tmem@libnl_3 3.5.0-1 + idiagnl_meminfo_set_wmem@Base 3.5.0-1 + idiagnl_meminfo_set_wmem@libnl_3 3.5.0-1 + idiagnl_msg_alloc@Base 3.5.0-1 + idiagnl_msg_alloc@libnl_3 3.5.0-1 + idiagnl_msg_alloc_cache@Base 3.5.0-1 + idiagnl_msg_alloc_cache@libnl_3 3.5.0-1 + idiagnl_msg_get@Base 3.5.0-1 + idiagnl_msg_get@libnl_3 3.5.0-1 + idiagnl_msg_get_cong@Base 3.5.0-1 + idiagnl_msg_get_cong@libnl_3 3.5.0-1 + idiagnl_msg_get_dport@Base 3.5.0-1 + idiagnl_msg_get_dport@libnl_3 3.5.0-1 + idiagnl_msg_get_dst@Base 3.5.0-1 + idiagnl_msg_get_dst@libnl_3 3.5.0-1 + idiagnl_msg_get_expires@Base 3.5.0-1 + idiagnl_msg_get_expires@libnl_3 3.5.0-1 + idiagnl_msg_get_family@Base 3.5.0-1 + idiagnl_msg_get_family@libnl_3 3.5.0-1 + idiagnl_msg_get_ifindex@Base 3.5.0-1 + idiagnl_msg_get_ifindex@libnl_3 3.5.0-1 + idiagnl_msg_get_inode@Base 3.5.0-1 + idiagnl_msg_get_inode@libnl_3 3.5.0-1 + idiagnl_msg_get_meminfo@Base 3.5.0-1 + idiagnl_msg_get_meminfo@libnl_3 3.5.0-1 + idiagnl_msg_get_retrans@Base 3.5.0-1 + idiagnl_msg_get_retrans@libnl_3 3.5.0-1 + idiagnl_msg_get_rqueue@Base 3.5.0-1 + idiagnl_msg_get_rqueue@libnl_3 3.5.0-1 + idiagnl_msg_get_shutdown@Base 3.5.0-1 + idiagnl_msg_get_shutdown@libnl_3 3.5.0-1 + idiagnl_msg_get_sport@Base 3.5.0-1 + idiagnl_msg_get_sport@libnl_3 3.5.0-1 + idiagnl_msg_get_src@Base 3.5.0-1 + idiagnl_msg_get_src@libnl_3 3.5.0-1 + idiagnl_msg_get_state@Base 3.5.0-1 + idiagnl_msg_get_state@libnl_3 3.5.0-1 + idiagnl_msg_get_tclass@Base 3.5.0-1 + idiagnl_msg_get_tclass@libnl_3 3.5.0-1 + idiagnl_msg_get_tcpinfo@Base 3.5.0-1 + idiagnl_msg_get_tcpinfo@libnl_3 3.5.0-1 + idiagnl_msg_get_timer@Base 3.5.0-1 + idiagnl_msg_get_timer@libnl_3 3.5.0-1 + idiagnl_msg_get_tos@Base 3.5.0-1 + idiagnl_msg_get_tos@libnl_3 3.5.0-1 + idiagnl_msg_get_uid@Base 3.5.0-1 + idiagnl_msg_get_uid@libnl_3 3.5.0-1 + idiagnl_msg_get_vegasinfo@Base 3.5.0-1 + idiagnl_msg_get_vegasinfo@libnl_3 3.5.0-1 + idiagnl_msg_get_wqueue@Base 3.5.0-1 + idiagnl_msg_get_wqueue@libnl_3 3.5.0-1 + idiagnl_msg_obj_ops@Base 3.5.0-1 + idiagnl_msg_obj_ops@libnl_3 3.5.0-1 + idiagnl_msg_parse@Base 3.5.0-1 + idiagnl_msg_parse@libnl_3 3.5.0-1 + idiagnl_msg_put@Base 3.5.0-1 + idiagnl_msg_put@libnl_3 3.5.0-1 + idiagnl_msg_set_cong@Base 3.5.0-1 + idiagnl_msg_set_cong@libnl_3 3.5.0-1 + idiagnl_msg_set_dport@Base 3.5.0-1 + idiagnl_msg_set_dport@libnl_3 3.5.0-1 + idiagnl_msg_set_dst@Base 3.5.0-1 + idiagnl_msg_set_dst@libnl_3 3.5.0-1 + idiagnl_msg_set_expires@Base 3.5.0-1 + idiagnl_msg_set_expires@libnl_3 3.5.0-1 + idiagnl_msg_set_family@Base 3.5.0-1 + idiagnl_msg_set_family@libnl_3 3.5.0-1 + idiagnl_msg_set_ifindex@Base 3.5.0-1 + idiagnl_msg_set_ifindex@libnl_3 3.5.0-1 + idiagnl_msg_set_inode@Base 3.5.0-1 + idiagnl_msg_set_inode@libnl_3 3.5.0-1 + idiagnl_msg_set_meminfo@Base 3.5.0-1 + idiagnl_msg_set_meminfo@libnl_3 3.5.0-1 + idiagnl_msg_set_retrans@Base 3.5.0-1 + idiagnl_msg_set_retrans@libnl_3 3.5.0-1 + idiagnl_msg_set_rqueue@Base 3.5.0-1 + idiagnl_msg_set_rqueue@libnl_3 3.5.0-1 + idiagnl_msg_set_shutdown@Base 3.5.0-1 + idiagnl_msg_set_shutdown@libnl_3 3.5.0-1 + idiagnl_msg_set_sport@Base 3.5.0-1 + idiagnl_msg_set_sport@libnl_3 3.5.0-1 + idiagnl_msg_set_src@Base 3.5.0-1 + idiagnl_msg_set_src@libnl_3 3.5.0-1 + idiagnl_msg_set_state@Base 3.5.0-1 + idiagnl_msg_set_state@libnl_3 3.5.0-1 + idiagnl_msg_set_tclass@Base 3.5.0-1 + idiagnl_msg_set_tclass@libnl_3 3.5.0-1 + idiagnl_msg_set_tcpinfo@Base 3.5.0-1 + idiagnl_msg_set_tcpinfo@libnl_3 3.5.0-1 + idiagnl_msg_set_timer@Base 3.5.0-1 + idiagnl_msg_set_timer@libnl_3 3.5.0-1 + idiagnl_msg_set_tos@Base 3.5.0-1 + idiagnl_msg_set_tos@libnl_3 3.5.0-1 + idiagnl_msg_set_uid@Base 3.5.0-1 + idiagnl_msg_set_uid@libnl_3 3.5.0-1 + idiagnl_msg_set_vegasinfo@Base 3.5.0-1 + idiagnl_msg_set_vegasinfo@libnl_3 3.5.0-1 + idiagnl_msg_set_wqueue@Base 3.5.0-1 + idiagnl_msg_set_wqueue@libnl_3 3.5.0-1 + idiagnl_req_alloc@Base 3.5.0-1 + idiagnl_req_alloc@libnl_3 3.5.0-1 + idiagnl_req_get@Base 3.5.0-1 + idiagnl_req_get@libnl_3 3.5.0-1 + idiagnl_req_get_dbs@Base 3.5.0-1 + idiagnl_req_get_dbs@libnl_3 3.5.0-1 + idiagnl_req_get_dst@Base 3.5.0-1 + idiagnl_req_get_dst@libnl_3 3.5.0-1 + idiagnl_req_get_ext@Base 3.5.0-1 + idiagnl_req_get_ext@libnl_3 3.5.0-1 + idiagnl_req_get_family@Base 3.5.0-1 + idiagnl_req_get_family@libnl_3 3.5.0-1 + idiagnl_req_get_ifindex@Base 3.5.0-1 + idiagnl_req_get_ifindex@libnl_3 3.5.0-1 + idiagnl_req_get_src@Base 3.5.0-1 + idiagnl_req_get_src@libnl_3 3.5.0-1 + idiagnl_req_get_states@Base 3.5.0-1 + idiagnl_req_get_states@libnl_3 3.5.0-1 + idiagnl_req_obj_ops@Base 3.5.0-1 + idiagnl_req_obj_ops@libnl_3 3.5.0-1 + idiagnl_req_parse@Base 3.5.0-1 + idiagnl_req_parse@libnl_3 3.5.0-1 + idiagnl_req_put@Base 3.5.0-1 + idiagnl_req_put@libnl_3 3.5.0-1 + idiagnl_req_set_dbs@Base 3.5.0-1 + idiagnl_req_set_dbs@libnl_3 3.5.0-1 + idiagnl_req_set_dst@Base 3.5.0-1 + idiagnl_req_set_dst@libnl_3 3.5.0-1 + idiagnl_req_set_ext@Base 3.5.0-1 + idiagnl_req_set_ext@libnl_3 3.5.0-1 + idiagnl_req_set_family@Base 3.5.0-1 + idiagnl_req_set_family@libnl_3 3.5.0-1 + idiagnl_req_set_ifindex@Base 3.5.0-1 + idiagnl_req_set_ifindex@libnl_3 3.5.0-1 + idiagnl_req_set_src@Base 3.5.0-1 + idiagnl_req_set_src@libnl_3 3.5.0-1 + idiagnl_req_set_states@Base 3.5.0-1 + idiagnl_req_set_states@libnl_3 3.5.0-1 + idiagnl_send_simple@Base 3.5.0-1 + idiagnl_send_simple@libnl_3 3.5.0-1 + idiagnl_shutdown2str@Base 3.5.0-1 + idiagnl_shutdown2str@libnl_3 3.5.0-1 + idiagnl_state2str@Base 3.5.0-1 + idiagnl_state2str@libnl_3 3.5.0-1 + idiagnl_str2state@Base 3.5.0-1 + idiagnl_str2state@libnl_3 3.5.0-1 + idiagnl_str2timer@Base 3.5.0-1 + idiagnl_str2timer@libnl_3 3.5.0-1 + idiagnl_tcpopts2str@Base 3.5.0-1 + idiagnl_tcpopts2str@libnl_3 3.5.0-1 + idiagnl_tcpstate2str@Base 3.5.0-1 + idiagnl_tcpstate2str@libnl_3 3.5.0-1 + idiagnl_timer2str@Base 3.5.0-1 + idiagnl_timer2str@libnl_3 3.5.0-1 + idiagnl_vegasinfo_alloc@Base 3.5.0-1 + idiagnl_vegasinfo_alloc@libnl_3 3.5.0-1 + idiagnl_vegasinfo_get@Base 3.5.0-1 + idiagnl_vegasinfo_get@libnl_3 3.5.0-1 + idiagnl_vegasinfo_get_enabled@Base 3.5.0-1 + idiagnl_vegasinfo_get_enabled@libnl_3 3.5.0-1 + idiagnl_vegasinfo_get_minrtt@Base 3.5.0-1 + idiagnl_vegasinfo_get_minrtt@libnl_3 3.5.0-1 + idiagnl_vegasinfo_get_rtt@Base 3.5.0-1 + idiagnl_vegasinfo_get_rtt@libnl_3 3.5.0-1 + idiagnl_vegasinfo_get_rttcnt@Base 3.5.0-1 + idiagnl_vegasinfo_get_rttcnt@libnl_3 3.5.0-1 + idiagnl_vegasinfo_obj_ops@Base 3.5.0-1 + idiagnl_vegasinfo_obj_ops@libnl_3 3.5.0-1 + idiagnl_vegasinfo_put@Base 3.5.0-1 + idiagnl_vegasinfo_put@libnl_3 3.5.0-1 + idiagnl_vegasinfo_set_enabled@Base 3.5.0-1 + idiagnl_vegasinfo_set_enabled@libnl_3 3.5.0-1 + idiagnl_vegasinfo_set_minrtt@Base 3.5.0-1 + idiagnl_vegasinfo_set_minrtt@libnl_3 3.5.0-1 + idiagnl_vegasinfo_set_rtt@Base 3.5.0-1 + idiagnl_vegasinfo_set_rtt@libnl_3 3.5.0-1 + idiagnl_vegasinfo_set_rttcnt@Base 3.5.0-1 + idiagnl_vegasinfo_set_rttcnt@libnl_3 3.5.0-1 + libnl_3@libnl_3 3.5.0-1 diff --git a/src/libnl3/debian/libnl-idiag-3-dev.install b/src/libnl3/debian/libnl-idiag-3-dev.install new file mode 100644 index 000000000000..6f19a6e83d61 --- /dev/null +++ b/src/libnl3/debian/libnl-idiag-3-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/*/pkgconfig/libnl-idiag-3* +debian/tmp/usr/lib/*/libnl-idiag-3*.so +debian/tmp/usr/lib/*/libnl-idiag-3*.a diff --git a/src/libnl3/debian/libnl-nf-3-200.install b/src/libnl3/debian/libnl-nf-3-200.install new file mode 100644 index 000000000000..6d65611ed34e --- /dev/null +++ b/src/libnl3/debian/libnl-nf-3-200.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/*/libnl-nf-3*.so.* diff --git a/src/libnl3/debian/libnl-nf-3-200.symbols b/src/libnl3/debian/libnl-nf-3-200.symbols new file mode 100644 index 000000000000..2ce4d2ad0ffc --- /dev/null +++ b/src/libnl3/debian/libnl-nf-3-200.symbols @@ -0,0 +1,620 @@ +libnl-nf-3.so.200 libnl-nf-3-200 #MINVER# + ct_obj_ops@Base 3.5.0-1 + ct_obj_ops@libnl_3 3.5.0-1 + exp_obj_ops@Base 3.5.0-1 + exp_obj_ops@libnl_3 3.5.0-1 + libnl_3@libnl_3 3.5.0-1 + log_msg_obj_ops@Base 3.5.0-1 + log_msg_obj_ops@libnl_3 3.5.0-1 + log_obj_ops@Base 3.5.0-1 + log_obj_ops@libnl_3 3.5.0-1 + nfnl_connect@Base 3.5.0-1 + nfnl_connect@libnl_3 3.5.0-1 + nfnl_ct_add@Base 3.5.0-1 + nfnl_ct_add@libnl_3 3.5.0-1 + nfnl_ct_alloc@Base 3.5.0-1 + nfnl_ct_alloc@libnl_3 3.5.0-1 + nfnl_ct_alloc_cache@Base 3.5.0-1 + nfnl_ct_alloc_cache@libnl_3 3.5.0-1 + nfnl_ct_build_add_request@Base 3.5.0-1 + nfnl_ct_build_add_request@libnl_3 3.5.0-1 + nfnl_ct_build_delete_request@Base 3.5.0-1 + nfnl_ct_build_delete_request@libnl_3 3.5.0-1 + nfnl_ct_build_query_request@Base 3.5.0-1 + nfnl_ct_build_query_request@libnl_3 3.5.0-1 + nfnl_ct_del@Base 3.5.0-1 + nfnl_ct_del@libnl_3 3.5.0-1 + nfnl_ct_dump_request@Base 3.5.0-1 + nfnl_ct_dump_request@libnl_3 3.5.0-1 + nfnl_ct_get@Base 3.5.0-1 + nfnl_ct_get@libnl_3 3.5.0-1 + nfnl_ct_get_bytes@Base 3.5.0-1 + nfnl_ct_get_bytes@libnl_3 3.5.0-1 + nfnl_ct_get_dst@Base 3.5.0-1 + nfnl_ct_get_dst@libnl_3 3.5.0-1 + nfnl_ct_get_dst_port@Base 3.5.0-1 + nfnl_ct_get_dst_port@libnl_3 3.5.0-1 + nfnl_ct_get_family@Base 3.5.0-1 + nfnl_ct_get_family@libnl_3 3.5.0-1 + nfnl_ct_get_icmp_code@Base 3.5.0-1 + nfnl_ct_get_icmp_code@libnl_3 3.5.0-1 + nfnl_ct_get_icmp_id@Base 3.5.0-1 + nfnl_ct_get_icmp_id@libnl_3 3.5.0-1 + nfnl_ct_get_icmp_type@Base 3.5.0-1 + nfnl_ct_get_icmp_type@libnl_3 3.5.0-1 + nfnl_ct_get_id@Base 3.5.0-1 + nfnl_ct_get_id@libnl_3 3.5.0-1 + nfnl_ct_get_mark@Base 3.5.0-1 + nfnl_ct_get_mark@libnl_3 3.5.0-1 + nfnl_ct_get_packets@Base 3.5.0-1 + nfnl_ct_get_packets@libnl_3 3.5.0-1 + nfnl_ct_get_proto@Base 3.5.0-1 + nfnl_ct_get_proto@libnl_3 3.5.0-1 + nfnl_ct_get_src@Base 3.5.0-1 + nfnl_ct_get_src@libnl_3 3.5.0-1 + nfnl_ct_get_src_port@Base 3.5.0-1 + nfnl_ct_get_src_port@libnl_3 3.5.0-1 + nfnl_ct_get_status@Base 3.5.0-1 + nfnl_ct_get_status@libnl_3 3.5.0-1 + nfnl_ct_get_tcp_state@Base 3.5.0-1 + nfnl_ct_get_tcp_state@libnl_3 3.5.0-1 + nfnl_ct_get_timeout@Base 3.5.0-1 + nfnl_ct_get_timeout@libnl_3 3.5.0-1 + nfnl_ct_get_timestamp@Base 3.5.0-1 + nfnl_ct_get_timestamp@libnl_3 3.5.0-1 + nfnl_ct_get_use@Base 3.5.0-1 + nfnl_ct_get_use@libnl_3 3.5.0-1 + nfnl_ct_get_zone@Base 3.5.0-1 + nfnl_ct_get_zone@libnl_3 3.5.0-1 + nfnl_ct_put@Base 3.5.0-1 + nfnl_ct_put@libnl_3 3.5.0-1 + nfnl_ct_query@Base 3.5.0-1 + nfnl_ct_query@libnl_3 3.5.0-1 + nfnl_ct_set_bytes@Base 3.5.0-1 + nfnl_ct_set_bytes@libnl_3 3.5.0-1 + nfnl_ct_set_dst@Base 3.5.0-1 + nfnl_ct_set_dst@libnl_3 3.5.0-1 + nfnl_ct_set_dst_port@Base 3.5.0-1 + nfnl_ct_set_dst_port@libnl_3 3.5.0-1 + nfnl_ct_set_family@Base 3.5.0-1 + nfnl_ct_set_family@libnl_3 3.5.0-1 + nfnl_ct_set_icmp_code@Base 3.5.0-1 + nfnl_ct_set_icmp_code@libnl_3 3.5.0-1 + nfnl_ct_set_icmp_id@Base 3.5.0-1 + nfnl_ct_set_icmp_id@libnl_3 3.5.0-1 + nfnl_ct_set_icmp_type@Base 3.5.0-1 + nfnl_ct_set_icmp_type@libnl_3 3.5.0-1 + nfnl_ct_set_id@Base 3.5.0-1 + nfnl_ct_set_id@libnl_3 3.5.0-1 + nfnl_ct_set_mark@Base 3.5.0-1 + nfnl_ct_set_mark@libnl_3 3.5.0-1 + nfnl_ct_set_packets@Base 3.5.0-1 + nfnl_ct_set_packets@libnl_3 3.5.0-1 + nfnl_ct_set_proto@Base 3.5.0-1 + nfnl_ct_set_proto@libnl_3 3.5.0-1 + nfnl_ct_set_src@Base 3.5.0-1 + nfnl_ct_set_src@libnl_3 3.5.0-1 + nfnl_ct_set_src_port@Base 3.5.0-1 + nfnl_ct_set_src_port@libnl_3 3.5.0-1 + nfnl_ct_set_status@Base 3.5.0-1 + nfnl_ct_set_status@libnl_3 3.5.0-1 + nfnl_ct_set_tcp_state@Base 3.5.0-1 + nfnl_ct_set_tcp_state@libnl_3 3.5.0-1 + nfnl_ct_set_timeout@Base 3.5.0-1 + nfnl_ct_set_timeout@libnl_3 3.5.0-1 + nfnl_ct_set_timestamp@Base 3.5.0-1 + nfnl_ct_set_timestamp@libnl_3 3.5.0-1 + nfnl_ct_set_use@Base 3.5.0-1 + nfnl_ct_set_use@libnl_3 3.5.0-1 + nfnl_ct_set_zone@Base 3.5.0-1 + nfnl_ct_set_zone@libnl_3 3.5.0-1 + nfnl_ct_status2str@Base 3.5.0-1 + nfnl_ct_status2str@libnl_3 3.5.0-1 + nfnl_ct_str2status@Base 3.5.0-1 + nfnl_ct_str2status@libnl_3 3.5.0-1 + nfnl_ct_str2tcp_state@Base 3.5.0-1 + nfnl_ct_str2tcp_state@libnl_3 3.5.0-1 + nfnl_ct_tcp_state2str@Base 3.5.0-1 + nfnl_ct_tcp_state2str@libnl_3 3.5.0-1 + nfnl_ct_test_bytes@Base 3.5.0-1 + nfnl_ct_test_bytes@libnl_3 3.5.0-1 + nfnl_ct_test_dst_port@Base 3.5.0-1 + nfnl_ct_test_dst_port@libnl_3 3.5.0-1 + nfnl_ct_test_icmp_code@Base 3.5.0-1 + nfnl_ct_test_icmp_code@libnl_3 3.5.0-1 + nfnl_ct_test_icmp_id@Base 3.5.0-1 + nfnl_ct_test_icmp_id@libnl_3 3.5.0-1 + nfnl_ct_test_icmp_type@Base 3.5.0-1 + nfnl_ct_test_icmp_type@libnl_3 3.5.0-1 + nfnl_ct_test_id@Base 3.5.0-1 + nfnl_ct_test_id@libnl_3 3.5.0-1 + nfnl_ct_test_mark@Base 3.5.0-1 + nfnl_ct_test_mark@libnl_3 3.5.0-1 + nfnl_ct_test_packets@Base 3.5.0-1 + nfnl_ct_test_packets@libnl_3 3.5.0-1 + nfnl_ct_test_proto@Base 3.5.0-1 + nfnl_ct_test_proto@libnl_3 3.5.0-1 + nfnl_ct_test_src_port@Base 3.5.0-1 + nfnl_ct_test_src_port@libnl_3 3.5.0-1 + nfnl_ct_test_status@Base 3.5.0-1 + nfnl_ct_test_status@libnl_3 3.5.0-1 + nfnl_ct_test_tcp_state@Base 3.5.0-1 + nfnl_ct_test_tcp_state@libnl_3 3.5.0-1 + nfnl_ct_test_timeout@Base 3.5.0-1 + nfnl_ct_test_timeout@libnl_3 3.5.0-1 + nfnl_ct_test_timestamp@Base 3.5.0-1 + nfnl_ct_test_timestamp@libnl_3 3.5.0-1 + nfnl_ct_test_use@Base 3.5.0-1 + nfnl_ct_test_use@libnl_3 3.5.0-1 + nfnl_ct_test_zone@Base 3.5.0-1 + nfnl_ct_test_zone@libnl_3 3.5.0-1 + nfnl_ct_unset_status@Base 3.5.0-1 + nfnl_ct_unset_status@libnl_3 3.5.0-1 + nfnl_exp_add@Base 3.5.0-1 + nfnl_exp_add@libnl_3 3.5.0-1 + nfnl_exp_alloc@Base 3.5.0-1 + nfnl_exp_alloc@libnl_3 3.5.0-1 + nfnl_exp_alloc_cache@Base 3.5.0-1 + nfnl_exp_alloc_cache@libnl_3 3.5.0-1 + nfnl_exp_build_add_request@Base 3.5.0-1 + nfnl_exp_build_add_request@libnl_3 3.5.0-1 + nfnl_exp_build_delete_request@Base 3.5.0-1 + nfnl_exp_build_delete_request@libnl_3 3.5.0-1 + nfnl_exp_build_query_request@Base 3.5.0-1 + nfnl_exp_build_query_request@libnl_3 3.5.0-1 + nfnl_exp_del@Base 3.5.0-1 + nfnl_exp_del@libnl_3 3.5.0-1 + nfnl_exp_dump_request@Base 3.5.0-1 + nfnl_exp_dump_request@libnl_3 3.5.0-1 + nfnl_exp_flags2str@Base 3.5.0-1 + nfnl_exp_flags2str@libnl_3 3.5.0-1 + nfnl_exp_get@Base 3.5.0-1 + nfnl_exp_get@libnl_3 3.5.0-1 + nfnl_exp_get_class@Base 3.5.0-1 + nfnl_exp_get_class@libnl_3 3.5.0-1 + nfnl_exp_get_dst@Base 3.5.0-1 + nfnl_exp_get_dst@libnl_3 3.5.0-1 + nfnl_exp_get_dst_port@Base 3.5.0-1 + nfnl_exp_get_dst_port@libnl_3 3.5.0-1 + nfnl_exp_get_family@Base 3.5.0-1 + nfnl_exp_get_family@libnl_3 3.5.0-1 + nfnl_exp_get_flags@Base 3.5.0-1 + nfnl_exp_get_flags@libnl_3 3.5.0-1 + nfnl_exp_get_fn@Base 3.5.0-1 + nfnl_exp_get_fn@libnl_3 3.5.0-1 + nfnl_exp_get_helper_name@Base 3.5.0-1 + nfnl_exp_get_helper_name@libnl_3 3.5.0-1 + nfnl_exp_get_icmp_code@Base 3.5.0-1 + nfnl_exp_get_icmp_code@libnl_3 3.5.0-1 + nfnl_exp_get_icmp_id@Base 3.5.0-1 + nfnl_exp_get_icmp_id@libnl_3 3.5.0-1 + nfnl_exp_get_icmp_type@Base 3.5.0-1 + nfnl_exp_get_icmp_type@libnl_3 3.5.0-1 + nfnl_exp_get_id@Base 3.5.0-1 + nfnl_exp_get_id@libnl_3 3.5.0-1 + nfnl_exp_get_l4protonum@Base 3.5.0-1 + nfnl_exp_get_l4protonum@libnl_3 3.5.0-1 + nfnl_exp_get_nat_dir@Base 3.5.0-1 + nfnl_exp_get_nat_dir@libnl_3 3.5.0-1 + nfnl_exp_get_src@Base 3.5.0-1 + nfnl_exp_get_src@libnl_3 3.5.0-1 + nfnl_exp_get_src_port@Base 3.5.0-1 + nfnl_exp_get_src_port@libnl_3 3.5.0-1 + nfnl_exp_get_timeout@Base 3.5.0-1 + nfnl_exp_get_timeout@libnl_3 3.5.0-1 + nfnl_exp_get_zone@Base 3.5.0-1 + nfnl_exp_get_zone@libnl_3 3.5.0-1 + nfnl_exp_put@Base 3.5.0-1 + nfnl_exp_put@libnl_3 3.5.0-1 + nfnl_exp_query@Base 3.5.0-1 + nfnl_exp_query@libnl_3 3.5.0-1 + nfnl_exp_set_class@Base 3.5.0-1 + nfnl_exp_set_class@libnl_3 3.5.0-1 + nfnl_exp_set_dst@Base 3.5.0-1 + nfnl_exp_set_dst@libnl_3 3.5.0-1 + nfnl_exp_set_family@Base 3.5.0-1 + nfnl_exp_set_family@libnl_3 3.5.0-1 + nfnl_exp_set_flags@Base 3.5.0-1 + nfnl_exp_set_flags@libnl_3 3.5.0-1 + nfnl_exp_set_fn@Base 3.5.0-1 + nfnl_exp_set_fn@libnl_3 3.5.0-1 + nfnl_exp_set_helper_name@Base 3.5.0-1 + nfnl_exp_set_helper_name@libnl_3 3.5.0-1 + nfnl_exp_set_icmp@Base 3.5.0-1 + nfnl_exp_set_icmp@libnl_3 3.5.0-1 + nfnl_exp_set_id@Base 3.5.0-1 + nfnl_exp_set_id@libnl_3 3.5.0-1 + nfnl_exp_set_l4protonum@Base 3.5.0-1 + nfnl_exp_set_l4protonum@libnl_3 3.5.0-1 + nfnl_exp_set_nat_dir@Base 3.5.0-1 + nfnl_exp_set_nat_dir@libnl_3 3.5.0-1 + nfnl_exp_set_ports@Base 3.5.0-1 + nfnl_exp_set_ports@libnl_3 3.5.0-1 + nfnl_exp_set_src@Base 3.5.0-1 + nfnl_exp_set_src@libnl_3 3.5.0-1 + nfnl_exp_set_timeout@Base 3.5.0-1 + nfnl_exp_set_timeout@libnl_3 3.5.0-1 + nfnl_exp_set_zone@Base 3.5.0-1 + nfnl_exp_set_zone@libnl_3 3.5.0-1 + nfnl_exp_str2flags@Base 3.5.0-1 + nfnl_exp_str2flags@libnl_3 3.5.0-1 + nfnl_exp_test_class@Base 3.5.0-1 + nfnl_exp_test_class@libnl_3 3.5.0-1 + nfnl_exp_test_dst@Base 3.5.0-1 + nfnl_exp_test_dst@libnl_3 3.5.0-1 + nfnl_exp_test_flags@Base 3.5.0-1 + nfnl_exp_test_flags@libnl_3 3.5.0-1 + nfnl_exp_test_fn@Base 3.5.0-1 + nfnl_exp_test_fn@libnl_3 3.5.0-1 + nfnl_exp_test_helper_name@Base 3.5.0-1 + nfnl_exp_test_helper_name@libnl_3 3.5.0-1 + nfnl_exp_test_icmp@Base 3.5.0-1 + nfnl_exp_test_icmp@libnl_3 3.5.0-1 + nfnl_exp_test_id@Base 3.5.0-1 + nfnl_exp_test_id@libnl_3 3.5.0-1 + nfnl_exp_test_l4protonum@Base 3.5.0-1 + nfnl_exp_test_l4protonum@libnl_3 3.5.0-1 + nfnl_exp_test_nat_dir@Base 3.5.0-1 + nfnl_exp_test_nat_dir@libnl_3 3.5.0-1 + nfnl_exp_test_ports@Base 3.5.0-1 + nfnl_exp_test_ports@libnl_3 3.5.0-1 + nfnl_exp_test_src@Base 3.5.0-1 + nfnl_exp_test_src@libnl_3 3.5.0-1 + nfnl_exp_test_timeout@Base 3.5.0-1 + nfnl_exp_test_timeout@libnl_3 3.5.0-1 + nfnl_exp_test_zone@Base 3.5.0-1 + nfnl_exp_test_zone@libnl_3 3.5.0-1 + nfnl_exp_unset_flags@Base 3.5.0-1 + nfnl_exp_unset_flags@libnl_3 3.5.0-1 + nfnl_inet_hook2str@Base 3.5.0-1 + nfnl_inet_hook2str@libnl_3 3.5.0-1 + nfnl_log_alloc@Base 3.5.0-1 + nfnl_log_alloc@libnl_3 3.5.0-1 + nfnl_log_build_change_request@Base 3.5.0-1 + nfnl_log_build_change_request@libnl_3 3.5.0-1 + nfnl_log_build_create_request@Base 3.5.0-1 + nfnl_log_build_create_request@libnl_3 3.5.0-1 + nfnl_log_build_delete_request@Base 3.5.0-1 + nfnl_log_build_delete_request@libnl_3 3.5.0-1 + nfnl_log_build_pf_bind@Base 3.5.0-1 + nfnl_log_build_pf_bind@libnl_3 3.5.0-1 + nfnl_log_build_pf_unbind@Base 3.5.0-1 + nfnl_log_build_pf_unbind@libnl_3 3.5.0-1 + nfnl_log_change@Base 3.5.0-1 + nfnl_log_change@libnl_3 3.5.0-1 + nfnl_log_copy_mode2str@Base 3.5.0-1 + nfnl_log_copy_mode2str@libnl_3 3.5.0-1 + nfnl_log_create@Base 3.5.0-1 + nfnl_log_create@libnl_3 3.5.0-1 + nfnl_log_delete@Base 3.5.0-1 + nfnl_log_delete@libnl_3 3.5.0-1 + nfnl_log_flags2str@Base 3.5.0-1 + nfnl_log_flags2str@libnl_3 3.5.0-1 + nfnl_log_get@Base 3.5.0-1 + nfnl_log_get@libnl_3 3.5.0-1 + nfnl_log_get_alloc_size@Base 3.5.0-1 + nfnl_log_get_alloc_size@libnl_3 3.5.0-1 + nfnl_log_get_copy_mode@Base 3.5.0-1 + nfnl_log_get_copy_mode@libnl_3 3.5.0-1 + nfnl_log_get_copy_range@Base 3.5.0-1 + nfnl_log_get_copy_range@libnl_3 3.5.0-1 + nfnl_log_get_flush_timeout@Base 3.5.0-1 + nfnl_log_get_flush_timeout@libnl_3 3.5.0-1 + nfnl_log_get_group@Base 3.5.0-1 + nfnl_log_get_group@libnl_3 3.5.0-1 + nfnl_log_get_queue_threshold@Base 3.5.0-1 + nfnl_log_get_queue_threshold@libnl_3 3.5.0-1 + nfnl_log_msg_alloc@Base 3.5.0-1 + nfnl_log_msg_alloc@libnl_3 3.5.0-1 + nfnl_log_msg_get@Base 3.5.0-1 + nfnl_log_msg_get@libnl_3 3.5.0-1 + nfnl_log_msg_get_family@Base 3.5.0-1 + nfnl_log_msg_get_family@libnl_3 3.5.0-1 + nfnl_log_msg_get_gid@Base 3.5.0-1 + nfnl_log_msg_get_gid@libnl_3 3.5.0-1 + nfnl_log_msg_get_hook@Base 3.5.0-1 + nfnl_log_msg_get_hook@libnl_3 3.5.0-1 + nfnl_log_msg_get_hwaddr@Base 3.5.0-1 + nfnl_log_msg_get_hwaddr@libnl_3 3.5.0-1 + nfnl_log_msg_get_hwproto@Base 3.5.0-1 + nfnl_log_msg_get_hwproto@libnl_3 3.5.0-1 + nfnl_log_msg_get_indev@Base 3.5.0-1 + nfnl_log_msg_get_indev@libnl_3 3.5.0-1 + nfnl_log_msg_get_mark@Base 3.5.0-1 + nfnl_log_msg_get_mark@libnl_3 3.5.0-1 + nfnl_log_msg_get_outdev@Base 3.5.0-1 + nfnl_log_msg_get_outdev@libnl_3 3.5.0-1 + nfnl_log_msg_get_payload@Base 3.5.0-1 + nfnl_log_msg_get_payload@libnl_3 3.5.0-1 + nfnl_log_msg_get_physindev@Base 3.5.0-1 + nfnl_log_msg_get_physindev@libnl_3 3.5.0-1 + nfnl_log_msg_get_physoutdev@Base 3.5.0-1 + nfnl_log_msg_get_physoutdev@libnl_3 3.5.0-1 + nfnl_log_msg_get_prefix@Base 3.5.0-1 + nfnl_log_msg_get_prefix@libnl_3 3.5.0-1 + nfnl_log_msg_get_seq@Base 3.5.0-1 + nfnl_log_msg_get_seq@libnl_3 3.5.0-1 + nfnl_log_msg_get_seq_global@Base 3.5.0-1 + nfnl_log_msg_get_seq_global@libnl_3 3.5.0-1 + nfnl_log_msg_get_timestamp@Base 3.5.0-1 + nfnl_log_msg_get_timestamp@libnl_3 3.5.0-1 + nfnl_log_msg_get_uid@Base 3.5.0-1 + nfnl_log_msg_get_uid@libnl_3 3.5.0-1 + nfnl_log_msg_put@Base 3.5.0-1 + nfnl_log_msg_put@libnl_3 3.5.0-1 + nfnl_log_msg_set_family@Base 3.5.0-1 + nfnl_log_msg_set_family@libnl_3 3.5.0-1 + nfnl_log_msg_set_gid@Base 3.5.0-1 + nfnl_log_msg_set_gid@libnl_3 3.5.0-1 + nfnl_log_msg_set_hook@Base 3.5.0-1 + nfnl_log_msg_set_hook@libnl_3 3.5.0-1 + nfnl_log_msg_set_hwaddr@Base 3.5.0-1 + nfnl_log_msg_set_hwaddr@libnl_3 3.5.0-1 + nfnl_log_msg_set_hwproto@Base 3.5.0-1 + nfnl_log_msg_set_hwproto@libnl_3 3.5.0-1 + nfnl_log_msg_set_indev@Base 3.5.0-1 + nfnl_log_msg_set_indev@libnl_3 3.5.0-1 + nfnl_log_msg_set_mark@Base 3.5.0-1 + nfnl_log_msg_set_mark@libnl_3 3.5.0-1 + nfnl_log_msg_set_outdev@Base 3.5.0-1 + nfnl_log_msg_set_outdev@libnl_3 3.5.0-1 + nfnl_log_msg_set_payload@Base 3.5.0-1 + nfnl_log_msg_set_payload@libnl_3 3.5.0-1 + nfnl_log_msg_set_physindev@Base 3.5.0-1 + nfnl_log_msg_set_physindev@libnl_3 3.5.0-1 + nfnl_log_msg_set_physoutdev@Base 3.5.0-1 + nfnl_log_msg_set_physoutdev@libnl_3 3.5.0-1 + nfnl_log_msg_set_prefix@Base 3.5.0-1 + nfnl_log_msg_set_prefix@libnl_3 3.5.0-1 + nfnl_log_msg_set_seq@Base 3.5.0-1 + nfnl_log_msg_set_seq@libnl_3 3.5.0-1 + nfnl_log_msg_set_seq_global@Base 3.5.0-1 + nfnl_log_msg_set_seq_global@libnl_3 3.5.0-1 + nfnl_log_msg_set_timestamp@Base 3.5.0-1 + nfnl_log_msg_set_timestamp@libnl_3 3.5.0-1 + nfnl_log_msg_set_uid@Base 3.5.0-1 + nfnl_log_msg_set_uid@libnl_3 3.5.0-1 + nfnl_log_msg_test_gid@Base 3.5.0-1 + nfnl_log_msg_test_gid@libnl_3 3.5.0-1 + nfnl_log_msg_test_hook@Base 3.5.0-1 + nfnl_log_msg_test_hook@libnl_3 3.5.0-1 + nfnl_log_msg_test_hwproto@Base 3.5.0-1 + nfnl_log_msg_test_hwproto@libnl_3 3.5.0-1 + nfnl_log_msg_test_mark@Base 3.5.0-1 + nfnl_log_msg_test_mark@libnl_3 3.5.0-1 + nfnl_log_msg_test_seq@Base 3.5.0-1 + nfnl_log_msg_test_seq@libnl_3 3.5.0-1 + nfnl_log_msg_test_seq_global@Base 3.5.0-1 + nfnl_log_msg_test_seq_global@libnl_3 3.5.0-1 + nfnl_log_msg_test_uid@Base 3.5.0-1 + nfnl_log_msg_test_uid@libnl_3 3.5.0-1 + nfnl_log_pf_bind@Base 3.5.0-1 + nfnl_log_pf_bind@libnl_3 3.5.0-1 + nfnl_log_pf_unbind@Base 3.5.0-1 + nfnl_log_pf_unbind@libnl_3 3.5.0-1 + nfnl_log_put@Base 3.5.0-1 + nfnl_log_put@libnl_3 3.5.0-1 + nfnl_log_set_alloc_size@Base 3.5.0-1 + nfnl_log_set_alloc_size@libnl_3 3.5.0-1 + nfnl_log_set_copy_mode@Base 3.5.0-1 + nfnl_log_set_copy_mode@libnl_3 3.5.0-1 + nfnl_log_set_copy_range@Base 3.5.0-1 + nfnl_log_set_copy_range@libnl_3 3.5.0-1 + nfnl_log_set_flags@Base 3.5.0-1 + nfnl_log_set_flags@libnl_3 3.5.0-1 + nfnl_log_set_flush_timeout@Base 3.5.0-1 + nfnl_log_set_flush_timeout@libnl_3 3.5.0-1 + nfnl_log_set_group@Base 3.5.0-1 + nfnl_log_set_group@libnl_3 3.5.0-1 + nfnl_log_set_queue_threshold@Base 3.5.0-1 + nfnl_log_set_queue_threshold@libnl_3 3.5.0-1 + nfnl_log_str2copy_mode@Base 3.5.0-1 + nfnl_log_str2copy_mode@libnl_3 3.5.0-1 + nfnl_log_str2flags@Base 3.5.0-1 + nfnl_log_str2flags@libnl_3 3.5.0-1 + nfnl_log_test_alloc_size@Base 3.5.0-1 + nfnl_log_test_alloc_size@libnl_3 3.5.0-1 + nfnl_log_test_copy_mode@Base 3.5.0-1 + nfnl_log_test_copy_mode@libnl_3 3.5.0-1 + nfnl_log_test_copy_range@Base 3.5.0-1 + nfnl_log_test_copy_range@libnl_3 3.5.0-1 + nfnl_log_test_flush_timeout@Base 3.5.0-1 + nfnl_log_test_flush_timeout@libnl_3 3.5.0-1 + nfnl_log_test_group@Base 3.5.0-1 + nfnl_log_test_group@libnl_3 3.5.0-1 + nfnl_log_test_queue_threshold@Base 3.5.0-1 + nfnl_log_test_queue_threshold@libnl_3 3.5.0-1 + nfnl_log_unset_flags@Base 3.5.0-1 + nfnl_log_unset_flags@libnl_3 3.5.0-1 + nfnl_queue_alloc@Base 3.5.0-1 + nfnl_queue_alloc@libnl_3 3.5.0-1 + nfnl_queue_build_change_request@Base 3.5.0-1 + nfnl_queue_build_change_request@libnl_3 3.5.0-1 + nfnl_queue_build_create_request@Base 3.5.0-1 + nfnl_queue_build_create_request@libnl_3 3.5.0-1 + nfnl_queue_build_delete_request@Base 3.5.0-1 + nfnl_queue_build_delete_request@libnl_3 3.5.0-1 + nfnl_queue_build_pf_bind@Base 3.5.0-1 + nfnl_queue_build_pf_bind@libnl_3 3.5.0-1 + nfnl_queue_build_pf_unbind@Base 3.5.0-1 + nfnl_queue_build_pf_unbind@libnl_3 3.5.0-1 + nfnl_queue_change@Base 3.5.0-1 + nfnl_queue_change@libnl_3 3.5.0-1 + nfnl_queue_copy_mode2str@Base 3.5.0-1 + nfnl_queue_copy_mode2str@libnl_3 3.5.0-1 + nfnl_queue_create@Base 3.5.0-1 + nfnl_queue_create@libnl_3 3.5.0-1 + nfnl_queue_delete@Base 3.5.0-1 + nfnl_queue_delete@libnl_3 3.5.0-1 + nfnl_queue_get@Base 3.5.0-1 + nfnl_queue_get@libnl_3 3.5.0-1 + nfnl_queue_get_copy_mode@Base 3.5.0-1 + nfnl_queue_get_copy_mode@libnl_3 3.5.0-1 + nfnl_queue_get_copy_range@Base 3.5.0-1 + nfnl_queue_get_copy_range@libnl_3 3.5.0-1 + nfnl_queue_get_group@Base 3.5.0-1 + nfnl_queue_get_group@libnl_3 3.5.0-1 + nfnl_queue_get_maxlen@Base 3.5.0-1 + nfnl_queue_get_maxlen@libnl_3 3.5.0-1 + nfnl_queue_msg_alloc@Base 3.5.0-1 + nfnl_queue_msg_alloc@libnl_3 3.5.0-1 + nfnl_queue_msg_build_verdict@Base 3.5.0-1 + nfnl_queue_msg_build_verdict@libnl_3 3.5.0-1 + nfnl_queue_msg_build_verdict_batch@Base 3.5.0-1 + nfnl_queue_msg_build_verdict_batch@libnl_3 3.5.0-1 + nfnl_queue_msg_get@Base 3.5.0-1 + nfnl_queue_msg_get@libnl_3 3.5.0-1 + nfnl_queue_msg_get_family@Base 3.5.0-1 + nfnl_queue_msg_get_family@libnl_3 3.5.0-1 + nfnl_queue_msg_get_group@Base 3.5.0-1 + nfnl_queue_msg_get_group@libnl_3 3.5.0-1 + nfnl_queue_msg_get_hook@Base 3.5.0-1 + nfnl_queue_msg_get_hook@libnl_3 3.5.0-1 + nfnl_queue_msg_get_hwaddr@Base 3.5.0-1 + nfnl_queue_msg_get_hwaddr@libnl_3 3.5.0-1 + nfnl_queue_msg_get_hwproto@Base 3.5.0-1 + nfnl_queue_msg_get_hwproto@libnl_3 3.5.0-1 + nfnl_queue_msg_get_indev@Base 3.5.0-1 + nfnl_queue_msg_get_indev@libnl_3 3.5.0-1 + nfnl_queue_msg_get_mark@Base 3.5.0-1 + nfnl_queue_msg_get_mark@libnl_3 3.5.0-1 + nfnl_queue_msg_get_outdev@Base 3.5.0-1 + nfnl_queue_msg_get_outdev@libnl_3 3.5.0-1 + nfnl_queue_msg_get_packetid@Base 3.5.0-1 + nfnl_queue_msg_get_packetid@libnl_3 3.5.0-1 + nfnl_queue_msg_get_payload@Base 3.5.0-1 + nfnl_queue_msg_get_payload@libnl_3 3.5.0-1 + nfnl_queue_msg_get_physindev@Base 3.5.0-1 + nfnl_queue_msg_get_physindev@libnl_3 3.5.0-1 + nfnl_queue_msg_get_physoutdev@Base 3.5.0-1 + nfnl_queue_msg_get_physoutdev@libnl_3 3.5.0-1 + nfnl_queue_msg_get_timestamp@Base 3.5.0-1 + nfnl_queue_msg_get_timestamp@libnl_3 3.5.0-1 + nfnl_queue_msg_get_verdict@Base 3.5.0-1 + nfnl_queue_msg_get_verdict@libnl_3 3.5.0-1 + nfnl_queue_msg_put@Base 3.5.0-1 + nfnl_queue_msg_put@libnl_3 3.5.0-1 + nfnl_queue_msg_send_verdict@Base 3.5.0-1 + nfnl_queue_msg_send_verdict@libnl_3 3.5.0-1 + nfnl_queue_msg_send_verdict_batch@Base 3.5.0-1 + nfnl_queue_msg_send_verdict_batch@libnl_3 3.5.0-1 + nfnl_queue_msg_send_verdict_payload@Base 3.5.0-1 + nfnl_queue_msg_send_verdict_payload@libnl_3 3.5.0-1 + nfnl_queue_msg_set_family@Base 3.5.0-1 + nfnl_queue_msg_set_family@libnl_3 3.5.0-1 + nfnl_queue_msg_set_group@Base 3.5.0-1 + nfnl_queue_msg_set_group@libnl_3 3.5.0-1 + nfnl_queue_msg_set_hook@Base 3.5.0-1 + nfnl_queue_msg_set_hook@libnl_3 3.5.0-1 + nfnl_queue_msg_set_hwaddr@Base 3.5.0-1 + nfnl_queue_msg_set_hwaddr@libnl_3 3.5.0-1 + nfnl_queue_msg_set_hwproto@Base 3.5.0-1 + nfnl_queue_msg_set_hwproto@libnl_3 3.5.0-1 + nfnl_queue_msg_set_indev@Base 3.5.0-1 + nfnl_queue_msg_set_indev@libnl_3 3.5.0-1 + nfnl_queue_msg_set_mark@Base 3.5.0-1 + nfnl_queue_msg_set_mark@libnl_3 3.5.0-1 + nfnl_queue_msg_set_outdev@Base 3.5.0-1 + nfnl_queue_msg_set_outdev@libnl_3 3.5.0-1 + nfnl_queue_msg_set_packetid@Base 3.5.0-1 + nfnl_queue_msg_set_packetid@libnl_3 3.5.0-1 + nfnl_queue_msg_set_payload@Base 3.5.0-1 + nfnl_queue_msg_set_payload@libnl_3 3.5.0-1 + nfnl_queue_msg_set_physindev@Base 3.5.0-1 + nfnl_queue_msg_set_physindev@libnl_3 3.5.0-1 + nfnl_queue_msg_set_physoutdev@Base 3.5.0-1 + nfnl_queue_msg_set_physoutdev@libnl_3 3.5.0-1 + nfnl_queue_msg_set_timestamp@Base 3.5.0-1 + nfnl_queue_msg_set_timestamp@libnl_3 3.5.0-1 + nfnl_queue_msg_set_verdict@Base 3.5.0-1 + nfnl_queue_msg_set_verdict@libnl_3 3.5.0-1 + nfnl_queue_msg_test_family@Base 3.5.0-1 + nfnl_queue_msg_test_family@libnl_3 3.5.0-1 + nfnl_queue_msg_test_group@Base 3.5.0-1 + nfnl_queue_msg_test_group@libnl_3 3.5.0-1 + nfnl_queue_msg_test_hook@Base 3.5.0-1 + nfnl_queue_msg_test_hook@libnl_3 3.5.0-1 + nfnl_queue_msg_test_hwaddr@Base 3.5.0-1 + nfnl_queue_msg_test_hwaddr@libnl_3 3.5.0-1 + nfnl_queue_msg_test_hwproto@Base 3.5.0-1 + nfnl_queue_msg_test_hwproto@libnl_3 3.5.0-1 + nfnl_queue_msg_test_indev@Base 3.5.0-1 + nfnl_queue_msg_test_indev@libnl_3 3.5.0-1 + nfnl_queue_msg_test_mark@Base 3.5.0-1 + nfnl_queue_msg_test_mark@libnl_3 3.5.0-1 + nfnl_queue_msg_test_outdev@Base 3.5.0-1 + nfnl_queue_msg_test_outdev@libnl_3 3.5.0-1 + nfnl_queue_msg_test_packetid@Base 3.5.0-1 + nfnl_queue_msg_test_packetid@libnl_3 3.5.0-1 + nfnl_queue_msg_test_payload@Base 3.5.0-1 + nfnl_queue_msg_test_payload@libnl_3 3.5.0-1 + nfnl_queue_msg_test_physindev@Base 3.5.0-1 + nfnl_queue_msg_test_physindev@libnl_3 3.5.0-1 + nfnl_queue_msg_test_physoutdev@Base 3.5.0-1 + nfnl_queue_msg_test_physoutdev@libnl_3 3.5.0-1 + nfnl_queue_msg_test_timestamp@Base 3.5.0-1 + nfnl_queue_msg_test_timestamp@libnl_3 3.5.0-1 + nfnl_queue_msg_test_verdict@Base 3.5.0-1 + nfnl_queue_msg_test_verdict@libnl_3 3.5.0-1 + nfnl_queue_pf_bind@Base 3.5.0-1 + nfnl_queue_pf_bind@libnl_3 3.5.0-1 + nfnl_queue_pf_unbind@Base 3.5.0-1 + nfnl_queue_pf_unbind@libnl_3 3.5.0-1 + nfnl_queue_put@Base 3.5.0-1 + nfnl_queue_put@libnl_3 3.5.0-1 + nfnl_queue_set_copy_mode@Base 3.5.0-1 + nfnl_queue_set_copy_mode@libnl_3 3.5.0-1 + nfnl_queue_set_copy_range@Base 3.5.0-1 + nfnl_queue_set_copy_range@libnl_3 3.5.0-1 + nfnl_queue_set_group@Base 3.5.0-1 + nfnl_queue_set_group@libnl_3 3.5.0-1 + nfnl_queue_set_maxlen@Base 3.5.0-1 + nfnl_queue_set_maxlen@libnl_3 3.5.0-1 + nfnl_queue_socket_alloc@Base 3.5.0-1 + nfnl_queue_socket_alloc@libnl_3 3.5.0-1 + nfnl_queue_str2copy_mode@Base 3.5.0-1 + nfnl_queue_str2copy_mode@libnl_3 3.5.0-1 + nfnl_queue_test_copy_mode@Base 3.5.0-1 + nfnl_queue_test_copy_mode@libnl_3 3.5.0-1 + nfnl_queue_test_copy_range@Base 3.5.0-1 + nfnl_queue_test_copy_range@libnl_3 3.5.0-1 + nfnl_queue_test_group@Base 3.5.0-1 + nfnl_queue_test_group@libnl_3 3.5.0-1 + nfnl_queue_test_maxlen@Base 3.5.0-1 + nfnl_queue_test_maxlen@libnl_3 3.5.0-1 + nfnl_send_simple@Base 3.5.0-1 + nfnl_send_simple@libnl_3 3.5.0-1 + nfnl_str2inet_hook@Base 3.5.0-1 + nfnl_str2inet_hook@libnl_3 3.5.0-1 + nfnl_str2verdict@Base 3.5.0-1 + nfnl_str2verdict@libnl_3 3.5.0-1 + nfnl_verdict2str@Base 3.5.0-1 + nfnl_verdict2str@libnl_3 3.5.0-1 + nfnlmsg_alloc_simple@Base 3.5.0-1 + nfnlmsg_alloc_simple@libnl_3 3.5.0-1 + nfnlmsg_ct_group@Base 3.5.0-1 + nfnlmsg_ct_group@libnl_3 3.5.0-1 + nfnlmsg_ct_parse@Base 3.5.0-1 + nfnlmsg_ct_parse@libnl_3 3.5.0-1 + nfnlmsg_exp_group@Base 3.5.0-1 + nfnlmsg_exp_group@libnl_3 3.5.0-1 + nfnlmsg_exp_parse@Base 3.5.0-1 + nfnlmsg_exp_parse@libnl_3 3.5.0-1 + nfnlmsg_family@Base 3.5.0-1 + nfnlmsg_family@libnl_3 3.5.0-1 + nfnlmsg_log_msg_parse@Base 3.5.0-1 + nfnlmsg_log_msg_parse@libnl_3 3.5.0-1 + nfnlmsg_put@Base 3.5.0-1 + nfnlmsg_put@libnl_3 3.5.0-1 + nfnlmsg_queue_msg_parse@Base 3.5.0-1 + nfnlmsg_queue_msg_parse@libnl_3 3.5.0-1 + nfnlmsg_res_id@Base 3.5.0-1 + nfnlmsg_res_id@libnl_3 3.5.0-1 + nfnlmsg_subsys@Base 3.5.0-1 + nfnlmsg_subsys@libnl_3 3.5.0-1 + nfnlmsg_subtype@Base 3.5.0-1 + nfnlmsg_subtype@libnl_3 3.5.0-1 + queue_msg_obj_ops@Base 3.5.0-1 + queue_msg_obj_ops@libnl_3 3.5.0-1 + queue_obj_ops@Base 3.5.0-1 + queue_obj_ops@libnl_3 3.5.0-1 diff --git a/src/libnl3/debian/libnl-nf-3-dev.install b/src/libnl3/debian/libnl-nf-3-dev.install new file mode 100644 index 000000000000..d1307c751b84 --- /dev/null +++ b/src/libnl3/debian/libnl-nf-3-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/*/pkgconfig/libnl-nf-3* +debian/tmp/usr/lib/*/libnl-nf-3*.so +debian/tmp/usr/lib/*/libnl-nf-3*.a diff --git a/src/libnl3/debian/libnl-route-3-200.install b/src/libnl3/debian/libnl-route-3-200.install new file mode 100644 index 000000000000..44c7ec8cdfad --- /dev/null +++ b/src/libnl3/debian/libnl-route-3-200.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/*/libnl-route-3*.so.* diff --git a/src/libnl3/debian/libnl-route-3-200.symbols b/src/libnl3/debian/libnl-route-3-200.symbols new file mode 100644 index 000000000000..e11157ba4e88 --- /dev/null +++ b/src/libnl3/debian/libnl-route-3-200.symbols @@ -0,0 +1,2051 @@ +libnl-route-3.so.200 libnl-route-3-200 #MINVER# + ematch__create_buffer@Base 3.5.0-1 + ematch__delete_buffer@Base 3.5.0-1 + ematch__flush_buffer@Base 3.5.0-1 + ematch__scan_buffer@Base 3.5.0-1 + ematch__scan_bytes@Base 3.5.0-1 + ematch__scan_string@Base 3.5.0-1 + ematch__switch_to_buffer@Base 3.5.0-1 + ematch_alloc@Base 3.5.0-1 + ematch_free@Base 3.5.0-1 + ematch_get_column@Base 3.5.0-1 + ematch_get_debug@Base 3.5.0-1 + ematch_get_extra@Base 3.5.0-1 + ematch_get_in@Base 3.5.0-1 + ematch_get_leng@Base 3.5.0-1 + ematch_get_lineno@Base 3.5.0-1 + ematch_get_lval@Base 3.5.0-1 + ematch_get_out@Base 3.5.0-1 + ematch_get_text@Base 3.5.0-1 + ematch_lex@Base 3.5.0-1 + ematch_lex_destroy@Base 3.5.0-1 + ematch_lex_init@Base 3.5.0-1 + ematch_lex_init_extra@Base 3.5.0-1 + ematch_parse@Base 3.5.0-1 + ematch_pop_buffer_state@Base 3.5.0-1 + ematch_push_buffer_state@Base 3.5.0-1 + ematch_realloc@Base 3.5.0-1 + ematch_restart@Base 3.5.0-1 + ematch_set_column@Base 3.5.0-1 + ematch_set_debug@Base 3.5.0-1 + ematch_set_extra@Base 3.5.0-1 + ematch_set_in@Base 3.5.0-1 + ematch_set_lineno@Base 3.5.0-1 + ematch_set_lval@Base 3.5.0-1 + ematch_set_out@Base 3.5.0-1 + flnl_lookup@Base 3.5.0-1 + flnl_lookup@libnl_3 3.5.0-1 + flnl_lookup_build_request@Base 3.5.0-1 + flnl_lookup_build_request@libnl_3 3.5.0-1 + flnl_request_alloc@Base 3.5.0-1 + flnl_request_alloc@libnl_3 3.5.0-1 + flnl_request_get_addr@Base 3.5.0-1 + flnl_request_get_addr@libnl_3 3.5.0-1 + flnl_request_get_fwmark@Base 3.5.0-1 + flnl_request_get_fwmark@libnl_3 3.5.0-1 + flnl_request_get_scope@Base 3.5.0-1 + flnl_request_get_scope@libnl_3 3.5.0-1 + flnl_request_get_table@Base 3.5.0-1 + flnl_request_get_table@libnl_3 3.5.0-1 + flnl_request_get_tos@Base 3.5.0-1 + flnl_request_get_tos@libnl_3 3.5.0-1 + flnl_request_set_addr@Base 3.5.0-1 + flnl_request_set_addr@libnl_3 3.5.0-1 + flnl_request_set_fwmark@Base 3.5.0-1 + flnl_request_set_fwmark@libnl_3 3.5.0-1 + flnl_request_set_scope@Base 3.5.0-1 + flnl_request_set_scope@libnl_3 3.5.0-1 + flnl_request_set_table@Base 3.5.0-1 + flnl_request_set_table@libnl_3 3.5.0-1 + flnl_request_set_tos@Base 3.5.0-1 + flnl_request_set_tos@libnl_3 3.5.0-1 + flnl_result_alloc@Base 3.5.0-1 + flnl_result_alloc@libnl_3 3.5.0-1 + flnl_result_alloc_cache@Base 3.5.0-1 + flnl_result_alloc_cache@libnl_3 3.5.0-1 + flnl_result_get_error@Base 3.5.0-1 + flnl_result_get_error@libnl_3 3.5.0-1 + flnl_result_get_nexthop_sel@Base 3.5.0-1 + flnl_result_get_nexthop_sel@libnl_3 3.5.0-1 + flnl_result_get_prefixlen@Base 3.5.0-1 + flnl_result_get_prefixlen@libnl_3 3.5.0-1 + flnl_result_get_scope@Base 3.5.0-1 + flnl_result_get_scope@libnl_3 3.5.0-1 + flnl_result_get_table_id@Base 3.5.0-1 + flnl_result_get_table_id@libnl_3 3.5.0-1 + flnl_result_get_type@Base 3.5.0-1 + flnl_result_get_type@libnl_3 3.5.0-1 + flnl_result_put@Base 3.5.0-1 + flnl_result_put@libnl_3 3.5.0-1 + libnl_3@libnl_3 3.5.0-1 + libnl_3_2_26@libnl_3_2_26 3.5.0-1 + libnl_3_2_27@libnl_3_2_27 3.5.0-1 + libnl_3_2_28@libnl_3_2_28 3.5.0-1 + libnl_3_2_29@libnl_3_2_29 3.5.0-1 + libnl_3_4@libnl_3_4 3.5.0-1 + libnl_3_5@libnl_3_5 3.5.0-1 + nl_ovl_strategy2str@Base 3.5.0-1 + nl_ovl_strategy2str@libnl_3 3.5.0-1 + nl_police2str@Base 3.5.0-1 + nl_police2str@libnl_3 3.5.0-1 + nl_rtgen_request@Base 3.5.0-1 + nl_rtgen_request@libnl_3 3.5.0-1 + nl_rtntype2str@Base 3.5.0-1 + nl_rtntype2str@libnl_3 3.5.0-1 + nl_str2ovl_strategy@Base 3.5.0-1 + nl_str2ovl_strategy@libnl_3 3.5.0-1 + nl_str2police@Base 3.5.0-1 + nl_str2police@libnl_3 3.5.0-1 + nl_str2rtntype@Base 3.5.0-1 + nl_str2rtntype@libnl_3 3.5.0-1 + pktloc__create_buffer@Base 3.5.0-1 + pktloc__delete_buffer@Base 3.5.0-1 + pktloc__flush_buffer@Base 3.5.0-1 + pktloc__scan_buffer@Base 3.5.0-1 + pktloc__scan_bytes@Base 3.5.0-1 + pktloc__scan_string@Base 3.5.0-1 + pktloc__switch_to_buffer@Base 3.5.0-1 + pktloc_alloc@Base 3.5.0-1 + pktloc_free@Base 3.5.0-1 + pktloc_get_column@Base 3.5.0-1 + pktloc_get_debug@Base 3.5.0-1 + pktloc_get_extra@Base 3.5.0-1 + pktloc_get_in@Base 3.5.0-1 + pktloc_get_leng@Base 3.5.0-1 + pktloc_get_lineno@Base 3.5.0-1 + pktloc_get_lloc@Base 3.5.0-1 + pktloc_get_lval@Base 3.5.0-1 + pktloc_get_out@Base 3.5.0-1 + pktloc_get_text@Base 3.5.0-1 + pktloc_lex@Base 3.5.0-1 + pktloc_lex_destroy@Base 3.5.0-1 + pktloc_lex_init@Base 3.5.0-1 + pktloc_lex_init_extra@Base 3.5.0-1 + pktloc_parse@Base 3.5.0-1 + pktloc_pop_buffer_state@Base 3.5.0-1 + pktloc_push_buffer_state@Base 3.5.0-1 + pktloc_realloc@Base 3.5.0-1 + pktloc_restart@Base 3.5.0-1 + pktloc_set_column@Base 3.5.0-1 + pktloc_set_debug@Base 3.5.0-1 + pktloc_set_extra@Base 3.5.0-1 + pktloc_set_in@Base 3.5.0-1 + pktloc_set_lineno@Base 3.5.0-1 + pktloc_set_lloc@Base 3.5.0-1 + + pktloc_set_lval@Base 3.5.0-1 + pktloc_set_out@Base 3.5.0-1 + route_obj_ops@Base 3.5.0-1 + route_obj_ops@libnl_3 3.5.0-1 + rtln_link_policy@Base 3.5.0-1 + rtln_link_policy@libnl_3 3.5.0-1 + rtnl_act_add@Base 3.5.0-1 + rtnl_act_add@libnl_3 3.5.0-1 + rtnl_act_alloc@Base 3.5.0-1 + rtnl_act_alloc@libnl_3 3.5.0-1 + rtnl_act_append@Base 3.5.0-1 + rtnl_act_append@libnl_3 3.5.0-1 + rtnl_act_build_add_request@Base 3.5.0-1 + rtnl_act_build_add_request@libnl_3 3.5.0-1 + rtnl_act_build_change_request@Base 3.5.0-1 + rtnl_act_build_change_request@libnl_3 3.5.0-1 + rtnl_act_build_delete_request@Base 3.5.0-1 + rtnl_act_build_delete_request@libnl_3 3.5.0-1 + rtnl_act_change@Base 3.5.0-1 + rtnl_act_change@libnl_3 3.5.0-1 + rtnl_act_delete@Base 3.5.0-1 + rtnl_act_delete@libnl_3 3.5.0-1 + rtnl_act_fill@Base 3.5.0-1 + rtnl_act_fill@libnl_3 3.5.0-1 + rtnl_act_get@Base 3.5.0-1 + rtnl_act_get@libnl_3 3.5.0-1 + rtnl_act_next@libnl_3_4 3.5.0-1 + rtnl_act_parse@Base 3.5.0-1 + rtnl_act_parse@libnl_3 3.5.0-1 + rtnl_act_put@Base 3.5.0-1 + rtnl_act_put@libnl_3 3.5.0-1 + rtnl_act_put_all@Base 3.5.0-1 + rtnl_act_put_all@libnl_3 3.5.0-1 + rtnl_act_remove@Base 3.5.0-1 + rtnl_act_remove@libnl_3 3.5.0-1 + rtnl_addr_add@Base 3.5.0-1 + rtnl_addr_add@libnl_3 3.5.0-1 + rtnl_addr_alloc@Base 3.5.0-1 + rtnl_addr_alloc@libnl_3 3.5.0-1 + rtnl_addr_alloc_cache@Base 3.5.0-1 + rtnl_addr_alloc_cache@libnl_3 3.5.0-1 + rtnl_addr_build_add_request@Base 3.5.0-1 + rtnl_addr_build_add_request@libnl_3 3.5.0-1 + rtnl_addr_build_delete_request@Base 3.5.0-1 + rtnl_addr_build_delete_request@libnl_3 3.5.0-1 + rtnl_addr_delete@Base 3.5.0-1 + rtnl_addr_delete@libnl_3 3.5.0-1 + rtnl_addr_flags2str@Base 3.5.0-1 + rtnl_addr_flags2str@libnl_3 3.5.0-1 + rtnl_addr_get@Base 3.5.0-1 + rtnl_addr_get@libnl_3 3.5.0-1 + rtnl_addr_get_anycast@Base 3.5.0-1 + rtnl_addr_get_anycast@libnl_3 3.5.0-1 + rtnl_addr_get_broadcast@Base 3.5.0-1 + rtnl_addr_get_broadcast@libnl_3 3.5.0-1 + rtnl_addr_get_create_time@Base 3.5.0-1 + rtnl_addr_get_create_time@libnl_3 3.5.0-1 + rtnl_addr_get_family@Base 3.5.0-1 + rtnl_addr_get_family@libnl_3 3.5.0-1 + rtnl_addr_get_flags@Base 3.5.0-1 + rtnl_addr_get_flags@libnl_3 3.5.0-1 + rtnl_addr_get_ifindex@Base 3.5.0-1 + rtnl_addr_get_ifindex@libnl_3 3.5.0-1 + rtnl_addr_get_label@Base 3.5.0-1 + rtnl_addr_get_label@libnl_3 3.5.0-1 + rtnl_addr_get_last_update_time@Base 3.5.0-1 + rtnl_addr_get_last_update_time@libnl_3 3.5.0-1 + rtnl_addr_get_link@Base 3.5.0-1 + rtnl_addr_get_link@libnl_3 3.5.0-1 + rtnl_addr_get_local@Base 3.5.0-1 + rtnl_addr_get_local@libnl_3 3.5.0-1 + rtnl_addr_get_multicast@Base 3.5.0-1 + rtnl_addr_get_multicast@libnl_3 3.5.0-1 + rtnl_addr_get_peer@Base 3.5.0-1 + rtnl_addr_get_peer@libnl_3 3.5.0-1 + rtnl_addr_get_preferred_lifetime@Base 3.5.0-1 + rtnl_addr_get_preferred_lifetime@libnl_3 3.5.0-1 + rtnl_addr_get_prefixlen@Base 3.5.0-1 + rtnl_addr_get_prefixlen@libnl_3 3.5.0-1 + rtnl_addr_get_scope@Base 3.5.0-1 + rtnl_addr_get_scope@libnl_3 3.5.0-1 + rtnl_addr_get_valid_lifetime@Base 3.5.0-1 + rtnl_addr_get_valid_lifetime@libnl_3 3.5.0-1 + rtnl_addr_put@Base 3.5.0-1 + rtnl_addr_put@libnl_3 3.5.0-1 + rtnl_addr_set_anycast@Base 3.5.0-1 + rtnl_addr_set_anycast@libnl_3 3.5.0-1 + rtnl_addr_set_broadcast@Base 3.5.0-1 + rtnl_addr_set_broadcast@libnl_3 3.5.0-1 + rtnl_addr_set_family@Base 3.5.0-1 + rtnl_addr_set_family@libnl_3 3.5.0-1 + rtnl_addr_set_flags@Base 3.5.0-1 + rtnl_addr_set_flags@libnl_3 3.5.0-1 + rtnl_addr_set_ifindex@Base 3.5.0-1 + rtnl_addr_set_ifindex@libnl_3 3.5.0-1 + rtnl_addr_set_label@Base 3.5.0-1 + rtnl_addr_set_label@libnl_3 3.5.0-1 + rtnl_addr_set_link@Base 3.5.0-1 + rtnl_addr_set_link@libnl_3 3.5.0-1 + rtnl_addr_set_local@Base 3.5.0-1 + rtnl_addr_set_local@libnl_3 3.5.0-1 + rtnl_addr_set_multicast@Base 3.5.0-1 + rtnl_addr_set_multicast@libnl_3 3.5.0-1 + rtnl_addr_set_peer@Base 3.5.0-1 + rtnl_addr_set_peer@libnl_3 3.5.0-1 + rtnl_addr_set_preferred_lifetime@Base 3.5.0-1 + rtnl_addr_set_preferred_lifetime@libnl_3 3.5.0-1 + rtnl_addr_set_prefixlen@Base 3.5.0-1 + rtnl_addr_set_prefixlen@libnl_3 3.5.0-1 + rtnl_addr_set_scope@Base 3.5.0-1 + rtnl_addr_set_scope@libnl_3 3.5.0-1 + rtnl_addr_set_valid_lifetime@Base 3.5.0-1 + rtnl_addr_set_valid_lifetime@libnl_3 3.5.0-1 + rtnl_addr_str2flags@Base 3.5.0-1 + rtnl_addr_str2flags@libnl_3 3.5.0-1 + rtnl_addr_unset_flags@Base 3.5.0-1 + rtnl_addr_unset_flags@libnl_3 3.5.0-1 + rtnl_basic_add_action@Base 3.5.0-1 + rtnl_basic_add_action@libnl_3 3.5.0-1 + rtnl_basic_del_action@Base 3.5.0-1 + rtnl_basic_del_action@libnl_3 3.5.0-1 + rtnl_basic_get_action@libnl_3_4 3.5.0-1 + rtnl_basic_get_ematch@Base 3.5.0-1 + rtnl_basic_get_ematch@libnl_3 3.5.0-1 + rtnl_basic_get_target@Base 3.5.0-1 + rtnl_basic_get_target@libnl_3 3.5.0-1 + rtnl_basic_set_ematch@Base 3.5.0-1 + rtnl_basic_set_ematch@libnl_3 3.5.0-1 + rtnl_basic_set_target@Base 3.5.0-1 + rtnl_basic_set_target@libnl_3 3.5.0-1 + rtnl_cgroup_get_ematch@Base 3.5.0-1 + rtnl_cgroup_get_ematch@libnl_3 3.5.0-1 + rtnl_cgroup_set_ematch@Base 3.5.0-1 + rtnl_cgroup_set_ematch@libnl_3 3.5.0-1 + rtnl_class_add@Base 3.5.0-1 + rtnl_class_add@libnl_3 3.5.0-1 + rtnl_class_alloc@Base 3.5.0-1 + rtnl_class_alloc@libnl_3 3.5.0-1 + rtnl_class_alloc_cache@Base 3.5.0-1 + rtnl_class_alloc_cache@libnl_3 3.5.0-1 + rtnl_class_build_add_request@Base 3.5.0-1 + rtnl_class_build_add_request@libnl_3 3.5.0-1 + rtnl_class_build_delete_request@Base 3.5.0-1 + rtnl_class_build_delete_request@libnl_3 3.5.0-1 + rtnl_class_delete@Base 3.5.0-1 + rtnl_class_delete@libnl_3 3.5.0-1 + rtnl_class_dsmark_get_bitmask@Base 3.5.0-1 + rtnl_class_dsmark_get_bitmask@libnl_3 3.5.0-1 + rtnl_class_dsmark_get_value@Base 3.5.0-1 + rtnl_class_dsmark_get_value@libnl_3 3.5.0-1 + rtnl_class_dsmark_set_bitmask@Base 3.5.0-1 + rtnl_class_dsmark_set_bitmask@libnl_3 3.5.0-1 + rtnl_class_dsmark_set_value@Base 3.5.0-1 + rtnl_class_dsmark_set_value@libnl_3 3.5.0-1 + rtnl_class_foreach_child@Base 3.5.0-1 + rtnl_class_foreach_child@libnl_3 3.5.0-1 + rtnl_class_foreach_cls@Base 3.5.0-1 + rtnl_class_foreach_cls@libnl_3 3.5.0-1 + rtnl_class_get@Base 3.5.0-1 + rtnl_class_get@libnl_3 3.5.0-1 + rtnl_class_get_by_parent@libnl_3_5 3.5.0-1 + rtnl_class_hfsc_get_fsc@Base 3.5.0-1 + rtnl_class_hfsc_get_fsc@libnl_3 3.5.0-1 + rtnl_class_hfsc_get_rsc@Base 3.5.0-1 + rtnl_class_hfsc_get_rsc@libnl_3 3.5.0-1 + rtnl_class_hfsc_get_usc@Base 3.5.0-1 + rtnl_class_hfsc_get_usc@libnl_3 3.5.0-1 + rtnl_class_hfsc_set_fsc@Base 3.5.0-1 + rtnl_class_hfsc_set_fsc@libnl_3 3.5.0-1 + rtnl_class_hfsc_set_rsc@Base 3.5.0-1 + rtnl_class_hfsc_set_rsc@libnl_3 3.5.0-1 + rtnl_class_hfsc_set_usc@Base 3.5.0-1 + rtnl_class_hfsc_set_usc@libnl_3 3.5.0-1 + rtnl_class_leaf_qdisc@Base 3.5.0-1 + rtnl_class_leaf_qdisc@libnl_3 3.5.0-1 + rtnl_class_put@Base 3.5.0-1 + rtnl_class_put@libnl_3 3.5.0-1 + rtnl_classid_generate@Base 3.5.0-1 + rtnl_classid_generate@libnl_3 3.5.0-1 + rtnl_cls_add@Base 3.5.0-1 + rtnl_cls_add@libnl_3 3.5.0-1 + rtnl_cls_alloc@Base 3.5.0-1 + rtnl_cls_alloc@libnl_3 3.5.0-1 + rtnl_cls_alloc_cache@Base 3.5.0-1 + rtnl_cls_alloc_cache@libnl_3 3.5.0-1 + rtnl_cls_build_add_request@Base 3.5.0-1 + rtnl_cls_build_add_request@libnl_3 3.5.0-1 + rtnl_cls_build_change_request@Base 3.5.0-1 + rtnl_cls_build_change_request@libnl_3 3.5.0-1 + rtnl_cls_build_delete_request@Base 3.5.0-1 + rtnl_cls_build_delete_request@libnl_3 3.5.0-1 + rtnl_cls_cache_set_tc_params@libnl_3_5 3.5.0-1 + rtnl_cls_change@Base 3.5.0-1 + rtnl_cls_change@libnl_3 3.5.0-1 + rtnl_cls_delete@Base 3.5.0-1 + rtnl_cls_delete@libnl_3 3.5.0-1 + rtnl_cls_get_prio@Base 3.5.0-1 + rtnl_cls_get_prio@libnl_3 3.5.0-1 + rtnl_cls_get_protocol@Base 3.5.0-1 + rtnl_cls_get_protocol@libnl_3 3.5.0-1 + rtnl_cls_put@Base 3.5.0-1 + rtnl_cls_put@libnl_3 3.5.0-1 + rtnl_cls_set_prio@Base 3.5.0-1 + rtnl_cls_set_prio@libnl_3 3.5.0-1 + rtnl_cls_set_protocol@Base 3.5.0-1 + rtnl_cls_set_protocol@libnl_3 3.5.0-1 + rtnl_ematch_add_child@Base 3.5.0-1 + rtnl_ematch_add_child@libnl_3 3.5.0-1 + rtnl_ematch_alloc@Base 3.5.0-1 + rtnl_ematch_alloc@libnl_3 3.5.0-1 + rtnl_ematch_cmp_get@Base 3.5.0-1 + rtnl_ematch_cmp_get@libnl_3 3.5.0-1 + rtnl_ematch_cmp_set@Base 3.5.0-1 + rtnl_ematch_cmp_set@libnl_3 3.5.0-1 + rtnl_ematch_data@Base 3.5.0-1 + rtnl_ematch_data@libnl_3 3.5.0-1 + rtnl_ematch_fill_attr@Base 3.5.0-1 + rtnl_ematch_fill_attr@libnl_3 3.5.0-1 + rtnl_ematch_free@Base 3.5.0-1 + rtnl_ematch_free@libnl_3 3.5.0-1 + rtnl_ematch_get_flags@Base 3.5.0-1 + rtnl_ematch_get_flags@libnl_3 3.5.0-1 + rtnl_ematch_lookup_ops@Base 3.5.0-1 + rtnl_ematch_lookup_ops@libnl_3 3.5.0-1 + rtnl_ematch_lookup_ops_by_name@Base 3.5.0-1 + rtnl_ematch_lookup_ops_by_name@libnl_3 3.5.0-1 + rtnl_ematch_meta_set_lvalue@Base 3.5.0-1 + rtnl_ematch_meta_set_lvalue@libnl_3 3.5.0-1 + rtnl_ematch_meta_set_operand@Base 3.5.0-1 + rtnl_ematch_meta_set_operand@libnl_3 3.5.0-1 + rtnl_ematch_meta_set_rvalue@Base 3.5.0-1 + rtnl_ematch_meta_set_rvalue@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_get_layer@Base 3.5.0-1 + rtnl_ematch_nbyte_get_layer@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_get_len@Base 3.5.0-1 + rtnl_ematch_nbyte_get_len@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_get_offset@Base 3.5.0-1 + rtnl_ematch_nbyte_get_offset@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_get_pattern@Base 3.5.0-1 + rtnl_ematch_nbyte_get_pattern@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_set_offset@Base 3.5.0-1 + rtnl_ematch_nbyte_set_offset@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_set_pattern@Base 3.5.0-1 + rtnl_ematch_nbyte_set_pattern@libnl_3 3.5.0-1 + rtnl_ematch_offset2txt@Base 3.5.0-1 + rtnl_ematch_offset2txt@libnl_3 3.5.0-1 + rtnl_ematch_opnd2txt@Base 3.5.0-1 + rtnl_ematch_opnd2txt@libnl_3 3.5.0-1 + rtnl_ematch_parse_attr@Base 3.5.0-1 + rtnl_ematch_parse_attr@libnl_3 3.5.0-1 + rtnl_ematch_parse_expr@Base 3.5.0-1 + rtnl_ematch_parse_expr@libnl_3 3.5.0-1 + rtnl_ematch_register@Base 3.5.0-1 + rtnl_ematch_register@libnl_3 3.5.0-1 + rtnl_ematch_set_flags@Base 3.5.0-1 + rtnl_ematch_set_flags@libnl_3 3.5.0-1 + rtnl_ematch_set_kind@Base 3.5.0-1 + rtnl_ematch_set_kind@libnl_3 3.5.0-1 + rtnl_ematch_set_name@Base 3.5.0-1 + rtnl_ematch_set_name@libnl_3 3.5.0-1 + rtnl_ematch_set_ops@Base 3.5.0-1 + rtnl_ematch_set_ops@libnl_3 3.5.0-1 + rtnl_ematch_text_get_algo@Base 3.5.0-1 + rtnl_ematch_text_get_algo@libnl_3 3.5.0-1 + rtnl_ematch_text_get_from_layer@Base 3.5.0-1 + rtnl_ematch_text_get_from_layer@libnl_3 3.5.0-1 + rtnl_ematch_text_get_from_offset@Base 3.5.0-1 + rtnl_ematch_text_get_from_offset@libnl_3 3.5.0-1 + rtnl_ematch_text_get_len@Base 3.5.0-1 + rtnl_ematch_text_get_len@libnl_3 3.5.0-1 + rtnl_ematch_text_get_pattern@Base 3.5.0-1 + rtnl_ematch_text_get_pattern@libnl_3 3.5.0-1 + rtnl_ematch_text_get_to_layer@Base 3.5.0-1 + rtnl_ematch_text_get_to_layer@libnl_3 3.5.0-1 + rtnl_ematch_text_get_to_offset@Base 3.5.0-1 + rtnl_ematch_text_get_to_offset@libnl_3 3.5.0-1 + rtnl_ematch_text_set_algo@Base 3.5.0-1 + rtnl_ematch_text_set_algo@libnl_3 3.5.0-1 + rtnl_ematch_text_set_from@Base 3.5.0-1 + rtnl_ematch_text_set_from@libnl_3 3.5.0-1 + rtnl_ematch_text_set_pattern@Base 3.5.0-1 + rtnl_ematch_text_set_pattern@libnl_3 3.5.0-1 + rtnl_ematch_text_set_to@Base 3.5.0-1 + rtnl_ematch_text_set_to@libnl_3 3.5.0-1 + rtnl_ematch_tree_add@Base 3.5.0-1 + rtnl_ematch_tree_add@libnl_3 3.5.0-1 + rtnl_ematch_tree_alloc@Base 3.5.0-1 + rtnl_ematch_tree_alloc@libnl_3 3.5.0-1 + rtnl_ematch_tree_clone@libnl_3_5 3.5.0-1 + rtnl_ematch_tree_dump@Base 3.5.0-1 + rtnl_ematch_tree_dump@libnl_3 3.5.0-1 + rtnl_ematch_tree_free@Base 3.5.0-1 + rtnl_ematch_tree_free@libnl_3 3.5.0-1 + rtnl_ematch_unlink@Base 3.5.0-1 + rtnl_ematch_unlink@libnl_3 3.5.0-1 + rtnl_ematch_unset_flags@Base 3.5.0-1 + rtnl_ematch_unset_flags@libnl_3 3.5.0-1 + rtnl_fw_set_classid@Base 3.5.0-1 + rtnl_fw_set_classid@libnl_3 3.5.0-1 + rtnl_fw_set_mask@Base 3.5.0-1 + rtnl_fw_set_mask@libnl_3 3.5.0-1 + rtnl_gact_get_action@libnl_3_2_29 3.5.0-1 + rtnl_gact_set_action@libnl_3_2_29 3.5.0-1 + rtnl_htb_get_cbuffer@Base 3.5.0-1 + rtnl_htb_get_cbuffer@libnl_3 3.5.0-1 + rtnl_htb_get_ceil64@libnl_3_5 3.5.0-1 + rtnl_htb_get_ceil@Base 3.5.0-1 + rtnl_htb_get_ceil@libnl_3 3.5.0-1 + rtnl_htb_get_defcls@Base 3.5.0-1 + rtnl_htb_get_defcls@libnl_3 3.5.0-1 + rtnl_htb_get_level@Base 3.5.0-1 + rtnl_htb_get_level@libnl_3 3.5.0-1 + rtnl_htb_get_prio@Base 3.5.0-1 + rtnl_htb_get_prio@libnl_3 3.5.0-1 + rtnl_htb_get_quantum@Base 3.5.0-1 + rtnl_htb_get_quantum@libnl_3 3.5.0-1 + rtnl_htb_get_rate2quantum@Base 3.5.0-1 + rtnl_htb_get_rate2quantum@libnl_3 3.5.0-1 + rtnl_htb_get_rate64@libnl_3_5 3.5.0-1 + rtnl_htb_get_rate@Base 3.5.0-1 + rtnl_htb_get_rate@libnl_3 3.5.0-1 + rtnl_htb_get_rbuffer@Base 3.5.0-1 + rtnl_htb_get_rbuffer@libnl_3 3.5.0-1 + rtnl_htb_set_cbuffer@Base 3.5.0-1 + rtnl_htb_set_cbuffer@libnl_3 3.5.0-1 + rtnl_htb_set_ceil64@libnl_3_5 3.5.0-1 + rtnl_htb_set_ceil@Base 3.5.0-1 + rtnl_htb_set_ceil@libnl_3 3.5.0-1 + rtnl_htb_set_defcls@Base 3.5.0-1 + rtnl_htb_set_defcls@libnl_3 3.5.0-1 + rtnl_htb_set_level@Base 3.5.0-1 + rtnl_htb_set_level@libnl_3 3.5.0-1 + rtnl_htb_set_prio@Base 3.5.0-1 + rtnl_htb_set_prio@libnl_3 3.5.0-1 + rtnl_htb_set_quantum@Base 3.5.0-1 + rtnl_htb_set_quantum@libnl_3 3.5.0-1 + rtnl_htb_set_rate2quantum@Base 3.5.0-1 + rtnl_htb_set_rate2quantum@libnl_3 3.5.0-1 + rtnl_htb_set_rate64@libnl_3_5 3.5.0-1 + rtnl_htb_set_rate@Base 3.5.0-1 + rtnl_htb_set_rate@libnl_3 3.5.0-1 + rtnl_htb_set_rbuffer@Base 3.5.0-1 + rtnl_htb_set_rbuffer@libnl_3 3.5.0-1 + rtnl_link_add@Base 3.5.0-1 + rtnl_link_add@libnl_3 3.5.0-1 + rtnl_link_af_alloc@Base 3.5.0-1 + rtnl_link_af_alloc@libnl_3 3.5.0-1 + rtnl_link_af_data@Base 3.5.0-1 + rtnl_link_af_data@libnl_3 3.5.0-1 + rtnl_link_af_data_compare@Base 3.5.0-1 + rtnl_link_af_data_compare@libnl_3 3.5.0-1 + rtnl_link_af_ops_lookup@Base 3.5.0-1 + rtnl_link_af_ops_lookup@libnl_3 3.5.0-1 + rtnl_link_af_ops_put@Base 3.5.0-1 + rtnl_link_af_ops_put@libnl_3 3.5.0-1 + rtnl_link_af_register@Base 3.5.0-1 + rtnl_link_af_register@libnl_3 3.5.0-1 + rtnl_link_af_unregister@Base 3.5.0-1 + rtnl_link_af_unregister@libnl_3 3.5.0-1 + rtnl_link_alloc@Base 3.5.0-1 + rtnl_link_alloc@libnl_3 3.5.0-1 + rtnl_link_alloc_cache@Base 3.5.0-1 + rtnl_link_alloc_cache@libnl_3 3.5.0-1 + rtnl_link_alloc_cache_flags@libnl_3_2_28 3.5.0-1 + rtnl_link_bond_add@Base 3.5.0-1 + rtnl_link_bond_add@libnl_3 3.5.0-1 + rtnl_link_bond_alloc@Base 3.5.0-1 + rtnl_link_bond_alloc@libnl_3 3.5.0-1 + rtnl_link_bond_enslave@Base 3.5.0-1 + rtnl_link_bond_enslave@libnl_3 3.5.0-1 + rtnl_link_bond_enslave_ifindex@Base 3.5.0-1 + rtnl_link_bond_enslave_ifindex@libnl_3 3.5.0-1 + rtnl_link_bond_release@Base 3.5.0-1 + rtnl_link_bond_release@libnl_3 3.5.0-1 + rtnl_link_bond_release_ifindex@Base 3.5.0-1 + rtnl_link_bond_release_ifindex@libnl_3 3.5.0-1 + rtnl_link_bridge_add@Base 3.5.0-1 + rtnl_link_bridge_add@libnl_3 3.5.0-1 + rtnl_link_bridge_alloc@Base 3.5.0-1 + rtnl_link_bridge_alloc@libnl_3 3.5.0-1 + rtnl_link_bridge_flags2str@Base 3.5.0-1 + rtnl_link_bridge_flags2str@libnl_3 3.5.0-1 + rtnl_link_bridge_get_cost@Base 3.5.0-1 + rtnl_link_bridge_get_cost@libnl_3 3.5.0-1 + rtnl_link_bridge_get_flags@Base 3.5.0-1 + rtnl_link_bridge_get_flags@libnl_3 3.5.0-1 + rtnl_link_bridge_get_hwmode@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_get_port_state@Base 3.5.0-1 + rtnl_link_bridge_get_port_state@libnl_3 3.5.0-1 + rtnl_link_bridge_get_port_vlan@libnl_3_2_28 3.5.0-1 + rtnl_link_bridge_get_priority@Base 3.5.0-1 + rtnl_link_bridge_get_priority@libnl_3 3.5.0-1 + rtnl_link_bridge_has_ext_info@Base 3.5.0-1 + rtnl_link_bridge_has_ext_info@libnl_3 3.5.0-1 + rtnl_link_bridge_has_vlan@libnl_3_2_28 3.5.0-1 + rtnl_link_bridge_hwmode2str@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_portstate2str@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_pvid@libnl_3_2_28 3.5.0-1 + rtnl_link_bridge_set_cost@Base 3.5.0-1 + rtnl_link_bridge_set_cost@libnl_3 3.5.0-1 + rtnl_link_bridge_set_flags@Base 3.5.0-1 + rtnl_link_bridge_set_flags@libnl_3 3.5.0-1 + rtnl_link_bridge_set_hwmode@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_set_port_state@Base 3.5.0-1 + rtnl_link_bridge_set_port_state@libnl_3 3.5.0-1 + rtnl_link_bridge_set_priority@Base 3.5.0-1 + rtnl_link_bridge_set_priority@libnl_3 3.5.0-1 + rtnl_link_bridge_set_self@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_str2flags@Base 3.5.0-1 + rtnl_link_bridge_str2flags@libnl_3 3.5.0-1 + rtnl_link_bridge_str2hwmode@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_str2portstate@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_unset_flags@Base 3.5.0-1 + rtnl_link_bridge_unset_flags@libnl_3 3.5.0-1 + rtnl_link_build_add_request@Base 3.5.0-1 + rtnl_link_build_add_request@libnl_3 3.5.0-1 + rtnl_link_build_change_request@Base 3.5.0-1 + rtnl_link_build_change_request@libnl_3 3.5.0-1 + rtnl_link_build_delete_request@Base 3.5.0-1 + rtnl_link_build_delete_request@libnl_3 3.5.0-1 + rtnl_link_build_get_request@Base 3.5.0-1 + rtnl_link_build_get_request@libnl_3 3.5.0-1 + rtnl_link_can_berr@Base 3.5.0-1 + rtnl_link_can_berr@libnl_3 3.5.0-1 + rtnl_link_can_berr_rx@Base 3.5.0-1 + rtnl_link_can_berr_rx@libnl_3 3.5.0-1 + rtnl_link_can_berr_tx@Base 3.5.0-1 + rtnl_link_can_berr_tx@libnl_3 3.5.0-1 + rtnl_link_can_ctrlmode2str@Base 3.5.0-1 + rtnl_link_can_ctrlmode2str@libnl_3 3.5.0-1 + rtnl_link_can_freq@Base 3.5.0-1 + rtnl_link_can_freq@libnl_3 3.5.0-1 + rtnl_link_can_get_bitrate@Base 3.5.0-1 + rtnl_link_can_get_bitrate@libnl_3 3.5.0-1 + rtnl_link_can_get_bittiming@Base 3.5.0-1 + rtnl_link_can_get_bittiming@libnl_3 3.5.0-1 + rtnl_link_can_get_bt_const@Base 3.5.0-1 + rtnl_link_can_get_bt_const@libnl_3 3.5.0-1 + rtnl_link_can_get_ctrlmode@Base 3.5.0-1 + rtnl_link_can_get_ctrlmode@libnl_3 3.5.0-1 + rtnl_link_can_get_restart_ms@Base 3.5.0-1 + rtnl_link_can_get_restart_ms@libnl_3 3.5.0-1 + rtnl_link_can_get_sample_point@Base 3.5.0-1 + rtnl_link_can_get_sample_point@libnl_3 3.5.0-1 + rtnl_link_can_restart@Base 3.5.0-1 + rtnl_link_can_restart@libnl_3 3.5.0-1 + rtnl_link_can_set_bitrate@Base 3.5.0-1 + rtnl_link_can_set_bitrate@libnl_3 3.5.0-1 + rtnl_link_can_set_bittiming@Base 3.5.0-1 + rtnl_link_can_set_bittiming@libnl_3 3.5.0-1 + rtnl_link_can_set_ctrlmode@Base 3.5.0-1 + rtnl_link_can_set_ctrlmode@libnl_3 3.5.0-1 + rtnl_link_can_set_restart_ms@Base 3.5.0-1 + rtnl_link_can_set_restart_ms@libnl_3 3.5.0-1 + rtnl_link_can_set_sample_point@Base 3.5.0-1 + rtnl_link_can_set_sample_point@libnl_3 3.5.0-1 + rtnl_link_can_state@Base 3.5.0-1 + rtnl_link_can_state@libnl_3 3.5.0-1 + rtnl_link_can_str2ctrlmode@Base 3.5.0-1 + rtnl_link_can_str2ctrlmode@libnl_3 3.5.0-1 + rtnl_link_can_unset_ctrlmode@Base 3.5.0-1 + rtnl_link_can_unset_ctrlmode@libnl_3 3.5.0-1 + rtnl_link_carrier2str@Base 3.5.0-1 + rtnl_link_carrier2str@libnl_3 3.5.0-1 + rtnl_link_change@Base 3.5.0-1 + rtnl_link_change@libnl_3 3.5.0-1 + rtnl_link_delete@Base 3.5.0-1 + rtnl_link_delete@libnl_3 3.5.0-1 + rtnl_link_enslave@Base 3.5.0-1 + rtnl_link_enslave@libnl_3 3.5.0-1 + rtnl_link_enslave_ifindex@Base 3.5.0-1 + rtnl_link_enslave_ifindex@libnl_3 3.5.0-1 + rtnl_link_fill_info@Base 3.5.0-1 + rtnl_link_fill_info@libnl_3 3.5.0-1 + rtnl_link_flags2str@Base 3.5.0-1 + rtnl_link_flags2str@libnl_3 3.5.0-1 + rtnl_link_geneve_alloc@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_flags@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_id@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_label@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_port@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_remote@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_tos@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_ttl@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_udp_csum@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_udp_zero_csum6_rx@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_udp_zero_csum6_tx@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_flags@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_id@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_label@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_port@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_remote@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_tos@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_ttl@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_udp_csum@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_udp_zero_csum6_rx@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_udp_zero_csum6_tx@libnl_3_5 3.5.0-1 + rtnl_link_get@Base 3.5.0-1 + rtnl_link_get@libnl_3 3.5.0-1 + rtnl_link_get_addr@Base 3.5.0-1 + rtnl_link_get_addr@libnl_3 3.5.0-1 + rtnl_link_get_arptype@Base 3.5.0-1 + rtnl_link_get_arptype@libnl_3 3.5.0-1 + rtnl_link_get_broadcast@Base 3.5.0-1 + rtnl_link_get_broadcast@libnl_3 3.5.0-1 + rtnl_link_get_by_name@Base 3.5.0-1 + rtnl_link_get_by_name@libnl_3 3.5.0-1 + rtnl_link_get_carrier@Base 3.5.0-1 + rtnl_link_get_carrier@libnl_3 3.5.0-1 + rtnl_link_get_carrier_changes@libnl_3_2_29 3.5.0-1 + rtnl_link_get_family@Base 3.5.0-1 + rtnl_link_get_family@libnl_3 3.5.0-1 + rtnl_link_get_flags@Base 3.5.0-1 + rtnl_link_get_flags@libnl_3 3.5.0-1 + rtnl_link_get_group@Base 3.5.0-1 + rtnl_link_get_group@libnl_3 3.5.0-1 + rtnl_link_get_gso_max_segs@libnl_3_2_29 3.5.0-1 + rtnl_link_get_gso_max_size@libnl_3_2_29 3.5.0-1 + rtnl_link_get_ifalias@Base 3.5.0-1 + rtnl_link_get_ifalias@libnl_3 3.5.0-1 + rtnl_link_get_ifindex@Base 3.5.0-1 + rtnl_link_get_ifindex@libnl_3 3.5.0-1 + rtnl_link_get_info_type@Base 3.5.0-1 + rtnl_link_get_info_type@libnl_3 3.5.0-1 + rtnl_link_get_kernel@Base 3.5.0-1 + rtnl_link_get_kernel@libnl_3 3.5.0-1 + rtnl_link_get_link@Base 3.5.0-1 + rtnl_link_get_link@libnl_3 3.5.0-1 + rtnl_link_get_link_netnsid@Base 3.5.0-1 + rtnl_link_get_link_netnsid@libnl_3_2_27 3.5.0-1 + rtnl_link_get_linkmode@Base 3.5.0-1 + rtnl_link_get_linkmode@libnl_3 3.5.0-1 + rtnl_link_get_master@Base 3.5.0-1 + rtnl_link_get_master@libnl_3 3.5.0-1 + rtnl_link_get_mtu@Base 3.5.0-1 + rtnl_link_get_mtu@libnl_3 3.5.0-1 + rtnl_link_get_name@Base 3.5.0-1 + rtnl_link_get_name@libnl_3 3.5.0-1 + rtnl_link_get_ns_fd@Base 3.5.0-1 + rtnl_link_get_ns_fd@libnl_3 3.5.0-1 + rtnl_link_get_ns_pid@Base 3.5.0-1 + rtnl_link_get_ns_pid@libnl_3 3.5.0-1 + rtnl_link_get_num_rx_queues@Base 3.5.0-1 + rtnl_link_get_num_rx_queues@libnl_3 3.5.0-1 + rtnl_link_get_num_tx_queues@Base 3.5.0-1 + rtnl_link_get_num_tx_queues@libnl_3 3.5.0-1 + rtnl_link_get_num_vf@Base 3.5.0-1 + rtnl_link_get_num_vf@libnl_3 3.5.0-1 + rtnl_link_get_operstate@Base 3.5.0-1 + rtnl_link_get_operstate@libnl_3 3.5.0-1 + rtnl_link_get_phys_port_id@Base 3.5.0-1 + rtnl_link_get_phys_port_id@libnl_3 3.5.0-1 + rtnl_link_get_phys_port_name@libnl_3_2_29 3.5.0-1 + rtnl_link_get_phys_switch_id@libnl_3_2_29 3.5.0-1 + rtnl_link_get_pmtudisc@Base 3.5.0-1 + rtnl_link_get_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_get_promiscuity@Base 3.5.0-1 + rtnl_link_get_promiscuity@libnl_3 3.5.0-1 + rtnl_link_get_qdisc@Base 3.5.0-1 + rtnl_link_get_qdisc@libnl_3 3.5.0-1 + rtnl_link_get_slave_type@libnl_3_5 3.5.0-1 + rtnl_link_get_stat@Base 3.5.0-1 + rtnl_link_get_stat@libnl_3 3.5.0-1 + rtnl_link_get_txqlen@Base 3.5.0-1 + rtnl_link_get_txqlen@libnl_3 3.5.0-1 + rtnl_link_get_type@Base 3.5.0-1 + rtnl_link_get_type@libnl_3 3.5.0-1 + rtnl_link_get_weight@Base 3.5.0-1 + rtnl_link_get_weight@libnl_3 3.5.0-1 + rtnl_link_has_vf_list@libnl_3_2_29 3.5.0-1 + rtnl_link_i2name@Base 3.5.0-1 + rtnl_link_i2name@libnl_3 3.5.0-1 + rtnl_link_inet6_addrgenmode2str@Base 3.5.0-1 + rtnl_link_inet6_addrgenmode2str@libnl_3 3.5.0-1 + rtnl_link_inet6_flags2str@libnl_3_4 3.5.0-1 + rtnl_link_inet6_get_addr_gen_mode@Base 3.5.0-1 + rtnl_link_inet6_get_addr_gen_mode@libnl_3 3.5.0-1 + rtnl_link_inet6_get_flags@libnl_3_4 3.5.0-1 + rtnl_link_inet6_get_token@Base 3.5.0-1 + rtnl_link_inet6_get_token@libnl_3 3.5.0-1 + rtnl_link_inet6_set_addr_gen_mode@Base 3.5.0-1 + rtnl_link_inet6_set_addr_gen_mode@libnl_3 3.5.0-1 + rtnl_link_inet6_set_flags@libnl_3_4 3.5.0-1 + rtnl_link_inet6_set_token@Base 3.5.0-1 + rtnl_link_inet6_set_token@libnl_3 3.5.0-1 + rtnl_link_inet6_str2addrgenmode@Base 3.5.0-1 + rtnl_link_inet6_str2addrgenmode@libnl_3 3.5.0-1 + rtnl_link_inet6_str2flags@libnl_3_4 3.5.0-1 + rtnl_link_inet_devconf2str@Base 3.5.0-1 + rtnl_link_inet_devconf2str@libnl_3 3.5.0-1 + rtnl_link_inet_get_conf@Base 3.5.0-1 + rtnl_link_inet_get_conf@libnl_3 3.5.0-1 + rtnl_link_inet_set_conf@Base 3.5.0-1 + rtnl_link_inet_set_conf@libnl_3 3.5.0-1 + rtnl_link_inet_str2devconf@Base 3.5.0-1 + rtnl_link_inet_str2devconf@libnl_3 3.5.0-1 + rtnl_link_info_ops_lookup@Base 3.5.0-1 + rtnl_link_info_ops_lookup@libnl_3 3.5.0-1 + rtnl_link_info_ops_put@Base 3.5.0-1 + rtnl_link_info_ops_put@libnl_3 3.5.0-1 + rtnl_link_info_parse@Base 3.5.0-1 + rtnl_link_info_parse@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_add@Base 3.5.0-1 + rtnl_link_ip6_tnl_add@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_alloc@Base 3.5.0-1 + rtnl_link_ip6_tnl_alloc@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_encaplimit@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_encaplimit@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_flags@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_flags@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_flowinfo@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_flowinfo@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_link@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_link@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_local@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_local@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_proto@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_proto@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_remote@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_remote@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_tos@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_tos@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_ttl@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_ttl@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_encaplimit@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_encaplimit@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_flags@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_flags@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_flowinfo@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_flowinfo@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_link@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_link@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_local@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_local@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_proto@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_proto@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_remote@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_remote@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_tos@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_tos@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_ttl@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_ttl@libnl_3 3.5.0-1 + rtnl_link_ipgre_add@Base 3.5.0-1 + rtnl_link_ipgre_add@libnl_3 3.5.0-1 + rtnl_link_ipgre_alloc@Base 3.5.0-1 + rtnl_link_ipgre_alloc@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_iflags@Base 3.5.0-1 + rtnl_link_ipgre_get_iflags@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_ikey@Base 3.5.0-1 + rtnl_link_ipgre_get_ikey@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_link@Base 3.5.0-1 + rtnl_link_ipgre_get_link@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_local@Base 3.5.0-1 + rtnl_link_ipgre_get_local@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_oflags@Base 3.5.0-1 + rtnl_link_ipgre_get_oflags@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_okey@Base 3.5.0-1 + rtnl_link_ipgre_get_okey@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_pmtudisc@libnl_3_2_29 3.5.0-1 + rtnl_link_ipgre_get_remote@Base 3.5.0-1 + rtnl_link_ipgre_get_remote@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_tos@Base 3.5.0-1 + rtnl_link_ipgre_get_tos@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_ttl@Base 3.5.0-1 + rtnl_link_ipgre_get_ttl@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_iflags@Base 3.5.0-1 + rtnl_link_ipgre_set_iflags@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_ikey@Base 3.5.0-1 + rtnl_link_ipgre_set_ikey@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_link@Base 3.5.0-1 + rtnl_link_ipgre_set_link@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_local@Base 3.5.0-1 + rtnl_link_ipgre_set_local@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_oflags@Base 3.5.0-1 + rtnl_link_ipgre_set_oflags@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_okey@Base 3.5.0-1 + rtnl_link_ipgre_set_okey@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_pmtudisc@Base 3.5.0-1 + rtnl_link_ipgre_set_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_remote@Base 3.5.0-1 + rtnl_link_ipgre_set_remote@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_tos@Base 3.5.0-1 + rtnl_link_ipgre_set_tos@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_ttl@Base 3.5.0-1 + rtnl_link_ipgre_set_ttl@libnl_3 3.5.0-1 + rtnl_link_ipgretap_add@libnl_3_2_28 3.5.0-1 + rtnl_link_ipgretap_alloc@libnl_3_2_28 3.5.0-1 + rtnl_link_ipip_add@Base 3.5.0-1 + rtnl_link_ipip_add@libnl_3 3.5.0-1 + rtnl_link_ipip_alloc@Base 3.5.0-1 + rtnl_link_ipip_alloc@libnl_3 3.5.0-1 + rtnl_link_ipip_get_link@Base 3.5.0-1 + rtnl_link_ipip_get_link@libnl_3 3.5.0-1 + rtnl_link_ipip_get_local@Base 3.5.0-1 + rtnl_link_ipip_get_local@libnl_3 3.5.0-1 + rtnl_link_ipip_get_pmtudisc@Base 3.5.0-1 + rtnl_link_ipip_get_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_ipip_get_remote@Base 3.5.0-1 + rtnl_link_ipip_get_remote@libnl_3 3.5.0-1 + rtnl_link_ipip_get_tos@Base 3.5.0-1 + rtnl_link_ipip_get_tos@libnl_3 3.5.0-1 + rtnl_link_ipip_get_ttl@Base 3.5.0-1 + rtnl_link_ipip_get_ttl@libnl_3 3.5.0-1 + rtnl_link_ipip_set_link@Base 3.5.0-1 + rtnl_link_ipip_set_link@libnl_3 3.5.0-1 + rtnl_link_ipip_set_local@Base 3.5.0-1 + rtnl_link_ipip_set_local@libnl_3 3.5.0-1 + rtnl_link_ipip_set_pmtudisc@Base 3.5.0-1 + rtnl_link_ipip_set_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_ipip_set_remote@Base 3.5.0-1 + rtnl_link_ipip_set_remote@libnl_3 3.5.0-1 + rtnl_link_ipip_set_tos@Base 3.5.0-1 + rtnl_link_ipip_set_tos@libnl_3 3.5.0-1 + rtnl_link_ipip_set_ttl@Base 3.5.0-1 + rtnl_link_ipip_set_ttl@libnl_3 3.5.0-1 + rtnl_link_ipvlan_alloc@Base 3.5.0-1 + rtnl_link_ipvlan_alloc@libnl_3_2_27 3.5.0-1 + rtnl_link_ipvlan_get_mode@Base 3.5.0-1 + rtnl_link_ipvlan_get_mode@libnl_3_2_27 3.5.0-1 + rtnl_link_ipvlan_mode2str@Base 3.5.0-1 + rtnl_link_ipvlan_mode2str@libnl_3_2_27 3.5.0-1 + rtnl_link_ipvlan_set_mode@Base 3.5.0-1 + rtnl_link_ipvlan_set_mode@libnl_3_2_27 3.5.0-1 + rtnl_link_ipvlan_str2mode@Base 3.5.0-1 + rtnl_link_ipvlan_str2mode@libnl_3_2_27 3.5.0-1 + rtnl_link_ipvti_add@Base 3.5.0-1 + rtnl_link_ipvti_add@libnl_3 3.5.0-1 + rtnl_link_ipvti_alloc@Base 3.5.0-1 + rtnl_link_ipvti_alloc@libnl_3 3.5.0-1 + rtnl_link_ipvti_get_ikey@Base 3.5.0-1 + rtnl_link_ipvti_get_ikey@libnl_3 3.5.0-1 + rtnl_link_ipvti_get_link@Base 3.5.0-1 + rtnl_link_ipvti_get_link@libnl_3 3.5.0-1 + rtnl_link_ipvti_get_local@Base 3.5.0-1 + rtnl_link_ipvti_get_local@libnl_3 3.5.0-1 + rtnl_link_ipvti_get_okey@Base 3.5.0-1 + rtnl_link_ipvti_get_okey@libnl_3 3.5.0-1 + rtnl_link_ipvti_get_remote@Base 3.5.0-1 + rtnl_link_ipvti_get_remote@libnl_3 3.5.0-1 + rtnl_link_ipvti_set_ikey@Base 3.5.0-1 + rtnl_link_ipvti_set_ikey@libnl_3 3.5.0-1 + rtnl_link_ipvti_set_link@Base 3.5.0-1 + rtnl_link_ipvti_set_link@libnl_3 3.5.0-1 + rtnl_link_ipvti_set_local@Base 3.5.0-1 + rtnl_link_ipvti_set_local@libnl_3 3.5.0-1 + rtnl_link_ipvti_set_okey@Base 3.5.0-1 + rtnl_link_ipvti_set_okey@libnl_3 3.5.0-1 + rtnl_link_ipvti_set_remote@Base 3.5.0-1 + rtnl_link_ipvti_set_remote@libnl_3 3.5.0-1 + rtnl_link_is_bridge@Base 3.5.0-1 + rtnl_link_is_bridge@libnl_3 3.5.0-1 + rtnl_link_is_can@Base 3.5.0-1 + rtnl_link_is_can@libnl_3 3.5.0-1 + rtnl_link_is_geneve@libnl_3_5 3.5.0-1 + rtnl_link_is_ip6_tnl@Base 3.5.0-1 + rtnl_link_is_ip6_tnl@libnl_3 3.5.0-1 + rtnl_link_is_ipgre@Base 3.5.0-1 + rtnl_link_is_ipgre@libnl_3 3.5.0-1 + rtnl_link_is_ipgretap@libnl_3_2_29 3.5.0-1 + rtnl_link_is_ipip@Base 3.5.0-1 + rtnl_link_is_ipip@libnl_3 3.5.0-1 + rtnl_link_is_ipvlan@Base 3.5.0-1 + rtnl_link_is_ipvlan@libnl_3_2_27 3.5.0-1 + rtnl_link_is_ipvti@Base 3.5.0-1 + rtnl_link_is_ipvti@libnl_3 3.5.0-1 + rtnl_link_is_macvlan@Base 3.5.0-1 + rtnl_link_is_macvlan@libnl_3 3.5.0-1 + rtnl_link_is_macvtap@libnl_3_2_28 3.5.0-1 + rtnl_link_is_sit@Base 3.5.0-1 + rtnl_link_is_sit@libnl_3 3.5.0-1 + rtnl_link_is_veth@Base 3.5.0-1 + rtnl_link_is_veth@libnl_3 3.5.0-1 + rtnl_link_is_vlan@Base 3.5.0-1 + rtnl_link_is_vlan@libnl_3 3.5.0-1 + rtnl_link_is_vrf@libnl_3_2_28 3.5.0-1 + rtnl_link_is_vxlan@Base 3.5.0-1 + rtnl_link_is_vxlan@libnl_3 3.5.0-1 + rtnl_link_is_xfrmi@libnl_3_5 3.5.0-1 + rtnl_link_macsec_alloc@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_cipher_suite@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_encoding_sa@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_encrypt@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_end_station@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_icv_len@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_port@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_protect@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_replay_protect@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_scb@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_sci@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_send_sci@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_validation_type@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_window@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_cipher_suite@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_encoding_sa@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_encrypt@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_end_station@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_icv_len@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_port@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_protect@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_replay_protect@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_scb@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_sci@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_send_sci@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_validation_type@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_window@libnl_3_2_28 3.5.0-1 + rtnl_link_macvlan_add_macaddr@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_alloc@Base 3.5.0-1 + rtnl_link_macvlan_alloc@libnl_3 3.5.0-1 + rtnl_link_macvlan_count_macaddr@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_del_macaddr@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_flags2str@Base 3.5.0-1 + rtnl_link_macvlan_flags2str@libnl_3 3.5.0-1 + rtnl_link_macvlan_get_flags@Base 3.5.0-1 + rtnl_link_macvlan_get_flags@libnl_3 3.5.0-1 + rtnl_link_macvlan_get_macaddr@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_get_macmode@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_get_mode@Base 3.5.0-1 + rtnl_link_macvlan_get_mode@libnl_3 3.5.0-1 + rtnl_link_macvlan_macmode2str@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_mode2str@Base 3.5.0-1 + rtnl_link_macvlan_mode2str@libnl_3 3.5.0-1 + rtnl_link_macvlan_set_flags@Base 3.5.0-1 + rtnl_link_macvlan_set_flags@libnl_3 3.5.0-1 + rtnl_link_macvlan_set_macmode@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_set_mode@Base 3.5.0-1 + rtnl_link_macvlan_set_mode@libnl_3 3.5.0-1 + rtnl_link_macvlan_str2flags@Base 3.5.0-1 + rtnl_link_macvlan_str2flags@libnl_3 3.5.0-1 + rtnl_link_macvlan_str2macmode@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_str2mode@Base 3.5.0-1 + rtnl_link_macvlan_str2mode@libnl_3 3.5.0-1 + rtnl_link_macvlan_unset_flags@Base 3.5.0-1 + rtnl_link_macvlan_unset_flags@libnl_3 3.5.0-1 + rtnl_link_macvtap_alloc@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_flags2str@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_get_flags@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_get_mode@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_mode2str@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_set_flags@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_set_mode@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_str2flags@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_str2mode@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_unset_flags@libnl_3_2_28 3.5.0-1 + rtnl_link_mode2str@Base 3.5.0-1 + rtnl_link_mode2str@libnl_3 3.5.0-1 + rtnl_link_name2i@Base 3.5.0-1 + rtnl_link_name2i@libnl_3 3.5.0-1 + rtnl_link_operstate2str@Base 3.5.0-1 + rtnl_link_operstate2str@libnl_3 3.5.0-1 + rtnl_link_ppp_alloc@libnl_3_2_29 3.5.0-1 + rtnl_link_ppp_get_fd@libnl_3_2_29 3.5.0-1 + rtnl_link_ppp_set_fd@libnl_3_2_29 3.5.0-1 + rtnl_link_put@Base 3.5.0-1 + rtnl_link_put@libnl_3 3.5.0-1 + rtnl_link_register_info@Base 3.5.0-1 + rtnl_link_register_info@libnl_3 3.5.0-1 + rtnl_link_release@Base 3.5.0-1 + rtnl_link_release@libnl_3 3.5.0-1 + rtnl_link_release_ifindex@Base 3.5.0-1 + rtnl_link_release_ifindex@libnl_3 3.5.0-1 + rtnl_link_set_addr@Base 3.5.0-1 + rtnl_link_set_addr@libnl_3 3.5.0-1 + rtnl_link_set_arptype@Base 3.5.0-1 + rtnl_link_set_arptype@libnl_3 3.5.0-1 + rtnl_link_set_broadcast@Base 3.5.0-1 + rtnl_link_set_broadcast@libnl_3 3.5.0-1 + rtnl_link_set_carrier@Base 3.5.0-1 + rtnl_link_set_carrier@libnl_3 3.5.0-1 + rtnl_link_set_family@Base 3.5.0-1 + rtnl_link_set_family@libnl_3 3.5.0-1 + rtnl_link_set_flags@Base 3.5.0-1 + rtnl_link_set_flags@libnl_3 3.5.0-1 + rtnl_link_set_group@Base 3.5.0-1 + rtnl_link_set_group@libnl_3 3.5.0-1 + rtnl_link_set_ifalias@Base 3.5.0-1 + rtnl_link_set_ifalias@libnl_3 3.5.0-1 + rtnl_link_set_ifindex@Base 3.5.0-1 + rtnl_link_set_ifindex@libnl_3 3.5.0-1 + rtnl_link_set_info_type@Base 3.5.0-1 + rtnl_link_set_info_type@libnl_3 3.5.0-1 + rtnl_link_set_link@Base 3.5.0-1 + rtnl_link_set_link@libnl_3 3.5.0-1 + rtnl_link_set_link_netnsid@Base 3.5.0-1 + rtnl_link_set_link_netnsid@libnl_3_2_27 3.5.0-1 + rtnl_link_set_linkmode@Base 3.5.0-1 + rtnl_link_set_linkmode@libnl_3 3.5.0-1 + rtnl_link_set_master@Base 3.5.0-1 + rtnl_link_set_master@libnl_3 3.5.0-1 + rtnl_link_set_mtu@Base 3.5.0-1 + rtnl_link_set_mtu@libnl_3 3.5.0-1 + rtnl_link_set_name@Base 3.5.0-1 + rtnl_link_set_name@libnl_3 3.5.0-1 + rtnl_link_set_ns_fd@Base 3.5.0-1 + rtnl_link_set_ns_fd@libnl_3 3.5.0-1 + rtnl_link_set_ns_pid@Base 3.5.0-1 + rtnl_link_set_ns_pid@libnl_3 3.5.0-1 + rtnl_link_set_num_rx_queues@Base 3.5.0-1 + rtnl_link_set_num_rx_queues@libnl_3 3.5.0-1 + rtnl_link_set_num_tx_queues@Base 3.5.0-1 + rtnl_link_set_num_tx_queues@libnl_3 3.5.0-1 + rtnl_link_set_operstate@Base 3.5.0-1 + rtnl_link_set_operstate@libnl_3 3.5.0-1 + rtnl_link_set_promiscuity@Base 3.5.0-1 + rtnl_link_set_promiscuity@libnl_3 3.5.0-1 + rtnl_link_set_qdisc@Base 3.5.0-1 + rtnl_link_set_qdisc@libnl_3 3.5.0-1 + rtnl_link_set_slave_type@libnl_3_5 3.5.0-1 + rtnl_link_set_stat@Base 3.5.0-1 + rtnl_link_set_stat@libnl_3 3.5.0-1 + rtnl_link_set_txqlen@Base 3.5.0-1 + rtnl_link_set_txqlen@libnl_3 3.5.0-1 + rtnl_link_set_type@Base 3.5.0-1 + rtnl_link_set_type@libnl_3 3.5.0-1 + rtnl_link_set_vf_list@libnl_3_2_29 3.5.0-1 + rtnl_link_set_weight@Base 3.5.0-1 + rtnl_link_set_weight@libnl_3 3.5.0-1 + rtnl_link_sit_add@Base 3.5.0-1 + rtnl_link_sit_add@libnl_3 3.5.0-1 + rtnl_link_sit_alloc@Base 3.5.0-1 + rtnl_link_sit_alloc@libnl_3 3.5.0-1 + rtnl_link_sit_get_flags@Base 3.5.0-1 + rtnl_link_sit_get_flags@libnl_3 3.5.0-1 + rtnl_link_sit_get_ip6rd_prefix@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_get_ip6rd_prefixlen@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_get_ip6rd_relay_prefix@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_get_ip6rd_relay_prefixlen@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_get_link@Base 3.5.0-1 + rtnl_link_sit_get_link@libnl_3 3.5.0-1 + rtnl_link_sit_get_local@Base 3.5.0-1 + rtnl_link_sit_get_local@libnl_3 3.5.0-1 + rtnl_link_sit_get_pmtudisc@Base 3.5.0-1 + rtnl_link_sit_get_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_sit_get_proto@Base 3.5.0-1 + rtnl_link_sit_get_proto@libnl_3 3.5.0-1 + rtnl_link_sit_get_remote@Base 3.5.0-1 + rtnl_link_sit_get_remote@libnl_3 3.5.0-1 + rtnl_link_sit_get_tos@Base 3.5.0-1 + rtnl_link_sit_get_tos@libnl_3 3.5.0-1 + rtnl_link_sit_get_ttl@Base 3.5.0-1 + rtnl_link_sit_get_ttl@libnl_3 3.5.0-1 + rtnl_link_sit_set_flags@Base 3.5.0-1 + rtnl_link_sit_set_flags@libnl_3 3.5.0-1 + rtnl_link_sit_set_ip6rd_prefix@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_set_ip6rd_prefixlen@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_set_ip6rd_relay_prefix@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_set_ip6rd_relay_prefixlen@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_set_link@Base 3.5.0-1 + rtnl_link_sit_set_link@libnl_3 3.5.0-1 + rtnl_link_sit_set_local@Base 3.5.0-1 + rtnl_link_sit_set_local@libnl_3 3.5.0-1 + rtnl_link_sit_set_pmtudisc@Base 3.5.0-1 + rtnl_link_sit_set_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_sit_set_proto@Base 3.5.0-1 + rtnl_link_sit_set_proto@libnl_3 3.5.0-1 + rtnl_link_sit_set_remote@Base 3.5.0-1 + rtnl_link_sit_set_remote@libnl_3 3.5.0-1 + rtnl_link_sit_set_tos@Base 3.5.0-1 + rtnl_link_sit_set_tos@libnl_3 3.5.0-1 + rtnl_link_sit_set_ttl@Base 3.5.0-1 + rtnl_link_sit_set_ttl@libnl_3 3.5.0-1 + rtnl_link_stat2str@Base 3.5.0-1 + rtnl_link_stat2str@libnl_3 3.5.0-1 + rtnl_link_str2carrier@Base 3.5.0-1 + rtnl_link_str2carrier@libnl_3 3.5.0-1 + rtnl_link_str2flags@Base 3.5.0-1 + rtnl_link_str2flags@libnl_3 3.5.0-1 + rtnl_link_str2mode@Base 3.5.0-1 + rtnl_link_str2mode@libnl_3 3.5.0-1 + rtnl_link_str2operstate@Base 3.5.0-1 + rtnl_link_str2operstate@libnl_3 3.5.0-1 + rtnl_link_str2stat@Base 3.5.0-1 + rtnl_link_str2stat@libnl_3 3.5.0-1 + rtnl_link_unregister_info@Base 3.5.0-1 + rtnl_link_unregister_info@libnl_3 3.5.0-1 + rtnl_link_unset_flags@Base 3.5.0-1 + rtnl_link_unset_flags@libnl_3 3.5.0-1 + rtnl_link_unset_vf_list@libnl_3_2_29 3.5.0-1 + rtnl_link_veth_add@Base 3.5.0-1 + rtnl_link_veth_add@libnl_3 3.5.0-1 + rtnl_link_veth_alloc@Base 3.5.0-1 + rtnl_link_veth_alloc@libnl_3 3.5.0-1 + rtnl_link_veth_get_peer@Base 3.5.0-1 + rtnl_link_veth_get_peer@libnl_3 3.5.0-1 + rtnl_link_veth_release@Base 3.5.0-1 + rtnl_link_veth_release@libnl_3 3.5.0-1 + rtnl_link_vf_add@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_alloc@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_free@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_addr@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_index@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_linkstate@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_rate@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_rss_query_en@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_spoofchk@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_stat@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_trust@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_vlans@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_linkstate2str@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_put@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_addr@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_ib_node_guid@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_ib_port_guid@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_index@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_linkstate@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_rate@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_rss_query_en@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_spoofchk@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_trust@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_vlans@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_str2guid@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_str2linkstate@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_str2vlanproto@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_vlan_alloc@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_vlan_free@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_vlan_put@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_vlanproto2str@libnl_3_2_29 3.5.0-1 + rtnl_link_vlan_alloc@Base 3.5.0-1 + rtnl_link_vlan_alloc@libnl_3 3.5.0-1 + rtnl_link_vlan_flags2str@Base 3.5.0-1 + rtnl_link_vlan_flags2str@libnl_3 3.5.0-1 + rtnl_link_vlan_get_egress_map@Base 3.5.0-1 + rtnl_link_vlan_get_egress_map@libnl_3 3.5.0-1 + rtnl_link_vlan_get_flags@Base 3.5.0-1 + rtnl_link_vlan_get_flags@libnl_3 3.5.0-1 + rtnl_link_vlan_get_id@Base 3.5.0-1 + rtnl_link_vlan_get_id@libnl_3 3.5.0-1 + rtnl_link_vlan_get_ingress_map@Base 3.5.0-1 + rtnl_link_vlan_get_ingress_map@libnl_3 3.5.0-1 + rtnl_link_vlan_get_protocol@Base 3.5.0-1 + rtnl_link_vlan_get_protocol@libnl_3 3.5.0-1 + rtnl_link_vlan_set_egress_map@Base 3.5.0-1 + rtnl_link_vlan_set_egress_map@libnl_3 3.5.0-1 + rtnl_link_vlan_set_flags@Base 3.5.0-1 + rtnl_link_vlan_set_flags@libnl_3 3.5.0-1 + rtnl_link_vlan_set_id@Base 3.5.0-1 + rtnl_link_vlan_set_id@libnl_3 3.5.0-1 + rtnl_link_vlan_set_ingress_map@Base 3.5.0-1 + rtnl_link_vlan_set_ingress_map@libnl_3 3.5.0-1 + rtnl_link_vlan_set_protocol@Base 3.5.0-1 + rtnl_link_vlan_set_protocol@libnl_3 3.5.0-1 + rtnl_link_vlan_str2flags@Base 3.5.0-1 + rtnl_link_vlan_str2flags@libnl_3 3.5.0-1 + rtnl_link_vlan_unset_flags@Base 3.5.0-1 + rtnl_link_vlan_unset_flags@libnl_3 3.5.0-1 + rtnl_link_vrf_alloc@libnl_3_2_28 3.5.0-1 + rtnl_link_vrf_get_tableid@libnl_3_2_28 3.5.0-1 + rtnl_link_vrf_set_tableid@libnl_3_2_28 3.5.0-1 + rtnl_link_vxlan_alloc@Base 3.5.0-1 + rtnl_link_vxlan_alloc@libnl_3 3.5.0-1 + rtnl_link_vxlan_disable_l2miss@Base 3.5.0-1 + rtnl_link_vxlan_disable_l2miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_disable_l3miss@Base 3.5.0-1 + rtnl_link_vxlan_disable_l3miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_disable_learning@Base 3.5.0-1 + rtnl_link_vxlan_disable_learning@libnl_3 3.5.0-1 + rtnl_link_vxlan_disable_proxy@Base 3.5.0-1 + rtnl_link_vxlan_disable_proxy@libnl_3 3.5.0-1 + rtnl_link_vxlan_disable_rsc@Base 3.5.0-1 + rtnl_link_vxlan_disable_rsc@libnl_3 3.5.0-1 + rtnl_link_vxlan_enable_l2miss@Base 3.5.0-1 + rtnl_link_vxlan_enable_l2miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_enable_l3miss@Base 3.5.0-1 + rtnl_link_vxlan_enable_l3miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_enable_learning@Base 3.5.0-1 + rtnl_link_vxlan_enable_learning@libnl_3 3.5.0-1 + rtnl_link_vxlan_enable_proxy@Base 3.5.0-1 + rtnl_link_vxlan_enable_proxy@libnl_3 3.5.0-1 + rtnl_link_vxlan_enable_rsc@Base 3.5.0-1 + rtnl_link_vxlan_enable_rsc@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_ageing@Base 3.5.0-1 + rtnl_link_vxlan_get_ageing@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_collect_metadata@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_flags@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_group@Base 3.5.0-1 + rtnl_link_vxlan_get_group@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_id@Base 3.5.0-1 + rtnl_link_vxlan_get_id@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_l2miss@Base 3.5.0-1 + rtnl_link_vxlan_get_l2miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_l3miss@Base 3.5.0-1 + rtnl_link_vxlan_get_l3miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_label@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_learning@Base 3.5.0-1 + rtnl_link_vxlan_get_learning@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_limit@Base 3.5.0-1 + rtnl_link_vxlan_get_limit@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_link@Base 3.5.0-1 + rtnl_link_vxlan_get_link@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_local@Base 3.5.0-1 + rtnl_link_vxlan_get_local@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_port@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_port_range@Base 3.5.0-1 + rtnl_link_vxlan_get_port_range@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_proxy@Base 3.5.0-1 + rtnl_link_vxlan_get_proxy@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_remcsum_rx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_remcsum_tx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_rsc@Base 3.5.0-1 + rtnl_link_vxlan_get_rsc@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_tos@Base 3.5.0-1 + rtnl_link_vxlan_get_tos@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_ttl@Base 3.5.0-1 + rtnl_link_vxlan_get_ttl@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_udp_csum@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_udp_zero_csum6_rx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_udp_zero_csum6_tx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_ageing@Base 3.5.0-1 + rtnl_link_vxlan_set_ageing@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_collect_metadata@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_flags@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_group@Base 3.5.0-1 + rtnl_link_vxlan_set_group@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_id@Base 3.5.0-1 + rtnl_link_vxlan_set_id@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_l2miss@Base 3.5.0-1 + rtnl_link_vxlan_set_l2miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_l3miss@Base 3.5.0-1 + rtnl_link_vxlan_set_l3miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_label@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_learning@Base 3.5.0-1 + rtnl_link_vxlan_set_learning@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_limit@Base 3.5.0-1 + rtnl_link_vxlan_set_limit@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_link@Base 3.5.0-1 + rtnl_link_vxlan_set_link@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_local@Base 3.5.0-1 + rtnl_link_vxlan_set_local@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_port@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_port_range@Base 3.5.0-1 + rtnl_link_vxlan_set_port_range@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_proxy@Base 3.5.0-1 + rtnl_link_vxlan_set_proxy@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_remcsum_rx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_remcsum_tx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_rsc@Base 3.5.0-1 + rtnl_link_vxlan_set_rsc@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_tos@Base 3.5.0-1 + rtnl_link_vxlan_set_tos@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_ttl@Base 3.5.0-1 + rtnl_link_vxlan_set_ttl@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_udp_csum@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_udp_zero_csum6_rx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_udp_zero_csum6_tx@libnl_3_2_29 3.5.0-1 + rtnl_link_xfrmi_alloc@libnl_3_5 3.5.0-1 + rtnl_link_xfrmi_get_if_id@libnl_3_5 3.5.0-1 + rtnl_link_xfrmi_get_link@libnl_3_5 3.5.0-1 + rtnl_link_xfrmi_set_if_id@libnl_3_5 3.5.0-1 + rtnl_link_xfrmi_set_link@libnl_3_5 3.5.0-1 + rtnl_mall_append_action@libnl_3_5 3.5.0-1 + rtnl_mall_del_action@libnl_3_5 3.5.0-1 + rtnl_mall_get_classid@libnl_3_5 3.5.0-1 + rtnl_mall_get_first_action@libnl_3_5 3.5.0-1 + rtnl_mall_get_flags@libnl_3_5 3.5.0-1 + rtnl_mall_set_classid@libnl_3_5 3.5.0-1 + rtnl_mall_set_flags@libnl_3_5 3.5.0-1 + rtnl_meta_value_alloc_id@Base 3.5.0-1 + rtnl_meta_value_alloc_id@libnl_3 3.5.0-1 + rtnl_meta_value_alloc_int@Base 3.5.0-1 + rtnl_meta_value_alloc_int@libnl_3 3.5.0-1 + rtnl_meta_value_alloc_var@Base 3.5.0-1 + rtnl_meta_value_alloc_var@libnl_3 3.5.0-1 + rtnl_meta_value_put@Base 3.5.0-1 + rtnl_meta_value_put@libnl_3 3.5.0-1 + rtnl_mirred_get_action@Base 3.5.0-1 + rtnl_mirred_get_action@libnl_3 3.5.0-1 + rtnl_mirred_get_ifindex@Base 3.5.0-1 + rtnl_mirred_get_ifindex@libnl_3 3.5.0-1 + rtnl_mirred_get_policy@Base 3.5.0-1 + rtnl_mirred_get_policy@libnl_3 3.5.0-1 + rtnl_mirred_set_action@Base 3.5.0-1 + rtnl_mirred_set_action@libnl_3 3.5.0-1 + rtnl_mirred_set_ifindex@Base 3.5.0-1 + rtnl_mirred_set_ifindex@libnl_3 3.5.0-1 + rtnl_mirred_set_policy@Base 3.5.0-1 + rtnl_mirred_set_policy@libnl_3 3.5.0-1 + rtnl_neigh_add@Base 3.5.0-1 + rtnl_neigh_add@libnl_3 3.5.0-1 + rtnl_neigh_alloc@Base 3.5.0-1 + rtnl_neigh_alloc@libnl_3 3.5.0-1 + rtnl_neigh_alloc_cache@Base 3.5.0-1 + rtnl_neigh_alloc_cache@libnl_3 3.5.0-1 + rtnl_neigh_alloc_cache_flags@libnl_3_2_28 3.5.0-1 + rtnl_neigh_build_add_request@Base 3.5.0-1 + rtnl_neigh_build_add_request@libnl_3 3.5.0-1 + rtnl_neigh_build_delete_request@Base 3.5.0-1 + rtnl_neigh_build_delete_request@libnl_3 3.5.0-1 + rtnl_neigh_delete@Base 3.5.0-1 + rtnl_neigh_delete@libnl_3 3.5.0-1 + rtnl_neigh_flags2str@Base 3.5.0-1 + rtnl_neigh_flags2str@libnl_3 3.5.0-1 + rtnl_neigh_get@Base 3.5.0-1 + rtnl_neigh_get@libnl_3 3.5.0-1 + rtnl_neigh_get_by_vlan@libnl_3_5 3.5.0-1 + rtnl_neigh_get_dst@Base 3.5.0-1 + rtnl_neigh_get_dst@libnl_3 3.5.0-1 + rtnl_neigh_get_family@Base 3.5.0-1 + rtnl_neigh_get_family@libnl_3 3.5.0-1 + rtnl_neigh_get_flags@Base 3.5.0-1 + rtnl_neigh_get_flags@libnl_3 3.5.0-1 + rtnl_neigh_get_ifindex@Base 3.5.0-1 + rtnl_neigh_get_ifindex@libnl_3 3.5.0-1 + rtnl_neigh_get_lladdr@Base 3.5.0-1 + rtnl_neigh_get_lladdr@libnl_3 3.5.0-1 + rtnl_neigh_get_master@libnl_3_5 3.5.0-1 + rtnl_neigh_get_state@Base 3.5.0-1 + rtnl_neigh_get_state@libnl_3 3.5.0-1 + rtnl_neigh_get_type@Base 3.5.0-1 + rtnl_neigh_get_type@libnl_3 3.5.0-1 + rtnl_neigh_get_vlan@Base 3.5.0-1 + rtnl_neigh_get_vlan@libnl_3_2_26 3.5.0-1 + rtnl_neigh_parse@Base 3.5.0-1 + rtnl_neigh_parse@libnl_3 3.5.0-1 + rtnl_neigh_put@Base 3.5.0-1 + rtnl_neigh_put@libnl_3 3.5.0-1 + rtnl_neigh_set_dst@Base 3.5.0-1 + rtnl_neigh_set_dst@libnl_3 3.5.0-1 + rtnl_neigh_set_family@Base 3.5.0-1 + rtnl_neigh_set_family@libnl_3 3.5.0-1 + rtnl_neigh_set_flags@Base 3.5.0-1 + rtnl_neigh_set_flags@libnl_3 3.5.0-1 + rtnl_neigh_set_ifindex@Base 3.5.0-1 + rtnl_neigh_set_ifindex@libnl_3 3.5.0-1 + rtnl_neigh_set_lladdr@Base 3.5.0-1 + rtnl_neigh_set_lladdr@libnl_3 3.5.0-1 + rtnl_neigh_set_master@libnl_3_5 3.5.0-1 + rtnl_neigh_set_state@Base 3.5.0-1 + rtnl_neigh_set_state@libnl_3 3.5.0-1 + rtnl_neigh_set_type@Base 3.5.0-1 + rtnl_neigh_set_type@libnl_3 3.5.0-1 + rtnl_neigh_set_vlan@Base 3.5.0-1 + rtnl_neigh_set_vlan@libnl_3_2_26 3.5.0-1 + rtnl_neigh_state2str@Base 3.5.0-1 + rtnl_neigh_state2str@libnl_3 3.5.0-1 + rtnl_neigh_str2flag@Base 3.5.0-1 + rtnl_neigh_str2flag@libnl_3 3.5.0-1 + rtnl_neigh_str2state@Base 3.5.0-1 + rtnl_neigh_str2state@libnl_3 3.5.0-1 + rtnl_neigh_unset_flags@Base 3.5.0-1 + rtnl_neigh_unset_flags@libnl_3 3.5.0-1 + rtnl_neigh_unset_state@Base 3.5.0-1 + rtnl_neigh_unset_state@libnl_3 3.5.0-1 + rtnl_neightbl_alloc@Base 3.5.0-1 + rtnl_neightbl_alloc@libnl_3 3.5.0-1 + rtnl_neightbl_alloc_cache@Base 3.5.0-1 + rtnl_neightbl_alloc_cache@libnl_3 3.5.0-1 + rtnl_neightbl_build_change_request@Base 3.5.0-1 + rtnl_neightbl_build_change_request@libnl_3 3.5.0-1 + rtnl_neightbl_change@Base 3.5.0-1 + rtnl_neightbl_change@libnl_3 3.5.0-1 + rtnl_neightbl_get@Base 3.5.0-1 + rtnl_neightbl_get@libnl_3 3.5.0-1 + rtnl_neightbl_put@Base 3.5.0-1 + rtnl_neightbl_put@libnl_3 3.5.0-1 + rtnl_neightbl_set_anycast_delay@Base 3.5.0-1 + rtnl_neightbl_set_anycast_delay@libnl_3 3.5.0-1 + rtnl_neightbl_set_app_probes@Base 3.5.0-1 + rtnl_neightbl_set_app_probes@libnl_3 3.5.0-1 + rtnl_neightbl_set_base_reachable_time@Base 3.5.0-1 + rtnl_neightbl_set_base_reachable_time@libnl_3 3.5.0-1 + rtnl_neightbl_set_delay_probe_time@Base 3.5.0-1 + rtnl_neightbl_set_delay_probe_time@libnl_3 3.5.0-1 + rtnl_neightbl_set_dev@Base 3.5.0-1 + rtnl_neightbl_set_dev@libnl_3 3.5.0-1 + rtnl_neightbl_set_family@Base 3.5.0-1 + rtnl_neightbl_set_family@libnl_3 3.5.0-1 + rtnl_neightbl_set_gc_interval@Base 3.5.0-1 + rtnl_neightbl_set_gc_interval@libnl_3 3.5.0-1 + rtnl_neightbl_set_gc_stale_time@Base 3.5.0-1 + rtnl_neightbl_set_gc_stale_time@libnl_3 3.5.0-1 + rtnl_neightbl_set_gc_tresh1@Base 3.5.0-1 + rtnl_neightbl_set_gc_tresh1@libnl_3 3.5.0-1 + rtnl_neightbl_set_gc_tresh2@Base 3.5.0-1 + rtnl_neightbl_set_gc_tresh2@libnl_3 3.5.0-1 + rtnl_neightbl_set_gc_tresh3@Base 3.5.0-1 + rtnl_neightbl_set_gc_tresh3@libnl_3 3.5.0-1 + rtnl_neightbl_set_locktime@Base 3.5.0-1 + rtnl_neightbl_set_locktime@libnl_3 3.5.0-1 + rtnl_neightbl_set_mcast_probes@Base 3.5.0-1 + rtnl_neightbl_set_mcast_probes@libnl_3 3.5.0-1 + rtnl_neightbl_set_name@Base 3.5.0-1 + rtnl_neightbl_set_name@libnl_3 3.5.0-1 + rtnl_neightbl_set_proxy_delay@Base 3.5.0-1 + rtnl_neightbl_set_proxy_delay@libnl_3 3.5.0-1 + rtnl_neightbl_set_proxy_queue_len@Base 3.5.0-1 + rtnl_neightbl_set_proxy_queue_len@libnl_3 3.5.0-1 + rtnl_neightbl_set_queue_len@Base 3.5.0-1 + rtnl_neightbl_set_queue_len@libnl_3 3.5.0-1 + rtnl_neightbl_set_retrans_time@Base 3.5.0-1 + rtnl_neightbl_set_retrans_time@libnl_3 3.5.0-1 + rtnl_neightbl_set_ucast_probes@Base 3.5.0-1 + rtnl_neightbl_set_ucast_probes@libnl_3 3.5.0-1 + rtnl_netconf_get_all@libnl_3_4 3.5.0-1 + rtnl_netconf_get_by_idx@libnl_3_4 3.5.0-1 + rtnl_netconf_get_default@libnl_3_4 3.5.0-1 + rtnl_netconf_get_family@libnl_3_4 3.5.0-1 + rtnl_netconf_get_forwarding@libnl_3_4 3.5.0-1 + rtnl_netconf_get_ifindex@libnl_3_4 3.5.0-1 + rtnl_netconf_get_input@libnl_3_4 3.5.0-1 + rtnl_netconf_get_mc_forwarding@libnl_3_4 3.5.0-1 + rtnl_netconf_get_rp_filter@libnl_3_4 3.5.0-1 + rtnl_netconf_put@libnl_3_4 3.5.0-1 + rtnl_netem_get_corruption_correlation@Base 3.5.0-1 + rtnl_netem_get_corruption_correlation@libnl_3 3.5.0-1 + rtnl_netem_get_corruption_probability@Base 3.5.0-1 + rtnl_netem_get_corruption_probability@libnl_3 3.5.0-1 + rtnl_netem_get_delay@Base 3.5.0-1 + rtnl_netem_get_delay@libnl_3 3.5.0-1 + rtnl_netem_get_delay_correlation@Base 3.5.0-1 + rtnl_netem_get_delay_correlation@libnl_3 3.5.0-1 + rtnl_netem_get_delay_distribution@Base 3.5.0-1 + rtnl_netem_get_delay_distribution@libnl_3 3.5.0-1 + rtnl_netem_get_delay_distribution_size@Base 3.5.0-1 + rtnl_netem_get_delay_distribution_size@libnl_3 3.5.0-1 + rtnl_netem_get_duplicate@Base 3.5.0-1 + rtnl_netem_get_duplicate@libnl_3 3.5.0-1 + rtnl_netem_get_duplicate_correlation@Base 3.5.0-1 + rtnl_netem_get_duplicate_correlation@libnl_3 3.5.0-1 + rtnl_netem_get_gap@Base 3.5.0-1 + rtnl_netem_get_gap@libnl_3 3.5.0-1 + rtnl_netem_get_jitter@Base 3.5.0-1 + rtnl_netem_get_jitter@libnl_3 3.5.0-1 + rtnl_netem_get_limit@Base 3.5.0-1 + rtnl_netem_get_limit@libnl_3 3.5.0-1 + rtnl_netem_get_loss@Base 3.5.0-1 + rtnl_netem_get_loss@libnl_3 3.5.0-1 + rtnl_netem_get_loss_correlation@Base 3.5.0-1 + rtnl_netem_get_loss_correlation@libnl_3 3.5.0-1 + rtnl_netem_get_reorder_correlation@Base 3.5.0-1 + rtnl_netem_get_reorder_correlation@libnl_3 3.5.0-1 + rtnl_netem_get_reorder_probability@Base 3.5.0-1 + rtnl_netem_get_reorder_probability@libnl_3 3.5.0-1 + rtnl_netem_set_corruption_correlation@Base 3.5.0-1 + rtnl_netem_set_corruption_correlation@libnl_3 3.5.0-1 + rtnl_netem_set_corruption_probability@Base 3.5.0-1 + rtnl_netem_set_corruption_probability@libnl_3 3.5.0-1 + rtnl_netem_set_delay@Base 3.5.0-1 + rtnl_netem_set_delay@libnl_3 3.5.0-1 + rtnl_netem_set_delay_correlation@Base 3.5.0-1 + rtnl_netem_set_delay_correlation@libnl_3 3.5.0-1 + rtnl_netem_set_delay_distribution@Base 3.5.0-1 + rtnl_netem_set_delay_distribution@libnl_3 3.5.0-1 + rtnl_netem_set_delay_distribution_data@libnl_3_5 3.5.0-1 + rtnl_netem_set_duplicate@Base 3.5.0-1 + rtnl_netem_set_duplicate@libnl_3 3.5.0-1 + rtnl_netem_set_duplicate_correlation@Base 3.5.0-1 + rtnl_netem_set_duplicate_correlation@libnl_3 3.5.0-1 + rtnl_netem_set_gap@Base 3.5.0-1 + rtnl_netem_set_gap@libnl_3 3.5.0-1 + rtnl_netem_set_jitter@Base 3.5.0-1 + rtnl_netem_set_jitter@libnl_3 3.5.0-1 + rtnl_netem_set_limit@Base 3.5.0-1 + rtnl_netem_set_limit@libnl_3 3.5.0-1 + rtnl_netem_set_loss@Base 3.5.0-1 + rtnl_netem_set_loss@libnl_3 3.5.0-1 + rtnl_netem_set_loss_correlation@Base 3.5.0-1 + rtnl_netem_set_loss_correlation@libnl_3 3.5.0-1 + rtnl_netem_set_reorder_correlation@Base 3.5.0-1 + rtnl_netem_set_reorder_correlation@libnl_3 3.5.0-1 + rtnl_netem_set_reorder_probability@Base 3.5.0-1 + rtnl_netem_set_reorder_probability@libnl_3 3.5.0-1 + rtnl_pktloc_add@Base 3.5.0-1 + rtnl_pktloc_add@libnl_3 3.5.0-1 + rtnl_pktloc_alloc@Base 3.5.0-1 + rtnl_pktloc_alloc@libnl_3 3.5.0-1 + rtnl_pktloc_foreach@Base 3.5.0-1 + rtnl_pktloc_foreach@libnl_3 3.5.0-1 + rtnl_pktloc_lookup@Base 3.5.0-1 + rtnl_pktloc_lookup@libnl_3 3.5.0-1 + rtnl_pktloc_put@Base 3.5.0-1 + rtnl_pktloc_put@libnl_3 3.5.0-1 + rtnl_prio2str@Base 3.5.0-1 + rtnl_prio2str@libnl_3 3.5.0-1 + rtnl_qdisc_add@Base 3.5.0-1 + rtnl_qdisc_add@libnl_3 3.5.0-1 + rtnl_qdisc_alloc@Base 3.5.0-1 + rtnl_qdisc_alloc@libnl_3 3.5.0-1 + rtnl_qdisc_alloc_cache@Base 3.5.0-1 + rtnl_qdisc_alloc_cache@libnl_3 3.5.0-1 + rtnl_qdisc_build_add_request@Base 3.5.0-1 + rtnl_qdisc_build_add_request@libnl_3 3.5.0-1 + rtnl_qdisc_build_change_request@Base 3.5.0-1 + rtnl_qdisc_build_change_request@libnl_3 3.5.0-1 + rtnl_qdisc_build_delete_request@Base 3.5.0-1 + rtnl_qdisc_build_delete_request@libnl_3 3.5.0-1 + rtnl_qdisc_build_update_request@Base 3.5.0-1 + rtnl_qdisc_build_update_request@libnl_3 3.5.0-1 + rtnl_qdisc_change@Base 3.5.0-1 + rtnl_qdisc_change@libnl_3 3.5.0-1 + rtnl_qdisc_delete@Base 3.5.0-1 + rtnl_qdisc_delete@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_get_default_index@Base 3.5.0-1 + rtnl_qdisc_dsmark_get_default_index@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_get_indices@Base 3.5.0-1 + rtnl_qdisc_dsmark_get_indices@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_get_set_tc_index@Base 3.5.0-1 + rtnl_qdisc_dsmark_get_set_tc_index@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_set_default_index@Base 3.5.0-1 + rtnl_qdisc_dsmark_set_default_index@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_set_indices@Base 3.5.0-1 + rtnl_qdisc_dsmark_set_indices@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_set_set_tc_index@Base 3.5.0-1 + rtnl_qdisc_dsmark_set_set_tc_index@libnl_3 3.5.0-1 + rtnl_qdisc_fifo_get_limit@Base 3.5.0-1 + rtnl_qdisc_fifo_get_limit@libnl_3 3.5.0-1 + rtnl_qdisc_fifo_set_limit@Base 3.5.0-1 + rtnl_qdisc_fifo_set_limit@libnl_3 3.5.0-1 + rtnl_qdisc_foreach_child@Base 3.5.0-1 + rtnl_qdisc_foreach_child@libnl_3 3.5.0-1 + rtnl_qdisc_foreach_cls@Base 3.5.0-1 + rtnl_qdisc_foreach_cls@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_ecn@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_ecn@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_flows@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_flows@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_interval@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_interval@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_limit@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_limit@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_quantum@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_quantum@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_target@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_target@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_ecn@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_ecn@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_flows@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_flows@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_interval@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_interval@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_limit@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_limit@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_quantum@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_quantum@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_target@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_target@libnl_3 3.5.0-1 + rtnl_qdisc_get@Base 3.5.0-1 + rtnl_qdisc_get@libnl_3 3.5.0-1 + rtnl_qdisc_get_by_parent@Base 3.5.0-1 + rtnl_qdisc_get_by_parent@libnl_3 3.5.0-1 + rtnl_qdisc_hfsc_get_defcls@Base 3.5.0-1 + rtnl_qdisc_hfsc_get_defcls@libnl_3 3.5.0-1 + rtnl_qdisc_hfsc_set_defcls@Base 3.5.0-1 + rtnl_qdisc_hfsc_set_defcls@libnl_3 3.5.0-1 + rtnl_qdisc_mqprio_get_hw_offload@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_max_rate@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_min_rate@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_mode@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_num_tc@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_priomap@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_queue@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_shaper@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_hw_offload@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_max_rate@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_min_rate@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_mode@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_num_tc@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_priomap@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_queue@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_shaper@libnl_3_5 3.5.0-1 + rtnl_qdisc_plug_buffer@Base 3.5.0-1 + rtnl_qdisc_plug_buffer@libnl_3 3.5.0-1 + rtnl_qdisc_plug_release_indefinite@Base 3.5.0-1 + rtnl_qdisc_plug_release_indefinite@libnl_3 3.5.0-1 + rtnl_qdisc_plug_release_one@Base 3.5.0-1 + rtnl_qdisc_plug_release_one@libnl_3 3.5.0-1 + rtnl_qdisc_plug_set_limit@Base 3.5.0-1 + rtnl_qdisc_plug_set_limit@libnl_3 3.5.0-1 + rtnl_qdisc_prio_get_bands@Base 3.5.0-1 + rtnl_qdisc_prio_get_bands@libnl_3 3.5.0-1 + rtnl_qdisc_prio_get_priomap@Base 3.5.0-1 + rtnl_qdisc_prio_get_priomap@libnl_3 3.5.0-1 + rtnl_qdisc_prio_set_bands@Base 3.5.0-1 + rtnl_qdisc_prio_set_bands@libnl_3 3.5.0-1 + rtnl_qdisc_prio_set_priomap@Base 3.5.0-1 + rtnl_qdisc_prio_set_priomap@libnl_3 3.5.0-1 + rtnl_qdisc_put@Base 3.5.0-1 + rtnl_qdisc_put@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_limit@Base 3.5.0-1 + rtnl_qdisc_tbf_get_limit@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate@Base 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate_bucket@Base 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate_bucket@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate_cell@Base 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate_cell@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_rate@Base 3.5.0-1 + rtnl_qdisc_tbf_get_rate@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_rate_bucket@Base 3.5.0-1 + rtnl_qdisc_tbf_get_rate_bucket@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_rate_cell@Base 3.5.0-1 + rtnl_qdisc_tbf_get_rate_cell@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_set_limit@Base 3.5.0-1 + rtnl_qdisc_tbf_set_limit@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_set_limit_by_latency@Base 3.5.0-1 + rtnl_qdisc_tbf_set_limit_by_latency@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_set_peakrate@Base 3.5.0-1 + rtnl_qdisc_tbf_set_peakrate@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_set_rate@Base 3.5.0-1 + rtnl_qdisc_tbf_set_rate@libnl_3 3.5.0-1 + rtnl_qdisc_update@Base 3.5.0-1 + rtnl_qdisc_update@libnl_3 3.5.0-1 + rtnl_realms2str@Base 3.5.0-1 + rtnl_realms2str@libnl_3 3.5.0-1 + rtnl_red_get_limit@Base 3.5.0-1 + rtnl_red_get_limit@libnl_3 3.5.0-1 + rtnl_red_set_limit@Base 3.5.0-1 + rtnl_red_set_limit@libnl_3 3.5.0-1 + rtnl_route_add@Base 3.5.0-1 + rtnl_route_add@libnl_3 3.5.0-1 + rtnl_route_add_nexthop@Base 3.5.0-1 + rtnl_route_add_nexthop@libnl_3 3.5.0-1 + rtnl_route_alloc@Base 3.5.0-1 + rtnl_route_alloc@libnl_3 3.5.0-1 + rtnl_route_alloc_cache@Base 3.5.0-1 + rtnl_route_alloc_cache@libnl_3 3.5.0-1 + rtnl_route_build_add_request@Base 3.5.0-1 + rtnl_route_build_add_request@libnl_3 3.5.0-1 + rtnl_route_build_del_request@Base 3.5.0-1 + rtnl_route_build_del_request@libnl_3 3.5.0-1 + rtnl_route_build_msg@Base 3.5.0-1 + rtnl_route_build_msg@libnl_3 3.5.0-1 + rtnl_route_delete@Base 3.5.0-1 + rtnl_route_delete@libnl_3 3.5.0-1 + rtnl_route_foreach_nexthop@Base 3.5.0-1 + rtnl_route_foreach_nexthop@libnl_3 3.5.0-1 + rtnl_route_get@Base 3.5.0-1 + rtnl_route_get@libnl_3 3.5.0-1 + rtnl_route_get_dst@Base 3.5.0-1 + rtnl_route_get_dst@libnl_3 3.5.0-1 + rtnl_route_get_family@Base 3.5.0-1 + rtnl_route_get_family@libnl_3 3.5.0-1 + rtnl_route_get_flags@Base 3.5.0-1 + rtnl_route_get_flags@libnl_3 3.5.0-1 + rtnl_route_get_iif@Base 3.5.0-1 + rtnl_route_get_iif@libnl_3 3.5.0-1 + rtnl_route_get_metric@Base 3.5.0-1 + rtnl_route_get_metric@libnl_3 3.5.0-1 + rtnl_route_get_nexthops@Base 3.5.0-1 + rtnl_route_get_nexthops@libnl_3 3.5.0-1 + rtnl_route_get_nnexthops@Base 3.5.0-1 + rtnl_route_get_nnexthops@libnl_3 3.5.0-1 + rtnl_route_get_pref_src@Base 3.5.0-1 + rtnl_route_get_pref_src@libnl_3 3.5.0-1 + rtnl_route_get_priority@Base 3.5.0-1 + rtnl_route_get_priority@libnl_3 3.5.0-1 + rtnl_route_get_protocol@Base 3.5.0-1 + rtnl_route_get_protocol@libnl_3 3.5.0-1 + rtnl_route_get_scope@Base 3.5.0-1 + rtnl_route_get_scope@libnl_3 3.5.0-1 + rtnl_route_get_src@Base 3.5.0-1 + rtnl_route_get_src@libnl_3 3.5.0-1 + rtnl_route_get_table@Base 3.5.0-1 + rtnl_route_get_table@libnl_3 3.5.0-1 + rtnl_route_get_tos@Base 3.5.0-1 + rtnl_route_get_tos@libnl_3 3.5.0-1 + rtnl_route_get_ttl_propagate@libnl_3_4 3.5.0-1 + rtnl_route_get_type@Base 3.5.0-1 + rtnl_route_get_type@libnl_3 3.5.0-1 + rtnl_route_guess_scope@Base 3.5.0-1 + rtnl_route_guess_scope@libnl_3 3.5.0-1 + rtnl_route_metric2str@Base 3.5.0-1 + rtnl_route_metric2str@libnl_3 3.5.0-1 + rtnl_route_nexthop_n@Base 3.5.0-1 + rtnl_route_nexthop_n@libnl_3 3.5.0-1 + rtnl_route_nh_alloc@Base 3.5.0-1 + rtnl_route_nh_alloc@libnl_3 3.5.0-1 + rtnl_route_nh_clone@Base 3.5.0-1 + rtnl_route_nh_clone@libnl_3 3.5.0-1 + rtnl_route_nh_compare@Base 3.5.0-1 + rtnl_route_nh_compare@libnl_3 3.5.0-1 + rtnl_route_nh_dump@Base 3.5.0-1 + rtnl_route_nh_dump@libnl_3 3.5.0-1 + rtnl_route_nh_encap_mpls@libnl_3_4 3.5.0-1 + rtnl_route_nh_flags2str@Base 3.5.0-1 + rtnl_route_nh_flags2str@libnl_3 3.5.0-1 + rtnl_route_nh_free@Base 3.5.0-1 + rtnl_route_nh_free@libnl_3 3.5.0-1 + rtnl_route_nh_get_flags@Base 3.5.0-1 + rtnl_route_nh_get_flags@libnl_3 3.5.0-1 + rtnl_route_nh_get_gateway@Base 3.5.0-1 + rtnl_route_nh_get_gateway@libnl_3 3.5.0-1 + rtnl_route_nh_get_ifindex@Base 3.5.0-1 + rtnl_route_nh_get_ifindex@libnl_3 3.5.0-1 + rtnl_route_nh_get_newdst@libnl_3_4 3.5.0-1 + rtnl_route_nh_get_realms@Base 3.5.0-1 + rtnl_route_nh_get_realms@libnl_3 3.5.0-1 + rtnl_route_nh_get_via@libnl_3_4 3.5.0-1 + rtnl_route_nh_get_weight@Base 3.5.0-1 + rtnl_route_nh_get_weight@libnl_3 3.5.0-1 + rtnl_route_nh_set_flags@Base 3.5.0-1 + rtnl_route_nh_set_flags@libnl_3 3.5.0-1 + rtnl_route_nh_set_gateway@Base 3.5.0-1 + rtnl_route_nh_set_gateway@libnl_3 3.5.0-1 + rtnl_route_nh_set_ifindex@Base 3.5.0-1 + rtnl_route_nh_set_ifindex@libnl_3 3.5.0-1 + rtnl_route_nh_set_newdst@libnl_3_4 3.5.0-1 + rtnl_route_nh_set_realms@Base 3.5.0-1 + rtnl_route_nh_set_realms@libnl_3 3.5.0-1 + rtnl_route_nh_set_via@libnl_3_4 3.5.0-1 + rtnl_route_nh_set_weight@Base 3.5.0-1 + rtnl_route_nh_set_weight@libnl_3 3.5.0-1 + rtnl_route_nh_str2flags@Base 3.5.0-1 + rtnl_route_nh_str2flags@libnl_3 3.5.0-1 + rtnl_route_nh_unset_flags@Base 3.5.0-1 + rtnl_route_nh_unset_flags@libnl_3 3.5.0-1 + rtnl_route_parse@Base 3.5.0-1 + rtnl_route_parse@libnl_3 3.5.0-1 + rtnl_route_proto2str@Base 3.5.0-1 + rtnl_route_proto2str@libnl_3 3.5.0-1 + rtnl_route_put@Base 3.5.0-1 + rtnl_route_put@libnl_3 3.5.0-1 + rtnl_route_read_protocol_names@Base 3.5.0-1 + rtnl_route_read_protocol_names@libnl_3 3.5.0-1 + rtnl_route_read_table_names@Base 3.5.0-1 + rtnl_route_read_table_names@libnl_3 3.5.0-1 + rtnl_route_remove_nexthop@Base 3.5.0-1 + rtnl_route_remove_nexthop@libnl_3 3.5.0-1 + rtnl_route_set_dst@Base 3.5.0-1 + rtnl_route_set_dst@libnl_3 3.5.0-1 + rtnl_route_set_family@Base 3.5.0-1 + rtnl_route_set_family@libnl_3 3.5.0-1 + rtnl_route_set_flags@Base 3.5.0-1 + rtnl_route_set_flags@libnl_3 3.5.0-1 + rtnl_route_set_iif@Base 3.5.0-1 + rtnl_route_set_iif@libnl_3 3.5.0-1 + rtnl_route_set_metric@Base 3.5.0-1 + rtnl_route_set_metric@libnl_3 3.5.0-1 + rtnl_route_set_pref_src@Base 3.5.0-1 + rtnl_route_set_pref_src@libnl_3 3.5.0-1 + rtnl_route_set_priority@Base 3.5.0-1 + rtnl_route_set_priority@libnl_3 3.5.0-1 + rtnl_route_set_protocol@Base 3.5.0-1 + rtnl_route_set_protocol@libnl_3 3.5.0-1 + rtnl_route_set_scope@Base 3.5.0-1 + rtnl_route_set_scope@libnl_3 3.5.0-1 + rtnl_route_set_src@Base 3.5.0-1 + rtnl_route_set_src@libnl_3 3.5.0-1 + rtnl_route_set_table@Base 3.5.0-1 + rtnl_route_set_table@libnl_3 3.5.0-1 + rtnl_route_set_tos@Base 3.5.0-1 + rtnl_route_set_tos@libnl_3 3.5.0-1 + rtnl_route_set_ttl_propagate@libnl_3_4 3.5.0-1 + rtnl_route_set_type@Base 3.5.0-1 + rtnl_route_set_type@libnl_3 3.5.0-1 + rtnl_route_str2metric@Base 3.5.0-1 + rtnl_route_str2metric@libnl_3 3.5.0-1 + rtnl_route_str2proto@Base 3.5.0-1 + rtnl_route_str2proto@libnl_3 3.5.0-1 + rtnl_route_str2table@Base 3.5.0-1 + rtnl_route_str2table@libnl_3 3.5.0-1 + rtnl_route_table2str@Base 3.5.0-1 + rtnl_route_table2str@libnl_3 3.5.0-1 + rtnl_route_unset_flags@Base 3.5.0-1 + rtnl_route_unset_flags@libnl_3 3.5.0-1 + rtnl_route_unset_metric@Base 3.5.0-1 + rtnl_route_unset_metric@libnl_3 3.5.0-1 + rtnl_rule_add@Base 3.5.0-1 + rtnl_rule_add@libnl_3 3.5.0-1 + rtnl_rule_alloc@Base 3.5.0-1 + rtnl_rule_alloc@libnl_3 3.5.0-1 + rtnl_rule_alloc_cache@Base 3.5.0-1 + rtnl_rule_alloc_cache@libnl_3 3.5.0-1 + rtnl_rule_build_add_request@Base 3.5.0-1 + rtnl_rule_build_add_request@libnl_3 3.5.0-1 + rtnl_rule_build_delete_request@Base 3.5.0-1 + rtnl_rule_build_delete_request@libnl_3 3.5.0-1 + rtnl_rule_delete@Base 3.5.0-1 + rtnl_rule_delete@libnl_3 3.5.0-1 + rtnl_rule_get_action@Base 3.5.0-1 + rtnl_rule_get_action@libnl_3 3.5.0-1 + rtnl_rule_get_dport@libnl_3_5 3.5.0-1 + rtnl_rule_get_dsfield@Base 3.5.0-1 + rtnl_rule_get_dsfield@libnl_3 3.5.0-1 + rtnl_rule_get_dst@Base 3.5.0-1 + rtnl_rule_get_dst@libnl_3 3.5.0-1 + rtnl_rule_get_family@Base 3.5.0-1 + rtnl_rule_get_family@libnl_3 3.5.0-1 + rtnl_rule_get_goto@Base 3.5.0-1 + rtnl_rule_get_goto@libnl_3 3.5.0-1 + rtnl_rule_get_iif@Base 3.5.0-1 + rtnl_rule_get_iif@libnl_3 3.5.0-1 + rtnl_rule_get_ipproto@libnl_3_5 3.5.0-1 + rtnl_rule_get_l3mdev@libnl_3_4 3.5.0-1 + rtnl_rule_get_mark@Base 3.5.0-1 + rtnl_rule_get_mark@libnl_3 3.5.0-1 + rtnl_rule_get_mask@Base 3.5.0-1 + rtnl_rule_get_mask@libnl_3 3.5.0-1 + rtnl_rule_get_oif@Base 3.5.0-1 + rtnl_rule_get_oif@libnl_3 3.5.0-1 + rtnl_rule_get_prio@Base 3.5.0-1 + rtnl_rule_get_prio@libnl_3 3.5.0-1 + rtnl_rule_get_protocol@libnl_3_5 3.5.0-1 + rtnl_rule_get_realms@Base 3.5.0-1 + rtnl_rule_get_realms@libnl_3 3.5.0-1 + rtnl_rule_get_sport@libnl_3_5 3.5.0-1 + rtnl_rule_get_src@Base 3.5.0-1 + rtnl_rule_get_src@libnl_3 3.5.0-1 + rtnl_rule_get_table@Base 3.5.0-1 + rtnl_rule_get_table@libnl_3 3.5.0-1 + rtnl_rule_put@Base 3.5.0-1 + rtnl_rule_put@libnl_3 3.5.0-1 + rtnl_rule_set_action@Base 3.5.0-1 + rtnl_rule_set_action@libnl_3 3.5.0-1 + rtnl_rule_set_dport@libnl_3_5 3.5.0-1 + rtnl_rule_set_dport_range@libnl_3_5 3.5.0-1 + rtnl_rule_set_dsfield@Base 3.5.0-1 + rtnl_rule_set_dsfield@libnl_3 3.5.0-1 + rtnl_rule_set_dst@Base 3.5.0-1 + rtnl_rule_set_dst@libnl_3 3.5.0-1 + rtnl_rule_set_family@Base 3.5.0-1 + rtnl_rule_set_family@libnl_3 3.5.0-1 + rtnl_rule_set_goto@Base 3.5.0-1 + rtnl_rule_set_goto@libnl_3 3.5.0-1 + rtnl_rule_set_iif@Base 3.5.0-1 + rtnl_rule_set_iif@libnl_3 3.5.0-1 + rtnl_rule_set_ipproto@libnl_3_5 3.5.0-1 + rtnl_rule_set_l3mdev@libnl_3_4 3.5.0-1 + rtnl_rule_set_mark@Base 3.5.0-1 + rtnl_rule_set_mark@libnl_3 3.5.0-1 + rtnl_rule_set_mask@Base 3.5.0-1 + rtnl_rule_set_mask@libnl_3 3.5.0-1 + rtnl_rule_set_oif@Base 3.5.0-1 + rtnl_rule_set_oif@libnl_3 3.5.0-1 + rtnl_rule_set_prio@Base 3.5.0-1 + rtnl_rule_set_prio@libnl_3 3.5.0-1 + rtnl_rule_set_protocol@libnl_3_5 3.5.0-1 + rtnl_rule_set_realms@Base 3.5.0-1 + rtnl_rule_set_realms@libnl_3 3.5.0-1 + rtnl_rule_set_sport@libnl_3_5 3.5.0-1 + rtnl_rule_set_sport_range@libnl_3_5 3.5.0-1 + rtnl_rule_set_src@Base 3.5.0-1 + rtnl_rule_set_src@libnl_3 3.5.0-1 + rtnl_rule_set_table@Base 3.5.0-1 + rtnl_rule_set_table@libnl_3 3.5.0-1 + rtnl_scope2str@Base 3.5.0-1 + rtnl_scope2str@libnl_3 3.5.0-1 + rtnl_sfq_get_divisor@Base 3.5.0-1 + rtnl_sfq_get_divisor@libnl_3 3.5.0-1 + rtnl_sfq_get_limit@Base 3.5.0-1 + rtnl_sfq_get_limit@libnl_3 3.5.0-1 + rtnl_sfq_get_perturb@Base 3.5.0-1 + rtnl_sfq_get_perturb@libnl_3 3.5.0-1 + rtnl_sfq_get_quantum@Base 3.5.0-1 + rtnl_sfq_get_quantum@libnl_3 3.5.0-1 + rtnl_sfq_set_limit@Base 3.5.0-1 + rtnl_sfq_set_limit@libnl_3 3.5.0-1 + rtnl_sfq_set_perturb@Base 3.5.0-1 + rtnl_sfq_set_perturb@libnl_3 3.5.0-1 + rtnl_sfq_set_quantum@Base 3.5.0-1 + rtnl_sfq_set_quantum@libnl_3 3.5.0-1 + rtnl_skbedit_get_action@Base 3.5.0-1 + rtnl_skbedit_get_action@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_get_mark@Base 3.5.0-1 + rtnl_skbedit_get_mark@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_get_priority@Base 3.5.0-1 + rtnl_skbedit_get_priority@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_get_queue_mapping@Base 3.5.0-1 + rtnl_skbedit_get_queue_mapping@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_set_action@Base 3.5.0-1 + rtnl_skbedit_set_action@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_set_mark@Base 3.5.0-1 + rtnl_skbedit_set_mark@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_set_priority@Base 3.5.0-1 + rtnl_skbedit_set_priority@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_set_queue_mapping@Base 3.5.0-1 + rtnl_skbedit_set_queue_mapping@libnl_3_2_26 3.5.0-1 + rtnl_str2prio@Base 3.5.0-1 + rtnl_str2prio@libnl_3 3.5.0-1 + rtnl_str2scope@Base 3.5.0-1 + rtnl_str2scope@libnl_3 3.5.0-1 + rtnl_tc_build_rate_table@Base 3.5.0-1 + rtnl_tc_build_rate_table@libnl_3 3.5.0-1 + rtnl_tc_calc_bufsize@Base 3.5.0-1 + rtnl_tc_calc_bufsize@libnl_3 3.5.0-1 + rtnl_tc_calc_cell_log@Base 3.5.0-1 + rtnl_tc_calc_cell_log@libnl_3 3.5.0-1 + rtnl_tc_calc_txtime@Base 3.5.0-1 + rtnl_tc_calc_txtime@libnl_3 3.5.0-1 + rtnl_tc_clone@Base 3.5.0-1 + rtnl_tc_clone@libnl_3 3.5.0-1 + rtnl_tc_compare@Base 3.5.0-1 + rtnl_tc_compare@libnl_3 3.5.0-1 + rtnl_tc_data@Base 3.5.0-1 + rtnl_tc_data@libnl_3 3.5.0-1 + rtnl_tc_data_check@Base 3.5.0-1 + rtnl_tc_data_check@libnl_3 3.5.0-1 + rtnl_tc_data_peek@Base 3.5.0-1 + rtnl_tc_dump_details@Base 3.5.0-1 + rtnl_tc_dump_details@libnl_3 3.5.0-1 + rtnl_tc_dump_line@Base 3.5.0-1 + rtnl_tc_dump_line@libnl_3 3.5.0-1 + rtnl_tc_dump_stats@Base 3.5.0-1 + rtnl_tc_dump_stats@libnl_3 3.5.0-1 + rtnl_tc_free_data@Base 3.5.0-1 + rtnl_tc_free_data@libnl_3 3.5.0-1 + rtnl_tc_get_chain@libnl_3_5 3.5.0-1 + rtnl_tc_get_handle@Base 3.5.0-1 + rtnl_tc_get_handle@libnl_3 3.5.0-1 + rtnl_tc_get_ifindex@Base 3.5.0-1 + rtnl_tc_get_ifindex@libnl_3 3.5.0-1 + rtnl_tc_get_kind@Base 3.5.0-1 + rtnl_tc_get_kind@libnl_3 3.5.0-1 + rtnl_tc_get_link@Base 3.5.0-1 + rtnl_tc_get_link@libnl_3 3.5.0-1 + rtnl_tc_get_linktype@Base 3.5.0-1 + rtnl_tc_get_linktype@libnl_3 3.5.0-1 + rtnl_tc_get_mpu@Base 3.5.0-1 + rtnl_tc_get_mpu@libnl_3 3.5.0-1 + rtnl_tc_get_mtu@Base 3.5.0-1 + rtnl_tc_get_mtu@libnl_3 3.5.0-1 + rtnl_tc_get_ops@Base 3.5.0-1 + rtnl_tc_get_ops@libnl_3 3.5.0-1 + rtnl_tc_get_overhead@Base 3.5.0-1 + rtnl_tc_get_overhead@libnl_3 3.5.0-1 + rtnl_tc_get_parent@Base 3.5.0-1 + rtnl_tc_get_parent@libnl_3 3.5.0-1 + rtnl_tc_get_stat@Base 3.5.0-1 + rtnl_tc_get_stat@libnl_3 3.5.0-1 + rtnl_tc_handle2str@Base 3.5.0-1 + rtnl_tc_handle2str@libnl_3 3.5.0-1 + rtnl_tc_lookup_ops@Base 3.5.0-1 + rtnl_tc_lookup_ops@libnl_3 3.5.0-1 + rtnl_tc_msg_build@Base 3.5.0-1 + rtnl_tc_msg_build@libnl_3 3.5.0-1 + rtnl_tc_msg_parse@Base 3.5.0-1 + rtnl_tc_msg_parse@libnl_3 3.5.0-1 + rtnl_tc_read_classid_file@Base 3.5.0-1 + rtnl_tc_read_classid_file@libnl_3 3.5.0-1 + rtnl_tc_register@Base 3.5.0-1 + rtnl_tc_register@libnl_3 3.5.0-1 + rtnl_tc_set_chain@libnl_3_5 3.5.0-1 + rtnl_tc_set_handle@Base 3.5.0-1 + rtnl_tc_set_handle@libnl_3 3.5.0-1 + rtnl_tc_set_ifindex@Base 3.5.0-1 + rtnl_tc_set_ifindex@libnl_3 3.5.0-1 + rtnl_tc_set_kind@Base 3.5.0-1 + rtnl_tc_set_kind@libnl_3 3.5.0-1 + rtnl_tc_set_link@Base 3.5.0-1 + rtnl_tc_set_link@libnl_3 3.5.0-1 + rtnl_tc_set_linktype@Base 3.5.0-1 + rtnl_tc_set_linktype@libnl_3 3.5.0-1 + rtnl_tc_set_mpu@Base 3.5.0-1 + rtnl_tc_set_mpu@libnl_3 3.5.0-1 + rtnl_tc_set_mtu@Base 3.5.0-1 + rtnl_tc_set_mtu@libnl_3 3.5.0-1 + rtnl_tc_set_overhead@Base 3.5.0-1 + rtnl_tc_set_overhead@libnl_3 3.5.0-1 + rtnl_tc_set_parent@Base 3.5.0-1 + rtnl_tc_set_parent@libnl_3 3.5.0-1 + rtnl_tc_stat2str@Base 3.5.0-1 + rtnl_tc_stat2str@libnl_3_2_26 3.5.0-1 + rtnl_tc_str2handle@Base 3.5.0-1 + rtnl_tc_str2handle@libnl_3 3.5.0-1 + rtnl_tc_str2stat@Base 3.5.0-1 + rtnl_tc_str2stat@libnl_3_2_26 3.5.0-1 + rtnl_tc_type_register@Base 3.5.0-1 + rtnl_tc_type_register@libnl_3 3.5.0-1 + rtnl_tc_type_unregister@Base 3.5.0-1 + rtnl_tc_type_unregister@libnl_3 3.5.0-1 + rtnl_tc_unregister@Base 3.5.0-1 + rtnl_tc_unregister@libnl_3 3.5.0-1 + rtnl_u32_add_action@Base 3.5.0-1 + rtnl_u32_add_action@libnl_3 3.5.0-1 + rtnl_u32_add_key@Base 3.5.0-1 + rtnl_u32_add_key@libnl_3 3.5.0-1 + rtnl_u32_add_key_in6_addr@Base 3.5.0-1 + rtnl_u32_add_key_in6_addr@libnl_3 3.5.0-1 + rtnl_u32_add_key_in_addr@Base 3.5.0-1 + rtnl_u32_add_key_in_addr@libnl_3 3.5.0-1 + rtnl_u32_add_key_uint16@Base 3.5.0-1 + rtnl_u32_add_key_uint16@libnl_3 3.5.0-1 + rtnl_u32_add_key_uint32@Base 3.5.0-1 + rtnl_u32_add_key_uint32@libnl_3 3.5.0-1 + rtnl_u32_add_key_uint8@Base 3.5.0-1 + rtnl_u32_add_key_uint8@libnl_3 3.5.0-1 + rtnl_u32_add_mark@Base 3.5.0-1 + rtnl_u32_add_mark@libnl_3 3.5.0-1 + rtnl_u32_del_action@Base 3.5.0-1 + rtnl_u32_del_action@libnl_3 3.5.0-1 + rtnl_u32_del_mark@Base 3.5.0-1 + rtnl_u32_del_mark@libnl_3 3.5.0-1 + rtnl_u32_get_action@libnl_3_4 3.5.0-1 + rtnl_u32_get_classid@Base 3.5.0-1 + rtnl_u32_get_classid@libnl_3_2_26 3.5.0-1 + rtnl_u32_get_key@Base 3.5.0-1 + rtnl_u32_get_key@libnl_3 3.5.0-1 + rtnl_u32_set_classid@Base 3.5.0-1 + rtnl_u32_set_classid@libnl_3 3.5.0-1 + rtnl_u32_set_cls_terminal@Base 3.5.0-1 + rtnl_u32_set_cls_terminal@libnl_3 3.5.0-1 + rtnl_u32_set_divisor@Base 3.5.0-1 + rtnl_u32_set_divisor@libnl_3 3.5.0-1 + rtnl_u32_set_flags@Base 3.5.0-1 + rtnl_u32_set_flags@libnl_3 3.5.0-1 + rtnl_u32_set_handle@Base 3.5.0-1 + rtnl_u32_set_handle@libnl_3 3.5.0-1 + rtnl_u32_set_hashmask@Base 3.5.0-1 + rtnl_u32_set_hashmask@libnl_3 3.5.0-1 + rtnl_u32_set_hashtable@Base 3.5.0-1 + rtnl_u32_set_hashtable@libnl_3 3.5.0-1 + rtnl_u32_set_link@Base 3.5.0-1 + rtnl_u32_set_link@libnl_3 3.5.0-1 + rtnl_u32_set_selector@libnl_3_2_29 3.5.0-1 + rtnl_vlan_get_action@libnl_3_5 3.5.0-1 + rtnl_vlan_get_mode@libnl_3_5 3.5.0-1 + rtnl_vlan_get_protocol@libnl_3_5 3.5.0-1 + rtnl_vlan_get_vlan_id@libnl_3_5 3.5.0-1 + rtnl_vlan_get_vlan_prio@libnl_3_5 3.5.0-1 + rtnl_vlan_set_action@libnl_3_5 3.5.0-1 + rtnl_vlan_set_mode@libnl_3_5 3.5.0-1 + rtnl_vlan_set_protocol@libnl_3_5 3.5.0-1 + rtnl_vlan_set_vlan_id@libnl_3_5 3.5.0-1 + rtnl_vlan_set_vlan_prio@libnl_3_5 3.5.0-1 + tc_groups@Base 3.5.0-1 + tca_parse@Base 3.5.0-1 + tca_set_kind@Base 3.5.0-1 diff --git a/src/libnl3/debian/libnl-route-3-dev.install b/src/libnl3/debian/libnl-route-3-dev.install new file mode 100644 index 000000000000..37e248c3ed5b --- /dev/null +++ b/src/libnl3/debian/libnl-route-3-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/*/pkgconfig/libnl-route-3* +debian/tmp/usr/lib/*/libnl-route-3*.so +debian/tmp/usr/lib/*/libnl-route-3*.a diff --git a/src/libnl3/debian/libnl-utils.install b/src/libnl3/debian/libnl-utils.install new file mode 100644 index 000000000000..8ffdce84e93a --- /dev/null +++ b/src/libnl3/debian/libnl-utils.install @@ -0,0 +1 @@ +debian/tmp/usr/bin/* diff --git a/src/libnl3/debian/libnl-utils.manpages b/src/libnl3/debian/libnl-utils.manpages new file mode 100644 index 000000000000..0b2dcacf5b84 --- /dev/null +++ b/src/libnl3/debian/libnl-utils.manpages @@ -0,0 +1 @@ +debian/tmp/usr/share/man/man8/* diff --git a/src/libnl3/debian/libnl-xfrm-3-200.install b/src/libnl3/debian/libnl-xfrm-3-200.install new file mode 100644 index 000000000000..89b2d4e0c9e0 --- /dev/null +++ b/src/libnl3/debian/libnl-xfrm-3-200.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/*/libnl-xfrm-3*.so.* diff --git a/src/libnl3/debian/libnl-xfrm-3-200.symbols b/src/libnl3/debian/libnl-xfrm-3-200.symbols new file mode 100644 index 000000000000..3704a7aa4384 --- /dev/null +++ b/src/libnl3/debian/libnl-xfrm-3-200.symbols @@ -0,0 +1,484 @@ +libnl-xfrm-3.so.200 libnl-xfrm-3-200 #MINVER# + libnl_3@libnl_3 3.5.0-1 + xfrmnl_ae_alloc@Base 3.5.0-1 + xfrmnl_ae_alloc@libnl_3 3.5.0-1 + xfrmnl_ae_build_get_request@Base 3.5.0-1 + xfrmnl_ae_build_get_request@libnl_3 3.5.0-1 + xfrmnl_ae_flags2str@Base 3.5.0-1 + xfrmnl_ae_flags2str@libnl_3 3.5.0-1 + xfrmnl_ae_get_curlifetime@Base 3.5.0-1 + xfrmnl_ae_get_curlifetime@libnl_3 3.5.0-1 + xfrmnl_ae_get_daddr@Base 3.5.0-1 + xfrmnl_ae_get_daddr@libnl_3 3.5.0-1 + xfrmnl_ae_get_family@Base 3.5.0-1 + xfrmnl_ae_get_family@libnl_3 3.5.0-1 + xfrmnl_ae_get_flags@Base 3.5.0-1 + xfrmnl_ae_get_flags@libnl_3 3.5.0-1 + xfrmnl_ae_get_kernel@Base 3.5.0-1 + xfrmnl_ae_get_kernel@libnl_3 3.5.0-1 + xfrmnl_ae_get_mark@Base 3.5.0-1 + xfrmnl_ae_get_mark@libnl_3 3.5.0-1 + xfrmnl_ae_get_proto@Base 3.5.0-1 + xfrmnl_ae_get_proto@libnl_3 3.5.0-1 + xfrmnl_ae_get_replay_maxage@Base 3.5.0-1 + xfrmnl_ae_get_replay_maxage@libnl_3 3.5.0-1 + xfrmnl_ae_get_replay_maxdiff@Base 3.5.0-1 + xfrmnl_ae_get_replay_maxdiff@libnl_3 3.5.0-1 + xfrmnl_ae_get_replay_state@Base 3.5.0-1 + xfrmnl_ae_get_replay_state@libnl_3 3.5.0-1 + xfrmnl_ae_get_replay_state_esn@Base 3.5.0-1 + xfrmnl_ae_get_replay_state_esn@libnl_3 3.5.0-1 + xfrmnl_ae_get_reqid@Base 3.5.0-1 + xfrmnl_ae_get_reqid@libnl_3 3.5.0-1 + xfrmnl_ae_get_saddr@Base 3.5.0-1 + xfrmnl_ae_get_saddr@libnl_3 3.5.0-1 + xfrmnl_ae_get_spi@Base 3.5.0-1 + xfrmnl_ae_get_spi@libnl_3 3.5.0-1 + xfrmnl_ae_parse@Base 3.5.0-1 + xfrmnl_ae_parse@libnl_3 3.5.0-1 + xfrmnl_ae_put@Base 3.5.0-1 + xfrmnl_ae_put@libnl_3 3.5.0-1 + xfrmnl_ae_set@Base 3.5.0-1 + xfrmnl_ae_set@libnl_3 3.5.0-1 + xfrmnl_ae_set_curlifetime@Base 3.5.0-1 + xfrmnl_ae_set_curlifetime@libnl_3 3.5.0-1 + xfrmnl_ae_set_daddr@Base 3.5.0-1 + xfrmnl_ae_set_daddr@libnl_3 3.5.0-1 + xfrmnl_ae_set_family@Base 3.5.0-1 + xfrmnl_ae_set_family@libnl_3 3.5.0-1 + xfrmnl_ae_set_flags@Base 3.5.0-1 + xfrmnl_ae_set_flags@libnl_3 3.5.0-1 + xfrmnl_ae_set_mark@Base 3.5.0-1 + xfrmnl_ae_set_mark@libnl_3 3.5.0-1 + xfrmnl_ae_set_proto@Base 3.5.0-1 + xfrmnl_ae_set_proto@libnl_3 3.5.0-1 + xfrmnl_ae_set_replay_maxage@Base 3.5.0-1 + xfrmnl_ae_set_replay_maxage@libnl_3 3.5.0-1 + xfrmnl_ae_set_replay_maxdiff@Base 3.5.0-1 + xfrmnl_ae_set_replay_maxdiff@libnl_3 3.5.0-1 + xfrmnl_ae_set_replay_state@Base 3.5.0-1 + xfrmnl_ae_set_replay_state@libnl_3 3.5.0-1 + xfrmnl_ae_set_replay_state_esn@Base 3.5.0-1 + xfrmnl_ae_set_replay_state_esn@libnl_3 3.5.0-1 + xfrmnl_ae_set_reqid@Base 3.5.0-1 + xfrmnl_ae_set_reqid@libnl_3 3.5.0-1 + xfrmnl_ae_set_saddr@Base 3.5.0-1 + xfrmnl_ae_set_saddr@libnl_3 3.5.0-1 + xfrmnl_ae_set_spi@Base 3.5.0-1 + xfrmnl_ae_set_spi@libnl_3 3.5.0-1 + xfrmnl_ae_str2flag@Base 3.5.0-1 + xfrmnl_ae_str2flag@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_alloc@Base 3.5.0-1 + xfrmnl_ltime_cfg_alloc@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_clone@Base 3.5.0-1 + xfrmnl_ltime_cfg_clone@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_cmp@Base 3.5.0-1 + xfrmnl_ltime_cfg_cmp@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get@Base 3.5.0-1 + xfrmnl_ltime_cfg_get@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_addexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_addexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_bytelimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_bytelimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_packetlimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_packetlimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_useexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_useexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_addexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_addexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_bytelimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_bytelimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_packetlimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_packetlimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_useexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_useexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_put@Base 3.5.0-1 + xfrmnl_ltime_cfg_put@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_addexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_addexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_bytelimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_bytelimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_packetlimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_packetlimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_useexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_useexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_addexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_addexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_bytelimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_bytelimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_packetlimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_packetlimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_useexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_useexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_shared@Base 3.5.0-1 + xfrmnl_ltime_cfg_shared@libnl_3 3.5.0-1 + xfrmnl_sa_add@Base 3.5.0-1 + xfrmnl_sa_add@libnl_3 3.5.0-1 + xfrmnl_sa_alloc@Base 3.5.0-1 + xfrmnl_sa_alloc@libnl_3 3.5.0-1 + xfrmnl_sa_alloc_cache@Base 3.5.0-1 + xfrmnl_sa_alloc_cache@libnl_3 3.5.0-1 + xfrmnl_sa_build_add_request@Base 3.5.0-1 + xfrmnl_sa_build_add_request@libnl_3 3.5.0-1 + xfrmnl_sa_build_delete_request@Base 3.5.0-1 + xfrmnl_sa_build_delete_request@libnl_3 3.5.0-1 + xfrmnl_sa_build_get_request@Base 3.5.0-1 + xfrmnl_sa_build_get_request@libnl_3 3.5.0-1 + xfrmnl_sa_build_update_request@Base 3.5.0-1 + xfrmnl_sa_build_update_request@libnl_3 3.5.0-1 + xfrmnl_sa_delete@Base 3.5.0-1 + xfrmnl_sa_delete@libnl_3 3.5.0-1 + xfrmnl_sa_flags2str@Base 3.5.0-1 + xfrmnl_sa_flags2str@libnl_3 3.5.0-1 + xfrmnl_sa_get@Base 3.5.0-1 + xfrmnl_sa_get@libnl_3 3.5.0-1 + xfrmnl_sa_get_aead_params@Base 3.5.0-1 + xfrmnl_sa_get_aead_params@libnl_3 3.5.0-1 + xfrmnl_sa_get_auth_params@Base 3.5.0-1 + xfrmnl_sa_get_auth_params@libnl_3 3.5.0-1 + xfrmnl_sa_get_coaddr@Base 3.5.0-1 + xfrmnl_sa_get_coaddr@libnl_3 3.5.0-1 + xfrmnl_sa_get_comp_params@Base 3.5.0-1 + xfrmnl_sa_get_comp_params@libnl_3 3.5.0-1 + xfrmnl_sa_get_crypto_params@Base 3.5.0-1 + xfrmnl_sa_get_crypto_params@libnl_3 3.5.0-1 + xfrmnl_sa_get_curlifetime@Base 3.5.0-1 + xfrmnl_sa_get_curlifetime@libnl_3 3.5.0-1 + xfrmnl_sa_get_daddr@Base 3.5.0-1 + xfrmnl_sa_get_daddr@libnl_3 3.5.0-1 + xfrmnl_sa_get_encap_tmpl@Base 3.5.0-1 + xfrmnl_sa_get_encap_tmpl@libnl_3 3.5.0-1 + xfrmnl_sa_get_family@Base 3.5.0-1 + xfrmnl_sa_get_family@libnl_3 3.5.0-1 + xfrmnl_sa_get_flags@Base 3.5.0-1 + xfrmnl_sa_get_flags@libnl_3 3.5.0-1 + xfrmnl_sa_get_kernel@Base 3.5.0-1 + xfrmnl_sa_get_kernel@libnl_3 3.5.0-1 + xfrmnl_sa_get_lifetime_cfg@Base 3.5.0-1 + xfrmnl_sa_get_lifetime_cfg@libnl_3 3.5.0-1 + xfrmnl_sa_get_mark@Base 3.5.0-1 + xfrmnl_sa_get_mark@libnl_3 3.5.0-1 + xfrmnl_sa_get_mode@Base 3.5.0-1 + xfrmnl_sa_get_mode@libnl_3 3.5.0-1 + xfrmnl_sa_get_proto@Base 3.5.0-1 + xfrmnl_sa_get_proto@libnl_3 3.5.0-1 + xfrmnl_sa_get_replay_maxage@Base 3.5.0-1 + xfrmnl_sa_get_replay_maxage@libnl_3 3.5.0-1 + xfrmnl_sa_get_replay_maxdiff@Base 3.5.0-1 + xfrmnl_sa_get_replay_maxdiff@libnl_3 3.5.0-1 + xfrmnl_sa_get_replay_state@Base 3.5.0-1 + xfrmnl_sa_get_replay_state@libnl_3 3.5.0-1 + xfrmnl_sa_get_replay_state_esn@Base 3.5.0-1 + xfrmnl_sa_get_replay_state_esn@libnl_3 3.5.0-1 + xfrmnl_sa_get_replay_window@Base 3.5.0-1 + xfrmnl_sa_get_replay_window@libnl_3 3.5.0-1 + xfrmnl_sa_get_reqid@Base 3.5.0-1 + xfrmnl_sa_get_reqid@libnl_3 3.5.0-1 + xfrmnl_sa_get_saddr@Base 3.5.0-1 + xfrmnl_sa_get_saddr@libnl_3 3.5.0-1 + xfrmnl_sa_get_sec_ctx@Base 3.5.0-1 + xfrmnl_sa_get_sec_ctx@libnl_3 3.5.0-1 + xfrmnl_sa_get_sel@Base 3.5.0-1 + xfrmnl_sa_get_sel@libnl_3 3.5.0-1 + xfrmnl_sa_get_seq@Base 3.5.0-1 + xfrmnl_sa_get_seq@libnl_3 3.5.0-1 + xfrmnl_sa_get_spi@Base 3.5.0-1 + xfrmnl_sa_get_spi@libnl_3 3.5.0-1 + xfrmnl_sa_get_stats@Base 3.5.0-1 + xfrmnl_sa_get_stats@libnl_3 3.5.0-1 + xfrmnl_sa_get_tfcpad@Base 3.5.0-1 + xfrmnl_sa_get_tfcpad@libnl_3 3.5.0-1 + xfrmnl_sa_is_expiry_reached@Base 3.5.0-1 + xfrmnl_sa_is_expiry_reached@libnl_3 3.5.0-1 + xfrmnl_sa_is_hardexpiry_reached@Base 3.5.0-1 + xfrmnl_sa_is_hardexpiry_reached@libnl_3 3.5.0-1 + xfrmnl_sa_mode2str@Base 3.5.0-1 + xfrmnl_sa_mode2str@libnl_3 3.5.0-1 + xfrmnl_sa_parse@Base 3.5.0-1 + xfrmnl_sa_parse@libnl_3 3.5.0-1 + xfrmnl_sa_put@Base 3.5.0-1 + xfrmnl_sa_put@libnl_3 3.5.0-1 + xfrmnl_sa_set_aead_params@Base 3.5.0-1 + xfrmnl_sa_set_aead_params@libnl_3 3.5.0-1 + xfrmnl_sa_set_auth_params@Base 3.5.0-1 + xfrmnl_sa_set_auth_params@libnl_3 3.5.0-1 + xfrmnl_sa_set_coaddr@Base 3.5.0-1 + xfrmnl_sa_set_coaddr@libnl_3 3.5.0-1 + xfrmnl_sa_set_comp_params@Base 3.5.0-1 + xfrmnl_sa_set_comp_params@libnl_3 3.5.0-1 + xfrmnl_sa_set_crypto_params@Base 3.5.0-1 + xfrmnl_sa_set_crypto_params@libnl_3 3.5.0-1 + xfrmnl_sa_set_daddr@Base 3.5.0-1 + xfrmnl_sa_set_daddr@libnl_3 3.5.0-1 + xfrmnl_sa_set_encap_tmpl@Base 3.5.0-1 + xfrmnl_sa_set_encap_tmpl@libnl_3 3.5.0-1 + xfrmnl_sa_set_family@Base 3.5.0-1 + xfrmnl_sa_set_family@libnl_3 3.5.0-1 + xfrmnl_sa_set_flags@Base 3.5.0-1 + xfrmnl_sa_set_flags@libnl_3 3.5.0-1 + xfrmnl_sa_set_lifetime_cfg@Base 3.5.0-1 + xfrmnl_sa_set_lifetime_cfg@libnl_3 3.5.0-1 + xfrmnl_sa_set_mark@Base 3.5.0-1 + xfrmnl_sa_set_mark@libnl_3 3.5.0-1 + xfrmnl_sa_set_mode@Base 3.5.0-1 + xfrmnl_sa_set_mode@libnl_3 3.5.0-1 + xfrmnl_sa_set_proto@Base 3.5.0-1 + xfrmnl_sa_set_proto@libnl_3 3.5.0-1 + xfrmnl_sa_set_replay_maxage@Base 3.5.0-1 + xfrmnl_sa_set_replay_maxage@libnl_3 3.5.0-1 + xfrmnl_sa_set_replay_maxdiff@Base 3.5.0-1 + xfrmnl_sa_set_replay_maxdiff@libnl_3 3.5.0-1 + xfrmnl_sa_set_replay_state@Base 3.5.0-1 + xfrmnl_sa_set_replay_state@libnl_3 3.5.0-1 + xfrmnl_sa_set_replay_state_esn@Base 3.5.0-1 + xfrmnl_sa_set_replay_state_esn@libnl_3 3.5.0-1 + xfrmnl_sa_set_replay_window@Base 3.5.0-1 + xfrmnl_sa_set_replay_window@libnl_3 3.5.0-1 + xfrmnl_sa_set_reqid@Base 3.5.0-1 + xfrmnl_sa_set_reqid@libnl_3 3.5.0-1 + xfrmnl_sa_set_saddr@Base 3.5.0-1 + xfrmnl_sa_set_saddr@libnl_3 3.5.0-1 + xfrmnl_sa_set_sec_ctx@Base 3.5.0-1 + xfrmnl_sa_set_sec_ctx@libnl_3 3.5.0-1 + xfrmnl_sa_set_sel@Base 3.5.0-1 + xfrmnl_sa_set_sel@libnl_3 3.5.0-1 + xfrmnl_sa_set_spi@Base 3.5.0-1 + xfrmnl_sa_set_spi@libnl_3 3.5.0-1 + xfrmnl_sa_set_tfcpad@Base 3.5.0-1 + xfrmnl_sa_set_tfcpad@libnl_3 3.5.0-1 + xfrmnl_sa_str2flag@Base 3.5.0-1 + xfrmnl_sa_str2flag@libnl_3 3.5.0-1 + xfrmnl_sa_str2mode@Base 3.5.0-1 + xfrmnl_sa_str2mode@libnl_3 3.5.0-1 + xfrmnl_sa_update@Base 3.5.0-1 + xfrmnl_sa_update@libnl_3 3.5.0-1 + xfrmnl_sel_alloc@Base 3.5.0-1 + xfrmnl_sel_alloc@libnl_3 3.5.0-1 + xfrmnl_sel_clone@Base 3.5.0-1 + xfrmnl_sel_clone@libnl_3 3.5.0-1 + xfrmnl_sel_cmp@Base 3.5.0-1 + xfrmnl_sel_cmp@libnl_3 3.5.0-1 + xfrmnl_sel_dump@Base 3.5.0-1 + xfrmnl_sel_dump@libnl_3 3.5.0-1 + xfrmnl_sel_get@Base 3.5.0-1 + xfrmnl_sel_get@libnl_3 3.5.0-1 + xfrmnl_sel_get_daddr@Base 3.5.0-1 + xfrmnl_sel_get_daddr@libnl_3 3.5.0-1 + xfrmnl_sel_get_dport@Base 3.5.0-1 + xfrmnl_sel_get_dport@libnl_3 3.5.0-1 + xfrmnl_sel_get_dportmask@Base 3.5.0-1 + xfrmnl_sel_get_dportmask@libnl_3 3.5.0-1 + xfrmnl_sel_get_family@Base 3.5.0-1 + xfrmnl_sel_get_family@libnl_3 3.5.0-1 + xfrmnl_sel_get_ifindex@Base 3.5.0-1 + xfrmnl_sel_get_ifindex@libnl_3 3.5.0-1 + xfrmnl_sel_get_prefixlen_d@Base 3.5.0-1 + xfrmnl_sel_get_prefixlen_d@libnl_3 3.5.0-1 + xfrmnl_sel_get_prefixlen_s@Base 3.5.0-1 + xfrmnl_sel_get_prefixlen_s@libnl_3 3.5.0-1 + xfrmnl_sel_get_proto@Base 3.5.0-1 + xfrmnl_sel_get_proto@libnl_3 3.5.0-1 + xfrmnl_sel_get_saddr@Base 3.5.0-1 + xfrmnl_sel_get_saddr@libnl_3 3.5.0-1 + xfrmnl_sel_get_sport@Base 3.5.0-1 + xfrmnl_sel_get_sport@libnl_3 3.5.0-1 + xfrmnl_sel_get_sportmask@Base 3.5.0-1 + xfrmnl_sel_get_sportmask@libnl_3 3.5.0-1 + xfrmnl_sel_get_userid@Base 3.5.0-1 + xfrmnl_sel_get_userid@libnl_3 3.5.0-1 + xfrmnl_sel_put@Base 3.5.0-1 + xfrmnl_sel_put@libnl_3 3.5.0-1 + xfrmnl_sel_set_daddr@Base 3.5.0-1 + xfrmnl_sel_set_daddr@libnl_3 3.5.0-1 + xfrmnl_sel_set_dport@Base 3.5.0-1 + xfrmnl_sel_set_dport@libnl_3 3.5.0-1 + xfrmnl_sel_set_dportmask@Base 3.5.0-1 + xfrmnl_sel_set_dportmask@libnl_3 3.5.0-1 + xfrmnl_sel_set_family@Base 3.5.0-1 + xfrmnl_sel_set_family@libnl_3 3.5.0-1 + xfrmnl_sel_set_ifindex@Base 3.5.0-1 + xfrmnl_sel_set_ifindex@libnl_3 3.5.0-1 + xfrmnl_sel_set_prefixlen_d@Base 3.5.0-1 + xfrmnl_sel_set_prefixlen_d@libnl_3 3.5.0-1 + xfrmnl_sel_set_prefixlen_s@Base 3.5.0-1 + xfrmnl_sel_set_prefixlen_s@libnl_3 3.5.0-1 + xfrmnl_sel_set_proto@Base 3.5.0-1 + xfrmnl_sel_set_proto@libnl_3 3.5.0-1 + xfrmnl_sel_set_saddr@Base 3.5.0-1 + xfrmnl_sel_set_saddr@libnl_3 3.5.0-1 + xfrmnl_sel_set_sport@Base 3.5.0-1 + xfrmnl_sel_set_sport@libnl_3 3.5.0-1 + xfrmnl_sel_set_sportmask@Base 3.5.0-1 + xfrmnl_sel_set_sportmask@libnl_3 3.5.0-1 + xfrmnl_sel_set_userid@Base 3.5.0-1 + xfrmnl_sel_set_userid@libnl_3 3.5.0-1 + xfrmnl_sel_shared@Base 3.5.0-1 + xfrmnl_sel_shared@libnl_3 3.5.0-1 + xfrmnl_sp_action2str@Base 3.5.0-1 + xfrmnl_sp_action2str@libnl_3 3.5.0-1 + xfrmnl_sp_add@Base 3.5.0-1 + xfrmnl_sp_add@libnl_3 3.5.0-1 + xfrmnl_sp_add_usertemplate@Base 3.5.0-1 + xfrmnl_sp_add_usertemplate@libnl_3 3.5.0-1 + xfrmnl_sp_alloc@Base 3.5.0-1 + xfrmnl_sp_alloc@libnl_3 3.5.0-1 + xfrmnl_sp_alloc_cache@Base 3.5.0-1 + xfrmnl_sp_alloc_cache@libnl_3 3.5.0-1 + xfrmnl_sp_build_add_request@Base 3.5.0-1 + xfrmnl_sp_build_add_request@libnl_3 3.5.0-1 + xfrmnl_sp_build_delete_request@Base 3.5.0-1 + xfrmnl_sp_build_delete_request@libnl_3 3.5.0-1 + xfrmnl_sp_build_get_request@Base 3.5.0-1 + xfrmnl_sp_build_get_request@libnl_3 3.5.0-1 + xfrmnl_sp_build_update_request@Base 3.5.0-1 + xfrmnl_sp_build_update_request@libnl_3 3.5.0-1 + xfrmnl_sp_delete@Base 3.5.0-1 + xfrmnl_sp_delete@libnl_3 3.5.0-1 + xfrmnl_sp_dir2str@Base 3.5.0-1 + xfrmnl_sp_dir2str@libnl_3 3.5.0-1 + xfrmnl_sp_flags2str@Base 3.5.0-1 + xfrmnl_sp_flags2str@libnl_3 3.5.0-1 + xfrmnl_sp_foreach_usertemplate@Base 3.5.0-1 + xfrmnl_sp_foreach_usertemplate@libnl_3 3.5.0-1 + xfrmnl_sp_get@Base 3.5.0-1 + xfrmnl_sp_get@libnl_3 3.5.0-1 + xfrmnl_sp_get_action@Base 3.5.0-1 + xfrmnl_sp_get_action@libnl_3 3.5.0-1 + xfrmnl_sp_get_curlifetime@Base 3.5.0-1 + xfrmnl_sp_get_curlifetime@libnl_3 3.5.0-1 + xfrmnl_sp_get_dir@Base 3.5.0-1 + xfrmnl_sp_get_dir@libnl_3 3.5.0-1 + xfrmnl_sp_get_flags@Base 3.5.0-1 + xfrmnl_sp_get_flags@libnl_3 3.5.0-1 + xfrmnl_sp_get_index@Base 3.5.0-1 + xfrmnl_sp_get_index@libnl_3 3.5.0-1 + xfrmnl_sp_get_kernel@Base 3.5.0-1 + xfrmnl_sp_get_kernel@libnl_3 3.5.0-1 + xfrmnl_sp_get_lifetime_cfg@Base 3.5.0-1 + xfrmnl_sp_get_lifetime_cfg@libnl_3 3.5.0-1 + xfrmnl_sp_get_mark@Base 3.5.0-1 + xfrmnl_sp_get_mark@libnl_3 3.5.0-1 + xfrmnl_sp_get_nusertemplates@Base 3.5.0-1 + xfrmnl_sp_get_nusertemplates@libnl_3 3.5.0-1 + xfrmnl_sp_get_priority@Base 3.5.0-1 + xfrmnl_sp_get_priority@libnl_3 3.5.0-1 + xfrmnl_sp_get_sec_ctx@Base 3.5.0-1 + xfrmnl_sp_get_sec_ctx@libnl_3 3.5.0-1 + xfrmnl_sp_get_sel@Base 3.5.0-1 + xfrmnl_sp_get_sel@libnl_3 3.5.0-1 + xfrmnl_sp_get_share@Base 3.5.0-1 + xfrmnl_sp_get_share@libnl_3 3.5.0-1 + xfrmnl_sp_get_userpolicy_type@Base 3.5.0-1 + xfrmnl_sp_get_userpolicy_type@libnl_3 3.5.0-1 + xfrmnl_sp_get_usertemplates@Base 3.5.0-1 + xfrmnl_sp_get_usertemplates@libnl_3 3.5.0-1 + xfrmnl_sp_index2dir@Base 3.5.0-1 + xfrmnl_sp_index2dir@libnl_3 3.5.0-1 + xfrmnl_sp_parse@Base 3.5.0-1 + xfrmnl_sp_parse@libnl_3 3.5.0-1 + xfrmnl_sp_put@Base 3.5.0-1 + xfrmnl_sp_put@libnl_3 3.5.0-1 + xfrmnl_sp_remove_usertemplate@Base 3.5.0-1 + xfrmnl_sp_remove_usertemplate@libnl_3 3.5.0-1 + xfrmnl_sp_set_action@Base 3.5.0-1 + xfrmnl_sp_set_action@libnl_3 3.5.0-1 + xfrmnl_sp_set_dir@Base 3.5.0-1 + xfrmnl_sp_set_dir@libnl_3 3.5.0-1 + xfrmnl_sp_set_flags@Base 3.5.0-1 + xfrmnl_sp_set_flags@libnl_3 3.5.0-1 + xfrmnl_sp_set_index@Base 3.5.0-1 + xfrmnl_sp_set_index@libnl_3 3.5.0-1 + xfrmnl_sp_set_lifetime_cfg@Base 3.5.0-1 + xfrmnl_sp_set_lifetime_cfg@libnl_3 3.5.0-1 + xfrmnl_sp_set_mark@Base 3.5.0-1 + xfrmnl_sp_set_mark@libnl_3 3.5.0-1 + xfrmnl_sp_set_priority@Base 3.5.0-1 + xfrmnl_sp_set_priority@libnl_3 3.5.0-1 + xfrmnl_sp_set_sec_ctx@Base 3.5.0-1 + xfrmnl_sp_set_sec_ctx@libnl_3 3.5.0-1 + xfrmnl_sp_set_sel@Base 3.5.0-1 + xfrmnl_sp_set_sel@libnl_3 3.5.0-1 + xfrmnl_sp_set_share@Base 3.5.0-1 + xfrmnl_sp_set_share@libnl_3 3.5.0-1 + xfrmnl_sp_set_userpolicy_type@Base 3.5.0-1 + xfrmnl_sp_set_userpolicy_type@libnl_3 3.5.0-1 + xfrmnl_sp_share2str@Base 3.5.0-1 + xfrmnl_sp_share2str@libnl_3 3.5.0-1 + xfrmnl_sp_str2action@Base 3.5.0-1 + xfrmnl_sp_str2action@libnl_3 3.5.0-1 + xfrmnl_sp_str2dir@Base 3.5.0-1 + xfrmnl_sp_str2dir@libnl_3 3.5.0-1 + xfrmnl_sp_str2flag@Base 3.5.0-1 + xfrmnl_sp_str2flag@libnl_3 3.5.0-1 + xfrmnl_sp_str2share@Base 3.5.0-1 + xfrmnl_sp_str2share@libnl_3 3.5.0-1 + xfrmnl_sp_str2type@Base 3.5.0-1 + xfrmnl_sp_str2type@libnl_3 3.5.0-1 + xfrmnl_sp_type2str@Base 3.5.0-1 + xfrmnl_sp_type2str@libnl_3 3.5.0-1 + xfrmnl_sp_update@Base 3.5.0-1 + xfrmnl_sp_update@libnl_3 3.5.0-1 + xfrmnl_sp_usertemplate_n@Base 3.5.0-1 + xfrmnl_sp_usertemplate_n@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_alloc@Base 3.5.0-1 + xfrmnl_user_tmpl_alloc@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_clone@Base 3.5.0-1 + xfrmnl_user_tmpl_clone@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_cmp@Base 3.5.0-1 + xfrmnl_user_tmpl_cmp@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_dump@Base 3.5.0-1 + xfrmnl_user_tmpl_dump@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_free@Base 3.5.0-1 + xfrmnl_user_tmpl_free@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_aalgos@Base 3.5.0-1 + xfrmnl_user_tmpl_get_aalgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_calgos@Base 3.5.0-1 + xfrmnl_user_tmpl_get_calgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_daddr@Base 3.5.0-1 + xfrmnl_user_tmpl_get_daddr@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_ealgos@Base 3.5.0-1 + xfrmnl_user_tmpl_get_ealgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_family@Base 3.5.0-1 + xfrmnl_user_tmpl_get_family@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_mode@Base 3.5.0-1 + xfrmnl_user_tmpl_get_mode@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_optional@Base 3.5.0-1 + xfrmnl_user_tmpl_get_optional@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_proto@Base 3.5.0-1 + xfrmnl_user_tmpl_get_proto@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_reqid@Base 3.5.0-1 + xfrmnl_user_tmpl_get_reqid@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_saddr@Base 3.5.0-1 + xfrmnl_user_tmpl_get_saddr@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_share@Base 3.5.0-1 + xfrmnl_user_tmpl_get_share@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_spi@Base 3.5.0-1 + xfrmnl_user_tmpl_get_spi@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_mode2str@Base 3.5.0-1 + xfrmnl_user_tmpl_mode2str@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_aalgos@Base 3.5.0-1 + xfrmnl_user_tmpl_set_aalgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_calgos@Base 3.5.0-1 + xfrmnl_user_tmpl_set_calgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_daddr@Base 3.5.0-1 + xfrmnl_user_tmpl_set_daddr@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_ealgos@Base 3.5.0-1 + xfrmnl_user_tmpl_set_ealgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_family@Base 3.5.0-1 + xfrmnl_user_tmpl_set_family@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_mode@Base 3.5.0-1 + xfrmnl_user_tmpl_set_mode@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_optional@Base 3.5.0-1 + xfrmnl_user_tmpl_set_optional@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_proto@Base 3.5.0-1 + xfrmnl_user_tmpl_set_proto@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_reqid@Base 3.5.0-1 + xfrmnl_user_tmpl_set_reqid@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_saddr@Base 3.5.0-1 + xfrmnl_user_tmpl_set_saddr@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_share@Base 3.5.0-1 + xfrmnl_user_tmpl_set_share@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_spi@Base 3.5.0-1 + xfrmnl_user_tmpl_set_spi@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_str2mode@Base 3.5.0-1 + xfrmnl_user_tmpl_str2mode@libnl_3 3.5.0-1 diff --git a/src/libnl3/debian/libnl-xfrm-3-dev.install b/src/libnl3/debian/libnl-xfrm-3-dev.install new file mode 100644 index 000000000000..f57e152c5aae --- /dev/null +++ b/src/libnl3/debian/libnl-xfrm-3-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/*/pkgconfig/libnl-xfrm-3* +debian/tmp/usr/lib/*/libnl-xfrm-3*.so +debian/tmp/usr/lib/*/libnl-xfrm-3*.a diff --git a/src/libnl3/debian/patches/series b/src/libnl3/debian/patches/series new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/libnl3/debian/rules b/src/libnl3/debian/rules new file mode 100755 index 000000000000..bb33dda05a64 --- /dev/null +++ b/src/libnl3/debian/rules @@ -0,0 +1,39 @@ +#!/usr/bin/make -f + +DEB_BUILDDIR = debian/build +DEB_MAKE_FLAVORS = main udeb + +udeb_libnl=libnl-3-200-udeb +udeb_libnl_genl=libnl-genl-3-200-udeb + +TG_BRANCHES := debian/etc-libnl-3,debian/out-of-tree,debian/no-symvers + +-include /usr/share/topgit/tg2quilt.mk + +# to export the patch series use +# debian/rules tg-clean +# debian/rules tg-export + + +include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/cdbs/1/rules/autoreconf.mk +include /usr/share/cdbs/1/class/autotools.mk + +# FIXME: not honoured +#CFLAGS_udeb += $(CFLAGS) -Os +CFLAGS += $(if $(findstring udeb,$(cdbs_make_curflavor)),-Os) + +DEB_DH_STRIP_ARGS := --dbg-package=libnl-3-200-dbg +DEB_DH_MAKESHLIBS_ARGS_libnl-3-200 := --add-udeb=$(udeb_libnl) +DEB_DH_MAKESHLIBS_ARGS_libnl-genl-3-200 := --add-udeb=$(udeb_libnl_genl) + +DEB_MAKE_DESTDIRSKEL = $(CURDIR)/debian/tmp +DEB_MAKE_DESTDIRSKEL_udeb = $(CURDIR)/debian/tmp/udeb + +DEB_DH_INSTALL_ARGS_$(udeb) += --sourcedir=debian/tmp/udeb + +DEB_CONFIGURE_EXTRA_FLAGS += --libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) + +clean:: + # from some unknown reason CDBS does not remove the builddir + rm -rf $(DEB_BUILDDIR) diff --git a/src/libnl3/debian/source/format b/src/libnl3/debian/source/format new file mode 100644 index 000000000000..163aaf8d82b6 --- /dev/null +++ b/src/libnl3/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/src/libnl3/debian/watch b/src/libnl3/debian/watch new file mode 100644 index 000000000000..9939913ca0e0 --- /dev/null +++ b/src/libnl3/debian/watch @@ -0,0 +1,2 @@ +version=3 +https://github.com/thom311/libnl/releases/libnl-(.*)\.tar\.gz diff --git a/src/libteam/patch/0011-teamd-fix-possible-race-in-master-ifname-callback.patch b/src/libteam/patch/0011-teamd-fix-possible-race-in-master-ifname-callback.patch new file mode 100644 index 000000000000..9203cd17c58b --- /dev/null +++ b/src/libteam/patch/0011-teamd-fix-possible-race-in-master-ifname-callback.patch @@ -0,0 +1,101 @@ +From c0eb9e4bfe1c6a0e77f02b1459d91498c1a3dcff Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Tue, 4 Feb 2020 09:39:08 -0800 +Subject: [PATCH 1/1] teamd: fix possible race in master ifname callback + +--- + teamd/teamd.h | 2 ++ + teamd/teamd_link_watch.c | 13 ++++++++++--- + teamd/teamd_per_port.c | 24 +++++++++++++++++++----- + 3 files changed, 31 insertions(+), 8 deletions(-) + +diff --git a/teamd/teamd.h b/teamd/teamd.h +index 418214d..1ce120e 100644 +--- a/teamd/teamd.h ++++ b/teamd/teamd.h +@@ -334,6 +334,8 @@ int teamd_port_remove_all(struct teamd_context *ctx); + void teamd_port_obj_remove_all(struct teamd_context *ctx); + int teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport, + bool *enabled); ++int teamd_port_enabled_check(struct teamd_context *ctx, ++ struct teamd_port *tdport, bool *enabled); + int teamd_port_prio(struct teamd_context *ctx, struct teamd_port *tdport); + int teamd_port_check_enable(struct teamd_context *ctx, + struct teamd_port *tdport, +diff --git a/teamd/teamd_link_watch.c b/teamd/teamd_link_watch.c +index 62f8267..e4b3d3f 100644 +--- a/teamd/teamd_link_watch.c ++++ b/teamd/teamd_link_watch.c +@@ -423,9 +423,16 @@ static int link_watch_refresh_forced_send(struct teamd_context *ctx) + int err; + + teamd_for_each_tdport(tdport, ctx) { +- err = teamd_port_enabled(ctx, tdport, &port_enabled); +- if (err) +- return err; ++ err = teamd_port_enabled_check(ctx, tdport, &port_enabled); ++ if (err) { ++ /* Looks like the options are not ready for this port. ++ * This can happen when called from ++ * link_watch_port_master_ifindex_changed(). Skip this ++ * for now, let it be handled by future call of ++ * link_watch_enabled_option_changed(). ++ */ ++ continue; ++ } + __set_forced_send_for_port(tdport, port_enabled); + if (port_enabled) + enabled_port_count++; +diff --git a/teamd/teamd_per_port.c b/teamd/teamd_per_port.c +index a87e809..d10cfb2 100644 +--- a/teamd/teamd_per_port.c ++++ b/teamd/teamd_per_port.c +@@ -395,19 +395,21 @@ int teamd_port_remove_ifname(struct teamd_context *ctx, const char *port_name) + return teamd_port_remove(ctx, tdport); + } + +-int teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport, +- bool *enabled) ++int __teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport, ++ bool *enabled, bool may_fail) + { + struct team_option *option; + + option = team_get_option(ctx->th, "np", "enabled", tdport->ifindex); + if (!option) { +- teamd_log_err("%s: Failed to find \"enabled\" option.", +- tdport->ifname); ++ if (!may_fail) ++ teamd_log_err("%s: Failed to find \"enabled\" option.", ++ tdport->ifname); + return -ENOENT; + } + if (team_get_option_type(option) != TEAM_OPTION_TYPE_BOOL) { +- teamd_log_err("Unexpected type of \"enabled\" option."); ++ if (!may_fail) ++ teamd_log_err("Unexpected type of \"enabled\" option."); + return -EINVAL; + } + +@@ -415,6 +417,18 @@ int teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport, + return 0; + } + ++int teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport, ++ bool *enabled) ++{ ++ return __teamd_port_enabled(ctx, tdport, enabled, false); ++} ++ ++int teamd_port_enabled_check(struct teamd_context *ctx, ++ struct teamd_port *tdport, bool *enabled) ++{ ++ return __teamd_port_enabled(ctx, tdport, enabled, true); ++} ++ + int teamd_port_prio(struct teamd_context *ctx, struct teamd_port *tdport) + { + int prio; +-- +2.17.1.windows.2 + diff --git a/src/libteam/patch/0012-teamd-Disregard-current-state-when-considering-port-.patch b/src/libteam/patch/0012-teamd-Disregard-current-state-when-considering-port-.patch new file mode 100644 index 000000000000..1673c4e4a9d1 --- /dev/null +++ b/src/libteam/patch/0012-teamd-Disregard-current-state-when-considering-port-.patch @@ -0,0 +1,67 @@ +From b9bde92fcc0586b327c577c41304e2ef938cff10 Mon Sep 17 00:00:00 2001 +From: Petr Machata +Date: Wed, 13 Nov 2019 13:26:47 +0000 +Subject: [PATCH] teamd: Disregard current state when considering port + enablement + +On systems where carrier is gained very quickly, there is a race between +teamd and the kernel that sometimes leads to all team slaves being stuck in +enabled=false state. + +When a port is enslaved to a team device, the kernel sends a netlink +message marking the port as enabled. teamd's lb_event_watch_port_added() +calls team_set_port_enabled(false), because link is down at that point. The +kernel responds with a message marking the port as disabled. At this point, +there are two outstanding messages: the initial one marking port as +enabled, and the second one marking it as disabled. teamd has not processed +either of these. + +Next teamd gets the netlink message that sets enabled=true, and updates its +internal cache accordingly. If at this point ethtool link-watch wakes up, +teamd considers (in teamd_port_check_enable()) enabling the port. After +consulting the cache, it concludes the port is already up, and neglects to +do so. Only then does teamd get the netlink message informing it of setting +enabled=false. + +The problem is that the teamd cache is not synchronous with respect to the +kernel state. If the carrier takes a while to come up (as is normally the +case), this is not a problem, because teamd caches up quickly enough. But +this may not always be the case, and particularly on a simulated system, +the carrier is gained almost immediately. + +Fix this by not suppressing the enablement message. + +Signed-off-by: Petr Machata +Signed-off-by: Jiri Pirko +--- + teamd/teamd_per_port.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/teamd/teamd_per_port.c b/teamd/teamd_per_port.c +index d10cfb2..8c63fec 100644 +--- a/teamd/teamd_per_port.c ++++ b/teamd/teamd_per_port.c +@@ -448,18 +448,14 @@ int teamd_port_check_enable(struct teamd_context *ctx, + bool should_enable, bool should_disable) + { + bool new_enabled_state; +- bool curr_enabled_state; + int err; + + if (!teamd_port_present(ctx, tdport)) + return 0; +- err = teamd_port_enabled(ctx, tdport, &curr_enabled_state); +- if (err) +- return err; + +- if (!curr_enabled_state && should_enable) ++ if (should_enable) + new_enabled_state = true; +- else if (curr_enabled_state && should_disable) ++ else if (should_disable) + new_enabled_state = false; + else + return 0; +-- +2.17.1.windows.2 + diff --git a/src/libteam/patch/series b/src/libteam/patch/series index 7be69525d9d0..966be75fda8a 100644 --- a/src/libteam/patch/series +++ b/src/libteam/patch/series @@ -8,3 +8,5 @@ 0008-libteam-Add-warm_reboot-mode.patch 0009-Fix-ifinfo_link_with_port-race-condition-with-newlink.patch 0010-When-read-of-timerfd-returned-0-don-t-consider-this-.patch +0011-teamd-fix-possible-race-in-master-ifname-callback.patch +0012-teamd-Disregard-current-state-when-considering-port-.patch diff --git a/src/lm-sensors/0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch b/src/lm-sensors/0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch new file mode 100644 index 000000000000..6d3e279ea5e7 --- /dev/null +++ b/src/lm-sensors/0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch @@ -0,0 +1,23 @@ +From b11fd3d516b62c01513d289bc901820aa150c63e Mon Sep 17 00:00:00 2001 +From: Charlie Chen +Date: Wed, 1 Apr 2020 06:59:06 +0000 +Subject: Patch to peform dh_installinit to include sensord.install in the + packed deb + +Signed-off-by: Charlie Chen +--- + debian/rules | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/rules b/src/lm-sensors/lm-sensors-3.4.0/debian/rules +index 5ebda06..1d77e28 100755 +--- a/src/lm-sensors/lm-sensors-3.4.0/debian/rules ++++ b/src/lm-sensors/lm-sensors-3.4.0/debian/rules +@@ -56,3 +56,4 @@ override_dh_auto_install-arch: + + override_dh_installinit-arch: + dh_installinit -plm-sensors --no-start ++ dh_installinit -psensord --no-start +-- +2.17.1 + diff --git a/src/snmpd/patch-5.7.3+dfsg/0004-Disable-SNMPv1.patch b/src/snmpd/patch-5.7.3+dfsg/0004-Disable-SNMPv1.patch deleted file mode 100644 index 6782a18c7758..000000000000 --- a/src/snmpd/patch-5.7.3+dfsg/0004-Disable-SNMPv1.patch +++ /dev/null @@ -1,25 +0,0 @@ -From db633987abf1ea093cb1785b3cd37adfdb55e4cc Mon Sep 17 00:00:00 2001 -From: Qi Luo -Date: Mon, 15 Oct 2018 22:30:28 +0000 -Subject: [PATCH] Disable SNMPv1 - -Signed-off-by: Qi Luo ---- - debian/rules | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/debian/rules b/debian/rules -index 9eb8d2d..4c3b5b6 100755 ---- a/debian/rules -+++ b/debian/rules -@@ -42,6 +42,7 @@ endif - override_dh_auto_configure: - dh_auto_configure -- --prefix=/usr --sysconfdir=/etc --mandir=/usr/share/man \ - --with-persistent-directory=/var/lib/snmp \ -+ --disable-snmpv1 \ - --enable-ucd-snmp-compatibility \ - --enable-shared --with-cflags="$(CFLAGS) -DNETSNMP_USE_INLINE" \ - --with-ldflags="$(LDFLAGS)" \ --- -2.18.0 - diff --git a/src/snmpd/patch-5.7.3+dfsg/series b/src/snmpd/patch-5.7.3+dfsg/series index 5cd0b06510f6..428a81eb6b22 100644 --- a/src/snmpd/patch-5.7.3+dfsg/series +++ b/src/snmpd/patch-5.7.3+dfsg/series @@ -1,7 +1,6 @@ 0001-SNMP-Stop-spamming-logs-with-statfs-permission-denie.patch 0002-at.c-properly-check-return-status-from-realloc.-Than.patch 0003-CHANGES-BUG-2743-snmpd-crashes-when-receiving-a-GetN.patch -0004-Disable-SNMPv1.patch 0005-Port-OpenSSL-1.1.0-with-support-for-1.0.2.patch 0006-From-Jiri-Cervenka-snmpd-Fixed-agentx-crashing-and-or-freezing-on-timeout.patch 0007-Linux-VRF-5.7.3-Support.patch diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 3ba6362c6ff0..c640d1378614 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -257,7 +257,14 @@ def parse_dpg(dpg, hname): aclintfs = child.find(str(QName(ns, "AclInterfaces"))) acls = {} for aclintf in aclintfs.findall(str(QName(ns, "AclInterface"))): - aclname = aclintf.find(str(QName(ns, "InAcl"))).text.upper().replace(" ", "_").replace("-", "_") + if aclintf.find(str(QName(ns, "InAcl"))) is not None: + aclname = aclintf.find(str(QName(ns, "InAcl"))).text.upper().replace(" ", "_").replace("-", "_") + stage = "ingress" + elif aclintf.find(str(QName(ns, "OutAcl"))) is not None: + aclname = aclintf.find(str(QName(ns, "OutAcl"))).text.upper().replace(" ", "_").replace("-", "_") + stage = "egress" + else: + system.exit("Error: 'AclInterface' must contain either an 'InAcl' or 'OutAcl' subelement.") aclattach = aclintf.find(str(QName(ns, "AttachTo"))).text.split(';') acl_intfs = [] is_mirror = False @@ -274,7 +281,7 @@ def parse_dpg(dpg, hname): # to LAG will be applied to all the LAG members internally by SAI/SDK acl_intfs.append(member) elif vlans.has_key(member): - print >> sys.stderr, "Warning: ACL " + aclname + " is attached to a Vlan interface, which is currently not supported" + acl_intfs.append(member) elif port_alias_map.has_key(member): acl_intfs.append(port_alias_map[member]) # Give a warning if trying to attach ACL to a LAG member interface, correct way is to attach ACL to the LAG interface @@ -297,13 +304,14 @@ def parse_dpg(dpg, hname): break if acl_intfs: acls[aclname] = {'policy_desc': aclname, + 'stage': stage, 'ports': acl_intfs} if is_mirror: acls[aclname]['type'] = 'MIRROR' elif is_mirror_v6: acls[aclname]['type'] = 'MIRRORV6' else: - acls[aclname]['type'] = 'L3' + acls[aclname]['type'] = 'L3V6' if 'v6' in aclname.lower() else 'L3' else: # This ACL has no interfaces to attach to -- consider this a control plane ACL try: @@ -321,6 +329,7 @@ def parse_dpg(dpg, hname): else: acls[aclname] = {'policy_desc': aclname, 'type': 'CTRLPLANE', + 'stage': stage, 'services': [aclservice]} except: print >> sys.stderr, "Warning: Ignoring Control Plane ACL %s without type" % aclname @@ -627,11 +636,6 @@ def parse_xml(filename, platform=None, port_config_file=None): 'hostname': hostname, 'hwsku': hwsku, 'type': current_device['type'] - }, - 'x509': { - 'server_crt': '/etc/sonic/telemetry/streamingtelemetryserver.cer', - 'server_key': '/etc/sonic/telemetry/streamingtelemetryserver.key', - 'ca_crt': '/etc/sonic/telemetry/dsmsroot.cer' } } results['BGP_NEIGHBOR'] = bgp_sessions @@ -820,6 +824,11 @@ def parse_xml(filename, platform=None, port_config_file=None): 'client_auth': 'true', 'port': '50051', 'log_level': '2' + }, + 'certs': { + 'server_crt': '/etc/sonic/telemetry/streamingtelemetryserver.cer', + 'server_key': '/etc/sonic/telemetry/streamingtelemetryserver.key', + 'ca_crt': '/etc/sonic/telemetry/dsmsroot.cer' } } diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 7cff6c9fb384..6000aefb4245 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -233,6 +233,10 @@ def main(): sys.exit(1) deep_update(data, {'PORT': ports}) + for json_file in args.json: + with open(json_file, 'r') as stream: + deep_update(data, FormatConverter.to_deserialized(json.load(stream))) + if args.minigraph != None: minigraph = args.minigraph if platform: @@ -254,10 +258,6 @@ def main(): additional_data = yaml.load(stream) deep_update(data, FormatConverter.to_deserialized(additional_data)) - for json_file in args.json: - with open(json_file, 'r') as stream: - deep_update(data, FormatConverter.to_deserialized(json.load(stream))) - if args.additional_data != None: deep_update(data, json.loads(args.additional_data)) @@ -295,7 +295,7 @@ def main(): template = jinja2.Template('{{' + args.var + '}}') print(template.render(data)) - if args.var_json != None: + if args.var_json != None and args.var_json in data: if args.key != None: print(json.dumps(FormatConverter.to_serialized(data[args.var_json], args.key), indent=4, cls=minigraph_encoder)) else: diff --git a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf index bae273eeaf81..fde1d6c7714d 100644 --- a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf +++ b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name dhcp_relay events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected @@ -37,3 +37,16 @@ stdout_logfile=syslog stderr_logfile=syslog +[group:dhcpmon] +programs=dhcpmon-Vlan1000 + +[program:dhcpmon-Vlan1000] +command=/usr/sbin/dhcpmon -id Vlan1000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + + + diff --git a/src/sonic-config-engine/tests/sample_output/interfaces b/src/sonic-config-engine/tests/sample_output/interfaces index d3921bcbab4d..913fc8531443 100644 --- a/src/sonic-config-engine/tests/sample_output/interfaces +++ b/src/sonic-config-engine/tests/sample_output/interfaces @@ -18,9 +18,9 @@ iface eth0 inet static up ip -4 route add 10.0.0.0/24 dev eth0 table default up ip -4 rule add from 10.0.0.100/32 table default # management port down rules - down ip -4 route delete default via 10.0.0.1 dev eth0 table default - down ip -4 route delete 10.0.0.0/24 dev eth0 table default - down ip -4 rule delete from 10.0.0.100/32 table default + pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table default + pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table default + pre-down ip -4 rule delete from 10.0.0.100/32 table default iface eth0 inet6 static address 2603:10e2:0:2902::8 netmask 64 @@ -30,9 +30,9 @@ iface eth0 inet6 static up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table default up ip -6 rule add from 2603:10e2:0:2902::8/128 table default # management port down rules - down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table default - down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table default - down ip -6 rule delete from 2603:10e2:0:2902::8/128 table default + pre-down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table default + pre-down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table default + pre-down ip -6 rule delete from 2603:10e2:0:2902::8/128 table default # source /etc/network/interfaces.d/* # diff --git a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces index afd0615b81e9..7bd664d4a9db 100644 --- a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces +++ b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces @@ -6,15 +6,15 @@ auto mgmt iface mgmt vrf-table 5000 -# The loopback network interface -auto lo -iface lo inet loopback # The loopback network interface for mgmt VRF that is required for applications like NTP up ip link add lo-m type dummy + up ip link set dev lo-m master mgmt up ip addr add 127.0.0.1/8 dev lo-m up ip link set lo-m up - up ip link set dev lo-m master mgmt - down ip link delete dev lo-m + down ip link delete dev lo-m +# The loopback network interface +auto lo +iface lo inet loopback # The management network interface auto eth0 @@ -30,9 +30,9 @@ iface eth0 inet static up cgcreate -g l3mdev:mgmt up cgset -r l3mdev.master-device=mgmt mgmt # management port down rules - down ip -4 route delete default via 10.0.0.1 dev eth0 table 5000 - down ip -4 route delete 10.0.0.0/24 dev eth0 table 5000 - down ip -4 rule delete from 10.0.0.100/32 table 5000 + pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table 5000 + pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table 5000 + pre-down ip -4 rule delete from 10.0.0.100/32 table 5000 down cgdelete -g l3mdev:mgmt iface eth0 inet6 static address 2603:10e2:0:2902::8 @@ -46,9 +46,9 @@ iface eth0 inet6 static up cgcreate -g l3mdev:mgmt up cgset -r l3mdev.master-device=mgmt mgmt # management port down rules - down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table 5000 - down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table 5000 - down ip -6 rule delete from 2603:10e2:0:2902::8/128 table 5000 + pre-down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table 5000 + pre-down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table 5000 + pre-down ip -6 rule delete from 2603:10e2:0:2902::8/128 table 5000 down cgdelete -g l3mdev:mgmt # source /etc/network/interfaces.d/* diff --git a/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh b/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh index 918f0b6e1648..6d90afa60ad7 100644 --- a/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh +++ b/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh @@ -1,7 +1,5 @@ #!/usr/bin/env bash -STATE_DB_IDX="6" - function wait_until_iface_ready { IFACE_NAME=$1 @@ -12,7 +10,7 @@ function wait_until_iface_ready # Wait for the interface to come up # (i.e., interface is present in STATE_DB and state is "ok") while true; do - RESULT=$(redis-cli -n ${STATE_DB_IDX} HGET "INTERFACE_TABLE|${IFACE_NAME}|${IFACE_CIDR}" "state" 2> /dev/null) + RESULT=$(sonic-db-cli STATE_DB HGET "INTERFACE_TABLE|${IFACE_NAME}|${IFACE_CIDR}" "state" 2> /dev/null) if [ x"$RESULT" == x"ok" ]; then break fi diff --git a/src/sonic-config-engine/tests/t0-sample-graph.xml b/src/sonic-config-engine/tests/t0-sample-graph.xml index 0c641107da06..47985f870e50 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph.xml @@ -305,7 +305,12 @@ PortChannel01;PortChannel02;PortChannel03;PortChannel04 - DataAcl + DataAclIngress + DataPlane + + + PortChannel01;PortChannel02 + DataAclEgress DataPlane diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 8288b729584c..7f5eb155092f 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -104,13 +104,14 @@ def test_minigraph_acl(self): self.assertEqual(output.strip(), "Warning: Ignoring Control Plane ACL NTP_ACL without type\n" "Warning: ignore interface 'fortyGigE0/2' as it is not in the port_config.ini\n" "Warning: ignore interface 'fortyGigE0/2' in DEVICE_NEIGHBOR as it is not in the port_config.ini\n" - "{'DATAACL': {'type': 'L3', 'policy_desc': 'DATAACL', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04']}, " - "'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL'}, " - "'EVERFLOW': {'type': 'MIRROR', 'policy_desc': 'EVERFLOW', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4']}, " - "'ROUTER_PROTECT': {'services': ['SSH', 'SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'ROUTER_PROTECT'}, " - "'SNMP_ACL': {'services': ['SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL'}, " - "'SSH_ACL': {'services': ['SSH'], 'type': 'CTRLPLANE', 'policy_desc': 'SSH_ACL'}, " - "'EVERFLOWV6': {'type': 'MIRRORV6', 'policy_desc': 'EVERFLOWV6', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4']}}") + "{'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL', 'stage': 'ingress'}, " + "'EVERFLOW': {'stage': 'ingress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4'], 'policy_desc': 'EVERFLOW'}, " + "'ROUTER_PROTECT': {'services': ['SSH', 'SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'ROUTER_PROTECT', 'stage': 'ingress'}, " + "'DATAACLINGRESS': {'stage': 'ingress', 'type': 'L3', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04'], 'policy_desc': 'DATAACLINGRESS'}, " + "'SNMP_ACL': {'services': ['SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL', 'stage': 'ingress'}, " + "'SSH_ACL': {'services': ['SSH'], 'type': 'CTRLPLANE', 'policy_desc': 'SSH_ACL', 'stage': 'ingress'}, " + "'DATAACLEGRESS': {'stage': 'egress', 'type': 'L3', 'ports': ['PortChannel01', 'PortChannel02'], 'policy_desc': 'DATAACLEGRESS'}, " + "'EVERFLOWV6': {'stage': 'ingress', 'type': 'MIRRORV6', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4'], 'policy_desc': 'EVERFLOWV6'}}") # everflow portion is not used # def test_minigraph_everflow(self): @@ -330,3 +331,13 @@ def test_minigraph_sub_port_interfaces(self, check_stderr=True): output = subprocess.check_output("sed -i \'s/%s/%s/g\' %s" % (BACKEND_TOR_ROUTER, TOR_ROUTER, self.sample_graph_simple), shell=True) self.test_jinja_expression(self.sample_graph_simple, TOR_ROUTER) + + def test_show_run_acl(self): + argument = '-a \'{"key1":"value"}\' --var-json ACL_RULE' + output = self.run_script(argument) + self.assertEqual(output, '') + + def test_show_run_interfaces(self): + argument = '-a \'{"key1":"value"}\' --var-json INTERFACE' + output = self.run_script(argument) + self.assertEqual(output, '') diff --git a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py index a0a5bff0a297..d3807bf91524 100644 --- a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py +++ b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py @@ -102,15 +102,15 @@ def __init__(self): # Signal handler def signal_handler(self, sig, frame): if sig == signal.SIGHUP: - self.syslog.syslog(self.syslog.LOG_INFO, "Caught SIGHUP - ignoring...") + syslog.syslog(syslog.LOG_INFO, "Caught SIGHUP - ignoring...") elif sig == signal.SIGINT: - self.syslog.syslog(self.syslog.LOG_INFO, "Caught SIGINT - exiting...") + syslog.syslog(syslog.LOG_INFO, "Caught SIGINT - exiting...") sys.exit(128 + sig) elif sig == signal.SIGTERM: - self.syslog.syslog(self.syslog.LOG_INFO, "Caught SIGTERM - exiting...") + syslog.syslog(syslog.LOG_INFO, "Caught SIGTERM - exiting...") sys.exit(128 + sig) else: - self.syslog.syslog(self.syslog.LOG_WARNING, "Caught unhandled signal '" + sig + "'") + syslog.syslog(syslog.LOG_WARNING, "Caught unhandled signal '" + sig + "'") # Returns platform and hwsku def get_platform_and_hwsku(self): diff --git a/src/sonic-frr/Makefile b/src/sonic-frr/Makefile index abd9adc3fc67..296f0226d2fe 100644 --- a/src/sonic-frr/Makefile +++ b/src/sonic-frr/Makefile @@ -5,14 +5,13 @@ 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 git checkout -b $(FRR_BRANCH) origin/$(FRR_BRANCH) - stg branch --create $(STG_BRANCH) $(FRR_BRANCH) + stg branch --create $(STG_BRANCH) $(FRR_TAG) stg import -s ../patch/series tools/tarsource.sh -V -e '-sonic' dpkg-buildpackage -rfakeroot -b -us -uc -Ppkg.frr.nortrlib -j$(SONIC_CONFIG_MAKE_JOBS) diff --git a/src/sonic-frr/frr b/src/sonic-frr/frr index d49e8f75bd46..e1b0c939960c 160000 --- a/src/sonic-frr/frr +++ b/src/sonic-frr/frr @@ -1 +1 @@ -Subproject commit d49e8f75bd46879c799375f304506dbc5d26230f +Subproject commit e1b0c939960c49eba05e972a68d50ca32dd09303 diff --git a/src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch b/src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch deleted file mode 100644 index 343f1b3262d9..000000000000 --- a/src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 2f0b5aef66316b47d2cc8ac18453600621a6a317 Mon Sep 17 00:00:00 2001 -From: Tyler Li -Date: Thu, 14 Nov 2019 23:46:52 -0800 -Subject: [PATCH] nexthops compare vrf only if ip type - ---- - lib/nexthop.c | 12 ++++++------ - lib/zclient.c | 12 ++++++------ - 2 files changed, 12 insertions(+), 12 deletions(-) - -diff --git a/lib/nexthop.c b/lib/nexthop.c -index cf5bed3d6..7d9f646c9 100644 ---- a/lib/nexthop.c -+++ b/lib/nexthop.c -@@ -105,12 +105,6 @@ static int _nexthop_cmp_no_labels(const struct nexthop *next1, - { - int ret = 0; - -- if (next1->vrf_id < next2->vrf_id) -- return -1; -- -- if (next1->vrf_id > next2->vrf_id) -- return 1; -- - if (next1->type < next2->type) - return -1; - -@@ -120,6 +114,12 @@ static int _nexthop_cmp_no_labels(const struct nexthop *next1, - switch (next1->type) { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV6: -+ if (next1->vrf_id < next2->vrf_id) -+ return -1; -+ -+ if (next1->vrf_id > next2->vrf_id) -+ return 1; -+ - ret = _nexthop_gateway_cmp(next1, next2); - if (ret != 0) - return ret; -diff --git a/lib/zclient.c b/lib/zclient.c -index c739af043..0d37c46d1 100644 ---- a/lib/zclient.c -+++ b/lib/zclient.c -@@ -783,12 +783,6 @@ static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1, - { - int ret = 0; - -- if (next1->vrf_id < next2->vrf_id) -- return -1; -- -- if (next1->vrf_id > next2->vrf_id) -- return 1; -- - if (next1->type < next2->type) - return -1; - -@@ -798,6 +792,12 @@ static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1, - switch (next1->type) { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV6: -+ if (next1->vrf_id < next2->vrf_id) -+ return -1; -+ -+ if (next1->vrf_id > next2->vrf_id) -+ return 1; -+ - ret = nexthop_g_addr_cmp(next1->type, &next1->gate, - &next2->gate); - if (ret != 0) --- -2.11.0 - diff --git a/src/sonic-frr/patch/series b/src/sonic-frr/patch/series index 13619c87ff65..233021ace50b 100644 --- a/src/sonic-frr/patch/series +++ b/src/sonic-frr/patch/series @@ -2,5 +2,4 @@ 0002-Reduce-severity-of-Vty-connected-from-message.patch 0003-Use-vrf_id-for-vrf-not-tabled_id.patch 0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch -0005-nexthops-compare-vrf-only-if-ip-type.patch 0006-changes-for-making-snmp-socket-non-blocking.patch diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index d5bc436a6179..3d97fcd5667e 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit d5bc436a6179ec5ba985f66e96d2fb7864f0002d +Subproject commit 3d97fcd5667ebb8351977956437f6662920f368e diff --git a/src/sonic-mgmt-framework b/src/sonic-mgmt-framework index 8b199a9f822c..f789b295f4c7 160000 --- a/src/sonic-mgmt-framework +++ b/src/sonic-mgmt-framework @@ -1 +1 @@ -Subproject commit 8b199a9f822ca42564a7a89da0cab3133684bd12 +Subproject commit f789b295f4c775ac303b4370d9380ebba8ac6272 diff --git a/src/sonic-platform-common b/src/sonic-platform-common index 6ddd012d9ab3..3fe07066892a 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 6ddd012d9ab362254bd6a54372ee0ab679a7130e +Subproject commit 3fe07066892aba5ae3e8f5f0ffd5163ffc578b31 diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index e97f2ab26c6c..364ae4254ba4 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit e97f2ab26c6cfc8e620cceddf94fe47646afe64c +Subproject commit 364ae4254ba4d770fffa1286e2219841571c78b5 diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index dd21b345d71d..7410ba1283e5 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit dd21b345d71dae02c6309c8faca911b1e25bc7b7 +Subproject commit 7410ba1283e5454de4b66556d7b47c25ec793e1e diff --git a/src/sonic-restapi b/src/sonic-restapi new file mode 160000 index 000000000000..c219e3da28fb --- /dev/null +++ b/src/sonic-restapi @@ -0,0 +1 @@ +Subproject commit c219e3da28fb20b63b065ceb1828125593d73f14 diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 792800607c0a..0305b7fb531b 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 792800607c0a987097d430d9f7fa9dce34361cfd +Subproject commit 0305b7fb531b60fafc42c16aecfed9a6701be870 diff --git a/src/sonic-swss b/src/sonic-swss index 7b9661b2aea0..e9cf94aaf159 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 7b9661b2aea0d9c3c770c421ca9963e2d742197f +Subproject commit e9cf94aaf159c6ee30d6da7fa53fbbaa640694a8 diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 8d6844984b6f..e81e661cea0d 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 8d6844984b6f02d389eb5f8d92e14f3e12e3f19c +Subproject commit e81e661cea0dbf441f9576013b9e9485de0e4c45 diff --git a/src/sonic-utilities b/src/sonic-utilities index 72f0e77aa172..250a49bf47e2 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 72f0e77aa172a7096b49b661e84512785efee4e0 +Subproject commit 250a49bf47e24b2b5aa5f84478cbe8550f817589 diff --git a/src/sonic-ztp b/src/sonic-ztp new file mode 160000 index 000000000000..374c9e804a9f --- /dev/null +++ b/src/sonic-ztp @@ -0,0 +1 @@ +Subproject commit 374c9e804a9f434cdb58fa7afe0c3f6201bfe56f diff --git a/src/systemd-sonic-generator/systemd-sonic-generator.c b/src/systemd-sonic-generator/systemd-sonic-generator.c index a2723a28ff03..566d37ff0a4c 100644 --- a/src/systemd-sonic-generator/systemd-sonic-generator.c +++ b/src/systemd-sonic-generator/systemd-sonic-generator.c @@ -9,13 +9,17 @@ #include #include -#define MAX_NUM_TARGETS 5 -#define MAX_NUM_INSTALL_LINES 5 +#define MAX_NUM_TARGETS 15 +#define MAX_NUM_INSTALL_LINES 15 #define MAX_NUM_UNITS 128 +#define MAX_BUF_SIZE 512 static const char* UNIT_FILE_PREFIX = "/etc/systemd/system/"; static const char* CONFIG_FILE = "/etc/sonic/generated_services.conf"; - +static const char* MACHINE_CONF_FILE = "/host/machine.conf"; +static int num_asics; +static char** multi_instance_services; +static int num_multi_inst; void strip_trailing_newline(char* str) { /*** @@ -61,7 +65,7 @@ static int get_target_lines(char* unit_file, char* target_lines[]) { if (num_target_lines >= MAX_NUM_INSTALL_LINES) { fprintf(stderr, "Number of lines in [Install] section of %s exceeds MAX_NUM_INSTALL_LINES\n", unit_file); fputs("Extra [Install] lines will be ignored\n", stderr); - return num_target_lines; + break; } target_lines[num_target_lines] = strdup(line); num_target_lines++; @@ -75,7 +79,18 @@ static int get_target_lines(char* unit_file, char* target_lines[]) { return num_target_lines; } -static int get_install_targets_from_line(char* target_string, char* suffix, char* targets[], int existing_targets) { +static bool is_multi_instance_service(char *service_name){ + int i; + for(i=0; i < num_multi_inst; i++){ + if (strstr(service_name, multi_instance_services[i]) != NULL) { + return true; + } + } + return false; + +} + +static int get_install_targets_from_line(char* target_string, char* install_type, char* targets[], int existing_targets) { /*** Helper fuction for get_install_targets @@ -88,26 +103,113 @@ static int get_install_targets_from_line(char* target_string, char* suffix, char int num_targets = 0; while ((token = strtok_r(target_string, " ", &target_string))) { - target = strdup(token); - strip_trailing_newline(target); - - strcpy(final_target, target); - strcat(final_target, suffix); - - free(target); - if (num_targets + existing_targets >= MAX_NUM_TARGETS) { fputs("Number of targets found exceeds MAX_NUM_TARGETS\n", stderr); fputs("Additional targets will be ignored \n", stderr); return num_targets; } + target = strdup(token); + strip_trailing_newline(target); + + if (strstr(target, "%") != NULL) { + char* prefix = strtok(target, "."); + char* suffix = strtok(NULL, "."); + int prefix_len = strlen(prefix); + + strncpy(final_target, prefix, prefix_len - 2); + final_target[prefix_len - 2] = '\0'; + strcat(final_target, "."); + strcat(final_target, suffix); + } + else { + strcpy(final_target, target); + } + strcat(final_target, install_type); + + free(target); + targets[num_targets + existing_targets] = strdup(final_target); num_targets++; } return num_targets; } +static void replace_multi_inst_dep(char *src) { + FILE *fp_src; + FILE *fp_tmp; + char buf[MAX_BUF_SIZE]; + char* line = NULL; + int i; + ssize_t len; + char *token; + char *word; + char *line_copy; + char *service_name; + char *type; + ssize_t nread; + bool section_done = false; + char tmp_file_path[PATH_MAX]; + + /* assumes that the service files has 3 sections, + * in the order: Unit, Service and Install. + * Read service dependency from Unit and Install + * sections, replace if dependent on multi instance + * service. + */ + fp_src = fopen(src, "r"); + snprintf(tmp_file_path, PATH_MAX, "%s.tmp", src); + fp_tmp = fopen(tmp_file_path, "w"); + + while ((nread = getline(&line, &len, fp_src)) != -1 ) { + if (strstr(line, "[Service]") != NULL) { + section_done = true; + fputs(line,fp_tmp); + } else if (strstr(line, "[Install]") != NULL) { + section_done = false; + fputs(line,fp_tmp); + } else if ((strstr(line, "[Unit]") != NULL) || + (strstr(line, "Description") != NULL) || + (section_done == true)){ + fputs(line,fp_tmp); + } else { + line_copy = strdup(line); + token = strtok(line_copy, "="); + while ((word = strtok(NULL, " "))){ + if((strchr(word, '.') == NULL) || + (strchr(word, '@') != NULL)) { + snprintf(buf, MAX_BUF_SIZE,"%s=%s\n",token, word); + fputs(buf,fp_tmp); + } else { + service_name = strdup(word); + service_name = strtok(service_name, "."); + type = strtok(NULL, " "); + if (is_multi_instance_service(word)) { + for(i = 0; i < num_asics; i++){ + snprintf(buf, MAX_BUF_SIZE, "%s=%s@%d.%s\n", + token, service_name, i, type); + fputs(buf,fp_tmp); + } + } else { + snprintf(buf, MAX_BUF_SIZE,"%s=%s.%s\n",token, service_name, type); + fputs(buf, fp_tmp); + } + free(service_name); + } + } + free(line_copy); + } + } + fclose(fp_src); + fclose(fp_tmp); + free(line); + /* remove the .service file, rename the .service.tmp file + * as .service. + */ + remove(src); + rename(tmp_file_path, src); +} + static int get_install_targets(char* unit_file, char* targets[]) { /*** Returns install targets for a unit file @@ -124,10 +226,21 @@ static int get_install_targets(char* unit_file, char* targets[]) { char* line = NULL; bool first; char* target_suffix; + char *instance_name; + char *dot_ptr; strcpy(file_path, UNIT_FILE_PREFIX); strcat(file_path, unit_file); + instance_name = strdup(unit_file); + dot_ptr = strchr(instance_name, '.'); + *dot_ptr = '\0'; + + if((num_asics > 1) && (!is_multi_instance_service(instance_name))) { + replace_multi_inst_dep(file_path); + } + free(instance_name); + num_target_lines = get_target_lines(file_path, target_lines); if (num_target_lines < 0) { fprintf(stderr, "Error parsing targets for %s\n", unit_file); @@ -170,6 +283,7 @@ static int get_unit_files(char* unit_files[]) { char *line = NULL; size_t len = 0; ssize_t read; + char *pos; fp = fopen(CONFIG_FILE, "r"); @@ -179,13 +293,30 @@ static int get_unit_files(char* unit_files[]) { } int num_unit_files = 0; + num_multi_inst = 0; + + multi_instance_services = malloc(MAX_NUM_UNITS * sizeof(char *)); while ((read = getline(&line, &len, fp)) != -1) { if (num_unit_files >= MAX_NUM_UNITS) { fprintf(stderr, "Maximum number of units exceeded, ignoring extras\n"); - return num_unit_files; + break; } strip_trailing_newline(line); + + /* Get the multi-instance services */ + pos = strchr(line, '@'); + if (pos != NULL) { + multi_instance_services[num_multi_inst] = malloc(strlen(line)*sizeof(char)); + strncpy(multi_instance_services[num_multi_inst], line, pos-line); + num_multi_inst++; + } + + /* topology service to be started only for multiasic VS platform */ + if ((strcmp(line, "topology.service") == 0) && + (num_asics == 1)) { + continue; + } unit_files[num_unit_files] = strdup(line); num_unit_files++; } @@ -198,28 +329,70 @@ static int get_unit_files(char* unit_files[]) { } -static int install_unit_file(char* unit_file, char* target, char* install_dir) { +static char* insert_instance_number(char* unit_file, int instance) { /*** - Creates a symlink for a unit file installation + Adds an instance number to a systemd template name - For a given unit file and target directory, - create the appropriate symlink in the target directory - to enable the unit and have it started by Systemd + E.g. given unit_file='example@.service', instance=3, + returns a pointer to 'example@1.service' ***/ - char final_install_dir[PATH_MAX]; + char* prefix; + char* suffix; + char* instance_string; + char* instance_name; + char* temp_unit_file; + + instance_string = malloc(2 * sizeof(char)); + snprintf(instance_string, 2, "%d", instance); + + instance_name = malloc(strlen(unit_file) + 2); + + if (instance_name == NULL) { + fprintf(stderr, "Error creating instance %d of %s\n", instance, unit_file); + return NULL; + } + + temp_unit_file = strdup(unit_file); + prefix = strtok(temp_unit_file, "@"); + suffix = strtok(NULL, "@"); + + strcpy(instance_name, prefix); + strcat(instance_name, "@"); + strcat(instance_name, instance_string); + strcat(instance_name, suffix); + + free(instance_string); + free(temp_unit_file); + + return instance_name; +} + + +static int create_symlink(char* unit, char* target, char* install_dir, int instance) { + struct stat st; char src_path[PATH_MAX]; char dest_path[PATH_MAX]; - struct stat st; + char final_install_dir[PATH_MAX]; + char* unit_instance; int r; - assert(unit_file); - assert(target); + strcpy(src_path, UNIT_FILE_PREFIX); + strcat(src_path, unit); + + if (instance < 0) { + unit_instance = strdup(unit); + } + else { + unit_instance = insert_instance_number(unit, instance); + } strcpy(final_install_dir, install_dir); strcat(final_install_dir, target); + strcpy(dest_path, final_install_dir); + strcat(dest_path, "/"); + strcat(dest_path, unit_instance); - strcpy(src_path, UNIT_FILE_PREFIX); - strcat(src_path, unit_file); + free(unit_instance); if (stat(final_install_dir, &st) == -1) { // If doesn't exist, create @@ -242,7 +415,7 @@ static int install_unit_file(char* unit_file, char* target, char* install_dir) { fprintf(stderr, "Unable to create target directory %s\n", final_install_dir); return -1; } - } + } else if (S_ISDIR(st.st_mode)) { // If directory, verify correct permissions r = chmod(final_install_dir, 0755); @@ -251,11 +424,6 @@ static int install_unit_file(char* unit_file, char* target, char* install_dir) { return -1; } } - - - strcpy(dest_path, final_install_dir); - strcat(dest_path, "/"); - strcat(dest_path, unit_file); r = symlink(src_path, dest_path); @@ -267,6 +435,123 @@ static int install_unit_file(char* unit_file, char* target, char* install_dir) { } return 0; + +} + + +static int install_unit_file(char* unit_file, char* target, char* install_dir) { + /*** + Creates a symlink for a unit file installation + + For a given unit file and target directory, + create the appropriate symlink in the target directory + to enable the unit and have it started by Systemd + + If a multi ASIC platform is detected, enables multi-instance + services as well + ***/ + char* target_instance; + char* prefix; + char* suffix; + int r; + + assert(unit_file); + assert(target); + + + if ((num_asics > 1) && strstr(unit_file, "@") != NULL) { + + for (int i = 0; i < num_asics; i++) { + + if (strstr(target, "@") != NULL) { + target_instance = insert_instance_number(target, i); + } + else { + target_instance = strdup(target); + } + + r = create_symlink(unit_file, target_instance, install_dir, i); + if (r < 0) + fprintf(stderr, "Error installing %s for target %s\n", unit_file, target_instance); + + free(target_instance); + + } + } + else { + r = create_symlink(unit_file, target, install_dir, -1); + if (r < 0) + fprintf(stderr, "Error installing %s for target %s\n", unit_file, target); + } + + return 0; +} + + +static int get_num_of_asic() { + /*** + Determines if the current platform is single or multi-ASIC + ***/ + FILE *fp; + FILE *env_fp; + char *line = NULL; + char* token; + char* platform; + size_t len = 0; + ssize_t nread; + bool ans; + char asic_file[512]; + char* str_num_asic; + int num_asic = 1; + + fp = fopen(MACHINE_CONF_FILE, "r"); + + if (fp == NULL) { + fprintf(stderr, "Failed to open %s\n", MACHINE_CONF_FILE); + exit(EXIT_FAILURE); + } + + while ((nread = getline(&line, &len, fp)) != -1) { + if ((strstr(line, "onie_platform") != NULL) || + (strstr(line, "aboot_platform") != NULL)) { + token = strtok(line, "="); + platform = strtok(NULL, "="); + strip_trailing_newline(platform); + break; + } + } + + fclose(fp); + if(platform != NULL) { + snprintf(asic_file, 512, "/usr/share/sonic/device/%s/asic.conf", platform); + fp = fopen(asic_file, "r"); + if (fp != NULL) { + while ((nread = getline(&line, &len, fp)) != -1) { + if (strstr(line, "NUM_ASIC") != NULL) { + token = strtok(line, "="); + str_num_asic = strtok(NULL, "="); + strip_trailing_newline(str_num_asic); + if (str_num_asic != NULL){ + sscanf(str_num_asic, "%d",&num_asic); + } + break; + } + } + fclose(fp); + free(line); + } + } + + /*set environment variable NUM_ASIC */ + env_fp = fopen("/etc/environment", "a"); + if (env_fp == NULL) { + fprintf(stderr, "Failed to open environment file\n"); + exit(EXIT_FAILURE); + } + fprintf(env_fp, "NUM_ASIC=%d\n", num_asic); + fclose(env_fp); + return num_asic; + } @@ -274,14 +559,20 @@ int main(int argc, char **argv) { char* unit_files[MAX_NUM_UNITS]; char install_dir[PATH_MAX]; char* targets[MAX_NUM_TARGETS]; + char* unit_instance; + char* prefix; + char* suffix; int num_unit_files; int num_targets; + int r; if (argc <= 1) { fputs("Installation directory required as argument\n", stderr); return 1; } + num_asics = get_num_of_asic(); + strcpy(install_dir, argv[1]); strcat(install_dir, "/"); @@ -289,21 +580,38 @@ int main(int argc, char **argv) { // For each unit file, get the installation targets and install the unit for (int i = 0; i < num_unit_files; i++) { - num_targets = get_install_targets(unit_files[i], targets); + unit_instance = strdup(unit_files[i]); + if ((num_asics == 1) && strstr(unit_instance, "@") != NULL) { + prefix = strtok(unit_instance, "@"); + suffix = strtok(NULL, "@"); + + strcpy(unit_instance, prefix); + strcat(unit_instance, suffix); + } + + num_targets = get_install_targets(unit_instance, targets); if (num_targets < 0) { - fprintf(stderr, "Error parsing %s\n", unit_files[i]); + fprintf(stderr, "Error parsing %s\n", unit_instance); + free(unit_instance); free(unit_files[i]); continue; } for (int j = 0; j < num_targets; j++) { - if (install_unit_file(unit_files[i], targets[j], install_dir) != 0) - fprintf(stderr, "Error installing %s to target directory %s\n", unit_files[i], targets[j]); + if (install_unit_file(unit_instance, targets[j], install_dir) != 0) + fprintf(stderr, "Error installing %s to target directory %s\n", unit_instance, targets[j]); free(targets[j]); } + free(unit_instance); free(unit_files[i]); } + + for (int i = 0; i < num_multi_inst; i++) { + free(multi_instance_services[i]); + } + free(multi_instance_services); + return 0; }