Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ orchagent_SOURCES = \
mplsrouteorch.cpp \
neighorch.cpp \
intfsorch.cpp \
port/portcap.cpp \
port/porthlpr.cpp \
portsorch.cpp \
fabricportsorch.cpp \
Expand Down
2 changes: 2 additions & 0 deletions orchagent/p4orch/tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ p4orch_tests_SOURCES = $(ORCHAGENT_DIR)/orch.cpp \
$(top_srcdir)/lib/recorder.cpp \
$(ORCHAGENT_DIR)/flex_counter/flex_counter_manager.cpp \
$(ORCHAGENT_DIR)/flex_counter/flow_counter_handler.cpp \
$(ORCHAGENT_DIR)/port/portcap.cpp \
$(ORCHAGENT_DIR)/port/porthlpr.cpp \
$(P4ORCH_DIR)/p4oidmapper.cpp \
$(P4ORCH_DIR)/p4orch.cpp \
$(P4ORCH_DIR)/p4orch_util.cpp \
Expand Down
78 changes: 78 additions & 0 deletions orchagent/port/portcap.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// includes -----------------------------------------------------------------------------------------------------------

extern "C" {
#include <saistatus.h>
}

#include <string>

#include <sai_serialize.h>
#include <logger.h>

#include "portcap.h"

using namespace swss;

// variables ----------------------------------------------------------------------------------------------------------

extern sai_object_id_t gSwitchId;

// functions ----------------------------------------------------------------------------------------------------------

static std::string toStr(sai_object_type_t objType, sai_attr_id_t attrId) noexcept
{
const auto *meta = sai_metadata_get_attr_metadata(objType, attrId);

return meta != nullptr ? meta->attridname : "UNKNOWN";
}

// Port capabilities --------------------------------------------------------------------------------------------------

PortCapabilities::PortCapabilities()
{
queryPortAttrCapabilities(portCapabilities.pfc, SAI_PORT_ATTR_PRIORITY_FLOW_CONTROL);
queryPortAttrCapabilities(portCapabilities.pfcTx, SAI_PORT_ATTR_PRIORITY_FLOW_CONTROL_TX);
queryPortAttrCapabilities(portCapabilities.pfcRx, SAI_PORT_ATTR_PRIORITY_FLOW_CONTROL_RX);
queryPortAttrCapabilities(portCapabilities.pfcMode, SAI_PORT_ATTR_PRIORITY_FLOW_CONTROL_MODE);
}

bool PortCapabilities::isPortPfcAsymSupported() const
{
auto supported = portCapabilities.pfcMode.attrCap.set_implemented;
supported = supported && portCapabilities.pfc.attrCap.set_implemented;
supported = supported && portCapabilities.pfcTx.attrCap.set_implemented;
supported = supported && portCapabilities.pfcRx.attrCap.set_implemented;

return supported;
}

sai_status_t PortCapabilities::queryAttrCapabilitiesSai(sai_attr_capability_t &attrCap, sai_object_type_t objType, sai_attr_id_t attrId) const
{
return sai_query_attribute_capability(gSwitchId, objType, attrId, &attrCap);
}

template<typename T>
void PortCapabilities::queryPortAttrCapabilities(T &obj, sai_port_attr_t attrId)
{
SWSS_LOG_ENTER();

auto status = queryAttrCapabilitiesSai(
obj.attrCap, SAI_OBJECT_TYPE_PORT, attrId
);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR(
"Failed to get attribute(%s) capabilities",
toStr(SAI_OBJECT_TYPE_PORT, attrId).c_str()
);
return;
}

if (!obj.attrCap.set_implemented)
{
SWSS_LOG_WARN(
"Attribute(%s) SET is not implemented in SAI",
toStr(SAI_OBJECT_TYPE_PORT, attrId).c_str()
);
}
}
41 changes: 41 additions & 0 deletions orchagent/port/portcap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

extern "C" {
#include <saiobject.h>
#include <saitypes.h>
#include <saiport.h>
}

class PortCapabilities final
{
public:
PortCapabilities();
~PortCapabilities() = default;

bool isPortPfcAsymSupported() const;

private:
sai_status_t queryAttrCapabilitiesSai(sai_attr_capability_t &attrCap, sai_object_type_t objType, sai_attr_id_t attrId) const;

template<typename T>
void queryPortAttrCapabilities(T &obj, sai_port_attr_t attrId);

// Port SAI capabilities
struct {
struct {
sai_attr_capability_t attrCap = { false, false, false };
} pfcRx; // SAI_PORT_ATTR_PRIORITY_FLOW_CONTROL_RX

struct {
sai_attr_capability_t attrCap = { false, false, false };
} pfcTx; // SAI_PORT_ATTR_PRIORITY_FLOW_CONTROL_TX

struct {
sai_attr_capability_t attrCap = { false, false, false };
} pfc; // SAI_PORT_ATTR_PRIORITY_FLOW_CONTROL

struct {
sai_attr_capability_t attrCap = { false, false, false };
} pfcMode; // SAI_PORT_ATTR_PRIORITY_FLOW_CONTROL_MODE
} portCapabilities;
};
38 changes: 24 additions & 14 deletions orchagent/portsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4016,24 +4016,34 @@ void PortsOrch::doPortTask(Consumer &consumer)
{
if (!p.m_pfc_asym_cfg || p.m_pfc_asym != pCfg.pfc_asym.value)
{
if (!setPortPfcAsym(p, pCfg.pfc_asym.value))
if (m_portCap.isPortPfcAsymSupported())
{
SWSS_LOG_ERROR(
"Failed to set port %s asymmetric PFC to %s",
if (!setPortPfcAsym(p, pCfg.pfc_asym.value))
{
SWSS_LOG_ERROR(
"Failed to set port %s asymmetric PFC to %s",
p.m_alias.c_str(), m_portHlpr.getPfcAsymStr(pCfg).c_str()
);
it++;
continue;
}

p.m_pfc_asym = pCfg.pfc_asym.value;
p.m_pfc_asym_cfg = true;
m_portList[p.m_alias] = p;

SWSS_LOG_NOTICE(
"Set port %s asymmetric PFC to %s",
p.m_alias.c_str(), m_portHlpr.getPfcAsymStr(pCfg).c_str()
);
it++;
continue;
}

p.m_pfc_asym = pCfg.pfc_asym.value;
p.m_pfc_asym_cfg = true;
m_portList[p.m_alias] = p;

SWSS_LOG_NOTICE(
"Set port %s asymmetric PFC to %s",
p.m_alias.c_str(), m_portHlpr.getPfcAsymStr(pCfg).c_str()
);
else
{
SWSS_LOG_WARN(
"Port %s asymmetric PFC configuration is not supported: skipping ...",
p.m_alias.c_str()
);
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions orchagent/portsorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "flexcounterorch.h"
#include "events.h"

#include "port/portcap.h"
#include "port/porthlpr.h"
#include "port/portschema.h"

Expand Down Expand Up @@ -508,6 +509,9 @@ class PortsOrch : public Orch, public Subject
// Port config aggregator
std::unordered_map<std::string, std::unordered_map<std::string, std::string>> m_portConfigMap;

// Port OA capabilities
PortCapabilities m_portCap;

// Port OA helper
PortHelper m_portHlpr;
};
Expand Down
1 change: 1 addition & 0 deletions tests/mock_tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ tests_SOURCES = aclorch_ut.cpp \
$(top_srcdir)/orchagent/cbf/nhgmaporch.cpp \
$(top_srcdir)/orchagent/neighorch.cpp \
$(top_srcdir)/orchagent/intfsorch.cpp \
$(top_srcdir)/orchagent/port/portcap.cpp \
$(top_srcdir)/orchagent/port/porthlpr.cpp \
$(top_srcdir)/orchagent/portsorch.cpp \
$(top_srcdir)/orchagent/fabricportsorch.cpp \
Expand Down