DPDK patches and discussions
 help / color / mirror / Atom feed
From: huangdengdui <huangdengdui@huawei.com>
To: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>, <dev@dpdk.org>
Cc: <ajit.khaparde@broadcom.com>,
	<kalesh-anakkur.purayil@broadcom.com>, <ferruh.yigit@amd.com>
Subject: Re: [PATCH v3] ethdev: Add link_speed lanes support
Date: Thu, 20 Jun 2024 11:23:18 +0800	[thread overview]
Message-ID: <e996e70a-71f6-4b1d-949d-c5f994bfca38@huawei.com> (raw)
In-Reply-To: <20240617203448.97972-1-damodharam.ammepalli@broadcom.com>

Hi Damodharam
Here are some suggestions. See below.

On 2024/6/18 4:34, Damodharam Ammepalli wrote:
> Update the eth_dev_ops structure with new function vectors
> to get, get capabilities and set ethernet link speed lanes.
> Update the testpmd to provide required config and information
> display infrastructure.
> 
> The supporting ethernet controller driver will register callbacks
> to avail link speed lanes config and get services. This lanes
> configuration is applicable only when the nic is forced to fixed
> speeds. In Autonegiation mode, the hardware automatically
> negotiates the number of lanes.
> 


> +
>  /* *** configure txq/rxq, txd/rxd *** */
>  struct cmd_config_rx_tx {
>  	cmdline_fixed_string_t port;
> @@ -13238,6 +13459,9 @@ static cmdline_parse_ctx_t builtin_ctx[] = {
>  	(cmdline_parse_inst_t *)&cmd_set_port_setup_on,
>  	(cmdline_parse_inst_t *)&cmd_config_speed_all,
>  	(cmdline_parse_inst_t *)&cmd_config_speed_specific,
> +	(cmdline_parse_inst_t *)&cmd_config_speed_lanes_all,
> +	(cmdline_parse_inst_t *)&cmd_config_speed_lanes_specific,
> +	(cmdline_parse_inst_t *)&cmd_show_speed_lanes,

Please also add to help string and update doc

>  	(cmdline_parse_inst_t *)&cmd_config_loopback_all,
>  	(cmdline_parse_inst_t *)&cmd_config_loopback_specific,
>  	(cmdline_parse_inst_t *)&cmd_config_rx_tx,
> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
> index 66c3a68c1d..cf3ea50114 100644
> --- a/app/test-pmd/config.c
> +++ b/app/test-pmd/config.c
> @@ -207,6 +207,32 @@ static const struct {
>  	{"gtpu", RTE_ETH_FLOW_GTPU},
>  };
>  
> +static const struct {
> +	enum rte_eth_speed_lanes lane;
> +	const uint32_t value;
> +} speed_lane_name[] = {
> +	{
> +		.lane = RTE_ETH_SPEED_LANE_NOLANE,
> +		.value = 0,
> +	},
> +	{
> +		.lane = RTE_ETH_SPEED_LANE_1,
> +		.value = 1,
> +	},
> +	{
> +		.lane = RTE_ETH_SPEED_LANE_2,
> +		.value = 2,
> +	},
> +	{
> +		.lane = RTE_ETH_SPEED_LANE_4,
> +		.value = 4,
> +	},
> +	{
> +		.lane = RTE_ETH_SPEED_LANE_8,
> +		.value = 8,
> +	},
> +};
> +
>  static void
>  print_ethaddr(const char *name, struct rte_ether_addr *eth_addr)
>  {
> @@ -786,6 +812,7 @@ port_infos_display(portid_t port_id)
>  	char name[RTE_ETH_NAME_MAX_LEN];
>  	int ret;
>  	char fw_version[ETHDEV_FWVERS_LEN];
> +	uint32_t lanes;
>  
>  	if (port_id_is_invalid(port_id, ENABLED_WARN)) {
>  		print_valid_ports();
> @@ -828,6 +855,8 @@ port_infos_display(portid_t port_id)
>  
>  	printf("\nLink status: %s\n", (link.link_status) ? ("up") : ("down"));
>  	printf("Link speed: %s\n", rte_eth_link_speed_to_str(link.link_speed));
> +	if (rte_eth_speed_lanes_get(port_id, &lanes) == 0)
> +		printf("Active Lanes: %d\n", lanes);

It should not be printed when lanes=0. Or print unknown when lane=0?

>  	printf("Link duplex: %s\n", (link.link_duplex == RTE_ETH_LINK_FULL_DUPLEX) ?
>  	       ("full-duplex") : ("half-duplex"));
>  	printf("Autoneg status: %s\n", (link.link_autoneg == RTE_ETH_LINK_AUTONEG) ?
> @@ -962,7 +991,7 @@ port_summary_header_display(void)
>  
>  	port_number = rte_eth_dev_count_avail();
>  	printf("Number of available ports: %i\n", port_number);
> -	printf("%-4s %-17s %-12s %-14s %-8s %s\n", "Port", "MAC Address", "Name",
> +	printf("%-4s %-17s %-12s %-14s %-8s %-8s\n", "Port", "MAC Address", "Name",
>  			"Driver", "Status", "Link");
>  }
>  
> @@ -993,7 +1022,7 @@ port_summary_display(portid_t port_id)
>  	if (ret != 0)
>  		return;
>  
> -	printf("%-4d " RTE_ETHER_ADDR_PRT_FMT " %-12s %-14s %-8s %s\n",
> +	printf("%-4d " RTE_ETHER_ADDR_PRT_FMT " %-12s %-14s %-8s %-8s\n",

Does the lanes need to be printed?

>  		port_id, RTE_ETHER_ADDR_BYTES(&mac_addr), name,
>  		dev_info.driver_name, (link.link_status) ? ("up") : ("down"),
>  		rte_eth_link_speed_to_str(link.link_speed));
> @@ -7244,3 +7273,35 @@ show_mcast_macs(portid_t port_id)
>  		printf("  %s\n", buf);
>  	}
>  }
> +
> +int
> +parse_speed_lanes(uint32_t lane, uint32_t *speed_lane)
> +{
> +	uint8_t i;
> +
> +	for (i = 0; i < RTE_DIM(speed_lane_name); i++) {
> +		if (speed_lane_name[i].value == lane) {
> +			*speed_lane = lane;
> +			return 0;
> +		}
> +	}
> +	return -1;
> +}
> +
> +void
> +show_speed_lanes_capability(unsigned int num, struct rte_eth_speed_lanes_capa *speed_lanes_capa)
> +{
> +	unsigned int i, j;
> +
> +	printf("\n%-15s %-10s", "Supported-speeds", "Valid-lanes");
> +	printf("\n-----------------------------------\n");
> +	for (i = 0; i < num; i++) {
> +		printf("%-17s ", rte_eth_link_speed_to_str(speed_lanes_capa[i].speed));
> +
> +		for (j = 0; j < RTE_ETH_SPEED_LANE_MAX; j++) {
> +			if (RTE_ETH_SPEED_LANES_TO_CAPA(j) & speed_lanes_capa[i].capa)
> +				printf("%-2d ", speed_lane_name[j].value);
> +		}
> +		printf("\n");
> +	}
> +}
> diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
> index 9facd7f281..fb9ef05cc5 100644
> --- a/app/test-pmd/testpmd.h
> +++ b/app/test-pmd/testpmd.h
> @@ -1253,6 +1253,10 @@ extern int flow_parse(const char *src, void *result, unsigned int size,
>  		      struct rte_flow_item **pattern,
>  		      struct rte_flow_action **actions);
>  
> +void show_speed_lanes_capability(uint32_t num,
> +				 struct rte_eth_speed_lanes_capa *speed_lanes_capa);
> +int parse_speed_lanes(uint32_t lane, uint32_t *speed_lane);
> +
>  uint64_t str_to_rsstypes(const char *str);
>  const char *rsstypes_to_str(uint64_t rss_type);
>  
> diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
> index 883e59a927..0f10aec3a1 100644
> --- a/lib/ethdev/ethdev_driver.h
> +++ b/lib/ethdev/ethdev_driver.h
> @@ -1179,6 +1179,79 @@ typedef int (*eth_rx_descriptor_dump_t)(const struct rte_eth_dev *dev,
>  					uint16_t queue_id, uint16_t offset,
>  					uint16_t num, FILE *file);
>  
> +/**
> + * @internal
> + * Get number of current active lanes
> + *
> + * @param dev
> + *   ethdev handle of port.
> + * @param speed_lanes
> + *   Number of active lanes that the link is trained up.
> + * @return
> + *   Negative errno value on error, 0 on success.
> + *
> + * @retval 0
> + *   Success, get speed_lanes data success.
> + * @retval -ENOTSUP
> + *   Operation is not supported.
> + * @retval -EIO
> + *   Device is removed.
> + */
> +typedef int (*eth_speed_lanes_get_t)(struct rte_eth_dev *dev, uint32_t *speed_lanes);
> +
> +/**
> + * @internal
> + * Set speed lanes
> + *
> + * @param dev
> + *   ethdev handle of port.
> + * @param speed_lanes
> + *   Non-negative number of lanes
> + *
> + * @return
> + *   Negative errno value on error, 0 on success.
> + *
> + * @retval 0
> + *   Success, set lanes success.
> + * @retval -ENOTSUP
> + *   Operation is not supported.
> + * @retval -EINVAL
> + *   Unsupported mode requested.
> + * @retval -EIO
> + *   Device is removed.
> + */
> +typedef int (*eth_speed_lanes_set_t)(struct rte_eth_dev *dev, uint32_t speed_lanes);
> +
> +/**
> + * @internal
> + * Get supported link speed lanes capability
> + *
> + * @param speed_lanes_capa
> + *   speed_lanes_capa is out only with per-speed capabilities.
> + * @param num
> + *   a number of elements in an speed_speed_lanes_capa array.
> + *

Some of the arguments are not documented, not just here.
You can add the 'enable_docs' to verify the document, for example
meson build  -Denable_docs=true

> + * @return
> + *   Negative errno value on error, positive value on success.
> + *
> + * @retval positive value
> + *   A non-negative value lower or equal to num: success. The return value
> + *   is the number of entries filled in the speed lanes array.
> + *   A non-negative value higher than num: error, the given speed lanes capa array
> + *   is too small. The return value corresponds to the num that should
> + *   be given to succeed. The entries in the speed lanes capa array are not valid
> + *   and shall not be used by the caller.
> + * @retval -ENOTSUP
> + *   Operation is not supported.
> + * @retval -EIO
> + *   Device is removed.
> + * @retval -EINVAL
> + *   *num* or *speed_lanes_capa* invalid.
> + */
> +typedef int (*eth_speed_lanes_get_capability_t)(struct rte_eth_dev *dev,
> +						struct rte_eth_speed_lanes_capa *speed_lanes_capa,
> +						unsigned int num);
> +
>  /**
>   * @internal
>   * Dump Tx descriptor info to a file.
> @@ -1247,6 +1320,10 @@ struct eth_dev_ops {
>  	eth_dev_close_t            dev_close;     /**< Close device */
>  	eth_dev_reset_t		   dev_reset;	  /**< Reset device */
>  	eth_link_update_t          link_update;   /**< Get device link state */
> +	eth_speed_lanes_get_t	   speed_lanes_get;	  /**<Get link speed active lanes */
> +	eth_speed_lanes_set_t      speed_lanes_set;	  /**<set the link speeds supported lanes */
> +	/** Get link speed lanes capability */
> +	eth_speed_lanes_get_capability_t speed_lanes_get_capa;
>  	/** Check if the device was physically removed */
>  	eth_is_removed_t           is_removed;
>  
> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
> index f1c658f49e..07cefea307 100644
> --- a/lib/ethdev/rte_ethdev.c
> +++ b/lib/ethdev/rte_ethdev.c
> @@ -7008,4 +7008,55 @@ int rte_eth_dev_map_aggr_tx_affinity(uint16_t port_id, uint16_t tx_queue_id,
>  	return ret;
>  }
>  
> +int
> +rte_eth_speed_lanes_get(uint16_t port_id, uint32_t *lane)
> +{
> +	struct rte_eth_dev *dev;
> +
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +	dev = &rte_eth_devices[port_id];
> +
> +	if (*dev->dev_ops->speed_lanes_get == NULL)
> +		return -ENOTSUP;
> +	return eth_err(port_id, (*dev->dev_ops->speed_lanes_get)(dev, lane));
> +}
> +
> +int
> +rte_eth_speed_lanes_get_capability(uint16_t port_id,
> +				   struct rte_eth_speed_lanes_capa *speed_lanes_capa,
> +				   unsigned int num)
> +{
> +	struct rte_eth_dev *dev;
> +	int ret;
> +
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +	dev = &rte_eth_devices[port_id];
> +
> +	if (speed_lanes_capa == NULL && num > 0) {
> +		RTE_ETHDEV_LOG_LINE(ERR,
> +				    "Cannot get ethdev port %u speed lanes capability to NULL when array size is non zero",
> +				    port_id);
> +		return -EINVAL;
> +	}
> +
> +	if (*dev->dev_ops->speed_lanes_get_capa == NULL)
> +		return -ENOTSUP;
> +	ret = (*dev->dev_ops->speed_lanes_get_capa)(dev, speed_lanes_capa, num);
> +
> +	return ret;
> +}
> +
> +int
> +rte_eth_speed_lanes_set(uint16_t port_id, uint32_t speed_lanes_capa)
> +{
> +	struct rte_eth_dev *dev;
> +
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +	dev = &rte_eth_devices[port_id];
> +
> +	if (*dev->dev_ops->speed_lanes_set == NULL)
> +		return -ENOTSUP;
> +	return eth_err(port_id, (*dev->dev_ops->speed_lanes_set)(dev, speed_lanes_capa));
> +}
> +
>  RTE_LOG_REGISTER_DEFAULT(rte_eth_dev_logtype, INFO);
> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
> index 548fada1c7..f5bacd4ba4 100644
> --- a/lib/ethdev/rte_ethdev.h
> +++ b/lib/ethdev/rte_ethdev.h
> @@ -357,6 +357,30 @@ struct rte_eth_link {
>  #define RTE_ETH_LINK_MAX_STR_LEN 40 /**< Max length of default link string. */
>  /**@}*/
>  
> +/**
> + * This enum indicates the possible link speed lanes of an ethdev port.
> + */
> +enum rte_eth_speed_lanes {
> +	RTE_ETH_SPEED_LANE_NOLANE = 0,  /**< speed lanes unsupported mode or default */
> +	RTE_ETH_SPEED_LANE_1,           /**< Link speed lane  1 */
> +	RTE_ETH_SPEED_LANE_2,           /**< Link speed lanes 2 */
> +	RTE_ETH_SPEED_LANE_4,           /**< Link speed lanes 4 */
> +	RTE_ETH_SPEED_LANE_8,           /**< Link speed lanes 8 */
> +	RTE_ETH_SPEED_LANE_MAX,
> +};

Is it better to make the index equal to the lanes num?
enum rte_eth_speed_lanes {
	RTE_ETH_SPEED_LANE_NOLANE = 0,      /**< speed lanes unsupported mode or default */
	RTE_ETH_SPEED_LANE_1 = 1,           /**< Link speed lane  1 */
	RTE_ETH_SPEED_LANE_2 = 2,           /**< Link speed lanes 2 */
	RTE_ETH_SPEED_LANE_4 = 4,           /**< Link speed lanes 4 */
	RTE_ETH_SPEED_LANE_8 = 8,           /**< Link speed lanes 8 */
	RTE_ETH_SPEED_LANE_MAX,
};

In addition, when lanes = 0, is it better to define it as Unknown?
If default lanes can return 0 lanes, The active lanes are different for each NIC,
users may be confused.

> +
> +/* Translate from link speed lanes to speed lanes capa */
> +#define RTE_ETH_SPEED_LANES_TO_CAPA(x) RTE_BIT32(x)
> +
> +/* This macro indicates link speed lanes capa mask */
> +#define RTE_ETH_SPEED_LANES_CAPA_MASK(x) RTE_BIT32(RTE_ETH_SPEED_ ## x)
> +
> +/* A structure used to get and set lanes capabilities per link speed */
> +struct rte_eth_speed_lanes_capa {
> +	uint32_t speed;
> +	uint32_t capa;
> +};
> +
>  /**
>   * A structure used to configure the ring threshold registers of an Rx/Tx
>   * queue for an Ethernet port.
> @@ -6922,6 +6946,72 @@ rte_eth_tx_queue_count(uint16_t port_id, uint16_t queue_id)
>  	return rc;
>  }
>  
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
> + *
> + * Get Active lanes.
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param lanes
> + *   driver populates a active lanes value whether link is Autonegotiated or Fixed speed.
> + *
> + * @return
> + *   - (0) if successful.
> + *   - (-ENOTSUP) if underlying hardware OR driver doesn't support.
> + *     that operation.
> + *   - (-EIO) if device is removed.
> + *   - (-ENODEV)  if *port_id* invalid.
> + */
> +__rte_experimental
> +int rte_eth_speed_lanes_get(uint16_t port_id, uint32_t *lanes);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
> + *
> + * Set speed lanes supported by the NIC.
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param speed_lanes
> + *   speed_lanes a non-zero value of number lanes for this speeds.
> + *
> + * @return
> + *  - (>=0) valid input and supported by driver or hardware.

Is it better to change the description to the following:
(0) if successful.

> + *   - (-ENOTSUP) if underlying hardware OR driver doesn't support.
> + *     that operation.
> + *   - (-EIO) if device is removed.
> + *   - (-ENODEV)  if *port_id* invalid.
> + */
> +__rte_experimental
> +int rte_eth_speed_lanes_set(uint16_t port_id, uint32_t speed_lanes_capa);
> +

Is it better to name 'speed_lanes'?

> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
> + *
> + * Set speed lanes supported by the NIC.
> + *

Set -> Get

> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param speed_lanes_bmap
> + *   speed_lanes_bmap int array updated by driver by valid lanes bmap.
> + *
> + * @return
> + *  - (>=0) valid input and supported by driver or hardware.
> + *   - (-ENOTSUP) if underlying hardware OR driver doesn't support.
> + *     that operation.
> + *   - (-EIO) if device is removed.
> + *   - (-ENODEV)  if *port_id* invalid.
> + *   - (-EINVAL)  if *speed_lanes* invalid
> + */
> +__rte_experimental
> +int rte_eth_speed_lanes_get_capability(uint16_t port_id,
> +				       struct rte_eth_speed_lanes_capa *speed_lanes_capa,
> +				       unsigned int num);
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
> index 79f6f5293b..db9261946f 100644
> --- a/lib/ethdev/version.map
> +++ b/lib/ethdev/version.map
> @@ -325,6 +325,11 @@ EXPERIMENTAL {
>  	rte_flow_template_table_resizable;
>  	rte_flow_template_table_resize;
>  	rte_flow_template_table_resize_complete;
> +
> +	# added in 24.07
> +	rte_eth_speed_lanes_get;
> +	rte_eth_speed_lanes_get_capability;
> +	rte_eth_speed_lanes_set;
>  };
>  
>  INTERNAL {

  reply	other threads:[~2024-06-20  3:23 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-22 22:25 [RFC 0/2] Add support for link speed lanes Damodharam Ammepalli
2024-03-22 22:25 ` [RFC 1/2] lib/ethdev: Add link_speed lanes support into rte lib Damodharam Ammepalli
2024-03-22 22:25 ` [RFC 2/2] testpmd: Add speed lanes to testpmd config and show command Damodharam Ammepalli
2024-05-22 20:59 ` [RFC 0/2] Add support for link speed lanes Ferruh Yigit
2024-05-28 21:19   ` Damodharam Ammepalli
2024-06-02  2:45     ` [PATCH v2 0/4] " Damodharam Ammepalli
2024-06-02  2:45       ` [PATCH v2 1/4] lib/ethdev: Add link_speed lanes support into rte lib Damodharam Ammepalli
2024-06-11 23:39         ` Ferruh Yigit
2024-06-14 18:27           ` Damodharam Ammepalli
2024-06-17 20:34             ` [PATCH v3] ethdev: Add link_speed lanes support Damodharam Ammepalli
2024-06-20  3:23               ` huangdengdui [this message]
2024-06-25 21:07                 ` Damodharam Ammepalli
2024-06-26  2:19                   ` huangdengdui
2024-06-02  2:45       ` [PATCH v2 2/4] testpmd: Add speed lanes to testpmd config and show command Damodharam Ammepalli
2024-06-11 23:39         ` Ferruh Yigit
2024-06-02  2:45       ` [PATCH v2 3/4] lib/ethdev: add support for displaying lanes capability Damodharam Ammepalli
2024-06-11 23:39         ` Ferruh Yigit
2024-06-02  2:45       ` [PATCH v2 4/4] testpmd: " Damodharam Ammepalli
2024-06-11 23:39         ` Ferruh Yigit
2024-06-12 17:53           ` Damodharam Ammepalli
2024-06-12 20:57             ` Ferruh Yigit
2024-06-11 23:38       ` [PATCH v2 0/4] Add support for link speed lanes Ferruh Yigit
2024-06-12 17:46         ` Damodharam Ammepalli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e996e70a-71f6-4b1d-949d-c5f994bfca38@huawei.com \
    --to=huangdengdui@huawei.com \
    --cc=ajit.khaparde@broadcom.com \
    --cc=damodharam.ammepalli@broadcom.com \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@amd.com \
    --cc=kalesh-anakkur.purayil@broadcom.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).