From 8dc0a85638eeee6a44b2542edbd116d6506beb94 Mon Sep 17 00:00:00 2001 From: Tomer Shalvi <116184476+tshalvi@users.noreply.github.com> Date: Fri, 1 Dec 2023 20:29:54 +0200 Subject: [PATCH] Add support for new Port SI parameters in PortsOA (#2929) * Swss changes to support port SI per speed --- orchagent/port/portcnt.h | 30 +++++++++++++++++++ orchagent/port/porthlpr.cpp | 50 +++++++++++++++++++++++++++++++ orchagent/port/portschema.h | 6 ++++ orchagent/portsorch.cpp | 34 +++++++++++++++++++++ tests/mock_tests/portsorch_ut.cpp | 32 +++++++++++++++++++- 5 files changed, 151 insertions(+), 1 deletion(-) diff --git a/orchagent/port/portcnt.h b/orchagent/port/portcnt.h index 2c276370a8..26c8a603f6 100644 --- a/orchagent/port/portcnt.h +++ b/orchagent/port/portcnt.h @@ -155,6 +155,36 @@ class PortConfig final bool is_set = false; } attn; // Port serdes attn + struct { + std::vector value; + bool is_set = false; + } ob_m2lp; // Port serdes ob_m2lp + + struct { + std::vector value; + bool is_set = false; + } ob_alev_out; // Port serdes ob_alev_out + + struct { + std::vector value; + bool is_set = false; + } obplev; // Port serdes obplev + + struct { + std::vector value; + bool is_set = false; + } obnlev; // Port serdes obnlev + + struct { + std::vector value; + bool is_set = false; + } regn_bfm1p; // Port serdes regn_bfm1p + + struct { + std::vector value; + bool is_set = false; + } regn_bfm1n; // Port serdes regn_bfm1n + } serdes; // Port serdes struct { diff --git a/orchagent/port/porthlpr.cpp b/orchagent/port/porthlpr.cpp index c64e6fac4a..64c05b2aec 100644 --- a/orchagent/port/porthlpr.cpp +++ b/orchagent/port/porthlpr.cpp @@ -683,6 +683,14 @@ template bool PortHelper::parsePortSerdes(decltype(PortSerdes_t::post1) &serdes, template bool PortHelper::parsePortSerdes(decltype(PortSerdes_t::post2) &serdes, const std::string &field, const std::string &value) const; template bool PortHelper::parsePortSerdes(decltype(PortSerdes_t::post3) &serdes, const std::string &field, const std::string &value) const; template bool PortHelper::parsePortSerdes(decltype(PortSerdes_t::attn) &serdes, const std::string &field, const std::string &value) const; +template bool PortHelper::parsePortSerdes(decltype(PortSerdes_t::ob_m2lp) &serdes, const std::string &field, const std::string &value) const; +template bool PortHelper::parsePortSerdes(decltype(PortSerdes_t::ob_alev_out) &serdes, const std::string &field, const std::string &value) const; +template bool PortHelper::parsePortSerdes(decltype(PortSerdes_t::obplev) &serdes, const std::string &field, const std::string &value) const; +template bool PortHelper::parsePortSerdes(decltype(PortSerdes_t::obnlev) &serdes, const std::string &field, const std::string &value) const; +template bool PortHelper::parsePortSerdes(decltype(PortSerdes_t::regn_bfm1p) &serdes, const std::string &field, const std::string &value) const; +template bool PortHelper::parsePortSerdes(decltype(PortSerdes_t::regn_bfm1n) &serdes, const std::string &field, const std::string &value) const; + + bool PortHelper::parsePortRole(PortConfig &port, const std::string &field, const std::string &value) const { @@ -924,6 +932,48 @@ bool PortHelper::parsePortConfig(PortConfig &port) const return false; } } + else if (field == PORT_OB_M2LP) + { + if (!this->parsePortSerdes(port.serdes.ob_m2lp, field, value)) + { + return false; + } + } + else if (field == PORT_OB_ALEV_OUT) + { + if (!this->parsePortSerdes(port.serdes.ob_alev_out, field, value)) + { + return false; + } + } + else if (field == PORT_OBPLEV) + { + if (!this->parsePortSerdes(port.serdes.obplev, field, value)) + { + return false; + } + } + else if (field == PORT_OBNLEV) + { + if (!this->parsePortSerdes(port.serdes.obnlev, field, value)) + { + return false; + } + } + else if (field == PORT_REGN_BFM1P) + { + if (!this->parsePortSerdes(port.serdes.regn_bfm1p, field, value)) + { + return false; + } + } + else if (field == PORT_REGN_BFM1N) + { + if (!this->parsePortSerdes(port.serdes.regn_bfm1n, field, value)) + { + return false; + } + } else if (field == PORT_ROLE) { if (!this->parsePortRole(port, field, value)) diff --git a/orchagent/port/portschema.h b/orchagent/port/portschema.h index 4aabf39fbc..56b2541c37 100644 --- a/orchagent/port/portschema.h +++ b/orchagent/port/portschema.h @@ -77,6 +77,12 @@ #define PORT_POST2 "post2" #define PORT_POST3 "post3" #define PORT_ATTN "attn" +#define PORT_OB_M2LP "ob_m2lp" +#define PORT_OB_ALEV_OUT "ob_alev_out" +#define PORT_OBPLEV "obplev" +#define PORT_OBNLEV "obnlev" +#define PORT_REGN_BFM1P "regn_bfm1p" +#define PORT_REGN_BFM1N "regn_bfm1n" #define PORT_ROLE "role" #define PORT_ADMIN_STATUS "admin_status" #define PORT_DESCRIPTION "description" diff --git a/orchagent/portsorch.cpp b/orchagent/portsorch.cpp index b5e6eef744..98c13b7dc7 100755 --- a/orchagent/portsorch.cpp +++ b/orchagent/portsorch.cpp @@ -339,6 +339,39 @@ static void getPortSerdesAttr(PortSerdesAttrMap_t &map, const PortConfig &port) { map[SAI_PORT_SERDES_ATTR_TX_FIR_ATTN] = port.serdes.attn.value; } + + if (port.serdes.ob_m2lp.is_set) + { + + map[SAI_PORT_SERDES_ATTR_TX_PAM4_RATIO] = port.serdes.ob_m2lp.value; + } + + if (port.serdes.ob_alev_out.is_set) + { + map[SAI_PORT_SERDES_ATTR_TX_OUT_COMMON_MODE] = port.serdes.ob_alev_out.value; + } + + if (port.serdes.obplev.is_set) + { + map[SAI_PORT_SERDES_ATTR_TX_PMOS_COMMON_MODE] = port.serdes.obplev.value; + } + + if (port.serdes.obnlev.is_set) + { + map[SAI_PORT_SERDES_ATTR_TX_NMOS_COMMON_MODE] = port.serdes.obnlev.value; + } + + if (port.serdes.regn_bfm1p.is_set) + { + map[SAI_PORT_SERDES_ATTR_TX_PMOS_VLTG_REG] = port.serdes.regn_bfm1p.value; + } + + if (port.serdes.regn_bfm1n.is_set) + { + map[SAI_PORT_SERDES_ATTR_TX_NMOS_VLTG_REG] = port.serdes.regn_bfm1n.value; + } + + } // Port OA ------------------------------------------------------------------------------------------------------------ @@ -8775,3 +8808,4 @@ void PortsOrch::doTask(swss::SelectableTimer &timer) m_port_state_poller->stop(); } } + diff --git a/tests/mock_tests/portsorch_ut.cpp b/tests/mock_tests/portsorch_ut.cpp index d304901c90..fca4f34beb 100644 --- a/tests/mock_tests/portsorch_ut.cpp +++ b/tests/mock_tests/portsorch_ut.cpp @@ -708,7 +708,13 @@ namespace portsorch_test { "post1", "0x10,0x12,0x11,0x13" }, { "post2", "0x10,0x12,0x11,0x13" }, { "post3", "0x10,0x12,0x11,0x13" }, - { "attn", "0x80,0x82,0x81,0x83" } + { "attn", "0x80,0x82,0x81,0x83" }, + { "ob_m2lp", "0x4,0x6,0x5,0x7" }, + { "ob_alev_out", "0xf,0x11,0x10,0x12" }, + { "obplev", "0x69,0x6b,0x6a,0x6c" }, + { "obnlev", "0x5f,0x61,0x60,0x62" }, + { "regn_bfm1p", "0x1e,0x20,0x1f,0x21" }, + { "regn_bfm1n", "0xaa,0xac,0xab,0xad" } } }}; @@ -767,6 +773,30 @@ namespace portsorch_test std::vector attn = { 0x80, 0x82, 0x81, 0x83 }; ASSERT_EQ(p.m_preemphasis.at(SAI_PORT_SERDES_ATTR_TX_FIR_ATTN), attn); + // Verify ob_m2lp + std::vector ob_m2lp = { 0x4, 0x6, 0x5, 0x7 }; + ASSERT_EQ(p.m_preemphasis.at(SAI_PORT_SERDES_ATTR_TX_PAM4_RATIO), ob_m2lp); + + // Verify ob_alev_out + std::vector ob_alev_out = { 0xf, 0x11, 0x10, 0x12 }; + ASSERT_EQ(p.m_preemphasis.at(SAI_PORT_SERDES_ATTR_TX_OUT_COMMON_MODE), ob_alev_out); + + // Verify obplev + std::vector obplev = { 0x69, 0x6b, 0x6a, 0x6c }; + ASSERT_EQ(p.m_preemphasis.at(SAI_PORT_SERDES_ATTR_TX_PMOS_COMMON_MODE), obplev); + + // Verify obnlev + std::vector obnlev = { 0x5f, 0x61, 0x60, 0x62 }; + ASSERT_EQ(p.m_preemphasis.at(SAI_PORT_SERDES_ATTR_TX_NMOS_COMMON_MODE), obnlev); + + // Verify regn_bfm1p + std::vector regn_bfm1p = { 0x1e, 0x20, 0x1f, 0x21 }; + ASSERT_EQ(p.m_preemphasis.at(SAI_PORT_SERDES_ATTR_TX_PMOS_VLTG_REG), regn_bfm1p); + + // Verify regn_bfm1n + std::vector regn_bfm1n = { 0xaa, 0xac, 0xab, 0xad }; + ASSERT_EQ(p.m_preemphasis.at(SAI_PORT_SERDES_ATTR_TX_NMOS_VLTG_REG), regn_bfm1n); + // Dump pending tasks std::vector taskList; gPortsOrch->dumpPendingTasks(taskList);