From 854d54e07fd8eeff9cae0410e8e7f04d6385400b Mon Sep 17 00:00:00 2001 From: Jiahua Wang Date: Thu, 28 Jul 2022 10:20:26 -0700 Subject: [PATCH] Add support of mdio IPC server class using sai switch api and unix socket (#1080) Why I did it When MDIO devices (external PHYs) are connected on MDIO bus from NPU, the MDIO access is through SAI switch mdio read/write APIs. The syncd calling the SAI APIs needs to act as an IPC server so that the gbsyncd programming the MDIO devices can use the APIs by the IPC mechanism. How I did it MdioIpcServer class is added to start a new thread, to create an unix socket, to listen on the socket, to accept connection and to read/reply IPC messages. The corresponding functions for MDIO clause 45 and clause 22 access are also added to VendorSai class. How to verify it We can use socat to simulate the IPC client, e.g. docker exec -it syncd socat - UNIX-CONNECT:/var/run/sswsyncd/mdio-ipc.srv to read MDIO clause 45 register at an address and an offset mdio
to write MDIO clause 45 register at an address and an offset with a value mdio
to read MDIO clause 22 register at an address and an offset mdio-cl22
to write MDIO clause 22 register at an address and an offset with a value mdio-cl22
Signed-off-by: Jiahua Wang --- configure.ac | 1 + meta/SaiInterface.cpp | 48 ++++ meta/SaiInterface.h | 28 +++ syncd/Makefile.am | 5 + syncd/MdioIpcServer.cpp | 472 ++++++++++++++++++++++++++++++++++++++++ syncd/MdioIpcServer.h | 60 +++++ syncd/Syncd.cpp | 14 ++ syncd/Syncd.h | 3 + syncd/VendorSai.cpp | 64 ++++++ syncd/VendorSai.h | 28 +++ tests/aspell.en.pws | 5 + 11 files changed, 728 insertions(+) create mode 100644 syncd/MdioIpcServer.cpp create mode 100644 syncd/MdioIpcServer.h diff --git a/configure.ac b/configure.ac index 659dce57d6..6dc4040103 100644 --- a/configure.ac +++ b/configure.ac @@ -16,6 +16,7 @@ AX_CODE_COVERAGE AX_ADD_AM_MACRO_STATIC([]) AM_CONDITIONAL(SONIC_ASIC_PLATFORM_BAREFOOT, test x$CONFIGURED_PLATFORM = xbarefoot) +AM_CONDITIONAL(SONIC_ASIC_PLATFORM_BROADCOM, test x$CONFIGURED_PLATFORM = xbroadcom) AC_ARG_ENABLE(debug, [ --enable-debug turn on debugging], diff --git a/meta/SaiInterface.cpp b/meta/SaiInterface.cpp index 82e37242dc..b268f7890a 100644 --- a/meta/SaiInterface.cpp +++ b/meta/SaiInterface.cpp @@ -197,3 +197,51 @@ sai_status_t SaiInterface::get( return SAI_STATUS_FAILURE; } } + +sai_status_t SaiInterface::switchMdioRead( + _In_ sai_object_id_t switch_id, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _Out_ uint32_t *reg_val) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +sai_status_t SaiInterface::switchMdioWrite( + _In_ sai_object_id_t switch_id, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _In_ const uint32_t *reg_val) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +sai_status_t SaiInterface::switchMdioCl22Read( + _In_ sai_object_id_t switch_id, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _Out_ uint32_t *reg_val) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +sai_status_t SaiInterface::switchMdioCl22Write( + _In_ sai_object_id_t switch_id, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _In_ const uint32_t *reg_val) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} diff --git a/meta/SaiInterface.h b/meta/SaiInterface.h index fb8cdf0c42..8acf4983cd 100644 --- a/meta/SaiInterface.h +++ b/meta/SaiInterface.h @@ -222,6 +222,34 @@ namespace sairedis _In_ uint32_t attrCount, _In_ const sai_attribute_t *attrList) = 0; + virtual sai_status_t switchMdioRead( + _In_ sai_object_id_t switch_id, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _Out_ uint32_t *reg_val); + + virtual sai_status_t switchMdioWrite( + _In_ sai_object_id_t switch_id, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _In_ const uint32_t *reg_val); + + virtual sai_status_t switchMdioCl22Read( + _In_ sai_object_id_t switch_id, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _Out_ uint32_t *reg_val); + + virtual sai_status_t switchMdioCl22Write( + _In_ sai_object_id_t switch_id, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _In_ const uint32_t *reg_val); + public: // SAI API virtual sai_status_t objectTypeGetAvailability( diff --git a/syncd/Makefile.am b/syncd/Makefile.am index ddcdd04fcf..14519ff997 100644 --- a/syncd/Makefile.am +++ b/syncd/Makefile.am @@ -23,6 +23,7 @@ libSyncd_a_SOURCES = \ FlexCounterManager.cpp \ GlobalSwitchId.cpp \ HardReiniter.cpp \ + MdioIpcServer.cpp \ MetadataLogger.cpp \ NotificationHandler.cpp \ NotificationProcessor.cpp \ @@ -71,6 +72,10 @@ syncd_CXXFLAGS += -DSAITHRIFT=yes syncd_LDADD += -lrpcserver -lthrift endif +if SONIC_ASIC_PLATFORM_BROADCOM +libSyncd_a_CXXFLAGS += -DMDIO_ACCESS_USE_NPU +endif + libSyncdRequestShutdown_a_SOURCES = \ RequestShutdown.cpp \ RequestShutdownCommandLineOptions.cpp \ diff --git a/syncd/MdioIpcServer.cpp b/syncd/MdioIpcServer.cpp new file mode 100644 index 0000000000..452719055e --- /dev/null +++ b/syncd/MdioIpcServer.cpp @@ -0,0 +1,472 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "MdioIpcServer.h" + +#include "meta/sai_serialize.h" + +#include "swss/logger.h" + +#include +#include +#include + +#define SYNCD_IPC_SOCK_SYNCD "/var/run/sswsyncd" +#define SYNCD_IPC_SOCK_HOST "/var/run/docker-syncd" +#define SYNCD_IPC_SOCK_FILE "mdio-ipc" +#define SYNCD_IPC_BUFF_SIZE 256 /* buffer size */ + +#define CONN_TIMEOUT 30 /* sec, connection timeout */ +#define CONN_MAX 18 /* max. number of connections */ + +#ifndef COUNTOF +#define COUNTOF(x) ((int)(sizeof((x)) / sizeof((x)[0]))) +#endif + +using namespace syncd; + +bool MdioIpcServer::m_syncdContext = true; + +typedef struct syncd_mdio_ipc_conn_s +{ + int fd; + time_t timeout; +} syncd_mdio_ipc_conn_t; + +MdioIpcServer::MdioIpcServer( + _In_ std::shared_ptr vendorSai, + _In_ int globalContext): + m_vendorSai(vendorSai), + m_switchRid(SAI_NULL_OBJECT_ID), + m_taskThread(), + m_taskAlive(0) +{ + SWSS_LOG_ENTER(); + + /* globalContext == 0 for syncd, globalContext > 0 for gbsyncd */ + MdioIpcServer::m_syncdContext = (globalContext == 0); +} + +MdioIpcServer::~MdioIpcServer() +{ + SWSS_LOG_ENTER(); + + m_taskAlive = 0; + if(m_taskThread.joinable()) + { + m_taskThread.join(); + } +} + +void MdioIpcServer::setSwitchId( + _In_ sai_object_id_t switchRid) +{ + SWSS_LOG_ENTER(); + +#ifdef MDIO_ACCESS_USE_NPU + /* MDIO switch id is only relevant in syncd but not in gbsyncd */ + if (!MdioIpcServer::m_syncdContext) + { + return; + } + + if (m_switchRid != SAI_NULL_OBJECT_ID) + { + SWSS_LOG_ERROR("mdio switch id already initialized"); + return; + } + + m_switchRid = switchRid; + + SWSS_LOG_NOTICE("Initialize mdio switch id with RID = %s", + sai_serialize_object_id(m_switchRid).c_str()); +#endif +} + +/* + * mdio reg: Read from the PHY register + * mdio reg val: Write to the PHY register + */ +sai_status_t MdioIpcServer::syncd_ipc_cmd_mdio_common(char *resp, int argc, char *argv[]) +{ + int ret = 0; + uint32_t mdio_addr = 0, reg_addr = 0, val = 0; + + if (argc < 3) + { + return SAI_STATUS_INVALID_PARAMETER; + } + + mdio_addr = (uint32_t)strtoul(argv[1], NULL, 0); + reg_addr = (uint32_t)strtoul(argv[2], NULL, 0); + + if (m_switchRid == SAI_NULL_OBJECT_ID) + { + SWSS_LOG_ERROR("mdio switch id not initialized"); + return SAI_STATUS_FAILURE; + } + + if (argc > 3) + { + val = (uint32_t)strtoul(argv[3], NULL, 0); + ret = m_vendorSai->switchMdioWrite(m_switchRid, mdio_addr, reg_addr, 1, &val); + sprintf(resp, "%d\n", ret); + } + else + { + ret = m_vendorSai->switchMdioRead(m_switchRid, mdio_addr, reg_addr, 1, &val); + sprintf(resp, "%d 0x%x\n", ret, val); + } + + return (ret == 0) ? SAI_STATUS_SUCCESS : SAI_STATUS_FAILURE; +} + +#if (SAI_API_VERSION >= SAI_VERSION(1, 11, 0)) +sai_status_t MdioIpcServer::syncd_ipc_cmd_mdio_common_cl22(char *resp, int argc, char *argv[]) +{ + int ret = 0; + uint32_t mdio_addr = 0, reg_addr = 0, val = 0; + + if (argc < 3) + { + return SAI_STATUS_INVALID_PARAMETER; + } + + mdio_addr = (uint32_t)strtoul(argv[1], NULL, 0); + reg_addr = (uint32_t)strtoul(argv[2], NULL, 0); + + if (m_switchRid == SAI_NULL_OBJECT_ID) + { + SWSS_LOG_ERROR("mdio switch id not initialized"); + return SAI_STATUS_FAILURE; + } + + if (argc > 3) + { + val = (uint32_t)strtoul(argv[3], NULL, 0); + ret = m_vendorSai->switchMdioCl22Write(m_switchRid, mdio_addr, reg_addr, 1, &val); + sprintf(resp, "%d\n", ret); + } + else + { + ret = m_vendorSai->switchMdioCl22Read(m_switchRid, mdio_addr, reg_addr, 1, &val); + sprintf(resp, "%d 0x%x\n", ret, val); + } + + return (ret == 0) ? SAI_STATUS_SUCCESS : SAI_STATUS_FAILURE; +} +#endif + +sai_status_t MdioIpcServer::syncd_ipc_cmd_mdio(char *resp, int argc, char *argv[]) +{ + return syncd_ipc_cmd_mdio_common(resp, argc, argv); +} + +sai_status_t MdioIpcServer::syncd_ipc_cmd_mdio_cl22(char *resp, int argc, char *argv[]) +{ +#if (SAI_API_VERSION >= SAI_VERSION(1, 11, 0)) + return MdioIpcServer::syncd_ipc_cmd_mdio_common_cl22(resp, argc, argv); +#else + /* In this case, sai configuration should take care of mdio clause 22 */ + return MdioIpcServer::syncd_ipc_cmd_mdio_common(resp, argc, argv); +#endif +} + +int MdioIpcServer::syncd_ipc_task_main() +{ + SWSS_LOG_ENTER(); + + int i; + int fd; + int len; + int ret; + int sock_srv; + int sock_cli; + int sock_max; + syncd_mdio_ipc_conn_t conn[CONN_MAX]; + struct sockaddr_un addr; + char path[64]; + fd_set rfds; + char cmd[SYNCD_IPC_BUFF_SIZE], resp[SYNCD_IPC_BUFF_SIZE], *argv[64], *save; + int argc = 0; + + strcpy(path, SYNCD_IPC_SOCK_SYNCD); + fd = open(path, O_DIRECTORY); + if (fd < 0) + { + SWSS_LOG_ERROR("Unable to open the directory %s for IPC\n", path); + return errno; + } + + sock_srv = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock_srv < 0) + { + SWSS_LOG_ERROR("socket() returns %d", errno); + return errno; + } + + /***************************************/ + /* Set up the UNIX socket address */ + /* by using AF_UNIX for the family and */ + /* giving it a file path to bind to. */ + /* */ + /* Delete the file so the bind will */ + /* succeed, then bind to that file. */ + /***************************************/ + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + sprintf(addr.sun_path, "%s/%s.srv", path, SYNCD_IPC_SOCK_FILE); + unlink(addr.sun_path); + if (bind(sock_srv, (struct sockaddr *)&addr, sizeof(addr)) < 0) + { + SWSS_LOG_ERROR("bind() returns %d", errno); + close(sock_srv); + return errno; + } + + /* Listen for the upcoming client sockets */ + if (listen(sock_srv, CONN_MAX) < 0) + { + SWSS_LOG_ERROR("listen() returns %d", errno); + unlink(addr.sun_path); + close(sock_srv); + return errno; + } + + SWSS_LOG_NOTICE("IPC service is online\n"); + + memset(conn, 0, sizeof(conn)); + while (m_taskAlive) + { + time_t now; + struct timeval timeout; + + /* garbage collection */ + now = time(NULL); + for (i = 0; i < CONN_MAX; ++i) + { + if ((conn[i].fd > 0) && (conn[i].timeout < now)) + { + SWSS_LOG_NOTICE("socket %d: connection timeout\n", conn[i].fd); + close(conn[i].fd); + conn[i].fd = 0; + conn[i].timeout = 0; + } + } + + /* reset read file descriptors */ + FD_ZERO(&rfds); + FD_SET(sock_srv, &rfds); + sock_max = sock_srv; + for (i = 0; i < CONN_MAX; ++i) + { + if (conn[i].fd <= 0) + { + continue; + } + FD_SET(conn[i].fd, &rfds); + if (sock_max < conn[i].fd) + { + sock_max = conn[i].fd; + } + } + + /* monitor the socket descriptors */ + timeout.tv_sec = 1; + timeout.tv_usec = 0; + ret = select(sock_max + 1, &rfds, NULL, NULL, &timeout); + if (ret == 0) + { + continue; + } + else if (ret < 0) + { + if (errno == EINTR) + { + continue; + } + else + { + SWSS_LOG_ERROR("select() returns %d", errno); + break; + } + } + + /* Accept the new connection */ + now = time(NULL); + if (FD_ISSET(sock_srv, &rfds)) + { + sock_cli = accept(sock_srv, NULL, NULL); + if (sock_cli <= 0) + { + SWSS_LOG_ERROR("accept() returns %d", errno); + continue; + } + + for (i = 0; i < CONN_MAX; ++i) + { + if (conn[i].fd <= 0) + { + break; + } + } + if (i < CONN_MAX) + { + conn[i].fd = sock_cli; + conn[i].timeout = now + CONN_TIMEOUT; + } + else + { + SWSS_LOG_ERROR("too many connections!"); + close(sock_cli); + } + } + + /* Handle the client requests */ + for (i = 0; i < CONN_MAX; ++i) + { + sai_status_t rc = SAI_STATUS_NOT_SUPPORTED; + + sock_cli = conn[i].fd; + if ((sock_cli <= 0) || !FD_ISSET(sock_cli, &rfds)) + { + continue; + } + + /* get the command message */ + len = (int)recv(sock_cli, (void *)cmd, sizeof(cmd) - 1, 0); + if (len <= 0) + { + close(sock_cli); + conn[i].fd = 0; + conn[i].timeout = 0; + continue; + } + cmd[len] = 0; + + /* tokenize the command string */ + argc = 0; + std::string str(cmd); + boost::algorithm::trim(str); + boost::algorithm::to_lower(str); + std::vectorv(str.size()+1); + memcpy( &v.front(), str.c_str(), str.size() + 1 ); + argv[argc++] = strtok_r(v.data(), " \t\r\n", &save); + while (argc < COUNTOF(argv)) + { + argv[argc] = strtok_r(NULL, " \t\r\n", &save); + if (argv[argc] == NULL) + break; + ++argc; + } + + /* command dispatch */ + resp[0] = 0; + rc = SAI_STATUS_NOT_SUPPORTED; + if (argv[0] == NULL) + { + rc = SAI_STATUS_NOT_SUPPORTED; + } + else if (strcmp("mdio", argv[0]) == 0) + { + rc = MdioIpcServer::syncd_ipc_cmd_mdio(resp, argc, argv); + } + else if (strcmp("mdio-cl22", argv[0]) == 0) + { + rc = MdioIpcServer::syncd_ipc_cmd_mdio_cl22(resp, argc, argv); + } + + /* build the error message */ + if (rc != SAI_STATUS_SUCCESS) + { + sprintf(resp, "%d\n", rc); + } + + /* send out the response */ + len = (int)strlen(resp); + if (send(sock_cli, resp, len, 0) < len) + { + SWSS_LOG_ERROR("send() returns %d", errno); + } + + /* update the connection timeout counter */ + conn[i].timeout = time(NULL) + CONN_TIMEOUT; + } + } + + /* close socket descriptors */ + for (i = 0; i < CONN_MAX; ++i) + { + if (conn[i].fd <= 0) + { + continue; + } + close(conn[i].fd); + } + close(sock_srv); + unlink(addr.sun_path); + return errno; +} + +void MdioIpcServer::syncd_ipc_task_enter(void *ctx) +{ + SWSS_LOG_ENTER(); + + MdioIpcServer *mdioServer = (MdioIpcServer *)ctx; + mdioServer->syncd_ipc_task_main(); +} + +void MdioIpcServer::stopMdioThread(void) +{ + SWSS_LOG_ENTER(); + +#ifdef MDIO_ACCESS_USE_NPU + /* MDIO IPC server thread is only relevant in syncd but not in gbsyncd */ + if (!MdioIpcServer::m_syncdContext) + { + return; + } + + m_taskAlive = 0; + m_taskThread.join(); + SWSS_LOG_NOTICE("IPC task thread is stopped\n"); +#endif +} + +int MdioIpcServer::startMdioThread() +{ + SWSS_LOG_ENTER(); + +#ifdef MDIO_ACCESS_USE_NPU + /* MDIO IPC server thread is only relevant in syncd but not in gbsyncd */ + if (!MdioIpcServer::m_syncdContext) + { + return 0; + } + + if (!m_taskAlive) + { + m_taskAlive = 1; + try { + m_taskThread = std::thread(&MdioIpcServer::syncd_ipc_task_enter, this); + } + catch(const std::exception& e) { + MdioIpcServer::m_taskAlive = 0; + SWSS_LOG_ERROR("Unable to create IPC task thread: %s", e.what()); + return SAI_STATUS_FAILURE; + } + } +#endif + return SAI_STATUS_SUCCESS; +} diff --git a/syncd/MdioIpcServer.h b/syncd/MdioIpcServer.h new file mode 100644 index 0000000000..2da4e6c64a --- /dev/null +++ b/syncd/MdioIpcServer.h @@ -0,0 +1,60 @@ +#pragma once + +#include +#include "VendorSai.h" + +extern "C" { +#include +#include +} + +namespace syncd +{ + class MdioIpcServer + { + public: + + MdioIpcServer( + _In_ std::shared_ptr vendorSai, + _In_ int globalContext); + + virtual ~MdioIpcServer(); + + public: + + void setSwitchId( + _In_ sai_object_id_t switchRid); + + int startMdioThread(); + + void stopMdioThread(); + + public: + + static void syncd_ipc_task_enter(void*); + + private: + + int syncd_ipc_task_main(); + + sai_status_t syncd_ipc_cmd_mdio_common(char *resp, int argc, char *argv[]); + +#if (SAI_API_VERSION >= SAI_VERSION(1, 11, 0)) + sai_status_t syncd_ipc_cmd_mdio_common_cl22(char *resp, int argc, char *argv[]); +#endif + + sai_status_t syncd_ipc_cmd_mdio(char *resp, int argc, char *argv[]); + + sai_status_t syncd_ipc_cmd_mdio_cl22(char *resp, int argc, char *argv[]); + + static bool m_syncdContext; + + std::shared_ptr m_vendorSai; + + sai_object_id_t m_switchRid; + + std::thread m_taskThread; + + int m_taskAlive; + }; +} diff --git a/syncd/Syncd.cpp b/syncd/Syncd.cpp index 583ab893b5..2c256576bc 100644 --- a/syncd/Syncd.cpp +++ b/syncd/Syncd.cpp @@ -106,6 +106,7 @@ Syncd::Syncd( // we need STATE_DB ASIC_DB and COUNTERS_DB m_dbAsic = std::make_shared(m_contextConfig->m_dbAsic, 0); + m_mdioIpcServer = std::make_shared(m_vendorSai, m_commandLineOptions->m_globalContext); if (m_contextConfig->m_zmqEnable) { @@ -2612,6 +2613,8 @@ sai_status_t Syncd::processOidCreate( m_switches[switchVid] = std::make_shared(switchVid, objectRid, m_client, m_translator, m_vendorSai); + m_mdioIpcServer->setSwitchId(objectRid); + startDiagShell(objectRid); } @@ -3896,6 +3899,8 @@ void Syncd::onSwitchCreateInInitViewMode( m_switches[switchVid] = std::make_shared(switchVid, switchRid, m_client, m_translator, m_vendorSai); + m_mdioIpcServer->setSwitchId(switchRid); + startDiagShell(switchRid); } else @@ -4494,6 +4499,13 @@ void Syncd::run() // notification queue is created before we create switch m_processor->startNotificationsProcessingThread(); + for (auto& sw: m_switches) + { + m_mdioIpcServer->setSwitchId(sw.second->getRid()); + } + + m_mdioIpcServer->startMdioThread(); + SWSS_LOG_NOTICE("syncd listening for events"); s->addSelectable(m_selectableChannel.get()); @@ -4678,6 +4690,8 @@ void Syncd::run() m_manager->removeAllCounters(); + m_mdioIpcServer->stopMdioThread(); + sai_status_t status = removeAllSwitches(); // Stop notification thread after removing switch diff --git a/syncd/Syncd.h b/syncd/Syncd.h index d841537035..b7622bf019 100644 --- a/syncd/Syncd.h +++ b/syncd/Syncd.h @@ -17,6 +17,7 @@ #include "BreakConfig.h" #include "NotificationProducerBase.h" #include "TimerWatchdog.h" +#include "MdioIpcServer.h" #include "meta/SaiAttributeList.h" #include "meta/SelectableChannel.h" @@ -443,6 +444,8 @@ namespace syncd std::shared_ptr m_selectableChannel; + std::shared_ptr m_mdioIpcServer; + bool m_enableSyncMode; private: diff --git a/syncd/VendorSai.cpp b/syncd/VendorSai.cpp index f917a33cb0..303cfde669 100644 --- a/syncd/VendorSai.cpp +++ b/syncd/VendorSai.cpp @@ -1177,6 +1177,70 @@ sai_status_t VendorSai::flushFdbEntries( return m_apis.fdb_api->flush_fdb_entries(switch_id, attr_count, attr_list); } +sai_status_t VendorSai::switchMdioRead( + _In_ sai_object_id_t switch_id, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _Out_ uint32_t *reg_val) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + return m_apis.switch_api->switch_mdio_read(switch_id, device_addr, start_reg_addr, number_of_registers, reg_val); +} + +sai_status_t VendorSai::switchMdioWrite( + _In_ sai_object_id_t switch_id, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _In_ const uint32_t *reg_val) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + return m_apis.switch_api->switch_mdio_write(switch_id, device_addr, start_reg_addr, number_of_registers, reg_val); +} + +sai_status_t VendorSai::switchMdioCl22Read( + _In_ sai_object_id_t switch_id, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _Out_ uint32_t *reg_val) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + +#if (SAI_API_VERSION >= SAI_VERSION(1, 11, 0)) + return m_apis.switch_api->switch_mdio_cl22_read(switch_id, device_addr, start_reg_addr, number_of_registers, reg_val); +#else + return m_apis.switch_api->switch_mdio_read(switch_id, device_addr, start_reg_addr, number_of_registers, reg_val); +#endif +} + +sai_status_t VendorSai::switchMdioCl22Write( + _In_ sai_object_id_t switch_id, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _In_ const uint32_t *reg_val) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + +#if (SAI_API_VERSION >= SAI_VERSION(1, 11, 0)) + return m_apis.switch_api->switch_mdio_cl22_write(switch_id, device_addr, start_reg_addr, number_of_registers, reg_val); +#else + return m_apis.switch_api->switch_mdio_write(switch_id, device_addr, start_reg_addr, number_of_registers, reg_val); +#endif +} + // SAI API sai_status_t VendorSai::objectTypeGetAvailability( diff --git a/syncd/VendorSai.h b/syncd/VendorSai.h index 091a2afda5..3ef2f7694e 100644 --- a/syncd/VendorSai.h +++ b/syncd/VendorSai.h @@ -121,6 +121,34 @@ namespace syncd _In_ uint32_t attrCount, _In_ const sai_attribute_t *attrList) override; + virtual sai_status_t switchMdioRead( + _In_ sai_object_id_t switch_id, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _Out_ uint32_t *reg_val) override; + + virtual sai_status_t switchMdioWrite( + _In_ sai_object_id_t switch_id, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _In_ const uint32_t *reg_val) override; + + virtual sai_status_t switchMdioCl22Read( + _In_ sai_object_id_t switch_id, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _Out_ uint32_t *reg_val) override; + + virtual sai_status_t switchMdioCl22Write( + _In_ sai_object_id_t switch_id, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _In_ const uint32_t *reg_val) override; + public: // SAI API virtual sai_status_t objectTypeGetAvailability( diff --git a/tests/aspell.en.pws b/tests/aspell.en.pws index 05c891b083..1ceca3ecdf 100644 --- a/tests/aspell.en.pws +++ b/tests/aspell.en.pws @@ -31,6 +31,7 @@ FDB FDBs FIXME FlexCounter +gbsyncd GCM GRE GUID @@ -87,6 +88,7 @@ TODO TPID TXSC TestCase +tokenize VID VIDCOUNTER VIDTORID @@ -261,6 +263,8 @@ macsec MACsec MCAST md +mdio +MDIO Mellanox memcpy metadata @@ -295,6 +299,7 @@ param params performTransition pfc +PHY plaintext pn PN