Skip to content

Commit 1e1438e

Browse files
authored
[portsorch] Expose supported FEC modes to STABE_DB and check whether FEC mode is supported before setting it (sonic-net#2400)
* Revert "Revert "[portsorch] Expose supported FEC modes to STABE_DB and check whether FEC mode is supported before setting it (sonic-net#2333)" (sonic-net#2396)" This reverts commit 6565b50. * Adjust the prototype of setPortFec Signed-off-by: Stephen Sun <[email protected]>
1 parent 168bd3b commit 1e1438e

File tree

4 files changed

+344
-13
lines changed

4 files changed

+344
-13
lines changed

orchagent/p4orch/tests/fake_portorch.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ bool PortsOrch::getPortPvid(Port &port, sai_uint32_t &pvid)
518518
return true;
519519
}
520520

521-
bool PortsOrch::setPortFec(Port &port, sai_port_fec_mode_t mode)
521+
bool PortsOrch::setPortFec(Port &port, std::string &mode)
522522
{
523523
return true;
524524
}

orchagent/portsorch.cpp

+109-11
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@ static map<string, sai_port_fec_mode_t> fec_mode_map =
7979
{ "fc", SAI_PORT_FEC_MODE_FC }
8080
};
8181

82+
static map<sai_port_fec_mode_t, string> fec_mode_reverse_map =
83+
{
84+
{ SAI_PORT_FEC_MODE_NONE, "none" },
85+
{ SAI_PORT_FEC_MODE_RS, "rs" },
86+
{ SAI_PORT_FEC_MODE_FC, "fc" }
87+
};
88+
8289
static map<string, sai_port_priority_flow_control_mode_t> pfc_asym_map =
8390
{
8491
{ "on", SAI_PORT_PRIORITY_FLOW_CONTROL_MODE_SEPARATE },
@@ -1214,27 +1221,39 @@ bool PortsOrch::setPortTpid(sai_object_id_t id, sai_uint16_t tpid)
12141221
return true;
12151222
}
12161223

1217-
1218-
bool PortsOrch::setPortFec(Port &port, sai_port_fec_mode_t mode)
1224+
bool PortsOrch::setPortFec(Port &port, string &mode)
12191225
{
12201226
SWSS_LOG_ENTER();
12211227

1228+
auto searchRef = m_portSupportedFecModes.find(port.m_port_id);
1229+
if (searchRef != m_portSupportedFecModes.end())
1230+
{
1231+
auto &supportedFecModes = searchRef->second;
1232+
if (!supportedFecModes.empty() && (supportedFecModes.find(mode) == supportedFecModes.end()))
1233+
{
1234+
SWSS_LOG_ERROR("Unsupported mode %s on port %s", mode.c_str(), port.m_alias.c_str());
1235+
// We return true becase the caller will keep the item in m_toSync and retry it later if we return false
1236+
// As the FEC mode is not supported it doesn't make sense to retry.
1237+
return true;
1238+
}
1239+
}
1240+
12221241
sai_attribute_t attr;
12231242
attr.id = SAI_PORT_ATTR_FEC_MODE;
1224-
attr.value.s32 = mode;
1243+
attr.value.s32 = port.m_fec_mode;
12251244

12261245
sai_status_t status = sai_port_api->set_port_attribute(port.m_port_id, &attr);
12271246
if (status != SAI_STATUS_SUCCESS)
12281247
{
1229-
SWSS_LOG_ERROR("Failed to set fec mode %d to port pid:%" PRIx64, mode, port.m_port_id);
1248+
SWSS_LOG_ERROR("Failed to set FEC mode %s to port %s", mode.c_str(), port.m_alias.c_str());
12301249
task_process_status handle_status = handleSaiSetStatus(SAI_API_PORT, status);
12311250
if (handle_status != task_success)
12321251
{
12331252
return parseHandleSaiStatusFailure(handle_status);
12341253
}
12351254
}
12361255

1237-
SWSS_LOG_INFO("Set fec mode %d to port pid:%" PRIx64, mode, port.m_port_id);
1256+
SWSS_LOG_NOTICE("Set port %s FEC mode %s", port.m_alias.c_str(), mode.c_str());
12381257

12391258
setGearboxPortsAttr(port, SAI_PORT_ATTR_FEC_MODE, &mode);
12401259

@@ -2011,6 +2030,7 @@ void PortsOrch::initPortSupportedSpeeds(const std::string& alias, sai_object_id_
20112030
m_portStateTable.set(alias, v);
20122031
}
20132032

2033+
20142034
void PortsOrch::initPortCapAutoNeg(Port &port)
20152035
{
20162036
sai_status_t status;
@@ -2040,6 +2060,87 @@ void PortsOrch::initPortCapLinkTraining(Port &port)
20402060
SWSS_LOG_WARN("Unable to get %s LT support capability", port.m_alias.c_str());
20412061
}
20422062

2063+
void PortsOrch::getPortSupportedFecModes(const std::string& alias, sai_object_id_t port_id, PortSupportedFecModes &supported_fecmodes)
2064+
{
2065+
sai_attribute_t attr;
2066+
sai_status_t status;
2067+
vector<sai_int32_t> fecModes(fec_mode_reverse_map.size());
2068+
2069+
attr.id = SAI_PORT_ATTR_SUPPORTED_FEC_MODE;
2070+
attr.value.s32list.count = static_cast<uint32_t>(fecModes.size());
2071+
attr.value.s32list.list = fecModes.data();
2072+
2073+
status = sai_port_api->get_port_attribute(port_id, 1, &attr);
2074+
fecModes.resize(attr.value.s32list.count);
2075+
if (status == SAI_STATUS_SUCCESS)
2076+
{
2077+
if (fecModes.empty())
2078+
{
2079+
supported_fecmodes.insert("N/A");
2080+
}
2081+
else
2082+
{
2083+
for(auto fecMode : fecModes)
2084+
{
2085+
supported_fecmodes.insert(fec_mode_reverse_map[static_cast<sai_port_fec_mode_t>(fecMode)]);
2086+
}
2087+
}
2088+
}
2089+
else
2090+
{
2091+
if (SAI_STATUS_IS_ATTR_NOT_SUPPORTED(status) ||
2092+
SAI_STATUS_IS_ATTR_NOT_IMPLEMENTED(status) ||
2093+
status == SAI_STATUS_NOT_IMPLEMENTED)
2094+
{
2095+
// unable to validate FEC mode if attribute is not supported on platform
2096+
SWSS_LOG_NOTICE("Unable to validate FEC mode for port %s id=%" PRIx64 " due to unsupported by platform",
2097+
alias.c_str(), port_id);
2098+
}
2099+
else
2100+
{
2101+
SWSS_LOG_ERROR("Failed to get a list of supported FEC modes for port %s id=%" PRIx64 ". Error=%d",
2102+
alias.c_str(), port_id, status);
2103+
}
2104+
2105+
supported_fecmodes.clear(); // return empty
2106+
}
2107+
}
2108+
2109+
void PortsOrch::initPortSupportedFecModes(const std::string& alias, sai_object_id_t port_id)
2110+
{
2111+
// If port supported speeds map already contains the information, save the SAI call
2112+
if (m_portSupportedFecModes.count(port_id))
2113+
{
2114+
return;
2115+
}
2116+
PortSupportedFecModes supported_fec_modes;
2117+
getPortSupportedFecModes(alias, port_id, supported_fec_modes);
2118+
m_portSupportedFecModes[port_id] = supported_fec_modes;
2119+
2120+
if (supported_fec_modes.empty())
2121+
{
2122+
// Do not expose "supported_fecs" in case fetching FEC modes is not supported by the vendor
2123+
SWSS_LOG_INFO("No supported_fecs exposed to STATE_DB for port %s since fetching supported FEC modes is not supported by the vendor",
2124+
alias.c_str());
2125+
return;
2126+
}
2127+
2128+
vector<FieldValueTuple> v;
2129+
std::string supported_fec_modes_str;
2130+
bool first = true;
2131+
for(auto fec : supported_fec_modes)
2132+
{
2133+
if (first)
2134+
first = false;
2135+
else
2136+
supported_fec_modes_str += ',';
2137+
supported_fec_modes_str += fec;
2138+
}
2139+
2140+
v.emplace_back(std::make_pair("supported_fecs", supported_fec_modes_str));
2141+
m_portStateTable.set(alias, v);
2142+
}
2143+
20432144
/*
20442145
* If Gearbox is enabled and this is a Gearbox port then set the attributes accordingly.
20452146
*/
@@ -3105,6 +3206,7 @@ void PortsOrch::doPortTask(Consumer &consumer)
31053206
}
31063207

31073208
initPortSupportedSpeeds(get<0>(it->second), m_portListLaneMap[it->first]);
3209+
initPortSupportedFecModes(get<0>(it->second), m_portListLaneMap[it->first]);
31083210
it++;
31093211
}
31103212

@@ -3520,14 +3622,12 @@ void PortsOrch::doPortTask(Consumer &consumer)
35203622
p.m_fec_mode = fec_mode_map[fec_mode];
35213623
p.m_fec_cfg = true;
35223624

3523-
if (setPortFec(p, p.m_fec_mode))
3625+
if (setPortFec(p, fec_mode))
35243626
{
35253627
m_portList[alias] = p;
3526-
SWSS_LOG_NOTICE("Set port %s fec to %s", alias.c_str(), fec_mode.c_str());
35273628
}
35283629
else
35293630
{
3530-
SWSS_LOG_ERROR("Failed to set port %s fec to %s", alias.c_str(), fec_mode.c_str());
35313631
it++;
35323632
continue;
35333633
}
@@ -3537,14 +3637,12 @@ void PortsOrch::doPortTask(Consumer &consumer)
35373637
/* Port is already down, setting fec mode*/
35383638
p.m_fec_mode = fec_mode_map[fec_mode];
35393639
p.m_fec_cfg = true;
3540-
if (setPortFec(p, p.m_fec_mode))
3640+
if (setPortFec(p, fec_mode))
35413641
{
35423642
m_portList[alias] = p;
3543-
SWSS_LOG_NOTICE("Set port %s fec to %s", alias.c_str(), fec_mode.c_str());
35443643
}
35453644
else
35463645
{
3547-
SWSS_LOG_ERROR("Failed to set port %s fec to %s", alias.c_str(), fec_mode.c_str());
35483646
it++;
35493647
continue;
35503648
}

orchagent/portsorch.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#define PG_DROP_STAT_COUNTER_FLEX_COUNTER_GROUP "PG_DROP_STAT_COUNTER"
2828

2929
typedef std::vector<sai_uint32_t> PortSupportedSpeeds;
30+
typedef std::set<std::string> PortSupportedFecModes;
3031

3132
static const map<sai_port_oper_status_t, string> oper_status_strings =
3233
{
@@ -209,6 +210,8 @@ class PortsOrch : public Orch, public Subject
209210
unique_ptr<Table> m_gbcounterTable;
210211

211212
std::map<sai_object_id_t, PortSupportedSpeeds> m_portSupportedSpeeds;
213+
// Supported FEC modes on the system side.
214+
std::map<sai_object_id_t, PortSupportedFecModes> m_portSupportedFecModes;
212215

213216
bool m_initDone = false;
214217
Port m_cpuPort;
@@ -311,7 +314,7 @@ class PortsOrch : public Orch, public Subject
311314
bool setPortTpid(sai_object_id_t id, sai_uint16_t tpid);
312315
bool setPortPvid (Port &port, sai_uint32_t pvid);
313316
bool getPortPvid(Port &port, sai_uint32_t &pvid);
314-
bool setPortFec(Port &port, sai_port_fec_mode_t mode);
317+
bool setPortFec(Port &port, std::string &mode);
315318
bool setPortPfcAsym(Port &port, string pfc_asym);
316319
bool getDestPortId(sai_object_id_t src_port_id, dest_port_type_t port_type, sai_object_id_t &des_port_id);
317320

@@ -320,6 +323,9 @@ class PortsOrch : public Orch, public Subject
320323
bool isSpeedSupported(const std::string& alias, sai_object_id_t port_id, sai_uint32_t speed);
321324
void getPortSupportedSpeeds(const std::string& alias, sai_object_id_t port_id, PortSupportedSpeeds &supported_speeds);
322325
void initPortSupportedSpeeds(const std::string& alias, sai_object_id_t port_id);
326+
// Get supported FEC modes on system side
327+
void getPortSupportedFecModes(const std::string& alias, sai_object_id_t port_id, PortSupportedFecModes &supported_fecmodes);
328+
void initPortSupportedFecModes(const std::string& alias, sai_object_id_t port_id);
323329
task_process_status setPortSpeed(Port &port, sai_uint32_t speed);
324330
bool getPortSpeed(sai_object_id_t id, sai_uint32_t &speed);
325331
bool setGearboxPortsAttr(Port &port, sai_port_attr_t id, void *value);

0 commit comments

Comments
 (0)