From ddd57fe08f78f4463ee39a2075b0b0b0d56e9117 Mon Sep 17 00:00:00 2001 From: Dante Su Date: Thu, 19 May 2022 04:03:13 +0000 Subject: [PATCH] Have AN cap defaults to 1, and use AN attr for LT cap query Signed-off-by: Dante Su --- orchagent/port.h | 1 + orchagent/portsorch.cpp | 55 ++++++++++++++++++++++++++++++++++++++--- orchagent/portsorch.h | 1 + 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/orchagent/port.h b/orchagent/port.h index decf19614f..be56fe1704 100644 --- a/orchagent/port.h +++ b/orchagent/port.h @@ -181,6 +181,7 @@ class Port bool m_an_cfg = false; int m_cap_an = -1; /* Capability - AutoNeg, -1 means not set */ + int m_cap_lt = -1; /* Capability - LinkTraining, -1 means not set */ }; } diff --git a/orchagent/portsorch.cpp b/orchagent/portsorch.cpp index 62d1406a92..7cad4a938f 100755 --- a/orchagent/portsorch.cpp +++ b/orchagent/portsorch.cpp @@ -1944,8 +1944,37 @@ void PortsOrch::initPortCapAutoNeg(Port &port) } else { - port.m_cap_an = 0; - SWSS_LOG_NOTICE("Unable to get %s AN capability", port.m_alias.c_str()); + // To avoid breakage on the existing platforms, AN should be 1 by default + port.m_cap_an = 1; + SWSS_LOG_WARN("Unable to get %s AN capability, assumming it's supported", + port.m_alias.c_str()); + } +} + +void PortsOrch::initPortCapLinkTraining(Port &port) +{ + sai_status_t status; + sai_attribute_t attr; + + // TODO: Use SAI_PORT_ATTR_SUPPORTED_LINK_TRAINING_MODE for the query + // + // While SAI_PORT_ATTR_SUPPORTED_LINK_TRAINING_MODE is available at SAI master, + // it's not available in SAI v1.10 paried with SONiC.202205. + // And given that LT is part of AN, it should be okay to use + // SAI_PORT_ATTR_SUPPORTED_AUTO_NEG_MODE as a fallback plan. + attr.id = SAI_PORT_ATTR_SUPPORTED_AUTO_NEG_MODE; + status = sai_port_api->get_port_attribute(port.m_port_id, 1, &attr); + if (status == SAI_STATUS_SUCCESS) + { + port.m_cap_lt = attr.value.booldata ? 1 : 0; + } + else + { + // This is a new feature, hence none of breakage should be observed by + // having the LT capability flagged as NOT SUPPORTED upon a get failure + port.m_cap_lt = 0; + SWSS_LOG_WARN("Unable to get %s LT capability, assumming it's NOT supported", + port.m_alias.c_str()); } } @@ -3118,6 +3147,19 @@ void PortsOrch::doPortTask(Consumer &consumer) lt = link_training_mode_map[lt_str]; if (lt != p.m_link_training) { + if (p.m_cap_lt < 0) + { + initPortCapLinkTraining(p); + m_portList[alias] = p; + } + if (p.m_cap_lt < 1) + { + SWSS_LOG_WARN("%s: LT is not supported by the ASIC", alias.c_str()); + // Don't retry + it = consumer.m_toSync.erase(it); + continue; + } + auto status = setPortLinkTraining(p, lt > 0 ? true : false); if (status != task_success) { @@ -5985,7 +6027,9 @@ void PortsOrch::updatePortOperStatus(Port &port, sai_port_oper_status_t status) { if (status == SAI_PORT_OPER_STATUS_UP) { + /* Refresh AN port states */ updatePortStateAutoNeg(port); + /* Stop port state polling for AN */ updatePortStatePoll(port, PORT_STATE_POLL_AN, false); } else @@ -5997,9 +6041,11 @@ void PortsOrch::updatePortOperStatus(Port &port, sai_port_oper_status_t status) } if (port.m_admin_state_up && port.m_link_training > 0) { + /* Refresh LT port states for both link up and down */ updatePortStateLinkTraining(port); if (status == SAI_PORT_OPER_STATUS_UP) { + /* Stop port state polling for LT */ updatePortStatePoll(port, PORT_STATE_POLL_LT, false); } else @@ -7193,6 +7239,7 @@ bool PortsOrch::decrFdbCount(const std::string& alias, int count) return true; } +/* Refresh the per-port Auto-Negotiation operational states */ void PortsOrch::updatePortStateAutoNeg(const Port &port) { SWSS_LOG_ENTER(); @@ -7215,6 +7262,7 @@ void PortsOrch::updatePortStateAutoNeg(const Port &port) } } +/* Refresh the per-port Link-Training operational states */ void PortsOrch::updatePortStateLinkTraining(const Port &port) { SWSS_LOG_ENTER(); @@ -7226,7 +7274,7 @@ void PortsOrch::updatePortStateLinkTraining(const Port &port) string status = "off"; - if (port.m_link_training > 0) + if ((port.m_link_training > 0) && (port.m_cap_lt > 0)) { sai_port_link_training_rx_status_t rx_status; sai_port_link_training_failure_status_t failure; @@ -7256,6 +7304,7 @@ void PortsOrch::updatePortStateLinkTraining(const Port &port) m_portStateTable.hset(port.m_alias, "link_training_status", status); } +/* Activate/De-activate a specific port state poller task */ void PortsOrch::updatePortStatePoll(const Port &port, port_state_poll_t type, bool active) { if (type == PORT_STATE_POLL_NONE) diff --git a/orchagent/portsorch.h b/orchagent/portsorch.h index 8231d4554e..8814225e1c 100755 --- a/orchagent/portsorch.h +++ b/orchagent/portsorch.h @@ -294,6 +294,7 @@ class PortsOrch : public Orch, public Subject void deInitPort(string alias, sai_object_id_t port_id); void initPortCapAutoNeg(Port &port); + void initPortCapLinkTraining(Port &port); bool setPortAdminStatus(Port &port, bool up); bool getPortAdminStatus(sai_object_id_t id, bool& up);