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