@@ -122,6 +122,24 @@ static const char *const bnxt_dev_args[] = {
122122 NULL
123123};
124124
125+ #define BNXT_SPEEDS_SUPP_SPEED_LANES (RTE_ETH_LINK_SPEED_10G | \
126+ RTE_ETH_LINK_SPEED_25G | \
127+ RTE_ETH_LINK_SPEED_40G | \
128+ RTE_ETH_LINK_SPEED_50G | \
129+ RTE_ETH_LINK_SPEED_100G | \
130+ RTE_ETH_LINK_SPEED_200G | \
131+ RTE_ETH_LINK_SPEED_400G)
132+
133+ static const struct rte_eth_speed_lanes_capa speed_lanes_capa_tbl [] = {
134+ { RTE_ETH_SPEED_NUM_10G , RTE_BIT32 (1 ) },
135+ { RTE_ETH_SPEED_NUM_25G , RTE_BIT32 (1 ) },
136+ { RTE_ETH_SPEED_NUM_40G , RTE_BIT32 (4 ) },
137+ { RTE_ETH_SPEED_NUM_50G , RTE_BIT32 (1 ) | RTE_BIT32 (2 ) },
138+ { RTE_ETH_SPEED_NUM_100G , RTE_BIT32 (1 ) | RTE_BIT32 (2 ) | RTE_BIT32 (4 ) },
139+ { RTE_ETH_SPEED_NUM_200G , RTE_BIT32 (2 ) | RTE_BIT32 (4 ) },
140+ { RTE_ETH_SPEED_NUM_400G , RTE_BIT32 (4 ) | RTE_BIT32 (8 ) },
141+ };
142+
125143/*
126144 * cqe-mode = an non-negative 8-bit number
127145 */
@@ -696,31 +714,58 @@ static inline bool bnxt_force_link_config(struct bnxt *bp)
696714 }
697715}
698716
699- static int bnxt_update_phy_setting (struct bnxt * bp )
717+ static int bnxt_validate_speed_lanes_change (struct bnxt * bp )
700718{
701719 struct rte_eth_conf * dev_conf = & bp -> eth_dev -> data -> dev_conf ;
702720 struct rte_eth_link * link = & bp -> eth_dev -> data -> dev_link ;
703- struct rte_eth_link new ;
704721 uint32_t curr_speed_bit ;
705722 int rc ;
706723
724+ /* Check if speed x lanes combo is supported */
725+ if (dev_conf -> link_speeds ) {
726+ rc = bnxt_parse_eth_link_speed_v2 (bp );
727+ if (rc == 0 )
728+ return - EINVAL ;
729+ }
730+
731+ /* convert to speedbit flag */
732+ curr_speed_bit = rte_eth_speed_bitflag ((uint32_t )link -> link_speed , 1 );
733+
734+ /* check if speed and lanes have changed */
735+ if (dev_conf -> link_speeds != curr_speed_bit ||
736+ bp -> link_info -> active_lanes != bp -> link_info -> pmd_speed_lanes )
737+ return 1 ;
738+
739+ return 0 ;
740+ }
741+
742+ static int bnxt_update_phy_setting (struct bnxt * bp )
743+ {
744+ struct rte_eth_link new ;
745+ int rc , rc1 = 0 ;
746+
707747 rc = bnxt_get_hwrm_link_config (bp , & new );
708748 if (rc ) {
709749 PMD_DRV_LOG (ERR , "Failed to get link settings\n" );
710750 return rc ;
711751 }
712752
713- /* convert to speedbit flag */
714- curr_speed_bit = rte_eth_speed_bitflag ((uint32_t )link -> link_speed , 1 );
753+ /* Validate speeds2 requirements */
754+ if (BNXT_LINK_SPEEDS_V2 (bp )) {
755+ rc1 = bnxt_validate_speed_lanes_change (bp );
756+ if (rc1 == - EINVAL ) {
757+ PMD_DRV_LOG (ERR , "Failed to set correct lanes\n" );
758+ return rc1 ;
759+ }
760+ }
715761
716762 /*
717763 * Device is not obliged link down in certain scenarios, even
718764 * when forced. When FW does not allow any user other than BMC
719765 * to shutdown the port, bnxt_get_hwrm_link_config() call always
720766 * returns link up. Force phy update always in that case.
721767 */
722- if (!new .link_status || bnxt_force_link_config (bp ) ||
723- (BNXT_LINK_SPEEDS_V2 (bp ) && dev_conf -> link_speeds != curr_speed_bit )) {
768+ if (!new .link_status || bnxt_force_link_config (bp ) || rc1 == 1 ) {
724769 rc = bnxt_set_hwrm_link_config (bp , true);
725770 if (rc ) {
726771 PMD_DRV_LOG (ERR , "Failed to update PHY settings\n" );
@@ -1331,16 +1376,17 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
13311376void bnxt_print_link_info (struct rte_eth_dev * eth_dev )
13321377{
13331378 struct rte_eth_link * link = & eth_dev -> data -> dev_link ;
1379+ struct bnxt * bp = eth_dev -> data -> dev_private ;
13341380
13351381 if (link -> link_status )
1336- PMD_DRV_LOG (DEBUG , "Port %d Link Up - speed %u Mbps - %s\n" ,
1337- eth_dev -> data -> port_id ,
1338- (uint32_t )link -> link_speed ,
1339- (link -> link_duplex == RTE_ETH_LINK_FULL_DUPLEX ) ?
1340- ("full-duplex" ) : ("half-duplex\n" ));
1382+ PMD_DRV_LOG (DEBUG , "Port %d Link Up - speed %u Mbps - %s Lanes - %d\n" ,
1383+ eth_dev -> data -> port_id ,
1384+ (uint32_t )link -> link_speed ,
1385+ (link -> link_duplex == RTE_ETH_LINK_FULL_DUPLEX ) ?
1386+ ("full-duplex" ) : ("half-duplex\n" ),
1387+ (uint16_t )bp -> link_info -> active_lanes );
13411388 else
1342- PMD_DRV_LOG (INFO , "Port %d Link Down\n" ,
1343- eth_dev -> data -> port_id );
1389+ PMD_DRV_LOG (INFO , "Port %d Link Down\n" , eth_dev -> data -> port_id );
13441390}
13451391
13461392/*
@@ -4191,6 +4237,105 @@ static int bnxt_get_module_eeprom(struct rte_eth_dev *dev,
41914237 return length ? - EINVAL : 0 ;
41924238}
41934239
4240+ #if (RTE_VERSION_NUM (22 , 11 , 0 , 0 ) <= RTE_VERSION )
4241+ static int bnxt_speed_lanes_set (struct rte_eth_dev * dev , uint32_t speed_lanes )
4242+ {
4243+ struct bnxt * bp = dev -> data -> dev_private ;
4244+
4245+ if (!BNXT_LINK_SPEEDS_V2 (bp ))
4246+ return - ENOTSUP ;
4247+
4248+ bp -> link_info -> pmd_speed_lanes = speed_lanes ;
4249+
4250+ return 0 ;
4251+ }
4252+
4253+ static uint32_t
4254+ bnxt_get_speed_lanes_capa (struct rte_eth_speed_lanes_capa * speed_lanes_capa ,
4255+ uint32_t speed_capa )
4256+ {
4257+ uint32_t speed_bit ;
4258+ uint32_t num = 0 ;
4259+ uint32_t i ;
4260+
4261+ for (i = 0 ; i < RTE_DIM (speed_lanes_capa_tbl ); i ++ ) {
4262+ speed_bit =
4263+ rte_eth_speed_bitflag (speed_lanes_capa_tbl [i ].speed ,
4264+ RTE_ETH_LINK_FULL_DUPLEX );
4265+ if ((speed_capa & speed_bit ) == 0 )
4266+ continue ;
4267+
4268+ speed_lanes_capa [num ].speed = speed_lanes_capa_tbl [i ].speed ;
4269+ speed_lanes_capa [num ].capa = speed_lanes_capa_tbl [i ].capa ;
4270+ num ++ ;
4271+ }
4272+
4273+ return num ;
4274+ }
4275+
4276+ static int bnxt_speed_lanes_get_capa (struct rte_eth_dev * dev ,
4277+ struct rte_eth_speed_lanes_capa * speed_lanes_capa ,
4278+ unsigned int num )
4279+ {
4280+ struct rte_eth_link * link = & dev -> data -> dev_link ;
4281+ struct bnxt * bp = dev -> data -> dev_private ;
4282+ unsigned int speed_num ;
4283+ uint32_t speed_capa ;
4284+ int rc ;
4285+
4286+ rc = is_bnxt_in_error (bp );
4287+ if (rc )
4288+ return rc ;
4289+
4290+ if (!BNXT_LINK_SPEEDS_V2 (bp ))
4291+ return - ENOTSUP ;
4292+
4293+ /* speed_num counts number of speed capabilities.
4294+ * When link is down, show the user choice all combinations of speeds x lanes
4295+ */
4296+ if (link -> link_status ) {
4297+ speed_capa = bnxt_get_speed_capabilities_v2 (bp );
4298+ speed_num = rte_popcount32 (speed_capa & BNXT_SPEEDS_SUPP_SPEED_LANES );
4299+ } else {
4300+ speed_capa = BNXT_SPEEDS_SUPP_SPEED_LANES ;
4301+ speed_num = rte_popcount32 (BNXT_SPEEDS_SUPP_SPEED_LANES );
4302+ }
4303+ if (speed_num == 0 )
4304+ return - ENOTSUP ;
4305+
4306+ if (speed_lanes_capa == NULL )
4307+ return speed_num ;
4308+
4309+ if (num < speed_num )
4310+ return - EINVAL ;
4311+
4312+ return bnxt_get_speed_lanes_capa (speed_lanes_capa , speed_capa );
4313+ }
4314+
4315+ static int bnxt_speed_lanes_get (struct rte_eth_dev * dev , uint32_t * lanes )
4316+ {
4317+ struct rte_eth_link * link = & dev -> data -> dev_link ;
4318+ struct bnxt * bp = dev -> data -> dev_private ;
4319+ int rc ;
4320+
4321+ rc = is_bnxt_in_error (bp );
4322+ if (rc )
4323+ return rc ;
4324+
4325+ if (!BNXT_LINK_SPEEDS_V2 (bp ))
4326+ return - ENOTSUP ;
4327+
4328+ if (!link -> link_status )
4329+ return - EINVAL ;
4330+
4331+ /* user app expects lanes 1 for zero */
4332+ * lanes = (bp -> link_info -> active_lanes ) ?
4333+ bp -> link_info -> active_lanes : 1 ;
4334+ return 0 ;
4335+ }
4336+
4337+ #endif
4338+
41944339/*
41954340 * Initialization
41964341 */
@@ -4262,6 +4407,11 @@ static const struct eth_dev_ops bnxt_dev_ops = {
42624407 .timesync_read_rx_timestamp = bnxt_timesync_read_rx_timestamp ,
42634408 .timesync_read_tx_timestamp = bnxt_timesync_read_tx_timestamp ,
42644409 .mtr_ops_get = bnxt_flow_meter_ops_get ,
4410+ #if (RTE_VERSION_NUM (22 , 11 , 0 , 0 ) <= RTE_VERSION )
4411+ .speed_lanes_get = bnxt_speed_lanes_get ,
4412+ .speed_lanes_set = bnxt_speed_lanes_set ,
4413+ .speed_lanes_get_capa = bnxt_speed_lanes_get_capa ,
4414+ #endif
42654415};
42664416
42674417static uint32_t bnxt_map_reset_regs (struct bnxt * bp , uint32_t reg )
0 commit comments