Skip to content

Commit 46d738c

Browse files
damodhar-aiferruhy
authored andcommitted
net/bnxt: support link speed lanes
Broadcom Thor2 NICs support link mode settings where user can configure fixed speed and associated supported number of lanes. This patch does code-refactoring to address proposed poll mode library design updates. Signed-off-by: Damodharam Ammepalli <[email protected]> Reviewed-by: Ajit Khaparde <[email protected]>
1 parent b741f55 commit 46d738c

File tree

3 files changed

+200
-19
lines changed

3 files changed

+200
-19
lines changed

drivers/net/bnxt/bnxt.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ struct bnxt_link_info {
328328
uint16_t cfg_auto_link_speeds2_mask;
329329
uint8_t active_lanes;
330330
uint8_t option_flags;
331+
uint16_t pmd_speed_lanes;
331332
};
332333

333334
#define BNXT_COS_QUEUE_COUNT 8
@@ -1219,6 +1220,7 @@ extern int bnxt_logtype_driver;
12191220
#define BNXT_LINK_SPEEDS_V2_VF(bp) (BNXT_VF((bp)) && ((bp)->link_info->option_flags))
12201221
#define BNXT_LINK_SPEEDS_V2(bp) (((bp)->link_info) && (((bp)->link_info->support_speeds_v2) || \
12211222
BNXT_LINK_SPEEDS_V2_VF((bp))))
1223+
#define BNXT_MAX_SPEED_LANES 8
12221224
extern const struct rte_flow_ops bnxt_ulp_rte_flow_ops;
12231225
int32_t bnxt_ulp_port_init(struct bnxt *bp);
12241226
void bnxt_ulp_port_deinit(struct bnxt *bp);
@@ -1244,4 +1246,5 @@ int bnxt_flow_meter_ops_get(struct rte_eth_dev *eth_dev, void *arg);
12441246
struct bnxt_vnic_info *bnxt_get_default_vnic(struct bnxt *bp);
12451247
struct tf *bnxt_get_tfp_session(struct bnxt *bp, enum bnxt_session_type type);
12461248
uint64_t bnxt_eth_rss_support(struct bnxt *bp);
1249+
uint16_t bnxt_parse_eth_link_speed_v2(struct bnxt *bp);
12471250
#endif

drivers/net/bnxt/bnxt_ethdev.c

Lines changed: 163 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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)
13311376
void 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

42674417
static uint32_t bnxt_map_reset_regs(struct bnxt *bp, uint32_t reg)

0 commit comments

Comments
 (0)