From 6b84160953c24f57fbaea5e62c3a5d79701036b5 Mon Sep 17 00:00:00 2001 From: Volodymyr Samotiy Date: Thu, 25 Apr 2019 12:38:59 +0000 Subject: [PATCH 01/88] [submodule]: Update sonic-sairedis pointer * 1b0d609 2019-04-24 [SAI] Advance submodule to v1.4.1 (#450) [Marian Pritsak] * 3d87ad1 2019-04-23 Add metadata serialization support for buffer pool stats (#448) [Wenda Ni] * a17e54e 2019-04-23 [SAI]: Move SAI pointer to v1.4 (#447) [Shuotian Cheng] * f8950b7 2019-04-23 Add warm-boot feature processing for wedge100bf_32x/65x platforms (#434) [Pavlo Yadvichuk] * e9e9dc3 2019-04-18 Add a comment to fix the docker issue (#442) [pavel-shirshov] Signed-off-by: Volodymyr Samotiy --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index e8cb8796592c..1b0d609c6f9a 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit e8cb8796592c83f669d73d5587be60afc54eb4f6 +Subproject commit 1b0d609c6f9acd1cb868898f019eaade071c85ee From 6bf97d8a23897459a3037dd5383ec7b472afdb64 Mon Sep 17 00:00:00 2001 From: Nikos <31227248+nikos-github@users.noreply.github.com> Date: Thu, 25 Apr 2019 13:21:20 -0700 Subject: [PATCH 02/88] [docker-frr]: Move docker to stretch and add pythontools (#2819) --- dockers/docker-fpm-frr/Dockerfile.j2 | 4 ++-- rules/docker-fpm-frr.mk | 6 ++++-- rules/frr.mk | 8 +++++++- src/sonic-frr/Makefile | 16 ++++++++++++---- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/dockers/docker-fpm-frr/Dockerfile.j2 b/dockers/docker-fpm-frr/Dockerfile.j2 index 6a11deed385f..df1de8ee82b7 100644 --- a/dockers/docker-fpm-frr/Dockerfile.j2 +++ b/dockers/docker-fpm-frr/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine +FROM docker-config-engine-stretch ARG docker_container_name ARG frr_user_uid @@ -13,7 +13,7 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update # Install required packages -RUN apt-get install -y libdbus-1-3 libdaemon0 libjansson4 libc-ares2 iproute2 libpython2.7 libjson-c2 logrotate +RUN apt-get install -y libdbus-1-3 libdaemon0 libjansson4 libc-ares2 iproute2 libpython2.7 libjson-c3 logrotate {% if docker_fpm_frr_debs.strip() -%} # Copy locally-built Debian package dependencies diff --git a/rules/docker-fpm-frr.mk b/rules/docker-fpm-frr.mk index f9a858611fa1..22da11f29c50 100644 --- a/rules/docker-fpm-frr.mk +++ b/rules/docker-fpm-frr.mk @@ -2,8 +2,8 @@ DOCKER_FPM_FRR = docker-fpm-frr.gz $(DOCKER_FPM_FRR)_PATH = $(DOCKERS_PATH)/docker-fpm-frr -$(DOCKER_FPM_FRR)_DEPENDS += $(FRR) $(SWSS) -$(DOCKER_FPM_FRR)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) +$(DOCKER_FPM_FRR)_DEPENDS += $(FRR) $(FRR_PYTHONTOOLS) $(SWSS) +$(DOCKER_FPM_FRR)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) SONIC_DOCKER_IMAGES += $(DOCKER_FPM_FRR) $(DOCKER_FPM_FRR)_CONTAINER_NAME = bgp @@ -12,3 +12,5 @@ $(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic/frr:/etc/frr:rw $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += vtysh:/usr/bin/vtysh + +SONIC_STRETCH_DOCKERS += $(DOCKER_FPM_FRR) diff --git a/rules/frr.mk b/rules/frr.mk index a5736452b1ab..3d077c4b055f 100644 --- a/rules/frr.mk +++ b/rules/frr.mk @@ -3,7 +3,13 @@ FRR_VERSION = 6.0.2 export FRR_VERSION -FRR = frr_$(FRR_VERSION)-1~sonic.debian8+1_amd64.deb +FRR = frr_$(FRR_VERSION)-1~sonic.debian9+1_amd64.deb $(FRR)_DEPENDS += $(LIBSNMP_DEV) $(FRR)_SRC_PATH = $(SRC_PATH)/sonic-frr SONIC_MAKE_DEBS += $(FRR) + +# FRRouting pythontools +FRR_PYTHONTOOLS = frr-pythontools_$(FRR_VERSION)-1~sonic.debian9+1_amd64.deb +$(FRR_PYTHONTOOLS)_DEPENDS += $(LIBSNMP_DEV) +$(FRR_PYTHONTOOLS)_SRC_PATH = $(SRC_PATH)/sonic-frr +SONIC_MAKE_DEBS += $(FRR_PYTHONTOOLS) diff --git a/src/sonic-frr/Makefile b/src/sonic-frr/Makefile index 22cd1897a1f5..c2ccffbbebd7 100644 --- a/src/sonic-frr/Makefile +++ b/src/sonic-frr/Makefile @@ -2,7 +2,10 @@ SHELL = /bin/bash .SHELLFLAGS += -e -MAIN_TARGET = frr_$(FRR_VERSION)-1~sonic.debian8+1_amd64.deb +MAIN_TARGET = frr_$(FRR_VERSION)-1~sonic.debian9+1_amd64.deb +TOOLS_TARGET = frr-pythontools_$(FRR_VERSION)-1~sonic.debian9+1_amd64.deb +MAIN_TARGET_DBG = frr-dbgsym_$(FRR_VERSION)-1~sonic.debian9+1_amd64.deb +DERIVED_TARGET = $(TOOLS_TARGET) $(MAIN_TARGET_DBG) $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : @@ -12,11 +15,16 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # This could very well be tools/tarsource.sh -V -e sonic tools/tarsource.sh -V # This is a no-op but here in case the changelog stops being a symlink - debchange -b -v $(FRR_VERSION)-1~sonic.debian8+1 'SONiC FRR debian package build' + debchange -b -v $(FRR_VERSION)-1~sonic.debian9+1 'SONiC FRR debian package build' + sudo apt-get -y install install-info dpkg-buildpackage -rfakeroot -b -us -uc -Ppkg.frr.nortrlib cd .. - mv frr_$(FRR_VERSION)-*_amd64.deb frr_$(FRR_VERSION)-1~sonic.debian8+1_amd64.deb - mv $* $(DEST)/ + mv frr_$(FRR_VERSION)-*_amd64.deb $(MAIN_TARGET) + mv frr-pythontools_$(FRR_VERSION)-*_all.deb $(TOOLS_TARGET) + mv frr-dbgsym_$(FRR_VERSION)-*_amd64.deb $(MAIN_TARGET_DBG) + mv $(DERIVED_TARGET) $* $(DEST)/ popd +$(addprefix $(DEST)/, $(DERIVED_TARGET)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) + From 452e75c95144d8aa5b0bd5a769a78cd59b41a406 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 25 Apr 2019 16:16:22 -0700 Subject: [PATCH 03/88] Downport the netlink patch to libteam1.26. Increase netlink buffers (#2822) --- ...nize-ifinfo-after-lost-RTNLGRP_LINK-.patch | 302 ++++++++++++++++++ src/libteam/series | 3 +- 2 files changed, 304 insertions(+), 1 deletion(-) create mode 100644 src/libteam/0011-libteam-resynchronize-ifinfo-after-lost-RTNLGRP_LINK-.patch diff --git a/src/libteam/0011-libteam-resynchronize-ifinfo-after-lost-RTNLGRP_LINK-.patch b/src/libteam/0011-libteam-resynchronize-ifinfo-after-lost-RTNLGRP_LINK-.patch new file mode 100644 index 000000000000..fcda98301174 --- /dev/null +++ b/src/libteam/0011-libteam-resynchronize-ifinfo-after-lost-RTNLGRP_LINK-.patch @@ -0,0 +1,302 @@ +commit 046fb6ba0aec8246075b18d787daec43201566fa +Author: Antti Tiainen +Date: Mon Feb 6 15:41:05 2017 +0200 + + libteam: resynchronize ifinfo after lost RTNLGRP_LINK notifications + + When there's a large number of interfaces (e.g. vlans), teamd loses + link notifications as it cannot read them as fast as kernel is + broadcasting them. This often prevents teamd starting properly if + started concurrently when other links are being set up. It can also + fail when it's up and running, especially in the cases where the team + device itself has a lot of vlans under it. + + This can easily be reproduces by simple example (in SMP system) by + manually adding team device with a bunch of vlans, putting it up, + and starting teamd with --take-over option: + + root@debian:~# ip link add name team0 type team + root@debian:~# for i in `seq 100 150` ; do + > ip link add link team0 name team0.$i type vlan id $i ; done + root@debian:~# ip link set team0 up + root@debian:~# cat teamd.conf + { + "device": "team0", + "runner": { + "name": "activebackup" + }, + "ports": { + "eth1": {}, + "eth2": {} + } + } + root@debian:~# teamd -o -N -f teamd.conf + + At this point, teamd will not give any error messages or other + indication that something is wrong. But state will not look healthy: + + root@debian:~# teamdctl team0 state + setup: + runner: activebackup + ports: + eth1 + link watches: + link summary: up + instance[link_watch_0]: + name: ethtool + link: up + down count: 0 + Failed to parse JSON port dump. + command call failed (Invalid argument) + + If checking state dump, it will show that port eth2 is missing info. + Running strace to teamd will reveal that there's one recvmsgs() that + returned -1 with errno ENOBUFS. What happened in this example was + that when teamd started, all vlans got carrier up, and kernel flooded + notifications faster than teamd could read them. It then lost events + related to port eth2 getting enslaved and up. + + The socket that joins RTNLGRP_LINK notifications uses default libnl + 32k buffer size. Netlink messages are large (over 1k), and this buffer + gets easily full. Kernel neither knows nor cares were notification + broadcasts delivered. This cannot be fixed by simply increasing the + buffer size, as there's no size that is guaranteed to work in every + use case, and this can require several megabytes of buffer (a way over + normal rmem_max limit) if there are hunderds of vlans. + + Only way to recover from this is to refresh all ifinfo list, as it's + invalidated at this point. It cannot easily work around of this by + just refreshing team device and its ports, because library side might + not have ports linked due to events missed, and it doesn't know about + teamd configuration. + + Checks now return value of nl_recvmsgs_default() for event socket. In + case of ENOBUFS (which libnl nicely changes to ENOMEM), refreshes + all ifinfo list. get_ifinfo_list() also checks now for removed interfaces + in case of missed dellink event. Currently all TEAM_IFINFO_CHANGE + handlers processed events one by one, so it had to be changed to support + multiple ifinfo changes. For this, ifinfo changed flags are cleared + and removed entries destroyed only after all handlers have been called. + + Also, increased nl_cli.sock_event receive buffers to 96k like all other + sockets. Added possibility to change this via environment variable. + + Signed-off-by: Antti Tiainen + Signed-off-by: Jiri Pirko + +diff --git a/libteam/ifinfo.c b/libteam/ifinfo.c +index 72155ae..5c32a9c 100644 +--- a/libteam/ifinfo.c ++++ b/libteam/ifinfo.c +@@ -72,6 +72,10 @@ struct team_ifinfo { + #define CHANGED_PHYS_PORT_ID (1 << 5) + #define CHANGED_PHYS_PORT_ID_LEN (1 << 6) + #define CHANGED_ADMIN_STATE (1 << 7) ++/* This is only used when tagging interfaces for finding ++ * removed, and thus not included to CHANGED_ANY. ++ */ ++#define CHANGED_REFRESHING (1 << 8) + #define CHANGED_ANY (CHANGED_REMOVED | CHANGED_HWADDR | \ + CHANGED_HWADDR_LEN | CHANGED_IFNAME | \ + CHANGED_MASTER_IFINDEX | CHANGED_PHYS_PORT_ID | \ +@@ -202,7 +206,7 @@ static struct team_ifinfo *ifinfo_find(struct team_handle *th, uint32_t ifindex) + return NULL; + } + +-static void clear_last_changed(struct team_handle *th) ++void ifinfo_clear_changed(struct team_handle *th) + { + struct team_ifinfo *ifinfo; + +@@ -236,7 +240,7 @@ static void ifinfo_destroy(struct team_ifinfo *ifinfo) + free(ifinfo); + } + +-static void ifinfo_destroy_removed(struct team_handle *th) ++void ifinfo_destroy_removed(struct team_handle *th) + { + struct team_ifinfo *ifinfo, *tmp; + +@@ -254,8 +258,6 @@ static void obj_input_newlink(struct nl_object *obj, void *arg, bool event) + uint32_t ifindex; + int err; + +- ifinfo_destroy_removed(th); +- + link = (struct rtnl_link *) obj; + + ifindex = rtnl_link_get_ifindex(link); +@@ -269,7 +271,7 @@ static void obj_input_newlink(struct nl_object *obj, void *arg, bool event) + return; + } + +- clear_last_changed(th); ++ clear_changed(ifinfo); + ifinfo_update(ifinfo, link); + + if (event) +@@ -292,8 +294,6 @@ static void event_handler_obj_input_dellink(struct nl_object *obj, void *arg) + uint32_t ifindex; + int err; + +- ifinfo_destroy_removed(th); +- + link = (struct rtnl_link *) obj; + + ifindex = rtnl_link_get_ifindex(link); +@@ -311,7 +311,7 @@ static void event_handler_obj_input_dellink(struct nl_object *obj, void *arg) + return; + } + +- clear_last_changed(th); ++ clear_changed(ifinfo); + set_changed(ifinfo, CHANGED_REMOVED); + set_call_change_handlers(th, TEAM_IFINFO_CHANGE); + } +@@ -367,6 +367,14 @@ int get_ifinfo_list(struct team_handle *th) + }; + int ret; + int retry = 1; ++ struct team_ifinfo *ifinfo; ++ ++ /* Tag all ifinfo, this is cleared in newlink handler. ++ * Any interface that has this after dump is processed ++ * has been removed. ++ */ ++ list_for_each_node_entry(ifinfo, &th->ifinfo_list, list) ++ set_changed(ifinfo, CHANGED_REFRESHING); + + while (retry) { + retry = 0; +@@ -395,6 +403,15 @@ int get_ifinfo_list(struct team_handle *th) + retry = 1; + } + } ++ ++ list_for_each_node_entry(ifinfo, &th->ifinfo_list, list) { ++ if (is_changed(ifinfo, CHANGED_REFRESHING)) { ++ clear_changed(ifinfo); ++ set_changed(ifinfo, CHANGED_REMOVED); ++ set_call_change_handlers(th, TEAM_IFINFO_CHANGE); ++ } ++ } ++ + ret = check_call_change_handlers(th, TEAM_IFINFO_CHANGE); + if (ret < 0) + err(th, "get_ifinfo_list: check_call_change_handers failed"); +diff --git a/libteam/libteam.c b/libteam/libteam.c +index ac187aa..d5f22cd 100644 +--- a/libteam/libteam.c ++++ b/libteam/libteam.c +@@ -236,6 +236,10 @@ int check_call_change_handlers(struct team_handle *th, + break; + } + } ++ if (call_type_mask & TEAM_IFINFO_CHANGE) { ++ ifinfo_destroy_removed(th); ++ ifinfo_clear_changed(th); ++ } + th->change_handler.pending_type_mask &= ~call_type_mask; + return err; + } +@@ -546,6 +550,11 @@ int team_destroy(struct team_handle *th) + #endif + /* \endcond */ + ++/* libnl uses default 32k socket receive buffer size, ++ * whicn can get too small. Use 96k for all sockets. ++ */ ++#define NETLINK_RCVBUF 983040 ++ + /** + * @param th libteam library context + * @param ifindex team device interface index +@@ -561,6 +570,8 @@ int team_init(struct team_handle *th, uint32_t ifindex) + int err; + int grp_id; + int val; ++ int eventbufsize; ++ const char *env; + + if (!ifindex) { + err(th, "Passed interface index %d is not valid.", ifindex); +@@ -589,12 +600,12 @@ int team_init(struct team_handle *th, uint32_t ifindex) + return -errno; + } + +- err = nl_socket_set_buffer_size(th->nl_sock, 98304, 0); ++ err = nl_socket_set_buffer_size(th->nl_sock, NETLINK_RCVBUF, 0); + if (err) { + err(th, "Failed to set buffer size of netlink sock."); + return -nl2syserr(err); + } +- err = nl_socket_set_buffer_size(th->nl_sock_event, 98304, 0); ++ err = nl_socket_set_buffer_size(th->nl_sock_event, NETLINK_RCVBUF, 0); + if (err) { + err(th, "Failed to set buffer size of netlink event sock."); + return -nl2syserr(err); +@@ -627,6 +638,25 @@ int team_init(struct team_handle *th, uint32_t ifindex) + nl_socket_modify_cb(th->nl_cli.sock_event, NL_CB_VALID, + NL_CB_CUSTOM, cli_event_handler, th); + nl_cli_connect(th->nl_cli.sock_event, NETLINK_ROUTE); ++ ++ env = getenv("TEAM_EVENT_BUFSIZE"); ++ if (env) { ++ eventbufsize = strtol(env, NULL, 10); ++ /* ignore other errors, libnl forces minimum 32k and ++ * too large values are truncated to system rmem_max ++ */ ++ if (eventbufsize < 0) ++ eventbufsize = 0; ++ } else { ++ eventbufsize = NETLINK_RCVBUF; ++ } ++ ++ err = nl_socket_set_buffer_size(th->nl_cli.sock_event, eventbufsize, 0); ++ if (err) { ++ err(th, "Failed to set cli event socket buffer size."); ++ return err; ++ } ++ + err = nl_socket_add_membership(th->nl_cli.sock_event, RTNLGRP_LINK); + if (err < 0) { + err(th, "Failed to add netlink membership."); +@@ -767,7 +797,23 @@ static int get_cli_sock_event_fd(struct team_handle *th) + + static int cli_sock_event_handler(struct team_handle *th) + { +- nl_recvmsgs_default(th->nl_cli.sock_event); ++ int err; ++ ++ err = nl_recvmsgs_default(th->nl_cli.sock_event); ++ err = -nl2syserr(err); ++ ++ /* libnl thinks ENOBUFS and ENOMEM are same. Hope it was ENOBUFS. */ ++ if (err == -ENOMEM) { ++ warn(th, "Lost link notifications from kernel."); ++ /* There's no way to know what events were lost and no ++ * way to get them again. Refresh all. ++ */ ++ err = get_ifinfo_list(th); ++ } ++ ++ if (err) ++ return err; ++ + return check_call_change_handlers(th, TEAM_IFINFO_CHANGE); + } + +diff --git a/libteam/team_private.h b/libteam/team_private.h +index a07632f..a5eb0be 100644 +--- a/libteam/team_private.h ++++ b/libteam/team_private.h +@@ -115,6 +115,9 @@ int ifinfo_link_with_port(struct team_handle *th, uint32_t ifindex, + int ifinfo_link(struct team_handle *th, uint32_t ifindex, + struct team_ifinfo **p_ifinfo); + void ifinfo_unlink(struct team_ifinfo *ifinfo); ++void ifinfo_clear_changed(struct team_handle *th); ++void ifinfo_destroy_removed(struct team_handle *th); ++int get_ifinfo_list(struct team_handle *th); + int get_options_handler(struct nl_msg *msg, void *arg); + int option_list_alloc(struct team_handle *th); + int option_list_init(struct team_handle *th); diff --git a/src/libteam/series b/src/libteam/series index 415d6f79af92..3cdcbd993ca9 100644 --- a/src/libteam/series +++ b/src/libteam/series @@ -7,4 +7,5 @@ 0007-Skip-setting-the-same-hwaddr-to-lag-port-to-avoid-di.patch 0008-teamd-register-change-handler-for-TEAM_IFINFO_CHANGE.patch 0009-teamd-prevent-private-change-handler-reentrance.patch -0010-teamd-lacp-update-port-state-according-to-partners-sy.patch \ No newline at end of file +0010-teamd-lacp-update-port-state-according-to-partners-sy.patch +0011-libteam-resynchronize-ifinfo-after-lost-RTNLGRP_LINK-.patch \ No newline at end of file From c7af19a4dba50a7f573d31ebbeb0bf64b36d73b1 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Fri, 26 Apr 2019 15:12:33 -0700 Subject: [PATCH 04/88] [teamd service] start teamd service after swss (#2829) SWSS clears DB tables, if teamd is not started after swss, there is a race condition that swss might clear vital teamd information. Signed-off-by: Ying Xie --- files/build_templates/teamd.service.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/build_templates/teamd.service.j2 b/files/build_templates/teamd.service.j2 index 792b8247119f..8034698ecc07 100644 --- a/files/build_templates/teamd.service.j2 +++ b/files/build_templates/teamd.service.j2 @@ -1,7 +1,7 @@ [Unit] Description=TEAMD container Requires=updategraph.service -After=updategraph.service +After=updategraph.service swss.service Before=ntp-config.service [Service] From ad2c1b26dd438d026ce2001319482df8ebefe713 Mon Sep 17 00:00:00 2001 From: Shuotian Cheng Date: Fri, 26 Apr 2019 15:25:09 -0700 Subject: [PATCH 05/88] [minigraph]: Fix bug in copying list in Python (#2831) '=' cannot be used for copying the list Signed-off-by: Shu0T1an ChenG --- src/sonic-config-engine/minigraph.py | 2 +- src/sonic-config-engine/tests/test_cfggen.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 6553055b84c3..ac0f4922f94f 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -251,7 +251,7 @@ def parse_dpg(dpg, hname): # Erspan session will be attached to all front panel ports, # if panel ports is a member port of LAG, should add the LAG # to acl table instead of the panel ports - acl_intfs = pc_intfs + acl_intfs = pc_intfs[:] for panel_port in port_alias_map.values(): if panel_port not in intfs_inpc: acl_intfs.append(panel_port) diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 1755468300d5..4833530fb466 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -83,11 +83,11 @@ def test_minigraph_acl(self): "Warning: ignore interface 'fortyGigE0/2' in DEVICE_NEIGHBOR as it is not in the port_config.ini\n" "{'DATAACL': {'type': 'L3', 'policy_desc': 'DATAACL', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04']}, " "'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL'}, " - "'EVERFLOW': {'type': 'MIRROR', 'policy_desc': 'EVERFLOW', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet24', 'Ethernet40', 'Ethernet20', 'Ethernet44', 'Ethernet48', 'Ethernet28', 'Ethernet96', 'Ethernet92', 'Ethernet76', 'Ethernet72', 'Ethernet52', 'Ethernet80', 'Ethernet56', 'Ethernet32', 'Ethernet16', 'Ethernet36', 'Ethernet12', 'Ethernet60', 'Ethernet8', 'Ethernet4', 'Ethernet0', 'Ethernet64', 'Ethernet68', 'Ethernet84', 'Ethernet88', 'Ethernet108', 'Ethernet104', 'Ethernet100', 'Ethernet24', 'Ethernet40', 'Ethernet20', 'Ethernet44', 'Ethernet48', 'Ethernet28', 'Ethernet96', 'Ethernet92', 'Ethernet76', 'Ethernet72', 'Ethernet52', 'Ethernet80', 'Ethernet56', 'Ethernet32', 'Ethernet16', 'Ethernet36', 'Ethernet12', 'Ethernet60', 'Ethernet8', 'Ethernet4', 'Ethernet0', 'Ethernet64', 'Ethernet68', 'Ethernet84', 'Ethernet88', 'Ethernet108', 'Ethernet104', 'Ethernet100']}, " + "'EVERFLOW': {'type': 'MIRROR', 'policy_desc': 'EVERFLOW', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet24', 'Ethernet40', 'Ethernet20', 'Ethernet44', 'Ethernet48', 'Ethernet28', 'Ethernet96', 'Ethernet92', 'Ethernet76', 'Ethernet72', 'Ethernet52', 'Ethernet80', 'Ethernet56', 'Ethernet32', 'Ethernet16', 'Ethernet36', 'Ethernet12', 'Ethernet60', 'Ethernet8', 'Ethernet4', 'Ethernet0', 'Ethernet64', 'Ethernet68', 'Ethernet84', 'Ethernet88', 'Ethernet108', 'Ethernet104', 'Ethernet100']}, " "'ROUTER_PROTECT': {'services': ['SSH', 'SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'ROUTER_PROTECT'}, " "'SNMP_ACL': {'services': ['SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL'}, " "'SSH_ACL': {'services': ['SSH'], 'type': 'CTRLPLANE', 'policy_desc': 'SSH_ACL'}, " - "'EVERFLOWV6': {'type': 'MIRROR', 'policy_desc': 'EVERFLOWV6', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet24', 'Ethernet40', 'Ethernet20', 'Ethernet44', 'Ethernet48', 'Ethernet28', 'Ethernet96', 'Ethernet92', 'Ethernet76', 'Ethernet72', 'Ethernet52', 'Ethernet80', 'Ethernet56', 'Ethernet32', 'Ethernet16', 'Ethernet36', 'Ethernet12', 'Ethernet60', 'Ethernet8', 'Ethernet4', 'Ethernet0', 'Ethernet64', 'Ethernet68', 'Ethernet84', 'Ethernet88', 'Ethernet108', 'Ethernet104', 'Ethernet100', 'Ethernet24', 'Ethernet40', 'Ethernet20', 'Ethernet44', 'Ethernet48', 'Ethernet28', 'Ethernet96', 'Ethernet92', 'Ethernet76', 'Ethernet72', 'Ethernet52', 'Ethernet80', 'Ethernet56', 'Ethernet32', 'Ethernet16', 'Ethernet36', 'Ethernet12', 'Ethernet60', 'Ethernet8', 'Ethernet4', 'Ethernet0', 'Ethernet64', 'Ethernet68', 'Ethernet84', 'Ethernet88', 'Ethernet108', 'Ethernet104', 'Ethernet100']}}") + "'EVERFLOWV6': {'type': 'MIRROR', 'policy_desc': 'EVERFLOWV6', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet24', 'Ethernet40', 'Ethernet20', 'Ethernet44', 'Ethernet48', 'Ethernet28', 'Ethernet96', 'Ethernet92', 'Ethernet76', 'Ethernet72', 'Ethernet52', 'Ethernet80', 'Ethernet56', 'Ethernet32', 'Ethernet16', 'Ethernet36', 'Ethernet12', 'Ethernet60', 'Ethernet8', 'Ethernet4', 'Ethernet0', 'Ethernet64', 'Ethernet68', 'Ethernet84', 'Ethernet88', 'Ethernet108', 'Ethernet104', 'Ethernet100']}}") def test_minigraph_everflow(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v MIRROR_SESSION' From b186bb2c4c693981edf9e5279233e2a299e5b91c Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sun, 28 Apr 2019 22:51:46 -0700 Subject: [PATCH 06/88] [dhcp_relay] Base DHCP Relay Docker container on Debian Stretch (#2832) * Base DHCP relay Docker image on Strech base Docker * Change URL for isc-dhcp source repository * Upgrade isc-dhcp source branch to 4.3.5-3.1 * Update patch #0001 to apply to isc-dhcp 4.3.5-3.1 * Update patch #0002 to apply to isc-dhcp 4.3.5-3.1 * Update patch #0003 to apply to isc-dhcp 4.3.5-3.1 * Update patch #0004 to apply to isc-dhcp 4.3.5-3.1 * Remove security patches, as they are now applied as part of 4.3.5-3.1 source * Reorder patches to apply bug fix first, then features * Extend makefile to build debug Docker image * Update commit that series file applies against --- dockers/docker-dhcp-relay/Dockerfile.j2 | 2 +- rules/docker-dhcp-relay.mk | 18 +- rules/isc-dhcp.mk | 4 +- src/isc-dhcp/Makefile | 2 +- ...t-log-messages-to-stderr-in-release.patch} | 6 +- ...ion-82-circuit-ID-and-remote-ID-fiel.patch | 273 ------------------ ...ion-82-circuit-ID-and-remote-ID-fiel.patch | 265 +++++++++++++++++ ...ining-name-of-physical-interface-tha.patch | 114 -------- ...ing-port-alias-map-file-to-replace-p.patch | 187 ------------ ...ining-name-of-physical-interface-tha.patch | 98 +++++++ ...ing-port-alias-map-file-to-replace-p.patch | 189 ++++++++++++ src/isc-dhcp/patch/0005-CVE-2017-3144.patch | 47 --- src/isc-dhcp/patch/0006-CVE-2018-5733.patch | 145 ---------- src/isc-dhcp/patch/0007-CVE-2018-5732.patch | 144 --------- src/isc-dhcp/patch/series | 13 +- 15 files changed, 580 insertions(+), 927 deletions(-) rename src/isc-dhcp/patch/{0004-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch => 0001-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch} (82%) delete mode 100644 src/isc-dhcp/patch/0001-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch create mode 100644 src/isc-dhcp/patch/0002-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch delete mode 100644 src/isc-dhcp/patch/0002-Support-for-obtaining-name-of-physical-interface-tha.patch delete mode 100644 src/isc-dhcp/patch/0003-Support-for-loading-port-alias-map-file-to-replace-p.patch create mode 100644 src/isc-dhcp/patch/0003-Support-for-obtaining-name-of-physical-interface-tha.patch create mode 100644 src/isc-dhcp/patch/0004-Support-for-loading-port-alias-map-file-to-replace-p.patch delete mode 100644 src/isc-dhcp/patch/0005-CVE-2017-3144.patch delete mode 100644 src/isc-dhcp/patch/0006-CVE-2018-5733.patch delete mode 100644 src/isc-dhcp/patch/0007-CVE-2018-5732.patch diff --git a/dockers/docker-dhcp-relay/Dockerfile.j2 b/dockers/docker-dhcp-relay/Dockerfile.j2 index 0a760d301f3a..3db714d4df94 100644 --- a/dockers/docker-dhcp-relay/Dockerfile.j2 +++ b/dockers/docker-dhcp-relay/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine +FROM docker-config-engine-stretch ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf diff --git a/rules/docker-dhcp-relay.mk b/rules/docker-dhcp-relay.mk index 44d3904d7394..f1f19d974a8e 100644 --- a/rules/docker-dhcp-relay.mk +++ b/rules/docker-dhcp-relay.mk @@ -1,12 +1,24 @@ # Docker image for DHCP relay -DOCKER_DHCP_RELAY = docker-dhcp-relay.gz -$(DOCKER_DHCP_RELAY)_PATH = $(DOCKERS_PATH)/docker-dhcp-relay +DOCKER_DHCP_RELAY_STEM = docker-dhcp-relay +DOCKER_DHCP_RELAY = $(DOCKER_DHCP_RELAY_STEM).gz +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_COMMON) $(ISC_DHCP_RELAY) -$(DOCKER_DHCP_RELAY)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE) +$(DOCKER_DHCP_RELAY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_DHCP_RELAY)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) + +$(DOCKER_DHCP_RELAY)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_STRETCH) + SONIC_DOCKER_IMAGES += $(DOCKER_DHCP_RELAY) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_DHCP_RELAY) +SONIC_STRETCH_DOCKERS += $(DOCKER_DHCP_RELAY) +SONIC_DOCKER_DBG_IMAGES += $(DOCKER_DHCP_RELAY_DBG) +SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_DHCP_RELAY_DBG) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_DHCP_RELAY_DBG) $(DOCKER_DHCP_RELAY)_CONTAINER_NAME = dhcp_relay $(DOCKER_DHCP_RELAY)_RUN_OPT += --net=host --privileged -t diff --git a/rules/isc-dhcp.mk b/rules/isc-dhcp.mk index 7b7f69c6cfc6..16b14ac5c082 100644 --- a/rules/isc-dhcp.mk +++ b/rules/isc-dhcp.mk @@ -1,6 +1,6 @@ # isc-dhcp packages -ISC_DHCP_VERSION = 4.3.3-6 +ISC_DHCP_VERSION = 4.3.5-3.1 export ISC_DHCP_VERSION @@ -10,3 +10,5 @@ SONIC_MAKE_DEBS += $(ISC_DHCP_COMMON) ISC_DHCP_RELAY = isc-dhcp-relay_$(ISC_DHCP_VERSION)_amd64.deb $(eval $(call add_derived_package,$(ISC_DHCP_COMMON),$(ISC_DHCP_RELAY))) + +SONIC_STRETCH_DEBS += $(ISC_DHCP_COMMON) $(ISC_DHCP_RELAY) diff --git a/src/isc-dhcp/Makefile b/src/isc-dhcp/Makefile index ce4fbc62608f..1227b3a0c33f 100644 --- a/src/isc-dhcp/Makefile +++ b/src/isc-dhcp/Makefile @@ -10,7 +10,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : rm -rf ./isc-dhcp # Clone isc-dhcp repo - git clone https://salsa.debian.org/berni/isc-dhcp.git + git clone https://salsa.debian.org/dhcp-team/isc-dhcp.git pushd ./isc-dhcp # Reset HEAD to the commit of the proper tag diff --git a/src/isc-dhcp/patch/0004-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch b/src/isc-dhcp/patch/0001-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch similarity index 82% rename from src/isc-dhcp/patch/0004-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch rename to src/isc-dhcp/patch/0001-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch index 428f4471a1f7..2ddbc1a90f93 100644 --- a/src/isc-dhcp/patch/0004-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch +++ b/src/isc-dhcp/patch/0001-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch @@ -1,6 +1,6 @@ -From 2bb21fcf4a9ad7535867809c50d2cf0ba1088e17 Mon Sep 17 00:00:00 2001 +From 7c1cfd636be589317710a8556a7ec667debee53a Mon Sep 17 00:00:00 2001 From: Joe LeVeque -Date: Fri, 9 Mar 2018 01:43:35 +0000 +Date: Fri, 26 Apr 2019 01:37:54 +0000 Subject: [PATCH] [Bugfix] Don't print log messages to stderr in release builds --- @@ -24,5 +24,5 @@ index 7c91d9d..aa74fd8 100644 void (*log_cleanup) (void); -- -2.1.4 +2.17.1 diff --git a/src/isc-dhcp/patch/0001-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch b/src/isc-dhcp/patch/0001-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch deleted file mode 100644 index 22a8f7faedd1..000000000000 --- a/src/isc-dhcp/patch/0001-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch +++ /dev/null @@ -1,273 +0,0 @@ -From 284c87ff4b3873d0215904273fe3c86b07b4ba94 Mon Sep 17 00:00:00 2001 -From: Joe LeVeque -Date: Mon, 11 Dec 2017 23:21:08 +0000 -Subject: [PATCH 1/3] Customizable Option 82 circuit ID and remote ID fields - ---- - relay/dhcrelay.c | 182 ++++++++++++++++++++++++++++++++++++++++++++++--------- - 1 file changed, 152 insertions(+), 30 deletions(-) - -diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c -index 15b4997..b9f8326 100644 ---- a/relay/dhcrelay.c -+++ b/relay/dhcrelay.c -@@ -73,6 +73,8 @@ int bad_circuit_id = 0; /* Circuit ID option in matching RAI option - did not match any known circuit ID. */ - int missing_circuit_id = 0; /* Circuit ID option in matching RAI option - was missing. */ -+const char *agent_circuit_id_fmt = NULL; /* Circuit ID custom format string. */ -+const char *agent_remote_id_fmt = NULL; /* Remote ID custom format string. */ - int max_hop_count = 10; /* Maximum hop count */ - - #ifdef DHCPv6 -@@ -140,9 +142,19 @@ static const char message[] = - static const char url[] = - "For info, please visit https://www.isc.org/software/dhcp/"; - -+#define DHCRELAY_OPTION82_USAGE \ -+"circuit_id/remote_id interpreted sequences are:\n" \ -+"\n" \ -+" %%%% A single %%\n" \ -+" %%h Hostname of device\n" \ -+" %%p Name of interface that generated the request\n" \ -+" %%P Hardware address of interface that generated the request\n" \ -+" %%C Client hardware address\n" \ -+" %%I DHCP relay agent IP Address\n" \ -+ - #ifdef DHCPv6 - #define DHCRELAY_USAGE \ --"Usage: dhcrelay [-4] [-d] [-q] [-a] [-D]\n"\ -+"Usage: dhcrelay [-4] [-d] [-q] [-a ] [-D]\n"\ - " [-A ] [-c ] [-p ]\n" \ - " [-pf ] [--no-pid]\n"\ - " [-m append|replace|forward|discard]\n" \ -@@ -154,14 +166,15 @@ static const char url[] = - " -l lower0 [ ... -l lowerN]\n" \ - " -u upper0 [ ... -u upperN]\n" \ - " lower (client link): [address%%]interface[#index]\n" \ --" upper (server link): [address%%]interface" -+" upper (server link): [address%%]interface\n\n" DHCRELAY_OPTION82_USAGE - #else - #define DHCRELAY_USAGE \ --"Usage: dhcrelay [-d] [-q] [-a] [-D] [-A ] [-c ] [-p ]\n" \ --" [-pf ] [--no-pid]\n" \ -+"Usage: dhcrelay [-d] [-q] [-a ] [-D]\n" \ -+" [-A ] [-c ] [-p ]\n" \ -+" [-pf ] [--no-pid]\n"\ - " [-m append|replace|forward|discard]\n" \ - " [-i interface0 [ ... -i interfaceN]\n" \ --" server0 [ ... serverN]\n\n" -+" server0 [ ... serverN]\n\n" DHCRELAY_OPTION82_USAGE - #endif - - static void usage() { -@@ -287,6 +300,15 @@ main(int argc, char **argv) { - local_family_set = 1; - local_family = AF_INET; - #endif -+ if (++i == argc) -+ usage(); -+ -+ if (argv[i] != NULL && argv[i][0] != '-') -+ agent_circuit_id_fmt = argv[i++]; -+ -+ if (argv[i] != NULL && argv[i][0] != '-') -+ agent_remote_id_fmt = argv[i]; -+ - add_agent_options = 1; - } else if (!strcmp(argv[i], "-A")) { - #ifdef DHCPv6 -@@ -938,6 +960,80 @@ find_interface_by_agent_option(struct dhcp_packet *packet, - } - - /* -+ * Format the message that will be used by circuit_id and remote_id -+ */ -+static int -+format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_packet *packet, -+ const char *format, char *msg, size_t msgn) { -+ size_t len = 0; -+ char hostname[HOST_NAME_MAX] = { 0 }; -+ char ifname[IFNAMSIZ] = { 0 }; -+ char *buf = msg; -+ -+ for ( ; format && *format && len < msgn; ++format) { -+ size_t strn = 0; -+ const char *str = NULL; -+ -+ if (*format == '%') { -+ switch (*++format) { -+ case '\0': -+ --format; -+ break; -+ -+ case '%': /* A literal '%' */ -+ str = "%"; -+ break; -+ -+ case 'h': /* Hostname */ -+ gethostname(hostname, HOST_NAME_MAX); -+ hostname[HOST_NAME_MAX - 1] = '\0'; -+ str = hostname; -+ break; -+ -+ case 'p': /* Name of interface that we received the request from */ -+ strncpy(ifname, ip->name, IFNAMSIZ); -+ str = ifname; -+ break; -+ -+ case 'P': /* Physical address of interface that we received the request from */ -+ str = print_hw_addr(ip->hw_address.hbuf[0], ip->hw_address.hlen - 1, &ip->hw_address.hbuf[1]); -+ break; -+ -+ case 'C': /* 24: Client hardware address */ -+ str = print_hw_addr(packet->htype, packet->hlen, packet->chaddr); -+ break; -+ -+ case 'I': /* 20: DHCP relay agent IP address */ -+ str = inet_ntoa(packet->giaddr); -+ break; -+ -+ default: -+ log_error("Option %%%c is unrecognized and will not be formatted!", *format); -+ continue; -+ } -+ -+ if (str) -+ strn = strlen(str); -+ } else { -+ str = format; -+ strn = 1; -+ } -+ -+ // Do we have room? -+ if ((strn+len) >= msgn) { -+ return 0; -+ } -+ -+ if (str && strn > 0) { -+ memcpy(buf+len, str, strn); -+ len += strn; -+ } -+ } -+ -+ return len; -+} -+ -+/* - * Examine a packet to see if it's a candidate to have a Relay - * Agent Information option tacked onto its tail. If it is, tack - * the option on. -@@ -946,8 +1042,11 @@ static int - add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, - unsigned length, struct in_addr giaddr) { - int is_dhcp = 0, mms; -- unsigned optlen; -+ unsigned optlen = 0; - u_int8_t *op, *nextop, *sp, *max, *end_pad = NULL; -+ char circuit_id_buf[256] = { '\0' }; -+ char remote_id_buf[256] = { '\0' }; -+ size_t circuit_id_len = 0, remote_id_len = 0; - - /* If we're not adding agent options to packets, we can skip - this. */ -@@ -1077,24 +1176,47 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, - op = sp; - #endif - -- /* Sanity check. Had better not ever happen. */ -- if ((ip->circuit_id_len > 255) ||(ip->circuit_id_len < 1)) -- log_fatal("Circuit ID length %d out of range [1-255] on " -- "%s\n", ip->circuit_id_len, ip->name); -- optlen = ip->circuit_id_len + 2; /* RAI_CIRCUIT_ID + len */ -- -- if (ip->remote_id) { -- if (ip->remote_id_len > 255 || ip->remote_id_len < 1) -- log_fatal("Remote ID length %d out of range [1-255] " -- "on %s\n", ip->circuit_id_len, ip->name); -- optlen += ip->remote_id_len + 2; /* RAI_REMOTE_ID + len */ -- } -+ /* option82: custom string for circuit_id */ -+ if (agent_circuit_id_fmt) { -+ circuit_id_len = format_relay_agent_rfc3046_msg(ip, packet, agent_circuit_id_fmt, -+ circuit_id_buf, sizeof(circuit_id_buf)); -+ -+ if (circuit_id_len == 0) { -+ strncpy(circuit_id_buf, ip->name, sizeof(ip->name)); -+ circuit_id_len = strlen(circuit_id_buf); -+ } -+ -+ /* Sanity check. Had better not ever happen. */ -+ if (circuit_id_len > 255 || circuit_id_len < 1) -+ log_fatal("Circuit ID length %d out of range [1-255] on %s\n", -+ (int)circuit_id_len, ip->name); -+ -+ optlen = circuit_id_len + 2; // RAI_CIRCUIT_ID + len -+ -+ //log_debug("Sending on %s option82:circuit_id='%s' (%d)", -+ // ip->name, circuit_id_buf, (int)circuit_id_len); -+ } -+ -+ /* option82: custom string for remote_id */ -+ if (agent_remote_id_fmt) { -+ remote_id_len = format_relay_agent_rfc3046_msg(ip, packet, agent_remote_id_fmt, -+ remote_id_buf, sizeof(remote_id_buf)); -+ -+ if (remote_id_len > 255 || remote_id_len < 1) -+ log_fatal("Remote ID length %d out of range [1-255] on %s\n", -+ (int)remote_id_len, ip->name); -+ -+ optlen += remote_id_len + 2; // RAI_REMOTE_ID + len -+ -+ //log_debug("Sending on %s option82:remote_id='%s' (%d)", -+ // ip->name, remote_id_buf, (int)remote_id_len); -+ } - -- /* We do not support relay option fragmenting(multiple options to -- * support an option data exceeding 255 bytes). -+ /* We do not support relay option fragmenting (multiple options to -+ * support an option data exceeding 255 bytes) - */ -- if ((optlen < 3) ||(optlen > 255)) -- log_fatal("Total agent option length(%u) out of range " -+ if (optlen < 3 || optlen > 255) -+ log_fatal("Total agent option length (%u) out of range " - "[3 - 255] on %s\n", optlen, ip->name); - - /* -@@ -1102,7 +1224,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, - * If not, forward without adding the option. - */ - if (max - sp >= optlen + 3) { -- log_debug("Adding %d-byte relay agent option", optlen + 3); -+ //log_debug("Adding %d-byte relay agent option", optlen + 3); - - /* Okay, cons up *our* Relay Agent Information option. */ - *sp++ = DHO_DHCP_AGENT_OPTIONS; -@@ -1110,16 +1232,16 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, - - /* Copy in the circuit id... */ - *sp++ = RAI_CIRCUIT_ID; -- *sp++ = ip->circuit_id_len; -- memcpy(sp, ip->circuit_id, ip->circuit_id_len); -- sp += ip->circuit_id_len; -+ *sp++ = circuit_id_len; -+ memcpy(sp, circuit_id_buf, circuit_id_len); -+ sp += circuit_id_len; - - /* Copy in remote ID... */ -- if (ip->remote_id) { -+ if (remote_id_len > 0) { - *sp++ = RAI_REMOTE_ID; -- *sp++ = ip->remote_id_len; -- memcpy(sp, ip->remote_id, ip->remote_id_len); -- sp += ip->remote_id_len; -+ *sp++ = remote_id_len; -+ memcpy(sp, remote_id_buf, remote_id_len); -+ sp += remote_id_len; - } - } else { - ++agent_option_errors; --- -2.1.4 - diff --git a/src/isc-dhcp/patch/0002-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch b/src/isc-dhcp/patch/0002-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch new file mode 100644 index 000000000000..a796845e516b --- /dev/null +++ b/src/isc-dhcp/patch/0002-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch @@ -0,0 +1,265 @@ +From 6b4c2e815118fb7312b8e8a07ac61a772b57e91a Mon Sep 17 00:00:00 2001 +From: Joe LeVeque +Date: Thu, 25 Apr 2019 22:07:20 +0000 +Subject: [PATCH] Customizable Option 82 circuit ID and remote ID fields + +--- + relay/dhcrelay.c | 171 ++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 147 insertions(+), 24 deletions(-) + +diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c +index 344cee7..7b4c1ef 100644 +--- a/relay/dhcrelay.c ++++ b/relay/dhcrelay.c +@@ -75,6 +75,8 @@ int bad_circuit_id = 0; /* Circuit ID option in matching RAI option + did not match any known circuit ID. */ + int missing_circuit_id = 0; /* Circuit ID option in matching RAI option + was missing. */ ++const char *agent_circuit_id_fmt = NULL; /* Circuit ID custom format string. */ ++const char *agent_remote_id_fmt = NULL; /* Remote ID custom format string. */ + int max_hop_count = 10; /* Maximum hop count */ + + #ifdef DHCPv6 +@@ -148,9 +150,19 @@ static const char url[] = + + char *progname; + ++#define DHCRELAY_OPTION82_USAGE \ ++"circuit_id/remote_id interpreted sequences are:\n" \ ++"\n" \ ++" %%%% A single %%\n" \ ++" %%h Hostname of device\n" \ ++" %%p Name of interface that generated the request\n" \ ++" %%P Hardware address of interface that generated the request\n" \ ++" %%C Client hardware address\n" \ ++" %%I DHCP relay agent IP Address\n" \ ++ + #ifdef DHCPv6 + #define DHCRELAY_USAGE \ +-"Usage: %s [-4] [-d] [-q] [-a] [-D]\n"\ ++"Usage: %s [-4] [-d] [-q] [-a ] [-D]\n"\ + " [-A ] [-c ] [-p ]\n" \ + " [-pf ] [--no-pid]\n"\ + " [-m append|replace|forward|discard]\n" \ +@@ -165,17 +177,18 @@ char *progname; + " -l lower0 [ ... -l lowerN]\n" \ + " -u upper0 [ ... -u upperN]\n" \ + " lower (client link): [address%%]interface[#index]\n" \ +-" upper (server link): [address%%]interface" ++" upper (server link): [address%%]interface\n\n" DHCRELAY_OPTION82_USAGE + #else + #define DHCRELAY_USAGE \ +-"Usage: %s [-d] [-q] [-a] [-D] [-A ] [-c ] [-p ]\n" \ ++"Usage: %s [-d] [-q] [-a ] [-D]\n" \ ++" [-A ] [-c ] [-p ]\n" \ + " [-pf ] [--no-pid]\n" \ + " [-m append|replace|forward|discard]\n" \ + " [-i interface0 [ ... -i interfaceN]\n" \ + " [-iu interface0 [ ... -iu interfaceN]\n" \ + " [-id interface0 [ ... -id interfaceN]\n" \ + " [-U interface]\n" \ +-" server0 [ ... serverN]\n\n" ++" server0 [ ... serverN]\n\n" DHCRELAY_OPTION82_USAGE + #endif + + /*! +@@ -354,6 +367,15 @@ main(int argc, char **argv) { + local_family_set = 1; + local_family = AF_INET; + #endif ++ if (++i == argc) ++ usage(use_noarg, argv[i-1]); ++ ++ if (argv[i] != NULL && argv[i][0] != '-') ++ agent_circuit_id_fmt = argv[i++]; ++ ++ if (argv[i] != NULL && argv[i][0] != '-') ++ agent_remote_id_fmt = argv[i]; ++ + add_agent_options = 1; + } else if (!strcmp(argv[i], "-A")) { + #ifdef DHCPv6 +@@ -1050,6 +1072,81 @@ find_interface_by_agent_option(struct dhcp_packet *packet, + return (-1); + } + ++/* ++ * Format the message that will be used by circuit_id and remote_id ++ */ ++static int ++format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_packet *packet, ++ const char *format, char *msg, size_t msgn) { ++ size_t len = 0; ++ char hostname[HOST_NAME_MAX] = { 0 }; ++ char ifname[IFNAMSIZ] = { 0 }; ++ char *buf = msg; ++ ++ for ( ; format && *format && len < msgn; ++format) { ++ size_t strn = 0; ++ const char *str = NULL; ++ ++ if (*format == '%') { ++ switch (*++format) { ++ case '\0': ++ --format; ++ break; ++ ++ case '%': /* A literal '%' */ ++ str = "%"; ++ break; ++ ++ case 'h': /* Hostname */ ++ gethostname(hostname, HOST_NAME_MAX); ++ hostname[HOST_NAME_MAX - 1] = '\0'; ++ str = hostname; ++ break; ++ ++ case 'p': /* Name of interface that we received the request from */ ++ strncpy(ifname, ip->name, IFNAMSIZ); ++ str = ifname; ++ break; ++ ++ case 'P': /* Physical address of interface that we received the request from */ ++ str = print_hw_addr(ip->hw_address.hbuf[0], ip->hw_address.hlen - 1, &ip->hw_address.hbuf[1]); ++ break; ++ ++ case 'C': /* 24: Client hardware address */ ++ str = print_hw_addr(packet->htype, packet->hlen, packet->chaddr); ++ break; ++ ++ case 'I': /* 20: DHCP relay agent IP address */ ++ str = inet_ntoa(packet->giaddr); ++ break; ++ ++ default: ++ log_error("Option %%%c is unrecognized and will not be formatted!", *format); ++ continue; ++ } ++ ++ if (str) { ++ strn = strlen(str); ++ } ++ } else { ++ str = format; ++ strn = 1; ++ } ++ ++ // Do we have room? ++ if ((strn+len) >= msgn) { ++ return 0; ++ } ++ ++ if (str && strn > 0) { ++ memcpy(buf+len, str, strn); ++ len += strn; ++ } ++ } ++ ++ return len; ++} ++ + /* + * Examine a packet to see if it's a candidate to have a Relay + * Agent Information option tacked onto its tail. If it is, tack +@@ -1059,9 +1156,12 @@ static int + add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, + unsigned length, struct in_addr giaddr) { + int is_dhcp = 0, mms; +- unsigned optlen; ++ unsigned optlen = 0; + u_int8_t *op, *nextop, *sp, *max, *end_pad = NULL; + int adding_link_select; ++ char circuit_id_buf[256] = { '\0' }; ++ char remote_id_buf[256] = { '\0' }; ++ size_t circuit_id_len = 0, remote_id_len = 0; + + /* If we're not adding agent options to packets, we can skip + this. */ +@@ -1195,17 +1295,40 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, + op = sp; + #endif + +- /* Sanity check. Had better not ever happen. */ +- if ((ip->circuit_id_len > 255) ||(ip->circuit_id_len < 1)) +- log_fatal("Circuit ID length %d out of range [1-255] on " +- "%s\n", ip->circuit_id_len, ip->name); +- optlen = ip->circuit_id_len + 2; /* RAI_CIRCUIT_ID + len */ +- +- if (ip->remote_id) { +- if (ip->remote_id_len > 255 || ip->remote_id_len < 1) +- log_fatal("Remote ID length %d out of range [1-255] " +- "on %s\n", ip->remote_id_len, ip->name); +- optlen += ip->remote_id_len + 2; /* RAI_REMOTE_ID + len */ ++ /* option82: custom string for circuit_id */ ++ if (agent_circuit_id_fmt) { ++ circuit_id_len = format_relay_agent_rfc3046_msg(ip, packet, agent_circuit_id_fmt, ++ circuit_id_buf, sizeof(circuit_id_buf)); ++ ++ if (circuit_id_len == 0) { ++ strncpy(circuit_id_buf, ip->name, sizeof(ip->name)); ++ circuit_id_len = strlen(circuit_id_buf); ++ } ++ ++ /* Sanity check. Had better not ever happen. */ ++ if (circuit_id_len > 255 || circuit_id_len < 1) ++ log_fatal("Circuit ID length %d out of range [1-255] on %s\n", ++ (int)circuit_id_len, ip->name); ++ ++ optlen = circuit_id_len + 2; // RAI_CIRCUIT_ID + len ++ ++ //log_debug("Sending on %s option82:circuit_id='%s' (%d)", ++ // ip->name, circuit_id_buf, (int)circuit_id_len); ++ } ++ ++ /* option82: custom string for remote_id */ ++ if (agent_remote_id_fmt) { ++ remote_id_len = format_relay_agent_rfc3046_msg(ip, packet, agent_remote_id_fmt, ++ remote_id_buf, sizeof(remote_id_buf)); ++ ++ if (remote_id_len > 255 || remote_id_len < 1) ++ log_fatal("Remote ID length %d out of range [1-255] on %s\n", ++ (int)remote_id_len, ip->name); ++ ++ optlen += remote_id_len + 2; // RAI_REMOTE_ID + len ++ ++ //log_debug("Sending on %s option82:remote_id='%s' (%d)", ++ // ip->name, remote_id_buf, (int)remote_id_len); + } + + if (adding_link_select) { +@@ -1224,7 +1347,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, + * If not, forward without adding the option. + */ + if (max - sp >= optlen + 3) { +- log_debug("Adding %d-byte relay agent option", optlen + 3); ++ //log_debug("Adding %d-byte relay agent option", optlen + 3); + + /* Okay, cons up *our* Relay Agent Information option. */ + *sp++ = DHO_DHCP_AGENT_OPTIONS; +@@ -1232,16 +1355,16 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, + + /* Copy in the circuit id... */ + *sp++ = RAI_CIRCUIT_ID; +- *sp++ = ip->circuit_id_len; +- memcpy(sp, ip->circuit_id, ip->circuit_id_len); +- sp += ip->circuit_id_len; ++ *sp++ = circuit_id_len; ++ memcpy(sp, circuit_id_buf, circuit_id_len); ++ sp += circuit_id_len; + + /* Copy in remote ID... */ +- if (ip->remote_id) { ++ if (remote_id_len > 0) { + *sp++ = RAI_REMOTE_ID; +- *sp++ = ip->remote_id_len; +- memcpy(sp, ip->remote_id, ip->remote_id_len); +- sp += ip->remote_id_len; ++ *sp++ = remote_id_len; ++ memcpy(sp, remote_id_buf, remote_id_len); ++ sp += remote_id_len; + } + + /* RFC3527: Use the inbound packet's interface address in +-- +2.17.1 + diff --git a/src/isc-dhcp/patch/0002-Support-for-obtaining-name-of-physical-interface-tha.patch b/src/isc-dhcp/patch/0002-Support-for-obtaining-name-of-physical-interface-tha.patch deleted file mode 100644 index ee85a7736287..000000000000 --- a/src/isc-dhcp/patch/0002-Support-for-obtaining-name-of-physical-interface-tha.patch +++ /dev/null @@ -1,114 +0,0 @@ -From caad3e05c31c9fad8cda378ce95a1969def771a2 Mon Sep 17 00:00:00 2001 -From: Joe LeVeque -Date: Mon, 11 Dec 2017 23:39:10 +0000 -Subject: [PATCH 2/3] Support for obtaining name of physical interface that is - a member of a bridge interface - ---- - relay/dhcrelay.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 67 insertions(+), 2 deletions(-) - -diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c -index b9f8326..8458ea9 100644 ---- a/relay/dhcrelay.c -+++ b/relay/dhcrelay.c -@@ -758,6 +758,7 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet, - print_hw_addr(packet->htype, packet->hlen, - packet->chaddr), - inet_ntoa(sp->to.sin_addr)); -+ - ++client_packets_relayed; - } - } -@@ -917,6 +918,7 @@ find_interface_by_agent_option(struct dhcp_packet *packet, - ++corrupt_agent_options; - return (-1); - } -+ - switch(buf[i]) { - /* Remember where the circuit ID is... */ - case RAI_CIRCUIT_ID: -@@ -959,6 +961,47 @@ find_interface_by_agent_option(struct dhcp_packet *packet, - return (-1); - } - -+static int -+_bridgefdbquery(const char *hwAddr, char *interface, int *vlanid) { -+ -+#define xstr(s) str(s) -+#define str(s) #s -+#define FDB_STRING_LEN 100 -+#define FDB_BUFFER_LEN (FDB_STRING_LEN + 1) -+ -+/* -+ * Format for sscanf() to read the 1st, 3th, and 5th -+ * space-delimited fields -+ * -+ * bridge fdb show output -+ * 6c:64:1a:00:06:13 dev swp35 vlan 0 master bridge permanent -+ */ -+#define FDB_LINE_FORMAT "%" xstr(FDB_STRING_LEN) "s %*s " \ -+ "%" xstr(FDB_STRING_LEN) "s %*s %d %*s" -+ -+ char cmdstr[FDB_BUFFER_LEN]; -+ char buf[FDB_BUFFER_LEN]; -+ char macAddr[FDB_BUFFER_LEN]; -+ -+ if ((interface == NULL) || (vlanid == NULL)) { -+ return 0; -+ } -+ sprintf(cmdstr, "bridge fdb show | grep -m 1 %s", hwAddr); -+ FILE *cmd = popen(cmdstr, "r"); -+ -+ if (cmd != NULL) { -+ while (fgets(buf, sizeof(buf), cmd)) { -+ sscanf(buf, FDB_LINE_FORMAT, macAddr, interface, vlanid); -+ //log_debug("bridgefdbquery: macAddr: %s interface: %s vlanid: %d", -+ // macAddr, interface, *vlanid); -+ } -+ pclose(cmd); -+ return 0; -+ } -+ -+ return -1; -+} -+ - /* - * Format the message that will be used by circuit_id and remote_id - */ -@@ -991,8 +1034,30 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack - break; - - case 'p': /* Name of interface that we received the request from */ -- strncpy(ifname, ip->name, IFNAMSIZ); -- str = ifname; -+ /* -+ * Query FDB to identify the exact physical interface only when source MAC address -+ * is present and '20: DHCP relay agent IP address' (giaddr) is not present -+ */ -+ if (packet->htype && !packet->giaddr.s_addr) { -+ int ret = 0, vlanid = 0; -+ -+ ret = _bridgefdbquery(print_hw_addr(packet->htype, packet->hlen, packet->chaddr), -+ ifname, -+ &vlanid); -+ -+ // If we failed to find a physical interface using the source mac, default -+ // to the interface name we received it on. -+ if (ret < 0) { -+ //log_debug("MAC Address: %s (interface:%s vlan:%d) not found in bridge fdb show", -+ // print_hw_addr (packet->htype, packet->hlen, packet->chaddr), -+ // ip->name, -+ // vlanid); -+ -+ strncpy(ifname, ip->name, IFNAMSIZ); -+ } -+ -+ str = ifname; -+ } - break; - - case 'P': /* Physical address of interface that we received the request from */ --- -2.1.4 - diff --git a/src/isc-dhcp/patch/0003-Support-for-loading-port-alias-map-file-to-replace-p.patch b/src/isc-dhcp/patch/0003-Support-for-loading-port-alias-map-file-to-replace-p.patch deleted file mode 100644 index 7411e1c4ff3e..000000000000 --- a/src/isc-dhcp/patch/0003-Support-for-loading-port-alias-map-file-to-replace-p.patch +++ /dev/null @@ -1,187 +0,0 @@ -From 3a42b497716375c9347b51c3a28c5e91e7cd4cf4 Mon Sep 17 00:00:00 2001 -From: Joe LeVeque -Date: Tue, 12 Dec 2017 00:49:09 +0000 -Subject: [PATCH 3/3] Support for loading port alias map file to replace port - name with alias in circuit id - ---- - relay/dhcrelay.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 105 insertions(+), 1 deletion(-) - -diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c -index 8458ea9..15f0acf 100644 ---- a/relay/dhcrelay.c -+++ b/relay/dhcrelay.c -@@ -122,6 +122,14 @@ static void setup_streams(void); - char *dhcrelay_sub_id = NULL; - #endif - -+struct interface_name_alias_tuple { -+ char if_name[IFNAMSIZ]; -+ char if_alias[IFNAMSIZ]; -+}; -+ -+static struct interface_name_alias_tuple *g_interface_name_alias_map = NULL; -+static size_t g_interface_name_alias_map_size = 0; -+ - static void do_relay4(struct interface_info *, struct dhcp_packet *, - unsigned int, unsigned int, struct iaddr, - struct hardware *); -@@ -134,6 +142,10 @@ static int strip_relay_agent_options(struct interface_info *, - struct interface_info **, - struct dhcp_packet *, unsigned); - -+static int load_interface_alias_map(const char *port_alias_map_file_path); -+static int get_interface_alias_by_name(const char *if_name, char *if_alias_out); -+static void free_interface_alias_map(void); -+ - static const char copyright[] = - "Copyright 2004-2015 Internet Systems Consortium."; - static const char arr[] = "All rights reserved."; -@@ -147,7 +159,7 @@ static const char url[] = - "\n" \ - " %%%% A single %%\n" \ - " %%h Hostname of device\n" \ --" %%p Name of interface that generated the request\n" \ -+" %%p Alias of interface that generated the request\n" \ - " %%P Hardware address of interface that generated the request\n" \ - " %%C Client hardware address\n" \ - " %%I DHCP relay agent IP Address\n" \ -@@ -158,10 +170,12 @@ static const char url[] = - " [-A ] [-c ] [-p ]\n" \ - " [-pf ] [--no-pid]\n"\ - " [-m append|replace|forward|discard]\n" \ -+" [--name-alias-map-file ]\n" \ - " [-i interface0 [ ... -i interfaceN]\n" \ - " server0 [ ... serverN]\n\n" \ - " dhcrelay -6 [-d] [-q] [-I] [-c ] [-p ]\n" \ - " [-pf ] [--no-pid]\n" \ -+" [--name-alias-map-file ]\n" \ - " [-s ]\n" \ - " -l lower0 [ ... -l lowerN]\n" \ - " -u upper0 [ ... -u upperN]\n" \ -@@ -405,6 +419,11 @@ main(int argc, char **argv) { - no_dhcrelay_pid = ISC_TRUE; - } else if (!strcmp(argv[i], "--no-pid")) { - no_pid_file = ISC_TRUE; -+ } else if (!strcmp(argv[i], "--name-alias-map-file")) { -+ if (++i == argc) -+ usage(); -+ if (load_interface_alias_map(argv[i]) != 0) -+ log_fatal("Failed to load interface name-alias map."); - } else if (!strcmp(argv[i], "--version")) { - log_info("isc-dhcrelay-%s", PACKAGE_VERSION); - exit(0); -@@ -624,6 +643,8 @@ main(int argc, char **argv) { - dispatch(); - - /* In fact dispatch() never returns. */ -+ free_interface_alias_map(); -+ - return (0); - } - -@@ -1040,6 +1061,7 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack - */ - if (packet->htype && !packet->giaddr.s_addr) { - int ret = 0, vlanid = 0; -+ char ifalias[IFNAMSIZ] = { 0 }; - - ret = _bridgefdbquery(print_hw_addr(packet->htype, packet->hlen, packet->chaddr), - ifname, -@@ -1056,6 +1078,18 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack - strncpy(ifname, ip->name, IFNAMSIZ); - } - -+ // Attempt to translate SONiC interface name to vendor alias -+ ret = get_interface_alias_by_name(ifname, ifalias); -+ if (ret < 0) { -+ //log_debug("Failed to retrieve alias for interface name '%s'. Defaulting to interface name.", ifname); -+ } -+ else { -+ //log_debug("Mapped interface name '%s' to alias '%s'. Adding as option 82 interface alias for MAC Address %s", -+ // ifname, ifalias, print_hw_addr (packet->htype, packet->hlen, packet->chaddr)); -+ -+ strncpy(ifname, ifalias, IFNAMSIZ); -+ } -+ - str = ifname; - } - break; -@@ -1922,3 +1956,73 @@ dhcp_set_control_state(control_object_state_t oldstate, - - exit(0); - } -+ -+#define MAX_PORT_CONFIG_LINE_LEN 1024 -+ -+// Allocates and loads global map g_interface_name_alias_map -+// Also sets global g_interface_name_alias_map_size -+static int -+load_interface_alias_map(const char *port_alias_map_file_path) { -+ int i = 0; -+ FILE *fp = NULL; -+ char line[MAX_PORT_CONFIG_LINE_LEN] = { 0 }; -+ -+ fp = fopen(port_alias_map_file_path,"r"); -+ if (fp == NULL) { -+ log_error("Unable to open %s", port_alias_map_file_path); -+ return -1; -+ } -+ -+ g_interface_name_alias_map_size = 0; -+ -+ // Count the number of interfaces listed in the file -+ while (fgets(line, sizeof(line), fp)) { -+ g_interface_name_alias_map_size++; -+ } -+ -+ // Allocate our map accordingly -+ g_interface_name_alias_map = ((struct interface_name_alias_tuple *) -+ dmalloc((sizeof(struct interface_name_alias_tuple) * g_interface_name_alias_map_size), -+ MDL)); -+ -+ // Reset file position indicator to beginning of file -+ fseek(fp, 0, SEEK_SET); -+ -+ // Every line should contain exactly one name-alias pair -+ while (fgets(line, sizeof(line), fp)) { -+ // Each line should read as "" -+ sscanf(line, "%s %s", g_interface_name_alias_map[i].if_name, g_interface_name_alias_map[i].if_alias); -+ i++; -+ } -+ -+ fclose(fp); -+ -+ log_info("Loaded %d interface name-alias mappings", i); -+ -+ return 0; -+} -+ -+// Locates alias for port named if_name, copies alias into if_alias_out, up to a -+// max of IFNAMSIZ bytes. -+// Returns 0 on success, -1 on failure -+static int -+get_interface_alias_by_name(const char *if_name, char *if_alias_out) { -+ int i = 0; -+ -+ for (i = 0; i < g_interface_name_alias_map_size; i++) { -+ if (strncmp(if_name, g_interface_name_alias_map[i].if_name, IFNAMSIZ) == 0) { -+ strncpy(if_alias_out, g_interface_name_alias_map[i].if_alias, IFNAMSIZ); -+ return 0; -+ } -+ } -+ -+ return -1; -+} -+ -+// Frees global map g_interface_name_alias_map -+// Sets g_interface_name_alias_map_size to 0 -+static void -+free_interface_alias_map(void) { -+ free(g_interface_name_alias_map); -+ g_interface_name_alias_map_size = 0; -+} --- -2.1.4 - diff --git a/src/isc-dhcp/patch/0003-Support-for-obtaining-name-of-physical-interface-tha.patch b/src/isc-dhcp/patch/0003-Support-for-obtaining-name-of-physical-interface-tha.patch new file mode 100644 index 000000000000..fd9ff420d970 --- /dev/null +++ b/src/isc-dhcp/patch/0003-Support-for-obtaining-name-of-physical-interface-tha.patch @@ -0,0 +1,98 @@ +From ab0be27d3862c7287e3b181cc6a70effa054be1c Mon Sep 17 00:00:00 2001 +From: Joe LeVeque +Date: Fri, 26 Apr 2019 01:06:49 +0000 +Subject: [PATCH] Support for obtaining name of physical interface that is a + member of a bridge interface + +--- + relay/dhcrelay.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 65 insertions(+), 2 deletions(-) + +diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c +index 4659660..0f7d658 100644 +--- a/relay/dhcrelay.c ++++ b/relay/dhcrelay.c +@@ -1072,6 +1072,47 @@ find_interface_by_agent_option(struct dhcp_packet *packet, + return (-1); + } + ++static int ++_bridgefdbquery(const char *hwAddr, char *interface, int *vlanid) { ++ ++#define xstr(s) str(s) ++#define str(s) #s ++#define FDB_STRING_LEN 100 ++#define FDB_BUFFER_LEN (FDB_STRING_LEN + 1) ++ ++/* ++ * Format for sscanf() to read the 1st, 3th, and 5th ++ * space-delimited fields ++ * ++ * bridge fdb show output ++ * 6c:64:1a:00:06:13 dev swp35 vlan 0 master bridge permanent ++ */ ++#define FDB_LINE_FORMAT "%" xstr(FDB_STRING_LEN) "s %*s " \ ++ "%" xstr(FDB_STRING_LEN) "s %*s %d %*s" ++ ++ char cmdstr[FDB_BUFFER_LEN]; ++ char buf[FDB_BUFFER_LEN]; ++ char macAddr[FDB_BUFFER_LEN]; ++ ++ if ((interface == NULL) || (vlanid == NULL)) { ++ return 0; ++ } ++ sprintf(cmdstr, "bridge fdb show | grep -m 1 %s", hwAddr); ++ FILE *cmd = popen(cmdstr, "r"); ++ ++ if (cmd != NULL) { ++ while (fgets(buf, sizeof(buf), cmd)) { ++ sscanf(buf, FDB_LINE_FORMAT, macAddr, interface, vlanid); ++ //log_debug("bridgefdbquery: macAddr: %s interface: %s vlanid: %d", ++ // macAddr, interface, *vlanid); ++ } ++ pclose(cmd); ++ return 0; ++ } ++ ++ return -1; ++} ++ + /* + * Format the message that will be used by circuit_id and remote_id + */ +@@ -1104,8 +1145,30 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack + break; + + case 'p': /* Name of interface that we received the request from */ +- strncpy(ifname, ip->name, IFNAMSIZ); +- str = ifname; ++ /* ++ * Query FDB to identify the exact physical interface only when source MAC address ++ * is present and '20: DHCP relay agent IP address' (giaddr) is not present ++ */ ++ if (packet->htype && !packet->giaddr.s_addr) { ++ int ret = 0, vlanid = 0; ++ ++ ret = _bridgefdbquery(print_hw_addr(packet->htype, packet->hlen, packet->chaddr), ++ ifname, ++ &vlanid); ++ ++ // If we failed to find a physical interface using the source mac, default ++ // to the interface name we received it on. ++ if (ret < 0) { ++ //log_debug("MAC Address: %s (interface:%s vlan:%d) not found in bridge fdb show", ++ // print_hw_addr (packet->htype, packet->hlen, packet->chaddr), ++ // ip->name, ++ // vlanid); ++ ++ strncpy(ifname, ip->name, IFNAMSIZ); ++ } ++ ++ str = ifname; ++ } + break; + + case 'P': /* Physical address of interface that we received the request from */ +-- +2.17.1 + diff --git a/src/isc-dhcp/patch/0004-Support-for-loading-port-alias-map-file-to-replace-p.patch b/src/isc-dhcp/patch/0004-Support-for-loading-port-alias-map-file-to-replace-p.patch new file mode 100644 index 000000000000..b564a0822a0c --- /dev/null +++ b/src/isc-dhcp/patch/0004-Support-for-loading-port-alias-map-file-to-replace-p.patch @@ -0,0 +1,189 @@ +From 9d255bbd7d7aadac5b57cba2ab4e29cecdf0180f Mon Sep 17 00:00:00 2001 +From: Joe LeVeque +Date: Fri, 26 Apr 2019 01:26:45 +0000 +Subject: [PATCH] Support for loading port alias map file to replace port name + with alias in circuit id + +--- + relay/dhcrelay.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 104 insertions(+), 1 deletion(-) + +diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c +index 0f7d658..797dac6 100644 +--- a/relay/dhcrelay.c ++++ b/relay/dhcrelay.c +@@ -126,6 +126,14 @@ static void setup_streams(void); + char *dhcrelay_sub_id = NULL; + #endif + ++struct interface_name_alias_tuple { ++ char if_name[IFNAMSIZ]; ++ char if_alias[IFNAMSIZ]; ++}; ++ ++static struct interface_name_alias_tuple *g_interface_name_alias_map = NULL; ++static size_t g_interface_name_alias_map_size = 0; ++ + static void do_relay4(struct interface_info *, struct dhcp_packet *, + unsigned int, unsigned int, struct iaddr, + struct hardware *); +@@ -140,6 +148,10 @@ static int strip_relay_agent_options(struct interface_info *, + + static void request_v4_interface(const char* name, int flags); + ++static int load_interface_alias_map(const char *port_alias_map_file_path); ++static int get_interface_alias_by_name(const char *if_name, char *if_alias_out); ++static void free_interface_alias_map(void); ++ + static const char copyright[] = + "Copyright 2004-2016 Internet Systems Consortium."; + static const char arr[] = "All rights reserved."; +@@ -155,7 +167,7 @@ char *progname; + "\n" \ + " %%%% A single %%\n" \ + " %%h Hostname of device\n" \ +-" %%p Name of interface that generated the request\n" \ ++" %%p Alias of interface that generated the request\n" \ + " %%P Hardware address of interface that generated the request\n" \ + " %%C Client hardware address\n" \ + " %%I DHCP relay agent IP Address\n" \ +@@ -166,6 +178,7 @@ char *progname; + " [-A ] [-c ] [-p ]\n" \ + " [-pf ] [--no-pid]\n"\ + " [-m append|replace|forward|discard]\n" \ ++" [--name-alias-map-file ]\n" \ + " [-i interface0 [ ... -i interfaceN]\n" \ + " [-iu interface0 [ ... -iu interfaceN]\n" \ + " [-id interface0 [ ... -id interfaceN]\n" \ +@@ -173,6 +186,7 @@ char *progname; + " server0 [ ... serverN]\n\n" \ + " %s -6 [-d] [-q] [-I] [-c ] [-p ]\n" \ + " [-pf ] [--no-pid]\n" \ ++" [--name-alias-map-file ]\n" \ + " [-s ]\n" \ + " -l lower0 [ ... -l lowerN]\n" \ + " -u upper0 [ ... -u upperN]\n" \ +@@ -503,6 +517,11 @@ main(int argc, char **argv) { + no_dhcrelay_pid = ISC_TRUE; + } else if (!strcmp(argv[i], "--no-pid")) { + no_pid_file = ISC_TRUE; ++ } else if (!strcmp(argv[i], "--name-alias-map-file")) { ++ if (++i == argc) ++ usage(use_noarg, argv[i-1]); ++ if (load_interface_alias_map(argv[i]) != 0) ++ log_fatal("Failed to load interface name-alias map."); + } else if (!strcmp(argv[i], "--version")) { + log_info("isc-dhcrelay-%s", PACKAGE_VERSION); + exit(0); +@@ -726,6 +745,7 @@ main(int argc, char **argv) { + dispatch(); + + /* In fact dispatch() never returns. */ ++ free_interface_alias_map(); + return (0); + } + +@@ -1151,6 +1171,7 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack + */ + if (packet->htype && !packet->giaddr.s_addr) { + int ret = 0, vlanid = 0; ++ char ifalias[IFNAMSIZ] = { 0 }; + + ret = _bridgefdbquery(print_hw_addr(packet->htype, packet->hlen, packet->chaddr), + ifname, +@@ -1167,6 +1188,18 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack + strncpy(ifname, ip->name, IFNAMSIZ); + } + ++ // Attempt to translate SONiC interface name to vendor alias ++ ret = get_interface_alias_by_name(ifname, ifalias); ++ if (ret < 0) { ++ //log_debug("Failed to retrieve alias for interface name '%s'. Defaulting to interface name.", ifname); ++ } ++ else { ++ //log_debug("Mapped interface name '%s' to alias '%s'. Adding as option 82 interface alias for MAC Address %s", ++ // ifname, ifalias, print_hw_addr (packet->htype, packet->hlen, packet->chaddr)); ++ ++ strncpy(ifname, ifalias, IFNAMSIZ); ++ } ++ + str = ifname; + } + break; +@@ -2096,3 +2129,73 @@ void request_v4_interface(const char* name, int flags) { + interface_snorf(tmp, (INTERFACE_REQUESTED | flags)); + interface_dereference(&tmp, MDL); + } ++ ++#define MAX_PORT_CONFIG_LINE_LEN 1024 ++ ++// Allocates and loads global map g_interface_name_alias_map ++// Also sets global g_interface_name_alias_map_size ++static int ++load_interface_alias_map(const char *port_alias_map_file_path) { ++ int i = 0; ++ FILE *fp = NULL; ++ char line[MAX_PORT_CONFIG_LINE_LEN] = { 0 }; ++ ++ fp = fopen(port_alias_map_file_path,"r"); ++ if (fp == NULL) { ++ log_error("Unable to open %s", port_alias_map_file_path); ++ return -1; ++ } ++ ++ g_interface_name_alias_map_size = 0; ++ ++ // Count the number of interfaces listed in the file ++ while (fgets(line, sizeof(line), fp)) { ++ g_interface_name_alias_map_size++; ++ } ++ ++ // Allocate our map accordingly ++ g_interface_name_alias_map = ((struct interface_name_alias_tuple *) ++ dmalloc((sizeof(struct interface_name_alias_tuple) * g_interface_name_alias_map_size), ++ MDL)); ++ ++ // Reset file position indicator to beginning of file ++ fseek(fp, 0, SEEK_SET); ++ ++ // Every line should contain exactly one name-alias pair ++ while (fgets(line, sizeof(line), fp)) { ++ // Each line should read as "" ++ sscanf(line, "%s %s", g_interface_name_alias_map[i].if_name, g_interface_name_alias_map[i].if_alias); ++ i++; ++ } ++ ++ fclose(fp); ++ ++ log_info("Loaded %d interface name-alias mappings", i); ++ ++ return 0; ++} ++ ++// Locates alias for port named if_name, copies alias into if_alias_out, up to a ++// max of IFNAMSIZ bytes. ++// Returns 0 on success, -1 on failure ++static int ++get_interface_alias_by_name(const char *if_name, char *if_alias_out) { ++ int i = 0; ++ ++ for (i = 0; i < g_interface_name_alias_map_size; i++) { ++ if (strncmp(if_name, g_interface_name_alias_map[i].if_name, IFNAMSIZ) == 0) { ++ strncpy(if_alias_out, g_interface_name_alias_map[i].if_alias, IFNAMSIZ); ++ return 0; ++ } ++ } ++ ++ return -1; ++} ++ ++// Frees global map g_interface_name_alias_map ++// Sets g_interface_name_alias_map_size to 0 ++static void ++free_interface_alias_map(void) { ++ free(g_interface_name_alias_map); ++ g_interface_name_alias_map_size = 0; ++} +-- +2.17.1 + diff --git a/src/isc-dhcp/patch/0005-CVE-2017-3144.patch b/src/isc-dhcp/patch/0005-CVE-2017-3144.patch deleted file mode 100644 index fe066e177a8c..000000000000 --- a/src/isc-dhcp/patch/0005-CVE-2017-3144.patch +++ /dev/null @@ -1,47 +0,0 @@ -From: Thomas Markwalder -Date: Thu, 7 Dec 2017 11:23:36 -0500 -Subject: [master] Plugs a socket descriptor leak in OMAPI -Origin: https://source.isc.org/cgi-bin/gitweb.cgi?p=dhcp.git;a=commit;h=1a6b62fe17a42b00fa234d06b6dfde3d03451894 -Bug: https://bugs.isc.org/Public/Bug/Display.html?id=46767 -Bug-Debian: https://bugs.debian.org/887413 -Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2017-3144 - - Merges in rt46767. ---- - -diff --git a/omapip/buffer.c b/omapip/buffer.c -index 6e0621b5..a21f0a80 100644 ---- a/omapip/buffer.c -+++ b/omapip/buffer.c -@@ -565,6 +565,15 @@ isc_result_t omapi_connection_writer (omapi_object_t *h) - omapi_buffer_dereference (&buffer, MDL); - } - } -+ -+ /* If we had data left to write when we're told to disconnect, -+ * we need recall disconnect, now that we're done writing. -+ * See rt46767. */ -+ if (c->out_bytes == 0 && c->state == omapi_connection_disconnecting) { -+ omapi_disconnect (h, 1); -+ return ISC_R_SHUTTINGDOWN; -+ } -+ - return ISC_R_SUCCESS; - } - -diff --git a/omapip/message.c b/omapip/message.c -index ee15d821..37abbd25 100644 ---- a/omapip/message.c -+++ b/omapip/message.c -@@ -339,7 +339,7 @@ isc_result_t omapi_message_unregister (omapi_object_t *mo) - } - - #ifdef DEBUG_PROTOCOL --static const char *omapi_message_op_name(int op) { -+const char *omapi_message_op_name(int op) { - switch (op) { - case OMAPI_OP_OPEN: return "OMAPI_OP_OPEN"; - case OMAPI_OP_REFRESH: return "OMAPI_OP_REFRESH"; --- -2.16.2 - diff --git a/src/isc-dhcp/patch/0006-CVE-2018-5733.patch b/src/isc-dhcp/patch/0006-CVE-2018-5733.patch deleted file mode 100644 index f2ddff0503eb..000000000000 --- a/src/isc-dhcp/patch/0006-CVE-2018-5733.patch +++ /dev/null @@ -1,145 +0,0 @@ -From: Zhenggen Xu -Date: Thu, 11 Oct 2018 17:18:32 -0700 -Subject: [PATCH] Subject: [master] Corrected refcnt loss in option parsing - Origin: - https://source.isc.org/cgi-bin/gitweb.cgi?p=dhcp.git;a=commit;h=197b26f25309f947b97a83b8fdfc414b767798f8 - Bug: https://bugs.isc.org/Public/Bug/Display.html?id=47140 Bug-Debian: - https://bugs.debian.org/891785 Bug-Debian-Security: - https://security-tracker.debian.org/tracker/CVE-2018-5733 - - Merges in 47140. ---- - common/options.c | 2 + - common/tests/Makefile.am | 11 ++++- - common/tests/option_unittest.c | 79 ++++++++++++++++++++++++++++++++++ - 3 files changed, 91 insertions(+), 1 deletion(-) - create mode 100644 common/tests/option_unittest.c - -diff --git a/common/options.c b/common/options.c -index 74f1fb5..db28b5c 100644 ---- a/common/options.c -+++ b/common/options.c -@@ -177,6 +177,8 @@ int parse_option_buffer (options, buffer, length, universe) - - /* If the length is outrageous, the options are bad. */ - if (offset + len > length) { -+ /* Avoid reference count overflow */ -+ option_dereference(&option, MDL); - reason = "option length exceeds option buffer length"; - bogus: - log_error("parse_option_buffer: malformed option " -diff --git a/common/tests/Makefile.am b/common/tests/Makefile.am -index 32e055c..19521c9 100644 ---- a/common/tests/Makefile.am -+++ b/common/tests/Makefile.am -@@ -8,7 +8,8 @@ ATF_TESTS = - - if HAVE_ATF - --ATF_TESTS += alloc_unittest dns_unittest misc_unittest ns_name_unittest -+ATF_TESTS += alloc_unittest dns_unittest misc_unittest ns_name_unittest \ -+ option_unittest - - alloc_unittest_SOURCES = test_alloc.c $(top_srcdir)/tests/t_api_dhcp.c - alloc_unittest_LDADD = $(ATF_LDFLAGS) -@@ -34,6 +35,14 @@ ns_name_unittest_LDADD += ../libdhcp.a \ - ../../omapip/libomapi.a ../../bind/lib/libirs.a \ - ../../bind/lib/libdns.a ../../bind/lib/libisccfg.a ../../bind/lib/libisc.a - -+option_unittest_SOURCES = option_unittest.c $(top_srcdir)/tests/t_api_dhcp.c -+option_unittest_LDADD = $(ATF_LDFLAGS) -+option_unittest_LDADD += ../libdhcp.@A@ ../../omapip/libomapi.@A@ \ -+ @BINDLIBIRSDIR@/libirs.@A@ \ -+ @BINDLIBDNSDIR@/libdns.@A@ \ -+ @BINDLIBISCCFGDIR@/libisccfg.@A@ \ -+ @BINDLIBISCDIR@/libisc.@A@ -+ - check: $(ATF_TESTS) - sh ${top_srcdir}/tests/unittest.sh - -diff --git a/common/tests/option_unittest.c b/common/tests/option_unittest.c -new file mode 100644 -index 0000000..36236b8 ---- /dev/null -+++ b/common/tests/option_unittest.c -@@ -0,0 +1,79 @@ -+/* -+ * Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC") -+ * -+ * This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH -+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, -+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -+ * PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include -+#include -+#include "dhcpd.h" -+ -+ATF_TC(option_refcnt); -+ -+ATF_TC_HEAD(option_refcnt, tc) -+{ -+ atf_tc_set_md_var(tc, "descr", -+ "Verify option reference count does not overflow."); -+} -+ -+/* This test does a simple check to see if option reference count is -+ * decremented even an error path exiting parse_option_buffer() -+ */ -+ATF_TC_BODY(option_refcnt, tc) -+{ -+ struct option_state *options; -+ struct option *option; -+ unsigned code; -+ int refcnt; -+ unsigned char buffer[3] = { 15, 255, 0 }; -+ -+ initialize_common_option_spaces(); -+ -+ options = NULL; -+ if (!option_state_allocate(&options, MDL)) { -+ atf_tc_fail("can't allocate option state"); -+ } -+ -+ option = NULL; -+ code = 15; /* domain-name */ -+ if (!option_code_hash_lookup(&option, dhcp_universe.code_hash, -+ &code, 0, MDL)) { -+ atf_tc_fail("can't find option 15"); -+ } -+ if (option == NULL) { -+ atf_tc_fail("option is NULL"); -+ } -+ refcnt = option->refcnt; -+ -+ buffer[0] = 15; -+ buffer[1] = 255; /* invalid */ -+ buffer[2] = 0; -+ -+ if (parse_option_buffer(options, buffer, 3, &dhcp_universe)) { -+ atf_tc_fail("parse_option_buffer is expected to fail"); -+ } -+ -+ if (refcnt != option->refcnt) { -+ atf_tc_fail("refcnt changed from %d to %d", refcnt, option->refcnt); -+ } -+} -+ -+/* This macro defines main() method that will call specified -+ test cases. tp and simple_test_case names can be whatever you want -+ as long as it is a valid variable identifier. */ -+ATF_TP_ADD_TCS(tp) -+{ -+ ATF_TP_ADD_TC(tp, option_refcnt); -+ -+ return (atf_no_error()); -+} - diff --git a/src/isc-dhcp/patch/0007-CVE-2018-5732.patch b/src/isc-dhcp/patch/0007-CVE-2018-5732.patch deleted file mode 100644 index d6c10e2e6532..000000000000 --- a/src/isc-dhcp/patch/0007-CVE-2018-5732.patch +++ /dev/null @@ -1,144 +0,0 @@ -From: Thomas Markwalder -Date: Sat, 10 Feb 2018 12:15:27 -0500 -Subject: [master] Correct buffer overrun in pretty_print_option -Origin: https://source.isc.org/cgi-bin/gitweb.cgi?p=dhcp.git;a=commit;h=c5931725b48b121d232df4ba9e45bc41e0ba114d -Bug: https://bugs.isc.org/Public/Bug/Display.html?id=47139 -Bug-Debian: https://bugs.debian.org/891786 -Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2018-5732 - - Merges in rt47139. ---- - -diff --git a/common/options.c b/common/options.c -index 6f23bc15..fc0e0889 100644 ---- a/common/options.c -+++ b/common/options.c -@@ -1776,7 +1776,8 @@ format_min_length(format, oc) - - - /* Format the specified option so that a human can easily read it. */ -- -+/* Maximum pretty printed size */ -+#define MAX_OUTPUT_SIZE 32*1024 - const char *pretty_print_option (option, data, len, emit_commas, emit_quotes) - struct option *option; - const unsigned char *data; -@@ -1784,8 +1785,9 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes) - int emit_commas; - int emit_quotes; - { -- static char optbuf [32768]; /* XXX */ -- static char *endbuf = &optbuf[sizeof(optbuf)]; -+ /* We add 128 byte pad so we don't have to add checks everywhere. */ -+ static char optbuf [MAX_OUTPUT_SIZE + 128]; /* XXX */ -+ static char *endbuf = optbuf + MAX_OUTPUT_SIZE; - int hunksize = 0; - int opthunk = 0; - int hunkinc = 0; -@@ -2211,7 +2213,14 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes) - log_error ("Unexpected format code %c", - fmtbuf [j]); - } -+ - op += strlen (op); -+ if (op >= endbuf) { -+ log_error ("Option data exceeds" -+ " maximum size %d", MAX_OUTPUT_SIZE); -+ return (""); -+ } -+ - if (dp == data + len) - break; - if (j + 1 < numelem && comma != ':') -diff --git a/common/tests/option_unittest.c b/common/tests/option_unittest.c -index 36236b84..cd52cfb4 100644 ---- a/common/tests/option_unittest.c -+++ b/common/tests/option_unittest.c -@@ -43,7 +43,7 @@ ATF_TC_BODY(option_refcnt, tc) - if (!option_state_allocate(&options, MDL)) { - atf_tc_fail("can't allocate option state"); - } -- -+ - option = NULL; - code = 15; /* domain-name */ - if (!option_code_hash_lookup(&option, dhcp_universe.code_hash, -@@ -68,12 +68,75 @@ ATF_TC_BODY(option_refcnt, tc) - } - } - -+ATF_TC(pretty_print_option); -+ -+ATF_TC_HEAD(pretty_print_option, tc) -+{ -+ atf_tc_set_md_var(tc, "descr", -+ "Verify pretty_print_option does not overrun its buffer."); -+} -+ -+ -+/* -+ * This test verifies that pretty_print_option() will not overrun its -+ * internal, static buffer when given large 'x/X' format options. -+ * -+ */ -+ATF_TC_BODY(pretty_print_option, tc) -+{ -+ struct option *option; -+ unsigned code; -+ unsigned char bad_data[32*1024]; -+ unsigned char good_data[] = { 1,2,3,4,5,6 }; -+ int emit_commas = 1; -+ int emit_quotes = 1; -+ const char *output_buf; -+ -+ /* Initialize whole thing to non-printable chars */ -+ memset(bad_data, 0x1f, sizeof(bad_data)); -+ -+ initialize_common_option_spaces(); -+ -+ /* We'll use dhcp_client_identitifer because it happens to be format X */ -+ code = 61; -+ option = NULL; -+ if (!option_code_hash_lookup(&option, dhcp_universe.code_hash, -+ &code, 0, MDL)) { -+ atf_tc_fail("can't find option %d", code); -+ } -+ -+ if (option == NULL) { -+ atf_tc_fail("option is NULL"); -+ } -+ -+ /* First we will try a good value we know should fit. */ -+ output_buf = pretty_print_option (option, good_data, sizeof(good_data), -+ emit_commas, emit_quotes); -+ -+ /* Make sure we get what we expect */ -+ if (!output_buf || strcmp(output_buf, "1:2:3:4:5:6")) { -+ atf_tc_fail("pretty_print_option did not return \"\""); -+ } -+ -+ -+ /* Now we'll try a data value that's too large */ -+ output_buf = pretty_print_option (option, bad_data, sizeof(bad_data), -+ emit_commas, emit_quotes); -+ -+ /* Make sure we safely get an error */ -+ if (!output_buf || strcmp(output_buf, "")) { -+ atf_tc_fail("pretty_print_option did not return \"\""); -+ } -+} -+ -+ - /* This macro defines main() method that will call specified - test cases. tp and simple_test_case names can be whatever you want - as long as it is a valid variable identifier. */ - ATF_TP_ADD_TCS(tp) - { - ATF_TP_ADD_TC(tp, option_refcnt); -+ ATF_TP_ADD_TC(tp, pretty_print_option); - - return (atf_no_error()); - } --- -2.16.2 - diff --git a/src/isc-dhcp/patch/series b/src/isc-dhcp/patch/series index 3e1c15338687..9f7164f5c4a9 100644 --- a/src/isc-dhcp/patch/series +++ b/src/isc-dhcp/patch/series @@ -1,9 +1,6 @@ -# This series applies on GIT commit ee3dffdda38a8cfc6ad2005d8d64a165d2a709ba -0001-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch -0002-Support-for-obtaining-name-of-physical-interface-tha.patch -0003-Support-for-loading-port-alias-map-file-to-replace-p.patch -0004-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch -0005-CVE-2017-3144.patch -0006-CVE-2018-5733.patch -0007-CVE-2018-5732.patch +# This series applies on GIT commit d613b77d0473054fb0071b00d01eaa1623e50a07 +0001-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch +0002-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch +0003-Support-for-obtaining-name-of-physical-interface-tha.patch +0004-Support-for-loading-port-alias-map-file-to-replace-p.patch From 6b3a26f0ccd99f9a254dc71b8ed2df1c22a6b296 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Mon, 29 Apr 2019 17:21:24 -0700 Subject: [PATCH 07/88] Remove unused packages in docker images and host (#2807) * Remove unneeded packages in docker images and host * Remove libpython3.6 from snmp docker image --- dockers/docker-base/Dockerfile.j2 | 4 ++++ dockers/docker-config-engine-stretch/Dockerfile.j2 | 2 +- dockers/docker-config-engine/Dockerfile.j2 | 2 +- dockers/docker-lldp-sv2/Dockerfile.j2 | 2 +- dockers/docker-platform-monitor/Dockerfile.j2 | 2 +- dockers/docker-snmp-sv2/Dockerfile.j2 | 4 +++- dockers/docker-sonic-mgmt/Dockerfile.j2 | 4 ++-- files/build_templates/sonic_debian_extension.j2 | 2 +- rules/python3.mk | 4 ++-- 9 files changed, 16 insertions(+), 10 deletions(-) diff --git a/dockers/docker-base/Dockerfile.j2 b/dockers/docker-base/Dockerfile.j2 index c622e6a59843..481af6e821ed 100644 --- a/dockers/docker-base/Dockerfile.j2 +++ b/dockers/docker-base/Dockerfile.j2 @@ -73,6 +73,10 @@ RUN apt-get -y install {{ dbg_pkg }} RUN ln /usr/bin/vim.tiny /usr/bin/vim {%- endif %} +# Remove python3.4 +# Note: if later python3 is required by more docker images, consider install homebrew python3 here instead of in SNMP image only +RUN apt-get purge -y libpython3.4-minimal + # Clean up apt # Remove /var/lib/apt/lists/*, could be obsoleted for derived images RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y diff --git a/dockers/docker-config-engine-stretch/Dockerfile.j2 b/dockers/docker-config-engine-stretch/Dockerfile.j2 index 3fe8f4d3e110..7c85e583ca6b 100644 --- a/dockers/docker-config-engine-stretch/Dockerfile.j2 +++ b/dockers/docker-config-engine-stretch/Dockerfile.j2 @@ -43,5 +43,5 @@ python-wheels/{{ whl }}{{' '}} {%- endif -%} ## Clean up -RUN apt-get remove -y python-pip python-dev; apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y +RUN apt-get purge -y python-pip python-dev; apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs /python-wheels diff --git a/dockers/docker-config-engine/Dockerfile.j2 b/dockers/docker-config-engine/Dockerfile.j2 index bc82e1ca2883..ba72cce31d47 100644 --- a/dockers/docker-config-engine/Dockerfile.j2 +++ b/dockers/docker-config-engine/Dockerfile.j2 @@ -43,5 +43,5 @@ python-wheels/{{ whl }}{{' '}} {%- endif -%} ## Clean up -RUN apt-get remove -y python-pip python-dev; apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y +RUN apt-get purge -y python-pip python-dev; apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs /python-wheels diff --git a/dockers/docker-lldp-sv2/Dockerfile.j2 b/dockers/docker-lldp-sv2/Dockerfile.j2 index 5f44d32cdd76..4b1c95f9e523 100644 --- a/dockers/docker-lldp-sv2/Dockerfile.j2 +++ b/dockers/docker-lldp-sv2/Dockerfile.j2 @@ -35,7 +35,7 @@ RUN pip install /python-wheels/{{ whl }} {% endif %} # Clean up -RUN apt-get remove -y python-pip +RUN apt-get purge -y python-pip RUN apt-get clean -y RUN apt-get autoclean -y RUN apt-get autoremove -y diff --git a/dockers/docker-platform-monitor/Dockerfile.j2 b/dockers/docker-platform-monitor/Dockerfile.j2 index 61f5b2a95827..bc91e28f4a23 100755 --- a/dockers/docker-platform-monitor/Dockerfile.j2 +++ b/dockers/docker-platform-monitor/Dockerfile.j2 @@ -46,7 +46,7 @@ RUN pip install /python-wheels/{{ whl }} {% endif %} # Clean up -RUN apt-get remove -y python-pip +RUN apt-get purge -y python-pip RUN apt-get clean -y RUN apt-get autoclean -y RUN apt-get autoremove -y diff --git a/dockers/docker-snmp-sv2/Dockerfile.j2 b/dockers/docker-snmp-sv2/Dockerfile.j2 index c931e2ed9d66..9b1b18c306e5 100644 --- a/dockers/docker-snmp-sv2/Dockerfile.j2 +++ b/dockers/docker-snmp-sv2/Dockerfile.j2 @@ -60,7 +60,9 @@ RUN pip install /python-wheels/{{ whl }} RUN python3.6 -m sonic_ax_impl install # Clean up -RUN apt-get -y purge libpython3.6-dev curl gcc make libdpkg-perl +RUN apt-get -y purge libpython3.6-dev libpython3.6 curl gcc make libdpkg-perl +# Note: these packages should be removed with autoremove but actually not, so explicitly purged +RUN apt-get -y purge libldap-2.4-2 libsasl2-2 libsasl2-modules libsasl2-modules-db RUN apt-get clean -y && apt-get autoclean -y && apt-get autoremove -y --purge RUN find / | grep -E "__pycache__" | xargs rm -rf RUN rm -rf /debs /python-wheels ~/.cache diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index eab2985fd1dc..fea0fe0c2125 100644 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -29,9 +29,9 @@ RUN apt-get install -y default-jre RUN apt-get install -y rsyslog psmisc # Remove cffi 1.5.2, will install 1.10.0 by pip later -RUN apt-get remove -y python-cffi python-cffi-backend +RUN apt-get purge -y python-cffi python-cffi-backend # Remove pycparser 2.14, will install >=2.17 by pip later -RUN apt-get remove -y python-ply python-pycparser +RUN apt-get purge -y python-ply python-pycparser RUN easy_install pip diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 55da564abfc4..145dc9796573 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -311,7 +311,7 @@ sudo LANG=C cp $SCRIPTS_DIR/syncd.sh $FILESYSTEM_ROOT/usr/local/bin/syncd.sh sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT/etc/systemd/system/ sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable snmp.timer -sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get remove -y python-dev +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 sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get autoremove -y diff --git a/rules/python3.mk b/rules/python3.mk index 2473c9aeb498..247a80b0cbea 100644 --- a/rules/python3.mk +++ b/rules/python3.mk @@ -26,8 +26,8 @@ $(PY3_MIN)_RDEPENDS += $(LIBPY3_MIN) PY3 = $(PYTHON_PNAME)_$(PYTHON_VER)_amd64.deb $(eval $(call add_derived_package,$(LIBPY3_MIN),$(PY3))) -$(PY3)_DEPENDS += $(PY3_MIN) $(LIBPY3) -$(PY3)_RDEPENDS += $(PY3_MIN) $(LIBPY3) $(LIBPY3_MIN) +$(PY3)_DEPENDS += $(PY3_MIN) $(LIBPY3_STD) +$(PY3)_RDEPENDS += $(PY3_MIN) $(LIBPY3_STD) LIBPY3_DEV = lib$(PYTHON_PNAME)-dev_$(PYTHON_VER)_amd64.deb $(eval $(call add_derived_package,$(LIBPY3_MIN),$(LIBPY3_DEV))) From b9ddae84436c534393e3e588f3e4138a3b964d76 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Mon, 29 Apr 2019 17:56:42 -0700 Subject: [PATCH 08/88] [teamd] do not process lacpdu before the port ifinfo is set (#2815) Port libteam patch which fixes the race condition we observed during warm reboot. Remove early patches: 0006, 0008, 0009. Signed-off-by: Ying Xie --- ...ith_port-race-condition-with-newlink.patch | 45 ---------- ...hange-handler-for-TEAM_IFINFO_CHANGE.patch | 34 ------- ...nt-private-change-handler-reentrance.patch | 90 ------------------- ...cess-lacpdu-before-the-port-ifinfo-i.patch | 46 ++++++++++ src/libteam/series | 6 +- 5 files changed, 48 insertions(+), 173 deletions(-) delete mode 100644 src/libteam/0006-Fix-ifinfo_link_with_port-race-condition-with-newlink.patch delete mode 100644 src/libteam/0008-teamd-register-change-handler-for-TEAM_IFINFO_CHANGE.patch delete mode 100644 src/libteam/0009-teamd-prevent-private-change-handler-reentrance.patch create mode 100644 src/libteam/0012-teamd-do-not-process-lacpdu-before-the-port-ifinfo-i.patch diff --git a/src/libteam/0006-Fix-ifinfo_link_with_port-race-condition-with-newlink.patch b/src/libteam/0006-Fix-ifinfo_link_with_port-race-condition-with-newlink.patch deleted file mode 100644 index bab3a9108325..000000000000 --- a/src/libteam/0006-Fix-ifinfo_link_with_port-race-condition-with-newlink.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 9a27e9b85afbbf6235e61c2426481e49a2139219 Mon Sep 17 00:00:00 2001 -From: Shu0T1an ChenG -Date: Tue, 15 Jan 2019 12:23:02 -0800 -Subject: [PATCH] Fix ifinfo_link_with_port race condition with newlink - -The race condition could happen like this: -When an interface is enslaved into the port channel immediately after -it is created, the order of creating the ifinfo and linking the ifinfo to -the port is not guaranteed. - -The team handler will listen to both netlink message to track new links -get created to allocate the ifinfo and add the ifinfo into its linked list, -and the team port change message to link the new port with ifinfo found -in its linkedin list. However, when the ifinfo is not yet created, the error -message "Failed to link port with ifinfo" is thrown with member port failed -to be added into the team handler's port list. - -This fix adds a condition to check if ifinfo_link_with_port is linking ifinfo -to a port or to the team interface itself. If it is a port, ifinfo_find_create -function is used to fix the race condition. - -Signed-off-by: Shu0T1an ChenG ---- - libteam/ifinfo.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/libteam/ifinfo.c b/libteam/ifinfo.c -index 44de4ca..444e0cd 100644 ---- a/libteam/ifinfo.c -+++ b/libteam/ifinfo.c -@@ -429,7 +429,10 @@ int ifinfo_link_with_port(struct team_handle *th, uint32_t ifindex, - { - struct team_ifinfo *ifinfo; - -- ifinfo = ifinfo_find(th, ifindex); -+ if (port) -+ ifinfo = ifinfo_find_create(th, ifindex); -+ else -+ ifinfo = ifinfo_find(th, ifindex); - if (!ifinfo) - return -ENOENT; - if (ifinfo->linked) --- -2.1.4 - diff --git a/src/libteam/0008-teamd-register-change-handler-for-TEAM_IFINFO_CHANGE.patch b/src/libteam/0008-teamd-register-change-handler-for-TEAM_IFINFO_CHANGE.patch deleted file mode 100644 index a603f91f62fe..000000000000 --- a/src/libteam/0008-teamd-register-change-handler-for-TEAM_IFINFO_CHANGE.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 7dff9798c2c92eb75b0120737efb81febcdb80c1 Mon Sep 17 00:00:00 2001 -From: Ying Xie -Date: Sun, 24 Mar 2019 21:49:59 +0000 -Subject: [PATCH] [teamd] register change handler for TEAM_IFINFO_CHANGE as - well - -There has been a race condition in the libnal/teamd interation, causing -TEAM_PORT_CHANGE to report a port with empty device name. Which then -causes the teamd unable to add the lag members into the lag. - -Registering to the TEAM_IFINFO_CHANGE would give teamd another chance to -add member again. - -Signed-off-by: Ying Xie ---- - teamd/teamd_per_port.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/teamd/teamd_per_port.c b/teamd/teamd_per_port.c -index 09d1dc7..137da57 100644 ---- a/teamd/teamd_per_port.c -+++ b/teamd/teamd_per_port.c -@@ -274,7 +274,7 @@ static int port_priv_change_handler_func(struct team_handle *th, void *priv, - - static const struct team_change_handler port_priv_change_handler = { - .func = port_priv_change_handler_func, -- .type_mask = TEAM_PORT_CHANGE, -+ .type_mask = TEAM_PORT_CHANGE | TEAM_IFINFO_CHANGE, - }; - - int teamd_per_port_init(struct teamd_context *ctx) --- -2.7.4 - diff --git a/src/libteam/0009-teamd-prevent-private-change-handler-reentrance.patch b/src/libteam/0009-teamd-prevent-private-change-handler-reentrance.patch deleted file mode 100644 index dad10a4c1ae9..000000000000 --- a/src/libteam/0009-teamd-prevent-private-change-handler-reentrance.patch +++ /dev/null @@ -1,90 +0,0 @@ -From fb00b070482dc587eec7b4e34acec094be1af00d Mon Sep 17 00:00:00 2001 -From: Ying Xie -Date: Fri, 29 Mar 2019 20:54:49 +0000 -Subject: [PATCH 10/11] [teamd] prevent private change handler reentrance - -While handling PORT_CHANGE, teamd could casue an INTERFACE_CHANGE in the -same context. Which will interfere with the PORT_CHANGE handling and -causing it to fail. - -Lock is not needed because the re-entrance happened in the same thread -context. - -This issue was noticed while dynamically adding a port into a lag. - -Signed-off-by: Ying Xie ---- - teamd/teamd.c | 2 ++ - teamd/teamd.h | 2 ++ - teamd/teamd_per_port.c | 13 +++++++++++-- - 3 files changed, 15 insertions(+), 2 deletions(-) - -diff --git a/teamd/teamd.c b/teamd/teamd.c -index e28aa7d..140b98b 100644 ---- a/teamd/teamd.c -+++ b/teamd/teamd.c -@@ -1255,6 +1255,8 @@ static int teamd_init(struct teamd_context *ctx) - { - int err; - -+ ctx->reentrant = false; -+ - ctx->th = team_alloc(); - if (!ctx->th) { - teamd_log_err("Team alloc failed."); -diff --git a/teamd/teamd.h b/teamd/teamd.h -index 622c365..7cd3266 100644 ---- a/teamd/teamd.h -+++ b/teamd/teamd.h -@@ -160,6 +160,8 @@ struct teamd_context { - int pipe_r; - int pipe_w; - } workq; -+ -+ bool reentrant; - }; - - struct teamd_port { -diff --git a/teamd/teamd_per_port.c b/teamd/teamd_per_port.c -index 137da57..8b4a457 100644 ---- a/teamd/teamd_per_port.c -+++ b/teamd/teamd_per_port.c -@@ -250,6 +250,10 @@ static int port_priv_change_handler_func(struct team_handle *th, void *priv, - struct port_obj *port_obj; - int err; - -+ if (ctx->reentrant) { -+ return 0; -+ } -+ ctx->reentrant = true; - team_for_each_port(port, th) { - uint32_t ifindex = team_get_port_ifindex(port); - -@@ -258,17 +262,22 @@ static int port_priv_change_handler_func(struct team_handle *th, void *priv, - if (team_is_port_removed(port)) - continue; - err = port_obj_create(ctx, &port_obj, ifindex, port); -- if (err) -+ if (err) { -+ ctx->reentrant = false; - return err; -+ } - } - if (team_is_port_changed(port)) { - err = teamd_event_port_changed(ctx, _port(port_obj)); -- if (err) -+ if (err) { -+ ctx->reentrant = false; - return err; -+ } - } - if (team_is_port_removed(port)) - port_obj_remove(ctx, port_obj); - } -+ ctx->reentrant = false; - return 0; - } - --- -2.7.4 - diff --git a/src/libteam/0012-teamd-do-not-process-lacpdu-before-the-port-ifinfo-i.patch b/src/libteam/0012-teamd-do-not-process-lacpdu-before-the-port-ifinfo-i.patch new file mode 100644 index 000000000000..db29825fb9da --- /dev/null +++ b/src/libteam/0012-teamd-do-not-process-lacpdu-before-the-port-ifinfo-i.patch @@ -0,0 +1,46 @@ +From 28ccb37eb388e7e3d214a9b05011f8421f0d65ac Mon Sep 17 00:00:00 2001 +From: Ying Xie +Date: Fri, 26 Apr 2019 23:30:38 +0000 +Subject: [PATCH] teamd: do not process lacpdu before the port ifinfo is set + +Now the port ifinfo will be set in obj_input_newlink when a RTM_NEWLINK +event is received. + +But when a port is being added, if a lacpdu gets received on this port +before the RTM_NEWLINK event, lacpdu_recv will process the packet with +incorrect port ifinfo. + +In Patrick's case, as ifinfo->master_ifindex was 0, it would skip this +port in teamd_for_each_tdport, which caused lacp_port->agg_lead not to +be updated in lacp_switch_agg_lead. Later the lacp_port actor would go +to a unexpected state. + +This patch is to avoid it by checking teamd_port_present in lacpdu_recv +so that it would not process lacpdu before the port ifinfo is set. + +Reported-by: Patrick Talbert +Tested-by: Patrick Talbert +Signed-off-by: Xin Long +Reviewed-by: Marcelo Ricardo Leitner +Signed-off-by: Jiri Pirko +--- + teamd/teamd_runner_lacp.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/teamd/teamd_runner_lacp.c b/teamd/teamd_runner_lacp.c +index 78f05dd..c8ae541 100644 +--- a/teamd/teamd_runner_lacp.c ++++ b/teamd/teamd_runner_lacp.c +@@ -1132,6 +1132,9 @@ static int lacpdu_process(struct lacp_port *lacp_port, struct lacpdu* lacpdu) + { + int err; + ++ if (!teamd_port_present(lacp_port->ctx, lacp_port->tdport)) ++ return 0; ++ + if (!lacpdu_check(lacpdu)) { + teamd_log_warn("malformed LACP PDU came."); + return 0; +-- +2.7.4 + diff --git a/src/libteam/series b/src/libteam/series index 3cdcbd993ca9..e9ef676ce52a 100644 --- a/src/libteam/series +++ b/src/libteam/series @@ -3,9 +3,7 @@ 0003-teamd-lacp-runner-will-send-lacp-update-right-after-.patch 0004-libteam-Add-lacp-fallback-support-for-single-member-.patch 0005-libteam-Add-warm_reboot-mode.patch -0006-Fix-ifinfo_link_with_port-race-condition-with-newlink.patch 0007-Skip-setting-the-same-hwaddr-to-lag-port-to-avoid-di.patch -0008-teamd-register-change-handler-for-TEAM_IFINFO_CHANGE.patch -0009-teamd-prevent-private-change-handler-reentrance.patch 0010-teamd-lacp-update-port-state-according-to-partners-sy.patch -0011-libteam-resynchronize-ifinfo-after-lost-RTNLGRP_LINK-.patch \ No newline at end of file +0011-libteam-resynchronize-ifinfo-after-lost-RTNLGRP_LINK-.patch +0012-teamd-do-not-process-lacpdu-before-the-port-ifinfo-i.patch From 259d51a94fbc07708edcb0ce93c0e302e91f348d Mon Sep 17 00:00:00 2001 From: simonJi2018 <37395146+simonJi2018@users.noreply.github.com> Date: Tue, 30 Apr 2019 09:25:40 +0800 Subject: [PATCH 09/88] [nephos]: upgrade compile sdk.deb from online to dpkg and fix compile error (#2800) * upgrade compile sdk.deb from online to dpkg and upgrade docker syncd and orchagent to stretch * Delete docker-orchagent-nephos.mk Delete docker-orchagent-nephos.mk * Update docker-syncd-nephos.mk * Update Dockerfile.j2 --- platform/nephos/docker-syncd-nephos.mk | 30 +- .../nephos/docker-syncd-nephos/Dockerfile.j2 | 20 +- platform/nephos/libsaithrift-dev.mk | 4 +- platform/nephos/nephos-modules.mk | 10 + platform/nephos/nephos-modules/README.md | 2 + .../nephos/nephos-modules/debian/changelog | 5 + platform/nephos/nephos-modules/debian/compat | 1 + platform/nephos/nephos-modules/debian/control | 12 + platform/nephos/nephos-modules/debian/rules | 34 + .../nephos/nephos-modules/modules/Makefile | 50 + platform/nephos/nephos-modules/modules/README | 32 + .../nephos/nephos-modules/modules/config.mk | 30 + .../init.d/nps-modules-4.9.0-8-2-amd64 | 54 + .../nps-modules-4.9.0-8-2-amd64.service | 13 + .../modules/src/hal_tau_pkt_knl.c | 6147 +++++++++++++++++ .../nephos-modules/modules/src/inc/aml.h | 366 + .../nephos-modules/modules/src/inc/hal_dev.h | 48 + .../modules/src/inc/hal_tau_pkt_knl.h | 2302 ++++++ .../modules/src/inc/netif_osal.h | 379 + .../modules/src/inc/netif_perf.h | 81 + .../nephos-modules/modules/src/inc/nps_cfg.h | 317 + .../modules/src/inc/nps_error.h | 77 + .../modules/src/inc/nps_types.h | 308 + .../nephos-modules/modules/src/inc/osal_mdc.h | 241 + .../modules/src/inc/osal_types.h | 319 + .../nephos/nephos-modules/modules/src/make.mk | 37 + .../nephos-modules/modules/src/netif_osal.c | 753 ++ .../nephos-modules/modules/src/netif_perf.c | 656 ++ .../nephos-modules/modules/src/osal_isymbol.c | 38 + .../nephos-modules/modules/src/osal_mdc.c | 2359 +++++++ platform/nephos/one-image.mk | 2 +- platform/nephos/rules.mk | 8 +- platform/nephos/sai.mk | 6 +- platform/nephos/sdk.mk | 7 - 34 files changed, 14705 insertions(+), 43 deletions(-) create mode 100644 platform/nephos/nephos-modules.mk create mode 100644 platform/nephos/nephos-modules/README.md create mode 100644 platform/nephos/nephos-modules/debian/changelog create mode 100644 platform/nephos/nephos-modules/debian/compat create mode 100644 platform/nephos/nephos-modules/debian/control create mode 100755 platform/nephos/nephos-modules/debian/rules create mode 100755 platform/nephos/nephos-modules/modules/Makefile create mode 100644 platform/nephos/nephos-modules/modules/README create mode 100755 platform/nephos/nephos-modules/modules/config.mk create mode 100755 platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9.0-8-2-amd64 create mode 100644 platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-8-2-amd64.service create mode 100755 platform/nephos/nephos-modules/modules/src/hal_tau_pkt_knl.c create mode 100755 platform/nephos/nephos-modules/modules/src/inc/aml.h create mode 100755 platform/nephos/nephos-modules/modules/src/inc/hal_dev.h create mode 100755 platform/nephos/nephos-modules/modules/src/inc/hal_tau_pkt_knl.h create mode 100755 platform/nephos/nephos-modules/modules/src/inc/netif_osal.h create mode 100755 platform/nephos/nephos-modules/modules/src/inc/netif_perf.h create mode 100755 platform/nephos/nephos-modules/modules/src/inc/nps_cfg.h create mode 100755 platform/nephos/nephos-modules/modules/src/inc/nps_error.h create mode 100755 platform/nephos/nephos-modules/modules/src/inc/nps_types.h create mode 100755 platform/nephos/nephos-modules/modules/src/inc/osal_mdc.h create mode 100755 platform/nephos/nephos-modules/modules/src/inc/osal_types.h create mode 100755 platform/nephos/nephos-modules/modules/src/make.mk create mode 100755 platform/nephos/nephos-modules/modules/src/netif_osal.c create mode 100755 platform/nephos/nephos-modules/modules/src/netif_perf.c create mode 100755 platform/nephos/nephos-modules/modules/src/osal_isymbol.c create mode 100755 platform/nephos/nephos-modules/modules/src/osal_mdc.c delete mode 100644 platform/nephos/sdk.mk diff --git a/platform/nephos/docker-syncd-nephos.mk b/platform/nephos/docker-syncd-nephos.mk index 86174506121e..4acd688de865 100644 --- a/platform/nephos/docker-syncd-nephos.mk +++ b/platform/nephos/docker-syncd-nephos.mk @@ -1,25 +1,13 @@ # docker image for nephos syncd -DOCKER_SYNCD_NEPHOS = docker-syncd-nephos.gz -$(DOCKER_SYNCD_NEPHOS)_PATH = $(PLATFORM_PATH)/docker-syncd-nephos -$(DOCKER_SYNCD_NEPHOS)_DEPENDS += $(SYNCD) -ifeq ($(INSTALL_DEBUG_TOOLS), y) -$(DOCKER_SYNCD_NEPHOS)_DEPENDS += $(SYNCD_DBG) \ - $(LIBSWSSCOMMON_DBG) \ - $(LIBSAIMETADATA_DBG) \ - $(LIBSAIREDIS_DBG) -endif -$(DOCKER_SYNCD_NEPHOS)_FILES += $(DSSERVE) $(NPX_DIAG) -$(DOCKER_SYNCD_NEPHOS)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) -SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_NEPHOS) -ifneq ($(ENABLE_SYNCD_RPC),y) -SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_NEPHOS) -endif +DOCKER_SYNCD_PLATFORM_CODE = nephos +include $(PLATFORM_PATH)/../template/docker-syncd-base.mk -$(DOCKER_SYNCD_NEPHOS)_CONTAINER_NAME = syncd -$(DOCKER_SYNCD_NEPHOS)_RUN_OPT += --net=host --privileged -t -$(DOCKER_SYNCD_NEPHOS)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf -$(DOCKER_SYNCD_NEPHOS)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd -$(DOCKER_SYNCD_NEPHOS)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_SYNCD_BASE)_DEPENDS += $(SYNCD) $(PYTHON_SDK_API) -$(DOCKER_SYNCD_NEPHOS)_BASE_IMAGE_FILES += npx_diag:/usr/bin/npx_diag +$(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ + $(LIBSWSSCOMMON_DBG) \ + $(LIBSAIMETADATA_DBG) \ + $(LIBSAIREDIS_DBG) + +$(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/platform/nephos/docker-syncd-nephos/Dockerfile.j2 b/platform/nephos/docker-syncd-nephos/Dockerfile.j2 index 1553e2786cf8..bb15fdd63bbb 100755 --- a/platform/nephos/docker-syncd-nephos/Dockerfile.j2 +++ b/platform/nephos/docker-syncd-nephos/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine +FROM docker-config-engine-stretch ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf @@ -14,17 +14,25 @@ debs/{{ deb }}{{' '}} {%- endfor -%} debs/ +COPY \ +{% for deb in docker_syncd_nephos_pydebs.split(' ') -%} +python-debs/{{ deb }}{{' '}} +{%- endfor -%} +debs/ + +RUN apt-get install -y libxml2 + RUN dpkg -i \ {% for deb in docker_syncd_nephos_debs.split(' ') -%} debs/{{ deb }}{{' '}} {%- endfor %} -## TODO: add kmod into Depends -RUN apt-get install -f kmod - -COPY ["files/dsserve", "files/npx_diag", "start.sh", "/usr/bin/"] -RUN chmod +x /usr/bin/dsserve /usr/bin/npx_diag +##RUN dpkg -i \ +##{% for deb in docker_syncd_nephos_pydebs.split(' ') -%} +##debs/{{ deb }}{{' '}} +##{%- endfor %} +COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] ## Clean up diff --git a/platform/nephos/libsaithrift-dev.mk b/platform/nephos/libsaithrift-dev.mk index 6ffb4bf51205..e21ebc5c6828 100644 --- a/platform/nephos/libsaithrift-dev.mk +++ b/platform/nephos/libsaithrift-dev.mk @@ -4,7 +4,7 @@ SAI_VER = 0.9.4 LIBSAITHRIFT_DEV = libsaithrift-dev_$(SAI_VER)_amd64.deb $(LIBSAITHRIFT_DEV)_SRC_PATH = $(SRC_PATH)/sonic-sairedis/SAI -$(LIBSAITHRIFT_DEV)_DEPENDS += $(LIBTHRIFT) $(LIBTHRIFT_DEV) $(THRIFT_COMPILER) $(NEPHOS_SAI) $(NEPHOS_SAI_DEV) +$(LIBSAITHRIFT_DEV)_DEPENDS += $(LIBTHRIFT) $(LIBTHRIFT_DEV) $(PYTHON_THRIFT) $(THRIFT_COMPILER) $(NEPHOS_SAI) $(NEPHOS_SAI_DEV) $(LIBSAITHRIFT_DEV)_RDEPENDS += $(LIBTHRIFT) $(NEPHOS_SAI) SONIC_DPKG_DEBS += $(LIBSAITHRIFT_DEV) @@ -12,7 +12,7 @@ PYTHON_SAITHRIFT = python-saithrift_$(SAI_VER)_amd64.deb $(eval $(call add_extra_package,$(LIBSAITHRIFT_DEV),$(PYTHON_SAITHRIFT))) SAISERVER = saiserver_$(SAI_VER)_amd64.deb -$(SAISERVER)_RDEPENDS += $(LIBTHRIFT) $(BRCM_SAI) +$(SAISERVER)_RDEPENDS += $(LIBTHRIFT) $(NEPHOS_SAI) $(eval $(call add_extra_package,$(LIBSAITHRIFT_DEV),$(SAISERVER))) SAISERVER_DBG = saiserver-dbg_$(SAI_VER)_amd64.deb diff --git a/platform/nephos/nephos-modules.mk b/platform/nephos/nephos-modules.mk new file mode 100644 index 000000000000..565e975e0a08 --- /dev/null +++ b/platform/nephos/nephos-modules.mk @@ -0,0 +1,10 @@ +# Nephos Platform modules + +VERSION = 1.0.0 + +NEPHOS_MODULE = nephos-modules_$(VERSION)_amd64.deb +$(NEPHOS_MODULE)_SRC_PATH = $(PLATFORM_PATH)/nephos-modules +$(NEPHOS_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +SONIC_DPKG_DEBS += $(NEPHOS_MODULE) + +SONIC_STRETCH_DEBS += $(NEPHOS_MODULE) diff --git a/platform/nephos/nephos-modules/README.md b/platform/nephos/nephos-modules/README.md new file mode 100644 index 000000000000..6bb4cf6bf658 --- /dev/null +++ b/platform/nephos/nephos-modules/README.md @@ -0,0 +1,2 @@ +# Nephos-modules +Device drivers for support of Nephos platform for the SONiC project diff --git a/platform/nephos/nephos-modules/debian/changelog b/platform/nephos/nephos-modules/debian/changelog new file mode 100644 index 000000000000..3de2bd045efd --- /dev/null +++ b/platform/nephos/nephos-modules/debian/changelog @@ -0,0 +1,5 @@ +nephos-modules (1.0.0) unstable; urgency=low + + * Initial release + + -- Support Fri, 15 Mar 2019 15:54:00 +0800 diff --git a/platform/nephos/nephos-modules/debian/compat b/platform/nephos/nephos-modules/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/nephos/nephos-modules/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/nephos/nephos-modules/debian/control b/platform/nephos/nephos-modules/debian/control new file mode 100644 index 000000000000..49cc83b9c524 --- /dev/null +++ b/platform/nephos/nephos-modules/debian/control @@ -0,0 +1,12 @@ +Source: nephos-modules +Section: main +Priority: extra +Maintainer: support +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: nephos-modules +Architecture: amd64 +Depends: linux-image-4.9.0-8-2-amd64 +Description: kernel modules for nephos asic + diff --git a/platform/nephos/nephos-modules/debian/rules b/platform/nephos/nephos-modules/debian/rules new file mode 100755 index 000000000000..acf96c80e104 --- /dev/null +++ b/platform/nephos/nephos-modules/debian/rules @@ -0,0 +1,34 @@ +#!/usr/bin/make -f + +export INSTALL_MOD_DIR:=extra + +PACKAGE_NAME := nephos-modules +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +SERVICE_DIR := service +INITD_DIR := init.d +MODULE_SRC := $(shell pwd)/modules +CURRENT_DIR := $(cd "$(dirname "$0")"; pwd) + +%: + dh $@ + +override_dh_auto_build: + make -C $(MODULE_SRC) + +override_dh_auto_install: + dh_installdirs -p$(PACKAGE_NAME) $(KERNEL_SRC)/extra + cp $(MODULE_SRC)/build/module/*.ko debian/$(PACKAGE_NAME)/$(KERNEL_SRC)/extra + dh_installdirs -p$(PACKAGE_NAME) /lib/systemd/system + cp $(MODULE_SRC)/service/*.service debian/$(PACKAGE_NAME)/lib/systemd/system/ + dh_installdirs -p$(PACKAGE_NAME) /etc/init.d + cp $(MODULE_SRC)/init.d/* debian/$(PACKAGE_NAME)/etc/init.d/ + +override_dh_usrlocal: + +override_dh_pysupport: + +override_dh_clean: + dh_clean + test -d $(MODULE_SRC)/build || rm -rf $(MODULE_SRC)/build + diff --git a/platform/nephos/nephos-modules/modules/Makefile b/platform/nephos/nephos-modules/modules/Makefile new file mode 100755 index 000000000000..8351996b04ea --- /dev/null +++ b/platform/nephos/nephos-modules/modules/Makefile @@ -0,0 +1,50 @@ +################################################################################ +# Copyright (C) 2019 Nephos, Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 of the GNU General Public +# License as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 along with this program. +################################################################################ +NPS_MODULES_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) +SRC_PATH := $(NPS_MODULES_DIR)/src +INC_PATH := $(SRC_PATH)/inc +################################################################################ +include $(NPS_MODULES_DIR)/config.mk +################################################################################ +MODULE_OUTPUT_DIR := $(BUILD_OUTPUT_DIR)/module +################################################################################ +all: compile install +################################################################################ +EXTRA_CFLAGS += -I$(INC_PATH) +EXTRA_CFLAGS += -DNPS_EN_NETIF +EXTRA_CFLAGS += -DNPS_EN_TAURUS +EXTRA_CFLAGS += -DNPS_LINUX_USER_MODE +EXTRA_CFLAGS += -DNPS_EN_LITTLE_ENDIAN +ifeq ($(shell uname -m),x86_64) +EXTRA_CFLAGS += -DNPS_EN_HOST_64_BIT_LITTLE_ENDIAN +else +EXTRA_CFLAGS += -DNPS_EN_HOST_32_BIT_LITTLE_ENDIAN +endif +################################################################################ +include $(SRC_PATH)/make.mk +################################################################################ +compile:: + +install:: + $(TEST_PATH) $(MODULE_OUTPUT_DIR) || $(MKDIR) $(MODULE_OUTPUT_DIR) + $(MV) $(BUILD_OUTPUT_DIR)/$(DEV_MODULE_NAME).ko $(MODULE_OUTPUT_DIR)/$(DEV_MODULE_NAME).ko + $(MV) $(BUILD_OUTPUT_DIR)/$(NETIF_MODULE_NAME).ko $(MODULE_OUTPUT_DIR)/$(NETIF_MODULE_NAME).ko + +clean:: + $(RM) $(BUILD_OUTPUT_DIR) + +.PHONY: all compile install clean +.NOTPARALLEL: all compile install clean diff --git a/platform/nephos/nephos-modules/modules/README b/platform/nephos/nephos-modules/modules/README new file mode 100644 index 000000000000..b2e6fb147936 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/README @@ -0,0 +1,32 @@ +################################################################################ +# Copyright (C) 2019 Nephos, Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 of the GNU General Public +# License as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 along with this program. +################################################################################ +Step 1~4 show how to build and execute NPS kernel modules. + +1. Modify nps-modules/config.mk to specify the output directory to BUILD_OUTPUT_DIR. + The default output path is nps-modules/build. + +2. Compile: + cd nps-modules/ && make + +3. The output kernel modules will be found in $(BUILD_OUTPUT_DIR)/modules/ + - nps_dev.ko + - nps_netif.ko + +4. Load modules: + (1) insmod nps_dev.ko + (2) insmod nps_netif.ko + + Note that the module inserting sequence cannot be changed. diff --git a/platform/nephos/nephos-modules/modules/config.mk b/platform/nephos/nephos-modules/modules/config.mk new file mode 100755 index 000000000000..b7a106ea0a4b --- /dev/null +++ b/platform/nephos/nephos-modules/modules/config.mk @@ -0,0 +1,30 @@ +################################################################################ +# Copyright (C) 2019 Nephos, Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 of the GNU General Public +# License as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 along with this program. +################################################################################ +BUILD_OUTPUT_DIR := $(NPS_MODULES_DIR)/build +################################################################################ +#OS_PATH := /lib/modules/$(shell uname -r)/build +OS_PATH := /lib/modules/$(KVERSION)/build + +################################################################################ +MAKE := make +RM := rm -rf +MKDIR := mkdir -p +CP := cp +MV := mv +TEST_PATH := test -d +################################################################################ +export BUILD_OUTPUT_DIR +export OS_PATH diff --git a/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9.0-8-2-amd64 b/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9.0-8-2-amd64 new file mode 100755 index 000000000000..22755dbaf778 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9.0-8-2-amd64 @@ -0,0 +1,54 @@ +#!/bin/bash +# This script load/unload nps kernel modules + +### BEGIN INIT INFO +# Provides: load-nps-modules +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Load nps kernel modules +### END INIT INFO + +case "$1" in +start) + echo -n "Load nps kernel modules... " + + RMEM_SIZE=`cat /proc/sys/net/core/rmem_max` + if [ $RMEM_SIZE -lt 8388608 ]; then + echo "8388608" > /proc/sys/net/core/rmem_max + fi + WMEM_SIZE=`cat /proc/sys/net/core/wmem_max` + if [ $WMEM_SIZE -lt 25165824 ]; then + echo "25165824" > /proc/sys/net/core/wmem_max + fi + + modprobe nps_dev + modprobe nps_netif + + echo "done." + ;; + +stop) + echo -n "Unload nps kernel modules... " + + rmmod nps_netif + rmmod nps_dev + + echo "done." + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/nps-modules-4.9.0-8-2-amd64.init {start|stop}" + exit 1 + ;; +esac + +exit 0 + diff --git a/platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-8-2-amd64.service b/platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-8-2-amd64.service new file mode 100644 index 000000000000..f044c95311e4 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-8-2-amd64.service @@ -0,0 +1,13 @@ +[Unit] +Description=Nephos kernel modules init +After=local-fs.target +Before=syncd.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/nps-modules-4.9.0-8-2-amd64 start +ExecStop=-/etc/init.d/nps-modules-4.9.0-8-2-amd64 stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/nephos/nephos-modules/modules/src/hal_tau_pkt_knl.c b/platform/nephos/nephos-modules/modules/src/hal_tau_pkt_knl.c new file mode 100755 index 000000000000..b386da63e247 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/hal_tau_pkt_knl.c @@ -0,0 +1,6147 @@ +/* Copyright (C) 2019 Nephos, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program. + */ + +/* FILE NAME: hal_tau_pkt_knl.c + * PURPOSE: + * To provide Linux kernel for PDMA TX/RX control. + * + * NOTES: + * + */ + +/***************************************************************************** + * INCLUDE FILE DECLARATIONS + ***************************************************************************** + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* netif */ +#include +#include +#include + +/* nps_sdk */ +#include + +/***************************************************************************** + * CHIP DEPENDENT VARIABLES + ***************************************************************************** + */ +/* Interrupt */ +#define HAL_TAU_PKT_ERR_REG(__unit__) (_hal_tau_pkt_intr_vec[0].intr_reg) +#define HAL_TAU_PKT_TCH_REG(__unit__, __channel__) (_hal_tau_pkt_intr_vec[1 + (__channel__)].intr_reg) +#define HAL_TAU_PKT_RCH_REG(__unit__, __channel__) (_hal_tau_pkt_intr_vec[5 + (__channel__)].intr_reg) + +#define HAL_TAU_PKT_ERR_EVENT(__unit__) (&_hal_tau_pkt_intr_vec[0].intr_event) +#define HAL_TAU_PKT_TCH_EVENT(__unit__, __channel__) (&_hal_tau_pkt_intr_vec[1 + (__channel__)].intr_event) +#define HAL_TAU_PKT_RCH_EVENT(__unit__, __channel__) (&_hal_tau_pkt_intr_vec[5 + (__channel__)].intr_event) + +#define HAL_TAU_PKT_ERR_CNT(__unit__) (_hal_tau_pkt_intr_vec[0].intr_cnt) +#define HAL_TAU_PKT_TCH_CNT(__unit__, __channel__) (_hal_tau_pkt_intr_vec[1 + (__channel__)].intr_cnt) +#define HAL_TAU_PKT_RCH_CNT(__unit__, __channel__) (_hal_tau_pkt_intr_vec[5 + (__channel__)].intr_cnt) + + +/* This flag value will be specified when user inserts kernel module. */ +#define HAL_TAU_PKT_DBG_ERR (0x1 << 0) +#define HAL_TAU_PKT_DBG_TX (0x1 << 1) +#define HAL_TAU_PKT_DBG_RX (0x1 << 2) +#define HAL_TAU_PKT_DBG_INTF (0x1 << 3) +#define HAL_TAU_PKT_DBG_PROFILE (0x1 << 4) +#define HAL_TAU_PKT_DBG_COMMON (0x1 << 5) + +/* Will be set when inserting kernel module */ +static UI32_T dbg_flag = 0; + +#define HAL_TAU_PKT_DBG(__flag__, ...) do \ +{ \ + if (0 != ((__flag__) & (dbg_flag))) \ + { \ + osal_printf(__VA_ARGS__); \ + } \ +}while (0) + +typedef struct +{ + UI32_T intr_reg; + NPS_SEMAPHORE_ID_T intr_event; + UI32_T intr_cnt; + +} HAL_TAU_PKT_INTR_VEC_T; + +typedef struct HAL_TAU_PKT_PROFILE_NODE_S +{ + HAL_TAU_PKT_NETIF_PROFILE_T *ptr_profile; + struct HAL_TAU_PKT_PROFILE_NODE_S *ptr_next_node; + +} HAL_TAU_PKT_PROFILE_NODE_T; + +typedef struct +{ + HAL_TAU_PKT_NETIF_INTF_T meta; + struct net_device *ptr_net_dev; + HAL_TAU_PKT_PROFILE_NODE_T *ptr_profile_list; /* the profiles binding to this interface */ + +} HAL_TAU_PKT_NETIF_PORT_DB_T; + + +static HAL_TAU_PKT_INTR_VEC_T _hal_tau_pkt_intr_vec[] = +{ + { /* 0: PDMA_ERR */ 1 << 0, 0x0, 0 }, + { /* 1: TX_CH0 */ 1 << 28, 0x0, 0 }, + { /* 2: TX_CH1 */ 1 << 29, 0x0, 0 }, + { /* 3: TX_CH2 */ 1 << 30, 0x0, 0 }, + { /* 4: TX_CH3 */ 1 << 31, 0x0, 0 }, + { /* 5: RX_CH0 */ 1 << 12, 0x0, 0 }, + { /* 6: RX_CH1 */ 1 << 13, 0x0, 0 }, + { /* 7: RX_CH2 */ 1 << 14, 0x0, 0 }, + { /* 8: RX_CH3 */ 1 << 15, 0x0, 0 }, +}; + +/***************************************************************************** + * NAMING CONSTANT DECLARATIONS + ***************************************************************************** + */ +/* Sleep Time Definitions */ +#define HAL_TAU_PKT_TX_DEQUE_SLEEP() osal_sleepThread(1000) /* us */ +#define HAL_TAU_PKT_RX_DEQUE_SLEEP() osal_sleepThread(1000) /* us */ +#define HAL_TAU_PKT_TX_ENQUE_RETRY_SLEEP() osal_sleepThread(1000) /* us */ +#define HAL_TAU_PKT_RX_ENQUE_RETRY_SLEEP() osal_sleepThread(1000) /* us */ +#define HAL_TAU_PKT_ALLOC_MEM_RETRY_SLEEP() osal_sleepThread(1000) /* us */ + +/* Network Device Definitions */ +#define HAL_TAU_PKT_TX_TIMEOUT (6*HZ) +#define HAL_TAU_PKT_MAX_ETH_FRAME_SIZE (HAL_TAU_PKT_RX_MAX_LEN) +#define HAL_TAU_PKT_MAX_PORT_NUM (HAL_TAU_PORT_NUM + 1) /* CPU port */ + +#define HAL_TAU_PKT_NET_PROFILE_NUM_MAX (256) + +static HAL_TAU_PKT_NETIF_PROFILE_T *_ptr_hal_tau_pkt_profile_entry[HAL_TAU_PKT_NET_PROFILE_NUM_MAX] = {0}; +static HAL_TAU_PKT_NETIF_PORT_DB_T _hal_tau_pkt_port_db[HAL_TAU_PKT_MAX_PORT_NUM]; + +/***************************************************************************** + * MACRO VLAUE DECLARATIONS + ***************************************************************************** + */ + +/***************************************************************************** + * MACRO FUNCTION DECLARATIONS + ***************************************************************************** + */ +/*---------------------------------------------------------------------------*/ +#define HAL_TAU_PKT_GET_DRV_CB_PTR(unit) (&_hal_tau_pkt_drv_cb[unit]) +/*---------------------------------------------------------------------------*/ +#define HAL_TAU_PKT_GET_TX_CB_PTR(unit) (&_hal_tau_pkt_tx_cb[unit]) +#define HAL_TAU_PKT_GET_TX_PDMA_PTR(unit, channel) (&_hal_tau_pkt_tx_cb[unit].pdma[channel]) +#define HAL_TAU_PKT_GET_TX_GPD_PTR(unit, channel, gpd) (&_hal_tau_pkt_tx_cb[unit].pdma[channel].ptr_gpd_align_start_addr[gpd]) +/*---------------------------------------------------------------------------*/ +#define HAL_TAU_PKT_GET_RX_CB_PTR(unit) (&_hal_tau_pkt_rx_cb[unit]) +#define HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, channel) (&_hal_tau_pkt_rx_cb[unit].pdma[channel]) +#define HAL_TAU_PKT_GET_RX_GPD_PTR(unit, channel, gpd) (&_hal_tau_pkt_rx_cb[unit].pdma[channel].ptr_gpd_align_start_addr[gpd]) +/*---------------------------------------------------------------------------*/ +#define HAL_TAU_PKT_GET_PORT_DB(port) (&_hal_tau_pkt_port_db[port]) +#define HAL_TAU_PKT_GET_PORT_PROFILE_LIST(port) (_hal_tau_pkt_port_db[port].ptr_profile_list) +#define HAL_TAU_PKT_GET_PORT_NETDEV(port) _hal_tau_pkt_port_db[port].ptr_net_dev + +/***************************************************************************** + * DATA TYPE DECLARATIONS + ***************************************************************************** + */ +/* ----------------------------------------------------------------------------------- General structure */ +typedef struct +{ + UI32_T unit; + UI32_T channel; + +} HAL_TAU_PKT_ISR_COOKIE_T; + +typedef struct +{ + NPS_HUGE_T que_id; + NPS_SEMAPHORE_ID_T sema; + UI32_T len; /* Software CPU queue maximum length. */ + UI32_T weight; /* The weight for thread de-queue algorithm. */ + +} HAL_TAU_PKT_SW_QUEUE_T; + +typedef struct +{ + /* handleErrorTask */ + NPS_THREAD_ID_T err_task_id; + + /* INTR dispatcher */ + NPS_ISRLOCK_ID_T intr_lock; + UI32_T intr_bitmap; + +#define HAL_TAU_PKT_INIT_DRV (1 << 0) +#define HAL_TAU_PKT_INIT_TASK (1 << 1) +#define HAL_TAU_PKT_INIT_INTR (1 << 2) +#define HAL_TAU_PKT_INIT_RX_START (1 << 3) + /* a bitmap to record the init status */ + UI32_T init_flag; + +} HAL_TAU_PKT_DRV_CB_T; + +/* ----------------------------------------------------------------------------------- TX structure */ +typedef struct +{ + /* NPS_SEMAPHORE_ID_T sema; */ + + /* since the Tx GPD ring may be accessed by multiple process including + * ndo_start_xmit (SW IRQ), it must be protected with an ISRLOCK + * instead of the original semaphore + */ + NPS_ISRLOCK_ID_T ring_lock; + + UI32_T used_idx; /* SW send index = LAMP simulate the Tx HW index */ + UI32_T free_idx; /* SW free index */ + UI32_T used_gpd_num; + UI32_T free_gpd_num; + UI32_T gpd_num; + + HAL_TAU_PKT_TX_GPD_T *ptr_gpd_start_addr; + HAL_TAU_PKT_TX_GPD_T *ptr_gpd_align_start_addr; + BOOL_T err_flag; + + /* ASYNC */ + HAL_TAU_PKT_TX_SW_GPD_T **pptr_sw_gpd_ring; + HAL_TAU_PKT_TX_SW_GPD_T **pptr_sw_gpd_bulk; /* temporary store packets to be enque */ + + /* SYNC_INTR */ + NPS_SEMAPHORE_ID_T sync_intr_sema; + +} HAL_TAU_PKT_TX_PDMA_T; + +typedef struct +{ + HAL_TAU_PKT_TX_WAIT_T wait_mode; + HAL_TAU_PKT_TX_PDMA_T pdma[HAL_TAU_PKT_TX_CHANNEL_LAST]; + HAL_TAU_PKT_TX_CNT_T cnt; + + /* handleTxDoneTask */ + NPS_THREAD_ID_T isr_task_id[HAL_TAU_PKT_TX_CHANNEL_LAST]; + HAL_TAU_PKT_ISR_COOKIE_T isr_task_cookie[HAL_TAU_PKT_TX_CHANNEL_LAST]; + + /* txTask */ + HAL_TAU_PKT_SW_QUEUE_T sw_queue; + NPS_SEMAPHORE_ID_T sync_sema; + NPS_THREAD_ID_T task_id; + BOOL_T running; /* TRUE when Init txTask + * FALSE when Destroy txTask + */ + +} HAL_TAU_PKT_TX_CB_T; + +/* ----------------------------------------------------------------------------------- RX structure */ +typedef struct +{ + NPS_SEMAPHORE_ID_T sema; + UI32_T cur_idx; /* SW free index */ + UI32_T gpd_num; + + HAL_TAU_PKT_RX_GPD_T *ptr_gpd_start_addr; + HAL_TAU_PKT_RX_GPD_T *ptr_gpd_align_start_addr; + BOOL_T err_flag; + struct sk_buff **pptr_skb_ring; +} HAL_TAU_PKT_RX_PDMA_T; + +typedef struct +{ + /* Rx system configuration */ + UI32_T buf_len; + + HAL_TAU_PKT_RX_SCHED_T sched_mode; + HAL_TAU_PKT_RX_PDMA_T pdma[HAL_TAU_PKT_RX_CHANNEL_LAST]; + HAL_TAU_PKT_RX_CNT_T cnt; + + /* handleRxDoneTask */ + NPS_THREAD_ID_T isr_task_id[HAL_TAU_PKT_RX_CHANNEL_LAST]; + HAL_TAU_PKT_ISR_COOKIE_T isr_task_cookie[HAL_TAU_PKT_RX_CHANNEL_LAST]; + + /* rxTask */ + HAL_TAU_PKT_SW_QUEUE_T sw_queue[HAL_TAU_PKT_RX_QUEUE_NUM]; + UI32_T deque_idx; + NPS_SEMAPHORE_ID_T sync_sema; + NPS_THREAD_ID_T task_id; + NPS_SEMAPHORE_ID_T deinit_sema; /* To sync-up the Rx-stop and thread flush queues */ + BOOL_T running; /* TRUE when rxStart + * FALSE when rxStop + */ + +} HAL_TAU_PKT_RX_CB_T; + +/* ----------------------------------------------------------------------------------- Network Device */ +struct net_device_priv +{ + struct net_device *ptr_net_dev; + struct net_device_stats stats; + UI32_T unit; + UI32_T id; + UI32_T port; + UI16_T vlan; + UI32_T speed; +}; + +typedef enum +{ + HAL_TAU_PKT_DEST_NETDEV = 0, + HAL_TAU_PKT_DEST_SDK, + HAL_TAU_PKT_DEST_DROP, + HAL_TAU_PKT_DEST_LAST +} HAL_TAU_PKT_DEST_T; + +/***************************************************************************** + * GLOBAL VARIABLE DECLARATIONS + ***************************************************************************** + */ + +/***************************************************************************** + * STATIC VARIABLE DECLARATIONS + ***************************************************************************** + */ +/*---------------------------------------------------------------------------*/ +static HAL_TAU_PKT_DRV_CB_T _hal_tau_pkt_drv_cb[NPS_CFG_MAXIMUM_CHIPS_PER_SYSTEM]; +static HAL_TAU_PKT_TX_CB_T _hal_tau_pkt_tx_cb[NPS_CFG_MAXIMUM_CHIPS_PER_SYSTEM]; +static HAL_TAU_PKT_RX_CB_T _hal_tau_pkt_rx_cb[NPS_CFG_MAXIMUM_CHIPS_PER_SYSTEM]; +/*---------------------------------------------------------------------------*/ + +/***************************************************************************** + * LOCAL SUBPROGRAM DECLARATIONS + ***************************************************************************** + */ +/* ----------------------------------------------------------------------------------- Interrupt */ +static NPS_ERROR_NO_T +_hal_tau_pkt_enableIntr( + const UI32_T unit, + const UI32_T intr_bitmap) +{ + HAL_TAU_PKT_DRV_CB_T *ptr_cb = HAL_TAU_PKT_GET_DRV_CB_PTR(unit); + NPS_IRQ_FLAGS_T irq_flag = 0; + UI32_T intr_en = 0; + + osal_takeIsrLock(&ptr_cb->intr_lock, &irq_flag); + osal_mdc_readPciReg(unit, HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_CP_COMMON_INT_EN_HI), &intr_en, sizeof(intr_en)); + intr_en |= intr_bitmap; + osal_mdc_writePciReg(unit, HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_CP_COMMON_INT_EN_HI), &intr_en, sizeof(intr_en)); + osal_giveIsrLock(&ptr_cb->intr_lock, &irq_flag); + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_disableIntr( + const UI32_T unit, + const UI32_T intr_bitmap) +{ + HAL_TAU_PKT_DRV_CB_T *ptr_cb = HAL_TAU_PKT_GET_DRV_CB_PTR(unit); + NPS_IRQ_FLAGS_T irq_flag = 0; + UI32_T intr_en = 0; + + osal_takeIsrLock(&ptr_cb->intr_lock, &irq_flag); + osal_mdc_readPciReg(unit, HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_CP_COMMON_INT_EN_HI), &intr_en, sizeof(intr_en)); + intr_en &= ~intr_bitmap; + osal_mdc_writePciReg(unit, HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_CP_COMMON_INT_EN_HI), &intr_en, sizeof(intr_en)); + osal_giveIsrLock(&ptr_cb->intr_lock, &irq_flag); + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_maskIntr( + const UI32_T unit, + const UI32_T intr_bitmap) +{ + HAL_TAU_PKT_DRV_CB_T *ptr_cb = HAL_TAU_PKT_GET_DRV_CB_PTR(unit); + NPS_IRQ_FLAGS_T irq_flag = 0; + + osal_takeIsrLock(&ptr_cb->intr_lock, &irq_flag); + osal_mdc_writePciReg(unit, HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_CP_COMMON_INT_MASK_CLR_HI), &intr_bitmap, sizeof(intr_bitmap)); + osal_giveIsrLock(&ptr_cb->intr_lock, &irq_flag); + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_unmaskIntr( + const UI32_T unit, + const UI32_T intr_bitmap) +{ + HAL_TAU_PKT_DRV_CB_T *ptr_cb = HAL_TAU_PKT_GET_DRV_CB_PTR(unit); + NPS_IRQ_FLAGS_T irq_flag = 0; + + osal_takeIsrLock(&ptr_cb->intr_lock, &irq_flag); + osal_mdc_writePciReg(unit, HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_CP_COMMON_INT_MASK_SET_HI), &intr_bitmap, sizeof(intr_bitmap)); + osal_giveIsrLock(&ptr_cb->intr_lock, &irq_flag); + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_dispatcher( + void *ptr_cookie) +{ + UI32_T unit = (UI32_T)((NPS_HUGE_T)ptr_cookie); + HAL_TAU_PKT_DRV_CB_T *ptr_cb = HAL_TAU_PKT_GET_DRV_CB_PTR(unit); + NPS_IRQ_FLAGS_T irq_flag = 0; + + UI32_T idx = 0, vec = sizeof(_hal_tau_pkt_intr_vec) / sizeof(HAL_TAU_PKT_INTR_VEC_T); + UI32_T intr_mask = ptr_cb->intr_bitmap; + UI32_T intr_unmask = 0; + UI32_T intr_status = 0; + + /* MASK, READ and CLEAR PKT IRQs */ + osal_takeIsrLock(&ptr_cb->intr_lock, &irq_flag); + osal_mdc_writePciReg(unit, HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_CP_COMMON_INT_MASK_CLR_HI), &intr_mask, sizeof(UI32_T)); + osal_mdc_readPciReg (unit, HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_CP_COMMON_INT_STAT_HI), &intr_status, sizeof(UI32_T)); + intr_status = intr_status & intr_mask; + osal_mdc_writePciReg(unit, HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_CP_COMMON_INT_CLR_HI), &intr_status, sizeof(UI32_T)); + osal_giveIsrLock(&ptr_cb->intr_lock, &irq_flag); + + /* Module thread handle and unmask the interrupt */ + intr_unmask = intr_status ^ intr_mask; + if (0x0 != intr_status) + { + for (idx = 0; idx < vec; idx++) + { + if (_hal_tau_pkt_intr_vec[idx].intr_reg & intr_status) + { + osal_triggerEvent(&_hal_tau_pkt_intr_vec[idx].intr_event); + _hal_tau_pkt_intr_vec[idx].intr_cnt++; + } + } + } + + /* UNMASK other PKT IRQs */ + osal_takeIsrLock(&ptr_cb->intr_lock, &irq_flag); + osal_mdc_writePciReg(unit, HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_CP_COMMON_INT_MASK_SET_HI), &intr_unmask, sizeof(UI32_T)); + osal_giveIsrLock(&ptr_cb->intr_lock, &irq_flag); + + return (NPS_E_OK); +} + +/* ----------------------------------------------------------------------------------- RW HW Regs */ +/* FUNCTION NAME: _hal_tau_pkt_startTxChannelReg + * PURPOSE: + * To issue "START" command to the target TX channel. + * INPUT: + * unit -- The unit ID + * channel -- The target TX channel + * gpd_num -- The GPD ring length of the channel + * OUTPUT: + * None. + * RETURN: + * NPS_E_OK -- Successfully configure the register. + * NPS_E_OTHERS -- Configure the register failed. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_startTxChannelReg( + const UI32_T unit, + const HAL_TAU_PKT_TX_CHANNEL_T channel, + const UI32_T gpd_num) +{ + HAL_TAU_PKT_TCH_CMD_REG_T tch_cmd; + + tch_cmd.reg = 0x0; + tch_cmd.field.tch_start = 0x1; + tch_cmd.field.tch_gpd_add_no_lo = gpd_num & 0xff; + tch_cmd.field.tch_gpd_add_no_hi = (gpd_num & 0xff00) >> 8; + + osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_PDMA_TCH_REG(HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_TCH_CMD), channel), + &tch_cmd.reg, sizeof(HAL_TAU_PKT_TCH_CMD_REG_T)); + + return (NPS_E_OK); +} + +/* FUNCTION NAME: _hal_tau_pkt_startRxChannelReg + * PURPOSE: + * To issue "START" command to the target RX channel. + * INPUT: + * unit -- The unit ID + * channel -- The target RX channel + * gpd_num -- The GPD ring length of the channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully configure the register. + * NPS_E_OTHERS -- Configure the register failed. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_startRxChannelReg( + const UI32_T unit, + const HAL_TAU_PKT_RX_CHANNEL_T channel, + const UI32_T gpd_num) +{ + HAL_TAU_PKT_RCH_CMD_REG_T rch_cmd; + + rch_cmd.reg = 0x0; + rch_cmd.field.rch_start = 0x1; + rch_cmd.field.rch_gpd_add_no_lo = gpd_num & 0xff; + rch_cmd.field.rch_gpd_add_no_hi = (gpd_num & 0xff00) >> 8; + + osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_PDMA_RCH_REG(HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_RCH_CMD), channel), + &rch_cmd.reg, sizeof(HAL_TAU_PKT_RCH_CMD_REG_T)); + + return (NPS_E_OK); +} + +/* FUNCTION NAME: _hal_tau_pkt_resumeTxChannelReg + * PURPOSE: + * To issue "RESUME" command to the target TX channel. + * INPUT: + * unit -- The unit ID + * channel -- The target TX channel + * gpd_num -- The GPD ring length of the channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully configure the register. + * NPS_E_OTHERS -- Configure the register failed. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_resumeTxChannelReg( + const UI32_T unit, + const HAL_TAU_PKT_TX_CHANNEL_T channel, + const UI32_T gpd_num) +{ + HAL_TAU_PKT_TCH_CMD_REG_T tch_cmd; + + tch_cmd.reg = 0x0; + tch_cmd.field.tch_resume = 0x1; + tch_cmd.field.tch_gpd_add_no_lo = gpd_num & 0xff; + tch_cmd.field.tch_gpd_add_no_hi = (gpd_num & 0xff00) >> 8; + + osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_PDMA_TCH_REG(HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_TCH_CMD), channel), + &tch_cmd.reg, sizeof(HAL_TAU_PKT_TCH_CMD_REG_T)); + + return (NPS_E_OK); +} + +/* FUNCTION NAME: _hal_tau_pkt_resumeRxChannelReg + * PURPOSE: + * To issue "RESUME" command to the target RX channel. + * INPUT: + * unit -- The unit ID + * channel -- The target RX channel + * gpd_num -- The GPD ring length of the channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully configure the register. + * NPS_E_OTHERS -- Configure the register failed. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_resumeRxChannelReg( + const UI32_T unit, + const HAL_TAU_PKT_RX_CHANNEL_T channel, + const UI32_T gpd_num) +{ + HAL_TAU_PKT_RCH_CMD_REG_T rch_cmd; + + rch_cmd.reg = 0x0; + rch_cmd.field.rch_resume = 0x1; + rch_cmd.field.rch_gpd_add_no_lo = gpd_num & 0xff; + rch_cmd.field.rch_gpd_add_no_hi = (gpd_num & 0xff00) >> 8; + + osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_PDMA_RCH_REG(HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_RCH_CMD), channel), + &rch_cmd.reg, sizeof(HAL_TAU_PKT_RCH_CMD_REG_T)); + + return (NPS_E_OK); +} + +/* FUNCTION NAME: _hal_tau_pkt_stopTxChannelReg + * PURPOSE: + * To issue "STOP" command to the target TX channel. + * INPUT: + * unit -- The unit ID + * channel -- The target TX channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully configure the register. + * NPS_E_OTHERS -- Configure the register failed. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_stopTxChannelReg( + const UI32_T unit, + const HAL_TAU_PKT_TX_CHANNEL_T channel) +{ + HAL_TAU_PKT_TCH_CMD_REG_T tch_cmd; + + tch_cmd.reg = 0x0; + tch_cmd.field.tch_stop = 0x1; + + osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_PDMA_TCH_REG(HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_TCH_CMD), channel), + &tch_cmd.reg, sizeof(HAL_TAU_PKT_TCH_CMD_REG_T)); + + return (NPS_E_OK); +} + +/* FUNCTION NAME: _hal_tau_pkt_stopRxChannelReg + * PURPOSE: + * To issue "STOP" command to the target RX channel. + * INPUT: + * unit -- The unit ID + * channel -- The target RX channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully configure the register. + * NPS_E_OTHERS -- Configure the register failed. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_stopRxChannelReg( + const UI32_T unit, + const HAL_TAU_PKT_RX_CHANNEL_T channel) +{ + HAL_TAU_PKT_RCH_CMD_REG_T rch_cmd; + + rch_cmd.reg = 0x0; + rch_cmd.field.rch_stop = 0x1; + + osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_PDMA_RCH_REG(HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_RCH_CMD), channel), + &rch_cmd.reg, sizeof(HAL_TAU_PKT_RCH_CMD_REG_T)); + + return (NPS_E_OK); +} + +/* ----------------------------------------------------------------------------------- Init HW Regs */ +/* FUNCTION NAME: _hal_tau_pkt_setTxGpdStartAddrReg + * PURPOSE: + * To configure the start address and the length of target GPD ring of TX channel. + * INPUT: + * unit -- The unit ID + * channel -- The target TX channel + * gpd_start_addr -- The start address of the GPD ring + * gpd_ring_sz -- The size of the GPD ring + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully configure the register. + * NPS_E_OTHERS -- Configure the register failed. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_setTxGpdStartAddrReg( + const UI32_T unit, + const HAL_TAU_PKT_TX_CHANNEL_T channel, + const NPS_ADDR_T gpd_start_addr, + const UI32_T gpd_ring_sz) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + UI32_T tch_gpd_ring_start_addr_lo = 0; + UI32_T tch_gpd_ring_start_addr_hi = 0; + UI32_T tch_gpd_ring_size = 0; + + /* Configure the low 32-bit address. */ + tch_gpd_ring_start_addr_lo = (UI32_T)NPS_ADDR_64_LOW(gpd_start_addr); + + rc = osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_PDMA_TCH_REG(HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_TCH_GPD_RING_START_ADDR_LO), channel), + &tch_gpd_ring_start_addr_lo, sizeof(UI32_T)); + + /* Configure the high 32-bit address. */ + if (NPS_E_OK == rc) + { + tch_gpd_ring_start_addr_hi = (UI32_T)NPS_ADDR_64_HI(gpd_start_addr); + + rc = osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_PDMA_TCH_REG(HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_TCH_GPD_RING_START_ADDR_HI), channel), + &tch_gpd_ring_start_addr_hi, sizeof(UI32_T)); + } + + /* Configure the GPD ring size. */ + if (NPS_E_OK == rc) + { + tch_gpd_ring_size = gpd_ring_sz; + + rc = osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_PDMA_TCH_REG(HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_TCH_GPD_RING_SIZE), channel), + &tch_gpd_ring_size, sizeof(UI32_T)); + } + + return (rc); +} + +/* FUNCTION NAME: _hal_tau_pkt_setRxGpdStartAddrReg + * PURPOSE: + * To configure the start address and the length of target GPD ring of RX channel. + * INPUT: + * unit -- The unit ID + * channel -- The target RX channel + * gpd_start_addr -- The start address of the GPD ring + * gpd_ring_sz -- The size of the GPD ring + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully configure the register. + * NPS_E_OTHERS -- Configure the register failed. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_setRxGpdStartAddrReg( + const UI32_T unit, + const HAL_TAU_PKT_RX_CHANNEL_T channel, + const NPS_ADDR_T gpd_start_addr, + const UI32_T gpd_ring_sz) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + UI32_T rch_gpd_ring_start_addr_lo = 0; + UI32_T rch_gpd_ring_start_addr_hi = 0; + UI32_T rch_gpd_ring_size = 0; + + /* Configure the low 32-bit address. */ + rch_gpd_ring_start_addr_lo = (UI32_T)NPS_ADDR_64_LOW(gpd_start_addr); + + rc = osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_PDMA_RCH_REG(HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_RCH_GPD_RING_START_ADDR_LO), channel), + &rch_gpd_ring_start_addr_lo, sizeof(UI32_T)); + + /* Configure the high 32-bit address. */ + if (NPS_E_OK == rc) + { + rch_gpd_ring_start_addr_hi = (UI32_T)NPS_ADDR_64_HI(gpd_start_addr); + + rc = osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_PDMA_RCH_REG(HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_RCH_GPD_RING_START_ADDR_HI), channel), + &rch_gpd_ring_start_addr_hi, sizeof(UI32_T)); + } + + /* Configure the GPD ring size. */ + if (NPS_E_OK == rc) + { + rch_gpd_ring_size = gpd_ring_sz; + + rc = osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_PDMA_RCH_REG(HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_RCH_GPD_RING_SIZE), channel), + &rch_gpd_ring_size, sizeof(UI32_T)); + } + + return (rc); +} + +/* ----------------------------------------------------------------------------------- ISR HW Regs */ +/* FUNCTION NAME: _hal_tau_pkt_maskAllTxL2IsrReg + * PURPOSE: + * To mask all the TX L2 interrupts for the specified channel. + * INPUT: + * unit -- The unit ID + * channel -- The target TX channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully mask all the TX L2 interrupts. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_maskAllTxL2IsrReg( + const UI32_T unit, + const HAL_TAU_PKT_TX_CHANNEL_T channel) +{ + UI32_T reg = 0; + + HAL_TAU_PKT_CLR_BITMAP(reg, + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_HWO_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_NO_OVFL_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_DMA_READ_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_BUF_SIZE_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_RUNT_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_OVSZ_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_LEN_MISMATCH_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PKTPL_DMA_READ_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_COS_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_GT255_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PFC | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_CREDIT_UDFL_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_DMA_WRITE_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_STOP_CMD_CPLT); + + osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_PDMA_TCH_REG(HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_TCH_INT_MASK), channel), + ®, sizeof(UI32_T)); + + return (NPS_E_OK); +} + +/* FUNCTION NAME: _hal_tau_pkt_maskAllRxL2IsrReg + * PURPOSE: + * To mask all the L2 interrupts for the specified channel. + * INPUT: + * unit -- The unit ID + * channel -- The target RX channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully mask all the L2 interrupts. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_maskAllRxL2IsrReg( + const UI32_T unit, + const HAL_TAU_PKT_RX_CHANNEL_T channel) +{ + UI32_T reg = 0; + + HAL_TAU_PKT_CLR_BITMAP(reg, + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_LOW | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_EMPTY | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_ERROR | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_READ_ERROR | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_WRITE_ERROR | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_STOP_CMD_CPLT | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_GT255_ERROR | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_TOD_UNINIT | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_PKT_ERROR_DROP | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_UDSZ_DROP | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_OVSZ_DROP | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_CMDQ_OVF_DROP | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_FIFO_OVF_DROP); + + osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_PDMA_RCH_REG(HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_RCH_INT_MASK), channel), + ®, sizeof(UI32_T)); + + return (NPS_E_OK); +} + +/* FUNCTION NAME: _hal_tau_pkt_unmaskAllTxL2IsrReg + * PURPOSE: + * To unmask all the TX L2 interrupts for the specified channel. + * INPUT: + * unit -- The unit ID + * channel -- The target TX channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully unmask all the TX L2 interrupts. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_unmaskAllTxL2IsrReg( + const UI32_T unit, + const HAL_TAU_PKT_TX_CHANNEL_T channel) +{ + UI32_T reg = 0; + + HAL_TAU_PKT_SET_BITMAP(reg, + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_HWO_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_NO_OVFL_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_DMA_READ_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_BUF_SIZE_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_RUNT_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_OVSZ_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_LEN_MISMATCH_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PKTPL_DMA_READ_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_COS_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_GT255_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PFC | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_CREDIT_UDFL_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_DMA_WRITE_ERROR | + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_STOP_CMD_CPLT); + + osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_PDMA_TCH_REG(HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_TCH_INT_MASK), channel), + ®, sizeof(UI32_T)); + + return (NPS_E_OK); +} + +/* FUNCTION NAME: _hal_tau_pkt_unmaskAllRxL2IsrReg + * PURPOSE: + * To unmask all the L2 interrupts for the specified channel. + * INPUT: + * unit -- The unit ID + * channel -- The target RX channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully unmask all the L2 interrupts. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_unmaskAllRxL2IsrReg( + const UI32_T unit, + const HAL_TAU_PKT_RX_CHANNEL_T channel) +{ + UI32_T reg = 0; + + HAL_TAU_PKT_SET_BITMAP(reg, + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_LOW | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_EMPTY | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_ERROR | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_READ_ERROR | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_WRITE_ERROR | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_STOP_CMD_CPLT | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_GT255_ERROR | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_TOD_UNINIT | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_PKT_ERROR_DROP | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_UDSZ_DROP | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_OVSZ_DROP | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_CMDQ_OVF_DROP | + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_FIFO_OVF_DROP); + + osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_PDMA_RCH_REG(HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_RCH_INT_MASK), channel), + ®, sizeof(UI32_T)); + + return (NPS_E_OK); +} + +/* FUNCTION NAME: _hal_tau_pkt_clearTxL2IsrStatusReg + * PURPOSE: + * To clear the status of TX L2 interrupts for the specified channel. + * INPUT: + * unit -- The unit ID + * channel -- The target TX channel + * isr_bitmap -- The bitmap used to specify the target ISRs + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully clear L1 ISR status. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_clearTxL2IsrStatusReg( + const UI32_T unit, + const HAL_TAU_PKT_TX_CHANNEL_T channel, + const HAL_TAU_PKT_TX_CHANNEL_L2_ISR_T isr_bitmap) +{ + UI32_T reg = 0; + + HAL_TAU_PKT_SET_BITMAP(reg, isr_bitmap); + + osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_PDMA_TCH_REG(HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_TCH_INT_CLR), channel), + ®, sizeof(UI32_T)); + + return (NPS_E_OK); +} + +/* FUNCTION NAME: _hal_tau_pkt_clearRxL2IsrStatusReg + * PURPOSE: + * To clear the status of RX L2 interrupts for the specified channel. + * INPUT: + * unit -- The unit ID + * channel -- The target RX channel + * isr_bitmap -- The bitmap used to specify the target ISRs + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully clear RX L2 ISR status. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_clearRxL2IsrStatusReg( + const UI32_T unit, + const HAL_TAU_PKT_RX_CHANNEL_T channel, + const HAL_TAU_PKT_RX_CHANNEL_L2_ISR_T isr_bitmap) +{ + UI32_T reg = 0; + + HAL_TAU_PKT_SET_BITMAP(reg, isr_bitmap); + + osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_PDMA_RCH_REG(HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_RCH_INT_CLR), channel), + ®, sizeof(UI32_T)); + + return (NPS_E_OK); +} + +/* FUNCTION NAME: hal_tau_pkt_getTxIntrCnt + * PURPOSE: + * To get the PDMA TX interrupt counters of the target channel. + * INPUT: + * unit -- The unit ID + * channel -- The target channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully get the counters. + * NOTES: + * None + */ +NPS_ERROR_NO_T +hal_tau_pkt_getTxIntrCnt( + const UI32_T unit, + const UI32_T channel, + UI32_T *ptr_intr_cnt) +{ + *ptr_intr_cnt = HAL_TAU_PKT_TCH_CNT(unit, channel); + return (NPS_E_OK); +} + +/* FUNCTION NAME: hal_tau_pkt_getRxIntrCnt + * PURPOSE: + * To get the PDMA RX interrupt counters of the target channel. + * INPUT: + * unit -- The unit ID + * channel -- The target channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully get the counters. + * NOTES: + * None + */ +NPS_ERROR_NO_T +hal_tau_pkt_getRxIntrCnt( + const UI32_T unit, + const UI32_T channel, + UI32_T *ptr_intr_cnt) +{ + *ptr_intr_cnt = HAL_TAU_PKT_RCH_CNT(unit, channel); + return (NPS_E_OK); +} + +/* FUNCTION NAME: hal_tau_pkt_getTxKnlCnt + * PURPOSE: + * To get the PDMA TX counters of the target channel. + * INPUT: + * unit -- The unit ID + * ptr_cookie -- Pointer of the TX cookie + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully get the counters. + * NOTES: + * None + */ +NPS_ERROR_NO_T +hal_tau_pkt_getTxKnlCnt( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_CH_CNT_COOKIE_T *ptr_cookie) +{ + HAL_TAU_PKT_TX_CB_T *ptr_tx_cb = HAL_TAU_PKT_GET_TX_CB_PTR(unit); + + osal_io_copyToUser(&ptr_cookie->tx_cnt, &ptr_tx_cb->cnt, sizeof(HAL_TAU_PKT_TX_CNT_T)); + return (NPS_E_OK); +} + +/* FUNCTION NAME: hal_tau_pkt_getRxKnlCnt + * PURPOSE: + * To get the PDMA RX counters of the target channel. + * INPUT: + * unit -- The unit ID + * ptr_cookie -- Pointer of the RX cookie + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully get the counters. + * NOTES: + * None + */ +NPS_ERROR_NO_T +hal_tau_pkt_getRxKnlCnt( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_CH_CNT_COOKIE_T *ptr_cookie) +{ + HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); + + osal_io_copyToUser(&ptr_cookie->rx_cnt, &ptr_rx_cb->cnt, sizeof(HAL_TAU_PKT_RX_CNT_T)); + return (NPS_E_OK); +} + +/* FUNCTION NAME: hal_tau_pkt_clearTxKnlCnt + * PURPOSE: + * To clear the PDMA TX counters of the target channel. + * INPUT: + * unit -- The unit ID + * ptr_cookie -- Pointer of the TX cookie + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully clear the counters. + * NOTES: + * None + */ +NPS_ERROR_NO_T +hal_tau_pkt_clearTxKnlCnt( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_TX_COOKIE_T *ptr_cookie) +{ + HAL_TAU_PKT_TX_CB_T *ptr_tx_cb = HAL_TAU_PKT_GET_TX_CB_PTR(unit); + + osal_memset(&ptr_tx_cb->cnt, 0, sizeof(HAL_TAU_PKT_TX_CNT_T)); + return (NPS_E_OK); +} + +/* FUNCTION NAME: hal_tau_pkt_clearRxKnlCnt + * PURPOSE: + * To clear the PDMA RX counters of the target channel. + * INPUT: + * unit -- The unit ID + * ptr_cookie -- Pointer of the RX cookie + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully clear the counters. + * NOTES: + * None + */ +NPS_ERROR_NO_T +hal_tau_pkt_clearRxKnlCnt( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_RX_COOKIE_T *ptr_cookie) +{ + HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); + + osal_memset(&ptr_rx_cb->cnt, 0, sizeof(HAL_TAU_PKT_RX_CNT_T)); + return (NPS_E_OK); +} + +/* FUNCTION NAME: hal_tau_pkt_setPortAttr + * PURPOSE: + * To set the port attributes such as status or speeds. + * INPUT: + * unit -- The unit ID + * ptr_cookie -- Pointer of the Port cookie + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully set the attributes. + * NOTES: + * None + */ +NPS_ERROR_NO_T +hal_tau_pkt_setPortAttr( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_PORT_COOKIE_T *ptr_cookie) +{ +#define HAL_TAU_PKT_PORT_STATUS_UP (1) +#define HAL_TAU_PKT_PORT_STATUS_DOWN (0) + struct net_device *ptr_net_dev; + struct net_device_priv *ptr_priv; + UI32_T port; + UI32_T status; + NPS_PORT_SPEED_T speed; + + osal_io_copyFromUser(&port, &ptr_cookie->port, sizeof(UI32_T)); + osal_io_copyFromUser(&status, &ptr_cookie->status, sizeof(UI32_T)); + osal_io_copyFromUser(&speed, &ptr_cookie->speed, sizeof(NPS_PORT_SPEED_T)); + + ptr_net_dev = HAL_TAU_PKT_GET_PORT_NETDEV(port); + if ((NULL != ptr_net_dev) && (portspeed = SPEED_1000; + break; + case NPS_PORT_SPEED_10G: + ptr_priv->speed = SPEED_10000; + break; + case NPS_PORT_SPEED_25G: + ptr_priv->speed = 25000; + break; + case NPS_PORT_SPEED_40G: + ptr_priv->speed = 40000; + break; + case NPS_PORT_SPEED_50G: + ptr_priv->speed = 50000; + break; + case NPS_PORT_SPEED_100G: + ptr_priv->speed = 100000; + break; + default: + break; + } + } + return (NPS_E_OK); +} + + +/* ----------------------------------------------------------------------------------- independent func */ +/* FUNCTION NAME: _hal_tau_pkt_enQueue + * PURPOSE: + * To enqueue the target data. + * INPUT: + * ptr_que -- Pointer for the target queue + * ptr_data -- Pointer for the data to be enqueued + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully enqueue the data. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_enQueue( + HAL_TAU_PKT_SW_QUEUE_T *ptr_que, + void *ptr_data) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + + osal_takeSemaphore(&ptr_que->sema, NPS_SEMAPHORE_WAIT_FOREVER); + rc = osal_que_enque(&ptr_que->que_id, ptr_data); + osal_giveSemaphore(&ptr_que->sema); + + return (rc); +} + +/* FUNCTION NAME: _hal_tau_pkt_deQueue + * PURPOSE: + * To dequeue the target data. + * INPUT: + * ptr_que -- Pointer for the target queue + * pptr_data -- Pointer for the data pointer to be dequeued + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully dequeue the data. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_deQueue( + HAL_TAU_PKT_SW_QUEUE_T *ptr_que, + void **pptr_data) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + + osal_takeSemaphore(&ptr_que->sema, NPS_SEMAPHORE_WAIT_FOREVER); + rc = osal_que_deque(&ptr_que->que_id, pptr_data); + osal_giveSemaphore(&ptr_que->sema); + + return (rc); +} + +/* FUNCTION NAME: _hal_tau_pkt_getQueueCount + * PURPOSE: + * To obtain the current GPD number in the target RX queue. + * INPUT: + * ptr_que -- Pointer for the target queue + * ptr_count -- Pointer for the data count + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully obtain the GPD count. + * NPS_E_BAD_PARAMETER -- Parameter pointer is null. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_getQueueCount( + HAL_TAU_PKT_SW_QUEUE_T *ptr_que, + UI32_T *ptr_count) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + + osal_takeSemaphore(&ptr_que->sema, NPS_SEMAPHORE_WAIT_FOREVER); + osal_que_getCount(&ptr_que->que_id, ptr_count); + osal_giveSemaphore(&ptr_que->sema); + + return (rc); +} + +/* FUNCTION NAME: _hal_tau_pkt_allocRxPayloadBuf + * PURPOSE: + * To allocate the RX packet payload buffer for the GPD. + * INPUT: + * unit -- The unit ID + * channel -- The target RX channel + * gpd_idx -- The current GPD index + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully allocate the buffer. + * NPS_E_NO_MEMORY -- Allocate the buffer failed. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_allocRxPayloadBuf( + const UI32_T unit, + const UI32_T channel, + const UI32_T gpd_idx) +{ + NPS_ERROR_NO_T rc = NPS_E_NO_MEMORY; + HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); + volatile HAL_TAU_PKT_RX_GPD_T *ptr_rx_gpd = HAL_TAU_PKT_GET_RX_GPD_PTR(unit, channel, gpd_idx); + NPS_ADDR_T phy_addr = 0; + + HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, channel); + struct sk_buff *ptr_skb = NULL; + + ptr_skb = osal_skb_alloc(ptr_rx_cb->buf_len); + if (NULL != ptr_skb) + { + /* map skb to dma */ + phy_addr = osal_skb_mapDma(ptr_skb, DMA_FROM_DEVICE); + if (0x0 == phy_addr) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_ERR, + "u=%u, rxch=%u, skb dma map err, size=%u\n", + unit, channel, ptr_skb->len); + osal_skb_free(ptr_skb); + rc = NPS_E_NO_MEMORY; + } + else + { + ptr_rx_pdma->pptr_skb_ring[gpd_idx] = ptr_skb; + rc = NPS_E_OK; + } + } + + if (NPS_E_OK == rc) + { + ptr_rx_gpd->data_buf_addr_hi = NPS_ADDR_64_HI(phy_addr); + ptr_rx_gpd->data_buf_addr_lo = NPS_ADDR_64_LOW(phy_addr); + ptr_rx_gpd->avbl_buf_len = ptr_rx_cb->buf_len; + } + + return (rc); +} + +/* FUNCTION NAME: _hal_tau_pkt_freeRxPayloadBuf + * PURPOSE: + * To free the RX packet payload buffer for the GPD. + * INPUT: + * unit -- The unit ID + * channel -- The target RX channel + * gpd_idx -- The current GPD index + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully free the buffer. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_freeRxPayloadBuf( + const UI32_T unit, + const UI32_T channel, + const UI32_T gpd_idx) +{ + NPS_ERROR_NO_T rc = NPS_E_OTHERS; + volatile HAL_TAU_PKT_RX_GPD_T *ptr_rx_gpd = HAL_TAU_PKT_GET_RX_GPD_PTR(unit, channel, gpd_idx); + NPS_ADDR_T phy_addr = 0; + + HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, channel); + struct sk_buff *ptr_skb = NULL; + + phy_addr = NPS_ADDR_32_TO_64(ptr_rx_gpd->data_buf_addr_hi, ptr_rx_gpd->data_buf_addr_lo); + if (0x0 != phy_addr) + { + /* unmap dma */ + ptr_skb = ptr_rx_pdma->pptr_skb_ring[gpd_idx]; + osal_skb_unmapDma(phy_addr, ptr_skb->len, DMA_FROM_DEVICE); + osal_skb_free(ptr_skb); + rc = NPS_E_OK; + } + + if (NPS_E_OK == rc) + { + ptr_rx_gpd->data_buf_addr_hi = 0x0; + ptr_rx_gpd->data_buf_addr_lo = 0x0; + } + + return (rc); +} + +/* FUNCTION NAME: _hal_tau_pkt_freeRxPayloadBufGpd + * PURPOSE: + * To free the RX packet payload buffer for the GPD. + * INPUT: + * unit -- The unit ID + * ptr_sw_gpd -- The pointer of RX SW GPD + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully free the buffer. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_freeRxPayloadBufGpd( + const UI32_T unit, + HAL_TAU_PKT_RX_SW_GPD_T *ptr_sw_gpd) +{ + NPS_ERROR_NO_T rc = NPS_E_OTHERS; + NPS_ADDR_T phy_addr = 0; + + struct sk_buff *ptr_skb = NULL; + + phy_addr = NPS_ADDR_32_TO_64(ptr_sw_gpd->rx_gpd.data_buf_addr_hi, ptr_sw_gpd->rx_gpd.data_buf_addr_lo); + if (0x0 != phy_addr) + { + ptr_skb = ptr_sw_gpd->ptr_cookie; + osal_skb_free(ptr_skb); + rc = NPS_E_OK; + } + + return (rc); +} + +/* FUNCTION NAME: _hal_tau_initTxPdmaRing + * PURPOSE: + * To initialize the GPD ring of target TX channel. + * + * INPUT: + * unit -- The unit ID + * channel -- The target TX channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully initialize the GPD ring. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_initTxPdmaRing( + const UI32_T unit, + const HAL_TAU_PKT_TX_CHANNEL_T channel) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + HAL_TAU_PKT_TX_PDMA_T *ptr_tx_pdma = HAL_TAU_PKT_GET_TX_PDMA_PTR(unit, channel); + volatile HAL_TAU_PKT_TX_GPD_T *ptr_tx_gpd = NULL; + NPS_ADDR_T phy_addr = 0; + UI32_T gpd_idx = 0; + + for (gpd_idx = 0; gpd_idx < ptr_tx_pdma->gpd_num; gpd_idx++) + { + ptr_tx_gpd = HAL_TAU_PKT_GET_TX_GPD_PTR(unit, channel, gpd_idx); + osal_memset((void *)ptr_tx_gpd, 0x0, sizeof(HAL_TAU_PKT_TX_GPD_T)); + ptr_tx_gpd->ioc = HAL_TAU_PKT_IOC_HAS_INTR; + ptr_tx_gpd->ch = HAL_TAU_PKT_CH_LAST_GPD; + ptr_tx_gpd->hwo = HAL_TAU_PKT_HWO_SW_OWN; + osal_dma_flushCache((void *)ptr_tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); + } + + phy_addr = osal_dma_convertVirtToPhy(ptr_tx_pdma->ptr_gpd_align_start_addr); + rc = _hal_tau_pkt_setTxGpdStartAddrReg(unit, channel, phy_addr, ptr_tx_pdma->gpd_num); + + return (rc); +} + +/* FUNCTION NAME: _hal_tau_pkt_initRxPdmaRing + * PURPOSE: + * To initialize the RX GPD ring. + * INPUT: + * unit -- The target unit + * channel -- The target RX channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully initialize the RX GPD ring. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_initRxPdmaRing( + const UI32_T unit, + const HAL_TAU_PKT_RX_CHANNEL_T channel) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, channel); + volatile HAL_TAU_PKT_RX_GPD_T *ptr_rx_gpd = NULL; + NPS_ADDR_T phy_addr = 0; + UI32_T gpd_idx = 0; + + for (gpd_idx = 0; gpd_idx < ptr_rx_pdma->gpd_num; gpd_idx++) + { + ptr_rx_gpd = HAL_TAU_PKT_GET_RX_GPD_PTR(unit, channel, gpd_idx); + osal_memset((void *)ptr_rx_gpd, 0x0, sizeof(HAL_TAU_PKT_RX_GPD_T)); + ptr_rx_gpd->ioc = HAL_TAU_PKT_IOC_NO_INTR; + ptr_rx_gpd->hwo = HAL_TAU_PKT_HWO_SW_OWN; + osal_dma_flushCache((void *)ptr_rx_gpd, sizeof(HAL_TAU_PKT_RX_GPD_T)); + } + + phy_addr = osal_dma_convertVirtToPhy(ptr_rx_pdma->ptr_gpd_align_start_addr); + rc = _hal_tau_pkt_setRxGpdStartAddrReg(unit, channel, phy_addr, ptr_rx_pdma->gpd_num); + + return (rc); +} + +/* FUNCTION NAME: _hal_tau_pkt_initRxPdmaRingBuf + * PURPOSE: + * To de-init the Rx PDMA ring configuration. + * INPUT: + * unit -- The unit ID + * channel -- The target RX channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully de-init the Rx PDMA ring. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_initRxPdmaRingBuf( + const UI32_T unit, + const HAL_TAU_PKT_RX_CHANNEL_T channel) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); + HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, channel); + volatile HAL_TAU_PKT_RX_GPD_T *ptr_rx_gpd = NULL; + UI32_T gpd_idx = 0; + + if (0 == ptr_rx_cb->buf_len) + { + return (NPS_E_BAD_PARAMETER); + } + + for (gpd_idx = 0; gpd_idx < ptr_rx_pdma->gpd_num; gpd_idx++) + { + ptr_rx_gpd = HAL_TAU_PKT_GET_RX_GPD_PTR(unit, channel, gpd_idx); + osal_dma_invalidateCache((void *)ptr_rx_gpd, sizeof(HAL_TAU_PKT_RX_GPD_T)); + + rc = _hal_tau_pkt_allocRxPayloadBuf(unit, channel, gpd_idx); + if (NPS_E_OK == rc) + { + ptr_rx_gpd->ioc = HAL_TAU_PKT_IOC_HAS_INTR; + ptr_rx_gpd->hwo = HAL_TAU_PKT_HWO_HW_OWN; + osal_dma_flushCache((void *)ptr_rx_gpd, sizeof(HAL_TAU_PKT_RX_GPD_T)); + } + else + { + ptr_rx_cb->cnt.no_memory++; + break; + } + } + + return (rc); +} + +/* FUNCTION NAME: _hal_tau_pkt_deinitRxPdmaRingBuf + * PURPOSE: + * To de-init the Rx PDMA ring configuration. + * INPUT: + * unit -- The unit ID + * channel -- The target RX channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully de-init the Rx PDMA ring. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_deinitRxPdmaRingBuf( + const UI32_T unit, + const HAL_TAU_PKT_RX_CHANNEL_T channel) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, channel); + volatile HAL_TAU_PKT_RX_GPD_T *ptr_rx_gpd = NULL; + UI32_T gpd_idx = 0; + + for (gpd_idx = 0; ((gpd_idx < ptr_rx_pdma->gpd_num) && (NPS_E_OK == rc)); gpd_idx++) + { + /* mark the GPD as invalid to prevent Rx-done task to process it */ + ptr_rx_gpd = HAL_TAU_PKT_GET_RX_GPD_PTR(unit, channel, gpd_idx); + ptr_rx_gpd->hwo = HAL_TAU_PKT_HWO_HW_OWN; + osal_dma_flushCache((void *)ptr_rx_gpd, sizeof(HAL_TAU_PKT_RX_GPD_T)); + + rc = _hal_tau_pkt_freeRxPayloadBuf(unit, channel, gpd_idx); + } + return (rc); +} + +/* FUNCTION NAME: _hal_tau_pkt_recoverTxPdma + * PURPOSE: + * To recover the PDMA status to the initial state. + * INPUT: + * unit -- The unit ID + * channel -- The target TX channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully recover PDMA. + * NOTES: + * + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_recoverTxPdma( + const UI32_T unit, + const HAL_TAU_PKT_TX_CHANNEL_T channel) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + HAL_TAU_PKT_TX_PDMA_T *ptr_tx_pdma = HAL_TAU_PKT_GET_TX_PDMA_PTR(unit, channel); + + /* Release the software GPD ring and configure it again. */ + ptr_tx_pdma->used_idx = 0; + ptr_tx_pdma->free_idx = 0; + ptr_tx_pdma->used_gpd_num = 0; + ptr_tx_pdma->free_gpd_num = ptr_tx_pdma->gpd_num; + + _hal_tau_pkt_stopTxChannelReg(unit, channel); + rc = _hal_tau_pkt_initTxPdmaRing(unit, channel); + _hal_tau_pkt_startTxChannelReg(unit, channel, 0); + + return (rc); +} + +/* FUNCTION NAME: _hal_tau_pkt_recoverRxPdma + * PURPOSE: + * To recover the RX PDMA from the error state. + * INPUT: + * unit -- The unit ID + * channel -- The target RX channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully recovery the PDMA. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_recoverRxPdma( + const UI32_T unit, + const HAL_TAU_PKT_RX_CHANNEL_T channel) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, channel); + + /* Release the software GPD ring and configure it again. */ + ptr_rx_pdma->cur_idx = 0; + + _hal_tau_pkt_stopRxChannelReg(unit, channel); + rc = _hal_tau_pkt_deinitRxPdmaRingBuf(unit, channel); + if (NPS_E_OK != rc) + { + return (rc); + } + rc = _hal_tau_pkt_initRxPdmaRing(unit, channel); + if (NPS_E_OK != rc) + { + return (rc); + } + rc = _hal_tau_pkt_initRxPdmaRingBuf(unit, channel); + if (NPS_E_OK != rc) + { + return (rc); + } + _hal_tau_pkt_startRxChannelReg(unit, channel, ptr_rx_pdma->gpd_num); + + return (rc); +} + +/* FUNCTION NAME: _hal_tau_pkt_freeTxGpdList + * PURPOSE: + * To free the TX SW GPD link list. + * INPUT: + * unit -- The unit ID + * ptr_sw_gpd -- The pointer of TX SW GPD + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully free the GPD list. + * NOTES: + * None + */ +static void +_hal_tau_pkt_freeTxGpdList( + UI32_T unit, + HAL_TAU_PKT_TX_SW_GPD_T *ptr_sw_gpd) +{ + HAL_TAU_PKT_TX_SW_GPD_T *ptr_sw_gpd_cur = NULL; + + while (NULL != ptr_sw_gpd) + { + ptr_sw_gpd_cur = ptr_sw_gpd; + ptr_sw_gpd = ptr_sw_gpd->ptr_next; + osal_free(ptr_sw_gpd_cur); + } +} + +/* FUNCTION NAME: _hal_tau_pkt_freeRxGpdList + * PURPOSE: + * To free the RX SW GPD link list. + * INPUT: + * unit -- The unit ID + * ptr_sw_gpd -- The pointer of RX SW GPD + * free_payload -- TRUE: To free the buf in SDK, FALSE: in user process. + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully recovery the PDMA. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_freeRxGpdList( + UI32_T unit, + HAL_TAU_PKT_RX_SW_GPD_T *ptr_sw_gpd, + BOOL_T free_payload) +{ + HAL_TAU_PKT_RX_SW_GPD_T *ptr_sw_gpd_cur = NULL; + + while (NULL != ptr_sw_gpd) + { + ptr_sw_gpd_cur = ptr_sw_gpd; + ptr_sw_gpd = ptr_sw_gpd->ptr_next; + if (TRUE == free_payload) + { + _hal_tau_pkt_freeRxPayloadBufGpd(unit, ptr_sw_gpd_cur); + } + osal_free(ptr_sw_gpd_cur); + } + + return (NPS_E_OK); +} + +/* ----------------------------------------------------------------------------------- pkt_drv */ +/* FUNCTION NAME: _hal_tau_pkt_txEnQueueBulk + * PURPOSE: + * To enqueue numbers of packet in the bulk buffer + * INPUT: + * unit -- The unit ID + * channel -- The target channel + * number -- The number of packet to be enqueue + * OUTPUT: + * None + * RETURN: + * None + * NOTES: + * None + */ +static void +_hal_tau_pkt_txEnQueueBulk( + const UI32_T unit, + const UI32_T channel, + const UI32_T number) +{ + HAL_TAU_PKT_TX_PDMA_T *ptr_tx_pdma = HAL_TAU_PKT_GET_TX_PDMA_PTR(unit, channel); + HAL_TAU_PKT_TX_SW_GPD_T *ptr_sw_gpd = NULL; + UI32_T idx; + + for (idx = 0; idx < number; idx++) + { + ptr_sw_gpd = ptr_tx_pdma->pptr_sw_gpd_bulk[idx]; + ptr_tx_pdma->pptr_sw_gpd_bulk[idx] = NULL; + if (NULL != ptr_sw_gpd->callback) + { + ptr_sw_gpd->callback(unit, ptr_sw_gpd, ptr_sw_gpd->ptr_cookie); + } + } +} + + +/* FUNCTION NAME: _hal_tau_pkt_strictTxDeQueue + * PURPOSE: + * To dequeue the packets based on the strict algorithm. + * INPUT: + * unit -- The unit ID + * ptr_cookie -- Pointer of the TX cookie + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully dequeue the packets. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_strictTxDeQueue( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_TX_COOKIE_T *ptr_cookie) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + HAL_TAU_PKT_TX_CB_T *ptr_tx_cb = HAL_TAU_PKT_GET_TX_CB_PTR(unit); + HAL_TAU_PKT_TX_SW_GPD_T *ptr_sw_gpd = NULL; + NPS_ADDR_T sw_gpd_addr; + UI32_T que_cnt = 0; + + /* get queue count */ + _hal_tau_pkt_getQueueCount(&ptr_tx_cb->sw_queue, &que_cnt); + + /* wait txTask event */ + if (0 == que_cnt) + { + osal_waitEvent(&ptr_tx_cb->sync_sema); + if (FALSE == ptr_tx_cb->running) + { + return (NPS_E_OTHERS); /* deinit */ + } + + ptr_tx_cb->cnt.wait_event++; + + /* re-get queue count */ + _hal_tau_pkt_getQueueCount(&ptr_tx_cb->sw_queue, &que_cnt); + } + + /* deque */ + if (que_cnt > 0) + { + rc = _hal_tau_pkt_deQueue(&ptr_tx_cb->sw_queue, (void **)&ptr_sw_gpd); + if (NPS_E_OK == rc) + { + ptr_tx_cb->cnt.deque_ok++; + + sw_gpd_addr = (NPS_ADDR_T)ptr_sw_gpd->ptr_cookie; + + /* Give the address of pre-saved SW GPD back to userspace */ + osal_io_copyToUser(&ptr_cookie->done_sw_gpd_addr, + &sw_gpd_addr, + sizeof(NPS_ADDR_T)); + + /* free kernel sw_gpd */ + _hal_tau_pkt_freeTxGpdList(unit, ptr_sw_gpd); + } + else + { + ptr_tx_cb->cnt.deque_fail++; + } + } + else + { + /* It may happen at last gpd, return error and do not invoke callback. */ + rc = NPS_E_OTHERS; + } + + return (rc); +} + +/* FUNCTION NAME: _hal_tau_pkt_rxCheckReason + * PURPOSE: + * To check the packets to linux kernel/user. + * INPUT: + * ptr_rx_gpd -- Pointer of the RX GPD + * ptr_hit_prof -- Pointer of the hit flag + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully dispatch the packets. + * NOTES: + * Reference to pkt_srv. + */ +static void +_hal_tau_pkt_rxCheckReason( + volatile HAL_TAU_PKT_RX_GPD_T *ptr_rx_gpd, + HAL_TAU_PKT_NETIF_PROFILE_T *ptr_profile, + BOOL_T *ptr_hit_prof) +{ + HAL_TAU_PKT_RX_REASON_BITMAP_T *ptr_reason_bitmap = &ptr_profile->reason_bitmap; + UI32_T bitval = 0; + UI32_T bitmap = 0x0; + + if (0 == (ptr_profile->flags & HAL_TAU_PKT_NETIF_PROFILE_FLAGS_REASON)) + { + /* It means that reason doesn't metters */ + *ptr_hit_prof = TRUE; + return; + } + +#define HAL_TAU_PKT_DI_NON_L3_CPU_MIN (HAL_TAU_EXCPT_CPU_BASE_ID + HAL_TAU_EXCPT_CPU_NON_L3_MIN) +#define HAL_TAU_PKT_DI_NON_L3_CPU_MAX (HAL_TAU_EXCPT_CPU_BASE_ID + HAL_TAU_EXCPT_CPU_NON_L3_MAX) +#define HAL_TAU_PKT_DI_L3_CPU_MIN (HAL_TAU_EXCPT_CPU_BASE_ID + HAL_TAU_EXCPT_CPU_L3_MIN) +#define HAL_TAU_PKT_DI_L3_CPU_MAX (HAL_TAU_EXCPT_CPU_BASE_ID + HAL_TAU_EXCPT_CPU_L3_MAX) + + switch (ptr_rx_gpd->itmh_eth.typ) + { + case HAL_TAU_PKT_TMH_TYPE_ITMH_ETH: + + /* IPP non-L3 exception */ + if (ptr_rx_gpd->itmh_eth.dst_idx >= HAL_TAU_PKT_DI_NON_L3_CPU_MIN && + ptr_rx_gpd->itmh_eth.dst_idx <= HAL_TAU_PKT_DI_NON_L3_CPU_MAX) + { + bitval = ptr_rx_gpd->itmh_eth.dst_idx - HAL_TAU_PKT_DI_NON_L3_CPU_MIN; + bitmap = 1 << (bitval % 32); + if (0 != (ptr_reason_bitmap->ipp_excpt_bitmap[bitval / 32] & bitmap)) + { + *ptr_hit_prof = TRUE; + break; + } + } + + /* IPP L3 exception */ + if (ptr_rx_gpd->itmh_eth.dst_idx >= HAL_TAU_PKT_DI_L3_CPU_MIN && + ptr_rx_gpd->itmh_eth.dst_idx <= HAL_TAU_PKT_DI_L3_CPU_MAX) + { + bitmap = ptr_rx_gpd->itmh_eth.dst_idx - HAL_TAU_PKT_DI_L3_CPU_MIN; + if (0 != (ptr_reason_bitmap->ipp_l3_excpt_bitmap[0] & bitmap)) + { + *ptr_hit_prof = TRUE; + break; + } + } + + /* IPP cp_to_cpu_bmap */ + bitmap = ptr_rx_gpd->itmh_eth.cp_to_cpu_bmap; + if (0 != (ptr_reason_bitmap->ipp_copy2cpu_bitmap[0] & bitmap)) + { + *ptr_hit_prof = TRUE; + break; + } + + /* IPP cp_to_cpu_rsn */ + bitval = ptr_rx_gpd->itmh_eth.cp_to_cpu_code; + bitmap = 1 << (bitval % 32); + if (0 != (ptr_reason_bitmap->ipp_rsn_bitmap[bitval / 32] & bitmap)) + { + *ptr_hit_prof = TRUE; + break; + } + break; + + case HAL_TAU_PKT_TMH_TYPE_ITMH_FAB: + case HAL_TAU_PKT_TMH_TYPE_ETMH_FAB: + break; + + case HAL_TAU_PKT_TMH_TYPE_ETMH_ETH: + + /* EPP exception */ + if (1 == ptr_rx_gpd->etmh_eth.redir) + { + bitval = ptr_rx_gpd->etmh_eth.excpt_code_mir_bmap; + bitmap = 1 << (bitval % 32); + if (0 != (ptr_reason_bitmap->epp_excpt_bitmap[bitval / 32] & bitmap)) + { + *ptr_hit_prof = TRUE; + break; + } + } + + /* EPP cp_to_cpu_bmap */ + bitmap = ((ptr_rx_gpd->etmh_eth.cp_to_cpu_bmap_w0 << 7) | + (ptr_rx_gpd->etmh_eth.cp_to_cpu_bmap_w1)); + if (0 != (ptr_reason_bitmap->epp_copy2cpu_bitmap[0] & bitmap)) + { + *ptr_hit_prof = TRUE; + break; + } + break; + + default: + *ptr_hit_prof = FALSE; + break; + } +} + +static BOOL_T +_hal_tau_pkt_comparePatternWithPayload( + volatile HAL_TAU_PKT_RX_GPD_T *ptr_rx_gpd, + const UI8_T *ptr_pattern, + const UI8_T *ptr_mask, + const UI32_T offset) +{ + NPS_ADDR_T phy_addr = 0; + UI8_T *ptr_virt_addr = NULL; + UI32_T idx; + + /* Get the packet payload */ + phy_addr = NPS_ADDR_32_TO_64(ptr_rx_gpd->data_buf_addr_hi, ptr_rx_gpd->data_buf_addr_lo); + ptr_virt_addr = (C8_T *) osal_dma_convertPhyToVirt(phy_addr); + + for (idx=0; idxflags & (HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_0 | + HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_1 | + HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_2 | + HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_3)) != 0) + { + /* Need to compare the payload with at least one of the four patterns */ + /* Pre-assume that the result is positive */ + *ptr_hit_prof = TRUE; + + /* If any of the following comparison fails, the result will be changed to negtive */ + } + else + { + return; + } + + for (idx=0; idxflags & (HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_0 << idx))) + { + match = _hal_tau_pkt_comparePatternWithPayload(ptr_rx_gpd, + ptr_profile->pattern[idx], + ptr_profile->mask[idx], + ptr_profile->offset[idx]); + if (TRUE == match) + { + /* Do nothing */ + } + else + { + /* Change the result to negtive */ + *ptr_hit_prof = FALSE; + break; + } + } + } +} + +static void +_hal_tau_pkt_matchUserProfile( + volatile HAL_TAU_PKT_RX_GPD_T *ptr_rx_gpd, + HAL_TAU_PKT_PROFILE_NODE_T *ptr_profile_list, + BOOL_T *ptr_hit_prof) +{ + HAL_TAU_PKT_PROFILE_NODE_T *ptr_curr_node = ptr_profile_list; + + while (NULL != ptr_curr_node) + { + /* 1st match reason */ + _hal_tau_pkt_rxCheckReason(ptr_rx_gpd, ptr_curr_node->ptr_profile, ptr_hit_prof); + if (TRUE == *ptr_hit_prof) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, + "rx prof matched by reason\n"); + + /* Then, check pattern */ + _hal_tau_pkt_rxCheckPattern(ptr_rx_gpd, ptr_curr_node->ptr_profile, ptr_hit_prof); + if (TRUE == *ptr_hit_prof) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, + "rx prof matched by pattern\n"); + break; + } + } + + /* Seach the next profile (priority lower) */ + ptr_curr_node = ptr_curr_node->ptr_next_node; + } +} + +static void +_hal_tau_pkt_getPacketDest( + volatile HAL_TAU_PKT_RX_GPD_T *ptr_rx_gpd, + HAL_TAU_PKT_DEST_T *ptr_dest) +{ + BOOL_T hit_prof = FALSE; + UI32_T port; + HAL_TAU_PKT_PROFILE_NODE_T *ptr_profile_list; + + port = ptr_rx_gpd->itmh_eth.igr_phy_port; + ptr_profile_list = HAL_TAU_PKT_GET_PORT_PROFILE_LIST(port); + + _hal_tau_pkt_matchUserProfile(ptr_rx_gpd, ptr_profile_list, &hit_prof); + if (TRUE == hit_prof) + { + *ptr_dest = HAL_TAU_PKT_DEST_SDK; + } + else + { + *ptr_dest = HAL_TAU_PKT_DEST_NETDEV; + } +} + +/* FUNCTION NAME: _hal_tau_pkt_rxEnQueue + * PURPOSE: + * To enqueue the packets to multiple queues. + * INPUT: + * unit -- The unit ID + * channel -- The target channel + * ptr_sw_gpd -- Pointer for the SW Rx GPD link list + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully enqueue the packets. + * NOTES: + * None + */ +static void +_hal_tau_pkt_rxEnQueue( + const UI32_T unit, + const UI32_T channel, + HAL_TAU_PKT_RX_SW_GPD_T *ptr_sw_gpd) +{ + HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); + HAL_TAU_PKT_RX_SW_GPD_T *ptr_sw_first_gpd = ptr_sw_gpd; + void *ptr_virt_addr = NULL; + NPS_ADDR_T phy_addr = 0; + HAL_TAU_PKT_DEST_T pkt_dest; + + /* skb meta */ + UI32_T port = 0, len = 0, total_len = 0; + struct net_device *ptr_net_dev = NULL; + struct net_device_priv *ptr_priv = NULL; + struct sk_buff *ptr_skb = NULL, *ptr_merge_skb = NULL; + UI32_T copy_offset; + +#if defined(PERF_EN_TEST) + /* To verify kernel Rx performance */ + if (NPS_E_OK == perf_rxTest()) + { + while (NULL != ptr_sw_gpd) + { + len += (HAL_TAU_PKT_CH_LAST_GPD == ptr_sw_gpd->rx_gpd.ch)? + ptr_sw_gpd->rx_gpd.cnsm_buf_len : ptr_sw_gpd->rx_gpd.avbl_buf_len; + + total_len += len; + + /* unmap dma */ + phy_addr = NPS_ADDR_32_TO_64(ptr_sw_gpd->rx_gpd.data_buf_addr_hi, ptr_sw_gpd->rx_gpd.data_buf_addr_lo); + osal_skb_unmapDma(phy_addr, len, DMA_FROM_DEVICE); + /* next */ + ptr_sw_gpd = ptr_sw_gpd->ptr_next; + } + perf_rxCallback(total_len); + _hal_tau_pkt_freeRxGpdList(unit, ptr_sw_first_gpd, TRUE); + return ; + } +#endif + + _hal_tau_pkt_getPacketDest(&ptr_sw_gpd->rx_gpd, &pkt_dest); + if (HAL_TAU_PKT_DEST_NETDEV == pkt_dest) + { + ptr_sw_gpd = ptr_sw_first_gpd; + while (NULL != ptr_sw_gpd) + { + len = (HAL_TAU_PKT_CH_LAST_GPD == ptr_sw_gpd->rx_gpd.ch)? + ptr_sw_gpd->rx_gpd.cnsm_buf_len : ptr_sw_gpd->rx_gpd.avbl_buf_len; + + total_len += len; + + /* unmap dma */ + phy_addr = NPS_ADDR_32_TO_64(ptr_sw_gpd->rx_gpd.data_buf_addr_hi, ptr_sw_gpd->rx_gpd.data_buf_addr_lo); + ptr_virt_addr = ptr_sw_gpd->ptr_cookie; + + ptr_skb = (struct sk_buff *)ptr_virt_addr; + + /* note here ptr_skb->len is the total buffer size not means the actual Rx packet len + * it should be updated later + */ + osal_skb_unmapDma(phy_addr, ptr_skb->len, DMA_FROM_DEVICE); + + /* reset ptr_skb->len with real packet len instead of total buffer size */ + if (NULL == ptr_sw_gpd->ptr_next) + { + /* strip CRC padded by asic for the last gpd segment */ + ptr_skb->len = len - ETH_FCS_LEN; + } + else + { + ptr_skb->len = len; + } + + skb_set_tail_pointer(ptr_skb, ptr_skb->len); + + /* next */ + ptr_sw_gpd = ptr_sw_gpd->ptr_next; + } + + /* if the packet is composed of multiple gpd (skb), need to merge it into a single skb */ + if (NULL != ptr_sw_first_gpd->ptr_next) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_RX, + "u=%u, rxch=%u, rcv pkt size=%u > gpd buf size=%u\n", + unit, channel, total_len, ptr_rx_cb->buf_len); + ptr_merge_skb = osal_skb_alloc(total_len - ETH_FCS_LEN); + if (NULL != ptr_merge_skb) + { + copy_offset = 0; + ptr_sw_gpd = ptr_sw_first_gpd; + while (NULL != ptr_sw_gpd) + { + ptr_skb = (struct sk_buff *)ptr_sw_gpd->ptr_cookie; + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_RX, + "u=%u, rxch=%u, copy size=%u to buf offset=%u\n", + unit, channel, ptr_skb->len, copy_offset); + + memcpy(&(((UI8_T *)ptr_merge_skb->data)[copy_offset]), + ptr_skb->data, ptr_skb->len); + copy_offset += ptr_skb->len; + ptr_sw_gpd = ptr_sw_gpd->ptr_next; + } + /* put the merged skb to ptr_skb for the following process */ + ptr_skb = ptr_merge_skb; + } + else + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_RX), + "u=%u, rxch=%u, alloc skb failed, size=%u\n", + unit, channel, (total_len - ETH_FCS_LEN)); + } + + /* free both sw_gpd and the skb attached on it */ + _hal_tau_pkt_freeRxGpdList(unit, ptr_sw_first_gpd, TRUE); + } + else + { + /* free only sw_gpd */ + _hal_tau_pkt_freeRxGpdList(unit, ptr_sw_first_gpd, FALSE); + } + + /* get port and net_device */ + port = ptr_sw_first_gpd->rx_gpd.itmh_eth.igr_phy_port; + ptr_net_dev = HAL_TAU_PKT_GET_PORT_NETDEV(port); + + /* if NULL netdev, drop the skb */ + if (NULL == ptr_net_dev) + { + ptr_rx_cb->cnt.channel[channel].netdev_miss++; + osal_skb_free(ptr_skb); + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_RX), + "u=%u, rxch=%u, find netdev failed\n", + unit, channel); + return; + } + + /* skb handling */ + ptr_skb->dev = ptr_net_dev; + ptr_skb->pkt_type = PACKET_HOST; /* this packet is for me */ + ptr_skb->protocol = eth_type_trans(ptr_skb, ptr_net_dev); /* skip ethernet header */ + ptr_skb->ip_summed = CHECKSUM_UNNECESSARY; /* skip checksum */ + + /* send to linux */ + osal_skb_recv(ptr_skb); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) + ptr_net_dev->last_rx = jiffies; +#endif + ptr_priv = netdev_priv(ptr_net_dev); + ptr_priv->stats.rx_packets++; + ptr_priv->stats.rx_bytes += total_len; + } + else if (HAL_TAU_PKT_DEST_SDK == pkt_dest) + { + while (0 != _hal_tau_pkt_enQueue(&ptr_rx_cb->sw_queue[channel], ptr_sw_gpd)) + { + ptr_rx_cb->cnt.channel[channel].enque_retry++; + HAL_TAU_PKT_RX_ENQUE_RETRY_SLEEP(); + } + ptr_rx_cb->cnt.channel[channel].enque_ok++; + + osal_triggerEvent(&ptr_rx_cb->sync_sema); + ptr_rx_cb->cnt.channel[channel].trig_event++; + } + else if (HAL_TAU_PKT_DEST_DROP == pkt_dest) + { + _hal_tau_pkt_freeRxGpdList(unit, ptr_sw_first_gpd, TRUE); + } + else + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_RX), + "u=%u, rxch=%u, invalid pkt dest=%d\n", + unit, channel, pkt_dest); + } +} + +/* FUNCTION NAME: _hal_tau_pkt_schedRxDeQueue + * PURPOSE: + * To dequeue the packets based on the configured algorithm. + * INPUT: + * unit -- The unit ID + * ptr_cookie -- Pointer of the RX cookie + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully dequeue the packets. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_schedRxDeQueue( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_RX_COOKIE_T *ptr_cookie) +{ + HAL_TAU_PKT_IOCTL_RX_COOKIE_T ioctl_data; + HAL_TAU_PKT_IOCTL_RX_GPD_T ioctl_gpd; + HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); + HAL_TAU_PKT_RX_SW_GPD_T *ptr_sw_gpd_knl = NULL; + HAL_TAU_PKT_RX_SW_GPD_T *ptr_sw_first_gpd_knl = NULL; + UI32_T que_cnt = 0; + UI32_T queue = 0; + UI32_T idx = 0; + UI32_T gpd_idx = 0; + /* copy Rx sw_gpd */ + volatile HAL_TAU_PKT_RX_GPD_T *ptr_rx_gpd = NULL; + void *ptr_virt_addr = NULL; + NPS_ADDR_T phy_addr = 0; + UI32_T buf_len = 0; + NPS_ERROR_NO_T rc = NPS_E_OK; + + /* get queue and count */ + for (idx = 0; idx < HAL_TAU_PKT_RX_QUEUE_NUM; idx++) + { + /* to gurantee the opportunity where each queue can be handler */ + queue = ((ptr_rx_cb->deque_idx + idx) % HAL_TAU_PKT_RX_QUEUE_NUM); + _hal_tau_pkt_getQueueCount(&ptr_rx_cb->sw_queue[queue], &que_cnt); + if (que_cnt > 0) + { + ptr_rx_cb->deque_idx = ((queue + 1) % HAL_TAU_PKT_RX_QUEUE_NUM); + break; + } + } + + /* If all of the queues are empty, wait rxTask event */ + if (0 == que_cnt) + { + osal_waitEvent(&ptr_rx_cb->sync_sema); + if (FALSE == ptr_rx_cb->running) + { + return (NPS_E_OTHERS); /* deinit */ + } + + ptr_rx_cb->cnt.wait_event++; + + /* re-get queue and count */ + for (queue = 0; queue < HAL_TAU_PKT_RX_QUEUE_NUM; queue++) + { + _hal_tau_pkt_getQueueCount(&ptr_rx_cb->sw_queue[queue], &que_cnt); + if (que_cnt > 0) + { + ptr_rx_cb->deque_idx = ((queue + 1) % HAL_TAU_PKT_RX_QUEUE_NUM); + break; + } + } + } + + /* deque */ + if ((que_cnt > 0) && (queue < HAL_TAU_PKT_RX_QUEUE_NUM)) + { + rc = _hal_tau_pkt_deQueue(&ptr_rx_cb->sw_queue[queue], (void **)&ptr_sw_gpd_knl); + if (NPS_E_OK == rc) + { + ptr_rx_cb->cnt.channel[queue].deque_ok++; + ptr_sw_first_gpd_knl = ptr_sw_gpd_knl; + + osal_io_copyFromUser(&ioctl_data, ptr_cookie, sizeof(HAL_TAU_PKT_IOCTL_RX_COOKIE_T)); + + while (NULL != ptr_sw_gpd_knl) + { + /* get the IOCTL GPD from user */ + osal_io_copyFromUser(&ioctl_gpd, + ((void *)((NPS_HUGE_T)ioctl_data.ioctl_gpd_addr)) + + gpd_idx*sizeof(HAL_TAU_PKT_IOCTL_RX_GPD_T), + sizeof(HAL_TAU_PKT_IOCTL_RX_GPD_T)); + + /* get knl buf addr */ + ptr_rx_gpd = &ptr_sw_gpd_knl->rx_gpd; + phy_addr = NPS_ADDR_32_TO_64(ptr_rx_gpd->data_buf_addr_hi, ptr_rx_gpd->data_buf_addr_lo); + + ptr_virt_addr = ptr_sw_gpd_knl->ptr_cookie; + osal_skb_unmapDma(phy_addr, ((struct sk_buff *)ptr_virt_addr)->len, DMA_FROM_DEVICE); + + buf_len = (HAL_TAU_PKT_CH_LAST_GPD == ptr_rx_gpd->ch)? + ptr_rx_gpd->cnsm_buf_len : ptr_rx_gpd->avbl_buf_len; + + /* overwrite whole rx_gpd to user + * the user should re-assign the correct value to data_buf_addr_hi, data_buf_addr_low + * after this IOCTL returns + */ + osal_io_copyToUser((void *)((NPS_HUGE_T)ioctl_gpd.hw_gpd_addr), + &ptr_sw_gpd_knl->rx_gpd, + sizeof(HAL_TAU_PKT_RX_GPD_T)); + /* copy buf */ + /* DMA buf address allocated by the user is store in ptr_ioctl_data->gpd[idx].cookie */ + osal_io_copyToUser((void *)((NPS_HUGE_T)ioctl_gpd.dma_buf_addr), + ((struct sk_buff *)ptr_virt_addr)->data, buf_len); + ptr_sw_gpd_knl->ptr_cookie = ptr_virt_addr; + + /* next */ + ptr_sw_gpd_knl = ptr_sw_gpd_knl->ptr_next; + gpd_idx++; + } + + /* Must free kernel sw_gpd */ + _hal_tau_pkt_freeRxGpdList(unit, ptr_sw_first_gpd_knl, TRUE); + } + else + { + ptr_rx_cb->cnt.channel[queue].deque_fail++; + } + } + else + { + /* It may happen at last gpd, return error and do not invoke callback. */ + rc = NPS_E_OTHERS; + } + + return (rc); +} + +/* FUNCTION NAME: _hal_tau_pkt_waitTxDone + * PURPOSE: + * To determine the next action after transfer the packet to HW. + * INPUT: + * unit -- The unit ID + * channel -- The target TX channel + * ptr_sw_gpd -- Pointer for the SW Tx GPD link list + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully perform the target action. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_waitTxDone( + const UI32_T unit, + const HAL_TAU_PKT_TX_CHANNEL_T channel, + HAL_TAU_PKT_TX_SW_GPD_T *ptr_sw_gpd) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + HAL_TAU_PKT_TX_CB_T *ptr_tx_cb = HAL_TAU_PKT_GET_TX_CB_PTR(unit); + HAL_TAU_PKT_TX_PDMA_T *ptr_tx_pdma = HAL_TAU_PKT_GET_TX_PDMA_PTR(unit, channel); + volatile HAL_TAU_PKT_TX_GPD_T *ptr_tx_gpd = NULL; + UI32_T last_gpd_idx = 0; + UI32_T loop_cnt = 0; + + if (HAL_TAU_PKT_TX_WAIT_ASYNC == ptr_tx_cb->wait_mode) + { + ; + } + else if (HAL_TAU_PKT_TX_WAIT_SYNC_INTR == ptr_tx_cb->wait_mode) + { + osal_takeSemaphore(&ptr_tx_pdma->sync_intr_sema, HAL_TAU_PKT_PDMA_TX_INTR_TIMEOUT); + /* rc = _hal_tau_pkt_invokeTxGpdCallback(unit, ptr_sw_gpd); */ + } + else if (HAL_TAU_PKT_TX_WAIT_SYNC_POLL == ptr_tx_cb->wait_mode) + { + last_gpd_idx = ptr_tx_pdma->free_idx + ptr_tx_pdma->used_gpd_num; + last_gpd_idx %= ptr_tx_pdma->gpd_num; + ptr_tx_gpd = HAL_TAU_PKT_GET_TX_GPD_PTR(unit, channel, last_gpd_idx); + + while (HAL_TAU_PKT_HWO_HW_OWN == ptr_tx_gpd->hwo) + { + osal_dma_invalidateCache((void *)ptr_tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); + loop_cnt++; + if (0 == loop_cnt % HAL_TAU_PKT_PDMA_TX_POLL_MAX_LOOP) + { + ptr_tx_cb->cnt.channel[channel].poll_timeout++; + rc = NPS_E_OTHERS; + break; + } + } + if (HAL_TAU_PKT_ECC_ERROR_OCCUR == ptr_tx_gpd->ecce) + { + ptr_tx_cb->cnt.channel[channel].ecc_err++; + } + if (NPS_E_OK == rc) + { + ptr_tx_pdma->free_gpd_num += ptr_tx_pdma->used_gpd_num; + ptr_tx_pdma->used_gpd_num = 0; + ptr_tx_pdma->free_idx = ptr_tx_pdma->used_idx; + /* rc = _hal_tau_pkt_invokeTxGpdCallback(unit, ptr_sw_gpd); */ + } + } + + return (rc); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_resumeAllIntf( + const UI32_T unit) +{ + struct net_device *ptr_net_dev = NULL; + UI32_T port; + + /* Unregister net devices by id */ + for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) + { + ptr_net_dev = HAL_TAU_PKT_GET_PORT_NETDEV(port); + if (NULL != ptr_net_dev) + { + if (netif_queue_stopped(ptr_net_dev)) + { + netif_wake_queue(ptr_net_dev); + } + } + } + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_suspendAllIntf( + const UI32_T unit) +{ + struct net_device *ptr_net_dev = NULL; + UI32_T port; + + /* Unregister net devices by id */ + for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) + { + ptr_net_dev = HAL_TAU_PKT_GET_PORT_NETDEV(port); + if (NULL != ptr_net_dev) + { + netif_stop_queue(ptr_net_dev); + } + } + + return (NPS_E_OK); +} + +/* FUNCTION NAME: hal_tau_pkt_sendGpd + * PURPOSE: + * To perform the packet transmission form CPU to the switch. + * INPUT: + * unit -- The unit ID + * channel -- The target TX channel + * ptr_sw_gpd -- Pointer for the SW Tx GPD link list + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully perform the transferring. + * NOTES: + * None + */ +NPS_ERROR_NO_T +hal_tau_pkt_sendGpd( + const UI32_T unit, + const HAL_TAU_PKT_TX_CHANNEL_T channel, + HAL_TAU_PKT_TX_SW_GPD_T *ptr_sw_gpd) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + HAL_TAU_PKT_TX_CB_T *ptr_tx_cb = HAL_TAU_PKT_GET_TX_CB_PTR(unit); + HAL_TAU_PKT_TX_PDMA_T *ptr_tx_pdma = HAL_TAU_PKT_GET_TX_PDMA_PTR(unit, channel); + volatile HAL_TAU_PKT_TX_GPD_T *ptr_tx_gpd = NULL; + HAL_TAU_PKT_TX_SW_GPD_T *ptr_sw_first_gpd = ptr_sw_gpd; + + UI32_T used_idx = 0; + UI32_T used_gpd_num = ptr_sw_gpd->gpd_num; + NPS_IRQ_FLAGS_T irq_flags; + + osal_takeIsrLock(&ptr_tx_pdma->ring_lock, &irq_flags); + + /* If not PDMA error */ + if (FALSE == ptr_tx_pdma->err_flag) + { + /* Make Sure GPD is enough */ + if (ptr_tx_pdma->free_gpd_num >= used_gpd_num) + { + used_idx = ptr_tx_pdma->used_idx; + while (NULL != ptr_sw_gpd) + { + ptr_tx_gpd = HAL_TAU_PKT_GET_TX_GPD_PTR(unit, channel, used_idx); + osal_dma_invalidateCache((void *)ptr_tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); + + if (HAL_TAU_PKT_HWO_HW_OWN == ptr_tx_gpd->hwo) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), + "u=%u, txch=%u, free gpd idx out-of-sync\n", + unit, channel); + rc = NPS_E_TABLE_FULL; + break; + } + + /* Fill in HW-GPD Ring */ + osal_memcpy((void *)ptr_tx_gpd, &ptr_sw_gpd->tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); + osal_dma_flushCache((void *)ptr_tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); + + /* next */ + used_idx++; + used_idx %= ptr_tx_pdma->gpd_num; + ptr_sw_gpd = ptr_sw_gpd->ptr_next; + } + + if (HAL_TAU_PKT_TX_WAIT_ASYNC == ptr_tx_cb->wait_mode) + { + /* Fill 1st GPD in SW-GPD Ring */ + ptr_tx_pdma->pptr_sw_gpd_ring[ptr_tx_pdma->used_idx] = ptr_sw_first_gpd; + } + + /* update Tx PDMA */ + ptr_tx_pdma->used_idx = used_idx; + ptr_tx_pdma->used_gpd_num += used_gpd_num; + ptr_tx_pdma->free_gpd_num -= used_gpd_num; + + _hal_tau_pkt_resumeTxChannelReg(unit, channel, used_gpd_num); + ptr_tx_cb->cnt.channel[channel].send_ok++; + + _hal_tau_pkt_waitTxDone(unit, channel, ptr_sw_first_gpd); + + /* reserve 1 packet buffer for each port in case that the suspension is too late */ +#define HAL_TAU_PKT_KNL_TX_RING_AVBL_GPD_LOW (HAL_TAU_PORT_NUM) + if (ptr_tx_pdma->free_gpd_num < HAL_TAU_PKT_KNL_TX_RING_AVBL_GPD_LOW) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_TX, + "u=%u, txch=%u, tx avbl gpd < %d, suspend all netdev\n", + unit, channel, HAL_TAU_PKT_KNL_TX_RING_AVBL_GPD_LOW); + _hal_tau_pkt_suspendAllIntf(unit); + } + } + else + { + rc = NPS_E_TABLE_FULL; + } + } + else + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), + "u=%u, txch=%u, pdma hw err\n", + unit, channel); + rc = NPS_E_OTHERS; + } + + osal_giveIsrLock(&ptr_tx_pdma->ring_lock, &irq_flags); + + return (rc); +} + +/* ----------------------------------------------------------------------------------- pkt_srv */ +/* ----------------------------------------------------------------------------------- Rx Init */ +static NPS_ERROR_NO_T +_hal_tau_pkt_rxStop( + const UI32_T unit) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + HAL_TAU_PKT_RX_CHANNEL_T channel = 0; + HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); + HAL_TAU_PKT_DRV_CB_T *ptr_cb = HAL_TAU_PKT_GET_DRV_CB_PTR(unit); + HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma = NULL; + + /* Check if Rx is already stopped*/ + if (0 == (ptr_cb->init_flag & HAL_TAU_PKT_INIT_RX_START)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_RX | HAL_TAU_PKT_DBG_ERR), + "u=%u, rx stop failed, not started\n", unit); + return (NPS_E_OK); + } + + /* Check if PKT Drv/Task were de-init before stopping Rx */ + /* Currently, we help to stop Rx when deinit Drv/Task, so it shouldn't enter below logic */ + if ((0 == (ptr_cb->init_flag & HAL_TAU_PKT_INIT_TASK)) || + (0 == (ptr_cb->init_flag & HAL_TAU_PKT_INIT_DRV))) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_RX | HAL_TAU_PKT_DBG_ERR), + "u=%u, rx stop failed, pkt task & pkt drv not init\n", unit); + return (NPS_E_OK); + } + + /* Deinit Rx PDMA and free buf for Rx GPD */ + for (channel = 0; channel < HAL_TAU_PKT_RX_CHANNEL_LAST; channel++) + { + ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, channel); + + osal_takeSemaphore(&ptr_rx_pdma->sema, NPS_SEMAPHORE_WAIT_FOREVER); + _hal_tau_pkt_stopRxChannelReg(unit, channel); + rc = _hal_tau_pkt_deinitRxPdmaRingBuf(unit, channel); + osal_giveSemaphore(&ptr_rx_pdma->sema); + } + + /* Return user thread */ + ptr_rx_cb->running = FALSE; + ptr_cb->init_flag &= (~HAL_TAU_PKT_INIT_RX_START); + + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_RX, + "u=%u, rx stop done, init flag=0x%x\n", unit, ptr_cb->init_flag); + + osal_triggerEvent(&ptr_rx_cb->sync_sema); + + return (rc); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_rxStart( + const UI32_T unit) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + HAL_TAU_PKT_RX_CHANNEL_T channel = 0; + HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); + HAL_TAU_PKT_DRV_CB_T *ptr_cb = HAL_TAU_PKT_GET_DRV_CB_PTR(unit); + HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma = NULL; + + if (0 != (ptr_cb->init_flag & HAL_TAU_PKT_INIT_RX_START)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_RX | HAL_TAU_PKT_DBG_ERR), + "u=%u, rx start failed, already started\n", unit); + return (NPS_E_OK); + } + + /* init Rx PDMA and alloc buf for Rx GPD */ + for (channel = 0; channel < HAL_TAU_PKT_RX_CHANNEL_LAST; channel++) + { + ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, channel); + + osal_takeSemaphore(&ptr_rx_pdma->sema, NPS_SEMAPHORE_WAIT_FOREVER); + rc = _hal_tau_pkt_initRxPdmaRingBuf(unit, channel); + if (NPS_E_OK == rc) + { + ptr_rx_pdma->cur_idx = 0; + _hal_tau_pkt_startRxChannelReg(unit, channel, ptr_rx_pdma->gpd_num); + } + osal_giveSemaphore(&ptr_rx_pdma->sema); + } + + /* enable to dequeue rx packets */ + ptr_rx_cb->running = TRUE; + + /* set the flag to record init state */ + ptr_cb->init_flag |= HAL_TAU_PKT_INIT_RX_START; + + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_RX, + "u=%u, rx start done, init flag=0x%x\n", unit, ptr_cb->init_flag); + return (rc); +} + +/* FUNCTION NAME: hal_tau_pkt_setRxKnlConfig + * PURPOSE: + * 1. To stop the Rx channel and deinit the Rx subsystem. + * 2. To init the Rx subsystem and start the Rx channel. + * 3. To restart the Rx subsystem + * INPUT: + * unit -- The unit ID + * ptr_cookie -- Pointer of the RX cookie + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully configure the RX parameters. + * NPS_E_OTHERS -- Configure the parameter failed. + * NOTES: + * + */ +NPS_ERROR_NO_T +hal_tau_pkt_setRxKnlConfig( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_RX_COOKIE_T *ptr_cookie) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); + HAL_TAU_PKT_DRV_CB_T *ptr_cb = HAL_TAU_PKT_GET_DRV_CB_PTR(unit); + HAL_TAU_PKT_IOCTL_RX_TYPE_T rx_type = HAL_TAU_PKT_IOCTL_RX_TYPE_LAST; + + osal_io_copyFromUser(&rx_type, &ptr_cookie->rx_type, sizeof(HAL_TAU_PKT_IOCTL_RX_TYPE_T)); + + if (HAL_TAU_PKT_IOCTL_RX_TYPE_DEINIT == rx_type) + { + _hal_tau_pkt_rxStop(unit); + } + if (HAL_TAU_PKT_IOCTL_RX_TYPE_INIT == rx_type) + { + /* To prevent buffer size from being on-the-fly changed */ + if (0 != (ptr_cb->init_flag & HAL_TAU_PKT_INIT_RX_START)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_RX | HAL_TAU_PKT_DBG_ERR), + "u=%u, rx stop failed, not started\n", unit); + return (NPS_E_OK); + } + + osal_io_copyFromUser(&ptr_rx_cb->buf_len, &ptr_cookie->buf_len, sizeof(UI32_T)); + _hal_tau_pkt_rxStart(unit); + } + + return (rc); +} + +/* FUNCTION NAME: hal_tau_pkt_getRxKnlConfig + * PURPOSE: + * To get the Rx subsystem configuration. + * INPUT: + * unit -- The unit ID + * ptr_cookie -- Pointer of the RX cookie + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully configure the RX parameters. + * NPS_E_OTHERS -- Configure the parameter failed. + * NOTES: + * + */ +NPS_ERROR_NO_T +hal_tau_pkt_getRxKnlConfig( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_RX_COOKIE_T *ptr_cookie) +{ + HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); + + osal_io_copyToUser(&ptr_cookie->buf_len, &ptr_rx_cb->buf_len, sizeof(UI32_T)); + + return (NPS_E_OK); +} + +/* ----------------------------------------------------------------------------------- Deinit */ +/* FUNCTION NAME: hal_tau_pkt_deinitTask + * PURPOSE: + * To de-initialize the Task for packet module. + * INPUT: + * unit -- The unit ID + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully dinitialize the control block. + * NPS_E_OTHERS -- Initialize the control block failed. + * NOTES: + * None + */ +NPS_ERROR_NO_T +hal_tau_pkt_deinitTask( + const UI32_T unit) +{ + HAL_TAU_PKT_DRV_CB_T *ptr_cb = HAL_TAU_PKT_GET_DRV_CB_PTR(unit); + HAL_TAU_PKT_TX_CB_T *ptr_tx_cb = HAL_TAU_PKT_GET_TX_CB_PTR(unit); + HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); + UI32_T channel = 0; + + if (0 == (ptr_cb->init_flag & HAL_TAU_PKT_INIT_TASK)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_RX | HAL_TAU_PKT_DBG_ERR), + "u=%u, rx stop failed, not started\n", unit); + return (NPS_E_OK); + } + + /* Need to stop Rx before de-init Task */ + if (0 != (ptr_cb->init_flag & HAL_TAU_PKT_INIT_RX_START)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_RX | HAL_TAU_PKT_DBG_ERR), + "u=%u, pkt task deinit failed, rx not stop\n", unit); + + _hal_tau_pkt_rxStop(unit); + } + + /* Make the Rx IOCTL from userspace return back*/ + osal_triggerEvent(&ptr_rx_cb->sync_sema); + + /* Destroy txTask */ + if (HAL_TAU_PKT_TX_WAIT_ASYNC == ptr_tx_cb->wait_mode) + { + ptr_tx_cb->running = FALSE; + osal_triggerEvent(&ptr_tx_cb->sync_sema); + } + + /* Destroy handleRxDoneTask */ + for (channel = 0; channel < HAL_TAU_PKT_RX_CHANNEL_LAST; channel++) + { + osal_stopThread(&ptr_rx_cb->isr_task_id[channel]); + osal_triggerEvent(HAL_TAU_PKT_RCH_EVENT(unit, channel)); + osal_destroyThread(&ptr_rx_cb->isr_task_id[channel]); + } + + /* Destroy handleTxDoneTask */ + for (channel = 0; channel < HAL_TAU_PKT_TX_CHANNEL_LAST; channel++) + { + osal_stopThread(&ptr_tx_cb->isr_task_id[channel]); + osal_triggerEvent(HAL_TAU_PKT_TCH_EVENT(unit, channel)); + osal_destroyThread(&ptr_tx_cb->isr_task_id[channel]); + } + + /* Destroy handleErrorTask */ + osal_stopThread(&ptr_cb->err_task_id); + osal_triggerEvent(HAL_TAU_PKT_ERR_EVENT(unit)); + osal_destroyThread(&ptr_cb->err_task_id); + + /* Set the flag to record init state */ + ptr_cb->init_flag &= (~HAL_TAU_PKT_INIT_TASK); + + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_RX, + "u=%u, pkt task deinit done, init flag=0x%x\n", + unit, ptr_cb->init_flag); + + return (NPS_E_OK); +} + +/* FUNCTION NAME: _hal_tau_pkt_deinitTxPdma + * PURPOSE: + * To de-initialize the Tx PDMA configuration of the specified channel. + * INPUT: + * unit -- The unit ID + * channel -- The target Tx channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully de-init the Tx PDMA. + * NPS_E_OTHERS -- De-init the Tx PDMA failed. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_deinitTxPdma( + const UI32_T unit, + const HAL_TAU_PKT_TX_CHANNEL_T channel) +{ + HAL_TAU_PKT_TX_CB_T *ptr_tx_cb = HAL_TAU_PKT_GET_TX_CB_PTR(unit); + HAL_TAU_PKT_TX_PDMA_T *ptr_tx_pdma = HAL_TAU_PKT_GET_TX_PDMA_PTR(unit, channel); + NPS_IRQ_FLAGS_T irg_flags; + + _hal_tau_pkt_stopTxChannelReg(unit, channel); + + /* Free DMA and flush queue */ + osal_takeIsrLock(&ptr_tx_pdma->ring_lock, &irg_flags); + + osal_dma_free(ptr_tx_pdma->ptr_gpd_start_addr); + + if (HAL_TAU_PKT_TX_WAIT_ASYNC == ptr_tx_cb->wait_mode) + { + osal_free(ptr_tx_pdma->pptr_sw_gpd_ring); + osal_free(ptr_tx_pdma->pptr_sw_gpd_bulk); + } + else if (HAL_TAU_PKT_TX_WAIT_SYNC_INTR == ptr_tx_cb->wait_mode) + { + osal_destroySemaphore(&ptr_tx_pdma->sync_intr_sema); + } + + osal_giveIsrLock(&ptr_tx_pdma->ring_lock, &irg_flags); + + osal_destroyIsrLock(&ptr_tx_pdma->ring_lock); + + return (NPS_E_OK); +} + +/* FUNCTION NAME: _hal_tau_pkt_deinitRxPdma + * PURPOSE: + * To de-initialize the Rx PDMA configuration of the specified channel. + * INPUT: + * unit -- The unit ID + * channel -- The target Rx channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully de-init the Rx PDMA. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_deinitRxPdma( + const UI32_T unit, + const HAL_TAU_PKT_RX_CHANNEL_T channel) +{ + HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, channel); + + /* Free DMA */ + osal_takeSemaphore(&ptr_rx_pdma->sema, NPS_SEMAPHORE_WAIT_FOREVER); + osal_dma_free(ptr_rx_pdma->ptr_gpd_start_addr); + osal_giveSemaphore(&ptr_rx_pdma->sema); + osal_destroySemaphore(&ptr_rx_pdma->sema); + + return (NPS_E_OK); +} + +/* FUNCTION NAME: _hal_tau_pkt_deinitPktCb + * PURPOSE: + * To de-init the control block of Drv. + * INPUT: + * unit -- The unit ID + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully de-init the control block. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_deinitPktCb( + const UI32_T unit) +{ + HAL_TAU_PKT_DRV_CB_T *ptr_cb = HAL_TAU_PKT_GET_DRV_CB_PTR(unit); + UI32_T idx = 0, vec = sizeof(_hal_tau_pkt_intr_vec) / sizeof(HAL_TAU_PKT_INTR_VEC_T); + + for (idx = 0; idx < vec; idx++) + { + osal_destroyEvent(&_hal_tau_pkt_intr_vec[idx].intr_event); + ptr_cb->intr_bitmap &= ~(_hal_tau_pkt_intr_vec[idx].intr_reg); + } + + /* Unregister PKT interrupt functions */ + osal_mdc_registerIsr(unit, NULL, NULL); + osal_destroyIsrLock(&ptr_cb->intr_lock); + + return (NPS_E_OK); +} + +/* FUNCTION NAME: _hal_tau_pkt_deinitPktTxCb + * PURPOSE: + * To de-init the control block of Tx PDMA. + * INPUT: + * unit -- The unit ID + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully de-init the control block. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_deinitPktTxCb( + const UI32_T unit) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + HAL_TAU_PKT_TX_CB_T *ptr_tx_cb = HAL_TAU_PKT_GET_TX_CB_PTR(unit); + HAL_TAU_PKT_TX_CHANNEL_T channel = 0; + + /* Deinitialize TX PDMA sub-system.*/ + for (channel = 0; channel < HAL_TAU_PKT_TX_CHANNEL_LAST; channel++) + { + _hal_tau_pkt_deinitTxPdma(unit, channel); + } + + if (HAL_TAU_PKT_TX_WAIT_ASYNC == ptr_tx_cb->wait_mode) + { + /* Destroy the sync semaphore of txTask */ + osal_destroyEvent(&ptr_tx_cb->sync_sema); + + /* Deinitialize Tx GPD-queue (of first SW-GPD) from handleTxDoneTask to txTask */ + osal_destroySemaphore(&ptr_tx_cb->sw_queue.sema); + osal_que_destroy(&ptr_tx_cb->sw_queue.que_id); + } + + return (rc); +} + +/* FUNCTION NAME: _hal_tau_pkt_deinitPktRxCb + * PURPOSE: + * To de-init the control block of Rx PDMA. + * INPUT: + * unit -- The unit ID + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully de-init the control block. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_deinitPktRxCb( + const UI32_T unit) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); + HAL_TAU_PKT_RX_CHANNEL_T channel = 0; + UI32_T queue = 0; + + /* Deinitialize RX PDMA sub-system */ + for (channel = 0; channel < HAL_TAU_PKT_RX_CHANNEL_LAST; channel++) + { + _hal_tau_pkt_deinitRxPdma(unit, channel); + } + + /* Destroy the sync semaphore of rxTask */ + osal_destroyEvent(&ptr_rx_cb->sync_sema); + + /* Deinitialize Rx GPD-queue (of first SW-GPD) from handleRxDoneTask to rxTask */ + for (queue = 0; queue < HAL_TAU_PKT_RX_QUEUE_NUM; queue++) + { + osal_destroySemaphore(&ptr_rx_cb->sw_queue[queue].sema); + osal_que_destroy(&ptr_rx_cb->sw_queue[queue].que_id); + } + + return (rc); +} + +/* FUNCTION NAME: _hal_tau_pkt_deinitL1Isr + * PURPOSE: + * To de-initialize the PDMA L1 ISR configuration. + * INPUT: + * unit -- The unit ID + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully de-initialize for the L1 ISR. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_deinitL1Isr( + const UI32_T unit) +{ + UI32_T idx = 0, vec = sizeof(_hal_tau_pkt_intr_vec) / sizeof(HAL_TAU_PKT_INTR_VEC_T); + + for (idx = 0; idx < vec; idx++) + { + _hal_tau_pkt_maskIntr(unit, _hal_tau_pkt_intr_vec[idx].intr_reg); + _hal_tau_pkt_disableIntr(unit, _hal_tau_pkt_intr_vec[idx].intr_reg); + } + + return (NPS_E_OK); +} + +/* FUNCTION NAME: _hal_tau_pkt_deinitL2Isr + * PURPOSE: + * To initialize the PDMA L2 ISR configuration. + * INPUT: + * unit -- The unit ID + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully configure for the L2 ISR. + * NPS_E_OTHERS -- Configure failed. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_deinitL2Isr( + const UI32_T unit) +{ + HAL_TAU_PKT_L2_ISR_T isr_status = 0x0; + + HAL_TAU_PKT_SET_BITMAP(isr_status, HAL_TAU_PKT_L2_ISR_RCH0); + HAL_TAU_PKT_SET_BITMAP(isr_status, HAL_TAU_PKT_L2_ISR_RCH1); + HAL_TAU_PKT_SET_BITMAP(isr_status, HAL_TAU_PKT_L2_ISR_RCH2); + HAL_TAU_PKT_SET_BITMAP(isr_status, HAL_TAU_PKT_L2_ISR_RCH3); + HAL_TAU_PKT_SET_BITMAP(isr_status, HAL_TAU_PKT_L2_ISR_TCH0); + HAL_TAU_PKT_SET_BITMAP(isr_status, HAL_TAU_PKT_L2_ISR_TCH1); + HAL_TAU_PKT_SET_BITMAP(isr_status, HAL_TAU_PKT_L2_ISR_TCH2); + HAL_TAU_PKT_SET_BITMAP(isr_status, HAL_TAU_PKT_L2_ISR_TCH3); + HAL_TAU_PKT_SET_BITMAP(isr_status, HAL_TAU_PKT_L2_ISR_RX_QID_MAP_ERR); + HAL_TAU_PKT_SET_BITMAP(isr_status, HAL_TAU_PKT_L2_ISR_RX_FRAME_ERR); + + osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_ERR_INT_MASK_SET), + &isr_status, sizeof(UI32_T)); + + isr_status = 0x0; + osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_ERR_INT_EN), + &isr_status, sizeof(UI32_T)); + + return (NPS_E_OK); +} + +/* FUNCTION NAME: hal_tau_pkt_deinitPktDrv + * PURPOSE: + * To invoke the functions to de-initialize the control block for each + * PDMA subsystem. + * INPUT: + * unit -- The unit ID + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully de-initialize the control blocks. + * NPS_E_OTHERS -- De-initialize the control blocks failed. + * NOTES: + * None + */ +NPS_ERROR_NO_T +hal_tau_pkt_deinitPktDrv( + const UI32_T unit) +{ + HAL_TAU_PKT_DRV_CB_T *ptr_cb = HAL_TAU_PKT_GET_DRV_CB_PTR(unit); + NPS_ERROR_NO_T rc = NPS_E_OK; + + if (0 == (ptr_cb->init_flag & HAL_TAU_PKT_INIT_DRV)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_RX | HAL_TAU_PKT_DBG_ERR), + "u=%u, pkt drv deinit failed, not inited\n", unit); + return (NPS_E_OK); + } + + rc = _hal_tau_pkt_deinitL2Isr(unit); + + if (NPS_E_OK == rc) + { + rc = _hal_tau_pkt_deinitL1Isr(unit); + } + if (NPS_E_OK == rc) + { + rc = _hal_tau_pkt_deinitPktRxCb(unit); + } + if (NPS_E_OK == rc) + { + rc = _hal_tau_pkt_deinitPktTxCb(unit); + } + if (NPS_E_OK == rc) + { + rc = _hal_tau_pkt_deinitPktCb(unit); + } + + ptr_cb->init_flag &= (~HAL_TAU_PKT_INIT_DRV); + + + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_COMMON, + "u=%u, pkt drv deinit done, init flag=0x%x\n", + unit, ptr_cb->init_flag); + return (rc); +} + +/* ----------------------------------------------------------------------------------- Init */ +/* FUNCTION NAME: _hal_tau_pkt_handleTxErrStat + * PURPOSE: + * To handle the TX flow control ISR. + * INPUT: + * unit -- The unit ID + * channel -- The target channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully handle the interrpt. + * NOTES: + * + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_handleTxErrStat( + const UI32_T unit, + const HAL_TAU_PKT_TX_CHANNEL_T channel) +{ + HAL_TAU_PKT_TX_CB_T *ptr_tx_cb = HAL_TAU_PKT_GET_TX_CB_PTR(unit); + HAL_TAU_PKT_TX_PDMA_T *ptr_tx_pdma = HAL_TAU_PKT_GET_TX_PDMA_PTR(unit, channel); + NPS_IRQ_FLAGS_T irg_flags; + + if (HAL_TAU_PKT_TX_WAIT_SYNC_INTR == ptr_tx_cb->wait_mode) + { + /* Notify the TX process to make it release the channel semaphore. */ + osal_giveSemaphore(&ptr_tx_pdma->sync_intr_sema); + } + + /* Set the error flag. */ + + osal_takeIsrLock(&ptr_tx_pdma->ring_lock, &irg_flags); + ptr_tx_pdma->err_flag = TRUE; + osal_giveIsrLock(&ptr_tx_pdma->ring_lock, &irg_flags); + + osal_triggerEvent(HAL_TAU_PKT_TCH_EVENT(unit, channel)); + + return (NPS_E_OK); +} + +/* FUNCTION NAME: _hal_tau_pkt_handleRxErrStat + * PURPOSE: + * To handle the error which occurs in RX channels. + * INPUT: + * unit -- The unit ID + * channel -- The channel where the error occurs + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully handle the error situation. + * NOTES: + * + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_handleRxErrStat( + const UI32_T unit, + const HAL_TAU_PKT_RX_CHANNEL_T channel) +{ + HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, channel); + + /* Set the error flag. */ + osal_takeSemaphore(&ptr_rx_pdma->sema, NPS_SEMAPHORE_WAIT_FOREVER); + ptr_rx_pdma->err_flag = TRUE; + osal_giveSemaphore(&ptr_rx_pdma->sema); + + osal_triggerEvent(HAL_TAU_PKT_RCH_EVENT(unit, channel)); + + return (NPS_E_OK); +} + +/* FUNCTION NAME: _hal_tau_pkt_handleTxL2Isr + * PURPOSE: + * To handle the TX L2 interrupt according to the ISR status. + * INPUT: + * unit -- The unit ID + * channel -- The channel where the interrupt occurs + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully handle the L2 interrupt. + * NOTES: + * + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_handleTxL2Isr( + const UI32_T unit, + const HAL_TAU_PKT_TX_CHANNEL_T channel) +{ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_T isr_status = 0x0; + HAL_TAU_PKT_TX_CB_T *ptr_tx_cb = HAL_TAU_PKT_GET_TX_CB_PTR(unit); + + osal_mdc_readPciReg(unit, + HAL_TAU_PKT_GET_PDMA_TCH_REG(HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_TCH_INT_STAT), channel), + &isr_status, sizeof(isr_status)); + + _hal_tau_pkt_maskAllTxL2IsrReg(unit, channel); + + if (0 != (isr_status & HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_HWO_ERROR)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), + "u=%u, txch=%u, pdma gpd hwo err\n", unit, channel); + _hal_tau_pkt_clearTxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_HWO_ERROR); + ptr_tx_cb->cnt.channel[channel].gpd_hwo_err++; + _hal_tau_pkt_handleTxErrStat(unit, channel); + } + if (0 != (isr_status & HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), + "u=%u, txch=%u, pdma gpd chksum err\n", unit, channel); + _hal_tau_pkt_clearTxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR); + ptr_tx_cb->cnt.channel[channel].gpd_chksm_err++; + _hal_tau_pkt_handleTxErrStat(unit, channel); + } + if (0 != (isr_status & HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_NO_OVFL_ERROR)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), + "u=%u, txch=%u, pdma gpd num overflow err\n", unit, channel); + _hal_tau_pkt_clearTxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_NO_OVFL_ERROR); + ptr_tx_cb->cnt.channel[channel].gpd_no_ovfl_err++; + _hal_tau_pkt_handleTxErrStat(unit, channel); + } + if (0 != (isr_status & HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_DMA_READ_ERROR)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), + "u=%u, txch=%u, pdma gpd dma read err\n", unit, channel); + _hal_tau_pkt_clearTxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_DMA_READ_ERROR); + ptr_tx_cb->cnt.channel[channel].gpd_dma_read_err++; + _hal_tau_pkt_handleTxErrStat(unit, channel); + } + if (0 != (isr_status & HAL_TAU_PKT_TX_CHANNEL_L2_ISR_BUF_SIZE_ERROR)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), + "u=%u, txch=%u, pdma buf size err\n", unit, channel); + _hal_tau_pkt_clearTxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_TX_CHANNEL_L2_ISR_BUF_SIZE_ERROR); + ptr_tx_cb->cnt.channel[channel].buf_size_err++; + _hal_tau_pkt_handleTxErrStat(unit, channel); + } + if (0 != (isr_status & HAL_TAU_PKT_TX_CHANNEL_L2_ISR_RUNT_ERROR)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_TX, + "u=%u, txch=%u, pdma pkt runt\n", unit, channel); + _hal_tau_pkt_clearTxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_TX_CHANNEL_L2_ISR_RUNT_ERROR); + ptr_tx_cb->cnt.channel[channel].runt_err++; + } + if (0 != (isr_status & HAL_TAU_PKT_TX_CHANNEL_L2_ISR_OVSZ_ERROR)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_TX, + "u=%u, txch=%u, pdma pkt over size\n", unit, channel);; + _hal_tau_pkt_clearTxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_TX_CHANNEL_L2_ISR_OVSZ_ERROR); + ptr_tx_cb->cnt.channel[channel].ovsz_err++; + } + if (0 != (isr_status & HAL_TAU_PKT_TX_CHANNEL_L2_ISR_LEN_MISMATCH_ERROR)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), + "u=%u, txch=%u, pdma len mismatch err\n", unit, channel); + _hal_tau_pkt_clearTxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_TX_CHANNEL_L2_ISR_LEN_MISMATCH_ERROR); + ptr_tx_cb->cnt.channel[channel].len_mismatch_err++; + } + if (0 != (isr_status & HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PKTPL_DMA_READ_ERROR)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), + "u=%u, txch=%u, pdma pkt buf dma read err\n", unit, channel); + _hal_tau_pkt_clearTxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PKTPL_DMA_READ_ERROR); + ptr_tx_cb->cnt.channel[channel].pktpl_dma_read_err++; + _hal_tau_pkt_handleTxErrStat(unit, channel); + } + if (0 != (isr_status & HAL_TAU_PKT_TX_CHANNEL_L2_ISR_COS_ERROR)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), + "u=%u, txch=%u, pdma tx cos err\n", unit, channel); + _hal_tau_pkt_clearTxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_TX_CHANNEL_L2_ISR_COS_ERROR); + ptr_tx_cb->cnt.channel[channel].cos_err++; + } + if (0 != (isr_status & HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_GT255_ERROR)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), + "u=%u, txch=%u, pdma gpd num > 255 err\n", unit, channel); + _hal_tau_pkt_clearTxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_GT255_ERROR); + ptr_tx_cb->cnt.channel[channel].gpd_gt255_err++; + _hal_tau_pkt_handleTxErrStat(unit, channel); + } + if (0 != (isr_status & HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PFC)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_TX, + "u=%u, txch=%u, pdma flow ctrl\n", unit, channel); + _hal_tau_pkt_clearTxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PFC); + ptr_tx_cb->cnt.channel[channel].pfc++; + } + if (0 != (isr_status & HAL_TAU_PKT_TX_CHANNEL_L2_ISR_CREDIT_UDFL_ERROR)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), + "u=%u, txch=%u, pdma credit underflow err\n", unit, channel); + _hal_tau_pkt_clearTxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_TX_CHANNEL_L2_ISR_CREDIT_UDFL_ERROR); + ptr_tx_cb->cnt.channel[channel].credit_udfl_err++; + _hal_tau_pkt_handleTxErrStat(unit, channel); + } + if (0 != (isr_status & HAL_TAU_PKT_TX_CHANNEL_L2_ISR_DMA_WRITE_ERROR)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), + "u=%u, txch=%u, pdma dma write err\n", unit, channel); + _hal_tau_pkt_clearTxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_TX_CHANNEL_L2_ISR_DMA_WRITE_ERROR); + ptr_tx_cb->cnt.channel[channel].dma_write_err++; + _hal_tau_pkt_handleTxErrStat(unit, channel); + } + if (0 != (isr_status & HAL_TAU_PKT_TX_CHANNEL_L2_ISR_STOP_CMD_CPLT)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_TX, + "u=%u, txch=%u, pdma stop done\n", unit, channel); + _hal_tau_pkt_clearTxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_TX_CHANNEL_L2_ISR_STOP_CMD_CPLT); + ptr_tx_cb->cnt.channel[channel].sw_issue_stop++; + } + if (0 != isr_status) + { + _hal_tau_pkt_unmaskAllTxL2IsrReg(unit, channel); + } + + return (NPS_E_OK); +} + +/* FUNCTION NAME: _hal_tau_pkt_handleRxL2Isr + * PURPOSE: + * To handle the RX L2 interrupt according to the ISR status. + * INPUT: + * unit -- The unit ID + * channel -- The channel where the interrupt occurs + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully handle the L2 interrupt. + * NOTES: + * + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_handleRxL2Isr( + const UI32_T unit, + const HAL_TAU_PKT_RX_CHANNEL_T channel) +{ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_T isr_status = 0x0; + HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); + + osal_mdc_readPciReg(unit, + HAL_TAU_PKT_GET_PDMA_RCH_REG(HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_RCH_INT_STAT), channel), + &isr_status, sizeof(isr_status)); + + _hal_tau_pkt_maskAllRxL2IsrReg(unit, channel); + + if (0 != (isr_status & HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_LOW)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_RX, + "u=%u, rxch=%u, pdma avbl gpd low\n", unit, channel); + _hal_tau_pkt_clearRxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_LOW); + ptr_rx_cb->cnt.channel[channel].avbl_gpd_low++; + } + if (0 != (isr_status & HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_EMPTY)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_RX, + "u=%u, rxch=%u, pdma avbl gpd empty\n", unit, channel); + _hal_tau_pkt_clearRxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_EMPTY); + ptr_rx_cb->cnt.channel[channel].avbl_gpd_empty++; + } + if (0 != (isr_status & HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_ERROR)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_RX), + "u=%u, rxch=%u, pdma avbl gpd err\n", unit, channel); + _hal_tau_pkt_clearRxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_ERROR); + ptr_rx_cb->cnt.channel[channel].avbl_gpd_err++; + _hal_tau_pkt_handleRxErrStat(unit, channel); + } + if (0 != (isr_status & HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_RX), + "u=%u, rxch=%u, pdma gpd chksum err\n", unit, channel); + _hal_tau_pkt_clearRxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR); + ptr_rx_cb->cnt.channel[channel].gpd_chksm_err++; + _hal_tau_pkt_handleRxErrStat(unit, channel); + } + if (0 != (isr_status & HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_READ_ERROR)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_RX), + "u=%u, rxch=%u, pdma dma read err\n", unit, channel); + _hal_tau_pkt_clearRxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_READ_ERROR); + ptr_rx_cb->cnt.channel[channel].dma_read_err++; + _hal_tau_pkt_handleRxErrStat(unit, channel); + } + if (0 != (isr_status & HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_WRITE_ERROR)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_RX), + "u=%u, rxch=%u, pdma dma write err\n", unit, channel); + _hal_tau_pkt_clearRxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_WRITE_ERROR); + ptr_rx_cb->cnt.channel[channel].dma_write_err++; + _hal_tau_pkt_handleRxErrStat(unit, channel); + } + if (0 != (isr_status & HAL_TAU_PKT_RX_CHANNEL_L2_ISR_STOP_CMD_CPLT)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_RX, + "u=%u, rxch=%u, pdma stop done\n", unit, channel); + _hal_tau_pkt_clearRxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_RX_CHANNEL_L2_ISR_STOP_CMD_CPLT); + ptr_rx_cb->cnt.channel[channel].sw_issue_stop++; + } + if (0 != (isr_status & HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_GT255_ERROR)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_RX), + "u=%u, rxch=%u, pdma gpd num > 255 err\n", unit, channel); + _hal_tau_pkt_clearRxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_GT255_ERROR); + ptr_rx_cb->cnt.channel[channel].gpd_gt255_err++; + _hal_tau_pkt_handleRxErrStat(unit, channel); + } + if (0 != (isr_status & HAL_TAU_PKT_RX_CHANNEL_L2_ISR_TOD_UNINIT)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_RX), + "u=%u, rxch=%u, pdma tod ununit err\n", unit, channel); + _hal_tau_pkt_clearRxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_RX_CHANNEL_L2_ISR_TOD_UNINIT); + ptr_rx_cb->cnt.channel[channel].tod_uninit++; + _hal_tau_pkt_handleRxErrStat(unit, channel); + } + if (0 != (isr_status & HAL_TAU_PKT_RX_CHANNEL_L2_ISR_PKT_ERROR_DROP)) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_RX), + "u=%u, rxch=%u, pdma pkt err drop\n", unit, channel); + _hal_tau_pkt_clearRxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_RX_CHANNEL_L2_ISR_PKT_ERROR_DROP); + ptr_rx_cb->cnt.channel[channel].pkt_err_drop++; + } + if (0 != (isr_status & HAL_TAU_PKT_RX_CHANNEL_L2_ISR_UDSZ_DROP)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_RX, + "u=%u, rxch=%u, pdma pkt under size\n", unit, channel); + _hal_tau_pkt_clearRxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_RX_CHANNEL_L2_ISR_UDSZ_DROP); + ptr_rx_cb->cnt.channel[channel].udsz_drop++; + } + if (0 != (isr_status & HAL_TAU_PKT_RX_CHANNEL_L2_ISR_OVSZ_DROP)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_RX, + "u=%u, rxch=%u, pdma pkt over size\n", unit, channel); + _hal_tau_pkt_clearRxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_RX_CHANNEL_L2_ISR_OVSZ_DROP); + ptr_rx_cb->cnt.channel[channel].ovsz_drop++; + } + if (0 != (isr_status & HAL_TAU_PKT_RX_CHANNEL_L2_ISR_CMDQ_OVF_DROP)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_RX, + "u=%u, rxch=%u, pdma cmdq overflow\n", unit, channel); + _hal_tau_pkt_clearRxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_RX_CHANNEL_L2_ISR_CMDQ_OVF_DROP); + ptr_rx_cb->cnt.channel[channel].cmdq_ovf_drop++; + } + if (0 != (isr_status & HAL_TAU_PKT_RX_CHANNEL_L2_ISR_FIFO_OVF_DROP)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_RX, + "u=%u, rxch=%u, pdma fifo overflow\n", unit, channel); + _hal_tau_pkt_clearRxL2IsrStatusReg(unit, channel, HAL_TAU_PKT_RX_CHANNEL_L2_ISR_FIFO_OVF_DROP); + ptr_rx_cb->cnt.channel[channel].fifo_ovf_drop++; + } + if (0 != isr_status) + { + _hal_tau_pkt_unmaskAllRxL2IsrReg(unit, channel); + } + + return (NPS_E_OK); +} + +/* FUNCTION NAME: _hal_tau_pkt_handleErrorTask + * PURPOSE: + * To invoke the corresponding handler for the L2 interrupts. + * INPUT: + * ptr_argv -- The unit ID + * OUTPUT: + * None + * RETURN: + * None + * NOTES: + * None + */ +static void +_hal_tau_pkt_handleErrorTask( + void *ptr_argv) +{ + UI32_T unit = (UI32_T)((NPS_HUGE_T)ptr_argv); + HAL_TAU_PKT_L2_ISR_T isr_status = 0x0; + + osal_initRunThread(); + do + { + /* receive Error-ISR */ + osal_waitEvent(HAL_TAU_PKT_ERR_EVENT(unit)); + if (NPS_E_OK != osal_isRunThread()) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_COMMON, + "u=%u, err task destroyed\n", unit); + break; /* deinit-thread */ + } + + osal_mdc_readPciReg(unit, + HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_ERR_INT_STAT), + &isr_status, sizeof(UI32_T)); + + if (0 != (HAL_TAU_PKT_L2_ISR_RCH0 & isr_status)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_COMMON, "u=%u, rxch=0, rcv err isr, status=0x%x\n", + unit, isr_status); + _hal_tau_pkt_handleRxL2Isr(unit, HAL_TAU_PKT_RX_CHANNEL_0); + } + if (0 != (HAL_TAU_PKT_L2_ISR_RCH1 & isr_status)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_COMMON, "u=%u, rxch=1, rcv err isr, status=0x%x\n", + unit, isr_status); + _hal_tau_pkt_handleRxL2Isr(unit, HAL_TAU_PKT_RX_CHANNEL_1); + } + if (0 != (HAL_TAU_PKT_L2_ISR_RCH2 & isr_status)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_COMMON, "u=%u, rxch=2, rcv err isr, status=0x%x\n", + unit, isr_status); + _hal_tau_pkt_handleRxL2Isr(unit, HAL_TAU_PKT_RX_CHANNEL_2); + } + if (0 != (HAL_TAU_PKT_L2_ISR_RCH3 & isr_status)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_COMMON, "u=%u, rxch=3, rcv err isr, status=0x%x\n", + unit, isr_status); + _hal_tau_pkt_handleRxL2Isr(unit, HAL_TAU_PKT_RX_CHANNEL_3); + } + if (0 != (HAL_TAU_PKT_L2_ISR_TCH0 & isr_status)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_COMMON, "u=%u, txch=0, rcv err isr, status=0x%x\n", + unit, isr_status); + _hal_tau_pkt_handleTxL2Isr(unit, HAL_TAU_PKT_TX_CHANNEL_0); + } + if (0 != (HAL_TAU_PKT_L2_ISR_TCH1 & isr_status)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_COMMON, "u=%u, txch=1, rcv err isr, status=0x%x\n", + unit, isr_status); + _hal_tau_pkt_handleTxL2Isr(unit, HAL_TAU_PKT_TX_CHANNEL_1); + } + if (0 != (HAL_TAU_PKT_L2_ISR_TCH2 & isr_status)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_COMMON, "u=%u, txch=2, rcv err isr, status=0x%x\n", + unit, isr_status); + _hal_tau_pkt_handleTxL2Isr(unit, HAL_TAU_PKT_TX_CHANNEL_2); + } + if (0 != (HAL_TAU_PKT_L2_ISR_TCH3 & isr_status)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_COMMON, "u=%u, txch=3, rcv err isr, status=0x%x\n", + unit, isr_status); + _hal_tau_pkt_handleTxL2Isr(unit, HAL_TAU_PKT_TX_CHANNEL_3); + } + if (0 != (HAL_TAU_PKT_L2_ISR_RX_QID_MAP_ERR & isr_status)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_COMMON, "u=%u, rcv rx qid map err isr, status=0x%x\n", + unit, isr_status); + } + if (0 != (HAL_TAU_PKT_L2_ISR_RX_FRAME_ERR & isr_status)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_COMMON, "u=%u, rcv rx frame err isr, status=0x%x\n", + unit, isr_status); + } + if (0 != isr_status) + { + osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_ERR_INT_CLR), + &isr_status, sizeof(UI32_T)); + + _hal_tau_pkt_unmaskIntr(unit, HAL_TAU_PKT_ERR_REG(unit)); + } + + } while (NPS_E_OK == osal_isRunThread()); + osal_exitRunThread(); +} + +/* FUNCTION NAME: _hal_tau_pkt_handleTxDoneTask + * PURPOSE: + * To handle the TX done interrupt for the specified TX channel. + * INPUT: + * ptr_argv -- The unit ID and channel ID + * OUTPUT: + * None + * RETURN: + * None + * NOTES: + * None + */ +static void +_hal_tau_pkt_handleTxDoneTask( + void *ptr_argv) +{ + /* cookie or index */ + UI32_T unit = ((HAL_TAU_PKT_ISR_COOKIE_T *)ptr_argv)->unit; + HAL_TAU_PKT_TX_CHANNEL_T channel = (HAL_TAU_PKT_TX_CHANNEL_T) + ((HAL_TAU_PKT_ISR_COOKIE_T *)ptr_argv)->channel; + /* control block */ + HAL_TAU_PKT_TX_CB_T *ptr_tx_cb = HAL_TAU_PKT_GET_TX_CB_PTR(unit); + HAL_TAU_PKT_TX_PDMA_T *ptr_tx_pdma = HAL_TAU_PKT_GET_TX_PDMA_PTR(unit, channel); + volatile HAL_TAU_PKT_TX_GPD_T *ptr_tx_gpd = NULL; + UI32_T first_gpd_idx = 0; /* To record the first GPD */ + UI32_T loop_cnt = 0; + NPS_IRQ_FLAGS_T irg_flags; + unsigned long timeout = 0; + UI32_T bulk_pkt_cnt = 0, idx; + + osal_initRunThread(); + do + { + /* receive Tx-Done-ISR */ + osal_waitEvent(HAL_TAU_PKT_TCH_EVENT(unit, channel)); + if (NPS_E_OK != osal_isRunThread()) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_TX, + "u=%u, txch=%u, tx done task destroyed\n", unit, channel); + break; /* deinit-thread */ + } + + /* protect Tx PDMA + * for sync-intr, the sema is locked by sendGpd + */ + if (HAL_TAU_PKT_TX_WAIT_SYNC_INTR != ptr_tx_cb->wait_mode) + { + osal_takeIsrLock(&ptr_tx_pdma->ring_lock, &irg_flags); + } + + loop_cnt = ptr_tx_pdma->used_gpd_num; + while (loop_cnt > 0) + { + ptr_tx_gpd = HAL_TAU_PKT_GET_TX_GPD_PTR(unit, channel, ptr_tx_pdma->free_idx); + osal_dma_invalidateCache((void *)ptr_tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); + + /* If hwo=HW, it might be: + * 1. err_flag=TRUE -> HW breakdown -> enque and recover -> break + * 2. err_flag=FALSE -> HW busy -> break + */ + if (HAL_TAU_PKT_HWO_HW_OWN == ptr_tx_gpd->hwo) + { + if (TRUE == ptr_tx_pdma->err_flag) + { + /* flush the incomplete Tx packet */ + if (HAL_TAU_PKT_TX_WAIT_ASYNC == ptr_tx_cb->wait_mode) + { + for (idx = 0; idx < ptr_tx_pdma->gpd_num; idx++) + { + if (NULL != ptr_tx_pdma->pptr_sw_gpd_ring[idx]) + { + ptr_tx_pdma->pptr_sw_gpd_bulk[bulk_pkt_cnt] + = ptr_tx_pdma->pptr_sw_gpd_ring[idx]; + ptr_tx_pdma->pptr_sw_gpd_ring[idx] = NULL; + bulk_pkt_cnt++; + } + } + } + + /* do error recover */ + first_gpd_idx = 0; + if (NPS_E_OK == _hal_tau_pkt_recoverTxPdma(unit, channel)) + { + ptr_tx_pdma->err_flag = FALSE; + ptr_tx_cb->cnt.channel[channel].err_recover++; + } + else + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_TX | HAL_TAU_PKT_DBG_ERR), + "u=%u, txch=%u, err recover failed\n", + unit, channel); + } + } + else + { + } + break; + } + + if (HAL_TAU_PKT_TX_WAIT_ASYNC == ptr_tx_cb->wait_mode) + { + /* If hwo=SW and ch=0, record the head of sw gpd in bulk buf */ + if (HAL_TAU_PKT_CH_LAST_GPD == ptr_tx_gpd->ch) + { + ptr_tx_pdma->pptr_sw_gpd_bulk[bulk_pkt_cnt] + = ptr_tx_pdma->pptr_sw_gpd_ring[first_gpd_idx]; + + bulk_pkt_cnt++; + ptr_tx_pdma->pptr_sw_gpd_ring[first_gpd_idx] = NULL; + + /* next SW-GPD must be the head of another PKT->SW-GPD */ + first_gpd_idx = ptr_tx_pdma->free_idx + 1; + first_gpd_idx %= ptr_tx_pdma->gpd_num; + } + } + + if (HAL_TAU_PKT_ECC_ERROR_OCCUR == ptr_tx_gpd->ecce) + { + ptr_tx_cb->cnt.channel[channel].ecc_err++; + } + + /* update Tx PDMA */ + ptr_tx_pdma->free_idx++; + ptr_tx_pdma->free_idx %= ptr_tx_pdma->gpd_num; + ptr_tx_pdma->used_gpd_num--; + ptr_tx_pdma->free_gpd_num++; + loop_cnt--; + } + + /* let the netdev resume Tx */ + _hal_tau_pkt_resumeAllIntf(unit); + + /* update ISR and counter */ + ptr_tx_cb->cnt.channel[channel].tx_done++; + + _hal_tau_pkt_unmaskIntr(unit, HAL_TAU_PKT_TCH_REG(unit, channel)); + + if (HAL_TAU_PKT_TX_WAIT_SYNC_INTR != ptr_tx_cb->wait_mode) + { + osal_giveIsrLock(&ptr_tx_pdma->ring_lock, &irg_flags); + } + else + { + osal_giveSemaphore(&ptr_tx_pdma->sync_intr_sema); + } + + /* enque packet after releasing the spinlock */ + _hal_tau_pkt_txEnQueueBulk(unit, channel, bulk_pkt_cnt); + bulk_pkt_cnt = 0; + + /* prevent this task from executing too long */ + if (!(time_before(jiffies, timeout))) + { + schedule(); + timeout = jiffies + 1; /* continuously free tx descriptor for 1 tick */ + } + + } while (NPS_E_OK == osal_isRunThread()); + osal_exitRunThread(); +} + +/* FUNCTION NAME: _hal_tau_pkt_handleRxDoneTask + * PURPOSE: + * To handle the RX done interrupt for the specified RX channel. + * INPUT: + * ptr_argv -- The unit ID and channel ID + * OUTPUT: + * None + * RETURN: + * None + * NOTES: + * None + */ +static void +_hal_tau_pkt_handleRxDoneTask( + void *ptr_argv) +{ + /* cookie or index */ + UI32_T unit = ((HAL_TAU_PKT_ISR_COOKIE_T *)ptr_argv)->unit; + HAL_TAU_PKT_RX_CHANNEL_T channel = (HAL_TAU_PKT_RX_CHANNEL_T) + ((HAL_TAU_PKT_ISR_COOKIE_T *)ptr_argv)->channel; + + /* control block */ + HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); + HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, channel); + volatile HAL_TAU_PKT_RX_GPD_T *ptr_rx_gpd = NULL; + + BOOL_T first = TRUE; + BOOL_T last = FALSE; + HAL_TAU_PKT_RX_SW_GPD_T *ptr_sw_gpd = NULL; + HAL_TAU_PKT_RX_SW_GPD_T *ptr_sw_first_gpd = NULL; + UI32_T loop_cnt = 0; + unsigned long timeout = 0; + + osal_initRunThread(); + do + { + /* receive Rx-Done-ISR */ + osal_waitEvent(HAL_TAU_PKT_RCH_EVENT(unit, channel)); + if (NPS_E_OK != osal_isRunThread()) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_RX, + "u=%u, rxch=%u, rx done task destroyed\n", unit, channel); + break; /* deinit-thread */ + } + + /* check if Rx-system is inited */ + if (0 == ptr_rx_cb->buf_len) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_RX | HAL_TAU_PKT_DBG_ERR), + "u=%u, rxch=%u, rx gpd buf len=0\n", + unit, channel); + continue; + } + + /* protect Rx PDMA */ + osal_takeSemaphore(&ptr_rx_pdma->sema, NPS_SEMAPHORE_WAIT_FOREVER); + loop_cnt = ptr_rx_pdma->gpd_num; + while (loop_cnt > 0) + { + ptr_rx_gpd = HAL_TAU_PKT_GET_RX_GPD_PTR(unit, channel, ptr_rx_pdma->cur_idx); + osal_dma_invalidateCache((void *)ptr_rx_gpd, sizeof(HAL_TAU_PKT_RX_GPD_T)); + + /* If hwo=HW, it might be: + * 1. err_flag=TRUE -> HW breakdown -> enque and recover -> break + * 2. err_flag=FALSE -> HW busy -> break + */ + if (HAL_TAU_PKT_HWO_HW_OWN == ptr_rx_gpd->hwo) + { + if (TRUE == ptr_rx_pdma->err_flag) + { + /* free the last incomplete Rx packet */ + if ((NULL != ptr_sw_first_gpd) && + (NULL != ptr_sw_gpd)) + { + ptr_sw_gpd->ptr_next = NULL; + ptr_sw_first_gpd->rx_complete = FALSE; + _hal_tau_pkt_rxEnQueue(unit, channel, ptr_sw_first_gpd); + } + + /* do error recover */ + first = TRUE; + last = FALSE; + if (NPS_E_OK == _hal_tau_pkt_recoverRxPdma(unit, channel)) + { + ptr_rx_pdma->err_flag = FALSE; + ptr_rx_cb->cnt.channel[channel].err_recover++; + } + else + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_RX | HAL_TAU_PKT_DBG_ERR), + "u=%u, rxch=%u, err recover failed\n", + unit, channel); + } + } + else + { + } + break; + } + + /* Move HW-GPD to SW-GPD and append to a link-list */ + if (TRUE == first) + { + ptr_sw_first_gpd = (HAL_TAU_PKT_RX_SW_GPD_T *)osal_alloc(sizeof(HAL_TAU_PKT_RX_SW_GPD_T)); + ptr_sw_gpd = ptr_sw_first_gpd; + if (NULL != ptr_sw_gpd) + { + memcpy(&ptr_sw_gpd->rx_gpd, (void *)ptr_rx_gpd, sizeof(HAL_TAU_PKT_RX_GPD_T)); + first = FALSE; + } + else + { + ptr_rx_cb->cnt.no_memory++; + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_RX | HAL_TAU_PKT_DBG_ERR), + "u=%u, rxch=%u, alloc 1st sw gpd failed, size=%d\n", + unit, channel, sizeof(HAL_TAU_PKT_RX_SW_GPD_T)); + break; + } + } + else + { + ptr_sw_gpd->ptr_next = (HAL_TAU_PKT_RX_SW_GPD_T *)osal_alloc(sizeof(HAL_TAU_PKT_RX_SW_GPD_T)); + ptr_sw_gpd = ptr_sw_gpd->ptr_next; + if (NULL != ptr_sw_gpd) + { + memcpy(&ptr_sw_gpd->rx_gpd, (void *)ptr_rx_gpd, sizeof(HAL_TAU_PKT_RX_GPD_T)); + } + else + { + ptr_rx_cb->cnt.no_memory++; + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_RX | HAL_TAU_PKT_DBG_ERR), + "u=%u, rxch=%u, alloc mid sw gpd failed, size=%d\n", + unit, channel, sizeof(HAL_TAU_PKT_RX_SW_GPD_T)); + break; + } + } + + ptr_sw_gpd->ptr_cookie = ptr_rx_pdma->pptr_skb_ring[ptr_rx_pdma->cur_idx]; + + /* If hwo=SW and ch=0, enque SW-GPD and signal rxTask */ + if (HAL_TAU_PKT_CH_LAST_GPD == ptr_rx_gpd->ch) + { + last = TRUE; + } + + /* If hwo=SW and ch=*, re-alloc-buf and resume */ + while (NPS_E_OK != _hal_tau_pkt_allocRxPayloadBuf(unit, channel, ptr_rx_pdma->cur_idx)) + { + ptr_rx_cb->cnt.no_memory++; + HAL_TAU_PKT_ALLOC_MEM_RETRY_SLEEP(); + } + ptr_rx_gpd->ioc = HAL_TAU_PKT_IOC_HAS_INTR; + ptr_rx_gpd->hwo = HAL_TAU_PKT_HWO_HW_OWN; + osal_dma_flushCache((void *)ptr_rx_gpd, sizeof(HAL_TAU_PKT_RX_GPD_T)); + + /* Enque the SW-GPD to rxTask */ + if (TRUE == last) + { + ptr_sw_gpd->ptr_next = NULL; + ptr_sw_first_gpd->rx_complete = TRUE; + _hal_tau_pkt_rxEnQueue(unit, channel, ptr_sw_first_gpd); + + /* To rebuild the SW GPD link list */ + first = TRUE; + last = FALSE; + } + + _hal_tau_pkt_resumeRxChannelReg(unit, channel, 1); + + /* update Rx PDMA */ + ptr_rx_pdma->cur_idx++; + ptr_rx_pdma->cur_idx %= ptr_rx_pdma->gpd_num; + loop_cnt--; + } + + osal_giveSemaphore(&ptr_rx_pdma->sema); + + /* update ISR and counter */ + ptr_rx_cb->cnt.channel[channel].rx_done++; + + _hal_tau_pkt_unmaskIntr(unit, HAL_TAU_PKT_RCH_REG(unit, channel)); + + /* prevent this task from executing too long */ + if (!(time_before(jiffies, timeout))) + { + schedule(); + timeout = jiffies + 1; /* continuously rx for 1 tick */ + } + + } while (NPS_E_OK == osal_isRunThread()); + osal_exitRunThread(); +} + +static void +_hal_tau_pkt_net_dev_tx_callback( + const UI32_T unit, + HAL_TAU_PKT_TX_SW_GPD_T *ptr_sw_gpd, + struct sk_buff *ptr_skb) +{ + NPS_ADDR_T phy_addr = 0; + + /* unmap dma */ + phy_addr = NPS_ADDR_32_TO_64(ptr_sw_gpd->tx_gpd.data_buf_addr_hi, ptr_sw_gpd->tx_gpd.data_buf_addr_lo); + osal_skb_unmapDma(phy_addr, ptr_skb->len, DMA_TO_DEVICE); + + /* free skb */ + osal_skb_free(ptr_skb); + + /* free gpd */ + osal_free(ptr_sw_gpd); +} + +/* FUNCTION NAME: hal_tau_pkt_initTask + * PURPOSE: + * To initialize the Task for packet module. + * INPUT: + * unit -- The unit ID + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully dinitialize the control block. + * NPS_E_OTHERS -- Initialize the control block failed. + * NOTES: + * None + */ +NPS_ERROR_NO_T +hal_tau_pkt_initTask( + const UI32_T unit) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + HAL_TAU_PKT_DRV_CB_T *ptr_cb = HAL_TAU_PKT_GET_DRV_CB_PTR(unit); + HAL_TAU_PKT_TX_CB_T *ptr_tx_cb = HAL_TAU_PKT_GET_TX_CB_PTR(unit); + HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); + UI32_T channel = 0; + + if (0 != (ptr_cb->init_flag & HAL_TAU_PKT_INIT_TASK)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_ERR, + "u=%u, pkt task init failed, not inited\n", unit); + return (rc); + } + + /* Init handleErrorTask */ + rc = osal_createThread("ERROR", HAL_TAU_PKT_ERROR_ISR_STACK_SIZE, + HAL_TAU_PKT_ERROR_ISR_THREAD_PRI, _hal_tau_pkt_handleErrorTask, + (void *)((NPS_HUGE_T)unit), &ptr_cb->err_task_id); + + /* Init handleTxDoneTask */ + for (channel = 0; ((channel < HAL_TAU_PKT_TX_CHANNEL_LAST) && (NPS_E_OK == rc)); channel++) + { + ptr_tx_cb->isr_task_cookie[channel].unit = unit; + ptr_tx_cb->isr_task_cookie[channel].channel = channel; + + rc = osal_createThread("TX_ISR", HAL_TAU_PKT_TX_ISR_STACK_SIZE, + HAL_TAU_PKT_TX_ISR_THREAD_PRI, _hal_tau_pkt_handleTxDoneTask, + (void *)&ptr_tx_cb->isr_task_cookie[channel], + &ptr_tx_cb->isr_task_id[channel]); + } + + /* Init handleRxDoneTask */ + for (channel = 0; ((channel < HAL_TAU_PKT_RX_CHANNEL_LAST) && (NPS_E_OK == rc)); channel++) + { + ptr_rx_cb->isr_task_cookie[channel].unit = unit; + ptr_rx_cb->isr_task_cookie[channel].channel = channel; + + rc = osal_createThread("RX_ISR", HAL_TAU_PKT_RX_ISR_STACK_SIZE, + HAL_TAU_PKT_RX_ISR_THREAD_PRI, _hal_tau_pkt_handleRxDoneTask, + (void *)&ptr_rx_cb->isr_task_cookie[channel], + &ptr_rx_cb->isr_task_id[channel]); + } + + /* Init txTask */ + if (HAL_TAU_PKT_TX_WAIT_ASYNC == ptr_tx_cb->wait_mode) + { + ptr_tx_cb->running = TRUE; + } + + ptr_cb->init_flag |= HAL_TAU_PKT_INIT_TASK; + + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_COMMON, + "u=%u, pkt task init done, init flag=0x%x\n", unit, ptr_cb->init_flag); + + return (rc); +} + +/* FUNCTION NAME: _hal_tau_pkt_initTxPdma + * PURPOSE: + * To initialize the TX PDMA. + * INPUT: + * unit -- The unit ID + * channel -- The target Tx channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully initialize the TX PDMA. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_initTxPdma( + const UI32_T unit, + const HAL_TAU_PKT_TX_CHANNEL_T channel) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + HAL_TAU_PKT_TX_CB_T *ptr_tx_cb = HAL_TAU_PKT_GET_TX_CB_PTR(unit); + HAL_TAU_PKT_TX_PDMA_T *ptr_tx_pdma = HAL_TAU_PKT_GET_TX_PDMA_PTR(unit, channel); + NPS_IRQ_FLAGS_T irg_flags; + + /* Isr lock to protect Tx PDMA */ + osal_createIsrLock("TCH_LCK", &ptr_tx_pdma->ring_lock); + + if (HAL_TAU_PKT_TX_WAIT_SYNC_INTR == ptr_tx_cb->wait_mode) + { + /* Sync semaphore to signal sendTxPacket */ + osal_createSemaphore("TCH_SYN", NPS_SEMAPHORE_SYNC, &ptr_tx_pdma->sync_intr_sema); + } + + /* Reset Tx PDMA */ + osal_takeIsrLock(&ptr_tx_pdma->ring_lock, &irg_flags); + + ptr_tx_pdma->used_idx = 0; + ptr_tx_pdma->free_idx = 0; + ptr_tx_pdma->used_gpd_num = 0; + ptr_tx_pdma->free_gpd_num = HAL_TAU_PKT_PDMA_TX_GPD_NUM; + ptr_tx_pdma->gpd_num = HAL_TAU_PKT_PDMA_TX_GPD_NUM; + + /* Prepare the HW-GPD ring */ + ptr_tx_pdma->ptr_gpd_start_addr = (HAL_TAU_PKT_TX_GPD_T *)osal_dma_alloc( + (ptr_tx_pdma->gpd_num + 1) * sizeof(HAL_TAU_PKT_TX_GPD_T)); + + if (NULL != ptr_tx_pdma->ptr_gpd_start_addr) + { + osal_memset(ptr_tx_pdma->ptr_gpd_start_addr, 0x0, + (ptr_tx_pdma->gpd_num + 1) * sizeof(HAL_TAU_PKT_TX_GPD_T)); + + ptr_tx_pdma->ptr_gpd_align_start_addr = (HAL_TAU_PKT_TX_GPD_T *)HAL_TAU_PKT_PDMA_ALIGN_ADDR( + (NPS_HUGE_T)ptr_tx_pdma->ptr_gpd_start_addr, sizeof(HAL_TAU_PKT_TX_GPD_T)); + + rc = _hal_tau_pkt_initTxPdmaRing(unit, channel); + if (NPS_E_OK == rc) + { + _hal_tau_pkt_startTxChannelReg(unit, channel, 0); + } + } + else + { + ptr_tx_cb->cnt.no_memory++; + rc = NPS_E_NO_MEMORY; + } + + if (HAL_TAU_PKT_TX_WAIT_ASYNC == ptr_tx_cb->wait_mode) + { + if (NPS_E_OK == rc) + { + /* Prepare the SW-GPD ring */ + ptr_tx_pdma->pptr_sw_gpd_ring = (HAL_TAU_PKT_TX_SW_GPD_T **)osal_alloc( + ptr_tx_pdma->gpd_num * sizeof(HAL_TAU_PKT_TX_SW_GPD_T *)); + + if (NULL != ptr_tx_pdma->pptr_sw_gpd_ring) + { + osal_memset(ptr_tx_pdma->pptr_sw_gpd_ring, 0x0, + ptr_tx_pdma->gpd_num * sizeof(HAL_TAU_PKT_TX_SW_GPD_T *)); + } + else + { + ptr_tx_cb->cnt.no_memory++; + rc = NPS_E_NO_MEMORY; + } + + /* a temp buffer to store the 1st sw gpd for each packet to be enque + * we cannot enque packet before release a spinlock + */ + ptr_tx_pdma->pptr_sw_gpd_bulk = (HAL_TAU_PKT_TX_SW_GPD_T **)osal_alloc( + ptr_tx_pdma->gpd_num * sizeof(HAL_TAU_PKT_TX_SW_GPD_T *)); + + if (NULL != ptr_tx_pdma->pptr_sw_gpd_bulk) + { + osal_memset(ptr_tx_pdma->pptr_sw_gpd_bulk, 0x0, + ptr_tx_pdma->gpd_num * sizeof(HAL_TAU_PKT_TX_SW_GPD_T *)); + } + else + { + ptr_tx_cb->cnt.no_memory++; + rc = NPS_E_NO_MEMORY; + } + } + } + + osal_giveIsrLock(&ptr_tx_pdma->ring_lock, &irg_flags); + + return (rc); +} + +/* FUNCTION NAME: _hal_tau_pkt_initRxPdma + * PURPOSE: + * To initialize the RX PDMA. + * INPUT: + * unit -- The unit ID + * channel -- The target Rx channel + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully initialize the RX PDMA. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_initRxPdma( + const UI32_T unit, + const HAL_TAU_PKT_RX_CHANNEL_T channel) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); + HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, channel); + + /* Binary semaphore to protect Rx PDMA */ + osal_createSemaphore("RCH_LCK", NPS_SEMAPHORE_BINARY, &ptr_rx_pdma->sema); + + /* Reset Rx PDMA */ + osal_takeSemaphore(&ptr_rx_pdma->sema, NPS_SEMAPHORE_WAIT_FOREVER); + ptr_rx_pdma->cur_idx = 0; + ptr_rx_pdma->gpd_num = HAL_TAU_PKT_PDMA_RX_GPD_NUM; + + /* Prepare the HW-GPD ring */ + ptr_rx_pdma->ptr_gpd_start_addr = (HAL_TAU_PKT_RX_GPD_T *)osal_dma_alloc( + (ptr_rx_pdma->gpd_num + 1) * sizeof(HAL_TAU_PKT_RX_GPD_T)); + + if (NULL != ptr_rx_pdma->ptr_gpd_start_addr) + { + osal_memset(ptr_rx_pdma->ptr_gpd_start_addr, 0, + (ptr_rx_pdma->gpd_num + 1) * sizeof(HAL_TAU_PKT_RX_GPD_T)); + + ptr_rx_pdma->ptr_gpd_align_start_addr = (HAL_TAU_PKT_RX_GPD_T *)HAL_TAU_PKT_PDMA_ALIGN_ADDR( + (NPS_HUGE_T)ptr_rx_pdma->ptr_gpd_start_addr, sizeof(HAL_TAU_PKT_RX_GPD_T)); + + /* will initRxPdmaRingBuf and start RCH after setRxConfig */ + rc = _hal_tau_pkt_initRxPdmaRing(unit, channel); + } + else + { + ptr_rx_cb->cnt.no_memory++; + rc = NPS_E_NO_MEMORY; + } + + if (NPS_E_OK == rc) + { + /* Prepare the SKB ring */ + ptr_rx_pdma->pptr_skb_ring = (struct sk_buff **)osal_alloc( + ptr_rx_pdma->gpd_num * sizeof(struct sk_buff *)); + + if (NULL != ptr_rx_pdma->pptr_skb_ring) + { + osal_memset(ptr_rx_pdma->pptr_skb_ring, 0x0, + ptr_rx_pdma->gpd_num * sizeof(struct sk_buff *)); + } + else + { + ptr_rx_cb->cnt.no_memory++; + rc = NPS_E_NO_MEMORY; + } + } + + osal_giveSemaphore(&ptr_rx_pdma->sema); + + return (rc); +} + +/* FUNCTION NAME: _hal_tau_pkt_initPktCb + * PURPOSE: + * To initialize the control block of Drv. + * INPUT: + * unit -- The unit ID + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully initialize the control block. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_initPktCb( + const UI32_T unit) +{ + HAL_TAU_PKT_DRV_CB_T *ptr_cb = HAL_TAU_PKT_GET_DRV_CB_PTR(unit); + UI32_T idx = 0, vec = sizeof(_hal_tau_pkt_intr_vec) / sizeof(HAL_TAU_PKT_INTR_VEC_T); + + osal_memset(ptr_cb, 0x0, sizeof(HAL_TAU_PKT_DRV_CB_T)); + + /* Register PKT interrupt functions */ + osal_createIsrLock("ISR_LOCK", &ptr_cb->intr_lock); + osal_mdc_registerIsr(unit, _hal_tau_pkt_dispatcher, (void *)((NPS_HUGE_T)unit)); + + for (idx = 0; idx < vec; idx++) + { + osal_createEvent("ISR_EVENT", &_hal_tau_pkt_intr_vec[idx].intr_event); + ptr_cb->intr_bitmap |= (_hal_tau_pkt_intr_vec[idx].intr_reg); + } + + return (NPS_E_OK); +} + +/* FUNCTION NAME: _hal_tau_pkt_initPktTxCb + * PURPOSE: + * To initialize the control block of Rx PDMA. + * INPUT: + * unit -- The unit ID + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully initialize the control block. + * NPS_E_OTHERS -- Configure failed. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_initPktTxCb( + const UI32_T unit) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + HAL_TAU_PKT_TX_CB_T *ptr_tx_cb = HAL_TAU_PKT_GET_TX_CB_PTR(unit); + HAL_TAU_PKT_TX_CHANNEL_T channel = 0; + + osal_memset(ptr_tx_cb, 0x0, sizeof(HAL_TAU_PKT_TX_CB_T)); + + ptr_tx_cb->wait_mode = HAL_TAU_PKT_TX_WAIT_MODE; + + if (HAL_TAU_PKT_TX_WAIT_ASYNC == ptr_tx_cb->wait_mode) + { + /* Sync semaphore to signal txTask */ + osal_createEvent("TX_SYNC", &ptr_tx_cb->sync_sema); + + /* Initialize Tx GPD-queue (of first SW-GPD) from handleTxDoneTask to txTask */ + ptr_tx_cb->sw_queue.len = HAL_TAU_PKT_TX_QUEUE_LEN; + ptr_tx_cb->sw_queue.weight = 0; + + osal_createSemaphore("TX_QUE", NPS_SEMAPHORE_BINARY, &ptr_tx_cb->sw_queue.sema); + osal_que_create(&ptr_tx_cb->sw_queue.que_id, ptr_tx_cb->sw_queue.len); + } + else if (HAL_TAU_PKT_TX_WAIT_SYNC_POLL == ptr_tx_cb->wait_mode) + { + /* Disable TX done ISR. */ + for (channel = 0; channel < HAL_TAU_PKT_TX_CHANNEL_LAST; channel++) + { + _hal_tau_pkt_disableIntr(unit, HAL_TAU_PKT_TCH_REG(unit, channel)); + } + } + + /* Init Tx PDMA */ + for (channel = 0; ((channel < HAL_TAU_PKT_TX_CHANNEL_LAST) && (NPS_E_OK == rc)); channel++) + { + rc = _hal_tau_pkt_initTxPdma(unit, channel); + } + + return (rc); +} + +/* FUNCTION NAME: _hal_tau_pkt_initPktRxCb + * PURPOSE: + * To initialize the control block of Rx PDMA. + * INPUT: + * unit -- The unit ID + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully initialize the control block. + * NPS_E_OTHERS -- Configure failed. + * NOTES: + * + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_initPktRxCb( + const UI32_T unit) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); + HAL_TAU_PKT_RX_CHANNEL_T channel = 0; + UI32_T queue = 0; + + osal_memset(ptr_rx_cb, 0x0, sizeof(HAL_TAU_PKT_RX_CB_T)); + + ptr_rx_cb->sched_mode = HAL_TAU_PKT_RX_SCHED_MODE; + + /* Sync semaphore to signal rxTask */ + osal_createEvent("RX_SYNC", &ptr_rx_cb->sync_sema); + + /* Initialize Rx GPD-queue (of first SW-GPD) from handleRxDoneTask to rxTask */ + for (queue = 0; ((queue < HAL_TAU_PKT_RX_QUEUE_NUM) && (NPS_E_OK == rc)); queue++) + { + ptr_rx_cb->sw_queue[queue].len = HAL_TAU_PKT_RX_QUEUE_LEN; + ptr_rx_cb->sw_queue[queue].weight = HAL_TAU_PKT_RX_QUEUE_WEIGHT; + + osal_createSemaphore("RX_QUE", NPS_SEMAPHORE_BINARY, &ptr_rx_cb->sw_queue[queue].sema); + osal_que_create(&ptr_rx_cb->sw_queue[queue].que_id, ptr_rx_cb->sw_queue[queue].len); + } + + /* Init Rx PDMA */ + for (channel = 0; ((channel < HAL_TAU_PKT_RX_CHANNEL_LAST) && (NPS_E_OK == rc)); channel++) + { + rc = _hal_tau_pkt_initRxPdma(unit, channel); + } + + return (rc); +} + +/* FUNCTION NAME: _hal_tau_pkt_initL1Isr + * PURPOSE: + * To initialize the PDMA L1 ISR configuration. + * INPUT: + * unit -- The unit ID + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully initialize the L1 ISR. + * NPS_E_OTHERS -- Configure failed. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_initL1Isr( + const UI32_T unit) +{ + UI32_T idx = 0, vec = sizeof(_hal_tau_pkt_intr_vec) / sizeof(HAL_TAU_PKT_INTR_VEC_T); + + for (idx = 0; idx < vec; idx++) + { + _hal_tau_pkt_enableIntr(unit, _hal_tau_pkt_intr_vec[idx].intr_reg); + _hal_tau_pkt_unmaskIntr(unit, _hal_tau_pkt_intr_vec[idx].intr_reg); + } + + return (NPS_E_OK); +} + +/* FUNCTION NAME: _hal_tau_pkt_initL2Isr + * PURPOSE: + * To initialize the PDMA L2 ISR configuration. + * INPUT: + * unit -- The unit ID + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully configure for the L2 ISR. + * NPS_E_OTHERS -- Configure failed. + * NOTES: + * None + */ +static NPS_ERROR_NO_T +_hal_tau_pkt_initL2Isr( + const UI32_T unit) +{ + HAL_TAU_PKT_L2_ISR_T isr_status = 0x0; + + HAL_TAU_PKT_SET_BITMAP(isr_status, HAL_TAU_PKT_L2_ISR_RCH0); + HAL_TAU_PKT_SET_BITMAP(isr_status, HAL_TAU_PKT_L2_ISR_RCH1); + HAL_TAU_PKT_SET_BITMAP(isr_status, HAL_TAU_PKT_L2_ISR_RCH2); + HAL_TAU_PKT_SET_BITMAP(isr_status, HAL_TAU_PKT_L2_ISR_RCH3); + HAL_TAU_PKT_SET_BITMAP(isr_status, HAL_TAU_PKT_L2_ISR_TCH0); + HAL_TAU_PKT_SET_BITMAP(isr_status, HAL_TAU_PKT_L2_ISR_TCH1); + HAL_TAU_PKT_SET_BITMAP(isr_status, HAL_TAU_PKT_L2_ISR_TCH2); + HAL_TAU_PKT_SET_BITMAP(isr_status, HAL_TAU_PKT_L2_ISR_TCH3); + HAL_TAU_PKT_SET_BITMAP(isr_status, HAL_TAU_PKT_L2_ISR_RX_QID_MAP_ERR); + HAL_TAU_PKT_SET_BITMAP(isr_status, HAL_TAU_PKT_L2_ISR_RX_FRAME_ERR); + + osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_ERR_INT_EN), + &isr_status, sizeof(UI32_T)); + + osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_ERR_INT_MASK_SET), + &isr_status, sizeof(UI32_T)); + + return (NPS_E_OK); + +} + +NPS_ERROR_NO_T +_hal_tau_pkt_resetIosCreditCfg( + const UI32_T unit) +{ +#define HAL_TAU_PKT_PDMA_CREDIT_CFG_RESET_OFFSET (16) + + UI32_T credit_cfg = 0x0; + UI32_T idx; + + for (idx=0; idxptr_profile = ptr_new_profile; + + /* Create the 1st node in the interface profile list */ + if (NULL == *pptr_profile_list) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, + "prof list empty\n"); + *pptr_profile_list = ptr_new_prof_node; + ptr_new_prof_node->ptr_next_node = NULL; + } + else + { + ptr_prev_node = *pptr_profile_list; + ptr_curr_node = *pptr_profile_list; + + while (ptr_curr_node != NULL) + { + if (ptr_curr_node->ptr_profile->priority <= ptr_new_profile->priority) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, + "find prof id=%d (%s) higher priority=%d, search next\n", + ptr_curr_node->ptr_profile->id, + ptr_curr_node->ptr_profile->name, + ptr_curr_node->ptr_profile->priority); + /* Search the next node */ + ptr_prev_node = ptr_curr_node; + ptr_curr_node = ptr_curr_node->ptr_next_node; + } + else + { + /* Insert intermediate node */ + ptr_new_prof_node->ptr_next_node = ptr_curr_node; + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, + "insert prof id=%d (%s) before prof id=%d (%s) (priority=%d >= %d)\n", + ptr_new_prof_node->ptr_profile->id, + ptr_new_prof_node->ptr_profile->name, + ptr_curr_node->ptr_profile->id, + ptr_curr_node->ptr_profile->name, + ptr_new_prof_node->ptr_profile->priority, + ptr_curr_node->ptr_profile->priority); + + if (ptr_prev_node == ptr_curr_node) + { + /* There is no previous node: change the root */ + *pptr_profile_list = ptr_new_prof_node; + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, + "insert prof id=%d (%s) to head (priority=%d)\n", + ptr_new_prof_node->ptr_profile->id, + ptr_new_prof_node->ptr_profile->name, + ptr_new_prof_node->ptr_profile->priority); + } + else + { + ptr_prev_node->ptr_next_node = ptr_new_prof_node; + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, + "insert prof id=%d (%s) after prof id=%d (%s) (priority=%d <= %d)\n", + ptr_new_prof_node->ptr_profile->id, + ptr_new_prof_node->ptr_profile->name, + ptr_prev_node->ptr_profile->id, + ptr_prev_node->ptr_profile->name, + ptr_new_prof_node->ptr_profile->priority, + ptr_prev_node->ptr_profile->priority); + } + + return (NPS_E_OK); + } + } + + /* Insert node to the tail of list */ + ptr_prev_node->ptr_next_node = ptr_new_prof_node; + ptr_new_prof_node->ptr_next_node = NULL; + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, + "insert prof id=%d (%s) to tail, after prof id=%d (%s) (priority=%d <= %d)\n", + ptr_new_prof_node->ptr_profile->id, + ptr_new_prof_node->ptr_profile->name, + ptr_prev_node->ptr_profile->id, + ptr_prev_node->ptr_profile->name, + ptr_new_prof_node->ptr_profile->priority, + ptr_prev_node->ptr_profile->priority); + } + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_addProfToAllIntf( + HAL_TAU_PKT_NETIF_PROFILE_T *ptr_new_profile) +{ + UI32_T port; + HAL_TAU_PKT_NETIF_PORT_DB_T *ptr_port_db; + + for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) + { + ptr_port_db = HAL_TAU_PKT_GET_PORT_DB(port); + /* Shall we check if the interface is ever created in the port?? */ + //if (NULL != ptr_port_db->ptr_net_dev) + if (1) + { + _hal_tau_pkt_addProfToList(ptr_new_profile, &ptr_port_db->ptr_profile_list); + } + } + + return (NPS_E_OK); +} + +static HAL_TAU_PKT_NETIF_PROFILE_T * +_hal_tau_pkt_delProfFromListById( + const UI32_T id, + HAL_TAU_PKT_PROFILE_NODE_T **pptr_profile_list) +{ + HAL_TAU_PKT_PROFILE_NODE_T *ptr_temp_node; + HAL_TAU_PKT_PROFILE_NODE_T *ptr_curr_node, *ptr_prev_node; + HAL_TAU_PKT_NETIF_PROFILE_T *ptr_profile = NULL;; + + if (NULL != *pptr_profile_list) + { + /* Check the 1st node */ + if (id == (*pptr_profile_list)->ptr_profile->id) + { + ptr_profile = (*pptr_profile_list)->ptr_profile; + ptr_temp_node = (*pptr_profile_list); + (*pptr_profile_list) = ptr_temp_node->ptr_next_node; + + if (NULL != ptr_temp_node->ptr_next_node) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, + "choose prof id=%d (%s) as new head\n", + ptr_temp_node->ptr_next_node->ptr_profile->id, + ptr_temp_node->ptr_next_node->ptr_profile->name); + } + else + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, + "prof list is empty\n"); + } + + + osal_free(ptr_temp_node); + } + else + { + ptr_prev_node = *pptr_profile_list; + ptr_curr_node = ptr_prev_node->ptr_next_node; + + while (NULL != ptr_curr_node) + { + if (id != ptr_curr_node->ptr_profile->id) + { + ptr_prev_node = ptr_curr_node; + ptr_curr_node = ptr_curr_node->ptr_next_node; + } + else + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, + "find prof id=%d, free done\n", id); + + ptr_profile = ptr_curr_node->ptr_profile; + ptr_prev_node->ptr_next_node = ptr_curr_node->ptr_next_node; + osal_free(ptr_curr_node); + break; + } + } + } + } + + if (NULL == ptr_profile) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_PROFILE | HAL_TAU_PKT_DBG_ERR), + "find prof failed, id=%d\n", id); + } + + return (ptr_profile); +} + + +static NPS_ERROR_NO_T +_hal_tau_pkt_delProfFromAllIntfById( + const UI32_T id) +{ + UI32_T port; + HAL_TAU_PKT_NETIF_PORT_DB_T *ptr_port_db; + + for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) + { + ptr_port_db = HAL_TAU_PKT_GET_PORT_DB(port); + /* Shall we check if the interface is ever created in the port?? */ + //if (NULL != ptr_port_db->ptr_net_dev) + if (1) + { + _hal_tau_pkt_delProfFromListById(id, &ptr_port_db->ptr_profile_list); + } + } + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_allocProfEntry( + HAL_TAU_PKT_NETIF_PROFILE_T *ptr_profile) +{ + UI32_T idx; + + for (idx=0; idxid = idx; + return (NPS_E_OK); + } + } + return (NPS_E_TABLE_FULL); +} + +static HAL_TAU_PKT_NETIF_PROFILE_T * +_hal_tau_pkt_freeProfEntry( + const UI32_T id) +{ + HAL_TAU_PKT_NETIF_PROFILE_T *ptr_profile = NULL; + + if (id < HAL_TAU_PKT_NET_PROFILE_NUM_MAX) + { + ptr_profile = _ptr_hal_tau_pkt_profile_entry[id]; + _ptr_hal_tau_pkt_profile_entry[id] = NULL; + } + + return (ptr_profile); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_destroyAllIntf( + const UI32_T unit) +{ + HAL_TAU_PKT_NETIF_PORT_DB_T *ptr_port_db; + UI32_T port = 0; + + /* Unregister net devices by id, although the "id" is now relavent to "port" we still perform a search */ + for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) + { + ptr_port_db = HAL_TAU_PKT_GET_PORT_DB(port); + if (NULL != ptr_port_db->ptr_net_dev) /* valid intf */ + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_INTF, + "u=%u, find intf %s (id=%d) on phy port=%d, destroy done\n", + unit, + ptr_port_db->meta.name, + ptr_port_db->meta.port, + ptr_port_db->meta.port); + + netif_stop_queue(ptr_port_db->ptr_net_dev); + unregister_netdev(ptr_port_db->ptr_net_dev); + free_netdev(ptr_port_db->ptr_net_dev); + + /* Don't need to remove profiles on this port. + * In fact, the profile is binding to "port" not "intf". + */ + /* _hal_tau_pkt_destroyProfList(ptr_port_db->ptr_profile_list); */ + + osal_memset(ptr_port_db, 0x0, sizeof(HAL_TAU_PKT_NETIF_PORT_DB_T)); + } + } + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_delProfListOnAllIntf( + const UI32_T unit) +{ + HAL_TAU_PKT_NETIF_PORT_DB_T *ptr_port_db; + UI32_T port = 0; + HAL_TAU_PKT_PROFILE_NODE_T *ptr_curr_node, *ptr_next_node; + + /* Unregister net devices by id, although the "id" is now relavent to "port" we still perform a search */ + for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) + { + ptr_port_db = HAL_TAU_PKT_GET_PORT_DB(port); + if (NULL != ptr_port_db->ptr_profile_list) /* valid intf */ + { + ptr_curr_node = ptr_port_db->ptr_profile_list; + while (NULL != ptr_curr_node) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, + "u=%u, del prof id=%d on phy port=%d\n", + unit, ptr_curr_node->ptr_profile->id, port); + + ptr_next_node = ptr_curr_node->ptr_next_node; + osal_free(ptr_curr_node); + ptr_curr_node = ptr_next_node; + } + } + } + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_destroyAllProfile( + const UI32_T unit) +{ + HAL_TAU_PKT_NETIF_PROFILE_T *ptr_profile; + UI32_T prof_id; + + _hal_tau_pkt_delProfListOnAllIntf(unit); + + for (prof_id=0; prof_idid, + ptr_profile->name, + ptr_profile->priority, + ptr_profile->flags); + osal_free(ptr_profile); + } + } + + return (NPS_E_OK); +} + +/* FUNCTION NAME: hal_tau_pkt_initPktDrv + * PURPOSE: + * To invoke the functions to initialize the control block for each + * PDMA subsystem. + * INPUT: + * unit -- The unit ID + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successfully initialize the control blocks. + * NPS_E_OTHERS -- Initialize the control blocks failed. + * NOTES: + * None + */ +NPS_ERROR_NO_T +hal_tau_pkt_initPktDrv( + const UI32_T unit) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + UI32_T channel = 0; + UI32_T flush_intr = 0x0; + UI32_T clear_intr = 0xffffffff; + HAL_TAU_PKT_DRV_CB_T *ptr_cb = HAL_TAU_PKT_GET_DRV_CB_PTR(unit); + + /* There's a case that PDMA Tx is on-going when doing chip reset, + * where PDMA may hang and be not programmable since current Tx packet + * stucks due to IOS credit too low. + * Thus, we always reset IOS credit value before progrmming Tx PDMA. + */ + _hal_tau_pkt_resetIosCreditCfg(unit); + + /* Since the users may kill SDK application without a de-init flow, + * we help to detect if NETIF is ever init before, and perform deinit. + * (Because the users cannot perform Task init bypassing Drv init, this + * check is required only in here) + */ + if (0 != (ptr_cb->init_flag & HAL_TAU_PKT_INIT_DRV)) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_ERR, + "u=%u, init pkt drv failed, inited\n", unit); + + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_ERR, + "u=%u, stop rx pkt\n", unit); + _hal_tau_pkt_rxStop(unit); + + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_ERR, + "u=%u, stop all intf\n", unit); + _hal_tau_pkt_stopAllIntf(unit); + + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_ERR, + "u=%u, deinit pkt task\n", unit); + + hal_tau_pkt_deinitTask(unit); + + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_ERR, + "u=%u, deinit pkt drv\n", unit); + hal_tau_pkt_deinitPktDrv(unit); + + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_ERR, + "u=%u, destroy all prof\n", unit); + _hal_tau_pkt_destroyAllProfile(unit); + + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_ERR, + "u=%u, destroy all intf\n", unit); + _hal_tau_pkt_destroyAllIntf(unit); + } + + /* [cold-boot] 1. stop DMA channel + * 2. disable/mask/clear the interrupt status. + */ + osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_ERR_INT_EN), + &flush_intr, sizeof(UI32_T)); + + osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_ERR_INT_MASK_SET), + &clear_intr, sizeof(UI32_T)); + + osal_mdc_writePciReg(unit, + HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_ERR_INT_CLR), + &clear_intr, sizeof(UI32_T)); + + for (channel = 0; channel < HAL_TAU_PKT_TX_CHANNEL_LAST; channel++) + { + _hal_tau_pkt_stopTxChannelReg(unit, channel); + _hal_tau_pkt_maskAllTxL2IsrReg(unit, channel); + _hal_tau_pkt_clearTxL2IsrStatusReg(unit, channel, clear_intr); + } + + for (channel = 0; channel < HAL_TAU_PKT_RX_CHANNEL_LAST; channel++) + { + _hal_tau_pkt_stopRxChannelReg(unit, channel); + _hal_tau_pkt_maskAllRxL2IsrReg(unit, channel); + _hal_tau_pkt_clearRxL2IsrStatusReg(unit, channel, clear_intr); + } + + rc = _hal_tau_pkt_initPktCb(unit); + if (NPS_E_OK == rc) + { + rc = _hal_tau_pkt_initPktTxCb(unit); + } + if (NPS_E_OK == rc) + { + rc = _hal_tau_pkt_initPktRxCb(unit); + } + if (NPS_E_OK == rc) + { + rc = _hal_tau_pkt_initL1Isr(unit); + } + if (NPS_E_OK == rc) + { + rc = _hal_tau_pkt_initL2Isr(unit); + } + + /* Set the flag to record init state */ + ptr_cb->init_flag |= HAL_TAU_PKT_INIT_DRV; + + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_COMMON, + "u=%u, pkt drv init done, init flag=0x%x\n", unit, ptr_cb->init_flag); + + return (rc); +} + +/* ----------------------------------------------------------------------------------- Init: I/O */ +NPS_ERROR_NO_T +hal_tau_pkt_getNetDev( + const UI32_T unit, + const UI32_T port, + struct net_device **pptr_net_dev) +{ + *pptr_net_dev = HAL_TAU_PKT_GET_PORT_NETDEV(port); + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +hal_tau_pkt_prepareGpd( + const UI32_T unit, + const NPS_ADDR_T phy_addr, + const UI32_T len, + const UI32_T port, + HAL_TAU_PKT_TX_SW_GPD_T *ptr_sw_gpd) +{ + /* fill up tx_gpd */ + ptr_sw_gpd->tx_gpd.data_buf_addr_hi = NPS_ADDR_64_HI(phy_addr); + ptr_sw_gpd->tx_gpd.data_buf_addr_lo = NPS_ADDR_64_LOW(phy_addr); + ptr_sw_gpd->tx_gpd.data_buf_size = len; + ptr_sw_gpd->tx_gpd.chksum = 0x0; + ptr_sw_gpd->tx_gpd.ipc = 0; /* Raw mode, sent to plane 0 */ + ptr_sw_gpd->tx_gpd.prg = HAL_TAU_PKT_PRG_PROCESS_GPD; + ptr_sw_gpd->tx_gpd.hwo = HAL_TAU_PKT_HWO_HW_OWN; + ptr_sw_gpd->tx_gpd.ch = HAL_TAU_PKT_CH_LAST_GPD; + ptr_sw_gpd->tx_gpd.ioc = HAL_TAU_PKT_IOC_HAS_INTR; + ptr_sw_gpd->tx_gpd.pkt_len = len; + ptr_sw_gpd->tx_gpd.crcc = HAL_TAU_PKT_CRCC_SUM_BY_HW; + + /* fill up cpu header */ + ptr_sw_gpd->tx_gpd.itmh_eth.skip_ipp = 1; + ptr_sw_gpd->tx_gpd.itmh_eth.skip_epp = 1; + ptr_sw_gpd->tx_gpd.itmh_eth.color = 0; /* Green */ + ptr_sw_gpd->tx_gpd.itmh_eth.tc = 15; /* Max tc */ + ptr_sw_gpd->tx_gpd.itmh_eth.igr_phy_port = 0; + + ptr_sw_gpd->tx_gpd.pph_l2.mrk_pcp_val = 7; /* Max pcp */ + ptr_sw_gpd->tx_gpd.pph_l2.mrk_pcp_dei_en = 1; + + /* destination index + * 1. to local ETH port + * 2. to remote ETH port + * 3. to remote CPU + */ + ptr_sw_gpd->tx_gpd.itmh_eth.dst_idx = port; + + /* [Taurus] we should set all-1 for the following fields to skip some tm-logic */ + + /* TM header */ + ptr_sw_gpd->tx_gpd.itmh_eth.src_idx = 0x7fff; + ptr_sw_gpd->tx_gpd.itmh_eth.intf_fdid = 0x3fff; + ptr_sw_gpd->tx_gpd.itmh_eth.src_supp_tag = 0x1f; + ptr_sw_gpd->tx_gpd.itmh_eth.nvo3_mgid = 0x6fff; + ptr_sw_gpd->tx_gpd.itmh_eth.nvo3_src_supp_tag_w0 = 0x1; + ptr_sw_gpd->tx_gpd.itmh_eth.nvo3_src_supp_tag_w1 = 0xf; + + /* PP header */ + ptr_sw_gpd->tx_gpd.pph_l2.nvo3_encap_idx = HAL_TAU_INVALID_NVO3_ENCAP_IDX; + ptr_sw_gpd->tx_gpd.pph_l2.nvo3_adj_idx = HAL_TAU_INVALID_NVO3_ADJ_IDX; + + return (NPS_E_OK); +} + +/* ----------------------------------------------------------------------------------- Init: net_dev_ops */ +static int +_hal_tau_pkt_net_dev_init( + struct net_device *ptr_net_dev) +{ + return 0; +} + +static int +_hal_tau_pkt_net_dev_open( + struct net_device *ptr_net_dev) +{ + netif_start_queue(ptr_net_dev); + +#if defined(PERF_EN_TEST) + /* Tx (len, tx_channel, rx_channel, test_skb) */ + perf_test(64, 1, 0, FALSE); + perf_test(64, 2, 0, FALSE); + perf_test(64, 4, 0, FALSE); + + perf_test(1518, 1, 0, FALSE); + perf_test(1518, 2, 0, FALSE); + perf_test(1518, 4, 0, FALSE); + + perf_test(9216, 1, 0, FALSE); + perf_test(9216, 2, 0, FALSE); + perf_test(9216, 4, 0, FALSE); + + /* Rx (len, tx_channel, rx_channel, test_skb) */ + perf_test(64, 0, 1, FALSE); + perf_test(64, 0, 3, FALSE); + perf_test(64, 0, 4, FALSE); + + perf_test(1518, 0, 1, FALSE); + perf_test(1518, 0, 3, FALSE); + perf_test(1518, 0, 4, FALSE); + + perf_test(9216, 0, 1, FALSE); + perf_test(9216, 0, 3, FALSE); + perf_test(9216, 0, 4, FALSE); +#endif + + return 0; +} + +static int +_hal_tau_pkt_net_dev_stop( + struct net_device *ptr_net_dev) +{ + netif_stop_queue(ptr_net_dev); + return 0; +} + +static int +_hal_tau_pkt_net_dev_ioctl( + struct net_device *ptr_net_dev, + struct ifreq *ptr_ifreq, + int cmd) +{ + return 0; +} + +static netdev_tx_t +_hal_tau_pkt_net_dev_tx( + struct sk_buff *ptr_skb, + struct net_device *ptr_net_dev) +{ + struct net_device_priv *ptr_priv = netdev_priv(ptr_net_dev); + /* chip meta */ + unsigned int unit; + unsigned int channel = 0; + HAL_TAU_PKT_TX_SW_GPD_T *ptr_sw_gpd = NULL; + void *ptr_virt_addr = NULL; + NPS_ADDR_T phy_addr = 0x0; + + if (NULL == ptr_priv) + { + /* in case that the netdev has been freed/reset somewhere */ + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_ERR, "get netdev_priv failed\n"); + return -EFAULT; + } + + /* check skb */ + if (NULL == ptr_skb) + { + ptr_priv->stats.tx_errors++; + return -EFAULT; + } + + unit = ptr_priv->unit; + + /* pad to 60-bytes if skb_len < 60, see: eth_skb_pad(skb) */ + if (ptr_skb->len < ETH_ZLEN) + { + skb_pad(ptr_skb, ETH_ZLEN - ptr_skb->len); + skb_set_tail_pointer(ptr_skb, ETH_ZLEN); + ptr_skb->len = ETH_ZLEN; + } + + /* pad 4-bytes for chip-crc */ + skb_pad(ptr_skb, ETH_FCS_LEN); + skb_set_tail_pointer(ptr_skb, ETH_FCS_LEN); + ptr_skb->len += ETH_FCS_LEN; + + /* alloc gpd */ + ptr_sw_gpd = osal_alloc(sizeof(HAL_TAU_PKT_TX_SW_GPD_T)); + if (NULL == ptr_sw_gpd) + { + ptr_priv->stats.tx_errors++; + osal_skb_free(ptr_skb); + } + else + { + /* map skb to dma */ + ptr_virt_addr = ptr_skb->data; + phy_addr = osal_skb_mapDma(ptr_skb, DMA_TO_DEVICE); + if (0x0 == phy_addr) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_ERR, "u=%u, txch=%u, skb dma map err\n", + unit, channel); + ptr_priv->stats.tx_errors++; + osal_skb_free(ptr_skb); + osal_free(ptr_sw_gpd); + } + else + { + /* trans skb to gpd */ + memset(ptr_sw_gpd, 0x0, sizeof(HAL_TAU_PKT_TX_SW_GPD_T)); + ptr_sw_gpd->callback = (void *)_hal_tau_pkt_net_dev_tx_callback; + ptr_sw_gpd->ptr_cookie = (void *)ptr_skb; + ptr_sw_gpd->gpd_num = 1; + ptr_sw_gpd->ptr_next = NULL; + ptr_sw_gpd->channel = channel; + + /* prepare gpd */ + hal_tau_pkt_prepareGpd(unit, phy_addr, ptr_skb->len, ptr_priv->port, ptr_sw_gpd); + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,6,7) + ptr_net_dev->trans_start = jiffies; +#else + netdev_get_tx_queue(ptr_net_dev, 0)->trans_start = jiffies; +#endif + /* send gpd */ + if (NPS_E_OK == hal_tau_pkt_sendGpd(unit, channel, ptr_sw_gpd)) + { + ptr_priv->stats.tx_packets++; + ptr_priv->stats.tx_bytes += ptr_skb->len; + } + else + { + ptr_priv->stats.tx_fifo_errors++; /* to record the extreme cases where packets are dropped */ + ptr_priv->stats.tx_dropped++; + + osal_skb_unmapDma(phy_addr, ptr_skb->len, DMA_TO_DEVICE); + osal_skb_free(ptr_skb); + osal_free(ptr_sw_gpd); + + return NETDEV_TX_OK; + } + } + } + + return NETDEV_TX_OK; +} + +static void +_hal_tau_pkt_net_dev_tx_timeout( + struct net_device *ptr_net_dev) +{ + netif_stop_queue(ptr_net_dev); + osal_sleepThread(1000); + netif_wake_queue(ptr_net_dev); +} + +static struct net_device_stats * +_hal_tau_pkt_net_dev_get_stats( + struct net_device *ptr_net_dev) +{ + struct net_device_priv *ptr_priv = netdev_priv(ptr_net_dev); + + return (&ptr_priv->stats); +} + +static int +_hal_tau_pkt_net_dev_set_mtu( + struct net_device *ptr_net_dev, + int new_mtu) +{ + if (new_mtu < 64 || new_mtu > 9216) + { + return -EINVAL; + } + ptr_net_dev->mtu = new_mtu; /* This mtu need to be synced to chip's */ + return 0; +} + +static int +_hal_tau_pkt_net_dev_set_mac( + struct net_device *ptr_net_dev, + void *ptr_mac_addr) +{ + struct sockaddr *ptr_addr = ptr_mac_addr; + + memcpy(ptr_net_dev->dev_addr, ptr_addr->sa_data, ptr_net_dev->addr_len); + return 0; +} + +static void +_hal_tau_pkt_net_dev_set_rx_mode( + struct net_device *ptr_dev) +{ + if (ptr_dev->flags & IFF_PROMISC) + { + } + else + { + if (ptr_dev->flags & IFF_ALLMULTI) + { + } + else + { + if (netdev_mc_empty(ptr_dev)) + { + return; + } + } + } +} + +static struct net_device_ops _hal_tau_pkt_net_dev_ops = +{ + .ndo_init = _hal_tau_pkt_net_dev_init, + .ndo_open = _hal_tau_pkt_net_dev_open, + .ndo_stop = _hal_tau_pkt_net_dev_stop, + .ndo_do_ioctl = _hal_tau_pkt_net_dev_ioctl, + .ndo_start_xmit = _hal_tau_pkt_net_dev_tx, + .ndo_tx_timeout = _hal_tau_pkt_net_dev_tx_timeout, + .ndo_get_stats = _hal_tau_pkt_net_dev_get_stats, + .ndo_change_mtu = _hal_tau_pkt_net_dev_set_mtu, + .ndo_set_mac_address = _hal_tau_pkt_net_dev_set_mac, + .ndo_set_rx_mode = _hal_tau_pkt_net_dev_set_rx_mode, +}; + +static int +_hal_tau_pkt_net_dev_ethtool_get( + struct net_device *ptr_dev, + struct ethtool_cmd *ptr_cmd) +{ + struct net_device_priv *ptr_priv; + + ptr_cmd->supported = SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE; + ptr_cmd->port = PORT_FIBRE; + ptr_cmd->duplex = DUPLEX_FULL; + + ptr_priv = netdev_priv(ptr_dev); + ethtool_cmd_speed_set(ptr_cmd, ptr_priv->speed); + + return 0; +} + +static struct ethtool_ops _hal_tau_pkt_net_dev_ethtool_ops = +{ + .get_settings = _hal_tau_pkt_net_dev_ethtool_get, + .get_link = ethtool_op_get_link, +}; + +static void +_hal_tau_pkt_setup( + struct net_device *ptr_net_dev) +{ + struct net_device_priv *ptr_priv = netdev_priv(ptr_net_dev); + + /* setup net device */ + ether_setup(ptr_net_dev); + ptr_net_dev->netdev_ops = &_hal_tau_pkt_net_dev_ops; + ptr_net_dev->ethtool_ops = &_hal_tau_pkt_net_dev_ethtool_ops; + ptr_net_dev->watchdog_timeo = HAL_TAU_PKT_TX_TIMEOUT; + ptr_net_dev->mtu = HAL_TAU_PKT_MAX_ETH_FRAME_SIZE; /* This mtu need to be synced to chip's */ + random_ether_addr(ptr_net_dev->dev_addr); /* Please use the mac-addr of interface. */ + + /* setup private data */ + ptr_priv->ptr_net_dev = ptr_net_dev; + memset(&ptr_priv->stats, 0, sizeof(struct net_device_stats)); +} + +static void +_hal_tau_pkt_lockRxChannelAll( + const UI32_T unit) +{ + UI32_T rch; + HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma; + + for (rch = 0; rch < HAL_TAU_PKT_RX_CHANNEL_LAST; rch++) + { + ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, rch); + osal_takeSemaphore(&ptr_rx_pdma->sema, NPS_SEMAPHORE_WAIT_FOREVER); + } +} + +static void +_hal_tau_pkt_unlockRxChannelAll( + const UI32_T unit) +{ + UI32_T rch; + HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma; + + for (rch = 0; rch < HAL_TAU_PKT_RX_CHANNEL_LAST; rch++) + { + ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, rch); + osal_giveSemaphore(&ptr_rx_pdma->sema); + } +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_createIntf( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_NETIF_COOKIE_T *ptr_cookie) +{ + HAL_TAU_PKT_NETIF_INTF_T net_intf = {0}; + HAL_TAU_PKT_NETIF_PORT_DB_T *ptr_port_db; + struct net_device *ptr_net_dev = NULL; + struct net_device_priv *ptr_priv = NULL; + NPS_ERROR_NO_T rc = NPS_E_OK; + + /* Lock all Rx tasks to avoid any access to the intf during packet processing */ + /* Only Rx tasks are locked since Tx action is performed under a spinlock protection */ + _hal_tau_pkt_lockRxChannelAll(unit); + + osal_io_copyFromUser(&net_intf, &ptr_cookie->net_intf, sizeof(HAL_TAU_PKT_NETIF_INTF_T)); + + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_INTF, "u=%u, create intf name=%s, phy port=%d\n", + unit, net_intf.name, net_intf.port); + + /* To check if the interface with the same name exists in kernel */ + ptr_net_dev = dev_get_by_name(&init_net, net_intf.name); + if (NULL != ptr_net_dev) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_INTF), + "u=%u, create intf failed, exist same name=%s\n", + unit, net_intf.name); + + dev_put(ptr_net_dev); + +#if defined(HAL_TAU_PKT_FORCR_REMOVE_DUPLICATE_NETDEV) + ptr_net_dev->operstate = IF_OPER_DOWN; + netif_carrier_off(ptr_net_dev); + netif_stop_queue(ptr_net_dev); + unregister_netdev(ptr_net_dev); + free_netdev(ptr_net_dev); +#endif + _hal_tau_pkt_unlockRxChannelAll(unit); + return (NPS_E_ENTRY_EXISTS); + } + + /* Bind the net dev and intf meta data to internel port-based array */ + ptr_port_db = HAL_TAU_PKT_GET_PORT_DB(net_intf.port); + if (ptr_port_db->ptr_net_dev == NULL) + { + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0) + ptr_net_dev = alloc_netdev(sizeof(struct net_device_priv), + net_intf.name, NET_NAME_UNKNOWN, _hal_tau_pkt_setup); +#else + ptr_net_dev = alloc_netdev(sizeof(struct net_device_priv), + net_intf.name, _hal_tau_pkt_setup); +#endif + memcpy(ptr_net_dev->dev_addr, net_intf.mac, ptr_net_dev->addr_len); + + ptr_priv = netdev_priv(ptr_net_dev); + + /* Port info will be used when packet sent from this netdev */ + ptr_priv->port = net_intf.port; + ptr_priv->id = net_intf.port; + ptr_priv->unit = unit; + + register_netdev(ptr_net_dev); + + net_intf.id = net_intf.port; /* Currently, id is 1-to-1 mapped to port */ + osal_memcpy(&ptr_port_db->meta, &net_intf, sizeof(HAL_TAU_PKT_NETIF_INTF_T)); + + ptr_port_db->ptr_net_dev = ptr_net_dev; + + /* Copy the intf-id to user space */ + osal_io_copyToUser(&ptr_cookie->net_intf, &net_intf, sizeof(HAL_TAU_PKT_NETIF_INTF_T)); + } + else + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_INTF | HAL_TAU_PKT_DBG_ERR), + "u=%u, create intf failed, exist on phy port=%d\n", + unit, net_intf.port); + /* The user needs to delete the existing intf binding to the same port */ + rc = NPS_E_ENTRY_EXISTS; + } + + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + _hal_tau_pkt_unlockRxChannelAll(unit); + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_destroyIntf( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_NETIF_COOKIE_T *ptr_cookie) +{ + HAL_TAU_PKT_NETIF_INTF_T net_intf = {0}; + HAL_TAU_PKT_NETIF_PORT_DB_T *ptr_port_db; + UI32_T port = 0; + NPS_ERROR_NO_T rc = NPS_E_ENTRY_NOT_FOUND; + + /* Lock all Rx tasks to avoid any access to the intf during packet processing */ + /* Only Rx tasks are locked since Tx action is performed under a spinlock protection */ + _hal_tau_pkt_lockRxChannelAll(unit); + + osal_io_copyFromUser(&net_intf, &ptr_cookie->net_intf, sizeof(HAL_TAU_PKT_NETIF_INTF_T)); + + /* Unregister net devices by id, although the "id" is now relavent to "port" we still perform a search */ + for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) + { + ptr_port_db = HAL_TAU_PKT_GET_PORT_DB(port); + if (NULL != ptr_port_db->ptr_net_dev) /* valid intf */ + { + if (ptr_port_db->meta.id == net_intf.id) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_INTF, + "u=%u, find intf %s (id=%d) on phy port=%d, destroy done\n", + unit, + ptr_port_db->meta.name, + ptr_port_db->meta.port); + + netif_carrier_off(ptr_port_db->ptr_net_dev); + netif_stop_queue(ptr_port_db->ptr_net_dev); + unregister_netdev(ptr_port_db->ptr_net_dev); + free_netdev(ptr_port_db->ptr_net_dev); + + /* Don't need to remove profiles on this port. + * In fact, the profile is binding to "port" not "intf". + */ + /* _hal_tau_pkt_destroyProfList(ptr_port_db->ptr_profile_list); */ + + osal_memset(ptr_port_db, 0x0, sizeof(HAL_TAU_PKT_NETIF_PORT_DB_T)); + rc = NPS_E_OK; + break; + } + } + } + + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + _hal_tau_pkt_unlockRxChannelAll(unit); + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_traverseProfList( + UI32_T intf_id, + HAL_TAU_PKT_PROFILE_NODE_T *ptr_prof_list) +{ + HAL_TAU_PKT_PROFILE_NODE_T *ptr_curr_node; + + ptr_curr_node = ptr_prof_list; + + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_INTF, "intf id=%d, prof list=\n", intf_id); + while(NULL != ptr_curr_node) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_INTF, "%s (%d) => ", + ptr_curr_node->ptr_profile->name, + ptr_curr_node->ptr_profile->priority); + ptr_curr_node = ptr_curr_node->ptr_next_node; + } + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_INTF, "null\n"); + return (NPS_E_OK); +} + + +static NPS_ERROR_NO_T +_hal_tau_pkt_getIntf( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_NETIF_COOKIE_T *ptr_cookie) +{ + HAL_TAU_PKT_NETIF_INTF_T net_intf = {0}; + HAL_TAU_PKT_NETIF_PORT_DB_T *ptr_port_db; + UI32_T port = 0; + NPS_ERROR_NO_T rc = NPS_E_ENTRY_NOT_FOUND; + + osal_io_copyFromUser(&net_intf, &ptr_cookie->net_intf, sizeof(HAL_TAU_PKT_NETIF_INTF_T)); + + for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) + { + ptr_port_db = HAL_TAU_PKT_GET_PORT_DB(port); + if (NULL != ptr_port_db->ptr_net_dev) /* valid intf */ + { + if (ptr_port_db->meta.id == net_intf.id) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_INTF, "u=%u, find intf id=%d\n", unit, net_intf.id); + _hal_tau_pkt_traverseProfList(net_intf.id, ptr_port_db->ptr_profile_list); + osal_io_copyToUser(&ptr_cookie->net_intf, &ptr_port_db->meta, sizeof(HAL_TAU_PKT_NETIF_INTF_T)); + rc = NPS_E_OK; + break; + } + } + } + + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + return (NPS_E_OK); +} + +static HAL_TAU_PKT_NETIF_PROFILE_T * +_hal_tau_pkt_getProfEntry( + const UI32_T id) +{ + HAL_TAU_PKT_NETIF_PROFILE_T *ptr_profile = NULL; + + if (id < HAL_TAU_PKT_NET_PROFILE_NUM_MAX) + { + if (NULL != _ptr_hal_tau_pkt_profile_entry[id]) + { + ptr_profile = _ptr_hal_tau_pkt_profile_entry[id]; + } + } + + return (ptr_profile); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_createProfile( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_NETIF_COOKIE_T *ptr_cookie) +{ + HAL_TAU_PKT_NETIF_PROFILE_T *ptr_profile; + HAL_TAU_PKT_NETIF_PORT_DB_T *ptr_port_db; + NPS_ERROR_NO_T rc; + + /* Lock all Rx tasks to avoid profiles being refered during packet processing */ + /* Need to lock all Rx tasks since packets from all Rx channels do profile lookup */ + _hal_tau_pkt_lockRxChannelAll(unit); + + ptr_profile = osal_alloc(sizeof(HAL_TAU_PKT_NETIF_PROFILE_T)); + osal_io_copyFromUser(ptr_profile, &ptr_cookie->net_profile, + sizeof(HAL_TAU_PKT_NETIF_PROFILE_T)); + + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, + "u=%u, create prof name=%s, priority=%d, flag=0x%x\n", + unit, + ptr_profile->name, + ptr_profile->priority, + ptr_profile->flags); + + /* Save the profile to the profile array and assign the index to ptr_profile->id */ + rc = _hal_tau_pkt_allocProfEntry(ptr_profile); + if (NPS_E_OK == rc) + { + /* Insert the profile to the corresponding (port) interface */ + if ((ptr_profile->flags & HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PORT) != 0) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, + "u=%u, bind prof to phy port=%d\n", unit, ptr_profile->port); + ptr_port_db = HAL_TAU_PKT_GET_PORT_DB(ptr_profile->port); + _hal_tau_pkt_addProfToList(ptr_profile, &ptr_port_db->ptr_profile_list); + } + else + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, + "u=%u, bind prof to all intf\n", unit); + _hal_tau_pkt_addProfToAllIntf(ptr_profile); + } + + /* Copy the ptr_profile->id to user space */ + osal_io_copyToUser(&ptr_cookie->net_profile, ptr_profile, sizeof(HAL_TAU_PKT_NETIF_PROFILE_T)); + } + else + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_PROFILE | HAL_TAU_PKT_DBG_ERR), + "u=%u, alloc prof entry failed, tbl full\n", unit); + osal_free(ptr_profile); + } + + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + _hal_tau_pkt_unlockRxChannelAll(unit); + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_destroyProfile( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_NETIF_COOKIE_T *ptr_cookie) +{ + HAL_TAU_PKT_NETIF_PROFILE_T profile = {0}; + HAL_TAU_PKT_NETIF_PROFILE_T *ptr_profile; + NPS_ERROR_NO_T rc = NPS_E_OK; + + /* Lock all Rx tasks to avoid profiles being refered during packet processing */ + /* Need to lock all Rx tasks since packets from all Rx channels do profile lookup */ + _hal_tau_pkt_lockRxChannelAll(unit); + + osal_io_copyFromUser(&profile, &ptr_cookie->net_profile, + sizeof(HAL_TAU_PKT_NETIF_PROFILE_T)); + + /* Remove the profile from corresponding interface (port) */ + _hal_tau_pkt_delProfFromAllIntfById(profile.id); + + ptr_profile = _hal_tau_pkt_freeProfEntry(profile.id); + if (NULL != ptr_profile) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, + "u=%u, destroy prof id=%d, name=%s, priority=%d, flag=0x%x\n", + unit, + ptr_profile->id, + ptr_profile->name, + ptr_profile->priority, + ptr_profile->flags); + osal_free(ptr_profile); + } + + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + _hal_tau_pkt_unlockRxChannelAll(unit); + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_getProfile( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_NETIF_COOKIE_T *ptr_cookie) +{ + HAL_TAU_PKT_NETIF_PROFILE_T profile = {0}; + HAL_TAU_PKT_NETIF_PROFILE_T *ptr_profile; + NPS_ERROR_NO_T rc = NPS_E_OK; + + osal_io_copyFromUser(&profile, &ptr_cookie->net_profile, sizeof(HAL_TAU_PKT_NETIF_PROFILE_T)); + + ptr_profile = _hal_tau_pkt_getProfEntry(profile.id); + if (NULL != ptr_profile) + { + osal_io_copyToUser(&ptr_cookie->net_profile, ptr_profile, sizeof(HAL_TAU_PKT_NETIF_PROFILE_T)); + } + else + { + rc = NPS_E_ENTRY_NOT_FOUND; + } + + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_getIntfCnt( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_NETIF_COOKIE_T *ptr_cookie) +{ + HAL_TAU_PKT_NETIF_INTF_T net_intf = {0}; + HAL_TAU_PKT_NETIF_INTF_CNT_T intf_cnt = {0}; + HAL_TAU_PKT_NETIF_PORT_DB_T *ptr_port_db; + struct net_device_priv *ptr_priv; + UI32_T port = 0; + NPS_ERROR_NO_T rc = NPS_E_ENTRY_NOT_FOUND; + + osal_io_copyFromUser(&net_intf, &ptr_cookie->net_intf, sizeof(HAL_TAU_PKT_NETIF_INTF_T)); + + for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) + { + ptr_port_db = HAL_TAU_PKT_GET_PORT_DB(port); + if (NULL != ptr_port_db->ptr_net_dev) /* valid intf */ + { + if (ptr_port_db->meta.id == net_intf.id) + { + ptr_priv = netdev_priv(ptr_port_db->ptr_net_dev); + intf_cnt.rx_pkt = ptr_priv->stats.rx_packets; + intf_cnt.tx_pkt = ptr_priv->stats.tx_packets; + intf_cnt.tx_error = ptr_priv->stats.tx_errors; + intf_cnt.tx_queue_full = ptr_priv->stats.tx_fifo_errors; + + rc = NPS_E_OK; + break; + } + } + } + + osal_io_copyToUser(&ptr_cookie->cnt, &intf_cnt, sizeof(HAL_TAU_PKT_NETIF_INTF_CNT_T)); + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_clearIntfCnt( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_NETIF_COOKIE_T *ptr_cookie) +{ + HAL_TAU_PKT_NETIF_INTF_T net_intf = {0}; + HAL_TAU_PKT_NETIF_PORT_DB_T *ptr_port_db; + struct net_device_priv *ptr_priv; + UI32_T port = 0; + NPS_ERROR_NO_T rc = NPS_E_ENTRY_NOT_FOUND; + + osal_io_copyFromUser(&net_intf, &ptr_cookie->net_intf, sizeof(HAL_TAU_PKT_NETIF_INTF_T)); + + for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) + { + ptr_port_db = HAL_TAU_PKT_GET_PORT_DB(port); + if (NULL != ptr_port_db->ptr_net_dev) /* valid intf */ + { + if (ptr_port_db->meta.id == net_intf.id) + { + ptr_priv = netdev_priv(ptr_port_db->ptr_net_dev); + ptr_priv->stats.rx_packets = 0; + ptr_priv->stats.tx_packets = 0; + ptr_priv->stats.tx_errors = 0; + ptr_priv->stats.tx_fifo_errors = 0; + + rc = NPS_E_OK; + break; + } + } + } + + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + return (NPS_E_OK); +} + +/* ----------------------------------------------------------------------------------- Init: dev_ops */ +static int +_hal_tau_pkt_dev_open( + struct inode *inode, + struct file *file) +{ + return (0); +} + +static int +_hal_tau_pkt_dev_close( + struct inode *inode, + struct file *file) +{ + return (0); +} + +static void +_hal_tau_pkt_dev_tx_callback( + const UI32_T unit, + HAL_TAU_PKT_TX_SW_GPD_T *ptr_sw_gpd, + HAL_TAU_PKT_TX_SW_GPD_T *ptr_sw_gpd_usr) +{ + UI32_T channel = ptr_sw_gpd->channel; + HAL_TAU_PKT_TX_CB_T *ptr_tx_cb = HAL_TAU_PKT_GET_TX_CB_PTR(unit); + + while (0 != _hal_tau_pkt_enQueue(&ptr_tx_cb->sw_queue, ptr_sw_gpd)) + { + ptr_tx_cb->cnt.channel[channel].enque_retry++; + HAL_TAU_PKT_TX_ENQUE_RETRY_SLEEP(); + } + ptr_tx_cb->cnt.channel[channel].enque_ok++; + + osal_triggerEvent(&ptr_tx_cb->sync_sema); + ptr_tx_cb->cnt.channel[channel].trig_event++; +} + +static ssize_t +_hal_tau_pkt_dev_tx( + struct file *file, + const char __user *buf, + size_t count, + loff_t *pos) +{ + int ret = 0; + int idx = 0; + unsigned int unit = 0; + unsigned int channel = 0; + HAL_TAU_PKT_IOCTL_TX_COOKIE_T tx_cookie; + HAL_TAU_PKT_IOCTL_TX_GPD_T ioctl_gpd; + HAL_TAU_PKT_TX_SW_GPD_T *ptr_sw_gpd_knl = NULL; + HAL_TAU_PKT_TX_SW_GPD_T *ptr_first_sw_gpd_knl = NULL; + + /* copy the tx-cookie */ + osal_io_copyFromUser(&tx_cookie, (void *)buf, sizeof(HAL_TAU_PKT_IOCTL_TX_COOKIE_T)); + + unit = tx_cookie.unit; + channel = tx_cookie.channel; + + ptr_sw_gpd_knl = osal_alloc(sizeof(HAL_TAU_PKT_TX_SW_GPD_T)); + ptr_first_sw_gpd_knl = ptr_sw_gpd_knl; + + /* create SW GPD based on the content of each IOCTL GPD */ + while (1) + { + osal_io_copyFromUser(&ioctl_gpd, + ((void *)((NPS_HUGE_T)tx_cookie.ioctl_gpd_addr)) + +idx*sizeof(HAL_TAU_PKT_IOCTL_TX_GPD_T), + sizeof(HAL_TAU_PKT_IOCTL_TX_GPD_T)); + + ptr_sw_gpd_knl->channel = ioctl_gpd.channel; + ptr_sw_gpd_knl->gpd_num = ioctl_gpd.gpd_num; + ptr_sw_gpd_knl->ptr_cookie = (void *)ioctl_gpd.cookie; + + /* directly copy user's HW GPD */ + osal_io_copyFromUser(&ptr_sw_gpd_knl->tx_gpd, + (void *)((NPS_HUGE_T)ioctl_gpd.hw_gpd_addr), + sizeof(HAL_TAU_PKT_TX_GPD_T)); + + /* replace the callback */ + ptr_sw_gpd_knl->callback = (void *)_hal_tau_pkt_dev_tx_callback; + + /* save the first SW GPD address from userspace since + * we have replaced the original callback + */ + ptr_sw_gpd_knl->ptr_cookie = (void *)ioctl_gpd.sw_gpd_addr; + + if (HAL_TAU_PKT_CH_LAST_GPD == ptr_sw_gpd_knl->tx_gpd.ch) + { + ptr_sw_gpd_knl->ptr_next = NULL; + break; + } + else + { + ptr_sw_gpd_knl->ptr_next = (HAL_TAU_PKT_TX_SW_GPD_T *)osal_alloc( + sizeof(HAL_TAU_PKT_TX_SW_GPD_T)); + ptr_sw_gpd_knl = ptr_sw_gpd_knl->ptr_next; + idx++; + } + } + + ret = hal_tau_pkt_sendGpd(unit, channel, ptr_first_sw_gpd_knl); + if (NPS_E_OK != ret) + { + _hal_tau_pkt_freeTxGpdList(unit, ptr_first_sw_gpd_knl); + } + + /* return 0 if success */ + return (ret); +} + +static ssize_t +_hal_tau_pkt_dev_rx( + struct file *file, + char __user *buf, + size_t count, + loff_t *pos) +{ + return (0); +} + +static long +_hal_tau_pkt_dev_ioctl( + struct file *filp, + unsigned int cmd, + unsigned long arg) +{ + int ret = 0; + + /* cmd */ + HAL_TAU_PKT_IOCTL_CMD_T *ptr_cmd = (HAL_TAU_PKT_IOCTL_CMD_T *)&cmd; + unsigned int unit = ptr_cmd->field.unit; + HAL_TAU_PKT_IOCTL_TYPE_T type = ptr_cmd->field.type; + + switch (type) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_COMMON, "u=%u, ioctl type=%u, cmd=%u\n", + unit, type, cmd); + + /* network interface */ + case HAL_TAU_PKT_IOCTL_TYPE_CREATE_INTF: + ret = _hal_tau_pkt_createIntf(unit, (HAL_TAU_PKT_IOCTL_NETIF_COOKIE_T *)arg); + break; + + case HAL_TAU_PKT_IOCTL_TYPE_DESTROY_INTF: + ret = _hal_tau_pkt_destroyIntf(unit, (HAL_TAU_PKT_IOCTL_NETIF_COOKIE_T *)arg); + break; + + case HAL_TAU_PKT_IOCTL_TYPE_GET_INTF: + ret = _hal_tau_pkt_getIntf(unit, (HAL_TAU_PKT_IOCTL_NETIF_COOKIE_T *)arg); + break; + + case HAL_TAU_PKT_IOCTL_TYPE_CREATE_PROFILE: + ret = _hal_tau_pkt_createProfile(unit, (HAL_TAU_PKT_IOCTL_NETIF_COOKIE_T *)arg); + break; + + case HAL_TAU_PKT_IOCTL_TYPE_DESTROY_PROFILE: + ret = _hal_tau_pkt_destroyProfile(unit, (HAL_TAU_PKT_IOCTL_NETIF_COOKIE_T *)arg); + break; + + case HAL_TAU_PKT_IOCTL_TYPE_GET_PROFILE: + ret = _hal_tau_pkt_getProfile(unit, (HAL_TAU_PKT_IOCTL_NETIF_COOKIE_T *)arg); + break; + + case HAL_TAU_PKT_IOCTL_TYPE_GET_INTF_CNT: + ret = _hal_tau_pkt_getIntfCnt(unit, (HAL_TAU_PKT_IOCTL_NETIF_COOKIE_T *)arg); + break; + + case HAL_TAU_PKT_IOCTL_TYPE_CLEAR_INTF_CNT: + ret = _hal_tau_pkt_clearIntfCnt(unit, (HAL_TAU_PKT_IOCTL_NETIF_COOKIE_T *)arg); + break; + + /* driver */ + case HAL_TAU_PKT_IOCTL_TYPE_WAIT_RX_FREE: + ret = _hal_tau_pkt_schedRxDeQueue(unit, (HAL_TAU_PKT_IOCTL_RX_COOKIE_T *)arg); + break; + + case HAL_TAU_PKT_IOCTL_TYPE_WAIT_TX_FREE: + ret = _hal_tau_pkt_strictTxDeQueue(unit, (HAL_TAU_PKT_IOCTL_TX_COOKIE_T *)arg); + break; + + case HAL_TAU_PKT_IOCTL_TYPE_SET_RX_CFG: + ret = hal_tau_pkt_setRxKnlConfig(unit, (HAL_TAU_PKT_IOCTL_RX_COOKIE_T *)arg); + break; + + case HAL_TAU_PKT_IOCTL_TYPE_GET_RX_CFG: + ret = hal_tau_pkt_getRxKnlConfig(unit, (HAL_TAU_PKT_IOCTL_RX_COOKIE_T *)arg); + break; + + case HAL_TAU_PKT_IOCTL_TYPE_DEINIT_TASK: + ret = hal_tau_pkt_deinitTask(unit); + break; + + case HAL_TAU_PKT_IOCTL_TYPE_DEINIT_DRV: + ret = hal_tau_pkt_deinitPktDrv(unit); + break; + + case HAL_TAU_PKT_IOCTL_TYPE_INIT_TASK: + ret = hal_tau_pkt_initTask(unit); + break; + + case HAL_TAU_PKT_IOCTL_TYPE_INIT_DRV: + ret = hal_tau_pkt_initPktDrv(unit); + break; + + /* counter */ + case HAL_TAU_PKT_IOCTL_TYPE_GET_TX_CNT: + ret = hal_tau_pkt_getTxKnlCnt(unit, (HAL_TAU_PKT_IOCTL_CH_CNT_COOKIE_T *)arg); + break; + + case HAL_TAU_PKT_IOCTL_TYPE_GET_RX_CNT: + ret = hal_tau_pkt_getRxKnlCnt(unit, (HAL_TAU_PKT_IOCTL_CH_CNT_COOKIE_T *)arg); + break; + + case HAL_TAU_PKT_IOCTL_TYPE_CLEAR_TX_CNT: + ret = hal_tau_pkt_clearTxKnlCnt(unit, (HAL_TAU_PKT_IOCTL_TX_COOKIE_T *)arg); + break; + + case HAL_TAU_PKT_IOCTL_TYPE_CLEAR_RX_CNT: + ret = hal_tau_pkt_clearRxKnlCnt(unit, (HAL_TAU_PKT_IOCTL_RX_COOKIE_T *)arg); + break; + + case HAL_TAU_PKT_IOCTL_TYPE_SET_PORT_ATTR: + ret = hal_tau_pkt_setPortAttr(unit, (HAL_TAU_PKT_IOCTL_PORT_COOKIE_T *)arg); + break; + + default: + ret = -1; + break; + } + + return (ret); +} + +#ifdef CONFIG_COMPAT +static long +_hal_tau_pkt_dev_compat_ioctl( + struct file *filp, + unsigned int cmd, + unsigned long arg) +{ + return _hal_tau_pkt_dev_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); +} +#endif + +static struct file_operations _hal_tau_pkt_dev_ops = +{ + .owner = THIS_MODULE, + .open = _hal_tau_pkt_dev_open, + .release = _hal_tau_pkt_dev_close, + .write = _hal_tau_pkt_dev_tx, + .read = _hal_tau_pkt_dev_rx, + .unlocked_ioctl = _hal_tau_pkt_dev_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = _hal_tau_pkt_dev_compat_ioctl, +#endif +}; + +static struct miscdevice _hal_tau_pkt_dev = +{ + .minor = HAL_TAU_PKT_DRIVER_MINOR_NUM, + .name = HAL_TAU_PKT_DRIVER_NAME, + .fops = &_hal_tau_pkt_dev_ops, +}; + +/* ----------------------------------------------------------------------------------- Init/Deinit */ +static int __init +_hal_tau_pkt_init(void) +{ + /* Register device */ + misc_register(&_hal_tau_pkt_dev); + + /* Init Thread */ + osal_init(); + + /* Reset all database*/ + osal_memset(_hal_tau_pkt_port_db, 0x0, + (HAL_TAU_PKT_MAX_PORT_NUM * sizeof(HAL_TAU_PKT_NETIF_PORT_DB_T))); + osal_memset(_hal_tau_pkt_rx_cb, 0x0, + NPS_CFG_MAXIMUM_CHIPS_PER_SYSTEM*sizeof(HAL_TAU_PKT_RX_CB_T)); + osal_memset(_hal_tau_pkt_tx_cb, 0x0, + NPS_CFG_MAXIMUM_CHIPS_PER_SYSTEM*sizeof(HAL_TAU_PKT_TX_CB_T)); + osal_memset(_hal_tau_pkt_drv_cb, 0x0, + NPS_CFG_MAXIMUM_CHIPS_PER_SYSTEM*sizeof(HAL_TAU_PKT_DRV_CB_T)); + + return (0); +} + +static void __exit +_hal_tau_pkt_exit(void) +{ + UI32_T unit = 0; + + /* 1st. Stop Rx HW DMA and free all the DMA buffer hooked on the ring */ + _hal_tau_pkt_rxStop(unit); + + /* 2nd. Need to wait Rx done task process all the availavle packets on GPD ring */ +#define HAL_TAU_PKT_MODULE_EXIT_HOLD_TIME_US (1000000) + osal_sleepThread(HAL_TAU_PKT_MODULE_EXIT_HOLD_TIME_US); + + /* 3rd. Stop all netdev (if any) to prevent kernel from Tx new packets */ + _hal_tau_pkt_stopAllIntf(unit); + + /* 4th. Stop all the internal tasks (if any) */ + hal_tau_pkt_deinitTask(unit); + + /* 5th. Deinit pkt driver for common database/interrupt source (if required) */ + hal_tau_pkt_deinitPktDrv(unit); + + /* 6th. Clean up those intf/profiles not been destroyed */ + _hal_tau_pkt_destroyAllProfile(unit); + _hal_tau_pkt_destroyAllIntf(unit); + + osal_deinit(); + + /* Unregister device */ + misc_deregister(&_hal_tau_pkt_dev); +} + +module_init(_hal_tau_pkt_init); +module_exit(_hal_tau_pkt_exit); + +module_param(dbg_flag, uint, S_IRUGO); +MODULE_PARM_DESC(dbg_flag, "bit0:Error, bit1:Tx, bit2:Rx, bit3:Intf, bit4:Profile"); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Nephos"); +MODULE_DESCRIPTION("NETIF Kernel Module"); diff --git a/platform/nephos/nephos-modules/modules/src/inc/aml.h b/platform/nephos/nephos-modules/modules/src/inc/aml.h new file mode 100755 index 000000000000..658aa6e56f46 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/inc/aml.h @@ -0,0 +1,366 @@ +/* Copyright (C) 2019 Nephos, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program. + */ + +/* FILE NAME: aml.h + * PURPOSE: + * 1. Provide whole AML resource initialization API. + * 2. Provide configuration access APIs. + * 3. Provide ISR registration and deregistration APIs. + * 4. Provide memory access. + * 5. Provide DMA management APIs. + * 6. Provide address translation APIs. + * NOTES: + */ + +#ifndef AML_H +#define AML_H + + +/* INCLUDE FILE DECLARATIONS + */ +#include +#include +#include + + +/* NAMING CONSTANT DECLARATIONS + */ + +/* #define AML_EN_I2C */ +/* #define AML_EN_CUSTOM_DMA_ADDR */ + +/* MACRO FUNCTION DECLARATIONS + */ + +/* DATA TYPE DECLARATIONS + */ +typedef enum +{ + AML_DEV_TYPE_PCI, + AML_DEV_TYPE_I2C, + AML_DEV_TYPE_SPI, + AML_DEV_TYPE_LAST + +} AML_HW_IF_T; + +typedef NPS_ERROR_NO_T +(*AML_DEV_READ_FUNC_T)( + const UI32_T unit, + const UI32_T addr_offset, + UI32_T *ptr_data, + const UI32_T len); + +typedef NPS_ERROR_NO_T +(*AML_DEV_WRITE_FUNC_T)( + const UI32_T unit, + const UI32_T addr_offset, + const UI32_T *ptr_data, + const UI32_T len); + +typedef NPS_ERROR_NO_T +(*AML_DEV_ISR_FUNC_T)( + void *ptr_data); + +/* To mask the chip interrupt in kernel interrupt routine. */ +typedef struct +{ + UI32_T mask_addr; + UI32_T mask_val; + +} AML_DEV_ISR_DATA_T; + +/* To read or write the HW-intf registers. */ +typedef struct +{ + AML_DEV_READ_FUNC_T read_callback; + AML_DEV_WRITE_FUNC_T write_callback; + +} AML_DEV_ACCESS_T; + +typedef struct +{ + UI32_T vendor; + UI32_T device; + UI32_T revision; + +} AML_DEV_ID_T; + + +typedef struct +{ + AML_HW_IF_T if_type; + AML_DEV_ID_T id; + AML_DEV_ACCESS_T access; + +} AML_DEV_T; + +/* EXPORTED SUBPROGRAM SPECIFICATIONS + */ + +/* FUNCTION NAME: aml_getRunMode + * PURPOSE: + * To get current SDK running mode. + * INPUT: + * unit -- the device unit + * OUTPUT: + * ptr_mode -- current running mode + * RETURN: + * NPS_E_OK -- Successfully get the running mode. + * NOTES: + * none + */ +NPS_ERROR_NO_T +aml_getRunMode( + const UI32_T unit, + UI32_T *ptr_mode); + +/* FUNCTION NAME: aml_init + * PURPOSE: + * To initialize the DMA memory and interface-related kernel source + * such as PCIe/I2C/SPI. + * INPUT: + * none + * OUTPUT: + * none + * RETURN: + * NPS_E_OK -- Successfully initialize AML module. + * NPS_E_OTHERS -- Failed to initialize AML module. + * NOTES: + * none + */ +NPS_ERROR_NO_T +aml_deinit(void); + +/* FUNCTION NAME: aml_init + * PURPOSE: + * To initialize the DMA memory and interface-related kernel source + * such as PCIe/I2C/SPI. + * INPUT: + * none + * OUTPUT: + * none + * RETURN: + * NPS_E_OK -- Successfully initialize AML module. + * NPS_E_OTHERS -- Failed to initialize AML module. + * NOTES: + * none + */ +NPS_ERROR_NO_T +aml_init(void); + +/* FUNCTION NAME: aml_getNumberOfChip + * PURPOSE: + * To get the number of chips connected to host CPU. + * INPUT: + * none + * OUTPUT: + * ptr_num -- pointer for the chip number + * RETURN: + * NPS_E_OK -- Successfully get the number of chips. + * NOTES: + * none + */ +NPS_ERROR_NO_T +aml_getNumberOfChip( + UI32_T *ptr_num); + +/* FUNCTION NAME: aml_connectIsr + * PURPOSE: + * To enable the system intterupt and specify the ISR handler. + * INPUT: + * unit -- the device unit + * handler -- the ISR hanlder + * ptr_cookie -- pointer for the data as an argument of the handler + * OUTPUT: + * none + * RETURN: + * NPS_E_OK -- Successfully connect the ISR handler to the system. + * NPS_E_OTHERS -- Failed to connect the ISR handler to the system. + * NOTES: + * none + */ +NPS_ERROR_NO_T +aml_connectIsr( + const UI32_T unit, + AML_DEV_ISR_FUNC_T handler, + AML_DEV_ISR_DATA_T *ptr_cookie); + +/* FUNCTION NAME: aml_disconnectIsr + * PURPOSE: + * To disable the system intterupt notification. + * INPUT: + * unit -- the device unit + * OUTPUT: + * none + * RETURN: + * NPS_E_OK -- Successfully disconnect the ISR handler to the system. + * NPS_E_OTHERS -- Failed to disconnect the ISR handler to the system. + * NOTES: + * none + */ +NPS_ERROR_NO_T +aml_disconnectIsr( + const UI32_T unit); + +/* FUNCTION NAME: aml_getDeviceId + * PURPOSE: + * To get the vendor/device/revision ID of the specified chip unit. + * INPUT: + * unit -- the device unit + * OUTPUT: + * ptr_vendor_id -- pointer for the vendor ID + * ptr_device_id -- pointer for the device ID + * ptr_revision_id -- pointer for the revision ID + * RETURN: + * NPS_E_OK -- Successfully get the IDs. + * NPS_E_OTHERS -- Failed to get the IDs. + * NOTES: + * none + */ +NPS_ERROR_NO_T +aml_getDeviceId( + const UI32_T unit, + UI32_T *ptr_vendor_id, + UI32_T *ptr_device_id, + UI32_T *ptr_revision_id); + +/* FUNCTION NAME: aml_readReg + * PURPOSE: + * To read data from the register of the specified chip unit. + * INPUT: + * unit -- the device unit + * addr_offset -- the address of register + * len -- data size read + * OUTPUT: + * ptr_data -- pointer for the register data + * RETURN: + * NPS_E_OK -- Successfully read the data. + * NPS_E_OTHERS -- Failed to read the data. + * NOTES: + * none + */ +NPS_ERROR_NO_T +aml_readReg( + const UI32_T unit, + const UI32_T addr_offset, + UI32_T *ptr_data, + const UI32_T len); + +/* FUNCTION NAME: aml_writeReg + * PURPOSE: + * To write data to the register of the specified chip unit. + * INPUT: + * unit -- the device unit + * addr_offset -- the address of register + * ptr_data -- pointer for the written data + * len -- data size read + * OUTPUT: + * none + * RETURN: + * NPS_E_OK -- Successfully write the data. + * NPS_E_OTHERS -- Failed to write the data. + * NOTES: + * none + */ +NPS_ERROR_NO_T +aml_writeReg( + const UI32_T unit, + const UI32_T addr_offset, + const UI32_T *ptr_data, + const UI32_T len); + +/* FUNCTION NAME: aml_convertVirtToPhy + * PURPOSE: + * To get the physical address of the corresponding virtual + * address input. + * INPUT: + * ptr_virt_addr -- pointer to the virtual address + * OUTPUT: + * ptr_phy_addr -- pointer to the physical address + * RETURN: + * NPS_E_OK -- Successfully convert the address. + * NPS_E_OTHERS -- Failed to convert the address. + * The memory might be not allocated by AML. + * NOTES: + * none + */ +NPS_ERROR_NO_T +aml_convertVirtToPhy( + void *ptr_virt_addr, + NPS_ADDR_T *ptr_phy_addr); + +/* FUNCTION NAME: aml_convertPhyToVirt + * PURPOSE: + * To get the virtual address of the corresponding physical + * address input. + * INPUT: + * ptr_virt_addr -- pointer for the physical address + * OUTPUT: + * pptr_virt_addr -- pointer for the virtual address pointer + * RETURN: + * NPS_E_OK -- Successfully convert the address. + * NPS_E_OTHERS -- Failed to convert the address. + * The memory might be not allocated by AML. + * NOTES: + * none + */ +NPS_ERROR_NO_T +aml_convertPhyToVirt( + const NPS_ADDR_T phy_addr, + void **pptr_virt_addr); + +/* FUNCTION NAME: aml_flushCache + * PURPOSE: + * To update the data from CPU cache to the physical memory. + * INPUT: + * ptr_virt_addr -- pointer for the data + * size -- target data size to be updated + * OUTPUT: + * none + * RETURN: + * NPS_E_OK -- Successfully update the data from CPU cache + * to the physical memory. + * NPS_E_OTHERS -- Failed to pdate the data from CPU cache + * to the physical memory. + * NOTES: + * none + */ +NPS_ERROR_NO_T +aml_flushCache( + void *ptr_virt_addr, + const UI32_T size); + +/* FUNCTION NAME: aml_invalidateCache + * PURPOSE: + * To update the data from physical memory to the CPU cache. + * INPUT: + * ptr_virt_addr -- pointer for the data + * size -- target data size to be updated + * OUTPUT: + * none + * RETURN: + * NPS_E_OK -- Successfully update the data from physical memory + * to the CPU cache. + * NPS_E_OTHERS -- Failed to pdate the data from physical memory + * to the CPU cache. + * NOTES: + * none + */ +NPS_ERROR_NO_T +aml_invalidateCache( + void *ptr_virt_addr, + const UI32_T size); + +#endif /* #ifndef AML_H */ diff --git a/platform/nephos/nephos-modules/modules/src/inc/hal_dev.h b/platform/nephos/nephos-modules/modules/src/inc/hal_dev.h new file mode 100755 index 000000000000..edd582adc197 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/inc/hal_dev.h @@ -0,0 +1,48 @@ +/* Copyright (C) 2019 Nephos, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program. + */ + +/* FILE NAME: hal_dev.h + * PURPOSE: + * Provide a list of device IDs. + * + * NOTES: + */ + +#ifndef HAL_DEV_H +#define HAL_DEV_H + +/* INCLUDE FILE DECLARATIONS + */ +/* NAMING CONSTANT DECLARATIONS + */ +#define HAL_MTK_VENDOR_ID (0x0E8D) +#define HAL_NP_VENDOR_ID (0x1D9F) + +#define HAL_DEVICE_ID_MT3257 (0x3257) +#define HAL_DEVICE_ID_MT3258 (0x3258) + +#define HAL_DEVICE_ID_NP8363 (0x8363) /* 1.08T 1Bin */ +#define HAL_DEVICE_ID_NP8365 (0x8365) /* 1.8T 1Bin */ +#define HAL_DEVICE_ID_NP8366 (0x8366) /* 2.4T 1Bin */ +#define HAL_DEVICE_ID_NP8367 (0x8367) /* 3.2T 1Bin */ +#define HAL_DEVICE_ID_NP8368 (0x8368) /* 3.2T 2Bin */ +#define HAL_DEVICE_ID_NP8369 (0x8369) /* 6.4T 2Bin */ + +#define HAL_REVISION_ID_E1 (0x01) +#define HAL_REVISION_ID_E2 (0x02) + +#define HAL_INVALID_DEVICE_ID (0xFFFFFFFF) + +#endif /* #ifndef HAL_DEV_H */ diff --git a/platform/nephos/nephos-modules/modules/src/inc/hal_tau_pkt_knl.h b/platform/nephos/nephos-modules/modules/src/inc/hal_tau_pkt_knl.h new file mode 100755 index 000000000000..96a8cf6441f0 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/inc/hal_tau_pkt_knl.h @@ -0,0 +1,2302 @@ +/* Copyright (C) 2019 Nephos, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program. + */ + +/* FILE NAME: hal_tau_pkt_knl.h + * PURPOSE: + * To provide Linux kernel for PDMA TX/RX control. + * + * NOTES: + */ + +#ifndef HAL_TAU_PKT_KNL_H +#define HAL_TAU_PKT_KNL_H + + +/* CP_COMMON */ +#define HAL_TAU_PKT_CP_COMMON_INT_EN_HI (0x012C0000) +#define HAL_TAU_PKT_CP_COMMON_INT_LO_HI (0x012C0004) +#define HAL_TAU_PKT_CP_COMMON_INT_LVL_HI (0x012C0008) +#define HAL_TAU_PKT_CP_COMMON_INT_LVL_LO (0x012C000C) +#define HAL_TAU_PKT_CP_COMMON_INT_MASK_SET_HI (0x012C0010) +#define HAL_TAU_PKT_CP_COMMON_INT_MASK_SET_LO (0x012C0014) +#define HAL_TAU_PKT_CP_COMMON_INT_MASK_CLR_HI (0x012C0018) +#define HAL_TAU_PKT_CP_COMMON_INT_MASK_CLR_LO (0x012C001C) +#define HAL_TAU_PKT_CP_COMMON_INT_MASK_VAL_HI (0x012C0020) +#define HAL_TAU_PKT_CP_COMMON_INT_MASK_VAL_LO (0x012C0024) +#define HAL_TAU_PKT_CP_COMMON_INT_STAT_HI (0x012C0028) +#define HAL_TAU_PKT_CP_COMMON_INT_STAT_LO (0x012C002C) +#define HAL_TAU_PKT_CP_COMMON_INT_CLR_HI (0x012C0030) +#define HAL_TAU_PKT_CP_COMMON_INT_CLR_LO (0x012C0034) +#define HAL_TAU_PKT_CP_COMMON_INT_SET_HI (0x012C0038) +#define HAL_TAU_PKT_CP_COMMON_INT_SET_LO (0x012C003C) + +/* PDMA */ +#define HAL_TAU_PKT_PDMA_ERR_INT_STAT (0x013F1000) +#define HAL_TAU_PKT_PDMA_ERR_INT_CLR (0x013F1004) +#define HAL_TAU_PKT_PDMA_ERR_INT_EN (0x013F1010) +#define HAL_TAU_PKT_PDMA_ERR_INT_LVL (0x013F1014) +#define HAL_TAU_PKT_PDMA_ERR_INT_MASK_SET (0x013F1018) +#define HAL_TAU_PKT_PDMA_ERR_INT_MASK_CLR (0x013F101C) +#define HAL_TAU_PKT_PDMA_ERR_INT_MASK_VAL (0x013F1020) +#define HAL_TAU_PKT_PDMA_ERR_INT_SET (0x013F1024) +#define HAL_TAU_PKT_PDMA_CREDIT_CFG (0x013F1100) + +/* Rx */ +#define HAL_TAU_PKT_PDMA_RCH_GPD_RING_START_ADDR_LO (0x013F12E4) +#define HAL_TAU_PKT_PDMA_RCH_GPD_RING_START_ADDR_HI (0x013F12E8) +#define HAL_TAU_PKT_PDMA_RCH_GPD_RING_SIZE (0x013F12EC) +#define HAL_TAU_PKT_PDMA_RCH_CMD (0x013F1300) +#define HAL_TAU_PKT_PDMA_RCH_INT_EN (0x013F1360) +#define HAL_TAU_PKT_PDMA_RCH_INT_LVL (0x013F1364) +#define HAL_TAU_PKT_PDMA_RCH_INT_MASK (0x013F1368) +#define HAL_TAU_PKT_PDMA_RCH_INT_SET (0x013F1370) +#define HAL_TAU_PKT_PDMA_RCH_INT_CLR (0x013F1374) +#define HAL_TAU_PKT_PDMA_RCH_INT_STAT (0x013F1378) + +/* Tx */ +#define HAL_TAU_PKT_PDMA_TCH_GPD_RING_START_ADDR_LO (0x013F1A00) +#define HAL_TAU_PKT_PDMA_TCH_GPD_RING_START_ADDR_HI (0x013F1A04) +#define HAL_TAU_PKT_PDMA_TCH_GPD_RING_SIZE (0x013F1A08) +#define HAL_TAU_PKT_PDMA_TCH_CMD (0x013F1A20) +#define HAL_TAU_PKT_PDMA_TCH_INT_EN (0x013F1A40) +#define HAL_TAU_PKT_PDMA_TCH_INT_LVL (0x013F1A44) +#define HAL_TAU_PKT_PDMA_TCH_INT_MASK (0x013F1A48) +#define HAL_TAU_PKT_PDMA_TCH_INT_SET (0x013F1A50) +#define HAL_TAU_PKT_PDMA_TCH_INT_CLR (0x013F1A54) +#define HAL_TAU_PKT_PDMA_TCH_INT_STAT (0x013F1A58) + +#define HAL_TAU_PKT_GET_MMIO(__tbl__) (0x00FFFFFF & (__tbl__)) +#define HAL_TAU_PKT_GET_PDMA_RCH_REG(__tbl__, __channel__) ((__tbl__) + (0x200 * (__channel__))) +#define HAL_TAU_PKT_GET_PDMA_TCH_REG(__tbl__, __channel__) ((__tbl__) + (0x100 * (__channel__))) + + + +#define NPS_NETIF_NAME_LEN (16) +#define NPS_NETIF_PROFILE_NUM_MAX (256) +#define NPS_NETIF_PROFILE_PATTERN_NUM (4) +#define NPS_NETIF_PROFILE_PATTERN_LEN (8) + +/* nps_port.h */ +typedef enum +{ + NPS_PORT_SPEED_1G = 1000, + NPS_PORT_SPEED_10G = 10000, + NPS_PORT_SPEED_25G = 25000, + NPS_PORT_SPEED_40G = 40000, + NPS_PORT_SPEED_50G = 50000, + NPS_PORT_SPEED_100G = 100000, + NPS_PORT_SPEED_200G = 200000, + NPS_PORT_SPEED_400G = 400000, + NPS_PORT_SPEED_LAST +} NPS_PORT_SPEED_T; + + +/* hal_tau_const.h */ +#define HAL_TAU_PORT_NUM (128) +#define HAL_TAU_EXCPT_CPU_NUM (256) +#define HAL_TAU_INVALID_NVO3_ENCAP_IDX (0x3FFF) +#define HAL_TAU_INVALID_NVO3_ADJ_IDX (0xFF) +#define HAL_TAU_EXCPT_CPU_BASE_ID (28 * 1024) +#define HAL_TAU_EXCPT_CPU_NON_L3_MIN (0) +#define HAL_TAU_EXCPT_CPU_NON_L3_MAX (HAL_TAU_EXCPT_CPU_NON_L3_MIN + HAL_TAU_EXCPT_CPU_NUM - 1) +#define HAL_TAU_EXCPT_CPU_L3_MIN (HAL_TAU_EXCPT_CPU_NON_L3_MIN + HAL_TAU_EXCPT_CPU_NUM) +#define HAL_TAU_EXCPT_CPU_L3_MAX (HAL_TAU_EXCPT_CPU_L3_MIN + HAL_TAU_EXCPT_CPU_NUM - 1) + +/* hal_tau_pkt_rsrc.h */ +#define HAL_TAU_PKT_IPP_EXCPT_LAST (256) +#define HAL_TAU_PKT_EPP_EXCPT_LAST (64) + +#define HAL_TAU_PKT_IPP_EXCPT_IEV_SDK_REDIRECT_TO_CPU_L2UC \ + (192 + IEV_CFG_EXCPT_EN_W1_SDK_REDIRECT_TO_CPU_L2UC_FIELD_ID ) +#define HAL_TAU_PKT_IPP_EXCPT_IEV_SDK_REDIRECT_TO_CPU_L3UC \ + (192 + IEV_CFG_EXCPT_EN_W1_SDK_REDIRECT_TO_CPU_L3UC_FIELD_ID ) +#define HAL_TAU_PKT_IPP_EXCPT_IEV_SDK_L3UC_DA_MISS \ + (192 + IEV_CFG_EXCPT_EN_W1_SDK_L3UC_DA_MISS_FIELD_ID ) +#define HAL_TAU_PKT_IPP_EXCPT_IEV_SDK_L3MC_PIM_REGISTER \ + (192 + IEV_CFG_EXCPT_EN_W1_SDK_L3MC_PIM_REGISTER_FIELD_ID ) +#define HAL_TAU_PKT_IPP_EXCPT_IEV_SDK_FLEX_DECAP_0_REASON_0 \ + (224 + IEV_CFG_EXCPT_EN_W0_SDK_FLEX_DECAP_0_REASON_0_FIELD_ID) + +/* offset of ITM_RSLT_CPU_CP */ +#define HAL_TAU_PKT_IPP_COPY2CPU_OFFSET (16) +#define HAL_TAU_PKT_EPP_COPY2CPU_OFFSET (32) + +typedef UI32_T HAL_TAU_PKT_IPP_EXCPT_T; +typedef UI32_T HAL_TAU_PKT_EPP_EXCPT_T; + +typedef enum +{ + HAL_TAU_PKT_IPP_L3_EXCPT_FCOE_ZONING = 0, + HAL_TAU_PKT_IPP_L3_EXCPT_RPF, + HAL_TAU_PKT_IPP_L3_EXCPT_ICMP_REDIR, + HAL_TAU_PKT_IPP_L3_EXCPT_SW_FWD, + HAL_TAU_PKT_IPP_L3_EXCPT_MTU, + HAL_TAU_PKT_IPP_L3_EXCPT_TTL, + HAL_TAU_PKT_IPP_L3_EXCPT_LAST +} HAL_TAU_PKT_IPP_L3_EXCPT_T; + +typedef enum +{ + HAL_TAU_PKT_IPP_RSN_RSVD_0 = 0, + HAL_TAU_PKT_IPP_RSN_IDS_MPLS_MP_LSP_INNER_IP_LCL, + HAL_TAU_PKT_IPP_RSN_IDS_IP_MC_TNL_LCL_INTF_MISS, + HAL_TAU_PKT_IPP_RSN_IDS_IP_MC_TNL_GRE_ISIS, + HAL_TAU_PKT_IPP_RSN_IDS_IP_MC_TNL_GRE_KA, + HAL_TAU_PKT_IPP_RSN_IDS_IP_MC_TNL_INNER_IP_LCL, + HAL_TAU_PKT_IPP_RSN_IDS_TRILL_MC_LCL_INTF_MISS, + HAL_TAU_PKT_IPP_RSN_IDS_INNER_SRV_1ST_MISS, + HAL_TAU_PKT_IPP_RSN_IDS_INNER_SRV_2ND_MISS, + HAL_TAU_PKT_IPP_RSN_IEV_IP_MC_TTL0, + HAL_TAU_PKT_IPP_RSN_IEV_IP_MC_TTL1, + HAL_TAU_PKT_IPP_RSN_RSVD_1, + HAL_TAU_PKT_IPP_RSN_RSVD_2, + HAL_TAU_PKT_IPP_RSN_IDS_ECN, + HAL_TAU_PKT_IPP_RSN_IEV_ICMP_REDIR, + HAL_TAU_PKT_IPP_RSN_IEV_ICMP_REDIR_WITH_RSN_IDS_ECN, + HAL_TAU_PKT_IPP_RSN_LAST +} HAL_TAU_PKT_IPP_RSN_T; + +typedef enum +{ + /* IEV.cp_to_cpu_bmap |= + * (1 << sw_plane.iev_cp_to_cpu_bit_pos_{i}) | + * (1 << sw_plane.iev_sflw_cp_to_cpu_bidx_{i}) | + * (1 << (IEV_RSLT_CTL2CPU_PROF.code - 1)) | + * (1 << (ICIA_RSLT_TCAM_UCP_POLICY.cp_to_cpu_idx - 1)); + */ + HAL_TAU_PKT_IPP_COPY2CPU_ICIA_0 = 0, + HAL_TAU_PKT_IPP_COPY2CPU_ICIA_1, + HAL_TAU_PKT_IPP_COPY2CPU_ICIA_2, + HAL_TAU_PKT_IPP_COPY2CPU_ICIA_3, + HAL_TAU_PKT_IPP_COPY2CPU_ICIA_4, + HAL_TAU_PKT_IPP_COPY2CPU_ICIA_5, + HAL_TAU_PKT_IPP_COPY2CPU_COPY_TO_CPU_L2UC, + HAL_TAU_PKT_IPP_COPY2CPU_COPY_TO_CPU_L3UC, + HAL_TAU_PKT_IPP_COPY2CPU_PORT_SFLOW, + HAL_TAU_PKT_IPP_COPY2CPU_ICIA_SFLOW, + HAL_TAU_PKT_IPP_COPY2CPU_FLOW_SFLOW, + HAL_TAU_PKT_IPP_COPY2CPU_L3MC_SPT_READY_UNSET, + HAL_TAU_PKT_IPP_COPY2CPU_COPY_TO_CPU_L2MC, + HAL_TAU_PKT_IPP_COPY2CPU_COPY_TO_CPU_L3MC, + HAL_TAU_PKT_IPP_COPY2CPU_USR_DEFINE_0, + HAL_TAU_PKT_IPP_COPY2CPU_USR_DEFINE_1, + HAL_TAU_PKT_IPP_COPY2CPU_LAST +} HAL_TAU_PKT_IPP_COPY2CPU_T; + +typedef enum +{ + /* The value of: + * 1. emi_sflw_cp_to_cpu_idx_bidx_* + * 2. ECIA.cp_to_cpu_idx (last is invalid) + */ + HAL_TAU_PKT_EPP_COPY2CPU_ECIA_0 = 0, + HAL_TAU_PKT_EPP_COPY2CPU_ECIA_1, + HAL_TAU_PKT_EPP_COPY2CPU_ECIA_2, + HAL_TAU_PKT_EPP_COPY2CPU_ECIA_3, + HAL_TAU_PKT_EPP_COPY2CPU_PORT_SFLOW, + HAL_TAU_PKT_EPP_COPY2CPU_ECIA_SFLOW, + HAL_TAU_PKT_EPP_COPY2CPU_RSVD_0, + HAL_TAU_PKT_EPP_COPY2CPU_RSVD_1, + HAL_TAU_PKT_EPP_COPY2CPU_LAST +} HAL_TAU_PKT_EPP_COPY2CPU_T; + +#define HAL_TAU_PKT_IPP_EXCPT_BITMAP_SIZE (NPS_BITMAP_SIZE(HAL_TAU_PKT_IPP_EXCPT_LAST)) +#define HAL_TAU_PKT_IPP_L3_EXCPT_BITMAP_SIZE (NPS_BITMAP_SIZE(HAL_TAU_PKT_IPP_L3_EXCPT_LAST)) +#define HAL_TAU_PKT_EPP_EXCPT_BITMAP_SIZE (NPS_BITMAP_SIZE(HAL_TAU_PKT_EPP_EXCPT_LAST)) +#define HAL_TAU_PKT_IPP_RSN_BITMAP_SIZE (NPS_BITMAP_SIZE(HAL_TAU_PKT_IPP_RSN_LAST)) +#define HAL_TAU_PKT_IPP_COPY2CPU_BITMAP_SIZE (NPS_BITMAP_SIZE(HAL_TAU_PKT_IPP_COPY2CPU_LAST)) +#define HAL_TAU_PKT_EPP_COPY2CPU_BITMAP_SIZE (NPS_BITMAP_SIZE(HAL_TAU_PKT_EPP_COPY2CPU_LAST)) + +typedef UI32_T HAL_TAU_PKT_IPP_EXCPT_BITMAP_T[HAL_TAU_PKT_IPP_EXCPT_BITMAP_SIZE]; +typedef UI32_T HAL_TAU_PKT_IPP_L3_EXCPT_BITMAP_T[HAL_TAU_PKT_IPP_L3_EXCPT_BITMAP_SIZE]; +typedef UI32_T HAL_TAU_PKT_EPP_EXCPT_BITMAP_T[HAL_TAU_PKT_EPP_EXCPT_BITMAP_SIZE]; +typedef UI32_T HAL_TAU_PKT_IPP_RSN_BITMAP_T[HAL_TAU_PKT_IPP_RSN_BITMAP_SIZE]; +typedef UI32_T HAL_TAU_PKT_IPP_COPY2CPU_BITMAP_T[HAL_TAU_PKT_IPP_COPY2CPU_BITMAP_SIZE]; +typedef UI32_T HAL_TAU_PKT_EPP_COPY2CPU_BITMAP_T[HAL_TAU_PKT_EPP_COPY2CPU_BITMAP_SIZE]; + +typedef struct +{ + /* excpt */ + HAL_TAU_PKT_IPP_EXCPT_BITMAP_T ipp_excpt_bitmap; + HAL_TAU_PKT_IPP_L3_EXCPT_BITMAP_T ipp_l3_excpt_bitmap; + HAL_TAU_PKT_EPP_EXCPT_BITMAP_T epp_excpt_bitmap; + + /* cp */ + HAL_TAU_PKT_IPP_RSN_BITMAP_T ipp_rsn_bitmap; + HAL_TAU_PKT_IPP_COPY2CPU_BITMAP_T ipp_copy2cpu_bitmap; + HAL_TAU_PKT_EPP_COPY2CPU_BITMAP_T epp_copy2cpu_bitmap; + +} HAL_TAU_PKT_RX_REASON_BITMAP_T; + + +/* hal_tau_pkt.h */ + +/* NAMING DECLARATIONS + */ +/* PKT related configurable parameters */ +#define HAL_TAU_PKT_RX_FREE_STACK_SIZE (64 * 1024) +#define HAL_TAU_PKT_RX_FREE_THREAD_PRI (80) + +#define HAL_TAU_PKT_RX_ISR_STACK_SIZE (64 * 1024) +#define HAL_TAU_PKT_RX_ISR_THREAD_PRI (80) + +#define HAL_TAU_PKT_TX_FREE_STACK_SIZE (64 * 1024) +#define HAL_TAU_PKT_TX_FREE_THREAD_PRI (80) + +#define HAL_TAU_PKT_TX_ISR_STACK_SIZE (64 * 1024) +#define HAL_TAU_PKT_TX_ISR_THREAD_PRI (80) + +#define HAL_TAU_PKT_TX_NET_STACK_SIZE (64 * 1024) +#define HAL_TAU_PKT_TX_NET_THREAD_PRI (80) + +#define HAL_TAU_PKT_ERROR_ISR_STACK_SIZE (64 * 1024) +#define HAL_TAU_PKT_ERROR_ISR_THREAD_PRI (80) + +/* PKT definitions */ +#define HAL_TAU_PKT_TX_MAX_LEN (9216) +#define HAL_TAU_PKT_RX_MAX_LEN (9216 + 86) /* EPP tunnel header */ +#define HAL_TAU_PKT_MIN_LEN (64) /* Ethernet definition */ +#define HAL_TAU_PKT_TMH_HDR_SZ (20) +#define HAL_TAU_PKT_PPH_HDR_SZ (20) +#define HAL_TAU_PKT_CRC_LEN (4) + +/* CH */ +#define HAL_TAU_PKT_CH_LAST_GPD (0) +#define HAL_TAU_PKT_CH_MIDDLE_GPD (1) + +/* PRG */ +#define HAL_TAU_PKT_PRG_PROCESS_GPD (0) /* Normal */ +#define HAL_TAU_PKT_PRG_SKIP_GPD (1) /* Skip */ + +/* CRCC */ +#define HAL_TAU_PKT_CRCC_SUM_BY_HW (0) /* calculated by HW */ +#define HAL_TAU_PKT_CRCC_SUM_BY_SW (1) /* calculated by SW */ + +/* IOC */ +#define HAL_TAU_PKT_IOC_NO_INTR (0) /* trigger interrupt each GPD */ +#define HAL_TAU_PKT_IOC_HAS_INTR (1) /* trigger interrupt when ch=0, default setting */ + +/* HWO */ +#define HAL_TAU_PKT_HWO_SW_OWN (0) +#define HAL_TAU_PKT_HWO_HW_OWN (1) + +/* ECC */ +#define HAL_TAU_PKT_ECC_ERROR_OCCUR (1) + +/* CPU queue number */ +#define HAL_TAU_PKT_CPU_QUE_NUM (48) + +/* PDMA Definitions */ +#define HAL_TAU_PKT_PDMA_MAX_GPD_PER_PKT (10) /* <= 256 */ +#define HAL_TAU_PKT_PDMA_TX_GPD_NUM (1024) /* <= 65535 */ +#define HAL_TAU_PKT_PDMA_RX_GPD_NUM (1024) /* <= 65535 */ +#define HAL_TAU_PKT_PDMA_TX_INTR_TIMEOUT (10 * 1000) /* us */ +#define HAL_TAU_PKT_PDMA_TX_POLL_MAX_LOOP (10 * 1000) /* int */ + +/* Mode */ +#define HAL_TAU_PKT_TX_WAIT_MODE (HAL_TAU_PKT_TX_WAIT_ASYNC) +#define HAL_TAU_PKT_RX_SCHED_MODE (HAL_TAU_PKT_RX_SCHED_RR) + +/* TX Queue */ +#define HAL_TAU_PKT_TX_QUEUE_LEN (HAL_TAU_PKT_PDMA_TX_GPD_NUM * 10) +#define HAL_TAU_PKT_TX_TASK_MAX_LOOP (HAL_TAU_PKT_TX_QUEUE_LEN) + +/* RX Queue */ +#define HAL_TAU_PKT_RX_QUEUE_NUM (HAL_TAU_PKT_RX_CHANNEL_LAST) +#define HAL_TAU_PKT_RX_QUEUE_WEIGHT (10) +#define HAL_TAU_PKT_RX_QUEUE_LEN (HAL_TAU_PKT_PDMA_RX_GPD_NUM * 10) +#define HAL_TAU_PKT_RX_TASK_MAX_LOOP (HAL_TAU_PKT_RX_QUEUE_LEN) + +/* MACRO FUNCTION DECLARATIONS + */ +/*---------------------------------------------------------------------------*/ +/* [Taurus] Alignment to 64-bytes */ +#if defined(NPS_EN_HOST_64_BIT_BIG_ENDIAN) || defined(NPS_EN_HOST_64_BIT_LITTLE_ENDIAN) +#define HAL_TAU_PKT_PDMA_ALIGN_ADDR(pdma_addr, align_sz) (((pdma_addr) + (align_sz)) & 0xFFFFFFFFFFFFFFC0) +#else +#define HAL_TAU_PKT_PDMA_ALIGN_ADDR(pdma_addr, align_sz) (((pdma_addr) + (align_sz)) & 0xFFFFFFC0) +#endif +/*---------------------------------------------------------------------------*/ +#if defined(NPS_EN_BIG_ENDIAN) +#define HAL_TAU_PKT_ENDIAN_SWAP32(val) (val) +#else +#define HAL_TAU_PKT_ENDIAN_SWAP32(val) ((((UI32_T)(val) & 0xFF) << 24) | \ + (((UI32_T)(val) & 0xFF00) << 8) | \ + (((UI32_T)(val) & 0xFF0000) >> 8) | \ + (((UI32_T)(val) & 0xFF000000) >> 24)) +#endif +/*---------------------------------------------------------------------------*/ +#define HAL_TAU_PKT_GET_BIT(flags, bit) ((((flags) & (bit)) > 0)? 1 : 0) +/*---------------------------------------------------------------------------*/ +#define HAL_TAU_PKT_SET_BITMAP(bitmap, mask_bitmap) (bitmap = ((bitmap) | (mask_bitmap))) +#define HAL_TAU_PKT_CLR_BITMAP(bitmap, mask_bitmap) (bitmap = ((bitmap) & (~(mask_bitmap)))) +/*---------------------------------------------------------------------------*/ +#define HAL_TAU_PKT_GET_TX_INTR_TYPE(channel) (HAL_INTR_TX_CH0 + channel) +#define HAL_TAU_PKT_GET_RX_INTR_TYPE(channel) (HAL_INTR_RX_CH0 + channel) + +/* DATA TYPE DECLARATIONS + */ +typedef enum +{ + HAL_TAU_PKT_TX_WAIT_ASYNC = 0, + HAL_TAU_PKT_TX_WAIT_SYNC_INTR = 1, + HAL_TAU_PKT_TX_WAIT_SYNC_POLL = 2 + +} HAL_TAU_PKT_TX_WAIT_T; + +typedef enum +{ + HAL_TAU_PKT_RX_SCHED_RR = 0, + HAL_TAU_PKT_RX_SCHED_WRR = 1 + +} HAL_TAU_PKT_RX_SCHED_T; + +/* GPD and Packet Strucutre Definition */ +#if defined(NPS_EN_BIG_ENDIAN) + +typedef struct +{ + /* NPS DWORD 0 */ + UI32_T typ : 2; + UI32_T tc : 4; + UI32_T color : 2; + UI32_T srv : 3; + UI32_T trig : 1; + UI32_T igr_phy_port :12; + UI32_T hsh_val_w0 : 8; + /* NPS DWORD 1 */ + UI32_T hsh_val_w1 : 2; + UI32_T dst_idx :15; + UI32_T src_idx :15; + /* NPS DWORD 2 */ + UI32_T intf_fdid :14; + UI32_T nvo3_mgid_is_transit : 1; + UI32_T skip_epp : 1; + UI32_T steer_applied : 1; + UI32_T nvo3_ip_tnl_decap_prop_ttl : 1; + UI32_T nvo3_mpls_uhp_prop_ttl : 1; + UI32_T ecn : 2; + UI32_T store_and_forward : 1; + UI32_T lag_epoch : 1; + UI32_T src_supp_tag : 5; + UI32_T one_arm_rte_srv_fdid : 1; + UI32_T fab_one_arm_rte : 1; + UI32_T skip_ipp : 1; + UI32_T igr_fab_port_grp : 1; + /* NPS DWORD 3 */ + UI32_T : 2; + UI32_T nvo3_mgid :15; + UI32_T nvo3_intf :14; + UI32_T nvo3_src_supp_tag_w0 : 1; + /* NPS DWORD 4 */ + UI32_T nvo3_src_supp_tag_w1 : 4; + UI32_T mir_bmap : 8; + UI32_T cp_to_cpu_code : 4; + UI32_T cp_to_cpu_bmap :16; +} HAL_TAU_PKT_ITMH_ETH_T; + +typedef struct +{ + /* NPS DWORD 0 */ + UI32_T typ : 2; + UI32_T tc : 4; + UI32_T color : 2; + UI32_T srv : 3; + UI32_T trig : 1; + UI32_T igr_phy_port :12; + UI32_T hsh_val_w0 : 8; + /* NPS DWORD 1 */ + UI32_T hsh_val_w1 : 2; + UI32_T dst_idx :15; + UI32_T src_idx :15; + /* NPS DWORD 2 */ + UI32_T intf_fdid :14; + UI32_T nvo3_mgid_is_transit : 1; + UI32_T skip_epp : 1; + UI32_T steer_applied : 1; + UI32_T nvo3_ip_tnl_decap_prop_ttl : 1; + UI32_T nvo3_mpls_uhp_prop_ttl : 1; + UI32_T ecn : 2; + UI32_T store_and_forward : 1; + UI32_T lag_epoch : 1; + UI32_T src_supp_tag : 5; + UI32_T one_arm_rte_srv_fdid : 1; + UI32_T fab_one_arm_rte : 1; + UI32_T : 2; + /* NPS DWORD 3 */ + UI32_T :32; + /* NPS DWORD 4 */ + UI32_T :23; + UI32_T excpt_code : 8; + UI32_T exp_dscp_mrkd : 1; +} HAL_TAU_PKT_ETMH_FAB_T; + +typedef struct +{ + /* NPS DWORD 0 */ + UI32_T typ : 2; + UI32_T tc : 4; + UI32_T color : 2; + UI32_T srv : 3; + UI32_T trig : 1; + UI32_T igr_phy_port :12; + UI32_T hsh_val_w0 : 8; + /* NPS DWORD 1 */ + UI32_T hsh_val_w1 : 2; + UI32_T dst_idx :15; + UI32_T src_idx :15; + /* NPS DWORD 2 */ + UI32_T intf_fdid :14; + UI32_T nvo3_mgid_is_transit : 1; + UI32_T skip_epp : 1; + UI32_T steer_applied : 1; + UI32_T nvo3_ip_tnl_decap_prop_ttl : 1; + UI32_T nvo3_mpls_uhp_prop_ttl : 1; + UI32_T ecn : 2; + UI32_T igr_fab_port_grp : 1; + UI32_T redir : 1; + UI32_T excpt_code_mir_bmap : 8; + UI32_T cp_to_cpu_bmap_w0 : 1; + /* NPS DWORD 3 */ + UI32_T cp_to_cpu_bmap_w1 : 7; + UI32_T egr_phy_port :12; + UI32_T src_supp_pnd : 1; + UI32_T mc_vid_ctl : 3; + UI32_T mc_vid_1st_w0 : 9; + /* NPS DWORD 4 */ + UI32_T mc_vid_1st_w1 : 3; + UI32_T mc_vid_2nd :12; + UI32_T mc_decr_ttl : 1; + UI32_T mc_is_routed : 1; + UI32_T mc_mel_vld : 1; + UI32_T mc_cp_idx :13; + UI32_T exp_dscp_mrkd : 1; +} HAL_TAU_PKT_ETMH_ETH_T; + +typedef struct +{ + /* NPS DWORD 0 */ + UI32_T decap_act : 3; + UI32_T igr_l2_vid_num : 2; + UI32_T nvo3_encap_idx :14; + UI32_T mpls_pw_cw_vld : 1; + UI32_T hit_idx_w0 :12; + /* NPS DWORD 1 */ + UI32_T hit_idx_w1 : 7; + UI32_T nvo3_adj_idx : 8; + UI32_T seg_vmid_w0 :17; + /* NPS DWORD 2 */ + UI32_T seg_vmid_w1 : 7; + UI32_T : 1; + UI32_T l2_sa_lrn_en_hw_cvs : 1; + UI32_T l2_sa_lrn_en_hw : 1; + UI32_T vid_ctl : 3; + UI32_T vid_1st :12; + UI32_T vid_2nd_w0 : 7; + /* NPS DWORD 3 */ + UI32_T vid_2nd_w1 : 5; + UI32_T flw_lbl :10; + UI32_T rewr_idx_ctl : 2; + UI32_T rewr_idx_0 :13; + UI32_T rewr_idx_1_w0 : 2; + /* NPS DWORD 4 */ + UI32_T rewr_idx_1_w1 :11; + UI32_T mrk_pcp_dei_en : 1; + UI32_T mrk_pcp_val : 3; + UI32_T mrk_dei_val : 1; + UI32_T ts :16; +} HAL_TAU_PKT_PPH_L2_T; + +typedef struct +{ + /* NPS DWORD 0 */ + UI32_T decap_act : 3; + UI32_T igr_l2_vid_num : 2; + UI32_T nvo3_encap_idx :14; + UI32_T mpls_pw_cw_vld : 1; + UI32_T hit_idx_w0 :12; + /* NPS DWORD 1 */ + UI32_T hit_idx_w1 : 7; + UI32_T nvo3_adj_idx : 8; + UI32_T seg_vmid_w0 :17; + /* NPS DWORD 2 */ + UI32_T seg_vmid_w1 : 7; + UI32_T : 1; + UI32_T rpf_pnd : 1; + UI32_T adj_idx :18; + UI32_T is_mc : 1; + UI32_T decr_ttl : 1; + UI32_T decap_prop_ttl : 1; + UI32_T mrk_dscp_en : 1; + UI32_T mrk_dscp_val_w0 : 1; + /* NPS DWORD 3 */ + UI32_T mrk_dscp_val_w1 : 5; + UI32_T flw_lbl :10; + UI32_T rewr_idx_ctl : 2; + UI32_T rewr_idx_0 :13; + UI32_T rewr_idx_1_w0 : 2; + /* NPS DWORD 4 */ + UI32_T rewr_idx_1_w1 :11; + UI32_T mrk_pcp_dei_en : 1; + UI32_T mrk_pcp_val : 3; + UI32_T mrk_dei_val : 1; + UI32_T ts :16; +} HAL_TAU_PKT_PPH_L3UC_T; + +typedef struct +{ + /* NPS DWORD 0 */ + UI32_T decap_act : 3; + UI32_T igr_l2_vid_num : 2; + UI32_T nvo3_encap_idx :14; + UI32_T mpls_pw_cw_vld : 1; + UI32_T hit_idx_w0 :12; + /* NPS DWORD 1 */ + UI32_T hit_idx_w1 : 7; + UI32_T nvo3_adj_idx : 8; + UI32_T vid_1st :12; + UI32_T vid_2nd_w0 : 5; + /* NPS DWORD 2 */ + UI32_T vid_2nd_w1 : 7; + UI32_T :15; + UI32_T l2_sa_lrn_en_hw_cvs : 1; + UI32_T l2_sa_lrn_en_hw : 1; + UI32_T vid_ctl : 3; + UI32_T is_mc : 1; + UI32_T : 1; + UI32_T decap_prop_ttl : 1; + UI32_T mrk_dscp_en : 1; + UI32_T mrk_dscp_val_w0 : 1; + /* NPS DWORD 3 */ + UI32_T mrk_dscp_val_w1 : 5; + UI32_T flw_lbl :10; + UI32_T rewr_idx_ctl : 2; + UI32_T rewr_idx_0 :13; + UI32_T rewr_idx_1_w0 : 2; + /* NPS DWORD 4 */ + UI32_T rewr_idx_1_w1 :11; + UI32_T mrk_pcp_dei_en : 1; + UI32_T mrk_pcp_val : 3; + UI32_T mrk_dei_val : 1; + UI32_T ts :16; +} HAL_TAU_PKT_PPH_L3MC_T; + +typedef struct +{ + /* NPS DWORD 0 */ + UI32_T decap_act : 3; + UI32_T igr_l2_vid_num : 2; + UI32_T nvo3_encap_idx :14; + UI32_T : 1; + UI32_T hit_idx_w0 :12; + /* NPS DWORD 1 */ + UI32_T hit_idx_w1 : 7; + UI32_T nvo3_adj_idx : 8; + UI32_T seg_vmid_w0 :17; + /* NPS DWORD 2 */ + UI32_T seg_vmid_w1 : 7; + UI32_T : 2; + UI32_T adj_idx :18; + UI32_T : 1; + UI32_T decr_ttl : 1; + UI32_T decap_prop_ttl : 1; + UI32_T mrk_exp_en : 1; + UI32_T : 1; + /* NPS DWORD 3 */ + UI32_T : 2; + UI32_T mrk_exp_val : 3; + UI32_T php_pop_keep_inner_qos : 1; + UI32_T :26; + /* NPS DWORD 4 */ + UI32_T :11; + UI32_T mrk_pcp_dei_en : 1; + UI32_T mrk_pcp_val : 3; + UI32_T mrk_dei_val : 1; + UI32_T ts :16; +} HAL_TAU_PKT_PPH_L25_T; + +#elif defined(NPS_EN_LITTLE_ENDIAN) + +typedef struct +{ + /* NPS DWORD 0 */ + UI32_T hsh_val_w0 : 8; + UI32_T igr_phy_port :12; + UI32_T trig : 1; + UI32_T srv : 3; + UI32_T color : 2; + UI32_T tc : 4; + UI32_T typ : 2; + /* NPS DWORD 1 */ + UI32_T src_idx :15; + UI32_T dst_idx :15; + UI32_T hsh_val_w1 : 2; + /* NPS DWORD 2 */ + UI32_T igr_fab_port_grp : 1; + UI32_T skip_ipp : 1; + UI32_T fab_one_arm_rte : 1; + UI32_T one_arm_rte_srv_fdid : 1; + UI32_T src_supp_tag : 5; + UI32_T lag_epoch : 1; + UI32_T store_and_forward : 1; + UI32_T ecn : 2; + UI32_T nvo3_mpls_uhp_prop_ttl : 1; + UI32_T nvo3_ip_tnl_decap_prop_ttl : 1; + UI32_T steer_applied : 1; + UI32_T skip_epp : 1; + UI32_T nvo3_mgid_is_transit : 1; + UI32_T intf_fdid :14; + /* NPS DWORD 3 */ + UI32_T nvo3_src_supp_tag_w0 : 1; + UI32_T nvo3_intf :14; + UI32_T nvo3_mgid :15; + UI32_T : 2; + /* NPS DWORD 4 */ + UI32_T cp_to_cpu_bmap :16; + UI32_T cp_to_cpu_code : 4; + UI32_T mir_bmap : 8; + UI32_T nvo3_src_supp_tag_w1 : 4; +} HAL_TAU_PKT_ITMH_ETH_T; + +typedef struct +{ + /* NPS DWORD 0 */ + UI32_T hsh_val_w0 : 8; + UI32_T igr_phy_port :12; + UI32_T trig : 1; + UI32_T srv : 3; + UI32_T color : 2; + UI32_T tc : 4; + UI32_T typ : 2; + /* NPS DWORD 1 */ + UI32_T src_idx :15; + UI32_T dst_idx :15; + UI32_T hsh_val_w1 : 2; + /* NPS DWORD 2 */ + UI32_T : 2; + UI32_T fab_one_arm_rte : 1; + UI32_T one_arm_rte_srv_fdid : 1; + UI32_T src_supp_tag : 5; + UI32_T lag_epoch : 1; + UI32_T store_and_forward : 1; + UI32_T ecn : 2; + UI32_T nvo3_mpls_uhp_prop_ttl : 1; + UI32_T nvo3_ip_tnl_decap_prop_ttl : 1; + UI32_T steer_applied : 1; + UI32_T skip_epp : 1; + UI32_T nvo3_mgid_is_transit : 1; + UI32_T intf_fdid :14; + /* NPS DWORD 3 */ + UI32_T :32; + /* NPS DWORD 4 */ + UI32_T exp_dscp_mrkd : 1; + UI32_T excpt_code : 8; + UI32_T :23; +} HAL_TAU_PKT_ETMH_FAB_T; + +typedef struct +{ + /* NPS DWORD 0 */ + UI32_T hsh_val_w0 : 8; + UI32_T igr_phy_port :12; + UI32_T trig : 1; + UI32_T srv : 3; + UI32_T color : 2; + UI32_T tc : 4; + UI32_T typ : 2; + /* NPS DWORD 1 */ + UI32_T src_idx :15; + UI32_T dst_idx :15; + UI32_T hsh_val_w1 : 2; + /* NPS DWORD 2 */ + UI32_T cp_to_cpu_bmap_w0 : 1; + UI32_T excpt_code_mir_bmap : 8; + UI32_T redir : 1; + UI32_T igr_fab_port_grp : 1; + UI32_T ecn : 2; + UI32_T nvo3_mpls_uhp_prop_ttl : 1; + UI32_T nvo3_ip_tnl_decap_prop_ttl : 1; + UI32_T steer_applied : 1; + UI32_T skip_epp : 1; + UI32_T nvo3_mgid_is_transit : 1; + UI32_T intf_fdid :14; + /* NPS DWORD 3 */ + UI32_T mc_vid_1st_w0 : 9; + UI32_T mc_vid_ctl : 3; + UI32_T src_supp_pnd : 1; + UI32_T egr_phy_port :12; + UI32_T cp_to_cpu_bmap_w1 : 7; + /* NPS DWORD 4 */ + UI32_T exp_dscp_mrkd : 1; + UI32_T mc_cp_idx :13; + UI32_T mc_mel_vld : 1; + UI32_T mc_is_routed : 1; + UI32_T mc_decr_ttl : 1; + UI32_T mc_vid_2nd :12; + UI32_T mc_vid_1st_w1 : 3; +} HAL_TAU_PKT_ETMH_ETH_T; + +typedef struct +{ + /* NPS DWORD 0 */ + UI32_T hit_idx_w0 :12; + UI32_T mpls_pw_cw_vld : 1; + UI32_T nvo3_encap_idx :14; + UI32_T igr_l2_vid_num : 2; + UI32_T decap_act : 3; + /* NPS DWORD 1 */ + UI32_T seg_vmid_w0 :17; + UI32_T nvo3_adj_idx : 8; + UI32_T hit_idx_w1 : 7; + /* NPS DWORD 2 */ + UI32_T vid_2nd_w0 : 7; + UI32_T vid_1st :12; + UI32_T vid_ctl : 3; + UI32_T l2_sa_lrn_en_hw : 1; + UI32_T l2_sa_lrn_en_hw_cvs : 1; + UI32_T : 1; + UI32_T seg_vmid_w1 : 7; + /* NPS DWORD 3 */ + UI32_T rewr_idx_1_w0 : 2; + UI32_T rewr_idx_0 :13; + UI32_T rewr_idx_ctl : 2; + UI32_T flw_lbl :10; + UI32_T vid_2nd_w1 : 5; + /* NPS DWORD 4 */ + UI32_T ts :16; + UI32_T mrk_dei_val : 1; + UI32_T mrk_pcp_val : 3; + UI32_T mrk_pcp_dei_en : 1; + UI32_T rewr_idx_1_w1 :11; +} HAL_TAU_PKT_PPH_L2_T; + +typedef struct +{ + /* NPS DWORD 0 */ + UI32_T hit_idx_w0 :12; + UI32_T mpls_pw_cw_vld : 1; + UI32_T nvo3_encap_idx :14; + UI32_T igr_l2_vid_num : 2; + UI32_T decap_act : 3; + /* NPS DWORD 1 */ + UI32_T seg_vmid_w0 :17; + UI32_T nvo3_adj_idx : 8; + UI32_T hit_idx_w1 : 7; + /* NPS DWORD 2 */ + UI32_T mrk_dscp_val_w0 : 1; + UI32_T mrk_dscp_en : 1; + UI32_T decap_prop_ttl : 1; + UI32_T decr_ttl : 1; + UI32_T is_mc : 1; + UI32_T adj_idx :18; + UI32_T rpf_pnd : 1; + UI32_T : 1; + UI32_T seg_vmid_w1 : 7; + /* NPS DWORD 3 */ + UI32_T rewr_idx_1_w0 : 2; + UI32_T rewr_idx_0 :13; + UI32_T rewr_idx_ctl : 2; + UI32_T flw_lbl :10; + UI32_T mrk_dscp_val_w1 : 5; + /* NPS DWORD 4 */ + UI32_T ts :16; + UI32_T mrk_dei_val : 1; + UI32_T mrk_pcp_val : 3; + UI32_T mrk_pcp_dei_en : 1; + UI32_T rewr_idx_1_w1 :11; +} HAL_TAU_PKT_PPH_L3UC_T; + +typedef struct +{ + /* NPS DWORD 0 */ + UI32_T hit_idx_w0 :12; + UI32_T mpls_pw_cw_vld : 1; + UI32_T nvo3_encap_idx :14; + UI32_T igr_l2_vid_num : 2; + UI32_T decap_act : 3; + /* NPS DWORD 1 */ + UI32_T vid_2nd_w0 : 5; + UI32_T vid_1st :12; + UI32_T nvo3_adj_idx : 8; + UI32_T hit_idx_w1 : 7; + /* NPS DWORD 2 */ + UI32_T mrk_dscp_val_w0 : 1; + UI32_T mrk_dscp_en : 1; + UI32_T decap_prop_ttl : 1; + UI32_T : 1; + UI32_T is_mc : 1; + UI32_T vid_ctl : 3; + UI32_T l2_sa_lrn_en_hw : 1; + UI32_T l2_sa_lrn_en_hw_cvs : 1; + UI32_T :15; + UI32_T vid_2nd_w1 : 7; + /* NPS DWORD 3 */ + UI32_T rewr_idx_1_w0 : 2; + UI32_T rewr_idx_0 :13; + UI32_T rewr_idx_ctl : 2; + UI32_T flw_lbl :10; + UI32_T mrk_dscp_val_w1 : 5; + /* NPS DWORD 4 */ + UI32_T ts :16; + UI32_T mrk_dei_val : 1; + UI32_T mrk_pcp_val : 3; + UI32_T mrk_pcp_dei_en : 1; + UI32_T rewr_idx_1_w1 :11; +} HAL_TAU_PKT_PPH_L3MC_T; + +typedef struct +{ + /* NPS DWORD 0 */ + UI32_T hit_idx_w0 :12; + UI32_T : 1; + UI32_T nvo3_encap_idx :14; + UI32_T igr_l2_vid_num : 2; + UI32_T decap_act : 3; + /* NPS DWORD 1 */ + UI32_T seg_vmid_w0 :17; + UI32_T nvo3_adj_idx : 8; + UI32_T hit_idx_w1 : 7; + /* NPS DWORD 2 */ + UI32_T : 1; + UI32_T mrk_exp_en : 1; + UI32_T decap_prop_ttl : 1; + UI32_T decr_ttl : 1; + UI32_T : 1; + UI32_T adj_idx :18; + UI32_T : 2; + UI32_T seg_vmid_w1 : 7; + /* NPS DWORD 3 */ + UI32_T :26; + UI32_T php_pop_keep_inner_qos : 1; + UI32_T mrk_exp_val : 3; + UI32_T : 2; + /* NPS DWORD 4 */ + UI32_T ts :16; + UI32_T mrk_dei_val : 1; + UI32_T mrk_pcp_val : 3; + UI32_T mrk_pcp_dei_en : 1; + UI32_T :11; +} HAL_TAU_PKT_PPH_L25_T; + +#else +#error "Host GPD endian is not defined!!\n" +#endif + +#if defined(NPS_EN_BIG_ENDIAN) + +/* RX GPD STRUCTURE */ +typedef struct +{ + UI32_T data_buf_addr_lo; + UI32_T data_buf_addr_hi; + UI32_T chksum : 16; + UI32_T ioc : 1; + UI32_T : 1; + UI32_T avbl_buf_len : 14; + UI32_T : 32; + + union + { + HAL_TAU_PKT_ITMH_ETH_T itmh_eth; + HAL_TAU_PKT_ETMH_FAB_T etmh_fab; + HAL_TAU_PKT_ETMH_ETH_T etmh_eth; + }; + union + { + HAL_TAU_PKT_PPH_L2_T pph_l2; + HAL_TAU_PKT_PPH_L3UC_T pph_l3uc; + HAL_TAU_PKT_PPH_L3MC_T pph_l3mc; + HAL_TAU_PKT_PPH_L25_T pph_l25; + }; + + UI32_T : 32; + UI32_T hwo : 1; + UI32_T ch : 1; + UI32_T trn : 1; + UI32_T ecce : 1; + UI32_T errf : 1; + UI32_T : 5; + UI32_T queue : 6; + UI32_T : 2; + UI32_T cnsm_buf_len : 14; + +} HAL_TAU_PKT_RX_GPD_T; + +/* TX GPD STRUCTURE */ +typedef struct +{ + UI32_T data_buf_addr_lo; + UI32_T data_buf_addr_hi; + UI32_T chksum : 16; + UI32_T ioc : 1; + UI32_T : 1; + UI32_T data_buf_size : 14; + UI32_T : 32; + + union + { + HAL_TAU_PKT_ITMH_ETH_T itmh_eth; + HAL_TAU_PKT_ETMH_FAB_T etmh_fab; + HAL_TAU_PKT_ETMH_ETH_T etmh_eth; + }; + union + { + HAL_TAU_PKT_PPH_L2_T pph_l2; + HAL_TAU_PKT_PPH_L3UC_T pph_l3uc; + HAL_TAU_PKT_PPH_L3MC_T pph_l3mc; + HAL_TAU_PKT_PPH_L25_T pph_l25; + }; + + UI32_T : 16; + UI32_T ptp_hdr : 16; + UI32_T hwo : 1; + UI32_T ch : 1; + UI32_T : 1; + UI32_T ecce : 1; + UI32_T : 4; + UI32_T cos : 3; + UI32_T phc : 1; /* PTP Header Control */ + UI32_T ipc : 2; /* Ingress Plane Control */ + UI32_T crcc : 1; + UI32_T prg : 1; /* Purge */ + UI32_T : 2; + UI32_T pkt_len : 14; /* Total packet length */ + +} HAL_TAU_PKT_TX_GPD_T; + +#elif defined(NPS_EN_LITTLE_ENDIAN) + +/* RX GPD STRUCTURE */ +typedef struct +{ + UI32_T data_buf_addr_lo; + UI32_T data_buf_addr_hi; + UI32_T avbl_buf_len : 14; + UI32_T : 1; + UI32_T ioc : 1; + UI32_T chksum : 16; + UI32_T : 32; + + union + { + HAL_TAU_PKT_ITMH_ETH_T itmh_eth; + HAL_TAU_PKT_ETMH_FAB_T etmh_fab; + HAL_TAU_PKT_ETMH_ETH_T etmh_eth; + }; + union + { + HAL_TAU_PKT_PPH_L2_T pph_l2; + HAL_TAU_PKT_PPH_L3UC_T pph_l3uc; + HAL_TAU_PKT_PPH_L3MC_T pph_l3mc; + HAL_TAU_PKT_PPH_L25_T pph_l25; + }; + + UI32_T : 32; + UI32_T cnsm_buf_len : 14; + UI32_T : 2; + UI32_T queue : 6; + UI32_T : 5; + UI32_T errf : 1; + UI32_T ecce : 1; + UI32_T trn : 1; + UI32_T ch : 1; + UI32_T hwo : 1; + +} HAL_TAU_PKT_RX_GPD_T; + +/* TX GPD STRUCTURE */ +typedef struct +{ + UI32_T data_buf_addr_lo; + UI32_T data_buf_addr_hi; + UI32_T data_buf_size : 14; + UI32_T : 1; + UI32_T ioc : 1; + UI32_T chksum : 16; + UI32_T : 32; + + union + { + HAL_TAU_PKT_ITMH_ETH_T itmh_eth; + HAL_TAU_PKT_ETMH_FAB_T etmh_fab; + HAL_TAU_PKT_ETMH_ETH_T etmh_eth; + }; + union + { + HAL_TAU_PKT_PPH_L2_T pph_l2; + HAL_TAU_PKT_PPH_L3UC_T pph_l3uc; + HAL_TAU_PKT_PPH_L3MC_T pph_l3mc; + HAL_TAU_PKT_PPH_L25_T pph_l25; + }; + + UI32_T ptp_hdr : 16; + UI32_T : 16; + UI32_T pkt_len : 14; /* Total packet length */ + UI32_T : 2; + UI32_T prg : 1; /* Purge */ + UI32_T crcc : 1; + UI32_T ipc : 2; /* Ingress Plane Control */ + UI32_T phc : 1; /* PTP Header Control */ + UI32_T cos : 3; + UI32_T : 4; + UI32_T ecce : 1; + UI32_T : 1; + UI32_T ch : 1; + UI32_T hwo : 1; +} HAL_TAU_PKT_TX_GPD_T; + +#else +#error "Host GPD endian is not defined\n" +#endif + +/* ----------------------------------------------------------------------------------- PP Type */ +typedef enum +{ + HAL_TAU_PKT_TMH_TYPE_ITMH_ETH = 0, + HAL_TAU_PKT_TMH_TYPE_ITMH_FAB, + HAL_TAU_PKT_TMH_TYPE_ETMH_FAB, + HAL_TAU_PKT_TMH_TYPE_ETMH_ETH, + HAL_TAU_PKT_TMH_TYPE_LAST + +} HAL_TAU_PKT_TMH_TYPE_T; + +typedef enum +{ + HAL_TAU_PKT_TMH_SRV_L2 = 0, + HAL_TAU_PKT_TMH_SRV_L25_MPLS, + HAL_TAU_PKT_TMH_SRV_L3, + HAL_TAU_PKT_TMH_SRV_EGR, /* L3 downgrade L2 */ + HAL_TAU_PKT_TMH_SRV_L25_NSH, + HAL_TAU_PKT_TMH_SRV_L25_TRILL, + HAL_TAU_PKT_TMH_SRV_LAST + +} HAL_TAU_PKT_TMH_SRV_T; + +typedef enum +{ + HAL_TAU_PKT_TMH_DECAP_NONE = 0, + HAL_TAU_PKT_TMH_DECAP_1_MPLS_LABEL, + HAL_TAU_PKT_TMH_DECAP_2_MPLS_LABEL, + HAL_TAU_PKT_TMH_DECAP_3_MPLS_LABEL, + HAL_TAU_PKT_TMH_DECAP_4_MPLS_LABEL, + HAL_TAU_PKT_TMH_DECAP_IP_TRILL_NSH, + HAL_TAU_PKT_TMH_DECAP_LAST + +} HAL_TAU_PKT_TMH_DECAP_T; + +typedef struct +{ + union + { + HAL_TAU_PKT_ITMH_ETH_T itmh_eth; + HAL_TAU_PKT_ETMH_FAB_T etmh_fab; + HAL_TAU_PKT_ETMH_ETH_T etmh_eth; + }; +} HAL_TAU_PKT_TMH_T; + +typedef struct +{ + union + { + HAL_TAU_PKT_PPH_L2_T pph_l2; + HAL_TAU_PKT_PPH_L3UC_T pph_l3uc; + HAL_TAU_PKT_PPH_L3MC_T pph_l3mc; + HAL_TAU_PKT_PPH_L25_T pph_l25; + }; +} HAL_TAU_PKT_PPH_T; + +/* ----------------------------------------------------------------------------------- Reg Type */ +typedef enum +{ + HAL_TAU_PKT_L2_ISR_RCH0 = (0x1 << 0), + HAL_TAU_PKT_L2_ISR_RCH1 = (0x1 << 1), + HAL_TAU_PKT_L2_ISR_RCH2 = (0x1 << 2), + HAL_TAU_PKT_L2_ISR_RCH3 = (0x1 << 3), + HAL_TAU_PKT_L2_ISR_TCH0 = (0x1 << 4), + HAL_TAU_PKT_L2_ISR_TCH1 = (0x1 << 5), + HAL_TAU_PKT_L2_ISR_TCH2 = (0x1 << 6), + HAL_TAU_PKT_L2_ISR_TCH3 = (0x1 << 7), + HAL_TAU_PKT_L2_ISR_RX_QID_MAP_ERR = (0x1 << 8), + HAL_TAU_PKT_L2_ISR_RX_FRAME_ERR = (0x1 << 9) + +} HAL_TAU_PKT_L2_ISR_T; + +typedef enum +{ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_HWO_ERROR = (0x1 << 0), /* Tx GPD.hwo = 0 */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR = (0x1 << 1), /* Tx GPD.chksm is error */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_NO_OVFL_ERROR = (0x1 << 2), /* S/W push too much GPD */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_DMA_READ_ERROR = (0x1 << 3), /* AXI Rd Error when do GPD read */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_BUF_SIZE_ERROR = (0x1 << 4), /* Tx GPD.data_buf_size = 0 */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_RUNT_ERROR = (0x1 << 5), /* Tx GPD.pkt_len < 64 */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_OVSZ_ERROR = (0x1 << 6), /* Tx GPD.pkt_len = 9217 */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_LEN_MISMATCH_ERROR = (0x1 << 7), /* Tx GPD.pkt_len != sum of data_buf_size */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PKTPL_DMA_READ_ERROR = (0x1 << 8), /* AXI Rd Error when do Payload read */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_COS_ERROR = (0x1 << 9), /* Tx GPD.cos is not match cos_to_tch_map */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_GT255_ERROR = (0x1 << 10), /* Multi-GPD packet's GPD# > 255 */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PFC = (0x1 << 11), /* */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_CREDIT_UDFL_ERROR = (0x1 << 12), /* Credit Underflow (count down to 0) */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_DMA_WRITE_ERROR = (0x1 << 13), /* AXI Wr Error (GPD Write-Back) */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_STOP_CMD_CPLT = (0x1 << 14) + +} HAL_TAU_PKT_TX_CHANNEL_L2_ISR_T; + +typedef enum +{ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_LOW = (0x1 << 0), /* Rx GPD.avbl_gpd_num < threshold */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_EMPTY = (0x1 << 1), /* Rx GPD.avbl_gpd_num = 0 */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_ERROR = (0x1 << 2), /* Rx GPD.hwo = 0 */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR = (0x1 << 3), /* Rx GPD.chksm is error */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_READ_ERROR = (0x1 << 4), /* DMAR error occurs in PCIE */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_WRITE_ERROR = (0x1 << 5), /* DMAW error occurs in PCIE */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_STOP_CMD_CPLT = (0x1 << 6), /* Stop Completion Acknowledge */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_GT255_ERROR = (0x1 << 7), /* Multi-GPD packet's GPD# > 255 */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_TOD_UNINIT = (0x1 << 8), /* */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_PKT_ERROR_DROP = (0x1 << 9), /* */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_UDSZ_DROP = (0x1 << 10), /* */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_OVSZ_DROP = (0x1 << 11), /* */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_CMDQ_OVF_DROP = (0x1 << 12), /* */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_FIFO_OVF_DROP = (0x1 << 13) + +} HAL_TAU_PKT_RX_CHANNEL_L2_ISR_T; + +typedef enum +{ + HAL_TAU_PKT_TX_CHANNEL_CFG_IOC = (0x1 << 0), + HAL_TAU_PKT_TX_CHANNEL_CFG_CHKSUM = (0x1 << 1), + HAL_TAU_PKT_TX_CHANNEL_CFG_PFC = (0x1 << 2), + HAL_TAU_PKT_TX_CHANNEL_CFG_PKT_LEN_CHK = (0x1 << 3), + HAL_TAU_PKT_TX_CHANNEL_CFG_EARLY_DONE_IRQ = (0x1 << 4), + HAL_TAU_PKT_TX_CHANNEL_CFG_CHK_COS = (0x1 << 5), + HAL_TAU_PKT_TX_CHANNEL_CFG_ADV_GPD_WRBK = (0x1 << 6), + HAL_TAU_PKT_TX_CHANNEL_CFG_GPD_WRBK_FULL_PKT_LEN = (0x1 << 7), + HAL_TAU_PKT_TX_CHANNEL_CFG_LAST = (0x1 << 8) + +} HAL_TAU_PKT_TX_CHANNEL_CFG_T; + +typedef enum +{ + HAL_TAU_PKT_RX_CHANNEL_CFG_IOC = (0x1 << 0), + HAL_TAU_PKT_RX_CHANNEL_CFG_CHKSUM = (0x1 << 1), + HAL_TAU_PKT_RX_CHANNEL_CFG_LAST = (0x1 << 2) + +} HAL_TAU_PKT_RX_CHANNEL_CFG_T; + +/* ----------------------------------------------------------------------------------- Tx */ +typedef enum +{ + HAL_TAU_PKT_TX_CHANNEL_0 = 0, + HAL_TAU_PKT_TX_CHANNEL_1, + HAL_TAU_PKT_TX_CHANNEL_2, + HAL_TAU_PKT_TX_CHANNEL_3, + HAL_TAU_PKT_TX_CHANNEL_LAST + +} HAL_TAU_PKT_TX_CHANNEL_T; + +typedef void +(*HAL_TAU_PKT_TX_FUNC_T)( + const UI32_T unit, + const void *ptr_sw_gpd, /* SW-GPD to be processed */ + void *ptr_coockie); /* Private data of SDK */ + +typedef struct HAL_TAU_PKT_TX_SW_GPD_S +{ + HAL_TAU_PKT_TX_FUNC_T callback; /* (unit, ptr_sw_gpd, ptr_cookie) */ + void *ptr_cookie; /* Pointer of NPS_PKT_TX_PKT_T */ + HAL_TAU_PKT_TX_GPD_T tx_gpd; + UI32_T gpd_num; + struct HAL_TAU_PKT_TX_SW_GPD_S *ptr_next; + +#if defined (NPS_EN_NETIF) + UI32_T channel; /* For counter */ +#endif + +} HAL_TAU_PKT_TX_SW_GPD_T; + +typedef struct +{ + UI32_T send_ok; + UI32_T gpd_empty; + UI32_T poll_timeout; + + /* queue */ + UI32_T enque_ok; + UI32_T enque_retry; + + /* event */ + UI32_T trig_event; + + /* normal interrupt */ + UI32_T tx_done; + + /* abnormal interrupt */ + UI32_T gpd_hwo_err; /* bit-0 */ + UI32_T gpd_chksm_err; /* bit-1 */ + UI32_T gpd_no_ovfl_err; /* bit-2 */ + UI32_T gpd_dma_read_err; /* bit-3 */ + UI32_T buf_size_err; /* bit-4 */ + UI32_T runt_err; /* bit-5 */ + UI32_T ovsz_err; /* bit-6 */ + UI32_T len_mismatch_err; /* bit-7 */ + UI32_T pktpl_dma_read_err; /* bit-8 */ + UI32_T cos_err; /* bit-9 */ + UI32_T gpd_gt255_err; /* bit-10 */ + UI32_T pfc; /* bit-11 */ + UI32_T credit_udfl_err; /* bit-12 */ + UI32_T dma_write_err; /* bit-13 */ + UI32_T sw_issue_stop; /* bit-14 */ + + /* others */ + UI32_T err_recover; + UI32_T ecc_err; + +} HAL_TAU_PKT_TX_CHANNEL_CNT_T; + +typedef struct +{ + HAL_TAU_PKT_TX_CHANNEL_CNT_T channel[HAL_TAU_PKT_TX_CHANNEL_LAST]; + UI32_T invoke_gpd_callback; + UI32_T no_memory; + + /* queue */ + UI32_T deque_ok; + UI32_T deque_fail; + + /* event */ + UI32_T wait_event; + +} HAL_TAU_PKT_TX_CNT_T; + +/* ----------------------------------------------------------------------------------- Rx */ +typedef enum +{ + HAL_TAU_PKT_RX_CHANNEL_0 = 0, + HAL_TAU_PKT_RX_CHANNEL_1, + HAL_TAU_PKT_RX_CHANNEL_2, + HAL_TAU_PKT_RX_CHANNEL_3, + HAL_TAU_PKT_RX_CHANNEL_LAST +} HAL_TAU_PKT_RX_CHANNEL_T; + +typedef enum +{ + HAL_TAU_PKT_C_NEXT = 0, /* callback continuous */ + HAL_TAU_PKT_C_STOP = 1, + HAL_TAU_PKT_C_OTHERS = 2 +} HAL_TAU_PKT_CALLBACK_NO_T; + +typedef enum +{ + HAL_TAU_PKT_RX_CALLBACK_ACTION_INSERT = 0, + HAL_TAU_PKT_RX_CALLBACK_ACTION_APPEND = 1, + HAL_TAU_PKT_RX_CALLBACK_ACTION_DELETE = 2, + HAL_TAU_PKT_RX_CALLBACK_ACTION_DELETE_ALL = 3 +} HAL_TAU_PKT_RX_CALLBACK_ACTION_T; + +typedef HAL_TAU_PKT_CALLBACK_NO_T +(*HAL_TAU_PKT_RX_FUNC_T)( + const UI32_T unit, + const void *ptr_sw_gpd, /* SW-GPD to be processed */ + void *ptr_cookie); /* Private data of SDK */ + +typedef struct HAL_TAU_PKT_RX_CALLBACK_S +{ + HAL_TAU_PKT_RX_FUNC_T callback; /* (unit, ptr_sw_gpd, ptr_cookie) */ + void *ptr_cookie; + struct HAL_TAU_PKT_RX_CALLBACK_S *ptr_next; +} HAL_TAU_PKT_RX_CALLBACK_T; + +typedef struct HAL_TAU_PKT_RX_SW_GPD_S +{ + BOOL_T rx_complete; /* FALSE when PDMA error occurs */ + HAL_TAU_PKT_RX_GPD_T rx_gpd; + struct HAL_TAU_PKT_RX_SW_GPD_S *ptr_next; + +#if defined (NPS_EN_NETIF) + void *ptr_cookie; /* Pointer of virt-addr */ +#endif + +} HAL_TAU_PKT_RX_SW_GPD_T; + +typedef struct +{ + /* queue */ + UI32_T enque_ok; + UI32_T enque_retry; + UI32_T deque_ok; + UI32_T deque_fail; + + /* event */ + UI32_T trig_event; + + /* normal interrupt */ + UI32_T rx_done; + + /* abnormal interrupt */ + UI32_T avbl_gpd_low; /* bit-0 */ + UI32_T avbl_gpd_empty; /* bit-1 */ + UI32_T avbl_gpd_err; /* bit-2 */ + UI32_T gpd_chksm_err; /* bit-3 */ + UI32_T dma_read_err; /* bit-4 */ + UI32_T dma_write_err; /* bit-5 */ + UI32_T sw_issue_stop; /* bit-6 */ + UI32_T gpd_gt255_err; /* bit-7 */ + UI32_T tod_uninit; /* bit-8 */ + UI32_T pkt_err_drop; /* bit-9 */ + UI32_T udsz_drop; /* bit-10 */ + UI32_T ovsz_drop; /* bit-11 */ + UI32_T cmdq_ovf_drop; /* bit-12 */ + UI32_T fifo_ovf_drop; /* bit-13 */ + + /* others */ + UI32_T err_recover; + UI32_T ecc_err; + +#if defined (NPS_EN_NETIF) + /* it means that user doesn't create intf on that port */ + UI32_T netdev_miss; +#endif + + +} HAL_TAU_PKT_RX_CHANNEL_CNT_T; + +typedef struct +{ + HAL_TAU_PKT_RX_CHANNEL_CNT_T channel[HAL_TAU_PKT_RX_CHANNEL_LAST]; + UI32_T invoke_gpd_callback; + UI32_T no_memory; + + /* event */ + UI32_T wait_event; + +} HAL_TAU_PKT_RX_CNT_T; + +/* ----------------------------------------------------------------------------------- Reg */ +#if defined(NPS_EN_LITTLE_ENDIAN) + +typedef union +{ + UI32_T reg; + struct + { + UI32_T tch_axlen_cfg : 3; + UI32_T : 5; + UI32_T tch_axi_free_arvalid : 1; + UI32_T : 7; + UI32_T tch_arvalid_thrhold_cfg : 2; + UI32_T : 6; + UI32_T tch_rready_low_4_hdr : 1; + UI32_T tch_ios_crdt_add_en : 1; + UI32_T : 6; + } field; +} HAL_TAU_PKT_AXI_LEN_CFG_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T pdma_lbk_en : 1; + UI32_T : 3; + UI32_T pdma_lbk_plane : 2; + UI32_T : 2; + UI32_T pm_lbk_en : 1; + UI32_T : 7; + UI32_T pm_lbk_rqid : 6; + UI32_T : 2; + UI32_T : 8; + } field; +} HAL_TAU_PKT_LBK_CTRL_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T pdma_lbk_rqid0 : 6; + UI32_T : 2; + UI32_T pdma_lbk_rqid1 : 6; + UI32_T : 2; + UI32_T pdma_lbk_rqid2 : 6; + UI32_T : 2; + UI32_T pdma_lbk_rqid3 : 6; + UI32_T : 2; + } field; +} HAL_TAU_PKT_LBK_RQID0_3_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T pdma_lbk_rqid4 : 6; + UI32_T : 2; + UI32_T pdma_lbk_rqid5 : 6; + UI32_T : 2; + UI32_T pdma_lbk_rqid6 : 6; + UI32_T : 2; + UI32_T pdma_lbk_rqid7 : 6; + UI32_T : 2; + } field; +} HAL_TAU_PKT_LBK_RQID4_7_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T cos_pfc_sts0 : 8; + UI32_T cos_pfc_sts1 : 8; + UI32_T cos_pfc_sts2 : 8; + UI32_T cos_pfc_sts3 : 8; + } field; +} HAL_TAU_PKT_COS_PFC_STS_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T pdma_ela_en : 1; + UI32_T : 7; + UI32_T pdma_ela_valid_sel : 8; + UI32_T : 8; + UI32_T : 8; + } field; +} HAL_TAU_PKT_ELA_CTRL_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T pdma_ela_word0_sel : 8; + UI32_T pdma_ela_word1_sel : 8; + UI32_T pdma_ela_word2_sel : 8; + UI32_T pdma_ela_word3_sel : 8; + } field; +} HAL_TAU_PKT_ELA_SEL_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T ingr_pln_ios_credit_base_size_lo : 8; + UI32_T ingr_pln_ios_credit_base_size_hi : 8; + UI32_T ingr_pln_ios_credit_set : 1; + UI32_T : 7; + UI32_T : 1; + UI32_T ingr_pln_full_pkt_mode : 1; + UI32_T : 6; + } field; +} HAL_TAU_PKT_IGR_PLN_CREDIT_CFG_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T ingr_pln_cur_ios_credit_lo : 8; + UI32_T ingr_pln_cur_ios_credit_hi : 8; + UI32_T ingr_pln_ios_credit_ovfl : 1; + UI32_T ingr_pln_ios_credit_udfl : 1; + UI32_T : 6; + UI32_T : 8; + } field; +} HAL_TAU_PKT_IGR_PLN_CREDIT_STS_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T ingr_pln_ios_credit_rdy_lo_bound : 8; + UI32_T ingr_pln_ios_credit_rdy_hi_bound : 8; + UI32_T : 8; + UI32_T : 8; + } field; +} HAL_TAU_PKT_IGR_PLN_CREDIT_THR_REG_T; + + +typedef union +{ + UI32_T reg; + struct + { + UI32_T rch_stomp_crc_en : 1; + UI32_T : 7; + UI32_T rch_crc_regen_en : 1; + UI32_T : 7; + UI32_T rch_pfc_fun_en : 1; + UI32_T : 7; + UI32_T : 8; + } field; +} HAL_TAU_PKT_RCH_STOMP_CRC_CTRL_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T rch_ioc_en : 1; + UI32_T : 7; + UI32_T rch_chksm_en : 1; + UI32_T : 7; + UI32_T : 8; + UI32_T : 8; + } field; +} HAL_TAU_PKT_RCH_MISC_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T rch_gpd_pfc_lo : 8; + UI32_T rch_gpd_pfc_hi : 8; + UI32_T : 8; + UI32_T : 8; + } field; +} HAL_TAU_PKT_RCH_GPD_PFC_CTRL_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T rch_fifo_pfc_lo_lo : 8; + UI32_T rch_fifo_pfc_lo_hi : 3; + UI32_T : 5; + UI32_T rch_fifo_pfc_hi_lo : 8; + UI32_T rch_fifo_pfc_hi_hi : 3; + UI32_T : 5; + } field; +} HAL_TAU_PKT_RCH_FIFO_PFC_CTRL_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T rch_cmdq_pfc_lo : 5; + UI32_T : 3; + UI32_T rch_cmdq_pfc_hi : 5; + UI32_T : 3; + UI32_T : 8; + UI32_T : 8; + } field; +} HAL_TAU_PKT_RCH_CMDQ_PFC_CTRL_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T rch_start : 1; + UI32_T rch_resume : 1; + UI32_T rch_stop : 1; + UI32_T : 5; + UI32_T : 8; + UI32_T rch_gpd_add_no_lo : 8; + UI32_T rch_gpd_add_no_hi : 8; + } field; +} HAL_TAU_PKT_RCH_CMD_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T rch_fifo_ovf_drop_cnt_clr : 1; + UI32_T rch_cmdq_ovf_drop_cnt_clr : 1; + UI32_T rch_ovsz_drop_cnt_clr : 1; + UI32_T rch_udsz_drop_cnt_clr : 1; + UI32_T rch_pkterr_drop_cnt_clr : 1; + UI32_T rch_flush_cnt_clr : 1; + UI32_T : 2; + UI32_T : 8; + UI32_T : 8; + UI32_T : 8; + } field; +} HAL_TAU_PKT_RCH_CNT_CLR_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T rch_active : 1; + UI32_T rch_avbl_gpd_pfc : 1; + UI32_T rch_fifo_pfc : 1; + UI32_T rch_cmdq_pfc : 1; + UI32_T rch_pfc : 1; + UI32_T : 3; + UI32_T : 8; + UI32_T rch_avbl_gpd_no_lo : 8; + UI32_T rch_avbl_gpd_no_hi : 8; + } field; +} HAL_TAU_PKT_RCH_STATUS_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T tch_ioc_en : 1; + UI32_T tch_chksm_en : 1; + UI32_T tch_pfc_en : 1; + UI32_T tch_pktlen_chk_en : 1; + UI32_T tch_early_done_irq : 1; + UI32_T tch_chk_cos_en : 1; + UI32_T tch_adv_gpd_wrbk : 1; + UI32_T tch_gpd_wrbk_full_pkt_len : 1; + UI32_T : 8; + UI32_T : 8; + UI32_T : 8; + } field; +} HAL_TAU_PKT_TCH_CFG_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T tch_start : 1; + UI32_T tch_resume : 1; + UI32_T tch_stop : 1; + UI32_T : 5; + UI32_T : 8; + UI32_T tch_gpd_add_no_lo : 8; + UI32_T tch_gpd_add_no_hi : 8; + } field; +} HAL_TAU_PKT_TCH_CMD_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T tch_active : 1; + UI32_T tch_pfc : 1; + UI32_T tch_gpd_rd_dma_act : 1; + UI32_T : 5; + UI32_T : 8; + UI32_T tch_avbl_gpd_no : 1; + UI32_T : 7; + UI32_T : 8; + } field; +} HAL_TAU_PKT_TCH_STS_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T tch_gpd_dmar_qos : 4; + UI32_T : 4; + UI32_T tch_pkt_dmar_qos : 4; + UI32_T : 4; + UI32_T tch_gpd_dmaw_qos : 4; + UI32_T : 4; + UI32_T : 8; + } field; +} HAL_TAU_PKT_TCH_QOS_CFG_REG_T; + +#elif defined(NPS_EN_BIG_ENDIAN) + +typedef union +{ + UI32_T reg; + struct + { + UI32_T : 6; + UI32_T tch_ios_crdt_add_en : 1; + UI32_T tch_rready_low_4_hdr : 1; + UI32_T : 6; + UI32_T tch_arvalid_thrhold_cfg : 2; + UI32_T : 7; + UI32_T tch_axi_free_arvalid : 1; + UI32_T : 5; + UI32_T tch_axlen_cfg : 3; + } field; +} HAL_TAU_PKT_AXI_LEN_CFG_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T : 8; + UI32_T : 2; + UI32_T pm_lbk_rqid : 6; + UI32_T : 7; + UI32_T pm_lbk_en : 1; + UI32_T : 2; + UI32_T pdma_lbk_plane : 2; + UI32_T : 3; + UI32_T pdma_lbk_en : 1; + } field; +} HAL_TAU_PKT_LBK_CTRL_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T : 2; + UI32_T pdma_lbk_rqid3 : 6; + UI32_T : 2; + UI32_T pdma_lbk_rqid2 : 6; + UI32_T : 2; + UI32_T pdma_lbk_rqid1 : 6; + UI32_T : 2; + UI32_T pdma_lbk_rqid0 : 6; + } field; +} HAL_TAU_PKT_LBK_RQID0_3_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T : 2; + UI32_T pdma_lbk_rqid7 : 6; + UI32_T : 2; + UI32_T pdma_lbk_rqid6 : 6; + UI32_T : 2; + UI32_T pdma_lbk_rqid5 : 6; + UI32_T : 2; + UI32_T pdma_lbk_rqid4 : 6; + } field; +} HAL_TAU_PKT_LBK_RQID4_7_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T cos_pfc_sts3 : 8; + UI32_T cos_pfc_sts2 : 8; + UI32_T cos_pfc_sts1 : 8; + UI32_T cos_pfc_sts0 : 8; + } field; +} HAL_TAU_PKT_COS_PFC_STS_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T : 8; + UI32_T : 8; + UI32_T pdma_ela_valid_sel : 8; + UI32_T : 7; + UI32_T pdma_ela_en : 1; + } field; +} HAL_TAU_PKT_ELA_CTRL_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T pdma_ela_word3_sel : 8; + UI32_T pdma_ela_word2_sel : 8; + UI32_T pdma_ela_word1_sel : 8; + UI32_T pdma_ela_word0_sel : 8; + } field; +} HAL_TAU_PKT_ELA_SEL_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T : 6; + UI32_T ingr_pln_full_pkt_mode : 1; + UI32_T : 1; + UI32_T : 7; + UI32_T ingr_pln_ios_credit_set : 1; + UI32_T ingr_pln_ios_credit_base_size_hi : 8; + UI32_T ingr_pln_ios_credit_base_size_lo : 8; + } field; +} HAL_TAU_PKT_IGR_PLN_CREDIT_CFG_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T : 8; + UI32_T : 6; + UI32_T ingr_pln_ios_credit_udfl : 1; + UI32_T ingr_pln_ios_credit_ovfl : 1; + UI32_T ingr_pln_cur_ios_credit_hi : 8; + UI32_T ingr_pln_cur_ios_credit_lo : 8; + } field; +} HAL_TAU_PKT_IGR_PLN_CREDIT_STS_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T : 8; + UI32_T : 8; + UI32_T ingr_pln_ios_credit_rdy_hi_bound : 8; + UI32_T ingr_pln_ios_credit_rdy_lo_bound : 8; + } field; +} HAL_TAU_PKT_IGR_PLN_CREDIT_THR_REG_T; + + +typedef union +{ + UI32_T reg; + struct + { + UI32_T : 8; + UI32_T : 7; + UI32_T rch_pfc_fun_en : 1; + UI32_T : 7; + UI32_T rch_crc_regen_en : 1; + UI32_T : 7; + UI32_T rch_stomp_crc_en : 1; + } field; +} HAL_TAU_PKT_RCH_STOMP_CRC_CTRL_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T : 8; + UI32_T : 8; + UI32_T : 7; + UI32_T rch_chksm_en : 1; + UI32_T : 7; + UI32_T rch_ioc_en : 1; + } field; +} HAL_TAU_PKT_RCH_MISC_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T : 8; + UI32_T : 8; + UI32_T rch_gpd_pfc_hi : 8; + UI32_T rch_gpd_pfc_lo : 8; + } field; +} HAL_TAU_PKT_RCH_GPD_PFC_CTRL_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T : 5; + UI32_T rch_fifo_pfc_hi_hi : 3; + UI32_T rch_fifo_pfc_hi_lo : 8; + UI32_T : 5; + UI32_T rch_fifo_pfc_lo_hi : 3; + UI32_T rch_fifo_pfc_lo_lo : 8; + } field; +} HAL_TAU_PKT_RCH_FIFO_PFC_CTRL_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T : 8; + UI32_T : 8; + UI32_T : 3; + UI32_T rch_cmdq_pfc_hi : 5; + UI32_T : 3; + UI32_T rch_cmdq_pfc_lo : 5; + } field; +} HAL_TAU_PKT_RCH_CMDQ_PFC_CTRL_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T rch_gpd_add_no_hi : 8; + UI32_T rch_gpd_add_no_lo : 8; + UI32_T : 8; + UI32_T : 5; + UI32_T rch_stop : 1; + UI32_T rch_resume : 1; + UI32_T rch_start : 1; + } field; +} HAL_TAU_PKT_RCH_CMD_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T : 8; + UI32_T : 8; + UI32_T : 8; + UI32_T : 2; + UI32_T rch_flush_cnt_clr : 1; + UI32_T rch_pkterr_drop_cnt_clr : 1; + UI32_T rch_udsz_drop_cnt_clr : 1; + UI32_T rch_ovsz_drop_cnt_clr : 1; + UI32_T rch_cmdq_ovf_drop_cnt_clr : 1; + UI32_T rch_fifo_ovf_drop_cnt_clr : 1; + } field; +} HAL_TAU_PKT_RCH_CNT_CLR_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T rch_avbl_gpd_no_hi : 8; + UI32_T rch_avbl_gpd_no_lo : 8; + UI32_T : 8; + UI32_T : 3; + UI32_T rch_pfc : 1; + UI32_T rch_cmdq_pfc : 1; + UI32_T rch_fifo_pfc : 1; + UI32_T rch_avbl_gpd_pfc : 1; + UI32_T rch_active : 1; + } field; +} HAL_TAU_PKT_RCH_STATUS_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T : 8; + UI32_T : 8; + UI32_T : 8; + UI32_T tch_gpd_wrbk_full_pkt_len : 1; + UI32_T tch_adv_gpd_wrbk : 1; + UI32_T tch_chk_cos_en : 1; + UI32_T tch_early_done_irq : 1; + UI32_T tch_pktlen_chk_en : 1; + UI32_T tch_pfc_en : 1; + UI32_T tch_chksm_en : 1; + UI32_T tch_ioc_en : 1; + } field; +} HAL_TAU_PKT_TCH_CFG_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T tch_gpd_add_no_hi : 8; + UI32_T tch_gpd_add_no_lo : 8; + UI32_T : 8; + UI32_T : 5; + UI32_T tch_stop : 1; + UI32_T tch_resume : 1; + UI32_T tch_start : 1; + } field; +} HAL_TAU_PKT_TCH_CMD_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T : 8; + UI32_T : 7; + UI32_T tch_avbl_gpd_no : 1; + UI32_T : 8; + UI32_T : 5; + UI32_T tch_gpd_rd_dma_act : 1; + UI32_T tch_pfc : 1; + UI32_T tch_active : 1; + } field; +} HAL_TAU_PKT_TCH_STS_REG_T; + +typedef union +{ + UI32_T reg; + struct + { + UI32_T : 8; + UI32_T : 4; + UI32_T tch_gpd_dmaw_qos : 4; + UI32_T : 4; + UI32_T tch_pkt_dmar_qos : 4; + UI32_T : 4; + UI32_T tch_gpd_dmar_qos : 4; + } field; +} HAL_TAU_PKT_TCH_QOS_CFG_REG_T; + +#else +#error "Host GPD endian is not defined\n" +#endif + +/* ----------------------------------------------------------------------------------- NPS_EN_NETIF */ +#if defined (NPS_EN_NETIF) +#define HAL_TAU_PKT_DRIVER_MAJOR_NUM (10) +#define HAL_TAU_PKT_DRIVER_MINOR_NUM (252) /* DO NOT use MISC_DYNAMIC_MINOR */ +#define HAL_TAU_PKT_DRIVER_NAME "nps_netif" +#define HAL_TAU_PKT_DRIVER_PATH "/dev/"HAL_TAU_PKT_DRIVER_NAME + +/* These requirements come from NPS_NETIF APIs. + * nps_netif -> hal_pkt_drv -> hal_pkt_knl + */ + +typedef struct +{ + UI32_T tx_pkt; + UI32_T tx_queue_full; + UI32_T tx_error; + UI32_T rx_pkt; + +} HAL_TAU_PKT_NETIF_INTF_CNT_T; + +typedef struct +{ + /* unique key */ + UI32_T id; + C8_T name[NPS_NETIF_NAME_LEN]; + UI32_T port; /* only support unit port and local port */ + + /* metadata */ + UI8_T mac[6]; + +#define HAL_TAU_PKT_NETIF_INTF_FLAGS_MAC (1 << 0) + UI32_T flags; + + +} HAL_TAU_PKT_NETIF_INTF_T; + +typedef struct +{ + /* unique key */ + UI32_T id; + C8_T name[NPS_NETIF_NAME_LEN]; + UI32_T priority; + + /* match fields */ + UI32_T port; /* only support unit port and local port */ + HAL_TAU_PKT_RX_REASON_BITMAP_T reason_bitmap; + UI8_T pattern[NPS_NETIF_PROFILE_PATTERN_NUM][NPS_NETIF_PROFILE_PATTERN_LEN]; + UI8_T mask[NPS_NETIF_PROFILE_PATTERN_NUM][NPS_NETIF_PROFILE_PATTERN_LEN]; + UI32_T offset[NPS_NETIF_PROFILE_PATTERN_NUM]; + + /* for each flag 1:must hit, 0:don't care */ +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PORT (1 << 0) +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_REASON (1 << 1) +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_0 (1 << 2) +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_1 (1 << 3) +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_2 (1 << 4) +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_3 (1 << 5) + UI32_T flags; + +} HAL_TAU_PKT_NETIF_PROFILE_T; + + +/* These requirements come from NPS_PKT APIs. + * nps_pkt -> hal_pkt_srv -> hal_pkt_drv -> hal_pkt_knl + */ +typedef enum +{ + /* network interface */ + HAL_TAU_PKT_IOCTL_TYPE_CREATE_INTF = 0, + HAL_TAU_PKT_IOCTL_TYPE_DESTROY_INTF, + HAL_TAU_PKT_IOCTL_TYPE_GET_INTF, + HAL_TAU_PKT_IOCTL_TYPE_CREATE_PROFILE, + HAL_TAU_PKT_IOCTL_TYPE_DESTROY_PROFILE, + HAL_TAU_PKT_IOCTL_TYPE_GET_PROFILE, + HAL_TAU_PKT_IOCTL_TYPE_GET_INTF_CNT, + HAL_TAU_PKT_IOCTL_TYPE_CLEAR_INTF_CNT, + /* driver */ + HAL_TAU_PKT_IOCTL_TYPE_WAIT_RX_FREE, + HAL_TAU_PKT_IOCTL_TYPE_WAIT_TX_FREE, /* waitTxFree(ASYNC) */ + HAL_TAU_PKT_IOCTL_TYPE_SET_RX_CFG, /* setRxConfig */ + HAL_TAU_PKT_IOCTL_TYPE_GET_RX_CFG, /* getRxConfig */ + HAL_TAU_PKT_IOCTL_TYPE_DEINIT_TASK, /* deinitTask */ + HAL_TAU_PKT_IOCTL_TYPE_DEINIT_DRV, /* deinitDrv */ + HAL_TAU_PKT_IOCTL_TYPE_INIT_TASK, /* initTask */ + HAL_TAU_PKT_IOCTL_TYPE_INIT_DRV, /* initDrv */ + /* counter */ + HAL_TAU_PKT_IOCTL_TYPE_GET_TX_CNT, + HAL_TAU_PKT_IOCTL_TYPE_GET_RX_CNT, + HAL_TAU_PKT_IOCTL_TYPE_CLEAR_TX_CNT, + HAL_TAU_PKT_IOCTL_TYPE_CLEAR_RX_CNT, + /* port attribute */ + HAL_TAU_PKT_IOCTL_TYPE_SET_PORT_ATTR, + HAL_TAU_PKT_IOCTL_TYPE_LAST + +} HAL_TAU_PKT_IOCTL_TYPE_T; + +typedef enum +{ + HAL_TAU_PKT_IOCTL_RX_TYPE_INIT = 0, + HAL_TAU_PKT_IOCTL_RX_TYPE_DEINIT, + HAL_TAU_PKT_IOCTL_RX_TYPE_LAST, + +} HAL_TAU_PKT_IOCTL_RX_TYPE_T; + +typedef struct +{ + UI32_T unit; + UI32_T channel; + HAL_TAU_PKT_RX_CNT_T rx_cnt; + HAL_TAU_PKT_TX_CNT_T tx_cnt; + NPS_ERROR_NO_T rc; + +} HAL_TAU_PKT_IOCTL_CH_CNT_COOKIE_T; + +typedef struct +{ + UI32_T unit; + HAL_TAU_PKT_NETIF_INTF_T net_intf; /* addIntf[In,Out], delIntf[In] */ + HAL_TAU_PKT_NETIF_PROFILE_T net_profile; /* createProfile[In,Out], destroyProfile[In] */ + HAL_TAU_PKT_NETIF_INTF_CNT_T cnt; + NPS_ERROR_NO_T rc; + +} HAL_TAU_PKT_IOCTL_NETIF_COOKIE_T; + +typedef struct +{ + NPS_ADDR_T callback; /* (unit, ptr_sw_gpd, ptr_cookie) */ + NPS_ADDR_T cookie; /* Pointer of NPS_PKT_TX_PKT_T */ + UI32_T channel; + UI32_T gpd_num; + NPS_ADDR_T hw_gpd_addr; + NPS_ADDR_T sw_gpd_addr; + +} HAL_TAU_PKT_IOCTL_TX_GPD_T; + +typedef struct +{ + UI32_T unit; + UI32_T channel; /* sendGpd[In] */ + NPS_ADDR_T ioctl_gpd_addr; /* sendGpd[In] */ + NPS_ADDR_T done_sw_gpd_addr; /* waitTxFree[Out] */ + +} HAL_TAU_PKT_IOCTL_TX_COOKIE_T; + +typedef struct +{ + BOOL_T rx_complete; /* FALSE when PDMA error occurs */ + NPS_ADDR_T hw_gpd_addr; /* Pointer to HW GPD in user's SW GPD struct */ + NPS_ADDR_T dma_buf_addr; /* Pointer to DMA buffer allocated by the user (virtual) */ + +} HAL_TAU_PKT_IOCTL_RX_GPD_T; + +typedef struct +{ + UI32_T unit; + UI32_T channel; /* getRxCnt[In], clearRxInt[In] */ + NPS_ADDR_T ioctl_gpd_addr; /* waitRxFree[Out] */ + UI32_T buf_len; /* setRxCfg[In] */ + HAL_TAU_PKT_IOCTL_RX_TYPE_T rx_type; /* setRxCfg[In] */ + +} HAL_TAU_PKT_IOCTL_RX_COOKIE_T; + +typedef struct +{ + UI32_T port; + UI32_T status; + UI32_T speed; + +} HAL_TAU_PKT_IOCTL_PORT_COOKIE_T; + +typedef union +{ + UI32_T value; + struct + { + UI32_T unit : 6; /* Maximum unit number is 64. */ + HAL_TAU_PKT_IOCTL_TYPE_T type : 10; /* Maximum 1024 IOCTL types */ + UI32_T rsvd : 16; + } field; + +} HAL_TAU_PKT_IOCTL_CMD_T; + +#endif /* End of NPS_EN_NETIF */ + +NPS_ERROR_NO_T +hal_tau_pkt_sendGpd( + const UI32_T unit, + const HAL_TAU_PKT_TX_CHANNEL_T channel, + HAL_TAU_PKT_TX_SW_GPD_T *ptr_sw_gpd); + +/*---------------------------------------------------------------------------*/ +/* perf */ +NPS_ERROR_NO_T +hal_tau_pkt_getTxIntrCnt( + const UI32_T unit, + const UI32_T channel, + UI32_T *ptr_intr_cnt); + +NPS_ERROR_NO_T +hal_tau_pkt_getRxIntrCnt( + const UI32_T unit, + const UI32_T channel, + UI32_T *ptr_intr_cnt); + +/* ioctl */ +NPS_ERROR_NO_T +hal_tau_pkt_getTxKnlCnt( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_CH_CNT_COOKIE_T *ptr_cookie); + +NPS_ERROR_NO_T +hal_tau_pkt_getRxKnlCnt( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_CH_CNT_COOKIE_T *ptr_cookie); + +NPS_ERROR_NO_T +hal_tau_pkt_clearTxKnlCnt( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_TX_COOKIE_T *ptr_cookie); + +NPS_ERROR_NO_T +hal_tau_pkt_clearRxKnlCnt( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_RX_COOKIE_T *ptr_cookie); + +NPS_ERROR_NO_T +hal_tau_pkt_setRxKnlConfig( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_RX_COOKIE_T *ptr_cookie); + +NPS_ERROR_NO_T +hal_tau_pkt_getRxKnlConfig( + const UI32_T unit, + HAL_TAU_PKT_IOCTL_RX_COOKIE_T *ptr_cookie); + +/* perf */ +NPS_ERROR_NO_T +hal_tau_pkt_getNetDev( + const UI32_T unit, + const UI32_T port, + struct net_device **pptr_net_dev); + +NPS_ERROR_NO_T +hal_tau_pkt_prepareGpd( + const UI32_T unit, + const NPS_ADDR_T phy_addr, + const UI32_T len, + const UI32_T port, + HAL_TAU_PKT_TX_SW_GPD_T *ptr_sw_gpd); + +#endif /* end of HAL_TAU_PKT_KNL_H */ diff --git a/platform/nephos/nephos-modules/modules/src/inc/netif_osal.h b/platform/nephos/nephos-modules/modules/src/inc/netif_osal.h new file mode 100755 index 000000000000..40c8c9ebc358 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/inc/netif_osal.h @@ -0,0 +1,379 @@ +/* Copyright (C) 2019 Nephos, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program. + */ + +/* FILE NAME: netif_osal.h + * PURPOSE: + * It provide customer linux API. + * NOTES: + */ + +#ifndef NETIF_OSAL_H +#define NETIF_OSAL_H + +/* + * ENOMEM : 12 - Out of memory + * EFAULT : 14 - Bad address + * EBUSY : 16 - Device or resource busy + * ENODEV : 19 - No such device + * EINVAL : 22 - Invalid argument + + * + * NETDEV_TX_OK : 0x00 + * NETDEV_TX_BUSY : 0x10 + + * + * ETH_HLEN : 14 dmac + smac + etyp + * ETH_ZLEN : 60 minimum ethernet frame size + * ETH_DATA_LEN : 1500 + * ETH_FRAME_LEN : 1514 + * ETH_FCS_LEN : 4 + * + * ETH_P_IP : 0x0800 + * ETH_P_ARP : 0x0806 + * ETH_P_IPV6 : 0x86DD + * ETH_P_SLOW : 0x8809 + * ETH_P_1588 : 0x88F7 + + * + * NET_IP_ALIGN : 2 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* ----------------------------------------------------------------------------------- macro value */ +/* Thread */ +#define OSAL_THREAD_NAME_LEN (16) +#define OSAL_THREAD_DFT_NAME ("Unknown") + +/* Semaphore */ +#define OSAL_SEMA_NAME_LEN (16) +#define OSAL_SEMA_DFT_NAME ("Unknown") + +/* Event */ +#define OSAL_EVENT_NAME_LEN (16) +#define OSAL_EVENT_DFT_NAME ("Unknown") + +/* Spinlock */ +#define OSAL_SPIN_NAME_LEN (16) +#define OSAL_SPIN_DFT_NAME ("Unknown") + +/* Queue */ +#define OSAL_QUEUE_NAME_LEN (16) +#define OSAL_QUEUE_DFT_NAME ("Unknown") + +#define OSAL_PRN_BUF_SZ (256) +#define OSAL_TICKS_PER_SEC (1000000) + +/* ----------------------------------------------------------------------------------- struct */ +typedef struct linux_thread_s +{ + char name[OSAL_THREAD_NAME_LEN + 1]; + struct task_struct *ptr_task; + unsigned int is_stop; + struct linux_thread_s *ptr_prev; + struct linux_thread_s *ptr_next; + +} linux_thread_t; + +typedef struct +{ + char name[OSAL_SEMA_NAME_LEN + 1]; + struct semaphore lock; + +} linux_sema_t; + +typedef struct +{ + char name[OSAL_EVENT_NAME_LEN + 1]; + wait_queue_head_t wait_que; + unsigned int condition; + +} linux_event_t; + +typedef struct +{ + char name[OSAL_SPIN_NAME_LEN + 1]; + spinlock_t spinlock; + +} linux_isrlock_t; + +typedef struct +{ + void *ptr_data; +} linux_queue_entry_t; + +typedef struct +{ + char name[OSAL_QUEUE_NAME_LEN + 1]; + int head; /* index of the queue head entry can be read */ + int tail; /* index of the queue tail entry can be write */ + unsigned int wr_cnt; /* enqueue total count */ + unsigned int rd_cnt; /* dequeue total count */ + unsigned int capacity; /* the queue size */ + linux_queue_entry_t *ptr_entry; /* the queue entry buffer */ + +} linux_queue_t; + +typedef struct +{ + unsigned int size; + dma_addr_t phy_addr; + char data[0]; + +} linux_dma_t; + +/* ----------------------------------------------------------------------------------- function */ +void * +osal_memset( + void *ptr_mem, + const I32_T value, + const UI32_T num); + +void * +osal_memcpy( + void *ptr_dst, + const void *ptr_src, + const UI32_T num); + +UI32_T +osal_strlen( + const C8_T *ptr_str); + +void +osal_printf( + const C8_T *ptr_fmt, + ...); + +void * +osal_alloc( + const UI32_T size); + +void +osal_free( + const void *ptr_mem); + +/* thread */ +NPS_ERROR_NO_T +osal_init(void); + +NPS_ERROR_NO_T +osal_deinit(void); + +NPS_ERROR_NO_T +osal_createThread ( + const C8_T *ptr_thread_name, + const UI32_T stack_size, + const UI32_T priority, + void (function)(void*), + void *ptr_arg, + NPS_THREAD_ID_T *ptr_thread_id); + +NPS_ERROR_NO_T +osal_stopThread( + NPS_THREAD_ID_T *ptr_thread_id); + +NPS_ERROR_NO_T +osal_destroyThread( + NPS_THREAD_ID_T *ptr_thread_id); + +void +osal_initRunThread( + void); + +NPS_ERROR_NO_T +osal_isRunThread( + void); + +void +osal_exitRunThread( + void); + +/* semaphore */ +NPS_ERROR_NO_T +osal_createSemaphore( + const C8_T *ptr_sema_name, + const UI32_T sema_count, + NPS_SEMAPHORE_ID_T *ptr_semaphore_id); + +NPS_ERROR_NO_T +osal_takeSemaphore( + NPS_SEMAPHORE_ID_T *ptr_semaphore_id, + UI32_T time_out); + +NPS_ERROR_NO_T +osal_giveSemaphore( + NPS_SEMAPHORE_ID_T *ptr_semaphore_id); + +NPS_ERROR_NO_T +osal_destroySemaphore( + NPS_SEMAPHORE_ID_T *ptr_semaphore_id); + +/* event */ +NPS_ERROR_NO_T +osal_createEvent( + const C8_T *ptr_event_name, + NPS_SEMAPHORE_ID_T *ptr_event_id); + +NPS_ERROR_NO_T +osal_waitEvent( + NPS_SEMAPHORE_ID_T *ptr_event_id); + +NPS_ERROR_NO_T +osal_triggerEvent( + NPS_SEMAPHORE_ID_T *ptr_event_id); + +NPS_ERROR_NO_T +osal_destroyEvent( + NPS_SEMAPHORE_ID_T *ptr_event_id); + +/* isr_lock */ +NPS_ERROR_NO_T +osal_createIsrLock( + const C8_T *ptr_isrlock_name, + NPS_ISRLOCK_ID_T *ptr_isrlock_id); + +NPS_ERROR_NO_T +osal_takeIsrLock( + NPS_ISRLOCK_ID_T *ptr_isrlock_id, + NPS_IRQ_FLAGS_T *ptr_irq_flags); + +NPS_ERROR_NO_T +osal_giveIsrLock( + NPS_ISRLOCK_ID_T *ptr_isrlock_id, + NPS_IRQ_FLAGS_T *ptr_irq_flags); + +NPS_ERROR_NO_T +osal_destroyIsrLock( + NPS_ISRLOCK_ID_T *ptr_isrlock_id); + +/* timer */ +NPS_ERROR_NO_T +osal_sleepThread( + const UI32_T usecond); + +NPS_ERROR_NO_T +osal_getTime( + NPS_TIME_T *ptr_time); + +/* queue */ +NPS_ERROR_NO_T +osal_que_create( + NPS_HUGE_T *ptr_queue_id, + UI32_T capacity); + +NPS_ERROR_NO_T +osal_que_enque( + NPS_HUGE_T *ptr_queue_id, + void *ptr_data); + +NPS_ERROR_NO_T +osal_que_deque( + NPS_HUGE_T *ptr_queue_id, + void **pptr_data); + +NPS_ERROR_NO_T +osal_que_destroy( + NPS_HUGE_T *ptr_queue_id); + +NPS_ERROR_NO_T +osal_que_getCount( + NPS_HUGE_T *ptr_queue_id, + unsigned int *ptr_count); + +/* IO */ +int +osal_io_copyToUser( + void *ptr_usr_buf, + void *ptr_knl_buf, + unsigned int size); + +int +osal_io_copyFromUser( + void *ptr_knl_buf, + void *ptr_usr_buf, + unsigned int size); + +/* dma */ +void * +osal_dma_alloc( + const UI32_T size); + +NPS_ERROR_NO_T +osal_dma_free( + void *ptr_dma_mem); + +dma_addr_t +osal_dma_convertVirtToPhy( + void *ptr_virt_addr); + +void * +osal_dma_convertPhyToVirt( + const dma_addr_t phy_addr); + +int +osal_dma_flushCache( + void *ptr_virt_addr, + const unsigned int size); + +int +osal_dma_invalidateCache( + void *ptr_virt_addr, + const unsigned int size); + +/* skb */ +struct sk_buff * +osal_skb_alloc( + UI32_T size); + +void +osal_skb_free( + struct sk_buff *ptr_skb); + +dma_addr_t +osal_skb_mapDma( + struct sk_buff *ptr_skb, + enum dma_data_direction dir); + +void +osal_skb_unmapDma( + const dma_addr_t phy_addr, + UI32_T size, + enum dma_data_direction dir); + +void +osal_skb_send( + struct sk_buff *ptr_skb); + +void +osal_skb_recv( + struct sk_buff *ptr_skb); + +#endif /* end of NETIF_OSAL_H */ diff --git a/platform/nephos/nephos-modules/modules/src/inc/netif_perf.h b/platform/nephos/nephos-modules/modules/src/inc/netif_perf.h new file mode 100755 index 000000000000..35596668ba9d --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/inc/netif_perf.h @@ -0,0 +1,81 @@ +/* Copyright (C) 2019 Nephos, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program. + */ + +/* FILE NAME: netif_perf.h + * PURPOSE: + * It provide customer performance test API. + * NOTES: + */ + +#ifndef NETIF_PERF_H +#define NETIF_PERF_H + +/* #define PERF_EN_TEST */ + +/* FUNCTION NAME: perf_rxCallback + * PURPOSE: + * To count the Rx-gpd for Rx-test. + * INPUT: + * len -- To check if the Rx-gpd length equals to test length. + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successful operation. + * NOTES: + * None + */ +NPS_ERROR_NO_T +perf_rxCallback( + const UI32_T len); + +/* FUNCTION NAME: perf_rxTest + * PURPOSE: + * To check if Rx-test is going. + * INPUT: + * None + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successful operation. + * NOTES: + * None + */ +NPS_ERROR_NO_T +perf_rxTest( + void); + +/* FUNCTION NAME: perf_test + * PURPOSE: + * To do Tx-test or Rx-test. + * INPUT: + * len -- Test length + * tx_channel -- Test Tx channel numbers + * rx_channel -- Test Rx channel numbers + * test_skb -- Test GPD or SKB + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successful operation. + * NOTES: + * None + */ +NPS_ERROR_NO_T +perf_test( + UI32_T len, + UI32_T tx_channel, + UI32_T rx_channel, + BOOL_T test_skb); + +#endif /* end of NETIF_PERF_H */ diff --git a/platform/nephos/nephos-modules/modules/src/inc/nps_cfg.h b/platform/nephos/nephos-modules/modules/src/inc/nps_cfg.h new file mode 100755 index 000000000000..34306344c55a --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/inc/nps_cfg.h @@ -0,0 +1,317 @@ +/* Copyright (C) 2019 Nephos, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program. + */ + +/* FILE NAME: nps_cfg.h + * PURPOSE: + * Customer configuration on NPS SDK. + * NOTES: + */ + +#ifndef NPS_CFG_H +#define NPS_CFG_H + +/* INCLUDE FILE DECLARATIONS + */ + +#include +#include + + +/* NAMING CONSTANT DECLARATIONS + */ + +/* MACRO FUNCTION DECLARATIONS + */ +#define NPS_CFG_MAXIMUM_CHIPS_PER_SYSTEM (16) +#define NPS_CFG_USER_PORT_NUM (96) + +/* DATA TYPE DECLARATIONS + */ +typedef enum +{ + NPS_CFG_TYPE_CHIP_MODE, /* chip operating mode. 0: legacy mode, 1:hybrid mode */ + + NPS_CFG_TYPE_PORT_MAX_SPEED, /* Reference to NPS_PORT_SPEED_XXX */ + NPS_CFG_TYPE_PORT_LANE_NUM, + NPS_CFG_TYPE_PORT_TX_LANE, + NPS_CFG_TYPE_PORT_RX_LANE, + NPS_CFG_TYPE_PORT_TX_POLARITY_REV, + NPS_CFG_TYPE_PORT_RX_POLARITY_REV, + NPS_CFG_TYPE_PORT_EXT_LANE, + NPS_CFG_TYPE_PORT_VALID, + + /* l2 module related configuration */ + NPS_CFG_TYPE_L2_THREAD_PRI, + NPS_CFG_TYPE_L2_THREAD_STACK, /* customize L2 thread stack size in bytes */ + NPS_CFG_TYPE_L2_ADDR_MODE, /* L2 address operation mode. 0: Polling mode, 1: FIFO mode */ + + /* PKT module related configuration */ + NPS_CFG_TYPE_PKT_TX_GPD_NUM, + NPS_CFG_TYPE_PKT_RX_GPD_NUM, + NPS_CFG_TYPE_PKT_RX_SCHED_MODE, /* 0: RR mode, 1: WRR mode */ + NPS_CFG_TYPE_PKT_TX_QUEUE_LEN, + NPS_CFG_TYPE_PKT_RX_QUEUE_LEN, + NPS_CFG_TYPE_PKT_RX_QUEUE_WEIGHT, /* valid while NPS_CFG_TYPE_PKT_RX_SCHED_MODE is 1 + * param0: queue + * param1: NA + * value : weight + */ + NPS_CFG_TYPE_PKT_RX_ISR_THREAD_PRI, + NPS_CFG_TYPE_PKT_RX_ISR_THREAD_STACK, /* customize PKT RX ISR thread stack size in bytes */ + NPS_CFG_TYPE_PKT_RX_FREE_THREAD_PRI, + NPS_CFG_TYPE_PKT_RX_FREE_THREAD_STACK, /* customize PKT RX free thread stack size in bytes */ + NPS_CFG_TYPE_PKT_TX_ISR_THREAD_PRI, + NPS_CFG_TYPE_PKT_TX_ISR_THREAD_STACK, /* customize PKT TX ISR thread stack size in bytes */ + NPS_CFG_TYPE_PKT_TX_FREE_THREAD_PRI, + NPS_CFG_TYPE_PKT_TX_FREE_THREAD_STACK, /* customize PKT TX free thread stack size in bytes */ + NPS_CFG_TYPE_PKT_ERROR_ISR_THREAD_PRI, + NPS_CFG_TYPE_PKT_ERROR_ISR_THREAD_STACK, /* customize PKT ERROR ISR thread stack size in bytes */ + + /* STAT module related configuration */ + NPS_CFG_TYPE_CNT_THREAD_PRI, + NPS_CFG_TYPE_CNT_THREAD_STACK, /* customize CNT thread stack size in bytes */ + + /* IFMON module related configuration */ + NPS_CFG_TYPE_IFMON_THREAD_PRI, + NPS_CFG_TYPE_IFMON_THREAD_STACK, /* customize IFMON thread stack size in bytes */ + + /* share memory related configuration */ + NPS_CFG_TYPE_SHARE_MEM_SDN_ENTRY_NUM, /* SDN flow table entry number from share memory */ + NPS_CFG_TYPE_SHARE_MEM_L3_ENTRY_NUM, /* L3 entry number from share memory */ + NPS_CFG_TYPE_SHARE_MEM_L2_ENTRY_NUM, /* L2 entry number from share memory */ + + /* DLB related configuration */ + NPS_CFG_TYPE_DLB_MONITOR_MODE, /* DLB monitor mode. 1: async, 0: sync */ + NPS_CFG_TYPE_DLB_LAG_MONITOR_THREAD_PRI, + NPS_CFG_TYPE_DLB_LAG_MONITOR_THREAD_SLEEP_TIME, + NPS_CFG_TYPE_DLB_L3_MONITOR_THREAD_PRI, + NPS_CFG_TYPE_DLB_L3_MONITOR_THREAD_SLEEP_TIME, + NPS_CFG_TYPE_DLB_L3_INTR_THREAD_PRI, + NPS_CFG_TYPE_DLB_NVO3_MONITOR_THREAD_PRI, + NPS_CFG_TYPE_DLB_NVO3_MONITOR_THREAD_SLEEP_TIME, + NPS_CFG_TYPE_DLB_NVO3_INTR_THREAD_PRI, + + /* l3 related configuration */ + NPS_CFG_TYPE_L3_ECMP_MIN_BLOCK_SIZE, + NPS_CFG_TYPE_L3_ECMP_BLOCK_SIZE, + NPS_CFG_TYPE_TCAM_L3_WITH_IPV6_PREFIX_128_REGION_ENTRY_NUM, + NPS_CFG_TYPE_TCAM_L3_WITH_IPV6_PREFIX_64_REGION_ENTRY_NUM, + + /* share memory related configuration */ + NPS_CFG_TYPE_HASH_L2_FDB_REGION_ENTRY_NUM, + NPS_CFG_TYPE_HASH_L2_GROUP_REGION_ENTRY_NUM, + NPS_CFG_TYPE_HASH_SECURITY_REGION_ENTRY_NUM, + NPS_CFG_TYPE_HASH_L3_WITH_IPV6_PREFIX_128_REGION_ENTRY_NUM, + NPS_CFG_TYPE_HASH_L3_WITH_IPV6_PREFIX_64_REGION_ENTRY_NUM, + NPS_CFG_TYPE_HASH_L3_WITHOUT_PREFIX_REGION_ENTRY_NUM, + NPS_CFG_TYPE_HASH_L3_RPF_REGION_ENTRY_NUM, + NPS_CFG_TYPE_HASH_FLOW_REGION_ENTRY_NUM, + + NPS_CFG_TYPE_PORT_FC_MODE, /* only use to init port TM buffer + * configuration for specific FC mode, + * which not enable/disable FC/PFC + * for the port/pcp. + * param0: port. + * param1: Invalid. + * value : 0, FC disable; + * 1, 802.3x FC; + * 2, PFC. + */ + NPS_CFG_TYPE_PORT_PFC_STATE, /* valid while NPS_CFG_TYPE_PORT_TYPE_FC_MODE + * of the port is PFC. + * param0: port. + * param1: pcp. + * value : 0, PFC disable; + * 1, PFC enable. + */ + NPS_CFG_TYPE_PORT_PFC_QUEUE_STATE, /* valid while NPS_CFG_TYPE_PORT_TYPE_FC_MODE + * of the port is PFC. + * param0: port. + * param1: queue. + * value : 0, PFC disable; + * 1, PFC enable; + */ + NPS_CFG_TYPE_PORT_PFC_MAPPING, /* valid while NPS_CFG_TYPE_PORT_FC_MODE + * of the port is PFC. + * param0: port. + * param1: queue. + * value : PCP bitmap; + * + */ + NPS_CFG_TYPE_TRILL_ENABLE, /* TRILL module related configuration */ + NPS_CFG_TYPE_USE_UNIT_PORT, /* use UNIT_PORT or native port of NPS_PORT_T + * 1 : UNIT_PORT, 0 : native port + */ + NPS_CFG_TYPE_MAC_VLAN_ENABLE, /* use dadicate mac vlan table */ + NPS_CFG_TYPE_CPI_PORT_MODE, /* use to init CPI port working mode. + * param0: CPI port number. + * param1: NA. + * value : 0, CPI mode. + * 1, Ether mode. + */ + NPS_CFG_TYPE_PHY_ADDR, + NPS_CFG_TYPE_LED_CFG, + NPS_CFG_TYPE_USER_BUF_CTRL, + NPS_CFG_TYPE_ARIES_SDP_MODE, /* Select which Aries parser to use + * value: 0, GTP (default) + * 1, PPPOE + * 2, TCP_SPLICING + */ + NPS_CFG_TYPE_FAIR_BUF_CTRL, /* to enable the fairness in flow-control traffic. + * value : 0, disable fairness. + * 1, enable fairness. + */ + NPS_CFG_TYPE_HRM_BUF_SIZE, /* to assign the head room size of port speed. + * param0: Port speed. + * 0, 1G (default) + * 1, 10G + * 2, 25G + * 3, 40G + * 4, 50G + * 5, 100G + * value : cell number. + */ + NPS_CFG_TYPE_STEERING_TRUNCATE_ENABLE, /* set value 0: Do not truncate steering packets. + * set value 1: steering packets will be trucated to 1 cell and + * the cell size is based on chip. + */ + NPS_CFG_TYPE_FABRIC_MODE_ENABLE, /* set value 0: Non-farbic chip mode. (default) + * set value 1: Fabric chip mode. + */ + NPS_CFG_TYPE_ACL_TCP_FLAGS_ENCODE_ENABLE, /* set value 0: Do not encode tcp flags at acl entry. + * (Can only match bit 0-6 of tcp flags.) + * set value 1: Encode tcp flags at acl entry. (default) + */ + NPS_CFG_TYPE_TCAM_ECC_SCAN_ENABLE, /* set value 0: Disable ECC TCAM scanning. (default) + * set value 1: Enable ECC TCAM scanning. + */ + NPS_CFG_TYPE_PORT_BUF_MAX, /* + * Port max buffer threshold and unit is cell count. + * param0: port. + * param1: 0, ingress; + * 1, egress. + * value : 0, disable; + * others, enable max threshold. + */ + NPS_CFG_TYPE_INGRESS_DYNAMIC_BUF, /* + * Queue dynamic alpha setting and value will be + * enlarge to multiple of 256. For example, set value + * as 16 to indicate alpha as 1/16. Set value + * as 256 to indicate alpha as 1. + * param0: port. + * param1: queue (0~7: sc). + * value : alpha * 256. + */ + NPS_CFG_TYPE_EGRESS_DYNAMIC_BUF, /* + * Queue dynamic alpha setting and value will be + * enlarge to multiple of 256. For example, set value + * as 16 to indicate alpha as 1/16. Set value + * as 256 to indicate alpha as 1. + * param0: port. + * param1: queue (0~7: uc, 8~15: mc). + * value : alpha * 256. + */ + + + NPS_CFG_TYPE_DCQCN_ENABLE, /* set value 0: Disable DCQCN. (default) + * set value 1: Enable DCQCN. + */ + + + NPS_CFG_TYPE_LAST + +}NPS_CFG_TYPE_T; + +typedef struct NPS_CFG_VALUE_S +{ + UI32_T param0; /*(Optional) The optional parameter which is available + * when the NPS_CFG_TYPE_T needs the first arguments*/ + UI32_T param1; /*(Optional) The optional parameter which is available + * when the NPS_CFG_TYPE_T needs the second arguments*/ + I32_T value; + +}NPS_CFG_VALUE_T; + +typedef NPS_ERROR_NO_T + (*NPS_CFG_GET_FUNC_T)( + const UI32_T unit, + const NPS_CFG_TYPE_T cfg_type, + NPS_CFG_VALUE_T *ptr_cfg_value); + +typedef NPS_ERROR_NO_T + (*NPS_CFG_GET_LED_FUNC_T) +( + const UI32_T unit, + UI32_T **pptr_led_cfg, + UI32_T *ptr_cfg_size); + +/* EXPORTED SUBPROGRAM SPECIFICATIONS + */ + +/* FUNCTION NAME: nps_cfg_register + * PURPOSE: + * The function is to register NPS_CFG_GET_FUNC to SDK. + * + * INPUT: + * unit -- Device unit number. + * ptr_cfg_callback -- function to get the configuration value. + * + * OUTPUT: + * None + * + * RETURN: + * NPS_E_OK -- Operate success. + * NPS_E_BAD_PARAMETER -- Bad parameter. + * + * NOTES: + * 1. During SDK initializtion, it will call registered NPS_CFG_GET_FUNC to get configuration + * and apply them. + * If No registered NPS_CFG_GET_FUNC or can not get specified NPS_CFG_TYPE_T + * configuration, SDK will apply default setting. + * 2. This function should be called before calling nps_init + */ +NPS_ERROR_NO_T +nps_cfg_register( + const UI32_T unit, + NPS_CFG_GET_FUNC_T ptr_cfg_callback); + +/* FUNCTION NAME: nps_cfg_led_register + * PURPOSE: + * The function is to register NPS_CFG_GET_FUNC to SDK. + * + * INPUT: + * unit -- Device unit number. + * ptr_led_cfg_callback -- function to get LED configuration array. + * + * OUTPUT: + * None + * + * RETURN: + * NPS_E_OK -- Operate success. + * NPS_E_BAD_PARAMETER -- Bad parameter. + * + * NOTES: + * 1. During SDK initializtion, it will call registered NPS_CFG_GET_FUNC to get configuration + * and apply them. + * If No registered NPS_CFG_GET_LED_FUNC or can not get specified external LED cfg + * configuration, SDK will apply default setting. + * 2. This function should be called before calling nps_init + */ +NPS_ERROR_NO_T +nps_cfg_led_register( + const UI32_T unit, + NPS_CFG_GET_LED_FUNC_T ptr_led_cfg_callback); + +#endif /* NPS_CFG_H */ diff --git a/platform/nephos/nephos-modules/modules/src/inc/nps_error.h b/platform/nephos/nephos-modules/modules/src/inc/nps_error.h new file mode 100755 index 000000000000..261878abf3cb --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/inc/nps_error.h @@ -0,0 +1,77 @@ +/* Copyright (C) 2019 Nephos, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program. + */ + +/* FILE NAME: nps_error.h + * PURPOSE: + * Define the generic error code on NPS SDK. + * NOTES: + */ + +#ifndef NPS_ERROR_H +#define NPS_ERROR_H + +/* INCLUDE FILE DECLARATIONS + */ +#include + + +/* NAMING CONSTANT DECLARATIONS + */ + +/* MACRO FUNCTION DECLARATIONS + */ + +/* DATA TYPE DECLARATIONS + */ + +typedef enum +{ + NPS_E_OK = 0, /* Ok and no error */ + NPS_E_BAD_PARAMETER, /* Parameter is wrong */ + NPS_E_NO_MEMORY, /* No memory is available */ + NPS_E_TABLE_FULL, /* Table is full */ + NPS_E_ENTRY_NOT_FOUND, /* Entry is not found */ + NPS_E_ENTRY_EXISTS, /* Entry already exists */ + NPS_E_NOT_SUPPORT, /* Feature is not supported */ + NPS_E_ALREADY_INITED, /* Module is reinitialized */ + NPS_E_NOT_INITED, /* Module is not initialized */ + NPS_E_OTHERS, /* Other errors */ + NPS_E_ENTRY_IN_USE, /* Entry is in use */ + NPS_E_LAST +} NPS_ERROR_NO_T; + +/* EXPORTED SUBPROGRAM SPECIFICATIONS + */ +/* FUNCTION NAME: nps_error_getString + * PURPOSE: + * To obtain the error string of the specified error code + * + * INPUT: + * cause -- The specified error code + * OUTPUT: + * None + * RETURN: + * Pointer to the target error string + * + * NOTES: + * + * + */ +C8_T * +nps_error_getString( + const NPS_ERROR_NO_T cause ); + +#endif /* NPS_ERROR_H */ + diff --git a/platform/nephos/nephos-modules/modules/src/inc/nps_types.h b/platform/nephos/nephos-modules/modules/src/inc/nps_types.h new file mode 100755 index 000000000000..5630b521404e --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/inc/nps_types.h @@ -0,0 +1,308 @@ +/* Copyright (C) 2019 Nephos, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program. + */ + +/* FILE NAME: nps_types.h + * PURPOSE: + * Define the commom data type in NPS SDK. + * NOTES: + */ + +#ifndef NPS_TYPES_H +#define NPS_TYPES_H + +/* INCLUDE FILE DECLARATIONS + */ + +#include + +/* NAMING CONSTANT DECLARATIONS + */ + +#define NPS_BIT_OFF 0 +#define NPS_BIT_ON 1 + +#define NPS_PORT_INVALID (0xFFFFFFFF) +#define NPS_SEG_INVALID (0xFFFFFFFF) + +/* for CPU Rx packet, indicate that the packet + * is not received from remote switch + */ +#define NPS_PATH_INVALID (0xFFFFFFFF) + + +#define NPS_SEMAPHORE_BINARY (1) +#define NPS_SEMAPHORE_SYNC (0) +#define NPS_SEMAPHORE_WAIT_FOREVER (0xFFFFFFFF) + +/* MACRO FUNCTION DECLARATIONS + */ +#if defined(NPS_EN_HOST_32_BIT_BIG_ENDIAN) || defined(NPS_EN_HOST_32_BIT_LITTLE_ENDIAN) +typedef unsigned int NPS_HUGE_T; +#elif defined(NPS_EN_HOST_64_BIT_BIG_ENDIAN) || defined(NPS_EN_HOST_64_BIT_LITTLE_ENDIAN) +typedef unsigned long long int NPS_HUGE_T; +#else +#error "The 32bit and 64bit compatible data type are not defined !!" +#endif + +#if defined(NPS_EN_64BIT_ADDR) +typedef unsigned long long int NPS_ADDR_T; +#else +typedef NPS_HUGE_T NPS_ADDR_T; +#endif + +#if defined(NPS_EN_HOST_64_BIT_BIG_ENDIAN) || defined(NPS_EN_HOST_64_BIT_LITTLE_ENDIAN) || defined(NPS_EN_64BIT_ADDR) +#define NPS_ADDR_64_HI(__addr__) ((__addr__) >> 32) +#define NPS_ADDR_64_LOW(__addr__) ((__addr__) & 0xFFFFFFFF) +#define NPS_ADDR_32_TO_64(__hi32__,__low32__) (((unsigned long long int)(__low32__)) | \ + (((unsigned long long int)(__hi32__)) << 32)) +#else +#define NPS_ADDR_64_HI(__addr__) (0) +#define NPS_ADDR_64_LOW(__addr__) (__addr__) +#define NPS_ADDR_32_TO_64(__hi32__,__low32__) (__low32__) +#endif + +#define NPS_BITMAP_SIZE(bit_num) ((((bit_num) - 1) / 32) + 1) +#define NPS_IPV4_IS_MULTICAST(addr) (0xE0000000 == ((addr) & 0xF0000000)) +#define NPS_IPV6_IS_MULTICAST(addr) (0xFF == (((UI8_T *)(addr))[0])) +#define NPS_MAC_IS_MULTICAST(mac) ((mac[0]) & (0x1)) + +/* DATA TYPE DECLARATIONS + */ +typedef UI8_T NPS_BIT_MASK_8_T; +typedef UI16_T NPS_BIT_MASK_16_T; +typedef UI32_T NPS_BIT_MASK_32_T; +typedef UI64_T NPS_BIT_MASK_64_T; + +typedef UI8_T NPS_MAC_T[6]; +typedef UI32_T NPS_IPV4_T; +typedef UI8_T NPS_IPV6_T[16]; + +typedef UI32_T NPS_TIME_T; + +/* Bridge Domain id data type. */ +typedef UI32_T NPS_BRIDGE_DOMAIN_T; + +/* TRILL nickname type. */ +typedef UI16_T NPS_TRILL_NICKNAME_T; + +typedef union NPS_IP_U +{ + + NPS_IPV4_T ipv4_addr; + NPS_IPV6_T ipv6_addr; + +}NPS_IP_T; + +typedef struct NPS_IP_ADDR_S +{ + NPS_IP_T ip_addr; + BOOL_T ipv4 ; +}NPS_IP_ADDR_T; + +/* Tunnel type*/ +typedef enum +{ + NPS_TUNNEL_TYPE_IPV4INIPV4 = 0, /* RFC2003, IPv4-in-IPv4 tunnel */ + NPS_TUNNEL_TYPE_IPV4INIPV6, /* RFC2003, IPv4-in-IPv6 tunnel */ + NPS_TUNNEL_TYPE_IPV6INIPV4, /* RFC2003, IPv6-in-IPv4 tunnel */ + NPS_TUNNEL_TYPE_IPV6INIPV6, /* RFC2003, IPv6-in-IPv6 tunnel */ + NPS_TUNNEL_TYPE_GREIPV4INIPV4, /* RFC2784/RFC2890,GRE IPv4-in-IPv4 tunnel */ + NPS_TUNNEL_TYPE_GREIPV6INIPV4, /* RFC2784/RFC2890,GRE IPv6-in-IPv4 tunnel */ + NPS_TUNNEL_TYPE_GREIPV4INIPV6, /* RFC2784/RFC2890,GRE IPv4-in-IPv6 tunnel */ + NPS_TUNNEL_TYPE_GREIPV6INIPV6, /* RFC2784/RFC2890,GRE IPv6-in-IPv6 tunnel */ + NPS_TUNNEL_TYPE_GRE_NSH, + NPS_TUNNEL_TYPE_6TO4, /* RFC3056, 6to4 tunnel*/ + NPS_TUNNEL_TYPE_ISATAP, /* RFC5214, ISATAP tunnel */ + NPS_TUNNEL_TYPE_NVGRE_L2, + NPS_TUNNEL_TYPE_NVGRE_V4, + NPS_TUNNEL_TYPE_NVGRE_V6, + NPS_TUNNEL_TYPE_NVGRE_NSH, + NPS_TUNNEL_TYPE_VXLAN, + NPS_TUNNEL_TYPE_GTP_V4, + NPS_TUNNEL_TYPE_GTP_V6, + NPS_TUNNEL_TYPE_MPLSINGRE, + NPS_TUNNEL_TYPE_VXLANGPE_L2, + NPS_TUNNEL_TYPE_VXLANGPE_V4, + NPS_TUNNEL_TYPE_VXLANGPE_V6, + NPS_TUNNEL_TYPE_VXLANGPE_NSH, + NPS_TUNNEL_TYPE_FLEX0_L2, + NPS_TUNNEL_TYPE_FLEX0_V4, + NPS_TUNNEL_TYPE_FLEX0_V6, + NPS_TUNNEL_TYPE_FLEX0_NSH, + NPS_TUNNEL_TYPE_FLEX1_L2, + NPS_TUNNEL_TYPE_FLEX1_V4, + NPS_TUNNEL_TYPE_FLEX1_V6, + NPS_TUNNEL_TYPE_FLEX1_NSH, + NPS_TUNNEL_TYPE_FLEX2_L2, + NPS_TUNNEL_TYPE_FLEX2_V4, + NPS_TUNNEL_TYPE_FLEX2_V6, + NPS_TUNNEL_TYPE_FLEX2_NSH, + NPS_TUNNEL_TYPE_FLEX3_L2, + NPS_TUNNEL_TYPE_FLEX3_V4, + NPS_TUNNEL_TYPE_FLEX3_V6, + NPS_TUNNEL_TYPE_FLEX3_NSH, + NPS_TUNNEL_TYPE_LAST +} NPS_TUNNEL_TYPE_T; + +/* tunnel key */ +typedef struct NPS_TUNNEL_KEY_S +{ + NPS_IP_ADDR_T src_ip; /* key: The outer source IP address used by tunnel encapsulation.*/ + NPS_IP_ADDR_T dst_ip; /* key: The outer destination IP address used by tunnel encapsulation. + * For automatic tunnel, this is not required. If not specified, + * its ip address value must be set to 0, but the IP version + * must be same with src_ip. + */ + NPS_TUNNEL_TYPE_T tunnel_type; /*key: The tunnel type.*/ +}NPS_TUNNEL_KEY_T; + +typedef UI16_T NPS_VLAN_T; +typedef UI32_T NPS_PORT_T; + +typedef enum{ + NPS_PORT_TYPE_NORMAL = 0, + NPS_PORT_TYPE_UNIT_PORT, + NPS_PORT_TYPE_LAG, + NPS_PORT_TYPE_VM_ETAG, + NPS_PORT_TYPE_VM_VNTAG, + NPS_PORT_TYPE_VM_VEPA, + NPS_PORT_TYPE_FCOE, + NPS_PORT_TYPE_IP_TUNNEL, + NPS_PORT_TYPE_TRILL, + NPS_PORT_TYPE_MPLS, + NPS_PORT_TYPE_MPLS_PW, + NPS_PORT_TYPE_CPU_PORT, + NPS_PORT_TYPE_SFC, + NPS_PORT_TYPE_LAST +}NPS_PORT_TYPE_T; + +/*support Green/Yellow/Red color*/ +typedef enum +{ + NPS_COLOR_GREEN = 0, + NPS_COLOR_YELLOW, + NPS_COLOR_RED, + NPS_COLOR_LAST +}NPS_COLOR_T; +typedef enum +{ + NPS_FWD_ACTION_FLOOD = 0, + NPS_FWD_ACTION_NORMAL, + NPS_FWD_ACTION_DROP, + NPS_FWD_ACTION_COPY_TO_CPU, + NPS_FWD_ACTION_REDIRECT_TO_CPU, + NPS_FWD_ACTION_FLOOD_COPY_TO_CPU, + NPS_FWD_ACTION_DROP_COPY_TO_CPU, + NPS_FWD_ACTION_LAST +} NPS_FWD_ACTION_T; + +typedef NPS_HUGE_T NPS_THREAD_ID_T; +typedef NPS_HUGE_T NPS_SEMAPHORE_ID_T; +typedef NPS_HUGE_T NPS_ISRLOCK_ID_T; +typedef NPS_HUGE_T NPS_IRQ_FLAGS_T; + +typedef enum +{ + NPS_DIR_INGRESS = 0, + NPS_DIR_EGRESS, + NPS_DIR_BOTH, + NPS_DIR_LAST +}NPS_DIR_T; + +typedef enum +{ + NPS_VLAN_ACTION_SET, + NPS_VLAN_ACTION_KEEP, + NPS_VLAN_ACTION_REMOVE, + NPS_VLAN_ACTION_LAST +} NPS_VLAN_ACTION_T; + +/* VLAN Precedence */ +/* 000 = SUBNET_PROTOCOL_MAC_PORT + * 001 = SUBNET_MAC_PROTOCOL_PORT + * 010 = PROTOCOL_SUBNET_MAC_PORT + * 011 = PROTOCOL_MAC_SUBNET_PORT + * 100 = MAC_SUBNET_PROTOCOL_PORT + * 101 = MAC_PROTOCOL_SUBNET_PORT + */ +typedef enum +{ + NPS_VLAN_PRECEDENCE_SUBNET_MAC_PROTOCOL_PORT = 1, + NPS_VLAN_PRECEDENCE_MAC_SUBNET_PROTOCOL_PORT = 4, + NPS_VLAN_PRECEDENCE_PORT_ONLY = 7, + NPS_VLAN_PRECEDENCE_FAVOR_TYPE = 8, + NPS_VLAN_PRECEDENCE_FAVOR_ADDR = 9, + NPS_VLAN_PRECEDENCE_LAST +} NPS_VLAN_PRECEDENCE_T; + +/* VLAN Tag Type */ +typedef enum +{ + NPS_VLAN_TAG_NONE = 0, /* UnTag */ + NPS_VLAN_TAG_SINGLE_PRI, /* Single Customer/Service Priority Tag */ + NPS_VLAN_TAG_SINGLE, /* Single Customer/Service Tag */ + NPS_VLAN_TAG_DOUBLE_PRI, /* Double Tag with any VID=0 */ + NPS_VLAN_TAG_DOUBLE, /* Double Tag */ + NPS_VLAN_TAG_LAST +} NPS_VLAN_TAG_T; + +typedef struct NPS_BUM_INFO_S +{ + UI32_T mcast_id; + UI32_T group_label; /* l2 da group label */ + UI32_T vid; /* used when FLAGS_ADD_VID is set */ + +#define NPS_BUM_INFO_FLAGS_MCAST_VALID (1 << 0) +#define NPS_BUM_INFO_FLAGS_TO_CPU (1 << 1) +#define NPS_BUM_INFO_FLAGS_ADD_VID (1 << 2) /* single tag to double tag (i.e) QinQ */ +#define NPS_BUM_INFO_FLAGS_TRILL_ALL_TREE (1 << 3) + UI32_T flags; +} NPS_BUM_INFO_T; + +typedef enum +{ + NPS_PHY_TYPE_INTERNAL = 0x0, + NPS_PHY_TYPE_EXTERNAL, + NPS_PHY_TYPE_LAST +} NPS_PHY_TYPE_T; + +typedef enum +{ + NPS_PHY_DEVICE_ADDR_PMA_PMD = 1, + NPS_PHY_DEVICE_ADDR_WIS = 2, + NPS_PHY_DEVICE_ADDR_PCS = 3, + NPS_PHY_DEVICE_ADDR_PHY_XS = 4, + NPS_PHY_DEVICE_ADDR_DTE_XS = 5, + NPS_PHY_DEVICE_ADDR_TC = 6, + NPS_PHY_DEVICE_ADDR_AN = 7, + NPS_PHY_DEVICE_ADDR_VENDOR_1 = 30, + NPS_PHY_DEVICE_ADDR_VENDOR_2 = 31, + NPS_PHY_DEVICE_ADDR_LAST +} NPS_PHY_DEVICE_ADDR_T; + +typedef struct NPS_RANGE_INFO_S +{ + UI32_T min_id; + UI32_T max_id; + UI32_T max_member_cnt; + +#define NPS_RANGE_INFO_FLAGS_MAX_MEMBER_CNT (1 << 0) + UI32_T flags; +} NPS_RANGE_INFO_T; + +/* EXPORTED SUBPROGRAM SPECIFICATIONS + */ + +#endif /* NPS_TYPES_H */ diff --git a/platform/nephos/nephos-modules/modules/src/inc/osal_mdc.h b/platform/nephos/nephos-modules/modules/src/inc/osal_mdc.h new file mode 100755 index 000000000000..47971bb38c8d --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/inc/osal_mdc.h @@ -0,0 +1,241 @@ +/* Copyright (C) 2019 Nephos, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program. + */ + +/* FILE NAME: osal_mdc.h + * PURPOSE: + * 1. Provide device operate from AML interface + * NOTES: + * + */ + +#ifndef OSAL_MDC_H +#define OSAL_MDC_H + +/* INCLUDE FILE DECLARATIONS */ +#include +#include + +#define OSAL_MDC_DRIVER_NAME "nps_dev" +#define OSAL_MDC_DRIVER_MISC_MAJOR_NUM (10) +#define OSAL_MDC_DRIVER_MISC_MINOR_NUM (250) +#define OSAL_MDC_PCI_BUS_WIDTH (4) + +#define OSAL_MDC_DMA_LIST_SZ_UNLIMITED (0) +#define OSAL_MDC_DMA_LIST_NAME "RSRV_DMA" +#define OSAL_MDC_DMA_SEMAPHORE_NAME "DMALIST" + +/* NAMING CONSTANT DECLARATIONS + */ + +/* linked list node */ +#if defined(NPS_LINUX_KERNEL_MODE) + +typedef struct OSAL_MDC_LIST_NODE_S +{ + void *ptr_data; /* node data */ + struct OSAL_MDC_LIST_NODE_S *ptr_next; /* point to next link node */ + struct OSAL_MDC_LIST_NODE_S *ptr_prev; /* point to previous link node */ +} OSAL_MDC_LIST_NODE_T; + +/* linked list head */ +typedef struct OSAL_MDC_LIST_S +{ + OSAL_MDC_LIST_NODE_T *ptr_head_node; /* linked list head node */ + OSAL_MDC_LIST_NODE_T *ptr_tail_node; /* linked list tail node */ + UI32_T capacity; /* max count of nodes in list + * size=0: the capacity is unlimited. + * size>0: the capacity is limited. + */ + UI32_T node_cnt; /* the count of nodes in the list */ +} OSAL_MDC_LIST_T; + +#endif /* End of defined(NPS_LINUX_KERNEL_MODE) */ + +typedef struct +{ + NPS_ADDR_T phy_addr; + void *ptr_virt_addr; + NPS_ADDR_T size; + +#if defined(NPS_EN_DMA_RESERVED) + BOOL_T available; +#endif + +} OSAL_MDC_DMA_NODE_T; + +typedef struct +{ +#if defined(NPS_EN_DMA_RESERVED) + void *ptr_rsrv_virt_addr; + NPS_ADDR_T rsrv_phy_addr; + NPS_ADDR_T rsrv_size; +#else + struct device *ptr_dma_dev; /* for allocate/free system memory */ +#endif + void *ptr_dma_list; /* the type should be casted again when use */ + NPS_SEMAPHORE_ID_T sema; + +} OSAL_MDC_DMA_INFO_T; + +#if defined(NPS_LINUX_USER_MODE) + +/* Data type of IOCTL argument for DMA management */ +typedef struct +{ +#if defined(NPS_EN_DMA_RESERVED) + NPS_ADDR_T rsrv_dma_phy_addr; /* information of reserved memory */ + NPS_ADDR_T rsrv_dma_size; +#else + NPS_ADDR_T phy_addr; /* information of system memory */ + NPS_ADDR_T size; +#endif +} OSAL_MDC_IOCTL_DMA_DATA_T; + +/* Data type of IOCTL argument for device initialization */ +#pragma pack (push,1) +typedef struct +{ + AML_DEV_ID_T id[NPS_CFG_MAXIMUM_CHIPS_PER_SYSTEM]; + NPS_ADDR_T pci_mmio_phy_start[NPS_CFG_MAXIMUM_CHIPS_PER_SYSTEM]; + NPS_ADDR_T pci_mmio_size[NPS_CFG_MAXIMUM_CHIPS_PER_SYSTEM]; + UI32_T dev_num; +} OSAL_MDC_IOCTL_DEV_DATA_T; +#pragma pack (pop) + +typedef enum +{ + OSAL_MDC_IOCTL_ACCESS_READ = 0, + OSAL_MDC_IOCTL_ACCESS_WRITE, + OSAL_MDC_IOCTL_ACCESS_READ_WRITE, + OSAL_MDC_IOCTL_ACCESS_NONE, + OSAL_MDC_IOCTL_ACCESS_LAST + +} OSAL_MDC_IOCTL_ACCESS_T; + +typedef enum +{ + OSAL_MDC_IOCTL_TYPE_MDC_INIT_DEV = 0, + OSAL_MDC_IOCTL_TYPE_MDC_DEINIT_DEV, + OSAL_MDC_IOCTL_TYPE_MDC_INIT_RSRV_DMA_MEM, + OSAL_MDC_IOCTL_TYPE_MDC_DEINIT_RSRV_DMA_MEM, + OSAL_MDC_IOCTL_TYPE_MDC_ALLOC_SYS_DMA_MEM, + OSAL_MDC_IOCTL_TYPE_MDC_FREE_SYS_DMA_MEM, + OSAL_MDC_IOCTL_TYPE_MDC_CONNECT_ISR, + OSAL_MDC_IOCTL_TYPE_MDC_DISCONNECT_ISR, + OSAL_MDC_IOCTL_TYPE_LAST + +} OSAL_MDC_IOCTL_TYPE_T; + +typedef union +{ + UI32_T value; + struct + { + UI32_T access : 2; /* 0:read, 1:write, 2:read and write, 3:none */ + UI32_T unit : 6; /* Maximum unit number is 64. */ + UI32_T size :14; /* Maximum IOCTL data size is 16KB. */ + UI32_T type :10; /* Maximum 1024 IOCTL types */ + } field; +} OSAL_MDC_IOCTL_CMD_T; + +typedef NPS_ERROR_NO_T +(*OSAL_MDC_IOCTL_CALLBACK_FUNC_T)( + const UI32_T unit, + void *ptr_data); + +#endif /* End of NPS_LINUX_USER_MODE */ + + +/* MACRO FUNCTION DECLARATIONS + */ + +/* DATA TYPE DECLARATIONS + */ + +/* EXPORTED SUBPROGRAM SPECIFICATIONS + */ +NPS_ERROR_NO_T +osal_mdc_readPciReg( + const UI32_T unit, + const UI32_T offset, + UI32_T *ptr_data, + const UI32_T len); + +NPS_ERROR_NO_T +osal_mdc_writePciReg( + const UI32_T unit, + const UI32_T offset, + const UI32_T *ptr_data, + const UI32_T len); + +NPS_ERROR_NO_T +osal_mdc_initDevice( + AML_DEV_T *ptr_dev_list, + UI32_T *ptr_dev_num); + +NPS_ERROR_NO_T +osal_mdc_deinitDevice(void); + +NPS_ERROR_NO_T +osal_mdc_initDmaMem(void); + +NPS_ERROR_NO_T +osal_mdc_deinitDmaMem(void); + +void * +osal_mdc_allocDmaMem( + const UI32_T size); + +NPS_ERROR_NO_T +osal_mdc_freeDmaMem( + void *ptr_virt_addr); + +NPS_ERROR_NO_T +osal_mdc_convertVirtToPhy( + void *ptr_virt_addr, + NPS_ADDR_T *ptr_phy_addr); + +NPS_ERROR_NO_T +osal_mdc_convertPhyToVirt( + const NPS_ADDR_T phy_addr, + void **pptr_virt_addr); + +NPS_ERROR_NO_T +osal_mdc_registerIsr( + const UI32_T unit, + AML_DEV_ISR_FUNC_T handler, + void *ptr_cookie); + +NPS_ERROR_NO_T +osal_mdc_connectIsr( + const UI32_T unit, + AML_DEV_ISR_FUNC_T handler, + AML_DEV_ISR_DATA_T *ptr_cookie); + +NPS_ERROR_NO_T +osal_mdc_disconnectIsr( + const UI32_T unit); + +NPS_ERROR_NO_T +osal_mdc_flushCache( + void *ptr_virt_addr, + const UI32_T size); + +NPS_ERROR_NO_T +osal_mdc_invalidateCache( + void *ptr_virt_addr, + const UI32_T size); + +#endif /* OSAL_MDC_H */ diff --git a/platform/nephos/nephos-modules/modules/src/inc/osal_types.h b/platform/nephos/nephos-modules/modules/src/inc/osal_types.h new file mode 100755 index 000000000000..48ac58aba335 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/inc/osal_types.h @@ -0,0 +1,319 @@ +/* Copyright (C) 2019 Nephos, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program. + */ + +/* FILE NAME: osal_types.h + * PURPOSE: + * Define the commom data type in NPS SDK. + * NOTES: + */ + +#ifndef OSAL_TYPES_H +#define OSAL_TYPES_H + +/* INCLUDE FILE DECLARATIONS + */ + +/* NAMING CONSTANT DECLARATIONS + */ + + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef NULL +#define NULL (void *)0 +#endif + + +#if defined(NPS_EN_HOST_64_BIT_BIG_ENDIAN) +#define UI64_MSW 0 +#define UI64_LSW 1 +#elif defined(NPS_EN_HOST_64_BIT_LITTLE_ENDIAN) +#define UI64_MSW 1 +#define UI64_LSW 0 +#else +#define UI64_MSW 1 +#define UI64_LSW 0 +#endif + +#if defined(NPS_EN_COMPILER_SUPPORT_LONG_LONG) +#define UI64_HI(dst) ((UI32_T)((dst) >> 32)) +#define UI64_LOW(dst) ((UI32_T)((dst) & 0xffffffff)) +#define UI64_ASSIGN(dst, high, low) ((dst) = ((long long)(high) << 32 | (long long)(low))) +#define UI64_SET(dst, src) ((dst) = (src)) +#define UI64_ADD_UI32(dst, src) ((dst) += ((long long)(src))) +#define UI64_SUB_UI32(dst, src) ((dst) -= ((long long)(src))) +#define UI64_ADD_UI64(dst, src) ((dst) += (src)) +#define UI64_SUB_UI64(dst, src) ((dst) -= (src)) +#define UI64_AND(dst, src) ((dst) &= (src)) +#define UI64_OR(dst, src) ((dst) |= (src)) +#define UI64_XOR(dst, src) ((dst) ^= (src)) +#define UI64_NOT(dst) ((dst) = ~(dst)) +#define UI64_MULT_UI32(dst, src) ((dst) *= (src)) +#define UI64_MULT_UI64(dst, src) ((dst) *= (src)) +/* UI64_T type data comparion: + * if data1 > data2 return 1 + * if data1 < data2 return -1 + * if data1 == data2 return 0 + */ +#define UI64_CMP(data1, data2) (((data1) > (data2)) ? 1 : (((data1) < (data2)) ? -1 : 0)) + +#else +#define UI64_HI(dst) ((dst).ui64[UI64_MSW]) +#define UI64_LOW(dst) ((dst).ui64[UI64_LSW]) +#define UI64_ASSIGN(dst, high, low) \ + do \ + { \ + UI64_HI(dst) = (high); \ + UI64_LOW(dst) = (low); \ + } while(0) + +#define UI64_SET(dst, src) \ + do \ + { \ + UI64_HI(dst) = UI64_HI(src); \ + UI64_LOW(dst) = UI64_LOW(src); \ + } while(0) + + +#define UI64_ADD_UI32(dst, src) \ + do \ + { \ + UI32_T _i_ = UI64_LOW(dst); \ + UI64_LOW(dst) += (src); \ + if (UI64_LOW(dst) < _i_) \ + { \ + UI64_HI(dst)++; \ + } \ + } while(0) + +#define UI64_SUB_UI32(dst, src) \ + do \ + { \ + UI32_T _i_ = UI64_LOW(dst); \ + UI64_LOW(dst) -= src; \ + if (UI64_LOW(dst) > _i_) \ + { \ + UI64_HI(dst)--; \ + } \ + } while(0) + + +#define UI64_ADD_UI64(dst, src) \ + do \ + { \ + UI32_T _i_ = UI64_LOW(dst); \ + UI64_LOW(dst) += UI64_LOW(src); \ + if (UI64_LOW(dst) < _i_) \ + { \ + UI64_HI(dst)++; \ + } \ + UI64_HI(dst) += UI64_HI(src); \ + } while(0) + +#define UI64_SUB_UI64(dst, src) \ + do { \ + UI32_T _i_ = UI64_LOW(dst); \ + UI64_LOW(dst) -= UI64_LOW(src); \ + if (UI64_LOW(dst) > _i_) \ + { \ + UI64_HI(dst)--; \ + } \ + UI64_HI(dst) -= UI64_HI(src); \ + } while(0) + + +#define UI64_AND(dst, src) \ + do { \ + UI64_HI(dst) &= UI64_HI(src); \ + UI64_LOW(dst) &= UI64_LOW(src); \ + } while(0) + +#define UI64_OR(dst, src) \ + do { \ + UI64_HI(dst) |= UI64_HI(src); \ + UI64_LOW(dst) |= UI64_LOW(src); \ + } while(0) + +#define UI64_XOR(dst, src) \ + do { \ + UI64_HI(dst) ^= UI64_HI(src); \ + UI64_LOW(dst) ^= UI64_LOW(src); \ + } while(0) + +#define UI64_NOT(dst) \ + do { \ + UI64_HI(dst) = ~UI64_HI(dst); \ + UI64_LOW(dst) = ~UI64_LOW(dst); \ + } while(0) + +/* UI64_T type data comparion: + * if data1 > data2 return 1 + * if data1 < data2 return -1 + * if data1 == data2 return 0 + */ +#define UI64_CMP(data1, data2) \ + (((data1).ui64[UI64_MSW] > (data2).ui64[UI64_MSW]) \ + ? 1 : (((data1).ui64[UI64_MSW] == (data2).ui64[UI64_MSW]) \ + ? (((data1).ui64[UI64_LSW] == (data2).ui64[UI64_LSW]) \ + ? 0 :(((data1).ui64[UI64_LSW] > (data2).ui64[UI64_LSW]) \ + ? 1 : -1)) : -1)) + +#define UI64_MULT_UI64(dst, src) \ + do \ + { \ + UI32_T _ret_low_ = 0; \ + UI32_T _ret_high_ = 0; \ + UI32_T _i_ = 0; \ + UI32_T _j_ = 0; \ + UI32_T _temp_ = 0; \ + UI32_T dst_t[4] = {0, 0, 0, 0}; \ + UI32_T src_t[4] = {0, 0, 0, 0}; \ + dst_t[0] = UI64_LOW(dst) & 0xFFFF; \ + dst_t[1] = UI64_LOW(dst) >> 16; \ + dst_t[2] = UI64_HI(dst) & 0xFFFF; \ + dst_t[3] = UI64_HI(dst) >> 16; \ + src_t[0] = UI64_LOW(src) & 0xFFFF; \ + src_t[1] = UI64_LOW(src) >> 16; \ + src_t[2] = UI64_HI(src) & 0xFFFF; \ + src_t[3] = UI64_HI(src) >> 16; \ + for(_i_ = 0; _i_ < 4; _i_++) \ + { \ + for(_j_ = 0; _j_ < 4; _j_++) \ + { \ + if((dst_t[_i_] != 0) && (src_t[_j_] != 0)) \ + { \ + _temp_ = dst_t[_i_] * src_t[_j_]; \ + if(0 == (_i_ + _j_)) \ + { \ + _ret_low_ += _temp_; \ + if (_ret_low_ < _temp_) \ + { \ + _ret_high_++; \ + } \ + } \ + if(1 == (_i_ + _j_)) \ + { \ + _ret_low_ += (_temp_ << 16); \ + if (_ret_low_ < (_temp_ << 16)) \ + { \ + _ret_high_++; \ + } \ + _ret_high_ += (_temp_ >> 16); \ + } \ + if(2 == (_i_+_j_)) \ + { \ + _ret_high_ += _temp_; \ + } \ + if(3 == (_i_ + _j_)) \ + { \ + _ret_high_ += (_temp_ << 16); \ + } \ + } \ + } \ + } \ + UI64_HI(dst) = _ret_high_; \ + UI64_LOW(dst) = _ret_low_; \ + } while(0) + +#define UI64_MULT_UI32(dst, src) \ + do \ + { \ + UI32_T _ret_low_ = 0; \ + UI32_T _ret_high_ = 0; \ + UI32_T _i_ = 0; \ + UI32_T _j_ = 0; \ + UI32_T _temp_ = 0; \ + UI32_T dst_t[4] = {0, 0, 0, 0}; \ + UI32_T src_t[2] = {0, 0}; \ + dst_t[0] = UI64_LOW(dst) & 0xFFFF; \ + dst_t[1] = UI64_LOW(dst) >> 16; \ + dst_t[2] = UI64_HI(dst) & 0xFFFF; \ + dst_t[3] = UI64_HI(dst) >> 16; \ + src_t[0] = src & 0xFFFF; \ + src_t[1] = src >> 16; \ + for(_i_ = 0; _i_ < 4; _i_++) \ + { \ + for(_j_ = 0; _j_ < 2; _j_++) \ + { \ + if((dst_t[_i_] != 0) && (src_t[_j_] != 0)) \ + { \ + _temp_ = dst_t[_i_] * src_t[_j_]; \ + if(0 == (_i_ + _j_)) \ + { \ + _ret_low_ += _temp_; \ + if (_ret_low_ < _temp_) \ + { \ + _ret_high_++; \ + } \ + } \ + if(1 == (_i_ + _j_)) \ + { \ + _ret_low_ += (_temp_ << 16); \ + if (_ret_low_ < (_temp_ << 16)) \ + { \ + _ret_high_++; \ + } \ + _ret_high_ += (_temp_ >> 16); \ + } \ + if(2 == (_i_ + _j_)) \ + { \ + _ret_high_ += _temp_; \ + } \ + if(3 == (_i_ + _j_)) \ + { \ + _ret_high_ += (_temp_ << 16); \ + } \ + } \ + } \ + } \ + UI64_HI(dst) = _ret_high_; \ + UI64_LOW(dst) = _ret_low_; \ + } while(0) + +#endif + +/* DATA TYPE DECLARATIONS + */ +typedef int BOOL_T; +typedef signed char I8_T; +typedef unsigned char UI8_T; +typedef signed short I16_T; +typedef unsigned short UI16_T; +typedef signed int I32_T; +typedef unsigned int UI32_T; +typedef char C8_T; + +#if defined(NPS_EN_COMPILER_SUPPORT_LONG_LONG) +typedef signed long long int I64_T; +typedef unsigned long long int UI64_T; +#else +typedef struct +{ + I32_T i64[2]; +} I64_T; + +typedef struct +{ + UI32_T ui64[2]; +} UI64_T; +#endif + +#endif /* OSAL_TYPES_H */ diff --git a/platform/nephos/nephos-modules/modules/src/make.mk b/platform/nephos/nephos-modules/modules/src/make.mk new file mode 100755 index 000000000000..e556ea10d765 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/make.mk @@ -0,0 +1,37 @@ +################################################################################ +# Copyright (C) 2019 Nephos, Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 of the GNU General Public +# License as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# version 2 along with this program. +################################################################################ +DEV_MODULE_NAME := nps_dev +NETIF_MODULE_NAME := nps_netif +################################################################################ +DEV_OBJS_TOTAL := ./src/osal_mdc.o ./src/osal_isymbol.o +NETIF_OBJS_TOTAL := ./src/hal_tau_pkt_knl.o ./src/netif_perf.o ./src/netif_osal.o + +obj-m := $(DEV_MODULE_NAME).o $(NETIF_MODULE_NAME).o +$(DEV_MODULE_NAME)-objs := $(DEV_OBJS_TOTAL) +$(NETIF_MODULE_NAME)-objs := $(NETIF_OBJS_TOTAL) + +KBUILD_EXTRA_SYMBOLS := $(BUILD_OUTPUT_DIR)/Module.symvers +################################################################################ +folder: + $(TEST_PATH) $(BUILD_OUTPUT_DIR) || $(MKDIR) $(BUILD_OUTPUT_DIR) + $(TEST_PATH) $(BUILD_OUTPUT_DIR)/src || $(MKDIR) $(BUILD_OUTPUT_DIR)/src + +compile:: folder + touch $(BUILD_OUTPUT_DIR)/Makefile + $(MAKE) -C $(OS_PATH) M=$(BUILD_OUTPUT_DIR) src=$(shell pwd) modules EXTRA_CFLAGS="$(EXTRA_CFLAGS)" KBUILD_EXTRA_SYMBOLS=$(KBUILD_EXTRA_SYMBOLS) +install:: + +clean:: diff --git a/platform/nephos/nephos-modules/modules/src/netif_osal.c b/platform/nephos/nephos-modules/modules/src/netif_osal.c new file mode 100755 index 000000000000..15599e3a0aa0 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/netif_osal.c @@ -0,0 +1,753 @@ +/* Copyright (C) 2019 Nephos, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program. + */ + +/* FILE NAME: netif_osal.c + * PURPOSE: + * It provide customer linux API. + * NOTES: + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) +#include +#endif +#include + +/* ----------------------------------------------------------------------------------- macro value */ +#define OSAL_US_PER_SECOND (1000000) /* macro second per second */ +#define OSAL_NS_PER_USECOND (1000) /* nano second per macro second */ + +/* ----------------------------------------------------------------------------------- macro function */ +#define OSAL_LOG_ERR(msg, ...) \ + osal_printf("\033[31m\033[0m"msg, __LINE__, ##__VA_ARGS__) + +/* ----------------------------------------------------------------------------------- struct */ +extern struct pci_dev *_ptr_ext_pci_dev; + +static linux_thread_t _osal_thread_head = {{0}}; + +/* ----------------------------------------------------------------------------------- function */ +/* general */ +void * +osal_memset( + void *ptr_mem, + const I32_T value, + const UI32_T num) +{ + return memset(ptr_mem, value, num); +} + +void * +osal_memcpy( + void *ptr_dst, + const void *ptr_src, + const UI32_T num) +{ + return memcpy(ptr_dst, ptr_src, num); +} + +UI32_T +osal_strlen( + const C8_T *ptr_str) +{ + return strlen(ptr_str); +} + +void +osal_printf( + const C8_T *ptr_fmt, + ...) +{ + va_list ap; + char buf[OSAL_PRN_BUF_SZ]; + + if (NULL != ptr_fmt) + { + va_start(ap, ptr_fmt); + vsnprintf(buf, OSAL_PRN_BUF_SZ, ptr_fmt, ap); + va_end(ap); + + printk("%s", buf); + } +} + +void * +osal_alloc( + const UI32_T size) +{ + return kmalloc(size, GFP_ATOMIC); +} + +void +osal_free( + const void *ptr_mem) +{ + kfree(ptr_mem); +} + +/* thread */ +NPS_ERROR_NO_T +osal_init(void) +{ + linux_thread_t *ptr_thread_head = &_osal_thread_head; + + memset(ptr_thread_head, 0x0, sizeof(linux_thread_t)); + + /* init */ + ptr_thread_head->ptr_prev = ptr_thread_head; + ptr_thread_head->ptr_next = ptr_thread_head; + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +osal_deinit(void) +{ + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +osal_createThread( + const C8_T *ptr_thread_name, + const UI32_T stack_size, + const UI32_T priority, + void (function)(void*), + void *ptr_arg, + NPS_THREAD_ID_T *ptr_thread_id) +{ + char dft_name[OSAL_THREAD_NAME_LEN + 1] = OSAL_THREAD_DFT_NAME; + linux_thread_t *ptr_thread_head = &_osal_thread_head; + linux_thread_t *ptr_thread_node = osal_alloc(sizeof(linux_thread_t)); + + /* process name */ + osal_memcpy(ptr_thread_node->name, (0 == osal_strlen(ptr_thread_name))? + dft_name : ptr_thread_name, OSAL_THREAD_NAME_LEN); + ptr_thread_node->name[OSAL_THREAD_NAME_LEN] = '\0'; + + /* init */ + ptr_thread_node->ptr_task = kthread_create((int(*)(void *))function, ptr_arg, ptr_thread_name); + ptr_thread_node->ptr_task->policy = SCHED_RR; + ptr_thread_node->ptr_task->rt_priority = priority; + ptr_thread_node->is_stop = FALSE; + + *ptr_thread_id = (NPS_THREAD_ID_T)ptr_thread_node; + + wake_up_process(ptr_thread_node->ptr_task); + + /* append the thread_node */ + ptr_thread_node->ptr_prev = ptr_thread_head->ptr_prev; + ptr_thread_head->ptr_prev->ptr_next = ptr_thread_node; + ptr_thread_node->ptr_next = ptr_thread_head; + ptr_thread_head->ptr_prev = ptr_thread_node; + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +osal_stopThread( + NPS_THREAD_ID_T *ptr_thread_id) +{ + linux_thread_t *ptr_thread_node = (linux_thread_t *)(*ptr_thread_id); + + ptr_thread_node->is_stop = TRUE; + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +osal_destroyThread( + NPS_THREAD_ID_T *ptr_thread_id) +{ + linux_thread_t *ptr_thread_node = (linux_thread_t *)(*ptr_thread_id); + + kthread_stop(ptr_thread_node->ptr_task); + + /* remove the thread_node */ + ptr_thread_node->ptr_next->ptr_prev = ptr_thread_node->ptr_prev; + ptr_thread_node->ptr_prev->ptr_next = ptr_thread_node->ptr_next; + + osal_free(ptr_thread_node); + *ptr_thread_id = 0; + + return (NPS_E_OK); +} + +void +osal_initRunThread(void) +{ + /* for reboot or shutdown without stopping kthread */ + allow_signal(SIGTERM); +} + +NPS_ERROR_NO_T +osal_isRunThread(void) +{ + linux_thread_t *ptr_thread_node = _osal_thread_head.ptr_next; + + while (1) + { + if (ptr_thread_node == &_osal_thread_head) + { + OSAL_LOG_ERR("Cannot find task 0x%x.\n", current); + break; + } + if (ptr_thread_node->ptr_task == current) + { + break; + } + ptr_thread_node = ptr_thread_node->ptr_next; + } + + if ((TRUE == ptr_thread_node->is_stop) || (signal_pending(current))) + { + return (NPS_E_OTHERS); + } + + return (NPS_E_OK); +} + +void +osal_exitRunThread(void) +{ + while (!kthread_should_stop() && !signal_pending(current)) + { + osal_sleepThread(OSAL_NS_PER_USECOND); + } +} + +/* semaphore */ +NPS_ERROR_NO_T +osal_createSemaphore( + const C8_T *ptr_sema_name, + const UI32_T sema_count, + NPS_SEMAPHORE_ID_T *ptr_semaphore_id) +{ + char dft_name[OSAL_SEMA_NAME_LEN + 1] = OSAL_SEMA_DFT_NAME; + linux_sema_t *ptr_sema = osal_alloc(sizeof(linux_sema_t)); + + /* process name */ + osal_memcpy(ptr_sema->name, (0 == osal_strlen(ptr_sema_name))? + dft_name : ptr_sema_name, OSAL_SEMA_NAME_LEN); + ptr_sema->name[OSAL_SEMA_NAME_LEN] = '\0'; + + /* init */ + sema_init(&ptr_sema->lock, NPS_SEMAPHORE_BINARY); + + *ptr_semaphore_id = (NPS_SEMAPHORE_ID_T)ptr_sema; + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +osal_takeSemaphore( + NPS_SEMAPHORE_ID_T *ptr_semaphore_id, + UI32_T time_out) +{ + linux_sema_t *ptr_sema = (linux_sema_t *)(*ptr_semaphore_id); + + if (in_interrupt()) + { + return (NPS_E_OTHERS); + } + + if (!down_interruptible(&ptr_sema->lock)) + { + return (NPS_E_OK); + } + + return (NPS_E_OTHERS); +} + +NPS_ERROR_NO_T +osal_giveSemaphore( + NPS_SEMAPHORE_ID_T *ptr_semaphore_id) +{ + linux_sema_t *ptr_sema = (linux_sema_t *)(*ptr_semaphore_id); + + up(&ptr_sema->lock); + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +osal_destroySemaphore( + NPS_SEMAPHORE_ID_T *ptr_semaphore_id) +{ + linux_sema_t *ptr_sema = (linux_sema_t *)(*ptr_semaphore_id); + + osal_free(ptr_sema); + *ptr_semaphore_id = 0; + + return (NPS_E_OK); +} + +/* event */ +NPS_ERROR_NO_T +osal_createEvent( + const C8_T *ptr_event_name, + NPS_SEMAPHORE_ID_T *ptr_event_id) +{ + char dft_name[OSAL_EVENT_NAME_LEN + 1] = OSAL_EVENT_DFT_NAME; + linux_event_t *ptr_event = osal_alloc(sizeof(linux_event_t)); + + /* process name */ + osal_memcpy(ptr_event->name, (0 == osal_strlen(ptr_event_name))? + dft_name : ptr_event_name, OSAL_EVENT_NAME_LEN); + ptr_event->name[OSAL_EVENT_NAME_LEN] = '\0'; + + /* init */ + ptr_event->condition = FALSE; + init_waitqueue_head(&ptr_event->wait_que); + + *ptr_event_id = (NPS_SEMAPHORE_ID_T)ptr_event; + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +osal_waitEvent( + NPS_SEMAPHORE_ID_T *ptr_event_id) +{ + linux_event_t *ptr_event = (linux_event_t *)(*ptr_event_id); + + if (!wait_event_interruptible(ptr_event->wait_que, ptr_event->condition)) + { + ptr_event->condition = FALSE; + + return (NPS_E_OK); + } + + return (NPS_E_OTHERS); +} + +NPS_ERROR_NO_T +osal_triggerEvent( + NPS_SEMAPHORE_ID_T *ptr_event_id) +{ + linux_event_t *ptr_event = (linux_event_t *)(*ptr_event_id); + + ptr_event->condition = TRUE; + wake_up_interruptible(&ptr_event->wait_que); + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +osal_destroyEvent( + NPS_SEMAPHORE_ID_T *ptr_event_id) +{ + linux_event_t *ptr_event = (linux_event_t *)(*ptr_event_id); + + osal_free(ptr_event); + *ptr_event_id = 0; + + return (NPS_E_OK); +} + +/* isr_lock */ +NPS_ERROR_NO_T +osal_createIsrLock( + const C8_T *ptr_isrlock_name, + NPS_ISRLOCK_ID_T *ptr_isrlock_id) +{ + char dft_name[OSAL_SPIN_NAME_LEN + 1] = OSAL_SPIN_DFT_NAME; + linux_isrlock_t *ptr_isrlock = osal_alloc(sizeof(linux_isrlock_t)); + + /* process name */ + osal_memcpy(ptr_isrlock->name, (0 == osal_strlen(ptr_isrlock_name))? + dft_name : ptr_isrlock_name, OSAL_SPIN_NAME_LEN); + ptr_isrlock->name[OSAL_SPIN_NAME_LEN] = '\0'; + + /* init */ + spin_lock_init(&ptr_isrlock->spinlock); + + *ptr_isrlock_id = (NPS_ISRLOCK_ID_T)ptr_isrlock; + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +osal_takeIsrLock( + NPS_ISRLOCK_ID_T *ptr_isrlock_id, + NPS_IRQ_FLAGS_T *ptr_irq_flags) +{ + linux_isrlock_t *ptr_isrlock = (linux_isrlock_t *)(*ptr_isrlock_id); + unsigned long flags = 0; + + spin_lock_irqsave(&ptr_isrlock->spinlock, flags); + *ptr_irq_flags = (NPS_IRQ_FLAGS_T)flags; + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +osal_giveIsrLock( + NPS_ISRLOCK_ID_T *ptr_isrlock_id, + NPS_IRQ_FLAGS_T *ptr_irq_flags) +{ + linux_isrlock_t *ptr_isrlock = (linux_isrlock_t *)(*ptr_isrlock_id); + unsigned long flags = 0; + + flags = (unsigned long)(*ptr_irq_flags); + spin_unlock_irqrestore(&ptr_isrlock->spinlock, flags); + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +osal_destroyIsrLock( + NPS_ISRLOCK_ID_T *ptr_isrlock_id) +{ + linux_isrlock_t *ptr_isrlock = (linux_isrlock_t *)(*ptr_isrlock_id); + + osal_free(ptr_isrlock); + *ptr_isrlock_id = 0; + + return (NPS_E_OK); +} + +/* time */ +NPS_ERROR_NO_T +osal_sleepThread( + const UI32_T usecond) +{ + UI32_T tick_usec; /* how many usec per second */ + UI32_T jiffies; + + if (0 != usecond) + { + /* HZ : times/sec, tick = 1/HZ */ + tick_usec = OSAL_TICKS_PER_SEC / HZ; + if (in_interrupt() || (usecond < tick_usec)) + { + return (-1); + } + else + { + DECLARE_WAIT_QUEUE_HEAD(suspend_queue); + + if (usecond > 0xFFFFFFFF - (tick_usec - 1)) + { + jiffies = 0xFFFFFFFF / tick_usec; + } + else + { + jiffies = (usecond + (tick_usec - 1)) / tick_usec; + } + + return wait_event_interruptible_timeout(suspend_queue, 0, jiffies); + } + } + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +osal_getTime( + NPS_TIME_T *ptr_time) +{ + struct timeval usec_time; + + do_gettimeofday(&usec_time); + *(NPS_TIME_T *)ptr_time = (usec_time.tv_sec * OSAL_US_PER_SECOND) + usec_time.tv_usec; + + return (NPS_E_OK); +} + +/* queue */ +NPS_ERROR_NO_T +osal_que_create( + NPS_HUGE_T *ptr_queue_id, + UI32_T capacity) +{ + linux_queue_t *ptr_queue = osal_alloc(sizeof(linux_queue_t)); + + ptr_queue->head = 0; + ptr_queue->tail = 0; + ptr_queue->wr_cnt = 0; + ptr_queue->rd_cnt = 0; + ptr_queue->capacity = capacity; + ptr_queue->ptr_entry = osal_alloc(sizeof(linux_queue_entry_t) * capacity); + memset(ptr_queue->ptr_entry, 0x0, sizeof(linux_queue_entry_t) * capacity); + + *ptr_queue_id = (NPS_HUGE_T)ptr_queue; + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +osal_que_enque( + NPS_HUGE_T *ptr_queue_id, + void *ptr_data) +{ + linux_queue_t *ptr_queue = (linux_queue_t *)(*ptr_queue_id); + + if (ptr_queue->wr_cnt - ptr_queue->rd_cnt >= ptr_queue->capacity) + { + return (NPS_E_OTHERS); + } + + /* save data to the tail */ + ptr_queue->ptr_entry[ptr_queue->tail].ptr_data = ptr_data; + + /* calculate tail and wr_cnt */ + ptr_queue->tail++; + if (ptr_queue->tail >= ptr_queue->capacity) + { + ptr_queue->tail = 0; + } + + ptr_queue->wr_cnt++; + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +osal_que_deque( + NPS_HUGE_T *ptr_queue_id, + void **pptr_data) +{ + linux_queue_t *ptr_queue = (linux_queue_t *)(*ptr_queue_id); + + if (ptr_queue->wr_cnt == ptr_queue->rd_cnt) + { + return (NPS_E_OTHERS); + } + + /* get data from head */ + *pptr_data = ptr_queue->ptr_entry[ptr_queue->head].ptr_data; + ptr_queue->ptr_entry[ptr_queue->head].ptr_data = NULL; + + /* calculate head and rd_cnt */ + ptr_queue->head++; + if (ptr_queue->head >= ptr_queue->capacity) + { + ptr_queue->head = 0; + } + + ptr_queue->rd_cnt++; + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +osal_que_destroy( + NPS_HUGE_T *ptr_queue_id) +{ + linux_queue_t *ptr_queue = (linux_queue_t *)(*ptr_queue_id); + + osal_free(ptr_queue->ptr_entry); + osal_free(ptr_queue); + *ptr_queue_id = 0; + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +osal_que_getCount( + NPS_HUGE_T *ptr_queue_id, + unsigned int *ptr_count) +{ + linux_queue_t *ptr_queue = (linux_queue_t *)(*ptr_queue_id); + + *ptr_count = ptr_queue->wr_cnt - ptr_queue->rd_cnt; + + return (NPS_E_OK); +} + +/* IO */ +int +osal_io_copyToUser( + void *ptr_usr_buf, + void *ptr_knl_buf, + unsigned int size) +{ + return copy_to_user(ptr_usr_buf, ptr_knl_buf, size); +} + +int +osal_io_copyFromUser( + void *ptr_knl_buf, + void *ptr_usr_buf, + unsigned int size) +{ + return copy_from_user(ptr_knl_buf, ptr_usr_buf, size); +} + +/* dma */ +void * +osal_dma_alloc( + const UI32_T size) +{ + struct device *ptr_dev = &_ptr_ext_pci_dev->dev; + linux_dma_t *ptr_dma_node = NULL; + dma_addr_t phy_addr = 0x0; + + ptr_dma_node = dma_alloc_coherent(ptr_dev, sizeof(linux_dma_t) + size, &phy_addr, GFP_ATOMIC); + ptr_dma_node->size = sizeof(linux_dma_t) + size; + ptr_dma_node->phy_addr = phy_addr; + + return (void *)ptr_dma_node->data; +} + +NPS_ERROR_NO_T +osal_dma_free( + void *ptr_dma_mem) +{ + struct device *ptr_dev = &_ptr_ext_pci_dev->dev; + linux_dma_t *ptr_dma_node = (linux_dma_t *)(ptr_dma_mem - sizeof(linux_dma_t)); + + dma_free_coherent(ptr_dev, ptr_dma_node->size, ptr_dma_node, ptr_dma_node->phy_addr); + + return (NPS_E_OK); +} + +dma_addr_t +osal_dma_convertVirtToPhy( + void *ptr_virt_addr) +{ + return virt_to_phys(ptr_virt_addr); +} + +void * +osal_dma_convertPhyToVirt( + const dma_addr_t phy_addr) +{ + return phys_to_virt(phy_addr); +} + +int +osal_dma_flushCache( + void *ptr_virt_addr, + const unsigned int size) +{ +#if defined(CONFIG_NOT_COHERENT_CACHE) || defined(CONFIG_DMA_NONCOHERENT) +#if defined(dma_cache_wback_inv) + dma_cache_wback_inv((NPS_HUGE_T)ptr_virt_addr, size); +#else + dma_cache_sync(NULL, ptr_virt_addr, size, DMA_TO_DEVICE); +#endif +#endif + return (0); +} + +int +osal_dma_invalidateCache( + void *ptr_virt_addr, + const unsigned int size) +{ +#if defined(CONFIG_NOT_COHERENT_CACHE) || defined(CONFIG_DMA_NONCOHERENT) +#if defined(dma_cache_wback_inv) + dma_cache_wback_inv((NPS_HUGE_T)ptr_virt_addr, size); +#else + dma_cache_sync(NULL, ptr_virt_addr, size, DMA_FROM_DEVICE); +#endif +#endif + return (0); +} + +/* skb */ +struct sk_buff * +osal_skb_alloc( + UI32_T size) +{ + struct sk_buff *ptr_skb = NULL; + + /* + * 1. alloc_skb (len, flag) : GFP_KERNEL + * 2. netdev_alloc_skb (dev, len) : GFP_ATOMIC + * 3. dev_alloc_skb (len) : GFP_ATOMIC + * 4. netdev_alloc_skb_ip_align (dev, len) : GFP_ATOMIC + * + * note: Eth header is 14-bytes, we reservd 2-bytes to alignment Ip header + */ + ptr_skb = dev_alloc_skb(size + NET_IP_ALIGN); + skb_reserve(ptr_skb, NET_IP_ALIGN); + skb_put(ptr_skb, size); + + return (ptr_skb); +} + +void +osal_skb_free( + struct sk_buff *ptr_skb) +{ + /* + * 1. dev_kfree_skb (*skb) : release in process context + * 2. dev_kfree_skb_irq (*skb) : release in interrupt context + * 3. dev_kfree_skb_any (*skb) : release in any context + */ + dev_kfree_skb_any(ptr_skb); +} + +dma_addr_t +osal_skb_mapDma( + struct sk_buff *ptr_skb, + enum dma_data_direction dir) +{ + struct device *ptr_dev = &_ptr_ext_pci_dev->dev; + dma_addr_t phy_addr = 0x0; + + phy_addr = dma_map_single(ptr_dev, ptr_skb->data, ptr_skb->len, dir); + if (dma_mapping_error(ptr_dev, phy_addr)) + { + phy_addr = 0x0; + } + + return (phy_addr); +} + +void +osal_skb_unmapDma( + const dma_addr_t phy_addr, + UI32_T size, + enum dma_data_direction dir) +{ + struct device *ptr_dev = &_ptr_ext_pci_dev->dev; + + dma_unmap_single(ptr_dev, phy_addr, size, dir); +} + +void +osal_skb_send( + struct sk_buff *ptr_skb) +{ + dev_queue_xmit(ptr_skb); +} + +void +osal_skb_recv( + struct sk_buff *ptr_skb) +{ + /* 1. netif_rx() : handle skb in process context + * 2. netif_rx_ni() : handle skb in interrupt context + * 3. netif_receive_skb() : for NAPI + */ + netif_rx(ptr_skb); +} + diff --git a/platform/nephos/nephos-modules/modules/src/netif_perf.c b/platform/nephos/nephos-modules/modules/src/netif_perf.c new file mode 100755 index 000000000000..18606d6d25d4 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/netif_perf.c @@ -0,0 +1,656 @@ +/* Copyright (C) 2019 Nephos, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program. + */ + +/* FILE NAME: netif_perf.c + * PURPOSE: + * It provide customer performance test API. + * NOTES: + */ +#include +#include + +#include +#include + +#if defined (NPS_EN_TAURUS) +#include +#endif + +/* -------------------------------------------------------------- switch */ +#if defined (NPS_EN_ARIES) +#define PERF_TX_CHANNEL_NUM_MAX (HAL_ARI_PKT_TX_CHANNEL_LAST) +#define PERF_RX_CHANNEL_NUM_MAX (HAL_ARI_PKT_RX_CHANNEL_LAST) +typedef HAL_ARI_PKT_TX_SW_GPD_T PERF_TX_SW_GPD; +typedef HAL_ARI_PKT_RX_SW_GPD_T PERF_RX_SW_GPD; +#endif + +#if defined (NPS_EN_TAURUS) +#define PERF_TX_CHANNEL_NUM_MAX (HAL_TAU_PKT_TX_CHANNEL_LAST) +#define PERF_RX_CHANNEL_NUM_MAX (HAL_TAU_PKT_RX_CHANNEL_LAST) +typedef HAL_TAU_PKT_TX_SW_GPD_T PERF_TX_SW_GPD; +typedef HAL_TAU_PKT_RX_SW_GPD_T PERF_RX_SW_GPD; +#endif + +/* -------------------------------------------------------------- common */ +#define PERF_TX_PERF_NUM (1000000) /* max: 4294967 */ +#define PERF_TX_PERF_MESG (50000) +#define PERF_TX_PERF_FAIL (10000) +#define PERF_RX_PERF_NUM (1000000) /* max: 4294967 */ +#define PERF_RX_PERF_MESG (50000) +#define PERF_RX_PERF_FAIL (10000) + +/* -------------------------------------------------------------- callbacks for chip dependency */ +/* Tx */ +typedef NPS_ERROR_NO_T +(*PERF_TX_GET_INTR_T)( + const UI32_T unit, + const UI32_T channel, + UI32_T *ptr_intr_cnt); + +typedef NPS_ERROR_NO_T +(*PERF_TX_GET_NETDEV_T)( + const UI32_T unit, + const UI32_T port, + struct net_device **pptr_net_dev); + +typedef NPS_ERROR_NO_T +(*PERF_TX_PREPARE_GPD_T)( + const UI32_T unit, + const NPS_ADDR_T phy_addr, + const UI32_T len, + const UI32_T port, + PERF_TX_SW_GPD *ptr_sw_gpd); + +typedef NPS_ERROR_NO_T +(*PERF_TX_SEND_GPD_T)( + const UI32_T unit, + const UI32_T channel, + PERF_TX_SW_GPD *ptr_sw_gpd); + +/* Rx */ +typedef NPS_ERROR_NO_T +(*PERF_RX_GET_INTR_T)( + const UI32_T unit, + const UI32_T channel, + UI32_T *ptr_intr_cnt); + +/* -------------------------------------------------------------- structs */ +typedef enum +{ + PERF_DIR_TX = 0, + PERF_DIR_RX, + PERF_DIR_LAST, + +} PERF_DIR_T; + +typedef struct +{ + UI32_T unit; + UI32_T channel; + UI32_T len; + UI32_T num; + UI32_T port; + BOOL_T test_skb; + +} PERF_COOKIE_T; + +typedef struct +{ + /* netif-only */ + PERF_COOKIE_T tx_cookie [PERF_TX_CHANNEL_NUM_MAX]; + + NPS_THREAD_ID_T tx_task [PERF_TX_CHANNEL_NUM_MAX]; + NPS_SEMAPHORE_ID_T start_sync [PERF_TX_CHANNEL_NUM_MAX]; + NPS_SEMAPHORE_ID_T end_sync [PERF_TX_CHANNEL_NUM_MAX]; + UI32_T send_ok [PERF_TX_CHANNEL_NUM_MAX]; + UI32_T send_fail [PERF_TX_CHANNEL_NUM_MAX]; + + /* chip dependent callbacks */ + PERF_TX_GET_INTR_T get_intr_cnt; + PERF_TX_GET_NETDEV_T get_netdev; + PERF_TX_PREPARE_GPD_T prepare_gpd; + PERF_TX_SEND_GPD_T send_gpd; + +} PERF_TX_PERF_CB_T; + +typedef struct +{ + /* netif-only */ + BOOL_T rx_test; + + NPS_SEMAPHORE_ID_T start_sync; + NPS_SEMAPHORE_ID_T end_sync; + UI32_T target_num; + UI32_T target_len; + UI32_T recv_pass; + UI32_T recv_fail; + + /* duplicate packets */ + UI32_T rch_qid_map_lo [PERF_RX_CHANNEL_NUM_MAX]; + UI32_T rch_qid_map_hi [PERF_RX_CHANNEL_NUM_MAX]; + + /* chip dependent callbacks */ + PERF_RX_GET_INTR_T get_intr_cnt; + +} PERF_RX_PERF_CB_T; + +/* -------------------------------------------------------------- statics */ +static PERF_TX_PERF_CB_T _perf_tx_perf_cb = +{ +#if defined (NPS_EN_ARIES) + .get_intr_cnt = hal_ari_pkt_getTxIntrCnt, + .get_netdev = hal_ari_pkt_getNetDev, /* test_skb = TRUE */ + .prepare_gpd = hal_ari_pkt_prepareGpd, /* test_skb = FALSE */ + .send_gpd = hal_ari_pkt_sendGpd, /* test_skb = FALSE */ +#endif +#if defined (NPS_EN_TAURUS) + .get_intr_cnt = hal_tau_pkt_getTxIntrCnt, + .get_netdev = hal_tau_pkt_getNetDev, /* test_skb = TRUE */ + .prepare_gpd = hal_tau_pkt_prepareGpd, /* test_skb = FALSE */ + .send_gpd = hal_tau_pkt_sendGpd, /* test_skb = FALSE */ +#endif +}; + +static PERF_RX_PERF_CB_T _perf_rx_perf_cb = +{ +#if defined (NPS_EN_ARIES) + .get_intr_cnt = hal_ari_pkt_getRxIntrCnt, +#endif +#if defined (NPS_EN_TAURUS) + .get_intr_cnt = hal_tau_pkt_getRxIntrCnt, +#endif +}; + +/* -------------------------------------------------------------- functions */ +static void +_perf_duplicateRxPacket( + const UI32_T unit, + const UI32_T rx_channel, + const BOOL_T enable) +{ + ; +} + +static void +_perf_showPerf( + PERF_DIR_T dir, + UI32_T channel, + UI32_T len, + UI32_T num, + UI32_T intr, + UI32_T duration) +{ + UI32_T tx_channel = 0; + UI32_T tx_fail = 0; + + if (duration < 1000) + { + osal_printf("***Error***, %d packets cost < 1000 us.\n", num); + return ; + } + + osal_printf("\n"); + + if (PERF_DIR_TX == dir) + { + osal_printf("Tx-perf\n"); + } + else + { + osal_printf("Rx-perf\n"); + } + + osal_printf("------------------------------------\n"); + osal_printf("channel number : %d\n", channel); + osal_printf("packet length (bytes): %d\n", len); + osal_printf("packet number : %d\n", num); + osal_printf("time duration (us) : %d\n", duration); + osal_printf("------------------------------------\n"); + osal_printf("avg. packet rate (pps) : %d\n", (num * 1000) / (duration / 1000)); + osal_printf("avg. throughput (Mbps) : %d\n", ((num / 1000) * len * 8) / (duration / 1000)); + osal_printf("interrupt number : %d\n", intr); + + if (PERF_DIR_TX == dir) + { + for (tx_channel = 0; tx_channel < channel; tx_channel++) + { + tx_fail += _perf_tx_perf_cb.send_fail[tx_channel]; + } + osal_printf("Tx fail : %d\n", tx_fail); + } + + osal_printf("------------------------------------\n"); +} + +static void +_perf_getIntrCnt( + UI32_T unit, + PERF_DIR_T dir, + UI32_T *ptr_intr_cnt) +{ + UI32_T intr_cnt = 0; + UI32_T channel = 0; + + if (PERF_DIR_TX == dir) + { + for (channel = 0; channel < PERF_TX_CHANNEL_NUM_MAX; channel++) + { + _perf_tx_perf_cb.get_intr_cnt(unit, channel, &intr_cnt); + *ptr_intr_cnt += intr_cnt; + } + } + else + { + for (channel = 0; channel < PERF_RX_CHANNEL_NUM_MAX; channel++) + { + _perf_rx_perf_cb.get_intr_cnt(unit, channel, &intr_cnt); + *ptr_intr_cnt += intr_cnt; + } + } +} + +static void +_perf_txCallback( + const UI32_T unit, + PERF_TX_SW_GPD *ptr_sw_gpd, + void *ptr_virt_addr) +{ + /* free dma */ + osal_dma_free(ptr_virt_addr); + + /* free gpd */ + osal_free(ptr_sw_gpd); +} + +static void +_perf_txTask( + void *ptr_argv) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + UI32_T unit = ((PERF_COOKIE_T *)ptr_argv)->unit; + UI32_T channel = ((PERF_COOKIE_T *)ptr_argv)->channel; + UI32_T len = ((PERF_COOKIE_T *)ptr_argv)->len; + UI32_T num = ((PERF_COOKIE_T *)ptr_argv)->num; + UI32_T port = ((PERF_COOKIE_T *)ptr_argv)->port; + BOOL_T test_skb = ((PERF_COOKIE_T *)ptr_argv)->test_skb; + + /* test targets */ + PERF_TX_SW_GPD *ptr_sw_gpd = NULL; + struct sk_buff *ptr_skb = NULL; + + /* temp variables */ + UI32_T send_fail = 0; + void *ptr_virt_addr = NULL; + NPS_ADDR_T phy_addr = 0x0; + + osal_initRunThread(); + do + { + rc = osal_waitEvent(&_perf_tx_perf_cb.start_sync[channel]); + if (NPS_E_OK != osal_isRunThread()) + { + break; /* deinit-thread */ + } + + while (_perf_tx_perf_cb.send_ok[channel] < num) + { + if (0 == (_perf_tx_perf_cb.send_ok[channel] % PERF_TX_PERF_MESG)) + { + printk("T"); + } + + if (TRUE == test_skb) + { + ptr_skb = osal_skb_alloc(len); + ptr_skb->len = len; + _perf_tx_perf_cb.get_netdev(unit, port, &ptr_skb->dev); + + /* send skb */ + osal_skb_send(ptr_skb); + } + else + { + ptr_sw_gpd = osal_alloc(sizeof(PERF_TX_SW_GPD)); + if (NULL == ptr_sw_gpd) + { + osal_printf("***Error***, alloc sw-gpd fail.\n"); + break; + } + + /* prepare buf */ + ptr_virt_addr = osal_dma_alloc(len); + phy_addr = osal_dma_convertVirtToPhy(ptr_virt_addr); + + /* trans skb to gpd */ + osal_memset(ptr_sw_gpd, 0x0, sizeof(PERF_TX_SW_GPD)); + ptr_sw_gpd->callback = (void *)_perf_txCallback; + ptr_sw_gpd->ptr_cookie = (void *)ptr_virt_addr; + ptr_sw_gpd->gpd_num = 1; + ptr_sw_gpd->ptr_next = NULL; + ptr_sw_gpd->channel = channel; + + /* prepare gpd */ + rc = _perf_tx_perf_cb.prepare_gpd(unit, phy_addr, len, port, ptr_sw_gpd); + + /* send gpd */ + rc = _perf_tx_perf_cb.send_gpd(unit, channel, ptr_sw_gpd); + if (NPS_E_OK == rc) + { + _perf_tx_perf_cb.send_ok[channel]++; + send_fail = 0; + } + else + { + _perf_tx_perf_cb.send_fail[channel]++; + if (send_fail++ >= PERF_TX_PERF_FAIL) + { + osal_printf("***Error***, Tch-%d send fail over %d packet(s). (rc: %d)\n", + channel, PERF_TX_PERF_FAIL, rc); + break; + } + + _perf_txCallback(unit, ptr_sw_gpd, ptr_virt_addr); + osal_sleepThread(1000); + } + } + } + + osal_triggerEvent(&_perf_tx_perf_cb.end_sync[channel]); + } + while (NPS_E_OK == osal_isRunThread()); + osal_exitRunThread(); +} + +static void +_perf_txDeinit( + const UI32_T unit, + const UI32_T tx_channel) +{ + UI32_T channel = 0; + + for (channel = 0; channel < tx_channel; channel++) + { + /* destroy Tx resources */ + osal_stopThread (&_perf_tx_perf_cb.tx_task [channel]); + osal_triggerEvent(&_perf_tx_perf_cb.start_sync [channel]); + osal_destroyThread(&_perf_tx_perf_cb.tx_task [channel]); + osal_destroyEvent(&_perf_tx_perf_cb.end_sync [channel]); + osal_destroyEvent(&_perf_tx_perf_cb.start_sync [channel]); + } +} + +static void +_perf_txInit( + const UI32_T unit, + const UI32_T tx_channel, + const UI32_T len, + BOOL_T test_skb) +{ + UI32_T channel = 0; + + for (channel = 0; channel < tx_channel; channel++) + { + _perf_tx_perf_cb.send_ok [channel] = 0; + _perf_tx_perf_cb.send_fail[channel] = 0; + + /* create Tx resources */ + osal_createEvent("TX_START", &_perf_tx_perf_cb.start_sync [channel]); + osal_createEvent("TX_END", &_perf_tx_perf_cb.end_sync [channel]); + + _perf_tx_perf_cb.tx_cookie[channel].unit = unit; + _perf_tx_perf_cb.tx_cookie[channel].channel = channel; + _perf_tx_perf_cb.tx_cookie[channel].len = len; + _perf_tx_perf_cb.tx_cookie[channel].num = PERF_TX_PERF_NUM / tx_channel; + _perf_tx_perf_cb.tx_cookie[channel].port = 0; + _perf_tx_perf_cb.tx_cookie[channel].test_skb = test_skb; + + osal_createThread( + "TX_PERF", 64 * 1024, 90, + _perf_txTask, + (void *)&_perf_tx_perf_cb.tx_cookie[channel], + &_perf_tx_perf_cb.tx_task[channel]); + } +} + +static void +_perf_rxDeinit( + const UI32_T unit, + const UI32_T rx_channel) +{ + /* turn-off Rx test */ + _perf_rx_perf_cb.rx_test = FALSE; + + /* destroy Rx resources */ + osal_destroyEvent(&_perf_rx_perf_cb.end_sync); + osal_destroyEvent(&_perf_rx_perf_cb.start_sync); + + /* disable duplicate Rx packets to channels */ + _perf_duplicateRxPacket(unit, rx_channel, FALSE); +} + +static void +_perf_rxInit( + const UI32_T unit, + const UI32_T rx_channel, + const UI32_T len) +{ + /* enable duplicate Rx packets to channels */ + _perf_duplicateRxPacket(unit, rx_channel, TRUE); + + /* create Rx callback resources */ + _perf_rx_perf_cb.target_num = PERF_RX_PERF_NUM; + _perf_rx_perf_cb.target_len = len; + _perf_rx_perf_cb.recv_pass = 0; + + osal_createEvent("RX_START", &_perf_rx_perf_cb.start_sync); + osal_createEvent("RX_END", &_perf_rx_perf_cb.end_sync); + + /* turn-on Rx test */ + _perf_rx_perf_cb.rx_test = TRUE; +} + +/* FUNCTION NAME: perf_rxCallback + * PURPOSE: + * To count the Rx-gpd for Rx-test. + * INPUT: + * len -- To check if the Rx-gpd length equals to test length. + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successful operation. + * NOTES: + * None + */ +NPS_ERROR_NO_T +perf_rxCallback( + const UI32_T len) +{ + /* check length */ + if (len == _perf_rx_perf_cb.target_len) + { + _perf_rx_perf_cb.recv_pass++; + } + else + { + if (_perf_rx_perf_cb.recv_fail++ >= PERF_RX_PERF_FAIL) + { + _perf_rx_perf_cb.recv_fail = 0; + } + } + + /* send signals */ + if (0 == _perf_rx_perf_cb.recv_pass) + { + ; /* do nothing */ + } + else if (1 == _perf_rx_perf_cb.recv_pass) + { + osal_triggerEvent(&_perf_rx_perf_cb.start_sync); + } + else if (_perf_rx_perf_cb.recv_pass == _perf_rx_perf_cb.target_num) + { + osal_triggerEvent(&_perf_rx_perf_cb.end_sync); + } + else if (0 == (_perf_rx_perf_cb.recv_pass % PERF_RX_PERF_MESG)) + { + printk("R"); + } + + return (NPS_E_OK); +} + +/* FUNCTION NAME: perf_rxTest + * PURPOSE: + * To check if Rx-test is going. + * INPUT: + * None + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successful operation. + * NOTES: + * None + */ +NPS_ERROR_NO_T +perf_rxTest(void) +{ + if (FALSE == _perf_rx_perf_cb.rx_test) + { + return (NPS_E_OTHERS); + } + + return (NPS_E_OK); +} + +/* FUNCTION NAME: perf_test + * PURPOSE: + * To do Tx-test or Rx-test. + * INPUT: + * len -- Test length + * tx_channel -- Test Tx channel numbers + * rx_channel -- Test Rx channel numbers + * test_skb -- Test GPD or SKB + * OUTPUT: + * None + * RETURN: + * NPS_E_OK -- Successful operation. + * NOTES: + * None + */ +NPS_ERROR_NO_T +perf_test( + UI32_T len, + UI32_T tx_channel, + UI32_T rx_channel, + BOOL_T test_skb) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + NPS_TIME_T start_time; + NPS_TIME_T end_time; + UI32_T unit = 0, channel = 0; + UI32_T tx_pkt_cnt = 0, tx_start_intr = 0, tx_end_intr = 0; + UI32_T rx_pkt_cnt = 0, rx_start_intr = 0, rx_end_intr = 0; + + if ((0 == tx_channel) && (0 == rx_channel)) + { + return (NPS_E_NOT_SUPPORT); + } + + /* start test */ + if ((tx_channel > 0) && (rx_channel > 0)) + { + _perf_getIntrCnt(unit, PERF_DIR_TX, &tx_start_intr); + _perf_getIntrCnt(unit, PERF_DIR_RX, &rx_start_intr); + _perf_txInit(unit, tx_channel, len, test_skb); + _perf_rxInit(unit, rx_channel, len); + + /* wait 1st Rx GPD done */ + osal_waitEvent(&_perf_rx_perf_cb.start_sync); + + /* ------------- in-time ------------- */ + osal_getTime(&start_time); + for (channel = 0; channel < tx_channel; channel++) + { + osal_triggerEvent(&_perf_tx_perf_cb.start_sync[channel]); + } + for (channel = 0; channel < tx_channel; channel++) + { + osal_waitEvent(&_perf_tx_perf_cb.end_sync[channel]); + tx_pkt_cnt += _perf_tx_perf_cb.send_ok[channel]; + } + rx_pkt_cnt = _perf_rx_perf_cb.recv_pass; + osal_getTime(&end_time); + /* ------------- in-time ------------- */ + + _perf_txDeinit(unit, tx_channel); + _perf_rxDeinit(unit, rx_channel); + _perf_getIntrCnt(unit, PERF_DIR_TX, &tx_end_intr); + _perf_getIntrCnt(unit, PERF_DIR_RX, &rx_end_intr); + + _perf_showPerf(PERF_DIR_TX, + tx_channel, len, tx_pkt_cnt, tx_end_intr - tx_start_intr, end_time - start_time); + + _perf_showPerf(PERF_DIR_RX, + rx_channel, len, rx_pkt_cnt, rx_end_intr - rx_start_intr, end_time - start_time); + } + else if (tx_channel > 0) + { + _perf_getIntrCnt(unit, PERF_DIR_TX, &tx_start_intr); + _perf_txInit(unit, tx_channel, len, test_skb); + + /* ------------- in-time ------------- */ + osal_getTime(&start_time); + for (channel = 0; channel < tx_channel; channel++) + { + osal_triggerEvent(&_perf_tx_perf_cb.start_sync[channel]); + } + for (channel = 0; channel < tx_channel; channel++) + { + osal_waitEvent(&_perf_tx_perf_cb.end_sync[channel]); + tx_pkt_cnt += _perf_tx_perf_cb.send_ok[channel]; + } + osal_getTime(&end_time); + /* ------------- in-time ------------- */ + + _perf_txDeinit(unit, tx_channel); + _perf_getIntrCnt(unit, PERF_DIR_TX, &tx_end_intr); + + _perf_showPerf(PERF_DIR_TX, + tx_channel, len, tx_pkt_cnt, tx_end_intr - tx_start_intr, end_time - start_time); + } + else if (rx_channel > 0) + { + _perf_getIntrCnt(unit, PERF_DIR_RX, &rx_start_intr); + _perf_rxInit(unit, rx_channel, len); + + /* wait 1st Rx GPD done */ + osal_waitEvent(&_perf_rx_perf_cb.start_sync); + + /* ------------- in-time ------------- */ + osal_getTime(&start_time); + osal_waitEvent(&_perf_rx_perf_cb.end_sync); + osal_getTime(&end_time); + /* ------------- in-time ------------- */ + + _perf_rxDeinit(unit, rx_channel); + _perf_getIntrCnt(unit, PERF_DIR_RX, &rx_end_intr); + + _perf_showPerf(PERF_DIR_RX, + rx_channel, len, PERF_RX_PERF_NUM, rx_end_intr - rx_start_intr, end_time - start_time); + } + + return (rc); +} + diff --git a/platform/nephos/nephos-modules/modules/src/osal_isymbol.c b/platform/nephos/nephos-modules/modules/src/osal_isymbol.c new file mode 100755 index 000000000000..c23cc70bed23 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/osal_isymbol.c @@ -0,0 +1,38 @@ +/* Copyright (C) 2019 Nephos, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program. + */ + +/* FILE NAME: osal_isymbol.c +* PURPOSE: +* It provide global OSAL symbol export for linux kernel module +* NOTES: +*/ +#include +#include + +/* ----------------------------------------------------- */ +#include +/* dma */ +extern struct pci_dev *_ptr_ext_pci_dev; +EXPORT_SYMBOL(_ptr_ext_pci_dev); + +#if defined(NPS_LINUX_USER_MODE) +EXPORT_SYMBOL(osal_mdc_readPciReg); +EXPORT_SYMBOL(osal_mdc_writePciReg); +#if defined(NPS_EN_NETIF) +/* intr */ +/* for kernel module, this API will be exported by script with other OSAL functions in osal_symbol.c */ +EXPORT_SYMBOL(osal_mdc_registerIsr); +#endif +#endif diff --git a/platform/nephos/nephos-modules/modules/src/osal_mdc.c b/platform/nephos/nephos-modules/modules/src/osal_mdc.c new file mode 100755 index 000000000000..3dad3173ac79 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/osal_mdc.c @@ -0,0 +1,2359 @@ +/* Copyright (C) 2019 Nephos, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program. + */ + +/* FILE NAME: osal_mdc.c + * PURPOSE: + * 1. Provide device operate from AML interface + * NOTES: + * + */ + +/* INCLUDE FILE DECLARATIONS + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include + +#if defined(NPS_LINUX_USER_MODE) +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) +#include +#else +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +/* #define OSAL_MDC_EN_MSI */ +/* #define OSAL_MDC_DMA_RESERVED_MEM_CACHEABLE */ +/* #define OSAL_MDC_EN_TEST */ + +/* NAMING CONSTANT DECLARATIONS + */ +#define OSAL_MDC_PCI_BAR0_OFFSET (0x0) +#define OSAL_MDC_ERR printk + +/* MACRO FUNCTION DECLARATIONS + */ + +/* DATA TYPE DECLARATIONS + */ +typedef struct +{ + UI32_T unit; + struct pci_dev *ptr_pci_dev; + UI32_T *ptr_mmio_virt_addr; + int irq; + AML_DEV_ISR_FUNC_T isr_callback; + void *ptr_isr_data; + +} OSAL_MDC_DEV_T; + +typedef struct +{ + OSAL_MDC_DEV_T dev[NPS_CFG_MAXIMUM_CHIPS_PER_SYSTEM]; + UI32_T dev_num; + OSAL_MDC_DMA_INFO_T dma_info; + +} OSAL_MDC_CB_T; + +#if defined(NPS_LINUX_USER_MODE) + +typedef struct +{ + OSAL_MDC_IOCTL_CALLBACK_FUNC_T callback[OSAL_MDC_IOCTL_TYPE_LAST]; + +} OSAL_MDC_IOCTL_CB_T; + +#if !defined(NPS_EN_DMA_RESERVED) +typedef struct +{ + NPS_ADDR_T phy_addr; + UI32_T size; + struct list_head list; + +} OSAL_MDC_USER_MODE_DMA_NODE_T; +#endif + +#endif + + +#if defined(NPS_LINUX_KERNEL_MODE) + +/* re-define the interface to align OSAL_MDC's implementation with the prototype of CMLIB */ +#define osal_mdc_list_create(__capa__, __type__, __name__, __list__) _osal_mdc_list_create(__capa__, __list__) +#define osal_mdc_list_destroy(__list__, __callback__) _osal_mdc_list_destroy(__list__) +#define osal_mdc_list_getNodeData(__list__, __node__, __data__) _osal_mdc_list_getNodeData(__list__, __node__, __data__) +#define osal_mdc_list_next(__list__, __node__, __next__) _osal_mdc_list_next(__list__, __node__, __next__) +#define osal_mdc_list_locateHead(__list__, __node__) _osal_mdc_list_locateHead(__list__, __node__) +#define osal_mdc_list_insertToHead(__list__, __data__) _osal_mdc_list_insertToHead(__list__, __data__) +#define osal_mdc_list_deleteByData(__list__, __data__) _osal_mdc_list_deleteByData(__list__, __data__) + +#if defined(NPS_EN_DMA_RESERVED) +#define osal_mdc_list_insertBefore(__list__, __node__, __data__) _osal_mdc_list_insertBefore(__list__, __node__, __data__) +#define osal_mdc_list_prev(__list__, __node__, __prev__) _osal_mdc_list_prev(__list__, __node__, __prev__) +#endif + +#define OSAL_MDC_LIST_TYPE_DOUBLE (1) /* don't care the type, always be double */ +#define OSAL_MDC_LIST_TYPE_SINGLE (0) /* don't care the type, always be double */ + +static NPS_ERROR_NO_T +_osal_mdc_list_create( + const UI32_T capacity, + OSAL_MDC_LIST_T **pptr_list ) +{ + NPS_ERROR_NO_T rc = NPS_E_NO_MEMORY; + + *pptr_list = NULL; + + *pptr_list = osal_alloc(sizeof(OSAL_MDC_LIST_T)); + if (NULL != *pptr_list) + { + (*pptr_list)->capacity = capacity; + (*pptr_list)->node_cnt = 0; + (*pptr_list)->ptr_head_node = NULL; + (*pptr_list)->ptr_tail_node = NULL; + rc = NPS_E_OK; + } + + return (rc); +} + +static NPS_ERROR_NO_T +_osal_mdc_list_destroy( + OSAL_MDC_LIST_T *ptr_list ) +{ + OSAL_MDC_LIST_NODE_T *ptr_cur_node, *ptr_next_node; + NPS_ERROR_NO_T rc = NPS_E_OTHERS; + + if (NULL != ptr_list) + { + if (ptr_list->node_cnt != 0) + { + OSAL_MDC_ERR("dma list not empty, node num=%d\n", + ptr_list->node_cnt); + ptr_cur_node = ptr_list->ptr_head_node; + while(NULL != ptr_cur_node) + { + ptr_next_node = ptr_cur_node->ptr_next; + osal_free(ptr_cur_node); + ptr_list->node_cnt--; + ptr_cur_node = ptr_next_node; + } + } + + osal_free(ptr_list); + rc = NPS_E_OK; + } + + return (rc); +} + +static NPS_ERROR_NO_T +_osal_mdc_list_getNodeData( + OSAL_MDC_LIST_T *ptr_list, + OSAL_MDC_LIST_NODE_T *ptr_node, + void **pptr_node_data ) +{ + NPS_ERROR_NO_T rc = NPS_E_OTHERS; + + if (NULL != ptr_list) + { + if (NULL != ptr_node) + { + *pptr_node_data = ptr_node->ptr_data; + rc = NPS_E_OK; + } + } + + return (rc); +} + +static NPS_ERROR_NO_T +_osal_mdc_list_insertToHead( + OSAL_MDC_LIST_T *ptr_list, + void *ptr_data ) +{ + OSAL_MDC_LIST_NODE_T *ptr_new_node = NULL; + NPS_ERROR_NO_T rc = NPS_E_OTHERS; + + if (NULL != ptr_list) + { + ptr_new_node = osal_alloc(sizeof(OSAL_MDC_LIST_NODE_T)); + if (NULL != ptr_new_node) + { + ptr_new_node->ptr_data = ptr_data; + + /* no former node */ + ptr_new_node->ptr_prev = NULL; + + if (NULL != ptr_list->ptr_head_node) + { + ptr_list->ptr_head_node->ptr_prev = ptr_new_node; + ptr_new_node->ptr_next = ptr_list->ptr_head_node; + } + else + { + /* 1st node insertion */ + ptr_list->ptr_tail_node = ptr_new_node; + ptr_new_node->ptr_next = NULL; + } + + ptr_list->ptr_head_node = ptr_new_node; + ptr_list->node_cnt++; + rc = NPS_E_OK; + } + } + + return (rc); +} + +#if defined(NPS_EN_DMA_RESERVED) +static NPS_ERROR_NO_T +_osal_mdc_list_insertBefore( + OSAL_MDC_LIST_T *ptr_list, + OSAL_MDC_LIST_NODE_T *ptr_node, + void *ptr_data ) +{ + OSAL_MDC_LIST_NODE_T *ptr_new_node = NULL; + OSAL_MDC_LIST_NODE_T *ptr_prev_node = ptr_node->ptr_prev; + NPS_ERROR_NO_T rc = NPS_E_OTHERS; + + if (NULL != ptr_list) + { + if (NULL != ptr_node) + { + ptr_new_node = osal_alloc(sizeof(OSAL_MDC_LIST_NODE_T)); + if (NULL != ptr_new_node) + { + ptr_new_node->ptr_data = ptr_data; + + /* location */ + if (NULL != ptr_prev_node) + { + ptr_prev_node->ptr_next = ptr_new_node; + } + ptr_new_node->ptr_prev = ptr_prev_node; + ptr_new_node->ptr_next = ptr_node; + ptr_node->ptr_prev = ptr_new_node; + + /* update head if necessary */ + if (ptr_list->ptr_head_node == ptr_node) + { + ptr_list->ptr_head_node = ptr_new_node; + } + + ptr_list->node_cnt++; + rc = NPS_E_OK; + } + } + } + + return (rc); +} +#endif + +static NPS_ERROR_NO_T +_osal_mdc_list_deleteTargetNode( + OSAL_MDC_LIST_T *ptr_list, + OSAL_MDC_LIST_NODE_T *ptr_target_node) +{ + OSAL_MDC_LIST_NODE_T *ptr_prev_node = ptr_target_node->ptr_prev; + OSAL_MDC_LIST_NODE_T *ptr_next_node = ptr_target_node->ptr_next; + + if (ptr_target_node == ptr_list->ptr_head_node) + { + ptr_list->ptr_head_node = ptr_next_node; + if (NULL != ptr_next_node) + { + ptr_next_node->ptr_prev = NULL; + } + else + { + /* there's only 1 node in the list, and it gets removed */ + ptr_list->ptr_tail_node = NULL; + } + } + else if (ptr_target_node == ptr_list->ptr_tail_node) + { + /* at least 2 nodes in the list, and the target node locates tail */ + ptr_list->ptr_tail_node = ptr_prev_node; + ptr_prev_node->ptr_next = NULL; + } + else + { + /* intermediate node */ + ptr_prev_node->ptr_next = ptr_next_node; + ptr_next_node->ptr_prev = ptr_prev_node; + } + + osal_free(ptr_target_node); + ptr_list->node_cnt--; + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_osal_mdc_list_deleteByData( + OSAL_MDC_LIST_T *ptr_list, + void *ptr_delete_data) +{ + OSAL_MDC_LIST_NODE_T *ptr_tmp_node; + NPS_ERROR_NO_T rc = NPS_E_OTHERS; + + if (NULL != ptr_list) + { + ptr_tmp_node = ptr_list->ptr_head_node; + while (NULL != ptr_tmp_node) + { + if (ptr_tmp_node->ptr_data == ptr_delete_data) + { + rc = _osal_mdc_list_deleteTargetNode(ptr_list, ptr_tmp_node); + break; + } + else + { + ptr_tmp_node = ptr_tmp_node->ptr_next; + } + } + } + + return (rc); +} + + +static NPS_ERROR_NO_T +_osal_mdc_list_locateHead( + OSAL_MDC_LIST_T *ptr_list, + OSAL_MDC_LIST_NODE_T **pptr_node ) +{ + NPS_ERROR_NO_T rc = NPS_E_OTHERS; + + if (NULL != ptr_list) + { + *pptr_node = ptr_list->ptr_head_node; + if (NULL != *pptr_node) + { + rc = NPS_E_OK; + } + } + + return (rc); +} + +static NPS_ERROR_NO_T +_osal_mdc_list_next( + OSAL_MDC_LIST_T *ptr_list, + OSAL_MDC_LIST_NODE_T *ptr_node, + OSAL_MDC_LIST_NODE_T **pptr_next_node ) +{ + NPS_ERROR_NO_T rc = NPS_E_OTHERS; + + if (NULL != ptr_list) + { + if (NULL != ptr_node) + { + *pptr_next_node = ptr_node->ptr_next; + if (NULL != *pptr_next_node) + { + rc = NPS_E_OK; + } + } + } + + return (rc); +} + +#if defined(NPS_EN_DMA_RESERVED) +static NPS_ERROR_NO_T +_osal_mdc_list_prev( + OSAL_MDC_LIST_T *ptr_list, + OSAL_MDC_LIST_NODE_T *ptr_node, + OSAL_MDC_LIST_NODE_T **pptr_prev_node ) +{ + NPS_ERROR_NO_T rc = NPS_E_OTHERS; + + if (NULL != ptr_list) + { + if (NULL != ptr_node) + { + *pptr_prev_node = ptr_node->ptr_prev; + if (NULL != *pptr_prev_node) + { + rc = NPS_E_OK; + } + } + } + + return (rc); +} +#endif /* End of defined(NPS_EN_DMA_RESERVED) */ + +#endif /* End if defined(NPS_LINUX_KERNEL_MODE) */ + +/* GLOBAL VARIABLE DECLARATIONS + */ +static OSAL_MDC_CB_T _osal_mdc_cb; + +/* To let system callback function to access AML database */ +static AML_DEV_T *_ptr_osal_mdc_dev; + +/* Interface */ +struct pci_dev *_ptr_ext_pci_dev; + + +/* STATIC VARIABLE DECLARATIONS + */ +/* --------------------------------------------------------------------------- I2C interface */ +#if defined(AML_EN_I2C) +extern NPS_ERROR_NO_T +dev_switch_readBuffer( + const UI32_T addr, + const UI32_T addr_len, + UI8_T *ptr_buf, + const UI32_T buf_len); + +extern NPS_ERROR_NO_T +dev_switch_writeBuffer( + const UI32_T addr, + const UI32_T addr_len, + const UI8_T *ptr_buf, + const UI32_T buf_len); + +static NPS_ERROR_NO_T +_osal_mdc_readI2cReg( + const UI32_T unit, + const UI32_T offset, + UI32_T *ptr_data, + const UI32_T len) +{ + return dev_switch_readBuffer(offset, sizeof(offset), (UI8_T *)ptr_data, len); +} + +static NPS_ERROR_NO_T +_osal_mdc_writeI2cReg( + const UI32_T unit, + const UI32_T offset, + const UI32_T *ptr_data, + const UI32_T len) +{ + return dev_switch_writeBuffer(offset, sizeof(offset), (UI8_T *)ptr_data, len); +} + +static NPS_ERROR_NO_T +_osal_mdc_probeI2cDevice(void) +{ + /* I2C interface will be probed in BSP. */ + _ptr_osal_mdc_dev->if_type = AML_DEV_TYPE_I2C; + _ptr_osal_mdc_dev->access.read_callback = _osal_mdc_readI2cReg; + _ptr_osal_mdc_dev->access.write_callback = _osal_mdc_writeI2cReg; + + _ptr_osal_mdc_dev->id.device = HAL_DEVICE_ID_MT3258; + _ptr_osal_mdc_dev->id.vendor = HAL_MTK_VENDOR_ID; + _ptr_osal_mdc_dev->id.revision = HAL_REVISION_ID_E2; + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_osal_mdc_removeI2cDevice(void) +{ + /* I2C interface will be removed in BSP. */ + return (NPS_E_OK); +} + +/* --------------------------------------------------------------------------- PCI interface */ +#else + +static NPS_ERROR_NO_T +_osal_mdc_getPciMmioInfo( + struct pci_dev *pdev, + UI32_T **pptr_base_addr) +{ + NPS_ERROR_NO_T rc = NPS_E_OTHERS; + NPS_ADDR_T phy_addr; + UI32_T reg_space_sz; + + phy_addr = pci_resource_start(pdev, OSAL_MDC_PCI_BAR0_OFFSET); + reg_space_sz = pci_resource_len(pdev, OSAL_MDC_PCI_BAR0_OFFSET); + + if (0 == pci_request_region(pdev, OSAL_MDC_PCI_BAR0_OFFSET, OSAL_MDC_DRIVER_NAME)) + { + *pptr_base_addr = ioremap_nocache(phy_addr, reg_space_sz); + if (NULL != *pptr_base_addr) + { + rc = NPS_E_OK; + } + } + return (rc); +} + +NPS_ERROR_NO_T +osal_mdc_readPciReg( + const UI32_T unit, + const UI32_T offset, + UI32_T *ptr_data, + const UI32_T len) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + UI32_T idx; + UI32_T count; + volatile UI32_T *ptr_base_addr = _osal_mdc_cb.dev[unit].ptr_mmio_virt_addr; + + if (NULL != ptr_base_addr) + { + if (OSAL_MDC_PCI_BUS_WIDTH == len) + { + *ptr_data = *((UI32_T *)((NPS_HUGE_T)ptr_base_addr + offset)); + } + else + { + if (0 == (len % OSAL_MDC_PCI_BUS_WIDTH)) + { + count = len / OSAL_MDC_PCI_BUS_WIDTH; + for (idx = 0; idx < count; idx++) + { + *(ptr_data + idx) = *((UI32_T *)((NPS_HUGE_T)ptr_base_addr + offset + idx * 4)); + } + } + else + { + rc = NPS_E_OTHERS; + } + } + } + else + { + rc = NPS_E_NOT_INITED; + } + + return (rc); +} + +NPS_ERROR_NO_T +osal_mdc_writePciReg( + const UI32_T unit, + const UI32_T offset, + const UI32_T *ptr_data, + const UI32_T len) +{ + UI32_T idx; + UI32_T count; + volatile UI32_T *ptr_base_addr = _osal_mdc_cb.dev[unit].ptr_mmio_virt_addr; + NPS_ERROR_NO_T rc = NPS_E_OK; + + if (NULL != ptr_base_addr) + { + if (OSAL_MDC_PCI_BUS_WIDTH == len) + { + *((UI32_T *)((NPS_HUGE_T)ptr_base_addr + offset)) = *ptr_data; + } + else + { + if (0 == (len % OSAL_MDC_PCI_BUS_WIDTH)) + { + count = len / OSAL_MDC_PCI_BUS_WIDTH; + for (idx = 0; idx < count; idx++) + { + *((UI32_T *)((NPS_HUGE_T)ptr_base_addr + offset + idx * 4)) = *(ptr_data + idx); + } + } + else + { + rc = NPS_E_OTHERS; + } + } + } + else + { + rc = NPS_E_NOT_INITED; + } + + return (rc); +} + +static int +_osal_mdc_probePciCallback( + struct pci_dev *pdev, + const struct pci_device_id *id) +{ + int linux_rc; + UI16_T device_id; + UI16_T vendor_id; + UI8_T revision_id; + NPS_ERROR_NO_T rc = NPS_E_OK; + + linux_rc = pci_enable_device(pdev); + if (0 == linux_rc) + { + _ptr_osal_mdc_dev->if_type = AML_DEV_TYPE_PCI; + + pci_read_config_word(pdev, PCI_DEVICE_ID, &device_id); + pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id); + pci_read_config_byte(pdev, PCI_REVISION_ID, &revision_id); + + _ptr_osal_mdc_dev->id.device = (UI32_T)device_id; + _ptr_osal_mdc_dev->id.vendor = (UI32_T)vendor_id; + _ptr_osal_mdc_dev->id.revision = (UI32_T)revision_id; + +#if defined(NPS_LINUX_KERNEL_MODE) + _ptr_osal_mdc_dev->access.read_callback = osal_mdc_readPciReg; + _ptr_osal_mdc_dev->access.write_callback = osal_mdc_writePciReg; +#endif + + rc = _osal_mdc_getPciMmioInfo(pdev, &_osal_mdc_cb.dev[_osal_mdc_cb.dev_num].ptr_mmio_virt_addr); + if (NPS_E_OK == rc) + { + /* Save the database to pdev structure for system callback to release recource, + * such like disconnecting ISR etc. + */ + _osal_mdc_cb.dev[_osal_mdc_cb.dev_num].irq = pdev->irq; + _osal_mdc_cb.dev[_osal_mdc_cb.dev_num].ptr_pci_dev = pdev; + _osal_mdc_cb.dev[_osal_mdc_cb.dev_num].unit = _osal_mdc_cb.dev_num; + + pci_set_drvdata(pdev, &_osal_mdc_cb.dev[_osal_mdc_cb.dev_num]); + + /* To set the bus master bit on device to enable the DMA transaction from PCIe EP to RC + * The bus master bit gets cleared when pci_disable_device() is called + */ + pci_set_master(pdev); + +#if !defined(NPS_EN_DMA_RESERVED) + if (NULL == _osal_mdc_cb.dma_info.ptr_dma_dev) + { + /* This variable is for dma_alloc_coherent */ + _osal_mdc_cb.dma_info.ptr_dma_dev = &pdev->dev; + } +#endif + _osal_mdc_cb.dev_num++; + _ptr_osal_mdc_dev++; + } + } + else + { + OSAL_MDC_ERR("enable pci dev failed, linux_rc=%d\n", linux_rc); + } + + return (0); +} + +static void +_osal_mdc_removePciCallback( + struct pci_dev *pdev) +{ + OSAL_MDC_DEV_T *ptr_dev = (OSAL_MDC_DEV_T *)pci_get_drvdata(pdev); + + iounmap(ptr_dev->ptr_mmio_virt_addr); + pci_release_region(pdev, OSAL_MDC_PCI_BAR0_OFFSET); + pci_disable_device(pdev); +} + +static struct pci_device_id _osal_mdc_id_table[] = +{ + {PCI_DEVICE(HAL_MTK_VENDOR_ID, PCI_ANY_ID)}, + {PCI_DEVICE(HAL_NP_VENDOR_ID, PCI_ANY_ID)}, +}; + +static struct pci_driver _osal_mdc_pci_driver = +{ + .name = OSAL_MDC_DRIVER_NAME, + .id_table = _osal_mdc_id_table, + .probe = _osal_mdc_probePciCallback, + .remove = _osal_mdc_removePciCallback, +}; + +static NPS_ERROR_NO_T +_osal_mdc_probePciDevice(void) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + + if (pci_register_driver(&_osal_mdc_pci_driver) < 0) + { + rc = NPS_E_OTHERS; + } + return (rc); +} + +static NPS_ERROR_NO_T +_osal_mdc_removePciDevice(void) +{ + pci_unregister_driver(&_osal_mdc_pci_driver); + return (NPS_E_OK); +} + +#endif /* End of AML_EN_I2C */ + +/* --------------------------------------------------------------------------- DMA */ +#if defined(NPS_LINUX_KERNEL_MODE) + +static NPS_ERROR_NO_T +_osal_mdc_searchDmaVirtAddr( + OSAL_MDC_LIST_T *ptr_dma_list, + const void *ptr_virt_addr, + OSAL_MDC_LIST_NODE_T **pptr_node, + OSAL_MDC_DMA_NODE_T **pptr_node_data) +{ + OSAL_MDC_LIST_NODE_T *ptr_curr_node; + OSAL_MDC_DMA_NODE_T *ptr_curr_node_data; + NPS_ERROR_NO_T rc; + + rc = osal_mdc_list_locateHead(ptr_dma_list, &ptr_curr_node); + while (NPS_E_OK == rc) + { + rc = osal_mdc_list_getNodeData(ptr_dma_list, ptr_curr_node, (void **)&ptr_curr_node_data); + if (NPS_E_OK == rc) + { + if (ptr_curr_node_data->ptr_virt_addr == ptr_virt_addr) + { + *pptr_node = ptr_curr_node; + *pptr_node_data = ptr_curr_node_data; + break; + } + rc = osal_mdc_list_next(ptr_dma_list, ptr_curr_node, &ptr_curr_node); + } + } + return (rc); +} + +static NPS_ERROR_NO_T +_osal_mdc_destroyDmaNodeList( + OSAL_MDC_DMA_INFO_T *ptr_dma_info) +{ + OSAL_MDC_LIST_T *ptr_dma_list = (OSAL_MDC_LIST_T *)ptr_dma_info->ptr_dma_list; + OSAL_MDC_LIST_NODE_T *ptr_curr_node = NULL; + OSAL_MDC_DMA_NODE_T *ptr_curr_node_data = NULL; + NPS_ERROR_NO_T rc = NPS_E_NOT_INITED; + + if (NULL != ptr_dma_list) + { + rc = osal_mdc_list_locateHead(ptr_dma_list, &ptr_curr_node); + while (NPS_E_OK == rc) + { + rc = osal_mdc_list_getNodeData(ptr_dma_list, ptr_curr_node, (void **)&ptr_curr_node_data); + if ((NPS_E_OK == rc) && (NULL != ptr_curr_node_data)) + { + rc = osal_mdc_list_deleteByData(ptr_dma_list, ptr_curr_node_data); + if (NPS_E_OK == rc) + { + kfree(ptr_curr_node_data); + } + } + rc = osal_mdc_list_locateHead(ptr_dma_list, &ptr_curr_node); + } + rc = osal_mdc_list_destroy(ptr_dma_list, NULL); + if (NPS_E_OK == rc) + { + ptr_dma_info->ptr_dma_list = NULL; + } + } + return (rc); +} + +#endif /* End of NPS_LINUX_KERNEL_MODE */ + +#if defined(NPS_EN_DMA_RESERVED) + +#if defined(NPS_LINUX_KERNEL_MODE) + +#if defined(OSAL_MDC_EN_TEST) +static NPS_ERROR_NO_T +_osal_mdc_dumpRsrvDmaList(void) +{ + OSAL_MDC_DMA_INFO_T *ptr_dma_info = &_osal_mdc_cb.dma_info; + OSAL_MDC_LIST_NODE_T *ptr_curr_node; + OSAL_MDC_DMA_NODE_T *ptr_curr_node_data; + UI32_T node = 0; + NPS_ERROR_NO_T rc = NPS_E_OK; + + rc = osal_mdc_list_locateHead((OSAL_MDC_LIST_T *)ptr_dma_info->ptr_dma_list, + &ptr_curr_node); + while (NPS_E_OK == rc) + { + rc = osal_mdc_list_getNodeData((OSAL_MDC_LIST_T *)ptr_dma_info->ptr_dma_list, + ptr_curr_node, (void **)&ptr_curr_node_data); + if (NPS_E_OK == rc) + { + OSAL_MDC_ERR( + "node %d. virt addr=%p, phy addr=%p, size=%d, avbl=%d\n", node, + ptr_curr_node_data->ptr_virt_addr, ptr_curr_node_data->phy_addr, + ptr_curr_node_data->size, ptr_curr_node_data->available); + } + rc = osal_mdc_list_next((OSAL_MDC_LIST_T *)ptr_dma_info->ptr_dma_list, + ptr_curr_node, &ptr_curr_node); + node++; + } + return (rc); +} +#endif + +static NPS_ERROR_NO_T +_osal_mdc_createRsrvDmaNodeList( + OSAL_MDC_DMA_INFO_T *ptr_dma_info) +{ + OSAL_MDC_DMA_NODE_T *ptr_node_data; + NPS_ERROR_NO_T rc; + + rc = osal_mdc_list_create(OSAL_MDC_DMA_LIST_SZ_UNLIMITED, + OSAL_MDC_LIST_TYPE_DOUBLE, + OSAL_MDC_DMA_LIST_NAME, + (OSAL_MDC_LIST_T **)&ptr_dma_info->ptr_dma_list); + if (NPS_E_OK == rc) + { + /* The first node, which contains all of the reserved memory */ + ptr_node_data = kmalloc(sizeof(OSAL_MDC_DMA_NODE_T), GFP_KERNEL); + if (NULL != ptr_node_data) + { + ptr_node_data->ptr_virt_addr = ptr_dma_info->ptr_rsrv_virt_addr; + ptr_node_data->phy_addr = ptr_dma_info->rsrv_phy_addr; + ptr_node_data->size = ptr_dma_info->rsrv_size; + ptr_node_data->available = TRUE; + rc = osal_mdc_list_insertToHead((OSAL_MDC_LIST_T *)ptr_dma_info->ptr_dma_list, + ptr_node_data); + } + else + { + rc = NPS_E_NO_MEMORY; + } + } + return (rc); +} + +static NPS_ERROR_NO_T +_osal_mdc_searchAvblRsrvDmaNode( + OSAL_MDC_LIST_T *ptr_dma_list, + const UI32_T size, + OSAL_MDC_LIST_NODE_T **pptr_avbl_node) +{ + OSAL_MDC_LIST_NODE_T *ptr_curr_node; + OSAL_MDC_DMA_NODE_T *ptr_curr_node_data; + NPS_ERROR_NO_T rc; + + rc = osal_mdc_list_locateHead(ptr_dma_list, &ptr_curr_node); + while (NPS_E_OK == rc) + { + rc = osal_mdc_list_getNodeData(ptr_dma_list, ptr_curr_node, (void **)&ptr_curr_node_data); + if (NPS_E_OK == rc) + { + if ((TRUE == ptr_curr_node_data->available) && (ptr_curr_node_data->size >= size)) + { + *pptr_avbl_node = ptr_curr_node; + break; + } + } + rc = osal_mdc_list_next(ptr_dma_list, ptr_curr_node, &ptr_curr_node); + } + return (rc); +} + +static NPS_ERROR_NO_T +_osal_mdc_splitRsrvDmaNodes( + OSAL_MDC_LIST_T *ptr_dma_list, + OSAL_MDC_LIST_NODE_T *ptr_ori_node, + const UI32_T size, + OSAL_MDC_DMA_NODE_T **pptr_new_node_data) +{ + OSAL_MDC_DMA_NODE_T *ptr_ori_node_data; + NPS_ERROR_NO_T rc; + + rc = osal_mdc_list_getNodeData(ptr_dma_list, ptr_ori_node, (void **)&ptr_ori_node_data); + + if (NPS_E_OK == rc) + { + *pptr_new_node_data = kmalloc(sizeof(OSAL_MDC_DMA_NODE_T), GFP_KERNEL); + + /* Create a new node */ + (*pptr_new_node_data)->size = size; + (*pptr_new_node_data)->phy_addr = ptr_ori_node_data->phy_addr; + (*pptr_new_node_data)->ptr_virt_addr = ptr_ori_node_data->ptr_virt_addr; + (*pptr_new_node_data)->available = TRUE; + + /* Update the original node */ + ptr_ori_node_data->size -= size; + ptr_ori_node_data->phy_addr += size; + ptr_ori_node_data->ptr_virt_addr = + (void *)((NPS_HUGE_T)ptr_ori_node_data->ptr_virt_addr + (NPS_HUGE_T)size); + + rc = osal_mdc_list_insertBefore(ptr_dma_list, ptr_ori_node, (void *)*pptr_new_node_data); + if (NPS_E_OK != rc) + { + OSAL_MDC_ERR("insert rsrv dma node to list failed, size=%d, rc=%d\n", size, rc); + /* Recovery */ + ptr_ori_node_data->size += size; + ptr_ori_node_data->phy_addr -= size; + ptr_ori_node_data->ptr_virt_addr = + (void *)((NPS_HUGE_T)ptr_ori_node_data->ptr_virt_addr - (NPS_HUGE_T)size); + kfree(*pptr_new_node_data); + } + } + return (rc); +} + +static void * +_osal_mdc_allocRsrvDmaMem( + OSAL_MDC_DMA_INFO_T *ptr_dma_info, + const UI32_T size) +{ + OSAL_MDC_LIST_T *ptr_dma_list = (OSAL_MDC_LIST_T *)ptr_dma_info->ptr_dma_list; + OSAL_MDC_LIST_NODE_T *ptr_node = NULL; + OSAL_MDC_DMA_NODE_T *ptr_node_data; + OSAL_MDC_DMA_NODE_T *ptr_new_node_data; + void *ptr_virt_addr = NULL; + NPS_ERROR_NO_T rc; + + rc = _osal_mdc_searchAvblRsrvDmaNode(ptr_dma_list, size, &ptr_node); + if (NPS_E_OK == rc) + { + rc = osal_mdc_list_getNodeData(ptr_dma_list, ptr_node, (void **)&ptr_node_data); + if (NPS_E_OK == rc) + { + /* If the node size just fit the user's requirement, just give it to user */ + if (ptr_node_data->size == size) + { + ptr_node_data->available = FALSE; + ptr_virt_addr = ptr_node_data->ptr_virt_addr; + } + /* or split a new node with user required size. */ + else + { + rc = _osal_mdc_splitRsrvDmaNodes(ptr_dma_list, ptr_node, size, &ptr_new_node_data); + if (NPS_E_OK == rc) + { + ptr_new_node_data->available = FALSE; + ptr_virt_addr = ptr_new_node_data->ptr_virt_addr; + } + } + } + } + return (ptr_virt_addr); +} + +static NPS_ERROR_NO_T +_osal_mdc_mergeTwoRsrvDmaNodes( + OSAL_MDC_LIST_T *ptr_dma_list, + OSAL_MDC_DMA_NODE_T *ptr_first_node_data, + OSAL_MDC_DMA_NODE_T *ptr_second_node_data) +{ + ptr_first_node_data->size += ptr_second_node_data->size; + + osal_mdc_list_deleteByData(ptr_dma_list, ptr_second_node_data); + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_osal_mdc_mergeRsrvDmaNodes( + OSAL_MDC_LIST_T *ptr_dma_list, + OSAL_MDC_LIST_NODE_T *ptr_curr_node) +{ + OSAL_MDC_LIST_NODE_T *ptr_prev_node; + OSAL_MDC_LIST_NODE_T *ptr_next_node; + OSAL_MDC_DMA_NODE_T *ptr_curr_node_data; + OSAL_MDC_DMA_NODE_T *ptr_prev_node_data; + OSAL_MDC_DMA_NODE_T *ptr_next_node_data; + NPS_ERROR_NO_T rc; + + rc = osal_mdc_list_getNodeData(ptr_dma_list, ptr_curr_node, (void **)&ptr_curr_node_data); + if (NPS_E_OK == rc) + { + /* First, check if the previous node is available */ + rc = osal_mdc_list_prev(ptr_dma_list, ptr_curr_node, &ptr_prev_node); + if (NPS_E_OK == rc) + { + osal_mdc_list_getNodeData(ptr_dma_list, ptr_prev_node, (void **)&ptr_prev_node_data); + if (TRUE == ptr_prev_node_data->available) + { + _osal_mdc_mergeTwoRsrvDmaNodes(ptr_dma_list, ptr_prev_node_data, ptr_curr_node_data); + ptr_curr_node = ptr_prev_node; + ptr_curr_node_data = ptr_prev_node_data; + } + } + + /* then, check if the next node is available */ + rc = osal_mdc_list_next(ptr_dma_list, ptr_curr_node, &ptr_next_node); + if (NPS_E_OK == rc) + { + rc = osal_mdc_list_getNodeData(ptr_dma_list, ptr_next_node, (void **)&ptr_next_node_data); + if (NPS_E_OK == rc) + { + if (TRUE == ptr_next_node_data->available) + { + _osal_mdc_mergeTwoRsrvDmaNodes(ptr_dma_list, ptr_curr_node_data, ptr_next_node_data); + } + } + } + } + return (rc); +} + +static NPS_ERROR_NO_T +_osal_mdc_freeRsrvDmaMem( + OSAL_MDC_DMA_INFO_T *ptr_dma_info, + void *ptr_virt_addr) +{ + OSAL_MDC_LIST_T *ptr_dma_list = (OSAL_MDC_LIST_T *)ptr_dma_info->ptr_dma_list; + OSAL_MDC_LIST_NODE_T *ptr_node = NULL; + OSAL_MDC_DMA_NODE_T *ptr_node_data = NULL; + NPS_ERROR_NO_T rc; + + rc = _osal_mdc_searchDmaVirtAddr(ptr_dma_list, ptr_virt_addr, &ptr_node, &ptr_node_data); + if (NPS_E_OK == rc) + { + ptr_node_data->available = TRUE; + _osal_mdc_mergeRsrvDmaNodes(ptr_dma_list, ptr_node); + } + return (rc); +} + +#endif /* End of NPS_LINUX_KERNEL_MODE */ + +static NPS_ERROR_NO_T +_osal_mdc_initRsrvDmaMem( + OSAL_MDC_DMA_INFO_T *ptr_dma_info) +{ + struct resource *ptr_res; + NPS_ERROR_NO_T rc = NPS_E_OK; + + ptr_dma_info->rsrv_size = (NPS_ADDR_T)NPS_DMA_RESERVED_SZ * 1024 * 1024; + ptr_dma_info->rsrv_phy_addr = (NPS_ADDR_T)NPS_OS_MEMORY_SZ * 1024 * 1024; + ptr_res = request_mem_region(ptr_dma_info->rsrv_phy_addr, + ptr_dma_info->rsrv_size, "nps_rsrv_mem"); + if (NULL != ptr_res) + { +#if defined(OSAL_MDC_DMA_RESERVED_MEM_CACHEABLE) + ptr_dma_info->ptr_rsrv_virt_addr = ioremap(ptr_dma_info->rsrv_phy_addr, + ptr_dma_info->rsrv_size); +#else + ptr_dma_info->ptr_rsrv_virt_addr = ioremap_nocache(ptr_dma_info->rsrv_phy_addr, + ptr_dma_info->rsrv_size); +#endif + if (NULL == ptr_dma_info->ptr_rsrv_virt_addr) + { +#if defined(NPS_EN_64BIT_ADDR) || defined(NPS_EN_HOST_64_BIT_BIG_ENDIAN) || defined(NPS_EN_HOST_64_BIT_LITTLE_ENDIAN) + OSAL_MDC_ERR( + "ioremap_nocache() failed, phy addr=0x%llx, size=%llu\n", + ptr_dma_info->rsrv_phy_addr, ptr_dma_info->rsrv_size); +#else + OSAL_MDC_ERR( + "ioremap_nocache() failed, phy addr=0x%x, size=%u\n", + ptr_dma_info->rsrv_phy_addr, ptr_dma_info->rsrv_size); +#endif + rc = NPS_E_OTHERS; + } + } + else + { +#if defined(NPS_EN_64BIT_ADDR) || defined(NPS_EN_HOST_64_BIT_BIG_ENDIAN) || defined(NPS_EN_HOST_64_BIT_LITTLE_ENDIAN) + OSAL_MDC_ERR( + "request_mem_region() failed, phy addr=0x%llx, size=%llu\n", + ptr_dma_info->rsrv_phy_addr, ptr_dma_info->rsrv_size); +#else + OSAL_MDC_ERR( + "request_mem_region() failed, phy addr=0x%x, size=%u\n", + ptr_dma_info->rsrv_phy_addr, ptr_dma_info->rsrv_size); +#endif + rc = NPS_E_OTHERS; + } + return (rc); +} + +static NPS_ERROR_NO_T +_osal_mdc_deinitRsrvDmaMem( + OSAL_MDC_DMA_INFO_T *ptr_dma_info) +{ + if (NULL != ptr_dma_info->ptr_rsrv_virt_addr) + { + iounmap(ptr_dma_info->ptr_rsrv_virt_addr); + } + if (0x0 != ptr_dma_info->rsrv_phy_addr) + { + release_mem_region(ptr_dma_info->rsrv_phy_addr, + ptr_dma_info->rsrv_size); + } + return (NPS_E_OK); +} + + +#else /* Else of NPS_EN_DMA_RESERVED */ + + +#if defined(NPS_LINUX_KERNEL_MODE) + +#if defined(OSAL_MDC_EN_TEST) +static NPS_ERROR_NO_T +_osal_mdc_dumpSysDmaList(void) +{ + OSAL_MDC_DMA_INFO_T *ptr_dma_info = &_osal_mdc_cb.dma_info; + OSAL_MDC_LIST_NODE_T *ptr_curr_node; + OSAL_MDC_DMA_NODE_T *ptr_curr_node_data; + UI32_T node = 0; + NPS_ERROR_NO_T rc = NPS_E_OK; + + rc = osal_mdc_list_locateHead((OSAL_MDC_LIST_T *)ptr_dma_info->ptr_dma_list, + &ptr_curr_node); + while (NPS_E_OK == rc) + { + rc = osal_mdc_list_getNodeData((OSAL_MDC_LIST_T *)ptr_dma_info->ptr_dma_list, + ptr_curr_node, (void **)&ptr_curr_node_data); + if (NPS_E_OK == rc) + { + OSAL_MDC_ERR( + "node %d. virt addr=%p, phy addr=%p, size=%d\n", node, + ptr_curr_node_data->ptr_virt_addr, ptr_curr_node_data->phy_addr, + ptr_curr_node_data->size); + } + + rc = osal_mdc_list_next((OSAL_MDC_LIST_T *)ptr_dma_info->ptr_dma_list, + ptr_curr_node, &ptr_curr_node); + node++; + + } + return (rc); +} +#endif + +static NPS_ERROR_NO_T +_osal_mdc_createSysDmaNodeList( + OSAL_MDC_DMA_INFO_T *ptr_dma_info) +{ + NPS_ERROR_NO_T rc; + + rc = osal_mdc_list_create(OSAL_MDC_DMA_LIST_SZ_UNLIMITED, + OSAL_MDC_LIST_TYPE_SINGLY, + OSAL_MDC_DMA_LIST_NAME, + (OSAL_MDC_LIST_T **)&ptr_dma_info->ptr_dma_list); + return (rc); +} +#if !defined(NPS_LAMP) + +static void * +_osal_mdc_allocSysDmaMem( + OSAL_MDC_DMA_INFO_T *ptr_dma_info, + const UI32_T size) +{ + dma_addr_t phy_addr; + OSAL_MDC_DMA_NODE_T *ptr_node_data; + void *ptr_virt_addr = NULL; + NPS_ERROR_NO_T rc = NPS_E_OK; + + ptr_virt_addr = dma_alloc_coherent(ptr_dma_info->ptr_dma_dev, size, &phy_addr, GFP_ATOMIC); + if (NULL != ptr_virt_addr) + { + ptr_node_data = kmalloc(sizeof(OSAL_MDC_DMA_NODE_T), GFP_KERNEL); + ptr_node_data->phy_addr = (NPS_ADDR_T)phy_addr; + ptr_node_data->ptr_virt_addr = ptr_virt_addr; + ptr_node_data->size = size; + + rc = osal_mdc_list_insertToHead((OSAL_MDC_LIST_T *)ptr_dma_info->ptr_dma_list, ptr_node_data); + if (NPS_E_OK != rc) + { + kfree(ptr_node_data); + dma_free_coherent(ptr_dma_info->ptr_dma_dev, size, + ptr_virt_addr, phy_addr); + ptr_virt_addr = NULL; + } + } + return (ptr_virt_addr); +} + +static NPS_ERROR_NO_T +_osal_mdc_freeSysDmaMem( + OSAL_MDC_DMA_INFO_T *ptr_dma_info, + void *ptr_virt_addr) +{ + OSAL_MDC_LIST_NODE_T *ptr_node = NULL; + OSAL_MDC_DMA_NODE_T *ptr_node_data = NULL; + NPS_ERROR_NO_T rc; + + rc = _osal_mdc_searchDmaVirtAddr((OSAL_MDC_LIST_T *)ptr_dma_info->ptr_dma_list, + ptr_virt_addr, &ptr_node, &ptr_node_data); + if (NPS_E_OK == rc) + { + dma_free_coherent(ptr_dma_info->ptr_dma_dev, ptr_node_data->size, + ptr_virt_addr, ptr_node_data->phy_addr); + + osal_mdc_list_deleteByData((OSAL_MDC_LIST_T *)ptr_dma_info->ptr_dma_list, + ptr_node_data); + kfree(ptr_node_data); + } + return (rc); +} +#endif +#endif /* End of NPS_LINUX_KERNEL_MODE */ + +#endif /* End of NPS_EN_DMA_RESERVED */ + +#if defined(NPS_LINUX_KERNEL_MODE) + +void * +osal_mdc_allocDmaMem( + const UI32_T size) +{ + void *ptr_virt_addr = NULL; + +#if defined(NPS_LAMP) + ptr_virt_addr = osal_alloc(size); +#else + OSAL_MDC_DMA_INFO_T *ptr_dma_info = &_osal_mdc_cb.dma_info; + osal_takeSemaphore(&ptr_dma_info->sema, NPS_SEMAPHORE_WAIT_FOREVER); + +#if defined(NPS_EN_DMA_RESERVED) + ptr_virt_addr = _osal_mdc_allocRsrvDmaMem(ptr_dma_info, size); +#else + ptr_virt_addr = _osal_mdc_allocSysDmaMem(ptr_dma_info, size); +#endif + + osal_giveSemaphore(&ptr_dma_info->sema); +#endif + + return ptr_virt_addr; +} + +NPS_ERROR_NO_T +osal_mdc_freeDmaMem( + void *ptr_virt_addr) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + +#if defined(NPS_LAMP) + osal_free(ptr_virt_addr); +#else + OSAL_MDC_DMA_INFO_T *ptr_dma_info = &_osal_mdc_cb.dma_info; + + osal_takeSemaphore(&ptr_dma_info->sema, NPS_SEMAPHORE_WAIT_FOREVER); + +#if defined(NPS_EN_DMA_RESERVED) + rc = _osal_mdc_freeRsrvDmaMem(ptr_dma_info, ptr_virt_addr); +#else + + rc = _osal_mdc_freeSysDmaMem(ptr_dma_info, ptr_virt_addr); +#endif + osal_giveSemaphore(&ptr_dma_info->sema); + + if (NPS_E_OK != rc) + { + OSAL_MDC_ERR("free dma mem failed, virt addr=%p\n", ptr_virt_addr); + } +#endif + + return (rc); +} + +NPS_ERROR_NO_T +osal_mdc_convertPhyToVirt( + const NPS_ADDR_T phy_addr, + void **pptr_virt_addr) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + +#if defined(NPS_EN_DMA_RESERVED) + OSAL_MDC_DMA_INFO_T *ptr_dma_info = &_osal_mdc_cb.dma_info; + NPS_HUGE_T rsrv_virt_base = (NPS_HUGE_T)ptr_dma_info->ptr_rsrv_virt_addr; + NPS_ADDR_T rsrv_phy_base = ptr_dma_info->rsrv_phy_addr; +#endif + +#if defined(NPS_EN_DMA_RESERVED) + *pptr_virt_addr = (void *)(rsrv_virt_base + (NPS_HUGE_T)(phy_addr - rsrv_phy_base)); +#else + *pptr_virt_addr = NULL; + *pptr_virt_addr = phys_to_virt(phy_addr); + rc = (NULL == *pptr_virt_addr) ? (NPS_E_ENTRY_NOT_FOUND) : (NPS_E_OK); +#endif + +#if defined(AML_EN_CUSTOM_DMA_ADDR) + if (NPS_E_OK != rc) + { + /* Here the user may invoke the API for their private DMA + * address conversion. + */ + } +#endif + return (rc); +} + +NPS_ERROR_NO_T +osal_mdc_convertVirtToPhy( + void *ptr_virt_addr, + NPS_ADDR_T *ptr_phy_addr) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + +#if defined(NPS_EN_DMA_RESERVED) + OSAL_MDC_DMA_INFO_T *ptr_dma_info = &_osal_mdc_cb.dma_info; + NPS_HUGE_T rsrv_virt_base = (NPS_HUGE_T)ptr_dma_info->ptr_rsrv_virt_addr; + NPS_ADDR_T rsrv_phy_base = ptr_dma_info->rsrv_phy_addr; +#endif + +#if defined(NPS_EN_DMA_RESERVED) + *ptr_phy_addr = (NPS_ADDR_T)((NPS_HUGE_T)rsrv_phy_base + + (NPS_HUGE_T)ptr_virt_addr - rsrv_virt_base); +#else + *ptr_phy_addr = 0x0; + *ptr_phy_addr = virt_to_phys(ptr_virt_addr); + rc = (0x0 == *ptr_phy_addr) ? (NPS_E_ENTRY_NOT_FOUND) : (NPS_E_OK); +#endif + +#if defined(AML_EN_CUSTOM_DMA_ADDR) + if (NPS_E_OK != rc) + { + /* Here the user may invoke the API for their private DMA + * address conversion. + */ + } +#endif + return (rc); +} + +NPS_ERROR_NO_T +osal_mdc_initDmaMem(void) +{ + OSAL_MDC_DMA_INFO_T *ptr_dma_info = &_osal_mdc_cb.dma_info; + NPS_ERROR_NO_T rc = NPS_E_OK; + + rc = osal_createSemaphore(OSAL_MDC_DMA_SEMAPHORE_NAME, + NPS_SEMAPHORE_BINARY, &ptr_dma_info->sema); + if (NPS_E_OK == rc) + { +#if defined(NPS_EN_DMA_RESERVED) + rc = _osal_mdc_initRsrvDmaMem(ptr_dma_info); + if (NPS_E_OK == rc) + { + rc = _osal_mdc_createRsrvDmaNodeList(ptr_dma_info); + } +#else + rc = _osal_mdc_createSysDmaNodeList(ptr_dma_info); +#endif + } + return (rc); +} + +NPS_ERROR_NO_T +osal_mdc_deinitDmaMem(void) +{ + OSAL_MDC_DMA_INFO_T *ptr_dma_info = &_osal_mdc_cb.dma_info; + + /* Common function for both reserved/system memory. */ + _osal_mdc_destroyDmaNodeList(ptr_dma_info); + +#if defined(NPS_EN_DMA_RESERVED) + _osal_mdc_deinitRsrvDmaMem(ptr_dma_info); +#endif + + osal_destroySemaphore(&ptr_dma_info->sema); + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +osal_mdc_flushCache( + void *ptr_virt_addr, + const UI32_T size) +{ +#if defined(CONFIG_NOT_COHERENT_CACHE) || defined(CONFIG_DMA_NONCOHERENT) + +#if defined(dma_cache_wback_inv) + dma_cache_wback_inv((NPS_HUGE_T)ptr_virt_addr, size); +#else + dma_cache_sync(NULL, ptr_virt_addr, size, DMA_TO_DEVICE); +#endif + +#endif + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +osal_mdc_invalidateCache( + void *ptr_virt_addr, + const UI32_T size) +{ +#if defined(CONFIG_NOT_COHERENT_CACHE) || defined(CONFIG_DMA_NONCOHERENT) + +#if defined(dma_cache_wback_inv) + dma_cache_wback_inv((NPS_HUGE_T)ptr_virt_addr, size); +#else + dma_cache_sync(NULL, ptr_virt_addr, size, DMA_FROM_DEVICE); +#endif + +#endif + return (NPS_E_OK); +} + +#endif /* End of NPS_LINUX_KERNEL_MODE */ + +/* --------------------------------------------------------------------------- Interrupt */ +#if defined(NPS_LINUX_USER_MODE) +static UI32_T _osal_mdc_isr_init_bitmap = 0; /* To record the dev request_irq */ +static UI32_T _osal_mdc_isr_dev_bitmap; /* To record the dev bitmap */ +static spinlock_t _osal_mdc_isr_dev_bitmap_lock; +static wait_queue_head_t _osal_mdc_isr_wait; +static UI32_T _osal_mdc_isr_mask_addr; +static UI32_T _osal_mdc_isr_mask_val; + + +static inline NPS_ERROR_NO_T +_osal_mdc_initInterrupt(void) +{ + /* init top and bottom halves */ + init_waitqueue_head(&_osal_mdc_isr_wait); + + /* init lock and clear device bitmap */ + spin_lock_init(&_osal_mdc_isr_dev_bitmap_lock); + _osal_mdc_isr_dev_bitmap = 0; + _osal_mdc_isr_init_bitmap = 0; + + /* clear chip interrupt mask address and value */ + _osal_mdc_isr_mask_addr = 0; + _osal_mdc_isr_mask_val = 0; + + return (NPS_E_OK); +} + +/* top half */ +static inline NPS_ERROR_NO_T +_osal_mdc_notifyUserProcess( + const UI32_T unit) +{ + unsigned long flags = 0; + + /* mask chip interrupt */ + osal_mdc_writePciReg(unit, _osal_mdc_isr_mask_addr, + &_osal_mdc_isr_mask_val, sizeof(UI32_T)); + + /* set the device bitmap. */ + spin_lock_irqsave(&_osal_mdc_isr_dev_bitmap_lock, flags); + _osal_mdc_isr_dev_bitmap |= (1 << unit); + spin_unlock_irqrestore(&_osal_mdc_isr_dev_bitmap_lock, flags); + + /* notify user process. */ + wake_up_interruptible(&_osal_mdc_isr_wait); + + return (NPS_E_OK); +} + +static inline NPS_ERROR_NO_T +_osal_mdc_waitEvent( + UI32_T *ptr_dev_bitmap) +{ + unsigned long flags = 0; + + wait_event_interruptible(_osal_mdc_isr_wait, (0 != _osal_mdc_isr_dev_bitmap)); + + /* save and clear the device bitmap. */ + spin_lock_irqsave(&_osal_mdc_isr_dev_bitmap_lock, flags); + *ptr_dev_bitmap = _osal_mdc_isr_dev_bitmap; + _osal_mdc_isr_dev_bitmap = 0; + spin_unlock_irqrestore(&_osal_mdc_isr_dev_bitmap_lock, flags); + + return (NPS_E_OK); +} + +static ssize_t +_osal_mdc_read( + struct file *filep, + char __user *buf, + size_t count, + loff_t *ppos) +{ + ssize_t ret; + UI32_T dev_bitmap = 0; + + if (count != sizeof(UI32_T)) + { + return -EINVAL; + } + + /* check if request_irq is inited. */ + if (0 != _osal_mdc_isr_init_bitmap) + { + _osal_mdc_waitEvent(&dev_bitmap); + } + + /* copy the device bitmap to user process. */ + if (0 != copy_to_user(buf, &dev_bitmap, count)) + { + ret = -EFAULT; + } + else + { + ret = count; + } + + return ret; +} +#endif /* End of NPS_LINUX_USER_MODE */ + +static irqreturn_t +_osal_mdc_systemIntrCallback( + int irq, + void *ptr_cookie) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + int linux_rc = IRQ_HANDLED; + OSAL_MDC_DEV_T *ptr_dev = (OSAL_MDC_DEV_T *)ptr_cookie; + + /* Invoke kernel callback, the callback function exist only in below cases: + * 1. SDK built in kernel mode + * 2. SDK built in user mode, NetIF kernel module is enabled + */ + if (NULL != ptr_dev->isr_callback) + { + rc = ptr_dev->isr_callback(ptr_dev->ptr_isr_data); + if (NPS_E_OK != rc) + { + OSAL_MDC_ERR("handle irq failed, rc=%d\n", rc); + linux_rc = IRQ_NONE; + } + } + +#if defined(NPS_LINUX_USER_MODE) + /* Notify user process */ + rc = _osal_mdc_notifyUserProcess(ptr_dev->unit); + if (NPS_E_OK != rc) + { + OSAL_MDC_ERR("notify intr to usr failed, rc=%d\n", rc); + linux_rc = IRQ_NONE; + } +#endif + + return (linux_rc); +} + +NPS_ERROR_NO_T +osal_mdc_registerIsr( + const UI32_T unit, + AML_DEV_ISR_FUNC_T handler, + void *ptr_cookie) +{ + OSAL_MDC_DEV_T *ptr_dev = &_osal_mdc_cb.dev[unit]; + + ptr_dev->isr_callback = handler; + ptr_dev->ptr_isr_data = (void *)((NPS_HUGE_T)unit); + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +osal_mdc_connectIsr( + const UI32_T unit, + AML_DEV_ISR_FUNC_T handler, + AML_DEV_ISR_DATA_T *ptr_cookie) +{ + OSAL_MDC_DEV_T *ptr_dev = &_osal_mdc_cb.dev[unit]; + int linux_rc = 0; + NPS_ERROR_NO_T rc = NPS_E_OK; + +#if defined(NPS_LINUX_USER_MODE) + if (NULL != ptr_cookie) + { + _osal_mdc_isr_mask_addr = ptr_cookie->mask_addr; + _osal_mdc_isr_mask_val = ptr_cookie->mask_val; + } +#endif + + if (NULL == ptr_dev->isr_callback) + { +#if defined(NPS_LINUX_KERNEL_MODE) + /* In user mode, the following database is created in user space. */ + ptr_dev->isr_callback = handler; + ptr_dev->ptr_isr_data = (void *)((NPS_HUGE_T)unit); +#endif + +#if defined(OSAL_MDC_EN_MSI) + /* If "no_msi" flag is set, it means the device doesn't support MSI. */ + if (1 != ptr_dev->ptr_pci_dev->no_msi) + { + linux_rc = pci_enable_msi(ptr_dev->ptr_pci_dev); + if (0 == linux_rc) + { + /* The system gives a new irq number if MSI is enabled sucessfully. */ + ptr_dev->irq = ptr_dev->ptr_pci_dev->irq; + } + else + { + OSAL_MDC_ERR("pci_enable_msi() failed, rc=%d\n", linux_rc); + rc = NPS_E_OTHERS; + } + } +#endif + + linux_rc = request_irq(ptr_dev->irq, _osal_mdc_systemIntrCallback, + 0, OSAL_MDC_DRIVER_NAME, (void *)ptr_dev); + + if (0 != linux_rc) + { + OSAL_MDC_ERR("request_irq() failed, rc=%d\n", linux_rc); + rc = NPS_E_OTHERS; + } + } + else + { + OSAL_MDC_ERR("double req isr err\n"); + rc = NPS_E_OTHERS; + } + return (rc); +} + +NPS_ERROR_NO_T +osal_mdc_disconnectIsr( + const UI32_T unit) +{ + OSAL_MDC_DEV_T *ptr_dev = &_osal_mdc_cb.dev[unit]; + + free_irq(ptr_dev->irq, (void *)ptr_dev); + +#if defined(OSAL_MDC_EN_MSI) + /* Must free the irq before disabling MSI */ + pci_disable_msi(ptr_dev->ptr_pci_dev); +#endif + +#if defined(NPS_LINUX_KERNEL_MODE) + ptr_dev->isr_callback = NULL; + ptr_dev->ptr_isr_data = NULL; +#endif + +#if defined(NPS_LINUX_USER_MODE) + _osal_mdc_isr_mask_addr = 0x0; + _osal_mdc_isr_mask_val = 0x0; +#endif + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +osal_mdc_initDevice( + AML_DEV_T *ptr_dev_list, + UI32_T *ptr_dev_num) +{ + OSAL_MDC_CB_T *ptr_cb = &_osal_mdc_cb; + NPS_ERROR_NO_T rc = NPS_E_OK; + + _ptr_osal_mdc_dev = ptr_dev_list; + + memset(ptr_cb, 0x0, sizeof(OSAL_MDC_CB_T)); + +#if defined(AML_EN_I2C) + rc = _osal_mdc_probeI2cDevice(); + *ptr_dev_num = 1; +#else + rc = _osal_mdc_probePciDevice(); + *ptr_dev_num = ptr_cb->dev_num; + + _ptr_ext_pci_dev = _osal_mdc_cb.dev[0].ptr_pci_dev; +#endif /* End of AML_EN_I2C */ + + return (rc); +} + +NPS_ERROR_NO_T +osal_mdc_deinitDevice(void) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + +#if defined(AML_EN_I2C) + rc = _osal_mdc_removeI2cDevice(); +#else + if (NULL != _ptr_ext_pci_dev) + { + rc = _osal_mdc_removePciDevice(); + _ptr_ext_pci_dev = NULL; + } +#endif + + return (rc); +} + +/*****************************************************************************/ +#if defined(NPS_LINUX_USER_MODE) +/* Interface */ +static UI32_T _osal_mdc_devInited = 0; + +/* DMA */ +#if defined(NPS_EN_DMA_RESERVED) +static UI32_T _osal_mdc_rsvDmaInited = 0; +#else +static struct list_head _osal_mdc_sysDmaList[2]; /* To avoid memory corruption when cold-boot */ +static UI32_T _osal_mdc_sysCurDmaListIdx = 0; +#endif + +/* IOCTL */ +static OSAL_MDC_IOCTL_CB_T _osal_mdc_ioctl_cb; +static AML_DEV_T _osal_mdc_ioctl_dev[NPS_CFG_MAXIMUM_CHIPS_PER_SYSTEM] = {}; + +static int +_osal_mdc_open( + struct inode *ptr_inode, + struct file *ptr_file) +{ + return (0); +} + +static int +_osal_mdc_release( + struct inode *ptr_inode, + struct file *ptr_file) +{ + return (0); +} + +static struct vm_operations_struct _osal_mdc_remap_vm_ops = +{ + .open = NULL, + .close = NULL, +}; + +static int +_osal_mdc_mmap( + struct file *filp, + struct vm_area_struct *vma) +{ + size_t size = vma->vm_end - vma->vm_start; + int linux_rc = 0; + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3,0,48) + pgprot_val(vma->vm_page_prot) |= (_PAGE_NO_CACHE | _PAGE_GUARDED); +#else + UI32_T dev_idx; + OSAL_MDC_DEV_T *ptr_dev; + NPS_ADDR_T phy_addr = vma->vm_pgoff << PAGE_SHIFT; + + /* check mmio base phy addr */ + for (dev_idx = 0, ptr_dev = &_osal_mdc_cb.dev[0]; + dev_idx < _osal_mdc_cb.dev_num; + dev_idx++, ptr_dev++) + { + if ((NULL != ptr_dev->ptr_pci_dev) && + (phy_addr == pci_resource_start(ptr_dev->ptr_pci_dev, OSAL_MDC_PCI_BAR0_OFFSET))) + { + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + break; + } + } +#endif + + vma->vm_flags |= VM_IO; + if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, + size, vma->vm_page_prot)) + { + linux_rc = -EAGAIN; + } + vma->vm_ops = &_osal_mdc_remap_vm_ops; + return (linux_rc); +} + +#if defined(NPS_EN_DMA_RESERVED) + +static NPS_ERROR_NO_T +_osal_mdc_ioctl_initRsrvDmaMemCallback( + const UI32_T unit, + void *ptr_data) +{ + OSAL_MDC_DMA_INFO_T *ptr_dma_info = &_osal_mdc_cb.dma_info; + OSAL_MDC_IOCTL_DMA_DATA_T *ptr_ioctl_data = (OSAL_MDC_IOCTL_DMA_DATA_T *)ptr_data; + NPS_ERROR_NO_T rc = NPS_E_OK; + + if (0 == _osal_mdc_rsvDmaInited) + { + rc = _osal_mdc_initRsrvDmaMem(ptr_dma_info); + _osal_mdc_rsvDmaInited = 1; + } + ptr_ioctl_data->rsrv_dma_phy_addr = ptr_dma_info->rsrv_phy_addr; + ptr_ioctl_data->rsrv_dma_size = ptr_dma_info->rsrv_size; + + return (rc); +} + +static NPS_ERROR_NO_T +_osal_mdc_ioctl_deinitRsrvDmaMemCallback( + const UI32_T unit, + void *ptr_data) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + + rc = _osal_mdc_deinitRsrvDmaMem(&_osal_mdc_cb.dma_info); + _osal_mdc_rsvDmaInited = 0; + + return (rc); +} + +#else + +static NPS_ERROR_NO_T +_osal_mdc_clearSysDmaList( + UI32_T dmaListIdx) +{ + OSAL_MDC_DMA_INFO_T *ptr_dma_info = &_osal_mdc_cb.dma_info; + OSAL_MDC_USER_MODE_DMA_NODE_T *ptr_curr_node_data = NULL; + OSAL_MDC_USER_MODE_DMA_NODE_T *ptr_next_node_data = NULL; + void *ptr_virt_addr; + + list_for_each_entry_safe(ptr_curr_node_data, ptr_next_node_data, + &_osal_mdc_sysDmaList[dmaListIdx], list) + { + list_del(&(ptr_curr_node_data->list)); + ptr_virt_addr = phys_to_virt(ptr_curr_node_data->phy_addr); + dma_free_coherent(ptr_dma_info->ptr_dma_dev, + ptr_curr_node_data->size, ptr_virt_addr, + ptr_curr_node_data->phy_addr); + kfree(ptr_curr_node_data); + } + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_osal_mdc_ioctl_allocSysDmaMemCallback( + const UI32_T unit, + void *ptr_data) +{ + OSAL_MDC_DMA_INFO_T *ptr_dma_info = &_osal_mdc_cb.dma_info; + OSAL_MDC_IOCTL_DMA_DATA_T *ptr_ioctl_data = (OSAL_MDC_IOCTL_DMA_DATA_T *)ptr_data; + OSAL_MDC_USER_MODE_DMA_NODE_T *ptr_node_data = NULL; + +/* To defense the compatible data type of 32bit and 64bit are not synchronized */ +#if defined(CONFIG_ARCH_DMA_ADDR_T_64BIT) /* Bus addressing is 64-bit */\ +&& !defined(NPS_EN_64BIT_ADDR) /* SDK follows HOST with 32-bit addr*/\ +&& (defined(NPS_EN_HOST_32_BIT_LITTLE_ENDIAN) || defined(NPS_EN_HOST_32_BIT_BIG_ENDIAN))/* HOST is 32-bit */ +#error "The DMA address of OS is 64bit. Please enable NPS_EN_64BIT_ADDR in SDK." +#endif + +#if !defined(CONFIG_ARCH_DMA_ADDR_T_64BIT) && defined(NPS_EN_64BIT_ADDR) +#error "The DMA address of OS is not 64bit. Please disable NPS_EN_64BIT_ADDR in SDK." +#endif + + if (NULL == dma_alloc_coherent(ptr_dma_info->ptr_dma_dev, ptr_ioctl_data->size, + (dma_addr_t *)&ptr_ioctl_data->phy_addr, GFP_ATOMIC)) + { + return (NPS_E_NO_MEMORY); + } + + ptr_node_data = kmalloc(sizeof(OSAL_MDC_USER_MODE_DMA_NODE_T), GFP_KERNEL); + if (NULL != ptr_node_data) + { + memset(ptr_node_data, 0, sizeof(OSAL_MDC_USER_MODE_DMA_NODE_T)); + ptr_node_data->phy_addr = ptr_ioctl_data->phy_addr; + ptr_node_data->size = ptr_ioctl_data->size; + list_add(&(ptr_node_data->list), &_osal_mdc_sysDmaList[_osal_mdc_sysCurDmaListIdx]); + } + else + { + dma_free_coherent(ptr_dma_info->ptr_dma_dev, ptr_ioctl_data->size, + phys_to_virt(ptr_ioctl_data->phy_addr), ptr_ioctl_data->phy_addr); + + return (NPS_E_NO_MEMORY); + } + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_osal_mdc_ioctl_freeSysDmaMemCallback( + const UI32_T unit, + void *ptr_data) +{ + OSAL_MDC_DMA_INFO_T *ptr_dma_info = &_osal_mdc_cb.dma_info; + OSAL_MDC_IOCTL_DMA_DATA_T *ptr_ioctl_data = (OSAL_MDC_IOCTL_DMA_DATA_T *)ptr_data; + void *ptr_virt_addr; + + OSAL_MDC_USER_MODE_DMA_NODE_T *ptr_curr_node_data = NULL; + OSAL_MDC_USER_MODE_DMA_NODE_T *ptr_next_node_data = NULL; + + + list_for_each_entry_safe(ptr_curr_node_data, ptr_next_node_data, + &_osal_mdc_sysDmaList[_osal_mdc_sysCurDmaListIdx], list) + { + if (ptr_curr_node_data->phy_addr == ptr_ioctl_data->phy_addr) + { + list_del(&(ptr_curr_node_data->list)); + kfree(ptr_curr_node_data); + break; + } + } + + ptr_virt_addr = phys_to_virt(ptr_ioctl_data->phy_addr); + dma_free_coherent(ptr_dma_info->ptr_dma_dev, ptr_ioctl_data->size, + ptr_virt_addr, ptr_ioctl_data->phy_addr); + + return (NPS_E_OK); +} + +#endif + +static NPS_ERROR_NO_T +_osal_mdc_getPciInfoToIoctlData( + const OSAL_MDC_DEV_T *ptr_dev_list, + OSAL_MDC_IOCTL_DEV_DATA_T *ptr_dev_data) +{ + UI32_T idx; + + /* Search for PCIe device and get the MMIO base address. */ + for (idx = 0; idx < _osal_mdc_cb.dev_num; idx++) + { + if (NULL != ptr_dev_list[idx].ptr_pci_dev) + { + ptr_dev_data->pci_mmio_phy_start[idx] = + pci_resource_start(ptr_dev_list[idx].ptr_pci_dev, OSAL_MDC_PCI_BAR0_OFFSET); + + ptr_dev_data->pci_mmio_size[idx] = + pci_resource_len(ptr_dev_list[idx].ptr_pci_dev, OSAL_MDC_PCI_BAR0_OFFSET); + } + } + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_osal_mdc_getDeviceIdToIoctlData( + AML_DEV_T *ptr_dev, + OSAL_MDC_IOCTL_DEV_DATA_T *ptr_dev_data, + const UI32_T dev_num) +{ + UI32_T idx; + + for (idx = 0; idx < ptr_dev_data->dev_num; idx++) + { + ptr_dev_data->id[idx].device = ptr_dev[idx].id.device; + ptr_dev_data->id[idx].vendor = ptr_dev[idx].id.vendor; + ptr_dev_data->id[idx].revision = ptr_dev[idx].id.revision; + } + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_osal_mdc_ioctl_initDeviceCallback( + const UI32_T unit, + void *ptr_data) +{ + OSAL_MDC_CB_T *ptr_cb = &_osal_mdc_cb; + OSAL_MDC_DEV_T *ptr_dev_list = _osal_mdc_cb.dev; + OSAL_MDC_IOCTL_DEV_DATA_T *ptr_ioctl_data = (OSAL_MDC_IOCTL_DEV_DATA_T *)ptr_data; + + /* "dev" is just created for invoking osal_mdc_initDevice, + * it is no use once the device IDs are copy to ptr_ioctl_data. + */ + + NPS_ERROR_NO_T rc = NPS_E_OK; + + if (0 == _osal_mdc_devInited) + { + rc = osal_mdc_initDevice(_osal_mdc_ioctl_dev, &ptr_ioctl_data->dev_num); + } + else + { + /* ptr_cb->dev_num was initialized in osal_mdc_initDevice(); */ + ptr_ioctl_data->dev_num = ptr_cb->dev_num; + } + + if (ptr_cb->dev_num >= NPS_CFG_MAXIMUM_CHIPS_PER_SYSTEM) + { + OSAL_MDC_ERR("dev num=%d > max support num=%d\n", + ptr_ioctl_data->dev_num, NPS_CFG_MAXIMUM_CHIPS_PER_SYSTEM); + } + +#if !defined(NPS_EN_DMA_RESERVED) + if (0 == _osal_mdc_devInited) + { + /* Create two DMA memory lists and use 1st. */ + INIT_LIST_HEAD(&_osal_mdc_sysDmaList[0]); + INIT_LIST_HEAD(&_osal_mdc_sysDmaList[1]); + _osal_mdc_sysCurDmaListIdx = 0; + } + else + { + /* Delay free the old list until the chip is reset. + * When we kill the process, the chip continues to write to the DMA memory. + * If we free the old DMA memory before stopping the chip, there could be memory corruption. + */ + _osal_mdc_sysCurDmaListIdx = ((_osal_mdc_sysCurDmaListIdx + 1) & 0x1); + rc = _osal_mdc_clearSysDmaList(_osal_mdc_sysCurDmaListIdx); + } +#endif + + if (NPS_E_OK == rc) + { + rc = _osal_mdc_getDeviceIdToIoctlData(_osal_mdc_ioctl_dev, ptr_ioctl_data, ptr_ioctl_data->dev_num); + } + if (NPS_E_OK == rc) + { + rc = _osal_mdc_getPciInfoToIoctlData(ptr_dev_list, ptr_ioctl_data); + } + + _osal_mdc_devInited = 1; + return (rc); +} + +static NPS_ERROR_NO_T +_osal_mdc_ioctl_deinitDeviceCallback( + const UI32_T unit, + void *ptr_data) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + +#if !defined(NPS_EN_DMA_RESERVED) + _osal_mdc_clearSysDmaList(0); + _osal_mdc_clearSysDmaList(1); +#endif + + if (0 != _osal_mdc_devInited) + { + rc = osal_mdc_deinitDevice(); + _osal_mdc_devInited = 0; + } + + return (rc); +} + +static NPS_ERROR_NO_T +_osal_mdc_ioctl_connectIsrCallback( + const UI32_T unit, + void *ptr_data) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + + if (0 == (_osal_mdc_isr_init_bitmap & (1 << unit))) + { + rc = osal_mdc_connectIsr(unit, NULL, ptr_data); + if (NPS_E_OK == rc) + { + _osal_mdc_isr_init_bitmap |= (1 << unit); + } + } + return (rc); +} + +static NPS_ERROR_NO_T +_osal_mdc_ioctl_disconnectIsrCallback( + const UI32_T unit, + void *ptr_data) +{ + /* To make the user-space polling task return from read. */ + _osal_mdc_notifyUserProcess(unit); + + osal_mdc_disconnectIsr(unit); + _osal_mdc_isr_init_bitmap &= ~(1 << unit); + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_osal_mdc_registerIoctlCallback( + const OSAL_MDC_IOCTL_TYPE_T type, + const OSAL_MDC_IOCTL_CALLBACK_FUNC_T func) +{ + OSAL_MDC_IOCTL_CB_T *ptr_cb = &_osal_mdc_ioctl_cb; + NPS_ERROR_NO_T rc = NPS_E_OTHERS; + + if (type < OSAL_MDC_IOCTL_TYPE_LAST) + { + if (NULL == ptr_cb->callback[type]) + { + ptr_cb->callback[type] = func; + rc = NPS_E_OK; + } + else + { + OSAL_MDC_ERR("register ioctl callback failed, type=%d exist\n", type); + } + } + else + { + OSAL_MDC_ERR("register ioctl callback failed, type=%d >= max=%d\n", + type, OSAL_MDC_IOCTL_TYPE_LAST); + } + return (rc); +} + +static NPS_ERROR_NO_T +_osal_mdc_initIoctl(void) +{ + memset(&_osal_mdc_ioctl_cb, 0x0, sizeof(OSAL_MDC_IOCTL_CB_T)); + + _osal_mdc_registerIoctlCallback(OSAL_MDC_IOCTL_TYPE_MDC_INIT_DEV, + _osal_mdc_ioctl_initDeviceCallback); + + _osal_mdc_registerIoctlCallback(OSAL_MDC_IOCTL_TYPE_MDC_DEINIT_DEV, + _osal_mdc_ioctl_deinitDeviceCallback); +#if defined(NPS_EN_DMA_RESERVED) + _osal_mdc_registerIoctlCallback(OSAL_MDC_IOCTL_TYPE_MDC_INIT_RSRV_DMA_MEM, + _osal_mdc_ioctl_initRsrvDmaMemCallback); + + _osal_mdc_registerIoctlCallback(OSAL_MDC_IOCTL_TYPE_MDC_DEINIT_RSRV_DMA_MEM, + _osal_mdc_ioctl_deinitRsrvDmaMemCallback); +#else + _osal_mdc_registerIoctlCallback(OSAL_MDC_IOCTL_TYPE_MDC_ALLOC_SYS_DMA_MEM, + _osal_mdc_ioctl_allocSysDmaMemCallback); + + _osal_mdc_registerIoctlCallback(OSAL_MDC_IOCTL_TYPE_MDC_FREE_SYS_DMA_MEM, + _osal_mdc_ioctl_freeSysDmaMemCallback); +#endif + _osal_mdc_registerIoctlCallback(OSAL_MDC_IOCTL_TYPE_MDC_CONNECT_ISR, + _osal_mdc_ioctl_connectIsrCallback); + + _osal_mdc_registerIoctlCallback(OSAL_MDC_IOCTL_TYPE_MDC_DISCONNECT_ISR, + _osal_mdc_ioctl_disconnectIsrCallback); + return (NPS_E_OK); +} + +static long +_osal_mdc_ioctl( + struct file *filp, + unsigned int cmd, + unsigned long arg) +{ +#define OSAL_MDC_IOCTL_LOCAL_BUF_SIZE (128) + + OSAL_MDC_IOCTL_CB_T *ptr_cb = &_osal_mdc_ioctl_cb; + OSAL_MDC_IOCTL_CMD_T *ptr_cmd = (OSAL_MDC_IOCTL_CMD_T *)&cmd; + UI32_T unit = ptr_cmd->field.unit; + OSAL_MDC_IOCTL_TYPE_T type = ptr_cmd->field.type; + OSAL_MDC_IOCTL_ACCESS_T access = ptr_cmd->field.access; + UI32_T data_size = ptr_cmd->field.size; + UI8_T temp_buf[OSAL_MDC_IOCTL_LOCAL_BUF_SIZE]; + UI8_T *ptr_temp_buf; + int linux_rc = 0; + + if (NULL != ptr_cb->callback[type]) + { + if (data_size > OSAL_MDC_IOCTL_LOCAL_BUF_SIZE) + { + ptr_temp_buf = kmalloc(data_size, GFP_KERNEL); + } + else + { + ptr_temp_buf = temp_buf; + } + + /*************************************************************/ + if (OSAL_MDC_IOCTL_ACCESS_WRITE == access) + { + /* type: FREE_SYS_DMA_MEM : DMA physical address + * CONNECT_ISR : Chip interrupt mask address and value + */ + if (copy_from_user(ptr_temp_buf, (int __user *)arg, data_size)) + { + linux_rc = -EFAULT; + } + else + { + if (NPS_E_OK != ptr_cb->callback[type](unit, (void *)ptr_temp_buf)) + { + linux_rc = -EFAULT; + } + } + } + else if (OSAL_MDC_IOCTL_ACCESS_READ == access) + { + /* type: INIT_DEV : PCIe device and vendor ID, mmio address and size + * INIT_RSRV_DMA_MEM : Reserved DMA physical address and size + */ + if (NPS_E_OK != ptr_cb->callback[type](unit, (void *)ptr_temp_buf)) + { + linux_rc = -EFAULT; + } + else + { + if (copy_to_user((int __user *)arg, ptr_temp_buf, data_size)) + { + linux_rc = -EFAULT; + } + } + } + else if (OSAL_MDC_IOCTL_ACCESS_READ_WRITE == access) + { + /* type: ALLOC_SYS_DMA_MEM : DMA physical address + */ + if (copy_from_user(ptr_temp_buf, (int __user *)arg, data_size)) + { + linux_rc = -EFAULT; + } + else + { + if (NPS_E_OK != ptr_cb->callback[type](unit, (void *)ptr_temp_buf)) + { + linux_rc = -EFAULT; + } + else + { + if (copy_to_user((int __user *)arg, ptr_temp_buf, data_size)) + { + linux_rc = -EFAULT; + } + } + } + } + else if (OSAL_MDC_IOCTL_ACCESS_NONE == access) + { + /* type: DEINIT_DEV + * DEINIT_RSRV_DMA_MEM + * DISCONNECT_ISR + */ + if (NPS_E_OK != ptr_cb->callback[type](unit, (void *)ptr_temp_buf)) + { + linux_rc = -EFAULT; + } + } + /*************************************************************/ + + if (data_size > OSAL_MDC_IOCTL_LOCAL_BUF_SIZE) + { + kfree(ptr_temp_buf); + } + } + else + { + OSAL_MDC_ERR("invalid ioctl, cmd=%u, arg=%lu, type=%d\n", cmd, arg, type); + } + return (linux_rc); +} + +#ifdef CONFIG_COMPAT +static long +_osal_mdc_compat_ioctl( + struct file *filp, + unsigned int cmd, + unsigned long arg) +{ + return _osal_mdc_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); +} +#endif + +static struct file_operations _osal_mdc_fops = +{ + .owner = THIS_MODULE, + .open = _osal_mdc_open, + .read = _osal_mdc_read, + .release = _osal_mdc_release, + .unlocked_ioctl = _osal_mdc_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = _osal_mdc_compat_ioctl, +#endif + .mmap = _osal_mdc_mmap, +}; + +static struct miscdevice _osal_mdc_misc = +{ + .minor = OSAL_MDC_DRIVER_MISC_MINOR_NUM, + .name = OSAL_MDC_DRIVER_NAME, + .fops = & _osal_mdc_fops, +}; + +static int __init +osal_mdc_module_init(void) +{ + int linux_rc; + + _osal_mdc_initIoctl(); /* To register IOCTL callback functions. */ + _osal_mdc_initInterrupt(); /* To init structs for top and bottom halves */ + + linux_rc = misc_register(&_osal_mdc_misc); + if (0 != linux_rc) + { + OSAL_MDC_ERR("register dev %s failed, linux_rc=%d\n", OSAL_MDC_DRIVER_NAME, linux_rc); + } + return (linux_rc); +} + +static void __exit +osal_mdc_module_exit(void) +{ + int unit = 0; + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,2,8) + int linux_rc; + + linux_rc = misc_deregister(&_osal_mdc_misc); + if (0 != linux_rc) + { + OSAL_MDC_ERR("de-register dev %s failed, linux_rc=%d\n", OSAL_MDC_DRIVER_NAME, linux_rc); + } +#else + misc_deregister(&_osal_mdc_misc); +#endif + + /* ref: _osal_mdc_ioctl_disconnectIsrCallback */ + for (unit = 0; unit < NPS_CFG_MAXIMUM_CHIPS_PER_SYSTEM; unit++) + { + if (0 != (_osal_mdc_isr_init_bitmap & (1 << unit))) + { + osal_mdc_disconnectIsr(unit); + _osal_mdc_isr_init_bitmap &= ~(1 << unit); + } + } + + /* ref: _osal_mdc_ioctl_deinitRsrvDmaMemCallback */ +#if defined(NPS_EN_DMA_RESERVED) + if (1 == _osal_mdc_rsvDmaInited) + { + _osal_mdc_deinitRsrvDmaMem(&_osal_mdc_cb.dma_info); + _osal_mdc_rsvDmaInited = 0; + } +#endif + + /* ref: _osal_mdc_ioctl_deinitDeviceCallback */ + if (1 == _osal_mdc_devInited) + { +#if !defined(NPS_EN_DMA_RESERVED) + _osal_mdc_clearSysDmaList(0); + _osal_mdc_clearSysDmaList(1); +#endif + osal_mdc_deinitDevice(); + _osal_mdc_devInited = 0; + } +} + +#else + +static int __init +osal_mdc_module_init(void) +{ + return (0); +} + +static void __exit +osal_mdc_module_exit(void) +{ + +} + +#endif /* End of NPS_LINUX_USER_MODE */ + +module_init(osal_mdc_module_init); +module_exit(osal_mdc_module_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Nephos"); +MODULE_DESCRIPTION("SDK Kernel Module"); diff --git a/platform/nephos/one-image.mk b/platform/nephos/one-image.mk index d29d0e8c9350..27bb09b46dba 100644 --- a/platform/nephos/one-image.mk +++ b/platform/nephos/one-image.mk @@ -3,7 +3,7 @@ SONIC_ONE_IMAGE = sonic-nephos.bin $(SONIC_ONE_IMAGE)_MACHINE = nephos $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie -$(SONIC_ONE_IMAGE)_INSTALLS += $(NEPHOS_NPS_KERNEL) +$(SONIC_ONE_IMAGE)_INSTALLS += $(NEPHOS_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9130_32X_PLATFORM_MODULE) \ $(INGRASYS_S9230_64X_PLATFORM_MODULE) \ $(ACCTON_AS7116_54X_PLATFORM_MODULE) \ diff --git a/platform/nephos/rules.mk b/platform/nephos/rules.mk index 4ae297521549..6c201fcccd96 100644 --- a/platform/nephos/rules.mk +++ b/platform/nephos/rules.mk @@ -1,5 +1,5 @@ -include $(PLATFORM_PATH)/sdk.mk include $(PLATFORM_PATH)/sai.mk +include $(PLATFORM_PATH)/nephos-modules.mk include $(PLATFORM_PATH)/platform-modules-ingrasys.mk include $(PLATFORM_PATH)/platform-modules-accton.mk include $(PLATFORM_PATH)/platform-modules-cig.mk @@ -12,15 +12,17 @@ include $(PLATFORM_PATH)/docker-ptf-nephos.mk NPX_DIAG = npx_diag $(NPX_DIAG)_URL = "https://github.com/NephosInc/SONiC/raw/master/sdk/npx_diag" +WARM_VERIFIER = warm-verifier +$(WARM_VERIFIER)_URL = "https://github.com/NephosInc/SONiC/raw/master/sai/warm-verifier" DSSERVE = dsserve $(DSSERVE)_URL = "https://sonicstorage.blob.core.windows.net/packages/20170518/dsserve?sv=2015-04-05&sr=b&sig=gyNbgSL%2FvpMXDdpboVkIJcTKMRdGgEaOR9OukHhEsu8%3D&se=2030-03-31T23%3A06%3A35Z&sp=r" -SONIC_ONLINE_FILES += $(NPX_DIAG) $(DSSERVE) +SONIC_ONLINE_FILES += $(NPX_DIAG) $(WARM_VERIFIER) $(DSSERVE) SONIC_ALL += $(SONIC_ONE_IMAGE) $(DOCKER_FPM) # Inject nephos sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(NEPHOS_SAI) $(NEPHOS_SAI_DEV) $(LIBSAITHRIFT_DEV_NEPHOS) +$(LIBSAIREDIS)_DEPENDS += $(NEPHOS_SAI) $(NEPHOS_SAI_DEV) $(LIBSAITHRIFT_DEV) # Runtime dependency on nephos sai is set only for syncd $(SYNCD)_RDEPENDS += $(NEPHOS_SAI) diff --git a/platform/nephos/sai.mk b/platform/nephos/sai.mk index 4bfa27999259..af5d1f4e1d2a 100644 --- a/platform/nephos/sai.mk +++ b/platform/nephos/sai.mk @@ -1,6 +1,6 @@ -SDK_VERSION = 2.0.5 -SAI_VERSION = 1.3.5 -SAI_COMMIT_ID = 575f90 +SDK_VERSION = 2.0.8 +SAI_VERSION = 1.4.0 +SAI_COMMIT_ID = c818c7 NEPHOS_SAI = libsainps_$(SDK_VERSION)_sai_$(SAI_VERSION)_$(SAI_COMMIT_ID)_amd64.deb $(NEPHOS_SAI)_URL = "https://github.com/NephosInc/SONiC/raw/master/sai/libsainps_$(SDK_VERSION)_sai_$(SAI_VERSION)_$(SAI_COMMIT_ID)_amd64.deb" diff --git a/platform/nephos/sdk.mk b/platform/nephos/sdk.mk deleted file mode 100644 index 79c05904e15a..000000000000 --- a/platform/nephos/sdk.mk +++ /dev/null @@ -1,7 +0,0 @@ -SDK_VERSION = 2.0.5 -LINUX_VER = 4.9.0-8-2 -SDK_COMMIT_ID = f2e56f -NEPHOS_NPS_KERNEL = nps-modules-$(LINUX_VER)_$(SDK_VERSION)_$(SDK_COMMIT_ID)_amd64.deb -$(NEPHOS_NPS_KERNEL)_URL = "https://github.com/NephosInc/SONiC/raw/master/sdk/nps-modules-$(LINUX_VER)_$(SDK_VERSION)_$(SDK_COMMIT_ID)_amd64.deb" - -SONIC_ONLINE_DEBS += $(NEPHOS_NPS_KERNEL) From 818bbe8b6838ef7a6562755e15eefbe53dad4f4a Mon Sep 17 00:00:00 2001 From: paavaanan Date: Tue, 30 Apr 2019 07:00:36 +0530 Subject: [PATCH 10/88] [devices]: DellEMC S6000 xcvrd support (#2560) * DellEMC S6000, xcvrd support * sleep 1 second to avoid busy looping * removal of dead code * Correct typo error to 1 second * Introduced 1 second sleep * Revamped script with blocking call support * get_transceiver_change_event api definition update * adding timeout support for get_transceiver_change_event --- .../plugins/sfputil.py | 87 +++++++++++++++++-- 1 file changed, 80 insertions(+), 7 deletions(-) diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/plugins/sfputil.py b/device/dell/x86_64-dell_s6000_s1220-r0/plugins/sfputil.py index 9275c4c9b6fb..b27bf4bc22ea 100644 --- a/device/dell/x86_64-dell_s6000_s1220-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dell_s6000_s1220-r0/plugins/sfputil.py @@ -5,6 +5,7 @@ try: import time + import datetime from sonic_sfp.sfputilbase import SfpUtilBase except ImportError as e: raise ImportError("%s - required module not found" % str(e)) @@ -20,6 +21,7 @@ class SfpUtil(SfpUtilBase): EEPROM_OFFSET = 20 _port_to_eeprom_mapping = {} + port_dict = {} @property def port_start(self): @@ -37,12 +39,33 @@ def qsfp_ports(self): def port_to_eeprom_mapping(self): return self._port_to_eeprom_mapping + @property + def get_transceiver_status(self): + + try: + reg_file = open("/sys/devices/platform/dell-s6000-cpld.0/qsfp_modprs") + + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = reg_file.readline().rstrip() + + reg_file.close() + + return int(content, 16) + + def __init__(self): + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" for x in range(0, self.port_end + 1): self._port_to_eeprom_mapping[x] = eeprom_path.format(x + self.EEPROM_OFFSET) + # Get Transceiver status + self.modprs_register = self.get_transceiver_status + SfpUtilBase.__init__(self) def get_presence(self, port_num): @@ -174,10 +197,60 @@ def reset(self, port_num): return True - def get_transceiver_change_event(self): - """ - TODO: This function need to be implemented - when decide to support monitoring SFP(Xcvrd) - on this platform. - """ - raise NotImplementedError + def get_transceiver_change_event(self, timeout=0): + + start_time = time.time() + port_dict = {} + port = self.port_start + forever = False + + if timeout == 0: + forever = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + print "get_transceiver_change_event:Invalid timeout value", timeout + return False, {} + + end_time = start_time + timeout + if start_time > end_time: + print 'get_transceiver_change_event:' \ + 'time wrap / invalid timeout value', timeout + + return False, {} # Time wrap or possibly incorrect timeout + + while timeout >= 0: + # Check for OIR events and return updated port_dict + reg_value = self.get_transceiver_status + if reg_value != self.modprs_register: + changed_ports = self.modprs_register ^ reg_value + while port >= self.port_start and port <= self.port_end: + + # Mask off the bit corresponding to our port + mask = (1 << port) + + if changed_ports & mask: + # ModPrsL is active low + if reg_value & mask == 0: + port_dict[port] = '1' + else: + port_dict[port] = '0' + + port += 1 + + # Update reg value + self.modprs_register = reg_value + return True, port_dict + + if forever: + time.sleep(1) + else: + timeout = end_time - time.time() + if timeout >= 1: + time.sleep(1) # We poll at 1 second granularity + else: + if timeout > 0: + time.sleep(timeout) + return True, {} + print "get_transceiver_change_event: Should not reach here." + return False, {} From df45a77296b60bbbffcd121f92aed9336e10c731 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Tue, 30 Apr 2019 14:45:45 -0700 Subject: [PATCH 11/88] [sonic-utilities] advance submodule head to latest (#2842) Submodule src/sonic-utilities 6ee0aea..b531934: > [db migrator] Introduce the DB migration infrastructure (#519) > Skip INTERFACE entries w/o prefix (#477) > Bring queue storm status to 'pfcwd show stats' (#500) > Align PSU DB count field with the schema Spec. (#509) > [scripts] remove duplicate script copying for nbrshow (#517) > If fast-reboot-dump gives an error, don't continue with fast-reboot (#515) > load_minigraph: restart hostcfgd (#511) > [fast/warm reboot] add some sanity check before warm reboot (#510) > show BPS, PPS, UTIL rates w/o previous clear (#508) > In sync with our latest change, where we default failthrough to be False. (#507) > Add warm-boot feature processing for wedge100bf_32x/65x platforms (#485) > [generate_dump] system dump improvements (#503) > [neighbor advertiser] convert int to string before concatenating (#505) Signed-off-by: Ying Xie --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 6ee0aea0e598..b531934c6212 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 6ee0aea0e59807b45b502296e4248ea4534bb96e +Subproject commit b531934c621287f29a7f0dace6cb30ad93ada008 From 64312482438dc0e577e8db0808aaa74e65b381eb Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Tue, 30 Apr 2019 14:46:18 -0700 Subject: [PATCH 12/88] [db migrator] migrate the DB to latest schema when needed (#2808) Signed-off-by: Ying Xie --- files/build_templates/docker_image_ctl.j2 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index c2d227b43522..a828dfb4c296 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -59,6 +59,11 @@ function postStartAction() redis-cli -n 4 SET "CONFIG_DB_INITIALIZED" "1" fi + + if [[ -x /usr/bin/db_migrator.py ]]; then + # Migrate the DB to the latest schema version if needed + /usr/bin/db_migrator.py -o migrate + fi {%- elif docker_container_name == "swss" %} docker exec swss rm -f /ready # remove cruft if [[ "$BOOT_TYPE" == "fast" ]] && [[ -d /host/fast-reboot ]]; then From 2736da97c7da5725a11398f2a2752e56d09ade5b Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 1 May 2019 08:01:44 -0700 Subject: [PATCH 13/88] [sudoers] Add /usr/bin/teamshow to READ_ONLY_CMDS (#2846) --- files/image_config/sudoers/sudoers | 1 + 1 file changed, 1 insertion(+) diff --git a/files/image_config/sudoers/sudoers b/files/image_config/sudoers/sudoers index 9944299830b0..45b943846cb1 100644 --- a/files/image_config/sudoers/sudoers +++ b/files/image_config/sudoers/sudoers @@ -32,6 +32,7 @@ Cmnd_Alias READ_ONLY_CMDS = /sbin/brctl show, \ /usr/bin/psuutil *, \ /usr/bin/sensors, \ /usr/bin/sfputil show *, \ + /usr/bin/teamshow, \ /usr/bin/vtysh -c show *, \ /bin/cat /var/log/syslog*, \ /usr/bin/tail -F /var/log/syslog From 6eca27e5647f5af9adc149ba3858955ca679f803 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 1 May 2019 08:02:38 -0700 Subject: [PATCH 14/88] [services] Restart SwSS service upon unexpected critical process exit (#2845) * [service] Restart SwSS Docker container if orchagent exits unexpectedly * Configure systemd to stop restarting swss if it attempts to restart more than 3 times in 20 minutes * Move supervisor-proc-exit-listener script * [docker-dhcp-relay] Enhance wait_for_intf.sh.j2 to utilize STATEDB * Ensure dependent services stop/start/restart with SwSS * Change 'StartLimitInterval' to 'StartLimitIntervalSec', as Stretch installs systemd 232 (>= v230) * Also update journald.conf options * Remove 'PartOf' option from unit files * Add '$(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT)' to new shared docker-orchagent makefile * Make supervisor-proc-exit-listener script read from 'critical_processes' file inside container * Update critical_processes file for swss container --- dockers/docker-dhcp-relay/wait_for_intf.sh.j2 | 38 +++++++------- dockers/docker-orchagent/Dockerfile.j2 | 2 + dockers/docker-orchagent/critical_processes | 11 ++++ dockers/docker-orchagent/supervisord.conf | 8 ++- files/build_templates/dhcp_relay.service.j2 | 2 +- files/build_templates/radv.service.j2 | 2 +- files/build_templates/snmp.service.j2 | 3 ++ files/build_templates/swss.service.j2 | 4 ++ files/build_templates/teamd.service.j2 | 4 +- files/image_config/systemd/journald.conf | 2 +- files/scripts/supervisor-proc-exit-listener | 45 +++++++++++++++++ rules/docker-dhcp-relay.mk | 2 +- rules/docker-orchagent.mk | 2 +- rules/scripts.mk | 6 ++- .../tests/sample_output/wait_for_intf.sh | 50 +++++++++---------- 15 files changed, 126 insertions(+), 55 deletions(-) create mode 100644 dockers/docker-orchagent/critical_processes create mode 100755 files/scripts/supervisor-proc-exit-listener diff --git a/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 b/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 index 037dc66ead63..23133706cb6c 100644 --- a/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 +++ b/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 @@ -1,42 +1,40 @@ #!/usr/bin/env bash -function wait_until_iface_ready -{ - IFACE=$1 +STATE_DB_IDX="6" - echo "Waiting until interface $IFACE is up..." - - # Wait for the interface to come up (i.e., 'ip link show' returns 0) - until ip link show dev $IFACE up > /dev/null 2>&1; do - sleep 1 - done +PORT_TABLE_PREFIX="PORT_TABLE" +VLAN_TABLE_PREFIX="VLAN_TABLE" +LAG_TABLE_PREFIX="LAG_TABLE" - echo "Interface $IFACE is up" +function wait_until_iface_ready +{ + TABLE_PREFIX=$1 + IFACE=$2 - echo "Waiting until interface $IFACE has an IPv4 address..." + echo "Waiting until interface $IFACE is ready..." - # Wait until the interface gets assigned an IPv4 address + # Wait for the interface to come up + # (i.e., interface is present in STATE_DB and state is "ok") while true; do - IP=$(ip -4 addr show dev $IFACE | grep "inet " | awk '{ print $2 }' | cut -d '/' -f1) - - if [ -n "$IP" ]; then + RESULT=$(redis-cli -n ${STATE_DB_IDX} HGET "${TABLE_PREFIX}|${IFACE}" "state" 2> /dev/null) + if [ x"$RESULT" == x"ok" ]; then break fi sleep 1 done - echo "Interface $IFACE is configured with IP $IP" + echo "Interface ${IFACE} is ready!" } -# Wait for all interfaces to come up and have IPv4 addresses assigned +# Wait for all interfaces to be up and ready {% for (name, prefix) in INTERFACE %} -wait_until_iface_ready {{ name }} +wait_until_iface_ready ${PORT_TABLE_PREFIX} {{ name }} {% endfor %} {% for (name, prefix) in VLAN_INTERFACE %} -wait_until_iface_ready {{ name }} +wait_until_iface_ready ${VLAN_TABLE_PREFIX} {{ name }} {% endfor %} {% for (name, prefix) in PORTCHANNEL_INTERFACE %} -wait_until_iface_ready {{ name }} +wait_until_iface_ready ${LAG_TABLE_PREFIX} {{ name }} {% endfor %} diff --git a/dockers/docker-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2 index d29ea6a8905a..8f480a53287e 100755 --- a/dockers/docker-orchagent/Dockerfile.j2 +++ b/dockers/docker-orchagent/Dockerfile.j2 @@ -41,6 +41,8 @@ COPY ["files/arp_update", "/usr/bin"] COPY ["enable_counters.py", "/usr/bin"] COPY ["start.sh", "orchagent.sh", "swssconfig.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Copy all Jinja2 template files into the templates folder COPY ["*.j2", "/usr/share/sonic/templates/"] diff --git a/dockers/docker-orchagent/critical_processes b/dockers/docker-orchagent/critical_processes new file mode 100644 index 000000000000..c0f441ecc0ea --- /dev/null +++ b/dockers/docker-orchagent/critical_processes @@ -0,0 +1,11 @@ +orchagent +portsyncd +neighsyncd +vlanmgrd +intfmgrd +portmgrd +buffermgrd +vrfmgrd +nbrmgrd +vxlanmgrd +intfsyncd diff --git a/dockers/docker-orchagent/supervisord.conf b/dockers/docker-orchagent/supervisord.conf index 4479a27f2a7b..46b37e77c0e4 100644 --- a/dockers/docker-orchagent/supervisord.conf +++ b/dockers/docker-orchagent/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/files/build_templates/dhcp_relay.service.j2 b/files/build_templates/dhcp_relay.service.j2 index 5a462e53973d..7ec133c87af7 100644 --- a/files/build_templates/dhcp_relay.service.j2 +++ b/files/build_templates/dhcp_relay.service.j2 @@ -11,4 +11,4 @@ ExecStart=/usr/bin/{{ docker_container_name }}.sh wait ExecStop=/usr/bin/{{ docker_container_name }}.sh stop [Install] -WantedBy=multi-user.target teamd.service +WantedBy=multi-user.target swss.service teamd.service diff --git a/files/build_templates/radv.service.j2 b/files/build_templates/radv.service.j2 index 8cda2fdd0afb..4f1c67e661b0 100644 --- a/files/build_templates/radv.service.j2 +++ b/files/build_templates/radv.service.j2 @@ -11,4 +11,4 @@ ExecStart=/usr/bin/{{ docker_container_name }}.sh wait ExecStop=/usr/bin/{{ docker_container_name }}.sh stop [Install] -WantedBy=multi-user.target +WantedBy=multi-user.target swss.service diff --git a/files/build_templates/snmp.service.j2 b/files/build_templates/snmp.service.j2 index 416156d5a891..43f46bd2b9c0 100644 --- a/files/build_templates/snmp.service.j2 +++ b/files/build_templates/snmp.service.j2 @@ -9,3 +9,6 @@ Before=ntp-config.service ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh wait ExecStop=/usr/bin/{{docker_container_name}}.sh stop + +[Install] +WantedBy=multi-user.target swss.service diff --git a/files/build_templates/swss.service.j2 b/files/build_templates/swss.service.j2 index b391f95de52d..048c9c34704b 100644 --- a/files/build_templates/swss.service.j2 +++ b/files/build_templates/swss.service.j2 @@ -9,6 +9,8 @@ Requires=nps-modules-4.9.0-8-2-amd64.service After=database.service updategraph.service After=interfaces-config.service Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 [Service] User=root @@ -16,6 +18,8 @@ Environment=sonic_asic_platform={{ sonic_asic_platform }} ExecStartPre=/usr/local/bin/swss.sh start ExecStart=/usr/local/bin/swss.sh wait ExecStop=/usr/local/bin/swss.sh stop +Restart=always +RestartSec=30 [Install] WantedBy=multi-user.target diff --git a/files/build_templates/teamd.service.j2 b/files/build_templates/teamd.service.j2 index 8034698ecc07..58c858effb36 100644 --- a/files/build_templates/teamd.service.j2 +++ b/files/build_templates/teamd.service.j2 @@ -1,6 +1,6 @@ [Unit] Description=TEAMD container -Requires=updategraph.service +Requires=updategraph.service swss.service After=updategraph.service swss.service Before=ntp-config.service @@ -11,4 +11,4 @@ ExecStart=/usr/bin/{{docker_container_name}}.sh wait ExecStop=/usr/bin/{{docker_container_name}}.sh stop [Install] -WantedBy=multi-user.target +WantedBy=multi-user.target swss.service diff --git a/files/image_config/systemd/journald.conf b/files/image_config/systemd/journald.conf index 0f3d1b5ec25b..214bd099a285 100644 --- a/files/image_config/systemd/journald.conf +++ b/files/image_config/systemd/journald.conf @@ -13,7 +13,7 @@ #Seal=yes #SplitMode=uid #SyncIntervalSec=5m -#RateLimitInterval=30s +#RateLimitIntervalSec=30s #RateLimitBurst=1000 SystemMaxUse=50M #SystemKeepFree= diff --git a/files/scripts/supervisor-proc-exit-listener b/files/scripts/supervisor-proc-exit-listener new file mode 100755 index 000000000000..6bc62fc400c8 --- /dev/null +++ b/files/scripts/supervisor-proc-exit-listener @@ -0,0 +1,45 @@ +#!/usr/bin/env python + +import os +import signal +import sys +import syslog + +from supervisor import childutils + +# Contents of file should be the names of critical processes (as defined in +# supervisor.conf file), one per line +CRITICAL_PROCESSES_FILE = '/etc/supervisor/critical_processes' + +def main(): + # Read the list of critical processes from a file + with open(CRITICAL_PROCESSES_FILE, 'r') as f: + critical_processes = [line.rstrip('\n') for line in f] + + while True: + # Transition from ACKNOWLEDGED to READY + childutils.listener.ready() + + line = sys.stdin.readline() + headers = childutils.get_headers(line) + payload = sys.stdin.read(int(headers['len'])) + + # Transition from READY to ACKNOWLEDGED + childutils.listener.ok() + + # We only care about PROCESS_STATE_EXITED events + if headers['eventname'] == 'PROCESS_STATE_EXITED': + payload_headers, payload_data = childutils.eventdata(payload + '\n') + + expected = int(payload_headers['expected']) + processname = payload_headers['processname'] + + # If a critical process exited unexpectedly, terminate supervisor + if expected == 0 and processname in critical_processes: + MSG_FORMAT_STR = "Process {} exited unxepectedly. Terminating supervisor..." + msg = MSG_FORMAT_STR.format(payload_headers['processname']) + syslog.syslog(syslog.LOG_INFO, msg) + os.kill(os.getppid(), signal.SIGTERM) + +if __name__ == "__main__": + main() diff --git a/rules/docker-dhcp-relay.mk b/rules/docker-dhcp-relay.mk index f1f19d974a8e..d15bdbf84dc4 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_COMMON) $(ISC_DHCP_RELAY) +$(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_COMMON) $(ISC_DHCP_RELAY) $(REDIS_TOOLS) $(DOCKER_DHCP_RELAY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) $(DOCKER_DHCP_RELAY)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) diff --git a/rules/docker-orchagent.mk b/rules/docker-orchagent.mk index ea637308179a..20536adc2520 100644 --- a/rules/docker-orchagent.mk +++ b/rules/docker-orchagent.mk @@ -34,4 +34,4 @@ $(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)_FILES += $(ARP_UPDATE_SCRIPT) +$(DOCKER_ORCHAGENT)_FILES += $(ARP_UPDATE_SCRIPT) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/scripts.mk b/rules/scripts.mk index 6010b10b832b..8c6d0324fc0e 100644 --- a/rules/scripts.mk +++ b/rules/scripts.mk @@ -11,9 +11,13 @@ $(BUFFERS_CONFIG_TEMPLATE)_PATH = files/build_templates QOS_CONFIG_TEMPLATE = qos_config.j2 $(QOS_CONFIG_TEMPLATE)_PATH = files/build_templates +SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT = supervisor-proc-exit-listener +$(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT)_PATH = files/scripts + SONIC_COPY_FILES += $(CONFIGDB_LOAD_SCRIPT) \ $(ARP_UPDATE_SCRIPT) \ $(BUFFERS_CONFIG_TEMPLATE) \ - $(QOS_CONFIG_TEMPLATE) + $(QOS_CONFIG_TEMPLATE) \ + $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh b/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh index 0f06235eb0dc..383f7cb389e9 100644 --- a/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh +++ b/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh @@ -1,43 +1,41 @@ #!/usr/bin/env bash -function wait_until_iface_ready -{ - IFACE=$1 +STATE_DB_IDX="6" - echo "Waiting until interface $IFACE is up..." - - # Wait for the interface to come up (i.e., 'ip link show' returns 0) - until ip link show dev $IFACE up > /dev/null 2>&1; do - sleep 1 - done +PORT_TABLE_PREFIX="PORT_TABLE" +VLAN_TABLE_PREFIX="VLAN_TABLE" +LAG_TABLE_PREFIX="LAG_TABLE" - echo "Interface $IFACE is up" +function wait_until_iface_ready +{ + TABLE_PREFIX=$1 + IFACE=$2 - echo "Waiting until interface $IFACE has an IPv4 address..." + echo "Waiting until interface $IFACE is ready..." - # Wait until the interface gets assigned an IPv4 address + # Wait for the interface to come up + # (i.e., interface is present in STATE_DB and state is "ok") while true; do - IP=$(ip -4 addr show dev $IFACE | grep "inet " | awk '{ print $2 }' | cut -d '/' -f1) - - if [ -n "$IP" ]; then + RESULT=$(redis-cli -n ${STATE_DB_IDX} HGET "${TABLE_PREFIX}|${IFACE}" "state" 2> /dev/null) + if [ x"$RESULT" == x"ok" ]; then break fi sleep 1 done - echo "Interface $IFACE is configured with IP $IP" + echo "Interface ${IFACE} is ready!" } -# Wait for all interfaces to come up and have IPv4 addresses assigned -wait_until_iface_ready Vlan1000 -wait_until_iface_ready PortChannel01 -wait_until_iface_ready PortChannel01 -wait_until_iface_ready PortChannel02 -wait_until_iface_ready PortChannel02 -wait_until_iface_ready PortChannel03 -wait_until_iface_ready PortChannel03 -wait_until_iface_ready PortChannel04 -wait_until_iface_ready PortChannel04 +# Wait for all interfaces to be up and ready +wait_until_iface_ready ${VLAN_TABLE_PREFIX} Vlan1000 +wait_until_iface_ready ${LAG_TABLE_PREFIX} PortChannel01 +wait_until_iface_ready ${LAG_TABLE_PREFIX} PortChannel01 +wait_until_iface_ready ${LAG_TABLE_PREFIX} PortChannel02 +wait_until_iface_ready ${LAG_TABLE_PREFIX} PortChannel02 +wait_until_iface_ready ${LAG_TABLE_PREFIX} PortChannel03 +wait_until_iface_ready ${LAG_TABLE_PREFIX} PortChannel03 +wait_until_iface_ready ${LAG_TABLE_PREFIX} PortChannel04 +wait_until_iface_ready ${LAG_TABLE_PREFIX} PortChannel04 From 386c041c2b5120e641f8c400eab99943acc027f6 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 1 May 2019 08:04:23 -0700 Subject: [PATCH 15/88] [sonic-utilites] Update submodule (#2847) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index b531934c6212..8d974001a9dc 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit b531934c621287f29a7f0dace6cb30ad93ada008 +Subproject commit 8d974001a9dcf51f38091011bc1fecd34ca895ab From 0b745ed94681c56a185070993945290f135c7101 Mon Sep 17 00:00:00 2001 From: Shuotian Cheng Date: Wed, 1 May 2019 12:04:33 -0700 Subject: [PATCH 16/88] [minigraph]: Add mirror type v6 condition (#2836) Signed-off-by: Shu0T1an ChenG --- src/sonic-config-engine/minigraph.py | 17 ++++++++++++----- src/sonic-config-engine/tests/test_cfggen.py | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index ac0f4922f94f..d4be412ed53f 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -228,6 +228,7 @@ def parse_dpg(dpg, hname): aclattach = aclintf.find(str(QName(ns, "AttachTo"))).text.split(';') acl_intfs = [] is_mirror = False + is_mirror_v6 = False # TODO: Ensure that acl_intfs will only ever contain front-panel interfaces (e.g., # maybe we should explicity ignore management and loopback interfaces?) because we @@ -247,7 +248,10 @@ def parse_dpg(dpg, hname): if port_alias_map[member] in intfs_inpc: print >> sys.stderr, "Warning: ACL " + aclname + " is attached to a LAG member interface " + port_alias_map[member] + ", instead of LAG interface" elif member.lower().startswith('erspan'): - is_mirror = True; + if member.lower().startswith('erspanv6'): + is_mirror_v6 = True + else: + is_mirror = True; # Erspan session will be attached to all front panel ports, # if panel ports is a member port of LAG, should add the LAG # to acl table instead of the panel ports @@ -258,10 +262,13 @@ def parse_dpg(dpg, hname): break; if acl_intfs: acls[aclname] = {'policy_desc': aclname, - 'ports': acl_intfs, - 'type': 'MIRROR' if is_mirror else 'L3'} - elif is_mirror: - acls[aclname] = {'policy_desc': aclname, 'type': 'MIRROR'} + 'ports': acl_intfs} + if is_mirror: + acls[aclname]['type'] = 'MIRROR' + elif is_mirror_v6: + acls[aclname]['type'] = 'MIRRORV6' + else: + acls[aclname]['type'] = 'L3' else: # This ACL has no interfaces to attach to -- consider this a control plane ACL try: diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 4833530fb466..a841f4d19c23 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -87,7 +87,7 @@ def test_minigraph_acl(self): "'ROUTER_PROTECT': {'services': ['SSH', 'SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'ROUTER_PROTECT'}, " "'SNMP_ACL': {'services': ['SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL'}, " "'SSH_ACL': {'services': ['SSH'], 'type': 'CTRLPLANE', 'policy_desc': 'SSH_ACL'}, " - "'EVERFLOWV6': {'type': 'MIRROR', 'policy_desc': 'EVERFLOWV6', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet24', 'Ethernet40', 'Ethernet20', 'Ethernet44', 'Ethernet48', 'Ethernet28', 'Ethernet96', 'Ethernet92', 'Ethernet76', 'Ethernet72', 'Ethernet52', 'Ethernet80', 'Ethernet56', 'Ethernet32', 'Ethernet16', 'Ethernet36', 'Ethernet12', 'Ethernet60', 'Ethernet8', 'Ethernet4', 'Ethernet0', 'Ethernet64', 'Ethernet68', 'Ethernet84', 'Ethernet88', 'Ethernet108', 'Ethernet104', 'Ethernet100']}}") + "'EVERFLOWV6': {'type': 'MIRRORV6', 'policy_desc': 'EVERFLOWV6', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet24', 'Ethernet40', 'Ethernet20', 'Ethernet44', 'Ethernet48', 'Ethernet28', 'Ethernet96', 'Ethernet92', 'Ethernet76', 'Ethernet72', 'Ethernet52', 'Ethernet80', 'Ethernet56', 'Ethernet32', 'Ethernet16', 'Ethernet36', 'Ethernet12', 'Ethernet60', 'Ethernet8', 'Ethernet4', 'Ethernet0', 'Ethernet64', 'Ethernet68', 'Ethernet84', 'Ethernet88', 'Ethernet108', 'Ethernet104', 'Ethernet100']}}") def test_minigraph_everflow(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v MIRROR_SESSION' From beb96dc2033a2512f0a1d5387a26753fdb0c14e7 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 1 May 2019 17:09:23 -0700 Subject: [PATCH 17/88] [docker-swss]: Remove intfsyncd from list of SwSS critical processes as it no longer exists (#2850) --- dockers/docker-orchagent/critical_processes | 1 - 1 file changed, 1 deletion(-) diff --git a/dockers/docker-orchagent/critical_processes b/dockers/docker-orchagent/critical_processes index c0f441ecc0ea..7fd8a516520c 100644 --- a/dockers/docker-orchagent/critical_processes +++ b/dockers/docker-orchagent/critical_processes @@ -8,4 +8,3 @@ buffermgrd vrfmgrd nbrmgrd vxlanmgrd -intfsyncd From 3bd15a07e529d2ecc5a48aef1fef289806cd6c4e Mon Sep 17 00:00:00 2001 From: sridhar-ravindran <45350577+sridhar-ravindran@users.noreply.github.com> Date: Thu, 2 May 2019 20:35:33 +0530 Subject: [PATCH 18/88] Enable Debugs in BCM Kernel-bde and Knet Modules (#2786) * Enable Debugs in BCM Kernel-bde and Knet Modules * Added Explanation for debugs enabled --- .../broadcom/saibcm-modules/debian/opennsl-modules.init | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.init b/platform/broadcom/saibcm-modules/debian/opennsl-modules.init index 0ef75c86c68b..1aaa91bb2d82 100755 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.init +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.init @@ -25,11 +25,16 @@ function create_devices() mknod /dev/linux-kernel-bde c 127 0 } +# linux-kernel-bde debug=4 ==> Verbose level debug +# dma_debug=1 ==> Enable DMA debug +# linux-bcm-knet debug=0x5020 ==> Enable KNET Warning(0x1000), +# Events(0x20) and Instance(0x4000) +# level logs function load_kernel_modules() { - modprobe linux-kernel-bde dmasize=32M maxpayload=128 + modprobe linux-kernel-bde dmasize=32M maxpayload=128 debug=4 dma_debug=1 modprobe linux-user-bde - modprobe linux-bcm-knet use_rx_skb=1 rx_buffer_size=9238 + modprobe linux-bcm-knet use_rx_skb=1 rx_buffer_size=9238 debug=0x5020 modprobe linux-knet-cb } From 1c7959988272fdf444f2d20efaf4715d7637b46c Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Fri, 3 May 2019 10:17:04 +0300 Subject: [PATCH 19/88] [submodule]: Updated SWSS submodule. (#2856) Signed-off-by: Nazarii Hnydyn --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index d612d5e50972..ea4cba6ca6c5 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit d612d5e50972e7f7574aaa5f24b5994e1194daaa +Subproject commit ea4cba6ca6c5da770edcf104ee8f826ca5f86466 From 2ceceac883fe08183f8e165cb9f85f4ce98c8b5d Mon Sep 17 00:00:00 2001 From: Volodymyr Samotiy Date: Fri, 3 May 2019 09:58:37 +0000 Subject: [PATCH 20/88] [mellanox]: Update SAI, SDK and FW * SAI: v1.14.0 (API v1.4.1) * SDK: v4.3.1104 * FW: v13.2000.1140/v29.2000.1140 Signed-off-by: Volodymyr Samotiy --- platform/mellanox/fw.mk | 4 ++-- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- platform/mellanox/sdk.mk | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 20d84aedcb49..4d1e8edd9d5f 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -2,12 +2,12 @@ MLNX_FW_BASE_URL = $(MLNX_SDK_BASE_URL) -MLNX_SPC_FW_VERSION = 13.1910.0920 +MLNX_SPC_FW_VERSION = 13.2000.1140 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) SONIC_ONLINE_FILES += $(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.1961.0006 +MLNX_SPC2_FW_VERSION = 29.2000.1140 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) SONIC_ONLINE_FILES += $(MLNX_SPC2_FW_FILE) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 44cf272957cb..eba727499a59 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.13.7-master +MLNX_SAI_VERSION = SAIRel1.14.0-master export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index 40eea3c069ef..ed2f0d276577 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit 40eea3c069efa6defd2ed3b4990543b15ce85ee5 +Subproject commit ed2f0d2765773bde8ee2d3ae552c96edd1d4859e diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index d818a724cc83..1d209fd5a3db 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ -MLNX_SDK_BASE_URL = https://github.com/Mellanox/SAI-Implementation/raw/3c8bb2e4f1292484bdf097ae90ec0a2ef9b41b2b/sdk -MLNX_SDK_VERSION = 4.3.0136 +MLNX_SDK_BASE_URL = https://github.com/Mellanox/SAI-Implementation/raw/e7da154ddf8447c04b852195f43c83802c6934c9/sdk +MLNX_SDK_VERSION = 4.3.1104 MLNX_SDK_ISSU_VERSION = 100 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From 76adaa80f8a030e4845b9a7ea1b4455807d9d8c5 Mon Sep 17 00:00:00 2001 From: Shu0T1an ChenG Date: Mon, 15 Apr 2019 18:05:51 -0700 Subject: [PATCH 21/88] [broadcom]: update saibcm-modules to sdk 6.5.14 --- .../broadcom/saibcm-modules/include/ibde.h | 22 ++ .../broadcom/saibcm-modules/include/kcom.h | 14 +- .../saibcm-modules/include/soc/devids.h | 63 ++++ .../saibcm-modules/make/Makefile.linux-gto | 8 +- .../bde/linux/kernel/linux-kernel-bde.c | 278 +++++++++++++----- .../bde/linux/user/kernel/linux-user-bde.c | 190 +++++++++++- .../bde/linux/user/kernel/linux-user-bde.h | 6 +- .../systems/bde/shared/shbde_iproc.c | 37 ++- .../linux/kernel/modules/bcm-knet/bcm-knet.c | 185 ++++++++---- .../linux/kernel/modules/include/lkm.h | 3 + 10 files changed, 635 insertions(+), 171 deletions(-) diff --git a/platform/broadcom/saibcm-modules/include/ibde.h b/platform/broadcom/saibcm-modules/include/ibde.h index bfc05e330e03..9c8956f5e3e0 100644 --- a/platform/broadcom/saibcm-modules/include/ibde.h +++ b/platform/broadcom/saibcm-modules/include/ibde.h @@ -148,6 +148,28 @@ 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. + */ + /* Read from the internal device Address space using I2C */ + int (*i2c_device_read)( + int dev, /* The device ID to access */ + uint32 addr, /* The address to access in the internal device address space */ + uint32 *value);/* the value to be read. */ + /* Write to the internal device Address space using I2C */ + int (*i2c_device_write)( + int dev, /* The device ID to access */ + uint32 addr, /* The address to access in the internal device address space */ + uint32 value); /* the value to be written. */ + } ibde_t; diff --git a/platform/broadcom/saibcm-modules/include/kcom.h b/platform/broadcom/saibcm-modules/include/kcom.h index f66e382e4d8f..76f3e47a8de5 100644 --- a/platform/broadcom/saibcm-modules/include/kcom.h +++ b/platform/broadcom/saibcm-modules/include/kcom.h @@ -46,6 +46,7 @@ #define KCOM_M_HW_INIT 4 /* H/W initialized */ #define KCOM_M_ETH_HW_CONFIG 5 /* ETH HW config*/ #define KCOM_M_DETACH 6 /* Detach kernel module */ +#define KCOM_M_REPROBE 7 /* Reprobe device */ #define KCOM_M_NETIF_CREATE 11 /* Create network interface */ #define KCOM_M_NETIF_DESTROY 12 /* Destroy network interface */ #define KCOM_M_NETIF_LIST 13 /* Get list of network interface IDs */ @@ -59,7 +60,7 @@ #define KCOM_M_DBGPKT_GET 42 /* Get debug packet function info */ #define KCOM_M_WB_CLEANUP 51 /* Clean up for warmbooting */ -#define KCOM_VERSION 9 /* Protocol version */ +#define KCOM_VERSION 10 /* Protocol version */ /* * Message status codes @@ -305,7 +306,7 @@ typedef struct kcom_eth_hw_config_s { uint8 chan; uint32 flags; uint32 value; - } kcom_eth_hw_config_t; +} kcom_eth_hw_config_t; /* * Message types @@ -379,6 +380,14 @@ typedef struct kcom_msg_detach_s { uint32 flags; } kcom_msg_detach_t; +/* + * Reprobe switch device. + */ +typedef struct kcom_msg_reprobe_s { + kcom_msg_hdr_t hdr; + uint32 flags; +} kcom_msg_reprobe_t; + /* * Enable/Disable debugging packet function. */ @@ -498,6 +507,7 @@ typedef union kcom_msg_s { kcom_msg_hw_init_t hw_init; kcom_msg_eth_hw_config_t eth_hw_config; kcom_msg_detach_t detach; + kcom_msg_reprobe_t reprobe; kcom_msg_netif_create_t netif_create; kcom_msg_netif_destroy_t netif_destroy; kcom_msg_netif_list_t netif_list; diff --git a/platform/broadcom/saibcm-modules/include/soc/devids.h b/platform/broadcom/saibcm-modules/include/soc/devids.h index c1b350f217a5..cb072a78cbd7 100644 --- a/platform/broadcom/saibcm-modules/include/soc/devids.h +++ b/platform/broadcom/saibcm-modules/include/soc/devids.h @@ -1238,6 +1238,15 @@ #define BCM56980_DEVICE_ID 0xb980 #define BCM56980_A0_REV_ID 1 +#define BCM56980_B0_REV_ID 0x11 +#define BCM56981_DEVICE_ID 0xb981 +#define BCM56981_A0_REV_ID 1 +#define BCM56982_DEVICE_ID 0xb982 +#define BCM56982_A0_REV_ID 1 +#define BCM56983_DEVICE_ID 0xb983 +#define BCM56983_A0_REV_ID 1 +#define BCM56984_DEVICE_ID 0xb984 +#define BCM56984_A0_REV_ID 1 #define BCM56968_DEVICE_ID 0xb968 #define BCM56968_A0_REV_ID 1 @@ -1289,15 +1298,20 @@ #define BCM56670_DEVICE_ID 0xb670 #define BCM56670_A0_REV_ID 1 +#define BCM56670_B0_REV_ID 0x11 #define BCM56671_DEVICE_ID 0xb671 #define BCM56671_A0_REV_ID 1 +#define BCM56671_B0_REV_ID 0x11 #define BCM56672_DEVICE_ID 0xb672 #define BCM56672_A0_REV_ID 1 +#define BCM56672_B0_REV_ID 0x11 #define BCM56675_DEVICE_ID 0xb675 #define BCM56675_A0_REV_ID 1 +#define BCM56675_B0_REV_ID 0x11 + #define BCM56565_DEVICE_ID 0xb565 #define BCM56565_A0_REV_ID 1 @@ -1317,12 +1331,19 @@ #define BCM56760_DEVICE_ID 0xb760 #define BCM56760_A0_REV_ID 1 +#define BCM56760_A1_REV_ID 2 #define BCM56760_B0_REV_ID 0x11 #define BCM56761_DEVICE_ID 0xb761 #define BCM56761_A0_REV_ID 1 #define BCM56761_B0_REV_ID 0x11 +#define BCM56761_DEVICE_ID 0xb761 +#define BCM56761_A0_REV_ID 1 +#define BCM56761_A1_REV_ID 2 +#define BCM56761_B0_REV_ID 0x11 +#define BCM56761_B1_REV_ID 0x12 + #define BCM56762_DEVICE_ID 0xb762 #define BCM56762_A0_REV_ID 1 #define BCM56762_B0_REV_ID 0x11 @@ -1347,6 +1368,11 @@ #define BCM56068_A0_REV_ID 1 #define BCM56068_B0_REV_ID 0x11 +#define BCM56068_DEVICE_ID 0xb068 +#define BCM56068_A0_REV_ID 1 +#define BCM56068_B0_REV_ID 0x11 +#define BCM56068_B1_REV_ID 0x12 + #define BCM56069_DEVICE_ID 0xb069 #define BCM56069_A0_REV_ID 1 #define BCM56069_B0_REV_ID 0x11 @@ -1400,6 +1426,42 @@ #define BCM56873_DEVICE_ID 0xb873 #define BCM56873_A0_REV_ID 1 +#define BCM56370_DEVICE_ID 0xb370 +#define BCM56370_A0_REV_ID 1 + +#define BCM56371_DEVICE_ID 0xb371 +#define BCM56371_A0_REV_ID 1 + +#define BCM56372_DEVICE_ID 0xb372 +#define BCM56372_A0_REV_ID 1 + +#define BCM56374_DEVICE_ID 0xb374 +#define BCM56374_A0_REV_ID 1 + +#define BCM56375_DEVICE_ID 0xb375 +#define BCM56375_A0_REV_ID 1 + +#define BCM56376_DEVICE_ID 0xb376 +#define BCM56376_A0_REV_ID 1 + +#define BCM56377_DEVICE_ID 0xb377 +#define BCM56377_A0_REV_ID 1 + +#define BCM56577_DEVICE_ID 0xb577 +#define BCM56577_A0_REV_ID 1 + +#define BCM56578_DEVICE_ID 0xb578 +#define BCM56578_A0_REV_ID 1 + +#define BCM56579_DEVICE_ID 0xb579 +#define BCM56579_A0_REV_ID 1 + +#define BCM56770_DEVICE_ID 0xb770 +#define BCM56770_A0_REV_ID 1 + +#define BCM56771_DEVICE_ID 0xb771 +#define BCM56771_A0_REV_ID 1 + #define BCM53540_DEVICE_ID 0x8540 #define BCM53540_A0_REV_ID 1 #define BCM53547_DEVICE_ID 0x8547 @@ -1718,6 +1780,7 @@ #define DNXC_B0_REV_ID 0x0011 #define BCM88790_DEVICE_ID 0x8790 #define BCM88790_A0_REV_ID DNXC_A0_REV_ID +#define BCM88790_B0_REV_ID DNXC_B0_REV_ID #define BCM88791_DEVICE_ID 0x8791 #define BCM88792_DEVICE_ID 0x8792 #define BCM88793_DEVICE_ID 0x8793 diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-gto b/platform/broadcom/saibcm-modules/make/Makefile.linux-gto index cd5e8fbca195..947c20e74f93 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-gto +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-gto @@ -86,15 +86,19 @@ endif endif ifdef DPP_CHIPS -CFLAGS += -DDUNE_BCM -D__DUNE_GTO_BCM_CPU__ -D__DUNE_LINUX_BCM_CPU_PCIE__ -D__DUNE_LINUX_BCM_CPU_PCP_DMA__ +CFLAGS += -DDUNE_BCM -D__DUNE_LINUX_BCM_CPU_PCP_DMA__ CFGFLAGS += -DSOC_CM_FUNCTION endif ifdef DFE_CHIPS -CFLAGS += -DDUNE_BCM -D__DUNE_GTO_BCM_CPU__ -D__DUNE_LINUX_BCM_CPU_PCIE__ +CFLAGS += -DDUNE_BCM CFGFLAGS += -DSOC_CM_FUNCTION endif +ifdef SAND_CHIPS +CFLAGS += -D__DUNE_GTO_BCM_CPU__ -D__DUNE_LINUX_BCM_CPU_PCIE__ +endif + ifdef SHADOW_PLX CFLAGS += -DBCM_PLX9656_LOCAL_BUS -DBDE_LINUX_NON_INTERRUPTIBLE -DSHADOW_SVK endif 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 e26d35332cc8..1a04b2b52e9b 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 @@ -94,6 +94,8 @@ LKM_MOD_PARAM(nodevices, "i", int, 0); MODULE_PARM_DESC(nodevices, "Ignore all recognized devices (default no)"); +int msixcnt = 1; + /* * This usually is defined at /usr/include/linux/pci_ids.h * But this ID is newer. @@ -366,6 +368,12 @@ static int robo_switch = 0; #define VALID_DEVICE(_n) ((_n >= 0) && (_n < _ndevices)) +#if defined(IPROC_CMICD) && defined(CONFIG_OF) +#define ICFG_CHIP_ID_REG 0x10236000 +#define IHOST_CMICX_MAX_INTRS 128 +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__)) static void *cpu_address = NULL; @@ -696,9 +704,9 @@ iproc_cmicd_get_irqres(ibde_dev_t bde_dev, struct resource *res_irq) #include #include -extern void iproc_platform_driver_register(struct platform_driver *drv); +extern int iproc_platform_driver_register(struct platform_driver *drv); extern void iproc_platform_driver_unregister(struct platform_driver *drv); -extern void iproc_platform_device_register(struct platform_device *drv); +extern int iproc_platform_device_register(struct platform_device *drv); extern void iproc_platform_device_unregister(struct platform_device *drv); extern struct resource * @@ -711,13 +719,14 @@ iproc_platform_get_resource(struct platform_device *dev, unsigned int type, #define IPROC_CMICD_INT 194 #define IPROC_CMICD_COMPATIBLE "brcm,iproc-cmicd" +#define IPROC_CMICX_COMPATIBLE "brcm,iproc-cmicx" static int iproc_cmicd_probe(struct platform_device *pldev) { bde_ctrl_t *ctrl; uint32 size, dev_rev_id; - struct resource *memres, *irqres; + struct resource *memres, *irqres; #ifdef CONFIG_OF if (debug >= 1) { gprintk("iproc_cmicd_probe %s\n", pldev->dev.of_node ? "with device node":""); @@ -725,7 +734,7 @@ iproc_cmicd_probe(struct platform_device *pldev) #endif memres = iproc_platform_get_resource(pldev, IORESOURCE_MEM, 0); if (memres == NULL) { - gprintk("Unable to retrieve iProc CMIC resources"); + gprintk("Unable to retrieve iProc CMIC resources"); return -1; } size = memres->end - memres->start + 1; @@ -739,32 +748,62 @@ iproc_cmicd_probe(struct platform_device *pldev) /* Map CMIC block in the AXI memory space into CPU address space */ ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(memres->start, size); if (!ctrl->bde_dev.base_address) { - gprintk("Error mapping iProc CMIC registers"); + gprintk("Error mapping iProc CMIC registers"); return -1; } ctrl->phys_address = memres->start; - /* Read switch device ID from CMIC */ - dev_rev_id = *((uint32_t*)(ctrl->bde_dev.base_address + 0x10224)); +#ifdef CONFIG_OF + if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { + uint32 *icfg_chip_id; + icfg_chip_id = (uint32 *)IOREMAP(ICFG_CHIP_ID_REG, 2 * sizeof(uint32)); + if (icfg_chip_id == NULL) { + gprintk("Error mapping ICFG_CHIP_ID_REG\n"); + return -1; + } + ctrl->bde_dev.device = readl(icfg_chip_id) & 0xffff; + ctrl->bde_dev.rev = readl(icfg_chip_id+1) & 0xff; + iounmap(icfg_chip_id); + } else +#endif + { + /* Read switch device ID from CMIC */ + dev_rev_id = *((uint32 *)(ctrl->bde_dev.base_address + 0x10224)); #if defined(BCM_CMICM_SUPPORT) && defined(BE_HOST) - ctrl->bde_dev.device = ( (((dev_rev_id >> 16) & 0xff) << 8) | - ((dev_rev_id >> 24) & 0xff)); - ctrl->bde_dev.rev = (dev_rev_id >> 8) & 0xff ; + ctrl->bde_dev.device = ( (((dev_rev_id >> 16) & 0xff) << 8) | + ((dev_rev_id >> 24) & 0xff)); + ctrl->bde_dev.rev = (dev_rev_id >> 8) & 0xff ; #else - ctrl->bde_dev.device = dev_rev_id & 0xffff; - ctrl->bde_dev.rev = (dev_rev_id >> 16) & 0xff; + ctrl->bde_dev.device = dev_rev_id & 0xffff; + ctrl->bde_dev.rev = (dev_rev_id >> 16) & 0xff; #endif + } #ifdef CONFIG_OF if (!pldev->dev.of_node) #endif { /* Assign locally if not available from device node */ - iproc_cmicd_get_irqres(ctrl->bde_dev, &pldev->resource[0]); + iproc_cmicd_get_irqres(ctrl->bde_dev, &pldev->resource[0]); } - irqres = iproc_platform_get_resource(pldev, IORESOURCE_IRQ, 0); - ctrl->iLine = irqres->start; +#ifdef CONFIG_OF + if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { + int i; + for (i = 0; i < IHOST_CMICX_MAX_INTRS; i++) { + irqres = iproc_platform_get_resource(pldev, IORESOURCE_IRQ, i); + iproc_cmicx_irqs[i] = irqres->start; + if (debug >= 1) { + gprintk("iproc_cmicx_irqs[%d] = %d\n", i, iproc_cmicx_irqs[i]); + } + } + ctrl->iLine = iproc_cmicx_irqs[0]; + } else +#endif + { + irqres = iproc_platform_get_resource(pldev, IORESOURCE_IRQ, 0); + ctrl->iLine = irqres->start; + } ctrl->isr = NULL; ctrl ->isr_data = NULL; @@ -785,14 +824,15 @@ iproc_cmicd_remove(struct platform_device *pldev) } #ifdef CONFIG_OF static const struct of_device_id iproc_cmicd_of_match[] = { - { .compatible = "brcm,iproc-cmicd" }, + { .compatible = IPROC_CMICD_COMPATIBLE }, + { .compatible = IPROC_CMICX_COMPATIBLE }, {}, }; MODULE_DEVICE_TABLE(of, iproc_cmicd_of_match); #endif static char iproc_cmicd_string[] = "bcmiproc-cmicd"; -static struct platform_driver iproc_cmicd_driver = +static struct platform_driver iproc_cmicd_driver = { .probe = iproc_cmicd_probe, .remove = iproc_cmicd_remove, @@ -995,10 +1035,10 @@ iproc_cmicd_get_memregion(struct resource *res_mem) iounmap(erom_base); if (debug >= 1) { - gprintk("CMICD info by %s: cmicd_mem.start=%x, cmicd_mem.end=%x\n", + gprintk("CMICD info by %s: cmicd_mem.start=%lx, cmicd_mem.end=%lx\n", found_cmicd_dev ? "EROM" : "Default", - iproc_cmicd_resources[IPROC_CMICD_RES_MEM].start, - iproc_cmicd_resources[IPROC_CMICD_RES_MEM].end); + (unsigned long)iproc_cmicd_resources[IPROC_CMICD_RES_MEM].start, + (unsigned long)iproc_cmicd_resources[IPROC_CMICD_RES_MEM].end); } } #endif /* IPROC_CMICD */ @@ -1382,6 +1422,7 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM56672_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56675_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56568_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56670_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56760_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56761_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56762_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1546,8 +1587,24 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM56832_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56836_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56870_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM56980_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56370_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56371_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56372_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56374_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56375_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56376_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56377_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56577_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56578_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56579_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56873_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56770_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56771_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56980_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56981_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56982_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56983_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56984_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53540_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53547_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53548_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1981,6 +2038,7 @@ _pci_msix_table_size(struct pci_dev *dev) if (nr_entries < 0) { nr_entries = 0; } + pci_disable_msix(dev); kfree(entries); } } @@ -1996,45 +2054,56 @@ _pci_msix_table_size(struct pci_dev *dev) static int _msi_connect(bde_ctrl_t *ctrl) { - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,84)) int ret; if (ctrl->use_msi == PCI_USE_INT_MSIX) { int i; - ret = _pci_msix_table_size(ctrl->pci_device); + ret = _pci_msix_table_size(ctrl->pci_device); if (ret == 0) { /* MSI-X failed */ gprintk("MSI-X not supported.\n"); goto er_intx; } - ctrl->entries = kcalloc(ret, sizeof(struct msix_entry)*ret, GFP_KERNEL); + ctrl->entries = kcalloc(ret, sizeof(struct msix_entry), GFP_KERNEL); if (!ctrl->entries) { goto er_intx; } - /* We need only that much interrupt vecotrs */ - ctrl->msix_cnt = ret/4; + /* Only one vector is mapped by default */ + /* May be more in future, can be controlled using module param */ + ctrl->msix_cnt = msixcnt; if (unlikely(debug > 1)) gprintk("MSIX Table size = %d\n", ctrl->msix_cnt); for (i = 0; i < ctrl->msix_cnt; i++) ctrl->entries[i].entry = i; - +#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) { /* 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; } else { - gprintk("Enabled MSI-X interrupts = %d\n", ctrl->msix_cnt); + gprintk("Enabled MSI-X interrupts = %d\n", ctrl->msix_cnt); + return 0; } } #endif @@ -2049,7 +2118,7 @@ _msi_connect(bde_ctrl_t *ctrl) } } else { /* failed */ - gprintk("Not MSI/MSIC interrupt.\n"); + gprintk("Not MSI/MSIX interrupt.\n"); goto er_intx; } return 0; @@ -2068,9 +2137,12 @@ _msi_disconnect(bde_ctrl_t *ctrl) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,84)) if (ctrl->use_msi == PCI_USE_INT_MSIX) { - pci_disable_msix(ctrl->pci_device); - kfree(ctrl->entries); - ctrl->msix_cnt = 0; + if (ctrl->msix_cnt) { + pci_disable_msix(ctrl->pci_device); + kfree(ctrl->entries); + ctrl->entries = NULL; + ctrl->msix_cnt = 0; + } } #endif if (ctrl->use_msi == PCI_USE_INT_MSI) { @@ -2085,16 +2157,30 @@ _msi_disconnect(bde_ctrl_t *ctrl) static void -config_pci_intr_type(bde_ctrl_t *ctrl) +config_pci_intr_type(struct pci_dev *dev, bde_ctrl_t *ctrl, int iproc) { - #ifdef CONFIG_PCI_MSI int ret; + shbde_iproc_config_t icfg; + /* Each device follows global policy by default */ ctrl->use_msi = use_msi; + if (unlikely(debug > 1)) gprintk("%s: msi = %d\n", __func__, ctrl->use_msi); + /* Check IPROC version for MSIX support */ + if (iproc && ctrl->bde_dev.base_address1 && + (ctrl->use_msi == PCI_USE_INT_MSIX)) { + if (shbde_pci_iproc_version_get(&ctrl->shbde, dev, &icfg.iproc_ver, + &icfg.cmic_ver, &icfg.cmic_rev)) { + if (icfg.iproc_ver < 0xe) { + gprintk("%s: MSI-X not supported, using MSI.\n", __func__); + ctrl->use_msi = PCI_USE_INT_MSI; + } + } + } + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,84)) if (ctrl->use_msi == PCI_USE_INT_MSIX) { /* check for support MSIX vector */ @@ -2108,10 +2194,10 @@ config_pci_intr_type(bde_ctrl_t *ctrl) if (ctrl->use_msi == PCI_USE_INT_MSI) { /* check for support MSI vector */ - ret = pci_enable_msi(ctrl->pci_device); + ret = pci_enable_msi(ctrl->pci_device); if (ret < 0) { ctrl->use_msi = PCI_USE_INT_INTX; - gprintk("%s: Failed to enable MSI\n", __func__); + gprintk("%s: Failed to enable MSI, using INTx.\n", __func__); } else { pci_disable_msi(ctrl->pci_device); } @@ -2268,7 +2354,7 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) return 0; } if (_switch_ndevices >= LINUX_BDE_MAX_SWITCH_DEVICES) { - return 0;; + return 0; } if (rescan) { @@ -2550,22 +2636,8 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) } } - /* Each device follows global policy by default */ - ctrl->use_msi = use_msi; - - /* Check is MSI is properly supported in kernel for this device */ - if (ctrl->use_msi) { - if (pci_enable_msi(ctrl->pci_device) == 0) { - /* Release MSI resources until interrupt_connect is called */ - pci_disable_msi(ctrl->pci_device); - } else { - gprintk("Could not enable MSI interrupts\n"); - ctrl->use_msi = 0; - } - } - /* configure interrupt type */ - config_pci_intr_type(ctrl); + config_pci_intr_type(dev, ctrl, iproc); /* Configure iProc PCI-AXI bridge */ if (iproc && ctrl->bde_dev.base_address1) { @@ -2580,7 +2652,7 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) &icfg->cmic_ver, &icfg->cmic_rev); shbde_iproc_config_init(icfg, ctrl->bde_dev.device, ctrl->bde_dev.rev); - if (debug >=2) { + if (debug >= 2) { gprintk("iproc version = %x dma_hi_bits = %x\n", icfg->iproc_ver, icfg->dma_hi_bits); } icfg->use_msi = ctrl->use_msi; @@ -2734,22 +2806,22 @@ _pci_remove(struct pci_dev* dev) if (ctrl->use_msi >= PCI_USE_INT_MSIX) { int i; for (i = 0; i < ctrl->msix_cnt; i++) - free_irq(ctrl->entries[i].vector, ctrl->pci_device); + free_irq(ctrl->entries[i].vector, ctrl); } else #endif { - free_irq(ctrl->iLine, ctrl); + free_irq(ctrl->iLine, ctrl); } } #ifdef CONFIG_PCI_MSI _msi_disconnect(ctrl); #endif - ctrl->isr = NULL; - ctrl->isr_data = NULL; - ctrl->isr2 = NULL; - ctrl->isr2_data = NULL; - } + ctrl->isr = NULL; + ctrl->isr_data = NULL; + ctrl->isr2 = NULL; + ctrl->isr2_data = NULL; +} static struct pci_driver _device_driver = { probe: _pci_probe, @@ -3641,8 +3713,12 @@ _gmac_dev_create(void) static int _init(void) { - #ifdef IPROC_CMICD +#ifdef CONFIG_OF + if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { + iproc_platform_driver_register(&iproc_cmicd_driver); + } else +#endif if (iproc_has_cmicd()) { iproc_cmicd_get_memregion(&iproc_cmicd_resources[IPROC_CMICD_RES_MEM]); iproc_platform_driver_register(&iproc_cmicd_driver); @@ -3651,8 +3727,8 @@ _init(void) #endif { /* Register platform device if no device node in dtb */ - iproc_platform_device_register(&iproc_cmicd_pdev); - } + iproc_platform_device_register(&iproc_cmicd_pdev); + } } #endif /* IPROC_CMICD */ @@ -3662,7 +3738,7 @@ _init(void) /* Register our goodies */ _device_driver.name = LINUX_KERNEL_BDE_NAME; -#if defined(BCM_ROBO_SUPPORT) +#if defined(BCM_ROBO_SUPPORT) #if defined(IPROC_CMICD) if (_gmac_dev_create()) { return -ENODEV; @@ -3771,6 +3847,11 @@ _cleanup(void) _dma_cleanup(); #ifdef IPROC_CMICD +#ifdef CONFIG_OF + if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { + iproc_platform_driver_unregister(&iproc_cmicd_driver); + } else +#endif if (iproc_has_cmicd()) { #ifdef CONFIG_OF if (!of_find_compatible_node(NULL, NULL, IPROC_CMICD_COMPATIBLE)) @@ -4251,14 +4332,18 @@ _interrupt_connect(int d, if (ctrl->use_msi == PCI_USE_INT_MSIX) { int i; for (i = 0; i < ctrl->msix_cnt; i++) { - ret = request_irq(ctrl->entries[i].vector, _isr, - irq_flags, LINUX_KERNEL_BDE_NAME, ctrl); + if (unlikely(debug >= 1)) { + gprintk("%s(%d):device# = %d, irq = %d\n", + __func__, __LINE__, d, ctrl->entries[i].vector); + } + ret = request_irq(ctrl->entries[i].vector, _isr, 0, + LINUX_KERNEL_BDE_NAME, ctrl); if (ret < 0) break; } if (ret < 0) { while (i >= 0) - free_irq(ctrl->entries[i--].vector, ctrl->pci_device); + free_irq(ctrl->entries[i--].vector, ctrl); goto err_disable_msi; } @@ -4266,15 +4351,39 @@ _interrupt_connect(int d, else #endif { - ret = request_irq(ctrl->iLine, _isr, irq_flags, +#if defined(IPROC_CMICD) && defined(CONFIG_OF) + if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { + int i, j; + for (i = 0; i < IHOST_CMICX_MAX_INTRS; i++) { + 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, + irq_flags, LINUX_KERNEL_BDE_NAME, ctrl); + if (ret < 0) { + gprintk("request_irq(%d) failed(%d)\n", iproc_cmicx_irqs[i], ret); + break; + } + } + if (ret < 0) { + for (j = 0; j < i; j++) { + free_irq(iproc_cmicx_irqs[j], ctrl); + } + goto err_disable_msi; + } + } else +#endif + { + ret = request_irq(ctrl->iLine, _isr, irq_flags, LINUX_KERNEL_BDE_NAME, ctrl); - if (ret < 0) - goto err_disable_msi; + if (ret < 0) + goto err_disable_msi; - if (unlikely(debug >= 1)) - gprintk("%s(%d):device# = %d, irq_flags = %lu, irq = %d\n", + if (unlikely(debug >= 1)) + gprintk("%s(%d):device# = %d, irq_flags = %lu, irq = %d\n", __func__, __LINE__, d, irq_flags, ctrl->pci_device ? ctrl->pci_device->irq : ctrl->iLine); + } } } return 0; @@ -4292,7 +4401,7 @@ _interrupt_connect(int d, ctrl->isr2_data = NULL; return -1; - } +} static int _interrupt_disconnect(int d) @@ -4353,13 +4462,30 @@ _interrupt_disconnect(int d) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,84)) if (ctrl->use_msi >= PCI_USE_INT_MSIX) { int i; - for (i = 0; i < ctrl->msix_cnt; i++) - free_irq(ctrl->entries[i].vector, ctrl->pci_device); + for (i = 0; i < ctrl->msix_cnt; i++) { + if (unlikely(debug > 1)) { + gprintk("%s(%d):device# = %d, irq = %d\n", + __func__, __LINE__, d, ctrl->entries[i].vector); + } + free_irq(ctrl->entries[i].vector, ctrl); + } } else +#endif +#if defined(IPROC_CMICD) && defined(CONFIG_OF) + if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { + int i; + for (i = 0; i < IHOST_CMICX_MAX_INTRS; i++) { + if (unlikely(debug > 1)) { + gprintk("%s(%d):device# = %d, free_irq(%d)\n", + __func__, __LINE__, d, iproc_cmicx_irqs[i]); + } + free_irq(iproc_cmicx_irqs[i], ctrl); + } + } else #endif { - free_irq(ctrl->iLine, ctrl); + free_irq(ctrl->iLine, ctrl); } #ifdef CONFIG_PCI_MSI if (ctrl->use_msi >= PCI_USE_INT_MSI) { 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 7fc9fd166bbd..6c7c9bb95056 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 @@ -30,6 +30,9 @@ #include "linux-user-bde.h" +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) +#include +#endif #ifdef KEYSTONE #include #endif @@ -75,21 +78,56 @@ MODULE_LICENSE("GPL"); /* CMICX defines */ #define INTC_INTR_REG_NUM (8) -#define INTC_INTR_ENABLE_REG0 (0x180130f0) -#define INTC_INTR_STATUS_REG0 (0x18013190) -#define INTC_INTR_RAW_STATUS_REG0 (0x18013140) +/* +TODO:HX5 +The INTR base address values are changed for HX5, +hence making new #defines so runtime decisions can +be made. +*/ + +#define INTC_INTR_ENABLE_REG0 (0x180130f0) +#define INTC_INTR_STATUS_REG0 (0x18013190) +#define INTC_INTR_RAW_STATUS_REG0 (0x18013140) #define INTC_INTR_ENABLE_BASE (INTC_INTR_ENABLE_REG0) #define INTC_INTR_STATUS_BASE (INTC_INTR_STATUS_REG0) #define INTC_INTR_RAW_STATUS_BASE (INTC_INTR_RAW_STATUS_REG0) -#define INTC_PDMA_INTR_REG_IND 4 +#define HX5_INTC_INTR_ENABLE_REG0 (0x102310f0) +#define HX5_INTC_INTR_STATUS_REG0 (0x10231190) +#define HX5_INTC_INTR_RAW_STATUS_REG0 (0x10231140) + +#define HX5_INTC_INTR_ENABLE_BASE (HX5_INTC_INTR_ENABLE_REG0) +#define HX5_INTC_INTR_STATUS_BASE (HX5_INTC_INTR_STATUS_REG0) +#define HX5_INTC_INTR_RAW_STATUS_BASE (HX5_INTC_INTR_RAW_STATUS_REG0) + +#define IOREMAP(addr, size) ioremap_nocache(addr, size) + +#define HX5_IHOST_GICD_ISENABLERN_0 (0x10781100) +#define HX5_IHOST_GICD_ISENABLERN_1 (0x10781104) +#define HX5_IHOST_GICD_ICENABLERN_1 (0x10781184) +#define HX5_IHOST_GICD_ICENABLERN_8 (0x107811a0) +/* Offset between ISENABLERN_1 and ICENABLERN_1 in 4-bytes */ +#define HX5_IHOST_IRQ_MASK_OFFSET 0x20 +#define HX5_IHOST_INTR_MAP_NUM (HX5_IHOST_GICD_ICENABLERN_8 - HX5_IHOST_GICD_ISENABLERN_0) +#define HX5_IHOST_INTR_STATUS_MAP_NUM (INTC_INTR_REG_NUM * (sizeof(uint32))) +#define IRQ_BIT(intr) (intr % (sizeof(uint32)*8)) +#define IRQ_MASK_INDEX(intr) (intr / (sizeof(uint32)*8)) +#define HX5_CHIP_INTR_LOW_PRIORITY 119 +#define INTR_LOW_PRIORITY_BITPOS (1 << IRQ_BIT(HX5_CHIP_INTR_LOW_PRIORITY)) +#define INTC_LOW_PRIORITY_INTR_REG_IND IRQ_MASK_INDEX(HX5_CHIP_INTR_LOW_PRIORITY) +#define INTC_PDMA_INTR_REG_IND 4 #define READ_INTC_INTR(d, reg, v) \ - (v = user_bde->iproc_read(d, reg)) + (v = user_bde->iproc_read(d, reg)) #define WRITE_INTC_INTR(d, reg, v) \ (user_bde->iproc_write(d, reg, v)) +#define IHOST_READ_INTR(d, reg, v) \ + (v = readl((reg))) +#define IHOST_WRITE_INTR(d, reg, v) \ + (writel((v), (reg))) + /* Allow override of default CMICm CMC */ #ifndef BDE_CMICM_PCIE_CMC #define BDE_CMICM_PCIE_CMC 0 @@ -103,6 +141,9 @@ MODULE_LICENSE("GPL"); /* Defines used to distinguish CMICe from CMICm */ #define CMICE_DEV_REV_ID (0x178 / sizeof(uint32)) +static uint32 *ihost_intr_status_base = NULL; +static uint32 *ihost_intr_enable_base = NULL; + static ibde_t *user_bde = NULL; typedef void (*isr_f)(void *); @@ -225,27 +266,68 @@ _cmicx_interrupt(bde_ctrl_t *ctrl) int d, ind; uint32 stat, iena, mask, fmask; bde_inst_resource_t *res; + uint32 intc_intr_status_base = 0, intc_intr_enable_base = 0; d = (((uint8 *)ctrl - (uint8 *)_devices) / sizeof (bde_ctrl_t)); res = &_bde_inst_resource[ctrl->inst]; lkbde_irq_mask_get(d, &mask, &fmask); + if ((ctrl->dev_type & BDE_SWITCH_DEV_TYPE) && + ((user_bde->get_dev(d)->device == BCM56370_DEVICE_ID) || + (user_bde->get_dev(d)->device == BCM56371_DEVICE_ID) || + (user_bde->get_dev(d)->device == BCM56372_DEVICE_ID) || + (user_bde->get_dev(d)->device == BCM56374_DEVICE_ID) || + (user_bde->get_dev(d)->device == BCM56375_DEVICE_ID) || + (user_bde->get_dev(d)->device == BCM56376_DEVICE_ID) || + (user_bde->get_dev(d)->device == BCM56377_DEVICE_ID) || + (user_bde->get_dev(d)->device == BCM56577_DEVICE_ID) || + (user_bde->get_dev(d)->device == BCM56578_DEVICE_ID) || + (user_bde->get_dev(d)->device == BCM56579_DEVICE_ID))) { + intc_intr_status_base = HX5_INTC_INTR_STATUS_BASE; + intc_intr_enable_base = HX5_INTC_INTR_ENABLE_BASE; + } else { + intc_intr_status_base = INTC_INTR_STATUS_BASE; + intc_intr_enable_base = INTC_INTR_ENABLE_BASE; + } if (fmask) { - READ_INTC_INTR(d, INTC_INTR_STATUS_BASE + 4 * INTC_PDMA_INTR_REG_IND, stat); - READ_INTC_INTR(d, INTC_INTR_ENABLE_BASE + 4 * INTC_PDMA_INTR_REG_IND, iena); + if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { + IHOST_READ_INTR(d, ihost_intr_status_base + INTC_PDMA_INTR_REG_IND, stat); + IHOST_READ_INTR(d, ihost_intr_enable_base + INTC_PDMA_INTR_REG_IND, iena); + } else { + READ_INTC_INTR(d, intc_intr_status_base + 4 * INTC_PDMA_INTR_REG_IND, stat); + READ_INTC_INTR(d, intc_intr_enable_base + 4 * INTC_PDMA_INTR_REG_IND, iena); + } if (stat & iena) { - WRITE_INTC_INTR(d, INTC_INTR_ENABLE_BASE + 4 * INTC_PDMA_INTR_REG_IND, 0); + if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { + IHOST_WRITE_INTR(d, ihost_intr_enable_base + INTC_PDMA_INTR_REG_IND + + HX5_IHOST_IRQ_MASK_OFFSET, ~0); + } else { + WRITE_INTC_INTR(d, intc_intr_enable_base + 4 * INTC_PDMA_INTR_REG_IND, 0); + } + for (ind = 0; ind < INTC_INTR_REG_NUM; ind++) { if (ind == INTC_PDMA_INTR_REG_IND) { continue; } - READ_INTC_INTR(d, INTC_INTR_STATUS_BASE + 4 * ind, stat); - READ_INTC_INTR(d, INTC_INTR_ENABLE_BASE + 4 * ind, iena); + if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { + if (ind < INTC_LOW_PRIORITY_INTR_REG_IND) { + continue; + } + IHOST_READ_INTR(d, ihost_intr_status_base + ind, stat); + IHOST_READ_INTR(d, ihost_intr_enable_base + ind, iena); + if (ind == INTC_LOW_PRIORITY_INTR_REG_IND) { + stat &= INTR_LOW_PRIORITY_BITPOS; + } + } else { + READ_INTC_INTR(d, intc_intr_status_base + 4 * ind, stat); + READ_INTC_INTR(d, intc_intr_enable_base + 4 * ind, iena); + } if (stat & iena) { break; } } + if (ind >= INTC_INTR_REG_NUM) { return; } @@ -260,7 +342,20 @@ _cmicx_interrupt(bde_ctrl_t *ctrl) if (fmask && ind == INTC_PDMA_INTR_REG_IND) { continue; } - WRITE_INTC_INTR(d, INTC_INTR_ENABLE_BASE + 4 * ind, 0); + if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { + if (ind < INTC_LOW_PRIORITY_INTR_REG_IND) { + continue; + } + if (ind == INTC_LOW_PRIORITY_INTR_REG_IND) { + IHOST_WRITE_INTR(d, ihost_intr_enable_base + INTC_LOW_PRIORITY_INTR_REG_IND + + HX5_IHOST_IRQ_MASK_OFFSET, INTR_LOW_PRIORITY_BITPOS); + } else { + IHOST_WRITE_INTR(d, ihost_intr_enable_base + ind + + HX5_IHOST_IRQ_MASK_OFFSET, ~0); + } + } else { + WRITE_INTC_INTR(d, intc_intr_enable_base + 4*ind, 0); + } } /* Notify */ @@ -750,6 +845,12 @@ _devices_init(int d) uint32 ver; uint16 device_id_mask = 0xFFF0; uint16 device_id; + int state = 0; + + (void)lkbde_dev_state_get(d, &state); + if (state == BDE_DEV_STATE_REMOVED) { + return; + } ctrl = &_devices[d]; /* Initialize our control info */ @@ -849,6 +950,31 @@ _devices_init(int d) case BCM88952_DEVICE_ID: ctrl->isr = (isr_f)_cmicd_cmc0_interrupt; break; + case BCM88790_DEVICE_ID: + ctrl->isr = (isr_f)_cmicx_interrupt; + break; + case BCM56370_DEVICE_ID: + case BCM56371_DEVICE_ID: + case BCM56372_DEVICE_ID: + case BCM56374_DEVICE_ID: + case BCM56375_DEVICE_ID: + case BCM56376_DEVICE_ID: + case BCM56377_DEVICE_ID: + case BCM56577_DEVICE_ID: + case BCM56578_DEVICE_ID: + case BCM56579_DEVICE_ID: + ctrl->isr = (isr_f)_cmicx_interrupt; + if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { + if (!ihost_intr_enable_base) { + ihost_intr_enable_base = (uint32_t *)IOREMAP(HX5_IHOST_GICD_ISENABLERN_1, + HX5_IHOST_INTR_MAP_NUM); + } + if (!ihost_intr_status_base) { + ihost_intr_status_base = (uint32_t *)IOREMAP(HX5_INTC_INTR_RAW_STATUS_REG0, + HX5_IHOST_INTR_STATUS_MAP_NUM); + } + } + break; default: /* Get CMIC version */ if (user_bde->get_cmic_ver(d, &ver) != 0) { @@ -876,7 +1002,7 @@ _devices_init(int d) } break; } - /*All Ramon devices from 0x8790 to 0x879F*/ + /* 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; } @@ -928,10 +1054,14 @@ _init(void) init_waitqueue_head(&res->intr_wq); atomic_set(&res->intr, 0); + ihost_intr_enable_base = NULL; + ihost_intr_status_base = NULL; + for (i = 0; i < user_bde->num_devices(BDE_ALL_DEVICES); i++) { res->inst_id |= (1 << i); _devices_init(i); } + return 0; } @@ -961,6 +1091,16 @@ _cleanup(void) linux_bde_destroy(user_bde); user_bde = NULL; } + + if (ihost_intr_enable_base) { + iounmap(ihost_intr_enable_base); + ihost_intr_enable_base = NULL; + } + if (ihost_intr_status_base) { + iounmap(ihost_intr_status_base); + ihost_intr_status_base = NULL; + } + return 0; } @@ -1088,6 +1228,7 @@ static int _device_reprobe(void) { int i; + for (i = 0; i < user_bde->num_devices(BDE_ALL_DEVICES); i++) { if (_devices[i].devid == 0) { _devices_init(i); @@ -1167,7 +1308,8 @@ _ioctl(unsigned int cmd, unsigned long arg) ssize_t size; const ibde_dev_t *bde_dev; int inst_id; - bde_inst_resource_t *res; + bde_inst_resource_t *res; + uint32_t *mapaddr; if (copy_from_user(&io, (void *)arg, sizeof(io))) { return -EFAULT; @@ -1396,9 +1538,22 @@ _ioctl(unsigned int cmd, unsigned long arg) } break; case LUBDE_IPROC_READ_REG: - io.d1 = user_bde->iproc_read(io.dev, io.d0); - if (io.d1 == -1) { - io.rc = LUBDE_FAIL; + if (!VALID_DEVICE(io.dev)) { + return -EINVAL; + } + if (_devices[io.dev].dev_type & BDE_AXI_DEV_TYPE) { + mapaddr = IOREMAP(io.d0, sizeof(uint32_t)); + if (mapaddr == NULL) { + io.rc = LUBDE_FAIL; + return -1; + } + io.d1 = readl(mapaddr); + iounmap(mapaddr); + } else { + io.d1 = user_bde->iproc_read(io.dev, io.d0); + if (io.d1 == -1) { + io.rc = LUBDE_FAIL; + } } break; case LUBDE_IPROC_WRITE_REG: @@ -1412,6 +1567,9 @@ _ioctl(unsigned int cmd, unsigned long arg) case LUBDE_GET_DEVICE_STATE: io.rc = lkbde_dev_state_get(io.dev, &io.d0); break; + case LUBDE_REPROBE: + io.rc = _device_reprobe(); + break; default: gprintk("Error: Invalid ioctl (%08x)\n", cmd); io.rc = LUBDE_FAIL; diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.h b/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.h index 621973b7a7f5..535ccac9fad9 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.h +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.h @@ -81,6 +81,7 @@ typedef struct { #define LUBDE_IPROC_WRITE_REG _IO(LUBDE_MAGIC, 28) #define LUBDE_ATTACH_INSTANCE _IO(LUBDE_MAGIC, 29) #define LUBDE_GET_DEVICE_STATE _IO(LUBDE_MAGIC, 30) +#define LUBDE_REPROBE _IO(LUBDE_MAGIC, 31) #define LUBDE_SEM_OP_CREATE 1 #define LUBDE_SEM_OP_DESTROY 2 @@ -93,9 +94,10 @@ typedef struct { /* * Version history - * 1:add LUBDE_GET_DEVICE_STATE to support PCI hot plug + * 1: add LUBDE_GET_DEVICE_STATE to support PCI hot plug + * 2: add LUBDE_REPROBE to support reprobe available devices */ -#define KBDE_VERSION 1 +#define KBDE_VERSION 2 /* This is the signal that will be used 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 d1e95725c5f7..e1bdcc4db0da 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c +++ b/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c @@ -40,6 +40,8 @@ #define BAR0_PAXB_OARR_2_UPPER 0x2d64 #define BAR0_DMU_PCU_PCIE_SLAVE_RESET_MODE 0x7024 +#define PAXB_0_FUNC0_IMAP1_3 0x2d88 + /* Force byte pointer for offset adjustments */ #define ROFFS(_ptr, _offset) ((unsigned char*)(_ptr) + (_offset)) @@ -47,6 +49,7 @@ #define PAXB_CONFIG_IND_ADDRr_PROTOCOL_LAYERf_MASK 0x3 #define PAXB_CONFIG_IND_ADDRr_ADDRESSf_SHFT 0 #define PAXB_CONFIG_IND_ADDRr_ADDRESSf_MASK 0x7ff +#define PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT 20 /* Register value set/get by field */ #define REG_FIELD_SET(_r, _f, _r_val, _f_val) \ @@ -273,17 +276,25 @@ shbde_iproc_paxb_init(shbde_hal_t *shbde, void *iproc_regs, reg = ROFFS(iproc_regs, BAR0_PAXB_PCIE_EP_AXI_CONFIG); iproc32_write(shbde, reg, 0x0); if(icfg->cmic_ver < 4) { /* Non-CMICX */ - reg = ROFFS(iproc_regs, BAR0_PAXB_OARR_2); - iproc32_write(shbde, reg, 0x1); - reg = ROFFS(iproc_regs, BAR0_PAXB_OARR_2_UPPER); - iproc32_write(shbde, reg, icfg->dma_hi_bits); - - /* Configure MSI interrupt page */ - if (icfg->use_msi) { - reg = ROFFS(iproc_regs, BAR0_PAXB_OARR_FUNC0_MSI_PAGE); - data = iproc32_read(shbde, reg); - iproc32_write(shbde, reg, data | 0x1); + reg = ROFFS(iproc_regs, BAR0_PAXB_OARR_2); + iproc32_write(shbde, reg, 0x1); + reg = ROFFS(iproc_regs, BAR0_PAXB_OARR_2_UPPER); + iproc32_write(shbde, reg, icfg->dma_hi_bits); + /* Configure MSI interrupt page */ + if (icfg->use_msi) { + reg = ROFFS(iproc_regs, BAR0_PAXB_OARR_FUNC0_MSI_PAGE); + data = iproc32_read(shbde, reg); + iproc32_write(shbde, reg, data | 0x1); + } } + /* 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); + data = iproc32_read(shbde, reg); + data &= mask; + data |= 0x410 << PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT; + iproc32_write(shbde, reg, data); } return pci_num; } @@ -315,7 +326,8 @@ shbde_iproc_pci_read(shbde_hal_t *shbde, void *iproc_regs, /* Sub-window size is 0x1000 (4K) */ subwin_base = (addr & ~0xfff); - if((icfg->cmic_ver >= 4) && (subwin_base == 0x18013000)) { + if((icfg->cmic_ver >= 4) && + ((subwin_base == 0x10231000) || (subwin_base == 0x18013000))) { /* Route the INTC block access through IMAP0_6 */ reg = ROFFS(iproc_regs, 0x6000 + (addr & 0xfff)); } else { @@ -361,7 +373,8 @@ shbde_iproc_pci_write(shbde_hal_t *shbde, void *iproc_regs, /* Sub-window size is 0x1000 (4K) */ subwin_base = (addr & ~0xfff); - if((icfg->cmic_ver >= 4) && (subwin_base == 0x18013000)) { + if((icfg->cmic_ver >= 4) && + ((subwin_base == 0x10231000) || (subwin_base == 0x18013000))) { /* Route the INTC block access through IMAP0_6 */ reg = ROFFS(iproc_regs, 0x6000 + (addr & 0xfff)); } else { 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 801f5d3e406c..6767090ec7bb 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 @@ -301,6 +301,13 @@ static int use_proxy = 0; #endif /* Compatibility */ + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)) +#define NETDEV_UPDATE_TRANS_START_TIME(dev) dev->trans_start = jiffies +#else +#define NETDEV_UPDATE_TRANS_START_TIME(dev) netif_trans_update(dev) +#endif + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) #define skb_copy_to_linear_data(_skb, _pkt, _len) \ eth_copy_and_sum(_skb, _pkt, _len, 0) @@ -505,6 +512,7 @@ typedef struct bkn_switch_info_s { uint32_t rcpu_sig; /* RCPU signature */ uint64_t halt_addr[NUM_DMA_CHAN]; /* DMA halt address */ uint32_t cdma_channels; /* Active channels for Continuous DMA mode */ + uint32_t poll_channels; /* Channels for polling */ uint32_t inst_id; /* Instance id of this device */ int evt_idx; /* Event queue index for this device*/ int basedev_suspended; /* Base device suspended */ @@ -536,7 +544,6 @@ typedef struct bkn_switch_info_s { int dirty; /* Index of next Rx DCB to complete */ int running; /* Rx DMA is active */ int api_active; /* BCM Rx API is active */ - int api_wait; /* Wait BCM Rx API resources */ int chain_complete; /* All DCBs in chain processed */ int sync_err; /* Chain done with incomplete DCBs (debug) */ int sync_retry; /* Total retry times for sync error (debug) */ @@ -684,7 +691,7 @@ typedef struct bkn_pkt_dnx_s { #endif /* defined(CMIC_SOFT_BYTE_SWAP) */ -#define MEMORY_BARRIER mb() +#define MEMORY_BARRIER smp_mb() /* Default random MAC address has Broadcom OUI with local admin bit set */ static u8 bkn_dev_mac[6] = { 0x02, 0x10, 0x18, 0x00, 0x00, 0x00 }; @@ -1753,7 +1760,6 @@ bkn_clean_rx_dcbs(bkn_switch_info_t *sinfo, int chan) } sinfo->rx[chan].running = 0; sinfo->rx[chan].api_active = 0; - sinfo->rx[chan].api_wait = 0; DBG_DCB_RX(("Cleaned Rx%d DCBs (%d %d).\n", chan, sinfo->rx[chan].cur, sinfo->rx[chan].dirty)); } @@ -1959,7 +1965,7 @@ bkn_api_rx_restart(bkn_switch_info_t *sinfo, int chan) sinfo->rx[chan].chain_complete = 0; start_dma = 1; if (CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan) && - sinfo->rx[chan].api_wait) { + sinfo->rx[chan].api_active) { /* HW is running already, so we just move to the next chain */ start_dma = 0; } @@ -1972,7 +1978,6 @@ bkn_api_rx_restart(bkn_switch_info_t *sinfo, int chan) dev_dma_chan_clear(sinfo, XGS_DMA_RX_CHAN + chan); dev_irq_mask_enable(sinfo, XGS_DMA_RX_CHAN + chan, 1); dev_dma_chan_start(sinfo, XGS_DMA_RX_CHAN + chan, dcb_chain->dcb_dma); - sinfo->rx[chan].api_wait = 1; } list_del(&dcb_chain->list); @@ -1992,10 +1997,6 @@ bkn_api_rx_chain_done(bkn_switch_info_t *sinfo, int chan) sinfo->rx[chan].api_dcb_chain = NULL; } bkn_api_rx_restart(sinfo, chan); - if (CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan) && - sinfo->rx[chan].api_dcb_chain == NULL) { - sinfo->rx[chan].api_active = 0; - } } static int @@ -2053,6 +2054,7 @@ bkn_api_rx_copy_from_skb(bkn_switch_info_t *sinfo, } } dcb[sinfo->dcb_wsize-1] = dcb_stat | SOC_DCB_KNET_DONE; + MEMORY_BARRIER; dcb_chain->dcb_cur++; @@ -2062,6 +2064,7 @@ bkn_api_rx_copy_from_skb(bkn_switch_info_t *sinfo, (sinfo->cmic_type != 'x' && dcb[1] & (1 << 18))) { /* Get the next chain if reload done */ dcb[sinfo->dcb_wsize-1] |= 1 << 31 | SOC_DCB_KNET_DONE; + MEMORY_BARRIER; bkn_api_rx_chain_done(sinfo, chan); dcb_chain = sinfo->rx[chan].api_dcb_chain; if (dcb_chain == NULL) { @@ -2090,7 +2093,7 @@ bkn_rx_refill(bkn_switch_info_t *sinfo, int chan) struct sk_buff *skb; bkn_desc_info_t *desc; uint32_t *dcb; - uint32_t encap_size = sinfo->cmic_type == 'x' ? RCPU_HDR_SIZE : RCPU_RX_ENCAP_SIZE; + uint32_t resv_size = sinfo->cmic_type == 'x' ? RCPU_HDR_SIZE : RCPU_RX_ENCAP_SIZE; int prev; if (sinfo->rx[chan].use_rx_skb == 0) { @@ -2107,11 +2110,11 @@ bkn_rx_refill(bkn_switch_info_t *sinfo, int chan) while (sinfo->rx[chan].free < MAX_RX_DCBS) { desc = &sinfo->rx[chan].desc[sinfo->rx[chan].cur]; if (desc->skb == NULL) { - skb = dev_alloc_skb(rx_buffer_size + encap_size); + skb = dev_alloc_skb(rx_buffer_size + RCPU_RX_ENCAP_SIZE); if (skb == NULL) { break; } - skb_reserve(skb, encap_size); + skb_reserve(skb, resv_size); desc->skb = skb; } else { DBG_DCB_RX(("Refill Rx%d SKB in DCB %d recycled.\n", @@ -3198,11 +3201,7 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) case KCOM_DEST_T_API: DBG_FLTR(("Send to Rx API\n")); sinfo->rx[chan].pkts_f_api++; - if (bkn_api_rx_copy_from_skb(sinfo, chan, desc) < 0) { - /* Suspend SKB Rx due to no API resources */ - sinfo->rx[chan].api_wait = 1; - return dcbs_done; - } + bkn_api_rx_copy_from_skb(sinfo, chan, desc); break; case KCOM_DEST_T_NETIF: priv = bkn_netif_lookup(sinfo, filter->kf.dest_id); @@ -3408,10 +3407,6 @@ bkn_rx_desc_done(bkn_switch_info_t *sinfo, int chan) static void bkn_rx_chain_done(bkn_switch_info_t *sinfo, int chan) { - if (sinfo->rx[chan].use_rx_skb && sinfo->rx[chan].api_wait) { - return; - } - DBG_IRQ(("Rx%d chain done\n", chan)); if (sinfo->rx[chan].chain_complete == 0) { @@ -3809,6 +3804,7 @@ static int xgs_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 dma_stat; int chan; @@ -3817,7 +3813,28 @@ xgs_do_dma(bkn_switch_info_t *sinfo, int budget) for (chan = 0; chan < sinfo->rx_chans; chan++) { if (dma_stat & DS_DESC_DONE_TST(XGS_DMA_RX_CHAN + chan)) { xgs_dma_desc_clear(sinfo, XGS_DMA_RX_CHAN + chan); - rx_dcbs_done += bkn_do_rx(sinfo, chan, budget - rx_dcbs_done); + sinfo->poll_channels |= 1 << chan; + } + } + if (!sinfo->poll_channels) { + sinfo->poll_channels = (uint32_t)(1 << sinfo->rx_chans) - 1; + budget_chans = budget / sinfo->rx_chans; + } else { + for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (1 << chan & sinfo->poll_channels) { + budget_chans++; + } + } + budget_chans = budget / budget_chans; + } + + for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (1 << chan & sinfo->poll_channels) { + chan_done = bkn_do_rx(sinfo, chan, budget_chans); + rx_dcbs_done += chan_done; + if (chan_done < budget_chans) { + sinfo->poll_channels &= ~(1 << chan); + } bkn_rx_desc_done(sinfo, chan); } @@ -3833,13 +3850,14 @@ xgs_do_dma(bkn_switch_info_t *sinfo, int budget) bkn_tx_chain_done(sinfo, tx_dcbs_done); } - return rx_dcbs_done; + return sinfo->poll_channels ? budget : rx_dcbs_done; } static int xgsm_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 dma_stat, irq_stat = 0; int chan; @@ -3854,7 +3872,28 @@ xgsm_do_dma(bkn_switch_info_t *sinfo, int budget) if (dma_stat & (0x10 << (XGS_DMA_RX_CHAN + chan)) || irq_stat & (0x08000000 << (XGS_DMA_RX_CHAN + chan))) { xgsm_dma_desc_clear(sinfo, XGS_DMA_RX_CHAN + chan); - rx_dcbs_done += bkn_do_rx(sinfo, chan, budget - rx_dcbs_done); + sinfo->poll_channels |= 1 << chan; + } + } + if (!sinfo->poll_channels) { + sinfo->poll_channels = (uint32_t)(1 << sinfo->rx_chans) - 1; + budget_chans = budget / sinfo->rx_chans; + } else { + for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (1 << chan & sinfo->poll_channels) { + budget_chans++; + } + } + budget_chans = budget / budget_chans; + } + + for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (1 << chan & sinfo->poll_channels) { + chan_done = bkn_do_rx(sinfo, chan, budget_chans); + rx_dcbs_done += chan_done; + if (chan_done < budget_chans) { + sinfo->poll_channels &= ~(1 << chan); + } bkn_rx_desc_done(sinfo, chan); } @@ -3879,22 +3918,45 @@ xgsm_do_dma(bkn_switch_info_t *sinfo, int budget) bkn_tx_chain_done(sinfo, tx_dcbs_done); } - return rx_dcbs_done; + return sinfo->poll_channels ? budget : rx_dcbs_done; } static int 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; int chan; DEV_READ32(sinfo, CMICX_IRQ_STATr, &irq_stat); + for (chan = 0; chan < sinfo->rx_chans; chan++) { if ((irq_stat & CMICX_DS_CMC_CTRLD_INT(XGS_DMA_RX_CHAN + chan)) || (irq_stat & CMICX_DS_CMC_DESC_DONE(XGS_DMA_RX_CHAN + chan))) { xgsx_dma_desc_clear(sinfo, XGS_DMA_RX_CHAN + chan); - rx_dcbs_done += bkn_do_rx(sinfo, chan, budget - rx_dcbs_done); + sinfo->poll_channels |= 1 << chan; + } + } + if (!sinfo->poll_channels) { + sinfo->poll_channels = (uint32_t)(1 << sinfo->rx_chans) - 1; + budget_chans = budget / sinfo->rx_chans; + } else { + for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (1 << chan & sinfo->poll_channels) { + budget_chans++; + } + } + budget_chans = budget / budget_chans; + } + + for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (1 << chan & sinfo->poll_channels) { + chan_done = bkn_do_rx(sinfo, chan, budget_chans); + rx_dcbs_done += chan_done; + if (chan_done < budget_chans) { + sinfo->poll_channels &= ~(1 << chan); + } bkn_rx_desc_done(sinfo, chan); } @@ -3919,7 +3981,7 @@ xgsx_do_dma(bkn_switch_info_t *sinfo, int budget) bkn_tx_chain_done(sinfo, tx_dcbs_done); } - return rx_dcbs_done; + return sinfo->poll_channels ? budget : rx_dcbs_done; } static int @@ -4400,10 +4462,12 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) dev_kfree_skb_any(skb); skb = new_skb; pktdata = skb->data; + rcpulen = 0; } else { /* Add tag to RCPU header space */ DBG_SKB(("Expand into unused RCPU header\n")); - pktdata = &skb->data[rcpulen - 4]; + rcpulen -= 4; + pktdata = &skb->data[rcpulen]; for (idx = 0; idx < 12; idx++) { pktdata[idx] = pktdata[idx + 4]; } @@ -4418,7 +4482,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) } else { if (sinfo->cmic_type == 'x' && priv->port >= 0) { if (skb_header_cloned(skb) || skb_headroom(skb) < hdrlen + 4 || - ((unsigned long)skb->data % 4)) { + (sinfo->dcb_type == 36 && (unsigned long)skb->data % 4)) { /* Current SKB cannot be modified */ DBG_SKB(("Realloc Tx SKB\n")); new_skb = dev_alloc_skb(pktlen + hdrlen + 4); @@ -4502,6 +4566,8 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&sinfo->lock, flags); return 0; } + /* skb_padto may update the skb->data pointer */ + pktdata = &skb->data[rcpulen]; DBG_SKB(("Packet padded to %d bytes\n", pktlen)); } @@ -4696,7 +4762,6 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) * bit0 -bit15 of dcb[1] is used to save requested byte count */ if ((skb->len + 4) <= SOC_DCB_KNET_COUNT_MASK) { - pktdata = skb->data; pktlen = skb->len + 4; if (pktlen < (64 + taglen + hdrlen)) { pktlen = (64 + taglen + hdrlen); @@ -4710,6 +4775,7 @@ 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; } else { DBG_WARN(("Tx drop: size of pkt (%d) is out of range(%d)\n", pktlen, SOC_DCB_KNET_COUNT_MASK)); @@ -4785,11 +4851,8 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) bkn_suspend_tx(sinfo); } -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4,6,0)) - dev->trans_start = jiffies; -#else - netif_trans_update(dev); -#endif + NETDEV_UPDATE_TRANS_START_TIME(dev); + spin_unlock_irqrestore(&sinfo->lock, flags); return 0; @@ -5491,14 +5554,12 @@ bkn_seq_dma_show(struct seq_file *s, void *v) seq_printf(s, "Rx%d DCB info (unit %d):\n" " api: %d\n" - " wait: %d\n" " dirty: %d\n" " cur: %d\n" " free: %d\n" " run: %d\n", chan, iter->dev_no, sinfo->rx[chan].api_active, - sinfo->rx[chan].api_wait, sinfo->rx[chan].dirty, sinfo->rx[chan].cur, sinfo->rx[chan].free, @@ -6127,6 +6188,7 @@ bkn_knet_dma_info(kcom_msg_dma_info_t *kmsg, int len) if (sinfo->cmic_type == 'x') { dcb_chain_end->dcb_mem[woffset + 1] = DMA_TO_BUS_HI(dcb_chain->dcb_dma >> 32); } + MEMORY_BARRIER; } sinfo->tx.api_dcb_chain_end = dcb_chain; if (sinfo->tx.api_active) { @@ -6181,6 +6243,7 @@ bkn_knet_dma_info(kcom_msg_dma_info_t *kmsg, int len) if (sinfo->cmic_type == 'x') { dcb_chain_end->dcb_mem[woffset + 1] = DMA_TO_BUS_HI(dcb_chain->dcb_dma >> 32); } + MEMORY_BARRIER; } sinfo->rx[chan].api_dcb_chain_end = dcb_chain; if (!sinfo->rx[chan].use_rx_skb) { @@ -6194,18 +6257,6 @@ bkn_knet_dma_info(kcom_msg_dma_info_t *kmsg, int len) if (sinfo->rx[chan].api_active == 0) { bkn_api_rx_restart(sinfo, chan); - /* Resume SKB Rx due to refilled API resources */ - if (sinfo->rx[chan].use_rx_skb && sinfo->rx[chan].api_wait) { - sinfo->rx[chan].api_wait = 0; - if (CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { - bkn_do_skb_rx(sinfo, chan, 1); - } else { - bkn_do_skb_rx(sinfo, chan, MAX_RX_DCBS); - if (sinfo->rx[chan].chain_complete) { - bkn_rx_chain_done(sinfo, chan); - } - } - } } spin_unlock_irqrestore(&sinfo->lock, flags); @@ -6272,7 +6323,7 @@ bkn_knet_dev_reprobe(void) for (i = 0; i < kernel_bde->num_devices(BDE_ALL_DEVICES); i++) { sinfo = bkn_sinfo_from_unit(i); - if (sinfo == NULL ) { + if (sinfo == NULL) { /* New device found after re-probe. */ if (bkn_knet_dev_init(i) < 0) { return -1; @@ -6289,7 +6340,7 @@ bkn_knet_dev_reprobe(void) /* Assign the inst_id and evt_idx */ static int -bkn_knet_dev_inst_set(kcom_msg_version_t *kmsg) +bkn_knet_dev_inst_set(kcom_msg_reprobe_t *kmsg) { bkn_switch_info_t *sinfo; int d = kmsg->hdr.unit; @@ -6333,13 +6384,6 @@ bkn_knet_dev_inst_set(kcom_msg_version_t *kmsg) static int bkn_knet_version(kcom_msg_version_t *kmsg, int len) { - /* Support pci hot plug and multiple instance */ - if ((bkn_knet_dev_reprobe() < 0) || - (bkn_knet_dev_inst_set(kmsg) < 0)) { - kmsg->hdr.status = KCOM_E_RESOURCE; - return sizeof(kcom_msg_version_t); - } - kmsg->hdr.type = KCOM_MSG_TYPE_RSP; kmsg->version = KCOM_VERSION; kmsg->netif_max = KCOM_NETIF_MAX; @@ -6496,6 +6540,21 @@ bkn_knet_detach(kcom_msg_detach_t *kmsg, int len) return sizeof(kcom_msg_detach_t); } +static int +bkn_knet_reprobe(kcom_msg_reprobe_t *kmsg, int len) +{ + kmsg->hdr.type = KCOM_MSG_TYPE_RSP; + + /* Support pci hot plug and multiple instance */ + if ((bkn_knet_dev_reprobe() < 0) || + (bkn_knet_dev_inst_set(kmsg) < 0)) { + kmsg->hdr.status = KCOM_E_RESOURCE; + return sizeof(kcom_msg_reprobe_t); + } + + return sizeof(kcom_msg_reprobe_t); +} + static int bkn_knet_netif_create(kcom_msg_netif_create_t *kmsg, int len) { @@ -7007,7 +7066,6 @@ bkn_knet_wb_cleanup(kcom_msg_wb_cleanup_t *kmsg, int len) } sinfo->rx[chan].api_dcb_chain_end = NULL; sinfo->rx[chan].api_active = 0; - sinfo->rx[chan].api_wait = 0; } spin_unlock_irqrestore(&sinfo->lock, flags); @@ -7055,6 +7113,11 @@ bkn_handle_cmd_req(kcom_msg_t *kmsg, int len) /* Detach kernel module */ len = bkn_knet_detach(&kmsg->detach, len); break; + case KCOM_M_REPROBE: + DBG_CMD(("KCOM_M_REPROBE\n")); + /* Reprobe device */ + len = bkn_knet_reprobe(&kmsg->reprobe, len); + break; case KCOM_M_NETIF_CREATE: DBG_CMD(("KCOM_M_NETIF_CREATE\n")); /* Create network interface */ @@ -7174,8 +7237,7 @@ bkn_get_next_dma_event(kcom_msg_dma_info_t *kmsg) } DBG_INST(("%s dev %d evt_idx %d\n",__FUNCTION__, dev_evt, sinfo->evt_idx)); - evt = &_bkn_evt[sinfo->evt_idx]; - dev_no = last_dev_no = dev_evt; + dev_no = last_dev_no; while (1) { dev_no++; sinfo = bkn_sinfo_from_unit(dev_no); @@ -7204,6 +7266,7 @@ bkn_get_next_dma_event(kcom_msg_dma_info_t *kmsg) } if (dev_no == last_dev_no) { + evt = &_bkn_evt[sinfo->evt_idx]; DBG_INST(("wait queue index %d\n",sinfo->evt_idx)); wait_event_interruptible(evt->evt_wq, evt->evt_wq_get != evt->evt_wq_put); diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/lkm.h b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/lkm.h index d1977076850b..a48cb540adaf 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/lkm.h +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/lkm.h @@ -62,6 +62,9 @@ #include #include #include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,11,0) +#include +#endif #include #include From 38ef219b7cb39db27c287af555dd688b0ac07a43 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Fri, 3 May 2019 08:22:33 +0000 Subject: [PATCH 22/88] [broadcom]: update broadcom sai to 3.5.2.1 --- platform/broadcom/sai.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index e129409f8960..eaf7afba0a21 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.3.5.4m-1_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.3/libsaibcm_3.3.5.4m-1_amd64.deb?sv=2015-04-05&sr=b&sig=5al8VoedFxE3anjfi4BwLLX2YqU%2BByafkZgEY85TnN8%3D&se=2032-12-17T20%3A59%3A24Z&sp=r" +BRCM_SAI = libsaibcm_3.5.2.1_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5s/libsaibcm_3.5.2.1_amd64.deb?sv=2015-04-05&sr=b&sig=VsOGePXPU9TtxXxQTkLfM%2FIzW6BL8q6RxP6QputuuEU%3D&se=2156-03-28T05%3A37%3A02Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.3.5.4m-1_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.5.2.1_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.3/libsaibcm-dev_3.3.5.4m-1_amd64.deb?sv=2015-04-05&sr=b&sig=ROLknrDMqOGeGfOXu8%2BUVl8yKKDyxsq3swiUtR7n63A%3D&se=2032-12-17T20%3A58%3A59Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5s/libsaibcm-dev_3.5.2.1_amd64.deb?sv=2015-04-05&sr=b&sig=3pWbROLKK5ZuVcAra%2BYo1pk4B0k1P3C76wVw4KiqOtY%3D&se=2156-03-28T05%3A35%3A35Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From 5e95e2753ed65758c116b337475397a7dc10d1eb Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Fri, 3 May 2019 09:15:54 +0000 Subject: [PATCH 23/88] [docker-brcm-syncd]: build brcm syncd from stretch Signed-off-by: Guohan Lu --- platform/broadcom/docker-syncd-brcm-rpc.mk | 3 +- platform/broadcom/docker-syncd-brcm.mk | 31 +++++++------------ .../broadcom/docker-syncd-brcm/Dockerfile.j2 | 2 +- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/platform/broadcom/docker-syncd-brcm-rpc.mk b/platform/broadcom/docker-syncd-brcm-rpc.mk index f875dcfb80be..bb31e82ef61d 100644 --- a/platform/broadcom/docker-syncd-brcm-rpc.mk +++ b/platform/broadcom/docker-syncd-brcm-rpc.mk @@ -10,8 +10,9 @@ $(DOCKER_SYNCD_BRCM_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSAIREDIS_DBG) endif $(DOCKER_SYNCD_BRCM_RPC)_FILES += $(DSSERVE) $(BCMCMD) -$(DOCKER_SYNCD_BRCM_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BRCM) +$(DOCKER_SYNCD_BRCM_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BASE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_BRCM_RPC) +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BRCM_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_BRCM_RPC) endif diff --git a/platform/broadcom/docker-syncd-brcm.mk b/platform/broadcom/docker-syncd-brcm.mk index ab2bed9f5b77..29727dbb2260 100644 --- a/platform/broadcom/docker-syncd-brcm.mk +++ b/platform/broadcom/docker-syncd-brcm.mk @@ -1,27 +1,18 @@ # docker image for brcm syncd -DOCKER_SYNCD_BRCM = docker-syncd-brcm.gz -$(DOCKER_SYNCD_BRCM)_PATH = $(PLATFORM_PATH)/docker-syncd-brcm -$(DOCKER_SYNCD_BRCM)_DEPENDS += $(SYNCD) -ifeq ($(INSTALL_DEBUG_TOOLS), y) -$(DOCKER_SYNCD_BRCM)_DEPENDS += $(SYNCD_DBG) \ +DOCKER_SYNCD_PLATFORM_CODE = brcm +include $(PLATFORM_PATH)/../template/docker-syncd-base.mk + +$(DOCKER_SYNCD_BASE)_DEPENDS += $(SYNCD) +$(DOCKER_SYNCD_BASE)_FILES += $(DSSERVE) $(BCMCMD) + +$(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSWSSCOMMON_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) -endif -$(DOCKER_SYNCD_BRCM)_FILES += $(DSSERVE) $(BCMCMD) -$(DOCKER_SYNCD_BRCM)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) -SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_BRCM) -ifneq ($(ENABLE_SYNCD_RPC),y) -SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_BRCM) -endif -$(DOCKER_SYNCD_BRCM)_CONTAINER_NAME = syncd -$(DOCKER_SYNCD_BRCM)_RUN_OPT += --net=host --privileged -t -$(DOCKER_SYNCD_BRCM)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf -$(DOCKER_SYNCD_BRCM)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd -$(DOCKER_SYNCD_BRCM)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro -$(DOCKER_SYNCD_BRCM)_RUN_OPT += -v /host/warmboot:/var/warmboot +$(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_BRCM)_BASE_IMAGE_FILES += bcmcmd:/usr/bin/bcmcmd -$(DOCKER_SYNCD_BRCM)_BASE_IMAGE_FILES += bcmsh:/usr/bin/bcmsh +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += bcmcmd:/usr/bin/bcmcmd +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += bcmsh:/usr/bin/bcmsh diff --git a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 index 78c296d96d92..328f698fdb6d 100755 --- a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 +++ b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine +FROM docker-config-engine-stretch ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf From 8080695ecf91ba008a48830a7c4a549a380e76e6 Mon Sep 17 00:00:00 2001 From: lguohan Date: Mon, 6 May 2019 07:19:36 -0700 Subject: [PATCH 24/88] [docker-{sonic,syncd}-vs]: upgrade {sonic,syncd}-vs docker to stretch (#2865) * [docker-{sonic,syncd}-vs]: upgrade sonic-vs and syncd-vs docker to stretch * remove python-click 6.6 Signed-off-by: Guohan Lu --- Makefile | 2 +- Makefile.work | 1 + platform/vs/docker-sonic-vs.mk | 6 ++--- platform/vs/docker-sonic-vs/Dockerfile.j2 | 10 ++++---- platform/vs/docker-syncd-vs.mk | 28 +++++++++-------------- platform/vs/docker-syncd-vs/Dockerfile.j2 | 2 +- slave.mk | 4 ++-- sonic-slave-stretch/Dockerfile | 7 ++++++ 8 files changed, 31 insertions(+), 29 deletions(-) diff --git a/Makefile b/Makefile index 4bc42cd3728c..f3908ce55c4c 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ NOSTRETCH ?= 0 %:: @echo "+++ --- Making $@ --- +++" ifeq ($(NOSTRETCH), 0) - BLDENV=stretch make -f Makefile.work stretch + BLDENV=stretch EXTRA_STRETCH_TARGETS=$(notdir $@) make -f Makefile.work stretch endif make -f Makefile.work $@ diff --git a/Makefile.work b/Makefile.work index ae15b1ec906d..95e7a2af444e 100644 --- a/Makefile.work +++ b/Makefile.work @@ -123,6 +123,7 @@ SONIC_BUILD_INSTRUCTION := make \ HTTP_PROXY=$(http_proxy) \ HTTPS_PROXY=$(https_proxy) \ SONIC_ENABLE_SYSTEM_TELEMETRY=$(ENABLE_SYSTEM_TELEMETRY) \ + EXTRA_STRETCH_TARGETS=$(EXTRA_STRETCH_TARGETS) \ $(SONIC_OVERRIDE_BUILD_VARS) .PHONY: sonic-slave-build sonic-slave-bash init reset diff --git a/platform/vs/docker-sonic-vs.mk b/platform/vs/docker-sonic-vs.mk index 79f4fe0cddba..718534231689 100644 --- a/platform/vs/docker-sonic-vs.mk +++ b/platform/vs/docker-sonic-vs.mk @@ -9,8 +9,7 @@ $(DOCKER_SONIC_VS)_DEPENDS += $(SWSS) \ $(PYTHON_SWSSCOMMON) \ $(LIBTEAMDCT) \ $(LIBTEAM_UTILS) \ - $(SONIC_DEVICE_DATA) \ - $(IPROUTE2) + $(SONIC_DEVICE_DATA) $(DOCKER_SONIC_VS)_PYTHON_DEBS += $(SONIC_UTILS) @@ -36,5 +35,6 @@ $(DOCKER_SONIC_VS)_FILES += $(CONFIGDB_LOAD_SCRIPT) \ $(QOS_CONFIG_TEMPLATE) \ $(SONIC_VERSION) -$(DOCKER_SONIC_VS)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) +$(DOCKER_SONIC_VS)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) SONIC_DOCKER_IMAGES += $(DOCKER_SONIC_VS) +SONIC_STRETCH_DOCKERS += $(DOCKER_SONIC_VS) diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index dcb62f95ae55..34c33a99d05f 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine +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 @@ -6,6 +6,7 @@ RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%s ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get install -y gnupg COPY ["sonic-dev.gpg.key", "/etc/apt/"] RUN apt-key add /etc/apt/sonic-dev.gpg.key RUN echo "deb http://packages.microsoft.com/repos/sonic-dev/ jessie main" >> /etc/apt/sources.list @@ -21,12 +22,11 @@ RUN apt-get install -y net-tools \ python-ply \ libqt5core5a \ libqt5network5 \ - libboost-program-options1.55.0 \ - libboost-system1.55.0 \ - libboost-thread1.55.0 \ + libboost-program-options1.62.0 \ + libboost-system1.62.0 \ + libboost-thread1.62.0 \ libgmp10 \ libjudydebian1 \ - libnanomsg0 \ libdaemon0 \ libjansson4 \ libjemalloc1 \ diff --git a/platform/vs/docker-syncd-vs.mk b/platform/vs/docker-syncd-vs.mk index 66d2aa9faed5..15d94c5854d2 100644 --- a/platform/vs/docker-syncd-vs.mk +++ b/platform/vs/docker-syncd-vs.mk @@ -1,20 +1,14 @@ # docker image for vs syncd -DOCKER_SYNCD_VS = docker-syncd-vs.gz -$(DOCKER_SYNCD_VS)_PATH = $(PLATFORM_PATH)/docker-syncd-vs -$(DOCKER_SYNCD_VS)_DEPENDS += $(SYNCD_VS) -ifeq ($(INSTALL_DEBUG_TOOLS), y) -$(DOCKER_SYNCD_VS)_DEPENDS += $(SYNCD_VS_DBG) \ - $(LIBSWSSCOMMON_DBG) \ - $(LIBSAIREDIS_DBG) \ - $(LIBSAIVS_DBG) -endif -$(DOCKER_SYNCD_VS)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) -SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_VS) -SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_VS) +DOCKER_SYNCD_PLATFORM_CODE = vs +include $(PLATFORM_PATH)/../template/docker-syncd-base.mk -$(DOCKER_SYNCD_VS)_CONTAINER_NAME = syncd -$(DOCKER_SYNCD_VS)_RUN_OPT += --net=host --privileged -t -$(DOCKER_SYNCD_VS)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf -$(DOCKER_SYNCD_VS)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro -$(DOCKER_SYNCD_VS)_RUN_OPT += -v /host/warmboot:/var/warmboot +$(DOCKER_SYNCD_BASE)_DEPENDS += $(SYNCD_VS) + +$(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_VS_DBG) \ + $(LIBSWSSCOMMON_DBG) \ + $(LIBSAIMETADATA_DBG) \ + $(LIBSAIREDIS_DBG) \ + $(LIBSAIVS_DBG) + +$(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/platform/vs/docker-syncd-vs/Dockerfile.j2 b/platform/vs/docker-syncd-vs/Dockerfile.j2 index 7bef89fe57b5..6c5e90fa877b 100644 --- a/platform/vs/docker-syncd-vs/Dockerfile.j2 +++ b/platform/vs/docker-syncd-vs/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine +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 diff --git a/slave.mk b/slave.mk index 135667f4a47d..0e6e2adcb37f 100644 --- a/slave.mk +++ b/slave.mk @@ -473,11 +473,11 @@ SONIC_TARGET_LIST += $(addprefix $(TARGET_PATH)/, $(SONIC_SIMPLE_DOCKER_IMAGES)) # Build stretch docker images only in stretch slave docker, # jessie docker images only in jessie slave docker -DOCKER_IMAGES_FOR_INSTALLERS := $(sort $(foreach installer,$(SONIC_INSTALLERS),$($(installer)_DOCKERS))) ifeq ($(BLDENV),stretch) + DOCKER_IMAGES_FOR_INSTALLERS := $(sort $(foreach installer,$(SONIC_INSTALLERS),$($(installer)_DOCKERS))) DOCKER_IMAGES := $(SONIC_STRETCH_DOCKERS) DOCKER_DBG_IMAGES := $(SONIC_STRETCH_DBG_DOCKERS) - SONIC_STRETCH_DOCKERS_FOR_INSTALLERS = $(filter $(SONIC_STRETCH_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS)) + SONIC_STRETCH_DOCKERS_FOR_INSTALLERS = $(filter $(SONIC_STRETCH_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS) $(EXTRA_STRETCH_TARGETS)) SONIC_STRETCH_DBG_DOCKERS_FOR_INSTALLERS = $(filter $(SONIC_STRETCH_DBG_DOCKERS), $(patsubst %.gz,%-$(DBG_IMAGE_MARK).gz, $(SONIC_STRETCH_DOCKERS_FOR_INSTALLERS))) else DOCKER_IMAGES := $(filter-out $(SONIC_STRETCH_DOCKERS), $(SONIC_DOCKER_IMAGES)) diff --git a/sonic-slave-stretch/Dockerfile b/sonic-slave-stretch/Dockerfile index 7a1762dfd111..ac41f1e77c81 100644 --- a/sonic-slave-stretch/Dockerfile +++ b/sonic-slave-stretch/Dockerfile @@ -262,6 +262,8 @@ RUN pip install --force-reinstall --upgrade jinja2>=2.10 # For templating RUN pip install j2cli +# Remove python-click 6.6 +RUN apt-get purge -y python-click # For sonic utilities testing RUN pip install click-default-group click natsort tabulate netifaces==0.10.7 fastentrypoints @@ -276,6 +278,11 @@ RUN pip3 install redis # For supervisor build RUN pip install meld3 mock +# For sonic-utilities build +RUN pip install mockredispy==2.9.3 +RUN pip install pytest-runner==4.4 +RUN pip install setuptools==40.8.0 + # Install dependencies for isc-dhcp-relay build RUN apt-get -y build-dep isc-dhcp From f35daa7694368db6ba91e00d322d2700f913fc82 Mon Sep 17 00:00:00 2001 From: lguohan Date: Tue, 7 May 2019 23:40:40 -0700 Subject: [PATCH 25/88] [frr]: change frr as default sonic routing stack (#2863) * [frr]: change frr as default sonic routing stack * fix quagga configuration * [vstest]: fix bgp test for frr * [vstest]: skip bgp/test_invalid_nexthop.py for frr Signed-off-by: Guohan Lu --- platform/vs/docker-sonic-vs/Dockerfile.j2 | 4 ++++ platform/vs/docker-sonic-vs/supervisord.conf | 4 ++-- platform/vs/tests/bgp/test_gr_livelock.py | 4 ++-- platform/vs/tests/bgp/test_invalid_nexthop.py | 6 ++++-- platform/vs/tests/bgp/test_no_export.py | 2 +- rules/config | 2 +- 6 files changed, 14 insertions(+), 8 deletions(-) diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 34c33a99d05f..2285c1f3e0fe 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -106,8 +106,12 @@ COPY ["files/sonic_version.yml", "/etc/sonic/"] RUN mv /usr/sbin/tcpdump /usr/bin/tcpdump RUN echo "docker-sonic-vs" > /etc/hostname +RUN mkdir -p /etc/quagga RUN touch /etc/quagga/zebra.conf +# disable integrated vtysh config +RUN rm /etc/frr/frr.conf + # Create /var/warmboot/teamd folder for teammgrd RUN mkdir -p /var/warmboot/teamd diff --git a/platform/vs/docker-sonic-vs/supervisord.conf b/platform/vs/docker-sonic-vs/supervisord.conf index 5b637e507053..250739153234 100644 --- a/platform/vs/docker-sonic-vs/supervisord.conf +++ b/platform/vs/docker-sonic-vs/supervisord.conf @@ -100,7 +100,7 @@ stdout_logfile=syslog stderr_logfile=syslog [program:zebra] -command=/usr/lib/quagga/zebra -A 127.0.0.1 +command=/usr/lib/frr/zebra -A 127.0.0.1 priority=13 autostart=false autorestart=false @@ -108,7 +108,7 @@ stdout_logfile=syslog stderr_logfile=syslog [program:bgpd] -command=/usr/lib/quagga/bgpd -A 127.0.0.1 -F +command=/usr/lib/frr/bgpd -A 127.0.0.1 priority=14 autostart=false autorestart=false diff --git a/platform/vs/tests/bgp/test_gr_livelock.py b/platform/vs/tests/bgp/test_gr_livelock.py index 8ba2b4cc7214..f269f1e8eee4 100644 --- a/platform/vs/tests/bgp/test_gr_livelock.py +++ b/platform/vs/tests/bgp/test_gr_livelock.py @@ -80,7 +80,7 @@ def test_gr_livelock(dvs, testlog): # update exabgp to version 4.0.10 dvs.servers[0].runcmd("pip install 'exabgp==4.0.10' --force-reinstall ") # - dvs.copy_file("/etc/quagga/", "bgp/files/gr_livelock/bgpd.conf") + dvs.copy_file("/etc/frr/", "bgp/files/gr_livelock/bgpd.conf") dvs.servers[0].runcmd("pkill exabgp") # In case previous test didn't stop exa dvs.runcmd("supervisorctl stop bgpd") time.sleep(5) @@ -115,7 +115,7 @@ def test_gr_livelock(dvs, testlog): run_exacli(dvs, 0, 'shutdown') p1 = p1.wait() - # Wait until quagga thinks that 1st neighbor was shut down + # Wait until frr thinks that 1st neighbor was shut down time.sleep(300) # Start the 1st neighbor again with graceful restart enabled diff --git a/platform/vs/tests/bgp/test_invalid_nexthop.py b/platform/vs/tests/bgp/test_invalid_nexthop.py index eb4f6c212e02..9458ecdeee5c 100644 --- a/platform/vs/tests/bgp/test_invalid_nexthop.py +++ b/platform/vs/tests/bgp/test_invalid_nexthop.py @@ -3,10 +3,12 @@ import re import time import json +import pytest +@pytest.mark.skip(reason="not working for frr") def test_InvalidNexthop(dvs, testlog): - dvs.copy_file("/etc/quagga/", "bgp/files/invalid_nexthop/bgpd.conf") + dvs.copy_file("/etc/frr/", "bgp/files/invalid_nexthop/bgpd.conf") dvs.runcmd("supervisorctl start bgpd") dvs.runcmd("ip addr add fc00::1/126 dev Ethernet0") dvs.runcmd("ifconfig Ethernet0 up") @@ -22,7 +24,7 @@ def test_InvalidNexthop(dvs, testlog): time.sleep(10) - (exit_code, output) = dvs.runcmd(["vtysh", "-c", "show ipv6 bgp"]) + (exit_code, output) = dvs.runcmd(["vtysh", "-c", "show bgp ipv6"]) p.terminate() p = p.wait() diff --git a/platform/vs/tests/bgp/test_no_export.py b/platform/vs/tests/bgp/test_no_export.py index f2d06f31cd72..efbc5331fef8 100644 --- a/platform/vs/tests/bgp/test_no_export.py +++ b/platform/vs/tests/bgp/test_no_export.py @@ -6,7 +6,7 @@ def test_bounce(dvs, testlog): dvs.servers[0].runcmd("pkill -f exabgp") - dvs.copy_file("/etc/quagga/", "bgp/files/no_export/bgpd.conf") + dvs.copy_file("/etc/frr/", "bgp/files/no_export/bgpd.conf") dvs.runcmd("supervisorctl start bgpd") dvs.runcmd("ip addr add 10.0.0.0/31 dev Ethernet0") dvs.runcmd("ifconfig Ethernet0 up") diff --git a/rules/config b/rules/config index f72573b1388a..c5213bddd409 100644 --- a/rules/config +++ b/rules/config @@ -51,7 +51,7 @@ DEFAULT_PASSWORD = YourPaSsWoRd # SONIC_ROUTING_STACK - specify the routing-stack being elected to drive SONiC's control-plane. # Supported routing stacks on SONiC are: # routing-stacks: quagga, frr. -SONIC_ROUTING_STACK = quagga +SONIC_ROUTING_STACK = frr # ENABLE_SYNCD_RPC - build docker-syncd with rpc packages for testing purposes. # Uncomment to enable: From 584ed989c81fc75ca4d19280864500c9514acd73 Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Wed, 8 May 2019 15:41:07 +0800 Subject: [PATCH 26/88] [device][accton]Add fan monitor for as7816-64x (#2859) * catch signal SIGINT and SIGTERM to set all fans full-speed before end fan monitor. Signed-off-by: roy_lee * Add fan_control monitor for as7816-64x. Signed-off-by: roy_lee * Fix typo. Signed-off-by: roy_lee * Correct typo and duty setting after verified. Signed-off-by: roy_lee --- .../as5712-54x/utils/accton_as5712_monitor.py | 10 + .../as7312-54x/setup.py | 2 +- .../as7312-54x/utils/accton_as7312_monitor.py | 12 +- .../as7816-64x/classes/fanutil.py | 244 ++++++++++++++++++ .../as7816-64x/classes/thermalutil.py | 128 +++++++++ .../service/as7816-platform-init.service | 6 +- .../as7816-64x/utils/accton_as7816_monitor.py | 163 ++++++++++++ 7 files changed, 560 insertions(+), 5 deletions(-) create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_monitor.py diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py index 84ab2d83bab4..d7b372145827 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py @@ -33,6 +33,7 @@ import types import time # this is only being used as part of the example import traceback + import signal from tabulate import tabulate from as5712_54x.fanutil import FanUtil from as5712_54x.thermalutil import ThermalUtil @@ -42,6 +43,7 @@ # Deafults VERSION = '1.0' FUNCTION_NAME = 'accton_as5712_monitor' +DUTY_MAX = 100 global log_file global log_level @@ -166,6 +168,12 @@ def manage_fans(self): return True +def handler(signum, frame): + fan = FanUtil() + logging.debug('INFO:Cause signal %d, set fan speed max.', signum) + fan.set_fan_duty_cycle(fan.get_idx_fan_start(), DUTY_MAX) + sys.exit(0) + def main(argv): log_file = '%s.log' % FUNCTION_NAME log_level = logging.INFO @@ -184,6 +192,8 @@ def main(argv): elif opt in ('-l', '--lfile'): log_file = arg + signal.signal(signal.SIGINT, handler) + signal.signal(signal.SIGTERM, handler) monitor = accton_as5712_monitor(log_file, log_level) # Loop forever, doing something useful hopefully: diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/setup.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/setup.py index f0518d07689d..5e862ce15048 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/setup.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/setup.py @@ -1,4 +1,4 @@ -#!/usr/bin/env pytho +#!/usr/bin/env python import os import sys diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_monitor.py index bdab0d4b8bff..19d7470515f9 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_monitor.py @@ -34,6 +34,7 @@ import types import time # this is only being used as part of the example import traceback + import signal from tabulate import tabulate from as7312_54x.fanutil import FanUtil from as7312_54x.thermalutil import ThermalUtil @@ -43,6 +44,7 @@ # Deafults VERSION = '1.0' FUNCTION_NAME = 'accton_as7312_monitor' +DUTY_MAX = 100 global log_file global log_level @@ -98,7 +100,7 @@ def __init__(self, log_file, log_level): logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level) def manage_fans(self): - max_duty = 100 + max_duty = DUTY_MAX fan_policy_f2b = { 0: [32, 0, 105000], 1: [50, 105000, 120000], @@ -179,6 +181,12 @@ def manage_fans(self): fan.set_fan_duty_cycle(new_duty_cycle) return True +def handler(signum, frame): + fan = FanUtil() + logging.debug('INFO:Cause signal %d, set fan speed max.', signum) + fan.set_fan_duty_cycle(DUTY_MAX) + sys.exit(0) + def main(argv): log_file = '%s.log' % FUNCTION_NAME log_level = logging.INFO @@ -197,6 +205,8 @@ def main(argv): elif opt in ('-l', '--lfile'): log_file = arg + signal.signal(signal.SIGINT, handler) + signal.signal(signal.SIGTERM, handler) monitor = accton_as7312_monitor(log_file, log_level) # Loop forever, doing something useful hopefully: diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/classes/fanutil.py index e69de29bb2d1..42ccb17eaa06 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/classes/fanutil.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/classes/fanutil.py @@ -0,0 +1,244 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# 1/10/2018: Jostar modify for as7716_32 +# 5/02/2019: Roy Lee modify for as7816_64x +# ------------------------------------------------------------------ + +try: + import time + import logging + from collections import namedtuple +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + + +class FanUtil(object): + """Platform-specific FanUtil class""" + + FAN_NUM_ON_MAIN_BROAD = 4 + FAN_NUM_1_IDX = 1 + FAN_NUM_2_IDX = 2 + FAN_NUM_3_IDX = 3 + FAN_NUM_4_IDX = 4 + + FAN_NODE_NUM_OF_MAP = 2 + FAN_NODE_FAULT_IDX_OF_MAP = 1 + #FAN_NODE_SPEED_IDX_OF_MAP = 2 + FAN_NODE_DIR_IDX_OF_MAP = 2 + #FAN_NODE_DUTY_IDX_OF_MAP = 4 + #FANR_NODE_FAULT_IDX_OF_MAP = 5 + + BASE_VAL_PATH = '/sys/bus/i2c/devices/17-0068/{0}' + FAN_DUTY_PATH = '/sys/bus/i2c/devices/17-0068/fan_duty_cycle_percentage' + + #logfile = '' + #loglevel = logging.INFO + + """ Dictionary where + key1 = fan id index (integer) starting from 1 + key2 = fan node index (interger) starting from 1 + value = path to fan device file (string) """ + _fan_to_device_path_mapping = {} + +#fan1_direction +#fan1_fault +#fan1_present + + #(FAN_NUM_2_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan2_duty_cycle_percentage', + _fan_to_device_node_mapping = { + (FAN_NUM_1_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan1_fault', + (FAN_NUM_1_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan1_direction', + (FAN_NUM_2_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan2_fault', + (FAN_NUM_2_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan2_direction', + + (FAN_NUM_3_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan3_fault', + (FAN_NUM_3_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan3_direction', + + (FAN_NUM_4_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan4_fault', + (FAN_NUM_4_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan4_direction', + } + + def _get_fan_to_device_node(self, fan_num, node_num): + return self._fan_to_device_node_mapping[(fan_num, node_num)] + + def _get_fan_node_val(self, fan_num, node_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num:%d', fan_num) + return None + + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + logging.debug('GET. Parameter error. node_num:%d', node_num) + return None + + device_path = self.get_fan_to_device_path(fan_num, node_num) + + try: + val_file = open(device_path, 'r') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return int(content) + + def _set_fan_node_val(self, fan_num, node_num, val): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num:%d', fan_num) + return None + + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + logging.debug('GET. Parameter error. node_num:%d', node_num) + return None + + content = str(val) + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + device_path = self.get_fan_to_device_path(fan_num, node_num) + try: + val_file = open(device_path, 'w') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + val_file.write(content) + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return True + + def __init__(self): + fan_path = self.BASE_VAL_PATH + + for fan_num in range(self.FAN_NUM_1_IDX, self.FAN_NUM_ON_MAIN_BROAD+1): + for node_num in range(self.FAN_NODE_FAULT_IDX_OF_MAP, self.FAN_NODE_NUM_OF_MAP+1): + self._fan_to_device_path_mapping[(fan_num, node_num)] = fan_path.format( + self._fan_to_device_node_mapping[(fan_num, node_num)]) + + def get_num_fans(self): + return self.FAN_NUM_ON_MAIN_BROAD + + def get_idx_fan_start(self): + return self.FAN_NUM_1_IDX + + def get_num_nodes(self): + return self.FAN_NODE_NUM_OF_MAP + + def get_idx_node_start(self): + return self.FAN_NODE_FAULT_IDX_OF_MAP + + def get_size_node_map(self): + return len(self._fan_to_device_node_mapping) + + def get_size_path_map(self): + return len(self._fan_to_device_path_mapping) + + def get_fan_to_device_path(self, fan_num, node_num): + return self._fan_to_device_path_mapping[(fan_num, node_num)] + + def get_fan_fault(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_FAULT_IDX_OF_MAP) + + #def get_fan_speed(self, fan_num): + # return self._get_fan_node_val(fan_num, self.FAN_NODE_SPEED_IDX_OF_MAP) + + def get_fan_dir(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_DIR_IDX_OF_MAP) + + def get_fan_duty_cycle(self): + #duty_path = self.FAN_DUTY_PATH + try: + val_file = open(self.FAN_DUTY_PATH) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = val_file.readline().rstrip() + val_file.close() + + return int(content) + #self._get_fan_node_val(fan_num, self.FAN_NODE_DUTY_IDX_OF_MAP) +#static u32 reg_val_to_duty_cycle(u8 reg_val) +#{ +# reg_val &= FAN_DUTY_CYCLE_REG_MASK; +# return ((u32)(reg_val+1) * 625 + 75)/ 100; +#} +# + def set_fan_duty_cycle(self, val): + + try: + fan_file = open(self.FAN_DUTY_PATH, 'r+') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + fan_file.write(str(val)) + fan_file.close() + return True + + #def get_fanr_fault(self, fan_num): + # return self._get_fan_node_val(fan_num, self.FANR_NODE_FAULT_IDX_OF_MAP) + + def get_fanr_speed(self, fan_num): + return self._get_fan_node_val(fan_num, self.FANR_NODE_SPEED_IDX_OF_MAP) + + def get_fan_status(self, fan_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num, %d', fan_num) + return None + + if self.get_fan_fault(fan_num) is not None and self.get_fan_fault(fan_num) > 0: + logging.debug('GET. FAN fault. fan_num, %d', fan_num) + return False + + #if self.get_fanr_fault(fan_num) is not None and self.get_fanr_fault(fan_num) > 0: + # logging.debug('GET. FANR fault. fan_num, %d', fan_num) + # return False + + return True + +#def main(): +# fan = FanUtil() +# +# print 'get_size_node_map : %d' % fan.get_size_node_map() +# print 'get_size_path_map : %d' % fan.get_size_path_map() +# for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): +# for y in range(fan.get_idx_node_start(), fan.get_num_nodes()+1): +# print fan.get_fan_to_device_path(x, y) +# +#if __name__ == '__main__': +# main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/classes/thermalutil.py b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/classes/thermalutil.py index e69de29bb2d1..65e872c6beb8 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/classes/thermalutil.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/classes/thermalutil.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# 1/10/2018:Jostar modify for as7716_32x +# 5/02/2019: Roy Lee modify for as7816_64x +# ------------------------------------------------------------------ + +try: + import time + import logging + import glob + from collections import namedtuple +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + + +class ThermalUtil(object): + """Platform-specific ThermalUtil class""" + + THERMAL_NUM_ON_MAIN_BROAD = 6 + THERMAL_NUM_1_IDX = 1 + BASE_VAL_PATH = '/sys/bus/i2c/devices/{0}-00{1}/hwmon/hwmon*/temp1_input' + + """ Dictionary where + key1 = thermal id index (integer) starting from 1 + value = path to fan device file (string) """ + _thermal_to_device_path_mapping = {} + + _thermal_to_device_node_mapping = [ + ['18', '48'], + ['18', '49'], + ['18', '4a'], + ['18', '4b'], + ['17', '4d'], + ['17', '4e'], + ] + + def __init__(self): + thermal_path = self.BASE_VAL_PATH + + for x in range(self.THERMAL_NUM_ON_MAIN_BROAD): + self._thermal_to_device_path_mapping[x+1] = thermal_path.format( + self._thermal_to_device_node_mapping[x][0], + self._thermal_to_device_node_mapping[x][1]) + + def _get_thermal_node_val(self, thermal_num): + if thermal_num < self.THERMAL_NUM_1_IDX or thermal_num > self.THERMAL_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. thermal_num, %d', thermal_num) + return None + + device_path = self.get_thermal_to_device_path(thermal_num) + for filename in glob.glob(device_path): + try: + val_file = open(filename, 'r') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return int(content) + + + def get_num_thermals(self): + return self.THERMAL_NUM_ON_MAIN_BROAD + + def get_idx_thermal_start(self): + return self.THERMAL_NUM_1_IDX + + def get_size_node_map(self): + return len(self._thermal_to_device_node_mapping) + + def get_size_path_map(self): + return len(self._thermal_to_device_path_mapping) + + def get_thermal_to_device_path(self, thermal_num): + return self._thermal_to_device_path_mapping[thermal_num] + + def get_thermal_2_val(self): + return self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) + + def get_thermal_temp(self): + sum = 0 + o = [] + for x in range(self.THERMAL_NUM_ON_MAIN_BROAD): + sum += self._get_thermal_node_val(x+1) + avg = sum/self.THERMAL_NUM_ON_MAIN_BROAD + avg = (avg/1000)*1000 #round down for hysteresis. + return avg + +#def main(): +# thermal = ThermalUtil() +# +# print 'get_size_node_map : %d' % thermal.get_size_node_map() +# print 'get_size_path_map : %d' % thermal.get_size_path_map() +# for x in range(thermal.get_idx_thermal_start(), thermal.get_num_thermals()+1): +# print thermal.get_thermal_to_device_path(x) +# +#if __name__ == '__main__': +# main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/service/as7816-platform-init.service b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/service/as7816-platform-init.service index c1ba30092f1d..486ed74f8243 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/service/as7816-platform-init.service +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/service/as7816-platform-init.service @@ -1,12 +1,12 @@ [Unit] Description=Accton AS7816-64X Platform initialization service Before=pmon.service +After=sysinit.target DefaultDependencies=no [Service] -Type=oneshot -ExecStart=/usr/local/bin/accton_as7816_util.py install -ExecStop=/usr/local/bin/accton_as7816_util.py clean +ExecStartPre=/usr/local/bin/accton_as7816_util.py install +ExecStart=/usr/local/bin/accton_as7816_monitor.py RemainAfterExit=yes [Install] diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_monitor.py new file mode 100755 index 000000000000..3d9f6fc3ce5e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_monitor.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# 1/10/2018: Jostar modify for as7716_32 +# 5/02/2019: Roy Lee modify for as7816_64x +# ------------------------------------------------------------------ + +try: + import os + import sys, getopt + import subprocess + import click + import imp + import logging + import logging.config + import types + import time # this is only being used as part of the example + import traceback + import signal + from tabulate import tabulate + from as7816_64x.fanutil import FanUtil + from as7816_64x.thermalutil import ThermalUtil +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + +# Deafults +VERSION = '1.0' +FUNCTION_NAME = 'accton_as7816_monitor' +DUTY_MAX = 100 +DUTY_DEF = 40 + +global log_file +global log_level + + +# Make a class we can use to capture stdout and sterr in the log +class accton_as7816_monitor(object): + # static temp var + _ori_temp = 0 + _new_perc = 0 + _ori_perc = 0 + + def __init__(self, log_file, log_level): + """Needs a logger and a logger level.""" + # set up logging to file + logging.basicConfig( + filename=log_file, + filemode='w', + level=log_level, + format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', + datefmt='%H:%M:%S' + ) + + # set up logging to console + if log_level == logging.DEBUG: + console = logging.StreamHandler() + console.setLevel(log_level) + formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) + + logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level) + + def manage_fans(self): + max_duty = DUTY_MAX + fan_policy = { + 0: [52, 0, 43000], + 1: [63, 43000, 46000], + 2: [75, 46000, 52000], + 3: [88, 52000, 57000], + 4: [max_duty, 57000, sys.maxsize], + } + + thermal = ThermalUtil() + fan = FanUtil() + for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): + fan_status = fan.get_fan_status(x) + if fan_status is None: + logging.debug('INFO. SET new_perc to %d (FAN stauts is None. fan_num:%d)', max_duty, x) + return False + if fan_status is False: + logging.debug('INFO. SET new_perc to %d (FAN fault. fan_num:%d)', max_duty, x) + fan.set_fan_duty_cycle(max_duty) + return True + #logging.debug('INFO. fan_status is True (fan_num:%d)', x) + + #Find if current duty matched any of define duty. + #If not, set it to highest one. + cur_duty_cycle = fan.get_fan_duty_cycle() + new_duty_cycle = DUTY_DEF + for x in range(0, len(fan_policy)): + if cur_duty_cycle == fan_policy[x][0]: + break + if x == len(fan_policy) : + fan.set_fan_duty_cycle(fan_policy[0][0]) + cur_duty_cycle = max_duty + + #Decide fan duty by if sum of sensors falls into any of fan_policy{} + get_temp = thermal.get_thermal_temp() + for x in range(0, len(fan_policy)): + y = len(fan_policy) - x -1 #checked from highest + if get_temp > fan_policy[y][1] and get_temp < fan_policy[y][2] : + new_duty_cycle = fan_policy[y][0] + logging.debug('INFO. Sum of temp %d > %d , new_duty_cycle=%d', get_temp, fan_policy[y][1], new_duty_cycle) + + logging.debug('INFO. Final duty_cycle=%d', new_duty_cycle) + if(new_duty_cycle != cur_duty_cycle): + fan.set_fan_duty_cycle(new_duty_cycle) + return True + +def handler(signum, frame): + fan = FanUtil() + logging.debug('INFO:Cause signal %d, set fan speed max.', signum) + fan.set_fan_duty_cycle(DUTY_MAX) + sys.exit(0) + +def main(argv): + log_file = '%s.log' % FUNCTION_NAME + log_level = logging.INFO + if len(sys.argv) != 1: + try: + opts, args = getopt.getopt(argv,'hdl:',['lfile=']) + except getopt.GetoptError: + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + for opt, arg in opts: + if opt == '-h': + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + elif opt in ('-d', '--debug'): + log_level = logging.DEBUG + elif opt in ('-l', '--lfile'): + log_file = arg + + signal.signal(signal.SIGINT, handler) + signal.signal(signal.SIGTERM, handler) + monitor = accton_as7816_monitor(log_file, log_level) + + # Loop forever, doing something useful hopefully: + while True: + monitor.manage_fans() + time.sleep(10) + +if __name__ == '__main__': + main(sys.argv[1:]) From 8468f636d52fd9f97603b6373c877675fca6616d Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Wed, 8 May 2019 10:22:06 -0700 Subject: [PATCH 27/88] [swss] advance sonic-swss sub module head (#2872) Submodule src/sonic-swss ea4cba6..f8792d5: > [watermarkorch] only perform periodic clear if the polling is on (#781) > [arp] copy arp IO to cpu instead of trap and drop (#812) > fix bad parameter for gCrmOrch->incCrmAclUsedCounter in qosorch (#830) > [test_watermark] avoid watermark clear vs test random failure (#873) Signed-off-by: Ying Xie --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index ea4cba6ca6c5..f8792d577786 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit ea4cba6ca6c5da770edcf104ee8f826ca5f86466 +Subproject commit f8792d5777868f0d831c915c4b3e02a53579854d From 5fb185cd8330329bcab64b2fb0bc8c4da75127c2 Mon Sep 17 00:00:00 2001 From: lguohan Date: Wed, 8 May 2019 23:00:49 -0700 Subject: [PATCH 28/88] [docker-frr]: bring quagga docker features to frr docker (#2870) - use superviord to manage process in frr docker - intro separated configuration mode for frr - bring quagga configuration template to frr. Signed-off-by: Guohan Lu --- dockers/docker-fpm-frr/Dockerfile.j2 | 12 +- dockers/docker-fpm-frr/bgpcfgd | 65 ++++++++ dockers/docker-fpm-frr/bgpd.conf.j2 | 140 ++++++++++++++++++ dockers/docker-fpm-frr/config.sh | 20 --- dockers/docker-fpm-frr/daemons | 65 -------- dockers/docker-fpm-frr/daemons.conf | 1 - dockers/docker-fpm-frr/start.sh | 43 +++++- dockers/docker-fpm-frr/supervisord.conf | 68 +++++++++ dockers/docker-fpm-frr/zebra.conf.j2 | 78 ++++++++++ .../build_templates/sonic_debian_extension.j2 | 2 - 10 files changed, 394 insertions(+), 100 deletions(-) create mode 100755 dockers/docker-fpm-frr/bgpcfgd create mode 100644 dockers/docker-fpm-frr/bgpd.conf.j2 delete mode 100755 dockers/docker-fpm-frr/config.sh delete mode 100644 dockers/docker-fpm-frr/daemons delete mode 100644 dockers/docker-fpm-frr/daemons.conf create mode 100644 dockers/docker-fpm-frr/supervisord.conf create mode 100644 dockers/docker-fpm-frr/zebra.conf.j2 diff --git a/dockers/docker-fpm-frr/Dockerfile.j2 b/dockers/docker-fpm-frr/Dockerfile.j2 index df1de8ee82b7..fc57b7c0ef3c 100644 --- a/dockers/docker-fpm-frr/Dockerfile.j2 +++ b/dockers/docker-fpm-frr/Dockerfile.j2 @@ -36,12 +36,8 @@ RUN apt-get autoclean -y RUN apt-get autoremove -y RUN rm -rf /debs ~/.cache +COPY ["bgpcfgd", "start.sh", "/usr/bin/"] COPY ["*.j2", "/usr/share/sonic/templates/"] -COPY ["start.sh", "config.sh", "/usr/bin/"] -COPY ["daemons", "/etc/frr/"] -COPY ["daemons.conf", "/etc/frr/"] -COPY ["vtysh.conf", "/etc/frr/"] - -ENTRYPOINT /usr/bin/config.sh \ - && /usr/bin/start.sh \ - && /bin/bash +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] + +ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-fpm-frr/bgpcfgd b/dockers/docker-fpm-frr/bgpcfgd new file mode 100755 index 000000000000..012a766c20b9 --- /dev/null +++ b/dockers/docker-fpm-frr/bgpcfgd @@ -0,0 +1,65 @@ +#!/usr/bin/env python + +import sys +import redis +import subprocess +import syslog +from swsssdk import ConfigDBConnector + +class BGPConfigDaemon: + + def __init__(self): + self.config_db = ConfigDBConnector() + self.config_db.connect() + self.bgp_asn = self.config_db.get_entry('DEVICE_METADATA', 'localhost')['bgp_asn'] + self.bgp_neighbor = self.config_db.get_table('BGP_NEIGHBOR') + + def __run_command(self, command): +# print command + p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) + stdout = p.communicate()[0] + p.wait() + if p.returncode != 0: + syslog.syslog(syslog.LOG_ERR, '[bgp cfgd] command execution returned {}. Command: "{}", stdout: "{}"'.format(p.returncode, command, stdout)) + + def metadata_handler(self, key, data): + if key == 'localhost' and data.has_key('bgp_asn'): + if data['bgp_asn'] != self.bgp_asn: + syslog.syslog(syslog.LOG_INFO, '[bgp cfgd] ASN changed to {} from {}, restart BGP...'.format(data['bgp_asn'], self.bgp_asn)) + self.__run_command("supervisorctl restart start.sh") + self.__run_command("service quagga restart") + self.bgp_asn = data['bgp_asn'] + + def bgp_handler(self, key, data): + syslog.syslog(syslog.LOG_INFO, '[bgp cfgd] value for {} changed to {}'.format(key, data)) + if not data: + # Neighbor is deleted + command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'no neighbor {}'".format(self.bgp_asn, key) + self.__run_command(command) + self.bgp_neighbor.pop(key) + else: + command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'neighbor {} remote-as {}'".format(self.bgp_asn, key, data['asn']) + self.__run_command(command) + if data.has_key('name'): + command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c 'neighbor {} description {}'".format(self.bgp_asn, key, data['name']) + self.__run_command(command) + if data.has_key('admin_status'): + command_mod = 'no ' if data['admin_status'] == 'up' else '' + command = "vtysh -c 'configure terminal' -c 'router bgp {}' -c '{}neighbor {} shutdown'".format(self.bgp_asn, command_mod, key) + self.__run_command(command) + self.bgp_neighbor[key] = data + + def start(self): + self.config_db.subscribe('BGP_NEIGHBOR', + lambda table, key, data: self.bgp_handler(key, data)) + self.config_db.subscribe('DEVICE_METADATA', + lambda table, key, data: self.metadata_handler(key, data)) + self.config_db.listen() + + +def main(): + daemon = BGPConfigDaemon() + daemon.start() + +if __name__ == "__main__": + main() diff --git a/dockers/docker-fpm-frr/bgpd.conf.j2 b/dockers/docker-fpm-frr/bgpd.conf.j2 new file mode 100644 index 000000000000..4879736437bc --- /dev/null +++ b/dockers/docker-fpm-frr/bgpd.conf.j2 @@ -0,0 +1,140 @@ +! +{% block banner %} +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/quagga/bgpd.conf.j2 with config DB data +! file: bgpd.conf +! +{% endblock banner %} +! +{% block system_init %} +hostname {{ DEVICE_METADATA['localhost']['hostname'] }} +password zebra +log syslog informational +log facility local4 +! enable password {# {{ en_passwd }} TODO: param needed #} +{% endblock system_init %} +! +{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %} +{% block bgp_init %} +! +! bgp multiple-instance +! +route-map FROM_BGP_SPEAKER_V4 permit 10 +! +route-map TO_BGP_SPEAKER_V4 deny 10 +! +router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} + bgp log-neighbor-changes + bgp bestpath as-path multipath-relax + no bgp default ipv4-unicast + bgp graceful-restart restart-time 240 + bgp graceful-restart +{% for (name, prefix) in LOOPBACK_INTERFACE %} +{% if prefix | ipv4 and name == 'Loopback0' %} + bgp router-id {{ prefix | ip }} +{% endif %} +{% endfor %} +{# advertise loopback #} +{% for (name, prefix) in LOOPBACK_INTERFACE %} +{% if prefix | ipv4 and name == 'Loopback0' %} + network {{ prefix | ip }}/32 +{% elif prefix | ipv6 and name == 'Loopback0' %} + address-family ipv6 + network {{ prefix | ip }}/64 + exit-address-family +{% endif %} +{% endfor %} +{% endblock bgp_init %} +{% endif %} +{% block vlan_advertisement %} +{% for (name, prefix) in VLAN_INTERFACE %} +{% if prefix | ipv4 %} + network {{ prefix }} +{% elif prefix | ipv6 %} + address-family ipv6 + network {{ prefix }} + exit-address-family +{% endif %} +{% endfor %} +{% endblock vlan_advertisement %} +{% block bgp_sessions %} +{% for neighbor_addr, bgp_session in BGP_NEIGHBOR.iteritems() %} +{% if bgp_session['asn'] | int != 0 %} + neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} + neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} +{# set the bgp neighbor timers if they have not default values #} +{% if (bgp_session['keepalive'] is defined and bgp_session['keepalive'] | int != 60) + or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} + neighbor {{ neighbor_addr }} timers {{ bgp_session['keepalive'] }} {{ bgp_session['holdtime'] }} +{% endif %} +{% if bgp_session.has_key('admin_status') and bgp_session['admin_status'] == 'down' or not bgp_session.has_key('admin_status') and DEVICE_METADATA['localhost'].has_key('default_bgp_status') and DEVICE_METADATA['localhost']['default_bgp_status'] == 'down' %} + neighbor {{ neighbor_addr }} shutdown +{% endif %} +{% if neighbor_addr | ipv4 %} + address-family ipv4 +{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} + neighbor {{ neighbor_addr }} allowas-in 1 +{% endif %} + neighbor {{ neighbor_addr }} activate + neighbor {{ neighbor_addr }} soft-reconfiguration inbound + maximum-paths 64 + exit-address-family +{% endif %} +{% if neighbor_addr | ipv6 %} + address-family ipv6 +{% if DEVICE_METADATA['localhost']['type'] == 'ToRRouter' %} + neighbor {{ neighbor_addr }} allowas-in 1 +{% endif %} + neighbor {{ neighbor_addr }} activate + neighbor {{ neighbor_addr }} soft-reconfiguration inbound + maximum-paths 64 + exit-address-family +{% endif %} +{% endif %} +{% endfor %} +{% endblock bgp_sessions %} +{% block bgp_peers_with_range %} +{% if BGP_PEER_RANGE %} +{% for bgp_peer in BGP_PEER_RANGE.values() %} + neighbor {{ bgp_peer['name'] }} peer-group + neighbor {{ bgp_peer['name'] }} passive +{% if bgp_peer['peer_asn'] is defined %} + neighbor {{ bgp_peer['name'] }} remote-as {{ bgp_peer['peer_asn'] }} +{% else %} + neighbor {{ bgp_peer['name'] }} remote-as {{ deployment_id_asn_map[DEVICE_METADATA['localhost']['deployment_id']] }} +{% endif %} + neighbor {{ bgp_peer['name'] }} ebgp-multihop 255 + neighbor {{ bgp_peer['name'] }} soft-reconfiguration inbound +{% if bgp_peer['src_address'] is defined %} + neighbor {{ bgp_peer['name'] }} update-source {{ bgp_peer['src_address'] | ip }} +{% else %} +{% for (name, prefix) in LOOPBACK_INTERFACE %} +{% if name == 'Loopback1' %} + neighbor {{ bgp_peer['name'] }} update-source {{ prefix | ip }} +{% endif %} +{% endfor %} +{% endif %} + neighbor {{ bgp_peer['name'] }} route-map FROM_BGP_SPEAKER_V4 in + neighbor {{ bgp_peer['name'] }} route-map TO_BGP_SPEAKER_V4 out +{% for ip_range in bgp_peer['ip_range'] %} + bgp listen range {{ip_range}} peer-group {{ bgp_peer['name'] }} +{% endfor %} + address-family ipv4 + neighbor {{ bgp_peer['name'] }} activate + maximum-paths 64 + exit-address-family + address-family ipv6 + neighbor {{ bgp_peer['name'] }} activate + maximum-paths 64 + exit-address-family +{% endfor %} +{% endif %} +{% endblock bgp_peers_with_range %} +! +{% if DEVICE_METADATA['localhost'].has_key('bgp_asn') %} +maximum-paths 64 +! +route-map ISOLATE permit 10 +set as-path prepend {{ DEVICE_METADATA['localhost']['bgp_asn'] }} +{% endif %} +! diff --git a/dockers/docker-fpm-frr/config.sh b/dockers/docker-fpm-frr/config.sh deleted file mode 100755 index de18a4fbb00a..000000000000 --- a/dockers/docker-fpm-frr/config.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -mkdir -p /etc/frr - -CONFIG_TYPE=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["docker_routing_config_mode"]'` - -if [ -z "$CONFIG_TYPE" ] || [ "$CONFIG_TYPE" == "unified" ]; then - sonic-cfggen -d -y /etc/sonic/deployment_id_asn_map.yml -t /usr/share/sonic/templates/frr.conf.j2 >/etc/frr/frr.conf -fi - -sonic-cfggen -d -t /usr/share/sonic/templates/isolate.j2 >/usr/sbin/bgp-isolate -chown root:root /usr/sbin/bgp-isolate -chmod 0755 /usr/sbin/bgp-isolate - -sonic-cfggen -d -t /usr/share/sonic/templates/unisolate.j2 >/usr/sbin/bgp-unisolate -chown root:root /usr/sbin/bgp-unisolate -chmod 0755 /usr/sbin/bgp-unisolate - -mkdir -p /var/sonic -echo "# Config files managed by sonic-config-engine" >/var/sonic/config_status diff --git a/dockers/docker-fpm-frr/daemons b/dockers/docker-fpm-frr/daemons deleted file mode 100644 index 8c9f1d10e6c0..000000000000 --- a/dockers/docker-fpm-frr/daemons +++ /dev/null @@ -1,65 +0,0 @@ -# This file tells the frr package which daemons to start. -# -# Sample configurations for these daemons can be found in -# /usr/share/doc/frr/examples/. -# -# ATTENTION: -# -# When activation a daemon at the first time, a config file, even if it is -# empty, has to be present *and* be owned by the user and group "frr", else -# the daemon will not be started by /etc/init.d/frr. The permissions should -# be u=rw,g=r,o=. -# When using "vtysh" such a config file is also needed. It should be owned by -# group "frrvty" and set to ug=rw,o= though. Check /etc/pam.d/frr, too. -# -# The watchfrr and zebra daemons are always started. -# -bgpd=yes -ospfd=no -ospf6d=no -ripd=no -ripngd=no -isisd=no -pimd=no -ldpd=no -nhrpd=no -eigrpd=no -babeld=no -sharpd=no -pbrd=no -bfdd=no -fabricd=no - -# -# If this option is set the /etc/init.d/frr script automatically loads -# the config via "vtysh -b" when the servers are started. -# Check /etc/pam.d/frr if you intend to use "vtysh"! -# -vtysh_enable=yes -zebra_options=" -A 127.0.0.1 -s 90000000 -M fpm" -bgpd_options=" -A 127.0.0.1" -ospfd_options=" -A 127.0.0.1" -ospf6d_options=" -A ::1" -ripd_options=" -A 127.0.0.1" -ripngd_options=" -A ::1" -isisd_options=" -A 127.0.0.1" -pimd_options=" -A 127.0.0.1" -ldpd_options=" -A 127.0.0.1" -nhrpd_options=" -A 127.0.0.1" -eigrpd_options=" -A 127.0.0.1" -babeld_options=" -A 127.0.0.1" -sharpd_options=" -A 127.0.0.1" -pbrd_options=" -A 127.0.0.1" -staticd_options="-A 127.0.0.1" -bfdd_options=" -A 127.0.0.1" -fabricd_options="-A 127.0.0.1" - -# The list of daemons to watch is automatically generated by the init script. -watchfrr_options="-r '/usr/lib/frr/watchfrr.sh restart %s' -s '/usr/lib/frr/watchfrr.sh start %s' -k '/usr/lib/frr/watchfrr.sh stop %s'" - -# for debugging purposes, you can specify a "wrap" command to start instead -# of starting the daemon directly, e.g. to use valgrind on ospfd: -# ospfd_wrap="/usr/bin/valgrind" -# or you can use "all_wrap" for all daemons, e.g. to use perf record: -# all_wrap="/usr/bin/perf record --call-graph -" -# the normal daemon command is added to this at the end. diff --git a/dockers/docker-fpm-frr/daemons.conf b/dockers/docker-fpm-frr/daemons.conf deleted file mode 100644 index 70b96a98007e..000000000000 --- a/dockers/docker-fpm-frr/daemons.conf +++ /dev/null @@ -1 +0,0 @@ -# this file is deprecated, please use "daemons" instead. diff --git a/dockers/docker-fpm-frr/start.sh b/dockers/docker-fpm-frr/start.sh index f46a42b4c34c..03bb71d4fc56 100755 --- a/dockers/docker-fpm-frr/start.sh +++ b/dockers/docker-fpm-frr/start.sh @@ -1,6 +1,41 @@ -#!/bin/bash +#!/usr/bin/env bash + +mkdir -p /etc/frr + +CONFIG_TYPE=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["docker_routing_config_mode"]'` + +if [ -z "$CONFIG_TYPE" ] || [ "$CONFIG_TYPE" == "separated" ]; then + sonic-cfggen -d -y /etc/sonic/deployment_id_asn_map.yml -t /usr/share/sonic/templates/bgpd.conf.j2 > /etc/frr/bgpd.conf + sonic-cfggen -d -t /usr/share/sonic/templates/zebra.conf.j2 > /etc/frr/zebra.conf + touch /etc/frr/vtysh.conf +elif [ "$CONFIG_TYPE" == "unified" ]; then + sonic-cfggen -d -y /etc/sonic/deployment_id_asn_map.yml -t /usr/share/sonic/templates/frr.conf.j2 >/etc/frr/frr.conf + echo "service integrated-vtysh-config" > /etc/frr/vtysh.conf +fi + +sonic-cfggen -d -t /usr/share/sonic/templates/isolate.j2 > /usr/sbin/bgp-isolate +chown root:root /usr/sbin/bgp-isolate +chmod 0755 /usr/sbin/bgp-isolate + +sonic-cfggen -d -t /usr/share/sonic/templates/unisolate.j2 > /usr/sbin/bgp-unisolate +chown root:root /usr/sbin/bgp-unisolate +chmod 0755 /usr/sbin/bgp-unisolate + +mkdir -p /var/sonic +echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status rm -f /var/run/rsyslogd.pid -service rsyslog start -service frr start -fpmsyncd & + +supervisorctl start rsyslogd + +supervisorctl start bgpcfgd + +# Start Quagga processes +supervisorctl start zebra +supervisorctl start bgpd + +if [ "$CONFIG_TYPE" == "unified" ]; then + supervisorctl start vtysh_b +fi + +supervisorctl start fpmsyncd diff --git a/dockers/docker-fpm-frr/supervisord.conf b/dockers/docker-fpm-frr/supervisord.conf new file mode 100644 index 000000000000..f8aa3297195a --- /dev/null +++ b/dockers/docker-fpm-frr/supervisord.conf @@ -0,0 +1,68 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[program:start.sh] +command=/usr/bin/start.sh +priority=1 +autostart=true +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog + +[program:bgpcfgd] +command=/usr/bin/bgpcfgd +priority=2 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n +priority=3 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog + +[program:zebra] +command=/usr/lib/frr/zebra -A 127.0.0.1 -s 90000000 -M fpm +priority=4 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog + +[program:bgpd] +command=/usr/lib/frr/bgpd -A 127.0.0.1 +priority=5 +stopsignal=KILL +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog + +[program:vtysh_b] +command=/usr/bin/vtysh -b +priority=6 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog + +[program:fpmsyncd] +command=fpmsyncd +priority=6 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog diff --git a/dockers/docker-fpm-frr/zebra.conf.j2 b/dockers/docker-fpm-frr/zebra.conf.j2 new file mode 100644 index 000000000000..4acb474b0e35 --- /dev/null +++ b/dockers/docker-fpm-frr/zebra.conf.j2 @@ -0,0 +1,78 @@ +! +{% block banner %} +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/quagga/zebra.conf.j2 using config DB data +! file: zebra.conf +! +{% endblock banner %} +! +{% block sys_init %} +hostname {{ DEVICE_METADATA['localhost']['hostname'] }} +password zebra +enable password zebra +{% endblock sys_init %} +! +{% block interfaces %} +! Enable link-detect (default disabled) +{% for (name, prefix) in INTERFACE %} +interface {{ name }} +link-detect +! +{% endfor %} +{% for pc in PORTCHANNEL %} +interface {{ pc }} +link-detect +! +{% endfor %} +{% endblock interfaces %} +! +{% block default_route %} +! set static default route to mgmt gateway as a backup to learned default +{% for (name, prefix) in MGMT_INTERFACE %} +{% if prefix | ipv4 %} +ip route 0.0.0.0/0 {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} 200 +{% endif %} +{% endfor %} +{% endblock default_route %} +! +{% block source_loopback %} +{% set lo_ipv4_addrs = [] %} +{% set lo_ipv6_addrs = [] %} +{% if LOOPBACK_INTERFACE %} +{% for (name, prefix) in LOOPBACK_INTERFACE %} +{% if name == 'Loopback0' %} +{% if prefix | ipv6 %} +{% if lo_ipv6_addrs.append(prefix) %} +{% endif %} +{% else %} +{% if lo_ipv4_addrs.append(prefix) %} +{% endif %} +{% endif %} +{% endif %} +{% endfor %} +{% endif %} +! Set ip source to loopback for bgp learned routes +{% if lo_ipv4_addrs|length > 0 -%} +route-map RM_SET_SRC permit 10 + set src {{ lo_ipv4_addrs[0] | ip }} +! +{% endif %} +{% if lo_ipv6_addrs|length > 0 %} +route-map RM_SET_SRC6 permit 10 + set src {{ lo_ipv6_addrs[0] | ip }} +! +{% endif %} +ip protocol bgp route-map RM_SET_SRC +! +{% if lo_ipv6_addrs|length > 0 %} +ipv6 protocol bgp route-map RM_SET_SRC6 +! +{% endif %} +{% endblock source_loopback %} +! +{% block logging %} +log syslog informational +log facility local4 +{% endblock logging %} +! + diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 145dc9796573..2aa8e5da60c0 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -337,8 +337,6 @@ sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh sudo mkdir $FILESYSTEM_ROOT/etc/sonic/frr sudo touch $FILESYSTEM_ROOT/etc/sonic/frr/frr.conf sudo touch $FILESYSTEM_ROOT/etc/sonic/frr/vtysh.conf -sudo cp dockers/docker-fpm-frr/daemons.conf $FILESYSTEM_ROOT/etc/sonic/frr/ -sudo cp dockers/docker-fpm-frr/daemons $FILESYSTEM_ROOT/etc/sonic/frr/ sudo chown -R $FRR_USER_UID:$FRR_USER_GID $FILESYSTEM_ROOT/etc/sonic/frr sudo chmod -R 640 $FILESYSTEM_ROOT/etc/sonic/frr/ sudo chmod 750 $FILESYSTEM_ROOT/etc/sonic/frr From 999ec0a7f2f88cb50d6cf55949c707f63c4f0528 Mon Sep 17 00:00:00 2001 From: Pradchaya Phucharoen Date: Thu, 9 May 2019 14:05:21 +0700 Subject: [PATCH 29/88] [devices]: Add HLX a dps200 psu driver (#2871) --- .../debian/platform-modules-haliburton.init | 4 + .../haliburton/modules/Makefile | 2 +- .../haliburton/modules/dps200.c | 128 ++++++ .../haliburton/modules/pmbus.h | 425 ++++++++++++++++++ 4 files changed, 558 insertions(+), 1 deletion(-) create mode 100644 platform/broadcom/sonic-platform-modules-cel/haliburton/modules/dps200.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/haliburton/modules/pmbus.h diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init index db0e8cfdb820..af74da87d5d3 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init @@ -17,6 +17,7 @@ start) modprobe smc modprobe hlx_gpio_ich + modprobe dps200 found=0 for devnum in 0 1; do @@ -51,6 +52,9 @@ start) echo max6697 0x1a > /sys/bus/i2c/devices/i2c-3/new_device echo max6697 0x1a > /sys/bus/i2c/devices/i2c-11/new_device + # Attach PSUs + echo dps200 0x5a > /sys/bus/i2c/devices/i2c-12/new_device + echo dps200 0x5b > /sys/bus/i2c/devices/i2c-13/new_device # Attach fans echo emc2305 0x4d > /sys/bus/i2c/devices/i2c-23/new_device diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/Makefile b/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/Makefile index b34cf2cabe20..415d1b5e62f0 100644 --- a/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/Makefile @@ -1 +1 @@ -obj-m := mc24lc64t.o emc2305.o smc.o hlx_gpio_ich.o +obj-m := mc24lc64t.o emc2305.o smc.o hlx_gpio_ich.o dps200.o diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/dps200.c b/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/dps200.c new file mode 100644 index 000000000000..6d5afdfb78b0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/dps200.c @@ -0,0 +1,128 @@ +/* + * Hardware monitoring driver for Delta DPS200 + * + * (C) Copyright 2019, Celestica Inc. + * Author: Pradchaya Phucharoen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "pmbus.h" + + +static int dps200_read_word_data(struct i2c_client *client, int page, int reg) +{ + + if (reg >= PMBUS_VIRT_BASE || + reg == PMBUS_VOUT_OV_FAULT_LIMIT || + reg == PMBUS_VOUT_OV_WARN_LIMIT || + reg == PMBUS_VOUT_UV_WARN_LIMIT || + reg == PMBUS_VOUT_UV_FAULT_LIMIT || + reg == PMBUS_IOUT_OC_LV_FAULT_LIMIT || + reg == PMBUS_IOUT_UC_FAULT_LIMIT || + reg == PMBUS_UT_WARN_LIMIT || + reg == PMBUS_UT_FAULT_LIMIT || + reg == PMBUS_VIN_OV_FAULT_LIMIT || + reg == PMBUS_VIN_OV_WARN_LIMIT || + reg == PMBUS_IIN_OC_FAULT_LIMIT || + reg == PMBUS_POUT_MAX) + return -ENXIO; + + /* + * WARNING: The following feild have coinstant driver value. + * If the register are + * PMBUS_IOUT_OC_WARN_LIMIT or PMBUS_IOUT_OC_FAULT_LIMIT convert + * the constant value from linear to direct fomat. + */ + if (reg == PMBUS_IOUT_OC_WARN_LIMIT) + return 0xb4; + else if (reg == PMBUS_IOUT_OC_FAULT_LIMIT) + return 0xc8; + else + return pmbus_read_word_data(client, page, reg); +} + +/* + * Form DPS-200 datasheet the supported sensors format defined as: + * VOUT: direct mode with one decimal place. + * + * Other sensors: + * IOUT: direct mode with one decimal place. + * IOUT Limits: linear mode, which difference from IOUT. + * VIN, IIN, POWER, TEMP, & FAN: linear mode. + */ +static struct pmbus_driver_info dps200_info = { + .pages = 1, + .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT + | PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT + | PMBUS_HAVE_PIN | PMBUS_HAVE_POUT + | PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12 + | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP + | PMBUS_HAVE_STATUS_INPUT, + .format = { + [PSC_VOLTAGE_OUT] = direct, + [PSC_CURRENT_OUT] = direct, + }, + .m = { + [PSC_VOLTAGE_OUT] = 10, + [PSC_CURRENT_OUT] = 10, + }, + .b = { + [PSC_VOLTAGE_OUT] = 0, + [PSC_CURRENT_OUT] = 0, + }, + .R = { + [PSC_VOLTAGE_OUT] = 0, + [PSC_CURRENT_OUT] = 0, + }, + .read_word_data = &dps200_read_word_data, +}; + +static int pmbus_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + return pmbus_do_probe(client, id, &dps200_info); +} +/* user driver datat to pass the grpup */ +static const struct i2c_device_id dps200_id[] = { + {"dps200", 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, dps200_id); + +/* This is the driver that will be inserted */ +static struct i2c_driver dps200_driver = { + .driver = { + .name = "dps200", + }, + .probe = pmbus_probe, + .remove = pmbus_do_remove, + .id_table = dps200_id, +}; + +module_i2c_driver(dps200_driver); + +MODULE_AUTHOR("Pradchaya Phucharoen"); +MODULE_DESCRIPTION("PMBus driver for Delta DPS200"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/pmbus.h b/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/pmbus.h new file mode 100644 index 000000000000..521baf6da49a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/pmbus.h @@ -0,0 +1,425 @@ +/* + * pmbus.h - Common defines and structures for PMBus devices + * + * Copyright (c) 2010, 2011 Ericsson AB. + * Copyright (c) 2012 Guenter Roeck + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PMBUS_H +#define PMBUS_H + +#include +#include + +/* + * Registers + */ +enum pmbus_regs { + PMBUS_PAGE = 0x00, + PMBUS_OPERATION = 0x01, + PMBUS_ON_OFF_CONFIG = 0x02, + PMBUS_CLEAR_FAULTS = 0x03, + PMBUS_PHASE = 0x04, + + PMBUS_CAPABILITY = 0x19, + PMBUS_QUERY = 0x1A, + + PMBUS_VOUT_MODE = 0x20, + PMBUS_VOUT_COMMAND = 0x21, + PMBUS_VOUT_TRIM = 0x22, + PMBUS_VOUT_CAL_OFFSET = 0x23, + PMBUS_VOUT_MAX = 0x24, + PMBUS_VOUT_MARGIN_HIGH = 0x25, + PMBUS_VOUT_MARGIN_LOW = 0x26, + PMBUS_VOUT_TRANSITION_RATE = 0x27, + PMBUS_VOUT_DROOP = 0x28, + PMBUS_VOUT_SCALE_LOOP = 0x29, + PMBUS_VOUT_SCALE_MONITOR = 0x2A, + + PMBUS_COEFFICIENTS = 0x30, + PMBUS_POUT_MAX = 0x31, + + PMBUS_FAN_CONFIG_12 = 0x3A, + PMBUS_FAN_COMMAND_1 = 0x3B, + PMBUS_FAN_COMMAND_2 = 0x3C, + PMBUS_FAN_CONFIG_34 = 0x3D, + PMBUS_FAN_COMMAND_3 = 0x3E, + PMBUS_FAN_COMMAND_4 = 0x3F, + + PMBUS_VOUT_OV_FAULT_LIMIT = 0x40, + PMBUS_VOUT_OV_FAULT_RESPONSE = 0x41, + PMBUS_VOUT_OV_WARN_LIMIT = 0x42, + PMBUS_VOUT_UV_WARN_LIMIT = 0x43, + PMBUS_VOUT_UV_FAULT_LIMIT = 0x44, + PMBUS_VOUT_UV_FAULT_RESPONSE = 0x45, + PMBUS_IOUT_OC_FAULT_LIMIT = 0x46, + PMBUS_IOUT_OC_FAULT_RESPONSE = 0x47, + PMBUS_IOUT_OC_LV_FAULT_LIMIT = 0x48, + PMBUS_IOUT_OC_LV_FAULT_RESPONSE = 0x49, + PMBUS_IOUT_OC_WARN_LIMIT = 0x4A, + PMBUS_IOUT_UC_FAULT_LIMIT = 0x4B, + PMBUS_IOUT_UC_FAULT_RESPONSE = 0x4C, + + PMBUS_OT_FAULT_LIMIT = 0x4F, + PMBUS_OT_FAULT_RESPONSE = 0x50, + PMBUS_OT_WARN_LIMIT = 0x51, + PMBUS_UT_WARN_LIMIT = 0x52, + PMBUS_UT_FAULT_LIMIT = 0x53, + PMBUS_UT_FAULT_RESPONSE = 0x54, + PMBUS_VIN_OV_FAULT_LIMIT = 0x55, + PMBUS_VIN_OV_FAULT_RESPONSE = 0x56, + PMBUS_VIN_OV_WARN_LIMIT = 0x57, + PMBUS_VIN_UV_WARN_LIMIT = 0x58, + PMBUS_VIN_UV_FAULT_LIMIT = 0x59, + + PMBUS_IIN_OC_FAULT_LIMIT = 0x5B, + PMBUS_IIN_OC_WARN_LIMIT = 0x5D, + + PMBUS_POUT_OP_FAULT_LIMIT = 0x68, + PMBUS_POUT_OP_WARN_LIMIT = 0x6A, + PMBUS_PIN_OP_WARN_LIMIT = 0x6B, + + PMBUS_STATUS_BYTE = 0x78, + PMBUS_STATUS_WORD = 0x79, + PMBUS_STATUS_VOUT = 0x7A, + PMBUS_STATUS_IOUT = 0x7B, + PMBUS_STATUS_INPUT = 0x7C, + PMBUS_STATUS_TEMPERATURE = 0x7D, + PMBUS_STATUS_CML = 0x7E, + PMBUS_STATUS_OTHER = 0x7F, + PMBUS_STATUS_MFR_SPECIFIC = 0x80, + PMBUS_STATUS_FAN_12 = 0x81, + PMBUS_STATUS_FAN_34 = 0x82, + + PMBUS_READ_VIN = 0x88, + PMBUS_READ_IIN = 0x89, + PMBUS_READ_VCAP = 0x8A, + PMBUS_READ_VOUT = 0x8B, + PMBUS_READ_IOUT = 0x8C, + PMBUS_READ_TEMPERATURE_1 = 0x8D, + PMBUS_READ_TEMPERATURE_2 = 0x8E, + PMBUS_READ_TEMPERATURE_3 = 0x8F, + PMBUS_READ_FAN_SPEED_1 = 0x90, + PMBUS_READ_FAN_SPEED_2 = 0x91, + PMBUS_READ_FAN_SPEED_3 = 0x92, + PMBUS_READ_FAN_SPEED_4 = 0x93, + PMBUS_READ_DUTY_CYCLE = 0x94, + PMBUS_READ_FREQUENCY = 0x95, + PMBUS_READ_POUT = 0x96, + PMBUS_READ_PIN = 0x97, + + PMBUS_REVISION = 0x98, + PMBUS_MFR_ID = 0x99, + PMBUS_MFR_MODEL = 0x9A, + PMBUS_MFR_REVISION = 0x9B, + PMBUS_MFR_LOCATION = 0x9C, + PMBUS_MFR_DATE = 0x9D, + PMBUS_MFR_SERIAL = 0x9E, + +/* + * Virtual registers. + * Useful to support attributes which are not supported by standard PMBus + * registers but exist as manufacturer specific registers on individual chips. + * Must be mapped to real registers in device specific code. + * + * Semantics: + * Virtual registers are all word size. + * READ registers are read-only; writes are either ignored or return an error. + * RESET registers are read/write. Reading reset registers returns zero + * (used for detection), writing any value causes the associated history to be + * reset. + * Virtual registers have to be handled in device specific driver code. Chip + * driver code returns non-negative register values if a virtual register is + * supported, or a negative error code if not. The chip driver may return + * -ENODATA or any other error code in this case, though an error code other + * than -ENODATA is handled more efficiently and thus preferred. Either case, + * the calling PMBus core code will abort if the chip driver returns an error + * code when reading or writing virtual registers. + */ + PMBUS_VIRT_BASE = 0x100, + PMBUS_VIRT_READ_TEMP_AVG, + PMBUS_VIRT_READ_TEMP_MIN, + PMBUS_VIRT_READ_TEMP_MAX, + PMBUS_VIRT_RESET_TEMP_HISTORY, + PMBUS_VIRT_READ_VIN_AVG, + PMBUS_VIRT_READ_VIN_MIN, + PMBUS_VIRT_READ_VIN_MAX, + PMBUS_VIRT_RESET_VIN_HISTORY, + PMBUS_VIRT_READ_IIN_AVG, + PMBUS_VIRT_READ_IIN_MIN, + PMBUS_VIRT_READ_IIN_MAX, + PMBUS_VIRT_RESET_IIN_HISTORY, + PMBUS_VIRT_READ_PIN_AVG, + PMBUS_VIRT_READ_PIN_MIN, + PMBUS_VIRT_READ_PIN_MAX, + PMBUS_VIRT_RESET_PIN_HISTORY, + PMBUS_VIRT_READ_POUT_AVG, + PMBUS_VIRT_READ_POUT_MIN, + PMBUS_VIRT_READ_POUT_MAX, + PMBUS_VIRT_RESET_POUT_HISTORY, + PMBUS_VIRT_READ_VOUT_AVG, + PMBUS_VIRT_READ_VOUT_MIN, + PMBUS_VIRT_READ_VOUT_MAX, + PMBUS_VIRT_RESET_VOUT_HISTORY, + PMBUS_VIRT_READ_IOUT_AVG, + PMBUS_VIRT_READ_IOUT_MIN, + PMBUS_VIRT_READ_IOUT_MAX, + PMBUS_VIRT_RESET_IOUT_HISTORY, + PMBUS_VIRT_READ_TEMP2_AVG, + PMBUS_VIRT_READ_TEMP2_MIN, + PMBUS_VIRT_READ_TEMP2_MAX, + PMBUS_VIRT_RESET_TEMP2_HISTORY, + + PMBUS_VIRT_READ_VMON, + PMBUS_VIRT_VMON_UV_WARN_LIMIT, + PMBUS_VIRT_VMON_OV_WARN_LIMIT, + PMBUS_VIRT_VMON_UV_FAULT_LIMIT, + PMBUS_VIRT_VMON_OV_FAULT_LIMIT, + PMBUS_VIRT_STATUS_VMON, +}; + +/* + * OPERATION + */ +#define PB_OPERATION_CONTROL_ON BIT(7) + +/* + * CAPABILITY + */ +#define PB_CAPABILITY_SMBALERT BIT(4) +#define PB_CAPABILITY_ERROR_CHECK BIT(7) + +/* + * VOUT_MODE + */ +#define PB_VOUT_MODE_MODE_MASK 0xe0 +#define PB_VOUT_MODE_PARAM_MASK 0x1f + +#define PB_VOUT_MODE_LINEAR 0x00 +#define PB_VOUT_MODE_VID 0x20 +#define PB_VOUT_MODE_DIRECT 0x40 + +/* + * Fan configuration + */ +#define PB_FAN_2_PULSE_MASK (BIT(0) | BIT(1)) +#define PB_FAN_2_RPM BIT(2) +#define PB_FAN_2_INSTALLED BIT(3) +#define PB_FAN_1_PULSE_MASK (BIT(4) | BIT(5)) +#define PB_FAN_1_RPM BIT(6) +#define PB_FAN_1_INSTALLED BIT(7) + +/* + * STATUS_BYTE, STATUS_WORD (lower) + */ +#define PB_STATUS_NONE_ABOVE BIT(0) +#define PB_STATUS_CML BIT(1) +#define PB_STATUS_TEMPERATURE BIT(2) +#define PB_STATUS_VIN_UV BIT(3) +#define PB_STATUS_IOUT_OC BIT(4) +#define PB_STATUS_VOUT_OV BIT(5) +#define PB_STATUS_OFF BIT(6) +#define PB_STATUS_BUSY BIT(7) + +/* + * STATUS_WORD (upper) + */ +#define PB_STATUS_UNKNOWN BIT(8) +#define PB_STATUS_OTHER BIT(9) +#define PB_STATUS_FANS BIT(10) +#define PB_STATUS_POWER_GOOD_N BIT(11) +#define PB_STATUS_WORD_MFR BIT(12) +#define PB_STATUS_INPUT BIT(13) +#define PB_STATUS_IOUT_POUT BIT(14) +#define PB_STATUS_VOUT BIT(15) + +/* + * STATUS_IOUT + */ +#define PB_POUT_OP_WARNING BIT(0) +#define PB_POUT_OP_FAULT BIT(1) +#define PB_POWER_LIMITING BIT(2) +#define PB_CURRENT_SHARE_FAULT BIT(3) +#define PB_IOUT_UC_FAULT BIT(4) +#define PB_IOUT_OC_WARNING BIT(5) +#define PB_IOUT_OC_LV_FAULT BIT(6) +#define PB_IOUT_OC_FAULT BIT(7) + +/* + * STATUS_VOUT, STATUS_INPUT + */ +#define PB_VOLTAGE_UV_FAULT BIT(4) +#define PB_VOLTAGE_UV_WARNING BIT(5) +#define PB_VOLTAGE_OV_WARNING BIT(6) +#define PB_VOLTAGE_OV_FAULT BIT(7) + +/* + * STATUS_INPUT + */ +#define PB_PIN_OP_WARNING BIT(0) +#define PB_IIN_OC_WARNING BIT(1) +#define PB_IIN_OC_FAULT BIT(2) + +/* + * STATUS_TEMPERATURE + */ +#define PB_TEMP_UT_FAULT BIT(4) +#define PB_TEMP_UT_WARNING BIT(5) +#define PB_TEMP_OT_WARNING BIT(6) +#define PB_TEMP_OT_FAULT BIT(7) + +/* + * STATUS_FAN + */ +#define PB_FAN_AIRFLOW_WARNING BIT(0) +#define PB_FAN_AIRFLOW_FAULT BIT(1) +#define PB_FAN_FAN2_SPEED_OVERRIDE BIT(2) +#define PB_FAN_FAN1_SPEED_OVERRIDE BIT(3) +#define PB_FAN_FAN2_WARNING BIT(4) +#define PB_FAN_FAN1_WARNING BIT(5) +#define PB_FAN_FAN2_FAULT BIT(6) +#define PB_FAN_FAN1_FAULT BIT(7) + +/* + * CML_FAULT_STATUS + */ +#define PB_CML_FAULT_OTHER_MEM_LOGIC BIT(0) +#define PB_CML_FAULT_OTHER_COMM BIT(1) +#define PB_CML_FAULT_PROCESSOR BIT(3) +#define PB_CML_FAULT_MEMORY BIT(4) +#define PB_CML_FAULT_PACKET_ERROR BIT(5) +#define PB_CML_FAULT_INVALID_DATA BIT(6) +#define PB_CML_FAULT_INVALID_COMMAND BIT(7) + +enum pmbus_sensor_classes { + PSC_VOLTAGE_IN = 0, + PSC_VOLTAGE_OUT, + PSC_CURRENT_IN, + PSC_CURRENT_OUT, + PSC_POWER, + PSC_TEMPERATURE, + PSC_FAN, + PSC_NUM_CLASSES /* Number of power sensor classes */ +}; + +#define PMBUS_PAGES 32 /* Per PMBus specification */ + +/* Functionality bit mask */ +#define PMBUS_HAVE_VIN BIT(0) +#define PMBUS_HAVE_VCAP BIT(1) +#define PMBUS_HAVE_VOUT BIT(2) +#define PMBUS_HAVE_IIN BIT(3) +#define PMBUS_HAVE_IOUT BIT(4) +#define PMBUS_HAVE_PIN BIT(5) +#define PMBUS_HAVE_POUT BIT(6) +#define PMBUS_HAVE_FAN12 BIT(7) +#define PMBUS_HAVE_FAN34 BIT(8) +#define PMBUS_HAVE_TEMP BIT(9) +#define PMBUS_HAVE_TEMP2 BIT(10) +#define PMBUS_HAVE_TEMP3 BIT(11) +#define PMBUS_HAVE_STATUS_VOUT BIT(12) +#define PMBUS_HAVE_STATUS_IOUT BIT(13) +#define PMBUS_HAVE_STATUS_INPUT BIT(14) +#define PMBUS_HAVE_STATUS_TEMP BIT(15) +#define PMBUS_HAVE_STATUS_FAN12 BIT(16) +#define PMBUS_HAVE_STATUS_FAN34 BIT(17) +#define PMBUS_HAVE_VMON BIT(18) +#define PMBUS_HAVE_STATUS_VMON BIT(19) + +enum pmbus_data_format { linear = 0, direct, vid }; +enum vrm_version { vr11 = 0, vr12 }; + +struct pmbus_driver_info { + int pages; /* Total number of pages */ + enum pmbus_data_format format[PSC_NUM_CLASSES]; + enum vrm_version vrm_version; + /* + * Support one set of coefficients for each sensor type + * Used for chips providing data in direct mode. + */ + int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */ + int b[PSC_NUM_CLASSES]; /* offset */ + int R[PSC_NUM_CLASSES]; /* exponent */ + + u32 func[PMBUS_PAGES]; /* Functionality, per page */ + /* + * The following functions map manufacturing specific register values + * to PMBus standard register values. Specify only if mapping is + * necessary. + * Functions return the register value (read) or zero (write) if + * successful. A return value of -ENODATA indicates that there is no + * manufacturer specific register, but that a standard PMBus register + * may exist. Any other negative return value indicates that the + * register does not exist, and that no attempt should be made to read + * the standard register. + */ + int (*read_byte_data)(struct i2c_client *client, int page, int reg); + int (*read_word_data)(struct i2c_client *client, int page, int reg); + int (*write_word_data)(struct i2c_client *client, int page, int reg, + u16 word); + int (*write_byte)(struct i2c_client *client, int page, u8 value); + /* + * The identify function determines supported PMBus functionality. + * This function is only necessary if a chip driver supports multiple + * chips, and the chip functionality is not pre-determined. + */ + int (*identify)(struct i2c_client *client, + struct pmbus_driver_info *info); + + /* Regulator functionality, if supported by this chip driver. */ + int num_regulators; + const struct regulator_desc *reg_desc; +}; + +/* Regulator ops */ + +extern const struct regulator_ops pmbus_regulator_ops; + +/* Macro for filling in array of struct regulator_desc */ +#define PMBUS_REGULATOR(_name, _id) \ + [_id] = { \ + .name = (_name # _id), \ + .id = (_id), \ + .of_match = of_match_ptr(_name # _id), \ + .regulators_node = of_match_ptr("regulators"), \ + .ops = &pmbus_regulator_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + } + +/* Function declarations */ + +void pmbus_clear_cache(struct i2c_client *client); +int pmbus_set_page(struct i2c_client *client, u8 page); +int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg); +int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word); +int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg); +int pmbus_write_byte(struct i2c_client *client, int page, u8 value); +int pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg, + u8 value); +int pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg, + u8 mask, u8 value); +void pmbus_clear_faults(struct i2c_client *client); +bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg); +bool pmbus_check_word_register(struct i2c_client *client, int page, int reg); +int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, + struct pmbus_driver_info *info); +int pmbus_do_remove(struct i2c_client *client); +const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client + *client); + +#endif /* PMBUS_H */ \ No newline at end of file From e7485fdcef5f3f5958d856409462a9d05fabc65d Mon Sep 17 00:00:00 2001 From: paavaanan Date: Thu, 9 May 2019 12:39:01 +0530 Subject: [PATCH 30/88] [baseimage]: Flashrom utitily support for BIOS upgrade (#2867) --- build_debian.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/build_debian.sh b/build_debian.sh index 614f2168e4b3..47837c0c1470 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -247,6 +247,7 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in tcptraceroute \ mtr-tiny \ locales \ + flashrom \ cgroup-tools #Adds a locale to a debian system in non-interactive mode From 25f285d2ed9ba1946a02f9e2987e3f43df5a5177 Mon Sep 17 00:00:00 2001 From: "Sudharsan D.G" Date: Thu, 9 May 2019 00:12:26 -0700 Subject: [PATCH 31/88] [devices]: DELL S6000 CPLD driver update to recover if mux is hung during i2c operation (#2858) --- .../modules/dell_s6000_platform.c | 179 ++++++++++++------ 1 file changed, 119 insertions(+), 60 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-s6000/modules/dell_s6000_platform.c b/platform/broadcom/sonic-platform-modules-s6000/modules/dell_s6000_platform.c index 5e205973d674..3ac029e73ffd 100644 --- a/platform/broadcom/sonic-platform-modules-s6000/modules/dell_s6000_platform.c +++ b/platform/broadcom/sonic-platform-modules-s6000/modules/dell_s6000_platform.c @@ -9,6 +9,7 @@ #include #include #include +#include #define S6000_MUX_BASE_NR 10 #define QSFP_MODULE_BASE_NR 20 @@ -20,6 +21,7 @@ #define QSFP_MODULE_NUM 16 #define QSFP_DEVICE_NUM 2 +#define GPIO_I2C_MUX_PIN 10 static void device_release(struct device *dev) { @@ -247,28 +249,59 @@ static struct platform_driver qsfp_mux_driver = { /* TODO */ /* module_platform_driver */ +static int dell_i2c_smbus_read_byte_data(const struct i2c_client *client, + u8 command) +{ + int ret = 0; + + ret = i2c_smbus_read_byte_data(client, command); + if(ret < 0) { + printk(KERN_WARNING "I2C smbus read failed. Resetting mux with gpio10"); + gpio_set_value(GPIO_I2C_MUX_PIN, 1); + gpio_set_value(GPIO_I2C_MUX_PIN, 0); + ret = i2c_smbus_read_byte_data(client, command); + } + return ret; +} + +static int dell_i2c_smbus_write_byte_data(const struct i2c_client *client, + u8 command, u8 value) +{ + int ret = 0; + + ret = i2c_smbus_write_byte_data(client, command, value); + if(ret < 0) + { + printk(KERN_WARNING "I2C smbus write failed. Resetting mux with gpio10"); + gpio_set_value(GPIO_I2C_MUX_PIN, 1); + gpio_set_value(GPIO_I2C_MUX_PIN, 0); + ret = i2c_smbus_write_byte_data(client, command, value); + } + return ret; +} + static ssize_t get_modsel(struct device *dev, struct device_attribute *devattr, char *buf) { int ret; u32 data = 0; struct cpld_platform_data *pdata = dev->platform_data; - ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x0); + ret = dell_i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x0); if (ret < 0) return sprintf(buf, "na"); data = (u32)ret & 0xff; - ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x1); + ret = dell_i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x1); if (ret < 0) return sprintf(buf, "na"); data |= (u32)(ret & 0xff) << 8; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xa); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xa); if (ret < 0) return sprintf(buf, "na"); data |= (u32)(ret & 0xff) << 16; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xb); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xb); if (ret < 0) return sprintf(buf, "na"); data |= (u32)(ret & 0xff) << 24; @@ -282,22 +315,22 @@ static ssize_t get_lpmode(struct device *dev, struct device_attribute *devattr, u32 data = 0; struct cpld_platform_data *pdata = dev->platform_data; - ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x2); + ret = dell_i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x2); if (ret < 0) return sprintf(buf, "na"); data = (u32)ret & 0xff; - ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x3); + ret = dell_i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x3); if (ret < 0) return sprintf(buf, "na"); data |= (u32)(ret & 0xff) << 8; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xc); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xc); if (ret < 0) return sprintf(buf, "na"); data |= (u32)(ret & 0xff) << 16; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xd); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xd); if (ret < 0) return sprintf(buf, "na"); data |= (u32)(ret & 0xff) << 24; @@ -315,10 +348,10 @@ static ssize_t set_lpmode(struct device *dev, struct device_attribute *devattr, if (err) return err; - i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x2, (u8)(data & 0xff)); - i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x3, (u8)((data >> 8) & 0xff)); - i2c_smbus_write_byte_data(pdata[master_cpld].client, 0xc, (u8)((data >> 16) & 0xff)); - i2c_smbus_write_byte_data(pdata[master_cpld].client, 0xd, (u8)((data >> 24) & 0xff)); + dell_i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x2, (u8)(data & 0xff)); + dell_i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x3, (u8)((data >> 8) & 0xff)); + dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0xc, (u8)((data >> 16) & 0xff)); + dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0xd, (u8)((data >> 24) & 0xff)); return count; } @@ -329,22 +362,22 @@ static ssize_t get_reset(struct device *dev, struct device_attribute *devattr, c u32 data = 0; struct cpld_platform_data *pdata = dev->platform_data; - ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x6); + ret = dell_i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x6); if (ret < 0) return sprintf(buf, "na"); data = (u32)ret & 0xff; - ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x7); + ret = dell_i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x7); if (ret < 0) return sprintf(buf, "na"); data |= (u32)(ret & 0xff) << 8; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x10); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x10); if (ret < 0) return sprintf(buf, "na"); data |= (u32)(ret & 0xff) << 16; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x11); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x11); if (ret < 0) return sprintf(buf, "na"); data |= (u32)(ret & 0xff) << 24; @@ -362,10 +395,10 @@ static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, c if (err) return err; - i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x6, (u8)(data & 0xff)); - i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x7, (u8)((data >> 8)& 0xff)); - i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x10, (u8)((data >> 16) & 0xff)); - i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x11, (u8)((data >> 24) & 0xff)); + dell_i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x6, (u8)(data & 0xff)); + dell_i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x7, (u8)((data >> 8)& 0xff)); + dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x10, (u8)((data >> 16) & 0xff)); + dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x11, (u8)((data >> 24) & 0xff)); return count; } @@ -376,22 +409,22 @@ static ssize_t get_modprs(struct device *dev, struct device_attribute *devattr, u32 data = 0; struct cpld_platform_data *pdata = dev->platform_data; - ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x4); + ret = dell_i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x4); if (ret < 0) return sprintf(buf, "read error"); data = (u32)ret & 0xff; - ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x5); + ret = dell_i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x5); if (ret < 0) return sprintf(buf, "read error"); data |= (u32)(ret & 0xff) << 8; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xe); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xe); if (ret < 0) return sprintf(buf, "na"); data |= (u32)(ret & 0xff) << 16; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xf); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xf); if (ret < 0) return sprintf(buf, "na"); data |= (u32)(ret & 0xff) << 24; @@ -411,7 +444,7 @@ static ssize_t set_power_reset(struct device *dev, struct device_attribute *deva if (data) { - i2c_smbus_write_byte_data(pdata[system_cpld].client, 0x1, (u8)(0xfd)); + dell_i2c_smbus_write_byte_data(pdata[system_cpld].client, 0x1, (u8)(0xfd)); } return count; @@ -422,7 +455,7 @@ static ssize_t get_power_reset(struct device *dev, struct device_attribute *deva uint8_t ret = 0; struct cpld_platform_data *pdata = dev->platform_data; - ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, 0x1); + ret = dell_i2c_smbus_read_byte_data(pdata[system_cpld].client, 0x1); if (ret < 0) return sprintf(buf, "read error"); @@ -435,12 +468,12 @@ static ssize_t get_fan_prs(struct device *dev, struct device_attribute *devattr, u32 data = 0; struct cpld_platform_data *pdata = dev->platform_data; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); if (ret < 0) return sprintf(buf, "read error"); data = (u32)((ret & 0xc0) >> 6); - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x9); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x9); if (ret < 0) return sprintf(buf, "read error"); data |= (u32)((ret & 0x01) << 2); @@ -455,7 +488,7 @@ static ssize_t get_psu0_prs(struct device *dev, struct device_attribute *devattr u32 data = 0; struct cpld_platform_data *pdata = dev->platform_data; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x3); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x3); if (ret < 0) return sprintf(buf, "read error"); @@ -471,7 +504,7 @@ static ssize_t get_psu1_prs(struct device *dev, struct device_attribute *devattr u32 data = 0; struct cpld_platform_data *pdata = dev->platform_data; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x3); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x3); if (ret < 0) return sprintf(buf, "read error"); @@ -487,7 +520,7 @@ static ssize_t get_psu0_status(struct device *dev, struct device_attribute *deva u32 data = 0; struct cpld_platform_data *pdata = dev->platform_data; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x3); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x3); if (ret < 0) return sprintf(buf, "read error"); @@ -503,7 +536,7 @@ static ssize_t get_psu1_status(struct device *dev, struct device_attribute *deva u32 data = 0; struct cpld_platform_data *pdata = dev->platform_data; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x3); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x3); if (ret < 0) return sprintf(buf, "read error"); @@ -519,7 +552,7 @@ static ssize_t get_system_led(struct device *dev, struct device_attribute *devat u32 data = 0; struct cpld_platform_data *pdata = dev->platform_data; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); if (ret < 0) return sprintf(buf, "read error"); @@ -570,11 +603,11 @@ static ssize_t set_system_led(struct device *dev, struct device_attribute *devat return -1; } - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); if (ret < 0) return ret; - i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x7, (u8)((ret & 0x9F) | (data << 5))); + dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x7, (u8)((ret & 0x9F) | (data << 5))); return count; } @@ -585,7 +618,7 @@ static ssize_t get_locator_led(struct device *dev, struct device_attribute *deva u32 data = 0; struct cpld_platform_data *pdata = dev->platform_data; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); if (ret < 0) return sprintf(buf, "read error"); @@ -632,11 +665,11 @@ static ssize_t set_locator_led(struct device *dev, struct device_attribute *deva return -1; } - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); if (ret < 0) return ret; - i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x7, (u8)((ret & 0xE7) | (data << 3))); + dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x7, (u8)((ret & 0xE7) | (data << 3))); return count; } @@ -647,7 +680,7 @@ static ssize_t get_power_led(struct device *dev, struct device_attribute *devatt u32 data = 0; struct cpld_platform_data *pdata = dev->platform_data; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); if (ret < 0) return sprintf(buf, "read error"); @@ -698,11 +731,11 @@ static ssize_t set_power_led(struct device *dev, struct device_attribute *devatt return -1; } - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); if (ret < 0) return ret; - i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x7, (u8)((ret & 0xF9) | (data << 1))); + dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x7, (u8)((ret & 0xF9) | (data << 1))); return count; } @@ -713,7 +746,7 @@ static ssize_t get_master_led(struct device *dev, struct device_attribute *devat u32 data = 0; struct cpld_platform_data *pdata = dev->platform_data; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); if (ret < 0) return sprintf(buf, "read error"); @@ -751,11 +784,11 @@ static ssize_t set_master_led(struct device *dev, struct device_attribute *devat return -1; } - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); if (ret < 0) return ret; - i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x7, (u8)((ret & 0xFE) | data)); + dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x7, (u8)((ret & 0xFE) | data)); return count; } @@ -766,7 +799,7 @@ static ssize_t get_fan_led(struct device *dev, struct device_attribute *devattr, u32 data = 0; struct cpld_platform_data *pdata = dev->platform_data; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x9); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x9); if (ret < 0) return sprintf(buf, "read error"); @@ -817,11 +850,11 @@ static ssize_t set_fan_led(struct device *dev, struct device_attribute *devattr, return -1; } - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x9); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x9); if (ret < 0) return ret; - i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x9, (u8)((ret & 0xE7) | (data << 3))); + dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x9, (u8)((ret & 0xE7) | (data << 3))); return count; } @@ -832,7 +865,7 @@ static ssize_t get_fan0_led(struct device *dev, struct device_attribute *devattr u32 data = 0; struct cpld_platform_data *pdata = dev->platform_data; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); if (ret < 0) return sprintf(buf, "read error"); @@ -879,11 +912,11 @@ static ssize_t set_fan0_led(struct device *dev, struct device_attribute *devattr return -1; } - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); if (ret < 0) return ret; - i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x8, (u8)((ret & 0xFC) | data)); + dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x8, (u8)((ret & 0xFC) | data)); return count; } @@ -895,7 +928,7 @@ static ssize_t get_fan1_led(struct device *dev, struct device_attribute *devattr u32 data = 0; struct cpld_platform_data *pdata = dev->platform_data; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); if (ret < 0) return sprintf(buf, "read error"); @@ -942,11 +975,11 @@ static ssize_t set_fan1_led(struct device *dev, struct device_attribute *devattr return -1; } - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); if (ret < 0) return ret; - i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x8, (u8)((ret & 0xF3) | (data << 2))); + dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x8, (u8)((ret & 0xF3) | (data << 2))); return count; } @@ -957,7 +990,7 @@ static ssize_t get_fan2_led(struct device *dev, struct device_attribute *devattr u32 data = 0; struct cpld_platform_data *pdata = dev->platform_data; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); if (ret < 0) return sprintf(buf, "read error"); @@ -1004,11 +1037,11 @@ static ssize_t set_fan2_led(struct device *dev, struct device_attribute *devattr return -1; } - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); if (ret < 0) return ret; - i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x8, (u8)((ret & 0xCF) | (data << 4))); + dell_i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x8, (u8)((ret & 0xCF) | (data << 4))); return count; } @@ -1020,7 +1053,7 @@ static ssize_t get_system_cpld_ver(struct device *dev, u32 data = 0; struct cpld_platform_data *pdata = dev->platform_data; - ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, 0x0); + ret = dell_i2c_smbus_read_byte_data(pdata[system_cpld].client, 0x0); if (ret < 0) return sprintf(buf, "read error"); @@ -1036,7 +1069,7 @@ static ssize_t get_master_cpld_ver(struct device *dev, u32 data = 0; struct cpld_platform_data *pdata = dev->platform_data; - ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x1); + ret = dell_i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x1); if (ret < 0) return sprintf(buf, "read error"); @@ -1052,7 +1085,7 @@ static ssize_t get_slave_cpld_ver(struct device *dev, u32 data = 0; struct cpld_platform_data *pdata = dev->platform_data; - ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0xa); + ret = dell_i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0xa); if (ret < 0) return sprintf(buf, "read error"); @@ -1201,8 +1234,28 @@ static int __init dell_s6000_platform_init(void) struct cpld_platform_data *cpld_pdata; struct qsfp_mux_platform_data *qsfp_pdata; int i; + bool gpio_allocated = false; - printk("delll_s6000_platform module initialization\n"); + printk("dell_s6000_platform module initialization\n"); + + ret = gpio_request(GPIO_I2C_MUX_PIN, "gpio10"); + if(ret < 0) { + printk(KERN_WARNING "Failed to request gpio 10"); + goto error_gpio_init; + } + gpio_allocated = true; + + ret = gpio_export(GPIO_I2C_MUX_PIN, false); + if(ret < 0) { + printk(KERN_WARNING "Failed to export gpio 10"); + goto error_gpio_init; + } + + ret = gpio_direction_output(GPIO_I2C_MUX_PIN, 0); + if(ret < 0) { + printk(KERN_WARNING "Failed to set direction out on gpio 10"); + goto error_gpio_init; + } ret = platform_driver_register(&cpld_driver); if (ret) { @@ -1261,6 +1314,11 @@ static int __init dell_s6000_platform_init(void) platform_driver_unregister(&cpld_driver); error_cpld_driver: return ret; +error_gpio_init: + if(gpio_allocated) { + gpio_free(GPIO_I2C_MUX_PIN); + } + return ret; } static void __exit dell_s6000_platform_exit(void) @@ -1274,6 +1332,7 @@ static void __exit dell_s6000_platform_exit(void) platform_driver_unregister(&cpld_driver); platform_driver_unregister(&qsfp_mux_driver); + gpio_free(GPIO_I2C_MUX_PIN); } module_init(dell_s6000_platform_init); From b1862f43726cc9dae95d968093b1a1f19a82f9e2 Mon Sep 17 00:00:00 2001 From: paavaanan Date: Thu, 9 May 2019 12:52:18 +0530 Subject: [PATCH 32/88] [devices]: DellEMC S6100/Z9100 sensor.conf update (#2861) --- .../x86_64-dell_s6100_c2538-r0/sensors.conf | 22 ++++++++++++++++++- .../x86_64-dell_z9100_c2538-r0/sensors.conf | 22 ++++++++++++++++++- .../s6100/scripts/sensors | 4 ---- .../z9100/scripts/sensors | 4 ---- 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/sensors.conf b/device/dell/x86_64-dell_s6100_c2538-r0/sensors.conf index 43fa7357c177..dfb1aa7c92b1 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/sensors.conf +++ b/device/dell/x86_64-dell_s6100_c2538-r0/sensors.conf @@ -4,6 +4,26 @@ label power2 "PSU1 Output Power" label power3 "PSU2 Input Power" label power4 "PSU2 Output Power" label temp14 "PSU1 Temp" -label temp15 "PSU1 Temp" +label temp15 "PSU2 Temp" +label curr601 "PSU1 Input Current" +label curr602 "PSU1 Output Current" +label curr701 "PSU2 Input Current" +label curr702 "PSU2 Output Current" ignore temp12 ignore temp13 +ignore in101 +ignore in102 +ignore in103 +ignore in104 +ignore in201 +ignore in202 +ignore in203 +ignore in204 +ignore in301 +ignore in302 +ignore in303 +ignore in304 +ignore in401 +ignore in402 +ignore in403 +ignore in404 diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/sensors.conf b/device/dell/x86_64-dell_z9100_c2538-r0/sensors.conf index 31a656fcf0b3..e23891de6bf9 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/sensors.conf +++ b/device/dell/x86_64-dell_z9100_c2538-r0/sensors.conf @@ -4,9 +4,29 @@ label power2 "PSU1 Output Power" label power3 "PSU2 Input Power" label power4 "PSU2 Output Power" label temp14 "PSU1 Temp" -label temp15 "PSU1 Temp" +label temp15 "PSU2 Temp" +label curr601 "PSU1 Input Current" +label curr602 "PSU1 Output Current" +label curr701 "PSU2 Input Current" +label curr702 "PSU2 Output Current" ignore temp12 ignore temp13 ignore temp5 ignore temp7 ignore temp8 +ignore in101 +ignore in102 +ignore in103 +ignore in104 +ignore in201 +ignore in202 +ignore in203 +ignore in204 +ignore in301 +ignore in302 +ignore in303 +ignore in304 +ignore in401 +ignore in402 +ignore in403 +ignore in404 diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/sensors b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/sensors index 030d636a1565..958cbdcb7bef 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/sensors +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/sensors @@ -1,7 +1,3 @@ #!/bin/bash docker exec -i pmon sensors "$@" -#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/z9100/scripts/sensors b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/sensors index 030d636a1565..958cbdcb7bef 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/sensors +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/sensors @@ -1,7 +1,3 @@ #!/bin/bash docker exec -i pmon sensors "$@" -#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 From b7235fc9493ae4a48786b395463dea6cb4578e38 Mon Sep 17 00:00:00 2001 From: zzhiyuan Date: Thu, 9 May 2019 00:25:09 -0700 Subject: [PATCH 33/88] [Arista] Add QoS needed files for Arista 7170 (#2814) --- .../Arista-7170-64C/buffers.json.j2 | 3 + .../Arista-7170-64C/buffers_defaults_t0.j2 | 46 +++++++++++++++ .../Arista-7170-64C/qos.json.j2 | 1 + .../Arista-7170-64C/switch-sai.conf | 3 +- .../Arista-7170-Q59S20/buffers.json.j2 | 3 + .../Arista-7170-Q59S20/buffers_defaults_t0.j2 | 58 +++++++++++++++++++ .../Arista-7170-Q59S20/qos.json.j2 | 1 + .../Arista-7170-Q59S20/switch-sai.conf | 3 +- 8 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers.json.j2 create mode 100644 device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t0.j2 create mode 100644 device/arista/x86_64-arista_7170_64c/Arista-7170-64C/qos.json.j2 create mode 100644 device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers.json.j2 create mode 100644 device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t0.j2 create mode 100644 device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/qos.json.j2 diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers.json.j2 b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers.json.j2 new file mode 100644 index 000000000000..e6e9e844469b --- /dev/null +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't0' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..62a6bac1c25f --- /dev/null +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/buffers_defaults_t0.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":"11075584" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"10587408" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1664", + "dynamic_th":"-1" + } + }, +{%- endmacro %} diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/qos.json.j2 b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/switch-sai.conf b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/switch-sai.conf index f64f5f88ec1b..c3abb3ebd8fc 100644 --- a/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/switch-sai.conf +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-64C/switch-sai.conf @@ -26,7 +26,8 @@ "tofino-bin": "share/tofinopd/switch/tofino.bin", "switchapi": "lib/libswitchapi.so", "switchsai": "lib/libswitchsai.so", - "switchapi_port_add": false + "switchapi_port_add": false, + "non_default_port_ppgs": 5 } ] } diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers.json.j2 b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers.json.j2 new file mode 100644 index 000000000000..e6e9e844469b --- /dev/null +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't0' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..8ca15c1b0391 --- /dev/null +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/buffers_defaults_t0.j2 @@ -0,0 +1,58 @@ +{%- set default_cable = '5m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,20) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(80,88) %} + {%- if PORT_ALL.append("Ethernet%d" % port_idx) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(22,32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(128,140) %} + {%- if PORT_ALL.append("Ethernet%d" % port_idx) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(35,64) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "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":"11075584" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"10587408" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1664", + "dynamic_th":"-1" + } + }, +{%- endmacro %} diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/qos.json.j2 b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/switch-sai.conf b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/switch-sai.conf index f64f5f88ec1b..c3abb3ebd8fc 100644 --- a/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/switch-sai.conf +++ b/device/arista/x86_64-arista_7170_64c/Arista-7170-Q59S20/switch-sai.conf @@ -26,7 +26,8 @@ "tofino-bin": "share/tofinopd/switch/tofino.bin", "switchapi": "lib/libswitchapi.so", "switchsai": "lib/libswitchsai.so", - "switchapi_port_add": false + "switchapi_port_add": false, + "non_default_port_ppgs": 5 } ] } From 38ad2a8dad5ca41977f6d49c9845ea829f78123c Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Thu, 9 May 2019 14:57:17 +0700 Subject: [PATCH 34/88] [platform-celestica] - Implement FAN APIs based on the new platform API (#2739) * [platform/cel] Implement FAN APIs based on the new platform API * [platform/cel] Move platform api to under device platform * [platform/cel] Remove rule to build platform api python wheel --- .../sonic_platform/__init__.py | 0 .../sonic_platform/chassis.py | 108 +++++++++ .../x86_64-cel_e1031-r0/sonic_platform/fan.py | 183 ++++++++++++++ .../sonic_platform/platform.py | 23 ++ .../sonic_platform/__init__.py | 0 .../sonic_platform/chassis.py | 109 +++++++++ .../sonic_platform/fan.py | 228 ++++++++++++++++++ .../sonic_platform/platform.py | 23 ++ .../debian/platform-modules-dx010.init | 58 +++-- .../dx010/modules/dx010_cpld.c | 81 ++++++- 10 files changed, 790 insertions(+), 23 deletions(-) create mode 100644 device/celestica/x86_64-cel_e1031-r0/sonic_platform/__init__.py create mode 100644 device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py create mode 100644 device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py create mode 100644 device/celestica/x86_64-cel_e1031-r0/sonic_platform/platform.py create mode 100644 device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py create mode 100644 device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py create mode 100644 device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py create mode 100644 device/celestica/x86_64-cel_seastone-r0/sonic_platform/platform.py diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/__init__.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 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 new file mode 100644 index 000000000000..33fa88f8e700 --- /dev/null +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Chassis information which are available in the platform +# +############################################################################# + +import sys +import re +import os +import subprocess +import json + +try: + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +MMC_CPLD_ADDR = '0x100' +BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version" +CONFIG_DB_PATH = "/etc/sonic/config_db.json" +SMC_CPLD_PATH = "/sys/devices/platform/e1031.smc/version" +MMC_CPLD_PATH = "/sys/devices/platform/e1031.smc/getreg" +NUM_FAN = 3 + + +class Chassis(ChassisBase): + """Platform-specific Chassis class""" + + def __init__(self): + self.config_data = {} + for index in range(0, NUM_FAN): + fan = Fan(index) + self._fan_list.append(fan) + ChassisBase.__init__(self) + + def __get_register_value(self, path, register): + cmd = "echo {1} > {0}; cat {0}".format(path, register) + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err is not '': + return 'None' + else: + return raw_data.strip() + + def __read_config_db(self): + try: + with open(CONFIG_DB_PATH, 'r') as fd: + data = json.load(fd) + return data + except IOError: + raise IOError("Unable to open config_db file !") + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + try: + self.config_data = self.__read_config_db() + base_mac = self.config_data["DEVICE_METADATA"]["localhost"]["mac"] + return str(base_mac) + except KeyError: + raise KeyError("Base MAC not found") + + def get_component_versions(self): + """ + Retrieves platform-specific hardware/firmware versions for chassis + componenets such as BIOS, CPLD, FPGA, etc. + Returns: + A string containing platform-specific component versions + """ + + component_versions = dict() + + # Get BIOS version + try: + with open(BIOS_VERSION_PATH, 'r') as fd: + bios_version = fd.read() + except IOError: + raise IOError("Unable to open version file !") + + # Get CPLD version + cpld_version = dict() + + with open(SMC_CPLD_PATH, 'r') as fd: + smc_cpld_version = fd.read() + smc_cpld_version = 'None' if smc_cpld_version is 'None' else "{}.{}".format( + int(smc_cpld_version[2], 16), int(smc_cpld_version[3], 16)) + + mmc_cpld_version = self.__get_register_value( + MMC_CPLD_PATH, MMC_CPLD_ADDR) + mmc_cpld_version = 'None' if mmc_cpld_version is 'None' else "{}.{}".format( + int(mmc_cpld_version[2], 16), int(mmc_cpld_version[3], 16)) + + cpld_version["SMC"] = smc_cpld_version + cpld_version["MMC"] = mmc_cpld_version + + component_versions["CPLD"] = cpld_version + component_versions["BIOS"] = bios_version.strip() + return str(component_versions) diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py new file mode 100644 index 000000000000..d16290aa4596 --- /dev/null +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py @@ -0,0 +1,183 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the fan status which are available in the platform +# +############################################################################# + +import json +import math +import os.path + +try: + from sonic_platform_base.fan_base import FanBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +EMC2305_FAN_PATH = "/sys/bus/i2c/drivers/emc2305/" +FAN_PATH = "/sys/devices/platform/e1031.smc/" +SYS_GPIO_DIR = "/sys/class/gpio" +EMC2305_MAX_PWM = 255 +EMC2305_FAN_PWM = "pwm{}" +EMC2305_FAN_TARGET = "fan{}_target" +EMC2305_FAN_INPUT = "pwm{}" + + +class Fan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, fan_index): + self.index = fan_index + self.config_data = {} + self.fan_speed = 0 + + # e1031 fan attributes + # Single emc2305 chip located at i2c-23-4d + # to control a fan module + self.e1031_emc2305_chip = [ + { + 'device': "23-004d", + 'index_map': [1, 2, 4] + } + ] + + # TODO: Add fan presence status in sysfs + self.fan_e1031_presence = "fan{}_prs" + self.fan_e1031_direction = "fan{}_dir" + self.fan_e1031_led = "fan{}_led" + self.fan_e1031_led_col_map = { + self.STATUS_LED_COLOR_GREEN: "green", + self.STATUS_LED_COLOR_RED: "amber", + self.STATUS_LED_COLOR_OFF: "off" + } + FanBase.__init__(self) + + def get_direction(self): + + direction = self.FAN_DIRECTION_INTAKE + + try: + fan_direction_file = (FAN_PATH + + self.fan_e1031_direction.format(self.index+1)) + with open(fan_direction_file, 'r') as file: + raw = file.read().strip('\r\n') + if str(raw).upper() == "F2B": + direction = self.FAN_DIRECTION_INTAKE + else: + direction = self.FAN_DIRECTION_EXHAUST + except IOError: + return False + + return direction + + def get_speed(self): + """ + E1031 platform specific data: + + speed = pwm_in/255*100 + """ + # TODO: Seperate PSU's fan and main fan class + if self.fan_speed != 0: + return self.fan_speed + else: + speed = 0 + pwm = [] + emc2305_chips = self.e1031_emc2305_chip + + for chip in emc2305_chips: + device = chip['device'] + fan_index = chip['index_map'] + sysfs_path = "%s%s/%s" % ( + EMC2305_FAN_PATH, device, EMC2305_FAN_INPUT) + sysfs_path = sysfs_path.format(fan_index[self.index]) + try: + with open(sysfs_path, 'r') as file: + raw = file.read().strip('\r\n') + pwm.append(int(raw, 10)) + except IOError: + raise IOError("Unable to open " + sysfs_path) + + speed = math.ceil( + float(pwm[0]) * 100 / EMC2305_MAX_PWM) + + return int(speed) + + def get_target_speed(self): + """ + E1031 platform specific data: + + speed_pc = pwm_target/255*100 + + 0 : when PWM mode is use + pwm : when pwm mode is not use + + """ + target = 0 + pwm = [] + emc2305_chips = self.e1031_emc2305_chip + + for chip in emc2305_chips: + device = chip['device'] + fan_index = chip['index_map'] + sysfs_path = "%s%s/%s" % ( + EMC2305_FAN_PATH, device, EMC2305_FAN_TARGET) + sysfs_path = sysfs_path.format(fan_index[self.index]) + try: + with open(sysfs_path, 'r') as file: + raw = file.read().strip('\r\n') + pwm.append(int(raw, 10)) + except IOError: + raise IOError("Unable to open " + sysfs_path) + + target = pwm[0] * 100 / EMC2305_MAX_PWM + + return target + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + return 10 + + def set_speed(self, speed): + """ + Depends on pwm or target mode is selected: + 1) pwm = speed_pc * 255 <-- Currently use this mode. + 2) target_pwm = speed_pc * 100 / 255 + 2.1) set pwm{}_enable to 3 + + """ + pwm = speed * 255 / 100 + emc2305_chips = self.e1031_emc2305_chip + + for chip in emc2305_chips: + device = chip['device'] + fan_index = chip['index_map'] + sysfs_path = "%s%s/%s" % ( + EMC2305_FAN_PATH, device, EMC2305_FAN_PWM) + sysfs_path = sysfs_path.format(fan_index[self.index]) + try: + with open(sysfs_path, 'w') as file: + file.write(str(int(pwm))) + except IOError: + return False + + return True + + def set_status_led(self, color): + + try: + fan_led_file = (FAN_PATH + + self.fan_e1031_led.format(self.index+1)) + with open(fan_led_file, 'r') as file: + file.write(self.fan_e1031_led_col_map[color]) + except IOError: + return False + + return True diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/platform.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/platform.py new file mode 100644 index 000000000000..a632de87e742 --- /dev/null +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/platform.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + """Platform-specific Platform class""" + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 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 new file mode 100644 index 000000000000..1d2e9af3757b --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Chassis information which are available in the platform +# +############################################################################# + +import sys +import re +import os +import subprocess +import json + +try: + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version" +GETREG_PATH = "/sys/devices/platform/dx010_cpld/getreg" +CONFIG_DB_PATH = "/etc/sonic/config_db.json" +NUM_FAN = 5 +CPLD_ADDR_MAPPING = { + "CPLD1": "0x100", + "CPLD2": "0x200", + "CPLD3": "0x280", + "CPLD4": "0x300", + "CPLD5": "0x380" +} + + +class Chassis(ChassisBase): + """Platform-specific Chassis class""" + + def __init__(self): + self.config_data = {} + for index in range(0, NUM_FAN): + fan = Fan(index) + self._fan_list.append(fan) + ChassisBase.__init__(self) + + def __get_register_value(self, path, register): + cmd = "echo {1} > {0}; cat {0}".format(path, register) + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err is not '': + return 'None' + else: + return raw_data.strip() + + def __read_config_db(self): + try: + with open(CONFIG_DB_PATH, 'r') as fd: + data = json.load(fd) + return data + except IOError: + raise IOError("Unable to open config_db file !") + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + try: + self.config_data = self.__read_config_db() + base_mac = self.config_data["DEVICE_METADATA"]["localhost"]["mac"] + return str(base_mac) + except KeyError: + raise KeyError("Base MAC not found") + + def get_component_versions(self): + """ + Retrieves platform-specific hardware/firmware versions for chassis + componenets such as BIOS, CPLD, FPGA, etc. + Returns: + A string containing platform-specific component versions + """ + + component_versions = dict() + + # Get BIOS version + try: + with open(BIOS_VERSION_PATH, 'r') as fd: + bios_version = fd.read() + except IOError: + raise IOError("Unable to open version file !") + + # Get CPLD version + cpld_version = dict() + for cpld_name in CPLD_ADDR_MAPPING: + try: + cpld_addr = CPLD_ADDR_MAPPING[cpld_name] + cpld_version_raw = self.__get_register_value( + GETREG_PATH, cpld_addr) + cpld_version_str = "{}.{}".format(int(cpld_version_raw[2], 16), int( + cpld_version_raw[3], 16)) if cpld_version_raw is not None else 'None' + cpld_version[cpld_name] = cpld_version_str + except Exception, e: + cpld_version[cpld_name] = 'None' + component_versions["CPLD"] = cpld_version + component_versions["BIOS"] = bios_version.strip() + return str(component_versions) diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py new file mode 100644 index 000000000000..227c1d2ade52 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py @@ -0,0 +1,228 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the fan status which are available in the platform +# +############################################################################# + +import json +import math +import os.path + +try: + from sonic_platform_base.fan_base import FanBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +CONFIG_DB_PATH = "/etc/sonic/config_db.json" +EMC2305_PATH = "/sys/bus/i2c/drivers/emc2305/" +SYS_GPIO_DIR = "/sys/class/gpio" +EMC2305_MAX_PWM = 255 +EMC2305_FAN_PWM = "pwm{}" +EMC2305_FAN_TARGET = "fan{}_target" +EMC2305_FAN_INPUT = "pwm{}" + + +class Fan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, fan_index): + self.index = fan_index + self.config_data = {} + self.fan_speed = 0 + FanBase.__init__(self) + + # dx010 fan attributes + # Two EMC2305s located at i2c-13-4d and i2c-13-2e + # to control a dual-fan module. + self.dx010_emc2305_chip = [ + { + 'device': "13-002e", + 'index_map': [2, 1, 4, 5, 3] + }, + { + 'device': "13-004d", + 'index_map': [2, 4, 5, 3, 1] + } + ] + + self.dx010_fan_gpio = [ + {'base': self.get_gpio_base()}, + {'prs': 10, 'dir': 15, 'color': {'red': 31, 'green': 32}}, + {'prs': 11, 'dir': 16, 'color': {'red': 29, 'green': 30}}, + {'prs': 12, 'dir': 17, 'color': {'red': 35, 'green': 36}}, + {'prs': 13, 'dir': 18, 'color': {'red': 37, 'green': 38}}, + {'prs': 14, 'dir': 19, 'color': {'red': 33, 'green': 34}}, + ] + + def get_gpio_base(self): + for r in os.listdir(SYS_GPIO_DIR): + if "gpiochip" in r: + return int(r[8:], 10) + return 216 # Reserve + + def get_gpio_value(self, pinnum): + gpio_base = self.dx010_fan_gpio[0]['base'] + + gpio_dir = SYS_GPIO_DIR + '/gpio' + str(gpio_base+pinnum) + gpio_file = gpio_dir + "/value" + + try: + with open(gpio_file, 'r') as fd: + retval = fd.read() + except IOError: + raise IOError("Unable to open " + gpio_file + "file !") + + retval = retval.rstrip('\r\n') + return retval + + def set_gpio_value(self, pinnum, value=0): + gpio_base = self.dx010_fan_gpio[0]['base'] + + gpio_dir = SYS_GPIO_DIR + '/gpio' + str(gpio_base+pinnum) + gpio_file = gpio_dir + "/value" + + try: + with open(gpio_file, 'w') as fd: + retval = fd.write(str(value)) + except IOError: + raise IOError("Unable to open " + gpio_file + "file !") + + def get_direction(self): + + direction = self.FAN_DIRECTION_INTAKE + raw = self.get_gpio_value(self.dx010_fan_gpio[self.index+1]['dir']) + + if int(raw, 10) == 0: + direction = self.FAN_DIRECTION_INTAKE + else: + direction = self.FAN_DIRECTION_EXHAUST + + return direction + + def get_speed(self): + """ + DX010 platform specific data: + + speed = pwm_in/255*100 + """ + # TODO: Seperate PSU's fan and main fan class + if self.fan_speed != 0: + return self.fan_speed + else: + speed = 0 + pwm = [] + emc2305_chips = self.dx010_emc2305_chip + + for chip in emc2305_chips: + device = chip['device'] + fan_index = chip['index_map'] + sysfs_path = "%s%s/%s" % ( + EMC2305_PATH, device, EMC2305_FAN_INPUT) + sysfs_path = sysfs_path.format(fan_index[self.index]) + try: + with open(sysfs_path, 'r') as file: + raw = file.read().strip('\r\n') + pwm.append(int(raw, 10)) + except IOError: + raise IOError("Unable to open " + sysfs_path) + + speed = math.ceil( + float(pwm[0]) * 100 / EMC2305_MAX_PWM) + + return int(speed) + + def get_target_speed(self): + """ + DX010 platform specific data: + + speed_pc = pwm_target/255*100 + + 0 : when PWM mode is use + pwm : when pwm mode is not use + + """ + target = 0 + pwm = [] + emc2305_chips = self.dx010_emc2305_chip + + for chip in emc2305_chips: + device = chip['device'] + fan_index = chip['index_map'] + sysfs_path = "%s%s/%s" % ( + EMC2305_PATH, device, EMC2305_FAN_TARGET) + sysfs_path = sysfs_path.format(fan_index[self.index]) + try: + with open(sysfs_path, 'r') as file: + raw = file.read().strip('\r\n') + pwm.append(int(raw, 10)) + except IOError: + raise IOError("Unable to open " + sysfs_path) + + target = pwm[0] * 100 / EMC2305_MAX_PWM + + return target + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + return 10 + + def set_speed(self, speed): + """ + Depends on pwm or target mode is selected: + 1) pwm = speed_pc * 255 <-- Currently use this mode. + 2) target_pwm = speed_pc * 100 / 255 + 2.1) set pwm{}_enable to 3 + + """ + pwm = speed * 255 / 100 + emc2305_chips = self.dx010_emc2305_chip + + for chip in emc2305_chips: + device = chip['device'] + fan_index = chip['index_map'] + sysfs_path = "%s%s/%s" % ( + EMC2305_PATH, device, EMC2305_FAN_PWM) + sysfs_path = sysfs_path.format(fan_index[self.index]) + try: + with open(sysfs_path, 'w') as file: + file.write(str(int(pwm))) + except IOError: + return False + + return True + + def set_status_led(self, color): + try: + if color == self.STATUS_LED_COLOR_GREEN: + self.set_gpio_value( + self.dx010_fan_gpio[self.index+1]['color']['red'], 1) + self.set_gpio_value( + self.dx010_fan_gpio[self.index+1]['color']['green'], 0) + + elif color == self.STATUS_LED_COLOR_RED: + self.set_gpio_value( + self.dx010_fan_gpio[self.index+1]['color']['red'], 0) + self.set_gpio_value( + self.dx010_fan_gpio[self.index+1]['color']['green'], 1) + + elif color == self.STATUS_LED_COLOR_OFF: + self.set_gpio_value( + self.dx010_fan_gpio[self.index+1]['color']['red'], 1) + self.set_gpio_value( + self.dx010_fan_gpio[self.index+1]['color']['green'], 1) + else: + return False + + except IOError: + return False + + return True diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/platform.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/platform.py new file mode 100644 index 000000000000..a632de87e742 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/platform.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + """Platform-specific Platform class""" + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init index 2117ab22b402..aa13d572be78 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init @@ -12,7 +12,8 @@ ### END INIT INFO function export_gpio { -label=$2 +label=$3 +gpio_dir=$2 gpio_num=$1 gpio_base=`( cat /sys/class/gpio/gpiochip*/base | head -1 ) 2>/dev/null` gpio_label=`( cat /sys/class/gpio/gpiochip*/label | head -1 ) 2>/dev/null` @@ -27,6 +28,13 @@ if [ $? -ne 0 ]; then echo "Platform driver error: Cannot export gpio$ionum!" exit 1; fi +if [[ "X$gpio_dir" != "X" ]]; then + echo $gpio_dir > /sys/class/gpio/gpio${ionum}/direction + if [ $? -ne 0 ]; then + echo "Platform driver error: Cannot set direction of gpio$ionum!" + exit 1; + fi +fi } case "$1" in @@ -95,27 +103,33 @@ start) sleep 2 # Export platform gpio sysfs - export_gpio 10 # Fan 1 present - export_gpio 11 # Fan 2 present - export_gpio 12 # Fan 3 present - export_gpio 13 # Fan 4 present - export_gpio 14 # Fan 5 present - - export_gpio 22 # PSU L PWOK - export_gpio 25 # PSU R PWOK - export_gpio 27 # PSU L ABS - export_gpio 28 # PSU R ABS - - export_gpio 29 # Fan 1 LED: Red - export_gpio 30 # Fan 1 LED: Yellow - export_gpio 31 # Fan 2 LED: Red - export_gpio 32 # Fan 2 LED: Yellow - export_gpio 33 # Fan 3 LED: Red - export_gpio 34 # Fan 3 LED: Yellow - export_gpio 35 # Fan 4 LED: Red - export_gpio 36 # Fan 4 LED: Yellow - export_gpio 37 # Fan 5 LED: Red - export_gpio 38 # Fan 5 LED: Yellow + export_gpio 10 "in" # Fan 1 present + export_gpio 11 "in" # Fan 2 present + export_gpio 12 "in" # Fan 3 present + export_gpio 13 "in" # Fan 4 present + export_gpio 14 "in" # Fan 5 present + + export_gpio 15 "in" # Fan 1 direction + export_gpio 16 "in" # Fan 2 direction + export_gpio 17 "in" # Fan 3 direction + export_gpio 18 "in" # Fan 4 direction + export_gpio 19 "in" # Fan 5 direction + + export_gpio 22 "in" # PSU L PWOK + export_gpio 25 "in" # PSU R PWOK + export_gpio 27 "in" # PSU L ABS + export_gpio 28 "in" # PSU R ABS + + export_gpio 29 "out" # Fan 1 LED: Red + export_gpio 30 "out" # Fan 1 LED: Yellow + export_gpio 31 "out" # Fan 2 LED: Red + export_gpio 32 "out" # Fan 2 LED: Yellow + export_gpio 33 "out" # Fan 3 LED: Red + export_gpio 34 "out" # Fan 3 LED: Yellow + export_gpio 35 "out" # Fan 4 LED: Red + export_gpio 36 "out" # Fan 4 LED: Yellow + export_gpio 37 "out" # Fan 5 LED: Red + export_gpio 38 "out" # Fan 5 LED: Yellow # Turn off/down lpmod by defult (0 - Normal, 1 - Low Pow) echo 0x00000000 > /sys/devices/platform/dx010_cpld/qsfp_lpmode diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c index 397361a5edd6..7893220ff6d5 100644 --- a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c @@ -30,6 +30,13 @@ #define DRIVER_NAME "dx010_cpld" +#define CPLD1_VERSION_ADDR 0x100 +#define CPLD2_VERSION_ADDR 0x200 +#define CPLD3_VERSION_ADDR 0x280 +#define CPLD4_VERSION_ADDR 0x300 +#define CPLD5_VERSION_ADDR 0x380 + + #define RESET0108 0x250 #define RESET0910 0x251 #define RESET1118 0x2d0 @@ -110,10 +117,36 @@ struct dx010_i2c_data { struct dx010_cpld_data { struct i2c_adapter *i2c_adapter[LENGTH_PORT_CPLD]; struct mutex cpld_lock; + uint16_t read_addr; }; struct dx010_cpld_data *cpld_data; +static ssize_t getreg_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + + uint16_t addr; + char *last; + + addr = (uint16_t)strtoul(buf,&last,16); + if(addr == 0 && buf == last){ + return -EINVAL; + } + cpld_data->read_addr = addr; + return count; +} + +static ssize_t getreg_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + + int len = 0; + mutex_lock(&cpld_data->cpld_lock); + len = sprintf(buf, "0x%2.2x\n",inb(cpld_data->read_addr)); + mutex_unlock(&cpld_data->cpld_lock); + return len; +} + static ssize_t get_reset(struct device *dev, struct device_attribute *devattr, char *buf) { @@ -134,6 +167,47 @@ static ssize_t get_reset(struct device *dev, struct device_attribute *devattr, return sprintf(buf,"0x%8.8lx\n", reset & 0xffffffff); } +static ssize_t setreg_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + + uint16_t addr; + uint8_t value; + char *tok; + char clone[count]; + char *pclone = clone; + char *last; + + strcpy(clone, buf); + + mutex_lock(&cpld_data->cpld_lock); + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + addr = (uint16_t)strtoul(tok,&last,16); + if(addr == 0 && tok == last){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + value = (uint8_t)strtoul(tok,&last,16); + if(value == 0 && tok == last){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + + outb(value,addr); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} + static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { @@ -248,12 +322,16 @@ static ssize_t get_modirq(struct device *dev, struct device_attribute *devattr, return sprintf(buf,"0x%8.8lx\n", irq & 0xffffffff); } +static DEVICE_ATTR_RW(getreg); +static DEVICE_ATTR_WO(setreg); static DEVICE_ATTR(qsfp_reset, S_IRUGO | S_IWUSR, get_reset, set_reset); static DEVICE_ATTR(qsfp_lpmode, S_IRUGO | S_IWUSR, get_lpmode, set_lpmode); static DEVICE_ATTR(qsfp_modprs, S_IRUGO, get_modprs, NULL); static DEVICE_ATTR(qsfp_modirq, S_IRUGO, get_modirq, NULL); static struct attribute *dx010_lpc_attrs[] = { + &dev_attr_getreg.attr, + &dev_attr_setreg.attr, &dev_attr_qsfp_reset.attr, &dev_attr_qsfp_lpmode.attr, &dev_attr_qsfp_modprs.attr, @@ -499,6 +577,7 @@ static int cel_dx010_lpc_drv_probe(struct platform_device *pdev) return -ENOMEM; mutex_init(&cpld_data->cpld_lock); + cpld_data->read_addr = CPLD1_VERSION_ADDR; res = platform_get_resource(pdev, IORESOURCE_IO, 0); if (unlikely(!res)) { @@ -558,4 +637,4 @@ module_exit(cel_dx010_lpc_exit); MODULE_AUTHOR("Abhisit Sangjan "); MODULE_AUTHOR("Pariwat Leamsumran "); MODULE_DESCRIPTION("Celestica SeaStone DX010 LPC Driver"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL"); \ No newline at end of file From 9efcf1759a5560941214dc9f383d896fdeb531ca Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Thu, 9 May 2019 09:44:41 -0700 Subject: [PATCH 35/88] [ebtables] install ebtables in base image and install filter rules (#2805) - Add ebtables package, and install some filter rules: 1. ebtables -A FORWARD -d BGA -j DROP 2. ebtables -A FORWARD -p ARP -j DROP Basically, we let the ARP packets in the VLAN being forwarded by the ASIC, kernel gets a copy of these ARP packets and the forwarding from Kenerl gets dropped. So there is always only one copy of ARP/response in the VLAN. Signed-off-by: Ying Xie --- build_debian.sh | 5 +++++ files/image_config/ebtables/ebtables.filter | Bin 0 -> 616 bytes 2 files changed, 5 insertions(+) create mode 100644 files/image_config/ebtables/ebtables.filter diff --git a/build_debian.sh b/build_debian.sh index 47837c0c1470..1108c455722f 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -230,6 +230,7 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in usbutils \ pciutils \ iptables-persistent \ + ebtables \ logrotate \ curl \ kexec-tools \ @@ -412,6 +413,10 @@ if [ "${enable_organization_extensions}" = "y" ]; then fi fi +## Setup ebtable rules (rule file is in binary format) +sudo sed -i 's/EBTABLES_LOAD_ON_START="no"/EBTABLES_LOAD_ON_START="yes"/g' ${FILESYSTEM_ROOT}/etc/default/ebtables +sudo cp files/image_config/ebtables/ebtables.filter ${FILESYSTEM_ROOT}/etc + ## Remove gcc and python dev pkgs sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y remove gcc libpython2.7-dev diff --git a/files/image_config/ebtables/ebtables.filter b/files/image_config/ebtables/ebtables.filter new file mode 100644 index 0000000000000000000000000000000000000000..4faad1f5f4bdbe57c1bb0378a4b959e209067ed9 GIT binary patch literal 616 zcmYex%qdANVql2SJ|?SE&wv5=fFevle1Q=nRcO3Y9;B||+^xtpp$rTQptQgR2)_<0 z4^=5pDpuHd# zNIl5C!VqCNc@WKAFbQ+0e(m&=V1L2f4U;$IfU!U{W5XdJ39+0V%G?Js#y>O!6hUCn QhQ)qRI731Lq6Qxc07O|=rvLx| literal 0 HcmV?d00001 From a357693f5281c3f4a59553479eaef57a8b637492 Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Thu, 9 May 2019 14:36:32 -0700 Subject: [PATCH 36/88] [tacacs]: skip accessing tacacs servers for local non-tacacs users (#2843) * Switch the nss look up order as "compat" followed by "tacplus". This helps use the legacy passwd file for user info and go to tacacs only if not found. This means, we never contact tacacs for local users like "admin". This isolates local users from any issues with tacacs servers. W/o this fix, the sudo commands by local users could take * seconds, if the tacacs servers are unreachable. * Skip tacacs server access for local non-tacacs users. Revert the order of 'compat tacplus' to original 'tacplus compat' as tacplus access is required for all tacacs users, who also get created locally. --- .../image_config/hostcfgd/tacplus_nss.conf.j2 | 2 +- ...acacs-servers-for-local-non-tacacs-u.patch | 81 +++++++++++++++++++ src/tacacs/nss/Makefile | 1 + 3 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 src/tacacs/nss/0004-Skip-accessing-tacacs-servers-for-local-non-tacacs-u.patch diff --git a/files/image_config/hostcfgd/tacplus_nss.conf.j2 b/files/image_config/hostcfgd/tacplus_nss.conf.j2 index 347a9ec3d8c2..7f737888f59d 100644 --- a/files/image_config/hostcfgd/tacplus_nss.conf.j2 +++ b/files/image_config/hostcfgd/tacplus_nss.conf.j2 @@ -1,4 +1,4 @@ -onfiguration for libnss-tacplus +# Configuration for libnss-tacplus # debug - If you want to open debug log, set it on # Default: off diff --git a/src/tacacs/nss/0004-Skip-accessing-tacacs-servers-for-local-non-tacacs-u.patch b/src/tacacs/nss/0004-Skip-accessing-tacacs-servers-for-local-non-tacacs-u.patch new file mode 100644 index 000000000000..fc0dd46376fb --- /dev/null +++ b/src/tacacs/nss/0004-Skip-accessing-tacacs-servers-for-local-non-tacacs-u.patch @@ -0,0 +1,81 @@ +From 228d743b907be6346731cacc9c5d2bc78ce6a4e8 Mon Sep 17 00:00:00 2001 +From: Renuka Manavalan +Date: Mon, 6 May 2019 04:23:26 +0000 +Subject: [PATCH 4/4] Skip accessing tacacs servers for local non-tacacs users. + +--- + nss_tacplus.c | 44 +++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 43 insertions(+), 1 deletion(-) + +diff --git a/nss_tacplus.c b/nss_tacplus.c +index aac5246..f2a86e1 100644 +--- a/nss_tacplus.c ++++ b/nss_tacplus.c +@@ -487,7 +487,7 @@ static int create_or_modify_local_user(const char *name, int level, bool existin + /* + * Lookup user in /etc/passwd, and fill up passwd info if found. + */ +-static int lookup_pw_local(char* username, struct pwbuf *pb, bool *found) ++static int lookup_pw_local(const char* username, struct pwbuf *pb, bool *found) + { + FILE *fp; + struct passwd *pw = NULL; +@@ -517,6 +517,45 @@ static int lookup_pw_local(char* username, struct pwbuf *pb, bool *found) + return ret; + } + ++/* ++ * Return true, if user has entry in /etc/passwd and his gecos ++ * does not match with expected gecos for any tacacs user of any ++ * privilege level. ++ */ ++static bool is_non_tacacs_user(const char *name) ++{ ++ char buf[1024]; ++ struct passwd pw; ++ int err = 0; ++ struct pwbuf pwbuf; ++ bool found = false; ++ bool ret = false; ++ ++ pwbuf.buf = buf; ++ pwbuf.pw = &pw; ++ pwbuf.errnop = &err; ++ pwbuf.buflen = sizeof(buf); ++ ++ lookup_pw_local(name, &pwbuf, &found); ++ ++ if (found && (err == 0)) { ++ int i = MIN_TACACS_USER_PRIV; ++ const useradd_info_t *pinfo = &useradd_grp_list[i]; ++ ++ for(; (i <= MAX_TACACS_USER_PRIV); ++i, ++pinfo) { ++ if ((pinfo->info != NULL) && ++ (strcmp(pinfo->info, pwbuf.pw->pw_gecos) == 0)) { ++ break; ++ } ++ } ++ if (i > MAX_TACACS_USER_PRIV) { ++ /* gecos did not match with gecos of any tacacs user info */ ++ ret = true; ++ } ++ } ++ return ret; ++} ++ + /* + * Lookup local user passwd info for TACACS+ user. If not found, local user will + * be created by user mapping strategy. +@@ -768,6 +807,9 @@ enum nss_status _nss_tacplus_getpwnam_r(const char *name, struct passwd *pw, + syslog(LOG_WARNING, "%s: no tacacs server in config for nss_tacplus", + nssname); + } ++ else if(is_non_tacacs_user(name)) { ++ /* It is non-tacacs user, so bail out */ ++ } + else { + /* marshal the args for the lower level functions */ + pbuf.name = (char *)name; +-- +2.17.1 + diff --git a/src/tacacs/nss/Makefile b/src/tacacs/nss/Makefile index d9c858bdcb38..308b05f2c13b 100644 --- a/src/tacacs/nss/Makefile +++ b/src/tacacs/nss/Makefile @@ -15,6 +15,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : git am ../0001-Modify-user-map-profile.patch git am ../0002-Enable-modifying-local-user-permission.patch git am ../0003-management-vrf-support.patch + git am ../0004-Skip-accessing-tacacs-servers-for-local-non-tacacs-u.patch dpkg-buildpackage -rfakeroot -b -us -uc popd From f32243b33487c6800831cc9e2882687e0afb9ee3 Mon Sep 17 00:00:00 2001 From: Shuotian Cheng Date: Thu, 9 May 2019 18:30:12 -0700 Subject: [PATCH 37/88] [swss]: Update sonic-swss submodule (#2879) [vnetorch]: Use metadata matching for tunnel (#841) [aclorch]: Add ICMP type/code match for v4/v6 (#868) [restore_neighbors] fix failure with scapy 2.4.2 (#862) [intfsorch] Fix bug for VRF existence check (#882) Return 0 for CRM counter instead of None if no match (#879) Undo skipping Vnet tests, Vrf check before enslaving (#857) [Makefile]: Remove header files from source files (#883) Signed-off-by: Shu0T1an ChenG --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index f8792d577786..ee4992665b94 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit f8792d5777868f0d831c915c4b3e02a53579854d +Subproject commit ee4992665b94566936340d32d8d96f8dd038ed75 From 3a8ce5f3889c9f3b692faad82610f4270ed927ec Mon Sep 17 00:00:00 2001 From: Sumukha Tumkur Vani Date: Fri, 10 May 2019 14:28:24 -0700 Subject: [PATCH 38/88] Fix for LLDP portname issue (#2886) * Fix for LLDP portname issue First check for operstate and if its not present then check for ifindex * Addressing review comments --- dockers/docker-lldp-sv2/lldpmgrd | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/dockers/docker-lldp-sv2/lldpmgrd b/dockers/docker-lldp-sv2/lldpmgrd index 7d2528a9d3a6..62ed6904fb13 100755 --- a/dockers/docker-lldp-sv2/lldpmgrd +++ b/dockers/docker-lldp-sv2/lldpmgrd @@ -74,11 +74,14 @@ def signal_handler(sig, frame): # ========================== Helpers ================================== def is_port_exist(port_name): - filename = "/sys/class/net/%s/ifindex" % port_name - if not os.path.exists(filename): - return False - - return True + filename = "/sys/class/net/%s/operstate" % port_name + if os.path.exists(filename): + with open(filename) as fp: + state = fp.read() + return "up" in state + else: + filename = "/sys/class/net/%s/ifindex" % port_name + return os.path.exists(filename) # ============================== Classes ============================== From 5e21b073151b759abc1be829a21428d7311bf46b Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Sat, 11 May 2019 11:54:09 -0700 Subject: [PATCH 39/88] [sonic-quagga]: Fix missing fpm messages (#2884) --- src/sonic-quagga | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-quagga b/src/sonic-quagga index 81ad4d25b618..2e192c06b8f5 160000 --- a/src/sonic-quagga +++ b/src/sonic-quagga @@ -1 +1 @@ -Subproject commit 81ad4d25b618755099be6859f387449132a00229 +Subproject commit 2e192c06b8f526cab6fce710ab5da0223b0ba2b1 From 77b9feaa1f45824e6b3f13634bdb432b33ac4c97 Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Sat, 11 May 2019 11:54:30 -0700 Subject: [PATCH 40/88] [bfn] fixed build failure (#2883) * fixed barefoot platform build * added TNA config * updated port_config.ini Signed-off-by: Andriy Kokhan --- .../montara/port_config.ini | 66 ++++----- .../montara/switch-tna-sai.conf | 40 ++++++ .../mavericks/port_config.ini | 131 +++++++++--------- .../mavericks/switch-tna-sai.conf | 40 ++++++ platform/barefoot/bfn-platform.mk | 8 +- platform/barefoot/bfn-sai.mk | 8 +- 6 files changed, 186 insertions(+), 107 deletions(-) create mode 100644 device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-tna-sai.conf create mode 100644 device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-tna-sai.conf diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/port_config.ini b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/port_config.ini index 816bb0e94a70..37ed4b68986e 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/port_config.ini +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/port_config.ini @@ -1,33 +1,33 @@ -# name lanes -Ethernet0 0,1,2,3 -Ethernet4 4,5,6,7 -Ethernet8 8,9,10,11 -Ethernet12 12,13,14,15 -Ethernet16 16,17,18,19 -Ethernet20 20,21,22,23 -Ethernet24 24,25,26,27 -Ethernet28 28,29,30,31 -Ethernet32 32,33,34,35 -Ethernet36 36,37,38,39 -Ethernet40 40,41,42,43 -Ethernet44 44,45,46,47 -Ethernet48 48,49,50,51 -Ethernet52 52,53,54,55 -Ethernet56 56,57,58,59 -Ethernet60 60,61,62,63 -Ethernet64 64,65,66,67 -Ethernet68 68,69,70,71 -Ethernet72 72,73,74,75 -Ethernet76 76,77,78,79 -Ethernet80 80,81,82,83 -Ethernet84 84,85,86,87 -Ethernet88 88,89,90,91 -Ethernet92 92,93,94,95 -Ethernet96 96,97,98,99 -Ethernet100 100,101,102,103 -Ethernet104 104,105,106,107 -Ethernet108 108,109,110,111 -Ethernet112 112,113,114,115 -Ethernet116 116,117,118,119 -Ethernet120 120,121,122,123 -Ethernet124 124,125,126,127 +# name lanes alias speed autoneg fec +Ethernet0 0,1,2,3 Ethernet0 100000 0 rs +Ethernet4 4,5,6,7 Ethernet4 100000 0 rs +Ethernet8 8,9,10,11 Ethernet8 100000 0 rs +Ethernet12 12,13,14,15 Ethernet12 100000 0 rs +Ethernet16 16,17,18,19 Ethernet16 100000 0 rs +Ethernet20 20,21,22,23 Ethernet20 100000 0 rs +Ethernet24 24,25,26,27 Ethernet24 100000 0 rs +Ethernet28 28,29,30,31 Ethernet28 100000 0 rs +Ethernet32 32,33,34,35 Ethernet32 100000 0 rs +Ethernet36 36,37,38,39 Ethernet36 100000 0 rs +Ethernet40 40,41,42,43 Ethernet40 100000 0 rs +Ethernet44 44,45,46,47 Ethernet44 100000 0 rs +Ethernet48 48,49,50,51 Ethernet48 100000 0 rs +Ethernet52 52,53,54,55 Ethernet52 100000 0 rs +Ethernet56 56,57,58,59 Ethernet56 100000 0 rs +Ethernet60 60,61,62,63 Ethernet60 100000 0 rs +Ethernet64 64,65,66,67 Ethernet64 100000 0 rs +Ethernet68 68,69,70,71 Ethernet68 100000 0 rs +Ethernet72 72,73,74,75 Ethernet72 100000 0 rs +Ethernet76 76,77,78,79 Ethernet76 100000 0 rs +Ethernet80 80,81,82,83 Ethernet80 100000 0 rs +Ethernet84 84,85,86,87 Ethernet84 100000 0 rs +Ethernet88 88,89,90,91 Ethernet88 100000 0 rs +Ethernet92 92,93,94,95 Ethernet92 100000 0 rs +Ethernet96 96,97,98,99 Ethernet96 100000 0 rs +Ethernet100 100,101,102,103 Ethernet100 100000 0 rs +Ethernet104 104,105,106,107 Ethernet104 100000 0 rs +Ethernet108 108,109,110,111 Ethernet108 100000 0 rs +Ethernet112 112,113,114,115 Ethernet112 100000 0 rs +Ethernet116 116,117,118,119 Ethernet116 100000 0 rs +Ethernet120 120,121,122,123 Ethernet120 100000 0 rs +Ethernet124 124,125,126,127 Ethernet124 100000 0 rs diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-tna-sai.conf b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-tna-sai.conf new file mode 100644 index 000000000000..79b10cafa864 --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-tna-sai.conf @@ -0,0 +1,40 @@ +{ + "instance": 0, + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0", + "pcie_domain": 0, + "pcie_bus": 5, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "p4_devices": [ + { + "device-id": 0, + "agent0": "lib/platform/x86_64-accton_wedge100bf_32x-r0/libpltfm_mgr.so", + "p4_programs": [ + { + "p4_pipelines": [ + { + "p4_pipeline_name": "pipe", + "config": "share/tofinopd/switch/pipe/tofino.bin", + "context": "share/tofinopd/switch/pipe/context.json" + } + ], + "program-name": "switch", + "switchsai": "lib/libswitchsai.so", + "bfrt-config": "share/tofinopd/switch/bf-rt.json", + "model_json_path" : "share/switch/aug_model.json", + "switchapi_port_add": false, + "non_default_port_ppgs": 5 + } + ] + } + ] +} diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/port_config.ini b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/port_config.ini index c1001741d28a..f81066d53bfe 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/port_config.ini +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/port_config.ini @@ -1,66 +1,65 @@ -# name lanes -Ethernet0 0,1,2,3 -Ethernet4 4,5,6,7 -Ethernet8 8,9,10,11 -Ethernet12 12,13,14,15 -Ethernet16 16,17,18,19 -Ethernet20 20,21,22,23 -Ethernet24 24,25,26,27 -Ethernet28 28,29,30,31 -Ethernet32 32,33,34,35 -Ethernet36 36,37,38,39 -Ethernet40 40,41,42,43 -Ethernet44 44,45,46,47 -Ethernet48 48,49,50,51 -Ethernet52 52,53,54,55 -Ethernet56 56,57,58,59 -Ethernet60 60,61,62,63 -Ethernet64 64,65,66,67 -Ethernet68 68,69,70,71 -Ethernet72 72,73,74,75 -Ethernet76 76,77,78,79 -Ethernet80 80,81,82,83 -Ethernet84 84,85,86,87 -Ethernet88 88,89,90,91 -Ethernet92 92,93,94,95 -Ethernet96 96,97,98,99 -Ethernet100 100,101,102,103 -Ethernet104 104,105,106,107 -Ethernet108 108,109,110,111 -Ethernet112 112,113,114,115 -Ethernet116 116,117,118,119 -Ethernet120 120,121,122,123 -Ethernet124 124,125,126,127 -Ethernet128 128,129,130,131 -Ethernet132 132,133,134,135 -Ethernet136 136,137,138,139 -Ethernet140 140,141,142,143 -Ethernet144 144,145,146,147 -Ethernet148 148,149,150,151 -Ethernet152 152,153,154,155 -Ethernet156 156,157,158,159 -Ethernet160 160,161,162,163 -Ethernet164 164,165,166,167 -Ethernet168 168,169,170,171 -Ethernet172 172,173,174,175 -Ethernet176 176,177,178,179 -Ethernet180 180,181,182,183 -Ethernet184 184,185,186,187 -Ethernet188 188,189,190,191 -Ethernet192 192,193,194,195 -Ethernet196 196,197,198,199 -Ethernet200 200,201,202,203 -Ethernet204 204,205,206,207 -Ethernet208 208,209,210,211 -Ethernet212 212,213,214,215 -Ethernet216 216,217,218,219 -Ethernet220 220,221,222,223 -Ethernet224 224,225,226,227 -Ethernet228 228,229,230,231 -Ethernet232 232,233,234,235 -Ethernet236 236,237,238,239 -Ethernet240 240,241,242,243 -Ethernet244 244,245,246,247 -Ethernet248 248,249,250,251 -Ethernet252 252,253,254,255 -Ethernet256 256,257,258,259 +# name lanes alias speed autoneg fec +Ethernet0 0,1,2,3 Ethernet0 100000 0 rs +Ethernet4 4,5,6,7 Ethernet4 100000 0 rs +Ethernet8 8,9,10,11 Ethernet8 100000 0 rs +Ethernet12 12,13,14,15 Ethernet12 100000 0 rs +Ethernet16 16,17,18,19 Ethernet16 100000 0 rs +Ethernet20 20,21,22,23 Ethernet20 100000 0 rs +Ethernet24 24,25,26,27 Ethernet24 100000 0 rs +Ethernet28 28,29,30,31 Ethernet28 100000 0 rs +Ethernet32 32,33,34,35 Ethernet32 100000 0 rs +Ethernet36 36,37,38,39 Ethernet36 100000 0 rs +Ethernet40 40,41,42,43 Ethernet40 100000 0 rs +Ethernet44 44,45,46,47 Ethernet44 100000 0 rs +Ethernet48 48,49,50,51 Ethernet48 100000 0 rs +Ethernet52 52,53,54,55 Ethernet52 100000 0 rs +Ethernet56 56,57,58,59 Ethernet56 100000 0 rs +Ethernet60 60,61,62,63 Ethernet60 100000 0 rs +Ethernet64 64,65,66,67 Ethernet64 100000 0 rs +Ethernet68 68,69,70,71 Ethernet68 100000 0 rs +Ethernet72 72,73,74,75 Ethernet72 100000 0 rs +Ethernet76 76,77,78,79 Ethernet76 100000 0 rs +Ethernet80 80,81,82,83 Ethernet80 100000 0 rs +Ethernet84 84,85,86,87 Ethernet84 100000 0 rs +Ethernet88 88,89,90,91 Ethernet88 100000 0 rs +Ethernet92 92,93,94,95 Ethernet92 100000 0 rs +Ethernet96 96,97,98,99 Ethernet96 100000 0 rs +Ethernet100 100,101,102,103 Ethernet100 100000 0 rs +Ethernet104 104,105,106,107 Ethernet104 100000 0 rs +Ethernet108 108,109,110,111 Ethernet108 100000 0 rs +Ethernet112 112,113,114,115 Ethernet112 100000 0 rs +Ethernet116 116,117,118,119 Ethernet116 100000 0 rs +Ethernet120 120,121,122,123 Ethernet120 100000 0 rs +Ethernet124 124,125,126,127 Ethernet124 100000 0 rs +Ethernet128 128,129,130,131 Ethernet128 100000 0 rs +Ethernet132 132,133,134,135 Ethernet132 100000 0 rs +Ethernet136 136,137,138,139 Ethernet136 100000 0 rs +Ethernet140 140,141,142,143 Ethernet140 100000 0 rs +Ethernet144 144,145,146,147 Ethernet144 100000 0 rs +Ethernet148 148,149,150,151 Ethernet148 100000 0 rs +Ethernet152 152,153,154,155 Ethernet152 100000 0 rs +Ethernet156 156,157,158,159 Ethernet156 100000 0 rs +Ethernet160 160,161,162,163 Ethernet169 100000 0 rs +Ethernet164 164,165,166,167 Ethernet164 100000 0 rs +Ethernet168 168,169,170,171 Ethernet168 100000 0 rs +Ethernet172 172,173,174,175 Ethernet172 100000 0 rs +Ethernet176 176,177,178,179 Ethernet176 100000 0 rs +Ethernet180 180,181,182,183 Ethernet180 100000 0 rs +Ethernet184 184,185,186,187 Ethernet184 100000 0 rs +Ethernet188 188,189,190,191 Ethernet188 100000 0 rs +Ethernet192 192,193,194,195 Ethernet192 100000 0 rs +Ethernet196 196,197,198,199 Ethernet196 100000 0 rs +Ethernet200 200,201,202,203 Ethernet200 100000 0 rs +Ethernet204 204,205,206,207 Ethernet204 100000 0 rs +Ethernet208 208,209,210,211 Ethernet208 100000 0 rs +Ethernet212 212,213,214,215 Ethernet212 100000 0 rs +Ethernet216 216,217,218,219 Ethernet216 100000 0 rs +Ethernet220 220,221,222,223 Ethernet220 100000 0 rs +Ethernet224 224,225,226,227 Ethernet224 100000 0 rs +Ethernet228 228,229,230,231 Ethernet228 100000 0 rs +Ethernet232 232,233,234,235 Ethernet232 100000 0 rs +Ethernet236 236,237,238,239 Ethernet236 100000 0 rs +Ethernet240 240,241,242,243 Ethernet240 100000 0 rs +Ethernet244 244,245,246,247 Ethernet244 100000 0 rs +Ethernet248 248,249,250,251 Ethernet248 100000 0 rs +Ethernet252 252,253,254,255 Etherner252 100000 0 rs diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-tna-sai.conf b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-tna-sai.conf new file mode 100644 index 000000000000..647f41838285 --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-tna-sai.conf @@ -0,0 +1,40 @@ +{ + "instance": 0, + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0", + "pcie_domain": 0, + "pcie_bus": 5, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "p4_devices": [ + { + "device-id": 0, + "agent0": "lib/platform/x86_64-accton_wedge100bf_65x-r0/libpltfm_mgr.so", + "p4_programs": [ + { + "p4_pipelines": [ + { + "p4_pipeline_name": "pipe", + "config": "share/tofinopd/switch/pipe/tofino.bin", + "context": "share/tofinopd/switch/pipe/context.json" + } + ], + "program-name": "switch", + "switchsai": "lib/libswitchsai.so", + "bfrt-config": "share/tofinopd/switch/bf-rt.json", + "model_json_path" : "share/switch/aug_model.json", + "switchapi_port_add": false, + "non_default_port_ppgs": 5 + } + ] + } + ] +} diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index b0d40cd8ba6c..bdba34177604 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,9 +1,9 @@ ifdef BLDENV -BFN_PLATFORM = bfnplatform_master.92171a1_deb9.deb -$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/sde-master/bfnplatform_master.92171a1_deb9.deb" +BFN_PLATFORM = bfnplatform_8.9.x.98de3ce_pr_deb9.deb +$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_8_9/bfnplatform_8.9.x.98de3ce_pr_deb9.deb" else -BFN_PLATFORM = bfnplatform_master.92171a1_deb8.deb -$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/sde-master/bfnplatform_master.92171a1_deb8.deb" +BFN_PLATFORM = bfnplatform_8.9.x.98de3ce_pr_deb8.deb +$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_8_9/bfnplatform_8.9.x.98de3ce_pr_deb8.deb" endif SONIC_ONLINE_DEBS += $(BFN_PLATFORM) # $(BFN_SAI_DEV) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 51c1e1a74f11..a93dd71bc1bb 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,9 +1,9 @@ ifdef BLDENV -BFN_SAI = bfnsdk_master.92171a1_deb9.deb -$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/sde-master/bfnsdk_master.92171a1_deb9.deb" +BFN_SAI = bfnsdk_8.9.x.98de3ce_pr_deb9.deb +$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_8_9/bfnsdk_8.9.x.98de3ce_pr_deb9.deb" else -BFN_SAI = bfnsdk_master.92171a1_deb8.deb -$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/sde-master/bfnsdk_master.92171a1_deb8.deb" +BFN_SAI = bfnsdk_8.9.x.98de3ce_pr_deb8.deb +$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_8_9/bfnsdk_8.9.x.98de3ce_pr_deb8.deb" endif SONIC_ONLINE_DEBS += $(BFN_SAI) # $(BFN_SAI_DEV) From 23fb00c21b036c70e45c0552836775917ce6f96a Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Sat, 11 May 2019 11:54:47 -0700 Subject: [PATCH 41/88] [bfn] fixed build failure (#2885) * fixed barefoot platform build * added TNA config * updated port_config.ini Signed-off-by: Andriy Kokhan --- .../montara/port_config.ini | 66 ++++----- .../montara/switch-tna-sai.conf | 40 ++++++ .../mavericks/port_config.ini | 131 +++++++++--------- .../mavericks/switch-tna-sai.conf | 40 ++++++ platform/barefoot/bfn-platform.mk | 8 +- platform/barefoot/bfn-sai.mk | 8 +- 6 files changed, 186 insertions(+), 107 deletions(-) create mode 100644 device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-tna-sai.conf create mode 100644 device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-tna-sai.conf diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/port_config.ini b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/port_config.ini index 816bb0e94a70..37ed4b68986e 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/port_config.ini +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/port_config.ini @@ -1,33 +1,33 @@ -# name lanes -Ethernet0 0,1,2,3 -Ethernet4 4,5,6,7 -Ethernet8 8,9,10,11 -Ethernet12 12,13,14,15 -Ethernet16 16,17,18,19 -Ethernet20 20,21,22,23 -Ethernet24 24,25,26,27 -Ethernet28 28,29,30,31 -Ethernet32 32,33,34,35 -Ethernet36 36,37,38,39 -Ethernet40 40,41,42,43 -Ethernet44 44,45,46,47 -Ethernet48 48,49,50,51 -Ethernet52 52,53,54,55 -Ethernet56 56,57,58,59 -Ethernet60 60,61,62,63 -Ethernet64 64,65,66,67 -Ethernet68 68,69,70,71 -Ethernet72 72,73,74,75 -Ethernet76 76,77,78,79 -Ethernet80 80,81,82,83 -Ethernet84 84,85,86,87 -Ethernet88 88,89,90,91 -Ethernet92 92,93,94,95 -Ethernet96 96,97,98,99 -Ethernet100 100,101,102,103 -Ethernet104 104,105,106,107 -Ethernet108 108,109,110,111 -Ethernet112 112,113,114,115 -Ethernet116 116,117,118,119 -Ethernet120 120,121,122,123 -Ethernet124 124,125,126,127 +# name lanes alias speed autoneg fec +Ethernet0 0,1,2,3 Ethernet0 100000 0 rs +Ethernet4 4,5,6,7 Ethernet4 100000 0 rs +Ethernet8 8,9,10,11 Ethernet8 100000 0 rs +Ethernet12 12,13,14,15 Ethernet12 100000 0 rs +Ethernet16 16,17,18,19 Ethernet16 100000 0 rs +Ethernet20 20,21,22,23 Ethernet20 100000 0 rs +Ethernet24 24,25,26,27 Ethernet24 100000 0 rs +Ethernet28 28,29,30,31 Ethernet28 100000 0 rs +Ethernet32 32,33,34,35 Ethernet32 100000 0 rs +Ethernet36 36,37,38,39 Ethernet36 100000 0 rs +Ethernet40 40,41,42,43 Ethernet40 100000 0 rs +Ethernet44 44,45,46,47 Ethernet44 100000 0 rs +Ethernet48 48,49,50,51 Ethernet48 100000 0 rs +Ethernet52 52,53,54,55 Ethernet52 100000 0 rs +Ethernet56 56,57,58,59 Ethernet56 100000 0 rs +Ethernet60 60,61,62,63 Ethernet60 100000 0 rs +Ethernet64 64,65,66,67 Ethernet64 100000 0 rs +Ethernet68 68,69,70,71 Ethernet68 100000 0 rs +Ethernet72 72,73,74,75 Ethernet72 100000 0 rs +Ethernet76 76,77,78,79 Ethernet76 100000 0 rs +Ethernet80 80,81,82,83 Ethernet80 100000 0 rs +Ethernet84 84,85,86,87 Ethernet84 100000 0 rs +Ethernet88 88,89,90,91 Ethernet88 100000 0 rs +Ethernet92 92,93,94,95 Ethernet92 100000 0 rs +Ethernet96 96,97,98,99 Ethernet96 100000 0 rs +Ethernet100 100,101,102,103 Ethernet100 100000 0 rs +Ethernet104 104,105,106,107 Ethernet104 100000 0 rs +Ethernet108 108,109,110,111 Ethernet108 100000 0 rs +Ethernet112 112,113,114,115 Ethernet112 100000 0 rs +Ethernet116 116,117,118,119 Ethernet116 100000 0 rs +Ethernet120 120,121,122,123 Ethernet120 100000 0 rs +Ethernet124 124,125,126,127 Ethernet124 100000 0 rs diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-tna-sai.conf b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-tna-sai.conf new file mode 100644 index 000000000000..79b10cafa864 --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-tna-sai.conf @@ -0,0 +1,40 @@ +{ + "instance": 0, + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0", + "pcie_domain": 0, + "pcie_bus": 5, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "p4_devices": [ + { + "device-id": 0, + "agent0": "lib/platform/x86_64-accton_wedge100bf_32x-r0/libpltfm_mgr.so", + "p4_programs": [ + { + "p4_pipelines": [ + { + "p4_pipeline_name": "pipe", + "config": "share/tofinopd/switch/pipe/tofino.bin", + "context": "share/tofinopd/switch/pipe/context.json" + } + ], + "program-name": "switch", + "switchsai": "lib/libswitchsai.so", + "bfrt-config": "share/tofinopd/switch/bf-rt.json", + "model_json_path" : "share/switch/aug_model.json", + "switchapi_port_add": false, + "non_default_port_ppgs": 5 + } + ] + } + ] +} diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/port_config.ini b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/port_config.ini index c1001741d28a..f81066d53bfe 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/port_config.ini +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/port_config.ini @@ -1,66 +1,65 @@ -# name lanes -Ethernet0 0,1,2,3 -Ethernet4 4,5,6,7 -Ethernet8 8,9,10,11 -Ethernet12 12,13,14,15 -Ethernet16 16,17,18,19 -Ethernet20 20,21,22,23 -Ethernet24 24,25,26,27 -Ethernet28 28,29,30,31 -Ethernet32 32,33,34,35 -Ethernet36 36,37,38,39 -Ethernet40 40,41,42,43 -Ethernet44 44,45,46,47 -Ethernet48 48,49,50,51 -Ethernet52 52,53,54,55 -Ethernet56 56,57,58,59 -Ethernet60 60,61,62,63 -Ethernet64 64,65,66,67 -Ethernet68 68,69,70,71 -Ethernet72 72,73,74,75 -Ethernet76 76,77,78,79 -Ethernet80 80,81,82,83 -Ethernet84 84,85,86,87 -Ethernet88 88,89,90,91 -Ethernet92 92,93,94,95 -Ethernet96 96,97,98,99 -Ethernet100 100,101,102,103 -Ethernet104 104,105,106,107 -Ethernet108 108,109,110,111 -Ethernet112 112,113,114,115 -Ethernet116 116,117,118,119 -Ethernet120 120,121,122,123 -Ethernet124 124,125,126,127 -Ethernet128 128,129,130,131 -Ethernet132 132,133,134,135 -Ethernet136 136,137,138,139 -Ethernet140 140,141,142,143 -Ethernet144 144,145,146,147 -Ethernet148 148,149,150,151 -Ethernet152 152,153,154,155 -Ethernet156 156,157,158,159 -Ethernet160 160,161,162,163 -Ethernet164 164,165,166,167 -Ethernet168 168,169,170,171 -Ethernet172 172,173,174,175 -Ethernet176 176,177,178,179 -Ethernet180 180,181,182,183 -Ethernet184 184,185,186,187 -Ethernet188 188,189,190,191 -Ethernet192 192,193,194,195 -Ethernet196 196,197,198,199 -Ethernet200 200,201,202,203 -Ethernet204 204,205,206,207 -Ethernet208 208,209,210,211 -Ethernet212 212,213,214,215 -Ethernet216 216,217,218,219 -Ethernet220 220,221,222,223 -Ethernet224 224,225,226,227 -Ethernet228 228,229,230,231 -Ethernet232 232,233,234,235 -Ethernet236 236,237,238,239 -Ethernet240 240,241,242,243 -Ethernet244 244,245,246,247 -Ethernet248 248,249,250,251 -Ethernet252 252,253,254,255 -Ethernet256 256,257,258,259 +# name lanes alias speed autoneg fec +Ethernet0 0,1,2,3 Ethernet0 100000 0 rs +Ethernet4 4,5,6,7 Ethernet4 100000 0 rs +Ethernet8 8,9,10,11 Ethernet8 100000 0 rs +Ethernet12 12,13,14,15 Ethernet12 100000 0 rs +Ethernet16 16,17,18,19 Ethernet16 100000 0 rs +Ethernet20 20,21,22,23 Ethernet20 100000 0 rs +Ethernet24 24,25,26,27 Ethernet24 100000 0 rs +Ethernet28 28,29,30,31 Ethernet28 100000 0 rs +Ethernet32 32,33,34,35 Ethernet32 100000 0 rs +Ethernet36 36,37,38,39 Ethernet36 100000 0 rs +Ethernet40 40,41,42,43 Ethernet40 100000 0 rs +Ethernet44 44,45,46,47 Ethernet44 100000 0 rs +Ethernet48 48,49,50,51 Ethernet48 100000 0 rs +Ethernet52 52,53,54,55 Ethernet52 100000 0 rs +Ethernet56 56,57,58,59 Ethernet56 100000 0 rs +Ethernet60 60,61,62,63 Ethernet60 100000 0 rs +Ethernet64 64,65,66,67 Ethernet64 100000 0 rs +Ethernet68 68,69,70,71 Ethernet68 100000 0 rs +Ethernet72 72,73,74,75 Ethernet72 100000 0 rs +Ethernet76 76,77,78,79 Ethernet76 100000 0 rs +Ethernet80 80,81,82,83 Ethernet80 100000 0 rs +Ethernet84 84,85,86,87 Ethernet84 100000 0 rs +Ethernet88 88,89,90,91 Ethernet88 100000 0 rs +Ethernet92 92,93,94,95 Ethernet92 100000 0 rs +Ethernet96 96,97,98,99 Ethernet96 100000 0 rs +Ethernet100 100,101,102,103 Ethernet100 100000 0 rs +Ethernet104 104,105,106,107 Ethernet104 100000 0 rs +Ethernet108 108,109,110,111 Ethernet108 100000 0 rs +Ethernet112 112,113,114,115 Ethernet112 100000 0 rs +Ethernet116 116,117,118,119 Ethernet116 100000 0 rs +Ethernet120 120,121,122,123 Ethernet120 100000 0 rs +Ethernet124 124,125,126,127 Ethernet124 100000 0 rs +Ethernet128 128,129,130,131 Ethernet128 100000 0 rs +Ethernet132 132,133,134,135 Ethernet132 100000 0 rs +Ethernet136 136,137,138,139 Ethernet136 100000 0 rs +Ethernet140 140,141,142,143 Ethernet140 100000 0 rs +Ethernet144 144,145,146,147 Ethernet144 100000 0 rs +Ethernet148 148,149,150,151 Ethernet148 100000 0 rs +Ethernet152 152,153,154,155 Ethernet152 100000 0 rs +Ethernet156 156,157,158,159 Ethernet156 100000 0 rs +Ethernet160 160,161,162,163 Ethernet169 100000 0 rs +Ethernet164 164,165,166,167 Ethernet164 100000 0 rs +Ethernet168 168,169,170,171 Ethernet168 100000 0 rs +Ethernet172 172,173,174,175 Ethernet172 100000 0 rs +Ethernet176 176,177,178,179 Ethernet176 100000 0 rs +Ethernet180 180,181,182,183 Ethernet180 100000 0 rs +Ethernet184 184,185,186,187 Ethernet184 100000 0 rs +Ethernet188 188,189,190,191 Ethernet188 100000 0 rs +Ethernet192 192,193,194,195 Ethernet192 100000 0 rs +Ethernet196 196,197,198,199 Ethernet196 100000 0 rs +Ethernet200 200,201,202,203 Ethernet200 100000 0 rs +Ethernet204 204,205,206,207 Ethernet204 100000 0 rs +Ethernet208 208,209,210,211 Ethernet208 100000 0 rs +Ethernet212 212,213,214,215 Ethernet212 100000 0 rs +Ethernet216 216,217,218,219 Ethernet216 100000 0 rs +Ethernet220 220,221,222,223 Ethernet220 100000 0 rs +Ethernet224 224,225,226,227 Ethernet224 100000 0 rs +Ethernet228 228,229,230,231 Ethernet228 100000 0 rs +Ethernet232 232,233,234,235 Ethernet232 100000 0 rs +Ethernet236 236,237,238,239 Ethernet236 100000 0 rs +Ethernet240 240,241,242,243 Ethernet240 100000 0 rs +Ethernet244 244,245,246,247 Ethernet244 100000 0 rs +Ethernet248 248,249,250,251 Ethernet248 100000 0 rs +Ethernet252 252,253,254,255 Etherner252 100000 0 rs diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-tna-sai.conf b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-tna-sai.conf new file mode 100644 index 000000000000..647f41838285 --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-tna-sai.conf @@ -0,0 +1,40 @@ +{ + "instance": 0, + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0", + "pcie_domain": 0, + "pcie_bus": 5, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "p4_devices": [ + { + "device-id": 0, + "agent0": "lib/platform/x86_64-accton_wedge100bf_65x-r0/libpltfm_mgr.so", + "p4_programs": [ + { + "p4_pipelines": [ + { + "p4_pipeline_name": "pipe", + "config": "share/tofinopd/switch/pipe/tofino.bin", + "context": "share/tofinopd/switch/pipe/context.json" + } + ], + "program-name": "switch", + "switchsai": "lib/libswitchsai.so", + "bfrt-config": "share/tofinopd/switch/bf-rt.json", + "model_json_path" : "share/switch/aug_model.json", + "switchapi_port_add": false, + "non_default_port_ppgs": 5 + } + ] + } + ] +} diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index b0d40cd8ba6c..bdba34177604 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,9 +1,9 @@ ifdef BLDENV -BFN_PLATFORM = bfnplatform_master.92171a1_deb9.deb -$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/sde-master/bfnplatform_master.92171a1_deb9.deb" +BFN_PLATFORM = bfnplatform_8.9.x.98de3ce_pr_deb9.deb +$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_8_9/bfnplatform_8.9.x.98de3ce_pr_deb9.deb" else -BFN_PLATFORM = bfnplatform_master.92171a1_deb8.deb -$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/sde-master/bfnplatform_master.92171a1_deb8.deb" +BFN_PLATFORM = bfnplatform_8.9.x.98de3ce_pr_deb8.deb +$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_8_9/bfnplatform_8.9.x.98de3ce_pr_deb8.deb" endif SONIC_ONLINE_DEBS += $(BFN_PLATFORM) # $(BFN_SAI_DEV) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 51c1e1a74f11..a93dd71bc1bb 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,9 +1,9 @@ ifdef BLDENV -BFN_SAI = bfnsdk_master.92171a1_deb9.deb -$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/sde-master/bfnsdk_master.92171a1_deb9.deb" +BFN_SAI = bfnsdk_8.9.x.98de3ce_pr_deb9.deb +$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_8_9/bfnsdk_8.9.x.98de3ce_pr_deb9.deb" else -BFN_SAI = bfnsdk_master.92171a1_deb8.deb -$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/sde-master/bfnsdk_master.92171a1_deb8.deb" +BFN_SAI = bfnsdk_8.9.x.98de3ce_pr_deb8.deb +$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_8_9/bfnsdk_8.9.x.98de3ce_pr_deb8.deb" endif SONIC_ONLINE_DEBS += $(BFN_SAI) # $(BFN_SAI_DEV) From db7c42f750acd4b36954c60c106493e4ef6cf754 Mon Sep 17 00:00:00 2001 From: "Sudharsan D.G" Date: Mon, 13 May 2019 13:36:25 -0700 Subject: [PATCH 42/88] [devices]: Adding new SKU to DELL Z9264f (#2891) correcting default sku Changes for adding tiers Adding new SKU to Z9264f correcting default sku Changes for adding tiers Modified reboot script Adding new SKU to Z9264f correcting default sku Changes for adding tiers Adding new SKU to Z9264f correcting default sku Changes for adding tiers Modified reboot script Renaming sai.profile UT Fixes Fixing z9100 c32 Modifying c64 sku Changing default sku Fixing typo --- .../DellEMC-Z9264f-C64/port_config.ini | 65 ++ .../sai.profile | 0 .../th2-z9264f-64x100G.config.bcm | 0 .../DellEMC-Z9264f-Q64/port_config.ini | 65 ++ .../DellEMC-Z9264f-Q64/sai.profile.j2 | 13 + .../th2-z9264f-64x40G-t0.config.bcm | 1007 +++++++++++++++++ .../th2-z9264f-64x40G-t1.config.bcm | 1007 +++++++++++++++++ .../DellEMC-Z9264f/port_config.ini | 65 -- .../default_sku | 2 +- .../platform_reboot | 25 - .../plugins/sfputil.py | 20 +- .../debian/platform-modules-z9264f.install | 1 + 12 files changed, 2169 insertions(+), 101 deletions(-) create mode 100644 device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/port_config.ini rename device/dell/x86_64-dellemc_z9264f_c3538-r0/{DellEMC-Z9264f => DellEMC-Z9264f-C64}/sai.profile (100%) rename device/dell/x86_64-dellemc_z9264f_c3538-r0/{DellEMC-Z9264f => DellEMC-Z9264f-C64}/th2-z9264f-64x100G.config.bcm (100%) create mode 100644 device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/port_config.ini create mode 100644 device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/sai.profile.j2 create mode 100644 device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t0.config.bcm create mode 100644 device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t1.config.bcm delete mode 100644 device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f/port_config.ini delete mode 100644 device/dell/x86_64-dellemc_z9264f_c3538-r0/platform_reboot diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/port_config.ini b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/port_config.ini new file mode 100644 index 000000000000..f0be4bb442d2 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/port_config.ini @@ -0,0 +1,65 @@ +# name lanes alias index +Ethernet0 49,50,51,52 hundredGigE1/1 1 +Ethernet4 53,54,55,56 hundredGigE1/2 2 +Ethernet8 65,66,67,68 hundredGigE1/3 3 +Ethernet12 69,70,71,72 hundredGigE1/4 4 +Ethernet16 81,82,83,84 hundredGigE1/5 5 +Ethernet20 85,86,87,88 hundredGigE1/6 6 +Ethernet24 97,98,99,100 hundredGigE1/7 7 +Ethernet28 101,102,103,104 hundredGigE1/8 8 +Ethernet32 1,2,3,4 hundredGigE1/9 9 +Ethernet36 5,6,7,8 hundredGigE1/10 10 +Ethernet40 17,18,19,20 hundredGigE1/11 11 +Ethernet44 21,22,23,24 hundredGigE1/12 12 +Ethernet48 33,34,35,36 hundredGigE1/13 13 +Ethernet52 37,38,39,40 hundredGigE1/14 14 +Ethernet56 113,114,115,116 hundredGigE1/15 15 +Ethernet60 117,118,119,120 hundredGigE1/16 16 +Ethernet64 133,134,135,136 hundredGigE1/17 17 +Ethernet68 129,130,131,132 hundredGigE1/18 18 +Ethernet72 213,214,215,216 hundredGigE1/19 19 +Ethernet76 209,210,211,212 hundredGigE1/20 20 +Ethernet80 229,230,231,232 hundredGigE1/21 21 +Ethernet84 225,226,227,228 hundredGigE1/22 22 +Ethernet88 245,246,247,248 hundredGigE1/23 23 +Ethernet92 241,242,243,244 hundredGigE1/24 24 +Ethernet96 149,150,151,152 hundredGigE1/25 25 +Ethernet100 145,146,147,148 hundredGigE1/26 26 +Ethernet104 165,166,167,168 hundredGigE1/27 27 +Ethernet108 161,162,163,164 hundredGigE1/28 28 +Ethernet112 181,182,183,184 hundredGigE1/29 29 +Ethernet116 177,178,179,180 hundredGigE1/30 30 +Ethernet120 197,198,199,200 hundredGigE1/31 31 +Ethernet124 193,194,195,196 hundredGigE1/32 32 +Ethernet128 61,62,63,64 hundredGigE1/33 33 +Ethernet132 57,58,59,60 hundredGigE1/34 34 +Ethernet136 77,78,79,80 hundredGigE1/35 35 +Ethernet140 73,74,75,76 hundredGigE1/36 36 +Ethernet144 93,94,95,96 hundredGigE1/37 37 +Ethernet148 89,90,91,92 hundredGigE1/38 38 +Ethernet152 109,110,111,112 hundredGigE1/39 39 +Ethernet156 105,106,107,108 hundredGigE1/40 40 +Ethernet160 13,14,15,16 hundredGigE1/41 41 +Ethernet164 9,10,11,12 hundredGigE1/42 42 +Ethernet168 29,30,31,32 hundredGigE1/43 43 +Ethernet172 25,26,27,28 hundredGigE1/44 44 +Ethernet176 45,46,47,48 hundredGigE1/45 45 +Ethernet180 41,42,43,44 hundredGigE1/46 46 +Ethernet184 125,126,127,128 hundredGigE1/47 47 +Ethernet188 121,122,123,124 hundredGigE1/48 48 +Ethernet192 137,138,139,140 hundredGigE1/49 49 +Ethernet196 141,142,143,144 hundredGigE1/50 50 +Ethernet200 217,218,219,220 hundredGigE1/51 51 +Ethernet204 221,222,223,224 hundredGigE1/52 52 +Ethernet208 233,234,235,236 hundredGigE1/53 53 +Ethernet212 237,238,239,240 hundredGigE1/54 54 +Ethernet216 249,250,251,252 hundredGigE1/55 55 +Ethernet220 253,254,255,256 hundredGigE1/56 56 +Ethernet224 153,154,155,156 hundredGigE1/57 57 +Ethernet228 157,158,159,160 hundredGigE1/58 58 +Ethernet232 169,170,171,172 hundredGigE1/59 59 +Ethernet236 173,174,175,176 hundredGigE1/60 60 +Ethernet240 185,186,187,188 hundredGigE1/61 61 +Ethernet244 189,190,191,192 hundredGigE1/62 62 +Ethernet248 201,202,203,204 hundredGigE1/63 63 +Ethernet252 205,206,207,208 hundredGigE1/64 64 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f/sai.profile b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/sai.profile similarity index 100% rename from device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f/sai.profile rename to device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/sai.profile diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f/th2-z9264f-64x100G.config.bcm b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/th2-z9264f-64x100G.config.bcm similarity index 100% rename from device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f/th2-z9264f-64x100G.config.bcm rename to device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/th2-z9264f-64x100G.config.bcm diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/port_config.ini b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/port_config.ini new file mode 100644 index 000000000000..0f05a642c3f9 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/port_config.ini @@ -0,0 +1,65 @@ +# name lanes alias index +Ethernet0 49,50,51,52 fortyGigE1/1 1 +Ethernet4 53,54,55,56 fortyGigE1/2 2 +Ethernet8 65,66,67,68 fortyGigE1/3 3 +Ethernet12 69,70,71,72 fortyGigE1/4 4 +Ethernet16 81,82,83,84 fortyGigE1/5 5 +Ethernet20 85,86,87,88 fortyGigE1/6 6 +Ethernet24 97,98,99,100 fortyGigE1/7 7 +Ethernet28 101,102,103,104 fortyGigE1/8 8 +Ethernet32 1,2,3,4 fortyGigE1/9 9 +Ethernet36 5,6,7,8 fortyGigE1/10 10 +Ethernet40 17,18,19,20 fortyGigE1/11 11 +Ethernet44 21,22,23,24 fortyGigE1/12 12 +Ethernet48 33,34,35,36 fortyGigE1/13 13 +Ethernet52 37,38,39,40 fortyGigE1/14 14 +Ethernet56 113,114,115,116 fortyGigE1/15 15 +Ethernet60 117,118,119,120 fortyGigE1/16 16 +Ethernet64 133,134,135,136 fortyGigE1/17 17 +Ethernet68 129,130,131,132 fortyGigE1/18 18 +Ethernet72 213,214,215,216 fortyGigE1/19 19 +Ethernet76 209,210,211,212 fortyGigE1/20 20 +Ethernet80 229,230,231,232 fortyGigE1/21 21 +Ethernet84 225,226,227,228 fortyGigE1/22 22 +Ethernet88 245,246,247,248 fortyGigE1/23 23 +Ethernet92 241,242,243,244 fortyGigE1/24 24 +Ethernet96 149,150,151,152 fortyGigE1/25 25 +Ethernet100 145,146,147,148 fortyGigE1/26 26 +Ethernet104 165,166,167,168 fortyGigE1/27 27 +Ethernet108 161,162,163,164 fortyGigE1/28 28 +Ethernet112 181,182,183,184 fortyGigE1/29 29 +Ethernet116 177,178,179,180 fortyGigE1/30 30 +Ethernet120 197,198,199,200 fortyGigE1/31 31 +Ethernet124 193,194,195,196 fortyGigE1/32 32 +Ethernet128 61,62,63,64 fortyGigE1/33 33 +Ethernet132 57,58,59,60 fortyGigE1/34 34 +Ethernet136 77,78,79,80 fortyGigE1/35 35 +Ethernet140 73,74,75,76 fortyGigE1/36 36 +Ethernet144 93,94,95,96 fortyGigE1/37 37 +Ethernet148 89,90,91,92 fortyGigE1/38 38 +Ethernet152 109,110,111,112 fortyGigE1/39 39 +Ethernet156 105,106,107,108 fortyGigE1/40 40 +Ethernet160 13,14,15,16 fortyGigE1/41 41 +Ethernet164 9,10,11,12 fortyGigE1/42 42 +Ethernet168 29,30,31,32 fortyGigE1/43 43 +Ethernet172 25,26,27,28 fortyGigE1/44 44 +Ethernet176 45,46,47,48 fortyGigE1/45 45 +Ethernet180 41,42,43,44 fortyGigE1/46 46 +Ethernet184 125,126,127,128 fortyGigE1/47 47 +Ethernet188 121,122,123,124 fortyGigE1/48 48 +Ethernet192 137,138,139,140 fortyGigE1/49 49 +Ethernet196 141,142,143,144 fortyGigE1/50 50 +Ethernet200 217,218,219,220 fortyGigE1/51 51 +Ethernet204 221,222,223,224 fortyGigE1/52 52 +Ethernet208 233,234,235,236 fortyGigE1/53 53 +Ethernet212 237,238,239,240 fortyGigE1/54 54 +Ethernet216 249,250,251,252 fortyGigE1/55 55 +Ethernet220 253,254,255,256 fortyGigE1/56 56 +Ethernet224 153,154,155,156 fortyGigE1/57 57 +Ethernet228 157,158,159,160 fortyGigE1/58 58 +Ethernet232 169,170,171,172 fortyGigE1/59 59 +Ethernet236 173,174,175,176 fortyGigE1/60 60 +Ethernet240 185,186,187,188 fortyGigE1/61 61 +Ethernet244 189,190,191,192 fortyGigE1/62 62 +Ethernet248 201,202,203,204 fortyGigE1/63 63 +Ethernet252 205,206,207,208 fortyGigE1/64 64 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/sai.profile.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/sai.profile.j2 new file mode 100644 index 000000000000..66859a473733 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/sai.profile.j2 @@ -0,0 +1,13 @@ +{# Get sai.profile based on switch_role #} +{%- if DEVICE_METADATA is defined -%} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] -%} +{%- if switch_role.lower() == 'torrouter' %} +{% set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-z9264f-64x40G-t0.config.bcm' -%} +{%- else %} +{%- set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-z9264f-64x40G-t1.config.bcm' -%} +{%- endif %} +{%- else %} +{%- set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-z9264f-64x40G-t1.config.bcm' -%} +{%- endif %} +{# Write the contents of sai_ profile_filename to sai.profile file #} +{{ sai_profile_contents }} diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t0.config.bcm b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t0.config.bcm new file mode 100644 index 000000000000..79ec519f7853 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t0.config.bcm @@ -0,0 +1,1007 @@ +#TH2 Z9264F 64x40G +os=unix +core_clock_frequency=1700 +dpp_clock_ratio=2:3 +pbmp_xport_xe=0x3FFFD0000FFFF40003FFFC0001FFFE +oversubscribe_mode=1 +fpem_mem_entries=65536 +l2xmsg_mode=1 + +l3_alpm_enable=2 +bcm_num_cos=8 +switch_bypass_mode=0 +mmu_lossless=0 +lpm_scaling_enable=0 +lpm_ipv6_128b_reserved=0 +ipv6_lpm_128b_enable=1 + +parity_correction=1 +parity_enable=1 + +dport_map_enable=1 + +dport_map_enable=1 +dport_map_port_13=1 +dport_map_port_14=2 +dport_map_port_34=3 +dport_map_port_35=4 +dport_map_port_38=5 +dport_map_port_39=6 +dport_map_port_42=7 +dport_map_port_43=8 +dport_map_port_1=9 +dport_map_port_2=10 +dport_map_port_5=11 +dport_map_port_6=12 +dport_map_port_9=13 +dport_map_port_10=14 +dport_map_port_46=15 +dport_map_port_47=16 + +dport_map_port_69=17 +dport_map_port_68=18 +dport_map_port_107=19 +dport_map_port_106=20 +dport_map_port_111=21 +dport_map_port_110=22 +dport_map_port_115=23 +dport_map_port_114=24 +dport_map_port_73=25 +dport_map_port_72=26 +dport_map_port_77=27 +dport_map_port_76=28 +dport_map_port_81=29 +dport_map_port_80=30 +dport_map_port_103=31 +dport_map_port_102=32 + +dport_map_port_16=33 +dport_map_port_15=34 +dport_map_port_37=35 +dport_map_port_36=36 +dport_map_port_41=37 +dport_map_port_40=38 +dport_map_port_45=39 +dport_map_port_44=40 +dport_map_port_4=41 +dport_map_port_3=42 +dport_map_port_8=43 +dport_map_port_7=44 +dport_map_port_12=45 +dport_map_port_11=46 +dport_map_port_49=47 +dport_map_port_48=48 + +dport_map_port_70=49 +dport_map_port_71=50 +dport_map_port_108=51 +dport_map_port_109=52 +dport_map_port_112=53 +dport_map_port_113=54 +dport_map_port_116=55 +dport_map_port_117=56 +dport_map_port_74=57 +dport_map_port_75=58 +dport_map_port_78=59 +dport_map_port_79=60 +dport_map_port_82=61 +dport_map_port_83=62 +dport_map_port_104=63 +dport_map_port_105=64 + +# +# Tile-0 FC0~FC15 +# +portmap_1=1:40 +portmap_2=5:40 +portmap_3=9:40 +portmap_4=13:40 +portmap_5=17:40 +portmap_6=21:40 +portmap_7=25:40 +portmap_8=29:40 +portmap_9=33:40 +portmap_10=37:40 +portmap_11=41:40 +portmap_12=45:40 +portmap_13=49:40 +portmap_14=53:40 +portmap_15=57:40 +portmap_16=61:40 + +# TX polarity +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_tx_polarity_flip_physical{3.0}=0x1 +phy_chain_tx_polarity_flip_physical{4.0}=0x1 + +phy_chain_tx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x0 +phy_chain_tx_polarity_flip_physical{7.0}=0x1 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 + +phy_chain_tx_polarity_flip_physical{9.0}=0x0 +phy_chain_tx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x1 + +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_tx_polarity_flip_physical{16.0}=0x1 + +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_tx_polarity_flip_physical{18.0}=0x0 +phy_chain_tx_polarity_flip_physical{19.0}=0x1 +phy_chain_tx_polarity_flip_physical{20.0}=0x1 + +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_tx_polarity_flip_physical{24.0}=0x1 + +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_tx_polarity_flip_physical{26.0}=0x1 +phy_chain_tx_polarity_flip_physical{27.0}=0x1 +phy_chain_tx_polarity_flip_physical{28.0}=0x1 + +phy_chain_tx_polarity_flip_physical{29.0}=0x1 +phy_chain_tx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_tx_polarity_flip_physical{32.0}=0x1 + +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_tx_polarity_flip_physical{36.0}=0x1 + +phy_chain_tx_polarity_flip_physical{37.0}=0x0 +phy_chain_tx_polarity_flip_physical{38.0}=0x1 +phy_chain_tx_polarity_flip_physical{39.0}=0x0 +phy_chain_tx_polarity_flip_physical{40.0}=0x1 + +phy_chain_tx_polarity_flip_physical{41.0}=0x1 +phy_chain_tx_polarity_flip_physical{42.0}=0x1 +phy_chain_tx_polarity_flip_physical{43.0}=0x0 +phy_chain_tx_polarity_flip_physical{44.0}=0x0 + +phy_chain_tx_polarity_flip_physical{45.0}=0x0 +phy_chain_tx_polarity_flip_physical{46.0}=0x0 +phy_chain_tx_polarity_flip_physical{47.0}=0x0 +phy_chain_tx_polarity_flip_physical{48.0}=0x1 + +phy_chain_tx_polarity_flip_physical{49.0}=0x0 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 + +phy_chain_tx_polarity_flip_physical{53.0}=0x0 +phy_chain_tx_polarity_flip_physical{54.0}=0x0 +phy_chain_tx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x1 + +phy_chain_tx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x0 + +phy_chain_tx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x1 +phy_chain_tx_polarity_flip_physical{63.0}=0x0 +phy_chain_tx_polarity_flip_physical{64.0}=0x1 + +# RX polarity +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 + +phy_chain_rx_polarity_flip_physical{5.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x0 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 + +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{10.0}=0x1 +phy_chain_rx_polarity_flip_physical{11.0}=0x0 +phy_chain_rx_polarity_flip_physical{12.0}=0x0 + +phy_chain_rx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_rx_polarity_flip_physical{16.0}=0x0 + +phy_chain_rx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{18.0}=0x1 +phy_chain_rx_polarity_flip_physical{19.0}=0x1 +phy_chain_rx_polarity_flip_physical{20.0}=0x0 + +phy_chain_rx_polarity_flip_physical{21.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x0 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_rx_polarity_flip_physical{24.0}=0x0 + +phy_chain_rx_polarity_flip_physical{25.0}=0x1 +phy_chain_rx_polarity_flip_physical{26.0}=0x0 +phy_chain_rx_polarity_flip_physical{27.0}=0x0 +phy_chain_rx_polarity_flip_physical{28.0}=0x1 + +phy_chain_rx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{31.0}=0x1 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 + +phy_chain_rx_polarity_flip_physical{33.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{36.0}=0x1 + +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x0 +phy_chain_rx_polarity_flip_physical{39.0}=0x0 +phy_chain_rx_polarity_flip_physical{40.0}=0x1 + +phy_chain_rx_polarity_flip_physical{41.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x0 + +phy_chain_rx_polarity_flip_physical{45.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{47.0}=0x0 +phy_chain_rx_polarity_flip_physical{48.0}=0x1 + +phy_chain_rx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x1 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x0 + +phy_chain_rx_polarity_flip_physical{53.0}=0x1 +phy_chain_rx_polarity_flip_physical{54.0}=0x0 +phy_chain_rx_polarity_flip_physical{55.0}=0x0 +phy_chain_rx_polarity_flip_physical{56.0}=0x1 + +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_rx_polarity_flip_physical{59.0}=0x1 +phy_chain_rx_polarity_flip_physical{60.0}=0x0 + +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_rx_polarity_flip_physical{63.0}=0x0 +phy_chain_rx_polarity_flip_physical{64.0}=0x1 + +# TX lane swap +phy_chain_tx_lane_map_physical{1.0}=0x3120 +phy_chain_tx_lane_map_physical{5.0}=0x2130 +phy_chain_tx_lane_map_physical{9.0}=0x0213 +phy_chain_tx_lane_map_physical{13.0}=0x3021 + +phy_chain_tx_lane_map_physical{17.0}=0x3201 +phy_chain_tx_lane_map_physical{21.0}=0x3210 +phy_chain_tx_lane_map_physical{25.0}=0x1023 +phy_chain_tx_lane_map_physical{29.0}=0x0231 + +phy_chain_tx_lane_map_physical{33.0}=0x3210 +phy_chain_tx_lane_map_physical{37.0}=0x3120 +phy_chain_tx_lane_map_physical{41.0}=0x2031 +phy_chain_tx_lane_map_physical{45.0}=0x2130 + +phy_chain_tx_lane_map_physical{49.0}=0x2130 +phy_chain_tx_lane_map_physical{53.0}=0x3012 +phy_chain_tx_lane_map_physical{57.0}=0x2031 +phy_chain_tx_lane_map_physical{61.0}=0x0231 + +# RX lane swap +phy_chain_rx_lane_map_physical{1.0}=0x1320 +phy_chain_rx_lane_map_physical{5.0}=0x0213 +phy_chain_rx_lane_map_physical{9.0}=0x2301 +phy_chain_rx_lane_map_physical{13.0}=0x0321 + +phy_chain_rx_lane_map_physical{17.0}=0x2031 +phy_chain_rx_lane_map_physical{21.0}=0x1032 +phy_chain_rx_lane_map_physical{25.0}=0x2310 +phy_chain_rx_lane_map_physical{29.0}=0x2013 + +phy_chain_rx_lane_map_physical{33.0}=0x2103 +phy_chain_rx_lane_map_physical{37.0}=0x0132 +phy_chain_rx_lane_map_physical{41.0}=0x2031 +phy_chain_rx_lane_map_physical{45.0}=0x1032 + +phy_chain_rx_lane_map_physical{49.0}=0x3201 +phy_chain_rx_lane_map_physical{53.0}=0x0132 +phy_chain_rx_lane_map_physical{57.0}=0x2031 +phy_chain_rx_lane_map_physical{61.0}=0x1032 + +# +# Tile-1 FC16~FC31 +# +portmap_34=65:40 +portmap_35=69:40 +portmap_36=73:40 +portmap_37=77:40 +portmap_38=81:40 +portmap_39=85:40 +portmap_40=89:40 +portmap_41=93:40 +portmap_42=97:40 +portmap_43=101:40 +portmap_44=105:40 +portmap_45=109:40 +portmap_46=113:40 +portmap_47=117:40 +portmap_48=121:40 +portmap_49=125:40 + +#TX polarity +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_tx_polarity_flip_physical{66.0}=0x1 +phy_chain_tx_polarity_flip_physical{67.0}=0x0 +phy_chain_tx_polarity_flip_physical{68.0}=0x0 + +phy_chain_tx_polarity_flip_physical{69.0}=0x1 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_tx_polarity_flip_physical{72.0}=0x1 + +phy_chain_tx_polarity_flip_physical{73.0}=0x0 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_tx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x0 + +phy_chain_tx_polarity_flip_physical{77.0}=0x1 +phy_chain_tx_polarity_flip_physical{78.0}=0x1 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x1 + +phy_chain_tx_polarity_flip_physical{81.0}=0x1 +phy_chain_tx_polarity_flip_physical{82.0}=0x1 +phy_chain_tx_polarity_flip_physical{83.0}=0x0 +phy_chain_tx_polarity_flip_physical{84.0}=0x0 + +phy_chain_tx_polarity_flip_physical{85.0}=0x1 +phy_chain_tx_polarity_flip_physical{86.0}=0x1 +phy_chain_tx_polarity_flip_physical{87.0}=0x0 +phy_chain_tx_polarity_flip_physical{88.0}=0x0 + +phy_chain_tx_polarity_flip_physical{89.0}=0x0 +phy_chain_tx_polarity_flip_physical{90.0}=0x1 +phy_chain_tx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x0 + +phy_chain_tx_polarity_flip_physical{93.0}=0x1 +phy_chain_tx_polarity_flip_physical{94.0}=0x1 +phy_chain_tx_polarity_flip_physical{95.0}=0x1 +phy_chain_tx_polarity_flip_physical{96.0}=0x1 + +phy_chain_tx_polarity_flip_physical{97.0}=0x0 +phy_chain_tx_polarity_flip_physical{98.0}=0x0 +phy_chain_tx_polarity_flip_physical{99.0}=0x0 +phy_chain_tx_polarity_flip_physical{100.0}=0x1 + +phy_chain_tx_polarity_flip_physical{101.0}=0x1 +phy_chain_tx_polarity_flip_physical{102.0}=0x0 +phy_chain_tx_polarity_flip_physical{103.0}=0x1 +phy_chain_tx_polarity_flip_physical{104.0}=0x0 + +phy_chain_tx_polarity_flip_physical{105.0}=0x0 +phy_chain_tx_polarity_flip_physical{106.0}=0x1 +phy_chain_tx_polarity_flip_physical{107.0}=0x0 +phy_chain_tx_polarity_flip_physical{108.0}=0x0 + +phy_chain_tx_polarity_flip_physical{109.0}=0x0 +phy_chain_tx_polarity_flip_physical{110.0}=0x1 +phy_chain_tx_polarity_flip_physical{111.0}=0x0 +phy_chain_tx_polarity_flip_physical{112.0}=0x0 + +phy_chain_tx_polarity_flip_physical{113.0}=0x1 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x0 +phy_chain_tx_polarity_flip_physical{116.0}=0x0 + +phy_chain_tx_polarity_flip_physical{117.0}=0x0 +phy_chain_tx_polarity_flip_physical{118.0}=0x1 +phy_chain_tx_polarity_flip_physical{119.0}=0x0 +phy_chain_tx_polarity_flip_physical{120.0}=0x0 + +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_tx_polarity_flip_physical{122.0}=0x0 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 + +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_tx_polarity_flip_physical{126.0}=0x1 +phy_chain_tx_polarity_flip_physical{127.0}=0x1 +phy_chain_tx_polarity_flip_physical{128.0}=0x1 + +#RX polarity +phy_chain_rx_polarity_flip_physical{65.0}=0x0 +phy_chain_rx_polarity_flip_physical{66.0}=0x0 +phy_chain_rx_polarity_flip_physical{67.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x1 + +phy_chain_rx_polarity_flip_physical{69.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 + +phy_chain_rx_polarity_flip_physical{73.0}=0x0 +phy_chain_rx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{75.0}=0x1 +phy_chain_rx_polarity_flip_physical{76.0}=0x0 + +phy_chain_rx_polarity_flip_physical{77.0}=0x1 +phy_chain_rx_polarity_flip_physical{78.0}=0x1 +phy_chain_rx_polarity_flip_physical{79.0}=0x0 +phy_chain_rx_polarity_flip_physical{80.0}=0x1 + +phy_chain_rx_polarity_flip_physical{81.0}=0x0 +phy_chain_rx_polarity_flip_physical{82.0}=0x0 +phy_chain_rx_polarity_flip_physical{83.0}=0x0 +phy_chain_rx_polarity_flip_physical{84.0}=0x1 + +phy_chain_rx_polarity_flip_physical{85.0}=0x0 +phy_chain_rx_polarity_flip_physical{86.0}=0x0 +phy_chain_rx_polarity_flip_physical{87.0}=0x1 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 + +phy_chain_rx_polarity_flip_physical{89.0}=0x0 +phy_chain_rx_polarity_flip_physical{90.0}=0x1 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_rx_polarity_flip_physical{92.0}=0x0 + +phy_chain_rx_polarity_flip_physical{93.0}=0x0 +phy_chain_rx_polarity_flip_physical{94.0}=0x1 +phy_chain_rx_polarity_flip_physical{95.0}=0x0 +phy_chain_rx_polarity_flip_physical{96.0}=0x0 + +phy_chain_rx_polarity_flip_physical{97.0}=0x0 +phy_chain_rx_polarity_flip_physical{98.0}=0x1 +phy_chain_rx_polarity_flip_physical{99.0}=0x0 +phy_chain_rx_polarity_flip_physical{100.0}=0x1 + +phy_chain_rx_polarity_flip_physical{101.0}=0x0 +phy_chain_rx_polarity_flip_physical{102.0}=0x0 +phy_chain_rx_polarity_flip_physical{103.0}=0x1 +phy_chain_rx_polarity_flip_physical{104.0}=0x1 + +phy_chain_rx_polarity_flip_physical{105.0}=0x1 +phy_chain_rx_polarity_flip_physical{106.0}=0x0 +phy_chain_rx_polarity_flip_physical{107.0}=0x0 +phy_chain_rx_polarity_flip_physical{108.0}=0x1 + +phy_chain_rx_polarity_flip_physical{109.0}=0x0 +phy_chain_rx_polarity_flip_physical{110.0}=0x1 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{112.0}=0x1 + +phy_chain_rx_polarity_flip_physical{113.0}=0x0 +phy_chain_rx_polarity_flip_physical{114.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x1 +phy_chain_rx_polarity_flip_physical{116.0}=0x0 + +phy_chain_rx_polarity_flip_physical{117.0}=0x1 +phy_chain_rx_polarity_flip_physical{118.0}=0x0 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{120.0}=0x0 + +phy_chain_rx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x0 +phy_chain_rx_polarity_flip_physical{124.0}=0x0 + +phy_chain_rx_polarity_flip_physical{125.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x1 +phy_chain_rx_polarity_flip_physical{127.0}=0x1 +phy_chain_rx_polarity_flip_physical{128.0}=0x0 + +# TX lane swap +phy_chain_tx_lane_map_physical{65.0}=0x2130 +phy_chain_tx_lane_map_physical{69.0}=0x3012 +phy_chain_tx_lane_map_physical{73.0}=0x2031 +phy_chain_tx_lane_map_physical{77.0}=0x0231 + +phy_chain_tx_lane_map_physical{81.0}=0x2130 +phy_chain_tx_lane_map_physical{85.0}=0x1032 +phy_chain_tx_lane_map_physical{89.0}=0x2031 +phy_chain_tx_lane_map_physical{93.0}=0x0231 + +phy_chain_tx_lane_map_physical{97.0}=0x0123 +phy_chain_tx_lane_map_physical{101.0}=0x1320 +phy_chain_tx_lane_map_physical{105.0}=0x2301 +phy_chain_tx_lane_map_physical{109.0}=0x0213 + +phy_chain_tx_lane_map_physical{113.0}=0x0123 +phy_chain_tx_lane_map_physical{117.0}=0x1023 +phy_chain_tx_lane_map_physical{121.0}=0x2130 +phy_chain_tx_lane_map_physical{125.0}=0x1302 + +# RX lane swap +phy_chain_rx_lane_map_physical{65.0}=0x2103 +phy_chain_rx_lane_map_physical{69.0}=0x3210 +phy_chain_rx_lane_map_physical{73.0}=0x2031 +phy_chain_rx_lane_map_physical{77.0}=0x1032 + +phy_chain_rx_lane_map_physical{81.0}=0x2103 +phy_chain_rx_lane_map_physical{85.0}=0x3210 +phy_chain_rx_lane_map_physical{89.0}=0x2031 +phy_chain_rx_lane_map_physical{93.0}=0x1032 + +phy_chain_rx_lane_map_physical{97.0}=0x1023 +phy_chain_rx_lane_map_physical{101.0}=0x3120 +phy_chain_rx_lane_map_physical{105.0}=0x1023 +phy_chain_rx_lane_map_physical{109.0}=0x0231 + +phy_chain_rx_lane_map_physical{113.0}=0x1320 +phy_chain_rx_lane_map_physical{117.0}=0x3102 +phy_chain_rx_lane_map_physical{121.0}=0x0213 +phy_chain_rx_lane_map_physical{125.0}=0x0231 + +# +# Tile-2 FC32~FC47 +# +# port 66 is the first management port +portmap_66=257:10 +# port 67 is the second loopback port +#portmap_67=261:10 +portmap_68=129:40 +portmap_69=133:40 +portmap_70=137:40 +portmap_71=141:40 +portmap_72=145:40 +portmap_73=149:40 +portmap_74=153:40 +portmap_75=157:40 +portmap_76=161:40 +portmap_77=165:40 +portmap_78=169:40 +portmap_79=173:40 +portmap_80=177:40 +portmap_81=181:40 +portmap_82=185:40 +portmap_83=189:40 + +# TX polarity +phy_chain_tx_polarity_flip_physical{129.0}=0x1 +phy_chain_tx_polarity_flip_physical{130.0}=0x0 +phy_chain_tx_polarity_flip_physical{131.0}=0x1 +phy_chain_tx_polarity_flip_physical{132.0}=0x1 + +phy_chain_tx_polarity_flip_physical{133.0}=0x0 +phy_chain_tx_polarity_flip_physical{134.0}=0x0 +phy_chain_tx_polarity_flip_physical{135.0}=0x1 +phy_chain_tx_polarity_flip_physical{136.0}=0x1 + +phy_chain_tx_polarity_flip_physical{137.0}=0x1 +phy_chain_tx_polarity_flip_physical{138.0}=0x0 +phy_chain_tx_polarity_flip_physical{139.0}=0x1 +phy_chain_tx_polarity_flip_physical{140.0}=0x0 + +phy_chain_tx_polarity_flip_physical{141.0}=0x1 +phy_chain_tx_polarity_flip_physical{142.0}=0x0 +phy_chain_tx_polarity_flip_physical{143.0}=0x1 +phy_chain_tx_polarity_flip_physical{144.0}=0x1 + +phy_chain_tx_polarity_flip_physical{145.0}=0x1 +phy_chain_tx_polarity_flip_physical{146.0}=0x0 +phy_chain_tx_polarity_flip_physical{147.0}=0x0 +phy_chain_tx_polarity_flip_physical{148.0}=0x1 + +phy_chain_tx_polarity_flip_physical{149.0}=0x0 +phy_chain_tx_polarity_flip_physical{150.0}=0x1 +phy_chain_tx_polarity_flip_physical{151.0}=0x1 +phy_chain_tx_polarity_flip_physical{152.0}=0x1 + +phy_chain_tx_polarity_flip_physical{153.0}=0x0 +phy_chain_tx_polarity_flip_physical{154.0}=0x1 +phy_chain_tx_polarity_flip_physical{155.0}=0x0 +phy_chain_tx_polarity_flip_physical{156.0}=0x0 + +phy_chain_tx_polarity_flip_physical{157.0}=0x0 +phy_chain_tx_polarity_flip_physical{158.0}=0x0 +phy_chain_tx_polarity_flip_physical{159.0}=0x1 +phy_chain_tx_polarity_flip_physical{160.0}=0x0 + +phy_chain_tx_polarity_flip_physical{161.0}=0x1 +phy_chain_tx_polarity_flip_physical{162.0}=0x0 +phy_chain_tx_polarity_flip_physical{163.0}=0x0 +phy_chain_tx_polarity_flip_physical{164.0}=0x1 + +phy_chain_tx_polarity_flip_physical{165.0}=0x1 +phy_chain_tx_polarity_flip_physical{166.0}=0x0 +phy_chain_tx_polarity_flip_physical{167.0}=0x0 +phy_chain_tx_polarity_flip_physical{168.0}=0x0 + +phy_chain_tx_polarity_flip_physical{169.0}=0x0 +phy_chain_tx_polarity_flip_physical{170.0}=0x0 +phy_chain_tx_polarity_flip_physical{171.0}=0x0 +phy_chain_tx_polarity_flip_physical{172.0}=0x0 + +phy_chain_tx_polarity_flip_physical{173.0}=0x0 +phy_chain_tx_polarity_flip_physical{174.0}=0x1 +phy_chain_tx_polarity_flip_physical{175.0}=0x0 +phy_chain_tx_polarity_flip_physical{176.0}=0x1 + +phy_chain_tx_polarity_flip_physical{177.0}=0x0 +phy_chain_tx_polarity_flip_physical{178.0}=0x0 +phy_chain_tx_polarity_flip_physical{179.0}=0x0 +phy_chain_tx_polarity_flip_physical{180.0}=0x0 + +phy_chain_tx_polarity_flip_physical{181.0}=0x1 +phy_chain_tx_polarity_flip_physical{182.0}=0x0 +phy_chain_tx_polarity_flip_physical{183.0}=0x0 +phy_chain_tx_polarity_flip_physical{184.0}=0x0 + +phy_chain_tx_polarity_flip_physical{185.0}=0x0 +phy_chain_tx_polarity_flip_physical{186.0}=0x0 +phy_chain_tx_polarity_flip_physical{187.0}=0x0 +phy_chain_tx_polarity_flip_physical{188.0}=0x0 + +phy_chain_tx_polarity_flip_physical{189.0}=0x1 +phy_chain_tx_polarity_flip_physical{190.0}=0x0 +phy_chain_tx_polarity_flip_physical{191.0}=0x1 +phy_chain_tx_polarity_flip_physical{192.0}=0x0 + +# RX polarity +phy_chain_rx_polarity_flip_physical{129.0}=0x0 +phy_chain_rx_polarity_flip_physical{130.0}=0x0 +phy_chain_rx_polarity_flip_physical{131.0}=0x1 +phy_chain_rx_polarity_flip_physical{132.0}=0x0 + +phy_chain_rx_polarity_flip_physical{133.0}=0x0 +phy_chain_rx_polarity_flip_physical{134.0}=0x1 +phy_chain_rx_polarity_flip_physical{135.0}=0x1 +phy_chain_rx_polarity_flip_physical{136.0}=0x0 + +phy_chain_rx_polarity_flip_physical{137.0}=0x1 +phy_chain_rx_polarity_flip_physical{138.0}=0x0 +phy_chain_rx_polarity_flip_physical{139.0}=0x1 +phy_chain_rx_polarity_flip_physical{140.0}=0x1 + +phy_chain_rx_polarity_flip_physical{141.0}=0x0 +phy_chain_rx_polarity_flip_physical{142.0}=0x0 +phy_chain_rx_polarity_flip_physical{143.0}=0x1 +phy_chain_rx_polarity_flip_physical{144.0}=0x1 + +phy_chain_rx_polarity_flip_physical{145.0}=0x0 +phy_chain_rx_polarity_flip_physical{146.0}=0x0 +phy_chain_rx_polarity_flip_physical{147.0}=0x1 +phy_chain_rx_polarity_flip_physical{148.0}=0x0 + +phy_chain_rx_polarity_flip_physical{149.0}=0x0 +phy_chain_rx_polarity_flip_physical{150.0}=0x1 +phy_chain_rx_polarity_flip_physical{151.0}=0x1 +phy_chain_rx_polarity_flip_physical{152.0}=0x0 + +phy_chain_rx_polarity_flip_physical{153.0}=0x0 +phy_chain_rx_polarity_flip_physical{154.0}=0x1 +phy_chain_rx_polarity_flip_physical{155.0}=0x0 +phy_chain_rx_polarity_flip_physical{156.0}=0x0 + +phy_chain_rx_polarity_flip_physical{157.0}=0x1 +phy_chain_rx_polarity_flip_physical{158.0}=0x1 +phy_chain_rx_polarity_flip_physical{159.0}=0x0 +phy_chain_rx_polarity_flip_physical{160.0}=0x0 + +phy_chain_rx_polarity_flip_physical{161.0}=0x1 +phy_chain_rx_polarity_flip_physical{162.0}=0x1 +phy_chain_rx_polarity_flip_physical{163.0}=0x0 +phy_chain_rx_polarity_flip_physical{164.0}=0x1 + +phy_chain_rx_polarity_flip_physical{165.0}=0x0 +phy_chain_rx_polarity_flip_physical{166.0}=0x1 +phy_chain_rx_polarity_flip_physical{167.0}=0x1 +phy_chain_rx_polarity_flip_physical{168.0}=0x0 + +phy_chain_rx_polarity_flip_physical{169.0}=0x0 +phy_chain_rx_polarity_flip_physical{170.0}=0x1 +phy_chain_rx_polarity_flip_physical{171.0}=0x0 +phy_chain_rx_polarity_flip_physical{172.0}=0x1 + +phy_chain_rx_polarity_flip_physical{173.0}=0x0 +phy_chain_rx_polarity_flip_physical{174.0}=0x1 +phy_chain_rx_polarity_flip_physical{175.0}=0x0 +phy_chain_rx_polarity_flip_physical{176.0}=0x0 + +phy_chain_rx_polarity_flip_physical{177.0}=0x1 +phy_chain_rx_polarity_flip_physical{178.0}=0x0 +phy_chain_rx_polarity_flip_physical{179.0}=0x0 +phy_chain_rx_polarity_flip_physical{180.0}=0x1 + +phy_chain_rx_polarity_flip_physical{181.0}=0x0 +phy_chain_rx_polarity_flip_physical{182.0}=0x1 +phy_chain_rx_polarity_flip_physical{183.0}=0x0 +phy_chain_rx_polarity_flip_physical{184.0}=0x1 + +phy_chain_rx_polarity_flip_physical{185.0}=0x1 +phy_chain_rx_polarity_flip_physical{186.0}=0x0 +phy_chain_rx_polarity_flip_physical{187.0}=0x1 +phy_chain_rx_polarity_flip_physical{188.0}=0x0 + +phy_chain_rx_polarity_flip_physical{189.0}=0x1 +phy_chain_rx_polarity_flip_physical{190.0}=0x1 +phy_chain_rx_polarity_flip_physical{191.0}=0x0 +phy_chain_rx_polarity_flip_physical{192.0}=0x0 + +# TX lane swap +phy_chain_tx_lane_map_physical{129.0}=0x0312 +phy_chain_tx_lane_map_physical{133.0}=0x3120 +phy_chain_tx_lane_map_physical{137.0}=0x1203 +phy_chain_tx_lane_map_physical{141.0}=0x0132 + +phy_chain_tx_lane_map_physical{145.0}=0x0312 +phy_chain_tx_lane_map_physical{149.0}=0x2310 +phy_chain_tx_lane_map_physical{153.0}=0x1032 +phy_chain_tx_lane_map_physical{157.0}=0x3120 + +phy_chain_tx_lane_map_physical{161.0}=0x1023 +phy_chain_tx_lane_map_physical{165.0}=0x1203 +phy_chain_tx_lane_map_physical{169.0}=0x0213 +phy_chain_tx_lane_map_physical{173.0}=0x0123 + +phy_chain_tx_lane_map_physical{177.0}=0x2031 +phy_chain_tx_lane_map_physical{181.0}=0x1203 +phy_chain_tx_lane_map_physical{185.0}=0x0213 +phy_chain_tx_lane_map_physical{189.0}=0x3210 + +# RX lane swap +phy_chain_rx_lane_map_physical{129.0}=0x0321 +phy_chain_rx_lane_map_physical{133.0}=0x0312 +phy_chain_rx_lane_map_physical{137.0}=0x2103 +phy_chain_rx_lane_map_physical{141.0}=0x0231 + +phy_chain_rx_lane_map_physical{145.0}=0x0321 +phy_chain_rx_lane_map_physical{149.0}=0x0312 +phy_chain_rx_lane_map_physical{153.0}=0x3120 +phy_chain_rx_lane_map_physical{157.0}=0x2103 + +phy_chain_rx_lane_map_physical{161.0}=0x1032 +phy_chain_rx_lane_map_physical{165.0}=0x2031 +phy_chain_rx_lane_map_physical{169.0}=0x0132 +phy_chain_rx_lane_map_physical{173.0}=0x2103 + +phy_chain_rx_lane_map_physical{177.0}=0x1032 +phy_chain_rx_lane_map_physical{181.0}=0x1230 +phy_chain_rx_lane_map_physical{185.0}=0x0321 +phy_chain_rx_lane_map_physical{189.0}=0x3201 + +# +# Tile-3 FC48~FC63 +# portmap_0=x:xx // cpu port (not required, but included for illustration purposes) +# +# port 100 is the second management port +portmap_100=259:10 +# port 101 is the third loopback port +#portmap_101=262:10 +portmap_102=193:40 +portmap_103=197:40 +portmap_104=201:40 +portmap_105=205:40 +portmap_106=209:40 +portmap_107=213:40 +portmap_108=217:40 +portmap_109=221:40 +portmap_110=225:40 +portmap_111=229:40 +portmap_112=233:40 +portmap_113=237:40 +portmap_114=241:40 +portmap_115=245:40 +portmap_116=249:40 +portmap_117=253:40 +# port 135 is the fourth loopback port +portmap_135=263:10 + +# TX polarity +phy_chain_tx_polarity_flip_physical{193.0}=0x0 +phy_chain_tx_polarity_flip_physical{194.0}=0x0 +phy_chain_tx_polarity_flip_physical{195.0}=0x0 +phy_chain_tx_polarity_flip_physical{196.0}=0x0 + +phy_chain_tx_polarity_flip_physical{197.0}=0x1 +phy_chain_tx_polarity_flip_physical{198.0}=0x0 +phy_chain_tx_polarity_flip_physical{199.0}=0x1 +phy_chain_tx_polarity_flip_physical{200.0}=0x0 + +phy_chain_tx_polarity_flip_physical{201.0}=0x0 +phy_chain_tx_polarity_flip_physical{202.0}=0x0 +phy_chain_tx_polarity_flip_physical{203.0}=0x0 +phy_chain_tx_polarity_flip_physical{204.0}=0x0 + +phy_chain_tx_polarity_flip_physical{205.0}=0x1 +phy_chain_tx_polarity_flip_physical{206.0}=0x0 +phy_chain_tx_polarity_flip_physical{207.0}=0x1 +phy_chain_tx_polarity_flip_physical{208.0}=0x0 + +phy_chain_tx_polarity_flip_physical{209.0}=0x1 +phy_chain_tx_polarity_flip_physical{210.0}=0x0 +phy_chain_tx_polarity_flip_physical{211.0}=0x0 +phy_chain_tx_polarity_flip_physical{212.0}=0x1 + +phy_chain_tx_polarity_flip_physical{213.0}=0x1 +phy_chain_tx_polarity_flip_physical{214.0}=0x0 +phy_chain_tx_polarity_flip_physical{215.0}=0x0 +phy_chain_tx_polarity_flip_physical{216.0}=0x0 + +phy_chain_tx_polarity_flip_physical{217.0}=0x0 +phy_chain_tx_polarity_flip_physical{218.0}=0x0 +phy_chain_tx_polarity_flip_physical{219.0}=0x0 +phy_chain_tx_polarity_flip_physical{220.0}=0x0 + +phy_chain_tx_polarity_flip_physical{221.0}=0x0 +phy_chain_tx_polarity_flip_physical{222.0}=0x1 +phy_chain_tx_polarity_flip_physical{223.0}=0x1 +phy_chain_tx_polarity_flip_physical{224.0}=0x0 + +phy_chain_tx_polarity_flip_physical{225.0}=0x1 +phy_chain_tx_polarity_flip_physical{226.0}=0x1 +phy_chain_tx_polarity_flip_physical{227.0}=0x0 +phy_chain_tx_polarity_flip_physical{228.0}=0x0 + +phy_chain_tx_polarity_flip_physical{229.0}=0x1 +phy_chain_tx_polarity_flip_physical{230.0}=0x1 +phy_chain_tx_polarity_flip_physical{231.0}=0x1 +phy_chain_tx_polarity_flip_physical{232.0}=0x1 + +phy_chain_tx_polarity_flip_physical{233.0}=0x0 +phy_chain_tx_polarity_flip_physical{234.0}=0x0 +phy_chain_tx_polarity_flip_physical{235.0}=0x1 +phy_chain_tx_polarity_flip_physical{236.0}=0x1 + +phy_chain_tx_polarity_flip_physical{237.0}=0x1 +phy_chain_tx_polarity_flip_physical{238.0}=0x1 +phy_chain_tx_polarity_flip_physical{239.0}=0x0 +phy_chain_tx_polarity_flip_physical{240.0}=0x0 + +phy_chain_tx_polarity_flip_physical{241.0}=0x0 +phy_chain_tx_polarity_flip_physical{242.0}=0x1 +phy_chain_tx_polarity_flip_physical{243.0}=0x0 +phy_chain_tx_polarity_flip_physical{244.0}=0x0 + +phy_chain_tx_polarity_flip_physical{245.0}=0x1 +phy_chain_tx_polarity_flip_physical{246.0}=0x0 +phy_chain_tx_polarity_flip_physical{247.0}=0x0 +phy_chain_tx_polarity_flip_physical{248.0}=0x0 + +phy_chain_tx_polarity_flip_physical{249.0}=0x0 +phy_chain_tx_polarity_flip_physical{250.0}=0x0 +phy_chain_tx_polarity_flip_physical{251.0}=0x0 +phy_chain_tx_polarity_flip_physical{252.0}=0x0 + +phy_chain_tx_polarity_flip_physical{253.0}=0x1 +phy_chain_tx_polarity_flip_physical{254.0}=0x0 +phy_chain_tx_polarity_flip_physical{255.0}=0x0 +phy_chain_tx_polarity_flip_physical{256.0}=0x0 + +# RX polarity +phy_chain_rx_polarity_flip_physical{193.0}=0x1 +phy_chain_rx_polarity_flip_physical{194.0}=0x0 +phy_chain_rx_polarity_flip_physical{195.0}=0x0 +phy_chain_rx_polarity_flip_physical{196.0}=0x1 + +phy_chain_rx_polarity_flip_physical{197.0}=0x1 +phy_chain_rx_polarity_flip_physical{198.0}=0x1 +phy_chain_rx_polarity_flip_physical{199.0}=0x0 +phy_chain_rx_polarity_flip_physical{200.0}=0x1 + +phy_chain_rx_polarity_flip_physical{201.0}=0x1 +phy_chain_rx_polarity_flip_physical{202.0}=0x0 +phy_chain_rx_polarity_flip_physical{203.0}=0x1 +phy_chain_rx_polarity_flip_physical{204.0}=0x1 + +phy_chain_rx_polarity_flip_physical{205.0}=0x1 +phy_chain_rx_polarity_flip_physical{206.0}=0x1 +phy_chain_rx_polarity_flip_physical{207.0}=0x0 +phy_chain_rx_polarity_flip_physical{208.0}=0x0 + +phy_chain_rx_polarity_flip_physical{209.0}=0x1 +phy_chain_rx_polarity_flip_physical{210.0}=0x1 +phy_chain_rx_polarity_flip_physical{211.0}=0x0 +phy_chain_rx_polarity_flip_physical{212.0}=0x1 + +phy_chain_rx_polarity_flip_physical{213.0}=0x0 +phy_chain_rx_polarity_flip_physical{214.0}=0x1 +phy_chain_rx_polarity_flip_physical{215.0}=0x1 +phy_chain_rx_polarity_flip_physical{216.0}=0x0 + +phy_chain_rx_polarity_flip_physical{217.0}=0x1 +phy_chain_rx_polarity_flip_physical{218.0}=0x0 +phy_chain_rx_polarity_flip_physical{219.0}=0x1 +phy_chain_rx_polarity_flip_physical{220.0}=0x1 + +phy_chain_rx_polarity_flip_physical{221.0}=0x1 +phy_chain_rx_polarity_flip_physical{222.0}=0x1 +phy_chain_rx_polarity_flip_physical{223.0}=0x0 +phy_chain_rx_polarity_flip_physical{224.0}=0x0 + +phy_chain_rx_polarity_flip_physical{225.0}=0x1 +phy_chain_rx_polarity_flip_physical{226.0}=0x1 +phy_chain_rx_polarity_flip_physical{227.0}=0x1 +phy_chain_rx_polarity_flip_physical{228.0}=0x0 + +phy_chain_rx_polarity_flip_physical{229.0}=0x1 +phy_chain_rx_polarity_flip_physical{230.0}=0x0 +phy_chain_rx_polarity_flip_physical{231.0}=0x0 +phy_chain_rx_polarity_flip_physical{232.0}=0x1 + +phy_chain_rx_polarity_flip_physical{233.0}=0x1 +phy_chain_rx_polarity_flip_physical{234.0}=0x1 +phy_chain_rx_polarity_flip_physical{235.0}=0x1 +phy_chain_rx_polarity_flip_physical{236.0}=0x0 + +phy_chain_rx_polarity_flip_physical{237.0}=0x0 +phy_chain_rx_polarity_flip_physical{238.0}=0x1 +phy_chain_rx_polarity_flip_physical{239.0}=0x0 +phy_chain_rx_polarity_flip_physical{240.0}=0x0 + +phy_chain_rx_polarity_flip_physical{241.0}=0x0 +phy_chain_rx_polarity_flip_physical{242.0}=0x1 +phy_chain_rx_polarity_flip_physical{243.0}=0x0 +phy_chain_rx_polarity_flip_physical{244.0}=0x1 + +phy_chain_rx_polarity_flip_physical{245.0}=0x1 +phy_chain_rx_polarity_flip_physical{246.0}=0x0 +phy_chain_rx_polarity_flip_physical{247.0}=0x0 +phy_chain_rx_polarity_flip_physical{248.0}=0x1 + +phy_chain_rx_polarity_flip_physical{249.0}=0x0 +phy_chain_rx_polarity_flip_physical{250.0}=0x0 +phy_chain_rx_polarity_flip_physical{251.0}=0x1 +phy_chain_rx_polarity_flip_physical{252.0}=0x0 + +phy_chain_rx_polarity_flip_physical{253.0}=0x1 +phy_chain_rx_polarity_flip_physical{254.0}=0x0 +phy_chain_rx_polarity_flip_physical{255.0}=0x0 +phy_chain_rx_polarity_flip_physical{256.0}=0x0 + +# TX lane swap +phy_chain_tx_lane_map_physical{193.0}=0x2031 +phy_chain_tx_lane_map_physical{197.0}=0x1203 +phy_chain_tx_lane_map_physical{201.0}=0x0213 +phy_chain_tx_lane_map_physical{205.0}=0x3210 + +phy_chain_tx_lane_map_physical{209.0}=0x1023 +phy_chain_tx_lane_map_physical{213.0}=0x1203 +phy_chain_tx_lane_map_physical{217.0}=0x0213 +phy_chain_tx_lane_map_physical{221.0}=0x3102 + +phy_chain_tx_lane_map_physical{225.0}=0x2031 +phy_chain_tx_lane_map_physical{229.0}=0x1023 +phy_chain_tx_lane_map_physical{233.0}=0x1320 +phy_chain_tx_lane_map_physical{237.0}=0x2013 + +phy_chain_tx_lane_map_physical{241.0}=0x1023 +phy_chain_tx_lane_map_physical{245.0}=0x1203 +phy_chain_tx_lane_map_physical{249.0}=0x3120 +phy_chain_tx_lane_map_physical{253.0}=0x3210 + +# RX lane swap +phy_chain_rx_lane_map_physical{193.0}=0x1032 +phy_chain_rx_lane_map_physical{197.0}=0x1230 +phy_chain_rx_lane_map_physical{201.0}=0x0321 +phy_chain_rx_lane_map_physical{205.0}=0x3201 + +phy_chain_rx_lane_map_physical{209.0}=0x3201 +phy_chain_rx_lane_map_physical{213.0}=0x2031 +phy_chain_rx_lane_map_physical{217.0}=0x0321 +phy_chain_rx_lane_map_physical{221.0}=0x3201 + +phy_chain_rx_lane_map_physical{225.0}=0x2103 +phy_chain_rx_lane_map_physical{229.0}=0x2310 +phy_chain_rx_lane_map_physical{233.0}=0x0213 +phy_chain_rx_lane_map_physical{237.0}=0x1032 + +phy_chain_rx_lane_map_physical{241.0}=0x0321 +phy_chain_rx_lane_map_physical{245.0}=0x2301 +phy_chain_rx_lane_map_physical{249.0}=0x2103 +phy_chain_rx_lane_map_physical{253.0}=0x2013 + +physical_ports=64 +logical_ports=136 +uplink_ports=2 +dport_map_port_66=65 +dport_map_port_100=66 + +module_64ports=1 + +mmu_init_config="MSFT-TH-Tier0" diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t1.config.bcm b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t1.config.bcm new file mode 100644 index 000000000000..8551d7b5b14d --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/th2-z9264f-64x40G-t1.config.bcm @@ -0,0 +1,1007 @@ +#TH2 Z9264F 64x40G +os=unix +core_clock_frequency=1700 +dpp_clock_ratio=2:3 +pbmp_xport_xe=0x3FFFD0000FFFF40003FFFC0001FFFE +oversubscribe_mode=1 +fpem_mem_entries=65536 +l2xmsg_mode=1 + +l3_alpm_enable=2 +bcm_num_cos=8 +switch_bypass_mode=0 +mmu_lossless=0 +lpm_scaling_enable=0 +lpm_ipv6_128b_reserved=0 +ipv6_lpm_128b_enable=1 + +parity_correction=1 +parity_enable=1 + +dport_map_enable=1 + +dport_map_enable=1 +dport_map_port_13=1 +dport_map_port_14=2 +dport_map_port_34=3 +dport_map_port_35=4 +dport_map_port_38=5 +dport_map_port_39=6 +dport_map_port_42=7 +dport_map_port_43=8 +dport_map_port_1=9 +dport_map_port_2=10 +dport_map_port_5=11 +dport_map_port_6=12 +dport_map_port_9=13 +dport_map_port_10=14 +dport_map_port_46=15 +dport_map_port_47=16 + +dport_map_port_69=17 +dport_map_port_68=18 +dport_map_port_107=19 +dport_map_port_106=20 +dport_map_port_111=21 +dport_map_port_110=22 +dport_map_port_115=23 +dport_map_port_114=24 +dport_map_port_73=25 +dport_map_port_72=26 +dport_map_port_77=27 +dport_map_port_76=28 +dport_map_port_81=29 +dport_map_port_80=30 +dport_map_port_103=31 +dport_map_port_102=32 + +dport_map_port_16=33 +dport_map_port_15=34 +dport_map_port_37=35 +dport_map_port_36=36 +dport_map_port_41=37 +dport_map_port_40=38 +dport_map_port_45=39 +dport_map_port_44=40 +dport_map_port_4=41 +dport_map_port_3=42 +dport_map_port_8=43 +dport_map_port_7=44 +dport_map_port_12=45 +dport_map_port_11=46 +dport_map_port_49=47 +dport_map_port_48=48 + +dport_map_port_70=49 +dport_map_port_71=50 +dport_map_port_108=51 +dport_map_port_109=52 +dport_map_port_112=53 +dport_map_port_113=54 +dport_map_port_116=55 +dport_map_port_117=56 +dport_map_port_74=57 +dport_map_port_75=58 +dport_map_port_78=59 +dport_map_port_79=60 +dport_map_port_82=61 +dport_map_port_83=62 +dport_map_port_104=63 +dport_map_port_105=64 + +# +# Tile-0 FC0~FC15 +# +portmap_1=1:40 +portmap_2=5:40 +portmap_3=9:40 +portmap_4=13:40 +portmap_5=17:40 +portmap_6=21:40 +portmap_7=25:40 +portmap_8=29:40 +portmap_9=33:40 +portmap_10=37:40 +portmap_11=41:40 +portmap_12=45:40 +portmap_13=49:40 +portmap_14=53:40 +portmap_15=57:40 +portmap_16=61:40 + +# TX polarity +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_tx_polarity_flip_physical{3.0}=0x1 +phy_chain_tx_polarity_flip_physical{4.0}=0x1 + +phy_chain_tx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x0 +phy_chain_tx_polarity_flip_physical{7.0}=0x1 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 + +phy_chain_tx_polarity_flip_physical{9.0}=0x0 +phy_chain_tx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x1 + +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_tx_polarity_flip_physical{16.0}=0x1 + +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_tx_polarity_flip_physical{18.0}=0x0 +phy_chain_tx_polarity_flip_physical{19.0}=0x1 +phy_chain_tx_polarity_flip_physical{20.0}=0x1 + +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_tx_polarity_flip_physical{24.0}=0x1 + +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_tx_polarity_flip_physical{26.0}=0x1 +phy_chain_tx_polarity_flip_physical{27.0}=0x1 +phy_chain_tx_polarity_flip_physical{28.0}=0x1 + +phy_chain_tx_polarity_flip_physical{29.0}=0x1 +phy_chain_tx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_tx_polarity_flip_physical{32.0}=0x1 + +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_tx_polarity_flip_physical{36.0}=0x1 + +phy_chain_tx_polarity_flip_physical{37.0}=0x0 +phy_chain_tx_polarity_flip_physical{38.0}=0x1 +phy_chain_tx_polarity_flip_physical{39.0}=0x0 +phy_chain_tx_polarity_flip_physical{40.0}=0x1 + +phy_chain_tx_polarity_flip_physical{41.0}=0x1 +phy_chain_tx_polarity_flip_physical{42.0}=0x1 +phy_chain_tx_polarity_flip_physical{43.0}=0x0 +phy_chain_tx_polarity_flip_physical{44.0}=0x0 + +phy_chain_tx_polarity_flip_physical{45.0}=0x0 +phy_chain_tx_polarity_flip_physical{46.0}=0x0 +phy_chain_tx_polarity_flip_physical{47.0}=0x0 +phy_chain_tx_polarity_flip_physical{48.0}=0x1 + +phy_chain_tx_polarity_flip_physical{49.0}=0x0 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 + +phy_chain_tx_polarity_flip_physical{53.0}=0x0 +phy_chain_tx_polarity_flip_physical{54.0}=0x0 +phy_chain_tx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x1 + +phy_chain_tx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x0 + +phy_chain_tx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x1 +phy_chain_tx_polarity_flip_physical{63.0}=0x0 +phy_chain_tx_polarity_flip_physical{64.0}=0x1 + +# RX polarity +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 + +phy_chain_rx_polarity_flip_physical{5.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x0 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 + +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{10.0}=0x1 +phy_chain_rx_polarity_flip_physical{11.0}=0x0 +phy_chain_rx_polarity_flip_physical{12.0}=0x0 + +phy_chain_rx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_rx_polarity_flip_physical{16.0}=0x0 + +phy_chain_rx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{18.0}=0x1 +phy_chain_rx_polarity_flip_physical{19.0}=0x1 +phy_chain_rx_polarity_flip_physical{20.0}=0x0 + +phy_chain_rx_polarity_flip_physical{21.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x0 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_rx_polarity_flip_physical{24.0}=0x0 + +phy_chain_rx_polarity_flip_physical{25.0}=0x1 +phy_chain_rx_polarity_flip_physical{26.0}=0x0 +phy_chain_rx_polarity_flip_physical{27.0}=0x0 +phy_chain_rx_polarity_flip_physical{28.0}=0x1 + +phy_chain_rx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{31.0}=0x1 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 + +phy_chain_rx_polarity_flip_physical{33.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{36.0}=0x1 + +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x0 +phy_chain_rx_polarity_flip_physical{39.0}=0x0 +phy_chain_rx_polarity_flip_physical{40.0}=0x1 + +phy_chain_rx_polarity_flip_physical{41.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x0 + +phy_chain_rx_polarity_flip_physical{45.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{47.0}=0x0 +phy_chain_rx_polarity_flip_physical{48.0}=0x1 + +phy_chain_rx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x1 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x0 + +phy_chain_rx_polarity_flip_physical{53.0}=0x1 +phy_chain_rx_polarity_flip_physical{54.0}=0x0 +phy_chain_rx_polarity_flip_physical{55.0}=0x0 +phy_chain_rx_polarity_flip_physical{56.0}=0x1 + +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_rx_polarity_flip_physical{59.0}=0x1 +phy_chain_rx_polarity_flip_physical{60.0}=0x0 + +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_rx_polarity_flip_physical{63.0}=0x0 +phy_chain_rx_polarity_flip_physical{64.0}=0x1 + +# TX lane swap +phy_chain_tx_lane_map_physical{1.0}=0x3120 +phy_chain_tx_lane_map_physical{5.0}=0x2130 +phy_chain_tx_lane_map_physical{9.0}=0x0213 +phy_chain_tx_lane_map_physical{13.0}=0x3021 + +phy_chain_tx_lane_map_physical{17.0}=0x3201 +phy_chain_tx_lane_map_physical{21.0}=0x3210 +phy_chain_tx_lane_map_physical{25.0}=0x1023 +phy_chain_tx_lane_map_physical{29.0}=0x0231 + +phy_chain_tx_lane_map_physical{33.0}=0x3210 +phy_chain_tx_lane_map_physical{37.0}=0x3120 +phy_chain_tx_lane_map_physical{41.0}=0x2031 +phy_chain_tx_lane_map_physical{45.0}=0x2130 + +phy_chain_tx_lane_map_physical{49.0}=0x2130 +phy_chain_tx_lane_map_physical{53.0}=0x3012 +phy_chain_tx_lane_map_physical{57.0}=0x2031 +phy_chain_tx_lane_map_physical{61.0}=0x0231 + +# RX lane swap +phy_chain_rx_lane_map_physical{1.0}=0x1320 +phy_chain_rx_lane_map_physical{5.0}=0x0213 +phy_chain_rx_lane_map_physical{9.0}=0x2301 +phy_chain_rx_lane_map_physical{13.0}=0x0321 + +phy_chain_rx_lane_map_physical{17.0}=0x2031 +phy_chain_rx_lane_map_physical{21.0}=0x1032 +phy_chain_rx_lane_map_physical{25.0}=0x2310 +phy_chain_rx_lane_map_physical{29.0}=0x2013 + +phy_chain_rx_lane_map_physical{33.0}=0x2103 +phy_chain_rx_lane_map_physical{37.0}=0x0132 +phy_chain_rx_lane_map_physical{41.0}=0x2031 +phy_chain_rx_lane_map_physical{45.0}=0x1032 + +phy_chain_rx_lane_map_physical{49.0}=0x3201 +phy_chain_rx_lane_map_physical{53.0}=0x0132 +phy_chain_rx_lane_map_physical{57.0}=0x2031 +phy_chain_rx_lane_map_physical{61.0}=0x1032 + +# +# Tile-1 FC16~FC31 +# +portmap_34=65:40 +portmap_35=69:40 +portmap_36=73:40 +portmap_37=77:40 +portmap_38=81:40 +portmap_39=85:40 +portmap_40=89:40 +portmap_41=93:40 +portmap_42=97:40 +portmap_43=101:40 +portmap_44=105:40 +portmap_45=109:40 +portmap_46=113:40 +portmap_47=117:40 +portmap_48=121:40 +portmap_49=125:40 + +#TX polarity +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_tx_polarity_flip_physical{66.0}=0x1 +phy_chain_tx_polarity_flip_physical{67.0}=0x0 +phy_chain_tx_polarity_flip_physical{68.0}=0x0 + +phy_chain_tx_polarity_flip_physical{69.0}=0x1 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_tx_polarity_flip_physical{72.0}=0x1 + +phy_chain_tx_polarity_flip_physical{73.0}=0x0 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_tx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x0 + +phy_chain_tx_polarity_flip_physical{77.0}=0x1 +phy_chain_tx_polarity_flip_physical{78.0}=0x1 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x1 + +phy_chain_tx_polarity_flip_physical{81.0}=0x1 +phy_chain_tx_polarity_flip_physical{82.0}=0x1 +phy_chain_tx_polarity_flip_physical{83.0}=0x0 +phy_chain_tx_polarity_flip_physical{84.0}=0x0 + +phy_chain_tx_polarity_flip_physical{85.0}=0x1 +phy_chain_tx_polarity_flip_physical{86.0}=0x1 +phy_chain_tx_polarity_flip_physical{87.0}=0x0 +phy_chain_tx_polarity_flip_physical{88.0}=0x0 + +phy_chain_tx_polarity_flip_physical{89.0}=0x0 +phy_chain_tx_polarity_flip_physical{90.0}=0x1 +phy_chain_tx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x0 + +phy_chain_tx_polarity_flip_physical{93.0}=0x1 +phy_chain_tx_polarity_flip_physical{94.0}=0x1 +phy_chain_tx_polarity_flip_physical{95.0}=0x1 +phy_chain_tx_polarity_flip_physical{96.0}=0x1 + +phy_chain_tx_polarity_flip_physical{97.0}=0x0 +phy_chain_tx_polarity_flip_physical{98.0}=0x0 +phy_chain_tx_polarity_flip_physical{99.0}=0x0 +phy_chain_tx_polarity_flip_physical{100.0}=0x1 + +phy_chain_tx_polarity_flip_physical{101.0}=0x1 +phy_chain_tx_polarity_flip_physical{102.0}=0x0 +phy_chain_tx_polarity_flip_physical{103.0}=0x1 +phy_chain_tx_polarity_flip_physical{104.0}=0x0 + +phy_chain_tx_polarity_flip_physical{105.0}=0x0 +phy_chain_tx_polarity_flip_physical{106.0}=0x1 +phy_chain_tx_polarity_flip_physical{107.0}=0x0 +phy_chain_tx_polarity_flip_physical{108.0}=0x0 + +phy_chain_tx_polarity_flip_physical{109.0}=0x0 +phy_chain_tx_polarity_flip_physical{110.0}=0x1 +phy_chain_tx_polarity_flip_physical{111.0}=0x0 +phy_chain_tx_polarity_flip_physical{112.0}=0x0 + +phy_chain_tx_polarity_flip_physical{113.0}=0x1 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x0 +phy_chain_tx_polarity_flip_physical{116.0}=0x0 + +phy_chain_tx_polarity_flip_physical{117.0}=0x0 +phy_chain_tx_polarity_flip_physical{118.0}=0x1 +phy_chain_tx_polarity_flip_physical{119.0}=0x0 +phy_chain_tx_polarity_flip_physical{120.0}=0x0 + +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_tx_polarity_flip_physical{122.0}=0x0 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 + +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_tx_polarity_flip_physical{126.0}=0x1 +phy_chain_tx_polarity_flip_physical{127.0}=0x1 +phy_chain_tx_polarity_flip_physical{128.0}=0x1 + +#RX polarity +phy_chain_rx_polarity_flip_physical{65.0}=0x0 +phy_chain_rx_polarity_flip_physical{66.0}=0x0 +phy_chain_rx_polarity_flip_physical{67.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x1 + +phy_chain_rx_polarity_flip_physical{69.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 + +phy_chain_rx_polarity_flip_physical{73.0}=0x0 +phy_chain_rx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{75.0}=0x1 +phy_chain_rx_polarity_flip_physical{76.0}=0x0 + +phy_chain_rx_polarity_flip_physical{77.0}=0x1 +phy_chain_rx_polarity_flip_physical{78.0}=0x1 +phy_chain_rx_polarity_flip_physical{79.0}=0x0 +phy_chain_rx_polarity_flip_physical{80.0}=0x1 + +phy_chain_rx_polarity_flip_physical{81.0}=0x0 +phy_chain_rx_polarity_flip_physical{82.0}=0x0 +phy_chain_rx_polarity_flip_physical{83.0}=0x0 +phy_chain_rx_polarity_flip_physical{84.0}=0x1 + +phy_chain_rx_polarity_flip_physical{85.0}=0x0 +phy_chain_rx_polarity_flip_physical{86.0}=0x0 +phy_chain_rx_polarity_flip_physical{87.0}=0x1 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 + +phy_chain_rx_polarity_flip_physical{89.0}=0x0 +phy_chain_rx_polarity_flip_physical{90.0}=0x1 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_rx_polarity_flip_physical{92.0}=0x0 + +phy_chain_rx_polarity_flip_physical{93.0}=0x0 +phy_chain_rx_polarity_flip_physical{94.0}=0x1 +phy_chain_rx_polarity_flip_physical{95.0}=0x0 +phy_chain_rx_polarity_flip_physical{96.0}=0x0 + +phy_chain_rx_polarity_flip_physical{97.0}=0x0 +phy_chain_rx_polarity_flip_physical{98.0}=0x1 +phy_chain_rx_polarity_flip_physical{99.0}=0x0 +phy_chain_rx_polarity_flip_physical{100.0}=0x1 + +phy_chain_rx_polarity_flip_physical{101.0}=0x0 +phy_chain_rx_polarity_flip_physical{102.0}=0x0 +phy_chain_rx_polarity_flip_physical{103.0}=0x1 +phy_chain_rx_polarity_flip_physical{104.0}=0x1 + +phy_chain_rx_polarity_flip_physical{105.0}=0x1 +phy_chain_rx_polarity_flip_physical{106.0}=0x0 +phy_chain_rx_polarity_flip_physical{107.0}=0x0 +phy_chain_rx_polarity_flip_physical{108.0}=0x1 + +phy_chain_rx_polarity_flip_physical{109.0}=0x0 +phy_chain_rx_polarity_flip_physical{110.0}=0x1 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{112.0}=0x1 + +phy_chain_rx_polarity_flip_physical{113.0}=0x0 +phy_chain_rx_polarity_flip_physical{114.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x1 +phy_chain_rx_polarity_flip_physical{116.0}=0x0 + +phy_chain_rx_polarity_flip_physical{117.0}=0x1 +phy_chain_rx_polarity_flip_physical{118.0}=0x0 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{120.0}=0x0 + +phy_chain_rx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x0 +phy_chain_rx_polarity_flip_physical{124.0}=0x0 + +phy_chain_rx_polarity_flip_physical{125.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x1 +phy_chain_rx_polarity_flip_physical{127.0}=0x1 +phy_chain_rx_polarity_flip_physical{128.0}=0x0 + +# TX lane swap +phy_chain_tx_lane_map_physical{65.0}=0x2130 +phy_chain_tx_lane_map_physical{69.0}=0x3012 +phy_chain_tx_lane_map_physical{73.0}=0x2031 +phy_chain_tx_lane_map_physical{77.0}=0x0231 + +phy_chain_tx_lane_map_physical{81.0}=0x2130 +phy_chain_tx_lane_map_physical{85.0}=0x1032 +phy_chain_tx_lane_map_physical{89.0}=0x2031 +phy_chain_tx_lane_map_physical{93.0}=0x0231 + +phy_chain_tx_lane_map_physical{97.0}=0x0123 +phy_chain_tx_lane_map_physical{101.0}=0x1320 +phy_chain_tx_lane_map_physical{105.0}=0x2301 +phy_chain_tx_lane_map_physical{109.0}=0x0213 + +phy_chain_tx_lane_map_physical{113.0}=0x0123 +phy_chain_tx_lane_map_physical{117.0}=0x1023 +phy_chain_tx_lane_map_physical{121.0}=0x2130 +phy_chain_tx_lane_map_physical{125.0}=0x1302 + +# RX lane swap +phy_chain_rx_lane_map_physical{65.0}=0x2103 +phy_chain_rx_lane_map_physical{69.0}=0x3210 +phy_chain_rx_lane_map_physical{73.0}=0x2031 +phy_chain_rx_lane_map_physical{77.0}=0x1032 + +phy_chain_rx_lane_map_physical{81.0}=0x2103 +phy_chain_rx_lane_map_physical{85.0}=0x3210 +phy_chain_rx_lane_map_physical{89.0}=0x2031 +phy_chain_rx_lane_map_physical{93.0}=0x1032 + +phy_chain_rx_lane_map_physical{97.0}=0x1023 +phy_chain_rx_lane_map_physical{101.0}=0x3120 +phy_chain_rx_lane_map_physical{105.0}=0x1023 +phy_chain_rx_lane_map_physical{109.0}=0x0231 + +phy_chain_rx_lane_map_physical{113.0}=0x1320 +phy_chain_rx_lane_map_physical{117.0}=0x3102 +phy_chain_rx_lane_map_physical{121.0}=0x0213 +phy_chain_rx_lane_map_physical{125.0}=0x0231 + +# +# Tile-2 FC32~FC47 +# +# port 66 is the first management port +portmap_66=257:10 +# port 67 is the second loopback port +#portmap_67=261:10 +portmap_68=129:40 +portmap_69=133:40 +portmap_70=137:40 +portmap_71=141:40 +portmap_72=145:40 +portmap_73=149:40 +portmap_74=153:40 +portmap_75=157:40 +portmap_76=161:40 +portmap_77=165:40 +portmap_78=169:40 +portmap_79=173:40 +portmap_80=177:40 +portmap_81=181:40 +portmap_82=185:40 +portmap_83=189:40 + +# TX polarity +phy_chain_tx_polarity_flip_physical{129.0}=0x1 +phy_chain_tx_polarity_flip_physical{130.0}=0x0 +phy_chain_tx_polarity_flip_physical{131.0}=0x1 +phy_chain_tx_polarity_flip_physical{132.0}=0x1 + +phy_chain_tx_polarity_flip_physical{133.0}=0x0 +phy_chain_tx_polarity_flip_physical{134.0}=0x0 +phy_chain_tx_polarity_flip_physical{135.0}=0x1 +phy_chain_tx_polarity_flip_physical{136.0}=0x1 + +phy_chain_tx_polarity_flip_physical{137.0}=0x1 +phy_chain_tx_polarity_flip_physical{138.0}=0x0 +phy_chain_tx_polarity_flip_physical{139.0}=0x1 +phy_chain_tx_polarity_flip_physical{140.0}=0x0 + +phy_chain_tx_polarity_flip_physical{141.0}=0x1 +phy_chain_tx_polarity_flip_physical{142.0}=0x0 +phy_chain_tx_polarity_flip_physical{143.0}=0x1 +phy_chain_tx_polarity_flip_physical{144.0}=0x1 + +phy_chain_tx_polarity_flip_physical{145.0}=0x1 +phy_chain_tx_polarity_flip_physical{146.0}=0x0 +phy_chain_tx_polarity_flip_physical{147.0}=0x0 +phy_chain_tx_polarity_flip_physical{148.0}=0x1 + +phy_chain_tx_polarity_flip_physical{149.0}=0x0 +phy_chain_tx_polarity_flip_physical{150.0}=0x1 +phy_chain_tx_polarity_flip_physical{151.0}=0x1 +phy_chain_tx_polarity_flip_physical{152.0}=0x1 + +phy_chain_tx_polarity_flip_physical{153.0}=0x0 +phy_chain_tx_polarity_flip_physical{154.0}=0x1 +phy_chain_tx_polarity_flip_physical{155.0}=0x0 +phy_chain_tx_polarity_flip_physical{156.0}=0x0 + +phy_chain_tx_polarity_flip_physical{157.0}=0x0 +phy_chain_tx_polarity_flip_physical{158.0}=0x0 +phy_chain_tx_polarity_flip_physical{159.0}=0x1 +phy_chain_tx_polarity_flip_physical{160.0}=0x0 + +phy_chain_tx_polarity_flip_physical{161.0}=0x1 +phy_chain_tx_polarity_flip_physical{162.0}=0x0 +phy_chain_tx_polarity_flip_physical{163.0}=0x0 +phy_chain_tx_polarity_flip_physical{164.0}=0x1 + +phy_chain_tx_polarity_flip_physical{165.0}=0x1 +phy_chain_tx_polarity_flip_physical{166.0}=0x0 +phy_chain_tx_polarity_flip_physical{167.0}=0x0 +phy_chain_tx_polarity_flip_physical{168.0}=0x0 + +phy_chain_tx_polarity_flip_physical{169.0}=0x0 +phy_chain_tx_polarity_flip_physical{170.0}=0x0 +phy_chain_tx_polarity_flip_physical{171.0}=0x0 +phy_chain_tx_polarity_flip_physical{172.0}=0x0 + +phy_chain_tx_polarity_flip_physical{173.0}=0x0 +phy_chain_tx_polarity_flip_physical{174.0}=0x1 +phy_chain_tx_polarity_flip_physical{175.0}=0x0 +phy_chain_tx_polarity_flip_physical{176.0}=0x1 + +phy_chain_tx_polarity_flip_physical{177.0}=0x0 +phy_chain_tx_polarity_flip_physical{178.0}=0x0 +phy_chain_tx_polarity_flip_physical{179.0}=0x0 +phy_chain_tx_polarity_flip_physical{180.0}=0x0 + +phy_chain_tx_polarity_flip_physical{181.0}=0x1 +phy_chain_tx_polarity_flip_physical{182.0}=0x0 +phy_chain_tx_polarity_flip_physical{183.0}=0x0 +phy_chain_tx_polarity_flip_physical{184.0}=0x0 + +phy_chain_tx_polarity_flip_physical{185.0}=0x0 +phy_chain_tx_polarity_flip_physical{186.0}=0x0 +phy_chain_tx_polarity_flip_physical{187.0}=0x0 +phy_chain_tx_polarity_flip_physical{188.0}=0x0 + +phy_chain_tx_polarity_flip_physical{189.0}=0x1 +phy_chain_tx_polarity_flip_physical{190.0}=0x0 +phy_chain_tx_polarity_flip_physical{191.0}=0x1 +phy_chain_tx_polarity_flip_physical{192.0}=0x0 + +# RX polarity +phy_chain_rx_polarity_flip_physical{129.0}=0x0 +phy_chain_rx_polarity_flip_physical{130.0}=0x0 +phy_chain_rx_polarity_flip_physical{131.0}=0x1 +phy_chain_rx_polarity_flip_physical{132.0}=0x0 + +phy_chain_rx_polarity_flip_physical{133.0}=0x0 +phy_chain_rx_polarity_flip_physical{134.0}=0x1 +phy_chain_rx_polarity_flip_physical{135.0}=0x1 +phy_chain_rx_polarity_flip_physical{136.0}=0x0 + +phy_chain_rx_polarity_flip_physical{137.0}=0x1 +phy_chain_rx_polarity_flip_physical{138.0}=0x0 +phy_chain_rx_polarity_flip_physical{139.0}=0x1 +phy_chain_rx_polarity_flip_physical{140.0}=0x1 + +phy_chain_rx_polarity_flip_physical{141.0}=0x0 +phy_chain_rx_polarity_flip_physical{142.0}=0x0 +phy_chain_rx_polarity_flip_physical{143.0}=0x1 +phy_chain_rx_polarity_flip_physical{144.0}=0x1 + +phy_chain_rx_polarity_flip_physical{145.0}=0x0 +phy_chain_rx_polarity_flip_physical{146.0}=0x0 +phy_chain_rx_polarity_flip_physical{147.0}=0x1 +phy_chain_rx_polarity_flip_physical{148.0}=0x0 + +phy_chain_rx_polarity_flip_physical{149.0}=0x0 +phy_chain_rx_polarity_flip_physical{150.0}=0x1 +phy_chain_rx_polarity_flip_physical{151.0}=0x1 +phy_chain_rx_polarity_flip_physical{152.0}=0x0 + +phy_chain_rx_polarity_flip_physical{153.0}=0x0 +phy_chain_rx_polarity_flip_physical{154.0}=0x1 +phy_chain_rx_polarity_flip_physical{155.0}=0x0 +phy_chain_rx_polarity_flip_physical{156.0}=0x0 + +phy_chain_rx_polarity_flip_physical{157.0}=0x1 +phy_chain_rx_polarity_flip_physical{158.0}=0x1 +phy_chain_rx_polarity_flip_physical{159.0}=0x0 +phy_chain_rx_polarity_flip_physical{160.0}=0x0 + +phy_chain_rx_polarity_flip_physical{161.0}=0x1 +phy_chain_rx_polarity_flip_physical{162.0}=0x1 +phy_chain_rx_polarity_flip_physical{163.0}=0x0 +phy_chain_rx_polarity_flip_physical{164.0}=0x1 + +phy_chain_rx_polarity_flip_physical{165.0}=0x0 +phy_chain_rx_polarity_flip_physical{166.0}=0x1 +phy_chain_rx_polarity_flip_physical{167.0}=0x1 +phy_chain_rx_polarity_flip_physical{168.0}=0x0 + +phy_chain_rx_polarity_flip_physical{169.0}=0x0 +phy_chain_rx_polarity_flip_physical{170.0}=0x1 +phy_chain_rx_polarity_flip_physical{171.0}=0x0 +phy_chain_rx_polarity_flip_physical{172.0}=0x1 + +phy_chain_rx_polarity_flip_physical{173.0}=0x0 +phy_chain_rx_polarity_flip_physical{174.0}=0x1 +phy_chain_rx_polarity_flip_physical{175.0}=0x0 +phy_chain_rx_polarity_flip_physical{176.0}=0x0 + +phy_chain_rx_polarity_flip_physical{177.0}=0x1 +phy_chain_rx_polarity_flip_physical{178.0}=0x0 +phy_chain_rx_polarity_flip_physical{179.0}=0x0 +phy_chain_rx_polarity_flip_physical{180.0}=0x1 + +phy_chain_rx_polarity_flip_physical{181.0}=0x0 +phy_chain_rx_polarity_flip_physical{182.0}=0x1 +phy_chain_rx_polarity_flip_physical{183.0}=0x0 +phy_chain_rx_polarity_flip_physical{184.0}=0x1 + +phy_chain_rx_polarity_flip_physical{185.0}=0x1 +phy_chain_rx_polarity_flip_physical{186.0}=0x0 +phy_chain_rx_polarity_flip_physical{187.0}=0x1 +phy_chain_rx_polarity_flip_physical{188.0}=0x0 + +phy_chain_rx_polarity_flip_physical{189.0}=0x1 +phy_chain_rx_polarity_flip_physical{190.0}=0x1 +phy_chain_rx_polarity_flip_physical{191.0}=0x0 +phy_chain_rx_polarity_flip_physical{192.0}=0x0 + +# TX lane swap +phy_chain_tx_lane_map_physical{129.0}=0x0312 +phy_chain_tx_lane_map_physical{133.0}=0x3120 +phy_chain_tx_lane_map_physical{137.0}=0x1203 +phy_chain_tx_lane_map_physical{141.0}=0x0132 + +phy_chain_tx_lane_map_physical{145.0}=0x0312 +phy_chain_tx_lane_map_physical{149.0}=0x2310 +phy_chain_tx_lane_map_physical{153.0}=0x1032 +phy_chain_tx_lane_map_physical{157.0}=0x3120 + +phy_chain_tx_lane_map_physical{161.0}=0x1023 +phy_chain_tx_lane_map_physical{165.0}=0x1203 +phy_chain_tx_lane_map_physical{169.0}=0x0213 +phy_chain_tx_lane_map_physical{173.0}=0x0123 + +phy_chain_tx_lane_map_physical{177.0}=0x2031 +phy_chain_tx_lane_map_physical{181.0}=0x1203 +phy_chain_tx_lane_map_physical{185.0}=0x0213 +phy_chain_tx_lane_map_physical{189.0}=0x3210 + +# RX lane swap +phy_chain_rx_lane_map_physical{129.0}=0x0321 +phy_chain_rx_lane_map_physical{133.0}=0x0312 +phy_chain_rx_lane_map_physical{137.0}=0x2103 +phy_chain_rx_lane_map_physical{141.0}=0x0231 + +phy_chain_rx_lane_map_physical{145.0}=0x0321 +phy_chain_rx_lane_map_physical{149.0}=0x0312 +phy_chain_rx_lane_map_physical{153.0}=0x3120 +phy_chain_rx_lane_map_physical{157.0}=0x2103 + +phy_chain_rx_lane_map_physical{161.0}=0x1032 +phy_chain_rx_lane_map_physical{165.0}=0x2031 +phy_chain_rx_lane_map_physical{169.0}=0x0132 +phy_chain_rx_lane_map_physical{173.0}=0x2103 + +phy_chain_rx_lane_map_physical{177.0}=0x1032 +phy_chain_rx_lane_map_physical{181.0}=0x1230 +phy_chain_rx_lane_map_physical{185.0}=0x0321 +phy_chain_rx_lane_map_physical{189.0}=0x3201 + +# +# Tile-3 FC48~FC63 +# portmap_0=x:xx // cpu port (not required, but included for illustration purposes) +# +# port 100 is the second management port +portmap_100=259:10 +# port 101 is the third loopback port +#portmap_101=262:10 +portmap_102=193:40 +portmap_103=197:40 +portmap_104=201:40 +portmap_105=205:40 +portmap_106=209:40 +portmap_107=213:40 +portmap_108=217:40 +portmap_109=221:40 +portmap_110=225:40 +portmap_111=229:40 +portmap_112=233:40 +portmap_113=237:40 +portmap_114=241:40 +portmap_115=245:40 +portmap_116=249:40 +portmap_117=253:40 +# port 135 is the fourth loopback port +portmap_135=263:10 + +# TX polarity +phy_chain_tx_polarity_flip_physical{193.0}=0x0 +phy_chain_tx_polarity_flip_physical{194.0}=0x0 +phy_chain_tx_polarity_flip_physical{195.0}=0x0 +phy_chain_tx_polarity_flip_physical{196.0}=0x0 + +phy_chain_tx_polarity_flip_physical{197.0}=0x1 +phy_chain_tx_polarity_flip_physical{198.0}=0x0 +phy_chain_tx_polarity_flip_physical{199.0}=0x1 +phy_chain_tx_polarity_flip_physical{200.0}=0x0 + +phy_chain_tx_polarity_flip_physical{201.0}=0x0 +phy_chain_tx_polarity_flip_physical{202.0}=0x0 +phy_chain_tx_polarity_flip_physical{203.0}=0x0 +phy_chain_tx_polarity_flip_physical{204.0}=0x0 + +phy_chain_tx_polarity_flip_physical{205.0}=0x1 +phy_chain_tx_polarity_flip_physical{206.0}=0x0 +phy_chain_tx_polarity_flip_physical{207.0}=0x1 +phy_chain_tx_polarity_flip_physical{208.0}=0x0 + +phy_chain_tx_polarity_flip_physical{209.0}=0x1 +phy_chain_tx_polarity_flip_physical{210.0}=0x0 +phy_chain_tx_polarity_flip_physical{211.0}=0x0 +phy_chain_tx_polarity_flip_physical{212.0}=0x1 + +phy_chain_tx_polarity_flip_physical{213.0}=0x1 +phy_chain_tx_polarity_flip_physical{214.0}=0x0 +phy_chain_tx_polarity_flip_physical{215.0}=0x0 +phy_chain_tx_polarity_flip_physical{216.0}=0x0 + +phy_chain_tx_polarity_flip_physical{217.0}=0x0 +phy_chain_tx_polarity_flip_physical{218.0}=0x0 +phy_chain_tx_polarity_flip_physical{219.0}=0x0 +phy_chain_tx_polarity_flip_physical{220.0}=0x0 + +phy_chain_tx_polarity_flip_physical{221.0}=0x0 +phy_chain_tx_polarity_flip_physical{222.0}=0x1 +phy_chain_tx_polarity_flip_physical{223.0}=0x1 +phy_chain_tx_polarity_flip_physical{224.0}=0x0 + +phy_chain_tx_polarity_flip_physical{225.0}=0x1 +phy_chain_tx_polarity_flip_physical{226.0}=0x1 +phy_chain_tx_polarity_flip_physical{227.0}=0x0 +phy_chain_tx_polarity_flip_physical{228.0}=0x0 + +phy_chain_tx_polarity_flip_physical{229.0}=0x1 +phy_chain_tx_polarity_flip_physical{230.0}=0x1 +phy_chain_tx_polarity_flip_physical{231.0}=0x1 +phy_chain_tx_polarity_flip_physical{232.0}=0x1 + +phy_chain_tx_polarity_flip_physical{233.0}=0x0 +phy_chain_tx_polarity_flip_physical{234.0}=0x0 +phy_chain_tx_polarity_flip_physical{235.0}=0x1 +phy_chain_tx_polarity_flip_physical{236.0}=0x1 + +phy_chain_tx_polarity_flip_physical{237.0}=0x1 +phy_chain_tx_polarity_flip_physical{238.0}=0x1 +phy_chain_tx_polarity_flip_physical{239.0}=0x0 +phy_chain_tx_polarity_flip_physical{240.0}=0x0 + +phy_chain_tx_polarity_flip_physical{241.0}=0x0 +phy_chain_tx_polarity_flip_physical{242.0}=0x1 +phy_chain_tx_polarity_flip_physical{243.0}=0x0 +phy_chain_tx_polarity_flip_physical{244.0}=0x0 + +phy_chain_tx_polarity_flip_physical{245.0}=0x1 +phy_chain_tx_polarity_flip_physical{246.0}=0x0 +phy_chain_tx_polarity_flip_physical{247.0}=0x0 +phy_chain_tx_polarity_flip_physical{248.0}=0x0 + +phy_chain_tx_polarity_flip_physical{249.0}=0x0 +phy_chain_tx_polarity_flip_physical{250.0}=0x0 +phy_chain_tx_polarity_flip_physical{251.0}=0x0 +phy_chain_tx_polarity_flip_physical{252.0}=0x0 + +phy_chain_tx_polarity_flip_physical{253.0}=0x1 +phy_chain_tx_polarity_flip_physical{254.0}=0x0 +phy_chain_tx_polarity_flip_physical{255.0}=0x0 +phy_chain_tx_polarity_flip_physical{256.0}=0x0 + +# RX polarity +phy_chain_rx_polarity_flip_physical{193.0}=0x1 +phy_chain_rx_polarity_flip_physical{194.0}=0x0 +phy_chain_rx_polarity_flip_physical{195.0}=0x0 +phy_chain_rx_polarity_flip_physical{196.0}=0x1 + +phy_chain_rx_polarity_flip_physical{197.0}=0x1 +phy_chain_rx_polarity_flip_physical{198.0}=0x1 +phy_chain_rx_polarity_flip_physical{199.0}=0x0 +phy_chain_rx_polarity_flip_physical{200.0}=0x1 + +phy_chain_rx_polarity_flip_physical{201.0}=0x1 +phy_chain_rx_polarity_flip_physical{202.0}=0x0 +phy_chain_rx_polarity_flip_physical{203.0}=0x1 +phy_chain_rx_polarity_flip_physical{204.0}=0x1 + +phy_chain_rx_polarity_flip_physical{205.0}=0x1 +phy_chain_rx_polarity_flip_physical{206.0}=0x1 +phy_chain_rx_polarity_flip_physical{207.0}=0x0 +phy_chain_rx_polarity_flip_physical{208.0}=0x0 + +phy_chain_rx_polarity_flip_physical{209.0}=0x1 +phy_chain_rx_polarity_flip_physical{210.0}=0x1 +phy_chain_rx_polarity_flip_physical{211.0}=0x0 +phy_chain_rx_polarity_flip_physical{212.0}=0x1 + +phy_chain_rx_polarity_flip_physical{213.0}=0x0 +phy_chain_rx_polarity_flip_physical{214.0}=0x1 +phy_chain_rx_polarity_flip_physical{215.0}=0x1 +phy_chain_rx_polarity_flip_physical{216.0}=0x0 + +phy_chain_rx_polarity_flip_physical{217.0}=0x1 +phy_chain_rx_polarity_flip_physical{218.0}=0x0 +phy_chain_rx_polarity_flip_physical{219.0}=0x1 +phy_chain_rx_polarity_flip_physical{220.0}=0x1 + +phy_chain_rx_polarity_flip_physical{221.0}=0x1 +phy_chain_rx_polarity_flip_physical{222.0}=0x1 +phy_chain_rx_polarity_flip_physical{223.0}=0x0 +phy_chain_rx_polarity_flip_physical{224.0}=0x0 + +phy_chain_rx_polarity_flip_physical{225.0}=0x1 +phy_chain_rx_polarity_flip_physical{226.0}=0x1 +phy_chain_rx_polarity_flip_physical{227.0}=0x1 +phy_chain_rx_polarity_flip_physical{228.0}=0x0 + +phy_chain_rx_polarity_flip_physical{229.0}=0x1 +phy_chain_rx_polarity_flip_physical{230.0}=0x0 +phy_chain_rx_polarity_flip_physical{231.0}=0x0 +phy_chain_rx_polarity_flip_physical{232.0}=0x1 + +phy_chain_rx_polarity_flip_physical{233.0}=0x1 +phy_chain_rx_polarity_flip_physical{234.0}=0x1 +phy_chain_rx_polarity_flip_physical{235.0}=0x1 +phy_chain_rx_polarity_flip_physical{236.0}=0x0 + +phy_chain_rx_polarity_flip_physical{237.0}=0x0 +phy_chain_rx_polarity_flip_physical{238.0}=0x1 +phy_chain_rx_polarity_flip_physical{239.0}=0x0 +phy_chain_rx_polarity_flip_physical{240.0}=0x0 + +phy_chain_rx_polarity_flip_physical{241.0}=0x0 +phy_chain_rx_polarity_flip_physical{242.0}=0x1 +phy_chain_rx_polarity_flip_physical{243.0}=0x0 +phy_chain_rx_polarity_flip_physical{244.0}=0x1 + +phy_chain_rx_polarity_flip_physical{245.0}=0x1 +phy_chain_rx_polarity_flip_physical{246.0}=0x0 +phy_chain_rx_polarity_flip_physical{247.0}=0x0 +phy_chain_rx_polarity_flip_physical{248.0}=0x1 + +phy_chain_rx_polarity_flip_physical{249.0}=0x0 +phy_chain_rx_polarity_flip_physical{250.0}=0x0 +phy_chain_rx_polarity_flip_physical{251.0}=0x1 +phy_chain_rx_polarity_flip_physical{252.0}=0x0 + +phy_chain_rx_polarity_flip_physical{253.0}=0x1 +phy_chain_rx_polarity_flip_physical{254.0}=0x0 +phy_chain_rx_polarity_flip_physical{255.0}=0x0 +phy_chain_rx_polarity_flip_physical{256.0}=0x0 + +# TX lane swap +phy_chain_tx_lane_map_physical{193.0}=0x2031 +phy_chain_tx_lane_map_physical{197.0}=0x1203 +phy_chain_tx_lane_map_physical{201.0}=0x0213 +phy_chain_tx_lane_map_physical{205.0}=0x3210 + +phy_chain_tx_lane_map_physical{209.0}=0x1023 +phy_chain_tx_lane_map_physical{213.0}=0x1203 +phy_chain_tx_lane_map_physical{217.0}=0x0213 +phy_chain_tx_lane_map_physical{221.0}=0x3102 + +phy_chain_tx_lane_map_physical{225.0}=0x2031 +phy_chain_tx_lane_map_physical{229.0}=0x1023 +phy_chain_tx_lane_map_physical{233.0}=0x1320 +phy_chain_tx_lane_map_physical{237.0}=0x2013 + +phy_chain_tx_lane_map_physical{241.0}=0x1023 +phy_chain_tx_lane_map_physical{245.0}=0x1203 +phy_chain_tx_lane_map_physical{249.0}=0x3120 +phy_chain_tx_lane_map_physical{253.0}=0x3210 + +# RX lane swap +phy_chain_rx_lane_map_physical{193.0}=0x1032 +phy_chain_rx_lane_map_physical{197.0}=0x1230 +phy_chain_rx_lane_map_physical{201.0}=0x0321 +phy_chain_rx_lane_map_physical{205.0}=0x3201 + +phy_chain_rx_lane_map_physical{209.0}=0x3201 +phy_chain_rx_lane_map_physical{213.0}=0x2031 +phy_chain_rx_lane_map_physical{217.0}=0x0321 +phy_chain_rx_lane_map_physical{221.0}=0x3201 + +phy_chain_rx_lane_map_physical{225.0}=0x2103 +phy_chain_rx_lane_map_physical{229.0}=0x2310 +phy_chain_rx_lane_map_physical{233.0}=0x0213 +phy_chain_rx_lane_map_physical{237.0}=0x1032 + +phy_chain_rx_lane_map_physical{241.0}=0x0321 +phy_chain_rx_lane_map_physical{245.0}=0x2301 +phy_chain_rx_lane_map_physical{249.0}=0x2103 +phy_chain_rx_lane_map_physical{253.0}=0x2013 + +physical_ports=64 +logical_ports=136 +uplink_ports=2 +dport_map_port_66=65 +dport_map_port_100=66 + +module_64ports=1 + +mmu_init_config="MSFT-TH-Tier1" diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f/port_config.ini b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f/port_config.ini deleted file mode 100644 index 2ae02b21b49c..000000000000 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f/port_config.ini +++ /dev/null @@ -1,65 +0,0 @@ -# name lanes alias index -Ethernet0 49,50,51,52 hundredGigE1/1 0 -Ethernet4 53,54,55,56 hundredGigE1/2 1 -Ethernet8 65,66,67,68 hundredGigE1/3 2 -Ethernet12 69,70,71,72 hundredGigE1/4 3 -Ethernet16 81,82,83,84 hundredGigE1/5 4 -Ethernet20 85,86,87,88 hundredGigE1/6 5 -Ethernet24 97,98,99,100 hundredGigE1/7 6 -Ethernet28 101,102,103,104 hundredGigE1/8 7 -Ethernet32 1,2,3,4 hundredGigE1/9 8 -Ethernet36 5,6,7,8 hundredGigE1/10 9 -Ethernet40 17,18,19,20 hundredGigE1/11 10 -Ethernet44 21,22,23,24 hundredGigE1/12 11 -Ethernet48 33,34,35,36 hundredGigE1/13 12 -Ethernet52 37,38,39,40 hundredGigE1/14 13 -Ethernet56 113,114,115,116 hundredGigE1/15 14 -Ethernet60 117,118,119,120 hundredGigE1/16 15 -Ethernet64 133,134,135,136 hundredGigE1/17 16 -Ethernet68 129,130,131,132 hundredGigE1/18 17 -Ethernet72 213,214,215,216 hundredGigE1/19 18 -Ethernet76 209,210,211,212 hundredGigE1/20 19 -Ethernet80 229,230,231,232 hundredGigE1/21 20 -Ethernet84 225,226,227,228 hundredGigE1/22 21 -Ethernet88 245,246,247,248 hundredGigE1/23 22 -Ethernet92 241,242,243,244 hundredGigE1/24 23 -Ethernet96 149,150,151,152 hundredGigE1/25 24 -Ethernet100 145,146,147,148 hundredGigE1/26 25 -Ethernet104 165,166,167,168 hundredGigE1/27 26 -Ethernet108 161,162,163,164 hundredGigE1/28 27 -Ethernet112 181,182,183,184 hundredGigE1/29 28 -Ethernet116 177,178,179,180 hundredGigE1/30 29 -Ethernet120 197,198,199,200 hundredGigE1/31 30 -Ethernet124 193,194,195,196 hundredGigE1/32 31 -Ethernet128 61,62,63,64 hundredGigE1/33 32 -Ethernet132 57,58,59,60 hundredGigE1/34 33 -Ethernet136 77,78,79,80 hundredGigE1/35 34 -Ethernet140 73,74,75,76 hundredGigE1/36 35 -Ethernet144 93,94,95,96 hundredGigE1/37 36 -Ethernet148 89,90,91,92 hundredGigE1/38 37 -Ethernet152 109,110,111,112 hundredGigE1/39 38 -Ethernet156 105,106,107,108 hundredGigE1/40 39 -Ethernet160 13,14,15,16 hundredGigE1/41 40 -Ethernet164 9,10,11,12 hundredGigE1/42 41 -Ethernet168 29,30,31,32 hundredGigE1/43 42 -Ethernet172 25,26,27,28 hundredGigE1/44 43 -Ethernet176 45,46,47,48 hundredGigE1/45 44 -Ethernet180 41,42,43,44 hundredGigE1/46 45 -Ethernet184 125,126,127,128 hundredGigE1/47 46 -Ethernet188 121,122,123,124 hundredGigE1/48 47 -Ethernet192 137,138,139,140 hundredGigE1/49 48 -Ethernet196 141,142,143,144 hundredGigE1/50 49 -Ethernet200 217,218,219,220 hundredGigE1/51 50 -Ethernet204 221,222,223,224 hundredGigE1/52 51 -Ethernet208 233,234,235,236 hundredGigE1/53 52 -Ethernet212 237,238,239,240 hundredGigE1/54 53 -Ethernet216 249,250,251,252 hundredGigE1/55 54 -Ethernet220 253,254,255,256 hundredGigE1/56 55 -Ethernet224 153,154,155,156 hundredGigE1/57 56 -Ethernet228 157,158,159,160 hundredGigE1/58 57 -Ethernet232 169,170,171,172 hundredGigE1/59 58 -Ethernet236 173,174,175,176 hundredGigE1/60 59 -Ethernet240 185,186,187,188 hundredGigE1/61 60 -Ethernet244 189,190,191,192 hundredGigE1/62 61 -Ethernet248 201,202,203,204 hundredGigE1/63 62 -Ethernet252 205,206,207,208 hundredGigE1/64 63 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/default_sku b/device/dell/x86_64-dellemc_z9264f_c3538-r0/default_sku index 206373c042de..e110b267e200 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/default_sku +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/default_sku @@ -1 +1 @@ -DellEMC-Z9264f t1 +DellEMC-Z9264f-C64 t1 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/platform_reboot b/device/dell/x86_64-dellemc_z9264f_c3538-r0/platform_reboot deleted file mode 100644 index 3e165630658b..000000000000 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/platform_reboot +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/python -import sys -import os -import struct - -PORT_RES = '/dev/port' - - -def portio_reg_write(resource, offset, val): - fd = os.open(resource, os.O_RDWR) - if(fd < 0): - print 'file open failed %s" % resource' - return - if(os.lseek(fd, offset, os.SEEK_SET) != offset): - print 'lseek failed on %s' % resource - return - ret = os.write(fd, struct.pack('B', val)) - if(ret != 1): - print 'write failed %d' % ret - return - os.close(fd) - -if __name__ == "__main__": - portio_reg_write(PORT_RES, 0xcf9, 0xe) - 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 a4a0747a3bc5..192fb80f6c56 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 @@ -19,9 +19,9 @@ class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" - PORT_START = 0 - PORT_END = 63 - PORTS_IN_BLOCK = 32 + PORT_START = 1 + PORT_END = 64 + PORTS_IN_BLOCK = 64 BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" @@ -39,7 +39,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(0, self.PORTS_IN_BLOCK + 1) + return range(self.PORT_START, self.PORTS_IN_BLOCK + 1) @property def port_to_eeprom_mapping(self): @@ -85,8 +85,8 @@ def init_global_port_presence(self): def __init__(self): eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" - for x in range(0, self.port_end + 1): - port_num = x + 2 + for x in range(self.port_start, self.port_end + 1): + port_num = x + 1 self.port_to_eeprom_mapping[x] = eeprom_path.format( port_num) port_num = 0 @@ -100,7 +100,7 @@ def get_presence(self, port_num): return False # Port offset starts with 0x4004 - port_offset = 16388 + ((port_num) * 16) + port_offset = 16388 + ((port_num-1) * 16) status = self.pci_get_value(self.BASE_RES_PATH, port_offset) reg_value = int(status) @@ -125,7 +125,7 @@ def get_low_power_mode(self, port_num): return False # Port offset starts with 0x4000 - port_offset = 16384 + ((port_num) * 16) + port_offset = 16384 + ((port_num-1) * 16) status = self.pci_get_value(self.BASE_RES_PATH, port_offset) reg_value = int(status) @@ -150,7 +150,7 @@ def set_low_power_mode(self, port_num, lpmode): return False # Port offset starts with 0x4000 - port_offset = 16384 + ((port_num) * 16) + port_offset = 16384 + ((port_num-1) * 16) status = self.pci_get_value(self.BASE_RES_PATH, port_offset) reg_value = int(status) @@ -180,7 +180,7 @@ def reset(self, port_num): return False # Port offset starts with 0x4000 - port_offset = 16384 + ((port_num) * 16) + port_offset = 16384 + ((port_num-1) * 16) status = self.pci_get_value(self.BASE_RES_PATH, port_offset) reg_value = int(status) 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 dbe2b81131db..43e876e40e5d 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 @@ -5,3 +5,4 @@ z9264f/scripts/sensors usr/bin z9264f/scripts/pcisysfs.py usr/bin z9264f/cfg/z9264f-modules.conf etc/modules-load.d z9264f/systemd/platform-modules-z9264f.service etc/systemd/system +common/platform_reboot usr/share/sonic/device/x86_64-dellemc_z9264f_c3538-r0 From d5d51c036951a9d1a27f6c83603aaa63b93af76c Mon Sep 17 00:00:00 2001 From: paavaanan Date: Wed, 15 May 2019 04:37:41 +0530 Subject: [PATCH 43/88] LED Supprot For DellEMC Z9100 (#2799) --- .../Force10-Z9100-C32/led_proc_init.soc | 51 ++++++++++++++++ .../Force10-Z9100-C8D48/led_proc_init.soc | 58 +++++++++++++++++++ .../z9100/scripts/z9100_platform.sh | 34 +++++++++++ 3 files changed, 143 insertions(+) create mode 100644 device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/led_proc_init.soc create mode 100644 device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/led_proc_init.soc diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/led_proc_init.soc b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/led_proc_init.soc new file mode 100644 index 000000000000..dd30163ddcf6 --- /dev/null +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/led_proc_init.soc @@ -0,0 +1,51 @@ +# LED microprocessor initialization for Dell Z9100 +# +# +#Led0 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=3 REMAP_PORT_61=2 REMAP_PORT_62=1 REMAP_PORT_63=0 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=7 REMAP_PORT_57=6 REMAP_PORT_58=5 REMAP_PORT_59=4 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=11 REMAP_PORT_53=10 REMAP_PORT_54=9 REMAP_PORT_55=8 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=15 REMAP_PORT_49=14 REMAP_PORT_50=13 REMAP_PORT_51=12 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=19 REMAP_PORT_9=18 REMAP_PORT_10=17 REMAP_PORT_11=16 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=23 REMAP_PORT_13=22 REMAP_PORT_14=21 REMAP_PORT_15=20 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=27 REMAP_PORT_1=26 REMAP_PORT_2=25 REMAP_PORT_3=24 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=31 REMAP_PORT_5=30 REMAP_PORT_6=29 REMAP_PORT_7=28 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=35 REMAP_PORT_41=34 REMAP_PORT_42=33 REMAP_PORT_43=32 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=39 REMAP_PORT_45=38 REMAP_PORT_46=37 REMAP_PORT_47=36 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=43 REMAP_PORT_33=42 REMAP_PORT_34=41 REMAP_PORT_35=40 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=47 REMAP_PORT_37=46 REMAP_PORT_38=45 REMAP_PORT_39=44 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=51 REMAP_PORT_25=50 REMAP_PORT_26=49 REMAP_PORT_27=48 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=55 REMAP_PORT_29=54 REMAP_PORT_30=53 REMAP_PORT_31=52 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=59 REMAP_PORT_17=58 REMAP_PORT_18=57 REMAP_PORT_19=56 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=63 REMAP_PORT_21=62 REMAP_PORT_22=61 REMAP_PORT_23=60 + +#Led1 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=3 REMAP_PORT_17=2 REMAP_PORT_18=1 REMAP_PORT_19=0 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=7 REMAP_PORT_21=6 REMAP_PORT_22=5 REMAP_PORT_23=4 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=11 REMAP_PORT_25=10 REMAP_PORT_26=9 REMAP_PORT_27=8 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=15 REMAP_PORT_29=14 REMAP_PORT_30=13 REMAP_PORT_31=12 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=19 REMAP_PORT_33=18 REMAP_PORT_34=17 REMAP_PORT_35=16 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=23 REMAP_PORT_37=22 REMAP_PORT_38=21 REMAP_PORT_39=20 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=27 REMAP_PORT_41=26 REMAP_PORT_42=25 REMAP_PORT_43=24 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=31 REMAP_PORT_45=30 REMAP_PORT_46=29 REMAP_PORT_47=28 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=35 REMAP_PORT_5=34 REMAP_PORT_6=33 REMAP_PORT_7=32 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=39 REMAP_PORT_1=38 REMAP_PORT_2=37 REMAP_PORT_3=36 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=43 REMAP_PORT_13=42 REMAP_PORT_14=41 REMAP_PORT_15=40 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=47 REMAP_PORT_9=46 REMAP_PORT_10=45 REMAP_PORT_11=44 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=51 REMAP_PORT_49=50 REMAP_PORT_50=49 REMAP_PORT_51=48 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=55 REMAP_PORT_53=54 REMAP_PORT_54=53 REMAP_PORT_55=52 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=59 REMAP_PORT_57=58 REMAP_PORT_58=57 REMAP_PORT_59=56 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=63 REMAP_PORT_61=62 REMAP_PORT_62=61 REMAP_PORT_63=60 + +led 0 stop +led 0 prog 02 A8 60 AA 02 00 60 A7 02 00 60 FE 02 00 60 AB 06 A7 D2 08 74 20 02 A9 60 AA 06 A7 E2 08 60 A7 06 FE 28 67 3D 86 FE 06 FE 86 AB 06 AB D2 04 71 10 86 A7 06 FE D2 40 71 0C 86 FF 3A 80 32 08 97 71 7C 77 4C 57 22 0E 87 22 0E 87 57 22 0F 87 22 0F 87 57 22 0F 87 22 0E 87 57 06 AA 61 A6 16 A7 49 27 16 A6 97 71 53 77 45 57 02 0A 50 95 75 74 85 75 5A 57 16 FF CA 05 74 4C 77 5A 06 FE 12 BC F8 32 00 32 01 B7 97 71 6A 77 5A +led 0 auto on +led 0 start + +led 1 stop +led 1 prog 02 A8 60 AA 02 00 60 A7 02 00 60 FE 02 00 60 AB 06 A7 D2 08 74 20 02 A9 60 AA 06 A7 E2 08 60 A7 06 FE 28 67 3D 86 FE 06 FE 86 AB 06 AB D2 04 71 10 86 A7 06 FE D2 40 71 0C 86 FF 3A 80 32 08 97 71 7C 77 4C 57 22 0E 87 22 0E 87 57 22 0F 87 22 0F 87 57 22 0F 87 22 0E 87 57 06 AA 61 A6 16 A7 49 27 16 A6 97 71 53 77 45 57 02 0A 50 95 75 74 85 75 5A 57 16 FF CA 05 74 4C 77 5A 06 FE 12 BC F8 32 00 32 01 B7 97 71 6A 77 5A + +led 1 auto on +led 1 start + +led 2 stop diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/led_proc_init.soc b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/led_proc_init.soc new file mode 100644 index 000000000000..487c9fb7dcd9 --- /dev/null +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/led_proc_init.soc @@ -0,0 +1,58 @@ +# LED microprocessor initialization for Dell Z9100 +# +# +#Led0 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=3 REMAP_PORT_61=2 REMAP_PORT_62=1 REMAP_PORT_63=0 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=7 REMAP_PORT_57=6 REMAP_PORT_58=5 REMAP_PORT_59=4 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=11 REMAP_PORT_53=10 REMAP_PORT_54=9 REMAP_PORT_55=8 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=15 REMAP_PORT_49=14 REMAP_PORT_50=13 REMAP_PORT_51=12 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=19 REMAP_PORT_9=18 REMAP_PORT_10=17 REMAP_PORT_11=16 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=23 REMAP_PORT_13=22 REMAP_PORT_14=21 REMAP_PORT_15=20 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=27 REMAP_PORT_1=26 REMAP_PORT_2=25 REMAP_PORT_3=24 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=31 REMAP_PORT_5=30 REMAP_PORT_6=29 REMAP_PORT_7=28 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=35 REMAP_PORT_41=34 REMAP_PORT_42=33 REMAP_PORT_43=32 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=39 REMAP_PORT_45=38 REMAP_PORT_46=37 REMAP_PORT_47=36 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=43 REMAP_PORT_33=42 REMAP_PORT_34=41 REMAP_PORT_35=40 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=47 REMAP_PORT_37=46 REMAP_PORT_38=45 REMAP_PORT_39=44 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=51 REMAP_PORT_25=50 REMAP_PORT_26=49 REMAP_PORT_27=48 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=55 REMAP_PORT_29=54 REMAP_PORT_30=53 REMAP_PORT_31=52 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=59 REMAP_PORT_17=58 REMAP_PORT_18=57 REMAP_PORT_19=56 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=63 REMAP_PORT_21=62 REMAP_PORT_22=61 REMAP_PORT_23=60 + +#Led1 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=3 REMAP_PORT_17=2 REMAP_PORT_18=1 REMAP_PORT_19=0 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=7 REMAP_PORT_21=6 REMAP_PORT_22=5 REMAP_PORT_23=4 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=11 REMAP_PORT_25=10 REMAP_PORT_26=9 REMAP_PORT_27=8 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=15 REMAP_PORT_29=14 REMAP_PORT_30=13 REMAP_PORT_31=12 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=19 REMAP_PORT_33=18 REMAP_PORT_34=17 REMAP_PORT_35=16 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=23 REMAP_PORT_37=22 REMAP_PORT_38=21 REMAP_PORT_39=20 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=27 REMAP_PORT_41=26 REMAP_PORT_42=25 REMAP_PORT_43=24 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=31 REMAP_PORT_45=30 REMAP_PORT_46=29 REMAP_PORT_47=28 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=35 REMAP_PORT_5=34 REMAP_PORT_6=33 REMAP_PORT_7=32 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=39 REMAP_PORT_1=38 REMAP_PORT_2=37 REMAP_PORT_3=36 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=43 REMAP_PORT_13=42 REMAP_PORT_14=41 REMAP_PORT_15=40 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=47 REMAP_PORT_9=46 REMAP_PORT_10=45 REMAP_PORT_11=44 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=51 REMAP_PORT_49=50 REMAP_PORT_50=49 REMAP_PORT_51=48 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=55 REMAP_PORT_53=54 REMAP_PORT_54=53 REMAP_PORT_55=52 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=59 REMAP_PORT_57=58 REMAP_PORT_58=57 REMAP_PORT_59=56 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=63 REMAP_PORT_61=62 REMAP_PORT_62=61 REMAP_PORT_63=60 + +led 0 stop +led 0 prog 02 A8 60 AA 02 00 60 A7 02 00 60 FE 02 00 60 AB 06 A7 D2 08 74 20 02 A9 60 AA 06 A7 E2 08 60 A7 06 FE 28 67 3D 86 FE 06 FE 86 AB 06 AB D2 04 71 10 86 A7 06 FE D2 40 71 0C 86 FF 3A 80 32 08 97 71 7C 77 4C 57 22 0E 87 22 0E 87 57 22 0F 87 22 0F 87 57 22 0F 87 22 0E 87 57 06 AA 61 A6 16 A7 49 27 16 A6 97 71 53 77 45 57 02 0A 50 95 75 74 85 75 5A 57 16 FF CA 05 74 4C 77 5A 06 FE 12 BC F8 32 00 32 01 B7 97 71 6A 77 5A +led 0 auto on +led 0 start + +led 1 stop +led 1 prog 02 A8 60 AA 02 00 60 A7 02 00 60 FE 02 00 60 AB 06 A7 D2 08 74 20 02 A9 60 AA 06 A7 E2 08 60 A7 06 FE 28 67 3D 86 FE 06 FE 86 AB 06 AB D2 04 71 10 86 A7 06 FE D2 40 71 0C 86 FF 3A 80 32 08 97 71 7C 77 4C 57 22 0E 87 22 0E 87 57 22 0F 87 22 0F 87 57 22 0F 87 22 0E 87 57 06 AA 61 A6 16 A7 49 27 16 A6 97 71 53 77 45 57 02 0A 50 95 75 74 85 75 5A 57 16 FF CA 05 74 4C 77 5A 06 FE 12 BC F8 32 00 32 01 B7 97 71 6A 77 5A + +led 1 auto on +led 1 start + +led 2 stop + + +setreg CMIC_LEDUP1_DATA_RAM[0xa8] 0x3f +setreg CMIC_LEDUP1_DATA_RAM[0xa9] 0xFC +setreg CMIC_LEDUP0_DATA_RAM[0xa8] 0xff +setreg CMIC_LEDUP0_DATA_RAM[0xa9] 0xC3 + diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh index c943e584943c..294b1b79aa88 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh @@ -171,6 +171,35 @@ reset_muxes() { io_rd_wr.py --set --val 0xff --offset 0x20b } +# Copy led_proc_init.soc file according to the HWSKU +init_switch_port_led() { + T0="Force10-Z9100-C8D48" + T1="Force10-Z9100-C32" + device="/usr/share/sonic/device" + platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) + hwsku=$(cat /etc/sonic/config_db.json | grep -A2 "DEVICE_METADATA" | grep "hwsku" | cut -d ":" -f2 | sed 's/"//g' | sed 's/,//g'| xargs ) + + if [ -z "$hwsku" ]; then + #Check minigraph for hwsku + cat /etc/sonic/minigraph.xml | grep $T1 > /dev/null + if [ $? -eq 0 ]; then + hwsku=$T1 + else + hwsku=$T0 + fi + fi + + led_proc_init="$device/$platform/$hwsku/led_proc_init.soc" + + # Remove old HWSKU LED file.. + rm -rf $device/$platform/led_proc_init.soc + + if [ -e $led_proc_init ] && [ ! -e $device/$platform/led_proc_init.soc ]; then + cp $led_proc_init $device/$platform + fi + +} + init_devnum if [[ "$1" == "init" ]]; then @@ -188,6 +217,11 @@ if [[ "$1" == "init" ]]; then switch_board_sfp "new_device" switch_board_qsfp "new_device" xcvr_presence_interrupts "enable" + + #Copy led_proc_init.soc + init_switch_port_led + + elif [[ "$1" == "deinit" ]]; then xcvr_presence_interrupts "disable" switch_board_sfp "delete_device" From f82ed250638d07582ec1cdb1e659721d930b7696 Mon Sep 17 00:00:00 2001 From: Shuotian Cheng Date: Wed, 15 May 2019 07:48:20 -0700 Subject: [PATCH 44/88] [sonic-cfggen]: Add -w as short for --write-to-db (#2900) --write-to-db is frequently used. Signed-off-by: Shu0T1an ChenG --- src/sonic-config-engine/sonic-cfggen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index f923cc4bc6c2..01b759d22e14 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -162,7 +162,7 @@ def main(): group.add_argument("-t", "--template", help="render the data with the template file") group.add_argument("-v", "--var", help="print the value of a variable, support jinja2 expression") group.add_argument("--var-json", help="print the value of a variable, in json format") - group.add_argument("--write-to-db", help="write config into configdb", action='store_true') + group.add_argument("-w", "--write-to-db", help="write config into configdb", action='store_true') group.add_argument("--print-data", help="print all data", action='store_true') group.add_argument("--preset", help="generate sample configuration from a preset template", choices=get_available_config()) args = parser.parse_args() From e6691c2a3490ba7c4f22c8bd95645144bc327dcd Mon Sep 17 00:00:00 2001 From: brandonchuang Date: Wed, 15 May 2019 22:49:02 +0800 Subject: [PATCH 45/88] [Accton AS7712]: Add lpmode in sfputil.py (#2896) Signed-off-by: brandon_chuang --- .../plugins/sfputil.py | 66 +++++++++++++++++-- 1 file changed, 60 insertions(+), 6 deletions(-) diff --git a/device/accton/x86_64-accton_as7712_32x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7712_32x-r0/plugins/sfputil.py index 5d1346e9b937..f70916ca435d 100644 --- a/device/accton/x86_64-accton_as7712_32x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7712_32x-r0/plugins/sfputil.py @@ -2,6 +2,8 @@ try: import time + import string + from ctypes import create_string_buffer from sonic_sfp.sfputilbase import SfpUtilBase except ImportError, e: raise ImportError (str(e) + "- required module not found") @@ -81,12 +83,6 @@ def reset(self, port_num): reg_file.write('0') reg_file.close() return True - - def set_low_power_mode(self, port_nuM, lpmode): - raise NotImplementedError - - def get_low_power_mode(self, port_num): - raise NotImplementedError def get_presence(self, port_num): # Check for invalid port_num @@ -132,3 +128,61 @@ def get_transceiver_change_event(self): on this platform. """ raise NotImplementedError + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + try: + eeprom = None + + if not self.get_presence(port_num): + return False + + eeprom = open(self.port_to_eeprom_mapping[port_num], "rb") + eeprom.seek(93) + lpmode = ord(eeprom.read(1)) + + if ((lpmode & 0x3) == 0x3): + return True # Low Power Mode if "Power override" bit is 1 and "Power set" bit is 1 + else: + return False # High Power Mode if one of the following conditions is matched: + # 1. "Power override" bit is 0 + # 2. "Power override" bit is 1 and "Power set" bit is 0 + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + try: + eeprom = None + + if not self.get_presence(port_num): + return False # Port is not present, unable to set the eeprom + + # Fill in write buffer + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + buffer = create_string_buffer(1) + buffer[0] = chr(regval) + + # Write to eeprom + eeprom = open(self.port_to_eeprom_mapping[port_num], "r+b") + eeprom.seek(93) + eeprom.write(buffer[0]) + return True + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) \ No newline at end of file From 83e74d6dbb35fb668afbc670f2b8029e970b561f Mon Sep 17 00:00:00 2001 From: simonJi2018 <37395146+simonJi2018@users.noreply.github.com> Date: Wed, 15 May 2019 07:50:13 -0700 Subject: [PATCH 46/88] [nephos]: upgrade sai.mk to cbb99f for support 1.4.1 (#2901) --- platform/nephos/sai.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/nephos/sai.mk b/platform/nephos/sai.mk index af5d1f4e1d2a..93265dc74c56 100644 --- a/platform/nephos/sai.mk +++ b/platform/nephos/sai.mk @@ -1,6 +1,6 @@ SDK_VERSION = 2.0.8 -SAI_VERSION = 1.4.0 -SAI_COMMIT_ID = c818c7 +SAI_VERSION = 1.4.1 +SAI_COMMIT_ID = cbb99f NEPHOS_SAI = libsainps_$(SDK_VERSION)_sai_$(SAI_VERSION)_$(SAI_COMMIT_ID)_amd64.deb $(NEPHOS_SAI)_URL = "https://github.com/NephosInc/SONiC/raw/master/sai/libsainps_$(SDK_VERSION)_sai_$(SAI_VERSION)_$(SAI_COMMIT_ID)_amd64.deb" From 77cde50541ad2839cd8512b1bcf8b70b0e3df5ef Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Wed, 15 May 2019 12:45:06 -0700 Subject: [PATCH 47/88] [device/Arista] Improvements to the boot of Arista devices. (#2898) * Fix showing systemd shutdown sequence when verbose is set * Fix creation of kernel-cmdline file Sometimes boot0 prints error "mv: can't preserve ownership of '/mnt/flash/image-arsonic.xxxx/kernel-cmdline': Operation not permitted" * Improve flash space usage during installation Some older systems only have 2GB of flash available. Installing a second image on these can prove to be challenging. The new installation process moves the installer swi to memory in order to avoid free up space from the flash before uncompressing it there. It removes all the flash space usage spike and also improves the IO since the installation is no more reading and writting to the flash at the same time. * Add support of 7060CX-32S-SSD * 7260CX3: use inventory powerCycle procedures * 7050QX-32S: use inventory powerCycle procedures * 7050QX-32: use inventory powerCycle procedures * platform: arista: add common platform_reboot Replace platform_reboot by a link to new common for devices already using a similar script. * 7060CX-32S: use inventory powerCycle procedures * Install python smbus in pmon Some platform plugin need the python smbus library to perform some actions. This installs the dependency. --- .../x86_64-arista_7050_qx32/platform_reboot | 88 +------------------ .../x86_64-arista_7050_qx32s/platform_reboot | 88 +------------------ .../x86_64-arista_7060_cx32s/platform_reboot | 19 +--- .../x86_64-arista_7060px4_32/platform_reboot | 12 +-- .../x86_64-arista_7170_64c/platform_reboot | 12 +-- .../x86_64-arista_7260cx3_64/platform_reboot | 88 +------------------ .../x86_64-arista_common/platform_reboot | 11 +++ dockers/docker-platform-monitor/Dockerfile.j2 | 2 +- files/Aboot/boot0.j2 | 45 ++++++++-- 9 files changed, 56 insertions(+), 309 deletions(-) mode change 100755 => 120000 device/arista/x86_64-arista_7050_qx32/platform_reboot mode change 100755 => 120000 device/arista/x86_64-arista_7050_qx32s/platform_reboot mode change 100755 => 120000 device/arista/x86_64-arista_7060_cx32s/platform_reboot mode change 100755 => 120000 device/arista/x86_64-arista_7060px4_32/platform_reboot mode change 100755 => 120000 device/arista/x86_64-arista_7170_64c/platform_reboot mode change 100755 => 120000 device/arista/x86_64-arista_7260cx3_64/platform_reboot create mode 100755 device/arista/x86_64-arista_common/platform_reboot diff --git a/device/arista/x86_64-arista_7050_qx32/platform_reboot b/device/arista/x86_64-arista_7050_qx32/platform_reboot deleted file mode 100755 index da438b8fe52b..000000000000 --- a/device/arista/x86_64-arista_7050_qx32/platform_reboot +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2018 Arista Networks, Inc. All rights reserved. -# Arista Networks, Inc. Confidential and Proprietary. - -# Reboot script for 7050QX-32 - -from __future__ import print_function -import sys -import mmap, os -import subprocess -from struct import pack, unpack - -class MmapResource( object ): - """Resource implementation for a directly-mapped memory region.""" - - def __init__( self, path ): - try: - fd = os.open( path, os.O_RDWR ) - except EnvironmentError: - print( "FAIL can not open scd memory-map resource file" ) - print( "FAIL are you running on the proper platform?" ) - sys.exit( 1 ) - try: - size = os.fstat( fd ).st_size - except EnvironmentError: - print( "FAIL can not fstat scd memory-map resource file" ) - print( "FAIL are you running on the proper platform?" ) - sys.exit( 1 ) - try: - self.mmap_ = mmap.mmap( fd, size, mmap.MAP_SHARED, - mmap.PROT_READ | mmap.PROT_WRITE ) - except EnvironmentError: - print( "FAIL can not map scd memory-map file" ) - print( "FAIL are you running on the proper platform?" ) - sys.exit( 1 ) - finally: - try: - # Note that closing the file descriptor has no effect on the memory map - os.close( fd ) - except EnvironmentError: - print( "FAIL failed to close scd memory-map file" ) - sys.exit( 1 ) - - def read32( self, addr ): - return unpack( '>/tmp/append fi - if [ "$sid" = "Upperlake" ] || [ "$sid" = "UpperlakeES" ]; then + if [ "$sid" = "Upperlake" ] || [ "$sid" = "UpperlakeES" ] || + [ "$sid" = "UpperlakeSsd" ]; then aboot_machine=arista_7060_cx32s flash_size=3700 echo "amd_iommu=off" >> /tmp/append @@ -304,7 +332,7 @@ write_boot_configs() { fi fi - mv /tmp/append $cmdline_image + cat /tmp/append > $cmdline_image [ -e ${target_path}/machine.conf ] || write_machine_config } @@ -313,7 +341,10 @@ run_kexec() { local kernel="${KERNEL:-$(find $image_path/boot -name 'vmlinuz-*' -type f | head -n 1)}" local initrd="${INITRD:-$(find $image_path/boot -name 'initrd.img-*' -type f | head -n 1)}" - if ! $verbose; then + if $verbose; then + # show systemd showdown sequence when verbose is set + cmdline="$cmdline systemd.show_status=true" + else # Start showing systemd information from the first failing unit if any. # systemd.show_status=false or quiet can be used to silence systemd entierly cmdline="$cmdline systemd.show_status=auto" From aa90cae1be0b35c6874d09fe40a5e6b09b00a6de Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Thu, 16 May 2019 07:22:56 +0800 Subject: [PATCH 48/88] [sonic-cfggen] fix name conflict between sonic_platform package and sonic_platform.py (#2875) * fix name conflict between sonic_platfrom package and sonic_platform.py * update sonic-utility submodule to pickup lastest fix * Revert "update sonic-utility submodule to pickup lastest fix" This reverts commit f66aa99738e06373bc2e141f420eab71839ff4e8. * update sonic-utility sub module --- src/sonic-config-engine/setup.py | 2 +- src/sonic-config-engine/sonic-cfggen | 6 +++--- .../{sonic_platform.py => sonic_device_util.py} | 10 +++++++--- src/sonic-utilities | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) rename src/sonic-config-engine/{sonic_platform.py => sonic_device_util.py} (90%) diff --git a/src/sonic-config-engine/setup.py b/src/sonic-config-engine/setup.py index 8375b6af89ad..7ca810ce6a54 100755 --- a/src/sonic-config-engine/setup.py +++ b/src/sonic-config-engine/setup.py @@ -16,7 +16,7 @@ def get_test_suite(): author='Taoyu Li', author_email='taoyl@microsoft.com', url='https://github.com/Azure/sonic-buildimage', - py_modules=['portconfig', 'minigraph', 'openconfig_acl', 'sonic_platform', 'config_samples'], + py_modules=['portconfig', 'minigraph', 'openconfig_acl', 'sonic_device_util', 'config_samples'], scripts=['sonic-cfggen'], install_requires=['lxml', 'jinja2>=2.10', 'netaddr', 'ipaddr', 'pyyaml', 'pyangbind==0.6.0'], test_suite='setup.get_test_suite', diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 01b759d22e14..a711ca1301e0 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -28,9 +28,9 @@ from minigraph import minigraph_encoder from minigraph import parse_xml from minigraph import parse_device_desc_xml from portconfig import get_port_config -from sonic_platform import get_machine_info -from sonic_platform import get_platform_info -from sonic_platform import get_system_mac +from sonic_device_util import get_machine_info +from sonic_device_util import get_platform_info +from sonic_device_util import get_system_mac from config_samples import generate_sample_config from config_samples import get_available_config from swsssdk import ConfigDBConnector diff --git a/src/sonic-config-engine/sonic_platform.py b/src/sonic-config-engine/sonic_device_util.py similarity index 90% rename from src/sonic-config-engine/sonic_platform.py rename to src/sonic-config-engine/sonic_device_util.py index 370f6e3a42ee..ac03ca818df1 100644 --- a/src/sonic-config-engine/sonic_platform.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -5,13 +5,17 @@ DOCUMENTATION = ''' --- -module: sonic_platform +module: sonic_device_util version_added: "1.9" -short_description: Retrive platform related facts for a device. +short_description: Retrieve device related facts for a device. description: - - Retrieve platform related facts from config files. + - Retrieve device related facts from config files. ''' +''' +TODO: this file shall be renamed and moved to other places in future +to have it shared with multiple applications. +''' def get_machine_info(): if not os.path.isfile('/host/machine.conf'): return None diff --git a/src/sonic-utilities b/src/sonic-utilities index 8d974001a9dc..09806b861486 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 8d974001a9dcf51f38091011bc1fecd34ca895ab +Subproject commit 09806b861486091d9db5cb75bdd2cc9428e46844 From 5d3da111b2e99be4b67e225f5b6151d1c91974dd Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Wed, 15 May 2019 18:35:04 -0700 Subject: [PATCH 49/88] [device/arista] update arista drivers submodules (#2903) - Update README.md - Improve reboot cause reporting on all platform - Refactor parts of the library toward sonic_platform API support - Add abstraction for fans - Export consistent sysfs entries for fan airflow direction - Bootstrap python testing of the driver library. - Fix miscellaneous bugs --- platform/barefoot/sonic-platform-modules-arista | 2 +- platform/broadcom/sonic-platform-modules-arista | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index 7e2d714ae7c0..96ca3f74630b 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 7e2d714ae7c072ee587d1cf0356cf548ac4be4a9 +Subproject commit 96ca3f74630b1b7cb07ef68e863d479bb2dcf85d diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index 7e2d714ae7c0..96ca3f74630b 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 7e2d714ae7c072ee587d1cf0356cf548ac4be4a9 +Subproject commit 96ca3f74630b1b7cb07ef68e863d479bb2dcf85d From d67b440c44f4ac06bbbe646c57abc384c9451f8a Mon Sep 17 00:00:00 2001 From: "Sudharsan D.G" Date: Thu, 16 May 2019 16:27:13 +0000 Subject: [PATCH 50/88] [devices]: Added index for dell z9100 c32 (#2892) --- .../Force10-Z9100-C32/port_config.ini | 66 +++++++++---------- .../plugins/sfputil.py | 2 +- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/port_config.ini b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/port_config.ini index e000f29bef38..6a8e8351f8b0 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/port_config.ini +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/port_config.ini @@ -1,33 +1,33 @@ -# name lanes alias -Ethernet0 49,50,51,52 hundredGigE1/1 -Ethernet4 53,54,55,56 hundredGigE1/2 -Ethernet8 57,58,59,60 hundredGigE1/3 -Ethernet12 61,62,63,64 hundredGigE1/4 -Ethernet16 65,66,67,68 hundredGigE1/5 -Ethernet20 69,70,71,72 hundredGigE1/6 -Ethernet24 73,74,75,76 hundredGigE1/7 -Ethernet28 77,78,79,80 hundredGigE1/8 -Ethernet32 37,38,39,40 hundredGigE1/9 -Ethernet36 33,34,35,36 hundredGigE1/10 -Ethernet40 45,46,47,48 hundredGigE1/11 -Ethernet44 41,42,43,44 hundredGigE1/12 -Ethernet48 81,82,83,84 hundredGigE1/13 -Ethernet52 85,86,87,88 hundredGigE1/14 -Ethernet56 89,90,91,92 hundredGigE1/15 -Ethernet60 93,94,95,96 hundredGigE1/16 -Ethernet64 97,98,99,100 hundredGigE1/17 -Ethernet68 101,102,103,104 hundredGigE1/18 -Ethernet72 105,106,107,108 hundredGigE1/19 -Ethernet76 109,110,111,112 hundredGigE1/20 -Ethernet80 21,22,23,24 hundredGigE1/21 -Ethernet84 17,18,19,20 hundredGigE1/22 -Ethernet88 29,30,31,32 hundredGigE1/23 -Ethernet92 25,26,27,28 hundredGigE1/24 -Ethernet96 117,118,119,120 hundredGigE1/25 -Ethernet100 113,114,115,116 hundredGigE1/26 -Ethernet104 125,126,127,128 hundredGigE1/27 -Ethernet108 121,122,123,124 hundredGigE1/28 -Ethernet112 5,6,7,8 hundredGigE1/29 -Ethernet116 1,2,3,4 hundredGigE1/30 -Ethernet120 13,14,15,16 hundredGigE1/31 -Ethernet124 9,10,11,12 hundredGigE1/32 +# name lanes alias index +Ethernet0 49,50,51,52 hundredGigE1/1 1 +Ethernet4 53,54,55,56 hundredGigE1/2 2 +Ethernet8 57,58,59,60 hundredGigE1/3 3 +Ethernet12 61,62,63,64 hundredGigE1/4 4 +Ethernet16 65,66,67,68 hundredGigE1/5 5 +Ethernet20 69,70,71,72 hundredGigE1/6 6 +Ethernet24 73,74,75,76 hundredGigE1/7 7 +Ethernet28 77,78,79,80 hundredGigE1/8 8 +Ethernet32 37,38,39,40 hundredGigE1/9 9 +Ethernet36 33,34,35,36 hundredGigE1/10 10 +Ethernet40 45,46,47,48 hundredGigE1/11 11 +Ethernet44 41,42,43,44 hundredGigE1/12 12 +Ethernet48 81,82,83,84 hundredGigE1/13 13 +Ethernet52 85,86,87,88 hundredGigE1/14 14 +Ethernet56 89,90,91,92 hundredGigE1/15 15 +Ethernet60 93,94,95,96 hundredGigE1/16 16 +Ethernet64 97,98,99,100 hundredGigE1/17 17 +Ethernet68 101,102,103,104 hundredGigE1/18 18 +Ethernet72 105,106,107,108 hundredGigE1/19 19 +Ethernet76 109,110,111,112 hundredGigE1/20 20 +Ethernet80 21,22,23,24 hundredGigE1/21 21 +Ethernet84 17,18,19,20 hundredGigE1/22 22 +Ethernet88 29,30,31,32 hundredGigE1/23 23 +Ethernet92 25,26,27,28 hundredGigE1/24 24 +Ethernet96 117,118,119,120 hundredGigE1/25 25 +Ethernet100 113,114,115,116 hundredGigE1/26 26 +Ethernet104 125,126,127,128 hundredGigE1/27 27 +Ethernet108 121,122,123,124 hundredGigE1/28 28 +Ethernet112 5,6,7,8 hundredGigE1/29 29 +Ethernet116 1,2,3,4 hundredGigE1/30 30 +Ethernet120 13,14,15,16 hundredGigE1/31 31 +Ethernet124 9,10,11,12 hundredGigE1/32 32 diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/plugins/sfputil.py b/device/dell/x86_64-dell_z9100_c2538-r0/plugins/sfputil.py index bee1f9bac923..98c01216902d 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dell_z9100_c2538-r0/plugins/sfputil.py @@ -78,7 +78,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(0, self.PORTS_IN_BLOCK + 1) + return range(self.PORT_START, self.PORTS_IN_BLOCK + 1) @property def iom1_port_start(self): From 1e3b62fe8f1f4a3532a4e619b45093dd550162be Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 16 May 2019 10:59:12 -0700 Subject: [PATCH 51/88] [FRR]: Update frr to frr-7.0.1 (#2899) * Update frr to frr-7.0.1 * Fix a typo * Set right permissions on /etc/frr * Convert external file links from debian to Azure * Revert python3 fix * Build frr using more than 1 job * Add SWIG as dependency for libswss-common --- .gitmodules | 1 + dockers/docker-fpm-frr/Dockerfile.j2 | 4 +++- dockers/docker-fpm-frr/start.sh | 1 + dockers/docker-fpm-frr/supervisord.conf | 9 +++++++++ rules/docker-fpm-frr.mk | 2 +- rules/frr.mk | 24 +++++++++++++++--------- rules/libyang.mk | 20 ++++++++++++++++++++ rules/swig.mk | 22 ++++++++++++++++++++++ rules/swss-common.mk | 2 +- sonic-slave-stretch/Dockerfile | 6 +++++- src/libyang/Makefile | 21 +++++++++++++++++++++ src/lldpd/Makefile | 2 +- src/sonic-frr/Makefile | 24 +++++------------------- src/sonic-frr/frr | 2 +- src/swig/Makefile | 21 +++++++++++++++++++++ 15 files changed, 127 insertions(+), 34 deletions(-) create mode 100644 rules/libyang.mk create mode 100644 rules/swig.mk create mode 100644 src/libyang/Makefile create mode 100644 src/swig/Makefile diff --git a/.gitmodules b/.gitmodules index 4e230df90d61..3d2a8e3f7a1d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -47,6 +47,7 @@ [submodule "src/sonic-frr/frr"] path = src/sonic-frr/frr url = https://github.com/Azure/sonic-frr.git + branch = frr/7.0 [submodule "platform/p4/p4-hlir/p4-hlir-v1.1"] path = platform/p4/p4-hlir/p4-hlir-v1.1 url = https://github.com/p4lang/p4-hlir.git diff --git a/dockers/docker-fpm-frr/Dockerfile.j2 b/dockers/docker-fpm-frr/Dockerfile.j2 index fc57b7c0ef3c..748c9b29a5ff 100644 --- a/dockers/docker-fpm-frr/Dockerfile.j2 +++ b/dockers/docker-fpm-frr/Dockerfile.j2 @@ -13,7 +13,7 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update # Install required packages -RUN apt-get install -y libdbus-1-3 libdaemon0 libjansson4 libc-ares2 iproute2 libpython2.7 libjson-c3 logrotate +RUN apt-get install -y libdbus-1-3 libdaemon0 libjansson4 libc-ares2 iproute2 libpython2.7 libjson-c3 logrotate libunwind8 {% if docker_fpm_frr_debs.strip() -%} # Copy locally-built Debian package dependencies @@ -30,6 +30,8 @@ RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return {%- endfor %} {%- endif %} +RUN chown -R ${frr_user_uid}:${frr_user_gid} /etc/frr/ + # Clean up RUN apt-get clean -y RUN apt-get autoclean -y diff --git a/dockers/docker-fpm-frr/start.sh b/dockers/docker-fpm-frr/start.sh index 03bb71d4fc56..238d26783ace 100755 --- a/dockers/docker-fpm-frr/start.sh +++ b/dockers/docker-fpm-frr/start.sh @@ -32,6 +32,7 @@ supervisorctl start bgpcfgd # Start Quagga processes supervisorctl start zebra +supervisorctl start staticd supervisorctl start bgpd if [ "$CONFIG_TYPE" == "unified" ]; then diff --git a/dockers/docker-fpm-frr/supervisord.conf b/dockers/docker-fpm-frr/supervisord.conf index f8aa3297195a..0b1c813847b6 100644 --- a/dockers/docker-fpm-frr/supervisord.conf +++ b/dockers/docker-fpm-frr/supervisord.conf @@ -39,6 +39,15 @@ startsecs=0 stdout_logfile=syslog stderr_logfile=syslog +[program:staticd] +command=/usr/lib/frr/staticd -A 127.0.0.1 +priority=4 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog + [program:bgpd] command=/usr/lib/frr/bgpd -A 127.0.0.1 priority=5 diff --git a/rules/docker-fpm-frr.mk b/rules/docker-fpm-frr.mk index 22da11f29c50..fd593c5cb92a 100644 --- a/rules/docker-fpm-frr.mk +++ b/rules/docker-fpm-frr.mk @@ -2,7 +2,7 @@ DOCKER_FPM_FRR = docker-fpm-frr.gz $(DOCKER_FPM_FRR)_PATH = $(DOCKERS_PATH)/docker-fpm-frr -$(DOCKER_FPM_FRR)_DEPENDS += $(FRR) $(FRR_PYTHONTOOLS) $(SWSS) +$(DOCKER_FPM_FRR)_DEPENDS += $(FRR) $(SWSS) $(LIBYANG) $(DOCKER_FPM_FRR)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) SONIC_DOCKER_IMAGES += $(DOCKER_FPM_FRR) diff --git a/rules/frr.mk b/rules/frr.mk index 3d077c4b055f..ac110d03f54d 100644 --- a/rules/frr.mk +++ b/rules/frr.mk @@ -1,15 +1,21 @@ # FRRouting (frr) package -FRR_VERSION = 6.0.2 -export FRR_VERSION +FRR_VERSION = 7.0.1 +FRR_SUBVERSION = 0 +export FRR_VERSION FRR_SUBVERSION -FRR = frr_$(FRR_VERSION)-1~sonic.debian9+1_amd64.deb -$(FRR)_DEPENDS += $(LIBSNMP_DEV) + +FRR = frr_$(FRR_VERSION)-sonic-$(FRR_SUBVERSION)_amd64.deb +$(FRR)_DEPENDS += $(LIBSNMP_DEV) $(LIBYANG_DEV) +$(FRR)_RDEPENDS += $(LIBYANG) $(FRR)_SRC_PATH = $(SRC_PATH)/sonic-frr SONIC_MAKE_DEBS += $(FRR) +SONIC_STRETCH_DEBS += $(FRR) + +FRR_PYTHONTOOLS = frr-pythontools_$(FRR_VERSION)-sonic-$(FRR_SUBVERSION)_all.deb +$(eval $(call add_derived_package,$(FRR),$(FRR_PYTHONTOOLS))) + +FRR_DBG = frr-dbgsym_$(FRR_VERSION)-sonic-$(FRR_SUBVERSION)_amd64.deb +$(eval $(call add_derived_package,$(FRR),$(FRR_DBG))) -# FRRouting pythontools -FRR_PYTHONTOOLS = frr-pythontools_$(FRR_VERSION)-1~sonic.debian9+1_amd64.deb -$(FRR_PYTHONTOOLS)_DEPENDS += $(LIBSNMP_DEV) -$(FRR_PYTHONTOOLS)_SRC_PATH = $(SRC_PATH)/sonic-frr -SONIC_MAKE_DEBS += $(FRR_PYTHONTOOLS) +export FRR FRR_PYTHONTOOLS FRR_DBG diff --git a/rules/libyang.mk b/rules/libyang.mk new file mode 100644 index 000000000000..e2dabdf30442 --- /dev/null +++ b/rules/libyang.mk @@ -0,0 +1,20 @@ +# libyang + +LIBYANG_VERSION_BASE = 0.16 +LIBYANG_VERSION = $(LIBYANG_VERSION_BASE).105 +LIBYANG_SUBVERSION = 1 + +export LIBYANG_VERSION_BASE +export LIBYANG_VERSION +export LIBYANG_SUBVERSION + +LIBYANG = libyang$(LIBYANG_VERSION_BASE)_$(LIBYANG_VERSION)-$(LIBYANG_SUBVERSION)_amd64.deb +$(LIBYANG)_SRC_PATH = $(SRC_PATH)/libyang +$(LIBYANG)_DEPENDS += $(SWIG_BASE) $(SWIG) +SONIC_MAKE_DEBS += $(LIBYANG) +SONIC_STRETCH_DEBS += $(LIBYANG) + +LIBYANG_DEV = libyang-dev_$(LIBYANG_VERSION)-$(LIBYANG_SUBVERSION)_amd64.deb +$(eval $(call add_derived_package,$(LIBYANG),$(LIBYANG_DEV))) + +export LIBYANG LIBYANG_DEV diff --git a/rules/swig.mk b/rules/swig.mk new file mode 100644 index 000000000000..630ac81c9c3d --- /dev/null +++ b/rules/swig.mk @@ -0,0 +1,22 @@ +# swig + +SWIG_VERSION_BASE = 3.0 +SWIG_VERSION = $(SWIG_VERSION_BASE).12 +SWIG_SUBVERSION = 2 + +export SWIG_VERSION_BASE +export SWIG_VERSION +export SWIG_SUBVERSION + +SWIG_BASE = swig$(SWIG_VERSION_BASE)_$(SWIG_VERSION)-$(SWIG_SUBVERSION)_amd64.deb +$(SWIG_BASE)_SRC_PATH = $(SRC_PATH)/swig +SONIC_MAKE_DEBS += $(SWIG_BASE) +SONIC_STRETCH_DEBS += $(SWIG_BASE) + +SWIG = swig_$(SWIG_VERSION)-$(SWIG_SUBVERSION)_amd64.deb +$(eval $(call add_derived_package,$(SWIG_BASE),$(SWIG))) + +SWIG_DBG = swig$(SWIG_VERSION_BASE)-dbgsym_$(SWIG_VERSION)-$(SWIG_SUBVERSION)_amd64.deb +$(eval $(call add_derived_package,$(SWIG_BASE),$(SWIG_DBG))) + +export SWIG_BASE SWIG SWIG_DBG diff --git a/rules/swss-common.mk b/rules/swss-common.mk index 623410d4cdab..c8e21d7d5f9f 100644 --- a/rules/swss-common.mk +++ b/rules/swss-common.mk @@ -4,7 +4,7 @@ LIBSWSSCOMMON = libswsscommon_1.0.0_amd64.deb $(LIBSWSSCOMMON)_SRC_PATH = $(SRC_PATH)/sonic-swss-common $(LIBSWSSCOMMON)_DEPENDS += $(LIBHIREDIS_DEV) $(LIBNL3_DEV) $(LIBNL_GENL3_DEV) \ $(LIBNL_ROUTE3_DEV) $(LIBNL_NF3_DEV) \ - $(LIBNL_CLI_DEV) + $(LIBNL_CLI_DEV) $(SWIG) $(LIBSWSSCOMMON)_RDEPENDS += $(LIBHIREDIS) $(LIBNL3) $(LIBNL_GENL3) \ $(LIBNL_ROUTE3) $(LIBNL_NF3) $(LIBNL_CLI) SONIC_DPKG_DEBS += $(LIBSWSSCOMMON) diff --git a/sonic-slave-stretch/Dockerfile b/sonic-slave-stretch/Dockerfile index ac41f1e77c81..43e8b6ff9c03 100644 --- a/sonic-slave-stretch/Dockerfile +++ b/sonic-slave-stretch/Dockerfile @@ -62,6 +62,11 @@ RUN apt-get update && apt-get install -y \ libjson-c-dev \ libsystemd-dev \ python-ipaddr \ + libcmocka-dev \ + python3-all-dev \ + python3-all-dbg \ + install-info \ + logrotate \ # For libnl3 (local) build cdbs \ # For SAI meta build @@ -109,7 +114,6 @@ RUN apt-get update && apt-get install -y \ dpatch \ libdb-dev \ iptables-dev \ - swig \ ctags \ # For mellanox sai build libtool-bin \ diff --git a/src/libyang/Makefile b/src/libyang/Makefile new file mode 100644 index 000000000000..99dedcd1a4ab --- /dev/null +++ b/src/libyang/Makefile @@ -0,0 +1,21 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +MAIN_TARGET = $(LIBYANG) +DERIVED_TARGETS = $(LIBYANG_DEV) + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + rm -fr ./libyang-$(LIBYANG_VERSION) + wget -O libyang_$(LIBYANG_VERSION).orig.tar.gz 'https://sonicstorage.blob.core.windows.net/packages/libyang_0.16.105.orig.tar.gz?sv=2015-04-05&sr=b&sig=yTWDhl6B9TTXWAQ46zpLiNxUib61W7U0%2F%2FGvhRibKOc%3D&se=2046-09-30T22%3A10%3A27Z&sp=r' + wget -O libyang_$(LIBYANG_VERSION).dsc 'https://sonicstorage.blob.core.windows.net/packages/libyang_0.16.105-1.dsc?sv=2015-04-05&sr=b&sig=eLkO5wzB1C5oKNIaUPro4gwrgEC3EygIO6eCyTzHmeI%3D&se=2046-09-30T22%3A10%3A12Z&sp=r' + wget -O libyang_$(LIBYANG_VERSION)-$(LIBYANG_SUBVERSION).debian.tar.xz 'https://sonicstorage.blob.core.windows.net/packages/libyang_0.16.105-1.debian.tar.xz?sv=2015-04-05&sr=b&sig=AH18p7pKK0xIBVxZuA8EMv9%2FhXbCFKmbWAn7Za8%2BZW4%3D&se=2046-09-30T22%3A09%3A36Z&sp=r' + dpkg-source -x libyang_$(LIBYANG_VERSION).dsc + + pushd ./libyang-$(LIBYANG_VERSION) + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + popd + + mv $(DERIVED_TARGETS) $* $(DEST)/ + +$(addprefix $(DEST)/, $(DERIVED_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) diff --git a/src/lldpd/Makefile b/src/lldpd/Makefile index ca0f83aa6d38..0d0dadbfdec6 100644 --- a/src/lldpd/Makefile +++ b/src/lldpd/Makefile @@ -17,7 +17,7 @@ DEBIAN_FILE_URL = $(LLDP_URL)/$(DEBIAN_FILE) $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Remove any stale files - rm -rf ./lldpd + rm -rf lldpd-$(LLDPD_VERSION) # download debian LLDPDD wget -NO "$(DSC_FILE)" $(DSC_FILE_URL) diff --git a/src/sonic-frr/Makefile b/src/sonic-frr/Makefile index c2ccffbbebd7..48da9c72116e 100644 --- a/src/sonic-frr/Makefile +++ b/src/sonic-frr/Makefile @@ -2,29 +2,15 @@ SHELL = /bin/bash .SHELLFLAGS += -e -MAIN_TARGET = frr_$(FRR_VERSION)-1~sonic.debian9+1_amd64.deb -TOOLS_TARGET = frr-pythontools_$(FRR_VERSION)-1~sonic.debian9+1_amd64.deb -MAIN_TARGET_DBG = frr-dbgsym_$(FRR_VERSION)-1~sonic.debian9+1_amd64.deb -DERIVED_TARGET = $(TOOLS_TARGET) $(MAIN_TARGET_DBG) +MAIN_TARGET = $(FRR) +DERIVED_TARGET = $(FRR_PYTHONTOOLS) $(FRR_DBG) $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : - # Build the package pushd ./frr - - # This could very well be tools/tarsource.sh -V -e sonic - tools/tarsource.sh -V - # This is a no-op but here in case the changelog stops being a symlink - debchange -b -v $(FRR_VERSION)-1~sonic.debian9+1 'SONiC FRR debian package build' - sudo apt-get -y install install-info - dpkg-buildpackage -rfakeroot -b -us -uc -Ppkg.frr.nortrlib - cd .. - mv frr_$(FRR_VERSION)-*_amd64.deb $(MAIN_TARGET) - mv frr-pythontools_$(FRR_VERSION)-*_all.deb $(TOOLS_TARGET) - mv frr-dbgsym_$(FRR_VERSION)-*_amd64.deb $(MAIN_TARGET_DBG) - mv $(DERIVED_TARGET) $* $(DEST)/ - + tools/tarsource.sh -V -e '-sonic' + dpkg-buildpackage -rfakeroot -b -us -uc -Ppkg.frr.nortrlib -j$(SONIC_CONFIG_MAKE_JOBS) popd + mv $(DERIVED_TARGET) $* $(DEST)/ $(addprefix $(DEST)/, $(DERIVED_TARGET)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) - diff --git a/src/sonic-frr/frr b/src/sonic-frr/frr index 5a35fd375978..cd305c0973be 160000 --- a/src/sonic-frr/frr +++ b/src/sonic-frr/frr @@ -1 +1 @@ -Subproject commit 5a35fd375978dd7fce99c4b8ba84b0cdd1f32ac3 +Subproject commit cd305c0973be0baa1173e09f9d72e096c03e7e7e diff --git a/src/swig/Makefile b/src/swig/Makefile new file mode 100644 index 000000000000..f9deda6a831d --- /dev/null +++ b/src/swig/Makefile @@ -0,0 +1,21 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +MAIN_TARGET = $(SWIG_BASE) +DERIVED_TARGETS = $(SWIG) $(SWIG_DBG) + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + rm -fr ./swig-$(SWIG_VERSION) *.deb + wget -O swig_$(SWIG_VERSION).orig.tar.gz 'https://sonicstorage.blob.core.windows.net/packages/swig_3.0.12.orig.tar.gz?sv=2015-04-05&sr=b&sig=kcSKFvlTQZst8Dbb8MUfckGbVEZU5sptFqT2HbwOUtA%3D&se=2046-09-30T22%3A11%3A59Z&sp=r' + wget -O swig_$(SWIG_VERSION).dsc 'https://sonicstorage.blob.core.windows.net/packages/swig_3.0.12-2.dsc?sv=2015-04-05&sr=b&sig=k3eLfmWgmCz1Kx8SYcirX18FSQdJ76ifo%2B9rbJBnrf8%3D&se=2046-09-30T22%3A11%3A45Z&sp=r' + wget -O swig_$(SWIG_VERSION)-$(SWIG_SUBVERSION).debian.tar.xz 'https://sonicstorage.blob.core.windows.net/packages/swig_3.0.12-2.debian.tar.xz?sv=2015-04-05&sr=b&sig=SQICTE%2BR1BO7npUBNwTQjo447OaFz%2BooX6VAm912c7g%3D&se=2046-09-30T22%3A11%3A32Z&sp=r' + dpkg-source -x swig_$(SWIG_VERSION).dsc + + pushd ./swig-$(SWIG_VERSION) + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + popd + + mv $(DERIVED_TARGETS) $* $(DEST)/ + +$(addprefix $(DEST)/, $(DERIVED_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) From d29a496dbc63983454c19d9d682df4b2614139d3 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Fri, 17 May 2019 04:49:00 +0300 Subject: [PATCH 52/88] [mlnx] refactor and fix mlnx-sfpd shutdown (#2907) * [mlnx] fix mlnx-sfpd shutdown Signed-off-by: Stepan Blyschak * fix type and handle only EINTR and EAGAIN errors from select Signed-off-by: Stepan Blyschak * handle select.error as well during init/run Signed-off-by: Stepan Blyschak --- platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd | 367 +++++++++--------- 1 file changed, 191 insertions(+), 176 deletions(-) diff --git a/platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd b/platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd index a1d2e6d9c3b5..764bcc7c5ad7 100644 --- a/platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd +++ b/platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd @@ -10,6 +10,7 @@ import os import time import syslog import signal +import select import json import threading from python_sdk_api.sx_api import * @@ -27,9 +28,12 @@ STATUS_PLUGIN = '1' STATUS_PLUGOUT = '0' STATUS_UNKNOWN = '2' -SFPD_LIVENESS_UPDATE_INTERVAL_SECS = 30 +SFPD_LIVENESS_EXPIRE_SECS = 30 -sfp_value_status_dict = {SDK_SFP_STATE_IN:STATUS_PLUGIN, SDK_SFP_STATE_OUT:STATUS_PLUGOUT} +sfp_value_status_dict = { + SDK_SFP_STATE_IN: STATUS_PLUGIN, + SDK_SFP_STATE_OUT: STATUS_PLUGOUT, +} # ========================== Syslog wrappers ========================== def log_info(msg, also_print_to_console=False): @@ -56,188 +60,199 @@ def log_error(msg, also_print_to_console=False): if also_print_to_console: print(msg) -# ========================== Signal Handling ========================== -def signal_handler(sig, frame): - if sig == signal.SIGHUP: - log_info("Caught SIGHUP - ignoring...") - return - elif sig == signal.SIGINT: - log_info("Caught SIGINT - exiting...") - sys.exit(128 + sig) - elif sig == signal.SIGTERM: - log_info("Caught SIGTERM - exiting...") - sys.exit(128 + sig) - else: - log_warning("Caught unhandled signal '" + sig + "'") - - -def sx_recv(fd_p, handle): - # recv parameters - pkt_size = 2000 - pkt_size_p = new_uint32_t_p() - uint32_t_p_assign(pkt_size_p, pkt_size) - pkt = new_uint8_t_arr(pkt_size) - recv_info_p = new_sx_receive_info_t_p() - pmpe_t = sx_event_pmpe_t() - logical_port_list = new_sx_port_log_id_t_arr(4) - port_attributes_list = new_sx_port_attributes_t_arr(64) - port_cnt_p = new_uint32_t_p() - uint32_t_p_assign(port_cnt_p,64) - label_port_list = [] - status = True - module_state = 0 - - rc = sx_lib_host_ifc_recv(fd_p, pkt, pkt_size_p, recv_info_p) - if rc != 0: - log_error("event receive exit with error, rc %d" % rc) - status = False - return status, label_port_list, module_state - - pmpe_t = recv_info_p.event_info.pmpe - port_list_size = pmpe_t.list_size - logical_port_list = pmpe_t.log_port_list - module_state = pmpe_t.module_state - - for i in range(0, port_list_size): - logical_port = sx_port_log_id_t_arr_getitem(logical_port_list, i) - rc = sx_api_port_device_get(handle, 1 , 0, port_attributes_list, port_cnt_p) - port_cnt = uint32_t_p_value(port_cnt_p) - - for i in range(0, port_cnt): - port_attributes = sx_port_attributes_t_arr_getitem(port_attributes_list,i) - if port_attributes.log_port == logical_port: - lable_port = port_attributes.port_mapping.module_port +# ========================== MlnxSfpd class ========================== +class MlnxSfpd: + ''' Listen to plugin/plugout cable events ''' + + SX_OPEN_RETRIES = 20 + SELECT_TIMEOUT = 1 + + def __init__(self): + self.swid = 0 + self.running = False + self.handle = None + + # Allocate SDK fd and user channel structures + self.rx_fd_p = new_sx_fd_t_p() + self.user_channel_p = new_sx_user_channel_t_p() + + self.state_db = SonicV2Connector(host=REDIS_HOSTIP) + + # Register our signal handlers + signal.signal(signal.SIGHUP, self.signal_handler) + signal.signal(signal.SIGINT, self.signal_handler) + signal.signal(signal.SIGTERM, self.signal_handler) + + def signal_handler(self, signum, frame): + if signum == signal.SIGHUP: + log_info("Caught SIGHUP - ignoring...") + elif signum == signal.SIGINT: + log_info("Caught SIGINT - exiting...") + self.running = False + elif signum == signal.SIGTERM: + log_info("Caught SIGINT - exiting...") + self.running = False + else: + log_warning("Caught unhandled signal '{}'".format(signum)) + + def initialize(self): + self.state_db.connect("STATE_DB") + + # open SDK API handle + # retry at most SX_OPEN_RETRIES times to wait + # until SDK is started during system startup + retry = 1 + while True: + rc, self.handle = sx_api_open(None) + if rc == SX_STATUS_SUCCESS: break - label_port_list.append(lable_port) - - return status, label_port_list, module_state, - -def send_sfp_notification(db, interface, state): - sfp_notify = [interface, state] - msg = json.dumps(sfp_notify, separators=(',', ':')) - db.publish('STATE_DB', 'TRANSCEIVER_NOTIFY', msg) - return - -def update_sfpd_liveness_key(db, timeout_secs): - if db.exists('STATE_DB', 'MLNX_SFPD_TASK|LIVENESS'): - db.expire('STATE_DB', 'MLNX_SFPD_TASK|LIVENESS', timeout_secs) - else: - db.set('STATE_DB', 'MLNX_SFPD_TASK|LIVENESS', 'value', 'ok') - db.expire('STATE_DB', 'MLNX_SFPD_TASK|LIVENESS', timeout_secs) - -# Timer thread wrapper class to update mlnx-sfpd liveness info to DB periodically -class sfpd_liveness_update_task: - def __init__(self, db): - self.task_stopping_event = threading.Event() - self.task_timer = None - self.state_db = db - - def task_run(self): - if self.task_stopping_event.isSet(): - log_error("Error: sfpd liveness update thread received stop event, exiting...") - return - update_sfpd_liveness_key(self.state_db, 2*SFPD_LIVENESS_UPDATE_INTERVAL_SECS) + log_warning("failed to open SDK API handle... retrying {}".format(retry)) + + time.sleep(2 ** retry) + retry += 1 + + if retry > self.SX_OPEN_RETRIES: + raise RuntimeError("failed to open SDK API handle after {} retries".format(retry)) + + rc = sx_api_host_ifc_open(self.handle, self.rx_fd_p) + if rc != SX_STATUS_SUCCESS: + raise RuntimeError("sx_api_host_ifc_open exited with error, rc {}".format(rc)) - self.task_timer = threading.Timer(SFPD_LIVENESS_UPDATE_INTERVAL_SECS, self.task_run) - self.task_timer.start() + self.user_channel_p.type = SX_USER_CHANNEL_TYPE_FD + self.user_channel_p.fd = self.rx_fd_p + + rc = sx_api_host_ifc_trap_id_register_set(self.handle, + SX_ACCESS_CMD_REGISTER, + self.swid, + SX_TRAP_ID_PMPE, + self.user_channel_p) + if rc != SX_STATUS_SUCCESS: + raise RuntimeError("sx_api_host_ifc_trap_id_register_set exited with error, rc {}".format(c)) + + def deinitialize(self): + # remove mlnx-sfpd liveness key in DB if not expired yet + if self.state_db.exists("STATE_DB", "MLNX_SFPD_TASK|LIVENESS"): + self.state_db.delete("STATE_DB", "MLNX_SFPD_TASK|LIVENESS") + + if self.handle is None: + return - def task_stop(self): - self.task_stopping_event.set() - self.task_timer.join() + # unregister trap id + rc = sx_api_host_ifc_trap_id_register_set(self.handle, + SX_ACCESS_CMD_DEREGISTER, + self.swid, + SX_TRAP_ID_PMPE, + self.user_channel_p) + if rc != SX_STATUS_SUCCESS: + log_error("sx_api_host_ifc_trap_id_register_set exited with error, rc {}".format(rc)) + + rc = sx_api_host_ifc_close(self.handle, self.rx_fd_p) + if rc != SX_STATUS_SUCCESS: + log_error("sx_api_host_ifc_close exited with error, rc {}".format(rc)) + + rc = sx_api_close(self.handle) + if rc != SX_STATUS_SUCCESS: + log_error("sx_api_close exited with error, rc {}".format(rc)) + + def run(self): + self.running = True + + while self.running: + try: + read, _, _ = select.select([self.rx_fd_p.fd], [], [], self.SELECT_TIMEOUT) + except select.error as err: + rc, msg = err + if rc == errno.EAGAIN or rc == errno.EINTR: + continue + else: + raise + + for fd in read: + if fd == self.rx_fd_p.fd: + rc, port_list, module_state = self.on_pmpe(self.rx_fd_p) + if rc != SX_STATUS_SUCCESS: + raise RuntimeError("failed to read from {}".format(fd)) + + sfp_state = sfp_value_status_dict.get(module_state, STATUS_UNKNOWN) + if sfp_state == STATUS_UNKNOWN: + log_error("unknown module state {} on port {}".format(module_state, port)) + continue + + for port in port_list: + log_info("SFP on port {} state {}".format(port, sfp_state)) + self.send_sfp_notification(port, sfp_state) + + self.update_sfpd_liveness_key(SFPD_LIVENESS_EXPIRE_SECS) + + def send_sfp_notification(self, port, state): + sfp_notify = [port, state] + msg = json.dumps(sfp_notify, seperators=(',', ':')) + self.state_db.publish('STATE_DB', 'TRANSCEIVER_NOTIFY', msg) + + def update_sfpd_liveness_key(self, timeout_secs): + if not self.state_db.exists('STATE_DB', 'MLNX_SFPD_TASK|LIVENESS'): + self.state_db.set('STATE_DB', 'MLNX_SFPD_TASK|LIVENESS', 'value', 'ok') + self.state_db.expire('STATE_DB', 'MLNX_SFPD_TASK|LIVENESS', timeout_secs) + + def on_pmpe(self, fd_p): + ''' on port module plug event handler ''' + + # recv parameters + pkt_size = 2000 + pkt_size_p = new_uint32_t_p() + uint32_t_p_assign(pkt_size_p, pkt_size) + pkt = new_uint8_t_arr(pkt_size) + recv_info_p = new_sx_receive_info_t_p() + pmpe_t = sx_event_pmpe_t() + logical_port_list = new_sx_port_log_id_t_arr(4) + port_attributes_list = new_sx_port_attributes_t_arr(64) + port_cnt_p = new_uint32_t_p() + uint32_t_p_assign(port_cnt_p,64) + label_port_list = [] + status = True + module_state = 0 + + rc = sx_lib_host_ifc_recv(fd_p, pkt, pkt_size_p, recv_info_p) + if rc != 0: + log_error("sx_lib_host_ifc_recv exited with error, rc %d" % rc) + status = False + return status, label_port_list, module_state + + pmpe_t = recv_info_p.event_info.pmpe + port_list_size = pmpe_t.list_size + logical_port_list = pmpe_t.log_port_list + module_state = pmpe_t.module_state + + for i in xrange(port_list_size): + logical_port = sx_port_log_id_t_arr_getitem(logical_port_list, i) + rc = sx_api_port_device_get(self.handle, 1 , 0, port_attributes_list, port_cnt_p) + port_cnt = uint32_t_p_value(port_cnt_p) + + for i in xrange(port_cnt): + port_attributes = sx_port_attributes_t_arr_getitem(port_attributes_list,i) + if port_attributes.log_port == logical_port: + lable_port = port_attributes.port_mapping.module_port + break + label_port_list.append(lable_port) + + return status, label_port_list, module_state, # main start def main(): - # Register our signal handlers - signal.signal(signal.SIGHUP, signal_handler) - signal.signal(signal.SIGINT, signal_handler) - signal.signal(signal.SIGTERM, signal_handler) - - # Connect to state db for notification sending - state_db = SonicV2Connector(host=REDIS_HOSTIP) - state_db.connect(state_db.STATE_DB) - - # Open SDK handler - log_info("starting mlnx-sfpd...") - rc, handle = sx_api_open(None) - retry_time = 1 - while rc != SX_STATUS_SUCCESS: - time.sleep(2**retry_time) - retry_time += 1 - rc, handle = sx_api_open(None) - if retry_time > 20: - log_error("Failed to open api handle. Please check that SDK is running.") - sys.exit(errno.EACCES) - - # Open recv fd - rx_fd_p = new_sx_fd_t_p() - rc = sx_api_host_ifc_open(handle, rx_fd_p) - if rc != 0: - log_error("sx_api_host_ifc_open exit with error, rc %d" % rc) - exit(rc) - - # Set up general host ifc parameters - swid = 0 - cmd = SX_ACCESS_CMD_REGISTER - uc_p = new_sx_user_channel_t_p() - uc_p.type = SX_USER_CHANNEL_TYPE_FD - uc_p.channel.fd = rx_fd_p - trap_id = SX_TRAP_ID_PMPE - - rc = sx_api_host_ifc_trap_id_register_set(handle, cmd, swid, trap_id, uc_p) - if rc != 0: - log_error("sx_api_host_ifc_trap_id_register_set exit with error, rc %d" % rc) - exit(rc) - - liveness_info_update = sfpd_liveness_update_task(state_db) - liveness_info_update.task_run() - - # Main loop for sfp event listening - log_info("mlnx-sfpd started") - while True: - sfp_state = STATUS_UNKNOWN - rc, port_list, module_state = sx_recv(rx_fd_p, handle) - if not rc: - log_error("Failed to recv event from SDK, please check that SDK is running.") - break - - if module_state in sfp_value_status_dict: sfp_state = sfp_value_status_dict[module_state] - - if sfp_state != STATUS_UNKNOWN: - for port in port_list: - log_info("SFP on port %d state %s" % (port, sfp_state)) - send_sfp_notification(state_db, str(port), sfp_state) - - log_info("sfp change event handling done") - - # Stop liveness update task - liveness_info_update.task_stop() - - # Remove mlnx-sfpd liveness key in DB if not expired yet. - if state_db.exists('STATE_DB', 'MLNX_SFPD_TASK|LIVENESS'): - state_db.delete(state_db, 'MLNX_SFPD_TASK|LIVENESS') - - # unregister trap id - cmd = SX_ACCESS_CMD_DEREGISTER - rc = sx_api_host_ifc_trap_id_register_set(handle, cmd, swid, trap_id, uc_p) - if rc != 0: - log_error("sx_api_host_ifc_trap_id_register_set exit with error, rc %d" % rc) - exit(rc) - - # Close read fp - rc = sx_api_host_ifc_close(handle, rx_fd_p) - if rc != 0: - log_error("sx_api_host_ifc_close exit with error, rc %d" % rc) - exit(rc) - - # Close sdk handler - rc = sx_api_close(handle) - if rc != 0: - log_error("sx_api_close exit with error, rc %d" % rc) - exit(rc) - - log_info("mlnx-sfpd exited") + log_info("mlnx-sfpd daemon started") + + sfpd = MlnxSfpd() + try: + sfpd.initialize() + sfpd.run() + except (RuntimeError, select.error) as err: + log_error("error: {}".format(err)) + finally: + sfpd.deinitialize() + + log_info("mlnx-sfpd daemon exited") if __name__ == '__main__': From 68ccfaaade82608419d834e240482da46e84d758 Mon Sep 17 00:00:00 2001 From: Harish Venkatraman Date: Thu, 16 May 2019 18:49:30 -0700 Subject: [PATCH 53/88] [DellEMC-Z9264f-C64] Add PFC support for z9264f (#2893) This commit adds new code and JSON file to support PFC and broadcom recommended MMU setting for PFC feaure on z9264f (100G) T1 support. The buffers_defaults_t1.json file has the broadcom recommended values for T1 configuration. Unit tested and verified by running the JSON file and checking the hardware registers and table in broadcom. The settings in the hardware is reflecting the broadcom recommended values. Signed-off-by: Harish Venkatraman --- .../DellEMC-Z9264f-C64/buffers.json.j2 | 2 + .../DellEMC-Z9264f-C64/buffers_defaults_t1.j2 | 47 +++++++++++++++++++ .../DellEMC-Z9264f-C64/pg_profile_lookup.ini | 17 +++++++ .../DellEMC-Z9264f-C64/qos.json.j2 | 1 + 4 files changed, 67 insertions(+) create mode 100644 device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/buffers.json.j2 create mode 100644 device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/buffers_defaults_t1.j2 create mode 100644 device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/pg_profile_lookup.ini create mode 100644 device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/qos.json.j2 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/buffers.json.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..f120b337de04 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/buffers_defaults_t1.j2 @@ -0,0 +1,47 @@ + +{%- set default_cable = '40m' %} + +{%- 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": "34859968", + "type": "ingress", + "mode": "dynamic", + "xoff": "7847424" + }, + "egress_lossy_pool": { + "size": "29631680", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "43481152", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"10870288" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/pg_profile_lookup.ini b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/pg_profile_lookup.ini new file mode 100644 index 000000000000..aedda37a8878 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1248 2288 35776 -3 2288 + 25000 5m 1248 2288 53248 -3 2288 + 40000 5m 1248 2288 66560 -3 2288 + 50000 5m 1248 2288 90272 -3 2288 + 100000 5m 1248 2288 165568 -3 2288 + 10000 40m 1248 2288 37024 -3 2288 + 25000 40m 1248 2288 53248 -3 2288 + 40000 40m 1248 2288 71552 -3 2288 + 50000 40m 1248 2288 96096 -3 2288 + 100000 40m 1248 2288 177632 -3 2288 + 10000 300m 1248 2288 46176 -3 2288 + 25000 300m 1248 2288 79040 -3 2288 + 40000 300m 1248 2288 108160 -3 2288 + 50000 300m 1248 2288 141856 -3 2288 + 100000 300m 1248 2288 268736 -3 2288 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/qos.json.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} From 939b6254e7a8ce65205fae3406482392401963f2 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Fri, 17 May 2019 23:45:33 +0300 Subject: [PATCH 54/88] [mellanox]: Fixed SDK build: added missing SWIG dependency. (#2914) Signed-off-by: Nazarii Hnydyn --- platform/mellanox/sdk.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 1d209fd5a3db..56ef185cdcd0 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -62,7 +62,7 @@ $(eval $(call add_derived_package,$(SXD_LIBS),$(SXD_LIBS_DEV))) #packages that are required for runtime only PYTHON_SDK_API = python-sdk-api_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb $(PYTHON_SDK_API)_SRC_PATH = $(PLATFORM_PATH)/sdk-src/python-sdk-api -$(PYTHON_SDK_API)_DEPENDS += $(APPLIBS_DEV) $(SXD_LIBS_DEV) +$(PYTHON_SDK_API)_DEPENDS += $(APPLIBS_DEV) $(SXD_LIBS_DEV) $(SWIG) $(PYTHON_SDK_API)_RDEPENDS += $(APPLIBS) $(SXD_LIBS) SX_KERNEL = sx-kernel_1.mlnx.$(MLNX_SDK_DEB_VERSION)_amd64.deb From f3d2d37e43c880a57db6d98753c9bbac945baf67 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Sat, 18 May 2019 04:53:57 +0300 Subject: [PATCH 55/88] [mlnx] fix incorrect attr assignment in mlnx-sfpd (#2913) * [mlnx] fix incorrect attr assignment in mlnx-sfpd Signed-off-by: Stepan Blyschak * [mlnx] on_pmpe returns bool and not SX_STATUS_SUCCESS Signed-off-by: Stepan Blyschak * [mlnx] fix typo Signed-off-by: Stepan Blyschak --- platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd b/platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd index 764bcc7c5ad7..d5f53c1c710e 100644 --- a/platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd +++ b/platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd @@ -120,7 +120,7 @@ class MlnxSfpd: raise RuntimeError("sx_api_host_ifc_open exited with error, rc {}".format(rc)) self.user_channel_p.type = SX_USER_CHANNEL_TYPE_FD - self.user_channel_p.fd = self.rx_fd_p + self.user_channel_p.channel.fd = self.rx_fd_p rc = sx_api_host_ifc_trap_id_register_set(self.handle, SX_ACCESS_CMD_REGISTER, @@ -170,8 +170,8 @@ class MlnxSfpd: for fd in read: if fd == self.rx_fd_p.fd: - rc, port_list, module_state = self.on_pmpe(self.rx_fd_p) - if rc != SX_STATUS_SUCCESS: + success, port_list, module_state = self.on_pmpe(self.rx_fd_p) + if not success: raise RuntimeError("failed to read from {}".format(fd)) sfp_state = sfp_value_status_dict.get(module_state, STATUS_UNKNOWN) @@ -187,7 +187,7 @@ class MlnxSfpd: def send_sfp_notification(self, port, state): sfp_notify = [port, state] - msg = json.dumps(sfp_notify, seperators=(',', ':')) + msg = json.dumps(sfp_notify, separators=(',', ':')) self.state_db.publish('STATE_DB', 'TRANSCEIVER_NOTIFY', msg) def update_sfpd_liveness_key(self, timeout_secs): From 59da7faca6ff24bf6c76692fe7cbcd5dfb13ac0b Mon Sep 17 00:00:00 2001 From: lguohan Date: Sat, 18 May 2019 10:31:13 -0700 Subject: [PATCH 56/88] [build]: install rsyslog and vim in sonic-slave-stretch (#2920) Signed-off-by: Guohan Lu --- sonic-slave-stretch/Dockerfile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sonic-slave-stretch/Dockerfile b/sonic-slave-stretch/Dockerfile index 43e8b6ff9c03..5cb328f6b257 100644 --- a/sonic-slave-stretch/Dockerfile +++ b/sonic-slave-stretch/Dockerfile @@ -290,6 +290,12 @@ RUN pip install setuptools==40.8.0 # Install dependencies for isc-dhcp-relay build RUN apt-get -y build-dep isc-dhcp +# Install vim +RUN apt-get install -y vim + +# Install rsyslog +RUN apt-get install -y rsyslog + RUN cd /usr/src/gtest && cmake . && make -C /usr/src/gtest RUN mkdir /var/run/sshd From 49ec97fad2e9f7ca45a6370b8c00f26d8b416370 Mon Sep 17 00:00:00 2001 From: Shuotian Cheng Date: Sat, 18 May 2019 10:32:26 -0700 Subject: [PATCH 57/88] [swss-common]: Update common submodule (#2918) Add schema for buffer pool: COUNTER_ID_LIST, PLUGIN_LIST, and COUNTERS NAME_MAP (#272) [schema]: Add STATE_MIRROR_SESSION_TABLE_NAME (#278) [schema]: Add POLICER configuration table (#277) [schema]: Add SWITCH_CAPABILITY_TABLE (#276) Signed-off-by: Shu0T1an ChenG --- 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 8af58ad80df5..485db073a17d 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 8af58ad80df531fc7fe1fa197a1caf2c5520dbb3 +Subproject commit 485db073a17d2ac0cd9d6f29b0b8d7c245c66663 From aac0c24312cb4f8130ec66bff9f596212800d208 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Sat, 18 May 2019 10:34:07 -0700 Subject: [PATCH 58/88] [device/Arista] Add support for the 7280CR3-32P4 (#2910) * Add boot0 support for the 7280CR3 * Add platform and plugins for 7280CR3 * Add port config for 7280CR3 * Add platform_reboot for 7280CR3 * Add support for 7280CR3-32D4 based on the 7280CR3-32P4 * Update arista driver submodules - Introduce new 7280CR3-32P4 - Improve to the led plugin for OSFP --- device/arista/x86_64-arista_7280cr3_32d4 | 1 + .../Arista-7280CR3-C32D4 | 1 + .../Arista-7280CR3-C32P4/port_config.ini | 37 +++++++++++ .../x86_64-arista_7280cr3_32p4/default_sku | 1 + .../x86_64-arista_7280cr3_32p4/fancontrol | 10 +++ .../platform_reboot | 1 + .../plugins/eeprom.py | 8 +++ .../plugins/led_control.py | 8 +++ .../plugins/psuutil.py | 8 +++ .../plugins/sfputil.py | 8 +++ .../x86_64-arista_7280cr3_32p4/sensors.conf | 66 +++++++++++++++++++ files/Aboot/boot0.j2 | 15 ++++- .../barefoot/sonic-platform-modules-arista | 2 +- .../broadcom/sonic-platform-modules-arista | 2 +- 14 files changed, 164 insertions(+), 4 deletions(-) create mode 120000 device/arista/x86_64-arista_7280cr3_32d4 create mode 120000 device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32D4 create mode 100644 device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32P4/port_config.ini create mode 100644 device/arista/x86_64-arista_7280cr3_32p4/default_sku create mode 100644 device/arista/x86_64-arista_7280cr3_32p4/fancontrol create mode 120000 device/arista/x86_64-arista_7280cr3_32p4/platform_reboot create mode 100644 device/arista/x86_64-arista_7280cr3_32p4/plugins/eeprom.py create mode 100644 device/arista/x86_64-arista_7280cr3_32p4/plugins/led_control.py create mode 100644 device/arista/x86_64-arista_7280cr3_32p4/plugins/psuutil.py create mode 100644 device/arista/x86_64-arista_7280cr3_32p4/plugins/sfputil.py create mode 100644 device/arista/x86_64-arista_7280cr3_32p4/sensors.conf diff --git a/device/arista/x86_64-arista_7280cr3_32d4 b/device/arista/x86_64-arista_7280cr3_32d4 new file mode 120000 index 000000000000..d6e2ddbb64bd --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32d4 @@ -0,0 +1 @@ +x86_64-arista_7280cr3_32p4 \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32D4 b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32D4 new file mode 120000 index 000000000000..cfdaca201c0a --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32D4 @@ -0,0 +1 @@ +Arista-7280CR3-C32P4 \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32P4/port_config.ini b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32P4/port_config.ini new file mode 100644 index 000000000000..976eae864d55 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32P4/port_config.ini @@ -0,0 +1,37 @@ +# name lanes alias index speed +Ethernet0 1,2 Ethernet1/1 1 100000 +Ethernet4 3,4 Ethernet2/1 2 100000 +Ethernet8 5,6 Ethernet3/1 3 100000 +Ethernet12 7,8 Ethernet4/1 4 100000 +Ethernet16 9,10 Ethernet5/1 5 100000 +Ethernet20 11,12 Ethernet6/1 6 100000 +Ethernet24 13,14 Ethernet7/1 7 100000 +Ethernet28 15,16 Ethernet8/1 8 100000 +Ethernet32 17,18 Ethernet9/1 9 100000 +Ethernet36 19,20 Ethernet10/1 10 100000 +Ethernet40 21,22 Ethernet11/1 11 100000 +Ethernet44 23,24 Ethernet12/1 12 100000 +Ethernet48 25,26 Ethernet13/1 13 100000 +Ethernet52 27,28 Ethernet14/1 14 100000 +Ethernet56 29,30 Ethernet15/1 15 100000 +Ethernet60 31,32 Ethernet16/1 16 100000 +Ethernet64 73,74 Ethernet17/1 17 100000 +Ethernet68 75,76 Ethernet18/1 18 100000 +Ethernet72 77,78 Ethernet19/1 19 100000 +Ethernet76 79,80 Ethernet20/1 20 100000 +Ethernet80 65,66 Ethernet21/1 21 100000 +Ethernet84 67,68 Ethernet22/1 22 100000 +Ethernet88 69,70 Ethernet23/1 23 100000 +Ethernet92 71,72 Ethernet24/1 24 100000 +Ethernet96 57,58 Ethernet25/1 25 100000 +Ethernet100 59,60 Ethernet26/1 26 100000 +Ethernet104 61,62 Ethernet27/1 27 100000 +Ethernet108 63,64 Ethernet28/1 28 100000 +Ethernet112 49,50 Ethernet29/1 29 100000 +Ethernet116 51,52 Ethernet30/1 30 100000 +Ethernet120 53,54 Ethernet31/1 31 100000 +Ethernet124 55,56 Ethernet32/1 32 100000 +Ethernet128 33,34,35,36,37,38,39,40 Ethernet33/1 33 400000 +Ethernet132 41,42,43,44,45,46,47,48 Ethernet34/1 34 400000 +Ethernet136 89,90,91,92,93,94,95,96 Ethernet35/1 35 400000 +Ethernet140 81,82,83,84,85,86,87,88 Ethernet36/1 36 400000 diff --git a/device/arista/x86_64-arista_7280cr3_32p4/default_sku b/device/arista/x86_64-arista_7280cr3_32p4/default_sku new file mode 100644 index 000000000000..a65e1f845ad3 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/default_sku @@ -0,0 +1 @@ +Arista-7280CR3-C32P4 t1 diff --git a/device/arista/x86_64-arista_7280cr3_32p4/fancontrol b/device/arista/x86_64-arista_7280cr3_32p4/fancontrol new file mode 100644 index 000000000000..1c0415b7e464 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/fancontrol @@ -0,0 +1,10 @@ +INTERVAL=5 +DEVPATH=hwmon2=devices/pci0000:00/0000:00:09.0 hwmon4=devices/pci0000:00/0000:00:09.0/i2c-56/56-004c +DEVNAME=hwmon2=scd_fan_p3 hwmon4=max6658 +FCTEMPS=hwmon2/pwm6=hwmon4/temp1_input hwmon2/pwm5=hwmon4/temp1_input hwmon2/pwm4=hwmon4/temp1_input hwmon2/pwm4=hwmon4/temp1_input hwmon2/pwm2=hwmon4/temp1_input hwmon2/pwm1=hwmon4/temp1_input +FCFANS=hwmon2/pwm6=hwmon2/fan6_input hwmon2/pwm5=hwmon2/fan5_input hwmon2/pwm4=hwmon2/fan4_input hwmon2/pwm3=hwmon2/fan3_input hwmon2/pwm2=hwmon2/fan2_input hwmon2/pwm1=hwmon2/fan1_input +MINTEMP=hwmon2/pwm6=50 hwmon2/pwm5=50 hwmon2/pwm4=50 hwmon2/pwm3=50 hwmon2/pwm2=50 hwmon2/pwm1=50 +MINPWM=hwmon2/pwm6=128 hwmon2/pwm5=128 hwmon2/pwm4=128 hwmon2/pwm3=128 hwmon2/pwm2=128 hwmon2/pwm1=128 +MAXTEMP=hwmon2/pwm6=60 hwmon2/pwm5=60 hwmon2/pwm4=60 hwmon2/pwm3=60 hwmon2/pwm2=60 hwmon2/pwm1=60 +MINSTART=hwmon2/pwm6=128 hwmon2/pwm5=128 hwmon2/pwm4=128 hwmon2/pwm3=128 hwmon2/pwm2=128 hwmon2/pwm1=128 +MINSTOP=hwmon2/pwm6=128 hwmon2/pwm5=128 hwmon2/pwm4=128 hwmon2/pwm3=128 hwmon2/pwm2=128 hwmon2/pwm1=128 diff --git a/device/arista/x86_64-arista_7280cr3_32p4/platform_reboot b/device/arista/x86_64-arista_7280cr3_32p4/platform_reboot new file mode 120000 index 000000000000..7f94a49e38b0 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/platform_reboot @@ -0,0 +1 @@ +../x86_64-arista_common/platform_reboot \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32p4/plugins/eeprom.py b/device/arista/x86_64-arista_7280cr3_32p4/plugins/eeprom.py new file mode 100644 index 000000000000..d439e442ee33 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/plugins/eeprom.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python + +try: + import arista.utils.sonic_eeprom as arista_eeprom +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +board = arista_eeprom.getTlvInfoDecoder() diff --git a/device/arista/x86_64-arista_7280cr3_32p4/plugins/led_control.py b/device/arista/x86_64-arista_7280cr3_32p4/plugins/led_control.py new file mode 100644 index 000000000000..fae2d504beb6 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/plugins/led_control.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python + +try: + import arista.utils.sonic_leds as arista_leds +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +LedControl = arista_leds.getLedControl() diff --git a/device/arista/x86_64-arista_7280cr3_32p4/plugins/psuutil.py b/device/arista/x86_64-arista_7280cr3_32p4/plugins/psuutil.py new file mode 100644 index 000000000000..d5ff3063dd8c --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/plugins/psuutil.py @@ -0,0 +1,8 @@ +# psuutil.py + +try: + import arista.utils.sonic_psu as arista_psuutil +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +PsuUtil = arista_psuutil.getPsuUtil() diff --git a/device/arista/x86_64-arista_7280cr3_32p4/plugins/sfputil.py b/device/arista/x86_64-arista_7280cr3_32p4/plugins/sfputil.py new file mode 100644 index 000000000000..1357ad786434 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/plugins/sfputil.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python + +try: + import arista.utils.sonic_sfputil as arista_sfputil +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +SfpUtil = arista_sfputil.getSfpUtil() diff --git a/device/arista/x86_64-arista_7280cr3_32p4/sensors.conf b/device/arista/x86_64-arista_7280cr3_32p4/sensors.conf new file mode 100644 index 000000000000..2a80dbd612ac --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/sensors.conf @@ -0,0 +1,66 @@ +# libsensors configuration file for DCS-7280CR3-32P4 +# ------------------------------------------------# + +bus "i2c-8" "SCD 0000:02:00.0 SMBus master 0 bus 0" +bus "i2c-14" "SCD 0000:02:00.0 SMBus master 0 bus 6" +bus "i2c-15" "SCD 0000:02:00.0 SMBus master 0 bus 7" +bus "i2c-56" "SCD 0000:00:09.0 SMBus master 0 bus 0" + +chip "tmp468-i2c-8-48" + label temp1 "Board sensor" + label temp2 "Front air (inlet) sensor" + label temp3 "Rear air sensor" + label temp4 "Front left sensor" + label temp5 "Front right sensor" + label temp6 "Rear left sensor" + label temp7 "Rear right sensor" + label temp8 "Asic temp sensor 1" + label temp9 "Asic temp sensor 2" + + set temp1_max 75 + set temp1_crit 80 + set temp2_max 65 + set temp2_crit 75 + set temp3_max 65 + set temp3_crit 75 + ignore temp4 + ignore temp5 + ignore temp6 + ignore temp7 + set temp8_max 100 + set temp8_crit 110 + set temp9_max 100 + set temp9_crit 110 + +chip "pmbus-i2c-14-58" + label temp1 "Power supply 1 hotspot sensor" + label temp2 "Power supply 1 inlet temp sensor" + label temp3 "Power supply 1 exhaust temp sensor" + + # setting maximum and critical thresholds is not supported for this psu + # fault and warning limits defined internally by hardware + + ignore fan2 + ignore fan3 + ignore fan4 + +chip "pmbus-i2c-15-58" + label temp1 "Power supply 2 hotspot sensor" + label temp2 "Power supply 2 inlet temp sensor" + label temp3 "Power supply 2 exhaust temp sensor" + + # setting maximum and critical thresholds is not supported for this psu + # fault and warning limits defined internally by hardware + + ignore fan2 + ignore fan3 + ignore fan4 + +chip "max6658-i2c-56-4c" + label temp1 "Back panel temp sensor 1" + label temp2 "Back panel temp sensor 2" + + set temp1_max 75 + set temp1_crit 85 + set temp2_max 75 + set temp2_crit 85 diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index bab1801dc91b..64b1414fc187 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -255,8 +255,13 @@ platform_specific() { aboot_machine=arista_7060dx4_32 flash_size=28000 fi - if [ "$platform" = "rook" ]; then - echo "iommu=on intel_iommu=on tsc=reliable pcie_ports=native" >>/tmp/append + if [ "$sid" = "Smartsville" ]; then + aboot_machine=arista_7280cr3_32p4 + flash_size=7382 + fi + if [ "$platform" = "rook" ] || [ "$platform" = "magpie" ] || + [ "$platform" = "woodpecker" ]; then + echo "tsc=reliable pcie_ports=native" >>/tmp/append echo "rhash_entries=1 usb-storage.delay_use=0" >>/tmp/append if [ -x /bin/readprefdl ]; then readprefdl -f /tmp/.system-prefdl -d > /mnt/flash/.system-prefdl @@ -266,6 +271,12 @@ platform_specific() { fi echo "reassign_prefmem" >> /tmp/append fi + if [ "$platform" = "rook" ] || [ "$platform" = "magpie" ]; then + echo "iommu=on intel_iommu=on" >>/tmp/append + fi + if [ "$platform" = "woodpecker" ]; then + echo "amd_iommu=off modprobe.blacklist=snd_hda_intel,hdaudio" >> /tmp/append + fi if [ $flash_size -ge 28000 ]; then varlog_size=4096 diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index 96ca3f74630b..0ed1df5a7d6c 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 96ca3f74630b1b7cb07ef68e863d479bb2dcf85d +Subproject commit 0ed1df5a7d6c88319ce41b10ce604c2727afab69 diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index 96ca3f74630b..0ed1df5a7d6c 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 96ca3f74630b1b7cb07ef68e863d479bb2dcf85d +Subproject commit 0ed1df5a7d6c88319ce41b10ce604c2727afab69 From 77919507f24f27d8f6da694684a87206e0328207 Mon Sep 17 00:00:00 2001 From: brandonchuang Date: Sun, 19 May 2019 01:36:58 +0800 Subject: [PATCH 59/88] [Accton AS7326]: Add lpmode in sfputil.py (#2905) Signed-off-by: brandon_chuang --- .../plugins/sfputil.py | 62 +++++++++++++++++-- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py index 4844d220158f..eca0abc39ee2 100644 --- a/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7326_56x-r0/plugins/sfputil.py @@ -5,6 +5,8 @@ try: import time + import string + from ctypes import create_string_buffer from sonic_sfp.sfputilbase import SfpUtilBase except ImportError as e: raise ImportError("%s - required module not found" % str(e)) @@ -193,11 +195,63 @@ def get_presence(self, port_num): return False - def get_low_power_mode(self, port_num): - raise NotImplementedError + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: + return False - def set_low_power_mode(self, port_num, lpmode): - raise NotImplementedError + try: + eeprom = None + + if not self.get_presence(port_num): + return False + + eeprom = open(self.port_to_eeprom_mapping[port_num], "rb") + eeprom.seek(93) + lpmode = ord(eeprom.read(1)) + + if ((lpmode & 0x3) == 0x1): + return False # High Power Mode if "Power override" bit is 1 and "Power set" bit is 0 + else: + return True # Low Power Mode if one of the following conditions is matched: + # 1. Power override" bit is 0 + # 2. Power override" bit is 1 and "Power set" bit is 1 + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: + return False + + try: + eeprom = None + + if not self.get_presence(port_num): + return False # Port is not present, unable to set the eeprom + + # Fill in write buffer + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + buffer = create_string_buffer(1) + buffer[0] = chr(regval) + + # Write to eeprom + eeprom = open(self.port_to_eeprom_mapping[port_num], "r+b") + eeprom.seek(93) + eeprom.write(buffer[0]) + return True + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) def reset(self, port_num): raise NotImplementedError From 71d0f4667215ca1faf410f921651cbd9b6374f5c Mon Sep 17 00:00:00 2001 From: xiongjihai Date: Sun, 19 May 2019 01:40:57 +0800 Subject: [PATCH 60/88] [sonic-cfggen]: fix bug in file sonic-cfggen (#2834) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixing bug of file sonic-cfggen. Error occurs if argument --var-json is set when running sonic-cfggen,for example: Command: sonic-cfggen -d --var-json VLAN_MEMBER Configuration in config_db.json: "VLAN_MEMBER": { ...... "Vlan11|Ethernet32": { "tagging_mode": "untagged" }, ...... Error occurs because FormatConverter.to_serialized(data) in file sonic-cfggen doesn't serialize keys correctly --- src/sonic-config-engine/sonic-cfggen | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index a711ca1301e0..3f7951248c61 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -109,13 +109,13 @@ TODO(taoyl): Current version of config db only supports BGP admin states. @staticmethod def to_serialized(data): - for table in data: - if type(data[table]) is dict: - data[table] = OrderedDict(natsorted(data[table].items())) - for key in data[table].keys(): - new_key = ConfigDBConnector.serialize_key(key) - if new_key != key: - data[table][new_key] = data[table].pop(key) + if type(data) is dict: + data = OrderedDict(natsorted(data.items())) + for key in data.keys(): + new_key = ConfigDBConnector.serialize_key(key) + if new_key != key: + data[new_key] = data.pop(key) + data[new_key] = FormatConverter.to_serialized(data[new_key]) return data @staticmethod From 222706120d83a2dc219775fd2f7666725ea7b8c5 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Sat, 18 May 2019 22:08:41 -0700 Subject: [PATCH 61/88] [updategraph] set DB version after minigraph reload (#2917) Signed-off-by: Ying Xie --- files/image_config/updategraph/updategraph | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/files/image_config/updategraph/updategraph b/files/image_config/updategraph/updategraph index 686108727b27..b14f75f8582f 100755 --- a/files/image_config/updategraph/updategraph +++ b/files/image_config/updategraph/updategraph @@ -16,6 +16,11 @@ reload_minigraph() fi config qos reload pfcwd start_default + + if [[ -x /usr/bin/db_migrator.py ]]; then + # Set latest version number + /usr/bin/db_migrator.py -o set_version + fi } function copy_config_files_and_directories() From 6aad2da47505d6e1c095d04e56036dade66e10b7 Mon Sep 17 00:00:00 2001 From: xiongjihai Date: Sun, 19 May 2019 13:10:54 +0800 Subject: [PATCH 62/88] [sonic-cfggen]: Add a unit-test in sonic-cfggen to test argument "--var-json" (#2906) --- src/sonic-config-engine/tests/test_cfggen.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index a841f4d19c23..5a6c0f62ce26 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -65,6 +65,11 @@ def test_additional_json_data(self): output = self.run_script(argument) self.assertEqual(output.strip(), 'value1') + def test_var_json_data(self): + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" --var-json VLAN_MEMBER' + output = self.run_script(argument) + self.assertEqual(output.strip(), '{\n "Vlan1000|Ethernet8": {\n "tagging_mode": "untagged"\n }\n}') + def test_read_yaml(self): argument = '-v yml_item -y ' + os.path.join(self.test_dir, 'test.yml') output = self.run_script(argument) From c1a501e9d5de0afa05ac6625d5931eb76f18e421 Mon Sep 17 00:00:00 2001 From: jostar-yang Date: Sun, 19 May 2019 13:11:38 +0800 Subject: [PATCH 63/88] [devices]: Add to support as4630-54pe platform (#2895) * Add to support as4630-54pe platform * Add as4630 monitor psu/fan status --- platform/broadcom/one-image.mk | 1 + platform/broadcom/platform-modules-accton.mk | 7 + .../as4630-54pe/classes/__init__.py | 0 .../as4630-54pe/classes/fanutil.py | 251 ++++ .../as4630-54pe/classes/thermalutil.py | 131 ++ .../as4630-54pe/modules/Makefile | 19 + .../modules/x86-64-accton-as4630-54pe-cpld.c | 1105 +++++++++++++++++ .../modules/x86-64-accton-as4630-54pe-leds.c | 579 +++++++++ .../modules/x86-64-accton-as4630-54pe-psu.c | 320 +++++ .../as4630-54pe/modules/ym2651y.c | 1 + .../as4630-54pe-platform-monitor-fan.service | 16 + .../as4630-54pe-platform-monitor-psu.service | 16 + .../as4630-54pe-platform-monitor.service | 18 + .../as4630-54pe/setup.py | 16 + .../as4630-54pe/utils/README | 117 ++ .../utils/accton_as4630_54pe_monitor.py | 345 +++++ .../utils/accton_as4630_54pe_monitor_fan.py | 191 +++ .../utils/accton_as4630_54pe_monitor_psu.py | 169 +++ .../utils/accton_as4630_54pe_util.py | 563 +++++++++ .../common/modules/ym2651y.c | 2 + .../debian/control | 4 + .../debian/rules | 2 +- 22 files changed, 3872 insertions(+), 1 deletion(-) create mode 100755 platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/__init__.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/thermalutil.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/Makefile create mode 100755 platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-cpld.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-leds.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-psu.c create mode 120000 platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/ym2651y.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor-fan.service create mode 100755 platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor-psu.service create mode 100755 platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor.service create mode 100755 platform/broadcom/sonic-platform-modules-accton/as4630-54pe/setup.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/README create mode 100755 platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_fan.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_psu.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py mode change 100644 => 100755 platform/broadcom/sonic-platform-modules-accton/common/modules/ym2651y.c diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index a277c6f59297..fe4d1be96adc 100755 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -22,6 +22,7 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(ACCTON_AS7716_32XB_PLATFORM_MODULE) \ $(ACCTON_AS6712_32X_PLATFORM_MODULE) \ $(ACCTON_AS7726_32X_PLATFORM_MODULE) \ + $(ACCTON_AS4630_54PE_PLATFORM_MODULE) \ $(ACCTON_MINIPACK_PLATFORM_MODULE) \ $(INVENTEC_D7032Q28B_PLATFORM_MODULE) \ $(INVENTEC_D7054Q28B_PLATFORM_MODULE) \ diff --git a/platform/broadcom/platform-modules-accton.mk b/platform/broadcom/platform-modules-accton.mk index 76ef6ae3ccdc..db169a1fe14c 100755 --- a/platform/broadcom/platform-modules-accton.mk +++ b/platform/broadcom/platform-modules-accton.mk @@ -9,6 +9,7 @@ ACCTON_AS7326_56X_PLATFORM_MODULE_VERSION = 1.1 ACCTON_AS7716_32XB_PLATFORM_MODULE_VERSION = 1.1 ACCTON_AS6712_32X_PLATFORM_MODULE_VERSION = 1.1 ACCTON_AS7726_32X_PLATFORM_MODULE_VERSION = 1.1 +ACCTON_AS4630_54PE_PLATFORM_MODULE_VERSION = 1.1 ACCTON_MINIPACK_PLATFORM_MODULE_VERSION = 1.1 export ACCTON_AS7712_32X_PLATFORM_MODULE_VERSION @@ -20,6 +21,7 @@ export ACCTON_AS7326_56X_PLATFORM_MODULE_VERSION export ACCTON_AS7716_32XB_PLATFORM_MODULE_VERSION export ACCTON_AS6712_32X_PLATFORM_MODULE_VERSION export ACCTON_AS7726_32X_PLATFORM_MODULE_VERSION +export ACCTON_AS4630_54PE_PLATFORM_MODULE_VERSION export ACCTON_MINIPACK_PLATFORM_MODULE_VERSION ACCTON_AS7712_32X_PLATFORM_MODULE = sonic-platform-accton-as7712-32x_$(ACCTON_AS7712_32X_PLATFORM_MODULE_VERSION)_amd64.deb @@ -60,6 +62,11 @@ ACCTON_AS7726_32X_PLATFORM_MODULE = sonic-platform-accton-as7726-32x_$(ACCTON_AS $(ACCTON_AS7726_32X_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as7726_32x-r0 $(eval $(call add_extra_package,$(ACCTON_AS7712_32X_PLATFORM_MODULE),$(ACCTON_AS7726_32X_PLATFORM_MODULE))) +ACCTON_AS4630_54PE_PLATFORM_MODULE = sonic-platform-accton-as4630-54pe_$(ACCTON_AS4630_54PE_PLATFORM_MODULE_VERSION)_amd64.deb +$(ACCTON_AS4630_54PE_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as4630_54pe-r0 +$(eval $(call add_extra_package,$(ACCTON_AS7712_32X_PLATFORM_MODULE),$(ACCTON_AS4630_54PE_PLATFORM_MODULE))) + + ACCTON_MINIPACK_PLATFORM_MODULE = sonic-platform-accton-minipack_$(ACCTON_MINIPACK_PLATFORM_MODULE_VERSION)_amd64.deb $(ACCTON_MINIPACK_PLATFORM_MODULE)_PLATFORM = x86_64-accton_minipack-r0 $(eval $(call add_extra_package,$(ACCTON_AS7712_32X_PLATFORM_MODULE),$(ACCTON_MINIPACK_PLATFORM_MODULE))) diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/__init__.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/__init__.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py new file mode 100755 index 000000000000..ca0f3f9da1e3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/fanutil.py @@ -0,0 +1,251 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# 1/10/2018: Jostar modify for as7716_32 +# 12/03/2018: Jostar modify for as7726_32 +# ------------------------------------------------------------------ + +try: + import time + import logging + from collections import namedtuple +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + + +class FanUtil(object): + """Platform-specific FanUtil class""" + + FAN_NUM_ON_MAIN_BROAD = 6 + FAN_NUM_1_IDX = 1 + FAN_NUM_2_IDX = 2 + FAN_NUM_3_IDX = 3 + FAN_NUM_4_IDX = 4 + FAN_NUM_5_IDX = 5 + FAN_NUM_6_IDX = 6 + + FAN_NODE_NUM_OF_MAP = 2 + FAN_NODE_FAULT_IDX_OF_MAP = 1 + FAN_NODE_DIR_IDX_OF_MAP = 2 + + BASE_VAL_PATH = '/sys/bus/i2c/devices/54-0066/{0}' + FAN_DUTY_PATH = '/sys/bus/i2c/devices/54-0066/fan_duty_cycle_percentage' + + #logfile = '' + #loglevel = logging.INFO + + """ Dictionary where + key1 = fan id index (integer) starting from 1 + key2 = fan node index (interger) starting from 1 + value = path to fan device file (string) """ + _fan_to_device_path_mapping = {} + +#fan1_direction +#fan1_fault +#fan1_present + + #(FAN_NUM_2_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan2_duty_cycle_percentage', + _fan_to_device_node_mapping = { + (FAN_NUM_1_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan1_fault', + (FAN_NUM_1_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan1_direction', + + (FAN_NUM_2_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan2_fault', + (FAN_NUM_2_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan2_direction', + + (FAN_NUM_3_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan3_fault', + (FAN_NUM_3_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan3_direction', + + (FAN_NUM_4_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan4_fault', + (FAN_NUM_4_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan4_direction', + + (FAN_NUM_5_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan5_fault', + (FAN_NUM_5_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan5_direction', + + (FAN_NUM_6_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan6_fault', + (FAN_NUM_6_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan6_direction', + } + + def _get_fan_to_device_node(self, fan_num, node_num): + return self._fan_to_device_node_mapping[(fan_num, node_num)] + + def _get_fan_node_val(self, fan_num, node_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num:%d', fan_num) + return None + + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + logging.debug('GET. Parameter error. node_num:%d', node_num) + return None + + device_path = self.get_fan_to_device_path(fan_num, node_num) + + try: + val_file = open(device_path, 'r') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return int(content) + + def _set_fan_node_val(self, fan_num, node_num, val): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num:%d', fan_num) + return None + + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + logging.debug('GET. Parameter error. node_num:%d', node_num) + return None + + content = str(val) + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + device_path = self.get_fan_to_device_path(fan_num, node_num) + try: + val_file = open(device_path, 'w') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + val_file.write(content) + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return True + + def __init__(self): + fan_path = self.BASE_VAL_PATH + + for fan_num in range(self.FAN_NUM_1_IDX, self.FAN_NUM_ON_MAIN_BROAD+1): + for node_num in range(self.FAN_NODE_FAULT_IDX_OF_MAP, self.FAN_NODE_NUM_OF_MAP+1): + self._fan_to_device_path_mapping[(fan_num, node_num)] = fan_path.format( + self._fan_to_device_node_mapping[(fan_num, node_num)]) + + def get_num_fans(self): + return self.FAN_NUM_ON_MAIN_BROAD + + def get_idx_fan_start(self): + return self.FAN_NUM_1_IDX + + def get_num_nodes(self): + return self.FAN_NODE_NUM_OF_MAP + + def get_idx_node_start(self): + return self.FAN_NODE_FAULT_IDX_OF_MAP + + def get_size_node_map(self): + return len(self._fan_to_device_node_mapping) + + def get_size_path_map(self): + return len(self._fan_to_device_path_mapping) + + def get_fan_to_device_path(self, fan_num, node_num): + return self._fan_to_device_path_mapping[(fan_num, node_num)] + + def get_fan_fault(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_FAULT_IDX_OF_MAP) + + #def get_fan_speed(self, fan_num): + # return self._get_fan_node_val(fan_num, self.FAN_NODE_SPEED_IDX_OF_MAP) + + def get_fan_dir(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_DIR_IDX_OF_MAP) + + def get_fan_duty_cycle(self): + #duty_path = self.FAN_DUTY_PATH + try: + val_file = open(self.FAN_DUTY_PATH) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = val_file.readline().rstrip() + val_file.close() + + return int(content) + #self._get_fan_node_val(fan_num, self.FAN_NODE_DUTY_IDX_OF_MAP) +#static u32 reg_val_to_duty_cycle(u8 reg_val) +#{ +# reg_val &= FAN_DUTY_CYCLE_REG_MASK; +# return ((u32)(reg_val+1) * 625 + 75)/ 100; +#} +# + def set_fan_duty_cycle(self, val): + + try: + fan_file = open(self.FAN_DUTY_PATH, 'r+') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + #val = ((val + 1 ) * 625 +75 ) / 100 + fan_file.write(str(val)) + fan_file.close() + return True + + #def get_fanr_fault(self, fan_num): + # return self._get_fan_node_val(fan_num, self.FANR_NODE_FAULT_IDX_OF_MAP) + + def get_fanr_speed(self, fan_num): + return self._get_fan_node_val(fan_num, self.FANR_NODE_SPEED_IDX_OF_MAP) + + def get_fan_status(self, fan_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num, %d', fan_num) + return None + + if self.get_fan_fault(fan_num) is not None and self.get_fan_fault(fan_num) > 0: + logging.debug('GET. FAN fault. fan_num, %d', fan_num) + return False + + #if self.get_fanr_fault(fan_num) is not None and self.get_fanr_fault(fan_num) > 0: + # logging.debug('GET. FANR fault. fan_num, %d', fan_num) + # return False + + return True + +#def main(): +# fan = FanUtil() +# +# print 'get_size_node_map : %d' % fan.get_size_node_map() +# print 'get_size_path_map : %d' % fan.get_size_path_map() +# for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): +# for y in range(fan.get_idx_node_start(), fan.get_num_nodes()+1): +# print fan.get_fan_to_device_path(x, y) +# +#if __name__ == '__main__': +# main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/thermalutil.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/thermalutil.py new file mode 100755 index 000000000000..96163f1d63ab --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/classes/thermalutil.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# 1/10/2018:Jostar modify for as7716_32x +# 12/03/2018:Jostar modify for as7726_32x thermal plan +# ------------------------------------------------------------------ + +try: + import os + import time + import logging + import glob + import commands + from collections import namedtuple +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + +class ThermalUtil(object): + """Platform-specific ThermalUtil class""" + THERMAL_NUM_MAX = 5 + THERMAL_NUM_1_IDX = 1 # 1_ON_MAIN_BROAD. LM75 + THERMAL_NUM_2_IDX = 2 # 2_ON_MAIN_BROAD. LM75 + THERMAL_NUM_3_IDX = 3 # 3_ON_MAIN_BROAD. LM75 + THERMAL_NUM_4_IDX = 4 # 4_ON_MAIN_BROAD. LM75 + THERMAL_NUM_5_IDX = 5 # 5_ON_MAIN_BROAD. LM75 + + """ Dictionary where + key1 = thermal id index (integer) starting from 1 + value = path to fan device file (string) """ + #_thermal_to_device_path_mapping = {} + + _thermal_to_device_node_mapping = { + THERMAL_NUM_1_IDX: ['55', '48'], + THERMAL_NUM_2_IDX: ['55', '49'], + THERMAL_NUM_3_IDX: ['55', '4a'], + THERMAL_NUM_4_IDX: ['55', '4b'], + THERMAL_NUM_5_IDX: ['54', '4c'], + } + thermal_sysfspath ={ + THERMAL_NUM_1_IDX: ["/sys/bus/i2c/devices/55-0048/hwmon/hwmon4/temp1_input"], + THERMAL_NUM_2_IDX: ["/sys/bus/i2c/devices/55-0049/hwmon/hwmon5/temp1_input"], + THERMAL_NUM_3_IDX: ["/sys/bus/i2c/devices/55-004a/hwmon/hwmon6/temp1_input"], + THERMAL_NUM_4_IDX: ["/sys/bus/i2c/devices/55-004b/hwmon/hwmon7/temp1_input"], + THERMAL_NUM_5_IDX: ["/sys/bus/i2c/devices/54-004c/hwmon/hwmon3/temp1_input"], + } + + #def __init__(self): + def _get_thermal_val(self, thermal_num): + if thermal_num < self.THERMAL_NUM_1_IDX or thermal_num > self.THERMAL_NUM_MAX: + logging.debug('GET. Parameter error. thermal_num, %d', thermal_num) + return None + + device_path = self.get_thermal_to_device_path(thermal_num) + if(os.path.isfile(device_path)): + for filename in glob.glob(device_path): + try: + val_file = open(filename, 'r') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + content = val_file.readline().rstrip() + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + return int(content) + + else: + print "No such device_path=%s"%device_path + return 0 + + def get_num_thermals(self): + return self.THERMAL_NUM_MAX + + def get_idx_thermal_start(self): + return self.THERMAL_NUM_1_IDX + + def get_size_node_map(self): + return len(self._thermal_to_device_node_mapping) + + def get_size_path_map(self): + return len(self.thermal_sysfspath) + + def get_thermal_to_device_path(self, thermal_num): + return self.thermal_sysfspath[thermal_num][0] + + def get_thermal_1_val(self): + return self._get_thermal_node_val(self.THERMAL_NUM_1_IDX) + + def get_thermal_2_val(self): + return self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) + def get_thermal_temp(self): + return (self._get_thermal_node_val(self.THERMAL_NUM_1_IDX) + self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) +self._get_thermal_node_val(self.THERMAL_NUM_3_IDX)) + +def main(): + thermal = ThermalUtil() + print "termal1=%d" %thermal._get_thermal_val(1) + print "termal2=%d" %thermal._get_thermal_val(2) + print "termal3=%d" %thermal._get_thermal_val(3) + print "termal4=%d" %thermal._get_thermal_val(4) + print "termal5=%d" %thermal._get_thermal_val(5) +# +# print 'get_size_node_map : %d' % thermal.get_size_node_map() +# print 'get_size_path_map : %d' % thermal.get_size_path_map() +# for x in range(thermal.get_idx_thermal_start(), thermal.get_num_thermals()+1): +# print thermal.get_thermal_to_device_path(x) +# +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/Makefile b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/Makefile new file mode 100755 index 000000000000..f845f2e17d86 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/Makefile @@ -0,0 +1,19 @@ +ifneq ($(KERNELRELEASE),) +obj-m:= x86-64-accton-as4630-54pe-cpld.o x86-64-accton-as4630-54pe-psu.o \ + x86-64-accton-as4630-54pe-leds.o ym2651y.o + +else +ifeq (,$(KERNEL_SRC)) +#$(error KERNEL_SRC is not defined) +KVERSION=3.16.0-8-amd64 +KERNEL_DIR = /usr/src/linux-headers-$(KVERSION)/ +KERNELDIR:=$(KERNEL_DIR) +else +KERNELDIR:=$(KERNEL_SRC) +endif +PWD:=$(shell pwd) +default: + $(MAKE) -C $(KERNELDIR) M=$(PWD) modules +clean: + rm -rf *.o *.mod.o *.mod.o *.mod.c *.ko .*cmd .tmp_versions Module.markers Module.symvers modules.order +endif diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-cpld.c b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-cpld.c new file mode 100755 index 000000000000..5e25e824d418 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-cpld.c @@ -0,0 +1,1105 @@ +/* + * Copyright (C) Jostar yang + * + * This module supports the accton cpld that hold the channel select + * mechanism for other i2c slave devices, such as SFP. + * This includes the: + * Accton as4630_54pe CPLD + * + * Based on: + * pca954x.c from Kumar Gala + * Copyright (C) 2006 + * + * Based on: + * pca954x.c from Ken Harrenstien + * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) + * + * Based on: + * i2c-virtual_cb.c from Brian Kuschak + * and + * pca9540.c from Jean Delvare . + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define I2C_RW_RETRY_COUNT 10 +#define I2C_RW_RETRY_INTERVAL 60 /* ms */ +#define FAN_DUTY_CYCLE_REG_MASK 0x1F +#define FAN_MAX_DUTY_CYCLE 100 +#define FAN_REG_VAL_TO_SPEED_RPM_STEP 114 // R.P.M value = read value x3.79*60/2 + +#define NUM_THERMAL_SENSORS (3) /* Get sum of this number of sensors.*/ +#define THERMAL_SENSORS_DRIVER "lm75" +#define THERMAL_SENSORS_ADDRS {0x48, 0x4a, 0x4b} + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +enum cpld_type { + as4630_54pe_cpld, +}; +enum fan_id { + FAN1_ID, + FAN2_ID, + FAN3_ID, +}; + +static const u8 fan_reg[] = { + 0x87, /* fan status, fan direction */ + 0x1A, /* fan PWM(for fan1 ,fan2) */ + 0x1B, /* fan PWM(for fan1 ,fan2) */ + 0x88, /* front fan1 speed(rpm) */ + 0x89, /* front fan2 speed(rpm) */ + 0x8A, /* front fan3 speed(rpm) */ + 0x20, /*fan fault*/ +}; + +struct as4630_54pe_cpld_data { + enum cpld_type type; + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_fan_val[ARRAY_SIZE(fan_reg)]; /* Register value */ + int system_temp; /*In unit of mini-Celsius*/ + int sensors_found; +}; + + + +static const struct i2c_device_id as4630_54pe_cpld_id[] = { + { "as4630_54pe_cpld", as4630_54pe_cpld}, + { } +}; +MODULE_DEVICE_TABLE(i2c, as4630_54pe_cpld_id); + +#define TRANSCEIVER_PRESENT_ATTR_ID(index) MODULE_PRESENT_##index +#define TRANSCEIVER_TXDISABLE_ATTR_ID(index) MODULE_TXDISABLE_##index +#define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index +#define TRANSCEIVER_TXFAULT_ATTR_ID(index) MODULE_TXFAULT_##index +#define FAN_SPEED_RPM_ATTR_ID(index) FAN_SPEED_RPM_##index +#define FAN_DIRECTION_ID(index) FAN_DIRECTION_##index +#define FAN_PRESENT_ATTR_ID(index) FAN_PRESENT_##index +#define FAN_FAULT_ATTR_ID(index) FAN_FAULT_##index + +enum as4630_54pe_cpld_sysfs_attributes { + CPLD_VERSION, + ACCESS, + /* transceiver attributes */ + TRANSCEIVER_RXLOS_ATTR_ID(49), + TRANSCEIVER_RXLOS_ATTR_ID(50), + TRANSCEIVER_RXLOS_ATTR_ID(51), + TRANSCEIVER_RXLOS_ATTR_ID(52), + TRANSCEIVER_TXFAULT_ATTR_ID(49), + TRANSCEIVER_TXFAULT_ATTR_ID(50), + TRANSCEIVER_TXFAULT_ATTR_ID(51), + TRANSCEIVER_TXFAULT_ATTR_ID(52), + TRANSCEIVER_PRESENT_ATTR_ID(49), + TRANSCEIVER_PRESENT_ATTR_ID(50), + TRANSCEIVER_PRESENT_ATTR_ID(51), + TRANSCEIVER_PRESENT_ATTR_ID(52), + TRANSCEIVER_PRESENT_ATTR_ID(53), + TRANSCEIVER_PRESENT_ATTR_ID(54), + TRANSCEIVER_TXDISABLE_ATTR_ID(49), + TRANSCEIVER_TXDISABLE_ATTR_ID(50), + TRANSCEIVER_TXDISABLE_ATTR_ID(51), + TRANSCEIVER_TXDISABLE_ATTR_ID(52), + FAN_PRESENT_ATTR_ID(1), + FAN_PRESENT_ATTR_ID(2), + FAN_PRESENT_ATTR_ID(3), + FAN_SPEED_RPM_ATTR_ID(1), + FAN_SPEED_RPM_ATTR_ID(2), + FAN_SPEED_RPM_ATTR_ID(3), + FAN_DIRECTION_ID(1), + FAN_DIRECTION_ID(2), + FAN_DIRECTION_ID(3), + FAN_FAULT_ATTR_ID(1), + FAN_FAULT_ATTR_ID(2), + FAN_FAULT_ATTR_ID(3), + FAN_DUTY_CYCLE_PERCENTAGE, +}; + +/* sysfs attributes for hwmon + */ +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t show_version(struct device *dev, struct device_attribute *da, + char *buf); +static int as4630_54pe_cpld_read_internal(struct i2c_client *client, u8 reg); +static int as4630_54pe_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value); + +/*fan sysfs*/ +static struct as4630_54pe_cpld_data *as4630_54pe_fan_update_device(struct device *dev); +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t get_sys_temp(struct device *dev, struct device_attribute *da, char *buf); +//static ssize_t show_power(struct device *dev, struct device_attribute *da, + // char *buf); + + + +/* transceiver attributes */ +#define DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, show_status, NULL, MODULE_PRESENT_##index); \ + static SENSOR_DEVICE_ATTR(module_tx_disable_##index, S_IRUGO | S_IWUSR, show_status, set_tx_disable, MODULE_TXDISABLE_##index); \ + static SENSOR_DEVICE_ATTR(module_rx_los_##index, S_IRUGO, show_status, NULL, MODULE_RXLOS_##index); \ + static SENSOR_DEVICE_ATTR(module_tx_fault_##index, S_IRUGO, show_status, NULL, MODULE_TXFAULT_##index); + +#define DECLARE_SFP_TRANSCEIVER_ATTR(index) \ + &sensor_dev_attr_module_present_##index.dev_attr.attr, \ + &sensor_dev_attr_module_tx_disable_##index.dev_attr.attr, \ + &sensor_dev_attr_module_rx_los_##index.dev_attr.attr, \ + &sensor_dev_attr_module_tx_fault_##index.dev_attr.attr + +#define DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, show_status, NULL, MODULE_PRESENT_##index); + +#define DECLARE_QSFP_TRANSCEIVER_ATTR(index) \ + &sensor_dev_attr_module_present_##index.dev_attr.attr + + +#define DECLARE_FAN_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan_present_##index, S_IRUGO, fan_show_value, NULL, FAN_PRESENT_##index); \ + static SENSOR_DEVICE_ATTR(fan_fault_##index, S_IRUGO, fan_show_value, NULL, FAN_FAULT_##index); \ + static SENSOR_DEVICE_ATTR(fan_speed_rpm_##index, S_IRUGO, fan_show_value, NULL, FAN_SPEED_RPM_##index); \ + static SENSOR_DEVICE_ATTR(fan##index##_input, S_IRUGO, fan_show_value, NULL, FAN_SPEED_RPM_##index);\ + static SENSOR_DEVICE_ATTR(fan_direction_##index, S_IRUGO, fan_show_value, NULL, FAN_DIRECTION_##index); + +#define DECLARE_FAN_ATTR(index) \ + &sensor_dev_attr_fan_present_##index.dev_attr.attr, \ + &sensor_dev_attr_fan_fault_##index.dev_attr.attr, \ + &sensor_dev_attr_fan_speed_rpm_##index.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_input.dev_attr.attr, \ + &sensor_dev_attr_fan_direction_##index.dev_attr.attr + +#define DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN_DUTY_CYCLE_PERCENTAGE); +#define DECLARE_FAN_DUTY_CYCLE_ATTR(index) &sensor_dev_attr_fan_duty_cycle_percentage.dev_attr.attr + +#define DECLARE_FAN_SYSTEM_TEMP_SENSOR_DEV_ATTR() \ + static SENSOR_DEVICE_ATTR(sys_temp, S_IRUGO, get_sys_temp, NULL, FAN_DUTY_CYCLE_PERCENTAGE) + +#define DECLARE_FAN_SYSTEM_TEMP_ATTR() &sensor_dev_attr_sys_temp.dev_attr.attr + +static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION); +static SENSOR_DEVICE_ATTR(access, S_IWUSR, NULL, access, ACCESS); + + + +/* transceiver attributes */ +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(49); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(50); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(51); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(52); +DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(53); +DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(54); +/* fan attributes */ +DECLARE_FAN_SENSOR_DEV_ATTR(1); +DECLARE_FAN_SENSOR_DEV_ATTR(2); +DECLARE_FAN_SENSOR_DEV_ATTR(3); +DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(1); + +static struct attribute *as4630_54pe_cpld_attributes[] = { + &sensor_dev_attr_version.dev_attr.attr, + &sensor_dev_attr_access.dev_attr.attr, + DECLARE_SFP_TRANSCEIVER_ATTR(49), + DECLARE_SFP_TRANSCEIVER_ATTR(50), + DECLARE_SFP_TRANSCEIVER_ATTR(51), + DECLARE_SFP_TRANSCEIVER_ATTR(52), + DECLARE_QSFP_TRANSCEIVER_ATTR(53), + DECLARE_QSFP_TRANSCEIVER_ATTR(54), + DECLARE_FAN_ATTR(1), + DECLARE_FAN_ATTR(2), + DECLARE_FAN_ATTR(3), + DECLARE_FAN_DUTY_CYCLE_ATTR(1), + NULL +}; + +static const struct attribute_group as4630_54pe_cpld_group = { + .attrs = as4630_54pe_cpld_attributes, +}; + + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as4630_54pe_cpld_data *data = i2c_get_clientdata(client); + int status = 0; + u8 reg = 0, mask = 0, revert = 0; + + switch (attr->index) + { + case MODULE_RXLOS_49 ... MODULE_RXLOS_50: + reg=0x5; + mask = 0x1<< (attr->index==MODULE_RXLOS_49?4:0); + break; + case MODULE_TXFAULT_49 ... MODULE_TXFAULT_50: + reg=0x5; + mask=0x1 << (attr->index==MODULE_TXFAULT_49?5:1); + break; + case MODULE_PRESENT_49 ... MODULE_PRESENT_50: + reg=0x5; + mask=0x1 << (attr->index==MODULE_PRESENT_49?6:2); + break; + case MODULE_TXDISABLE_49 ... MODULE_TXDISABLE_50: + reg=0x5; + mask=0x1 << (attr->index==MODULE_TXFAULT_49?7:3); + break; + + case MODULE_RXLOS_51 ... MODULE_RXLOS_52: + reg=0x6; + mask = 0x1<< (attr->index==MODULE_RXLOS_51?4:0); + break; + case MODULE_TXFAULT_51 ... MODULE_TXFAULT_52: + reg=0x6; + mask=0x1 << (attr->index==MODULE_TXFAULT_51?5:1); + break; + case MODULE_PRESENT_51 ... MODULE_PRESENT_52: + reg=0x6; + mask=0x1 << (attr->index==MODULE_PRESENT_51?6:2); + break; + case MODULE_TXDISABLE_51 ... MODULE_TXDISABLE_52: + reg=0x6; + mask=0x1 << (attr->index==MODULE_TXFAULT_51?7:3); + break; + case MODULE_PRESENT_53 ... MODULE_PRESENT_54: + reg=0x21; + mask=0x1 << (attr->index==MODULE_PRESENT_53?0:4); + break; + default: + return 0; + } + + if( attr->index >= MODULE_PRESENT_49 && attr->index <= MODULE_PRESENT_54 ) + { + revert = 1; + } + + mutex_lock(&data->update_lock); + status = as4630_54pe_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", revert ? !(status & mask) : !!(status & mask)); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as4630_54pe_cpld_data *data = i2c_get_clientdata(client); + long disable; + int status; + u8 reg = 0, mask = 0; + + status = kstrtol(buf, 10, &disable); + if (status) { + return status; + } + reg = 0x9; + switch (attr->index) + { + case MODULE_TXDISABLE_49 ... MODULE_TXDISABLE_50: + reg=0x5; + mask=0x1 << (attr->index==MODULE_TXFAULT_49?7:3); + break; + case MODULE_TXDISABLE_51 ... MODULE_TXDISABLE_52: + reg=0x6; + mask=0x1 << (attr->index==MODULE_TXFAULT_51?7:3); + break; + + default: + return 0; + } + + /* Read current status */ + mutex_lock(&data->update_lock); + status = as4630_54pe_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + /* Update tx_disable status */ + if (disable) { + status &= ~mask; + } + else { + status |= mask; + } + status = as4630_54pe_cpld_write_internal(client, reg, status); + if (unlikely(status < 0)) { + goto exit; + } + + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int status; + u32 addr, val; + struct i2c_client *client = to_i2c_client(dev); + struct as4630_54pe_cpld_data *data = i2c_get_clientdata(client); + + if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) { + return -EINVAL; + } + + if (addr > 0xFF || val > 0xFF) { + return -EINVAL; + } + + mutex_lock(&data->update_lock); + status = as4630_54pe_cpld_write_internal(client, addr, val); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static void as4630_54pe_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +static void as4630_54pe_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + + mutex_unlock(&list_lock); +} + +static ssize_t show_version(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0; + struct i2c_client *client = to_i2c_client(dev); + + val = i2c_smbus_read_byte_data(client, 0x1); + + if (val < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x1) err %d\n", client->addr, val); + } + + return sprintf(buf, "%d\n", val); +} + +/* fan utility functions + */ +static u32 reg_val_to_duty_cycle(u8 reg_val) +{ + reg_val &= FAN_DUTY_CYCLE_REG_MASK; + return ((u32)(reg_val) * 625)/ 100; +} + +static u8 duty_cycle_to_reg_val(u8 duty_cycle) +{ + return ((u32)duty_cycle * 100 / 625); +} + +static u32 reg_val_to_speed_rpm(u8 reg_val) +{ + return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP; +} + +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value; + struct i2c_client *client = to_i2c_client(dev); + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value < 0 || value > FAN_MAX_DUTY_CYCLE) + return -EINVAL; + + as4630_54pe_cpld_write_internal(client, fan_reg[1], duty_cycle_to_reg_val(value)); + as4630_54pe_cpld_write_internal(client, fan_reg[2], duty_cycle_to_reg_val(value)); + return count; +} + +static u8 reg_val_to_direction(u8 reg_val, enum fan_id id) +{ + u8 mask = (1 << id); + + reg_val &= mask; + + return reg_val ? 1 : 0; +} + +static u8 reg_val_to_is_present(u8 reg_val, enum fan_id id) +{ + u8 mask = (1 << id); + + reg_val &= mask; + + return reg_val ? 0 : 1; +} + +static u8 is_fan_fault(struct as4630_54pe_cpld_data *data, enum fan_id id) +{ + u8 ret = 1; + + if(id > FAN3_ID) + return 1; + /* Check if the speed of front or rear fan is ZERO, + */ + if (reg_val_to_speed_rpm(data->reg_fan_val[id+3])) + { + + ret = 0; + } + + return ret; +} + +/* Due to this struct is declared at lm75.c, it cannot be include + * under Sonic environment. I duplicate it from lm75.c. + */ +struct lm75_data { + struct i2c_client *client; + struct device *hwmon_dev; + struct thermal_zone_device *tz; + struct mutex update_lock; + u8 orig_conf; + u8 resolution; /* In bits, between 9 and 12 */ + u8 resolution_limits; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + unsigned long sample_time; /* In jiffies */ + s16 temp[3]; /* Register values, + 0 = input + 1 = max + 2 = hyst */ +}; + +/*Copied from lm75.c*/ +static inline long lm75_reg_to_mc(s16 temp, u8 resolution) +{ + return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); +} + +/*Get hwmon_dev from i2c_client, set hwmon_dev = NULL is failed.*/ +static struct device * get_hwmon_dev( + struct i2c_client *client) +{ + struct lm75_data *data = NULL; + + data = i2c_get_clientdata(client); + if(data) + { + if( data->valid == 1 && data->hwmon_dev) + { + return data->hwmon_dev; + } + + } + return NULL; +} + +/* To find hwmon index by opening hwmon under that i2c address. + */ +static int find_hwmon_index_by_FileOpen( + int bus_nr, + unsigned short addr, + int *index) +{ +#define MAX_HWMON_DEVICE (10) /* Find hwmon device in 0~10*/ + struct file *sfd; + char client_name[96]; + int i=0; + + do { + snprintf(client_name, sizeof(client_name), + "/sys/bus/i2c/devices/%d-%04x/hwmon/hwmon%d/temp1_input", + bus_nr, addr, i); + + sfd = filp_open(client_name, O_RDONLY, 0); + i++; + } while( IS_ERR(sfd) && i < MAX_HWMON_DEVICE); + + if (IS_ERR(sfd)) { + pr_err("Failed to open file(%s)#%d\r\n", client_name, __LINE__); + return -ENOENT; + } + filp_close(sfd, 0); + *index = i - 1; + return 0; + +#undef MAX_HWMON_DEVICE +} + +static int get_temp_file_path( + int bus_nr, unsigned short addr, + struct device *hwmon_dev + ,char *path, int max_len) +{ + + if(hwmon_dev && strlen(dev_name(hwmon_dev))) + { + snprintf(path, max_len, + "/sys/bus/i2c/devices/%d-%04x/hwmon/%s/temp1_input", + bus_nr, addr, dev_name(hwmon_dev)); + } + else + { + int i=0; + if(find_hwmon_index_by_FileOpen( bus_nr, addr, &i)) + { + return -EIO; + } + snprintf(path, max_len, + "/sys/bus/i2c/devices/%d-%04x/hwmon/hwmon%d/temp1_input", + bus_nr, addr, i); + } + + return 0; +} + +/*File read the dev file at user space.*/ +static int read_devfile_temp1_input( + struct device *dev, + int bus_nr, + unsigned short addr, + struct device *hwmon_dev, + int *miniCelsius) +{ + struct file *sfd; + char buffer[96]; + char devfile[96]; + int rc, status; + int rdlen, value; + mm_segment_t old_fs; + + rc = 0; + get_temp_file_path(bus_nr, addr, hwmon_dev, devfile, sizeof(devfile)); + sfd = filp_open(devfile, O_RDONLY, 0); + if (IS_ERR(sfd)) { + pr_err("Failed to open file(%s)#%d\r\n", devfile, __LINE__); + return -ENOENT; + } + dev_dbg(dev, "Found device:%s\n",devfile); + + if(!(sfd->f_op) || !(sfd->f_op->read) ) { + pr_err("file %s cann't readable ?\n",devfile); + return -ENOENT; + } + + old_fs = get_fs(); + set_fs(KERNEL_DS); + rdlen = sfd->f_op->read(sfd, buffer, sizeof(buffer), &sfd->f_pos); + if (rdlen == 0) { + pr_err( "File(%s) empty!\n", devfile); + rc = -EIO; + goto exit; + } + status = sscanf(buffer, "%d", &value); + if (status != 1) { + rc = -EIO; + goto exit; + } + *miniCelsius = value; + dev_dbg(dev,"found sensors: %d @i2c %d-%04x\n", value, bus_nr, addr); + +exit: + set_fs(old_fs); + filp_close(sfd, 0); + return rc; +} + +static u8 is_lm75_data_due(struct i2c_client *client) +{ + struct lm75_data *data = NULL; + + data = i2c_get_clientdata(client); + if (time_after(jiffies, data->last_updated + data->sample_time)) + { + return 1; + } + return 0; +} +static int get_lm75_temp(struct i2c_client *client, int *miniCelsius) +{ + struct lm75_data *data = NULL; + + data = i2c_get_clientdata(client); + *miniCelsius = lm75_reg_to_mc(data->temp[0], data->resolution); + + return 0; +} + +static bool lm75_addr_mached(unsigned short addr) +{ + int i; + unsigned short addrs[] = THERMAL_SENSORS_ADDRS; + + for (i = 0; i < ARRAY_SIZE(addrs); i++) + { + if( addr == addrs[i]) + return 1; + } + return 0; +} + +static int _find_lm75_device(struct device *dev, void *data) +{ + struct device_driver *driver; + struct as4630_54pe_cpld_data *prv = data; + char *driver_name = THERMAL_SENSORS_DRIVER; + + driver = dev->driver; + if (driver && driver->name && + strcmp(driver->name, driver_name) == 0) + { + struct i2c_client *client; + client = to_i2c_client(dev); + if (client) + { + /*cannot use "struct i2c_adapter *adap = to_i2c_adapter(dev);"*/ + struct i2c_adapter *adap = client->adapter; + int miniCelsius = 0; + + if (! lm75_addr_mached(client->addr)) + { + return 0; + } + + if (!adap) { + return -ENXIO; + } + + /* If the data is not updated, read them from devfile + to drive them updateing data from chip.*/ + if (is_lm75_data_due(client)) + { + struct device *hwmon_dev; + + hwmon_dev = get_hwmon_dev(client); + if(0 == read_devfile_temp1_input(dev, adap->nr, + client->addr, hwmon_dev, &miniCelsius)) + { + prv->system_temp += miniCelsius; + prv->sensors_found++; + } + + } + else + { + get_lm75_temp(client, &miniCelsius); + prv->system_temp += miniCelsius; + prv->sensors_found++; + + } + } + } + return 0; +} + +/*Find all lm75 devices and return sum of temperatures.*/ +static ssize_t get_sys_temp(struct device *dev, struct device_attribute *da, + char *buf) +{ + ssize_t ret = 0; + struct as4630_54pe_cpld_data *data = as4630_54pe_fan_update_device(dev); + + data->system_temp=0; + data->sensors_found=0; + i2c_for_each_dev(data, _find_lm75_device); + if (NUM_THERMAL_SENSORS != data->sensors_found) + { + dev_dbg(dev,"only %d of %d temps are found\n", + data->sensors_found, NUM_THERMAL_SENSORS); + data->system_temp = INT_MAX; + } + ret = sprintf(buf, "%d\n",data->system_temp); + return ret; +} + +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, + char *buf) +{ + u32 duty_cycle; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as4630_54pe_cpld_data *data = as4630_54pe_fan_update_device(dev); + ssize_t ret = 0; + + if (data->valid) { + switch (attr->index) + { + case FAN_PRESENT_1: + case FAN_PRESENT_2: + case FAN_PRESENT_3: + ret = sprintf(buf, "%d\n", + reg_val_to_is_present(data->reg_fan_val[0], + attr->index - FAN_PRESENT_1)); + break; + case FAN_DUTY_CYCLE_PERCENTAGE: + duty_cycle = reg_val_to_duty_cycle(data->reg_fan_val[1]); + ret = sprintf(buf, "%u\n", duty_cycle); + break; + case FAN_SPEED_RPM_1: + case FAN_SPEED_RPM_2: + case FAN_SPEED_RPM_3: + ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_fan_val[attr->index-FAN_SPEED_RPM_1+3])); + break; + case FAN_FAULT_1: + case FAN_FAULT_2: + case FAN_FAULT_3: + ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN_FAULT_1)); + break; + case FAN_DIRECTION_1: + case FAN_DIRECTION_2: + case FAN_DIRECTION_3: + ret = sprintf(buf, "%d\n", + reg_val_to_direction(data->reg_fan_val[0], + attr->index - FAN_DIRECTION_1)); + break; + default: + break; + } + } + + return ret; +} + +static struct as4630_54pe_cpld_data *as4630_54pe_fan_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as4630_54pe_cpld_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || + !data->valid) { + int i; + + dev_dbg(&client->dev, "Starting as4630_54pe_fan update\n"); + data->valid = 0; + + /* Update fan data + */ + for (i = 0; i < ARRAY_SIZE(data->reg_fan_val); i++) { + int status = as4630_54pe_cpld_read_internal(client, fan_reg[i]); + if (status < 0) { + data->valid = 0; + mutex_unlock(&data->update_lock); + dev_dbg(&client->dev, "reg 0x%x, err %d\n", fan_reg[i], status); + return data; + } + else { + data->reg_fan_val[i] = status & 0xff; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +/* +static ssize_t show_power(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as4630_54pe_cpld_data *data = i2c_get_clientdata(client); + int status = 0; + u8 reg = 0, mask = 0; + + reg=0xc; + mask=0x2; + mutex_lock(&data->update_lock); + status = as4630_54pe_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", !(status & mask)); + +exit: + mutex_unlock(&data->update_lock); + return status; +} +*/ +/* + * I2C init/probing/exit functions + */ +static int as4630_54pe_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); + struct as4630_54pe_cpld_data *data; + int ret = -ENODEV; +// int status; + const struct attribute_group *group = NULL; + + if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) + goto exit; + + data = kzalloc(sizeof(struct as4630_54pe_cpld_data), GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->type = id->driver_data; + + /* Register sysfs hooks */ + switch (data->type) + { + case as4630_54pe_cpld: + group = &as4630_54pe_cpld_group; + break; + default: + break; + } + + if (group) + { + ret = sysfs_create_group(&client->dev.kobj, group); + if (ret) { + goto exit_free; + } + } + + as4630_54pe_cpld_add_client(client); + + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + ret = PTR_ERR(data->hwmon_dev); + goto exit_free; + } + + + return 0; + +exit_free: + kfree(data); +exit: + return ret; +} + +static int as4630_54pe_cpld_remove(struct i2c_client *client) +{ + struct as4630_54pe_cpld_data *data = i2c_get_clientdata(client); + const struct attribute_group *group = NULL; + + as4630_54pe_cpld_remove_client(client); + + /* Remove sysfs hooks */ + switch (data->type) + { + case as4630_54pe_cpld: + group = &as4630_54pe_cpld_group; + break; + default: + break; + } + + if (group) { + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, group); + } + + + kfree(data); + + return 0; +} + +static int as4630_54pe_cpld_read_internal(struct i2c_client *client, u8 reg) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, reg); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + +static int as4630_54pe_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, reg, value); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + +int as4630_54pe_cpld_read(unsigned short cpld_addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EPERM; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = as4630_54pe_cpld_read_internal(cpld_node->client, reg); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(as4630_54pe_cpld_read); + +int as4630_54pe_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EIO; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = as4630_54pe_cpld_write_internal(cpld_node->client, reg, value); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(as4630_54pe_cpld_write); + +static struct i2c_driver as4630_54pe_cpld_driver = { + .driver = { + .name = "as4630_54pe_cpld", + .owner = THIS_MODULE, + }, + .probe = as4630_54pe_cpld_probe, + .remove = as4630_54pe_cpld_remove, + .id_table = as4630_54pe_cpld_id, +}; + +static int __init as4630_54pe_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&as4630_54pe_cpld_driver); +} + +static void __exit as4630_54pe_cpld_exit(void) +{ + i2c_del_driver(&as4630_54pe_cpld_driver); +} + +MODULE_AUTHOR("Jostar Yang "); +MODULE_DESCRIPTION("Accton I2C CPLD driver"); +MODULE_LICENSE("GPL"); + +module_init(as4630_54pe_cpld_init); +module_exit(as4630_54pe_cpld_exit); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-leds.c b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-leds.c new file mode 100755 index 000000000000..34c22fd82aa1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-leds.c @@ -0,0 +1,579 @@ +/* + * A LED driver for the accton_as4630_54pe_led + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*#define DEBUG*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern int as4630_54pe_cpld_read (unsigned short cpld_addr, u8 reg); +extern int as4630_54pe_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +#define DRVNAME "accton_as4630_54pe_led" + +struct accton_as4630_54pe_led_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[2]; /* only 1 register*/ +}; + +static struct accton_as4630_54pe_led_data *ledctl = NULL; + +/* LED related data + */ + +#define LED_CNTRLER_I2C_ADDRESS (0x60) + +#define LED_TYPE_DIAG_REG_MASK (0x20|0x40|0x80) +#define LED_MODE_DIAG_GREEN_VALUE (0x20) +#define LED_MODE_DIAG_GREEN_BLINK_VALUE (0x60) +#define LED_MODE_DIAG_AMBER_VALUE (0x80) /*It's yellow actually. Green+Red=Yellow*/ +#define LED_MODE_DIAG_OFF_VALUE (0x0) + +#define LED_TYPE_PRI_REG_MASK (0x8|0x4) +#define LED_MODE_PRI_GREEN_VALUE 0x4 +#define LED_MODE_PRI_AMBER_VALUE 0x8 +#define LED_MODE_PRI_OFF_VALUE 0x0 + +#define LED_TYPE_POE_REG_MASK (0x2|0x1) +#define LED_MODE_POE_GREEN_VALUE 0x1 +#define LED_MODE_POE_AMBER_VALUE 0x2 +#define LED_MODE_POE_OFF_VALUE 0x0 + +#define LED_TYPE_STK1_REG_MASK 0x20 +#define LED_MODE_STK1_GREEN_VALUE 0x0 +#define LED_MODE_STK1_OFF_VALUE 0x20 + +#define LED_TYPE_STK2_REG_MASK 0x10 +#define LED_MODE_STK2_GREEN_VALUE 0x0 +#define LED_MODE_STK2_OFF_VALUE 0x10 + +#define LED_TYPE_FAN_REG_MASK (0x20|0x10) +#define LED_MODE_FAN_AMBER_VALUE 0x20 +#define LED_MODE_FAN_GREEN_VALUE 0x10 +#define LED_MODE_FAN_OFF_VALUE (0x0) + +#define LED_TYPE_PSU2_REG_MASK (0x8|0x4) +#define LED_MODE_PSU2_AMBER_VALUE 0x8 +#define LED_MODE_PSU2_GREEN_VALUE 0x4 +#define LED_MODE_PSU2_OFF_VALUE (0x0) + +#define LED_TYPE_PSU1_REG_MASK (0x2|0x1) +#define LED_MODE_PSU1_AMBER_VALUE 0x2 +#define LED_MODE_PSU1_GREEN_VALUE 0x1 +#define LED_MODE_PSU1_OFF_VALUE (0x0) + +enum led_type { + LED_TYPE_DIAG, + LED_TYPE_PRI, + LED_TYPE_POE, + LED_TYPE_STK1, + LED_TYPE_STK2, + LED_TYPE_FAN, + LED_TYPE_PSU1, + LED_TYPE_PSU2 +}; + +struct led_reg { + u32 types; + u8 reg_addr; +}; + +static const struct led_reg led_reg_map[] = { + {(1<update_lock); + + if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2) + || !ledctl->valid) { + int i; + + dev_dbg(&ledctl->pdev->dev, "Starting accton_as4630_54pe_led update\n"); + + /* Update LED data + */ + for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) { + int status = accton_as4630_54pe_led_read_value(led_reg_map[i].reg_addr); + + if (status < 0) { + ledctl->valid = 0; + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg_map[i].reg_addr, status); + goto exit; + } + else + { + ledctl->reg_val[i] = status; + } + } + + ledctl->last_updated = jiffies; + ledctl->valid = 1; + } + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void accton_as4630_54pe_led_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode, + enum led_type type) +{ + int reg_val; + u8 reg ; + mutex_lock(&ledctl->update_lock); + + if( !accton_getLedReg(type, ®)) + { + dev_dbg(&ledctl->pdev->dev, "Not match item for %d.\n", type); + } + + + reg_val = accton_as4630_54pe_led_read_value(reg); + if (reg_val < 0) { + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val); + goto exit; + } + reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val); + + accton_as4630_54pe_led_write_value(reg, reg_val); + + /* to prevent the slow-update issue */ + ledctl->valid = 0; + +exit: + mutex_unlock(&ledctl->update_lock); +} + + +static void accton_as4630_54pe_led_diag_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as4630_54pe_led_set(led_cdev, led_light_mode, LED_TYPE_DIAG); +} + +static enum led_brightness accton_as4630_54pe_led_diag_get(struct led_classdev *cdev) +{ + accton_as4630_54pe_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_DIAG, ledctl->reg_val[0]); +} + +static void accton_as4630_54pe_led_pri_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as4630_54pe_led_set(led_cdev, led_light_mode, LED_TYPE_PRI); +} + +static enum led_brightness accton_as4630_54pe_led_pri_get(struct led_classdev *cdev) +{ + accton_as4630_54pe_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PRI, ledctl->reg_val[0]); +} + +static void accton_as4630_54pe_led_poe_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as4630_54pe_led_set(led_cdev, led_light_mode, LED_TYPE_POE); +} + +static enum led_brightness accton_as4630_54pe_led_poe_get(struct led_classdev *cdev) +{ + accton_as4630_54pe_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_POE, ledctl->reg_val[1]); +} + + +static void accton_as4630_54pe_led_stk1_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as4630_54pe_led_set(led_cdev, led_light_mode, LED_TYPE_STK1); +} + +static enum led_brightness accton_as4630_54pe_led_stk1_get(struct led_classdev *cdev) +{ + accton_as4630_54pe_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_STK1, ledctl->reg_val[1]); +} + +static void accton_as4630_54pe_led_stk2_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as4630_54pe_led_set(led_cdev, led_light_mode, LED_TYPE_STK2); +} + +static enum led_brightness accton_as4630_54pe_led_stk2_get(struct led_classdev *cdev) +{ + accton_as4630_54pe_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_STK2, ledctl->reg_val[1]); +} + +static void accton_as4630_54pe_led_fan_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as4630_54pe_led_set(led_cdev, led_light_mode, LED_TYPE_FAN); +} + +static enum led_brightness accton_as4630_54pe_led_fan_get(struct led_classdev *cdev) +{ + accton_as4630_54pe_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_FAN, ledctl->reg_val[0]); +} + +static void accton_as4630_54pe_led_psu1_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as4630_54pe_led_set(led_cdev, led_light_mode, LED_TYPE_PSU1); +} + +static enum led_brightness accton_as4630_54pe_led_psu1_get(struct led_classdev *cdev) +{ + accton_as4630_54pe_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU1, ledctl->reg_val[0]); +} + +static void accton_as4630_54pe_led_psu2_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as4630_54pe_led_set(led_cdev, led_light_mode, LED_TYPE_PSU2); +} + +static enum led_brightness accton_as4630_54pe_led_psu2_get(struct led_classdev *cdev) +{ + accton_as4630_54pe_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU2, ledctl->reg_val[0]); +} + +static struct led_classdev accton_as4630_54pe_leds[] = { + [LED_TYPE_DIAG] = { + .name = "diag", + .default_trigger = "unused", + .brightness_set = accton_as4630_54pe_led_diag_set, + .brightness_get = accton_as4630_54pe_led_diag_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_GREEN, + }, + [LED_TYPE_PRI] = { + .name = "pri", + .default_trigger = "unused", + .brightness_set = accton_as4630_54pe_led_pri_set, + .brightness_get = accton_as4630_54pe_led_pri_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AMBER, + }, + [LED_TYPE_POE] = { + .name = "poe", + .default_trigger = "unused", + .brightness_set = accton_as4630_54pe_led_poe_set, + .brightness_get = accton_as4630_54pe_led_poe_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AMBER, + }, + [LED_TYPE_STK1] = { + .name = "stk1", + .default_trigger = "unused", + .brightness_set = accton_as4630_54pe_led_stk1_set, + .brightness_get = accton_as4630_54pe_led_stk1_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_GREEN, + }, + [LED_TYPE_STK2] = { + .name = "stk2", + .default_trigger = "unused", + .brightness_set = accton_as4630_54pe_led_stk2_set, + .brightness_get = accton_as4630_54pe_led_stk2_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_GREEN, + }, + [LED_TYPE_FAN] = { + .name = "fan", + .default_trigger = "unused", + .brightness_set = accton_as4630_54pe_led_fan_set, + .brightness_get = accton_as4630_54pe_led_fan_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU1] = { + .name = "psu1", + .default_trigger = "unused", + .brightness_set = accton_as4630_54pe_led_psu1_set, + .brightness_get = accton_as4630_54pe_led_psu1_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU2] = { + .name = "psu2", + .default_trigger = "unused", + .brightness_set = accton_as4630_54pe_led_psu2_set, + .brightness_get = accton_as4630_54pe_led_psu2_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, +}; + +static int accton_as4630_54pe_led_suspend(struct platform_device *dev, + pm_message_t state) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(accton_as4630_54pe_leds); i++) { + led_classdev_suspend(&accton_as4630_54pe_leds[i]); + } + + return 0; +} + +static int accton_as4630_54pe_led_resume(struct platform_device *dev) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(accton_as4630_54pe_leds); i++) { + led_classdev_resume(&accton_as4630_54pe_leds[i]); + } + + return 0; +} + +static int accton_as4630_54pe_led_probe(struct platform_device *pdev) +{ + int ret, i; + + for (i = 0; i < ARRAY_SIZE(accton_as4630_54pe_leds); i++) { + ret = led_classdev_register(&pdev->dev, &accton_as4630_54pe_leds[i]); + + if (ret < 0) + break; + } + + /* Check if all LEDs were successfully registered */ + if (i != ARRAY_SIZE(accton_as4630_54pe_leds)) { + int j; + + /* only unregister the LEDs that were successfully registered */ + for (j = 0; j < i; j++) { + led_classdev_unregister(&accton_as4630_54pe_leds[i]); + } + } + + return ret; +} + +static int accton_as4630_54pe_led_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(accton_as4630_54pe_leds); i++) { + led_classdev_unregister(&accton_as4630_54pe_leds[i]); + } + + return 0; +} + +static struct platform_driver accton_as4630_54pe_led_driver = { + .probe = accton_as4630_54pe_led_probe, + .remove = accton_as4630_54pe_led_remove, + .suspend = accton_as4630_54pe_led_suspend, + .resume = accton_as4630_54pe_led_resume, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int __init accton_as4630_54pe_led_init(void) +{ + int ret; + + ret = platform_driver_register(&accton_as4630_54pe_led_driver); + if (ret < 0) { + goto exit; + } + + ledctl = kzalloc(sizeof(struct accton_as4630_54pe_led_data), GFP_KERNEL); + if (!ledctl) { + ret = -ENOMEM; + platform_driver_unregister(&accton_as4630_54pe_led_driver); + goto exit; + } + + mutex_init(&ledctl->update_lock); + + ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(ledctl->pdev)) { + ret = PTR_ERR(ledctl->pdev); + platform_driver_unregister(&accton_as4630_54pe_led_driver); + kfree(ledctl); + goto exit; + } + +exit: + return ret; +} + +static void __exit accton_as4630_54pe_led_exit(void) +{ + platform_device_unregister(ledctl->pdev); + platform_driver_unregister(&accton_as4630_54pe_led_driver); + kfree(ledctl); +} + +module_init(accton_as4630_54pe_led_init); +module_exit(accton_as4630_54pe_led_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton_as4630_54pe_led driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-psu.c b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-psu.c new file mode 100755 index 000000000000..798a5656410e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-psu.c @@ -0,0 +1,320 @@ +/* + * An hwmon driver for accton as4630_54pe Power Module + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_MODEL_NAME 20 +#define MAX_SERIAL_NUMBER 18 + +static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_string(struct device *dev, struct device_attribute *da, char *buf); +static int as4630_54pe_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len); +extern int as4630_54pe_cpld_read(unsigned short cpld_addr, u8 reg); + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { 0x50, 0x51, I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct as4630_54pe_psu_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 index; /* PSU index */ + u8 status; /* Status(present/power_good) register read from CPLD */ + char model_name[MAX_MODEL_NAME]; /* Model name, read from eeprom */ + char serial_number[MAX_SERIAL_NUMBER]; +}; + +static struct as4630_54pe_psu_data *as4630_54pe_psu_update_device(struct device *dev); + +enum as4630_54pe_psu_sysfs_attributes { + PSU_PRESENT, + PSU_MODEL_NAME, + PSU_POWER_GOOD, + PSU_SERIAL_NUMBER +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_string, NULL, PSU_MODEL_NAME); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD); +static SENSOR_DEVICE_ATTR(psu_serial_number, S_IRUGO, show_string, NULL, PSU_SERIAL_NUMBER); + + +static struct attribute *as4630_54pe_psu_attributes[] = { + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_model_name.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + &sensor_dev_attr_psu_serial_number.dev_attr.attr, + NULL +}; + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as4630_54pe_psu_data *data = as4630_54pe_psu_update_device(dev); + u8 status = 0; + + //printk("data->status=0x%x, attr->index=%d,data->index=%d \n", data->status, attr->index, data->index); + if (attr->index == PSU_PRESENT) { + if(data->index==0) + status = !( (data->status >> 5) & 0x1); + else + status = !( (data->status >> 1) & 0x1); + } + else { /* PSU_POWER_GOOD */ + if(data->index==0) + status = ( (data->status >> 6) & 0x1); + else + status = ( (data->status >> 2) & 0x1); + } + + return sprintf(buf, "%d\n", status); +} + +static ssize_t show_string(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as4630_54pe_psu_data *data = as4630_54pe_psu_update_device(dev); + char *ptr = NULL; + + if (!data->valid) { + return -EIO; + } + + switch (attr->index) { + case PSU_MODEL_NAME: + ptr = data->model_name; + break; + case PSU_SERIAL_NUMBER: + ptr = data->serial_number; + break; + default: + return -EINVAL; + } + + return sprintf(buf, "%s\n", ptr); +} + +static const struct attribute_group as4630_54pe_psu_group = { + .attrs = as4630_54pe_psu_attributes, +}; + +static int as4630_54pe_psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as4630_54pe_psu_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as4630_54pe_psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + data->index = dev_id->driver_data; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as4630_54pe_psu_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as4630_54pe_psu_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as4630_54pe_psu_remove(struct i2c_client *client) +{ + struct as4630_54pe_psu_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as4630_54pe_psu_group); + kfree(data); + + return 0; +} + +enum psu_index +{ + as4630_54pe_psu1, + as4630_54pe_psu2 +}; + +static const struct i2c_device_id as4630_54pe_psu_id[] = { + { "as4630_54pe_psu1", as4630_54pe_psu1 }, + { "as4630_54pe_psu2", as4630_54pe_psu2 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as4630_54pe_psu_id); + +static struct i2c_driver as4630_54pe_psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as4630_54pe_psu", + }, + .probe = as4630_54pe_psu_probe, + .remove = as4630_54pe_psu_remove, + .id_table = as4630_54pe_psu_id, + .address_list = normal_i2c, +}; + +static int as4630_54pe_psu_read_block(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int result = 0; + int retry_count = 5; + + while (retry_count) { + retry_count--; + + result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + + if (unlikely(result < 0)) { + msleep(10); + continue; + } + + if (unlikely(result != data_len)) { + result = -EIO; + msleep(10); + continue; + } + + result = 0; + break; + } + + return result; +} + +static struct as4630_54pe_psu_data *as4630_54pe_psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as4630_54pe_psu_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int status; + int power_good = 0; + + dev_dbg(&client->dev, "Starting as4630_54pe update\n"); + + /* Read psu status */ + status = as4630_54pe_cpld_read(0x60, 0x22); + //printk("status=0x%x in %s\n", status, __FUNCTION__); + if (status < 0) { + dev_dbg(&client->dev, "cpld reg 0x60 err %d\n", status); + } + else { + data->status = status; + } + + /* Read model name */ + memset(data->model_name, 0, sizeof(data->model_name)); + memset(data->serial_number, 0, sizeof(data->serial_number)); + power_good = (data->status >> (3-data->index) & 0x1); + + if (power_good) { + status = as4630_54pe_psu_read_block(client, 0x20, data->model_name, + ARRAY_SIZE(data->model_name)-1); + if (status < 0) { + data->model_name[0] = '\0'; + dev_dbg(&client->dev, "unable to read model name from (0x%x)\n", client->addr); + printk("unable to read model name from (0x%x)\n", client->addr); + } + else { + data->model_name[ARRAY_SIZE(data->model_name)-1] = '\0'; + + } + /* Read from offset 0x2e ~ 0x3d (16 bytes) */ + status = as4630_54pe_psu_read_block(client, 0x35,data->serial_number, MAX_SERIAL_NUMBER); + if (status < 0) + { + data->serial_number[0] = '\0'; + dev_dbg(&client->dev, "unable to read model name from (0x%x) offset(0x2e)\n", client->addr); + printk("unable to read model name from (0x%x) offset(0x2e)\n", client->addr); + } + data->serial_number[MAX_SERIAL_NUMBER-1]='\0'; + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +module_i2c_driver(as4630_54pe_psu_driver); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as4630_54pe_psu driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/ym2651y.c new file mode 120000 index 000000000000..f4d67640ccc3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/ym2651y.c @@ -0,0 +1 @@ +../../common/modules/ym2651y.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor-fan.service b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor-fan.service new file mode 100755 index 000000000000..9f562d2a05e1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor-fan.service @@ -0,0 +1,16 @@ +[Unit] +Description=Accton AS4630-54PE Platform Monitoring FAN service +Before=pmon.service +After=as4630-54pe-platform-monitor.service +DefaultDependencies=no + +[Service] +ExecStart=/usr/local/bin/accton_as4630_54pe_monitor_fan.py +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor-psu.service b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor-psu.service new file mode 100755 index 000000000000..28d6013aa19d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor-psu.service @@ -0,0 +1,16 @@ +[Unit] +Description=Accton AS4630-54PE Platform Monitoring PSU service +Before=pmon.service +After=as4630-54pe-platform-monitor.service +DefaultDependencies=no + +[Service] +ExecStart=/usr/local/bin/accton_as4630_54pe_monitor_psu.py +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor.service b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor.service new file mode 100755 index 000000000000..47bf4e81d82e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/service/as4630-54pe-platform-monitor.service @@ -0,0 +1,18 @@ +[Unit] +Description=Accton AS4630-54PE Platform Monitoring service +Before=pmon.service +After=sysinit.target +DefaultDependencies=no + +[Service] +ExecStartPre=/usr/local/bin/accton_as4630_54pe_util.py install +ExecStart=/usr/local/bin/accton_as4630_54pe_monitor.py +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL +#StandardOutput=tty + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/setup.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/setup.py new file mode 100755 index 000000000000..34e6bb59de52 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/setup.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='as4630_54pe', + version='1.0', + description='Module to initialize Accton AS4630-54PE platforms', + + packages=['as4630_54pe'], + package_dir={'as4630_54pe': 'as4630-54pe/classes'}, +) + diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/README b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/README new file mode 100755 index 000000000000..44e03cab5f52 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/README @@ -0,0 +1,117 @@ +Copyright (C) 2016 Accton Networks, Inc. + +This program is free software: you can redistribute it and/or modify +It under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +Contents of this package: + patch - files under patch/ is for kernel and ONIE installer + for the kernel: + config-accton-as5712_54x.patch + for kernel configuration. + driver-i2c-muxes-pca954x-always-deselect.patch + for i2c_mux deselects after transaction. + driver-patches-for-accton-as5712-fan-psu-cpld.patch + for as5712's fan/psu/cpld/led/sfp drivers. + for ONIE: + onie_installer-accton-AS5712-54X.patch + for console port setting and copy util script o rootfs. + module - Contains source code of as5712 kernel driver modules. + +The late Sonic building scripts, pushed @Dec 5 2016, will automatically +create a docker container and run building process under it. +User is not necessary to handle docker environment creation. + +1. Download sonic-buildimage environment. + - Run "git clone https://github.com/Azure/sonic-buildimage". + - cd to sonic-buildimage and run "git submodule update --init --recursive". +2. Build kernel + - cd ./src/sonic-linux-kernel + - Copy patches and series from patch/kernel of this release to + sonic-linux-kernel/patch. + - Build kernel by "make". + - The built kernel package, linux-image-3.16.0-5-amd64_3.16.51-3+deb8u1_amd64.deb + , is generated. +3. Build installer + - Change directory back to sonic-buildimage/. + - Get onie_installer-accton-AS5712-54X.patch" from patch/installer. + - Change setting for AS5712-54X by patching build_image.sh. + "patch -p1 < onie_installer-accton-AS5712-54X.patch" + !!NOTICE, patching onie_installer-accton-AS5712-54X.patch comments out the + "git status" checking at build_image.sh. + - The account and password of installed OS can be given at rules/config. + The default user and password are "admin" & "YourPaSsWoRd" respectively. + - Run "make configure PLATFORM=broadcom" + - Copy the built kernel debian package to target/debs/. + The file is linux-image-3.16.0-5-amd64_*_amd64.deb under directory + src/sonic-linux-kernel/. + - Run "make target/sonic-generic.bin" + - Get the installer, target/sonic-generic.bin, to target machine and install. + +All Linux kernel code is licensed under the GPLv1. All other code is +licensed under the GPLv3. Please see the LICENSE file for copies of +both licenses. + +The code for integacting with Accton AS5712-54X has 2 parts, +kernel drivers and operational script. +The kernel drivers of peripherals are under module/ directory. +1. These drivers are patched into kernel by + driver-patches-for-accton-as5712-fan-psu-cpld.patch + Or you can build the driver under module/ by setting environment variable, + KERNEL_SRC, to proper linux built directory and run make. + It may be sonic-linux-kernel/linux-3.*/debian/build/build_amd64_none_amd64/. +2. A operational script, accton_as5712_util.py, for device initializatian and + peripheral accessing should be installed at /usr/bin. + This script is generated by onie_installer-accton-AS5712-54X.patch. + It's done by patching onie_installer-accton-AS5712-54X.patch at build-image. + Run "accton_as5712_util.py install" to install drivers. + +To initialize the system, run "accton_as5712_util.py install". +To clean up the drivers & devices, run "accton_as5712_util.py clean". +To dump information of sensors, run "accton_as5712_util.py show". +To dump SFP EEPROM, run "accton_as5712_util.py sff". +To set fan speed, run "accton_as5712_util.py set fan". +To enable/disable SFP emission, run "accton_as5712_util.py set sfp". +To set system LEDs' color, run "accton_as5712_util.py set led" +For more information, run "accton_as5712_util.py --help". + +==================================================================== +Besides applying accton_as5712_util.py to access peripherals, you can +access peripherals by sysfs nodes directly after the installation is run. + +System LED: + There are 5 system LEDs at the lower-left corner of front panel. + They are loc, diag, fan, ps1, and ps2. + The sysfs interface color mappings are as follows: + Brightness: + 0 => off + 1 => green + 2 => amber + 3 => red + 4 => blue + But not all colors are available for each LED. + +Fan Control: + There are 10 fans inside 5 fan modules. + All fans share 1 duty setting, ranged from 0~100. + +Thermal sensers: + 3 temperature sensors are controlled by the lm75 kernel modules. + +PSUs: + There 2 power supplies slot at the left/right side of the back. + Once if a PSU is not plugged, the status of it is shown failed. + +There are 48 SFP+ and 6 QSFP modules are equipped. +Before operating on PSU and QSFP+, please make sure it is well plugged. +Otherwise, operation is going to fail. + diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor.py new file mode 100755 index 000000000000..eca1eac6b216 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor.py @@ -0,0 +1,345 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.)# +# 4/20/2018: Jostar modify for as7726_32x +# 12/03/2018:Jostar modify for as7726_32x thermal plan +# ------------------------------------------------------------------ + +try: + import os + import sys, getopt + import subprocess + import click + import imp + import logging + import logging.config + import logging.handlers + import types + import time # this is only being used as part of the example + import traceback + from tabulate import tabulate + from as7726_32x.fanutil import FanUtil + from as7726_32x.thermalutil import ThermalUtil +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + +# Deafults +VERSION = '1.0' +FUNCTION_NAME = '/usr/local/bin/accton_as4630_54pe_monitor' + +global log_file +global log_level + + +# Air Flow Front to Back : +# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 <=38C : Keep 37.5%(0x04) Fan speed +# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 38C : Change Fan speed from 37.5%(0x04) to 62.5%(0x08) +# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 46C : Change Fan speed from 62.5%(0x08) to 100%(0x0E) +# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 58C : Send alarm message +# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 66C : Shut down system +# One Fan fail : Change Fan speed to 100%(0x0E) + + +# Air Flow Back to Front : +# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 <=34C : Keep 37.5%(0x04) Fan speed +# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 34C : Change Fan speed from 37.5%(0x04) to 62.5%(0x08) +# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 44C : Change Fan speed from 62.5%(0x08) to 100%(0x0E) +# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 59C : Send alarm message +# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 67C : Shut down system +# One Fan fail: Change Fan speed to 100%(0x0E) +# sensor_LM75_CPU == sensor_LM75_4B + + +class switch(object): + def __init__(self, value): + self.value = value + self.fall = False + + def __iter__(self): + """Return the match method once, then stop""" + yield self.match + raise StopIteration + + def match(self, *args): + """Indicate whether or not to enter a case suite""" + if self.fall or not args: + return True + elif self.value in args: # changed for v1.5, see below + self.fall = True + return True + else: + return False + + +fan_policy_state=1 +fan_fail=0 +alarm_state = 0 #0->default or clear, 1-->alarm detect +test_temp = 0 +test_temp_list = [0, 0, 0, 0, 0, 0] +temp_test_data=0 +# Make a class we can use to capture stdout and sterr in the log +class device_monitor(object): + # static temp var + temp = 0 + new_pwm = 0 + pwm=0 + ori_pwm = 0 + default_pwm=0x4 + + def __init__(self, log_file, log_level): + """Needs a logger and a logger level.""" + # set up logging to file + logging.basicConfig( + filename=log_file, + filemode='w', + level=log_level, + format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', + datefmt='%H:%M:%S' + ) + # set up logging to console + if log_level == logging.DEBUG: + console = logging.StreamHandler() + console.setLevel(log_level) + formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) + + sys_handler = handler = logging.handlers.SysLogHandler(address = '/dev/log') + sys_handler.setLevel(logging.WARNING) + logging.getLogger('').addHandler(sys_handler) + + #logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level) + + def get_state_from_fan_policy(self, temp, policy): + state=0 + + logging.debug('temp=%d', temp) + for i in range(0, len(policy)): + #logging.debug('policy[%d][0]=%d, policy[%d][1]=%d, policy[%d][2]=%d', i,policy[i][0],i, policy[i][1], i, policy[i][2]) + if temp > policy[i][2]: + if temp <= policy[i][3]: + state =i + logging.debug ('temp=%d >= policy[%d][2]=%d, temp=%d < policy[%d][3]=%d' , temp, i, policy[i][2], temp, i, policy[i][3]) + logging.debug ('fan_state=%d', state) + break + + return state + + + def manage_fans(self): + + global fan_policy_state + global fan_fail + global test_temp + global test_temp_list + global alarm_state + global temp_test_data + + LEVEL_FAN_DEF=0 + LEVEL_FAN_MID=1 + LEVEL_FAN_MAX=2 + LEVEL_TEMP_HIGH=3 + LEVEL_TEMP_CRITICAL=4 + + + fan_policy_f2b = { + LEVEL_FAN_DEF: [38, 0x4, 0, 38000], + LEVEL_FAN_MID: [63, 0x6, 38000, 46000], + LEVEL_FAN_MAX: [100, 0xE, 46000, 58000], + LEVEL_TEMP_HIGH: [100, 0xE, 58000, 66000], + LEVEL_TEMP_CRITICAL: [100, 0xE, 58000, 200000], + } + fan_policy_b2f = { + LEVEL_FAN_DEF: [38, 0x4, 0, 34000], + LEVEL_FAN_MID: [63, 0x8, 34000, 44000], + LEVEL_FAN_MAX: [100, 0xE, 44000, 59000], + LEVEL_TEMP_HIGH: [100, 0xE, 59000, 67000], + LEVEL_TEMP_CRITICAL: [100, 0xE, 59000, 200000], + } + + fan_policy = fan_policy_f2b + + thermal = ThermalUtil() + fan = FanUtil() + fan_dir=fan.get_fan_dir(1) + if fan_dir == 1: + fan_dri=1 #something wrong, set fan_dir to default val + else: + fan_policy = fan_policy_b2f + + ori_pwm=fan.get_fan_duty_cycle() + new_pwm=0 + logging.debug('fan_dir=%d, ori_pwm=%d', fan_dir, ori_pwm) + logging.debug('test_temp=%d', test_temp) + if test_temp==0: + temp1 = thermal._get_thermal_val(1) + temp2 = thermal._get_thermal_val(2) + temp3 = thermal._get_thermal_val(3) + temp4 = thermal._get_thermal_val(4) + temp5 = thermal._get_thermal_val(5) + else: + temp1 = test_temp_list[0] + temp2 = test_temp_list[1] + temp3 = test_temp_list[2] + temp4 = test_temp_list[3] + temp5 = test_temp_list[4] + fan_fail=0 + + if temp3==0: + temp_get=50000 # if one detect sensor is fail or zero, assign temp=50000, let fan to 75% + logging.debug('lm75_49 detect fail, so set temp_get=50000, let fan to 75%') + elif temp4==0: + temp_get=50000 # if one detect sensor is fail or zero, assign temp=50000, let fan to 75% + logging.debug('lm75_4b detect fail, so set temp_get=50000, let fan to 75%') + else: + temp_get= (temp3 + temp4)/2 # Use (sensor_LM75_4a + sensor_LM75_4b) /2 + ori_state=fan_policy_state + + #temp_test_data=temp_test_data+1000 + #temp_get = temp_get + temp_test_data + #print "Unit test:temp_get=%d"%temp_get + + fan_policy_state=self.get_state_from_fan_policy(temp_get, fan_policy) + #print "temp3=%d"%temp3 + #print "temp4=%d"%temp4 + #print "temp_get=%d"%temp_get + + logging.debug('lm75_48=%d, lm75_49=%d, lm75_4a=%d, lm_4b=%d, lm_4b=%d', temp1,temp2,temp3,temp4,temp5) + logging.debug('ori_state=%d, fan_policy_state=%d', ori_state, fan_policy_state) + new_pwm = fan_policy[fan_policy_state][0] + if fan_fail==0: + logging.debug('new_fan_cycle=%d', new_pwm) + + if fan_fail==0: + if new_pwm!=ori_pwm: + fan.set_fan_duty_cycle(new_pwm) + logging.info('Set fan speed from %d to %d', ori_pwm, new_pwm) + + #Check Fan status + for i in range (fan.FAN_NUM_1_IDX, fan.FAN_NUM_ON_MAIN_BROAD+1): + if fan.get_fan_status(i)==0: + new_pwm=100 + logging.debug('fan_%d fail, set pwm to 100',i) + if test_temp==0: + fan_fail=1 + fan.set_fan_duty_cycle(new_pwm) + break + else: + fan_fail=0 + + #if fan_policy_state == ori_state: + # return True + #else: + new_state = fan_policy_state + + #logging.warning('Temperature high alarm testing') + if ori_state==LEVEL_FAN_DEF: + if new_state==LEVEL_TEMP_HIGH: + if alarm_state==0: + logging.warning('Alarm for temperature high is detected') + alarm_state=1 + if new_state==LEVEL_TEMP_CRITICAL: + logging.critical('Alarm for temperature critical is detected, reboot DUT') + time.sleep(2) + os.system('reboot') + if ori_state==LEVEL_FAN_MID: + if new_state==LEVEL_TEMP_HIGH: + if alarm_state==0: + logging.warning('Alarm for temperature high is detected') + alarm_state=1 + if new_state==LEVEL_TEMP_CRITICAL: + logging.critical('Alarm for temperature critical is detected') + time.sleep(2) + os.system('reboot') + if ori_state==LEVEL_FAN_MAX: + if new_state==LEVEL_TEMP_HIGH: + if alarm_state==0: + logging.warning('Alarm for temperature high is detected') + alarm_state=1 + if new_state==LEVEL_TEMP_CRITICAL: + logging.critical('Alarm for temperature critical is detected') + time.sleep(2) + os.system('reboot') + if alarm_state==1: + if temp_get < (fan_policy[3][0] - 5000): #below 65 C, clear alarm + logging.warning('Alarm for temperature high is cleared') + alarm_state=0 + if ori_state==LEVEL_TEMP_HIGH: + if new_state==LEVEL_TEMP_CRITICAL: + logging.critical('Alarm for temperature critical is detected') + time.sleep(2) + os.system('reboot') + if new_state <= LEVEL_FAN_MID: + logging.warning('Alarm for temperature high is cleared') + alarm_state=0 + if new_state <= LEVEL_FAN_MAX: + if temp_get < (fan_policy[3][0] - 5000): #below 65 C, clear alarm + logging.warning('Alarm for temperature high is cleared') + alarm_state=0 + if ori_state==LEVEL_TEMP_CRITICAL: + if new_state <= LEVEL_FAN_MAX: + logging.warning('Alarm for temperature critical is cleared') + + return True + +def main(argv): + log_file = '%s.log' % FUNCTION_NAME + log_level = logging.INFO + global test_temp + if len(sys.argv) != 1: + try: + opts, args = getopt.getopt(argv,'hdlt:',['lfile=']) + except getopt.GetoptError: + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + for opt, arg in opts: + if opt == '-h': + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + elif opt in ('-d', '--debug'): + log_level = logging.DEBUG + elif opt in ('-l', '--lfile'): + log_file = arg + + if sys.argv[1]== '-t': + if len(sys.argv)!=7: + print "temp test, need input six temp" + return 0 + + i=0 + for x in range(2, 7): + test_temp_list[i]= int(sys.argv[x])*1000 + i=i+1 + test_temp = 1 + log_level = logging.DEBUG + print test_temp_list + + fan = FanUtil() + fan.set_fan_duty_cycle(38) + print "set default fan speed to 37.5%" + monitor = device_monitor(log_file, log_level) + # Loop forever, doing something useful hopefully: + while True: + #monitor.manage_fans() + time.sleep(5) + +if __name__ == '__main__': + main(sys.argv[1:]) + diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_fan.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_fan.py new file mode 100755 index 000000000000..11453818b04c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_fan.py @@ -0,0 +1,191 @@ +#!/usr/bin/env python +# +# Copyright (C) 2018 Accton Technology Corporation +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 5/15/2019: Jostar create for as4630-54pe +# ------------------------------------------------------------------ + +try: + import os + import sys, getopt + import subprocess + import click + import imp + import logging + import logging.config + import logging.handlers + import types + import time # this is only being used as part of the example + import traceback + from tabulate import tabulate + +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + +# Deafults +VERSION = '1.0' +FUNCTION_NAME = '/usr/local/bin/accton_as4630_54pe_monitor_fan' + +global log_file +global log_level + + +class switch(object): + def __init__(self, value): + self.value = value + self.fall = False + + def __iter__(self): + """Return the match method once, then stop""" + yield self.match + raise StopIteration + + def match(self, *args): + """Indicate whether or not to enter a case suite""" + if self.fall or not args: + return True + elif self.value in args: # changed for v1.5, see below + self.fall = True + return True + else: + return False + + +fan_state=[2, 2, 2, 2] #init state=2, insert=1, remove=0 +fan_status_state=[2, 2, 2, 2] #init state=2, fault=1, normal=0 +# Make a class we can use to capture stdout and sterr in the log +class device_monitor(object): + + def __init__(self, log_file, log_level): + + self.fan_num = 3 + self.fan_path = "/sys/bus/i2c/devices/3-0060/" + self.present = { + 0: "fan_present_1", + 1: "fan_present_2", + 2: "fan_present_3", + } + + self.fault = { + 0: "fan_fault_1", + 1: "fan_fault_2", + 2: "fan_fault_3", + } + + + """Needs a logger and a logger level.""" + # set up logging to file + logging.basicConfig( + filename=log_file, + filemode='w', + level=log_level, + format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', + datefmt='%H:%M:%S' + ) + + # set up logging to console + if log_level == logging.DEBUG: + console = logging.StreamHandler() + console.setLevel(logging.DEBUG) + formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) + + sys_handler = logging.handlers.SysLogHandler(address = '/dev/log') + #sys_handler.setLevel(logging.WARNING) + sys_handler.setLevel(logging.INFO) + logging.getLogger('').addHandler(sys_handler) + + + #logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level) + + def manage_fan(self): + + FAN_STATE_REMOVE = 0 + FAN_STATE_INSERT = 1 + + FAN_STATUS_FAULT = 1 + FAN_STATUS_NORMAL = 0 + + global fan_state + global fan_status_state + + for idx in range (0, self.fan_num): + node = self.fan_path + self.present[idx] + try: + val_file = open(node) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + content = val_file.readline().rstrip() + val_file.close() + # content is a string, either "0" or "1" + if content == "1": + if fan_state[idx]!=1: + fan_state[idx]=FAN_STATE_INSERT + logging.info("FAN-%d present is detected", idx+1); + else: + if fan_state[idx]!=0: + fan_state[idx]=FAN_STATE_REMOVE + logging.warning("Alarm for FAN-%d absent is detected", idx+1) + + for idx in range (0, self.fan_num): + node = self.fan_path + self.fault[idx] + try: + val_file = open(node) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + content = val_file.readline().rstrip() + val_file.close() + # content is a string, either "0" or "1" + if content == "1": + if fan_status_state[idx]!=FAN_STATUS_FAULT: + if fan_state[idx] == FAN_STATE_INSERT: + logging.warning("Alarm for FAN-%d failed is detected", idx+1); + fan_status_state[idx]=FAN_STATUS_FAULT + else: + fan_status_state[idx]=FAN_STATUS_NORMAL + + return True + +def main(argv): + log_file = '%s.log' % FUNCTION_NAME + log_level = logging.INFO + if len(sys.argv) != 1: + try: + opts, args = getopt.getopt(argv,'hdl:',['lfile=']) + except getopt.GetoptError: + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + for opt, arg in opts: + if opt == '-h': + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + elif opt in ('-d', '--debug'): + log_level = logging.DEBUG + elif opt in ('-l', '--lfile'): + log_file = arg + monitor = device_monitor(log_file, log_level) + while True: + monitor.manage_fan() + time.sleep(3) + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_psu.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_psu.py new file mode 100755 index 000000000000..8ef700f33ca0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_monitor_psu.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python +# +# Copyright (C) 2018 Accton Technology Corporation +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 5/15/2019: Jostar create for as4630-54pe +# ------------------------------------------------------------------ + +try: + import os + import sys, getopt + import subprocess + import click + import imp + import logging + import logging.config + import logging.handlers + import types + import time # this is only being used as part of the example + import traceback + from tabulate import tabulate +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + +# Deafults +VERSION = '1.0' +FUNCTION_NAME = '/usr/local/bin/accton_as4630_54pe_monitor_psu' + +global log_file +global log_level + + +psu_state=[2, 2] +psu_status_state=[2, 2] +# Make a class we can use to capture stdout and sterr in the log +class device_monitor(object): + + def __init__(self, log_file, log_level): + + self.psu_num = 2 + self.psu_path = "/sys/bus/i2c/devices/" + self.presence = "/psu_present" + self.oper_status = "/psu_power_good" + self.mapping = { + 0: "10-0050", + 1: "11-0051", + } + + """Needs a logger and a logger level.""" + # set up logging to file + logging.basicConfig( + filename=log_file, + filemode='w', + level=log_level, + format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', + datefmt='%H:%M:%S' + ) + # set up logging to console + + if log_level == logging.DEBUG: + console = logging.StreamHandler() + console.setLevel(log_level) + formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) + + sys_handler = logging.handlers.SysLogHandler(address = '/dev/log') + #sys_handler.setLevel(logging.WARNING) + sys_handler.setLevel(logging.INFO) + logging.getLogger('').addHandler(sys_handler) + + #logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level) + + def manage_psu(self): + + PSU_STATE_REMOVE = 0 + PSU_STATE_INSERT = 1 + + PSU_STATUS_NO_POWER = 0 + PSU_STATUS_POWER_GOOD = 1 + PSU_STATUS_IDLE =2 + + global psu_state + + for idx in range (0, self.psu_num): + node = self.psu_path + self.mapping[idx] + self.presence + try: + val_file = open(node) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + content = val_file.readline().rstrip() + val_file.close() + # content is a string, either "0" or "1" + if content == "1": + if psu_state[idx]!=1: + psu_state[idx]=PSU_STATE_INSERT + logging.info("PSU-%d present is detected", idx+1); + #psu_status_state[idx]=PSU_STATUS_POWER_GOOD #when insert, assume power is good. If no_power, next code will find it. + else: + if psu_state[idx]!=0: + psu_state[idx]=PSU_STATE_REMOVE + logging.warning("Alarm for PSU-%d absent is detected", idx+1); + psu_status_state[idx]=PSU_STATUS_IDLE + + for idx in range (0, self.psu_num): + node = self.psu_path + self.mapping[idx] + self.oper_status + try: + val_file = open(node) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + content = val_file.readline().rstrip() + val_file.close() + # content is a string, either "0" or "1" + if content == "0": + if psu_status_state[idx]!=PSU_STATUS_NO_POWER: + if psu_state[idx]==PSU_STATE_INSERT: + logging.warning("Alarm for PSU-%d failed is detected", idx+1); + psu_status_state[idx]=PSU_STATUS_NO_POWER + else: + if psu_state[idx]==PSU_STATE_INSERT: + if psu_status_state[idx]!=PSU_STATUS_POWER_GOOD: + logging.info("PSU-%d power_good is detected", idx+1); + psu_status_state[idx]=PSU_STATUS_POWER_GOOD + + + return True + +def main(argv): + log_file = '%s.log' % FUNCTION_NAME + log_level = logging.INFO + if len(sys.argv) != 1: + try: + opts, args = getopt.getopt(argv,'hdl:',['lfile=']) + except getopt.GetoptError: + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + for opt, arg in opts: + if opt == '-h': + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + elif opt in ('-d', '--debug'): + log_level = logging.DEBUG + elif opt in ('-l', '--lfile'): + log_file = arg + monitor = device_monitor(log_file, log_level) + # Loop forever, doing something useful hopefully: + while True: + monitor.manage_psu() + time.sleep(3) + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py new file mode 100755 index 000000000000..2f73726f846d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py @@ -0,0 +1,563 @@ +#!/usr/bin/env python +# +# Copyright (C) 2016 Accton Networks, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +from collections import namedtuple + +PROJECT_NAME = 'as4630_54pe' +version = '0.0.1' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +DEVICE_NO = {'led':5, 'fan1':1, 'fan2':1,'fan3':1,'fan4':1,'fan5':1,'thermal':3, 'psu':2, 'sfp':54} + + +led_prefix ='/sys/devices/platform/as4630_54pe_led/leds/accton_'+PROJECT_NAME+'_led::' +fan_prefix ='/sys/devices/platform/as4630_54pe_' +hwmon_types = {'led': ['diag','fan','loc','psu1','psu2'], + 'fan1': ['fan'], + 'fan2': ['fan'], + 'fan3': ['fan'], + 'fan4': ['fan'], + 'fan5': ['fan'], + 'fan5': ['fan'], + } +hwmon_nodes = {'led': ['brightness'] , + 'fan1': ['fan_duty_cycle_percentage', 'fan1_fault', 'fan1_speed_rpm', 'fan1_direction', 'fanr1_fault', 'fanr1_speed_rpm'], + 'fan2': ['fan_duty_cycle_percentage','fan2_fault', 'fan2_speed_rpm', 'fan2_direction', 'fanr2_fault', 'fanr2_speed_rpm'], + 'fan3': ['fan_duty_cycle_percentage','fan3_fault', 'fan3_speed_rpm', 'fan3_direction', 'fanr3_fault', 'fanr3_speed_rpm'], + 'fan4': ['fan4_duty_cycle_percentage','fan4_fault', 'fan4_speed_rpm', 'fan4_direction', 'fanr4_fault', 'fanr4_speed_rpm'], + 'fan5': ['fan_duty_cycle_percentage','fan5_fault', 'fan5_speed_rpm', 'fan5_direction', 'fanr5_fault', 'fanr5_speed_rpm'], + } +hwmon_prefix ={'led': led_prefix, + 'fan1': fan_prefix, + 'fan2': fan_prefix, + 'fan3': fan_prefix, + 'fan4': fan_prefix, + 'fan5': fan_prefix, + } + +i2c_prefix = '/sys/bus/i2c/devices/' +i2c_bus = {'fan': ['54-0066'], + 'thermal': ['54-004c', '55-0048','55-0049', '55-004a', '55-004b'] , + 'psu': ['49-0050','50-0053'], + 'sfp': ['-0050']} +i2c_nodes = {'fan': ['present', 'front_speed_rpm', 'rear_speed_rpm'], + 'thermal': ['hwmon/hwmon*/temp1_input'] , + 'psu': ['psu_present ', 'psu_power_good'] , + 'sfp': ['module_present_ ', 'module_tx_disable_']} + +sfp_map = [18, 19, 20, 21, 22, 23] + +mknod =[ +'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-2/new_device', +'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-3/new_device', + +'echo as4630_54pe_cpld 0x60 > /sys/bus/i2c/devices/i2c-3/new_device', + +'echo lm77 0x48 > /sys/bus/i2c/devices/i2c-14/new_device', +'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-25/new_device', +'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-24/new_device', + + +# PSU-1 +'echo as4630_54pe_psu1 0x50 > /sys/bus/i2c/devices/i2c-10/new_device', +'echo ype1200am 0x58 > /sys/bus/i2c/devices/i2c-10/new_device', + +# PSU-2 +'echo as4630_54pe_psu2 0x51> /sys/bus/i2c/devices/i2c-11/new_device', +'echo ype1200am 0x59 > /sys/bus/i2c/devices/i2c-11/new_device', + +#EERPOM +'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device', +] + + + +FORCE = 0 +logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) +logging.basicConfig(level=logging.INFO) + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + print "TEST" + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + device_traversal() + elif arg == 'sff': + if len(args)!=2: + show_eeprom_help() + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + show_eeprom_help() + else: + show_eeprom(args[1]) + return + elif arg == 'set': + if len(args)<3: + show_set_help() + else: + set_device(args[1:]) + return + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_set_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print cmd +" [led|sfp|fan]" + print " use \""+ cmd + " led 0-4 \" to set led color" + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-32 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + +def show_eeprom_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print " use \""+ cmd + " 1-32 \" to dump sfp# eeprom" + sys.exit(0) + +def my_log(txt): + if DEBUG == True: + print "[ACCTON DBG]: "+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status = 1 + output = "" + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log ("cmd:" + cmd) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_inserted(): + ret, lsmod = log_os_system("lsmod| grep accton", 0) + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + +#'modprobe cpr_4011_4mxx', + +kos = [ +'depmod -ae', +'modprobe i2c_dev', +'modprobe i2c_mux_pca954x force_deselect_on_exit=1', +'modprobe ym2651y', +'modprobe x86_64_accton_as4630_54pe_cpld', +'modprobe x86_64_accton_as4630_54pe_leds', +'modprobe x86_64_accton_as4630_54pe_psu', +'modprobe optoe'] + +def driver_install(): + global FORCE + + ret=log_os_system("lsmod|grep i2c_ismt",1) + my_log("rmmond i2cismt") + log_os_system("rmmod i2c_ismt", 1) + log_os_system("rmmod i2c_i801", 1) + log_os_system("modprobe i2c-i801", 1) + time.sleep(1) + log_os_system("modprobe i2c-ismt", 1) + + + + for i in range(0,len(kos)): + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + + return 0 + +def driver_uninstall(): + global FORCE + for i in range(0,len(kos)): + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + lst = rm.split(" ") + print "lst=%s"%lst + if len(lst) > 3: + del(lst[3]) + rm = " ".join(lst) + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + +def device_install(): + global FORCE + + for i in range(0,len(mknod)): + #for pca954x need times to built new i2c buses + if mknod[i].find('pca954') != -1: + time.sleep(2) + + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + print("Check SFP") + for i in range(0,len(sfp_map)): + if(i < 4): + opt='optoe2' + else: + opt='optoe1' + status, output =log_os_system("echo " + str(opt) + " 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + + status, output =log_os_system("echo port"+str(i+49) + " > /sys/bus/i2c/devices/"+str(sfp_map[i])+"-0050/port_name", 1) + if status: + print output + if FORCE == 0: + return status + + return + +def device_uninstall(): + global FORCE + + status, output =log_os_system("ls /sys/bus/i2c/devices/0-0070", 0) + if status==0: + I2C_ORDER=1 + else: + I2C_ORDER=0 + + for i in range(0,len(sfp_map)): + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" + status, output =log_os_system("echo 0x50 > "+ target, 1) + if status: + print output + if FORCE == 0: + return status + + nodelist = mknod + + for i in range(len(nodelist)): + target = nodelist[-(i+1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + if status: + print output + if FORCE == 0: + return status + + return + +def system_ready(): + if driver_inserted() == False: + return False + if not device_exist(): + print "not device_exist()" + return False + return True + +def do_install(): + if driver_inserted() == False: + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" drivers detected...." + if not device_exist(): + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" devices detected...." + return + +def do_uninstall(): + if not device_exist(): + print PROJECT_NAME.upper() +" has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_inserted()== False : + print PROJECT_NAME.upper() +" has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + +def devices_info(): + global DEVICE_NO + global ALL_DEVICE + global i2c_bus, hwmon_types + for key in DEVICE_NO: + ALL_DEVICE[key]= {} + for i in range(0,DEVICE_NO[key]): + ALL_DEVICE[key][key+str(i+1)] = [] + + for key in i2c_bus: + buses = i2c_bus[key] + nodes = i2c_nodes[key] + for i in range(0,len(buses)): + for j in range(0,len(nodes)): + if 'fan' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + elif 'sfp' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + else: + node = key+str(i+1) + path = i2c_prefix+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + + for key in hwmon_types: + itypes = hwmon_types[key] + nodes = hwmon_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + #show dict all in the order + if DEBUG == True: + for i in sorted(ALL_DEVICE.keys()): + print(i+": ") + for j in sorted(ALL_DEVICE[i].keys()): + print(" "+j) + for k in (ALL_DEVICE[i][j]): + print(" "+" "+k) + return + +def show_eeprom(index): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] + node = node.replace(node.split("/")[-1], 'eeprom') + # check if got hexdump command in current environment + ret, log = log_os_system("which hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) + if len(log): + hex_cmd = 'hexdump' + elif len(log2): + hex_cmd = ' busybox hexdump' + else: + log = 'Failed : no hexdump cmd!!' + logging.info(log) + print log + return 1 + print "node=%s"%node + print node + ":" + ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) + if ret==0: + print log + else: + print "**********device no found**********" + return + +def set_device(args): + global DEVICE_NO + global ALL_DEVICE + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + + if args[0]=='led': + if int(args[1])>4: + show_set_help() + return + #print ALL_DEVICE['led'] + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): + ret, log = log_os_system("echo "+args[1]+" >"+k, 1) + if ret: + return ret + elif args[0]=='fan': + if int(args[1])>100: + show_set_help() + return + #print ALL_DEVICE['fan'] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan1'] ['fan11'][0] + node = node.replace(node.split("/")[-1], 'fan1_duty_cycle_percentage') + ret, log = log_os_system("cat "+ node, 1) + if ret==0: + print ("Previous fan duty: " + log.strip() +"%") + ret, log = log_os_system("echo "+args[1]+" >"+node, 1) + if ret==0: + print ("Current fan duty: " + args[1] +"%") + return ret + elif args[0]=='sfp': + if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: + show_set_help() + return + if len(args)<2: + show_set_help() + return + + if int(args[2])>1: + show_set_help() + return + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: + ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) + if ret: + return ret + + return + +#get digits inside a string. +#Ex: 31 for "sfp31" +def get_value(input): + digit = re.findall('\d+', input) + return int(digit[0]) + +def device_traversal(): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + for i in sorted(ALL_DEVICE.keys()): + print("============================================") + print(i.upper()+": ") + print("============================================") + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + print " "+j+":", + for k in (ALL_DEVICE[i][j]): + ret, log = log_os_system("cat "+k, 0) + func = k.split("/")[-1].strip() + func = re.sub(j+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) + if ret==0: + print func+"="+log+" ", + else: + print func+"="+"X"+" ", + print + print("----------------------------------------------------------------") + + + print + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"*0077", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0) + return not(ret1 or ret2) + +if __name__ == "__main__": + main() diff --git a/platform/broadcom/sonic-platform-modules-accton/common/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/common/modules/ym2651y.c old mode 100644 new mode 100755 index 47e6a1d06bc5..dd4f6dd8c4db --- a/platform/broadcom/sonic-platform-modules-accton/common/modules/ym2651y.c +++ b/platform/broadcom/sonic-platform-modules-accton/common/modules/ym2651y.c @@ -42,6 +42,7 @@ enum chips { YM2651, YM2401, YM2851, + YPEB1200AM }; /* Each client has this additional data @@ -438,6 +439,7 @@ static const struct i2c_device_id ym2651y_id[] = { { "ym2651", YM2651 }, { "ym2401", YM2401 }, { "ym2851", YM2851 }, + { "ype1200am", YPEB1200AM }, {} }; MODULE_DEVICE_TABLE(i2c, ym2651y_id); diff --git a/platform/broadcom/sonic-platform-modules-accton/debian/control b/platform/broadcom/sonic-platform-modules-accton/debian/control index 731c45456894..6d65d1ecdc51 100755 --- a/platform/broadcom/sonic-platform-modules-accton/debian/control +++ b/platform/broadcom/sonic-platform-modules-accton/debian/control @@ -41,6 +41,10 @@ Package: sonic-platform-accton-as7726-32x Architecture: amd64 Description: kernel modules for platform devices such as fan, led, sfp +Package: sonic-platform-accton-as4630-54pe +Architecture: amd64 +Description: kernel modules for platform devices such as fan, led, sfp + Package: sonic-platform-accton-minipack Architecture: amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-accton/debian/rules b/platform/broadcom/sonic-platform-modules-accton/debian/rules index ef761c01aacb..33168702bd50 100755 --- a/platform/broadcom/sonic-platform-modules-accton/debian/rules +++ b/platform/broadcom/sonic-platform-modules-accton/debian/rules @@ -19,7 +19,7 @@ PACKAGE_PRE_NAME := sonic-platform-accton KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= as7712-32x as5712-54x as7816-64x as7716-32x as7716-32xb as7312-54x as7326-56x as6712-32x as7726-32x minipack +MODULE_DIRS:= as7712-32x as5712-54x as7816-64x as7716-32x as7716-32xb as7312-54x as7326-56x as6712-32x as7726-32x as4630-54pe minipack MODULE_DIR := modules UTILS_DIR := utils SERVICE_DIR := service From a5a5ba6d6a8e2abee61b7a4636194357fc8b0032 Mon Sep 17 00:00:00 2001 From: Karthik Gengan <50580882+gengankarthik@users.noreply.github.com> Date: Mon, 20 May 2019 10:35:46 +0530 Subject: [PATCH 64/88] [devices]: DellEmc-Z9264f: Bug fixed in platform specific sensor script (#2916) --- .../z9264f/scripts/platform_sensors.py | 130 +++++++++--------- 1 file changed, 68 insertions(+), 62 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/platform_sensors.py index 3e2e1657818d..77a9887f9a0a 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/platform_sensors.py @@ -3,7 +3,7 @@ # autonomous subsystem provides monitoring and management # facility independent of the host CPU. IPMI standard # protocol is used with ipmitool to fetch sensor details. -# Current script support X00 board only. X01 support will +# Current script support X00 board only. X01 support will # be added soon. This provies support for the # following objects: # * Onboard temperature sensors @@ -26,7 +26,6 @@ PSU_PRESENCE = "PSU{0}_state" # Use this for older firmware # PSU_PRESENCE="PSU{0}_prsnt" - ipmi_sdr_list = "" # Dump sensor registers @@ -53,7 +52,7 @@ def get_pmc_register(reg_name): output = item.strip() if not output: - print('\nFailed to fetch: ' + reg_name + ' sensor ') + print('\nFailed to fetch: ' + reg_name + ' sensor ') sys.exit(0) output = output.split('|')[1] @@ -83,8 +82,10 @@ def print_temperature_sensors(): (get_pmc_register('CPU_Near_temp')) print ' CPU Near Temp: ',\ (get_pmc_register('CPU_temp')) - print ' DRAM Temp: ',\ - (get_pmc_register('DRAM1_temp')) + print ' PSU FAN AirFlow Temperature 1: ',\ + (get_pmc_register('PSU1_AF_temp')) + print ' PSU FAN AirFlow Temperature 2: ',\ + (get_pmc_register('PSU2_AF_temp')) ipmi_sensor_dump() @@ -95,15 +96,23 @@ def print_temperature_sensors(): def print_fan_tray(tray): - Fan_Status = [' Normal', ' Abnormal'] + Fan_Status = [' Normal', ' Abnormal', ' no reading'] Airflow_Direction = ['B2F', 'F2B'] print ' Fan Tray ' + str(tray) + ':' if (tray == 1): - fan1_status = int(get_pmc_register('Fan1_Front_state'), 16) - fan2_status = int(get_pmc_register('Fan1_Rear_state'), 16) + if(int(get_pmc_register('FAN1_prsnt'), 16)): + fan1_status = int(get_pmc_register('Fan1_Front_state'), 16) + fan2_status = int(get_pmc_register('Fan1_Rear_state'), 16) + # BMC taking some time to update + if(fan1_status > 2 or fan2_status > 2): + fan1_status = 2 + fan2_status = 2 + else: + fan1_status = 2 + fan2_status = 2 print ' Fan1 Speed: ',\ get_pmc_register('FAN1_Front_rpm') @@ -116,8 +125,16 @@ def print_fan_tray(tray): elif (tray == 2): - fan1_status = int(get_pmc_register('Fan2_Front_state'), 16) - fan2_status = int(get_pmc_register('Fan2_Rear_state'), 16) + if(int(get_pmc_register('FAN2_prsnt'), 16)): + fan1_status = int(get_pmc_register('Fan2_Front_state'), 16) + fan2_status = int(get_pmc_register('Fan2_Rear_state'), 16) + # BMC taking some time to update + if(fan1_status > 2 or fan2_status > 2): + fan1_status = 2 + fan2_status = 2 + else: + fan1_status = 2 + fan2_status = 2 print ' Fan1 Speed: ',\ get_pmc_register('FAN2_Front_rpm') @@ -130,8 +147,16 @@ def print_fan_tray(tray): elif (tray == 3): - fan1_status = int(get_pmc_register('Fan3_Front_state'), 16) - fan2_status = int(get_pmc_register('Fan3_Rear_state'), 16) + if(int(get_pmc_register('FAN3_prsnt'), 16)): + fan1_status = int(get_pmc_register('Fan3_Front_state'), 16) + fan2_status = int(get_pmc_register('Fan3_Rear_state'), 16) + # BMC taking some time to update + if(fan1_status > 2 or fan2_status > 2): + fan1_status = 2 + fan2_status = 2 + else: + fan1_status = 2 + fan2_status = 2 print ' Fan1 Speed: ',\ get_pmc_register('FAN3_Front_rpm') @@ -144,8 +169,16 @@ def print_fan_tray(tray): elif (tray == 4): - fan1_status = int(get_pmc_register('Fan4_Front_state'), 16) - fan2_status = int(get_pmc_register('Fan4_Rear_state'), 16) + if(int(get_pmc_register('FAN4_prsnt'), 16)): + fan1_status = int(get_pmc_register('Fan4_Front_state'), 16) + fan2_status = int(get_pmc_register('Fan4_Rear_state'), 16) + # BMC taking some time to update + if(fan1_status > 2 or fan2_status > 2): + fan1_status = 2 + fan2_status = 2 + else: + fan1_status = 2 + fan2_status = 2 print ' Fan1 Speed: ',\ get_pmc_register('FAN4_Front_rpm') @@ -169,80 +202,54 @@ def print_fan_tray(tray): # Print the information for PSU1, PSU2 def print_psu(psu): - Psu_Type = ['Normal', 'Mismatch'] - Psu_Input_Type = ['AC', 'DC'] - PSU_STATUS_TYPE_BIT = 4 - PSU_STATUS_INPUT_TYPE_BIT = 1 - PSU_FAN_PRESENT_BIT = 2 - PSU_FAN_STATUS_BIT = 1 - PSU_FAN_AIR_FLOW_BIT = 0 - Psu_Fan_Presence = ['Present', 'Absent'] - Psu_Fan_Status = ['Normal', 'Abnormal'] - Psu_Fan_Airflow = ['B2F', 'F2B'] - - # print ' Input: ', Psu_Input_Type[psu_input_type] - # print ' Type: ', Psu_Type[psu_type] # PSU FAN details if (psu == 1): - # psu1_fan_status = int(get_pmc_register('PSU1_status'),16) - print ' PSU1:' - print ' FAN Normal Temperature: ',\ + print ' FAN Normal Temperature: ',\ get_pmc_register('PSU1_Normal_temp') - print ' FAN System Temperature: ',\ - get_pmc_register('PSU1_Sys_temp') - print ' FAN Chassis Temperature: ',\ + print ' Chassis Temperature: ',\ get_pmc_register('PSU1_Chass_temp') - print ' FAN AirFlow Temperature: ',\ - get_pmc_register('PSU1AF_temp') + print ' System Temperature: ',\ + get_pmc_register('PSU1_Sys_temp') print ' FAN RPM: ',\ get_pmc_register('PSU1_rpm') - # print ' FAN Status: ', Psu_Fan_Status[psu1_fan_status] - - # PSU input & output monitors - print ' Input Voltage: ',\ + print ' Input Voltage: ',\ get_pmc_register('PSU1_In_volt') - print ' Output Voltage: ',\ + print ' Output Voltage: ',\ get_pmc_register('PSU1_Out_volt') - print ' Input Power: ',\ + print ' Input Power: ',\ get_pmc_register('PSU1_In_watt') - print ' Output Power: ',\ + print ' Output Power: ',\ get_pmc_register('PSU1_Out_watt') - print ' Input Current: ',\ + print ' Input Current: ',\ get_pmc_register('PSU1_In_amp') - print ' Output Current: ',\ + print ' Output Current: ',\ get_pmc_register('PSU1_Out_amp') else: - # psu2_fan_status = int(get_pmc_register('PSU1_status'),16) print ' PSU2:' - print ' FAN Normal Temperature: ',\ + print ' FAN Normal Temperature: ',\ get_pmc_register('PSU2_Normal_temp') - print ' FAN System Temperature: ',\ - get_pmc_register('PSU2_Sys_temp') - print ' FAN Chassis Temperature: ',\ + print ' Chassis Temperature: ',\ get_pmc_register('PSU2_Chass_temp') - print ' FAN AirFlow Temperature: ',\ - get_pmc_register('PSU2AF_temp') + print ' System Temperature: ',\ + get_pmc_register('PSU2_Sys_temp') print ' FAN RPM: ',\ get_pmc_register('PSU2_rpm') - # print ' FAN Status: ', Psu_Fan_Status[psu2_fan_status] - - # PSU input & output monitors - print ' Input Voltage: ',\ + print ' Input Voltage: ',\ get_pmc_register('PSU2_In_volt') - print ' Output Voltage: ',\ + print ' Output Voltage: ',\ get_pmc_register('PSU2_Out_volt') - print ' Input Power: ',\ + print ' Input Power: ',\ get_pmc_register('PSU2_In_watt') - print ' Output Power: ',\ + print ' Output Power: ',\ get_pmc_register('PSU2_Out_watt') - print ' Input Current: ',\ + print ' Input Current: ',\ get_pmc_register('PSU2_In_amp') - print ' Output Current: ',\ + print ' Output Current: ',\ get_pmc_register('PSU2_Out_amp') @@ -254,6 +261,5 @@ def print_psu(psu): else: print '\n PSU ', psu, 'Not present' -print '\n Total Power: ',\ +print '\n Total Power: ',\ get_pmc_register('PSU_Total_watt') - From 85077a9211fb89c29226b9c47869662f2f269a2c Mon Sep 17 00:00:00 2001 From: paavaanan Date: Mon, 20 May 2019 22:05:31 +0530 Subject: [PATCH 65/88] [devices]: Export reboot_reason sysfs attribute for DellEMC S6100/Z9100 (#2922) --- .../common/dell_pmc.c | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c index 57eff4181d97..b8ed4bbb082b 100644 --- a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c +++ b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c @@ -45,6 +45,7 @@ #define SMF_READ_DATA_REG_OFFSET 2 #define SMF_REG_ADDR 0x200 #define SMF_PROBE_ADDR 0x210 +#define SMF_RST_SRC_REG 0x20A #define SIO_REG_DEVID 0x1 #define SIO_Z9100_ID 0x1 @@ -502,6 +503,23 @@ static ssize_t show_smf_version(struct device *dev, } +/* SMF Reset Reason */ +static ssize_t show_reset_reason(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + unsigned int ret = 0, val = 0; + struct smf_data *data = dev_get_drvdata(dev); + + ret = inb(SMF_RST_SRC_REG); + + if(ret < 0) + return ret; + + return sprintf(buf, "%x\n", ret); +} + + /* FANIN ATTR */ static ssize_t show_fan_label(struct device *dev, struct device_attribute *attr, char *buf) @@ -1779,10 +1797,14 @@ static SENSOR_DEVICE_ATTR(current_total_power, S_IRUGO, show_psu, NULL, 10); static SENSOR_DEVICE_ATTR(smf_version, S_IRUGO, show_smf_version, NULL, 0); static SENSOR_DEVICE_ATTR(smf_firmware_ver, S_IRUGO, show_smf_version, NULL, 1); +/* SMF Reset Reason */ +static SENSOR_DEVICE_ATTR(smf_reset_reason, S_IRUGO, show_reset_reason, NULL, 1); + static struct attribute *smf_dell_attrs[] = { &sensor_dev_attr_smf_version.dev_attr.attr, &sensor_dev_attr_smf_firmware_ver.dev_attr.attr, + &sensor_dev_attr_smf_reset_reason.dev_attr.attr, &sensor_dev_attr_fan_tray_presence.dev_attr.attr, &sensor_dev_attr_fan1_airflow.dev_attr.attr, &sensor_dev_attr_fan3_airflow.dev_attr.attr, From d2eba43b40d5ca32b8d4258cf8723389a55745e5 Mon Sep 17 00:00:00 2001 From: Shuotian Cheng Date: Mon, 20 May 2019 15:06:04 -0700 Subject: [PATCH 66/88] [docker-vs]: Connect zebra with fpm and add staticd (#2925) Since we move to FRR, we need to connect FRR with fpmsyncd via FPM. Adding static routes is also required. Signed-off-by: Shu0T1an ChenG --- platform/vs/docker-sonic-vs/supervisord.conf | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/platform/vs/docker-sonic-vs/supervisord.conf b/platform/vs/docker-sonic-vs/supervisord.conf index 250739153234..2010dc918e0a 100644 --- a/platform/vs/docker-sonic-vs/supervisord.conf +++ b/platform/vs/docker-sonic-vs/supervisord.conf @@ -100,7 +100,7 @@ stdout_logfile=syslog stderr_logfile=syslog [program:zebra] -command=/usr/lib/frr/zebra -A 127.0.0.1 +command=/usr/lib/frr/zebra -A 127.0.0.1 -s 90000000 -M fpm priority=13 autostart=false autorestart=false @@ -115,6 +115,14 @@ autorestart=false stdout_logfile=syslog stderr_logfile=syslog +[program:staticd] +command=/usr/lib/frr/staticd -A 127.0.0.1 +priority=14 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + [program:fpmsyncd] command=/usr/bin/fpmsyncd priority=15 From f8920d754521e8137de974be504885d8e3d1d6b9 Mon Sep 17 00:00:00 2001 From: Mykola F <37578614+mykolaf@users.noreply.github.com> Date: Thu, 23 May 2019 03:30:47 +0300 Subject: [PATCH 67/88] [submodule] advance sonic-sairedis pointer (#2934) Signed-off-by: Mykola Faryma --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 1b0d609c6f9a..8bf43a630f8c 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 1b0d609c6f9acd1cb868898f019eaade071c85ee +Subproject commit 8bf43a630f8c7a6d028fa1c322685d1ee2d11fb1 From 9331d21cd2e68ddbc96ca451224ad07b2d208ae4 Mon Sep 17 00:00:00 2001 From: Shuotian Cheng Date: Wed, 22 May 2019 21:32:34 -0700 Subject: [PATCH 68/88] [swss]: Update sonic-swss submodule (#2935) [vlan] Add pytest case to add max vlan. (#881) [badge]: add vs build badge (#898) Fix PFC watchdog not getting lossless TC (#876) [vstest]: skip test_AddMaxVlan as it takes almost two hours to finish (#901) [test]: Enforce fake port-channel interfaces carrier up Signed-off-by: Shu0T1an ChenG --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index ee4992665b94..f437f9fa1737 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit ee4992665b94566936340d32d8d96f8dd038ed75 +Subproject commit f437f9fa173738f9ccf1b59313cc44c3da0a0c99 From 9523e64666937d310e26bc75fddf9759fc692c0a Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Thu, 23 May 2019 08:07:29 +0300 Subject: [PATCH 69/88] [swss.sh] flush FDB table during cold start (#2933) Signed-off-by: Stepan Blyschak --- files/scripts/swss.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index 780051def9e6..5093e4c7f9fd 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -104,7 +104,7 @@ start() { /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*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*'" + clean_up_tables 6 "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" fi # start service docker From 154a88331d1cc5e7540cbeda594f90538c192b16 Mon Sep 17 00:00:00 2001 From: Karthik Gengan <50580882+gengankarthik@users.noreply.github.com> Date: Thu, 23 May 2019 10:39:53 +0530 Subject: [PATCH 70/88] [devices]: DellEmc-Z9264f:Interrupt based Optic OIR (#2926) --- .../plugins/sfputil.py | 166 +++++++++++++----- .../debian/platform-modules-z9264f.install | 1 + .../z9264f/modules/dell_z9264f_fpga_ocores.c | 111 +++++++++++- .../z9264f/scripts/qsfp_irq_enable.py | 32 ++++ .../z9264f/scripts/z9264f_platform.sh | 1 + 5 files changed, 264 insertions(+), 47 deletions(-) create mode 100755 platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/qsfp_irq_enable.py 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 192fb80f6c56..24938a122c0e 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 @@ -8,6 +8,7 @@ import sys import getopt import time + import select from sonic_sfp.sfputilbase import SfpUtilBase from os import * from mmap import * @@ -24,6 +25,10 @@ class SfpUtil(SfpUtilBase): PORTS_IN_BLOCK = 64 BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" + OIR_FD_PATH = "/sys/bus/pci/devices/0000:04:00.0/port_msi" + + oir_fd = -1 + epoll = -1 _port_to_eeprom_mapping = {} @@ -47,8 +52,8 @@ def port_to_eeprom_mapping(self): def pci_mem_read(self, mm, offset): mm.seek(offset) - read_data_stream=mm.read(4) - reg_val=struct.unpack('I',read_data_stream) + read_data_stream = mm.read(4) + reg_val = struct.unpack('I', read_data_stream) mem_val = str(reg_val)[1:-2] # print "reg_val read:%x"%reg_val return mem_val @@ -56,7 +61,7 @@ def pci_mem_read(self, mm, offset): def pci_mem_write(self, mm, offset, data): mm.seek(offset) # print "data to write:%x"%data - mm.write(struct.pack('I',data)) + mm.write(struct.pack('I', data)) def pci_set_value(self, resource, val, offset): fd = open(resource, O_RDWR) @@ -73,7 +78,7 @@ def pci_get_value(self, resource, offset): mm.close() close(fd) return val - + def init_global_port_presence(self): for port_num in range(self.port_start, (self.port_end + 1)): presence = self.get_presence(port_num) @@ -81,17 +86,15 @@ def init_global_port_presence(self): self._global_port_pres_dict[port_num] = '1' else: self._global_port_pres_dict[port_num] = '0' - + def __init__(self): eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" for x in range(self.port_start, self.port_end + 1): - port_num = x + 1 - self.port_to_eeprom_mapping[x] = eeprom_path.format( - port_num) + port_num = x + 1 + self.port_to_eeprom_mapping[x] = eeprom_path.format(port_num) port_num = 0 self.init_global_port_presence() - SfpUtilBase.__init__(self) def get_presence(self, port_num): @@ -100,13 +103,13 @@ def get_presence(self, port_num): return False # Port offset starts with 0x4004 - port_offset = 16388 + ((port_num-1) * 16) + port_offset = 16388 + ((port_num-1) * 16) + + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) - status = self.pci_get_value(self.BASE_RES_PATH, port_offset) - reg_value = int(status) - # Absence of status throws error - if (reg_value == "" ): + if (reg_value == ""): return False # Mask off 4th bit for presence @@ -124,14 +127,14 @@ def get_low_power_mode(self, port_num): if port_num < self.port_start or port_num > self.port_end: return False - # Port offset starts with 0x4000 - port_offset = 16384 + ((port_num-1) * 16) + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) - status = self.pci_get_value(self.BASE_RES_PATH, port_offset) - reg_value = int(status) + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) # Absence of status throws error - if (reg_value == "" ): + if (reg_value == ""): return False # Mask off 4th bit for presence @@ -149,44 +152,44 @@ def set_low_power_mode(self, port_num, lpmode): if port_num < self.port_start or port_num > self.port_end: return False - # Port offset starts with 0x4000 - port_offset = 16384 + ((port_num-1) * 16) + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) - status = self.pci_get_value(self.BASE_RES_PATH, port_offset) - reg_value = int(status) + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) # Absence of status throws error - if (reg_value == "" ): + if (reg_value == ""): return False # Mask off 4th bit for presence mask = (1 << 6) - - # LPMode is active high; set or clear the bit accordingly + + # LPMode is active high; set or clear the bit accordingly if lpmode is True: reg_value = reg_value | mask else: reg_value = reg_value & ~mask # Convert our register value back to a hex string and write back - status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) return True def reset(self, port_num): - # Check for invalid port_num + # Check for invalid port_num if port_num < self.port_start or port_num > self.port_end: return False - # Port offset starts with 0x4000 - port_offset = 16384 + ((port_num-1) * 16) + # Port offset starts with 0x4000 + port_offset = 16384 + ((port_num-1) * 16) - status = self.pci_get_value(self.BASE_RES_PATH, port_offset) - reg_value = int(status) + status = self.pci_get_value(self.BASE_RES_PATH, port_offset) + reg_value = int(status) # Absence of status throws error - if (reg_value == "" ): + if (reg_value == ""): return False # Mask off 4th bit for presence @@ -195,33 +198,106 @@ def reset(self, port_num): # ResetL is active low reg_value = reg_value & ~mask - # Convert our register value back to a hex string and write back - status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + # Convert our register value back to a hex string and write back + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) # Sleep 1 second to allow it to settle time.sleep(1) reg_value = reg_value | mask - # Convert our register value back to a hex string and write back - status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + # Convert our register value back to a hex string and write back + status = self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) return True - def get_transceiver_change_event(self): - port_dict = {} - while 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 check_interrupts(self, port_dict): + retval = 0 + is_port_dict_updated = False for port_num in range(self.port_start, (self.port_end + 1)): presence = self.get_presence(port_num) if(presence and self._global_port_pres_dict[port_num] == '0'): + is_port_dict_updated = True self._global_port_pres_dict[port_num] = '1' port_dict[port_num] = '1' elif(not presence and self._global_port_pres_dict[port_num] == '1'): + is_port_dict_updated = True self._global_port_pres_dict[port_num] = '0' port_dict[port_num] = '0' - - if(len(port_dict) > 0): - return True, port_dict - - time.sleep(0.5) + return retval, is_port_dict_updated + + def get_transceiver_change_event(self, timeout=0): + port_dict = {} + try: + # We get notified when there is a MSI interrupt (vector 4/5)CVR + # Open the sysfs file and register the epoll object + self.oir_fd = fdopen(open(self.OIR_FD_PATH, O_RDONLY)) + if self.oir_fd != -1: + # Do a dummy read before epoll register + self.oir_fd.read() + self.epoll = select.epoll() + self.epoll.register( + self.oir_fd.fileno(), select.EPOLLIN & select.EPOLLET) + else: + print("get_transceiver_change_event : unable to create fd") + return False, {} + + # Check for missed interrupts by invoking self.check_interrupts + # which will update the port_dict. + while True: + interrupt_count_start = self.get_register(self.OIR_FD_PATH) + retval, is_port_dict_updated = \ + self.check_interrupts(port_dict) + if ((retval == 0) and (is_port_dict_updated is True)): + return True, port_dict + interrupt_count_end = self.get_register(self.OIR_FD_PATH) + if (interrupt_count_start == 'ERR' or + interrupt_count_end == 'ERR'): + print("get_transceiver_change_event : \ + unable to retrive interrupt count") + break + + # check_interrupts() itself may take upto 100s of msecs. + # We detect a missed interrupt based on the count + if interrupt_count_start == interrupt_count_end: + break + + # Block until an xcvr is inserted or removed with timeout = -1 + events = self.epoll.poll( + timeout=timeout if timeout != 0 else -1) + if events: + # check interrupts and return the port_dict + retval, is_port_dict_updated = \ + self.check_interrupts(port_dict) + if (retval != 0): + return False, {} + + return True, port_dict + except: + return False, {} + finally: + if self.oir_fd != -1: + self.epoll.unregister(self.oir_fd.fileno()) + self.epoll.close() + self.oir_fd.close() + self.oir_fd = -1 + self.epoll = -1 + + return False, {} \ No newline at end of file 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 43e876e40e5d..6a2f15511d66 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 @@ -3,6 +3,7 @@ z9264f/scripts/check_qsfp.sh usr/local/bin z9264f/scripts/platform_sensors.py usr/local/bin z9264f/scripts/sensors usr/bin z9264f/scripts/pcisysfs.py usr/bin +z9264f/scripts/qsfp_irq_enable.py usr/bin z9264f/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 diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/modules/dell_z9264f_fpga_ocores.c b/platform/broadcom/sonic-platform-modules-dell/z9264f/modules/dell_z9264f_fpga_ocores.c index c08a4c210c53..d3a4a51ead72 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/modules/dell_z9264f_fpga_ocores.c +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/modules/dell_z9264f_fpga_ocores.c @@ -19,6 +19,7 @@ * @file fpga_ocores.c * @brief This is a driver to interface with Linux Open Cores driver for FPGA i2c access * + * 2019/5/9 - PCIe Interrupt supported is added for OIR Events. ************************************************************************/ #include #include @@ -89,7 +90,7 @@ struct fpgapci_dev { unsigned int irq_first; unsigned int irq_length; unsigned int irq_assigned; - + unsigned int xcvr_intr_count; }; static int use_irq = 1; @@ -226,6 +227,14 @@ enum { #define I2C_PCI_BUS_NUM_12 12 #define I2C_PCI_BUS_NUM_16 16 + +#define IRQ_LTCH_STS 0x20 +#define PRSNT_LTCH_STS 0x10 + +#define PORT_CTRL_OFFSET 0x4000 +#define PORT_STS_OFFSET 0x4004 +#define PORT_IRQ_STS_OFFSET 0x4008 +#define PORT_IRQ_EN_OFFSET 0x400C #define MB_BRD_REV_TYPE 0x0008 #define MB_BRD_REV_MASK 0x00f0 #define MB_BRD_REV_00 0x0000 @@ -248,7 +257,7 @@ enum { #define BRD_TYPE_S5232_NON_NEBS 0xc #define BRD_TYPE_S5232_NEBS 0xd -#define FPGA_CTL_REG_SIZE 0x60 +#define FPGA_CTL_REG_SIZE 0x6000 #define MSI_VECTOR_MAP_MASK 0x1f #define MSI_VECTOR_MAP1 0x58 #define I2C_CH1_MSI_MAP_VECT_8 0x00000008 @@ -284,6 +293,8 @@ enum { #define MSI_VECTOR_REV_00 16 #define MSI_VECTOR_REV_01 32 +#define FPGA_MSI_VECTOR_ID_4 4 +#define FPGA_MSI_VECTOR_ID_5 5 #define FPGA_MSI_VECTOR_ID_8 8 #define FPGA_MSI_VECTOR_ID_9 9 #define FPGA_MSI_VECTOR_ID_10 10 @@ -506,6 +517,73 @@ static int fpgai2c_poll(struct fpgalogic_i2c *i2c) return 0; } +static ssize_t get_mod_msi(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ind = 0, port_status=0, port_irq_status=0; + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(dev); + PRINT("%s:xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); + for(ind=0;ind<64;ind++) + { + port_status = ioread32(fpga_ctl_addr + PORT_STS_OFFSET + (ind*16)); + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); + } + return sprintf(buf,"0x%04x\n",fpgapci->xcvr_intr_count); +} +static DEVICE_ATTR(port_msi, S_IRUGO, get_mod_msi, NULL); + +static struct attribute *port_attrs[] = { + &dev_attr_port_msi.attr, + NULL, +}; + +static struct attribute_group port_attr_grp = { + .attrs = port_attrs, +}; + + +static irqreturn_t fpgaport_1_32_isr(int irq, void *dev) +{ + struct pci_dev *pdev = dev; + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); + int ind = 0, port_status=0, port_irq_status=0; + for(ind=0;ind<32;ind++) + { + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + if(port_irq_status&(IRQ_LTCH_STS|PRSNT_LTCH_STS)) + { + PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); + //write on clear + iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + } + } + fpgapci->xcvr_intr_count++; + PRINT("%s: xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); + sysfs_notify(&pdev->dev.kobj, NULL, "port_msi"); + return IRQ_HANDLED; +} + +static irqreturn_t fpgaport_33_64_isr(int irq, void *dev) +{ + struct pci_dev *pdev = dev; + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); + int ind = 0, port_status=0, port_irq_status=0; + for(ind=32;ind<64;ind++) + { + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + if(port_irq_status| (IRQ_LTCH_STS|PRSNT_LTCH_STS)) + { + PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); + //write on clear + iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + } + } + fpgapci->xcvr_intr_count++; + PRINT("%s: xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); + sysfs_notify(&pdev->dev.kobj, NULL, "port_msi"); + return IRQ_HANDLED; +} + static void fpgai2c_process(struct fpgalogic_i2c *i2c) { struct i2c_msg *msg = i2c->msg; @@ -1028,6 +1106,18 @@ static int register_intr_handler(struct pci_dev *dev, int irq_num_id) switch(irq_num_id) { /* Currently we only support test vector 2 for FPGA Logic I2C channel * controller 1-7 interrupt*/ + case FPGA_MSI_VECTOR_ID_4: + err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_5: + err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; case FPGA_MSI_VECTOR_ID_8: err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[0]); @@ -1074,6 +1164,18 @@ static int register_intr_handler(struct pci_dev *dev, int irq_num_id) ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { /* FPGA SPEC 4.3.1.34, First i2c channel mapped to vector 8 */ switch (irq_num_id) { + case FPGA_MSI_VECTOR_ID_4: + err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_5: + err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; case FPGA_MSI_VECTOR_ID_8: err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[0]); @@ -1387,6 +1489,7 @@ static int fpgapci_configure_msi(struct fpgapci_dev *fpgapci,struct pci_dev *dev static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id) { struct fpgapci_dev *fpgapci = 0; + int status = 0; #ifdef TEST PRINT ( " vendor = 0x%x, device = 0x%x, class = 0x%x, bus:slot.func = %02x:%02x.%02x\n", @@ -1404,6 +1507,10 @@ static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id) dev_set_drvdata(&dev->dev, (void*)fpgapci); fpgapci->upstream = find_upstream_dev (dev); + status = sysfs_create_group(&dev->dev.kobj, &port_attr_grp); + if (status) { + printk(KERN_INFO "%s:Cannot create sysfs\n", __FUNCTION__); + } if(fpgapci_setup_device(fpgapci,dev)) { goto error_no_device; diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/qsfp_irq_enable.py b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/qsfp_irq_enable.py new file mode 100755 index 000000000000..b2eb03dd2011 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/qsfp_irq_enable.py @@ -0,0 +1,32 @@ +#!/usr/bin/python + +try: + import struct + import sys + from os import * + from mmap import * + +except ImportError as e: + raise ImportError("%s - required module no found" % str(e)) + +BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" +PORT_START = 0 +PORT_END = 64 + + +def pci_mem_write(mm, offset, data): + mm.seek(offset) + mm.write(struct.pack('I', data)) + + +def pci_set_value(resource, val, offset): + fd = open(resource, O_RDWR) + mm = mmap(fd, 0) + val = pci_mem_write(mm, offset, val) + mm.close() + close(fd) + return val + +for port_num in range(PORT_START, PORT_END+1): + port_offset = 0x400c + ((port_num) * 16) + pci_set_value(BASE_RES_PATH, 0x30, port_offset) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh index 5002ce72c081..4c0646333575 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh @@ -98,6 +98,7 @@ if [ "$1" == "init" ]; then switch_board_qsfp_mux "new_device" switch_board_qsfp "new_device" switch_board_modsel + python /usr/bin/qsfp_irq_enable.py elif [ "$1" == "deinit" ]; then sys_eeprom "delete_device" From e10ec8c5f51063462f0623480632aa5b8b3899f6 Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Thu, 23 May 2019 21:11:56 +0000 Subject: [PATCH 71/88] [.gitignore]: add build artifacts * Ignore images * Ignore debug files * Ignore compressed/tarred files * Ignore libyang, smartmontools, and swig artifacts * Ignore miscellaneous initramfs-tools artifacts Signed-off-by: Lawrence Lee --- .gitignore | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.gitignore b/.gitignore index 85987cbc0543..c578849f5838 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,11 @@ target/ *.deb *.changes *.buildinfo +*.tar +*.xz +*.gz +*dbg* +*.img # Subdirectories in src src/bash/* @@ -43,6 +48,8 @@ src/libnl3/* !src/libnl3/Makefile src/libteam/* !src/libteam/Makefile +src/libyang/* +!src/libyang/Makefile src/lldpd/* !src/lldpd/Makefile !src/lldpd/patch/ @@ -59,6 +66,8 @@ src/radvd/* !src/radvd/patch/ src/redis/* !src/redis/Makefile +src/smartmontools/* +!src/smartmontools/Makefile src/snmpd/* !src/snmpd/Makefile src/sonic-device-data/src/device/ @@ -66,6 +75,8 @@ src/sonic-device-data/src/debian/ src/supervisor/* !src/supervisor/Makefile !src/supervisor/patch/ +src/swig/* +!src/swig/Makefile src/telemetry/debian/* !src/telemetry/debian/changelog !src/telemetry/debian/compat @@ -109,3 +120,7 @@ src/sonic-config-engine/sonic_config_engine.egg-info src/sonic-daemon-base/**/*.pyc src/sonic-daemon-base/build src/sonic-daemon-base/sonic_daemon_base.egg-info + +# Misc. files +files/initramfs-tools/arista-convertfs +files/initramfs-tools/union-mount From 62ef8593e7f8f51275fac47c1a9b6a12469875b5 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Fri, 24 May 2019 02:38:41 -0700 Subject: [PATCH 72/88] [monit] Set memory usage alert at 50% (#2939) Signed-off-by: Qi Luo --- build_debian.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_debian.sh b/build_debian.sh index 1108c455722f..cadb0b5f89bd 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -307,7 +307,7 @@ check filesystem root-overlay with path / 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 memory usage > 50% for 5 times within 10 cycles then alert if cpu usage (user) > 90% for 5 times within 10 cycles then alert if cpu usage (system) > 90% for 5 times within 10 cycles then alert EOF From b44eef9822a5a5811a5ce4dc5a93893043060040 Mon Sep 17 00:00:00 2001 From: jostar-yang Date: Fri, 24 May 2019 17:40:44 +0800 Subject: [PATCH 73/88] Add support as4630-54pe device and sdk cfg (#2928) * Add to support as4630-54pe platform * Add as4630 monitor psu/fan status * Add support as4630-54pe device and sdk cfg --- .../hx5-as4630-48x1G+4x25G+2x100G.bcm | 486 ++++++++++++++++++ .../Accton-AS4630-54PE/port_config.ini | 55 ++ .../Accton-AS4630-54PE/sai.profile | 1 + .../x86_64-accton_as4630_54pe-r0/default_sku | 1 + .../installer.conf | 3 + .../led_proc_init.soc | 2 + .../plugins/eeprom.py | 21 + .../plugins/psuutil.py | 61 +++ .../plugins/sfputil.py | 103 ++++ 9 files changed, 733 insertions(+) create mode 100755 device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/hx5-as4630-48x1G+4x25G+2x100G.bcm create mode 100755 device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/port_config.ini create mode 100755 device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/sai.profile create mode 100755 device/accton/x86_64-accton_as4630_54pe-r0/default_sku create mode 100755 device/accton/x86_64-accton_as4630_54pe-r0/installer.conf create mode 100755 device/accton/x86_64-accton_as4630_54pe-r0/led_proc_init.soc create mode 100755 device/accton/x86_64-accton_as4630_54pe-r0/plugins/eeprom.py create mode 100755 device/accton/x86_64-accton_as4630_54pe-r0/plugins/psuutil.py create mode 100755 device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/hx5-as4630-48x1G+4x25G+2x100G.bcm b/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/hx5-as4630-48x1G+4x25G+2x100G.bcm new file mode 100755 index 000000000000..a7f89ba4c62d --- /dev/null +++ b/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/hx5-as4630-48x1G+4x25G+2x100G.bcm @@ -0,0 +1,486 @@ +stable_size=71303168 + +#polarity/lanemap is using TH2 style. +core_clock_frequency=893 +dpp_clock_ratio=2:3 + +ptp_ts_pll_fref=50000000 +ptp_bs_fref_0=50000000 +ptp_bs_fref_1=50000000 + +#oversubscribe_mode=1 + +pbmp_xport_xe=0x1FFFFFFE000000000000 + +parity_enable=0 +mem_cache_enable=1 + +l2_mem_entries=32768 +#l3_mem_entries=49152 +#fpem_mem_entries=16384 +l2xmsg_mode=1 +port_flex_enable=1 + +#3x PM4x10Q (3 * 16 = 48 physical ports) +#Doesn't support oversubscribe in Q mode +#MCQ0 +port_gmii_mode_1=1 #Q mode + +#PHY4 U56 xx1, MDC/MDIO2, PHYADDR:0x00-0x07, 0x08 +port_phy_addr_1=0x40 +port_phy_addr_2=0x41 +port_phy_addr_3=0x42 +port_phy_addr_4=0x43 +port_phy_addr_5=0x44 +port_phy_addr_6=0x45 +port_phy_addr_7=0x46 +port_phy_addr_8=0x47 +phy_port_primary_and_offset_1=0x0100 +phy_port_primary_and_offset_2=0x0101 +phy_port_primary_and_offset_3=0x0102 +phy_port_primary_and_offset_4=0x0103 +phy_port_primary_and_offset_5=0x0104 +phy_port_primary_and_offset_6=0x0105 +phy_port_primary_and_offset_7=0x0106 +phy_port_primary_and_offset_8=0x0107 +dport_map_port_1=26 +dport_map_port_2=25 +dport_map_port_3=28 +dport_map_port_4=27 +dport_map_port_5=30 +dport_map_port_6=29 +dport_map_port_7=32 +dport_map_port_8=31 +portmap_1=1:1 +portmap_2=2:1 +portmap_3=3:1 +portmap_4=4:1 +portmap_5=5:1 +portmap_6=6:1 +portmap_7=7:1 +portmap_8=8:1 +phy_chain_rx_lane_map_physical{1.0}=0x3210 +phy_chain_rx_lane_map_physical{2.0}=0x3210 +phy_chain_rx_lane_map_physical{3.0}=0x3210 +phy_chain_rx_lane_map_physical{4.0}=0x3210 +phy_chain_rx_lane_map_physical{5.0}=0x3210 +phy_chain_rx_lane_map_physical{6.0}=0x3210 +phy_chain_rx_lane_map_physical{7.0}=0x3210 +phy_chain_rx_lane_map_physical{8.0}=0x3210 +phy_chain_tx_lane_map_physical{1.0}=0x3210 +phy_chain_tx_lane_map_physical{2.0}=0x3210 +phy_chain_tx_lane_map_physical{3.0}=0x3210 +phy_chain_tx_lane_map_physical{4.0}=0x3210 +phy_chain_tx_lane_map_physical{5.0}=0x3210 +phy_chain_tx_lane_map_physical{6.0}=0x3210 +phy_chain_tx_lane_map_physical{7.0}=0x3210 +phy_chain_tx_lane_map_physical{8.0}=0x3210 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{4.0}=0x0 +phy_chain_rx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{6.0}=0x0 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{4.0}=0x0 +phy_chain_tx_polarity_flip_physical{5.0}=0x0 +phy_chain_tx_polarity_flip_physical{6.0}=0x0 +phy_chain_tx_polarity_flip_physical{7.0}=0x0 +phy_chain_tx_polarity_flip_physical{8.0}=0x0 + + +#PHY5 U57 x1x, MDC/MDIO2, PHYADDR:0x09-0x10, 0x11 +port_phy_addr_9=0x49 +port_phy_addr_10=0x4A +port_phy_addr_11=0x4B +port_phy_addr_12=0x4C +port_phy_addr_13=0x4D +port_phy_addr_14=0x4E +port_phy_addr_15=0x4F +port_phy_addr_16=0x50 +phy_port_primary_and_offset_9=0x0900 +phy_port_primary_and_offset_10=0x0901 +phy_port_primary_and_offset_11=0x0902 +phy_port_primary_and_offset_12=0x0903 +phy_port_primary_and_offset_13=0x0904 +phy_port_primary_and_offset_14=0x0905 +phy_port_primary_and_offset_15=0x0906 +phy_port_primary_and_offset_16=0x0907 +dport_map_port_9=34 +dport_map_port_10=33 +dport_map_port_11=36 +dport_map_port_12=35 +dport_map_port_13=38 +dport_map_port_14=37 +dport_map_port_15=40 +dport_map_port_16=39 +portmap_9=9:1 +portmap_10=10:1 +portmap_11=11:1 +portmap_12=12:1 +portmap_13=13:1 +portmap_14=14:1 +portmap_15=15:1 +portmap_16=16:1 +phy_chain_rx_lane_map_physical{9.0}=0x3210 +phy_chain_rx_lane_map_physical{10.0}=0x3210 +phy_chain_rx_lane_map_physical{11.0}=0x3210 +phy_chain_rx_lane_map_physical{12.0}=0x3210 +phy_chain_rx_lane_map_physical{13.0}=0x3210 +phy_chain_rx_lane_map_physical{14.0}=0x3210 +phy_chain_rx_lane_map_physical{15.0}=0x3210 +phy_chain_rx_lane_map_physical{16.0}=0x3210 +phy_chain_tx_lane_map_physical{9.0}=0x3210 +phy_chain_tx_lane_map_physical{10.0}=0x3210 +phy_chain_tx_lane_map_physical{11.0}=0x3210 +phy_chain_tx_lane_map_physical{12.0}=0x3210 +phy_chain_tx_lane_map_physical{13.0}=0x3210 +phy_chain_tx_lane_map_physical{14.0}=0x3210 +phy_chain_tx_lane_map_physical{15.0}=0x3210 +phy_chain_tx_lane_map_physical{16.0}=0x3210 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{10.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x0 +phy_chain_rx_polarity_flip_physical{12.0}=0x0 +phy_chain_rx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{14.0}=0x0 +phy_chain_rx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{16.0}=0x0 +phy_chain_tx_polarity_flip_physical{9.0}=0x0 +phy_chain_tx_polarity_flip_physical{10.0}=0x0 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x0 +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x0 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_tx_polarity_flip_physical{16.0}=0x0 + +#MCQ1 +port_gmii_mode_17=1 #Q mode + +#PHY6 U58 11x, MDC/MDIO2, PHYADDR:0x12-0x19, 0x1A +port_phy_addr_17=0x52 +port_phy_addr_18=0x53 +port_phy_addr_19=0x54 +port_phy_addr_20=0x55 +port_phy_addr_21=0x56 +port_phy_addr_22=0x57 +port_phy_addr_23=0x58 +port_phy_addr_24=0x59 +phy_port_primary_and_offset_17=0x1100 +phy_port_primary_and_offset_18=0x1101 +phy_port_primary_and_offset_19=0x1102 +phy_port_primary_and_offset_20=0x1103 +phy_port_primary_and_offset_21=0x1104 +phy_port_primary_and_offset_22=0x1105 +phy_port_primary_and_offset_23=0x1106 +phy_port_primary_and_offset_24=0x1107 +dport_map_port_17=42 +dport_map_port_18=41 +dport_map_port_19=44 +dport_map_port_20=43 +dport_map_port_21=46 +dport_map_port_22=45 +dport_map_port_23=48 +dport_map_port_24=47 +portmap_17=17:1 +portmap_18=18:1 +portmap_19=19:1 +portmap_20=20:1 +portmap_21=21:1 +portmap_22=22:1 +portmap_23=23:1 +portmap_24=24:1 +phy_chain_rx_lane_map_physical{17.0}=0x3210 +phy_chain_rx_lane_map_physical{18.0}=0x3210 +phy_chain_rx_lane_map_physical{19.0}=0x3210 +phy_chain_rx_lane_map_physical{20.0}=0x3210 +phy_chain_rx_lane_map_physical{21.0}=0x3210 +phy_chain_rx_lane_map_physical{22.0}=0x3210 +phy_chain_rx_lane_map_physical{23.0}=0x3210 +phy_chain_rx_lane_map_physical{24.0}=0x3210 +phy_chain_tx_lane_map_physical{17.0}=0x3210 +phy_chain_tx_lane_map_physical{18.0}=0x3210 +phy_chain_tx_lane_map_physical{19.0}=0x3210 +phy_chain_tx_lane_map_physical{20.0}=0x3210 +phy_chain_tx_lane_map_physical{21.0}=0x3210 +phy_chain_tx_lane_map_physical{22.0}=0x3210 +phy_chain_tx_lane_map_physical{23.0}=0x3210 +phy_chain_tx_lane_map_physical{24.0}=0x3210 +phy_chain_rx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{18.0}=0x0 +phy_chain_rx_polarity_flip_physical{19.0}=0x0 +phy_chain_rx_polarity_flip_physical{20.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{22.0}=0x0 +phy_chain_rx_polarity_flip_physical{23.0}=0x0 +phy_chain_rx_polarity_flip_physical{24.0}=0x0 +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_tx_polarity_flip_physical{18.0}=0x0 +phy_chain_tx_polarity_flip_physical{19.0}=0x0 +phy_chain_tx_polarity_flip_physical{20.0}=0x0 +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x0 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_tx_polarity_flip_physical{24.0}=0x0 + +#PHY1 U53 xx1, MDC/MDIO0, PHYADDR:0x00-0x07, 0x08 +port_phy_addr_25=0x00 +port_phy_addr_26=0x01 +port_phy_addr_27=0x02 +port_phy_addr_28=0x03 +port_phy_addr_29=0x04 +port_phy_addr_30=0x05 +port_phy_addr_31=0x06 +port_phy_addr_32=0x07 +phy_port_primary_and_offset_25=0x1900 +phy_port_primary_and_offset_26=0x1901 +phy_port_primary_and_offset_27=0x1902 +phy_port_primary_and_offset_28=0x1903 +phy_port_primary_and_offset_29=0x1904 +phy_port_primary_and_offset_30=0x1905 +phy_port_primary_and_offset_31=0x1906 +phy_port_primary_and_offset_32=0x1907 +dport_map_port_25=2 +dport_map_port_26=1 +dport_map_port_27=4 +dport_map_port_28=3 +dport_map_port_29=6 +dport_map_port_30=5 +dport_map_port_31=8 +dport_map_port_32=7 +portmap_25=25:1 +portmap_26=26:1 +portmap_27=27:1 +portmap_28=28:1 +portmap_29=29:1 +portmap_30=30:1 +portmap_31=31:1 +portmap_32=32:1 +phy_chain_rx_lane_map_physical{25.0}=0x3210 +phy_chain_rx_lane_map_physical{26.0}=0x3210 +phy_chain_rx_lane_map_physical{27.0}=0x3210 +phy_chain_rx_lane_map_physical{28.0}=0x3210 +phy_chain_rx_lane_map_physical{29.0}=0x3210 +phy_chain_rx_lane_map_physical{30.0}=0x3210 +phy_chain_rx_lane_map_physical{31.0}=0x3210 +phy_chain_rx_lane_map_physical{32.0}=0x3210 +phy_chain_tx_lane_map_physical{25.0}=0x3210 +phy_chain_tx_lane_map_physical{26.0}=0x3210 +phy_chain_tx_lane_map_physical{27.0}=0x3210 +phy_chain_tx_lane_map_physical{28.0}=0x3210 +phy_chain_tx_lane_map_physical{29.0}=0x3210 +phy_chain_tx_lane_map_physical{30.0}=0x3210 +phy_chain_tx_lane_map_physical{31.0}=0x3210 +phy_chain_tx_lane_map_physical{32.0}=0x3210 +phy_chain_rx_polarity_flip_physical{25.0}=0x0 +phy_chain_rx_polarity_flip_physical{26.0}=0x0 +phy_chain_rx_polarity_flip_physical{27.0}=0x0 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 +phy_chain_rx_polarity_flip_physical{29.0}=0x0 +phy_chain_rx_polarity_flip_physical{30.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_tx_polarity_flip_physical{26.0}=0x0 +phy_chain_tx_polarity_flip_physical{27.0}=0x0 +phy_chain_tx_polarity_flip_physical{28.0}=0x0 +phy_chain_tx_polarity_flip_physical{29.0}=0x0 +phy_chain_tx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_tx_polarity_flip_physical{32.0}=0x0 + +#MCQ2 +port_gmii_mode_33=1 #Q mode + +#PHY2 U54 x1x, MDC/MDIO0, PHYADDR:0x09-0x10, 0x11 +port_phy_addr_33=0x0D +port_phy_addr_34=0x0E +port_phy_addr_35=0x0F +port_phy_addr_36=0x10 +port_phy_addr_37=0x09 +port_phy_addr_38=0x0A +port_phy_addr_39=0x0B +port_phy_addr_40=0x0C +phy_port_primary_and_offset_33=0x2504 +phy_port_primary_and_offset_34=0x2505 +phy_port_primary_and_offset_35=0x2506 +phy_port_primary_and_offset_36=0x2507 +phy_port_primary_and_offset_37=0x2500 +phy_port_primary_and_offset_38=0x2501 +phy_port_primary_and_offset_39=0x2502 +phy_port_primary_and_offset_40=0x2503 +dport_map_port_33=14 +dport_map_port_34=13 +dport_map_port_35=16 +dport_map_port_36=15 +dport_map_port_37=10 +dport_map_port_38=9 +dport_map_port_39=12 +dport_map_port_40=11 +portmap_33=33:1 +portmap_34=34:1 +portmap_35=35:1 +portmap_36=36:1 +portmap_37=37:1 +portmap_38=38:1 +portmap_39=39:1 +portmap_40=40:1 +phy_chain_rx_lane_map_physical{33.0}=0x3210 +phy_chain_rx_lane_map_physical{34.0}=0x3210 +phy_chain_rx_lane_map_physical{35.0}=0x3210 +phy_chain_rx_lane_map_physical{36.0}=0x3210 +phy_chain_rx_lane_map_physical{37.0}=0x3210 +phy_chain_rx_lane_map_physical{38.0}=0x3210 +phy_chain_rx_lane_map_physical{39.0}=0x3210 +phy_chain_rx_lane_map_physical{40.0}=0x3210 +phy_chain_tx_lane_map_physical{33.0}=0x3210 +phy_chain_tx_lane_map_physical{34.0}=0x3210 +phy_chain_tx_lane_map_physical{35.0}=0x3210 +phy_chain_tx_lane_map_physical{36.0}=0x3210 +phy_chain_tx_lane_map_physical{37.0}=0x3210 +phy_chain_tx_lane_map_physical{38.0}=0x3210 +phy_chain_tx_lane_map_physical{39.0}=0x3210 +phy_chain_tx_lane_map_physical{40.0}=0x3210 +phy_chain_rx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{34.0}=0x1 +phy_chain_rx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{36.0}=0x1 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x1 +phy_chain_rx_polarity_flip_physical{39.0}=0x1 +phy_chain_rx_polarity_flip_physical{40.0}=0x1 +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_tx_polarity_flip_physical{34.0}=0x1 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_tx_polarity_flip_physical{36.0}=0x1 +phy_chain_tx_polarity_flip_physical{37.0}=0x1 +phy_chain_tx_polarity_flip_physical{38.0}=0x1 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_tx_polarity_flip_physical{40.0}=0x1 + +#PHY3 U55 11x, MDC/MDIO0, PHYADDR:0x12-0x19, 0x1A +port_phy_addr_41=0x16 +port_phy_addr_42=0x17 +port_phy_addr_43=0x18 +port_phy_addr_44=0x19 +port_phy_addr_45=0x12 +port_phy_addr_46=0x13 +port_phy_addr_47=0x14 +port_phy_addr_48=0x15 +phy_port_primary_and_offset_41=0x2D00 +phy_port_primary_and_offset_42=0x2D01 +phy_port_primary_and_offset_43=0x2D02 +phy_port_primary_and_offset_44=0x2D03 +phy_port_primary_and_offset_45=0x2D04 +phy_port_primary_and_offset_46=0x2D05 +phy_port_primary_and_offset_47=0x2D06 +phy_port_primary_and_offset_48=0x2D07 +dport_map_port_41=22 +dport_map_port_42=21 +dport_map_port_43=24 +dport_map_port_44=23 +dport_map_port_45=18 +dport_map_port_46=17 +dport_map_port_47=20 +dport_map_port_48=19 +portmap_41=41:1 +portmap_42=42:1 +portmap_43=43:1 +portmap_44=44:1 +portmap_45=45:1 +portmap_46=46:1 +portmap_47=47:1 +portmap_48=48:1 +phy_chain_rx_lane_map_physical{41.0}=0x3210 +phy_chain_rx_lane_map_physical{42.0}=0x3210 +phy_chain_rx_lane_map_physical{43.0}=0x3210 +phy_chain_rx_lane_map_physical{44.0}=0x3210 +phy_chain_rx_lane_map_physical{45.0}=0x3210 +phy_chain_rx_lane_map_physical{46.0}=0x3210 +phy_chain_rx_lane_map_physical{47.0}=0x3210 +phy_chain_rx_lane_map_physical{48.0}=0x3210 +phy_chain_tx_lane_map_physical{41.0}=0x3210 +phy_chain_tx_lane_map_physical{42.0}=0x3210 +phy_chain_tx_lane_map_physical{43.0}=0x3210 +phy_chain_tx_lane_map_physical{44.0}=0x3210 +phy_chain_tx_lane_map_physical{45.0}=0x3210 +phy_chain_tx_lane_map_physical{46.0}=0x3210 +phy_chain_tx_lane_map_physical{47.0}=0x3210 +phy_chain_tx_lane_map_physical{48.0}=0x3210 +phy_chain_rx_polarity_flip_physical{41.0}=0x1 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x1 +phy_chain_rx_polarity_flip_physical{45.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{47.0}=0x1 +phy_chain_rx_polarity_flip_physical{48.0}=0x1 +phy_chain_tx_polarity_flip_physical{41.0}=0x1 +phy_chain_tx_polarity_flip_physical{42.0}=0x1 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_tx_polarity_flip_physical{44.0}=0x1 +phy_chain_tx_polarity_flip_physical{45.0}=0x1 +phy_chain_tx_polarity_flip_physical{46.0}=0x1 +phy_chain_tx_polarity_flip_physical{47.0}=0x1 +phy_chain_tx_polarity_flip_physical{48.0}=0x1 + +#3x PM4x25 (3 * 4 = 12 physical ports) +#FC0 +dport_map_port_49=51 +dport_map_port_50=50 +dport_map_port_51=49 +dport_map_port_52=52 +portmap_49=65:25 +portmap_50=66:25 +portmap_51=67:25 +portmap_52=68:25 +#FC1 +dport_map_port_53=57 +dport_map_port_54=58 +dport_map_port_55=59 +dport_map_port_56=60 +portmap_53=69:100:4 +#portmap_55=71:50 +#portmap_54=70:25 +#portmap_55=71:25 +#portmap_56=72:25 +#FC2 +dport_map_port_57=53 +dport_map_port_58=54 +dport_map_port_59=55 +dport_map_port_60=56 +portmap_57=73:100:4 +#portmap_59=75:50 +#portmap_58=74:25 +#portmap_59=75:25 +#portmap_60=76:25 + +#4x PM4x10 (4 * 4 = 16 physical ports) +#MC0 No connection +#MC1 No connection +#MC2 No connection +#MC3 No connection +#portmap_=49:10 +#portmap_=50:10 +#portmap_=51:10 +#portmap_=52:10 + +#portmap_=53:10 +#portmap_=54:10 +#portmap_=55:10 +#portmap_=56:10 + +#portmap_=57:10 +#portmap_=58:10 +#portmap_=59:10 +#portmap_=60:10 + +#portmap_=61:10 +#portmap_=62:10 +#portmap_=63:10 +#portmap_=64:10 diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/port_config.ini b/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/port_config.ini new file mode 100755 index 000000000000..d008d016ef5c --- /dev/null +++ b/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/port_config.ini @@ -0,0 +1,55 @@ +# name lanes alias index +Ethernet0 26 thousandE1 0 +Ethernet1 25 thousandE2 1 +Ethernet2 28 thousandE3 2 +Ethernet3 27 thousandE4 3 +Ethernet4 30 thousandE5 4 +Ethernet5 29 thousandE6 5 +Ethernet6 32 thousandE7 6 +Ethernet7 31 thousandE8 7 +Ethernet8 38 thousandE9 8 +Ethernet9 37 thousandE10 9 +Ethernet10 40 thousandE11 10 +Ethernet11 39 thousandE12 11 +Ethernet12 34 thousandE13 12 +Ethernet13 33 thousandE14 13 +Ethernet14 36 thousandE15 14 +Ethernet15 35 thousandE16 15 +Ethernet16 46 thousandE17 16 +Ethernet17 45 thousandE18 17 +Ethernet18 48 thousandE19 18 +Ethernet19 47 thousandE20 19 +Ethernet20 42 thousandE21 20 +Ethernet21 41 thousandE22 21 +Ethernet22 44 thousandE23 22 +Ethernet23 43 thousandE24 23 +Ethernet24 2 thousandE25 24 +Ethernet25 1 thousandE26 25 +Ethernet26 4 thousandE27 26 +Ethernet27 3 thousandE28 27 +Ethernet28 6 thousandE29 28 +Ethernet29 5 thousandE30 29 +Ethernet30 8 thousandE31 30 +Ethernet31 7 thousandE32 31 +Ethernet32 10 thousandE33 32 +Ethernet33 9 thousandE34 33 +Ethernet34 12 thousandE35 34 +Ethernet35 11 thousandE36 35 +Ethernet36 14 thousandE37 36 +Ethernet37 13 thousandE38 37 +Ethernet38 16 thousandE39 38 +Ethernet39 15 thousandE40 39 +Ethernet40 18 thousandE41 40 +Ethernet41 17 thousandE42 41 +Ethernet42 20 thousandE43 42 +Ethernet43 19 thousandE44 43 +Ethernet44 22 thousandE45 44 +Ethernet45 21 thousandE46 45 +Ethernet46 24 thousandE47 46 +Ethernet47 23 thousandE48 47 +Ethernet48 67 twentyfiveGigE49 48 +Ethernet49 66 twentyfiveGigE50 49 +Ethernet50 65 twentyfiveGigE51 50 +Ethernet51 68 twentyfiveGigE52 51 +Ethernet52 73,74,75,76 hundredGigE53 52 +Ethernet56 69,70,71,72 hundredGigE54 56 diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/sai.profile b/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/sai.profile new file mode 100755 index 000000000000..5329410fe8b3 --- /dev/null +++ b/device/accton/x86_64-accton_as4630_54pe-r0/Accton-AS4630-54PE/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/hx5-as4630-48x1G+4x25G+2x100G.bcm diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/default_sku b/device/accton/x86_64-accton_as4630_54pe-r0/default_sku new file mode 100755 index 000000000000..64e4213bdc71 --- /dev/null +++ b/device/accton/x86_64-accton_as4630_54pe-r0/default_sku @@ -0,0 +1 @@ +Accton-AS4630-54PE t1 diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/installer.conf b/device/accton/x86_64-accton_as4630_54pe-r0/installer.conf new file mode 100755 index 000000000000..925a32fc0c3a --- /dev/null +++ b/device/accton/x86_64-accton_as4630_54pe-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/led_proc_init.soc b/device/accton/x86_64-accton_as4630_54pe-r0/led_proc_init.soc new file mode 100755 index 000000000000..4fa004f5d130 --- /dev/null +++ b/device/accton/x86_64-accton_as4630_54pe-r0/led_proc_init.soc @@ -0,0 +1,2 @@ +led start +led auto on diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as4630_54pe-r0/plugins/eeprom.py new file mode 100755 index 000000000000..0d7def70fdc0 --- /dev/null +++ b/device/accton/x86_64-accton_as4630_54pe-r0/plugins/eeprom.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +try: + import exceptions + import binascii + import time + import optparse + import warnings + import os + import sys + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + import subprocess +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/bus/i2c/devices/1-0057/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as4630_54pe-r0/plugins/psuutil.py new file mode 100755 index 000000000000..a646981334e6 --- /dev/null +++ b/device/accton/x86_64-accton_as4630_54pe-r0/plugins/psuutil.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python + +############################################################################# +# Accton +# +# Module contains an implementation of SONiC PSU Base API and +# provides the PSUs status which are available in the platform +# +############################################################################# + +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + self.psu_path = "/sys/bus/i2c/devices/" + self.psu_presence = "/psu_present" + self.psu_oper_status = "/psu_power_good" + self.psu_mapping = { + 1: "10-0050", + 2: "11-0051", + } + + def get_num_psus(self): + return len(self.psu_mapping) + + def get_psu_status(self, index): + if index is None: + return False + + status = 0 + node = self.psu_path + self.psu_mapping[index]+self.psu_oper_status + try: + with open(node, 'r') as power_status: + status = int(power_status.read()) + except IOError: + return False + + return status == 1 + + def get_psu_presence(self, index): + if index is None: + return False + + status = 0 + node = self.psu_path + self.psu_mapping[index] + self.psu_presence + try: + with open(node, 'r') as presence_status: + status = int(presence_status.read()) + except IOError: + return False + + return status == 1 diff --git a/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py new file mode 100755 index 000000000000..69c2870669e7 --- /dev/null +++ b/device/accton/x86_64-accton_as4630_54pe-r0/plugins/sfputil.py @@ -0,0 +1,103 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + + PORT_START = 48 + PORT_END = 53 + PORTS_IN_BLOCK = 54 + + BASE_OOM_PATH = "/sys/bus/i2c/devices/{0}-0050/" + BASE_CPLD_PATH = "/sys/bus/i2c/devices/3-0060/" + + _port_to_is_present = {} + _port_to_lp_mode = {} + + _port_to_eeprom_mapping = {} + _port_to_i2c_mapping = { + 48: [18], + 49: [19], + 50: [20], + 51: [21], + 52: [22], + 53: [23], + } + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return range(self.PORT_START, self.PORTS_IN_BLOCK + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + eeprom_path = self.BASE_OOM_PATH + "eeprom" + + for x in range(0, self.port_end+1): + if x < 48: + self.port_to_eeprom_mapping[x] = eeprom_path.format(0) + else: + self.port_to_eeprom_mapping[x] = eeprom_path.format( + self._port_to_i2c_mapping[x][0]) + + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + present_path = self.BASE_CPLD_PATH + "module_present_" + str(port_num+1) + self.__port_to_is_present = present_path + + try: + val_file = open(self.__port_to_is_present) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = val_file.readline().rstrip() + val_file.close() + + # content is a string, either "0" or "1" + if content == "1": + return True + + return False + + def get_low_power_mode(self, port_num): + raise NotImplementedError + + def set_low_power_mode(self, port_num, lpmode): + raise NotImplementedError + + def reset(self, port_num): + raise NotImplementedError + + def get_transceiver_change_event(self): + """ + TODO: This function need to be implemented + when decide to support monitoring SFP(Xcvrd) + on this platform. + """ + raise NotImplementedError From a0c740b2f9b7e4d6414bc330bfdc7d44743d468c Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Fri, 24 May 2019 16:36:23 +0000 Subject: [PATCH 74/88] [.gitignore]: update inclusion of dbg files * Remove pattern '*dbg*' and replaced with '*-dbg' and '*dbg.j2' Signed-off-by: Lawrence Lee --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index c578849f5838..7d355b8ff46f 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,8 @@ target/ *.tar *.xz *.gz -*dbg* +*-dbg +*dbg.j2 *.img # Subdirectories in src From f5d3ee71a2e32d96be5728340fc9a9cfa1992d08 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Sun, 26 May 2019 08:59:56 +0800 Subject: [PATCH 75/88] [pmon]: Add ethtool to pmon docker (#2943) --- dockers/docker-platform-monitor/Dockerfile.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-platform-monitor/Dockerfile.j2 b/dockers/docker-platform-monitor/Dockerfile.j2 index 829db1369acc..2244828c2117 100755 --- a/dockers/docker-platform-monitor/Dockerfile.j2 +++ b/dockers/docker-platform-monitor/Dockerfile.j2 @@ -7,7 +7,7 @@ RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%s ENV DEBIAN_FRONTEND=noninteractive # Install required packages -RUN apt-get update && apt-get install -y python-pip libpython2.7 ipmitool librrd8 librrd-dev rrdtool python-smbus +RUN apt-get update && apt-get install -y python-pip libpython2.7 ipmitool librrd8 librrd-dev rrdtool python-smbus ethtool {% if docker_platform_monitor_debs.strip() -%} # Copy locally-built Debian package dependencies From 3ec3e20e5a946e9b136b996d82ddaa5545786c6e Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sat, 25 May 2019 18:00:18 -0700 Subject: [PATCH 76/88] [logrotate] Enhance robustness (#2942) * [logrotate] Decrease frequency to every 10 minutes; kill any lingering logrotate processes * [logrotate] Delete all *.1.gz files as firstaction; Remove note about init-system-helpers < 1.47 workaround However, continue to send SIGHUP directly to rsyslogd process because 'service rsyslog rotate' still doesn't work properly with init-system-helpers version 1.48 --- files/image_config/cron.d/logrotate | 5 +++-- .../image_config/logrotate/logrotate.d/rsyslog | 18 +++++++----------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/files/image_config/cron.d/logrotate b/files/image_config/cron.d/logrotate index d0c2e0829ba9..173a2abe2bd2 100644 --- a/files/image_config/cron.d/logrotate +++ b/files/image_config/cron.d/logrotate @@ -1,2 +1,3 @@ -# Attempt to rotate system logs once per minute -* * * * * root /usr/sbin/logrotate /etc/logrotate.conf > /dev/null 2>&1 +# Attempt to rotate system logs once every 10 minutes. +# First kill any logrotate process(es) if they are still running, as they're most likely hung +*/10 * * * * root /usr/bin/pkill -9 logrotate > /dev/null 2>&1; /usr/sbin/logrotate /etc/logrotate.conf > /dev/null 2>&1 diff --git a/files/image_config/logrotate/logrotate.d/rsyslog b/files/image_config/logrotate/logrotate.d/rsyslog index 6788762d7687..76737ba14420 100644 --- a/files/image_config/logrotate/logrotate.d/rsyslog +++ b/files/image_config/logrotate/logrotate.d/rsyslog @@ -19,11 +19,7 @@ delaycompress sharedscripts postrotate - # calling kill directly instead of 'service rsyslog rotate >/dev/null' due - # to bug in init-system-helpers. bug has apparently been fixed in v1.47. - # however, debian jessie is still using v1.22. - # see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=672218 - kill -hup $(cat /var/run/rsyslogd.pid) + /bin/kill -HUP $(cat /var/run/rsyslogd.pid) endscript } @@ -44,7 +40,7 @@ compress delaycompress nosharedscripts - prerotate + firstaction # Adjust NUM_LOGS_TO_ROTATE to reflect number of log files that trigger this block specified above NUM_LOGS_TO_ROTATE=8 @@ -65,6 +61,10 @@ # of caution, giving us a bit of a cushion if a log grows quickly and passes its rotation size THRESHOLD_KB=$((USABLE_SPACE_KB - (NUM_LOGS_TO_ROTATE * LOG_FILE_ROTATE_SIZE_KB * 2))) + # First, delete any *.1.gz files that might be left around from a prior incomplete + # logrotate execution, otherwise logrotate will fail to do its job + find /var/log/ -name '*.1.gz' -type f -exec rm -f {} + + while true; do USED_KB=$(du -s /var/log | awk '{ print $1; }') @@ -87,11 +87,7 @@ if [ $(echo $1 | grep -c "/var/log/swss/") -gt 0 ]; then pgrep -x orchagent | xargs /bin/kill -HUP 2>/dev/null || true else - # Calling kill directly instead of 'service rsyslog rotate >/dev/null' due - # to bug in init-system-helpers. Bug has apparently been fixed in v1.47. - # However, Debian Jessie is still using v1.22. - # See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=672218 - kill -HUP $(cat /var/run/rsyslogd.pid) + /bin/kill -HUP $(cat /var/run/rsyslogd.pid) fi endscript } From 0cdc22d3cb1e3560e75e5cc9f38ba2fb542113f4 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Sun, 26 May 2019 09:00:52 +0800 Subject: [PATCH 77/88] [devices]: enable ISSU on 2410 (#2937) --- .../mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/sai_2410.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/sai_2410.xml b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/sai_2410.xml index 1f97994f887b..4884cd754a30 100644 --- a/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/sai_2410.xml +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/sai_2410.xml @@ -5,6 +5,9 @@ 00:02:03:04:05:00 + + 1 + 56 From 6d62249f04dcc00bbeaa0c18dfa4304915b8f2ad Mon Sep 17 00:00:00 2001 From: "Sudharsan D.G" Date: Sun, 26 May 2019 01:06:53 +0000 Subject: [PATCH 78/88] [devices]: Optics fixes in Dell Z9100/Z9264f platforms (#2936) --- .../z9100/scripts/z9100_platform.sh | 4 ++++ .../z9264f/scripts/z9264f_platform.sh | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh index 294b1b79aa88..3cc48e52110f 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh @@ -221,6 +221,10 @@ if [[ "$1" == "init" ]]; then #Copy led_proc_init.soc init_switch_port_led + value=0x0 + echo $value > /sys/class/i2c-adapter/i2c-14/14-003e/qsfp_lpmode + echo $value > /sys/class/i2c-adapter/i2c-15/15-003e/qsfp_lpmode + echo $value > /sys/class/i2c-adapter/i2c-16/16-003e/qsfp_lpmode elif [[ "$1" == "deinit" ]]; then xcvr_presence_interrupts "disable" diff --git a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh index 4c0646333575..880ba98abb1f 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9264f/scripts/z9264f_platform.sh @@ -82,7 +82,7 @@ switch_board_modsel() { do port_addr=$(( 16384 + ((i - 1) * 16))) hex=$( printf "0x%x" $port_addr ) - python /usr/bin/pcisysfs.py --set --offset $hex --val 0x41 --res $resource > /dev/null 2>&1 + python /usr/bin/pcisysfs.py --set --offset $hex --val 0x10 --res $resource > /dev/null 2>&1 done } init_devnum From 30b37ec6fb54183ce9606dc92ab79347190386b9 Mon Sep 17 00:00:00 2001 From: lguohan Date: Mon, 27 May 2019 15:50:51 -0700 Subject: [PATCH 79/88] [build]: make sonic-slave-stretch as the default build docker (#2921) Signed-off-by: Guohan Lu --- Makefile | 16 ++++++++-------- Makefile.work | 9 ++++----- README.md | 3 --- build_debian.sh | 2 +- .../build_templates/sonic_debian_extension.j2 | 10 ++++++---- rules/docker-base-stretch.mk | 1 + rules/docker-config-engine-stretch.mk | 1 + rules/docker-ptf.mk | 1 + slave.mk | 18 ++++++++++-------- sonic-slave-stretch/Dockerfile | 7 +++++++ 10 files changed, 39 insertions(+), 29 deletions(-) diff --git a/Makefile b/Makefile index f3908ce55c4c..c949171a899a 100644 --- a/Makefile +++ b/Makefile @@ -1,20 +1,20 @@ # SONiC make file -NOSTRETCH ?= 0 +NOJESSIE ?= 0 %:: @echo "+++ --- Making $@ --- +++" -ifeq ($(NOSTRETCH), 0) - BLDENV=stretch EXTRA_STRETCH_TARGETS=$(notdir $@) make -f Makefile.work stretch +ifeq ($(NOJESSIE), 0) + EXTRA_JESSIE_TARGETS=$(notdir $@) make -f Makefile.work jessie endif - make -f Makefile.work $@ + BLDENV=stretch make -f Makefile.work $@ -stretch: +jessie: @echo "+++ Making $@ +++" -ifeq ($(NOSTRETCH), 0) - BLDENV=stretch make -f Makefile.work stretch +ifeq ($(NOJESSIE), 0) + make -f Makefile.work jessie endif clean reset init configure showtag sonic-slave-build sonic-slave-bash : @echo "+++ Making $@ +++" - make -f Makefile.work $@ + BLDENV=stretch make -f Makefile.work $@ diff --git a/Makefile.work b/Makefile.work index 95e7a2af444e..975b9a5dcd21 100644 --- a/Makefile.work +++ b/Makefile.work @@ -20,11 +20,10 @@ # * Please note that with current Stretch build structure, # * user of KEEP_SLAVE_ON feature will have to be conscious # * about which docker to stay inside after build is done. -# * - If user desires to stay inside Stretch docker, please issue -# * make KEEP_SLAVE_ON=yes stretch # * - If user desires to stay inside Jessie docker, please issue -# * (a successful "make stretch" may be needed before the following command) -# * make NOSTRETCH=1 KEEP_SLAVE_ON=yes +# * make KEEP_SLAVE_ON=yes jessie +# * - If user desires to stay inside Stretch docker, please issue +# * make NOJESSIE=1 KEEP_SLAVE_ON=yes # * SOURCE_FOLDER: host path to be mount as /var/$(USER)/src, only effective when KEEP_SLAVE_ON=yes # * SONIC_BUILD_JOBS: Specifying number of concurrent build job(s) to run # * VS_PREPARE_MEM: Prepare memory in VS build (drop cache and compact). @@ -123,7 +122,7 @@ SONIC_BUILD_INSTRUCTION := make \ HTTP_PROXY=$(http_proxy) \ HTTPS_PROXY=$(https_proxy) \ SONIC_ENABLE_SYSTEM_TELEMETRY=$(ENABLE_SYSTEM_TELEMETRY) \ - EXTRA_STRETCH_TARGETS=$(EXTRA_STRETCH_TARGETS) \ + EXTRA_JESSIE_TARGETS=$(EXTRA_JESSIE_TARGETS) \ $(SONIC_OVERRIDE_BUILD_VARS) .PHONY: sonic-slave-build sonic-slave-bash init reset diff --git a/README.md b/README.md index 84d08bd664a5..4f9ed41d22b1 100644 --- a/README.md +++ b/README.md @@ -71,9 +71,6 @@ To build SONiC installer image and docker images, run the following commands: # Execute make configure once to configure ASIC make configure PLATFORM=[ASIC_VENDOR] - # Build Debian Stretch required targets (Manual execution optional; will also be executed as part of the build) - BLDENV=stretch make stretch - # Build SONiC image make all diff --git a/build_debian.sh b/build_debian.sh index cadb0b5f89bd..35b3882f837e 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -160,7 +160,7 @@ sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/hooks/union-fsck pushd $FILESYSTEM_ROOT/usr/share/initramfs-tools/scripts/init-bottom && sudo patch -p1 < $OLDPWD/files/initramfs-tools/udev.patch; popd ## Install latest intel ixgbe driver -sudo cp target/files/stretch/ixgbe.ko $FILESYSTEM_ROOT/lib/modules/${LINUX_KERNEL_VERSION}-amd64/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe.ko +sudo cp $files_path/ixgbe.ko $FILESYSTEM_ROOT/lib/modules/${LINUX_KERNEL_VERSION}-amd64/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe.ko ## Install docker echo '[INFO] Install docker' diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 2aa8e5da60c0..03ae5f317de6 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -111,6 +111,8 @@ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/python-click*_all.deb || \ # Install python pexpect used by sonic-utilities consutil # using pip install instead to get a more recent version than is available through debian sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install pexpect +# Install python click-default-group by sonic-utilities +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install click-default-group==1.2 # Install tabulate >= 0.8.1 via pip in order to support multi-line row output for sonic-utilities sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install tabulate==0.8.2 @@ -325,10 +327,10 @@ sudo cp {{src}} $FILESYSTEM_ROOT/{{dst}} {% if sonic_asic_platform == "mellanox" %} sudo mkdir -p $FILESYSTEM_ROOT/etc/mlnx/ -sudo cp target/files/$MLNX_SPC_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC.mfa -sudo cp target/files/$MLNX_SPC2_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC2.mfa -sudo cp target/files/$ISSU_VERSION_FILE $FILESYSTEM_ROOT/etc/mlnx/issu-version -sudo cp target/files/$MLNX_FFB_SCRIPT $FILESYSTEM_ROOT/usr/bin/mlnx-ffb.sh +sudo cp $files_path/$MLNX_SPC_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC.mfa +sudo cp $files_path/$MLNX_SPC2_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC2.mfa +sudo cp $files_path/$ISSU_VERSION_FILE $FILESYSTEM_ROOT/etc/mlnx/issu-version +sudo cp $files_path/$MLNX_FFB_SCRIPT $FILESYSTEM_ROOT/usr/bin/mlnx-ffb.sh j2 platform/mellanox/mlnx-fw-upgrade.j2 | sudo tee $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh {% endif %} diff --git a/rules/docker-base-stretch.mk b/rules/docker-base-stretch.mk index 898e018f9b10..a2495ed31659 100644 --- a/rules/docker-base-stretch.mk +++ b/rules/docker-base-stretch.mk @@ -16,4 +16,5 @@ ifeq ($(INSTALL_DEBUG_TOOLS),y) $(DOCKER_BASE_STRETCH)_DBG_PACKAGES += $($(DOCKER_BASE_STRETCH)_DBG_IMAGE_PACKAGES) endif +SONIC_DOCKER_IMAGES += $(DOCKER_BASE_STRETCH) SONIC_STRETCH_DOCKERS += $(DOCKER_BASE_STRETCH) diff --git a/rules/docker-config-engine-stretch.mk b/rules/docker-config-engine-stretch.mk index a18ed380f6f2..2a1e36d28833 100644 --- a/rules/docker-config-engine-stretch.mk +++ b/rules/docker-config-engine-stretch.mk @@ -9,4 +9,5 @@ $(DOCKER_CONFIG_ENGINE_STRETCH)_LOAD_DOCKERS += $(DOCKER_BASE_STRETCH) $(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS = $($(DOCKER_BASE_STRETCH)_DBG_DEPENDS) $(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES = $($(DOCKER_BASE_STRETCH)_DBG_IMAGE_PACKAGES) +SONIC_DOCKER_IMAGES += $(DOCKER_CONFIG_ENGINE_STRETCH) SONIC_STRETCH_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) diff --git a/rules/docker-ptf.mk b/rules/docker-ptf.mk index 2782c45339bd..aa517bf16d74 100644 --- a/rules/docker-ptf.mk +++ b/rules/docker-ptf.mk @@ -4,3 +4,4 @@ DOCKER_PTF = docker-ptf.gz $(DOCKER_PTF)_PATH = $(DOCKERS_PATH)/docker-ptf $(DOCKER_PTF)_DEPENDS += $(LIBTHRIFT) $(PYTHON_THRIFT) $(PTF) SONIC_DOCKER_IMAGES += $(DOCKER_PTF) +SONIC_JESSIE_DOCKERS += $(DOCKER_PTF) diff --git a/slave.mk b/slave.mk index 0e6e2adcb37f..6cedda612024 100644 --- a/slave.mk +++ b/slave.mk @@ -471,17 +471,17 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_SIMPLE_DOCKER_IMAGES)) : $(TARGET_PATH)/%.g SONIC_TARGET_LIST += $(addprefix $(TARGET_PATH)/, $(SONIC_SIMPLE_DOCKER_IMAGES)) -# Build stretch docker images only in stretch slave docker, +# Build jessie docker images only in jessie slave docker, # jessie docker images only in jessie slave docker -ifeq ($(BLDENV),stretch) +ifeq ($(BLDENV),) DOCKER_IMAGES_FOR_INSTALLERS := $(sort $(foreach installer,$(SONIC_INSTALLERS),$($(installer)_DOCKERS))) - DOCKER_IMAGES := $(SONIC_STRETCH_DOCKERS) - DOCKER_DBG_IMAGES := $(SONIC_STRETCH_DBG_DOCKERS) - SONIC_STRETCH_DOCKERS_FOR_INSTALLERS = $(filter $(SONIC_STRETCH_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS) $(EXTRA_STRETCH_TARGETS)) - SONIC_STRETCH_DBG_DOCKERS_FOR_INSTALLERS = $(filter $(SONIC_STRETCH_DBG_DOCKERS), $(patsubst %.gz,%-$(DBG_IMAGE_MARK).gz, $(SONIC_STRETCH_DOCKERS_FOR_INSTALLERS))) + DOCKER_IMAGES := $(SONIC_JESSIE_DOCKERS) + DOCKER_DBG_IMAGES := $(SONIC_JESSIE_DBG_DOCKERS) + SONIC_JESSIE_DOCKERS_FOR_INSTALLERS = $(filter $(SONIC_JESSIE_DOCKERS),$(DOCKER_IMAGES_FOR_INSTALLERS) $(EXTRA_JESSIE_TARGETS)) + SONIC_JESSIE_DBG_DOCKERS_FOR_INSTALLERS = $(filter $(SONIC_JESSIE_DBG_DOCKERS), $(patsubst %.gz,%-$(DBG_IMAGE_MARK).gz, $(SONIC_JESSIE_DOCKERS_FOR_INSTALLERS))) else - DOCKER_IMAGES := $(filter-out $(SONIC_STRETCH_DOCKERS), $(SONIC_DOCKER_IMAGES)) - DOCKER_DBG_IMAGES := $(filter-out $(SONIC_STRETCH_DBG_DOCKERS), $(SONIC_DOCKER_DBG_IMAGES)) + DOCKER_IMAGES := $(filter-out $(SONIC_JESSIE_DOCKERS), $(SONIC_DOCKER_IMAGES)) + DOCKER_DBG_IMAGES := $(filter-out $(SONIC_JESSIE_DBG_DOCKERS), $(SONIC_DOCKER_DBG_IMAGES)) endif # Targets for building docker images @@ -593,6 +593,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(HEADER) # 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 initramfs_tools="$(STRETCH_DEBS_PATH)/$(INITRAMFS_TOOLS)" export linux_kernel="$(STRTCH_DEBS_PATH)/$(LINUX_KERNEL)" @@ -719,6 +720,7 @@ stretch : $$(addprefix $(DEBS_PATH)/,$$(SONIC_STRETCH_DEBS)) \ $$(addprefix $(TARGET_PATH)/,$$(SONIC_STRETCH_DOCKERS_FOR_INSTALLERS)) \ $$(addprefix $(TARGET_PATH)/,$$(SONIC_STRETCH_DBG_DOCKERS_FOR_INSTALLERS)) +jessie : $$(addprefix $(TARGET_PATH)/,$$(SONIC_JESSIE_DOCKERS_FOR_INSTALLERS)) ############################################################################### ## Standard targets diff --git a/sonic-slave-stretch/Dockerfile b/sonic-slave-stretch/Dockerfile index 5cb328f6b257..9d94d11197e0 100644 --- a/sonic-slave-stretch/Dockerfile +++ b/sonic-slave-stretch/Dockerfile @@ -232,6 +232,10 @@ RUN apt-get update && apt-get install -y \ python3-colorama \ # For initramfs bash-completion \ +# For sonic vs image build + dosfstools \ + qemu-kvm \ + libvirt-clients \ # For lm-sensors librrd8 \ librrd-dev \ @@ -282,6 +286,9 @@ RUN pip3 install redis # For supervisor build RUN pip install meld3 mock +# For vs image build +RUN pip install pexpect==4.6.0 + # For sonic-utilities build RUN pip install mockredispy==2.9.3 RUN pip install pytest-runner==4.4 From 38fb90d7da1f5737c0df23ffe94c3618930cae47 Mon Sep 17 00:00:00 2001 From: Karthik Gengan <50580882+gengankarthik@users.noreply.github.com> Date: Tue, 28 May 2019 11:57:21 +0530 Subject: [PATCH 80/88] [devices]: DellEmc Z9264f: Adding port speed entry in port_config.ini. (#2949) --- .../DellEMC-Z9264f-C64/port_config.ini | 130 +++++++++--------- .../DellEMC-Z9264f-Q64/port_config.ini | 130 +++++++++--------- 2 files changed, 130 insertions(+), 130 deletions(-) diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/port_config.ini b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/port_config.ini index f0be4bb442d2..1dc88972d530 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/port_config.ini +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/port_config.ini @@ -1,65 +1,65 @@ -# name lanes alias index -Ethernet0 49,50,51,52 hundredGigE1/1 1 -Ethernet4 53,54,55,56 hundredGigE1/2 2 -Ethernet8 65,66,67,68 hundredGigE1/3 3 -Ethernet12 69,70,71,72 hundredGigE1/4 4 -Ethernet16 81,82,83,84 hundredGigE1/5 5 -Ethernet20 85,86,87,88 hundredGigE1/6 6 -Ethernet24 97,98,99,100 hundredGigE1/7 7 -Ethernet28 101,102,103,104 hundredGigE1/8 8 -Ethernet32 1,2,3,4 hundredGigE1/9 9 -Ethernet36 5,6,7,8 hundredGigE1/10 10 -Ethernet40 17,18,19,20 hundredGigE1/11 11 -Ethernet44 21,22,23,24 hundredGigE1/12 12 -Ethernet48 33,34,35,36 hundredGigE1/13 13 -Ethernet52 37,38,39,40 hundredGigE1/14 14 -Ethernet56 113,114,115,116 hundredGigE1/15 15 -Ethernet60 117,118,119,120 hundredGigE1/16 16 -Ethernet64 133,134,135,136 hundredGigE1/17 17 -Ethernet68 129,130,131,132 hundredGigE1/18 18 -Ethernet72 213,214,215,216 hundredGigE1/19 19 -Ethernet76 209,210,211,212 hundredGigE1/20 20 -Ethernet80 229,230,231,232 hundredGigE1/21 21 -Ethernet84 225,226,227,228 hundredGigE1/22 22 -Ethernet88 245,246,247,248 hundredGigE1/23 23 -Ethernet92 241,242,243,244 hundredGigE1/24 24 -Ethernet96 149,150,151,152 hundredGigE1/25 25 -Ethernet100 145,146,147,148 hundredGigE1/26 26 -Ethernet104 165,166,167,168 hundredGigE1/27 27 -Ethernet108 161,162,163,164 hundredGigE1/28 28 -Ethernet112 181,182,183,184 hundredGigE1/29 29 -Ethernet116 177,178,179,180 hundredGigE1/30 30 -Ethernet120 197,198,199,200 hundredGigE1/31 31 -Ethernet124 193,194,195,196 hundredGigE1/32 32 -Ethernet128 61,62,63,64 hundredGigE1/33 33 -Ethernet132 57,58,59,60 hundredGigE1/34 34 -Ethernet136 77,78,79,80 hundredGigE1/35 35 -Ethernet140 73,74,75,76 hundredGigE1/36 36 -Ethernet144 93,94,95,96 hundredGigE1/37 37 -Ethernet148 89,90,91,92 hundredGigE1/38 38 -Ethernet152 109,110,111,112 hundredGigE1/39 39 -Ethernet156 105,106,107,108 hundredGigE1/40 40 -Ethernet160 13,14,15,16 hundredGigE1/41 41 -Ethernet164 9,10,11,12 hundredGigE1/42 42 -Ethernet168 29,30,31,32 hundredGigE1/43 43 -Ethernet172 25,26,27,28 hundredGigE1/44 44 -Ethernet176 45,46,47,48 hundredGigE1/45 45 -Ethernet180 41,42,43,44 hundredGigE1/46 46 -Ethernet184 125,126,127,128 hundredGigE1/47 47 -Ethernet188 121,122,123,124 hundredGigE1/48 48 -Ethernet192 137,138,139,140 hundredGigE1/49 49 -Ethernet196 141,142,143,144 hundredGigE1/50 50 -Ethernet200 217,218,219,220 hundredGigE1/51 51 -Ethernet204 221,222,223,224 hundredGigE1/52 52 -Ethernet208 233,234,235,236 hundredGigE1/53 53 -Ethernet212 237,238,239,240 hundredGigE1/54 54 -Ethernet216 249,250,251,252 hundredGigE1/55 55 -Ethernet220 253,254,255,256 hundredGigE1/56 56 -Ethernet224 153,154,155,156 hundredGigE1/57 57 -Ethernet228 157,158,159,160 hundredGigE1/58 58 -Ethernet232 169,170,171,172 hundredGigE1/59 59 -Ethernet236 173,174,175,176 hundredGigE1/60 60 -Ethernet240 185,186,187,188 hundredGigE1/61 61 -Ethernet244 189,190,191,192 hundredGigE1/62 62 -Ethernet248 201,202,203,204 hundredGigE1/63 63 -Ethernet252 205,206,207,208 hundredGigE1/64 64 +# name lanes alias index speed +Ethernet0 49,50,51,52 hundredGigE1/1 1 100000 +Ethernet4 53,54,55,56 hundredGigE1/2 2 100000 +Ethernet8 65,66,67,68 hundredGigE1/3 3 100000 +Ethernet12 69,70,71,72 hundredGigE1/4 4 100000 +Ethernet16 81,82,83,84 hundredGigE1/5 5 100000 +Ethernet20 85,86,87,88 hundredGigE1/6 6 100000 +Ethernet24 97,98,99,100 hundredGigE1/7 7 100000 +Ethernet28 101,102,103,104 hundredGigE1/8 8 100000 +Ethernet32 1,2,3,4 hundredGigE1/9 9 100000 +Ethernet36 5,6,7,8 hundredGigE1/10 10 100000 +Ethernet40 17,18,19,20 hundredGigE1/11 11 100000 +Ethernet44 21,22,23,24 hundredGigE1/12 12 100000 +Ethernet48 33,34,35,36 hundredGigE1/13 13 100000 +Ethernet52 37,38,39,40 hundredGigE1/14 14 100000 +Ethernet56 113,114,115,116 hundredGigE1/15 15 100000 +Ethernet60 117,118,119,120 hundredGigE1/16 16 100000 +Ethernet64 133,134,135,136 hundredGigE1/17 17 100000 +Ethernet68 129,130,131,132 hundredGigE1/18 18 100000 +Ethernet72 213,214,215,216 hundredGigE1/19 19 100000 +Ethernet76 209,210,211,212 hundredGigE1/20 20 100000 +Ethernet80 229,230,231,232 hundredGigE1/21 21 100000 +Ethernet84 225,226,227,228 hundredGigE1/22 22 100000 +Ethernet88 245,246,247,248 hundredGigE1/23 23 100000 +Ethernet92 241,242,243,244 hundredGigE1/24 24 100000 +Ethernet96 149,150,151,152 hundredGigE1/25 25 100000 +Ethernet100 145,146,147,148 hundredGigE1/26 26 100000 +Ethernet104 165,166,167,168 hundredGigE1/27 27 100000 +Ethernet108 161,162,163,164 hundredGigE1/28 28 100000 +Ethernet112 181,182,183,184 hundredGigE1/29 29 100000 +Ethernet116 177,178,179,180 hundredGigE1/30 30 100000 +Ethernet120 197,198,199,200 hundredGigE1/31 31 100000 +Ethernet124 193,194,195,196 hundredGigE1/32 32 100000 +Ethernet128 61,62,63,64 hundredGigE1/33 33 100000 +Ethernet132 57,58,59,60 hundredGigE1/34 34 100000 +Ethernet136 77,78,79,80 hundredGigE1/35 35 100000 +Ethernet140 73,74,75,76 hundredGigE1/36 36 100000 +Ethernet144 93,94,95,96 hundredGigE1/37 37 100000 +Ethernet148 89,90,91,92 hundredGigE1/38 38 100000 +Ethernet152 109,110,111,112 hundredGigE1/39 39 100000 +Ethernet156 105,106,107,108 hundredGigE1/40 40 100000 +Ethernet160 13,14,15,16 hundredGigE1/41 41 100000 +Ethernet164 9,10,11,12 hundredGigE1/42 42 100000 +Ethernet168 29,30,31,32 hundredGigE1/43 43 100000 +Ethernet172 25,26,27,28 hundredGigE1/44 44 100000 +Ethernet176 45,46,47,48 hundredGigE1/45 45 100000 +Ethernet180 41,42,43,44 hundredGigE1/46 46 100000 +Ethernet184 125,126,127,128 hundredGigE1/47 47 100000 +Ethernet188 121,122,123,124 hundredGigE1/48 48 100000 +Ethernet192 137,138,139,140 hundredGigE1/49 49 100000 +Ethernet196 141,142,143,144 hundredGigE1/50 50 100000 +Ethernet200 217,218,219,220 hundredGigE1/51 51 100000 +Ethernet204 221,222,223,224 hundredGigE1/52 52 100000 +Ethernet208 233,234,235,236 hundredGigE1/53 53 100000 +Ethernet212 237,238,239,240 hundredGigE1/54 54 100000 +Ethernet216 249,250,251,252 hundredGigE1/55 55 100000 +Ethernet220 253,254,255,256 hundredGigE1/56 56 100000 +Ethernet224 153,154,155,156 hundredGigE1/57 57 100000 +Ethernet228 157,158,159,160 hundredGigE1/58 58 100000 +Ethernet232 169,170,171,172 hundredGigE1/59 59 100000 +Ethernet236 173,174,175,176 hundredGigE1/60 60 100000 +Ethernet240 185,186,187,188 hundredGigE1/61 61 100000 +Ethernet244 189,190,191,192 hundredGigE1/62 62 100000 +Ethernet248 201,202,203,204 hundredGigE1/63 63 100000 +Ethernet252 205,206,207,208 hundredGigE1/64 64 100000 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/port_config.ini b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/port_config.ini index 0f05a642c3f9..646d91492beb 100644 --- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/port_config.ini +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/port_config.ini @@ -1,65 +1,65 @@ -# name lanes alias index -Ethernet0 49,50,51,52 fortyGigE1/1 1 -Ethernet4 53,54,55,56 fortyGigE1/2 2 -Ethernet8 65,66,67,68 fortyGigE1/3 3 -Ethernet12 69,70,71,72 fortyGigE1/4 4 -Ethernet16 81,82,83,84 fortyGigE1/5 5 -Ethernet20 85,86,87,88 fortyGigE1/6 6 -Ethernet24 97,98,99,100 fortyGigE1/7 7 -Ethernet28 101,102,103,104 fortyGigE1/8 8 -Ethernet32 1,2,3,4 fortyGigE1/9 9 -Ethernet36 5,6,7,8 fortyGigE1/10 10 -Ethernet40 17,18,19,20 fortyGigE1/11 11 -Ethernet44 21,22,23,24 fortyGigE1/12 12 -Ethernet48 33,34,35,36 fortyGigE1/13 13 -Ethernet52 37,38,39,40 fortyGigE1/14 14 -Ethernet56 113,114,115,116 fortyGigE1/15 15 -Ethernet60 117,118,119,120 fortyGigE1/16 16 -Ethernet64 133,134,135,136 fortyGigE1/17 17 -Ethernet68 129,130,131,132 fortyGigE1/18 18 -Ethernet72 213,214,215,216 fortyGigE1/19 19 -Ethernet76 209,210,211,212 fortyGigE1/20 20 -Ethernet80 229,230,231,232 fortyGigE1/21 21 -Ethernet84 225,226,227,228 fortyGigE1/22 22 -Ethernet88 245,246,247,248 fortyGigE1/23 23 -Ethernet92 241,242,243,244 fortyGigE1/24 24 -Ethernet96 149,150,151,152 fortyGigE1/25 25 -Ethernet100 145,146,147,148 fortyGigE1/26 26 -Ethernet104 165,166,167,168 fortyGigE1/27 27 -Ethernet108 161,162,163,164 fortyGigE1/28 28 -Ethernet112 181,182,183,184 fortyGigE1/29 29 -Ethernet116 177,178,179,180 fortyGigE1/30 30 -Ethernet120 197,198,199,200 fortyGigE1/31 31 -Ethernet124 193,194,195,196 fortyGigE1/32 32 -Ethernet128 61,62,63,64 fortyGigE1/33 33 -Ethernet132 57,58,59,60 fortyGigE1/34 34 -Ethernet136 77,78,79,80 fortyGigE1/35 35 -Ethernet140 73,74,75,76 fortyGigE1/36 36 -Ethernet144 93,94,95,96 fortyGigE1/37 37 -Ethernet148 89,90,91,92 fortyGigE1/38 38 -Ethernet152 109,110,111,112 fortyGigE1/39 39 -Ethernet156 105,106,107,108 fortyGigE1/40 40 -Ethernet160 13,14,15,16 fortyGigE1/41 41 -Ethernet164 9,10,11,12 fortyGigE1/42 42 -Ethernet168 29,30,31,32 fortyGigE1/43 43 -Ethernet172 25,26,27,28 fortyGigE1/44 44 -Ethernet176 45,46,47,48 fortyGigE1/45 45 -Ethernet180 41,42,43,44 fortyGigE1/46 46 -Ethernet184 125,126,127,128 fortyGigE1/47 47 -Ethernet188 121,122,123,124 fortyGigE1/48 48 -Ethernet192 137,138,139,140 fortyGigE1/49 49 -Ethernet196 141,142,143,144 fortyGigE1/50 50 -Ethernet200 217,218,219,220 fortyGigE1/51 51 -Ethernet204 221,222,223,224 fortyGigE1/52 52 -Ethernet208 233,234,235,236 fortyGigE1/53 53 -Ethernet212 237,238,239,240 fortyGigE1/54 54 -Ethernet216 249,250,251,252 fortyGigE1/55 55 -Ethernet220 253,254,255,256 fortyGigE1/56 56 -Ethernet224 153,154,155,156 fortyGigE1/57 57 -Ethernet228 157,158,159,160 fortyGigE1/58 58 -Ethernet232 169,170,171,172 fortyGigE1/59 59 -Ethernet236 173,174,175,176 fortyGigE1/60 60 -Ethernet240 185,186,187,188 fortyGigE1/61 61 -Ethernet244 189,190,191,192 fortyGigE1/62 62 -Ethernet248 201,202,203,204 fortyGigE1/63 63 -Ethernet252 205,206,207,208 fortyGigE1/64 64 +# name lanes alias index speed +Ethernet0 49,50,51,52 fortyGigE1/1 1 40000 +Ethernet4 53,54,55,56 fortyGigE1/2 2 40000 +Ethernet8 65,66,67,68 fortyGigE1/3 3 40000 +Ethernet12 69,70,71,72 fortyGigE1/4 4 40000 +Ethernet16 81,82,83,84 fortyGigE1/5 5 40000 +Ethernet20 85,86,87,88 fortyGigE1/6 6 40000 +Ethernet24 97,98,99,100 fortyGigE1/7 7 40000 +Ethernet28 101,102,103,104 fortyGigE1/8 8 40000 +Ethernet32 1,2,3,4 fortyGigE1/9 9 40000 +Ethernet36 5,6,7,8 fortyGigE1/10 10 40000 +Ethernet40 17,18,19,20 fortyGigE1/11 11 40000 +Ethernet44 21,22,23,24 fortyGigE1/12 12 40000 +Ethernet48 33,34,35,36 fortyGigE1/13 13 40000 +Ethernet52 37,38,39,40 fortyGigE1/14 14 40000 +Ethernet56 113,114,115,116 fortyGigE1/15 15 40000 +Ethernet60 117,118,119,120 fortyGigE1/16 16 40000 +Ethernet64 133,134,135,136 fortyGigE1/17 17 40000 +Ethernet68 129,130,131,132 fortyGigE1/18 18 40000 +Ethernet72 213,214,215,216 fortyGigE1/19 19 40000 +Ethernet76 209,210,211,212 fortyGigE1/20 20 40000 +Ethernet80 229,230,231,232 fortyGigE1/21 21 40000 +Ethernet84 225,226,227,228 fortyGigE1/22 22 40000 +Ethernet88 245,246,247,248 fortyGigE1/23 23 40000 +Ethernet92 241,242,243,244 fortyGigE1/24 24 40000 +Ethernet96 149,150,151,152 fortyGigE1/25 25 40000 +Ethernet100 145,146,147,148 fortyGigE1/26 26 40000 +Ethernet104 165,166,167,168 fortyGigE1/27 27 40000 +Ethernet108 161,162,163,164 fortyGigE1/28 28 40000 +Ethernet112 181,182,183,184 fortyGigE1/29 29 40000 +Ethernet116 177,178,179,180 fortyGigE1/30 30 40000 +Ethernet120 197,198,199,200 fortyGigE1/31 31 40000 +Ethernet124 193,194,195,196 fortyGigE1/32 32 40000 +Ethernet128 61,62,63,64 fortyGigE1/33 33 40000 +Ethernet132 57,58,59,60 fortyGigE1/34 34 40000 +Ethernet136 77,78,79,80 fortyGigE1/35 35 40000 +Ethernet140 73,74,75,76 fortyGigE1/36 36 40000 +Ethernet144 93,94,95,96 fortyGigE1/37 37 40000 +Ethernet148 89,90,91,92 fortyGigE1/38 38 40000 +Ethernet152 109,110,111,112 fortyGigE1/39 39 40000 +Ethernet156 105,106,107,108 fortyGigE1/40 40 40000 +Ethernet160 13,14,15,16 fortyGigE1/41 41 40000 +Ethernet164 9,10,11,12 fortyGigE1/42 42 40000 +Ethernet168 29,30,31,32 fortyGigE1/43 43 40000 +Ethernet172 25,26,27,28 fortyGigE1/44 44 40000 +Ethernet176 45,46,47,48 fortyGigE1/45 45 40000 +Ethernet180 41,42,43,44 fortyGigE1/46 46 40000 +Ethernet184 125,126,127,128 fortyGigE1/47 47 40000 +Ethernet188 121,122,123,124 fortyGigE1/48 48 40000 +Ethernet192 137,138,139,140 fortyGigE1/49 49 40000 +Ethernet196 141,142,143,144 fortyGigE1/50 50 40000 +Ethernet200 217,218,219,220 fortyGigE1/51 51 40000 +Ethernet204 221,222,223,224 fortyGigE1/52 52 40000 +Ethernet208 233,234,235,236 fortyGigE1/53 53 40000 +Ethernet212 237,238,239,240 fortyGigE1/54 54 40000 +Ethernet216 249,250,251,252 fortyGigE1/55 55 40000 +Ethernet220 253,254,255,256 fortyGigE1/56 56 40000 +Ethernet224 153,154,155,156 fortyGigE1/57 57 40000 +Ethernet228 157,158,159,160 fortyGigE1/58 58 40000 +Ethernet232 169,170,171,172 fortyGigE1/59 59 40000 +Ethernet236 173,174,175,176 fortyGigE1/60 60 40000 +Ethernet240 185,186,187,188 fortyGigE1/61 61 40000 +Ethernet244 189,190,191,192 fortyGigE1/62 62 40000 +Ethernet248 201,202,203,204 fortyGigE1/63 63 40000 +Ethernet252 205,206,207,208 fortyGigE1/64 64 40000 From 60bd7417ea500feec47b59ef1eaafa37e14a887c Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Tue, 28 May 2019 23:30:57 +0800 Subject: [PATCH 81/88] [Mellanox] Update hw-mgmt package to v175 (#2948) * update hw-mgmt package to v175 * update sonic linux kernel to pick up kernel patch --- 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 f473d4da2319..e3bf43c33619 100644 --- a/platform/mellanox/hw-management.mk +++ b/platform/mellanox/hw-management.mk @@ -1,6 +1,6 @@ # Mellanox HW Management -MLNX_HW_MANAGEMENT_VERSION = 2.0.0.0172 +MLNX_HW_MANAGEMENT_VERSION = 2.0.0175 export MLNX_HW_MANAGEMENT_VERSION diff --git a/platform/mellanox/hw-management/hw-mgmt b/platform/mellanox/hw-management/hw-mgmt index 425a653ea0d7..f78e386382e5 160000 --- a/platform/mellanox/hw-management/hw-mgmt +++ b/platform/mellanox/hw-management/hw-mgmt @@ -1 +1 @@ -Subproject commit 425a653ea0d7b27d4502c3ebdc9bb720b6c34bee +Subproject commit f78e386382e5d857af7f69f4040918ffb6f20362 diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index 69ba0c13f6b9..6fc9850e83d0 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit 69ba0c13f6b984b554dd83fadfaace4e856239ae +Subproject commit 6fc9850e83d0cba3f8eff7c98ea371e131be8d8a From 81071ec461400833cf4539e644d971021e438aaf Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Tue, 28 May 2019 23:32:08 +0800 Subject: [PATCH 82/88] [mellanox]: fix wrong type of paramerter (#2950) --- platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd b/platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd index d5f53c1c710e..08d1f1188005 100644 --- a/platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd +++ b/platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd @@ -181,7 +181,7 @@ class MlnxSfpd: for port in port_list: log_info("SFP on port {} state {}".format(port, sfp_state)) - self.send_sfp_notification(port, sfp_state) + self.send_sfp_notification(str(port), sfp_state) self.update_sfpd_liveness_key(SFPD_LIVENESS_EXPIRE_SECS) From 10a6157c833b042329aa5e590f11b3d924c35520 Mon Sep 17 00:00:00 2001 From: Harish Venkatraman Date: Tue, 28 May 2019 08:42:23 -0700 Subject: [PATCH 83/88] [DellEMC-Z9264f-Q64] Add PFC support for 40G z9264f (#2940) This commit adds new code and JAON file to support PFC and MMU setting for PFC feature on z9264f-Q64 (40G) T0 and T1 support. The buffers_defaults_t0.json and buffers_defaults_t1.json file has the recommended values for T0 and T1 configuration. Unit tested and verified by running JSON file and checking the hardware registers and table in broadcom. THe settings in hardware are reflecting the JSON values. Signed-off-by: Harish Venkatraman --- .../DellEMC-Z9264f-Q64/buffers.json.j2 | 2 + .../DellEMC-Z9264f-Q64/buffers_defaults_t0.j2 | 47 +++++++++++++++++++ .../DellEMC-Z9264f-Q64/buffers_defaults_t1.j2 | 47 +++++++++++++++++++ .../DellEMC-Z9264f-Q64/pg_profile_lookup.ini | 17 +++++++ .../DellEMC-Z9264f-Q64/qos.json.j2 | 1 + 5 files changed, 114 insertions(+) create mode 100644 device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers.json.j2 create mode 100644 device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t0.j2 create mode 100644 device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t1.j2 create mode 100644 device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/pg_profile_lookup.ini create mode 100644 device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/qos.json.j2 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers.json.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..c3e8cbda67dd --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t0.j2 @@ -0,0 +1,47 @@ + +{%- 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": "38738752", + "type": "ingress", + "mode": "dynamic", + "xoff": "3855488" + }, + "egress_lossy_pool": { + "size": "37057280", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "43507776", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"10876944" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..a5322c73272d --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t1.j2 @@ -0,0 +1,47 @@ + +{%- set default_cable = '40m' %} + +{%- 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": "37968320", + "type": "ingress", + "mode": "dynamic", + "xoff": "4625920" + }, + "egress_lossy_pool": { + "size": "36402496", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "43507776", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"10876944" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/pg_profile_lookup.ini b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/pg_profile_lookup.ini new file mode 100644 index 000000000000..aedda37a8878 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1248 2288 35776 -3 2288 + 25000 5m 1248 2288 53248 -3 2288 + 40000 5m 1248 2288 66560 -3 2288 + 50000 5m 1248 2288 90272 -3 2288 + 100000 5m 1248 2288 165568 -3 2288 + 10000 40m 1248 2288 37024 -3 2288 + 25000 40m 1248 2288 53248 -3 2288 + 40000 40m 1248 2288 71552 -3 2288 + 50000 40m 1248 2288 96096 -3 2288 + 100000 40m 1248 2288 177632 -3 2288 + 10000 300m 1248 2288 46176 -3 2288 + 25000 300m 1248 2288 79040 -3 2288 + 40000 300m 1248 2288 108160 -3 2288 + 50000 300m 1248 2288 141856 -3 2288 + 100000 300m 1248 2288 268736 -3 2288 diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/qos.json.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} From df149cd1fc77e0e70bd1a11050af48a315a15b4c Mon Sep 17 00:00:00 2001 From: Phanindra TV <48400987+phanindra-tv@users.noreply.github.com> Date: Wed, 29 May 2019 11:13:04 +0530 Subject: [PATCH 84/88] [teamd]: Administratively shutdown port channel has member ports in deselected state and traffic is not forwarded. #1771 (#2882) --- ...-port-admin-down-recv-not-processing.patch | 22 +++++++++++++++++++ src/libteam/series | 1 + 2 files changed, 23 insertions(+) create mode 100644 src/libteam/0013-teamd-lacp-port-admin-down-recv-not-processing.patch diff --git a/src/libteam/0013-teamd-lacp-port-admin-down-recv-not-processing.patch b/src/libteam/0013-teamd-lacp-port-admin-down-recv-not-processing.patch new file mode 100644 index 000000000000..6e6c37e096fe --- /dev/null +++ b/src/libteam/0013-teamd-lacp-port-admin-down-recv-not-processing.patch @@ -0,0 +1,22 @@ +diff --git a/teamd/teamd_runner_lacp.c b/teamd/teamd_runner_lacp.c +index 4a3fe6b..19592c5 100644 +--- a/teamd/teamd_runner_lacp.c ++++ b/teamd/teamd_runner_lacp.c +@@ -1182,12 +1182,17 @@ static int lacpdu_recv(struct lacp_port *lacp_port) + struct lacpdu lacpdu; + struct sockaddr_ll ll_from; + int err; ++ bool admin_state; + + err = teamd_recvfrom(lacp_port->sock, &lacpdu, sizeof(lacpdu), 0, + (struct sockaddr *) &ll_from, sizeof(ll_from)); + if (err <= 0) + return err; + ++ admin_state = team_get_ifinfo_admin_state(lacp_port->ctx->ifinfo); ++ if (!admin_state) ++ return 0; ++ + return lacpdu_process(lacp_port, &lacpdu); + } + diff --git a/src/libteam/series b/src/libteam/series index e9ef676ce52a..76e5e8177ccd 100644 --- a/src/libteam/series +++ b/src/libteam/series @@ -7,3 +7,4 @@ 0010-teamd-lacp-update-port-state-according-to-partners-sy.patch 0011-libteam-resynchronize-ifinfo-after-lost-RTNLGRP_LINK-.patch 0012-teamd-do-not-process-lacpdu-before-the-port-ifinfo-i.patch +0013-teamd-lacp-port-admin-down-recv-not-processing.patch From 4d212debc7a646ffa61cca767e18d882daadb51d Mon Sep 17 00:00:00 2001 From: Roy Lee Date: Wed, 29 May 2019 13:44:32 +0800 Subject: [PATCH 85/88] [device][platform] add platform as5812-54x, accton. (#2889) * Add new device accton_as5812_54x. Signed-off-by: roy_lee * Rename 5812's config.bcm. Signed-off-by: roy_lee * Change fan module to support lm-sensors. Validate for thermal policy. Signed-off-by: roy_lee * Add bask reset and lpmode control of 6 QSFP ports. Signed-off-by: roy_lee * Get currect duty of fan for comparing. Instead of by stored duty from previous iteration. Signed-off-by: roy_lee * Roll back the mistakes to update mellanox submodules. Signed-off-by: roy_lee * Rollback for misoperation on submodule platform/p4/SAI-P4-BM. Signed-off-by: roy_lee * Change indexes of ports to start from 1, as them on the front panel. Add low-power mode control of the transciever's eeprom, follows SFF-8436. Signed-off-by: roy_lee --- .../Accton-AS5812-54X/port_config.ini | 73 + .../Accton-AS5812-54X/sai.profile | 1 + .../td2-as5812-72x10G.config.bcm | 148 ++ .../x86_64-accton_as5812_54x-r0/default_sku | 1 + .../installer.conf | 3 + .../led_proc_init.soc | 162 ++ .../plugins/eeprom.py | 24 + .../plugins/psuutil.py | 61 + .../plugins/sfputil.py | 311 ++++ platform/broadcom/one-image.mk | 1 + platform/broadcom/platform-modules-accton.mk | 6 + .../modules/i2c-mux-accton_as5712_54x_cpld.c | 245 ++- .../as5712-54x/utils/accton_as5712_monitor.py | 21 +- .../as5812-54x/classes/__init__.py | 0 .../as5812-54x/classes/fanutil.py | 238 +++ .../as5812-54x/classes/thermalutil.py | 121 ++ .../as5812-54x/modules/Makefile | 17 + .../modules/accton_as5812_54x_fan.c | 457 ++++++ .../modules/accton_as5812_54x_psu.c | 371 +++++ .../modules/accton_as5812_54x_sfp.c | 825 ++++++++++ .../as5812-54x/modules/cpr_4011_4mxx.c | 400 +++++ .../modules/i2c-mux-accton_as5812_54x_cpld.c | 1421 +++++++++++++++++ .../modules/leds-accton_as5812_54x.c | 594 +++++++ .../as5812-54x/modules/ym2651y.c | 683 ++++++++ .../service/as5812-platform-monitor.service | 17 + .../as5812-54x/setup.py | 16 + .../as5812-54x/utils/README | 117 ++ .../as5812-54x/utils/accton_as5812_monitor.py | 204 +++ .../as5812-54x/utils/accton_as5812_util.py | 686 ++++++++ .../debian/control | 3 + .../debian/rules | 2 +- 31 files changed, 7170 insertions(+), 59 deletions(-) create mode 100755 device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/port_config.ini create mode 100755 device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/sai.profile create mode 100644 device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/td2-as5812-72x10G.config.bcm create mode 100644 device/accton/x86_64-accton_as5812_54x-r0/default_sku create mode 100644 device/accton/x86_64-accton_as5812_54x-r0/installer.conf create mode 100644 device/accton/x86_64-accton_as5812_54x-r0/led_proc_init.soc create mode 100644 device/accton/x86_64-accton_as5812_54x-r0/plugins/eeprom.py create mode 100755 device/accton/x86_64-accton_as5812_54x-r0/plugins/psuutil.py create mode 100755 device/accton/x86_64-accton_as5812_54x-r0/plugins/sfputil.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5812-54x/classes/__init__.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5812-54x/classes/fanutil.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5812-54x/classes/thermalutil.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/accton_as5812_54x_fan.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/accton_as5812_54x_psu.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/accton_as5812_54x_sfp.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/cpr_4011_4mxx.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/i2c-mux-accton_as5812_54x_cpld.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/leds-accton_as5812_54x.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/ym2651y.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5812-54x/service/as5812-platform-monitor.service create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5812-54x/setup.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/README create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_monitor.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_util.py diff --git a/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/port_config.ini b/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/port_config.ini new file mode 100755 index 000000000000..315fd86981e1 --- /dev/null +++ b/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/port_config.ini @@ -0,0 +1,73 @@ +# name lanes alias index +Ethernet0 13 tenGigE0 1 +Ethernet1 14 tenGigE1 2 +Ethernet2 15 tenGigE2 3 +Ethernet3 16 tenGigE3 4 +Ethernet4 21 tenGigE4 5 +Ethernet5 22 tenGigE5 6 +Ethernet6 23 tenGigE6 7 +Ethernet7 24 tenGigE7 8 +Ethernet8 25 tenGigE8 9 +Ethernet9 26 tenGigE9 10 +Ethernet10 27 tenGigE10 11 +Ethernet11 28 tenGigE11 12 +Ethernet12 29 tenGigE12 13 +Ethernet13 30 tenGigE13 14 +Ethernet14 31 tenGigE14 15 +Ethernet15 32 tenGigE15 16 +Ethernet16 45 tenGigE16 17 +Ethernet17 46 tenGigE17 18 +Ethernet18 47 tenGigE18 19 +Ethernet19 48 tenGigE19 20 +Ethernet20 49 tenGigE20 21 +Ethernet21 50 tenGigE21 22 +Ethernet22 51 tenGigE22 23 +Ethernet23 52 tenGigE23 24 +Ethernet24 53 tenGigE24 25 +Ethernet25 54 tenGigE25 26 +Ethernet26 55 tenGigE26 27 +Ethernet27 56 tenGigE27 28 +Ethernet28 57 tenGigE28 29 +Ethernet29 58 tenGigE29 30 +Ethernet30 59 tenGigE30 31 +Ethernet31 60 tenGigE31 32 +Ethernet32 61 tenGigE32 33 +Ethernet33 62 tenGigE33 34 +Ethernet34 63 tenGigE34 35 +Ethernet35 64 tenGigE35 36 +Ethernet36 65 tenGigE36 37 +Ethernet37 66 tenGigE37 38 +Ethernet38 67 tenGigE38 39 +Ethernet39 68 tenGigE39 40 +Ethernet40 69 tenGigE40 41 +Ethernet41 70 tenGigE41 42 +Ethernet42 71 tenGigE42 43 +Ethernet43 72 tenGigE43 44 +Ethernet44 73 tenGigE44 45 +Ethernet45 74 tenGigE45 46 +Ethernet46 75 tenGigE46 47 +Ethernet47 76 tenGigE47 48 +Ethernet48 97 tenGigE48 49 +Ethernet49 98 tenGigE49 50 +Ethernet50 99 tenGigE50 51 +Ethernet51 100 tenGigE51 52 +Ethernet52 101 tenGigE52 53 +Ethernet53 102 tenGigE53 54 +Ethernet54 103 tenGigE54 55 +Ethernet55 104 tenGigE55 56 +Ethernet56 81 tenGigE56 57 +Ethernet57 82 tenGigE57 58 +Ethernet58 83 tenGigE58 59 +Ethernet59 84 tenGigE59 60 +Ethernet60 105 tenGigE60 61 +Ethernet61 106 tenGigE61 62 +Ethernet62 107 tenGigE62 63 +Ethernet63 108 tenGigE63 64 +Ethernet64 109 tenGigE64 65 +Ethernet65 110 tenGigE65 66 +Ethernet66 111 tenGigE66 67 +Ethernet67 112 tenGigE67 68 +Ethernet68 77 tenGigE68 69 +Ethernet69 78 tenGigE69 70 +Ethernet70 79 tenGigE70 71 +EthernEt71 80 tenGigE71 72 diff --git a/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/sai.profile b/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/sai.profile new file mode 100755 index 000000000000..063814c1fcb3 --- /dev/null +++ b/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-as5812-72x10G.config.bcm diff --git a/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/td2-as5812-72x10G.config.bcm b/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/td2-as5812-72x10G.config.bcm new file mode 100644 index 000000000000..4844616d0382 --- /dev/null +++ b/device/accton/x86_64-accton_as5812_54x-r0/Accton-AS5812-54X/td2-as5812-72x10G.config.bcm @@ -0,0 +1,148 @@ +os=unix +bcm_stat_flags=0 +parity_enable=0 +parity_correction=0 + +bcm_num_cos=8 +l2_mem_entries=32768 +l3_mem_entries=16384 +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 + +mmu_lossless=0 +lls_num_l2uc=12 +module_64ports=0 + +#SFI +serdes_if_type=9 + +port_init_cl72=0 +phy_an_c73=5 # TSCMOD_CL73_CL37 + +#sdk6.5.5 only supports 156(default) or 125 +#xgxs_lcpll_xtal_refclk=1 +tslam_dma_enable=1 +table_dma_enable=1 + +#for 72 ports with 48 10G ports and 6 40G ports for breakout mode +pbmp_oversubscribe=0x1fffffffffffffffffe +pbmp_xport_xe=0x1fffffffffffffffffe + +rate_ext_mdio_divisor=96 + +#SFP+ 1-4 from WC3 +portmap_1=13:10 +portmap_2=14:10 +portmap_3=15:10 +portmap_4=16:10 + +#SFP+ 5-8 from WC5 +portmap_5=21:10 +portmap_6=22:10 +portmap_7=23:10 +portmap_8=24:10 + +#SFP+ 9-12 from WC6 +portmap_9=25:10 +portmap_10=26:10 +portmap_11=27:10 +portmap_12=28:10 + +#SFP+ 13-16 from WC7 +portmap_13=29:10 +portmap_14=30:10 +portmap_15=31:10 +portmap_16=32:10 + +#SFP+ 17-20 from WC11 +portmap_17=45:10 +portmap_18=46:10 +portmap_19=47:10 +portmap_20=48:10 + +#SFP+ 21-24 from WC12 +portmap_21=49:10 +portmap_22=50:10 +portmap_23=51:10 +portmap_24=52:10 + +#SFP+ 25-28 from WC13 +portmap_25=53:10 +portmap_26=54:10 +portmap_27=55:10 +portmap_28=56:10 + +#SFP+ 29-32 from WC14 +portmap_29=57:10 +portmap_30=58:10 +portmap_31=59:10 +portmap_32=60:10 + +#SFP+ 33-36 from WC15 +portmap_33=61:10 +portmap_34=62:10 +portmap_35=63:10 +portmap_36=64:10 + +#SFP+ 37-40 from WC16 +portmap_37=65:10 +portmap_38=66:10 +portmap_39=67:10 +portmap_40=68:10 + +#SFP+ 41-44 from WC17 +portmap_41=69:10 +portmap_42=70:10 +portmap_43=71:10 +portmap_44=72:10 + +#SFP+ 45-48 from WC18 +portmap_45=73:10 +portmap_46=74:10 +portmap_47=75:10 +portmap_48=76:10 + +# QSFP+ 49/WC24/port 49 +portmap_49=97:10 +portmap_50=98:10 +portmap_51=99:10 +portmap_52=100:10 + +# QSFP+ 51/WC25/port 50 +portmap_53=101:10 +portmap_54=102:10 +portmap_55=103:10 +portmap_56=104:10 + +# QSFP+ 53/WC20/port 51 +portmap_57=81:10 +portmap_58=82:10 +portmap_59=83:10 +portmap_60=84:10 + +# QSFP+ 50/WC26/port 52 +portmap_61=105:10 +portmap_62=106:10 +portmap_63=107:10 +portmap_64=108:10 + +# QSFP+ 52/WC27/port 53 +portmap_65=109:10 +portmap_66=110:10 +portmap_67=111:10 +portmap_68=112:10 + +# QSFP+ 54/WC19/port 54 +portmap_69=77:10 +portmap_70=78:10 +portmap_71=79:10 +portmap_72=80:10 + +# L3 ECMP +# - In Trident2, VP LAGs share the same table as ECMP group table. +# The first N entries are reserved for VP LAGs, where N is the value of the +# config property "max_vp_lags". By default this was set to 256 +l3_max_ecmp_mode=1 +max_vp_lags=0 + +stable_size=0x2000000 diff --git a/device/accton/x86_64-accton_as5812_54x-r0/default_sku b/device/accton/x86_64-accton_as5812_54x-r0/default_sku new file mode 100644 index 000000000000..b52f97504176 --- /dev/null +++ b/device/accton/x86_64-accton_as5812_54x-r0/default_sku @@ -0,0 +1 @@ +Accton-AS5812-54X t1 diff --git a/device/accton/x86_64-accton_as5812_54x-r0/installer.conf b/device/accton/x86_64-accton_as5812_54x-r0/installer.conf new file mode 100644 index 000000000000..14404194ef53 --- /dev/null +++ b/device/accton/x86_64-accton_as5812_54x-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_PORT=0x2f8 +CONSOLE_DEV=1 +CONSOLE_SPEED=115200 diff --git a/device/accton/x86_64-accton_as5812_54x-r0/led_proc_init.soc b/device/accton/x86_64-accton_as5812_54x-r0/led_proc_init.soc new file mode 100644 index 000000000000..d93e373d0567 --- /dev/null +++ b/device/accton/x86_64-accton_as5812_54x-r0/led_proc_init.soc @@ -0,0 +1,162 @@ +# LED setting for active +# ----------------------------------------------------------------------------- +# for as5812_54x (48xg+6qxg) +# +# on green - if link up +# off - if link down +# blink - if active +# ----------------------------------------------------------------------------- +m CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 REMAP_PORT_63=0 +m CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 REMAP_PORT_62=1 +m CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 REMAP_PORT_61=2 +m CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=3 +m CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 REMAP_PORT_59=4 +m CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 REMAP_PORT_58=5 +m CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 REMAP_PORT_57=6 +m CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=7 +m CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 REMAP_PORT_55=8 +m CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 REMAP_PORT_54=9 +m CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 REMAP_PORT_53=10 +m CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=11 +m CMIC_LEDUP0_PORT_ORDER_REMAP_48_51 REMAP_PORT_51=12 +m CMIC_LEDUP0_PORT_ORDER_REMAP_48_51 REMAP_PORT_50=13 +m CMIC_LEDUP0_PORT_ORDER_REMAP_48_51 REMAP_PORT_49=14 +m CMIC_LEDUP0_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=15 +m CMIC_LEDUP0_PORT_ORDER_REMAP_32_35 REMAP_PORT_35=16 +m CMIC_LEDUP0_PORT_ORDER_REMAP_32_35 REMAP_PORT_34=17 +m CMIC_LEDUP0_PORT_ORDER_REMAP_32_35 REMAP_PORT_33=18 +m CMIC_LEDUP0_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=19 +m CMIC_LEDUP0_PORT_ORDER_REMAP_36_39 REMAP_PORT_39=20 +m CMIC_LEDUP0_PORT_ORDER_REMAP_36_39 REMAP_PORT_38=21 +m CMIC_LEDUP0_PORT_ORDER_REMAP_36_39 REMAP_PORT_37=22 +m CMIC_LEDUP0_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=23 +m CMIC_LEDUP0_PORT_ORDER_REMAP_40_43 REMAP_PORT_43=24 +m CMIC_LEDUP0_PORT_ORDER_REMAP_40_43 REMAP_PORT_42=25 +m CMIC_LEDUP0_PORT_ORDER_REMAP_40_43 REMAP_PORT_41=26 +m CMIC_LEDUP0_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=27 +m CMIC_LEDUP0_PORT_ORDER_REMAP_44_47 REMAP_PORT_47=28 +m CMIC_LEDUP0_PORT_ORDER_REMAP_44_47 REMAP_PORT_46=29 +m CMIC_LEDUP0_PORT_ORDER_REMAP_44_47 REMAP_PORT_45=30 +m CMIC_LEDUP0_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=31 +m CMIC_LEDUP0_PORT_ORDER_REMAP_28_31 REMAP_PORT_31=32 +m CMIC_LEDUP0_PORT_ORDER_REMAP_28_31 REMAP_PORT_30=33 +m CMIC_LEDUP0_PORT_ORDER_REMAP_28_31 REMAP_PORT_29=34 +m CMIC_LEDUP0_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=35 +m CMIC_LEDUP0_PORT_ORDER_REMAP_24_27 REMAP_PORT_27=36 +m CMIC_LEDUP0_PORT_ORDER_REMAP_24_27 REMAP_PORT_26=37 +m CMIC_LEDUP0_PORT_ORDER_REMAP_24_27 REMAP_PORT_25=38 +m CMIC_LEDUP0_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=39 +m CMIC_LEDUP0_PORT_ORDER_REMAP_20_23 REMAP_PORT_23=40 +m CMIC_LEDUP0_PORT_ORDER_REMAP_20_23 REMAP_PORT_22=41 +m CMIC_LEDUP0_PORT_ORDER_REMAP_20_23 REMAP_PORT_21=42 +m CMIC_LEDUP0_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=43 +m CMIC_LEDUP0_PORT_ORDER_REMAP_16_19 REMAP_PORT_19=44 +m CMIC_LEDUP0_PORT_ORDER_REMAP_16_19 REMAP_PORT_18=45 +m CMIC_LEDUP0_PORT_ORDER_REMAP_16_19 REMAP_PORT_17=46 +m CMIC_LEDUP0_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=47 +m CMIC_LEDUP0_PORT_ORDER_REMAP_0_3 REMAP_PORT_3=48 +m CMIC_LEDUP0_PORT_ORDER_REMAP_0_3 REMAP_PORT_2=49 +m CMIC_LEDUP0_PORT_ORDER_REMAP_0_3 REMAP_PORT_1=50 +m CMIC_LEDUP0_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=51 +m CMIC_LEDUP0_PORT_ORDER_REMAP_4_7 REMAP_PORT_7=52 +m CMIC_LEDUP0_PORT_ORDER_REMAP_4_7 REMAP_PORT_6=53 +m CMIC_LEDUP0_PORT_ORDER_REMAP_4_7 REMAP_PORT_5=54 +m CMIC_LEDUP0_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=55 +m CMIC_LEDUP0_PORT_ORDER_REMAP_8_11 REMAP_PORT_11=56 +m CMIC_LEDUP0_PORT_ORDER_REMAP_8_11 REMAP_PORT_10=57 +m CMIC_LEDUP0_PORT_ORDER_REMAP_8_11 REMAP_PORT_9=58 +m CMIC_LEDUP0_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=59 +m CMIC_LEDUP0_PORT_ORDER_REMAP_12_15 REMAP_PORT_15=60 +m CMIC_LEDUP0_PORT_ORDER_REMAP_12_15 REMAP_PORT_14=61 +m CMIC_LEDUP0_PORT_ORDER_REMAP_12_15 REMAP_PORT_13=62 +m CMIC_LEDUP0_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=63 +m CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 REMAP_PORT_63=0 +m CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 REMAP_PORT_62=1 +m CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 REMAP_PORT_61=2 +m CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=3 +m CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 REMAP_PORT_59=4 +m CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 REMAP_PORT_58=5 +m CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 REMAP_PORT_57=6 +m CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=7 +m CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 REMAP_PORT_55=8 +m CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 REMAP_PORT_54=9 +m CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 REMAP_PORT_53=10 +m CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=11 +m CMIC_LEDUP1_PORT_ORDER_REMAP_48_51 REMAP_PORT_51=12 +m CMIC_LEDUP1_PORT_ORDER_REMAP_48_51 REMAP_PORT_50=13 +m CMIC_LEDUP1_PORT_ORDER_REMAP_48_51 REMAP_PORT_49=14 +m CMIC_LEDUP1_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=15 +m CMIC_LEDUP1_PORT_ORDER_REMAP_32_35 REMAP_PORT_35=16 +m CMIC_LEDUP1_PORT_ORDER_REMAP_32_35 REMAP_PORT_34=17 +m CMIC_LEDUP1_PORT_ORDER_REMAP_32_35 REMAP_PORT_33=18 +m CMIC_LEDUP1_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=19 +m CMIC_LEDUP1_PORT_ORDER_REMAP_36_39 REMAP_PORT_39=20 +m CMIC_LEDUP1_PORT_ORDER_REMAP_36_39 REMAP_PORT_38=21 +m CMIC_LEDUP1_PORT_ORDER_REMAP_36_39 REMAP_PORT_37=22 +m CMIC_LEDUP1_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=23 +m CMIC_LEDUP1_PORT_ORDER_REMAP_40_43 REMAP_PORT_43=24 +m CMIC_LEDUP1_PORT_ORDER_REMAP_40_43 REMAP_PORT_42=25 +m CMIC_LEDUP1_PORT_ORDER_REMAP_40_43 REMAP_PORT_41=26 +m CMIC_LEDUP1_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=27 +m CMIC_LEDUP1_PORT_ORDER_REMAP_44_47 REMAP_PORT_47=28 +m CMIC_LEDUP1_PORT_ORDER_REMAP_44_47 REMAP_PORT_46=29 +m CMIC_LEDUP1_PORT_ORDER_REMAP_44_47 REMAP_PORT_45=30 +m CMIC_LEDUP1_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=31 +m CMIC_LEDUP1_PORT_ORDER_REMAP_28_31 REMAP_PORT_31=32 +m CMIC_LEDUP1_PORT_ORDER_REMAP_28_31 REMAP_PORT_30=33 +m CMIC_LEDUP1_PORT_ORDER_REMAP_28_31 REMAP_PORT_29=34 +m CMIC_LEDUP1_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=35 +m CMIC_LEDUP1_PORT_ORDER_REMAP_24_27 REMAP_PORT_27=36 +m CMIC_LEDUP1_PORT_ORDER_REMAP_24_27 REMAP_PORT_26=37 +m CMIC_LEDUP1_PORT_ORDER_REMAP_24_27 REMAP_PORT_25=38 +m CMIC_LEDUP1_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=39 +m CMIC_LEDUP1_PORT_ORDER_REMAP_20_23 REMAP_PORT_23=40 +m CMIC_LEDUP1_PORT_ORDER_REMAP_20_23 REMAP_PORT_22=41 +m CMIC_LEDUP1_PORT_ORDER_REMAP_20_23 REMAP_PORT_21=42 +m CMIC_LEDUP1_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=43 +m CMIC_LEDUP1_PORT_ORDER_REMAP_16_19 REMAP_PORT_19=44 +m CMIC_LEDUP1_PORT_ORDER_REMAP_16_19 REMAP_PORT_18=45 +m CMIC_LEDUP1_PORT_ORDER_REMAP_16_19 REMAP_PORT_17=46 +m CMIC_LEDUP1_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=47 +m CMIC_LEDUP1_PORT_ORDER_REMAP_0_3 REMAP_PORT_3=48 +m CMIC_LEDUP1_PORT_ORDER_REMAP_0_3 REMAP_PORT_2=49 +m CMIC_LEDUP1_PORT_ORDER_REMAP_0_3 REMAP_PORT_1=50 +m CMIC_LEDUP1_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=51 +m CMIC_LEDUP1_PORT_ORDER_REMAP_4_7 REMAP_PORT_7=52 +m CMIC_LEDUP1_PORT_ORDER_REMAP_4_7 REMAP_PORT_6=53 +m CMIC_LEDUP1_PORT_ORDER_REMAP_4_7 REMAP_PORT_5=54 +m CMIC_LEDUP1_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=55 +m CMIC_LEDUP1_PORT_ORDER_REMAP_8_11 REMAP_PORT_11=56 +m CMIC_LEDUP1_PORT_ORDER_REMAP_8_11 REMAP_PORT_10=57 +m CMIC_LEDUP1_PORT_ORDER_REMAP_8_11 REMAP_PORT_9=58 +m CMIC_LEDUP1_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=59 +m CMIC_LEDUP1_PORT_ORDER_REMAP_12_15 REMAP_PORT_15=60 +m CMIC_LEDUP1_PORT_ORDER_REMAP_12_15 REMAP_PORT_14=61 +m CMIC_LEDUP1_PORT_ORDER_REMAP_12_15 REMAP_PORT_13=62 +m CMIC_LEDUP1_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=63 + +led 0 stop +led 0 prog \ + 06 FE 80 D2 19 71 08 E0 60 FE E9 D2 0F 75 10 81 \ + 61 FD 02 3F 60 FF 28 32 0F 87 67 4A 96 FF 06 FF \ + D2 2B 74 16 02 1F 60 FF 28 32 0F 87 67 4A 96 FF \ + 06 FF D2 13 74 28 02 0F 60 FF 28 32 0F 87 67 4A \ + 96 FF 06 FF D2 0B 74 3A 3A 48 32 07 32 08 C7 32 \ + 04 C7 97 71 57 77 69 32 00 32 01 B7 97 71 63 32 \ + 0E 77 6B 26 FD 97 27 77 6B 32 0F 87 57 00 00 00 +led 0 start + +led 1 stop +led 1 prog \ + 06 FE 80 D2 19 71 08 E0 60 FE E9 D2 0F 75 10 81 \ + 61 FD 02 20 67 89 02 24 67 89 02 10 67 89 02 28 \ + 67 89 02 2C 67 89 02 0C 67 89 02 2C 67 79 02 28 \ + 67 79 02 24 67 79 02 20 67 79 02 10 67 79 02 0C \ + 67 79 02 0B 60 FF 28 32 0F 87 67 56 96 FF 06 FF \ + D2 FF 74 46 3A 36 32 07 32 08 C7 32 04 C7 97 71 \ + 63 77 75 32 00 32 01 B7 97 71 6F 32 0E 77 77 26 \ + FD 97 27 77 77 32 0F 87 57 12 A0 F8 15 1A 01 75 \ + 85 28 67 56 57 32 0F 87 57 12 A0 F8 15 1A 01 71 \ + A1 28 67 56 80 28 67 56 80 28 67 56 80 28 67 56 \ + 57 32 0F 87 32 0F 87 32 0F 87 32 0F 87 57 00 00 +led 1 start diff --git a/device/accton/x86_64-accton_as5812_54x-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as5812_54x-r0/plugins/eeprom.py new file mode 100644 index 000000000000..7681caafeef4 --- /dev/null +++ b/device/accton/x86_64-accton_as5812_54x-r0/plugins/eeprom.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +try: + import exceptions + import binascii + import time + import optparse + import warnings + import os + import sys + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + import subprocess +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/bus/i2c/devices/1-0057/eeprom" + #Two i2c buses might get flipped order, check them both. + if not os.path.exists(self.eeprom_path): + self.eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as5812_54x-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as5812_54x-r0/plugins/psuutil.py new file mode 100755 index 000000000000..841070637b3e --- /dev/null +++ b/device/accton/x86_64-accton_as5812_54x-r0/plugins/psuutil.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python + +############################################################################# +# Accton +# +# Module contains an implementation of SONiC PSU Base API and +# provides the PSUs status which are available in the platform +# +############################################################################# + +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + self.psu_path = "/sys/bus/i2c/devices/" + self.psu_presence = "/psu_present" + self.psu_oper_status = "/psu_power_good" + self.psu_mapping = { + 1: "57-0038", + 2: "58-003b", + } + + def get_num_psus(self): + return len(self.psu_mapping) + + def get_psu_status(self, index): + if index is None: + return False + + status = 0 + node = self.psu_path + self.psu_mapping[index]+self.psu_oper_status + try: + with open(node, 'r') as power_status: + status = int(power_status.read()) + except IOError: + return False + + return status == 1 + + def get_psu_presence(self, index): + if index is None: + return False + + status = 0 + node = self.psu_path + self.psu_mapping[index] + self.psu_presence + try: + with open(node, 'r') as presence_status: + status = int(presence_status.read()) + except IOError: + return False + + return status == 1 diff --git a/device/accton/x86_64-accton_as5812_54x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as5812_54x-r0/plugins/sfputil.py new file mode 100755 index 000000000000..0200aa14499e --- /dev/null +++ b/device/accton/x86_64-accton_as5812_54x-r0/plugins/sfputil.py @@ -0,0 +1,311 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# +try: + import time + import os + import pickle + from ctypes import create_string_buffer + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 1 + PORT_END = 72 + PORTS_IN_BLOCK = 72 + QSFP_PORT_START = 48 + QSFP_PORT_END = 72 + + BASE_VAL_PATH = "/sys/class/i2c-adapter/i2c-{0}/{1}-0050/" + BASE_OOM_PATH = "/sys/bus/i2c/devices/{0}-0050/" + BASE_CPLD2_PATH = "/sys/bus/i2c/devices/{0}-0061/" + BASE_CPLD3_PATH = "/sys/bus/i2c/devices/{0}-0062/" + I2C_BUS_ORDER = -1 + + #The sidebands of QSFP is different. + #present is in-order. + #But lp_mode and reset are not. + qsfp_sb_map = [1, 3, 5, 2, 4, 6] + + _port_to_is_present = {} + _port_to_lp_mode = {} + + _port_to_eeprom_mapping = {} + _port_to_i2c_mapping = { + 1: [1, 2], + 2: [2, 3], + 3: [3, 4], + 4: [4, 5], + 5: [5, 6], + 6: [6, 7], + 7: [7, 8], + 8: [8, 9], + 9: [9, 10], + 10: [10, 11], + 11: [11, 12], + 12: [12, 13], + 13: [13, 14], + 14: [14, 15], + 15: [15, 16], + 16: [16, 17], + 17: [17, 18], + 18: [18, 19], + 19: [19, 20], + 20: [20, 21], + 21: [21, 22], + 22: [22, 23], + 23: [23, 24], + 24: [24, 25], + 25: [25, 26], + 26: [26, 27], + 27: [27, 28], + 28: [28, 29], + 29: [29, 30], + 30: [30, 31], + 31: [31, 32], + 32: [32, 33], + 33: [33, 34], + 34: [34, 35], + 35: [35, 36], + 36: [36, 37], + 37: [37, 38], + 38: [38, 39], + 39: [39, 40], + 40: [40, 41], + 41: [41, 42], + 42: [42, 43], + 43: [43, 44], + 44: [44, 45], + 45: [45, 46], + 46: [46, 47], + 47: [47, 48], + 48: [48, 49], + 49: [49, 50],#QSFP49 + 50: [49, 50], + 51: [49, 50], + 52: [49, 50], + 53: [50, 52],#QSFP50 + 54: [50, 52], + 55: [50, 52], + 56: [50, 52], + 57: [51, 54],#QSFP51 + 58: [51, 54], + 59: [51, 54], + 60: [51, 54], + 61: [52, 51],#QSFP52 + 62: [52, 51], + 63: [52, 51], + 64: [52, 51], + 65: [53, 53],#QSFP53 + 66: [53, 53], + 67: [53, 53], + 68: [53, 53], + 69: [54, 55],#QSFP54 + 70: [54, 55], + 71: [54, 55], + 72: [54, 55], + } + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_port_start(self): + return self.QSFP_PORT_START + + @property + def qsfp_port_end(self): + return self.QSFP_PORT_END + + @property + def qsfp_ports(self): + return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + eeprom_path = self.BASE_OOM_PATH + "eeprom" + + for x in range(self.port_start, self.port_end+1): + self.port_to_eeprom_mapping[x] = eeprom_path.format( + self._port_to_i2c_mapping[x][1] + ) + + SfpUtilBase.__init__(self) + + #Two i2c buses might get flipped order, check them both. + def update_i2c_order(self): + if os.path.exists("/tmp/accton_util.p"): + self.I2C_BUS_ORDER = pickle.load(open("/tmp/accton_util.p", "rb")) + else: + if self.I2C_BUS_ORDER < 0: + eeprom_path = "/sys/bus/i2c/devices/1-0057/eeprom" + if os.path.exists(eeprom_path): + self.I2C_BUS_ORDER = 0 + eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" + if os.path.exists(eeprom_path): + self.I2C_BUS_ORDER = 1 + return self.I2C_BUS_ORDER + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + order = self.update_i2c_order() + if port_num <= 24: + present_path = self.BASE_CPLD2_PATH.format(order) + else: + present_path = self.BASE_CPLD3_PATH.format(order) + + present_path = present_path + "module_present_" + str(self._port_to_i2c_mapping[port_num][0]) + self.__port_to_is_present = present_path + + try: + val_file = open(self.__port_to_is_present) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = val_file.readline().rstrip() + val_file.close() + + # content is a string, either "0" or "1" + if content == "1": + return True + + return False + + def qsfp_sb_remap(self, port_num): + qsfp_start = self.qsfp_port_start + qsfp_index = self._port_to_i2c_mapping[port_num][0] - qsfp_start + qsfp_index = self.qsfp_sb_map[qsfp_index-1] + return qsfp_start+qsfp_index + + def get_low_power_mode_cpld(self, port_num): + if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: + return False + + order = self.update_i2c_order() + lp_mode_path = self.BASE_CPLD3_PATH.format(order) + lp_mode_path = lp_mode_path + "module_lp_mode_" + q = self.qsfp_sb_remap(port_num) + lp_mode_path = lp_mode_path + str(q) + + try: + val_file = open(lp_mode_path) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = val_file.readline().rstrip() + val_file.close() + + # content is a string, either "0" or "1" + if content == "1": + return True + + return False + + def get_low_power_mode(self, port_num): + if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: + return False + + if not self.get_presence(port_num): + return self.get_low_power_mode_cpld(port_num) + + try: + eeprom = None + + eeprom = open(self.port_to_eeprom_mapping[port_num], "rb") + eeprom.seek(93) + lpmode = ord(eeprom.read(1)) + + if not (lpmode & 0x1): # 'Power override' bit is 0 + return self.get_low_power_mode_cpld(port_num) + else: + if ((lpmode & 0x2) == 0x2): + return True # Low Power Mode if "Power set" bit is 1 + else: + return False # High Power Mode if "Power set" bit is 0 + except IOError as err: + print "Error: unable to open file: %s" % str(err) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + def set_low_power_mode(self, port_num, lpmode): + if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: + return False + + try: + eeprom = None + + if not self.get_presence(port_num): + return False # Port is not present, unable to set the eeprom + + # Fill in write buffer + regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode + buffer = create_string_buffer(1) + buffer[0] = chr(regval) + + # Write to eeprom + eeprom = open(self.port_to_eeprom_mapping[port_num], "r+b") + eeprom.seek(93) + eeprom.write(buffer[0]) + return True + except IOError as err: + print "Error: unable to open file: %s" % str(err) + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + def reset(self, port_num): + if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: + return False + + order = self.update_i2c_order() + lp_mode_path = self.BASE_CPLD3_PATH.format(order) + mod_rst_path = lp_mode_path + "module_reset_" + q = self.qsfp_sb_remap(port_num) + mod_rst_path = mod_rst_path + str(q) + + try: + reg_file = open(mod_rst_path, 'r+') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + #toggle reset + reg_file.seek(0) + reg_file.write('0') + time.sleep(1) + reg_file.seek(0) + reg_file.write('1') + reg_file.close() + return True + + def get_transceiver_change_event(self): + """ + TODO: This function need to be implemented + when decide to support monitoring SFP(Xcvrd) + on this platform. + """ + raise NotImplementedError + diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index fe4d1be96adc..24cdd64c57b2 100755 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -24,6 +24,7 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(ACCTON_AS7726_32X_PLATFORM_MODULE) \ $(ACCTON_AS4630_54PE_PLATFORM_MODULE) \ $(ACCTON_MINIPACK_PLATFORM_MODULE) \ + $(ACCTON_AS5812_54X_PLATFORM_MODULE) \ $(INVENTEC_D7032Q28B_PLATFORM_MODULE) \ $(INVENTEC_D7054Q28B_PLATFORM_MODULE) \ $(INVENTEC_D7264Q28B_PLATFORM_MODULE) \ diff --git a/platform/broadcom/platform-modules-accton.mk b/platform/broadcom/platform-modules-accton.mk index db169a1fe14c..397b38cb0c34 100755 --- a/platform/broadcom/platform-modules-accton.mk +++ b/platform/broadcom/platform-modules-accton.mk @@ -11,6 +11,7 @@ ACCTON_AS6712_32X_PLATFORM_MODULE_VERSION = 1.1 ACCTON_AS7726_32X_PLATFORM_MODULE_VERSION = 1.1 ACCTON_AS4630_54PE_PLATFORM_MODULE_VERSION = 1.1 ACCTON_MINIPACK_PLATFORM_MODULE_VERSION = 1.1 +ACCTON_AS5812_54X_PLATFORM_MODULE_VERSION = 1.1 export ACCTON_AS7712_32X_PLATFORM_MODULE_VERSION export ACCTON_AS5712_54X_PLATFORM_MODULE_VERSION @@ -23,6 +24,7 @@ export ACCTON_AS6712_32X_PLATFORM_MODULE_VERSION export ACCTON_AS7726_32X_PLATFORM_MODULE_VERSION export ACCTON_AS4630_54PE_PLATFORM_MODULE_VERSION export ACCTON_MINIPACK_PLATFORM_MODULE_VERSION +export ACCTON_AS5812_54X_PLATFORM_MODULE_VERSION ACCTON_AS7712_32X_PLATFORM_MODULE = sonic-platform-accton-as7712-32x_$(ACCTON_AS7712_32X_PLATFORM_MODULE_VERSION)_amd64.deb $(ACCTON_AS7712_32X_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-accton @@ -71,4 +73,8 @@ ACCTON_MINIPACK_PLATFORM_MODULE = sonic-platform-accton-minipack_$(ACCTON_MINIPA $(ACCTON_MINIPACK_PLATFORM_MODULE)_PLATFORM = x86_64-accton_minipack-r0 $(eval $(call add_extra_package,$(ACCTON_AS7712_32X_PLATFORM_MODULE),$(ACCTON_MINIPACK_PLATFORM_MODULE))) +ACCTON_AS5812_54X_PLATFORM_MODULE = sonic-platform-accton-as5812-54x_$(ACCTON_AS5812_54X_PLATFORM_MODULE_VERSION)_amd64.deb +$(ACCTON_AS5812_54X_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as5812_54x-r0 +$(eval $(call add_extra_package,$(ACCTON_AS7712_32X_PLATFORM_MODULE),$(ACCTON_AS5812_54X_PLATFORM_MODULE))) + SONIC_STRETCH_DEBS += $(ACCTON_AS7712_32X_PLATFORM_MODULE) diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/i2c-mux-accton_as5712_54x_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/i2c-mux-accton_as5712_54x_cpld.c index ed097e6b30e8..9dbac9ca337e 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/i2c-mux-accton_as5712_54x_cpld.c +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/i2c-mux-accton_as5712_54x_cpld.c @@ -37,6 +37,7 @@ #include #include #include +#include #define I2C_RW_RETRY_COUNT 10 #define I2C_RW_RETRY_INTERVAL 60 /* ms */ @@ -78,16 +79,16 @@ struct chip_desc { /* Provide specs for the PCA954x types we know about */ static const struct chip_desc chips[] = { [as5712_54x_cpld1] = { - .nchans = NUM_OF_CPLD1_CHANS, - .deselectChan = CPLD_DESELECT_CHANNEL, + .nchans = NUM_OF_CPLD1_CHANS, + .deselectChan = CPLD_DESELECT_CHANNEL, }, [as5712_54x_cpld2] = { - .nchans = NUM_OF_CPLD2_CHANS, - .deselectChan = CPLD_DESELECT_CHANNEL, + .nchans = NUM_OF_CPLD2_CHANS, + .deselectChan = CPLD_DESELECT_CHANNEL, }, [as5712_54x_cpld3] = { - .nchans = NUM_OF_CPLD3_CHANS, - .deselectChan = CPLD_DESELECT_CHANNEL, + .nchans = NUM_OF_CPLD3_CHANS, + .deselectChan = CPLD_DESELECT_CHANNEL, } }; @@ -103,6 +104,8 @@ MODULE_DEVICE_TABLE(i2c, as5712_54x_cpld_mux_id); #define TRANSCEIVER_TXDISABLE_ATTR_ID(index) MODULE_TXDISABLE_##index #define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index #define TRANSCEIVER_TXFAULT_ATTR_ID(index) MODULE_TXFAULT_##index +#define TRANSCEIVER_LPMODE_ATTR_ID(index) MODULE_LPMODE_##index +#define TRANSCEIVER_RESET_ATTR_ID(index) MODULE_RESET_##index enum as5712_54x_cpld1_sysfs_attributes { CPLD_VERSION, @@ -308,22 +311,38 @@ enum as5712_54x_cpld1_sysfs_attributes { TRANSCEIVER_TXFAULT_ATTR_ID(46), TRANSCEIVER_TXFAULT_ATTR_ID(47), TRANSCEIVER_TXFAULT_ATTR_ID(48), + TRANSCEIVER_LPMODE_ATTR_ID(49), + TRANSCEIVER_LPMODE_ATTR_ID(50), + TRANSCEIVER_LPMODE_ATTR_ID(51), + TRANSCEIVER_LPMODE_ATTR_ID(52), + TRANSCEIVER_LPMODE_ATTR_ID(53), + TRANSCEIVER_LPMODE_ATTR_ID(54), + TRANSCEIVER_RESET_ATTR_ID(49), + TRANSCEIVER_RESET_ATTR_ID(50), + TRANSCEIVER_RESET_ATTR_ID(51), + TRANSCEIVER_RESET_ATTR_ID(52), + TRANSCEIVER_RESET_ATTR_ID(53), + TRANSCEIVER_RESET_ATTR_ID(54), }; -/* sysfs attributes for hwmon +/* sysfs attributes for hwmon */ static ssize_t show_status(struct device *dev, struct device_attribute *da, - char *buf); + char *buf); static ssize_t show_present_all(struct device *dev, struct device_attribute *da, - char *buf); + char *buf); static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, - char *buf); + char *buf); static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); + const char *buf, size_t count); +static ssize_t set_lp_mode(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); static ssize_t access(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); + const char *buf, size_t count); static ssize_t show_version(struct device *dev, struct device_attribute *da, - char *buf); + char *buf); static int as5712_54x_cpld_read_internal(struct i2c_client *client, u8 reg); static int as5712_54x_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value); @@ -336,11 +355,21 @@ static int as5712_54x_cpld_write_internal(struct i2c_client *client, u8 reg, u8 static SENSOR_DEVICE_ATTR(module_tx_disable_##index, S_IRUGO | S_IWUSR, show_status, set_tx_disable, MODULE_TXDISABLE_##index); \ static SENSOR_DEVICE_ATTR(module_rx_los_##index, S_IRUGO, show_status, NULL, MODULE_RXLOS_##index); \ static SENSOR_DEVICE_ATTR(module_tx_fault_##index, S_IRUGO, show_status, NULL, MODULE_TXFAULT_##index) + #define DECLARE_SFP_TRANSCEIVER_ATTR(index) \ &sensor_dev_attr_module_tx_disable_##index.dev_attr.attr, \ &sensor_dev_attr_module_rx_los_##index.dev_attr.attr, \ &sensor_dev_attr_module_tx_fault_##index.dev_attr.attr +#define DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_lp_mode_##index, S_IRUGO | S_IWUSR, show_status, set_lp_mode, MODULE_LPMODE_##index); \ + static SENSOR_DEVICE_ATTR(module_reset_##index, S_IWUSR | S_IRUGO, show_status, set_mode_reset, MODULE_RESET_##index) + +#define DECLARE_QSFP_TRANSCEIVER_ATTR(index) \ + &sensor_dev_attr_module_lp_mode_##index.dev_attr.attr, \ + &sensor_dev_attr_module_reset_##index.dev_attr.attr + + static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION); static SENSOR_DEVICE_ATTR(access, S_IWUSR, NULL, access, ACCESS); /* transceiver attributes */ @@ -449,6 +478,12 @@ DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(45); DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(46); DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(47); DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(48); +DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(49); +DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(50); +DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(51); +DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(52); +DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(53); +DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(54); static struct attribute *as5712_54x_cpld1_attributes[] = { &sensor_dev_attr_version.dev_attr.attr, @@ -581,6 +616,12 @@ static struct attribute *as5712_54x_cpld3_attributes[] = { DECLARE_SFP_TRANSCEIVER_ATTR(46), DECLARE_SFP_TRANSCEIVER_ATTR(47), DECLARE_SFP_TRANSCEIVER_ATTR(48), + DECLARE_QSFP_TRANSCEIVER_ATTR(49), + DECLARE_QSFP_TRANSCEIVER_ATTR(50), + DECLARE_QSFP_TRANSCEIVER_ATTR(51), + DECLARE_QSFP_TRANSCEIVER_ATTR(52), + DECLARE_QSFP_TRANSCEIVER_ATTR(53), + DECLARE_QSFP_TRANSCEIVER_ATTR(54), NULL }; @@ -589,7 +630,7 @@ static const struct attribute_group as5712_54x_cpld3_group = { }; static ssize_t show_present_all(struct device *dev, struct device_attribute *da, - char *buf) + char *buf) { int i, status, num_regs = 0; u8 values[4] = {0}; @@ -604,7 +645,7 @@ static ssize_t show_present_all(struct device *dev, struct device_attribute *da, for (i = 0; i < num_regs; i++) { status = as5712_54x_cpld_read_internal(client, regs[i]); - + if (status < 0) { goto exit; } @@ -617,12 +658,12 @@ static ssize_t show_present_all(struct device *dev, struct device_attribute *da, /* Return values 1 -> 54 in order */ if (data->type == as5712_54x_cpld2) { status = sprintf(buf, "%.2x %.2x %.2x\n", - values[0], values[1], values[2]); + values[0], values[1], values[2]); } else { /* as5712_54x_cpld3 */ values[3] &= 0x3F; status = sprintf(buf, "%.2x %.2x %.2x %.2x\n", - values[0], values[1], values[2], values[3]); + values[0], values[1], values[2], values[3]); } return status; @@ -633,7 +674,7 @@ static ssize_t show_present_all(struct device *dev, struct device_attribute *da, } static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, - char *buf) + char *buf) { int i, status; u8 values[3] = {0}; @@ -646,7 +687,7 @@ static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, for (i = 0; i < ARRAY_SIZE(regs); i++) { status = as5712_54x_cpld_read_internal(client, regs[i]); - + if (status < 0) { goto exit; } @@ -665,7 +706,7 @@ static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, } static ssize_t show_status(struct device *dev, struct device_attribute *da, - char *buf) + char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct i2c_client *client = to_i2c_client(dev); @@ -795,6 +836,14 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, reg = 0x11; mask = 0x1 << (attr->index - MODULE_RXLOS_41); break; + case MODULE_LPMODE_49 ... MODULE_LPMODE_54: + reg = 0x16; + mask = 0x1 << (attr->index - MODULE_LPMODE_49); + break; + case MODULE_RESET_49 ... MODULE_RESET_54: + reg = 0x15; + mask = 0x1 << (attr->index - MODULE_RESET_49); + break; default: return 0; } @@ -818,7 +867,7 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, } static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) + const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct i2c_client *client = to_i2c_client(dev); @@ -881,17 +930,119 @@ static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, if (unlikely(status < 0)) { goto exit; } - + + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t set_lp_mode(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc); + + long on; + int status= -ENOENT; + u8 reg = 0x16, mask = 0; + + if(attr->index < MODULE_LPMODE_49 || attr->index > MODULE_LPMODE_54) + return status; + + status = kstrtol(buf, 10, &on); + if (status) { + return status; + } + + /* Read current status */ + mutex_lock(&data->update_lock); + status = as5712_54x_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + + mask = 0x1 << (attr->index - MODULE_LPMODE_49); + + /* Update lp_mode status */ + if (on) { + status |= mask; + } + else { + status &= ~mask; + } + + status = as5712_54x_cpld_write_internal(client, reg, status); + if (unlikely(status < 0)) { + goto exit; + } + + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; + +} + +static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc); + + long on; + int status= -ENOENT; + u8 reg = 0x15, mask = 0; + + if(attr->index < MODULE_RESET_49 || attr->index > MODULE_RESET_54) + return status; + + status = kstrtol(buf, 10, &on); + if (status) { + return status; + } + + /* Read current status */ + mutex_lock(&data->update_lock); + status = as5712_54x_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + + mask = 0x1 << (attr->index - MODULE_RESET_49); + + /* Update tx_disable status */ + if (on) { + status |= mask; + } + else { + status &= ~mask; + } + + status = as5712_54x_cpld_write_internal(client, reg, status); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); return count; exit: mutex_unlock(&data->update_lock); return status; + } static ssize_t access(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct i2c_mux_core *muxc = i2c_get_clientdata(client); @@ -923,7 +1074,7 @@ static ssize_t access(struct device *dev, struct device_attribute *da, /* Write to mux register. Don't use i2c_transfer()/i2c_smbus_xfer() for this as they will try to lock adapter a second time */ static int as5712_54x_cpld_mux_reg_write(struct i2c_adapter *adap, - struct i2c_client *client, u8 val) + struct i2c_client *client, u8 val) { unsigned long orig_jiffies; unsigned short flags; @@ -939,22 +1090,22 @@ static int as5712_54x_cpld_mux_reg_write(struct i2c_adapter *adap, /* Retry automatically on arbitration loss */ orig_jiffies = jiffies; for (res = 0, try = 0; try <= adap->retries; try++) { - res = adap->algo->smbus_xfer(adap, client->addr, flags, - I2C_SMBUS_WRITE, CPLD_CHANNEL_SELECT_REG, - I2C_SMBUS_BYTE_DATA, &data); - if (res != -EAGAIN) - break; - if (time_after(jiffies, - orig_jiffies + adap->timeout)) - break; - } + res = adap->algo->smbus_xfer(adap, client->addr, flags, + I2C_SMBUS_WRITE, CPLD_CHANNEL_SELECT_REG, + I2C_SMBUS_BYTE_DATA, &data); + if (res != -EAGAIN) + break; + if (time_after(jiffies, + orig_jiffies + adap->timeout)) + break; + } } return res; } -static int as5712_54x_cpld_mux_select_chan(struct i2c_mux_core *muxc, - u32 chan) +static int as5712_54x_cpld_mux_select_chan(struct i2c_mux_core *muxc, + u32 chan) { struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc); struct i2c_client *client = data->client; @@ -972,7 +1123,7 @@ static int as5712_54x_cpld_mux_select_chan(struct i2c_mux_core *muxc, } static int as5712_54x_cpld_mux_deselect_mux(struct i2c_mux_core *muxc, - u32 chan) + u32 chan) { struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc); struct i2c_client *client = data->client; @@ -1028,13 +1179,13 @@ static ssize_t show_version(struct device *dev, struct device_attribute *attr, c { int val = 0; struct i2c_client *client = to_i2c_client(dev); - + val = i2c_smbus_read_byte_data(client, 0x1); if (val < 0) { dev_dbg(&client->dev, "cpld(0x%x) reg(0x1) err %d\n", client->addr, val); } - + return sprintf(buf, "%d", val); } @@ -1042,7 +1193,7 @@ static ssize_t show_version(struct device *dev, struct device_attribute *attr, c * I2C init/probing/exit functions */ static int as5712_54x_cpld_mux_probe(struct i2c_client *client, - const struct i2c_device_id *id) + const struct i2c_device_id *id) { struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); int num, force, class; @@ -1055,8 +1206,8 @@ static int as5712_54x_cpld_mux_probe(struct i2c_client *client, return -ENODEV; muxc = i2c_mux_alloc(adap, &client->dev, - chips[id->driver_data].nchans, sizeof(*data), 0, - as5712_54x_cpld_mux_select_chan, as5712_54x_cpld_mux_deselect_mux); + chips[id->driver_data].nchans, sizeof(*data), 0, + as5712_54x_cpld_mux_select_chan, as5712_54x_cpld_mux_deselect_mux); if (!muxc) return -ENOMEM; @@ -1076,8 +1227,8 @@ static int as5712_54x_cpld_mux_probe(struct i2c_client *client, if (ret) { dev_err(&client->dev, - "failed to register multiplexed adapter" - " %d as bus %d\n", num, force); + "failed to register multiplexed adapter" + " %d as bus %d\n", num, force); goto add_mux_failed; } } @@ -1099,7 +1250,7 @@ static int as5712_54x_cpld_mux_probe(struct i2c_client *client, default: break; } - + if (group) { ret = sysfs_create_group(&client->dev.kobj, group); if (ret) { @@ -1109,12 +1260,12 @@ static int as5712_54x_cpld_mux_probe(struct i2c_client *client, if (chips[data->type].nchans) { dev_info(&client->dev, - "registered %d multiplexed busses for I2C %s\n", - num, client->name); + "registered %d multiplexed busses for I2C %s\n", + num, client->name); } else { dev_info(&client->dev, - "device %s registered\n", client->name); + "device %s registered\n", client->name); } as5712_54x_cpld_add_client(client); diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py index d7b372145827..09b2b9ea96bd 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright (C) 2017 Accton Technology Corporation +# Copyright (C) 2019 Accton Technology Corporation # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -19,7 +19,7 @@ # HISTORY: # mm/dd/yyyy (A.D.) # 11/13/2017: Polly Hsu, Create -# +# 05/08/2019: Roy Lee, changed for as5712-54x. # ------------------------------------------------------------------ try: @@ -53,7 +53,6 @@ class accton_as5712_monitor(object): # static temp var _ori_temp = 0 _new_perc = 0 - _ori_perc = 0 def __init__(self, log_file, log_level): """Needs a logger and a logger level.""" @@ -77,9 +76,9 @@ def __init__(self, log_file, log_level): logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level) def manage_fans(self): - FAN_LEV1_UP_TEMP = 57500 # temperature + FAN_LEV1_UP_TEMP = 57700 # temperature FAN_LEV1_DOWN_TEMP = 0 # unused - FAN_LEV1_SPEED_PERC = 100 # percentage*/ + FAN_LEV1_SPEED_PERC = DUTY_MAX # percentage*/ FAN_LEV2_UP_TEMP = 53000 FAN_LEV2_DOWN_TEMP = 52700 @@ -151,8 +150,9 @@ def manage_fans(self): self._new_perc = FAN_LEV1_SPEED_PERC logging.debug('INFO. SET. FAN_SPEED as %d (new THERMAL temp:%d)', self._new_perc, new_temp) - if self._ori_perc == self._new_perc: - logging.debug('INFO. RETURN. FAN speed not changed. %d / %d (new_perc / ori_perc)', self._new_perc, self._ori_perc) + cur_perc = fan.get_fan_duty_cycle(fan.get_idx_fan_start()) + if cur_perc == self._new_perc: + logging.debug('INFO. RETURN. FAN speed not changed. %d / %d (new_perc / ori_perc)', self._new_perc, cur_perc) return True set_stat = fan.set_fan_duty_cycle(fan.get_idx_fan_start(), self._new_perc) @@ -161,10 +161,9 @@ def manage_fans(self): else: logging.debug('INFO: FAIL. set_fan_duty_cycle (%d)', self._new_perc) - logging.debug('INFO: GET. ori_perc is %d. ori_temp is %d', self._ori_perc, self._ori_temp) - self._ori_perc = self._new_perc + logging.debug('INFO: GET. ori_perc is %d. ori_temp is %d', cur_perc, self._ori_temp) self._ori_temp = new_temp - logging.debug('INFO: UPDATE. ori_perc to %d. ori_temp to %d', self._ori_perc, self._ori_temp) + logging.debug('INFO: UPDATE. ori_perc to %d. ori_temp to %d', cur_perc, self._ori_temp) return True @@ -199,7 +198,7 @@ def main(argv): # Loop forever, doing something useful hopefully: while True: monitor.manage_fans() - time.sleep(1) + time.sleep(10) if __name__ == '__main__': main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/classes/__init__.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/classes/__init__.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/classes/fanutil.py new file mode 100755 index 000000000000..efb21b9a4516 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/classes/fanutil.py @@ -0,0 +1,238 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# +# ------------------------------------------------------------------ + +try: + import time + import logging + from collections import namedtuple +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + + +class FanUtil(object): + """Platform-specific FanUtil class""" + + FAN_NUM_ON_MAIN_BROAD = 5 + FAN_NUM_1_IDX = 1 + FAN_NUM_2_IDX = 2 + FAN_NUM_3_IDX = 3 + FAN_NUM_4_IDX = 4 + FAN_NUM_5_IDX = 5 + + FAN_NODE_NUM_OF_MAP = 6 + FAN_NODE_FAULT_IDX_OF_MAP = 1 + FAN_NODE_SPEED_IDX_OF_MAP = 2 + FAN_NODE_DIR_IDX_OF_MAP = 3 + FAN_NODE_DUTY_IDX_OF_MAP = 4 + FANR_NODE_FAULT_IDX_OF_MAP = 5 + FANR_NODE_SPEED_IDX_OF_MAP = 6 + + BASE_VAL_PATH = '/sys/devices/platform/as5812_54x_fan/{0}' + + #logfile = '' + #loglevel = logging.INFO + + """ Dictionary where + key1 = fan id index (integer) starting from 1 + key2 = fan node index (interger) starting from 1 + value = path to fan device file (string) """ + _fan_to_device_path_mapping = {} + + _fan_to_device_node_mapping = { + (FAN_NUM_1_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan1_fault', + (FAN_NUM_1_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan1_speed_rpm', + (FAN_NUM_1_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan1_direction', + (FAN_NUM_1_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan1_duty_cycle_percentage', + (FAN_NUM_1_IDX, FANR_NODE_FAULT_IDX_OF_MAP): 'fanr1_fault', + (FAN_NUM_1_IDX, FANR_NODE_SPEED_IDX_OF_MAP): 'fanr1_speed_rpm', + + (FAN_NUM_2_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan2_fault', + (FAN_NUM_2_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan2_speed_rpm', + (FAN_NUM_2_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan2_direction', + (FAN_NUM_2_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan2_duty_cycle_percentage', + (FAN_NUM_2_IDX, FANR_NODE_FAULT_IDX_OF_MAP): 'fanr2_fault', + (FAN_NUM_2_IDX, FANR_NODE_SPEED_IDX_OF_MAP): 'fanr2_speed_rpm', + + (FAN_NUM_3_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan3_fault', + (FAN_NUM_3_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan3_speed_rpm', + (FAN_NUM_3_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan3_direction', + (FAN_NUM_3_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan3_duty_cycle_percentage', + (FAN_NUM_3_IDX, FANR_NODE_FAULT_IDX_OF_MAP): 'fanr3_fault', + (FAN_NUM_3_IDX, FANR_NODE_SPEED_IDX_OF_MAP): 'fanr3_speed_rpm', + + (FAN_NUM_4_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan4_fault', + (FAN_NUM_4_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan4_speed_rpm', + (FAN_NUM_4_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan4_direction', + (FAN_NUM_4_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan4_duty_cycle_percentage', + (FAN_NUM_4_IDX, FANR_NODE_FAULT_IDX_OF_MAP): 'fanr4_fault', + (FAN_NUM_4_IDX, FANR_NODE_SPEED_IDX_OF_MAP): 'fanr4_speed_rpm', + + (FAN_NUM_5_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan5_fault', + (FAN_NUM_5_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan5_speed_rpm', + (FAN_NUM_5_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan5_direction', + (FAN_NUM_5_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan5_duty_cycle_percentage', + (FAN_NUM_5_IDX, FANR_NODE_FAULT_IDX_OF_MAP): 'fanr5_fault', + (FAN_NUM_5_IDX, FANR_NODE_SPEED_IDX_OF_MAP): 'fanr5_speed_rpm', + } + + def _get_fan_to_device_node(self, fan_num, node_num): + return self._fan_to_device_node_mapping[(fan_num, node_num)] + + def _get_fan_node_val(self, fan_num, node_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num:%d', fan_num) + return None + + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + logging.debug('GET. Parameter error. node_num:%d', node_num) + return None + + device_path = self.get_fan_to_device_path(fan_num, node_num) + try: + val_file = open(device_path, 'r') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return int(content) + + def _set_fan_node_val(self, fan_num, node_num, val): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num:%d', fan_num) + return None + + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + logging.debug('GET. Parameter error. node_num:%d', node_num) + return None + + content = str(val) + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + device_path = self.get_fan_to_device_path(fan_num, node_num) + try: + val_file = open(device_path, 'w') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + val_file.write(content) + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return True + + def __init__(self): + fan_path = self.BASE_VAL_PATH + + for fan_num in range(self.FAN_NUM_1_IDX, self.FAN_NUM_ON_MAIN_BROAD+1): + for node_num in range(self.FAN_NODE_FAULT_IDX_OF_MAP, self.FAN_NODE_NUM_OF_MAP+1): + self._fan_to_device_path_mapping[(fan_num, node_num)] = fan_path.format( + self._fan_to_device_node_mapping[(fan_num, node_num)]) + + def get_num_fans(self): + return self.FAN_NUM_ON_MAIN_BROAD + + def get_idx_fan_start(self): + return self.FAN_NUM_1_IDX + + def get_num_nodes(self): + return self.FAN_NODE_NUM_OF_MAP + + def get_idx_node_start(self): + return self.FAN_NODE_FAULT_IDX_OF_MAP + + def get_size_node_map(self): + return len(self._fan_to_device_node_mapping) + + def get_size_path_map(self): + return len(self._fan_to_device_path_mapping) + + def get_fan_to_device_path(self, fan_num, node_num): + return self._fan_to_device_path_mapping[(fan_num, node_num)] + + def get_fan_fault(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_FAULT_IDX_OF_MAP) + + def get_fan_speed(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_SPEED_IDX_OF_MAP) + + def get_fan_dir(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_DIR_IDX_OF_MAP) + + def get_fan_duty_cycle(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_DUTY_IDX_OF_MAP) + + def set_fan_duty_cycle(self, fan_num, val): + return self._set_fan_node_val(fan_num, self.FAN_NODE_DUTY_IDX_OF_MAP, val) + + def get_fanr_fault(self, fan_num): + return self._get_fan_node_val(fan_num, self.FANR_NODE_FAULT_IDX_OF_MAP) + + def get_fanr_speed(self, fan_num): + return self._get_fan_node_val(fan_num, self.FANR_NODE_SPEED_IDX_OF_MAP) + + def get_fan_status(self, fan_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num, %d', fan_num) + return None + + if self.get_fan_fault(fan_num) is not None and self.get_fan_fault(fan_num) > 0: + logging.debug('GET. FAN fault. fan_num, %d', fan_num) + return False + + if self.get_fanr_fault(fan_num) is not None and self.get_fanr_fault(fan_num) > 0: + logging.debug('GET. FANR fault. fan_num, %d', fan_num) + return False + + return True + +#def main(): +# fan = FanUtil() +# +# print 'get_size_node_map : %d' % fan.get_size_node_map() +# print 'get_size_path_map : %d' % fan.get_size_path_map() +# for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): +# for y in range(fan.get_idx_node_start(), fan.get_num_nodes()+1): +# print fan.get_fan_to_device_path(x, y) +# +#if __name__ == '__main__': +# main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/classes/thermalutil.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/classes/thermalutil.py new file mode 100755 index 000000000000..5b8f890e8819 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/classes/thermalutil.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# +# ------------------------------------------------------------------ + +try: + import time + import logging + import glob + from collections import namedtuple +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + + +class ThermalUtil(object): + """Platform-specific ThermalUtil class""" + + THERMAL_NUM_ON_MAIN_BROAD = 3 + THERMAL_NUM_1_IDX = 1 # 1_ON_MAIN_BROAD + THERMAL_NUM_2_IDX = 2 # 2_ON_MAIN_BROAD + THERMAL_NUM_3_IDX = 3 # 3_ON_MAIN_BROAD + + BASE_VAL_PATH = '/sys/bus/i2c/devices/{0}-00{1}/hwmon/hwmon*/temp1_input' + + """ Dictionary where + key1 = thermal id index (integer) starting from 1 + value = path to fan device file (string) """ + _thermal_to_device_path_mapping = {} + + _thermal_to_device_node_mapping = { + THERMAL_NUM_1_IDX: ['61', '48'], + THERMAL_NUM_2_IDX: ['62', '49'], + THERMAL_NUM_3_IDX: ['63', '4a'], + } + + def __init__(self): + thermal_path = self.BASE_VAL_PATH + + for x in range(self.THERMAL_NUM_1_IDX, self.THERMAL_NUM_ON_MAIN_BROAD+1): + self._thermal_to_device_path_mapping[x] = thermal_path.format( + self._thermal_to_device_node_mapping[x][0], + self._thermal_to_device_node_mapping[x][1]) + + def _get_thermal_node_val(self, thermal_num): + if thermal_num < self.THERMAL_NUM_1_IDX or thermal_num > self.THERMAL_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. thermal_num, %d', thermal_num) + return None + + device_path = self.get_thermal_to_device_path(thermal_num) + for filename in glob.glob(device_path): + try: + val_file = open(filename, 'r') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return int(content) + + + def get_num_thermals(self): + return self.THERMAL_NUM_ON_MAIN_BROAD + + def get_idx_thermal_start(self): + return self.THERMAL_NUM_1_IDX + + def get_size_node_map(self): + return len(self._thermal_to_device_node_mapping) + + def get_size_path_map(self): + return len(self._thermal_to_device_path_mapping) + + def get_thermal_to_device_path(self, thermal_num): + return self._thermal_to_device_path_mapping[thermal_num] + + def get_thermal_1_val(self): + return self._get_thermal_node_val(self.THERMAL_NUM_1_IDX) + + def get_thermal_2_val(self): + return self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) + +#def main(): +# thermal = ThermalUtil() +# +# print 'get_size_node_map : %d' % thermal.get_size_node_map() +# print 'get_size_path_map : %d' % thermal.get_size_path_map() +# for x in range(thermal.get_idx_thermal_start(), thermal.get_num_thermals()+1): +# print thermal.get_thermal_to_device_path(x) +# +#if __name__ == '__main__': +# main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/Makefile b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/Makefile new file mode 100755 index 000000000000..ba91f25f2430 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/Makefile @@ -0,0 +1,17 @@ +ifneq ($(KERNELRELEASE),) +obj-m:= i2c-mux-accton_as5812_54x_cpld.o \ + accton_as5812_54x_fan.o leds-accton_as5812_54x.o accton_as5812_54x_psu.o \ + cpr_4011_4mxx.o ym2651y.o + +else +ifeq (,$(KERNEL_SRC)) +$(error KERNEL_SRC is not defined) +else +KERNELDIR:=$(KERNEL_SRC) +endif +PWD:=$(shell pwd) +default: + $(MAKE) -C $(KERNELDIR) M=$(PWD) modules +clean: + rm -rf *.o *.mod.o *.mod.o *.ko .*cmd .tmp_versions Module.markers Module.symvers modules.order +endif diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/accton_as5812_54x_fan.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/accton_as5812_54x_fan.c new file mode 100644 index 000000000000..deeabde23b28 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/accton_as5812_54x_fan.c @@ -0,0 +1,457 @@ +/* + * A hwmon driver for the Accton as5710 54x fan contrl + * + * Copyright (C) 2013 Accton Technology Corporation. + * Brandon Chuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "as5812_54x_fan" + +#define FAN_MAX_NUMBER 5 +#define FAN_SPEED_CPLD_TO_RPM_STEP 150 +#define FAN_SPEED_PRECENT_TO_CPLD_STEP 5 +#define FAN_DUTY_CYCLE_MIN 0 /* 10% ??*/ +#define FAN_DUTY_CYCLE_MAX 100 /* 100% */ + +#define CPLD_REG_FAN_STATUS_OFFSET 0xC +#define CPLD_REG_FANR_STATUS_OFFSET 0x1F +#define CPLD_REG_FAN_DIRECTION_OFFSET 0x1E + +#define CPLD_FAN1_REG_SPEED_OFFSET 0x10 +#define CPLD_FAN2_REG_SPEED_OFFSET 0x11 +#define CPLD_FAN3_REG_SPEED_OFFSET 0x12 +#define CPLD_FAN4_REG_SPEED_OFFSET 0x13 +#define CPLD_FAN5_REG_SPEED_OFFSET 0x14 + +#define CPLD_FANR1_REG_SPEED_OFFSET 0x18 +#define CPLD_FANR2_REG_SPEED_OFFSET 0x19 +#define CPLD_FANR3_REG_SPEED_OFFSET 0x1A +#define CPLD_FANR4_REG_SPEED_OFFSET 0x1B +#define CPLD_FANR5_REG_SPEED_OFFSET 0x1C + +#define CPLD_REG_FAN_PWM_CYCLE_OFFSET 0xD + +#define CPLD_FAN1_INFO_BIT_MASK 0x1 +#define CPLD_FAN2_INFO_BIT_MASK 0x2 +#define CPLD_FAN3_INFO_BIT_MASK 0x4 +#define CPLD_FAN4_INFO_BIT_MASK 0x8 +#define CPLD_FAN5_INFO_BIT_MASK 0x10 + +#define PROJECT_NAME + +#define LOCAL_DEBUG 0 + +static struct accton_as5812_54x_fan *fan_data = NULL; + +struct accton_as5812_54x_fan { + struct platform_device *pdev; + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status[FAN_MAX_NUMBER]; /* inner first fan status */ + u32 speed[FAN_MAX_NUMBER]; /* inner first fan speed */ + u8 direction[FAN_MAX_NUMBER]; /* reconrd the direction of inner first and second fans */ + u32 duty_cycle[FAN_MAX_NUMBER]; /* control the speed of inner first and second fans */ + u8 r_status[FAN_MAX_NUMBER]; /* inner second fan status */ + u32 r_speed[FAN_MAX_NUMBER]; /* inner second fan speed */ +}; + +/*******************/ +#define MAKE_FAN_MASK_OR_REG(name,type) \ + CPLD_FAN##type##1_##name, \ + CPLD_FAN##type##2_##name, \ + CPLD_FAN##type##3_##name, \ + CPLD_FAN##type##4_##name, \ + CPLD_FAN##type##5_##name, + +/* fan related data + */ +static const u8 fan_info_mask[] = { + MAKE_FAN_MASK_OR_REG(INFO_BIT_MASK,) +}; + +static const u8 fan_speed_reg[] = { + MAKE_FAN_MASK_OR_REG(REG_SPEED_OFFSET,) +}; + +static const u8 fanr_speed_reg[] = { + MAKE_FAN_MASK_OR_REG(REG_SPEED_OFFSET,R) +}; + +/*******************/ +#define DEF_FAN_SET(id) \ + FAN##id##_FAULT, \ + FAN##id##_SPEED, \ + FAN##id##_DUTY_CYCLE, \ + FAN##id##_DIRECTION, \ + FANR##id##_FAULT, \ + FANR##id##_SPEED, + +enum sysfs_fan_attributes { + DEF_FAN_SET(1) + DEF_FAN_SET(2) + DEF_FAN_SET(3) + DEF_FAN_SET(4) + DEF_FAN_SET(5) +}; +/*******************/ +static void accton_as5812_54x_fan_update_device(struct device *dev); +static int accton_as5812_54x_fan_read_value(u8 reg); +static int accton_as5812_54x_fan_write_value(u8 reg, u8 value); + +static ssize_t fan_set_duty_cycle(struct device *dev, + struct device_attribute *da,const char *buf, size_t count); +static ssize_t fan_show_value(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t show_name(struct device *dev, + struct device_attribute *da, char *buf); + +extern int as5812_54x_cpld_read(unsigned short cpld_addr, u8 reg); +extern int as5812_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + + +/*******************/ +#define _MAKE_SENSOR_DEVICE_ATTR(prj, id, id2) \ + static SENSOR_DEVICE_ATTR(prj##fan##id##_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##id##_SPEED); \ + static SENSOR_DEVICE_ATTR(prj##fan##id##_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, \ + fan_set_duty_cycle, FAN##id##_DUTY_CYCLE); \ + static SENSOR_DEVICE_ATTR(prj##fan##id##_direction, S_IRUGO, fan_show_value, NULL, FAN##id##_DIRECTION); \ + static SENSOR_DEVICE_ATTR(prj##fanr##id##_fault, S_IRUGO, fan_show_value, NULL, FANR##id##_FAULT); \ + static SENSOR_DEVICE_ATTR(prj##fanr##id##_speed_rpm, S_IRUGO, fan_show_value, NULL, FANR##id##_SPEED); \ + static SENSOR_DEVICE_ATTR(prj##fan##id##_input, S_IRUGO, fan_show_value, NULL, FAN##id##_SPEED); \ + static SENSOR_DEVICE_ATTR(prj##fan##id2##_input, S_IRUGO, fan_show_value, NULL, FANR##id##_SPEED); \ + static SENSOR_DEVICE_ATTR(prj##fan##id##_fault, S_IRUGO, fan_show_value, NULL, FAN##id##_FAULT); \ + static SENSOR_DEVICE_ATTR(prj##fan##id2##_fault, S_IRUGO, fan_show_value, NULL, FAN##id##_FAULT); + +#define MAKE_SENSOR_DEVICE_ATTR(prj,id, id2) _MAKE_SENSOR_DEVICE_ATTR(prj,id, id2) + +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME,1,11) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME,2,12) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME,3,13) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME,4,14) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME,5,15) + +static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0); +/*******************/ + +#define _MAKE_FAN_ATTR(prj, id, id2) \ + &sensor_dev_attr_##prj##fan##id##_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_##prj##fan##id##_duty_cycle_percentage.dev_attr.attr,\ + &sensor_dev_attr_##prj##fan##id##_direction.dev_attr.attr, \ + &sensor_dev_attr_##prj##fanr##id##_fault.dev_attr.attr, \ + &sensor_dev_attr_##prj##fanr##id##_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_##prj##fan##id##_input.dev_attr.attr, \ + &sensor_dev_attr_##prj##fan##id2##_input.dev_attr.attr, \ + &sensor_dev_attr_##prj##fan##id##_fault.dev_attr.attr, \ + &sensor_dev_attr_##prj##fan##id2##_fault.dev_attr.attr, + + +#define MAKE_FAN_ATTR(prj, id, id2) _MAKE_FAN_ATTR(prj, id, id2) + +static struct attribute *accton_as5812_54x_fan_attributes[] = { + /* fan related attributes */ + MAKE_FAN_ATTR(PROJECT_NAME,1,11) + MAKE_FAN_ATTR(PROJECT_NAME,2,12) + MAKE_FAN_ATTR(PROJECT_NAME,3,13) + MAKE_FAN_ATTR(PROJECT_NAME,4,14) + MAKE_FAN_ATTR(PROJECT_NAME,5,15) + &sensor_dev_attr_name.dev_attr.attr, + NULL +}; +/*******************/ + +/* fan related functions + */ +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + ssize_t ret = 0; + int data_index, type_index; + + accton_as5812_54x_fan_update_device(dev); + + if (fan_data->valid == 0) { + return ret; + } + + type_index = attr->index%FAN2_FAULT; + data_index = attr->index/FAN2_FAULT; + + switch (type_index) { + case FAN1_FAULT: + ret = sprintf(buf, "%d\n", fan_data->status[data_index]); + if (LOCAL_DEBUG) + printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index); + break; + case FAN1_SPEED: + ret = sprintf(buf, "%d\n", fan_data->speed[data_index]); + if (LOCAL_DEBUG) + printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index); + break; + case FAN1_DUTY_CYCLE: + ret = sprintf(buf, "%d\n", fan_data->duty_cycle[data_index]); + if (LOCAL_DEBUG) + printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index); + break; + case FAN1_DIRECTION: + ret = sprintf(buf, "%d\n", fan_data->direction[data_index]); /* presnet, need to modify*/ + if (LOCAL_DEBUG) + printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index); + break; + case FANR1_FAULT: + ret = sprintf(buf, "%d\n", fan_data->r_status[data_index]); + if (LOCAL_DEBUG) + printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index); + break; + case FANR1_SPEED: + ret = sprintf(buf, "%d\n", fan_data->r_speed[data_index]); + if (LOCAL_DEBUG) + printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index); + break; + default: + if (LOCAL_DEBUG) + printk ("[Check !!][%s][%d] \n", __FUNCTION__, __LINE__); + break; + } + + return ret; +} + +static ssize_t show_name(struct device *dev, struct device_attribute *da, + char *buf) +{ + return sprintf(buf, "%s\n", DRVNAME); +} +/*******************/ +static ssize_t fan_set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) { + + int error, value; + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value < FAN_DUTY_CYCLE_MIN || value > FAN_DUTY_CYCLE_MAX) + return -EINVAL; + + accton_as5812_54x_fan_write_value(CPLD_REG_FAN_PWM_CYCLE_OFFSET, value/FAN_SPEED_PRECENT_TO_CPLD_STEP); + + fan_data->valid = 0; + + return count; +} + +static const struct attribute_group accton_as5812_54x_fan_group = { + .attrs = accton_as5812_54x_fan_attributes, +}; + +static int accton_as5812_54x_fan_read_value(u8 reg) +{ + return as5812_54x_cpld_read(0x60, reg); +} + +static int accton_as5812_54x_fan_write_value(u8 reg, u8 value) +{ + return as5812_54x_cpld_write(0x60, reg, value); +} + +static void accton_as5812_54x_fan_update_device(struct device *dev) +{ + int speed, r_speed, fault, r_fault, ctrl_speed, direction; + int i; + + mutex_lock(&fan_data->update_lock); + + if (LOCAL_DEBUG) + printk ("Starting accton_as5812_54x_fan update \n"); + + if (!(time_after(jiffies, fan_data->last_updated + HZ + HZ / 2) || !fan_data->valid)) { + /* do nothing */ + goto _exit; + } + + fan_data->valid = 0; + + if (LOCAL_DEBUG) + printk ("Starting accton_as5812_54x_fan update 2 \n"); + + fault = accton_as5812_54x_fan_read_value(CPLD_REG_FAN_STATUS_OFFSET); + r_fault = accton_as5812_54x_fan_read_value(CPLD_REG_FANR_STATUS_OFFSET); + direction = accton_as5812_54x_fan_read_value(CPLD_REG_FAN_DIRECTION_OFFSET); + ctrl_speed = accton_as5812_54x_fan_read_value(CPLD_REG_FAN_PWM_CYCLE_OFFSET); + + if ( (fault < 0) || (r_fault < 0) || (direction < 0) || (ctrl_speed < 0) ) + { + if (LOCAL_DEBUG) + printk ("[Error!!][%s][%d] \n", __FUNCTION__, __LINE__); + goto _exit; /* error */ + } + + if (LOCAL_DEBUG) + printk ("[fan:] fault:%d, r_fault=%d, direction=%d, ctrl_speed=%d \n",fault, r_fault, direction, ctrl_speed); + + for (i=0; istatus[i] = (fault & fan_info_mask[i]) >> i; + if (LOCAL_DEBUG) + printk ("[fan%d:] fail=%d \n",i, fan_data->status[i]); + + fan_data->r_status[i] = (r_fault & fan_info_mask[i]) >> i; + fan_data->direction[i] = (direction & fan_info_mask[i]) >> i; + fan_data->duty_cycle[i] = ctrl_speed * FAN_SPEED_PRECENT_TO_CPLD_STEP; + + /* fan speed + */ + speed = accton_as5812_54x_fan_read_value(fan_speed_reg[i]); + r_speed = accton_as5812_54x_fan_read_value(fanr_speed_reg[i]); + if ( (speed < 0) || (r_speed < 0) ) + { + if (LOCAL_DEBUG) + printk ("[Error!!][%s][%d] \n", __FUNCTION__, __LINE__); + goto _exit; /* error */ + } + + if (LOCAL_DEBUG) + printk ("[fan%d:] speed:%d, r_speed=%d \n", i, speed, r_speed); + + fan_data->speed[i] = speed * FAN_SPEED_CPLD_TO_RPM_STEP; + fan_data->r_speed[i] = r_speed * FAN_SPEED_CPLD_TO_RPM_STEP; + } + + /* finish to update */ + fan_data->last_updated = jiffies; + fan_data->valid = 1; + +_exit: + mutex_unlock(&fan_data->update_lock); +} + +static int accton_as5812_54x_fan_probe(struct platform_device *pdev) +{ + int status = -1; + + /* Register sysfs hooks */ + status = sysfs_create_group(&pdev->dev.kobj, &accton_as5812_54x_fan_group); + if (status) { + goto exit; + + } + + fan_data->hwmon_dev = hwmon_device_register(&pdev->dev); + if (IS_ERR(fan_data->hwmon_dev)) { + status = PTR_ERR(fan_data->hwmon_dev); + goto exit_remove; + } + + dev_info(&pdev->dev, "accton_as5812_54x_fan\n"); + + return 0; + +exit_remove: + sysfs_remove_group(&pdev->dev.kobj, &accton_as5812_54x_fan_group); +exit: + return status; +} + +static int accton_as5812_54x_fan_remove(struct platform_device *pdev) +{ + hwmon_device_unregister(fan_data->hwmon_dev); + sysfs_remove_group(&fan_data->pdev->dev.kobj, &accton_as5812_54x_fan_group); + + return 0; +} + + + +static struct platform_driver accton_as5812_54x_fan_driver = { + .probe = accton_as5812_54x_fan_probe, + .remove = accton_as5812_54x_fan_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int __init accton_as5812_54x_fan_init(void) +{ + int ret; + + ret = platform_driver_register(&accton_as5812_54x_fan_driver); + if (ret < 0) { + goto exit; + } + + fan_data = kzalloc(sizeof(struct accton_as5812_54x_fan), GFP_KERNEL); + if (!fan_data) { + ret = -ENOMEM; + platform_driver_unregister(&accton_as5812_54x_fan_driver); + goto exit; + } + + mutex_init(&fan_data->update_lock); + fan_data->valid = 0; + + fan_data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(fan_data->pdev)) { + ret = PTR_ERR(fan_data->pdev); + platform_driver_unregister(&accton_as5812_54x_fan_driver); + kfree(fan_data); + goto exit; + } + +exit: + return ret; +} + +static void __exit accton_as5812_54x_fan_exit(void) +{ + platform_device_unregister(fan_data->pdev); + platform_driver_unregister(&accton_as5812_54x_fan_driver); + kfree(fan_data); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton_as5812_54x_fan driver"); +MODULE_LICENSE("GPL"); + +module_init(accton_as5812_54x_fan_init); +module_exit(accton_as5812_54x_fan_exit); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/accton_as5812_54x_psu.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/accton_as5812_54x_psu.c new file mode 100755 index 000000000000..2c6b5f492a97 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/accton_as5812_54x_psu.c @@ -0,0 +1,371 @@ +/* + * An hwmon driver for accton as5812_54x Power Module + * + * Copyright (C) 2015 Accton Technology Corporation. + * Copyright (C) Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#if 0 +#define DEBUG +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define PSU_STATUS_I2C_ADDR 0x60 +#define PSU_STATUS_I2C_REG_OFFSET 0x2 + +#define IS_POWER_GOOD(id, value) (!!(value & BIT(id*4 + 1))) +#define IS_PRESENT(id, value) (!(value & BIT(id*4))) + +static ssize_t show_index(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_model_name(struct device *dev, struct device_attribute *da, char *buf); +static int as5812_54x_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len); +extern int as5812_54x_cpld_read(unsigned short cpld_addr, u8 reg); +static int as5812_54x_psu_model_name_get(struct device *dev); + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct as5812_54x_psu_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 index; /* PSU index */ + u8 status; /* Status(present/power_good) register read from CPLD */ + char model_name[14]; /* Model name, read from eeprom */ +}; + +static struct as5812_54x_psu_data *as5812_54x_psu_update_device(struct device *dev); + +enum as5812_54x_psu_sysfs_attributes { + PSU_INDEX, + PSU_PRESENT, + PSU_MODEL_NAME, + PSU_POWER_GOOD +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_index, S_IRUGO, show_index, NULL, PSU_INDEX); +static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_model_name,NULL, PSU_MODEL_NAME); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD); + +static struct attribute *as5812_54x_psu_attributes[] = { + &sensor_dev_attr_psu_index.dev_attr.attr, + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_model_name.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + NULL +}; + +static ssize_t show_index(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54x_psu_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d\n", data->index); +} + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as5812_54x_psu_data *data = as5812_54x_psu_update_device(dev); + u8 status = 0; + + if (!data->valid) { + return sprintf(buf, "0\n"); + } + + if (attr->index == PSU_PRESENT) { + status = IS_PRESENT(data->index, data->status); + } + else { /* PSU_POWER_GOOD */ + status = IS_POWER_GOOD(data->index, data->status); + } + + return sprintf(buf, "%d\n", status); +} + +static ssize_t show_model_name(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct as5812_54x_psu_data *data = as5812_54x_psu_update_device(dev); + + if (!data->valid) { + return 0; + } + + if (!IS_PRESENT(data->index, data->status)) { + return 0; + } + + if (as5812_54x_psu_model_name_get(dev) < 0) { + return -ENXIO; + } + + return sprintf(buf, "%s\n", data->model_name); +} + +static const struct attribute_group as5812_54x_psu_group = { + .attrs = as5812_54x_psu_attributes, +}; + +static int as5812_54x_psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as5812_54x_psu_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as5812_54x_psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + data->index = dev_id->driver_data; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as5812_54x_psu_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as5812_54x_psu_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as5812_54x_psu_remove(struct i2c_client *client) +{ + struct as5812_54x_psu_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as5812_54x_psu_group); + kfree(data); + + return 0; +} + +enum psu_index +{ + as5812_54x_psu1, + as5812_54x_psu2 +}; + +static const struct i2c_device_id as5812_54x_psu_id[] = { + { "as5812_54x_psu1", as5812_54x_psu1 }, + { "as5812_54x_psu2", as5812_54x_psu2 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as5812_54x_psu_id); + +static struct i2c_driver as5812_54x_psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as5812_54x_psu", + }, + .probe = as5812_54x_psu_probe, + .remove = as5812_54x_psu_remove, + .id_table = as5812_54x_psu_id, + .address_list = normal_i2c, +}; + +static int as5812_54x_psu_read_block(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; + +abort: + return result; +} + +enum psu_type { + PSU_YM_2401_JCR, /* AC110V - F2B */ + PSU_YM_2401_JDR, /* AC110V - B2F */ + PSU_CPR_4011_4M11, /* AC110V - F2B */ + PSU_CPR_4011_4M21, /* AC110V - B2F */ + PSU_CPR_6011_2M11, /* AC110V - F2B */ + PSU_CPR_6011_2M21, /* AC110V - B2F */ + PSU_UM400D_01G, /* DC48V - F2B */ + PSU_UM400D01_01G /* DC48V - B2F */ +}; + +struct model_name_info { + enum psu_type type; + u8 offset; + u8 length; + char* model_name; +}; + +struct model_name_info models[] = { +{PSU_YM_2401_JCR, 0x20, 11, "YM-2401JCR"}, +{PSU_YM_2401_JDR, 0x20, 11, "YM-2401JDR"}, +{PSU_CPR_4011_4M11, 0x26, 13, "CPR-4011-4M11"}, +{PSU_CPR_4011_4M21, 0x26, 13, "CPR-4011-4M21"}, +{PSU_CPR_6011_2M11, 0x26, 13, "CPR-6011-2M11"}, +{PSU_CPR_6011_2M21, 0x26, 13, "CPR-6011-2M21"}, +{PSU_UM400D_01G, 0x50, 9, "um400d01G"}, +{PSU_UM400D01_01G, 0x50, 12, "um400d01-01G"}, +}; + +static int as5812_54x_psu_model_name_get(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54x_psu_data *data = i2c_get_clientdata(client); + int i, status; + + for (i = 0; i < ARRAY_SIZE(models); i++) { + memset(data->model_name, 0, sizeof(data->model_name)); + + status = as5812_54x_psu_read_block(client, models[i].offset, + data->model_name, models[i].length); + if (status < 0) { + data->model_name[0] = '\0'; + dev_dbg(&client->dev, "unable to read model name from (0x%x) offset(0x%x)\n", + client->addr, models[i].offset); + return status; + } + else { + data->model_name[models[i].length] = '\0'; + } + + if (i == PSU_YM_2401_JCR || i == PSU_YM_2401_JDR) { + /* Skip the meaningless data byte 8*/ + data->model_name[8] = data->model_name[9]; + data->model_name[9] = data->model_name[10]; + data->model_name[10] = '\0'; + } + + /* Determine if the model name is known, if not, read next index + */ + if (strncmp(data->model_name, models[i].model_name, models[i].length) == 0) { + return 0; + } + else { + data->model_name[0] = '\0'; + } + } + + return -ENODATA; +} + +static struct as5812_54x_psu_data *as5812_54x_psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54x_psu_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int status = -1; + + dev_dbg(&client->dev, "Starting as5812_54x update\n"); + data->valid = 0; + + + /* Read psu status */ + status = as5812_54x_cpld_read(PSU_STATUS_I2C_ADDR, PSU_STATUS_I2C_REG_OFFSET); + + if (status < 0) { + dev_dbg(&client->dev, "cpld reg (0x%x) err %d\n", PSU_STATUS_I2C_ADDR, status); + goto exit; + } + else { + data->status = status; + } + + data->last_updated = jiffies; + data->valid = 1; + } + +exit: + mutex_unlock(&data->update_lock); + + return data; +} + +static int __init as5812_54x_psu_init(void) +{ + return i2c_add_driver(&as5812_54x_psu_driver); +} + +static void __exit as5812_54x_psu_exit(void) +{ + i2c_del_driver(&as5812_54x_psu_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton as5812_54x_psu driver"); +MODULE_LICENSE("GPL"); + +module_init(as5812_54x_psu_init); +module_exit(as5812_54x_psu_exit); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/accton_as5812_54x_sfp.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/accton_as5812_54x_sfp.c new file mode 100755 index 000000000000..10841c1d22e4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/accton_as5812_54x_sfp.c @@ -0,0 +1,825 @@ +/* + * An hwmon driver for accton as5812_54x sfp + * + * Copyright (C) Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#if 0 +#define DEBUG +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NUM_OF_SFF_PORT 54 +#define SFP_PORT_MAX 48 +#define I2C_ADDR_CPLD1 0x60 +#define I2C_ADDR_CPLD2 0x61 +#define I2C_ADDR_CPLD3 0x62 +#define CPLD3_OFFSET_QSFP_MOD_RST 0x15 +#define CPLD3_OFFSET_QSFP_LPMODE 0x16 + + +#define BIT_INDEX(i) (1ULL << (i)) + +#if 0 +static ssize_t show_status(struct device *dev, struct device_attribute *da,char *buf); +static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_eeprom(struct device *dev, struct device_attribute *da, char *buf); +static int as5812_54x_sfp_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len); +extern int as5812_54x_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int as5812_54x_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); +#endif + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct as5812_54x_sfp_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + int port; /* Front port index */ + char eeprom[256]; /* eeprom data */ + u64 status[4]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => is_present + 1 => tx_fail + 2 => tx_disable + 3 => rx_loss */ +}; + +/* The table maps active port to cpld port. + * Array index 0 is for active port 1, + * index 1 for active port 2, and so on. + * The array content implies cpld port index. + */ +static const u8 cpld_to_front_port_table[] = +{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 52, 50, 53, 51, 54}; + +#define CPLD_PORT_TO_FRONT_PORT(port) (cpld_to_front_port_table[port]) + +static struct as5812_54x_sfp_data *as5812_54x_sfp_update_device(struct device *dev, int update_eeprom); +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_eeprom(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t get_lp_mode(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t set_lp_mode(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t get_mode_reset(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +extern int as5812_54x_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int as5812_54x_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +enum as5812_54x_sfp_sysfs_attributes { + SFP_IS_PRESENT, + SFP_TX_FAULT, + SFP_TX_DISABLE, + SFP_RX_LOSS, + SFP_PORT_NUMBER, + SFP_EEPROM, + SFP_RX_LOS_ALL, + SFP_IS_PRESENT_ALL, + SFP_LP_MODE, + SFP_MOD_RST, +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_status, NULL, SFP_IS_PRESENT); +static SENSOR_DEVICE_ATTR(sfp_tx_fault, S_IRUGO, show_status, NULL, SFP_TX_FAULT); +static SENSOR_DEVICE_ATTR(sfp_tx_disable, S_IWUSR | S_IRUGO, show_status, set_tx_disable, SFP_TX_DISABLE); +static SENSOR_DEVICE_ATTR(sfp_rx_loss, S_IRUGO, show_status,NULL, SFP_RX_LOSS); +static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, SFP_PORT_NUMBER); +static SENSOR_DEVICE_ATTR(sfp_eeprom, S_IRUGO, show_eeprom, NULL, SFP_EEPROM); +static SENSOR_DEVICE_ATTR(sfp_rx_los_all, S_IRUGO, show_status,NULL, SFP_RX_LOS_ALL); +static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_status,NULL, SFP_IS_PRESENT_ALL); +static SENSOR_DEVICE_ATTR(sfp_lp_mode, S_IWUSR | S_IRUGO, get_lp_mode, set_lp_mode, SFP_LP_MODE); +static SENSOR_DEVICE_ATTR(sfp_mod_rst, S_IWUSR | S_IRUGO, get_mode_reset, set_mode_reset, SFP_MOD_RST); + +static struct attribute *as5812_54x_sfp_attributes[] = { + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp_eeprom.dev_attr.attr, + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los_all.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_lp_mode.dev_attr.attr, + &sensor_dev_attr_sfp_mod_rst.dev_attr.attr, + NULL +}; + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54x_sfp_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port)); +} + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as5812_54x_sfp_data *data; + u8 val; + int values[7]; + + /* Error-check the CPLD read results. */ +#define VALIDATED_READ(_buf, _rv, _read_expr, _invert) \ + do { \ + _rv = (_read_expr); \ + if(_rv < 0) { \ + return sprintf(_buf, "READ ERROR\n"); \ + } \ + if(_invert) { \ + _rv = ~_rv; \ + } \ + _rv &= 0xFF; \ + } while(0) + + if(attr->index == SFP_RX_LOS_ALL) { + /* + * Report the RX_LOS status for all ports. + * This does not depend on the currently active SFP selector. + */ + + /* RX_LOS Ports 1-8 */ + VALIDATED_READ(buf, values[0], as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD2, 0x0F), 0); + /* RX_LOS Ports 9-16 */ + VALIDATED_READ(buf, values[1], as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD2, 0x10), 0); + /* RX_LOS Ports 17-24 */ + VALIDATED_READ(buf, values[2], as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD2, 0x11), 0); + /* RX_LOS Ports 25-32 */ + VALIDATED_READ(buf, values[3], as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x0F), 0); + /* RX_LOS Ports 33-40 */ + VALIDATED_READ(buf, values[4], as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x10), 0); + /* RX_LOS Ports 41-48 */ + VALIDATED_READ(buf, values[5], as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x11), 0); + + /** Return values 1 -> 48 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5]); + } + + if(attr->index == SFP_IS_PRESENT_ALL) { + /* + * Report the SFP_PRESENCE status for all ports. + * This does not depend on the currently active SFP selector. + */ + + /* SFP_PRESENT Ports 1-8 */ + VALIDATED_READ(buf, values[0], as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD2, 0x6), 1); + /* SFP_PRESENT Ports 9-16 */ + VALIDATED_READ(buf, values[1], as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD2, 0x7), 1); + /* SFP_PRESENT Ports 17-24 */ + VALIDATED_READ(buf, values[2], as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD2, 0x8), 1); + /* SFP_PRESENT Ports 25-32 */ + VALIDATED_READ(buf, values[3], as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x6), 1); + /* SFP_PRESENT Ports 33-40 */ + VALIDATED_READ(buf, values[4], as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x7), 1); + /* SFP_PRESENT Ports 41-48 */ + VALIDATED_READ(buf, values[5], as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x8), 1); + /* QSFP_PRESENT Ports 49-54 */ + VALIDATED_READ(buf, values[6], as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x14), 1); + + /* Return values 1 -> 54 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5], + values[6] & 0x3F); + } + /* + * The remaining attributes are gathered on a per-selected-sfp basis. + */ + data = as5812_54x_sfp_update_device(dev, 0); + if (attr->index == SFP_IS_PRESENT) { + val = (data->status[attr->index] & BIT_INDEX(data->port)) ? 0 : 1; + } + else { + val = (data->status[attr->index] & BIT_INDEX(data->port)) ? 1 : 0; + } + + return sprintf(buf, "%d", val); +} + +static ssize_t get_lp_mode(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54x_sfp_data *data = i2c_get_clientdata(client); + u8 cpld_val = 0; + int port_bit; + int status = -EINVAL; + + /* Low power mode is not supported for SFP ports(1-48) */ + if (data->port < SFP_PORT_MAX) { + return -EINVAL; + } + mutex_lock(&data->update_lock); + + port_bit = data->port - SFP_PORT_MAX; + cpld_val = as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD3, CPLD3_OFFSET_QSFP_LPMODE); + cpld_val = cpld_val & 0x3F; + cpld_val = cpld_val & BIT_INDEX(port_bit); + status = snprintf(buf, PAGE_SIZE - 1, "%d\r\n", cpld_val>>port_bit); + + mutex_unlock(&data->update_lock); + + return status; +} + +static ssize_t set_lp_mode(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54x_sfp_data *data = i2c_get_clientdata(client); + u8 cpld_val = 0; + long mode; + int error, port_bit; + + /* Tx disable is not supported for QSFP ports(49-54) */ + if (data->port < SFP_PORT_MAX) { + return -EINVAL; + } + port_bit = data->port - SFP_PORT_MAX; + error = kstrtol(buf, 10, &mode); + if (error) { + return error; + } + mutex_lock(&data->update_lock); + + cpld_val = as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD3, CPLD3_OFFSET_QSFP_LPMODE); + /* Update lp_mode status */ + if (mode) + { + cpld_val |= BIT_INDEX(port_bit); + } + else + { + cpld_val &=~BIT_INDEX(port_bit); + } + as5812_54x_i2c_cpld_write(I2C_ADDR_CPLD3, CPLD3_OFFSET_QSFP_LPMODE, cpld_val); + + mutex_unlock(&data->update_lock); + + return count; +} + + +static ssize_t get_mode_reset(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54x_sfp_data *data = i2c_get_clientdata(client); + u8 cpld_val = 0; + int port_bit; + int status = -EINVAL; + + /* Low power mode is not supported for SFP ports(1-48) */ + if (data->port < SFP_PORT_MAX) { + return -EINVAL; + } + mutex_lock(&data->update_lock); + + port_bit = data->port - SFP_PORT_MAX; + cpld_val = as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD3, CPLD3_OFFSET_QSFP_MOD_RST); + cpld_val = cpld_val & 0x3F; + cpld_val = cpld_val & BIT_INDEX(port_bit); + status = snprintf(buf, PAGE_SIZE - 1, "%d\r\n", cpld_val>>port_bit); + + mutex_unlock(&data->update_lock); + + return status; +} + +static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54x_sfp_data *data = i2c_get_clientdata(client); + u8 cpld_val = 0; + long reset; + int error, port_bit; + + /* Tx disable is not supported for QSFP ports(49-54) */ + if (data->port < SFP_PORT_MAX) { + return -EINVAL; + } + port_bit = data->port - SFP_PORT_MAX; + error = kstrtol(buf, 10, &reset); + if (error) { + return error; + } + mutex_lock(&data->update_lock); + + cpld_val = as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD3, CPLD3_OFFSET_QSFP_MOD_RST); + /* Update lp_mode status */ + if (reset) + { + cpld_val |= BIT_INDEX(port_bit); + } + else + { + cpld_val &=~BIT_INDEX(port_bit); + } + as5812_54x_i2c_cpld_write(I2C_ADDR_CPLD3, CPLD3_OFFSET_QSFP_MOD_RST, cpld_val); + + mutex_unlock(&data->update_lock); + + return count; +} + + +static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54x_sfp_data *data = i2c_get_clientdata(client); + unsigned short cpld_addr = 0; + u8 cpld_reg = 0, cpld_val = 0, cpld_bit = 0; + long disable; + int error; + + /* Tx disable is not supported for QSFP ports(49-54) */ + if (data->port >= SFP_PORT_MAX) { + return -EINVAL; + } + + error = kstrtol(buf, 10, &disable); + if (error) { + return error; + } + + mutex_lock(&data->update_lock); + + if(data->port < 24) { + cpld_addr = I2C_ADDR_CPLD2; + cpld_reg = 0xC + data->port / 8; + cpld_bit = 1 << (data->port % 8); + } + else { + cpld_addr = I2C_ADDR_CPLD3; + cpld_reg = 0xC + (data->port - 24) / 8; + cpld_bit = 1 << (data->port % 8); + } + + cpld_val = as5812_54x_i2c_cpld_read(cpld_addr, cpld_reg); + + /* Update tx_disable status */ + if (disable) { + data->status[SFP_TX_DISABLE] |= BIT_INDEX(data->port); + cpld_val |= cpld_bit; + } + else { + data->status[SFP_TX_DISABLE] &= ~BIT_INDEX(data->port); + cpld_val &= ~cpld_bit; + } + + as5812_54x_i2c_cpld_write(cpld_addr, cpld_reg, cpld_val); + + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_eeprom(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct as5812_54x_sfp_data *data = as5812_54x_sfp_update_device(dev, 1); + + if (!data->valid) { + return 0; + } + + if ((data->status[SFP_IS_PRESENT] & BIT_INDEX(data->port)) != 0) { + return 0; + } + + memcpy(buf, data->eeprom, sizeof(data->eeprom)); + + return sizeof(data->eeprom); +} + +static const struct attribute_group as5812_54x_sfp_group = { + .attrs = as5812_54x_sfp_attributes, +}; + +static int as5812_54x_sfp_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as5812_54x_sfp_data *data; + int status; + + extern int platform_accton_as5812_54x(void); + if(!platform_accton_as5812_54x()) { + return -ENODEV; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as5812_54x_sfp_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + mutex_init(&data->update_lock); + data->port = dev_id->driver_data; + i2c_set_clientdata(client, data); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as5812_54x_sfp_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: sfp '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as5812_54x_sfp_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as5812_54x_sfp_remove(struct i2c_client *client) +{ + struct as5812_54x_sfp_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as5812_54x_sfp_group); + kfree(data); + + return 0; +} + +enum port_numbers { +as5812_54x_sfp1, as5812_54x_sfp2, as5812_54x_sfp3, as5812_54x_sfp4, +as5812_54x_sfp5, as5812_54x_sfp6, as5812_54x_sfp7, as5812_54x_sfp8, +as5812_54x_sfp9, as5812_54x_sfp10, as5812_54x_sfp11,as5812_54x_sfp12, +as5812_54x_sfp13, as5812_54x_sfp14, as5812_54x_sfp15,as5812_54x_sfp16, +as5812_54x_sfp17, as5812_54x_sfp18, as5812_54x_sfp19,as5812_54x_sfp20, +as5812_54x_sfp21, as5812_54x_sfp22, as5812_54x_sfp23,as5812_54x_sfp24, +as5812_54x_sfp25, as5812_54x_sfp26, as5812_54x_sfp27,as5812_54x_sfp28, +as5812_54x_sfp29, as5812_54x_sfp30, as5812_54x_sfp31,as5812_54x_sfp32, +as5812_54x_sfp33, as5812_54x_sfp34, as5812_54x_sfp35,as5812_54x_sfp36, +as5812_54x_sfp37, as5812_54x_sfp38, as5812_54x_sfp39,as5812_54x_sfp40, +as5812_54x_sfp41, as5812_54x_sfp42, as5812_54x_sfp43,as5812_54x_sfp44, +as5812_54x_sfp45, as5812_54x_sfp46, as5812_54x_sfp47,as5812_54x_sfp48, +as5812_54x_sfp49, as5812_54x_sfp52, as5812_54x_sfp50,as5812_54x_sfp53, +as5812_54x_sfp51, as5812_54x_sfp54 +}; + +static const struct i2c_device_id as5812_54x_sfp_id[] = { +{ "as5812_54x_sfp1", as5812_54x_sfp1 }, { "as5812_54x_sfp2", as5812_54x_sfp2 }, +{ "as5812_54x_sfp3", as5812_54x_sfp3 }, { "as5812_54x_sfp4", as5812_54x_sfp4 }, +{ "as5812_54x_sfp5", as5812_54x_sfp5 }, { "as5812_54x_sfp6", as5812_54x_sfp6 }, +{ "as5812_54x_sfp7", as5812_54x_sfp7 }, { "as5812_54x_sfp8", as5812_54x_sfp8 }, +{ "as5812_54x_sfp9", as5812_54x_sfp9 }, { "as5812_54x_sfp10", as5812_54x_sfp10 }, +{ "as5812_54x_sfp11", as5812_54x_sfp11 }, { "as5812_54x_sfp12", as5812_54x_sfp12 }, +{ "as5812_54x_sfp13", as5812_54x_sfp13 }, { "as5812_54x_sfp14", as5812_54x_sfp14 }, +{ "as5812_54x_sfp15", as5812_54x_sfp15 }, { "as5812_54x_sfp16", as5812_54x_sfp16 }, +{ "as5812_54x_sfp17", as5812_54x_sfp17 }, { "as5812_54x_sfp18", as5812_54x_sfp18 }, +{ "as5812_54x_sfp19", as5812_54x_sfp19 }, { "as5812_54x_sfp20", as5812_54x_sfp20 }, +{ "as5812_54x_sfp21", as5812_54x_sfp21 }, { "as5812_54x_sfp22", as5812_54x_sfp22 }, +{ "as5812_54x_sfp23", as5812_54x_sfp23 }, { "as5812_54x_sfp24", as5812_54x_sfp24 }, +{ "as5812_54x_sfp25", as5812_54x_sfp25 }, { "as5812_54x_sfp26", as5812_54x_sfp26 }, +{ "as5812_54x_sfp27", as5812_54x_sfp27 }, { "as5812_54x_sfp28", as5812_54x_sfp28 }, +{ "as5812_54x_sfp29", as5812_54x_sfp29 }, { "as5812_54x_sfp30", as5812_54x_sfp30 }, +{ "as5812_54x_sfp31", as5812_54x_sfp31 }, { "as5812_54x_sfp32", as5812_54x_sfp32 }, +{ "as5812_54x_sfp33", as5812_54x_sfp33 }, { "as5812_54x_sfp34", as5812_54x_sfp34 }, +{ "as5812_54x_sfp35", as5812_54x_sfp35 }, { "as5812_54x_sfp36", as5812_54x_sfp36 }, +{ "as5812_54x_sfp37", as5812_54x_sfp37 }, { "as5812_54x_sfp38", as5812_54x_sfp38 }, +{ "as5812_54x_sfp39", as5812_54x_sfp39 }, { "as5812_54x_sfp40", as5812_54x_sfp40 }, +{ "as5812_54x_sfp41", as5812_54x_sfp41 }, { "as5812_54x_sfp42", as5812_54x_sfp42 }, +{ "as5812_54x_sfp43", as5812_54x_sfp43 }, { "as5812_54x_sfp44", as5812_54x_sfp44 }, +{ "as5812_54x_sfp45", as5812_54x_sfp45 }, { "as5812_54x_sfp46", as5812_54x_sfp46 }, +{ "as5812_54x_sfp47", as5812_54x_sfp47 }, { "as5812_54x_sfp48", as5812_54x_sfp48 }, +{ "as5812_54x_sfp49", as5812_54x_sfp49 }, { "as5812_54x_sfp50", as5812_54x_sfp50 }, +{ "as5812_54x_sfp51", as5812_54x_sfp51 }, { "as5812_54x_sfp52", as5812_54x_sfp52 }, +{ "as5812_54x_sfp53", as5812_54x_sfp53 }, { "as5812_54x_sfp54", as5812_54x_sfp54 }, + +{} +}; +MODULE_DEVICE_TABLE(i2c, as5812_54x_sfp_id); + +static struct i2c_driver as5812_54x_sfp_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as5812_54x_sfp", + }, + .probe = as5812_54x_sfp_probe, + .remove = as5812_54x_sfp_remove, + .id_table = as5812_54x_sfp_id, + .address_list = normal_i2c, +}; + +static int as5812_54x_sfp_read_byte(struct i2c_client *client, u8 command, u8 *data) +{ + int result = i2c_smbus_read_byte_data(client, command); + + if (unlikely(result < 0)) { + dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, result); + goto abort; + } + + *data = (u8)result; + result = 0; + +abort: + return result; +} + +#define ALWAYS_UPDATE_DEVICE 1 + +static struct as5812_54x_sfp_data *as5812_54x_sfp_update_device(struct device *dev, int update_eeprom) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54x_sfp_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (ALWAYS_UPDATE_DEVICE || time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int status = -1; + int i = 0, j = 0; + + data->valid = 0; + //dev_dbg(&client->dev, "Starting as5812_54x sfp status update\n"); + memset(data->status, 0, sizeof(data->status)); + + /* Read status of port 1~48(SFP port) */ + for (i = 0; i < 2; i++) { + for (j = 0; j < 12; j++) { + status = as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD2+i, 0x6+j); + + if (status < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", I2C_ADDR_CPLD2+i, 0x6+j, status); + goto exit; + } + + data->status[j/3] |= (u64)status << ((i*24) + (j%3)*8); + } + } + + /* + * Bring QSFPs out of reset, + * This is a temporary fix until the QSFP+_MOD_RST register + * can be exposed through the driver. + */ + as5812_54x_i2c_cpld_write(I2C_ADDR_CPLD3, 0x15, 0x3F); + + /* Read present status of port 49-54(QSFP port) */ + status = as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x14); + + if (status < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", I2C_ADDR_CPLD2+i, 0x6+j, status); + } + else { + data->status[SFP_IS_PRESENT] |= (u64)status << 48; + } + + if (update_eeprom) { + /* Read eeprom data based on port number */ + memset(data->eeprom, 0, sizeof(data->eeprom)); + + /* Check if the port is present */ + if ((data->status[SFP_IS_PRESENT] & BIT_INDEX(data->port)) == 0) { + /* read eeprom */ + for (i = 0; i < sizeof(data->eeprom); i++) { + status = as5812_54x_sfp_read_byte(client, i, data->eeprom + i); + + if (status < 0) { + dev_dbg(&client->dev, "unable to read eeprom from port(%d)\n", + CPLD_PORT_TO_FRONT_PORT(data->port)); + goto exit; + } + } + } + } + + data->valid = 1; + data->last_updated = jiffies; + } + +exit: + mutex_unlock(&data->update_lock); + + return data; +} + +module_i2c_driver(as5812_54x_sfp_driver); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton as5812_54x_sfp driver"); +MODULE_LICENSE("GPL"); + +#if 0 + int i = 0, j = 0; + + data->valid = 0; + //dev_dbg(&client->dev, "Starting as5812_54x sfp update\n"); + memset(data->status, 0, sizeof(data->status)); + + /* Read status of port 1~48(SFP port) */ + for (i = 0; i < 2; i++) { + for (j = 0; j < 12; j++) { + status = as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD2+i, 0x6+j); + + if (status < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", I2C_ADDR_CPLD2+i, 0x6+j, status); + continue; + } + + data->status[j/3] |= (u64)status << ((i*24) + (j%3)*8); + } + } + + /* Read present status of port 49-54(QSFP port) */ + status = as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x14); + + if (status < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", I2C_ADDR_CPLD2+i, 0x6+j, status); + } + else { + data->status[SFP_IS_PRESENT] |= (u64)status << 48; + } +#endif + +/* Reserver to prevent from CPLD port mapping is changed + */ +#if 0 +BIT_INDEX(port_present_index[data->port]) +/* The bit index of is_present field read from CPLD + * Array index 0 is for as5812_54x_sfp1, + * index 1 is for as5812_54x_sfp2, and so on. + */ +static const int port_present_index[] = { + 4, 5, 6, 7, 9, 8, 11, 10, + 0, 1, 2, 3, 12, 13, 14, 15, +16, 17, 18, 19, 28, 29, 30, 31, +20, 21, 22, 23, 24, 25, 26, 27 +}; +#endif + +#if 0 +static struct as5812_54x_sfp_data *as5812_54x_sfp_update_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54x_sfp_data *data = i2c_get_clientdata(client); + int status = -1; + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->status_last_updated + HZ + HZ / 2) + || !data->status_valid) { + int status = -1; + int i = 0, j = 0; + + data->status_valid = 0; + //dev_dbg(&client->dev, "Starting as5812_54x sfp status update\n"); + memset(data->status, 0, sizeof(data->status)); + + /* Read status of port 1~48(SFP port) */ + for (i = 0; i < 2; i++) { + for (j = 0; j < 12; j++) { + status = as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD2+i, 0x6+j); + + if (status < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", I2C_ADDR_CPLD2+i, 0x6+j, status); + goto exit; + } + + data->status[j/3] |= (u64)status << ((i*24) + (j%3)*8); + } + } + + /* + * Bring QSFPs out of reset, + * This is a temporary fix until the QSFP+_MOD_RST register + * can be exposed through the driver. + */ + as5812_54x_i2c_cpld_write(I2C_ADDR_CPLD3, 0x15, 0x3F); + + /* Read present status of port 49-54(QSFP port) */ + status = as5812_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x14); + + if (status < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", I2C_ADDR_CPLD2+i, 0x6+j, status); + } + else { + data->status[SFP_IS_PRESENT] |= (u64)status << 48; + } + + data->status_valid = 1; + data->status_last_updated = jiffies; + } + +exit: + mutex_unlock(&data->update_lock); + + return data; +} + +static struct as5812_54x_sfp_data *as5812_54x_sfp_update_eeprom(struct device *dev) +{ + struct as5812_54x_sfp_data *data = NULL; + + data = as5812_54x_sfp_update_status(dev); + + if (data == NULL || data->status_valid == 0) { + data->eeprom_valid = 0; + return data; + } + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->eeprom_last_updated + HZ + HZ / 2) + || !data->eeprom_valid) { + int status = -1; + int i = 0; + + /* Read eeprom data based on port number */ + memset(data->eeprom, 0, sizeof(data->eeprom)); + + /* Check if the port is present */ + if ((data->status[SFP_IS_PRESENT] & BIT_INDEX(data->port)) == 0) { + /* read eeprom */ + for (i = 0; i < sizeof(data->eeprom)/I2C_SMBUS_BLOCK_MAX; i++) { + status = as5812_54x_sfp_read_block(client, i*I2C_SMBUS_BLOCK_MAX, + data->eeprom+(i*I2C_SMBUS_BLOCK_MAX), + I2C_SMBUS_BLOCK_MAX); + if (status < 0) { + dev_dbg(&client->dev, "unable to read eeprom from port(%d)\n", + CPLD_PORT_TO_FRONT_PORT(data->port)); + goto exit; + } + } + } + + data->eeprom_last_updated = jiffies; + data->eeprom_valid = 1; + } + +exit: + mutex_unlock(&data->update_lock); + + return data; +} +#endif diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/cpr_4011_4mxx.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/cpr_4011_4mxx.c new file mode 100755 index 000000000000..30bea914d589 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/cpr_4011_4mxx.c @@ -0,0 +1,400 @@ +/* + * An hwmon driver for the CPR-4011-4Mxx Redundant Power Module + * + * Copyright (C) Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#if 0 +#define DEBUG +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_FAN_DUTY_CYCLE 100 + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { 0x3c, 0x3d, 0x3e, 0x3f, I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct cpr_4011_4mxx_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 vout_mode; /* Register value */ + u16 v_in; /* Register value */ + u16 v_out; /* Register value */ + u16 i_in; /* Register value */ + u16 i_out; /* Register value */ + u16 p_in; /* Register value */ + u16 p_out; /* Register value */ + u16 temp_input[2]; /* Register value */ + u8 fan_fault; /* Register value */ + u16 fan_duty_cycle[2]; /* Register value */ + u16 fan_speed[2]; /* Register value */ +}; + +static ssize_t show_linear(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_vout(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static int cpr_4011_4mxx_write_word(struct i2c_client *client, u8 reg, u16 value); +static struct cpr_4011_4mxx_data *cpr_4011_4mxx_update_device(struct device *dev); + +enum cpr_4011_4mxx_sysfs_attributes { + PSU_V_IN, + PSU_V_OUT, + PSU_I_IN, + PSU_I_OUT, + PSU_P_IN, + PSU_P_OUT, + PSU_TEMP1_INPUT, + PSU_FAN1_FAULT, + PSU_FAN1_DUTY_CYCLE, + PSU_FAN1_SPEED, +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, show_linear, NULL, PSU_V_IN); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_vout, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, show_linear, NULL, PSU_I_IN); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, show_linear, NULL, PSU_P_IN); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); + +static struct attribute *cpr_4011_4mxx_attributes[] = { + &sensor_dev_attr_psu_v_in.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_in.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_in.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + NULL +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpr_4011_4mxx_data *data = i2c_get_clientdata(client); + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; + cpr_4011_4mxx_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_linear(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct cpr_4011_4mxx_data *data = cpr_4011_4mxx_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + switch (attr->index) { + case PSU_V_IN: + value = data->v_in; + break; + case PSU_I_IN: + value = data->i_in; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_IN: + value = data->p_in; + break; + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp_input[0]; + break; + case PSU_FAN1_DUTY_CYCLE: + multiplier = 1; + value = data->fan_duty_cycle[0]; + break; + case PSU_FAN1_SPEED: + multiplier = 1; + value = data->fan_speed[0]; + break; + default: + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + + return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct cpr_4011_4mxx_data *data = cpr_4011_4mxx_update_device(dev); + + u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t show_vout(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct cpr_4011_4mxx_data *data = cpr_4011_4mxx_update_device(dev); + int exponent, mantissa; + int multiplier = 1000; + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + mantissa = data->v_out; + + return (exponent > 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static const struct attribute_group cpr_4011_4mxx_group = { + .attrs = cpr_4011_4mxx_attributes, +}; + +static int cpr_4011_4mxx_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct cpr_4011_4mxx_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct cpr_4011_4mxx_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &cpr_4011_4mxx_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &cpr_4011_4mxx_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int cpr_4011_4mxx_remove(struct i2c_client *client) +{ + struct cpr_4011_4mxx_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &cpr_4011_4mxx_group); + kfree(data); + + return 0; +} + +static const struct i2c_device_id cpr_4011_4mxx_id[] = { + { "cpr_4011_4mxx", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, cpr_4011_4mxx_id); + +static struct i2c_driver cpr_4011_4mxx_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "cpr_4011_4mxx", + }, + .probe = cpr_4011_4mxx_probe, + .remove = cpr_4011_4mxx_remove, + .id_table = cpr_4011_4mxx_id, + .address_list = normal_i2c, +}; + +static int cpr_4011_4mxx_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int cpr_4011_4mxx_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int cpr_4011_4mxx_write_word(struct i2c_client *client, u8 reg, u16 value) +{ + return i2c_smbus_write_word_data(client, reg, value); +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + +static struct cpr_4011_4mxx_data *cpr_4011_4mxx_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpr_4011_4mxx_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int i, status; + struct reg_data_byte regs_byte[] = { {0x20, &data->vout_mode}, + {0x81, &data->fan_fault}}; + struct reg_data_word regs_word[] = { {0x88, &data->v_in}, + {0x8b, &data->v_out}, + {0x89, &data->i_in}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x97, &data->p_in}, + {0x8d, &(data->temp_input[0])}, + {0x8e, &(data->temp_input[1])}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x3c, &(data->fan_duty_cycle[1])}, + {0x90, &(data->fan_speed[0])}, + {0x91, &(data->fan_speed[1])}}; + + dev_dbg(&client->dev, "Starting cpr_4011_4mxx update\n"); + + /* Read byte data */ + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = cpr_4011_4mxx_read_byte(client, regs_byte[i].reg); + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + } + else { + *(regs_byte[i].value) = status; + } + } + + /* Read word data */ + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + status = cpr_4011_4mxx_read_word(client, regs_word[i].reg); + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + } + else { + *(regs_word[i].value) = status; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int __init cpr_4011_4mxx_init(void) +{ + return i2c_add_driver(&cpr_4011_4mxx_driver); +} + +static void __exit cpr_4011_4mxx_exit(void) +{ + i2c_del_driver(&cpr_4011_4mxx_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("CPR_4011_4MXX driver"); +MODULE_LICENSE("GPL"); + +module_init(cpr_4011_4mxx_init); +module_exit(cpr_4011_4mxx_exit); diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/i2c-mux-accton_as5812_54x_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/i2c-mux-accton_as5812_54x_cpld.c new file mode 100644 index 000000000000..1578d75bdd92 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/i2c-mux-accton_as5812_54x_cpld.c @@ -0,0 +1,1421 @@ +/* + * An I2C multiplexer dirver for accton as5812 CPLD + * + * Copyright (C) 2015 Accton Technology Corporation. + * Brandon Chuang + * + * This module supports the accton cpld that hold the channel select + * mechanism for other i2c slave devices, such as SFP. + * This includes the: + * Accton as5812_54x CPLD1/CPLD2/CPLD3 + * + * Based on: + * pca954x.c from Kumar Gala + * Copyright (C) 2006 + * + * Based on: + * pca954x.c from Ken Harrenstien + * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) + * + * Based on: + * i2c-virtual_cb.c from Brian Kuschak + * and + * pca9540.c from Jean Delvare . + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define I2C_RW_RETRY_COUNT 10 +#define I2C_RW_RETRY_INTERVAL 60 /* ms */ + +#define NUM_OF_CPLD1_CHANS 0x0 +#define NUM_OF_CPLD2_CHANS 0x18 +#define NUM_OF_CPLD3_CHANS 0x1E +#define CPLD_CHANNEL_SELECT_REG 0x2 +#define CPLD_DESELECT_CHANNEL 0xFF + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +enum cpld_mux_type { + as5812_54x_cpld2, + as5812_54x_cpld3, + as5812_54x_cpld1 +}; + +struct as5812_54x_cpld_data { + enum cpld_mux_type type; + struct i2c_client *client; + u8 last_chan; /* last register value */ + + struct device *hwmon_dev; + struct mutex update_lock; +}; + +struct chip_desc { + u8 nchans; + u8 deselectChan; +}; + +/* Provide specs for the PCA954x types we know about */ +static const struct chip_desc chips[] = { + [as5812_54x_cpld1] = { + .nchans = NUM_OF_CPLD1_CHANS, + .deselectChan = CPLD_DESELECT_CHANNEL, + }, + [as5812_54x_cpld2] = { + .nchans = NUM_OF_CPLD2_CHANS, + .deselectChan = CPLD_DESELECT_CHANNEL, + }, + [as5812_54x_cpld3] = { + .nchans = NUM_OF_CPLD3_CHANS, + .deselectChan = CPLD_DESELECT_CHANNEL, + } +}; + +static const struct i2c_device_id as5812_54x_cpld_mux_id[] = { + { "as5812_54x_cpld1", as5812_54x_cpld1 }, + { "as5812_54x_cpld2", as5812_54x_cpld2 }, + { "as5812_54x_cpld3", as5812_54x_cpld3 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, as5812_54x_cpld_mux_id); + +#define TRANSCEIVER_PRESENT_ATTR_ID(index) MODULE_PRESENT_##index +#define TRANSCEIVER_TXDISABLE_ATTR_ID(index) MODULE_TXDISABLE_##index +#define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index +#define TRANSCEIVER_TXFAULT_ATTR_ID(index) MODULE_TXFAULT_##index +#define TRANSCEIVER_LPMODE_ATTR_ID(index) MODULE_LPMODE_##index +#define TRANSCEIVER_RESET_ATTR_ID(index) MODULE_RESET_##index + +enum as5812_54x_cpld1_sysfs_attributes { + CPLD_VERSION, + ACCESS, + MODULE_PRESENT_ALL, + MODULE_RXLOS_ALL, + /* transceiver attributes */ + TRANSCEIVER_PRESENT_ATTR_ID(1), + TRANSCEIVER_PRESENT_ATTR_ID(2), + TRANSCEIVER_PRESENT_ATTR_ID(3), + TRANSCEIVER_PRESENT_ATTR_ID(4), + TRANSCEIVER_PRESENT_ATTR_ID(5), + TRANSCEIVER_PRESENT_ATTR_ID(6), + TRANSCEIVER_PRESENT_ATTR_ID(7), + TRANSCEIVER_PRESENT_ATTR_ID(8), + TRANSCEIVER_PRESENT_ATTR_ID(9), + TRANSCEIVER_PRESENT_ATTR_ID(10), + TRANSCEIVER_PRESENT_ATTR_ID(11), + TRANSCEIVER_PRESENT_ATTR_ID(12), + TRANSCEIVER_PRESENT_ATTR_ID(13), + TRANSCEIVER_PRESENT_ATTR_ID(14), + TRANSCEIVER_PRESENT_ATTR_ID(15), + TRANSCEIVER_PRESENT_ATTR_ID(16), + TRANSCEIVER_PRESENT_ATTR_ID(17), + TRANSCEIVER_PRESENT_ATTR_ID(18), + TRANSCEIVER_PRESENT_ATTR_ID(19), + TRANSCEIVER_PRESENT_ATTR_ID(20), + TRANSCEIVER_PRESENT_ATTR_ID(21), + TRANSCEIVER_PRESENT_ATTR_ID(22), + TRANSCEIVER_PRESENT_ATTR_ID(23), + TRANSCEIVER_PRESENT_ATTR_ID(24), + TRANSCEIVER_PRESENT_ATTR_ID(25), + TRANSCEIVER_PRESENT_ATTR_ID(26), + TRANSCEIVER_PRESENT_ATTR_ID(27), + TRANSCEIVER_PRESENT_ATTR_ID(28), + TRANSCEIVER_PRESENT_ATTR_ID(29), + TRANSCEIVER_PRESENT_ATTR_ID(30), + TRANSCEIVER_PRESENT_ATTR_ID(31), + TRANSCEIVER_PRESENT_ATTR_ID(32), + TRANSCEIVER_PRESENT_ATTR_ID(33), + TRANSCEIVER_PRESENT_ATTR_ID(34), + TRANSCEIVER_PRESENT_ATTR_ID(35), + TRANSCEIVER_PRESENT_ATTR_ID(36), + TRANSCEIVER_PRESENT_ATTR_ID(37), + TRANSCEIVER_PRESENT_ATTR_ID(38), + TRANSCEIVER_PRESENT_ATTR_ID(39), + TRANSCEIVER_PRESENT_ATTR_ID(40), + TRANSCEIVER_PRESENT_ATTR_ID(41), + TRANSCEIVER_PRESENT_ATTR_ID(42), + TRANSCEIVER_PRESENT_ATTR_ID(43), + TRANSCEIVER_PRESENT_ATTR_ID(44), + TRANSCEIVER_PRESENT_ATTR_ID(45), + TRANSCEIVER_PRESENT_ATTR_ID(46), + TRANSCEIVER_PRESENT_ATTR_ID(47), + TRANSCEIVER_PRESENT_ATTR_ID(48), + TRANSCEIVER_PRESENT_ATTR_ID(49), + TRANSCEIVER_PRESENT_ATTR_ID(50), + TRANSCEIVER_PRESENT_ATTR_ID(51), + TRANSCEIVER_PRESENT_ATTR_ID(52), + TRANSCEIVER_PRESENT_ATTR_ID(53), + TRANSCEIVER_PRESENT_ATTR_ID(54), + TRANSCEIVER_TXDISABLE_ATTR_ID(1), + TRANSCEIVER_TXDISABLE_ATTR_ID(2), + TRANSCEIVER_TXDISABLE_ATTR_ID(3), + TRANSCEIVER_TXDISABLE_ATTR_ID(4), + TRANSCEIVER_TXDISABLE_ATTR_ID(5), + TRANSCEIVER_TXDISABLE_ATTR_ID(6), + TRANSCEIVER_TXDISABLE_ATTR_ID(7), + TRANSCEIVER_TXDISABLE_ATTR_ID(8), + TRANSCEIVER_TXDISABLE_ATTR_ID(9), + TRANSCEIVER_TXDISABLE_ATTR_ID(10), + TRANSCEIVER_TXDISABLE_ATTR_ID(11), + TRANSCEIVER_TXDISABLE_ATTR_ID(12), + TRANSCEIVER_TXDISABLE_ATTR_ID(13), + TRANSCEIVER_TXDISABLE_ATTR_ID(14), + TRANSCEIVER_TXDISABLE_ATTR_ID(15), + TRANSCEIVER_TXDISABLE_ATTR_ID(16), + TRANSCEIVER_TXDISABLE_ATTR_ID(17), + TRANSCEIVER_TXDISABLE_ATTR_ID(18), + TRANSCEIVER_TXDISABLE_ATTR_ID(19), + TRANSCEIVER_TXDISABLE_ATTR_ID(20), + TRANSCEIVER_TXDISABLE_ATTR_ID(21), + TRANSCEIVER_TXDISABLE_ATTR_ID(22), + TRANSCEIVER_TXDISABLE_ATTR_ID(23), + TRANSCEIVER_TXDISABLE_ATTR_ID(24), + TRANSCEIVER_TXDISABLE_ATTR_ID(25), + TRANSCEIVER_TXDISABLE_ATTR_ID(26), + TRANSCEIVER_TXDISABLE_ATTR_ID(27), + TRANSCEIVER_TXDISABLE_ATTR_ID(28), + TRANSCEIVER_TXDISABLE_ATTR_ID(29), + TRANSCEIVER_TXDISABLE_ATTR_ID(30), + TRANSCEIVER_TXDISABLE_ATTR_ID(31), + TRANSCEIVER_TXDISABLE_ATTR_ID(32), + TRANSCEIVER_TXDISABLE_ATTR_ID(33), + TRANSCEIVER_TXDISABLE_ATTR_ID(34), + TRANSCEIVER_TXDISABLE_ATTR_ID(35), + TRANSCEIVER_TXDISABLE_ATTR_ID(36), + TRANSCEIVER_TXDISABLE_ATTR_ID(37), + TRANSCEIVER_TXDISABLE_ATTR_ID(38), + TRANSCEIVER_TXDISABLE_ATTR_ID(39), + TRANSCEIVER_TXDISABLE_ATTR_ID(40), + TRANSCEIVER_TXDISABLE_ATTR_ID(41), + TRANSCEIVER_TXDISABLE_ATTR_ID(42), + TRANSCEIVER_TXDISABLE_ATTR_ID(43), + TRANSCEIVER_TXDISABLE_ATTR_ID(44), + TRANSCEIVER_TXDISABLE_ATTR_ID(45), + TRANSCEIVER_TXDISABLE_ATTR_ID(46), + TRANSCEIVER_TXDISABLE_ATTR_ID(47), + TRANSCEIVER_TXDISABLE_ATTR_ID(48), + TRANSCEIVER_RXLOS_ATTR_ID(1), + TRANSCEIVER_RXLOS_ATTR_ID(2), + TRANSCEIVER_RXLOS_ATTR_ID(3), + TRANSCEIVER_RXLOS_ATTR_ID(4), + TRANSCEIVER_RXLOS_ATTR_ID(5), + TRANSCEIVER_RXLOS_ATTR_ID(6), + TRANSCEIVER_RXLOS_ATTR_ID(7), + TRANSCEIVER_RXLOS_ATTR_ID(8), + TRANSCEIVER_RXLOS_ATTR_ID(9), + TRANSCEIVER_RXLOS_ATTR_ID(10), + TRANSCEIVER_RXLOS_ATTR_ID(11), + TRANSCEIVER_RXLOS_ATTR_ID(12), + TRANSCEIVER_RXLOS_ATTR_ID(13), + TRANSCEIVER_RXLOS_ATTR_ID(14), + TRANSCEIVER_RXLOS_ATTR_ID(15), + TRANSCEIVER_RXLOS_ATTR_ID(16), + TRANSCEIVER_RXLOS_ATTR_ID(17), + TRANSCEIVER_RXLOS_ATTR_ID(18), + TRANSCEIVER_RXLOS_ATTR_ID(19), + TRANSCEIVER_RXLOS_ATTR_ID(20), + TRANSCEIVER_RXLOS_ATTR_ID(21), + TRANSCEIVER_RXLOS_ATTR_ID(22), + TRANSCEIVER_RXLOS_ATTR_ID(23), + TRANSCEIVER_RXLOS_ATTR_ID(24), + TRANSCEIVER_RXLOS_ATTR_ID(25), + TRANSCEIVER_RXLOS_ATTR_ID(26), + TRANSCEIVER_RXLOS_ATTR_ID(27), + TRANSCEIVER_RXLOS_ATTR_ID(28), + TRANSCEIVER_RXLOS_ATTR_ID(29), + TRANSCEIVER_RXLOS_ATTR_ID(30), + TRANSCEIVER_RXLOS_ATTR_ID(31), + TRANSCEIVER_RXLOS_ATTR_ID(32), + TRANSCEIVER_RXLOS_ATTR_ID(33), + TRANSCEIVER_RXLOS_ATTR_ID(34), + TRANSCEIVER_RXLOS_ATTR_ID(35), + TRANSCEIVER_RXLOS_ATTR_ID(36), + TRANSCEIVER_RXLOS_ATTR_ID(37), + TRANSCEIVER_RXLOS_ATTR_ID(38), + TRANSCEIVER_RXLOS_ATTR_ID(39), + TRANSCEIVER_RXLOS_ATTR_ID(40), + TRANSCEIVER_RXLOS_ATTR_ID(41), + TRANSCEIVER_RXLOS_ATTR_ID(42), + TRANSCEIVER_RXLOS_ATTR_ID(43), + TRANSCEIVER_RXLOS_ATTR_ID(44), + TRANSCEIVER_RXLOS_ATTR_ID(45), + TRANSCEIVER_RXLOS_ATTR_ID(46), + TRANSCEIVER_RXLOS_ATTR_ID(47), + TRANSCEIVER_RXLOS_ATTR_ID(48), + TRANSCEIVER_TXFAULT_ATTR_ID(1), + TRANSCEIVER_TXFAULT_ATTR_ID(2), + TRANSCEIVER_TXFAULT_ATTR_ID(3), + TRANSCEIVER_TXFAULT_ATTR_ID(4), + TRANSCEIVER_TXFAULT_ATTR_ID(5), + TRANSCEIVER_TXFAULT_ATTR_ID(6), + TRANSCEIVER_TXFAULT_ATTR_ID(7), + TRANSCEIVER_TXFAULT_ATTR_ID(8), + TRANSCEIVER_TXFAULT_ATTR_ID(9), + TRANSCEIVER_TXFAULT_ATTR_ID(10), + TRANSCEIVER_TXFAULT_ATTR_ID(11), + TRANSCEIVER_TXFAULT_ATTR_ID(12), + TRANSCEIVER_TXFAULT_ATTR_ID(13), + TRANSCEIVER_TXFAULT_ATTR_ID(14), + TRANSCEIVER_TXFAULT_ATTR_ID(15), + TRANSCEIVER_TXFAULT_ATTR_ID(16), + TRANSCEIVER_TXFAULT_ATTR_ID(17), + TRANSCEIVER_TXFAULT_ATTR_ID(18), + TRANSCEIVER_TXFAULT_ATTR_ID(19), + TRANSCEIVER_TXFAULT_ATTR_ID(20), + TRANSCEIVER_TXFAULT_ATTR_ID(21), + TRANSCEIVER_TXFAULT_ATTR_ID(22), + TRANSCEIVER_TXFAULT_ATTR_ID(23), + TRANSCEIVER_TXFAULT_ATTR_ID(24), + TRANSCEIVER_TXFAULT_ATTR_ID(25), + TRANSCEIVER_TXFAULT_ATTR_ID(26), + TRANSCEIVER_TXFAULT_ATTR_ID(27), + TRANSCEIVER_TXFAULT_ATTR_ID(28), + TRANSCEIVER_TXFAULT_ATTR_ID(29), + TRANSCEIVER_TXFAULT_ATTR_ID(30), + TRANSCEIVER_TXFAULT_ATTR_ID(31), + TRANSCEIVER_TXFAULT_ATTR_ID(32), + TRANSCEIVER_TXFAULT_ATTR_ID(33), + TRANSCEIVER_TXFAULT_ATTR_ID(34), + TRANSCEIVER_TXFAULT_ATTR_ID(35), + TRANSCEIVER_TXFAULT_ATTR_ID(36), + TRANSCEIVER_TXFAULT_ATTR_ID(37), + TRANSCEIVER_TXFAULT_ATTR_ID(38), + TRANSCEIVER_TXFAULT_ATTR_ID(39), + TRANSCEIVER_TXFAULT_ATTR_ID(40), + TRANSCEIVER_TXFAULT_ATTR_ID(41), + TRANSCEIVER_TXFAULT_ATTR_ID(42), + TRANSCEIVER_TXFAULT_ATTR_ID(43), + TRANSCEIVER_TXFAULT_ATTR_ID(44), + TRANSCEIVER_TXFAULT_ATTR_ID(45), + TRANSCEIVER_TXFAULT_ATTR_ID(46), + TRANSCEIVER_TXFAULT_ATTR_ID(47), + TRANSCEIVER_TXFAULT_ATTR_ID(48), + TRANSCEIVER_LPMODE_ATTR_ID(49), + TRANSCEIVER_LPMODE_ATTR_ID(50), + TRANSCEIVER_LPMODE_ATTR_ID(51), + TRANSCEIVER_LPMODE_ATTR_ID(52), + TRANSCEIVER_LPMODE_ATTR_ID(53), + TRANSCEIVER_LPMODE_ATTR_ID(54), + TRANSCEIVER_RESET_ATTR_ID(49), + TRANSCEIVER_RESET_ATTR_ID(50), + TRANSCEIVER_RESET_ATTR_ID(51), + TRANSCEIVER_RESET_ATTR_ID(52), + TRANSCEIVER_RESET_ATTR_ID(53), + TRANSCEIVER_RESET_ATTR_ID(54), +}; + +/* sysfs attributes for hwmon + */ +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_present_all(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t set_lp_mode(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t show_version(struct device *dev, struct device_attribute *da, + char *buf); +static int as5812_54x_cpld_read_internal(struct i2c_client *client, u8 reg); +static int as5812_54x_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value); + +/* transceiver attributes */ +#define DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, show_status, NULL, MODULE_PRESENT_##index) +#define DECLARE_TRANSCEIVER_PRESENT_ATTR(index) &sensor_dev_attr_module_present_##index.dev_attr.attr + +#define DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_tx_disable_##index, S_IRUGO | S_IWUSR, show_status, set_tx_disable, MODULE_TXDISABLE_##index); \ + static SENSOR_DEVICE_ATTR(module_rx_los_##index, S_IRUGO, show_status, NULL, MODULE_RXLOS_##index); \ + static SENSOR_DEVICE_ATTR(module_tx_fault_##index, S_IRUGO, show_status, NULL, MODULE_TXFAULT_##index) + +#define DECLARE_SFP_TRANSCEIVER_ATTR(index) \ + &sensor_dev_attr_module_tx_disable_##index.dev_attr.attr, \ + &sensor_dev_attr_module_rx_los_##index.dev_attr.attr, \ + &sensor_dev_attr_module_tx_fault_##index.dev_attr.attr + +#define DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_lp_mode_##index, S_IRUGO | S_IWUSR, show_status, set_lp_mode, MODULE_LPMODE_##index); \ + static SENSOR_DEVICE_ATTR(module_reset_##index, S_IWUSR | S_IRUGO, show_status, set_mode_reset, MODULE_RESET_##index) + +#define DECLARE_QSFP_TRANSCEIVER_ATTR(index) \ + &sensor_dev_attr_module_lp_mode_##index.dev_attr.attr, \ + &sensor_dev_attr_module_reset_##index.dev_attr.attr + + +static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION); +static SENSOR_DEVICE_ATTR(access, S_IWUSR, NULL, access, ACCESS); +/* transceiver attributes */ +static SENSOR_DEVICE_ATTR(module_present_all, S_IRUGO, show_present_all, NULL, MODULE_PRESENT_ALL); +static SENSOR_DEVICE_ATTR(module_rx_los_all, S_IRUGO, show_rxlos_all, NULL, MODULE_RXLOS_ALL); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(1); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(2); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(3); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(4); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(5); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(6); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(7); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(8); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(9); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(10); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(11); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(12); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(13); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(14); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(15); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(16); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(17); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(18); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(19); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(20); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(21); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(22); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(23); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(24); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(25); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(26); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(27); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(28); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(29); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(30); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(31); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(32); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(33); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(34); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(35); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(36); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(37); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(38); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(39); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(40); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(41); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(42); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(43); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(44); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(45); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(46); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(47); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(48); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(49); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(50); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(51); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(52); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(53); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(54); + +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(1); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(2); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(3); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(4); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(5); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(6); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(7); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(8); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(9); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(10); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(11); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(12); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(13); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(14); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(15); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(16); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(17); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(18); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(19); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(20); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(21); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(22); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(23); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(24); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(25); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(26); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(27); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(28); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(29); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(30); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(31); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(32); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(33); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(34); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(35); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(36); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(37); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(38); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(39); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(40); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(41); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(42); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(43); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(44); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(45); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(46); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(47); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(48); +DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(49); +DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(50); +DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(51); +DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(52); +DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(53); +DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(54); + +static struct attribute *as5812_54x_cpld1_attributes[] = { + &sensor_dev_attr_version.dev_attr.attr, + &sensor_dev_attr_access.dev_attr.attr, + NULL +}; + +static const struct attribute_group as5812_54x_cpld1_group = { + .attrs = as5812_54x_cpld1_attributes, +}; + +static struct attribute *as5812_54x_cpld2_attributes[] = { + &sensor_dev_attr_version.dev_attr.attr, + &sensor_dev_attr_access.dev_attr.attr, + /* transceiver attributes */ + &sensor_dev_attr_module_present_all.dev_attr.attr, + &sensor_dev_attr_module_rx_los_all.dev_attr.attr, + DECLARE_TRANSCEIVER_PRESENT_ATTR(1), + DECLARE_TRANSCEIVER_PRESENT_ATTR(2), + DECLARE_TRANSCEIVER_PRESENT_ATTR(3), + DECLARE_TRANSCEIVER_PRESENT_ATTR(4), + DECLARE_TRANSCEIVER_PRESENT_ATTR(5), + DECLARE_TRANSCEIVER_PRESENT_ATTR(6), + DECLARE_TRANSCEIVER_PRESENT_ATTR(7), + DECLARE_TRANSCEIVER_PRESENT_ATTR(8), + DECLARE_TRANSCEIVER_PRESENT_ATTR(9), + DECLARE_TRANSCEIVER_PRESENT_ATTR(10), + DECLARE_TRANSCEIVER_PRESENT_ATTR(11), + DECLARE_TRANSCEIVER_PRESENT_ATTR(12), + DECLARE_TRANSCEIVER_PRESENT_ATTR(13), + DECLARE_TRANSCEIVER_PRESENT_ATTR(14), + DECLARE_TRANSCEIVER_PRESENT_ATTR(15), + DECLARE_TRANSCEIVER_PRESENT_ATTR(16), + DECLARE_TRANSCEIVER_PRESENT_ATTR(17), + DECLARE_TRANSCEIVER_PRESENT_ATTR(18), + DECLARE_TRANSCEIVER_PRESENT_ATTR(19), + DECLARE_TRANSCEIVER_PRESENT_ATTR(20), + DECLARE_TRANSCEIVER_PRESENT_ATTR(21), + DECLARE_TRANSCEIVER_PRESENT_ATTR(22), + DECLARE_TRANSCEIVER_PRESENT_ATTR(23), + DECLARE_TRANSCEIVER_PRESENT_ATTR(24), + DECLARE_SFP_TRANSCEIVER_ATTR(1), + DECLARE_SFP_TRANSCEIVER_ATTR(2), + DECLARE_SFP_TRANSCEIVER_ATTR(3), + DECLARE_SFP_TRANSCEIVER_ATTR(4), + DECLARE_SFP_TRANSCEIVER_ATTR(5), + DECLARE_SFP_TRANSCEIVER_ATTR(6), + DECLARE_SFP_TRANSCEIVER_ATTR(7), + DECLARE_SFP_TRANSCEIVER_ATTR(8), + DECLARE_SFP_TRANSCEIVER_ATTR(9), + DECLARE_SFP_TRANSCEIVER_ATTR(10), + DECLARE_SFP_TRANSCEIVER_ATTR(11), + DECLARE_SFP_TRANSCEIVER_ATTR(12), + DECLARE_SFP_TRANSCEIVER_ATTR(13), + DECLARE_SFP_TRANSCEIVER_ATTR(14), + DECLARE_SFP_TRANSCEIVER_ATTR(15), + DECLARE_SFP_TRANSCEIVER_ATTR(16), + DECLARE_SFP_TRANSCEIVER_ATTR(17), + DECLARE_SFP_TRANSCEIVER_ATTR(18), + DECLARE_SFP_TRANSCEIVER_ATTR(19), + DECLARE_SFP_TRANSCEIVER_ATTR(20), + DECLARE_SFP_TRANSCEIVER_ATTR(21), + DECLARE_SFP_TRANSCEIVER_ATTR(22), + DECLARE_SFP_TRANSCEIVER_ATTR(23), + DECLARE_SFP_TRANSCEIVER_ATTR(24), + NULL +}; + +static const struct attribute_group as5812_54x_cpld2_group = { + .attrs = as5812_54x_cpld2_attributes, +}; + +static struct attribute *as5812_54x_cpld3_attributes[] = { + &sensor_dev_attr_version.dev_attr.attr, + &sensor_dev_attr_access.dev_attr.attr, + /* transceiver attributes */ + &sensor_dev_attr_module_present_all.dev_attr.attr, + &sensor_dev_attr_module_rx_los_all.dev_attr.attr, + DECLARE_TRANSCEIVER_PRESENT_ATTR(25), + DECLARE_TRANSCEIVER_PRESENT_ATTR(26), + DECLARE_TRANSCEIVER_PRESENT_ATTR(27), + DECLARE_TRANSCEIVER_PRESENT_ATTR(28), + DECLARE_TRANSCEIVER_PRESENT_ATTR(29), + DECLARE_TRANSCEIVER_PRESENT_ATTR(30), + DECLARE_TRANSCEIVER_PRESENT_ATTR(31), + DECLARE_TRANSCEIVER_PRESENT_ATTR(32), + DECLARE_TRANSCEIVER_PRESENT_ATTR(33), + DECLARE_TRANSCEIVER_PRESENT_ATTR(34), + DECLARE_TRANSCEIVER_PRESENT_ATTR(35), + DECLARE_TRANSCEIVER_PRESENT_ATTR(36), + DECLARE_TRANSCEIVER_PRESENT_ATTR(37), + DECLARE_TRANSCEIVER_PRESENT_ATTR(38), + DECLARE_TRANSCEIVER_PRESENT_ATTR(39), + DECLARE_TRANSCEIVER_PRESENT_ATTR(40), + DECLARE_TRANSCEIVER_PRESENT_ATTR(41), + DECLARE_TRANSCEIVER_PRESENT_ATTR(42), + DECLARE_TRANSCEIVER_PRESENT_ATTR(43), + DECLARE_TRANSCEIVER_PRESENT_ATTR(44), + DECLARE_TRANSCEIVER_PRESENT_ATTR(45), + DECLARE_TRANSCEIVER_PRESENT_ATTR(46), + DECLARE_TRANSCEIVER_PRESENT_ATTR(47), + DECLARE_TRANSCEIVER_PRESENT_ATTR(48), + DECLARE_TRANSCEIVER_PRESENT_ATTR(49), + DECLARE_TRANSCEIVER_PRESENT_ATTR(50), + DECLARE_TRANSCEIVER_PRESENT_ATTR(51), + DECLARE_TRANSCEIVER_PRESENT_ATTR(52), + DECLARE_TRANSCEIVER_PRESENT_ATTR(53), + DECLARE_TRANSCEIVER_PRESENT_ATTR(54), + DECLARE_SFP_TRANSCEIVER_ATTR(25), + DECLARE_SFP_TRANSCEIVER_ATTR(26), + DECLARE_SFP_TRANSCEIVER_ATTR(27), + DECLARE_SFP_TRANSCEIVER_ATTR(28), + DECLARE_SFP_TRANSCEIVER_ATTR(29), + DECLARE_SFP_TRANSCEIVER_ATTR(30), + DECLARE_SFP_TRANSCEIVER_ATTR(31), + DECLARE_SFP_TRANSCEIVER_ATTR(32), + DECLARE_SFP_TRANSCEIVER_ATTR(33), + DECLARE_SFP_TRANSCEIVER_ATTR(34), + DECLARE_SFP_TRANSCEIVER_ATTR(35), + DECLARE_SFP_TRANSCEIVER_ATTR(36), + DECLARE_SFP_TRANSCEIVER_ATTR(37), + DECLARE_SFP_TRANSCEIVER_ATTR(38), + DECLARE_SFP_TRANSCEIVER_ATTR(39), + DECLARE_SFP_TRANSCEIVER_ATTR(40), + DECLARE_SFP_TRANSCEIVER_ATTR(41), + DECLARE_SFP_TRANSCEIVER_ATTR(42), + DECLARE_SFP_TRANSCEIVER_ATTR(43), + DECLARE_SFP_TRANSCEIVER_ATTR(44), + DECLARE_SFP_TRANSCEIVER_ATTR(45), + DECLARE_SFP_TRANSCEIVER_ATTR(46), + DECLARE_SFP_TRANSCEIVER_ATTR(47), + DECLARE_SFP_TRANSCEIVER_ATTR(48), + DECLARE_QSFP_TRANSCEIVER_ATTR(49), + DECLARE_QSFP_TRANSCEIVER_ATTR(50), + DECLARE_QSFP_TRANSCEIVER_ATTR(51), + DECLARE_QSFP_TRANSCEIVER_ATTR(52), + DECLARE_QSFP_TRANSCEIVER_ATTR(53), + DECLARE_QSFP_TRANSCEIVER_ATTR(54), + NULL +}; + +static const struct attribute_group as5812_54x_cpld3_group = { + .attrs = as5812_54x_cpld3_attributes, +}; + +static ssize_t show_present_all(struct device *dev, struct device_attribute *da, + char *buf) +{ + int i, status, num_regs = 0; + u8 values[4] = {0}; + u8 regs[] = {0x6, 0x7, 0x8, 0x14}; + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct as5812_54x_cpld_data *data = i2c_mux_priv(muxc); + + mutex_lock(&data->update_lock); + + num_regs = (data->type == as5812_54x_cpld2) ? 3 : 4; + + for (i = 0; i < num_regs; i++) { + status = as5812_54x_cpld_read_internal(client, regs[i]); + + if (status < 0) { + goto exit; + } + + values[i] = ~(u8)status; + } + + mutex_unlock(&data->update_lock); + + /* Return values 1 -> 54 in order */ + if (data->type == as5812_54x_cpld2) { + status = sprintf(buf, "%.2x %.2x %.2x\n", + values[0], values[1], values[2]); + } + else { /* as5812_54x_cpld3 */ + values[3] &= 0x3F; + status = sprintf(buf, "%.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], values[3]); + } + + return status; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, + char *buf) +{ + int i, status; + u8 values[3] = {0}; + u8 regs[] = {0xF, 0x10, 0x11}; + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct as5812_54x_cpld_data *data = i2c_mux_priv(muxc); + + mutex_lock(&data->update_lock); + + for (i = 0; i < ARRAY_SIZE(regs); i++) { + status = as5812_54x_cpld_read_internal(client, regs[i]); + + if (status < 0) { + goto exit; + } + + values[i] = (u8)status; + } + + mutex_unlock(&data->update_lock); + + /* Return values 1 -> 24 in order */ + return sprintf(buf, "%.2x %.2x %.2x\n", values[0], values[1], values[2]); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct as5812_54x_cpld_data *data = i2c_mux_priv(muxc); + int status = 0; + u8 reg = 0, mask = 0, revert = 0; + + switch (attr->index) { + case MODULE_PRESENT_1 ... MODULE_PRESENT_8: + reg = 0x6; + mask = 0x1 << (attr->index - MODULE_PRESENT_1); + break; + case MODULE_PRESENT_9 ... MODULE_PRESENT_16: + reg = 0x7; + mask = 0x1 << (attr->index - MODULE_PRESENT_9); + break; + case MODULE_PRESENT_17 ... MODULE_PRESENT_24: + reg = 0x8; + mask = 0x1 << (attr->index - MODULE_PRESENT_17); + break; + case MODULE_PRESENT_25 ... MODULE_PRESENT_32: + reg = 0x6; + mask = 0x1 << (attr->index - MODULE_PRESENT_25); + break; + case MODULE_PRESENT_33 ... MODULE_PRESENT_40: + reg = 0x7; + mask = 0x1 << (attr->index - MODULE_PRESENT_33); + break; + case MODULE_PRESENT_41 ... MODULE_PRESENT_48: + reg = 0x8; + mask = 0x1 << (attr->index - MODULE_PRESENT_41); + break; + case MODULE_PRESENT_49: + reg = 0x14; + mask = 0x1; + break; + case MODULE_PRESENT_50: + reg = 0x14; + mask = 0x4; + break; + case MODULE_PRESENT_51: + reg = 0x14; + mask = 0x10; + break; + case MODULE_PRESENT_52: + reg = 0x14; + mask = 0x2; + break; + case MODULE_PRESENT_53: + reg = 0x14; + mask = 0x8; + break; + case MODULE_PRESENT_54: + reg = 0x14; + mask = 0x20; + break; + case MODULE_TXFAULT_1 ... MODULE_TXFAULT_8: + reg = 0x9; + mask = 0x1 << (attr->index - MODULE_TXFAULT_1); + break; + case MODULE_TXFAULT_9 ... MODULE_TXFAULT_16: + reg = 0xA; + mask = 0x1 << (attr->index - MODULE_TXFAULT_9); + break; + case MODULE_TXFAULT_17 ... MODULE_TXFAULT_24: + reg = 0xB; + mask = 0x1 << (attr->index - MODULE_TXFAULT_17); + break; + case MODULE_TXFAULT_25 ... MODULE_TXFAULT_32: + reg = 0x9; + mask = 0x1 << (attr->index - MODULE_TXFAULT_25); + break; + case MODULE_TXFAULT_33 ... MODULE_TXFAULT_40: + reg = 0xA; + mask = 0x1 << (attr->index - MODULE_TXFAULT_33); + break; + case MODULE_TXFAULT_41 ... MODULE_TXFAULT_48: + reg = 0xB; + mask = 0x1 << (attr->index - MODULE_TXFAULT_41); + break; + case MODULE_TXDISABLE_1 ... MODULE_TXDISABLE_8: + reg = 0xC; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_1); + break; + case MODULE_TXDISABLE_9 ... MODULE_TXDISABLE_16: + reg = 0xD; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_9); + break; + case MODULE_TXDISABLE_17 ... MODULE_TXDISABLE_24: + reg = 0xE; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_17); + break; + case MODULE_TXDISABLE_25 ... MODULE_TXDISABLE_32: + reg = 0xC; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_25); + break; + case MODULE_TXDISABLE_33 ... MODULE_TXDISABLE_40: + reg = 0xD; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_33); + break; + case MODULE_TXDISABLE_41 ... MODULE_TXDISABLE_48: + reg = 0xE; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_41); + break; + case MODULE_RXLOS_1 ... MODULE_RXLOS_8: + reg = 0xF; + mask = 0x1 << (attr->index - MODULE_RXLOS_1); + break; + case MODULE_RXLOS_9 ... MODULE_RXLOS_16: + reg = 0x10; + mask = 0x1 << (attr->index - MODULE_RXLOS_9); + break; + case MODULE_RXLOS_17 ... MODULE_RXLOS_24: + reg = 0x11; + mask = 0x1 << (attr->index - MODULE_RXLOS_17); + break; + case MODULE_RXLOS_25 ... MODULE_RXLOS_32: + reg = 0xF; + mask = 0x1 << (attr->index - MODULE_RXLOS_25); + break; + case MODULE_RXLOS_33 ... MODULE_RXLOS_40: + reg = 0x10; + mask = 0x1 << (attr->index - MODULE_RXLOS_33); + break; + case MODULE_RXLOS_41 ... MODULE_RXLOS_48: + reg = 0x11; + mask = 0x1 << (attr->index - MODULE_RXLOS_41); + break; + case MODULE_LPMODE_49 ... MODULE_LPMODE_54: + reg = 0x16; + mask = 0x1 << (attr->index - MODULE_LPMODE_49); + break; + case MODULE_RESET_49 ... MODULE_RESET_54: + reg = 0x15; + mask = 0x1 << (attr->index - MODULE_RESET_49); + break; + default: + return 0; + } + + if (attr->index >= MODULE_PRESENT_1 && attr->index <= MODULE_PRESENT_54) { + revert = 1; + } + + mutex_lock(&data->update_lock); + status = as5812_54x_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", revert ? !(status & mask) : !!(status & mask)); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct as5812_54x_cpld_data *data = i2c_mux_priv(muxc); + long disable; + int status; + u8 reg = 0, mask = 0; + + status = kstrtol(buf, 10, &disable); + if (status) { + return status; + } + + switch (attr->index) { + case MODULE_TXDISABLE_1 ... MODULE_TXDISABLE_8: + reg = 0xC; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_1); + break; + case MODULE_TXDISABLE_9 ... MODULE_TXDISABLE_16: + reg = 0xD; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_9); + break; + case MODULE_TXDISABLE_17 ... MODULE_TXDISABLE_24: + reg = 0xE; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_17); + break; + case MODULE_TXDISABLE_25 ... MODULE_TXDISABLE_32: + reg = 0xC; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_25); + break; + case MODULE_TXDISABLE_33 ... MODULE_TXDISABLE_40: + reg = 0xD; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_33); + break; + case MODULE_TXDISABLE_41 ... MODULE_TXDISABLE_48: + reg = 0xE; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_41); + break; + default: + return 0; + } + + /* Read current status */ + mutex_lock(&data->update_lock); + status = as5812_54x_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + + /* Update tx_disable status */ + if (disable) { + status |= mask; + } + else { + status &= ~mask; + } + + status = as5812_54x_cpld_write_internal(client, reg, status); + if (unlikely(status < 0)) { + goto exit; + } + + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t set_lp_mode(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct as5812_54x_cpld_data *data = i2c_mux_priv(muxc); + + long on; + int status= -ENOENT; + u8 reg = 0x16, mask = 0; + + if(attr->index < MODULE_LPMODE_49 || attr->index > MODULE_LPMODE_54) + return status; + + status = kstrtol(buf, 10, &on); + if (status) { + return status; + } + + /* Read current status */ + mutex_lock(&data->update_lock); + status = as5812_54x_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + + mask = 0x1 << (attr->index - MODULE_LPMODE_49); + + /* Update lp_mode status */ + if (on) { + status |= mask; + } + else { + status &= ~mask; + } + + status = as5812_54x_cpld_write_internal(client, reg, status); + if (unlikely(status < 0)) { + goto exit; + } + + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; + +} + +static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct as5812_54x_cpld_data *data = i2c_mux_priv(muxc); + + long on; + int status= -ENOENT; + u8 reg = 0x15, mask = 0; + + if(attr->index < MODULE_RESET_49 || attr->index > MODULE_RESET_54) + return status; + + status = kstrtol(buf, 10, &on); + if (status) { + return status; + } + + /* Read current status */ + mutex_lock(&data->update_lock); + status = as5812_54x_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + + mask = 0x1 << (attr->index - MODULE_RESET_49); + + /* Update tx_disable status */ + if (on) { + status |= mask; + } + else { + status &= ~mask; + } + + status = as5812_54x_cpld_write_internal(client, reg, status); + if (unlikely(status < 0)) { + goto exit; + } + + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; + +} + +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct as5812_54x_cpld_data *data = i2c_mux_priv(muxc); + int status; + u32 addr, val; + + if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) { + return -EINVAL; + } + + if (addr > 0xFF || val > 0xFF) { + return -EINVAL; + } + + mutex_lock(&data->update_lock); + status = as5812_54x_cpld_write_internal(client, addr, val); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +/* Write to mux register. Don't use i2c_transfer()/i2c_smbus_xfer() + for this as they will try to lock adapter a second time */ +static int as5812_54x_cpld_mux_reg_write(struct i2c_adapter *adap, + struct i2c_client *client, u8 val) +{ + unsigned long orig_jiffies; + unsigned short flags; + union i2c_smbus_data data; + int try; + s32 res = -EIO; + + data.byte = val; + flags = client->flags; + flags &= I2C_M_TEN | I2C_CLIENT_PEC; + + if (adap->algo->smbus_xfer) { + /* Retry automatically on arbitration loss */ + orig_jiffies = jiffies; + for (res = 0, try = 0; try <= adap->retries; try++) { + res = adap->algo->smbus_xfer(adap, client->addr, flags, + I2C_SMBUS_WRITE, CPLD_CHANNEL_SELECT_REG, + I2C_SMBUS_BYTE_DATA, &data); + if (res != -EAGAIN) + break; + if (time_after(jiffies, + orig_jiffies + adap->timeout)) + break; + } + } + + return res; +} + +static int as5812_54x_cpld_mux_select_chan(struct i2c_mux_core *muxc, + u32 chan) +{ + struct as5812_54x_cpld_data *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + u8 regval; + int ret = 0; + + regval = chan; + /* Only select the channel if its different from the last channel */ + if (data->last_chan != regval) { + ret = as5812_54x_cpld_mux_reg_write(muxc->parent, client, regval); + data->last_chan = regval; + } + + return ret; +} + +static int as5812_54x_cpld_mux_deselect_mux(struct i2c_mux_core *muxc, + u32 chan) +{ + struct as5812_54x_cpld_data *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + + /* Deselect active channel */ + data->last_chan = chips[data->type].deselectChan; + + return as5812_54x_cpld_mux_reg_write(muxc->parent, client, data->last_chan); +} + +static void as5812_54x_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +static void as5812_54x_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + + mutex_unlock(&list_lock); +} + +static ssize_t show_version(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0; + struct i2c_client *client = to_i2c_client(dev); + + val = i2c_smbus_read_byte_data(client, 0x1); + + if (val < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x1) err %d\n", client->addr, val); + } + + return sprintf(buf, "%d", val); +} + +/* + * I2C init/probing/exit functions + */ +static int as5812_54x_cpld_mux_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); + int num, force, class; + struct i2c_mux_core *muxc; + struct as5812_54x_cpld_data *data; + int ret = 0; + const struct attribute_group *group = NULL; + + if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) + return -ENODEV; + + muxc = i2c_mux_alloc(adap, &client->dev, + chips[id->driver_data].nchans, sizeof(*data), 0, + as5812_54x_cpld_mux_select_chan, as5812_54x_cpld_mux_deselect_mux); + if (!muxc) + return -ENOMEM; + + i2c_set_clientdata(client, muxc); + data = i2c_mux_priv(muxc); + data->client = client; + data->type = id->driver_data; + data->last_chan = chips[data->type].deselectChan; /* force the first selection */ + mutex_init(&data->update_lock); + + /* Now create an adapter for each channel */ + for (num = 0; num < chips[data->type].nchans; num++) { + force = 0; /* dynamic adap number */ + class = 0; /* no class by default */ + + ret = i2c_mux_add_adapter(muxc, force, num, class); + + if (ret) { + dev_err(&client->dev, + "failed to register multiplexed adapter" + " %d as bus %d\n", num, force); + goto add_mux_failed; + } + } + + /* Register sysfs hooks */ + switch (data->type) { + case as5812_54x_cpld1: + group = &as5812_54x_cpld1_group; + break; + case as5812_54x_cpld2: + group = &as5812_54x_cpld2_group; + break; + case as5812_54x_cpld3: + group = &as5812_54x_cpld3_group; + + /* Bring QSFPs out of reset */ + as5812_54x_cpld_write_internal(client, 0x15, 0x3F); + break; + default: + break; + } + + if (group) { + ret = sysfs_create_group(&client->dev.kobj, group); + if (ret) { + goto add_mux_failed; + } + } + + if (chips[data->type].nchans) { + dev_info(&client->dev, + "registered %d multiplexed busses for I2C %s\n", + num, client->name); + } + else { + dev_info(&client->dev, + "device %s registered\n", client->name); + } + + as5812_54x_cpld_add_client(client); + + return 0; + +add_mux_failed: + i2c_mux_del_adapters(muxc); + return ret; +} + +static int as5812_54x_cpld_mux_remove(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct as5812_54x_cpld_data *data = i2c_mux_priv(muxc); + const struct attribute_group *group = NULL; + + as5812_54x_cpld_remove_client(client); + + /* Remove sysfs hooks */ + switch (data->type) { + case as5812_54x_cpld1: + group = &as5812_54x_cpld1_group; + break; + case as5812_54x_cpld2: + group = &as5812_54x_cpld2_group; + break; + case as5812_54x_cpld3: + group = &as5812_54x_cpld3_group; + break; + default: + break; + } + + if (group) { + sysfs_remove_group(&client->dev.kobj, group); + } + + i2c_mux_del_adapters(muxc); + + return 0; +} + +static int as5812_54x_cpld_read_internal(struct i2c_client *client, u8 reg) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, reg); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + +static int as5812_54x_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, reg, value); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + +int as5812_54x_cpld_read(unsigned short cpld_addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EPERM; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = as5812_54x_cpld_read_internal(cpld_node->client, reg); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(as5812_54x_cpld_read); + +int as5812_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EIO; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = as5812_54x_cpld_write_internal(cpld_node->client, reg, value); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(as5812_54x_cpld_write); + +static struct i2c_driver as5812_54x_cpld_mux_driver = { + .driver = { + .name = "as5812_54x_cpld", + .owner = THIS_MODULE, + }, + .probe = as5812_54x_cpld_mux_probe, + .remove = as5812_54x_cpld_mux_remove, + .id_table = as5812_54x_cpld_mux_id, +}; + +static int __init as5812_54x_cpld_mux_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&as5812_54x_cpld_mux_driver); +} + +static void __exit as5812_54x_cpld_mux_exit(void) +{ + i2c_del_driver(&as5812_54x_cpld_mux_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("Accton as5812-54x CPLD driver"); +MODULE_LICENSE("GPL"); + +module_init(as5812_54x_cpld_mux_init); +module_exit(as5812_54x_cpld_mux_exit); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/leds-accton_as5812_54x.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/leds-accton_as5812_54x.c new file mode 100755 index 000000000000..2ebe948612c2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/leds-accton_as5812_54x.c @@ -0,0 +1,594 @@ +/* + * A LED driver for the accton_as5812_54x_led + * + * Copyright (C) 2013 Accton Technology Corporation. + * Brandon Chuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#if 0 +#define DEBUG +#endif + +#include +#include +#include +#include +#include +#include +#include + +extern int as5812_54x_cpld_read (unsigned short cpld_addr, u8 reg); +extern int as5812_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +extern void led_classdev_unregister(struct led_classdev *led_cdev); +extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); +extern void led_classdev_resume(struct led_classdev *led_cdev); +extern void led_classdev_suspend(struct led_classdev *led_cdev); + +#define DRVNAME "as5812_54x_led" + +struct accton_as5812_54x_led_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[4]; /* Register value, 0 = LOC/DIAG/FAN LED + 1 = PSU1/PSU2 LED + 2 = FAN1-4 LED + 3 = FAN5-6 LED */ +}; + +static struct accton_as5812_54x_led_data *ledctl = NULL; + +/* LED related data + */ +#define LED_TYPE_PSU1_REG_MASK 0x03 +#define LED_MODE_PSU1_GREEN_MASK 0x02 +#define LED_MODE_PSU1_AMBER_MASK 0x01 +#define LED_MODE_PSU1_OFF_MASK 0x03 +#define LED_MODE_PSU1_AUTO_MASK 0x00 + +#define LED_TYPE_PSU2_REG_MASK 0x0C +#define LED_MODE_PSU2_GREEN_MASK 0x08 +#define LED_MODE_PSU2_AMBER_MASK 0x04 +#define LED_MODE_PSU2_OFF_MASK 0x0C +#define LED_MODE_PSU2_AUTO_MASK 0x00 + +#define LED_TYPE_DIAG_REG_MASK 0x0C +#define LED_MODE_DIAG_GREEN_MASK 0x08 +#define LED_MODE_DIAG_AMBER_MASK 0x04 +#define LED_MODE_DIAG_OFF_MASK 0x0C + +#define LED_TYPE_FAN_REG_MASK 0x03 +#define LED_MODE_FAN_GREEN_MASK 0x02 +#define LED_MODE_FAN_AMBER_MASK 0x01 +#define LED_MODE_FAN_OFF_MASK 0x03 +#define LED_MODE_FAN_AUTO_MASK 0x00 + +#define LED_TYPE_FAN1_REG_MASK 0x03 +#define LED_TYPE_FAN2_REG_MASK 0x0C +#define LED_TYPE_FAN3_REG_MASK 0x30 +#define LED_TYPE_FAN4_REG_MASK 0xC0 +#define LED_TYPE_FAN5_REG_MASK 0x03 +#define LED_TYPE_FAN6_REG_MASK 0x0C + +#define LED_MODE_FANX_GREEN_MASK 0x01 +#define LED_MODE_FANX_RED_MASK 0x02 +#define LED_MODE_FANX_OFF_MASK 0x00 + +#define LED_TYPE_LOC_REG_MASK 0x30 +#define LED_MODE_LOC_ON_MASK 0x00 +#define LED_MODE_LOC_OFF_MASK 0x10 +#define LED_MODE_LOC_BLINK_MASK 0x20 + +static const u8 led_reg[] = { + 0xA, /* LOC/DIAG/FAN LED*/ + 0xB, /* PSU1/PSU2 LED */ + 0x16, /* FAN1-4 LED */ + 0x17, /* FAN4-6 LED */ +}; + +enum led_type { + LED_TYPE_PSU1, + LED_TYPE_PSU2, + LED_TYPE_DIAG, + LED_TYPE_FAN, + LED_TYPE_FAN1, + LED_TYPE_FAN2, + LED_TYPE_FAN3, + LED_TYPE_FAN4, + LED_TYPE_FAN5, + LED_TYPE_LOC +}; + +enum led_light_mode { + LED_MODE_OFF = 0, + LED_MODE_GREEN, + LED_MODE_AMBER, + LED_MODE_RED, + LED_MODE_GREEN_BLINK, + LED_MODE_AMBER_BLINK, + LED_MODE_RED_BLINK, + LED_MODE_AUTO, +}; + +struct led_type_mode { + enum led_type type; + int type_mask; + enum led_light_mode mode; + int mode_mask; +}; + +static struct led_type_mode led_type_mode_data[] = { +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU1_GREEN_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU1_AMBER_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_AUTO, LED_MODE_PSU1_AUTO_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_OFF, LED_MODE_PSU1_OFF_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU2_GREEN_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU2_AMBER_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_AUTO, LED_MODE_PSU2_AUTO_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_OFF, LED_MODE_PSU2_OFF_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_GREEN, LED_MODE_FAN_GREEN_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_AMBER, LED_MODE_FAN_AMBER_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_AUTO, LED_MODE_FAN_AUTO_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_OFF, LED_MODE_FAN_OFF_MASK}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 2}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 4}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 6}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0}, +{LED_TYPE_DIAG, LED_TYPE_DIAG_REG_MASK, LED_MODE_GREEN, LED_MODE_DIAG_GREEN_MASK}, +{LED_TYPE_DIAG, LED_TYPE_DIAG_REG_MASK, LED_MODE_AMBER, LED_MODE_DIAG_AMBER_MASK}, +{LED_TYPE_DIAG, LED_TYPE_DIAG_REG_MASK, LED_MODE_OFF, LED_MODE_DIAG_OFF_MASK}, +{LED_TYPE_LOC, LED_TYPE_LOC_REG_MASK, LED_MODE_AMBER, LED_MODE_LOC_ON_MASK}, +{LED_TYPE_LOC, LED_TYPE_LOC_REG_MASK, LED_MODE_OFF, LED_MODE_LOC_OFF_MASK}, +{LED_TYPE_LOC, LED_TYPE_LOC_REG_MASK, LED_MODE_AMBER_BLINK, LED_MODE_LOC_BLINK_MASK} +}; + + +struct fanx_info_s { + u8 cname; /* device name */ + enum led_type type; + u8 reg_id; /* map to led_reg & reg_val */ +}; + +static struct fanx_info_s fanx_info[] = { + {'1', LED_TYPE_FAN1, 2}, + {'2', LED_TYPE_FAN2, 2}, + {'3', LED_TYPE_FAN3, 2}, + {'4', LED_TYPE_FAN4, 2}, + {'5', LED_TYPE_FAN5, 3} +}; + +static int led_reg_val_to_light_mode(enum led_type type, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + + if (type != led_type_mode_data[i].type) + continue; + + if ((led_type_mode_data[i].type_mask & reg_val) == + led_type_mode_data[i].mode_mask) + { + return led_type_mode_data[i].mode; + } + } + + return 0; +} + +static u8 led_light_mode_to_reg_val(enum led_type type, + enum led_light_mode mode, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + if (type != led_type_mode_data[i].type) + continue; + + if (mode != led_type_mode_data[i].mode) + continue; + + reg_val = led_type_mode_data[i].mode_mask | + (reg_val & (~led_type_mode_data[i].type_mask)); + } + + return reg_val; +} + +static int accton_as5812_54x_led_read_value(u8 reg) +{ + return as5812_54x_cpld_read(0x60, reg); +} + +static int accton_as5812_54x_led_write_value(u8 reg, u8 value) +{ + return as5812_54x_cpld_write(0x60, reg, value); +} + +static void accton_as5812_54x_led_update(void) +{ + mutex_lock(&ledctl->update_lock); + + if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2) + || !ledctl->valid) { + int i; + + dev_dbg(&ledctl->pdev->dev, "Starting accton_as5812_54x_led update\n"); + + /* Update LED data + */ + for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) { + int status = accton_as5812_54x_led_read_value(led_reg[i]); + + if (status < 0) { + ledctl->valid = 0; + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg[i], status); + goto exit; + } + else + { + ledctl->reg_val[i] = status; + } + } + + ledctl->last_updated = jiffies; + ledctl->valid = 1; + } + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void accton_as5812_54x_led_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode, + u8 reg, enum led_type type) +{ + int reg_val; + + mutex_lock(&ledctl->update_lock); + + reg_val = accton_as5812_54x_led_read_value(reg); + + if (reg_val < 0) { + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val); + goto exit; + } + + reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val); + accton_as5812_54x_led_write_value(reg, reg_val); + + /* to prevent the slow-update issue */ + ledctl->valid = 0; + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void accton_as5812_54x_led_psu_1_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as5812_54x_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU1); +} + +static enum led_brightness accton_as5812_54x_led_psu_1_get(struct led_classdev *cdev) +{ + accton_as5812_54x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU1, ledctl->reg_val[1]); +} + +static void accton_as5812_54x_led_psu_2_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as5812_54x_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU2); +} + +static enum led_brightness accton_as5812_54x_led_psu_2_get(struct led_classdev *cdev) +{ + accton_as5812_54x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU2, ledctl->reg_val[1]); +} + +static void accton_as5812_54x_led_fan_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as5812_54x_led_set(led_cdev, led_light_mode, led_reg[0], LED_TYPE_FAN); +} + +static enum led_brightness accton_as5812_54x_led_fan_get(struct led_classdev *cdev) +{ + accton_as5812_54x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_FAN, ledctl->reg_val[0]); +} + + +static void accton_as5812_54x_led_fanx_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + enum led_type led_type1; + int reg_id; + int i, nsize; + int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s); + + for(i=0;iname); + + if (led_cdev->name[nsize-1] == fanx_info[i].cname) + { + led_type1 = fanx_info[i].type; + reg_id = fanx_info[i].reg_id; + accton_as5812_54x_led_set(led_cdev, led_light_mode, led_reg[reg_id], led_type1); + return; + } + } +} + + +static enum led_brightness accton_as5812_54x_led_fanx_get(struct led_classdev *cdev) +{ + enum led_type led_type1; + int reg_id; + int i, nsize; + int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s); + + for(i=0;iname); + + if (cdev->name[nsize-1] == fanx_info[i].cname) + { + led_type1 = fanx_info[i].type; + reg_id = fanx_info[i].reg_id; + accton_as5812_54x_led_update(); + return led_reg_val_to_light_mode(led_type1, ledctl->reg_val[reg_id]); + } + } + + + return led_reg_val_to_light_mode(LED_TYPE_FAN1, ledctl->reg_val[2]); +} + + +static void accton_as5812_54x_led_diag_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as5812_54x_led_set(led_cdev, led_light_mode, led_reg[0], LED_TYPE_DIAG); +} + +static enum led_brightness accton_as5812_54x_led_diag_get(struct led_classdev *cdev) +{ + accton_as5812_54x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_DIAG, ledctl->reg_val[0]); +} + +static void accton_as5812_54x_led_loc_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as5812_54x_led_set(led_cdev, led_light_mode, led_reg[0], LED_TYPE_LOC); +} + +static enum led_brightness accton_as5812_54x_led_loc_get(struct led_classdev *cdev) +{ + accton_as5812_54x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_LOC, ledctl->reg_val[0]); +} + +static struct led_classdev accton_as5812_54x_leds[] = { + [LED_TYPE_PSU1] = { + .name = "accton_as5812_54x_led::psu1", + .default_trigger = "unused", + .brightness_set = accton_as5812_54x_led_psu_1_set, + .brightness_get = accton_as5812_54x_led_psu_1_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU2] = { + .name = "accton_as5812_54x_led::psu2", + .default_trigger = "unused", + .brightness_set = accton_as5812_54x_led_psu_2_set, + .brightness_get = accton_as5812_54x_led_psu_2_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN] = { + .name = "accton_as5812_54x_led::fan", + .default_trigger = "unused", + .brightness_set = accton_as5812_54x_led_fan_set, + .brightness_get = accton_as5812_54x_led_fan_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN1] = { + .name = "accton_as5812_54x_led::fan1", + .default_trigger = "unused", + .brightness_set = accton_as5812_54x_led_fanx_set, + .brightness_get = accton_as5812_54x_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN2] = { + .name = "accton_as5812_54x_led::fan2", + .default_trigger = "unused", + .brightness_set = accton_as5812_54x_led_fanx_set, + .brightness_get = accton_as5812_54x_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN3] = { + .name = "accton_as5812_54x_led::fan3", + .default_trigger = "unused", + .brightness_set = accton_as5812_54x_led_fanx_set, + .brightness_get = accton_as5812_54x_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN4] = { + .name = "accton_as5812_54x_led::fan4", + .default_trigger = "unused", + .brightness_set = accton_as5812_54x_led_fanx_set, + .brightness_get = accton_as5812_54x_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN5] = { + .name = "accton_as5812_54x_led::fan5", + .default_trigger = "unused", + .brightness_set = accton_as5812_54x_led_fanx_set, + .brightness_get = accton_as5812_54x_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_DIAG] = { + .name = "accton_as5812_54x_led::diag", + .default_trigger = "unused", + .brightness_set = accton_as5812_54x_led_diag_set, + .brightness_get = accton_as5812_54x_led_diag_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_LOC] = { + .name = "accton_as5812_54x_led::loc", + .default_trigger = "unused", + .brightness_set = accton_as5812_54x_led_loc_set, + .brightness_get = accton_as5812_54x_led_loc_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, +}; + +static int accton_as5812_54x_led_suspend(struct platform_device *dev, + pm_message_t state) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(accton_as5812_54x_leds); i++) { + led_classdev_suspend(&accton_as5812_54x_leds[i]); + } + + return 0; +} + +static int accton_as5812_54x_led_resume(struct platform_device *dev) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(accton_as5812_54x_leds); i++) { + led_classdev_resume(&accton_as5812_54x_leds[i]); + } + + return 0; +} + +static int accton_as5812_54x_led_probe(struct platform_device *pdev) +{ + int ret, i; + + for (i = 0; i < ARRAY_SIZE(accton_as5812_54x_leds); i++) { + ret = led_classdev_register(&pdev->dev, &accton_as5812_54x_leds[i]); + + if (ret < 0) + break; + } + + /* Check if all LEDs were successfully registered */ + if (i != ARRAY_SIZE(accton_as5812_54x_leds)){ + int j; + + /* only unregister the LEDs that were successfully registered */ + for (j = 0; j < i; j++) { + led_classdev_unregister(&accton_as5812_54x_leds[i]); + } + } + + return ret; +} + +static int accton_as5812_54x_led_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(accton_as5812_54x_leds); i++) { + led_classdev_unregister(&accton_as5812_54x_leds[i]); + } + + return 0; +} + +static struct platform_driver accton_as5812_54x_led_driver = { + .probe = accton_as5812_54x_led_probe, + .remove = accton_as5812_54x_led_remove, + .suspend = accton_as5812_54x_led_suspend, + .resume = accton_as5812_54x_led_resume, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int __init accton_as5812_54x_led_init(void) +{ + int ret; + + ret = platform_driver_register(&accton_as5812_54x_led_driver); + if (ret < 0) { + goto exit; + } + + ledctl = kzalloc(sizeof(struct accton_as5812_54x_led_data), GFP_KERNEL); + if (!ledctl) { + ret = -ENOMEM; + platform_driver_unregister(&accton_as5812_54x_led_driver); + goto exit; + } + + mutex_init(&ledctl->update_lock); + + ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(ledctl->pdev)) { + ret = PTR_ERR(ledctl->pdev); + platform_driver_unregister(&accton_as5812_54x_led_driver); + kfree(ledctl); + goto exit; + } + +exit: + return ret; +} + +static void __exit accton_as5812_54x_led_exit(void) +{ + platform_device_unregister(ledctl->pdev); + platform_driver_unregister(&accton_as5812_54x_led_driver); + kfree(ledctl); +} + +module_init(accton_as5812_54x_led_init); +module_exit(accton_as5812_54x_led_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton_as5812_54x_led driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/ym2651y.c new file mode 100755 index 000000000000..519530387e29 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/modules/ym2651y.c @@ -0,0 +1,683 @@ +/* + * An hwmon driver for the 3Y Power YM-2651Y Power Module + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#if 0 +#define DEBUG +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_FAN_DUTY_CYCLE 100 + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +enum chips { + YM2651, + YM2401, +}; + +/* Each client has this additional data + */ +struct ym2651y_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 chip; /* chip id */ + u8 capability; /* Register value */ + u16 status_word; /* Register value */ + u8 fan_fault; /* Register value */ + u8 over_temp; /* Register value */ + u16 v_out; /* Register value */ + u16 i_out; /* Register value */ + u16 p_out; /* Register value */ + u8 vout_mode; /* Register value */ + u16 temp; /* Register value */ + u16 fan_speed; /* Register value */ + u16 fan_duty_cycle[2]; /* Register value */ + u8 fan_dir[5]; /* Register value */ + u8 pmbus_revision; /* Register value */ + u8 mfr_id[10]; /* Register value */ + u8 mfr_model[16]; /* Register value */ + u8 mfr_revsion[3]; /* Register value */ + u16 mfr_vin_min; /* Register value */ + u16 mfr_vin_max; /* Register value */ + u16 mfr_iin_max; /* Register value */ + u16 mfr_iout_max; /* Register value */ + u16 mfr_pin_max; /* Register value */ + u16 mfr_pout_max; /* Register value */ + u16 mfr_vout_min; /* Register value */ + u16 mfr_vout_max; /* Register value */ +}; + +static ssize_t show_byte(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_word(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_linear(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_vout(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_ascii(struct device *dev, struct device_attribute *da, + char *buf); +static struct ym2651y_data *ym2651y_update_device(struct device *dev); +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value); + +enum ym2651y_sysfs_attributes { + PSU_POWER_ON = 0, + PSU_TEMP_FAULT, + PSU_POWER_GOOD, + PSU_FAN1_FAULT, + PSU_FAN_DIRECTION, + PSU_OVER_TEMP, + PSU_V_OUT, + PSU_I_OUT, + PSU_P_OUT, + PSU_TEMP1_INPUT, + PSU_FAN1_SPEED, + PSU_FAN1_DUTY_CYCLE, + PSU_PMBUS_REVISION, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_REVISION, + PSU_MFR_VIN_MIN, + PSU_MFR_VIN_MAX, + PSU_MFR_VOUT_MIN, + PSU_MFR_VOUT_MAX, + PSU_MFR_IIN_MAX, + PSU_MFR_IOUT_MAX, + PSU_MFR_PIN_MAX, + PSU_MFR_POUT_MAX +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_power_on, S_IRUGO, show_word, NULL, PSU_POWER_ON); +static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_word, NULL, PSU_POWER_GOOD); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_over_temp, S_IRUGO, show_over_temp, NULL, PSU_OVER_TEMP); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_vout, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_fan_dir, S_IRUGO, show_ascii, NULL, PSU_FAN_DIRECTION); +static SENSOR_DEVICE_ATTR(psu_pmbus_revision,S_IRUGO, show_byte, NULL, PSU_PMBUS_REVISION); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_ascii, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, show_ascii, NULL, PSU_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu_mfr_revision, S_IRUGO, show_ascii, NULL, PSU_MFR_REVISION); +static SENSOR_DEVICE_ATTR(psu_mfr_vin_min, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MIN); +static SENSOR_DEVICE_ATTR(psu_mfr_vin_max, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_vout_min, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MIN); +static SENSOR_DEVICE_ATTR(psu_mfr_vout_max, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_iin_max, S_IRUGO, show_linear, NULL, PSU_MFR_IIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_iout_max, S_IRUGO, show_linear, NULL, PSU_MFR_IOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_pin_max, S_IRUGO, show_linear, NULL, PSU_MFR_PIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_pout_max, S_IRUGO, show_linear, NULL, PSU_MFR_POUT_MAX); + +static struct attribute *ym2651y_attributes[] = { + &sensor_dev_attr_psu_power_on.dev_attr.attr, + &sensor_dev_attr_psu_temp_fault.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_over_temp.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan_dir.dev_attr.attr, + &sensor_dev_attr_psu_pmbus_revision.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_mfr_revision.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vin_min.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_pout_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_iin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_pin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vout_min.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vout_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_iout_max.dev_attr.attr, + NULL +}; + +static ssize_t show_byte(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + + if (!data->valid) { + return 0; + } + + return (attr->index == PSU_PMBUS_REVISION) ? sprintf(buf, "%d\n", data->pmbus_revision) : + sprintf(buf, "0\n"); +} + +static ssize_t show_word(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + u16 status = 0; + + if (!data->valid) { + return 0; + } + + switch (attr->index) { + case PSU_POWER_ON: /* psu_power_on, low byte bit 6 of status_word, 0=>ON, 1=>OFF */ + status = (data->status_word & 0x40) ? 0 : 1; + break; + case PSU_TEMP_FAULT: /* psu_temp_fault, low byte bit 2 of status_word, 0=>Normal, 1=>temp fault */ + status = (data->status_word & 0x4) >> 2; + break; + case PSU_POWER_GOOD: /* psu_power_good, high byte bit 3 of status_word, 0=>OK, 1=>FAIL */ + status = (data->status_word & 0x800) ? 0 : 1; + break; + } + + return sprintf(buf, "%d\n", status); +} + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; + ym2651y_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_linear(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + if (!data->valid) { + return 0; + } + + switch (attr->index) { + case PSU_V_OUT: + value = data->v_out; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp; + break; + case PSU_FAN1_SPEED: + value = data->fan_speed; + multiplier = 1; + break; + case PSU_FAN1_DUTY_CYCLE: + value = data->fan_duty_cycle[0]; + multiplier = 1; + break; + case PSU_MFR_VIN_MIN: + value = data->mfr_vin_min; + break; + case PSU_MFR_VIN_MAX: + value = data->mfr_vin_max; + break; + case PSU_MFR_VOUT_MIN: + value = data->mfr_vout_min; + break; + case PSU_MFR_VOUT_MAX: + value = data->mfr_vout_max; + break; + case PSU_MFR_PIN_MAX: + value = data->mfr_pin_max; + break; + case PSU_MFR_POUT_MAX: + value = data->mfr_pout_max; + break; + case PSU_MFR_IOUT_MAX: + value = data->mfr_iout_max; + break; + case PSU_MFR_IIN_MAX: + value = data->mfr_iin_max; + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + + return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + u8 shift; + + if (!data->valid) { + return 0; + } + + shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct ym2651y_data *data = ym2651y_update_device(dev); + + if (!data->valid) { + return 0; + } + + return sprintf(buf, "%d\n", data->over_temp >> 7); +} + +static ssize_t show_ascii(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + u8 *ptr = NULL; + + if (!data->valid) { + return 0; + } + + switch (attr->index) { + case PSU_FAN_DIRECTION: /* psu_fan_dir */ + ptr = data->fan_dir + 1; /* Skip the first byte since it is the length of string. */ + break; + case PSU_MFR_ID: /* psu_mfr_id */ + ptr = data->mfr_id + 1; /* The first byte is the count byte of string. */; + break; + case PSU_MFR_MODEL: /* psu_mfr_model */ + ptr = data->mfr_model + 1; /* The first byte is the count byte of string. */ + break; + case PSU_MFR_REVISION: /* psu_mfr_revision */ + ptr = data->mfr_revsion + 1; /* The first byte is the count byte of string. */ + break; + default: + return 0; + } + + return sprintf(buf, "%s\n", ptr); +} + +static ssize_t show_vout_by_mode(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct ym2651y_data *data = ym2651y_update_device(dev); + int exponent, mantissa; + int multiplier = 1000; + + if (!data->valid) { + return 0; + } + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + mantissa = data->v_out; + + return (exponent > 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t show_vout(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + + if (data->chip == YM2401) { + return show_vout_by_mode(dev, da, buf); + } + + return show_linear(dev, da, buf); +} + +static const struct attribute_group ym2651y_group = { + .attrs = ym2651y_attributes, +}; + +static int ym2651y_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct ym2651y_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct ym2651y_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->chip = dev_id->driver_data; + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &ym2651y_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &ym2651y_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int ym2651y_remove(struct i2c_client *client) +{ + struct ym2651y_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &ym2651y_group); + kfree(data); + + return 0; +} + +static const struct i2c_device_id ym2651y_id[] = { + { "ym2651", YM2651 }, + { "ym2401", YM2401 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, ym2651y_id); + +static struct i2c_driver ym2651y_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "ym2651", + }, + .probe = ym2651y_probe, + .remove = ym2651y_remove, + .id_table = ym2651y_id, + .address_list = normal_i2c, +}; + +static int ym2651y_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int ym2651y_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value) +{ + return i2c_smbus_write_word_data(client, reg, value); +} + +static int ym2651y_read_block(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; + +abort: + return result; +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + +static struct ym2651y_data *ym2651y_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int i, status, length; + u8 command, buf; + struct reg_data_byte regs_byte[] = { {0x19, &data->capability}, + {0x20, &data->vout_mode}, + {0x7d, &data->over_temp}, + {0x81, &data->fan_fault}, + {0x98, &data->pmbus_revision}}; + struct reg_data_word regs_word[] = { {0x79, &data->status_word}, + {0x8b, &data->v_out}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x8d, &data->temp}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x3c, &(data->fan_duty_cycle[1])}, + {0x90, &data->fan_speed}, + {0xa0, &data->mfr_vin_min}, + {0xa1, &data->mfr_vin_max}, + {0xa2, &data->mfr_iin_max}, + {0xa3, &data->mfr_pin_max}, + {0xa4, &data->mfr_vout_min}, + {0xa5, &data->mfr_vout_max}, + {0xa6, &data->mfr_iout_max}, + {0xa7, &data->mfr_pout_max}}; + + dev_dbg(&client->dev, "Starting ym2651 update\n"); + data->valid = 0; + + /* Read byte data */ + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = ym2651y_read_byte(client, regs_byte[i].reg); + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + goto exit; + } + else { + *(regs_byte[i].value) = status; + } + } + + /* Read word data */ + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + status = ym2651y_read_word(client, regs_word[i].reg); + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + goto exit; + } + else { + *(regs_word[i].value) = status; + } + } + + /* Read fan_direction */ + command = 0xC3; + status = ym2651y_read_block(client, command, data->fan_dir, + ARRAY_SIZE(data->fan_dir)-1); + data->fan_dir[ARRAY_SIZE(data->fan_dir)-1] = '\0'; + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + goto exit; + } + + /* Read mfr_id */ + command = 0x99; + status = ym2651y_read_block(client, command, data->mfr_id, + ARRAY_SIZE(data->mfr_id)-1); + data->mfr_id[ARRAY_SIZE(data->mfr_id)-1] = '\0'; + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + goto exit; + } + + /* Read mfr_model */ + command = 0x9a; + length = 1; + + /* Read first byte to determine the length of data */ + status = ym2651y_read_block(client, command, &buf, length); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + goto exit; + } + + status = ym2651y_read_block(client, command, data->mfr_model, buf+1); + data->mfr_model[buf+1] = '\0'; + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + goto exit; + } + + /* Read mfr_revsion */ + command = 0x9b; + status = ym2651y_read_block(client, command, data->mfr_revsion, + ARRAY_SIZE(data->mfr_revsion)-1); + data->mfr_revsion[ARRAY_SIZE(data->mfr_revsion)-1] = '\0'; + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + goto exit; + } + + data->last_updated = jiffies; + data->valid = 1; + } + +exit: + mutex_unlock(&data->update_lock); + + return data; +} + +static int __init ym2651y_init(void) +{ + return i2c_add_driver(&ym2651y_driver); +} + +static void __exit ym2651y_exit(void) +{ + i2c_del_driver(&ym2651y_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("3Y Power YM-2651Y driver"); +MODULE_LICENSE("GPL"); + +module_init(ym2651y_init); +module_exit(ym2651y_exit); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/service/as5812-platform-monitor.service b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/service/as5812-platform-monitor.service new file mode 100755 index 000000000000..e495bcba3ade --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/service/as5812-platform-monitor.service @@ -0,0 +1,17 @@ +[Unit] +Description=Accton AS5812-54X Platform Monitoring service +Before=pmon.service +After=sysinit.target +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStartPre=/usr/local/bin/accton_as5812_util.py install +ExecStart=/usr/local/bin/accton_as5812_monitor.py +RemainAfterExit=yes + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/setup.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/setup.py new file mode 100755 index 000000000000..aa8615fd8a88 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/setup.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='as5812_54x', + version='1.0', + description='Module to initialize Accton AS5812-54X platforms', + + packages=['as5812_54x'], + package_dir={'as5812_54x': 'as5812-54x/classes'}, +) + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/README b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/README new file mode 100755 index 000000000000..4ce43d9407d8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/README @@ -0,0 +1,117 @@ +Copyright (C) 2016 Accton Networks, Inc. + +This program is free software: you can redistribute it and/or modify +It under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +Contents of this package: + patch - files under patch/ is for kernel and ONIE installer + for the kernel: + config-accton-as5812_54x.patch + for kernel configuration. + driver-i2c-muxes-pca954x-always-deselect.patch + for i2c_mux deselects after transaction. + driver-patches-for-accton-as5812-fan-psu-cpld.patch + for as5812's fan/psu/cpld/led/sfp drivers. + for ONIE: + onie_installer-accton-AS5812-54X.patch + for console port setting and copy util script o rootfs. + module - Contains source code of as5812 kernel driver modules. + +The late Sonic building scripts, pushed @Dec 5 2016, will automatically +create a docker container and run building process under it. +User is not necessary to handle docker environment creation. + +1. Download sonic-buildimage environment. + - Run "git clone https://github.com/Azure/sonic-buildimage". + - cd to sonic-buildimage and run "git submodule update --init --recursive". +2. Build kernel + - cd ./src/sonic-linux-kernel + - Copy patches and series from patch/kernel of this release to + sonic-linux-kernel/patch. + - Build kernel by "make". + - The built kernel package, linux-image-3.16.0-5-amd64_3.16.51-3+deb8u1_amd64.deb + , is generated. +3. Build installer + - Change directory back to sonic-buildimage/. + - Get onie_installer-accton-AS5812-54X.patch" from patch/installer. + - Change setting for AS5812-54X by patching build_image.sh. + "patch -p1 < onie_installer-accton-AS5812-54X.patch" + !!NOTICE, patching onie_installer-accton-AS5812-54X.patch comments out the + "git status" checking at build_image.sh. + - The account and password of installed OS can be given at rules/config. + The default user and password are "admin" & "YourPaSsWoRd" respectively. + - Run "make configure PLATFORM=broadcom" + - Copy the built kernel debian package to target/debs/. + The file is linux-image-3.16.0-5-amd64_*_amd64.deb under directory + src/sonic-linux-kernel/. + - Run "make target/sonic-generic.bin" + - Get the installer, target/sonic-generic.bin, to target machine and install. + +All Linux kernel code is licensed under the GPLv1. All other code is +licensed under the GPLv3. Please see the LICENSE file for copies of +both licenses. + +The code for integacting with Accton AS5812-54X has 2 parts, +kernel drivers and operational script. +The kernel drivers of peripherals are under module/ directory. +1. These drivers are patched into kernel by + driver-patches-for-accton-as5812-fan-psu-cpld.patch + Or you can build the driver under module/ by setting environment variable, + KERNEL_SRC, to proper linux built directory and run make. + It may be sonic-linux-kernel/linux-3.*/debian/build/build_amd64_none_amd64/. +2. A operational script, accton_as5812_util.py, for device initializatian and + peripheral accessing should be installed at /usr/bin. + This script is generated by onie_installer-accton-AS5812-54X.patch. + It's done by patching onie_installer-accton-AS5812-54X.patch at build-image. + Run "accton_as5812_util.py install" to install drivers. + +To initialize the system, run "accton_as5812_util.py install". +To clean up the drivers & devices, run "accton_as5812_util.py clean". +To dump information of sensors, run "accton_as5812_util.py show". +To dump SFP EEPROM, run "accton_as5812_util.py sff". +To set fan speed, run "accton_as5812_util.py set fan". +To enable/disable SFP emission, run "accton_as5812_util.py set sfp". +To set system LEDs' color, run "accton_as5812_util.py set led" +For more information, run "accton_as5812_util.py --help". + +==================================================================== +Besides applying accton_as5812_util.py to access peripherals, you can +access peripherals by sysfs nodes directly after the installation is run. + +System LED: + There are 5 system LEDs at the lower-left corner of front panel. + They are loc, diag, fan, ps1, and ps2. + The sysfs interface color mappings are as follows: + Brightness: + 0 => off + 1 => green + 2 => amber + 3 => red + 4 => blue + But not all colors are available for each LED. + +Fan Control: + There are 10 fans inside 5 fan modules. + All fans share 1 duty setting, ranged from 0~100. + +Thermal sensers: + 3 temperature sensors are controlled by the lm75 kernel modules. + +PSUs: + There 2 power supplies slot at the left/right side of the back. + Once if a PSU is not plugged, the status of it is shown failed. + +There are 48 SFP+ and 6 QSFP modules are equipped. +Before operating on PSU and QSFP+, please make sure it is well plugged. +Otherwise, operation is going to fail. + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_monitor.py new file mode 100755 index 000000000000..78c06f4656a2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_monitor.py @@ -0,0 +1,204 @@ +#!/usr/bin/env python +# +# Copyright (C) 2019 Accton Technology Corporation +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# 05/08/2019: Roy Lee, changed for as5812-54x. +# ------------------------------------------------------------------ + +try: + import os + import sys, getopt + import subprocess + import click + import imp + import logging + import logging.config + import types + import time # this is only being used as part of the example + import traceback + import signal + from tabulate import tabulate + from as5812_54x.fanutil import FanUtil + from as5812_54x.thermalutil import ThermalUtil +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + +# Deafults +VERSION = '1.0' +FUNCTION_NAME = 'accton_as5812_monitor' +DUTY_MAX = 100 + +global log_file +global log_level + +# Make a class we can use to capture stdout and sterr in the log +class accton_as5812_monitor(object): + # static temp var + _ori_temp = 0 + _new_perc = 0 + + def __init__(self, log_file, log_level): + """Needs a logger and a logger level.""" + # set up logging to file + logging.basicConfig( + filename=log_file, + filemode='w', + level=log_level, + format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', + datefmt='%H:%M:%S' + ) + + # set up logging to console + if log_level == logging.DEBUG: + console = logging.StreamHandler() + console.setLevel(log_level) + formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) + + logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level) + + def manage_fans(self): + FAN_LEV1_UP_TEMP = 57700 # temperature + FAN_LEV1_DOWN_TEMP = 0 # unused + FAN_LEV1_SPEED_PERC = DUTY_MAX # percentage*/ + + FAN_LEV2_UP_TEMP = 53000 + FAN_LEV2_DOWN_TEMP = 52700 + FAN_LEV2_SPEED_PERC = 80 + + FAN_LEV3_UP_TEMP = 49500 + FAN_LEV3_DOWN_TEMP = 47700 + FAN_LEV3_SPEED_PERC = 65 + + FAN_LEV4_UP_TEMP = 0 # unused + FAN_LEV4_DOWN_TEMP = 42700 + FAN_LEV4_SPEED_PERC = 40 + + + thermal = ThermalUtil() + fan = FanUtil() + + temp1 = thermal.get_thermal_1_val() + if temp1 is None: + return False + + temp2 = thermal.get_thermal_2_val() + if temp2 is None: + return False + + new_temp = (temp1 + temp2) / 2 + + for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): + fan_stat = fan.get_fan_status(x) + if fan_stat is None: + return False + if fan_stat is False: + self._new_perc = FAN_LEV1_SPEED_PERC + logging.debug('INFO. SET new_perc to %d (FAN fault. fan_num:%d)', self._new_perc, x) + break + logging.debug('INFO. fan_stat is True (fan_num:%d)', x) + + if fan_stat is not None and fan_stat is not False: + diff = new_temp - self._ori_temp + if diff == 0: + logging.debug('INFO. RETURN. THERMAL temp not changed. %d / %d (new_temp / ori_temp)', new_temp, self._ori_temp) + return True + else: + if diff >= 0: + is_up = True + logging.debug('INFO. THERMAL temp UP %d / %d (new_temp / ori_temp)', new_temp, self._ori_temp) + else: + is_up = False + logging.debug('INFO. THERMAL temp DOWN %d / %d (new_temp / ori_temp)', new_temp, self._ori_temp) + + if is_up is True: + if new_temp >= FAN_LEV1_UP_TEMP: + self._new_perc = FAN_LEV1_SPEED_PERC + elif new_temp >= FAN_LEV2_UP_TEMP: + self._new_perc = FAN_LEV2_SPEED_PERC + elif new_temp >= FAN_LEV3_UP_TEMP: + self._new_perc = FAN_LEV3_SPEED_PERC + else: + self._new_perc = FAN_LEV4_SPEED_PERC + logging.debug('INFO. SET. FAN_SPEED as %d (new THERMAL temp:%d)', self._new_perc, new_temp) + else: + if new_temp <= FAN_LEV4_DOWN_TEMP: + self._new_perc = FAN_LEV4_SPEED_PERC + elif new_temp <= FAN_LEV3_DOWN_TEMP: + self._new_perc = FAN_LEV3_SPEED_PERC + elif new_temp <= FAN_LEV2_DOWN_TEMP: + self._new_perc = FAN_LEV2_SPEED_PERC + else: + self._new_perc = FAN_LEV1_SPEED_PERC + logging.debug('INFO. SET. FAN_SPEED as %d (new THERMAL temp:%d)', self._new_perc, new_temp) + + cur_perc = fan.get_fan_duty_cycle(fan.get_idx_fan_start()) + if cur_perc == self._new_perc: + logging.debug('INFO. RETURN. FAN speed not changed. %d / %d (new_perc / ori_perc)', self._new_perc, cur_perc) + return True + + set_stat = fan.set_fan_duty_cycle(fan.get_idx_fan_start(), self._new_perc) + if set_stat is True: + logging.debug('INFO: PASS. set_fan_duty_cycle (%d)', self._new_perc) + else: + logging.debug('INFO: FAIL. set_fan_duty_cycle (%d)', self._new_perc) + + logging.debug('INFO: GET. ori_perc is %d. ori_temp is %d', cur_perc, self._ori_temp) + self._ori_temp = new_temp + logging.debug('INFO: UPDATE. ori_perc to %d. ori_temp to %d', cur_perc, self._ori_temp) + + return True + +def handler(signum, frame): + fan = FanUtil() + logging.debug('INFO:Cause signal %d, set fan speed max.', signum) + fan.set_fan_duty_cycle(fan.get_idx_fan_start(), DUTY_MAX) + sys.exit(0) + +def main(argv): + log_file = '%s.log' % FUNCTION_NAME + log_level = logging.INFO + if len(sys.argv) != 1: + try: + opts, args = getopt.getopt(argv,'hdl:',['lfile=']) + except getopt.GetoptError: + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + for opt, arg in opts: + if opt == '-h': + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + elif opt in ('-d', '--debug'): + log_level = logging.DEBUG + elif opt in ('-l', '--lfile'): + log_file = arg + + signal.signal(signal.SIGINT, handler) + signal.signal(signal.SIGTERM, handler) + monitor = accton_as5812_monitor(log_file, log_level) + + # Loop forever, doing something useful hopefully: + while True: + monitor.manage_fans() + time.sleep(10) + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_util.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_util.py new file mode 100755 index 000000000000..37ca9f28755d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54x/utils/accton_as5812_util.py @@ -0,0 +1,686 @@ +#!/usr/bin/env python +# +# Copyright (C) 2016 Accton Networks, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +import pickle +from collections import namedtuple + +PROJECT_NAME = 'as5812_54x' +version = '0.2.0' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +DEVICE_NO = {'led':5, 'fan1':1, 'fan2':1,'fan3':1,'fan4':1,'fan5':1,'thermal':3, 'psu':2, 'sfp':54} + + +led_prefix ='/sys/devices/platform/as5812_54x_led/leds/accton_'+PROJECT_NAME+'_led::' +fan_prefix ='/sys/devices/platform/as5812_54x_' +hwmon_types = {'led': ['diag','fan','loc','psu1','psu2'], + 'fan1': ['fan'], + 'fan2': ['fan'], + 'fan3': ['fan'], + 'fan4': ['fan'], + 'fan5': ['fan'], + } +hwmon_nodes = {'led': ['brightness'] , + 'fan1': ['fan1_duty_cycle_percentage', 'fan1_fault', 'fan1_speed_rpm', 'fan1_direction', 'fanr1_fault', 'fanr1_speed_rpm'], + 'fan2': ['fan2_duty_cycle_percentage','fan2_fault', 'fan2_speed_rpm', 'fan2_direction', 'fanr2_fault', 'fanr2_speed_rpm'], + 'fan3': ['fan3_duty_cycle_percentage','fan3_fault', 'fan3_speed_rpm', 'fan3_direction', 'fanr3_fault', 'fanr3_speed_rpm'], + 'fan4': ['fan4_duty_cycle_percentage','fan4_fault', 'fan4_speed_rpm', 'fan4_direction', 'fanr4_fault', 'fanr4_speed_rpm'], + 'fan5': ['fan5_duty_cycle_percentage','fan5_fault', 'fan5_speed_rpm', 'fan5_direction', 'fanr5_fault', 'fanr5_speed_rpm'], + } +hwmon_prefix ={'led': led_prefix, + 'fan1': fan_prefix, + 'fan2': fan_prefix, + 'fan3': fan_prefix, + 'fan4': fan_prefix, + 'fan5': fan_prefix, + } + +i2c_prefix = '/sys/bus/i2c/devices/' +i2c_bus = {'thermal': ['61-0048','62-0049', '63-004a'] , + 'psu': ['57-0050','58-0053'], + 'sfp': ['-0050']} +i2c_nodes = { + 'thermal': ['hwmon/hwmon*/temp1_input'] , + 'psu': ['psu_present ', 'psu_power_good'] , + 'sfp': ['sfp_is_present ', 'sfp_tx_disable']} + +QSFP_START = 48 +I2C_BUS_ORDER = -1 + +sfp_map = [2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 52, 54, 51, 53, 55] + +port_cpld_path = [ "/sys/bus/i2c/devices/0-0061/" + ,'/sys/bus/i2c/devices/0-0062/'] + +mknod =[ +'echo as5812_54x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo as5812_54x_cpld2 0x61 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo as5812_54x_cpld3 0x62 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device', + +# PSU-1 +'echo as5812_54x_psu1 0x38 > /sys/bus/i2c/devices/i2c-57/new_device', +'echo cpr_4011_4mxx 0x3c > /sys/bus/i2c/devices/i2c-57/new_device', +'echo as5812_54x_psu1 0x50 > /sys/bus/i2c/devices/i2c-57/new_device', + +# PSU-2 +'echo as5812_54x_psu2 0x3b > /sys/bus/i2c/devices/i2c-58/new_device', +'echo cpr_4011_4mxx 0x3f > /sys/bus/i2c/devices/i2c-58/new_device', +'echo as5812_54x_psu2 0x53 > /sys/bus/i2c/devices/i2c-58/new_device', + +'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-61/new_device', +'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-62/new_device', +'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-63/new_device', + +#EERPOM +'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device', +] + +mknod2 =[ +'echo as5812_54x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo as5812_54x_cpld2 0x61 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo as5812_54x_cpld3 0x62 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-0/new_device', + +# PSU-1 +'echo as5812_54x_psu1 0x38 > /sys/bus/i2c/devices/i2c-57/new_device', +'echo cpr_4011_4mxx 0x3c > /sys/bus/i2c/devices/i2c-57/new_device', +'echo as5812_54x_psu1 0x50 > /sys/bus/i2c/devices/i2c-57/new_device', + +# PSU-2 +'echo as5812_54x_psu2 0x3b > /sys/bus/i2c/devices/i2c-58/new_device', +'echo cpr_4011_4mxx 0x3f > /sys/bus/i2c/devices/i2c-58/new_device', +'echo as5812_54x_psu2 0x53 > /sys/bus/i2c/devices/i2c-58/new_device', + +'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-61/new_device', +'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-62/new_device', +'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-63/new_device', + +#EERPOM +'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-0/new_device', +] + +FORCE = 0 +logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) +logging.basicConfig(level=logging.INFO) + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + device_traversal() + elif arg == 'sff': + if len(args)!=2: + show_eeprom_help() + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + show_eeprom_help() + else: + show_eeprom(args[1]) + return + elif arg == 'set': + if len(args)<3: + show_set_help() + else: + set_device(args[1:]) + return + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_set_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print cmd +" [led|sfp|fan]" + print " use \""+ cmd + " led 0-4 \" to set led color" + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-48 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + +def show_eeprom_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print " use \""+ cmd + " 1-54 \" to dump sfp# eeprom" + sys.exit(0) + +def my_log(txt): + if DEBUG == True: + print "[ACCTON DBG]: "+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status = 1 + output = "" + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log ("cmd:" + cmd) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_inserted(): + ret, lsmod = log_os_system("lsmod| grep accton", 0) + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + + + +kos = [ +'depmod -ae', +'modprobe i2c_dev', +'modprobe i2c_mux_pca954x', +'modprobe optoe', +'modprobe i2c-mux-accton_as5812_54x_cpld', +'modprobe cpr_4011_4mxx', +'modprobe ym2651y', +'modprobe accton_as5812_54x_fan', +'modprobe leds-accton_as5812_54x', +'modprobe accton_as5812_54x_psu'] + +def driver_install(): + global FORCE + for i in range(0,len(kos)): + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + +def driver_uninstall(): + global FORCE + for i in range(0,len(kos)): + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + + + +def i2c_order_check(): + # i2c bus 0 and 1 might be installed in different order. + # Here check if 0x70 is exist @ i2c-0 + tmp = "echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device" + status, output = log_os_system(tmp, 0) + if not device_exist(): + order = 1 + else: + order = 0 + tmp = "echo 0x70 > /sys/bus/i2c/devices/i2c-1/delete_device" + status, output = log_os_system(tmp, 0) + return order + +def update_i2c_order(): + global I2C_BUS_ORDER + + order = i2c_order_check() + pickle.dump(order, open("/tmp/accton_util.p", "wb")) # save it + I2C_BUS_ORDER = order + print "[%s]Detected I2C_BUS_ORDER:%d" % (os.path.basename(__file__), I2C_BUS_ORDER) + +def get_i2c_order(): + global I2C_BUS_ORDER + if I2C_BUS_ORDER < 0: + if os.path.exists("/tmp/accton_util.p"): + I2C_BUS_ORDER = pickle.load(open("/tmp/accton_util.p", "rb")) + else: + update_i2c_order() + +def device_install(): + global FORCE + global I2C_BUS_ORDER + + update_i2c_order() + order = I2C_BUS_ORDER + # if 0x76 is not exist @i2c-0, use reversed bus order + if order: + for i in range(0,len(mknod2)): + #for pca954x need times to built new i2c buses + if mknod2[i].find('pca954') != -1: + time.sleep(2) + + status, output = log_os_system(mknod2[i], 1) + if status: + print output + if FORCE == 0: + return status + else: + for i in range(0,len(mknod)): + #for pca954x need times to built new i2c buses + if mknod[i].find('pca954') != -1: + time.sleep(2) + + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + + for i in range(0,len(sfp_map)): + if i < QSFP_START: + status, output =log_os_system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + else: + status, output =log_os_system("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + status, output =log_os_system("echo port"+str(i)+" > /sys/bus/i2c/devices/"+str(sfp_map[i])+"-0050/port_name", 1) + if status: + print output + if FORCE == 0: + return status + + return + +def device_uninstall(): + global FORCE + global I2C_BUS_ORDER + + get_i2c_order() + order = I2C_BUS_ORDER + for i in range(0,len(sfp_map)): + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" + status, output =log_os_system("echo 0x50 > "+ target, 1) + if status: + print output + if FORCE == 0: + return status + + if order == 0: + nodelist = mknod + else: + nodelist = mknod2 + + for i in range(len(nodelist)): + target = nodelist[-(i+1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + if status: + print output + if FORCE == 0: + return status + + return + +def system_ready(): + if driver_inserted() == False: + return False + if not device_exist(): + return False + return True + +def do_install(): + print "Checking system...." + if driver_inserted() == False: + print "No driver, installing...." + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" drivers detected...." + if not device_exist(): + print "No device, installing...." + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" devices detected...." + return + +def do_uninstall(): + print "Checking system...." + if not device_exist(): + print PROJECT_NAME.upper() +" has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_inserted()== False : + print PROJECT_NAME.upper() +" has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + +def devices_info(): + global DEVICE_NO + global ALL_DEVICE + global i2c_bus, hwmon_types + for key in DEVICE_NO: + ALL_DEVICE[key]= {} + for i in range(0,DEVICE_NO[key]): + ALL_DEVICE[key][key+str(i+1)] = [] + + for key in i2c_bus: + buses = i2c_bus[key] + nodes = i2c_nodes[key] + for i in range(0,len(buses)): + for j in range(0,len(nodes)): + if 'fan' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + elif 'sfp' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + else: + node = key+str(i+1) + path = i2c_prefix+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + + for key in hwmon_types: + itypes = hwmon_types[key] + nodes = hwmon_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + #show dict all in the order + if DEBUG == True: + for i in sorted(ALL_DEVICE.keys()): + print(i+": ") + for j in sorted(ALL_DEVICE[i].keys()): + print(" "+j) + for k in (ALL_DEVICE[i][j]): + print(" "+" "+k) + return + +def show_eeprom(index): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] + node = node.replace(node.split("/")[-1], 'eeprom') + # check if got hexdump command in current environment + ret, log = log_os_system("which hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) + if len(log): + hex_cmd = 'hexdump' + elif len(log2): + hex_cmd = ' busybox hexdump' + else: + log = 'Failed : no hexdump cmd!!' + logging.info(log) + print log + return 1 + + print node + ":" + ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) + if ret==0: + print log + else: + print "**********device no found**********" + return + + +def get_cpld_path(index): + global I2C_BUS_ORDER + + if I2C_BUS_ORDER < 0: + get_i2c_order() + + if I2C_BUS_ORDER !=0 : + return port_cpld_path[index].replace("0-", "1-") + else: + return port_cpld_path[index] + +def cpld_path_of_port(port_index): + if port_index < 1 and port_index > DEVICE_NO['sfp']: + return None + if port_index < 25: + return get_cpld_path(0) + else: + return get_cpld_path(1) + +def get_path_sfp_tx_dis(port_index): + cpld_p = cpld_path_of_port(port_index) + if cpld_p == None: + return False, '' + else: + dev = cpld_p+"module_tx_disable_"+str(port_index) + return True, dev + +def get_path_sfp_presence(port_index): + cpld_p = cpld_path_of_port(port_index) + if cpld_p == None: + return False, '' + else: + dev = cpld_p+"module_present_"+str(port_index) + return True, dev + + +def set_device(args): + global DEVICE_NO + global ALL_DEVICE + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + + if args[0]=='led': + if int(args[1])>4: + show_set_help() + return + #print ALL_DEVICE['led'] + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): + ret, log = log_os_system("echo "+args[1]+" >"+k, 1) + if ret: + return ret + elif args[0]=='fan': + if int(args[1])>100: + show_set_help() + return + #print ALL_DEVICE['fan'] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan1'] ['fan11'][0] + node = node.replace(node.split("/")[-1], 'fan1_duty_cycle_percentage') + ret, log = log_os_system("cat "+ node, 1) + if ret==0: + print ("Previous fan duty: " + log.strip() +"%") + ret, log = log_os_system("echo "+args[1]+" >"+node, 1) + if ret==0: + print ("Current fan duty: " + args[1] +"%") + return ret + elif args[0]=='sfp': + #if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: + #There no tx_disable for QSFP port + if int(args[1]) > QSFP_START or int(args[1])==0: + show_set_help() + return + if len(args)<2: + show_set_help() + return + + if int(args[2])>1: + show_set_help() + return + + port_index = int(args[1]) + ret, dev = get_path_sfp_tx_dis(port_index) + if ret == False: + return False + else: + ret, log = log_os_system("echo "+args[2]+" >"+ dev, 1) + return ret + return + +#get digits inside a string. +#Ex: 31 for "sfp31" +def get_value(input): + digit = re.findall('\d+', input) + return int(digit[0]) + +def print_1_device_traversal(i, j, k): + ret, log = log_os_system("cat "+k, 0) + func = k.split("/")[-1].strip() + func = re.sub(j+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) + if ret==0: + return func+"="+log+" " + else: + return func+"="+"X"+" " + +def device_traversal(): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + for i in sorted(ALL_DEVICE.keys()): + print("============================================") + print(i.upper()+": ") + print("============================================") + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + print " "+j+":", + if i == 'sfp': + port_index = int(filter(str.isdigit, j)) + for k in (ALL_DEVICE[i][j]): + if k.find('tx_disable')!= -1: + ret, k = get_path_sfp_tx_dis(port_index) + if ret == False: + continue + log = print_1_device_traversal(i, j, k) + print log, + if k.find('present')!= -1: + ret, k = get_path_sfp_presence(port_index) + if ret == False: + continue + log = print_1_device_traversal(i, j, k) + print log, + + else: + for k in (ALL_DEVICE[i][j]): + log = print_1_device_traversal(i, j, k) + print log, + print + print("----------------------------------------------------------------") + + + print + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"*0070", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0) + return not(ret1 or ret2) + +if __name__ == "__main__": + main() diff --git a/platform/broadcom/sonic-platform-modules-accton/debian/control b/platform/broadcom/sonic-platform-modules-accton/debian/control index 6d65d1ecdc51..8cc6b986c506 100755 --- a/platform/broadcom/sonic-platform-modules-accton/debian/control +++ b/platform/broadcom/sonic-platform-modules-accton/debian/control @@ -49,3 +49,6 @@ Package: sonic-platform-accton-minipack Architecture: amd64 Description: kernel modules for platform devices such as fan, led, sfp +Package: sonic-platform-accton-as5812-54x +Architecture: amd64 +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-accton/debian/rules b/platform/broadcom/sonic-platform-modules-accton/debian/rules index 33168702bd50..2cd3d6d7b651 100755 --- a/platform/broadcom/sonic-platform-modules-accton/debian/rules +++ b/platform/broadcom/sonic-platform-modules-accton/debian/rules @@ -19,7 +19,7 @@ PACKAGE_PRE_NAME := sonic-platform-accton KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= as7712-32x as5712-54x as7816-64x as7716-32x as7716-32xb as7312-54x as7326-56x as6712-32x as7726-32x as4630-54pe minipack +MODULE_DIRS:= as7712-32x as5712-54x as7816-64x as7716-32x as7716-32xb as7312-54x as7326-56x as6712-32x as7726-32x as4630-54pe minipack as5812-54x MODULE_DIR := modules UTILS_DIR := utils SERVICE_DIR := service From 89ee636b9988b297867652dfd885e76c3ba502dd Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Wed, 29 May 2019 14:46:20 +0800 Subject: [PATCH 86/88] [Mellanox] SFP new platform API implementation (#2944) * add sfp new api * fix get presence --- .../sonic_platform/chassis.py | 31 +- .../mlnx-platform-api/sonic_platform/sfp.py | 1052 +++++++++++++++++ 2 files changed, 1082 insertions(+), 1 deletion(-) create mode 100644 platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index b8657a68f8d6..b144f2162b0a 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -15,15 +15,24 @@ from sonic_platform.psu import Psu from sonic_platform.fan import Fan from sonic_platform.fan import FAN_PATH + from sonic_platform.sfp import SFP from sonic_platform.watchdog import get_watchdog from os import listdir from os.path import isfile, join import re + import subprocess except ImportError as e: raise ImportError (str(e) + "- required module not found") MLNX_NUM_PSU = 2 +GET_HWSKU_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.hwsku" + +# magic code defnition for port number, qsfp port position of each hwsku +# port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) +hwsku_dict = {'ACS-MSN2700': 0, "LS-SN2700":0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0} +port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1),(0, 18, 21, 22, 1)] + class Chassis(ChassisBase): """Platform-specific Chassis class""" @@ -50,6 +59,20 @@ def __init__(self): fan = Fan(index, index) self._fan_list.append(fan) + # Initialize SFP list + port_position_tuple = self._get_port_position_tuple_by_sku_name() + self.PORT_START = port_position_tuple[0] + self.QSFP_PORT_START = port_position_tuple[1] + self.PORT_END = port_position_tuple[2] + self.PORTS_IN_BLOCK = port_position_tuple[3] + + for index in range(self.PORT_START, self.PORT_END + 1): + if index in range(QSFP_PORT_START, self.PORTS_IN_BLOCK + 1): + sfp_module = SFP(index, 'QSFP') + else: + sfp_module = SFP(index, 'SFP') + self._psu_list.append(sfp_module) + def _extract_num_of_fans_and_fan_drawers(self): num_of_fan = 0 num_of_drawer = 0 @@ -64,7 +87,13 @@ def _extract_num_of_fans_and_fan_drawers(self): if match_obj != None and int(match_obj.group(1)) > num_of_drawer: num_of_drawer = int(match_obj.group(1)) - return num_of_fan, num_of_drawer + return num_of_fan, num_of_drawer + + def _get_port_position_tuple_by_sku_name(self): + p = subprocess.Popen(GET_HWSKU_CMD, shell=True, stdout=subprocess.PIPE) + out, err = p.communicate() + position_tuple = port_position_tuple_list[hwsku_dict[out.rstrip('\n')]] + return position_tuple diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py new file mode 100644 index 000000000000..7f6c4aeaf5db --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -0,0 +1,1052 @@ +#!/usr/bin/env python + +############################################################################# +# Mellanox +# +# Module contains an implementation of SONiC Platform Base API and +# provides the FANs status which are available in the platform +# +############################################################################# + +try: + import os.path + import subprocess + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_eeprom import eeprom_dts + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.inf8628 import inf8628InterfaceId + +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +# definitions of the offset and width for values in XCVR info eeprom +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_QSFP = 20 +XCVR_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_TYPE_OFFSET = 0 +XCVR_TYPE_WIDTH = 1 +XCVR_EXT_TYPE_OFFSET = 1 +XCVR_EXT_TYPE_WIDTH = 1 +XCVR_CONNECTOR_OFFSET = 2 +XCVR_CONNECTOR_WIDTH = 1 +XCVR_COMPLIANCE_CODE_OFFSET = 3 +XCVR_COMPLIANCE_CODE_WIDTH = 8 +XCVR_ENCODING_OFFSET = 11 +XCVR_ENCODING_WIDTH = 1 +XCVR_NBR_OFFSET = 12 +XCVR_NBR_WIDTH = 1 +XCVR_EXT_RATE_SEL_OFFSET = 13 +XCVR_EXT_RATE_SEL_WIDTH = 1 +XCVR_CABLE_LENGTH_OFFSET = 14 +XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +XCVR_CABLE_LENGTH_WIDTH_SFP = 6 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 + +# definitions of the offset for values in OSFP info eeprom +OSFP_TYPE_OFFSET = 0 +OSFP_VENDOR_NAME_OFFSET = 129 +OSFP_VENDOR_PN_OFFSET = 148 +OSFP_HW_REV_OFFSET = 164 +OSFP_VENDOR_SN_OFFSET = 166 + +#definitions of the offset and width for values in DOM info eeprom +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VLOT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_VERSION_COMPLIANCE_OFFSET = 1 +QSFP_VERSION_COMPLIANCE_WIDTH = 1 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_CHANNL_DISABLE_STATUS_OFFSET = 86 +QSFP_CHANNL_DISABLE_STATUS_WIDTH = 1 +QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 +QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 +QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VLOT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 +SFP_CHANNL_STATUS_OFFSET = 110 +SFP_CHANNL_STATUS_WIDTH = 1 + +qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', + 'Length Cable Assembly(m)') + +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes','FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia','FibreChannelSpeed') + +qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', 'Fibre Channel Speed') + +SFP_PATH = "/var/run/hw-management/qsfp/" +SFP_TYPE = "SFP" +QSFP_TYPE = "QSFP" +OSFP_TYPE = "OSFP" + +class SFP(SfpBase): + """Platform-specific SFP class""" + + 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._dom_capability_detect() + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + presence = False + ethtool_cmd = "ethtool -m sfp{} 2>/dev/null".format(self.index) + try: + proc = subprocess.Popen(ethtool_cmd, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + result = stdout.rstrip('\n') + if result != '': + presence = True + + except OSError, e: + raise OSError("Cannot detect sfp") + + return presence + + # Read out any bytes from any offset + def _read_eeprom_specific_bytes(self, offset, num_bytes): + eeprom_raw = [] + ethtool_cmd = "ethtool -m sfp{} hex on offset {} length {}".format(self.index, offset, num_bytes) + try: + output = subprocess.check_output(ethtool_cmd, shell=True) + output_lines = output.splitlines() + first_line_raw = output_lines[0] + if "Offset" in first_line_raw: + for line in output_lines[2:]: + line_split = line.split() + eeprom_raw = eeprom_raw + line_split[1:] + except subprocess.CalledProcessError as e: + return None + + return eeprom_raw + + def _dom_capability_detect(self): + if self.sfp_type == "QSFP": + self.calibration = 1 + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + self.dom_supported = False + offset = 128 + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_version_compliance_raw = self._read_eeprom_specific_bytes(QSFP_VERSION_COMPLIANCE_OFFSET, QSFP_VERSION_COMPLIANCE_OFFSET) + qsfp_version_compliance = int(qsfp_version_compliance_raw[0], 16) + qsfp_dom_capability_raw = self._read_eeprom_specific_bytes((offset + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qspf_dom_capability = int(qsfp_dom_capability_raw[0], 16) + if qsfp_version_compliance >= 0x08: + self.dom_temp_supported = (qspf_dom_capability & 0x20 != 0) + self.dom_volt_supported = (qspf_dom_capability & 0x10 != 0) + self.dom_rx_power_supported = (qspf_dom_capability & 0x08 != 0) + self.dom_tx_power_supported = (qspf_dom_capability & 0x04 != 0) + else: + self.dom_temp_supported = True + self.dom_volt_supported = True + self.dom_rx_power_supported = (qspf_dom_capability & 0x08 != 0) + self.dom_tx_power_supported = True + self.dom_supported = True + self.calibration = 1 + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + self.calibration = 0 + elif self.sfp_type == "SFP": + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + return None + sfp_dom_capability_raw = self._read_eeprom_specific_bytes(XCVR_DOM_CAPABILITY_OFFSET, XCVR_DOM_CAPABILITY_WIDTH) + if sfp_dom_capability_raw is not None: + sfp_dom_capability = int(sfp_dom_capability_raw[0], 16) + self.dom_supported = (sfp_dom_capability & 0x40 != 0) + if self.dom_supported: + self.dom_temp_supported = True + self.dom_volt_supported = True + self.dom_rx_power_supported = True + self.dom_tx_power_supported = True + if sfp_dom_capability & 0x20 != 0: + self.calibration = 1 + elif sfp_dom_capability & 0x10 != 0: + self.calibration = 2 + else: + self.calibration = 0 + else: + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + else: + self.dom_supported = False + self.dom_temp_supported = False + self.dom_volt_supported = False + self.dom_rx_power_supported = False + self.dom_tx_power_supported = False + + def _convert_string_to_num(self, value_str): + if "-inf" in value_str: + return 'N/A' + elif "Unknown" in value_str: + return 'N/A' + elif 'dBm' in value_str: + t_str = value_str.rstrip('dBm') + return float(t_str) + elif 'mA' in value_str: + t_str = value_str.rstrip('mA') + return float(t_str) + elif 'C' in value_str: + t_str = value_str.rstrip('C') + return float(t_str) + elif 'Volts' in value_str: + t_str = value_str.rstrip('Volts') + return float(t_str) + else: + return 'N/A' + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardwarerev |1*255VCHAR |hardware version of SFP + serialnum |1*255VCHAR |serial number of the SFP + manufacturename |1*255VCHAR |SFP vendor name + modelname |1*255VCHAR |SFP model name + Connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + mominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + ======================================================================== + """ + transceiver_info_dict = {} + compliance_code_dict = {} + + # ToDo: OSFP tranceiver info parsing not fully supported. + # in inf8628.py lack of some memory map definition + # will be implemented when the inf8628 memory map ready + if self.sfp_type == OSFP_TYPE: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_OSFP + + sfpi_obj = inf8628InterfaceId() + if sfpi_obj is None: + return None + + sfp_type_raw = self._read_eeprom_specific_bytes((offset + OSFP_TYPE_OFFSET), XCVR_TYPE_WIDTH) + if sfp_type_raw is not None: + sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) + else: + return None + + sfp_vendor_name_raw = self._read_eeprom_specific_bytes((offset + OSFP_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + if sfp_vendor_name_raw is not None: + sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0) + else: + return None + + sfp_vendor_pn_raw = self._read_eeprom_specific_bytes((offset + OSFP_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + if sfp_vendor_pn_raw is not None: + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) + else: + return None + + sfp_vendor_rev_raw = self._read_eeprom_specific_bytes((offset + OSFP_HW_REV_OFFSET), vendor_rev_width) + if sfp_vendor_rev_raw is not None: + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) + else: + return None + + sfp_vendor_sn_raw = self._read_eeprom_specific_bytes((offset + OSFP_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + if sfp_vendor_sn_raw is not None: + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) + else: + return None + + transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] + transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['vendor_oui'] = 'N/A' + transceiver_info_dict['vendor_date'] = 'N/A' + transceiver_info_dict['Connector'] = 'N/A' + transceiver_info_dict['encoding'] = 'N/A' + transceiver_info_dict['ext_identifier'] = 'N/A' + transceiver_info_dict['ext_rateselect_compliance'] = 'N/A' + transceiver_info_dict['cable_type'] = 'N/A' + transceiver_info_dict['cable_length'] = 'N/A' + transceiver_info_dict['specification_compliance'] = 'N/A' + transceiver_info_dict['nominal_bit_rate'] = 'N/A' + + else: + if self.sfp_type == QSFP_TYPE: + offset = 128 + vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP + cable_length_width = XCVR_CABLE_LENGTH_WIDTH_QSFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + sfp_type = 'QSFP' + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + else: + offset = 0 + vendor_rev_width = XCVR_HW_REV_WIDTH_SFP + cable_length_width = XCVR_CABLE_LENGTH_WIDTH_SFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + sfp_type = 'SFP' + + sfpi_obj = sff8472InterfaceId() + if sfpi_obj is None: + print("Error: sfp_object open failed") + return None + + sfp_interface_bulk_raw = self._read_eeprom_specific_bytes((offset + XCVR_INTFACE_BULK_OFFSET), interface_info_bulk_width) + if sfp_interface_bulk_raw is not None: + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw, 0) + else: + return None + + sfp_vendor_name_raw = self._read_eeprom_specific_bytes((offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) + if sfp_vendor_name_raw is not None: + sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0) + else: + return None + + sfp_vendor_pn_raw = self._read_eeprom_specific_bytes((offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) + if sfp_vendor_pn_raw is not None: + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0) + else: + return None + + sfp_vendor_rev_raw = self._read_eeprom_specific_bytes((offset + XCVR_HW_REV_OFFSET), vendor_rev_width) + if sfp_vendor_rev_raw is not None: + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0) + else: + return None + + sfp_vendor_sn_raw = self._read_eeprom_specific_bytes((offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) + if sfp_vendor_sn_raw is not None: + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0) + else: + return None + + sfp_vendor_oui_raw = self._read_eeprom_specific_bytes((offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0) + else: + return None + + sfp_vendor_date_raw = self._read_eeprom_specific_bytes((offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + if sfp_vendor_date_raw is not None: + sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0) + else: + return None + + transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] + transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] + transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] + transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] + transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] + transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] + transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + + if self.sfp_type == QSFP_TYPE: + for key in qsfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + + for key in qsfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + else: + for key in sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + transceiver_info_dict['cable_type'] = key + transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + + for key in sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + transceiver_info_dict['specification_compliance'] = str(compliance_code_dict) + + transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + + return transceiver_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + RX LOS |BOOLEAN |RX lost-of-signal status, + | |True if has RX los, False if not. + TX FAULT |BOOLEAN |TX fault status, + | |True if has TX fault, False if not. + Reset status |BOOLEAN |reset status, + | |True if SFP in reset, False if not. + LP mode |BOOLEAN |low power mode status, + | |True in lp mode, False if not. + TX disable |BOOLEAN |TX disable status, + | |True TX disabled, False if not. + TX disabled channel |HEX |disabled TX channles in hex, + | |bits 0 to 3 represent channel 0 + | |to channel 3. + Temperature |INT |module temperature in Celsius + Voltage |INT |supply voltage in mV + TX bias |INT |TX Bias Current in mA + RX power |INT |received optical power in mW + TX power |INT |TX output power in mW + ======================================================================== + """ + transceiver_dom_info_dict = {} + + if self.sfp_type == OSFP_TYPE: + transceiver_dom_info_dict['temperature'] = 'N/A' + transceiver_dom_info_dict['voltage'] = 'N/A' + transceiver_dom_info_dict['rx1power'] = 'N/A' + transceiver_dom_info_dict['rx2power'] = 'N/A' + transceiver_dom_info_dict['rx3power'] = 'N/A' + transceiver_dom_info_dict['rx4power'] = 'N/A' + transceiver_dom_info_dict['tx1bias'] = 'N/A' + transceiver_dom_info_dict['tx2bias'] = 'N/A' + transceiver_dom_info_dict['tx3bias'] = 'N/A' + transceiver_dom_info_dict['tx4bias'] = 'N/A' + transceiver_dom_info_dict['tx1power'] = 'N/A' + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + + elif self.sfp_type == QSFP_TYPE: + if not self.dom_supported: + return None + + offset = 0 + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_temp_supported: + dom_temperature_raw = self._read_eeprom_specific_bytes((offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + temp = self._convert_string_to_num(dom_temperature_data['data']['Temperature']['value']) + if temp is not None: + transceiver_dom_info_dict['temperature'] = temp + else: + transceiver_dom_info_dict['temperature'] = 'N/A' + else: + return None + else: + transceiver_dom_info_dict['temperature'] = 'N/A' + + if self.dom_volt_supported: + dom_voltage_raw = self._read_eeprom_specific_bytes((offset + QSFP_VLOT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + volt = self._convert_string_to_num(dom_voltage_data['data']['Vcc']['value']) + if volt is not None: + transceiver_dom_info_dict['voltage'] = volt + else: + transceiver_dom_info_dict['voltage'] = 'N/A' + else: + return None + else: + transceiver_dom_info_dict['voltage'] = 'N/A' + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + + if self.dom_tx_power_supported: + transceiver_dom_info_dict['tx1power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['TX1Power']['value']) + transceiver_dom_info_dict['tx2power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['TX2Power']['value']) + transceiver_dom_info_dict['tx3power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['TX3Power']['value']) + transceiver_dom_info_dict['tx4power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['TX4Power']['value']) + else: + transceiver_dom_info_dict['tx1power'] = 'N/A' + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + + if self.dom_rx_power_supported: + transceiver_dom_info_dict['rx1power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['RX1Power']['value']) + transceiver_dom_info_dict['rx2power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['RX2Power']['value']) + transceiver_dom_info_dict['rx3power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['RX3Power']['value']) + transceiver_dom_info_dict['rx4power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['RX4Power']['value']) + else: + transceiver_dom_info_dict['rx1power'] = 'N/A' + transceiver_dom_info_dict['rx2power'] = 'N/A' + transceiver_dom_info_dict['rx3power'] = 'N/A' + transceiver_dom_info_dict['rx4power'] = 'N/A' + + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + 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: + if not self.dom_supported: + return None + + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + sfpd_obj._calibration_type = self.calibration + + dom_temperature_raw = self._read_eeprom_specific_bytes((offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return None + + dom_voltage_raw = self._read_eeprom_specific_bytes((offset + SFP_VLOT_OFFSET), SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return None + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return None + + transceiver_dom_info_dict['temperature'] = self._convert_string_to_num(dom_temperature_data['data']['Temperature']['value']) + transceiver_dom_info_dict['voltage'] = self._convert_string_to_num(dom_voltage_data['data']['Vcc']['value']) + transceiver_dom_info_dict['rx1power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['RXPower']['value']) + transceiver_dom_info_dict['rx2power'] = 'N/A' + transceiver_dom_info_dict['rx3power'] = 'N/A' + transceiver_dom_info_dict['rx4power'] = 'N/A' + transceiver_dom_info_dict['tx1bias'] = self._convert_string_to_num(dom_channel_monitor_data['data']['TXBias']['value']) + transceiver_dom_info_dict['tx2bias'] = 'N/A' + transceiver_dom_info_dict['tx3bias'] = 'N/A' + transceiver_dom_info_dict['tx4bias'] = 'N/A' + transceiver_dom_info_dict['tx1power'] = self._convert_string_to_num(dom_channel_monitor_data['data']['TXPower']['value']) + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + + return transceiver_dom_info_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + + Returns: + A Boolean, True if reset enabled, False if disabled + """ + return NotImplementedError + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + if not self.dom_supported: + return None + + rx_los_list = [] + if self.sfp_type == OSFP_TYPE: + return None + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_RX_LOS_STATUS_OFFSET), QSFP_CHANNL_RX_LOS_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x01 != 0) + rx_los_list.append(rx_los_data & 0x02 != 0) + rx_los_list.append(rx_los_data & 0x04 != 0) + rx_los_list.append(rx_los_data & 0x08 != 0) + else: + offset = 256 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los_list.append(rx_los_data & 0x02 != 0) + else: + return None + return rx_los_list + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + if not self.dom_supported: + return None + + tx_fault_list = [] + if self.sfp_type == OSFP_TYPE: + return None + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_TX_FAULT_STATUS_OFFSET), QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x01 != 0) + tx_fault_list.append(tx_fault_data & 0x02 != 0) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + tx_fault_list.append(tx_fault_data & 0x08 != 0) + else: + offset = 256 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault_list.append(tx_fault_data & 0x04 != 0) + else: + return None + return tx_fault_list + + def get_tx_disable(self): + """ + Retrieves the tx_disable status of this SFP + + Returns: + A Boolean, True if tx_disable is enabled, False if disabled + """ + if not self.dom_supported: + return None + + tx_disable_list = [] + if self.sfp_type == OSFP_TYPE: + return None + elif self.sfp_type == QSFP_TYPE: + offset = 0 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_DISABLE_STATUS_OFFSET), QSFP_CHANNL_DISABLE_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list.append(tx_disable_data & 0x01 != 0) + tx_disable_list.append(tx_disable_data & 0x02 != 0) + tx_disable_list.append(tx_disable_data & 0x04 != 0) + tx_disable_list.append(tx_disable_data & 0x08 != 0) + else: + offset = 256 + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) + if dom_channel_monitor_raw is not None: + tx_disable_data = int(dom_channel_monitor_raw[0], 16) + tx_disable_list.append(tx_disable_data & 0x80 != 0) + else: + return None + return tx_disable_list + + def get_tx_disable_channel(self): + """ + Retrieves the TX disabled channels in this SFP + + Returns: + A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent + TX channels which have been disabled in this SFP. + As an example, a returned value of 0x5 indicates that channel 0 + and channel 2 have been disabled. + """ + return NotImplementedError + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + return NotImplementedError + + def get_power_override(self): + """ + Retrieves the power-override status of this SFP + + Returns: + A Boolean, True if power-override is enabled, False if disabled + """ + return NotImplementedError + + def get_temperature(self): + """ + Retrieves the temperature of this SFP + + Returns: + An integer number of current temperature in Celsius + """ + if not self.dom_supported: + return None + if self.sfp_type == QSFP_TYPE: + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_temp_supported: + dom_temperature_raw = self._read_eeprom_specific_bytes((offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + temp = self._convert_string_to_num(dom_temperature_data['data']['Temperature']['value']) + return temp + else: + return None + else: + return None + else: + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + sfpd_obj._calibration_type = 1 + + dom_temperature_raw = self._read_eeprom_specific_bytes((offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + temp = self._convert_string_to_num(dom_temperature_data['data']['Temperature']['value']) + return temp + else: + return None + + def get_voltage(self): + """ + Retrieves the supply voltage of this SFP + + Returns: + An integer number of supply voltage in mV + """ + if not self.dom_supported: + return None + if self.sfp_type == QSFP_TYPE: + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_volt_supported: + dom_voltage_raw = self._read_eeprom_specific_bytes((offset + QSFP_VLOT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + voltage = self._convert_string_to_num(dom_voltage_data['data']['Vcc']['value']) + return voltage + else: + return None + return None + else: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + sfpd_obj._calibration_type = self.calibration + + dom_voltage_raw = self._read_eeprom_specific_bytes((offset + SFP_VLOT_OFFSET), SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + voltage = self._convert_string_to_num(dom_voltage_data['data']['Vcc']['value']) + return voltage + else: + return None + + def get_tx_bias(self): + """ + Retrieves the TX bias current of this SFP + + Returns: + A list of four integer numbers, representing TX bias in mA + for channel 0 to channel 4. + Ex. ['110.09', '111.12', '108.21', '112.09'] + """ + tx_bias_list = [] + if self.sfp_type == QSFP_TYPE: + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX1Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX2Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX3Bias']['value'])) + tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX4Bias']['value'])) + else: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + sfpd_obj._calibration_type = 1 + + if self.dom_supported: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + tx_bias_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TXBias']['value'])) + else: + return None + else: + return None + + return tx_bias_list + + def get_rx_power(self): + """ + Retrieves the received optical power for this SFP + + Returns: + A list of four integer numbers, representing received optical + power in mW for channel 0 to channel 4. + Ex. ['1.77', '1.71', '1.68', '1.70'] + """ + rx_power_list = [] + if self.sfp_type == OSFP_TYPE: + # OSFP not supported on our platform yet. + return None + + elif self.sfp_type == QSFP_TYPE: + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_rx_power_supported: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + rx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['RX1Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['RX2Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['RX3Power']['value'])) + rx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['RX4Power']['value'])) + else: + return None + else: + return None + else: + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + if self.dom_supported: + sfpd_obj._calibration_type = self.calibration + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + rx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['RXPower']['value'])) + else: + return None + else: + return None + return rx_power_list + + def get_tx_power(self): + """ + Retrieves the TX power of this SFP + + Returns: + A list of four integer numbers, representing TX power in mW + for channel 0 to channel 4. + Ex. ['1.86', '1.86', '1.86', '1.86'] + """ + tx_power_list = [] + if self.sfp_type == OSFP_TYPE: + # OSFP not supported on our platform yet. + return None + + elif self.sfp_type == QSFP_TYPE: + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + if self.dom_tx_power_supported: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX1Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX2Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX3Power']['value'])) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TX4Power']['value'])) + else: + return None + else: + return None + else: + offset = 256 + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + if self.dom_supported: + sfpd_obj._calibration_type = 1 + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + tx_power_list.append(self._convert_string_to_num(dom_channel_monitor_data['data']['TXPower']['value'])) + else: + return None + else: + return None + return tx_power_list + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + + Returns: + A boolean, True if successful, False if not + """ + return NotImplementedError + + def tx_disable(self, tx_disable): + """ + Disable SFP TX for all channels + + Args: + tx_disable : A Boolean, True to enable tx_disable mode, False to disable + tx_disable mode. + + Returns: + A boolean, True if tx_disable is set successfully, False if not + """ + return NotImplementedError + + def tx_disable_channel(self, channel, disable): + """ + Sets the tx_disable for specified SFP channels + + Args: + channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, + e.g. 0x5 for channel 0 and channel 2. + disable : A boolean, True to disable TX channels specified in channel, + False to enable + + Returns: + A boolean, True if successful, False if not + """ + return NotImplementedError + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + return NotImplementedError + + def set_power_override(self, power_override, power_set): + """ + Sets SFP power level using power_override and power_set + + Args: + power_override : + A Boolean, True to override set_lpmode and use power_set + to control SFP power, False to disable SFP power control + through power_override/power_set and use set_lpmode + to control SFP power. + power_set : + Only valid when power_override is True. + A Boolean, True to set SFP to low power mode, False to set + SFP to high power mode. + + Returns: + A boolean, True if power-override and power_set are set successfully, + False if not + """ + return NotImplementedError From e041b15d1081239a8dc19aadbdfd429045187828 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Wed, 29 May 2019 09:57:29 +0300 Subject: [PATCH 87/88] [mellanox]: Fixed config reload race. (#2930) Signed-off-by: Nazarii Hnydyn --- files/scripts/syncd.sh | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 0aa33add1632..04f407ebbcc8 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -101,8 +101,13 @@ start() { fi if [[ x"$WARM_BOOT" != x"true" ]]; then - /bin/systemctl stop pmon - /usr/bin/hw-management.sh chipdown + if [[ x"$(/bin/systemctl is-active pmon)" == x"active" ]]; then + /bin/systemctl stop pmon + /usr/bin/hw-management.sh chipdown + /bin/systemctl restart pmon + else + /usr/bin/hw-management.sh chipdown + fi fi if [[ x"$BOOT_TYPE" == x"fast" ]]; then @@ -112,10 +117,6 @@ start() { /usr/bin/mst start /usr/bin/mlnx-fw-upgrade.sh /etc/init.d/sxdkernel start - - if [[ x"$WARM_BOOT" != x"true" ]]; then - /bin/systemctl start pmon - fi fi if [[ x"$WARM_BOOT" != x"true" ]]; then @@ -128,10 +129,6 @@ start() { /usr/bin/${SERVICE}.sh start debug "Started ${SERVICE} service..." - if [[ x"$sonic_asic_platform" == x"mellanox" && x"$BOOT_TYPE" == x"fast" ]]; then - /usr/bin/hw-management.sh chipupen - fi - unlock_service_state_change } From c0eb90b96cb355b816ce8c055a5942c780782d44 Mon Sep 17 00:00:00 2001 From: Shuotian Cheng Date: Wed, 29 May 2019 16:14:48 -0700 Subject: [PATCH 88/88] [docker-vs]: Start staticd by default (#2929) Signed-off-by: Shu0T1an ChenG --- platform/vs/docker-sonic-vs/start.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index e8d062411f1c..3aaefa291fb2 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -59,6 +59,8 @@ supervisorctl start vlanmgrd supervisorctl start zebra +supervisorctl start staticd + supervisorctl start buffermgrd supervisorctl start nbrmgrd