@@ -1952,6 +1952,9 @@ void PortsOrch::deInitPort(string alias, sai_object_id_t port_id)
19521952 /* remove port name map from counter table */
19531953 m_counter_db->hdel (COUNTERS_PORT_NAME_MAP, alias);
19541954
1955+ /* Remove the associated port serdes attribute */
1956+ removePortSerdesAttribute (p.m_port_id );
1957+
19551958 m_portList[alias].m_init = false ;
19561959 SWSS_LOG_NOTICE (" De-Initialized port %s" , alias.c_str ());
19571960}
@@ -2109,9 +2112,9 @@ void PortsOrch::doPortTask(Consumer &consumer)
21092112 if (op == SET_COMMAND)
21102113 {
21112114 set<int > lane_set;
2112- vector<uint32_t > pre_emphasis ;
2113- vector<uint32_t > idriver ;
2114- vector<uint32_t > ipredriver ;
2115+ vector<uint32_t > attr_val ;
2116+ map< sai_port_serdes_attr_t , vector<uint32_t >> serdes_attr ;
2117+ typedef pair< sai_port_serdes_attr_t , vector<uint32_t >> serdes_attr_pair ;
21152118 string admin_status;
21162119 string fec_mode;
21172120 string pfc_asym;
@@ -2123,14 +2126,14 @@ void PortsOrch::doPortTask(Consumer &consumer)
21232126
21242127 for (auto i : kfvFieldsValues (t))
21252128 {
2129+ attr_val.clear ();
21262130 /* Set interface index */
21272131 if (fvField (i) == " index" )
21282132 {
21292133 index = (int )stoul (fvValue (i));
21302134 }
2131-
21322135 /* Get lane information of a physical port and initialize the port */
2133- if (fvField (i) == " lanes" )
2136+ else if (fvField (i) == " lanes" )
21342137 {
21352138 string lane_str;
21362139 istringstream iss (fvValue (i));
@@ -2140,65 +2143,107 @@ void PortsOrch::doPortTask(Consumer &consumer)
21402143 int lane = stoi (lane_str);
21412144 lane_set.insert (lane);
21422145 }
2143-
21442146 }
2145-
21462147 /* Set port admin status */
2147- if (fvField (i) == " admin_status" )
2148+ else if (fvField (i) == " admin_status" )
21482149 {
21492150 admin_status = fvValue (i);
21502151 }
2151-
21522152 /* Set port MTU */
2153- if (fvField (i) == " mtu" )
2153+ else if (fvField (i) == " mtu" )
21542154 {
21552155 mtu = (uint32_t )stoul (fvValue (i));
21562156 }
2157-
21582157 /* Set port speed */
2159- if (fvField (i) == " speed" )
2158+ else if (fvField (i) == " speed" )
21602159 {
21612160 speed = (uint32_t )stoul (fvValue (i));
21622161 }
2163-
21642162 /* Set port fec */
2165- if (fvField (i) == " fec" )
2163+ else if (fvField (i) == " fec" )
21662164 {
21672165 fec_mode = fvValue (i);
21682166 }
2169-
21702167 /* Get port fdb learn mode*/
2171- if (fvField (i) == " learn_mode" )
2168+ else if (fvField (i) == " learn_mode" )
21722169 {
21732170 learn_mode = fvValue (i);
21742171 }
2175-
21762172 /* Set port asymmetric PFC */
2177- if (fvField (i) == " pfc_asym" )
2173+ else if (fvField (i) == " pfc_asym" )
2174+ {
21782175 pfc_asym = fvValue (i);
2179-
2176+ }
21802177 /* Set autoneg and ignore the port speed setting */
2181- if (fvField (i) == " autoneg" )
2178+ else if (fvField (i) == " autoneg" )
21822179 {
21832180 an = (int )stoul (fvValue (i));
21842181 }
2185-
21862182 /* Set port serdes Pre-emphasis */
2187- if (fvField (i) == " preemphasis" )
2183+ else if (fvField (i) == " preemphasis" )
21882184 {
2189- getPortSerdesVal (fvValue (i), pre_emphasis);
2185+ getPortSerdesVal (fvValue (i), attr_val);
2186+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_PREEMPHASIS, attr_val));
21902187 }
2191-
21922188 /* Set port serdes idriver */
2193- if (fvField (i) == " idriver" )
2189+ else if (fvField (i) == " idriver" )
21942190 {
2195- getPortSerdesVal (fvValue (i), idriver);
2191+ getPortSerdesVal (fvValue (i), attr_val);
2192+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_IDRIVER, attr_val));
21962193 }
2197-
21982194 /* Set port serdes ipredriver */
2199- if (fvField (i) == " ipredriver" )
2195+ else if (fvField (i) == " ipredriver" )
2196+ {
2197+ getPortSerdesVal (fvValue (i), attr_val);
2198+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_IPREDRIVER, attr_val));
2199+ }
2200+ /* Set port serdes pre1 */
2201+ else if (fvField (i) == " pre1" )
2202+ {
2203+ getPortSerdesVal (fvValue (i), attr_val);
2204+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_TX_FIR_PRE1, attr_val));
2205+ }
2206+ /* Set port serdes pre2 */
2207+ else if (fvField (i) == " pre2" )
2208+ {
2209+ getPortSerdesVal (fvValue (i), attr_val);
2210+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_TX_FIR_PRE2, attr_val));
2211+ }
2212+ /* Set port serdes pre3 */
2213+ else if (fvField (i) == " pre3" )
22002214 {
2201- getPortSerdesVal (fvValue (i), ipredriver);
2215+ getPortSerdesVal (fvValue (i), attr_val);
2216+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_TX_FIR_PRE3, attr_val));
2217+ }
2218+ /* Set port serdes main */
2219+ else if (fvField (i) == " main" )
2220+ {
2221+ getPortSerdesVal (fvValue (i), attr_val);
2222+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_TX_FIR_MAIN, attr_val));
2223+ }
2224+ /* Set port serdes post1 */
2225+ else if (fvField (i) == " post1" )
2226+ {
2227+ getPortSerdesVal (fvValue (i), attr_val);
2228+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_TX_FIR_POST1, attr_val));
2229+ }
2230+ /* Set port serdes post2 */
2231+ else if (fvField (i) == " post2" )
2232+ {
2233+ getPortSerdesVal (fvValue (i), attr_val);
2234+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_TX_FIR_POST2, attr_val));
2235+ }
2236+ /* Set port serdes post3 */
2237+ else if (fvField (i) == " post3" )
2238+ {
2239+ getPortSerdesVal (fvValue (i), attr_val);
2240+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_TX_FIR_POST3, attr_val));
2241+ }
2242+ /* Set port serdes attn */
2243+ else if (fvField (i) == " attn" )
2244+ {
2245+ getPortSerdesVal (fvValue (i), attr_val);
2246+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_TX_FIR_ATTN, attr_val));
22022247 }
22032248 }
22042249
@@ -2519,9 +2564,9 @@ void PortsOrch::doPortTask(Consumer &consumer)
25192564 }
25202565 }
25212566
2522- if (pre_emphasis .size () != 0 )
2567+ if (serdes_attr .size () != 0 )
25232568 {
2524- if (setPortSerdesAttribute (p.m_port_id , SAI_PORT_ATTR_SERDES_PREEMPHASIS, pre_emphasis ))
2569+ if (setPortSerdesAttribute (p.m_port_id , serdes_attr ))
25252570 {
25262571 SWSS_LOG_NOTICE (" Set port %s preemphasis is success" , alias.c_str ());
25272572 }
@@ -2534,36 +2579,6 @@ void PortsOrch::doPortTask(Consumer &consumer)
25342579
25352580 }
25362581
2537- if (idriver.size () != 0 )
2538- {
2539- if (setPortSerdesAttribute (p.m_port_id , SAI_PORT_ATTR_SERDES_IDRIVER, idriver))
2540- {
2541- SWSS_LOG_NOTICE (" Set port %s idriver is success" , alias.c_str ());
2542- }
2543- else
2544- {
2545- SWSS_LOG_ERROR (" Failed to set port %s idriver" , alias.c_str ());
2546- it++;
2547- continue ;
2548- }
2549-
2550- }
2551-
2552- if (ipredriver.size () != 0 )
2553- {
2554- if (setPortSerdesAttribute (p.m_port_id , SAI_PORT_ATTR_SERDES_IPREDRIVER, ipredriver))
2555- {
2556- SWSS_LOG_NOTICE (" Set port %s ipredriver is success" , alias.c_str ());
2557- }
2558- else
2559- {
2560- SWSS_LOG_ERROR (" Failed to set port %s ipredriver" , alias.c_str ());
2561- it++;
2562- continue ;
2563- }
2564-
2565- }
2566-
25672582 /* Last step set port admin status */
25682583 if (!admin_status.empty () && (p.m_admin_state_up != (admin_status == " up" )))
25692584 {
@@ -4394,29 +4409,95 @@ bool PortsOrch::removeAclTableGroup(const Port &p)
43944409 return true ;
43954410}
43964411
4397- bool PortsOrch::setPortSerdesAttribute (sai_object_id_t port_id, sai_attr_id_t attr_id,
4398- vector<uint32_t > &serdes_val )
4412+ bool PortsOrch::setPortSerdesAttribute (sai_object_id_t port_id,
4413+ map< sai_port_serdes_attr_t , vector<uint32_t >> &serdes_attr )
43994414{
44004415 SWSS_LOG_ENTER ();
44014416
4402- sai_attribute_t attr;
4417+ vector<sai_attribute_t > attr_list;
4418+ sai_attribute_t port_attr;
4419+ sai_attribute_t port_serdes_attr;
4420+ sai_status_t status;
4421+ sai_object_id_t port_serdes_id = SAI_NULL_OBJECT_ID;
4422+
4423+ port_attr.id = SAI_PORT_ATTR_PORT_SERDES_ID;
4424+ status = sai_port_api->get_port_attribute (port_id, 1 , &port_attr);
4425+ if (status != SAI_STATUS_SUCCESS)
4426+ {
4427+ SWSS_LOG_ERROR (" Failed to get port attr serdes id %d to port pid:0x%" PRIx64,
4428+ port_attr.id , port_id);
4429+ return false ;
4430+ }
4431+
4432+ if (port_attr.value .oid != SAI_NULL_OBJECT_ID)
4433+ {
4434+ status = sai_port_api->remove_port_serdes (port_attr.value .oid );
4435+ if (status != SAI_STATUS_SUCCESS)
4436+ {
4437+ SWSS_LOG_ERROR (" Failed to remove existing port serdes attr 0x%" PRIx64 " port 0x%" PRIx64,
4438+ port_attr.value .oid , port_id);
4439+ return false ;
4440+ }
4441+ }
44034442
4404- memset (&attr, 0 , sizeof (attr));
4405- attr.id = attr_id;
44064443
4407- attr.value .u32list .count = (uint32_t )serdes_val.size ();
4408- attr.value .u32list .list = serdes_val.data ();
4444+ port_serdes_attr.id = SAI_PORT_SERDES_ATTR_PORT_ID;
4445+ port_serdes_attr.value .oid = port_id;
4446+ attr_list.emplace_back (port_serdes_attr);
4447+ SWSS_LOG_INFO (" Creating serdes for port 0x%" PRIx64, port_id);
4448+
4449+ for (auto it = serdes_attr.begin (); it != serdes_attr.end (); it++)
4450+ {
4451+ port_serdes_attr.id = it->first ;
4452+ port_serdes_attr.value .u32list .count = (uint32_t )it->second .size ();
4453+ port_serdes_attr.value .u32list .list = it->second .data ();
4454+ attr_list.emplace_back (port_serdes_attr);
4455+ }
4456+ status = sai_port_api->create_port_serdes (&port_serdes_id, gSwitchId ,
4457+ static_cast <uint32_t >(serdes_attr.size ()+1 ),
4458+ attr_list.data ());
44094459
4410- sai_status_t status = sai_port_api->set_port_attribute (port_id, &attr);
44114460 if (status != SAI_STATUS_SUCCESS)
44124461 {
4413- SWSS_LOG_ERROR (" Failed to set serdes attribute %d to port pid: %" PRIx64,
4414- attr_id, port_id);
4462+ SWSS_LOG_ERROR (" Failed to create port serdes for port 0x %" PRIx64,
4463+ port_id);
44154464 return false ;
44164465 }
4466+ SWSS_LOG_NOTICE (" Created port serdes object 0x%" PRIx64 " for port 0x%" PRIx64, port_serdes_id, port_id);
44174467 return true ;
44184468}
44194469
4470+ void PortsOrch::removePortSerdesAttribute (sai_object_id_t port_id)
4471+ {
4472+ SWSS_LOG_ENTER ();
4473+
4474+ sai_attribute_t port_attr;
4475+ sai_status_t status;
4476+ sai_object_id_t port_serdes_id = SAI_NULL_OBJECT_ID;
4477+
4478+ port_attr.id = SAI_PORT_ATTR_PORT_SERDES_ID;
4479+ status = sai_port_api->get_port_attribute (port_id, 1 , &port_attr);
4480+
4481+ if (status != SAI_STATUS_SUCCESS)
4482+ {
4483+ SWSS_LOG_DEBUG (" Failed to get port attr serdes id %d to port pid:0x%" PRIx64,
4484+ port_attr.id , port_id);
4485+ return ;
4486+ }
4487+
4488+ if (port_attr.value .oid != SAI_NULL_OBJECT_ID)
4489+ {
4490+ status = sai_port_api->remove_port_serdes (port_attr.value .oid );
4491+ if (status != SAI_STATUS_SUCCESS)
4492+ {
4493+ SWSS_LOG_ERROR (" Failed to remove existing port serdes attr 0x%" PRIx64 " port 0x%" PRIx64,
4494+ port_attr.value .oid , port_id);
4495+ return ;
4496+ }
4497+ }
4498+ SWSS_LOG_NOTICE (" Removed port serdes object 0x%" PRIx64 " for port 0x%" PRIx64, port_serdes_id, port_id);
4499+ }
4500+
44204501void PortsOrch::getPortSerdesVal (const std::string& val_str,
44214502 std::vector<uint32_t > &lane_values)
44224503{
0 commit comments