@@ -1986,6 +1986,9 @@ void PortsOrch::deInitPort(string alias, sai_object_id_t port_id)
19861986 /* remove port name map from counter table */
19871987 m_counter_db->hdel (COUNTERS_PORT_NAME_MAP, alias);
19881988
1989+ /* Remove the associated port serdes attribute */
1990+ removePortSerdesAttribute (p.m_port_id );
1991+
19891992 m_portList[alias].m_init = false ;
19901993 SWSS_LOG_NOTICE (" De-Initialized port %s" , alias.c_str ());
19911994}
@@ -2144,9 +2147,9 @@ void PortsOrch::doPortTask(Consumer &consumer)
21442147 if (op == SET_COMMAND)
21452148 {
21462149 set<int > lane_set;
2147- vector<uint32_t > pre_emphasis ;
2148- vector<uint32_t > idriver ;
2149- vector<uint32_t > ipredriver ;
2150+ vector<uint32_t > attr_val ;
2151+ map< sai_port_serdes_attr_t , vector<uint32_t >> serdes_attr ;
2152+ typedef pair< sai_port_serdes_attr_t , vector<uint32_t >> serdes_attr_pair ;
21502153 string admin_status;
21512154 string fec_mode;
21522155 string pfc_asym;
@@ -2158,14 +2161,14 @@ void PortsOrch::doPortTask(Consumer &consumer)
21582161
21592162 for (auto i : kfvFieldsValues (t))
21602163 {
2164+ attr_val.clear ();
21612165 /* Set interface index */
21622166 if (fvField (i) == " index" )
21632167 {
21642168 index = (int )stoul (fvValue (i));
21652169 }
2166-
21672170 /* Get lane information of a physical port and initialize the port */
2168- if (fvField (i) == " lanes" )
2171+ else if (fvField (i) == " lanes" )
21692172 {
21702173 string lane_str;
21712174 istringstream iss (fvValue (i));
@@ -2175,65 +2178,107 @@ void PortsOrch::doPortTask(Consumer &consumer)
21752178 int lane = stoi (lane_str);
21762179 lane_set.insert (lane);
21772180 }
2178-
21792181 }
2180-
21812182 /* Set port admin status */
2182- if (fvField (i) == " admin_status" )
2183+ else if (fvField (i) == " admin_status" )
21832184 {
21842185 admin_status = fvValue (i);
21852186 }
2186-
21872187 /* Set port MTU */
2188- if (fvField (i) == " mtu" )
2188+ else if (fvField (i) == " mtu" )
21892189 {
21902190 mtu = (uint32_t )stoul (fvValue (i));
21912191 }
2192-
21932192 /* Set port speed */
2194- if (fvField (i) == " speed" )
2193+ else if (fvField (i) == " speed" )
21952194 {
21962195 speed = (uint32_t )stoul (fvValue (i));
21972196 }
2198-
21992197 /* Set port fec */
2200- if (fvField (i) == " fec" )
2198+ else if (fvField (i) == " fec" )
22012199 {
22022200 fec_mode = fvValue (i);
22032201 }
2204-
22052202 /* Get port fdb learn mode*/
2206- if (fvField (i) == " learn_mode" )
2203+ else if (fvField (i) == " learn_mode" )
22072204 {
22082205 learn_mode = fvValue (i);
22092206 }
2210-
22112207 /* Set port asymmetric PFC */
2212- if (fvField (i) == " pfc_asym" )
2208+ else if (fvField (i) == " pfc_asym" )
2209+ {
22132210 pfc_asym = fvValue (i);
2214-
2211+ }
22152212 /* Set autoneg and ignore the port speed setting */
2216- if (fvField (i) == " autoneg" )
2213+ else if (fvField (i) == " autoneg" )
22172214 {
22182215 an = (int )stoul (fvValue (i));
22192216 }
2220-
22212217 /* Set port serdes Pre-emphasis */
2222- if (fvField (i) == " preemphasis" )
2218+ else if (fvField (i) == " preemphasis" )
22232219 {
2224- getPortSerdesVal (fvValue (i), pre_emphasis);
2220+ getPortSerdesVal (fvValue (i), attr_val);
2221+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_PREEMPHASIS, attr_val));
22252222 }
2226-
22272223 /* Set port serdes idriver */
2228- if (fvField (i) == " idriver" )
2224+ else if (fvField (i) == " idriver" )
22292225 {
2230- getPortSerdesVal (fvValue (i), idriver);
2226+ getPortSerdesVal (fvValue (i), attr_val);
2227+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_IDRIVER, attr_val));
22312228 }
2232-
22332229 /* Set port serdes ipredriver */
2234- if (fvField (i) == " ipredriver" )
2230+ else if (fvField (i) == " ipredriver" )
2231+ {
2232+ getPortSerdesVal (fvValue (i), attr_val);
2233+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_IPREDRIVER, attr_val));
2234+ }
2235+ /* Set port serdes pre1 */
2236+ else if (fvField (i) == " pre1" )
2237+ {
2238+ getPortSerdesVal (fvValue (i), attr_val);
2239+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_TX_FIR_PRE1, attr_val));
2240+ }
2241+ /* Set port serdes pre2 */
2242+ else if (fvField (i) == " pre2" )
2243+ {
2244+ getPortSerdesVal (fvValue (i), attr_val);
2245+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_TX_FIR_PRE2, attr_val));
2246+ }
2247+ /* Set port serdes pre3 */
2248+ else if (fvField (i) == " pre3" )
22352249 {
2236- getPortSerdesVal (fvValue (i), ipredriver);
2250+ getPortSerdesVal (fvValue (i), attr_val);
2251+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_TX_FIR_PRE3, attr_val));
2252+ }
2253+ /* Set port serdes main */
2254+ else if (fvField (i) == " main" )
2255+ {
2256+ getPortSerdesVal (fvValue (i), attr_val);
2257+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_TX_FIR_MAIN, attr_val));
2258+ }
2259+ /* Set port serdes post1 */
2260+ else if (fvField (i) == " post1" )
2261+ {
2262+ getPortSerdesVal (fvValue (i), attr_val);
2263+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_TX_FIR_POST1, attr_val));
2264+ }
2265+ /* Set port serdes post2 */
2266+ else if (fvField (i) == " post2" )
2267+ {
2268+ getPortSerdesVal (fvValue (i), attr_val);
2269+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_TX_FIR_POST2, attr_val));
2270+ }
2271+ /* Set port serdes post3 */
2272+ else if (fvField (i) == " post3" )
2273+ {
2274+ getPortSerdesVal (fvValue (i), attr_val);
2275+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_TX_FIR_POST3, attr_val));
2276+ }
2277+ /* Set port serdes attn */
2278+ else if (fvField (i) == " attn" )
2279+ {
2280+ getPortSerdesVal (fvValue (i), attr_val);
2281+ serdes_attr.insert (serdes_attr_pair (SAI_PORT_SERDES_ATTR_TX_FIR_ATTN, attr_val));
22372282 }
22382283 }
22392284
@@ -2554,9 +2599,9 @@ void PortsOrch::doPortTask(Consumer &consumer)
25542599 }
25552600 }
25562601
2557- if (pre_emphasis .size () != 0 )
2602+ if (serdes_attr .size () != 0 )
25582603 {
2559- if (setPortSerdesAttribute (p.m_port_id , SAI_PORT_ATTR_SERDES_PREEMPHASIS, pre_emphasis ))
2604+ if (setPortSerdesAttribute (p.m_port_id , serdes_attr ))
25602605 {
25612606 SWSS_LOG_NOTICE (" Set port %s preemphasis is success" , alias.c_str ());
25622607 }
@@ -2569,36 +2614,6 @@ void PortsOrch::doPortTask(Consumer &consumer)
25692614
25702615 }
25712616
2572- if (idriver.size () != 0 )
2573- {
2574- if (setPortSerdesAttribute (p.m_port_id , SAI_PORT_ATTR_SERDES_IDRIVER, idriver))
2575- {
2576- SWSS_LOG_NOTICE (" Set port %s idriver is success" , alias.c_str ());
2577- }
2578- else
2579- {
2580- SWSS_LOG_ERROR (" Failed to set port %s idriver" , alias.c_str ());
2581- it++;
2582- continue ;
2583- }
2584-
2585- }
2586-
2587- if (ipredriver.size () != 0 )
2588- {
2589- if (setPortSerdesAttribute (p.m_port_id , SAI_PORT_ATTR_SERDES_IPREDRIVER, ipredriver))
2590- {
2591- SWSS_LOG_NOTICE (" Set port %s ipredriver is success" , alias.c_str ());
2592- }
2593- else
2594- {
2595- SWSS_LOG_ERROR (" Failed to set port %s ipredriver" , alias.c_str ());
2596- it++;
2597- continue ;
2598- }
2599-
2600- }
2601-
26022617 /* Last step set port admin status */
26032618 if (!admin_status.empty () && (p.m_admin_state_up != (admin_status == " up" )))
26042619 {
@@ -4449,29 +4464,95 @@ bool PortsOrch::removeAclTableGroup(const Port &p)
44494464 return true ;
44504465}
44514466
4452- bool PortsOrch::setPortSerdesAttribute (sai_object_id_t port_id, sai_attr_id_t attr_id,
4453- vector<uint32_t > &serdes_val )
4467+ bool PortsOrch::setPortSerdesAttribute (sai_object_id_t port_id,
4468+ map< sai_port_serdes_attr_t , vector<uint32_t >> &serdes_attr )
44544469{
44554470 SWSS_LOG_ENTER ();
44564471
4457- sai_attribute_t attr;
4472+ vector<sai_attribute_t > attr_list;
4473+ sai_attribute_t port_attr;
4474+ sai_attribute_t port_serdes_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+ if (status != SAI_STATUS_SUCCESS)
4481+ {
4482+ SWSS_LOG_ERROR (" Failed to get port attr serdes id %d to port pid:0x%" PRIx64,
4483+ port_attr.id , port_id);
4484+ return false ;
4485+ }
4486+
4487+ if (port_attr.value .oid != SAI_NULL_OBJECT_ID)
4488+ {
4489+ status = sai_port_api->remove_port_serdes (port_attr.value .oid );
4490+ if (status != SAI_STATUS_SUCCESS)
4491+ {
4492+ SWSS_LOG_ERROR (" Failed to remove existing port serdes attr 0x%" PRIx64 " port 0x%" PRIx64,
4493+ port_attr.value .oid , port_id);
4494+ return false ;
4495+ }
4496+ }
44584497
4459- memset (&attr, 0 , sizeof (attr));
4460- attr.id = attr_id;
44614498
4462- attr.value .u32list .count = (uint32_t )serdes_val.size ();
4463- attr.value .u32list .list = serdes_val.data ();
4499+ port_serdes_attr.id = SAI_PORT_SERDES_ATTR_PORT_ID;
4500+ port_serdes_attr.value .oid = port_id;
4501+ attr_list.emplace_back (port_serdes_attr);
4502+ SWSS_LOG_INFO (" Creating serdes for port 0x%" PRIx64, port_id);
4503+
4504+ for (auto it = serdes_attr.begin (); it != serdes_attr.end (); it++)
4505+ {
4506+ port_serdes_attr.id = it->first ;
4507+ port_serdes_attr.value .u32list .count = (uint32_t )it->second .size ();
4508+ port_serdes_attr.value .u32list .list = it->second .data ();
4509+ attr_list.emplace_back (port_serdes_attr);
4510+ }
4511+ status = sai_port_api->create_port_serdes (&port_serdes_id, gSwitchId ,
4512+ static_cast <uint32_t >(serdes_attr.size ()+1 ),
4513+ attr_list.data ());
44644514
4465- sai_status_t status = sai_port_api->set_port_attribute (port_id, &attr);
44664515 if (status != SAI_STATUS_SUCCESS)
44674516 {
4468- SWSS_LOG_ERROR (" Failed to set serdes attribute %d to port pid: %" PRIx64,
4469- attr_id, port_id);
4517+ SWSS_LOG_ERROR (" Failed to create port serdes for port 0x %" PRIx64,
4518+ port_id);
44704519 return false ;
44714520 }
4521+ SWSS_LOG_NOTICE (" Created port serdes object 0x%" PRIx64 " for port 0x%" PRIx64, port_serdes_id, port_id);
44724522 return true ;
44734523}
44744524
4525+ void PortsOrch::removePortSerdesAttribute (sai_object_id_t port_id)
4526+ {
4527+ SWSS_LOG_ENTER ();
4528+
4529+ sai_attribute_t port_attr;
4530+ sai_status_t status;
4531+ sai_object_id_t port_serdes_id = SAI_NULL_OBJECT_ID;
4532+
4533+ port_attr.id = SAI_PORT_ATTR_PORT_SERDES_ID;
4534+ status = sai_port_api->get_port_attribute (port_id, 1 , &port_attr);
4535+
4536+ if (status != SAI_STATUS_SUCCESS)
4537+ {
4538+ SWSS_LOG_DEBUG (" Failed to get port attr serdes id %d to port pid:0x%" PRIx64,
4539+ port_attr.id , port_id);
4540+ return ;
4541+ }
4542+
4543+ if (port_attr.value .oid != SAI_NULL_OBJECT_ID)
4544+ {
4545+ status = sai_port_api->remove_port_serdes (port_attr.value .oid );
4546+ if (status != SAI_STATUS_SUCCESS)
4547+ {
4548+ SWSS_LOG_ERROR (" Failed to remove existing port serdes attr 0x%" PRIx64 " port 0x%" PRIx64,
4549+ port_attr.value .oid , port_id);
4550+ return ;
4551+ }
4552+ }
4553+ SWSS_LOG_NOTICE (" Removed port serdes object 0x%" PRIx64 " for port 0x%" PRIx64, port_serdes_id, port_id);
4554+ }
4555+
44754556void PortsOrch::getPortSerdesVal (const std::string& val_str,
44764557 std::vector<uint32_t > &lane_values)
44774558{
0 commit comments