Skip to content

Commit

Permalink
net/bnxt: support link speed lanes
Browse files Browse the repository at this point in the history
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 <damodharam.ammepalli@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
  • Loading branch information
Damodharam Ammepalli authored and ferruhy committed Sep 27, 2024
1 parent b741f55 commit 46d738c
Show file tree
Hide file tree
Showing 3 changed files with 200 additions and 19 deletions.
3 changes: 3 additions & 0 deletions drivers/net/bnxt/bnxt.h
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ struct bnxt_link_info {
uint16_t cfg_auto_link_speeds2_mask;
uint8_t active_lanes;
uint8_t option_flags;
uint16_t pmd_speed_lanes;
};

#define BNXT_COS_QUEUE_COUNT 8
Expand Down Expand Up @@ -1219,6 +1220,7 @@ extern int bnxt_logtype_driver;
#define BNXT_LINK_SPEEDS_V2_VF(bp) (BNXT_VF((bp)) && ((bp)->link_info->option_flags))
#define BNXT_LINK_SPEEDS_V2(bp) (((bp)->link_info) && (((bp)->link_info->support_speeds_v2) || \
BNXT_LINK_SPEEDS_V2_VF((bp))))
#define BNXT_MAX_SPEED_LANES 8
extern const struct rte_flow_ops bnxt_ulp_rte_flow_ops;
int32_t bnxt_ulp_port_init(struct bnxt *bp);
void bnxt_ulp_port_deinit(struct bnxt *bp);
Expand All @@ -1244,4 +1246,5 @@ int bnxt_flow_meter_ops_get(struct rte_eth_dev *eth_dev, void *arg);
struct bnxt_vnic_info *bnxt_get_default_vnic(struct bnxt *bp);
struct tf *bnxt_get_tfp_session(struct bnxt *bp, enum bnxt_session_type type);
uint64_t bnxt_eth_rss_support(struct bnxt *bp);
uint16_t bnxt_parse_eth_link_speed_v2(struct bnxt *bp);
#endif
176 changes: 163 additions & 13 deletions drivers/net/bnxt/bnxt_ethdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,24 @@ static const char *const bnxt_dev_args[] = {
NULL
};

#define BNXT_SPEEDS_SUPP_SPEED_LANES (RTE_ETH_LINK_SPEED_10G | \
RTE_ETH_LINK_SPEED_25G | \
RTE_ETH_LINK_SPEED_40G | \
RTE_ETH_LINK_SPEED_50G | \
RTE_ETH_LINK_SPEED_100G | \
RTE_ETH_LINK_SPEED_200G | \
RTE_ETH_LINK_SPEED_400G)

static const struct rte_eth_speed_lanes_capa speed_lanes_capa_tbl[] = {
{ RTE_ETH_SPEED_NUM_10G, RTE_BIT32(1) },
{ RTE_ETH_SPEED_NUM_25G, RTE_BIT32(1) },
{ RTE_ETH_SPEED_NUM_40G, RTE_BIT32(4) },
{ RTE_ETH_SPEED_NUM_50G, RTE_BIT32(1) | RTE_BIT32(2) },
{ RTE_ETH_SPEED_NUM_100G, RTE_BIT32(1) | RTE_BIT32(2) | RTE_BIT32(4) },
{ RTE_ETH_SPEED_NUM_200G, RTE_BIT32(2) | RTE_BIT32(4) },
{ RTE_ETH_SPEED_NUM_400G, RTE_BIT32(4) | RTE_BIT32(8) },
};

/*
* cqe-mode = an non-negative 8-bit number
*/
Expand Down Expand Up @@ -696,31 +714,58 @@ static inline bool bnxt_force_link_config(struct bnxt *bp)
}
}

static int bnxt_update_phy_setting(struct bnxt *bp)
static int bnxt_validate_speed_lanes_change(struct bnxt *bp)
{
struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
struct rte_eth_link *link = &bp->eth_dev->data->dev_link;
struct rte_eth_link new;
uint32_t curr_speed_bit;
int rc;

/* Check if speed x lanes combo is supported */
if (dev_conf->link_speeds) {
rc = bnxt_parse_eth_link_speed_v2(bp);
if (rc == 0)
return -EINVAL;
}

/* convert to speedbit flag */
curr_speed_bit = rte_eth_speed_bitflag((uint32_t)link->link_speed, 1);

/* check if speed and lanes have changed */
if (dev_conf->link_speeds != curr_speed_bit ||
bp->link_info->active_lanes != bp->link_info->pmd_speed_lanes)
return 1;

return 0;
}

static int bnxt_update_phy_setting(struct bnxt *bp)
{
struct rte_eth_link new;
int rc, rc1 = 0;

rc = bnxt_get_hwrm_link_config(bp, &new);
if (rc) {
PMD_DRV_LOG(ERR, "Failed to get link settings\n");
return rc;
}

/* convert to speedbit flag */
curr_speed_bit = rte_eth_speed_bitflag((uint32_t)link->link_speed, 1);
/* Validate speeds2 requirements */
if (BNXT_LINK_SPEEDS_V2(bp)) {
rc1 = bnxt_validate_speed_lanes_change(bp);
if (rc1 == -EINVAL) {
PMD_DRV_LOG(ERR, "Failed to set correct lanes\n");
return rc1;
}
}

/*
* Device is not obliged link down in certain scenarios, even
* when forced. When FW does not allow any user other than BMC
* to shutdown the port, bnxt_get_hwrm_link_config() call always
* returns link up. Force phy update always in that case.
*/
if (!new.link_status || bnxt_force_link_config(bp) ||
(BNXT_LINK_SPEEDS_V2(bp) && dev_conf->link_speeds != curr_speed_bit)) {
if (!new.link_status || bnxt_force_link_config(bp) || rc1 == 1) {
rc = bnxt_set_hwrm_link_config(bp, true);
if (rc) {
PMD_DRV_LOG(ERR, "Failed to update PHY settings\n");
Expand Down Expand Up @@ -1331,16 +1376,17 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
void bnxt_print_link_info(struct rte_eth_dev *eth_dev)
{
struct rte_eth_link *link = &eth_dev->data->dev_link;
struct bnxt *bp = eth_dev->data->dev_private;

if (link->link_status)
PMD_DRV_LOG(DEBUG, "Port %d Link Up - speed %u Mbps - %s\n",
eth_dev->data->port_id,
(uint32_t)link->link_speed,
(link->link_duplex == RTE_ETH_LINK_FULL_DUPLEX) ?
("full-duplex") : ("half-duplex\n"));
PMD_DRV_LOG(DEBUG, "Port %d Link Up - speed %u Mbps - %s Lanes - %d\n",
eth_dev->data->port_id,
(uint32_t)link->link_speed,
(link->link_duplex == RTE_ETH_LINK_FULL_DUPLEX) ?
("full-duplex") : ("half-duplex\n"),
(uint16_t)bp->link_info->active_lanes);
else
PMD_DRV_LOG(INFO, "Port %d Link Down\n",
eth_dev->data->port_id);
PMD_DRV_LOG(INFO, "Port %d Link Down\n", eth_dev->data->port_id);
}

/*
Expand Down Expand Up @@ -4191,6 +4237,105 @@ static int bnxt_get_module_eeprom(struct rte_eth_dev *dev,
return length ? -EINVAL : 0;
}

#if (RTE_VERSION_NUM(22, 11, 0, 0) <= RTE_VERSION)
static int bnxt_speed_lanes_set(struct rte_eth_dev *dev, uint32_t speed_lanes)
{
struct bnxt *bp = dev->data->dev_private;

if (!BNXT_LINK_SPEEDS_V2(bp))
return -ENOTSUP;

bp->link_info->pmd_speed_lanes = speed_lanes;

return 0;
}

static uint32_t
bnxt_get_speed_lanes_capa(struct rte_eth_speed_lanes_capa *speed_lanes_capa,
uint32_t speed_capa)
{
uint32_t speed_bit;
uint32_t num = 0;
uint32_t i;

for (i = 0; i < RTE_DIM(speed_lanes_capa_tbl); i++) {
speed_bit =
rte_eth_speed_bitflag(speed_lanes_capa_tbl[i].speed,
RTE_ETH_LINK_FULL_DUPLEX);
if ((speed_capa & speed_bit) == 0)
continue;

speed_lanes_capa[num].speed = speed_lanes_capa_tbl[i].speed;
speed_lanes_capa[num].capa = speed_lanes_capa_tbl[i].capa;
num++;
}

return num;
}

static int bnxt_speed_lanes_get_capa(struct rte_eth_dev *dev,
struct rte_eth_speed_lanes_capa *speed_lanes_capa,
unsigned int num)
{
struct rte_eth_link *link = &dev->data->dev_link;
struct bnxt *bp = dev->data->dev_private;
unsigned int speed_num;
uint32_t speed_capa;
int rc;

rc = is_bnxt_in_error(bp);
if (rc)
return rc;

if (!BNXT_LINK_SPEEDS_V2(bp))
return -ENOTSUP;

/* speed_num counts number of speed capabilities.
* When link is down, show the user choice all combinations of speeds x lanes
*/
if (link->link_status) {
speed_capa = bnxt_get_speed_capabilities_v2(bp);
speed_num = rte_popcount32(speed_capa & BNXT_SPEEDS_SUPP_SPEED_LANES);
} else {
speed_capa = BNXT_SPEEDS_SUPP_SPEED_LANES;
speed_num = rte_popcount32(BNXT_SPEEDS_SUPP_SPEED_LANES);
}
if (speed_num == 0)
return -ENOTSUP;

if (speed_lanes_capa == NULL)
return speed_num;

if (num < speed_num)
return -EINVAL;

return bnxt_get_speed_lanes_capa(speed_lanes_capa, speed_capa);
}

static int bnxt_speed_lanes_get(struct rte_eth_dev *dev, uint32_t *lanes)
{
struct rte_eth_link *link = &dev->data->dev_link;
struct bnxt *bp = dev->data->dev_private;
int rc;

rc = is_bnxt_in_error(bp);
if (rc)
return rc;

if (!BNXT_LINK_SPEEDS_V2(bp))
return -ENOTSUP;

if (!link->link_status)
return -EINVAL;

/* user app expects lanes 1 for zero */
*lanes = (bp->link_info->active_lanes) ?
bp->link_info->active_lanes : 1;
return 0;
}

#endif

/*
* Initialization
*/
Expand Down Expand Up @@ -4262,6 +4407,11 @@ static const struct eth_dev_ops bnxt_dev_ops = {
.timesync_read_rx_timestamp = bnxt_timesync_read_rx_timestamp,
.timesync_read_tx_timestamp = bnxt_timesync_read_tx_timestamp,
.mtr_ops_get = bnxt_flow_meter_ops_get,
#if (RTE_VERSION_NUM(22, 11, 0, 0) <= RTE_VERSION)
.speed_lanes_get = bnxt_speed_lanes_get,
.speed_lanes_set = bnxt_speed_lanes_set,
.speed_lanes_get_capa = bnxt_speed_lanes_get_capa,
#endif
};

static uint32_t bnxt_map_reset_regs(struct bnxt *bp, uint32_t reg)
Expand Down
Loading

0 comments on commit 46d738c

Please sign in to comment.