Skip to content

Commit

Permalink
[portsorch]: Add support of port speed set via PORT_TABLE (sonic-net#248
Browse files Browse the repository at this point in the history
)

* Add support of port speed set via PORT_TABLE
* Port will go down/up automatically to apply speed once it is set
* PR comments fixed
  - variable array changed to std::vector
  - is port speed get failed - undefined value is not assigned
* Supported speeds query once per run. Used std::find for search
  • Loading branch information
andriymoroz-mlnx authored and Shuotian Cheng committed Jul 18, 2017
1 parent 179daac commit 32f41b4
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 12 deletions.
140 changes: 128 additions & 12 deletions orchagent/portsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <fstream>
#include <sstream>
#include <set>
#include <algorithm>

#include <netinet/if_ether.h>
#include "net/if.h"
Expand Down Expand Up @@ -243,6 +244,79 @@ bool PortsOrch::setPortMtu(sai_object_id_t id, sai_uint32_t mtu)
return true;
}

bool PortsOrch::validatePortSpeed(sai_object_id_t port_id, sai_uint32_t speed)
{
sai_attribute_t attr;
sai_status_t status;

// "Lazy" query of supported speeds for given port
// Once received the list will be stored in m_portSupportedSpeeds
if (!m_portSupportedSpeeds.count(port_id))
{
attr.id = SAI_PORT_ATTR_SUPPORTED_SPEED;
attr.value.u32list.count = 0;
attr.value.u32list.list = NULL;
status = sai_port_api->get_port_attribute(port_id, 1, &attr);
if (status == SAI_STATUS_BUFFER_OVERFLOW)
{
std::vector<sai_uint32_t> speeds(attr.value.u32list.count);
attr.value.u32list.list = speeds.data();
status = sai_port_api->get_port_attribute(port_id, 1, &attr);
if (status == SAI_STATUS_SUCCESS)
{
m_portSupportedSpeeds[port_id] = speeds;
}
else
{
SWSS_LOG_ERROR("Failed to get supported speed list for port %lx\n", port_id);
return false;
}
}
else
{
SWSS_LOG_ERROR("Failed to get number of supported speeds for port %lx\n", port_id);
return false;
}
}

PortSupportedSpeeds &supp_speeds = m_portSupportedSpeeds[port_id];

return std::find(supp_speeds.begin(), supp_speeds.end(), speed) != supp_speeds.end();
}

bool PortsOrch::setPortSpeed(sai_object_id_t port_id, sai_uint32_t speed)
{
SWSS_LOG_ENTER();

sai_attribute_t attr;
sai_status_t status;

attr.id = SAI_PORT_ATTR_SPEED;
attr.value.u32 = speed;

status = sai_port_api->set_port_attribute(port_id, &attr);

return status == SAI_STATUS_SUCCESS;
}

bool PortsOrch::getPortSpeed(sai_object_id_t port_id, sai_uint32_t &speed)
{
SWSS_LOG_ENTER();

sai_attribute_t attr;
sai_status_t status;

attr.id = SAI_PORT_ATTR_SPEED;
attr.value.u32 = 0;

status = sai_port_api->get_port_attribute(port_id, 1, &attr);

if (status == SAI_STATUS_SUCCESS)
speed = attr.value.u32;

return status == SAI_STATUS_SUCCESS;
}

bool PortsOrch::setHostIntfsOperStatus(sai_object_id_t port_id, bool up)
{
SWSS_LOG_ENTER();
Expand Down Expand Up @@ -324,6 +398,7 @@ void PortsOrch::doPortTask(Consumer &consumer)
set<int> lane_set;
string admin_status;
uint32_t mtu = 0;
uint32_t speed = 0;

for (auto i : kfvFieldsValues(t))
{
Expand All @@ -348,6 +423,10 @@ void PortsOrch::doPortTask(Consumer &consumer)
/* Set port mtu */
if (fvField(i) == "mtu")
mtu = stoul(fvValue(i));

/* Set port speed */
if (fvField(i) == "speed")
speed = stoul(fvValue(i));
}

if (lane_set.size())
Expand Down Expand Up @@ -393,10 +472,55 @@ void PortsOrch::doPortTask(Consumer &consumer)
SWSS_LOG_ERROR("Failed to locate port lane combination alias:%s", alias.c_str());
}

if (admin_status != "")
Port p;
if (!getPort(alias, p))
{
SWSS_LOG_ERROR("Failed to get port id by alias:%s", alias.c_str());
}
else
{
Port p;
if (getPort(alias, p))
if (speed != 0)
{
sai_uint32_t current_speed;

if (!validatePortSpeed(p.m_port_id, speed))
{
SWSS_LOG_ERROR("Failed to set speed %u for port %s. The value is not supported", speed, alias.c_str());
it++;
continue;
}

if (getPortSpeed(p.m_port_id, current_speed))
{
if (speed != current_speed)
{
if(setPortAdminStatus(p.m_port_id, false))
{
if (setPortSpeed(p.m_port_id, speed))
{
SWSS_LOG_NOTICE("Set port %s speed to %u", alias.c_str(), speed);
}
else
{
SWSS_LOG_ERROR("Failed to set port %s speed to %u", alias.c_str(), speed);
it++;
continue;
}
}
else
{
SWSS_LOG_ERROR("Failed to set port admin status DOWN to set speed");
}
}
}
else
{
SWSS_LOG_ERROR("Failed to get current speed for port %s", alias.c_str());
}

}

if (admin_status != "")
{
if (setPortAdminStatus(p.m_port_id, admin_status == "up"))
SWSS_LOG_NOTICE("Set port %s admin status to %s", alias.c_str(), admin_status.c_str());
Expand All @@ -407,14 +531,8 @@ void PortsOrch::doPortTask(Consumer &consumer)
continue;
}
}
else
SWSS_LOG_ERROR("Failed to get port id by alias:%s", alias.c_str());
}

if (mtu != 0)
{
Port p;
if (getPort(alias, p))
if (mtu != 0)
{
if (setPortMtu(p.m_port_id, mtu))
SWSS_LOG_NOTICE("Set port %s MTU to %u", alias.c_str(), mtu);
Expand All @@ -425,8 +543,6 @@ void PortsOrch::doPortTask(Consumer &consumer)
continue;
}
}
else
SWSS_LOG_ERROR("Failed to get port id by alias:%s", alias.c_str());
}
}
else
Expand Down
7 changes: 7 additions & 0 deletions orchagent/portsorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#define FCS_LEN 4
#define VLAN_TAG_LEN 4

typedef std::vector<sai_uint32_t> PortSupportedSpeeds;

static const map<sai_port_oper_status_t, string> oper_status_strings =
{
{ SAI_PORT_OPER_STATUS_UNKNOWN, "unknown" },
Expand Down Expand Up @@ -53,6 +55,8 @@ class PortsOrch : public Orch, public Subject
unique_ptr<Table> m_counterTable;
unique_ptr<Table> m_portTable;

std::map<sai_object_id_t, PortSupportedSpeeds> m_portSupportedSpeeds;

bool m_initDone = false;
sai_object_id_t m_cpuPort;

Expand Down Expand Up @@ -85,6 +89,9 @@ class PortsOrch : public Orch, public Subject

bool setPortAdminStatus(sai_object_id_t id, bool up);
bool setPortMtu(sai_object_id_t id, sai_uint32_t mtu);
bool validatePortSpeed(sai_object_id_t port_id, sai_uint32_t speed);
bool setPortSpeed(sai_object_id_t port_id, sai_uint32_t speed);
bool getPortSpeed(sai_object_id_t port_id, sai_uint32_t &speed);
};
#endif /* SWSS_PORTSORCH_H */

0 comments on commit 32f41b4

Please sign in to comment.