From f345935aec5325c76d34d1fa38f158a9171dbbe9 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Thu, 5 Dec 2019 21:23:16 +0200 Subject: [PATCH 01/66] [submodule]: Advance sonic-platform-common. (#3848) Signed-off-by: Nazarii Hnydyn --- src/sonic-platform-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index d22f0a0e64f3..6ad48b87eb96 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit d22f0a0e64f30e9e26064824fb11f27b2d636850 +Subproject commit 6ad48b87eb9654daa3f3c854134434d14572573f From 8ab75e0e90879a8b59a55b16f89ca4f4c2439d55 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sat, 7 Dec 2019 11:26:29 -0800 Subject: [PATCH 02/66] [isc-dhcp-relay] Patch to allow relay to discover interfaces even if (#3851) Patch isc-dhcp-relay in order to allow the relay agent to discover configured interfaces even if they are down. Without this patch, the relay agent will not discover configured interfaces if they are down when the relay agent starts up. If the interface(s) then get brought up after the relay started, the relay will discard packets received on these interfaces and log the message, Discarding packet received on interface that has no IPv4 address assigned. This led to race conditions when starting SONiC (or loading configuration). To resolve this, the relay agent would need to be restarted with all configured interfaces up. With this patch, the relay agent will discover all configured interfaces, whether or not they are up at the time the relay agent starts. Thus, the state of the configured interfaces can be down when the relay agent starts and brought up during the lifetime of the relay agent process, and the relay agent will relay packets as expected; it will not discard them. --- ...interfaces-when-discovering-interfac.patch | 32 +++++++++++++++++++ src/isc-dhcp/patch/series | 1 + 2 files changed, 33 insertions(+) create mode 100644 src/isc-dhcp/patch/0012-Don-t-skip-down-interfaces-when-discovering-interfac.patch diff --git a/src/isc-dhcp/patch/0012-Don-t-skip-down-interfaces-when-discovering-interfac.patch b/src/isc-dhcp/patch/0012-Don-t-skip-down-interfaces-when-discovering-interfac.patch new file mode 100644 index 000000000000..f088b035edb4 --- /dev/null +++ b/src/isc-dhcp/patch/0012-Don-t-skip-down-interfaces-when-discovering-interfac.patch @@ -0,0 +1,32 @@ +From 06850e9beb2c50b5cc23fc94168acd9ae58d8ef8 Mon Sep 17 00:00:00 2001 +From: Joe LeVeque +Date: Fri, 6 Dec 2019 05:53:09 +0000 +Subject: [PATCH] Don't skip down interfaces when discovering interfaces in + relay mode + +When discovering interfaces in relay mode, don't skip interfaces just +because they're down. If we fail to discover the interfaces because they +are down when the relay starts, but then are brought up at a later point +in time, the relay will discard any packets received on them because it +didn't discover the interface(s) when it started up. +--- + common/discover.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/common/discover.c b/common/discover.c +index 8d5b958..5efff49 100644 +--- a/common/discover.c ++++ b/common/discover.c +@@ -1016,7 +1016,8 @@ discover_interfaces(int state) { + info.flags & IFF_LOOPBACK || + info.flags & IFF_POINTOPOINT) && !tmp) || + (!(info.flags & IFF_UP) && +- state != DISCOVER_UNCONFIGURED)) ++ state != DISCOVER_UNCONFIGURED && ++ state != DISCOVER_RELAY)) + continue; + + /* If there isn't already an interface by this name, +-- +2.17.1 + diff --git a/src/isc-dhcp/patch/series b/src/isc-dhcp/patch/series index 1b83f2166b96..ec68967e28b9 100644 --- a/src/isc-dhcp/patch/series +++ b/src/isc-dhcp/patch/series @@ -10,3 +10,4 @@ 0009-CVE-2018-5733.patch 0010-CVE-2018-5732.patch 0008-interface-name-maxlen-crash.patch +0012-Don-t-skip-down-interfaces-when-discovering-interfac.patch From 90ddad48d1ff0a1482867b12b7552e1d774a6fd7 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Sun, 8 Dec 2019 03:28:49 +0800 Subject: [PATCH 03/66] [mellanox ]improve the method the type of sfp module is detected (#3846) Fix the issue when an SFP module is plugged into a QSFP port via an adapter. - How I did it Originally the type of an SFP module is determined according to the SKU dictionary. However, it's possible that as SFP module is plugged into a QSFP port via an adapter. In this case, the EEPROM content will be parsed in the wrong format. To address that we fetch the identifier value of an xSFP module and then get the type by parsing it. --- .../mlnx-platform-api/sonic_platform/sfp.py | 46 +++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py index 845f355e28f1..254d9c2e3e58 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -136,6 +136,26 @@ SFP_CHANNL_STATUS_OFFSET = 110 SFP_CHANNL_STATUS_WIDTH = 1 +# identifier value of xSFP module which is in the first byte of the EEPROM +# if the identifier value falls into SFP_TYPE_CODE_LIST the module is treated as a SFP module and parsed according to 8472 +# for QSFP_TYPE_CODE_LIST the module is treated as a QSFP module and parsed according to 8436/8636 +# Originally the type (SFP/QSFP) of each module is determined according to the SKU dictionary +# where the type of each FP port is defined. The content of EEPROM is parsed according to its type. +# However, sometimes the SFP module can be fit in an adapter and then pluged into a QSFP port. +# In this case the EEPROM content is in format of SFP but parsed as QSFP, causing failure. +# To resolve that issue the type field of the xSFP module is also fetched so that we can know exectly what type the +# module is. Currently only the following types are recognized as SFP/QSFP module. +# Meanwhile, if the a module's identifier value can't be recognized, it will be parsed according to the SKU dictionary. +# This is because in the future it's possible that some new identifier value which is not regonized but backward compatible +# with the current format and by doing so it can be parsed as much as possible. +SFP_TYPE_CODE_LIST = [ + '03' # SFP/SFP+/SFP28 +] +QSFP_TYPE_CODE_LIST = [ + '0d', # QSFP+ or later + '11' # QSFP28 or later +] + qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)', 'Length OM1(m)', 'Length Cable Assembly(m)') @@ -206,7 +226,7 @@ def __init__(self, sfp_index, sfp_type): self.index = sfp_index + 1 self.sfp_eeprom_path = "qsfp{}".format(self.index) self.sfp_status_path = "qsfp{}_status".format(self.index) - self.sfp_type = sfp_type + self._detect_sfp_type(sfp_type) self.dom_tx_disable_supported = False self._dom_capability_detect() self.sdk_handle = None @@ -293,6 +313,26 @@ def _read_eeprom_specific_bytes(self, offset, num_bytes): return eeprom_raw + def _detect_sfp_type(self, sfp_type): + eeprom_raw = [] + eeprom_raw = self._read_eeprom_specific_bytes(XCVR_TYPE_OFFSET, XCVR_TYPE_WIDTH) + if eeprom_raw: + if eeprom_raw[0] in SFP_TYPE_CODE_LIST: + self.sfp_type = SFP_TYPE + elif eeprom_raw[0] in QSFP_TYPE_CODE_LIST: + self.sfp_type = QSFP_TYPE + else: + # we don't regonize this identifier value, treat the xSFP module as the default type + self.sfp_type = sfp_type + logger.log_info("Identifier value of {} module {} is {} which isn't regonized and will be treated as default type ({})".format( + sfp_type, self.index, eeprom_raw[0], sfp_type + )) + else: + # eeprom_raw being None indicates the module is not present. + # in this case we treat it as the default type according to the SKU + self.sfp_type = sfp_type + + def _dom_capability_detect(self): if not self.get_presence(): self.dom_supported = False @@ -303,7 +343,7 @@ def _dom_capability_detect(self): self.calibration = 0 return - if self.sfp_type == "QSFP": + if self.sfp_type == QSFP_TYPE: self.calibration = 1 sfpi_obj = sff8436InterfaceId() if sfpi_obj is None: @@ -348,7 +388,7 @@ def _dom_capability_detect(self): self.dom_tx_power_supported = False self.calibration = 0 self.qsfp_page3_available = False - elif self.sfp_type == "SFP": + elif self.sfp_type == SFP_TYPE: sfpi_obj = sff8472InterfaceId() if sfpi_obj is None: return None From d39f10b31fafeb4ca55d6551bfa1cba26e384306 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sat, 7 Dec 2019 20:18:49 -0800 Subject: [PATCH 04/66] Revert "[dhcp_relay] Add extra sleep before starting relay agent processes (#3824)" (#3857) This reverts commit 7622a30d98553288ca5cb53bb3b1eff210d40a77. --- dockers/docker-dhcp-relay/start.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dockers/docker-dhcp-relay/start.sh b/dockers/docker-dhcp-relay/start.sh index 54e58dd42a07..0ac5ea1a10ec 100755 --- a/dockers/docker-dhcp-relay/start.sh +++ b/dockers/docker-dhcp-relay/start.sh @@ -16,12 +16,6 @@ if [ $(supervisorctl status | grep -c "^isc-dhcp-relay:") -gt 0 ]; then # lifetime of the process. /usr/bin/wait_for_intf.sh - # Allow a bit more time for interfaces to settle before starting the - # relay agent processes. - # FIXME: Remove/decrease this once we determine how to prevent future race - # conditions here. - sleep 180 - # Start all DHCP relay agent(s) supervisorctl start isc-dhcp-relay:* fi From 335514bf87ee93f6d4c381192574dc82ae6547c4 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Mon, 9 Dec 2019 18:42:29 -0800 Subject: [PATCH 05/66] [swss-common] update submodule for sonic-swss-common (#3863) --- src/sonic-swss-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss-common b/src/sonic-swss-common index a4a1e108afb3..29a2cdfe9ea9 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit a4a1e108afb3e75717e204da49a975681d964e8c +Subproject commit 29a2cdfe9ea9bb0c4d2d82be9428228a8ab6b9d4 From fec80293dd22c358b5ccc68eedc23d9feb15aca5 Mon Sep 17 00:00:00 2001 From: rajendra-dendukuri <47423477+rajendra-dendukuri@users.noreply.github.com> Date: Tue, 10 Dec 2019 11:16:56 -0500 Subject: [PATCH 06/66] ZTP infrastructure changes to support DHCP discovery provisioning data (#3298) * ZTP infrastructure changes to support DHCP discovery provisioning data - Dynamically generate DHCP client configuration based on current ZTP state - Added support to request and process hostname when using DHCPv6 - Do not process graphservice url dhcp option if ZTP is enabled, ZTP service will process it - Generate /e/n/i file with all active interfaces seeking address assignment via DHCP. Only interfaces that are created in Linux will be added to /e/n/i. Also DHCP is started only on linked up in-band interfaces. Signed-off-by: Rajendra Dendukuri --- build_debian.sh | 5 +-- .../build_templates/sonic_debian_extension.j2 | 6 +++ files/dhcp/90-dhcp6-systcl.conf.j2 | 7 +++ files/dhcp/dhclient.conf | 24 ---------- files/dhcp/dhclient.conf.j2 | 45 +++++++++++++++++++ files/dhcp/graphserviceurl | 26 ++++++----- files/dhcp/ifupdown2_policy.json | 12 +++++ files/dhcp/rfc3442-classless-routes | 7 ++- files/dhcp/sethostname6 | 14 ++++++ .../interfaces/interfaces-config.sh | 32 ++++++++++++- files/image_config/interfaces/interfaces.j2 | 36 +++++++++++++++ 11 files changed, 172 insertions(+), 42 deletions(-) create mode 100644 files/dhcp/90-dhcp6-systcl.conf.j2 delete mode 100644 files/dhcp/dhclient.conf create mode 100644 files/dhcp/dhclient.conf.j2 create mode 100644 files/dhcp/ifupdown2_policy.json create mode 100644 files/dhcp/sethostname6 diff --git a/build_debian.sh b/build_debian.sh index fb3ecfef6ce6..666e140416c9 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -392,9 +392,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 @@ -429,10 +426,10 @@ EOF sudo cp files/dhcp/rfc3442-classless-routes $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d sudo cp files/dhcp/sethostname $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ +sudo cp files/dhcp/sethostname6 $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/graphserviceurl $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/snmpcommunity $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/vrf $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ -sudo cp files/dhcp/dhclient.conf $FILESYSTEM_ROOT/etc/dhcp/ if [ -f files/image_config/ntp/ntp ]; then sudo cp ./files/image_config/ntp/ntp $FILESYSTEM_ROOT/etc/init.d/ fi diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 209bc19971b3..4e81593298f6 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -203,6 +203,12 @@ sudo cp $IMAGE_CONFIGS/interfaces/interfaces-config.sh $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/interfaces/*.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ echo "interfaces-config.service" | sudo tee -a $GENERATED_SERVICE_FILE +# Copy dhcp client configuration template and create an initial configuration +sudo cp files/dhcp/dhclient.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ +j2 files/dhcp/dhclient.conf.j2 | sudo tee $FILESYSTEM_ROOT/etc/dhcp/dhclient.conf +sudo cp files/dhcp/ifupdown2_policy.json $FILESYSTEM_ROOT/etc/network/ifupdown2/policy.d +sudo cp files/dhcp/90-dhcp6-systcl.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ + # Copy initial interfaces configuration file, will be overwritten on first boot sudo cp $IMAGE_CONFIGS/interfaces/init_interfaces $FILESYSTEM_ROOT/etc/network/interfaces sudo mkdir -p $FILESYSTEM_ROOT/etc/network/interfaces.d diff --git a/files/dhcp/90-dhcp6-systcl.conf.j2 b/files/dhcp/90-dhcp6-systcl.conf.j2 new file mode 100644 index 000000000000..addb94675258 --- /dev/null +++ b/files/dhcp/90-dhcp6-systcl.conf.j2 @@ -0,0 +1,7 @@ +{% if MGMT_INTERFACE %} +net.ipv6.conf.eth0.accept_ra_defrtr = 0 +net.ipv6.conf.eth0.accept_ra = 0 +{% else %} +net.ipv6.conf.eth0.accept_ra_defrtr = 1 +net.ipv6.conf.eth0.accept_ra = 1 +{% endif %} diff --git a/files/dhcp/dhclient.conf b/files/dhcp/dhclient.conf deleted file mode 100644 index 6a542e069fab..000000000000 --- a/files/dhcp/dhclient.conf +++ /dev/null @@ -1,24 +0,0 @@ -# Configuration file for /sbin/dhclient, which is included in Debian's -# dhcp3-client package. -# -# This is a sample configuration file for dhclient. See dhclient.conf's -# man page for more information about the syntax of this file -# and a more comprehensive list of the parameters understood by -# dhclient. -# -# Normally, if the DHCP server provides reasonable information and does -# not leave anything out (like the domain name, for example), then -# few changes must be made to this file, if any. -# - -option rfc3442-classless-static-routes code 121 = array of unsigned integer 8; -option snmp-community code 224 = text; -option minigraph-url code 225 = text; -option acl-url code 226 = text; - -send host-name = gethostname(); -request subnet-mask, broadcast-address, time-offset, routers, - domain-name, domain-name-servers, domain-search, host-name, - dhcp6.name-servers, dhcp6.domain-search, interface-mtu, - rfc3442-classless-static-routes, ntp-servers, - snmp-community, minigraph-url, acl-url; diff --git a/files/dhcp/dhclient.conf.j2 b/files/dhcp/dhclient.conf.j2 new file mode 100644 index 000000000000..2a6f6fa84fbd --- /dev/null +++ b/files/dhcp/dhclient.conf.j2 @@ -0,0 +1,45 @@ +{% block banner %} +# =============== Managed by SONiC Config Engine DO NOT EDIT! =============== +# generated from /usr/share/sonic/templates/dhclient.conf.j2 using sonic-cfggen +# file: /etc/dhcp/dhclient.conf +# +{% endblock banner %} +# Configuration file for /sbin/dhclient, which is included in Debian's +# dhcp3-client package. +# +# This is a sample configuration file for dhclient. See dhclient.conf's +# man page for more information about the syntax of this file +# and a more comprehensive list of the parameters understood by +# dhclient. +# +# Normally, if the DHCP server provides reasonable information and does +# not leave anything out (like the domain name, for example), then +# few changes must be made to this file, if any. +# + +option rfc3442-classless-static-routes code 121 = array of unsigned integer 8; +option snmp-community code 224 = text; +option minigraph-url code 225 = text; +option acl-url code 226 = text; +option tftp-server-name code 66 = text; +option bootfile-name code 67 = text; +option user-class code 77 = text; +option provisioning-script-url code 239 = text; +option dhcp6.user-class code 15 = text; +option dhcp6.provisioning-script-url code 239 = text; +option dhcp6.boot-file-url code 59 = text; + +send host-name = gethostname(); +request subnet-mask, broadcast-address, time-offset, routers, + domain-name, domain-name-servers, domain-search, host-name, + dhcp6.name-servers, dhcp6.domain-search, interface-mtu, dhcp6.fqdn, + rfc3442-classless-static-routes, ntp-servers, log-servers, +{%- if ZTP is defined and ZTP_DHCP_DISABLED is not defined -%}bootfile-name, provisioning-script-url, tftp-server-name, + dhcp6.provisioning-script-url, dhcp6.boot-file-url,{%- endif -%} + snmp-community, minigraph-url, acl-url; +{% if ZTP is defined and ZTP_DHCP_DISABLED is not defined %} +send user-class "SONiC-ZTP"; +send dhcp6.user-class "SONiC-ZTP"; +send dhcp-client-identifier "SONiC##{{ ZTP['mode']['product-name'] }}##{{ ZTP['mode']['serial-no'] }}"; +retry 60; +{% endif %} diff --git a/files/dhcp/graphserviceurl b/files/dhcp/graphserviceurl index f255cdff9877..9bd5fded4b8f 100644 --- a/files/dhcp/graphserviceurl +++ b/files/dhcp/graphserviceurl @@ -1,12 +1,14 @@ -case $reason in - BOUND|RENEW|REBIND|REBOOT) - if [ -n "$new_minigraph_url" ]; then - echo $new_minigraph_url > /tmp/dhcp_graph_url - else - echo "N/A" > /tmp/dhcp_graph_url - fi - if [ -n "$new_acl_url" ]; then - echo $new_acl_url > /tmp/dhcp_acl_url - fi - ;; -esac +if [ ! -e /usr/bin/ztp ] || [ "$(ztp status -c)" = "0:DISABLED" ]; then + case $reason in + BOUND|RENEW|REBIND|REBOOT) + if [ -n "$new_minigraph_url" ]; then + echo $new_minigraph_url > /tmp/dhcp_graph_url + else + echo "N/A" > /tmp/dhcp_graph_url + fi + if [ -n "$new_acl_url" ]; then + echo $new_acl_url > /tmp/dhcp_acl_url + fi + ;; + esac +fi diff --git a/files/dhcp/ifupdown2_policy.json b/files/dhcp/ifupdown2_policy.json new file mode 100644 index 000000000000..9a5010dead8a --- /dev/null +++ b/files/dhcp/ifupdown2_policy.json @@ -0,0 +1,12 @@ +{ + "dhcp" : { + "defaults" : { + "dhcp-wait" : "no" + }, + "iface_defaults" : { + "eth0" : { + "dhcp6-duid" : "LL" + } + } + } +} diff --git a/files/dhcp/rfc3442-classless-routes b/files/dhcp/rfc3442-classless-routes index 64e24192816b..797a0d24429f 100644 --- a/files/dhcp/rfc3442-classless-routes +++ b/files/dhcp/rfc3442-classless-routes @@ -55,8 +55,13 @@ if [ "$RUN" = "yes" ]; then fi # set route (ip detects host routes automatically) - ip -4 route add "${net_address}/${net_length}" \ + if echo $interface | grep -v Ethernet ; then + ip -4 route add "${net_address}/${net_length}" \ ${via_arg} dev "${interface}" table default >/dev/null 2>&1 + else + ip -4 route add "${net_address}/${net_length}" \ + ${via_arg} dev "${interface}" >/dev/null 2>&1 + fi done fi fi diff --git a/files/dhcp/sethostname6 b/files/dhcp/sethostname6 new file mode 100644 index 000000000000..6ca5d8dbc995 --- /dev/null +++ b/files/dhcp/sethostname6 @@ -0,0 +1,14 @@ +case $reason in + BOUND6|RENEW6|REBIND6|REBOOT) + current_dhcp6_fqdn=`hostname` + if [ "$current_dhcp6_fqdn" != "$new_dhcp6_fqdn" ] && [ -n "$new_dhcp6_fqdn" ] + then + echo $new_dhcp6_fqdn > /etc/hostname + hostname -F /etc/hostname + sed -i "/\s$current_dhcp6_fqdn$/d" /etc/hosts + sed -i "/\s$new_dhcp6_fqdn$/d" /etc/hosts + echo "127.0.0.1 $new_dhcp6_fqdn" >> /etc/hosts + echo ":: $new_dhcp6_fqdn" >> /etc/hosts + fi + ;; +esac diff --git a/files/image_config/interfaces/interfaces-config.sh b/files/image_config/interfaces/interfaces-config.sh index a702917419ca..8dddc215bbd9 100755 --- a/files/image_config/interfaces/interfaces-config.sh +++ b/files/image_config/interfaces/interfaces-config.sh @@ -2,10 +2,40 @@ ifdown --force eth0 -sonic-cfggen -d -t /usr/share/sonic/templates/interfaces.j2 > /etc/network/interfaces +# Check if ZTP DHCP policy has been installed +if [ -e /etc/network/ifupdown2/policy.d/ztp_dhcp.json ]; then + # Obtain port operational state information + redis-dump -d 0 -k "PORT_TABLE:Ethernet*" -y > /tmp/ztp_port_data.json + + if [ $? -ne 0 ] || [ ! -e /tmp/ztp_port_data.json ] || [ "$(cat /tmp/ztp_port_data.json)" = "" ]; then + echo "{}" > /tmp/ztp_port_data.json + fi + + # Create an input file with ztp input information + echo "{ \"PORT_DATA\" : $(cat /tmp/ztp_port_data.json) }" > \ + /tmp/ztp_input.json +else + echo "{ \"ZTP_DHCP_DISABLED\" : \"true\" }" > /tmp/ztp_input.json +fi + +# Create /e/n/i file for existing and active interfaces +sonic-cfggen -d -j /tmp/ztp_input.json -t /usr/share/sonic/templates/interfaces.j2 > /etc/network/interfaces [ -f /var/run/dhclient.eth0.pid ] && kill `cat /var/run/dhclient.eth0.pid` && rm -f /var/run/dhclient.eth0.pid +[ -f /var/run/dhclient6.eth0.pid ] && kill `cat /var/run/dhclient6.eth0.pid` && rm -f /var/run/dhclient6.eth0.pid +for intf_pid in $(ls -1 /var/run/dhclient*.Ethernet*.pid 2> /dev/null); do + [ -f ${intf_pid} ] && kill `cat ${intf_pid}` && rm -f ${intf_pid} +done + +sonic-cfggen -d -j /tmp/ztp_input.json -t /usr/share/sonic/templates/90-dhcp6-systcl.conf.j2 > /etc/sysctl.d/90-dhcp6-systcl.conf +# Read sysctl conf files again +sysctl -p /etc/sysctl.d/90-dhcp6-systcl.conf + +sonic-cfggen -d -j /tmp/ztp_input.json -t /usr/share/sonic/templates/dhclient.conf.j2 > /etc/dhcp/dhclient.conf systemctl restart networking +# Clean-up created files +rm -f /tmp/ztp_input.json /tmp/ztp_port_data.json + ifdown lo && ifup lo diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index 91be4437fc06..8b8ea0b52bc8 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -27,6 +27,38 @@ iface lo inet loopback # The management network interface auto eth0 +{% if (ZTP_DHCP_DISABLED is not defined) and (ZTP is defined) and (ZTP['mode'] is defined and ZTP['mode']['profile'] == 'active') %} + + +# ZTP out-of-band interface +allow-hotplug eth0 +{% if ZTP['mode']['ipv4'] == 'true' %} +iface eth0 inet dhcp +{% endif %} +{% if ZTP['mode']['ipv6'] == 'true' %} +iface eth0 inet6 dhcp + up sysctl net.ipv6.conf.eth0.accept_ra=1 + down sysctl net.ipv6.conf.eth0.accept_ra=0 +{% endif %} + +{% if ZTP['mode']['inband'] == 'true' %} +{% for port in PORT %} + +# ZTP in-band interface {{ port }} +auto {{ port }} +allow-hotplug {{ port }} +{% if PORT_DATA['PORT_TABLE:'+port] is defined and PORT_DATA['PORT_TABLE:'+port]['value']['oper_status'] == 'up' %} +{% if ZTP['mode']['ipv4'] == 'true' %} +iface {{ port }} inet dhcp +{% endif %} +{% if ZTP['mode']['ipv6'] == 'true' %} +iface {{ port }} inet6 dhcp +{% endif %} +{% endif %} +{% endfor %} +{% endif %} + +{% else %} {% if MGMT_INTERFACE %} {% for (name, prefix) in MGMT_INTERFACE|pfx_filter %} iface eth0 {{ 'inet' if prefix | ipv4 else 'inet6' }} static @@ -70,6 +102,10 @@ iface eth0 inet dhcp up cgset -r l3mdev.master-device=mgmt mgmt down cgdelete -g l3mdev:mgmt {% endif %} +iface eth0 inet6 dhcp + up sysctl net.ipv6.conf.eth0.accept_ra=1 + down sysctl net.ipv6.conf.eth0.accept_ra=0 +{% endif %} {% endif %} # source /etc/network/interfaces.d/* From 9b8c59f4090d462ccc89a31e2951a10a664b4413 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Tue, 10 Dec 2019 09:45:32 -0800 Subject: [PATCH 07/66] [swss] update submodule for sonic-swss (#3864) update multiDB changes in sonic-swss to include multiDB API changes: - [MultiDB]: using new APIs in orch agents and mocktest (#1138) - [vstest]: gather logs when dvs fail to start (#1140) --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index c3b8fe10b156..fc085ee70df1 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit c3b8fe10b1568022fa025ef4be9cb063bfe49df4 +Subproject commit fc085ee70df1b6e4edf512bcfac212be429ab021 From dd322270cba96dbb766688b899167c01f485ef73 Mon Sep 17 00:00:00 2001 From: srideepDell Date: Tue, 10 Dec 2019 16:13:25 -0700 Subject: [PATCH 08/66] [DellEMC]: utility to set onie modes from NOS (#3860) This common utility would set next boot option as onie mode and when reboot is triggered it would reboot the box into that specific onie mode. Current support modes are rescue/install/uninstall --- .../common/onie_mode_set | 90 +++++++++++++++++++ .../debian/platform-modules-s5232f.install | 1 + .../debian/platform-modules-s5248f.install | 1 + .../debian/platform-modules-s6100.install | 1 + .../debian/platform-modules-z9100.install | 1 + .../debian/platform-modules-z9264f.install | 1 + 6 files changed, 95 insertions(+) create mode 100755 platform/broadcom/sonic-platform-modules-dell/common/onie_mode_set diff --git a/platform/broadcom/sonic-platform-modules-dell/common/onie_mode_set b/platform/broadcom/sonic-platform-modules-dell/common/onie_mode_set new file mode 100755 index 000000000000..247dda5dcc8e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/common/onie_mode_set @@ -0,0 +1,90 @@ +#!/bin/bash +#scrit to set onie boot modes from NOS +# modes supported rescue/install/uninstall + +VERBOSE=no +ONIEPATH="/mnt/onie-boot" + +unset ONIE_MODE + +function set_onie_boot() +{ + # If reboot to ONIE is requested, set the ONIE boot mode (update/install/uninstall/rescue) + # and reboot. + + # Exit if not superuser + if [[ "$EUID" -ne 0 ]]; then + echo "This command must be run as root" >&2 + exit 1 + fi + + # Mount ONIE partition if not already mounted + if ! grep -qs '/mnt/onie-boot ' /proc/mounts; then + mkdir -p ${ONIEPATH} + mount LABEL=ONIE-BOOT ${ONIEPATH} || ERR=$? + if [[ ${ERR} -ne 0 ]]; then + VERBOSE=yes debug "Failed to mount ONIE partition." + exit 1 + fi + fi + + # Set mode + ${ONIEPATH}/onie/tools/bin/onie-boot-mode -o ${ONIE_MODE} || ERR=$? + if [[ ${ERR} -ne 0 ]]; then + VERBOSE=yes debug "Failed to set ONIE boot mode. Ensure that mode is valid" + exit 1 + fi + + # Set next boot to ONIE + grub-editenv /host/grub/grubenv set next_entry=ONIE || ERR=$? + if [[ ${ERR} -ne 0 ]]; then + VERBOSE=yes debug "Failed to set next boot to ONIE." + exit 1 + fi + echo "next boot mode set to onie - ${ONIE_MODE}" + +} + + +function debug() +{ + if [[ x"${VERBOSE}" == x"yes" ]]; then + echo `date` $@ + fi + logger "$@" +} + + +SCRIPT=$0 + +function show_help_and_exit() +{ + echo "Usage ${SCRIPT} [options]" + echo " This script will set modes in onie rescue/uninstall/install." + echo " " + echo " Available options:" + echo " -h, -? : getting this help" + echo " -o [mode] : boot into ONIE" + + exit 0 +} + +function parse_options() +{ + while getopts "h?vo:" opt; do + case $opt in + h|\? ) + show_help_and_exit + ;; + o ) + ONIE_MODE=$OPTARG + set_onie_boot + ;; + v ) + VERBOSE=yes + ;; + esac + done +} + +parse_options $@ diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install index b577c5cd5b10..303e978848db 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5232f.install @@ -8,3 +8,4 @@ s5232f/cfg/s5232f-modules.conf etc/modules-load.d s5232f/systemd/platform-modules-s5232f.service etc/systemd/system common/platform_reboot usr/share/sonic/device/x86_64-dellemc_s5232f_c3538-r0 common/fw-updater usr/local/bin +common/onie_mode_set usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install index 7aa27d23b536..e87ea7e37b4e 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5248f.install @@ -8,3 +8,4 @@ s5248f/cfg/s5248f-modules.conf etc/modules-load.d s5248f/systemd/platform-modules-s5248f.service etc/systemd/system common/platform_reboot usr/share/sonic/device/x86_64-dellemc_s5248f_c3538-r0 common/fw-updater usr/local/bin +common/onie_mode_set usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install index 5d1cb6341fc7..eb0211b3afde 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install @@ -14,3 +14,4 @@ s6100/systemd/platform-modules-s6100.service etc/systemd/system s6100/systemd/s6100-lpc-monitor.service etc/systemd/system tools/flashrom/flashrom usr/local/bin/ common/fw-updater usr/local/bin +common/onie_mode_set usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install index 5c5c4cc55be2..a4dffe0d023c 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install @@ -12,3 +12,4 @@ z9100/cfg/z9100-modules.conf etc/modules-load.d z9100/systemd/platform-modules-z9100.service etc/systemd/system z9100/systemd/z9100-lpc-monitor.service etc/systemd/system common/fw-updater usr/local/bin +common/onie_mode_set usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install index 29e8b1df2e36..e7d589f14e0c 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9264f.install @@ -8,3 +8,4 @@ z9264f/cfg/z9264f-modules.conf etc/modules-load.d z9264f/systemd/platform-modules-z9264f.service etc/systemd/system common/platform_reboot usr/share/sonic/device/x86_64-dellemc_z9264f_c3538-r0 common/fw-updater usr/local/bin +common/onie_mode_set usr/local/bin From 7ef57f92e1479b382fce962b2ea8c0346d0550b5 Mon Sep 17 00:00:00 2001 From: Myron Sosyak <49795530+msosyak@users.noreply.github.com> Date: Tue, 10 Dec 2019 18:03:55 -0800 Subject: [PATCH 09/66] [docker-sonic-mgmt]: Add docker-ce-cli to sonic-mgmt container (#3868) In the scope of migration from docker shell plugin to docker connection plugin, we need to have docker-ce-cli installed in docker-sonic-mgmt. Azure/sonic-mgmt#1269 Added docker-ce-cli package to docker-sonic-mgmt. --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index d24df1ca5d77..4c53baf7c485 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -71,6 +71,19 @@ RUN pip install ipaddr \ && pip install nnpy \ && pip install dpkt +# Install docker-ce-cli +RUN apt-get update \ + && apt-get install -y \ + apt-transport-https \ + ca-certificates \ + curl \ + gnupg-agent \ + software-properties-common \ + && curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - \ + && add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \ + && apt-get update \ + && apt-get install -y docker-ce-cli + # Install Microsoft Azure Kusto Library for Python RUN pip install azure-kusto-data==0.0.13 \ azure-kusto-ingest==0.0.13 From 979b0dd4a2e051a2226aac3f5daa4c8be11bfa94 Mon Sep 17 00:00:00 2001 From: kannankvs Date: Wed, 11 Dec 2019 13:18:18 +0530 Subject: [PATCH 10/66] [doc]: Added one extra sentence to give example for check out 201911 branch (#3867) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a1de15524b63..301bff39547e 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ To build SONiC installer image and docker images, run the following commands: # Enter the source directory cd sonic-buildimage - # (Optional) Checkout a specific branch. By default, it uses master branch + # (Optional) Checkout a specific branch. By default, it uses master branch. For example, to checkout the branch 201911, use "git checkout 201911" git checkout [branch_name] # Execute make init once after cloning the repo, or after fetching remote repo with submodule updates From 3b0c51f423637aafb0c0c42c98c6729e1609468a Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Thu, 12 Dec 2019 01:41:29 +0800 Subject: [PATCH 11/66] [sub module] Update sonic-platform-common pointer to pick up fix (#3859) Azure/sonic-platform-common#71 [Bug fix] fix a syntax error which was introduced by last commit Azure/sonic-platform-common#70 Fix EEPROM vendor extension TLV number counting issue Azure/sonic-platform-common#62 Platform Driver Development Framework (PDDF): 1) Changes to psu base class (1.0 APIs) to support PDDF CLI utils, 2) Adding fan_base class to support PDDF fan CLI utils (comments incorporated) Azure/sonic-platform-common#68 DeviceBase.get_name should raise NotImplementedError like other member --- src/sonic-platform-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index 6ad48b87eb96..6f74dd3f4f42 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 6ad48b87eb9654daa3f3c854134434d14572573f +Subproject commit 6f74dd3f4f42bc945467cffa4f889b50e4b1468a From ef26ba024d73996073ff9afc2fc15d8da0802d7e Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Fri, 13 Dec 2019 03:09:28 +0800 Subject: [PATCH 12/66] [Mellanox]Update hw-mgmt to V7.0000.2308 (#3858) * [Mellanox]Update hw-mgmt to V7.0000.2308 sonic-linux-kernel should be updated accordingly with necessary patches uploaded. * [sub-module]Advance submodule head for sonic-linux-kernel --- platform/mellanox/hw-management.mk | 2 +- platform/mellanox/hw-management/hw-mgmt | 2 +- src/sonic-linux-kernel | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/mellanox/hw-management.mk b/platform/mellanox/hw-management.mk index f41c2b9a25ce..ff1ea207572d 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.2303 +MLNX_HW_MANAGEMENT_VERSION = 7.0000.2308 export MLNX_HW_MANAGEMENT_VERSION diff --git a/platform/mellanox/hw-management/hw-mgmt b/platform/mellanox/hw-management/hw-mgmt index 7c26a8f6a520..28d83cdb3565 160000 --- a/platform/mellanox/hw-management/hw-mgmt +++ b/platform/mellanox/hw-management/hw-mgmt @@ -1 +1 @@ -Subproject commit 7c26a8f6a520b06663992afe874bc56b1fcd9311 +Subproject commit 28d83cdb3565d3b0352cc718fe82a14cacd1d4a5 diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index feb42b05eb91..87576c061d10 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit feb42b05eb912ea64f0b4ce17f4bc890929eb57e +Subproject commit 87576c061d10dfe7de8e8e5cc1bae6bd29b0143b From 13eec88732835b82802721deed72c2c43f3751bc Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Thu, 12 Dec 2019 18:46:35 -0800 Subject: [PATCH 13/66] Change the dpkg default behavior in slave, and docker-base, in order to prevent prompt (#3879) * Change the dpkg default behavior in slave, and docker-base, in order to prevent prompt * Move to right place --- dockers/docker-base-stretch/dpkg_01_drop | 8 ++++++++ dockers/docker-base/dpkg_01_drop | 8 ++++++++ sonic-slave-stretch/Dockerfile.j2 | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/dockers/docker-base-stretch/dpkg_01_drop b/dockers/docker-base-stretch/dpkg_01_drop index e75ef3147158..d749943797d9 100644 --- a/dockers/docker-base-stretch/dpkg_01_drop +++ b/dockers/docker-base-stretch/dpkg_01_drop @@ -20,3 +20,11 @@ path-exclude /usr/share/pyshared/twisted/test* path-exclude /usr/lib/python*/dist-packages/twisted/test* path-exclude /usr/share/pyshared/twisted/*/test* path-exclude /usr/lib/python*/dist-packages/twisted/*/test* + +## install the configuration file if it’s currently missing +force-confmiss +## combined with confold: overwrite configuration files that you have not modified +force-confdef +## do not modify the current configuration file, the new version is installed with a .dpkg-dist suffix +force-confold + diff --git a/dockers/docker-base/dpkg_01_drop b/dockers/docker-base/dpkg_01_drop index e75ef3147158..d749943797d9 100644 --- a/dockers/docker-base/dpkg_01_drop +++ b/dockers/docker-base/dpkg_01_drop @@ -20,3 +20,11 @@ path-exclude /usr/share/pyshared/twisted/test* path-exclude /usr/lib/python*/dist-packages/twisted/test* path-exclude /usr/share/pyshared/twisted/*/test* path-exclude /usr/lib/python*/dist-packages/twisted/*/test* + +## install the configuration file if it’s currently missing +force-confmiss +## combined with confold: overwrite configuration files that you have not modified +force-confdef +## do not modify the current configuration file, the new version is installed with a .dpkg-dist suffix +force-confold + diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index f52bd943b0a7..133238622f76 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -293,6 +293,14 @@ RUN apt-get update && apt-get install -y \ # For kdump-tools liblzo2-dev +## Config dpkg +## install the configuration file if it’s currently missing +RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confmiss" +## combined with confold: overwrite configuration files that you have not modified +RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confdef" +## do not modify the current configuration file, the new version is installed with a .dpkg-dist suffix +RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confold" + # For smartmontools 6.6-1 RUN apt-get -t stretch-backports install -y debhelper From f126258d5fa40406b5412cb6afff7eeb6529b224 Mon Sep 17 00:00:00 2001 From: ciju-juniper <53076238+ciju-juniper@users.noreply.github.com> Date: Fri, 13 Dec 2019 22:36:05 +0530 Subject: [PATCH 14/66] [Juniper][QFX5210] Platform monitoring updates (#3899) As part of this commit, there are a few enhancements being made for EM policy implementation: a) Introduced hysteresis algorithm to prevent fan hunting b) Reading ASIC temperature to make decision for fan speed. As part of the PR# 3599, Workaround for the boot problem from secondary bios was addressed. When the SONiC image is upgraded, this resulted in creating multiple entries for BOOTX64.EFI. To fix the problem, as part of this changeset, introducing a check to see if there is already an UEFI entry for BOOTX64.EFI and accordingly creating / skipping the UEFI entry. Signed-off-by: Ciju Rajan K --- .../sonic-platform-juniper-qfx5210.postinst | 11 +- .../qfx5210/utils/juniper_qfx5210_monitor.py | 221 ++++++++++++++---- 2 files changed, 181 insertions(+), 51 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst index dcff39f53799..97b66fb44e4c 100644 --- a/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst +++ b/platform/broadcom/sonic-platform-modules-juniper/debian/sonic-platform-juniper-qfx5210.postinst @@ -1,3 +1,5 @@ +#!/bin/bash + systemctl enable qfx5210-platform-init.service systemctl start qfx5210-platform-init.service @@ -18,5 +20,12 @@ if [ -f $FIRST_BOOT_FILE ]; then cp SONiC-OS/grubx64.efi BOOT/BOOTX64.EFI cd /tmp umount sda1 - efibootmgr -c -L "SONiC" -l "\EFI\BOOT\BOOTX64.EFI" > /dev/null 2>&1 + # This code block ensures that no additional entries + # are added. This is applicable during SONiC image + # upgrades. + entries=`efibootmgr -v | grep "BOOTX64"` + if [ -z "$entries" ]; then + # Creating the UEFI entry for the first time. + efibootmgr -c -L "SONiC" -l "\EFI\BOOT\BOOTX64.EFI" > /var/tmp/efi_log 2>&1 + fi fi diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py index d225400121b8..97adf9588f9f 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 @@ -47,6 +47,7 @@ import traceback import glob import collections + import StringIO from tabulate import tabulate except ImportError as e: raise ImportError('%s - required module not found' % str(e)) @@ -54,15 +55,20 @@ # Deafults VERSION = '1.0' FUNCTION_NAME = '/var/log/juniper_qfx5210_monitor' - +verbose = False +DEBUG = False global log_file global log_level global isPlatformAFI +global is80PerFlag +global is60PerFlag global isFireThresholdReached -FireThresholdSecsRemaining = 120 +global isFireThresholdPrint +global PrevASICValue +global FireThresholdSecsRemaining temp_policy_AFI = { 0: [[70, 0, 48000], [70, 48000, 53000], [80, 53000, 0], [80, 53000, 58000], [100, 58000, 0], ['Yellow Alarm', 64000, 70000], ['Red Alarm', 70000, 75000], ['Fire Shut Alarm', 75000, 0]], @@ -72,6 +78,7 @@ 4: [[70, 0, 31000], [70, 31000, 36000], [80, 36000, 0], [80, 36000, 42000], [100, 42000, 0], ['Yellow Alarm', 48000, 55000], ['Red Alarm', 55000, 60000], ['Fire Shut Alarm', 60000, 0]], 5: [[70, 0, 31000], [70, 31000, 36000], [80, 36000, 0], [80, 36000, 43000], [100, 43000, 0], ['Yellow Alarm', 49000, 56000], ['Red Alarm', 56000, 61000], ['Fire Shut Alarm', 61000, 0]], 6: [[70, 0, 70000], [70, 70000, 78000], [80, 78000, 0], [80, 78000, 86000], [100, 86000, 0], ['Yellow Alarm', 91000, 96000], ['Red Alarm', 96000, 102000], ['Fire Shut Alarm', 102000, 0]], + 7: [[70, 0, 84000], [70, 84000, 91000], [80, 91000, 0], [80, 91000, 98000], [100, 98000, 0], ['Yellow Alarm', 103000, 108000], ['Red Alarm', 108000, 120000], ['Fire Shut Alarm', 120000, 0]], } temp_policy_AFO = { @@ -82,6 +89,7 @@ 4: [[60, 0, 39000], [60, 39000, 45000], [80, 45000, 0], [80, 45000, 52000], [100, 52000, 0], ['Yellow Alarm', 59000, 65000], ['Red Alarm', 65000, 69000], ['Fire Shut Alarm', 69000, 0]], 5: [[60, 0, 37000], [60, 37000, 43000], [80, 43000, 0], [80, 43000, 50000], [100, 50000, 0], ['Yellow Alarm', 57000, 63000], ['Red Alarm', 63000, 67000], ['Fire Shut Alarm', 67000, 0]], 6: [[60, 0, 70000], [60, 70000, 78000], [80, 78000, 0], [80, 78000, 86000], [100, 86000, 0], ['Yellow Alarm', 91000, 96000], ['Red Alarm', 96000, 102000], ['Fire Shut Alarm', 102000, 0]], + 7: [[60, 0, 84000], [60, 84000, 91000], [80, 91000, 0], [80, 91000, 98000], [100, 98000, 0], ['Yellow Alarm', 103000, 108000], ['Red Alarm', 108000, 120000], ['Fire Shut Alarm', 120000, 0]], } class QFX5210_FanUtil(object): @@ -97,7 +105,7 @@ def get_fan_duty_cycle(self): try: val_file = open(self.FAN_DUTY_PATH) except IOError as e: - print "Error: unable to open file: %s" % str(e) + logging.error('get_fan_duty_cycle: unable to open file: %s', str(e)) return False content = val_file.readline().rstrip() @@ -110,7 +118,7 @@ def set_fan_duty_cycle(self, val): try: fan_file = open(self.FAN_DUTY_PATH, 'r+') except IOError as e: - print "Error: unable to open file: %s" % str(e) + logging.error('set_fan_duty_cycle: unable to open file: %s', str(e)) return False fan_file.write(str(val)) fan_file.close() @@ -120,7 +128,8 @@ class QFX5210_ThermalUtil(object): """QFX5210 Platform ThermalUtil class""" SENSOR_NUM_ON_MAIN_BOARD = 6 - SENSOR_CORETEMP_NUM_ON_MAIN_BOARD = 7 + CORETEMP_INDEX_ON_MAIN_BOARD = 6 + SENSOR_CORETEMP_NUM_ON_MAIN_BOARD = 8 CORETEMP_NUM_ON_MAIN_BOARD = 5 THERMAL_NUM_RANGE = 8 SENSOR_NUM_1_IDX = 1 @@ -181,19 +190,19 @@ def _get_sensor_node_val(self, thermal_num): try: val_file = open(filename, 'r') except IOError as e: - logging.error('GET. unable to open file: %s', str(e)) + logging.error('get_sensor_node_val: unable to open file: %s', str(e)) return None content = val_file.readline().rstrip() if content == '': - logging.debug('GET. content is NULL. device_path:%s', device_path) + logging.debug('get_sensor_node_val: content is NULL. device_path:%s', device_path) return None try: - val_file.close() + val_file.close() except: - logging.debug('GET. unable to close file. device_path:%s', device_path) + logging.debug('get_sensor_node_val: unable to close file. device_path:%s', device_path) return None return int(content) @@ -208,19 +217,19 @@ def _get_coretemp_node_val(self, thermal_num): try: val_file = open(filename, 'r') except IOError as e: - logging.error('GET. unable to open file: %s', str(e)) + logging.error('get_coretemp_node_val: unable to open file: %s', str(e)) return None content = val_file.readline().rstrip() if content == '': - logging.debug('GET. content is NULL. device_path:%s', device_path) + logging.debug('get_coretemp_node_val: content is NULL. device_path:%s', device_path) return None try: val_file.close() except: - logging.debug('GET. unable to close file. device_path:%s', device_path) + logging.debug('get_coretemp_node_val: unable to close file. device_path:%s', device_path) return None return int(content) @@ -243,7 +252,7 @@ def get_alarm_led_brightness(self): try: val_file = open(self.ALARM_LED_PATH) except IOError as e: - print "Error: unable to open file: %s" % str(e) + logging.error('get_alarm_led_brightness: unable to open file: %s', str(e)) return False content = val_file.readline().rstrip() @@ -260,7 +269,7 @@ def set_alarm_led_brightness(self, val): try: val_file = open(self.ALARM_LED_PATH, 'r+') except IOError as e: - print "Error: unable to open file: %s" % str(e) + logging.error('set_alarm_led_brightness: unable to open file: %s', str(e)) return False val_file.write(str(val)) val_file.close() @@ -274,8 +283,12 @@ def set_alarm_led_brightness(self, val): def getSensorTemp(self): sum = 0 global isPlatformAFI + global is80PerFlag + global is60PerFlag global isFireThresholdReached - global FireThresholdSecsRemaining + global FireThresholdSecsRemaining + global isFireThresholdPrint + global PrevASICValue #AFI if (isPlatformAFI == True): temp_policy = temp_policy_AFI @@ -294,14 +307,22 @@ def getSensorTemp(self): 4: [0,0,0,0,0,0,0,0], 5: [0,0,0,0,0,0,0,0], 6: [0,0,0,0,0,0,0,0], + 7: [0,0,0,0,0,0,0,0], } # if the Firethreshold Flag is set and 120 seconds have elapsed, invoking the "poweroff" to shutdown the box if (isFireThresholdReached == True): firethr = FireThresholdSecsRemaining - 20 - logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown in %s seconds', firethr) - print "Fire Threshold reached: System is going to shutdown in %s seconds\n" % firethr + if firethr == 0: + logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown now') + os.system("echo 'CRITICAL: Fire Threshold reached: System is going to shutdown now' > /dev/console") + else: + logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown in %s seconds', firethr) + os.system("echo 'CRITICAL: Fire Threshold reached: System is going to shutdown in %s seconds' > /dev/console" % firethr) + FireThresholdSecsRemaining = FireThresholdSecsRemaining - 20 - if (FireThresholdSecsRemaining == 20): + logging.critical('CRITICAL: Value of FireThresholdSecsRemaining %s seconds', FireThresholdSecsRemaining) + + if (FireThresholdSecsRemaining == 0): isFireThresholdReached == False time.sleep(20) cmd = "poweroff" @@ -310,9 +331,32 @@ def getSensorTemp(self): for x in range(self.SENSOR_CORETEMP_NUM_ON_MAIN_BOARD): if x < self.SENSOR_NUM_ON_MAIN_BOARD: value = self._get_sensor_node_val(x+1) + logging.debug('Sensor value %d : %s', x, value) + elif x == self.CORETEMP_INDEX_ON_MAIN_BOARD: + value = self.get_coretempValue() + logging.debug('Main Board CORE temp: %s', value) else: - value = self.get_coretempValue() - + logging.debug('Reading ASIC Temp value using bcmcmd') + proc = subprocess.Popen("bcmcmd \"show temp\" | grep \"maximum peak temperature\" | awk '{ print $5 }' > /var/log/asic_value 2>&1 & ",shell=True) + time.sleep(2) + cmd = "kill -9 %s"%(proc.pid) + status, cmd_out = commands.getstatusoutput(cmd) + + if os.stat("/var/log/asic_value").st_size == 0: + value = PrevASICValue + logging.debug('No ASIC Temp file, Prev ASIC Temp Value: %s', PrevASICValue) + else: + with open('/var/log/asic_value', 'r') as f: + value1 = f.readline() + value2 = float(value1) + value1 = value2 * 1000 + value = int(value1) + PrevASICValue = value + logging.debug('Reading from ASIC Temp file: %s', value) + logging.debug('Reading from Prev ASIC Temp Value: %s', PrevASICValue) + + os.system('rm /var/log/asic_value') + # 60% Duty Cycle for AFO and 70% Duty Cycle for AFI if value > temp_policy[x][0][1] and value <= temp_policy[x][0][2]: SensorFlag[x][0] = True @@ -350,57 +394,113 @@ def getSensorTemp(self): fan = QFX5210_FanUtil() # CHECK IF ANY TEMPERATURE SENSORS HAS SET FIRE SHUTDOWN FLAG - if SensorFlag[0][7] or SensorFlag[1][7] or SensorFlag[2][7] or SensorFlag[3][7] or SensorFlag[4][7] or SensorFlag[5][7] or SensorFlag[6][7]: + if SensorFlag[0][7] or SensorFlag[1][7] or SensorFlag[2][7] or SensorFlag[3][7] or SensorFlag[4][7] or SensorFlag[5][7] or SensorFlag[6][7] or SensorFlag[7][7]: isFireThresholdReached = True - logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown in 120 seconds') - print "CRITICAL: Fire Threshold reached: System is going to shutdown in 120 seconds\n" - value = self.get_alarm_led_brightness() - if ( value > 0): - self.set_alarm_led_brightness(0) + if (isFireThresholdPrint == True): + logging.critical('CRITICAL: Fire Threshold reached: System is going to shutdown in 120 seconds') + os.system("echo 'CRITICAL: Fire Threshold reached: System is going to shutdown in 120 seconds' > /dev/console") + isFireThresholdPrint = False + + logging.debug('Temp Sensor is set to FIRE SHUTDOWN Flag') + fan.set_fan_duty_cycle(100) + self.set_alarm_led_brightness(2) # CHECK IF ANY TEMPERATURE SENSORS HAS SET 'RED' ALARM FLAG, IF YES, SET THE ALARM LED TO 'RED' - elif SensorFlag[0][6] or SensorFlag[1][6] or SensorFlag[2][6] or SensorFlag[3][6] or SensorFlag[4][6] or SensorFlag[5][6] or SensorFlag[6][6]: + elif SensorFlag[0][6] or SensorFlag[1][6] or SensorFlag[2][6] or SensorFlag[3][6] or SensorFlag[4][6] or SensorFlag[5][6] or SensorFlag[6][6] or SensorFlag[7][6]: + fan.set_fan_duty_cycle(100) self.set_alarm_led_brightness(2) + logging.debug('Temp Sensor is set to Red Alarm Flag') + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False # CHECK IF ANY TEMPERATURE SENSORS HAS SET 'YELLOW' ALARM FLAG, IF YES, SET THE ALARM LED TO 'YELLOW' - elif SensorFlag[0][5] or SensorFlag[1][5] or SensorFlag[2][5] or SensorFlag[3][5] or SensorFlag[4][5] or SensorFlag[5][5] or SensorFlag[6][5]: + elif SensorFlag[0][5] or SensorFlag[1][5] or SensorFlag[2][5] or SensorFlag[3][5] or SensorFlag[4][5] or SensorFlag[5][5] or SensorFlag[6][5] or SensorFlag[7][5]: + fan.set_fan_duty_cycle(100) self.set_alarm_led_brightness(1) + logging.debug('Temp Sensor is set to Yellow Alarm Flag') + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False # CHECK IF ANY TEMPERATURE SENSORS HAS SET 100% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 100% - elif SensorFlag[0][4] or SensorFlag[1][4] or SensorFlag[2][4] or SensorFlag[3][4] or SensorFlag[4][4] or SensorFlag[5][4] or SensorFlag[6][4]: + elif SensorFlag[0][4] or SensorFlag[1][4] or SensorFlag[2][4] or SensorFlag[3][4] or SensorFlag[4][4] or SensorFlag[5][4] or SensorFlag[6][4] or SensorFlag[7][4]: fan.set_fan_duty_cycle(100) value = self.get_alarm_led_brightness() if ( value > 0): self.set_alarm_led_brightness(0) + is80PerFlag = False + is60PerFlag = False + logging.debug('Temp Sensor is set to 100% Duty Cycle Flag') # CHECK IF ANY TEMPERATURE SENSORS HAS SET 80% DUTY CYCLE PREV FLAG, IF YES, SET THE FAN DUTY CYCLE TO 80% - elif SensorFlag[0][3] or SensorFlag[1][3] or SensorFlag[2][3] or SensorFlag[3][3] or SensorFlag[4][3] or SensorFlag[5][3] or SensorFlag[6][3]: - fan.set_fan_duty_cycle(80) + elif SensorFlag[0][3] or SensorFlag[1][3] or SensorFlag[2][3] or SensorFlag[3][3] or SensorFlag[4][3] or SensorFlag[5][3] or SensorFlag[6][3] or SensorFlag[7][3]: + if (is80PerFlag == True): + fan.set_fan_duty_cycle(80) + is80PerFlag = False + else: + pass + value = self.get_alarm_led_brightness() if ( value > 0): self.set_alarm_led_brightness(0) + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + logging.debug('Temp Sensor is set to 80% Prev Duty Cycle Flag') + # CHECK IF ANY TEMPERATURE SENSORS HAS SET 80% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 80% - elif SensorFlag[0][2] or SensorFlag[1][2] or SensorFlag[2][2] or SensorFlag[3][2] or SensorFlag[4][2] or SensorFlag[5][2] or SensorFlag[6][2]: + elif SensorFlag[0][2] or SensorFlag[1][2] or SensorFlag[2][2] or SensorFlag[3][2] or SensorFlag[4][2] or SensorFlag[5][2] or SensorFlag[6][2] or SensorFlag[7][2]: fan.set_fan_duty_cycle(80) value = self.get_alarm_led_brightness() if ( value > 0): self.set_alarm_led_brightness(0) + is80PerFlag = True + + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + logging.debug('Temp Sensor is set to 80% Duty Cycle Flag') # FOR "AFO" Platform CHECK IF ANY TEMPERATURE SENSORS HAS SET 60% DUTY CYCLE PREV FLAG, IF YES, SET THE FAN DUTY CYCLE TO 60% # FOR "AFI" Platform CHECK IF ANY TEMPERATURE SENSORS HAS SET 70% DUTY CYCLE PREV FLAG, IF YES, SET THE FAN DUTY CYCLE TO 70% - elif SensorFlag[0][1] or SensorFlag[1][1] or SensorFlag[2][1] or SensorFlag[3][1] or SensorFlag[4][1] or SensorFlag[5][1] or SensorFlag[6][1]: - if (isPlatformAFI == True): - fan.set_fan_duty_cycle(70) + elif SensorFlag[0][1] or SensorFlag[1][1] or SensorFlag[2][1] or SensorFlag[3][1] or SensorFlag[4][1] or SensorFlag[5][1] or SensorFlag[6][1] or SensorFlag[7][1]: + if (is60PerFlag == True): + if (isPlatformAFI == True): + fan.set_fan_duty_cycle(70) + else: + fan.set_fan_duty_cycle(60) + + is60PerFlag = False + is80PerFlag = True else: - fan.set_fan_duty_cycle(60) + pass + value = self.get_alarm_led_brightness() if ( value > 0): self.set_alarm_led_brightness(0) + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + + logging.debug('Temp Sensor is set to 60% Prev Duty Cycle Flag') + # FOR "AFO" Platform CHECK IF ANY TEMPERATURE SENSORS HAS SET 60% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 60% # FOR "AFI" Platform CHECK IF ANY TEMPERATURE SENSORS HAS SET 70% DUTY CYCLE FLAG, IF YES, SET THE FAN DUTY CYCLE TO 70% - elif SensorFlag[0][0] or SensorFlag[1][0] or SensorFlag[2][0] or SensorFlag[3][0] or SensorFlag[4][0] or SensorFlag[5][0] or SensorFlag[6][0]: + elif SensorFlag[0][0] or SensorFlag[1][0] or SensorFlag[2][0] or SensorFlag[3][0] or SensorFlag[4][0] or SensorFlag[5][0] or SensorFlag[6][0] or SensorFlag[7][0]: if (isPlatformAFI == True): fan.set_fan_duty_cycle(70) else: @@ -408,6 +508,15 @@ def getSensorTemp(self): value = self.get_alarm_led_brightness() if ( value > 0): self.set_alarm_led_brightness(0) + is60PerFlag = True + is80PerFlag = True + + if (isFireThresholdReached == True): + logging.critical('CRITICAL: System Stabilized, not shutting down') + os.system("echo 'CRITICAL: System Stabilized, not shutting down' > /dev/console") + FireThresholdSecsRemaining = 120 + isFireThresholdReached = False + logging.debug('Temp Sensor is set to 60% Duty Cycle Flag') else: pass @@ -417,14 +526,18 @@ def getSensorTemp(self): for x in range(self.SENSOR_CORETEMP_NUM_ON_MAIN_BOARD): for y in range(self.THERMAL_NUM_RANGE): SensorFlag[x][y] = 0 - class device_monitor(object): def __init__(self, log_file, log_level): - + global DEBUG global isPlatformAFI global isFireThresholdReached + global is80PerFlag + global is60PerFlag + global isFireThresholdPrint + global PrevASICValue + global FireThresholdSecsRemaining MASTER_LED_PATH = '/sys/class/leds/master/brightness' SYSTEM_LED_PATH = '/sys/class/leds/system/brightness' FANTYPE_PATH = '/sys/bus/i2c/devices/17-0068/fan1_direction' @@ -439,13 +552,14 @@ def __init__(self, log_file, log_level): datefmt='%H:%M:%S' ) + if DEBUG == True: # set up logging to console - if log_level == logging.DEBUG: - console = logging.StreamHandler() - console.setLevel(log_level) - formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') - console.setFormatter(formatter) - logging.getLogger('').addHandler(console) + if log_level == logging.DEBUG: + console = logging.StreamHandler() + console.setLevel(log_level) + formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) import sonic_platform platform = sonic_platform.platform.Platform() @@ -454,20 +568,25 @@ def __init__(self, log_file, log_level): # the return value of get_fan_type is AFO = 0, AFI = 1 and for error condition it is -1 # In the error condition also, we are making default platform as AFO, to continue with Energy Monitoring - if (fan_type == -1 or fan_type == 0): - if (fan_type == -1): - print "Error: unable to open sys file for fan handling, defaulting it to AFO" + if (int(fan_type) == -1 or int(fan_type) == 0): + if (int(fan_type) == -1): + logging.error('device_monitor: unable to open sys file for fan handling, defaulting it to AFO') isPlatformAFI = False else: isPlatformAFI = True isFireThresholdReached = False + is80PerFlag = True + is60PerFlag = True + isFireThresholdPrint = True + FireThresholdSecsRemaining = 120 + PrevASICValue = 0 master_led_value = 1 try: masterLED_file = open(MASTER_LED_PATH, 'r+') except IOError as e: - print "Error: unable to open file: %s" % str(e) + logging.error('device_monitor: unable to open Master LED file: %s', str(e)) return False masterLED_file.write(str(master_led_value)) masterLED_file.close() @@ -476,7 +595,7 @@ def __init__(self, log_file, log_level): try: systemLED_file = open(SYSTEM_LED_PATH, 'r+') except IOError as e: - print "Error: unable to open file: %s" % str(e) + logging.error('device_monitor: unable to open System LED file: %s', str(e)) return False systemLED_file.write(str(system_led_value)) systemLED_file.close() @@ -490,6 +609,8 @@ def main(): log_file = '%s.log' % FUNCTION_NAME log_level = logging.DEBUG + #Introducing sleep of 150 seconds to wait for all the docker containers to start before starting the EM policy. + time.sleep(150) monitor = device_monitor(log_file, log_level) while True: monitor.manage_device() From 86e23f9ededb0b56d55bdad09e4d9c91b20aaee4 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Fri, 13 Dec 2019 13:46:48 -0800 Subject: [PATCH 15/66] [lldpd]: Ports few fixes from lldpd master (#3889) * lldpctl: put a lock around some commands to avoid race conditions * Read all notifications in lldpctl_recv * lib: fix memory leak * lib: fix memory leak when handling I/O * Update series --- ...ck-around-some-commands-to-avoid-rac.patch | 169 ++++++++++++++++++ ...ad-all-notifications-in-lldpctl_recv.patch | 27 +++ .../patch/0006-lib-fix-memory-leak.patch | 24 +++ ...ib-fix-memory-leak-when-handling-I-O.patch | 85 +++++++++ src/lldpd/patch/series | 4 + 5 files changed, 309 insertions(+) create mode 100644 src/lldpd/patch/0004-lldpctl-put-a-lock-around-some-commands-to-avoid-rac.patch create mode 100644 src/lldpd/patch/0005-Read-all-notifications-in-lldpctl_recv.patch create mode 100644 src/lldpd/patch/0006-lib-fix-memory-leak.patch create mode 100644 src/lldpd/patch/0007-lib-fix-memory-leak-when-handling-I-O.patch diff --git a/src/lldpd/patch/0004-lldpctl-put-a-lock-around-some-commands-to-avoid-rac.patch b/src/lldpd/patch/0004-lldpctl-put-a-lock-around-some-commands-to-avoid-rac.patch new file mode 100644 index 000000000000..df7f26131dd4 --- /dev/null +++ b/src/lldpd/patch/0004-lldpctl-put-a-lock-around-some-commands-to-avoid-rac.patch @@ -0,0 +1,169 @@ +From 46aa45d0fa3e8879ecdca1c156cb2d91194c45e9 Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Thu, 12 Dec 2019 13:47:17 -0800 +Subject: [PATCH 1/1] lldpctl: put a lock around some commands to avoid race + conditions + +--- + src/client/client.h | 3 +++ + src/client/commands.c | 58 ++++++++++++++++++++++++++++++++++++++++--- + src/client/conf.c | 4 +-- + 3 files changed, 60 insertions(+), 5 deletions(-) + +diff --git a/src/client/client.h b/src/client/client.h +index e3ee352..6c3e30d 100644 +--- a/src/client/client.h ++++ b/src/client/client.h +@@ -62,6 +62,8 @@ extern void add_history (); + #endif + #undef NEWLINE + ++extern const char *ctlname; ++ + /* commands.c */ + #define NEWLINE "" + struct cmd_node; +@@ -76,6 +78,7 @@ struct cmd_node *commands_new( + struct cmd_env*, void *), + void *); + struct cmd_node* commands_privileged(struct cmd_node *); ++struct cmd_node* commands_lock(struct cmd_node *); + struct cmd_node* commands_hidden(struct cmd_node *); + void commands_free(struct cmd_node *); + const char *cmdenv_arg(struct cmd_env*); +diff --git a/src/client/commands.c b/src/client/commands.c +index beedbf1..58df4a7 100644 +--- a/src/client/commands.c ++++ b/src/client/commands.c +@@ -18,6 +18,9 @@ + #include "client.h" + #include + #include ++#include ++#include ++#include + + /** + * An element of the environment (a key and a value). +@@ -68,6 +71,7 @@ struct cmd_node { + const char *token; /**< Token to enter this cnode */ + const char *doc; /**< Documentation string */ + int privileged; /**< Privileged command? */ ++ int lock; /**< Lock required for execution? */ + int hidden; /**< Hidden command? */ + + /** +@@ -113,6 +117,21 @@ commands_privileged(struct cmd_node *node) + return node; + } + ++/** ++ * Make a node accessible only with a lock. ++ * ++ * @param node node to use lock to execute ++ * @return the modified node ++ * ++ * The node is modified. It is returned to ease chaining. ++ */ ++struct cmd_node* ++commands_lock(struct cmd_node *node) ++{ ++ if (node) node->lock = 1; ++ return node; ++} ++ + /** + * Hide a node from help or completion. + * +@@ -344,6 +363,7 @@ _commands_execute(struct lldpctl_conn_t *conn, struct writer *w, + int n, rc = 0, completion = (word != NULL); + int help = 0; /* Are we asking for help? */ + int complete = 0; /* Are we asking for possible completions? */ ++ int needlock = 0; /* Do we need a lock? */ + struct cmd_env env = { + .elements = TAILQ_HEAD_INITIALIZER(env.elements), + .stack = TAILQ_HEAD_INITIALIZER(env.stack), +@@ -351,6 +371,7 @@ _commands_execute(struct lldpctl_conn_t *conn, struct writer *w, + .argv = argv, + .argp = 0 + }; ++ static int lockfd = -1; + cmdenv_push(&env, root); + if (!completion) + for (n = 0; n < argc; n++) +@@ -388,6 +409,7 @@ _commands_execute(struct lldpctl_conn_t *conn, struct writer *w, + !strcmp(candidate->token, token)) { + /* Exact match */ + best = candidate; ++ needlock = needlock || candidate->lock; + break; + } + if (!best) best = candidate; +@@ -406,6 +428,7 @@ _commands_execute(struct lldpctl_conn_t *conn, struct writer *w, + if (!candidate->token && + CAN_EXECUTE(candidate)) { + best = candidate; ++ needlock = needlock || candidate->lock; + break; + } + } +@@ -421,9 +444,38 @@ _commands_execute(struct lldpctl_conn_t *conn, struct writer *w, + + /* Push and execute */ + cmdenv_push(&env, best); +- if (best->execute && best->execute(conn, w, &env, best->arg) != 1) { +- rc = -1; +- goto end; ++ if (best->execute) { ++ struct sockaddr_un su; ++ if (needlock) { ++ if (lockfd == -1) { ++ log_debug("lldpctl", "reopen %s for locking", ctlname); ++ if ((lockfd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) { ++ log_warn("lldpctl", "cannot open for lock %s", ctlname); ++ rc = -1; ++ goto end; ++ } ++ su.sun_family = AF_UNIX; ++ strlcpy(su.sun_path, ctlname, sizeof(su.sun_path)); ++ if (connect(lockfd, (struct sockaddr *)&su, sizeof(struct sockaddr_un)) == -1) { ++ log_warn("lldpctl", "cannot connect to socket %s", ctlname); ++ rc = -1; ++ close(lockfd); lockfd = -1; ++ goto end; ++ } ++ } ++ if (lockf(lockfd, F_LOCK, 0) == -1) { ++ log_warn("lldpctl", "cannot get lock on %s", ctlname); ++ rc = -1; ++ close(lockfd); lockfd = -1; ++ goto end; ++ } ++ } ++ rc = best->execute(conn, w, &env, best->arg) != 1 ? -1 : rc; ++ if (needlock && lockf(lockfd, F_ULOCK, 0) == -1) { ++ log_warn("lldpctl", "cannot unlock %s", ctlname); ++ close(lockfd); lockfd = -1; ++ } ++ if (rc == -1) goto end; + } + env.argp++; + } +diff --git a/src/client/conf.c b/src/client/conf.c +index 1a14981..ba5743f 100644 +--- a/src/client/conf.c ++++ b/src/client/conf.c +@@ -37,8 +37,8 @@ register_commands_configure(struct cmd_node *root) + "unconfigure", + "Unconfigure system settings", + NULL, NULL, NULL); +- commands_privileged(configure); +- commands_privileged(unconfigure); ++ commands_privileged(commands_lock(configure)); ++ commands_privileged(commands_lock(unconfigure)); + cmd_restrict_ports(configure); + cmd_restrict_ports(unconfigure); + +-- +2.17.1.windows.2 + diff --git a/src/lldpd/patch/0005-Read-all-notifications-in-lldpctl_recv.patch b/src/lldpd/patch/0005-Read-all-notifications-in-lldpctl_recv.patch new file mode 100644 index 000000000000..1c3781da67ce --- /dev/null +++ b/src/lldpd/patch/0005-Read-all-notifications-in-lldpctl_recv.patch @@ -0,0 +1,27 @@ +From b8e66b52f40103fd3abea77031c4634742c31860 Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Thu, 12 Dec 2019 12:47:42 -0800 +Subject: [PATCH 1/1] Read all notifications in lldpctl_recv + +--- + src/lib/connection.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/lib/connection.c b/src/lib/connection.c +index 591d9e9..88bbc99 100644 +--- a/src/lib/connection.c ++++ b/src/lib/connection.c +@@ -253,8 +253,8 @@ lldpctl_recv(lldpctl_conn_t *conn, const uint8_t *data, size_t length) + memcpy(conn->input_buffer + conn->input_buffer_len, data, length); + conn->input_buffer_len += length; + +- /* Is it a notification? */ +- check_for_notification(conn); ++ /* Read all notifications */ ++ while(!check_for_notification(conn)); + + RESET_ERROR(conn); + +-- +2.17.1.windows.2 + diff --git a/src/lldpd/patch/0006-lib-fix-memory-leak.patch b/src/lldpd/patch/0006-lib-fix-memory-leak.patch new file mode 100644 index 000000000000..765b5fb751e7 --- /dev/null +++ b/src/lldpd/patch/0006-lib-fix-memory-leak.patch @@ -0,0 +1,24 @@ +From 833653dffb9be40110142af2a7cb4076a0dd24f5 Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Thu, 12 Dec 2019 12:48:47 -0800 +Subject: [PATCH 1/1] lib: fix memory leak + +--- + src/lib/connection.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/lib/connection.c b/src/lib/connection.c +index 88bbc99..aa88dad 100644 +--- a/src/lib/connection.c ++++ b/src/lib/connection.c +@@ -114,6 +114,7 @@ lldpctl_new_name(const char *ctlname, lldpctl_send_callback send, lldpctl_recv_c + } + if (!send && !recv) { + if ((data = malloc(sizeof(struct lldpctl_conn_sync_t))) == NULL) { ++ free(conn->ctlname); + free(conn); + return NULL; + } +-- +2.17.1.windows.2 + diff --git a/src/lldpd/patch/0007-lib-fix-memory-leak-when-handling-I-O.patch b/src/lldpd/patch/0007-lib-fix-memory-leak-when-handling-I-O.patch new file mode 100644 index 000000000000..cad8bf2fd48a --- /dev/null +++ b/src/lldpd/patch/0007-lib-fix-memory-leak-when-handling-I-O.patch @@ -0,0 +1,85 @@ +From f6086575e63b5e089814ca116aa637d7588bfcd3 Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Thu, 12 Dec 2019 13:52:42 -0800 +Subject: [PATCH 1/1] lib: fix memory leak when handling I/O. + +--- + src/lib/atom.c | 11 ++++++----- + src/lib/atom.h | 9 ++++----- + src/lib/atoms/port.c | 2 +- + 3 files changed, 11 insertions(+), 11 deletions(-) + +diff --git a/src/lib/atom.c b/src/lib/atom.c +index 955f434..f81d3bb 100644 +--- a/src/lib/atom.c ++++ b/src/lib/atom.c +@@ -322,10 +322,12 @@ _lldpctl_do_something(lldpctl_conn_t *conn, + return SET_ERROR(conn, LLDPCTL_ERR_SERIALIZATION); + conn->state = state_send; + if (state_data) +- conn->state_data = strdup(state_data); ++ strlcpy(conn->state_data, state_data, sizeof(conn->state_data)); ++ else ++ conn->state_data[0] = 0; + } + if (conn->state == state_send && +- (state_data == NULL || !strcmp(conn->state_data, state_data))) { ++ (state_data == NULL || !strncmp(conn->state_data, state_data, sizeof(conn->state_data)))) { + /* We need to send the currently built message */ + rc = lldpctl_send(conn); + if (rc < 0) +@@ -333,7 +335,7 @@ _lldpctl_do_something(lldpctl_conn_t *conn, + conn->state = state_recv; + } + if (conn->state == state_recv && +- (state_data == NULL || !strcmp(conn->state_data, state_data))) { ++ (state_data == NULL || !strncmp(conn->state_data, state_data, sizeof(conn->state_data)))) { + /* We need to receive the answer */ + while ((rc = ctl_msg_recv_unserialized(&conn->input_buffer, + &conn->input_buffer_len, +@@ -347,8 +349,7 @@ _lldpctl_do_something(lldpctl_conn_t *conn, + return SET_ERROR(conn, LLDPCTL_ERR_SERIALIZATION); + /* rc == 0 */ + conn->state = CONN_STATE_IDLE; +- free(conn->state_data); +- conn->state_data = NULL; ++ conn->state_data[0] = 0; + return 0; + } else + return SET_ERROR(conn, LLDPCTL_ERR_INVALID_STATE); +diff --git a/src/lib/atom.h b/src/lib/atom.h +index 265c0a7..ab7037d 100644 +--- a/src/lib/atom.h ++++ b/src/lib/atom.h +@@ -55,11 +55,10 @@ struct lldpctl_conn_t { + #define CONN_STATE_GET_DEFAULT_PORT_SEND 14 + #define CONN_STATE_GET_DEFAULT_PORT_RECV 15 + int state; /* Current state */ +- char *state_data; /* Data attached to the state. It is used to +- * check that we are using the same data as a +- * previous call until the state machine goes to +- * CONN_STATE_IDLE. */ +- ++ /* Data attached to the state. It is used to check that we are using the ++ * same data as a previous call until the state machine goes to ++ * CONN_STATE_IDLE. */ ++ char state_data[IFNAMSIZ + 64]; + /* Error handling */ + lldpctl_error_t error; /* Last error */ + +diff --git a/src/lib/atoms/port.c b/src/lib/atoms/port.c +index 545155c..d902188 100644 +--- a/src/lib/atoms/port.c ++++ b/src/lib/atoms/port.c +@@ -329,7 +329,7 @@ _lldpctl_atom_set_atom_port(lldpctl_atom_t *atom, lldpctl_key_t key, lldpctl_ato + struct lldpd_hardware *hardware = p->hardware; + struct lldpd_port_set set = {}; + int rc; +- char *canary; ++ char *canary = NULL; + + #ifdef ENABLE_DOT3 + struct _lldpctl_atom_dot3_power_t *dpow; +-- +2.17.1.windows.2 + diff --git a/src/lldpd/patch/series b/src/lldpd/patch/series index 5e5e8bc99714..626c5d59751b 100644 --- a/src/lldpd/patch/series +++ b/src/lldpd/patch/series @@ -2,3 +2,7 @@ 0001-return-error-when-port-does-not-exist.patch 0002-Let-linux-kernel-to-find-appropriate-nl_pid-automa.patch 0003-update-tx-interval-immediately.patch +0004-lldpctl-put-a-lock-around-some-commands-to-avoid-rac.patch +0005-Read-all-notifications-in-lldpctl_recv.patch +0006-lib-fix-memory-leak.patch +0007-lib-fix-memory-leak-when-handling-I-O.patch From fbcaaa498e2dd87fbeb9e519a0f706133e477e48 Mon Sep 17 00:00:00 2001 From: Mykola F <37578614+mykolaf@users.noreply.github.com> Date: Sat, 14 Dec 2019 00:30:52 +0200 Subject: [PATCH 16/66] [config engine] For l2 preset, use admin_status: up by default (#3902) Updated the l2 preset config generator to specify 'admin_status': 'up' for every port by default. The use of setdefault() ensures that if port already has some admin_status set, the original value will not be overwritten. Signed-off-by: Mykola Faryma --- src/sonic-config-engine/config_samples.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sonic-config-engine/config_samples.py b/src/sonic-config-engine/config_samples.py index adaea0c4532c..1b38276524c0 100644 --- a/src/sonic-config-engine/config_samples.py +++ b/src/sonic-config-engine/config_samples.py @@ -51,6 +51,7 @@ def generate_l2_config(data): data['VLAN']['Vlan1000'].setdefault('members', vp) data['VLAN_MEMBER'] = {} for port in natsorted(data['PORT'].keys()): + data['PORT'][port].setdefault('admin_status', 'up') data['VLAN_MEMBER']['Vlan1000|{}'.format(port)] = {'tagging_mode': 'untagged'} return data From e8f3bee0b4ef54cf3d903d94083dfc6a224a8ff5 Mon Sep 17 00:00:00 2001 From: Wataru Ishida <5915117+ishidawataru@users.noreply.github.com> Date: Fri, 13 Dec 2019 14:41:00 -0800 Subject: [PATCH 17/66] [broadcom]: fix KNET MTU setting with Linux Kernel > 4.10.0 (#3895) We need to set min_mtu/max_mtu properly to support MTU setting https://github.com/torvalds/linux/commit/61e84623 Signed-off-by: Wataru Ishida --- .../systems/linux/kernel/modules/bcm-knet/bcm-knet.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c index 6767090ec7bb..3559ace7a898 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c @@ -5128,6 +5128,10 @@ bkn_init_ndev(u8 *mac, char *name) if (dev->mtu == 0) { dev->mtu = rx_buffer_size; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)) + dev->min_mtu = 68; + dev->max_mtu = rx_buffer_size; +#endif /* Device vectors */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) From eefa8455d73c35b41bd43d4b988b74f5c474581d Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Fri, 13 Dec 2019 19:26:39 -0800 Subject: [PATCH 18/66] [hostcfgd] avoid in place editing config file contents (#3904) In place editing (sed -i) seems having some issues with filesystem interaction. It could leave 0 size file or corrupted file behind. It would be safer to sed the file contents into a new file and switch new file with the old file. Signed-off-by: Ying Xie --- files/image_config/hostcfgd/hostcfgd | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 7fa8ed2ba205..e10288c0dd37 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -176,6 +176,11 @@ class AaaCfg(object): if modify_conf: self.modify_conf_file() + def modify_single_file(self, filename, operations=None): + if operations: + cmd = "sed -e {0} {1} > {1}.new; mv -f {1} {1}.old; mv -f {1}.new {1}".format(' -e '.join(operations), filename) + os.system(cmd) + def modify_conf_file(self): auth = self.auth_default.copy() auth.update(self.auth) @@ -201,19 +206,19 @@ class AaaCfg(object): # Modify common-auth include file in /etc/pam.d/login and sshd if os.path.isfile(PAM_AUTH_CONF): - os.system("sed -i -e '/^@include/s/common-auth$/common-auth-sonic/' /etc/pam.d/sshd") - os.system("sed -i -e '/^@include/s/common-auth$/common-auth-sonic/' /etc/pam.d/login") + self.modify_single_file('/etc/pam.d/sshd', [ "'/^@include/s/common-auth$/common-auth-sonic/'" ]) + self.modify_single_file('/etc/pam.d/login', [ "'/^@include/s/common-auth$/common-auth-sonic/'" ]) else: - os.system("sed -i -e '/^@include/s/common-auth-sonic$/common-auth/' /etc/pam.d/sshd") - os.system("sed -i -e '/^@include/s/common-auth-sonic$/common-auth/' /etc/pam.d/login") + self.modify_single_file('/etc/pam.d/sshd', [ "'/^@include/s/common-auth-sonic$/common-auth/'" ]) + self.modify_single_file('/etc/pam.d/login', [ "'/^@include/s/common-auth-sonic$/common-auth/'" ]) # Add tacplus in nsswitch.conf if TACACS+ enable if 'tacacs+' in auth['login']: if os.path.isfile(NSS_CONF): - os.system("sed -i -e '/tacplus/b' -e '/^passwd/s/compat/tacplus &/' /etc/nsswitch.conf") + self.modify_single_file(NSS_CONF, [ "'/tacplus/b'", "'/^passwd/s/compat/tacplus &/'"]) else: if os.path.isfile(NSS_CONF): - os.system("sed -i -e '/^passwd/s/tacplus //' /etc/nsswitch.conf") + self.modify_single_file(NSS_CONF, [ "'/^passwd/s/tacplus //'" ]) # Set tacacs+ server in nss-tacplus conf template_file = os.path.abspath(NSS_TACPLUS_CONF_TEMPLATE) From 80bb7fd15a92d7f0153869854d43f9590a191572 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Sun, 15 Dec 2019 01:41:48 +0800 Subject: [PATCH 19/66] [process-reboot-cause]Address the issue: Incorrect reboot cause returned when warm reboot follows a hardware caused reboot (#3880) * [process-reboot-cause]Address the issue: Incorrect reboot cause returned when warm reboot follows a hardware caused reboot 1. check whether /proc/cmdline indicates warm/fast reboot. if yes the software reboot cause file will be treated as the reboot cause. finish 2. check whether platform api returns a reboot cause. if yes it is treated as the reboot cause. finish. 3. check whether /hosts/reboot-cause contains a cause. if yes it is treated as the cause otherwise return unknown. * [process-reboot-cause]Fix review comments * [process-reboot-cause]address comments 1. use "with" statement 2. update fast/warm reboot BOOT_ARG * [process-reboot-cause]address comments * refactor the code flow * Remove escape * Remove extra ':' --- .../process-reboot-cause/process-reboot-cause | 114 +++++++++++------- 1 file changed, 73 insertions(+), 41 deletions(-) diff --git a/files/image_config/process-reboot-cause/process-reboot-cause b/files/image_config/process-reboot-cause/process-reboot-cause index 49cfa752641f..e5d228b4c6b6 100755 --- a/files/image_config/process-reboot-cause/process-reboot-cause +++ b/files/image_config/process-reboot-cause/process-reboot-cause @@ -11,6 +11,7 @@ try: import pwd import sys import syslog + import re except ImportError as err: raise ImportError("%s - required module not found" % str(err)) @@ -22,6 +23,16 @@ REBOOT_CAUSE_DIR = "/host/reboot-cause/" REBOOT_CAUSE_FILE = REBOOT_CAUSE_DIR + "reboot-cause.txt" PREVIOUS_REBOOT_CAUSE_FILE = REBOOT_CAUSE_DIR + "previous-reboot-cause.txt" FIRST_BOOT_PLATFORM_FILE = "/tmp/notify_firstboot_to_platform" +REBOOT_TYPE_KEXEC_FILE = "/proc/cmdline" +# The following SONIC_BOOT_TYPEs come from the warm/fast reboot script which is in sonic-utilities +# Because the system can be rebooted from some old versions, we have to take all possible BOOT options into consideration. +# On 201803, 201807 we have +# BOOT_OPTIONS="$(echo $KERNEL_OPTIONS | sed -e 's/\s*linux\s*/BOOT_IMAGE=/') fast-reboot" +# On 201811 and later we have +# BOOT_OPTIONS="$(echo $KERNEL_OPTIONS | sed -e 's/\s*linux\s*/BOOT_IMAGE=/') SONIC_BOOT_TYPE=${BOOT_TYPE_ARG}" where BOOT_TYPE_ARG can be warm, fastfast or fast +# To extract the commom part of them, we should have the following PATTERN +REBOOT_TYPE_KEXEC_PATTERN_WARM = ".*SONIC_BOOT_TYPE=(warm|fastfast).*" +REBOOT_TYPE_KEXEC_PATTERN_FAST = ".*SONIC_BOOT_TYPE=(fast|fast-reboot).*" UNKNOWN_REBOOT_CAUSE = "Unknown" @@ -47,7 +58,32 @@ def log_error(msg): # ============================= Functions ============================= - +def parse_warmfast_reboot_from_proc_cmdline(): + if os.path.isfile(REBOOT_TYPE_KEXEC_FILE): + with open(REBOOT_TYPE_KEXEC_FILE, "r") as cause_file: + cause_file_kexec = cause_file.readline() + m = re.match(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) + if m and m.group(1): + return 'fast-reboot' + return None + + +def find_software_reboot_cause(): + software_reboot_cause = UNKNOWN_REBOOT_CAUSE + + if os.path.isfile(REBOOT_CAUSE_FILE): + with open(REBOOT_CAUSE_FILE, "r") as cause_file: + software_reboot_cause = cause_file.readline().rstrip('\n') + + if os.path.isfile(FIRST_BOOT_PLATFORM_FILE): + os.remove(FIRST_BOOT_PLATFORM_FILE) + + return software_reboot_cause + + def main(): log_info("Starting up...") @@ -73,51 +109,48 @@ def main(): try: import sonic_platform - # Check if the previous reboot was caused by hardware - 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. + # 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): - cause_file = open(REBOOT_CAUSE_FILE, "r") - previous_reboot_cause = cause_file.readline().rstrip('\n') - cause_file.close() - # If it is FirstTime Boot and previous_reboot_cause is unknown - # and hardware_reboot cause is non_hardware then - # Update the reboot cause as required - if os.path.isfile(FIRST_BOOT_PLATFORM_FILE): - if (previous_reboot_cause == UNKNOWN_REBOOT_CAUSE): - previous_reboot_cause = UNKNOWN_REBOOT_CAUSE - os.remove(FIRST_BOOT_PLATFORM_FILE) - elif hardware_reboot_cause == chassis.REBOOT_CAUSE_HARDWARE_OTHER: - previous_reboot_cause = "{} ({})".format(hardware_reboot_cause, optional_details) + 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: - previous_reboot_cause = hardware_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 + 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. - if os.path.isfile(REBOOT_CAUSE_FILE): - cause_file = open(REBOOT_CAUSE_FILE, "r") - previous_reboot_cause = cause_file.readline().rstrip('\n') - cause_file.close() - - # If it is FirstTime Boot and previous_reboot_cause is unknown - # Update the reboot cause as required - if os.path.isfile(FIRST_BOOT_PLATFORM_FILE): - if (previous_reboot_cause == UNKNOWN_REBOOT_CAUSE): - previous_reboot_cause = UNKNOWN_REBOOT_CAUSE - os.remove(FIRST_BOOT_PLATFORM_FILE) + previous_reboot_cause = find_software_reboot_cause() + # Write the previous reboot cause to PREVIOUS_REBOOT_CAUSE_FILE - prev_cause_file = open(PREVIOUS_REBOOT_CAUSE_FILE, "w") - prev_cause_file.write(previous_reboot_cause) - prev_cause_file.close() + with open(PREVIOUS_REBOOT_CAUSE_FILE, "w") as prev_cause_file: + prev_cause_file.write(previous_reboot_cause) # Also log the previous reboot cause to the syslog log_info("Previous reboot cause: {}".format(previous_reboot_cause)) @@ -127,9 +160,8 @@ def main(): os.remove(REBOOT_CAUSE_FILE) # Write a new default reboot cause file for the next reboot - cause_file = open(REBOOT_CAUSE_FILE, "w") - cause_file.write(UNKNOWN_REBOOT_CAUSE) - cause_file.close() + with open(REBOOT_CAUSE_FILE, "w") as cause_file: + cause_file.write(UNKNOWN_REBOOT_CAUSE) if __name__ == "__main__": From 3ab4b71656e8cd300aab69e897de6fa7e8103e3d Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Sun, 15 Dec 2019 16:48:48 -0800 Subject: [PATCH 20/66] Corefile uploader service (#3887) * Corefile uploader service 1) A service is added to watch /var/core and upload to Azure storage 2) The service is disabled on boot. One may enable explicitly. 3) The .rc file to be updated with acct credentials and http proxy to use. 4) If service is enabled with no credentials, it would sleep, with periodic log messages 5) For any update in .rc, the service has to be restarted to take effect. * Remove rw permission for .rc file for group & others. * Changes per review comments. Re-ordered .rc file per JSON.dump order. Added a script to enable partial update of .rc, which HWProxy would use to add acct key. * Azure storage upload requires python module futures, hence added it to install list. * Removed trailing spaces. * A mistake in name corrected. Copy the .rc updater script to /usr/bin. --- .../build_templates/sonic_debian_extension.j2 | 13 + .../corefile_uploader/core_analyzer.rc.json | 17 ++ .../corefile_uploader/core_uploader.py | 276 ++++++++++++++++++ .../corefile_uploader/core_uploader.service | 11 + .../corefile_uploader/update_json.py | 55 ++++ 5 files changed, 372 insertions(+) create mode 100644 files/image_config/corefile_uploader/core_analyzer.rc.json create mode 100755 files/image_config/corefile_uploader/core_uploader.py create mode 100644 files/image_config/corefile_uploader/core_uploader.service create mode 100755 files/image_config/corefile_uploader/update_json.py diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 4e81593298f6..b11325e86835 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -36,6 +36,8 @@ FILESYSTEM_ROOT_USR="$FILESYSTEM_ROOT/usr" FILESYSTEM_ROOT_USR_SHARE="$FILESYSTEM_ROOT_USR/share" FILESYSTEM_ROOT_USR_SHARE_SONIC="$FILESYSTEM_ROOT_USR_SHARE/sonic" FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES="$FILESYSTEM_ROOT_USR_SHARE_SONIC/templates" +FILESYSTEM_ROOT_ETC="$FILESYSTEM_ROOT/etc" +FILESYSTEM_ROOT_ETC_SONIC="$FILESYSTEM_ROOT_ETC/sonic" GENERATED_SERVICE_FILE="$FILESYSTEM_ROOT/etc/sonic/generated_services.conf" @@ -219,6 +221,17 @@ echo "hostcfgd.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/hostcfgd/hostcfgd $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/hostcfgd/*.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ +# copy core file uploader files +sudo cp $IMAGE_CONFIGS/corefile_uploader/core_uploader.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo 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/update_json.py $FILESYSTEM_ROOT/usr/bin/ +sudo cp $IMAGE_CONFIGS/corefile_uploader/core_analyzer.rc.json $FILESYSTEM_ROOT_ETC_SONIC/ +sudo chmod og-rw $FILESYSTEM_ROOT_ETC_SONIC/core_analyzer.rc.json +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install azure-storage +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install watchdog +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install futures + # Copy the buffer configuration template sudo cp $BUILD_TEMPLATES/buffers_config.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ diff --git a/files/image_config/corefile_uploader/core_analyzer.rc.json b/files/image_config/corefile_uploader/core_analyzer.rc.json new file mode 100644 index 000000000000..3ffa33fd1e1d --- /dev/null +++ b/files/image_config/corefile_uploader/core_analyzer.rc.json @@ -0,0 +1,17 @@ +{ + "local_work": { + "core_upload": "/tmp/core_upload/" + }, + "azure_sonic_core_storage": { + "account_name": "corefilecollection", + "account_key": "", + "share_name": "corefiles-root" + }, + "metadata_files_in_archive": { + "version": "/etc/sonic/sonic_version.yml", + "core_info": "core_info.json" + }, + "env": { + "https_proxy": "" + } +} diff --git a/files/image_config/corefile_uploader/core_uploader.py b/files/image_config/corefile_uploader/core_uploader.py new file mode 100755 index 000000000000..676ff9583b06 --- /dev/null +++ b/files/image_config/corefile_uploader/core_uploader.py @@ -0,0 +1,276 @@ +#!/usr/bin/env python + +import os +import time +import tarfile +import socket +import yaml +import json +import syslog +from watchdog.observers import Observer +from watchdog.events import FileSystemEventHandler +from azure.storage.file import FileService + +global CORE_FILE_PATH, RC_FILE +global hostname, sonicversion, asicname, acctname, acctkey, sharename, cwd +global INIT_CWD +global log_level +global this_file + +this_file = os.path.basename(__file__) + +global cfg +cfg = "" + +CORE_FILE_PATH = "/var/core/" +RC_FILE = "/etc/sonic/core_analyzer.rc.json" +INIT_CWD = "/tmp" + +hostname = "" +sonicversion = "" +asicname = "" +acctname = "" +acctkey = "" +sharename = "" +cwd = [] + +HOURS_4 = (4 * 60 * 60) +PAUSE_ON_FAIL = (60 * 60) +MAX_RETRIES = 5 + +log_level = syslog.LOG_DEBUG + +def log_msg(lvl, fname, m): + if (lvl <= log_level): + syslog.syslog(lvl, "{}: {}".format(fname, m)) + + if log_level == syslog.LOG_DEBUG: + print("{}: {}".format(fname, m)) + +def log_err(m): + log_msg(syslog.LOG_ERR, this_file, m) + +def log_info(m): + log_msg(syslog.LOG_INFO, this_file, m) + +def log_warn(m): + log_msg(syslog.LOG_WARNING, this_file, m) + +def log_debug(m): + log_msg(syslog.LOG_DEBUG, this_file, m) + + +def make_new_dir(p): + os.system("rm -rf " + p) + os.system("mkdir -p " + p) + +def parse_a_json(data, prefix, val): + for i in data: + if type(data[i]) == dict: + parse_a_json(data[i], prefix + (i,), val) + else: + val[prefix + (i,)] = data[i] + +class config: + parsed_data = {} + cfg_data = {} + + def __init__(self): + while not os.path.exists(RC_FILE): + # Wait here until service restart + log_err("Unable to retrieve Azure storage credentials") + time.sleep (HOURS_4) + + with open(RC_FILE, 'r') as f: + self.parsed_data = json.load(f) + parse_a_json(self.parsed_data, (), self.cfg_data) + + def get_data(self, k): + return self.cfg_data[k] if self.cfg_data.has_key(k) else "" + + def get_dict(self): + return self.parsed_data + + def get_core_info(self, corepath, devicename): + info = {} + info["corefname"] = os.path.basename(corepath) + info["tstamp"] = str(os.stat(corepath).st_ctime) + info["devicename"] = devicename + + lpath = self.get_data(("metadata_files_in_archive", "core_info")) + f = open(lpath, "w+") + f.write(json.dumps(info, indent=4)) + f.close() + + return lpath + + +class Watcher: + + def __init__(self): + self.observer = Observer() + + def run(self): + event_handler = Handler() + self.observer.schedule(event_handler, CORE_FILE_PATH) + self.observer.start() + try: + while True: + time.sleep(5) + except: + self.observer.stop() + log_err("Error in watcher") + + self.observer.join() + +def set_env(lst): + for k in lst: + if lst[k]: + os.environ[k] = lst[k] + log_debug("set env {} = {}".format(k, lst[k])) + +class Handler(FileSystemEventHandler): + + @staticmethod + def init(): + global hostname, sonicversion, asicname, acctname, acctkey, sharename + global cwd, cfg + + cfg = config() + + set_env(cfg.get_dict()["env"]) + + hostname = socket.gethostname() + if not hostname: + raise Exception("Failed to read hostname") + + acctname = cfg.get_data(("azure_sonic_core_storage", "account_name")) + acctkey = cfg.get_data(("azure_sonic_core_storage", "account_key")) + sharename = cfg.get_data(("azure_sonic_core_storage", "share_name")) + + if not acctname or not acctkey or not sharename: + while True: + # Wait here until service restart + log_err("Unable to retrieve Azure storage credentials") + time.sleep (HOURS_4) + + with open("/etc/sonic/sonic_version.yml", 'r') as stream: + l = yaml.safe_load(stream) + sonicversion = l['build_version'] + asicname = l['asic_type'] + + if not sonicversion: + raise Exception("Failed to read build_version from /etc/sonic/sonic_version.yml") + + if not asicname: + raise Exception("Failed to read asic_type from /etc/sonic/sonic_version.yml") + + cwd = cfg.get_data(("local_work", "core_upload")).split("/") + if not len(cwd) > 2: + raise Exception("Invalid path for core_upload. Expect a min of two elements in path") + + os.chdir(INIT_CWD) + + @staticmethod + def on_any_event(event): + if event.is_directory: + return None + + elif event.event_type == 'created': + # Take any action here when a file is first created. + log_debug("Received create event - " + event.src_path) + Handler.handle_file(event.src_path) + + + @staticmethod + def wait_for_file_write_complete(path): + ct_size = -1 + + while ct_size != os.path.getsize(path): + ct_size = os.path.getsize(path) + time.sleep(2) + + time.sleep(2) + if ct_size != os.path.getsize(path): + raise Exception("Dump file creation is too slow: " + path) + + log_debug("File write complete - " + path) + + + @staticmethod + def handle_file(path): + + Handler.wait_for_file_write_complete(path) + + lpath = "/".join(cwd) + make_new_dir(lpath) + os.chdir(lpath) + + # Create a new archive with core & more. + metafiles = cfg.get_dict()["metadata_files_in_archive"] + + fname = os.path.basename(path) + tarf_name = fname + ".tar.gz" + + cfg.get_core_info(path, hostname) + + tar = tarfile.open(tarf_name, "w:gz") + for e in metafiles: + tar.add(metafiles[e]) + tar.add(path) + tar.close() + log_debug("Tar file for upload created: " + tarf_name) + + Handler.upload_file(tarf_name, tarf_name) + + log_debug("File uploaded - " + path) + os.chdir(INIT_CWD) + + @staticmethod + def upload_file(fname, fpath): + daemonname = fname.split(".")[0] + i = 0 + fail_msg = "" + + while i <= MAX_RETRIES: + try: + svc = FileService(account_name=acctname, account_key=acctkey) + + l = [sonicversion, asicname, daemonname, hostname] + e = [] + while len(e) != len(l): + e.append(l[len(e)]) + svc.create_directory(sharename, "/".join(e)) + + log_debug("Remote dir created: " + "/".join(e)) + + svc.create_file_from_path(sharename, "/".join(l), fname, fpath) + log_debug("Remote file created: name{} path{}".format(fname, fpath)) + break + + except Exception as e: + log_err("core uploader failed: Failed during upload (" + str(e) +")") + fail_msg = str(e) + i += 1 + if i >= MAX_RETRIES: + raise Exception("Failed while uploading. msg(" + fail_msg + ") after " + str(i) + " retries") + time.sleep(PAUSE_ON_FAIL) + + + @staticmethod + def scan(): + for e in os.listdir(CORE_FILE_PATH): + fl = CORE_FILE_PATH + e + if os.path.isfile(fl): + Handler.handle_file(fl) + + +if __name__ == '__main__': + try: + Handler.init() + w = Watcher() + Handler.scan() + w.run() + except Exception as e: + log_err("core uploader failed: " + str(e) + " Exiting ...") + diff --git a/files/image_config/corefile_uploader/core_uploader.service b/files/image_config/corefile_uploader/core_uploader.service new file mode 100644 index 000000000000..5c061e72a16e --- /dev/null +++ b/files/image_config/corefile_uploader/core_uploader.service @@ -0,0 +1,11 @@ +[Unit] +Description=Host core file uploader daemon +Requires=updategraph.service +After=updategraph.service + +[Service] +Type=simple +ExecStart=/usr/bin/core_uploader.py + +[Install] +WantedBy=multi-user.target diff --git a/files/image_config/corefile_uploader/update_json.py b/files/image_config/corefile_uploader/update_json.py new file mode 100755 index 000000000000..03bb39aa4ec8 --- /dev/null +++ b/files/image_config/corefile_uploader/update_json.py @@ -0,0 +1,55 @@ +#! /usr/bin/env python + +import os +import sys +import json +import argparse + +TMP_SUFFIX = ".tmp" +BAK_SUFFIX = ".bak" + +def dict_update(dst, patch): + for k in patch.keys(): + if type(patch[k]) == dict: + dst[k] = dict_update(dst[k], patch[k]) + else: + dst[k] = patch[k] + return dst + +def do_update(rcf, patchf): + dst = {} + patch = {} + + tmpf = rcf + TMP_SUFFIX + bakf = rcf + BAK_SUFFIX + + with open(rcf, "r") as f: + dst = json.load(f) + + with open(patchf, "r") as f: + patch = json.load(f) + + dst = dict_update(dst, patch) + + with open(tmpf, "w") as f: + json.dump(dst, f, indent = 4) + + os.rename(rcf, bakf) + os.rename(tmpf, rcf) + + +def main(): + parser=argparse.ArgumentParser(description="Update JSON based file") + parser.add_argument("-r", "--rc", help="JSON file to be updated") + parser.add_argument("-p", "--patch", help="JSON file holding patch") + args = parser.parse_args() + + if not args.rc or not args.patch: + raise Exception("check usage") + + do_update(args.rc, args.patch) + +if __name__ == '__main__': + main() + + From 1286e5ed3fada79fd81526f91ab079ea254756b8 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Mon, 16 Dec 2019 22:30:35 +0700 Subject: [PATCH 21/66] [platform/cel]: Remove afulnx_64 (#3900) remove afulnx_64 install script --- .../sonic_platform/component.py | 4 ++-- .../sonic_platform/component.py | 4 ++-- .../debian/platform-modules-dx010.install | 1 - .../debian/platform-modules-haliburton.install | 1 - .../sonic-platform-modules-cel/tools/afulnx_64 | Bin 828912 -> 0 bytes 5 files changed, 4 insertions(+), 6 deletions(-) delete mode 100755 platform/broadcom/sonic-platform-modules-cel/tools/afulnx_64 diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py index ad6810b14c38..fe34bc45c670 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py @@ -140,7 +140,7 @@ def install_firmware(self, image_path): new_image_path = os.path.join("/tmp", (root.lower() + ext)) shutil.copy(image_path, new_image_path) install_command = "ispvm %s" % new_image_path - elif self.name == "BIOS": - install_command = "afulnx_64 %s /p /b /n /x /r" % image_path + # elif self.name == "BIOS": + # install_command = "afulnx_64 %s /p /b /n /x /r" % image_path return self.__run_command(install_command) diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py index 67c7a9c46341..d94a93474452 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py @@ -141,7 +141,7 @@ def install_firmware(self, image_path): new_image_path = os.path.join("/tmp", (root.lower() + ext)) shutil.copy(image_path, new_image_path) install_command = "ispvm %s" % new_image_path - elif self.name == "BIOS": - install_command = "afulnx_64 %s /p /b /n /x /r" % image_path + # elif self.name == "BIOS": + # install_command = "afulnx_64 %s /p /b /n /x /r" % image_path return self.__run_command(install_command) diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install index 2ab53302a9bf..8570fa1eae84 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install @@ -3,4 +3,3 @@ dx010/cfg/dx010-modules.conf etc/modules-load.d dx010/systemd/platform-modules-dx010.service lib/systemd/system dx010/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_seastone-r0 services/platform_api/platform_api_mgnt.sh usr/local/bin -tools/afulnx_64 usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install index d50306304cd5..df78b7a34ea4 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install @@ -5,4 +5,3 @@ services/fancontrol/fancontrol.service lib/systemd/system services/fancontrol/fancontrol usr/local/bin haliburton/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_e1031-r0 services/platform_api/platform_api_mgnt.sh usr/local/bin -tools/afulnx_64 usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/afulnx_64 b/platform/broadcom/sonic-platform-modules-cel/tools/afulnx_64 deleted file mode 100755 index c32823393c0805484f1a5ef37375c0ca3384a72b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 828912 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 zⅅ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%0AW?1 zn}rz5l+^tY3q<|vNaF$1rKr#K_-Wkn3f?qi0G9#g$l(qI zTlQ}z;c-kb$nLkFM|n+S-%WWHS56& z>En;;>SzEt^)z9N67&N}N^t(`xzIUMU&0=ji`hsd*C-!>(}h&p)!o19T7IaTbJR*P`=V81Lr4%HcO(e{VG=to zkCg(%5ye<4DF6rjv%s2ng7GP0Yb3rhvfW%|fi~%&sewHBd$hr+5`(3K>8|p!eF-DN z&;I=&a2~?F*fC#SZO~c)c4G$EH3Sna0SZm78H@WoL#p8MNZd!=Ud_YdHlG$?hiB3bx*JJcHJiw z_GZGmy6$?wc9F@kE+*M#>rl{jKOfvl*L_Hg-oV1fCjCwoE~aU%6>Ds`6t}HM8`xg_ zA3|d=kRnjh9(@w+G?!iUp0xHk?BBy(Gtw$IBv>sh(?B=yc!Kzbbr#yutXQzmB%kMb@X62`y9*3)0H{l_AW7mkDn@RM4>mmZ^xt+R*qbSB) zrqGR8IbB4rzo%Wq=uYI;@Q8}nBe&#L>N&RC)$trtzLx%X0Djzk>gp?u=h!gFdX5na z*^58wIVu3undi8uq064*kt@?S49_tQHFn}TCZWjj9C!X(IKK)%ZqM;TEj-8Wa0%`~ z|6+wbmas0*aXVn0-j-|JOh+c&Tuf$oj>Wrl(Q_0$q;}9X&#{WoS)OB%n69s6_9Sg} z%f`Degg$V72n&9M=NL`pWqOWaY>s%loP+b_m)KF;8T)0BmkkaMMr&j{J043EzvyA| zrBNSZR0;aB*hH{sLX`b;vBk-?Q-LR5=*+vs9#r9N!@Ep1V4hx*sz|&>E^@n=y}Cv@ zKa=wR*2O$TDMOoVh~p8Wd+2DB5KGEoGxv#ZAla-5#KQNt?P7-fR%PrFo^>$`3LO{o z?HAHf-@=c(^X(ipE+z_44NhKF$S3%tF6Q4g?4hPz8No@5<;xv(`n7ZZ7ae0ABy ztk1>Pk9RS`nl zG(W_T`T7qMR)VpGY()LokdN7cA$XXVyj9xO=Tfcrcyfp*w(>ix(Tl&m+}n#MDC{u8 zx&noZ0lQ5`-(zd656)mzIm0yL`u?}pugS}A1%JK?XB z5*jGB=c`O*MgcFg0P_aH$}L&bIY)1eTX0VbI6OfFW+%@$91RLQ?o%o-Kg4%}$&@d3 zI<@u3x~N2hp~wp(}nU%6VwkfC}@)cP?u_`R9Uf#;#h`^qag-! zBD}{ZutpqjS`S{tO_0W0;mup{P+ot8Mf{K)>Kl^O)gK|;mN@hd55(JmC`vvjH2i&F zKrQVMFGz_D5`RW-YxJ*2RcK?sMt>WwlN#yF@~84_<&~_wo(Em1qDnr@R8&ND zQ75fLJNmot!O}5zS#{N|rXb>MiBZbFQkJch$8c`Sst;h*MDXY*65roRu!~TTDl*@o zn1&T7E1DBjV6u0DC)6MqOu?F%K$LG-5|+n!PZZadQ)tn!hOeZz^Tk@5 zW$$Iwn!$Ix-0*LI!vVAdvL_kyEM6YKZEq;OR85Wv@f8EWOk(JKupEb%7JCu2KwG$g zW%8^ojLkmIwRjQpoFJwb>p_b~rE-!nXmB~kw@i*$saI!!@r{XisY-XBUeDTj-xwYs zCW)2K*`La>vjoMkCsdq@;ARuNLBS^c@{iZ8a;4YpuIqKK>kij7v-|ubZoqZDK_AQW zjpmx~R22#guXdKJNRzWrAcC@=XCTBN2X;4w#WS&W)(3Y@{)0>KUu%6wsAf`q$FN`n zKQd6?(Ki_T3KuFLw3IC*hWysIcHJh>89_{R9~l{_`)(7RB2%>WW0 zoCYt=$-#yw39;$?7Oq0X;Tp68EbZtcbZvbCNMr`YXEZ0@0jeVyS)2is{MNVTJAyIK z(3o!S1`-a>3f&DfxI5==;3*jmd?PZvEfViA4TObz8koY{^bXHIzIDIB0zZ#C6U&MA z1}PeS@N$B@Yp+(ckx-q2j|u^sEyr+26fA)W?tPSZ3#` zFyhTJBARvwm(CMrr^TB|n77vMNhaRBn8d7*VAid2-!l@2qdFeLe>r}Y>9)EjP{u#| z#3j@IkDki zSU^tfHwhDMI&&lCc(X=H>VeV)!KHQNiLWJK{LU;j9K$eZhjico;U#t~&^5oXj4y${ z&@8@sJ}wd2z4Sg8m}`2-pqz(ul&7S%$F0pthe+>TXa0T?`0r{2W)^4|o zx%XY;F9N4|!e(k;=>!V*<+vqz*Q{_^+leri~9HTBC!{1 zwx7fAUF6k&j%^-z){W14nwNL$KgYm=hxq~+mk(pqf1V%zVr6o>_>0b~zVR;r0<`W5 z!P{=Q?O~|!K99v(lQM(grDVA;pN$YDv|)o1j~d3=p)*5MB2ANV*g(^i&}2g6l;4_A zn1QH%G^nN9XRerj6gn0feLAAU)BW7YiH)Oh2=SHT^3=)f286^(7!46k3CYrUGb;!2 zat&}wVcGfmWJ>x;cQOdBD$$z*yue{6=(XK=ew>_uSURUU02tm^NyFweZ|}nCNt|$F zAl?&WO#Za^;rWD=6f7`%8qA9gW-oJpk-6_}?k_a=ea!s@=Dx4FKi}L3agP=aGQlS_ z-dtcFiKq`{lY_rpW!e|<7vi2_WRX$A>Sp>V*h*U+(-u8wW4w*D)fKYC$UVOJ=-#eW zM87tBHSO_*@l#IZF?iM6QLQ-Ai?&%w+pM5%mQRM7+*^OJX%Ue6As3Fh{PToesJjwd z2!p{T8^{N*`{J+@=cW&C5HDy+Z``!on_jpPvnNi^;F1nouzhgJCVL%l5SE6!;@1ed_tTJ~jQ z?7VYPBZLI+LrRQyl*aO z!Q&Os>%!&n*N1!$f0A)lfPPbLD=^zPb{~@G0}clrphz^K87`p$s^>xVjS7$~6E3mo zP@9n0Rce%ZKzT%cR=Jrs$-WdzV<>1S8{Iq<3?{;Qn63t3X|m8mh9$a$*%MUiabMhXHlS;vJ1xk1D=%eBPFoX$R7@K*4tMR9ED6cJ~jo7cv zNs1TlCEqoO!%+febZg_x5HvcO^W-T^tkm!bjRyH>%y`T|&~HBY279`j%0eaTQtpF9 zT6_roQ6}SlV#xKVp8&QG>f@c+5s|mRAUbkO6x(t9>wFkQ;Ymtbo&XUC|7M6nx=IRT z;#{d3Y8knlkp)H(uy6^Q&-_mjpX2_Y*RjPjLq!CsA?c_?+V@Wv=>r|oCZ2*)*lzb| z^Avma?9~+6&n>z~c+eSy3%Qznd5POQhry~>l&{Bfit<%7!z;?zmQXHHPJ}6_D39($ zlp)$3MVXdgKO@yUP`M%(m?zis33?FvRkqx&q>UQ6nNfOy^fsI%#ZkH(quOK+(qRUW z-a&dk05ygzcMZn8b_QeKID;{7oWYnk&S1A z#2VoU(xu?16p+~ZtV0z1Gp9Zw{Bl->OHQYF8EL}8Bd$fa%ZmW#%!2?ml8AhUYYwgU z+NQ1&HUCPtiunUZ9m!WvHD+cdf03CPzJWfI5@E~@u~g8ph*+x3GD8SmBYCF`jZQ=+ zI+2JhBOr64Gups9N|#Wyfp&Y-(;c0`2%P8)MzBeN)Cf!^Fajq$YYdP_37{yI_=TZT z4a-hvST=<-pvj>^T5$oi5Wu8iLOeMkzOkj;?Q8CY8AO^8+JS`3^c)9QfS!T~fr>z+ z#2;U9&Z+ou!YbmJu*vQ!_*9>e6cknC9wXLX%bsn<5TJ^>f(`!y z0fH^yFHG{c2CR_i0OK$ATfgK1L;QqgQj5G=O(4dD8-QcBmZ)?m(mvV``!AiXB$eZnBMj4#=q)c%JX8=>@z2^&1PgASF+t zQ`1jQP?$dQq`d&t2BZwaKY2r&)QY=J3xsXO_snuv99$9j!d85Q;Tp2501(I)%39Nj zk@&~sPab~~y%=Y33q|nHW9bX(dZrma@msM095+qaud$^p9>bo}Ev^V9L% zO_(_YEf`seF0^tZx>0N)irZpO;9v0PYl|($75~~|%gj}z>6uns=J1t?3-B!m>)v}c z3YFw>>IaKo6+bw-Q5xC!JR28jl%_@+rTLM@7=>Y?tmQZsKe?m$!x)7F{}zNxgSWD` z92qyJZ#g!?FWOS$8SSm{jrP`fM|-RO(cY zPgxc}n={z0xXN!Q;5=uKtGon;VrbY-l30u{W}9cr>!6F4@l>m|zn5WUaZyhF^HdRh z;tG_jWk97+<*G(0hZ}_{UQJgeDy)B=iUfQe={1VNBTcFmc&o-+RWtgWgp86jhvcU_ z5c7knv5fX&D`IH+m&}T4d#gF2HeYJ5L>USA;<4v|ml~8fz88c%Fbd!l|REOov^NA^-HlHH$+K+oB58eP)(spHRpUz+_XO_r`H!f*_R zk1Jn|yg?LpX7}AOb@0`SLq2)XZP>=m^tjtD!^vs0KXsW8kG%4PMR% zJM^1xI3DQID^1)gufKDwAm4ErN5UMB@JeL*0Z!nS;b(#8QFqccdAsl&B<65iVMxp= z-=4RX&TUWLRynu5cw6n<_U3J^bBixuXy({?(w9$|+;W}-#kpWy;jc}3wW1SHdm2o0 z4(E-bm!TXU5^AdhmQctD<;p@cIUi4~##_18O_`+5yO=B@TDx|wc&T1;hCee#sqN*G zd30$rE$q^(IKrZdw4iFoa_*9Z475R4Wdb%{I}to@oCuybP6W>zCxYjVjo^80BY0j1 zOoWG%*wYa_Z)^k~(R3Oe#(x*YpI%Fsgk(OYj%X15LDhy&m?L4m{NFIQ7N4lZOnXNV z1FA-z1_Nzbs)#oTBFp<*R1?viiEa!CG2Lnkv=RnOfmTtVRb~&%N@U?lK_CvZ5Xr$Z zBnWJ4|CaByexW0c$-%7k@N+0%=22ANr6Dl+c`i-LqOt#g09q^X=E|4e)!1#d=QcbtRVR4tnk(9+iaKZc64#@jSNx+c3k zm%N7IQ$1*!ez)f{;l#A>r%^8#6;|O>E(QI^?j4NX^W#V&>cF^zhR4?rNA?awD}5PE#8Gwfd^~I9+h{CG-AIR-aV9|IQooi8K%nkPAbD*-5|5OxnXKVB_<_p zb+3Q{{-vbL;Gu{UK+P=4z{(HVFI-^3y&$FEVq-76b2?b9=dP#OpK8>PAf2sr#hAKl zfy)ILo>(Pb{v9mSvLewy?k{6#;}9noX$ya|IK3$vo(v?C4>*iMLj@^Wj=|=G)_x4H zi?BLYV4Oof|9}Gz!f$cunDK|>cjOUe z6DC3gB{aX?wx}?0b`D!JA3ym;!IllY?G1rkep$zsF)u`WNiizgEj88%r3T`%aW55Ezd9_Z1(Y%hLGQyRB=(bH_7hb#?gHMLm`Kj3 z3bHLGIA0b`f2gN7duLqSBS`CKa9}{XRa7?Op@+03F5AOwF`#EjAL}s{{8?p|zM$LF zcP7tmzIEScx~BEgm`{skmQDx2^9=@VQ8_1LXpP7+vK{)>5`4xicw>FWGd0C;tC2G3 zm^h201?^10u_g#M^AV%tY8u))Xc{`-pe%Q36l*y_s@Gkd|8-mT?z}Cf7(uq$mVL9^vhR;<%VvIY zFRLvg8K{td(g|cu#}R^2PCTb_PQOHzbFmv-m2)lx=V?$-q+ByX>*LnIRs4o?5Fei% z1i(n1m?aFkz}u{Ys3JuU#?Hx55xM(SG^pD5x*pq7cSk}vAD|tMa0WElaCDmG34JBr z+JfK@++jTko!-@3h7pSWfqSQeu?2wAJ}{7Qx%$A%ED%?R?X4soX&NA%SgGiK(q-^< zbOq>;hkL59qyN%NJ0X9uArEThg2|B_mE_^Sb1?Cur3;KguSGGn<~-Ey zcEd%g(P`c?>2LG!bw#7nk(BsIqtYSN;fVMuqfMOLg%iQqD@Rb1qi}MCjw7c+lcRcg zJDZVd7XPb+CO4iK`60rQL4pR7=8bCF^II`%?0SXAOrXj5b|6k!#xL8OkoI1)gZIHK zyEl0pINTzH5jdP;K0%JFqe4*V^dA1b@-vyF69Dez3x?x zq{lj_Z=4lI7st7h^!O+dSg_$cD^TiwY%ul-?xB)W{PYnQUJ;Ecy#p%I#V9 zG3NznPeC63DYXUYq9u{~Pw>6Sbu;?Yn#R?eFIz&F_T>!N#R6BEe3}zsO?e)+6wFZr zF0c!>i50_qd{aVV^f8pO^v%8XgPsNpX%USym-j?1PTuZ?i{TSE#_I&wRYfXSornTf zC%8K141duYMzTz+ulIWuKI(JaD8q&{FyznH)=5V%_;T>IUZl`I5}iP>6d| zM^Y7{0~;|o57naIs#1$S&x4>A{Sm&ngYGzrZpVZMSRrGi-Wcv{jagivjy;Hd%KOq~ z?d=%y@xa~N4n9?C$9S}lPvc&P84N-u?k$qy=zugowDx*@FUP*WQ?Ev!IWGO&s(6r* z3ryrEsA9r-KSdSCp4+)9PC@%SQw8>)Yb21Nih=(dRdiq-HA5BubznDTnl?R0ka`Bb zf@Iuk?jSWkJFv_5MnKyPQiq~R8tz~O?4XHvpo7YXO6`Ed{j{cleX~6C7?aOi65)#*sZbdaL#M38XV(8LT_vn_v`Q z3F&EVVcEopS|VmlL{Iw4XIJoh2o$%TO$l{qSU^CWL~0s_n}O~dIM;N^k-X75O>J_I zH?ttI-tn4H0L=?vRA}t|#|3xc9sWlD{J({KsH=BN*zKiGMc06+<&($`E^@kiJpC+Q-IGX z+5$cENQkBl0KmS~3_~bw0P?spO`qD605h#yY{_?Mu@)2J$v4Q-cF_rx?#6H>I-D%n zX{b6e4UUAK%VfcV4Rv_R`Vi>Kc%vKlCm|H%k>>b>X`Ekmn1n$n0+2~a5Jigci*6mk zBzRH@eoOERj~gk)Zy3K}{37g#M1o6>FP~G6k&NV<%8!dQGSS1m!LWg^o*F6>grTVm zG}PY<9X)5L|A7=>Yyqp_)xVsWXhT5?3lBQv$Xk`*)83hkYVig?JMXq$Xi%x70ZbW>}gwA74%wHGRkIhZCopZq=08 zc)=MneNZ+|c!uc5Kzm>&Xxq~La35hE$)*w4cH2E4vtFYk+t4a2vTrQf-Yge$Z z3UXfDQuu=|W4r{Lp;<>54Mubk1&f=2i7;pu*j)@P?Q2`GyBgTbw+-8s1Y3Pa-gJ32 z5yEIo^iAQ7LTEbv#&DbjBx) z+z+i8$x^ri_r#>A5yz#XKA?Pvxu8buwL6HEX5u|CAm^q02#>GI!^k`| z3GbOX65jZVlVm@Hi9E{$f$?^DAG`-7=+l4kY|$1Z58uJ)-%)*pLkHiKP(2T+@8x8jboK<1c^XQmf>Kc&ytJ2>n4$N?3&Ib57TS z4HtoSC(_`Q3)1*2rmD$_X)r`qoYTmcpwZXb5{E!sIjPrZ$M?!vP>#n=ytrh%Aa+@? zS;PskYK0>)zkrM}m%Z85ju)MpjAPmWISLl}7-UEkIrGHZPz~fW?@>l4!Ff_)p}aB_ zTvAZ~!RGDP&XIKsY*D~Efd4{)iz52SklzK#PFfgjDCx5;`Q6H0huf#YAV0=9Y59E* zfFCKpewf>NN2{!Db4H;+p7iq8MPS*kjsb6 zs1p;iO431F6Irgg!!;|eqY>Y8sw|^OUFZc^aZG*!g7moRXhEewSM=~0Uc4>w$tif# zcM)%(0xV7Ga(K%uQ~Wk4!ZBTqFd7~4YFU)In#&ap`E>w68eQI{{g7P;&)4WnPqF-pTaG37AYKpG$*5hxmj= z6bmXE-bnY1j!xgg+B(&6FNh7Se}QS5L4bw>M#Jd|hV%!%V8uF&@E${mB8><(j81ct zX+oxgW>k>unFa&XoNfIyrh6;XV?9h4q?tAop790X4KZBE3)f^;Wq>T_W91)DYhXIL&h&Nhc z?957CoCdA~Fo&gX>aVa2S8DwI&i}CXg~OF|+7jG3Yyb8OwD1b41*>s{g^8AT*ICw8 zX?0}^2;UAN`f{Ql>@eB2$e;>6_!?~%o3wi{md_XtbyvxbO4|)lkU}-y0+XAJFfDhD zqy~%Dgu`+X=}Ke*IXVf*AJF^F0tZ`tpf;c1ix>Z|LuVC%L@q4Yb_?S&$P{6%?Jz;Z zIvl=Sh0pYGRxsbGd$zak@yWTAfkc)3=%evOV|gB~8H>>EWGsIPV-cNcHKB~1aXiLn z7oj}_F`R=zH@j`JLCn)ezk(6*rX5c?2@Y3xb(=b`3dS@~srrz)hS=lP!Pq}s`p|;h z`VgfRaS0Ml_cnY^g-7V)t&p-Ir+Oi+ddl4>?IJ4O;PMuXQJrdM;hm98K74?NcXuFf z<1m1k-}+DF&MFVmMIUFUK9tY(me~f^@X4Xv~$svp=gddld6b(-eA)e3QM$ z?tt_%kJ!>_(cv0Vi@Y(=cF$^W_(L?~W3%56{C47k4nmd5mNb}6qM(HvYRYN zKQ+3z3By*ZusJobIp>FvbP_$0+S1^s=3wXgG@VDv^RYFZ^<>P{sq;NKJgUxZ1SX4% z>UM&$`(>O(EgC%JbUlBB=_YH_)~9h_u;D3GVQAw~9k;dJXC5ij!PxjTmik?3g%iF7 zV?|j2xkI><9YJ^I?o9}HAU0Yj*9sfiAsmM};h6K2-vAOkH{6@S^Nsf2VKaJ7CxPY4 zcdYtlmr)LN8?F{00!^8KQogIm;1p-E$U;gEG-RWwz4M5cC#T7P?|G7}b8i&95@wIh zq)htB%La^Wko-ezgpFeHbvYA$3js8`bxlKv?eyXICjQE*VH*FC&X0@$d9-5!OU@HJ&MURQT3pB&`*lAS5$(R5V~3g(-p?O;%Bm)i>`{ zG)+QUdR5C7j+NNrdDBsNc?*+QrdSL|Ej(C*&A%LFURo6vW;t^LEt||#_|aqNIHEm` zbn{XrNdEuog%FnNH@g3)Yv*qpc^4g2lxfj2;DQDOSVpv3FtJrZW5|B*e(Aw8`Iy09Jp=e zOv}f%CIC&<4v}qv%FAP$B8O5R(~$)=#@3!^Oe+=bYNe!v|B>yWJwRsjR0c+NX5KKE zZL#8b^i-6w+cHR5T#eqyVO0YLc9fp$L74Nb}EHl)w6CwFDI{gb1j{J)9|wF-Od#U6`-L@R>*}2 zwlR#gE9@fO@WU1!Oh=eBR&pl8Kp<2K0xqibLf;#<*9&=pKO%~K%hfH;vw6@0p22kCesXt0!!_rhqe*O+-Mod z*l0;(Elz$)d^8Fh*x=)l7(?V_majMcQbKllc}Qz4qf(3WqWflHjNL2Pus9bfynWPg z7YcMZ-kBVdMz?4U#(6(L z^RB-Tyi4u6tQw4Mr~Azk(_tNLU=l&pl#tFcT6jmxSx#j@R3(XWK*>vShUn2kbSBTVunWB>E6E?j5^M`g?8U*~ zv~o(b5q*S4?@RU8A7{xuBJY}%rz39Jhk<675gfk}{yLK8MTvb%QKO|`P|Kf{v z+uZWYNr}_ZCzTm}vw7RZW;6yk#H8Fe!%v&z2uXPv?t#NWrz<2RwsJA>;t|RKWZ!iL zL{VM_h8PBlTWXAt3>wO%y7#QqvGLpS-hw@zdIW{cl>-d-UoVv%T9KAor69^mECZP& z--Q&yd|%y{Sj@`MOG;sEWzxw?wUb3}MJvi8XRTvvu#X67IA{o6rXk2KgNG#!f0tMy zd~9ZLOz;VX`OaGd3k6J);3O#frV7kk19nUQN8`ayn{T1-sEil-?gBDeI9Y5(Si%iH%`k371*fGYEWOE;N)G_vSi@Oeewy^4O7qbqK2?l zP1o=Z6G$gyGVvCK3^7%Rm}nf1xweu$s6V3JDdKde2=)-TyVDfYogP^%-D!%qJDmqs zlRQ_?Wm)G~(lELT=}u-VQ1n(>0ly@AGZ<2PgC#t4Fj%1%!+cXltp*_=eWVC|G@=m?+e*heR3#B zgnE||3_9L{6ZVp+95r^3k07>^DRLt(rQ(D zK0JtoI;HH}PgA2#KLu#ml!jS)t0@h$F%a1l^!!SBs}a+YoE_g8KN&xQZrTAdHo+?# z_v5+R6H2!oJep`xUZ^-MdM+b^0tuPrWy-GOuQ9cf3-e-z(LZ0zAfqrV8Tc9LLS2)E zNwvrKuus8uv^@b^W^C`UC&l*4T9&zO&j+QYj?(^9a|B3 z;A)cTTr2p~RWuYJB3@mQ>%9+fGZGAoNSz~-68mH@Jkl`S^n@@x(#!C%U?}xV){nt3 zUBBL#b$q?Sk{-bVUh_ScR;u0i@a`zazR}!oM&xF8Ha0(4>5d?XVRqvmaxwb=_Gl&R z*?&QiZNC-pK=cV5lLG}S65hhQL!bX#YCx`8Zl z0woDtPriW@tkJEU^*@Fyoj?CxuGsS`d6i@4stJcv+BM-o_%wy&_nhDWxk{1E6rEI_ z;1m4uT6`g{iMW6d<>~?F>Otq~VYw0$fS;3uL#1)XXMzLzpvuI5?$m@sB@+(BWx|2f zm~dDizw@Mi%>W?bK(aRBP-W;;u@=n+j6^G#a3C#7IP7AYRf`A0>q1`06{i>=Cb+0h zW*kk(0r4Rc4%Kv5@2pi;s|hC4=Y}Qd)?G+AR4Rri;ZW;IILup5+IsQ~C;xNEPO#w! z(ua7Pd5b?L16Y(R;ebkzEOcibZs@652V#?`Q2BqXy$gI))z$w!2^k5BPO4y|Vu>0w z-fFN`K}07dqbEAiR77pnYNe&N)z<2apamJ6L^vHs>GNnyFShhzi>-Z1TMH2t!o?(5 zAB}j6muke@83#3L3jvk9-{0Qn%uE1jpT7V3K+Zn*a3q)Hx4QQH5WPPKibo6h)*x=D7X zvZ+oCEVIq;(IQ;(jU^w66(J7p8DxmtOJ&pcIu6q*h?+_SfEg(~XVWGl5w2FiJAbYv zAXBw2?|t^nQsZo3&Mr$_rAKJ)XH?iqTGL)R%EDLu&WPMuEBnh!jH%-wTkfwFMm_FS zKCevGiXI_Ta=>o3S&8dVu=+zwAqnX8_R)5ge} zv*!gYYQM0=$l@vpw%)#Vqsh5%p|bAELiOQ;cLcMhbto9a8;1ktw>yEUD#2MCceeU= zzvILgCDWq!#3-QhX-jZF+on$|)>yO@wN6ovlo$^}RHMSD1D~4FC5HZ6t=>KtydADL zuFdnQYL-Jp-(pNfp`pPNPz^Ej{5*Q5yVVMX3{-Bp0jAkrW{8?UX1msPjfb=K`C_gy zv~<-sKH?k&-{BdSIEO!T_rm`ax#iDgcz5YD}E$z^;!WpjV$k8t_eLQm*SO0m!xDr9bBw1u26m6X;UA6ZKubyGbW6l@ckfU>oHVxV$Chu@9`AsJ$*b~vF3b;Kn6EJB=Fs6O zfzxpI#ls)g`(vUoyw8!qF!YA1M{tQ?0a~I4v9;_jpJ3hL5`xVdk1bcWkYckC`VyLJ z7wTF~T;27KJI8a}WS`r!AofCJS?q-^y_^ei!#|xrE|i+{f(|Rv+ z*92*bY4>qQn|6Q0W}B{u0Si_zXUNB@D>lH3z&DYDHiez^R~fL&!Y7x!mx}_I1np3- zK#yd<<4%Lh&3$n<)=T|^-?i-;>9n)LtY0cW*2&Bvt(hJnZ-z2J^4Esy#}?2?ZxV5e zKr`V#?*bU78wI4<0P$tT{iQ$(n7Pw76%n%tWQZDC|6pm+7V7V%Q9bUoM=07so7&@U z^HT6{r^=2D(V1iq==b{QcTgO*>4$Clxp?!3w3pyg1eOLb^myk6`fYjiC`{%ghooXl z@k8iGus{E8GCWEKWMDPHwSHbCrvs0d^#FOm$xQyevSgcS^)%{ELdpX9GGg1zXx9Kq zl0!`TxH;V*W?gfvlBX?obg(kkZ~MDl^?So%4Zk-t;U-f)TCMBH!i}xtLR@Wkd&ebq z4BA|!e}{CF-}lf-gz>m^rLUgB1p_ca&@bhW0lzlCiwy(%QRz)p1(2EWy0lom8@&6~ z9;^7~AK|Y#4;e`%%p#^RjW^|Nq2rI=X?+xWQvlJA@{ye%mQyCLt_1Sf1om$UAwPBcr4(rSLcljO<0q7DM-^s zX2GVrEx^)xjpDKWqocTWP?&m?eWv;8IUXbJNwqmWr;p%z8|)=0eFWS-r1*q_uof1* zNN@jZBe7ojNMc?=(zj^cyUms~`PLfLV3V&y7z)DMBP@ER=ny6IgF0#?>#3q)MmLBc z5zSZ5M5-?DaK&eJ!z%GQbYu0vW#Sj>aJph`qJfkbd1Tz!<60hT=FI{f?c{s9s+HcYu zLn9uZ;ZFOF&LMYj>pc9pB;6Mp0TVCjjNP50=r*>n#XjQyU?>y2g@ba8aPI$$-JQm? zjNQ$s*ylQ~YRYZbMJL)F6j|rHIi(~CNXiaolhm~XPWd6uN_=xL@Z5yIhB=qFD z{x7zTTr=F*HYa^m57hEAv;;wo9w)M@!wefMFDJ!%t{sDGbRs)ZY)N$)Cm=?Ae_r}Mrv?{+Ln%WROLDR;Fl_9s(?m# z=VLT56Qi?Y-DW6sO8|G%Tn~_)wwQ45O8IL|M%g*( zSnr;xIolbl-(rracAIf3)?)LiUotaIjqEj>yh=+}<&3V~iT-SwD-`vy`&fp_o}x}! zsO^bWAU628vA+Bsjnew7$7$9&&XS7RXMHt z4kg7AefiS%^%2`Uq&PtP_*$GGOMsd0+a>l8&}5edt-Yi>qk+vk1Wuk$otX-~Ar&HO zsZh$fgrJ_OQ1tM2u28$53;nUn;=Sb-u|ELT2#6@{WlKn`DlScwnN|nC)vIDVAR7h| zE;4oN;m2NEHX(;%p~M}MY!piEqL7$a%muJmzb$-nP%*Ygq*cx&f%2IT>9PZfZJ|ol z=+oKe&BSUD(Qr2TD@!P3^FOZ{9r=}Bnx8QFYj(>2KV}B#v!NjagY?aEYuS~Kj&=h8 zYzkdsE4&&2$ksn!E!i4r)#qLd90i3VZFXXvELpV3K{Dud@wd6I%HYw!!r6(_Ec%jA5rs%su`4vH7762 z{no%N#kfcx;Ga=||KRoicle33if9zTuDD{4vqHfts3Agr+`{~!3-eKFjX%LEasAFj%@IFM*qbL&3z@)9W6lA2!aCDCXks^qeT#UZ4OA|q9lOw zwObD7bE-Y4Yh8-EmSA@*#_C#x;jysMjom_JDa?!>3oE?OESVWgu@&x>nXzT&4ra!( zz|2@yVrI1aW=4Bw?7jt^vF&i%w7N|5El_@mRZ3VDus$bn3bTpa15!#xj~_=q=!eOG zw2_RmFPY{#L~=Jo1=%j|!5Z>2HuACziYZi~)SvsQMrvu|f{7oyFWud;Aas`dAjG_@L?atA#xI6l6{Pg5#08L=vKy{ZFq z>2901s8hUBo#N+@TlDG-N#wOECB$j!+iiih3dr-*w@2UV%qjywE6osw`~LbeA5^y3AAo_;96gZ zesZp$aYvo@kF@dPG*z7bK#k7f2tvIdn^UyS!=gMv_wqTf<>(=>G z^gg5qiAI@`y_v=;-FTqL!+vs3I~&-$QDITkN-t^!1~d~EX57&c>Hd_p3^hj{VOX{c zM}qCNZX;HVU&t$wC*4LGz?)#w4_>4V8QT;S0fv^_J$Capb*M^zz72v4b~)ijinLvU zp<1$sAU2>+l_WdN{CmY728#dX?RX|@=Ia^6Yqog-qv-)?wh)XLIaz5~t9$>q)-Vt~ zjwkVY`3sij{%8q6@5@>+U~D73m(4-$62&3YyAfSZpENJXOnZP@HMNc#1z~H8XJa@w zjThhO{RhfC+Cb@w?g`a_KMhAt zO<=x2TDl7zV;t{XWw)c7xZ4~h5YV6DY-PGU#PJr`C?5y#VyM@@axoSl5Ul5O_5sqi ziAg3URhn|SO*sTs8St68zto+YsG+qK-4zA}2Myg=G?eflFW8YcBnvXpN?4noD%87n! zgxO@DYKBR$vMl4SF}I&$+Z)*Kx5QNK`%nYFlru5buFd>1J-WP%uBO5zkw0E5OSvgz z74jzS+e#Z!F3G0rz@Y_rx~G(}o*!MpSWy_uqYL_AEQAZjF!V%4#%CD+6mmTL8G^Ff zO6hyP)i^W_K@p>6MpE(&mB<-VovM#XW~GJ{<=71X;Ng4Sayd$oewPRZ&6XM;qeOpMi`I%#+5wrp zucJOiuh5_~P4}X<{|9!)*2QpnK@|yh&k+Wjez55u+68v+ZFu-M4R0kl1{iz6U9)8a zCGmTQ4iOY%UCRru#1TGR8X}%5&c9WJNMjYN;$jL8Dlr*}hC7Q18+NbEthn{K_|>dR zn3n8eTVm;&EbY(}86r^(N=dq5o2R`>jRSZLUp2mRLM%YO8mwFHJTql^$4&l2MC%{A z#B(*>zoZ}=GvT{nK)Puu;FtLFuw7xx6+M}7&!vV#kzT&0t3T8XfzsJn^Dj5o{odMuhLopGM9VMw7oP%~q#yqpGD3PtNS!_9cSkF_Sop^EqtWLYd;i)~GdeJZdq` zIZHdb7;<@za+`7HQPv-l1wv-cz966Wv#^1~_g+RNlVYBK`K@;ZJC-O|98y(A=Zl-{ zf~YP;)Do3hMKY1W%BN((fd3t=qdBAxqLC`Uej&df_BA`}Y`%+>uVgU{ z6RKs1JoPmlg2@Z<0XD6NB@X1#6H4sI19PI9I(x*C@I>kA?2W77cZqzA&yG>!o99W0|2r}7S1}s(&B$PhfHtnpNV~FR*5880t+BN zimbh%#E6W*vb;z)1dGzNCpx4(rXBlGfOZTw-j z(U|LsEe`R+JdqU9bAkU{WS+a82smj|5AK57RVdS@TCLwb(mGF3=?8^DC^0kBCM42* zDGZix1TR`6;p3S$MN11U6cCo7#GZtNXeej z!Iq4BbF7^HEA_W+)SAaU10E2e>q^b0PNfA^9~r35WrzAW}TxaIY;W;+Q=-J!wVpdKn(;q&a)Prx1qFz=tVT{G0#8)itpXWm&;Ewqo zTdb+1@q+l(2aJ;&C5+7^N|RO~Sef?|+6}8yl`(=B*rYBmrLpbC7NNR#=vtqoNxmrA zW=K!#f;KY+OR6Jmmz4HY@{0y#Q6v}^xp~%!^E((9^hc-WtTLuW0p%|ff}^3x5R{ko z8!^2QR2SwZE02hgJR3`WNjzh?m6@VY$XG@mO2zD)4(tA99w((o6>|_t){_6Bx$Z5t zFpt=smSP4eFpai(02Oc2DQ2vQhNk4~+8P3=cx|lT1$4ufK?T3`D=1EJm>(=m)D;a& zy+_)qfw3$P;U2RcuwD8W}p&--&5p=HY(D}MOw5{X%TDZm}!;`GL z+AzTOd{IT9+%Re=>9+(oBFtG3&t_HV-ykEcRkIg;T(c3IfnoZYKB{yf>N)>D_?_uk z0`Oh#tr0*veqm@pG!4_uGSi-f zM|w>$8~xHJ*`+6F)~fRFdYA5FBASWTKsIH^8q>@xwn<~eda8U^-)&%{g}Gzkq5L#u zEy$gbG!EXQFphMLW`q&G@weGa@b-*Ju}wEtnvfgY6jZPS=)bX6Zt9oHO#XUCI<^Tx zspVi z;UB9MS09DHPaqSXZ-AiaB5m3ul?mTa3P|PwZ5hz)-{lhrn#8+j!g);h-7}#klQH+q z8lLdPnNXBZ9Jpt~-wq>#PaI^T6Znu=G!w2ZLJeDMBYfvH)xVeO7dqtxP|SVjT93V! zSTo_bc-v*G7OPctwpEeVhfU@VG8<6K3FPG9&xG&UEr2&h7s!$h3g18=6Hb(t`+r7- zPZgmCRQTa}sxBPV{^9457P1=?H?l{PmqP1(B>MkF5%m|~B$yq_Rq`fNR+_WAt zBX)v4P{CYmB9b+7x{=L2+91ZAV$5z(_;MBci_&zBQ8=n`DZzfLO_mVsA!uk+6hkdw z-7l6<6+2GfCg_gQf*YzZeOvbw)3U=cRl8Jh==5!>>@$Cw_fzt%=b|ICi!<2dths4m zrW(4F8-Gm4p7|O={ZI|W@kFQBpg>rb-k?u6I$NHDG$ng!cZ4#$o%JW}hS$n9i+065 z+cgC(?yK$m#ngivu4RwNGG{pQzS0@-Fep_bU#pxEJ=`x9{xo`>8MVA0o(`T$B}-85 zwj9n)UpJflW?5`HS5WoX=WmBnsFQqSqt#zjgN)w5RDIlCwR>GEz7tYA;SOn1W>xtl~lUxOQ_ zFjYea?calJp%Cu4v|Z}$EjD6Lv(}0uWM;2lTH6BrcI>(|bLft8`A%lOq9Wo7U}H%Q zZs{#Zhx$VI6}JAu#zg|}Z{0Q?gVhTKZTN-Szyg}td1tWp=S7vY6UH@OSUXb^3l4AB zk`By+K_lkrqa#61v-Wd_WETCZZRK5_K0s&tLcEdJ2ppiih{tX+tNf1!j=RP=S}QA} zI;<_4U=Nn{_)QGh!Hx+hGkOK86Sm*7VSLZH6!82$D~=j9Vu%AL*oSS63TjMB==5ho zlg~cC;oL~u*J+m`;CXz1;V)3Zgf)@Ya|_XiI!mc3(l$AWw7#Wd$&0-dX&qOHk5+Kf zaL>ri`<294D~eiWE3Gz-EQmEq-}Z*3i!j*DsB1@4VViy1$Ms`#nsiHHfZy`He*-v0 zc8T4@H8an))%hHvF8-`yG(>c5UC9tJdq`+QbVO^%^|mX?^gS{$#E0|?zFy_YEH`yO>lsI!2r59Nm>;yHnGgN&+ z9;lLS{dwknf^GbW4X9n&#_}(k`qaMw!>7dnEUICk zrVuub?Xd$H!OxP1*@;g|m)C2ko6zz=AVB$)nh^??49Is$W<$6D)>}cB(E3pRNLvdM z&%#p62lD&vQ05ZQEe=V%`B)C>jN-V%sS>$kO(yman!s+&N&3188LSIa9NVj@W3r z*6vCu-H`sq)-76u_F=9uyeW8H-eI;>w-D9)e)he`Eb)9Uk6S6$tqtZqnhtg|CZYVk zHdw`@hZs&*JiAlO#fAg5cBUyJB3Sm4HX{pSueSfP=~&9g?l*=h6c$J(aAq_-vvZWc zyJN_4GV7V{r5k{+r44(K3gWa2fKQzF^syML7K!Tejak9a!op2(((W=VLhX=0jNTw)LF9a+bXhEUpJA1csn>KN`v`(MC;Igvd6H@l zt?%-#ER`>+OzcKO&A9lebScE&C}S&=hNv!R2$weaT0$m`SqA7EI{)yu#q@QBur5Q? zVRVvp{4y@I_}j;)p4RYH00oWJQ6i#-X3>DMS&C4QP^C~Rcaa4Fr3!2`1HKh9#qXZ3G>OH>GaI-8l zWrog_H3iIC-fyH!6qS{VDR$5jxks%b4UscAGPeht^cP*E41~_jd~KUGmSF1>Vu3*Z0$0G8I91is=ECCECD5%f04@Y^+L~l!BEvWk%AS%XK<^Hf&X5_> zTBuq<XoJ-IA)ybM)1nU`}jBFaq2+w&9qGeZdFIviaZnyRX;lZZ2b}d$>*-rB*n$)f($lT@4 zw@PauIK=>AqxCo)5}!9Y^dd^zv3iZ!C7ob9g*reb(0&Xb|U=glTo zYA?v>FO-%x_C?WZ!<{?WRK*QayY*b3yEp$g<`~SUc*c zOb>JtMt%Nr^YNutvA+>$Ea~Je=sZs%&d(o37!*cuUC{rozw3saRTSodx5K!bB%>KD zEq-*U=uuZ}jZ$Zr-B${+nDD}amI;33QD&5Qd~e2V)Y9%AWB(>)mr;c+4V3EqB{rs5 zw{eQA29c6ymv<<)K={K-=+!Vl2T(9ZnECT15wxWy??WkqFSNHlXfF~ABC@^1uo8R7 zueKW=y(QM(@_ETOVYF#Q=Y}dJDCq-uRUE+;rrU(swQTCO3@$SVxMm5*FDnt!yF%N- z3O>%cM)|~wE{t7jfJV1@U03WwF>?NV_6^9n-{f}0he>Rg%4uJF?If%3w8NsmxTMP3 zVZT4E+ds_#C7@1X03~O$u1{ld`=949`Fgf=rP+{Pjb-HLn1Q|#i zQz&RrGzE=p|ALk6U<@n(+-x_On(!e(DUb|!9v73=v%6yd;BU$_Xx1c4AZ@Z*iVSe8 zf^u$`GfX!sXl%$z7K`-ln$j%(r^uwWMJd820L$oFN37k$$ zTs6V-`zIY6pyvnZ`N&OIiWPV2K%|Gy2>70ifGRpxOJCEQu7FLJz$S|sP>TS>Lc4#T zvTm}bP7>r}#x9UVfr(6*L30l{X-B)+$JXWDXde-nGj<7cbfd}}prQRA3U%T92n&vv3#k9>_!0i8~S07tj@;G=@H^GaSJNH@;B~j5$6G_J5E5j)iggPB1k3)w}Rg zWhUJDrCNP9XD@Ihw$j4mD;r$TR>^%$Bl#%sJkA7Yktun|s>|RL?*gU>?cX>t8d}kP zpA%ZCI8o=a*EDnR0k2d6yGh}98pr~@a3K||&U2{~e#d1!`kMq-wN##E*X{>55OtxV z&Mk@Z%ff^o((Dfn9Csi#zGM9Q$kGHa8fV%LW$QMchnZs zI~IwT}nwW4V3&$v%E>A9vZu&+X$!dKCHt`qnw=cVMvBy{kVbB-d~> zXZWKbz45f>$RBU7y^QM5&W_r@*}a_)o~iz|*Ntt;WL3B+bFYnCoddnBMeosT(kQNO z&U93mhDF+L8bPt_S9>pNxVYhxhA%Z-%HpZu$HuR(X8@;wr15J%(X2sy$ad$6*Uboi zS0nh9ru4Q?G-Yn#rff3KzkwkfkNk0c6AP$Qx*8AFX`0YE?#M%PmyzPbi?P&n*7T7- zh?l)P_%i&i`UEC2e-fDrMOAg~NMgW6!esY&#KvzJzuxlg$Kd;(kMGtJd>_VI0pG`) z*n$JThZuaDwmf%^JL-_!A4mk(2WoXYKtsyBJQiu)e|RX==&nz{e06$jO{8@{_Vh(= zJCew@^@%;xTdUYicdkl~-#{6x-q_+uTaM#tPL`$L^veTIwt)dZqRG9*bWrYeGDns% zIqE2Diu~~w)2mK)3+bLq|;Sn$E&OL&E++_bZ+AY4G z`H4c`X_xg`Zp9&fZ7E)N-)_}+v8iwHU(k7rkyCNE6T1z~vw(?m%3H$xvMD`S5M9jU zI+)Mt>|iP~f0!Kokv~4#wE7K+u_KHaJIft;L@vja-N*4?;OBM*T~k_bz2>!efJ?i} z3>(S&00BuV(blZ$Z70`5T$B4v}va^p_cX z-K50Et4|8{!N>6LF8ifQ&HLDX`6j@J^oy!B{lb@8|Gj?Mf$y|Z@PFpJS8+ihNdmre z+*>tlo%HI;uA9Xw{Nt^&%CR;`^2OYrDdDqCboYGI>}Go?o=aIb*J9+MQI3)H){&9< zO^VHa_IIz8hurnf^pUqZ()rjs_IiNy)|N=?6ObakwLa1|hRn^GJ7jz3R*Q0(dZcva z`1MZP=1A)!#5ACE8&I+FNaM7{vDU$+>v;S*3F2`A!B2u7tuM z!vD1}j#t6E2!}Cgcn<6UYUCm_PHivB-|kFT(TaS=R9%rzN0u8{xtVB{@teo5Z+4%M z`L=4VAz4RR{E%myC*Hswaz<>AwQiWTvDtktcP5!>h$aoW0oy1|Fmjtjjd`0cgWhp& z;*B(=U+&NC&)D_mJ!gz=%l{42WRd;@GxZ~_)75Rh*-RS}m!?))BRqThgv7bbI3lgD z0ydsK_J*U!g~mT0*q5mX4mR@#Co}u+*nua!kUYp~8)Tg$F|Hx?z!;O3IItl#`(OAA@2zF$zZnV~*vFA$zH|_;t;1fyZtE(`wtPg_52Uue zecj$(|C1t`?JvyPrs<<@kC$y6+!z@fMJ%4=WY4Ii(KbE(!D%xeb*4W7D~f<_;>mhv z;zu)=v^}3#p3av!)1T)K{1@tRKp3>$?u#x7ta0WzQ8XIj$=JVm`?~4Q_49G-esCjJo%h*MGzOtx&| zK5FKRk+#ECEHmC2#?%4Qn8V`KYbNu|nS%C2mT63Y$9qHP^P6YA){q{c`WG=+cTs(Z zs^5d^AL3>}st*U%N7|mH1XI>X+pknKGd|bNGpNtBt|9%-)!r}hi<=hS`YBM&U1u_d zBCCdTrzfU>?cdqM%X2>^r9l6-=Oe8;YDqqkJKa^T&PdOGvOZK=u3|V7#(~_IZBfQU z`h&8_tvVZ+&X=dX11WS0JC5kR>{L1pZ%F*f`pEouF-)E8=;d60gA>`AUU3r}?c@QV ze0k*74J2pJ8q7}Jo}KcMGkrZZs%YX7Zq{jB#~*;i-8ipqBYfc|*45`;q>T7F{Z5PR z&#dY&Cqiw1ni-z$&kFkUydC=U>EvFgK+6kMDuaL=$X!pcK#zv(%pOI4#Z(iu?L3N? z?9{>RlwCl9{D(&&+o69Na6Gveu3YsaitbC*)mpO-q*HEt_%aT65{nPFU!n`~Zb zM`V@KVV=#oBTMUxEI0AFQGU6|O1;A(n{#DEAwSG}?jKmJ8qeT!nlflgiFAD?(prPq zaUTz6l-ds&xph5VZ4~99yc$Kh&cxI+znlZ4=1iM3rRJDT?rN(~1;Z-di^zfEP4*2@ zyq12V?z&GWK%^}%3luf&-fDV1MRds7@}f#;7YbA35$Nqm+ge_bC%KprHIgH^&d~0? z#HTl2o!(Z}9BEt~FY83RN8B}nnmIAIf+vks!2?t<-GM~z8}JQ;+)qe`9PQMZ+r)S! zY;>lbkv&H!5B-zB#nLH|d-Ru?oyXmW z3;ctVGS<3&)~jHe8$-F&wz5du>sYdpWhdtLA|kLtat8}xYgXiRXxUm8xjhI5#>F=9 z6w~^2rM}%57`aDGs}lOcT$ekl)?6=x1gWj`(z?%sAtAk%Aq9P2g@CE8%q>!xiL6u& zL?b`#j7FAi&dmVXAnFbqHC0g~lq=^bm_1>MszgH6VGaEINC^+eA9+BlI=C07w*Ut?X-1jM1N8Ugg zULQ`A1)=$j`9_XDT~vwnj5p9a&7^6nNyUPJ{N_u&cWrL1eFG5D#GWiV3=#?@o3t`< zp|R5TWwzKr7Hh_hXkewrT0)ugYAc&K7CJ#CGB-tmst-7{UQP$52g(zpy#<^qMB&5n z6Y_rvGnzm$r_5YQYqG~Ke4(68IM%2d z|9sObA;2#x{!h=T49~nM6RT{R-q;q3mwCQFn?>S~VbgzEU)+7yn?Z%mZ4cCT05+jE zTf?)-t$4xOkq=d2OYWQezFEOZwO>n1LXoz|csT704*ljf9nxw5=yN@ydEqviNL#Nm z&ReH`+QD8z8-Kk9|9U1CN}X~bif|d+A0SZHl&#>qc@Oc)p#YH&_Kmc$hBBDDhCk@t z%rt!SYf=wX41f_RX{jn`3COO)>35>C*O~0mlC)STu{fwGl)t0UUq0Om_TsWjzY_>_parbZSDzFruUuy zEtwBF?!~qJj(cS-QsAFVh_KB+@XjC`r)#ee7r1M5U?)BMsLDMOU!*B>kJ+3yV~ti^ z`YGFr6V{qW?45dGSg&wl+L-(Vm?lPewd-Zeiyr$pZf21Z871tAxR~jS*35!_>`E(9 zza26RT@PxwV0_1Y_2jY=Me{hv-Qq7WIPW{Z=ODZ0H~JA=tS3JwV;2$R2>cNOfYx;= zI{Q~CGp%kp+1cfTUKWQSVx`Gl7is;x%_jmoZrXtuj9EV2w57K>o2aO0&VFk|+_(orf6?Ss-&2|3jeb=9@Sz!z$fnX0G0 zDg97cJiGUnXUb_JS}%WOYU{a)DXFb3iStuir$*Y^3;>A_rX*bk1{y-eTGvNf=R=y* z)_9WRR+TioY(Yj<<$D?Dg&6tw^PMPtYd@lYCn&4$^6%n2DD7e2RJ!l#^Z=v(170Jy zCMlIhpSBM0njXNDAso^J^?V&*Nc+9Doo3y}xOks4UDeZ&*&k#b_t~awVtLQH1tP6~QGK`FMGABNv7zMun8QONdu;q$sr#=XAwqcz zilhhdKxu1~+tD<=Vjdn?DY7X2F1vHc{59amfOPTfF%t~=+E!D(x$P}_icZ4sKUNFcY(7 zxw3FH7++RJIR}|^4WV2I%r_85Eo%6Yrr}Xs^frE%{z+#G8iPpLi;$Nt1N~L|sX5g*PJ|^hlWUr~~n&Q|P$t=>v zhZJAHUy~(s`YbE!&0AMmDiRq<7B$>vRLW(!IeuvtjoyDc-u$UJ&PI zgp8B@o-lTfTU$b}_N|7uRN<}O$)0(&O^6b_!UkIi&a%PF2-cfm z#(>XqWL{Nd77Ir9%&2`^YTq3D)?wdT>|2k0yU@P%*|*D_d27^i=g2i(=>Y<^;gviT zGI{@7L8mJ%T2?92&Ghr=OdH7zk3FnOqXmm(Jo*+Bl=^l&(GSJ`=+3kxSA7V#a&I2M(%5VFV?!5ZJF1ze`n9)_;9m}X<6+R!O`?$(JzGfen+sDQBalU=D z*vFan(P$s1+Q$U@I9`v4xh+00DBXK%Q#6|mF=^kK-D)B%VM^9S^&!tdY&hw z5~F4h%SUF#z{w`7raIX>&AG;Tn-(B%@z3Lef2m~h8tWe4;f+9C=g0ZY<1Q2Xm%N+UA?*i`U^2sgN$iN{dDe?#v!*!uxF2T+)nHM;%m#h$lL zRhMij@qV$o#GbeQ`jRycP&F-{$@rdIo&SoD*GiqQZ+5pfyRc=Bme@UO4TDdE=;i4T z!imephSHJP9f?DW`ONj^b}Lp-dSJM_HZdVRP?`KRy`;s1-)pVG2K6OCnnjN919Wdw zFrTq{_I?^6`U^R?w?x4kbAM=mu+5{J#o8Xny`(qpezlKY=#YAJuVOSM``Kj_*Qx7y zo9g{eX>vEKyKpz`&^_&R&o?BJvJdvqzy8pC(d+=YvbH*&{ez;LF@?1d5_jMB?x7-D znc#MqY3+rsNOE8gTrywni)TQ>9LSl&c~);U1CL_r-~YnqjA!n;0sv0tK^iD+jlMQB2z2kjown)RH?~H%m`#DE@nxqAsiAL#1ZeP3l6&>mM zMSDqi+0I()HQm2u(7y}9?;mLXF?|%z-X+TJ)K5&_hKwI|(0U}O=^47fan(6ZItrB> z1MxKB+Uj@77_VzZL5}%pAJMsVSMpUm?!3L3NA0o`Zhz)K>Vyz`+6D}AO<1{R+Ud)J zET5IsV9|JgtwbcW*3N=<@@G9G8DCgv;5{y9mspl1etFuxv2+I1K6*ThR=1mS1&-rm zYLT|z_+y5=9KJJlEZ=aBQf+zSZ%+2V?Pul9>AaGb$@ zO0|+^*;19cC<@XW`JkQmTY0L{*l>P4`&W%y?F;-U?rv!~53XpT!;DykJI-x^qi1Pu zieN1vVN6`{7u2agUSEp4o8gN5so;xXNie5cOmWGnnkE+!k!wPpnJfMatiMNMnpofQ z`6A3>mmmBcL8MgjuR}(7#CW-PH6quWbwe}%%0IG@x;3<$x?)u#bP0w{Zmb$C;b1YX zwjqfze{9~jcnPlR+a+Uu@Z^8MnBJX?MZ*uGx8$Ydq>+Dt*tD{;WB~3!U?)A7F;?%{ z*;I+Fi?sdKbpFn=Y5iLKPgWMI$JEKb1eN?N*Mj^`au(qzEinyOw!~_sH*C2uXFrw^ znwRu_3|U@%;y)qF%?JoKUzhw?tkwlCEziwh2E#Bg5DoReMJEE60{KxqHMWzH#I6vFw$#WwD9x+}I8r zcVw+!8ep08)>bxUP85X9$l6)eRFc0_@(dqiiFL8CY5GH|JU`E;w`{!|kWH8jMlQ*6 zdXhy7c|tQ7{M^-}IfL_fo)x`Whqw><<=kf*q++)riZs0cDV>xryWW#ulR(?^H%@k@ zuWia+xvt9k8<0ra15(xC_Ksg~OOdaMIT>6Qga5aAO9A4f->PhTelCj=L+~!}4~SJp zS=&sUpMGO_dayik>WyR4gToR>qz5bHe@X1?{pl|y_F&s!@@?Zg03bWd7aG5T4I8|y zVmE2#9Yy88v}!y+Kfk`C@NePXN_<-N)hAApuff*WutR;v_%Qr-pDsVIHk79fyv*r1 zsEY5*1{05Y+u0Lk?LyktGPTKl7(XW*$1LwLn5oh2PWQ>>bX}$Q1Xi*x%h&5F0%Z~JW&P8^Z#q> zFPYaK*w8-LP+(12^C7)WW=}|bM29A}?6Nv-=1&^ZuS64fG<9`IWROl`{^p>a(*?F7 zcdZ#ptasbjub5Zxj4U_R<}}$99skXGbBFo)0d8ldw!IhGM(JC(*>8_v0Dgc)Cnol$ z(mRo5XCa-hmecApsjb79$&QH3{~K*feRsqSiIJwibetc$`u;-}xc+JAS@Mp-V7~}# z{d~sHsC-WLlClDSmgMJnDK)YrmfCi1a!fvE;H9?3legJ5Dt$R}KhhFMr?#~uUpJ27 zma_4iO{$wqzcJT)8?|mTC7-wbW40S;XaxJ9FvD^;K$O(%&y1+#*wrA-%ITiq6b1?B zKeM0PD>vE@Ek%mIpD9?1G{+Jqu!_w(q0!%3E*IlD*~Z#B_6EgpH*mn9v9>yYqUEnN zIm?GE;OVmFFyCxBJ`r0#WwLVHM8A zHxuX6L!PdFo-CA^`$bxxAppxGS6=5_Q>2j$v#}eRtE;GW9JbA$A7z&^uAM@;sYt{|3?9m~uth3x5ZjFu&RyJkjvFLQ%hYIN#KfQ@nLegG# z+_wv9-zLpaaw2KI1t6t+F&xG!UQImnmD;*Eq511)IqrRU2EjxRdb_`VAG zI@3?Dz(f_w8WywnsPImOZkGS)@Oj$qP=Ym4FDh#K6s^HgU|5Bx%`=4pEvCR!wF2Si zc6xtQggD_p$6x%}pSo& zGNpOqJL1)MnxWHX8eZVliC_j=@ap%(t5xvnTUJ1HA{eyArP6C7kC7b2u;iP5BQk!o zr~Mof9SgAJ3tX&?FKG0CB|lml#Jurt{Ro>dr!8S^E8oXIpMSOVJlVft zf2{u9PCE4!_WJs8`8m~2I>*k- ztq3#SqdR^xN(-SF8~@Cdd%SnM$)?+n!+#){ zf5dc{8(wsXijRKxBOclC=eFxH`hN8yeH5gJ zIgEZLh4ky1QfD)V8;MaH{hn$&AH|;=UK|hciG5B6%rh5OM_RQmDmG|x&#j{!LbQVN zxx0yvESrN8d(qQoP7_AHI8Jt2g#_M8Jg!8Rvwy)%68Q4uuu1mX1tV}+^l%)!YMK3{ zk82EW{!J8}(tSpek`qCd&^B#EmbXnxKmuwC3&1A}v*}zf$OW$1*;N(ZEx4}ZndvnM zVX#72oF#(=17C6ve(H?78;KnUVzMoWnNn?7AU9H=(%TP+%s&FwXonPoxdH4wX)QId z+%~XWfTBQA`(AusV0dQ)L|Xqq?j^$_ZHK6Pr!zt)vDIZXd()qZ-1L1pgrGK4%WgK1 zYZHt~x%M1W^p7-s{O0_==30>VByZE^&^+hXv!nKL9)FW^Jmfe9q9=%9987%l+OIcHzp}RC?Ch1tvO6Ru#nhCY9j@>aG#EkK-{@{JHzpxJMG#(5 zwBbrCU?Vh#)pHC;ZmwXnhg0^ZGjYFbE8^}qYn(C&8qi8Bx!$vPZDH9>Ysp`gIKqYFJW8f;T4R841Pb1hNw|)W*UoTi0j)|m}RgTwpsJUE!P~7yO7)k z`7rUr$jxUE(Tt-M^-y_Ew)WJf$2XmsxpHHbV<`w{LBZo8j*MY=K}zUaIjW_;;Ppxx zskq1dxN2U;Z-%B2(pzC78{v^ju=LDZongX8;mG`p5!cPx*|lZ4%gxY>hB6n_xR0;S z?ZpY2Ha6Ozo+GWll2;SlXx=eTX<8sl{UE4sh5^f^k=DN}OINg#M3ef_uM4RY5?mc? zQ#MbjLDJr1i1kfOCicD|u4?1iuK>fJ52qi(Qr8-h_pTWuCQp(z1=c5RMZG1byci0M49+hV!yL8iR}zan&dBm&FYT314FBtd8bx% z@mhb%z-9S?`k2(=8F`ez>M~~{Qs}xvn$ok^;h=n}G{Zm0&}lQwd`Z5bdUe}`Cim>h zCfJrm6+Ae@xIh397}&q3_kBNO*nDqNLk{YqB+io|ru(XlkX`M-&>VZ{0G7HczQS=RUk=o zcE;e`$D7@MC^zk)3$)*8ly(=gBITa4CenJeVMxfJL8JaMm$5E^x5}hdGv9`{fY`P< z`KjDppVL zW-g^mp1XF6ldae<@B7CluEE!KZ9V5ZoX0(87hTY`nQU0kG@ZE);eAoSDO13xUNha8U0dgU z`WJE)i}N#6K@)X9r8;$1O<681rK~u+Y2qdCV#u2NHsnCbSIb8$E;}gKMm{@U)9diN zn&?RDM^d^0ORUj7fwCJON<5c)g%or+t3Dd-IUUueTht>L)Z`YL#P|H6`3*MO=Prdp zp7%3$RvOnb(?si7<^x;t%x7===rA@0Z{`DF*~xqTqc-H-iujFZjy;1g259n=IXN~A ze$APy>WH%TZu6wChOT)FaVwYYzM32gzqOIpACNr&xZ-^PT6xY{jtV%viS63*(ei{+ zu}YjVF{Xaru!haCnhM-6k+u#1z#o0Ip^@c{P8}971`vJ$qpaTW4%KH-Z9f1ey)IfZ z{VCedPTTV=9AWhx6>0khM4(k)2O*i&N$Mv-$YT&r6`E&j+J=id6OQwWIF9Lo)1$p9 z(~P{Xymn;%4~7neulW@N2Ug=-1=s^`7i&uVI5((%FP&K53%0qVKw$jyxs6K9PJUS( zs_JXCu;_noDR7)ArWzt3P2fxgcxoXr0QGzLmGZEFB4IjpPGLoMg$Y){`*ErcJ5ac2V@_h0w3hm(+ng}Vk0W8n$`dB#= z>-6P5vO?LjnL5`&bM$ao@?`-}zG~9ka@kh_DhZ*oT&RG<34T{=y)2{BRrzOpJeZ+9 zV*FMDk7GLX-D+>)om&R;%e>rASiH)803Ay9r)WN$i7@|TpFLjmh2Ha`BSCgJj$bD;YeNt3D-mQwYvch<&T(J*%{Y%<@xOB^)>MKhFsf?SG#(aQZGx7sU zCVy%A*B~OGAA&||HmGq^KLB*=oLr!^!rba)ahDi{CAz#%!#1$b?LuKxWchjEsk*sZ z(-t-cQYF`_{n=inQ~*QcDjTOZp2w5#pIOe7H5WocvFD6N2oC5|$>&cR7=$n*q02~= z!1Kz*D=9A?<Q7M6AUL?8K;~LXe-VzMEEtZ7ShD_!h-x*WTEP6vxvn##Z1hN= zu3B9zYkENBJVxyir464{cZHwsuVqtV83Q+bzk>W$^xbe(=su4>853t|bovpL>R!<({o$jd{VOjkeK2Pow&5!eu5Q{7IFDCv-`yf9)19N7&dz4fnDUY&ZCa+^1>u zm+A%vEd)8cDO9;umuhKl(=X%Cqxi$`7@&zGY(c}}{iw!Fc!^TnHNwVY?3(E-JS$2W zFhChFk^kZjG1IosQmVZ*%cp+L9b$@8w~YA_q9SO_%3a+d#;8UzGOB&5ba}eF#gtj7 z_yNTa1XB=$KNcMh( zjM1wBfnc>Y)R`LKL`U8$;1PkdiU2Vv94ar#VqSuLBmrMHmYO-Ft`N1QqO$Ysi`x>V zp%V;!4Gr>pD}i!dUOiY9UieyTDBWKM!@aZOVP`|X)3>BXysoB zDqpFZmGfF#d32YRTX|%v&x8*q3r5b1n|Nfx&+vddMw-$1FfR=jXLt1q5V6-Pu9BzC z`@<~*gWiQ1BdC6{yNst~jTp3-0iqo#JI6@Q@HbQ$#|z4aUP}pqD#d@5tC(PgycU~z zvY&a_$7N>98S=DfOEao=mpK!DH*YH*mV~*(ukfaxlyc-J8?VRDP+>Bxu^GaFBr>># zRh^En715QH@P08QN^T49)*wneXZaC9R-q3;jec}*(H#c1YREy+RF=VP-9?3h9;yf- zfz!CZG~VzETT#sUAh>U2!5~EY8LgrS>kTEKLCb`*vG!zRD4wEM@0;yg2WJ#ieOLI^ zH)})k%9+m2-Gby^6~a34&f@D5c5H$~weB!Ilw7%Q8s)%{U7=i98yX;(F#lx-W3^(? zGF{$Wa4TBHRWEAQbDKx) z$OT9;!kui(qtDJ8DN3T+4N|_Xbm<*i2EBWi3r_emWT3*4GpO$52&=p&bL+B|M4uEO zdZx>pc__D&iWIq<`9tN>p2wtbq-;Nm&UExVNYd4tPcAlKLZun^8 zGU0Lj#a0+%4HQ_jD_kBFG-GO&DfphJf}8len}X{})^8O(9rA8A1@AKj|FZjn3xk4Y z3^bd9DO2!<-50zdD2R0v@Y(W*uqHIv;BX_ldFYBT#fq58?_;Z+o$bNh}LK*ggc3ZBUb4F)%*eR z9s{B?{3jw&qv2oj96B-vZZ*2VB|&3@WrZ&9l>aeYnN((qhgM#|A0@Qfgo{Zijt@-n z@R>Vh?PJ}Qgz+R`Ho+@n0yZ^zvra}l{9eTzfVKLn%;^1;lYDhotkLHCa*T zrLAdD4X}}_2rm38`DxaEwul*o``aQT1(qU4vz8V)en=5B;I)QDEgxHC@YT{8 zP!BwMns^GsuXB~5-fau5N+G7pdoQ~Mad(9w<0XcSs(zKx#9G7J9T`6z(8Lrmn))$( zZM&n%2Q`jFN$>ABIg^GxXK8=ulq$T8Bc+X=~pZnM~*RMyqZ`2b|lKW z?=j5}CoMtGSEd3%Wk+xn2STYJPd;xBI})f40yPRq+VQag{vM-OFR`>l*p2E69}IA9 zlecRBTQIJbb>|&q)jsC7IweWg_dwv#Le?o{H61ln%zXlsO*HLK8CJRAZjE~owIc39 zAgCvQ5kwaS+^Ah-EBn1lGiw3Ds6etY@)^*0A*A(9$jYDa)C!Gy=1`>uz?a||?=MzN z9#4iq`Wz+ca?}v%Gb+TT@Zk|Ov_O;mCDaaP;Vr{}?OOmA0RWYVi1NgK`9r(Hk8HGk zX(z5V%=3wmE;PR zAgX}6`ApNzx~x6qWlu+sG*4d8yq95HGL>D{q1Pc!i39SsWO)&k*1mPFTid=Q3xa!Pw zU!b!(Y?`mL;^6T=#Mo-$qC-(A zDO(W!BJTyHrNH`_FeJeIBocZGn7^jp6KMk`?$gnu$vz?X5(+~I`KUNxl#xgOdr_$#6DS0*&@-z?4BSHdaR#2URbL7xG zH8#(AK^~!mhSq}tcH!Dgcrr;`oDrVrKacmHN9(ECocELO^2PV%;ks+ommMoH5p`pI zXEnnoZD*sLPC$R!!G<%Iu6kwgu!1-lsg566?D#I5wuj~#`;d1z?{vFz?NjV`8Z!ES zm68enz+_k*WH257>Qmg`{3Q z=*M8cp#>0scn3q*_-b}2aNb=OPIbxLtP1KGXNP0- ze-Tx1uA!oWYEp`ssVXo*DRzc4Li2fO$j&Q&0;(x`ZXp@W%ut+Ay#sPJMhPgTW`%46 zf3RO>{C-4+l~kFDmZiNgppP-Hd|)~Z|C^T@zr?3iLKUz|zQ3@rbI;CbS-IDV4d%VZ zA7x-V8r3EAW|sCJG}YK!pOTkg=cZ~J`foKAxfe7wxd_DZBxsMani@)b6{Rh$*s-OJ zDlnv_p6<2tDt2n1^&OesboK`0V@Tf!sNy8;C;Lj@ zg}+QBW9o}~6enqIl;{k{iPR)*GS8t(Z|Xb|AzVuWgQL=nf*&q6%Arb`B~VsgYpC4i zy<`)%JZFTzFW}*x@N2{j%{u9q2F4>KSjm4(FpMUM<`X()cJcGhmDZ)7n62m!gD^GU z#zd7d%H~A#2=w9={`;(vHa=RVlLsbCbX0cHm6)u0o8W|70Wa^eJF2$9%{90K?z`@D zD=(aEmY$5f@cwy|nWv0#jV7M3prxFmW58jN*}>H1CCE@nacf7^4u0)8Q_V-cgTQu9@4!NS``Lt8$jFe>Wk(sx}zY2kd&Xcp$9VkT+x+YGR< z`>Zj|4>F}PsnK+eKH6v+Kfzt7cazkaI>4v_Ro0n0kg(y;2@GNK?mZDOblHL14zsM_ zkNcyj#G7lxS$O-_qL4pP()mPms`Yzo#(GQ$kBjDl`J?<6z?8wfvAlHN_;+Orw~Kcf z5bVFS-x!%)>$!>AS7G%JNij0qW3>*@uL`u{@{>s&Fd@@m58CjhsEy_9;K+p7dGaAc zolh4v*1o#h(`wg196Bs{KWVMt9AEi)+V7IgMJNF-rx3 zjcKGX@5a{TX@s#x9-MaET{%Dw-8$|n>fOZ*C?Hj8> zwm<(&rL7fOAB;go*rf;iC7rJ$hAD4`rXz_q#=03D{2V@88Rm3bhGCIb@JUA=V=9wq zd1%rV)jTnjHzU%3cDd6+ZP37u+WA!C2BXXp*D66a*dEAd>juSmW{(Te1tYX26TW84 zVZN2zVZ{UKE!y-@vqBRZv;*M~hrW zW-iuZ)&RC|mU*&+-8=$7-j}Rc`#TwEg7K=JssVCpFhKNyQPc1)?~uLms{R37bLW`} zNBFk_Ypm^JNBD&U+qu;O_C+geMd51-g)SDlMcdg`0^j^G>9U=bZcM06rxr{o(_8jf zmF=-9LXVZD;cmF^DJz`x#sI1=L4C$ZQ2&)s|52g)qr=?r-4w}xPLQe+!}X|1nwgIS zG0I?nyPeR!X^Epqj8TFJz)ROIhM_T6zz&}jhXrxuXWNz`AyN|iqE333#{!C8sC(?SCg7Qm6T8($@LEZ~})3#TD zj*u!ue@oH7CMNfb(&!5mEqFQm@p!+3ql*3w(fR8N5ROsYZxwfWA+B0+OB8o@A+ADk zcPsAXLR|lz#Qjcju&Q6j3yS-_;`S}Xbt_Jcg-pHdqP3mj5l_}?ezKPy{AAr@GfUDH zJapo-k#=26GjTMB}m=2D7qZM zZg!lS1!QEqT03R|avh;;$RP18KTx=T1MgLMlEQBi`v2H_8{o*Y>pbkua>rUsxaP`P zu}FrI?#>RD-53Ck0f)=w%wRN)Mq{S6KsVS8%nx_BT8-`ppgH}={+YpWX6P-GakQc3 z$SRj?rIb`8SDd00%gm1zRb|mDaE*#wV?mhS1bI(2Z+@E)UfHqA_E+$`_`qz%WMkM@RJNi%X1g+5vEjWwe z{BifhG-5r6Jm52nczgxgeiUucb4SpRIpVzjJrl;t&(Yk?d0&l43aOoAys!T{{$ZU0 z5_ku=V4b`1jvm za8f#$o5tQ>bU}5$ng_Rn(h2Z#!s(va0;5w$w(vIfImlQ*z1 z@aSv5VHkVm=r7{Qn(g;~_UPZon`Q~$ne@quT+{N#Z-M4HD#21b6DJ#TiLS;#6}$hw5Bl5o)g zHHCY{j8%;<@|J&Sq1T=^Q^S#jgFMP#le*YXZsi5Ee zQwW60KOId_EBt3HLFC&bfo2dhip)7UdJkz)L>Qrb@%3Y`9NhrX&mPU;KN!(7;$iYA zR5p39#|-WF;JX*GfBB2QuP25cL!0&Kb13F_gDNV}J5NZ>VN!4W27ED?Gegq%fDEJ;^j#_1;HSzXhty z6)T)#2;7)2PSqO1OEG2z2NyyseA7S#aO?GRK}RC zj6ZbLR7OQ5R$gUf>i~*++@-H4M!tVd>-_tn!|!Be{1v=IvEJ!b#$hD_gW|mYV^|jt zZk|LcPugnsK3&b;XR6tgwwfsl`n$o@H!q_8+azB(dKpiq=uoB^lQI`-p=s)<)uAWNfK9H^50&-WYEzIc$6 zE+Eg0e(rzAyEdbL2T#a#lo@@QNcg>W^snHFs}oq9QgUKO10GUxVn%=M9g${~3(>)m zF{580*`x1e0!A?JXUR?A9VPdEujH&5{r3L`ZX?a;hi{m%n=zhd?(CJ{(9A+Y3aPyQ z53oxFSsl%e&VhH@(Z7ro$=NGMdwBBg=r-Q09Yr;L5hK%~cJx0E+R=aZNYIXc_UQM4 z4kq|c&@t;V(Gz90nt?%%L< z$y|&G_*hI*UqMHD;+v+^4_WG|-}iRW-*5bw9ea6rkN@5`jBo|-+a0oh^vm?to%87Bd#7PJoD<&-~BS`N8qEE`V<6r2lGX2*Pg+!@&Ei^`Mva?;yfCl^{Ci?R%k=Oqp6xpjse*jG3 z8r#i4qMW8iYnU^XI2Ve^zH>)<-;2KCKhf0Trxk#+Ub^_d-nPZaqMCHjMb*v4r}4R1 z55_$eg&K)E!M5vqt*on!2Nh2@5`36r2p^uaC>Q9`C@mZROMJ)5;42zSD=b>-C&46U z1MKy~KLbMq&+pTow~!Ydj+y|y-R4Hsc|R;I*)l~ zN|~=#zx`(hS-x7?8SQWBp(6y+KW+CDbt7!f5|}#k`+v=9s+orqm7o6MJ_Y_IT`N&% zV&DPGD`k0+X7F8~`60-X+|A)z6DBpj^_rg4=wdVa(Lca5>KyEvLR0i8EH0iv=us~t zC%$mDgA)OQ7JV_k=scUGI$54_doJVy#fqsileCw4p`=twfXt~-s4awB+NTw*= ztBiBitDi@c|H{;3^tyCC{wU3h&EIEq{*HbxQTn2Ka}hAiN8k8Esmk68iRV6h^!MOv zKHL2g<7zvDSwF1v4o*n?UrjwBfg$$MpC=jrlhP$SA@N0Ey#DSVHO1od{rD?HM^=RI z9|s<&v^{15#r4^vFTh*u$}%m*GK|N61=+uP^!BT$MqwNC9?bK;dh}C3&~|0ne6^un z`EEnW+La5;|G$*{U+A+d7Z4kE;y(g?nwNjpj}~EGehgar>d|9NR2M9b2xkiQmp7P~ zZy8ED&#%4y?SGH!kFCwXuok-XYY68jte^gp?stFJ&(m^YK9Nvi1gSCxE7XlAA9{jhqb5A zuTXx`zay|F!QUN~Yjvy5M(2!r)4w~%9A~3(z0thcP~~R5UTRcSv#pvs0d+=Ac8)pe zd_I@g&(7qon$dpkP3PvO(>@6YkY3Id3md6ax=_&1E4k!SQAg9Sne64{N@l6Jmdqzt z)9dNH_T9)9HrCd1`StXYeqThK#f|0VbiP=~d@ODJ%=>ySS1hb1S5~xVHn(2Pr;|(9 z^xIPUawe4yq;@5rSx*<&^11bNN@(Xc){D7i#46-A@?cZPyqsIvSWOpGxqNo&@4qExSL)hg{9#d@o1mw`Gxt+vhC$ZV9)+&hs?@qJVF1rbe zHr;MF+hwpIO|1$z0yZrkJTgUsY{%6(v|~yW3S% z$#${4(}sq}ZZxZv_*o;0h2d3~$x z_Hh?kZoNjQy4`?5tu-6lrXb2to#IxzSuge=mq2n+8)+1RRX&+eQ@RSX5eWOvY5Mur*d85v~EVq{RYQSC+sY;_{N zq0`kyG;?md-DpNes@EgEZy2SH3}a_AGN4l{ZH59$oqD1gopP^KMw@K1VoK`i>Xur` zWH+u#CkI`;rL;Pyo=@kq=@s#f%}+l&Jr^G=0@mXeT25U&Fs0S40M2o*EjfP7wg6V2 zXhXc_ui7kkYr)C|)}rtrgqDXkwB|$xP*WoVSXYKtl4z}G^^6WdD$>wJ*rQGtUAwa1 zJg`>~vqrJ1`xaB$nO4?w3td1p#sAW3MB1$|-L_kEOC9%Mq^Sp{p{v9$B`>Fo8`+gy z>iP6iF_TNJub|}3Z+O0ZtJ!P7HeYuuMN_ch+_a{BvqwEB*DC=ZO{Ub|W|p6JYaMrJ zdl}AmUut^`baWPm=htfnwOWQV>3XGjqh3VUs8qBVQ>f<1o5(W|uLy-`>)wCIuNzy< zR!1!yb8a7Vl)}K%MJG?G^-GyTaW%KJv67zF0Z=79z}3wv6-#?tO*kXn5v>;p!4FMM zUnw!Rj@<99$!NiP2>MO?Gvj`$e1rF0leZyu<@~}h!(#PIdRyVHOe?NBZnwBu?Z(zF zqGzSMDbSl|VzE|y=KNNzwB3o*KH1)y#P_>2piqVY+WXTWD@M4*3(esRzAi|tTA$F=cRFf7NgH+Foj-E6h1ZnxCFrNf^# zHdWNc2`If8VNq)u#d5QUnzW#3n+8=Du{~`)h}EHLDFqgb7!DUV3LO7$WY>`f{b4a; z13aJz7{*`Q?e@^cnMp5h6t3Ag1NbLTA_PB1=(cZhu!=!Xaog?20!mIP6T^^<&GG%N zu0vkF4rulKtSzMnvo^ry%#7v0^4IDO@W)&@&i%H6Qt)0r@4uB}gT2*2y-^W{-^j`I z3ZY-xtXffM&r|S33)QlIrvC~*81J)&;-)l=40K1t8t!l!WME=&EV*COBA`u-sQJ|qw+7zfkjRtR2Vd-1VDYwLr#KRf;!rF#l>lwMbAb*YFi54qID-0ta9&(8ISEa%f{6L6|O zfFq6K^NS{IzCX;2L%h%r+7=|3BEO614;hQs)@=gMf=H`f+OC%{-&DRHJ0)`I-fFpQ z>TJfkrET=mmRFYYmy3O5q@lX)3B0p|>2|e-e`o#iOL?c%R+me)o*VGgMW3!z2fR9i zUYo4}tj*m4ugaiTdC;r0d-kr1&JN2cC=U^bvxhu%L3(mvrY2ZPLd;EEr)jOZjkC(s zH)X3-tK0Uyh*PRme2>=7tqwizdi?6-z-LGm%LB7MsF|2s>9s-=HD22}yK@}5m8qiO z9E5JGrHQqpQ!*_rffuA3cL~uoFVOFvvKiFFIvD6IK7Y|955_(s&8>)fV>cip^e^U!;oo1i(&{mo;5+CUnIK__F3qn3_Y`dDtl33AeO6t=vui zEAwB4|2kDZRjmMwDT9>sgwRy{nFtPy5%qC&CTx7udLWD{-Q0>r=ZlJ=J69nyO@H%a zwm>DE`mD{aqjMOAAX!H?qk_}00+NC@YN-pyCmss0XB*E>SMvFfvd}6f8#uYKbBbk%1LW7S=W@ zO)YNZGBQw$+o)$)HG^vBgmp4XZ+(rEhMPh#{XH4`TJ;Os2hVzO659@>&2%ZMo$mBO zW}G1K7<|Ty!f7UiU_6EHZcJO61#}(&m8ogFHFMZ!>bjKbo2`wXRhpN_^&6dq5 zGh>b3dCl}O2jALNOyexfoz?C+gJE7yo0x~u+)TUd)nk7Xc>?pPq(!8=x``8hiNgEv-TYv>iPOJkW-JKFh+@+sY=@w zKYJItcUJ{kH!7pYqcod3>A}&kU$t}|?EDU^P|VZAK!wuEihNo;cQ=UFudhU+btd_3qjR&`E$_rY0Cu;G*?+~ZcwZZR z=9oi6>$mVA;b&eO1}~zno`|3;l$MLvKI$Od-kHy6#SS{yoHsGQV3k|YwOb4Y>;#uK z0W(mN$b;=ZG2&Cq)tx(D?V+l(I@+PGP@t*t)FRmahd9zW970p9Gr=f> zgw-2XQCP1k8jjmiM3mtR)t44xbGxOj%G|kgr=E?glT}SoaM+Rh(rUzbq(o8v*?gFP{+_B!TgXP00AV*Gn_>EDeRZ zOe1;EkQpAqrdQ5TtBHUf=#G$Ka-b{3XkI*)?a+AC1{5g;B6*{|+!Nnu>|JF)4L|t) zkFG9}cE;0~C^Mt|#LD=S+;MAX!u=j~+oL9;Va+y%TQ6raF(r_4(^CfGVXT5~T*b?l zg>7(6k?RjzOk9-VDPI|G2g;?dz;*lQ8sS(7b1^K{pN&ml(+JKyFZ3;7J`wBexL8{&OPu3oJu|gKuNPx` zk<6zqErby3_*T}zddwMD;Y-@=bI&HKAH+ZN-sv??_YxRwEPkn0Ep@PD5ED$b+L;Mo z^|?r&)xoTN^tqTd>mP;xK?HUy5+`m`fOiv8G@!J_&m5^-b~$qq`$5)@Ier$9b@&vE z$DD-QEhpM;WvA4gu`4Koc=17pl16w0YGAsz!{H98Q!CS} z6lauRmnO^#{3*jM`5j!6Kjjf>s;N&|37Gv8iOpuSYgeYuU`aVXXxefzRm7>Iion+- z8`!*H0tP&Q8T3QWjkY?DQAX(NXf?`7UtP~9i&o3e?60m-n%Ug^_)L9bV&de&fPS(J zywaQjVrSxvkJYaP(7#fz)`hewUoDZD6iUk0FICuBT*~ANsP$`Cmg36Hs9>i+s3>Ne z#m-I@i%ct8uL62vk~3c{14yCxMw@K$fsc@$U2hI5nx`EscKgzGJ6-Q(b_z2s-rE#d zpYq>kucHR&SbDETy;Zd9lsk!Iru?-Q_LX?zB6bMnFFT2C*hFlWnRT$!X>DVD!Qoex zUU$JN!h!=;(fc^CjU&9p$Ea|>x9AbF-5(Ho#SWp)twtHUPo8z4ectAfNgkbtpV52o z+nlcGW$L|DO1ttq3U4Qfw}TvbX3C?R@F?5jv{CHaa6HkCethwDj4H!y2lbYfK1vV5 zIN@aql*2K*(dPN!)*7yWa#7jM=9^7dZDBbc_l_ibopxfg+DO1gF}5F{MhklgTeT`0 zhzd4-aN7=M6FXf*!%y}hnT<(-g+Uro)7N-<>lB6+cGng5fF;amG|{M6i#JP{6|6M3 z_2xs8#TTWWrkbPf>0MgG@C_bzFz$!g+39sF+z<(4kByOz|GuN&Z8C0cE8*_qb~z`( zB)6(&!%zbK2zqo&n@%#dmYJVhnB3KTzOaO4gBM>?OTBta-6*xIdb<|4Vqgc=+;dlt zIg@kqyN+@oLK&{@BMf5F(K#J2OaN7ynLs|K@j@8obOy*yYj{`x~UI zQ@jVF34TZA#!>ydk96Cmn?*3SC*6i?aT2uKv`FYEV{Pg-IyQ>a;Z<~GK8bz|jHjX^ zBA9&-EsWH<(}Af&@2-K}kLU~CVs)|B&(OQ*Vzo23lkG|K za;cr~)_0r}$-=U8VtK8Af0-rc#Nyhz!<$R6A@~Vw3FfwJ?hJku@ECySEGWPQz{>!Q z;9(Kt0^ntU=NTDw?W6g^`o`reS3mZ`i>*(zJ1--lpT=$6+=u)qQhLHU^2no)J)w?_ z%EP`)?vHTf5u~aAJ@$l2{Q@!}{3zrM`8r~Jo`4jNJo1i5kAg>>kPB9YU-2esAyl(Shv z4~8{zTu!=%9!@!p>jheJ3`{1|1AX$UelL`6xC||>H;c=hX+)#~wiC7TZlT+3`|tkS zs?K>Z-1vkrvPI8h5m{K|PQ_vlTd0_X@1u2%UaO^QW3k%ocsQPihhiioG|ZbHxR}yW zy=-LRp+kM2)MD}ZMhMIJ^&{pl6_;^HhKWw*;IYyOyf*8XnwXOJ66aYZ!58ltTg_75 zOWoZfF`SB^-F%v=OrOG~jrFD6m8^cYC884ulu8rZ7|LB#VInn4I2;FunCO=ZwxM?2 zzHsXm#7b`UF4mfxr5fXVFU52NdcbXGnf0PB*i3dgN0e-{xP*~f!_~D5C%~;F_0w-z zSKdDtdKdo(<$mL$;p>r0#(kf4=dJq#*4?!3C$0OV*8OSg{<3xdxpn`@y2o+K4u8k2 zEBQKO-}Bb}xOM-Eb^i_kXeO zZ(8>o)_vr8D+lY&TlWX7yJ_7|TK7k-`_tC_W$XTP>;92-CEsE9m@WU~);(k0ymdcr z-M?(zziHhtonh}^u=wNt+oAQ}ip!TTIjVpOhb0${hgz@V03FN@>3L$cj0G0n;YyK6 z#~e+;l;9E6rG2|sULR{bKcMFf-t7DUWIoxM!`#|)wW}&NS((HyuGs%0u;W*0;^dvs z@0imUg%KV{zb+b8<x)z}JJ-i^ihsGP#n>XK`|%ddifv zK0hy0$H+y0tWlMw+i85DtLpqhqRPEC&H?MHf<8hI2chsJC>;~cNZD0AbFNtx2YXd9 z5=D5o-NdMM$F)&DfFWwRi?0s)@V@6=&SvZ16&FeAZ#He0XGUVq+n6HSoLe}*O|g3` z*wA;(vQwXrUpvl0F_yRa$y-bhC96>|X6+i1q~cYV4!YksZHxA^xurQZ=TvsiXuePh z(kW9d^z5LS$~R_FaaQmIX5G^%R+bcJ4+}kfc%j`rjZZK1#3)Q*M91@&(B@v9#XuVk zFG6zZ)zJfNG{^Ca3)#yE0eosug=+GGU!KOAnW&2#}r$AUtW+)9sL4) zj~gs7D|V$0SU{fem-jE9bVT`h@sm0bV<##NjunJjnI_7fEXui&iYOjKH#t=8h^DB5 z3#E1KR~EC(3df;9$x5|y4~I&+T4;K~6ZQt|U?I?Uql5!FT$HhL(t2GMh+!zsFKc)* zM$GhvMx0F=_lNH5_mT^RwY+lyGfU0|6ozwQDN}Ipm6qS!pa9MVZ0SIoqr}#Y`zD9j zH-VwkUs%TV<L)QJM zb?erB#k&8Eb-!TUuUhw8)}63)|Fw13t@{b<{&nmAjCFt2y1C`WC7h3(FRtMDUG!U? z!e*m2?O9mQZ=}|Xm*?Z#txTiaUhHk*fUnBUJm!DhMgfQD^*UIKt8w!M9Hp(##g0?p zI96gcjY-4hToGqS+YlR|rG$NBHero5bAFRl+d_2#E9i%jz_Aqk&8Qca7O^e`+P2>8 zmTGpqn9}EO=^hgLM*$==oXj+~nwXjZ2^q`2Fj;vC3X{ZkOa!1~Rl7QERM&f3$Es2j zhM*NR{`N&PB6PHi?ih9so>9jqJ2*IK$?cTeRm{WUU})nN!X$9TZET~{VMy9QPNV1DZP2t) zHPL}U8`TfAC8m%r&NoJ)A3Ww5O}T=39Vn4Id)c~M*8MT-{vGRn-n#EzGIV~?zJJ-eUk!x|-oxVlf#vVp)|K}^dq8~u z2Uc!>-MT+#-LG2rPpmtcHuB9{_w&~Migo|kx<@V=y!R{{_kwkQ(7F=-u(_YH{QabL z<^8n>#P=WCbjG&m@N5z7(3-R8WS!@owDVC6^YluHs}8Qf!9ohhTMtoKb1vmp(r291 zN;Z8N2W4M$FrZ9kofRkP;8dt|IE7Y zsTllu>#kUL%epUH_itJEXRZ4s>;4Pt{u}F#_3QBTOFDaxsmJiW(v-ybd(ngcUW88- zSP3YlF)oM0S_4XZm{_}V#^E=5C0}m!w;WE|%wiMV^B7`rkPOHC?o3W$r!8hN_*K{Y z7>vQ0{;W4^W-Ipj&wJd)cJL7G;QZBj{V`s7pP?2rt0`x7CAlUgGq#Hl-Y&9+B?_zh z1F_!bh>DiQwnTlq9QL@n{2Yth1y~sma1Y|Rt{vicszjxwcb;0ixzyyM2R$>YlDxN4 zoz~x(&GUy8R$=Sw2qO*Y*lx=1xC?APuoZ**`ySkWI@}pKcY54!JiPrvu#Yf_%RJQp zUw>-Yo!Y=^6TOfgpG?e$2Cqq@H3fbjc2_OpH1b}{bZ@v2W3tn??lF21Lxn$2(v-UZ>@jc}Fi!Y`{t@>_oan!fY2$-p5-_PaYe*diBo0 zn1;LJhg`ghZ%Vjx6)lr)v9;uE{8ZmvsFj1=g=$y;&Hj@_c)75yCF4H(gYOe0KE64$ zf0t6FN~y&Uk6cQ)S?c2P)_@-Q9$H(*_U`cP-B|XACi~!OzOfy9@OI3!AZ$p+`>-DL zxN@xfhdZt}+YrZnsKfdWk!aV-XE?Gq^J3TuxKhH_oUXr!S2?-snDtEU@S1xb>}Gqs zV|#@z%LAVWXLcVN2DBJ|>RhpB&r3+;1DO{; z85JK}p&Csc&rp(BfpnLL#Dm<*+$5$qrPXT9n|e=~-K?ZGAsY<6xvV(w!?O7sRh;pL zWJcYWX2;{}7;C#-j^y=Zo0S1S^PzSs?Dl5$EbHnx8%v)_djgqO$uk_sXgW$IH*w|3 zv|2v1%#C630B<8al8(YoHyle1DJSwPsWZ3?q{E$5m|ZA^xQnZuQb!A=)$Fo_usFP3 z?Ocb%G@WvrH$hwF!m-PgR|j!!=rZAvpk^Q8e6w z2eIKGoeCK7Pt=*kkvh(JY;kB~i^L@-@%^?0#{JtvYA-%&S_x}k3TO~a{vCJ<#jPja~ZWtJp1#F%p(%B5BZH^$T6!Sr!UEKbA4#H`xvZEa!d3!hrl;DHh2 z?<}_Ks*i$u2+o5`$bv~zO>wS^>4l*Kw2fo*b-#mW3!@)(voVeP$6W57$A0Hh<<|GB z*tJBKJHWi}134VI-A31=e@{oNS*w=yVRI>~HIX%bT)z*$ekZ(zv)Jh0Q zZI{RL@1Y!sZ0-Mk`jJO33Mv#mTRzs0!_|)jmqd^IvxnE8UBuFOa|Grr%=Wk}4s(51 zdR!N95c%QN1)c^lt_u&vdGiTx^|0;SqH64UTrwIF^R;Pwp5OgA&kyn+*9BgS@Gy+0 zvg3B)P}_yYSYHr?NOr{=9l2#~lj|b?PPWasDOF`UDm_2G>dA)5x3p zah&hbBR^)>8OY}JrEKQ-M8n%T`frJE^6haMdYC_HcH~9Sx0uPb z6|1cyKnmk|qC*=SQ#bDOy7=*2 z(;?1vusjnu-WTVPnnQ%~F5gpmuCd-7fmIJTO0}N;Ag2#3RuW}*cQ;tK{pay~`XSG! z`(>)F<+v~W;MXWfB|()Mmw~!KAw2MPh2t{dyd1S=zlEB;h!{z=6 z56#^BRpbRfJ5CIqKf~GG%u=A8-tTeTjvsD2&T>pF@xQ~}Qr_&mET+7K#h7l}yL-XE zXU4l`Mqkw6#S7ikAcvwb9&c*c(kHW<PY0b`yO)50|2vPUmht(fuc_j+e8@tGS zKx+d2qBH&2eOCoQqr6j}{QI<+il=9JmwOQ~VD-MTB?|jBcV0N#y^y}jg>_~-*@#+8 zI%7S3`}CctKZzXwqg}&vNU5f`J8-{er;D55)RkthR?+()YSrs{#=Y&faQ_<~v8z<0 z>20sEYjN%q z(V}~r8vQ`M+wUIMfh%42+@UjKKN==>yuQz@g1R5;`%H^9mi?j3P27*>6W7)BTHG_uoxpvkokiD4`m$b*%k=Qpj*n%3c(PwCB#WZ`(n^fi{yn(0 ze~CP;*q|LtuB_m~E!`Wz(HXrmZ>&|7UYmUtdlzb*&%xi=jvey6kp8kT?iUd&~A7#{Gc9{XPLZ2z%IwvWM0dc6k?Q zHo_3b8VhqX^B?+9@MxQ{JsjIZ_N@L~es5Z2EeiB2^!4d#5eEa!9a}Bo3LZT=+S_#Xg^umm*p7|u*!W!O2Ys%zwqts>dZ0g+ zy_`?3_8F-WUdDE8Y{$lSY;4C4#g08sYc^oVO0^nJRBp_a+c<)^jJ>psV`Douwqu8A$MjrtggwLUpgR!;P0uo)`cORDu8r;4*q)8;+1Q>PialG=-7OD97uQ-)8HRP5s-mKOq%SH5;{Cdv_&tWgOST zL#~J8^*o1mW>Vr(ZY7P=b?mzPjaH@9#Vt~D@32>uO6791UExYNtmDC*NNniz{-!_| zo%Kl5Q7Y@+v`D9B7c*I9lF@rx{Pu6y)3`p4>*Jr-{(T~y+F17I{cL?qr_4v#n>*Mj z+Hh}TZx=S3c6c}?E-b0IU0e>1YtKRziuFjP>zi%`ccS6^#s=<&tJM$}-*nAJF2*+G zy13hn{;crakpo&tw1HJD=H@ni3E|jIADW#$kxnh@J*H;(!S$CYAH4^4V1u&aZf3jF zV!YP;!Jq5IB1-U{1pI8fy4E)1#HiZ1$SM3#)$My7w}*$@9x82x+4rFx)}>_*02uwE zFKs!;b@9R1MYN{}s)w^Gwyf_-Yjbz{$fjUiw-2#yvq9#)7`ATXhLpKn&MX%`bAdYX~-a@{YhHXdgj!Z<_j z6V?ikdAGjyYFxg~6Ht2vxBz$=fDJz*tYE+a(GSV}W+6K^F5i)g4@i5Sa`Et#Z$7=4 z%dJbFB(JY_R;8^jrpp88KQaE#OLb-spZ$ zB|9$HLoV0x`1{bt-}(c7Zev|8;<5dBeNNxKtrjrzskR>`QDppt{97|Yk>Ch&vam-qMZzBund^;^we+nlN{Y&x7u;#AM^YsdL505d**^7{OB%oPbrR-=5P z2evdxra7b5YHq26rE_i#-wUwx)aB9coSts#TVy+?<-~;3p66!u=Vm&TI}u2^)F>kz zy(q`XIfCvojur2gHc^5uCqqY~r7h~%o<8{bBbcCZTc$2h445%^4AVsq?rg}h?77fUp`~uCG%j7~s+H!p`E-n1V7P2@xE^{0_En*P9)^+{Y5LHkPda1Uba=MO z>PHIbSQ)Xf@wT9z^%>n7h^atlN>H|R7S8RoymA4fTJlePMqN_{WxUSrJyKG;v7- z79?`dM%}G9+qayXo6cITQeVOfiP_C+V>qVi`lhh#n~XJESXmy7XjXw6BnSfhd1t>5 zWzpwP>XEE_l{<~>39wvhg|p*vf_z!$vDY@^4Nvv;L!ch%c_wbM{6r690Iqx2mp*qO zP;}K@(+}^D?Z1ud(IL;j7#O;&Az!1kkU{7yDa-%aN7>FnrfO@4$`nhqwN9@V^Ua1F8U~xeZW&ARYQQ0mM~+ zEdbxiAHynurvOrMl6WR=koG3t6(C4gp5d*-=<=rk-110QaQM6dpd0inMEJ3D6~x1< z{we&YtZo9xKl4rA6<`%0GT?hK4ThBfBG+ITyq(K7oaI89xBvx^Um6cmo^?ED>^svY zZkVpfF^e$LV;stlxa3&@$Un=0&o=<%FPJ{dRskjfr2iB^=mvQan#?TgL-+U1*YD$~XrQ z{a|G7S<ppJmBgk_MHr|jFSNJ5afep9@OQBl^^EqUgSd^r#!tv z!E=-yU>#$A)-GukuqNcyw`tn;iJOq)D1eZG@N;;{bnIoPhy9^X&C zc4s!y%bA(vYR1{s|EG}vev}RQAz$P{c%%%4f7+wBipOwSCU%;2H?di5c4m6rYORX9 zvuAdnJ)Kx`JJ-9-R${Gm4a$VFc+hr3UnpWO^HonH{k?2q z65%W(0(qvsOBn{`s^HJFCKyJ4;!{VZ-0|p)(vPBysJAx&q(wTUM;%uH3738vWlR4c zKGUVH(O>3N$Oqq703`s^U>iYPzVlh)bmny114DwRC=3rE=Nzd~T(f z$u8%nOd=ng7dJrJq%lDMO;Qf)s_35RzKjLeki6&x%SOtDIzxLiDxI)C&@PCs(Um$v zy8MwYb%Xv4r>?Lsc@aPy>I!v(b&0H(?PZDY80j#4L>ylpukhU<5XYwz3 zpsN6^53B=x<{S$B>Bsy?7-gXVVvhu;1V7e$mXp+{N&7D2BGRGE6oC9)2IK)r0A(cg zmhq?q{9&!?1GC>#Nbdyz(`OBx2V4cb1PJB@ulhGCF7q{Eff4zhu%O^lZ#Dqba{^_O z2GE}nh3~>YsAmfA9|chF7)F^(xl!gUSMsm`P=H{5!t|wHP_Kzg9!N{dnzX0~qtaUk zE_sl7vLG+yBPeUq49bS~nsF6?I+FvCo&vBw${d~W#Jn?%{4%Txpez)Cy2*Fq5-*%@ z(xz=8Fb;7@NAelwH5{MqKj~9-(g&qjqoWpN5OBb z3q~%Kg_H%$=3&-_aoK+7*YmfczTOXeP1`~{`!L$*d$G&+VvD2d-^0`{Kg?y6fbI|! z;9klr82?_%4#^I*jSo{hIxf4xel_bGe^K@Bt?bi`%VKz0NO`;!?bO38_j|Ef_hP3w zhTu4a{ZRP@Z6EpIxT_0bf3*qVc!l^fmcXO_1!)DJrCyCnD?Bg4cpU4=JPe=t3*#}( z;Mgtvt|RRekMo z^n>ZKtjIS(0r;a{l>n4G%bxj`@vXwM%;T_*Qde96$HK&8JnEMM(60$#T*{2}_%8aV z@JzkpIGO$&KQfHvt^kZjf5ue+8EbRyhiTG}I*|e70OThDV1INO!1h-GM2|SGE&(JR z(q;MzKzczw<(sYOGJ^M%i^zn$kdDkxF+Y@x2HYDFEpO^U8PfDS1ufId6fq_{{uG04HLB@-1qk$zHk45MyH{)fqu_+fped|5t0+I$z&SwA}^K+ zRW~4)&gXJ)dcLiXcMP6YW&2TAu^2;9_h2<~0 zM!&FZrCy6ns28&U(J7V_>lE`(zX=O)`s}yDJMI4*fb9wMmH;qcQM45NgS7G5_s;NP z?MW~m@%YYkPXlPjBt7Bv&C+@K@1{Z3ael%awXTU>NnT1fb4Q59vo;Q-Eav!{|?Z>KbX0Hh;aJ zF>?ILKPT>IZ9czd-GBPunf$-cx*xXg4_WsgT37H6+g-Q(G_3nm_sHL$+Wf!!@0t9^ zt$WS7KW^R69ngK{fcT@*|A?iVv2OJq)465i{o9{4`4;y}_Wch-;qS2i%DOkL`@7ba z_=oK-Sbjcc-M?{<{QZoL_uK!#$mbi@RX=CmcdWa6K=<+i@kgcq|5^V2qNP87kLfJg zc>n3ECZFQ|!k7Br#s4R*|1ekZe*IUX<4d@>TQ=Q4w)o;o_(9#@v2>oXbj1~Zh2E&? zgyTv4VeZO5Hu-)~?bzeC<1vXgjqM!!A~OKKho9l4+eXC)`~-*3jKd%O*spmG5R4z} z>j?c}e)Bf2(31CHJn;+TyxDgot$(;Lad&2N?zH!Bes^+io^R$M>@v~{fPDt`Avm7l zZw)}X(x3ed>ASKoQ3piD!PZuP7h$>Wa@VWgL^#=zZejr8CJy^|{o}gS87#Xv_CVHM z2s4+E5B8G??Avo3BR}FK0jq!vpa4h#(f|dZ99)2m!AL{=WcCp#ro3^d~;Y zh;%7u(xU9?GCs!z3Lxb`{}O;B)GC?~Kc|2~3aa?$wWs8hc54 zQF-QAMgb0zKPiXFC1-LSarvXXnLp|n<;FDMiheM5aGCYAfd#hHNQ-;~@SSFQWRe`wNC)}6EN4?g7Xg?r?0&Bpr)>;8S~{<3xd{X_2l_C50V zx{bH`q$%$$>;BKy{eQnh-LKhvedv2kzAwGoxJ~>1*R1%JPo6a4+$uiaz3{pbo` z;{Ll(I#1gCgz3zN{PQ;6XRQAZTlc@T?yC>E`}gjVzhAWR9#lKI@m`}};-0ndi|^_8 zFWUDz*8Oqo{#*!8=^~!NqS33NgI;ZP=+{qK%?EHI@%so4$2Q{yjt>aT zJY5Blu>r>)6+n3WKtJNrpW{o{zROrk-otb!fycNCz;Oq|iOY02RtcxmfFJo{9O5Ye zaq9r$ZUM-vd?P1)j(dcULHQyOKhk2_d-2C~TNammgn1h#gW_@n`R7+R!^cZ^e?_D~8KCZ}<~G ziNwrX{X6E&&z(Aj{PG8WQ_a?`c6EEFt754*ZW>G0-FCHHYN%CgPV2UD;xJA=Zj@(L z5+)>1#E#0l9k+c$AKd$N#oemnlwgV>xxSvyEN-l)i_06?6y-VS%c(3y(G}b7cC~|x zNs8s2HY`T$MzdOppEacr5s$$pVy`hY>Ynj%v|O>S6V}`Z6C5cX(+$Oph!@Bo6Kj>W z-D11c*mn0x4`)K-3NS@{HKhe~quTBkyG>0Z7&%(5T0SP?^}0SzFAyh!PhXzbx7uzW zcai1RYw%QSocC92;@CUQU>T}Y+-f)L#UA7mNG__}hs8$*!?95(ccB;!)gMQxUM<<) zo`a6;6@F@;@OeMHwT;FNGL}l)+U}>XWh8-cr&>2G0xJ)GmXByWGSY7?%Fff(M!D9j zxawT3+UV^j%)x=PJLiuL1l@4k9o`5R6=qCqWYBd8&aFiTRU6fAWWZJ@(i!2INd@(Qb>C|stIcw^ z7OWJ$zVzWC_bm@?sK!SIP{SevsN+MGJ6c;=t)fGainNUpc7#VCR?EIw=MkJSYs{*R zCRBY&JJZT~>TexW{4dr%(%yvWws96RPNqK?Y3hM#penIT$;;{D2F}h+J)d4GW^$?Z z6_mXB4bPWv?RpK~neJAKreMRlX-)g)isf6bR{}noOsT!iEI;kmI_}VRE}ZYa)bQ6-iFwf^9#cai`6gbC55{ntvC;mEpAr3v9*in5t(k)w0b5M zYsF{I<6egCPMr41_Oc|t-xUFcG7o~@p9Wbm!Yw8@)-UDqvE#$~ddH<^TKuJSA(hYQ zqYV&=U0Qv)yzS4LlT2=@O1p|SOUJeGRx+t{wvdh;#{s&ncGc~c+P8H0)5fNXx;O!) zHzQ4IO`}+D_E3{>ECXuIpvoe)r>zIEI#eyCz#$8re^`vz01qev zhVj?NfxqaQ%%m4L3fF9$0sNCE5rQ8hblbN$FvgImh%;kj0VSuDiD5{_=JwB=mp}etZ!dZi{wq917JvMcEDogA7azjsf>enuL9_Vn}5~r*j3mVSizl!?J!Bb%_rW z^ewaIQ|S5Lds4LR=CDDa5gp`V4VffdE_Jc~Bw+_J znC;;hhCP0DM{T#=7EGB=aI0a)yiWLC^T=vr9?qX%OI}PD3zss>w7;;1o?`XUiHX$0 z-43fY=xOPpp>0Y(=8-mc_->@Kh845JiP#7FOOX29| z&f3jk^ks5DGT2970*6!gM&H`{V6x7R*GK7|LLH^om0DdY;);Y^YGQ8p^r>g(`a_oU z>9h$r)gQo-M)CPY6E@!;X2v02=m%{J5=;^IMy}=Z>o^iBziw!p_S%^Uyv1vnchiSR z8RQQUIRX!zp7s3V#`4;wYssahyg`0;kM#TTi|Inf#Q8Ad1nHB{EBVZNnw+p9)WUjB zQx4)4((6|WtH_sOz~X%b@@ch8+w~Hrz{=NSr*x5baV{5|a9d#A(l&aZ%PULy%UUd6 za+ZDPwx>v)9h|bI*6{DFKQ1fpl-f!kw-xZzDxI!W2fR9iUYo4}tj*m4ugaiTdC;r0 zd-kr1&JJ}iC=5}5XAgO31@+{>Oii%zhnSnV&L*SgHqI(zN0c=ct!~@*B2KAN@jY5Q zw>tE=>+!3T1D~NPHaNoti-XCcUMn>74YzaAg#rDYo3_F`{qZRb|9QX%UcEe*lfe6vzmG|QJq zPlxLY(oaY0O0L&s)Wus}ci!)9`4ufN-Qia>)AEMn`_Y*LQjLrp@Epu(T>1I*GT?J_ zg$rlXohsSgGdUAQXL{uH0_9BRbz1!iX-T$te+?_ISMdEt5@UyAv)65bM6m)?WGIvq z+}4P|puZL^tgA6&wxqpS6q8%pomTE9|CRZ#!hfAApQ=`5rpZJZ>xsvy_%jiln8w=2 z(V4OFO)mvuG%?MsSakka_PP@v>JAv4po%hcpb}1f)@IrfRUAN&+#{P&@zb!%_)1WY z4ummAV5b@x6ILIAmFPe%z+w^e&BbEum~$M3w~4ZtoGjI*@xQYBVguIf%<+ZN@feCB zj+vw53!8Y}w9jQcm+f-}&lUSzz;mZ+@R#Uch1#4s4l+8YIv_wNKn7GOEsYVN;t`>+ z2gH{yQ8M5#GEmDDEJp@vnIaF7ffY>_?O#-yTHwfKWS|zfQP8k*1{5!>lTmu>Yn*ft zDFQRDkU5r+ePpfiS`&UHu@g3CS{{{B4=x}vnpTg!XS^t!&O`{t?HE?YwB=vWYz&ND zPsU7?YL-4a2mW!<=iVmg&YfuBH@P4Q5W-9c^Yk zt~f8)=(WOm>HChS2assl*-}vo)mpRJvKeJ&Y$Jq2g~9YO2iF^^n8sO{JFDGu2E)9Z zJgKp;9@~8FDVnxa-q_CRNH5J=FZMc^bHU)0GE$e0ypGapMcZBLs#1T6!y z^-UgM?<59XXI?CXz zi(j>L9_&0Kt5D3-!$5`7%8GniJa;#U*RQV{HQaAFK)*wmaj;#SsCPE0+0&|~A2NOY zCa`~ex7n^uOit?dQ#-KcXU)?OY1#dz9;^Z*&tB*B11&VBVm|9k7kb$Zz8S~h|#e(IX7zm&U%DjJ@Qx3ri0BE7@ zD|wNujMyZFqxf?Hh$nq0FCrw`*Om7<)>;{7Lest{JDhRT3!yR9zi@(~Nd=_ZU%J7} zl0YE+fErONh9(~1hLKV4hs4wS?H$|Um>eSr)>G)t4y*!#BeJmDD6C;# zyC@5s+*MPs%f2#eB@rYN*@t!Azw^2!_q#*n_o0G4BI@96Phei+XU%N!93-Uk9qJ4j zPw5MJpK;EbjrYbtDw?#aZ;S1H57GiU|rLD@`xpSwU zjjNMYO;K>zAvHavmy9}@vFm`ENeM>9vwo&X1p#l2Bd@`9WX2AHkYM&Mb=4J*0eo~+ z1NgcJ%LtM9c5)B+y2fc0>T9mzp6oFV=!ug=Aw(DkJyE4Uc@NYV&HNB%z|SE5n`Oq> zi4p8(ziqfKGn|3(U4;D!+a^8!43<8`;hA)P7!YIJ!4i$~4n%Aw=ZtXCq)7<;g2T6D2S{v5B&}?u{}HJxfF3o1ZB`&mj5}h>|AMb0VNmdR%6h z92m;!0+4vrk)iRZRZxwf-qY^xiElLjuCl$;2S0w()h^Ord2L&ixzc`Ot^AL{aci%_ z<2H5Mqb8!Hg)j|(Uao6mN+9J1-C8*-9>%)pMq0dVS=ff#6uDji!o)=xp7NF9cE}!i zI;Y!F-xvjL4}*f`IYd!HMJyK8a%ycM6-jvSr$fatISz(_Heu}o4|7QZP`AO*CWj4*4Mdsiai!@p1}W%V=5WS-+uQC zfAz=u6`F~?zu6Bij%{vjVRj7>5r5`9h_<%jb?#jM8U*THU-PG@-vY6)b`AH)3k`e< z&=d5Gre~ULD$l4-X}Y>sc-znU)lAM-dW-**6aq>*ZV@ppm<6Jk2Thmya$azu{!zHB z$}z*hN#e(&B4F(riIWSBFFDbx4bhpsyjs*BR?)G2Mm-ga2rgVo=F>~@00(-IpxNz5 zzq3GcX3Z_i+p}uG!mHowvjrl;^g74XS-l5>JrCO;59{B09TFXT9wlbYky!(RcU#b8 z9;sXTYolt{sd!5?VqWF~(lXyVS4-Ei<)!9AczSu6>9ZS^HO~uu+n`RwIy)}*&d6q| zxY-rO+M(B#laFLRb!j1lSjU>04)$BjxC$$7W}kaDQT-tPnfFewak`hlAg*1;^>N0p z)UMA?CGcNxN~ccE>37U3m|tpnC3&#`Nz5!2?O>x=#EV(4sb(@KVkQf5S>t13ns_G> z?+SMk&Rjvotd_gjU)bz6`BA!~W^(h`AJ(i_yE9vDYzv!dHBq}=Y@XU`G-oV+sa7p@ zu%`f@2Wqu56Mog_=0%zVvpK@&V%BVs5dH@d*sV&OxJ?1xO-RvDvAJvjmuM|#E*1-` zYsVZv3&=Wrip672!tIt5ZMU*h>dx4emO;FHdNsLLyu6x}Wu zu<*&2lUWYn)KNv?YmyCY_A~(l9>5IxA?H?I9ixoU*U@T}lfJs1PZq6~pV?nsqcpR* z`SF?h#KgqOg#rC!8F-~R1H{h686T@(37~(aUabphQ@&avGbxmmtzW9JvAC4U7f|ch zt}MlsnGwg)PNAZhZ5BH_RbCdS^(vqzCONaRDS#A;Z?wr4ANUCA+4TrT^R$D-ZeMUw zW!HO|ox)6|_cjIAr~J3s>!<-bmfl2JZx!uErcMIW%Tx@lg?%NSxR}mjO^=hd2yG%WoO300)_(kFE1o3vjvuBn({Deo@7N3n`--hFfF7)GzuVYjfW;&>+tmIMU z9>xhTUu6EMH)+7IJ-XbR&i%6o*=wtS&wbC_kIa3!jL&_!3LyJ=8+aygudeL*-NZ9- z6@c+&A20E^mw6T-dYCshyNr2F$|6cpJ6E<9EFc0)&eDWaYr_rD9j7yh#MwfCS4dLrjCX;HHKREB;+`tOq z@ne%6z*QWw7^Im(9P&VUe-JPakl*8YAU)=TI>j`C_x>?&f`i9k05Kd!1UKQd5Wjl*^`Y|1rCCixUk`8$xPpkI51b3JWlnoOaa(+Mq{`8})m3^jM z$ve}MGx;b_#-aQPjKj1Vbp)hRQRJG<)r{jgJI;G_##iz=I?ScpGhvRq>C3fGE4qjHo2O1UXZ|-(6+J; zqI=l)0HH?7Q-N;ShHSu(Jdu~6&MUkJWkTCQ-sq>S8$ADzc7`;hOv3b7&lP}WPaMjE zGE{&leVnynv?Y=b<;nV?0OUjb`Odn-vdI9HeP$ZeOUgD}Cl&non*_`O<^i-l@{5vR zSavf&Rsg0+8Hx;;7Ry!YL{$D1!YLExNn|ED(q$Z$^E!ZG1jmS_2nX- znZFER3BX?xKzfoNDKF}Sq{IBkkL6SXNL}D_xO}q~hq^$X`5Pr3c_KZgOP4?9KW`yt z-M35mNg04`eIEy9khFPV8Sr@#umWH{dH09>_QRDkzet1jl=1ny-|})nle#bZaS(kU zrOcUk>Kt{9Y4DlpZ37e_Z0|&-k0VT;@u>A{FWFLFQTl&Sd9mEc-wi+s!1_*}X(JUt z-iPI9SUum*?mVpJKs&(SBwz}_d@BIo#qQwozwp3j z0K;tTFkM0vtxF7N`AU6McuoPB23-Z9?V-#3v8-vEsfVn`j7u9u9u#2IxIjIyd=8RN z@geNkOWYc zEIZ1IF6*QMjAAQ9=EL}BJ58RbE98fKkW`1_%5*7!)&3Wd+v6Kth?!Wo_h|1 zWz$zTE*2-YtNf6txKqY|%i;q9#@X{%mHv+rwzA1OUFtG*Mff5Ad{)+FIS9Yx zpZ?N^A})b>V_7j=Yz_0qxbjXKQcm<&0McO`rYE$NeGjKQ3xAQ1)IW(6P9LcHr|@6$ zIf-ZHlW|y2_!D{x&%^K-CcpjCRY1%Gm>=esd6PDYI!hU`?;?3qcqT6EDZ}|ppv=U5 z3eWO8tn@`r*o3WrC-A=jNCVaZY#+!QAqij@f%R$$Air=t;xc>{Aa!mp8sYd%SNNdZ z_lk?)p>|9mj66{0b%5xylpXn`?hqKpvMK>s#;niu6P>1=W*Gg6&+-->59)9N{-o0a zP=6}`{^-v*QU0VGL7k2sVs ze|)B%@W*HB5r2GUe~dpqQ?C38KHrHO%oEcUJ#vmXj~v1KBY;N%j{%+lC;)!Lf-bCm zG+$WXxO{~OKfUqB8z6)Dk0I`nM;?9bi6f*pG%~_o1`IH<)OzH%-w z_7R&7gO5D&jz^FFh3|R{UMG@;We7Z9SW;{2d8P9)iKHky=34=z?5FU|AM>oN3uhqC z3j8FF^BpEH=C@FwRrULzd{cl+0M^SAfcnB`>aqgRj`E$hO>7tSO!`1#(}<%0lK|;w z;!*z|L_KFh4=SB$lP&K*+qEQsvdRJ|SGw#kN*|ohtnaifloe&D0OYv@pj{#mhheP8 z3PAZXT>MxDd}lc6!~m2z@u>H4fC8`_n*icSeIO0`u`CsUVJs`ANgVMP9+dUlflFMz z7XWMr1)u)3fnL4Aa~eQd5OUU4a77lwbcgnh{IvlJK%2;S@=f08&v)ik0fyy0oKI;# zDU%X_w8%H#6@Y#sBZdX@%kpA4( zw|{THam2848@GRNul8?Tj&JYwZ&>+_+rNXgf0QHVms|kH9GpM-0D$u^3cz_4hH-9% z^EsR+Qh=!W8P4%AKHc&BjFA)NHf&DoLCmwgUCMV{Z{MEvcGx&%+#kBP{?NlxUx$_J zxSqZ}>*;vhd4K!64@*5IA5rrNWBdE|w!iz;*Kzs2z03E_)?0p$-vlTC$8Y@R&M_Is zUVP^`Oab^V;}4F>7N2HEDIp6d~;pF zvjW@%Fb&aV`Y}E7M_v_xdEoex&%`B<%nNZi_9Py|DKCDnR{;J-)&B%=-wHV~kCeql zKoUS%Tmw)pA}6l-cv$5}xeye9Wu5`#00n>oFb|Y_)LM@T_;ar@f0F=~FZD^D`F<4; zTwf7PZxvz70Lo4QMokN-Z;DsOzt^-SZ_MX8fV?xW)XnpNV16Y$h(9VGX%g56ABFCI zcrSns`I!UE1B5=yh>QD`^BT4$WM3)>M_$Jh&~fH3U9w~p(FY`jLxudNt1LaC;ozRVmU>%i_A+< zrxpmC-^;~@1H==yiiIOH>!H`>W2fOC}0ivqB| zksrDWz&sO2o`bqBGN7y}Bg%qw=&t~jRaDu)Tia3LMar0T_@iA4`_W&G0K{W_p{?-D zc8I*>0nD=k6aZ4!HjT(=A z62>V3C_h3tF6;U{fb}QLGv&a#M;mi5v=A+lCgrzgfpVv;nHE6-!ev6fxFr6s8{q!UQ`cXQtmrM_;2S`HagD!tzz9}>2cM(9^+6;Zv8p0P0E$pa35Q@SR~ykKt876Tr4>FTR3uXPqnogf8<-T5SO7 zNt-(=J<5hW@caPs7UX3T@4>Po%^)u%zEfzw_()TTx%{hrOmvrJa2kZS=j^<$JNkQT31Q{KL{NKg?y6fSd>la4+Q*jDIg> zhhzuZ^M|P&9haRMs|EXdtZ)29)w{Q{Pctry;bkG^@m91`53}6w#b({BoeJ8zGz89Z z4aYg;fn#C?p#1l1dw`;UqtM&W7LpM2lLT;VPo6T?Wn9_I$9WO@6BK}Bof4pHT?LnZ zO#th#^tah3ryubYfMX-Z3(j>BH>%$AY=phWwUP$=_e_UlIHtw%Y8@c_F`WLy5!-{u zk@C&*k@1y`BRT#Q+T>dSM&(s_Bu(-|nau(eAP1ly(~+}4gzr()QHXmJz&w);|g zBsAzU9p-`l#GxN~Q2>!ApIL4!Gl@%?GygItz_|kAFc0!e;DMk3X+Rc0IWm8v>N(>v zj4f!P=#n1m**ZW0$X8Sv@ZM8T6vCyBkT;eqZ9b3amia$-J}0rGF1rQ zOP-_1P3)GG57Q$}@~i+-znC|X7i|!6m=E&E{L&>3{S+Vu5cx=*D#0&UFGas5;ZHe` zhiQNUP`@_-8360cUbrFy@M-4?ewl(l(`UV-&huH~(3Y@XD?r#51?z{{AmWW;D}wcuaSmF4 zRuG4ElXheq!2AiHQim1%$RoqVZU{cZ!uerd8J9Q`hwro}3P3v)Cr!aldEon#j&b-i70H(|QNjXV6 zB75e6a-Ri=&fsz6`mh3A(iHl_pMoFDka^@Y`Dd8OLGT$y9O5!e0mgb`AzDcqSgh#eRuBq)t&66=0a{W>~l{Pe0ONo>|_cA7z)rx-bbm z@<6>mjC`yjUCM*~VgpOrmd(Q@d|m@kZY)2_BV2w-_>n(p z7g@&A)=2pktRHDGez47AK7(a0@}|qM41jGy8lV6v0C}gY0HQxqX4GxQjnait<0ATj z<#dodD$u8Fg7%eulpX!V#?n?&_WwV7_XA($+&_N&?5r}WIY@@&lEtLj(H|CJtF1Ox z9c|Sl+S*QSTHCQdwUSzdxrHGa!Xyk~2#YX;Aq>%OlA)U+8TVGFwz+<<_jP@)v$M0M zeDC{v-@o7E=R6*l=RWW2bA7JQzw2{d=bSZ?mOkCz8Y}xHpY*R>S8g_|jKF@d`d9i> z`cXD(9%%e*^{321|7*n>H|yGzyb_Z-%e=7a;6MHn*Vv>@a*fH)lF$EnO7d9swXSW+ zcQDVWe|-+nxjzr4-=zO#zF6ZEIPc_ryNro!vQJ}^xhUf(^H#=P##59$)^#4i&(=C1 zb5Zuod89mR-dOW%po&Qy2D52wvffQ$OJIv-`=h+poRWI@&msR~oa`IMCTqfJY(v@p zn*Uv2hk@&a^p(bz%;tZ+TH`C@Dc7rvzs4rxAY&rquCWDP=Q2mE>syYMxgl#>8k^*` z%8|ItIT=%l%YI2qUMr6^_8PIk^Zd8wzyI8#T3y~hq`ubtl=*G7UHrfOeSaKvlzWA2 zlaw0nuRW4S=0xE2DaXiKBI7J$yuW)~;C%AG#;tjzas0uI_dxQ=oRcy%Hfs&w$Af-f z8aQ76ue9$#>F)#0>qN%L%_jE_ zc_y~*6BD4)_iNsnPLZgzcr3La=pu1 zVBMdrIVx+1tT`In{_f4PFYrCG#H0+F<9~GDm3>matT`InKsKp^tZ!Bu;`mwaO|o@$ zfBJXSe*$GoIpf(hwtrXMDavTaf!YvDKC6GF{W2D^hRe9f7)U>AYzOn6ZUOn^cx&C4 zp5W{F&Q_>o6IKp{Qup7 zsdg? zTIPYqcA$AQlswiZ`Tw0`PjSZU&y4&3OYQ1vjI8+^Psr?6=Wk~&`9v_}4BlYqByj}7PWRv+@Hft`(vC^Kv^90Tz$z#nE zxxTG7NFT_#Wju$nS#3^IaoKMj$B#z8{5$$V+LFe$zkZ0!Uzi^`J1cMAg0wt$q*_W-U8UGHd?Ha0gDc15F;YzH)wPvsE`~lhjQ% z>w4ArIk0YojO*XZYhAl?pOLj;B3lfbtR0DLacmk}GTS8ev*==zeUe{ev(^*q80pWh z;u5p|HcnvOq`a=`C1p#UWWAE|Wj)c@{Ocso-*UXfG&adA>#S_jE{RJSf$fsArA*l; zW%$p7f2BTSRk>1zls%bEWBZ@hOWJJJ?GL6*rmQ?&|Ho!r$Y*O4(z0dca;sHrz`*&1LwU)Y@*s{wL`{L@=9B!9GQz6 zn{|!Iypp&)AIte=jO3hFzOK%tvA?S^waR3-aX*rBr4QvZ4eOaip7o_}61UDFeKCej z>LO$OXXiMF{OR-kPv^YcXa7vQq&){SXAd+E2b!<@JCDZs|7fiKYBnHw6L)LHJa*0pc- zyX+st=0Ar>`qnXxpC_?()h4N*e}73`=doG+_CNW&LDoyDtBkL8zmmF2+434FZ;yG& zd1ajC9MX5vE;&wiYHV?AUClH9d1I}${^K{0<78cw^5tjABkiZl>x%1qSv$AsYhZGiMWoH$*^M@3jIU+LFojEyZJFOYgS~8#}hd=ciz0*9OFk<%w*oC4^8)YY_rDZ7UmT2*f&}`W0>utnKq}< zowfyU%hQL=_Ck&6h<8j6dCzpC@`}x7`nLB?&-=*q#ZOIt`o#3;k4#>GRAUE$XH6hTJuojXPM8|JaO~0#KgdHmup8}=U!=( zKMQNT4)**BgwFXF;QihZ#b(Z@0zh>p;W^3cJax$#<3_Slw z@D3$!&|vd@18IJA@kx@KC;fuLd{X21kOszFoE$e;E6mBynv=uZjI5l3(~P1A^WXjT z^+5KeuxV^v-2)^p{cT;_l9q9iw6sOWRr+1h(k6{f;*yqq8k@BiOS`2nB`$5Z`ch(Y zt!Zqs&wow#?|&&rj?>sAzsw0qOMPTMSo6ZaY>8WC%g_58)1mD19}Bq;NIC!8>slP= zka;iLB&A#f1KF%`v96a`Vp1pR6KRXIThbbv^qX~GwqpKm4;+(&=|BHIiKG03t><6! zh|W^4gXy;<^2(UW7+Tkg#?Ke2wCt1dlKnEK*0rbcvwUtSG3&aKn9NzZrsVptj+1Lt z^2t1y!=|wfWRq)F@@Q;-G+(SWK1r*o=3QW&WDI1i{nrALM!Wwv+I*lkXq;R6Cyho}2b zGT3d){rIl9BaW*|*l^;t*T;S64WGc#bNHmijcLrnY>QY{*=#{JyTdNnY+&og7Q*IW)7YZfirI_|zFd+cnyr}47wqy-*F}?) zlBZ0amNNa48J;Wh@{2jqV^egU({ip5&J$$s7UIx?4z>;ltmJ_+1lc*K@t+WfdG=@; zVbw>YWwa~Ej5z3pAbW7P?$j~b$ZXY@SdT+Oq$Jtw9ZIkj6C_;R;VhEy3k3DFX|BB7 zba#HfmYzG$lkF~WXAG5#@~<(G-tN$&|DiFF`Mlp(@xTj>eJfRtq{4I=yt6g+!|cNB z?1g?qX^YFt%gsAmo02m(CwD=P?3u^s+p-)PFSXnF7(FvBU(3nWW@o46XY%xGeuv6O z^;+8ew5;s3S=sKPR&kRjP0(g%WxKWftVMjXpX-(*3pBoSP0!TaMSR-MN9meTs^sW= z90l+-E#DZ(VKVd53bHtXwjiq@umB^guY@tVxdpSbbJOQ)ZfTj-5Y>)k`4Yl7?RYwJ(BsL?lX-8o&L|)~)15vyzi^&) z9(9I<9KM;z%FuGnZ!uIfNxC6-w&v@XfG&~mKa8#-58rqfxaUb$DzA>8k|W(K-;@-3 z_=eeS6qK2p?Y1&Z&Yh>llQ#Ox=wP$u>Ug8Z>d)_-BOw{hQ`>nk6V&Ey^y&z&bVY|7v`kP*HqTD_Dw8}nDOX&h(=~U()-(t~Ra}7x6i!UuAtw5X1XCGPf+#M=-TGz*`NqDdYbUJ^Yn>lr`NBgdy z_WCmyjRqPca^MDZI=?Yn&AGq_0J+*cH><}&v-4RoRsIhBdf;)FrLx2LO?Go#&Zozj z4IO&bI*~e0`~1kt;ZkAcVVyCn#9}L7K&mURQ~va9nYNv>s(jq@S#RcPY1u5LEWIq& z9UB^uZ+4#B-62!Je!p^zrD#^+?Ab=u0`ghqbj;M=uU5UReDl&g9_voxKi>lL73Kuw z3^=dCo=s>h!@eq^WPjd{Z@ z-l+Ew#-PBR?tkYV%l+JVqA+H^xr}fbyYptJrFU+pud`&a=+u?65*mGO?lm5l0{gSQ zr&OkZ{x(-5zfuDBv+A22Z7f%Q&s@IRaHq6>Jx<|W{ zaE{!yJjO387&#bkqeuMaMT}Z8w>T67n9BBs`C31+8E>cEymp4VSXefy0p3Oh1MZP zi5fQ`)|U?Xe9u{aT^9Hls-CmVd#9@Rc))2Ej>q@kTfKgUpASSo6$a#tmi&gVyt=~rm@E3rtxSg7s|M)#*?2}eP934G28%T zV(^`KRatqVIFHSBQV>z9s7-wG4FlPlDy`F5oF)=Ss>wLzZ0^^z5n2L;wF_!}C zH8#zYUr1Hd+ah`9H7+C`dRfLYn0L83?!ms9V8o=;dKznBq(_UKrA6kbe)Su#$?kN1 z`zgneM@q>YN~PbP_<(s zsOL5FD)C+4R=-HqyK0MiV_=-RAeU8)-+uBfSuw_2QkmO%?m4^_l*cDkf9^2GrInT~ zYwtphYRi4iw|`7htd?dRt|d(J>(9ijoWi2^3*5Q@VhU-&n8K{=4C@BGAk&>=Jy6M8 zMJ>*FXB9Z^)^*$dUQC;pm2bR#<*lssPR&|neASZxZ(FUbl&ad*{;qUCZyU{tOl|Ws z3kx!MC+;iLw}*?lAT6(8D8J?BE0_D(sRc|g8l}#yZprGrenD%^O!GZj_)cNHXPpo; z)>@RU4pHS;IgF=Y<05659y@{M&RjA&6(!fM%x+dV>9ZH|h%fzMjI{439`_f@dvWgMd4(S1nMYc@pX23rFd@A;Fk$ex1-h zPS$nMDU&*%Rqq%|o^L*DT*zZ!r}rPm+F&f++|lRAa{x^=9<|K3>}l=C%VVUq?)ci3 zV0_3Em@6%h_t9oCM#DSqHwIqSGoXH*r>4rsQ+ty6v7#1mh})bZD&M3S>v7lj!PQ_* zZo2G{4p5KI#?xIIAHeWo=9q+uM!y7pB-N?J4i7vX_sV^lYcnfHRukSZ`1+^IaUaV= zM4o26AJDRMxf%i|Kwt*dM!$I}A3d2Pl%2Lvo;Wl3qCwudX}%9OX)2F~{EoQ%@`ZV^ zwa*`;UYTk9LV5ecHBV-~qfgB@|J@ITSbf#udTsyQ(04w0gz`M76 zhuI35m|RH*{Fu;Hq??nA3pmiSAzt*#UmiZw)rK@_V`IFBBz4_p2E_iaCb!eAw{u?7JpK2{I zZ+X%?lGneyz(oYvsCEWs{-0a~swm&mF9YCvha0%l_+ZDk*VkV4 z+!xql=Bs%?nwG;CU#yGnY;)~U<#v6XZy2ZKSP!a3er+tbTs3e9z|qtE9!|cqme(07 zE#Lgg%cau6X3|!y(((nhysA{XyP34@Q|TTm9d?*m{vj%TnM%vI-tts&tJ?AEVN?P&0p+N=K;lu`2CS>El$oRHcts=~|WUr_zqY&GJsL zj#ugaDqXD7C#rO{N^2_JpwcI)beO{|Z-7citMth#ovG5{DqW(|168_GrB6}mI+Z?E zrEN!;<;(BP$SXpn<#%S}CC=n`BPN7Ql;g0{p8i4($mbOO*_WSFTcYmuXvTd*i72W zReHKgdsSL~cU@koVdn9vM#^TpSEbWbx=N)zDqW}2^7}*bYE2O^dl;rqS6&AU98fNs&s`)Kc>>PD*d=h z?^fw`Djn9}Jl_*49i`Gws&uMKKc&()sdS}ESE}^WDqXA6IlrJq&ls1wcetyk$H zm3~g8%T@Y$m9A0g7gYK<%{;zJrK41OgG#5U^ouHevr50D(v>Q`QKcJI`el`No@AE) zib`jy^sCnKDqXG8wgG1T*Hk)6rC(R+VwHYNr7KkWZI!N5=~|U`oNSi&kxDyN`eT(& zQRz=qx>%*RsC1=Df2z{9aI?J6R60tfx2kleO4q6Mvnu^}m9ACkFI2iwr9W5c2=#kP zx=N2%>4kmT^vy@N>BIZB=~o}qra#D*%+DXO9m~%bv%SGKGOSHcXDeab&35LoZTjVG zPq3YET$^6X_B-3~px*>AJCsCNm5ozSNDV(Z2x>9V6bZtoC# zm92$M_V+rmP5-68xve|dv>*0jYaP(0?_k@)wuw#h%C>@^v)K~aMzi%}+j&x(zLBjD zo0KPIZP7Y!68GQd|Fe~Ubr;83`xdir9q0IOZpobgzq!qz5B{6mHZ^BvC}j*~%p+CW znooae_RIf9KMbbNtGMpwv)#;g7uz~ES#xCT&Cg*f9gdM~XS2nrm0rm&x z4@{r%FCHIQ-k(jMs?Pt{?_0}n;Qx1i-&z}@4b1=Rci#V-{|@1=e{W#?3zYxT{O2Fx zF#U~x@e#!Hx}8lvrwn0puxV`3Y{hKkQvZ=$k|Ua}n9bO;-$VcUH#joD*1y~7@NaNz z#`@zMfdh1;)ziN2{%Z`3e;f6${W~ZgPDW(#OwwsH<~9F1?XTtN&&Zl z^*=P}wfwx`rzYKtccCNJW?Q+lNq6GSKR4+vd>k{;`Ad^tiqByM_G)a>BlyC_gB~ow zYT|3L4y&;dYcYf`YNCE^(luO;QCN#EtjA1@|E)`B|E3Cyc+o&II zNBJXRA-^~2VR$l@VvtTgT!bMP*la&w1V#rn>+$$7X5uFF@Nw-S_GY~tHFR=Z1;*of z!OeOquE8SQj>R0e56iG;w`RQ(^RNcJSdaI0Z`Qq7i}LkjzaGtc1g^zsd=XPH>X2r= z1e37}E3p>4g*598cmv8G>O3Np;1lSVsaCKe#usg!-WU2I_;y|Be2` zJ?O#3H_`w2=`EZer{2bS`J(p6mDCsK-a-H3PAtbkt7t#QV=czq$#FQkjB)1+-GO&; z9()Jm@u<5g2cN+rtin>;y`~Vy9N3?NVzXvE6hoKWIF%?gIkal9(T8_u3A7b3G1?zF_V~h)5 zKo4BUaX9Kp`Vr50ig}3Pm7E{H!*bk-RoIHPSo1XXzz@-O3D?gv)C1={OL^FY@i^jn z%EK>TpgbI1MS1u)tirYp%ohxPk$%T57&3$T^Ah8Rp&OYm`1s5852n0A|KLklf;(Sj zym8}el!GhYpgxz}jPDjxNB>W3LvDsim9sLv@6>(Ptjwo%S3)&q3nVP8@X#$hU6gr&F=D{vhap%<$$ zcRTIGE5D*V+>BxAtmE~Rhj|!}C;UJ=F$GKTEiA|FScSi0Eqbv5m;FdPGq_$c44>V_ z_~9;0!Qat?vwxvHEW>hq602}j(hG7{F!b%*CH8>ILF%`X-hmJWm zTPa518jQwjOu>)QgN;~%_Pw+hdtw##!&*EW8!!>&kC0uCVYnEbxE$kg6{g~SScH{W ziXUJF)?+pPj&Y&2mSHVc;x4Q~TMO;S{^-Tg z=(wEcPK>}JjK)=%g6q+PA7cqNVmS_PrTusj)?zL;;7urh$IyivF%vgoF@A<+xE(985o^$k_1N=w z+K)$~V;<`@M&MwK#`7=*$Ds#Pumn@F9P_XW7hx@~zy@52@<*;7#xQ&momh?WSc9qf zITqnJSc*+pfvs4Lp*royzSxKn7?MkUP{S0A!ujaJ63oPhu^6kc3_rt4Y`_}qVcV_O zV;FkzOmui`w(~Ipufk}&7E^Fz&~Cj5AGGh*EAYPH-Fgik*^P2=L-*af{E^h)!*=UY zI0rMa7&TmtF08_0T-s~5UWVr#zFV)tO<0RMHsBEs%FDCaj>RyHKqp3GJf4NAI1P(% z1D4`@Sb>fscI(yn5H{c!N724~j_*VJuwP&5gT0TTo)~j1$73E=;I!kZ4?c+vcw+zE zdPo7+#Yxly-$ECLhI4+Lk7d|5g7e~1tjF>}99PKoFoff9@KBD!^Dz_GVhL`-a{L~v za39v&)E_?@xm&Nqsb_LL&O2+j-iSIn7SOIy zj1T^R@kP|{fz}! zhqsPnK4aN<%3H*ILnro5q4DU>Vk7C59$ZFO0={oP%Ec8#=D!eE>#aEk@%% zF$Mc3(_ff~C3rQK;|8q4U$7PjPNBbW2HF zl$SyM@Cl5^;hD4-&%qKLgXOpstFRnv@ilC~Z_u`s`G#S5XcpyR1jgfdOvUL~gvD5j z4`T&>jMcdGa@vdfT*d{R+0?I?_RnKnu$PDOa3H4Q+&t=sS713Vz$zTNfO7Dhg_MJ1 z(6Nm9dL{M3hcO7(Tgk4L4BGq0()M~yu=br!TZpI z{jQ-Oa2S?jCD!3)Y{Ui(p*`J}Q!lJX7uv6-UYLc&cmLaapR^^7w{VFR9z+$?P4 zF$^c76Q^Q4UW%#c#v;tdQk-5&zoK?4^}=D;h*L1+I_h&9?ZY0o(>^>MQ*ab|Fntx} z;QLr1-pM#%9oFHc_fW6vIWLCc0~m!H(S^z!2RMe%E2es(LeY+rsBLO>2G|e zl6v5`ScPp^i^n`oe`74#{>D0qVOWk%dAN%*QgIZj;UCK zMffh3V$SRI7kaT8&w7(`@I3TlJUVXTc@HD-g|{gW-+zaG$NKju2S53cd5M?RQXl*Q z>+!^oY1hqM2V1ER=3x}RhAy<%Q4UVQVqAq~_ybnr4WBc9`1&@=xrP3zryM;0Ys$ei zbm1z@#1F9;L%yLLjK)eV!Ww-0TlyP6L|ZA>_4l+3zxjc7VdzhkgSTQami|ot;1^hp z=k20C_y9KI;lD7SZlxZmVJ1dlF1qk;%*3a#7?(Ct9%k&JKKMP>W44$6#!__LM*H?s zFZ>9j@q>NL1N^pyaxklv_TgPvi4|CbRalRo{!aUDXTIpv3wzu4=+WrH6nq*z7-iq1 zm*N@S_vlsF(qoTahy4!Oqc`FJ3|YzhH`H(#Mqxa>1U%#ZwUOfGjJ$l$G zo;yyZ9DF~5cHyV!!A2~>b57f%mt)Kz%E8U2@6qe=+#!2(+nv16$1qGqCw__Xc#o5E zaP}FLgMEfkAG{i?@h7aqwBfW5H=?7A>uJOuJp!M=Xp9<3z3^%D;IvVD^fH`0;WqSQ^7+*3Zu$o! z@XcuIg*v8SY7F(lUSnt{F2Ztr9jkC)Ed7Nu(Tm}6ly?vJQ;fj%<0uaYjHf)zLl3@$ zCFsR+oE=YjxD;#g4Q#+K5-4vq>+1#dKW@5^cH)ji<^yUIm=Aa}R^WXTIUaXn1FoJ# zf8EP<=%T-H8Ajoo=tA2?^cUt}G4`2Ef8nwu`U_veI&>z}K70Zl_idk(Nk$3zK<0cGL7=^7_7r3*oeiKGQaL;d{Ze0|A8rZ%q;4I_hT8l(&-=Um%;uA zSYNOlU&K1%pJ5~Zh9Tu#FK*h4f5Rx;h%VfPnfN;vL){BXA!^ltswRIFc0Irw=o^}ym~v;&X0ntI^MYpKUW+@G$aUorD~#sfb`58hkC z@mO>N$K$V9gNZkCJg!_pKRnFy(oKvHzJpP?_GZqHC)~ok#-dWj1*>nRKXKS?)B~Hb z0c&rk9*^)n%}V+M*WN)paOW!e124Oi@x_zMCbBQXj~%jqZFf*!11LwUGq zE&YURAEKY|x`!Dr%z1?R;q4XF?=jY!M=1xte~fZ4JsY;M}({jgCsj?|tfpBR`;CxC1ls#Sf_$ z4)}<1#PL{-SAI1W)$o#XM5ujpqit!EzLfUh|}Zuo}!gi#pM!1{yXKhO_& z)=!)l&)7+S;#XLUE!cn|KU4qp%s&jnMd-wh7?0VzsE4Gn2>85ql!t?{21j8% zjzcddq2oF3(-?u}7>!S13da3LdAQ@Bl!tqp7#}R$O*xpghjQ>3FZFt!&kxXvhwP4!e#BaKJ^?3X^#H)Mo>qEVIDZbFtt5@PDScB^hqa56TUVIB3 z8`zH??Ayz$H{ei=zzZ-MS78eF@9ot~@N6u{Y^=hou@-Hi)bB;!mtq)(I5-|pKf6C-FBu04%%WIvW;HCACg*5cy9)C=z)LchGie2VnyQFynL`e4l&vZL`aIap0gGbOm`0Pl=1*^}ZU9Ym9N6{}h_iT>G$Isz-ym&PIf`wR#N1V&JV}Gp2 zVd%y4(NWF$FaldKTGHoH9zJnC<>B{OicMI7LDAF)KO94Sa84}cyvFrCj`rYAbYUxI zV(56r8^6Xf+!ar~Wd8;9FZN8NKDc@U{rWoB`$X!2mrtT!@j)!YFR&CFumW4L8V_|* z4u)YP)?mmRq%Wd8oHv>Ba4n|b)9ArhumoR9V!W_dGUJ6yrqEA#BYLq69h;aR7=d}y zXdkwuP!2A=m~wF1bjrbuODIRYlyWfdGOmX=xz1BL9!t`gH+beO`UfXtF|NTfdi5f1% zC>(w{V?;08P?{|F8nf=`Hb7Hpg!0=pZQ$F{ck?~jG;vwk2|m!M=j)doQ;*3 zk2QEb*5gX_;sfY-hx#mLUgPOk(Js6aQ*rGQ%ERqghCg8?hAyQ%oK;M_u=Uvtb zbmG=)79s zFsPK{@%dXh9=F}b@tb*{aXZK3!x)9zS8_a-t)d;c3(N4Pdzi=g$!dyO`{&+?;^8@F-#_@RE>l}}#Vi}IWN^IOjJ#gTgl!HgTML8ewe)VnYgJWuF51#oh z^8z`9I-({TCdM8!#T@k9&^5@9{4w`!C$c+e@8Dmeqerm%KKc5!c%`_d~pP3Vk{QpBrL-L zKT#e=?xZ{{+C{r?FNS=^I{ORdVV_?aCmj77?ZSEgq#Qi0nf74%ZjQ$z_Rt>8K-*T@ z;iZ4D3Z1C$rGIhCKH7!-TDb0TDwbm@R^cbDv$g`g#k&4`^(q{EBK?dX zVI$r%fO59;x!cKm^(g#X_+C8)UqBCT!V>%l%W*qaVfDbhdM&1$LOIxmAz$(SEQ0#r z@q_m2E}V}Zyar3K6wC2mtis2z7SBGN_Td%`spoz+c(1PEJ(08v-*D33*#8X5!3(h* zQ?Lr%Sc`esfc9bZ)7Q*1)bQBhv=3*DpntFqi?9((v3w-sh9{iKxMAv9vJ?OIQ(MT^&R)=8O&q+;2lQag9Qp-+!3vz6NqP8E7X6D= zb1A2ReA(0k&z#5j;1W#1?dZX<9Qp+ZMf3~K!YVv}5%s`C^y0s@SucRD&4&(8z#gv1NtLR_ciRI{CLOFPC zG38+I658_<&-tif%nclm*_ev8E9eg#aTEQ3tFR8c-%P*aO&GG1enkzRxQ+h6Z!iVt z+)jUBHJ0F8SdN)1sRzD+wK(t&#u-PiqP(A3H_GT=yx=bCgD+qz4!WE9i=p>2-uMbu z;`R)?+!gY5VkQyzwOJgV_V954K`RGwbKc`}7DL8BV>h7E|!afs}_s zPNQDf@AQ3o6+SqW`e3g!Ies^vqmSZv958yH9xtA^PtQc#IO>6yOrSmJP1>i|;-S+x zKTb{Cr#tpAt{8#eVKgqB#rbhmI_JlJ8I*%(VL5hpQxAM>HtoT)=TIK@&!RjppCe!d zzJEF8VfkFj!^UjN!^7uM9_Hli(<|`nJo*`L%%@!vFQA|IQeO@30Y1TtYwXWk{*Ha$$ETKGH zd?WS3&u^k$=(vS?wXlwrQVuS?mG3!AY*_TND{_}VJU!SFjN zrcAt7#8jbszoQ#(3OMKjVw#j5}_8fO_C# zYxn8JxaMKX!Q{s{KhDB>^q?1aqT_e^=Lz~3`&UvAT=NY5i!+|3J~&`K<>1ces1L4w zfpYM5^kOYKbk>;-l!FZzkJrCQeK6uB>VuhBhB+H42Oq>bJnd!Lg->CKEy#B9EA%f$ zy~;SD3td=_nfNOfV@fsU;jLJS?_mx0dX4(wk?6%yZ&4oqufl}48800C0rkSlTFSxq zunebtL^=2y*5J;MDF@HrLOJ*{%D=R2{gifM;#S%zY0Si=I?BVxuncGXo$~N9ATj%N;T(W^0hc#B?-SDf3T+qwtYvd(MKHGJay7Cj!KjidJVQ=J?Hg zj#@%}upHyDWGVH*)mV&cunhYxqds`v)wBy|UqgK`{5s0%$-F6{K6nSZ@Dbr4T!+<|eJAz7 zJZ!|+)zqg~kgfWD>Vr8Cx9BO@{b~9KYhR!qcvThkz#})%Kls3lEqVhkdACIm=^bPn z|3ix&fk*#Dzu>%`vRE;-%J1EhF1DFG|2Xk;8tD3)NZYM6s|`X zCU$StGjYOEt$Hc0iEP!Yu+Z76*JA6iR=p8lII~rE93Eu*{OnfUiRYfr@mM~#Rrg?1 z9LM98<689!ymx%7UW3QSx9auyD0*=xIvhbZ#|4ywB^ZyDn2JfRR=pT!U>Q!mi27g^ z)}kw!`rtJex9Sl`Fs{=%9(P|tJMh9wTlI4MHI?(?p|e_b+mS)G8{C`^$IhYNSUI;< zFTvZh$&c^PYt^eUBBxca!$+_Yf5(uc7^hs$hj)57AEsYHeK9hxRWHJ0^Jzc!C~Va$ z@k*@0jq_Xe20W#Ra{2_>o?b{fIQmM;!H~t2gU@0So_ZDK;8|FK`B;swU>!ccgnHqQ zrS#*`LAJfiTJ>n$eFx=W;yv^qF1(L+;pGo-Jg!?yJ@DZQj_Vs_>;D-2f$w2FzVJB5 z~9YcS=zkAG!XhlgC$I`PV;z2nUJQMa;Pn`fhkn5P!COA$cs%VRj>oN7gAaYo@p!~19Dh9X1S4?47LLb3 zpK?5YiY2)4GmgiEtsIXv*nm5>aeP1K+m{@VW4>ZO;%8rT9pQ!FF#fm}EAgFgX*Z78 zLA!AYhMmCu52Nthf6#9@9gDCW%P{LZ`VAAm=XhL&UL5iR>p*|{<45X^OE43^!V+BZ z6ZOWUex}}d`7Y{>-(bjz+)sX?-gsUk^~OQJQg8egOYxz9Qg1x7nd?>3*ob%RX5MMs zH}^2_@KtnS&0dbjtyqfRVI@}V<9O`b!uc_`mE%uhoyG`k!f5Q-M*DFBdN319a4nW& zC03#BcgjNtHlT*K0YSEC3_}+>F%{#{gQ-}IMOccZSdJA~jn(MTS!Xa6Z6~uI!%(xe z=}vTEJT~@h(~BhDt4*)LRQ^t7SUC0K?^d8@+8 zf&6VXj6Q|(PYJR)Pi@mvF_pjFR*JQ!wdu9k$lri-oJ##qCm)t#JURwb9%@*O(O8By z{x)0#R-!Y4{rt_hR4m03tc`5bE3wf@J}e$a{Z1qQaQ0*B2==2klD|oZ^jJhx&IK897q-@;lv@&d}oC(*|KdJMze=){5xX+M@?DfUim z(<^WVR%6fv+JQr{5ih}zq1?|U<$ ztd|&uCtpOpa0bR>2BzZHB+A2xWXi)!uo7>^8r+BVm^+33#x>}0vQA+HCQfbBqcJRn z@=(JfTzCoPVKG)>3D#gK)?*oZaU(j;U>%!5dAJXw@gJ8mK3H=Z!3{QVvc=4<2?o^}@5T5*K1EzKRWKpG&_D53=2aVfY+6 z@oS7n&pgV(N3aBwaw!L=V-03tJwAnA?2$(~BZ6$_%%?s$7E|yN^k6!cpa;vb7^~2+ zfO1enFFMgNlIx6DKjXiArn<;A*%nmf=n-6TTD0x>UWbH~8X3abFWa_WB#qQOEbeM79NwH0c8*78~lgl)X}Z2HP^?ycPBxui2Z7!)5<+wiy*o zI&ZoC_W#q^FXgUfJM+;d{RG)hxha$@b=t^w4)JR{)N4tndhH-z*<<8Gj*qq%hlWVG zt!&*NZ_=lkam_y2jQ63uYU0PM_*Bj(`ME@Go4Sa{60aeCxa3za$v;DtlW7G};swMV z>zZ`wFY6`o6~tq^h_5AHL_Dzkjl?~~1Iyn+yqfqKQh02rmaXc)llbSvuQTIL`!ch= z-RykU_C)9W{fN&ZezfFQFRAAU;;F=!NQ|jqUuc$-Nc^oX@@Ej=)J6Wq#J4ei8D=?} zeWqE?O5#U8*}4DM5%1eYd=qgm<%F5#IFi)7+eW+_`S}Q&50yfT?e=>1m@k=kt?b{- z{salBd9B&U_~vE5U_R4fzsGOC)1KwqKbrk`oE%DgOCVgl?d?WGc#79UxHZ&|(jq?`b^NC*?kbfufmx!-4^E>UgsPXT{ zXG>2v>GxUjyUch$;x7{)7f{X!;y)3;(##)apRdNB_{3-U+caie%cnl!{G35NhxlfR z)6du0V?x8O36?AIjnFUxEF&@=E68``vrYOsmG2t6{V{96q<_}2|33B~Ci~S(;+u%y zO1zg9M2T-Ber*@=CgO{UXGngTziQs~>dtjcT&)Mu)_M?5{E+pXBVJ*a79=NV7mv|L_yT_`}HD)=hiKlF6(pQ=BX#1^Ze7%%UJl%|I z_RGxpX5s^0Y|=-o_yW!={kntrjhuJ8#ML}^*|+-oUBayYiN+1!5aR|AY~2AyurHkL zwC9@ih1hNMfw;rKwQIV?hPv$8p&9`SA7hS~oOebKzN_H4Tz$GS3 z&byfX8`wXMb%}9s1y2sLhTEw3YW6oi-=xp>J6;wEnJ+TF8`*#63r%`|+0T99V%5)E zh)<<|0{eL<@#(|^*U@f=@SP#?Oesgbr2Kxw*ATx>Vlq$EdO3o)gMNP4ia%i1Cz1Gl z!~@se4B}P91K0b-#CH-m#$C$dCFfm9e8x+i*WGo*rxOoccQ+AFq@Tu00j&2+R6lGZ zUP1oAerO^-ll=bcrJT1{2MvWewWYq^Fs2%|647hZFyl z_!Kklw7bmpYBcd9-)zz^2r|ld2FJC}U+K3Q>>vGBlYW(TT#;E`0r3ZjrZhqq_ z*Lx!Q205Db{zy61!NGldTII<8Y~m5e@wXoMnf;YP_Bv~~QI8euZ(#qS(ooqS9OUaz zssB3me{_7aHUFcn=Z;Op&+5nDVvusxOY(1%^ASJR3ZlfDh@VE>xGvN_iTC2hGMKn= zUHHYrRXi~NXyTFN@2m0((#~Y!Lx`73K&`i${RZEBEnxq>?9Y(>T(5Hfk$zr5{0HI} zO8eDu#X-TbK>_`|o_xLfH|xL3@hV@m{YPK$GOA(~F7!N<6~Mucb2^q@0z+g9bF~(w8z%r>Xcl;@!K5Zz6tZKwSEB8}Z)6 z>;2kAfBxOSVRF81z4o5d;(fz?^>bMD8$tXO;&KkDAH!$#Pa^SQ z#1kZL^bZ$`nv}-;Xa6Pa&-d+@MJd}iZY$XTB>M-+e&&Vs+_08-HSx1lJWut3lf6QQi75h(?{YHPJbvWN*_P@k_bsy5?x!o9l z6)%zFq>I$^&^qF$pW58v{iWpJM0_N1wVpcd6eRI�!aAZIt39-bB2bc;J1p7Y_!T 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 Si3xq7R#~=kHl`c Date: Mon, 16 Dec 2019 07:58:16 -0800 Subject: [PATCH 22/66] [swss service] flush fast-reboot enabled flag upon swss stopping (#3908) If we need to stop swss during fast-reboot procedure on the boot up path, it means that something went wrong, like syncd/orchagent crashed already, we are stopping and restarting swss/syncd to re-initialize. In this case, we should proceed as if it is a cold reboot. Signed-off-by: Ying Xie --- files/scripts/swss.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index 7dde4aecb365..93f311019d66 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -161,6 +161,13 @@ stop() { /usr/bin/${SERVICE}.sh stop debug "Stopped ${SERVICE} service..." + # Flush FAST_REBOOT table when swss needs to stop. The only + # time when this would take effect is when fast-reboot + # encountered error, e.g. syncd crashed. And swss needs to + # be restarted. + debug "Clearing FAST_REBOOT flag..." + clean_up_tables 6 "'FAST_REBOOT*'" + # Unlock has to happen before reaching out to peer service unlock_service_state_change From 2c6c6bb33fbc9e5b6d77d87a7c39d820e7c8c2be Mon Sep 17 00:00:00 2001 From: rajendra-dendukuri <47423477+rajendra-dendukuri@users.noreply.github.com> Date: Mon, 16 Dec 2019 11:28:29 -0500 Subject: [PATCH 23/66] [sonic-ztp]: Add Azure/sonic-ztp as a submodule to Azure/sonic-buildimage (#3903) --- .gitmodules | 3 +++ src/sonic-ztp | 1 + 2 files changed, 4 insertions(+) create mode 160000 src/sonic-ztp diff --git a/.gitmodules b/.gitmodules index cfc6878c7291..b2ffb2b26fff 100644 --- a/.gitmodules +++ b/.gitmodules @@ -69,3 +69,6 @@ [submodule "Switch-SDK-drivers"] path = platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers url = https://github.com/Mellanox/Switch-SDK-drivers +[submodule "src/sonic-ztp"] + path = src/sonic-ztp + url = https://github.com/Azure/sonic-ztp diff --git a/src/sonic-ztp b/src/sonic-ztp new file mode 160000 index 000000000000..374c9e804a9f --- /dev/null +++ b/src/sonic-ztp @@ -0,0 +1 @@ +Subproject commit 374c9e804a9f434cdb58fa7afe0c3f6201bfe56f From 9cb12e6474c263c4e5d1bb10b4e18e230a525093 Mon Sep 17 00:00:00 2001 From: Aravind Mani <53524901+aravindmani-1@users.noreply.github.com> Date: Mon, 16 Dec 2019 22:27:25 +0530 Subject: [PATCH 24/66] DellEMC: S52xx platforms optoe driver changes (#3865) used overriding method instead of making changes in sfputilbase.py and changed the sff84xx to optoe driver for both QSFP and SFP. --- .../plugins/sfputil.py | 328 ++++++++++++++++- .../plugins/sfputil.py | 329 ++++++++++++++++++ .../plugins/sfputil.py | 12 +- .../s5232f/scripts/s5232f_platform.sh | 33 +- .../s5248f/scripts/s5248f_platform.sh | 2 +- .../z9100/sonic_platform/sfp.py | 2 +- 6 files changed, 692 insertions(+), 14 deletions(-) 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..d09f621ee882 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py @@ -8,13 +8,42 @@ 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 sff8472InterfaceId + 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""" @@ -225,3 +254,300 @@ def get_transceiver_change_event(self): return True, port_dict time.sleep(0.5) + + 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'] + + 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_s5248f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py index e6680dc8d919..911c04a0fe0d 100644 --- a/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_s5248f_c3538-r0/plugins/sfputil.py @@ -9,13 +9,44 @@ 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 sff8472InterfaceId + from sonic_sfp.sff8472 import sff8472Dom except ImportError as e: raise ImportError("%s - required module not found" % str(e)) +#definitions of the offset and width for values in DOM info eeprom +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNL_THRESHOLD_OFFSET = 176 +QSFP_CHANNL_THRESHOLD_WIDTH = 16 +QSFP_CHANNL_MON_MASK_OFFSET = 242 +QSFP_CHANNL_MON_MASK_WIDTH = 4 + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 56 + +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" @@ -287,3 +318,301 @@ def get_transceiver_change_event(self, timeout=0): return True, port_dict time.sleep(0.5) + + def get_transceiver_dom_info_dict(self, port_num): + transceiver_dom_info_dict = {} + + 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'] + + 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_z9264f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py index bb1c961ab670..70e0b26f7890 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/plugins/sfputil.py @@ -348,7 +348,7 @@ def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') if port_num in self.qsfp_ports: - offset = 0 + 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): @@ -415,7 +415,7 @@ def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict['tx2power'] = 'N/A' transceiver_dom_info_dict['tx3power'] = 'N/A' transceiver_dom_info_dict['tx4power'] = 'N/A' - try: + try: sysfsfile_eeprom.close() except IOError: print("Error: closing sysfs file %s" % file_path) @@ -433,7 +433,7 @@ def get_transceiver_dom_info_dict(self, port_num): transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] else: - offset = 256 + 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 @@ -507,7 +507,7 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): transceiver_dom_threshold_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') if port_num in self.qsfp_ports: - file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) if not self._sfp_eeprom_present(file_path, 0): return None @@ -578,7 +578,7 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): print("Error: reading sysfs file %s" % file_path) return None - sfpd_obj = sff8472Dom(None,1) + sfpd_obj = sff8472Dom(None,1) if sfpd_obj is None: return transceiver_dom_threshold_info_dict @@ -608,7 +608,7 @@ def get_transceiver_dom_threshold_info_dict(self, port_num): 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['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'] 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..6923c9f4b353 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 @@ -51,19 +51,41 @@ switch_board_qsfp_mux() { sleep 2 } -#Attach/Detach 64 instances of EEPROM driver QSFP ports +#Attach/Detach 32 instances of EEPROM driver QSFP ports #eeprom can dump data using below command switch_board_qsfp() { case $1 in "new_device") - for ((i=2;i<=41;i++)); + for ((i=2;i<=33;i++)); do - echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 done ;; "delete_device") - for ((i=2;i<=41;i++)); + for ((i=2;i<=33;i++)); + do + echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + *) echo "s5232f_platform: switch_board_qsfp: invalid command !" + ;; + esac +} + +#Attach 2 instances of EEPROM driver SFP ports +switch_board_sfp() { + case $1 in + "new_device") + for ((i=34;i<=35;i++)); + do + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + "delete_device") + for ((i=34;i<=35;i++)); do echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 done @@ -103,6 +125,7 @@ if [ "$1" == "init" ]; then sys_eeprom "new_device" switch_board_qsfp_mux "new_device" switch_board_qsfp "new_device" + switch_board_sfp "new_device" switch_board_modsel switch_board_led_default python /usr/bin/qsfp_irq_enable.py @@ -111,7 +134,7 @@ elif [ "$1" == "deinit" ]; then sys_eeprom "delete_device" switch_board_qsfp "delete_device" switch_board_qsfp_mux "delete_device" - + switch_board_sfp "delete_device" modprobe -r i2c-mux-pca954x modprobe -r i2c-dev else diff --git a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh index e74a3d6c40de..094c88eeaba6 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s5248f/scripts/s5248f_platform.sh @@ -58,7 +58,7 @@ switch_board_qsfp() { "new_device") for ((i=2;i<=57;i++)); do - echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 done ;; diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py index 87057545cbb7..9f5844d2058c 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/sfp.py @@ -44,7 +44,7 @@ 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', - 'specification_compliance', ,'type_abbrv_name','vendor_date', 'vendor_oui'] + 'specification_compliance','type_abbrv_name','vendor_date', 'vendor_oui'] dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', From 1e5d25b48e896c46ae31a10d2ebeef7dafde40a0 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Tue, 17 Dec 2019 00:04:42 +0700 Subject: [PATCH 25/66] [platform-celestica]: Update fancontrol service for Seastone-DX010 device (#3690) * [platform/cel]: add fancontrol service support for dx010 * [device/celestica]: add hysteresis temp to dx010 fancontrol configuration --- .../x86_64-cel_seastone-r0/fancontrol | 12 --- .../x86_64-cel_seastone-r0/fancontrol-B2F | 11 +++ .../x86_64-cel_seastone-r0/fancontrol-F2B | 12 +++ .../debian/platform-modules-dx010.install | 3 + .../debian/platform-modules-dx010.postinst | 3 + .../dx010/scripts/fancontrol.sh | 81 +++++++++++++++++++ .../services/fancontrol/fancontrol | 11 +-- 7 files changed, 116 insertions(+), 17 deletions(-) delete mode 100644 device/celestica/x86_64-cel_seastone-r0/fancontrol create mode 100644 device/celestica/x86_64-cel_seastone-r0/fancontrol-B2F create mode 100644 device/celestica/x86_64-cel_seastone-r0/fancontrol-F2B create mode 100644 platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.sh diff --git a/device/celestica/x86_64-cel_seastone-r0/fancontrol b/device/celestica/x86_64-cel_seastone-r0/fancontrol deleted file mode 100644 index 8d5cbccb9d00..000000000000 --- a/device/celestica/x86_64-cel_seastone-r0/fancontrol +++ /dev/null @@ -1,12 +0,0 @@ -# Configuration file generated by pwmconfig, changes will be lost -INTERVAL=10 -DEVPATH=hwmon6=devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-002e hwmon7=devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-004d -DEVNAME=hwmon6=emc2305 hwmon7=emc2305 -FCTEMPS=hwmon6/device/pwm1=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-5/5-0048/hwmon/hwmon1/temp1_input hwmon6/device/pwm2=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-5/5-0048/hwmon/hwmon1/temp1_input hwmon6/device/pwm3=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-5/5-0048/hwmon/hwmon1/temp1_input hwmon6/device/pwm4=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-5/5-0048/hwmon/hwmon1/temp1_input hwmon6/device/pwm5=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-5/5-0048/hwmon/hwmon1/temp1_input hwmon7/device/pwm1=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-5/5-0048/hwmon/hwmon1/temp1_input hwmon7/device/pwm2=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-5/5-0048/hwmon/hwmon1/temp1_input hwmon7/device/pwm3=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-5/5-0048/hwmon/hwmon1/temp1_input hwmon7/device/pwm4=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-5/5-0048/hwmon/hwmon1/temp1_input hwmon7/device/pwm5=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-5/5-0048/hwmon/hwmon1/temp1_input -FCFANS=hwmon7/device/pwm5=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-004d/pwm5 hwmon7/device/pwm4=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-004d/pwm4 hwmon7/device/pwm3=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-004d/pwm3 hwmon7/device/pwm2=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-004d/pwm2 hwmon7/device/pwm1=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-004d/pwm1 hwmon6/device/pwm5=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-002e/pwm5 hwmon6/device/pwm4=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-002e/pwm4 hwmon6/device/pwm3=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-002e/pwm3 hwmon6/device/pwm2=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-002e/pwm2 hwmon6/device/pwm1=/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-13/13-002e/pwm1 -MINTEMP=hwmon6/device/pwm1=26 hwmon6/device/pwm2=26 hwmon6/device/pwm3=26 hwmon6/device/pwm4=26 hwmon6/device/pwm5=26 hwmon7/device/pwm1=26 hwmon7/device/pwm2=26 hwmon7/device/pwm3=26 hwmon7/device/pwm4=26 hwmon7/device/pwm5=26 -MAXTEMP=hwmon6/device/pwm1=45 hwmon6/device/pwm2=45 hwmon6/device/pwm3=45 hwmon6/device/pwm4=45 hwmon6/device/pwm5=45 hwmon7/device/pwm1=45 hwmon7/device/pwm2=45 hwmon7/device/pwm3=45 hwmon7/device/pwm4=45 hwmon7/device/pwm5=45 -MINSTART=hwmon6/device/pwm1=89 hwmon6/device/pwm2=89 hwmon6/device/pwm3=89 hwmon6/device/pwm4=89 hwmon6/device/pwm5=89 hwmon7/device/pwm1=89 hwmon7/device/pwm2=89 hwmon7/device/pwm3=89 hwmon7/device/pwm4=89 hwmon7/device/pwm5=89 -MINSTOP=hwmon6/device/pwm1=89 hwmon6/device/pwm2=89 hwmon6/device/pwm3=89 hwmon6/device/pwm4=89 hwmon6/device/pwm5=89 hwmon7/device/pwm1=89 hwmon7/device/pwm2=89 hwmon7/device/pwm3=89 hwmon7/device/pwm4=89 hwmon7/device/pwm5=89 -MINPWM=hwmon6/device/pwm1=89 hwmon6/device/pwm2=89 hwmon6/device/pwm3=89 hwmon6/device/pwm4=89 hwmon6/device/pwm5=89 hwmon7/device/pwm1=89 hwmon7/device/pwm2=89 hwmon7/device/pwm3=89 hwmon7/device/pwm4=89 hwmon7/device/pwm5=89 -MAXPWM=hwmon6/device/pwm1=255 hwmon6/device/pwm2=255 hwmon6/device/pwm3=255 hwmon6/device/pwm4=255 hwmon6/device/pwm5=255 hwmon7/device/pwm1=255 hwmon7/device/pwm2=255 hwmon7/device/pwm3=255 hwmon7/device/pwm4=255 hwmon7/device/pwm5=255 diff --git a/device/celestica/x86_64-cel_seastone-r0/fancontrol-B2F b/device/celestica/x86_64-cel_seastone-r0/fancontrol-B2F new file mode 100644 index 000000000000..c2132d7f2806 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/fancontrol-B2F @@ -0,0 +1,11 @@ +# Configuration file generated by pwmconfig, changes will be lost +INTERVAL=2 +FCTEMPS=13-002e/pwm1=/sys/bus/i2c/devices/15-004e/hwmon/hwmon*/temp1_input 13-002e/pwm2=/sys/bus/i2c/devices/15-004e/hwmon/hwmon*/temp1_input 13-002e/pwm3=/sys/bus/i2c/devices/15-004e/hwmon/hwmon*/temp1_input 13-002e/pwm4=/sys/bus/i2c/devices/15-004e/hwmon/hwmon*/temp1_input 13-002e/pwm5=/sys/bus/i2c/devices/15-004e/hwmon/hwmon*/temp1_input 13-004d/pwm1=/sys/bus/i2c/devices/15-004e/hwmon/hwmon*/temp1_input 13-004d/pwm2=/sys/bus/i2c/devices/15-004e/hwmon/hwmon*/temp1_input 13-004d/pwm3=/sys/bus/i2c/devices/15-004e/hwmon/hwmon*/temp1_input 13-004d/pwm4=/sys/bus/i2c/devices/15-004e/hwmon/hwmon*/temp1_input 13-004d/pwm5=/sys/bus/i2c/devices/15-004e/hwmon/hwmon*/temp1_input +FCFANS=13-004d/pwm5=13-004d/fan5_input 13-004d/pwm4=13-004d/fan4_input 13-004d/pwm3=13-004d/fan3_input 13-004d/pwm2=13-004d/fan2_input 13-004d/pwm1=13-004d/fan1_input 13-002e/pwm5=13-002e/fan5_input 13-002e/pwm4=13-002e/fan4_input 13-002e/pwm3=13-002e/fan3_input 13-002e/pwm2=13-002e/fan2_input 13-002e/pwm1=13-002e/fan1_input +MINTEMP=13-002e/pwm1=27 13-002e/pwm2=27 13-002e/pwm3=27 13-002e/pwm4=27 13-002e/pwm5=27 13-004d/pwm1=27 13-004d/pwm2=27 13-004d/pwm3=27 13-004d/pwm4=27 13-004d/pwm5=27 +MAXTEMP=13-002e/pwm1=46 13-002e/pwm2=46 13-002e/pwm3=46 13-002e/pwm4=46 13-002e/pwm5=46 13-004d/pwm1=46 13-004d/pwm2=46 13-004d/pwm3=46 13-004d/pwm4=46 13-004d/pwm5=46 +MINSTART=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/pwm5=89 13-004d/pwm1=89 13-004d/pwm2=89 13-004d/pwm3=89 13-004d/pwm4=89 13-004d/pwm5=89 +MINSTOP=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/pwm5=89 13-004d/pwm1=89 13-004d/pwm2=89 13-004d/pwm3=89 13-004d/pwm4=89 13-004d/pwm5=89 +MINPWM=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/pwm5=89 13-004d/pwm1=89 13-004d/pwm2=89 13-004d/pwm3=89 13-004d/pwm4=89 13-004d/pwm5=89 +MAXPWM=13-002e/pwm1=255 13-002e/pwm2=255 13-002e/pwm3=255 13-002e/pwm4=255 13-002e/pwm5=255 13-004d/pwm1=255 13-004d/pwm2=255 13-004d/pwm3=255 13-004d/pwm4=255 13-004d/pwm5=255 +THYST=13-002e/pwm1=3 13-002e/pwm2=3 13-002e/pwm3=3 13-002e/pwm4=3 13-002e/pwm5=3 13-004d/pwm1=3 13-004d/pwm2=3 13-004d/pwm3=3 13-004d/pwm4=3 13-004d/pwm5=3 \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone-r0/fancontrol-F2B b/device/celestica/x86_64-cel_seastone-r0/fancontrol-F2B new file mode 100644 index 000000000000..dc67e2623cc2 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/fancontrol-F2B @@ -0,0 +1,12 @@ +# Configuration file generated by pwmconfig, changes will be lost +INTERVAL=2 +FCTEMPS=13-002e/pwm1=/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input 13-002e/pwm2=/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input 13-002e/pwm3=/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input 13-002e/pwm4=/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input 13-002e/pwm5=/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input 13-004d/pwm1=/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input 13-004d/pwm2=/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input 13-004d/pwm3=/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input 13-004d/pwm4=/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input 13-004d/pwm5=/sys/bus/i2c/devices/5-0048/hwmon/hwmon*/temp1_input +FCFANS=13-004d/pwm5=13-004d/fan5_input 13-004d/pwm4=13-004d/fan4_input 13-004d/pwm3=13-004d/fan3_input 13-004d/pwm2=13-004d/fan2_input 13-004d/pwm1=13-004d/fan1_input 13-002e/pwm5=13-002e/fan5_input 13-002e/pwm4=13-002e/fan4_input 13-002e/pwm3=13-002e/fan3_input 13-002e/pwm2=13-002e/fan2_input 13-002e/pwm1=13-002e/fan1_input +MINTEMP=13-002e/pwm1=26 13-002e/pwm2=26 13-002e/pwm3=26 13-002e/pwm4=26 13-002e/pwm5=26 13-004d/pwm1=26 13-004d/pwm2=26 13-004d/pwm3=26 13-004d/pwm4=26 13-004d/pwm5=26 +MAXTEMP=13-002e/pwm1=45 13-002e/pwm2=45 13-002e/pwm3=45 13-002e/pwm4=45 13-002e/pwm5=45 13-004d/pwm1=45 13-004d/pwm2=45 13-004d/pwm3=45 13-004d/pwm4=45 13-004d/pwm5=45 +MINSTART=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/pwm5=89 13-004d/pwm1=89 13-004d/pwm2=89 13-004d/pwm3=89 13-004d/pwm4=89 13-004d/pwm5=89 +MINSTOP=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/pwm5=89 13-004d/pwm1=89 13-004d/pwm2=89 13-004d/pwm3=89 13-004d/pwm4=89 13-004d/pwm5=89 +MINPWM=13-002e/pwm1=89 13-002e/pwm2=89 13-002e/pwm3=89 13-002e/pwm4=89 13-002e/pwm5=89 13-004d/pwm1=89 13-004d/pwm2=89 13-004d/pwm3=89 13-004d/pwm4=89 13-004d/pwm5=89 +MAXPWM=13-002e/pwm1=255 13-002e/pwm2=255 13-002e/pwm3=255 13-002e/pwm4=255 13-002e/pwm5=255 13-004d/pwm1=255 13-004d/pwm2=255 13-004d/pwm3=255 13-004d/pwm4=255 13-004d/pwm5=255 +THYST=13-002e/pwm1=3 13-002e/pwm2=3 13-002e/pwm3=3 13-002e/pwm4=3 13-002e/pwm5=3 13-004d/pwm1=3 13-004d/pwm2=3 13-004d/pwm3=3 13-004d/pwm4=3 13-004d/pwm5=3 + 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 8570fa1eae84..9b456a7c9112 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install @@ -1,5 +1,8 @@ dx010/scripts/dx010_check_qsfp.sh usr/local/bin dx010/cfg/dx010-modules.conf etc/modules-load.d dx010/systemd/platform-modules-dx010.service lib/systemd/system +dx010/scripts/fancontrol.sh etc/init.d +services/fancontrol/fancontrol.service lib/systemd/system +services/fancontrol/fancontrol usr/local/bin dx010/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_seastone-r0 services/platform_api/platform_api_mgnt.sh usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst index 15243c935ca3..8dbf0ece6676 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.postinst @@ -1,6 +1,9 @@ depmod -a systemctl enable platform-modules-dx010.service +systemctl enable fancontrol.service + systemctl start platform-modules-dx010.service +systemctl start fancontrol.service /usr/local/bin/platform_api_mgnt.sh install diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.sh b/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.sh new file mode 100644 index 000000000000..75ad6c65b37f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/fancontrol.sh @@ -0,0 +1,81 @@ +#! /bin/sh + +### BEGIN INIT INFO +# Provides: fancontrol +# Required-Start: $remote_fs +# Required-Stop: $remote_fs +# Default-Start: 2 3 4 5 +# Default-Stop: +# Short-Description: fancontrol +# Description: fan speed regulator +### END INIT INFO + +. /lib/lsb/init-functions + +[ -f /etc/default/rcS ] && . /etc/default/rcS +PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin +DAEMON=/usr/local/bin/fancontrol +DESC="fan speed regulator" +NAME="fancontrol" +PIDFILE=/var/run/fancontrol.pid +MAIN_CONF=/usr/share/sonic/device/x86_64-cel_seastone-r0/fancontrol +DEVPATH=/sys/devices/pci0000:00/0000:00:13.0/i2c-*/i2c-13/13-002e +GPIO_DIR=/sys/class/gpio +BASE_GPIO=$(find $GPIO_DIR | grep gpiochip | grep -o '[[:digit:]]*') +DIRGPIO_START=15 + +test -x $DAEMON || exit 0 + +for i in 1 2 3 4 5 +do + FANFAULT=$(cat ${DEVPATH}/fan${i}_fault) + [ $FANFAULT = 1 ] && continue + FANDIR_GPIO_NUMBER=$((DIRGPIO_START + BASE_GPIO)) + FANDIR_VALUE=$(cat ${GPIO_DIR}/gpio${FANDIR_GPIO_NUMBER}/value) + DIRGPIO_START=$((DIRGPIO_START+1)) + FANDIR=$([ $FANDIR_VALUE = 1 ] && echo "B2F" || echo "F2B") +done +CONF=${MAIN_CONF}-${FANDIR} + +case "$1" in + start) + if [ -f $CONF ] ; then + if $DAEMON --check $CONF 1>/dev/null 2>/dev/null ; then + log_daemon_msg "Starting $DESC" "$NAME\n" + start-stop-daemon --start --quiet --pidfile $PIDFILE --startas $DAEMON $CONF + log_end_msg $? + else + log_failure_msg "Not starting fancontrol, broken configuration file; please re-run pwmconfig." + fi + else + if [ "$VERBOSE" != no ]; then + log_warning_msg "Not starting fancontrol; run pwmconfig first." + fi + fi + ;; + stop) + log_daemon_msg "Stopping $DESC" "$NAME" + start-stop-daemon --stop --quiet --pidfile $PIDFILE --oknodo --startas $DAEMON $CONF + rm -f $PIDFILE + log_end_msg $? + ;; + restart) + $0 stop + sleep 3 + $0 start + ;; + force-reload) + if start-stop-daemon --stop --test --quiet --pidfile $PIDFILE --startas $DAEMON $CONF ; then + $0 restart + fi + ;; + status) + status_of_proc $DAEMON $NAME $CONF && exit 0 || exit $? + ;; + *) + log_success_msg "Usage: /etc/init.d/fancontrol {start|stop|restart|force-reload|status}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol b/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol index 9155d8a66998..eb15598b0efa 100755 --- a/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol +++ b/platform/broadcom/sonic-platform-modules-cel/services/fancontrol/fancontrol @@ -322,11 +322,12 @@ fi cd $DIR # Check for configuration change -if [ "$DIR" != "/" ] && [ -z "$DEVPATH" -o -z "$DEVNAME" ] -then - echo "Configuration is too old, please run pwmconfig again" >&2 - exit 1 -fi +# if [ "$DIR" != "/" ] && [ -z "$DEVPATH" -o -z "$DEVNAME" ] +# then +# echo "Configuration is too old, please run pwmconfig again" >&2 +# exit 1 +# fi + if [ "$DIR" = "/" -a -n "$DEVPATH" ] then echo "Unneeded DEVPATH with absolute device paths" >&2 From 4ba0ff25d2ac89b10b2a94208140f7c52776fb69 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Mon, 16 Dec 2019 19:07:05 +0200 Subject: [PATCH 26/66] [services] make snmp.timer work again and delay telemetry.service (#3742) Delay CPU intensive services at boot - How I did it Made snmp.timer work and add telemetry.timer. But this is not enough because it breaks the existing snmp dependency on swss. So, in this solution snmp timer is a wanted by swss service, but since OnBootSec timer expires only once it will not trigger snmp service, so I added line "OnUnitActiveSec=0 sec" which will start snmp service based on the last time it was active. On boot only OnBootSec will expire, on swss start/restarts only second timer will expire immediately and trigger snmp service. However, snmp service will not stop after "systemctl stop snmp" because of the second timer which will always expire when snmp service because unavailable. So there is a conflict which will be handled by systemd if we add "Conflicts=" line to both snmp.service and snmp.timer. So during boot: snmp does not start by default swss starts and starts snmp timer OnUnitActiveSec=0 does not expire since there is no snmp active OnBootSec expires and starts snmp service and snmp timer gets stopped During "systemctl restart swss" snmp stops because of Requisite on swss snmp unblocks snmp timer from running swss starts and starts snmp timer OnUnitActiveSec=0 expires imidiately and start snmp which stops snmp timer During "systemctl stop snmp" stop of snmp service unblocks snmp timer but no one starts the timer so it is not started by "OnUnitActiveSec=0" --- files/build_templates/snmp.service.j2 | 3 +-- files/build_templates/snmp.timer | 4 +++- files/build_templates/sonic_debian_extension.j2 | 8 ++++++-- files/build_templates/telemetry.service.j2 | 2 -- files/build_templates/telemetry.timer | 9 +++++++++ slave.mk | 1 + 6 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 files/build_templates/telemetry.timer diff --git a/files/build_templates/snmp.service.j2 b/files/build_templates/snmp.service.j2 index 310048e68beb..4997ab737e37 100644 --- a/files/build_templates/snmp.service.j2 +++ b/files/build_templates/snmp.service.j2 @@ -4,6 +4,7 @@ Requires=updategraph.service Requisite=swss.service After=updategraph.service swss.service syncd.service Before=ntp-config.service +Conflicts=snmp.timer StartLimitIntervalSec=1200 StartLimitBurst=3 @@ -14,5 +15,3 @@ ExecStop=/usr/bin/{{docker_container_name}}.sh stop Restart=always RestartSec=30 -[Install] -WantedBy=multi-user.target swss.service diff --git a/files/build_templates/snmp.timer b/files/build_templates/snmp.timer index 464cf01459ba..6d1838554d0e 100644 --- a/files/build_templates/snmp.timer +++ b/files/build_templates/snmp.timer @@ -1,9 +1,11 @@ [Unit] Description=Delays snmp container until SONiC has started +Conflicts=snmp.service [Timer] +OnUnitActiveSec=0 sec OnBootSec=3min 30 sec Unit=snmp.service [Install] -WantedBy=timers.target +WantedBy=timers.target swss.service diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index b11325e86835..b63b5addac4b 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -359,7 +359,7 @@ EOF ## Bind docker path if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then sudo mkdir -p $FILESYSTEM_ROOT/dockerfs - sudo mount --bind dockerfs $FILESYSTEM_ROOT/dockerfs + sudo mount --bind dockerfs $FILESYSTEM_ROOT/dockerfs fi {% if installer_images.strip() -%} @@ -376,7 +376,7 @@ sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS ta {% endif %} {% endfor %} if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then - sudo umount $FILESYSTEM_ROOT/dockerfs + sudo umount $FILESYSTEM_ROOT/dockerfs sudo rm -fr $FILESYSTEM_ROOT/dockerfs sudo kill -9 `sudo $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS_PID` || true else @@ -404,6 +404,10 @@ sudo LANG=C cp $SCRIPTS_DIR/syncd.sh $FILESYSTEM_ROOT/usr/local/bin/syncd.sh # It implements delayed start of services sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT/etc/systemd/system/ sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable snmp.timer +{% if enable_system_telemetry == 'y' %} +sudo cp $BUILD_TEMPLATES/telemetry.timer $FILESYSTEM_ROOT/etc/systemd/system/ +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable telemetry.timer +{% endif %} sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get purge -y python-dev sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get clean -y diff --git a/files/build_templates/telemetry.service.j2 b/files/build_templates/telemetry.service.j2 index 98ae2871bf6f..43fa039156d7 100644 --- a/files/build_templates/telemetry.service.j2 +++ b/files/build_templates/telemetry.service.j2 @@ -14,5 +14,3 @@ ExecStop=/usr/bin/{{docker_container_name}}.sh stop Restart=always RestartSec=30 -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/telemetry.timer b/files/build_templates/telemetry.timer new file mode 100644 index 000000000000..e08f1c09eac6 --- /dev/null +++ b/files/build_templates/telemetry.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Delays telemetry container until SONiC has started + +[Timer] +OnBootSec=3min 30 sec +Unit=telemetry.service + +[Install] +WantedBy=timers.target diff --git a/slave.mk b/slave.mk index e518f1e4d8a5..44b903ddf9c9 100644 --- a/slave.mk +++ b/slave.mk @@ -641,6 +641,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export sonic_asic_platform="$(patsubst %-$(CONFIGURED_ARCH),%,$(CONFIGURED_PLATFORM))" export enable_organization_extensions="$(ENABLE_ORGANIZATION_EXTENSIONS)" export enable_dhcp_graph_service="$(ENABLE_DHCP_GRAPH_SERVICE)" + export enable_system_telemetry="$(ENABLE_SYSTEM_TELEMETRY)" export enable_ztp="$(ENABLE_ZTP)" export shutdown_bgp_on_start="$(SHUTDOWN_BGP_ON_START)" export enable_pfcwd_on_start="$(ENABLE_PFCWD_ON_START)" From 08ec4fcfe7290d4a05e14a6b7597f4b38f2cef34 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Tue, 17 Dec 2019 08:00:14 -0800 Subject: [PATCH 27/66] [swss-common] update submodule for sonic-swss-common (#3916) update multiDB changes in sonic-swss-common, including: [Enhancement] debian/conffiles will give prompt when file existing, need a way to supress prompt (#323) [MultiDB]:swsscommon replace old API with new APIs including tests (#324) Signed-off-by: Dong Zhang d.zhang@alibaba-inc.com --- src/sonic-swss-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 29a2cdfe9ea9..5b55954c5d6d 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 29a2cdfe9ea9bb0c4d2d82be9428228a8ab6b9d4 +Subproject commit 5b55954c5d6d4ae343af141357c3a2f6dd600c58 From 7ae371287f5d2c7c046003812c558e5cf169fd85 Mon Sep 17 00:00:00 2001 From: Volodymyr Samotiy Date: Tue, 17 Dec 2019 19:45:28 +0200 Subject: [PATCH 28/66] [Mellanox]: Update SAI submodule (#3883) Signed-off-by: Volodymyr Samotiy --- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index 925116eb63a5..d878245e364c 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit 925116eb63a5a9012dcc22a7a0682ada6e976380 +Subproject commit d878245e364ce8d5edd08bbd7120c44c92362235 From 51b78b5c335099e2c47e7277cbc8748a219eed77 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Tue, 17 Dec 2019 20:58:55 +0200 Subject: [PATCH 29/66] [mellanox]: Enhance pmon synchronization with hw-mgmt platform counters. (#3885) Signed-off-by: Nazarii Hnydyn --- .../x86_64-mlnx_msn2700-r0/platform_wait | 49 +++++++++++++++---- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/platform_wait b/device/mellanox/x86_64-mlnx_msn2700-r0/platform_wait index 44321184dccc..a233eb41de42 100755 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/platform_wait +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/platform_wait @@ -1,12 +1,37 @@ #!/bin/bash +declare -r SYSLOG_LOGGER="/usr/bin/logger" +declare -r SYSLOG_IDENTIFIER="platform_wait" +declare -r SYSLOG_ERROR="error" +declare -r SYSLOG_NOTICE="notice" +declare -r SYSLOG_INFO="info" + +declare -r HW_MGMT_CONFIG="/var/run/hw-management/config" + +declare -r MODULE_COUNTER="${HW_MGMT_CONFIG}/module_counter" +declare -r SFP_COUNTER="${HW_MGMT_CONFIG}/sfp_counter" + declare -r EXIT_SUCCESS="0" declare -r EXIT_TIMEOUT="1" -declare -r QSFP_PATH="/var/run/hw-management/qsfp" +function log_error() { + eval "${SYSLOG_LOGGER} -t ${SYSLOG_IDENTIFIER} -p ${SYSLOG_ERROR} $@" +} -function WaitForQsfpReady() { - local -r _QSFP_PATH="${1}" +function log_notice() { + eval "${SYSLOG_LOGGER} -t ${SYSLOG_IDENTIFIER} -p ${SYSLOG_NOTICE} $@" +} + +function log_info() { + eval "${SYSLOG_LOGGER} -t ${SYSLOG_IDENTIFIER} -p ${SYSLOG_INFO} $@" +} + +function wait_for_sfp() { + local -r _NUM_MATCH="^[0-9]+$" + local -r _NUM_ZERO="0" + + local _MODULE_CNT="0" + local _SFP_CNT="0" local -i _WDOG_CNT="1" local -ir _WDOG_MAX="300" @@ -14,11 +39,14 @@ function WaitForQsfpReady() { local -r _TIMEOUT="1s" while [[ "${_WDOG_CNT}" -le "${_WDOG_MAX}" ]]; do - for _QSFP in ${_QSFP_PATH}/qsfp*; do - if [[ -e "${_QSFP}" ]]; then + _MODULE_CNT="$(cat ${MODULE_COUNTER} 2>&1)" + _SFP_CNT="$(cat ${SFP_COUNTER} 2>&1)" + + if [[ "${_MODULE_CNT}" =~ ${_NUM_MATCH} && "${_SFP_CNT}" =~ ${_NUM_MATCH} ]]; then + if [[ "${_SFP_CNT}" -gt "${_NUM_ZERO}" && "${_MODULE_CNT}" -eq "${_SFP_CNT}" ]]; then return "${EXIT_SUCCESS}" fi - done + fi let "_WDOG_CNT++" sleep "${_TIMEOUT}" @@ -27,14 +55,15 @@ function WaitForQsfpReady() { return "${EXIT_TIMEOUT}" } -echo "Wait for QSFP I2C interface is ready" +log_info "Wait for SFP interfaces to be ready" -WaitForQsfpReady "${QSFP_PATH}" +wait_for_sfp EXIT_CODE="$?" if [[ "${EXIT_CODE}" != "${EXIT_SUCCESS}" ]]; then - echo "QSFP I2C interface is not ready: timeout" + log_error "SFP interfaces are not ready: timeout" exit "${EXIT_CODE}" fi -echo "QSFP I2C interface is ready: mlxsw_minimal has finished initialization" +log_info "SFP interfaces are ready" + exit "${EXIT_SUCCESS}" From a4b107b1dea1b16bbb000dfd7acaa335cd8e604f Mon Sep 17 00:00:00 2001 From: Ciju Rajan K Date: Wed, 18 Dec 2019 01:23:53 +0530 Subject: [PATCH 30/66] [Juniper][QFX5210] Skip starting 'ledd' (#3920) There is no ledd in qfx5210 platform. This patch skip starting ledd in pmon container. This also will help in fixing the pmon container not getting started if there is no ledd running. Signed-off-by: Ciju Rajan K --- .../juniper/x86_64-juniper_qfx5210-r0/pmon_daemon_control.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 device/juniper/x86_64-juniper_qfx5210-r0/pmon_daemon_control.json diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/pmon_daemon_control.json b/device/juniper/x86_64-juniper_qfx5210-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5210-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} From 063deb9b5f1e0601e7f7d55eef6939943c0f8a2b Mon Sep 17 00:00:00 2001 From: "arheneus@marvell.com" <51254330+antony-rheneus@users.noreply.github.com> Date: Wed, 18 Dec 2019 01:28:17 +0530 Subject: [PATCH 31/66] [Marvell HwSKU] port configration updated with speed (#3919) Signed-off-by: Antony Rheneus --- .../et6448m/port_config.ini | 106 +++++++++--------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/port_config.ini b/device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/port_config.ini index 8073e8bec86e..062c252ce195 100644 --- a/device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/port_config.ini +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/port_config.ini @@ -1,53 +1,53 @@ -# name lanes alias -Ethernet0 1 Ethernet0 -Ethernet1 2 Ethernet1 -Ethernet2 3 Ethernet2 -Ethernet3 4 Ethernet3 -Ethernet4 5 Ethernet4 -Ethernet5 6 Ethernet5 -Ethernet6 7 Ethernet6 -Ethernet7 8 Ethernet7 -Ethernet8 9 Ethernet8 -Ethernet9 10 Ethernet9 -Ethernet10 11 Ethernet10 -Ethernet11 12 Ethernet11 -Ethernet12 13 Ethernet12 -Ethernet13 14 Ethernet13 -Ethernet14 15 Ethernet14 -Ethernet15 16 Ethernet15 -Ethernet16 17 Ethernet16 -Ethernet17 18 Ethernet17 -Ethernet18 19 Ethernet18 -Ethernet19 20 Ethernet19 -Ethernet20 21 Ethernet20 -Ethernet21 22 Ethernet21 -Ethernet22 23 Ethernet22 -Ethernet23 24 Ethernet23 -Ethernet24 25 Ethernet24 -Ethernet25 26 Ethernet25 -Ethernet26 27 Ethernet26 -Ethernet27 28 Ethernet27 -Ethernet28 29 Ethernet28 -Ethernet29 30 Ethernet29 -Ethernet30 31 Ethernet30 -Ethernet31 32 Ethernet31 -Ethernet32 33 Ethernet32 -Ethernet33 34 Ethernet33 -Ethernet34 35 Ethernet34 -Ethernet35 36 Ethernet35 -Ethernet36 37 Ethernet36 -Ethernet37 38 Ethernet37 -Ethernet38 39 Ethernet38 -Ethernet39 40 Ethernet39 -Ethernet40 41 Ethernet40 -Ethernet41 42 Ethernet41 -Ethernet42 43 Ethernet42 -Ethernet43 44 Ethernet43 -Ethernet44 45 Ethernet44 -Ethernet45 46 Ethernet45 -Ethernet46 47 Ethernet46 -Ethernet47 48 Ethernet47 -Ethernet48 49 Ethernet48 -Ethernet49 50 Ethernet49 -Ethernet50 51 Ethernet50 -Ethernet51 52 Ethernet51 +# name lanes alias index speed +Ethernet0 1 Ethernet0 1 1000 +Ethernet1 2 Ethernet1 2 1000 +Ethernet2 3 Ethernet2 3 1000 +Ethernet3 4 Ethernet3 4 1000 +Ethernet4 5 Ethernet4 5 1000 +Ethernet5 6 Ethernet5 6 1000 +Ethernet6 7 Ethernet6 7 1000 +Ethernet7 8 Ethernet7 8 1000 +Ethernet8 9 Ethernet8 9 1000 +Ethernet9 10 Ethernet9 10 1000 +Ethernet10 11 Ethernet10 11 1000 +Ethernet11 12 Ethernet11 12 1000 +Ethernet12 13 Ethernet12 13 1000 +Ethernet13 14 Ethernet13 14 1000 +Ethernet14 15 Ethernet14 15 1000 +Ethernet15 16 Ethernet15 16 1000 +Ethernet16 17 Ethernet16 17 1000 +Ethernet17 18 Ethernet17 18 1000 +Ethernet18 19 Ethernet18 19 1000 +Ethernet19 20 Ethernet19 20 1000 +Ethernet20 21 Ethernet20 21 1000 +Ethernet21 22 Ethernet21 22 1000 +Ethernet22 23 Ethernet22 23 1000 +Ethernet23 24 Ethernet23 24 1000 +Ethernet24 25 Ethernet24 25 1000 +Ethernet25 26 Ethernet25 26 1000 +Ethernet26 27 Ethernet26 27 1000 +Ethernet27 28 Ethernet27 28 1000 +Ethernet28 29 Ethernet28 29 1000 +Ethernet29 30 Ethernet29 30 1000 +Ethernet30 31 Ethernet30 31 1000 +Ethernet31 32 Ethernet31 32 1000 +Ethernet32 33 Ethernet32 33 1000 +Ethernet33 34 Ethernet33 34 1000 +Ethernet34 35 Ethernet34 35 1000 +Ethernet35 36 Ethernet35 36 1000 +Ethernet36 37 Ethernet36 37 1000 +Ethernet37 38 Ethernet37 38 1000 +Ethernet38 39 Ethernet38 39 1000 +Ethernet39 40 Ethernet39 40 1000 +Ethernet40 41 Ethernet40 41 1000 +Ethernet41 42 Ethernet41 42 1000 +Ethernet42 43 Ethernet42 43 1000 +Ethernet43 44 Ethernet43 44 1000 +Ethernet44 45 Ethernet44 45 1000 +Ethernet45 46 Ethernet45 46 1000 +Ethernet46 47 Ethernet46 47 1000 +Ethernet47 48 Ethernet47 48 1000 +Ethernet48 49 Ethernet48 49 10000 +Ethernet49 50 Ethernet49 50 10000 +Ethernet50 51 Ethernet50 51 10000 +Ethernet51 52 Ethernet51 52 10000 From 4458efbd7161985c8c14b76fcaf66688d06b2c8d Mon Sep 17 00:00:00 2001 From: srideepDell Date: Tue, 17 Dec 2019 16:26:23 -0700 Subject: [PATCH 32/66] DellEMC: Add support for new platform z9332f -32x400G (#3845) * Switch Vendor: DellEMC * Switch SKU: z9332F * ASIC Vendor: Broadcom * Swich ASIC: tomahawk3 * Port Configuration: 32x400G * SONiC Image: sonic-broadcom.bin * Changes Include ipmitool implementation for platform_sensors script is inclued in pmon startup --- .../DellEMC-Z9332f-O32/buffers.json.j2 | 2 + .../DellEMC-Z9332f-O32/buffers_defaults_t0.j2 | 20 + .../DellEMC-Z9332f-O32/buffers_defaults_t1.j2 | 20 + .../DellEMC-Z9332f-O32/custom_led.bin | Bin 0 -> 920 bytes .../DellEMC-Z9332f-O32/linkscan_led_fw.bin | Bin 0 -> 4752 bytes .../DellEMC-Z9332f-O32/pg_profile_lookup.ini | 23 + .../DellEMC-Z9332f-O32/port_config.ini | 35 + .../DellEMC-Z9332f-O32/qos.json.j2 | 226 ++ .../DellEMC-Z9332f-O32/sai.profile | 1 + .../DellEMC-Z9332f-O32/sai_postinit_cmd.soc | 2530 +++++++++++++++++ .../DellEMC-Z9332f-O32/sai_preinit_cmd.soc | 3 + .../th3-z9332f-32x400G.config.bcm | 519 ++++ .../default_sku | 1 + .../installer.conf | 2 + .../led_proc_init.soc | 7 + .../plugins/eeprom.py | 22 + .../plugins/psuutil.py | 126 + .../plugins/sfputil.py | 307 ++ platform/broadcom/one-image.mk | 1 + platform/broadcom/platform-modules-dell.mk | 8 +- .../debian/control | 5 + .../debian/platform-modules-z9332f.init | 39 + .../debian/platform-modules-z9332f.install | 7 + .../debian/platform-modules-z9332f.postinst | 10 + .../sonic-platform-modules-dell/debian/rules | 2 +- .../z9332f/cfg/z9332f-modules.conf | 17 + .../z9332f/modules/Makefile | 4 + .../z9332f/modules/cls-i2c-ocore.c | 845 ++++++ .../z9332f/modules/cls-i2c-ocore.h | 22 + .../z9332f/modules/cls-switchboard.c | 447 +++ .../z9332f/modules/mc24lc64t.c | 142 + .../z9332f/modules/z9332f-modules.conf | 17 + .../z9332f/scripts/pcisysfs.py | 102 + .../z9332f/scripts/platform_sensors.py | 198 ++ .../z9332f/scripts/sensors | 8 + .../z9332f/scripts/z9332f_platform.sh | 180 ++ .../systemd/platform-modules-z9332f.service | 13 + src/sonic-device-data/tests/permitted_list | 1 + 38 files changed, 5910 insertions(+), 2 deletions(-) create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers.json.j2 create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t0.j2 create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t1.j2 create mode 100755 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/custom_led.bin create mode 100755 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/linkscan_led_fw.bin create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/pg_profile_lookup.ini create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/port_config.ini create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/qos.json.j2 create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai.profile create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai_postinit_cmd.soc create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai_preinit_cmd.soc create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/default_sku create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/installer.conf create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/led_proc_init.soc create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/eeprom.py create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/psuutil.py create mode 100644 device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/sfputil.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.init create mode 100644 platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.install create mode 100644 platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.postinst create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9332f/cfg/z9332f-modules.conf create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9332f/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-ocore.c create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-ocore.h create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-switchboard.c create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9332f/modules/mc24lc64t.c create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9332f/modules/z9332f-modules.conf create mode 100755 platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/pcisysfs.py create mode 100755 platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/platform_sensors.py create mode 100755 platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/sensors create mode 100755 platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/z9332f_platform.sh create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9332f/systemd/platform-modules-z9332f.service diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers.json.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..77747f6403c8 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t0.j2 @@ -0,0 +1,20 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + }, + "BUFFER_PROFILE": { + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..77747f6403c8 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t1.j2 @@ -0,0 +1,20 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + }, + "BUFFER_PROFILE": { + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + } +{% endmacro %} + diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/custom_led.bin b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/custom_led.bin new file mode 100755 index 0000000000000000000000000000000000000000..3ee9545e28ae08c5b597570c490af69a5d1f2bb4 GIT binary patch literal 920 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 X`cUsHXR!vGk^Z4y?GFw9z}SBSTZoUr literal 0 HcmV?d00001 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/pg_profile_lookup.ini b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/pg_profile_lookup.ini new file mode 100644 index 000000000000..a5f3286beef8 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/pg_profile_lookup.ini @@ -0,0 +1,23 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1270 0 190500 -2 2540 + 25000 5m 1270 0 190500 -2 2540 + 40000 5m 1270 0 190500 -2 2540 + 50000 5m 1270 0 190500 -2 2540 + 100000 5m 1270 0 190500 -2 2540 + 200000 5m 1270 0 190500 -2 2540 + 400000 5m 1270 0 190500 -2 2540 + 10000 40m 1270 0 190500 -2 2540 + 25000 40m 1270 0 190500 -2 2540 + 40000 40m 1270 0 190500 -2 2540 + 50000 40m 1270 0 190500 -2 2540 + 100000 40m 1270 0 190500 -2 2540 + 200000 40m 1270 0 190500 -2 2540 + 400000 40m 1270 0 190500 -2 2540 + 10000 300m 1270 0 190500 -2 2540 + 25000 300m 1270 0 190500 -2 2540 + 40000 300m 1270 0 190500 -2 2540 + 50000 300m 1270 0 190500 -2 2540 + 100000 300m 1270 0 190500 -2 2540 + 200000 300m 1270 0 190500 -2 2540 + 400000 300m 1270 0 190500 -2 2540 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/port_config.ini b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/port_config.ini new file mode 100644 index 000000000000..790fb490cfe6 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/port_config.ini @@ -0,0 +1,35 @@ +# name lanes alias index speed +Ethernet0 33,34,35,36,37,38,39,40 fourhundredGigE1/1 1 400000 +Ethernet8 41,42,43,44,45,46,47,48 fourhundredGigE1/2 2 400000 +Ethernet16 49,50,51,52,53,54,55,56 fourhundredGigE1/3 3 400000 +Ethernet24 57,58,59,60,61,62,63,64 fourhundredGigE1/4 4 400000 +Ethernet32 65,66,67,68,69,70,71,72 fourhundredGigE1/5 5 400000 +Ethernet40 73,74,75,76,77,78,79,80 fourhundredGigE1/6 6 400000 +Ethernet48 81,82,83,84,85,86,87,88 fourhundredGigE1/7 7 400000 +Ethernet56 89,90,91,92,93,94,95,96 fourhundredGigE1/8 8 400000 +Ethernet64 1,2,3,4,5,6,7,8 fourhundredGigE1/9 9 400000 +Ethernet72 9,10,11,12,13,14,15,16 fourhundredGigE1/10 10 400000 +Ethernet80 17,18,19,20,21,22,23,24 fourhundredGigE1/11 11 400000 +Ethernet88 25,26,27,28,29,30,31,32 fourhundredGigE1/12 12 400000 +Ethernet96 97,98,99,100,101,102,103,104 fourhundredGigE1/13 13 400000 +Ethernet104 105,106,107,108,109,110,111,112 fourhundredGigE1/14 14 400000 +Ethernet112 113,114,115,116,117,118,119,120 fourhundredGigE1/15 15 400000 +Ethernet120 121,122,123,124,125,126,127,128 fourhundredGigE1/16 16 400000 +Ethernet128 129,130,131,132,133,134,135,136 fourhundredGigE1/17 17 400000 +Ethernet136 137,138,139,140,141,142,143,144 fourhundredGigE1/18 18 400000 +Ethernet144 145,146,147,148,149,150,151,152 fourhundredGigE1/19 19 400000 +Ethernet152 153,154,155,156,157,158,159,160 fourhundredGigE1/20 20 400000 +Ethernet160 225,226,227,228,229,230,231,232 fourhundredGigE1/21 21 400000 +Ethernet168 233,234,235,236,237,238,239,240 fourhundredGigE1/22 22 400000 +Ethernet176 241,242,243,244,245,246,247,248 fourhundredGigE1/23 23 400000 +Ethernet184 249,250,251,252,253,254,255,256 fourhundredGigE1/24 24 400000 +Ethernet192 161,162,163,164,165,166,167,168 fourhundredGigE1/25 25 400000 +Ethernet200 169,170,171,172,173,174,175,176 fourhundredGigE1/26 26 400000 +Ethernet208 177,178,179,180,181,182,183,184 fourhundredGigE1/27 27 400000 +Ethernet216 185,186,187,188,189,190,191,192 fourhundredGigE1/28 28 400000 +Ethernet224 193,194,195,196,197,198,199,200 fourhundredGigE1/29 29 400000 +Ethernet232 201,202,203,204,205,206,207,208 fourhundredGigE1/30 30 400000 +Ethernet240 209,210,211,212,213,214,215,216 fourhundredGigE1/31 31 400000 +Ethernet248 217,218,219,220,221,222,223,224 fourhundredGigE1/32 32 400000 +Ethernet256 257 tenGigE1/33 33 10000 +Ethernet257 258 tenGigE1/34 34 10000 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/qos.json.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/qos.json.j2 new file mode 100644 index 000000000000..a48e1b56621c --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/qos.json.j2 @@ -0,0 +1,226 @@ +{%- set PORT_ALL = [] %} +{%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{% endif %} +{%- endfor %} +{%- if PORT_ALL | sort_by_port_index %}{% endif %} + +{%- set port_names_list_all = [] %} +{%- for port in PORT_ALL %} + {%- if port_names_list_all.append(port) %}{% endif %} +{%- endfor %} +{%- set port_names_all = port_names_list_all | join(',') -%} + + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} +{%- if PORT_ACTIVE | sort_by_port_index %}{% endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') -%} + + +{%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%} + + +{ +{% if generate_tc_to_pg_map is defined %} + {{- generate_tc_to_pg_map() }} +{% else %} + "TC_TO_PRIORITY_GROUP_MAP": { + "DEFAULT": { + "0": "0", + "1": "0", + "2": "0", + "3": "3", + "4": "4", + "5": "0", + "6": "0", + "7": "7" + } + }, +{% endif %} + "MAP_PFC_PRIORITY_TO_QUEUE": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "DEFAULT": { + "0" : "0", + "1" : "0", + "2" : "0", + "3" : "0", + "4" : "0", + "5" : "0", + "6" : "0", + "7" : "0", + "8" : "0", + "9" : "0", + "10": "0", + "11": "0", + "12": "0", + "13": "0", + "14": "0", + "15": "0", + "16": "0", + "17": "0", + "18": "0", + "19": "0", + "20": "0", + "21": "0", + "22": "0", + "23": "0", + "24": "0", + "25": "0", + "26": "0", + "27": "0", + "28": "0", + "29": "0", + "30": "0", + "31": "0", + "32": "0", + "33": "0", + "34": "0", + "35": "0", + "36": "0", + "37": "0", + "38": "0", + "39": "0", + "40": "0", + "41": "0", + "42": "0", + "43": "0", + "44": "0", + "45": "0", + "46": "0", + "47": "0", + "48": "0", + "49": "0", + "50": "0", + "51": "0", + "52": "0", + "53": "0", + "54": "0", + "55": "0", + "56": "0", + "57": "0", + "58": "0", + "59": "0", + "60": "0", + "61": "0", + "62": "0", + "63": "0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "1" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "2" + }, + "scheduler.2": { + "type" : "DWRR", + "weight": "3" + }, + "scheduler.3": { + "type" : "DWRR", + "weight": "4" + }, + "scheduler.4": { + "type" : "DWRR", + "weight": "5" + }, + "scheduler.5": { + "type" : "DWRR", + "weight": "10" + }, + "scheduler.6": { + "type" : "DWRR", + "weight": "25" + }, + "scheduler.7": { + "type" : "STRICT" + } + }, + "PORT_QOS_MAP": { + "{{ port_names_active }}": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|DEFAULT]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|DEFAULT]", + "pfc_enable" : "3,4", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|DEFAULT]" + } + }, + "QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|1": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|2": { + "scheduler": "[SCHEDULER|scheduler.2]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|3": { + "scheduler": "[SCHEDULER|scheduler.3]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|4": { + "scheduler": "[SCHEDULER|scheduler.4]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5": { + "scheduler": "[SCHEDULER|scheduler.5]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|6": { + "scheduler": "[SCHEDULER|scheduler.6]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + }{% if not loop.last %},{% endif %} +{% endfor %} + } +} diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai.profile b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai.profile new file mode 100644 index 000000000000..19cd5cb02839 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-z9332f-32x400G.config.bcm diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai_postinit_cmd.soc b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai_postinit_cmd.soc new file mode 100644 index 000000000000..9550e9c822c8 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai_postinit_cmd.soc @@ -0,0 +1,2530 @@ +delay 200 +link off +counter off + +#*** +#*** Port CD0 Preemphasis setting *** +#*** + +local port cd0 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD1 Preemphasis setting *** +#*** + +local port cd1 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD2 Preemphasis setting *** +#*** + +local port cd2 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD3 Preemphasis setting *** +#*** + +local port cd3 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD4 Preemphasis setting *** +#*** + +local port cd4 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD5 Preemphasis setting *** +#*** + +local port cd5 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD6 Preemphasis setting *** +#*** + +local port cd6 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD7 Preemphasis setting *** +#*** + +local port cd7 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD8 Preemphasis setting *** +#*** + +local port cd8 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD9 Preemphasis setting *** +#*** + +local port cd9 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD10 Preemphasis setting *** +#*** + +local port cd10 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x78 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1EC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD11 Preemphasis setting *** +#*** + +local port cd11 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD12 Preemphasis setting *** +#*** + +local port cd12 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD13 Preemphasis setting *** +#*** + +local port cd13 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD14 Preemphasis setting *** +#*** + +local port cd14 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD15 Preemphasis setting *** +#*** + +local port cd15 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD16 Preemphasis setting *** +#*** + +local port cd16 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD17 Preemphasis setting *** +#*** + +local port cd17 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD18 Preemphasis setting *** +#*** + +local port cd18 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD19 Preemphasis setting *** +#*** + +local port cd19 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD20 Preemphasis setting *** +#*** + +local port cd20 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD21 Preemphasis setting *** +#*** + +local port cd21 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD22 Preemphasis setting *** +#*** + +local port cd22 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD23 Preemphasis setting *** +#*** + +local port cd23 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD24 Preemphasis setting *** +#*** + +local port cd24 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD25 Preemphasis setting *** +#*** + +local port cd25 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD26 Preemphasis setting *** +#*** + +local port cd26 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD27 Preemphasis setting *** +#*** + +local port cd27 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD28 Preemphasis setting *** +#*** + +local port cd28 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x88 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F8 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD29 Preemphasis setting *** +#*** + +local port cd29 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD30 Preemphasis setting *** +#*** + +local port cd30 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x84 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1F4 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +delay 10 + +#*** +#*** Port CD31 Preemphasis setting *** +#*** + +local port cd31 +#*** lane 0 *** +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.0 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.0 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.0 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.0 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.0 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.0 TXFIR_TAP_LOAD=0x1 + +#*** lane 1 *** +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.1 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.1 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.1 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.1 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.1 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.1 TXFIR_TAP_LOAD=0x1 + +#*** lane 2 *** +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.2 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.2 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.2 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.2 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.2 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.2 TXFIR_TAP_LOAD=0x1 + +#*** lane 3 *** +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.3 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.3 TXFIR_TAP2_COEFF=0x90 +phy $port TXFIR_TAP_CTL3r.3 TXFIR_TAP3_COEFF=0 +phy $port TXFIR_TAP_CTL4r.3 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.3 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.3 TXFIR_TAP_LOAD=0x1 + +#*** lane 4 *** +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.4 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.4 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.4 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.4 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.4 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.4 TXFIR_TAP_LOAD=0x1 + +#*** lane 5 *** +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP0_COEFF=4 +phy $port TXFIR_TAP_CTL1r.5 TXFIR_TAP1_COEFF=0x1E4 +phy $port TXFIR_TAP_CTL2r.5 TXFIR_TAP2_COEFF=0x70 +phy $port TXFIR_TAP_CTL3r.5 TXFIR_TAP3_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL4r.5 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.5 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.5 TXFIR_TAP_LOAD=0x1 + +#*** lane 6 *** +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.6 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.6 TXFIR_TAP2_COEFF=0x80 +phy $port TXFIR_TAP_CTL3r.6 TXFIR_TAP3_COEFF=0x1F0 +phy $port TXFIR_TAP_CTL4r.6 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.6 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.6 TXFIR_TAP_LOAD=0x1 + +#*** lane 7 *** +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP0_COEFF=0 +phy $port TXFIR_TAP_CTL1r.7 TXFIR_TAP1_COEFF=0x1E8 +phy $port TXFIR_TAP_CTL2r.7 TXFIR_TAP2_COEFF=0x8C +phy $port TXFIR_TAP_CTL3r.7 TXFIR_TAP3_COEFF=0x1FC +phy $port TXFIR_TAP_CTL4r.7 TXFIR_TAP4_COEFF=0 +phy $port TXFIR_TAP_CTL5r.7 TXFIR_TAP5_COEFF=0 +phy $port TXFIR_TAP_CTL0r.7 TXFIR_TAP_LOAD=0x1 + +link on +counter on diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai_preinit_cmd.soc new file mode 100644 index 000000000000..e48c05b9f664 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/sai_preinit_cmd.soc @@ -0,0 +1,3 @@ +#Not supported Until SAI 3.6 +#m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +#m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm new file mode 100644 index 000000000000..3d204640d5aa --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm @@ -0,0 +1,519 @@ +core_clock_frequency=1325 +dpr_clock_frequency=1000 +device_clock_frequency=1325 +port_flex_enable=1 + +#firmware load method, use fast load +load_firmware=0x2 + +ccm_dma_enable=0 +ccmdma_intr_enable=0 +mem_cache_enable=0 +phy_enable=0 +phy_null=1 + +dport_map_enable=1 + +module_64ports.0=0 +tdma_intr_enable.0=1 +ipv6_lpm_128b_enable.0=1 +stat_if_parity_enable.0=1 +oversubscribe_mode=0 +bcm_tunnel_term_compatible_mode.0=1 +table_dma_enable.0=1 +schan_intr_enable.0=0 +parity_enable.0=1 +tdma_timeout_usec=1000000 +lls_num_l2uc.0=10 +miim_intr_enable.0=0 +table_dma_enable=1 +max_vp_lags.0=0 +tdma_intr_enable=1 +tdma_timeout_usec.0=5000000 +parity_correction.0=1 +mmu_lossless.0=0 +bcm_num_cos=8 +default_cpu_tx_queue=7 +pktdma_poll_mode_channel_bitmap=1 +l3_max_ecmp_mode.0=1 +l3_alpm_enable=2 +l3_alpm_ipv6_128b_bkt_rsvd=1 +l2_mem_entries=40960 +l3_mem_entries=40960 + +l2xlrn_thread_interval=50000 +l2xlrn_intr_en=0 + +pbmp_xport_xe=0xffffffFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + +phy_an_c73=3 + +portmap_1.0=1:400 +portmap_5.0=9:400 +portmap_10.0=17:400 +portmap_14.0=25:400 + +portmap_20.0=33:400 +portmap_24.0=41:400 +portmap_29.0=49:400 +portmap_33.0=57:400 + +portmap_40.0=65:400 +portmap_44.0=73:400 +portmap_49.0=81:400 +portmap_53.0=89:400 + +portmap_60.0=97:400 +portmap_64.0=105:400 +portmap_69.0=113:400 +portmap_73.0=121:400 + +portmap_80.0=129:400 +portmap_84.0=137:400 +portmap_89.0=145:400 +portmap_93.0=153:400 + +portmap_100.0=161:400 +portmap_104.0=169:400 +portmap_109.0=177:400 +portmap_113.0=185:400 + +portmap_120.0=193:400 +portmap_124.0=201:400 +portmap_129.0=209:400 +portmap_133.0=217:400 + +portmap_140.0=225:400 +portmap_144.0=233:400 +portmap_149.0=241:400 +portmap_153.0=249:400 + +portmap_38.0=257:10:1 +portmap_118.0=258:10:1 + +dport_map_port_20=1 +dport_map_port_21=2 +dport_map_port_22=3 +dport_map_port_23=4 +dport_map_port_24=5 +dport_map_port_25=6 +dport_map_port_26=7 +dport_map_port_27=8 +dport_map_port_28=9 +dport_map_port_29=10 +dport_map_port_30=11 +dport_map_port_31=12 +dport_map_port_32=13 +dport_map_port_33=14 +dport_map_port_34=15 +dport_map_port_35=16 +dport_map_port_36=17 +dport_map_port_37=18 +dport_map_port_40=19 +dport_map_port_41=20 +dport_map_port_42=21 +dport_map_port_43=22 +dport_map_port_44=23 +dport_map_port_45=24 +dport_map_port_46=25 +dport_map_port_47=26 +dport_map_port_48=27 +dport_map_port_49=28 +dport_map_port_50=29 +dport_map_port_51=30 +dport_map_port_52=31 +dport_map_port_53=32 +dport_map_port_54=33 +dport_map_port_55=34 +dport_map_port_56=35 +dport_map_port_57=36 +dport_map_port_1=37 +dport_map_port_2=38 +dport_map_port_3=39 +dport_map_port_4=40 +dport_map_port_5=41 +dport_map_port_6=42 +dport_map_port_7=43 +dport_map_port_8=44 +dport_map_port_9=45 +dport_map_port_10=46 +dport_map_port_11=47 +dport_map_port_12=48 +dport_map_port_13=49 +dport_map_port_14=50 +dport_map_port_15=51 +dport_map_port_16=52 +dport_map_port_17=53 +dport_map_port_18=54 +dport_map_port_60=55 +dport_map_port_61=56 +dport_map_port_62=57 +dport_map_port_63=58 +dport_map_port_64=59 +dport_map_port_65=60 +dport_map_port_66=61 +dport_map_port_67=62 +dport_map_port_68=63 +dport_map_port_69=64 +dport_map_port_70=65 +dport_map_port_71=66 +dport_map_port_72=67 +dport_map_port_73=68 +dport_map_port_74=69 +dport_map_port_75=70 +dport_map_port_76=71 +dport_map_port_77=72 +dport_map_port_80=73 +dport_map_port_81=74 +dport_map_port_82=75 +dport_map_port_83=76 +dport_map_port_84=77 +dport_map_port_85=78 +dport_map_port_86=79 +dport_map_port_87=80 +dport_map_port_88=81 +dport_map_port_89=82 +dport_map_port_90=83 +dport_map_port_91=84 +dport_map_port_92=85 +dport_map_port_93=86 +dport_map_port_94=87 +dport_map_port_95=88 +dport_map_port_96=89 +dport_map_port_97=90 +dport_map_port_140=91 +dport_map_port_141=92 +dport_map_port_142=93 +dport_map_port_143=94 +dport_map_port_144=95 +dport_map_port_145=96 +dport_map_port_146=97 +dport_map_port_147=98 +dport_map_port_148=99 +dport_map_port_149=100 +dport_map_port_150=101 +dport_map_port_151=102 +dport_map_port_152=103 +dport_map_port_153=104 +dport_map_port_154=105 +dport_map_port_155=106 +dport_map_port_156=107 +dport_map_port_157=108 +dport_map_port_100=109 +dport_map_port_101=110 +dport_map_port_102=111 +dport_map_port_103=112 +dport_map_port_104=113 +dport_map_port_105=114 +dport_map_port_106=115 +dport_map_port_107=116 +dport_map_port_108=117 +dport_map_port_109=118 +dport_map_port_110=119 +dport_map_port_111=120 +dport_map_port_112=121 +dport_map_port_113=122 +dport_map_port_114=123 +dport_map_port_115=124 +dport_map_port_116=125 +dport_map_port_117=126 +dport_map_port_120=127 +dport_map_port_121=128 +dport_map_port_122=129 +dport_map_port_123=130 +dport_map_port_124=131 +dport_map_port_125=132 +dport_map_port_126=133 +dport_map_port_127=134 +dport_map_port_128=135 +dport_map_port_129=136 +dport_map_port_130=137 +dport_map_port_131=138 +dport_map_port_132=139 +dport_map_port_133=140 +dport_map_port_134=141 +dport_map_port_135=142 +dport_map_port_136=143 +dport_map_port_137=144 +dport_map_port_38=145 +dport_map_port_118=146 + +phy_chain_rx_lane_map_physical{33.0}=0x65732041 +phy_chain_tx_lane_map_physical{33.0}=0x47206531 +phy_chain_rx_lane_map_physical{41.0}=0x07561243 +phy_chain_tx_lane_map_physical{41.0}=0x36207514 +phy_chain_rx_lane_map_physical{49.0}=0x54632071 +phy_chain_tx_lane_map_physical{49.0}=0x06241735 +phy_chain_rx_lane_map_physical{57.0}=0x07561243 +phy_chain_tx_lane_map_physical{57.0}=0x35207614 +phy_chain_rx_lane_map_physical{65.0}=0x45623170 +phy_chain_tx_lane_map_physical{65.0}=0x51260734 +phy_chain_rx_lane_map_physical{73.0}=0x07561243 +phy_chain_tx_lane_map_physical{73.0}=0x37245610 +phy_chain_rx_lane_map_physical{81.0}=0x45632071 +phy_chain_tx_lane_map_physical{81.0}=0x51260734 +phy_chain_rx_lane_map_physical{89.0}=0x07561243 +phy_chain_tx_lane_map_physical{89.0}=0x26437510 +phy_chain_rx_lane_map_physical{1.0}=0x30176524 +phy_chain_tx_lane_map_physical{1.0}=0x20615374 +phy_chain_rx_lane_map_physical{9.0}=0x37562041 +phy_chain_tx_lane_map_physical{9.0}=0x05176432 +phy_chain_rx_lane_map_physical{17.0}=0x43607251 +phy_chain_tx_lane_map_physical{17.0}=0x70261435 +phy_chain_rx_lane_map_physical{25.0}=0x60347125 +phy_chain_tx_lane_map_physical{25.0}=0x46357120 +phy_chain_rx_lane_map_physical{97.0}=0x47601352 +phy_chain_tx_lane_map_physical{97.0}=0x04265137 +phy_chain_rx_lane_map_physical{105.0}=0x73206415 +phy_chain_tx_lane_map_physical{105.0}=0x26374150 +phy_chain_rx_lane_map_physical{113.0}=0x47632051 +phy_chain_tx_lane_map_physical{113.0}=0x03254617 +phy_chain_rx_lane_map_physical{121.0}=0x63027415 +phy_chain_tx_lane_map_physical{121.0}=0x63721045 +phy_chain_rx_lane_map_physical{129.0}=0x30154627 +phy_chain_tx_lane_map_physical{129.0}=0x04735261 +phy_chain_rx_lane_map_physical{137.0}=0x24753061 +phy_chain_tx_lane_map_physical{137.0}=0x37614520 +phy_chain_rx_lane_map_physical{145.0}=0x47601352 +phy_chain_tx_lane_map_physical{145.0}=0x63274510 +phy_chain_rx_lane_map_physical{153.0}=0x07361524 +phy_chain_tx_lane_map_physical{153.0}=0x36527104 +phy_chain_rx_lane_map_physical{225.0}=0x56410273 +phy_chain_tx_lane_map_physical{225.0}=0x10274635 +phy_chain_rx_lane_map_physical{233.0}=0x15740263 +phy_chain_tx_lane_map_physical{233.0}=0x24351607 +phy_chain_rx_lane_map_physical{241.0}=0x74015263 +phy_chain_tx_lane_map_physical{241.0}=0x04152637 +phy_chain_rx_lane_map_physical{249.0}=0x62037514 +phy_chain_tx_lane_map_physical{249.0}=0x72453160 +phy_chain_rx_lane_map_physical{161.0}=0x46510273 +phy_chain_tx_lane_map_physical{161.0}=0x01653724 +phy_chain_rx_lane_map_physical{169.0}=0x25743160 +phy_chain_tx_lane_map_physical{169.0}=0x07216435 +phy_chain_rx_lane_map_physical{177.0}=0x46510273 +phy_chain_tx_lane_map_physical{177.0}=0x01652734 +phy_chain_rx_lane_map_physical{185.0}=0x25743160 +phy_chain_tx_lane_map_physical{185.0}=0x37016425 +phy_chain_rx_lane_map_physical{193.0}=0x46510372 +phy_chain_tx_lane_map_physical{193.0}=0x06153724 +phy_chain_rx_lane_map_physical{201.0}=0x25743160 +phy_chain_tx_lane_map_physical{201.0}=0x36017524 +phy_chain_rx_lane_map_physical{209.0}=0x47601352 +phy_chain_tx_lane_map_physical{209.0}=0x04152736 +phy_chain_rx_lane_map_physical{217.0}=0x26453170 +phy_chain_tx_lane_map_physical{217.0}=0x36027415 + +serdes_core_rx_polarity_flip_physical{33}=0x29 +serdes_core_tx_polarity_flip_physical{33}=0xfe +serdes_core_rx_polarity_flip_physical{41}=0xb1 +serdes_core_tx_polarity_flip_physical{41}=0xe8 +serdes_core_rx_polarity_flip_physical{49}=0xca +serdes_core_tx_polarity_flip_physical{49}=0xb6 +serdes_core_rx_polarity_flip_physical{57}=0x9b +serdes_core_tx_polarity_flip_physical{57}=0xdc +serdes_core_rx_polarity_flip_physical{65}=0x17 +serdes_core_tx_polarity_flip_physical{65}=0x86 +serdes_core_rx_polarity_flip_physical{73}=0x9b +serdes_core_tx_polarity_flip_physical{73}=0x55 +serdes_core_rx_polarity_flip_physical{81}=0xa +serdes_core_tx_polarity_flip_physical{81}=0x6 +serdes_core_rx_polarity_flip_physical{89}=0x9b +serdes_core_tx_polarity_flip_physical{89}=0x48 +serdes_core_rx_polarity_flip_physical{1}=0xec +serdes_core_tx_polarity_flip_physical{1}=0x56 +serdes_core_rx_polarity_flip_physical{9}=0x13 +serdes_core_tx_polarity_flip_physical{9}=0xa6 +serdes_core_rx_polarity_flip_physical{17}=0x5a +serdes_core_tx_polarity_flip_physical{17}=0xc6 +serdes_core_rx_polarity_flip_physical{25}=0xf +serdes_core_tx_polarity_flip_physical{25}=0x4e +serdes_core_rx_polarity_flip_physical{97}=0x17 +serdes_core_tx_polarity_flip_physical{97}=0x2e +serdes_core_rx_polarity_flip_physical{105}=0xce +serdes_core_tx_polarity_flip_physical{105}=0x7c +serdes_core_rx_polarity_flip_physical{113}=0xa +serdes_core_tx_polarity_flip_physical{113}=0x35 + +serdes_core_rx_polarity_flip_physical{121}=0xb9 +serdes_core_tx_polarity_flip_physical{121}=0xef +serdes_core_rx_polarity_flip_physical{129}=0xe8 +serdes_core_tx_polarity_flip_physical{129}=0xac +serdes_core_rx_polarity_flip_physical{137}=0xcb +serdes_core_tx_polarity_flip_physical{137}=0x9c +serdes_core_rx_polarity_flip_physical{145}=0x17 +serdes_core_tx_polarity_flip_physical{145}=0x32 +serdes_core_rx_polarity_flip_physical{153}=0xb9 +serdes_core_tx_polarity_flip_physical{153}=0xaf +serdes_core_rx_polarity_flip_physical{225}=0xaa +serdes_core_tx_polarity_flip_physical{225}=0x7 +serdes_core_rx_polarity_flip_physical{233}=0x31 +serdes_core_tx_polarity_flip_physical{233}=0x47 +serdes_core_rx_polarity_flip_physical{241}=0xe8 +serdes_core_tx_polarity_flip_physical{241}=0x9e +serdes_core_rx_polarity_flip_physical{249}=0xec +serdes_core_tx_polarity_flip_physical{249}=0x1f +serdes_core_rx_polarity_flip_physical{161}=0x6a +serdes_core_tx_polarity_flip_physical{161}=0xd4 +serdes_core_rx_polarity_flip_physical{169}=0x9e +serdes_core_tx_polarity_flip_physical{169}=0x7b +serdes_core_rx_polarity_flip_physical{177}=0x6a +serdes_core_tx_polarity_flip_physical{177}=0xcc +serdes_core_rx_polarity_flip_physical{185}=0x9e +serdes_core_tx_polarity_flip_physical{185}=0x58 +serdes_core_rx_polarity_flip_physical{193}=0x6f +serdes_core_tx_polarity_flip_physical{193}=0x24 +serdes_core_rx_polarity_flip_physical{201}=0x9e +serdes_core_tx_polarity_flip_physical{201}=0xdf +serdes_core_rx_polarity_flip_physical{209}=0x17 +serdes_core_tx_polarity_flip_physical{209}=0xe9 +serdes_core_rx_polarity_flip_physical{217}=0xec +serdes_core_tx_polarity_flip_physical{217}=0x68 + +serdes_lane_config_media_type_49=copper +serdes_lane_config_media_type_50=copper +serdes_lane_config_media_type_51=copper +serdes_lane_config_media_type_52=copper +serdes_lane_config_media_type_54=copper +serdes_lane_config_media_type_55=copper +serdes_lane_config_media_type_56=copper +serdes_lane_config_media_type_57=copper +serdes_lane_config_media_type_53=copper +serdes_lane_config_media_type_60=copper +serdes_lane_config_media_type_61=copper +serdes_lane_config_media_type_62=copper +serdes_lane_config_media_type_63=copper +serdes_lane_config_media_type_65=copper +serdes_lane_config_media_type_66=copper +serdes_lane_config_media_type_67=copper +serdes_lane_config_media_type_68=copper +serdes_lane_config_media_type_64=copper +serdes_lane_config_media_type_80=copper +serdes_lane_config_media_type_81=copper +serdes_lane_config_media_type_82=copper +serdes_lane_config_media_type_83=copper +serdes_lane_config_media_type_85=copper +serdes_lane_config_media_type_86=copper +serdes_lane_config_media_type_87=copper +serdes_lane_config_media_type_88=copper +serdes_lane_config_media_type_84=copper +serdes_lane_config_media_type_100=copper +serdes_lane_config_media_type_101=copper +serdes_lane_config_media_type_102=copper +serdes_lane_config_media_type_103=copper +serdes_lane_config_media_type_105=copper +serdes_lane_config_media_type_106=copper +serdes_lane_config_media_type_107=copper +serdes_lane_config_media_type_108=copper +serdes_lane_config_media_type_104=copper +serdes_lane_config_media_type_120=copper +serdes_lane_config_media_type_121=copper +serdes_lane_config_media_type_122=copper +serdes_lane_config_media_type_123=copper +serdes_lane_config_media_type_125=copper +serdes_lane_config_media_type_126=copper +serdes_lane_config_media_type_127=copper +serdes_lane_config_media_type_128=copper +serdes_lane_config_media_type_124=copper +serdes_lane_config_media_type_140=copper +serdes_lane_config_media_type_141=copper +serdes_lane_config_media_type_142=copper +serdes_lane_config_media_type_143=copper +serdes_lane_config_media_type_145=copper +serdes_lane_config_media_type_146=copper +serdes_lane_config_media_type_147=copper +serdes_lane_config_media_type_148=copper +serdes_lane_config_media_type_144=copper +serdes_lane_config_media_type_40=copper +serdes_lane_config_media_type_41=copper +serdes_lane_config_media_type_42=copper +serdes_lane_config_media_type_43=copper +serdes_lane_config_media_type_45=copper +serdes_lane_config_media_type_46=copper +serdes_lane_config_media_type_47=copper +serdes_lane_config_media_type_48=copper +serdes_lane_config_media_type_44=copper +serdes_lane_config_media_type_69=copper +serdes_lane_config_media_type_70=copper +serdes_lane_config_media_type_71=copper +serdes_lane_config_media_type_72=copper +serdes_lane_config_media_type_74=copper +serdes_lane_config_media_type_75=copper +serdes_lane_config_media_type_76=copper +serdes_lane_config_media_type_77=copper +serdes_lane_config_media_type_73=copper +serdes_lane_config_media_type_1=copper +serdes_lane_config_media_type_2=copper +serdes_lane_config_media_type_3=copper +serdes_lane_config_media_type_4=copper +serdes_lane_config_media_type_6=copper +serdes_lane_config_media_type_7=copper +serdes_lane_config_media_type_8=copper +serdes_lane_config_media_type_9=copper +serdes_lane_config_media_type_5=copper +serdes_lane_config_media_type_29=copper +serdes_lane_config_media_type_30=copper +serdes_lane_config_media_type_31=copper +serdes_lane_config_media_type_32=copper +serdes_lane_config_media_type_34=copper +serdes_lane_config_media_type_35=copper +serdes_lane_config_media_type_36=copper +serdes_lane_config_media_type_37=copper +serdes_lane_config_media_type_33=copper +serdes_lane_config_media_type_89=copper +serdes_lane_config_media_type_90=copper +serdes_lane_config_media_type_91=copper +serdes_lane_config_media_type_92=copper +serdes_lane_config_media_type_94=copper +serdes_lane_config_media_type_95=copper +serdes_lane_config_media_type_96=copper +serdes_lane_config_media_type_97=copper +serdes_lane_config_media_type_93=copper +serdes_lane_config_media_type_109=copper +serdes_lane_config_media_type_110=copper +serdes_lane_config_media_type_111=copper +serdes_lane_config_media_type_112=copper +serdes_lane_config_media_type_114=copper +serdes_lane_config_media_type_115=copper +serdes_lane_config_media_type_116=copper +serdes_lane_config_media_type_117=copper +serdes_lane_config_media_type_113=copper +serdes_lane_config_media_type_129=copper +serdes_lane_config_media_type_130=copper +serdes_lane_config_media_type_131=copper +serdes_lane_config_media_type_132=copper +serdes_lane_config_media_type_134=copper +serdes_lane_config_media_type_135=copper +serdes_lane_config_media_type_136=copper +serdes_lane_config_media_type_137=copper +serdes_lane_config_media_type_133=copper +serdes_lane_config_media_type_149=copper +serdes_lane_config_media_type_150=copper +serdes_lane_config_media_type_151=copper +serdes_lane_config_media_type_152=copper +serdes_lane_config_media_type_154=copper +serdes_lane_config_media_type_155=copper +serdes_lane_config_media_type_156=copper +serdes_lane_config_media_type_157=copper +serdes_lane_config_media_type_153=copper +serdes_lane_config_media_type_10=copper +serdes_lane_config_media_type_11=copper +serdes_lane_config_media_type_12=copper +serdes_lane_config_media_type_13=copper +serdes_lane_config_media_type_15=copper +serdes_lane_config_media_type_16=copper +serdes_lane_config_media_type_17=copper +serdes_lane_config_media_type_18=copper +serdes_lane_config_media_type_14=copper +serdes_lane_config_media_type_20=copper +serdes_lane_config_media_type_21=copper +serdes_lane_config_media_type_22=copper +serdes_lane_config_media_type_23=copper +serdes_lane_config_media_type_25=copper +serdes_lane_config_media_type_26=copper +serdes_lane_config_media_type_27=copper +serdes_lane_config_media_type_28=copper +serdes_lane_config_media_type_24=copper + +#sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc +sai_postinit_cmd_file=/usr/share/sonic/hwsku/sai_postinit_cmd.soc + diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/default_sku b/device/dell/x86_64-dellemc_z9332f_d1508-r0/default_sku new file mode 100644 index 000000000000..7716a7af3216 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/default_sku @@ -0,0 +1 @@ +DellEMC-Z9332f-O32 t1 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/installer.conf b/device/dell/x86_64-dellemc_z9332f_d1508-r0/installer.conf new file mode 100644 index 000000000000..924e0fb81963 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/installer.conf @@ -0,0 +1,2 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/led_proc_init.soc b/device/dell/x86_64-dellemc_z9332f_d1508-r0/led_proc_init.soc new file mode 100644 index 000000000000..0c116f35f80b --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/led_proc_init.soc @@ -0,0 +1,7 @@ +# LED microprocessor initialization for Dell z9332f +# +# +#Led0 +#Support only after SAI 3.6 +#led auto on +#led start diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/eeprom.py b/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/eeprom.py new file mode 100644 index 000000000000..e224cd452496 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/eeprom.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +############################################################################# +# DellEMC Z9332f +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + 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/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/psuutil.py b/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/psuutil.py new file mode 100644 index 000000000000..b2c373de358f --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/psuutil.py @@ -0,0 +1,126 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + + +import os.path +import logging +import commands +import sys + + +Z9332F_MAX_PSUS = 2 +IPMI_PSU1_DATA = "docker exec -it pmon ipmitool raw 0x04 0x2d 0x2f | awk '{print substr($0,9,1)}'" +IPMI_PSU1_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x2f | awk '{print substr($0,9,1)}'" +IPMI_PSU2_DATA = "docker exec -it pmon ipmitool raw 0x04 0x2d 0x39 | awk '{print substr($0,9,1)}'" +IPMI_PSU2_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x39 | awk '{print substr($0,9,1)}'" +PSU_PRESENCE = "PSU{0}_Status" +# Use this for older firmware +# PSU_PRESENCE="PSU{0}_prsnt" +ipmi_sdr_list = "" + + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + def isDockerEnv(self): + num_docker = open('/proc/self/cgroup', 'r').read().count(":/docker") + if num_docker > 0: + return True + else: + return False + + # Fetch a BMC register + def get_pmc_register(self, reg_name): + + status = 1 + global ipmi_sdr_list + ipmi_dev_node = "/dev/pmi0" + ipmi_cmd_1 = IPMI_PSU1_DATA + ipmi_cmd_2 = IPMI_PSU1_DATA + dockerenv = self.isDockerEnv() + if dockerenv == True: + if index == 1: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + 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 ipmitool') + sys.exit(0) + + output = ipmi_sdr_list + + return output + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + Z9332F_MAX_PSUS = 2 + return Z9332F_MAX_PSUS + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is\ + faulty + """ + # Until psu_status is implemented this is hardcoded temporarily + + status = 1 + return status + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + ret_status = 1 + global ipmi_sdr_list + ipmi_dev_node = "/dev/pmi0" + dockerenv = self.isDockerEnv() + if dockerenv == True: + if index == 1: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + else: + if index == 1: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA) + elif index == 2: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA) + + #if ret_status: + # print ipmi_sdr_list + # logging.error('Failed to execute ipmitool') + # sys.exit(0) + + psu_status = ipmi_sdr_list + + if psu_status == '1': + status = 1 + + return status + diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/sfputil.py new file mode 100644 index 000000000000..1ea6af1f8d26 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/plugins/sfputil.py @@ -0,0 +1,307 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import struct + import sys + import getopt + import time + import select + from sonic_sfp.sfputilbase import SfpUtilBase + from os import * + from mmap import * + +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +#from xcvrd +SFP_STATUS_REMOVED = '0' +SFP_STATUS_INSERTED = '1' + + + + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 1 + PORT_END = 34 + PORTS_IN_BLOCK = 34 + + BASE_RES_PATH = "/sys/bus/pci/devices/0000:09:00.0/resource0" + + _port_to_i2c_mapping = { + 1: 10, + 2: 11, + 3: 12, + 4: 13, + 5: 14, + 6: 15, + 7: 16, + 8: 17, + 9: 18, + 10: 19, + 11: 20, + 12: 21, + 13: 22, + 14: 23, + 15: 24, + 16: 25, + 17: 26, + 18: 27, + 19: 28, + 20: 29, + 21: 30, + 22: 31, + 23: 32, + 24: 33, + 25: 34, + 26: 35, + 27: 36, + 28: 37, + 29: 38, + 30: 39, + 31: 40, + 32: 41, + 33: 1, + 34: 2, + } + + _port_to_eeprom_mapping = {} + + _global_port_pres_dict = {} + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return range(self.PORT_START, self.PORTS_IN_BLOCK + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def pci_mem_read(self, mm, offset): + mm.seek(offset) + read_data_stream = mm.read(4) + reg_val = struct.unpack('I', read_data_stream) + mem_val = str(reg_val)[1:-2] + # print "reg_val read:%x"%reg_val + return mem_val + + def pci_mem_write(self, mm, offset, data): + mm.seek(offset) + # print "data to write:%x"%data + mm.write(struct.pack('I', data)) + + def pci_set_value(self, resource, val, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + val = self.pci_mem_write(mm, offset, val) + mm.close() + close(fd) + return val + + def pci_get_value(self, resource, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + val = self.pci_mem_read(mm, offset) + mm.close() + close(fd) + return val + + def init_global_port_presence(self): + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + if(presence): + self._global_port_pres_dict[port_num] = '1' + else: + self._global_port_pres_dict[port_num] = '0' + + def mod_pres(self): + port_pres_mask =0 + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + if(presence): + self._global_port_pres_dict[port_num] = '1' + port_val = (1 << (port_num -1)) + port_pres_mask = (port_pres_mask | port_val) + else: + self._global_port_pres_dict[port_num] = '0' + port_val = ~(1 << (port_num -1)) + port_pres_mask = (port_pres_mask & port_val) + + return port_pres_mask + + + def __init__(self): + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + + for x in range(self.port_start, self.port_end + 1): + self.port_to_eeprom_mapping[x] = eeprom_path.format( + self._port_to_i2c_mapping[x]) + self.init_global_port_presence() + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4004 + port_offset = 16388 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 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 + + return False + + def get_low_power_mode(self, port_num): + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 4th bit for presence + mask = (1 << 6) + + # LPMode is active high + if reg_value & mask == 0: + return False + + return True + + def set_low_power_mode(self, port_num, lpmode): + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 4th bit for presence + mask = (1 << 6) + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + reg_value = reg_value | mask + else: + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + return True + + def reset(self, port_num): + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 4th bit for presence + mask = (1 << 6) + + # ResetL is active low + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + # Sleep 1 second to allow it to settle + time.sleep(1) + + reg_value = reg_value | mask + + # Convert our register value back to a hex string and write back + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + return True + + def get_register(self, reg_file): + retval = 'ERR' + if (not path.isfile(reg_file)): + print reg_file, 'not found !' + return retval + + try: + with fdopen(open(reg_file, O_RDONLY)) as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", reg_file, "file !") + + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + return retval + + 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) + + diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index 8cbf72695920..7436fef0ef1b 100644 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -9,6 +9,7 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(DELL_Z9264F_PLATFORM_MODULE) \ $(DELL_S5232F_PLATFORM_MODULE) \ $(DELL_S5248F_PLATFORM_MODULE) \ + $(DELL_Z9332F_PLATFORM_MODULE) \ $(DELL_Z9100_PLATFORM_MODULE) \ $(DELL_S6100_PLATFORM_MODULE) \ $(INGRASYS_S8900_54XC_PLATFORM_MODULE) \ diff --git a/platform/broadcom/platform-modules-dell.mk b/platform/broadcom/platform-modules-dell.mk index 583f74f72d8b..298e3c4f7396 100644 --- a/platform/broadcom/platform-modules-dell.mk +++ b/platform/broadcom/platform-modules-dell.mk @@ -1,10 +1,11 @@ -# Dell S6000,Z9100, S6100, Z9264F , S5232 Platform modules +# Dell S6000,Z9100, S6100, Z9264F , S5232F,Z9332F Platform modules DELL_S6000_PLATFORM_MODULE_VERSION = 1.1 DELL_Z9100_PLATFORM_MODULE_VERSION = 1.1 DELL_S6100_PLATFORM_MODULE_VERSION = 1.1 DELL_Z9264F_PLATFORM_MODULE_VERSION = 1.1 DELL_S5232F_PLATFORM_MODULE_VERSION = 1.1 +DELL_Z9332F_PLATFORM_MODULE_VERSION = 1.1 DELL_S5248F_PLATFORM_MODULE_VERSION = 1.1 export DELL_S6000_PLATFORM_MODULE_VERSION @@ -12,6 +13,7 @@ export DELL_Z9100_PLATFORM_MODULE_VERSION export DELL_S6100_PLATFORM_MODULE_VERSION export DELL_Z9264F_PLATFORM_MODULE_VERSION export DELL_S5232F_PLATFORM_MODULE_VERSION +export DELL_Z9332F_PLATFORM_MODULE_VERSION export DELL_S5248F_PLATFORM_MODULE_VERSION DELL_Z9100_PLATFORM_MODULE = platform-modules-z9100_$(DELL_Z9100_PLATFORM_MODULE_VERSION)_amd64.deb @@ -37,6 +39,10 @@ DELL_S5232F_PLATFORM_MODULE = platform-modules-s5232f_$(DELL_S5232F_PLATFORM_MOD $(DELL_S5232F_PLATFORM_MODULE)_PLATFORM = x86_64-dellemc_s5232f_c3538-r0 $(eval $(call add_extra_package,$(DELL_Z9100_PLATFORM_MODULE),$(DELL_S5232F_PLATFORM_MODULE))) +DELL_Z9332F_PLATFORM_MODULE = platform-modules-z9332f_$(DELL_Z9332F_PLATFORM_MODULE_VERSION)_amd64.deb +$(DELL_Z9332F_PLATFORM_MODULE)_PLATFORM = x86_64-dellemc_z9332f_d1508-r0 +$(eval $(call add_extra_package,$(DELL_Z9100_PLATFORM_MODULE),$(DELL_Z9332F_PLATFORM_MODULE))) + DELL_S5248F_PLATFORM_MODULE = platform-modules-s5248f_$(DELL_S5248F_PLATFORM_MODULE_VERSION)_amd64.deb $(DELL_S5248F_PLATFORM_MODULE)_PLATFORM = x86_64-dellemc_s5248f_c3538-r0 $(eval $(call add_extra_package,$(DELL_Z9100_PLATFORM_MODULE),$(DELL_S5248F_PLATFORM_MODULE))) diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/control b/platform/broadcom/sonic-platform-modules-dell/debian/control index f32fa7244acc..3131890e6353 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/control +++ b/platform/broadcom/sonic-platform-modules-dell/debian/control @@ -34,3 +34,8 @@ Package: platform-modules-s5248f Architecture: amd64 Depends: linux-image-4.9.0-9-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp + +Package: platform-modules-z9332f +Architecture: amd64 +Depends: linux-image-4.9.0-9-2-amd64 +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.init b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.init new file mode 100644 index 000000000000..f4fe9eb396fd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.init @@ -0,0 +1,39 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup Z9332f board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + + /usr/local/bin/z9332f_platform.sh init + + echo "done." + ;; + +stop) + /usr/local/bin/z9332f_platform.sh deinit + echo "done." + + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-z9332f.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.install new file mode 100644 index 000000000000..16d2b952186f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.install @@ -0,0 +1,7 @@ +z9332f/scripts/z9332f_platform.sh usr/local/bin +z9332f/scripts/platform_sensors.py usr/local/bin +z9332f/scripts/sensors usr/bin +z9332f/scripts/pcisysfs.py usr/bin +z9332f/cfg/z9332f-modules.conf etc/modules-load.d +z9332f/systemd/platform-modules-z9332f.service etc/systemd/system +common/platform_reboot usr/share/sonic/device/x86_64-dellemc_z9332f_d1508-r0 diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.postinst b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.postinst new file mode 100644 index 000000000000..3a3a72cb304a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.postinst @@ -0,0 +1,10 @@ +# postinst script for Z9332f + +# Enable Dell-Z9332f-platform-service +depmod -a +systemctl enable platform-modules-z9332f.service +systemctl start platform-modules-z9332f.service + + +#DEBHELPER# + diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/rules b/platform/broadcom/sonic-platform-modules-dell/debian/rules index a7f68a21f55a..8af0642b40d3 100755 --- a/platform/broadcom/sonic-platform-modules-dell/debian/rules +++ b/platform/broadcom/sonic-platform-modules-dell/debian/rules @@ -5,7 +5,7 @@ export INSTALL_MOD_DIR:=extra KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= s6000 z9100 s6100 z9264f s5232f s5248f +MODULE_DIRS:= s6000 z9100 s6100 z9264f s5232f s5248f z9332f COMMON_DIR := common %: diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/cfg/z9332f-modules.conf b/platform/broadcom/sonic-platform-modules-dell/z9332f/cfg/z9332f-modules.conf new file mode 100644 index 000000000000..b6d4fe4fb00a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/cfg/z9332f-modules.conf @@ -0,0 +1,17 @@ +# /etc/modules: kernel modules to load at boot time. +# +# This file contains the names of kernel modules that should be loaded +# at boot time, one per line. Lines beginning with "#" are ignored. + +i2c-i801 +i2c-isch +i2c-ismt +i2c-dev +i2c-mux +i2c-smbus + +i2c-mux-gpio +i2c-mux-pca954x + +ipmi_devintf +ipmi_si diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/Makefile b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/Makefile new file mode 100644 index 000000000000..bb71bb0d9185 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/Makefile @@ -0,0 +1,4 @@ +obj-m += cls-switchboard.o +obj-m += cls-i2c-ocore.o +obj-m += mc24lc64t.o + diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-ocore.c b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-ocore.c new file mode 100644 index 000000000000..c80757e6619d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-ocore.c @@ -0,0 +1,845 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * cls-i2c-ocores.c: I2C bus driver for OpenCores I2C controller + * (https://opencores.org/project/i2c/overview) + * + * Peter Korsgaard + * + * Support for the GRLIB port of the controller by + * Andreas Larsson + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#include +#include +#include +#include +#include +#include "cls-i2c-ocore.h" + +#define OCORES_FLAG_POLL BIT(0) + +/* + * 'process_lock' exists because ocores_process() and ocores_process_timeout() + * can't run in parallel. + */ +struct ocores_i2c { + void __iomem *base; + int iobase; + u32 reg_shift; + u32 reg_io_width; + unsigned long flags; + wait_queue_head_t wait; + struct i2c_adapter adap; + struct i2c_msg *msg; + int pos; + int nmsgs; + int state; /* see STATE_ */ + int nack_retry; + spinlock_t process_lock; + struct clk *clk; + int ip_clock_khz; + int bus_clock_khz; + void (*setreg)(struct ocores_i2c *i2c, int reg, u8 value); + u8 (*getreg)(struct ocores_i2c *i2c, int reg); +}; + +/* registers */ +#define OCI2C_PRELOW 0 +#define OCI2C_PREHIGH 1 +#define OCI2C_CONTROL 2 +#define OCI2C_DATA 3 +#define OCI2C_CMD 4 /* write only */ +#define OCI2C_STATUS 4 /* read only, same address as OCI2C_CMD */ + +#define OCI2C_CTRL_IEN 0x40 +#define OCI2C_CTRL_EN 0x80 + +#define OCI2C_CMD_START 0x91 +#define OCI2C_CMD_STOP 0x41 +#define OCI2C_CMD_READ 0x21 +#define OCI2C_CMD_WRITE 0x11 +#define OCI2C_CMD_READ_ACK 0x21 +#define OCI2C_CMD_READ_NACK 0x29 +#define OCI2C_CMD_IACK 0x01 + +#define OCI2C_STAT_IF 0x01 +#define OCI2C_STAT_TIP 0x02 +#define OCI2C_STAT_ARBLOST 0x20 +#define OCI2C_STAT_BUSY 0x40 +#define OCI2C_STAT_NACK 0x80 + +#define STATE_DONE 0 +#define STATE_START 1 +#define STATE_WRITE 2 +#define STATE_READ 3 +#define STATE_ERROR 4 + +#define TYPE_OCORES 0 +#define TYPE_GRLIB 1 + +static void oc_setreg_8(struct ocores_i2c *i2c, int reg, u8 value) +{ + iowrite8(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void oc_setreg_16(struct ocores_i2c *i2c, int reg, u8 value) +{ + iowrite16(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void oc_setreg_32(struct ocores_i2c *i2c, int reg, u8 value) +{ + iowrite32(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void oc_setreg_16be(struct ocores_i2c *i2c, int reg, u8 value) +{ + iowrite16be(value, i2c->base + (reg << i2c->reg_shift)); +} + +static void oc_setreg_32be(struct ocores_i2c *i2c, int reg, u8 value) +{ + iowrite32be(value, i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 oc_getreg_8(struct ocores_i2c *i2c, int reg) +{ + return ioread8(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 oc_getreg_16(struct ocores_i2c *i2c, int reg) +{ + return ioread16(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 oc_getreg_32(struct ocores_i2c *i2c, int reg) +{ + return ioread32(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 oc_getreg_16be(struct ocores_i2c *i2c, int reg) +{ + return ioread16be(i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 oc_getreg_32be(struct ocores_i2c *i2c, int reg) +{ + return ioread32be(i2c->base + (reg << i2c->reg_shift)); +} + +static void oc_setreg_io_8(struct ocores_i2c *i2c, int reg, u8 value) +{ + outb(value, i2c->iobase + reg); +} + +static inline u8 oc_getreg_io_8(struct ocores_i2c *i2c, int reg) +{ + return inb(i2c->iobase + reg); +} + +static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value) +{ + i2c->setreg(i2c, reg, value); +} + +static inline u8 oc_getreg(struct ocores_i2c *i2c, int reg) +{ + return i2c->getreg(i2c, reg); +} + +static void ocores_process(struct ocores_i2c *i2c, u8 stat) +{ + struct i2c_msg *msg = i2c->msg; + unsigned long flags; + + /* + * If we spin here is because we are in timeout, so we are going + * to be in STATE_ERROR. See ocores_process_timeout() + */ + spin_lock_irqsave(&i2c->process_lock, flags); + + dev_dbg(&i2c->adap.dev, "STATE: %d\n", i2c->state); + + if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) { + /* stop has been sent */ + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); + wake_up(&i2c->wait); + goto out; + } + + /* error? */ + if (stat & OCI2C_STAT_ARBLOST) { + // i2c->state = STATE_ERROR; + i2c->state = STATE_START; + // i2c->nack_retry = 1; + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); + dev_dbg(&i2c->adap.dev, "ERR: AL\n"); + goto out; + } + + if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) { + i2c->state = + (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; + + if (stat & OCI2C_STAT_NACK) { + dev_dbg(&i2c->adap.dev, "ERR: NACK\n"); + // printk(KERN_INFO "ERR: NACK\n"); + i2c->state = STATE_ERROR; + if(!(msg->flags & I2C_M_RD)) + i2c->nack_retry = 1; + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); + goto out; + } + } else { + msg->buf[i2c->pos++] = oc_getreg(i2c, OCI2C_DATA); + } + + /* end of msg? */ + if (i2c->pos == msg->len) { + i2c->nmsgs--; + i2c->msg++; + i2c->pos = 0; + msg = i2c->msg; + + if (i2c->nmsgs) { /* end? */ + /* send start? */ + if (!(msg->flags & I2C_M_NOSTART)) { + u8 addr = i2c_8bit_addr_from_msg(msg); + + i2c->state = STATE_START; + + oc_setreg(i2c, OCI2C_DATA, addr); + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); + goto out; + } + i2c->state = (msg->flags & I2C_M_RD) + ? STATE_READ : STATE_WRITE; + } else { + i2c->state = STATE_DONE; + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); + goto out; + } + } + + if (i2c->state == STATE_READ) { + oc_setreg(i2c, OCI2C_CMD, i2c->pos == (msg->len-1) ? + OCI2C_CMD_READ_NACK : OCI2C_CMD_READ_ACK); + } else { + oc_setreg(i2c, OCI2C_DATA, msg->buf[i2c->pos++]); + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_WRITE); + } + +out: + spin_unlock_irqrestore(&i2c->process_lock, flags); +} + +static irqreturn_t ocores_isr(int irq, void *dev_id) +{ + struct ocores_i2c *i2c = dev_id; + u8 stat = oc_getreg(i2c, OCI2C_STATUS); + + dev_dbg(&i2c->adap.dev, "STATUS: 0x%x\n", stat); + // printk(KERN_INFO "STATUS: 0x%x\n", stat); + + if (!(stat & OCI2C_STAT_IF)) + return IRQ_NONE; + + ocores_process(i2c, stat); + + return IRQ_HANDLED; +} + +/** + * Process timeout event + * @i2c: ocores I2C device instance + */ +static void ocores_process_timeout(struct ocores_i2c *i2c) +{ + unsigned long flags; + + spin_lock_irqsave(&i2c->process_lock, flags); + i2c->state = STATE_ERROR; + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); + spin_unlock_irqrestore(&i2c->process_lock, flags); +} + +/** + * Wait until something change in a given register + * @i2c: ocores I2C device instance + * @reg: register to query + * @mask: bitmask to apply on register value + * @val: expected result + * @timeout: timeout in jiffies + * + * Timeout is necessary to avoid to stay here forever when the chip + * does not answer correctly. + * + * Return: 0 on success, -ETIMEDOUT on timeout + */ +static int ocores_wait(struct ocores_i2c *i2c, + int reg, u8 mask, u8 val, + const unsigned long timeout) +{ + unsigned long j; + + j = jiffies + timeout; + while (1) { + u8 status = oc_getreg(i2c, reg); + + if ((status & mask) == val) + break; + + if (time_after(jiffies, j)) + return -ETIMEDOUT; + cpu_relax(); + cond_resched(); + } + return 0; +} + +/** + * Wait until is possible to process some data + * @i2c: ocores I2C device instance + * + * Used when the device is in polling mode (interrupts disabled). + * + * Return: 0 on success, -ETIMEDOUT on timeout + */ +static int ocores_poll_wait(struct ocores_i2c *i2c) +{ + u8 mask; + int err; + + if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) { + /* transfer is over */ + mask = OCI2C_STAT_BUSY; + } else { + /* on going transfer */ + mask = OCI2C_STAT_TIP; + /* + * We wait for the data to be transferred (8bit), + * then we start polling on the ACK/NACK bit + */ + udelay((8 * 1000) / i2c->bus_clock_khz); + } + + dev_dbg(&i2c->adap.dev, "Wait for: 0x%x\n", mask); + // printk(KERN_INFO "Wait for: 0x%x\n", mask); + + /* + * once we are here we expect to get the expected result immediately + * so if after 1ms we timeout then something is broken. + */ + err = ocores_wait(i2c, OCI2C_STATUS, mask, 0, msecs_to_jiffies(30)); + if (err) + dev_warn(i2c->adap.dev.parent, + "%s: STATUS timeout, bit 0x%x did not clear in 1ms\n", + __func__, mask); + return err; +} + +/** + * It handles an IRQ-less transfer + * @i2c: ocores I2C device instance + * + * Even if IRQ are disabled, the I2C OpenCore IP behavior is exactly the same + * (only that IRQ are not produced). This means that we can re-use entirely + * ocores_isr(), we just add our polling code around it. + * + * It can run in atomic context + */ +static void ocores_process_polling(struct ocores_i2c *i2c) +{ + while (1) { + irqreturn_t ret; + int err; + + err = ocores_poll_wait(i2c); + if (err) { + i2c->state = STATE_ERROR; + break; /* timeout */ + } + + ret = ocores_isr(-1, i2c); + if (ret == IRQ_NONE) + break; /* all messages have been transferred */ + } +} + +static int ocores_xfer_core(struct ocores_i2c *i2c, + struct i2c_msg *msgs, int num, + bool polling) +{ + int ret; + u8 ctrl; + + ctrl = oc_getreg(i2c, OCI2C_CONTROL); + if (polling) + oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~OCI2C_CTRL_IEN); + else + oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_IEN); + + i2c->msg = msgs; + i2c->pos = 0; + i2c->nmsgs = num; + i2c->state = STATE_START; + + dev_dbg(&i2c->adap.dev, "STATE: %d\n", i2c->state); + // printk(KERN_INFO "STATE: %d\n", i2c->state); + + oc_setreg(i2c, OCI2C_DATA, i2c_8bit_addr_from_msg(i2c->msg)); + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); + + if (polling) { + ocores_process_polling(i2c); + } else { + ret = wait_event_timeout(i2c->wait, + (i2c->state == STATE_ERROR) || + (i2c->state == STATE_DONE), HZ); + if (ret == 0) { + ocores_process_timeout(i2c); + return -ETIMEDOUT; + } + } + + return (i2c->state == STATE_DONE) ? num : -EIO; +} + +static int ocores_xfer_polling(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + return ocores_xfer_core(i2c_get_adapdata(adap), msgs, num, true); +} + +static int ocores_xfer(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + int ret; + int retry=0; + int max_retry = 0; + struct ocores_i2c *i2c = i2c_get_adapdata(adap); + + i2c->nack_retry = 0; + + if (i2c->flags & OCORES_FLAG_POLL) + { + //return ocores_xfer_polling(adap, msgs, num); + ret = ocores_xfer_polling(adap, msgs, num); + // Fix i2cdetect issue + if(num == 1) + max_retry = 5; + else + max_retry = 5; + + while((i2c->nack_retry == 1)&&(retry < max_retry)) + { + retry++; + i2c->nack_retry = 0; + ret = ocores_xfer_polling(adap, msgs, num); + // printk("nack retry polling = %d\n",retry); + } + // if(i2c->nack_retry!=0){ + // printk("nack retry = %d, ret=%d\n",retry, ret); + // } + i2c->nack_retry = 0; + return ret; + } + return ocores_xfer_core(i2c, msgs, num, false); +} + +static int ocores_init(struct device *dev, struct ocores_i2c *i2c) +{ + int prescale; + int diff; + u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); + + /* make sure the device is disabled */ + ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN); + oc_setreg(i2c, OCI2C_CONTROL, ctrl); + + prescale = (i2c->ip_clock_khz / (5 * i2c->bus_clock_khz)) - 1; + prescale = clamp(prescale, 0, 0xffff); + + dev_info(dev, "Prescale: %d\n", prescale); + + diff = i2c->ip_clock_khz / (5 * (prescale + 1)) - i2c->bus_clock_khz; + if (abs(diff) > i2c->bus_clock_khz / 10) { + dev_err(dev, + "Unsupported clock settings: core: %d KHz, bus: %d KHz\n", + i2c->ip_clock_khz, i2c->bus_clock_khz); + return -EINVAL; + } + + oc_setreg(i2c, OCI2C_PRELOW, prescale & 0xff); + oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8); + + /* Init the device */ + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); + oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_EN); + + return 0; +} + + +static u32 ocores_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm ocores_algorithm = { + .master_xfer = ocores_xfer, + .functionality = ocores_func, +}; + +static const struct i2c_adapter ocores_adapter = { + .owner = THIS_MODULE, + .name = "i2c-goodcores", + .class = I2C_CLASS_DEPRECATED, + .algo = &ocores_algorithm, +}; + +static const struct of_device_id ocores_i2c_match[] = { + { + .compatible = "opencores,i2c-ocores", + .data = (void *)TYPE_OCORES, + }, + { + .compatible = "aeroflexgaisler,i2cmst", + .data = (void *)TYPE_GRLIB, + }, + {}, +}; +MODULE_DEVICE_TABLE(of, ocores_i2c_match); + +#ifdef CONFIG_OF +/* + * Read and write functions for the GRLIB port of the controller. Registers are + * 32-bit big endian and the PRELOW and PREHIGH registers are merged into one + * register. The subsequent registers have their offsets decreased accordingly. + */ +static u8 oc_getreg_grlib(struct ocores_i2c *i2c, int reg) +{ + u32 rd; + int rreg = reg; + + if (reg != OCI2C_PRELOW) + rreg--; + rd = ioread32be(i2c->base + (rreg << i2c->reg_shift)); + if (reg == OCI2C_PREHIGH) + return (u8)(rd >> 8); + else + return (u8)rd; +} + +static void oc_setreg_grlib(struct ocores_i2c *i2c, int reg, u8 value) +{ + u32 curr, wr; + int rreg = reg; + + if (reg != OCI2C_PRELOW) + rreg--; + if (reg == OCI2C_PRELOW || reg == OCI2C_PREHIGH) { + curr = ioread32be(i2c->base + (rreg << i2c->reg_shift)); + if (reg == OCI2C_PRELOW) + wr = (curr & 0xff00) | value; + else + wr = (((u32)value) << 8) | (curr & 0xff); + } else { + wr = value; + } + iowrite32be(wr, i2c->base + (rreg << i2c->reg_shift)); +} + +static int ocores_i2c_of_probe(struct platform_device *pdev, + struct ocores_i2c *i2c) +{ + struct device_node *np = pdev->dev.of_node; + const struct of_device_id *match; + u32 val; + u32 clock_frequency; + bool clock_frequency_present; + + if (of_property_read_u32(np, "reg-shift", &i2c->reg_shift)) { + /* no 'reg-shift', check for deprecated 'regstep' */ + if (!of_property_read_u32(np, "regstep", &val)) { + if (!is_power_of_2(val)) { + dev_err(&pdev->dev, "invalid regstep %d\n", + val); + return -EINVAL; + } + i2c->reg_shift = ilog2(val); + dev_warn(&pdev->dev, + "regstep property deprecated, use reg-shift\n"); + } + } + + clock_frequency_present = !of_property_read_u32(np, "clock-frequency", + &clock_frequency); + i2c->bus_clock_khz = 100; + + i2c->clk = devm_clk_get(&pdev->dev, NULL); + + if (!IS_ERR(i2c->clk)) { + int ret = clk_prepare_enable(i2c->clk); + + if (ret) { + dev_err(&pdev->dev, + "clk_prepare_enable failed: %d\n", ret); + return ret; + } + i2c->ip_clock_khz = clk_get_rate(i2c->clk) / 1000; + if (clock_frequency_present) + i2c->bus_clock_khz = clock_frequency / 1000; + } + + if (i2c->ip_clock_khz == 0) { + if (of_property_read_u32(np, "opencores,ip-clock-frequency", + &val)) { + if (!clock_frequency_present) { + dev_err(&pdev->dev, + "Missing required parameter 'opencores,ip-clock-frequency'\n"); + clk_disable_unprepare(i2c->clk); + return -ENODEV; + } + i2c->ip_clock_khz = clock_frequency / 1000; + dev_warn(&pdev->dev, + "Deprecated usage of the 'clock-frequency' property, please update to 'opencores,ip-clock-frequency'\n"); + } else { + i2c->ip_clock_khz = val / 1000; + if (clock_frequency_present) + i2c->bus_clock_khz = clock_frequency / 1000; + } + } + + of_property_read_u32(pdev->dev.of_node, "reg-io-width", + &i2c->reg_io_width); + + match = of_match_node(ocores_i2c_match, pdev->dev.of_node); + if (match && (long)match->data == TYPE_GRLIB) { + dev_dbg(&pdev->dev, "GRLIB variant of i2c-ocores\n"); + // printk(KERN_INFO "GRLIB variant of i2c-ocores\n"); + i2c->setreg = oc_setreg_grlib; + i2c->getreg = oc_getreg_grlib; + } + + return 0; +} +#else +#define ocores_i2c_of_probe(pdev, i2c) -ENODEV +#endif + +static int ocores_i2c_probe(struct platform_device *pdev) +{ + struct ocores_i2c *i2c; + struct ocores_i2c_platform_data *pdata; + struct resource *res; + int irq; + int ret; + int i; + + i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); + if (!i2c) + return -ENOMEM; + + spin_lock_init(&i2c->process_lock); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res) { + i2c->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(i2c->base)) + return PTR_ERR(i2c->base); + } else { + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (!res) + return -EINVAL; + i2c->iobase = res->start; + if (!devm_request_region(&pdev->dev, res->start, + resource_size(res), + pdev->name)) { + dev_err(&pdev->dev, "Can't get I/O resource.\n"); + return -EBUSY; + } + i2c->setreg = oc_setreg_io_8; + i2c->getreg = oc_getreg_io_8; + } + + pdata = dev_get_platdata(&pdev->dev); + if (pdata) { + i2c->reg_shift = pdata->reg_shift; + i2c->reg_io_width = pdata->reg_io_width; + i2c->ip_clock_khz = pdata->clock_khz; + if (pdata->bus_khz) + i2c->bus_clock_khz = pdata->bus_khz; + else + i2c->bus_clock_khz = 100; + } else { + ret = ocores_i2c_of_probe(pdev, i2c); + if (ret) + return ret; + } + + if (i2c->reg_io_width == 0) + i2c->reg_io_width = 1; /* Set to default value */ + + if (!i2c->setreg || !i2c->getreg) { + bool be = pdata ? pdata->big_endian : + of_device_is_big_endian(pdev->dev.of_node); + + switch (i2c->reg_io_width) { + case 1: + i2c->setreg = oc_setreg_8; + i2c->getreg = oc_getreg_8; + break; + + case 2: + i2c->setreg = be ? oc_setreg_16be : oc_setreg_16; + i2c->getreg = be ? oc_getreg_16be : oc_getreg_16; + break; + + case 4: + i2c->setreg = be ? oc_setreg_32be : oc_setreg_32; + i2c->getreg = be ? oc_getreg_32be : oc_getreg_32; + break; + + default: + dev_err(&pdev->dev, "Unsupported I/O width (%d)\n", + i2c->reg_io_width); + ret = -EINVAL; + goto err_clk; + } + } + + init_waitqueue_head(&i2c->wait); + + irq = platform_get_irq(pdev, 0); + if (irq == -ENXIO) { + i2c->flags |= OCORES_FLAG_POLL; + } else { + if (irq < 0) + return irq; + } + + if (!(i2c->flags & OCORES_FLAG_POLL)) { + ret = devm_request_irq(&pdev->dev, irq, ocores_isr, 0, + pdev->name, i2c); + if (ret) { + dev_err(&pdev->dev, "Cannot claim IRQ\n"); + goto err_clk; + } + } + + ret = ocores_init(&pdev->dev, i2c); + if (ret) + goto err_clk; + + /* hook up driver to tree */ + platform_set_drvdata(pdev, i2c); + i2c->adap = ocores_adapter; + i2c_set_adapdata(&i2c->adap, i2c); + i2c->adap.dev.parent = &pdev->dev; + i2c->adap.dev.of_node = pdev->dev.of_node; + + /* add i2c adapter to i2c tree */ + ret = i2c_add_adapter(&i2c->adap); + if (ret) + goto err_clk; + + /* add in known devices to the bus */ + if (pdata) { + for (i = 0; i < pdata->num_devices; i++) + i2c_new_device(&i2c->adap, pdata->devices + i); + } + + return 0; + +err_clk: + clk_disable_unprepare(i2c->clk); + return ret; +} + +static int ocores_i2c_remove(struct platform_device *pdev) +{ + struct ocores_i2c *i2c = platform_get_drvdata(pdev); + u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); + + /* disable i2c logic */ + ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN); + oc_setreg(i2c, OCI2C_CONTROL, ctrl); + + /* remove adapter & data */ + i2c_del_adapter(&i2c->adap); + + if (!IS_ERR(i2c->clk)) + clk_disable_unprepare(i2c->clk); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int ocores_i2c_suspend(struct device *dev) +{ + struct ocores_i2c *i2c = dev_get_drvdata(dev); + u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); + + /* make sure the device is disabled */ + ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN); + oc_setreg(i2c, OCI2C_CONTROL, ctrl); + + if (!IS_ERR(i2c->clk)) + clk_disable_unprepare(i2c->clk); + return 0; +} + +static int ocores_i2c_resume(struct device *dev) +{ + struct ocores_i2c *i2c = dev_get_drvdata(dev); + + if (!IS_ERR(i2c->clk)) { + unsigned long rate; + int ret = clk_prepare_enable(i2c->clk); + + if (ret) { + dev_err(dev, + "clk_prepare_enable failed: %d\n", ret); + return ret; + } + rate = clk_get_rate(i2c->clk) / 1000; + if (rate) + i2c->ip_clock_khz = rate; + } + return ocores_init(dev, i2c); +} + +static SIMPLE_DEV_PM_OPS(ocores_i2c_pm, ocores_i2c_suspend, ocores_i2c_resume); +#define OCORES_I2C_PM (&ocores_i2c_pm) +#else +#define OCORES_I2C_PM NULL +#endif + +static struct platform_driver ocores_i2c_driver = { + .probe = ocores_i2c_probe, + .remove = ocores_i2c_remove, + .driver = { + .name = "goodcores-i2c", + .of_match_table = ocores_i2c_match, + .pm = OCORES_I2C_PM, + }, +}; + +module_platform_driver(ocores_i2c_driver); + +MODULE_AUTHOR("Peter Korsgaard "); +MODULE_DESCRIPTION("OpenCores I2C bus driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ocores-i2c"); diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-ocore.h b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-ocore.h new file mode 100644 index 000000000000..bc2a53cd6832 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-ocore.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * cls-i2c-ocores.h - definitions for the i2c-ocores interface + * + * Peter Korsgaard + */ + +#ifndef _LINUX_I2C_OCORES_H +#define _LINUX_I2C_OCORES_H + +struct ocores_i2c_platform_data { + u32 reg_shift; /* register offset shift value */ + u32 reg_io_width; /* register io read/write width */ + u32 clock_khz; /* input clock in kHz */ + u32 bus_khz; /* bus clock in kHz */ + bool big_endian; /* registers are big endian */ + u8 num_devices; /* number of devices in the devices list */ + struct i2c_board_info const *devices; /* devices connected to the bus */ +}; + +#endif /* _LINUX_I2C_OCORES_H */ + diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-switchboard.c b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-switchboard.c new file mode 100644 index 000000000000..240580e577a3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-switchboard.c @@ -0,0 +1,447 @@ +/* + * cls_switchboard.c - PCI device driver for Silverstone Switch board FPGA. + * + * Author: Pradchaya Phucharoen + * + * Copyright (C) 2019 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 "cls-i2c-ocore.h" + +#define MOD_VERSION "2.1.0-1" +#define DRV_NAME "cls-switchboard" + +#define I2C_MUX_CHANNEL(_ch, _adap_id, _deselect) \ + [_ch] = { .adap_id = _adap_id, .deselect_on_exit = _deselect } + +#define FPGA_PCIE_DEVICE_ID 0x7021 +#define MMIO_BAR 0 +#define I2C_BUS_OFS 9 + +/* I2C ocore configurations */ +#define OCORE_REGSHIFT 2 +#define OCORE_IP_CLK_khz 62500 //TODO: check fpga's `wb_clk_i` +#define OCORE_BUS_CLK_khz 100 +#define OCORE_REG_IO_WIDTH 1 + +/* Optical port xcvr configuration */ +#define XCVR_REG_SHIFT 2 +#define XCVR_NUM_PORT 34 +#define XCVR_PORT_REG_SIZE 0x10 + +/* i2c_bus_config - an i2c-core resource and platform data + * @id - I2C bus device ID, for identification. + * @res - resources for an i2c-core device. + * @num_res - size of the resources. + * @pdata - a platform data of an i2c-core device. + */ +struct i2c_bus_config { + int id; + struct resource *res; + ssize_t num_res; + struct ocores_i2c_platform_data pdata; +}; + +/* switchbrd_priv - switchboard private data */ +struct switchbrd_priv { + unsigned long base; + int num_i2c_bus; + struct platform_device **i2cbuses_pdev; + struct platform_device *regio_pdev; + struct platform_device *spiflash_pdev; + //struct platform_device *xcvr_pdev; +}; + + +// NOTE: Silverstone i2c channel mapping is very wierd!!! +/* PCA9548 channel config on MASTER BUS 3 */ +static struct pca954x_platform_mode i2c_mux_70_modes[] = { + I2C_MUX_CHANNEL(5, I2C_BUS_OFS + 23, true), + I2C_MUX_CHANNEL(6, I2C_BUS_OFS + 26, true), + I2C_MUX_CHANNEL(0, I2C_BUS_OFS + 27, true), + I2C_MUX_CHANNEL(7, I2C_BUS_OFS + 28, true), + I2C_MUX_CHANNEL(2, I2C_BUS_OFS + 29, true), + I2C_MUX_CHANNEL(4, I2C_BUS_OFS + 30, true), + I2C_MUX_CHANNEL(3, I2C_BUS_OFS + 31, true), + I2C_MUX_CHANNEL(1, I2C_BUS_OFS + 32, true), +}; + +static struct pca954x_platform_mode i2c_mux_71_modes[] = { + I2C_MUX_CHANNEL(2, I2C_BUS_OFS + 1, true), + I2C_MUX_CHANNEL(3, I2C_BUS_OFS + 2, true), + I2C_MUX_CHANNEL(0, I2C_BUS_OFS + 3, true), + I2C_MUX_CHANNEL(1, I2C_BUS_OFS + 4, true), + I2C_MUX_CHANNEL(6, I2C_BUS_OFS + 5, true), + I2C_MUX_CHANNEL(5, I2C_BUS_OFS + 6, true), + I2C_MUX_CHANNEL(7, I2C_BUS_OFS + 15, true), + I2C_MUX_CHANNEL(4, I2C_BUS_OFS + 8, true), +}; + +static struct pca954x_platform_mode i2c_mux_72_modes[] = { + I2C_MUX_CHANNEL(1, I2C_BUS_OFS + 17, true), + I2C_MUX_CHANNEL(7, I2C_BUS_OFS + 18, true), + I2C_MUX_CHANNEL(4, I2C_BUS_OFS + 19, true), + I2C_MUX_CHANNEL(0, I2C_BUS_OFS + 20, true), + I2C_MUX_CHANNEL(5, I2C_BUS_OFS + 21, true), + I2C_MUX_CHANNEL(2, I2C_BUS_OFS + 22, true), + I2C_MUX_CHANNEL(3, I2C_BUS_OFS + 25, true), + I2C_MUX_CHANNEL(6, I2C_BUS_OFS + 24, true), +}; + +static struct pca954x_platform_mode i2c_mux_73_modes[] = { + I2C_MUX_CHANNEL(4, I2C_BUS_OFS + 9, true), + I2C_MUX_CHANNEL(3, I2C_BUS_OFS + 10, true), + I2C_MUX_CHANNEL(6, I2C_BUS_OFS + 11, true), + I2C_MUX_CHANNEL(2, I2C_BUS_OFS + 12, true), + I2C_MUX_CHANNEL(1, I2C_BUS_OFS + 13, true), + I2C_MUX_CHANNEL(5, I2C_BUS_OFS + 14, true), + I2C_MUX_CHANNEL(7, I2C_BUS_OFS + 7, true), + I2C_MUX_CHANNEL(0, I2C_BUS_OFS + 16, true), +}; + +static struct pca954x_platform_data om_muxes[] = { + { + .modes = i2c_mux_70_modes, + .num_modes = ARRAY_SIZE(i2c_mux_70_modes), + }, + { + .modes = i2c_mux_71_modes, + .num_modes = ARRAY_SIZE(i2c_mux_71_modes), + }, + { + .modes = i2c_mux_72_modes, + .num_modes = ARRAY_SIZE(i2c_mux_72_modes), + }, + { + .modes = i2c_mux_73_modes, + .num_modes = ARRAY_SIZE(i2c_mux_73_modes), + }, +}; + +/* Optical Module bus 3 i2c muxes info */ +static struct i2c_board_info i2c_info_3[] = { + { + I2C_BOARD_INFO("pca9548", 0x70), + .platform_data = &om_muxes[0], + }, + { + I2C_BOARD_INFO("pca9548", 0x71), + .platform_data = &om_muxes[1], + }, + { + I2C_BOARD_INFO("pca9548", 0x72), + .platform_data = &om_muxes[2], + }, + { + I2C_BOARD_INFO("pca9548", 0x73), + .platform_data = &om_muxes[3], + }, +}; + +/* RESOURCE SEPERATES BY FUNCTION */ +/* Resource IOMEM for i2c bus 1 */ +static struct resource cls_i2c_res_1[] = { + { + .start = 0x800, .end = 0x81F, + .flags = IORESOURCE_MEM,}, +}; + +/* Resource IOMEM for i2c bus 2 */ +static struct resource cls_i2c_res_2[] = { + { + .start = 0x820, .end = 0x83F, + .flags = IORESOURCE_MEM,}, +}; + +/* Resource IOMEM for i2c bus 3 */ +static struct resource cls_i2c_res_3[] = { + { + .start = 0x840, .end = 0x85F, + .flags = IORESOURCE_MEM,}, +}; + +/* Resource IOMEM for i2c bus 4 */ +static struct resource cls_i2c_res_4[] = { + { + .start = 0x860, .end = 0x87F, + .flags = IORESOURCE_MEM,}, +}; + +/* Resource IOMEM for i2c bus 5 */ +static struct resource cls_i2c_res_5[] = { + { + .start = 0x880, .end = 0x89F, + .flags = IORESOURCE_MEM,}, +}; + +/* Resource IOMEM for reg access */ +static struct resource reg_io_res[] = { + { + .start = 0x00, .end = 0xFF, + .flags = IORESOURCE_MEM,}, +}; + +/* Resource IOMEM for spi flash firmware upgrade */ +static struct resource spi_flash_res[] = { + { + .start = 0x1200, .end = 0x121F, + .flags = IORESOURCE_MEM,}, +}; + +/* Resource IOMEM for front panel XCVR */ +// static struct resource xcvr_res[] = { +// { +// .start = 0x4000, .end = 0x421F, +// .flags = IORESOURCE_MEM,}, +// }; + +static struct i2c_bus_config i2c_bus_configs[] = { + { + .id = 1, + .res = cls_i2c_res_1, + .num_res = ARRAY_SIZE(cls_i2c_res_1), + .pdata = { + .reg_shift = OCORE_REGSHIFT, + .reg_io_width = OCORE_REG_IO_WIDTH, + .clock_khz = OCORE_IP_CLK_khz, + .bus_khz = OCORE_BUS_CLK_khz, + .big_endian = false, + .num_devices = 0, + .devices = NULL, + }, + }, + { + .id = 2, + .res = cls_i2c_res_2, + .num_res = ARRAY_SIZE(cls_i2c_res_2), + .pdata = { + .reg_shift = OCORE_REGSHIFT, + .reg_io_width = OCORE_REG_IO_WIDTH, + .clock_khz = OCORE_IP_CLK_khz, + .bus_khz = OCORE_BUS_CLK_khz, + .big_endian = false, + .num_devices = 0, + .devices = NULL, + }, + }, + { + .id = 3, + .res = cls_i2c_res_3, + .num_res = ARRAY_SIZE(cls_i2c_res_3), + .pdata = { + .reg_shift = OCORE_REGSHIFT, + .reg_io_width = OCORE_REG_IO_WIDTH, + .clock_khz = OCORE_IP_CLK_khz, + .bus_khz = OCORE_BUS_CLK_khz, + .big_endian = false, + .num_devices = ARRAY_SIZE(i2c_info_3), + .devices = i2c_info_3, + }, + }, + { + .id = 4, + .res = cls_i2c_res_4, + .num_res = ARRAY_SIZE(cls_i2c_res_4), + .pdata = { + .reg_shift = OCORE_REGSHIFT, + .reg_io_width = OCORE_REG_IO_WIDTH, + .clock_khz = OCORE_IP_CLK_khz, + .bus_khz = OCORE_BUS_CLK_khz, + .big_endian = false, + .num_devices = 0, + .devices = NULL, + }, + }, + { + .id = 5, + .res = cls_i2c_res_5, + .num_res = ARRAY_SIZE(cls_i2c_res_5), + .pdata = { + .reg_shift = OCORE_REGSHIFT, + .reg_io_width = OCORE_REG_IO_WIDTH, + .clock_khz = OCORE_IP_CLK_khz, + .bus_khz = OCORE_BUS_CLK_khz, + .big_endian = false, + .num_devices = 0, + .devices = NULL, + }, + }, +}; + +// TODO: Add a platform configuration struct, and use probe as a factory, +// so xcvr, fwupgrade device can configured as options. + +static int cls_fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + + struct switchbrd_priv *priv; + struct platform_device **i2cbuses_pdev; + struct platform_device *regio_pdev; + struct platform_device *spiflash_pdev; + //struct platform_device *xcvr_pdev; + unsigned long rstart; + int num_i2c_bus, i; + int err; + + err = pci_enable_device(dev); + if (err){ + dev_err(&dev->dev, "Failed to enable PCI device\n"); + goto err_exit; + } + + /* Check for valid MMIO address */ + rstart = pci_resource_start(dev, MMIO_BAR); + if (!rstart) { + dev_err(&dev->dev, "Switchboard base address uninitialized, " + "check FPGA\n"); + err = -ENODEV; + goto err_disable_device; + } + + dev_dbg(&dev->dev, "BAR%d res: 0x%lx-0x%llx\n", MMIO_BAR, + rstart, pci_resource_end(dev, MMIO_BAR)); + + priv = devm_kzalloc(&dev->dev, + sizeof(struct switchbrd_priv), GFP_KERNEL); + if (!priv){ + err = -ENOMEM; + goto err_disable_device; + } + + pci_set_drvdata(dev, priv); + num_i2c_bus = ARRAY_SIZE(i2c_bus_configs); + i2cbuses_pdev = devm_kzalloc( + &dev->dev, + num_i2c_bus * sizeof(struct platform_device*), + GFP_KERNEL); + + reg_io_res[0].start += rstart; + reg_io_res[0].end += rstart; + + spi_flash_res[0].start += rstart; + spi_flash_res[0].end += rstart; + + regio_pdev = platform_device_register_resndata( + &dev->dev, "cls-swbrd-io", + -1, + reg_io_res, ARRAY_SIZE(reg_io_res), + NULL, 0); + + if (IS_ERR(regio_pdev)) { + dev_err(&dev->dev, "Failed to register cls-swbrd-io\n"); + err = PTR_ERR(regio_pdev); + goto err_disable_device; + } + + spiflash_pdev = platform_device_register_resndata( + &dev->dev, "cls-swbrd-fwug", + -1, + spi_flash_res, ARRAY_SIZE(spi_flash_res), + NULL, 0); + + if (IS_ERR(spiflash_pdev)) { + dev_err(&dev->dev, "Failed to register firmware upgrade node\n"); + err = PTR_ERR(spiflash_pdev); + goto err_unregister_regio; + } + + for(i = 0; i < num_i2c_bus; i++){ + + i2c_bus_configs[i].res[0].start += rstart; + i2c_bus_configs[i].res[0].end += rstart; + + dev_dbg(&dev->dev, "i2c-bus.%d: 0x%llx - 0x%llx\n", + i2c_bus_configs[i].id, + i2c_bus_configs[i].res[0].start, + i2c_bus_configs[i].res[0].end); + + i2cbuses_pdev[i] = platform_device_register_resndata( + &dev->dev, "goodcores-i2c", + i2c_bus_configs[i].id, + i2c_bus_configs[i].res, + i2c_bus_configs[i].num_res, + &i2c_bus_configs[i].pdata, + sizeof(i2c_bus_configs[i].pdata)); + + if (IS_ERR(i2cbuses_pdev[i])) { + dev_err(&dev->dev, "Failed to register goodcores-i2c.%d\n", + i2c_bus_configs[i].id); + err = PTR_ERR(i2cbuses_pdev[i]); + goto err_unregister_ocore; + } + } + + priv->base = rstart; + priv->num_i2c_bus = num_i2c_bus; + priv->i2cbuses_pdev = i2cbuses_pdev; + priv->regio_pdev = regio_pdev; + priv->spiflash_pdev = spiflash_pdev; + return 0; + +err_unregister_ocore: + for(i = 0; i < num_i2c_bus; i++){ + if(priv->i2cbuses_pdev[i]){ + platform_device_unregister(priv->i2cbuses_pdev[i]); + } + } +// err_unregister_spiflash: +// platform_device_unregister(spiflash_pdev); +err_unregister_regio: + platform_device_unregister(regio_pdev); +err_disable_device: + pci_disable_device(dev); +err_exit: + return err; +} + +static void cls_fpga_remove(struct pci_dev *dev) +{ + int i; + struct switchbrd_priv *priv = pci_get_drvdata(dev); + + for(i = 0; i < priv->num_i2c_bus; i++){ + if(priv->i2cbuses_pdev[i]) + platform_device_unregister(priv->i2cbuses_pdev[i]); + } + platform_device_unregister(priv->spiflash_pdev); + platform_device_unregister(priv->regio_pdev); + pci_disable_device(dev); + return; +}; + +static const struct pci_device_id pci_clsswbrd[] = { + { PCI_VDEVICE(XILINX, FPGA_PCIE_DEVICE_ID) }, + {0, } +}; + +MODULE_DEVICE_TABLE(pci, pci_clsswbrd); + +static struct pci_driver clsswbrd_pci_driver = { + .name = DRV_NAME, + .id_table = pci_clsswbrd, + .probe = cls_fpga_probe, + .remove = cls_fpga_remove, +}; + +module_pci_driver(clsswbrd_pci_driver); + +MODULE_AUTHOR("Pradchaya P."); +MODULE_DESCRIPTION("Celestica Silverstone switchboard driver"); +MODULE_VERSION(MOD_VERSION); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/mc24lc64t.c b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/mc24lc64t.c new file mode 100644 index 000000000000..a391056d09a7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/mc24lc64t.c @@ -0,0 +1,142 @@ +/* + * mc24lc64t.c - driver for Microchip 24LC64T + * + * Copyright (C) 2017 Celestica Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct mc24lc64t_data { + struct i2c_client *fake_client; + struct mutex update_lock; +}; + +static ssize_t mc24lc64t_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = kobj_to_i2c_client(kobj); + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + unsigned long timeout, read_time, i = 0; + int status; + + mutex_lock(&drvdata->update_lock); + + if (i2c_smbus_write_byte_data(client, off>>8, off)) + { + status = -EIO; + goto exit; + } + + msleep(1); + +begin: + + if (i < count) + { + timeout = jiffies + msecs_to_jiffies(25); /* 25 mS timeout*/ + do { + read_time = jiffies; + + status = i2c_smbus_read_byte(client); + if (status >= 0) + { + buf[i++] = status; + goto begin; + } + } while (time_before(read_time, timeout)); + + status = -ETIMEDOUT; + goto exit; + } + + status = count; + +exit: + mutex_unlock(&drvdata->update_lock); + + return status; +} + +static struct bin_attribute mc24lc64t_bit_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO, + }, + .size = 65536, + .read = mc24lc64t_read, +}; + +static int mc24lc64t_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adapter = client->adapter; + struct mc24lc64t_data *drvdata; + int err; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA + | I2C_FUNC_SMBUS_READ_BYTE)) + return -EPFNOSUPPORT; + + if (!(drvdata = devm_kzalloc(&client->dev, + sizeof(struct mc24lc64t_data), GFP_KERNEL))) + return -ENOMEM; + + drvdata->fake_client = i2c_new_dummy(client->adapter, client->addr + 1); + if (!drvdata->fake_client) + return -ENOMEM; + + i2c_set_clientdata(client, drvdata); + mutex_init(&drvdata->update_lock); + + err = sysfs_create_bin_file(&client->dev.kobj, &mc24lc64t_bit_attr); + if (err) + i2c_unregister_device(drvdata->fake_client); + + return err; +} + +static int mc24lc64t_remove(struct i2c_client *client) +{ + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + + i2c_unregister_device(drvdata->fake_client); + + sysfs_remove_bin_file(&client->dev.kobj, &mc24lc64t_bit_attr); + + return 0; +} + +static const struct i2c_device_id mc24lc64t_id[] = { + { "24lc64t", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mc24lc64t_id); + +static struct i2c_driver mc24lc64t_driver = { + .driver = { + .name = "mc24lc64t", + .owner = THIS_MODULE, + }, + .probe = mc24lc64t_probe, + .remove = mc24lc64t_remove, + .id_table = mc24lc64t_id, +}; + +module_i2c_driver(mc24lc64t_driver); + +MODULE_AUTHOR("Abhisit Sangjan "); +MODULE_DESCRIPTION("Microchip 24LC64T Driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/z9332f-modules.conf b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/z9332f-modules.conf new file mode 100644 index 000000000000..b6d4fe4fb00a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/z9332f-modules.conf @@ -0,0 +1,17 @@ +# /etc/modules: kernel modules to load at boot time. +# +# This file contains the names of kernel modules that should be loaded +# at boot time, one per line. Lines beginning with "#" are ignored. + +i2c-i801 +i2c-isch +i2c-ismt +i2c-dev +i2c-mux +i2c-smbus + +i2c-mux-gpio +i2c-mux-pca954x + +ipmi_devintf +ipmi_si diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/pcisysfs.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/pcisysfs.py new file mode 100755 index 000000000000..047618e057c8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/pcisysfs.py @@ -0,0 +1,102 @@ +#!/usr/bin/python +# Copyright (c) 2015 Dell Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. +# +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. + +import struct +import sys +import getopt +from os import * +from mmap import * + +def usage(): + ''' This is the Usage Method ''' + + print '\t\t pcisysfs.py --get --offset --res ' + print '\t\t pcisysfs.py --set --val --offset --res ' + sys.exit(1) + +def pci_mem_read(mm,offset): + mm.seek(offset) + read_data_stream=mm.read(4) + print "" + reg_val=struct.unpack('I',read_data_stream) + print "reg_val read:%x"%reg_val + return reg_val + +def pci_mem_write(mm,offset,data): + mm.seek(offset) + print "data to write:%x"%data + mm.write(struct.pack('I',data)) + +def pci_set_value(resource,val,offset): + fd=open(resource,O_RDWR) + mm=mmap(fd,0) + pci_mem_write(mm,offset,val) + +def pci_get_value(resource,offset): + fd=open(resource,O_RDWR) + mm=mmap(fd,0) + pci_mem_read(mm,offset) + +def main(argv): + + ''' The main function will read the user input from the + command line argument and process the request ''' + + opts = '' + val = '' + choice = '' + resource = '' + offset = '' + + try: + opts, args = getopt.getopt(argv, "hgsv:" , \ + ["val=","res=","offset=","help", "get", "set"]) + + except getopt.GetoptError: + usage() + + for opt,arg in opts: + + if opt in ('-h','--help'): + choice = 'help' + + elif opt in ('-g', '--get'): + choice = 'get' + + elif opt in ('-s', '--set'): + choice = 'set' + + elif opt == '--res': + resource = arg + + elif opt == '--val': + val = int(arg,16) + + elif opt == '--offset': + offset = int(arg,16) + + if choice == 'set' and val != '' and offset !='' and resource !='': + pci_set_value(resource,val,offset) + + elif choice == 'get' and offset != '' and resource !='': + pci_get_value(resource,offset) + + else: + usage() + +#Calling the main method +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/platform_sensors.py new file mode 100755 index 000000000000..2fd2b84900da --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/platform_sensors.py @@ -0,0 +1,198 @@ +#!/usr/bin/python +# On Z9332F, the BaseBoard Management Controller is an +# autonomous subsystem provides monitoring and management +# facility independent of the host CPU. IPMI standard +# protocol is used with ipmitool to fetch sensor details. +# Current script support X00 board only. X01 support will +# be added soon. This provies support for the +# following objects: +# * Onboard temperature sensors +# * FAN trays +# * PSU + + +import os +import sys +import logging +import subprocess +import commands + +Z9332F_MAX_FAN_TRAYS = 7 +Z9332F_MAX_PSUS = 2 +IPMI_SENSOR_DATA = "ipmitool sdr list" +IPMI_SENSOR_DUMP = "/tmp/sdr" + +FAN_PRESENCE = "Fan{0}_Status" +PSU_PRESENCE = "PSU{0}_Status" +# Use this for older firmware +# PSU_PRESENCE="PSU{0}_prsnt" + +IPMI_PSU1_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x2f | awk '{print substr($0,9,1)}'" +IPMI_PSU2_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x39 | awk '{print substr($0,9,1)}'" + +ipmi_sdr_list = "" + +# Dump sensor registers + + +def ipmi_sensor_dump(): + + status = 1 + global ipmi_sdr_list + ipmi_cmd = IPMI_SENSOR_DATA + status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) + + if status: + logging.error('Failed to execute:' + ipmi_sdr_list) + sys.exit(0) + +# Fetch a BMC register + + +def get_pmc_register(reg_name): + + output = None + for item in ipmi_sdr_list.split("\n"): + if reg_name in item: + output = item.strip() + + if output is None: + print('\nFailed to fetch: ' + reg_name + ' sensor ') + sys.exit(0) + + output = output.split('|')[1] + + logging.basicConfig(level=logging.DEBUG) + return output + + +# Print the information for temperature sensors + + +def print_temperature_sensors(): + + print("\nOnboard Temperature Sensors:") + + for x in (('TEMP_FAN_U52', 'Fan U52'), + ('TEMP_FAN_U17', 'Fan U17'), + ('TEMP_SW_U52', 'SW U52'), + ('TEMP_SW_U16', 'SW U16'), + ('TEMP_BB_U3', 'Baseboard U3'), + ('TEMP_CPU', 'Near CPU'), + ('TEMP_SW_Internal', 'SW interal'), + ('PSU1_Temp1', 'PSU1 inlet'), + ('PSU1_Temp2', 'PSU1 hotspot'), + ('PSU2_Temp1', 'PSU2 inlet'), + ('PSU2_Temp2', 'PSU2 hotspot'), + ('SW_U04_Temp', 'SW U04'), + ('SW_U14_Temp', 'SW U14'), + ('SW_U4403_Temp', 'SW U4403') + ): + print ' {0:32}{1}'.format(x[1] + ':', get_pmc_register(x[0])) + +ipmi_sensor_dump() + +print_temperature_sensors() + +# Print the information for 1 Fan Tray + + +def print_fan_tray(tray): + + Fan_Status = [' Normal', ' Abnormal'] + Airflow_Direction = ['B2F', 'F2B'] + + print ' Fan Tray ' + str(tray) + ':' + + print ' Fan1 Speed: ',\ + get_pmc_register('Fan{}_Front'.format(tray)) + print ' Fan2 Speed: ',\ + get_pmc_register('Fan{}_Rear'.format(tray)) + print ' Fan State: ',\ + Fan_Status[int(get_pmc_register('Fan{}_Status'.format(tray)), 16)] + + +print('\nFan Trays:') + +for tray in range(1, Z9332F_MAX_FAN_TRAYS + 1): + fan_presence = FAN_PRESENCE.format(tray) + if (get_pmc_register(fan_presence)): + print_fan_tray(tray) + else: + print '\n Fan Tray ' + str(tray + 1) + ': Not present' + + def get_psu_presence(index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + ret_status = 1 + + if index == 1: + status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + + #if ret_status: + # print ipmi_cmd_ret + # logging.error('Failed to execute ipmitool') + # sys.exit(0) + + psu_status = ipmi_cmd_ret + + if psu_status == '1': + status = 1 + + return status + + +# Print the information for PSU1, PSU2 +def print_psu(psu): + Psu_Type = ['Normal', 'Mismatch'] + Psu_Input_Type = ['AC', 'DC'] + PSU_STATUS_TYPE_BIT = 4 + PSU_STATUS_INPUT_TYPE_BIT = 1 + PSU_FAN_PRESENT_BIT = 2 + PSU_FAN_STATUS_BIT = 1 + PSU_FAN_AIR_FLOW_BIT = 0 + Psu_Fan_Presence = ['Present', 'Absent'] + Psu_Fan_Status = ['Normal', 'Abnormal'] + Psu_Fan_Airflow = ['B2F', 'F2B'] + + # print ' Input: ', Psu_Input_Type[psu_input_type] + # print ' Type: ', Psu_Type[psu_type] + + print ' PSU{}:'.format(psu) + print ' Inlet Temperature: ',\ + get_pmc_register('PSU{}_Temp1'.format(psu)) + print ' Hotspot Temperature: ',\ + get_pmc_register('PSU{}_Temp2'.format(psu)) + print ' FAN RPM: ',\ + get_pmc_register('PSU{}_Fan'.format(psu)) + # print ' FAN Status: ', Psu_Fan_Status[psu1_fan_status] + + # PSU input & output monitors + print ' Input Voltage: ',\ + get_pmc_register('PSU{}_VIn'.format(psu)) + print ' Output Voltage: ',\ + get_pmc_register('PSU{}_VOut'.format(psu)) + print ' Input Power: ',\ + get_pmc_register('PSU{}_PIn'.format(psu)) + print ' Output Power: ',\ + get_pmc_register('PSU{}_POut'.format(psu)) + print ' Input Current: ',\ + get_pmc_register('PSU{}_CIn'.format(psu)) + print ' Output Current: ',\ + get_pmc_register('PSU{}_COut'.format(psu)) + + +print('\nPSUs:') +for psu in range(1, Z9332F_MAX_PSUS + 1): + #psu_presence = PSU_PRESENCE.format(psu) + if (get_psu_presence(psu)): + print_psu(psu) + else: + print '\n PSU ', psu, 'Not present' diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/sensors b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/sensors new file mode 100755 index 000000000000..ee53f2b0f325 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/sensors @@ -0,0 +1,8 @@ +#!/bin/bash +docker exec -i pmon sensors "$@" +docker exec -i pmon /usr/bin/platform_sensors.py "$@" + +#To probe sensors not part of lm-sensors +#if [ -r /usr/local/bin/platform_sensors.py ]; then +# python /usr/local/bin/platform_sensors.py +#fi diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/z9332f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/z9332f_platform.sh new file mode 100755 index 000000000000..ab2a787a6627 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/z9332f_platform.sh @@ -0,0 +1,180 @@ +#!/bin/bash + +init_devnum() { + found=0 + for devnum in 0; do + devname=`cat /sys/bus/i2c/devices/i2c-${devnum}/name` + # I801 adapter f000 + if [[ $devname == 'SMBus I801 adapter at '* ]]; then + found=1 + break + fi + done + + [ $found -eq 0 ] && echo "cannot find I801" && exit 1 +} + +# Attach/Detach syseeprom on CPU board +sys_eeprom() { + case $1 in + "new_device") echo 24lc64t 0x56 > /sys/bus/i2c/devices/i2c-0/$1 + ;; + "delete_device") echo 0x56 > /sys/bus/i2c/devices/i2c-0/$1 + ;; + *) echo "z9332f_platform: sys_eeprom : invalid command !" + ;; + esac +} + +#Attach/Detach the MUX connecting all QSFPs +switch_board_qsfp_mux() { + case $1 in + "new_device") + for ((i=603;i<=607;i++)); + do + echo "Attaching PCA9548 @ 0x74" + echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-$i/$1 + done + + ;; + "delete_device") + for ((i=603;i<=607;i++)); + do + echo "Detaching PCA9548 @ 0x74" + echo 0x74 > /sys/bus/i2c/devices/i2c-$i/$1 + done + + ;; + *) echo "z9332f_platform: switch_board_qsfp_mux: invalid command !" + ;; + esac + sleep 2 +} + +#Attach/Detach 64 instances of EEPROM driver QSFP ports +#eeprom can dump data using below command +switch_board_qsfp() { + case $1 in + "new_device") + for ((i=10;i<=41;i++)); + do + echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + "delete_device") + for ((i=10;i<=41;i++)); + do + echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + *) echo "z9332f_platform: switch_board_qsfp: invalid command !" + ;; + esac +} + +#Attach/Detach 2 instances of EEPROM driver SFP+ ports +#eeprom can dump data using below command +switch_board_sfp() { + case $1 in + "new_device") + for ((i=1;i<=2;i++)); + do + echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + "delete_device") + for ((i=1;i<=2;i++)); + do + echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1 + done + ;; + + *) echo "z9332f_platform: switch_board_qsfp: invalid command !" + ;; + esac +} + +#Modsel 64 ports to applicable QSFP type modules +#This enables the adapter to respond for i2c commands +switch_board_modsel() { + resource="/sys/bus/pci/devices/0000:09:00.0/resource0" + for ((i=1;i<=32;i++)); + do + port_addr=$(( 16384 + ((i - 1) * 16))) + hex=$( printf "0x%x" $port_addr ) + python /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 + done +} + +#This enables the led control for CPU and default states +switch_board_led_default() { + /usr/sbin/i2cset -y 5 0x0d 0x62 0xd0 +} + +# 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 -t bios | grep Version | awk -F":" '{print $2}'`" > $FIRMWARE_VERSION_FILE + # Get FPGA version + r=`/usr/bin/pcisysfs.py --get --offset 0x00 --res /sys/bus/pci/devices/0000\:09\: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=`docker exec -it pmon ipmitool mc info | awk '/Firmware Revision/ { print $NF }'` + r=`cat /sys/class/ipmi/ipmi0/device/bmc/firmware_revision` + echo "BMC: $r" >> $FIRMWARE_VERSION_FILE + + #BaseBoard CPLD 0x0d on i2c bus 5 ( physical FPGA I2C-5) + ver=`/usr/sbin/i2cget -y 5 0x0d 0x0` + echo "Baseboard CPLD: $((ver))" >> $FIRMWARE_VERSION_FILE + + #Switch CPLD 1 0x30 on i2c bus 4 ( physical FPGA I2C-4) + ver=`/usr/sbin/i2cget -y 4 0x30 0x0` + echo "Switch CPLD 1: $((ver))" >> $FIRMWARE_VERSION_FILE + + #Switch CPLD 1 0x30 on i2c bus 4 ( physical FPGA I2C-4) + ver=`/usr/sbin/i2cget -y 4 0x31 0x0` + echo "Switch CPLD 2: $((ver))" >> $FIRMWARE_VERSION_FILE +} +init_devnum + +if [ "$1" == "init" ]; then + modprobe i2c-dev + modprobe i2c-mux-pca954x force_deselect_on_exit=1 + modprobe ipmi_devintf + modprobe ipmi_si + modprobe cls-i2c-ocore + modprobe cls-switchboard + modprobe mc24lc64t + #insmod /lib/modules/`uname -r`/extra/mc24lc64t.ko + sys_eeprom "new_device" + switch_board_qsfp "new_device" + switch_board_sfp "new_device" + 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" + modprobe -r i2c-mux-pca954x + modprobe -r i2c-dev + modprobe -r ipmi_devintf + modprobe -r ipmi_si + modprobe -r cls-i2c-ocore + modprobe -r cls-switchboard + modprobe -r mc24lc64t +else + echo "z9332f_platform : Invalid option !" +fi + diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/systemd/platform-modules-z9332f.service b/platform/broadcom/sonic-platform-modules-dell/z9332f/systemd/platform-modules-z9332f.service new file mode 100644 index 000000000000..49064b00d682 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/systemd/platform-modules-z9332f.service @@ -0,0 +1,13 @@ +[Unit] +Description=Dell Z9332f Platform modules +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/z9332f_platform.sh init +ExecStop=/usr/local/bin/z9332f_platform.sh deinit +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/src/sonic-device-data/tests/permitted_list b/src/sonic-device-data/tests/permitted_list index 370a920d2187..5bddb7a0ded7 100644 --- a/src/sonic-device-data/tests/permitted_list +++ b/src/sonic-device-data/tests/permitted_list @@ -2,6 +2,7 @@ arl_clean_timeout_usec asf_mem_profile bcm_linkscan_interval bcm_num_cos +default_cpu_tx_queue bcm_stat_flags bcm_stat_interval bcm_stat_jumbo From 9c4c36e1b5717446e12d119d1a487bf9611c9e89 Mon Sep 17 00:00:00 2001 From: Judy Joseph Date: Thu, 19 Dec 2019 06:26:34 +0000 Subject: [PATCH 33/66] [broadom]: Upgrade broadcom SAI to 3.7.3.2 [Broadcom] : update saibcm-modules to sdk 6.5.16 [Broadcom SAI] : upgrade Broadcom SAI to 3.7.3.2 --- .../broadcom/docker-syncd-brcm/Dockerfile.j2 | 7 +- platform/broadcom/sai-modules.mk | 2 +- platform/broadcom/sai.mk | 10 +- .../broadcom/saibcm-modules/debian/changelog | 21 + .../debian/opennsl-modules.init | 26 +- .../debian/opennsl-modules.install | 1 + platform/broadcom/saibcm-modules/debian/rules | 6 +- .../broadcom/saibcm-modules/include/ibde.h | 8 - .../broadcom/saibcm-modules/include/kcom.h | 19 +- .../saibcm-modules/include/soc/devids.h | 313 +-- .../broadcom/saibcm-modules/make/Make.config | 7 +- .../saibcm-modules/make/Makefile.linux-gto | 6 - .../make/Makefile.linux-gto-2_6 | 6 - .../saibcm-modules/make/Makefile.linux-iproc | 8 +- .../make/Makefile.linux-kmodule | 2 +- .../make/Makefile.linux-x86-common-2_6 | 2 +- .../Makefile.linux-x86-generic-common-2_6 | 2 +- .../Makefile.linux-x86-smp_generic_64-2_6 | 1 - .../systems/bde/linux/include/linux-bde.h | 13 +- .../systems/bde/linux/include/linux_dma.h | 4 +- .../systems/bde/linux/kernel/Makefile | 24 +- .../bde/linux/kernel/linux-kernel-bde.c | 1287 ++---------- .../systems/bde/linux/kernel/linux_dma.c | 117 +- .../systems/bde/linux/shared/mpool.c | 133 +- .../bde/linux/user/kernel/linux-user-bde.c | 177 +- .../systems/bde/shared/shbde_iproc.c | 16 +- .../linux/kernel/modules/bcm-knet/bcm-knet.c | 1732 ++++++++++++++--- .../linux/kernel/modules/include/bcm-knet.h | 84 +- .../kernel/modules/include/net/psample.h | 24 + .../modules/include/uapi/linux/psample.h | 35 + .../linux/kernel/modules/knet-cb/Makefile | 4 +- .../linux/kernel/modules/knet-cb/knet-cb.c | 104 +- .../linux/kernel/modules/knet-cb/psample-cb.c | 875 +++++++++ .../linux/kernel/modules/knet-cb/psample-cb.h | 58 + .../linux/kernel/modules/psample/Makefile | 64 + .../linux/kernel/modules/psample/psample.c | 302 +++ .../systems/linux/user/common/Makefile | 21 + .../systems/linux/user/iproc/Makefile | 2 +- sonic-slave-stretch/Dockerfile.j2 | 4 +- 39 files changed, 3560 insertions(+), 1967 deletions(-) create mode 100644 platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/net/psample.h create mode 100644 platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/uapi/linux/psample.h create mode 100644 platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c create mode 100644 platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.h create mode 100644 platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/Makefile create mode 100644 platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c diff --git a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 index b20e353f842f..1ef1c588777c 100755 --- a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 +++ b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 @@ -1,3 +1,4 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages %} FROM docker-config-engine-stretch ARG docker_container_name @@ -14,10 +15,8 @@ debs/{{ deb }}{{' '}} {%- endfor -%} debs/ -RUN dpkg -i \ -{% for deb in docker_syncd_brcm_debs.split(' ') -%} -debs/{{ deb }}{{' '}} -{%- endfor %} +# Install locally-built Debian packages and implicitly install their dependencies +{{ install_debian_packages(docker_syncd_brcm_debs.split(' ')) }} ## TODO: add kmod into Depends RUN apt-get install -yf kmod diff --git a/platform/broadcom/sai-modules.mk b/platform/broadcom/sai-modules.mk index dc77c4b5cb78..1d559d0ad320 100644 --- a/platform/broadcom/sai-modules.mk +++ b/platform/broadcom/sai-modules.mk @@ -1,7 +1,7 @@ # Broadcom SAI modules KVERSION = 4.9.0-9-2-amd64 -BRCM_OPENNSL_KERNEL_VERSION = 3.4.1.11-1 +BRCM_OPENNSL_KERNEL_VERSION = 3.7.3.3-1 BRCM_OPENNSL_KERNEL = opennsl-modules_$(BRCM_OPENNSL_KERNEL_VERSION)_amd64.deb $(BRCM_OPENNSL_KERNEL)_SRC_PATH = $(PLATFORM_PATH)/saibcm-modules diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 833c22f6bb94..63c1e21ec7fc 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.5.3.1m-25_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm_3.5.3.1m-26_amd64.deb?sv=2015-04-05&sr=b&sig=zo83IKnlT7goymXwynW8%2Fx6rR2eIh0AiIS%2BSrSMUhRE%3D&se=2033-07-21T18%3A50%3A27Z&sp=r" +BRCM_SAI = 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.5.3.1m-25_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.7.3.3_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm-dev_3.5.3.1m-26_amd64.deb?sv=2015-04-05&sr=b&sig=tQmkCIy2mnb9rH7B9oXFUZDwijMGXWnVtta2CNTMbFM%3D&se=2033-07-21T18%3A50%3A47Z&sp=r" +$(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" SONIC_ONLINE_DEBS += $(BRCM_SAI) -$(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) +$(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) \ No newline at end of file diff --git a/platform/broadcom/saibcm-modules/debian/changelog b/platform/broadcom/saibcm-modules/debian/changelog index 5ea7b289ee65..2be513ed0435 100644 --- a/platform/broadcom/saibcm-modules/debian/changelog +++ b/platform/broadcom/saibcm-modules/debian/changelog @@ -1,3 +1,24 @@ +opennsl (3.7.3.3-1) unstable; urgency=medium + + * Port Broadcom SAI 3.7.3.3 + * Cherry-pick change from master branch, 3.7.3.3-1 + + -- Judy Joseph Fri, 2 Dec 2019 15:32:47 +0000 + +opennsl (3.7.3.2-1) unstable; urgency=medium + + * Port Broadcom SAI 3.7.3.2 + * Cherry-pick change from master branch, 3.7.3.2-1 + + -- Judy Joseph Fri, 12 Nov 2019 15:22:47 +0000 + +opennsl (3.7.3.1-1) unstable; urgency=medium + + * Port Broadcom SAI 3.7.3.1 + * Cherry-pick change from master branch, 3.7.3.1-1 + + -- Judy Joseph Fri, 19 Sep 2019 13:11:47 +0000 + opennsl (3.4.1.11-1) unstable; urgency=medium * Port Broadcom SAI 3.4.1.11 diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.init b/platform/broadcom/saibcm-modules/debian/opennsl-modules.init index 1aaa91bb2d82..7def10cbff86 100755 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.init +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.init @@ -32,14 +32,38 @@ function create_devices() # level logs function load_kernel_modules() { - modprobe linux-kernel-bde dmasize=32M maxpayload=128 debug=4 dma_debug=1 + . /host/machine.conf + + if [ -n "$aboot_platform" ]; then + platform=$aboot_platform + elif [ -n "$onie_platform" ]; then + platform=$onie_platform + else + platform="unknown" + fi + + # Set the default configuration for dmasize and usemsi parameters + dmasize=32M + usemsi=0 + + # Source the platform env file + env_file="/usr/share/sonic/device/$platform/platform_env.conf" + source $env_file + + modprobe linux-kernel-bde dmasize=$dmasize maxpayload=128 debug=4 dma_debug=1 usemsi=$usemsi modprobe linux-user-bde + + # Using insmod with absolute path for psample to make sure bcm psample is loaded. + # There is a different psample.ko module getting created at net/psample/psample.ko + insmod /lib/modules/$(uname -r)/extra/psample.ko + modprobe linux-bcm-knet use_rx_skb=1 rx_buffer_size=9238 debug=0x5020 modprobe linux-knet-cb } function remove_kernel_modules() { + rmmod psample.ko rmmod linux-knet-cb rmmod linux-bcm-knet rmmod linux-user-bde diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install index 11b100d37f30..e16980dc2c0d 100644 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install @@ -2,4 +2,5 @@ systems/linux/user/x86-smp_generic_64-2_6/linux-bcm-knet.ko lib/modules/4.9.0-9- 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 systemd/opennsl-modules.service lib/systemd/system diff --git a/platform/broadcom/saibcm-modules/debian/rules b/platform/broadcom/saibcm-modules/debian/rules index 33abe645d44a..0092cc1a1027 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 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-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 # 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 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-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 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 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-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 dh_clean diff --git a/platform/broadcom/saibcm-modules/include/ibde.h b/platform/broadcom/saibcm-modules/include/ibde.h index 9c8956f5e3e0..45112eadcb4b 100644 --- a/platform/broadcom/saibcm-modules/include/ibde.h +++ b/platform/broadcom/saibcm-modules/include/ibde.h @@ -148,14 +148,6 @@ typedef struct ibde_s { */ int (*get_cmic_ver)(int d, uint32 *ver); - /* - * Probe available devices. - * Return value : - * 0: success to probe available devices - * -1: error happens during probe - */ - int (*probe)(void); - /* * I2C operations on the Device, assuming it is connected by I2C to the CPU. */ diff --git a/platform/broadcom/saibcm-modules/include/kcom.h b/platform/broadcom/saibcm-modules/include/kcom.h index 76f3e47a8de5..1e3cad0753bc 100644 --- a/platform/broadcom/saibcm-modules/include/kcom.h +++ b/platform/broadcom/saibcm-modules/include/kcom.h @@ -121,6 +121,13 @@ typedef struct kcom_msg_hdr_s { #define KCOM_NETIF_NAME_MAX 16 +/* + * Max size of Sand System Headers + * For DNX, Module Header(20B) + PTCH(2B) + ITMH(5B) + * For DPP, PTCH(2B) + ITMH(4B) + */ +#define KCOM_NETIF_SYSTEM_HEADERS_SIZE_MAX 27 + typedef struct kcom_netif_s { uint16 id; uint8 type; @@ -133,6 +140,8 @@ typedef struct kcom_netif_s { uint8 macaddr[6]; uint8 ptch[2]; uint8 itmh[4]; + uint8 system_headers[KCOM_NETIF_SYSTEM_HEADERS_SIZE_MAX]; + uint8 system_headers_size; char name[KCOM_NETIF_NAME_MAX]; } kcom_netif_t; @@ -216,6 +225,13 @@ typedef struct kcom_filter_s { uint8 b[KCOM_FILTER_BYTES_MAX]; uint32 w[KCOM_FILTER_WORDS_MAX]; } mask; + /** Information to parse Dune system headers */ + uint32 ftmh_lb_key_ext_size; + uint32 ftmh_stacking_ext_size; + uint32 pph_base_size; + uint32 pph_lif_ext_size[8]; + uint8 udh_enable; + uint32 udh_length_type[4]; } kcom_filter_t; /* @@ -470,8 +486,7 @@ typedef struct kcom_msg_filter_destroy_s { * Get list of currently defined packet filters. */ #ifndef KCOM_FILTER_MAX -/* SAI_FIXUP - Increased the filters to 1024 from 128 */ -#define KCOM_FILTER_MAX 1024 +#define KCOM_FILTER_MAX 128 #endif typedef struct kcom_msg_filter_list_s { diff --git a/platform/broadcom/saibcm-modules/include/soc/devids.h b/platform/broadcom/saibcm-modules/include/soc/devids.h index cb072a78cbd7..7546ef392298 100644 --- a/platform/broadcom/saibcm-modules/include/soc/devids.h +++ b/platform/broadcom/saibcm-modules/include/soc/devids.h @@ -14,7 +14,7 @@ * version 2 (GPLv2) along with this source code. */ /* - * Copyright: (c) 2018 Broadcom. + * Copyright: (c) 2019 Broadcom. * All Rights Reserved. */ @@ -835,31 +835,6 @@ #define BCM56746_A0_REV_ID 1 #define BCM56746_A1_REV_ID 2 -#define BCM88230_DEVICE_ID 0x0230 -#define BCM88230_A0_REV_ID 1 -#define BCM88230_B0_REV_ID 0x11 -#define BCM88230_C0_REV_ID 0x21 -#define BCM88231_DEVICE_ID 0x0231 -#define BCM88231_A0_REV_ID 1 -#define BCM88231_B0_REV_ID 0x11 -#define BCM88231_C0_REV_ID 0x21 -#define BCM88235_DEVICE_ID 0x0235 -#define BCM88235_A0_REV_ID 1 -#define BCM88235_B0_REV_ID 0x11 -#define BCM88235_C0_REV_ID 0x21 -#define BCM88236_DEVICE_ID 0x0236 -#define BCM88236_A0_REV_ID 1 -#define BCM88236_B0_REV_ID 0x11 -#define BCM88236_C0_REV_ID 0x21 -#define BCM88239_DEVICE_ID 0x0239 -#define BCM88239_A0_REV_ID 1 -#define BCM88239_B0_REV_ID 0x11 -#define BCM88239_C0_REV_ID 0x21 -#define BCM56613_DEVICE_ID 0xb613 -#define BCM56613_A0_REV_ID 1 -#define BCM56613_B0_REV_ID 0x11 -#define BCM56613_C0_REV_ID 0x21 - #define BCM88732_DEVICE_ID 0x0732 #define BCM88732_A0_REV_ID 1 #define BCM88732_A1_REV_ID 2 @@ -1243,10 +1218,13 @@ #define BCM56981_A0_REV_ID 1 #define BCM56982_DEVICE_ID 0xb982 #define BCM56982_A0_REV_ID 1 +#define BCM56982_B0_REV_ID 0x11 #define BCM56983_DEVICE_ID 0xb983 #define BCM56983_A0_REV_ID 1 +#define BCM56983_B0_REV_ID 0x11 #define BCM56984_DEVICE_ID 0xb984 #define BCM56984_A0_REV_ID 1 +#define BCM56984_B0_REV_ID 0x11 #define BCM56968_DEVICE_ID 0xb968 #define BCM56968_A0_REV_ID 1 @@ -1428,33 +1406,43 @@ #define BCM56370_DEVICE_ID 0xb370 #define BCM56370_A0_REV_ID 1 +#define BCM56370_A1_REV_ID 0x02 #define BCM56371_DEVICE_ID 0xb371 #define BCM56371_A0_REV_ID 1 +#define BCM56371_A1_REV_ID 0x02 #define BCM56372_DEVICE_ID 0xb372 #define BCM56372_A0_REV_ID 1 +#define BCM56372_A1_REV_ID 0x02 #define BCM56374_DEVICE_ID 0xb374 #define BCM56374_A0_REV_ID 1 +#define BCM56374_A1_REV_ID 0x02 #define BCM56375_DEVICE_ID 0xb375 #define BCM56375_A0_REV_ID 1 +#define BCM56375_A1_REV_ID 0x02 #define BCM56376_DEVICE_ID 0xb376 #define BCM56376_A0_REV_ID 1 +#define BCM56376_A1_REV_ID 0x02 #define BCM56377_DEVICE_ID 0xb377 #define BCM56377_A0_REV_ID 1 +#define BCM56377_A1_REV_ID 0x02 #define BCM56577_DEVICE_ID 0xb577 #define BCM56577_A0_REV_ID 1 +#define BCM56577_A1_REV_ID 0x02 #define BCM56578_DEVICE_ID 0xb578 #define BCM56578_A0_REV_ID 1 +#define BCM56578_A1_REV_ID 0x02 #define BCM56579_DEVICE_ID 0xb579 #define BCM56579_A0_REV_ID 1 +#define BCM56579_A1_REV_ID 0x02 #define BCM56770_DEVICE_ID 0xb770 #define BCM56770_A0_REV_ID 1 @@ -1488,247 +1476,6 @@ #define BROADCOM_PHYID_HIGH 0x0040 -#define BCM5338_PHYID_LOW 0x62b0 -#define BCM5338_A0_REV_ID 0 -#define BCM5338_A1_REV_ID 1 -#define BCM5338_B0_REV_ID 3 - -#define BCM5324_PHYID_LOW 0xbc20 -#define BCM5324_PHYID_HIGH 0x143 -#define BCM5324_A1_PHYID_HIGH 0x153 -#define BCM5324_DEVICE_ID 0xbc20 -#define BCM5324_A0_REV_ID 0 -#define BCM5324_A1_REV_ID 1 -#define BCM5324_A2_REV_ID 2 - -#define BCM5380_PHYID_LOW 0x6250 -#define BCM5380_A0_REV_ID 0 - -#define BCM5388_PHYID_LOW 0x6288 -#define BCM5388_A0_REV_ID 0 - -#define BCM5396_PHYID_LOW 0xbd70 -#define BCM5396_PHYID_HIGH 0x143 -#define BCM5396_DEVICE_ID 0x96 -#define BCM5396_A0_REV_ID 0 - -#define BCM5389_PHYID_LOW 0xbd70 -#define BCM5389_PHYID_HIGH 0x143 -#define BCM5389_DEVICE_ID 0x89 -#define BCM5389_A0_REV_ID 0 -#define BCM5389_A1_DEVICE_ID 0x86 -#define BCM5389_A1_REV_ID 1 - -#define BCM5398_PHYID_LOW 0xbcd0 -#define BCM5398_PHYID_HIGH 0x0143 -#define BCM5398_DEVICE_ID 0x98 -#define BCM5398_A0_REV_ID 0 - -#define BCM5325_PHYID_LOW 0xbc30 -#define BCM5325_PHYID_HIGH 0x143 -#define BCM5325_DEVICE_ID 0xbc30 -#define BCM5325_A0_REV_ID 0 -#define BCM5325_A1_REV_ID 1 - -#define BCM5348_PHYID_LOW 0xbe40 -#define BCM5348_PHYID_HIGH 0x0143 -#define BCM5348_DEVICE_ID 0x48 -#define BCM5348_A0_REV_ID 0 -#define BCM5348_A1_REV_ID 1 - -#define BCM5397_PHYID_LOW 0xbcd0 -#define BCM5397_PHYID_HIGH 0x0143 -#define BCM5397_DEVICE_ID 0x97 -#define BCM5397_A0_REV_ID 0 - -#define BCM5347_PHYID_LOW 0xbe40 -#define BCM5347_PHYID_HIGH 0x0143 -#define BCM5347_DEVICE_ID 0x47 -#define BCM5347_A0_REV_ID 0 - -#define BCM5395_PHYID_LOW 0xbcf0 -#define BCM5395_PHYID_HIGH 0x0143 -#define BCM5395_DEVICE_ID 0xbcf0 -#define BCM5395_A0_REV_ID 0 - -#define BCM53242_PHYID_LOW 0xbf10 -#define BCM53242_PHYID_HIGH 0x0143 -#define BCM53242_DEVICE_ID 0xbf10 -#define BCM53242_A0_REV_ID 0 -#define BCM53242_B0_REV_ID 4 -#define BCM53242_B1_REV_ID 5 - -#define BCM53262_PHYID_LOW 0xbf20 -#define BCM53262_PHYID_HIGH 0x0143 -#define BCM53262_DEVICE_ID 0xbf20 -#define BCM53262_A0_REV_ID 0 -#define BCM53262_B0_REV_ID 4 -#define BCM53262_B1_REV_ID 5 - -#define BCM53115_PHYID_LOW 0xbf80 -#define BCM53115_PHYID_HIGH 0x0143 -#define BCM53115_DEVICE_ID 0xbf80 -#define BCM53115_A0_REV_ID 0 -#define BCM53115_A1_REV_ID 1 -#define BCM53115_B0_REV_ID 2 -#define BCM53115_B1_REV_ID 3 -#define BCM53115_C0_REV_ID 8 - -#define BCM53118_PHYID_LOW 0xbfe0 -#define BCM53118_PHYID_HIGH 0x0143 -#define BCM53118_DEVICE_ID 0xbfe0 -#define BCM53118_A0_REV_ID 0 - -#define BCM53118_B0_REV_ID 4 -#define BCM53118_B1_REV_ID 5 - -#define BCM53280_PHYID_LOW 0x5e90 -#define BCM53280_PHYID_HIGH 0x0362 -#define BCM53280_DEVICE_ID (0x4 | BCM53280_PHYID_LOW) -#define BCM53280_A0_REV_ID 0 -#define BCM53280_B0_REV_ID 0x4 -#define BCM53280_B1_REV_ID 0x5 -#define BCM53280_B2_REV_ID 0x6 -#define BCM53286_DEVICE_ID (0x4 | BCM53280_PHYID_LOW) -#define BCM53288_DEVICE_ID (0xc | BCM53280_PHYID_LOW) -#define BCM53284_DEVICE_ID (0x7 | BCM53280_PHYID_LOW) -#define BCM53283_DEVICE_ID (0x6 | BCM53280_PHYID_LOW) -#define BCM53282_DEVICE_ID (0x5 | BCM53280_PHYID_LOW) -#define BCM53101_PHYID_LOW 0x5ed0 -#define BCM53101_PHYID_HIGH 0x0362 -#define BCM53101_DEVICE_ID 0x5ed0 -#define BCM53101_A0_REV_ID 0 -#define BCM53101_B0_REV_ID 4 - -#define BCM53125_PHYID_LOW 0x5f20 -#define BCM53125_PHYID_HIGH 0x0362 -#define BCM53125_DEVICE_ID 0x5f20 -#define BCM53125_A0_REV_ID 0 -#define BCM53125_B0_REV_ID 0x4 -#define BCM53125_MODEL_ID 0x53125 - -#define BCM53134_PHYID_LOW 0x5350 -#define BCM53134_PHYID_HIGH 0xAE02 -#define BCM53134_DEVICE_ID 0x5350 -#define BCM53134_A0_REV_ID 0x0 -#define BCM53134_B0_REV_ID 0x1 -#define BCM53134_B1_REV_ID 0x2 -#define BCM53134_A0_MODEL_ID 0x5035 -#define BCM53134_B0_MODEL_ID 0x5075 - -#define BCM53128_PHYID_LOW 0x5e10 -#define BCM53128_PHYID_HIGH 0x0362 -#define BCM53128_DEVICE_ID 0x5e10 -#define BCM53128_A0_REV_ID 0 -#define BCM53128_B0_REV_ID 0x4 -#define BCM53128_MODEL_ID 0x53128 - -#define BCM53600_PHYID_LOW 0x5f40 -#define BCM53600_PHYID_HIGH 0x0362 -#define BCM53600_DEVICE_ID (0x3 | BCM53600_PHYID_LOW) -#define BCM53600_A0_REV_ID 0 -#define BCM53602_DEVICE_ID (0x1 | BCM53600_PHYID_LOW) -#define BCM53603_DEVICE_ID (0x2 | BCM53600_PHYID_LOW) -#define BCM53604_DEVICE_ID (0x3 | BCM53600_PHYID_LOW) -#define BCM53606_DEVICE_ID (0x7 | BCM53600_PHYID_LOW) - -#define BCM89500_PHYID_LOW 0x5d30 -#define BCM89500_PHYID_HIGH 0x0362 -#define BCM89500_DEVICE_ID 0x9500 -#define BCM89501_DEVICE_ID 0x9501 -#define BCM89200_DEVICE_ID 0x9200 -#define BCM89500_A0_REV_ID 0 -#define BCM89500_B0_REV_ID 0x4 -#define BCM89500_MODEL_ID 0x89500 - -#define BCM53010_PHYID_LOW 0x8760 -#define BCM53010_PHYID_HIGH 0x600d -#define BCM53010_DEVICE_ID 0x3010 -#define BCM53011_DEVICE_ID 0x3011 -#define BCM53012_DEVICE_ID 0x3012 -#define BCM53010_A0_REV_ID 0 -#define BCM53010_A2_REV_ID 0x2 -#define BCM53010_MODEL_ID 0x53010 - -#define BCM53018_PHYID_LOW 0x87c0 -#define BCM53018_PHYID_HIGH 0x600d -#define BCM53017_DEVICE_ID 0x3016 -#define BCM53018_DEVICE_ID 0x3018 -#define BCM53019_DEVICE_ID 0x3019 -#define BCM53018_A0_REV_ID 0 -#define BCM53018_MODEL_ID 0x53016 - -#define BCM53020_PHYID_LOW 0x87f0 -#define BCM53020_PHYID_HIGH 0x600d -#define BCM53020_DEVICE_ID 0x8022 -#define BCM53022_DEVICE_ID 0x8022 -#define BCM53023_DEVICE_ID 0x8023 -#define BCM53025_DEVICE_ID 0x8025 -#define BCM58625_DEVICE_ID 0x8625 -#define BCM58622_DEVICE_ID 0x8622 -#define BCM58623_DEVICE_ID 0x8623 -#define BCM58525_DEVICE_ID 0x8525 -#define BCM58522_DEVICE_ID 0x8522 -#define BCM53020_A0_REV_ID 0 -#define BCM53020_MODEL_ID 0x3025 - -#define BCM4713_DEVICE_ID 0x4713 -#define BCM4713_A0_REV_ID 0 -#define BCM4713_A9_REV_ID 9 - -#define BCM53000_GMAC_DEVICE_ID 0x4715 -#define BCM53000_A0_REV_ID 0 - -#define BCM53010_GMAC_DEVICE_ID 0x4715 - -#define BCM53000PCIE_DEVICE_ID 0x5300 - -#define SANDBURST_VENDOR_ID 0x17ba -#define BME3200_DEVICE_ID 0x0280 -#define BME3200_A0_REV_ID 0x0000 -#define BME3200_B0_REV_ID 0x0001 -#define BM9600_DEVICE_ID 0x0480 -#define BM9600_A0_REV_ID 0x0000 -#define BM9600_B0_REV_ID 0x0010 -#define QE2000_DEVICE_ID 0x0300 -#define QE2000_A1_REV_ID 0x0001 -#define QE2000_A2_REV_ID 0x0002 -#define QE2000_A3_REV_ID 0x0003 -#define QE2000_A4_REV_ID 0x0004 -#define BCM88020_DEVICE_ID 0x0380 -#define BCM88020_A0_REV_ID 0x0000 -#define BCM88020_A1_REV_ID 0x0001 -#define BCM88020_A2_REV_ID 0x0002 -#define BCM88025_DEVICE_ID 0x0580 -#define BCM88025_A0_REV_ID 0x0000 -#define BCM88030_DEVICE_ID 0x0038 -#define BCM88030_A0_REV_ID 0x0001 -#define BCM88030_A1_REV_ID 0x0002 -#define BCM88030_B0_REV_ID 0x0011 -#define BCM88030_B1_REV_ID 0x0012 -#define BCM88034_DEVICE_ID 0x0034 -#define BCM88034_A0_REV_ID (BCM88030_A0_REV_ID) -#define BCM88034_A1_REV_ID (BCM88030_A1_REV_ID) -#define BCM88034_B0_REV_ID (BCM88030_B0_REV_ID) -#define BCM88034_B1_REV_ID (BCM88030_B1_REV_ID) -#define BCM88039_DEVICE_ID 0x0039 -#define BCM88039_A0_REV_ID (BCM88030_A0_REV_ID) -#define BCM88039_A1_REV_ID (BCM88030_A1_REV_ID) -#define BCM88039_B0_REV_ID (BCM88030_B0_REV_ID) -#define BCM88039_B1_REV_ID (BCM88030_B1_REV_ID) -#define BCM88130_DEVICE_ID 0x0480 -#define BCM88130_A0_REV_ID 0x0000 -#define BCM88130_A1_REV_ID 0x0001 -#define BCM88130_B0_REV_ID 0x0010 -#define PLX_VENDOR_ID 0x10b5 -#define PLX9656_DEVICE_ID 0x9656 -#define PLX9656_REV_ID 0x0000 -#define PLX9056_DEVICE_ID 0x9056 -#define PLX9056_REV_ID 0x0000 - -#define TK371X_DEVICE_ID 0x8600 -#define TK371X_A0_REV_ID 0x0 - #define GEDI_DEVICE_ID 0xa100 #define GEDI_REV_ID 0x0001 #define ARAD_DEVICE_ID 0x8650 @@ -1778,6 +1525,7 @@ #define DNXC_A0_REV_ID 0x0001 #define DNXC_A1_REV_ID 0x0002 #define DNXC_B0_REV_ID 0x0011 +#define DNXC_B1_REV_ID 0x0012 #define BCM88790_DEVICE_ID 0x8790 #define BCM88790_A0_REV_ID DNXC_A0_REV_ID #define BCM88790_B0_REV_ID DNXC_B0_REV_ID @@ -1933,9 +1681,34 @@ #define BCM88381_A0_REV_ID JERICHO_PLUS_A0_REV_ID #define JERICHO_2_DEVICE_ID 0x8690 -#define JERICHO_2_A0_REV_ID 0x0001 +#define JERICHO_2_A0_REV_ID DNXC_A0_REV_ID +#define JERICHO_2_B0_REV_ID DNXC_B0_REV_ID +#define JERICHO_2_B1_REV_ID DNXC_B1_REV_ID #define BCM88690_DEVICE_ID JERICHO_2_DEVICE_ID #define BCM88690_A0_REV_ID JERICHO_2_A0_REV_ID +#define BCM88690_B0_REV_ID JERICHO_2_B0_REV_ID +#define BCM88690_B1_REV_ID JERICHO_2_B1_REV_ID +#define BCM88691_DEVICE_ID 0x8691 +#define BCM88692_DEVICE_ID 0x8692 +#define BCM88693_DEVICE_ID 0x8693 +#define BCM88694_DEVICE_ID 0x8694 +#define BCM88695_DEVICE_ID 0x8695 +#define BCM88696_DEVICE_ID 0x8696 +#define BCM88697_DEVICE_ID 0x8697 +#define BCM88698_DEVICE_ID 0x8698 +#define BCM88699_DEVICE_ID 0x8699 +#define BCM8869A_DEVICE_ID 0x869A +#define BCM8869B_DEVICE_ID 0x869B +#define BCM8869C_DEVICE_ID 0x869C +#define BCM8869D_DEVICE_ID 0x869D +#define BCM8869E_DEVICE_ID 0x869E +#define BCM8869F_DEVICE_ID 0x869F +#define BCM_JR2_DEVID_MASK 0xFFF0 + +#define J2C_DEVICE_ID 0x8800 +#define J2C_A0_REV_ID DNXC_A0_REV_ID +#define BCM88800_DEVICE_ID J2C_DEVICE_ID +#define BCM88800_A0_REV_ID J2C_A0_REV_ID #define QAX_DEVICE_ID 0x8470 #define QAX_A0_REV_ID 0x0001 @@ -1964,6 +1737,7 @@ #define BCM88270_A1_REV_ID QUX_A1_REV_ID #define BCM88272_DEVICE_ID 0x8272 #define BCM88273_DEVICE_ID 0x8273 +#define BCM88274_DEVICE_ID 0x8274 #define BCM88278_DEVICE_ID 0x8278 #define BCM88279_DEVICE_ID 0x8279 @@ -2045,5 +1819,8 @@ #define ACP_PCI_VENDOR_ID 0x10ee #define ACP_PCI_DEVICE_ID 0x7011 #define ACP_PCI_REV_ID 0x0001 + +#define PLX9056_DEVICE_ID 0x9056 + #endif diff --git a/platform/broadcom/saibcm-modules/make/Make.config b/platform/broadcom/saibcm-modules/make/Make.config index b8fa17bda119..409a6a49b3f3 100644 --- a/platform/broadcom/saibcm-modules/make/Make.config +++ b/platform/broadcom/saibcm-modules/make/Make.config @@ -54,12 +54,7 @@ endif -include ${SDK}/make/Make.local ifdef ALL_CHIPS - ROBO_CHIPS = 1 ESW_CHIPS = 1 -else - ifndef ROBO_CHIPS - ESW_CHIPS = 1 - endif endif # ALL_CHIPS # @@ -166,7 +161,7 @@ CFLAGS += ${INCFLAGS} CXXFLAGS += ${INCFLAGS} CPPFLAGS += ${INCFLAGS} -CFLAGS += -DSAI_FIXUP -DBCM_PORT_DEFAULT_DISABLE -DBCM_VLAN_NO_DEFAULT_ETHER -DBCM_VLAN_NO_DEFAULT_CPU -DBCM_WARM_BOOT_SUPPORT -DSAL_CONFIG_FILE_DISABLE -DSAL_THREAD_NAME_PRINT_DISABLE -UKCOM_FILTER_MAX -DKCOM_FILTER_MAX=256 -DALPM_ENABLE -DOPENNSL_PHY_ROUTINES -DTH2_CPU_POOL_SETUP -DINCLUDE_L3 -DSAI_ONLY -DPRINT_TO_SYSLOG -D_SHR_PBMP_WIDTH=256 -DINCLUDE_DIAG_SHELL -DSTATIC=static -DLOG_TEST -DLOG_SAI -D_GNU_SOURCE +CFLAGS += -DSAI_FIXUP -UKCOM_FILTER_MAX -DKCOM_FILTER_MAX=1024 # # Debug #ifdef control diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-gto b/platform/broadcom/saibcm-modules/make/Makefile.linux-gto index 947c20e74f93..786b4cc26bc3 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-gto +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-gto @@ -74,12 +74,6 @@ modname_flags = $(if $(filter 1,$(words $(modname))),\ KFLAG_INCLD = $(TOOLCHAIN_BIN_DIR)/../lib/gcc/$(TARGET_ARCHITECTURE)/4.6.4/include ifdef BROADCOM_SVK -ifdef BCM_BME3200_B0 -PLX_PCI2LBUS=1 -endif -ifdef BCM_BM9600_B0 -PLX_PCI2LBUS=1 -endif ifeq ($PLX_PCI2LBUS, 1) CFLAGS += -DBCM_PLX9656_LOCAL_BUS -DBDE_LINUX_NON_INTERRUPTIBLE endif diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-gto-2_6 b/platform/broadcom/saibcm-modules/make/Makefile.linux-gto-2_6 index 4caa4902421f..56085c7a3cdd 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-gto-2_6 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-gto-2_6 @@ -224,12 +224,6 @@ endif endif ifdef BROADCOM_SVK -ifdef BCM_BME3200_B0 -PLX_PCI2LBUS=1 -endif -ifdef BCM_BM9600_B0 -PLX_PCI2LBUS=1 -endif ifeq ($PLX_PCI2LBUS, 1) CFLAGS += -DBCM_PLX9656_LOCAL_BUS -DBDE_LINUX_NON_INTERRUPTIBLE endif diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc index 7c0f9411f5e2..092e474e2563 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc @@ -27,11 +27,11 @@ endif # TARGET_ARCHITECTURE Compiler for target architecture # KERNDIR Kernel directory for iPROC-CMICd devices ifeq (BE,$(ENDIAN_MODE)) -TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/iproc-be/XLDK +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk50-be/XLDK32 TARGET_ARCHITECTURE:=armeb-broadcom-linux-uclibcgnueabi KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux else -TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/iproc/XLDK +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk50/XLDK32 TARGET_ARCHITECTURE:= arm-broadcom-linux-uclibcgnueabi KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux endif @@ -60,6 +60,8 @@ CFGFLAGS += -DSYS_BE_PIO=0 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=0 ENDIAN = LE_HOST=1 endif +CFLAGS += -fno-aggressive-loop-optimizations + CFGFLAGS += -D$(ENDIAN) -DIPROC_CMICD CFGFLAGS += -DBCM_PLATFORM_STRING=\"IPROC_CMICD\" @@ -80,7 +82,7 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" modname_flags = $(if $(filter 1,$(words $(modname))),\ -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") -KFLAG_INCLD ?= $(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/4.9.3/include +KFLAG_INCLD ?= $(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/4.9.4/include ifeq (,$(KFLAGS)) KFLAGS := -D__LINUX_ARM_ARCH__=7 -D__KERNEL__ -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/arm/include -I$(KERNDIR)/arch/arm/include/generated -I$(KERNDIR)/arch/arm/mach-iproc/include -Wall -Wstrict-prototypes -Wno-trigraphs -Os -fno-strict-aliasing -fno-common -marm -mabi=aapcs-linux -fno-pic -pipe -msoft-float -ffreestanding -march=armv7-a -mfpu=vfp -mfloat-abi=softfp -fomit-frame-pointer -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign -mlong-calls diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-kmodule b/platform/broadcom/saibcm-modules/make/Makefile.linux-kmodule index 3ad11d169c64..540c497ea258 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-kmodule +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-kmodule @@ -71,7 +71,7 @@ $(KMODULE): rm -f *.o *.ko .*.cmd rm -fr .tmp_versions ln -s $(LIBDIR)/$(MODULE) $(PRE_COMPILED_OBJ)_shipped - echo "suppress warning" > .$(PRE_COMPILED_OBJ).cmd + if [ ! -f $(KERNBLDDIR)/NO_SUPRESS ]; then echo "# suppress warning" > .$(PRE_COMPILED_OBJ).cmd; fi $(MAKE) -C $(KERNBLDDIR) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) modules if [ ! -f Module.symvers ]; then echo "old kernel (pre-2.6.17)" > Module.symvers; fi cp -f $(KMODULE) $(LIBDIR) diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-common-2_6 b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-common-2_6 index 07af2afcc93b..25e953136bc0 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-common-2_6 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-common-2_6 @@ -22,7 +22,7 @@ ENDIAN = LE_HOST=1 CFGFLAGS += -D$(ENDIAN) CFGFLAGS += -DBCM_PLATFORM_STRING=\"X86\" ifeq (,$(findstring -DSAL_BDE_DMA_MEM_DEFAULT,$(CFGFLAGS))) -CFGFLAGS += -DSAL_BDE_DMA_MEM_DEFAULT=32 +CFGFLAGS += -DSAL_BDE_DMA_MEM_DEFAULT=16 endif # Extra variables. diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-generic-common-2_6 b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-generic-common-2_6 index ab342c12d210..bf0ea85d578e 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-generic-common-2_6 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-generic-common-2_6 @@ -48,4 +48,4 @@ AUTOCONF = $(KERNDIR)/include/linux/autoconf.h endif # gcc system include path -SYSINC = $(shell gcc -print-search-dirs | grep install | cut -c 10-)include +SYSINC = $(shell $(CC) -print-search-dirs | grep install | cut -c 10-)include diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 index bb0bbea536a3..bc0230ec8226 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 @@ -43,4 +43,3 @@ KFLAGS += -I$(KERNDIR_COMMON)/include -I$(KERNDIR_COMMON)/include/uapi -I$(KERND endif include ${SDK}/make/Makefile.linux-x86-common-2_6 - diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux-bde.h b/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux-bde.h index 927201bc1fd8..bdf7a56dcabb 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux-bde.h +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux-bde.h @@ -222,7 +222,7 @@ extern int lkbde_dev_instid_set(int d, uint32 instid); extern int lkbde_irq_mask_set(int d, uint32 addr, uint32 mask, uint32 fmask); extern int lkbde_irq_mask_get(int d, uint32 *mask, uint32 *fmask); -#if (defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)) +#ifdef BCM_SAND_SUPPORT extern int lkbde_cpu_write(int d, uint32 addr, uint32 *buf); extern int lkbde_cpu_read(int d, uint32 addr, uint32 *buf); extern int lkbde_cpu_pci_register(int d); @@ -241,15 +241,12 @@ extern int lkbde_cpu_pci_register(int d); */ #define LKBDE_IPROC_REG 0x4000 -#if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) +#ifdef BCM_SAND_SUPPORT #include #if defined(__DUNE_LINUX_BCM_CPU_PCIE__) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) #ifndef _SIMPLE_MEMORY_ALLOCATION_ #define _SIMPLE_MEMORY_ALLOCATION_ 1 #endif -#ifndef USE_LINUX_BDE_MMAP -#define USE_LINUX_BDE_MMAP 1 -#endif #endif #endif @@ -271,13 +268,9 @@ extern int lkbde_cpu_pci_register(int d); #define _SIMPLE_MEMORY_ALLOCATION_ 9 /* compile in the allocation method, but do not use it by default */ #endif -/* By default we use our private mmap only if /dev/mem mmap has restrictions */ +/* By default we use our private mmap for DMA pool */ #ifndef USE_LINUX_BDE_MMAP -#ifdef CONFIG_STRICT_DEVMEM #define USE_LINUX_BDE_MMAP 1 -#else -#define USE_LINUX_BDE_MMAP 0 -#endif #endif #endif /* __KERNEL__ */ diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux_dma.h b/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux_dma.h index bfbbceb2d8e7..3bf7488abce9 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux_dma.h +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux_dma.h @@ -58,7 +58,7 @@ #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) #endif -extern void _dma_init(int robo_switch, int dev_index); +extern void _dma_init(int dev_index); extern int _dma_cleanup(void); extern void _dma_pprint(void); extern uint32_t *_salloc(int d, int size, const char *name); @@ -68,7 +68,7 @@ extern int _sflush(int d, void *ptr, int length); extern sal_paddr_t _l2p(int d, void *vaddr); extern void *_p2l(int d, sal_paddr_t paddr); extern int _dma_pool_allocated(void); -extern int _dma_range_valid(unsigned long phys_addr, unsigned long size); +extern int _dma_mmap(struct file *filp, struct vm_area_struct *vma); #endif /* __KERNEL__ */ diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/Makefile b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/Makefile index 3d504a5665fa..aedd487b1f11 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/Makefile +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/Makefile @@ -33,33 +33,11 @@ LIBS = $(LIBDIR)/libkern.a BDE = linux-kernel-bde.o -ifdef ROBO_CHIPS -CFLAGS += -I$(ET_ROBO) -I${SDK}/include/shared/et -ET_ROBO = ${SDK}/systems/drv/et -endif - # need to add vpath sources -VPATH = ../shared $(ET_ROBO) +VPATH = ../shared # Add the srcs to be found by vpath LSRCS += mpool.c -ifdef ROBO_CHIPS -platformsplt = $(subst -, , ${platform}) # change hyphens to spaces -platformbase = $(word 1,${platformsplt}) - -ifeq ($(platformbase), keystone) - LSRCS += etc_robo_spi.c aiutils.c -else - ifeq ($(platformbase), keystone_le) - LSRCS += etc_robo_spi.c aiutils.c - else - ifeq ($(platformbase), iproc) - LSRCS += robo_srab.c robo_spi.c aiutils.c - endif - endif -endif # platformbase - -endif # ROBO_CHIPS # Add shared BDE sources VPATH += ../../shared diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c index 1a04b2b52e9b..464a72bd3e41 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c @@ -35,30 +35,22 @@ #include "linux_shbde.h" -#ifdef BCM_ROBO_SUPPORT -/* robo/et related header files */ -#include - -#include - -#if defined(KEYSTONE) -#include -#include -#include -#include -#elif defined(IPROC_CMICD) -#include -#include -#ifdef BCM_STARFIGHTER3_SUPPORT -#include -#endif -#include -#include -#else /* BCM4704 */ -#include -#include -#endif -#endif /* BCM_ROBO_SUPPORT */ + +#ifdef __GNUC__ +#if __GNUC__ == 8 +/* + * Prevent gcc 8.1.10 using a compiler inline memcpy even if using -fno-builtin or + * -fno-builtin-memcpy . + * __inline_memcpy and __memcpy are kernel functions that may be used instead, + * for either an inline or non-inline implementations of the function + */ +#define MEMCPY __inline_memcpy +#else +#define MEMCPY memcpy +#endif /* __GNUC__ == 8 */ +#else /* ifdef __GNUC__ */ +#define MEMCPY memcpy +#endif /* ifdef __GNUC__ */ #define PCI_USE_INT_NONE (-1) #define PCI_USE_INT_INTX (0) @@ -108,26 +100,6 @@ int msixcnt = 1; #define PCI_DEVICE_ID_PLX_9056 0x9056 #endif -/* local defined device IDs, refer to bcmdevs.h */ -#ifndef BCM53000_GMAC_ID -#define BCM53000_GMAC_ID 0x4715 /* 53003 gmac id */ -#endif -#ifndef BCM53010_GMAC_ID -#define BCM53010_GMAC_ID 0x4715 /* 5301x gmac id */ -#endif -#ifndef BCM47XX_ENET_ID -#define BCM47XX_ENET_ID 0x4713 /* 4710 enet */ -#endif -#ifndef BCM53010_CHIP_ID -#define BCM53010_CHIP_ID 0xcf12 /* 53010 chipcommon chipid */ -#endif -#ifndef BCM53018_CHIP_ID -#define BCM53018_CHIP_ID 0xcf1a /* 53018 chipcommon chipid */ -#endif -#ifndef BCM53020_CHIP_ID -#define BCM53020_CHIP_ID 0xcf1e /* 53020 chipcommon chipid */ -#endif - /* For 2.4.x kernel support */ #ifndef IRQF_SHARED #define IRQF_SHARED SA_SHIRQ @@ -186,14 +158,6 @@ MODULE_PARM_DESC(spifreq, "Force SPI Frequency for Keystone CPU (0 for default frequency)"); #endif -#if defined(BCM_EA_SUPPORT) -#if defined(BCM_TK371X_SUPPORT) -static int eadevices; -LKM_MOD_PARAM(eadevices, "i", int, 0); -MODULE_PARM_DESC(eadevices, -"Number of TK371X devices"); -#endif /* */ -#endif /* BCM_EA_SUPPORT */ /* Compatibility */ #ifdef LKM_2_4 @@ -203,7 +167,7 @@ MODULE_PARM_DESC(eadevices, #define IRQ_HANDLED #define SYNC_IRQ(_i) synchronize_irq() #else /* LKM_2_6 */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) #define _ISR_RET irqreturn_t #else #define _ISR_RET int @@ -212,6 +176,7 @@ MODULE_PARM_DESC(eadevices, #define _ISR_PARAMS(_i,_d,_r) int _i, void *_d #else #define _ISR_PARAMS(_i,_d,_r) int _i, void *_d, struct pt_regs *_r +typedef irqreturn_t (*irq_handler_t)(int _i, void *_d, struct pt_regs *_r); #endif #define SYNC_IRQ(_i) synchronize_irq(_i) char * ___strtok; @@ -364,7 +329,6 @@ static int _ndevices = 0; static int _switch_ndevices = 0; static int _ether_ndevices = 0; static int _cpu_ndevices = 0; -static int robo_switch = 0; #define VALID_DEVICE(_n) ((_n >= 0) && (_n < _ndevices)) @@ -375,48 +339,10 @@ static uint32 iproc_cmicx_irqs[IHOST_CMICX_MAX_INTRS]; #endif /* CPU MMIO area used with CPU cards provided on demo boards */ -#if (defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) || defined(BCM_DNX_SUPPORT) || defined(BCM_DNXF_SUPPORT)) && (defined(__DUNE_WRX_BCM_CPU__) || defined(__DUNE_GTO_BCM_CPU__)) +#if defined(BCM_SAND_SUPPORT) && (defined(__DUNE_WRX_BCM_CPU__) || defined(__DUNE_GTO_BCM_CPU__)) static void *cpu_address = NULL; #endif -#ifdef BCM_ROBO_SUPPORT - -/* for SPI access via bcm4710 core */ -static void *robo = NULL; -static void *sbh = NULL; - -#ifdef ALTA_ROBO_SPI - -extern void *alta_eth_spi_ctrl; - -extern int -robo_spi_read(void *cookie, uint16_t reg, uint8_t *buf, int len); - -extern int -robo_spi_write(void *cookie, uint16_t reg, uint8_t *buf, int len); - -#define ROBO_RREG(_robo, _dev, _page, _reg, _buf, _len) \ - robo_spi_read(_dev ? NULL : alta_eth_spi_ctrl, \ - (_page << 8) | (_reg), _buf, _len) -#define ROBO_WREG(_robo, _dev, _page, _reg, _buf, _len) \ - robo_spi_write(_dev ? NULL : alta_eth_spi_ctrl, \ - (_page << 8) | (_reg), _buf, _len) - -#else /* !ALTA_ROBO_SPI */ - -#if defined(KEYSTONE) || defined(IPROC_CMICD) -#define ROBO_RREG(_robo, _dev, _page, _reg, _buf, _len) \ - robo_rreg(_robo, _dev, _page, _reg, _buf, _len) -#define ROBO_WREG(_robo, _dev, _page, _reg, _buf, _len) \ - robo_wreg(_robo, _dev, _page, _reg, _buf, _len) -#else -#define ROBO_RREG(_robo, _dev, _page, _reg, _buf, _len) -#define ROBO_WREG(_robo, _dev, _page, _reg, _buf, _len) -#endif - -#endif /* ALTA_ROBO_SPI */ - -#endif /* BCM_ROBO_SUPPORT */ /* Broadcom BCM4704 */ #define BCM4704_VENDOR_ID 0x14E4 @@ -500,6 +426,17 @@ robo_spi_write(void *cookie, uint16_t reg, uint8_t *buf, int len); #define BCM58712_PCI_VENDOR_ID 0x14E4 #define BCM58712_PCI_DEVICE_ID 0x168E +/* Default gicd address if not available in DTB */ +#define IHOST_GICD_REG_ADDR 0x10781100 +#define IHOST_GICD_REG_REMAP_LEN 0x100 + +#define IHOST_GICD_REG_ADDR_VALID(d, addr) \ + (_devices[d].bde_dev.base_address1 && \ + (addr & 0xFFFFFF00) == _devices[d].phys_address1) + +#define IHOST_GICD_REG_ADDR_REMAP(d, addr) \ + (void *)(_devices[d].bde_dev.base_address1 + (addr - _devices[d].phys_address1)) + static uint32_t _read(int d, uint32_t addr); #ifdef BCM_ICS @@ -551,6 +488,19 @@ _parse_eb_args(char *str, char * format, ...) static void _bde_add_device(void) { + int add_switch_device = 0; + if (_devices[_ndevices].dev_type & BDE_SWITCH_DEV_TYPE) { + _switch_ndevices++; + add_switch_device = 1; + } else if (_devices[_ndevices].dev_type & BDE_ETHER_DEV_TYPE) { + _ether_ndevices++; + } else if (_devices[_ndevices].dev_type & BDE_CPU_DEV_TYPE) { + _cpu_ndevices++; + } else { + return; + } + _ndevices++; + /* * In order to be backward compatible with the user mode BDE * (specifically the interrupt IOCTLs) and the CM, switch devices @@ -558,7 +508,7 @@ _bde_add_device(void) * order), we let the non-switch device(s) drop down to the end of * the device array. */ - if (_switch_ndevices > 0) { + if (add_switch_device) { bde_ctrl_t tmp_dev; int i, s = 0; @@ -573,13 +523,12 @@ _bde_add_device(void) } _devices[i] = tmp_dev; } - } - /* Initialize device locks and dma */ - if (_ndevices > 0) { - spin_lock_init(&_devices[_ndevices-1].lock); - _dma_init(robo_switch, _ndevices-1); + _dma_init(_switch_ndevices-1); } + + /* Initialize device locks */ + spin_lock_init(&_devices[_ndevices-1].lock); } static int @@ -590,8 +539,7 @@ _eb_device_create(resource_size_t paddr, int irq, int rd_hw, int wr_hw) dev_id = _ndevices; - ctrl = _devices + _ndevices++; - _switch_ndevices++; + ctrl = _devices + _ndevices; ctrl->dev_type |= BDE_EB_DEV_TYPE | BDE_SWITCH_DEV_TYPE; ctrl->pci_device = NULL; /* No PCI bus */ @@ -617,15 +565,15 @@ _eb_device_create(resource_size_t paddr, int irq, int rd_hw, int wr_hw) ctrl->isr = NULL; ctrl->isr_data = NULL; - _bde_add_device(); - gprintk("Created EB device at BA=%x IRQ=%d RD16=%d WR16=%d device=0x%x\n", (unsigned int)paddr, irq, rd_hw, wr_hw, ctrl->bde_dev.device); + _bde_add_device(); + return 0; } -#if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) || defined(BCM_DNX_SUPPORT) || defined(BCM_DNXF_SUPPORT) +#ifdef BCM_SAND_SUPPORT #include @@ -637,9 +585,6 @@ sand_device_create(void) ctrl = _devices; /* FIX_ME: on petra, take first device */ #ifndef __DUNE_LINUX_BCM_CPU_PCIE__ - _switch_ndevices++; - _ndevices++; - ctrl->dev_type |= BDE_PCI_DEV_TYPE | BDE_SWITCH_DEV_TYPE; ctrl->pci_device = NULL; /* No PCI bus */ @@ -677,7 +622,7 @@ sand_device_create(void) return 0; } -#endif +#endif /* BCM_SAND_SUPPORT */ #ifdef IPROC_CMICD static void @@ -739,8 +684,7 @@ iproc_cmicd_probe(struct platform_device *pldev) } size = memres->end - memres->start + 1; - ctrl = _devices + _ndevices++; - _switch_ndevices++; + ctrl = _devices + _ndevices; ctrl->dev_type = BDE_AXI_DEV_TYPE | BDE_SWITCH_DEV_TYPE | BDE_256K_REG_SPACE; ctrl->pci_device = NULL; /* No PCI bus */ @@ -764,6 +708,24 @@ iproc_cmicd_probe(struct platform_device *pldev) ctrl->bde_dev.device = readl(icfg_chip_id) & 0xffff; ctrl->bde_dev.rev = readl(icfg_chip_id+1) & 0xff; iounmap(icfg_chip_id); + /* Map GICD block in the AXI memory space into CPU address space */ + memres = iproc_platform_get_resource(pldev, IORESOURCE_MEM, 1); + if (memres) { + ctrl->bde_dev.base_address1 = (sal_vaddr_t)IOREMAP(memres->start, memres->end - memres->start + 1); + ctrl->phys_address1 = memres->start; + } else { + /* Use default address if not available in DTB */ + ctrl->bde_dev.base_address1 = (sal_vaddr_t)IOREMAP(IHOST_GICD_REG_ADDR, IHOST_GICD_REG_REMAP_LEN); + ctrl->phys_address1 = IHOST_GICD_REG_ADDR; + } + if (ctrl->bde_dev.base_address1) { + if (debug >= 1) { + gprintk("base_address1:0x%lx phys_address1:0x%lx\n", + (unsigned long)ctrl->bde_dev.base_address1, (unsigned long)ctrl->phys_address1); + } + } else { + gprintk("Error mapping ihost GICD registers\n"); + } } else #endif { @@ -777,6 +739,7 @@ iproc_cmicd_probe(struct platform_device *pldev) ctrl->bde_dev.device = dev_rev_id & 0xffff; ctrl->bde_dev.rev = (dev_rev_id >> 16) & 0xff; #endif + ctrl->bde_dev.base_address1 = 0; } #ifdef CONFIG_OF @@ -901,10 +864,6 @@ iproc_has_cmicd(void) /* Only allowed accessing CMICD module if the SOC has it */ switch (cca_cid) { - case BCM53010_CHIP_ID: - case BCM53018_CHIP_ID: - case BCM53020_CHIP_ID: - return 0; default: break; } @@ -1052,8 +1011,7 @@ _ics_bde_create(void) resource_size_t paddr; if (_ndevices == 0) { - ctrl = _devices + _ndevices++; - _switch_ndevices++; + ctrl = _devices + _ndevices; ctrl->dev_type |= BDE_ICS_DEV_TYPE | BDE_SWITCH_DEV_TYPE; ctrl->pci_device = NULL; /* No PCI bus */ @@ -1072,8 +1030,8 @@ _ics_bde_create(void) ctrl->isr = NULL; ctrl->isr_data = NULL; - _bde_add_device(); printk("Created ICS device ..%x\n", ctrl->bde_dev.base_address); + _bde_add_device(); } return 0; @@ -1248,7 +1206,6 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM56150_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56151_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56152_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM56613_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56930_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56931_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56935_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1301,14 +1258,6 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM56044_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56045_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56046_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88230_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88030_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88034_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88039_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88231_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88235_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88236_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88239_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM55440_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56440_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56441_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1450,15 +1399,6 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM56174_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53570_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53575_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, -#ifdef BCM_ROBO_SUPPORT - { BROADCOM_VENDOR_ID, BCM47XX_ENET_ID, PCI_ANY_ID, PCI_ANY_ID }, -#ifdef KEYSTONE - { BROADCOM_VENDOR_ID, BCM53000_GMAC_ID, PCI_ANY_ID, PCI_ANY_ID }, -#endif -#endif - { SANDBURST_VENDOR_ID, QE2000_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { SANDBURST_VENDOR_ID, BCM88020_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { SANDBURST_VENDOR_ID, BCM88025_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9656, PCI_ANY_ID, PCI_ANY_ID }, { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9056, PCI_ANY_ID, PCI_ANY_ID }, { BCM53000_VENDOR_ID, BCM53000PCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1506,6 +1446,7 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM88270_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88272_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88273_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88274_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88278_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88279_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1524,7 +1465,6 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM88685_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88380_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88381_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88690_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88202_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88360_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88361_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1537,6 +1477,25 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM88661_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88664_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, #endif +#ifdef BCM_DNX_SUPPORT + { BROADCOM_VENDOR_ID, BCM88690_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88690_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88691_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88692_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88693_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88694_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88695_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88696_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88697_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88698_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88699_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8869A_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8869B_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8869C_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8869D_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8869F_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88800_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, +#endif /* BCM_DNX_SUPPORT */ #ifdef BCM_DFE_SUPPORT { BROADCOM_VENDOR_ID, BCM88750_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88753_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -2083,24 +2042,20 @@ _msi_connect(bde_ctrl_t *ctrl) #else ret = pci_enable_msix(ctrl->pci_device, ctrl->entries, ctrl->msix_cnt); -#endif if (ret > 0) { /* Not enough vectors available , Retry MSI-X */ gprintk("Retrying with MSI-X interrupts = %d\n", ret); ctrl->msix_cnt = ret; msixcnt = ret; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) - ret = pci_enable_msix_range(ctrl->pci_device, - ctrl->entries, ctrl->msix_cnt, ctrl->msix_cnt); -#else ret = pci_enable_msix(ctrl->pci_device, ctrl->entries, ctrl->msix_cnt); -#endif if (ret != 0) goto er_intx_free; - } else if (ret < 0) { - /* Error */ - goto er_intx_free; + } +#endif + if (ret < 0) { + /* Error */ + goto er_intx_free; } else { gprintk("Enabled MSI-X interrupts = %d\n", ctrl->msix_cnt); return 0; @@ -2228,13 +2183,12 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) int cmic_bar; int baroff = 0; int iproc = 0; - uint32 gmac_base = 0; int plx_dev = 0; int eth_dev = 0; int cpu_dev = 0; int update_devid = 0; int paxb_core = 0; - int rescan = 0, rescan_idx = -1; + int add_dev = 0, rescan = 0, rescan_idx = -1; shbde_hal_t shared_bde, *shbde = &shared_bde; if (debug >= 4) {gprintk("probing: vendor_id=0x%x, device_id=0x%x\n", dev->vendor, dev->device);} @@ -2280,17 +2234,6 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) case PCI_DEVICE_ID_PLX_9656: plx_dev = 1; break; -#if defined (BCM_ROBO_SUPPORT) && defined(KEYSTONE) - case BCM53000_GMAC_ID: - eth_dev = 1; - gmac_base = SB_ENUM_BASE; - break; -#endif -#if defined (BCM_ROBO_SUPPORT) - case BCM47XX_ENET_ID: - eth_dev = 1; - break; -#endif case BCM53000PCIE_DEVICE_ID: cpu_dev = 1; break; @@ -2332,10 +2275,10 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) if (_ether_ndevices >= LINUX_BDE_MAX_ETHER_DEVICES) { return 0;; } - ctrl = _devices + _ndevices++; - _ether_ndevices++; + ctrl = _devices + _ndevices; ctrl->dev_type |= BDE_ETHER_DEV_TYPE; ctrl->iLine = dev->irq; + add_dev = 1; if (debug >= 1) gprintk("Found PCI device %04x:%04x as Ethernet device\n", dev->vendor, dev->device); @@ -2343,9 +2286,9 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) if (_cpu_ndevices >= LINUX_BDE_MAX_CPU_DEVICES) { return 0;; } - ctrl = _devices + _ndevices++; - _cpu_ndevices++; + ctrl = _devices + _ndevices; ctrl->dev_type |= BDE_CPU_DEV_TYPE; + add_dev = 1; if (debug >= 1) gprintk("Found PCI device %04x:%04x as CPU device\n", dev->vendor, dev->device); @@ -2365,16 +2308,16 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) ctrl = _devices + rescan_idx; ctrl->dev_state = BDE_DEV_STATE_CHANGED; } else { - ctrl = _devices + _ndevices++; - _switch_ndevices++; + ctrl = _devices + _ndevices; ctrl->dev_type |= BDE_SWITCH_DEV_TYPE; ctrl->domain_no = pci_domain_nr(dev->bus); ctrl->bus_no = dev->bus->number; ctrl->dev_state = BDE_DEV_STATE_NORMAL; + add_dev = 1; } /* Save shared BDE HAL in device structure */ - memcpy(&ctrl->shbde, shbde, sizeof(ctrl->shbde)); + MEMCPY(&ctrl->shbde, shbde, sizeof(ctrl->shbde)); if (update_devid) { /* Re-read the device ID */ @@ -2675,42 +2618,8 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) } /* Save shared BDE HAL in device structure */ - memcpy(&ctrl->shbde, shbde, sizeof(ctrl->shbde)); - - - /* - * Since the GMAC driver of Robo chips needs access to the - * ChipCommon and Wrapper registers, we set the base address - * as the enumeration base address and its size as 3MB to - * cover all Wrapper register regions. - */ - if (gmac_base) { - uint32_t offset; - - ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(gmac_base, 0x300000); - - /* Record the base address of GMAC core */ - offset = ctrl->phys_address - gmac_base; - ctrl->alt_base_addr = ctrl->bde_dev.base_address + offset; - ctrl->phys_address = gmac_base; - } - - /* - * Workaround bug in FE2K A1 part; shows as A0 part in PCI config space, - * read the FE's regs directly to get the true revision - */ - if (ctrl->bde_dev.device == BCM88020_DEVICE_ID && ctrl->bde_dev.rev == 0) { -#define FE2000_REVISION_OFFSET (0x0) - uint32_t fe_rev; + MEMCPY(&ctrl->shbde, shbde, sizeof(ctrl->shbde)); - fe_rev = *((uint32_t*)(ctrl->bde_dev.base_address + FE2000_REVISION_OFFSET)); - if ((fe_rev >> 16) == BCM88020_DEVICE_ID) { - fe_rev &= 0xff; - } else { - fe_rev = (fe_rev >> 24) & 0xff; - } - ctrl->bde_dev.rev = fe_rev; - } ctrl->isr = NULL; ctrl->isr_data = NULL; @@ -2732,28 +2641,21 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) if (debug >= 1) gprintk("PCI resource len 8MB\n"); } -#if defined (BCM_ROBO_SUPPORT) && !defined(ALTA_ROBO_SPI) - /* MDC/MDIO path for pseudo PHY access to ROBO register on BCM5836/4704 */ - if (dev->device == BCM47XX_ENET_ID) { - ((uint32 *)ctrl->bde_dev.base_address)[0x410 / 4] = 0; - } -#endif #ifdef LINUX_BDE_DMA_DEVICE_SUPPORT ctrl->dma_dev = &dev->dev; #endif - if (!rescan) { - _bde_add_device(); - } - if (debug >= 2) { gprintk("_pci_probe: configured dev:0x%x rev:0x%x with base_addresses: 0x%lx 0x%lx\n", (unsigned)ctrl->bde_dev.device, (unsigned)ctrl->bde_dev.rev, (unsigned long)ctrl->bde_dev.base_address, (unsigned long)ctrl->bde_dev.base_address1); } - /* Let's boogie */ + if (add_dev) { + _bde_add_device(); + } + /* Let's boogie */ return 0; } @@ -2833,8 +2735,7 @@ static struct pci_driver _device_driver = { static void _spi_device_setup(void) { bde_ctrl_t *ctrl; - ctrl = _devices + _ndevices++; - _switch_ndevices++; + ctrl = _devices + _ndevices; ctrl->dev_type |= BDE_SWITCH_DEV_TYPE; ctrl->iLine = 0xa3; ctrl->be_pio = 0; @@ -2846,483 +2747,12 @@ _spi_device_setup(void) { gprintk("SPI Slave Mode: force ctrl->bde_dev.rev=0x%x\n",ctrl->bde_dev.rev); gprintk("SPI Slave Mode: force ctrl->dev_type=0x%x\n",ctrl->dev_type); } + _bde_add_device(); } #endif /* BCM_ICS */ -#ifdef BCM_ROBO_SUPPORT - -#ifdef KEYSTONE -#define DEFAULT_FREQ (SPI_FREQ_DEFAULT) -#define FREQ_20MHZ (SPI_FREQ_20MHZ) -#else /* IPROC_CMICD */ -#define DEFAULT_FREQ (0) -#define FREQ_20MHZ (0) -#endif - - -/* -* The model_info /rev_info for Robo devices is defined like this: -* -* 31 28 27 24 23 20 19 16 15 8 7 0 -* +----+---------+------+-----+---------+--------+ -* | op | reserved| mask |len | page |offset | -* +----+---------+------+-----+---------+--------+ -* -* op: 1:OR phyidl, 2: use PCIE device ID -* mlen: mask len (in bytes) 1:means 0xf,2 means 0xff -* len: Size of model/rev ID register (in bytes) -* page: Page containing model ID and revision registers -* offset: Model/rev ID register offset -*/ -static struct bde_spi_device_id _spi_id_table[] = { - { BCM53242_PHYID_HIGH, BCM53242_PHYID_LOW , 0, 0, DEFAULT_FREQ}, - { BCM53262_PHYID_HIGH, BCM53262_PHYID_LOW , 0, 0, DEFAULT_FREQ}, - { BCM53115_PHYID_HIGH, BCM53115_PHYID_LOW , 0, 0, DEFAULT_FREQ}, - { BCM53118_PHYID_HIGH, BCM53118_PHYID_LOW , 0, 0, DEFAULT_FREQ}, - { BCM53280_PHYID_HIGH, BCM53280_PHYID_LOW , 0x101800e8, 0, FREQ_20MHZ}, - { BCM53101_PHYID_HIGH, BCM53101_PHYID_LOW , 0, 0x110240, FREQ_20MHZ}, - { BCM53125_PHYID_HIGH, BCM53125_PHYID_LOW , 0, 0x110240, FREQ_20MHZ}, - { BCM53128_PHYID_HIGH, BCM53128_PHYID_LOW , 0, 0x110240, FREQ_20MHZ}, - { BCM53600_PHYID_HIGH, BCM53600_PHYID_LOW , 0x101800e8, 0, FREQ_20MHZ}, - { BCM89500_PHYID_HIGH, BCM89500_PHYID_LOW ,0x240230, 0x110240, FREQ_20MHZ}, - { BCM53010_PHYID_HIGH, BCM53010_PHYID_LOW ,0x240230, 0x110240, 0}, - { BCM53018_PHYID_HIGH, BCM53018_PHYID_LOW ,0x240230, 0x110240, 0}, - { BCM5389_PHYID_HIGH, BCM5389_PHYID_LOW, 0x110230, 0x110240, DEFAULT_FREQ}, - { BCM53020_PHYID_HIGH, BCM53020_PHYID_LOW ,0x20240230, 0x110240, 0}, - { BCM5396_PHYID_HIGH , BCM5396_PHYID_LOW, 0x110230, 0x110240, DEFAULT_FREQ}, - { BCM53134_PHYID_HIGH, BCM53134_PHYID_LOW , 0, 0x110240, DEFAULT_FREQ}, - { 0, 0, 0, 0, 0 }, -}; -#endif - -#ifdef BCM_ROBO_SUPPORT - -static int -_spi_device_valid_check(unsigned short phyidh,unsigned short phyidl, uint8 check_flag) -{ - struct bde_spi_device_id *_ids; - int idx, match_idx; - - match_idx = -1; - idx = 0; - - if (check_flag == 0){ - /* check_flag == 0 check phyidh only*/ - for (_ids = _spi_id_table; - _ids->phyid_high && _ids->phyid_low; _ids++){ - if (_ids->phyid_high == phyidh) { - return 0; - } - } - /* No valid SPI devices found */ - return 1; - } else { - while(_spi_id_table[idx].phyid_high){ - if (phyidh == _spi_id_table[idx].phyid_high && - phyidl == _spi_id_table[idx].phyid_low) { - /* Found a match */ - match_idx = idx; - break; - } - idx++; - } - return match_idx; - } -} - -#if defined(IPROC_CMICD) || defined(KEYSTONE) -#define ROBO_ATTACH_AVAIL -#endif - -#ifdef ROBO_ATTACH_AVAIL - -#define SOC_ATTACH(_sc)\ - ai_soc_kattach(_sc) - -#if defined(IPROC_CMICD) -#ifdef BCM_STARFIGHTER3_SUPPORT -#define ROBO_ATTACH_SPI(_sih, _ss)\ - robo_attach_spi(_sih) -#define ROBO_DETACH_SPI(robo)\ - robo_detach_spi(robo) -#define ROBO_SPI_RREG(_robo, _dev, _page, _reg, _buf, _len) \ - robo_spi_rreg(_robo, _dev, _page, _reg, _buf, _len) -#define ROBO_SPI_WREG(_robo, _dev, _page, _reg, _buf, _len) \ - robo_spi_wreg(_robo, _dev, _page, _reg, _buf, _len) -#endif -#define ROBO_ATTACH(_sih, _ss)\ - robo_attach(_sih) -#define MAX_BUSTYPE 1 -#define ROBO_SWITCH_BUS(_robo, _bustype) -#define ROBO_SELECT_DEVICE(_robo, _phyidh, _phyidl) -#else /* KEYSTONE */ -#define ROBO_ATTACH(_sih, _ss)\ - robo_attach(_sih, _ss) -/* bustype 2: ROBO_MDCMDIO_BUS, 1: ROBO_SPI_BUS */ -#define MAX_BUSTYPE 2 -#define ROBO_SWITCH_BUS(_robo, _bustype)\ - robo_switch_bus(_robo, _bustype) - -#define ROBO_SELECT_DEVICE(_robo, _phyidh, _phyidl) \ - robo_select_device(_robo, _phyidh, _phyidl) -#endif - -#else - -#define SOC_ATTACH(_sc) (NULL) -#define ROBO_ATTACH(_sih, _ss) (NULL) -#define MAX_BUSTYPE (0) -#define ROBO_SWITCH_BUS(_robo, _bustype) -#define ROBO_SELECT_DEVICE(_robo, _phyidh, _phyidl) -#endif - - -#if defined(IPROC_CMICD) && defined(BCM_STARFIGHTER3_SUPPORT) -static int -probe_robo_switch_iproc_spi(void) -{ - int dev; - int max_devices, max_bustype; - uint8 buf[8]; - unsigned short phyidh = 0, phyidl = 0; - - - /* Get Robo device handle */ - if (robo == NULL) { - robo = (void *)ROBO_ATTACH_SPI(sbh, 0); - } - if (robo == NULL) { - return -ENODEV; - } - - max_bustype = MAX_BUSTYPE + 1; - - while(_spi_device_valid_check(phyidh, 0, 0)) { - max_bustype --; - if(!max_bustype) - return -ENODEV; - buf[0] = buf[1] = 0; - ROBO_SPI_RREG(robo, 0, 0x10, 0x04, buf, (uint)2); - phyidh = buf[0] | (buf[1] << 8); - /* re-try */ - if ((phyidh == 0x0) || (phyidh == 0xffff)) { - ROBO_SPI_RREG(robo, 0, 0x10, 0x04, buf, (uint)2); - phyidh = buf[0] | (buf[1] << 8); - } - } - - /* For psedo_phy access, only support one robo switch*/ - /* For Northstar, only one switch on SRAB interface */ - max_devices = (max_bustype == MAX_BUSTYPE) ? 1 : LINUX_BDE_MAX_SWITCH_DEVICES; - - for (dev = 0; dev < max_devices; dev++) { - bde_ctrl_t *ctrl; - int match_idx, i; - unsigned short phyidl_nr; /* phyidl with revision stripped */ - uint16 model_id; - uint8 rev_id; - uint32 addr, len; - uint32 mlen; - - if (_switch_ndevices >= LINUX_BDE_MAX_SWITCH_DEVICES) { - break; - } - buf[0] = buf[1] = 0; - ROBO_SPI_RREG(robo, dev, 0x10, 0x04, buf, (uint)2); - phyidh = buf[0] | (buf[1] << 8); - - buf[0] = buf[1] = 0; - ROBO_SPI_RREG(robo, dev, 0x10, 0x06, buf, (uint)2); - phyidl = buf[0] | (buf[1] << 8); - - /* Strip revision */ - phyidl_nr = phyidl & 0xfff0; - - match_idx = _spi_device_valid_check(phyidh, phyidl_nr, 1); - if (match_idx == -1) { - if (debug >= 1) gprintk("found %d robo device(s).\n", robo_switch); - break; - } - - model_id = phyidl_nr; - - if(_spi_id_table[match_idx].rev_info){ - addr = _spi_id_table[match_idx].rev_info & 0xffff; - len = (_spi_id_table[match_idx].rev_info >> 16) & 0xf; - ROBO_SPI_RREG(robo, dev, (addr >> 8), (addr & 0xff), buf, (uint)len); - mlen = (_spi_id_table[match_idx].rev_info >> 20) & 0xf; - rev_id = 0; - for (i = 0; i < mlen; i++) - rev_id |= buf[i] << (i << 3); - } else { - rev_id = phyidl & 0xf; - } - - gprintk("found robo device with %d:%04x:%04x:%04x:%02x\n", - dev, phyidh, phyidl, model_id, rev_id); - - ROBO_SELECT_DEVICE(robo, phyidh, phyidl); - - /* Match supported chips */ - ctrl = _devices + _ndevices++; - _switch_ndevices++; - - if (NULL == (ctrl->spi_device = (struct spi_dev *) - KMALLOC(sizeof(struct spi_dev), GFP_KERNEL))) { - gprintk("no memory available"); - return -ENOMEM; - } - ctrl->dev_type = (BDE_SPI_DEV_TYPE | BDE_SWITCH_DEV_TYPE); - ctrl->spi_device->cid = dev; - ctrl->spi_device->part = model_id; - ctrl->spi_device->rev = rev_id; - ctrl->spi_device->robo = robo; - ctrl->spi_device->phyid_high = phyidh; - ctrl->spi_device->phyid_low = phyidl; - ctrl->bde_dev.device = model_id; - ctrl->bde_dev.rev = rev_id; - ctrl->bde_dev.base_address = (sal_vaddr_t)NULL; - ctrl->isr = NULL; - ctrl->isr_data = NULL; - robo_switch++; - _bde_add_device(); - - } - - return robo_switch; - -} - -int spi_device_found = 0; - -#endif /* IPROC_CMICD || SF3 */ - - -static int -probe_robo_switch(void) -{ - int dev; - int max_devices, max_bustype; - uint8 buf[8]; - unsigned short phyidh = 0, phyidl = 0; -#if defined(KEYSTONE) - uint32 spi_freq = 0; -#endif -#if defined(IPROC_CMICD) - sal_vaddr_t addr_base; - uint32 data_reg; -#endif /* IPROC_CMICD */ - - - spin_lock_init(&bus_lock); - - if (_switch_ndevices) { - /* - * Currently skip probe robo if esw chips were found - * FIX this while combined plateform support. - */ - return robo_switch; - } - - /* Get Robo device handle */ - if (robo == NULL) { - sbh = (void *)SOC_ATTACH(NULL); - if (sbh == NULL) { - return -ENODEV; - } - } - -#if defined(IPROC_CMICD) && defined(BCM_STARFIGHTER3_SUPPORT) - robo_switch = probe_robo_switch_iproc_spi(); - - if (robo_switch > 0) { - /* Robo switch found by SPI probe */ - spi_device_found = 1; - gprintk("SPI device found, Skipping SRAB probe\n"); - return robo_switch; - } else { - gprintk("SPI device NOT found, Probe SRAB probe\n"); - ROBO_DETACH_SPI(robo); - } -#endif - - if (robo == NULL) { - robo = (void *)ROBO_ATTACH(sbh, 0); - } - if (robo == NULL) { - return -ENODEV; - } - - max_bustype = MAX_BUSTYPE + 1; - - while(_spi_device_valid_check(phyidh, 0, 0)) { - max_bustype --; - if(!max_bustype) - return -ENODEV; - ROBO_SWITCH_BUS(robo, max_bustype); - buf[0] = buf[1] = 0; - ROBO_RREG(robo, 0, 0x10, 0x04, buf, (uint)2); - phyidh = buf[0] | (buf[1] << 8); - /* re-try */ - if ((phyidh == 0x0) || (phyidh == 0xffff)) { - ROBO_RREG(robo, 0, 0x10, 0x04, buf, (uint)2); - phyidh = buf[0] | (buf[1] << 8); - } - } - - /* For psedo_phy access, only support one robo switch*/ - /* For Northstar, only one switch on SRAB interface */ - max_devices = (max_bustype == MAX_BUSTYPE) ? 1 : LINUX_BDE_MAX_SWITCH_DEVICES; - - for (dev = 0; dev < max_devices; dev++) { - bde_ctrl_t *ctrl; - int match_idx, i; - unsigned short phyidl_nr; /* phyidl with revision stripped */ - uint16 model_id; - uint8 rev_id; -#if defined(KEYSTONE) || defined(IPROC_CMICD) - uint32 addr, len; -#endif - uint32 mlen, op; - - if (_switch_ndevices >= LINUX_BDE_MAX_SWITCH_DEVICES) { - break; - } - buf[0] = buf[1] = 0; - ROBO_RREG(robo, dev, 0x10, 0x04, buf, (uint)2); - phyidh = buf[0] | (buf[1] << 8); - - buf[0] = buf[1] = 0; - ROBO_RREG(robo, dev, 0x10, 0x06, buf, (uint)2); - phyidl = buf[0] | (buf[1] << 8); - - /* Strip revision */ - phyidl_nr = phyidl & 0xfff0; - - match_idx = _spi_device_valid_check(phyidh, phyidl_nr, 1); - if (match_idx == -1) { - if (debug >= 1) gprintk("found %d robo device(s).\n", robo_switch); - break; - } - - if(_spi_id_table[match_idx].model_info){ -#if defined(KEYSTONE) || defined(IPROC_CMICD) - addr = _spi_id_table[match_idx].model_info & 0xffff; - len = (_spi_id_table[match_idx].model_info >> 16) & 0xf; -#endif - ROBO_RREG(robo, dev, (addr >> 8), (addr & 0xff), buf, (uint)len); - mlen = (_spi_id_table[match_idx].model_info >> 20) & 0xf; - model_id = 0; - for (i = 0; i < mlen; i++) - model_id |= buf[i] << (i << 3); - op = (_spi_id_table[match_idx].model_info >> 28) & 0xf; - if(op == 1) { - model_id |= phyidl_nr; -#if defined(IPROC_CMICD) - } else if (op == 2) { - /* The package id of NS+ is determined by : - * Write 0 to 0x18012120 (PAXB_0_CONFIG_IND_ADDR) - * Read 0x18012124 (PAX_B_CONFIG_IND_DATA), - * bits 31:16 will be the device id from OTP space - */ -#define PAXB_ENUM_BASE (0x18012000) -#define PAXB_CONFIG_IND_ADDR_OFFSET (0x120) -#define PAXB_CONFIG_IND_DATA_OFFSET (0x124) - - addr_base = (sal_vaddr_t)IOREMAP(PAXB_ENUM_BASE, 0x1000); - if (!addr_base) { - gprintk("ioremap of PAXB registers failed\n"); - } else { - writel(0x0, (uint32 *)(addr_base + - PAXB_CONFIG_IND_ADDR_OFFSET)); - data_reg = readl((uint32 *)(addr_base + - PAXB_CONFIG_IND_DATA_OFFSET)); - model_id = (data_reg >> 16); - iounmap((void *)addr_base); - - /* - * Some model ID can't be determined by PCIE device ID - * It needs to refer some OTP values. - */ - robo_model_id_adjust_from_otp(robo, &model_id); - } - -#undef PAXB_ENUM_BASE -#undef PAXB_CONFIG_IND_ADDR_OFFSET -#undef PAXB_CONFIG_IND_DATA_OFFSET -#endif /* IPROC_CMICD */ - } - } else { - model_id = phyidl_nr; - } - if(_spi_id_table[match_idx].rev_info){ -#if defined(KEYSTONE) || defined(IPROC_CMICD) - addr = _spi_id_table[match_idx].rev_info & 0xffff; - len = (_spi_id_table[match_idx].rev_info >> 16) & 0xf; -#endif - ROBO_RREG(robo, dev, (addr >> 8), (addr & 0xff), buf, (uint)len); - mlen = (_spi_id_table[match_idx].rev_info >> 20) & 0xf; - rev_id = 0; - for (i = 0; i < mlen; i++) - rev_id |= buf[i] << (i << 3); - } else { - rev_id = phyidl & 0xf; - } - gprintk("found robo device with %d:%04x:%04x:%04x:%02x\n", - dev, phyidh, phyidl, model_id, rev_id); - - ROBO_SELECT_DEVICE(robo, phyidh, phyidl); - - /* Match supported chips */ - ctrl = _devices + _ndevices++; - _switch_ndevices++; - - if (NULL == (ctrl->spi_device = (struct spi_dev *) - KMALLOC(sizeof(struct spi_dev), GFP_KERNEL))) { - gprintk("no memory available"); - return -ENOMEM; - } - ctrl->dev_type = (BDE_SPI_DEV_TYPE | BDE_SWITCH_DEV_TYPE); - ctrl->spi_device->cid = dev; - ctrl->spi_device->part = model_id; - ctrl->spi_device->rev = rev_id; - ctrl->spi_device->robo = robo; - ctrl->spi_device->phyid_high = phyidh; - ctrl->spi_device->phyid_low = phyidl; - ctrl->bde_dev.device = model_id; - ctrl->bde_dev.rev = rev_id; - ctrl->bde_dev.base_address = (sal_vaddr_t)NULL; - ctrl->isr = NULL; - ctrl->isr_data = NULL; - robo_switch++; -#if defined(KEYSTONE) - spi_freq = _spi_id_table[match_idx].spifreq; -#endif - _bde_add_device(); - } - -#if defined(KEYSTONE) - /* Override the SPI frequency from user configuration */ - if (spifreq != 0) { - spi_freq = spifreq; - } - if (spi_freq != 0) { - /* - * The underlying chip can support the SPI frequency - * higher than default (2MHz). - */ - if (spi_freq != SPI_FREQ_DEFAULT) { - chipc_spi_set_freq(robo, 0, spi_freq); - } - } -#endif - return robo_switch; - -} - -#endif #if defined(BCM_METROCORE_LOCAL_BUS) static bde_ctrl_t* @@ -3330,8 +2760,7 @@ map_local_bus(uint64_t addr, uint32_t size) { bde_ctrl_t *ctrl; - ctrl = _devices + _ndevices++; - _switch_ndevices++; + ctrl = _devices + _ndevices; /* * For now: use EB type as `local bus' @@ -3347,7 +2776,6 @@ map_local_bus(uint64_t addr, uint32_t size) ctrl->phys_address = addr; _bde_add_device(); - return(ctrl); } @@ -3355,106 +2783,6 @@ map_local_bus(uint64_t addr, uint32_t size) #endif - -#ifdef BCM_METROCORE_LOCAL_BUS - /* - * SBX platform has both PCI- and local bus-attached devices - * The local bus devices have fixed address ranges (and don't - * support or require DMA), but are otherwise the same as PCI devices - */ -#define FPGA_IRQ 37 -#define FPGA_PHYS 0x100E0000 -#define BME_PHYS 0x100C0000 -#define SE_PHYS 0x100D0000 -#define FPGA_SIZE 0x00004000 -#define BME_SIZE 0x00004000 -#define MAC0_PHYS 0x100B0000 -#define MAC1_PHYS 0x100B8000 -#define MAC_SIZE 0x800 - - -/* - * Please refer to "Supervisor Fabric Module (SFM) Specification" - * page 23 for the following registers. - */ -#define FPGA_LC_POWER_DISABLE_OFFSET 0x4 -#define FPGA_LC_POWER_DISABLE_ENABLE_ALL_MASK 0x1e - -#define FPGA_LC_POWER_RESET_OFFSET 0x5 -#define FPGA_LC_POWER_RESET_ENABLE_ALL_MASK 0x1e - -#define FPGA_SW_SFM_MASTER_MODE_OFFSET 0x14 -#define FPGA_SW_SFM_MASTER_MODE_ENABLE_MASK 0x10 - - -static int -probe_metrocore_local_bus(void) { - bde_ctrl_t *ctrl; - uint32_t dev_rev_id; - VOL uint8_t *fpga; - - /* - * Write the FPGA on the fabric card, to let metrocore - * line cards out of reset. We actually don't bother to determine whether - * the card is a line card or a fabric card because when we do - * this on the line cards, it has no effect. - */ - fpga = (uint8_t *) IOREMAP(FPGA_PHYS, FPGA_SIZE); - fpga[FPGA_SW_SFM_MASTER_MODE_OFFSET] - |= FPGA_SW_SFM_MASTER_MODE_ENABLE_MASK; - fpga[FPGA_LC_POWER_DISABLE_OFFSET] - |= FPGA_LC_POWER_DISABLE_ENABLE_ALL_MASK; - fpga[FPGA_LC_POWER_RESET_OFFSET] - |= FPGA_LC_POWER_RESET_ENABLE_ALL_MASK; - - ctrl = map_local_bus(BME_PHYS, BME_SIZE); - - dev_rev_id = - *((uint32_t *) - (((uint8_t *) ctrl->bde_dev.base_address) + BME_REVISION_OFFSET)); - ctrl->bde_dev.device = dev_rev_id >> 16; - ctrl->bde_dev.rev = (dev_rev_id & 0xFF); - - if ((ctrl->bde_dev.device != BME3200_DEVICE_ID) && - (ctrl->bde_dev.device != BCM88130_DEVICE_ID)) { - gprintk("probe_metrocore_local_bus: wrong BME type: " - "0x%x (vs 0x%x or 0x%x)\n", - ctrl->bde_dev.device, BME3200_DEVICE_ID, BCM88130_DEVICE_ID); - return -1; - } - - ctrl->iLine = FPGA_IRQ; - ctrl->isr = NULL; - ctrl->isr_data = NULL; - - /* - * - * We start from SE & include the FPGA, which is 128k - */ - ctrl = map_local_bus(SE_PHYS, 128 * 1024); - - dev_rev_id = - *((uint32_t *) - (((uint8_t *) ctrl->bde_dev.base_address) + BME_REVISION_OFFSET)); - ctrl->bde_dev.device = dev_rev_id >> 16; - ctrl->bde_dev.rev = (dev_rev_id & 0xFF); - - if ((ctrl->bde_dev.device != BME3200_DEVICE_ID) && - (ctrl->bde_dev.device != BCM88130_DEVICE_ID)) { - gprintk("probe_metrocore_local_bus: wrong SE (BME) type: " - "0x%x (vs 0x%x)\n", - ctrl->bde_dev.device, BME3200_DEVICE_ID); - return -1; - } - - ctrl->iLine = FPGA_IRQ; - ctrl->isr = NULL; - ctrl->isr_data = NULL; - - return 0; -} -#endif - #ifdef BCM_PLX9656_LOCAL_BUS #if 1 @@ -3476,8 +2804,7 @@ map_local_bus2(bde_ctrl_t *plx_ctrl, uint32_t dev_base, uint32_t size) uint8_t *addr; bde_ctrl_t *ctrl; - ctrl = _devices + _ndevices++; - _switch_ndevices++; + ctrl = _devices + _ndevices; /* * For now: use EB type as `local bus' @@ -3499,15 +2826,11 @@ map_local_bus2(bde_ctrl_t *plx_ctrl, uint32_t dev_base, uint32_t size) ctrl->bde_dev.device = dev_rev_id >> 16; ctrl->bde_dev.rev = (dev_rev_id & 0xFF); + _bde_add_device(); switch (ctrl->bde_dev.device) { - case BCM88130_DEVICE_ID: - case BME3200_DEVICE_ID: - break; default: - gprintk("wrong BME type: 0x%x (vs 0x%x or 0x%x)\n", - ctrl->bde_dev.device, BME3200_DEVICE_ID, BCM88130_DEVICE_ID); return 0; } return(ctrl); @@ -3557,143 +2880,8 @@ probe_plx_local_bus(void) #endif /* BCM_PLX9656_LOCAL_BUS */ -#if defined(BCM_EA_SUPPORT) -#if defined(BCM_TK371X_SUPPORT) -static void -probe_tk371x_dev(void) -{ - bde_ctrl_t *ctrl; - int ea_uid=0; - /* eadevices is from the argument of insmod */ - for (ea_uid = 0; ea_uid < eadevices; ea_uid++) { - ctrl = _devices + _ndevices++; - _switch_ndevices++; - ctrl->dev_type = (BDE_MII_DEV_TYPE | BDE_SWITCH_DEV_TYPE); - ctrl->bde_dev.device = TK371X_DEVICE_ID; - ctrl->bde_dev.rev = 0x0; - ctrl->bde_dev.base_address = (sal_vaddr_t)NULL; - ctrl->iLine = 0; - } -} -#endif /* BCM_TK371X_SUPPORT*/ -#endif /* BCM_EA_SUPPORT */ - - -#if defined(BCM_ROBO_SUPPORT) -#if defined(IPROC_CMICD) -struct chip_device_info { - uint32 cc_base; /* Chip-common register base */ - uint32 cc_size; /* Chip-common register limit */ - uint32 cid_reg_off; /* Chip id register offset */ -}; - -static struct chip_device_info _chip_table = { -#if defined(IPROC_CMICD) - 0x18000000, 0x00000300, 0x00000000 -#else - 0,0,0 -#endif -}; - -struct gmac_device_info { - uint32 cid; /* chip id */ - uint32 rid; /* revision id */ - uint32 pid; /* package id */ - - uint32 gmac_dev_id; /* gmac core device id */ - uint32 gmac_base_addr; /* gmac core base address */ - int gmac_irq; /* gmac irq number */ -}; - -static struct gmac_device_info _gmac_table[] = { -#if defined(IPROC_CMICD) - {BCM53010_CHIP_ID, 0, 0, BCM53010_GMAC_ID, 0x18026000, 181}, /* BCM53012 */ - {BCM53010_CHIP_ID, 0, 2, BCM53010_GMAC_ID, 0x18026000, 181}, /* BCM53011 */ - {BCM53010_CHIP_ID, 0, 1, BCM53010_GMAC_ID, 0x18026000, 181}, /* BCM53010 */ - {BCM53018_CHIP_ID, 0, 0, BCM53010_GMAC_ID, 0x18026000, 181}, /* BCM53018 */ - {BCM53018_CHIP_ID, 0, 2, BCM53010_GMAC_ID, 0x18026000, 181}, /* BCM53017 */ - {BCM53018_CHIP_ID, 0, 1, BCM53010_GMAC_ID, 0x18026000, 181}, /* BCM53019 */ - {BCM53020_CHIP_ID, 0, 0, BCM53010_GMAC_ID, 0x18024000, 181}, /* BCM53022 */ - {BCM53020_CHIP_ID, 4, 0, BCM53010_GMAC_ID, 0x18023000, 180}, /* BCM53022 */ -#endif - {0,0,0,0,0,0} -}; - -static sal_vaddr_t _cca_base = 0; - -static int -_gmac_dev_create(void) -{ - bde_ctrl_t *ctrl; - uint32 gmac_base = 0; - uint32 offset = 0; - uint32 cca_cid; - uint32 cid, rid, pid; - int i = 0, found; - if (_chip_table.cc_base == 0) { - gprintk("Create GMAC device failed. Unable to identify CPU.\n"); - return -1; - } - - /* 1. Determine which CPU/GMAC configuration is now */ - _cca_base = (sal_vaddr_t)IOREMAP(_chip_table.cc_base, _chip_table.cc_size); - cca_cid = readl((uint32 *)(_cca_base + _chip_table.cid_reg_off)); - - cid = cca_cid & CID_ID_MASK; - rid = (cca_cid & CID_REV_MASK) >> CID_REV_SHIFT; - pid = (cca_cid & CID_PKG_MASK) >> CID_PKG_SHIFT; - - found = 0; - for (i = 0; ; i++) { - if (_gmac_table[i].cid == 0) { - /* End of table */ - break; - } - if ((_gmac_table[i].cid == cid) && - (_gmac_table[i].rid == rid) && - (_gmac_table[i].pid == pid)) { - /* found */ - found = 1; - break; - } - } - if (!found) { - gprintk("Create GMAC device failed. Unable to identify GMAC device.\n"); - } - - /* 2. Create GMAC device */ - /* fill-in necessary information depends on the CPU/GMAC configuration */ - if ((cid == BCM53010_CHIP_ID) || (cid == BCM53018_CHIP_ID) || - (cid == BCM53020_CHIP_ID)) { - ctrl = _devices + _ndevices++; - _ether_ndevices++; - - ctrl->dev_type |= BDE_ETHER_DEV_TYPE; - ctrl->dev_type |= BDE_PCI_DEV_TYPE; - - ctrl->iLine = _gmac_table[i].gmac_irq; - - ctrl->be_pio = 0; - - ctrl->bde_dev.rev = _gmac_table[i].rid; - ctrl->bde_dev.device = _gmac_table[i].gmac_dev_id; - - gmac_base = 0x18000000; - offset = _gmac_table[i].gmac_base_addr - gmac_base; - ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(gmac_base, 0x300000); - ctrl->alt_base_addr = ctrl->bde_dev.base_address + offset; - ctrl->phys_address = gmac_base; - - ctrl->isr = NULL; - ctrl->isr_data = NULL; - } - - return 0; -} -#endif -#endif /* * Generic module functions @@ -3738,13 +2926,6 @@ _init(void) /* Register our goodies */ _device_driver.name = LINUX_KERNEL_BDE_NAME; -#if defined(BCM_ROBO_SUPPORT) -#if defined(IPROC_CMICD) - if (_gmac_dev_create()) { - return -ENODEV; - } -#endif -#endif /* defined (BCM_ROBO_SUPPORT) */ /* Configure MSI interrupt support */ use_msi = usemsi; @@ -3797,17 +2978,11 @@ _init(void) #endif #endif /* BCM_ICS */ -#ifdef BCM_ROBO_SUPPORT - probe_robo_switch(); -#endif -#if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) || defined(BCM_DNX_SUPPORT) || defined(BCM_DNXF_SUPPORT) +#ifdef BCM_SAND_SUPPORT sand_device_create(); #endif -#if defined(BCM_TK371X_SUPPORT) - probe_tk371x_dev(); -#endif /* * Probe for EB Bus devices. */ @@ -3863,24 +3038,6 @@ _cleanup(void) } #endif -#if defined(BCM_ROBO_SUPPORT) -#if defined(IPROC_CMICD) - if (_cca_base) { - iounmap((void *)_cca_base); - } -#endif - - if (robo) { -#if defined(KEYSTONE) || defined(IPROC_CMICD) - robo_detach(robo); -#endif /* KEYSTONE || IPROC_CMICD */ - } - if (sbh) { -#if defined(KEYSTONE) || defined(IPROC_CMICD) - ai_soc_detach(sbh); -#endif /* KEYSTONE || IPROC_CMICD */ - } -#endif for (i = 0; i < _ndevices; i++) { bde_ctrl_t *ctrl = _devices + i; @@ -3891,7 +3048,7 @@ _cleanup(void) } } } -#if (defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) || defined(BCM_DNX_SUPPORT) || defined(BCM_DNXF_SUPPORT)) && (defined(__DUNE_WRX_BCM_CPU__) || defined(__DUNE_GTO_BCM_CPU__)) +#if defined(BCM_SAND_SUPPORT) && (defined(__DUNE_WRX_BCM_CPU__) || defined(__DUNE_GTO_BCM_CPU__)) if (cpu_address) { /* unmap CPU card MMIO */ iounmap(cpu_address); cpu_address = NULL; @@ -3950,7 +3107,10 @@ _pprint(void) continue; } if (ctrl->dev_type & BDE_PCI_DEV_TYPE) { - pprintf("PCI device 0x%x:0x%x:%d:0x%.8lx:0x%.8lx:%d%s\n", + pprintf("PCI device %02x:%02x.%x 0x%x:0x%x:%d:0x%.8lx:0x%.8lx:%d%s\n", + (unsigned int)ctrl->pci_device->bus->number, + PCI_SLOT(ctrl->pci_device->devfn), + PCI_FUNC(ctrl->pci_device->devfn), ctrl->pci_device->vendor, ctrl->pci_device->device, ctrl->bde_dev.rev, @@ -3991,40 +3151,6 @@ _pprint(void) return 0; } -#if USE_LINUX_BDE_MMAP -/* - * Some kernels (mainly x86) prevent mapping of kernel RAM memory to - * user space via the /dev/mem device. The function below provides a - * backdoor to mapping the DMA pool to user space via the - * /dev/linux-kernel-bde device. - */ -static int _mmap(struct file *filp, struct vm_area_struct *vma) -{ - unsigned long phys_addr = vma->vm_pgoff << PAGE_SHIFT; - unsigned long size = vma->vm_end - vma->vm_start; - - if(!_dma_range_valid(phys_addr, size)) { - return -EINVAL; - } - -#ifdef REMAP_DMA_NONCACHED - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); -#endif - - if (remap_pfn_range(vma, - vma->vm_start, - vma->vm_pgoff, - size, - vma->vm_page_prot)) { - gprintk("Failed to mmap phys range 0x%lx-0x%lx to 0x%lx-0x%lx\n", - phys_addr, phys_addr + size, vma->vm_start,vma->vm_end); - return -EAGAIN; - } - - return 0; -} -#endif /* USE_LINUX_BDE_MMAP */ - /* Workaround for broken Busybox/PPC insmod */ static char _modname[] = LINUX_KERNEL_BDE_NAME; @@ -4034,9 +3160,7 @@ static gmodule_t _gmodule = { init: _init, cleanup: _cleanup, pprint: _pprint, -#if USE_LINUX_BDE_MMAP - mmap: _mmap, -#endif + mmap: _dma_mmap, }; gmodule_t * @@ -4336,7 +3460,7 @@ _interrupt_connect(int d, gprintk("%s(%d):device# = %d, irq = %d\n", __func__, __LINE__, d, ctrl->entries[i].vector); } - ret = request_irq(ctrl->entries[i].vector, _isr, 0, + ret = request_irq(ctrl->entries[i].vector, (irq_handler_t)_isr, 0, LINUX_KERNEL_BDE_NAME, ctrl); if (ret < 0) break; @@ -4358,7 +3482,7 @@ _interrupt_connect(int d, if (unlikely(debug >= 1)) gprintk("%s(%d):device# = %d, request_irq(%d)\n", __func__, __LINE__, d, iproc_cmicx_irqs[i]); - ret = request_irq(iproc_cmicx_irqs[i], _isr, + ret = request_irq(iproc_cmicx_irqs[i], (irq_handler_t)_isr, irq_flags, LINUX_KERNEL_BDE_NAME, ctrl); if (ret < 0) { gprintk("request_irq(%d) failed(%d)\n", iproc_cmicx_irqs[i], ret); @@ -4536,6 +3660,9 @@ _iproc_read(int d, uint32_t addr) } if (_devices[d].dev_type & BDE_AXI_DEV_TYPE) { + if (IHOST_GICD_REG_ADDR_VALID(d, addr)) { + return readl(IHOST_GICD_REG_ADDR_REMAP(d, addr)); + } return _iproc_ihost_read(d, addr); } @@ -4556,6 +3683,10 @@ _iproc_write(int d, uint32_t addr, uint32_t data) } if (_devices[d].dev_type & BDE_AXI_DEV_TYPE) { + if (IHOST_GICD_REG_ADDR_VALID(d, addr)) { + writel(data, IHOST_GICD_REG_ADDR_REMAP(d, addr)); + return 0; + } return _iproc_ihost_write(d, addr, data); } @@ -4626,126 +3757,7 @@ _get_cmic_ver(int d , uint32_t *ver) return -1; } -#ifdef BCM_ROBO_SUPPORT -#define SOC_ROBO_PAGE_BP 8 /* for Robo Chip only */ - -#if defined(IPROC_CMICD) -extern int ccb_mii_read(int dev_type, int phy_addr, int reg_off, uint16 *data); -extern int ccb_mii_write(int dev_type, int phy_addr, int reg_off, uint16 data); - -/* device type */ -#define MII_DEV_LOCAL 0 -#define MII_DEV_EXT 1 -#endif - -static int -_spi_read(int d, uint32 addr, uint8 *buf, int len) -{ -#if defined(KEYSTONE) || defined(IPROC_CMICD) - bde_ctrl_t *ctrl; - uint8 page, offset; -#endif -#if defined(IPROC_CMICD) - int rv = 0; - uint16 value = 0; -#endif - - if (!VALID_DEVICE(d)) { - return -1; - } - - if (!(_devices[d].dev_type & BDE_SPI_DEV_TYPE)) { - gprintk("_spi_read: Not SPI device %d, type %x\n", - d, _devices[d].dev_type); - return -1; - } - -#if defined(KEYSTONE) || defined(IPROC_CMICD) - ctrl = _devices + d; -#endif - -#if defined(IPROC_CMICD) - if (addr & SOC_EXTERNAL_PHY_BUS_CPUMDIO) { - rv = ccb_mii_read(MII_DEV_EXT, (addr >> 8) & 0xff, addr & 0xff, &value); - memcpy(buf, &value, 2); - return rv; - } -#endif - -#if defined(KEYSTONE) || defined(IPROC_CMICD) - page = (addr >> SOC_ROBO_PAGE_BP) & 0xFF; - offset = addr & 0xFF; -#endif - -#if defined(IPROC_CMICD) && defined(BCM_STARFIGHTER3_SUPPORT) - if (spi_device_found) { - ROBO_SPI_RREG(ctrl->spi_device->robo, ctrl->spi_device->cid, - page, offset, buf, (uint)len); - } else -#endif - { - ROBO_RREG(ctrl->spi_device->robo, ctrl->spi_device->cid, - page, offset, buf, (uint)len); - } - - return 0; -} - -static int -_spi_write(int d, uint32 addr, uint8 *buf, int len) -{ -#if defined(KEYSTONE) || defined(IPROC_CMICD) - bde_ctrl_t *ctrl; - uint8 page, offset; -#endif -#if defined(IPROC_CMICD) - int rv = 0; - uint16 value = 0; -#endif - if (!VALID_DEVICE(d)) { - return -1; - } - - if (!(_devices[d].dev_type & BDE_SPI_DEV_TYPE)) { - gprintk("_spi_write: Not SPI device %d, type %x\n", - d, _devices[d].dev_type); - return -1; - } - -#if defined(KEYSTONE) || defined(IPROC_CMICD) - ctrl = _devices + d; -#endif - -#if defined(IPROC_CMICD) - if (addr & SOC_EXTERNAL_PHY_BUS_CPUMDIO) { - memcpy(&value, buf, 2); - rv = ccb_mii_write(MII_DEV_EXT, (addr >> 8) & 0xff, addr & 0xff, value); - return rv; - } -#endif - -#if defined(KEYSTONE) || defined(IPROC_CMICD) - page = (addr >> SOC_ROBO_PAGE_BP) & 0xFF; - offset = addr & 0xFF; -#endif - -#if defined(IPROC_CMICD) && defined(BCM_STARFIGHTER3_SUPPORT) - if (spi_device_found) { - ROBO_SPI_WREG(ctrl->spi_device->robo, ctrl->spi_device->cid, - page, offset, buf, (uint)len); - } else -#endif - { - ROBO_WREG(ctrl->spi_device->robo, ctrl->spi_device->cid, - page, offset, buf, (uint)len); - } - - return 0; -} - -#endif - -#if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) || defined(BCM_DNX_SUPPORT) || defined(BCM_DNXF_SUPPORT) +#ifdef BCM_SAND_SUPPORT int lkbde_cpu_write(int d, uint32 addr, uint32 *buf) { @@ -4853,7 +3865,7 @@ lkbde_cpu_pci_register(int d) case BCM88380_DEVICE_ID: case BCM88381_DEVICE_ID: case BCM88680_DEVICE_ID: - case BCM88690_DEVICE_ID: + case BCM88800_DEVICE_ID: case BCM88470_DEVICE_ID: case BCM88470P_DEVICE_ID: case BCM88471_DEVICE_ID: @@ -4865,6 +3877,7 @@ lkbde_cpu_pci_register(int d) case BCM88270_DEVICE_ID: case BCM88272_DEVICE_ID: case BCM88273_DEVICE_ID: + case BCM88274_DEVICE_ID: case BCM88278_DEVICE_ID: case BCM8206_DEVICE_ID: case BCM88350_DEVICE_ID: @@ -4902,6 +3915,22 @@ lkbde_cpu_pci_register(int d) break; } +#ifdef BCM_DNX_SUPPORT + /*All Jericho 2 devices from 0x8690 to 0x869F*/ + if (SOC_IS_JERICHO_2_TYPE(ctrl->bde_dev.device)) { + /* Fix bar 0 address */ /* FIXME: write full phy address */ + pci_write_config_byte(ctrl->pci_device, 0x12, 0x10); + pci_write_config_byte(ctrl->pci_device, 0x13, 0x60); + + /* + * For DMA transactions - set Max_Payload_Size and + * Max_Read_Request_Size to 128 bytes. + */ + pci_write_config_byte(ctrl->pci_device, 0xb5, 0x0c); + pci_write_config_byte(ctrl->pci_device, 0xb4, 0x0); + } +#endif + /* Redo ioremap */ if (ctrl->bde_dev.base_address) { iounmap((void *)ctrl->bde_dev.base_address); @@ -4955,7 +3984,7 @@ lkbde_mem_read(int d, uint32 addr, uint32 *buf) return 0; } LKM_EXPORT_SYM(lkbde_mem_read); -#endif /* defined(BCM_PETRA_SUPPORT) */ +#endif /* BCM_SAND_SUPPORT */ static ibde_t _ibde = { name: _name, @@ -4975,13 +4004,9 @@ static ibde_t _ibde = { interrupt_disconnect: _interrupt_disconnect, l2p: _l2p, p2l: _p2l, -#if defined(BCM_ROBO_SUPPORT) - spi_read: _spi_read, - spi_write: _spi_write, -#else + NULL, NULL, -#endif /* defined(BCM_ROBO_SUPPORT) */ iproc_read: _iproc_read, iproc_write: _iproc_write, get_cmic_ver: _get_cmic_ver, @@ -5328,7 +4353,7 @@ LKM_EXPORT_SYM(lkbde_dev_state_set); LKM_EXPORT_SYM(lkbde_dev_state_get); LKM_EXPORT_SYM(lkbde_dev_instid_set); LKM_EXPORT_SYM(lkbde_dev_instid_get); -#if (defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)) +#ifdef BCM_SAND_SUPPORT LKM_EXPORT_SYM(lkbde_cpu_write); LKM_EXPORT_SYM(lkbde_cpu_read); LKM_EXPORT_SYM(lkbde_cpu_pci_register); diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c index 32b769784c2e..eb3dc0495195 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c @@ -85,10 +85,25 @@ #if _SIMPLE_MEMORY_ALLOCATION_ == 1 #define ALLOC_METHOD_DEFAULT ALLOC_TYPE_API +#if defined(__arm__) +#define USE_DMA_MMAP_COHERENT +#define _PGPROT_NONCACHED(x) x = pgprot_noncached((x)) +#elif defined(__aarch64__ ) +#define USE_DMA_MMAP_COHERENT +#define _PGPROT_NONCACHED(x) x = pgprot_writecombine((x)) +#endif #else #define ALLOC_METHOD_DEFAULT ALLOC_TYPE_CHUNK #endif +#ifndef _PGPROT_NONCACHED +#ifdef REMAP_DMA_NONCACHED +#define _PGPROT_NONCACHED(x) x = pgprot_noncached((x)) +#else +#define _PGPROT_NONCACHED(x) +#endif +#endif + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) #include #define virt_to_bus virt_to_phys @@ -101,6 +116,12 @@ #define VIRT_TO_PAGE(p) virt_to_page((p)) #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) +#define DMA_MAPPING_ERROR(d, p) dma_mapping_error((d),(p)) +#else +#define DMA_MAPPING_ERROR(d, p) dma_mapping_error((p)) +#endif + #ifndef KMALLOC_MAX_SIZE #define KMALLOC_MAX_SIZE (1UL << (MAX_ORDER - 1 + PAGE_SHIFT)) #endif @@ -170,7 +191,6 @@ MODULE_PARM_DESC(himemaddr, #else #define DMA_MEM_DEFAULT (8 * ONE_MB) #endif -#define DMA_MEM_DEFAULT_ROBO (4 * ONE_MB) /* We try to assemble a contiguous segment from chunks of this size */ #define DMA_BLOCK_SIZE (512 * ONE_KB) @@ -203,6 +223,7 @@ static unsigned long _himemaddr = 0; static int _use_dma_mapping = 0; static LIST_HEAD(_dma_seg); +#define DMA_DEV_INDEX 0 /* Device index to allocate memory pool */ #define DMA_DEV(n) lkbde_get_dma_dev(n) #define BDE_NUM_DEVICES(t) lkbde_get_num_devices(t) @@ -545,7 +566,7 @@ _pgcleanup(void) case ALLOC_TYPE_API: if (_dma_vbase) { if (dma_debug >= 1) gprintk("freeing v=%p p=0x%lx size=0x%lx\n", _dma_vbase,(unsigned long) _dma_pbase, (unsigned long)_dma_mem_size); - dma_free_coherent(DMA_DEV(0), _dma_mem_size, _dma_vbase, _dma_pbase); + dma_free_coherent(DMA_DEV(DMA_DEV_INDEX), _dma_mem_size, _dma_vbase, _dma_pbase); } break; #endif /* _SIMPLE_MEMORY_ALLOCATION_ */ @@ -554,7 +575,7 @@ _pgcleanup(void) struct list_head *pos, *tmp; int i, ndevices; if (_use_dma_mapping) { - ndevices = BDE_NUM_DEVICES(BDE_ALL_DEVICES); + ndevices = BDE_NUM_DEVICES(BDE_SWITCH_DEVICES); for (i = 0; i < ndevices && DMA_DEV(i); i ++) { dma_unmap_single(DMA_DEV(i), (dma_addr_t)_dma_pbase, _dma_mem_size, DMA_BIDIRECTIONAL); } @@ -591,7 +612,6 @@ static void _alloc_mpool(size_t size) { unsigned long pbase = 0; - #if defined(__arm__) && !defined(CONFIG_HIGHMEM) if (_use_himem) { gprintk("DMA in high memory requires CONFIG_HIGHMEM on ARM CPUs.\n"); @@ -614,6 +634,9 @@ _alloc_mpool(size_t size) _dma_vbase = IOREMAP(_dma_pbase, size); } else { /* Get DMA memory from kernel */ + if (dma_debug >= 1) { + gprintk("Allocating DMA memory using method dmaalloc=%d\n", dmaalloc); + } switch (dmaalloc) { #if _SIMPLE_MEMORY_ALLOCATION_ case ALLOC_TYPE_API: { @@ -624,8 +647,9 @@ _alloc_mpool(size_t size) /* get a memory allocation from the kernel */ { dma_addr_t dma_handle; - if (!(_dma_vbase = dma_alloc_coherent(DMA_DEV(0), alloc_size, &dma_handle, GFP_KERNEL)) || !dma_handle) { - gprintk("failed to allocate the memory pool of size 0x%lx\n", (unsigned long)alloc_size); + if (!(_dma_vbase = dma_alloc_coherent(DMA_DEV(DMA_DEV_INDEX), + alloc_size, &dma_handle, GFP_KERNEL)) || !dma_handle) { + gprintk("Failed to allocate coherent memory pool of size 0x%lx\n", (unsigned long)alloc_size); return; } _cpu_pbase = pbase = dma_handle; @@ -643,14 +667,14 @@ _alloc_mpool(size_t size) case ALLOC_TYPE_CHUNK: _dma_vbase = _pgalloc(size); if (!_dma_vbase) { - gprintk("failed to allocate the memory pool of size 0x%lx\n", (unsigned long)size); + gprintk("Failed to allocate memory pool of size 0x%lx\n", (unsigned long)size); return; } _cpu_pbase = virt_to_bus(_dma_vbase); /* Use dma_map_single to obtain DMA bus address or IOVA if iommu is present. */ - if (DMA_DEV(0)) { - pbase = dma_map_single(DMA_DEV(0), _dma_vbase, size, DMA_BIDIRECTIONAL); - if (dma_mapping_error(DMA_DEV(0), pbase)) { + if (DMA_DEV(DMA_DEV_INDEX)) { + pbase = dma_map_single(DMA_DEV(DMA_DEV_INDEX), _dma_vbase, size, DMA_BIDIRECTIONAL); + if (DMA_MAPPING_ERROR(DMA_DEV(DMA_DEV_INDEX), pbase)) { gprintk("Failed to map memory at %p\n", _dma_vbase); _pgcleanup(); _dma_vbase = NULL; @@ -659,7 +683,6 @@ _alloc_mpool(size_t size) } _use_dma_mapping = 1; } else { - /* Device has not been probed. */ pbase = _cpu_pbase; } break; @@ -719,15 +742,21 @@ _dma_cleanup(void) return 0; } -void _dma_init(int robo_switch, int dev_index) +void _dma_init(int dev_index) { unsigned long pbase; - if (dev_index > 0) { - if ((_use_dma_mapping == 1) && DMA_DEV(dev_index) && _dma_vbase) { + if (dev_index > DMA_DEV_INDEX) { + if (_use_dma_mapping && DMA_DEV(dev_index) && _dma_vbase) { pbase = dma_map_single(DMA_DEV(dev_index), _dma_vbase, _dma_mem_size, DMA_BIDIRECTIONAL); - if (dma_mapping_error(DMA_DEV(dev_index), pbase)) { + if (DMA_MAPPING_ERROR(DMA_DEV(dev_index), pbase)) { gprintk("Failed to map memory for device %d at %p\n", dev_index, _dma_vbase); + return; + } + if (pbase != (unsigned long)_dma_pbase) { + /* Bus address/IOVA must be identical for all devices. */ + gprintk("Device %d has different pbase: %lx (should be %lx)\n", + dev_index, pbase, (unsigned long)_dma_pbase); } } return; @@ -745,10 +774,6 @@ void _dma_init(int robo_switch, int dev_index) gprintk("dmasize must be a power of 2 (1M, 2M, 4M, 8M etc.)\n"); _dma_mem_size = 0; } - } else { - if(robo_switch){ - _dma_mem_size = DMA_MEM_DEFAULT_ROBO; - } } if (himem) { @@ -775,42 +800,54 @@ void _dma_init(int robo_switch, int dev_index) _alloc_mpool(_dma_mem_size); if (_dma_vbase == NULL) { gprintk("no DMA memory available\n"); - } - else { + } else { mpool_init(); _dma_pool = mpool_create(_dma_vbase, _dma_mem_size); } } } -#if USE_LINUX_BDE_MMAP /* - * Function: _dma_range_valid + * Some kernels are configured to prevent mapping of kernel RAM memory + * into user space via the /dev/mem device. * - * Purpose: - * Check if DMA address range is valid. - * Parameters: - * phys_addr - start physical address - * size - range size - * Returns: - * 0 : not valid - * 1 : valid + * The function below provides a backdoor to mapping the DMA pool to + * user space via the BDE device file. */ -int -_dma_range_valid(unsigned long phys_addr, unsigned long size) +int _dma_mmap(struct file *filp, struct vm_area_struct *vma) { - unsigned long pool_start = _cpu_pbase; - unsigned long pool_end = pool_start + _dma_mem_size; + unsigned long phys_addr = vma->vm_pgoff << PAGE_SHIFT; + unsigned long size = vma->vm_end - vma->vm_start; - if (phys_addr < pool_start || (phys_addr + size) > pool_end) { + if (phys_addr < (unsigned long )_cpu_pbase || + (phys_addr + size) > ((unsigned long )_cpu_pbase + _dma_mem_size)) { gprintk("range 0x%lx-0x%lx outside DMA pool 0x%lx-0x%lx\n", - phys_addr, phys_addr + size, pool_start, pool_end); - return 0; + phys_addr, phys_addr + size, (unsigned long )_cpu_pbase, + (unsigned long )_cpu_pbase + _dma_mem_size); + return -EINVAL; + } + +#ifdef USE_DMA_MMAP_COHERENT + if (dmaalloc == ALLOC_TYPE_API) { + vma->vm_pgoff = 0; + return dma_mmap_coherent(DMA_DEV(DMA_DEV_INDEX), vma, (void *)_dma_vbase, phys_addr, size); } - return 1; -} #endif + _PGPROT_NONCACHED(vma->vm_page_prot); + + if (remap_pfn_range(vma, + vma->vm_start, + vma->vm_pgoff, + size, + vma->vm_page_prot)) { + gprintk("Failed to mmap phys range 0x%lx-0x%lx to 0x%lx-0x%lx\n", + phys_addr, phys_addr + size, vma->vm_start,vma->vm_end); + return -EAGAIN; + } + return 0; +} + /* * Function: _dma_pool_allocated * diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/shared/mpool.c b/platform/broadcom/saibcm-modules/systems/bde/linux/shared/mpool.c index 7a377cd00787..13206596ee26 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/shared/mpool.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/shared/mpool.c @@ -70,12 +70,31 @@ static sal_sem_t _mpool_lock; #endif #endif +#define MPOOL_BUF_SIZE 1024 +#define MPOOL_BUF_ALLOC_COUNT_MAX 16 + typedef struct mpool_mem_s { unsigned char *address; int size; + struct mpool_mem_s *prev; struct mpool_mem_s *next; } mpool_mem_t; +static int _buf_alloc_count; +static mpool_mem_t *mpool_buf[MPOOL_BUF_ALLOC_COUNT_MAX]; +static mpool_mem_t *free_list; + +#define ALLOC_INIT_MPOOL_BUF(ptr) \ + ptr = MALLOC((sizeof(mpool_mem_t) * MPOOL_BUF_SIZE)); \ + if (ptr) { \ + int i; \ + for (i = 0; i < MPOOL_BUF_SIZE - 1; i++) { \ + ptr[i].next = &ptr[i+1]; \ + } \ + ptr[MPOOL_BUF_SIZE - 1].next = NULL; \ + free_list = &ptr[0]; \ + } + /* * Function: mpool_init * @@ -116,6 +135,10 @@ mpool_alloc(mpool_handle_t pool, int size) MPOOL_LOCK(); + if (size < BCM_CACHE_LINE_BYTES) { + size = BCM_CACHE_LINE_BYTES; + } + mod = size & (BCM_CACHE_LINE_BYTES - 1); if (mod != 0 ) { size += (BCM_CACHE_LINE_BYTES - mod); @@ -131,21 +154,37 @@ mpool_alloc(mpool_handle_t pool, int size) MPOOL_UNLOCK(); return NULL; } - newptr = MALLOC(sizeof(mpool_mem_t)); - if (!newptr) { - MPOOL_UNLOCK(); - return NULL; + + if (!free_list) { + if (_buf_alloc_count == MPOOL_BUF_ALLOC_COUNT_MAX) { + MPOOL_UNLOCK(); + return NULL; + } + + ALLOC_INIT_MPOOL_BUF(mpool_buf[_buf_alloc_count]); + + if (mpool_buf[_buf_alloc_count] == NULL) { + MPOOL_UNLOCK(); + return NULL; + } + + _buf_alloc_count++; } + + newptr = free_list; + free_list = free_list->next; newptr->address = ptr->address + ptr->size; newptr->size = size; newptr->next = ptr->next; + newptr->prev = ptr; + ptr->next->prev = newptr; ptr->next = newptr; #ifdef TRACK_DMA_USAGE _dma_mem_used += size; #endif - MPOOL_UNLOCK(); + MPOOL_UNLOCK(); return newptr->address; } @@ -165,25 +204,29 @@ void mpool_free(mpool_handle_t pool, void *addr) { unsigned char *address = (unsigned char *)addr; - mpool_mem_t *ptr = pool, *prev = NULL; + mpool_mem_t *head = pool, *ptr = NULL; MPOOL_LOCK(); - - while (ptr && ptr->next) { - if (ptr->next->address == address) { + + if (!(head && head->prev)) { + MPOOL_UNLOCK(); + return; + } + + ptr = head->prev->prev; + + while (ptr && (ptr != head)) { + if (ptr->address == address) { #ifdef TRACK_DMA_USAGE - _dma_mem_used -= ptr->next->size; + _dma_mem_used -= ptr->size; #endif + ptr->prev->next = ptr->next; + ptr->next->prev = ptr->prev; + ptr->next = free_list; + free_list = ptr; break; } - ptr = ptr->next; - } - - if (ptr && ptr->next) { - prev = ptr; - ptr = ptr->next; - prev->next = ptr->next; - FREE(ptr); + ptr = ptr->prev; } MPOOL_UNLOCK(); @@ -208,34 +251,45 @@ mpool_create(void *base_ptr, int size) { mpool_mem_t *head, *tail; int mod = (int)(((unsigned long)base_ptr) & (BCM_CACHE_LINE_BYTES - 1)); + int i; MPOOL_LOCK(); + for (i = 0; i < MPOOL_BUF_ALLOC_COUNT_MAX; i++) { + mpool_buf[i] = NULL; + } + + _buf_alloc_count = 0; + + ALLOC_INIT_MPOOL_BUF(mpool_buf[_buf_alloc_count]); + + if (mpool_buf[_buf_alloc_count] == NULL) { + MPOOL_UNLOCK(); + return NULL; + } + + _buf_alloc_count++; + if (mod) { base_ptr = (char*)base_ptr + (BCM_CACHE_LINE_BYTES - mod); size -= (BCM_CACHE_LINE_BYTES - mod); } size &= ~(BCM_CACHE_LINE_BYTES - 1); - - head = (mpool_mem_t *)MALLOC(sizeof(mpool_mem_t)); - if (head == NULL) { - return NULL; - } - tail = (mpool_mem_t *)MALLOC(sizeof(mpool_mem_t)); - if (tail == NULL) { - FREE(head); - return NULL; - } - + head = free_list; + free_list = free_list->next; + tail = free_list; + free_list = free_list->next; + head->size = tail->size = 0; head->address = base_ptr; tail->address = head->address + size; + head->prev = tail; head->next = tail; + tail->prev = head; tail->next = NULL; MPOOL_UNLOCK(); - return head; } @@ -252,13 +306,20 @@ mpool_create(void *base_ptr, int size) int mpool_destroy(mpool_handle_t pool) { - mpool_mem_t *ptr, *next; - + int i; + MPOOL_LOCK(); - for (ptr = pool; ptr; ptr = next) { - next = ptr->next; - FREE(ptr); + if ((mpool_mem_t *)pool != mpool_buf[0]) { + MPOOL_UNLOCK(); + return 0; + } + + for (i = 0; i < MPOOL_BUF_ALLOC_COUNT_MAX; i++) { + if (mpool_buf[i]) { + FREE(mpool_buf[i]); + mpool_buf[i] = NULL; + } } MPOOL_UNLOCK(); @@ -285,7 +346,7 @@ mpool_usage(mpool_handle_t pool) MPOOL_LOCK(); for (ptr = pool; ptr; ptr = ptr->next) { - usage += ptr->size; + usage += ptr->size; } MPOOL_UNLOCK(); diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c b/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c index 6c7c9bb95056..370f89e022c4 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c @@ -33,9 +33,6 @@ #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) #include #endif -#ifdef KEYSTONE -#include -#endif MODULE_AUTHOR("Broadcom Corporation"); @@ -676,124 +673,10 @@ _bcm88750_interrupt(bde_ctrl_t *ctrl) #endif } -static void -_qe2k_interrupt(bde_ctrl_t *ctrl) -{ - bde_inst_resource_t *res; - - res = &_bde_inst_resource[ctrl->inst]; - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x20/sizeof(uint32)); - - atomic_set(&res->intr, 1); -#ifdef BDE_LINUX_NON_INTERRUPTIBLE - wake_up(&res->intr_wq); -#else - wake_up_interruptible(&res->intr_wq); -#endif -} - -static void -_fe2k_interrupt(bde_ctrl_t *ctrl) -{ - bde_inst_resource_t *res; - - res = &_bde_inst_resource[ctrl->inst]; - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x18/sizeof(uint32)); /* PC_INTERRUPT_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x24/sizeof(uint32)); /* PC_ERROR0_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x2c/sizeof(uint32)); /* PC_ERROR1_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x34/sizeof(uint32)); /* PC_UNIT_MASK */ - - atomic_set(&res->intr, 1); -#ifdef BDE_LINUX_NON_INTERRUPTIBLE - wake_up(&res->intr_wq); -#else - wake_up_interruptible(&res->intr_wq); -#endif -} - -static void -_fe2kxt_interrupt(bde_ctrl_t *ctrl) -{ - bde_inst_resource_t *res; - - res = &_bde_inst_resource[ctrl->inst]; - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x2c/sizeof(uint32)); /* PC_INTERRUPT_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x38/sizeof(uint32)); /* PC_ERROR0_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x40/sizeof(uint32)); /* PC_ERROR1_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x50/sizeof(uint32)); /* PC_UNIT_MASK */ - - atomic_set(&res->intr, 1); -#ifdef BDE_LINUX_NON_INTERRUPTIBLE - wake_up(&res->intr_wq); -#else - wake_up_interruptible(&res->intr_wq); -#endif -} - -static void -_bme3200_interrupt(bde_ctrl_t *ctrl) -{ - bde_inst_resource_t *res; - - res = &_bde_inst_resource[ctrl->inst]; - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x54/sizeof(uint32)); /* PI_PT_ERROR0 */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x5c/sizeof(uint32)); /* PI_PT_ERROR1 */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x64/sizeof(uint32)); /* PI_PT_ERROR2 */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x6c/sizeof(uint32)); /* PI_PT_ERROR3 */ - - atomic_set(&res->intr, 1); -#ifdef BDE_LINUX_NON_INTERRUPTIBLE - wake_up(&res->intr_wq); -#else - wake_up_interruptible(&res->intr_wq); -#endif -} - - -static void -_bm9600_interrupt(bde_ctrl_t *ctrl) -{ - bde_inst_resource_t *res; - - res = &_bde_inst_resource[ctrl->inst]; - - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x5c/sizeof(uint32)); /* PI_INTERRUPT_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0xc/sizeof(uint32)); /* PI_UNIT_INTERRUPT0_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x14/sizeof(uint32)); /* PI_UNIT_INTERRUPT1_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x1c/sizeof(uint32)); /* PI_UNIT_INTERRUPT2_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x24/sizeof(uint32)); /* PI_UNIT_INTERRUPT3_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x2c/sizeof(uint32)); /* PI_UNIT_INTERRUPT4_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x34/sizeof(uint32)); /* PI_UNIT_INTERRUPT5_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x3c/sizeof(uint32)); /* PI_UNIT_INTERRUPT6_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x44/sizeof(uint32)); /* PI_UNIT_INTERRUPT7_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x4c/sizeof(uint32)); /* PI_UNIT_INTERRUPT8_MASK */ - SSOC_WRITEL(0xffffffff, ctrl->ba + 0x54/sizeof(uint32)); /* PI_UNIT_INTERRUPT9_MASK */ - - atomic_set(&res->intr, 1); -#ifdef BDE_LINUX_NON_INTERRUPTIBLE - wake_up(&res->intr_wq); -#else - wake_up_interruptible(&res->intr_wq); -#endif -} - - - /* The actual interrupt handler of ethernet devices */ static void _ether_interrupt(bde_ctrl_t *ctrl) { -#ifdef KEYSTONE - /* - * Since the two GMAC cores are sharing the same IRQ. - * Add the checking to handle the interrupt events. - */ - if ((ctrl->devid == BCM53000_GMAC_ID)) { - if ((readl(ctrl->ba + 0x020/4) & readl(ctrl->ba + 0x024/4)) == 0) { - return; - } - } -#endif SSOC_WRITEL(0, ctrl->ba + 0x024/4); atomic_set(&_ether_interrupt_has_taken_place, 1); @@ -813,11 +696,6 @@ static struct _intr_mode_s { { (isr_f)_cmicm_interrupt, "CMICm" }, { (isr_f)_cmicd_interrupt, "CMICd" }, { (isr_f)_cmicd_cmc0_interrupt, "CMICd CMC0" }, - { (isr_f)_qe2k_interrupt, "QE2K" }, - { (isr_f)_fe2k_interrupt, "FE2K" }, - { (isr_f)_fe2kxt_interrupt, "FE2KXT" }, - { (isr_f)_bme3200_interrupt, "BME3200" }, - { (isr_f)_bm9600_interrupt, "BM9600" }, { (isr_f)_bcm88750_interrupt, "BCM88750" }, { (isr_f)_cmicx_interrupt, "CMICx" }, { NULL, NULL } @@ -845,7 +723,7 @@ _devices_init(int d) uint32 ver; uint16 device_id_mask = 0xFFF0; uint16 device_id; - int state = 0; + uint32 state = 0; (void)lkbde_dev_state_get(d, &state); if (state == BDE_DEV_STATE_REMOVED) { @@ -864,21 +742,6 @@ _devices_init(int d) } if (ctrl->dev_type & BDE_SWITCH_DEV_TYPE) { switch (user_bde->get_dev(d)->device) { - case QE2000_DEVICE_ID: - ctrl->isr = (isr_f)_qe2k_interrupt; - break; - case BCM88020_DEVICE_ID: - ctrl->isr = (isr_f)_fe2k_interrupt; - break; - case BCM88025_DEVICE_ID: - ctrl->isr = (isr_f)_fe2kxt_interrupt; - break; - case BME3200_DEVICE_ID: - ctrl->isr = (isr_f)_bme3200_interrupt; - break; - case BM9600_DEVICE_ID: - ctrl->isr = (isr_f)_bm9600_interrupt; - break; case BCM88750_DEVICE_ID: case BCM88753_DEVICE_ID: case BCM88754_DEVICE_ID: @@ -920,7 +783,7 @@ _devices_init(int d) case BCM88380_DEVICE_ID: case BCM88381_DEVICE_ID: case BCM88680_DEVICE_ID: - case BCM88690_DEVICE_ID: + case BCM88800_DEVICE_ID: case BCM88770_DEVICE_ID: case BCM88773_DEVICE_ID: case BCM88774_DEVICE_ID: @@ -938,6 +801,7 @@ _devices_init(int d) case BCM88270_DEVICE_ID: case BCM88272_DEVICE_ID: case BCM88273_DEVICE_ID: + case BCM88274_DEVICE_ID: case BCM88278_DEVICE_ID: case BCM88279_DEVICE_ID: case BCM8206_DEVICE_ID: @@ -1002,7 +866,15 @@ _devices_init(int d) } break; } - /* All Ramon devices from 0x8790 to 0x879F */ + +#ifdef BCM_DNX_SUPPORT + /*All Jericho 2 devices from 0x8690 to 0x869F*/ + if (SOC_IS_JERICHO_2_TYPE(user_bde->get_dev(d)->device)) { + ctrl->isr = (isr_f)_cmicx_interrupt; + } +#endif + + /*All Ramon devices from 0x8790 to 0x879F*/ if ((user_bde->get_dev(d)->device & BCM88790_DEVICE_ID) == BCM88790_DEVICE_ID) { ctrl->isr = (isr_f)_cmicx_interrupt; } @@ -1456,30 +1328,9 @@ _ioctl(unsigned int cmd, unsigned long arg) } break; case LUBDE_USLEEP: - sal_usleep(io.d0); - break; case LUBDE_UDELAY: - sal_udelay(io.d0); - break; case LUBDE_SEM_OP: - switch (io.d0) { - case LUBDE_SEM_OP_CREATE: - io.p0 = (bde_kernel_addr_t)sal_sem_create("", io.d1, io.d2); - break; - case LUBDE_SEM_OP_DESTROY: - sal_sem_destroy((sal_sem_t)io.p0); - break; - case LUBDE_SEM_OP_TAKE: - io.rc = sal_sem_take((sal_sem_t)io.p0, io.d2); - break; - case LUBDE_SEM_OP_GIVE: - io.rc = sal_sem_give((sal_sem_t)io.p0); - break; - default: - io.rc = LUBDE_FAIL; - break; - } - break; + return -EINVAL; case LUBDE_WRITE_IRQ_MASK: io.rc = lkbde_irq_mask_set(io.dev, io.d0, io.d1, 0); break; @@ -1499,7 +1350,7 @@ _ioctl(unsigned int cmd, unsigned long arg) case LUBDE_WRITE_REG_16BIT_BUS: io.rc = user_bde->write(io.dev, io.d0, io.d1); break; -#if (defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)) +#ifdef BCM_SAND_SUPPORT case LUBDE_CPU_WRITE_REG: { if (lkbde_cpu_write(io.dev, io.d0, (uint32*)io.dx.buf) == -1) { diff --git a/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c b/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c index e1bdcc4db0da..05253141b2ff 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c +++ b/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c @@ -30,6 +30,8 @@ #define BAR0_PAXB_CONFIG_IND_ADDR 0x2120 #define BAR0_PAXB_CONFIG_IND_DATA 0x2124 +#define PAXB_0_CMICD_TO_PCIE_INTR_EN 0x2380 + #define BAR0_PAXB_IMAP0_0 (0x2c00) #define BAR0_PAXB_IMAP0_1 (0x2c04) #define BAR0_PAXB_IMAP0_2 (0x2c08) @@ -287,7 +289,8 @@ shbde_iproc_paxb_init(shbde_hal_t *shbde, void *iproc_regs, iproc32_write(shbde, reg, data | 0x1); } } - /* Configure MSIX interrupt page, only need for iproc ver == 0x10 */ + + /* Configure MSIX interrupt page, only need for iproc ver == 0x10 */ if ((icfg->use_msi == 2) && (icfg->iproc_ver == 0x10)) { unsigned int mask = (0x1 << PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT) - 1; reg = ROFFS(iproc_regs, PAXB_0_FUNC0_IMAP1_3); @@ -296,6 +299,17 @@ shbde_iproc_paxb_init(shbde_hal_t *shbde, void *iproc_regs, data |= 0x410 << PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT; iproc32_write(shbde, reg, data); } + + /* Disable INTx interrupt if MSI/MSIX is selected */ + reg = ROFFS(iproc_regs, PAXB_0_CMICD_TO_PCIE_INTR_EN); + data = iproc32_read(shbde, reg); + if (icfg->use_msi) { + data &= ~0x1; + } else { + data |= 0x1; + } + iproc32_write(shbde, reg, data); + return pci_num; } diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c index 3559ace7a898..0c91c3ecd5f7 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c @@ -67,6 +67,7 @@ #include #include +#include #include #include #include @@ -405,6 +406,59 @@ static inline struct sk_buff *skb_padto(struct sk_buff *skb, unsigned int len) pci_dma_mapping_error(d, a) #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) +enum { + SKBTX_HW_TSTAMP = 1 << 0, + SKBTX_SW_TSTAMP = 1 << 1, + SKBTX_IN_PROGRESS = 1 << 2, +}; +struct skb_shared_hwtstamps { + ktime_t hwtstamp; + ktime_t syststamp; +}; +struct bkn_skb_shared_info { + uint8_t tx_flags; + struct skb_shared_hwtstamps hwtstamps; +}; +#define bkn_skb_shinfo(_skb) ((struct bkn_skb_shared_info *)(unsigned char *)_skb->end) +#define bkn_skb_tx_flags(_skb) bkn_skb_shinfo(_skb)->tx_flags +static inline struct skb_shared_hwtstamps *skb_hwtstamps(struct sk_buff *skb) +{ + return &bkn_skb_shinfo(skb)->hwtstamps; +} +void skb_tstamp_tx(struct sk_buff *orig_skb, struct skb_shared_hwtstamps *hwtstamps) +{ +} +static inline void bkn_skb_tx_timestamp(struct sk_buff *skb) +{ +} +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) +static inline ktime_t ns_to_ktime(u64 ns) +{ + static const ktime_t ktime; + return ktime; +} +#endif +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) +#include +enum { + SKBTX_HW_TSTAMP = 1 << 0, + SKBTX_SW_TSTAMP = 1 << 1, + SKBTX_IN_PROGRESS = 1 << 2, +}; +#define bkn_skb_tx_flags(_skb) skb_shinfo(_skb)->tx_flags.flags +static inline void bkn_skb_tx_timestamp(struct sk_buff *skb) +{ +} +#else +#include +#define bkn_skb_tx_flags(_skb) skb_shinfo(_skb)->tx_flags +static inline void bkn_skb_tx_timestamp(struct sk_buff *skb) +{ + return skb_tx_timestamp(skb); +} +#endif + #ifdef LINUX_BDE_DMA_DEVICE_SUPPORT #define DMA_DEV device #define DMA_FROMDEV DMA_FROM_DEVICE @@ -471,6 +525,9 @@ typedef struct bkn_dcb_chain_s { #define NUM_CMICX_RX_CHAN 7 #define NUM_CMICM_RX_CHAN 3 +#define FCS_SZ 4 +#define TAG_SZ 4 + /* Device control info */ typedef struct bkn_switch_info_s { struct list_head list; @@ -497,6 +554,12 @@ typedef struct bkn_switch_info_s { int dcb_type; /* DCB type */ int dcb_wsize; /* DCB size (in 32-bit words) */ int pkt_hdr_size; /* Packet header size */ + uint32_t ftmh_lb_key_ext_size; /* FTMH LB-Key Extension existence/size */ + uint32_t ftmh_stacking_ext_size; /* FTMH Stacking extension existence/size */ + uint32_t pph_base_size; /* Size of PPH base */ + uint32_t pph_lif_ext_size[8]; /* Size of PPH Lif extension header */ + uint8_t udh_enable; /* Indicates UDH existence */ + uint32_t udh_length_type[4]; /* Size of UDH header per type */ int rx_chans; /* Number of Rx channels */ uint32_t dma_hi; /* DMA higher address */ uint32_t cmic_type; /* CMIC type (CMICe or CMICm) */ @@ -516,6 +579,10 @@ typedef struct bkn_switch_info_s { uint32_t inst_id; /* Instance id of this device */ int evt_idx; /* Event queue index for this device*/ int basedev_suspended; /* Base device suspended */ + int tx_hwts; /* HW timestamp for Tx */ + int rx_hwts; /* HW timestamp for Rx */ + struct sk_buff_head tx_ptp_queue; /* Tx PTP skb queue */ + struct work_struct tx_ptp_work; /* Tx PTP work */ struct { bkn_desc_info_t desc[MAX_TX_DCBS+1]; int free; /* Number of free Tx DCBs */ @@ -574,71 +641,163 @@ typedef struct bkn_switch_info_s { } rx[NUM_RX_CHAN]; } bkn_switch_info_t; -#define BKN_DNX_HDR_MAX_SIZE 40 +/* PTCH_2 */ +#define BKN_DNX_PTCH_2_SIZE 2 +/* ITMH */ +#define BKN_DNX_ITMH_SIZE 5 +/* Modlue Header */ +#define BKN_DNX_MODULE_HEADER_SIZE 20 +/* FTMH */ +#define BKN_DNX_FTMH_SRC_SYS_PORT_AGGREGATE_MSB 17 +#define BKN_DNX_FTMH_SRC_SYS_PORT_AGGREGATE_NOF_BITS 16 +#define BKN_DNX_FTMH_PP_DSP_MSB 33 +#define BKN_DNX_FTMH_PP_DSP_NOF_BITS 8 +#define BKN_DNX_FTMH_ACTION_TYPE_MSB 43 +#define BKN_DNX_FTMH_ACTION_TYPE_NOF_BITS 2 +#define BKN_DNX_FTMH_PPH_TYPE_IS_TSH_EN_MSB 73 +#define BKN_DNX_FTMH_PPH_TYPE_IS_TSH_EN_NOF_BITS 1 +#define BKN_DNX_FTMH_PPH_TYPE_IS_PPH_EN_MSB 74 +#define BKN_DNX_FTMH_PPH_TYPE_IS_PPH_EN_NOF_BITS 1 +#define BKN_DNX_FTMH_TM_DST_EXT_PRESENT_MSB 75 +#define BKN_DNX_FTMH_TM_DST_EXT_PRESENT_NOF_BITS 1 +#define BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE_MSB 76 +#define BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE_NOF_BITS 1 +#define BKN_DNX_FTMH_FLOW_ID_EXT_SIZE_MSB 77 +#define BKN_DNX_FTMH_FLOW_ID_EXT_SIZE_NOF_BITS 1 +#define BKN_DNX_FTMH_BIER_BFR_EXT_SIZE_MSB 78 +#define BKN_DNX_FTMH_BIER_BFR_EXT_SIZE_NOF_BITS 1 +/* Fix Length for FTMH and Extension headers */ +#define BKN_DNX_FTMH_BASE_SIZE 10 +#define BKN_DNX_FTMH_BIER_BFR_EXT_SIZE 2 +#define BKN_DNX_FTMH_TM_DST_EXT_SIZE 3 +#define BKN_DNX_FTMH_FLOW_ID_EXT_SIZE 3 +#define BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE 6 +/* TSH */ +#define BKN_DNX_TSH_SIZE 4 +/* PPH */ +#define BKN_DNX_PPH_BASE_TYPE_9 9 +#define BKN_DNX_PPH_BASE_TYPE_10 10 +#define BKN_DNX_PPH_BASE_TYPE_12 12 +#define BKN_DNX_PPH_9_FORWARD_DOMAIN_MSB 5 +#define BKN_DNX_PPH_9_FORWARD_DOMAIN_NOF_BITS 16 +#define BKN_DNX_PPH_9_LEARN_EXT_PRESENT_MSB 53 +#define BKN_DNX_PPH_9_LEARN_EXT_PRESENT_NOF_BITS 1 +#define BKN_DNX_PPH_9_FHEI_SIZE_MSB 54 +#define BKN_DNX_PPH_9_FHEI_SIZE_NOF_BITS 2 +#define BKN_DNX_PPH_9_LIF_EXT_TYPE_MSB 56 +#define BKN_DNX_PPH_9_LIF_EXT_TYPE_NOF_BITS 3 +#define BKN_DNX_PPH_10_FORWARD_DOMAIN_MSB 9 +#define BKN_DNX_PPH_10_FORWARD_DOMAIN_NOF_BITS 16 +#define BKN_DNX_PPH_10_LEARN_EXT_PRESENT_MSB 61 +#define BKN_DNX_PPH_10_LEARN_EXT_PRESENT_NOF_BITS 1 +#define BKN_DNX_PPH_10_FHEI_SIZE_MSB 62 +#define BKN_DNX_PPH_10_FHEI_SIZE_NOF_BITS 2 +#define BKN_DNX_PPH_10_LIF_EXT_TYPE_MSB 64 +#define BKN_DNX_PPH_10_LIF_EXT_TYPE_NOF_BITS 3 +#define BKN_DNX_PPH_12_FORWARD_DOMAIN_MSB 21 +#define BKN_DNX_PPH_12_FORWARD_DOMAIN_NOF_BITS 18 +#define BKN_DNX_PPH_12_LEARN_EXT_PRESENT_MSB 77 +#define BKN_DNX_PPH_12_LEARN_EXT_PRESENT_NOF_BITS 1 +#define BKN_DNX_PPH_12_FHEI_SIZE_MSB 78 +#define BKN_DNX_PPH_12_FHEI_SIZE_NOF_BITS 2 +#define BKN_DNX_PPH_12_LIF_EXT_TYPE_MSB 80 +#define BKN_DNX_PPH_12_LIF_EXT_TYPE_NOF_BITS 3 +/* PPH.FHEI_TYPE */ +#define BKN_DNX_PPH_FHEI_TYPE_SZ0 1 +#define BKN_DNX_PPH_FHEI_TYPE_SZ1 2 +#define BKN_DNX_PPH_FHEI_TYPE_SZ2 3 +/* FHEI */ +#define BKN_DNX_PPH_FHEI_SZ0_SIZE 3 +#define BKN_DNX_PPH_FHEI_SZ1_SIZE 5 +#define BKN_DNX_PPH_FHEI_SZ2_SIZE 8 +#define BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_MSB 0 +#define BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_NOF_BITS 27 +#define BKN_DNX_PPH_FHEI_TRAP_5B_CODE_MSB 27 +#define BKN_DNX_PPH_FHEI_TRAP_5B_CODE_NOF_BITS 9 +#define BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_MSB 36 +#define BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_NOF_BITS 4 +/* PPH Extension */ +#define BKN_DNX_PPH_LEARN_EXT_SIZE 19 +/* UDH */ +#define BKN_DNX_UDH_DATA_TYPE_0_MSB 0 +#define BKN_DNX_UDH_DATA_TYPE_0_NOF_BITS 2 +#define BKN_DNX_UDH_DATA_TYPE_1_MSB 2 +#define BKN_DNX_UDH_DATA_TYPE_1_NOF_BITS 2 +#define BKN_DNX_UDH_DATA_TYPE_2_MSB 4 +#define BKN_DNX_UDH_DATA_TYPE_2_NOF_BITS 2 +#define BKN_DNX_UDH_DATA_TYPE_3_MSB 6 +#define BKN_DNX_UDH_DATA_TYPE_3_NOF_BITS 2 +#define BKN_DNX_UDH_BASE_SIZE 1 + +#define BKN_DPP_HDR_MAX_SIZE 40 +/* PTCH_2 */ +#define BKN_DPP_PTCH_2_SIZE 2 +/* ITMH */ +#define BKN_DPP_ITMH_SIZE 4 /* FTMH */ -#define BKN_DNX_FTMH_LB_EXT_EN 0x1 -#define BKN_DNX_FTMH_STACKING_EXT_EN 0x2 -#define BKN_DNX_FTMH_SIZE_BYTE 9 -#define BKN_DNX_FTMH_LB_EXT_SIZE_BYTE 1 -#define BKN_DNX_FTMH_STACKING_SIZE_BYTE 2 -#define BKN_DNX_FTMH_DEST_EXT_SIZE_BYTE 2 -#define BKN_DNX_FTMH_LB_EXT_SIZE_BYTE 1 -#define BKN_DNX_FTMH_PKT_SIZE_MSB 0 -#define BKN_DNX_FTMH_PKT_SIZE_NOF_BITS 14 -#define BKN_DNX_FTMH_TC_MSB 14 -#define BKN_DNX_FTMH_TC_NOF_BITS 3 -#define BKN_DNX_FTMH_SRC_SYS_PORT_MSB 17 -#define BKN_DNX_FTMH_SRC_SYS_PORT_NOF_BITS 16 -#define BKN_DNX_FTMH_EXT_DSP_EXIST_MSB 68 -#define BKN_DNX_FTMH_EXT_DSP_EXIST_NOF_BITS 1 -#define BKN_DNX_FTMH_EXT_MSB 45 -#define BKN_DNX_FTMH_EXT_NOF_BITS 2 -#define BKN_DNX_FTMH_FIRST_EXT_MSB 72 -#define BKN_DNX_FTMH_ACTION_TYPE_MSB 43 -#define BKN_DNX_FTMH_ACTION_TYPE_NOF_BITS 2 -#define BKN_DNX_FTMH_PPH_TYPE_MSB 45 -#define BKN_DNX_FTMH_PPH_TYPE_NOF_BITS 2 +#define BKN_DPP_FTMH_LB_EXT_EN 0x1 +#define BKN_DPP_FTMH_STACKING_EXT_EN 0x2 +#define BKN_DPP_FTMH_SIZE_BYTE 9 +#define BKN_DPP_FTMH_LB_EXT_SIZE_BYTE 1 +#define BKN_DPP_FTMH_STACKING_SIZE_BYTE 2 +#define BKN_DPP_FTMH_DEST_EXT_SIZE_BYTE 2 +#define BKN_DPP_FTMH_LB_EXT_SIZE_BYTE 1 +#define BKN_DPP_FTMH_PKT_SIZE_MSB 0 +#define BKN_DPP_FTMH_PKT_SIZE_NOF_BITS 14 +#define BKN_DPP_FTMH_TC_MSB 14 +#define BKN_DPP_FTMH_TC_NOF_BITS 3 +#define BKN_DPP_FTMH_SRC_SYS_PORT_MSB 17 +#define BKN_DPP_FTMH_SRC_SYS_PORT_NOF_BITS 16 +#define BKN_DPP_FTMH_EXT_DSP_EXIST_MSB 68 +#define BKN_DPP_FTMH_EXT_DSP_EXIST_NOF_BITS 1 +#define BKN_DPP_FTMH_EXT_MSB 45 +#define BKN_DPP_FTMH_EXT_NOF_BITS 2 +#define BKN_DPP_FTMH_FIRST_EXT_MSB 72 +#define BKN_DPP_FTMH_ACTION_TYPE_MSB 43 +#define BKN_DPP_FTMH_ACTION_TYPE_NOF_BITS 2 +#define BKN_DPP_FTMH_PPH_TYPE_MSB 45 +#define BKN_DPP_FTMH_PPH_TYPE_NOF_BITS 2 + /* PPH */ -#define BKN_DNX_PPH_SIZE_BYTE 7 -#define BKN_DNX_PPH_EEI_EXTENSION_PRESENT_MSB 0 -#define BKN_DNX_PPH_EEI_EXTENSION_PRESENT_NOF_BITS 1 -#define BKN_DNX_PPH_LEARN_EXENSION_PRESENT_MSB 1 -#define BKN_DNX_PPH_LEARN_EXENSION_PRESENT_NOF_BITS 1 -#define BKN_DNX_PPH_FHEI_SIZE_MSB 2 -#define BKN_DNX_PPH_FHEI_SIZE_NOF_BITS 2 -#define BKN_DNX_PPH_FORWARD_CODE_MSB 4 -#define BKN_DNX_PPH_FORWARD_CODE_NOF_BITS 4 -#define BKN_DNX_PPH_VSI_MSB 22 -#define BKN_DNX_PPH_VSI_NOF_BITS 16 +#define BKN_DPP_PPH_SIZE_BYTE 7 +#define BKN_DPP_PPH_EEI_EXTENSION_PRESENT_MSB 0 +#define BKN_DPP_PPH_EEI_EXTENSION_PRESENT_NOF_BITS 1 +#define BKN_DPP_PPH_LEARN_EXENSION_PRESENT_MSB 1 +#define BKN_DPP_PPH_LEARN_EXENSION_PRESENT_NOF_BITS 1 +#define BKN_DPP_PPH_FHEI_SIZE_MSB 2 +#define BKN_DPP_PPH_FHEI_SIZE_NOF_BITS 2 +#define BKN_DPP_PPH_FORWARD_CODE_MSB 4 +#define BKN_DPP_PPH_FORWARD_CODE_NOF_BITS 4 +#define BKN_DPP_PPH_VSI_MSB 22 +#define BKN_DPP_PPH_VSI_NOF_BITS 16 /* FHEI TRAP/SNOOP 3B */ -#define BKN_DNX_PPH_FHEI_3B_SIZE_BYTE 3 -#define BKN_DNX_PPH_FHEI_5B_SIZE_BYTE 5 -#define BKN_DNX_PPH_FHEI_8B_SIZE_BYTE 8 -#define BKN_DNX_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB 0 -#define BKN_DNX_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS 16 -#define BKN_DNX_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB 16 -#define BKN_DNX_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS 8 +#define BKN_DPP_PPH_FHEI_3B_SIZE_BYTE 3 +#define BKN_DPP_PPH_FHEI_5B_SIZE_BYTE 5 +#define BKN_DPP_PPH_FHEI_8B_SIZE_BYTE 8 +#define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB 0 +#define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS 16 +#define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB 16 +#define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS 8 /* PPH extension */ -#define BKN_DNX_PPH_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE 3 -#define BKN_DNX_PPH_LEARN_EXTENSION_SIZE_BYTE 5 - +#define BKN_DPP_PPH_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE 3 +#define BKN_DPP_PPH_LEARN_EXTENSION_SIZE_BYTE 5 /* ftmh action type. */ -typedef enum bkn_dnx_ftmh_action_type_e { - BKN_DNX_FTMH_ACTION_TYPE_FORWARD = 0, /* TM action is forward */ - BKN_DNX_FTMH_ACTION_TYPE_SNOOP = 1, /* TM action is snoop */ - BKN_DNX_FTMH_ACTION_TYPE_INBOUND_MIRROR = 2, /* TM action is inbound mirror. */ - BKN_DNX_FTMH_ACTION_TYPE_OUTBOUND_MIRROR = 3 /* TM action is outbound mirror. */ -}bkn_dnx_ftmh_action_type_t; +typedef enum bkn_dpp_ftmh_action_type_e { + BKN_DPP_FTMH_ACTION_TYPE_FORWARD = 0, /* TM action is forward */ + BKN_DPP_FTMH_ACTION_TYPE_SNOOP = 1, /* TM action is snoop */ + BKN_DPP_FTMH_ACTION_TYPE_INBOUND_MIRROR = 2, /* TM action is inbound mirror. */ + BKN_DPP_FTMH_ACTION_TYPE_OUTBOUND_MIRROR = 3 /* TM action is outbound mirror. */ +}bkn_dpp_ftmh_action_type_t; /* ftmh dest extension. */ -typedef struct bkn_dnx_ftmh_dest_extension_s { +typedef struct bkn_dpp_ftmh_dest_extension_s { uint8 valid; /* Set if the extension is present */ uint32_t dst_sys_port; /* Destination System Port */ -} bkn_dnx_ftmh_dest_extension_t; +} bkn_dpp_ftmh_dest_extension_t; /* dnx packet */ -typedef struct bkn_pkt_dnx_s { +typedef struct bkn_dune_system_header_info_s { uint32_t ntwrk_header_ptr; struct { uint32_t packet_size; /* Packet size in bytes */ @@ -652,8 +811,13 @@ typedef struct bkn_pkt_dnx_s { uint32_t trap_qualifier; /* RAW Data */ uint32_t trap_id; /* RAW Data */ } internal; -} bkn_dnx_packet_info; - + uint32_t system_header_size; + uint32_t ftmh_spa; /* FTMH: Source-System-Port-Aggregate*/ + uint32_t pph_forward_domain; /* PPH: Forward-Domain*/ + uint32_t fhei_qualifier; /* FHEI: Qualifier */ + uint32_t fhei_code; /* FHEI: Code */ + uint32_t fhei_type; /* FHEI: Type */ +} bkn_dune_system_header_info_t; #define PREV_IDX(_cur, _max) (((_cur) == 0) ? (_max) - 1 : (_cur) - 1) @@ -715,6 +879,8 @@ typedef struct bkn_priv_s { uint32_t vlan; uint32_t flags; uint32_t cb_user_data; + uint8_t system_headers[27]; + uint32_t system_headers_size; } bkn_priv_t; typedef struct bkn_filter_s { @@ -755,6 +921,14 @@ LIST_HEAD(_sinfo_list); static knet_skb_cb_f knet_rx_cb = NULL; static knet_skb_cb_f knet_tx_cb = NULL; static knet_filter_cb_f knet_filter_cb = NULL; +static knet_hw_tstamp_enable_cb_f knet_hw_tstamp_enable_cb = NULL; +static knet_hw_tstamp_enable_cb_f knet_hw_tstamp_disable_cb = NULL; +static knet_hw_tstamp_tx_time_get_cb_f knet_hw_tstamp_tx_time_get_cb = NULL; +static knet_hw_tstamp_tx_meta_get_cb_f knet_hw_tstamp_tx_meta_get_cb = NULL; +static knet_hw_tstamp_ptp_clock_index_cb_f knet_hw_tstamp_ptp_clock_index_cb = NULL; +static knet_hw_tstamp_rx_time_upscale_cb_f knet_hw_tstamp_rx_time_upscale_cb = NULL; +static knet_netif_cb_f knet_netif_create_cb = NULL; +static knet_netif_cb_f knet_netif_destroy_cb = NULL; /* * Thread management @@ -955,6 +1129,8 @@ static bkn_thread_ctrl_t bkn_evt_ctrl; #define CMICX_IRQ_STATr (CMICX_CMC_BASE + 0x0000106c) #define CMICX_IRQ_STAT_CLRr (CMICX_CMC_BASE + 0x00001074) #define CMICX_IRQ_ENABr 0x18013100 +#define IHOST_GIC_GIC400_GICD_ISENABLERN_5r 0x10781114 +#define IHOST_GIC_GIC400_GICD_ICENABLERN_5r 0x10781194 /* CMICx interrupts reserved for kernel handler */ #define CMICX_TXRX_IRQ_MASK 0xffffffff @@ -992,6 +1168,7 @@ static bkn_thread_ctrl_t bkn_evt_ctrl; #define CMICX_DS_CMC_DESC_DONE(ch) (0x00000001 << ((ch) * 4)) #define CMICX_DS_CMC_CHAIN_DONE(ch) (0x00000002 << ((ch) * 4)) #define CMICX_DS_CMC_CTRLD_INT(ch) (0x00000008 << ((ch) * 4)) +#define CMICX_DS_CMC_DMA_CHAIN_DONE (0x00000001) #define CMICX_DS_CMC_DMA_ACTIVE (0x00000002) #define DMA_TO_BUS_HI(dma) ((dma) | sinfo->dma_hi) @@ -1498,12 +1675,25 @@ xgsx_dma_chan_abort(bkn_switch_info_t *sinfo, int chan, int polls) static inline void xgsx_irq_mask_set(bkn_switch_info_t *sinfo, uint32_t mask) { + uint32_t irq_mask_reg = CMICX_IRQ_ENABr; + uint32_t irq_mask, irq_fmask, disable_mask; + if (sinfo->napi_poll_mode) { mask = 0; } + if (sinfo->cpu_no == 1) { + lkbde_irq_mask_get(sinfo->dev_no, &irq_mask, &irq_fmask); + disable_mask = ~mask & (irq_mask & irq_fmask); + if (disable_mask) { + lkbde_irq_mask_set(sinfo->dev_no | LKBDE_ISR2_DEV | LKBDE_IPROC_REG, + IHOST_GIC_GIC400_GICD_ICENABLERN_5r, disable_mask, CMICX_TXRX_IRQ_MASK); + } + irq_mask_reg = IHOST_GIC_GIC400_GICD_ISENABLERN_5r; + } + lkbde_irq_mask_set(sinfo->dev_no | LKBDE_ISR2_DEV | LKBDE_IPROC_REG, - CMICX_IRQ_ENABr, mask, CMICX_TXRX_IRQ_MASK); + irq_mask_reg, mask, CMICX_TXRX_IRQ_MASK); } static inline void @@ -2094,6 +2284,7 @@ bkn_rx_refill(bkn_switch_info_t *sinfo, int chan) bkn_desc_info_t *desc; uint32_t *dcb; uint32_t resv_size = sinfo->cmic_type == 'x' ? RCPU_HDR_SIZE : RCPU_RX_ENCAP_SIZE; + uint32_t meta_size = sinfo->cmic_type == 'x' ? RCPU_RX_META_SIZE : 0; int prev; if (sinfo->rx[chan].use_rx_skb == 0) { @@ -2121,7 +2312,7 @@ bkn_rx_refill(bkn_switch_info_t *sinfo, int chan) chan, sinfo->rx[chan].cur)); } skb = desc->skb; - desc->dma_size = rx_buffer_size; + desc->dma_size = rx_buffer_size + meta_size; #ifdef KNET_NO_AXI_DMA_INVAL /* * FIXME: Need to retain this code until iProc customers have been @@ -2166,7 +2357,7 @@ bkn_rx_refill(bkn_switch_info_t *sinfo, int chan) } if (sinfo->cmic_type == 'x') { dcb[1] = DMA_TO_BUS_HI(desc->skb_dma >> 32); - dcb[2] |= rx_buffer_size; + dcb[2] |= rx_buffer_size + meta_size; } else { dcb[1] |= rx_buffer_size; } @@ -2327,6 +2518,37 @@ bkn_dma_abort(bkn_switch_info_t *sinfo) return 0; } +static int +device_is_dpp(bkn_switch_info_t *sinfo) +{ + int is_dpp = 0; + + is_dpp = (sinfo->dcb_type == 28) ? 1 : 0; + return is_dpp; +} + +static int +device_is_dnx(bkn_switch_info_t *sinfo) +{ + int is_dnx = 0; + + /* No EP_TO_CPU header for DNX(JR2) */ + is_dnx = ((sinfo->cmic_type == 'x') && (sinfo->pkt_hdr_size ==0)) ? 1 : 0; + return is_dnx; +} + +/* is DPP or is DNX*/ +static int +device_is_sand(bkn_switch_info_t *sinfo) +{ + int is_sand = 0; + + if (device_is_dpp(sinfo) || device_is_dnx(sinfo)) { + is_sand = 1; + } + return is_sand; +} + static bkn_filter_t * bkn_match_rx_pkt(bkn_switch_info_t *sinfo, uint8_t *pkt, int pktlen, void *meta, int chan, bkn_filter_t *cbf) @@ -2349,12 +2571,38 @@ bkn_match_rx_pkt(bkn_switch_info_t *sinfo, uint8_t *pkt, int pktlen, wsize = BYTES2WORDS(size); DBG_VERB(("Filter: size = %d (%d), data = 0x%08x, mask = 0x%08x\n", size, wsize, kf->data.w[0], kf->mask.w[0])); + + if (device_is_dnx(sinfo)) { + DBG_DUNE(("Filter: size = %d (wsize %d)\n", size, wsize)); + for (idx = 0; idx < wsize; idx++) + { + DBG_DUNE(("OOB[%d]: 0x%08x [0x%08x]\n", idx, kf->data.w[idx], kf->mask.w[idx])); + } + DBG_DUNE(("Meta Data [+ Selected Raw packet data]\n")); + for (idx = 0; idx < wsize; idx++) + { + DBG_DUNE(("Scratch[%d]: 0x%08x\n", idx, scratch.data.w[idx])); + } + } + match = 1; if (match) { - if (kf->priority < (num_rx_prio * sinfo->rx_chans)) { - if (kf->priority < (num_rx_prio * chan) || - kf->priority >= (num_rx_prio * (chan + 1))) { - match = 0; + if (device_is_sand(sinfo)) + { + /** priority 0 means no priority check */ + if (kf->priority && (kf->priority < (num_rx_prio * sinfo->rx_chans))) { + if (kf->priority < (num_rx_prio * chan) || + kf->priority >= (num_rx_prio * (chan + 1))) { + match = 0; + } + } + } + else { + if (kf->priority < (num_rx_prio * sinfo->rx_chans)) { + if (kf->priority < (num_rx_prio * chan) || + kf->priority >= (num_rx_prio * (chan + 1))) { + match = 0; + } } } } @@ -2422,6 +2670,43 @@ bkn_netif_lookup(bkn_switch_info_t *sinfo, int id) return NULL; } +static int +bkn_hw_tstamp_rx_set(bkn_switch_info_t *sinfo, struct sk_buff *skb, uint32 *meta) +{ + struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); + uint32_t *md = meta; + uint64_t ts = 0; + + switch (sinfo->dcb_type) { + case 26: + case 32: + case 33: + ts = md[14]; + ts = ts << 32 | md[12]; + break; + case 36: + ts = md[10]; + break; + case 38: + ts = md[4] & 0xffff; + ts = ts << 32 | md[5]; + break; + default: + return -1; + } + + if (knet_hw_tstamp_rx_time_upscale_cb) { + if (knet_hw_tstamp_rx_time_upscale_cb(sinfo->dev_no, &ts) < 0) { + return -1; + } + } + + memset(shhwtstamps, 0, sizeof(*shhwtstamps)); + shhwtstamps->hwtstamp = ns_to_ktime(be64_to_cpu(ts)); + + return 0; +} + static int bkn_add_rcpu_encap(bkn_switch_info_t *sinfo, struct sk_buff *skb, void *meta) { @@ -2491,15 +2776,6 @@ bkn_eth_type_update(struct sk_buff *skb, int ethertype) #define BKN_DNX_BYTE_SWAP(x) ((((x) << 24)) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) >> 24))) #endif -static int -device_is_dune(bkn_switch_info_t *sinfo) -{ - int is_dune = 0; - - is_dune = (sinfo->dcb_type == 28) ? 1 : 0; - return is_dune; -} - static int packet_is_untagged(uint16_t tpid) { @@ -2513,7 +2789,7 @@ packet_is_untagged(uint16_t tpid) } static void -bkn_dnx_bitstream_set_field(uint32_t *input_buffer, uint32_t start_bit, uint32_t nof_bits, uint32_t field) +bkn_bitstream_set_field(uint32_t *input_buffer, uint32_t start_bit, uint32_t nof_bits, uint32_t field) { uint32_t place; uint32_t field_bit_i; @@ -2540,7 +2816,7 @@ bkn_dnx_bitstream_set_field(uint32_t *input_buffer, uint32_t start_bit, uint32_t } static void -bkn_dnx_bitstream_get_field(uint8_t *input_buffer, uint32_t start_bit, uint32_t nof_bits, uint32_t *output_value) +bkn_bitstream_get_field(uint8_t *input_buffer, uint32_t start_bit, uint32_t nof_bits, uint32_t *output_value) { uint32_t idx; uint32_t buf_sizes=0; @@ -2590,7 +2866,7 @@ bkn_dnx_bitstream_get_field(uint8_t *input_buffer, uint32_t start_bit, uint32_t } static void -bkn_dnx_packet_parse_ftmh(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_dnx_packet_info *packet_info) +bkn_dpp_packet_parse_ftmh(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_dune_system_header_info_t *packet_info) { uint32_t header_ptr = 0; uint32_t dsp_ext_exist=0; @@ -2599,76 +2875,76 @@ bkn_dnx_packet_parse_ftmh(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_dnx_ header_ptr = packet_info->ntwrk_header_ptr; /* Packet-size */ - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_FTMH_PKT_SIZE_MSB, - BKN_DNX_FTMH_PKT_SIZE_NOF_BITS, + BKN_DPP_FTMH_PKT_SIZE_MSB, + BKN_DPP_FTMH_PKT_SIZE_NOF_BITS, &fld_val); packet_info->ftmh.packet_size = fld_val; /* Traffic-class */ - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_FTMH_TC_MSB, - BKN_DNX_FTMH_TC_NOF_BITS, + BKN_DPP_FTMH_TC_MSB, + BKN_DPP_FTMH_TC_NOF_BITS, &fld_val); packet_info->ftmh.prio = fld_val; /* Source-system-port-aggregate */ - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_FTMH_SRC_SYS_PORT_MSB, - BKN_DNX_FTMH_SRC_SYS_PORT_NOF_BITS, + BKN_DPP_FTMH_SRC_SYS_PORT_MSB, + BKN_DPP_FTMH_SRC_SYS_PORT_NOF_BITS, &fld_val); packet_info->ftmh.src_sys_port = fld_val; /* TM-action-type */ - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_FTMH_ACTION_TYPE_MSB, - BKN_DNX_FTMH_ACTION_TYPE_NOF_BITS, + BKN_DPP_FTMH_ACTION_TYPE_MSB, + BKN_DPP_FTMH_ACTION_TYPE_NOF_BITS, &fld_val); packet_info->ftmh.action_type = fld_val; /* PPH-type */ - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_FTMH_PPH_TYPE_MSB, - BKN_DNX_FTMH_PPH_TYPE_NOF_BITS, + BKN_DPP_FTMH_PPH_TYPE_MSB, + BKN_DPP_FTMH_PPH_TYPE_NOF_BITS, &fld_val); packet_info->ftmh.pph_type = fld_val; - packet_info->ntwrk_header_ptr += BKN_DNX_FTMH_SIZE_BYTE; + packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_SIZE_BYTE; DBG_DUNE(("FTMH(%d) Packet-size %d Action-type %d PPH-type %d Source-system-port 0x%x Traffic-class %d\n", packet_info->ntwrk_header_ptr, packet_info->ftmh.packet_size, packet_info->ftmh.action_type, packet_info->ftmh.pph_type, packet_info->ftmh.src_sys_port, packet_info->ftmh.prio)); /* LB-Key ext */ - if ((sinfo->pkt_hdr_size & BKN_DNX_FTMH_LB_EXT_EN) == BKN_DNX_FTMH_LB_EXT_EN) + if ((sinfo->pkt_hdr_size & BKN_DPP_FTMH_LB_EXT_EN) == BKN_DPP_FTMH_LB_EXT_EN) { - packet_info->ntwrk_header_ptr += BKN_DNX_FTMH_LB_EXT_SIZE_BYTE; + packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_LB_EXT_SIZE_BYTE; DBG_DUNE(("FTMH(%d) FTMH LB-Key Extension is present\n", packet_info->ntwrk_header_ptr)); } /* DSP ext*/ fld_val = 0; - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_FTMH_EXT_DSP_EXIST_MSB, - BKN_DNX_FTMH_EXT_DSP_EXIST_NOF_BITS, + BKN_DPP_FTMH_EXT_DSP_EXIST_MSB, + BKN_DPP_FTMH_EXT_DSP_EXIST_NOF_BITS, &dsp_ext_exist); if (dsp_ext_exist) { - packet_info->ntwrk_header_ptr += BKN_DNX_FTMH_DEST_EXT_SIZE_BYTE; + packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_DEST_EXT_SIZE_BYTE; DBG_DUNE(("FTMH(%d) DSP-extension-present 1\n", packet_info->ntwrk_header_ptr)); } /* stacking ext */ - if ((sinfo->pkt_hdr_size & BKN_DNX_FTMH_STACKING_EXT_EN) == BKN_DNX_FTMH_STACKING_EXT_EN) + if ((sinfo->pkt_hdr_size & BKN_DPP_FTMH_STACKING_EXT_EN) == BKN_DPP_FTMH_STACKING_EXT_EN) { - packet_info->ntwrk_header_ptr += BKN_DNX_FTMH_STACKING_SIZE_BYTE; + packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_STACKING_SIZE_BYTE; DBG_DUNE(("FTMH(%d) FTMH Stacking Extension is present\n", packet_info->ntwrk_header_ptr)); } return; } static void -bkn_dnx_packet_parse_internal(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_dnx_packet_info *packet_info) +bkn_dpp_packet_parse_internal(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_dune_system_header_info_t *packet_info) { uint32_t header_ptr = 0; uint32_t fld_val; @@ -2680,38 +2956,38 @@ bkn_dnx_packet_parse_internal(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_ header_ptr = packet_info->ntwrk_header_ptr; - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_PPH_EEI_EXTENSION_PRESENT_MSB, - BKN_DNX_PPH_EEI_EXTENSION_PRESENT_NOF_BITS, + BKN_DPP_PPH_EEI_EXTENSION_PRESENT_MSB, + BKN_DPP_PPH_EEI_EXTENSION_PRESENT_NOF_BITS, &eei_extension_present); - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_PPH_LEARN_EXENSION_PRESENT_MSB, - BKN_DNX_PPH_LEARN_EXENSION_PRESENT_NOF_BITS, + BKN_DPP_PPH_LEARN_EXENSION_PRESENT_MSB, + BKN_DPP_PPH_LEARN_EXENSION_PRESENT_NOF_BITS, &learn_extension_present); - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_PPH_FHEI_SIZE_MSB, - BKN_DNX_PPH_FHEI_SIZE_NOF_BITS, + BKN_DPP_PPH_FHEI_SIZE_MSB, + BKN_DPP_PPH_FHEI_SIZE_NOF_BITS, &fhei_size); - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_PPH_FORWARD_CODE_MSB, - BKN_DNX_PPH_FORWARD_CODE_NOF_BITS, + BKN_DPP_PPH_FORWARD_CODE_MSB, + BKN_DPP_PPH_FORWARD_CODE_NOF_BITS, &forward_code); /* 7: CPU-Trap */ is_trapped = (uint8_t)(forward_code == 7); - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_PPH_VSI_MSB, - BKN_DNX_PPH_VSI_NOF_BITS, + BKN_DPP_PPH_VSI_MSB, + BKN_DPP_PPH_VSI_NOF_BITS, &fld_val); packet_info->internal.vsi = fld_val; /* size of PPH base is 7 */ - packet_info->ntwrk_header_ptr += BKN_DNX_PPH_SIZE_BYTE; + packet_info->ntwrk_header_ptr += BKN_DPP_PPH_SIZE_BYTE; header_ptr = packet_info->ntwrk_header_ptr; DBG_DUNE(("PPH(%d) Forward-Code %d EEI-Extension %d Learn-Extension %d VSI %d FHEI-size %d\n", packet_info->ntwrk_header_ptr, @@ -2721,38 +2997,38 @@ bkn_dnx_packet_parse_internal(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_ if (is_trapped && (fhei_size == 1)) { /* CPU trap code qualifier */ - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB, - BKN_DNX_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS, + BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB, + BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS, &fld_val); packet_info->internal.trap_qualifier = fld_val; /* CPU trap code */ - bkn_dnx_bitstream_get_field( + bkn_bitstream_get_field( &hdr_buff[header_ptr], - BKN_DNX_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB, - BKN_DNX_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS, + BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB, + BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS, &fld_val); packet_info->internal.trap_id = fld_val; } switch(fhei_size) { case 1: - packet_info->ntwrk_header_ptr += BKN_DNX_PPH_FHEI_3B_SIZE_BYTE; + packet_info->ntwrk_header_ptr += BKN_DPP_PPH_FHEI_3B_SIZE_BYTE; break; case 2: - packet_info->ntwrk_header_ptr += BKN_DNX_PPH_FHEI_5B_SIZE_BYTE; + packet_info->ntwrk_header_ptr += BKN_DPP_PPH_FHEI_5B_SIZE_BYTE; break; case 3: - packet_info->ntwrk_header_ptr += BKN_DNX_PPH_FHEI_8B_SIZE_BYTE; + packet_info->ntwrk_header_ptr += BKN_DPP_PPH_FHEI_8B_SIZE_BYTE; break; default: break; } if (eei_extension_present) { - packet_info->ntwrk_header_ptr += BKN_DNX_PPH_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE; + packet_info->ntwrk_header_ptr += BKN_DPP_PPH_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE; } if (learn_extension_present) { - packet_info->ntwrk_header_ptr += BKN_DNX_PPH_LEARN_EXTENSION_SIZE_BYTE; + packet_info->ntwrk_header_ptr += BKN_DPP_PPH_LEARN_EXTENSION_SIZE_BYTE; } DBG_DUNE(("FHEI(%d) trap_qualifier 0x%x trap_id 0x%x\n", packet_info->ntwrk_header_ptr, packet_info->internal.trap_qualifier, packet_info->internal.trap_id)); @@ -2760,23 +3036,23 @@ bkn_dnx_packet_parse_internal(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_ } static int -bkn_dnx_packet_header_parse(bkn_switch_info_t *sinfo, uint8 *buff, uint32_t buff_len, bkn_dnx_packet_info *packet_info) +bkn_dpp_packet_header_parse(bkn_switch_info_t *sinfo, uint8 *buff, uint32_t buff_len, bkn_dune_system_header_info_t *packet_info) { - uint8_t hdr_buff[BKN_DNX_HDR_MAX_SIZE]; + uint8_t hdr_buff[BKN_DPP_HDR_MAX_SIZE]; uint32_t hdr_size; uint8_t has_internal = 0; if ((buff == NULL) || (packet_info == NULL)) { return -1; } - hdr_size = buff_len < BKN_DNX_HDR_MAX_SIZE ? buff_len: BKN_DNX_HDR_MAX_SIZE; + hdr_size = buff_len < BKN_DPP_HDR_MAX_SIZE ? buff_len: BKN_DPP_HDR_MAX_SIZE; memcpy(hdr_buff, buff, hdr_size); /* FTMH */ - bkn_dnx_packet_parse_ftmh(sinfo, hdr_buff, packet_info); + bkn_dpp_packet_parse_ftmh(sinfo, hdr_buff, packet_info); if (packet_info->ftmh.packet_size != (buff_len + 2)) { DBG_DUNE(("FTMH packet size verfication failed, %d-%d\n", packet_info->ftmh.packet_size, buff_len)); - memset(packet_info, 0, sizeof(bkn_dnx_packet_info)); + memset(packet_info, 0, sizeof(bkn_dune_system_header_info_t)); return -1; } switch (packet_info->ftmh.pph_type) { @@ -2798,7 +3074,7 @@ bkn_dnx_packet_header_parse(bkn_switch_info_t *sinfo, uint8 *buff, uint32_t buff } if (has_internal) { - bkn_dnx_packet_parse_internal(sinfo, &hdr_buff[0], packet_info); + bkn_dpp_packet_parse_internal(sinfo, &hdr_buff[0], packet_info); } /* FIXME: */ @@ -2807,6 +3083,398 @@ bkn_dnx_packet_header_parse(bkn_switch_info_t *sinfo, uint8 *buff, uint32_t buff return 0; } +static int +bkn_dnx_packet_header_parse(bkn_switch_info_t *sinfo, uint8 *buf, uint32_t buf_len, bkn_dune_system_header_info_t *packet_info) +{ + uint32_t fld_val; + uint32_t hdr_size = 0; + uint32_t pkt_offset_ingress_untrapped =0; + uint8_t tm_dst_ext_present = 0; + uint8_t app_specific_ext_size = 0; + uint8_t flow_id_ext_size = 0; + uint8_t bier_bfr_ext_size = 0; + uint8_t is_pph_en = 0; + uint8_t is_tsh_en = 0; + + if ((buf == NULL) || (packet_info == NULL)) { + return -1; + } + + /* FTMH: Source-System-Port-Aggregate */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_FTMH_SRC_SYS_PORT_AGGREGATE_MSB, + BKN_DNX_FTMH_SRC_SYS_PORT_AGGREGATE_NOF_BITS, + &fld_val); + packet_info->ftmh_spa = fld_val; + /* FTMH: PPH-Type TSH */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_FTMH_PPH_TYPE_IS_TSH_EN_MSB, + BKN_DNX_FTMH_PPH_TYPE_IS_TSH_EN_NOF_BITS, + &fld_val); + is_tsh_en = fld_val; + /* FTMH: PPH-Type PPH base */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_FTMH_PPH_TYPE_IS_PPH_EN_MSB, + BKN_DNX_FTMH_PPH_TYPE_IS_PPH_EN_NOF_BITS, + &fld_val); + is_pph_en = fld_val; + /* FTMH: TM-Destination-Extension-Present */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_FTMH_TM_DST_EXT_PRESENT_MSB, + BKN_DNX_FTMH_TM_DST_EXT_PRESENT_NOF_BITS, + &fld_val); + tm_dst_ext_present = fld_val; + /* FTMH: Application-Specific-Extension-Size */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE_MSB, + BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE_NOF_BITS, + &fld_val); + app_specific_ext_size = fld_val; + /* FTMH: Flow-ID-Extension-Size */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_FTMH_FLOW_ID_EXT_SIZE_MSB, + BKN_DNX_FTMH_FLOW_ID_EXT_SIZE_NOF_BITS, + &fld_val); + flow_id_ext_size = fld_val; + /* FTMH: BIER-BFR-Extension-Size */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_FTMH_BIER_BFR_EXT_SIZE_MSB, + BKN_DNX_FTMH_BIER_BFR_EXT_SIZE_NOF_BITS, + &fld_val); + bier_bfr_ext_size = fld_val; + + hdr_size = BKN_DNX_FTMH_BASE_SIZE; + pkt_offset_ingress_untrapped = BKN_DNX_FTMH_BASE_SIZE; + + DBG_DUNE(("FTMH(%d) source-system-port 0x%x is_tsh_en %d is_pph_en %d\n", + hdr_size, packet_info->ftmh_spa, is_tsh_en, is_pph_en)); + + /* FTMH LB-Key Extension */ + if (sinfo->ftmh_lb_key_ext_size > 0) + { + hdr_size += sinfo->ftmh_lb_key_ext_size; + DBG_DUNE(("FTMH LB-Key Extension(%d) is present\n", sinfo->ftmh_lb_key_ext_size)); + } + /* FTMH Stacking Extension */ + if (sinfo->ftmh_stacking_ext_size > 0) + { + hdr_size += sinfo->ftmh_stacking_ext_size; + DBG_DUNE(("FTMH Stacking Extension(%d) is present\n", sinfo->ftmh_stacking_ext_size)); + } + /* FTMH BIER BFR Extension */ + if (bier_bfr_ext_size > 0) + { + hdr_size += BKN_DNX_FTMH_BIER_BFR_EXT_SIZE; + DBG_DUNE(("FTMH BIER BFR Extension(2) is present\n")); + } + /* FTMH TM Destination Extension */ + if (tm_dst_ext_present > 0) + { + hdr_size += BKN_DNX_FTMH_TM_DST_EXT_SIZE; + DBG_DUNE(("FTMH TM Destination Extension(3) is present\n")); + } + /* FTMH Application Specific Extension */ + if (app_specific_ext_size > 0) + { + hdr_size += BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE; + DBG_DUNE(("FTMH Application Specific Extension(6) is present\n")); + } + /* FTMH Flow-ID Extension */ + if (flow_id_ext_size > 0) + { + hdr_size += BKN_DNX_FTMH_FLOW_ID_EXT_SIZE; + DBG_DUNE(("FTMH Flow-ID Extension(3) is present\n")); + } + + /* Given the packet is trapped to CPU */ + + /* Time-Stamp Header */ + if (is_tsh_en == TRUE) + { + hdr_size += BKN_DNX_TSH_SIZE; + DBG_DUNE(("Time-Stamp Header(4) is present\n")); + } + + /* Packet Processing Header */ + if (is_pph_en) + { + uint8_t learn_ext_present; + uint8_t fhei_size; + uint8_t lif_ext_type; + + switch (sinfo->pph_base_size) + { + case BKN_DNX_PPH_BASE_TYPE_9: + /* FTMH: Forward-Domain */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_9_FORWARD_DOMAIN_MSB, + BKN_DNX_PPH_9_FORWARD_DOMAIN_NOF_BITS, + &fld_val); + packet_info->pph_forward_domain = fld_val; + /* FTMH: Learn-Extension-Present */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_9_LEARN_EXT_PRESENT_MSB, + BKN_DNX_PPH_9_LEARN_EXT_PRESENT_NOF_BITS, + &fld_val); + learn_ext_present = fld_val; + /* FTMH: FHEI-Size */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_9_FHEI_SIZE_MSB, + BKN_DNX_PPH_9_FHEI_SIZE_NOF_BITS, + &fld_val); + fhei_size = fld_val; + /* FTMH: LIF-Extension-Type */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_9_LIF_EXT_TYPE_MSB, + BKN_DNX_PPH_9_LIF_EXT_TYPE_NOF_BITS, + &fld_val); + lif_ext_type = fld_val; + + hdr_size += BKN_DNX_PPH_BASE_TYPE_9; + DBG_DUNE(("PPH(10) FWD_DOMAIN %d, LEARN_EXT %d, FHEI_SIZE %d, LIF_EXT %d \n", + packet_info->pph_forward_domain, learn_ext_present, fhei_size, lif_ext_type)); + break; + case BKN_DNX_PPH_BASE_TYPE_10: + /* FTMH: Forward-Domain */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_10_FORWARD_DOMAIN_MSB, + BKN_DNX_PPH_10_FORWARD_DOMAIN_NOF_BITS, + &fld_val); + packet_info->pph_forward_domain = fld_val; + /* FTMH: Learn-Extension-Present */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_10_LEARN_EXT_PRESENT_MSB, + BKN_DNX_PPH_10_LEARN_EXT_PRESENT_NOF_BITS, + &fld_val); + learn_ext_present = fld_val; + /* FTMH: FHEI-Size */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_10_FHEI_SIZE_MSB, + BKN_DNX_PPH_10_FHEI_SIZE_NOF_BITS, + &fld_val); + fhei_size = fld_val; + /* FTMH: LIF-Extension-Type */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_10_LIF_EXT_TYPE_MSB, + BKN_DNX_PPH_10_LIF_EXT_TYPE_NOF_BITS, + &fld_val); + lif_ext_type = fld_val; + + hdr_size += BKN_DNX_PPH_BASE_TYPE_10; + DBG_DUNE(("PPH(10) FWD_DOMAIN %d, LEARN_EXT %d, FHEI_SIZE %d, LIF_EXT %d \n", + packet_info->pph_forward_domain, learn_ext_present, fhei_size, lif_ext_type)); + break; + case BKN_DNX_PPH_BASE_TYPE_12: + /* FTMH: Forward-Domain */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_12_FORWARD_DOMAIN_MSB, + BKN_DNX_PPH_12_FORWARD_DOMAIN_NOF_BITS, + &fld_val); + packet_info->pph_forward_domain = fld_val; + /* FTMH: Learn-Extension-Present */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_12_LEARN_EXT_PRESENT_MSB, + BKN_DNX_PPH_12_LEARN_EXT_PRESENT_NOF_BITS, + &fld_val); + learn_ext_present = fld_val; + /* FTMH: FHEI-Size */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_12_FHEI_SIZE_MSB, + BKN_DNX_PPH_12_FHEI_SIZE_NOF_BITS, + &fld_val); + fhei_size = fld_val; + /* FTMH: LIF-Extension-Type */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_12_LIF_EXT_TYPE_MSB, + BKN_DNX_PPH_12_LIF_EXT_TYPE_NOF_BITS, + &fld_val); + lif_ext_type = fld_val; + + hdr_size += BKN_DNX_PPH_BASE_TYPE_12; + DBG_DUNE(("PPH(12) FWD_DOMAIN %d, LEARN_EXT %d, FHEI_SIZE %d, LIF_EXT %d \n", + packet_info->pph_forward_domain, learn_ext_present, fhei_size, lif_ext_type)); + break; + default: + fhei_size = 0; + lif_ext_type = 0; + learn_ext_present = 0; + break; + } + if (fhei_size) + { + switch (fhei_size) + { + case BKN_DNX_PPH_FHEI_TYPE_SZ0: + hdr_size += BKN_DNX_PPH_FHEI_SZ0_SIZE; + DBG_DUNE(("FHEI(3) is present\n")); + break; + case BKN_DNX_PPH_FHEI_TYPE_SZ1: + /* FHEI: Code */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_MSB, + BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_NOF_BITS, + &fld_val); + packet_info->fhei_type = fld_val; + /* FHEI-Size == 5B, FHEI-Type == Trap/Sniff */ + if (packet_info->fhei_type == 0x5) + { + /* FHEI: Qualifier */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_MSB, + BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_NOF_BITS, + &fld_val); + packet_info->fhei_qualifier = fld_val; + /* FHEI: Code */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_FHEI_TRAP_5B_CODE_MSB, + BKN_DNX_PPH_FHEI_TRAP_5B_CODE_NOF_BITS, + &fld_val); + packet_info->fhei_code = fld_val; + } + hdr_size += BKN_DNX_PPH_FHEI_SZ1_SIZE; + DBG_DUNE(("FHEI(5) is present code 0x%x qualifier 0x%x\n", packet_info->fhei_code, packet_info->fhei_qualifier)); + break; + case BKN_DNX_PPH_FHEI_TYPE_SZ2: + hdr_size += BKN_DNX_PPH_FHEI_SZ1_SIZE; + DBG_DUNE(("FHEI(8) is present\n")); + break; + } + } + + /* PPH LIF Extension */ + if (lif_ext_type) + { + hdr_size += sinfo->pph_lif_ext_size[lif_ext_type]; + DBG_DUNE(("PPH LIF Extension(%d) is present\n", sinfo->pph_lif_ext_size[lif_ext_type])); + } + + /* PPH Learn Extension */ + if (learn_ext_present) + { + hdr_size += BKN_DNX_PPH_LEARN_EXT_SIZE; + DBG_DUNE(("PPH Learn Extension(19) is present\n")); + } + } + + /* UDH Header */ + if (sinfo->udh_enable) + { + uint8 data_type_0; + uint8 data_type_1; + uint8 data_type_2; + uint8 data_type_3; + + DBG_DUNE(("UDH base(1) is present\n")); + + /* UDH: UDH-Data-Type[0] */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_UDH_DATA_TYPE_0_MSB, + BKN_DNX_UDH_DATA_TYPE_0_NOF_BITS, + &fld_val); + data_type_0 = fld_val; + hdr_size += sinfo->udh_length_type[data_type_0]; + /* UDH: UDH-Data-Type[1] */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_UDH_DATA_TYPE_1_MSB, + BKN_DNX_UDH_DATA_TYPE_1_NOF_BITS, + &fld_val); + data_type_1 = fld_val; + hdr_size += sinfo->udh_length_type[data_type_1]; + /* UDH: UDH-Data-Type[2] */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_UDH_DATA_TYPE_2_MSB, + BKN_DNX_UDH_DATA_TYPE_2_NOF_BITS, + &fld_val); + data_type_2 = fld_val; + hdr_size += sinfo->udh_length_type[data_type_2]; + /* UDH: UDH-Data-Type[3] */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_UDH_DATA_TYPE_3_MSB, + BKN_DNX_UDH_DATA_TYPE_3_NOF_BITS, + &fld_val); + data_type_3 = fld_val; + hdr_size += sinfo->udh_length_type[data_type_3]; + hdr_size += BKN_DNX_UDH_BASE_SIZE; + } + + /* + * Check if fhei_type if of type trap + * There is a RISK that raw packet data is parsed and fhei_type is 0x5 by chance + */ + if (packet_info->fhei_type == 0x5) + { + /* Done for ingress trapped packets */ + packet_info->system_header_size = hdr_size; + DBG_DUNE(("Total Size of Headers is %d\n", packet_info->system_header_size)); + return 0; + } + else + { + /* New generated header will be FTMH(80b), TSH(32b), PPH(96b), FHEI(40b) */ + + /* Revert packet_info except info from FTHM base header */ + packet_info->fhei_qualifier = 0; + packet_info->fhei_code = 0; + packet_info->fhei_type = 0; + hdr_size = pkt_offset_ingress_untrapped; + + /* Time-Stamp Header */ + hdr_size += BKN_DNX_TSH_SIZE; + DBG_DUNE(("Time-Stamp Header(4) is present\n")); + + /** Packet Processing Header */ + bkn_bitstream_get_field( + &buf[hdr_size], + BKN_DNX_PPH_12_FORWARD_DOMAIN_MSB, + BKN_DNX_PPH_12_FORWARD_DOMAIN_NOF_BITS, + &fld_val); + packet_info->pph_forward_domain = fld_val; + hdr_size += BKN_DNX_PPH_BASE_TYPE_12; + DBG_DUNE(("PPH(12) is present\n")); + + /* + * FHEI(Trap,40) + * 5B-FHEI format for sys_hdr_generation_profile:J2-OAM + * 8b' 0 + * 19b'oam_id + * 9b' cpu_trap_code: INGRESS_TRAP_ID is always 0 here + * 4b' type(0x5): J2-Configuration FHEI Type for CPU trap + */ + hdr_size += BKN_DNX_PPH_FHEI_SZ1_SIZE; + DBG_DUNE(("FHEI(5) is present\n")); + } + packet_info->system_header_size = hdr_size; + DBG_DUNE(("Total Size of Headers is %d\n", packet_info->system_header_size)); + return 0; +} + + static int bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) { @@ -2824,7 +3492,8 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) int pktlen; int idx; int dcbs_done = 0; - bkn_dnx_packet_info packet_info = {0}; + bkn_dune_system_header_info_t packet_info = {0}; + uint32_t dnx_meta_data[3] = {0}; dcb_chain = sinfo->rx[chan].api_dcb_chain; if (dcb_chain == NULL) { @@ -2868,9 +3537,16 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) } pkt = (uint8_t *)kernel_bde->p2l(sinfo->dev_no, (sal_paddr_t)pkt_dma); if (sinfo->cmic_type == 'x') { - meta = (uint32_t *)pkt; - err_woff = sinfo->pkt_hdr_size / sizeof(uint32_t) - 1; - meta[err_woff] = dcb[sinfo->dcb_wsize-1]; + if (device_is_dnx(sinfo)){ + meta = &dnx_meta_data[0]; + /* get error bit from last DCB words */ + err_woff = 2; + meta[err_woff] = dcb[sinfo->dcb_wsize-1]; + } else { + meta = (uint32_t *)pkt; + err_woff = sinfo->pkt_hdr_size / sizeof(uint32_t) - 1; + meta[err_woff] = dcb[sinfo->dcb_wsize-1]; + } } else { meta = dcb; err_woff = sinfo->dcb_wsize - 1; @@ -2878,22 +3554,22 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) pktlen = dcb[sinfo->dcb_wsize-1] & SOC_DCB_KNET_COUNT_MASK; bkn_dump_pkt(pkt, pktlen, XGS_DMA_RX_CHAN); - if (device_is_dune(sinfo)) { + if (device_is_dpp(sinfo)) { uint16_t tpid = 0; uint16_t vid = 0; int res = -1; - memset(&packet_info, 0, sizeof(bkn_dnx_packet_info)); - res = bkn_dnx_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); + memset(&packet_info, 0, sizeof(bkn_dune_system_header_info_t)); + res = bkn_dpp_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); if (res == 0) { if (packet_info.ftmh.action_type == 0x2) { - bkn_dnx_bitstream_set_field((uint32_t *)dcb, 192, 32, 0x8); + bkn_bitstream_set_field((uint32_t *)dcb, 192, 32, 0x8); } else if (packet_info.ftmh.action_type == 0x1) { - bkn_dnx_bitstream_set_field((uint32_t *)dcb, 231, 25, 0x20); + bkn_bitstream_set_field((uint32_t *)dcb, 231, 25, 0x20); } - bkn_dnx_bitstream_set_field((uint32_t *)dcb, 112, 16, packet_info.ftmh.src_sys_port); - bkn_dnx_bitstream_set_field((uint32_t *)dcb, 296, 12, packet_info.internal.vsi); - bkn_dnx_bitstream_set_field((uint32_t *)dcb, 64, 32, (packet_info.internal.trap_id << 16 | packet_info.internal.trap_qualifier)); + bkn_bitstream_set_field((uint32_t *)dcb, 112, 16, packet_info.ftmh.src_sys_port); + bkn_bitstream_set_field((uint32_t *)dcb, 296, 12, packet_info.internal.vsi); + bkn_bitstream_set_field((uint32_t *)dcb, 64, 32, (packet_info.internal.trap_id << 16 | packet_info.internal.trap_qualifier)); pkt += packet_info.ntwrk_header_ptr; pktlen -= packet_info.ntwrk_header_ptr; bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); @@ -2919,10 +3595,25 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) } } } + else if (device_is_dnx(sinfo)) { + int res = -1; + res = bkn_dnx_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); + if (res == 0) { + bkn_bitstream_set_field(meta, 0, 16, packet_info.fhei_code); + bkn_bitstream_set_field(meta, 16, 16, packet_info.fhei_qualifier); + bkn_bitstream_set_field(meta, 32, 16, packet_info.ftmh_spa); + bkn_bitstream_set_field(meta, 48, 16, (packet_info.pph_forward_domain & 0xffff)); - if (device_is_dune(sinfo)) { - filter = bkn_match_rx_pkt(sinfo, pkt, pktlen + packet_info.ntwrk_header_ptr, - dcb, chan, &cbf); + pkt += packet_info.system_header_size; + pktlen -= packet_info.system_header_size; + bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); + } + } + + if (device_is_dpp(sinfo)) { + filter = bkn_match_rx_pkt(sinfo, pkt, pktlen, dcb, chan, &cbf); + } else if (device_is_dnx(sinfo)) { + filter = bkn_match_rx_pkt(sinfo, pkt, pktlen, meta, chan, &cbf); } else { filter = bkn_match_rx_pkt(sinfo, pkt + sinfo->pkt_hdr_size, pktlen - sinfo->pkt_hdr_size, meta, chan, &cbf); @@ -3001,7 +3692,7 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) } skb_copy_to_linear_data(skb, pkt, pktlen); - if (device_is_dune(sinfo)) { + if (device_is_sand(sinfo)) { /* CRC has been stripped */ skb_put(skb, pktlen); } else { @@ -3023,6 +3714,11 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) } } + /* Do Rx timestamping */ + if (sinfo->rx_hwts) { + bkn_hw_tstamp_rx_set(sinfo, skb, meta); + } + if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { bkn_add_rcpu_encap(sinfo, skb, meta); DBG_PDMP(("After add RCPU ENCAP\n")); @@ -3095,7 +3791,8 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) int pktlen; int idx; int dcbs_done = 0; - bkn_dnx_packet_info packet_info = {0}; + bkn_dune_system_header_info_t packet_info = {0}; + uint32_t dnx_meta_data[3] = {0}; if (!sinfo->rx[chan].running) { /* Rx not ready */ @@ -3122,9 +3819,16 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) sinfo->rx[chan].pkts++; skb = desc->skb; if (sinfo->cmic_type == 'x') { - meta = (uint32_t *)skb->data; - err_woff = sinfo->pkt_hdr_size / sizeof(uint32_t) - 1; - meta[err_woff] = dcb[sinfo->dcb_wsize-1]; + if (device_is_dnx(sinfo)){ + meta = &dnx_meta_data[0]; + /* get error bit from last DCB words */ + err_woff = 2; + meta[err_woff] = dcb[sinfo->dcb_wsize-1]; + } else { + meta = (uint32_t *)skb->data; + err_woff = sinfo->pkt_hdr_size / sizeof(uint32_t) - 1; + meta[err_woff] = dcb[sinfo->dcb_wsize-1]; + } } else { meta = dcb; err_woff = sinfo->dcb_wsize - 1; @@ -3138,23 +3842,23 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) desc->skb_dma = 0; bkn_dump_pkt(skb->data, pktlen, XGS_DMA_RX_CHAN); - if (device_is_dune(sinfo)) { + if (device_is_dpp(sinfo)) { uint16_t tpid = 0; uint16_t vid = 0; uint8_t *pkt = skb->data; int res = 0; - memset(&packet_info, 0, sizeof(bkn_dnx_packet_info)); - res = bkn_dnx_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); + memset(&packet_info, 0, sizeof(bkn_dune_system_header_info_t)); + res = bkn_dpp_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); if (res == 0) { if (packet_info.ftmh.action_type == 0x2) { - bkn_dnx_bitstream_set_field((uint32_t *)dcb, 192, 32, 0x8); + bkn_bitstream_set_field((uint32_t *)dcb, 192, 32, 0x8); } else if (packet_info.ftmh.action_type == 0x1) { - bkn_dnx_bitstream_set_field((uint32_t *)dcb, 231, 25, 0x20); + bkn_bitstream_set_field((uint32_t *)dcb, 231, 25, 0x20); } - bkn_dnx_bitstream_set_field((uint32_t *)dcb, 112, 16, packet_info.ftmh.src_sys_port); - bkn_dnx_bitstream_set_field((uint32_t *)dcb, 296, 12, packet_info.internal.vsi); - bkn_dnx_bitstream_set_field((uint32_t *)dcb, 64, 32, (packet_info.internal.trap_id << 16 | packet_info.internal.trap_qualifier)); + bkn_bitstream_set_field((uint32_t *)dcb, 112, 16, packet_info.ftmh.src_sys_port); + bkn_bitstream_set_field((uint32_t *)dcb, 296, 12, packet_info.internal.vsi); + bkn_bitstream_set_field((uint32_t *)dcb, 64, 32, (packet_info.internal.trap_id << 16 | packet_info.internal.trap_qualifier)); pkt = skb->data + packet_info.ntwrk_header_ptr; /* check if vlan tag exists */ tpid = (uint16_t)((pkt[12] << 8) | pkt[13]); @@ -3178,10 +3882,29 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) } } } + else if (device_is_dnx(sinfo)) { + uint8_t *pkt = skb->data; + int res = -1; + + res = bkn_dnx_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); + if (res == 0) { + bkn_bitstream_set_field(meta, 0, 16, packet_info.fhei_code); + bkn_bitstream_set_field(meta, 16, 16, packet_info.fhei_qualifier); + bkn_bitstream_set_field(meta, 32, 16, packet_info.ftmh_spa); + bkn_bitstream_set_field(meta, 48, 16, (packet_info.pph_forward_domain & 0xffff)); - if (device_is_dune(sinfo)) { - filter = bkn_match_rx_pkt(sinfo, skb->data + packet_info.ntwrk_header_ptr, + pkt += packet_info.system_header_size; + pktlen -= packet_info.ntwrk_header_ptr; + bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); + } + } + + if (device_is_dpp(sinfo)) { + filter = bkn_match_rx_pkt(sinfo, skb->data + packet_info.ntwrk_header_ptr, pktlen, dcb, chan, &cbf); + } else if (device_is_dnx(sinfo)) { + filter = bkn_match_rx_pkt(sinfo, skb->data + packet_info.system_header_size, + pktlen, meta, chan, &cbf); } else { filter = bkn_match_rx_pkt(sinfo, skb->data + sinfo->pkt_hdr_size, pktlen - sinfo->pkt_hdr_size, meta, chan, &cbf); @@ -3216,12 +3939,12 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) sinfo->rx[chan].pkts_f_netif++; if (((filter->kf.mirror_type == KCOM_DEST_T_API) && - (!device_is_dune(sinfo))) || dbg_pkt_enable) { + (!device_is_sand(sinfo))) || dbg_pkt_enable) { sinfo->rx[chan].pkts_m_api++; bkn_api_rx_copy_from_skb(sinfo, chan, desc); } - if (device_is_dune(sinfo)) { + if (device_is_dpp(sinfo)) { if (filter->kf.mirror_type == KCOM_DEST_T_API) { sinfo->rx[chan].pkts_m_api++; bkn_api_rx_copy_from_skb(sinfo, chan, desc); @@ -3232,11 +3955,22 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) bkn_dump_pkt(skb->data, 32, XGS_DMA_RX_CHAN); /* CRC has been stripped on Dune*/ skb_put(skb, pktlen); + } else if (device_is_dnx(sinfo)) { + if (filter->kf.mirror_type == KCOM_DEST_T_API) { + sinfo->rx[chan].pkts_m_api++; + bkn_api_rx_copy_from_skb(sinfo, chan, desc); + } + /* Strip Dune headers */ + skb->data += packet_info.system_header_size; + pktlen -= packet_info.system_header_size; + bkn_dump_pkt(skb->data, 32, XGS_DMA_RX_CHAN); + /* CRC has been stripped on Dune*/ + skb_put(skb, pktlen); } else { skb_put(skb, pktlen - 4); /* Strip CRC */ } - if (sinfo->cmic_type == 'x') { + if (sinfo->cmic_type == 'x' && !device_is_dnx(sinfo)) { skb_pull(skb, sinfo->pkt_hdr_size); } @@ -3252,7 +3986,7 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) ((u32*)skb->data)[2] = ((u32*)skb->data)[1]; ((u32*)skb->data)[1] = ((u32*)skb->data)[0]; skb_pull(skb, 4); - if (sinfo->cmic_type == 'x') { + if (sinfo->cmic_type == 'x' && !device_is_dnx(sinfo)) { for (idx = sinfo->pkt_hdr_size / sizeof(uint32_t); idx; idx--) { meta[idx] = meta[idx - 1]; } @@ -3292,6 +4026,11 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) } } + /* Do Rx timestamping */ + if (sinfo->rx_hwts) { + bkn_hw_tstamp_rx_set(sinfo, skb, meta); + } + if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { bkn_add_rcpu_encap(sinfo, skb, meta); DBG_PDMP(("After add RCPU ENCAP\n")); @@ -3489,6 +4228,45 @@ bkn_resume_tx(bkn_switch_info_t *sinfo) } } +static int +bkn_hw_tstamp_tx_set(bkn_switch_info_t *sinfo, struct sk_buff *skb) +{ + struct skb_shared_hwtstamps shhwtstamps; + uint64_t ts = 0; + uint32_t hdrlen = sinfo->cmic_type == 'x' ? PKT_TX_HDR_SIZE : 0; + int port; + + if (!knet_hw_tstamp_tx_time_get_cb) { + return -1; + } + + port = KNET_SKB_CB(skb)->port; + if (knet_hw_tstamp_tx_time_get_cb(sinfo->dev_no, port, skb->data + hdrlen, &ts) < 0) { + return -1; + } + + memset(&shhwtstamps, 0, sizeof(shhwtstamps)); + shhwtstamps.hwtstamp = ns_to_ktime(be64_to_cpu(ts)); + skb_tstamp_tx(skb, &shhwtstamps); + + return 0; +} + +static void +bkn_hw_tstamp_tx_work(struct work_struct *work) +{ + bkn_switch_info_t *sinfo = container_of(work, bkn_switch_info_t, tx_ptp_work); + struct sk_buff *skb; + + while (skb_queue_len(&sinfo->tx_ptp_queue)) { + skb = skb_dequeue(&sinfo->tx_ptp_queue); + if (bkn_hw_tstamp_tx_set(sinfo, skb) < 0) { + gprintk("Timestamp has not been taken for the current skb.\n"); + } + dev_kfree_skb_any(skb); + } +} + static int bkn_do_tx(bkn_switch_info_t *sinfo) { @@ -3515,7 +4293,12 @@ bkn_do_tx(bkn_switch_info_t *sinfo) DMA_UNMAP_SINGLE(sinfo->dma_dev, desc->skb_dma, desc->dma_size, DMA_TODEV); - dev_kfree_skb_any(desc->skb); + if (bkn_skb_tx_flags(desc->skb) & SKBTX_IN_PROGRESS) { + skb_queue_tail(&sinfo->tx_ptp_queue, desc->skb); + schedule_work(&sinfo->tx_ptp_work); + } else { + dev_kfree_skb_any(desc->skb); + } desc->skb = NULL; desc->skb_dma = 0; } @@ -3926,10 +4709,16 @@ xgsx_do_dma(bkn_switch_info_t *sinfo, int budget) { int rx_dcbs_done = 0, tx_dcbs_done = 0; int chan_done, budget_chans = 0; - uint32_t irq_stat; + uint32_t irq_stat, tx_dma_stat, rx_dma_stat[NUM_CMICX_RX_CHAN]; int chan; DEV_READ32(sinfo, CMICX_IRQ_STATr, &irq_stat); + DEV_READ32(sinfo, CMICX_DMA_STATr + 0x80 * XGS_DMA_TX_CHAN, &tx_dma_stat); + for (chan = 0; chan < sinfo->rx_chans; chan++) { + DEV_READ32(sinfo, + CMICX_DMA_STATr + 0x80 * (XGS_DMA_RX_CHAN + chan), + &rx_dma_stat[chan]); + } for (chan = 0; chan < sinfo->rx_chans; chan++) { if ((irq_stat & CMICX_DS_CMC_CTRLD_INT(XGS_DMA_RX_CHAN + chan)) || @@ -3964,14 +4753,14 @@ xgsx_do_dma(bkn_switch_info_t *sinfo, int budget) continue; } - if (irq_stat & CMICX_DS_CMC_CHAIN_DONE(XGS_DMA_RX_CHAN + chan)) { + if (rx_dma_stat[chan] & CMICX_DS_CMC_DMA_CHAIN_DONE) { xgsx_dma_chain_clear(sinfo, XGS_DMA_RX_CHAN + chan); bkn_rx_chain_done(sinfo, chan); } } if ((irq_stat & CMICX_DS_CMC_CTRLD_INT(XGS_DMA_TX_CHAN)) || - (irq_stat & CMICX_DS_CMC_CHAIN_DONE(XGS_DMA_TX_CHAN))) { + (tx_dma_stat & CMICX_DS_CMC_DMA_CHAIN_DONE)) { if (CDMA_CH(sinfo, XGS_DMA_TX_CHAN)) { xgsx_dma_desc_clear(sinfo, XGS_DMA_TX_CHAN); } else { @@ -4229,6 +5018,70 @@ bkn_set_mac_address(struct net_device *dev, void *addr) } #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) +static int +bkn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + bkn_priv_t *priv = netdev_priv(dev); + bkn_switch_info_t *sinfo = priv->sinfo; + struct hwtstamp_config config; + + if (cmd == SIOCSHWTSTAMP) { + if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) { + return -EFAULT; + } + + if (!knet_hw_tstamp_enable_cb || !knet_hw_tstamp_disable_cb || + priv->type != KCOM_NETIF_T_PORT) { + return -ERANGE; + } + + switch (config.tx_type) { + case HWTSTAMP_TX_OFF: + knet_hw_tstamp_disable_cb(sinfo->dev_no, priv->port); + sinfo->tx_hwts = 0; + break; + case HWTSTAMP_TX_ON: + knet_hw_tstamp_enable_cb(sinfo->dev_no, priv->port); + sinfo->tx_hwts = 1; + break; + default: + return -ERANGE; + } + + switch (config.rx_filter) { + case HWTSTAMP_FILTER_NONE: + if (sinfo->rx_hwts) { + knet_hw_tstamp_disable_cb(sinfo->dev_no, priv->port); + sinfo->rx_hwts = 0; + } + break; + default: + if (!sinfo->rx_hwts) { + knet_hw_tstamp_enable_cb(sinfo->dev_no, priv->port); + sinfo->rx_hwts = 1; + } + config.rx_filter = HWTSTAMP_FILTER_ALL; + break; + } + + return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? -EFAULT : 0; + } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + if (cmd == SIOCGHWTSTAMP) { + config.flags = 0; + config.tx_type = sinfo->tx_hwts ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; + config.rx_filter = sinfo->rx_hwts ? HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE; + + return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? -EFAULT : 0; + } +#endif + + return -EINVAL; +} +#endif + static int bkn_change_mtu(struct net_device *dev, int new_mtu) { @@ -4354,6 +5207,44 @@ bkn_set_multicast_list(struct net_device *dev) { } +static int +bkn_hw_tstamp_tx_config(bkn_switch_info_t *sinfo, struct sk_buff *skb, uint32_t *meta) +{ + uint32_t *md = NULL; + + if (!knet_hw_tstamp_tx_meta_get_cb) { + return -1; + } + + KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; + knet_hw_tstamp_tx_meta_get_cb(sinfo->dev_no, skb, &md); + if (!md) { + return -1; + } + + switch (sinfo->dcb_type) { + case 26: + case 32: + case 33: + meta[2] |= md[0]; + meta[3] |= md[1]; + meta[4] |= md[2]; + meta[5] |= md[3]; + break; + case 36: + case 38: + meta[0] |= md[0]; + meta[1] |= md[1]; + meta[2] |= md[2]; + meta[3] |= md[3]; + break; + default: + return -1; + } + + return 0; +} + static int bkn_tx(struct sk_buff *skb, struct net_device *dev) { @@ -4391,8 +5282,8 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) uint32_t *dcb, *meta; pktdata = skb->data; - pktlen = skb->len + 4; - hdrlen = sinfo->cmic_type == 'x' ? PKT_TX_HDR_SIZE : 0; + pktlen = skb->len; + hdrlen = (sinfo->cmic_type == 'x' ) ? ((device_is_dnx(sinfo)) ? priv->system_headers_size: PKT_TX_HDR_SIZE) : 0; rcpulen = 0; sop = 0; @@ -4447,7 +5338,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) if (skb_header_cloned(skb)) { /* Current SKB cannot be modified */ DBG_SKB(("Realloc Tx SKB\n")); - new_skb = dev_alloc_skb(pktlen + 4); + new_skb = dev_alloc_skb(pktlen + TAG_SZ + FCS_SZ); if (new_skb == NULL) { DBG_WARN(("Tx drop: No SKB memory\n")); priv->stats.tx_dropped++; @@ -4458,7 +5349,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) } memcpy(new_skb->data, pktdata, 12); memcpy(&new_skb->data[16], &pktdata[12], pktlen - 12); - skb_put(new_skb, pktlen + 4); + skb_put(new_skb, pktlen + TAG_SZ); dev_kfree_skb_any(skb); skb = new_skb; pktdata = skb->data; @@ -4466,26 +5357,25 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) } else { /* Add tag to RCPU header space */ DBG_SKB(("Expand into unused RCPU header\n")); - rcpulen -= 4; + rcpulen -= TAG_SZ; pktdata = &skb->data[rcpulen]; for (idx = 0; idx < 12; idx++) { - pktdata[idx] = pktdata[idx + 4]; + pktdata[idx] = pktdata[idx + TAG_SZ]; } } pktdata[12] = 0x81; pktdata[13] = 0x00; pktdata[14] = (priv->vlan >> 8) & 0xf; pktdata[15] = priv->vlan & 0xff; - pktlen += 4; + pktlen += TAG_SZ; } } } else { if (sinfo->cmic_type == 'x' && priv->port >= 0) { - if (skb_header_cloned(skb) || skb_headroom(skb) < hdrlen + 4 || - (sinfo->dcb_type == 36 && (unsigned long)skb->data % 4)) { + if (skb_header_cloned(skb) || skb_headroom(skb) < hdrlen + 4) { /* Current SKB cannot be modified */ DBG_SKB(("Realloc Tx SKB\n")); - new_skb = dev_alloc_skb(pktlen + hdrlen + 4); + new_skb = dev_alloc_skb(pktlen + hdrlen + 4 + FCS_SZ); if (new_skb == NULL) { DBG_WARN(("Tx drop: No SKB memory\n")); priv->stats.tx_dropped++; @@ -4494,7 +5384,10 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&sinfo->lock, flags); return 0; } - skb_reserve(new_skb, 4); + if (!device_is_dnx(sinfo)) + { + skb_reserve(new_skb, 4); + } memcpy(new_skb->data + hdrlen, skb->data, pktlen); skb_put(new_skb, pktlen + hdrlen); dev_kfree_skb_any(skb); @@ -4511,13 +5404,14 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) } if (priv->port < 0 || (priv->flags & KCOM_NETIF_F_ADD_TAG)) { + DBG_DUNE(("ADD VLAN TAG\n")); /* Need to add VLAN tag if packet is untagged */ tpid = (skb->data[hdrlen + 12] << 8) | skb->data[hdrlen + 13]; if (tpid != 0x8100) { if (skb_header_cloned(skb) || skb_headroom(skb) < 4) { /* Current SKB cannot be modified */ DBG_SKB(("Realloc Tx SKB\n")); - new_skb = dev_alloc_skb(pktlen + 4); + new_skb = dev_alloc_skb(pktlen + TAG_SZ + FCS_SZ); if (new_skb == NULL) { DBG_WARN(("Tx drop: No SKB memory\n")); priv->stats.tx_dropped++; @@ -4529,15 +5423,15 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) memcpy(new_skb->data, skb->data, hdrlen + 12); memcpy(&new_skb->data[hdrlen + 16], &skb->data[hdrlen + 12], pktlen - hdrlen - 12); - skb_put(new_skb, pktlen + 4); + skb_put(new_skb, pktlen + TAG_SZ); dev_kfree_skb_any(skb); skb = new_skb; } else { /* Add tag to existing buffer */ DBG_SKB(("Expand Tx SKB\n")); - skb_push(skb, 4); + skb_push(skb, TAG_SZ); for (idx = 0; idx < hdrlen + 12; idx++) { - skb->data[idx] = skb->data[idx + 4]; + skb->data[idx] = skb->data[idx + TAG_SZ]; } } pktdata = skb->data; @@ -4545,7 +5439,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) pktdata[hdrlen + 13] = 0x00; pktdata[hdrlen + 14] = (priv->vlan >> 8) & 0xf; pktdata[hdrlen + 15] = priv->vlan & 0xff; - pktlen += 4; + pktlen += TAG_SZ; } } } @@ -4556,8 +5450,8 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) if (tpid == 0x8100) { taglen = 4; } - if (pktlen < (64 + taglen + hdrlen)) { - pktlen = (64 + taglen + hdrlen); + if (pktlen < (60 + taglen + hdrlen)) { + pktlen = (60 + taglen + hdrlen); if (SKB_PADTO(skb, pktlen) != 0) { DBG_WARN(("Tx drop: skb_padto failed\n")); priv->stats.tx_dropped++; @@ -4568,12 +5462,11 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) } /* skb_padto may update the skb->data pointer */ pktdata = &skb->data[rcpulen]; - DBG_SKB(("Packet padded to %d bytes\n", pktlen)); } - if (pktlen > SOC_DCB_KNET_COUNT_MASK) { + if ((pktlen + FCS_SZ) > SOC_DCB_KNET_COUNT_MASK) { DBG_WARN(("Tx drop: size of pkt (%d) is out of range(%d)\n", - pktlen, SOC_DCB_KNET_COUNT_MASK)); + (pktlen + FCS_SZ), SOC_DCB_KNET_COUNT_MASK)); sinfo->tx.pkts_d_over_limit++; priv->stats.tx_dropped++; dev_kfree_skb_any(skb); @@ -4582,7 +5475,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) } dcb = desc->dcb_mem; - meta = sinfo->cmic_type == 'x' ? (uint32_t *)pktdata : dcb; + meta = (sinfo->cmic_type == 'x') ? (uint32_t *)pktdata : dcb; memset(dcb, 0, sinfo->dcb_wsize * sizeof(uint32_t)); if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { /* If module header SOP is non-zero, use RCPU meta data */ @@ -4634,7 +5527,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) if (skb_header_cloned(skb) || skb_headroom(skb) < 4) { /* Current SKB cannot be modified */ DBG_SKB(("Realloc Tx SKB for DNX ITMH header\n")); - new_skb = dev_alloc_skb(pktlen + 4 + 2); + new_skb = dev_alloc_skb(pktlen + 4 + 2 + FCS_SZ); if (new_skb == NULL) { DBG_WARN(("Tx drop: No SKB memory for DNX ITMH header\n")); priv->stats.tx_dropped++; @@ -4663,7 +5556,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) if (skb_header_cloned(skb) || skb_headroom(skb) < 4) { /* Current SKB cannot be modified */ DBG_SKB(("Realloc Tx SKB for DNX header\n")); - new_skb = dev_alloc_skb(pktlen + 2); + new_skb = dev_alloc_skb(pktlen + 2 + FCS_SZ); if (new_skb == NULL) { DBG_WARN(("Tx drop: No SKB memory for DNX header\n")); priv->stats.tx_dropped++; @@ -4737,6 +5630,16 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) dcb[4] |= (priv->qnum & 0x3f) << 8; } break; + case 39: + if (device_is_dnx(sinfo)) { + /* + * if KCOM_NETIF_T_PORT, add MH+PTCH+ITMH header + * if KCOM_NETIF_T_VLAN, add MH+PTCH+header + */ + pktdata = skb->data; + memcpy(&pktdata[0], priv->system_headers, priv->system_headers_size); + } + break; default: dcb[2] = 0xff000000; dcb[3] = 0x00000100; @@ -4761,10 +5664,10 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) /* Restore (possibly) altered packet variables * bit0 -bit15 of dcb[1] is used to save requested byte count */ - if ((skb->len + 4) <= SOC_DCB_KNET_COUNT_MASK) { - pktlen = skb->len + 4; - if (pktlen < (64 + taglen + hdrlen)) { - pktlen = (64 + taglen + hdrlen); + if ((skb->len + FCS_SZ) <= SOC_DCB_KNET_COUNT_MASK) { + pktlen = skb->len; + if (pktlen < (60 + taglen + hdrlen)) { + pktlen = (60 + taglen + hdrlen); if (SKB_PADTO(skb, pktlen) != 0) { DBG_WARN(("Tx drop: skb_padto failed\n")); priv->stats.tx_dropped++; @@ -4776,9 +5679,12 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) DBG_SKB(("Packet padded to %d bytes after tx callback\n", pktlen)); } pktdata = skb->data; + if (sinfo->cmic_type == 'x') { + meta = (uint32_t *)pktdata; + } } else { DBG_WARN(("Tx drop: size of pkt (%d) is out of range(%d)\n", - pktlen, SOC_DCB_KNET_COUNT_MASK)); + (pktlen + FCS_SZ), SOC_DCB_KNET_COUNT_MASK)); sinfo->tx.pkts_d_over_limit++; priv->stats.tx_dropped++; sinfo->tx.pkts_d_callback++; @@ -4788,8 +5694,20 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) } } + /* Do Tx timestamping */ + if (priv->port >= 0) { + if (bkn_skb_tx_flags(skb) & SKBTX_HW_TSTAMP && sinfo->tx_hwts) { + KNET_SKB_CB(skb)->port = priv->port; + bkn_hw_tstamp_tx_config(sinfo, skb, meta); + bkn_skb_tx_flags(skb) |= SKBTX_IN_PROGRESS; + } + bkn_skb_tx_timestamp(skb); + } + /* Prepare for DMA */ desc->skb = skb; + /* Add FCS bytes */ + pktlen = pktlen + FCS_SZ; desc->dma_size = pktlen; desc->skb_dma = DMA_MAP_SINGLE(sinfo->dma_dev, pktdata, desc->dma_size, @@ -4859,9 +5777,8 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) } static void -bkn_timer(unsigned long context) +bkn_timer_func(bkn_switch_info_t *sinfo) { - bkn_switch_info_t *sinfo = (bkn_switch_info_t *)context; unsigned long flags; int chan; int restart_timer; @@ -4892,6 +5809,22 @@ bkn_timer(unsigned long context) spin_unlock_irqrestore(&sinfo->lock, flags); } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) +static void +bkn_timer(unsigned long context) +{ + bkn_switch_info_t *sinfo = (bkn_switch_info_t *)context; + return bkn_timer_func(sinfo); +} +#else +static void +bkn_timer(struct timer_list *t) +{ + bkn_switch_info_t *sinfo = from_timer(sinfo, t, timer); + return bkn_timer_func(sinfo); +} +#endif + static void bkn_rx_add_tokens(bkn_switch_info_t *sinfo, int chan) { @@ -4925,9 +5858,8 @@ bkn_rx_add_tokens(bkn_switch_info_t *sinfo, int chan) } static void -bkn_rxtick(unsigned long context) +bkn_rxtick_func(bkn_switch_info_t *sinfo) { - bkn_switch_info_t *sinfo = (bkn_switch_info_t *)context; unsigned long flags; unsigned long cur_jif, ticks; uint32_t pkt_diff; @@ -4962,6 +5894,22 @@ bkn_rxtick(unsigned long context) add_timer(&sinfo->rxtick); } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) +static void +bkn_rxtick(unsigned long context) +{ + bkn_switch_info_t *sinfo = (bkn_switch_info_t *)context; + return bkn_rxtick_func(sinfo); +} +#else +static void +bkn_rxtick(struct timer_list *t) +{ + bkn_switch_info_t *sinfo = from_timer(sinfo, t, rxtick); + return bkn_rxtick_func(sinfo); +} +#endif + static void bkn_rx_rate_config(bkn_switch_info_t *sinfo) { @@ -5041,11 +5989,17 @@ bkn_create_sinfo(int dev_no) sinfo->evt_idx = -1; spin_lock_init(&sinfo->lock); + skb_queue_head_init(&sinfo->tx_ptp_queue); + INIT_WORK(&sinfo->tx_ptp_work, bkn_hw_tstamp_tx_work); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) init_timer(&sinfo->timer); - sinfo->timer.expires = jiffies + 1; sinfo->timer.data = (unsigned long)sinfo; sinfo->timer.function = bkn_timer; +#else + timer_setup(&sinfo->timer, bkn_timer, 0); +#endif + sinfo->timer.expires = jiffies + 1; INIT_LIST_HEAD(&sinfo->tx.api_dcb_list); @@ -5063,10 +6017,14 @@ bkn_create_sinfo(int dev_no) sinfo->rx[0].use_rx_skb = 0; } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) init_timer(&sinfo->rxtick); - sinfo->rxtick.expires = jiffies + 1; sinfo->rxtick.data = (unsigned long)sinfo; sinfo->rxtick.function = bkn_rxtick; +#else + timer_setup(&sinfo->rxtick, bkn_rxtick, 0); +#endif + sinfo->rxtick.expires = jiffies + 1; for (chan = 0; chan < NUM_RX_CHAN; chan++) { sinfo->rx[chan].rate_max = rx_rate[chan]; @@ -5081,7 +6039,6 @@ bkn_create_sinfo(int dev_no) return sinfo; } - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) static const struct net_device_ops bkn_netdev_ops = { .ndo_open = bkn_open, @@ -5091,7 +6048,7 @@ static const struct net_device_ops bkn_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_rx_mode = bkn_set_multicast_list, .ndo_set_mac_address = bkn_set_mac_address, - .ndo_do_ioctl = NULL, + .ndo_do_ioctl = bkn_ioctl, .ndo_tx_timeout = NULL, .ndo_change_mtu = bkn_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER @@ -5100,6 +6057,61 @@ static const struct net_device_ops bkn_netdev_ops = { }; #endif +static void +bkn_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) +{ + strlcpy(drvinfo->driver, "bcm-knet", sizeof(drvinfo->driver)); + snprintf(drvinfo->version, sizeof(drvinfo->version), "%d", KCOM_VERSION); + strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); + strlcpy(drvinfo->bus_info, "N/A", sizeof(drvinfo->bus_info)); +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) +static int +bkn_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info) +{ + bkn_priv_t *priv = netdev_priv(dev); + bkn_switch_info_t *sinfo = priv->sinfo; + + switch (sinfo->dcb_type) { + case 26: + case 32: + case 33: + case 36: + case 38: + info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE | + SOF_TIMESTAMPING_TX_SOFTWARE | + SOF_TIMESTAMPING_RX_HARDWARE | + SOF_TIMESTAMPING_RX_SOFTWARE | + SOF_TIMESTAMPING_SOFTWARE | + SOF_TIMESTAMPING_RAW_HARDWARE; + info->tx_types = 1 << HWTSTAMP_TX_OFF | 1 << HWTSTAMP_TX_ON; + info->rx_filters = 1 << HWTSTAMP_FILTER_NONE | 1 << HWTSTAMP_FILTER_ALL; + if (knet_hw_tstamp_ptp_clock_index_cb) { + info->phc_index = knet_hw_tstamp_ptp_clock_index_cb(sinfo->dev_no); + } else { + info->phc_index = -1; + } + break; + default: + info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE | + SOF_TIMESTAMPING_RX_SOFTWARE | + SOF_TIMESTAMPING_SOFTWARE; + info->phc_index = -1; + break; + } + + return 0; +} +#endif + +static const struct ethtool_ops bkn_ethtool_ops = { + .get_drvinfo = bkn_get_drvinfo, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) + .get_ts_info = bkn_get_ts_info, +#endif +}; + static struct net_device * bkn_init_ndev(u8 *mac, char *name) { @@ -5148,6 +6160,7 @@ bkn_init_ndev(u8 *mac, char *name) dev->poll_controller = bkn_poll_controller; #endif #endif + dev->ethtool_ops = &bkn_ethtool_ops; if (name && *name) { strncpy(dev->name, name, IFNAMSIZ-1); } @@ -6417,10 +7430,12 @@ bkn_knet_hw_reset(kcom_msg_hw_reset_t *kmsg, int len) /* Clean all if no channels specified */ bkn_dma_abort(sinfo); bkn_clean_dcbs(sinfo); + skb_queue_purge(&sinfo->tx_ptp_queue); } else { if (kmsg->channels & (1 << XGS_DMA_TX_CHAN)) { bkn_dma_abort_tx(sinfo); bkn_clean_tx_dcbs(sinfo); + skb_queue_purge(&sinfo->tx_ptp_queue); } for (chan = 0; chan < sinfo->rx_chans; chan++) { if (kmsg->channels & (1 << (XGS_DMA_RX_CHAN + chan))) { @@ -6464,6 +7479,10 @@ bkn_knet_hw_init(kcom_msg_hw_init_t *kmsg, int len) sinfo->rx_chans = NUM_RX_CHAN; } + DBG_DUNE(("CMIC:%c DCB:%d WSIZE:%d DMA HI: 0x%08x HDR size: %d\n", + sinfo->cmic_type, sinfo->dcb_type, sinfo->dcb_wsize, + sinfo->dma_hi, sinfo->pkt_hdr_size)); + /* Config Continuous DMA mode */ sinfo->cdma_channels = kmsg->cdma_channels & ~(~0 << (sinfo->rx_chans + 1)); @@ -6602,17 +7621,26 @@ bkn_knet_netif_create(kcom_msg_netif_create_t *kmsg, int len) priv->vlan = kmsg->netif.vlan; if (priv->type == KCOM_NETIF_T_PORT) { priv->port = kmsg->netif.port; - memcpy(priv->itmh, kmsg->netif.itmh, 4); + if (device_is_dpp(sinfo)) { + memcpy(priv->itmh, kmsg->netif.itmh, 4); + } else if (device_is_dnx(sinfo)) { + memcpy(priv->system_headers, kmsg->netif.system_headers, kmsg->netif.system_headers_size); + priv->system_headers_size = kmsg->netif.system_headers_size; + } priv->qnum = kmsg->netif.qnum; } else { - if ((device_is_dune(sinfo)) && (priv->type == KCOM_NETIF_T_VLAN)) { - /* set port as SSP to PTCH */ - priv->port = kmsg->netif.port; - priv->qnum = kmsg->netif.qnum; - } - else { - priv->port = -1; - } + if (device_is_sand(sinfo)) { + if (device_is_dpp(sinfo)) { + priv->port = kmsg->netif.port; + priv->qnum = kmsg->netif.qnum; + }else if (device_is_dnx(sinfo)) { + memcpy(priv->system_headers, kmsg->netif.system_headers, kmsg->netif.system_headers_size); + priv->system_headers_size = kmsg->netif.system_headers_size; + } + } + else { + priv->port = -1; + } } priv->flags = kmsg->netif.flags; priv->cb_user_data = kmsg->netif.cb_user_data; @@ -6673,14 +7701,28 @@ bkn_knet_netif_create(kcom_msg_netif_create_t *kmsg, int len) } } - spin_unlock_irqrestore(&sinfo->lock, flags); - DBG_VERB(("Assigned ID %d to Ethernet device %s\n", priv->id, dev->name)); kmsg->netif.id = priv->id; memcpy(kmsg->netif.macaddr, dev->dev_addr, 6); memcpy(kmsg->netif.name, dev->name, KCOM_NETIF_NAME_MAX - 1); + + if (knet_netif_create_cb != NULL) { + int retv = knet_netif_create_cb(kmsg->hdr.unit, &(kmsg->netif), dev); + if (retv) { + gprintk("Warning: knet_netif_create_cb() returned %d for netif '%s'\n", retv, dev->name); + } + } + + spin_unlock_irqrestore(&sinfo->lock, flags); + + if (device_is_dnx(sinfo)) { + int idx = 0; + for (idx = 0; idx < priv->system_headers_size; idx++) { + DBG_DUNE(("System Header[%d]: 0x%02x\n", idx, priv->system_headers[idx])); + } + } return sizeof(*kmsg); } @@ -6720,6 +7762,12 @@ bkn_knet_netif_destroy(kcom_msg_netif_destroy_t *kmsg, int len) return sizeof(kcom_msg_hdr_t); } + if (knet_netif_destroy_cb != NULL) { + kcom_netif_t netif; + memset(&netif, 0, sizeof(kcom_netif_t)); + netif.id = priv->id; + knet_netif_destroy_cb(kmsg->hdr.unit, &netif, priv->dev); + } list_del(&priv->list); if (priv->id < sinfo->ndev_max) { @@ -6875,6 +7923,17 @@ bkn_knet_filter_create(kcom_msg_filter_create_t *kmsg, int len) } memset(filter, 0, sizeof(*filter)); memcpy(&filter->kf, &kmsg->filter, sizeof(filter->kf)); + + if (device_is_dnx(sinfo)) { + /* Information to parser Dune system headers */ + sinfo->ftmh_lb_key_ext_size = kmsg->filter.ftmh_lb_key_ext_size; + sinfo->ftmh_stacking_ext_size = kmsg->filter.ftmh_stacking_ext_size; + sinfo->pph_base_size = kmsg->filter.pph_base_size; + memcpy(sinfo->pph_lif_ext_size, kmsg->filter.pph_lif_ext_size, sizeof(sinfo->pph_lif_ext_size)); + sinfo->udh_enable = kmsg->filter.udh_enable; + memcpy(sinfo->udh_length_type, kmsg->filter.udh_length_type, sizeof(sinfo->udh_length_type)); + } + filter->kf.id = id; /* Add according to priority */ @@ -6898,6 +7957,20 @@ bkn_knet_filter_create(kcom_msg_filter_create_t *kmsg, int len) DBG_VERB(("Created filter ID %d (%s).\n", filter->kf.id, filter->kf.desc)); + if (device_is_dnx(sinfo)) { + int idx, wsize; + wsize = BYTES2WORDS(filter->kf.oob_data_size + filter->kf.pkt_data_size); + DBG_DUNE(("Filter: oob_data_size = %d pkt_data_size=%d wsize %d\n", filter->kf.oob_data_size, filter->kf.pkt_data_size, wsize)); + for (idx = 0; idx < wsize; idx++) + { + DBG_DUNE(("OOB[%d]: 0x%08x [0x%08x]\n", idx, filter->kf.data.w[idx], filter->kf.mask.w[idx])); + } + DBG_DUNE(("DNX system headers parameters:LB_KEY_EXT %d, STK_EXT %d, PPH_BASE %d, LIF_EXT %d %d %d, UDH_ENA %d, %d %d %d %d\n", + sinfo->ftmh_lb_key_ext_size, sinfo->ftmh_stacking_ext_size, sinfo->pph_base_size, + sinfo->pph_lif_ext_size[1],sinfo->pph_lif_ext_size[2], sinfo->pph_lif_ext_size[3], + sinfo->udh_enable, sinfo->udh_length_type[0], sinfo->udh_length_type[1], sinfo->udh_length_type[2], sinfo->udh_length_type[3])); + } + return len; } @@ -7252,10 +8325,14 @@ bkn_get_next_dma_event(kcom_msg_dma_info_t *kmsg) if (sinfo && (sinfo->inst_id != 0) && ((sinfo->inst_id & (1 << dev_evt)) == 0)) { - DBG_INST((" %s skip dev(%d)\n",__FUNCTION__,dev_evt)); + DBG_INST((" %s skip dev(%d)\n",__FUNCTION__,dev_no)); continue; } + if (sinfo->evt_idx == -1) { + /* Event queue is not ready yet */ + continue; + } if (sinfo && sinfo->dma_events) { DBG_EVT(("Next DMA events (0x%08x)\n", sinfo->dma_events)); kmsg->hdr.unit = sinfo->dev_no; @@ -7269,9 +8346,11 @@ bkn_get_next_dma_event(kcom_msg_dma_info_t *kmsg) break; } - if (dev_no == last_dev_no) { + if ((dev_no == last_dev_no) || + (_bkn_multi_inst && (dev_no == dev_evt))) { evt = &_bkn_evt[sinfo->evt_idx]; - DBG_INST(("wait queue index %d\n",sinfo->evt_idx)); + DBG_INST(("dev_no %d dev_evt %d wait queue index %d\n", + dev_no, dev_evt, sinfo->evt_idx)); wait_event_interruptible(evt->evt_wq, evt->evt_wq_get != evt->evt_wq_put); DBG_VERB(("Event thread wakeup\n")); @@ -7367,6 +8446,7 @@ _cleanup(void) spin_lock_irqsave(&sinfo->lock, flags); bkn_clean_dcbs(sinfo); + skb_queue_purge(&sinfo->tx_ptp_queue); spin_unlock_irqrestore(&sinfo->lock, flags); } @@ -7671,6 +8751,68 @@ gmodule_get(void) return &_gmodule; } +/* + * Get DCB type and other HW info + */ +int +bkn_hw_info_get(int unit, knet_hw_info_t *hw_info) +{ + bkn_switch_info_t *sinfo; + sinfo = bkn_sinfo_from_unit(unit); + if (sinfo == NULL) { + gprintk("Warning: unknown unit: %d\n", unit); + return (-1); + } + + hw_info->cmic_type = sinfo->cmic_type; + hw_info->dcb_type = sinfo->dcb_type; + hw_info->dcb_size = WORDS2BYTES(sinfo->dcb_wsize); + hw_info->pkt_hdr_size = sinfo->pkt_hdr_size; + hw_info->cdma_channels = sinfo->cdma_channels; + + return (0); +} + +int +bkn_netif_create_cb_register(knet_netif_cb_f netif_cb) +{ + if (knet_netif_create_cb != NULL) { + return -1; + } + knet_netif_create_cb = netif_cb; + return 0; +} + +int +bkn_netif_create_cb_unregister(knet_netif_cb_f netif_cb) +{ + if (netif_cb != NULL && knet_netif_create_cb != netif_cb) { + return -1; + } + knet_netif_create_cb = NULL; + return 0; +} + +int +bkn_netif_destroy_cb_register(knet_netif_cb_f netif_cb) +{ + if (knet_netif_destroy_cb != NULL) { + return -1; + } + knet_netif_destroy_cb = netif_cb; + return 0; +} + +int +bkn_netif_destroy_cb_unregister(knet_netif_cb_f netif_cb) +{ + if (netif_cb != NULL && knet_netif_destroy_cb != netif_cb) { + return -1; + } + knet_netif_destroy_cb = NULL; + return 0; +} + /* * Call-back interfaces for other Linux kernel drivers. * @@ -7679,6 +8821,11 @@ gmodule_get(void) * * The Tx call-back allows an external module to modify SKB contents * before it is injected inot the switch. + * + * The HW timestamp callbacks invoke an external module to enable, disable + * HW timestamp on a specific port which is indicated while the netif is + * created through KNET API. KNET can also get device-specific SOBMH and + * timestamp for a Tx PTP packet through these callbacks. */ int @@ -7741,9 +8888,152 @@ bkn_filter_cb_unregister(knet_filter_cb_f filter_cb) return 0; } +int +bkn_hw_tstamp_enable_cb_register(knet_hw_tstamp_enable_cb_f hw_tstamp_enable_cb) +{ + if (knet_hw_tstamp_enable_cb != NULL) { + return -1; + } + knet_hw_tstamp_enable_cb = hw_tstamp_enable_cb; + return 0; +} + +int +bkn_hw_tstamp_enable_cb_unregister(knet_hw_tstamp_enable_cb_f hw_tstamp_enable_cb) +{ + if (hw_tstamp_enable_cb == NULL || + knet_hw_tstamp_enable_cb != hw_tstamp_enable_cb) { + return -1; + } + knet_hw_tstamp_enable_cb = NULL; + return 0; +} + +int +bkn_hw_tstamp_disable_cb_register(knet_hw_tstamp_enable_cb_f hw_tstamp_disable_cb) +{ + if (knet_hw_tstamp_disable_cb != NULL) { + return -1; + } + knet_hw_tstamp_disable_cb = hw_tstamp_disable_cb; + return 0; +} + +int +bkn_hw_tstamp_disable_cb_unregister(knet_hw_tstamp_enable_cb_f hw_tstamp_disable_cb) +{ + if (hw_tstamp_disable_cb == NULL || + knet_hw_tstamp_disable_cb != hw_tstamp_disable_cb) { + return -1; + } + knet_hw_tstamp_disable_cb = NULL; + return 0; +} + +int +bkn_hw_tstamp_tx_time_get_cb_register(knet_hw_tstamp_tx_time_get_cb_f hw_tstamp_tx_time_get_cb) +{ + if (knet_hw_tstamp_tx_time_get_cb != NULL) { + return -1; + } + knet_hw_tstamp_tx_time_get_cb = hw_tstamp_tx_time_get_cb; + return 0; +} + +int +bkn_hw_tstamp_tx_time_get_cb_unregister(knet_hw_tstamp_tx_time_get_cb_f hw_tstamp_tx_time_get_cb) +{ + if (hw_tstamp_tx_time_get_cb == NULL || + knet_hw_tstamp_tx_time_get_cb != hw_tstamp_tx_time_get_cb) { + return -1; + } + knet_hw_tstamp_tx_time_get_cb = NULL; + return 0; +} + +int +bkn_hw_tstamp_tx_meta_get_cb_register(knet_hw_tstamp_tx_meta_get_cb_f hw_tstamp_tx_meta_get_cb) +{ + if (knet_hw_tstamp_tx_meta_get_cb != NULL) { + return -1; + } + knet_hw_tstamp_tx_meta_get_cb = hw_tstamp_tx_meta_get_cb; + return 0; +} + +int +bkn_hw_tstamp_tx_meta_get_cb_unregister(knet_hw_tstamp_tx_meta_get_cb_f hw_tstamp_tx_meta_get_cb) +{ + if (hw_tstamp_tx_meta_get_cb == NULL || + knet_hw_tstamp_tx_meta_get_cb != hw_tstamp_tx_meta_get_cb) { + return -1; + } + knet_hw_tstamp_tx_meta_get_cb = NULL; + return 0; +} + +int +bkn_hw_tstamp_ptp_clock_index_cb_register(knet_hw_tstamp_ptp_clock_index_cb_f hw_tstamp_ptp_clock_index_cb) +{ + if (knet_hw_tstamp_ptp_clock_index_cb != NULL) { + return -1; + } + knet_hw_tstamp_ptp_clock_index_cb = hw_tstamp_ptp_clock_index_cb; + return 0; +} + +int +bkn_hw_tstamp_ptp_clock_index_cb_unregister(knet_hw_tstamp_ptp_clock_index_cb_f hw_tstamp_ptp_clock_index_cb) +{ + if (hw_tstamp_ptp_clock_index_cb == NULL || + knet_hw_tstamp_ptp_clock_index_cb != hw_tstamp_ptp_clock_index_cb) { + return -1; + } + knet_hw_tstamp_ptp_clock_index_cb = NULL; + return 0; +} + +int +bkn_hw_tstamp_rx_time_upscale_cb_register(knet_hw_tstamp_rx_time_upscale_cb_f hw_tstamp_rx_time_upscale_cb) +{ + if (knet_hw_tstamp_rx_time_upscale_cb != NULL) { + return -1; + } + knet_hw_tstamp_rx_time_upscale_cb = hw_tstamp_rx_time_upscale_cb; + return 0; +} + +int +bkn_hw_tstamp_rx_time_upscale_cb_unregister(knet_hw_tstamp_rx_time_upscale_cb_f hw_tstamp_rx_time_upscale_cb) +{ + if (hw_tstamp_rx_time_upscale_cb == NULL || + knet_hw_tstamp_rx_time_upscale_cb != hw_tstamp_rx_time_upscale_cb) { + return -1; + } + knet_hw_tstamp_rx_time_upscale_cb = NULL; + return 0; +} + LKM_EXPORT_SYM(bkn_rx_skb_cb_register); LKM_EXPORT_SYM(bkn_rx_skb_cb_unregister); LKM_EXPORT_SYM(bkn_tx_skb_cb_register); LKM_EXPORT_SYM(bkn_tx_skb_cb_unregister); LKM_EXPORT_SYM(bkn_filter_cb_register); LKM_EXPORT_SYM(bkn_filter_cb_unregister); +LKM_EXPORT_SYM(bkn_hw_tstamp_enable_cb_register); +LKM_EXPORT_SYM(bkn_hw_tstamp_enable_cb_unregister); +LKM_EXPORT_SYM(bkn_hw_tstamp_disable_cb_register); +LKM_EXPORT_SYM(bkn_hw_tstamp_disable_cb_unregister); +LKM_EXPORT_SYM(bkn_hw_tstamp_tx_time_get_cb_register); +LKM_EXPORT_SYM(bkn_hw_tstamp_tx_time_get_cb_unregister); +LKM_EXPORT_SYM(bkn_hw_tstamp_tx_meta_get_cb_register); +LKM_EXPORT_SYM(bkn_hw_tstamp_tx_meta_get_cb_unregister); +LKM_EXPORT_SYM(bkn_hw_tstamp_ptp_clock_index_cb_register); +LKM_EXPORT_SYM(bkn_hw_tstamp_ptp_clock_index_cb_unregister); +LKM_EXPORT_SYM(bkn_hw_tstamp_rx_time_upscale_cb_register); +LKM_EXPORT_SYM(bkn_hw_tstamp_rx_time_upscale_cb_unregister); +LKM_EXPORT_SYM(bkn_hw_info_get); +LKM_EXPORT_SYM(bkn_netif_create_cb_register); +LKM_EXPORT_SYM(bkn_netif_create_cb_unregister); +LKM_EXPORT_SYM(bkn_netif_destroy_cb_register); +LKM_EXPORT_SYM(bkn_netif_destroy_cb_unregister); diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h index 760690b3fb9d..477c037a0c43 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h @@ -39,14 +39,17 @@ typedef struct { * Call-back interfaces for other Linux kernel drivers. */ #include +#include +#include typedef struct { uint32 netif_user_data; uint32 filter_user_data; uint16 dcb_type; + int port; } knet_skb_cb_t; -#define KNET_SKB_CB(__skb) ((knet_skb_cb_t *)&((__skb)->cb[0])) +#define KNET_SKB_CB(_skb) ((knet_skb_cb_t *)_skb->cb) typedef struct sk_buff * (*knet_skb_cb_f)(struct sk_buff *skb, int dev_no, void *meta); @@ -55,6 +58,21 @@ typedef int (*knet_filter_cb_f)(uint8_t *pkt, int size, int dev_no, void *meta, int chan, kcom_filter_t *filter); +typedef int +(*knet_hw_tstamp_enable_cb_f)(int dev_no, int port); + +typedef int +(*knet_hw_tstamp_tx_time_get_cb_f)(int dev_no, int port, uint8_t *pkt, uint64_t *ts); + +typedef int +(*knet_hw_tstamp_tx_meta_get_cb_f)(int dev_no, struct sk_buff *skb, uint32_t **md); + +typedef int +(*knet_hw_tstamp_ptp_clock_index_cb_f)(int dev_no); + +typedef int +(*knet_hw_tstamp_rx_time_upscale_cb_f)(int dev_no, uint64_t *ts); + extern int bkn_rx_skb_cb_register(knet_skb_cb_f rx_cb); @@ -73,6 +91,68 @@ bkn_filter_cb_register(knet_filter_cb_f filter_cb); extern int bkn_filter_cb_unregister(knet_filter_cb_f filter_cb); -#endif +extern int +bkn_hw_tstamp_enable_cb_register(knet_hw_tstamp_enable_cb_f hw_tstamp_enable_cb); + +extern int +bkn_hw_tstamp_enable_cb_unregister(knet_hw_tstamp_enable_cb_f hw_tstamp_enable_cb); + +extern int +bkn_hw_tstamp_disable_cb_register(knet_hw_tstamp_enable_cb_f hw_tstamp_disable_cb); + +extern int +bkn_hw_tstamp_disable_cb_unregister(knet_hw_tstamp_enable_cb_f hw_tstamp_disable_cb); + +extern int +bkn_hw_tstamp_tx_time_get_cb_register(knet_hw_tstamp_tx_time_get_cb_f hw_tstamp_tx_time_get_cb); + +extern int +bkn_hw_tstamp_tx_time_get_cb_unregister(knet_hw_tstamp_tx_time_get_cb_f hw_tstamp_tx_time_get_cb); + +extern int +bkn_hw_tstamp_tx_meta_get_cb_register(knet_hw_tstamp_tx_meta_get_cb_f hw_tstamp_tx_meta_get_cb); + +extern int +bkn_hw_tstamp_tx_meta_get_cb_unregister(knet_hw_tstamp_tx_meta_get_cb_f hw_tstamp_tx_meta_get_cb); + +extern int +bkn_hw_tstamp_ptp_clock_index_cb_register(knet_hw_tstamp_ptp_clock_index_cb_f hw_tstamp_ptp_clock_index_cb); + +extern int +bkn_hw_tstamp_ptp_clock_index_cb_unregister(knet_hw_tstamp_ptp_clock_index_cb_f hw_tstamp_ptp_clock_index_cb); + +extern int +bkn_hw_tstamp_rx_time_upscale_cb_register(knet_hw_tstamp_rx_time_upscale_cb_f hw_tstamp_rx_time_upscale_cb); + +extern int +bkn_hw_tstamp_rx_time_upscale_cb_unregister(knet_hw_tstamp_rx_time_upscale_cb_f hw_tstamp_rx_time_upscale_cb); + +typedef struct { + uint8 cmic_type; + uint8 dcb_type; + uint8 dcb_size; + uint8 pkt_hdr_size; + uint32 cdma_channels; +} knet_hw_info_t; + +extern int +bkn_hw_info_get(int unit, knet_hw_info_t *hw_info); + +typedef int +(*knet_netif_cb_f)(int unit, kcom_netif_t *netif, struct net_device *dev); + +extern int +bkn_netif_create_cb_register(knet_netif_cb_f netif_cb); + +extern int +bkn_netif_create_cb_unregister(knet_netif_cb_f netif_cb); + +extern int +bkn_netif_destroy_cb_register(knet_netif_cb_f netif_cb); + +extern int +bkn_netif_destroy_cb_unregister(knet_netif_cb_f netif_cb); + +#endif /* __KERNEL__ */ #endif /* __LINUX_BCM_KNET_H__ */ diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/net/psample.h b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/net/psample.h new file mode 100644 index 000000000000..57c000785e9c --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/net/psample.h @@ -0,0 +1,24 @@ +#ifndef __NET_PSAMPLE_H +#define __NET_PSAMPLE_H + +#include +#include +#include +#include + +struct psample_group { + struct list_head list; + struct net *net; + u32 group_num; + u32 refcount; + u32 seq; +}; + +extern struct psample_group *psample_group_get(struct net *net, u32 group_num); +extern void psample_group_put(struct psample_group *group); + +extern void psample_sample_packet(struct psample_group *group, struct sk_buff *skb, + u32 trunc_size, int in_ifindex, int out_ifindex, + u32 sample_rate); + +#endif /* __NET_PSAMPLE_H */ diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/uapi/linux/psample.h b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/uapi/linux/psample.h new file mode 100644 index 000000000000..ed48996ec0e8 --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/uapi/linux/psample.h @@ -0,0 +1,35 @@ +#ifndef __UAPI_PSAMPLE_H +#define __UAPI_PSAMPLE_H + +enum { + /* sampled packet metadata */ + PSAMPLE_ATTR_IIFINDEX, + PSAMPLE_ATTR_OIFINDEX, + PSAMPLE_ATTR_ORIGSIZE, + PSAMPLE_ATTR_SAMPLE_GROUP, + PSAMPLE_ATTR_GROUP_SEQ, + PSAMPLE_ATTR_SAMPLE_RATE, + PSAMPLE_ATTR_DATA, + + /* commands attributes */ + PSAMPLE_ATTR_GROUP_REFCOUNT, + + __PSAMPLE_ATTR_MAX +}; + +enum psample_command { + PSAMPLE_CMD_SAMPLE, + PSAMPLE_CMD_GET_GROUP, + PSAMPLE_CMD_NEW_GROUP, + PSAMPLE_CMD_DEL_GROUP, +}; + +/* Can be overridden at runtime by module option */ +#define PSAMPLE_ATTR_MAX (__PSAMPLE_ATTR_MAX - 1) + +#define PSAMPLE_NL_MCGRP_CONFIG_NAME "config" +#define PSAMPLE_NL_MCGRP_SAMPLE_NAME "packets" +#define PSAMPLE_GENL_NAME "psample" +#define PSAMPLE_GENL_VERSION 1 + +#endif diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile index d7ca56cd5701..2a167bb9e811 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile @@ -36,7 +36,9 @@ KMODULE = $(LIBDIR)/$(THIS_MOD_NAME).ko build: $(MODULE) $(KMODULE) endif -KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../bcm-knet/kernel_module/Module.symvers +ifeq ($(BUILD_PSAMPLE),1) +KBUILD_EXTRA_SYMBOLS += ${BLDDIR}/../psample/kernel_module/Module.symvers +endif # BCM Network Device diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c index da221f9f453a..89d1087212c7 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c @@ -1,5 +1,5 @@ /* - * Copyright 2017 Broadcom + * Copyright 2017-2019 Broadcom * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -45,17 +45,20 @@ #include #include +/* Enable sflow sampling using psample */ +#ifdef PSAMPLE_SUPPORT +#include "psample-cb.h" +#endif + MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("Broadcom Linux KNET Call-Back Driver"); MODULE_LICENSE("GPL"); - -static int debug; +int debug; LKM_MOD_PARAM(debug, "i", int, 0); MODULE_PARM_DESC(debug, "Debug level (default 0)"); - /* Module Information */ #define MODULE_MAJOR 121 #define MODULE_NAME "linux-knet-cb" @@ -63,8 +66,10 @@ MODULE_PARM_DESC(debug, /* set KNET_CB_DEBUG for debug info */ #define KNET_CB_DEBUG -#define FILTER_TAG_STRIP 0 -#define FILTER_TAG_KEEP 1 +/* These below need to match incoming enum values */ +#define FILTER_TAG_STRIP 0 +#define FILTER_TAG_KEEP 1 +#define FILTER_TAG_ORIGINAL 2 /* Maintain tag strip statistics */ struct strip_stats_s { @@ -105,7 +110,7 @@ strip_vlan_tag(struct sk_buff *skb) * * DCB type 14: word 12, bits 10.11 * DCB type 19, 20, 21, 22, 30: word 12, bits 10..11 - * DCB type 23, 29: word 13, bits 0..1 + * DCB type 23, 29: word 13, bits 0..1 * DCB type 31, 34, 37: word 13, bits 0..1 * DCB type 26, 32, 33, 35: word 13, bits 0..1 * @@ -150,7 +155,7 @@ get_tag_status(int dcb_type, void *meta) { /* untested */ /* TH3 only parses outer tag. */ - const int tag_map[4] = { 0, 2, -1, -1 }; + const int tag_map[4] = { 0, 2, -1, -1 }; tag_status = tag_map[(dcb[9] >> 13) & 0x3]; } break; @@ -162,7 +167,7 @@ get_tag_status(int dcb_type, void *meta) if (debug & 0x1) { gprintk("%s; DCB Type: %d; tag status: %d\n", __func__, dcb_type, tag_status); } -#endif +#endif return tag_status; } @@ -183,12 +188,12 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta) if (debug & 0x1) { gprintk("%s Enter; netif Flags: %08X filter_flags %08X \n", __func__, netif_flags, filter_flags); - } + } #endif /* KNET implements this already */ if (filter_flags == FILTER_TAG_KEEP) - { +{ strip_stats.skipped++; return skb; } @@ -217,8 +222,17 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta) return skb; } + if (filter_flags == FILTER_TAG_ORIGINAL) + { + /* If untagged or single inner, strip the extra tag that knet + keep tag will add. */ + if (tag_status < 2) + { + strip_tag = 1; + } + } strip_stats.checked++; - + if (strip_tag) { #ifdef KNET_CB_DEBUG if (debug & 0x1) { @@ -235,7 +249,6 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta) } } #endif - return skb; } @@ -250,16 +263,50 @@ strip_tag_tx_cb(struct sk_buff *skb, int dev_no, void *meta) /* Filter callback not used */ static int strip_tag_filter_cb(uint8_t * pkt, int size, int dev_no, void *meta, - int chan, kcom_filter_t *kf) + int chan, kcom_filter_t *kf) { /* Pass through for now */ return 0; } +static int +knet_filter_cb(uint8_t * pkt, int size, int dev_no, void *meta, + int chan, kcom_filter_t *kf) +{ + /* check for filter callback handler */ +#ifdef PSAMPLE_SUPPORT + if (strncmp(kf->desc, PSAMPLE_CB_NAME, KCOM_FILTER_DESC_MAX) == 0) { + return psample_filter_cb (pkt, size, dev_no, meta, chan, kf); + } +#endif + return strip_tag_filter_cb (pkt, size, dev_no, meta, chan, kf); +} + +static int +knet_netif_create_cb(int unit, kcom_netif_t *netif, struct net_device *dev) +{ + int retv = 0; +#ifdef PSAMPLE_SUPPORT + retv = psample_netif_create_cb(unit, netif, dev); +#endif + return retv; +} + +static int +knet_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev) +{ + int retv = 0; +#ifdef PSAMPLE_SUPPORT + retv = psample_netif_destroy_cb(unit, netif, dev); +#endif + return retv; +} + /* * Get statistics. * % cat /proc/linux-knet-cb */ + static int _pprint(void) { @@ -275,19 +322,40 @@ static int _cleanup(void) { bkn_rx_skb_cb_unregister(strip_tag_rx_cb); - bkn_tx_skb_cb_unregister(strip_tag_tx_cb); - bkn_filter_cb_unregister(strip_tag_filter_cb); + /* strip_tag_tx_cb is currently a no-op, so no need to unregister */ + if (0) + { + bkn_tx_skb_cb_unregister(strip_tag_tx_cb); + } + bkn_filter_cb_unregister(knet_filter_cb); + bkn_netif_create_cb_unregister(knet_netif_create_cb); + bkn_netif_destroy_cb_unregister(knet_netif_destroy_cb); + +#ifdef PSAMPLE_SUPPORT + psample_cleanup(); +#endif return 0; } static int _init(void) { + bkn_rx_skb_cb_register(strip_tag_rx_cb); - bkn_tx_skb_cb_register(strip_tag_tx_cb); - bkn_filter_cb_register(strip_tag_filter_cb); + /* strip_tag_tx_cb is currently a no-op, so no need to register */ + if (0) + { + bkn_tx_skb_cb_register(strip_tag_tx_cb); + } +#ifdef PSAMPLE_SUPPORT + psample_init(); +#endif + + bkn_filter_cb_register(knet_filter_cb); + bkn_netif_create_cb_register(knet_netif_create_cb); + bkn_netif_destroy_cb_register(knet_netif_destroy_cb); return 0; } diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c new file mode 100644 index 000000000000..ef6fc102ce78 --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c @@ -0,0 +1,875 @@ +/* + * Copyright 2017-2019 Broadcom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation (the "GPL"). + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 (GPLv2) for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 (GPLv2) along with this source code. + */ +/* + * $Id: psample_cb.c $ + * $Copyright: (c) 2019 Broadcom Corp. + * All Rights Reserved.$ + */ + +/* + * Driver for call-back functions for Linux KNET driver. + * + * This code is used to integrate packet sampling KNET callback to + * the psample infra for sending sampled pkts to userspace sflow + * applications such as Host Sflow (https://github.com/sflow/host-sflow) + * using genetlink interfaces. + * + * The module can be built from the standard Linux user mode target + * directories using the following command (assuming bash), e.g. + * + * cd $SDK/systems/linux/user/ + * make BUILD_KNET_CB=1 + * + */ + +#include /* Must be included first */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "psample-cb.h" + +#define PSAMPLE_CB_DBG +#ifdef PSAMPLE_CB_DBG +extern int debug; +#define PSAMPLE_CB_DBG_PRINT(...) \ + if (debug & 0x1) { \ + gprintk(__VA_ARGS__); \ + } +#else +#define PSAMPLE_CB_DBG_PRINT(...) +#endif + +/* HIGIG2 header fields */ +#define SOC_HIGIG_SOP (0xfb) +#define SOC_HIGIG_START(x) ((x[0] >> 24) & 0xff) +#define SOC_HIGIG_DSTPORT(x) ((x[1] >> 11) & 0x1f) +#define SOC_HIGIG_SRCPORT(x) ((x[1] >> 16) & 0x1f) +#define SOC_HIGIG2_SOP (0xfb) //0xfc - TODO: how can we differentiate between Higig and higig2? +#define SOC_HIGIG2_START(x) ((x[0] >> 24) & 0xff) +#define SOC_HIGIG2_DSTPORT(x) ((x[0] >> 0) & 0xff) +#define SOC_HIGIG2_SRCPORT(x) ((x[1] >> 16) & 0xff) +#define SOC_DCB32_HG_OFFSET (6) + +#define FCS_SZ 4 +#define PSAMPLE_NLA_PADDING 4 + +#define PSAMPLE_RATE_DFLT 1 +#define PSAMPLE_SIZE_DFLT 128 +static int psample_size = PSAMPLE_SIZE_DFLT; +LKM_MOD_PARAM(psample_size, "i", int, 0); +MODULE_PARM_DESC(psample_size, +"psample pkt size (default 128 bytes)"); + +/* driver proc entry root */ +static struct proc_dir_entry *psample_proc_root = NULL; + +/* psample general info */ +typedef struct { + struct list_head netif_list; + knet_hw_info_t hw; + struct net *netns; + spinlock_t lock; +} psample_info_t; +static psample_info_t g_psample_info = {{0}}; + +/* Maintain sampled pkt statistics */ +typedef struct psample_stats_s { + unsigned long pkts_f_psample_cb; + unsigned long pkts_f_psample_mod; + unsigned long pkts_f_handled; + unsigned long pkts_f_pass_through; + unsigned long pkts_d_no_group; + unsigned long pkts_d_sampling_disabled; + unsigned long pkts_d_no_skb; + unsigned long pkts_d_not_ready; + unsigned long pkts_d_metadata; + unsigned long pkts_d_meta_srcport; + unsigned long pkts_d_meta_dstport; + unsigned long pkts_d_invalid_size; +} psample_stats_t; +static psample_stats_t g_psample_stats = {0}; + +typedef struct psample_meta_s { + int trunc_size; + int src_ifindex; + int dst_ifindex; + int sample_rate; +} psample_meta_t; + + +static psample_netif_t* +psample_netif_lookup_by_port(int unit, int port) +{ + struct list_head *list; + psample_netif_t *psample_netif = NULL; + unsigned long flags; + + /* look for port from list of available net_devices */ + spin_lock_irqsave(&g_psample_info.lock, flags); + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + if (psample_netif->port == port) { + spin_unlock_irqrestore(&g_psample_info.lock, flags); + return psample_netif; + } + } + spin_unlock_irqrestore(&g_psample_info.lock, flags); + return (NULL); +} + +static int +psample_info_get (int unit, psample_info_t *psample_info) +{ + int rv = 0; + if (!psample_info) { + gprintk("%s: psample_info is NULL\n", __func__); + return (-1); + } + + /* get hw info */ + rv = bkn_hw_info_get(unit, &psample_info->hw); + if (rv < 0) { + gprintk("%s: failed to get hw info\n", __func__); + return (-1); + } + + PSAMPLE_CB_DBG_PRINT("%s: DCB type %d\n", + __func__, psample_info->hw.dcb_type); + return (0); +} + +static int +psample_meta_srcport_get(uint8_t *pkt, void *pkt_meta) +{ + int srcport = 0; + uint32_t *metadata = (uint32_t*)pkt_meta; + + switch(g_psample_info.hw.dcb_type) { + case 36: /* TD3 */ + case 38: /* TH3 */ + break; + case 32: /* TH1/TH2 */ + case 26: /* TD2 */ + case 23: /* HX4 */ + metadata += SOC_DCB32_HG_OFFSET; + break; + default: + break; + } + + if (SOC_HIGIG2_START(metadata) == SOC_HIGIG2_SOP) + { + srcport = SOC_HIGIG2_SRCPORT(metadata); + } + else if (SOC_HIGIG_START(metadata) == SOC_HIGIG_SOP) + { + srcport = SOC_HIGIG_SRCPORT(metadata); + } + else + { + PSAMPLE_CB_DBG_PRINT("%s: Could not detect metadata sop type: 0x%02x (w[0]: 0x%04x)\n", __func__, + SOC_HIGIG_START(metadata), metadata[0]); + return -1; + } + return srcport; +} + +static int +psample_meta_dstport_get(uint8_t *pkt, void *pkt_meta) +{ + int dstport = 0; + uint32_t *metadata = (uint32_t*)pkt_meta; + + switch(g_psample_info.hw.dcb_type) { + case 36: /* TD3 */ + case 38: /* TH3 */ + break; + case 32: /* TH1/TH2 */ + case 26: /* TD2 */ + case 23: /* HX4 */ + metadata += SOC_DCB32_HG_OFFSET; + break; + default: + break; + } + + if (SOC_HIGIG2_START(metadata) == SOC_HIGIG2_SOP) + { + dstport = SOC_HIGIG2_DSTPORT(metadata); + } + else if (SOC_HIGIG_START(metadata) == SOC_HIGIG_SOP) + { + dstport = SOC_HIGIG_DSTPORT(metadata); + } + else + { + PSAMPLE_CB_DBG_PRINT("%s: Could not detect metadata sop type: 0x%02x (w[0]: 0x%04x)\n", __func__, + SOC_HIGIG_START(metadata), metadata[0]); + return (-1); + } + return dstport; +} + +static int +psample_meta_sample_reason(uint8_t *pkt, void *pkt_meta) +{ + uint32_t *metadata = (uint32_t*)pkt_meta; + uint32_t reason = 0; + uint32_t reason_hi = 0; + uint32_t sample_rx_reason_mask = 0; + + /* Sample Pkt reason code (bcmRxReasonSampleSource) */ + switch(g_psample_info.hw.dcb_type) { + case 36: /* TD3 */ + case 38: /* TH3 */ + reason_hi = *(metadata + 4); + reason = *(metadata + 5); + sample_rx_reason_mask = (1 << 3); + break; + case 32: /* TH1/TH2 */ + case 26: /* TD2 */ + case 23: /* HX4 */ + default: + reason_hi = *(metadata + 2); + reason = *(metadata + 3); + sample_rx_reason_mask = (1 << 5); + break; + } + + PSAMPLE_CB_DBG_PRINT("%s: DCB%d sample_rx_reason_mask: 0x%08x, reason: 0x%08x, reason_hi: 0x%08x\n", + __func__, g_psample_info.hw.dcb_type, sample_rx_reason_mask, reason, reason_hi); + + /* Check if only sample reason code is set. + * If only sample reason code, then consume pkt. + * If other reason codes exist, then pkt should be + * passed through to Linux network stack. + */ + if ((reason & ~sample_rx_reason_mask) || reason_hi) { + return 0; /* multiple reasons set, pass through */ + } + + /* only sample rx reason set, consume pkt */ + return (1); +} + +static int +psample_meta_get(int unit, uint8_t *pkt, void *pkt_meta, psample_meta_t *sflow_meta) +{ + int srcport, dstport; + int src_ifindex = 0; + int dst_ifindex = 0; + int sample_rate = PSAMPLE_RATE_DFLT; + int sample_size = PSAMPLE_SIZE_DFLT; + psample_netif_t *psample_netif = NULL; + +#ifdef PSAMPLE_CB_DBG + if (debug & 0x1) { + int i=0; + uint8_t *meta = (uint8_t*)pkt_meta; + PSAMPLE_CB_DBG_PRINT("%s: psample pkt metadata\n", __func__); + for (i=0; i<64; i+=16) { + PSAMPLE_CB_DBG_PRINT("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + meta[i+0], meta[i+1], meta[i+2], meta[i+3], meta[i+4], meta[i+5], meta[i+6], meta[i+7], + meta[i+8], meta[i+9], meta[i+10], meta[i+11], meta[i+12], meta[i+13], meta[i+14], meta[i+15]); + } + } +#endif + + /* parse pkt metadata for src and dst ports */ + srcport = psample_meta_srcport_get(pkt, pkt_meta); + dstport = psample_meta_dstport_get(pkt, pkt_meta); + if ((srcport == -1) || (dstport == -1)) { + gprintk("%s: invalid srcport %d or dstport %d\n", __func__, srcport, dstport); + return (-1); + } + + /* find src port netif (no need to lookup CPU port) */ + if (srcport != 0) { + if ((psample_netif = psample_netif_lookup_by_port(unit, srcport))) { + src_ifindex = psample_netif->dev->ifindex; + sample_rate = psample_netif->sample_rate; + sample_size = psample_netif->sample_size; + } else { + g_psample_stats.pkts_d_meta_srcport++; + PSAMPLE_CB_DBG_PRINT("%s: could not find srcport(%d)\n", __func__, srcport); + } + } + + /* find dst port netif (no need to lookup CPU port) */ + if (dstport != 0) { + if ((psample_netif = psample_netif_lookup_by_port(unit, dstport))) { + dst_ifindex = psample_netif->dev->ifindex; + } else { + g_psample_stats.pkts_d_meta_dstport++; + PSAMPLE_CB_DBG_PRINT("%s: could not find dstport(%d)\n", __func__, dstport); + } + } + + PSAMPLE_CB_DBG_PRINT("%s: srcport %d, dstport %d, src_ifindex %d, dst_ifindex %d, trunc_size %d, sample_rate %d\n", + __func__, srcport, dstport, src_ifindex, dst_ifindex, sample_size, sample_rate); + + sflow_meta->src_ifindex = src_ifindex; + sflow_meta->dst_ifindex = dst_ifindex; + sflow_meta->trunc_size = sample_size; + sflow_meta->sample_rate = sample_rate; + + return (0); +} + +int +psample_filter_cb(uint8_t * pkt, int size, int dev_no, void *pkt_meta, + int chan, kcom_filter_t *kf) +{ + struct psample_group *group; + psample_meta_t meta; + struct sk_buff skb; + int rv = 0; + static int info_get = 0; + + if (!info_get) { + rv = psample_info_get (dev_no, &g_psample_info); + if (rv < 0) { + gprintk("%s: failed to get psample info\n", __func__); + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } + info_get = 1; + } + + PSAMPLE_CB_DBG_PRINT("%s: pkt size %d, kf->dest_id %d, kf->cb_user_data %d\n", + __func__, size, kf->dest_id, kf->cb_user_data); + g_psample_stats.pkts_f_psample_cb++; + + /* get psample group info. psample genetlink group ID passed in kf->dest_id */ + group = psample_group_get(g_psample_info.netns, kf->dest_id); + if (!group) { + gprintk("%s: Could not find psample genetlink group %d\n", __func__, kf->cb_user_data); + g_psample_stats.pkts_d_no_group++; + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } + + /* get psample metadata */ + rv = psample_meta_get(dev_no, pkt, pkt_meta, &meta); + if (rv < 0) { + gprintk("%s: Could not parse pkt metadata\n", __func__); + g_psample_stats.pkts_d_metadata++; + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } + + /* Adjust original pkt size to remove 4B FCS */ + if (size < FCS_SZ) { + g_psample_stats.pkts_d_invalid_size++; + goto PSAMPLE_FILTER_CB_PKT_HANDLED; + } else { + size -= FCS_SZ; + } + + /* Account for padding in libnl used by psample */ + if (meta.trunc_size >= size) { + meta.trunc_size = size - PSAMPLE_NLA_PADDING; + } + + PSAMPLE_CB_DBG_PRINT("%s: group 0x%x, trunc_size %d, src_ifdx %d, dst_ifdx %d, sample_rate %d\n", + __func__, group->group_num, meta.trunc_size, meta.src_ifindex, meta.dst_ifindex, meta.sample_rate); + + /* drop if configured sample rate is 0 */ + if (meta.sample_rate > 0) { + /* setup skb to point to pkt */ + memset(&skb, 0, sizeof(struct sk_buff)); + skb.len = size; + skb.data = pkt; + + psample_sample_packet(group, + &skb, + meta.trunc_size, + meta.src_ifindex, + meta.dst_ifindex, + meta.sample_rate); + + g_psample_stats.pkts_f_psample_mod++; + } else { + g_psample_stats.pkts_d_sampling_disabled++; + } + +PSAMPLE_FILTER_CB_PKT_HANDLED: + /* if sample reason only, consume pkt. else pass through */ + rv = psample_meta_sample_reason(pkt, pkt_meta); + if (rv) { + g_psample_stats.pkts_f_handled++; + } else { + g_psample_stats.pkts_f_pass_through++; + } + return rv; +} + +int +psample_netif_create_cb(int unit, kcom_netif_t *netif, struct net_device *dev) +{ + int found; + struct list_head *list; + psample_netif_t *psample_netif, *lpsample_netif; + unsigned long flags; + + if ((psample_netif = kmalloc(sizeof(psample_netif_t), GFP_KERNEL)) == NULL) { + gprintk("%s: failed to alloc psample mem for netif '%s'\n", + __func__, dev->name); + return (-1); + } + + spin_lock_irqsave(&g_psample_info.lock, flags); + + psample_netif->dev = dev; + psample_netif->id = netif->id; + psample_netif->port = netif->port; + psample_netif->vlan = netif->vlan; + psample_netif->qnum = netif->qnum; + psample_netif->sample_rate = PSAMPLE_RATE_DFLT; + psample_netif->sample_size = PSAMPLE_SIZE_DFLT; + + /* insert netif sorted by ID similar to bkn_knet_netif_create() */ + found = 0; + list_for_each(list, &g_psample_info.netif_list) { + lpsample_netif = (psample_netif_t*)list; + if (netif->id < lpsample_netif->id) { + found = 1; + break; + } + } + + if (found) { + /* Replace previously removed interface */ + list_add_tail(&psample_netif->list, &lpsample_netif->list); + } else { + /* No holes - add to end of list */ + list_add_tail(&psample_netif->list, &g_psample_info.netif_list); + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + + PSAMPLE_CB_DBG_PRINT("%s: added psample netif '%s'\n", __func__, dev->name); + return (0); +} + +int +psample_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev) +{ + int found; + struct list_head *list; + psample_netif_t *psample_netif; + unsigned long flags; + + if (!netif || !dev) { + gprintk("%s: netif or net_device is NULL\n", __func__); + return (-1); + } + + spin_lock_irqsave(&g_psample_info.lock, flags); + + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + if (netif->id == psample_netif->id) { + found = 1; + list_del(&psample_netif->list); + PSAMPLE_CB_DBG_PRINT("%s: removing psample netif '%s'\n", __func__, dev->name); + kfree(psample_netif); + break; + } + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + + if (!found) { + gprintk("%s: netif ID %d not found!\n", __func__, netif->id); + return (-1); + } + return (0); +} + +/* + * psample rate Proc Read Entry + */ +static int +psample_proc_rate_show(struct seq_file *m, void *v) +{ + struct list_head *list; + psample_netif_t *psample_netif; + unsigned long flags; + + spin_lock_irqsave(&g_psample_info.lock, flags); + + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + seq_printf(m, " %-14s %d\n", psample_netif->dev->name, psample_netif->sample_rate); + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + + return 0; +} + +static int +psample_proc_rate_open(struct inode * inode, struct file * file) +{ + return single_open(file, psample_proc_rate_show, NULL); +} + +/* + * psample rate Proc Write Entry + * + * Syntax: + * = + * + * Where is a virtual network interface name. + * + * Examples: + * eth4=1000 + */ +static ssize_t +psample_proc_rate_write(struct file *file, const char *buf, + size_t count, loff_t *loff) +{ + int found; + struct list_head *list; + psample_netif_t *psample_netif; + char sample_str[40], *ptr, *newline; + unsigned long flags; + + + if (count > sizeof(sample_str)) { + count = sizeof(sample_str) - 1; + sample_str[count] = '\0'; + } + if (copy_from_user(sample_str, buf, count)) { + return -EFAULT; + } + sample_str[count] = 0; + newline = strchr(sample_str, '\n'); + if (newline) { + /* Chop off the trailing newline */ + *newline = '\0'; + } + + if ((ptr = strchr(sample_str, '=')) == NULL && + (ptr = strchr(sample_str, ':')) == NULL) { + gprintk("Error: Pkt sample rate syntax not recognized: '%s'\n", sample_str); + return count; + } + *ptr++ = 0; + + spin_lock_irqsave(&g_psample_info.lock, flags); + + found = 0; + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + if (strcmp(psample_netif->dev->name, sample_str) == 0) { + psample_netif->sample_rate = simple_strtol(ptr, NULL, 10); + // TODO MLI@BRCM - check valid sample rate + found = 1; + break; + } + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + + if (!found) { + gprintk("Warning: Failed setting psample rate on unknown network interface: '%s'\n", sample_str); + } + return count; +} + +struct file_operations psample_proc_rate_file_ops = { + owner: THIS_MODULE, + open: psample_proc_rate_open, + read: seq_read, + llseek: seq_lseek, + write: psample_proc_rate_write, + release: single_release, +}; + +/* + * psample size Proc Read Entry + */ +static int +psample_proc_size_show(struct seq_file *m, void *v) +{ + struct list_head *list; + psample_netif_t *psample_netif; + unsigned long flags; + + spin_lock_irqsave(&g_psample_info.lock, flags); + + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + seq_printf(m, " %-14s %d\n", psample_netif->dev->name, psample_netif->sample_size); + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + return 0; +} + +static int +psample_proc_size_open(struct inode * inode, struct file * file) +{ + return single_open(file, psample_proc_size_show, NULL); +} + +/* + * psample size Proc Write Entry + * + * Syntax: + * = + * + * Where is a virtual network interface name. + * + * Examples: + * eth4=128 + */ +static ssize_t +psample_proc_size_write(struct file *file, const char *buf, + size_t count, loff_t *loff) +{ + int found; + struct list_head *list; + psample_netif_t *psample_netif; + char sample_str[40], *ptr, *newline; + unsigned long flags; + + if (count > sizeof(sample_str)) { + count = sizeof(sample_str) - 1; + sample_str[count] = '\0'; + } + if (copy_from_user(sample_str, buf, count)) { + return -EFAULT; + } + sample_str[count] = 0; + newline = strchr(sample_str, '\n'); + if (newline) { + /* Chop off the trailing newline */ + *newline = '\0'; + } + + if ((ptr = strchr(sample_str, '=')) == NULL && + (ptr = strchr(sample_str, ':')) == NULL) { + gprintk("Error: Pkt sample size syntax not recognized: '%s'\n", sample_str); + return count; + } + *ptr++ = 0; + + spin_lock_irqsave(&g_psample_info.lock, flags); + + found = 0; + list_for_each(list, &g_psample_info.netif_list) { + psample_netif = (psample_netif_t*)list; + if (strcmp(psample_netif->dev->name, sample_str) == 0) { + psample_netif->sample_size = simple_strtol(ptr, NULL, 10); + // TODO MLI@BRCM - check valid sample size + found = 1; + break; + } + } + + spin_unlock_irqrestore(&g_psample_info.lock, flags); + + if (!found) { + gprintk("Warning: Failed setting psample size on unknown network interface: '%s'\n", sample_str); + } + return count; +} + +struct file_operations psample_proc_size_file_ops = { + owner: THIS_MODULE, + open: psample_proc_size_open, + read: seq_read, + llseek: seq_lseek, + write: psample_proc_size_write, + release: single_release, +}; + +/* + * psample debug Proc Read Entry + */ +static int +psample_proc_debug_show(struct seq_file *m, void *v) +{ + seq_printf(m, "BCM KNET %s Callback Config\n", PSAMPLE_CB_NAME); + seq_printf(m, " debug: 0x%x\n", debug); + seq_printf(m, " cmic_type: %d\n", g_psample_info.hw.cmic_type); + seq_printf(m, " dcb_type: %d\n", g_psample_info.hw.dcb_type); + seq_printf(m, " dcb_size: %d\n", g_psample_info.hw.dcb_size); + seq_printf(m, " pkt_hdr_size: %d\n", g_psample_info.hw.pkt_hdr_size); + seq_printf(m, " cdma_channels: %d\n", g_psample_info.hw.cdma_channels); + + return 0; +} + +static int +psample_proc_debug_open(struct inode * inode, struct file * file) +{ + return single_open(file, psample_proc_debug_show, NULL); +} + +/* + * psample debug Proc Write Entry + * + * Syntax: + * debug= + * + * Where corresponds to the debug module parameter. + * + * Examples: + * debug=0x1 + */ +static ssize_t +psample_proc_debug_write(struct file *file, const char *buf, + size_t count, loff_t *loff) +{ + char debug_str[40]; + char *ptr; + + if (count > sizeof(debug_str)) { + count = sizeof(debug_str) - 1; + debug_str[count] = '\0'; + } + if (copy_from_user(debug_str, buf, count)) { + return -EFAULT; + } + + if ((ptr = strstr(debug_str, "debug=")) != NULL) { + ptr += 6; + debug = simple_strtol(ptr, NULL, 0); + } else { + gprintk("Warning: unknown configuration setting\n"); + } + + return count; +} + +struct file_operations psample_proc_debug_file_ops = { + owner: THIS_MODULE, + open: psample_proc_debug_open, + read: seq_read, + llseek: seq_lseek, + write: psample_proc_debug_write, + release: single_release, +}; + +static int +psample_proc_stats_show(struct seq_file *m, void *v) +{ + seq_printf(m, "BCM KNET %s Callback Stats\n", PSAMPLE_CB_NAME); + seq_printf(m, " DCB type %d\n", g_psample_info.hw.dcb_type); + seq_printf(m, " pkts filter psample cb %10lu\n", g_psample_stats.pkts_f_psample_cb); + seq_printf(m, " pkts sent to psample module %10lu\n", g_psample_stats.pkts_f_psample_mod); + seq_printf(m, " pkts handled by psample %10lu\n", g_psample_stats.pkts_f_handled); + seq_printf(m, " pkts pass through %10lu\n", g_psample_stats.pkts_f_pass_through); + seq_printf(m, " pkts drop no psample group %10lu\n", g_psample_stats.pkts_d_no_group); + seq_printf(m, " pkts drop sampling disabled %10lu\n", g_psample_stats.pkts_d_sampling_disabled); + seq_printf(m, " pkts drop no skb %10lu\n", g_psample_stats.pkts_d_no_skb); + seq_printf(m, " pkts drop psample not ready %10lu\n", g_psample_stats.pkts_d_not_ready); + seq_printf(m, " pkts drop metadata parse error %10lu\n", g_psample_stats.pkts_d_metadata); + seq_printf(m, " pkts with invalid src port %10lu\n", g_psample_stats.pkts_d_meta_srcport); + seq_printf(m, " pkts with invalid dst port %10lu\n", g_psample_stats.pkts_d_meta_dstport); + seq_printf(m, " pkts with invalid orig pkt sz %10lu\n", g_psample_stats.pkts_d_invalid_size); + return 0; +} + +static int +psample_proc_stats_open(struct inode * inode, struct file * file) +{ + return single_open(file, psample_proc_stats_show, NULL); +} + +struct file_operations psample_proc_stats_file_ops = { + owner: THIS_MODULE, + open: psample_proc_stats_open, + read: seq_read, + llseek: seq_lseek, + write: NULL, + release: single_release, +}; + +int psample_cleanup(void) +{ + remove_proc_entry("stats", psample_proc_root); + remove_proc_entry("rate", psample_proc_root); + remove_proc_entry("size", psample_proc_root); + remove_proc_entry("debug", psample_proc_root); + return 0; +} + +int psample_init(void) +{ + #define PROCFS_MAX_PATH 1024 + char psample_procfs_path[PROCFS_MAX_PATH]; + struct proc_dir_entry *entry; + + /* create procfs for psample */ + snprintf(psample_procfs_path, PROCFS_MAX_PATH, "bcm/knet-cb"); + proc_mkdir(psample_procfs_path, NULL); + snprintf(psample_procfs_path, PROCFS_MAX_PATH, "%s/%s", psample_procfs_path, PSAMPLE_CB_NAME); + psample_proc_root = proc_mkdir(psample_procfs_path, NULL); + + /* create procfs for psample stats */ + PROC_CREATE(entry, "stats", 0666, psample_proc_root, &psample_proc_stats_file_ops); + if (entry == NULL) { + gprintk("%s: Unable to create procfs entry '/procfs/%s/stats'\n", __func__, psample_procfs_path); + return -1; + } + + /* create procfs for setting sample rates */ + PROC_CREATE(entry, "rate", 0666, psample_proc_root, &psample_proc_rate_file_ops); + if (entry == NULL) { + gprintk("%s: Unable to create procfs entry '/procfs/%s/rate'\n", __func__, psample_procfs_path); + return -1; + } + + /* create procfs for setting sample size */ + PROC_CREATE(entry, "size", 0666, psample_proc_root, &psample_proc_size_file_ops); + if (entry == NULL) { + gprintk("%s: Unable to create procfs entry '/procfs/%s/size'\n", __func__, psample_procfs_path); + return -1; + } + + /* create procfs for debug log */ + PROC_CREATE(entry, "debug", 0666, psample_proc_root, &psample_proc_debug_file_ops); + if (entry == NULL) { + gprintk("%s: Unable to create procfs entry '/procfs/%s/debug'\n", __func__, psample_procfs_path); + return -1; + } + + /* clear data structs */ + memset(&g_psample_stats, 0, sizeof(psample_stats_t)); + memset(&g_psample_info, 0, sizeof(psample_info_t)); + + /* setup psample_info struct */ + INIT_LIST_HEAD(&g_psample_info.netif_list); + spin_lock_init(&g_psample_info.lock); + + /* get net namespace */ + g_psample_info.netns = get_net_ns_by_pid(current->pid); + if (!g_psample_info.netns) { + gprintk("%s: Could not get network namespace for pid %d\n", __func__, current->pid); + return (-1); + } + PSAMPLE_CB_DBG_PRINT("%s: current->pid %d, netns 0x%p, sample_size %d\n", __func__, + current->pid, g_psample_info.netns, psample_size); + + return 0; +} diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.h b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.h new file mode 100644 index 000000000000..8f9398c51692 --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.h @@ -0,0 +1,58 @@ +/* + * Copyright 2017 Broadcom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation (the "GPL"). + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 (GPLv2) for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 (GPLv2) along with this source code. + */ +/* + * $Id: psample_cb.h $ + * $Copyright: (c) 2019 Broadcom Corp. + * All Rights Reserved.$ + */ +#ifndef __PSAMPLE_CB_H__ +#define __PSAMPLE_CB_H__ + +#include +#include +#include + +#define PSAMPLE_CB_NAME "psample" + +extern int +psample_init(void); + +extern int +psample_cleanup(void); + +extern int +psample_filter_cb(uint8_t * pkt, int size, int dev_no, void *pkt_meta, + int chan, kcom_filter_t *kf); + +/* psample data per interface */ +typedef struct { + struct list_head list; + struct net_device *dev; + uint16 id; + uint8 port; + uint16 vlan; + uint16 qnum; + uint32 sample_rate; + uint32 sample_size; +} psample_netif_t; + +extern int +psample_netif_create_cb(int unit, kcom_netif_t *netif, struct net_device *dev); + +extern int +psample_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev); + +#endif /* __PSAMPLE_CB_H__ */ diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/Makefile b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/Makefile new file mode 100644 index 000000000000..631590104cd8 --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/Makefile @@ -0,0 +1,64 @@ +# +# Copyright 2017 Broadcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License, version 2, as +# published by the Free Software Foundation (the "GPL"). +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License version 2 (GPLv2) for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 (GPLv2) along with this source code. +# +# -*- Makefile -*- +# $Id: Makefile,v 1.3 Broadcom SDK $ +# $Copyright: (c) 2005 Broadcom Corp. +# All Rights Reserved.$ +# +LOCALDIR = systems/linux/kernel/modules/psample + +include ${SDK}/make/Make.config + +LIBS = $(LIBDIR)/libkern.a + +ifeq ($(kernel_version),2_4) +MODULE = $(LIBDIR)/psample.o +else +KERNEL_MODULE_DIR = kernel_module + +THIS_MOD_NAME := psample +MODULE = $(LIBDIR)/$(THIS_MOD_NAME).o +KMODULE = $(LIBDIR)/$(THIS_MOD_NAME).ko + +build: $(MODULE) $(KMODULE) +endif + +KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../bcm-knet/kernel_module/Module.symvers + +# BCM Network Device + +$(MODULE): $(BLDDIR)/.tree $(BOBJS) $(LIBS) + $(LD) $(MODULE_LDFLAGS) -r -d $(BOBJS) $(LIBS) -o $@ +ifneq ($(kernel_version),2_4) +$(KMODULE): $(MODULE) + rm -fr $(BLDDIR)/$(KERNEL_MODULE_DIR) + mkdir $(BLDDIR)/$(KERNEL_MODULE_DIR) + cp ${SDK}/make/Makefile.linux-kmodule $(BLDDIR)/$(KERNEL_MODULE_DIR)/Makefile + cat ${KBUILD_EXTRA_SYMBOLS} > $(BLDDIR)/$(KERNEL_MODULE_DIR)/Module.symvers + MOD_NAME=$(THIS_MOD_NAME) $(MAKE) -C $(BLDDIR)/$(KERNEL_MODULE_DIR) $(THIS_MOD_NAME).ko +endif + +# Make.depend is before clean:: so that Make.depend's clean:: runs first. + +include ${SDK}/make/Make.depend + +clean:: + $(RM) $(BLDDIR)/version.c $(BLDDIR)/version.o + $(RM) $(BOBJS) $(MODULE) + +ifneq ($(kernel_version),2_4) +.PHONY: build +endif diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c new file mode 100644 index 000000000000..e1d4e2353b09 --- /dev/null +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c @@ -0,0 +1,302 @@ +/* + * net/psample/psample.c - Netlink channel for packet sampling + * Copyright (c) 2017 Yotam Gigi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PSAMPLE_MAX_PACKET_SIZE 0xffff + +static LIST_HEAD(psample_groups_list); +static DEFINE_SPINLOCK(psample_groups_lock); + +/* multicast groups */ +enum psample_nl_multicast_groups { + PSAMPLE_NL_MCGRP_CONFIG, + PSAMPLE_NL_MCGRP_SAMPLE, +}; + +static const struct genl_multicast_group psample_nl_mcgrps[] = { + [PSAMPLE_NL_MCGRP_CONFIG] = { .name = PSAMPLE_NL_MCGRP_CONFIG_NAME }, + [PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME }, +}; + +static struct genl_family psample_nl_family __ro_after_init; + +static int psample_group_nl_fill(struct sk_buff *msg, + struct psample_group *group, + enum psample_command cmd, u32 portid, u32 seq, + int flags) +{ + void *hdr; + int ret; + + hdr = genlmsg_put(msg, portid, seq, &psample_nl_family, flags, cmd); + if (!hdr) + return -EMSGSIZE; + + ret = nla_put_u32(msg, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num); + if (ret < 0) + goto error; + + ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_REFCOUNT, group->refcount); + if (ret < 0) + goto error; + + ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_SEQ, group->seq); + if (ret < 0) + goto error; + + genlmsg_end(msg, hdr); + return 0; + +error: + genlmsg_cancel(msg, hdr); + return -EMSGSIZE; +} + +static int psample_nl_cmd_get_group_dumpit(struct sk_buff *msg, + struct netlink_callback *cb) +{ + struct psample_group *group; + int start = cb->args[0]; + int idx = 0; + int err; + + spin_lock(&psample_groups_lock); + list_for_each_entry(group, &psample_groups_list, list) { + if (!net_eq(group->net, sock_net(msg->sk))) + continue; + if (idx < start) { + idx++; + continue; + } + err = psample_group_nl_fill(msg, group, PSAMPLE_CMD_NEW_GROUP, + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, NLM_F_MULTI); + if (err) + break; + idx++; + } + + spin_unlock(&psample_groups_lock); + cb->args[0] = idx; + return msg->len; +} + +static const struct genl_ops psample_nl_ops[] = { + { + .cmd = PSAMPLE_CMD_GET_GROUP, + .dumpit = psample_nl_cmd_get_group_dumpit, + /* can be retrieved by unprivileged users */ + } +}; + +static struct genl_family psample_nl_family __ro_after_init = { + .name = PSAMPLE_GENL_NAME, + .version = PSAMPLE_GENL_VERSION, + .maxattr = PSAMPLE_ATTR_MAX, + .netnsok = true, + .module = THIS_MODULE, + .mcgrps = psample_nl_mcgrps, + .ops = psample_nl_ops, + .n_ops = ARRAY_SIZE(psample_nl_ops), + .n_mcgrps = ARRAY_SIZE(psample_nl_mcgrps), +}; + +static void psample_group_notify(struct psample_group *group, + enum psample_command cmd) +{ + struct sk_buff *msg; + int err; + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); + if (!msg) + return; + + err = psample_group_nl_fill(msg, group, cmd, 0, 0, NLM_F_MULTI); + if (!err) + genlmsg_multicast_netns(&psample_nl_family, group->net, msg, 0, + PSAMPLE_NL_MCGRP_CONFIG, GFP_ATOMIC); + else + nlmsg_free(msg); +} + +static struct psample_group *psample_group_create(struct net *net, + u32 group_num) +{ + struct psample_group *group; + + group = kzalloc(sizeof(*group), GFP_ATOMIC); + if (!group) + return NULL; + + group->net = net; + group->group_num = group_num; + list_add_tail(&group->list, &psample_groups_list); + + psample_group_notify(group, PSAMPLE_CMD_NEW_GROUP); + return group; +} + +static void psample_group_destroy(struct psample_group *group) +{ + psample_group_notify(group, PSAMPLE_CMD_DEL_GROUP); + list_del(&group->list); + kfree(group); +} + +static struct psample_group * +psample_group_lookup(struct net *net, u32 group_num) +{ + struct psample_group *group; + + list_for_each_entry(group, &psample_groups_list, list) + if ((group->group_num == group_num) && (group->net == net)) + return group; + return NULL; +} + +struct psample_group *psample_group_get(struct net *net, u32 group_num) +{ + struct psample_group *group; + + spin_lock(&psample_groups_lock); + + group = psample_group_lookup(net, group_num); + if (!group) { + group = psample_group_create(net, group_num); + if (!group) + goto out; + } + group->refcount++; + +out: + spin_unlock(&psample_groups_lock); + return group; +} +EXPORT_SYMBOL_GPL(psample_group_get); + +void psample_group_put(struct psample_group *group) +{ + spin_lock(&psample_groups_lock); + + if (--group->refcount == 0) + psample_group_destroy(group); + + spin_unlock(&psample_groups_lock); +} +EXPORT_SYMBOL_GPL(psample_group_put); + +void psample_sample_packet(struct psample_group *group, struct sk_buff *skb, + u32 trunc_size, int in_ifindex, int out_ifindex, + u32 sample_rate) +{ + struct sk_buff *nl_skb; + int data_len; + int meta_len; + void *data; + int ret; + + meta_len = (in_ifindex ? nla_total_size(sizeof(u16)) : 0) + + (out_ifindex ? nla_total_size(sizeof(u16)) : 0) + + nla_total_size(sizeof(u32)) + /* sample_rate */ + nla_total_size(sizeof(u32)) + /* orig_size */ + nla_total_size(sizeof(u32)) + /* group_num */ + nla_total_size(sizeof(u32)); /* seq */ + + data_len = min(skb->len, trunc_size); + if (meta_len + nla_total_size(data_len) > PSAMPLE_MAX_PACKET_SIZE) + data_len = PSAMPLE_MAX_PACKET_SIZE - meta_len - NLA_HDRLEN + - NLA_ALIGNTO; + + nl_skb = genlmsg_new(meta_len + data_len, GFP_ATOMIC); + if (unlikely(!nl_skb)) + return; + + data = genlmsg_put(nl_skb, 0, 0, &psample_nl_family, 0, + PSAMPLE_CMD_SAMPLE); + if (unlikely(!data)) + goto error; + + if (in_ifindex) { + ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_IIFINDEX, in_ifindex); + if (unlikely(ret < 0)) + goto error; + } + + if (out_ifindex) { + ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_OIFINDEX, out_ifindex); + if (unlikely(ret < 0)) + goto error; + } + + ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_RATE, sample_rate); + if (unlikely(ret < 0)) + goto error; + + ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_ORIGSIZE, skb->len); + if (unlikely(ret < 0)) + goto error; + + ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num); + if (unlikely(ret < 0)) + goto error; + + ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_GROUP_SEQ, group->seq++); + if (unlikely(ret < 0)) + goto error; + + if (data_len) { + int nla_len = nla_total_size(data_len); + struct nlattr *nla; + + nla = (struct nlattr *)skb_put(nl_skb, nla_len); + nla->nla_type = PSAMPLE_ATTR_DATA; + nla->nla_len = nla_attr_size(data_len); + + if (skb_copy_bits(skb, 0, nla_data(nla), data_len)) + goto error; + } + + genlmsg_end(nl_skb, data); + genlmsg_multicast_netns(&psample_nl_family, group->net, nl_skb, 0, + PSAMPLE_NL_MCGRP_SAMPLE, GFP_ATOMIC); + + return; +error: + pr_err_ratelimited("Could not create psample log message\n"); + nlmsg_free(nl_skb); +} +EXPORT_SYMBOL_GPL(psample_sample_packet); + +static int __init psample_module_init(void) +{ + return genl_register_family(&psample_nl_family); +} + +static void __exit psample_module_exit(void) +{ + genl_unregister_family(&psample_nl_family); +} + +module_init(psample_module_init); +module_exit(psample_module_exit); + +MODULE_AUTHOR("Yotam Gigi "); +MODULE_DESCRIPTION("netlink channel for packet sampling"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile index 0e6226544334..20d83735fcce 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile @@ -91,6 +91,9 @@ KNET_CB := $(DEST_DIR)/$(KNET_CB_LOCAL) BCM_KNET_LOCAL :=linux-bcm-knet.$(KOBJ) BCM_KNET=$(DEST_DIR)/$(BCM_KNET_LOCAL) +PSAMPLE_LOCAL := psample.$(KOBJ) +PSAMPLE := $(DEST_DIR)/$(PSAMPLE_LOCAL) + ifeq (,$(findstring DELIVER,$(MAKECMDGOALS))) .DEFAULT_GOAL := all all_targets := kernel_modules $(KERNEL_BDE) $(USER_BDE) @@ -126,6 +129,15 @@ all_targets +=$(LOCAL_TARGETS) endif endif +ifdef BUILD_PSAMPLE +all_targets += $(PSAMPLE) +ADD_TO_CFLAGS += -DPSAMPLE_SUPPORT +ifeq ($(NO_LOCAL_TARGETS),) +LOCAL_TARGETS +=$(patsubst %,../$(platform)/%,$(PSAMPLE_LOCAL)) +all_targets +=$(LOCAL_TARGETS) +endif +endif + ADD_TO_CFLAGS += -I$(SDK)/systems/linux/kernel/modules/include COND_KNET_LIBS = libuser.$(libext) endif @@ -159,6 +171,10 @@ kernel_modules: ifeq ($(BUILD_KNET),1) $(MAKE) -j1 -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ subdirs="shared bcm-knet" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" +ifdef BUILD_PSAMPLE + $(MAKE) -j1 -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ + subdirs="psample" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" +endif ifdef BUILD_KNET_CB $(MAKE) -j1 -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ subdirs="knet-cb" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" @@ -178,6 +194,10 @@ $(BCM_KNET): $(KERN_BLDROOT)/linux-bcm-knet.$(KOBJ) $(KNET_CB): $(KERN_BLDROOT)/linux-knet-cb.$(KOBJ) $(OBJCOPY) --strip-debug $< $@ +$(PSAMPLE): $(KERN_BLDROOT)/psample.$(KOBJ) + $(OBJCOPY) --strip-debug $< $@ + + ifeq ($(NO_LOCAL_TARGETS),) $(foreach targ,$(LOCAL_TARGETS),$(eval $(call LOCAL_TARGET_DEF,$(targ)))) endif @@ -194,6 +214,7 @@ clean:: $(RM) $(KERN_BLDROOT)/linux-user-bde.$(KOBJ) $(RM) $(KERN_BLDROOT)/linux-bcm-knet.$(KOBJ) $(RM) $(KERN_BLDROOT)/linux-knet-cb.$(KOBJ) + $(RM) $(KERN_BLDROOT)/psample.$(KOBJ) $(RM) $(LOCAL_TARGETS) distclean:: clean diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/iproc/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/iproc/Makefile index 7a8b4a8b0c4d..03300ff8a046 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/user/iproc/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/user/iproc/Makefile @@ -44,7 +44,7 @@ endif export SDK -override kernel_version=4_4 +override kernel_version=4_14 platform=iproc IPROC_BUILD=1 diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 133238622f76..08e002624abb 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -291,7 +291,9 @@ RUN apt-get update && apt-get install -y \ automake1.11 \ libselinux1-dev \ # For kdump-tools - liblzo2-dev + liblzo2-dev \ +# For SAI3.7 + libprotobuf-dev ## Config dpkg ## install the configuration file if it’s currently missing From 1e05a41c7f8e8f8b06cc9dd6c6de510241f5cb58 Mon Sep 17 00:00:00 2001 From: Polly Hsu Date: Thu, 19 Dec 2019 03:09:19 +0800 Subject: [PATCH 34/66] [device][accton]: Update for AS7326-56X complying the BCM SAI 3.5.3.1m-26 (#3830) * [device][accton]: Update for AS7326-56X complying the Broadcom SAI latest version 3.5.3.1m-26 * Update Accton-AS7326-56X to adapt xxx.config.bcm based on the latest update of Device-Specific File Directory Structure. * Update Accton-AS7326-56X LED BIN complying the Broadcom SAI latest version 3.5.3.1m-26 Signed-off-by: polly_hsu@edge-core.com * [device][accton]: Merge the SDK config with #3103 (Fix Accton as7326 port breakouk) Signed-off-by: Polly Hsu --- .../Accton-AS7326-56X/sai.profile | 2 +- .../td3-as7326-48x25G+8x100G.config.bcm | 3 +++ .../x86_64-accton_as7326_56x-r0/custom_led.bin | Bin 0 -> 1092 bytes .../led_proc_init.soc | 6 ++++++ .../linkscan_led_fw.bin | Bin 0 -> 4716 bytes 5 files changed, 10 insertions(+), 1 deletion(-) mode change 100644 => 100755 device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile create mode 100755 device/accton/x86_64-accton_as7326_56x-r0/custom_led.bin create mode 100755 device/accton/x86_64-accton_as7326_56x-r0/led_proc_init.soc create mode 100755 device/accton/x86_64-accton_as7326_56x-r0/linkscan_led_fw.bin diff --git a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile old mode 100644 new mode 100755 index 0e465ce12edd..47e3107477a2 --- a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile +++ b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/etc/bcm/td3-as7326-48x25G+8x100G.config.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-as7326-48x25G+8x100G.config.bcm diff --git a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/td3-as7326-48x25G+8x100G.config.bcm b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/td3-as7326-48x25G+8x100G.config.bcm index 2b7b6fb08007..1a4b7da32df3 100755 --- a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/td3-as7326-48x25G+8x100G.config.bcm +++ b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/td3-as7326-48x25G+8x100G.config.bcm @@ -17,6 +17,7 @@ l2xmsg_mode=1 bcm_num_cos=8 bcm_stat_interval=2000000 cdma_timeout_usec=3000000 +ifp_inports_support_enable=1 ipv6_lpm_128b_enable=0x1 l3_max_ecmp_mode=1 l3_alpm_enable=2 @@ -24,11 +25,13 @@ lpm_scaling_enable=0 max_vp_lags=0 miim_intr_enable=0 module_64ports=1 +port_flex_enable=1 schan_intr_enable=0 stable_size=0x5500000 tdma_timeout_usec=3000000 skip_L2_USER_ENTRY=0 bcm_tunnel_term_compatible_mode=1 +l3_alpm_ipv6_128b_bkt_rsvd=1 dport_map_port_1=6 dport_map_port_2=2 diff --git a/device/accton/x86_64-accton_as7326_56x-r0/custom_led.bin b/device/accton/x86_64-accton_as7326_56x-r0/custom_led.bin new file mode 100755 index 0000000000000000000000000000000000000000..8495c821680117741b78205c42c959878fbfd2b4 GIT binary patch literal 1092 zcmZwGT~E_c7zgmvuCxO(gdj5Th#e(_w-8`NVW^B14rWAArU)zu8^lcU0>ujiUncVd zs3QhCjS1d)VTj0`B=Z}r(F-FtBV2f4OqOT@8k71j8wQL`emOaPdY*sJNt;@YEDO{| zi9#IV@+V|8^uAAUMm@iDQd!!&VkJ?TR#O*sQj*I3DIBY+|A9(TuY7#P>UQp}{@ymL z-*s;#d1|h)dEHIuno4bRj*U^GD1q$qU?8u2DX6)!KL74aC2;P+_Icnn{OfH zU@IZ>z!5@tuz&zrAc6!|ut6RifP5%|Lr@HMI09vG6l8EfIVey8)ldVqPzR0B1WsrM zyaI7S8=QcXa0=SN4ISVC6*{2{7<9vFI0I*)7tX;&=!Z)%0K;$@Mqm^I5QH%phpTW6 zCg3{UfSWJ{x8OF+z%1N>yKoQgLl_=F1dPlT2@Tr0R_nA{w$L%z9cSrz?zFX5Ok~&c z2_j3i7M+v1Brh9ZCcAg*S#6)+2sOE%qD1t57mEG9Ww03JxvB2RWV;DA!ABdniw zvEo5*u)(UYU+D;kSR zVuDvVt8R{tHG}c1RwXY13`j|!47@s7S1W%^#zc#|`A@MP)T9QOrV5n92nZLvz z(irEgPPEYT%-D(`xmfS(@pbM`Ui651RN@m{EGBUu!wOZ?&rcyuP)WV0r{}YVn-f$% zsWLxDRkMF=r+;gvzYqQGy6ZpvrN8}o^j{~t37$-XHIv{q2#-YUt02kOOPRav#vHTo zRF#l?7^7L|uuqK*cYX^^&<5mJ<8%sl@=JTZ{&TX69^1bB7~Vd;g5R@4vqO#%N4^!= s7Tw3zk!9}I9A`o~u^4&Q$1l@&kC?_@veX(rr}jGh7!6>K&CmjW02uKW<^TWy literal 0 HcmV?d00001 diff --git a/device/accton/x86_64-accton_as7326_56x-r0/led_proc_init.soc b/device/accton/x86_64-accton_as7326_56x-r0/led_proc_init.soc new file mode 100755 index 000000000000..01b49772c0ba --- /dev/null +++ b/device/accton/x86_64-accton_as7326_56x-r0/led_proc_init.soc @@ -0,0 +1,6 @@ +#led auto off +#led stop +m0 load 0 0x0 /usr/share/sonic/platform/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin +led auto on +led start diff --git a/device/accton/x86_64-accton_as7326_56x-r0/linkscan_led_fw.bin b/device/accton/x86_64-accton_as7326_56x-r0/linkscan_led_fw.bin new file mode 100755 index 0000000000000000000000000000000000000000..a6a4794ecc2bfa213cd2dfcbb38f743421708819 GIT binary patch literal 4716 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 Date: Thu, 19 Dec 2019 07:15:27 -0800 Subject: [PATCH 35/66] [caclmgrd] Fix application of IPv6 service ACL rules (#3917) --- files/image_config/caclmgrd/caclmgrd | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index 5e8d83074de1..6226bb16768f 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -194,13 +194,14 @@ class ControlPlaneAclManager(object): continue # If we haven't determined the IP version for this ACL table yet, - # try to do it now. We determine heuristically based on whether the - # src IP is an IPv4 or IPv6 address. - if not table_ip_version and "SRC_IP" in rule_props and rule_props["SRC_IP"]: - ip_addr = ipaddress.IPAddress(rule_props["SRC_IP"].split("/")[0]) - if isinstance(ip_addr, ipaddress.IPv6Address): + # try to do it now. We attempt to determine heuristically based on + # whether the src or dst IP of this rule is an IPv4 or IPv6 address. + if not table_ip_version: + if (("SRC_IPV6" in rule_props and rule_props["SRC_IPV6"]) or + ("DST_IPV6" in rule_props and rule_props["DST_IPV6"])): table_ip_version = 6 - elif isinstance(ip_addr, ipaddress.IPv4Address): + elif (("SRC_IP" in rule_props and rule_props["SRC_IP"]) or + ("DST_IP" in rule_props and rule_props["DST_IP"])): table_ip_version = 4 # If we were unable to determine whether this ACL table contains From b6ad09aa352370e6e69fd609802dfd74ea8cd00e Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Mon, 23 Dec 2019 11:15:08 +0200 Subject: [PATCH 36/66] [syncd.sh] remove chipdown on mellanox (#3926) ASIC reset events are captured by hw-mgmt and hw-mgmt calls chipup/chipdown internally without OS iteraction Signed-off-by: Stepan Blyschak --- files/scripts/syncd.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 89f15f0f413f..05e5552a64b1 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -111,7 +111,6 @@ start() { /bin/systemctl stop pmon debug "pmon is active while syncd starting, stop it first" fi - /usr/bin/hw-management.sh chipdown fi if [[ x"$BOOT_TYPE" == x"fast" ]]; then From ed2d5f8a32f1deffb6e8a59c4b153b36f7c30e16 Mon Sep 17 00:00:00 2001 From: Wataru Ishida <5915117+ishidawataru@users.noreply.github.com> Date: Mon, 23 Dec 2019 10:27:22 -0800 Subject: [PATCH 37/66] [broadcom]: respect the current network namespace when creating netdev (#3896) https://github.com/Broadcom-Switch/OpenNSL/issues/26 Signed-off-by: Wataru Ishida --- .../systems/linux/kernel/modules/bcm-knet/bcm-knet.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c index 0c91c3ecd5f7..077386e6dcbc 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c @@ -6165,6 +6165,10 @@ bkn_init_ndev(u8 *mac, char *name) strncpy(dev->name, name, IFNAMSIZ-1); } +#ifdef CONFIG_NET_NS + dev_net_set(dev, current->nsproxy->net_ns); +#endif + /* Register the kernel Ethernet device */ if (register_netdev(dev)) { DBG_WARN(("Error registering Ethernet device.\n")); From 183c945ab109d541083123277d9553863cd44df8 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Mon, 23 Dec 2019 20:34:22 +0200 Subject: [PATCH 38/66] [slave.mk] use curl instead of wget (#3939) wget creates empty file on failure which makes subsequent make runs think that file is already there and won't try to download it again. e.g.: $ make target/files/stretch/fw-SPC-rel-13_2000_2602-EVB.mfa ... Fails to download ... $ ls target/files/stretch/fw-SPC-rel-13_2000_2602-EVB.mfa target/files/stretch/fw-SPC-rel-13_2000_2602-EVB.mfa $ make target/files/stretch/fw-SPC-rel-13_2000_2602-EVB.mfa make: `target/files/stretch/fw-SPC-rel-13_2000_2602-EVB.mfa' is up to date. Signed-off-by: Stepan Blyschak --- slave.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/slave.mk b/slave.mk index 44b903ddf9c9..f62be5672221 100644 --- a/slave.mk +++ b/slave.mk @@ -256,7 +256,7 @@ SONIC_TARGET_LIST += $(addprefix $(FILES_PATH)/, $(SONIC_COPY_FILES)) $(addprefix $(DEBS_PATH)/, $(SONIC_ONLINE_DEBS)) : $(DEBS_PATH)/% : .platform $(HEADER) $(foreach deb,$* $($*_DERIVED_DEBS), \ - { wget --no-use-server-timestamps -O $(DEBS_PATH)/$(deb) $($(deb)_URL) $(LOG) || exit 1 ; } ; ) + { curl -f -o $(DEBS_PATH)/$(deb) $($(deb)_URL) $(LOG) || { exit 1 ; } } ; ) $(FOOTER) SONIC_TARGET_LIST += $(addprefix $(DEBS_PATH)/, $(SONIC_ONLINE_DEBS)) @@ -269,7 +269,7 @@ SONIC_TARGET_LIST += $(addprefix $(DEBS_PATH)/, $(SONIC_ONLINE_DEBS)) # SONIC_ONLINE_FILES += $(SOME_NEW_FILE) $(addprefix $(FILES_PATH)/, $(SONIC_ONLINE_FILES)) : $(FILES_PATH)/% : .platform $(HEADER) - wget --no-use-server-timestamps -O $@ $($*_URL) $(LOG) + curl -f -o $@ $($*_URL) $(LOG) $(FOOTER) SONIC_TARGET_LIST += $(addprefix $(FILES_PATH)/, $(SONIC_ONLINE_FILES)) @@ -631,7 +631,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ # Pass initramfs and linux kernel explicitly. They are used for all platforms export debs_path="$(STRETCH_DEBS_PATH)" export files_path="$(FILES_PATH)" - export python_debs_path="$(PYTHON_DEBS_PATH)" + export python_debs_path="$(PYTHON_DEBS_PATH)" export initramfs_tools="$(STRETCH_DEBS_PATH)/$(INITRAMFS_TOOLS)" export linux_kernel="$(STRETCH_DEBS_PATH)/$(LINUX_KERNEL)" export onie_recovery_image="$(FILES_PATH)/$(ONIE_RECOVERY_IMAGE)" From 87f70108cb240c484dff6913500e56eda8c1bdb5 Mon Sep 17 00:00:00 2001 From: Prabhu Sreenivasan <45380242+PrabhuSreenivasan@users.noreply.github.com> Date: Tue, 24 Dec 2019 11:17:16 +0530 Subject: [PATCH 39/66] SONiC Management Framework Release 1.0 (#3488) * Added sonic-mgmt-framework as submodule / docker * fix build issues * update sonic-mgmt-framework submodule branch to master * Merged changes 70007e6d2ba3a4c0b371cd693ccc63e0a8906e77..00d4fcfed6a759e40d7b92120ea0ee1f08300fc6 00d4fcfed6a759e40d7b92120ea0ee1f08300fc6 Modified environemnt variables * Changes to build sonic-mgmt-framework docker * bumped up sonic-mgmt-framework commit-id * version bump for sonic-mgmt-framework commit-it * bumped up sonic-mgmt-framework commit-id * Add python packages to docker * Build fix for docker with python packages * added libyang as dependent package * Allow building images on NFS-mounted clones Prior to this change, `build_debian.sh` would generate a Debian filesystem in `./fsroot`. This needs root permissions, and one of the tests that is performed is whether the user can create a character special file in the filesystem (using mknod). On most NFS deployments, `root` is the least privileged user, and cannot run mknod. Also, attempting to run commands like rm or mv as root would fail due to permission errors, since the root user gets mapped to an unprivileged user like `nobody`. This commit changes the location of the Debian filesystem to `/fsroot`, which is a tmpfs mount within the slave Docker. The default squashfs, docker tarball and zip files are also created within /tmp, before being copied back to /sonic as the regular user. The side effect of this change is that the contents of `/fsroot` are no longer available once the slave container exits, however they are available within the squashfs image. Signed-off-by: Nirenjan Krishnan * bumped up sonc-mgmt-framework commit to include PR #18 * REST Server startup script is enahnced to read the settings from ConfigDB. Below table provides mapping of db field to command line argument name. ============================================================ ConfigDB entry key Field name REST Server argument ============================================================ REST_SERVER|default port -port REST_SERVER|default client_auth -client_auth REST_SERVER|default log_level -v DEVICE_METADATA|x509 server_crt -cert DEVICE_METADATA|x509 server_key -key DEVICE_METADATA|x509 ca_crt -cacert ============================================================ * Replace src/telemetry as submodule to sonic-telemetry * Update telemetry commit HEAD * Update sonic-telemetry commit HEAD * libyang env path update * Add libyang dependency to telemetry * Add scripts to create JSON files for CLI backend Scripts to create /var/platform/syseeprom and /var/platform/system, which are back-end files for CLI, for system EEPROM and system information. Signed-off-by: Howard Persh * In startup script, create directory where CLI back-end files live Signed-off-by: Howard Persh * build dependency pkgs added to docker for build failure fix * Changes to fix build issue for mgmt framework * Fix exec path issue with telemetry * s5232[device] PSU detecttion and default led state support * Processing of first boot in rc.local should not have premature exit Signed-off-by: Howard Persh * docker mount options added for platform, system features * bumped up sonic-mgmt-framework commit id to pick 23rd July 2019 changes * Added mount options for telemetry docker to get access for system and platform info. * Update commit for sonic-utilities * [dell]: Corrected dport map and renamed config files for S5232F * Fix telemetry submodule commit * added support for sonic-cli console * [Dell S5232F, Z9264F] Harden FPGA driver kernel module For Dell S5232F and Z9264F platforms, be more strict when checking state in ISR of FPGA driver, to harden against spurious interrupts. Signed-off-by: Howard Persh * update mgmt-framework submodule to 27th Aug commit. * remove changes not related to mgmt-framework and sonic-telemetry * Revert "Replace src/telemetry as submodule to sonic-telemetry" This reverts commit 11c31929759a17122782d4944066a6ac8453b78d. * Revert "Replace src/telemetry as submodule to sonic-telemetry" This reverts commit 11c31929759a17122782d4944066a6ac8453b78d. * make submodule changes and remove a change not related to PR * more changes * Update .gitmodules * Update Dockerfile.j2 * Update .gitmodules * Update .gitmodules * Update .gitmodules reverting experimental change * Removed syspoll for release_1.0 Signed-off-by: Jeff Yin <29264773+jeff-yin@users.noreply.github.com> * Update docker-sonic-mgmt-framework.mk * Update sonic-mgmt-framework.mk * Update sonic-mgmt-framework.mk * Update docker-sonic-mgmt-framework.mk * Update docker-sonic-mgmt-framework.mk * Revert "Processing of first boot in rc.local should not have premature exit" This reverts commit e99a91ffc28a0fd13f4ad458719d2511c3665431. * Remove old telemetry directory * Update docker-sonic-mgmt-framework.mk * Resolving merge conflict with Azure * Reverting the wrong merge * Use CVL_SCHEMA_PATH instead of changing directory for telemetry startup * Add missing export * Add python mmh3 to slave dockerfile * Remove sonic-mgmt-framework build dep for telemetry, fix dialout startup issues * Provided flag to disable compiling mgmt-framework * Update sonic-utilites point latest commit id * Point sonic-utilities to Azure accepted SHA * Updating mgmt framework to right sha * Add sonic-telemetry submodule * Update the mgmt-framework commit id Co-authored-by: jghalam Co-authored-by: Partha Dutta <51353699+dutta-partha@users.noreply.github.com> Co-authored-by: srideepDell Co-authored-by: nirenjan Co-authored-by: Sachin Holla <51310506+sachinholla@users.noreply.github.com> Co-authored-by: Eric Seifert Co-authored-by: Howard Persh Co-authored-by: Jeff Yin <29264773+jeff-yin@users.noreply.github.com> Co-authored-by: Arunsundar Kannan <31632515+arunsundark@users.noreply.github.com> Co-authored-by: rvasanthm <51932293+rvasanthm@users.noreply.github.com> Co-authored-by: Ashok Daparthi-Dell Co-authored-by: anand-kumar-subramanian <51383315+anand-kumar-subramanian@users.noreply.github.com> --- .gitmodules | 6 +++ .../docker-sonic-mgmt-framework/Dockerfile.j2 | 42 +++++++++++++++ .../base_image_files/sonic-cli | 4 ++ .../rest-server.sh | 52 +++++++++++++++++++ dockers/docker-sonic-mgmt-framework/start.sh | 10 ++++ .../supervisord.conf | 28 ++++++++++ dockers/docker-sonic-telemetry/dialout.sh | 2 +- .../docker-sonic-telemetry/supervisord.conf | 4 +- dockers/docker-sonic-telemetry/telemetry.sh | 1 + .../build_templates/mgmt-framework.service.j2 | 14 +++++ files/image_config/platform/rc.local | 3 ++ rules/config | 3 ++ rules/docker-sonic-mgmt-framework.mk | 34 ++++++++++++ rules/docker-telemetry.mk | 1 + rules/sonic-mgmt-framework.mk | 16 ++++++ rules/telemetry.mk | 4 +- sonic-slave-stretch/Dockerfile.j2 | 3 ++ src/sonic-mgmt-framework | 1 + src/sonic-telemetry | 1 + src/telemetry/Makefile | 20 ------- src/telemetry/debian/changelog | 5 -- src/telemetry/debian/compat | 1 - src/telemetry/debian/control | 17 ------ src/telemetry/debian/rules | 3 -- src/telemetry/debian/telemetry.init.d | 14 ----- 25 files changed, 225 insertions(+), 64 deletions(-) create mode 100644 dockers/docker-sonic-mgmt-framework/Dockerfile.j2 create mode 100755 dockers/docker-sonic-mgmt-framework/base_image_files/sonic-cli create mode 100755 dockers/docker-sonic-mgmt-framework/rest-server.sh create mode 100755 dockers/docker-sonic-mgmt-framework/start.sh create mode 100644 dockers/docker-sonic-mgmt-framework/supervisord.conf create mode 100644 files/build_templates/mgmt-framework.service.j2 create mode 100644 rules/docker-sonic-mgmt-framework.mk create mode 100644 rules/sonic-mgmt-framework.mk create mode 160000 src/sonic-mgmt-framework create mode 160000 src/sonic-telemetry delete mode 100644 src/telemetry/Makefile delete mode 100644 src/telemetry/debian/changelog delete mode 100644 src/telemetry/debian/compat delete mode 100644 src/telemetry/debian/control delete mode 100755 src/telemetry/debian/rules delete mode 100644 src/telemetry/debian/telemetry.init.d diff --git a/.gitmodules b/.gitmodules index b2ffb2b26fff..0cccf14a8e94 100644 --- a/.gitmodules +++ b/.gitmodules @@ -66,6 +66,12 @@ [submodule "platform/mellanox/mlnx-sai/SAI-Implementation"] path = platform/mellanox/mlnx-sai/SAI-Implementation url = https://github.com/Mellanox/SAI-Implementation +[submodule "src/sonic-mgmt-framework"] + path = src/sonic-mgmt-framework + url = https://github.com/Azure/sonic-mgmt-framework +[submodule "src/sonic-telemetry"] + path = src/sonic-telemetry + url = https://github.com/Azure/sonic-telemetry [submodule "Switch-SDK-drivers"] path = platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers url = https://github.com/Mellanox/Switch-SDK-drivers diff --git a/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 new file mode 100644 index 000000000000..08c819c1cc14 --- /dev/null +++ b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 @@ -0,0 +1,42 @@ +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 +RUN pip install connexion==1.1.15 \ + setuptools==21.0.0 \ + grpcio-tools==1.20.0 \ + pyangbind==0.6.0 \ + certifi==2017.4.17 \ + python-dateutil==2.6.0 \ + six==1.11.0 \ + urllib3==1.21.1 + + + +## Install redis-tools dependencies +## TODO: implicitly install dependencies +RUN apt-get -y install libjemalloc1 libatomic1 liblua5.1-0 lua-bitop lua-cjson + +COPY \ +{% for deb in docker_sonic_mgmt_framework_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor -%} +debs/ + +RUN dpkg -i \ +{% for deb in docker_sonic_mgmt_framework_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor %} + +COPY ["start.sh", "rest-server.sh", "/usr/bin/"] +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] + +RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y +RUN rm -rf /debs + +ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-sonic-mgmt-framework/base_image_files/sonic-cli b/dockers/docker-sonic-mgmt-framework/base_image_files/sonic-cli new file mode 100755 index 000000000000..6675e3badbaf --- /dev/null +++ b/dockers/docker-sonic-mgmt-framework/base_image_files/sonic-cli @@ -0,0 +1,4 @@ +#!/bin/bash + +docker exec -it mgmt-framework /usr/sbin/cli/clish_start "$@" + diff --git a/dockers/docker-sonic-mgmt-framework/rest-server.sh b/dockers/docker-sonic-mgmt-framework/rest-server.sh new file mode 100755 index 000000000000..f2a29c9b1ed2 --- /dev/null +++ b/dockers/docker-sonic-mgmt-framework/rest-server.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +# Startup script for SONiC Management REST Server + +SERVER_PORT= +LOG_LEVEL= +CLIENT_AUTH= +SERVER_CRT= +SERVER_KEY= +CA_CERT= + +# Read basic server settings from REST_SERVER|default entry +HAS_REST_CONFIG=$(sonic-cfggen -d -v "1 if REST_SERVER and REST_SERVER['default']") +if [ "$HAS_REST_CONFIG" == "1" ]; then + SERVER_PORT=$(sonic-cfggen -d -v "REST_SERVER['default']['port']") + CLIENT_AUTH=$(sonic-cfggen -d -v "REST_SERVER['default']['client_auth']") + LOG_LEVEL=$(sonic-cfggen -d -v "REST_SERVER['default']['log_level']") +fi + +# Read certificate file paths from DEVICE_METADATA|x509 entry. +HAS_X509_CONFIG=$(sonic-cfggen -d -v "1 if DEVICE_METADATA and DEVICE_METADATA['x509']") +if [ "$HAS_X509_CONFIG" == "1" ]; then + SERVER_CRT=$(sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_crt']") + SERVER_KEY=$(sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_key']") + CA_CRT=$(sonic-cfggen -d -v "DEVICE_METADATA['x509']['ca_crt']") +fi + +# Create temporary server certificate if they not configured in ConfigDB +if [ -z $SERVER_CRT ] && [ -z $SERVER_KEY ]; then + echo "Generating temporary TLS server certificate ..." + (cd /tmp && /usr/sbin/generate_cert --host="localhost,127.0.0.1") + SERVER_CRT=/tmp/cert.pem + SERVER_KEY=/tmp/key.pem +fi + + +REST_SERVER_ARGS="-ui /rest_ui -logtostderr" +[ ! -z $SERVER_PORT ] && REST_SERVER_ARGS+=" -port $SERVER_PORT" +[ ! -z $LOG_LEVEL ] && REST_SERVER_ARGS+=" -v $LOG_LEVEL" +[ ! -z $CLIENT_AUTH ] && REST_SERVER_ARGS+=" -client_auth $CLIENT_AUTH" +[ ! -z $SERVER_CRT ] && REST_SERVER_ARGS+=" -cert $SERVER_CRT" +[ ! -z $SERVER_KEY ] && REST_SERVER_ARGS+=" -key $SERVER_KEY" +[ ! -z $CA_CRT ] && REST_SERVER_ARGS+=" -cacert $CA_CRT" + +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-mgmt-framework/start.sh b/dockers/docker-sonic-mgmt-framework/start.sh new file mode 100755 index 000000000000..24d355670e87 --- /dev/null +++ b/dockers/docker-sonic-mgmt-framework/start.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +mkdir -p /var/sonic +echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status + +rm -f /var/run/rsyslogd.pid + +supervisorctl start rsyslogd + +supervisorctl start rest-server diff --git a/dockers/docker-sonic-mgmt-framework/supervisord.conf b/dockers/docker-sonic-mgmt-framework/supervisord.conf new file mode 100644 index 000000000000..e26f815f5fb9 --- /dev/null +++ b/dockers/docker-sonic-mgmt-framework/supervisord.conf @@ -0,0 +1,28 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[program:start.sh] +command=/usr/bin/start.sh +priority=1 +autostart=true +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n +priority=2 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:rest-server] +command=/usr/bin/rest-server.sh +priority=3 +autostart=false +autorestart=true +stdout_logfile=syslog +stderr_logfile=syslog diff --git a/dockers/docker-sonic-telemetry/dialout.sh b/dockers/docker-sonic-telemetry/dialout.sh index 8683e8edae8e..485c3292d0df 100755 --- a/dockers/docker-sonic-telemetry/dialout.sh +++ b/dockers/docker-sonic-telemetry/dialout.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Start with default config - +export CVL_SCHEMA_PATH=/usr/sbin/schema exec /usr/sbin/dialout_client_cli -insecure -logtostderr -v 2 diff --git a/dockers/docker-sonic-telemetry/supervisord.conf b/dockers/docker-sonic-telemetry/supervisord.conf index b6a01de58a7b..e1346fe7db4e 100644 --- a/dockers/docker-sonic-telemetry/supervisord.conf +++ b/dockers/docker-sonic-telemetry/supervisord.conf @@ -6,8 +6,8 @@ nodaemon=true [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener events=PROCESS_STATE_EXITED -autostart=always -autorestart=unexpected +autostart=true +autorestart=false [program:start.sh] command=/usr/bin/start.sh diff --git a/dockers/docker-sonic-telemetry/telemetry.sh b/dockers/docker-sonic-telemetry/telemetry.sh index 8cfd8a531cca..8b29b4d616a5 100755 --- a/dockers/docker-sonic-telemetry/telemetry.sh +++ b/dockers/docker-sonic-telemetry/telemetry.sh @@ -6,6 +6,7 @@ X509=`sonic-cfggen -d -v "DEVICE_METADATA['x509']"` TELEMETRY=`sonic-cfggen -d -v 'TELEMETRY.keys() | join(" ") if TELEMETRY'` 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']"` diff --git a/files/build_templates/mgmt-framework.service.j2 b/files/build_templates/mgmt-framework.service.j2 new file mode 100644 index 000000000000..d0a030347b51 --- /dev/null +++ b/files/build_templates/mgmt-framework.service.j2 @@ -0,0 +1,14 @@ +[Unit] +Description=Management Framework container +Requires=swss.service +After=swss.service +Before=ntp-config.service + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start +ExecStart=/usr/bin/{{docker_container_name}}.sh wait +ExecStop=/usr/bin/{{docker_container_name}}.sh stop + +[Install] +WantedBy=multi-user.target diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index b74e9f40c4b0..d64ec1bb7916 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -331,4 +331,7 @@ if [ -f $FIRST_BOOT_FILE ]; then firsttime_exit fi +# Create dir where following scripts put their output files +mkdir -p /var/platform + exit 0 diff --git a/rules/config b/rules/config index c158fcc27726..a559a5b2fc88 100644 --- a/rules/config +++ b/rules/config @@ -101,3 +101,6 @@ DEFAULT_VS_PREPARE_MEM = yes # ENABLE_SYSTEM_SFLOW - build docker-sonic-sflow for sFlow support ENABLE_SFLOW = y + +# ENABLE_MGMT_FRAMEWORK - build docker-sonic-mgt-framework for CLI and REST server support +ENABLE_MGMT_FRAMEWORK = y diff --git a/rules/docker-sonic-mgmt-framework.mk b/rules/docker-sonic-mgmt-framework.mk new file mode 100644 index 000000000000..eb99f37875fc --- /dev/null +++ b/rules/docker-sonic-mgmt-framework.mk @@ -0,0 +1,34 @@ +# docker image for mgmt-framework + +DOCKER_MGMT_FRAMEWORK_STEM = docker-sonic-mgmt-framework +DOCKER_MGMT_FRAMEWORK = $(DOCKER_MGMT_FRAMEWORK_STEM).gz +DOCKER_MGMT_FRAMEWORK_DBG = $(DOCKER_MGMT_FRAMEWORK_STEM)-$(DBG_IMAGE_MARK).gz + +$(DOCKER_MGMT_FRAMEWORK)_PATH = $(DOCKERS_PATH)/$(DOCKER_MGMT_FRAMEWORK_STEM) + +$(DOCKER_MGMT_FRAMEWORK)_DEPENDS += $(REDIS_TOOLS) $(SONIC_MGMT_FRAMEWORK) +$(DOCKER_MGMT_FRAMEWORK)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_MGMT_FRAMEWORK)_DBG_DEPENDS += $(REDIS_TOOLS) $(SONIC_MGMT_FRAMEWORK_DBG) + +SONIC_DOCKER_IMAGES += $(DOCKER_MGMT_FRAMEWORK) +$(DOCKER_MGMT_FRAMEWORK)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_MGMT_FRAMEWORK)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) + +ifeq ($(ENABLE_MGMT_FRAMEWORK), y) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_MGMT_FRAMEWORK) +SONIC_STRETCH_DOCKERS += $(DOCKER_MGMT_FRAMEWORK) +endif + +SONIC_DOCKER_DBG_IMAGES += $(DOCKER_MGMT_FRAMEWORK_DBG) +ifeq ($(ENABLE_MGMT_FRAMEWORK), y) +SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_MGMT_FRAMEWORK_DBG) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_MGMT_FRAMEWORK_DBG) +endif + +$(DOCKER_MGMT_FRAMEWORK)_CONTAINER_NAME = mgmt-framework +$(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += --net=host --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/" + +$(DOCKER_MGMT_FRAMEWORK)_BASE_IMAGE_FILES += sonic-cli:/usr/bin/sonic-cli diff --git a/rules/docker-telemetry.mk b/rules/docker-telemetry.mk index defeb4d00821..799bef1b1735 100644 --- a/rules/docker-telemetry.mk +++ b/rules/docker-telemetry.mk @@ -27,5 +27,6 @@ endif $(DOCKER_TELEMETRY)_CONTAINER_NAME = telemetry $(DOCKER_TELEMETRY)_RUN_OPT += --net=host --privileged -t $(DOCKER_TELEMETRY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_TELEMETRY)_RUN_OPT += --mount type=bind,source="/var/platform/",target="/mnt/platform/" $(DOCKER_TELEMETRY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/sonic-mgmt-framework.mk b/rules/sonic-mgmt-framework.mk new file mode 100644 index 000000000000..a57ce6b1b083 --- /dev/null +++ b/rules/sonic-mgmt-framework.mk @@ -0,0 +1,16 @@ +# SONiC mgmt-framework package + +ifeq ($(ENABLE_MGMT_FRAMEWORK), y) + +SONIC_MGMT_FRAMEWORK = sonic-mgmt-framework_1.0-01_amd64.deb +$(SONIC_MGMT_FRAMEWORK)_SRC_PATH = $(SRC_PATH)/sonic-mgmt-framework +$(SONIC_MGMT_FRAMEWORK)_DEPENDS = $(LIBYANG_DEV) $(LIBYANG) +$(SONIC_MGMT_FRAMEWORK)_RDEPENDS = $(LIBYANG) +SONIC_DPKG_DEBS += $(SONIC_MGMT_FRAMEWORK) + +SONIC_MGMT_FRAMEWORK_DBG = sonic-mgmt-framework-dbg_1.0-01_amd64.deb +$(SONIC_MGMT_FRAMEWORK_DBG)_DEPENDS += $(SONIC_MGMT_FRAMEWORK) +$(SONIC_MGMT_FRAMEWORK_DBG)_RDEPENDS += $(SONIC_MGMT_FRAMEWORK) +$(eval $(call add_derived_package,$(SONIC_MGMT_FRAMEWORK),$(SONIC_MGMT_FRAMEWORK_DBG))) + +endif diff --git a/rules/telemetry.mk b/rules/telemetry.mk index 1d903e603251..0b4421b11942 100644 --- a/rules/telemetry.mk +++ b/rules/telemetry.mk @@ -1,5 +1,7 @@ # SONiC telemetry package SONIC_TELEMETRY = sonic-telemetry_0.1_$(CONFIGURED_ARCH).deb -$(SONIC_TELEMETRY)_SRC_PATH = $(SRC_PATH)/telemetry +$(SONIC_TELEMETRY)_SRC_PATH = $(SRC_PATH)/sonic-telemetry +$(SONIC_TELEMETRY)_DEPENDS = $(LIBYANG_DEV) $(LIBYANG) +$(SONIC_TELEMETRY)_RDEPENDS = $(LIBYANG) SONIC_DPKG_DEBS += $(SONIC_TELEMETRY) diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 08e002624abb..d0e3775396dc 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -362,6 +362,9 @@ RUN pip install mockredispy==2.9.3 RUN pip install pytest-runner==4.4 RUN pip install setuptools==40.8.0 +# For mgmt-framework build +RUN pip install mmh3 + # Install dependencies for isc-dhcp-relay build RUN apt-get -y build-dep isc-dhcp diff --git a/src/sonic-mgmt-framework b/src/sonic-mgmt-framework new file mode 160000 index 000000000000..8b199a9f822c --- /dev/null +++ b/src/sonic-mgmt-framework @@ -0,0 +1 @@ +Subproject commit 8b199a9f822ca42564a7a89da0cab3133684bd12 diff --git a/src/sonic-telemetry b/src/sonic-telemetry new file mode 160000 index 000000000000..aaa9188fda4b --- /dev/null +++ b/src/sonic-telemetry @@ -0,0 +1 @@ +Subproject commit aaa9188fda4b6f36dd5da00cdb240933fedae5ce diff --git a/src/telemetry/Makefile b/src/telemetry/Makefile deleted file mode 100644 index 91a822d4f93c..000000000000 --- a/src/telemetry/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -export GOPATH=/tmp/go - -INSTALL := /usr/bin/install - -all: sonic-telemetry - -sonic-telemetry: - /usr/local/go/bin/go get -v github.com/Azure/sonic-telemetry/telemetry - /usr/local/go/bin/go get -v github.com/Azure/sonic-telemetry/dialout/dialout_client_cli - -install: - $(INSTALL) -D ${GOPATH}/bin/telemetry $(DESTDIR)/usr/sbin/telemetry - $(INSTALL) -D ${GOPATH}/bin/dialout_client_cli $(DESTDIR)/usr/sbin/dialout_client_cli - -deinstall: - rm $(DESTDIR)/usr/sbin/telemetry - rm $(DESTDIR)/usr/sbin/dialout_client_cli - -clean: - rm -fr ${GOPATH} diff --git a/src/telemetry/debian/changelog b/src/telemetry/debian/changelog deleted file mode 100644 index 77dab629040e..000000000000 --- a/src/telemetry/debian/changelog +++ /dev/null @@ -1,5 +0,0 @@ -sonic-telemetry (0.1) UNRELEASED; urgency=medium - - * Initial release. - - -- Jipan Yang Sat, 24 Mar 2018 12:48:22 -0700 diff --git a/src/telemetry/debian/compat b/src/telemetry/debian/compat deleted file mode 100644 index ec635144f600..000000000000 --- a/src/telemetry/debian/compat +++ /dev/null @@ -1 +0,0 @@ -9 diff --git a/src/telemetry/debian/control b/src/telemetry/debian/control deleted file mode 100644 index f1b6a7c07282..000000000000 --- a/src/telemetry/debian/control +++ /dev/null @@ -1,17 +0,0 @@ -Source: sonic-telemetry -Section: devel -Priority: optional -Maintainer: Jipan Yang -Build-Depends: debhelper (>= 8.0.0), - dh-systemd -Standards-Version: 3.9.3 -Homepage: https://github.com/Azure/sonic-telemetry -XS-Go-Import-Path: github.com/Azure/sonic-telemetry - -Package: sonic-telemetry -Architecture: any -Built-Using: ${misc:Built-Using} -Depends: ${misc:Depends}, - ${shlibs:Depends} -Description: SONiC telemetry - sonic-telemetry \ No newline at end of file diff --git a/src/telemetry/debian/rules b/src/telemetry/debian/rules deleted file mode 100755 index 3995a26d7fcd..000000000000 --- a/src/telemetry/debian/rules +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/make -f -%: - dh $@ --with systemd diff --git a/src/telemetry/debian/telemetry.init.d b/src/telemetry/debian/telemetry.init.d deleted file mode 100644 index 2fea32e17c49..000000000000 --- a/src/telemetry/debian/telemetry.init.d +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -# -### BEGIN INIT INFO -# Provides: sonic-telemetry -# Required-Start: $local_fs $network $remote_fs $syslog -# Required-Stop: $local_fs $network $remote_fs $syslog -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: start and stop the telemetry -# Description: sonic-telemetry is an implementation of sonic telemetry daemon in Go -### END INIT INFO -# - -exit 0 From baea7e2a24d5e948ef47b3922839ff8066a16766 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Fri, 27 Dec 2019 19:26:51 +0200 Subject: [PATCH 40/66] [slave.mk] make curl follow HTTP redirects (#3947) Fix an issue with SONIC_ONLINE_DEBS with curl by instructing curl to follow http redirects Signed-off-by: Stepan Blyschak --- slave.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slave.mk b/slave.mk index f62be5672221..382b03607186 100644 --- a/slave.mk +++ b/slave.mk @@ -256,7 +256,7 @@ SONIC_TARGET_LIST += $(addprefix $(FILES_PATH)/, $(SONIC_COPY_FILES)) $(addprefix $(DEBS_PATH)/, $(SONIC_ONLINE_DEBS)) : $(DEBS_PATH)/% : .platform $(HEADER) $(foreach deb,$* $($*_DERIVED_DEBS), \ - { curl -f -o $(DEBS_PATH)/$(deb) $($(deb)_URL) $(LOG) || { exit 1 ; } } ; ) + { curl -L -f -o $(DEBS_PATH)/$(deb) $($(deb)_URL) $(LOG) || { exit 1 ; } } ; ) $(FOOTER) SONIC_TARGET_LIST += $(addprefix $(DEBS_PATH)/, $(SONIC_ONLINE_DEBS)) @@ -269,7 +269,7 @@ SONIC_TARGET_LIST += $(addprefix $(DEBS_PATH)/, $(SONIC_ONLINE_DEBS)) # SONIC_ONLINE_FILES += $(SOME_NEW_FILE) $(addprefix $(FILES_PATH)/, $(SONIC_ONLINE_FILES)) : $(FILES_PATH)/% : .platform $(HEADER) - curl -f -o $@ $($*_URL) $(LOG) + curl -L -f -o $@ $($*_URL) $(LOG) $(FOOTER) SONIC_TARGET_LIST += $(addprefix $(FILES_PATH)/, $(SONIC_ONLINE_FILES)) From 86ab2aee06e931cf1fb21d86de150371cf0cea60 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Fri, 27 Dec 2019 09:30:47 -0800 Subject: [PATCH 41/66] [swsssdk-py] submodule update for sonic-py-swsssdk (#3929) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit update multiDB changes in sonic-py-swsssdk, including: - read portchannel name from LAG_NAME_MAP_TABLE in COUNTERS_DB (#51) - Revert "read portchannel name from LAG_NAME_MAP_TABLE in COUNTERS_DB (#51)" (#57) - [MultiDB] sonic-db-cli should support EVAL operation, app script use … (#58) PR #3928 needs this swsssdk-py changes to work Signed-off-by: Dong Zhang d.zhang@alibaba-inc.com --- src/sonic-py-swsssdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index bc3964b788c3..ccc1307aae0b 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit bc3964b788c3a4a45f2b359a5df5934ecdee84c2 +Subproject commit ccc1307aae0b017a5c0d92385c9df67379da6d22 From 18cb5c6765a694467ab4eca733efab9ab9ad00b6 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Fri, 27 Dec 2019 19:38:39 +0200 Subject: [PATCH 42/66] [swss] submodule update (#3925) 9f6efa0 [port/buffer] introduce a sync mechanism to protect port PG/queue from changes under PFC storm (#1143) 823e426 [aclorch] Enable DSCP rules on IPv6 mirror tables (#1146) b8745f8 [bitmap_vnet]: Fix removal flow for tunnel route (#1139) 03be983 Increase ip2me CIR/CBR for faster in-band file transfers (#1000) a4a1d3b [vnet]: Update VNET route table size to 40K for BITMAP implementation (#1132) efe142a Fix bug: Wrong condition for mac address (#1142) 7bf63a0 [teammgrd]during warm-reboot teamd need to recover system-id from saved lacp-pdu (#1003) 8b4cfb6 Cleanup configure.ac from BFN specific code (#1133) b931751 [teamsyncd]: Add retry logic in teamsyncd to avoid team handler init failure (#854) Signed-off-by: Stepan Blyschak --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index fc085ee70df1..9f6efa088d86 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit fc085ee70df1b6e4edf512bcfac212be429ab021 +Subproject commit 9f6efa088d8645572b82af590f20e8d60e9be285 From bd72844f758dbe424a07f4b4fe98d326764f2725 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 28 Dec 2019 21:21:09 +0000 Subject: [PATCH 43/66] [kvm]: increase the kvm installer size to 2G for dbg image Signed-off-by: Guohan Lu --- scripts/build_kvm_image.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build_kvm_image.sh b/scripts/build_kvm_image.sh index a8ae21c9777a..5a56ac46efce 100755 --- a/scripts/build_kvm_image.sh +++ b/scripts/build_kvm_image.sh @@ -31,7 +31,7 @@ create_disk() prepare_installer_disk() { - fallocate -l 1024M $INSTALLER_DISK + fallocate -l 2048M $INSTALLER_DISK mkfs.vfat $INSTALLER_DISK From 78db0804d3a0ab9cf54a7ddf4c4d00c7ecd8751d Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Mon, 30 Dec 2019 13:01:03 -0800 Subject: [PATCH 44/66] corefile uploader: Updates per review comments offline (#3915) * Updates per review comments 1) core_uploader service waits for syslog.service 2) core_uploader service enabled for restart on failure 3) Use mtime instead of file size + ample time to be robust. * Avoid reloading already uploaded file, by marking the names with a prefix. * Updated failing path. 1) If rc file is missing or required data missing, it periodically logs error in forever loop. 2) If upload fails, retry every hour with a error log, forever. * Fix few bugs * The binary update_json.py will come from sonic-utilities. --- .../build_templates/sonic_debian_extension.j2 | 1 - .../corefile_uploader/core_uploader.py | 47 +++++++++------- .../corefile_uploader/core_uploader.service | 6 +- .../corefile_uploader/update_json.py | 55 ------------------- 4 files changed, 32 insertions(+), 77 deletions(-) delete mode 100755 files/image_config/corefile_uploader/update_json.py diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index b63b5addac4b..a007745406e4 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -225,7 +225,6 @@ sudo cp $IMAGE_CONFIGS/hostcfgd/*.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ sudo cp $IMAGE_CONFIGS/corefile_uploader/core_uploader.service $FILESYSTEM_ROOT/etc/systemd/system/ sudo LANG=C chroot $FILESYSTEM_ROOT systemctl disable core_uploader.service sudo cp $IMAGE_CONFIGS/corefile_uploader/core_uploader.py $FILESYSTEM_ROOT/usr/bin/ -sudo cp $IMAGE_CONFIGS/corefile_uploader/update_json.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 diff --git a/files/image_config/corefile_uploader/core_uploader.py b/files/image_config/corefile_uploader/core_uploader.py index 676ff9583b06..2ae91ce0896b 100755 --- a/files/image_config/corefile_uploader/core_uploader.py +++ b/files/image_config/corefile_uploader/core_uploader.py @@ -36,7 +36,11 @@ HOURS_4 = (4 * 60 * 60) PAUSE_ON_FAIL = (60 * 60) +WAIT_FILE_WRITE1 = (10 * 60) +WAIT_FILE_WRITE2= (5 * 60) +POLL_SLEEP = (60 * 60) MAX_RETRIES = 5 +UPLOAD_PREFIX = "UPLOADED_" log_level = syslog.LOG_DEBUG @@ -116,7 +120,7 @@ def run(self): self.observer.start() try: while True: - time.sleep(5) + time.sleep(POLL_SLEEP) except: self.observer.stop() log_err("Error in watcher") @@ -179,29 +183,33 @@ def on_any_event(event): elif event.event_type == 'created': # Take any action here when a file is first created. log_debug("Received create event - " + event.src_path) + Handler.wait_for_file_write_complete(event.src_path) Handler.handle_file(event.src_path) @staticmethod def wait_for_file_write_complete(path): - ct_size = -1 + mtime = 0 - while ct_size != os.path.getsize(path): - ct_size = os.path.getsize(path) - time.sleep(2) + # Sleep for ample time enough for file dump to complete. + time.sleep(WAIT_FILE_WRITE1) - time.sleep(2) - if ct_size != os.path.getsize(path): + # Give another chance & poll until mtime stabilizes + while mtime != os.stat(path).st_mtime: + mtime = os.stat(path).st_mtime + time.sleep(10) + + # A safety pause for double confirmation + time.sleep(WAIT_FILE_WRITE2) + if mtime != os.stat(path).st_mtime: raise Exception("Dump file creation is too slow: " + path) + # Give up as something is terribly wrong with this file. log_debug("File write complete - " + path) @staticmethod def handle_file(path): - - Handler.wait_for_file_write_complete(path) - lpath = "/".join(cwd) make_new_dir(lpath) os.chdir(lpath) @@ -221,18 +229,18 @@ def handle_file(path): tar.close() log_debug("Tar file for upload created: " + tarf_name) - Handler.upload_file(tarf_name, tarf_name) + Handler.upload_file(tarf_name, tarf_name, path) log_debug("File uploaded - " + path) os.chdir(INIT_CWD) @staticmethod - def upload_file(fname, fpath): + def upload_file(fname, fpath, coref): daemonname = fname.split(".")[0] i = 0 fail_msg = "" - while i <= MAX_RETRIES: + while True: try: svc = FileService(account_name=acctname, account_key=acctkey) @@ -246,14 +254,15 @@ def upload_file(fname, fpath): svc.create_file_from_path(sharename, "/".join(l), fname, fpath) log_debug("Remote file created: name{} path{}".format(fname, fpath)) + newcoref = os.path.dirname(coref) + "/" + UPLOAD_PREFIX + os.path.basename(coref) + os.rename(coref, newcoref) break - except Exception as e: - log_err("core uploader failed: Failed during upload (" + str(e) +")") - fail_msg = str(e) + except Exception as ex: + log_err("core uploader failed: Failed during upload (" + coref + ") err: ("+ str(ex) +") retry:" + str(i)) + if not os.path.exists(fpath): + break i += 1 - if i >= MAX_RETRIES: - raise Exception("Failed while uploading. msg(" + fail_msg + ") after " + str(i) + " retries") time.sleep(PAUSE_ON_FAIL) @@ -261,7 +270,7 @@ def upload_file(fname, fpath): def scan(): for e in os.listdir(CORE_FILE_PATH): fl = CORE_FILE_PATH + e - if os.path.isfile(fl): + if os.path.isfile(fl) and not e.startswith(UPLOAD_PREFIX): Handler.handle_file(fl) diff --git a/files/image_config/corefile_uploader/core_uploader.service b/files/image_config/corefile_uploader/core_uploader.service index 5c061e72a16e..09ac1bd5191f 100644 --- a/files/image_config/corefile_uploader/core_uploader.service +++ b/files/image_config/corefile_uploader/core_uploader.service @@ -1,11 +1,13 @@ [Unit] Description=Host core file uploader daemon -Requires=updategraph.service -After=updategraph.service +Requires=syslog.service +After=syslog.service [Service] Type=simple ExecStart=/usr/bin/core_uploader.py +StandardOutput=null +Restart=on-failure [Install] WantedBy=multi-user.target diff --git a/files/image_config/corefile_uploader/update_json.py b/files/image_config/corefile_uploader/update_json.py deleted file mode 100755 index 03bb39aa4ec8..000000000000 --- a/files/image_config/corefile_uploader/update_json.py +++ /dev/null @@ -1,55 +0,0 @@ -#! /usr/bin/env python - -import os -import sys -import json -import argparse - -TMP_SUFFIX = ".tmp" -BAK_SUFFIX = ".bak" - -def dict_update(dst, patch): - for k in patch.keys(): - if type(patch[k]) == dict: - dst[k] = dict_update(dst[k], patch[k]) - else: - dst[k] = patch[k] - return dst - -def do_update(rcf, patchf): - dst = {} - patch = {} - - tmpf = rcf + TMP_SUFFIX - bakf = rcf + BAK_SUFFIX - - with open(rcf, "r") as f: - dst = json.load(f) - - with open(patchf, "r") as f: - patch = json.load(f) - - dst = dict_update(dst, patch) - - with open(tmpf, "w") as f: - json.dump(dst, f, indent = 4) - - os.rename(rcf, bakf) - os.rename(tmpf, rcf) - - -def main(): - parser=argparse.ArgumentParser(description="Update JSON based file") - parser.add_argument("-r", "--rc", help="JSON file to be updated") - parser.add_argument("-p", "--patch", help="JSON file holding patch") - args = parser.parse_args() - - if not args.rc or not args.patch: - raise Exception("check usage") - - do_update(args.rc, args.patch) - -if __name__ == '__main__': - main() - - From 08cde0600c2dc5015894a56fe8ba4f5da49f85c9 Mon Sep 17 00:00:00 2001 From: ciju-juniper <53076238+ciju-juniper@users.noreply.github.com> Date: Tue, 31 Dec 2019 07:39:32 +0530 Subject: [PATCH 45/66] [Juniper][QFX5210] Adding qos.json (#3946) Adding buffers.json.j2, buffers_defaults_t1.j2 and qos.json.j2 for qfx5210 platform. Signed-off-by: Ciju Rajan K --- .../Juniper-QFX5210-64C/buffers.json.j2 | 1 + .../buffers_defaults_t1.j2 | 46 +++++++++++++++++++ .../Juniper-QFX5210-64C/qos.json.j2 | 1 + 3 files changed, 48 insertions(+) create mode 100644 device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/buffers.json.j2 create mode 100644 device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/buffers_defaults_t1.j2 create mode 100644 device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/qos.json.j2 diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/buffers.json.j2 b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/buffers.json.j2 new file mode 100644 index 000000000000..a9a01d707ebf --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/buffers.json.j2 @@ -0,0 +1 @@ +{%- include 'buffers_config.j2' %} diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/buffers_defaults_t1.j2 b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..3442612f70b2 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/buffers_defaults_t1.j2 @@ -0,0 +1,46 @@ +{%- set default_cable = '5m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,64) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "33329088", + "type": "ingress", + "mode": "dynamic", + "xoff": "7827456" + }, + "egress_lossy_pool": { + "size": "26663272", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "42349632", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"44302336" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"42349632" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1664", + "dynamic_th":"-1" + } + }, +{%- endmacro %} diff --git a/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/qos.json.j2 b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/juniper/x86_64-juniper_qfx5210-r0/Juniper-QFX5210-64C/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} From 24a0c464648fa8d9e53d4cdfdaae7c12eaaaf95f Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Mon, 30 Dec 2019 18:25:57 -0800 Subject: [PATCH 46/66] [monit] Build from source and patch to use MemAvailable value if available on system (#3875) --- .gitignore | 3 + build_debian.sh | 5 -- .../build_templates/sonic_debian_extension.j2 | 8 +++ files/image_config/monit/conf.d/sonic-host | 22 ++++++ files/image_config/monit/monitrc | 19 +---- rules/monit.mk | 14 ++++ slave.mk | 3 +- src/monit/Makefile | 33 +++++++++ ...ry_sysdep-Use-MemAvailable-value-if-.patch | 70 +++++++++++++++++++ src/monit/patch/series | 2 + 10 files changed, 157 insertions(+), 22 deletions(-) create mode 100644 files/image_config/monit/conf.d/sonic-host create mode 100644 rules/monit.mk create mode 100644 src/monit/Makefile create mode 100644 src/monit/patch/0001-used_system_memory_sysdep-Use-MemAvailable-value-if-.patch create mode 100644 src/monit/patch/series diff --git a/.gitignore b/.gitignore index 739454168796..1f921971d8bb 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,9 @@ src/lldpd/* !src/lldpd/patch/ src/lm-sensors/* !src/lm-sensors/Makefile +src/monit/* +!src/monit/Makefile +!src/monit/patch/ src/mpdecimal/* !src/mpdecimal/Makefile src/python-click/* diff --git a/build_debian.sh b/build_debian.sh index 666e140416c9..335dab8ba89f 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -240,7 +240,6 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in openssh-server \ python \ python-setuptools \ - monit \ python-apt \ traceroute \ iputils-ping \ @@ -348,10 +347,6 @@ EOF sudo sed -i 's/^ListenAddress ::/#ListenAddress ::/' $FILESYSTEM_ROOT/etc/ssh/sshd_config sudo sed -i 's/^#ListenAddress 0.0.0.0/ListenAddress 0.0.0.0/' $FILESYSTEM_ROOT/etc/ssh/sshd_config -## Config monit -sudo cp files/image_config/monit/monitrc $FILESYSTEM_ROOT/etc/monit/ -sudo chmod 600 $FILESYSTEM_ROOT/etc/monit/monitrc - ## Config sysctl sudo mkdir -p $FILESYSTEM_ROOT/var/core sudo augtool --autosave " diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index a007745406e4..e5dd9d9e0912 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -172,6 +172,14 @@ sudo sed -i -e '/^passwd/s/ tacplus//' $FILESYSTEM_ROOT/etc/nsswitch.conf 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 +# Install custom-built monit package and SONiC configuration files +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/monit_*.deb || \ + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f +sudo cp $IMAGE_CONFIGS/monit/monitrc $FILESYSTEM_ROOT/etc/monit/ +sudo chmod 600 $FILESYSTEM_ROOT/etc/monit/monitrc +sudo cp $IMAGE_CONFIGS/monit/conf.d/* $FILESYSTEM_ROOT/etc/monit/conf.d/ +sudo chmod 600 $FILESYSTEM_ROOT/etc/monit/conf.d/* + # Copy crontabs sudo cp -f $IMAGE_CONFIGS/cron.d/* $FILESYSTEM_ROOT/etc/cron.d/ diff --git a/files/image_config/monit/conf.d/sonic-host b/files/image_config/monit/conf.d/sonic-host new file mode 100644 index 000000000000..8eaa1671d821 --- /dev/null +++ b/files/image_config/monit/conf.d/sonic-host @@ -0,0 +1,22 @@ +############################################################################### +## Monit configuration for SONiC host OS +## +## This includes system-level monitoring as well as processes which +## run in the host OS (i.e., not inside a Docker container) +############################################################################### + +check filesystem root-overlay with path / + if space usage > 90% for 5 times within 10 cycles then alert + +check filesystem var-log with path /var/log + if space usage > 90% for 5 times within 10 cycles then alert + +check system $HOST + if memory usage > 90% for 5 times within 10 cycles then alert + if cpu usage (user) > 90% for 5 times within 10 cycles then alert + if cpu usage (system) > 90% for 5 times within 10 cycles then alert + +check process rsyslog with pidfile /var/run/rsyslogd.pid + start program = "/bin/systemctl start rsyslog.service" + stop program = "/bin/systemctl stop rsyslog.service" + if totalmem > 800 MB for 5 times within 10 cycles then restart diff --git a/files/image_config/monit/monitrc b/files/image_config/monit/monitrc index f9350733fa44..7864069e3af1 100644 --- a/files/image_config/monit/monitrc +++ b/files/image_config/monit/monitrc @@ -24,8 +24,7 @@ ## Set syslog logging. If you want to log to a standalone log file instead, ## specify the full path to the log file # -# set logfile /var/log/monit.log -set logfile syslog + set logfile syslog # # ## Set the location of the Monit lock file which stores the process id of the @@ -153,8 +152,8 @@ set logfile syslog ## commands to a running Monit daemon. See the Monit Wiki if you want to ## enable SSL for the HTTP interface. # -set httpd unixsocket /var/run/monit.sock and - allow localhost # allow localhost to connect to the server and + set httpd unixsocket /var/run/monit.sock and + allow localhost # allow localhost to connect to the server # ############################################################################### ## Services @@ -294,15 +293,3 @@ set httpd unixsocket /var/run/monit.sock and include /etc/monit/conf.d/* include /etc/monit/conf-enabled/* # -check filesystem root-overlay with path / - if space usage > 90% for 5 times within 10 cycles then alert -check filesystem var-log with path /var/log - if space usage > 90% for 5 times within 10 cycles then alert -check system $HOST - if memory usage > 90% for 5 times within 10 cycles then alert - if cpu usage (user) > 90% for 5 times within 10 cycles then alert - if cpu usage (system) > 90% for 5 times within 10 cycles then alert -check process rsyslog with pidfile /var/run/rsyslogd.pid - start program = "/bin/systemctl start rsyslog.service" - stop program = "/bin/systemctl stop rsyslog.service" - if totalmem > 800 MB for 5 times within 10 cycles then restart diff --git a/rules/monit.mk b/rules/monit.mk new file mode 100644 index 000000000000..d4c73453e4a6 --- /dev/null +++ b/rules/monit.mk @@ -0,0 +1,14 @@ +# monit package + +MONIT_VERSION = 5.20.0-6 + +export MONIT_VERSION + +MONIT = monit_$(MONIT_VERSION)_$(CONFIGURED_ARCH).deb +$(MONIT)_SRC_PATH = $(SRC_PATH)/monit +SONIC_MAKE_DEBS += $(MONIT) + +SONIC_STRETCH_DEBS += $(MONIT) + +MONIT_DBG = monit-dbgsym_$(MONIT_VERSION)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(MONIT),$(MONIT_DBG))) diff --git a/slave.mk b/slave.mk index 382b03607186..9a34e5379b14 100644 --- a/slave.mk +++ b/slave.mk @@ -617,7 +617,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(IFUPDOWN2) \ $(KDUMP_TOOLS) \ $(LIBPAM_TACPLUS) \ - $(LIBNSS_TACPLUS)) \ + $(LIBNSS_TACPLUS) \ + $(MONIT)) \ $$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \ $$(addprefix $(FILES_PATH)/,$$($$*_FILES)) \ $(if $(findstring y,$(ENABLE_ZTP)),$(addprefix $(DEBS_PATH)/,$(SONIC_ZTP))) \ diff --git a/src/monit/Makefile b/src/monit/Makefile new file mode 100644 index 000000000000..4ad9edd79143 --- /dev/null +++ b/src/monit/Makefile @@ -0,0 +1,33 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +MAIN_TARGET = monit_$(MONIT_VERSION)_$(CONFIGURED_ARCH).deb +DERIVED_TARGETS = monit-dbgsym_$(MONIT_VERSION)_$(CONFIGURED_ARCH).deb + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + # Remove any stale files + rm -rf ./monit + + # Clone monit repo + git clone https://salsa.debian.org/sk-guest/monit.git + pushd ./monit + + # Reset HEAD to the commit of the proper tag + # NOTE: Using "git checkout " here detaches our HEAD, + # which stg doesn't like, so we use this method instead + # NOTE: For some reason, tags in the Debian monit repo are prefixed with "1%" + git reset --hard debian/1\%$(MONIT_VERSION) + + # Apply patches + stg init + stg import -s ../patch/series + + # Build source and Debian packages + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + popd + + # Move the newly-built .deb packages to the destination directory + mv $(DERIVED_TARGETS) $* $(DEST)/ + +$(addprefix $(DEST)/, $(DERIVED_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) diff --git a/src/monit/patch/0001-used_system_memory_sysdep-Use-MemAvailable-value-if-.patch b/src/monit/patch/0001-used_system_memory_sysdep-Use-MemAvailable-value-if-.patch new file mode 100644 index 000000000000..9c67d153cbbb --- /dev/null +++ b/src/monit/patch/0001-used_system_memory_sysdep-Use-MemAvailable-value-if-.patch @@ -0,0 +1,70 @@ +From c392362c9c1d57256b7e8ab7c77926824677fd73 Mon Sep 17 00:00:00 2001 +From: Joe LeVeque +Date: Tue, 19 Nov 2019 01:51:13 +0000 +Subject: [PATCH] [used_system_memory_sysdep] Use 'MemAvailable' value if + available + +--- + src/process/sysdep_LINUX.c | 35 +++++++++++++++++++++++------------ + 1 file changed, 23 insertions(+), 12 deletions(-) + +diff --git a/src/process/sysdep_LINUX.c b/src/process/sysdep_LINUX.c +index 0d18f85..221e785 100644 +--- a/src/process/sysdep_LINUX.c ++++ b/src/process/sysdep_LINUX.c +@@ -335,6 +335,7 @@ int getloadavg_sysdep(double *loadv, int nelem) { + boolean_t used_system_memory_sysdep(SystemInfo_T *si) { + char *ptr; + char buf[2048]; ++ unsigned long mem_available = 0UL; + unsigned long mem_free = 0UL; + unsigned long buffers = 0UL; + unsigned long cached = 0UL; +@@ -343,22 +344,32 @@ boolean_t used_system_memory_sysdep(SystemInfo_T *si) { + unsigned long swap_free = 0UL; + + if (! file_readProc(buf, sizeof(buf), "meminfo", -1, NULL)) { +- LogError("system statistic error -- cannot get real memory free amount\n"); ++ LogError("system statistic error -- cannot read /proc/meminfo\n"); + goto error; + } + +- /* Memory */ +- if (! (ptr = strstr(buf, "MemFree:")) || sscanf(ptr + 8, "%ld", &mem_free) != 1) { +- LogError("system statistic error -- cannot get real memory free amount\n"); +- goto error; ++ /* ++ * Memory ++ * ++ * First, check if the "MemAvailable" value is available on this system. If it is, we will ++ * use it. Otherwise we will attempt to calculate the amount of available memory ourself. ++ */ ++ if ((ptr = strstr(buf, "MemAvailable:")) && sscanf(ptr + 13, "%ld", &mem_available) == 1) { ++ si->total_mem = systeminfo.mem_max - (uint64_t)mem_available * 1024; ++ } else { ++ DEBUG("'MemAvailable' value not available on this system. Attempting to calculate available memory manually...\n"); ++ if (! (ptr = strstr(buf, "MemFree:")) || sscanf(ptr + 8, "%ld", &mem_free) != 1) { ++ LogError("system statistic error -- cannot get real memory free amount\n"); ++ goto error; ++ } ++ if (! (ptr = strstr(buf, "Buffers:")) || sscanf(ptr + 8, "%ld", &buffers) != 1) ++ DEBUG("system statistic error -- cannot get real memory buffers amount\n"); ++ if (! (ptr = strstr(buf, "Cached:")) || sscanf(ptr + 7, "%ld", &cached) != 1) ++ DEBUG("system statistic error -- cannot get real memory cache amount\n"); ++ if (! (ptr = strstr(buf, "SReclaimable:")) || sscanf(ptr + 13, "%ld", &slabreclaimable) != 1) ++ DEBUG("system statistic error -- cannot get slab reclaimable memory amount\n"); ++ si->total_mem = systeminfo.mem_max - (uint64_t)(mem_free + buffers + cached + slabreclaimable) * 1024; + } +- if (! (ptr = strstr(buf, "Buffers:")) || sscanf(ptr + 8, "%ld", &buffers) != 1) +- DEBUG("system statistic error -- cannot get real memory buffers amount\n"); +- if (! (ptr = strstr(buf, "Cached:")) || sscanf(ptr + 7, "%ld", &cached) != 1) +- DEBUG("system statistic error -- cannot get real memory cache amount\n"); +- if (! (ptr = strstr(buf, "SReclaimable:")) || sscanf(ptr + 13, "%ld", &slabreclaimable) != 1) +- DEBUG("system statistic error -- cannot get slab reclaimable memory amount\n"); +- si->total_mem = systeminfo.mem_max - (uint64_t)(mem_free + buffers + cached + slabreclaimable) * 1024; + + /* Swap */ + if (! (ptr = strstr(buf, "SwapTotal:")) || sscanf(ptr + 10, "%ld", &swap_total) != 1) { +-- +2.17.1 + diff --git a/src/monit/patch/series b/src/monit/patch/series new file mode 100644 index 000000000000..15fcdd50c8a5 --- /dev/null +++ b/src/monit/patch/series @@ -0,0 +1,2 @@ +# This series applies on GIT commit dc9bc1c949125140d967edfc598dfad47eedc552 +0001-used_system_memory_sysdep-Use-MemAvailable-value-if-.patch From ea1128741c28f89294c4296110dcd33dde7458d9 Mon Sep 17 00:00:00 2001 From: noaOrMlnx <58519608+noaOrMlnx@users.noreply.github.com> Date: Tue, 31 Dec 2019 17:01:08 +0200 Subject: [PATCH 47/66] [Mellanox] Update FW/SDK: 13/29.2000.2696 and 4.3.2904 (#3948) --- platform/mellanox/fw.mk | 4 ++-- platform/mellanox/sdk-src/sx-kernel/Makefile | 1 - .../sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- .../sx_kernel_makefile_sonic_build.patch | 18 ------------------ platform/mellanox/sdk.mk | 2 +- 5 files changed, 4 insertions(+), 23 deletions(-) delete mode 100644 platform/mellanox/sdk-src/sx-kernel/sx_kernel_makefile_sonic_build.patch diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 9d506c1f5bdd..eb1a58cfda9d 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,12 +11,12 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2000.2602 +MLNX_SPC_FW_VERSION = 13.2000.2696 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.2602 +MLNX_SPC2_FW_VERSION = 29.2000.2696 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) diff --git a/platform/mellanox/sdk-src/sx-kernel/Makefile b/platform/mellanox/sdk-src/sx-kernel/Makefile index 9e979879fef8..422f2ae95aae 100644 --- a/platform/mellanox/sdk-src/sx-kernel/Makefile +++ b/platform/mellanox/sdk-src/sx-kernel/Makefile @@ -19,7 +19,6 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : fi # build - patch -p1 < ../sx_kernel_makefile_sonic_build.patch debuild -e KVERSION=$(KVERSION) -e KSRC_EXT=/lib/modules/$(KVERSION)/source/ -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index 87f7a7911275..c08b5bb3810f 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 87f7a7911275285abc63c24ba39aa4af4c4b4678 +Subproject commit c08b5bb3810fe7da2811622aa7003ac9cc95344b diff --git a/platform/mellanox/sdk-src/sx-kernel/sx_kernel_makefile_sonic_build.patch b/platform/mellanox/sdk-src/sx-kernel/sx_kernel_makefile_sonic_build.patch deleted file mode 100644 index e7c87d079922..000000000000 --- a/platform/mellanox/sdk-src/sx-kernel/sx_kernel_makefile_sonic_build.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff --git a/makefile b/makefile -index f23f0ac..a16b2ce 100644 ---- a/makefile -+++ b/makefile -@@ -93,10 +93,10 @@ V ?= 1 - - ifneq ($(findstring 3.10,$(KVERSION))$(findstring 3.13,$(KVERSION))$(findstring 3.14,$(KVERSION))$(findstring 3.16,$(KVERSION)),) - MLNX_LINUX_AUTOCONF_FILE = include/generated/autoconf.h --MLNX_LINUX_EXTRA_INCLUDE_FILES = -include include/linux/kconfig.h -+MLNX_LINUX_EXTRA_INCLUDE_FILES = -include $(KSRC_EXT)/include/linux/kconfig.h - MLNX_LINUX_EXTRA_INCLUDE_FOLDERS = \ -- -Iarch/$$(SRCARCH)/include/uapi \ -- -Iinclude/uapi \ -+ -I$(KSRC_EXT)/arch/$$(SRCARCH)/include/uapi \ -+ -I$(KSRC_EXT)/include/uapi \ - -Iarch/$$(SRCARCH)/include/generated/uapi \ - -Iarch/$$(SRCARCH)/include/generated \ - -Iinclude/generated/uapi diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 73568ce84596..55a5b08bba31 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.2602 +MLNX_SDK_VERSION = 4.3.2904 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From 476be913c1238e07f1f4004638ee76dadb177cd5 Mon Sep 17 00:00:00 2001 From: lguohan Date: Tue, 31 Dec 2019 16:30:10 -0800 Subject: [PATCH 48/66] [docker-base-stretch]: Do not check expire for stretch-backports repo (#3958) * [docker-base-stretch]: Do not check expire for stretch-backports repo Signed-off-by: Guohan Lu --- build_debian.sh | 2 +- dockers/docker-base-stretch/Dockerfile.j2 | 1 + dockers/docker-base-stretch/aptconf_archive_expired_release | 3 +++ files/apt/apt.conf.d/no-check-valid-until | 1 + 4 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 dockers/docker-base-stretch/aptconf_archive_expired_release create mode 100644 files/apt/apt.conf.d/no-check-valid-until diff --git a/build_debian.sh b/build_debian.sh index 335dab8ba89f..39b984edec4e 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -107,7 +107,7 @@ sudo LANG=C chroot $FILESYSTEM_ROOT mount proc /proc -t proc ## Pointing apt to public apt mirrors and getting latest packages, needed for latest security updates sudo cp files/apt/sources.list.$CONFIGURED_ARCH $FILESYSTEM_ROOT/etc/apt/sources.list -sudo cp files/apt/apt.conf.d/{81norecommends,apt-{clean,gzip-indexes,no-languages}} $FILESYSTEM_ROOT/etc/apt/apt.conf.d/ +sudo cp files/apt/apt.conf.d/{81norecommends,apt-{clean,gzip-indexes,no-languages},no-check-valid-until} $FILESYSTEM_ROOT/etc/apt/apt.conf.d/ sudo LANG=C chroot $FILESYSTEM_ROOT bash -c 'apt-mark auto `apt-mark showmanual`' ## Note: set lang to prevent locale warnings in your chroot diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index 3b3ede376d12..d8188a06afd6 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -34,6 +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"] # 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 new file mode 100644 index 000000000000..67bc409b2174 --- /dev/null +++ b/dockers/docker-base-stretch/aptconf_archive_expired_release @@ -0,0 +1,3 @@ +# Instruct apt-get to override expired releases repo list for jessie archives + +Acquire::Check-Valid-Until "0"; diff --git a/files/apt/apt.conf.d/no-check-valid-until b/files/apt/apt.conf.d/no-check-valid-until new file mode 100644 index 000000000000..97b9c9005181 --- /dev/null +++ b/files/apt/apt.conf.d/no-check-valid-until @@ -0,0 +1 @@ +Acquire::Check-Valid-Until "false"; From 0dae59ac301f18e7dad948282addf961b69d82fc Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Thu, 2 Jan 2020 14:46:25 -0800 Subject: [PATCH 49/66] [MultiDB]except src and dockers : replace redis-cli with sonic-db-cli and use new DBConnector (#3928) * [MultiDB]except src and dockers : replace redis-cli with sonic-db-cli and use new DBConnector * fix vs tests along with swss vs tests together --- .../x86_64-mlnx_msn2700-r0/plugins/sfputil.py | 9 ++--- files/build_templates/docker_image_ctl.j2 | 34 +++++++++---------- files/image_config/config-setup/config-setup | 11 +++--- files/image_config/updategraph/updategraph | 10 +++--- .../warmboot-finalizer/finalize-warmboot.sh | 10 +++--- files/scripts/configdb-load.sh | 2 +- files/scripts/swss.sh | 26 +++++++------- files/scripts/syncd.sh | 12 +++---- .../s9180-32x/utils/qsfp_monitor.sh | 2 +- .../s9280-64x/utils/qsfp_monitor.sh | 2 +- .../s8810-32q/utils/qsfp_monitor.sh | 2 +- .../s8900-54xc/utils/qsfp_monitor.sh | 2 +- .../s8900-64xc/utils/qsfp_monitor.sh | 2 +- .../s9100/utils/qsfp_monitor.sh | 2 +- .../s9200-64x/utils/qsfp_monitor.sh | 2 +- .../s9130-32x/utils/qsfp_monitor.sh | 2 +- .../s9230-64x/utils/qsfp_monitor.sh | 2 +- 17 files changed, 60 insertions(+), 72 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index e41ac2924da2..7c4f33f74973 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -22,8 +22,6 @@ SFP_I2C_PAGE_SIZE = 256 # parameters for DB connection -REDIS_HOSTNAME = "localhost" -REDIS_PORT = 6379 REDIS_TIMEOUT_USECS = 0 # parameters for SFP presence @@ -190,10 +188,9 @@ def get_transceiver_change_event(self, timeout=0): if self.db_sel == None: from swsscommon import swsscommon - self.state_db = swsscommon.DBConnector(swsscommon.STATE_DB, - REDIS_HOSTNAME, - REDIS_PORT, - REDIS_TIMEOUT_USECS) + self.state_db = swsscommon.DBConnector("STATE_DB", + REDIS_TIMEOUT_USECS, + True)) # Subscribe to state table for SFP change notifications self.db_sel = swsscommon.Select() diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 167a392730e4..df236f6523e8 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -63,20 +63,20 @@ function preStartAction() docker cp /tmp/dump.rdb database:/var/lib/redis/ fi {%- elif docker_container_name == "snmp" %} - docker exec -i database redis-cli -n 6 HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) - vrfenabled=`/usr/bin/redis-cli -n 4 hget "MGMT_VRF_CONFIG|vrf_global" mgmtVrfEnabled` - v1SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" DestIp` - v1SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" DestPort` - v1Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" vrf` - v1Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" Community` - v2SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" DestIp` - v2SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" DestPort` - v2Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" vrf` - v2Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" Community` - v3SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" DestIp` - v3SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" DestPort` - v3Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" vrf` - v3Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" Community` + sonic-db-cli STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) + vrfenabled=`sonic-db-cli CONFIG_DB hget "MGMT_VRF_CONFIG|vrf_global" mgmtVrfEnabled` + v1SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" DestIp` + v1SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" DestPort` + v1Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" vrf` + v1Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" Community` + v2SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" DestIp` + v2SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" DestPort` + v2Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" vrf` + v2Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" Community` + v3SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" DestIp` + v3SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" DestPort` + v3Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" vrf` + v3Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" Community` if [ "${v1SnmpTrapIp}" != "" ] then @@ -113,7 +113,7 @@ function preStartAction() fi echo -n "" > /tmp/snmpagentaddr.yml - keys=`/usr/bin/redis-cli -n 4 keys "SNMP_AGENT_ADDRESS_CONFIG|*"` + keys=`sonic-db-cli CONFIG_DB keys "SNMP_AGENT_ADDRESS_CONFIG|*"` count=1 for key in $keys;do ip=`echo $key|cut -d "|" -f2` @@ -151,10 +151,10 @@ function postStartAction() if [[ "$BOOT_TYPE" == "fast" ]]; then # set the key to expire in 3 minutes - redis-cli -n 6 SET "FAST_REBOOT|system" "1" "EX" "180" + sonic-db-cli STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180" fi - redis-cli -n 4 SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" fi if [[ -x /usr/bin/db_migrator.py ]]; then diff --git a/files/image_config/config-setup/config-setup b/files/image_config/config-setup/config-setup index bd497d06b257..f19abd266e95 100755 --- a/files/image_config/config-setup/config-setup +++ b/files/image_config/config-setup/config-setup @@ -25,7 +25,6 @@ ########################################################################### # Initialize constants -CONFIG_DB_INDEX=4 UPDATEGRAPH_CONF=/etc/sonic/updategraph.conf CONFIG_DB_JSON=/etc/sonic/config_db.json MINGRAPH_FILE=/etc/sonic/minigraph.xml @@ -107,9 +106,9 @@ reload_minigraph() if [ ! -f /etc/sonic/init_cfg.json ]; then echo "{}" > /etc/sonic/init_cfg.json fi - redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-db-cli CONFIG_DB FLUSHDB sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --write-to-db - redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" if [ -f /etc/sonic/acl.json ]; then acl-loader update full /etc/sonic/acl.json fi @@ -138,7 +137,7 @@ function copy_config_files_and_directories() # Check if SONiC swich has booted after a warm reboot request check_system_warm_boot() { - SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. if [[ x"$SYSTEM_WARM_START" == x"true" ]]; then WARM_BOOT="true" @@ -187,7 +186,7 @@ load_config() return 1 fi - redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-db-cli CONFIG_DB FLUSHDB sonic-cfggen -j ${CONFIG_FILE} --write-to-db if [ $? -ne 0 ]; then return $? @@ -198,7 +197,7 @@ load_config() /usr/bin/db_migrator.py -o migrate fi - redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" return 0 } diff --git a/files/image_config/updategraph/updategraph b/files/image_config/updategraph/updategraph index b2bd027e82e7..a24d452b1ad2 100755 --- a/files/image_config/updategraph/updategraph +++ b/files/image_config/updategraph/updategraph @@ -1,16 +1,14 @@ #!/bin/bash -CONFIG_DB_INDEX=4 - reload_minigraph() { echo "Reloading minigraph..." if [ ! -f /etc/sonic/init_cfg.json ]; then echo "{}" > /etc/sonic/init_cfg.json fi - redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-db-cli CONFIG_DB FLUSHDB sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --write-to-db - redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" if [ -f /etc/sonic/acl.json ]; then acl-loader update full /etc/sonic/acl.json fi @@ -77,9 +75,9 @@ if [ "$src" = "dhcp" ]; then else cp -f /tmp/device_meta.json /etc/sonic/config_db.json fi - redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-db-cli CONFIG_DB FLUSHDB sonic-cfggen -j /etc/sonic/config_db.json --write-to-db - redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" if [ "$dhcp_as_static" = "true" ]; then sed -i "/enabled=/d" /etc/sonic/updategraph.conf echo "enabled=false" >> /etc/sonic/updategraph.conf diff --git a/files/image_config/warmboot-finalizer/finalize-warmboot.sh b/files/image_config/warmboot-finalizer/finalize-warmboot.sh index 32c9c8444cc3..eec50ccef692 100755 --- a/files/image_config/warmboot-finalizer/finalize-warmboot.sh +++ b/files/image_config/warmboot-finalizer/finalize-warmboot.sh @@ -20,7 +20,7 @@ function debug() function check_warm_boot() { - WARM_BOOT=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` + WARM_BOOT=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` } @@ -29,12 +29,10 @@ function wait_for_database_service() debug "Wait for database to become ready..." # Wait for redis server start before database clean - until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; - do sleep 1; - done + /usr/bin/docker exec database ping_pong_db_insts # Wait for configDB initialization - until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done @@ -44,7 +42,7 @@ function wait_for_database_service() function get_component_state() { - /usr/bin/redis-cli -n 6 hget "WARM_RESTART_TABLE|$1" state + sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|$1" state } diff --git a/files/scripts/configdb-load.sh b/files/scripts/configdb-load.sh index 5ba2e0e0bc7f..e7080eb40f3d 100755 --- a/files/scripts/configdb-load.sh +++ b/files/scripts/configdb-load.sh @@ -10,4 +10,4 @@ if [ -r /etc/sonic/config_db.json ]; then sonic-cfggen -j /etc/sonic/config_db.json --write-to-db fi -redis-cli -n 4 SET "CONFIG_DB_INITIALIZED" "1" +sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index 93f311019d66..a14d03e40f50 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -31,8 +31,8 @@ function unlock_service_state_change() function check_warm_boot() { - SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" else @@ -43,7 +43,7 @@ function check_warm_boot() function validate_restore_count() { if [[ x"$WARM_BOOT" == x"true" ]]; then - RESTORE_COUNT=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_TABLE|orchagent" restore_count` + RESTORE_COUNT=`sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` # We have to make sure db data has not been flushed. if [[ -z "$RESTORE_COUNT" ]]; then WARM_BOOT="false" @@ -54,12 +54,10 @@ function validate_restore_count() function wait_for_database_service() { # Wait for redis server start before database clean - until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; - do sleep 1; - done + /usr/bin/docker exec database ping_pong_db_insts # Wait for configDB initialization - until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -69,7 +67,7 @@ function wait_for_database_service() # $2 the string of a list of table prefixes function clean_up_tables() { - redis-cli -n $1 EVAL " + sonic-db-cli $1 EVAL " local tables = {$2} for i = 1, table.getn(tables) do local matches = redis.call('KEYS', tables[i]) @@ -114,11 +112,11 @@ start() { # Don't flush DB during warm boot if [[ x"$WARM_BOOT" != x"true" ]]; then debug "Flushing APP, ASIC, COUNTER, CONFIG, and partial STATE databases ..." - /usr/bin/docker exec database redis-cli -n 0 FLUSHDB - /usr/bin/docker exec database redis-cli -n 1 FLUSHDB - /usr/bin/docker exec database redis-cli -n 2 FLUSHDB - /usr/bin/docker exec database redis-cli -n 5 FLUSHDB - clean_up_tables 6 "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" + sonic-db-cli APPL_DB FLUSHDB + sonic-db-cli ASIC_DB FLUSHDB + sonic-db-cli COUNTERS_DB FLUSHDB + sonic-db-cli FLEX_COUNTER_DB FLUSHDB + clean_up_tables STATE_DB "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" fi # start service docker @@ -166,7 +164,7 @@ stop() { # encountered error, e.g. syncd crashed. And swss needs to # be restarted. debug "Clearing FAST_REBOOT flag..." - clean_up_tables 6 "'FAST_REBOOT*'" + clean_up_tables STATE_DB "'FAST_REBOOT*'" # Unlock has to happen before reaching out to peer service unlock_service_state_change diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 05e5552a64b1..4b47e7ad4c45 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -30,8 +30,8 @@ function unlock_service_state_change() function check_warm_boot() { - SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" @@ -43,12 +43,10 @@ function check_warm_boot() function wait_for_database_service() { # Wait for redis server start before database clean - until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; - do sleep 1; - done + /usr/bin/docker exec database ping_pong_db_insts # Wait for configDB initialization - until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -65,7 +63,7 @@ function getBootType() ;; *SONIC_BOOT_TYPE=fast*|*fast-reboot*) # check that the key exists - if [[ $(redis-cli -n 6 GET "FAST_REBOOT|system") == "1" ]]; then + if [[ $(sonic-db-cli STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then TYPE='fast' else TYPE='cold' diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh index 249f179216a6..7776493bc20a 100755 --- a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh index 23a3fd066bee..9213d115f656 100755 --- a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh @@ -66,7 +66,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh index 249f179216a6..7776493bc20a 100755 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh index 7f50d137bcb7..0a4ba20ab767 100644 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh @@ -67,7 +67,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh index 36f9e53ef108..b3192f2efb7a 100644 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh @@ -67,7 +67,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh index 249f179216a6..7776493bc20a 100755 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh index 51c49c1152f5..47cfbb3ea008 100755 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh @@ -66,7 +66,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh index 249f179216a6..7776493bc20a 100755 --- a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh index 23a3fd066bee..9213d115f656 100755 --- a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh @@ -66,7 +66,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi From 122124679dbcb5210efd29b9535d7f2f81b74230 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Fri, 3 Jan 2020 16:35:08 -0800 Subject: [PATCH 50/66] Update bgpcfgd with vrf support (#3952) * Implement path traversal just once * Add support of vrf to bgpcfgd --- dockers/docker-fpm-frr/bgpcfgd | 72 +++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/dockers/docker-fpm-frr/bgpcfgd b/dockers/docker-fpm-frr/bgpcfgd index 120e07fcdbe2..4211f49d2272 100755 --- a/dockers/docker-fpm-frr/bgpcfgd +++ b/dockers/docker-fpm-frr/bgpcfgd @@ -120,29 +120,23 @@ class Directory(object): self.data = defaultdict(dict) self.notify = defaultdict(lambda: defaultdict(list)) - def path_exist(self, slot, path): + def path_traverse(self, slot, path): if slot not in self.data: - return False + return False, None elif path == '': - return True + return True, self.data[slot] d = self.data[slot] for p in path.split("/"): if p not in d: - return False + return False, None d = d[p] - return True + return True, d + + def path_exist(self, slot, path): + return self.path_traverse(slot, path)[0] def get_path(self, slot, path): - if slot not in self.data: - return None - elif path == '': - return self.data[slot] - d = self.data[slot] - for p in path.split("/"): - if p not in d: - return None - d = d[p] - return d + return self.path_traverse(slot, path)[1] def put(self, slot, key, value): self.data[slot][key] = value @@ -289,6 +283,8 @@ class BGPPeerMgr(Manager): } def set_handler(self, key, data): + key = self.normalize_key(key) + vrf, nbr = key.split('|', 1) if key not in self.peers: cmd = None neigmeta = self.directory.get_slot("neigmeta") @@ -298,14 +294,14 @@ class BGPPeerMgr(Manager): cmd = self.templates["add"].render( DEVICE_METADATA=self.directory.get_slot("meta"), DEVICE_NEIGHBOR_METADATA=neigmeta, - neighbor_addr=key, + neighbor_addr=nbr, bgp_session=data ) except: syslog.syslog(syslog.LOG_ERR, 'Peer {}. Error in rendering the template for "SET" command {}'.format(key, data)) return True if cmd is not None: - rc = self.apply_op(cmd) + rc = self.apply_op(cmd, vrf) if rc: self.peers.add(key) syslog.syslog(syslog.LOG_INFO, 'Peer {} added with attributes {}'.format(key, data)) @@ -316,13 +312,13 @@ class BGPPeerMgr(Manager): # commands for the peers only if "admin_status" in data: if data['admin_status'] == 'up': - rc = self.apply_op(self.templates["no shutdown"].render(neighbor_addr=key)) + rc = self.apply_op(self.templates["no shutdown"].render(neighbor_addr=nbr), vrf) if rc: syslog.syslog(syslog.LOG_INFO, 'Peer {} admin state is set to "up"'.format(key)) else: syslog.syslog(syslog.LOG_ERR, "Peer {} admin state wasn't set to 'up'.".format(key)) elif data['admin_status'] == 'down': - rc = self.apply_op(self.templates["shutdown"].render(neighbor_addr=key)) + rc = self.apply_op(self.templates["shutdown"].render(neighbor_addr=nbr), vrf) if rc: syslog.syslog(syslog.LOG_INFO, 'Peer {} admin state is set to "down"'.format(key)) else: @@ -334,23 +330,28 @@ class BGPPeerMgr(Manager): return True def del_handler(self, key): + key = self.normalize_key(key) + vrf, nbr = key.split('|', 1) if key not in self.peers: syslog.syslog(syslog.LOG_WARNING, 'Peer {} has not been found'.format(key)) return - cmd = self.templates["delete"].render(neighbor_addr=key) - rc = self.apply_op(cmd) + cmd = self.templates["delete"].render(neighbor_addr=nbr) + rc = self.apply_op(cmd, vrf) if rc: syslog.syslog(syslog.LOG_INFO, 'Peer {} has been removed'.format(key)) self.peers.remove(key) else: syslog.syslog(syslog.LOG_ERR, "Peer {} hasn't been removed".format(key)) - def apply_op(self, cmd): + def apply_op(self, cmd, vrf): bgp_asn = self.directory.get_slot("meta")["localhost"]["bgp_asn"] fd, tmp_filename = tempfile.mkstemp(dir='/tmp') os.close(fd) with open(tmp_filename, 'w') as fp: - fp.write('router bgp %s\n' % bgp_asn) + if vrf == 'default': + fp.write('router bgp %s\n' % bgp_asn) + else: + fp.write('router bgp %s vrf %s\n' % (bgp_asn, vrf)) fp.write("%s\n" % cmd) command = ["vtysh", "-f", tmp_filename] @@ -358,14 +359,31 @@ class BGPPeerMgr(Manager): os.remove(tmp_filename) return rc == 0 + @staticmethod + def normalize_key(key): + if '|' not in key: + return 'default|' + key + else: + return key + @staticmethod def load_peers(): - peers = set() - command = ["vtysh", "-c", "show bgp neighbors json"] + vrfs = [] + command = ["vtysh", "-c", "show bgp vrfs json"] rc, out, err = run_command(command) if rc == 0: - js_bgp = json.loads(out) - peers = set(js_bgp.keys()) + js_vrf = json.loads(out) + vrfs = js_vrf['vrfs'].keys() + + peers = set() + for vrf in vrfs: + command = ["vtysh", "-c", 'show bgp vrf {} neighbors json'.format(vrf)] + rc, out, err = run_command(command) + if rc == 0: + js_bgp = json.loads(out) + for nbr in js_bgp.keys(): + peers.add((vrf, nbr)) + return peers From df04809cb878ca69d408448c82da8f57f696bd9f Mon Sep 17 00:00:00 2001 From: tahmed-dev <56694863+tahmed-dev@users.noreply.github.com> Date: Mon, 6 Jan 2020 17:01:28 -0800 Subject: [PATCH 51/66] [libnl]: Debian Packaging libnl version 3.5.0 (#3967) Packaging libnl 3.5.0 based off libnl 3.2.27 packaging. libnl contains various bug fixes that are nice to have. pull-request: https://github.com/Azure/sonic-buildimage/pull/3967 signed-off-by: Tamer Ahmed --- .gitignore | 16 + rules/libnl3.mk | 4 +- src/libnl3/Makefile | 9 +- src/libnl3/debian/README.Debian | 17 + src/libnl3/debian/README.source | 10 + src/libnl3/debian/changelog | 1043 +++++++++ src/libnl3/debian/compat | 1 + src/libnl3/debian/control | 245 ++ src/libnl3/debian/copyright | 160 ++ src/libnl3/debian/gbp.conf | 16 + src/libnl3/debian/libnl-3-200-udeb.install | 1 + src/libnl3/debian/libnl-3-200.install | 3 + src/libnl3/debian/libnl-3-200.symbols | 661 ++++++ src/libnl3/debian/libnl-3-dev.install | 5 + src/libnl3/debian/libnl-cli-3-200.install | 4 + src/libnl3/debian/libnl-cli-3-200.symbols | 226 ++ src/libnl3/debian/libnl-cli-3-dev.install | 3 + .../debian/libnl-genl-3-200-udeb.install | 2 + src/libnl3/debian/libnl-genl-3-200.install | 2 + src/libnl3/debian/libnl-genl-3-200.symbols | 88 + src/libnl3/debian/libnl-genl-3-dev.install | 4 + src/libnl3/debian/libnl-idiag-3-200.install | 1 + src/libnl3/debian/libnl-idiag-3-200.symbols | 206 ++ src/libnl3/debian/libnl-idiag-3-dev.install | 3 + src/libnl3/debian/libnl-nf-3-200.install | 1 + src/libnl3/debian/libnl-nf-3-200.symbols | 620 +++++ src/libnl3/debian/libnl-nf-3-dev.install | 3 + src/libnl3/debian/libnl-route-3-200.install | 1 + src/libnl3/debian/libnl-route-3-200.symbols | 2051 +++++++++++++++++ src/libnl3/debian/libnl-route-3-dev.install | 3 + src/libnl3/debian/libnl-utils.install | 1 + src/libnl3/debian/libnl-utils.manpages | 1 + src/libnl3/debian/libnl-xfrm-3-200.install | 1 + src/libnl3/debian/libnl-xfrm-3-200.symbols | 484 ++++ src/libnl3/debian/libnl-xfrm-3-dev.install | 3 + src/libnl3/debian/patches/series | 0 src/libnl3/debian/rules | 39 + src/libnl3/debian/source/format | 1 + src/libnl3/debian/watch | 2 + 39 files changed, 5934 insertions(+), 7 deletions(-) create mode 100644 src/libnl3/debian/README.Debian create mode 100644 src/libnl3/debian/README.source create mode 100644 src/libnl3/debian/changelog create mode 100644 src/libnl3/debian/compat create mode 100644 src/libnl3/debian/control create mode 100644 src/libnl3/debian/copyright create mode 100644 src/libnl3/debian/gbp.conf create mode 100644 src/libnl3/debian/libnl-3-200-udeb.install create mode 100755 src/libnl3/debian/libnl-3-200.install create mode 100644 src/libnl3/debian/libnl-3-200.symbols create mode 100755 src/libnl3/debian/libnl-3-dev.install create mode 100755 src/libnl3/debian/libnl-cli-3-200.install create mode 100644 src/libnl3/debian/libnl-cli-3-200.symbols create mode 100644 src/libnl3/debian/libnl-cli-3-dev.install create mode 100755 src/libnl3/debian/libnl-genl-3-200-udeb.install create mode 100755 src/libnl3/debian/libnl-genl-3-200.install create mode 100644 src/libnl3/debian/libnl-genl-3-200.symbols create mode 100755 src/libnl3/debian/libnl-genl-3-dev.install create mode 100644 src/libnl3/debian/libnl-idiag-3-200.install create mode 100644 src/libnl3/debian/libnl-idiag-3-200.symbols create mode 100644 src/libnl3/debian/libnl-idiag-3-dev.install create mode 100644 src/libnl3/debian/libnl-nf-3-200.install create mode 100644 src/libnl3/debian/libnl-nf-3-200.symbols create mode 100644 src/libnl3/debian/libnl-nf-3-dev.install create mode 100644 src/libnl3/debian/libnl-route-3-200.install create mode 100644 src/libnl3/debian/libnl-route-3-200.symbols create mode 100644 src/libnl3/debian/libnl-route-3-dev.install create mode 100644 src/libnl3/debian/libnl-utils.install create mode 100644 src/libnl3/debian/libnl-utils.manpages create mode 100644 src/libnl3/debian/libnl-xfrm-3-200.install create mode 100644 src/libnl3/debian/libnl-xfrm-3-200.symbols create mode 100644 src/libnl3/debian/libnl-xfrm-3-dev.install create mode 100644 src/libnl3/debian/patches/series create mode 100755 src/libnl3/debian/rules create mode 100644 src/libnl3/debian/source/format create mode 100644 src/libnl3/debian/watch diff --git a/.gitignore b/.gitignore index 1f921971d8bb..fbf646fcd40f 100644 --- a/.gitignore +++ b/.gitignore @@ -50,6 +50,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 @@ -140,3 +142,17 @@ src/sonic-daemon-base/sonic_daemon_base.egg-info # Misc. files files/initramfs-tools/arista-convertfs files/initramfs-tools/union-mount + +# Debian byproduct files +src/**/debian/stamp-*/ +src/**/debian/*.log +src/**/debian/*.substvars +src/**/debian/.debhelper/ +src/**/debian/tmp/ +src/**/debian/autoreconf.* +src/**/debian/build/ +src/**/debian/files +src/**/debian/stamp-autotools-files + +# .o files +src/**/*.o diff --git a/rules/libnl3.mk b/rules/libnl3.mk index 897b6c34482f..cdd807b2f5c8 100644 --- a/rules/libnl3.mk +++ b/rules/libnl3.mk @@ -1,7 +1,7 @@ # libnl3 -LIBNL3_VERSION_BASE = 3.2.27 -LIBNL3_VERSION = $(LIBNL3_VERSION_BASE)-2 +LIBNL3_VERSION_BASE = 3.5.0 +LIBNL3_VERSION = $(LIBNL3_VERSION_BASE)-1 export LIBNL3_VERSION_BASE export LIBNL3_VERSION diff --git a/src/libnl3/Makefile b/src/libnl3/Makefile index c9fc72f50f74..a0e9891c9efc 100644 --- a/src/libnl3/Makefile +++ b/src/libnl3/Makefile @@ -16,12 +16,11 @@ DERIVED_TARGETS = libnl-3-dev_$(LIBNL3_VERSION)_$(CONFIGURED_ARCH).deb \ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Obtaining the libnl3 rm -rf ./libnl3-$(LIBNL3_VERSION_BASE) - wget -O libnl3_$(LIBNL3_VERSION_BASE).orig.tar.gz -N "https://sonicstorage.blob.core.windows.net/packages/libnl3_$(LIBNL3_VERSION_BASE).orig.tar.gz?sv=2015-04-05&sr=b&sig=b4DnqrIsyVBDLmYhw7qwfaUJWqGCX2lDVMmmx7ihfrU%3D&se=2028-06-16T21%3A06%3A00Z&sp=r" - wget -O libnl3_$(LIBNL3_VERSION).dsc -N "https://sonicstorage.blob.core.windows.net/packages/libnl3_$(LIBNL3_VERSION).dsc?sv=2015-04-05&sr=b&sig=AWTX45oDbeGA%2BRJZyiCcHmeIfCAgSeNV3IqopOBaRDg%3D&se=2028-06-16T21%3A05%3A30Z&sp=r" - wget -O libnl3_$(LIBNL3_VERSION).debian.tar.xz -N "https://sonicstorage.blob.core.windows.net/packages/libnl3_$(LIBNL3_VERSION).debian.tar.xz?sv=2015-04-05&sr=b&sig=upIZ9dp5WEcLqp3ODeWKJXq5pJWCfeT0TIM0bx76wxM%3D&se=2028-06-16T21%3A04%3A44Z&sp=r" - dpkg-source -x libnl3_$(LIBNL3_VERSION).dsc + git clone https://github.com/thom311/libnl libnl3-$(LIBNL3_VERSION_BASE) + pushd libnl3-$(LIBNL3_VERSION_BASE) + git checkout tags/libnl$(subst .,_,$(LIBNL3_VERSION_BASE)) - pushd ./libnl3-$(LIBNL3_VERSION_BASE) + ln -s ../debian debian dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) popd diff --git a/src/libnl3/debian/README.Debian b/src/libnl3/debian/README.Debian new file mode 100644 index 000000000000..002e249bbfcb --- /dev/null +++ b/src/libnl3/debian/README.Debian @@ -0,0 +1,17 @@ + +libnl versions explained +======================== + +Once libnl3 hits the archive there will exist 3 versions of libnl. +libnl1 with libnl-dev - up until March 2011 the stable version +libnl2 with libnl2-dev - development version that resulted in +libnl3 with libnl3-dev - the new stable (API and ABI wise) version + +libnl1 has currently a lot of users in the archive and a lot of changes +happened since its last upstream release in 2008-01. + +The plan is therefore to introduce libnl3, port the two users of libnl2 +(freesmartphone.org libs and powertop) to it, remove libnl2 and don't touch +libnl1 and libnl-dev for now. + + -- Heiko Stuebner Sat, 21 May 2011 19:25:13 +0200 diff --git a/src/libnl3/debian/README.source b/src/libnl3/debian/README.source new file mode 100644 index 000000000000..f6e8ee70da94 --- /dev/null +++ b/src/libnl3/debian/README.source @@ -0,0 +1,10 @@ +This package uses the simple-patchsys of cdbs. + +The following patches are used: +0001: Fixes the header inclusion in the Makefiles. + This for example make distcheck +0002: Includes all generated libraries as linktargets in the pkg-config file. + Reason: Currently libnl3 generates a bunch of child libraries. + These don't get individual .pc files from upstream at the moment but + programs linking against libnl3 using the .pc file mostly need these + additional libraries too. diff --git a/src/libnl3/debian/changelog b/src/libnl3/debian/changelog new file mode 100644 index 000000000000..c51ae1121796 --- /dev/null +++ b/src/libnl3/debian/changelog @@ -0,0 +1,1043 @@ +libnl3 (3.5.0-1) unstable; urgency=low + + [ skuklinski ] + * route/link: IFLA_VLAN_PROTOCOL added to vlan_put_attrs + + [ Thomas Haller ] + * rtnl/link: indicate capability NL_CAPABILITY_RTNL_LINK_VLAN_PROTOCOL_SERIALZE + + [ David Ahern ] + * route/vrf: add VRF support + * neigh: add support for NTF_SELF + + [ Beniamino Galvani ] + * route/link: fix parsing of 'remote' attribute for GRE links + + [ Thomas Haller ] + * route/vlan: allow clearing vlan ingress map + + [ David Ahern ] + * link/neigh: add flags option to link and neighbor caches + + [ Thomas Haller ] + * gitignore: ignore test binaries in "tests/" + + [ Beniamino Galvani ] + * route/link: add macvtap support + * route/link: fix dump of parent link for some link types + * route/link: add ipv6 support to vxlan links + + [ Tobias Jungel ] + * route/link: corrected array size for inet_policy + + [ David Ahern ] + * route/link: add link info compare operation + * route/link/vxlan: trivial rename VXLAN_HAS_ prefix and vxi_mask + * route/link/vxlan: add support for link_info compare + + [ Andrew Vagin ] + * libnl: don't use out-of-scope buffer in nl_send_iovec() + + [ David Ahern ] + * link: add AF operation to append attributes to a GETLINK message + * lib: handle family-based parsing of IFLA_AF_SPEC attribute + + [ Thomas Haller ] + * include/linux: update copy of kernel headers + + [ David Ahern ] + * bridge: add support for VLANs + + [ Tobias Jungel ] + * route/link: handle RTEXT_FILTER_BRVLAN_COMPRESSED + * route/link/bridge: fixed return type + + [ Quentin Armitage ] + * route/link: add support for IN6_ADDR_GEN_MODE_STABLE_PRIVACY + + [ Amit Khatri ] + * lib/route: potential memory leak in pktloc.c + + [ Nick Lewycky ] + * remove null dereference from netlink/link.h + + [ David Ahern ] + * lib: update ce-mask to uint64_t + + [ Thomas Haller ] + * libnl: add nl_object_diff64() to libnl-3.sym + * lib/utils: add NL_CAPABILITY_NL_OBJECT_DIFF64 capability + + [ Przemyslaw Szczerbik ] + * lib: add type casting for nla_for_each_nested macro + + [ Tobias Klauser ] + * build: move -rdynamic from CPPFLAGS to LDFLAGS + + [ Thomas Haller ] + * route: sort entries in libnl-route-3.sym by name + + [ Haishuang Yan ] + * ipgre: add support for gretap tunnel + + [ Thadeu Lima de Souza Cascardo ] + * sit: add 6RD support + + [ Thomas Haller ] + * sit/trivial: whitespace + * sit: don't print ip6rd_prefix as integer in sit_dump_details() + * sit: refactor IS_SIT_LINK_ASSERT() + * sit: fix invalid declaration of rtnl_link_sit_get_proto() in sit.h + * sit: add public API for sit 6RD support + + [ Jonas Johansson ] + * neigh: support neighbour flag NTF_SELF + * neigh: add function to look up neighbour (fdb) by ifindex, mac and vlan + + [ Jef Oliver ] + * link: support RTEXT_FILTER_VF + + [ Thomas Haller ] + * link: allow overwriting IFLA_EXT_MASK flag in ao_get_af() function + + [ Przemyslaw Szczerbik ] + * lib: return error on Netlink attribute length overflow + + [ Thomas Egerer ] + * xfrm: fix buffer overflow when copying keys + * xfrm: check length of alg_name before strcpying it + * xfrm: make character pointers in setters const + * xfrm: fix segfault when using encapsulation templates + + [ Thomas Haller ] + * xfrm: reuse encap data in xfrmnl_sa_set_encap_tmpl() + + [ Thomas Egerer ] + * xfrm: fix memory leak for encap original address + * xfrm: attach only one xfrm alg attribute to netlink message + + [ Thomas Haller ] + * xfrm: fix memleak in build_xfrm_sa_message() error-path + + [ Sabrina Dubroca ] + * pass flags through ->io_compare op + * vxlan: properly handle LOOSE_COMPARISON in ->io_compare + * import macsec uapi headers + * lib/route: add macsec support + + [ Thomas Haller ] + * xfrm: allow avoiding buffer overflow for key in xfrmnl_sa_get_*_params() + * route/addr: fix ID comparison for AF_INET and AF_INET6 addresses + * route/addr: fix handling peer addresses for IPv4 addresses + * route/addr: add capability NL_CAPABILITY_RTNL_ADDR_PEER_FIX to indicate address fixes + * build: fix adding macsec files to include/Makefile.am + * libnl-3.2.28-rc1 release + * libnl-3.2.28 release + + [ Craig Gallek ] + * build: fixup headers for C++ inclusion + + [ Peter Wu ] + * trivial: whitespace-only fixes for src and lib + * cli: add noreturn attributes + * xfrm: fix memleak in another error path of build_xfrm_sa_message + * exp: fix a GCC 6 -Wmisleading-indentation warning + * doc: fix URLs and typo + + [ Tobias Jungel ] + * route/addr: address attributes based on object + + [ Thomas Haller ] + * lib: capability NL_CAPABILITY_RTNL_ADDR_PEER_ID_FIX for ID comparison of v4 addresses + * nl-addr: avoid read-out-of-bound in nl_addr_fill_sockaddr() + + [ André Draszik ] + * lib: add utility function nl_strerror_l() + * lib: switch to using strerror_l() instead of strerror_r() + * src: switch to using strerror_l() instead of strerror_r() + + [ Jeff Squyres ] + * compat: add linux/socket.h for __kernel_sa_family_t + + [ Jef Oliver ] + * lib/route: allow override of message type during link change + * lib/route: set IFLA_PROTINFO attribute in request message + * lib/route: modify link/bridge to set attributes + + [ Davide Caratti ] + * macsec: fix endianness of 'sci' parameter + * macsec: fix maximum ICV length + * remove multiple implementations of htonll(), ntohll() + + [ Jef Oliver ] + * lib/route: Fix appending IFLA_BRPORT_FASTLEAVE + * lib/route: Add port state translation functions + * lib/route: Extend Bridge Flags + * lib/route: Allow override of IFLA_AF_SPEC nesting + * lib/route: Support IFLA_BRIDGE_MODE + + [ Thomas Haller ] + * trivial: whitespace + * bridge: change return values for rtnl_link_bridge_get_hwmode() + + [ Michael Braun ] + * macvlan: add support for "source" mode + + [ Thomas Haller ] + * macvlan: adjust types and merge MACVLAN_HAS_MACCOUNT and MACVLAN_HAS_MACDATA + + [ Brandon Carpenter ] + * vxlan: add support for additional VXLAN attributes. + + [ Thomas Haller ] + * vxlan: fix exporting new symbols + * vxlan: remove redundant enable/disable API from vxlan + * vxlan: restore previous VXLAN_ATTR flag values + * vxlan: don't store vxlan flags as ce_mask + * vxlan: refactor setting/getting vxlan flags + * vxlan: fix error code for missing attribute + + [ Jef Oliver ] + * lib/route: Export correct ipgre functionality + + [ Thomas Haller ] + * lib/route: preserve old ABI for rtnl_link_get_pmtudisc() + + [ Thomas Egerer ] + * xfrm: fix xfrm security context management + * xfrm: add capability reference to xfrmnl_sa_set_* + + [ Thomas Haller ] + * xfrm: remove unused struct xfrmnl_sec_ctx from header files + + [ Jef Oliver ] + * lib/route: SRIOV Parse and Read support + * lib/route: SRIOV Clone Support + * lib/route: SRIOV Utility Functions + * lib/route: SRIOV Info Dump Functions + * lib/route: SRIOV Set Functionality + + [ Thomas Haller ] + * route: remove symbols of internal API from ABI + + [ Tobias Klauser ] + * lib/route: keep link stats minlen compatible with kernel < 4.6 + + [ Thomas Haller ] + * utils: add internal _nl_offset_plus_sizeof() macro + * lib/route: use _nl_offset_plus_sizeof() macro for minlen field for rtln_link_policy + + [ Jonas Johansson ] + * Add PPP support + * ppp: update code after review + * ppp: rename local struct ppp_info* variables; pi -> info + * ppp: fix type of file descriptor; uint32_t -> int32_t + + [ Thomas Haller ] + * ppp: fix API in ppp.h header + + [ Sushma Sitaram ] + * route/cls: support setting of selector fields + + [ Tobias Klauser ] + * src: nl-link-stats: use correct rtnl link stats maximum + * lib/route: add rx_nohandler link stats field + + [ Thomas Haller ] + * nl-link-stats: prefer RTNL_LINK_STATS_MAX over __RTNL_LINK_STATS_MAX + * lib/route: pass sizeof() argument to nl_memcpy() + * link: set ifi_change flags for rtnl_link_build_add_request() + * lib: use MSG_PEEK by default for nl_recvmsgs() + + [ Tobias Jungel ] + * cache_mngr: add include callback v2 + + [ Tobias Klauser ] + * cache: fix GCC warning and avoid variable shadowing + + [ Sushma Sitaram ] + * route/act: add gact tc action + + [ Tobias Klauser ] + * link: add support for IFLA_CARRIER_CHANGES + * link: add support for IFLA_PHYS_PORT_NAME + * link: add support for IFLA_PHYS_SWITCH_ID + * link: add support for IFLA_GSO_MAX_SEGS and IFLA_GSO_MAX_SIZE + * link: fix documentation for rtnl_link_get_carrier_changes + + [ Thomas Haller ] + * libnl-3.2.29-rc1 release + * utils/trivial: rename internal _nl_offset_plus_sizeof() macro to _nl_offsetofend() + + [ Beniamino Galvani ] + * Revert "macsec: fix endianness of 'sci' parameter" + * macsec: document byte order for the SCI and port attributes + + [ Thomas Haller ] + * macsec: fix endianness of sci during dump() + * libnl-3.2.29 release + + [ Tobias Klauser ] + * route/tc: Remove unused function tca_set_kind() + + [ Laine Stump ] + * sriov: fix crash in rtnl_link_sriov_parse_vflist + + [ Thomas Haller ] + * sriov: avoid buffer overrun in rtnl_link_sriov_parse_vflist() + + [ Nick Kralevich ] + * lib/utils.c: lazy initialize user_hz and psched_hz + + [ Thomas Haller ] + * lib/utils.c: ensure calling get_psched_settings() for nl_us2ticks()/nl_ticks2us() + * lib/utils.c: add mutex to get_psched_settings() + + [ Nick Kralevich ] + * fopen: add O_CLOEXEC + + [ Thomas Haller ] + * lib/attr.c: check for valid length argument in nla_reserve() + + [ Tobias Klauser ] + * sit: Fix invalid function prototypes in public header + * sriov: Add missing prototype for rtnl_link_vf_vlan_free() + * qdisc/red: Add missing prototypes for rtnl_red_set_limit() and rtnl_red_get_limit() + * fib_lookup: Add missing prototypes to public header + * link/inet6: Include own public header for function prototypes + * link/ipip: Include own public header for function prototypes + * link/ipip: Add missing prototype for rtnl_link_is_ipip() + * link/ipvti: Include own public header for function prototypes + * link/ipvti: Fix and add function prototypes in public header + * link/macsec: Include own public header for function prototypes + * link/sit: Add missing prototype for rtnl_link_is_sit() + * link/ipgre: Add prototype for ABI-preserving wrapper rtnl_link_get_pmtudisc() + * netfilter/queue: Add missing prototype for nfnl_queue_msg_build_verdict_batch() + * netfilter/exp: Add missing function prototypes + * idiag/req: Add missing function prototype + * xfrm/ae: Include own public header for function prototypes + * xfrm/lifetime: Include own public header for function prototypes + * xfrm/sa: Include own public header for function prototypes + * xfrm/selector: Include own public header for function prototypes + * xfrm/template: Include own public header for function prototypes + * pktloc: Add missing function prototypes + * ematch: Add missing function prototypes + * build: Add -Wmissing-prototypes to CPPFLAGS + + [ Jeroen Roovers ] + * build: distribute in.h in6.h libc-compat.h + + [ Thomas Haller ] + * lib: fix comment for nl_recv() about return value for non-blocking read + * lib: check for integer-overflow in nlmsg_reserve() + * build: cleanup top-level Makefile.am + * build: merge include/Makefile.am into top-level makefile + * build: merge lib/Makefile.am into top-level makefile + * build: merge man/Makefile.am into top-level makefile + * build: merge python/Makefile.am into top-level makefile + * build: merge tests/Makefile.am into top-level makefile + * build: merge src/lib/Makefile.am into top-level makefile + * build: merge src/Makefile.am into top-level makefile + * build: enable building cli during tests + * build: move compiler warning flags to separate autoconf variable + * all: enable -Wmissing-prototype warning for all components + * build: enable more warnings + + [ Roopa Prabhu ] + * route: neigh: use NDA_MASTER for neigh->n_master if available + + [ Simon Buttgereit ] + * fix build_xfrm_sp_message index condition + * fix xfrmnl_sp_set_sec_ctx length attributes + * little style fixes. + * update sp_attr condition in build_xfrm_sp_message + * add possibity to delete policy without index + * update documentation of xfrmnl_sp_get_sec_ctx + * fix of boolean operators + + [ Thomas Haller ] + * xfrm: allow quering optional arguments from xfrmnl_sp_get_sec_ctx() + * xfrm: NUL terminate the ctx_str buffer in xfrmnl_sa_set_sec_ctx() + * build: ensure build directory for generated sources exist + * build: pass --disable-dependency-tracking to `make distcheck` + * build: fix creating directories for generated sources + * build: style cleanup in doc/Makefile.am + * build: reorder checks in configure.ac + * build: add tools/build_release.sh script + * include: don't include kernel headers in public libnl3 headers + * include: restore linux header includes in public headers + * libnl-3.3.0-rc1 release + + [ Alexey Brodkin ] + * lib: escape usage of strerror_l() if it doesn't exist in libc + + [ Thomas Haller ] + * all: don't use math.h or link with libm.so + * libnl-3.3.0 release + * tools: fix building doc in build_release.sh + + [ Markus Trapp ] + * route/link: add accessor API for IPv6 flags + + [ Santhosh Kumar ] + * Provide accessors for actions (rtnl_act). + * Do not increment refcount in rtnl_*_get_action APIs. + + [ Thomas Haller ] + * route: fix symbol versioning + + [ David Ahern ] + * route: Add support for netconf + * nl-monitor: All user to specify line format + * nl-monitor: Add support for netconf caches + * route: Add support for MPLS to netconf + * Update fib_rules.h to latest kernel + * rule: Add support for l3mdev in FIB rules + + [ Thomas Haller ] + * rule: change API for setting/getting l3mdev rule property + + [ Tobias Klauser ] + * addr: add AF_VSOCK to translation table + + [ Thomas Haller ] + * build: don't build cli libraries by default + * build: allow building cli without dynamic librarires support + + [ Tobias Klauser ] + * genl: drop usage of GENL_ID_GENERATE + + [ Rasmus Villemoes ] + * lib/cache_mngr.c: avoid memleak if realloc fails + * lib/cache_mgr.c: remove pointless goto + * lib/data.c: avoid memleak if realloc fails + * lib/route/cls/u32.c: remove pointless nl_data_append calls + * lib/route/cls/u32.c: avoid overflowing an unsigned char + * lib/route/cls/u32.c: let the compiler do pointer arithmetic + * lib/route/cls/u32.c: remove bogus comment + * lib/route/qdisc/netem.c: avoid memory leak if realloc fails + + [ Thomas Haller ] + * lib/route/cls/u32.c: use UCHAR_MAX define instead of numeric 255 + * lib/route/qdisc/netem.c/trivial: fix whitespace and indentation in netem_msg_fill_raw() + * lib/route/qdisc/netem.c/trivial: don't use braces for one-line blocks + + [ Rasmus Villemoes ] + * lib/xfrm/ae.c: fix memcpy(dst, dst) bug + * lib/genl/family.c: fix if (x) y; else y; + + [ Thomas Haller ] + * all: avoid compiler warnings -Wimplicit-fallthrough + * lib/route: add /usr/lib64/tc/ search path for netem dist file + + [ David Ahern ] + * Update rtnetlink.h from kernel tree + * Import mpls header from kernel tree + + [ Thomas Haller ] + * build: add include/linux-private/linux/mpls.h to Makefile.am + + [ David Ahern ] + * addr: Add implementations for mpls_ntop and mpls_pton + * addr: Add support for AF_MPLS + * route: Add support for MPLS address family + * route: Add support for ttl propagation in MPLS routes + * Add support for label stack in nl-route commands + * Import lwtunnel encap files from kernel + * route: Add support for lwtunnel encapsulations + * route: Add support for MPLS encap + + [ Thomas Haller ] + * build: add new include/netlink-private/route/*.h files to Makefile.am + + [ Amit Khatri ] + * Potential memory leak becaue of wrong variable check. + + [ Tobias Klauser ] + * cli: include sys/select.h for select(2) + + [ Thomas Haller ] + * libnl-3.4.0-rc1 release + + [ David Ahern ] + * netconf: Put nc reference in msg_parser + + [ Jeroen Roovers ] + * build: add missing headers for issue #152 + + [ Thomas Haller ] + * libnl-3.4.0 release + * nl: add "const" specifier for nla_policy argument of parse functions [ Roopa Prabhu ] + * route: link: add family to dump messages + * route: neigh: print family in neigh dumps + + [ Sebastian Bixl ] + * route/vlan: fix memory corruption in rtnl_link_vlan_set_egress_map + + [ Thomas Haller ] + * route/vlan: fix cloning vlan link in vlan_clone() + * route/vlan: grow buffer exponentially in rtnl_link_vlan_set_egress_map() + * route/vlan: add capability to indicate heap overflow fix in rtnl_link_vlan_set_egress_map() + * route: fix handling old_nh in rtnl_route_parse() and avoid leak + + [ Jef Oliver ] + * Change rtnl_link_af_ops.ao_override_rtm behavior + + [ Chris Grahn ] + * tests: fix bug in test-create-bridge.c + + [ Steffen Vogel ] + * route: add separate function to set netem qdisc delay distribution + + [ Thomas Haller ] + * all: declare all variables at the beginning of scope (-Wdeclaration-after-statement) + * route: add rtnl_netem_set_delay_distribution_data() to linker script + * route: mark data argument for rtnl_netem_set_delay_distribution_data() as const + * route: fix memleak in rtnl_netem_set_delay_distribution_data() + * route: free previous data in rtnl_netem_set_delay_distribution_data() + * travis: enable more warnings during build + + [ Marcos Paulo de Souza ] + * tests: Add test to {de}activate loopback interface + * lib/veth.c: Disassociate link name of peer name + + [ d0u9 ] + * Coding style format + * Add new function for setting ifindex and parent of a classifier cache. + + [ Thomas Haller ] + * route: rename rtnl_cls_cache_set_tcm_params() and fix symbol versioning + + [ d0u9 ] + * Fix for cgroup filter addition problem. + + [ Thomas Haller ] + * lib: merge implementations of nl_attr_end() and nl_attr_keep_empty() + + [ Wang Jian ] + * link: add Geneve support. + + [ Thomas Haller ] + * lib/rtnl: rename public define RTNL_GENEVE_ID_MAX + + [ Roopa Prabhu ] + * lib: route: rule: add rule_groups to cache ops + + [ Jonas Johansson ] + * route/vrf: initalize clone destination with NULL in vrf_clone() + + [ David Ahern ] + * Update fib_rules.h to latest kernel + * rule: Add support for protocol and port ranges + + [ Lukáš Karas ] + * add demo program for listen conntrack events + * nf-ct-add typo + + [ Thomas Haller ] + * build: sort entries in Makefile.am and .gitignore by name + * build: indent libnl-route-3.sym with tabs + + [ Tobias Jungel ] + * neigh: set correct AF for NDA_DST + * neigh: support bridge entries for vxlan interfaces + + [ Tuetuopay ] + * cache: make "result" output argument for nl_cache_mngr_add() optional + + [ Volodymyr Bendiuga ] + * include: copy entire pkt_cls.h from linux + * route:cls: add matchall classifier + + [ Thomas Haller ] + * route/mall: fix deep cloning mall + + [ Tuetuopay ] + * route/link: fix sequence number handling in rtnl_link_change() + + [ Thomas Haller ] + * route/link: assert in rtnl_link_change() that the sequence number is set as expected + * nl-msg: explicitly initialize nlmsg_seq and nlmsg_pid field in nlmsg_alloc_simple() + + [ d0u9 ] + * route/class: add new api rtnl_class_get_by_parent() + + [ Tobias Jungel ] + * neigh: correct symbol exposed + + [ Matthieu Baerts ] + * nl: fix function name in debug msg + + [ Tobias Jungel ] + * neigh: cache updates as well query AF_BRIDGE neigh + * whitespace cleanup + * nl-neigh-list: free allocated items + * neigh: add get/set functions for NEIGH_ATTR_MASTER + * neigh_dump_line: dump master as well + + [ d0u9 ] + * Add support for cloning cgroup filter object. + + [ Tuetuopay ] + * route/link/vxlan: Fix IPv4 set_local resetting ce_mask + + [ Tobias Jungel ] + * neigh: update neighbour.h and add missing flags + + [ Thomas Winter ] + * ipgre: Fix wrong array size initialization + * ipvti: Fix wrong array size initialization + * if_tunnel: Update IFLA defines up to FWMARK + + [ Thomas Haller ] + * include/linux: update copy of kernel headers + + [ Volodymyr Bendiuga ] + * include: import linux header pkt_sched.h + * route:qdisc: add MQPRIO Qdisc + + [ Thomas Haller ] + * build: cleanup Makefile.am + * lib/tc: ensure correct error code in rtnl_tc_msg_build() + * lib/qdisc: style fixes in "lib/route/qdisc/mqprio.c" + * lib/qdisc: avoid BUG() in "lib/route/qdisc/mqprio.c" + * build: sort entries in libnl-route-3.sym + * lib/tc: fix uninitalized err variable in rtnl_tc_msg_build() + + [ Volodymyr Bendiuga ] + * route:tc: allow to set chain index for tc objects + + [ Thomas Haller ] + * route/tc: return error code from rtnl_tc_get_chain() + + [ Volodymyr Bendiuga ] + * include: import tc_vlan.h + * route:act: add vlan action + + [ Thomas Haller ] + * route/act: style fixes in "lib/route/act/vlan.c" + * route/act: return error code from act-vlan getters + + [ Ilya Pronin ] + * route/cls: fix potential memory leak + + [ Patrick Havelange ] + * nla_ok: fix overrun in attribute iteration. + + [ Wang Jian ] + * link: macvlan fixes + + [ Thomas Haller ] + * route/macvlan: style fixes in "lib/route/link/macvlan.c" + + [ Tobias Jungel ] + * route/link: expose IFLA_INFO_SLAVE_KIND + + [ Thomas Haller ] + * route/link: avoid dangling pointer in rtnl_link_set_slave_type() + + [ Byeonggon Lee ] + * tests: use nl_send_auto() instead of deprecated nl_send_auto_complete() in test-genl.c + + [ Thomas Haller ] + * doc: fix typos in example in documentation + * attr: mark nested attributes as NLA_F_NESTED + + [ xinbao ] + * Add CTA_LABELS and CTA_LABELS_MASK to ctattr_type according to the new kernel + + [ Thomas Haller ] + * route: fix strncpy() warning from coverity about unterminated string + * link/sriov: fix memleak in rtnl_link_sriov_clone() + * utils: add internal helper macros for cleanup + * lib/genl: avoid VLA in cmd_msg_parser() + * travis: enable -Wvla compiler warning in tests + * travis: build tests with NL_MORE_ASSERTS enabled + * xfrm: fix memory corruption (dangling pointer) when when setting xfrmnl_sa + * route/inet6: fix strncpy() in inet6_dump_details() + * route/tc: ensure not string truncation in rtnl_tc_set_kind() + * genl: reject invalid group names in genl_family_add_grp() + + [ Yegor Yefremov ] + * Add SPDX identifiers + + [ Thomas Haller ] + * lib/genl: fix allocating buffer of too small size in cmd_msg_parser() + + [ Michael Forney ] + * dbg: Use __func__ instead of __PRETTY_FUNCTION__ + * all: Avoid pointer arithmetic on `void *` + * lib: Don't return expression in function returning void + * lib: Don't omit second operand to `?` operator + * all: Use __typeof__ instead of typeof + * route: Remove stray `;` at top-level + * Sync linux headers to 4.19.66 + + [ Thomas Haller ] + * idiag: workaround and add comment about idiagnl_send_simple() only handling 8 bit flags + * lib: accept %NULL arguments for nl_addr_cmp() + * lib: fix error code from nfnl_exp_build_message() + + [ Eyal Birger ] + * doc/route: fix example code comments + * xfrmi: introduce XFRM interfaces support + + [ Thomas Haller ] + * xfrmi: return error code from getters for XFRM links + * route/trivial: sort entries in "libnl-route-3.sym" asciibetically + + [ d0u9 ] + * Add 64bit rate/ceil support for htb class + + [ Thomas Haller ] + * route/qdisc: adjust API for 64 bit rate/ceil support for htb class + * libnl-3.5.0 release + + -- Tamer Ahmed Thu, 02 Jan 2020 10:25:18 -0800 + +libnl3 (3.2.27-2) unstable; urgency=low + + * Add upstream fix for CVE-2017-0553 (Closes: #859948) + + -- Heiko Stuebner Mon, 10 Apr 2017 11:48:23 +0200 + +libnl3 (3.2.27-1) unstable; urgency=low + + * New upstream release + Including fixes for unusable sockets after a failed portid + generation (Closes: #808213) + + -- Heiko Stuebner Sun, 24 Jan 2016 23:54:47 +0100 + +libnl3 (3.2.26-1) unstable; urgency=low + + * New upstream release + * Provide Multiarch:same dev packages + * Add new libnl-xfrm library handling packet transformations + * Update standards to 3.9.6 + + -- Heiko Stuebner Mon, 13 Jul 2015 14:16:22 +0200 + +libnl3 (3.2.24-2) unstable; urgency=low + + * Backport two upstream fixes to prevent issues with older kernels: + - dfd0a80ec845 (route: don't enforce minlen in inet6_parse_protinfo() + (IFLA_PROTINFO) and inet_parse_af() (IFLA_AF_SPEC) + - 5206c050504f (route/addr: only sent IFA_FLAGS when needed to workaround + picky older kernels) + + -- Heiko Stuebner Fri, 18 Apr 2014 17:19:37 +0200 + +libnl3 (3.2.24-1) unstable; urgency=low + + * New upstream release + * Add new libnl-idiag library handling inetdiag requests + + -- Heiko Stuebner Sun, 16 Feb 2014 14:23:26 +0100 + +libnl3 (3.2.21-1) unstable; urgency=low + + * New upstream release (Closes: #707081) + Including CAN support (Closes: #698954) + * Add symbols files (Closes: #654758) + * Provide static libraries (Closes: #693939, #693940) + * Update standards to 3.9.4 + * Removed doc package. Libnl3 documentation is released + separately now. + + -- Heiko Stuebner Tue, 21 May 2013 11:39:13 +0200 + +libnl3 (3.2.7-4) unstable; urgency=low + + * Add watch file (Closes: #679473) + * Use dh-autoreconf to update the build system (Closes: 679474) + + -- Heiko Stuebner Sat, 30 Jun 2012 15:54:25 +0200 + +libnl3 (3.2.7-3) unstable; urgency=low + + * Fix FTBFS due to failing gen-tags.sh (Closes: #674322) + * Convert to Multi-Arch (Closes: #676611) + * Update standards to 3.9.3 - no changes + * Switch to dpkg-source format 3.0 (quilt) + + -- Heiko Stuebner Mon, 18 Jun 2012 21:19:30 +0200 + +libnl3 (3.2.7-2) unstable; urgency=low + + * Force doxygen dot-threads to 1 to circumvent segfaults on armel + * Add missing build-dependency on ghostscript + + -- Heiko Stuebner Mon, 05 Mar 2012 23:29:10 +0100 + +libnl3 (3.2.7-1) unstable; urgency=low + + * New upstream release + * Build-depend on source-highlight (Closes: #657254) + + -- Heiko Stuebner Mon, 13 Feb 2012 18:59:30 +0100 + +libnl3 (3.2.3-2) unstable; urgency=low + + * Upload to unstable + * Split split udeb to be in line with regular packages + * Move libnl and libnl-genl to /lib for iw and wpa_supplicant. + + -- Heiko Stuebner Mon, 19 Dec 2011 20:43:21 +0100 + +libnl3 (3.2.3-1) experimental; urgency=low + + * Upload to experimental to not break debian-installer + * Split library and dev packages for the individual libraries + * Add utils package + + [Mathieu Trudel-Lapierre ] + * New upstream release (Closes: #648819) + * debian/patches/0001-fix-headers.patch, + debian/patches/0002-link-sub-libs.patch, + debian/patches/0003-fix-out-of-tree-build.patch: dropped. + * debian/patches/0004-more-out-of-tree-build-fixes.patch: new patch; adjust + Makefiles some more to properly deal with the out-of-tree build when + generating headers and documentation. + * debian/control: + - rename packages to follow upstream soname. + - add python-pygments, xmlstarlet, texlive-latex-base and asciidoc to + Build-Depends. + * debian/rules: update due to upstream soname changes. + * debian/*.install: rename and update due to upstream soname changes. + * debian/libnl-3-200.install: netlink config files should be installed to + /etc/libnl, not /etc/libnl3. + * debian/libnl-3-doc.install, + debian/libnl-3-doc.doc-base: update to take into account new paths. + + -- Heiko Stuebner Tue, 06 Nov 2011 21:23:12 +0200 + +libnl3 (3.0-2) unstable; urgency=low + + * Acknowledge NMU + * Install config-files to /etc/libnl3 (Closes: #632790) + + -- Heiko Stuebner Mon, 26 Sep 2011 20:27:45 +0200 + +libnl3 (3.0-1.1) unstable; urgency=low + + * Non-maintainer upload with agreement from Heiko Stuebner + * Add libnl3-udeb package with seperate build for + debian-installer (Closes: #635962). + + -- Gaudenz Steinlin Fri, 29 Jul 2011 23:25:48 +0200 + +libnl3 (3.0-1) unstable; urgency=low + + * New upstream release (Closes: #626098) + see README.Debian for version explanation. + * Update standards to 3.9.2 + + -- Heiko Stuebner Sat, 21 May 2011 19:25:13 +0200 + +libnl2 (2.0-1) unstable; urgency=low + + * New upstream release (Closes: #603765) + * Fix compilation with binutils-gold or ld --no-add-needed + (Closes: #615745) + * Update standards + * Update build dependencies - tetex-live is not necessary + anymore (Closes: #616260) + + -- Heiko Stuebner Sun, 06 Mar 2011 18:20:47 +0100 + +libnl2 (1.99+git20091216-2) unstable; urgency=low + + * add README.source describing the patches in use. + * remove libnl*-provides - libnl2 should stay sepparate + from libnl1 for now + + -- Heiko Stuebner Wed, 10 Mar 2010 18:03:35 +0100 + +libnl2 (1.99+git20091216-1) unstable; urgency=low + + * New upstream snapshot + * New source name to enable installing libnl and libnl2 side by side + * Set myself as new maintainer for libnl2 according to agreement + with Michael Biebl + * Add debug package + * README.Debian warns of possible breakage in this snapshot + * Add Patch 0001 which fixes some errors in the build system + * Add Patch 0002 which adds libnl-?? libs to linker statement + until I can resolve this with upstream + + -- Heiko Stuebner Mon, 15 Feb 2010 21:50:35 +0100 + +libnl (1.1-5) unstable; urgency=low + + * Add symbols file for libnl1. + + -- Michael Biebl Wed, 25 Feb 2009 00:26:05 +0100 + +libnl (1.1-4) unstable; urgency=low + + * debian/control + - Add ${misc:Depends} to all binary packages. + - Bump Build-Depends on debhelper to (>= 7). + * debian/compat + - Bump debhelper compat level to 7. + * debian/rules + - Include debhelper.mk before other files as recommended by the cdbs + documentation. + + -- Michael Biebl Wed, 18 Feb 2009 13:26:53 +0100 + +libnl (1.1-3) unstable; urgency=low + + * debian/control + - Bump Standards-Version to 3.8.0. + * Switch to quilt for patch management. + * Add README.source which refers to the quilt documentation. + * debian/patches/limits.patch + - Add missing include to limits.h. This is required when compiling against + glibc 2.8. Thanks to Kees Cook for the patch. Closes: #501485 + + -- Michael Biebl Wed, 08 Oct 2008 21:34:34 +0200 + +libnl (1.1-2) unstable; urgency=low + + * debian/libnl-doc.doc-base + - Register the API documentation with doc-base. + * debian/control + - Add Suggests: doc-base to libnl-doc. + + -- Michael Biebl Wed, 05 Mar 2008 00:42:54 +0100 + +libnl (1.1-1) unstable; urgency=low + + * New stable upstream release. + * debian/patches/01-ip_mg_alg_internal_only.patch + - Removed, merged upstream. + * debian/control + - Rename binary package libnl1-pre8 to libnl1. + - [libnl1] Add Conflicts/Replaces: libnl1-pre8. + - [libnl-dev] Change Depends to libnl1. + * Rename debian/libnl1-pre8.install to debian/libnl1.install + * debian/copyright + - Minor updates and additions. + + -- Michael Biebl Thu, 10 Jan 2008 16:58:12 +0100 + +libnl (1.0~pre8-1) unstable; urgency=low + + * New upstream release. Closes: #456175 + * debian/control + - Bump Standards-Version to 3.7.3. No further changes required. + - The Vcs-* fields are now officially supported, so remove the XS- prefix. + - Rename binary package libnl1-pre6 to libnl1-pre8. + - [libnl1-pre8] Add Conflicts/Replaces: libnl1-pre6. The two versions are + not coinstallable. + - [libnl-dev] Change Depends to libnl1-pre8. + * Rename debian/libnl1-pre6.install to debian/libnl1-pre8.install. + * debian/patches/10-amd64-linux-types.patch + - Removed, merged upstream. + * debian/patches/01-ip_mg_alg_internal_only.patch + - Pull a fix from upstream. The header linux/ip_mp_alg.h is no longer part + of the linux kernel headers (i.e. linux-libc-dev) so remove it from + netlink/netlink.h. + + -- Michael Biebl Thu, 20 Dec 2007 07:45:03 +0100 + +libnl (1.0~pre6-6) unstable; urgency=low + + * debian/control + - Use the new "Homepage:" field to specify the upstream URL. + - Replace deprecated ${Source-Version} substvar with ${binary:Version}. + - Change Build-Depends: gs-gpl | gs-esp to Build-Depends: ghostscript. + + -- Michael Biebl Mon, 22 Oct 2007 07:15:29 +0200 + +libnl (1.0~pre6-5) unstable; urgency=low + + * debian/control + - Add XS-Vcs-* fields. + - Replace Build-Depends: tetex-bin with texlive-latex-base. teTeX is now + gone, superseded by texlive. + - Add Build-Depends: graphviz, gs-gpl | gs-esp. + The "dot" program is needed for generating the diagram image and "gs" + for the ps to png conversion. + + -- Michael Biebl Sun, 15 Apr 2007 15:45:48 +0200 + +libnl (1.0~pre6-4) unstable; urgency=medium + + * Autobuilders do not distinguish between build-arch and build-indep, they + simply run build. So we have to move doxygen and tetex-bin from + Build-Depends-Indep to Build-Depends. Closes: #408719 + * Urgency medium, as it fixes a FTBFS bug. + + -- Michael Biebl Fri, 12 Jan 2007 11:23:52 +0100 + +libnl (1.0~pre6-3) unstable; urgency=low + + * Build and package the API documentation. Closes: #406497 + * debian/control + - Add Build-Depends-Indep on doxygen and tetex-bin (dvips). + - Add new package libnl-doc. + - Add a "Suggests: libnl-doc" to libnl-dev. + * debian/rules + - Call "make gendoc" to build the API documentation. + * debian/libnl-doc.install + - Added. List the files that should be installed. + + -- Michael Biebl Fri, 12 Jan 2007 10:30:40 +0100 + +libnl (1.0~pre6-2) unstable; urgency=low + + * Update maintainer email address to biebl@debian.org. + + -- Michael Biebl Thu, 19 Oct 2006 20:16:09 +0200 + +libnl (1.0~pre6-1) unstable; urgency=low + + * New upstream release. + * Removed 20-autoconf-dirs.patch, merged upstream. + * Updated debian/copyright, libnl is now licensed under the LGPL 2.1. + * Updated debian/watch. + + -- Michael Biebl Fri, 18 Aug 2006 00:40:34 +0200 + +libnl (1.0~pre6~svn30-1) unstable; urgency=low + + * Updated to svn revision 30. + * Bumped Standards-Version to 3.7.2, no further changes required. + * Now that dak officially supports ~ in the version number, let's make use + of it. + * Some install directories were not set correctly, 20-autoconf-dirs.patch + fixes that. + + -- Michael Biebl Thu, 10 Aug 2006 19:51:42 +0200 + +libnl (0.99+1.0.svn21-4) unstable; urgency=low + + * Do not create bogus /usr/lib/pkg-config directory. Closes: #364601 + + -- Michael Biebl Mon, 24 Apr 2006 15:40:23 +0200 + +libnl (0.99+1.0.svn21-3) unstable; urgency=low + + * Include simple-patchsys.mk in debian/rules. + * Merged debian/patches/10-amd64-linux-types.patch from Ubuntu which fixes + the FTBFS error on AMD64. Closes: #358887 + Thanks to Scott James Remnant for this patch. + + -- Michael Biebl Sat, 1 Apr 2006 04:52:13 +0200 + +libnl (0.99+1.0.svn21-2) unstable; urgency=low + + * Initial upload to unstable. + * Renamed libnl1 to libnl1-pre6 to match the currently used so-name. + Otherwise dependent packages like NM will break on upgrades of libnl. + + -- Michael Biebl Tue, 7 Mar 2006 21:22:09 +0100 + +libnl (0.99+1.0.svn21-1) experimental; urgency=low + + * Initial release. Closes: #286847 + + -- Michael Biebl Tue, 21 Feb 2006 18:36:35 +0100 diff --git a/src/libnl3/debian/compat b/src/libnl3/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/src/libnl3/debian/compat @@ -0,0 +1 @@ +9 diff --git a/src/libnl3/debian/control b/src/libnl3/debian/control new file mode 100644 index 000000000000..ba5062607bc1 --- /dev/null +++ b/src/libnl3/debian/control @@ -0,0 +1,245 @@ +Source: libnl3 +Section: net +Priority: optional +Maintainer: Heiko Stuebner +Build-Depends: debhelper (>= 9), dh-exec (>= 0.3), cdbs (>= 0.4.93~), bison, flex, + automake, autoconf, dh-autoreconf, linux-libc-dev (>= 3.2.41), pkg-config +Standards-Version: 3.9.6 +Homepage: http://www.infradead.org/~tgr/libnl/ +#Vcs-Git: https://github.com/thom311/libnl/ +#Vcs-Browser: https://github.com/thom311/libnl/ + +Package: libnl-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + +Package: libnl-cli-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), libnl-genl-3-200 (= ${binary:Version}), libnl-nf-3-200 (= ${binary:Version}), libnl-route-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - cli helpers + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + Library for cli helpers in libnl-utils. + +Package: libnl-utils +Architecture: linux-any +Section: libs +Depends: libnl-cli-3-200 (= ${binary:Version}), libnl-idiag-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Description: Utilities for dealing with netlink sockets + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + These utilities help dealing with netlink sockets. + +Package: libnl-genl-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - generic netlink + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + API to the generic netlink protocol, an extended version of the netlink + protocol. + +Package: libnl-idiag-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - inetdiag interface + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + API to the inetdiag netlink protocol, handling inetdiag requests + +Package: libnl-nf-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), libnl-route-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - netfilter interface + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + API to netlink based netfilter configuration and monitoring interfaces. + +Package: libnl-route-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - route interface + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + API to the configuration interfaces of the NETLINK_ROUTE family. + +Package: libnl-xfrm-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - package transformations + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + API to netlink based package transformations (such as encrypting + their payloads). + +Package: libnl-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends} +Conflicts: libnl-dev, libnl2-dev +Breaks: libnl3-dev +Replaces: libnl3-dev +Multi-Arch: same +Description: development library and headers for libnl-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the headers needed by all libraries and the files + that are needed to build applications using libnl3. + +Package: libnl-cli-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-genl-3-dev (= ${binary:Version}), libnl-nf-3-dev (= ${binary:Version}), libnl-route-3-dev (= ${binary:Version}), libnl-cli-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-cli-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-cli-3. + +Package: libnl-genl-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-genl-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-genl-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-genl-3. + +Package: libnl-idiag-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-idiag-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-genl-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-idiag-3. + +Package: libnl-nf-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-route-3-dev (= ${binary:Version}), libnl-nf-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-nf-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-nf-3. + +Package: libnl-route-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-route-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-route-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-route-3. + +Package: libnl-xfrm-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-xfrm-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-xfrm-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-xfrm-3. + +Package: libnl-3-200-dbg +Architecture: linux-any +Section: debug +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends} +Priority: extra +Description: debug symbols for libnl3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains unstripped shared libraries. It is provided primarily + to provide a backtrace with names in a debugger, this makes it somewhat easier + to interpret core dumps. The libraries are installed in /usr/lib/debug and + are automatically used by gdb. + +Package: libnl-3-200-udeb +Architecture: linux-any +XC-Package-Type: udeb +Section: debian-installer +Depends: ${misc:Depends}, ${shlibs:Depends} +Description: library for dealing with netlink sockets + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package is a udeb. It's only useful inside of debian-installer. + +Package: libnl-genl-3-200-udeb +Architecture: linux-any +XC-Package-Type: udeb +Section: debian-installer +Depends: libnl-3-200-udeb (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Description: library for dealing with netlink sockets - generic netlink + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package is a udeb. It's only useful inside of debian-installer. diff --git a/src/libnl3/debian/copyright b/src/libnl3/debian/copyright new file mode 100644 index 000000000000..07457363bf67 --- /dev/null +++ b/src/libnl3/debian/copyright @@ -0,0 +1,160 @@ +This package was debianized by Tamer Ahmed on +Tue, 31 Decn 2019 12:00:46 +0000. +The packaging is based on Heiko Stuebner's original packaging +of libnl1. + +It was downloaded from https://github.com/thom311/libnl/releases + +Upstream Author: + Thomas Graf + + +Copyright: + +lib/route/addr.c +include/netlink/route/addr.h + + Copyright (c) Thomas Graf + Baruch Even + + +lib/route/cls/u32.c +lib/route/cls/fw.c +lib/route/sch/htb.c +include/netlink/route/cls/fw.h +include/netlink/route/sch/htb.h + + Copyright (c) Thomas Graf + Copyright (c) Petr Gotthard + Copyright (c) Siemens AG Oesterreich + + + +lib/netfilter/log_msg.c +lib/netfilter/ct.c +include/netlink/netfilter/log_msg.h +include/netlink/netfilter/log.h +lib/netfilter/log_obj.c + + Copyright (c) Thomas Graf + Copyright (c) Philip Craig + Copyright (c) Patrick McHardy + Copyright (c) Secure Computing Corporation + + + +include/netlink/netfilter/queue_msg.h +lib/netfilter/queue_msg_obj.c +lib/netfilter/queue_msg.c +lib/netfilter/queue.c +lib/netfilter/netfilter.c +lib/netfilter/queue_obj.c +include/netlink/netfilter/netfilter.h +include/netlink/netfilter/queue.h +src/nf-queue.c + + Copyright (c) Patrick McHardy + + + +include/netlink/xfrm/selector.h +include/netlink/xfrm/sa.h +include/netlink/xfrm/ae.h +include/netlink/xfrm/sp.h +include/netlink/xfrm/template.h +include/netlink/xfrm/lifetime.h +lib/xfrm/sa.c +lib/xfrm/template.c +lib/xfrm/ae.c +lib/xfrm/sp.c +lib/xfrm/selector.c +lib/xfrm/lifetime.c + + Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + + +All other *.c and *.h files not mentioned above are copyright of: + + Copyright (c) 2003-2006 Thomas Graf + + +License: + +src/nl-addr-add.c +src/nl-addr-list.c +src/nl-cls-add.c +src/cls/utils.c +src/cls/cgroup.c +src/cls/utils.h +src/cls/basic.c +src/nl-addr-delete.c: + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation version 2 of the License. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + +On Debian GNU/Linux systems, the complete text of the GNU General +Public License can be found in /usr/share/common-licenses/GPL-2 + + +include/netlink/xfrm/selector.h +include/netlink/xfrm/sa.h +include/netlink/xfrm/ae.h +include/netlink/xfrm/sp.h +include/netlink/xfrm/template.h +include/netlink/xfrm/lifetime.h +lib/xfrm/sa.c +lib/xfrm/template.c +lib/xfrm/ae.c +lib/xfrm/sp.c +lib/xfrm/selector.c +lib/xfrm/lifetime.c + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the + distribution. + + Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +All other *.c and *.h files not mentioned above: + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation version 2.1 of the License. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + +On Debian GNU/Linux systems, the complete text of the GNU Lesser General +Public License can be found in /usr/share/common-licenses/LGPL-2.1 + diff --git a/src/libnl3/debian/gbp.conf b/src/libnl3/debian/gbp.conf new file mode 100644 index 000000000000..a504bacc7748 --- /dev/null +++ b/src/libnl3/debian/gbp.conf @@ -0,0 +1,16 @@ +# Configuration file for git-buildpackage and friends + +[DEFAULT] +# the default build command: +#builder = debuild -i -I +# the default clean command: +#cleaner = debuild clean +# the default branch for upstream sources: +upstream-branch = upstream-dist +# the default branch for the debian patch: +#debian-branch = master +# the default tag formats used: +#upstream-tag = upstream/%(version)s +#debian-tag = debian/%(version)s +# use pristine-tar: +pristine-tar = true diff --git a/src/libnl3/debian/libnl-3-200-udeb.install b/src/libnl3/debian/libnl-3-200-udeb.install new file mode 100644 index 000000000000..4b3a77ce011d --- /dev/null +++ b/src/libnl3/debian/libnl-3-200-udeb.install @@ -0,0 +1 @@ +usr/lib/*/libnl-3.so.* lib diff --git a/src/libnl3/debian/libnl-3-200.install b/src/libnl3/debian/libnl-3-200.install new file mode 100755 index 000000000000..0a6aa3850b2c --- /dev/null +++ b/src/libnl3/debian/libnl-3-200.install @@ -0,0 +1,3 @@ +#!/usr/bin/dh-exec +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-3*.so.* lib/${DEB_HOST_MULTIARCH}/ +debian/tmp/etc/libnl/* etc/libnl-3 diff --git a/src/libnl3/debian/libnl-3-200.symbols b/src/libnl3/debian/libnl-3-200.symbols new file mode 100644 index 000000000000..119e0554920f --- /dev/null +++ b/src/libnl3/debian/libnl-3-200.symbols @@ -0,0 +1,661 @@ +libnl-3.so.200 libnl-3-200 #MINVER# + __flags2str@Base 3.5.0-1 + __flags2str@libnl_3 3.5.0-1 + __list_str2type@Base 3.5.0-1 + __list_str2type@libnl_3 3.5.0-1 + __list_type2str@Base 3.5.0-1 + __list_type2str@libnl_3 3.5.0-1 + __nl_cache_mngt_require@Base 3.5.0-1 + __nl_cache_mngt_require@libnl_3 3.5.0-1 + __nl_cache_ops_lookup@Base 3.5.0-1 + __nl_read_num_str_file@Base 3.5.0-1 + __nl_read_num_str_file@libnl_3 3.5.0-1 + __str2flags@Base 3.5.0-1 + __str2flags@libnl_3 3.5.0-1 + __str2type@Base 3.5.0-1 + __str2type@libnl_3 3.5.0-1 + __trans_list_add@Base 3.5.0-1 + __trans_list_add@libnl_3 3.5.0-1 + __trans_list_clear@Base 3.5.0-1 + __trans_list_clear@libnl_3 3.5.0-1 + __type2str@Base 3.5.0-1 + __type2str@libnl_3 3.5.0-1 + _nl_socket_generate_local_port_no_release@Base 3.5.0-1 + _nl_socket_is_local_port_unspecified@Base 3.5.0-1 + _nl_socket_set_local_port_no_release@Base 3.5.0-1 + _nl_socket_used_ports_release_all@Base 3.5.0-1 + _nl_socket_used_ports_set@Base 3.5.0-1 + dump_from_ops@Base 3.5.0-1 + libnl_3@libnl_3 3.5.0-1 + libnl_3_2_26@libnl_3_2_26 3.5.0-1 + libnl_3_2_27@libnl_3_2_27 3.5.0-1 + libnl_3_2_28@libnl_3_2_28 3.5.0-1 + libnl_3_2_29@libnl_3_2_29 3.5.0-1 + libnl_3_5@libnl_3_5 3.5.0-1 + nl_addr2str@Base 3.5.0-1 + nl_addr2str@libnl_3 3.5.0-1 + nl_addr_alloc@Base 3.5.0-1 + nl_addr_alloc@libnl_3 3.5.0-1 + nl_addr_alloc_attr@Base 3.5.0-1 + nl_addr_alloc_attr@libnl_3 3.5.0-1 + nl_addr_build@Base 3.5.0-1 + nl_addr_build@libnl_3 3.5.0-1 + nl_addr_clone@Base 3.5.0-1 + nl_addr_clone@libnl_3 3.5.0-1 + nl_addr_cmp@Base 3.5.0-1 + nl_addr_cmp@libnl_3 3.5.0-1 + nl_addr_cmp_prefix@Base 3.5.0-1 + nl_addr_cmp_prefix@libnl_3 3.5.0-1 + nl_addr_fill_sockaddr@Base 3.5.0-1 + nl_addr_fill_sockaddr@libnl_3 3.5.0-1 + nl_addr_get@Base 3.5.0-1 + nl_addr_get@libnl_3 3.5.0-1 + nl_addr_get_binary_addr@Base 3.5.0-1 + nl_addr_get_binary_addr@libnl_3 3.5.0-1 + nl_addr_get_family@Base 3.5.0-1 + nl_addr_get_family@libnl_3 3.5.0-1 + nl_addr_get_len@Base 3.5.0-1 + nl_addr_get_len@libnl_3 3.5.0-1 + nl_addr_get_prefixlen@Base 3.5.0-1 + nl_addr_get_prefixlen@libnl_3 3.5.0-1 + nl_addr_guess_family@Base 3.5.0-1 + nl_addr_guess_family@libnl_3 3.5.0-1 + nl_addr_info@Base 3.5.0-1 + nl_addr_info@libnl_3 3.5.0-1 + nl_addr_iszero@Base 3.5.0-1 + nl_addr_iszero@libnl_3 3.5.0-1 + nl_addr_parse@Base 3.5.0-1 + nl_addr_parse@libnl_3 3.5.0-1 + nl_addr_put@Base 3.5.0-1 + nl_addr_put@libnl_3 3.5.0-1 + nl_addr_resolve@Base 3.5.0-1 + nl_addr_resolve@libnl_3 3.5.0-1 + nl_addr_set_binary_addr@Base 3.5.0-1 + nl_addr_set_binary_addr@libnl_3 3.5.0-1 + nl_addr_set_family@Base 3.5.0-1 + nl_addr_set_family@libnl_3 3.5.0-1 + nl_addr_set_prefixlen@Base 3.5.0-1 + nl_addr_set_prefixlen@libnl_3 3.5.0-1 + nl_addr_shared@Base 3.5.0-1 + nl_addr_shared@libnl_3 3.5.0-1 + nl_addr_valid@Base 3.5.0-1 + nl_addr_valid@libnl_3 3.5.0-1 + nl_af2str@Base 3.5.0-1 + nl_af2str@libnl_3 3.5.0-1 + nl_auto_complete@Base 3.5.0-1 + nl_auto_complete@libnl_3 3.5.0-1 + nl_cache_add@Base 3.5.0-1 + nl_cache_add@libnl_3 3.5.0-1 + nl_cache_alloc@Base 3.5.0-1 + nl_cache_alloc@libnl_3 3.5.0-1 + nl_cache_alloc_and_fill@Base 3.5.0-1 + nl_cache_alloc_and_fill@libnl_3 3.5.0-1 + nl_cache_alloc_name@Base 3.5.0-1 + nl_cache_alloc_name@libnl_3 3.5.0-1 + nl_cache_clear@Base 3.5.0-1 + nl_cache_clear@libnl_3 3.5.0-1 + nl_cache_clone@Base 3.5.0-1 + nl_cache_clone@libnl_3 3.5.0-1 + nl_cache_dump@Base 3.5.0-1 + nl_cache_dump@libnl_3 3.5.0-1 + nl_cache_dump_filter@Base 3.5.0-1 + nl_cache_dump_filter@libnl_3 3.5.0-1 + nl_cache_find@Base 3.5.0-1 + nl_cache_find@libnl_3 3.5.0-1 + nl_cache_foreach@Base 3.5.0-1 + nl_cache_foreach@libnl_3 3.5.0-1 + nl_cache_foreach_filter@Base 3.5.0-1 + nl_cache_foreach_filter@libnl_3 3.5.0-1 + nl_cache_free@Base 3.5.0-1 + nl_cache_free@libnl_3 3.5.0-1 + nl_cache_get@Base 3.5.0-1 + nl_cache_get@libnl_3 3.5.0-1 + nl_cache_get_first@Base 3.5.0-1 + nl_cache_get_first@libnl_3 3.5.0-1 + nl_cache_get_last@Base 3.5.0-1 + nl_cache_get_last@libnl_3 3.5.0-1 + nl_cache_get_next@Base 3.5.0-1 + nl_cache_get_next@libnl_3 3.5.0-1 + nl_cache_get_ops@Base 3.5.0-1 + nl_cache_get_ops@libnl_3 3.5.0-1 + nl_cache_get_prev@Base 3.5.0-1 + nl_cache_get_prev@libnl_3 3.5.0-1 + nl_cache_include@Base 3.5.0-1 + nl_cache_include@libnl_3 3.5.0-1 + nl_cache_include_v2@libnl_3_2_29 3.5.0-1 + nl_cache_is_empty@Base 3.5.0-1 + nl_cache_is_empty@libnl_3 3.5.0-1 + nl_cache_mark_all@Base 3.5.0-1 + nl_cache_mark_all@libnl_3 3.5.0-1 + nl_cache_mngr_add@Base 3.5.0-1 + nl_cache_mngr_add@libnl_3 3.5.0-1 + nl_cache_mngr_add_cache@Base 3.5.0-1 + nl_cache_mngr_add_cache@libnl_3 3.5.0-1 + nl_cache_mngr_add_cache_v2@libnl_3_2_29 3.5.0-1 + nl_cache_mngr_alloc@Base 3.5.0-1 + nl_cache_mngr_alloc@libnl_3 3.5.0-1 + nl_cache_mngr_data_ready@Base 3.5.0-1 + nl_cache_mngr_data_ready@libnl_3 3.5.0-1 + nl_cache_mngr_free@Base 3.5.0-1 + nl_cache_mngr_free@libnl_3 3.5.0-1 + nl_cache_mngr_get_fd@Base 3.5.0-1 + nl_cache_mngr_get_fd@libnl_3 3.5.0-1 + nl_cache_mngr_info@Base 3.5.0-1 + nl_cache_mngr_info@libnl_3 3.5.0-1 + nl_cache_mngr_poll@Base 3.5.0-1 + nl_cache_mngr_poll@libnl_3 3.5.0-1 + nl_cache_mngt_provide@Base 3.5.0-1 + nl_cache_mngt_provide@libnl_3 3.5.0-1 + nl_cache_mngt_register@Base 3.5.0-1 + nl_cache_mngt_register@libnl_3 3.5.0-1 + nl_cache_mngt_require@Base 3.5.0-1 + nl_cache_mngt_require@libnl_3 3.5.0-1 + nl_cache_mngt_require_safe@Base 3.5.0-1 + nl_cache_mngt_require_safe@libnl_3 3.5.0-1 + nl_cache_mngt_unprovide@Base 3.5.0-1 + nl_cache_mngt_unprovide@libnl_3 3.5.0-1 + nl_cache_mngt_unregister@Base 3.5.0-1 + nl_cache_mngt_unregister@libnl_3 3.5.0-1 + nl_cache_move@Base 3.5.0-1 + nl_cache_move@libnl_3 3.5.0-1 + nl_cache_nitems@Base 3.5.0-1 + nl_cache_nitems@libnl_3 3.5.0-1 + nl_cache_nitems_filter@Base 3.5.0-1 + nl_cache_nitems_filter@libnl_3 3.5.0-1 + nl_cache_ops_associate@Base 3.5.0-1 + nl_cache_ops_associate@libnl_3 3.5.0-1 + nl_cache_ops_associate_safe@Base 3.5.0-1 + nl_cache_ops_associate_safe@libnl_3 3.5.0-1 + nl_cache_ops_foreach@Base 3.5.0-1 + nl_cache_ops_foreach@libnl_3 3.5.0-1 + nl_cache_ops_get@Base 3.5.0-1 + nl_cache_ops_get@libnl_3 3.5.0-1 + nl_cache_ops_lookup@Base 3.5.0-1 + nl_cache_ops_lookup@libnl_3 3.5.0-1 + nl_cache_ops_lookup_safe@Base 3.5.0-1 + nl_cache_ops_lookup_safe@libnl_3 3.5.0-1 + nl_cache_ops_put@Base 3.5.0-1 + nl_cache_ops_put@libnl_3 3.5.0-1 + nl_cache_ops_set_flags@Base 3.5.0-1 + nl_cache_ops_set_flags@libnl_3 3.5.0-1 + nl_cache_parse@Base 3.5.0-1 + nl_cache_parse@libnl_3 3.5.0-1 + nl_cache_parse_and_add@Base 3.5.0-1 + nl_cache_parse_and_add@libnl_3 3.5.0-1 + nl_cache_pickup@Base 3.5.0-1 + nl_cache_pickup@libnl_3 3.5.0-1 + nl_cache_pickup_checkdup@Base 3.5.0-1 + nl_cache_pickup_checkdup@libnl_3 3.5.0-1 + nl_cache_put@Base 3.5.0-1 + nl_cache_put@libnl_3 3.5.0-1 + nl_cache_refill@Base 3.5.0-1 + nl_cache_refill@libnl_3 3.5.0-1 + nl_cache_remove@Base 3.5.0-1 + nl_cache_remove@libnl_3 3.5.0-1 + nl_cache_resync@Base 3.5.0-1 + nl_cache_resync@libnl_3 3.5.0-1 + nl_cache_search@Base 3.5.0-1 + nl_cache_search@libnl_3 3.5.0-1 + nl_cache_set_arg1@Base 3.5.0-1 + nl_cache_set_arg1@libnl_3 3.5.0-1 + nl_cache_set_arg2@Base 3.5.0-1 + nl_cache_set_arg2@libnl_3 3.5.0-1 + nl_cache_set_flags@Base 3.5.0-1 + nl_cache_set_flags@libnl_3 3.5.0-1 + nl_cache_subset@Base 3.5.0-1 + nl_cache_subset@libnl_3 3.5.0-1 + nl_cancel_down_bits@Base 3.5.0-1 + nl_cancel_down_bits@libnl_3 3.5.0-1 + nl_cancel_down_bytes@Base 3.5.0-1 + nl_cancel_down_bytes@libnl_3 3.5.0-1 + nl_cancel_down_us@Base 3.5.0-1 + nl_cancel_down_us@libnl_3 3.5.0-1 + nl_cb_active_type@Base 3.5.0-1 + nl_cb_active_type@libnl_3 3.5.0-1 + nl_cb_alloc@Base 3.5.0-1 + nl_cb_alloc@libnl_3 3.5.0-1 + nl_cb_clone@Base 3.5.0-1 + nl_cb_clone@libnl_3 3.5.0-1 + nl_cb_err@Base 3.5.0-1 + nl_cb_err@libnl_3 3.5.0-1 + nl_cb_get@Base 3.5.0-1 + nl_cb_get@libnl_3 3.5.0-1 + nl_cb_overwrite_recv@Base 3.5.0-1 + nl_cb_overwrite_recv@libnl_3 3.5.0-1 + nl_cb_overwrite_recvmsgs@Base 3.5.0-1 + nl_cb_overwrite_recvmsgs@libnl_3 3.5.0-1 + nl_cb_overwrite_send@Base 3.5.0-1 + nl_cb_overwrite_send@libnl_3 3.5.0-1 + nl_cb_put@Base 3.5.0-1 + nl_cb_put@libnl_3 3.5.0-1 + nl_cb_set@Base 3.5.0-1 + nl_cb_set@libnl_3 3.5.0-1 + nl_cb_set_all@Base 3.5.0-1 + nl_cb_set_all@libnl_3 3.5.0-1 + nl_close@Base 3.5.0-1 + nl_close@libnl_3 3.5.0-1 + nl_complete_msg@Base 3.5.0-1 + nl_complete_msg@libnl_3 3.5.0-1 + nl_connect@Base 3.5.0-1 + nl_connect@libnl_3 3.5.0-1 + nl_data_alloc@Base 3.5.0-1 + nl_data_alloc@libnl_3 3.5.0-1 + nl_data_alloc_attr@Base 3.5.0-1 + nl_data_alloc_attr@libnl_3 3.5.0-1 + nl_data_append@Base 3.5.0-1 + nl_data_append@libnl_3 3.5.0-1 + nl_data_clone@Base 3.5.0-1 + nl_data_clone@libnl_3 3.5.0-1 + nl_data_cmp@Base 3.5.0-1 + nl_data_cmp@libnl_3 3.5.0-1 + nl_data_free@Base 3.5.0-1 + nl_data_free@libnl_3 3.5.0-1 + nl_data_get@Base 3.5.0-1 + nl_data_get@libnl_3 3.5.0-1 + nl_data_get_size@Base 3.5.0-1 + nl_data_get_size@libnl_3 3.5.0-1 + nl_debug@Base 3.5.0-1 + nl_debug@libnl_3 3.5.0-1 + nl_debug_dp@Base 3.5.0-1 + nl_debug_dp@libnl_3 3.5.0-1 + nl_dump@Base 3.5.0-1 + nl_dump@libnl_3 3.5.0-1 + nl_dump_line@Base 3.5.0-1 + nl_dump_line@libnl_3 3.5.0-1 + nl_ether_proto2str@Base 3.5.0-1 + nl_ether_proto2str@libnl_3 3.5.0-1 + nl_get_psched_hz@Base 3.5.0-1 + nl_get_psched_hz@libnl_3 3.5.0-1 + nl_get_user_hz@Base 3.5.0-1 + nl_get_user_hz@libnl_3 3.5.0-1 + nl_geterror@Base 3.5.0-1 + nl_geterror@libnl_3 3.5.0-1 + nl_has_capability@Base 3.5.0-1 + nl_has_capability@libnl_3 3.5.0-1 + nl_hash@Base 3.5.0-1 + nl_hash@libnl_3 3.5.0-1 + nl_hash_any@Base 3.5.0-1 + nl_hash_any@libnl_3 3.5.0-1 + nl_hash_table_add@Base 3.5.0-1 + nl_hash_table_add@libnl_3 3.5.0-1 + nl_hash_table_alloc@Base 3.5.0-1 + nl_hash_table_alloc@libnl_3 3.5.0-1 + nl_hash_table_del@Base 3.5.0-1 + nl_hash_table_del@libnl_3 3.5.0-1 + nl_hash_table_free@Base 3.5.0-1 + nl_hash_table_free@libnl_3 3.5.0-1 + nl_hash_table_lookup@Base 3.5.0-1 + nl_hash_table_lookup@libnl_3 3.5.0-1 + nl_ip_proto2str@Base 3.5.0-1 + nl_ip_proto2str@libnl_3 3.5.0-1 + nl_join_groups@Base 3.5.0-1 + nl_join_groups@libnl_3 3.5.0-1 + nl_llproto2str@Base 3.5.0-1 + nl_llproto2str@libnl_3 3.5.0-1 + nl_msec2str@Base 3.5.0-1 + nl_msec2str@libnl_3 3.5.0-1 + nl_msg_dump@Base 3.5.0-1 + nl_msg_dump@libnl_3 3.5.0-1 + nl_msg_parse@Base 3.5.0-1 + nl_msg_parse@libnl_3 3.5.0-1 + nl_msgtype_lookup@Base 3.5.0-1 + nl_msgtype_lookup@libnl_3 3.5.0-1 + nl_new_line@Base 3.5.0-1 + nl_new_line@libnl_3 3.5.0-1 + nl_nlfamily2str@Base 3.5.0-1 + nl_nlfamily2str@libnl_3 3.5.0-1 + nl_nlmsg_flags2str@Base 3.5.0-1 + nl_nlmsg_flags2str@libnl_3 3.5.0-1 + nl_nlmsgtype2str@Base 3.5.0-1 + nl_nlmsgtype2str@libnl_3 3.5.0-1 + nl_object_alloc@Base 3.5.0-1 + nl_object_alloc@libnl_3 3.5.0-1 + nl_object_alloc_name@Base 3.5.0-1 + nl_object_alloc_name@libnl_3 3.5.0-1 + nl_object_attr_list@Base 3.5.0-1 + nl_object_attr_list@libnl_3 3.5.0-1 + nl_object_attrs2str@Base 3.5.0-1 + nl_object_attrs2str@libnl_3 3.5.0-1 + nl_object_clone@Base 3.5.0-1 + nl_object_clone@libnl_3 3.5.0-1 + nl_object_diff64@libnl_3_2_28 3.5.0-1 + nl_object_diff@Base 3.5.0-1 + nl_object_diff@libnl_3 3.5.0-1 + nl_object_dump@Base 3.5.0-1 + nl_object_dump@libnl_3 3.5.0-1 + nl_object_dump_buf@Base 3.5.0-1 + nl_object_dump_buf@libnl_3 3.5.0-1 + nl_object_free@Base 3.5.0-1 + nl_object_free@libnl_3 3.5.0-1 + nl_object_get@Base 3.5.0-1 + nl_object_get@libnl_3 3.5.0-1 + nl_object_get_cache@Base 3.5.0-1 + nl_object_get_cache@libnl_3 3.5.0-1 + nl_object_get_id_attrs@Base 3.5.0-1 + nl_object_get_id_attrs@libnl_3 3.5.0-1 + nl_object_get_msgtype@Base 3.5.0-1 + nl_object_get_msgtype@libnl_3 3.5.0-1 + nl_object_get_ops@Base 3.5.0-1 + nl_object_get_ops@libnl_3 3.5.0-1 + nl_object_get_refcnt@Base 3.5.0-1 + nl_object_get_refcnt@libnl_3 3.5.0-1 + nl_object_get_type@Base 3.5.0-1 + nl_object_get_type@libnl_3 3.5.0-1 + nl_object_identical@Base 3.5.0-1 + nl_object_identical@libnl_3 3.5.0-1 + nl_object_is_marked@Base 3.5.0-1 + nl_object_is_marked@libnl_3 3.5.0-1 + nl_object_keygen@Base 3.5.0-1 + nl_object_keygen@libnl_3 3.5.0-1 + nl_object_mark@Base 3.5.0-1 + nl_object_mark@libnl_3 3.5.0-1 + nl_object_match_filter@Base 3.5.0-1 + nl_object_match_filter@libnl_3 3.5.0-1 + nl_object_put@Base 3.5.0-1 + nl_object_put@libnl_3 3.5.0-1 + nl_object_shared@Base 3.5.0-1 + nl_object_shared@libnl_3 3.5.0-1 + nl_object_unmark@Base 3.5.0-1 + nl_object_unmark@libnl_3 3.5.0-1 + nl_object_update@Base 3.5.0-1 + nl_object_update@libnl_3 3.5.0-1 + nl_perror@Base 3.5.0-1 + nl_perror@libnl_3 3.5.0-1 + nl_pickup@Base 3.5.0-1 + nl_pickup@libnl_3 3.5.0-1 + nl_pickup_keep_syserr@Base 3.5.0-1 + nl_pickup_keep_syserr@libnl_3 3.5.0-1 + nl_prob2int@Base 3.5.0-1 + nl_prob2int@libnl_3 3.5.0-1 + nl_rate2str@Base 3.5.0-1 + nl_rate2str@libnl_3 3.5.0-1 + nl_recv@Base 3.5.0-1 + nl_recv@libnl_3 3.5.0-1 + nl_recvmsgs@Base 3.5.0-1 + nl_recvmsgs@libnl_3 3.5.0-1 + nl_recvmsgs_default@Base 3.5.0-1 + nl_recvmsgs_default@libnl_3 3.5.0-1 + nl_recvmsgs_report@Base 3.5.0-1 + nl_recvmsgs_report@libnl_3 3.5.0-1 + nl_send@Base 3.5.0-1 + nl_send@libnl_3 3.5.0-1 + nl_send_auto@Base 3.5.0-1 + nl_send_auto@libnl_3 3.5.0-1 + nl_send_auto_complete@Base 3.5.0-1 + nl_send_auto_complete@libnl_3 3.5.0-1 + nl_send_iovec@Base 3.5.0-1 + nl_send_iovec@libnl_3 3.5.0-1 + nl_send_simple@Base 3.5.0-1 + nl_send_simple@libnl_3 3.5.0-1 + nl_send_sync@Base 3.5.0-1 + nl_send_sync@libnl_3 3.5.0-1 + nl_sendmsg@Base 3.5.0-1 + nl_sendmsg@libnl_3 3.5.0-1 + nl_sendto@Base 3.5.0-1 + nl_sendto@libnl_3 3.5.0-1 + nl_size2int@Base 3.5.0-1 + nl_size2int@libnl_3 3.5.0-1 + nl_size2str@Base 3.5.0-1 + nl_size2str@libnl_3 3.5.0-1 + nl_socket_add_membership@Base 3.5.0-1 + nl_socket_add_membership@libnl_3 3.5.0-1 + nl_socket_add_memberships@Base 3.5.0-1 + nl_socket_add_memberships@libnl_3 3.5.0-1 + nl_socket_alloc@Base 3.5.0-1 + nl_socket_alloc@libnl_3 3.5.0-1 + nl_socket_alloc_cb@Base 3.5.0-1 + nl_socket_alloc_cb@libnl_3 3.5.0-1 + nl_socket_disable_auto_ack@Base 3.5.0-1 + nl_socket_disable_auto_ack@libnl_3 3.5.0-1 + nl_socket_disable_msg_peek@Base 3.5.0-1 + nl_socket_disable_msg_peek@libnl_3 3.5.0-1 + nl_socket_disable_seq_check@Base 3.5.0-1 + nl_socket_disable_seq_check@libnl_3 3.5.0-1 + nl_socket_drop_membership@Base 3.5.0-1 + nl_socket_drop_membership@libnl_3 3.5.0-1 + nl_socket_drop_memberships@Base 3.5.0-1 + nl_socket_drop_memberships@libnl_3 3.5.0-1 + nl_socket_enable_auto_ack@Base 3.5.0-1 + nl_socket_enable_auto_ack@libnl_3 3.5.0-1 + nl_socket_enable_msg_peek@Base 3.5.0-1 + nl_socket_enable_msg_peek@libnl_3 3.5.0-1 + nl_socket_free@Base 3.5.0-1 + nl_socket_free@libnl_3 3.5.0-1 + nl_socket_get_cb@Base 3.5.0-1 + nl_socket_get_cb@libnl_3 3.5.0-1 + nl_socket_get_fd@Base 3.5.0-1 + nl_socket_get_fd@libnl_3 3.5.0-1 + nl_socket_get_local_port@Base 3.5.0-1 + nl_socket_get_local_port@libnl_3 3.5.0-1 + nl_socket_get_msg_buf_size@Base 3.5.0-1 + nl_socket_get_msg_buf_size@libnl_3 3.5.0-1 + nl_socket_get_peer_groups@Base 3.5.0-1 + nl_socket_get_peer_groups@libnl_3 3.5.0-1 + nl_socket_get_peer_port@Base 3.5.0-1 + nl_socket_get_peer_port@libnl_3 3.5.0-1 + nl_socket_modify_cb@Base 3.5.0-1 + nl_socket_modify_cb@libnl_3 3.5.0-1 + nl_socket_modify_err_cb@Base 3.5.0-1 + nl_socket_modify_err_cb@libnl_3 3.5.0-1 + nl_socket_recv_pktinfo@Base 3.5.0-1 + nl_socket_recv_pktinfo@libnl_3 3.5.0-1 + nl_socket_set_buffer_size@Base 3.5.0-1 + nl_socket_set_buffer_size@libnl_3 3.5.0-1 + nl_socket_set_cb@Base 3.5.0-1 + nl_socket_set_cb@libnl_3 3.5.0-1 + nl_socket_set_fd@Base 3.5.0-1 + nl_socket_set_fd@libnl_3_2_26 3.5.0-1 + nl_socket_set_local_port@Base 3.5.0-1 + nl_socket_set_local_port@libnl_3 3.5.0-1 + nl_socket_set_msg_buf_size@Base 3.5.0-1 + nl_socket_set_msg_buf_size@libnl_3 3.5.0-1 + nl_socket_set_nonblocking@Base 3.5.0-1 + nl_socket_set_nonblocking@libnl_3 3.5.0-1 + nl_socket_set_passcred@Base 3.5.0-1 + nl_socket_set_passcred@libnl_3 3.5.0-1 + nl_socket_set_peer_groups@Base 3.5.0-1 + nl_socket_set_peer_groups@libnl_3 3.5.0-1 + nl_socket_set_peer_port@Base 3.5.0-1 + nl_socket_set_peer_port@libnl_3 3.5.0-1 + nl_socket_use_seq@Base 3.5.0-1 + nl_socket_use_seq@libnl_3 3.5.0-1 + nl_str2af@Base 3.5.0-1 + nl_str2af@libnl_3 3.5.0-1 + nl_str2ether_proto@Base 3.5.0-1 + nl_str2ether_proto@libnl_3 3.5.0-1 + nl_str2ip_proto@Base 3.5.0-1 + nl_str2ip_proto@libnl_3 3.5.0-1 + nl_str2llproto@Base 3.5.0-1 + nl_str2llproto@libnl_3 3.5.0-1 + nl_str2msec@Base 3.5.0-1 + nl_str2msec@libnl_3 3.5.0-1 + nl_str2nlfamily@Base 3.5.0-1 + nl_str2nlfamily@libnl_3 3.5.0-1 + nl_str2nlmsgtype@Base 3.5.0-1 + nl_str2nlmsgtype@libnl_3 3.5.0-1 + nl_strerror_l@libnl_3_2_29 3.5.0-1 + nl_syserr2nlerr@Base 3.5.0-1 + nl_syserr2nlerr@libnl_3 3.5.0-1 + nl_ticks2us@Base 3.5.0-1 + nl_ticks2us@libnl_3 3.5.0-1 + nl_us2ticks@Base 3.5.0-1 + nl_us2ticks@libnl_3 3.5.0-1 + nl_ver_maj@Base 3.5.0-1 + nl_ver_maj@libnl_3 3.5.0-1 + nl_ver_mic@Base 3.5.0-1 + nl_ver_mic@libnl_3 3.5.0-1 + nl_ver_min@Base 3.5.0-1 + nl_ver_min@libnl_3 3.5.0-1 + nl_ver_num@Base 3.5.0-1 + nl_ver_num@libnl_3 3.5.0-1 + nl_wait_for_ack@Base 3.5.0-1 + nl_wait_for_ack@libnl_3 3.5.0-1 + nla_attr_size@Base 3.5.0-1 + nla_attr_size@libnl_3 3.5.0-1 + nla_data@Base 3.5.0-1 + nla_data@libnl_3 3.5.0-1 + nla_find@Base 3.5.0-1 + nla_find@libnl_3 3.5.0-1 + nla_get_flag@Base 3.5.0-1 + nla_get_flag@libnl_3 3.5.0-1 + nla_get_msecs@Base 3.5.0-1 + nla_get_msecs@libnl_3 3.5.0-1 + nla_get_s16@Base 3.5.0-1 + nla_get_s16@libnl_3_2_27 3.5.0-1 + nla_get_s32@Base 3.5.0-1 + nla_get_s32@libnl_3_2_27 3.5.0-1 + nla_get_s64@Base 3.5.0-1 + nla_get_s64@libnl_3_2_27 3.5.0-1 + nla_get_s8@Base 3.5.0-1 + nla_get_s8@libnl_3_2_27 3.5.0-1 + nla_get_string@Base 3.5.0-1 + nla_get_string@libnl_3 3.5.0-1 + nla_get_u16@Base 3.5.0-1 + nla_get_u16@libnl_3 3.5.0-1 + nla_get_u32@Base 3.5.0-1 + nla_get_u32@libnl_3 3.5.0-1 + nla_get_u64@Base 3.5.0-1 + nla_get_u64@libnl_3 3.5.0-1 + nla_get_u8@Base 3.5.0-1 + nla_get_u8@libnl_3 3.5.0-1 + nla_is_nested@Base 3.5.0-1 + nla_is_nested@libnl_3 3.5.0-1 + nla_len@Base 3.5.0-1 + nla_len@libnl_3 3.5.0-1 + nla_memcmp@Base 3.5.0-1 + nla_memcmp@libnl_3 3.5.0-1 + nla_memcpy@Base 3.5.0-1 + nla_memcpy@libnl_3 3.5.0-1 + nla_nest_cancel@Base 3.5.0-1 + nla_nest_cancel@libnl_3 3.5.0-1 + nla_nest_end@Base 3.5.0-1 + nla_nest_end@libnl_3 3.5.0-1 + nla_nest_end_keep_empty@libnl_3_5 3.5.0-1 + nla_nest_start@Base 3.5.0-1 + nla_nest_start@libnl_3 3.5.0-1 + nla_next@Base 3.5.0-1 + nla_next@libnl_3 3.5.0-1 + nla_ok@Base 3.5.0-1 + nla_ok@libnl_3 3.5.0-1 + nla_padlen@Base 3.5.0-1 + nla_padlen@libnl_3 3.5.0-1 + nla_parse@Base 3.5.0-1 + nla_parse@libnl_3 3.5.0-1 + nla_parse_nested@Base 3.5.0-1 + nla_parse_nested@libnl_3 3.5.0-1 + nla_put@Base 3.5.0-1 + nla_put@libnl_3 3.5.0-1 + nla_put_addr@Base 3.5.0-1 + nla_put_addr@libnl_3 3.5.0-1 + nla_put_data@Base 3.5.0-1 + nla_put_data@libnl_3 3.5.0-1 + nla_put_flag@Base 3.5.0-1 + nla_put_flag@libnl_3 3.5.0-1 + nla_put_msecs@Base 3.5.0-1 + nla_put_msecs@libnl_3 3.5.0-1 + nla_put_nested@Base 3.5.0-1 + nla_put_nested@libnl_3 3.5.0-1 + nla_put_s16@Base 3.5.0-1 + nla_put_s16@libnl_3_2_27 3.5.0-1 + nla_put_s32@Base 3.5.0-1 + nla_put_s32@libnl_3_2_27 3.5.0-1 + nla_put_s64@Base 3.5.0-1 + nla_put_s64@libnl_3_2_27 3.5.0-1 + nla_put_s8@Base 3.5.0-1 + nla_put_s8@libnl_3_2_27 3.5.0-1 + nla_put_string@Base 3.5.0-1 + nla_put_string@libnl_3 3.5.0-1 + nla_put_u16@Base 3.5.0-1 + nla_put_u16@libnl_3 3.5.0-1 + nla_put_u32@Base 3.5.0-1 + nla_put_u32@libnl_3 3.5.0-1 + nla_put_u64@Base 3.5.0-1 + nla_put_u64@libnl_3 3.5.0-1 + nla_put_u8@Base 3.5.0-1 + nla_put_u8@libnl_3 3.5.0-1 + nla_reserve@Base 3.5.0-1 + nla_reserve@libnl_3 3.5.0-1 + nla_strcmp@Base 3.5.0-1 + nla_strcmp@libnl_3 3.5.0-1 + nla_strdup@Base 3.5.0-1 + nla_strdup@libnl_3 3.5.0-1 + nla_strlcpy@Base 3.5.0-1 + nla_strlcpy@libnl_3 3.5.0-1 + nla_total_size@Base 3.5.0-1 + nla_total_size@libnl_3 3.5.0-1 + nla_type@Base 3.5.0-1 + nla_type@libnl_3 3.5.0-1 + nla_validate@Base 3.5.0-1 + nla_validate@libnl_3 3.5.0-1 + nlmsg_alloc@Base 3.5.0-1 + nlmsg_alloc@libnl_3 3.5.0-1 + nlmsg_alloc_simple@Base 3.5.0-1 + nlmsg_alloc_simple@libnl_3 3.5.0-1 + nlmsg_alloc_size@Base 3.5.0-1 + nlmsg_alloc_size@libnl_3 3.5.0-1 + nlmsg_append@Base 3.5.0-1 + nlmsg_append@libnl_3 3.5.0-1 + nlmsg_attrdata@Base 3.5.0-1 + nlmsg_attrdata@libnl_3 3.5.0-1 + nlmsg_attrlen@Base 3.5.0-1 + nlmsg_attrlen@libnl_3 3.5.0-1 + nlmsg_convert@Base 3.5.0-1 + nlmsg_convert@libnl_3 3.5.0-1 + nlmsg_data@Base 3.5.0-1 + nlmsg_data@libnl_3 3.5.0-1 + nlmsg_datalen@Base 3.5.0-1 + nlmsg_datalen@libnl_3 3.5.0-1 + nlmsg_expand@Base 3.5.0-1 + nlmsg_expand@libnl_3 3.5.0-1 + nlmsg_find_attr@Base 3.5.0-1 + nlmsg_find_attr@libnl_3 3.5.0-1 + nlmsg_free@Base 3.5.0-1 + nlmsg_free@libnl_3 3.5.0-1 + nlmsg_get@Base 3.5.0-1 + nlmsg_get@libnl_3 3.5.0-1 + nlmsg_get_creds@Base 3.5.0-1 + nlmsg_get_creds@libnl_3 3.5.0-1 + nlmsg_get_dst@Base 3.5.0-1 + nlmsg_get_dst@libnl_3 3.5.0-1 + nlmsg_get_max_size@Base 3.5.0-1 + nlmsg_get_max_size@libnl_3 3.5.0-1 + nlmsg_get_proto@Base 3.5.0-1 + nlmsg_get_proto@libnl_3 3.5.0-1 + nlmsg_get_src@Base 3.5.0-1 + nlmsg_get_src@libnl_3 3.5.0-1 + nlmsg_hdr@Base 3.5.0-1 + nlmsg_hdr@libnl_3 3.5.0-1 + nlmsg_inherit@Base 3.5.0-1 + nlmsg_inherit@libnl_3 3.5.0-1 + nlmsg_next@Base 3.5.0-1 + nlmsg_next@libnl_3 3.5.0-1 + nlmsg_ok@Base 3.5.0-1 + nlmsg_ok@libnl_3 3.5.0-1 + nlmsg_padlen@Base 3.5.0-1 + nlmsg_padlen@libnl_3 3.5.0-1 + nlmsg_parse@Base 3.5.0-1 + nlmsg_parse@libnl_3 3.5.0-1 + nlmsg_put@Base 3.5.0-1 + nlmsg_put@libnl_3 3.5.0-1 + nlmsg_reserve@Base 3.5.0-1 + nlmsg_reserve@libnl_3 3.5.0-1 + nlmsg_set_creds@Base 3.5.0-1 + nlmsg_set_creds@libnl_3 3.5.0-1 + nlmsg_set_default_size@Base 3.5.0-1 + nlmsg_set_default_size@libnl_3 3.5.0-1 + nlmsg_set_dst@Base 3.5.0-1 + nlmsg_set_dst@libnl_3 3.5.0-1 + nlmsg_set_proto@Base 3.5.0-1 + nlmsg_set_proto@libnl_3 3.5.0-1 + nlmsg_set_src@Base 3.5.0-1 + nlmsg_set_src@libnl_3 3.5.0-1 + nlmsg_size@Base 3.5.0-1 + nlmsg_size@libnl_3 3.5.0-1 + nlmsg_tail@Base 3.5.0-1 + nlmsg_tail@libnl_3 3.5.0-1 + nlmsg_total_size@Base 3.5.0-1 + nlmsg_total_size@libnl_3 3.5.0-1 + nlmsg_valid_hdr@Base 3.5.0-1 + nlmsg_valid_hdr@libnl_3 3.5.0-1 + nlmsg_validate@Base 3.5.0-1 + nlmsg_validate@libnl_3 3.5.0-1 diff --git a/src/libnl3/debian/libnl-3-dev.install b/src/libnl3/debian/libnl-3-dev.install new file mode 100755 index 000000000000..3715b8b22bbd --- /dev/null +++ b/src/libnl3/debian/libnl-3-dev.install @@ -0,0 +1,5 @@ +#!/usr/bin/dh-exec +debian/tmp/usr/include/* +debian/tmp/usr/lib/*/pkgconfig/libnl-3* +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-3.so lib/${DEB_HOST_MULTIARCH}/ +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-3.a lib/${DEB_HOST_MULTIARCH}/ diff --git a/src/libnl3/debian/libnl-cli-3-200.install b/src/libnl3/debian/libnl-cli-3-200.install new file mode 100755 index 000000000000..6735ec9d14b1 --- /dev/null +++ b/src/libnl3/debian/libnl-cli-3-200.install @@ -0,0 +1,4 @@ +#!/usr/bin/dh-exec +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-cli-3*.so.* +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl/cli/cls/*.so usr/lib/${DEB_HOST_MULTIARCH}/libnl-3/cli/cls +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl/cli/qdisc/*.so usr/lib/${DEB_HOST_MULTIARCH}/libnl-3/cli/qdisc diff --git a/src/libnl3/debian/libnl-cli-3-200.symbols b/src/libnl3/debian/libnl-cli-3-200.symbols new file mode 100644 index 000000000000..2d21c139623c --- /dev/null +++ b/src/libnl3/debian/libnl-cli-3-200.symbols @@ -0,0 +1,226 @@ +basic.so libnl-cli-3-200 #MINVER# +bfifo.so libnl-cli-3-200 #MINVER# +blackhole.so libnl-cli-3-200 #MINVER# +cgroup.so libnl-cli-3-200 #MINVER# +fq_codel.so libnl-cli-3-200 #MINVER# +hfsc.so libnl-cli-3-200 #MINVER# +htb.so libnl-cli-3-200 #MINVER# +ingress.so libnl-cli-3-200 #MINVER# +libnl-cli-3.so.200 libnl-cli-3-200 #MINVER# + libnl_3@libnl_3 3.5.0-1 + libnl_3_2_28@libnl_3_2_28 3.5.0-1 + nl_cli_addr_alloc@Base 3.5.0-1 + nl_cli_addr_alloc@libnl_3 3.5.0-1 + nl_cli_addr_parse@Base 3.5.0-1 + nl_cli_addr_parse@libnl_3 3.5.0-1 + nl_cli_addr_parse_broadcast@Base 3.5.0-1 + nl_cli_addr_parse_broadcast@libnl_3 3.5.0-1 + nl_cli_addr_parse_dev@Base 3.5.0-1 + nl_cli_addr_parse_dev@libnl_3 3.5.0-1 + nl_cli_addr_parse_family@Base 3.5.0-1 + nl_cli_addr_parse_family@libnl_3 3.5.0-1 + nl_cli_addr_parse_label@Base 3.5.0-1 + nl_cli_addr_parse_label@libnl_3 3.5.0-1 + nl_cli_addr_parse_local@Base 3.5.0-1 + nl_cli_addr_parse_local@libnl_3 3.5.0-1 + nl_cli_addr_parse_peer@Base 3.5.0-1 + nl_cli_addr_parse_peer@libnl_3 3.5.0-1 + nl_cli_addr_parse_preferred@Base 3.5.0-1 + nl_cli_addr_parse_preferred@libnl_3 3.5.0-1 + nl_cli_addr_parse_scope@Base 3.5.0-1 + nl_cli_addr_parse_scope@libnl_3 3.5.0-1 + nl_cli_addr_parse_valid@Base 3.5.0-1 + nl_cli_addr_parse_valid@libnl_3 3.5.0-1 + nl_cli_alloc_cache@Base 3.5.0-1 + nl_cli_alloc_cache@libnl_3 3.5.0-1 + nl_cli_alloc_cache_flags@libnl_3_2_28 3.5.0-1 + nl_cli_alloc_socket@Base 3.5.0-1 + nl_cli_alloc_socket@libnl_3 3.5.0-1 + nl_cli_class_alloc@Base 3.5.0-1 + nl_cli_class_alloc@libnl_3 3.5.0-1 + nl_cli_class_alloc_cache@Base 3.5.0-1 + nl_cli_class_alloc_cache@libnl_3 3.5.0-1 + nl_cli_cls_alloc@Base 3.5.0-1 + nl_cli_cls_alloc@libnl_3 3.5.0-1 + nl_cli_cls_alloc_cache@Base 3.5.0-1 + nl_cli_cls_alloc_cache@libnl_3 3.5.0-1 + nl_cli_cls_parse_ematch@Base 3.5.0-1 + nl_cli_cls_parse_ematch@libnl_3 3.5.0-1 + nl_cli_cls_parse_proto@Base 3.5.0-1 + nl_cli_cls_parse_proto@libnl_3 3.5.0-1 + nl_cli_confirm@Base 3.5.0-1 + nl_cli_confirm@libnl_3 3.5.0-1 + nl_cli_connect@Base 3.5.0-1 + nl_cli_connect@libnl_3 3.5.0-1 + nl_cli_ct_alloc@Base 3.5.0-1 + nl_cli_ct_alloc@libnl_3 3.5.0-1 + nl_cli_ct_alloc_cache@Base 3.5.0-1 + nl_cli_ct_alloc_cache@libnl_3 3.5.0-1 + nl_cli_ct_parse_dst@Base 3.5.0-1 + nl_cli_ct_parse_dst@libnl_3 3.5.0-1 + nl_cli_ct_parse_dst_port@Base 3.5.0-1 + nl_cli_ct_parse_dst_port@libnl_3 3.5.0-1 + nl_cli_ct_parse_family@Base 3.5.0-1 + nl_cli_ct_parse_family@libnl_3 3.5.0-1 + nl_cli_ct_parse_id@Base 3.5.0-1 + nl_cli_ct_parse_id@libnl_3 3.5.0-1 + nl_cli_ct_parse_mark@Base 3.5.0-1 + nl_cli_ct_parse_mark@libnl_3 3.5.0-1 + nl_cli_ct_parse_protocol@Base 3.5.0-1 + nl_cli_ct_parse_protocol@libnl_3 3.5.0-1 + nl_cli_ct_parse_src@Base 3.5.0-1 + nl_cli_ct_parse_src@libnl_3 3.5.0-1 + nl_cli_ct_parse_src_port@Base 3.5.0-1 + nl_cli_ct_parse_src_port@libnl_3 3.5.0-1 + nl_cli_ct_parse_status@Base 3.5.0-1 + nl_cli_ct_parse_status@libnl_3 3.5.0-1 + nl_cli_ct_parse_tcp_state@Base 3.5.0-1 + nl_cli_ct_parse_tcp_state@libnl_3 3.5.0-1 + nl_cli_ct_parse_timeout@Base 3.5.0-1 + nl_cli_ct_parse_timeout@libnl_3 3.5.0-1 + nl_cli_ct_parse_use@Base 3.5.0-1 + nl_cli_ct_parse_use@libnl_3 3.5.0-1 + nl_cli_ct_parse_zone@Base 3.5.0-1 + nl_cli_ct_parse_zone@libnl_3 3.5.0-1 + nl_cli_exp_alloc@Base 3.5.0-1 + nl_cli_exp_alloc@libnl_3 3.5.0-1 + nl_cli_exp_alloc_cache@Base 3.5.0-1 + nl_cli_exp_alloc_cache@libnl_3 3.5.0-1 + nl_cli_exp_parse_class@Base 3.5.0-1 + nl_cli_exp_parse_class@libnl_3 3.5.0-1 + nl_cli_exp_parse_dst@Base 3.5.0-1 + nl_cli_exp_parse_dst@libnl_3 3.5.0-1 + nl_cli_exp_parse_dst_port@Base 3.5.0-1 + nl_cli_exp_parse_dst_port@libnl_3 3.5.0-1 + nl_cli_exp_parse_family@Base 3.5.0-1 + nl_cli_exp_parse_family@libnl_3 3.5.0-1 + nl_cli_exp_parse_flags@Base 3.5.0-1 + nl_cli_exp_parse_flags@libnl_3 3.5.0-1 + nl_cli_exp_parse_fn@Base 3.5.0-1 + nl_cli_exp_parse_fn@libnl_3 3.5.0-1 + nl_cli_exp_parse_helper_name@Base 3.5.0-1 + nl_cli_exp_parse_helper_name@libnl_3 3.5.0-1 + nl_cli_exp_parse_icmp_code@Base 3.5.0-1 + nl_cli_exp_parse_icmp_code@libnl_3 3.5.0-1 + nl_cli_exp_parse_icmp_id@Base 3.5.0-1 + nl_cli_exp_parse_icmp_id@libnl_3 3.5.0-1 + nl_cli_exp_parse_icmp_type@Base 3.5.0-1 + nl_cli_exp_parse_icmp_type@libnl_3 3.5.0-1 + nl_cli_exp_parse_id@Base 3.5.0-1 + nl_cli_exp_parse_id@libnl_3 3.5.0-1 + nl_cli_exp_parse_l4protonum@Base 3.5.0-1 + nl_cli_exp_parse_l4protonum@libnl_3 3.5.0-1 + nl_cli_exp_parse_nat_dir@Base 3.5.0-1 + nl_cli_exp_parse_nat_dir@libnl_3 3.5.0-1 + nl_cli_exp_parse_src@Base 3.5.0-1 + nl_cli_exp_parse_src@libnl_3 3.5.0-1 + nl_cli_exp_parse_src_port@Base 3.5.0-1 + nl_cli_exp_parse_src_port@libnl_3 3.5.0-1 + nl_cli_exp_parse_timeout@Base 3.5.0-1 + nl_cli_exp_parse_timeout@libnl_3 3.5.0-1 + nl_cli_exp_parse_zone@Base 3.5.0-1 + nl_cli_exp_parse_zone@libnl_3 3.5.0-1 + nl_cli_fatal@Base 3.5.0-1 + nl_cli_fatal@libnl_3 3.5.0-1 + nl_cli_link_alloc@Base 3.5.0-1 + nl_cli_link_alloc@libnl_3 3.5.0-1 + nl_cli_link_alloc_cache@Base 3.5.0-1 + nl_cli_link_alloc_cache@libnl_3 3.5.0-1 + nl_cli_link_alloc_cache_family@Base 3.5.0-1 + nl_cli_link_alloc_cache_family@libnl_3 3.5.0-1 + nl_cli_link_alloc_cache_family_flags@libnl_3_2_28 3.5.0-1 + nl_cli_link_alloc_cache_flags@libnl_3_2_28 3.5.0-1 + nl_cli_link_parse_family@Base 3.5.0-1 + nl_cli_link_parse_family@libnl_3 3.5.0-1 + nl_cli_link_parse_ifalias@Base 3.5.0-1 + nl_cli_link_parse_ifalias@libnl_3 3.5.0-1 + nl_cli_link_parse_ifindex@Base 3.5.0-1 + nl_cli_link_parse_ifindex@libnl_3 3.5.0-1 + nl_cli_link_parse_mtu@Base 3.5.0-1 + nl_cli_link_parse_mtu@libnl_3 3.5.0-1 + nl_cli_link_parse_name@Base 3.5.0-1 + nl_cli_link_parse_name@libnl_3 3.5.0-1 + nl_cli_link_parse_txqlen@Base 3.5.0-1 + nl_cli_link_parse_txqlen@libnl_3 3.5.0-1 + nl_cli_link_parse_weight@Base 3.5.0-1 + nl_cli_link_parse_weight@libnl_3 3.5.0-1 + nl_cli_load_module@Base 3.5.0-1 + nl_cli_load_module@libnl_3 3.5.0-1 + nl_cli_neigh_alloc@Base 3.5.0-1 + nl_cli_neigh_alloc@libnl_3 3.5.0-1 + nl_cli_neigh_parse_dev@Base 3.5.0-1 + nl_cli_neigh_parse_dev@libnl_3 3.5.0-1 + nl_cli_neigh_parse_dst@Base 3.5.0-1 + nl_cli_neigh_parse_dst@libnl_3 3.5.0-1 + nl_cli_neigh_parse_family@Base 3.5.0-1 + nl_cli_neigh_parse_family@libnl_3 3.5.0-1 + nl_cli_neigh_parse_lladdr@Base 3.5.0-1 + nl_cli_neigh_parse_lladdr@libnl_3 3.5.0-1 + nl_cli_neigh_parse_state@Base 3.5.0-1 + nl_cli_neigh_parse_state@libnl_3 3.5.0-1 + nl_cli_parse_dumptype@Base 3.5.0-1 + nl_cli_parse_dumptype@libnl_3 3.5.0-1 + nl_cli_parse_u32@Base 3.5.0-1 + nl_cli_parse_u32@libnl_3 3.5.0-1 + nl_cli_print_version@Base 3.5.0-1 + nl_cli_print_version@libnl_3 3.5.0-1 + nl_cli_qdisc_alloc@Base 3.5.0-1 + nl_cli_qdisc_alloc@libnl_3 3.5.0-1 + nl_cli_route_alloc@Base 3.5.0-1 + nl_cli_route_alloc@libnl_3 3.5.0-1 + nl_cli_route_alloc_cache@Base 3.5.0-1 + nl_cli_route_alloc_cache@libnl_3 3.5.0-1 + nl_cli_route_parse_dst@Base 3.5.0-1 + nl_cli_route_parse_dst@libnl_3 3.5.0-1 + nl_cli_route_parse_family@Base 3.5.0-1 + nl_cli_route_parse_family@libnl_3 3.5.0-1 + nl_cli_route_parse_iif@Base 3.5.0-1 + nl_cli_route_parse_iif@libnl_3 3.5.0-1 + nl_cli_route_parse_metric@Base 3.5.0-1 + nl_cli_route_parse_metric@libnl_3 3.5.0-1 + nl_cli_route_parse_nexthop@Base 3.5.0-1 + nl_cli_route_parse_nexthop@libnl_3 3.5.0-1 + nl_cli_route_parse_pref_src@Base 3.5.0-1 + nl_cli_route_parse_pref_src@libnl_3 3.5.0-1 + nl_cli_route_parse_prio@Base 3.5.0-1 + nl_cli_route_parse_prio@libnl_3 3.5.0-1 + nl_cli_route_parse_protocol@Base 3.5.0-1 + nl_cli_route_parse_protocol@libnl_3 3.5.0-1 + nl_cli_route_parse_scope@Base 3.5.0-1 + nl_cli_route_parse_scope@libnl_3 3.5.0-1 + nl_cli_route_parse_src@Base 3.5.0-1 + nl_cli_route_parse_src@libnl_3 3.5.0-1 + nl_cli_route_parse_table@Base 3.5.0-1 + nl_cli_route_parse_table@libnl_3 3.5.0-1 + nl_cli_route_parse_type@Base 3.5.0-1 + nl_cli_route_parse_type@libnl_3 3.5.0-1 + nl_cli_rule_alloc@Base 3.5.0-1 + nl_cli_rule_alloc@libnl_3 3.5.0-1 + nl_cli_rule_alloc_cache@Base 3.5.0-1 + nl_cli_rule_alloc_cache@libnl_3 3.5.0-1 + nl_cli_rule_parse_family@Base 3.5.0-1 + nl_cli_rule_parse_family@libnl_3 3.5.0-1 + nl_cli_tc_lookup@Base 3.5.0-1 + nl_cli_tc_lookup@libnl_3 3.5.0-1 + nl_cli_tc_parse_dev@Base 3.5.0-1 + nl_cli_tc_parse_dev@libnl_3 3.5.0-1 + nl_cli_tc_parse_handle@Base 3.5.0-1 + nl_cli_tc_parse_handle@libnl_3 3.5.0-1 + nl_cli_tc_parse_kind@Base 3.5.0-1 + nl_cli_tc_parse_kind@libnl_3 3.5.0-1 + nl_cli_tc_parse_linktype@Base 3.5.0-1 + nl_cli_tc_parse_linktype@libnl_3 3.5.0-1 + nl_cli_tc_parse_mpu@Base 3.5.0-1 + nl_cli_tc_parse_mpu@libnl_3 3.5.0-1 + nl_cli_tc_parse_mtu@Base 3.5.0-1 + nl_cli_tc_parse_mtu@libnl_3 3.5.0-1 + nl_cli_tc_parse_overhead@Base 3.5.0-1 + nl_cli_tc_parse_overhead@libnl_3 3.5.0-1 + nl_cli_tc_parse_parent@Base 3.5.0-1 + nl_cli_tc_parse_parent@libnl_3 3.5.0-1 + nl_cli_tc_register@Base 3.5.0-1 + nl_cli_tc_register@libnl_3 3.5.0-1 + nl_cli_tc_unregister@Base 3.5.0-1 + nl_cli_tc_unregister@libnl_3 3.5.0-1 +pfifo.so libnl-cli-3-200 #MINVER# +plug.so libnl-cli-3-200 #MINVER# diff --git a/src/libnl3/debian/libnl-cli-3-dev.install b/src/libnl3/debian/libnl-cli-3-dev.install new file mode 100644 index 000000000000..66aa3b3d9457 --- /dev/null +++ b/src/libnl3/debian/libnl-cli-3-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/*/pkgconfig/libnl-cli-3* +debian/tmp/usr/lib/*/libnl-cli-3*.so +debian/tmp/usr/lib/*/libnl-cli-3*.a diff --git a/src/libnl3/debian/libnl-genl-3-200-udeb.install b/src/libnl3/debian/libnl-genl-3-200-udeb.install new file mode 100755 index 000000000000..cb5597bf74da --- /dev/null +++ b/src/libnl3/debian/libnl-genl-3-200-udeb.install @@ -0,0 +1,2 @@ +#!/usr/bin/dh-exec +usr/lib/${DEB_HOST_MULTIARCH}/libnl-genl-3.so.* lib/${DEB_HOST_MULTIARCH}/ diff --git a/src/libnl3/debian/libnl-genl-3-200.install b/src/libnl3/debian/libnl-genl-3-200.install new file mode 100755 index 000000000000..d9d6fae40b21 --- /dev/null +++ b/src/libnl3/debian/libnl-genl-3-200.install @@ -0,0 +1,2 @@ +#!/usr/bin/dh-exec +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-genl-3*.so.* lib/${DEB_HOST_MULTIARCH}/ diff --git a/src/libnl3/debian/libnl-genl-3-200.symbols b/src/libnl3/debian/libnl-genl-3-200.symbols new file mode 100644 index 000000000000..0eb2e3be4460 --- /dev/null +++ b/src/libnl3/debian/libnl-genl-3-200.symbols @@ -0,0 +1,88 @@ +libnl-genl-3.so.200 libnl-genl-3-200 #MINVER# + genl_connect@Base 3.5.0-1 + genl_connect@libnl_3 3.5.0-1 + genl_ctrl_alloc_cache@Base 3.5.0-1 + genl_ctrl_alloc_cache@libnl_3 3.5.0-1 + genl_ctrl_resolve@Base 3.5.0-1 + genl_ctrl_resolve@libnl_3 3.5.0-1 + genl_ctrl_resolve_grp@Base 3.5.0-1 + genl_ctrl_resolve_grp@libnl_3 3.5.0-1 + genl_ctrl_search@Base 3.5.0-1 + genl_ctrl_search@libnl_3 3.5.0-1 + genl_ctrl_search_by_name@Base 3.5.0-1 + genl_ctrl_search_by_name@libnl_3 3.5.0-1 + genl_family_add_grp@Base 3.5.0-1 + genl_family_add_grp@libnl_3 3.5.0-1 + genl_family_add_op@Base 3.5.0-1 + genl_family_add_op@libnl_3 3.5.0-1 + genl_family_alloc@Base 3.5.0-1 + genl_family_alloc@libnl_3 3.5.0-1 + genl_family_get_hdrsize@Base 3.5.0-1 + genl_family_get_hdrsize@libnl_3 3.5.0-1 + genl_family_get_id@Base 3.5.0-1 + genl_family_get_id@libnl_3 3.5.0-1 + genl_family_get_maxattr@Base 3.5.0-1 + genl_family_get_maxattr@libnl_3 3.5.0-1 + genl_family_get_name@Base 3.5.0-1 + genl_family_get_name@libnl_3 3.5.0-1 + genl_family_get_version@Base 3.5.0-1 + genl_family_get_version@libnl_3 3.5.0-1 + genl_family_ops@Base 3.5.0-1 + genl_family_ops@libnl_3 3.5.0-1 + genl_family_put@Base 3.5.0-1 + genl_family_put@libnl_3 3.5.0-1 + genl_family_set_hdrsize@Base 3.5.0-1 + genl_family_set_hdrsize@libnl_3 3.5.0-1 + genl_family_set_id@Base 3.5.0-1 + genl_family_set_id@libnl_3 3.5.0-1 + genl_family_set_maxattr@Base 3.5.0-1 + genl_family_set_maxattr@libnl_3 3.5.0-1 + genl_family_set_name@Base 3.5.0-1 + genl_family_set_name@libnl_3 3.5.0-1 + genl_family_set_version@Base 3.5.0-1 + genl_family_set_version@libnl_3 3.5.0-1 + genl_handle_msg@Base 3.5.0-1 + genl_handle_msg@libnl_3 3.5.0-1 + genl_mngt_resolve@Base 3.5.0-1 + genl_mngt_resolve@libnl_3 3.5.0-1 + genl_op2name@Base 3.5.0-1 + genl_op2name@libnl_3 3.5.0-1 + genl_ops_resolve@Base 3.5.0-1 + genl_ops_resolve@libnl_3 3.5.0-1 + genl_register@Base 3.5.0-1 + genl_register@libnl_3 3.5.0-1 + genl_register_family@Base 3.5.0-1 + genl_register_family@libnl_3 3.5.0-1 + genl_resolve_id@Base 3.5.0-1 + genl_resolve_id@libnl_3 3.5.0-1 + genl_send_simple@Base 3.5.0-1 + genl_send_simple@libnl_3 3.5.0-1 + genl_unregister@Base 3.5.0-1 + genl_unregister@libnl_3 3.5.0-1 + genl_unregister_family@Base 3.5.0-1 + genl_unregister_family@libnl_3 3.5.0-1 + genlmsg_attrdata@Base 3.5.0-1 + genlmsg_attrdata@libnl_3 3.5.0-1 + genlmsg_attrlen@Base 3.5.0-1 + genlmsg_attrlen@libnl_3 3.5.0-1 + genlmsg_data@Base 3.5.0-1 + genlmsg_data@libnl_3 3.5.0-1 + genlmsg_hdr@Base 3.5.0-1 + genlmsg_hdr@libnl_3 3.5.0-1 + genlmsg_len@Base 3.5.0-1 + genlmsg_len@libnl_3 3.5.0-1 + genlmsg_parse@Base 3.5.0-1 + genlmsg_parse@libnl_3 3.5.0-1 + genlmsg_put@Base 3.5.0-1 + genlmsg_put@libnl_3 3.5.0-1 + genlmsg_user_data@Base 3.5.0-1 + genlmsg_user_data@libnl_3 3.5.0-1 + genlmsg_user_datalen@Base 3.5.0-1 + genlmsg_user_datalen@libnl_3 3.5.0-1 + genlmsg_user_hdr@Base 3.5.0-1 + genlmsg_user_hdr@libnl_3 3.5.0-1 + genlmsg_valid_hdr@Base 3.5.0-1 + genlmsg_valid_hdr@libnl_3 3.5.0-1 + genlmsg_validate@Base 3.5.0-1 + genlmsg_validate@libnl_3 3.5.0-1 + libnl_3@libnl_3 3.5.0-1 diff --git a/src/libnl3/debian/libnl-genl-3-dev.install b/src/libnl3/debian/libnl-genl-3-dev.install new file mode 100755 index 000000000000..cbc6b51ef474 --- /dev/null +++ b/src/libnl3/debian/libnl-genl-3-dev.install @@ -0,0 +1,4 @@ +#!/usr/bin/dh-exec +debian/tmp/usr/lib/*/pkgconfig/libnl-genl-3* +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-genl-3*.so lib/${DEB_HOST_MULTIARCH}/ +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-genl-3*.a lib/${DEB_HOST_MULTIARCH}/ diff --git a/src/libnl3/debian/libnl-idiag-3-200.install b/src/libnl3/debian/libnl-idiag-3-200.install new file mode 100644 index 000000000000..f6d6b8064e5f --- /dev/null +++ b/src/libnl3/debian/libnl-idiag-3-200.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/*/libnl-idiag-3*.so.* diff --git a/src/libnl3/debian/libnl-idiag-3-200.symbols b/src/libnl3/debian/libnl-idiag-3-200.symbols new file mode 100644 index 000000000000..13cf27c7c8ac --- /dev/null +++ b/src/libnl3/debian/libnl-idiag-3-200.symbols @@ -0,0 +1,206 @@ +libnl-idiag-3.so.200 libnl-idiag-3-200 #MINVER# + idiagnl_attrs2str@Base 3.5.0-1 + idiagnl_attrs2str@libnl_3 3.5.0-1 + idiagnl_connect@Base 3.5.0-1 + idiagnl_connect@libnl_3 3.5.0-1 + idiagnl_exts2str@Base 3.5.0-1 + idiagnl_exts2str@libnl_3 3.5.0-1 + idiagnl_meminfo_alloc@Base 3.5.0-1 + idiagnl_meminfo_alloc@libnl_3 3.5.0-1 + idiagnl_meminfo_get@Base 3.5.0-1 + idiagnl_meminfo_get@libnl_3 3.5.0-1 + idiagnl_meminfo_get_fmem@Base 3.5.0-1 + idiagnl_meminfo_get_fmem@libnl_3 3.5.0-1 + idiagnl_meminfo_get_rmem@Base 3.5.0-1 + idiagnl_meminfo_get_rmem@libnl_3 3.5.0-1 + idiagnl_meminfo_get_tmem@Base 3.5.0-1 + idiagnl_meminfo_get_tmem@libnl_3 3.5.0-1 + idiagnl_meminfo_get_wmem@Base 3.5.0-1 + idiagnl_meminfo_get_wmem@libnl_3 3.5.0-1 + idiagnl_meminfo_obj_ops@Base 3.5.0-1 + idiagnl_meminfo_obj_ops@libnl_3 3.5.0-1 + idiagnl_meminfo_put@Base 3.5.0-1 + idiagnl_meminfo_put@libnl_3 3.5.0-1 + idiagnl_meminfo_set_fmem@Base 3.5.0-1 + idiagnl_meminfo_set_fmem@libnl_3 3.5.0-1 + idiagnl_meminfo_set_rmem@Base 3.5.0-1 + idiagnl_meminfo_set_rmem@libnl_3 3.5.0-1 + idiagnl_meminfo_set_tmem@Base 3.5.0-1 + idiagnl_meminfo_set_tmem@libnl_3 3.5.0-1 + idiagnl_meminfo_set_wmem@Base 3.5.0-1 + idiagnl_meminfo_set_wmem@libnl_3 3.5.0-1 + idiagnl_msg_alloc@Base 3.5.0-1 + idiagnl_msg_alloc@libnl_3 3.5.0-1 + idiagnl_msg_alloc_cache@Base 3.5.0-1 + idiagnl_msg_alloc_cache@libnl_3 3.5.0-1 + idiagnl_msg_get@Base 3.5.0-1 + idiagnl_msg_get@libnl_3 3.5.0-1 + idiagnl_msg_get_cong@Base 3.5.0-1 + idiagnl_msg_get_cong@libnl_3 3.5.0-1 + idiagnl_msg_get_dport@Base 3.5.0-1 + idiagnl_msg_get_dport@libnl_3 3.5.0-1 + idiagnl_msg_get_dst@Base 3.5.0-1 + idiagnl_msg_get_dst@libnl_3 3.5.0-1 + idiagnl_msg_get_expires@Base 3.5.0-1 + idiagnl_msg_get_expires@libnl_3 3.5.0-1 + idiagnl_msg_get_family@Base 3.5.0-1 + idiagnl_msg_get_family@libnl_3 3.5.0-1 + idiagnl_msg_get_ifindex@Base 3.5.0-1 + idiagnl_msg_get_ifindex@libnl_3 3.5.0-1 + idiagnl_msg_get_inode@Base 3.5.0-1 + idiagnl_msg_get_inode@libnl_3 3.5.0-1 + idiagnl_msg_get_meminfo@Base 3.5.0-1 + idiagnl_msg_get_meminfo@libnl_3 3.5.0-1 + idiagnl_msg_get_retrans@Base 3.5.0-1 + idiagnl_msg_get_retrans@libnl_3 3.5.0-1 + idiagnl_msg_get_rqueue@Base 3.5.0-1 + idiagnl_msg_get_rqueue@libnl_3 3.5.0-1 + idiagnl_msg_get_shutdown@Base 3.5.0-1 + idiagnl_msg_get_shutdown@libnl_3 3.5.0-1 + idiagnl_msg_get_sport@Base 3.5.0-1 + idiagnl_msg_get_sport@libnl_3 3.5.0-1 + idiagnl_msg_get_src@Base 3.5.0-1 + idiagnl_msg_get_src@libnl_3 3.5.0-1 + idiagnl_msg_get_state@Base 3.5.0-1 + idiagnl_msg_get_state@libnl_3 3.5.0-1 + idiagnl_msg_get_tclass@Base 3.5.0-1 + idiagnl_msg_get_tclass@libnl_3 3.5.0-1 + idiagnl_msg_get_tcpinfo@Base 3.5.0-1 + idiagnl_msg_get_tcpinfo@libnl_3 3.5.0-1 + idiagnl_msg_get_timer@Base 3.5.0-1 + idiagnl_msg_get_timer@libnl_3 3.5.0-1 + idiagnl_msg_get_tos@Base 3.5.0-1 + idiagnl_msg_get_tos@libnl_3 3.5.0-1 + idiagnl_msg_get_uid@Base 3.5.0-1 + idiagnl_msg_get_uid@libnl_3 3.5.0-1 + idiagnl_msg_get_vegasinfo@Base 3.5.0-1 + idiagnl_msg_get_vegasinfo@libnl_3 3.5.0-1 + idiagnl_msg_get_wqueue@Base 3.5.0-1 + idiagnl_msg_get_wqueue@libnl_3 3.5.0-1 + idiagnl_msg_obj_ops@Base 3.5.0-1 + idiagnl_msg_obj_ops@libnl_3 3.5.0-1 + idiagnl_msg_parse@Base 3.5.0-1 + idiagnl_msg_parse@libnl_3 3.5.0-1 + idiagnl_msg_put@Base 3.5.0-1 + idiagnl_msg_put@libnl_3 3.5.0-1 + idiagnl_msg_set_cong@Base 3.5.0-1 + idiagnl_msg_set_cong@libnl_3 3.5.0-1 + idiagnl_msg_set_dport@Base 3.5.0-1 + idiagnl_msg_set_dport@libnl_3 3.5.0-1 + idiagnl_msg_set_dst@Base 3.5.0-1 + idiagnl_msg_set_dst@libnl_3 3.5.0-1 + idiagnl_msg_set_expires@Base 3.5.0-1 + idiagnl_msg_set_expires@libnl_3 3.5.0-1 + idiagnl_msg_set_family@Base 3.5.0-1 + idiagnl_msg_set_family@libnl_3 3.5.0-1 + idiagnl_msg_set_ifindex@Base 3.5.0-1 + idiagnl_msg_set_ifindex@libnl_3 3.5.0-1 + idiagnl_msg_set_inode@Base 3.5.0-1 + idiagnl_msg_set_inode@libnl_3 3.5.0-1 + idiagnl_msg_set_meminfo@Base 3.5.0-1 + idiagnl_msg_set_meminfo@libnl_3 3.5.0-1 + idiagnl_msg_set_retrans@Base 3.5.0-1 + idiagnl_msg_set_retrans@libnl_3 3.5.0-1 + idiagnl_msg_set_rqueue@Base 3.5.0-1 + idiagnl_msg_set_rqueue@libnl_3 3.5.0-1 + idiagnl_msg_set_shutdown@Base 3.5.0-1 + idiagnl_msg_set_shutdown@libnl_3 3.5.0-1 + idiagnl_msg_set_sport@Base 3.5.0-1 + idiagnl_msg_set_sport@libnl_3 3.5.0-1 + idiagnl_msg_set_src@Base 3.5.0-1 + idiagnl_msg_set_src@libnl_3 3.5.0-1 + idiagnl_msg_set_state@Base 3.5.0-1 + idiagnl_msg_set_state@libnl_3 3.5.0-1 + idiagnl_msg_set_tclass@Base 3.5.0-1 + idiagnl_msg_set_tclass@libnl_3 3.5.0-1 + idiagnl_msg_set_tcpinfo@Base 3.5.0-1 + idiagnl_msg_set_tcpinfo@libnl_3 3.5.0-1 + idiagnl_msg_set_timer@Base 3.5.0-1 + idiagnl_msg_set_timer@libnl_3 3.5.0-1 + idiagnl_msg_set_tos@Base 3.5.0-1 + idiagnl_msg_set_tos@libnl_3 3.5.0-1 + idiagnl_msg_set_uid@Base 3.5.0-1 + idiagnl_msg_set_uid@libnl_3 3.5.0-1 + idiagnl_msg_set_vegasinfo@Base 3.5.0-1 + idiagnl_msg_set_vegasinfo@libnl_3 3.5.0-1 + idiagnl_msg_set_wqueue@Base 3.5.0-1 + idiagnl_msg_set_wqueue@libnl_3 3.5.0-1 + idiagnl_req_alloc@Base 3.5.0-1 + idiagnl_req_alloc@libnl_3 3.5.0-1 + idiagnl_req_get@Base 3.5.0-1 + idiagnl_req_get@libnl_3 3.5.0-1 + idiagnl_req_get_dbs@Base 3.5.0-1 + idiagnl_req_get_dbs@libnl_3 3.5.0-1 + idiagnl_req_get_dst@Base 3.5.0-1 + idiagnl_req_get_dst@libnl_3 3.5.0-1 + idiagnl_req_get_ext@Base 3.5.0-1 + idiagnl_req_get_ext@libnl_3 3.5.0-1 + idiagnl_req_get_family@Base 3.5.0-1 + idiagnl_req_get_family@libnl_3 3.5.0-1 + idiagnl_req_get_ifindex@Base 3.5.0-1 + idiagnl_req_get_ifindex@libnl_3 3.5.0-1 + idiagnl_req_get_src@Base 3.5.0-1 + idiagnl_req_get_src@libnl_3 3.5.0-1 + idiagnl_req_get_states@Base 3.5.0-1 + idiagnl_req_get_states@libnl_3 3.5.0-1 + idiagnl_req_obj_ops@Base 3.5.0-1 + idiagnl_req_obj_ops@libnl_3 3.5.0-1 + idiagnl_req_parse@Base 3.5.0-1 + idiagnl_req_parse@libnl_3 3.5.0-1 + idiagnl_req_put@Base 3.5.0-1 + idiagnl_req_put@libnl_3 3.5.0-1 + idiagnl_req_set_dbs@Base 3.5.0-1 + idiagnl_req_set_dbs@libnl_3 3.5.0-1 + idiagnl_req_set_dst@Base 3.5.0-1 + idiagnl_req_set_dst@libnl_3 3.5.0-1 + idiagnl_req_set_ext@Base 3.5.0-1 + idiagnl_req_set_ext@libnl_3 3.5.0-1 + idiagnl_req_set_family@Base 3.5.0-1 + idiagnl_req_set_family@libnl_3 3.5.0-1 + idiagnl_req_set_ifindex@Base 3.5.0-1 + idiagnl_req_set_ifindex@libnl_3 3.5.0-1 + idiagnl_req_set_src@Base 3.5.0-1 + idiagnl_req_set_src@libnl_3 3.5.0-1 + idiagnl_req_set_states@Base 3.5.0-1 + idiagnl_req_set_states@libnl_3 3.5.0-1 + idiagnl_send_simple@Base 3.5.0-1 + idiagnl_send_simple@libnl_3 3.5.0-1 + idiagnl_shutdown2str@Base 3.5.0-1 + idiagnl_shutdown2str@libnl_3 3.5.0-1 + idiagnl_state2str@Base 3.5.0-1 + idiagnl_state2str@libnl_3 3.5.0-1 + idiagnl_str2state@Base 3.5.0-1 + idiagnl_str2state@libnl_3 3.5.0-1 + idiagnl_str2timer@Base 3.5.0-1 + idiagnl_str2timer@libnl_3 3.5.0-1 + idiagnl_tcpopts2str@Base 3.5.0-1 + idiagnl_tcpopts2str@libnl_3 3.5.0-1 + idiagnl_tcpstate2str@Base 3.5.0-1 + idiagnl_tcpstate2str@libnl_3 3.5.0-1 + idiagnl_timer2str@Base 3.5.0-1 + idiagnl_timer2str@libnl_3 3.5.0-1 + idiagnl_vegasinfo_alloc@Base 3.5.0-1 + idiagnl_vegasinfo_alloc@libnl_3 3.5.0-1 + idiagnl_vegasinfo_get@Base 3.5.0-1 + idiagnl_vegasinfo_get@libnl_3 3.5.0-1 + idiagnl_vegasinfo_get_enabled@Base 3.5.0-1 + idiagnl_vegasinfo_get_enabled@libnl_3 3.5.0-1 + idiagnl_vegasinfo_get_minrtt@Base 3.5.0-1 + idiagnl_vegasinfo_get_minrtt@libnl_3 3.5.0-1 + idiagnl_vegasinfo_get_rtt@Base 3.5.0-1 + idiagnl_vegasinfo_get_rtt@libnl_3 3.5.0-1 + idiagnl_vegasinfo_get_rttcnt@Base 3.5.0-1 + idiagnl_vegasinfo_get_rttcnt@libnl_3 3.5.0-1 + idiagnl_vegasinfo_obj_ops@Base 3.5.0-1 + idiagnl_vegasinfo_obj_ops@libnl_3 3.5.0-1 + idiagnl_vegasinfo_put@Base 3.5.0-1 + idiagnl_vegasinfo_put@libnl_3 3.5.0-1 + idiagnl_vegasinfo_set_enabled@Base 3.5.0-1 + idiagnl_vegasinfo_set_enabled@libnl_3 3.5.0-1 + idiagnl_vegasinfo_set_minrtt@Base 3.5.0-1 + idiagnl_vegasinfo_set_minrtt@libnl_3 3.5.0-1 + idiagnl_vegasinfo_set_rtt@Base 3.5.0-1 + idiagnl_vegasinfo_set_rtt@libnl_3 3.5.0-1 + idiagnl_vegasinfo_set_rttcnt@Base 3.5.0-1 + idiagnl_vegasinfo_set_rttcnt@libnl_3 3.5.0-1 + libnl_3@libnl_3 3.5.0-1 diff --git a/src/libnl3/debian/libnl-idiag-3-dev.install b/src/libnl3/debian/libnl-idiag-3-dev.install new file mode 100644 index 000000000000..6f19a6e83d61 --- /dev/null +++ b/src/libnl3/debian/libnl-idiag-3-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/*/pkgconfig/libnl-idiag-3* +debian/tmp/usr/lib/*/libnl-idiag-3*.so +debian/tmp/usr/lib/*/libnl-idiag-3*.a diff --git a/src/libnl3/debian/libnl-nf-3-200.install b/src/libnl3/debian/libnl-nf-3-200.install new file mode 100644 index 000000000000..6d65611ed34e --- /dev/null +++ b/src/libnl3/debian/libnl-nf-3-200.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/*/libnl-nf-3*.so.* diff --git a/src/libnl3/debian/libnl-nf-3-200.symbols b/src/libnl3/debian/libnl-nf-3-200.symbols new file mode 100644 index 000000000000..2ce4d2ad0ffc --- /dev/null +++ b/src/libnl3/debian/libnl-nf-3-200.symbols @@ -0,0 +1,620 @@ +libnl-nf-3.so.200 libnl-nf-3-200 #MINVER# + ct_obj_ops@Base 3.5.0-1 + ct_obj_ops@libnl_3 3.5.0-1 + exp_obj_ops@Base 3.5.0-1 + exp_obj_ops@libnl_3 3.5.0-1 + libnl_3@libnl_3 3.5.0-1 + log_msg_obj_ops@Base 3.5.0-1 + log_msg_obj_ops@libnl_3 3.5.0-1 + log_obj_ops@Base 3.5.0-1 + log_obj_ops@libnl_3 3.5.0-1 + nfnl_connect@Base 3.5.0-1 + nfnl_connect@libnl_3 3.5.0-1 + nfnl_ct_add@Base 3.5.0-1 + nfnl_ct_add@libnl_3 3.5.0-1 + nfnl_ct_alloc@Base 3.5.0-1 + nfnl_ct_alloc@libnl_3 3.5.0-1 + nfnl_ct_alloc_cache@Base 3.5.0-1 + nfnl_ct_alloc_cache@libnl_3 3.5.0-1 + nfnl_ct_build_add_request@Base 3.5.0-1 + nfnl_ct_build_add_request@libnl_3 3.5.0-1 + nfnl_ct_build_delete_request@Base 3.5.0-1 + nfnl_ct_build_delete_request@libnl_3 3.5.0-1 + nfnl_ct_build_query_request@Base 3.5.0-1 + nfnl_ct_build_query_request@libnl_3 3.5.0-1 + nfnl_ct_del@Base 3.5.0-1 + nfnl_ct_del@libnl_3 3.5.0-1 + nfnl_ct_dump_request@Base 3.5.0-1 + nfnl_ct_dump_request@libnl_3 3.5.0-1 + nfnl_ct_get@Base 3.5.0-1 + nfnl_ct_get@libnl_3 3.5.0-1 + nfnl_ct_get_bytes@Base 3.5.0-1 + nfnl_ct_get_bytes@libnl_3 3.5.0-1 + nfnl_ct_get_dst@Base 3.5.0-1 + nfnl_ct_get_dst@libnl_3 3.5.0-1 + nfnl_ct_get_dst_port@Base 3.5.0-1 + nfnl_ct_get_dst_port@libnl_3 3.5.0-1 + nfnl_ct_get_family@Base 3.5.0-1 + nfnl_ct_get_family@libnl_3 3.5.0-1 + nfnl_ct_get_icmp_code@Base 3.5.0-1 + nfnl_ct_get_icmp_code@libnl_3 3.5.0-1 + nfnl_ct_get_icmp_id@Base 3.5.0-1 + nfnl_ct_get_icmp_id@libnl_3 3.5.0-1 + nfnl_ct_get_icmp_type@Base 3.5.0-1 + nfnl_ct_get_icmp_type@libnl_3 3.5.0-1 + nfnl_ct_get_id@Base 3.5.0-1 + nfnl_ct_get_id@libnl_3 3.5.0-1 + nfnl_ct_get_mark@Base 3.5.0-1 + nfnl_ct_get_mark@libnl_3 3.5.0-1 + nfnl_ct_get_packets@Base 3.5.0-1 + nfnl_ct_get_packets@libnl_3 3.5.0-1 + nfnl_ct_get_proto@Base 3.5.0-1 + nfnl_ct_get_proto@libnl_3 3.5.0-1 + nfnl_ct_get_src@Base 3.5.0-1 + nfnl_ct_get_src@libnl_3 3.5.0-1 + nfnl_ct_get_src_port@Base 3.5.0-1 + nfnl_ct_get_src_port@libnl_3 3.5.0-1 + nfnl_ct_get_status@Base 3.5.0-1 + nfnl_ct_get_status@libnl_3 3.5.0-1 + nfnl_ct_get_tcp_state@Base 3.5.0-1 + nfnl_ct_get_tcp_state@libnl_3 3.5.0-1 + nfnl_ct_get_timeout@Base 3.5.0-1 + nfnl_ct_get_timeout@libnl_3 3.5.0-1 + nfnl_ct_get_timestamp@Base 3.5.0-1 + nfnl_ct_get_timestamp@libnl_3 3.5.0-1 + nfnl_ct_get_use@Base 3.5.0-1 + nfnl_ct_get_use@libnl_3 3.5.0-1 + nfnl_ct_get_zone@Base 3.5.0-1 + nfnl_ct_get_zone@libnl_3 3.5.0-1 + nfnl_ct_put@Base 3.5.0-1 + nfnl_ct_put@libnl_3 3.5.0-1 + nfnl_ct_query@Base 3.5.0-1 + nfnl_ct_query@libnl_3 3.5.0-1 + nfnl_ct_set_bytes@Base 3.5.0-1 + nfnl_ct_set_bytes@libnl_3 3.5.0-1 + nfnl_ct_set_dst@Base 3.5.0-1 + nfnl_ct_set_dst@libnl_3 3.5.0-1 + nfnl_ct_set_dst_port@Base 3.5.0-1 + nfnl_ct_set_dst_port@libnl_3 3.5.0-1 + nfnl_ct_set_family@Base 3.5.0-1 + nfnl_ct_set_family@libnl_3 3.5.0-1 + nfnl_ct_set_icmp_code@Base 3.5.0-1 + nfnl_ct_set_icmp_code@libnl_3 3.5.0-1 + nfnl_ct_set_icmp_id@Base 3.5.0-1 + nfnl_ct_set_icmp_id@libnl_3 3.5.0-1 + nfnl_ct_set_icmp_type@Base 3.5.0-1 + nfnl_ct_set_icmp_type@libnl_3 3.5.0-1 + nfnl_ct_set_id@Base 3.5.0-1 + nfnl_ct_set_id@libnl_3 3.5.0-1 + nfnl_ct_set_mark@Base 3.5.0-1 + nfnl_ct_set_mark@libnl_3 3.5.0-1 + nfnl_ct_set_packets@Base 3.5.0-1 + nfnl_ct_set_packets@libnl_3 3.5.0-1 + nfnl_ct_set_proto@Base 3.5.0-1 + nfnl_ct_set_proto@libnl_3 3.5.0-1 + nfnl_ct_set_src@Base 3.5.0-1 + nfnl_ct_set_src@libnl_3 3.5.0-1 + nfnl_ct_set_src_port@Base 3.5.0-1 + nfnl_ct_set_src_port@libnl_3 3.5.0-1 + nfnl_ct_set_status@Base 3.5.0-1 + nfnl_ct_set_status@libnl_3 3.5.0-1 + nfnl_ct_set_tcp_state@Base 3.5.0-1 + nfnl_ct_set_tcp_state@libnl_3 3.5.0-1 + nfnl_ct_set_timeout@Base 3.5.0-1 + nfnl_ct_set_timeout@libnl_3 3.5.0-1 + nfnl_ct_set_timestamp@Base 3.5.0-1 + nfnl_ct_set_timestamp@libnl_3 3.5.0-1 + nfnl_ct_set_use@Base 3.5.0-1 + nfnl_ct_set_use@libnl_3 3.5.0-1 + nfnl_ct_set_zone@Base 3.5.0-1 + nfnl_ct_set_zone@libnl_3 3.5.0-1 + nfnl_ct_status2str@Base 3.5.0-1 + nfnl_ct_status2str@libnl_3 3.5.0-1 + nfnl_ct_str2status@Base 3.5.0-1 + nfnl_ct_str2status@libnl_3 3.5.0-1 + nfnl_ct_str2tcp_state@Base 3.5.0-1 + nfnl_ct_str2tcp_state@libnl_3 3.5.0-1 + nfnl_ct_tcp_state2str@Base 3.5.0-1 + nfnl_ct_tcp_state2str@libnl_3 3.5.0-1 + nfnl_ct_test_bytes@Base 3.5.0-1 + nfnl_ct_test_bytes@libnl_3 3.5.0-1 + nfnl_ct_test_dst_port@Base 3.5.0-1 + nfnl_ct_test_dst_port@libnl_3 3.5.0-1 + nfnl_ct_test_icmp_code@Base 3.5.0-1 + nfnl_ct_test_icmp_code@libnl_3 3.5.0-1 + nfnl_ct_test_icmp_id@Base 3.5.0-1 + nfnl_ct_test_icmp_id@libnl_3 3.5.0-1 + nfnl_ct_test_icmp_type@Base 3.5.0-1 + nfnl_ct_test_icmp_type@libnl_3 3.5.0-1 + nfnl_ct_test_id@Base 3.5.0-1 + nfnl_ct_test_id@libnl_3 3.5.0-1 + nfnl_ct_test_mark@Base 3.5.0-1 + nfnl_ct_test_mark@libnl_3 3.5.0-1 + nfnl_ct_test_packets@Base 3.5.0-1 + nfnl_ct_test_packets@libnl_3 3.5.0-1 + nfnl_ct_test_proto@Base 3.5.0-1 + nfnl_ct_test_proto@libnl_3 3.5.0-1 + nfnl_ct_test_src_port@Base 3.5.0-1 + nfnl_ct_test_src_port@libnl_3 3.5.0-1 + nfnl_ct_test_status@Base 3.5.0-1 + nfnl_ct_test_status@libnl_3 3.5.0-1 + nfnl_ct_test_tcp_state@Base 3.5.0-1 + nfnl_ct_test_tcp_state@libnl_3 3.5.0-1 + nfnl_ct_test_timeout@Base 3.5.0-1 + nfnl_ct_test_timeout@libnl_3 3.5.0-1 + nfnl_ct_test_timestamp@Base 3.5.0-1 + nfnl_ct_test_timestamp@libnl_3 3.5.0-1 + nfnl_ct_test_use@Base 3.5.0-1 + nfnl_ct_test_use@libnl_3 3.5.0-1 + nfnl_ct_test_zone@Base 3.5.0-1 + nfnl_ct_test_zone@libnl_3 3.5.0-1 + nfnl_ct_unset_status@Base 3.5.0-1 + nfnl_ct_unset_status@libnl_3 3.5.0-1 + nfnl_exp_add@Base 3.5.0-1 + nfnl_exp_add@libnl_3 3.5.0-1 + nfnl_exp_alloc@Base 3.5.0-1 + nfnl_exp_alloc@libnl_3 3.5.0-1 + nfnl_exp_alloc_cache@Base 3.5.0-1 + nfnl_exp_alloc_cache@libnl_3 3.5.0-1 + nfnl_exp_build_add_request@Base 3.5.0-1 + nfnl_exp_build_add_request@libnl_3 3.5.0-1 + nfnl_exp_build_delete_request@Base 3.5.0-1 + nfnl_exp_build_delete_request@libnl_3 3.5.0-1 + nfnl_exp_build_query_request@Base 3.5.0-1 + nfnl_exp_build_query_request@libnl_3 3.5.0-1 + nfnl_exp_del@Base 3.5.0-1 + nfnl_exp_del@libnl_3 3.5.0-1 + nfnl_exp_dump_request@Base 3.5.0-1 + nfnl_exp_dump_request@libnl_3 3.5.0-1 + nfnl_exp_flags2str@Base 3.5.0-1 + nfnl_exp_flags2str@libnl_3 3.5.0-1 + nfnl_exp_get@Base 3.5.0-1 + nfnl_exp_get@libnl_3 3.5.0-1 + nfnl_exp_get_class@Base 3.5.0-1 + nfnl_exp_get_class@libnl_3 3.5.0-1 + nfnl_exp_get_dst@Base 3.5.0-1 + nfnl_exp_get_dst@libnl_3 3.5.0-1 + nfnl_exp_get_dst_port@Base 3.5.0-1 + nfnl_exp_get_dst_port@libnl_3 3.5.0-1 + nfnl_exp_get_family@Base 3.5.0-1 + nfnl_exp_get_family@libnl_3 3.5.0-1 + nfnl_exp_get_flags@Base 3.5.0-1 + nfnl_exp_get_flags@libnl_3 3.5.0-1 + nfnl_exp_get_fn@Base 3.5.0-1 + nfnl_exp_get_fn@libnl_3 3.5.0-1 + nfnl_exp_get_helper_name@Base 3.5.0-1 + nfnl_exp_get_helper_name@libnl_3 3.5.0-1 + nfnl_exp_get_icmp_code@Base 3.5.0-1 + nfnl_exp_get_icmp_code@libnl_3 3.5.0-1 + nfnl_exp_get_icmp_id@Base 3.5.0-1 + nfnl_exp_get_icmp_id@libnl_3 3.5.0-1 + nfnl_exp_get_icmp_type@Base 3.5.0-1 + nfnl_exp_get_icmp_type@libnl_3 3.5.0-1 + nfnl_exp_get_id@Base 3.5.0-1 + nfnl_exp_get_id@libnl_3 3.5.0-1 + nfnl_exp_get_l4protonum@Base 3.5.0-1 + nfnl_exp_get_l4protonum@libnl_3 3.5.0-1 + nfnl_exp_get_nat_dir@Base 3.5.0-1 + nfnl_exp_get_nat_dir@libnl_3 3.5.0-1 + nfnl_exp_get_src@Base 3.5.0-1 + nfnl_exp_get_src@libnl_3 3.5.0-1 + nfnl_exp_get_src_port@Base 3.5.0-1 + nfnl_exp_get_src_port@libnl_3 3.5.0-1 + nfnl_exp_get_timeout@Base 3.5.0-1 + nfnl_exp_get_timeout@libnl_3 3.5.0-1 + nfnl_exp_get_zone@Base 3.5.0-1 + nfnl_exp_get_zone@libnl_3 3.5.0-1 + nfnl_exp_put@Base 3.5.0-1 + nfnl_exp_put@libnl_3 3.5.0-1 + nfnl_exp_query@Base 3.5.0-1 + nfnl_exp_query@libnl_3 3.5.0-1 + nfnl_exp_set_class@Base 3.5.0-1 + nfnl_exp_set_class@libnl_3 3.5.0-1 + nfnl_exp_set_dst@Base 3.5.0-1 + nfnl_exp_set_dst@libnl_3 3.5.0-1 + nfnl_exp_set_family@Base 3.5.0-1 + nfnl_exp_set_family@libnl_3 3.5.0-1 + nfnl_exp_set_flags@Base 3.5.0-1 + nfnl_exp_set_flags@libnl_3 3.5.0-1 + nfnl_exp_set_fn@Base 3.5.0-1 + nfnl_exp_set_fn@libnl_3 3.5.0-1 + nfnl_exp_set_helper_name@Base 3.5.0-1 + nfnl_exp_set_helper_name@libnl_3 3.5.0-1 + nfnl_exp_set_icmp@Base 3.5.0-1 + nfnl_exp_set_icmp@libnl_3 3.5.0-1 + nfnl_exp_set_id@Base 3.5.0-1 + nfnl_exp_set_id@libnl_3 3.5.0-1 + nfnl_exp_set_l4protonum@Base 3.5.0-1 + nfnl_exp_set_l4protonum@libnl_3 3.5.0-1 + nfnl_exp_set_nat_dir@Base 3.5.0-1 + nfnl_exp_set_nat_dir@libnl_3 3.5.0-1 + nfnl_exp_set_ports@Base 3.5.0-1 + nfnl_exp_set_ports@libnl_3 3.5.0-1 + nfnl_exp_set_src@Base 3.5.0-1 + nfnl_exp_set_src@libnl_3 3.5.0-1 + nfnl_exp_set_timeout@Base 3.5.0-1 + nfnl_exp_set_timeout@libnl_3 3.5.0-1 + nfnl_exp_set_zone@Base 3.5.0-1 + nfnl_exp_set_zone@libnl_3 3.5.0-1 + nfnl_exp_str2flags@Base 3.5.0-1 + nfnl_exp_str2flags@libnl_3 3.5.0-1 + nfnl_exp_test_class@Base 3.5.0-1 + nfnl_exp_test_class@libnl_3 3.5.0-1 + nfnl_exp_test_dst@Base 3.5.0-1 + nfnl_exp_test_dst@libnl_3 3.5.0-1 + nfnl_exp_test_flags@Base 3.5.0-1 + nfnl_exp_test_flags@libnl_3 3.5.0-1 + nfnl_exp_test_fn@Base 3.5.0-1 + nfnl_exp_test_fn@libnl_3 3.5.0-1 + nfnl_exp_test_helper_name@Base 3.5.0-1 + nfnl_exp_test_helper_name@libnl_3 3.5.0-1 + nfnl_exp_test_icmp@Base 3.5.0-1 + nfnl_exp_test_icmp@libnl_3 3.5.0-1 + nfnl_exp_test_id@Base 3.5.0-1 + nfnl_exp_test_id@libnl_3 3.5.0-1 + nfnl_exp_test_l4protonum@Base 3.5.0-1 + nfnl_exp_test_l4protonum@libnl_3 3.5.0-1 + nfnl_exp_test_nat_dir@Base 3.5.0-1 + nfnl_exp_test_nat_dir@libnl_3 3.5.0-1 + nfnl_exp_test_ports@Base 3.5.0-1 + nfnl_exp_test_ports@libnl_3 3.5.0-1 + nfnl_exp_test_src@Base 3.5.0-1 + nfnl_exp_test_src@libnl_3 3.5.0-1 + nfnl_exp_test_timeout@Base 3.5.0-1 + nfnl_exp_test_timeout@libnl_3 3.5.0-1 + nfnl_exp_test_zone@Base 3.5.0-1 + nfnl_exp_test_zone@libnl_3 3.5.0-1 + nfnl_exp_unset_flags@Base 3.5.0-1 + nfnl_exp_unset_flags@libnl_3 3.5.0-1 + nfnl_inet_hook2str@Base 3.5.0-1 + nfnl_inet_hook2str@libnl_3 3.5.0-1 + nfnl_log_alloc@Base 3.5.0-1 + nfnl_log_alloc@libnl_3 3.5.0-1 + nfnl_log_build_change_request@Base 3.5.0-1 + nfnl_log_build_change_request@libnl_3 3.5.0-1 + nfnl_log_build_create_request@Base 3.5.0-1 + nfnl_log_build_create_request@libnl_3 3.5.0-1 + nfnl_log_build_delete_request@Base 3.5.0-1 + nfnl_log_build_delete_request@libnl_3 3.5.0-1 + nfnl_log_build_pf_bind@Base 3.5.0-1 + nfnl_log_build_pf_bind@libnl_3 3.5.0-1 + nfnl_log_build_pf_unbind@Base 3.5.0-1 + nfnl_log_build_pf_unbind@libnl_3 3.5.0-1 + nfnl_log_change@Base 3.5.0-1 + nfnl_log_change@libnl_3 3.5.0-1 + nfnl_log_copy_mode2str@Base 3.5.0-1 + nfnl_log_copy_mode2str@libnl_3 3.5.0-1 + nfnl_log_create@Base 3.5.0-1 + nfnl_log_create@libnl_3 3.5.0-1 + nfnl_log_delete@Base 3.5.0-1 + nfnl_log_delete@libnl_3 3.5.0-1 + nfnl_log_flags2str@Base 3.5.0-1 + nfnl_log_flags2str@libnl_3 3.5.0-1 + nfnl_log_get@Base 3.5.0-1 + nfnl_log_get@libnl_3 3.5.0-1 + nfnl_log_get_alloc_size@Base 3.5.0-1 + nfnl_log_get_alloc_size@libnl_3 3.5.0-1 + nfnl_log_get_copy_mode@Base 3.5.0-1 + nfnl_log_get_copy_mode@libnl_3 3.5.0-1 + nfnl_log_get_copy_range@Base 3.5.0-1 + nfnl_log_get_copy_range@libnl_3 3.5.0-1 + nfnl_log_get_flush_timeout@Base 3.5.0-1 + nfnl_log_get_flush_timeout@libnl_3 3.5.0-1 + nfnl_log_get_group@Base 3.5.0-1 + nfnl_log_get_group@libnl_3 3.5.0-1 + nfnl_log_get_queue_threshold@Base 3.5.0-1 + nfnl_log_get_queue_threshold@libnl_3 3.5.0-1 + nfnl_log_msg_alloc@Base 3.5.0-1 + nfnl_log_msg_alloc@libnl_3 3.5.0-1 + nfnl_log_msg_get@Base 3.5.0-1 + nfnl_log_msg_get@libnl_3 3.5.0-1 + nfnl_log_msg_get_family@Base 3.5.0-1 + nfnl_log_msg_get_family@libnl_3 3.5.0-1 + nfnl_log_msg_get_gid@Base 3.5.0-1 + nfnl_log_msg_get_gid@libnl_3 3.5.0-1 + nfnl_log_msg_get_hook@Base 3.5.0-1 + nfnl_log_msg_get_hook@libnl_3 3.5.0-1 + nfnl_log_msg_get_hwaddr@Base 3.5.0-1 + nfnl_log_msg_get_hwaddr@libnl_3 3.5.0-1 + nfnl_log_msg_get_hwproto@Base 3.5.0-1 + nfnl_log_msg_get_hwproto@libnl_3 3.5.0-1 + nfnl_log_msg_get_indev@Base 3.5.0-1 + nfnl_log_msg_get_indev@libnl_3 3.5.0-1 + nfnl_log_msg_get_mark@Base 3.5.0-1 + nfnl_log_msg_get_mark@libnl_3 3.5.0-1 + nfnl_log_msg_get_outdev@Base 3.5.0-1 + nfnl_log_msg_get_outdev@libnl_3 3.5.0-1 + nfnl_log_msg_get_payload@Base 3.5.0-1 + nfnl_log_msg_get_payload@libnl_3 3.5.0-1 + nfnl_log_msg_get_physindev@Base 3.5.0-1 + nfnl_log_msg_get_physindev@libnl_3 3.5.0-1 + nfnl_log_msg_get_physoutdev@Base 3.5.0-1 + nfnl_log_msg_get_physoutdev@libnl_3 3.5.0-1 + nfnl_log_msg_get_prefix@Base 3.5.0-1 + nfnl_log_msg_get_prefix@libnl_3 3.5.0-1 + nfnl_log_msg_get_seq@Base 3.5.0-1 + nfnl_log_msg_get_seq@libnl_3 3.5.0-1 + nfnl_log_msg_get_seq_global@Base 3.5.0-1 + nfnl_log_msg_get_seq_global@libnl_3 3.5.0-1 + nfnl_log_msg_get_timestamp@Base 3.5.0-1 + nfnl_log_msg_get_timestamp@libnl_3 3.5.0-1 + nfnl_log_msg_get_uid@Base 3.5.0-1 + nfnl_log_msg_get_uid@libnl_3 3.5.0-1 + nfnl_log_msg_put@Base 3.5.0-1 + nfnl_log_msg_put@libnl_3 3.5.0-1 + nfnl_log_msg_set_family@Base 3.5.0-1 + nfnl_log_msg_set_family@libnl_3 3.5.0-1 + nfnl_log_msg_set_gid@Base 3.5.0-1 + nfnl_log_msg_set_gid@libnl_3 3.5.0-1 + nfnl_log_msg_set_hook@Base 3.5.0-1 + nfnl_log_msg_set_hook@libnl_3 3.5.0-1 + nfnl_log_msg_set_hwaddr@Base 3.5.0-1 + nfnl_log_msg_set_hwaddr@libnl_3 3.5.0-1 + nfnl_log_msg_set_hwproto@Base 3.5.0-1 + nfnl_log_msg_set_hwproto@libnl_3 3.5.0-1 + nfnl_log_msg_set_indev@Base 3.5.0-1 + nfnl_log_msg_set_indev@libnl_3 3.5.0-1 + nfnl_log_msg_set_mark@Base 3.5.0-1 + nfnl_log_msg_set_mark@libnl_3 3.5.0-1 + nfnl_log_msg_set_outdev@Base 3.5.0-1 + nfnl_log_msg_set_outdev@libnl_3 3.5.0-1 + nfnl_log_msg_set_payload@Base 3.5.0-1 + nfnl_log_msg_set_payload@libnl_3 3.5.0-1 + nfnl_log_msg_set_physindev@Base 3.5.0-1 + nfnl_log_msg_set_physindev@libnl_3 3.5.0-1 + nfnl_log_msg_set_physoutdev@Base 3.5.0-1 + nfnl_log_msg_set_physoutdev@libnl_3 3.5.0-1 + nfnl_log_msg_set_prefix@Base 3.5.0-1 + nfnl_log_msg_set_prefix@libnl_3 3.5.0-1 + nfnl_log_msg_set_seq@Base 3.5.0-1 + nfnl_log_msg_set_seq@libnl_3 3.5.0-1 + nfnl_log_msg_set_seq_global@Base 3.5.0-1 + nfnl_log_msg_set_seq_global@libnl_3 3.5.0-1 + nfnl_log_msg_set_timestamp@Base 3.5.0-1 + nfnl_log_msg_set_timestamp@libnl_3 3.5.0-1 + nfnl_log_msg_set_uid@Base 3.5.0-1 + nfnl_log_msg_set_uid@libnl_3 3.5.0-1 + nfnl_log_msg_test_gid@Base 3.5.0-1 + nfnl_log_msg_test_gid@libnl_3 3.5.0-1 + nfnl_log_msg_test_hook@Base 3.5.0-1 + nfnl_log_msg_test_hook@libnl_3 3.5.0-1 + nfnl_log_msg_test_hwproto@Base 3.5.0-1 + nfnl_log_msg_test_hwproto@libnl_3 3.5.0-1 + nfnl_log_msg_test_mark@Base 3.5.0-1 + nfnl_log_msg_test_mark@libnl_3 3.5.0-1 + nfnl_log_msg_test_seq@Base 3.5.0-1 + nfnl_log_msg_test_seq@libnl_3 3.5.0-1 + nfnl_log_msg_test_seq_global@Base 3.5.0-1 + nfnl_log_msg_test_seq_global@libnl_3 3.5.0-1 + nfnl_log_msg_test_uid@Base 3.5.0-1 + nfnl_log_msg_test_uid@libnl_3 3.5.0-1 + nfnl_log_pf_bind@Base 3.5.0-1 + nfnl_log_pf_bind@libnl_3 3.5.0-1 + nfnl_log_pf_unbind@Base 3.5.0-1 + nfnl_log_pf_unbind@libnl_3 3.5.0-1 + nfnl_log_put@Base 3.5.0-1 + nfnl_log_put@libnl_3 3.5.0-1 + nfnl_log_set_alloc_size@Base 3.5.0-1 + nfnl_log_set_alloc_size@libnl_3 3.5.0-1 + nfnl_log_set_copy_mode@Base 3.5.0-1 + nfnl_log_set_copy_mode@libnl_3 3.5.0-1 + nfnl_log_set_copy_range@Base 3.5.0-1 + nfnl_log_set_copy_range@libnl_3 3.5.0-1 + nfnl_log_set_flags@Base 3.5.0-1 + nfnl_log_set_flags@libnl_3 3.5.0-1 + nfnl_log_set_flush_timeout@Base 3.5.0-1 + nfnl_log_set_flush_timeout@libnl_3 3.5.0-1 + nfnl_log_set_group@Base 3.5.0-1 + nfnl_log_set_group@libnl_3 3.5.0-1 + nfnl_log_set_queue_threshold@Base 3.5.0-1 + nfnl_log_set_queue_threshold@libnl_3 3.5.0-1 + nfnl_log_str2copy_mode@Base 3.5.0-1 + nfnl_log_str2copy_mode@libnl_3 3.5.0-1 + nfnl_log_str2flags@Base 3.5.0-1 + nfnl_log_str2flags@libnl_3 3.5.0-1 + nfnl_log_test_alloc_size@Base 3.5.0-1 + nfnl_log_test_alloc_size@libnl_3 3.5.0-1 + nfnl_log_test_copy_mode@Base 3.5.0-1 + nfnl_log_test_copy_mode@libnl_3 3.5.0-1 + nfnl_log_test_copy_range@Base 3.5.0-1 + nfnl_log_test_copy_range@libnl_3 3.5.0-1 + nfnl_log_test_flush_timeout@Base 3.5.0-1 + nfnl_log_test_flush_timeout@libnl_3 3.5.0-1 + nfnl_log_test_group@Base 3.5.0-1 + nfnl_log_test_group@libnl_3 3.5.0-1 + nfnl_log_test_queue_threshold@Base 3.5.0-1 + nfnl_log_test_queue_threshold@libnl_3 3.5.0-1 + nfnl_log_unset_flags@Base 3.5.0-1 + nfnl_log_unset_flags@libnl_3 3.5.0-1 + nfnl_queue_alloc@Base 3.5.0-1 + nfnl_queue_alloc@libnl_3 3.5.0-1 + nfnl_queue_build_change_request@Base 3.5.0-1 + nfnl_queue_build_change_request@libnl_3 3.5.0-1 + nfnl_queue_build_create_request@Base 3.5.0-1 + nfnl_queue_build_create_request@libnl_3 3.5.0-1 + nfnl_queue_build_delete_request@Base 3.5.0-1 + nfnl_queue_build_delete_request@libnl_3 3.5.0-1 + nfnl_queue_build_pf_bind@Base 3.5.0-1 + nfnl_queue_build_pf_bind@libnl_3 3.5.0-1 + nfnl_queue_build_pf_unbind@Base 3.5.0-1 + nfnl_queue_build_pf_unbind@libnl_3 3.5.0-1 + nfnl_queue_change@Base 3.5.0-1 + nfnl_queue_change@libnl_3 3.5.0-1 + nfnl_queue_copy_mode2str@Base 3.5.0-1 + nfnl_queue_copy_mode2str@libnl_3 3.5.0-1 + nfnl_queue_create@Base 3.5.0-1 + nfnl_queue_create@libnl_3 3.5.0-1 + nfnl_queue_delete@Base 3.5.0-1 + nfnl_queue_delete@libnl_3 3.5.0-1 + nfnl_queue_get@Base 3.5.0-1 + nfnl_queue_get@libnl_3 3.5.0-1 + nfnl_queue_get_copy_mode@Base 3.5.0-1 + nfnl_queue_get_copy_mode@libnl_3 3.5.0-1 + nfnl_queue_get_copy_range@Base 3.5.0-1 + nfnl_queue_get_copy_range@libnl_3 3.5.0-1 + nfnl_queue_get_group@Base 3.5.0-1 + nfnl_queue_get_group@libnl_3 3.5.0-1 + nfnl_queue_get_maxlen@Base 3.5.0-1 + nfnl_queue_get_maxlen@libnl_3 3.5.0-1 + nfnl_queue_msg_alloc@Base 3.5.0-1 + nfnl_queue_msg_alloc@libnl_3 3.5.0-1 + nfnl_queue_msg_build_verdict@Base 3.5.0-1 + nfnl_queue_msg_build_verdict@libnl_3 3.5.0-1 + nfnl_queue_msg_build_verdict_batch@Base 3.5.0-1 + nfnl_queue_msg_build_verdict_batch@libnl_3 3.5.0-1 + nfnl_queue_msg_get@Base 3.5.0-1 + nfnl_queue_msg_get@libnl_3 3.5.0-1 + nfnl_queue_msg_get_family@Base 3.5.0-1 + nfnl_queue_msg_get_family@libnl_3 3.5.0-1 + nfnl_queue_msg_get_group@Base 3.5.0-1 + nfnl_queue_msg_get_group@libnl_3 3.5.0-1 + nfnl_queue_msg_get_hook@Base 3.5.0-1 + nfnl_queue_msg_get_hook@libnl_3 3.5.0-1 + nfnl_queue_msg_get_hwaddr@Base 3.5.0-1 + nfnl_queue_msg_get_hwaddr@libnl_3 3.5.0-1 + nfnl_queue_msg_get_hwproto@Base 3.5.0-1 + nfnl_queue_msg_get_hwproto@libnl_3 3.5.0-1 + nfnl_queue_msg_get_indev@Base 3.5.0-1 + nfnl_queue_msg_get_indev@libnl_3 3.5.0-1 + nfnl_queue_msg_get_mark@Base 3.5.0-1 + nfnl_queue_msg_get_mark@libnl_3 3.5.0-1 + nfnl_queue_msg_get_outdev@Base 3.5.0-1 + nfnl_queue_msg_get_outdev@libnl_3 3.5.0-1 + nfnl_queue_msg_get_packetid@Base 3.5.0-1 + nfnl_queue_msg_get_packetid@libnl_3 3.5.0-1 + nfnl_queue_msg_get_payload@Base 3.5.0-1 + nfnl_queue_msg_get_payload@libnl_3 3.5.0-1 + nfnl_queue_msg_get_physindev@Base 3.5.0-1 + nfnl_queue_msg_get_physindev@libnl_3 3.5.0-1 + nfnl_queue_msg_get_physoutdev@Base 3.5.0-1 + nfnl_queue_msg_get_physoutdev@libnl_3 3.5.0-1 + nfnl_queue_msg_get_timestamp@Base 3.5.0-1 + nfnl_queue_msg_get_timestamp@libnl_3 3.5.0-1 + nfnl_queue_msg_get_verdict@Base 3.5.0-1 + nfnl_queue_msg_get_verdict@libnl_3 3.5.0-1 + nfnl_queue_msg_put@Base 3.5.0-1 + nfnl_queue_msg_put@libnl_3 3.5.0-1 + nfnl_queue_msg_send_verdict@Base 3.5.0-1 + nfnl_queue_msg_send_verdict@libnl_3 3.5.0-1 + nfnl_queue_msg_send_verdict_batch@Base 3.5.0-1 + nfnl_queue_msg_send_verdict_batch@libnl_3 3.5.0-1 + nfnl_queue_msg_send_verdict_payload@Base 3.5.0-1 + nfnl_queue_msg_send_verdict_payload@libnl_3 3.5.0-1 + nfnl_queue_msg_set_family@Base 3.5.0-1 + nfnl_queue_msg_set_family@libnl_3 3.5.0-1 + nfnl_queue_msg_set_group@Base 3.5.0-1 + nfnl_queue_msg_set_group@libnl_3 3.5.0-1 + nfnl_queue_msg_set_hook@Base 3.5.0-1 + nfnl_queue_msg_set_hook@libnl_3 3.5.0-1 + nfnl_queue_msg_set_hwaddr@Base 3.5.0-1 + nfnl_queue_msg_set_hwaddr@libnl_3 3.5.0-1 + nfnl_queue_msg_set_hwproto@Base 3.5.0-1 + nfnl_queue_msg_set_hwproto@libnl_3 3.5.0-1 + nfnl_queue_msg_set_indev@Base 3.5.0-1 + nfnl_queue_msg_set_indev@libnl_3 3.5.0-1 + nfnl_queue_msg_set_mark@Base 3.5.0-1 + nfnl_queue_msg_set_mark@libnl_3 3.5.0-1 + nfnl_queue_msg_set_outdev@Base 3.5.0-1 + nfnl_queue_msg_set_outdev@libnl_3 3.5.0-1 + nfnl_queue_msg_set_packetid@Base 3.5.0-1 + nfnl_queue_msg_set_packetid@libnl_3 3.5.0-1 + nfnl_queue_msg_set_payload@Base 3.5.0-1 + nfnl_queue_msg_set_payload@libnl_3 3.5.0-1 + nfnl_queue_msg_set_physindev@Base 3.5.0-1 + nfnl_queue_msg_set_physindev@libnl_3 3.5.0-1 + nfnl_queue_msg_set_physoutdev@Base 3.5.0-1 + nfnl_queue_msg_set_physoutdev@libnl_3 3.5.0-1 + nfnl_queue_msg_set_timestamp@Base 3.5.0-1 + nfnl_queue_msg_set_timestamp@libnl_3 3.5.0-1 + nfnl_queue_msg_set_verdict@Base 3.5.0-1 + nfnl_queue_msg_set_verdict@libnl_3 3.5.0-1 + nfnl_queue_msg_test_family@Base 3.5.0-1 + nfnl_queue_msg_test_family@libnl_3 3.5.0-1 + nfnl_queue_msg_test_group@Base 3.5.0-1 + nfnl_queue_msg_test_group@libnl_3 3.5.0-1 + nfnl_queue_msg_test_hook@Base 3.5.0-1 + nfnl_queue_msg_test_hook@libnl_3 3.5.0-1 + nfnl_queue_msg_test_hwaddr@Base 3.5.0-1 + nfnl_queue_msg_test_hwaddr@libnl_3 3.5.0-1 + nfnl_queue_msg_test_hwproto@Base 3.5.0-1 + nfnl_queue_msg_test_hwproto@libnl_3 3.5.0-1 + nfnl_queue_msg_test_indev@Base 3.5.0-1 + nfnl_queue_msg_test_indev@libnl_3 3.5.0-1 + nfnl_queue_msg_test_mark@Base 3.5.0-1 + nfnl_queue_msg_test_mark@libnl_3 3.5.0-1 + nfnl_queue_msg_test_outdev@Base 3.5.0-1 + nfnl_queue_msg_test_outdev@libnl_3 3.5.0-1 + nfnl_queue_msg_test_packetid@Base 3.5.0-1 + nfnl_queue_msg_test_packetid@libnl_3 3.5.0-1 + nfnl_queue_msg_test_payload@Base 3.5.0-1 + nfnl_queue_msg_test_payload@libnl_3 3.5.0-1 + nfnl_queue_msg_test_physindev@Base 3.5.0-1 + nfnl_queue_msg_test_physindev@libnl_3 3.5.0-1 + nfnl_queue_msg_test_physoutdev@Base 3.5.0-1 + nfnl_queue_msg_test_physoutdev@libnl_3 3.5.0-1 + nfnl_queue_msg_test_timestamp@Base 3.5.0-1 + nfnl_queue_msg_test_timestamp@libnl_3 3.5.0-1 + nfnl_queue_msg_test_verdict@Base 3.5.0-1 + nfnl_queue_msg_test_verdict@libnl_3 3.5.0-1 + nfnl_queue_pf_bind@Base 3.5.0-1 + nfnl_queue_pf_bind@libnl_3 3.5.0-1 + nfnl_queue_pf_unbind@Base 3.5.0-1 + nfnl_queue_pf_unbind@libnl_3 3.5.0-1 + nfnl_queue_put@Base 3.5.0-1 + nfnl_queue_put@libnl_3 3.5.0-1 + nfnl_queue_set_copy_mode@Base 3.5.0-1 + nfnl_queue_set_copy_mode@libnl_3 3.5.0-1 + nfnl_queue_set_copy_range@Base 3.5.0-1 + nfnl_queue_set_copy_range@libnl_3 3.5.0-1 + nfnl_queue_set_group@Base 3.5.0-1 + nfnl_queue_set_group@libnl_3 3.5.0-1 + nfnl_queue_set_maxlen@Base 3.5.0-1 + nfnl_queue_set_maxlen@libnl_3 3.5.0-1 + nfnl_queue_socket_alloc@Base 3.5.0-1 + nfnl_queue_socket_alloc@libnl_3 3.5.0-1 + nfnl_queue_str2copy_mode@Base 3.5.0-1 + nfnl_queue_str2copy_mode@libnl_3 3.5.0-1 + nfnl_queue_test_copy_mode@Base 3.5.0-1 + nfnl_queue_test_copy_mode@libnl_3 3.5.0-1 + nfnl_queue_test_copy_range@Base 3.5.0-1 + nfnl_queue_test_copy_range@libnl_3 3.5.0-1 + nfnl_queue_test_group@Base 3.5.0-1 + nfnl_queue_test_group@libnl_3 3.5.0-1 + nfnl_queue_test_maxlen@Base 3.5.0-1 + nfnl_queue_test_maxlen@libnl_3 3.5.0-1 + nfnl_send_simple@Base 3.5.0-1 + nfnl_send_simple@libnl_3 3.5.0-1 + nfnl_str2inet_hook@Base 3.5.0-1 + nfnl_str2inet_hook@libnl_3 3.5.0-1 + nfnl_str2verdict@Base 3.5.0-1 + nfnl_str2verdict@libnl_3 3.5.0-1 + nfnl_verdict2str@Base 3.5.0-1 + nfnl_verdict2str@libnl_3 3.5.0-1 + nfnlmsg_alloc_simple@Base 3.5.0-1 + nfnlmsg_alloc_simple@libnl_3 3.5.0-1 + nfnlmsg_ct_group@Base 3.5.0-1 + nfnlmsg_ct_group@libnl_3 3.5.0-1 + nfnlmsg_ct_parse@Base 3.5.0-1 + nfnlmsg_ct_parse@libnl_3 3.5.0-1 + nfnlmsg_exp_group@Base 3.5.0-1 + nfnlmsg_exp_group@libnl_3 3.5.0-1 + nfnlmsg_exp_parse@Base 3.5.0-1 + nfnlmsg_exp_parse@libnl_3 3.5.0-1 + nfnlmsg_family@Base 3.5.0-1 + nfnlmsg_family@libnl_3 3.5.0-1 + nfnlmsg_log_msg_parse@Base 3.5.0-1 + nfnlmsg_log_msg_parse@libnl_3 3.5.0-1 + nfnlmsg_put@Base 3.5.0-1 + nfnlmsg_put@libnl_3 3.5.0-1 + nfnlmsg_queue_msg_parse@Base 3.5.0-1 + nfnlmsg_queue_msg_parse@libnl_3 3.5.0-1 + nfnlmsg_res_id@Base 3.5.0-1 + nfnlmsg_res_id@libnl_3 3.5.0-1 + nfnlmsg_subsys@Base 3.5.0-1 + nfnlmsg_subsys@libnl_3 3.5.0-1 + nfnlmsg_subtype@Base 3.5.0-1 + nfnlmsg_subtype@libnl_3 3.5.0-1 + queue_msg_obj_ops@Base 3.5.0-1 + queue_msg_obj_ops@libnl_3 3.5.0-1 + queue_obj_ops@Base 3.5.0-1 + queue_obj_ops@libnl_3 3.5.0-1 diff --git a/src/libnl3/debian/libnl-nf-3-dev.install b/src/libnl3/debian/libnl-nf-3-dev.install new file mode 100644 index 000000000000..d1307c751b84 --- /dev/null +++ b/src/libnl3/debian/libnl-nf-3-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/*/pkgconfig/libnl-nf-3* +debian/tmp/usr/lib/*/libnl-nf-3*.so +debian/tmp/usr/lib/*/libnl-nf-3*.a diff --git a/src/libnl3/debian/libnl-route-3-200.install b/src/libnl3/debian/libnl-route-3-200.install new file mode 100644 index 000000000000..44c7ec8cdfad --- /dev/null +++ b/src/libnl3/debian/libnl-route-3-200.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/*/libnl-route-3*.so.* diff --git a/src/libnl3/debian/libnl-route-3-200.symbols b/src/libnl3/debian/libnl-route-3-200.symbols new file mode 100644 index 000000000000..e11157ba4e88 --- /dev/null +++ b/src/libnl3/debian/libnl-route-3-200.symbols @@ -0,0 +1,2051 @@ +libnl-route-3.so.200 libnl-route-3-200 #MINVER# + ematch__create_buffer@Base 3.5.0-1 + ematch__delete_buffer@Base 3.5.0-1 + ematch__flush_buffer@Base 3.5.0-1 + ematch__scan_buffer@Base 3.5.0-1 + ematch__scan_bytes@Base 3.5.0-1 + ematch__scan_string@Base 3.5.0-1 + ematch__switch_to_buffer@Base 3.5.0-1 + ematch_alloc@Base 3.5.0-1 + ematch_free@Base 3.5.0-1 + ematch_get_column@Base 3.5.0-1 + ematch_get_debug@Base 3.5.0-1 + ematch_get_extra@Base 3.5.0-1 + ematch_get_in@Base 3.5.0-1 + ematch_get_leng@Base 3.5.0-1 + ematch_get_lineno@Base 3.5.0-1 + ematch_get_lval@Base 3.5.0-1 + ematch_get_out@Base 3.5.0-1 + ematch_get_text@Base 3.5.0-1 + ematch_lex@Base 3.5.0-1 + ematch_lex_destroy@Base 3.5.0-1 + ematch_lex_init@Base 3.5.0-1 + ematch_lex_init_extra@Base 3.5.0-1 + ematch_parse@Base 3.5.0-1 + ematch_pop_buffer_state@Base 3.5.0-1 + ematch_push_buffer_state@Base 3.5.0-1 + ematch_realloc@Base 3.5.0-1 + ematch_restart@Base 3.5.0-1 + ematch_set_column@Base 3.5.0-1 + ematch_set_debug@Base 3.5.0-1 + ematch_set_extra@Base 3.5.0-1 + ematch_set_in@Base 3.5.0-1 + ematch_set_lineno@Base 3.5.0-1 + ematch_set_lval@Base 3.5.0-1 + ematch_set_out@Base 3.5.0-1 + flnl_lookup@Base 3.5.0-1 + flnl_lookup@libnl_3 3.5.0-1 + flnl_lookup_build_request@Base 3.5.0-1 + flnl_lookup_build_request@libnl_3 3.5.0-1 + flnl_request_alloc@Base 3.5.0-1 + flnl_request_alloc@libnl_3 3.5.0-1 + flnl_request_get_addr@Base 3.5.0-1 + flnl_request_get_addr@libnl_3 3.5.0-1 + flnl_request_get_fwmark@Base 3.5.0-1 + flnl_request_get_fwmark@libnl_3 3.5.0-1 + flnl_request_get_scope@Base 3.5.0-1 + flnl_request_get_scope@libnl_3 3.5.0-1 + flnl_request_get_table@Base 3.5.0-1 + flnl_request_get_table@libnl_3 3.5.0-1 + flnl_request_get_tos@Base 3.5.0-1 + flnl_request_get_tos@libnl_3 3.5.0-1 + flnl_request_set_addr@Base 3.5.0-1 + flnl_request_set_addr@libnl_3 3.5.0-1 + flnl_request_set_fwmark@Base 3.5.0-1 + flnl_request_set_fwmark@libnl_3 3.5.0-1 + flnl_request_set_scope@Base 3.5.0-1 + flnl_request_set_scope@libnl_3 3.5.0-1 + flnl_request_set_table@Base 3.5.0-1 + flnl_request_set_table@libnl_3 3.5.0-1 + flnl_request_set_tos@Base 3.5.0-1 + flnl_request_set_tos@libnl_3 3.5.0-1 + flnl_result_alloc@Base 3.5.0-1 + flnl_result_alloc@libnl_3 3.5.0-1 + flnl_result_alloc_cache@Base 3.5.0-1 + flnl_result_alloc_cache@libnl_3 3.5.0-1 + flnl_result_get_error@Base 3.5.0-1 + flnl_result_get_error@libnl_3 3.5.0-1 + flnl_result_get_nexthop_sel@Base 3.5.0-1 + flnl_result_get_nexthop_sel@libnl_3 3.5.0-1 + flnl_result_get_prefixlen@Base 3.5.0-1 + flnl_result_get_prefixlen@libnl_3 3.5.0-1 + flnl_result_get_scope@Base 3.5.0-1 + flnl_result_get_scope@libnl_3 3.5.0-1 + flnl_result_get_table_id@Base 3.5.0-1 + flnl_result_get_table_id@libnl_3 3.5.0-1 + flnl_result_get_type@Base 3.5.0-1 + flnl_result_get_type@libnl_3 3.5.0-1 + flnl_result_put@Base 3.5.0-1 + flnl_result_put@libnl_3 3.5.0-1 + libnl_3@libnl_3 3.5.0-1 + libnl_3_2_26@libnl_3_2_26 3.5.0-1 + libnl_3_2_27@libnl_3_2_27 3.5.0-1 + libnl_3_2_28@libnl_3_2_28 3.5.0-1 + libnl_3_2_29@libnl_3_2_29 3.5.0-1 + libnl_3_4@libnl_3_4 3.5.0-1 + libnl_3_5@libnl_3_5 3.5.0-1 + nl_ovl_strategy2str@Base 3.5.0-1 + nl_ovl_strategy2str@libnl_3 3.5.0-1 + nl_police2str@Base 3.5.0-1 + nl_police2str@libnl_3 3.5.0-1 + nl_rtgen_request@Base 3.5.0-1 + nl_rtgen_request@libnl_3 3.5.0-1 + nl_rtntype2str@Base 3.5.0-1 + nl_rtntype2str@libnl_3 3.5.0-1 + nl_str2ovl_strategy@Base 3.5.0-1 + nl_str2ovl_strategy@libnl_3 3.5.0-1 + nl_str2police@Base 3.5.0-1 + nl_str2police@libnl_3 3.5.0-1 + nl_str2rtntype@Base 3.5.0-1 + nl_str2rtntype@libnl_3 3.5.0-1 + pktloc__create_buffer@Base 3.5.0-1 + pktloc__delete_buffer@Base 3.5.0-1 + pktloc__flush_buffer@Base 3.5.0-1 + pktloc__scan_buffer@Base 3.5.0-1 + pktloc__scan_bytes@Base 3.5.0-1 + pktloc__scan_string@Base 3.5.0-1 + pktloc__switch_to_buffer@Base 3.5.0-1 + pktloc_alloc@Base 3.5.0-1 + pktloc_free@Base 3.5.0-1 + pktloc_get_column@Base 3.5.0-1 + pktloc_get_debug@Base 3.5.0-1 + pktloc_get_extra@Base 3.5.0-1 + pktloc_get_in@Base 3.5.0-1 + pktloc_get_leng@Base 3.5.0-1 + pktloc_get_lineno@Base 3.5.0-1 + pktloc_get_lloc@Base 3.5.0-1 + pktloc_get_lval@Base 3.5.0-1 + pktloc_get_out@Base 3.5.0-1 + pktloc_get_text@Base 3.5.0-1 + pktloc_lex@Base 3.5.0-1 + pktloc_lex_destroy@Base 3.5.0-1 + pktloc_lex_init@Base 3.5.0-1 + pktloc_lex_init_extra@Base 3.5.0-1 + pktloc_parse@Base 3.5.0-1 + pktloc_pop_buffer_state@Base 3.5.0-1 + pktloc_push_buffer_state@Base 3.5.0-1 + pktloc_realloc@Base 3.5.0-1 + pktloc_restart@Base 3.5.0-1 + pktloc_set_column@Base 3.5.0-1 + pktloc_set_debug@Base 3.5.0-1 + pktloc_set_extra@Base 3.5.0-1 + pktloc_set_in@Base 3.5.0-1 + pktloc_set_lineno@Base 3.5.0-1 + pktloc_set_lloc@Base 3.5.0-1 + + pktloc_set_lval@Base 3.5.0-1 + pktloc_set_out@Base 3.5.0-1 + route_obj_ops@Base 3.5.0-1 + route_obj_ops@libnl_3 3.5.0-1 + rtln_link_policy@Base 3.5.0-1 + rtln_link_policy@libnl_3 3.5.0-1 + rtnl_act_add@Base 3.5.0-1 + rtnl_act_add@libnl_3 3.5.0-1 + rtnl_act_alloc@Base 3.5.0-1 + rtnl_act_alloc@libnl_3 3.5.0-1 + rtnl_act_append@Base 3.5.0-1 + rtnl_act_append@libnl_3 3.5.0-1 + rtnl_act_build_add_request@Base 3.5.0-1 + rtnl_act_build_add_request@libnl_3 3.5.0-1 + rtnl_act_build_change_request@Base 3.5.0-1 + rtnl_act_build_change_request@libnl_3 3.5.0-1 + rtnl_act_build_delete_request@Base 3.5.0-1 + rtnl_act_build_delete_request@libnl_3 3.5.0-1 + rtnl_act_change@Base 3.5.0-1 + rtnl_act_change@libnl_3 3.5.0-1 + rtnl_act_delete@Base 3.5.0-1 + rtnl_act_delete@libnl_3 3.5.0-1 + rtnl_act_fill@Base 3.5.0-1 + rtnl_act_fill@libnl_3 3.5.0-1 + rtnl_act_get@Base 3.5.0-1 + rtnl_act_get@libnl_3 3.5.0-1 + rtnl_act_next@libnl_3_4 3.5.0-1 + rtnl_act_parse@Base 3.5.0-1 + rtnl_act_parse@libnl_3 3.5.0-1 + rtnl_act_put@Base 3.5.0-1 + rtnl_act_put@libnl_3 3.5.0-1 + rtnl_act_put_all@Base 3.5.0-1 + rtnl_act_put_all@libnl_3 3.5.0-1 + rtnl_act_remove@Base 3.5.0-1 + rtnl_act_remove@libnl_3 3.5.0-1 + rtnl_addr_add@Base 3.5.0-1 + rtnl_addr_add@libnl_3 3.5.0-1 + rtnl_addr_alloc@Base 3.5.0-1 + rtnl_addr_alloc@libnl_3 3.5.0-1 + rtnl_addr_alloc_cache@Base 3.5.0-1 + rtnl_addr_alloc_cache@libnl_3 3.5.0-1 + rtnl_addr_build_add_request@Base 3.5.0-1 + rtnl_addr_build_add_request@libnl_3 3.5.0-1 + rtnl_addr_build_delete_request@Base 3.5.0-1 + rtnl_addr_build_delete_request@libnl_3 3.5.0-1 + rtnl_addr_delete@Base 3.5.0-1 + rtnl_addr_delete@libnl_3 3.5.0-1 + rtnl_addr_flags2str@Base 3.5.0-1 + rtnl_addr_flags2str@libnl_3 3.5.0-1 + rtnl_addr_get@Base 3.5.0-1 + rtnl_addr_get@libnl_3 3.5.0-1 + rtnl_addr_get_anycast@Base 3.5.0-1 + rtnl_addr_get_anycast@libnl_3 3.5.0-1 + rtnl_addr_get_broadcast@Base 3.5.0-1 + rtnl_addr_get_broadcast@libnl_3 3.5.0-1 + rtnl_addr_get_create_time@Base 3.5.0-1 + rtnl_addr_get_create_time@libnl_3 3.5.0-1 + rtnl_addr_get_family@Base 3.5.0-1 + rtnl_addr_get_family@libnl_3 3.5.0-1 + rtnl_addr_get_flags@Base 3.5.0-1 + rtnl_addr_get_flags@libnl_3 3.5.0-1 + rtnl_addr_get_ifindex@Base 3.5.0-1 + rtnl_addr_get_ifindex@libnl_3 3.5.0-1 + rtnl_addr_get_label@Base 3.5.0-1 + rtnl_addr_get_label@libnl_3 3.5.0-1 + rtnl_addr_get_last_update_time@Base 3.5.0-1 + rtnl_addr_get_last_update_time@libnl_3 3.5.0-1 + rtnl_addr_get_link@Base 3.5.0-1 + rtnl_addr_get_link@libnl_3 3.5.0-1 + rtnl_addr_get_local@Base 3.5.0-1 + rtnl_addr_get_local@libnl_3 3.5.0-1 + rtnl_addr_get_multicast@Base 3.5.0-1 + rtnl_addr_get_multicast@libnl_3 3.5.0-1 + rtnl_addr_get_peer@Base 3.5.0-1 + rtnl_addr_get_peer@libnl_3 3.5.0-1 + rtnl_addr_get_preferred_lifetime@Base 3.5.0-1 + rtnl_addr_get_preferred_lifetime@libnl_3 3.5.0-1 + rtnl_addr_get_prefixlen@Base 3.5.0-1 + rtnl_addr_get_prefixlen@libnl_3 3.5.0-1 + rtnl_addr_get_scope@Base 3.5.0-1 + rtnl_addr_get_scope@libnl_3 3.5.0-1 + rtnl_addr_get_valid_lifetime@Base 3.5.0-1 + rtnl_addr_get_valid_lifetime@libnl_3 3.5.0-1 + rtnl_addr_put@Base 3.5.0-1 + rtnl_addr_put@libnl_3 3.5.0-1 + rtnl_addr_set_anycast@Base 3.5.0-1 + rtnl_addr_set_anycast@libnl_3 3.5.0-1 + rtnl_addr_set_broadcast@Base 3.5.0-1 + rtnl_addr_set_broadcast@libnl_3 3.5.0-1 + rtnl_addr_set_family@Base 3.5.0-1 + rtnl_addr_set_family@libnl_3 3.5.0-1 + rtnl_addr_set_flags@Base 3.5.0-1 + rtnl_addr_set_flags@libnl_3 3.5.0-1 + rtnl_addr_set_ifindex@Base 3.5.0-1 + rtnl_addr_set_ifindex@libnl_3 3.5.0-1 + rtnl_addr_set_label@Base 3.5.0-1 + rtnl_addr_set_label@libnl_3 3.5.0-1 + rtnl_addr_set_link@Base 3.5.0-1 + rtnl_addr_set_link@libnl_3 3.5.0-1 + rtnl_addr_set_local@Base 3.5.0-1 + rtnl_addr_set_local@libnl_3 3.5.0-1 + rtnl_addr_set_multicast@Base 3.5.0-1 + rtnl_addr_set_multicast@libnl_3 3.5.0-1 + rtnl_addr_set_peer@Base 3.5.0-1 + rtnl_addr_set_peer@libnl_3 3.5.0-1 + rtnl_addr_set_preferred_lifetime@Base 3.5.0-1 + rtnl_addr_set_preferred_lifetime@libnl_3 3.5.0-1 + rtnl_addr_set_prefixlen@Base 3.5.0-1 + rtnl_addr_set_prefixlen@libnl_3 3.5.0-1 + rtnl_addr_set_scope@Base 3.5.0-1 + rtnl_addr_set_scope@libnl_3 3.5.0-1 + rtnl_addr_set_valid_lifetime@Base 3.5.0-1 + rtnl_addr_set_valid_lifetime@libnl_3 3.5.0-1 + rtnl_addr_str2flags@Base 3.5.0-1 + rtnl_addr_str2flags@libnl_3 3.5.0-1 + rtnl_addr_unset_flags@Base 3.5.0-1 + rtnl_addr_unset_flags@libnl_3 3.5.0-1 + rtnl_basic_add_action@Base 3.5.0-1 + rtnl_basic_add_action@libnl_3 3.5.0-1 + rtnl_basic_del_action@Base 3.5.0-1 + rtnl_basic_del_action@libnl_3 3.5.0-1 + rtnl_basic_get_action@libnl_3_4 3.5.0-1 + rtnl_basic_get_ematch@Base 3.5.0-1 + rtnl_basic_get_ematch@libnl_3 3.5.0-1 + rtnl_basic_get_target@Base 3.5.0-1 + rtnl_basic_get_target@libnl_3 3.5.0-1 + rtnl_basic_set_ematch@Base 3.5.0-1 + rtnl_basic_set_ematch@libnl_3 3.5.0-1 + rtnl_basic_set_target@Base 3.5.0-1 + rtnl_basic_set_target@libnl_3 3.5.0-1 + rtnl_cgroup_get_ematch@Base 3.5.0-1 + rtnl_cgroup_get_ematch@libnl_3 3.5.0-1 + rtnl_cgroup_set_ematch@Base 3.5.0-1 + rtnl_cgroup_set_ematch@libnl_3 3.5.0-1 + rtnl_class_add@Base 3.5.0-1 + rtnl_class_add@libnl_3 3.5.0-1 + rtnl_class_alloc@Base 3.5.0-1 + rtnl_class_alloc@libnl_3 3.5.0-1 + rtnl_class_alloc_cache@Base 3.5.0-1 + rtnl_class_alloc_cache@libnl_3 3.5.0-1 + rtnl_class_build_add_request@Base 3.5.0-1 + rtnl_class_build_add_request@libnl_3 3.5.0-1 + rtnl_class_build_delete_request@Base 3.5.0-1 + rtnl_class_build_delete_request@libnl_3 3.5.0-1 + rtnl_class_delete@Base 3.5.0-1 + rtnl_class_delete@libnl_3 3.5.0-1 + rtnl_class_dsmark_get_bitmask@Base 3.5.0-1 + rtnl_class_dsmark_get_bitmask@libnl_3 3.5.0-1 + rtnl_class_dsmark_get_value@Base 3.5.0-1 + rtnl_class_dsmark_get_value@libnl_3 3.5.0-1 + rtnl_class_dsmark_set_bitmask@Base 3.5.0-1 + rtnl_class_dsmark_set_bitmask@libnl_3 3.5.0-1 + rtnl_class_dsmark_set_value@Base 3.5.0-1 + rtnl_class_dsmark_set_value@libnl_3 3.5.0-1 + rtnl_class_foreach_child@Base 3.5.0-1 + rtnl_class_foreach_child@libnl_3 3.5.0-1 + rtnl_class_foreach_cls@Base 3.5.0-1 + rtnl_class_foreach_cls@libnl_3 3.5.0-1 + rtnl_class_get@Base 3.5.0-1 + rtnl_class_get@libnl_3 3.5.0-1 + rtnl_class_get_by_parent@libnl_3_5 3.5.0-1 + rtnl_class_hfsc_get_fsc@Base 3.5.0-1 + rtnl_class_hfsc_get_fsc@libnl_3 3.5.0-1 + rtnl_class_hfsc_get_rsc@Base 3.5.0-1 + rtnl_class_hfsc_get_rsc@libnl_3 3.5.0-1 + rtnl_class_hfsc_get_usc@Base 3.5.0-1 + rtnl_class_hfsc_get_usc@libnl_3 3.5.0-1 + rtnl_class_hfsc_set_fsc@Base 3.5.0-1 + rtnl_class_hfsc_set_fsc@libnl_3 3.5.0-1 + rtnl_class_hfsc_set_rsc@Base 3.5.0-1 + rtnl_class_hfsc_set_rsc@libnl_3 3.5.0-1 + rtnl_class_hfsc_set_usc@Base 3.5.0-1 + rtnl_class_hfsc_set_usc@libnl_3 3.5.0-1 + rtnl_class_leaf_qdisc@Base 3.5.0-1 + rtnl_class_leaf_qdisc@libnl_3 3.5.0-1 + rtnl_class_put@Base 3.5.0-1 + rtnl_class_put@libnl_3 3.5.0-1 + rtnl_classid_generate@Base 3.5.0-1 + rtnl_classid_generate@libnl_3 3.5.0-1 + rtnl_cls_add@Base 3.5.0-1 + rtnl_cls_add@libnl_3 3.5.0-1 + rtnl_cls_alloc@Base 3.5.0-1 + rtnl_cls_alloc@libnl_3 3.5.0-1 + rtnl_cls_alloc_cache@Base 3.5.0-1 + rtnl_cls_alloc_cache@libnl_3 3.5.0-1 + rtnl_cls_build_add_request@Base 3.5.0-1 + rtnl_cls_build_add_request@libnl_3 3.5.0-1 + rtnl_cls_build_change_request@Base 3.5.0-1 + rtnl_cls_build_change_request@libnl_3 3.5.0-1 + rtnl_cls_build_delete_request@Base 3.5.0-1 + rtnl_cls_build_delete_request@libnl_3 3.5.0-1 + rtnl_cls_cache_set_tc_params@libnl_3_5 3.5.0-1 + rtnl_cls_change@Base 3.5.0-1 + rtnl_cls_change@libnl_3 3.5.0-1 + rtnl_cls_delete@Base 3.5.0-1 + rtnl_cls_delete@libnl_3 3.5.0-1 + rtnl_cls_get_prio@Base 3.5.0-1 + rtnl_cls_get_prio@libnl_3 3.5.0-1 + rtnl_cls_get_protocol@Base 3.5.0-1 + rtnl_cls_get_protocol@libnl_3 3.5.0-1 + rtnl_cls_put@Base 3.5.0-1 + rtnl_cls_put@libnl_3 3.5.0-1 + rtnl_cls_set_prio@Base 3.5.0-1 + rtnl_cls_set_prio@libnl_3 3.5.0-1 + rtnl_cls_set_protocol@Base 3.5.0-1 + rtnl_cls_set_protocol@libnl_3 3.5.0-1 + rtnl_ematch_add_child@Base 3.5.0-1 + rtnl_ematch_add_child@libnl_3 3.5.0-1 + rtnl_ematch_alloc@Base 3.5.0-1 + rtnl_ematch_alloc@libnl_3 3.5.0-1 + rtnl_ematch_cmp_get@Base 3.5.0-1 + rtnl_ematch_cmp_get@libnl_3 3.5.0-1 + rtnl_ematch_cmp_set@Base 3.5.0-1 + rtnl_ematch_cmp_set@libnl_3 3.5.0-1 + rtnl_ematch_data@Base 3.5.0-1 + rtnl_ematch_data@libnl_3 3.5.0-1 + rtnl_ematch_fill_attr@Base 3.5.0-1 + rtnl_ematch_fill_attr@libnl_3 3.5.0-1 + rtnl_ematch_free@Base 3.5.0-1 + rtnl_ematch_free@libnl_3 3.5.0-1 + rtnl_ematch_get_flags@Base 3.5.0-1 + rtnl_ematch_get_flags@libnl_3 3.5.0-1 + rtnl_ematch_lookup_ops@Base 3.5.0-1 + rtnl_ematch_lookup_ops@libnl_3 3.5.0-1 + rtnl_ematch_lookup_ops_by_name@Base 3.5.0-1 + rtnl_ematch_lookup_ops_by_name@libnl_3 3.5.0-1 + rtnl_ematch_meta_set_lvalue@Base 3.5.0-1 + rtnl_ematch_meta_set_lvalue@libnl_3 3.5.0-1 + rtnl_ematch_meta_set_operand@Base 3.5.0-1 + rtnl_ematch_meta_set_operand@libnl_3 3.5.0-1 + rtnl_ematch_meta_set_rvalue@Base 3.5.0-1 + rtnl_ematch_meta_set_rvalue@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_get_layer@Base 3.5.0-1 + rtnl_ematch_nbyte_get_layer@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_get_len@Base 3.5.0-1 + rtnl_ematch_nbyte_get_len@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_get_offset@Base 3.5.0-1 + rtnl_ematch_nbyte_get_offset@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_get_pattern@Base 3.5.0-1 + rtnl_ematch_nbyte_get_pattern@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_set_offset@Base 3.5.0-1 + rtnl_ematch_nbyte_set_offset@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_set_pattern@Base 3.5.0-1 + rtnl_ematch_nbyte_set_pattern@libnl_3 3.5.0-1 + rtnl_ematch_offset2txt@Base 3.5.0-1 + rtnl_ematch_offset2txt@libnl_3 3.5.0-1 + rtnl_ematch_opnd2txt@Base 3.5.0-1 + rtnl_ematch_opnd2txt@libnl_3 3.5.0-1 + rtnl_ematch_parse_attr@Base 3.5.0-1 + rtnl_ematch_parse_attr@libnl_3 3.5.0-1 + rtnl_ematch_parse_expr@Base 3.5.0-1 + rtnl_ematch_parse_expr@libnl_3 3.5.0-1 + rtnl_ematch_register@Base 3.5.0-1 + rtnl_ematch_register@libnl_3 3.5.0-1 + rtnl_ematch_set_flags@Base 3.5.0-1 + rtnl_ematch_set_flags@libnl_3 3.5.0-1 + rtnl_ematch_set_kind@Base 3.5.0-1 + rtnl_ematch_set_kind@libnl_3 3.5.0-1 + rtnl_ematch_set_name@Base 3.5.0-1 + rtnl_ematch_set_name@libnl_3 3.5.0-1 + rtnl_ematch_set_ops@Base 3.5.0-1 + rtnl_ematch_set_ops@libnl_3 3.5.0-1 + rtnl_ematch_text_get_algo@Base 3.5.0-1 + rtnl_ematch_text_get_algo@libnl_3 3.5.0-1 + rtnl_ematch_text_get_from_layer@Base 3.5.0-1 + rtnl_ematch_text_get_from_layer@libnl_3 3.5.0-1 + rtnl_ematch_text_get_from_offset@Base 3.5.0-1 + rtnl_ematch_text_get_from_offset@libnl_3 3.5.0-1 + rtnl_ematch_text_get_len@Base 3.5.0-1 + rtnl_ematch_text_get_len@libnl_3 3.5.0-1 + rtnl_ematch_text_get_pattern@Base 3.5.0-1 + rtnl_ematch_text_get_pattern@libnl_3 3.5.0-1 + rtnl_ematch_text_get_to_layer@Base 3.5.0-1 + rtnl_ematch_text_get_to_layer@libnl_3 3.5.0-1 + rtnl_ematch_text_get_to_offset@Base 3.5.0-1 + rtnl_ematch_text_get_to_offset@libnl_3 3.5.0-1 + rtnl_ematch_text_set_algo@Base 3.5.0-1 + rtnl_ematch_text_set_algo@libnl_3 3.5.0-1 + rtnl_ematch_text_set_from@Base 3.5.0-1 + rtnl_ematch_text_set_from@libnl_3 3.5.0-1 + rtnl_ematch_text_set_pattern@Base 3.5.0-1 + rtnl_ematch_text_set_pattern@libnl_3 3.5.0-1 + rtnl_ematch_text_set_to@Base 3.5.0-1 + rtnl_ematch_text_set_to@libnl_3 3.5.0-1 + rtnl_ematch_tree_add@Base 3.5.0-1 + rtnl_ematch_tree_add@libnl_3 3.5.0-1 + rtnl_ematch_tree_alloc@Base 3.5.0-1 + rtnl_ematch_tree_alloc@libnl_3 3.5.0-1 + rtnl_ematch_tree_clone@libnl_3_5 3.5.0-1 + rtnl_ematch_tree_dump@Base 3.5.0-1 + rtnl_ematch_tree_dump@libnl_3 3.5.0-1 + rtnl_ematch_tree_free@Base 3.5.0-1 + rtnl_ematch_tree_free@libnl_3 3.5.0-1 + rtnl_ematch_unlink@Base 3.5.0-1 + rtnl_ematch_unlink@libnl_3 3.5.0-1 + rtnl_ematch_unset_flags@Base 3.5.0-1 + rtnl_ematch_unset_flags@libnl_3 3.5.0-1 + rtnl_fw_set_classid@Base 3.5.0-1 + rtnl_fw_set_classid@libnl_3 3.5.0-1 + rtnl_fw_set_mask@Base 3.5.0-1 + rtnl_fw_set_mask@libnl_3 3.5.0-1 + rtnl_gact_get_action@libnl_3_2_29 3.5.0-1 + rtnl_gact_set_action@libnl_3_2_29 3.5.0-1 + rtnl_htb_get_cbuffer@Base 3.5.0-1 + rtnl_htb_get_cbuffer@libnl_3 3.5.0-1 + rtnl_htb_get_ceil64@libnl_3_5 3.5.0-1 + rtnl_htb_get_ceil@Base 3.5.0-1 + rtnl_htb_get_ceil@libnl_3 3.5.0-1 + rtnl_htb_get_defcls@Base 3.5.0-1 + rtnl_htb_get_defcls@libnl_3 3.5.0-1 + rtnl_htb_get_level@Base 3.5.0-1 + rtnl_htb_get_level@libnl_3 3.5.0-1 + rtnl_htb_get_prio@Base 3.5.0-1 + rtnl_htb_get_prio@libnl_3 3.5.0-1 + rtnl_htb_get_quantum@Base 3.5.0-1 + rtnl_htb_get_quantum@libnl_3 3.5.0-1 + rtnl_htb_get_rate2quantum@Base 3.5.0-1 + rtnl_htb_get_rate2quantum@libnl_3 3.5.0-1 + rtnl_htb_get_rate64@libnl_3_5 3.5.0-1 + rtnl_htb_get_rate@Base 3.5.0-1 + rtnl_htb_get_rate@libnl_3 3.5.0-1 + rtnl_htb_get_rbuffer@Base 3.5.0-1 + rtnl_htb_get_rbuffer@libnl_3 3.5.0-1 + rtnl_htb_set_cbuffer@Base 3.5.0-1 + rtnl_htb_set_cbuffer@libnl_3 3.5.0-1 + rtnl_htb_set_ceil64@libnl_3_5 3.5.0-1 + rtnl_htb_set_ceil@Base 3.5.0-1 + rtnl_htb_set_ceil@libnl_3 3.5.0-1 + rtnl_htb_set_defcls@Base 3.5.0-1 + rtnl_htb_set_defcls@libnl_3 3.5.0-1 + rtnl_htb_set_level@Base 3.5.0-1 + rtnl_htb_set_level@libnl_3 3.5.0-1 + rtnl_htb_set_prio@Base 3.5.0-1 + rtnl_htb_set_prio@libnl_3 3.5.0-1 + rtnl_htb_set_quantum@Base 3.5.0-1 + rtnl_htb_set_quantum@libnl_3 3.5.0-1 + rtnl_htb_set_rate2quantum@Base 3.5.0-1 + rtnl_htb_set_rate2quantum@libnl_3 3.5.0-1 + rtnl_htb_set_rate64@libnl_3_5 3.5.0-1 + rtnl_htb_set_rate@Base 3.5.0-1 + rtnl_htb_set_rate@libnl_3 3.5.0-1 + rtnl_htb_set_rbuffer@Base 3.5.0-1 + rtnl_htb_set_rbuffer@libnl_3 3.5.0-1 + rtnl_link_add@Base 3.5.0-1 + rtnl_link_add@libnl_3 3.5.0-1 + rtnl_link_af_alloc@Base 3.5.0-1 + rtnl_link_af_alloc@libnl_3 3.5.0-1 + rtnl_link_af_data@Base 3.5.0-1 + rtnl_link_af_data@libnl_3 3.5.0-1 + rtnl_link_af_data_compare@Base 3.5.0-1 + rtnl_link_af_data_compare@libnl_3 3.5.0-1 + rtnl_link_af_ops_lookup@Base 3.5.0-1 + rtnl_link_af_ops_lookup@libnl_3 3.5.0-1 + rtnl_link_af_ops_put@Base 3.5.0-1 + rtnl_link_af_ops_put@libnl_3 3.5.0-1 + rtnl_link_af_register@Base 3.5.0-1 + rtnl_link_af_register@libnl_3 3.5.0-1 + rtnl_link_af_unregister@Base 3.5.0-1 + rtnl_link_af_unregister@libnl_3 3.5.0-1 + rtnl_link_alloc@Base 3.5.0-1 + rtnl_link_alloc@libnl_3 3.5.0-1 + rtnl_link_alloc_cache@Base 3.5.0-1 + rtnl_link_alloc_cache@libnl_3 3.5.0-1 + rtnl_link_alloc_cache_flags@libnl_3_2_28 3.5.0-1 + rtnl_link_bond_add@Base 3.5.0-1 + rtnl_link_bond_add@libnl_3 3.5.0-1 + rtnl_link_bond_alloc@Base 3.5.0-1 + rtnl_link_bond_alloc@libnl_3 3.5.0-1 + rtnl_link_bond_enslave@Base 3.5.0-1 + rtnl_link_bond_enslave@libnl_3 3.5.0-1 + rtnl_link_bond_enslave_ifindex@Base 3.5.0-1 + rtnl_link_bond_enslave_ifindex@libnl_3 3.5.0-1 + rtnl_link_bond_release@Base 3.5.0-1 + rtnl_link_bond_release@libnl_3 3.5.0-1 + rtnl_link_bond_release_ifindex@Base 3.5.0-1 + rtnl_link_bond_release_ifindex@libnl_3 3.5.0-1 + rtnl_link_bridge_add@Base 3.5.0-1 + rtnl_link_bridge_add@libnl_3 3.5.0-1 + rtnl_link_bridge_alloc@Base 3.5.0-1 + rtnl_link_bridge_alloc@libnl_3 3.5.0-1 + rtnl_link_bridge_flags2str@Base 3.5.0-1 + rtnl_link_bridge_flags2str@libnl_3 3.5.0-1 + rtnl_link_bridge_get_cost@Base 3.5.0-1 + rtnl_link_bridge_get_cost@libnl_3 3.5.0-1 + rtnl_link_bridge_get_flags@Base 3.5.0-1 + rtnl_link_bridge_get_flags@libnl_3 3.5.0-1 + rtnl_link_bridge_get_hwmode@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_get_port_state@Base 3.5.0-1 + rtnl_link_bridge_get_port_state@libnl_3 3.5.0-1 + rtnl_link_bridge_get_port_vlan@libnl_3_2_28 3.5.0-1 + rtnl_link_bridge_get_priority@Base 3.5.0-1 + rtnl_link_bridge_get_priority@libnl_3 3.5.0-1 + rtnl_link_bridge_has_ext_info@Base 3.5.0-1 + rtnl_link_bridge_has_ext_info@libnl_3 3.5.0-1 + rtnl_link_bridge_has_vlan@libnl_3_2_28 3.5.0-1 + rtnl_link_bridge_hwmode2str@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_portstate2str@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_pvid@libnl_3_2_28 3.5.0-1 + rtnl_link_bridge_set_cost@Base 3.5.0-1 + rtnl_link_bridge_set_cost@libnl_3 3.5.0-1 + rtnl_link_bridge_set_flags@Base 3.5.0-1 + rtnl_link_bridge_set_flags@libnl_3 3.5.0-1 + rtnl_link_bridge_set_hwmode@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_set_port_state@Base 3.5.0-1 + rtnl_link_bridge_set_port_state@libnl_3 3.5.0-1 + rtnl_link_bridge_set_priority@Base 3.5.0-1 + rtnl_link_bridge_set_priority@libnl_3 3.5.0-1 + rtnl_link_bridge_set_self@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_str2flags@Base 3.5.0-1 + rtnl_link_bridge_str2flags@libnl_3 3.5.0-1 + rtnl_link_bridge_str2hwmode@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_str2portstate@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_unset_flags@Base 3.5.0-1 + rtnl_link_bridge_unset_flags@libnl_3 3.5.0-1 + rtnl_link_build_add_request@Base 3.5.0-1 + rtnl_link_build_add_request@libnl_3 3.5.0-1 + rtnl_link_build_change_request@Base 3.5.0-1 + rtnl_link_build_change_request@libnl_3 3.5.0-1 + rtnl_link_build_delete_request@Base 3.5.0-1 + rtnl_link_build_delete_request@libnl_3 3.5.0-1 + rtnl_link_build_get_request@Base 3.5.0-1 + rtnl_link_build_get_request@libnl_3 3.5.0-1 + rtnl_link_can_berr@Base 3.5.0-1 + rtnl_link_can_berr@libnl_3 3.5.0-1 + rtnl_link_can_berr_rx@Base 3.5.0-1 + rtnl_link_can_berr_rx@libnl_3 3.5.0-1 + rtnl_link_can_berr_tx@Base 3.5.0-1 + rtnl_link_can_berr_tx@libnl_3 3.5.0-1 + rtnl_link_can_ctrlmode2str@Base 3.5.0-1 + rtnl_link_can_ctrlmode2str@libnl_3 3.5.0-1 + rtnl_link_can_freq@Base 3.5.0-1 + rtnl_link_can_freq@libnl_3 3.5.0-1 + rtnl_link_can_get_bitrate@Base 3.5.0-1 + rtnl_link_can_get_bitrate@libnl_3 3.5.0-1 + rtnl_link_can_get_bittiming@Base 3.5.0-1 + rtnl_link_can_get_bittiming@libnl_3 3.5.0-1 + rtnl_link_can_get_bt_const@Base 3.5.0-1 + rtnl_link_can_get_bt_const@libnl_3 3.5.0-1 + rtnl_link_can_get_ctrlmode@Base 3.5.0-1 + rtnl_link_can_get_ctrlmode@libnl_3 3.5.0-1 + rtnl_link_can_get_restart_ms@Base 3.5.0-1 + rtnl_link_can_get_restart_ms@libnl_3 3.5.0-1 + rtnl_link_can_get_sample_point@Base 3.5.0-1 + rtnl_link_can_get_sample_point@libnl_3 3.5.0-1 + rtnl_link_can_restart@Base 3.5.0-1 + rtnl_link_can_restart@libnl_3 3.5.0-1 + rtnl_link_can_set_bitrate@Base 3.5.0-1 + rtnl_link_can_set_bitrate@libnl_3 3.5.0-1 + rtnl_link_can_set_bittiming@Base 3.5.0-1 + rtnl_link_can_set_bittiming@libnl_3 3.5.0-1 + rtnl_link_can_set_ctrlmode@Base 3.5.0-1 + rtnl_link_can_set_ctrlmode@libnl_3 3.5.0-1 + rtnl_link_can_set_restart_ms@Base 3.5.0-1 + rtnl_link_can_set_restart_ms@libnl_3 3.5.0-1 + rtnl_link_can_set_sample_point@Base 3.5.0-1 + rtnl_link_can_set_sample_point@libnl_3 3.5.0-1 + rtnl_link_can_state@Base 3.5.0-1 + rtnl_link_can_state@libnl_3 3.5.0-1 + rtnl_link_can_str2ctrlmode@Base 3.5.0-1 + rtnl_link_can_str2ctrlmode@libnl_3 3.5.0-1 + rtnl_link_can_unset_ctrlmode@Base 3.5.0-1 + rtnl_link_can_unset_ctrlmode@libnl_3 3.5.0-1 + rtnl_link_carrier2str@Base 3.5.0-1 + rtnl_link_carrier2str@libnl_3 3.5.0-1 + rtnl_link_change@Base 3.5.0-1 + rtnl_link_change@libnl_3 3.5.0-1 + rtnl_link_delete@Base 3.5.0-1 + rtnl_link_delete@libnl_3 3.5.0-1 + rtnl_link_enslave@Base 3.5.0-1 + rtnl_link_enslave@libnl_3 3.5.0-1 + rtnl_link_enslave_ifindex@Base 3.5.0-1 + rtnl_link_enslave_ifindex@libnl_3 3.5.0-1 + rtnl_link_fill_info@Base 3.5.0-1 + rtnl_link_fill_info@libnl_3 3.5.0-1 + rtnl_link_flags2str@Base 3.5.0-1 + rtnl_link_flags2str@libnl_3 3.5.0-1 + rtnl_link_geneve_alloc@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_flags@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_id@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_label@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_port@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_remote@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_tos@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_ttl@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_udp_csum@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_udp_zero_csum6_rx@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_udp_zero_csum6_tx@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_flags@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_id@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_label@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_port@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_remote@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_tos@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_ttl@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_udp_csum@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_udp_zero_csum6_rx@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_udp_zero_csum6_tx@libnl_3_5 3.5.0-1 + rtnl_link_get@Base 3.5.0-1 + rtnl_link_get@libnl_3 3.5.0-1 + rtnl_link_get_addr@Base 3.5.0-1 + rtnl_link_get_addr@libnl_3 3.5.0-1 + rtnl_link_get_arptype@Base 3.5.0-1 + rtnl_link_get_arptype@libnl_3 3.5.0-1 + rtnl_link_get_broadcast@Base 3.5.0-1 + rtnl_link_get_broadcast@libnl_3 3.5.0-1 + rtnl_link_get_by_name@Base 3.5.0-1 + rtnl_link_get_by_name@libnl_3 3.5.0-1 + rtnl_link_get_carrier@Base 3.5.0-1 + rtnl_link_get_carrier@libnl_3 3.5.0-1 + rtnl_link_get_carrier_changes@libnl_3_2_29 3.5.0-1 + rtnl_link_get_family@Base 3.5.0-1 + rtnl_link_get_family@libnl_3 3.5.0-1 + rtnl_link_get_flags@Base 3.5.0-1 + rtnl_link_get_flags@libnl_3 3.5.0-1 + rtnl_link_get_group@Base 3.5.0-1 + rtnl_link_get_group@libnl_3 3.5.0-1 + rtnl_link_get_gso_max_segs@libnl_3_2_29 3.5.0-1 + rtnl_link_get_gso_max_size@libnl_3_2_29 3.5.0-1 + rtnl_link_get_ifalias@Base 3.5.0-1 + rtnl_link_get_ifalias@libnl_3 3.5.0-1 + rtnl_link_get_ifindex@Base 3.5.0-1 + rtnl_link_get_ifindex@libnl_3 3.5.0-1 + rtnl_link_get_info_type@Base 3.5.0-1 + rtnl_link_get_info_type@libnl_3 3.5.0-1 + rtnl_link_get_kernel@Base 3.5.0-1 + rtnl_link_get_kernel@libnl_3 3.5.0-1 + rtnl_link_get_link@Base 3.5.0-1 + rtnl_link_get_link@libnl_3 3.5.0-1 + rtnl_link_get_link_netnsid@Base 3.5.0-1 + rtnl_link_get_link_netnsid@libnl_3_2_27 3.5.0-1 + rtnl_link_get_linkmode@Base 3.5.0-1 + rtnl_link_get_linkmode@libnl_3 3.5.0-1 + rtnl_link_get_master@Base 3.5.0-1 + rtnl_link_get_master@libnl_3 3.5.0-1 + rtnl_link_get_mtu@Base 3.5.0-1 + rtnl_link_get_mtu@libnl_3 3.5.0-1 + rtnl_link_get_name@Base 3.5.0-1 + rtnl_link_get_name@libnl_3 3.5.0-1 + rtnl_link_get_ns_fd@Base 3.5.0-1 + rtnl_link_get_ns_fd@libnl_3 3.5.0-1 + rtnl_link_get_ns_pid@Base 3.5.0-1 + rtnl_link_get_ns_pid@libnl_3 3.5.0-1 + rtnl_link_get_num_rx_queues@Base 3.5.0-1 + rtnl_link_get_num_rx_queues@libnl_3 3.5.0-1 + rtnl_link_get_num_tx_queues@Base 3.5.0-1 + rtnl_link_get_num_tx_queues@libnl_3 3.5.0-1 + rtnl_link_get_num_vf@Base 3.5.0-1 + rtnl_link_get_num_vf@libnl_3 3.5.0-1 + rtnl_link_get_operstate@Base 3.5.0-1 + rtnl_link_get_operstate@libnl_3 3.5.0-1 + rtnl_link_get_phys_port_id@Base 3.5.0-1 + rtnl_link_get_phys_port_id@libnl_3 3.5.0-1 + rtnl_link_get_phys_port_name@libnl_3_2_29 3.5.0-1 + rtnl_link_get_phys_switch_id@libnl_3_2_29 3.5.0-1 + rtnl_link_get_pmtudisc@Base 3.5.0-1 + rtnl_link_get_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_get_promiscuity@Base 3.5.0-1 + rtnl_link_get_promiscuity@libnl_3 3.5.0-1 + rtnl_link_get_qdisc@Base 3.5.0-1 + rtnl_link_get_qdisc@libnl_3 3.5.0-1 + rtnl_link_get_slave_type@libnl_3_5 3.5.0-1 + rtnl_link_get_stat@Base 3.5.0-1 + rtnl_link_get_stat@libnl_3 3.5.0-1 + rtnl_link_get_txqlen@Base 3.5.0-1 + rtnl_link_get_txqlen@libnl_3 3.5.0-1 + rtnl_link_get_type@Base 3.5.0-1 + rtnl_link_get_type@libnl_3 3.5.0-1 + rtnl_link_get_weight@Base 3.5.0-1 + rtnl_link_get_weight@libnl_3 3.5.0-1 + rtnl_link_has_vf_list@libnl_3_2_29 3.5.0-1 + rtnl_link_i2name@Base 3.5.0-1 + rtnl_link_i2name@libnl_3 3.5.0-1 + rtnl_link_inet6_addrgenmode2str@Base 3.5.0-1 + rtnl_link_inet6_addrgenmode2str@libnl_3 3.5.0-1 + rtnl_link_inet6_flags2str@libnl_3_4 3.5.0-1 + rtnl_link_inet6_get_addr_gen_mode@Base 3.5.0-1 + rtnl_link_inet6_get_addr_gen_mode@libnl_3 3.5.0-1 + rtnl_link_inet6_get_flags@libnl_3_4 3.5.0-1 + rtnl_link_inet6_get_token@Base 3.5.0-1 + rtnl_link_inet6_get_token@libnl_3 3.5.0-1 + rtnl_link_inet6_set_addr_gen_mode@Base 3.5.0-1 + rtnl_link_inet6_set_addr_gen_mode@libnl_3 3.5.0-1 + rtnl_link_inet6_set_flags@libnl_3_4 3.5.0-1 + rtnl_link_inet6_set_token@Base 3.5.0-1 + rtnl_link_inet6_set_token@libnl_3 3.5.0-1 + rtnl_link_inet6_str2addrgenmode@Base 3.5.0-1 + rtnl_link_inet6_str2addrgenmode@libnl_3 3.5.0-1 + rtnl_link_inet6_str2flags@libnl_3_4 3.5.0-1 + rtnl_link_inet_devconf2str@Base 3.5.0-1 + rtnl_link_inet_devconf2str@libnl_3 3.5.0-1 + rtnl_link_inet_get_conf@Base 3.5.0-1 + rtnl_link_inet_get_conf@libnl_3 3.5.0-1 + rtnl_link_inet_set_conf@Base 3.5.0-1 + rtnl_link_inet_set_conf@libnl_3 3.5.0-1 + rtnl_link_inet_str2devconf@Base 3.5.0-1 + rtnl_link_inet_str2devconf@libnl_3 3.5.0-1 + rtnl_link_info_ops_lookup@Base 3.5.0-1 + rtnl_link_info_ops_lookup@libnl_3 3.5.0-1 + rtnl_link_info_ops_put@Base 3.5.0-1 + rtnl_link_info_ops_put@libnl_3 3.5.0-1 + rtnl_link_info_parse@Base 3.5.0-1 + rtnl_link_info_parse@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_add@Base 3.5.0-1 + rtnl_link_ip6_tnl_add@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_alloc@Base 3.5.0-1 + rtnl_link_ip6_tnl_alloc@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_encaplimit@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_encaplimit@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_flags@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_flags@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_flowinfo@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_flowinfo@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_link@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_link@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_local@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_local@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_proto@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_proto@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_remote@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_remote@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_tos@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_tos@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_ttl@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_ttl@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_encaplimit@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_encaplimit@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_flags@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_flags@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_flowinfo@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_flowinfo@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_link@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_link@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_local@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_local@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_proto@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_proto@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_remote@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_remote@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_tos@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_tos@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_ttl@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_ttl@libnl_3 3.5.0-1 + rtnl_link_ipgre_add@Base 3.5.0-1 + rtnl_link_ipgre_add@libnl_3 3.5.0-1 + rtnl_link_ipgre_alloc@Base 3.5.0-1 + rtnl_link_ipgre_alloc@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_iflags@Base 3.5.0-1 + rtnl_link_ipgre_get_iflags@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_ikey@Base 3.5.0-1 + rtnl_link_ipgre_get_ikey@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_link@Base 3.5.0-1 + rtnl_link_ipgre_get_link@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_local@Base 3.5.0-1 + rtnl_link_ipgre_get_local@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_oflags@Base 3.5.0-1 + rtnl_link_ipgre_get_oflags@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_okey@Base 3.5.0-1 + rtnl_link_ipgre_get_okey@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_pmtudisc@libnl_3_2_29 3.5.0-1 + rtnl_link_ipgre_get_remote@Base 3.5.0-1 + rtnl_link_ipgre_get_remote@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_tos@Base 3.5.0-1 + rtnl_link_ipgre_get_tos@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_ttl@Base 3.5.0-1 + rtnl_link_ipgre_get_ttl@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_iflags@Base 3.5.0-1 + rtnl_link_ipgre_set_iflags@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_ikey@Base 3.5.0-1 + rtnl_link_ipgre_set_ikey@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_link@Base 3.5.0-1 + rtnl_link_ipgre_set_link@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_local@Base 3.5.0-1 + rtnl_link_ipgre_set_local@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_oflags@Base 3.5.0-1 + rtnl_link_ipgre_set_oflags@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_okey@Base 3.5.0-1 + rtnl_link_ipgre_set_okey@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_pmtudisc@Base 3.5.0-1 + rtnl_link_ipgre_set_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_remote@Base 3.5.0-1 + rtnl_link_ipgre_set_remote@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_tos@Base 3.5.0-1 + rtnl_link_ipgre_set_tos@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_ttl@Base 3.5.0-1 + rtnl_link_ipgre_set_ttl@libnl_3 3.5.0-1 + rtnl_link_ipgretap_add@libnl_3_2_28 3.5.0-1 + rtnl_link_ipgretap_alloc@libnl_3_2_28 3.5.0-1 + rtnl_link_ipip_add@Base 3.5.0-1 + rtnl_link_ipip_add@libnl_3 3.5.0-1 + rtnl_link_ipip_alloc@Base 3.5.0-1 + rtnl_link_ipip_alloc@libnl_3 3.5.0-1 + rtnl_link_ipip_get_link@Base 3.5.0-1 + rtnl_link_ipip_get_link@libnl_3 3.5.0-1 + rtnl_link_ipip_get_local@Base 3.5.0-1 + rtnl_link_ipip_get_local@libnl_3 3.5.0-1 + rtnl_link_ipip_get_pmtudisc@Base 3.5.0-1 + rtnl_link_ipip_get_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_ipip_get_remote@Base 3.5.0-1 + rtnl_link_ipip_get_remote@libnl_3 3.5.0-1 + rtnl_link_ipip_get_tos@Base 3.5.0-1 + rtnl_link_ipip_get_tos@libnl_3 3.5.0-1 + rtnl_link_ipip_get_ttl@Base 3.5.0-1 + rtnl_link_ipip_get_ttl@libnl_3 3.5.0-1 + rtnl_link_ipip_set_link@Base 3.5.0-1 + rtnl_link_ipip_set_link@libnl_3 3.5.0-1 + rtnl_link_ipip_set_local@Base 3.5.0-1 + rtnl_link_ipip_set_local@libnl_3 3.5.0-1 + rtnl_link_ipip_set_pmtudisc@Base 3.5.0-1 + rtnl_link_ipip_set_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_ipip_set_remote@Base 3.5.0-1 + rtnl_link_ipip_set_remote@libnl_3 3.5.0-1 + rtnl_link_ipip_set_tos@Base 3.5.0-1 + rtnl_link_ipip_set_tos@libnl_3 3.5.0-1 + rtnl_link_ipip_set_ttl@Base 3.5.0-1 + rtnl_link_ipip_set_ttl@libnl_3 3.5.0-1 + rtnl_link_ipvlan_alloc@Base 3.5.0-1 + rtnl_link_ipvlan_alloc@libnl_3_2_27 3.5.0-1 + rtnl_link_ipvlan_get_mode@Base 3.5.0-1 + rtnl_link_ipvlan_get_mode@libnl_3_2_27 3.5.0-1 + rtnl_link_ipvlan_mode2str@Base 3.5.0-1 + rtnl_link_ipvlan_mode2str@libnl_3_2_27 3.5.0-1 + rtnl_link_ipvlan_set_mode@Base 3.5.0-1 + rtnl_link_ipvlan_set_mode@libnl_3_2_27 3.5.0-1 + rtnl_link_ipvlan_str2mode@Base 3.5.0-1 + rtnl_link_ipvlan_str2mode@libnl_3_2_27 3.5.0-1 + rtnl_link_ipvti_add@Base 3.5.0-1 + rtnl_link_ipvti_add@libnl_3 3.5.0-1 + rtnl_link_ipvti_alloc@Base 3.5.0-1 + rtnl_link_ipvti_alloc@libnl_3 3.5.0-1 + rtnl_link_ipvti_get_ikey@Base 3.5.0-1 + rtnl_link_ipvti_get_ikey@libnl_3 3.5.0-1 + rtnl_link_ipvti_get_link@Base 3.5.0-1 + rtnl_link_ipvti_get_link@libnl_3 3.5.0-1 + rtnl_link_ipvti_get_local@Base 3.5.0-1 + rtnl_link_ipvti_get_local@libnl_3 3.5.0-1 + rtnl_link_ipvti_get_okey@Base 3.5.0-1 + rtnl_link_ipvti_get_okey@libnl_3 3.5.0-1 + rtnl_link_ipvti_get_remote@Base 3.5.0-1 + rtnl_link_ipvti_get_remote@libnl_3 3.5.0-1 + rtnl_link_ipvti_set_ikey@Base 3.5.0-1 + rtnl_link_ipvti_set_ikey@libnl_3 3.5.0-1 + rtnl_link_ipvti_set_link@Base 3.5.0-1 + rtnl_link_ipvti_set_link@libnl_3 3.5.0-1 + rtnl_link_ipvti_set_local@Base 3.5.0-1 + rtnl_link_ipvti_set_local@libnl_3 3.5.0-1 + rtnl_link_ipvti_set_okey@Base 3.5.0-1 + rtnl_link_ipvti_set_okey@libnl_3 3.5.0-1 + rtnl_link_ipvti_set_remote@Base 3.5.0-1 + rtnl_link_ipvti_set_remote@libnl_3 3.5.0-1 + rtnl_link_is_bridge@Base 3.5.0-1 + rtnl_link_is_bridge@libnl_3 3.5.0-1 + rtnl_link_is_can@Base 3.5.0-1 + rtnl_link_is_can@libnl_3 3.5.0-1 + rtnl_link_is_geneve@libnl_3_5 3.5.0-1 + rtnl_link_is_ip6_tnl@Base 3.5.0-1 + rtnl_link_is_ip6_tnl@libnl_3 3.5.0-1 + rtnl_link_is_ipgre@Base 3.5.0-1 + rtnl_link_is_ipgre@libnl_3 3.5.0-1 + rtnl_link_is_ipgretap@libnl_3_2_29 3.5.0-1 + rtnl_link_is_ipip@Base 3.5.0-1 + rtnl_link_is_ipip@libnl_3 3.5.0-1 + rtnl_link_is_ipvlan@Base 3.5.0-1 + rtnl_link_is_ipvlan@libnl_3_2_27 3.5.0-1 + rtnl_link_is_ipvti@Base 3.5.0-1 + rtnl_link_is_ipvti@libnl_3 3.5.0-1 + rtnl_link_is_macvlan@Base 3.5.0-1 + rtnl_link_is_macvlan@libnl_3 3.5.0-1 + rtnl_link_is_macvtap@libnl_3_2_28 3.5.0-1 + rtnl_link_is_sit@Base 3.5.0-1 + rtnl_link_is_sit@libnl_3 3.5.0-1 + rtnl_link_is_veth@Base 3.5.0-1 + rtnl_link_is_veth@libnl_3 3.5.0-1 + rtnl_link_is_vlan@Base 3.5.0-1 + rtnl_link_is_vlan@libnl_3 3.5.0-1 + rtnl_link_is_vrf@libnl_3_2_28 3.5.0-1 + rtnl_link_is_vxlan@Base 3.5.0-1 + rtnl_link_is_vxlan@libnl_3 3.5.0-1 + rtnl_link_is_xfrmi@libnl_3_5 3.5.0-1 + rtnl_link_macsec_alloc@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_cipher_suite@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_encoding_sa@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_encrypt@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_end_station@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_icv_len@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_port@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_protect@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_replay_protect@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_scb@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_sci@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_send_sci@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_validation_type@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_window@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_cipher_suite@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_encoding_sa@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_encrypt@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_end_station@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_icv_len@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_port@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_protect@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_replay_protect@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_scb@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_sci@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_send_sci@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_validation_type@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_window@libnl_3_2_28 3.5.0-1 + rtnl_link_macvlan_add_macaddr@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_alloc@Base 3.5.0-1 + rtnl_link_macvlan_alloc@libnl_3 3.5.0-1 + rtnl_link_macvlan_count_macaddr@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_del_macaddr@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_flags2str@Base 3.5.0-1 + rtnl_link_macvlan_flags2str@libnl_3 3.5.0-1 + rtnl_link_macvlan_get_flags@Base 3.5.0-1 + rtnl_link_macvlan_get_flags@libnl_3 3.5.0-1 + rtnl_link_macvlan_get_macaddr@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_get_macmode@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_get_mode@Base 3.5.0-1 + rtnl_link_macvlan_get_mode@libnl_3 3.5.0-1 + rtnl_link_macvlan_macmode2str@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_mode2str@Base 3.5.0-1 + rtnl_link_macvlan_mode2str@libnl_3 3.5.0-1 + rtnl_link_macvlan_set_flags@Base 3.5.0-1 + rtnl_link_macvlan_set_flags@libnl_3 3.5.0-1 + rtnl_link_macvlan_set_macmode@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_set_mode@Base 3.5.0-1 + rtnl_link_macvlan_set_mode@libnl_3 3.5.0-1 + rtnl_link_macvlan_str2flags@Base 3.5.0-1 + rtnl_link_macvlan_str2flags@libnl_3 3.5.0-1 + rtnl_link_macvlan_str2macmode@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_str2mode@Base 3.5.0-1 + rtnl_link_macvlan_str2mode@libnl_3 3.5.0-1 + rtnl_link_macvlan_unset_flags@Base 3.5.0-1 + rtnl_link_macvlan_unset_flags@libnl_3 3.5.0-1 + rtnl_link_macvtap_alloc@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_flags2str@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_get_flags@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_get_mode@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_mode2str@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_set_flags@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_set_mode@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_str2flags@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_str2mode@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_unset_flags@libnl_3_2_28 3.5.0-1 + rtnl_link_mode2str@Base 3.5.0-1 + rtnl_link_mode2str@libnl_3 3.5.0-1 + rtnl_link_name2i@Base 3.5.0-1 + rtnl_link_name2i@libnl_3 3.5.0-1 + rtnl_link_operstate2str@Base 3.5.0-1 + rtnl_link_operstate2str@libnl_3 3.5.0-1 + rtnl_link_ppp_alloc@libnl_3_2_29 3.5.0-1 + rtnl_link_ppp_get_fd@libnl_3_2_29 3.5.0-1 + rtnl_link_ppp_set_fd@libnl_3_2_29 3.5.0-1 + rtnl_link_put@Base 3.5.0-1 + rtnl_link_put@libnl_3 3.5.0-1 + rtnl_link_register_info@Base 3.5.0-1 + rtnl_link_register_info@libnl_3 3.5.0-1 + rtnl_link_release@Base 3.5.0-1 + rtnl_link_release@libnl_3 3.5.0-1 + rtnl_link_release_ifindex@Base 3.5.0-1 + rtnl_link_release_ifindex@libnl_3 3.5.0-1 + rtnl_link_set_addr@Base 3.5.0-1 + rtnl_link_set_addr@libnl_3 3.5.0-1 + rtnl_link_set_arptype@Base 3.5.0-1 + rtnl_link_set_arptype@libnl_3 3.5.0-1 + rtnl_link_set_broadcast@Base 3.5.0-1 + rtnl_link_set_broadcast@libnl_3 3.5.0-1 + rtnl_link_set_carrier@Base 3.5.0-1 + rtnl_link_set_carrier@libnl_3 3.5.0-1 + rtnl_link_set_family@Base 3.5.0-1 + rtnl_link_set_family@libnl_3 3.5.0-1 + rtnl_link_set_flags@Base 3.5.0-1 + rtnl_link_set_flags@libnl_3 3.5.0-1 + rtnl_link_set_group@Base 3.5.0-1 + rtnl_link_set_group@libnl_3 3.5.0-1 + rtnl_link_set_ifalias@Base 3.5.0-1 + rtnl_link_set_ifalias@libnl_3 3.5.0-1 + rtnl_link_set_ifindex@Base 3.5.0-1 + rtnl_link_set_ifindex@libnl_3 3.5.0-1 + rtnl_link_set_info_type@Base 3.5.0-1 + rtnl_link_set_info_type@libnl_3 3.5.0-1 + rtnl_link_set_link@Base 3.5.0-1 + rtnl_link_set_link@libnl_3 3.5.0-1 + rtnl_link_set_link_netnsid@Base 3.5.0-1 + rtnl_link_set_link_netnsid@libnl_3_2_27 3.5.0-1 + rtnl_link_set_linkmode@Base 3.5.0-1 + rtnl_link_set_linkmode@libnl_3 3.5.0-1 + rtnl_link_set_master@Base 3.5.0-1 + rtnl_link_set_master@libnl_3 3.5.0-1 + rtnl_link_set_mtu@Base 3.5.0-1 + rtnl_link_set_mtu@libnl_3 3.5.0-1 + rtnl_link_set_name@Base 3.5.0-1 + rtnl_link_set_name@libnl_3 3.5.0-1 + rtnl_link_set_ns_fd@Base 3.5.0-1 + rtnl_link_set_ns_fd@libnl_3 3.5.0-1 + rtnl_link_set_ns_pid@Base 3.5.0-1 + rtnl_link_set_ns_pid@libnl_3 3.5.0-1 + rtnl_link_set_num_rx_queues@Base 3.5.0-1 + rtnl_link_set_num_rx_queues@libnl_3 3.5.0-1 + rtnl_link_set_num_tx_queues@Base 3.5.0-1 + rtnl_link_set_num_tx_queues@libnl_3 3.5.0-1 + rtnl_link_set_operstate@Base 3.5.0-1 + rtnl_link_set_operstate@libnl_3 3.5.0-1 + rtnl_link_set_promiscuity@Base 3.5.0-1 + rtnl_link_set_promiscuity@libnl_3 3.5.0-1 + rtnl_link_set_qdisc@Base 3.5.0-1 + rtnl_link_set_qdisc@libnl_3 3.5.0-1 + rtnl_link_set_slave_type@libnl_3_5 3.5.0-1 + rtnl_link_set_stat@Base 3.5.0-1 + rtnl_link_set_stat@libnl_3 3.5.0-1 + rtnl_link_set_txqlen@Base 3.5.0-1 + rtnl_link_set_txqlen@libnl_3 3.5.0-1 + rtnl_link_set_type@Base 3.5.0-1 + rtnl_link_set_type@libnl_3 3.5.0-1 + rtnl_link_set_vf_list@libnl_3_2_29 3.5.0-1 + rtnl_link_set_weight@Base 3.5.0-1 + rtnl_link_set_weight@libnl_3 3.5.0-1 + rtnl_link_sit_add@Base 3.5.0-1 + rtnl_link_sit_add@libnl_3 3.5.0-1 + rtnl_link_sit_alloc@Base 3.5.0-1 + rtnl_link_sit_alloc@libnl_3 3.5.0-1 + rtnl_link_sit_get_flags@Base 3.5.0-1 + rtnl_link_sit_get_flags@libnl_3 3.5.0-1 + rtnl_link_sit_get_ip6rd_prefix@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_get_ip6rd_prefixlen@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_get_ip6rd_relay_prefix@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_get_ip6rd_relay_prefixlen@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_get_link@Base 3.5.0-1 + rtnl_link_sit_get_link@libnl_3 3.5.0-1 + rtnl_link_sit_get_local@Base 3.5.0-1 + rtnl_link_sit_get_local@libnl_3 3.5.0-1 + rtnl_link_sit_get_pmtudisc@Base 3.5.0-1 + rtnl_link_sit_get_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_sit_get_proto@Base 3.5.0-1 + rtnl_link_sit_get_proto@libnl_3 3.5.0-1 + rtnl_link_sit_get_remote@Base 3.5.0-1 + rtnl_link_sit_get_remote@libnl_3 3.5.0-1 + rtnl_link_sit_get_tos@Base 3.5.0-1 + rtnl_link_sit_get_tos@libnl_3 3.5.0-1 + rtnl_link_sit_get_ttl@Base 3.5.0-1 + rtnl_link_sit_get_ttl@libnl_3 3.5.0-1 + rtnl_link_sit_set_flags@Base 3.5.0-1 + rtnl_link_sit_set_flags@libnl_3 3.5.0-1 + rtnl_link_sit_set_ip6rd_prefix@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_set_ip6rd_prefixlen@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_set_ip6rd_relay_prefix@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_set_ip6rd_relay_prefixlen@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_set_link@Base 3.5.0-1 + rtnl_link_sit_set_link@libnl_3 3.5.0-1 + rtnl_link_sit_set_local@Base 3.5.0-1 + rtnl_link_sit_set_local@libnl_3 3.5.0-1 + rtnl_link_sit_set_pmtudisc@Base 3.5.0-1 + rtnl_link_sit_set_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_sit_set_proto@Base 3.5.0-1 + rtnl_link_sit_set_proto@libnl_3 3.5.0-1 + rtnl_link_sit_set_remote@Base 3.5.0-1 + rtnl_link_sit_set_remote@libnl_3 3.5.0-1 + rtnl_link_sit_set_tos@Base 3.5.0-1 + rtnl_link_sit_set_tos@libnl_3 3.5.0-1 + rtnl_link_sit_set_ttl@Base 3.5.0-1 + rtnl_link_sit_set_ttl@libnl_3 3.5.0-1 + rtnl_link_stat2str@Base 3.5.0-1 + rtnl_link_stat2str@libnl_3 3.5.0-1 + rtnl_link_str2carrier@Base 3.5.0-1 + rtnl_link_str2carrier@libnl_3 3.5.0-1 + rtnl_link_str2flags@Base 3.5.0-1 + rtnl_link_str2flags@libnl_3 3.5.0-1 + rtnl_link_str2mode@Base 3.5.0-1 + rtnl_link_str2mode@libnl_3 3.5.0-1 + rtnl_link_str2operstate@Base 3.5.0-1 + rtnl_link_str2operstate@libnl_3 3.5.0-1 + rtnl_link_str2stat@Base 3.5.0-1 + rtnl_link_str2stat@libnl_3 3.5.0-1 + rtnl_link_unregister_info@Base 3.5.0-1 + rtnl_link_unregister_info@libnl_3 3.5.0-1 + rtnl_link_unset_flags@Base 3.5.0-1 + rtnl_link_unset_flags@libnl_3 3.5.0-1 + rtnl_link_unset_vf_list@libnl_3_2_29 3.5.0-1 + rtnl_link_veth_add@Base 3.5.0-1 + rtnl_link_veth_add@libnl_3 3.5.0-1 + rtnl_link_veth_alloc@Base 3.5.0-1 + rtnl_link_veth_alloc@libnl_3 3.5.0-1 + rtnl_link_veth_get_peer@Base 3.5.0-1 + rtnl_link_veth_get_peer@libnl_3 3.5.0-1 + rtnl_link_veth_release@Base 3.5.0-1 + rtnl_link_veth_release@libnl_3 3.5.0-1 + rtnl_link_vf_add@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_alloc@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_free@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_addr@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_index@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_linkstate@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_rate@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_rss_query_en@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_spoofchk@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_stat@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_trust@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_vlans@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_linkstate2str@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_put@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_addr@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_ib_node_guid@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_ib_port_guid@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_index@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_linkstate@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_rate@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_rss_query_en@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_spoofchk@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_trust@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_vlans@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_str2guid@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_str2linkstate@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_str2vlanproto@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_vlan_alloc@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_vlan_free@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_vlan_put@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_vlanproto2str@libnl_3_2_29 3.5.0-1 + rtnl_link_vlan_alloc@Base 3.5.0-1 + rtnl_link_vlan_alloc@libnl_3 3.5.0-1 + rtnl_link_vlan_flags2str@Base 3.5.0-1 + rtnl_link_vlan_flags2str@libnl_3 3.5.0-1 + rtnl_link_vlan_get_egress_map@Base 3.5.0-1 + rtnl_link_vlan_get_egress_map@libnl_3 3.5.0-1 + rtnl_link_vlan_get_flags@Base 3.5.0-1 + rtnl_link_vlan_get_flags@libnl_3 3.5.0-1 + rtnl_link_vlan_get_id@Base 3.5.0-1 + rtnl_link_vlan_get_id@libnl_3 3.5.0-1 + rtnl_link_vlan_get_ingress_map@Base 3.5.0-1 + rtnl_link_vlan_get_ingress_map@libnl_3 3.5.0-1 + rtnl_link_vlan_get_protocol@Base 3.5.0-1 + rtnl_link_vlan_get_protocol@libnl_3 3.5.0-1 + rtnl_link_vlan_set_egress_map@Base 3.5.0-1 + rtnl_link_vlan_set_egress_map@libnl_3 3.5.0-1 + rtnl_link_vlan_set_flags@Base 3.5.0-1 + rtnl_link_vlan_set_flags@libnl_3 3.5.0-1 + rtnl_link_vlan_set_id@Base 3.5.0-1 + rtnl_link_vlan_set_id@libnl_3 3.5.0-1 + rtnl_link_vlan_set_ingress_map@Base 3.5.0-1 + rtnl_link_vlan_set_ingress_map@libnl_3 3.5.0-1 + rtnl_link_vlan_set_protocol@Base 3.5.0-1 + rtnl_link_vlan_set_protocol@libnl_3 3.5.0-1 + rtnl_link_vlan_str2flags@Base 3.5.0-1 + rtnl_link_vlan_str2flags@libnl_3 3.5.0-1 + rtnl_link_vlan_unset_flags@Base 3.5.0-1 + rtnl_link_vlan_unset_flags@libnl_3 3.5.0-1 + rtnl_link_vrf_alloc@libnl_3_2_28 3.5.0-1 + rtnl_link_vrf_get_tableid@libnl_3_2_28 3.5.0-1 + rtnl_link_vrf_set_tableid@libnl_3_2_28 3.5.0-1 + rtnl_link_vxlan_alloc@Base 3.5.0-1 + rtnl_link_vxlan_alloc@libnl_3 3.5.0-1 + rtnl_link_vxlan_disable_l2miss@Base 3.5.0-1 + rtnl_link_vxlan_disable_l2miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_disable_l3miss@Base 3.5.0-1 + rtnl_link_vxlan_disable_l3miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_disable_learning@Base 3.5.0-1 + rtnl_link_vxlan_disable_learning@libnl_3 3.5.0-1 + rtnl_link_vxlan_disable_proxy@Base 3.5.0-1 + rtnl_link_vxlan_disable_proxy@libnl_3 3.5.0-1 + rtnl_link_vxlan_disable_rsc@Base 3.5.0-1 + rtnl_link_vxlan_disable_rsc@libnl_3 3.5.0-1 + rtnl_link_vxlan_enable_l2miss@Base 3.5.0-1 + rtnl_link_vxlan_enable_l2miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_enable_l3miss@Base 3.5.0-1 + rtnl_link_vxlan_enable_l3miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_enable_learning@Base 3.5.0-1 + rtnl_link_vxlan_enable_learning@libnl_3 3.5.0-1 + rtnl_link_vxlan_enable_proxy@Base 3.5.0-1 + rtnl_link_vxlan_enable_proxy@libnl_3 3.5.0-1 + rtnl_link_vxlan_enable_rsc@Base 3.5.0-1 + rtnl_link_vxlan_enable_rsc@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_ageing@Base 3.5.0-1 + rtnl_link_vxlan_get_ageing@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_collect_metadata@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_flags@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_group@Base 3.5.0-1 + rtnl_link_vxlan_get_group@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_id@Base 3.5.0-1 + rtnl_link_vxlan_get_id@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_l2miss@Base 3.5.0-1 + rtnl_link_vxlan_get_l2miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_l3miss@Base 3.5.0-1 + rtnl_link_vxlan_get_l3miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_label@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_learning@Base 3.5.0-1 + rtnl_link_vxlan_get_learning@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_limit@Base 3.5.0-1 + rtnl_link_vxlan_get_limit@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_link@Base 3.5.0-1 + rtnl_link_vxlan_get_link@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_local@Base 3.5.0-1 + rtnl_link_vxlan_get_local@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_port@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_port_range@Base 3.5.0-1 + rtnl_link_vxlan_get_port_range@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_proxy@Base 3.5.0-1 + rtnl_link_vxlan_get_proxy@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_remcsum_rx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_remcsum_tx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_rsc@Base 3.5.0-1 + rtnl_link_vxlan_get_rsc@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_tos@Base 3.5.0-1 + rtnl_link_vxlan_get_tos@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_ttl@Base 3.5.0-1 + rtnl_link_vxlan_get_ttl@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_udp_csum@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_udp_zero_csum6_rx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_udp_zero_csum6_tx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_ageing@Base 3.5.0-1 + rtnl_link_vxlan_set_ageing@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_collect_metadata@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_flags@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_group@Base 3.5.0-1 + rtnl_link_vxlan_set_group@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_id@Base 3.5.0-1 + rtnl_link_vxlan_set_id@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_l2miss@Base 3.5.0-1 + rtnl_link_vxlan_set_l2miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_l3miss@Base 3.5.0-1 + rtnl_link_vxlan_set_l3miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_label@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_learning@Base 3.5.0-1 + rtnl_link_vxlan_set_learning@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_limit@Base 3.5.0-1 + rtnl_link_vxlan_set_limit@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_link@Base 3.5.0-1 + rtnl_link_vxlan_set_link@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_local@Base 3.5.0-1 + rtnl_link_vxlan_set_local@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_port@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_port_range@Base 3.5.0-1 + rtnl_link_vxlan_set_port_range@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_proxy@Base 3.5.0-1 + rtnl_link_vxlan_set_proxy@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_remcsum_rx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_remcsum_tx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_rsc@Base 3.5.0-1 + rtnl_link_vxlan_set_rsc@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_tos@Base 3.5.0-1 + rtnl_link_vxlan_set_tos@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_ttl@Base 3.5.0-1 + rtnl_link_vxlan_set_ttl@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_udp_csum@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_udp_zero_csum6_rx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_udp_zero_csum6_tx@libnl_3_2_29 3.5.0-1 + rtnl_link_xfrmi_alloc@libnl_3_5 3.5.0-1 + rtnl_link_xfrmi_get_if_id@libnl_3_5 3.5.0-1 + rtnl_link_xfrmi_get_link@libnl_3_5 3.5.0-1 + rtnl_link_xfrmi_set_if_id@libnl_3_5 3.5.0-1 + rtnl_link_xfrmi_set_link@libnl_3_5 3.5.0-1 + rtnl_mall_append_action@libnl_3_5 3.5.0-1 + rtnl_mall_del_action@libnl_3_5 3.5.0-1 + rtnl_mall_get_classid@libnl_3_5 3.5.0-1 + rtnl_mall_get_first_action@libnl_3_5 3.5.0-1 + rtnl_mall_get_flags@libnl_3_5 3.5.0-1 + rtnl_mall_set_classid@libnl_3_5 3.5.0-1 + rtnl_mall_set_flags@libnl_3_5 3.5.0-1 + rtnl_meta_value_alloc_id@Base 3.5.0-1 + rtnl_meta_value_alloc_id@libnl_3 3.5.0-1 + rtnl_meta_value_alloc_int@Base 3.5.0-1 + rtnl_meta_value_alloc_int@libnl_3 3.5.0-1 + rtnl_meta_value_alloc_var@Base 3.5.0-1 + rtnl_meta_value_alloc_var@libnl_3 3.5.0-1 + rtnl_meta_value_put@Base 3.5.0-1 + rtnl_meta_value_put@libnl_3 3.5.0-1 + rtnl_mirred_get_action@Base 3.5.0-1 + rtnl_mirred_get_action@libnl_3 3.5.0-1 + rtnl_mirred_get_ifindex@Base 3.5.0-1 + rtnl_mirred_get_ifindex@libnl_3 3.5.0-1 + rtnl_mirred_get_policy@Base 3.5.0-1 + rtnl_mirred_get_policy@libnl_3 3.5.0-1 + rtnl_mirred_set_action@Base 3.5.0-1 + rtnl_mirred_set_action@libnl_3 3.5.0-1 + rtnl_mirred_set_ifindex@Base 3.5.0-1 + rtnl_mirred_set_ifindex@libnl_3 3.5.0-1 + rtnl_mirred_set_policy@Base 3.5.0-1 + rtnl_mirred_set_policy@libnl_3 3.5.0-1 + rtnl_neigh_add@Base 3.5.0-1 + rtnl_neigh_add@libnl_3 3.5.0-1 + rtnl_neigh_alloc@Base 3.5.0-1 + rtnl_neigh_alloc@libnl_3 3.5.0-1 + rtnl_neigh_alloc_cache@Base 3.5.0-1 + rtnl_neigh_alloc_cache@libnl_3 3.5.0-1 + rtnl_neigh_alloc_cache_flags@libnl_3_2_28 3.5.0-1 + rtnl_neigh_build_add_request@Base 3.5.0-1 + rtnl_neigh_build_add_request@libnl_3 3.5.0-1 + rtnl_neigh_build_delete_request@Base 3.5.0-1 + rtnl_neigh_build_delete_request@libnl_3 3.5.0-1 + rtnl_neigh_delete@Base 3.5.0-1 + rtnl_neigh_delete@libnl_3 3.5.0-1 + rtnl_neigh_flags2str@Base 3.5.0-1 + rtnl_neigh_flags2str@libnl_3 3.5.0-1 + rtnl_neigh_get@Base 3.5.0-1 + rtnl_neigh_get@libnl_3 3.5.0-1 + rtnl_neigh_get_by_vlan@libnl_3_5 3.5.0-1 + rtnl_neigh_get_dst@Base 3.5.0-1 + rtnl_neigh_get_dst@libnl_3 3.5.0-1 + rtnl_neigh_get_family@Base 3.5.0-1 + rtnl_neigh_get_family@libnl_3 3.5.0-1 + rtnl_neigh_get_flags@Base 3.5.0-1 + rtnl_neigh_get_flags@libnl_3 3.5.0-1 + rtnl_neigh_get_ifindex@Base 3.5.0-1 + rtnl_neigh_get_ifindex@libnl_3 3.5.0-1 + rtnl_neigh_get_lladdr@Base 3.5.0-1 + rtnl_neigh_get_lladdr@libnl_3 3.5.0-1 + rtnl_neigh_get_master@libnl_3_5 3.5.0-1 + rtnl_neigh_get_state@Base 3.5.0-1 + rtnl_neigh_get_state@libnl_3 3.5.0-1 + rtnl_neigh_get_type@Base 3.5.0-1 + rtnl_neigh_get_type@libnl_3 3.5.0-1 + rtnl_neigh_get_vlan@Base 3.5.0-1 + rtnl_neigh_get_vlan@libnl_3_2_26 3.5.0-1 + rtnl_neigh_parse@Base 3.5.0-1 + rtnl_neigh_parse@libnl_3 3.5.0-1 + rtnl_neigh_put@Base 3.5.0-1 + rtnl_neigh_put@libnl_3 3.5.0-1 + rtnl_neigh_set_dst@Base 3.5.0-1 + rtnl_neigh_set_dst@libnl_3 3.5.0-1 + rtnl_neigh_set_family@Base 3.5.0-1 + rtnl_neigh_set_family@libnl_3 3.5.0-1 + rtnl_neigh_set_flags@Base 3.5.0-1 + rtnl_neigh_set_flags@libnl_3 3.5.0-1 + rtnl_neigh_set_ifindex@Base 3.5.0-1 + rtnl_neigh_set_ifindex@libnl_3 3.5.0-1 + rtnl_neigh_set_lladdr@Base 3.5.0-1 + rtnl_neigh_set_lladdr@libnl_3 3.5.0-1 + rtnl_neigh_set_master@libnl_3_5 3.5.0-1 + rtnl_neigh_set_state@Base 3.5.0-1 + rtnl_neigh_set_state@libnl_3 3.5.0-1 + rtnl_neigh_set_type@Base 3.5.0-1 + rtnl_neigh_set_type@libnl_3 3.5.0-1 + rtnl_neigh_set_vlan@Base 3.5.0-1 + rtnl_neigh_set_vlan@libnl_3_2_26 3.5.0-1 + rtnl_neigh_state2str@Base 3.5.0-1 + rtnl_neigh_state2str@libnl_3 3.5.0-1 + rtnl_neigh_str2flag@Base 3.5.0-1 + rtnl_neigh_str2flag@libnl_3 3.5.0-1 + rtnl_neigh_str2state@Base 3.5.0-1 + rtnl_neigh_str2state@libnl_3 3.5.0-1 + rtnl_neigh_unset_flags@Base 3.5.0-1 + rtnl_neigh_unset_flags@libnl_3 3.5.0-1 + rtnl_neigh_unset_state@Base 3.5.0-1 + rtnl_neigh_unset_state@libnl_3 3.5.0-1 + rtnl_neightbl_alloc@Base 3.5.0-1 + rtnl_neightbl_alloc@libnl_3 3.5.0-1 + rtnl_neightbl_alloc_cache@Base 3.5.0-1 + rtnl_neightbl_alloc_cache@libnl_3 3.5.0-1 + rtnl_neightbl_build_change_request@Base 3.5.0-1 + rtnl_neightbl_build_change_request@libnl_3 3.5.0-1 + rtnl_neightbl_change@Base 3.5.0-1 + rtnl_neightbl_change@libnl_3 3.5.0-1 + rtnl_neightbl_get@Base 3.5.0-1 + rtnl_neightbl_get@libnl_3 3.5.0-1 + rtnl_neightbl_put@Base 3.5.0-1 + rtnl_neightbl_put@libnl_3 3.5.0-1 + rtnl_neightbl_set_anycast_delay@Base 3.5.0-1 + rtnl_neightbl_set_anycast_delay@libnl_3 3.5.0-1 + rtnl_neightbl_set_app_probes@Base 3.5.0-1 + rtnl_neightbl_set_app_probes@libnl_3 3.5.0-1 + rtnl_neightbl_set_base_reachable_time@Base 3.5.0-1 + rtnl_neightbl_set_base_reachable_time@libnl_3 3.5.0-1 + rtnl_neightbl_set_delay_probe_time@Base 3.5.0-1 + rtnl_neightbl_set_delay_probe_time@libnl_3 3.5.0-1 + rtnl_neightbl_set_dev@Base 3.5.0-1 + rtnl_neightbl_set_dev@libnl_3 3.5.0-1 + rtnl_neightbl_set_family@Base 3.5.0-1 + rtnl_neightbl_set_family@libnl_3 3.5.0-1 + rtnl_neightbl_set_gc_interval@Base 3.5.0-1 + rtnl_neightbl_set_gc_interval@libnl_3 3.5.0-1 + rtnl_neightbl_set_gc_stale_time@Base 3.5.0-1 + rtnl_neightbl_set_gc_stale_time@libnl_3 3.5.0-1 + rtnl_neightbl_set_gc_tresh1@Base 3.5.0-1 + rtnl_neightbl_set_gc_tresh1@libnl_3 3.5.0-1 + rtnl_neightbl_set_gc_tresh2@Base 3.5.0-1 + rtnl_neightbl_set_gc_tresh2@libnl_3 3.5.0-1 + rtnl_neightbl_set_gc_tresh3@Base 3.5.0-1 + rtnl_neightbl_set_gc_tresh3@libnl_3 3.5.0-1 + rtnl_neightbl_set_locktime@Base 3.5.0-1 + rtnl_neightbl_set_locktime@libnl_3 3.5.0-1 + rtnl_neightbl_set_mcast_probes@Base 3.5.0-1 + rtnl_neightbl_set_mcast_probes@libnl_3 3.5.0-1 + rtnl_neightbl_set_name@Base 3.5.0-1 + rtnl_neightbl_set_name@libnl_3 3.5.0-1 + rtnl_neightbl_set_proxy_delay@Base 3.5.0-1 + rtnl_neightbl_set_proxy_delay@libnl_3 3.5.0-1 + rtnl_neightbl_set_proxy_queue_len@Base 3.5.0-1 + rtnl_neightbl_set_proxy_queue_len@libnl_3 3.5.0-1 + rtnl_neightbl_set_queue_len@Base 3.5.0-1 + rtnl_neightbl_set_queue_len@libnl_3 3.5.0-1 + rtnl_neightbl_set_retrans_time@Base 3.5.0-1 + rtnl_neightbl_set_retrans_time@libnl_3 3.5.0-1 + rtnl_neightbl_set_ucast_probes@Base 3.5.0-1 + rtnl_neightbl_set_ucast_probes@libnl_3 3.5.0-1 + rtnl_netconf_get_all@libnl_3_4 3.5.0-1 + rtnl_netconf_get_by_idx@libnl_3_4 3.5.0-1 + rtnl_netconf_get_default@libnl_3_4 3.5.0-1 + rtnl_netconf_get_family@libnl_3_4 3.5.0-1 + rtnl_netconf_get_forwarding@libnl_3_4 3.5.0-1 + rtnl_netconf_get_ifindex@libnl_3_4 3.5.0-1 + rtnl_netconf_get_input@libnl_3_4 3.5.0-1 + rtnl_netconf_get_mc_forwarding@libnl_3_4 3.5.0-1 + rtnl_netconf_get_rp_filter@libnl_3_4 3.5.0-1 + rtnl_netconf_put@libnl_3_4 3.5.0-1 + rtnl_netem_get_corruption_correlation@Base 3.5.0-1 + rtnl_netem_get_corruption_correlation@libnl_3 3.5.0-1 + rtnl_netem_get_corruption_probability@Base 3.5.0-1 + rtnl_netem_get_corruption_probability@libnl_3 3.5.0-1 + rtnl_netem_get_delay@Base 3.5.0-1 + rtnl_netem_get_delay@libnl_3 3.5.0-1 + rtnl_netem_get_delay_correlation@Base 3.5.0-1 + rtnl_netem_get_delay_correlation@libnl_3 3.5.0-1 + rtnl_netem_get_delay_distribution@Base 3.5.0-1 + rtnl_netem_get_delay_distribution@libnl_3 3.5.0-1 + rtnl_netem_get_delay_distribution_size@Base 3.5.0-1 + rtnl_netem_get_delay_distribution_size@libnl_3 3.5.0-1 + rtnl_netem_get_duplicate@Base 3.5.0-1 + rtnl_netem_get_duplicate@libnl_3 3.5.0-1 + rtnl_netem_get_duplicate_correlation@Base 3.5.0-1 + rtnl_netem_get_duplicate_correlation@libnl_3 3.5.0-1 + rtnl_netem_get_gap@Base 3.5.0-1 + rtnl_netem_get_gap@libnl_3 3.5.0-1 + rtnl_netem_get_jitter@Base 3.5.0-1 + rtnl_netem_get_jitter@libnl_3 3.5.0-1 + rtnl_netem_get_limit@Base 3.5.0-1 + rtnl_netem_get_limit@libnl_3 3.5.0-1 + rtnl_netem_get_loss@Base 3.5.0-1 + rtnl_netem_get_loss@libnl_3 3.5.0-1 + rtnl_netem_get_loss_correlation@Base 3.5.0-1 + rtnl_netem_get_loss_correlation@libnl_3 3.5.0-1 + rtnl_netem_get_reorder_correlation@Base 3.5.0-1 + rtnl_netem_get_reorder_correlation@libnl_3 3.5.0-1 + rtnl_netem_get_reorder_probability@Base 3.5.0-1 + rtnl_netem_get_reorder_probability@libnl_3 3.5.0-1 + rtnl_netem_set_corruption_correlation@Base 3.5.0-1 + rtnl_netem_set_corruption_correlation@libnl_3 3.5.0-1 + rtnl_netem_set_corruption_probability@Base 3.5.0-1 + rtnl_netem_set_corruption_probability@libnl_3 3.5.0-1 + rtnl_netem_set_delay@Base 3.5.0-1 + rtnl_netem_set_delay@libnl_3 3.5.0-1 + rtnl_netem_set_delay_correlation@Base 3.5.0-1 + rtnl_netem_set_delay_correlation@libnl_3 3.5.0-1 + rtnl_netem_set_delay_distribution@Base 3.5.0-1 + rtnl_netem_set_delay_distribution@libnl_3 3.5.0-1 + rtnl_netem_set_delay_distribution_data@libnl_3_5 3.5.0-1 + rtnl_netem_set_duplicate@Base 3.5.0-1 + rtnl_netem_set_duplicate@libnl_3 3.5.0-1 + rtnl_netem_set_duplicate_correlation@Base 3.5.0-1 + rtnl_netem_set_duplicate_correlation@libnl_3 3.5.0-1 + rtnl_netem_set_gap@Base 3.5.0-1 + rtnl_netem_set_gap@libnl_3 3.5.0-1 + rtnl_netem_set_jitter@Base 3.5.0-1 + rtnl_netem_set_jitter@libnl_3 3.5.0-1 + rtnl_netem_set_limit@Base 3.5.0-1 + rtnl_netem_set_limit@libnl_3 3.5.0-1 + rtnl_netem_set_loss@Base 3.5.0-1 + rtnl_netem_set_loss@libnl_3 3.5.0-1 + rtnl_netem_set_loss_correlation@Base 3.5.0-1 + rtnl_netem_set_loss_correlation@libnl_3 3.5.0-1 + rtnl_netem_set_reorder_correlation@Base 3.5.0-1 + rtnl_netem_set_reorder_correlation@libnl_3 3.5.0-1 + rtnl_netem_set_reorder_probability@Base 3.5.0-1 + rtnl_netem_set_reorder_probability@libnl_3 3.5.0-1 + rtnl_pktloc_add@Base 3.5.0-1 + rtnl_pktloc_add@libnl_3 3.5.0-1 + rtnl_pktloc_alloc@Base 3.5.0-1 + rtnl_pktloc_alloc@libnl_3 3.5.0-1 + rtnl_pktloc_foreach@Base 3.5.0-1 + rtnl_pktloc_foreach@libnl_3 3.5.0-1 + rtnl_pktloc_lookup@Base 3.5.0-1 + rtnl_pktloc_lookup@libnl_3 3.5.0-1 + rtnl_pktloc_put@Base 3.5.0-1 + rtnl_pktloc_put@libnl_3 3.5.0-1 + rtnl_prio2str@Base 3.5.0-1 + rtnl_prio2str@libnl_3 3.5.0-1 + rtnl_qdisc_add@Base 3.5.0-1 + rtnl_qdisc_add@libnl_3 3.5.0-1 + rtnl_qdisc_alloc@Base 3.5.0-1 + rtnl_qdisc_alloc@libnl_3 3.5.0-1 + rtnl_qdisc_alloc_cache@Base 3.5.0-1 + rtnl_qdisc_alloc_cache@libnl_3 3.5.0-1 + rtnl_qdisc_build_add_request@Base 3.5.0-1 + rtnl_qdisc_build_add_request@libnl_3 3.5.0-1 + rtnl_qdisc_build_change_request@Base 3.5.0-1 + rtnl_qdisc_build_change_request@libnl_3 3.5.0-1 + rtnl_qdisc_build_delete_request@Base 3.5.0-1 + rtnl_qdisc_build_delete_request@libnl_3 3.5.0-1 + rtnl_qdisc_build_update_request@Base 3.5.0-1 + rtnl_qdisc_build_update_request@libnl_3 3.5.0-1 + rtnl_qdisc_change@Base 3.5.0-1 + rtnl_qdisc_change@libnl_3 3.5.0-1 + rtnl_qdisc_delete@Base 3.5.0-1 + rtnl_qdisc_delete@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_get_default_index@Base 3.5.0-1 + rtnl_qdisc_dsmark_get_default_index@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_get_indices@Base 3.5.0-1 + rtnl_qdisc_dsmark_get_indices@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_get_set_tc_index@Base 3.5.0-1 + rtnl_qdisc_dsmark_get_set_tc_index@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_set_default_index@Base 3.5.0-1 + rtnl_qdisc_dsmark_set_default_index@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_set_indices@Base 3.5.0-1 + rtnl_qdisc_dsmark_set_indices@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_set_set_tc_index@Base 3.5.0-1 + rtnl_qdisc_dsmark_set_set_tc_index@libnl_3 3.5.0-1 + rtnl_qdisc_fifo_get_limit@Base 3.5.0-1 + rtnl_qdisc_fifo_get_limit@libnl_3 3.5.0-1 + rtnl_qdisc_fifo_set_limit@Base 3.5.0-1 + rtnl_qdisc_fifo_set_limit@libnl_3 3.5.0-1 + rtnl_qdisc_foreach_child@Base 3.5.0-1 + rtnl_qdisc_foreach_child@libnl_3 3.5.0-1 + rtnl_qdisc_foreach_cls@Base 3.5.0-1 + rtnl_qdisc_foreach_cls@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_ecn@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_ecn@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_flows@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_flows@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_interval@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_interval@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_limit@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_limit@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_quantum@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_quantum@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_target@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_target@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_ecn@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_ecn@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_flows@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_flows@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_interval@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_interval@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_limit@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_limit@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_quantum@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_quantum@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_target@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_target@libnl_3 3.5.0-1 + rtnl_qdisc_get@Base 3.5.0-1 + rtnl_qdisc_get@libnl_3 3.5.0-1 + rtnl_qdisc_get_by_parent@Base 3.5.0-1 + rtnl_qdisc_get_by_parent@libnl_3 3.5.0-1 + rtnl_qdisc_hfsc_get_defcls@Base 3.5.0-1 + rtnl_qdisc_hfsc_get_defcls@libnl_3 3.5.0-1 + rtnl_qdisc_hfsc_set_defcls@Base 3.5.0-1 + rtnl_qdisc_hfsc_set_defcls@libnl_3 3.5.0-1 + rtnl_qdisc_mqprio_get_hw_offload@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_max_rate@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_min_rate@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_mode@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_num_tc@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_priomap@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_queue@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_shaper@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_hw_offload@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_max_rate@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_min_rate@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_mode@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_num_tc@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_priomap@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_queue@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_shaper@libnl_3_5 3.5.0-1 + rtnl_qdisc_plug_buffer@Base 3.5.0-1 + rtnl_qdisc_plug_buffer@libnl_3 3.5.0-1 + rtnl_qdisc_plug_release_indefinite@Base 3.5.0-1 + rtnl_qdisc_plug_release_indefinite@libnl_3 3.5.0-1 + rtnl_qdisc_plug_release_one@Base 3.5.0-1 + rtnl_qdisc_plug_release_one@libnl_3 3.5.0-1 + rtnl_qdisc_plug_set_limit@Base 3.5.0-1 + rtnl_qdisc_plug_set_limit@libnl_3 3.5.0-1 + rtnl_qdisc_prio_get_bands@Base 3.5.0-1 + rtnl_qdisc_prio_get_bands@libnl_3 3.5.0-1 + rtnl_qdisc_prio_get_priomap@Base 3.5.0-1 + rtnl_qdisc_prio_get_priomap@libnl_3 3.5.0-1 + rtnl_qdisc_prio_set_bands@Base 3.5.0-1 + rtnl_qdisc_prio_set_bands@libnl_3 3.5.0-1 + rtnl_qdisc_prio_set_priomap@Base 3.5.0-1 + rtnl_qdisc_prio_set_priomap@libnl_3 3.5.0-1 + rtnl_qdisc_put@Base 3.5.0-1 + rtnl_qdisc_put@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_limit@Base 3.5.0-1 + rtnl_qdisc_tbf_get_limit@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate@Base 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate_bucket@Base 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate_bucket@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate_cell@Base 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate_cell@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_rate@Base 3.5.0-1 + rtnl_qdisc_tbf_get_rate@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_rate_bucket@Base 3.5.0-1 + rtnl_qdisc_tbf_get_rate_bucket@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_rate_cell@Base 3.5.0-1 + rtnl_qdisc_tbf_get_rate_cell@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_set_limit@Base 3.5.0-1 + rtnl_qdisc_tbf_set_limit@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_set_limit_by_latency@Base 3.5.0-1 + rtnl_qdisc_tbf_set_limit_by_latency@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_set_peakrate@Base 3.5.0-1 + rtnl_qdisc_tbf_set_peakrate@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_set_rate@Base 3.5.0-1 + rtnl_qdisc_tbf_set_rate@libnl_3 3.5.0-1 + rtnl_qdisc_update@Base 3.5.0-1 + rtnl_qdisc_update@libnl_3 3.5.0-1 + rtnl_realms2str@Base 3.5.0-1 + rtnl_realms2str@libnl_3 3.5.0-1 + rtnl_red_get_limit@Base 3.5.0-1 + rtnl_red_get_limit@libnl_3 3.5.0-1 + rtnl_red_set_limit@Base 3.5.0-1 + rtnl_red_set_limit@libnl_3 3.5.0-1 + rtnl_route_add@Base 3.5.0-1 + rtnl_route_add@libnl_3 3.5.0-1 + rtnl_route_add_nexthop@Base 3.5.0-1 + rtnl_route_add_nexthop@libnl_3 3.5.0-1 + rtnl_route_alloc@Base 3.5.0-1 + rtnl_route_alloc@libnl_3 3.5.0-1 + rtnl_route_alloc_cache@Base 3.5.0-1 + rtnl_route_alloc_cache@libnl_3 3.5.0-1 + rtnl_route_build_add_request@Base 3.5.0-1 + rtnl_route_build_add_request@libnl_3 3.5.0-1 + rtnl_route_build_del_request@Base 3.5.0-1 + rtnl_route_build_del_request@libnl_3 3.5.0-1 + rtnl_route_build_msg@Base 3.5.0-1 + rtnl_route_build_msg@libnl_3 3.5.0-1 + rtnl_route_delete@Base 3.5.0-1 + rtnl_route_delete@libnl_3 3.5.0-1 + rtnl_route_foreach_nexthop@Base 3.5.0-1 + rtnl_route_foreach_nexthop@libnl_3 3.5.0-1 + rtnl_route_get@Base 3.5.0-1 + rtnl_route_get@libnl_3 3.5.0-1 + rtnl_route_get_dst@Base 3.5.0-1 + rtnl_route_get_dst@libnl_3 3.5.0-1 + rtnl_route_get_family@Base 3.5.0-1 + rtnl_route_get_family@libnl_3 3.5.0-1 + rtnl_route_get_flags@Base 3.5.0-1 + rtnl_route_get_flags@libnl_3 3.5.0-1 + rtnl_route_get_iif@Base 3.5.0-1 + rtnl_route_get_iif@libnl_3 3.5.0-1 + rtnl_route_get_metric@Base 3.5.0-1 + rtnl_route_get_metric@libnl_3 3.5.0-1 + rtnl_route_get_nexthops@Base 3.5.0-1 + rtnl_route_get_nexthops@libnl_3 3.5.0-1 + rtnl_route_get_nnexthops@Base 3.5.0-1 + rtnl_route_get_nnexthops@libnl_3 3.5.0-1 + rtnl_route_get_pref_src@Base 3.5.0-1 + rtnl_route_get_pref_src@libnl_3 3.5.0-1 + rtnl_route_get_priority@Base 3.5.0-1 + rtnl_route_get_priority@libnl_3 3.5.0-1 + rtnl_route_get_protocol@Base 3.5.0-1 + rtnl_route_get_protocol@libnl_3 3.5.0-1 + rtnl_route_get_scope@Base 3.5.0-1 + rtnl_route_get_scope@libnl_3 3.5.0-1 + rtnl_route_get_src@Base 3.5.0-1 + rtnl_route_get_src@libnl_3 3.5.0-1 + rtnl_route_get_table@Base 3.5.0-1 + rtnl_route_get_table@libnl_3 3.5.0-1 + rtnl_route_get_tos@Base 3.5.0-1 + rtnl_route_get_tos@libnl_3 3.5.0-1 + rtnl_route_get_ttl_propagate@libnl_3_4 3.5.0-1 + rtnl_route_get_type@Base 3.5.0-1 + rtnl_route_get_type@libnl_3 3.5.0-1 + rtnl_route_guess_scope@Base 3.5.0-1 + rtnl_route_guess_scope@libnl_3 3.5.0-1 + rtnl_route_metric2str@Base 3.5.0-1 + rtnl_route_metric2str@libnl_3 3.5.0-1 + rtnl_route_nexthop_n@Base 3.5.0-1 + rtnl_route_nexthop_n@libnl_3 3.5.0-1 + rtnl_route_nh_alloc@Base 3.5.0-1 + rtnl_route_nh_alloc@libnl_3 3.5.0-1 + rtnl_route_nh_clone@Base 3.5.0-1 + rtnl_route_nh_clone@libnl_3 3.5.0-1 + rtnl_route_nh_compare@Base 3.5.0-1 + rtnl_route_nh_compare@libnl_3 3.5.0-1 + rtnl_route_nh_dump@Base 3.5.0-1 + rtnl_route_nh_dump@libnl_3 3.5.0-1 + rtnl_route_nh_encap_mpls@libnl_3_4 3.5.0-1 + rtnl_route_nh_flags2str@Base 3.5.0-1 + rtnl_route_nh_flags2str@libnl_3 3.5.0-1 + rtnl_route_nh_free@Base 3.5.0-1 + rtnl_route_nh_free@libnl_3 3.5.0-1 + rtnl_route_nh_get_flags@Base 3.5.0-1 + rtnl_route_nh_get_flags@libnl_3 3.5.0-1 + rtnl_route_nh_get_gateway@Base 3.5.0-1 + rtnl_route_nh_get_gateway@libnl_3 3.5.0-1 + rtnl_route_nh_get_ifindex@Base 3.5.0-1 + rtnl_route_nh_get_ifindex@libnl_3 3.5.0-1 + rtnl_route_nh_get_newdst@libnl_3_4 3.5.0-1 + rtnl_route_nh_get_realms@Base 3.5.0-1 + rtnl_route_nh_get_realms@libnl_3 3.5.0-1 + rtnl_route_nh_get_via@libnl_3_4 3.5.0-1 + rtnl_route_nh_get_weight@Base 3.5.0-1 + rtnl_route_nh_get_weight@libnl_3 3.5.0-1 + rtnl_route_nh_set_flags@Base 3.5.0-1 + rtnl_route_nh_set_flags@libnl_3 3.5.0-1 + rtnl_route_nh_set_gateway@Base 3.5.0-1 + rtnl_route_nh_set_gateway@libnl_3 3.5.0-1 + rtnl_route_nh_set_ifindex@Base 3.5.0-1 + rtnl_route_nh_set_ifindex@libnl_3 3.5.0-1 + rtnl_route_nh_set_newdst@libnl_3_4 3.5.0-1 + rtnl_route_nh_set_realms@Base 3.5.0-1 + rtnl_route_nh_set_realms@libnl_3 3.5.0-1 + rtnl_route_nh_set_via@libnl_3_4 3.5.0-1 + rtnl_route_nh_set_weight@Base 3.5.0-1 + rtnl_route_nh_set_weight@libnl_3 3.5.0-1 + rtnl_route_nh_str2flags@Base 3.5.0-1 + rtnl_route_nh_str2flags@libnl_3 3.5.0-1 + rtnl_route_nh_unset_flags@Base 3.5.0-1 + rtnl_route_nh_unset_flags@libnl_3 3.5.0-1 + rtnl_route_parse@Base 3.5.0-1 + rtnl_route_parse@libnl_3 3.5.0-1 + rtnl_route_proto2str@Base 3.5.0-1 + rtnl_route_proto2str@libnl_3 3.5.0-1 + rtnl_route_put@Base 3.5.0-1 + rtnl_route_put@libnl_3 3.5.0-1 + rtnl_route_read_protocol_names@Base 3.5.0-1 + rtnl_route_read_protocol_names@libnl_3 3.5.0-1 + rtnl_route_read_table_names@Base 3.5.0-1 + rtnl_route_read_table_names@libnl_3 3.5.0-1 + rtnl_route_remove_nexthop@Base 3.5.0-1 + rtnl_route_remove_nexthop@libnl_3 3.5.0-1 + rtnl_route_set_dst@Base 3.5.0-1 + rtnl_route_set_dst@libnl_3 3.5.0-1 + rtnl_route_set_family@Base 3.5.0-1 + rtnl_route_set_family@libnl_3 3.5.0-1 + rtnl_route_set_flags@Base 3.5.0-1 + rtnl_route_set_flags@libnl_3 3.5.0-1 + rtnl_route_set_iif@Base 3.5.0-1 + rtnl_route_set_iif@libnl_3 3.5.0-1 + rtnl_route_set_metric@Base 3.5.0-1 + rtnl_route_set_metric@libnl_3 3.5.0-1 + rtnl_route_set_pref_src@Base 3.5.0-1 + rtnl_route_set_pref_src@libnl_3 3.5.0-1 + rtnl_route_set_priority@Base 3.5.0-1 + rtnl_route_set_priority@libnl_3 3.5.0-1 + rtnl_route_set_protocol@Base 3.5.0-1 + rtnl_route_set_protocol@libnl_3 3.5.0-1 + rtnl_route_set_scope@Base 3.5.0-1 + rtnl_route_set_scope@libnl_3 3.5.0-1 + rtnl_route_set_src@Base 3.5.0-1 + rtnl_route_set_src@libnl_3 3.5.0-1 + rtnl_route_set_table@Base 3.5.0-1 + rtnl_route_set_table@libnl_3 3.5.0-1 + rtnl_route_set_tos@Base 3.5.0-1 + rtnl_route_set_tos@libnl_3 3.5.0-1 + rtnl_route_set_ttl_propagate@libnl_3_4 3.5.0-1 + rtnl_route_set_type@Base 3.5.0-1 + rtnl_route_set_type@libnl_3 3.5.0-1 + rtnl_route_str2metric@Base 3.5.0-1 + rtnl_route_str2metric@libnl_3 3.5.0-1 + rtnl_route_str2proto@Base 3.5.0-1 + rtnl_route_str2proto@libnl_3 3.5.0-1 + rtnl_route_str2table@Base 3.5.0-1 + rtnl_route_str2table@libnl_3 3.5.0-1 + rtnl_route_table2str@Base 3.5.0-1 + rtnl_route_table2str@libnl_3 3.5.0-1 + rtnl_route_unset_flags@Base 3.5.0-1 + rtnl_route_unset_flags@libnl_3 3.5.0-1 + rtnl_route_unset_metric@Base 3.5.0-1 + rtnl_route_unset_metric@libnl_3 3.5.0-1 + rtnl_rule_add@Base 3.5.0-1 + rtnl_rule_add@libnl_3 3.5.0-1 + rtnl_rule_alloc@Base 3.5.0-1 + rtnl_rule_alloc@libnl_3 3.5.0-1 + rtnl_rule_alloc_cache@Base 3.5.0-1 + rtnl_rule_alloc_cache@libnl_3 3.5.0-1 + rtnl_rule_build_add_request@Base 3.5.0-1 + rtnl_rule_build_add_request@libnl_3 3.5.0-1 + rtnl_rule_build_delete_request@Base 3.5.0-1 + rtnl_rule_build_delete_request@libnl_3 3.5.0-1 + rtnl_rule_delete@Base 3.5.0-1 + rtnl_rule_delete@libnl_3 3.5.0-1 + rtnl_rule_get_action@Base 3.5.0-1 + rtnl_rule_get_action@libnl_3 3.5.0-1 + rtnl_rule_get_dport@libnl_3_5 3.5.0-1 + rtnl_rule_get_dsfield@Base 3.5.0-1 + rtnl_rule_get_dsfield@libnl_3 3.5.0-1 + rtnl_rule_get_dst@Base 3.5.0-1 + rtnl_rule_get_dst@libnl_3 3.5.0-1 + rtnl_rule_get_family@Base 3.5.0-1 + rtnl_rule_get_family@libnl_3 3.5.0-1 + rtnl_rule_get_goto@Base 3.5.0-1 + rtnl_rule_get_goto@libnl_3 3.5.0-1 + rtnl_rule_get_iif@Base 3.5.0-1 + rtnl_rule_get_iif@libnl_3 3.5.0-1 + rtnl_rule_get_ipproto@libnl_3_5 3.5.0-1 + rtnl_rule_get_l3mdev@libnl_3_4 3.5.0-1 + rtnl_rule_get_mark@Base 3.5.0-1 + rtnl_rule_get_mark@libnl_3 3.5.0-1 + rtnl_rule_get_mask@Base 3.5.0-1 + rtnl_rule_get_mask@libnl_3 3.5.0-1 + rtnl_rule_get_oif@Base 3.5.0-1 + rtnl_rule_get_oif@libnl_3 3.5.0-1 + rtnl_rule_get_prio@Base 3.5.0-1 + rtnl_rule_get_prio@libnl_3 3.5.0-1 + rtnl_rule_get_protocol@libnl_3_5 3.5.0-1 + rtnl_rule_get_realms@Base 3.5.0-1 + rtnl_rule_get_realms@libnl_3 3.5.0-1 + rtnl_rule_get_sport@libnl_3_5 3.5.0-1 + rtnl_rule_get_src@Base 3.5.0-1 + rtnl_rule_get_src@libnl_3 3.5.0-1 + rtnl_rule_get_table@Base 3.5.0-1 + rtnl_rule_get_table@libnl_3 3.5.0-1 + rtnl_rule_put@Base 3.5.0-1 + rtnl_rule_put@libnl_3 3.5.0-1 + rtnl_rule_set_action@Base 3.5.0-1 + rtnl_rule_set_action@libnl_3 3.5.0-1 + rtnl_rule_set_dport@libnl_3_5 3.5.0-1 + rtnl_rule_set_dport_range@libnl_3_5 3.5.0-1 + rtnl_rule_set_dsfield@Base 3.5.0-1 + rtnl_rule_set_dsfield@libnl_3 3.5.0-1 + rtnl_rule_set_dst@Base 3.5.0-1 + rtnl_rule_set_dst@libnl_3 3.5.0-1 + rtnl_rule_set_family@Base 3.5.0-1 + rtnl_rule_set_family@libnl_3 3.5.0-1 + rtnl_rule_set_goto@Base 3.5.0-1 + rtnl_rule_set_goto@libnl_3 3.5.0-1 + rtnl_rule_set_iif@Base 3.5.0-1 + rtnl_rule_set_iif@libnl_3 3.5.0-1 + rtnl_rule_set_ipproto@libnl_3_5 3.5.0-1 + rtnl_rule_set_l3mdev@libnl_3_4 3.5.0-1 + rtnl_rule_set_mark@Base 3.5.0-1 + rtnl_rule_set_mark@libnl_3 3.5.0-1 + rtnl_rule_set_mask@Base 3.5.0-1 + rtnl_rule_set_mask@libnl_3 3.5.0-1 + rtnl_rule_set_oif@Base 3.5.0-1 + rtnl_rule_set_oif@libnl_3 3.5.0-1 + rtnl_rule_set_prio@Base 3.5.0-1 + rtnl_rule_set_prio@libnl_3 3.5.0-1 + rtnl_rule_set_protocol@libnl_3_5 3.5.0-1 + rtnl_rule_set_realms@Base 3.5.0-1 + rtnl_rule_set_realms@libnl_3 3.5.0-1 + rtnl_rule_set_sport@libnl_3_5 3.5.0-1 + rtnl_rule_set_sport_range@libnl_3_5 3.5.0-1 + rtnl_rule_set_src@Base 3.5.0-1 + rtnl_rule_set_src@libnl_3 3.5.0-1 + rtnl_rule_set_table@Base 3.5.0-1 + rtnl_rule_set_table@libnl_3 3.5.0-1 + rtnl_scope2str@Base 3.5.0-1 + rtnl_scope2str@libnl_3 3.5.0-1 + rtnl_sfq_get_divisor@Base 3.5.0-1 + rtnl_sfq_get_divisor@libnl_3 3.5.0-1 + rtnl_sfq_get_limit@Base 3.5.0-1 + rtnl_sfq_get_limit@libnl_3 3.5.0-1 + rtnl_sfq_get_perturb@Base 3.5.0-1 + rtnl_sfq_get_perturb@libnl_3 3.5.0-1 + rtnl_sfq_get_quantum@Base 3.5.0-1 + rtnl_sfq_get_quantum@libnl_3 3.5.0-1 + rtnl_sfq_set_limit@Base 3.5.0-1 + rtnl_sfq_set_limit@libnl_3 3.5.0-1 + rtnl_sfq_set_perturb@Base 3.5.0-1 + rtnl_sfq_set_perturb@libnl_3 3.5.0-1 + rtnl_sfq_set_quantum@Base 3.5.0-1 + rtnl_sfq_set_quantum@libnl_3 3.5.0-1 + rtnl_skbedit_get_action@Base 3.5.0-1 + rtnl_skbedit_get_action@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_get_mark@Base 3.5.0-1 + rtnl_skbedit_get_mark@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_get_priority@Base 3.5.0-1 + rtnl_skbedit_get_priority@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_get_queue_mapping@Base 3.5.0-1 + rtnl_skbedit_get_queue_mapping@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_set_action@Base 3.5.0-1 + rtnl_skbedit_set_action@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_set_mark@Base 3.5.0-1 + rtnl_skbedit_set_mark@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_set_priority@Base 3.5.0-1 + rtnl_skbedit_set_priority@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_set_queue_mapping@Base 3.5.0-1 + rtnl_skbedit_set_queue_mapping@libnl_3_2_26 3.5.0-1 + rtnl_str2prio@Base 3.5.0-1 + rtnl_str2prio@libnl_3 3.5.0-1 + rtnl_str2scope@Base 3.5.0-1 + rtnl_str2scope@libnl_3 3.5.0-1 + rtnl_tc_build_rate_table@Base 3.5.0-1 + rtnl_tc_build_rate_table@libnl_3 3.5.0-1 + rtnl_tc_calc_bufsize@Base 3.5.0-1 + rtnl_tc_calc_bufsize@libnl_3 3.5.0-1 + rtnl_tc_calc_cell_log@Base 3.5.0-1 + rtnl_tc_calc_cell_log@libnl_3 3.5.0-1 + rtnl_tc_calc_txtime@Base 3.5.0-1 + rtnl_tc_calc_txtime@libnl_3 3.5.0-1 + rtnl_tc_clone@Base 3.5.0-1 + rtnl_tc_clone@libnl_3 3.5.0-1 + rtnl_tc_compare@Base 3.5.0-1 + rtnl_tc_compare@libnl_3 3.5.0-1 + rtnl_tc_data@Base 3.5.0-1 + rtnl_tc_data@libnl_3 3.5.0-1 + rtnl_tc_data_check@Base 3.5.0-1 + rtnl_tc_data_check@libnl_3 3.5.0-1 + rtnl_tc_data_peek@Base 3.5.0-1 + rtnl_tc_dump_details@Base 3.5.0-1 + rtnl_tc_dump_details@libnl_3 3.5.0-1 + rtnl_tc_dump_line@Base 3.5.0-1 + rtnl_tc_dump_line@libnl_3 3.5.0-1 + rtnl_tc_dump_stats@Base 3.5.0-1 + rtnl_tc_dump_stats@libnl_3 3.5.0-1 + rtnl_tc_free_data@Base 3.5.0-1 + rtnl_tc_free_data@libnl_3 3.5.0-1 + rtnl_tc_get_chain@libnl_3_5 3.5.0-1 + rtnl_tc_get_handle@Base 3.5.0-1 + rtnl_tc_get_handle@libnl_3 3.5.0-1 + rtnl_tc_get_ifindex@Base 3.5.0-1 + rtnl_tc_get_ifindex@libnl_3 3.5.0-1 + rtnl_tc_get_kind@Base 3.5.0-1 + rtnl_tc_get_kind@libnl_3 3.5.0-1 + rtnl_tc_get_link@Base 3.5.0-1 + rtnl_tc_get_link@libnl_3 3.5.0-1 + rtnl_tc_get_linktype@Base 3.5.0-1 + rtnl_tc_get_linktype@libnl_3 3.5.0-1 + rtnl_tc_get_mpu@Base 3.5.0-1 + rtnl_tc_get_mpu@libnl_3 3.5.0-1 + rtnl_tc_get_mtu@Base 3.5.0-1 + rtnl_tc_get_mtu@libnl_3 3.5.0-1 + rtnl_tc_get_ops@Base 3.5.0-1 + rtnl_tc_get_ops@libnl_3 3.5.0-1 + rtnl_tc_get_overhead@Base 3.5.0-1 + rtnl_tc_get_overhead@libnl_3 3.5.0-1 + rtnl_tc_get_parent@Base 3.5.0-1 + rtnl_tc_get_parent@libnl_3 3.5.0-1 + rtnl_tc_get_stat@Base 3.5.0-1 + rtnl_tc_get_stat@libnl_3 3.5.0-1 + rtnl_tc_handle2str@Base 3.5.0-1 + rtnl_tc_handle2str@libnl_3 3.5.0-1 + rtnl_tc_lookup_ops@Base 3.5.0-1 + rtnl_tc_lookup_ops@libnl_3 3.5.0-1 + rtnl_tc_msg_build@Base 3.5.0-1 + rtnl_tc_msg_build@libnl_3 3.5.0-1 + rtnl_tc_msg_parse@Base 3.5.0-1 + rtnl_tc_msg_parse@libnl_3 3.5.0-1 + rtnl_tc_read_classid_file@Base 3.5.0-1 + rtnl_tc_read_classid_file@libnl_3 3.5.0-1 + rtnl_tc_register@Base 3.5.0-1 + rtnl_tc_register@libnl_3 3.5.0-1 + rtnl_tc_set_chain@libnl_3_5 3.5.0-1 + rtnl_tc_set_handle@Base 3.5.0-1 + rtnl_tc_set_handle@libnl_3 3.5.0-1 + rtnl_tc_set_ifindex@Base 3.5.0-1 + rtnl_tc_set_ifindex@libnl_3 3.5.0-1 + rtnl_tc_set_kind@Base 3.5.0-1 + rtnl_tc_set_kind@libnl_3 3.5.0-1 + rtnl_tc_set_link@Base 3.5.0-1 + rtnl_tc_set_link@libnl_3 3.5.0-1 + rtnl_tc_set_linktype@Base 3.5.0-1 + rtnl_tc_set_linktype@libnl_3 3.5.0-1 + rtnl_tc_set_mpu@Base 3.5.0-1 + rtnl_tc_set_mpu@libnl_3 3.5.0-1 + rtnl_tc_set_mtu@Base 3.5.0-1 + rtnl_tc_set_mtu@libnl_3 3.5.0-1 + rtnl_tc_set_overhead@Base 3.5.0-1 + rtnl_tc_set_overhead@libnl_3 3.5.0-1 + rtnl_tc_set_parent@Base 3.5.0-1 + rtnl_tc_set_parent@libnl_3 3.5.0-1 + rtnl_tc_stat2str@Base 3.5.0-1 + rtnl_tc_stat2str@libnl_3_2_26 3.5.0-1 + rtnl_tc_str2handle@Base 3.5.0-1 + rtnl_tc_str2handle@libnl_3 3.5.0-1 + rtnl_tc_str2stat@Base 3.5.0-1 + rtnl_tc_str2stat@libnl_3_2_26 3.5.0-1 + rtnl_tc_type_register@Base 3.5.0-1 + rtnl_tc_type_register@libnl_3 3.5.0-1 + rtnl_tc_type_unregister@Base 3.5.0-1 + rtnl_tc_type_unregister@libnl_3 3.5.0-1 + rtnl_tc_unregister@Base 3.5.0-1 + rtnl_tc_unregister@libnl_3 3.5.0-1 + rtnl_u32_add_action@Base 3.5.0-1 + rtnl_u32_add_action@libnl_3 3.5.0-1 + rtnl_u32_add_key@Base 3.5.0-1 + rtnl_u32_add_key@libnl_3 3.5.0-1 + rtnl_u32_add_key_in6_addr@Base 3.5.0-1 + rtnl_u32_add_key_in6_addr@libnl_3 3.5.0-1 + rtnl_u32_add_key_in_addr@Base 3.5.0-1 + rtnl_u32_add_key_in_addr@libnl_3 3.5.0-1 + rtnl_u32_add_key_uint16@Base 3.5.0-1 + rtnl_u32_add_key_uint16@libnl_3 3.5.0-1 + rtnl_u32_add_key_uint32@Base 3.5.0-1 + rtnl_u32_add_key_uint32@libnl_3 3.5.0-1 + rtnl_u32_add_key_uint8@Base 3.5.0-1 + rtnl_u32_add_key_uint8@libnl_3 3.5.0-1 + rtnl_u32_add_mark@Base 3.5.0-1 + rtnl_u32_add_mark@libnl_3 3.5.0-1 + rtnl_u32_del_action@Base 3.5.0-1 + rtnl_u32_del_action@libnl_3 3.5.0-1 + rtnl_u32_del_mark@Base 3.5.0-1 + rtnl_u32_del_mark@libnl_3 3.5.0-1 + rtnl_u32_get_action@libnl_3_4 3.5.0-1 + rtnl_u32_get_classid@Base 3.5.0-1 + rtnl_u32_get_classid@libnl_3_2_26 3.5.0-1 + rtnl_u32_get_key@Base 3.5.0-1 + rtnl_u32_get_key@libnl_3 3.5.0-1 + rtnl_u32_set_classid@Base 3.5.0-1 + rtnl_u32_set_classid@libnl_3 3.5.0-1 + rtnl_u32_set_cls_terminal@Base 3.5.0-1 + rtnl_u32_set_cls_terminal@libnl_3 3.5.0-1 + rtnl_u32_set_divisor@Base 3.5.0-1 + rtnl_u32_set_divisor@libnl_3 3.5.0-1 + rtnl_u32_set_flags@Base 3.5.0-1 + rtnl_u32_set_flags@libnl_3 3.5.0-1 + rtnl_u32_set_handle@Base 3.5.0-1 + rtnl_u32_set_handle@libnl_3 3.5.0-1 + rtnl_u32_set_hashmask@Base 3.5.0-1 + rtnl_u32_set_hashmask@libnl_3 3.5.0-1 + rtnl_u32_set_hashtable@Base 3.5.0-1 + rtnl_u32_set_hashtable@libnl_3 3.5.0-1 + rtnl_u32_set_link@Base 3.5.0-1 + rtnl_u32_set_link@libnl_3 3.5.0-1 + rtnl_u32_set_selector@libnl_3_2_29 3.5.0-1 + rtnl_vlan_get_action@libnl_3_5 3.5.0-1 + rtnl_vlan_get_mode@libnl_3_5 3.5.0-1 + rtnl_vlan_get_protocol@libnl_3_5 3.5.0-1 + rtnl_vlan_get_vlan_id@libnl_3_5 3.5.0-1 + rtnl_vlan_get_vlan_prio@libnl_3_5 3.5.0-1 + rtnl_vlan_set_action@libnl_3_5 3.5.0-1 + rtnl_vlan_set_mode@libnl_3_5 3.5.0-1 + rtnl_vlan_set_protocol@libnl_3_5 3.5.0-1 + rtnl_vlan_set_vlan_id@libnl_3_5 3.5.0-1 + rtnl_vlan_set_vlan_prio@libnl_3_5 3.5.0-1 + tc_groups@Base 3.5.0-1 + tca_parse@Base 3.5.0-1 + tca_set_kind@Base 3.5.0-1 diff --git a/src/libnl3/debian/libnl-route-3-dev.install b/src/libnl3/debian/libnl-route-3-dev.install new file mode 100644 index 000000000000..37e248c3ed5b --- /dev/null +++ b/src/libnl3/debian/libnl-route-3-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/*/pkgconfig/libnl-route-3* +debian/tmp/usr/lib/*/libnl-route-3*.so +debian/tmp/usr/lib/*/libnl-route-3*.a diff --git a/src/libnl3/debian/libnl-utils.install b/src/libnl3/debian/libnl-utils.install new file mode 100644 index 000000000000..8ffdce84e93a --- /dev/null +++ b/src/libnl3/debian/libnl-utils.install @@ -0,0 +1 @@ +debian/tmp/usr/bin/* diff --git a/src/libnl3/debian/libnl-utils.manpages b/src/libnl3/debian/libnl-utils.manpages new file mode 100644 index 000000000000..0b2dcacf5b84 --- /dev/null +++ b/src/libnl3/debian/libnl-utils.manpages @@ -0,0 +1 @@ +debian/tmp/usr/share/man/man8/* diff --git a/src/libnl3/debian/libnl-xfrm-3-200.install b/src/libnl3/debian/libnl-xfrm-3-200.install new file mode 100644 index 000000000000..89b2d4e0c9e0 --- /dev/null +++ b/src/libnl3/debian/libnl-xfrm-3-200.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/*/libnl-xfrm-3*.so.* diff --git a/src/libnl3/debian/libnl-xfrm-3-200.symbols b/src/libnl3/debian/libnl-xfrm-3-200.symbols new file mode 100644 index 000000000000..3704a7aa4384 --- /dev/null +++ b/src/libnl3/debian/libnl-xfrm-3-200.symbols @@ -0,0 +1,484 @@ +libnl-xfrm-3.so.200 libnl-xfrm-3-200 #MINVER# + libnl_3@libnl_3 3.5.0-1 + xfrmnl_ae_alloc@Base 3.5.0-1 + xfrmnl_ae_alloc@libnl_3 3.5.0-1 + xfrmnl_ae_build_get_request@Base 3.5.0-1 + xfrmnl_ae_build_get_request@libnl_3 3.5.0-1 + xfrmnl_ae_flags2str@Base 3.5.0-1 + xfrmnl_ae_flags2str@libnl_3 3.5.0-1 + xfrmnl_ae_get_curlifetime@Base 3.5.0-1 + xfrmnl_ae_get_curlifetime@libnl_3 3.5.0-1 + xfrmnl_ae_get_daddr@Base 3.5.0-1 + xfrmnl_ae_get_daddr@libnl_3 3.5.0-1 + xfrmnl_ae_get_family@Base 3.5.0-1 + xfrmnl_ae_get_family@libnl_3 3.5.0-1 + xfrmnl_ae_get_flags@Base 3.5.0-1 + xfrmnl_ae_get_flags@libnl_3 3.5.0-1 + xfrmnl_ae_get_kernel@Base 3.5.0-1 + xfrmnl_ae_get_kernel@libnl_3 3.5.0-1 + xfrmnl_ae_get_mark@Base 3.5.0-1 + xfrmnl_ae_get_mark@libnl_3 3.5.0-1 + xfrmnl_ae_get_proto@Base 3.5.0-1 + xfrmnl_ae_get_proto@libnl_3 3.5.0-1 + xfrmnl_ae_get_replay_maxage@Base 3.5.0-1 + xfrmnl_ae_get_replay_maxage@libnl_3 3.5.0-1 + xfrmnl_ae_get_replay_maxdiff@Base 3.5.0-1 + xfrmnl_ae_get_replay_maxdiff@libnl_3 3.5.0-1 + xfrmnl_ae_get_replay_state@Base 3.5.0-1 + xfrmnl_ae_get_replay_state@libnl_3 3.5.0-1 + xfrmnl_ae_get_replay_state_esn@Base 3.5.0-1 + xfrmnl_ae_get_replay_state_esn@libnl_3 3.5.0-1 + xfrmnl_ae_get_reqid@Base 3.5.0-1 + xfrmnl_ae_get_reqid@libnl_3 3.5.0-1 + xfrmnl_ae_get_saddr@Base 3.5.0-1 + xfrmnl_ae_get_saddr@libnl_3 3.5.0-1 + xfrmnl_ae_get_spi@Base 3.5.0-1 + xfrmnl_ae_get_spi@libnl_3 3.5.0-1 + xfrmnl_ae_parse@Base 3.5.0-1 + xfrmnl_ae_parse@libnl_3 3.5.0-1 + xfrmnl_ae_put@Base 3.5.0-1 + xfrmnl_ae_put@libnl_3 3.5.0-1 + xfrmnl_ae_set@Base 3.5.0-1 + xfrmnl_ae_set@libnl_3 3.5.0-1 + xfrmnl_ae_set_curlifetime@Base 3.5.0-1 + xfrmnl_ae_set_curlifetime@libnl_3 3.5.0-1 + xfrmnl_ae_set_daddr@Base 3.5.0-1 + xfrmnl_ae_set_daddr@libnl_3 3.5.0-1 + xfrmnl_ae_set_family@Base 3.5.0-1 + xfrmnl_ae_set_family@libnl_3 3.5.0-1 + xfrmnl_ae_set_flags@Base 3.5.0-1 + xfrmnl_ae_set_flags@libnl_3 3.5.0-1 + xfrmnl_ae_set_mark@Base 3.5.0-1 + xfrmnl_ae_set_mark@libnl_3 3.5.0-1 + xfrmnl_ae_set_proto@Base 3.5.0-1 + xfrmnl_ae_set_proto@libnl_3 3.5.0-1 + xfrmnl_ae_set_replay_maxage@Base 3.5.0-1 + xfrmnl_ae_set_replay_maxage@libnl_3 3.5.0-1 + xfrmnl_ae_set_replay_maxdiff@Base 3.5.0-1 + xfrmnl_ae_set_replay_maxdiff@libnl_3 3.5.0-1 + xfrmnl_ae_set_replay_state@Base 3.5.0-1 + xfrmnl_ae_set_replay_state@libnl_3 3.5.0-1 + xfrmnl_ae_set_replay_state_esn@Base 3.5.0-1 + xfrmnl_ae_set_replay_state_esn@libnl_3 3.5.0-1 + xfrmnl_ae_set_reqid@Base 3.5.0-1 + xfrmnl_ae_set_reqid@libnl_3 3.5.0-1 + xfrmnl_ae_set_saddr@Base 3.5.0-1 + xfrmnl_ae_set_saddr@libnl_3 3.5.0-1 + xfrmnl_ae_set_spi@Base 3.5.0-1 + xfrmnl_ae_set_spi@libnl_3 3.5.0-1 + xfrmnl_ae_str2flag@Base 3.5.0-1 + xfrmnl_ae_str2flag@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_alloc@Base 3.5.0-1 + xfrmnl_ltime_cfg_alloc@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_clone@Base 3.5.0-1 + xfrmnl_ltime_cfg_clone@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_cmp@Base 3.5.0-1 + xfrmnl_ltime_cfg_cmp@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get@Base 3.5.0-1 + xfrmnl_ltime_cfg_get@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_addexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_addexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_bytelimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_bytelimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_packetlimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_packetlimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_useexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_useexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_addexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_addexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_bytelimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_bytelimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_packetlimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_packetlimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_useexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_useexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_put@Base 3.5.0-1 + xfrmnl_ltime_cfg_put@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_addexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_addexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_bytelimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_bytelimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_packetlimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_packetlimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_useexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_useexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_addexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_addexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_bytelimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_bytelimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_packetlimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_packetlimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_useexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_useexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_shared@Base 3.5.0-1 + xfrmnl_ltime_cfg_shared@libnl_3 3.5.0-1 + xfrmnl_sa_add@Base 3.5.0-1 + xfrmnl_sa_add@libnl_3 3.5.0-1 + xfrmnl_sa_alloc@Base 3.5.0-1 + xfrmnl_sa_alloc@libnl_3 3.5.0-1 + xfrmnl_sa_alloc_cache@Base 3.5.0-1 + xfrmnl_sa_alloc_cache@libnl_3 3.5.0-1 + xfrmnl_sa_build_add_request@Base 3.5.0-1 + xfrmnl_sa_build_add_request@libnl_3 3.5.0-1 + xfrmnl_sa_build_delete_request@Base 3.5.0-1 + xfrmnl_sa_build_delete_request@libnl_3 3.5.0-1 + xfrmnl_sa_build_get_request@Base 3.5.0-1 + xfrmnl_sa_build_get_request@libnl_3 3.5.0-1 + xfrmnl_sa_build_update_request@Base 3.5.0-1 + xfrmnl_sa_build_update_request@libnl_3 3.5.0-1 + xfrmnl_sa_delete@Base 3.5.0-1 + xfrmnl_sa_delete@libnl_3 3.5.0-1 + xfrmnl_sa_flags2str@Base 3.5.0-1 + xfrmnl_sa_flags2str@libnl_3 3.5.0-1 + xfrmnl_sa_get@Base 3.5.0-1 + xfrmnl_sa_get@libnl_3 3.5.0-1 + xfrmnl_sa_get_aead_params@Base 3.5.0-1 + xfrmnl_sa_get_aead_params@libnl_3 3.5.0-1 + xfrmnl_sa_get_auth_params@Base 3.5.0-1 + xfrmnl_sa_get_auth_params@libnl_3 3.5.0-1 + xfrmnl_sa_get_coaddr@Base 3.5.0-1 + xfrmnl_sa_get_coaddr@libnl_3 3.5.0-1 + xfrmnl_sa_get_comp_params@Base 3.5.0-1 + xfrmnl_sa_get_comp_params@libnl_3 3.5.0-1 + xfrmnl_sa_get_crypto_params@Base 3.5.0-1 + xfrmnl_sa_get_crypto_params@libnl_3 3.5.0-1 + xfrmnl_sa_get_curlifetime@Base 3.5.0-1 + xfrmnl_sa_get_curlifetime@libnl_3 3.5.0-1 + xfrmnl_sa_get_daddr@Base 3.5.0-1 + xfrmnl_sa_get_daddr@libnl_3 3.5.0-1 + xfrmnl_sa_get_encap_tmpl@Base 3.5.0-1 + xfrmnl_sa_get_encap_tmpl@libnl_3 3.5.0-1 + xfrmnl_sa_get_family@Base 3.5.0-1 + xfrmnl_sa_get_family@libnl_3 3.5.0-1 + xfrmnl_sa_get_flags@Base 3.5.0-1 + xfrmnl_sa_get_flags@libnl_3 3.5.0-1 + xfrmnl_sa_get_kernel@Base 3.5.0-1 + xfrmnl_sa_get_kernel@libnl_3 3.5.0-1 + xfrmnl_sa_get_lifetime_cfg@Base 3.5.0-1 + xfrmnl_sa_get_lifetime_cfg@libnl_3 3.5.0-1 + xfrmnl_sa_get_mark@Base 3.5.0-1 + xfrmnl_sa_get_mark@libnl_3 3.5.0-1 + xfrmnl_sa_get_mode@Base 3.5.0-1 + xfrmnl_sa_get_mode@libnl_3 3.5.0-1 + xfrmnl_sa_get_proto@Base 3.5.0-1 + xfrmnl_sa_get_proto@libnl_3 3.5.0-1 + xfrmnl_sa_get_replay_maxage@Base 3.5.0-1 + xfrmnl_sa_get_replay_maxage@libnl_3 3.5.0-1 + xfrmnl_sa_get_replay_maxdiff@Base 3.5.0-1 + xfrmnl_sa_get_replay_maxdiff@libnl_3 3.5.0-1 + xfrmnl_sa_get_replay_state@Base 3.5.0-1 + xfrmnl_sa_get_replay_state@libnl_3 3.5.0-1 + xfrmnl_sa_get_replay_state_esn@Base 3.5.0-1 + xfrmnl_sa_get_replay_state_esn@libnl_3 3.5.0-1 + xfrmnl_sa_get_replay_window@Base 3.5.0-1 + xfrmnl_sa_get_replay_window@libnl_3 3.5.0-1 + xfrmnl_sa_get_reqid@Base 3.5.0-1 + xfrmnl_sa_get_reqid@libnl_3 3.5.0-1 + xfrmnl_sa_get_saddr@Base 3.5.0-1 + xfrmnl_sa_get_saddr@libnl_3 3.5.0-1 + xfrmnl_sa_get_sec_ctx@Base 3.5.0-1 + xfrmnl_sa_get_sec_ctx@libnl_3 3.5.0-1 + xfrmnl_sa_get_sel@Base 3.5.0-1 + xfrmnl_sa_get_sel@libnl_3 3.5.0-1 + xfrmnl_sa_get_seq@Base 3.5.0-1 + xfrmnl_sa_get_seq@libnl_3 3.5.0-1 + xfrmnl_sa_get_spi@Base 3.5.0-1 + xfrmnl_sa_get_spi@libnl_3 3.5.0-1 + xfrmnl_sa_get_stats@Base 3.5.0-1 + xfrmnl_sa_get_stats@libnl_3 3.5.0-1 + xfrmnl_sa_get_tfcpad@Base 3.5.0-1 + xfrmnl_sa_get_tfcpad@libnl_3 3.5.0-1 + xfrmnl_sa_is_expiry_reached@Base 3.5.0-1 + xfrmnl_sa_is_expiry_reached@libnl_3 3.5.0-1 + xfrmnl_sa_is_hardexpiry_reached@Base 3.5.0-1 + xfrmnl_sa_is_hardexpiry_reached@libnl_3 3.5.0-1 + xfrmnl_sa_mode2str@Base 3.5.0-1 + xfrmnl_sa_mode2str@libnl_3 3.5.0-1 + xfrmnl_sa_parse@Base 3.5.0-1 + xfrmnl_sa_parse@libnl_3 3.5.0-1 + xfrmnl_sa_put@Base 3.5.0-1 + xfrmnl_sa_put@libnl_3 3.5.0-1 + xfrmnl_sa_set_aead_params@Base 3.5.0-1 + xfrmnl_sa_set_aead_params@libnl_3 3.5.0-1 + xfrmnl_sa_set_auth_params@Base 3.5.0-1 + xfrmnl_sa_set_auth_params@libnl_3 3.5.0-1 + xfrmnl_sa_set_coaddr@Base 3.5.0-1 + xfrmnl_sa_set_coaddr@libnl_3 3.5.0-1 + xfrmnl_sa_set_comp_params@Base 3.5.0-1 + xfrmnl_sa_set_comp_params@libnl_3 3.5.0-1 + xfrmnl_sa_set_crypto_params@Base 3.5.0-1 + xfrmnl_sa_set_crypto_params@libnl_3 3.5.0-1 + xfrmnl_sa_set_daddr@Base 3.5.0-1 + xfrmnl_sa_set_daddr@libnl_3 3.5.0-1 + xfrmnl_sa_set_encap_tmpl@Base 3.5.0-1 + xfrmnl_sa_set_encap_tmpl@libnl_3 3.5.0-1 + xfrmnl_sa_set_family@Base 3.5.0-1 + xfrmnl_sa_set_family@libnl_3 3.5.0-1 + xfrmnl_sa_set_flags@Base 3.5.0-1 + xfrmnl_sa_set_flags@libnl_3 3.5.0-1 + xfrmnl_sa_set_lifetime_cfg@Base 3.5.0-1 + xfrmnl_sa_set_lifetime_cfg@libnl_3 3.5.0-1 + xfrmnl_sa_set_mark@Base 3.5.0-1 + xfrmnl_sa_set_mark@libnl_3 3.5.0-1 + xfrmnl_sa_set_mode@Base 3.5.0-1 + xfrmnl_sa_set_mode@libnl_3 3.5.0-1 + xfrmnl_sa_set_proto@Base 3.5.0-1 + xfrmnl_sa_set_proto@libnl_3 3.5.0-1 + xfrmnl_sa_set_replay_maxage@Base 3.5.0-1 + xfrmnl_sa_set_replay_maxage@libnl_3 3.5.0-1 + xfrmnl_sa_set_replay_maxdiff@Base 3.5.0-1 + xfrmnl_sa_set_replay_maxdiff@libnl_3 3.5.0-1 + xfrmnl_sa_set_replay_state@Base 3.5.0-1 + xfrmnl_sa_set_replay_state@libnl_3 3.5.0-1 + xfrmnl_sa_set_replay_state_esn@Base 3.5.0-1 + xfrmnl_sa_set_replay_state_esn@libnl_3 3.5.0-1 + xfrmnl_sa_set_replay_window@Base 3.5.0-1 + xfrmnl_sa_set_replay_window@libnl_3 3.5.0-1 + xfrmnl_sa_set_reqid@Base 3.5.0-1 + xfrmnl_sa_set_reqid@libnl_3 3.5.0-1 + xfrmnl_sa_set_saddr@Base 3.5.0-1 + xfrmnl_sa_set_saddr@libnl_3 3.5.0-1 + xfrmnl_sa_set_sec_ctx@Base 3.5.0-1 + xfrmnl_sa_set_sec_ctx@libnl_3 3.5.0-1 + xfrmnl_sa_set_sel@Base 3.5.0-1 + xfrmnl_sa_set_sel@libnl_3 3.5.0-1 + xfrmnl_sa_set_spi@Base 3.5.0-1 + xfrmnl_sa_set_spi@libnl_3 3.5.0-1 + xfrmnl_sa_set_tfcpad@Base 3.5.0-1 + xfrmnl_sa_set_tfcpad@libnl_3 3.5.0-1 + xfrmnl_sa_str2flag@Base 3.5.0-1 + xfrmnl_sa_str2flag@libnl_3 3.5.0-1 + xfrmnl_sa_str2mode@Base 3.5.0-1 + xfrmnl_sa_str2mode@libnl_3 3.5.0-1 + xfrmnl_sa_update@Base 3.5.0-1 + xfrmnl_sa_update@libnl_3 3.5.0-1 + xfrmnl_sel_alloc@Base 3.5.0-1 + xfrmnl_sel_alloc@libnl_3 3.5.0-1 + xfrmnl_sel_clone@Base 3.5.0-1 + xfrmnl_sel_clone@libnl_3 3.5.0-1 + xfrmnl_sel_cmp@Base 3.5.0-1 + xfrmnl_sel_cmp@libnl_3 3.5.0-1 + xfrmnl_sel_dump@Base 3.5.0-1 + xfrmnl_sel_dump@libnl_3 3.5.0-1 + xfrmnl_sel_get@Base 3.5.0-1 + xfrmnl_sel_get@libnl_3 3.5.0-1 + xfrmnl_sel_get_daddr@Base 3.5.0-1 + xfrmnl_sel_get_daddr@libnl_3 3.5.0-1 + xfrmnl_sel_get_dport@Base 3.5.0-1 + xfrmnl_sel_get_dport@libnl_3 3.5.0-1 + xfrmnl_sel_get_dportmask@Base 3.5.0-1 + xfrmnl_sel_get_dportmask@libnl_3 3.5.0-1 + xfrmnl_sel_get_family@Base 3.5.0-1 + xfrmnl_sel_get_family@libnl_3 3.5.0-1 + xfrmnl_sel_get_ifindex@Base 3.5.0-1 + xfrmnl_sel_get_ifindex@libnl_3 3.5.0-1 + xfrmnl_sel_get_prefixlen_d@Base 3.5.0-1 + xfrmnl_sel_get_prefixlen_d@libnl_3 3.5.0-1 + xfrmnl_sel_get_prefixlen_s@Base 3.5.0-1 + xfrmnl_sel_get_prefixlen_s@libnl_3 3.5.0-1 + xfrmnl_sel_get_proto@Base 3.5.0-1 + xfrmnl_sel_get_proto@libnl_3 3.5.0-1 + xfrmnl_sel_get_saddr@Base 3.5.0-1 + xfrmnl_sel_get_saddr@libnl_3 3.5.0-1 + xfrmnl_sel_get_sport@Base 3.5.0-1 + xfrmnl_sel_get_sport@libnl_3 3.5.0-1 + xfrmnl_sel_get_sportmask@Base 3.5.0-1 + xfrmnl_sel_get_sportmask@libnl_3 3.5.0-1 + xfrmnl_sel_get_userid@Base 3.5.0-1 + xfrmnl_sel_get_userid@libnl_3 3.5.0-1 + xfrmnl_sel_put@Base 3.5.0-1 + xfrmnl_sel_put@libnl_3 3.5.0-1 + xfrmnl_sel_set_daddr@Base 3.5.0-1 + xfrmnl_sel_set_daddr@libnl_3 3.5.0-1 + xfrmnl_sel_set_dport@Base 3.5.0-1 + xfrmnl_sel_set_dport@libnl_3 3.5.0-1 + xfrmnl_sel_set_dportmask@Base 3.5.0-1 + xfrmnl_sel_set_dportmask@libnl_3 3.5.0-1 + xfrmnl_sel_set_family@Base 3.5.0-1 + xfrmnl_sel_set_family@libnl_3 3.5.0-1 + xfrmnl_sel_set_ifindex@Base 3.5.0-1 + xfrmnl_sel_set_ifindex@libnl_3 3.5.0-1 + xfrmnl_sel_set_prefixlen_d@Base 3.5.0-1 + xfrmnl_sel_set_prefixlen_d@libnl_3 3.5.0-1 + xfrmnl_sel_set_prefixlen_s@Base 3.5.0-1 + xfrmnl_sel_set_prefixlen_s@libnl_3 3.5.0-1 + xfrmnl_sel_set_proto@Base 3.5.0-1 + xfrmnl_sel_set_proto@libnl_3 3.5.0-1 + xfrmnl_sel_set_saddr@Base 3.5.0-1 + xfrmnl_sel_set_saddr@libnl_3 3.5.0-1 + xfrmnl_sel_set_sport@Base 3.5.0-1 + xfrmnl_sel_set_sport@libnl_3 3.5.0-1 + xfrmnl_sel_set_sportmask@Base 3.5.0-1 + xfrmnl_sel_set_sportmask@libnl_3 3.5.0-1 + xfrmnl_sel_set_userid@Base 3.5.0-1 + xfrmnl_sel_set_userid@libnl_3 3.5.0-1 + xfrmnl_sel_shared@Base 3.5.0-1 + xfrmnl_sel_shared@libnl_3 3.5.0-1 + xfrmnl_sp_action2str@Base 3.5.0-1 + xfrmnl_sp_action2str@libnl_3 3.5.0-1 + xfrmnl_sp_add@Base 3.5.0-1 + xfrmnl_sp_add@libnl_3 3.5.0-1 + xfrmnl_sp_add_usertemplate@Base 3.5.0-1 + xfrmnl_sp_add_usertemplate@libnl_3 3.5.0-1 + xfrmnl_sp_alloc@Base 3.5.0-1 + xfrmnl_sp_alloc@libnl_3 3.5.0-1 + xfrmnl_sp_alloc_cache@Base 3.5.0-1 + xfrmnl_sp_alloc_cache@libnl_3 3.5.0-1 + xfrmnl_sp_build_add_request@Base 3.5.0-1 + xfrmnl_sp_build_add_request@libnl_3 3.5.0-1 + xfrmnl_sp_build_delete_request@Base 3.5.0-1 + xfrmnl_sp_build_delete_request@libnl_3 3.5.0-1 + xfrmnl_sp_build_get_request@Base 3.5.0-1 + xfrmnl_sp_build_get_request@libnl_3 3.5.0-1 + xfrmnl_sp_build_update_request@Base 3.5.0-1 + xfrmnl_sp_build_update_request@libnl_3 3.5.0-1 + xfrmnl_sp_delete@Base 3.5.0-1 + xfrmnl_sp_delete@libnl_3 3.5.0-1 + xfrmnl_sp_dir2str@Base 3.5.0-1 + xfrmnl_sp_dir2str@libnl_3 3.5.0-1 + xfrmnl_sp_flags2str@Base 3.5.0-1 + xfrmnl_sp_flags2str@libnl_3 3.5.0-1 + xfrmnl_sp_foreach_usertemplate@Base 3.5.0-1 + xfrmnl_sp_foreach_usertemplate@libnl_3 3.5.0-1 + xfrmnl_sp_get@Base 3.5.0-1 + xfrmnl_sp_get@libnl_3 3.5.0-1 + xfrmnl_sp_get_action@Base 3.5.0-1 + xfrmnl_sp_get_action@libnl_3 3.5.0-1 + xfrmnl_sp_get_curlifetime@Base 3.5.0-1 + xfrmnl_sp_get_curlifetime@libnl_3 3.5.0-1 + xfrmnl_sp_get_dir@Base 3.5.0-1 + xfrmnl_sp_get_dir@libnl_3 3.5.0-1 + xfrmnl_sp_get_flags@Base 3.5.0-1 + xfrmnl_sp_get_flags@libnl_3 3.5.0-1 + xfrmnl_sp_get_index@Base 3.5.0-1 + xfrmnl_sp_get_index@libnl_3 3.5.0-1 + xfrmnl_sp_get_kernel@Base 3.5.0-1 + xfrmnl_sp_get_kernel@libnl_3 3.5.0-1 + xfrmnl_sp_get_lifetime_cfg@Base 3.5.0-1 + xfrmnl_sp_get_lifetime_cfg@libnl_3 3.5.0-1 + xfrmnl_sp_get_mark@Base 3.5.0-1 + xfrmnl_sp_get_mark@libnl_3 3.5.0-1 + xfrmnl_sp_get_nusertemplates@Base 3.5.0-1 + xfrmnl_sp_get_nusertemplates@libnl_3 3.5.0-1 + xfrmnl_sp_get_priority@Base 3.5.0-1 + xfrmnl_sp_get_priority@libnl_3 3.5.0-1 + xfrmnl_sp_get_sec_ctx@Base 3.5.0-1 + xfrmnl_sp_get_sec_ctx@libnl_3 3.5.0-1 + xfrmnl_sp_get_sel@Base 3.5.0-1 + xfrmnl_sp_get_sel@libnl_3 3.5.0-1 + xfrmnl_sp_get_share@Base 3.5.0-1 + xfrmnl_sp_get_share@libnl_3 3.5.0-1 + xfrmnl_sp_get_userpolicy_type@Base 3.5.0-1 + xfrmnl_sp_get_userpolicy_type@libnl_3 3.5.0-1 + xfrmnl_sp_get_usertemplates@Base 3.5.0-1 + xfrmnl_sp_get_usertemplates@libnl_3 3.5.0-1 + xfrmnl_sp_index2dir@Base 3.5.0-1 + xfrmnl_sp_index2dir@libnl_3 3.5.0-1 + xfrmnl_sp_parse@Base 3.5.0-1 + xfrmnl_sp_parse@libnl_3 3.5.0-1 + xfrmnl_sp_put@Base 3.5.0-1 + xfrmnl_sp_put@libnl_3 3.5.0-1 + xfrmnl_sp_remove_usertemplate@Base 3.5.0-1 + xfrmnl_sp_remove_usertemplate@libnl_3 3.5.0-1 + xfrmnl_sp_set_action@Base 3.5.0-1 + xfrmnl_sp_set_action@libnl_3 3.5.0-1 + xfrmnl_sp_set_dir@Base 3.5.0-1 + xfrmnl_sp_set_dir@libnl_3 3.5.0-1 + xfrmnl_sp_set_flags@Base 3.5.0-1 + xfrmnl_sp_set_flags@libnl_3 3.5.0-1 + xfrmnl_sp_set_index@Base 3.5.0-1 + xfrmnl_sp_set_index@libnl_3 3.5.0-1 + xfrmnl_sp_set_lifetime_cfg@Base 3.5.0-1 + xfrmnl_sp_set_lifetime_cfg@libnl_3 3.5.0-1 + xfrmnl_sp_set_mark@Base 3.5.0-1 + xfrmnl_sp_set_mark@libnl_3 3.5.0-1 + xfrmnl_sp_set_priority@Base 3.5.0-1 + xfrmnl_sp_set_priority@libnl_3 3.5.0-1 + xfrmnl_sp_set_sec_ctx@Base 3.5.0-1 + xfrmnl_sp_set_sec_ctx@libnl_3 3.5.0-1 + xfrmnl_sp_set_sel@Base 3.5.0-1 + xfrmnl_sp_set_sel@libnl_3 3.5.0-1 + xfrmnl_sp_set_share@Base 3.5.0-1 + xfrmnl_sp_set_share@libnl_3 3.5.0-1 + xfrmnl_sp_set_userpolicy_type@Base 3.5.0-1 + xfrmnl_sp_set_userpolicy_type@libnl_3 3.5.0-1 + xfrmnl_sp_share2str@Base 3.5.0-1 + xfrmnl_sp_share2str@libnl_3 3.5.0-1 + xfrmnl_sp_str2action@Base 3.5.0-1 + xfrmnl_sp_str2action@libnl_3 3.5.0-1 + xfrmnl_sp_str2dir@Base 3.5.0-1 + xfrmnl_sp_str2dir@libnl_3 3.5.0-1 + xfrmnl_sp_str2flag@Base 3.5.0-1 + xfrmnl_sp_str2flag@libnl_3 3.5.0-1 + xfrmnl_sp_str2share@Base 3.5.0-1 + xfrmnl_sp_str2share@libnl_3 3.5.0-1 + xfrmnl_sp_str2type@Base 3.5.0-1 + xfrmnl_sp_str2type@libnl_3 3.5.0-1 + xfrmnl_sp_type2str@Base 3.5.0-1 + xfrmnl_sp_type2str@libnl_3 3.5.0-1 + xfrmnl_sp_update@Base 3.5.0-1 + xfrmnl_sp_update@libnl_3 3.5.0-1 + xfrmnl_sp_usertemplate_n@Base 3.5.0-1 + xfrmnl_sp_usertemplate_n@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_alloc@Base 3.5.0-1 + xfrmnl_user_tmpl_alloc@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_clone@Base 3.5.0-1 + xfrmnl_user_tmpl_clone@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_cmp@Base 3.5.0-1 + xfrmnl_user_tmpl_cmp@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_dump@Base 3.5.0-1 + xfrmnl_user_tmpl_dump@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_free@Base 3.5.0-1 + xfrmnl_user_tmpl_free@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_aalgos@Base 3.5.0-1 + xfrmnl_user_tmpl_get_aalgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_calgos@Base 3.5.0-1 + xfrmnl_user_tmpl_get_calgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_daddr@Base 3.5.0-1 + xfrmnl_user_tmpl_get_daddr@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_ealgos@Base 3.5.0-1 + xfrmnl_user_tmpl_get_ealgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_family@Base 3.5.0-1 + xfrmnl_user_tmpl_get_family@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_mode@Base 3.5.0-1 + xfrmnl_user_tmpl_get_mode@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_optional@Base 3.5.0-1 + xfrmnl_user_tmpl_get_optional@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_proto@Base 3.5.0-1 + xfrmnl_user_tmpl_get_proto@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_reqid@Base 3.5.0-1 + xfrmnl_user_tmpl_get_reqid@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_saddr@Base 3.5.0-1 + xfrmnl_user_tmpl_get_saddr@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_share@Base 3.5.0-1 + xfrmnl_user_tmpl_get_share@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_spi@Base 3.5.0-1 + xfrmnl_user_tmpl_get_spi@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_mode2str@Base 3.5.0-1 + xfrmnl_user_tmpl_mode2str@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_aalgos@Base 3.5.0-1 + xfrmnl_user_tmpl_set_aalgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_calgos@Base 3.5.0-1 + xfrmnl_user_tmpl_set_calgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_daddr@Base 3.5.0-1 + xfrmnl_user_tmpl_set_daddr@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_ealgos@Base 3.5.0-1 + xfrmnl_user_tmpl_set_ealgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_family@Base 3.5.0-1 + xfrmnl_user_tmpl_set_family@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_mode@Base 3.5.0-1 + xfrmnl_user_tmpl_set_mode@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_optional@Base 3.5.0-1 + xfrmnl_user_tmpl_set_optional@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_proto@Base 3.5.0-1 + xfrmnl_user_tmpl_set_proto@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_reqid@Base 3.5.0-1 + xfrmnl_user_tmpl_set_reqid@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_saddr@Base 3.5.0-1 + xfrmnl_user_tmpl_set_saddr@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_share@Base 3.5.0-1 + xfrmnl_user_tmpl_set_share@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_spi@Base 3.5.0-1 + xfrmnl_user_tmpl_set_spi@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_str2mode@Base 3.5.0-1 + xfrmnl_user_tmpl_str2mode@libnl_3 3.5.0-1 diff --git a/src/libnl3/debian/libnl-xfrm-3-dev.install b/src/libnl3/debian/libnl-xfrm-3-dev.install new file mode 100644 index 000000000000..f57e152c5aae --- /dev/null +++ b/src/libnl3/debian/libnl-xfrm-3-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/*/pkgconfig/libnl-xfrm-3* +debian/tmp/usr/lib/*/libnl-xfrm-3*.so +debian/tmp/usr/lib/*/libnl-xfrm-3*.a diff --git a/src/libnl3/debian/patches/series b/src/libnl3/debian/patches/series new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/libnl3/debian/rules b/src/libnl3/debian/rules new file mode 100755 index 000000000000..bb33dda05a64 --- /dev/null +++ b/src/libnl3/debian/rules @@ -0,0 +1,39 @@ +#!/usr/bin/make -f + +DEB_BUILDDIR = debian/build +DEB_MAKE_FLAVORS = main udeb + +udeb_libnl=libnl-3-200-udeb +udeb_libnl_genl=libnl-genl-3-200-udeb + +TG_BRANCHES := debian/etc-libnl-3,debian/out-of-tree,debian/no-symvers + +-include /usr/share/topgit/tg2quilt.mk + +# to export the patch series use +# debian/rules tg-clean +# debian/rules tg-export + + +include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/cdbs/1/rules/autoreconf.mk +include /usr/share/cdbs/1/class/autotools.mk + +# FIXME: not honoured +#CFLAGS_udeb += $(CFLAGS) -Os +CFLAGS += $(if $(findstring udeb,$(cdbs_make_curflavor)),-Os) + +DEB_DH_STRIP_ARGS := --dbg-package=libnl-3-200-dbg +DEB_DH_MAKESHLIBS_ARGS_libnl-3-200 := --add-udeb=$(udeb_libnl) +DEB_DH_MAKESHLIBS_ARGS_libnl-genl-3-200 := --add-udeb=$(udeb_libnl_genl) + +DEB_MAKE_DESTDIRSKEL = $(CURDIR)/debian/tmp +DEB_MAKE_DESTDIRSKEL_udeb = $(CURDIR)/debian/tmp/udeb + +DEB_DH_INSTALL_ARGS_$(udeb) += --sourcedir=debian/tmp/udeb + +DEB_CONFIGURE_EXTRA_FLAGS += --libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) + +clean:: + # from some unknown reason CDBS does not remove the builddir + rm -rf $(DEB_BUILDDIR) diff --git a/src/libnl3/debian/source/format b/src/libnl3/debian/source/format new file mode 100644 index 000000000000..163aaf8d82b6 --- /dev/null +++ b/src/libnl3/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/src/libnl3/debian/watch b/src/libnl3/debian/watch new file mode 100644 index 000000000000..9939913ca0e0 --- /dev/null +++ b/src/libnl3/debian/watch @@ -0,0 +1,2 @@ +version=3 +https://github.com/thom311/libnl/releases/libnl-(.*)\.tar\.gz From 04b911341016546fcfa39f31742fb28a2b7686a8 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Tue, 7 Jan 2020 16:42:00 +0800 Subject: [PATCH 52/66] [Mellanox]Update the hw-mgmt patch for simx on V.7.0000.2308 (#3957) * [Mellanox/hw-mgmt] Update the hw-mgmt patch for simx on V.7.0000.2308 * removing the extra "[PATCH]" --- .../0001-Make-hw-mgmt-SimX-compatiable.patch | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch b/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch index 31a85434fb49..f16c0d02794b 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,53 +1,53 @@ -From 051938b7c49cc18aaddd699939353f591554d635 Mon Sep 17 00:00:00 2001 -From: Mykola Faryma -Date: Wed, 3 Apr 2019 14:09:26 +0000 +From c6ee8c86c35f8b1e60bf4df0d7198f349f8552c1 Mon Sep 17 00:00:00 2001 +From: Stephen Sun +Date: Wed, 25 Dec 2019 19:33:17 +0800 Subject: [PATCH] Make hw-mgmt SimX compatiable. -Signed-off-by: Mykola Faryma +Signed-off-by: Stephen Sun --- usr/usr/bin/hw-management.sh | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/usr/usr/bin/hw-management.sh b/usr/usr/bin/hw-management.sh -index fdb3013..68da9bc 100755 +index cff10fe..0511c7c 100755 --- a/usr/usr/bin/hw-management.sh +++ b/usr/usr/bin/hw-management.sh -@@ -646,6 +646,35 @@ do_chip_down() +@@ -737,6 +737,35 @@ do_chip_down() /usr/bin/hw-management-thermal-events.sh change hotplug_asic down %S %p } +handle_simx() +{ -+ local -r onie_platform="$(cat /host/machine.conf | grep onie_platform | cut -d= -f2)" ++ local -r 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 ++ handle_simx ++ exit 0 +fi + case $ACTION in start) - do_start + if [ -d /var/run/hw-management ]; then -- 1.9.1 From 3548587b733f1c11ffadc4af0a7598b269b85588 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 7 Jan 2020 15:52:49 -0800 Subject: [PATCH 53/66] [apt] Instruct apt-get to NOT check the "Valid Until" date in Release files (#3973) This is an addendum to #3958, which also instructs apt to ignore the "Valid Until" date in Release files inside the slave containers, making a complete solution, much like the previously abandoned PR #2609. This patch also unifies file names and contents. When the Debian team archives a repo, it stops updating the "Valid Until" date, thus apt-get will not apply updates for that repo unless we explicitly tell it to ignore the "Valid Until" date. Also, this has become an issue with active (i.e., non-archived) repos twice in the past year because the Debian folks seem to occasionally let the expiration lapse before updating the date. This will cause SONiC builds to fail with a message like E: Release file for http://debian-archive.trafficmanager.net/debian-security/dists/jessie/updates/InRelease is expired (invalid since 3d 3h 11min 20s). Updates for this repository will not be applied. until the dates have been updated and propagated to all mirrors. With this patch, SONiC should no longer be affected by lapsed "Valid Until" dates, whether they be accidental or purposeful. --- dockers/docker-base-stretch/Dockerfile.j2 | 2 +- dockers/docker-base-stretch/aptconf_archive_expired_release | 3 --- dockers/docker-base-stretch/no-check-valid-until | 4 ++++ dockers/docker-base/Dockerfile.j2 | 2 +- dockers/docker-base/aptconf_archive_expired_release | 3 --- dockers/docker-base/no-check-valid-until | 4 ++++ files/apt/apt.conf.d/no-check-valid-until | 3 +++ sonic-slave-jessie/Dockerfile.j2 | 2 ++ sonic-slave-jessie/no-check-valid-until | 4 ++++ sonic-slave-stretch/Dockerfile.j2 | 2 ++ sonic-slave-stretch/no-check-valid-until | 4 ++++ 11 files changed, 25 insertions(+), 8 deletions(-) delete mode 100644 dockers/docker-base-stretch/aptconf_archive_expired_release create mode 100644 dockers/docker-base-stretch/no-check-valid-until delete mode 100644 dockers/docker-base/aptconf_archive_expired_release create mode 100644 dockers/docker-base/no-check-valid-until create mode 100644 sonic-slave-jessie/no-check-valid-until create mode 100644 sonic-slave-stretch/no-check-valid-until diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index d8188a06afd6..dea58a210f89 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -34,7 +34,7 @@ COPY ["sources.list.arm64", "/etc/apt/sources.list"] COPY ["sources.list", "/etc/apt/sources.list"] {% endif %} COPY ["no_install_recommend_suggest", "/etc/apt/apt.conf.d"] -COPY ["aptconf_archive_expired_release", "/etc/apt/apt.conf.d"] +COPY ["no-check-valid-until", "/etc/apt/apt.conf.d"] # Update apt cache and # pre-install fundamental packages diff --git a/dockers/docker-base-stretch/aptconf_archive_expired_release b/dockers/docker-base-stretch/aptconf_archive_expired_release deleted file mode 100644 index 67bc409b2174..000000000000 --- a/dockers/docker-base-stretch/aptconf_archive_expired_release +++ /dev/null @@ -1,3 +0,0 @@ -# Instruct apt-get to override expired releases repo list for jessie archives - -Acquire::Check-Valid-Until "0"; diff --git a/dockers/docker-base-stretch/no-check-valid-until b/dockers/docker-base-stretch/no-check-valid-until new file mode 100644 index 000000000000..c7c25d017f7f --- /dev/null +++ b/dockers/docker-base-stretch/no-check-valid-until @@ -0,0 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + +Acquire::Check-Valid-Until "false"; diff --git a/dockers/docker-base/Dockerfile.j2 b/dockers/docker-base/Dockerfile.j2 index cb2ff80186a3..e45235a1e139 100644 --- a/dockers/docker-base/Dockerfile.j2 +++ b/dockers/docker-base/Dockerfile.j2 @@ -32,7 +32,7 @@ COPY ["dpkg_01_drop", "/etc/dpkg/dpkg.cfg.d/01_drop"] COPY ["sources.list.armhf", "/etc/apt/sources.list"] {% elif CONFIGURED_ARCH == "arm64" %} COPY ["sources.list.arm64", "/etc/apt/sources.list"] -COPY ["aptconf_archive_expired_release", "/etc/apt/apt.conf.d"] +COPY ["no-check-valid-until", "/etc/apt/apt.conf.d"] {% else %} COPY ["sources.list", "/etc/apt/sources.list"] {% endif %} diff --git a/dockers/docker-base/aptconf_archive_expired_release b/dockers/docker-base/aptconf_archive_expired_release deleted file mode 100644 index 67bc409b2174..000000000000 --- a/dockers/docker-base/aptconf_archive_expired_release +++ /dev/null @@ -1,3 +0,0 @@ -# Instruct apt-get to override expired releases repo list for jessie archives - -Acquire::Check-Valid-Until "0"; diff --git a/dockers/docker-base/no-check-valid-until b/dockers/docker-base/no-check-valid-until new file mode 100644 index 000000000000..c7c25d017f7f --- /dev/null +++ b/dockers/docker-base/no-check-valid-until @@ -0,0 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + +Acquire::Check-Valid-Until "false"; diff --git a/files/apt/apt.conf.d/no-check-valid-until b/files/apt/apt.conf.d/no-check-valid-until index 97b9c9005181..c7c25d017f7f 100644 --- a/files/apt/apt.conf.d/no-check-valid-until +++ b/files/apt/apt.conf.d/no-check-valid-until @@ -1 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + Acquire::Check-Valid-Until "false"; diff --git a/sonic-slave-jessie/Dockerfile.j2 b/sonic-slave-jessie/Dockerfile.j2 index 7ed7c4eb7096..dce30193420c 100644 --- a/sonic-slave-jessie/Dockerfile.j2 +++ b/sonic-slave-jessie/Dockerfile.j2 @@ -8,6 +8,8 @@ FROM debian:jessie MAINTAINER johnar@microsoft.com +COPY ["no-check-valid-until", "/etc/apt/apt.conf.d/"] + ## Remove retired jessie-updates repo RUN sed -i '/http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list diff --git a/sonic-slave-jessie/no-check-valid-until b/sonic-slave-jessie/no-check-valid-until new file mode 100644 index 000000000000..c7c25d017f7f --- /dev/null +++ b/sonic-slave-jessie/no-check-valid-until @@ -0,0 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + +Acquire::Check-Valid-Until "false"; diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index d0e3775396dc..054920b8280e 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -8,6 +8,8 @@ FROM debian:stretch MAINTAINER gulv@microsoft.com +COPY ["no-check-valid-until", "/etc/apt/apt.conf.d/"] + RUN echo "deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ stretch main contrib non-free" >> /etc/apt/sources.list && \ echo "deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian/ stretch main contrib non-free" >> /etc/apt/sources.list && \ echo "deb [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ stretch/updates main contrib non-free" >> /etc/apt/sources.list && \ diff --git a/sonic-slave-stretch/no-check-valid-until b/sonic-slave-stretch/no-check-valid-until new file mode 100644 index 000000000000..c7c25d017f7f --- /dev/null +++ b/sonic-slave-stretch/no-check-valid-until @@ -0,0 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + +Acquire::Check-Valid-Until "false"; From 2658ab8add1aea30380f83564e55af0931fd49f8 Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Tue, 7 Jan 2020 17:48:03 -0800 Subject: [PATCH 54/66] [dhcp-relay]: Add DHCP Relay Monitor (#3886) DHCP relay MONitor (dhcpmon) keeps track of DORA messages. If DHCP Relay is detected to be not forwarding DORA message, dhcpmon will log such event to syslog. Under the hood dhcpmon keeps counts of clients DR messages, forwarded DR messages, DHCP server OA messages, and forwarded OA messages. dhcpmon will check every 12 sec (configurable) if counts are monotonically increasing and record snapshot of those counters. dhcpmon will report discrepancies when detected between current counters and snapshot counters. pull-request: https://github.com/Azure/sonic-buildimage/pull/3886 signed-off-by: Tamer Ahmed --- .gitignore | 6 + .../docker-dhcp-relay.supervisord.conf.j2 | 48 ++ dockers/docker-dhcp-relay/start.sh | 6 + rules/dhcpmon.mk | 8 + rules/docker-dhcp-relay.mk | 2 +- sonic-slave-stretch/Dockerfile.j2 | 5 +- src/dhcpmon/Makefile | 44 ++ src/dhcpmon/debian/changelog | 5 + src/dhcpmon/debian/compat | 1 + src/dhcpmon/debian/control | 16 + src/dhcpmon/debian/rules | 3 + src/dhcpmon/objects.mk | 4 + src/dhcpmon/src/dhcp_device.c | 460 ++++++++++++++++++ src/dhcpmon/src/dhcp_device.h | 113 +++++ src/dhcpmon/src/dhcp_devman.c | 149 ++++++ src/dhcpmon/src/dhcp_devman.h | 76 +++ src/dhcpmon/src/dhcp_mon.c | 199 ++++++++ src/dhcpmon/src/dhcp_mon.h | 54 ++ src/dhcpmon/src/main.c | 174 +++++++ src/dhcpmon/src/subdir.mk | 29 ++ .../docker-dhcp-relay.supervisord.conf | 13 + 21 files changed, 1413 insertions(+), 2 deletions(-) create mode 100644 rules/dhcpmon.mk create mode 100644 src/dhcpmon/Makefile create mode 100644 src/dhcpmon/debian/changelog create mode 100644 src/dhcpmon/debian/compat create mode 100644 src/dhcpmon/debian/control create mode 100755 src/dhcpmon/debian/rules create mode 100644 src/dhcpmon/objects.mk create mode 100644 src/dhcpmon/src/dhcp_device.c create mode 100644 src/dhcpmon/src/dhcp_device.h create mode 100644 src/dhcpmon/src/dhcp_devman.c create mode 100644 src/dhcpmon/src/dhcp_devman.h create mode 100644 src/dhcpmon/src/dhcp_mon.c create mode 100644 src/dhcpmon/src/dhcp_mon.h create mode 100644 src/dhcpmon/src/main.c create mode 100644 src/dhcpmon/src/subdir.mk diff --git a/.gitignore b/.gitignore index fbf646fcd40f..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/* @@ -106,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 diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 index e738e8699e6c..94fdbfdaff2f 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -85,5 +85,53 @@ stderr_logfile=syslog {% endif %} {% endif %} {% endfor %} + +[group:dhcpmon] +programs= +{%- set add_preceding_comma = { 'flag': False } %} +{% for vlan_name in VLAN %} +{% if VLAN[vlan_name]['dhcp_servers'] %} +{% if add_preceding_comma.flag %},{% endif %} +{% set _dummy = add_preceding_comma.update({'flag': True}) %} +dhcpmon-{{ vlan_name }} +{%- endif %} +{% endfor %} + + +{# Create a program entry for each DHCP MONitor instance #} +{% set relay_for_ipv4 = { 'flag': False } %} +{% for vlan_name in VLAN %} +{% if VLAN[vlan_name]['dhcp_servers'] %} +{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %} +{% if dhcp_server | ipv4 %} +{% set _dummy = relay_for_ipv4.update({'flag': True}) %} +{% endif %} +{% endfor %} +{% if relay_for_ipv4.flag %} +{% set _dummy = relay_for_ipv4.update({'flag': False}) %} +[program:dhcpmon-{{ vlan_name }}] +{# We treat this VLAN as a downstream interface (-id), as we only want to listen for requests #} +command=/usr/sbin/dhcpmon -id {{ vlan_name }} +{#- We treat all other interfaces as upstream interfaces (-iu), as we only want to listen for replies #} +{% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} +{% if prefix | ipv4 and name != vlan_name %} -iu {{ name }}{% endif -%} +{% endfor %} +{% for (name, prefix) in INTERFACE|pfx_filter %} +{% if prefix | ipv4 %} -iu {{ name }}{% endif -%} +{% endfor %} +{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %} +{% if prefix | ipv4 %} -iu {{ name }}{% endif -%} +{% endfor %} + +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +{% endif %} +{% endif %} +{% endfor %} + {% endif %} {% endif %} diff --git a/dockers/docker-dhcp-relay/start.sh b/dockers/docker-dhcp-relay/start.sh index 0ac5ea1a10ec..dbbf32251080 100755 --- a/dockers/docker-dhcp-relay/start.sh +++ b/dockers/docker-dhcp-relay/start.sh @@ -19,3 +19,9 @@ if [ $(supervisorctl status | grep -c "^isc-dhcp-relay:") -gt 0 ]; then # Start all DHCP relay agent(s) supervisorctl start isc-dhcp-relay:* fi + +# If our supervisor config has entries in the "dhcpmon" group... +if [ $(supervisorctl status | grep -c "^dhcpmon:") -gt 0 ]; then + # Start all DHCP Monitor daemon(s) + supervisorctl start dhcpmon:* +fi diff --git a/rules/dhcpmon.mk b/rules/dhcpmon.mk new file mode 100644 index 000000000000..3d80d227c156 --- /dev/null +++ b/rules/dhcpmon.mk @@ -0,0 +1,8 @@ +# SONiC DHCP MONitor package + +SONIC_DHCPMON_VERSION = 1.0.0-0 +SONIC_DHCPMON_PKG_NAME = dhcpmon + +SONIC_DHCPMON = sonic-$(SONIC_DHCPMON_PKG_NAME)_$(SONIC_DHCPMON_VERSION)_$(CONFIGURED_ARCH).deb +$(SONIC_DHCPMON)_SRC_PATH = $(SRC_PATH)/$(SONIC_DHCPMON_PKG_NAME) +SONIC_DPKG_DEBS += $(SONIC_DHCPMON) diff --git a/rules/docker-dhcp-relay.mk b/rules/docker-dhcp-relay.mk index 5aae24ee33b5..8deb6ebbfad7 100644 --- a/rules/docker-dhcp-relay.mk +++ b/rules/docker-dhcp-relay.mk @@ -6,7 +6,7 @@ DOCKER_DHCP_RELAY_DBG = $(DOCKER_DHCP_RELAY_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_DHCP_RELAY)_PATH = $(DOCKERS_PATH)/$(DOCKER_DHCP_RELAY_STEM) -$(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_RELAY) $(REDIS_TOOLS) +$(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_RELAY) $(REDIS_TOOLS) $(SONIC_DHCPMON) $(DOCKER_DHCP_RELAY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) $(DOCKER_DHCP_RELAY)_DBG_DEPENDS += $(ISC_DHCP_RELAY_DBG) diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 054920b8280e..8786a9d4101f 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -295,7 +295,10 @@ RUN apt-get update && apt-get install -y \ # For kdump-tools liblzo2-dev \ # For SAI3.7 - libprotobuf-dev + libprotobuf-dev \ +# For DHCP Monitor tool + libexplain-dev \ + libevent-dev ## Config dpkg ## install the configuration file if it’s currently missing diff --git a/src/dhcpmon/Makefile b/src/dhcpmon/Makefile new file mode 100644 index 000000000000..61cde376730b --- /dev/null +++ b/src/dhcpmon/Makefile @@ -0,0 +1,44 @@ +RM := rm -rf +DHCPMON_TARGET := dhcpmon +CP := cp +MKDIR := mkdir +CC := gcc +MV := mv + +# All of the sources participating in the build are defined here +-include src/subdir.mk +-include objects.mk + +ifneq ($(MAKECMDGOALS),clean) +ifneq ($(strip $(C_DEPS)),) +-include $(C_DEPS) +endif +endif + +# Add inputs and outputs from these tool invocations to the build variables + +# All Target +all: sonic-dhcpmon + +# Tool invocations +sonic-dhcpmon: $(OBJS) $(USER_OBJS) + @echo 'Building target: $@' + @echo 'Invoking: GCC C Linker' + $(CC) -o "$(DHCPMON_TARGET)" $(OBJS) $(USER_OBJS) $(LIBS) + @echo 'Finished building target: $@' + @echo ' ' + +# Other Targets +install: + $(MKDIR) -p $(DESTDIR)/usr/sbin + $(MV) $(DHCPMON_TARGET) $(DESTDIR)/usr/sbin + +deinstall: + $(RM) $(DESTDIR)/usr/sbin/$(DHCPMON_TARGET) + $(RM) -rf $(DESTDIR)/usr/sbin + +clean: + -$(RM) $(EXECUTABLES)$(OBJS)$(C_DEPS) $(DHCPMON_TARGET) + -@echo ' ' + +.PHONY: all clean dependents diff --git a/src/dhcpmon/debian/changelog b/src/dhcpmon/debian/changelog new file mode 100644 index 000000000000..83b79d6d93bd --- /dev/null +++ b/src/dhcpmon/debian/changelog @@ -0,0 +1,5 @@ +sonic-dhcpmon (1.0.0-0) UNRELEASED; urgency=medium + + * Initial release. + + -- Tamer Ahmed Mon, 09 Dec 2019 12:00:00 -0700 diff --git a/src/dhcpmon/debian/compat b/src/dhcpmon/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/src/dhcpmon/debian/compat @@ -0,0 +1 @@ +9 diff --git a/src/dhcpmon/debian/control b/src/dhcpmon/debian/control new file mode 100644 index 000000000000..2f05fda79963 --- /dev/null +++ b/src/dhcpmon/debian/control @@ -0,0 +1,16 @@ +Source: sonic-dhcpmon +Section: devel +Priority: optional +Maintainer: Tamer Ahmed +Build-Depends: debhelper (>= 8.0.0), + dh-systemd +Standards-Version: 3.9.3 +Homepage: https://github.com/Azure/sonic-buildimage +XS-Go-Import-Path: github.com/Azure/sonic-buildimage + +Package: sonic-dhcpmon +Architecture: any +Built-Using: ${misc:Built-Using} +Depends: libexplain51, + libevent-2.0-5 +Description: SONiC DHCP Monitor diff --git a/src/dhcpmon/debian/rules b/src/dhcpmon/debian/rules new file mode 100755 index 000000000000..3995a26d7fcd --- /dev/null +++ b/src/dhcpmon/debian/rules @@ -0,0 +1,3 @@ +#!/usr/bin/make -f +%: + dh $@ --with systemd diff --git a/src/dhcpmon/objects.mk b/src/dhcpmon/objects.mk new file mode 100644 index 000000000000..c9b774a53921 --- /dev/null +++ b/src/dhcpmon/objects.mk @@ -0,0 +1,4 @@ +USER_OBJS := + +LIBS := -levent -lexplain + diff --git a/src/dhcpmon/src/dhcp_device.c b/src/dhcpmon/src/dhcp_device.c new file mode 100644 index 000000000000..aa0c0f835cbd --- /dev/null +++ b/src/dhcpmon/src/dhcp_device.c @@ -0,0 +1,460 @@ +/** + * @file dhcp_device.c + * + * device (interface) module + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dhcp_device.h" + +/** Start of Ether header of a captured frame */ +#define ETHER_START_OFFSET 0 +/** Start of IP header of a captured frame */ +#define IP_START_OFFSET (ETHER_START_OFFSET + ETHER_HDR_LEN) +/** Start of UDP header of a captured frame */ +#define UDP_START_OFFSET (IP_START_OFFSET + sizeof(struct ip)) +/** Start of DHCP header of a captured frame */ +#define DHCP_START_OFFSET (UDP_START_OFFSET + sizeof(struct udphdr)) +/** Start of DHCP Options segment of a captured frame */ +#define DHCP_OPTIONS_HEADER_SIZE 240 + +#define OP_LDHA (BPF_LD | BPF_H | BPF_ABS) /** bpf ldh Abs */ +#define OP_LDHI (BPF_LD | BPF_H | BPF_IND) /** bpf ldh Ind */ +#define OP_LDB (BPF_LD | BPF_B | BPF_ABS) /** bpf ldb Abs*/ +#define OP_JEQ (BPF_JMP | BPF_JEQ | BPF_K) /** bpf jeq */ +#define OP_JGT (BPF_JMP | BPF_JGT | BPF_K) /** bpf jgt */ +#define OP_RET (BPF_RET | BPF_K) /** bpf ret */ +#define OP_JSET (BPF_JMP | BPF_JSET | BPF_K) /** bpf jset */ +#define OP_LDXB (BPF_LDX | BPF_B | BPF_MSH) /** bpf ldxb */ + +/** Berkley Packet Fitler program for "udp and (port 67 or port 68)". This program is obtained suing the following + * tcpdump command: 'tcpdump -dd "udp and (port 67 or port 68)"' + */ +static struct sock_filter dhcp_bpf_code[] = { + {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x0000000c}, // (000) ldh [12] + {.code = OP_JEQ, .jt = 0, .jf = 7, .k = 0x000086dd}, // (001) jeq #0x86dd jt 2 jf 9 + {.code = OP_LDB, .jt = 0, .jf = 0, .k = 0x00000014}, // (002) ldb [20] + {.code = OP_JEQ, .jt = 0, .jf = 18, .k = 0x00000011}, // (003) jeq #0x11 jt 4 jf 22 + {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x00000036}, // (004) ldh [54] + {.code = OP_JEQ, .jt = 15, .jf = 0, .k = 0x00000043}, // (005) jeq #0x43 jt 21 jf 6 + {.code = OP_JEQ, .jt = 14, .jf = 0, .k = 0x00000044}, // (006) jeq #0x44 jt 21 jf 7 + {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x00000038}, // (007) ldh [56] + {.code = OP_JEQ, .jt = 12, .jf = 11, .k = 0x00000043}, // (008) jeq #0x43 jt 21 jf 20 + {.code = OP_JEQ, .jt = 0, .jf = 12, .k = 0x00000800}, // (009) jeq #0x800 jt 10 jf 22 + {.code = OP_LDB, .jt = 0, .jf = 0, .k = 0x00000017}, // (010) ldb [23] + {.code = OP_JEQ, .jt = 0, .jf = 10, .k = 0x00000011}, // (011) jeq #0x11 jt 12 jf 22 + {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x00000014}, // (012) ldh [20] + {.code = OP_JSET, .jt = 8, .jf = 0, .k = 0x00001fff}, // (013) jset #0x1fff jt 22 jf 14 + {.code = OP_LDXB, .jt = 0, .jf = 0, .k = 0x0000000e}, // (014) ldxb 4*([14]&0xf) + {.code = OP_LDHI, .jt = 0, .jf = 0, .k = 0x0000000e}, // (015) ldh [x + 14] + {.code = OP_JEQ, .jt = 4, .jf = 0, .k = 0x00000043}, // (016) jeq #0x43 jt 21 jf 17 + {.code = OP_JEQ, .jt = 3, .jf = 0, .k = 0x00000044}, // (017) jeq #0x44 jt 21 jf 18 + {.code = OP_LDHI, .jt = 0, .jf = 0, .k = 0x00000010}, // (018) ldh [x + 16] + {.code = OP_JEQ, .jt = 1, .jf = 0, .k = 0x00000043}, // (019) jeq #0x43 jt 21 jf 20 + {.code = OP_JEQ, .jt = 0, .jf = 1, .k = 0x00000044}, // (020) jeq #0x44 jt 21 jf 22 + {.code = OP_RET, .jt = 0, .jf = 0, .k = 0x00040000}, // (021) ret #262144 + {.code = OP_RET, .jt = 0, .jf = 0, .k = 0x00000000}, // (022) ret #0 +}; + +/** Filter program socket struct */ +static struct sock_fprog dhcp_sock_bfp = { + .len = sizeof(dhcp_bpf_code) / sizeof(*dhcp_bpf_code), .filter = dhcp_bpf_code +}; + +/** global aggregate counter for DHCP interfaces */ +static dhcp_device_counters_t glob_counters[DHCP_DIR_COUNT] = { + [DHCP_RX] = {.discover = 0, .offer = 0, .request = 0, .ack = 0}, + [DHCP_TX] = {.discover = 0, .offer = 0, .request = 0, .ack = 0}, +}; + +/** global aggregate counter snapshot for DHCP interfaces */ +static dhcp_device_counters_t glob_counters_snapshot[DHCP_DIR_COUNT] = { + [DHCP_RX] = {.discover = 0, .offer = 0, .request = 0, .ack = 0}, + [DHCP_TX] = {.discover = 0, .offer = 0, .request = 0, .ack = 0}, +}; + +/** + * @code handle_dhcp_option_53(context, dhcp_option, dir); + * + * @brief handle the logic related to DHCP option 53 + * + * @param context Device (interface) context + * @param dhcp_option pointer to DHCP option buffer space + * @param dir packet direction + * + * @return none + */ +static void handle_dhcp_option_53(dhcp_device_context_t *context, const u_char *dhcp_option, dhcp_packet_direction_t dir) +{ + switch (dhcp_option[2]) + { + case 1: + context->counters[dir].discover++; + if ((context->is_uplink && dir == DHCP_TX) || (!context->is_uplink && dir == DHCP_RX)) { + glob_counters[dir].discover++; + } + break; + case 2: + context->counters[dir].offer++; + if ((!context->is_uplink && dir == DHCP_TX) || (context->is_uplink && dir == DHCP_RX)) { + glob_counters[dir].offer++; + } + break; + case 3: + context->counters[dir].request++; + if ((context->is_uplink && dir == DHCP_TX) || (!context->is_uplink && dir == DHCP_RX)) { + glob_counters[dir].request++; + } + break; + case 5: + context->counters[dir].ack++; + if ((!context->is_uplink && dir == DHCP_TX) || (context->is_uplink && dir == DHCP_RX)) { + glob_counters[dir].ack++; + } + break; + case 4: // type: Decline + case 6 ... 8: + // type: NAK, Release, Inform + break; + default: + syslog(LOG_WARNING, "handle_dhcp_option_53(%s): Unknown DHCP option 53 type %d", context->intf, dhcp_option[2]); + break; + } +} + +/** + * @code read_callback(fd, event, arg); + * + * @brief callback for libevent which is called every time out in order to read queued packet capture + * + * @param fd socket to read from + * @param event libevent triggered event + * @param arg user provided argument for callback (interface context) + * @param packet pointer to packet data + * + * @return none + */ +static void read_callback(int fd, short event, void *arg) +{ + dhcp_device_context_t *context = (dhcp_device_context_t*) arg; + ssize_t buffer_sz; + + while ((event == EV_READ) && + ((buffer_sz = recv(fd, context->buffer, context->snaplen, MSG_DONTWAIT)) > 0)) { + struct ether_header *ethhdr = (struct ether_header*) context->buffer; + struct udphdr *udp = (struct udphdr*) (context->buffer + UDP_START_OFFSET); + int dhcp_option_offset = DHCP_START_OFFSET + DHCP_OPTIONS_HEADER_SIZE; + + if ((buffer_sz > UDP_START_OFFSET + sizeof(struct udphdr) + DHCP_OPTIONS_HEADER_SIZE) && + (ntohs(udp->len) > DHCP_OPTIONS_HEADER_SIZE)) { + int dhcp_sz = ntohs(udp->len) < buffer_sz - UDP_START_OFFSET - sizeof(struct udphdr) ? + ntohs(udp->len) : buffer_sz - UDP_START_OFFSET - sizeof(struct udphdr); + int dhcp_option_sz = dhcp_sz - DHCP_OPTIONS_HEADER_SIZE; + const u_char *dhcp_option = context->buffer + dhcp_option_offset; + dhcp_packet_direction_t dir = (ethhdr->ether_shost[0] == context->mac[0] && + ethhdr->ether_shost[1] == context->mac[1] && + ethhdr->ether_shost[2] == context->mac[2] && + ethhdr->ether_shost[3] == context->mac[3] && + ethhdr->ether_shost[4] == context->mac[4] && + ethhdr->ether_shost[5] == context->mac[5]) ? + DHCP_TX : DHCP_RX; + int offset = 0; + int stop_dhcp_processing = 0; + while ((offset < (dhcp_option_sz + 1)) && dhcp_option[offset] != 255) { + switch (dhcp_option[offset]) + { + case 53: + if (offset < (dhcp_option_sz + 2)) { + handle_dhcp_option_53(context, &dhcp_option[offset], dir); + } + stop_dhcp_processing = 1; // break while loop since we are only interested in Option 53 + break; + default: + break; + } + + if (stop_dhcp_processing == 1) { + break; + } + + if (dhcp_option[offset] == 0) { // DHCP Option Padding + offset++; + } else { + offset += dhcp_option[offset + 1] + 2; + } + } + } else { + syslog(LOG_WARNING, "read_callback(%s): read length (%ld) is too small to capture DHCP options", + context->intf, buffer_sz); + } + } +} + +/** + * @code dhcp_device_validate(counters, counters_snapshot); + * + * @brief validate current interface counters by comparing aggregate counter with snapshot counters. + * + * @param counters recent interface counter + * @param counters_snapshot snapshot counters + * + * @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE + */ +static dhcp_mon_status_t dhcp_device_validate(dhcp_device_counters_t *counters, + dhcp_device_counters_t *counters_snapshot) +{ + dhcp_mon_status_t rv = DHCP_MON_STATUS_HEALTHY; + + if ((counters[DHCP_RX].discover == counters_snapshot[DHCP_RX].discover) && + (counters[DHCP_RX].offer == counters_snapshot[DHCP_RX].offer ) && + (counters[DHCP_RX].request == counters_snapshot[DHCP_RX].request ) && + (counters[DHCP_RX].ack == counters_snapshot[DHCP_RX].ack ) ) { + rv = DHCP_MON_STATUS_INDETERMINATE; + } else { + // if we have rx DORA then we should have corresponding tx DORA (DORA being relayed) + if (((counters[DHCP_RX].discover > counters_snapshot[DHCP_RX].discover) && + (counters[DHCP_TX].discover <= counters_snapshot[DHCP_TX].discover) ) || + ((counters[DHCP_RX].offer > counters_snapshot[DHCP_RX].offer ) && + (counters[DHCP_TX].offer <= counters_snapshot[DHCP_TX].offer ) ) || + ((counters[DHCP_RX].request > counters_snapshot[DHCP_RX].request ) && + (counters[DHCP_TX].request <= counters_snapshot[DHCP_TX].request ) ) || + ((counters[DHCP_RX].ack > counters_snapshot[DHCP_RX].ack ) && + (counters[DHCP_TX].ack <= counters_snapshot[DHCP_TX].ack ) ) ) { + rv = DHCP_MON_STATUS_UNHEALTHY; + } + } + + return rv; +} + +/** + * @code dhcp_print_counters(counters); + * + * @brief prints DHCP counters to sylsog. + * + * @param counters interface counter + */ +static void dhcp_print_counters(dhcp_device_counters_t *counters) +{ + syslog(LOG_NOTICE, "DHCP Discover rx: %lu, tx:%lu, Offer rx: %lu, tx:%lu, Request rx: %lu, tx:%lu, ACK rx: %lu, tx:%lu\n", + counters[DHCP_RX].discover, counters[DHCP_TX].discover, + counters[DHCP_RX].offer, counters[DHCP_TX].offer, + counters[DHCP_RX].request, counters[DHCP_TX].request, + counters[DHCP_RX].ack, counters[DHCP_TX].ack); +} + +/** + * @code init_socket(context, intf, snaplen, base); + * + * @brief initializes socket, bind it to interface and bpf prgram, and + * associate with libevent base + * + * @param context pointer to device (interface) context + * @param intf interface name + * @param snaplen length of packet capture + * @param base libevent base + * + * @return 0 on success, otherwise for failure + */ +static int init_socket(dhcp_device_context_t *context, + const char *intf, + size_t snaplen, + struct event_base *base) +{ + int rv = -1; + + do { + if (snaplen < UDP_START_OFFSET + sizeof(struct udphdr) + DHCP_OPTIONS_HEADER_SIZE) { + syslog(LOG_ALERT, "init_socket(%s): snap length is too low to capture DHCP options", intf); + break; + } + + context->sock = socket(AF_PACKET, SOCK_RAW | SOCK_NONBLOCK, htons(ETH_P_ALL)); + if (context->sock < 0) { + syslog(LOG_ALERT, "socket: failed to open socket with '%s'\n", strerror(errno)); + break; + } + + struct sockaddr_ll addr; + memset(&addr, 0, sizeof(addr)); + addr.sll_ifindex = if_nametoindex(intf); + addr.sll_family = AF_PACKET; + addr.sll_protocol = htons(ETH_P_ALL); + if (bind(context->sock, (struct sockaddr *) &addr, sizeof(addr))) { + syslog(LOG_ALERT, "bind: failed to bind to interface '%s' with '%s'\n", intf, strerror(errno)); + break; + } + + if (setsockopt(context->sock, SOL_SOCKET, SO_ATTACH_FILTER, &dhcp_sock_bfp, sizeof(dhcp_sock_bfp)) != 0) { + syslog(LOG_ALERT, "setsockopt: failed to attach filter with '%s'\n", strerror(errno)); + break; + } + + context->buffer = (uint8_t *) malloc(snaplen); + if (context->buffer == NULL) { + syslog(LOG_ALERT, "malloc: failed to allocate memory for socket buffer '%s'\n", strerror(errno)); + break; + } + context->snaplen = snaplen; + + struct event *ev = event_new(base, context->sock, EV_READ | EV_PERSIST, read_callback, context); + if (ev == NULL) { + syslog(LOG_ALERT, "event_new: failed to allocate memory for libevent event '%s'\n", strerror(errno)); + break; + } + event_add(ev, NULL); + + strncpy(context->intf, intf, sizeof(context->intf) - 1); + context->intf[sizeof(context->intf) - 1] = '\0'; + + rv = 0; + } while (0); + + return rv; +} + +/** + * @code initialize_intf_mac_and_ip_addr(context); + * + * @brief initializes device (interface) mac/ip addresses + * + * @param context pointer to device (interface) context + * + * @return 0 on success, otherwise for failure + */ +static int initialize_intf_mac_and_ip_addr(dhcp_device_context_t *context) +{ + int rv = -1; + + do { + int fd; + struct ifreq ifr; + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + syslog(LOG_ALERT, "socket: %s", strerror(errno)); + break; + } + + ifr.ifr_addr.sa_family = AF_INET; + strncpy(ifr.ifr_name, context->intf, sizeof(ifr.ifr_name) - 1); + ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; + + // Get network address + if (ioctl(fd, SIOCGIFADDR, &ifr) == -1) { + syslog(LOG_ALERT, "ioctl: %s", explain_ioctl(fd, SIOCGIFADDR, &ifr)); + break; + } + context->ip = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr; + + // Get mac address + if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) { + syslog(LOG_ALERT, "ioctl: %s", explain_ioctl(fd, SIOCGIFHWADDR, &ifr)); + break; + } + memcpy(context->mac, ifr.ifr_hwaddr.sa_data, sizeof(context->mac)); + + close(fd); + + rv = 0; + } while (0); + + return rv; +} + +/** + * @code dhcp_device_init(context, intf, snaplen, is_uplink, base); + * + * @brief initializes device (interface) that handles packet capture per interface. + */ +int dhcp_device_init(dhcp_device_context_t **context, + const char *intf, + int snaplen, + uint8_t is_uplink, + struct event_base *base) +{ + int rv = -1; + dhcp_device_context_t *dev_context = NULL; + + if ((context != NULL) && (strlen(intf) < sizeof(dev_context->intf))) { + + dev_context = (dhcp_device_context_t *) malloc(sizeof(dhcp_device_context_t)); + if (dev_context != NULL) { + if ((init_socket(dev_context, intf, snaplen, base) == 0) && + (initialize_intf_mac_and_ip_addr(dev_context) == 0 ) ) { + + dev_context->is_uplink = is_uplink; + + memset(&dev_context->counters, 0, sizeof(dev_context->counters)); + memset(&dev_context->counters_snapshot, 0, sizeof(dev_context->counters_snapshot)); + + *context = dev_context; + rv = 0; + } + } + else { + syslog(LOG_ALERT, "malloc: failed to allocated device context memory for '%s'", dev_context->intf); + } + } + + return rv; +} + +/** + * @code dhcp_device_shutdown(context); + * + * @brief shuts down device (interface). Also, stops packet capture on interface and cleans up any allocated memory + */ +void dhcp_device_shutdown(dhcp_device_context_t *context) +{ + free(context); +} + +/** + * @code dhcp_device_get_status(context); + * + * @brief collects DHCP relay status info for a given interface. If context is null, it will report aggregate + * status + */ +dhcp_mon_status_t dhcp_device_get_status(dhcp_device_context_t *context) +{ + dhcp_mon_status_t rv = 0; + + if (context != NULL) { + rv = dhcp_device_validate(context->counters, context->counters_snapshot); + memcpy(context->counters_snapshot, context->counters, sizeof(context->counters_snapshot)); + } else { + rv = dhcp_device_validate(glob_counters, glob_counters_snapshot); + memcpy(glob_counters_snapshot, glob_counters, sizeof(glob_counters_snapshot)); + } + + return rv; +} + +/** + * @code dhcp_device_print_status(); + * + * @brief prints status counters to syslog. If context is null, it will print aggregate status + */ +void dhcp_device_print_status(dhcp_device_context_t *context) +{ + if (context != NULL) { + dhcp_print_counters(context->counters); + } else { + dhcp_print_counters(glob_counters); + } +} diff --git a/src/dhcpmon/src/dhcp_device.h b/src/dhcpmon/src/dhcp_device.h new file mode 100644 index 000000000000..04113eeabdc0 --- /dev/null +++ b/src/dhcpmon/src/dhcp_device.h @@ -0,0 +1,113 @@ +/** + * @file dhcp_device.h + * + * device (interface) module + */ + +#ifndef DHCP_DEVICE_H_ +#define DHCP_DEVICE_H_ + +#include +#include +#include +#include + +#include +#include +#include + + +/** packet direction */ +typedef enum +{ + DHCP_RX, /** RX DHCP packet */ + DHCP_TX, /** TX DHCP packet */ + + DHCP_DIR_COUNT +} dhcp_packet_direction_t; + +/** dhcp health status */ +typedef enum +{ + DHCP_MON_STATUS_HEALTHY, /** DHCP relay is healthy */ + DHCP_MON_STATUS_UNHEALTHY, /** DHCP relay is unhealthy and is missing out on some packets */ + DHCP_MON_STATUS_INDETERMINATE, /** DHCP relay health could not be determined */ +} dhcp_mon_status_t; + +/** DHCP device (interface) health counters */ +typedef struct +{ + uint64_t discover; /** DHCP discover packets */ + uint64_t offer; /** DHCP offer packets */ + uint64_t request; /** DHCP request packets */ + uint64_t ack; /** DHCP ack packets */ +} dhcp_device_counters_t; + +/** DHCP device (interface) context */ +typedef struct +{ + int sock; /** Raw socket associated with this device/interface */ + in_addr_t ip; /** network address of this device (interface) */ + uint8_t mac[ETHER_ADDR_LEN]; /** hardware address of this device (interface) */ + uint8_t is_uplink; /** north interface? */ + char intf[IF_NAMESIZE]; /** device (interface) name */ + uint8_t *buffer; /** buffer used to read socket data */ + size_t snaplen; /** snap length or buffer size */ + dhcp_device_counters_t counters[DHCP_DIR_COUNT]; + /** current coutners of DORA packets */ + dhcp_device_counters_t counters_snapshot[DHCP_DIR_COUNT]; + /** counter snapshot */ +} dhcp_device_context_t; + +/** + * @code dhcp_device_init(context, intf, snaplen, timeout_ms, is_uplink, base); + * + * @brief initializes device (interface) that handles packet capture per interface. + * + * @param context(inout) pointer to device (interface) context + * @param intf interface name + * @param snaplen length of packet capture + * @param is_uplink uplink interface + * @param base pointer to libevent base + * + * @return 0 on success, otherwise for failure + */ +int dhcp_device_init(dhcp_device_context_t **context, + const char *intf, + int snaplen, + uint8_t is_uplink, + struct event_base *base); + +/** + * @code dhcp_device_shutdown(context); + * + * @brief shuts down device (interface). Also, stops packet capture on interface and cleans up any allocated memory + * + * @param context Device (interface) context + * + * @return nonedhcp_device_shutdown + */ +void dhcp_device_shutdown(dhcp_device_context_t *context); + +/** + * @code dhcp_device_get_status(context); + * + * @brief collects DHCP relay status info for a given interface. If context is null, it will report aggregate + * status + * + * @param context Device (interface) context + * + * @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE + */ +dhcp_mon_status_t dhcp_device_get_status(dhcp_device_context_t *context); + +/** + * @code dhcp_device_print_status(); + * + * @brief prints status counters to syslog. If context is null, it will print aggregate status + * + * @return none + */ +void dhcp_device_print_status(dhcp_device_context_t *context); + +#endif /* DHCP_DEVICE_H_ */ diff --git a/src/dhcpmon/src/dhcp_devman.c b/src/dhcpmon/src/dhcp_devman.c new file mode 100644 index 000000000000..c19cbde591b8 --- /dev/null +++ b/src/dhcpmon/src/dhcp_devman.c @@ -0,0 +1,149 @@ +/** + * @file dhcp_devman.c + * + * Device (interface) manager + */ +#include +#include +#include +#include +#include +#include + +#include "dhcp_devman.h" + +/** struct for interface information */ +struct intf +{ + const char *name; /** interface name */ + uint8_t is_uplink; /** is uplink (north) interface */ + dhcp_device_context_t *dev_context; /** device (interface_ context */ + LIST_ENTRY(intf) entry; /** list link/pointers entries */ +}; + +/** intfs list of interfaces */ +static LIST_HEAD(intf_list, intf) intfs; +/** dhcp_num_south_intf number of south interfaces */ +static uint32_t dhcp_num_south_intf = 0; +/** dhcp_num_north_intf number of north interfaces */ +static uint32_t dhcp_num_north_intf = 0; + +/** + * @code dhcp_devman_init(); + * + * initializes device (interface) manager that keeps track of interfaces and assert that there is one south + * interface and as many north interfaces + */ +void dhcp_devman_init() +{ + LIST_INIT(&intfs); +} + +/** + * @code dhcp_devman_shutdown(); + * + * shuts down device (interface) manager. Also, stops packet capture on interface and cleans up any allocated + * memory + */ +void dhcp_devman_shutdown() +{ + struct intf *int_ptr, *prev_intf = NULL; + + LIST_FOREACH(int_ptr, &intfs, entry) { + dhcp_device_shutdown(int_ptr->dev_context); + if (prev_intf) { + LIST_REMOVE(prev_intf, entry); + free(prev_intf); + prev_intf = int_ptr; + } + } + + if (prev_intf) { + LIST_REMOVE(prev_intf, entry); + free(prev_intf); + } +} + +/** + * @code dhcp_devman_add_intf(name, uplink); + * + * @brief adds interface to the device manager. + */ +int dhcp_devman_add_intf(const char *name, uint8_t is_uplink) +{ + int rv = -1; + struct intf *dev = malloc(sizeof(struct intf)); + + if (dev != NULL) { + dev->name = name; + dev->is_uplink = is_uplink; + if (is_uplink) { + dhcp_num_north_intf++; + } else { + dhcp_num_south_intf++; + assert(dhcp_num_south_intf <= 1); + } + + LIST_INSERT_HEAD(&intfs, dev, entry); + + rv = 0; + } + else { + syslog(LOG_ALERT, "malloc: failed to allocate memory for intf '%s'\n", name); + } + + return rv; +} + +/** + * @code dhcp_devman_start_capture(snaplen, base); + * + * @brief start packet capture on the devman interface list + */ +int dhcp_devman_start_capture(int snaplen, struct event_base *base) +{ + int rv = -1; + struct intf *int_ptr; + + if ((dhcp_num_south_intf == 1) && (dhcp_num_north_intf >= 1)) { + LIST_FOREACH(int_ptr, &intfs, entry) { + rv = dhcp_device_init(&int_ptr->dev_context, int_ptr->name, snaplen, int_ptr->is_uplink, base); + if (rv == 0) { + syslog(LOG_INFO, + "Capturing DHCP packets on interface %s, ip: 0x%08x, mac [%02x:%02x:%02x:%02x:%02x:%02x] \n", + int_ptr->name, int_ptr->dev_context->ip, int_ptr->dev_context->mac[0], + int_ptr->dev_context->mac[1], int_ptr->dev_context->mac[2], int_ptr->dev_context->mac[3], + int_ptr->dev_context->mac[4], int_ptr->dev_context->mac[5]); + } + else { + break; + } + } + } + else { + syslog(LOG_ERR, "Invalid number of interfaces, downlink/south %d, uplink/north %d\n", + dhcp_num_south_intf, dhcp_num_north_intf); + } + + return rv; +} + +/** + * @code dhcp_devman_get_status(); + * + * @brief collects DHCP relay status info. + */ +dhcp_mon_status_t dhcp_devman_get_status() +{ + return dhcp_device_get_status(NULL); +} + +/** + * @code dhcp_devman_print_status(); + * + * @brief prints status counters to syslog + */ +void dhcp_devman_print_status() +{ + dhcp_device_print_status(NULL); +} diff --git a/src/dhcpmon/src/dhcp_devman.h b/src/dhcpmon/src/dhcp_devman.h new file mode 100644 index 000000000000..a0753b4b93a1 --- /dev/null +++ b/src/dhcpmon/src/dhcp_devman.h @@ -0,0 +1,76 @@ +/** + * @file dhcp_devman.h + * + * Device (interface) manager + */ + +#ifndef DHCP_DEVMAN_H_ +#define DHCP_DEVMAN_H_ + +#include + +#include "dhcp_device.h" + +/** + * @code dhcp_devman_init(); + * + * @brief initializes device (interface) manager that keeps track of interfaces and assert that there is one south + * interface and as many north interfaces + * + * @return none + */ +void dhcp_devman_init(); + +/** + * @code dhcp_devman_shutdown(); + * + * @brief shuts down device (interface) manager. Also, stops packet capture on interface and cleans up any allocated + * memory + * + * @return none + */ +void dhcp_devman_shutdown(); + +/** + * @code dhcp_devman_add_intf(name, uplink); + * + * @brief adds interface to the device manager. + * + * @param name interface name + * @param is_uplink true for uplink (north) interface + * + * @return 0 on success, nonzero otherwise + */ +int dhcp_devman_add_intf(const char *name, uint8_t is_uplink); + +/** + * @code dhcp_devman_start_capture(snaplen, timeout_ms); + * + * @brief start packet capture on the devman interface list + * + * @param snaplen packet capture snap length + * @param base libevent base + * + * @return 0 on success, nonzero otherwise + */ +int dhcp_devman_start_capture(int snaplen, struct event_base *base); + +/** + * @code dhcp_devman_get_status(); + * + * @brief collects DHCP relay status info. + * + * @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE + */ +dhcp_mon_status_t dhcp_devman_get_status(); + +/** + * @code dhcp_devman_print_status(); + * + * @brief prints status counters to syslog + * + * @return none + */ +void dhcp_devman_print_status(); + +#endif /* DHCP_DEVMAN_H_ */ diff --git a/src/dhcpmon/src/dhcp_mon.c b/src/dhcpmon/src/dhcp_mon.c new file mode 100644 index 000000000000..dc0a7d94f149 --- /dev/null +++ b/src/dhcpmon/src/dhcp_mon.c @@ -0,0 +1,199 @@ +/** + * @file dhcp_mon.c + * + * @brief dhcp relay monitor module + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dhcp_mon.h" +#include "dhcp_devman.h" + +/** window_interval_sec monitoring window for dhcp relay health checks */ +static int window_interval_sec = 12; +/** dhcp_unhealthy_max_count max count of consecutive unhealthy statuses before reporting to syslog */ +static int dhcp_unhealthy_max_count = 10; +/** libevent base struct */ +static struct event_base *base; +/** libevent timeout event struct */ +static struct event *ev_timeout = NULL; +/** libevent SIGINT signal event struct */ +static struct event *ev_sigint; +/** libevent SIGTERM signal event struct */ +static struct event *ev_sigterm; + +/** + * @code signal_callback(fd, event, arg); + * + * @brief signal handler for dhcpmon. It will initiate shutdown when signal is caught + * + * @param fd libevent socket + * @param event event triggered + * @param arg pointer user provided context (libevent base) + * + * @return none + */ +static void signal_callback(evutil_socket_t fd, short event, void *arg) +{ + syslog(LOG_ALERT, "Received signal %d\n", event); + dhcp_devman_print_status(); + dhcp_mon_stop(); +} + +/** + * @code timeout_callback(fd, event, arg); + * + * @brief periodic timer call back + * + * @param fd libevent socket + * @param event event triggered + * @param arg pointer user provided context (libevent base) + * + * @return none + */ +static void timeout_callback(evutil_socket_t fd, short event, void *arg) +{ + static int count = 0; + dhcp_mon_status_t dhcp_mon_status = dhcp_devman_get_status(); + + switch (dhcp_mon_status) + { + case DHCP_MON_STATUS_UNHEALTHY: + if (++count > dhcp_unhealthy_max_count) { + syslog(LOG_ALERT, "DHCP Relay is not healthy after %d health checks\n", count); + } + break; + case DHCP_MON_STATUS_HEALTHY: + if (count > 0) { + count = 0; + } + break; + case DHCP_MON_STATUS_INDETERMINATE: + break; + default: + syslog(LOG_ERR, "DHCP Relay returned unknown status %d\n", dhcp_mon_status); + break; + } +} + +/** + * @code dhcp_mon_init(window_sec, max_count); + * + * initializes event base and periodic timer event that continuously collects dhcp relay health status every window_sec + * seconds. It also writes to syslog when dhcp relay has been unhealthy for consecutive max_count checks. + * + */ +int dhcp_mon_init(int window_sec, int max_count) +{ + int rv = -1; + + do { + window_interval_sec = window_sec; + dhcp_unhealthy_max_count = max_count; + + base = event_base_new(); + if (base == NULL) { + syslog(LOG_ERR, "Could not initialize libevent!\n"); + break; + } + + ev_sigint = evsignal_new(base, SIGINT, signal_callback, base); + if (ev_sigint == NULL) { + syslog(LOG_ERR, "Could not create SIGINT libevent signal!\n"); + break; + } + + ev_sigterm = evsignal_new(base, SIGTERM, signal_callback, base); + if (ev_sigterm == NULL) { + syslog(LOG_ERR, "Could not create SIGTERM libevent signal!\n"); + break; + } + + ev_timeout = event_new(base, -1, EV_PERSIST, timeout_callback, base); + if (ev_timeout == NULL) { + syslog(LOG_ERR, "Could not create libevent timer!\n"); + break; + } + + rv = 0; + } while (0); + + return rv; +} + +/** + * @code dhcp_mon_shutdown(); + * + * @brief shuts down libevent loop + */ +void dhcp_mon_shutdown() +{ + event_del(ev_timeout); + event_del(ev_sigint); + event_del(ev_sigterm); + + event_free(ev_timeout); + event_free(ev_sigint); + event_free(ev_sigterm); + + event_base_free(base); +} + +/** + * @code dhcp_mon_start(snaplen); + * + * @brief start monitoring DHCP Relay + */ +int dhcp_mon_start(int snaplen) +{ + int rv = -1; + + do + { + if (dhcp_devman_start_capture(snaplen, base) != 0) { + break; + } + + if (evsignal_add(ev_sigint, NULL) != 0) { + syslog(LOG_ERR, "Could not add SIGINT libevent signal!\n"); + break; + } + + if (evsignal_add(ev_sigterm, NULL) != 0) { + syslog(LOG_ERR, "Could not add SIGTERM libevent signal!\n"); + break; + } + + struct timeval event_time = {.tv_sec = window_interval_sec, .tv_usec = 0}; + if (evtimer_add(ev_timeout, &event_time) != 0) { + syslog(LOG_ERR, "Could not add event timer to libevent!\n"); + break; + } + + if (event_base_dispatch(base) != 0) { + syslog(LOG_ERR, "Could not start libevent dispatching loop!\n"); + break; + } + + rv = 0; + } while (0); + + return rv; +} + +/** + * @code dhcp_mon_stop(); + * + * @brief stop monitoring DHCP Relay + */ +void dhcp_mon_stop() +{ + event_base_loopexit(base, NULL); +} diff --git a/src/dhcpmon/src/dhcp_mon.h b/src/dhcpmon/src/dhcp_mon.h new file mode 100644 index 000000000000..44d361b32ec0 --- /dev/null +++ b/src/dhcpmon/src/dhcp_mon.h @@ -0,0 +1,54 @@ +/** + * @file dhcp_mon.h + * + * @brief dhcp relay monitor module + * + */ + +#ifndef DHCP_MON_H_ +#define DHCP_MON_H_ + +/** + * @code dhcp_mon_init(window_ssec, max_count); + * + * @brief initializes event base and periodic timer event that continuously collects dhcp relay health status every + * window_sec seconds. It also writes to syslog when dhcp relay has been unhealthy for consecutive max_count + * checks. + * + * @param window_sec time interval between health checks + * @param max_count max count of consecutive unhealthy statuses before reporting to syslog + * + * @return 0 upon success, otherwise upon failure + */ +int dhcp_mon_init(int window_sec, int max_count); + +/** + * @code dhcp_mon_shutdown(); + * + * @brief shuts down libevent loop + * + * @return none + */ +void dhcp_mon_shutdown(); + +/** + * @code dhcp_mon_start(snaplen); + * + * @brief start monitoring DHCP Relay + * + * @param snaplen packet capture length + * + * @return 0 upon success, otherwise upon failure + */ +int dhcp_mon_start(int snaplen); + +/** + * @code dhcp_mon_stop(); + * + * @brief stop monitoring DHCP Relay + * + * @return none + */ +void dhcp_mon_stop(); + +#endif /* DHCP_MON_H_ */ diff --git a/src/dhcpmon/src/main.c b/src/dhcpmon/src/main.c new file mode 100644 index 000000000000..11eab6ee9ea1 --- /dev/null +++ b/src/dhcpmon/src/main.c @@ -0,0 +1,174 @@ +/** + * @file main.c + * + * @brief: Main entry point for dhcpmon utility. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dhcp_mon.h" +#include "dhcp_devman.h" + +/** dhcpmon_default_snaplen: default snap length of packet being captured */ +static const uint32_t dhcpmon_default_snaplen = 65535; +/** dhcpmon_default_health_check_window: default value for a time window, during which DHCP DORA packet counts are being + * collected */ +static const uint32_t dhcpmon_default_health_check_window = 12; +/** dhcpmon_default_unhealthy_max_count: default max consecutive unhealthy status reported before reporting an issue + * with DHCP relay */ +static const uint32_t dhcpmon_default_unhealthy_max_count = 10; + +/** + * @code usage(prog); + * + * @brief prints help message about how to use dhcpmon utility + * + * @param prog program name + * + * @return none + */ +static void usage(const char *prog) +{ + printf("Usage: %s -id {-iu }+ [-w ]" + "[-c ] [-s ] [-d]\n", prog); + printf("where\n"); + printf("\tsouth interface: is a vlan interface,\n"); + printf("\tnorth interface: is a TOR-T1 interface,\n"); + printf("\tsnapshot window: during which DHCP counters are gathered and DHCP status is validated (default %d),\n", + dhcpmon_default_health_check_window); + printf("\tunhealthy status count: count of consecutive unhealthy status before writing an alert to syslog " + "(default %d),\n", + dhcpmon_default_unhealthy_max_count); + printf("\tsnap length: snap length of packet capture (default %d),\n", dhcpmon_default_snaplen); + printf("\t-d: daemonize %s.\n", prog); + + exit(EXIT_SUCCESS); +} + +/** + * @code dhcpmon_daemonize(); + * + * @brief make this utility run as a daemon. + * + * @return none + */ +static void dhcpmon_daemonize() +{ + pid_t pid, sid; + pid = fork(); + if (pid < 0) { + syslog(LOG_ALERT, "fork: %s", strerror(errno)); + exit(EXIT_FAILURE); + } + + if (pid > 0) { + exit(EXIT_SUCCESS); + } + + // this is the daemon running now + umask(0); + // Create a new SID for the child process + sid = setsid(); + if (sid < 0) { + syslog(LOG_ALERT, "setsid: %s", strerror(errno)); + exit(EXIT_FAILURE); + } + + // Change the current working directory + if ((chdir("/")) < 0) { + syslog(LOG_ALERT, "chdir: %s", strerror(errno)); + exit(EXIT_FAILURE); + } + + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); +} + +/** + * @code main(argc, argv); + * + * @brief main entry point of dhcpmon utility + * + * @return int 0 on success, otherwise on failure + */ +int main(int argc, char **argv) +{ + int rv = EXIT_FAILURE; + int i; + int window_interval = dhcpmon_default_health_check_window; + int max_unhealthy_count = dhcpmon_default_unhealthy_max_count; + uint32_t snaplen = dhcpmon_default_snaplen; + int make_daemon = 0; + + setlogmask(LOG_UPTO(LOG_INFO)); + openlog(basename(argv[0]), LOG_CONS | LOG_PID | LOG_NDELAY, LOG_DAEMON); + + dhcp_devman_init(); + + for (i = 1; i < argc;) { + if ((argv[i] == NULL) || (argv[i][0] != '-')) { + break; + } + switch (argv[i][1]) + { + case 'h': + usage(basename(argv[0])); + break; + case 'i': + if (dhcp_devman_add_intf(argv[i + 1], argv[i][2] == 'u') != 0) { + usage(basename(argv[0])); + } + i += 2; + break; + case 'd': + make_daemon = 1; + i++; + break; + case 's': + snaplen = atoi(argv[i + 1]); + i += 2; + break; + case 'w': + window_interval = atoi(argv[i + 1]); + i += 2; + break; + case 'c': + max_unhealthy_count = atoi(argv[i + 1]); + i += 2; + break; + default: + fprintf(stderr, "%s: %c: Unknown option\n", basename(argv[0]), argv[i][1]); + usage(basename(argv[0])); + } + } + + if (make_daemon) { + dhcpmon_daemonize(); + } + + if ((dhcp_mon_init(window_interval, max_unhealthy_count) == 0) && + (dhcp_mon_start(snaplen) == 0)) { + + rv = EXIT_SUCCESS; + + dhcp_mon_shutdown(); + } + + dhcp_devman_shutdown(); + + closelog(); + + return rv; +} diff --git a/src/dhcpmon/src/subdir.mk b/src/dhcpmon/src/subdir.mk new file mode 100644 index 000000000000..324977aa39f7 --- /dev/null +++ b/src/dhcpmon/src/subdir.mk @@ -0,0 +1,29 @@ +# Add inputs and outputs from these tool invocations to the build variables +CC := gcc + +C_SRCS += \ +../src/dhcp_device.c \ +../src/dhcp_devman.c \ +../src/dhcp_mon.c \ +../src/main.c + +OBJS += \ +./src/dhcp_device.o \ +./src/dhcp_devman.o \ +./src/dhcp_mon.o \ +./src/main.o + +C_DEPS += \ +./src/dhcp_device.d \ +./src/dhcp_devman.d \ +./src/dhcp_mon.d \ +./src/main.d + + +# Each subdirectory must supply rules for building sources it contributes +src/%.o: ../src/%.c + @echo 'Building file: $<' + @echo 'Invoking: GCC C Compiler' + $(CC) -O3 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' diff --git a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf index bae273eeaf81..a29982a646f4 100644 --- a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf +++ b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf @@ -37,3 +37,16 @@ stdout_logfile=syslog stderr_logfile=syslog +[group:dhcpmon] +programs=dhcpmon-Vlan1000 + +[program:dhcpmon-Vlan1000] +command=/usr/sbin/dhcpmon -id Vlan1000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + + + From 68499e681f533be96e5e0bc21c4a4acaccd0861d Mon Sep 17 00:00:00 2001 From: Iris Hsu Date: Thu, 9 Jan 2020 00:01:06 +0800 Subject: [PATCH 55/66] [sonic-mgmt]: Install python-subnettree to sonic-mgmt container. (#3978) * Install python-subnettree to sonic-mgmt container. --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 4c53baf7c485..4a7e1a977549 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -143,4 +143,6 @@ RUN azure-cli_bundle_*/installer # TODO: if azure-cli contains newer version azure-keyvault, remove this RUN ~/lib/azure-cli/bin/python -m pip install azure-keyvault==0.3.7 -U +RUN pip install pysubnettree + RUN git clone https://github.com/Azure/sonic-mgmt From c4755192b1ecdd256f842a86cb999b82a1e9e2e6 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Wed, 8 Jan 2020 14:37:06 -0800 Subject: [PATCH 56/66] Fix bug: chroot command line (#3972) --- files/build_templates/sonic_debian_extension.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index e5dd9d9e0912..7e24df158f59 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -170,7 +170,7 @@ sudo sed -i -e '/^passwd/s/ tacplus//' $FILESYSTEM_ROOT/etc/nsswitch.conf # Install a custom version of kdump-tools (and its dependencies via 'apt-get -y install -f') sudo DEBIAN_FRONTEND=noninteractive dpkg --root=$FILESYSTEM_ROOT -i $debs_path/kdump-tools_*.deb || \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=truechroot $FILESYSTEM_ROOT apt-get -q --no-install-suggests --no-install-recommends --force-no install + sudo LANG=C DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true chroot $FILESYSTEM_ROOT apt-get -q --no-install-suggests --no-install-recommends --force-no install # Install custom-built monit package and SONiC configuration files sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/monit_*.deb || \ From 483a5946a85793a7fba0aa329e6fec21e9091c87 Mon Sep 17 00:00:00 2001 From: lguohan Date: Fri, 10 Jan 2020 08:27:34 -0800 Subject: [PATCH 57/66] Revert "[MultiDB]except src and dockers : replace redis-cli with sonic-db-cli and use new DBConnector (#3928)" (#4002) This reverts commit 0dae59ac301f18e7dad948282addf961b69d82fc. --- .../x86_64-mlnx_msn2700-r0/plugins/sfputil.py | 9 +++-- files/build_templates/docker_image_ctl.j2 | 34 +++++++++---------- files/image_config/config-setup/config-setup | 11 +++--- files/image_config/updategraph/updategraph | 10 +++--- .../warmboot-finalizer/finalize-warmboot.sh | 10 +++--- files/scripts/configdb-load.sh | 2 +- files/scripts/swss.sh | 26 +++++++------- files/scripts/syncd.sh | 12 ++++--- .../s9180-32x/utils/qsfp_monitor.sh | 2 +- .../s9280-64x/utils/qsfp_monitor.sh | 2 +- .../s8810-32q/utils/qsfp_monitor.sh | 2 +- .../s8900-54xc/utils/qsfp_monitor.sh | 2 +- .../s8900-64xc/utils/qsfp_monitor.sh | 2 +- .../s9100/utils/qsfp_monitor.sh | 2 +- .../s9200-64x/utils/qsfp_monitor.sh | 2 +- .../s9130-32x/utils/qsfp_monitor.sh | 2 +- .../s9230-64x/utils/qsfp_monitor.sh | 2 +- 17 files changed, 72 insertions(+), 60 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index 7c4f33f74973..e41ac2924da2 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -22,6 +22,8 @@ SFP_I2C_PAGE_SIZE = 256 # parameters for DB connection +REDIS_HOSTNAME = "localhost" +REDIS_PORT = 6379 REDIS_TIMEOUT_USECS = 0 # parameters for SFP presence @@ -188,9 +190,10 @@ def get_transceiver_change_event(self, timeout=0): if self.db_sel == None: from swsscommon import swsscommon - self.state_db = swsscommon.DBConnector("STATE_DB", - REDIS_TIMEOUT_USECS, - True)) + self.state_db = swsscommon.DBConnector(swsscommon.STATE_DB, + REDIS_HOSTNAME, + REDIS_PORT, + REDIS_TIMEOUT_USECS) # Subscribe to state table for SFP change notifications self.db_sel = swsscommon.Select() diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index df236f6523e8..167a392730e4 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -63,20 +63,20 @@ function preStartAction() docker cp /tmp/dump.rdb database:/var/lib/redis/ fi {%- elif docker_container_name == "snmp" %} - sonic-db-cli STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) - vrfenabled=`sonic-db-cli CONFIG_DB hget "MGMT_VRF_CONFIG|vrf_global" mgmtVrfEnabled` - v1SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" DestIp` - v1SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" DestPort` - v1Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" vrf` - v1Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" Community` - v2SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" DestIp` - v2SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" DestPort` - v2Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" vrf` - v2Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" Community` - v3SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" DestIp` - v3SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" DestPort` - v3Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" vrf` - v3Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" Community` + 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 @@ -113,7 +113,7 @@ function preStartAction() fi echo -n "" > /tmp/snmpagentaddr.yml - keys=`sonic-db-cli CONFIG_DB keys "SNMP_AGENT_ADDRESS_CONFIG|*"` + 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` @@ -151,10 +151,10 @@ function postStartAction() if [[ "$BOOT_TYPE" == "fast" ]]; then # set the key to expire in 3 minutes - sonic-db-cli STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180" + redis-cli -n 6 SET "FAST_REBOOT|system" "1" "EX" "180" fi - sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" + redis-cli -n 4 SET "CONFIG_DB_INITIALIZED" "1" fi if [[ -x /usr/bin/db_migrator.py ]]; then diff --git a/files/image_config/config-setup/config-setup b/files/image_config/config-setup/config-setup index f19abd266e95..bd497d06b257 100755 --- a/files/image_config/config-setup/config-setup +++ b/files/image_config/config-setup/config-setup @@ -25,6 +25,7 @@ ########################################################################### # Initialize constants +CONFIG_DB_INDEX=4 UPDATEGRAPH_CONF=/etc/sonic/updategraph.conf CONFIG_DB_JSON=/etc/sonic/config_db.json MINGRAPH_FILE=/etc/sonic/minigraph.xml @@ -106,9 +107,9 @@ reload_minigraph() if [ ! -f /etc/sonic/init_cfg.json ]; then echo "{}" > /etc/sonic/init_cfg.json fi - sonic-db-cli CONFIG_DB FLUSHDB + redis-cli -n $CONFIG_DB_INDEX FLUSHDB sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --write-to-db - sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" + redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" if [ -f /etc/sonic/acl.json ]; then acl-loader update full /etc/sonic/acl.json fi @@ -137,7 +138,7 @@ function copy_config_files_and_directories() # Check if SONiC swich has booted after a warm reboot request check_system_warm_boot() { - SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + 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" @@ -186,7 +187,7 @@ load_config() return 1 fi - sonic-db-cli CONFIG_DB FLUSHDB + redis-cli -n $CONFIG_DB_INDEX FLUSHDB sonic-cfggen -j ${CONFIG_FILE} --write-to-db if [ $? -ne 0 ]; then return $? @@ -197,7 +198,7 @@ load_config() /usr/bin/db_migrator.py -o migrate fi - sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" + redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" return 0 } diff --git a/files/image_config/updategraph/updategraph b/files/image_config/updategraph/updategraph index a24d452b1ad2..b2bd027e82e7 100755 --- a/files/image_config/updategraph/updategraph +++ b/files/image_config/updategraph/updategraph @@ -1,14 +1,16 @@ #!/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 - sonic-db-cli CONFIG_DB FLUSHDB + redis-cli -n $CONFIG_DB_INDEX FLUSHDB sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --write-to-db - sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" + redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" if [ -f /etc/sonic/acl.json ]; then acl-loader update full /etc/sonic/acl.json fi @@ -75,9 +77,9 @@ if [ "$src" = "dhcp" ]; then else cp -f /tmp/device_meta.json /etc/sonic/config_db.json fi - sonic-db-cli CONFIG_DB FLUSHDB + redis-cli -n $CONFIG_DB_INDEX FLUSHDB sonic-cfggen -j /etc/sonic/config_db.json --write-to-db - sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" + redis-cli -n $CONFIG_DB_INDEX 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 eec50ccef692..32c9c8444cc3 100755 --- a/files/image_config/warmboot-finalizer/finalize-warmboot.sh +++ b/files/image_config/warmboot-finalizer/finalize-warmboot.sh @@ -20,7 +20,7 @@ function debug() function check_warm_boot() { - WARM_BOOT=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + WARM_BOOT=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` } @@ -29,10 +29,12 @@ function wait_for_database_service() debug "Wait for database to become ready..." # Wait for redis server start before database clean - /usr/bin/docker exec database ping_pong_db_insts + until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; + do sleep 1; + done # Wait for configDB initialization - until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done @@ -42,7 +44,7 @@ function wait_for_database_service() function get_component_state() { - sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|$1" state + /usr/bin/redis-cli -n 6 hget "WARM_RESTART_TABLE|$1" state } diff --git a/files/scripts/configdb-load.sh b/files/scripts/configdb-load.sh index e7080eb40f3d..5ba2e0e0bc7f 100755 --- a/files/scripts/configdb-load.sh +++ b/files/scripts/configdb-load.sh @@ -10,4 +10,4 @@ if [ -r /etc/sonic/config_db.json ]; then sonic-cfggen -j /etc/sonic/config_db.json --write-to-db fi -sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" +redis-cli -n 4 SET "CONFIG_DB_INITIALIZED" "1" diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index a14d03e40f50..93f311019d66 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -31,8 +31,8 @@ function unlock_service_state_change() function check_warm_boot() { - SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`/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` if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" else @@ -43,7 +43,7 @@ function check_warm_boot() function validate_restore_count() { if [[ x"$WARM_BOOT" == x"true" ]]; then - RESTORE_COUNT=`sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` + RESTORE_COUNT=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_TABLE|orchagent" restore_count` # We have to make sure db data has not been flushed. if [[ -z "$RESTORE_COUNT" ]]; then WARM_BOOT="false" @@ -54,10 +54,12 @@ function validate_restore_count() function wait_for_database_service() { # Wait for redis server start before database clean - /usr/bin/docker exec database ping_pong_db_insts + until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; + do sleep 1; + done # Wait for configDB initialization - until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -67,7 +69,7 @@ function wait_for_database_service() # $2 the string of a list of table prefixes function clean_up_tables() { - sonic-db-cli $1 EVAL " + redis-cli -n $1 EVAL " local tables = {$2} for i = 1, table.getn(tables) do local matches = redis.call('KEYS', tables[i]) @@ -112,11 +114,11 @@ start() { # Don't flush DB during warm boot if [[ x"$WARM_BOOT" != x"true" ]]; then debug "Flushing APP, ASIC, COUNTER, CONFIG, and partial STATE databases ..." - sonic-db-cli APPL_DB FLUSHDB - sonic-db-cli ASIC_DB FLUSHDB - sonic-db-cli COUNTERS_DB FLUSHDB - sonic-db-cli FLEX_COUNTER_DB FLUSHDB - clean_up_tables STATE_DB "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" + /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*'" fi # start service docker @@ -164,7 +166,7 @@ stop() { # encountered error, e.g. syncd crashed. And swss needs to # be restarted. debug "Clearing FAST_REBOOT flag..." - clean_up_tables STATE_DB "'FAST_REBOOT*'" + clean_up_tables 6 "'FAST_REBOOT*'" # Unlock has to happen before reaching out to peer service unlock_service_state_change diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 4b47e7ad4c45..05e5552a64b1 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -30,8 +30,8 @@ function unlock_service_state_change() function check_warm_boot() { - SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`/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 could be empty, always make WARM_BOOT meaningful. if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" @@ -43,10 +43,12 @@ function check_warm_boot() function wait_for_database_service() { # Wait for redis server start before database clean - /usr/bin/docker exec database ping_pong_db_insts + until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; + do sleep 1; + done # Wait for configDB initialization - until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -63,7 +65,7 @@ function getBootType() ;; *SONIC_BOOT_TYPE=fast*|*fast-reboot*) # check that the key exists - if [[ $(sonic-db-cli STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then + if [[ $(redis-cli -n 6 GET "FAST_REBOOT|system") == "1" ]]; then TYPE='fast' else TYPE='cold' diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh index 7776493bc20a..249f179216a6 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=`sonic-db-cli ASIC_DB HLEN HIDDEN` + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME 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 9213d115f656..23a3fd066bee 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=`sonic-db-cli ASIC_DB HLEN HIDDEN` + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh index 7776493bc20a..249f179216a6 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=`sonic-db-cli ASIC_DB HLEN HIDDEN` + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME 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 0a4ba20ab767..7f50d137bcb7 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=`sonic-db-cli ASIC_DB HLEN HIDDEN` + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME 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 b3192f2efb7a..36f9e53ef108 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=`sonic-db-cli ASIC_DB HLEN HIDDEN` + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME 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 7776493bc20a..249f179216a6 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=`sonic-db-cli ASIC_DB HLEN HIDDEN` + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME 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 47cfbb3ea008..51c49c1152f5 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=`sonic-db-cli ASIC_DB HLEN HIDDEN` + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME if [ "$result" == "3" ]; then return fi diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh index 7776493bc20a..249f179216a6 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=`sonic-db-cli ASIC_DB HLEN HIDDEN` + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME 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 9213d115f656..23a3fd066bee 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=`sonic-db-cli ASIC_DB HLEN HIDDEN` + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME if [ "$result" == "3" ]; then return fi From 856b4b64eb62b7a1cc9ddcaf7418a9a3128f130f Mon Sep 17 00:00:00 2001 From: Sujin Kang Date: Fri, 10 Jan 2020 09:47:13 -0800 Subject: [PATCH 58/66] [reboot cause]: Delay process-reboot-cause service until network connection is stable (#4003) --- files/build_templates/process-reboot-cause.timer | 9 +++++++++ files/build_templates/sonic_debian_extension.j2 | 5 +++++ .../process-reboot-cause/process-reboot-cause.service | 3 --- 3 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 files/build_templates/process-reboot-cause.timer diff --git a/files/build_templates/process-reboot-cause.timer b/files/build_templates/process-reboot-cause.timer new file mode 100644 index 000000000000..222c51a79a03 --- /dev/null +++ b/files/build_templates/process-reboot-cause.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Delays process-reboot-cause until network is stably connected + +[Timer] +OnBootSec=1min 30 sec +Unit=process-reboot-cause.service + +[Install] +WantedBy=timers.target diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 7e24df158f59..bdcb415839d4 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -295,6 +295,11 @@ sudo cp $IMAGE_CONFIGS/procdockerstatsd/procdockerstatsd.service $FILESYSTEM_RO echo "procdockerstatsd.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/procdockerstatsd/procdockerstatsd $FILESYSTEM_ROOT/usr/bin/ +# Copy systemd timer configuration +# It implements delayed start of services +sudo cp $BUILD_TEMPLATES/process-reboot-cause.timer $FILESYSTEM_ROOT/etc/systemd/system/ +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable process-reboot-cause.timer + # Copy process-reboot-cause service files sudo cp $IMAGE_CONFIGS/process-reboot-cause/process-reboot-cause.service $FILESYSTEM_ROOT/etc/systemd/system/ echo "process-reboot-cause.service" | sudo tee -a $GENERATED_SERVICE_FILE diff --git a/files/image_config/process-reboot-cause/process-reboot-cause.service b/files/image_config/process-reboot-cause/process-reboot-cause.service index a429339dbe58..b9821f60c420 100644 --- a/files/image_config/process-reboot-cause/process-reboot-cause.service +++ b/files/image_config/process-reboot-cause/process-reboot-cause.service @@ -5,6 +5,3 @@ After=rc-local.service [Service] Type=simple ExecStart=/usr/bin/process-reboot-cause - -[Install] -WantedBy=multi-user.target From bac6615bf5a946d68a28c2c6610fb02167eb97fe Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Sat, 11 Jan 2020 03:50:51 +0700 Subject: [PATCH 59/66] [device/celestica]: Fix xcvrd error (#3979) * [device/celestica]: add pmon_daemon_control config * [device/celestica]: update sfp index follow port_config * [device/celestica]: update get_watchdog to avoid multiple daemon try opening watchdog --- .../pmon_daemon_control.json | 3 +++ .../sonic_platform/chassis.py | 19 ++++++++++++++++--- .../x86_64-cel_e1031-r0/sonic_platform/sfp.py | 2 +- .../pmon_daemon_control.json | 3 +++ .../pmon_daemon_control.json | 3 +++ .../sonic_platform/chassis.py | 19 ++++++++++++++++--- .../sonic_platform/sfp.py | 2 +- .../pmon_daemon_control.json | 3 +++ 8 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 device/celestica/x86_64-cel_e1031-r0/pmon_daemon_control.json create mode 100644 device/celestica/x86_64-cel_midstone-r0/pmon_daemon_control.json create mode 100644 device/celestica/x86_64-cel_seastone-r0/pmon_daemon_control.json create mode 100644 device/celestica/x86_64-cel_silverstone-r0/pmon_daemon_control.json diff --git a/device/celestica/x86_64-cel_e1031-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_e1031-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/celestica/x86_64-cel_e1031-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py index 99eb49ce53e0..719170d831b7 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py @@ -19,7 +19,6 @@ from sonic_platform.fan import Fan from sonic_platform.psu import Psu from sonic_platform.component import Component - from sonic_platform.watchdog import Watchdog from sonic_platform.thermal import Thermal from sonic_platform.sfp import Sfp from sonic_platform.eeprom import Tlv @@ -54,7 +53,9 @@ def __init__(self): for index in range(0, NUM_THERMAL): thermal = Thermal(index) self._thermal_list.append(thermal) - for index in range(0, NUM_SFP): + # sfp index start from 1 + self._sfp_list.append(None) + for index in range(1, NUM_SFP+1): sfp = Sfp(index) self._sfp_list.append(sfp) for index in range(0, NUM_COMPONENT): @@ -63,7 +64,6 @@ def __init__(self): self._reboot_cause_path = HOST_REBOOT_CAUSE_PATH if self.__is_host( ) else PMON_REBOOT_CAUSE_PATH - self._watchdog = Watchdog() self._eeprom = Tlv() def __is_host(self): @@ -134,3 +134,16 @@ def get_reboot_cause(self): description = 'Unknown reason' return (reboot_cause, description) + + def get_watchdog(self): + """ + Retreives hardware watchdog device on this chassis + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + """ + if self._watchdog is None: + from sonic_platform.watchdog import Watchdog + self._watchdog = Watchdog() + + return self._watchdog diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py index 4cfdcf50b66d..6ef8838ba8af 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py @@ -94,7 +94,7 @@ class Sfp(SfpBase): def __init__(self, sfp_index): # Init index self.index = sfp_index - self.port_num = self.index + 1 + self.port_num = self.index # Init eeprom path eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' diff --git a/device/celestica/x86_64-cel_midstone-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_midstone-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/celestica/x86_64-cel_seastone-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_seastone-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py index c9447b56a2fe..7db46e55bd8c 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py @@ -19,7 +19,6 @@ from sonic_platform.fan import Fan from sonic_platform.psu import Psu from sonic_platform.component import Component - from sonic_platform.watchdog import Watchdog from sonic_platform.thermal import Thermal from sonic_platform.sfp import Sfp from sonic_platform.eeprom import Tlv @@ -56,14 +55,15 @@ def __init__(self): for index in range(0, NUM_THERMAL): thermal = Thermal(index) self._thermal_list.append(thermal) - for index in range(0, NUM_SFP): + # sfp index start from 1 + self._sfp_list.append(None) + for index in range(1, NUM_SFP+1): sfp = Sfp(index) self._sfp_list.append(sfp) for index in range(0, NUM_COMPONENT): component = Component(index) self._component_list.append(component) - self._watchdog = Watchdog() self._eeprom = Tlv() def __is_host(self): @@ -146,3 +146,16 @@ def get_reboot_cause(self): description = 'Unknown reason' return (reboot_cause, description) + + def get_watchdog(self): + """ + Retreives hardware watchdog device on this chassis + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + """ + if self._watchdog is None: + from sonic_platform.watchdog import Watchdog + self._watchdog = Watchdog() + + return self._watchdog diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py index 3a02be39df6e..04fb36b72b8f 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py @@ -100,7 +100,7 @@ class Sfp(SfpBase): def __init__(self, sfp_index): # Init index self.index = sfp_index - self.port_num = self.index + 1 if self.PORT_START == 1 else index + self.port_num = self.index # Init eeprom path eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' diff --git a/device/celestica/x86_64-cel_silverstone-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_silverstone-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} From e45ff4edb4944bfd8521239936a87e5816d65467 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:55:29 +0200 Subject: [PATCH 60/66] [build] make debian package install noninteractive (#3980) Otherwise, build process gets stuck because isc-dhcp-relay gives promt: ``` $ make SONIC_PROFILING_ON=y INSTALL_DEBUG_TOOLS=y SONIC_BUILD_JOBS=12 target/debs/stretch/isc-dhcp-relay_4.3.5-2_amd64.deb-install +++ --- Making target/debs/stretch/isc-dhcp-relay_4.3.5-2_amd64.deb-install --- +++ EXTRA_JESSIE_TARGETS=isc-dhcp-relay_4.3.5-2_amd64.deb-install make -f Makefile.work jessie make[1]: Entering directory `/build2/stepanb/hitless/sonic-buildimage' SONiC Build System Build Configuration "CONFIGURED_PLATFORM" : "mellanox" "CONFIGURED_ARCH" : "amd64" "SONIC_CONFIG_PRINT_DEPENDENCIES" : "" "SONIC_BUILD_JOBS" : "12" "SONIC_CONFIG_MAKE_JOBS" : "12" "SONIC_USE_DOCKER_BUILDKIT" : "" "USERNAME" : "admin" "PASSWORD" : "YourPaSsWoRd" "ENABLE_DHCP_GRAPH_SERVICE" : "" "SHUTDOWN_BGP_ON_START" : "" "ENABLE_PFCWD_ON_START" : "" "INSTALL_DEBUG_TOOLS" : "" "ROUTING_STACK" : "frr" "FRR_USER_UID" : "300" "FRR_USER_GID" : "300" "ENABLE_SYNCD_RPC" : "" "ENABLE_ORGANIZATION_EXTENSIONS" : "y" "HTTP_PROXY" : "" "HTTPS_PROXY" : "" "ENABLE_SYSTEM_TELEMETRY" : "y" "ENABLE_ZTP" : "" "SONIC_DEBUGGING_ON" : "" "SONIC_PROFILING_ON" : "" "KERNEL_PROCURE_METHOD" : "build" "BUILD_TIMESTAMP" : "20200106.124851" "BLDENV" : "" "VS_PREPARE_MEM" : "yes" "ENABLE_SFLOW" : "y" make: Nothing to be done for 'jessie'. make[1]: Leaving directory `/build2/stepanb/hitless/sonic-buildimage' BLDENV=stretch make -f Makefile.work target/debs/stretch/isc-dhcp-relay_4.3.5-2_amd64.deb-install make[1]: Entering directory `/build2/stepanb/hitless/sonic-buildimage' SONiC Build System Build Configuration "CONFIGURED_PLATFORM" : "mellanox" "CONFIGURED_ARCH" : "amd64" "SONIC_CONFIG_PRINT_DEPENDENCIES" : "" "SONIC_BUILD_JOBS" : "12" "SONIC_CONFIG_MAKE_JOBS" : "12" "SONIC_USE_DOCKER_BUILDKIT" : "" "USERNAME" : "admin" "PASSWORD" : "YourPaSsWoRd" "ENABLE_DHCP_GRAPH_SERVICE" : "" "SHUTDOWN_BGP_ON_START" : "" "ENABLE_PFCWD_ON_START" : "" "INSTALL_DEBUG_TOOLS" : "" "ROUTING_STACK" : "frr" "FRR_USER_UID" : "300" "FRR_USER_GID" : "300" "ENABLE_SYNCD_RPC" : "" "ENABLE_ORGANIZATION_EXTENSIONS" : "y" "HTTP_PROXY" : "" "HTTPS_PROXY" : "" "ENABLE_SYSTEM_TELEMETRY" : "y" "ENABLE_ZTP" : "" "SONIC_DEBUGGING_ON" : "" "SONIC_PROFILING_ON" : "" "KERNEL_PROCURE_METHOD" : "build" "BUILD_TIMESTAMP" : "20200106.124855" "BLDENV" : "stretch" "VS_PREPARE_MEM" : "yes" "ENABLE_SFLOW" : "y" [ 01 ] [ target/debs/stretch/isc-dhcp-relay_4.3.5-2_amd64.deb-install ] Servers the DHCP relay should forward requests to: Interfaces the DHCP relay should listen on: ``` Signed-off-by: Stepan Blyschak --- slave.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slave.mk b/slave.mk index 9a34e5379b14..8f8c4dd87890 100644 --- a/slave.mk +++ b/slave.mk @@ -399,7 +399,7 @@ $(SONIC_INSTALL_TARGETS) : $(DEBS_PATH)/%-install : .platform $$(addsuffix -inst # put a lock here because dpkg does not allow installing packages in parallel while true; do if mkdir $(DEBS_PATH)/dpkg_lock &> /dev/null; then - { sudo dpkg -i $(DEBS_PATH)/$* $(LOG) && rm -d $(DEBS_PATH)/dpkg_lock && break; } || { rm -d $(DEBS_PATH)/dpkg_lock && exit 1 ; } + { sudo DEBIAN_FRONTEND=noninteractive dpkg -i $(DEBS_PATH)/$* $(LOG) && rm -d $(DEBS_PATH)/dpkg_lock && break; } || { rm -d $(DEBS_PATH)/dpkg_lock && exit 1 ; } fi done $(FOOTER) From f3b5b13a7551f974128c62d2b3f51d20cc199525 Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Fri, 10 Jan 2020 12:56:42 -0800 Subject: [PATCH 61/66] [barefoot]: Update SDK package (#3950) Updated SDK package with X1/X2 profiles Signed-off-by: Andriy Kokhan --- platform/barefoot/bfn-platform.mk | 4 ++-- platform/barefoot/bfn-sai.mk | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 854026b52949..96c204d25ea0 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_20191227_deb9.deb +$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/bfnplatform_20191227_deb9.deb" 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..25c851de313c 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,5 +1,5 @@ -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_20191227_deb9.deb +$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/bfnsdk_20191227_deb9.deb" SONIC_ONLINE_DEBS += $(BFN_SAI) $(BFN_SAI_DEV)_DEPENDS += $(BFN_SAI) From aa67921d066b0b56022c2f08b37bf3ff8f8b8d82 Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Fri, 10 Jan 2020 13:01:24 -0800 Subject: [PATCH 62/66] [Monit] Change the monitoring period from 120 seconds to 60 seconds. (#3974) * [Monit] Change the monitoring period of monit from 120 seconds to 60 seconds and also at the same time double the interval for existing sonic monit config file in host. Signed-off-by: Yong Zhao --- files/image_config/monit/conf.d/sonic-host | 12 ++++++------ files/image_config/monit/monitrc | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/files/image_config/monit/conf.d/sonic-host b/files/image_config/monit/conf.d/sonic-host index 8eaa1671d821..5a67f7a9909b 100644 --- a/files/image_config/monit/conf.d/sonic-host +++ b/files/image_config/monit/conf.d/sonic-host @@ -6,17 +6,17 @@ ############################################################################### check filesystem root-overlay with path / - if space usage > 90% for 5 times within 10 cycles then alert + if space usage > 90% for 10 times within 20 cycles then alert check filesystem var-log with path /var/log - if space usage > 90% for 5 times within 10 cycles then alert + if space usage > 90% for 10 times within 20 cycles then alert check system $HOST - if memory usage > 90% for 5 times within 10 cycles then alert - if cpu usage (user) > 90% for 5 times within 10 cycles then alert - if cpu usage (system) > 90% for 5 times within 10 cycles then alert + if memory usage > 90% for 10 times within 20 cycles then alert + if cpu usage (user) > 90% for 10 times within 20 cycles then alert + if cpu usage (system) > 90% for 10 times within 20 cycles then alert check process rsyslog with pidfile /var/run/rsyslogd.pid start program = "/bin/systemctl start rsyslog.service" stop program = "/bin/systemctl stop rsyslog.service" - if totalmem > 800 MB for 5 times within 10 cycles then restart + if totalmem > 800 MB for 10 times within 20 cycles then restart diff --git a/files/image_config/monit/monitrc b/files/image_config/monit/monitrc index 7864069e3af1..3c3714882dcc 100644 --- a/files/image_config/monit/monitrc +++ b/files/image_config/monit/monitrc @@ -16,7 +16,7 @@ ## ## Start Monit in the background (run as a daemon): # - set daemon 120 # check services at 2-minute intervals + set daemon 60 # check services at 1-minute intervals # with start delay 240 # optional: delay the first check by 4-minutes (by # # default Monit check immediately after Monit start) # From 6dcc08e36cc517a7d8b9bc14dd5721c52abc0548 Mon Sep 17 00:00:00 2001 From: Kalimuthu-Velappan <53821802+Kalimuthu-Velappan@users.noreply.github.com> Date: Sat, 11 Jan 2020 02:56:04 +0530 Subject: [PATCH 63/66] [psud]: Fix for psud crash because of database connection reset (#3647) When database service is down, psud daemon throws an error because of DB connection reset, this because pmon service has no dependency with database service. To resolve this issue, added database service dependency to the pmon service. Also, increased the net.core.somaxconn value to 512 to solve the connection failure on the scaled setup. --- build_debian.sh | 3 +++ files/build_templates/pmon.service.j2 | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index 39b984edec4e..3ccdd3e9820a 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -392,6 +392,9 @@ set /files/etc/sysctl.conf/net.ipv4.udp_l3mdev_accept 1 set /files/etc/sysctl.conf/net.core.rmem_max 2097152 set /files/etc/sysctl.conf/net.core.wmem_max 2097152 + +set /files/etc/sysctl.conf/net.core.somaxconn 512 + " -r $FILESYSTEM_ROOT if [[ $CONFIGURED_ARCH == amd64 ]]; then diff --git a/files/build_templates/pmon.service.j2 b/files/build_templates/pmon.service.j2 index 11dea5d12783..9195b4d38ad6 100644 --- a/files/build_templates/pmon.service.j2 +++ b/files/build_templates/pmon.service.j2 @@ -1,7 +1,7 @@ [Unit] Description=Platform monitor container -Requires=updategraph.service -After=updategraph.service +Requires=database.service updategraph.service +After=database.service updategraph.service {% if sonic_asic_platform == 'mellanox' %} After=syncd.service {% endif %} From 3b1ee5dc2b8e5ac9411292d65e190ea7562ca4ec Mon Sep 17 00:00:00 2001 From: Sumukha Tumkur Vani Date: Fri, 10 Jan 2020 13:46:32 -0800 Subject: [PATCH 64/66] Changes to build restapi docker (#3993) --- .gitmodules | 4 +++ dockers/docker-sonic-restapi/Dockerfile.j2 | 25 +++++++++++++++++++ dockers/docker-sonic-restapi/start.sh | 10 ++++++++ dockers/docker-sonic-restapi/supervisord.conf | 12 +++++++++ rules/docker-restapi.mk | 20 +++++++++++++++ rules/restapi.mk | 9 +++++++ src/sonic-restapi | 1 + 7 files changed, 81 insertions(+) create mode 100644 dockers/docker-sonic-restapi/Dockerfile.j2 create mode 100755 dockers/docker-sonic-restapi/start.sh create mode 100644 dockers/docker-sonic-restapi/supervisord.conf create mode 100644 rules/docker-restapi.mk create mode 100644 rules/restapi.mk create mode 160000 src/sonic-restapi diff --git a/.gitmodules b/.gitmodules index 0cccf14a8e94..4fd4bd52be6c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -78,3 +78,7 @@ [submodule "src/sonic-ztp"] path = src/sonic-ztp url = https://github.com/Azure/sonic-ztp +[submodule "src/sonic-restapi"] + path = src/sonic-restapi + url = https://github.com/Azure/sonic-restapi.git + branch = master diff --git a/dockers/docker-sonic-restapi/Dockerfile.j2 b/dockers/docker-sonic-restapi/Dockerfile.j2 new file mode 100644 index 000000000000..de8080880fc7 --- /dev/null +++ b/dockers/docker-sonic-restapi/Dockerfile.j2 @@ -0,0 +1,25 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} +FROM docker-config-engine-stretch + +ARG docker_container_name +RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update + +{% if docker_sonic_restapi_debs.strip() -%} +# Copy locally-built Debian package dependencies +{{ copy_files("debs/", docker_sonic_restapi_debs.split(' '), "/debs/") }} + +# Install locally-built Debian packages and implicitly install their dependencies +{{ install_debian_packages( docker_sonic_restapi_debs.split(' ')) }} +{%- endif %} + +## Clean up +RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y + +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] + +ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-sonic-restapi/start.sh b/dockers/docker-sonic-restapi/start.sh new file mode 100755 index 000000000000..015d246d1200 --- /dev/null +++ b/dockers/docker-sonic-restapi/start.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +mkdir -p /var/sonic +echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status + +rm -f /var/run/rsyslogd.pid + +supervisorctl start rsyslogd + +supervisorctl start restapi diff --git a/dockers/docker-sonic-restapi/supervisord.conf b/dockers/docker-sonic-restapi/supervisord.conf new file mode 100644 index 000000000000..284c8aef423b --- /dev/null +++ b/dockers/docker-sonic-restapi/supervisord.conf @@ -0,0 +1,12 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[program:restapi] +command=/usr/sbin/go-server-server -loglevel trace +priority=1 +autostart=true +autorestart=false +stdout_logfile=/tmp/rest-api.out.log +stderr_logfile=/tmp/rest-api.err.log diff --git a/rules/docker-restapi.mk b/rules/docker-restapi.mk new file mode 100644 index 000000000000..66d60205915a --- /dev/null +++ b/rules/docker-restapi.mk @@ -0,0 +1,20 @@ +# docker image for rest-api + +DOCKER_RESTAPI_STEM = docker-sonic-restapi +DOCKER_RESTAPI = $(DOCKER_RESTAPI_STEM).gz + +$(DOCKER_RESTAPI)_DEPENDS += $(LIBHIREDIS) $(LIBNL3) $(LIBNL_GENL3) \ + $(LIBNL_ROUTE3) $(LIBSWSSCOMMON) $(RESTAPI) + +$(DOCKER_RESTAPI)_PATH = $(DOCKERS_PATH)/$(DOCKER_RESTAPI_STEM) + +$(DOCKER_RESTAPI)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) + +SONIC_DOCKER_IMAGES += $(DOCKER_RESTAPI) +SONIC_STRETCH_DOCKERS += $(DOCKER_RESTAPI) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_RESTAPI) + +$(DOCKER_RESTAPI)_CONTAINER_NAME = rest-api +$(DOCKER_RESTAPI)_RUN_OPT += --cap-add NET_ADMIN --privileged -t +$(DOCKER_RESTAPI)_RUN_OPT += -v /var/run/redis/redis.sock:/var/run/redis/redis.sock +$(DOCKER_RESTAPI)_RUN_OPT += -p=8090:8090/tcp diff --git a/rules/restapi.mk b/rules/restapi.mk new file mode 100644 index 000000000000..e66b4a1d976a --- /dev/null +++ b/rules/restapi.mk @@ -0,0 +1,9 @@ +# sonic-rest-api package + +RESTAPI = sonic-rest-api_1.0.1_amd64.deb +$(RESTAPI)_SRC_PATH = $(SRC_PATH)/sonic-restapi +$(RESTAPI)_DEPENDS += $(LIBHIREDIS_DEV) $(LIBNL3_DEV) $(LIBNL_GENL3_DEV) \ + $(LIBNL_ROUTE3_DEV) $(LIBSWSSCOMMON_DEV) $(LIBSWSSCOMMON) +$(RESTAPI)_RDEPENDS += $(LIBHIREDIS) $(LIBNL3) $(LIBNL_GENL3) \ + $(LIBNL_ROUTE3) $(LIBSWSSCOMMON) +SONIC_DPKG_DEBS += $(RESTAPI) diff --git a/src/sonic-restapi b/src/sonic-restapi new file mode 160000 index 000000000000..163ee272ae99 --- /dev/null +++ b/src/sonic-restapi @@ -0,0 +1 @@ +Subproject commit 163ee272ae992f5885990dcca6552cd86b74391a From b7e48b422f44947502daab3740245152eab651f9 Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Fri, 10 Jan 2020 16:21:02 -0800 Subject: [PATCH 65/66] [Services] Allow monit system tool to monitor the critical processes status running in various SONiC containers. (#3940) * Add a monit config file for teamd container. Signed-off-by: Yong Zhao * Add a copy mechanism to put the monit config file in teamd container into base image. Signed-off-by: Yong Zhao * Add a monit config file for snmp container. Signed-off-by: Yong Zhao * Add a copy mechanism to put the monit config file of snmp container into the base image. Signed-off-by: Yong Zhao * Add a monit config file for dhcp_relay container in the dir base_image_files. Signed-off-by: Yong Zhao * Add a copy mechanism to put the monit config file of dhcp_relay container into base image under /etc/monit/conf.d. Signed-off-by: Yong Zhao * Add a monit config file for router advertiser container. Signed-off-by: Yong Zhao * Add a copy mechanism to put the monit config file of router advertiser contianer into base image. Signed-off-by: Yong Zhao * [Docker-Pmon] Add a monit config file for pmon container. Signed-off-by: Yong Zhao * [Docker-Pmon] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-lldp] Add a monit config file for lldp container. Signed-off-by: Yong Zhao * [Docker-lldp] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-bgp] Add a monit config file for BGP container. Signed-off-by: Yong Zhao * [Docker-bgp] Add a copy mechanism to put monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-swss] Add a monit config file for the swss container. Signed-off-by: Yong Zhao * [Docker-swss] Add a copy mechanism to put monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on barefoot platform. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image on barefoot. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on broadcom. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image on broadcom. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on cavium. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-centec] Add a monit config file for syncd container on centen platform. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on centen platform. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on marvell. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit conifg file into the base image. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on marvell-arm64. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image on marvell-arm64. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on marvell-armhf. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on mellanox. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on nephos. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-sflow] Add a monit config file for sflow container. Signed-off-by: Yong Zhao * [Docker-sflow] Add a copy mechanism to put the monit conifg file into the base image. Signed-off-by: Yong Zhao * [Docker-telemetry] Add a monit config file for telemetry container. Signed-off-by: Yong Zhao * [Docker-telemetry] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-database] Add a monit config file for database container. Signed-off-by: Yong Zhao * [Docker-database] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-Dhcprelay] Change a typo. Signed-off-by: Yong Zhao * [Docker-Dhcprelay] Change the process name in monit config file to dhcrelay. Signed-off-by: Yong Zhao * [Docker-syncd] There is no desserve process in syncd container on barefoot. Signed-off-by: Yong Zhao * [Docker-syncd] There is no process desserve in syncd container on cavium. Signed-off-by: Yong Zhao * [Docker-syncd] There is no process named desserve in syncd on centec. Signed-off-by: Yong Zhao * [Docker-syncd] There is no process named desserve in syncd on marvell. Signed-off-by: Yong Zhao * [Docker-syncd] Should not delete the process desserve in syncd container on marvell. Signed-off-by: Yong Zhao * [Docker-syncd] Delete the process dsserve in syncd on marvell. Signed-off-by: Yong Zhao * [Docker-syncd] Delete the process dsserve in syncd container on marvell-arm64. Signed-off-by: Yong Zhao * [Docker-syncd] Delete the process dsserve in syncd container on marvell-armhf. Signed-off-by: Yong Zhao * [Docker-syncd] Delete the process dsserve in syncd container on mellanox. Signed-off-by: Yong Zhao * [Docker-Radv] Change the process name to radvd. Signed-off-by: Yong Zhao * [Docker-telemetry] Correct a typo in monit_telemetry. Signed-off-by: Yong Zhao * [Docker-teamd] Delete the monit config file for teamd. Signed-off-by: Yong Zhao * [Docker-teamd] Delete the mechanism to copy the monit config file into base image. Signed-off-by: Yong Zhao * [Docker-dhcprelay] Delete the monit config file for dhcp_relay container. Signed-off-by: Yong Zhao * [Docker-dhcprelay] Delete the mechanism to copy the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-radv] Delete the monit config file foe radv container. Signed-off-by: Yong Zhao * [Docker-radv] Delete the mechanism to copy the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-bgp] change the monit config file for BGP container such that monit only generates alert if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-snmp] Change the monit config file for snmp container such that monit only generates alret if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-pmon] Change the monit config file for pmon container such that monit only generates alert if the processes are not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-lldp] Change the monit config file for lldp container such that monit only generates alerts if some processes are not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-pmon] Delete the monit config file for pmon container since some of processes are not running depended on the type of box. Signed-off-by: Yong Zhao * [Docker-pmon] Delete the copy mechanism to copy the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-lldp] Change the matching name for the process lldpd. Signed-off-by: Yong Zhao * [Docker-swss] Change the monit config file for swss container such that monit only generates alerts if the processes are not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container on barefoot such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Correct a typo in monit config file. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container on broadcom such that monit only generates alerts if the processes are not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container on cavium such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container on marvell such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container on marvell-arm64 such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container on marvell-armhf such that monit will generate alert if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container on mellanox such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-sycnd] Change the monit config file for syncd container such that monit only generates alerts if the processes are not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-sflow] Change the monit config file for sflow container such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-telemetry] Change the monit config file for telemetry container such that monit only generates alerts if the processes are not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-database] Change the monit config file for database container such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-database] Use 4 spaces to replace 2 spaces in monit config file. Signed-off-by: Yong Zhao * [Docker-bgp] Use 4 spcess to replace 2 spaces in monit config file. Signed-off-by: Yong Zhao * [Docker-lldp] Use 4 spaces to replace 2 spaces in monit config file. Signed-off-by: Yong Zhao * [Docker-swss] Use 4 spaces to replace 2 space in monit config file. Signed-off-by: Yong Zhao * [Docker-sflow] Use 4 spaces to replace 2 spaces in monit config file. Signed-off-by: Yong Zhao * [Docker-snmp] Use 4 spaces to replace 2 spaces in monit config file. Signed-off-by: Yong Zhao * [Docker-telemetry] Use 4 spaces to replace 2 spaces in monit config file. Signed-off-by: Yong Zhao * [Docker-syncd] Use 4 spaces to replace 2 spaces in the monit config file on barefoot. Signed-off-by: Yong Zhao * [Docker-syncd] Use 4 spaces to replace 2 spaces in the monit config file on broadcom. Signed-off-by: Yong Zhao * [Docker-syncd] Use 4 spaces to replace 2 spaces in the monit config file on cavium. Signed-off-by: Yong Zhao * [Docker-syncd] Use 4 spaces to replace 2 spaces in the monit config file on centec. Signed-off-by: Yong Zhao * [Docker-syncd] Use 4 spaces to replace 2 spaces in the monit config file on marvell. Signed-off-by: Yong Zhao * [Docker-syncd] Use 4 spaces to replace 2 spaces in the monit config file on mellanox. Signed-off-by: Yong Zhao * [Docker-syncd] Use 4 spaces to repalce 2 spaces in the monit config file on nephos. Signed-off-by: Yong Zhao * [Docker-bgp] Remove the trailing extra spaces in monit config file. Signed-off-by: Yong Zhao --- .../base_image_files/monit_database | 7 +++ .../docker-fpm-frr/base_image_files/monit_bgp | 23 ++++++++++ .../base_image_files/monit_lldp | 15 +++++++ .../base_image_files/monit_swss | 43 +++++++++++++++++++ .../docker-sflow/base_image_files/monit_sflow | 7 +++ .../base_image_files/monit_snmp | 11 +++++ .../base_image_files/monit_telemetry | 11 +++++ platform/barefoot/docker-syncd-bfn.mk | 2 +- .../base_image_files/monit_syncd | 7 +++ platform/broadcom/docker-syncd-brcm.mk | 1 + .../base_image_files/monit_syncd | 11 +++++ platform/cavium/docker-syncd-cavm.mk | 1 + .../base_image_files/monit_syncd | 7 +++ platform/centec/docker-syncd-centec.mk | 1 + .../base_image_files/monit_syncd | 7 +++ platform/marvell-arm64/docker-syncd-mrvl.mk | 1 + .../base_image_files/monit_syncd | 7 +++ platform/marvell-armhf/docker-syncd-mrvl.mk | 1 + .../base_image_files/monit_syncd | 7 +++ platform/marvell/docker-syncd-mrvl.mk | 1 + .../base_image_files/monit_syncd | 7 +++ platform/mellanox/docker-syncd-mlnx.mk | 2 +- .../base_image_files/monit_syncd | 7 +++ platform/nephos/docker-syncd-nephos.mk | 2 +- .../base_image_files/monit_syncd | 11 +++++ rules/docker-database.mk | 1 + rules/docker-fpm-frr.mk | 1 + rules/docker-lldp-sv2.mk | 1 + rules/docker-orchagent.mk | 1 + rules/docker-sflow.mk | 1 + rules/docker-snmp-sv2.mk | 1 + rules/docker-telemetry.mk | 1 + 32 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 dockers/docker-database/base_image_files/monit_database create mode 100644 dockers/docker-fpm-frr/base_image_files/monit_bgp create mode 100644 dockers/docker-lldp-sv2/base_image_files/monit_lldp create mode 100644 dockers/docker-orchagent/base_image_files/monit_swss create mode 100644 dockers/docker-sflow/base_image_files/monit_sflow create mode 100644 dockers/docker-snmp-sv2/base_image_files/monit_snmp create mode 100644 dockers/docker-sonic-telemetry/base_image_files/monit_telemetry create mode 100644 platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd create mode 100644 platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd create mode 100644 platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd create mode 100644 platform/centec/docker-syncd-centec/base_image_files/monit_syncd create mode 100644 platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd create mode 100644 platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd create mode 100644 platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd create mode 100644 platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd create mode 100644 platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd diff --git a/dockers/docker-database/base_image_files/monit_database b/dockers/docker-database/base_image_files/monit_database new file mode 100644 index 000000000000..c5508922864e --- /dev/null +++ b/dockers/docker-database/base_image_files/monit_database @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for database container +## process list: +## redis_server +############################################################################### +check process redis_server matching "/usr/bin/redis-server" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-fpm-frr/base_image_files/monit_bgp b/dockers/docker-fpm-frr/base_image_files/monit_bgp new file mode 100644 index 000000000000..5b943ea7c0bb --- /dev/null +++ b/dockers/docker-fpm-frr/base_image_files/monit_bgp @@ -0,0 +1,23 @@ +############################################################################### +## Monit configuration for BGP container +## process list: +## zebra +## fpmsyncd +## bgpd +## staticd +## bgpcfgd +############################################################################### +check process zebra matching "/usr/lib/frr/zebra" + if does not exist for 5 times within 5 cycles then alert + +check process fpmsyncd matching "fpmsyncd" + if does not exist for 5 times within 5 cycles then alert + +check process bgpd matching "/usr/lib/frr/bgpd" + if does not exist for 5 times within 5 cycles then alert + +check process staticd matching "/usr/lib/frr/staticd" + if does not exist for 5 times within 5 cycles then alert + +check process bgpcfgd matching "python /usr/bin/bgpcfgd" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-lldp-sv2/base_image_files/monit_lldp b/dockers/docker-lldp-sv2/base_image_files/monit_lldp new file mode 100644 index 000000000000..200c52c7d332 --- /dev/null +++ b/dockers/docker-lldp-sv2/base_image_files/monit_lldp @@ -0,0 +1,15 @@ +############################################################################### +## Monit configuration for lldp container +## process list: +## lldpd +## lldp-syncd +## lldpmgrd +############################################################################### +check process lldpd_monitor matching "lldpd: " + if does not exist for 5 times within 5 cycles then alert + +check process lldp_syncd matching "python2 -m lldp_syncd" + if does not exist for 5 times within 5 cycles then alert + +check process lldpmgrd matching "python /usr/bin/lldpmgrd" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-orchagent/base_image_files/monit_swss b/dockers/docker-orchagent/base_image_files/monit_swss new file mode 100644 index 000000000000..5928dbd4ddb0 --- /dev/null +++ b/dockers/docker-orchagent/base_image_files/monit_swss @@ -0,0 +1,43 @@ +############################################################################### +## Monit configuration for swss container +## process list: +## orchagent +## portsyncd +## neighsyncd +## vrfmgrd +## vlanmgrd +## intfmgrd +## portmgrd +## buffermgrd +## nbrmgrd +## vxlanmgrd +############################################################################### +check process orchagent matching "/usr/bin/orchagent -d /var/log/swss" + if does not exist for 5 times within 5 cycles then alert + +check process portsyncd matching "/usr/bin/portsyncd" + if does not exist for 5 times within 5 cycles then alert + +check process neighsyncd matching "/usr/bin/neighsyncd" + if does not exist for 5 times within 5 cycles then alert + +check process vrfmgrd matching "/usr/bin/vrfmgrd" + if does not exist for 5 times within 5 cycles then alert + +check process vlanmgrd matching "/usr/bin/vlanmgrd" + if does not exist for 5 times within 5 cycles then alert + +check process intfmgrd matching "/usr/bin/intfmgrd" + if does not exist for 5 times within 5 cycles then alert + +check process portmgrd matching "/usr/bin/portmgrd" + if does not exist for 5 times within 5 cycles then alert + +check process buffermgrd matching "/usr/bin/buffermgrd -l" + if does not exist for 5 times within 5 cycles then alert + +check process nbrmgrd matching "/usr/bin/nbrmgrd" + if does not exist for 5 times within 5 cycles then alert + +check process vxlanmgrd matching "/usr/bin/vxlanmgrd" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-sflow/base_image_files/monit_sflow b/dockers/docker-sflow/base_image_files/monit_sflow new file mode 100644 index 000000000000..d041f81001ea --- /dev/null +++ b/dockers/docker-sflow/base_image_files/monit_sflow @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for sflow container +## process list: +## sflowmgrd +############################################################################### +check process sflowmgrd matching "/usr/bin/sflowmgrd" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-snmp-sv2/base_image_files/monit_snmp b/dockers/docker-snmp-sv2/base_image_files/monit_snmp new file mode 100644 index 000000000000..811f9d14b3d4 --- /dev/null +++ b/dockers/docker-snmp-sv2/base_image_files/monit_snmp @@ -0,0 +1,11 @@ +############################################################################### +## Monit configuration for snmp container +## process list: +## snmpd +## snmpd_subagent +############################################################################### +check process snmpd matching "/usr/sbin/snmpd -f" + if does not exist for 5 times within 5 cycles then alert + +check process snmp_subagent matching "python3.6 -m sonic_ax_impl" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry b/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry new file mode 100644 index 000000000000..555822c57f80 --- /dev/null +++ b/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry @@ -0,0 +1,11 @@ +############################################################################### +## Monit configuration for telemetry container +## process list: +## telemetry +## dialout_client +############################################################################### +check process telemetry matching "/usr/sbin/telemetry -logtostderr --insecure" + if does not exist for 5 times within 5 cycles then alert + +check process dialout_client matching "/usr/sbin/dialout_client_cli -insecure -logtostderr" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/barefoot/docker-syncd-bfn.mk b/platform/barefoot/docker-syncd-bfn.mk index 6f3ed59ad285..3a5c693e2fa8 100644 --- a/platform/barefoot/docker-syncd-bfn.mk +++ b/platform/barefoot/docker-syncd-bfn.mk @@ -11,4 +11,4 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIREDIS_DBG) $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot - +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd b/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd new file mode 100644 index 000000000000..9cc5891c7c32 --- /dev/null +++ b/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/broadcom/docker-syncd-brcm.mk b/platform/broadcom/docker-syncd-brcm.mk index 29727dbb2260..d3a6d67c5cbc 100644 --- a/platform/broadcom/docker-syncd-brcm.mk +++ b/platform/broadcom/docker-syncd-brcm.mk @@ -16,3 +16,4 @@ $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += bcmcmd:/usr/bin/bcmcmd $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += bcmsh:/usr/bin/bcmsh +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd b/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd new file mode 100644 index 000000000000..3f8bc50007d7 --- /dev/null +++ b/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd @@ -0,0 +1,11 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +## dsserve +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert + +check process dsserve matching "/usr/bin/dsserve /usr/bin/syncd" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/cavium/docker-syncd-cavm.mk b/platform/cavium/docker-syncd-cavm.mk index a136828dbff1..ad43d6f1196f 100644 --- a/platform/cavium/docker-syncd-cavm.mk +++ b/platform/cavium/docker-syncd-cavm.mk @@ -20,3 +20,4 @@ $(DOCKER_SYNCD_CAVM)_CONTAINER_NAME = syncd $(DOCKER_SYNCD_CAVM)_RUN_OPT += --net=host --privileged -t $(DOCKER_SYNCD_CAVM)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_CAVM)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_SYNCD_CAVM)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd b/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd new file mode 100644 index 000000000000..9cc5891c7c32 --- /dev/null +++ b/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/centec/docker-syncd-centec.mk b/platform/centec/docker-syncd-centec.mk index 360690731a58..a0dbcc629dee 100644 --- a/platform/centec/docker-syncd-centec.mk +++ b/platform/centec/docker-syncd-centec.mk @@ -21,3 +21,4 @@ $(DOCKER_SYNCD_CENTEC)_RUN_OPT += --net=host --privileged -t $(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd $(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_SYNCD_CENTEC)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/centec/docker-syncd-centec/base_image_files/monit_syncd b/platform/centec/docker-syncd-centec/base_image_files/monit_syncd new file mode 100644 index 000000000000..9cc5891c7c32 --- /dev/null +++ b/platform/centec/docker-syncd-centec/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/marvell-arm64/docker-syncd-mrvl.mk b/platform/marvell-arm64/docker-syncd-mrvl.mk index e00769a59700..841e3b4b165f 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl.mk +++ b/platform/marvell-arm64/docker-syncd-mrvl.mk @@ -11,3 +11,4 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIREDIS_DBG) $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd new file mode 100644 index 000000000000..9cc5891c7c32 --- /dev/null +++ b/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/marvell-armhf/docker-syncd-mrvl.mk b/platform/marvell-armhf/docker-syncd-mrvl.mk index e00769a59700..841e3b4b165f 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl.mk +++ b/platform/marvell-armhf/docker-syncd-mrvl.mk @@ -11,3 +11,4 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIREDIS_DBG) $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd new file mode 100644 index 000000000000..9cc5891c7c32 --- /dev/null +++ b/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/marvell/docker-syncd-mrvl.mk b/platform/marvell/docker-syncd-mrvl.mk index 5257bf5e68e7..97b7eab19895 100644 --- a/platform/marvell/docker-syncd-mrvl.mk +++ b/platform/marvell/docker-syncd-mrvl.mk @@ -12,3 +12,4 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd new file mode 100644 index 000000000000..9cc5891c7c32 --- /dev/null +++ b/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/mellanox/docker-syncd-mlnx.mk b/platform/mellanox/docker-syncd-mlnx.mk index db582e517bff..9bdc5a8ad8ec 100644 --- a/platform/mellanox/docker-syncd-mlnx.mk +++ b/platform/mellanox/docker-syncd-mlnx.mk @@ -15,4 +15,4 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(MLNX_SDK_DBG_DEBS) $(MLNX_SAI_DBGSYM) endif $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot - +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd b/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd new file mode 100644 index 000000000000..9cc5891c7c32 --- /dev/null +++ b/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/nephos/docker-syncd-nephos.mk b/platform/nephos/docker-syncd-nephos.mk index 6829c91c67aa..67bad252870a 100644 --- a/platform/nephos/docker-syncd-nephos.mk +++ b/platform/nephos/docker-syncd-nephos.mk @@ -15,4 +15,4 @@ $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += npx_diag:/usr/bin/npx_diag - +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd b/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd new file mode 100644 index 000000000000..3f8bc50007d7 --- /dev/null +++ b/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd @@ -0,0 +1,11 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +## dsserve +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert + +check process dsserve matching "/usr/bin/dsserve /usr/bin/syncd" + if does not exist for 5 times within 5 cycles then alert diff --git a/rules/docker-database.mk b/rules/docker-database.mk index 43dc2ed5d446..9ad6b0b36b45 100644 --- a/rules/docker-database.mk +++ b/rules/docker-database.mk @@ -27,3 +27,4 @@ $(DOCKER_DATABASE)_RUN_OPT += --net=host --privileged -t $(DOCKER_DATABASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_DATABASE)_BASE_IMAGE_FILES += redis-cli:/usr/bin/redis-cli +$(DOCKER_DATABASE)_BASE_IMAGE_FILES += monit_database:/etc/monit/conf.d diff --git a/rules/docker-fpm-frr.mk b/rules/docker-fpm-frr.mk index 1d158effe7ff..e833d360bec2 100644 --- a/rules/docker-fpm-frr.mk +++ b/rules/docker-fpm-frr.mk @@ -30,3 +30,4 @@ $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += vtysh:/usr/bin/vtysh $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSA:/usr/bin/TSA $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSB:/usr/bin/TSB $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSC:/usr/bin/TSC +$(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += monit_bgp:/etc/monit/conf.d diff --git a/rules/docker-lldp-sv2.mk b/rules/docker-lldp-sv2.mk index 91acbe58ad82..8224239c1ced 100644 --- a/rules/docker-lldp-sv2.mk +++ b/rules/docker-lldp-sv2.mk @@ -30,4 +30,5 @@ $(DOCKER_LLDP_SV2)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_LLDP_SV2)_BASE_IMAGE_FILES += lldpctl:/usr/bin/lldpctl $(DOCKER_LLDP_SV2)_BASE_IMAGE_FILES += lldpcli:/usr/bin/lldpcli +$(DOCKER_LLDP_SV2)_BASE_IMAGE_FILES += monit_lldp:/etc/monit/conf.d $(DOCKER_LLDP_SV2)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-orchagent.mk b/rules/docker-orchagent.mk index 20536adc2520..0244138cbfe2 100644 --- a/rules/docker-orchagent.mk +++ b/rules/docker-orchagent.mk @@ -34,4 +34,5 @@ $(DOCKER_ORCHAGENT)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_ORCHAGENT)_RUN_OPT += -v /var/log/swss:/var/log/swss:rw $(DOCKER_ORCHAGENT)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel +$(DOCKER_ORCHAGENT)_BASE_IMAGE_FILES += monit_swss:/etc/monit/conf.d $(DOCKER_ORCHAGENT)_FILES += $(ARP_UPDATE_SCRIPT) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-sflow.mk b/rules/docker-sflow.mk index 94b568481885..449ff7c566f2 100644 --- a/rules/docker-sflow.mk +++ b/rules/docker-sflow.mk @@ -32,4 +32,5 @@ $(DOCKER_SFLOW)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SFLOW)_BASE_IMAGE_FILES += psample:/usr/bin/psample $(DOCKER_SFLOW)_BASE_IMAGE_FILES += sflowtool:/usr/bin/sflowtool +$(DOCKER_SFLOW)_BASE_IMAGE_FILES += monit_sflow:/etc/monit/conf.d $(DOCKER_SFLOW)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-snmp-sv2.mk b/rules/docker-snmp-sv2.mk index bd34f271b861..1f403b7a8c8a 100644 --- a/rules/docker-snmp-sv2.mk +++ b/rules/docker-snmp-sv2.mk @@ -31,3 +31,4 @@ $(DOCKER_SNMP_SV2)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro # mount Arista platform python libraries to support corresponding platforms SNMP power status query $(DOCKER_SNMP_SV2)_RUN_OPT += -v /usr/lib/python3/dist-packages/arista:/usr/lib/python3/dist-packages/arista:ro $(DOCKER_SNMP_SV2)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_SNMP_SV2)_BASE_IMAGE_FILES += monit_snmp:/etc/monit/conf.d diff --git a/rules/docker-telemetry.mk b/rules/docker-telemetry.mk index 799bef1b1735..361136306337 100644 --- a/rules/docker-telemetry.mk +++ b/rules/docker-telemetry.mk @@ -30,3 +30,4 @@ $(DOCKER_TELEMETRY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_TELEMETRY)_RUN_OPT += --mount type=bind,source="/var/platform/",target="/mnt/platform/" $(DOCKER_TELEMETRY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_TELEMETRY)_BASE_IMAGE_FILES += monit_telemetry:/etc/monit/conf.d From 952dfb15f706a9be10833c186a8bcbed3847843f Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sun, 12 Jan 2020 21:53:52 +0000 Subject: [PATCH 66/66] [docker-sonic-mgmt]: fix installation permission issue --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 4a7e1a977549..7cfaeaaf7d2b 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -105,6 +105,8 @@ debs/{{ deb }}{{' '}} RUN pip install ansible==2.8.7 +RUN pip install pysubnettree + RUN mkdir /var/run/sshd EXPOSE 22 @@ -143,6 +145,4 @@ RUN azure-cli_bundle_*/installer # TODO: if azure-cli contains newer version azure-keyvault, remove this RUN ~/lib/azure-cli/bin/python -m pip install azure-keyvault==0.3.7 -U -RUN pip install pysubnettree - RUN git clone https://github.com/Azure/sonic-mgmt