Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions orchagent/port.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ class Port
sai_port_interface_type_t m_interface_type = SAI_PORT_INTERFACE_TYPE_NONE;
std::set<sai_port_interface_type_t> m_adv_interface_types;
bool m_mpls = false;
std::string m_media_type = "unknown";
/*
* Following bit vector is used to lock
* the queue from being changed in BufferOrch.
Expand Down
5 changes: 5 additions & 0 deletions orchagent/port/portcnt.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ class PortConfig final
bool is_set = false;
} link_training; // Port link training

struct {
std::string value;
bool is_set = false;
} media_type; // Port media type

struct {

struct {
Expand Down
23 changes: 23 additions & 0 deletions orchagent/port/porthlpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,22 @@ bool PortHelper::parsePortPtTimestampTemplate(PortConfig &port, const std::strin
return true;
}

bool PortHelper::parsePortMediaType(PortConfig &port, const std::string &field, const std::string &value) const
{
SWSS_LOG_ENTER();

if (value.empty())
{
SWSS_LOG_ERROR("Failed to parse field(%s): empty string is prohibited", field.c_str());
return false;
}

port.media_type.value = value;
port.media_type.is_set = true;

return true;
}

bool PortHelper::parsePortConfig(PortConfig &port) const
{
SWSS_LOG_ENTER();
Expand Down Expand Up @@ -1299,6 +1315,13 @@ bool PortHelper::parsePortConfig(PortConfig &port) const
* Setting exists in sonic-port.yang with possible values: routed|access|trunk
*/
}
else if (field == PORT_MEDIA_TYPE)
{
if (!this->parsePortMediaType(port, field, value))
{
return false;
}
}
else
{
SWSS_LOG_WARN("Unknown field(%s): skipping ...", field.c_str());
Expand Down
1 change: 1 addition & 0 deletions orchagent/port/porthlpr.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,5 @@ class PortHelper final
bool parsePortSubport(PortConfig &port, const std::string &field, const std::string &value) const;
bool parsePortPtIntfId(PortConfig &port, const std::string &field, const std::string &value) const;
bool parsePortPtTimestampTemplate(PortConfig &port, const std::string &field, const std::string &value) const;
bool parsePortMediaType(PortConfig &port, const std::string &field, const std::string &value) const;
};
1 change: 1 addition & 0 deletions orchagent/port/portschema.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,4 @@
#define PORT_FLAP_PENALTY "flap_penalty"
#define PORT_MODE "mode"
#define PORT_UNRELIABLE_LOS "unreliable_los"
#define PORT_MEDIA_TYPE "media_type"
48 changes: 47 additions & 1 deletion orchagent/portsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ static map<string, sai_bridge_port_fdb_learning_mode_t> learn_mode_map =
static map<string, sai_port_media_type_t> media_type_map =
{
{ "fiber", SAI_PORT_MEDIA_TYPE_FIBER },
{ "copper", SAI_PORT_MEDIA_TYPE_COPPER }
{ "copper", SAI_PORT_MEDIA_TYPE_COPPER },
{ "backplane", SAI_PORT_MEDIA_TYPE_BACKPLANE}
};

static map<string, sai_port_internal_loopback_mode_t> loopback_mode_map =
Expand Down Expand Up @@ -5196,6 +5197,21 @@ void PortsOrch::doPortTask(Consumer &consumer)
}
}
}
if (pCfg.media_type.is_set)
{
if (setPortMediaType(p, pCfg.media_type.value))
{
SWSS_LOG_NOTICE("Set port %s Media Type %s is successful",
p.m_alias.c_str(), pCfg.media_type.value.c_str());
}
else
{
SWSS_LOG_ERROR("Failed to set port %s Media Type %s",
p.m_alias.c_str(), pCfg.media_type.value.c_str());
it++;
continue;
}
}

/* create host_tx_ready field in state-db */
initHostTxReadyState(p);
Expand Down Expand Up @@ -9535,6 +9551,36 @@ bool PortsOrch::setPortSerdesAttribute(sai_object_id_t port_id, sai_object_id_t
}
}
SWSS_LOG_NOTICE("Created port serdes object 0x%" PRIx64 " for port 0x%" PRIx64, port_serdes_id, port_id);

return true;
}

bool PortsOrch::setPortMediaType(Port& port, const string &media_type)
{
sai_attribute_t attr;
sai_status_t status;

if (media_type_map.find(media_type) == media_type_map.end())
{
SWSS_LOG_NOTICE("Invalid media_type:%s for port %s", media_type.c_str(), port.m_alias.c_str());
return false;
}

attr.id = SAI_PORT_ATTR_MEDIA_TYPE;
attr.value.u32 = media_type_map[media_type];
status = sai_port_api->set_port_attribute(port.m_port_id, &attr);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to set Media Type %s 0x%x to port %s, rv:%d",
media_type.c_str(), attr.value.u32, port.m_alias.c_str(), status);
task_process_status handle_status = handleSaiSetStatus(SAI_API_PORT, status);
if (handle_status != task_success)
{
return parseHandleSaiStatusFailure(handle_status);
}
}
port.m_media_type = media_type;
SWSS_LOG_INFO("Set Media Type %s 0x%x to port pid:%" PRIx64, media_type.c_str(), attr.value.u32, port.m_port_id);
return true;
}

Expand Down
1 change: 1 addition & 0 deletions orchagent/portsorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ class PortsOrch : public Orch, public Subject
bool setPortFecOverride(sai_object_id_t port_obj, bool override_fec);
bool setPortPfcAsym(Port &port, sai_port_priority_flow_control_mode_t pfc_asym);
bool getDestPortId(sai_object_id_t src_port_id, dest_port_type_t port_type, sai_object_id_t &des_port_id);
bool setPortMediaType(Port& port, const string &media_type);

bool setBridgePortAdminStatus(sai_object_id_t id, bool up);

Expand Down
44 changes: 40 additions & 4 deletions tests/mock_tests/portsorch_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1219,19 +1219,51 @@ namespace portsorch_test
{ "obnlev", "0x5f,0x61,0x60,0x62" },
{ "regn_bfm1p", "0x1e,0x20,0x1f,0x21" },
{ "regn_bfm1n", "0xaa,0xac,0xab,0xad" },
{ "custom_serdes_attrs", custom_serdes_attrs }
{ "custom_serdes_attrs", custom_serdes_attrs },
{ "media_type", "backplane" }
}
}};
std::deque<KeyOpFieldsValuesTuple> kfvList1 = {{"Ethernet0", SET_COMMAND, {{ "media_type", "" }}}};
std::deque<KeyOpFieldsValuesTuple> kfvList2 = {{"Ethernet0", SET_COMMAND, {{ "media_type", "none" }}}};
std::deque<KeyOpFieldsValuesTuple> kfvListDel = {{"Ethernet0", "DEL" , {}}};

auto fvs = ports.begin()->second;

// Refill consumer
auto consumer = dynamic_cast<Consumer*>(gPortsOrch->getExecutor(APP_PORT_TABLE_NAME));
std::deque<KeyOpFieldsValuesTuple> kfvListAdd= {{"Ethernet0", SET_COMMAND , fvs}};

Port p;
//empty media_type should not be processed
consumer->addToSync(kfvList1);
static_cast<Orch*>(gPortsOrch)->doTask();
ASSERT_TRUE(gPortsOrch->getPort("Ethernet0", p));
ASSERT_EQ(p.m_media_type, "unknown");

consumer->addToSync(kfvListDel);
static_cast<Orch *>(gPortsOrch)->doTask();
consumer->addToSync(kfvListAdd);
static_cast<Orch*>(gPortsOrch)->doTask();
ASSERT_TRUE(gPortsOrch->getPort("Ethernet0", p));

consumer->addToSync(kfvList2);
static_cast<Orch*>(gPortsOrch)->doTask();
ASSERT_TRUE(gPortsOrch->getPort("Ethernet0", p));
ASSERT_EQ(p.m_media_type, "unknown");

consumer->addToSync(kfvListDel);
static_cast<Orch *>(gPortsOrch)->doTask();
consumer->addToSync(kfvListAdd);
static_cast<Orch*>(gPortsOrch)->doTask();
ASSERT_TRUE(gPortsOrch->getPort("Ethernet0", p));

// Refill consumer
consumer->addToSync(kfvList);

// Apply configuration
static_cast<Orch*>(gPortsOrch)->doTask();

// Get port
Port p;
// Port p;
ASSERT_TRUE(gPortsOrch->getPort("Ethernet0", p));

// Verify preemphasis
Expand Down Expand Up @@ -1305,9 +1337,14 @@ namespace portsorch_test
// Verify custom_serdes_attrs
ASSERT_EQ(p.m_serdes_attrs.at(SAI_PORT_SERDES_ATTR_CUSTOM_COLLECTION), SerdesValue(custom_serdes_attrs));

// Verify media_type
std::string media_type = "backplane";
ASSERT_EQ(p.m_media_type, media_type);

// Verify unreliablelos
ASSERT_EQ(p.m_unreliable_los, false);


// Dump pending tasks
std::vector<std::string> taskList;
gPortsOrch->dumpPendingTasks(taskList);
Expand Down Expand Up @@ -4071,5 +4108,4 @@ namespace portsorch_test

ASSERT_FALSE(port.m_init);
}

}
57 changes: 57 additions & 0 deletions tests/test_port.py
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,63 @@
if fv[0] == "SAI_PORT_ATTR_ADMIN_STATE":
assert fv[1] == "false"

def test_media_type(self, dvs, testlog):

db = swsscommon.DBConnector(0, dvs.redis_sock, 0)
adb = swsscommon.DBConnector(1, dvs.redis_sock, 0)

tbl = swsscommon.Table(db, "PORT_TABLE")
ptbl = swsscommon.ProducerStateTable(db, "PORT_TABLE")
atbl = swsscommon.Table(adb, "ASIC_STATE:SAI_OBJECT_TYPE_PORT")

media_name = 'media_type'
media_val = ""

fvs = swsscommon.FieldValuePairs([(media_name, media_val)])
ptbl.set("Ethernet0", fvs)

time.sleep(1)

# get media_type
(status, fvs) = atbl.get(dvs.asicdb.portnamemap["Ethernet0"])
assert status == True
#empty media_type should be rejected
for fv in fvs:
assert fv[0] != "SAI_PORT_ATTR_MEDIA_TYPE"

media_name = 'media_type'
media_val = "none"
fvs = swsscommon.FieldValuePairs([(media_name, media_val)])
ptbl.set("Ethernet0", fvs)

time.sleep(1)

# get media_type
(status, fvs) = atbl.get(dvs.asicdb.portnamemap["Ethernet0"])
assert status == True
#"none" media_type should be rejected
for fv in fvs:
assert fv[0] != "SAI_PORT_ATTR_MEDIA_TYPE"

media_name = 'media_type'
media_val = "backplane"
fvs = swsscommon.FieldValuePairs([(media_name, media_val)])
ptbl.set("Ethernet0", fvs)

time.sleep(1)

# get media_type
(status, fvs) = atbl.get(dvs.asicdb.portnamemap["Ethernet0"])
assert status == True

found = False
#check the media_type is added in ASIC_DB
for fv in fvs:
if fv[0] == "SAI_PORT_ATTR_MEDIA_TYPE":
assert fv[1] == "SAI_PORT_MEDIA_TYPE_BACKPLANE"
found = True
assert found == True

# 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():
Expand Down
Loading