@@ -61,6 +61,7 @@ extern string gMyAsicName;
61
61
#define DEFAULT_VLAN_ID 1
62
62
#define MAX_VALID_VLAN_ID 4094
63
63
64
+ #define PORT_SPEED_LIST_DEFAULT_SIZE 16
64
65
#define PORT_STATE_POLLING_SEC 5
65
66
#define PORT_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS 1000
66
67
#define PORT_BUFFER_DROP_STAT_POLLING_INTERVAL_MS 60000
@@ -1930,29 +1931,38 @@ void PortsOrch::initPortSupportedSpeeds(const std::string& alias, sai_object_id_
1930
1931
m_portStateTable.set (alias, v);
1931
1932
}
1932
1933
1934
+ void PortsOrch::initPortCapAutoNeg (Port &port)
1935
+ {
1936
+ sai_status_t status;
1937
+ sai_attribute_t attr;
1938
+
1939
+ attr.id = SAI_PORT_ATTR_SUPPORTED_AUTO_NEG_MODE;
1940
+ status = sai_port_api->get_port_attribute (port.m_port_id , 1 , &attr);
1941
+ if (status == SAI_STATUS_SUCCESS)
1942
+ {
1943
+ port.m_cap_an = attr.value .booldata ? 1 : 0 ;
1944
+ }
1945
+ else
1946
+ {
1947
+ port.m_cap_an = 0 ;
1948
+ SWSS_LOG_NOTICE (" Unable to get %s AN capability" , port.m_alias .c_str ());
1949
+ }
1950
+ }
1951
+
1933
1952
void PortsOrch::initPortCapLinkTraining (Port &port)
1934
1953
{
1935
1954
sai_status_t status;
1936
1955
sai_attribute_t attr;
1937
1956
1938
- #ifdef SAI_PORT_ATTR_SUPPORTED_LINK_TRAINING_MODE
1939
1957
attr.id = SAI_PORT_ATTR_SUPPORTED_LINK_TRAINING_MODE;
1940
- #else
1941
- /*
1942
- * Fallback to autoneg upon legacy SAI implementation
1943
- * In the case of SFP/QSFP ports, link-training is most likely available
1944
- * if autoneg is supported.
1945
- */
1946
- attr.id = SAI_PORT_ATTR_SUPPORTED_AUTO_NEG_MODE;
1947
- #endif
1948
1958
status = sai_port_api->get_port_attribute (port.m_port_id , 1 , &attr);
1949
1959
if (status == SAI_STATUS_SUCCESS)
1950
1960
{
1951
1961
port.m_cap_lt = attr.value .booldata ? 1 : 0 ;
1952
1962
}
1953
1963
else
1954
1964
{
1955
- port.m_cap_lt = 1 ; /* Default to 1 for vstest */
1965
+ port.m_cap_lt = 0 ;
1956
1966
SWSS_LOG_NOTICE (" Unable to get %s LT capability" , port.m_alias .c_str ());
1957
1967
}
1958
1968
}
@@ -2111,6 +2121,45 @@ bool PortsOrch::getPortSpeed(sai_object_id_t id, sai_uint32_t &speed)
2111
2121
return true ;
2112
2122
}
2113
2123
2124
+ bool PortsOrch::getPortAdvSpeeds (const Port& port, bool remote, std::vector<sai_uint32_t >& speed_list)
2125
+ {
2126
+ sai_object_id_t port_id = port.m_port_id ;
2127
+ sai_object_id_t line_port_id;
2128
+ sai_attribute_t attr;
2129
+ sai_status_t status;
2130
+ std::vector<sai_uint32_t > speeds (PORT_SPEED_LIST_DEFAULT_SIZE);
2131
+
2132
+ attr.id = remote ? SAI_PORT_ATTR_REMOTE_ADVERTISED_SPEED : SAI_PORT_ATTR_ADVERTISED_SPEED;
2133
+ attr.value .u32list .count = static_cast <uint32_t >(speeds.size ());
2134
+ attr.value .u32list .list = speeds.data ();
2135
+
2136
+ if (getDestPortId (port_id, LINE_PORT_TYPE, line_port_id))
2137
+ {
2138
+ status = sai_port_api->get_port_attribute (line_port_id, 1 , &attr);
2139
+ }
2140
+ else
2141
+ {
2142
+ status = sai_port_api->get_port_attribute (port_id, 1 , &attr);
2143
+ }
2144
+ if (status != SAI_STATUS_SUCCESS)
2145
+ {
2146
+ SWSS_LOG_WARN (" Unable to get advertised speed for %s" , port.m_alias .c_str ());
2147
+ return false ;
2148
+ }
2149
+ speeds.resize (attr.value .u32list .count );
2150
+ speed_list.swap (speeds);
2151
+ return true ;
2152
+ }
2153
+
2154
+ bool PortsOrch::getPortAdvSpeeds (const Port& port, bool remote, string& adv_speeds)
2155
+ {
2156
+ std::vector<sai_uint32_t > speed_list;
2157
+ bool rc = getPortAdvSpeeds (port, remote, speed_list);
2158
+
2159
+ adv_speeds = rc ? swss::join (' ,' , speed_list.begin (), speed_list.end ()) : " " ;
2160
+ return rc;
2161
+ }
2162
+
2114
2163
task_process_status PortsOrch::setPortAdvSpeeds (sai_object_id_t port_id, std::vector<sai_uint32_t >& speed_list)
2115
2164
{
2116
2165
SWSS_LOG_ENTER ();
@@ -3015,6 +3064,18 @@ void PortsOrch::doPortTask(Consumer &consumer)
3015
3064
{
3016
3065
if (!an_str.empty ())
3017
3066
{
3067
+ if (p.m_cap_an < 0 )
3068
+ {
3069
+ initPortCapAutoNeg (p);
3070
+ m_portList[alias] = p;
3071
+ }
3072
+ if (p.m_cap_an < 1 )
3073
+ {
3074
+ SWSS_LOG_ERROR (" %s: autoneg is not supported" , p.m_alias .c_str ());
3075
+ // Invalid auto negotiation mode configured, don't retry
3076
+ it = consumer.m_toSync .erase (it);
3077
+ continue ;
3078
+ }
3018
3079
if (autoneg_mode_map.find (an_str) == autoneg_mode_map.end ())
3019
3080
{
3020
3081
SWSS_LOG_ERROR (" Failed to parse autoneg value: %s" , an_str.c_str ());
@@ -3057,6 +3118,8 @@ void PortsOrch::doPortTask(Consumer &consumer)
3057
3118
SWSS_LOG_NOTICE (" Set port %s AutoNeg from %d to %d" , alias.c_str (), p.m_autoneg , an);
3058
3119
p.m_autoneg = an;
3059
3120
m_portList[alias] = p;
3121
+ m_portStateTable.hdel (p.m_alias , " rmt_adv_speeds" );
3122
+ updatePortStatePoll (p, PORT_STATE_POLL_AN, (an > 0 ));
3060
3123
}
3061
3124
}
3062
3125
@@ -5949,6 +6012,20 @@ void PortsOrch::updatePortOperStatus(Port &port, sai_port_oper_status_t status)
5949
6012
if (port.m_type == Port::PHY)
5950
6013
{
5951
6014
updateDbPortOperStatus (port, status);
6015
+ if (port.m_admin_state_up && port.m_autoneg > 0 )
6016
+ {
6017
+ if (status == SAI_PORT_OPER_STATUS_UP)
6018
+ {
6019
+ updatePortStateAutoNeg (port);
6020
+ updatePortStatePoll (port, PORT_STATE_POLL_AN, false );
6021
+ }
6022
+ else
6023
+ {
6024
+ /* Restart autoneg state polling upon link down event */
6025
+ m_portStateTable.hdel (port.m_alias , " rmt_adv_speeds" );
6026
+ updatePortStatePoll (port, PORT_STATE_POLL_AN, true );
6027
+ }
6028
+ }
5952
6029
if (port.m_admin_state_up && port.m_link_training > 0 )
5953
6030
{
5954
6031
updatePortStateLinkTraining (port);
@@ -7147,6 +7224,28 @@ bool PortsOrch::decrFdbCount(const std::string& alias, int count)
7147
7224
return true ;
7148
7225
}
7149
7226
7227
+ void PortsOrch::updatePortStateAutoNeg (const Port &port)
7228
+ {
7229
+ SWSS_LOG_ENTER ();
7230
+
7231
+ if (port.m_type != Port::Type::PHY)
7232
+ {
7233
+ return ;
7234
+ }
7235
+
7236
+ string adv_speeds;
7237
+
7238
+ if (getPortAdvSpeeds (port, true , adv_speeds))
7239
+ {
7240
+ m_portStateTable.hset (port.m_alias , " rmt_adv_speeds" , adv_speeds);
7241
+ }
7242
+ else
7243
+ {
7244
+ m_portStateTable.hset (port.m_alias , " rmt_adv_speeds" , " N/A" );
7245
+ updatePortStatePoll (port, PORT_STATE_POLL_AN, false );
7246
+ }
7247
+ }
7248
+
7150
7249
void PortsOrch::updatePortStateLinkTraining (const Port &port)
7151
7250
{
7152
7251
SWSS_LOG_ENTER ();
@@ -7221,6 +7320,10 @@ void PortsOrch::doTask(swss::SelectableTimer &timer)
7221
7320
++it;
7222
7321
continue ;
7223
7322
}
7323
+ if (it->second & PORT_STATE_POLL_AN)
7324
+ {
7325
+ updatePortStateAutoNeg (port);
7326
+ }
7224
7327
if (it->second & PORT_STATE_POLL_LT)
7225
7328
{
7226
7329
updatePortStateLinkTraining (port);
0 commit comments