Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions orchagent/portsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,18 @@ PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vector<table_name_wi
}
}

sai_attr_capability_t attr_cap;
if (sai_query_attribute_capability(gSwitchId, SAI_OBJECT_TYPE_PORT,
SAI_PORT_ATTR_AUTO_NEG_FEC_MODE_OVERRIDE,
&attr_cap) != SAI_STATUS_SUCCESS)
{
SWSS_LOG_NOTICE("Unable to query autoneg fec mode override");
}
else if (attr_cap.set_implemented && attr_cap.create_implemented)
{
fec_override_sup = true;
}

/* Get default 1Q bridge and default VLAN */
sai_status_t status;
sai_attribute_t attr;
Expand Down Expand Up @@ -1521,6 +1533,24 @@ bool PortsOrch::setPortFec(Port &port, sai_port_fec_mode_t fec_mode)
}
}

if (fec_override_sup)
{
attr.id = SAI_PORT_ATTR_AUTO_NEG_FEC_MODE_OVERRIDE;
attr.value.booldata = true;

status = sai_port_api->set_port_attribute(port.m_port_id, &attr);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to set fec override %d to port pid:%" PRIx64, attr.value.booldata, port.m_port_id);
task_process_status handle_status = handleSaiSetStatus(SAI_API_PORT, status);
if (handle_status != task_success)
{
return parseHandleSaiStatusFailure(handle_status);
}
}

SWSS_LOG_INFO("Set fec override %d to port pid:%" PRIx64, attr.value.booldata, port.m_port_id);
}
setGearboxPortsAttr(port, SAI_PORT_ATTR_FEC_MODE, &fec_mode);

SWSS_LOG_NOTICE("Set port %s FEC mode %d", port.m_alias.c_str(), fec_mode);
Expand Down Expand Up @@ -2524,6 +2554,18 @@ bool PortsOrch::setGearboxPortAttr(const Port &port, dest_port_type_t port_type,
m_gearboxTable->hset(key, speed_attr, to_string(speed));
SWSS_LOG_NOTICE("BOX: Updated APPL_DB key:%s %s %d", key.c_str(), speed_attr.c_str(), speed);
}
else if (id == SAI_PORT_ATTR_FEC_MODE && fec_override_sup)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dgsudharsan why are we setting this inside gerabox ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The FEC attribute setting API after setting for port will call gearbox API if gearbox is present. Hence this needs to be set to be in sync with Port FEC setting.

{
attr.id = SAI_PORT_ATTR_AUTO_NEG_FEC_MODE_OVERRIDE;
attr.value.booldata = true;

status = sai_port_api->set_port_attribute(dest_port_id, &attr);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dgsudharsan i think we should do fec override if AN is configured.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@prgeor Both are independent attributes. SAI headers doesn't mandate that FEC override should need to be set only on AN. To avoid complexity in orchagent, both are set independently and vendor SAI will handle them in any order

if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("BOX: Failed to set %s port fec override %d",
port.m_alias.c_str(), attr.value.booldata);
}
}
}
else
{
Expand Down
1 change: 1 addition & 0 deletions orchagent/portsorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ class PortsOrch : public Orch, public Subject
map<string, uint32_t> m_bridge_port_ref_count;

NotificationConsumer* m_portStatusNotificationConsumer;
bool fec_override_sup = false;

swss::SelectableTimer *m_port_state_poller = nullptr;

Expand Down
30 changes: 30 additions & 0 deletions tests/test_port_fec_override.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import time
import os
import pytest

from swsscommon import swsscommon

DVS_ENV = ["HWSKU=Mellanox-SN2700"]

class TestPort(object):
def test_PortFecOverride(self, dvs, testlog):
db = swsscommon.DBConnector(0, dvs.redis_sock, 0)
adb = dvs.get_asic_db()

ptbl = swsscommon.ProducerStateTable(db, "PORT_TABLE")

# set fec
fvs = swsscommon.FieldValuePairs([("fec","rs")])
ptbl.set("Ethernet4", fvs)

# validate if fec rs is pushed to asic db when set first time
port_oid = adb.port_name_map["Ethernet4"]
expected_fields = {"SAI_PORT_ATTR_FEC_MODE":"SAI_PORT_FEC_MODE_RS", "SAI_PORT_ATTR_AUTO_NEG_FEC_MODE_OVERRIDE":"true"}
adb.wait_for_field_match("ASIC_STATE:SAI_OBJECT_TYPE_PORT", port_oid, expected_fields)


# Add Dummy always-pass test at end as workaroud
# for issue when Flaky fail on final test it invokes module tear-down before retrying
def test_nonflaky_dummy():
pass