* [RFC PATCH 0/3] Make Link Status on Close Configurable
@ 2025-08-29 14:02 Ciara Loftus
2025-08-29 14:02 ` [RFC PATCH 1/3] ethdev: add set link state on close API Ciara Loftus
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Ciara Loftus @ 2025-08-29 14:02 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
Most drivers bring the port link down on device close (eg. intel i40e), however
some others restore the link to its original state when the device was started
(eg. intel ice). It may be useful to be able to configure this behaviour which
is the motivation for this RFC.
This RFC proposes a way to make the link status of a port configurable
when the port is closed or stopped. Three configuration options are available:
1. down: bring (or keep) the link down
2. up: bring (or keep) the link up
3. initial: restore the link to the state it was in when the device was
started.
Ciara Loftus (3):
ethdev: add set link state on close API
net/ice: implement the link state on close device op
app/testpmd: support link state on close ethdev API
app/test-pmd/cmdline.c | 56 +++++++++++++++++++++
app/test-pmd/config.c | 17 +++++++
app/test-pmd/parameters.c | 26 ++++++++++
app/test-pmd/testpmd.c | 16 ++++++
app/test-pmd/testpmd.h | 3 ++
doc/guides/rel_notes/release_25_11.rst | 4 ++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 7 +++
drivers/net/intel/ice/ice_ethdev.c | 20 +++++++-
drivers/net/intel/ice/ice_ethdev.h | 1 +
lib/ethdev/ethdev_driver.h | 18 +++++++
lib/ethdev/ethdev_trace.h | 8 +++
lib/ethdev/ethdev_trace_points.c | 3 ++
lib/ethdev/rte_ethdev.c | 19 +++++++
lib/ethdev/rte_ethdev.h | 32 ++++++++++++
14 files changed, 229 insertions(+), 1 deletion(-)
--
2.34.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [RFC PATCH 1/3] ethdev: add set link state on close API
2025-08-29 14:02 [RFC PATCH 0/3] Make Link Status on Close Configurable Ciara Loftus
@ 2025-08-29 14:02 ` Ciara Loftus
2025-08-29 15:19 ` Ivan Malov
2025-08-29 14:02 ` [RFC PATCH 2/3] net/ice: implement the link state on close device op Ciara Loftus
2025-08-29 14:02 ` [RFC PATCH 3/3] app/testpmd: support link state on close ethdev API Ciara Loftus
2 siblings, 1 reply; 5+ messages in thread
From: Ciara Loftus @ 2025-08-29 14:02 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
Allow the user to configure the state a link should be in after
the device has been stopped/closed. Make this configurable
through the new experimental rte_eth_dev_set_link_state_on_close
API. Three states are allowed:
1. down: bring (or keep) the link down
2. up: bring (or keep) the link up
3. initial: restore the link to the state it was in when the device was
started.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
doc/guides/rel_notes/release_25_11.rst | 4 ++++
lib/ethdev/ethdev_driver.h | 18 +++++++++++++++
lib/ethdev/ethdev_trace.h | 8 +++++++
lib/ethdev/ethdev_trace_points.c | 3 +++
lib/ethdev/rte_ethdev.c | 19 +++++++++++++++
lib/ethdev/rte_ethdev.h | 32 ++++++++++++++++++++++++++
6 files changed, 84 insertions(+)
diff --git a/doc/guides/rel_notes/release_25_11.rst b/doc/guides/rel_notes/release_25_11.rst
index 32d61691d2..8f9ab31687 100644
--- a/doc/guides/rel_notes/release_25_11.rst
+++ b/doc/guides/rel_notes/release_25_11.rst
@@ -55,6 +55,10 @@ New Features
Also, make sure to start the actual text at the margin.
=======================================================
+ * ** Added link state on close ethdev API
+
+ * Added a new API to the ethdev library to allow the configuration of link state
+ on device close. It can be configured as down, up or restored to initial state.
Removed Items
-------------
diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
index 2b4d2ae9c3..f82c67ce36 100644
--- a/lib/ethdev/ethdev_driver.h
+++ b/lib/ethdev/ethdev_driver.h
@@ -1199,6 +1199,21 @@ typedef int (*eth_ip_reassembly_conf_set_t)(struct rte_eth_dev *dev,
typedef const uint32_t *(*eth_buffer_split_supported_hdr_ptypes_get_t)(struct rte_eth_dev *dev,
size_t *no_of_elements);
+/**
+ * @internal
+ * Set the state the link should be configured to be on device closure.
+ *
+ * @param dev
+ * Ethdev handle of port.
+ * @param state
+ * Either down, up or initial.
+ *
+ * @return
+ * Negative errno value on error, zero otherwise.
+ */
+typedef int (*eth_link_state_on_close_set_t)(struct rte_eth_dev *dev,
+ enum rte_eth_link_state_on_close state);
+
/**
* @internal
* Dump private info from device to a file.
@@ -1599,6 +1614,9 @@ struct eth_dev_ops {
/** Get supported header ptypes to split */
eth_buffer_split_supported_hdr_ptypes_get_t buffer_split_supported_hdr_ptypes_get;
+ /** Set link state on close */
+ eth_link_state_on_close_set_t link_state_on_close_set;
+
/** Dump private info from device */
eth_dev_priv_dump_t eth_dev_priv_dump;
diff --git a/lib/ethdev/ethdev_trace.h b/lib/ethdev/ethdev_trace.h
index 482befc209..6554d176b8 100644
--- a/lib/ethdev/ethdev_trace.h
+++ b/lib/ethdev/ethdev_trace.h
@@ -1298,6 +1298,14 @@ RTE_TRACE_POINT(
rte_trace_point_emit_u32(ptypes);
)
+RTE_TRACE_POINT(
+ rte_eth_trace_link_state_on_close_set,
+ RTE_TRACE_POINT_ARGS(uint16_t port_id, enum rte_eth_link_state_on_close state, int ret),
+ rte_trace_point_emit_u16(port_id);
+ rte_trace_point_emit_int(state);
+ rte_trace_point_emit_int(ret);
+)
+
RTE_TRACE_POINT(
rte_eth_trace_cman_info_get,
RTE_TRACE_POINT_ARGS(uint16_t port_id,
diff --git a/lib/ethdev/ethdev_trace_points.c b/lib/ethdev/ethdev_trace_points.c
index 071c508327..e515efacc7 100644
--- a/lib/ethdev/ethdev_trace_points.c
+++ b/lib/ethdev/ethdev_trace_points.c
@@ -482,6 +482,9 @@ RTE_TRACE_POINT_REGISTER(rte_eth_trace_ip_reassembly_conf_set,
RTE_TRACE_POINT_REGISTER(rte_eth_trace_buffer_split_get_supported_hdr_ptypes,
lib.ethdev.buffer_split_get_supported_hdr_ptypes)
+RTE_TRACE_POINT_REGISTER(rte_eth_trace_link_state_on_close_set,
+ lib.ethdev.link_state_on_close_set)
+
RTE_TRACE_POINT_REGISTER(rte_eth_trace_cman_info_get,
lib.ethdev.cman_info_get)
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index dd7c00bc94..4847a89440 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -7344,6 +7344,25 @@ rte_eth_buffer_split_get_supported_hdr_ptypes(uint16_t port_id, uint32_t *ptypes
return j;
}
+RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_dev_set_link_state_on_close, 25.11)
+int
+rte_eth_dev_set_link_state_on_close(uint16_t port_id, enum rte_eth_link_state_on_close state)
+{
+ struct rte_eth_dev *dev;
+ int ret;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+ dev = &rte_eth_devices[port_id];
+
+ if (dev->dev_ops->link_state_on_close_set == NULL)
+ return -ENOTSUP;
+ ret = eth_err(port_id, dev->dev_ops->link_state_on_close_set(dev, state));
+
+ rte_eth_trace_link_state_on_close_set(port_id, state, ret);
+
+ return ret;
+}
+
RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eth_dev_count_aggr_ports, 23.03)
int rte_eth_dev_count_aggr_ports(uint16_t port_id)
{
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index f9fb6ae549..3312f1e95c 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -514,6 +514,12 @@ struct rte_eth_rss_conf {
enum rte_eth_hash_function algorithm; /**< Hash algorithm. */
};
+enum rte_eth_link_state_on_close {
+ RTE_ETH_LINK_STATE_ON_CLOSE_DOWN = 1,
+ RTE_ETH_LINK_STATE_ON_CLOSE_UP = 2,
+ RTE_ETH_LINK_STATE_ON_CLOSE_INITIAL = 3
+};
+
/*
* A packet can be identified by hardware as different flow types. Different
* NIC hardware may support different flow types.
@@ -7065,6 +7071,32 @@ __rte_experimental
int rte_eth_buffer_split_get_supported_hdr_ptypes(uint16_t port_id, uint32_t *ptypes, int num)
__rte_warn_unused_result;
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Configure the state of the physical link when the device is closed.
+ *
+ * This function allows the configuration of the physical link state
+ * when the device is closed. The link can be set to either down, up or
+ * remain configured as the device default, depending on the value of the
+ * 'state' parameter.
+ *
+ * @param port_id
+ * The port identifier of the device.
+ * @param state
+ * - RTE_ETH_LINK_STATE_ON_CLOSE_DOWN - Bring (or keep) the link down.
+ * - RTE_ETH_LINK_STATE_ON_CLOSE_UP - Bring (or keep) the link up.
+ * - RTE_ETH_LINK_STATE_ON_CLOSE_INITIAL - Restore the link to the state it
+ * was in when the device was started.
+ * @return
+ * - (0) on success
+ * - (-ENOTSUP) if the device does not support this function.
+ */
+__rte_experimental
+int rte_eth_dev_set_link_state_on_close(uint16_t port_id, enum rte_eth_link_state_on_close state)
+ __rte_warn_unused_result;
+
/**
* @warning
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice.
--
2.34.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [RFC PATCH 2/3] net/ice: implement the link state on close device op
2025-08-29 14:02 [RFC PATCH 0/3] Make Link Status on Close Configurable Ciara Loftus
2025-08-29 14:02 ` [RFC PATCH 1/3] ethdev: add set link state on close API Ciara Loftus
@ 2025-08-29 14:02 ` Ciara Loftus
2025-08-29 14:02 ` [RFC PATCH 3/3] app/testpmd: support link state on close ethdev API Ciara Loftus
2 siblings, 0 replies; 5+ messages in thread
From: Ciara Loftus @ 2025-08-29 14:02 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
Implement the callback that allows for configuration of the link state
when the device is closed or stopped. The default behaviour remains the
same, that being that the link is restored to its original state on
device closure.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
drivers/net/intel/ice/ice_ethdev.c | 20 +++++++++++++++++++-
drivers/net/intel/ice/ice_ethdev.h | 1 +
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c
index 513777e372..37aee45abc 100644
--- a/drivers/net/intel/ice/ice_ethdev.c
+++ b/drivers/net/intel/ice/ice_ethdev.c
@@ -194,6 +194,8 @@ static int ice_fec_get(struct rte_eth_dev *dev, uint32_t *fec_capa);
static int ice_fec_set(struct rte_eth_dev *dev, uint32_t fec_capa);
static const uint32_t *ice_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev,
size_t *no_of_elements);
+static int ice_link_state_on_close_set(struct rte_eth_dev *dev,
+ enum rte_eth_link_state_on_close state);
static const struct rte_pci_id pci_id_ice_map[] = {
{ RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E823L_BACKPLANE) },
@@ -324,6 +326,7 @@ static const struct eth_dev_ops ice_eth_dev_ops = {
.fec_get = ice_fec_get,
.fec_set = ice_fec_set,
.buffer_split_supported_hdr_ptypes_get = ice_buffer_split_supported_hdr_ptypes_get,
+ .link_state_on_close_set = ice_link_state_on_close_set,
};
/* store statistics names and its offset in stats structure */
@@ -2811,7 +2814,9 @@ ice_dev_stop(struct rte_eth_dev *dev)
/* disable all queue interrupts */
ice_vsi_disable_queues_intr(main_vsi);
- if (pf->init_link_up)
+ if (pf->adapter->link_state_on_close == RTE_ETH_LINK_STATE_ON_CLOSE_UP ||
+ (pf->adapter->link_state_on_close == RTE_ETH_LINK_STATE_ON_CLOSE_INITIAL &&
+ pf->init_link_up))
ice_dev_set_link_up(dev);
else
ice_dev_set_link_down(dev);
@@ -3695,6 +3700,8 @@ ice_dev_configure(struct rte_eth_dev *dev)
}
}
+ ad->link_state_on_close = RTE_ETH_LINK_STATE_ON_CLOSE_INITIAL;
+
return 0;
}
@@ -7000,6 +7007,17 @@ ice_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused,
return ptypes;
}
+static int
+ice_link_state_on_close_set(struct rte_eth_dev *dev, enum rte_eth_link_state_on_close state)
+{
+ struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct ice_adapter *ad = (struct ice_adapter *)hw->back;
+
+ ad->link_state_on_close = state;
+
+ return 0;
+}
+
static unsigned int
ice_fec_get_capa_num(struct ice_aqc_get_phy_caps_data *pcaps,
struct rte_eth_fec_capa *speed_fec_capa)
diff --git a/drivers/net/intel/ice/ice_ethdev.h b/drivers/net/intel/ice/ice_ethdev.h
index 8e5799f8b4..408684631f 100644
--- a/drivers/net/intel/ice/ice_ethdev.h
+++ b/drivers/net/intel/ice/ice_ethdev.h
@@ -663,6 +663,7 @@ struct ice_adapter {
bool tx_use_avx2;
bool tx_use_avx512;
bool rx_vec_offload_support;
+ enum rte_eth_link_state_on_close link_state_on_close; /* link state on device closure. */
};
struct ice_vsi_vlan_pvid_info {
--
2.34.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [RFC PATCH 3/3] app/testpmd: support link state on close ethdev API
2025-08-29 14:02 [RFC PATCH 0/3] Make Link Status on Close Configurable Ciara Loftus
2025-08-29 14:02 ` [RFC PATCH 1/3] ethdev: add set link state on close API Ciara Loftus
2025-08-29 14:02 ` [RFC PATCH 2/3] net/ice: implement the link state on close device op Ciara Loftus
@ 2025-08-29 14:02 ` Ciara Loftus
2 siblings, 0 replies; 5+ messages in thread
From: Ciara Loftus @ 2025-08-29 14:02 UTC (permalink / raw)
To: dev; +Cc: Ciara Loftus
Allow the user to configure link state on close behaviour via the
link_state_on_close argument. Three options are allowed:
1. down: bring (or keep) the link down
2. up: bring (or keep) the link up
3. initial: restore the link to the state it was in when the device was
started.
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
app/test-pmd/cmdline.c | 56 +++++++++++++++++++++
app/test-pmd/config.c | 17 +++++++
app/test-pmd/parameters.c | 26 ++++++++++
app/test-pmd/testpmd.c | 16 ++++++
app/test-pmd/testpmd.h | 3 ++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 7 +++
6 files changed, 125 insertions(+)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 7b4e27eddf..79afcca60c 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -679,6 +679,9 @@ static void cmd_help_long_parsed(void *parsed_result,
" Set a controllable LED associated with a certain"
" port on or off.\n\n"
+ "set port (port_id) link_state_on_close (down|up|initial)\n"
+ " Set link state on close to down, up or initial for a port\n\n"
+
, list_pkt_forwarding_modes()
);
}
@@ -13857,6 +13860,58 @@ static cmdline_parse_inst_t cmd_set_dev_led = {
},
};
+/* *** SET LINK STATE ON CLOSE FOR A CERTAIN PORT *** */
+struct cmd_link_state_on_close_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t port;
+ portid_t port_id;
+ cmdline_fixed_string_t link_state_on_close;
+ cmdline_fixed_string_t state;
+};
+
+static void
+cmd_set_link_state_on_close_parsed(void *parsed_result,
+ __rte_unused struct cmdline *cl,
+ __rte_unused void *data)
+{
+ struct cmd_link_state_on_close_result *res = parsed_result;
+
+ if (strcmp(res->state, "down") == 0)
+ set_link_state_on_close(res->port_id, RTE_ETH_LINK_STATE_ON_CLOSE_DOWN);
+ else if (strcmp(res->state, "up") == 0)
+ set_link_state_on_close(res->port_id, RTE_ETH_LINK_STATE_ON_CLOSE_UP);
+ else if (strcmp(res->state, "initial") == 0)
+ set_link_state_on_close(res->port_id, RTE_ETH_LINK_STATE_ON_CLOSE_INITIAL);
+ else
+ printf("Invalid state: %s\n", res->state);
+}
+
+static cmdline_parse_token_string_t cmd_link_state_on_close_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_link_state_on_close_result, set, "set");
+static cmdline_parse_token_string_t cmd_link_state_on_close_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_link_state_on_close_result, port, "port");
+static cmdline_parse_token_num_t cmd_link_state_on_close_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_link_state_on_close_result, port_id, RTE_UINT16);
+static cmdline_parse_token_string_t cmd_link_state_on_close =
+ TOKEN_STRING_INITIALIZER(struct cmd_link_state_on_close_result, link_state_on_close,
+ "link_state_on_close");
+static cmdline_parse_token_string_t cmd_link_state_on_close_state =
+ TOKEN_STRING_INITIALIZER(struct cmd_link_state_on_close_result, state, "down#up#initial");
+
+static cmdline_parse_inst_t cmd_set_link_state_on_close = {
+ .f = cmd_set_link_state_on_close_parsed,
+ .data = NULL,
+ .help_str = "set port <port_id> link_state_on_close <down/up/initial>",
+ .tokens = {
+ (void *)&cmd_link_state_on_close_set,
+ (void *)&cmd_link_state_on_close_port,
+ (void *)&cmd_link_state_on_close_port_id,
+ (void *)&cmd_link_state_on_close,
+ (void *)&cmd_link_state_on_close_state,
+ NULL,
+ },
+};
+
/* ******************************************************************************** */
/* list of instructions */
@@ -14105,6 +14160,7 @@ static cmdline_parse_ctx_t builtin_ctx[] = {
&cmd_set_port_cman_config,
&cmd_config_tx_affinity_map,
&cmd_set_dev_led,
+ &cmd_set_link_state_on_close,
NULL,
};
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 0fda8e99f8..c5c5e23b4b 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -5429,6 +5429,23 @@ set_dev_led(portid_t port_id, bool active)
port_id, rte_strerror(-ret));
}
+void
+set_link_state_on_close(portid_t port_id, enum rte_eth_link_state_on_close state)
+{
+ int ret;
+
+ if (!rte_eth_dev_is_valid_port(port_id)) {
+ fprintf(stderr, "Error: Invalid port number %u\n", port_id);
+ return;
+ }
+
+ ret = rte_eth_dev_set_link_state_on_close(port_id, state);
+
+ if (ret < 0)
+ fprintf(stderr, "Error: Unable to set link state on close for port %u: %s\n",
+ port_id, rte_strerror(-ret));
+}
+
int
set_fwd_lcores_list(unsigned int *lcorelist, unsigned int nb_lc)
{
diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
index 1132972913..83c077f651 100644
--- a/app/test-pmd/parameters.c
+++ b/app/test-pmd/parameters.c
@@ -253,6 +253,8 @@ enum {
TESTPMD_OPT_NUM_PROCS_NUM,
#define TESTPMD_OPT_PROC_ID "proc-id"
TESTPMD_OPT_PROC_ID_NUM,
+#define TESTPMD_OPT_LINK_STATE_ON_CLOSE "link_state_on_close"
+ TESTPMD_OPT_LINK_STATE_ON_CLOSE_NUM,
TESTPMD_OPT_LONG_MAX_NUM
};
@@ -378,6 +380,7 @@ static const struct option long_options[] = {
NO_ARG(TESTPMD_OPT_RECORD_BURST_STATS),
REQUIRED_ARG(TESTPMD_OPT_NUM_PROCS),
REQUIRED_ARG(TESTPMD_OPT_PROC_ID),
+ REQUIRED_ARG(TESTPMD_OPT_LINK_STATE_ON_CLOSE),
{ 0, 0, NULL, 0 }
};
#undef NO_ARG
@@ -930,6 +933,23 @@ parse_link_speed(int n)
return speed;
}
+static int
+parse_link_state_on_close(const char *optarg)
+{
+ if (!strcmp(optarg, "down")) {
+ close_state = RTE_ETH_LINK_STATE_ON_CLOSE_DOWN;
+ } else if (!strcmp(optarg, "up")) {
+ close_state = RTE_ETH_LINK_STATE_ON_CLOSE_UP;
+ } else if (!strcmp(optarg, "initial")) {
+ close_state = RTE_ETH_LINK_STATE_ON_CLOSE_INITIAL;
+ } else {
+ fprintf(stderr, "Invalid state: %s\n", optarg);
+ return -1;
+ }
+
+ return 0;
+}
+
void
launch_args_parse(int argc, char** argv)
{
@@ -1733,6 +1753,12 @@ launch_args_parse(int argc, char** argv)
case TESTPMD_OPT_PROC_ID_NUM:
proc_id = atoi(optarg);
break;
+ case TESTPMD_OPT_LINK_STATE_ON_CLOSE_NUM:
+ if (parse_link_state_on_close(optarg)) {
+ rte_exit(EXIT_FAILURE,
+ "invalid link_state_on_close argument\n");
+ }
+ break;
default:
usage(argv[0]);
fprintf(stderr, "Invalid option: %s\n", argv[optind - 1]);
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index bb88555328..4ffa1113cd 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -557,6 +557,11 @@ uint32_t eth_link_speed;
*/
int proc_id;
+/*
+ * Link state on close.
+ */
+enum rte_eth_link_state_on_close close_state;
+
/*
* Number of processes in multi-process, used to
* configure the queues to be polled.
@@ -3103,6 +3108,17 @@ start_port(portid_t pid)
p_pi = pi;
cnt_pi++;
+ /* Configure link state on close */
+ if (close_state) {
+ diag = rte_eth_dev_set_link_state_on_close(pi, close_state);
+ if (diag < 0)
+ fprintf(stderr,
+ "Port %d: Failed to configure link state on close\n",
+ pi);
+ else
+ printf("Link state on close configured for port %i\n", pi);
+ }
+
/* start port */
diag = eth_dev_start_mp(pi);
if (diag < 0) {
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index e629edaa02..9e39bfea5b 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -821,6 +821,8 @@ extern struct rte_flow_action_conntrack conntrack_context;
extern int proc_id;
extern unsigned int num_procs;
+extern enum rte_eth_link_state_on_close close_state;
+
static inline bool
is_proc_primary(void)
{
@@ -959,6 +961,7 @@ void update_fwd_ports(portid_t new_pid);
void set_fwd_eth_peer(portid_t port_id, char *peer_addr);
void set_dev_led(portid_t port_id, bool active);
+void set_link_state_on_close(portid_t port_id, enum rte_eth_link_state_on_close state);
void port_mtu_set(portid_t port_id, uint16_t mtu);
int port_action_handle_create(portid_t port_id, uint32_t id, bool indirect_list,
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 6ad83ae50d..96a7dd5470 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1863,6 +1863,13 @@ Set a controllable LED associated with a certain port on or off::
testpmd> set port (port_id) led (on|off)
+set port link_state_on_close
+~~~~~~~~~~~~
+
+Set the link state on close for a certain port::
+
+ testpmd> set port (port_id) link_state_on_close (down|up|initial)
+
Port Functions
--------------
--
2.34.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [RFC PATCH 1/3] ethdev: add set link state on close API
2025-08-29 14:02 ` [RFC PATCH 1/3] ethdev: add set link state on close API Ciara Loftus
@ 2025-08-29 15:19 ` Ivan Malov
0 siblings, 0 replies; 5+ messages in thread
From: Ivan Malov @ 2025-08-29 15:19 UTC (permalink / raw)
To: Ciara Loftus; +Cc: dev
Hi Ciara,
On Fri, 29 Aug 2025, Ciara Loftus wrote:
> Allow the user to configure the state a link should be in after
> the device has been stopped/closed. Make this configurable
> through the new experimental rte_eth_dev_set_link_state_on_close
> API. Three states are allowed:
> 1. down: bring (or keep) the link down
> 2. up: bring (or keep) the link up
> 3. initial: restore the link to the state it was in when the device was
> started.
>
Perhaps it pays to name it 'status' instead of 'state', as the latter is not
confined to just 'up/down' but also includes the speed, technology, FEC, etc.
As for the three cases:
(3)
When the driver gets probed, it may discover the link being in some state that
the previous driver left us, (A). Then if the user does not invoke any APIs to
tweak the link settings and proceeds straight to 'rte_eth_dev_start', the link
will be in some best-effort state (B). Otherwise it will be in other state, (C).
Which one is implied by 'when the device was started'?
(2)
Does 'keep' describe the link being up prior to 'close'? If so, then if the
link is not 'up' prior to 'close', this commands to bring it up, which may
not be possible if the link partner is gone or the cable is unplugged.
(1)
This is OK. If the driver is capable to force link down, in electrical idle,
it will do that. If it can't do this, the whole API won't be supported.
Thank you.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-08-29 15:19 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-08-29 14:02 [RFC PATCH 0/3] Make Link Status on Close Configurable Ciara Loftus
2025-08-29 14:02 ` [RFC PATCH 1/3] ethdev: add set link state on close API Ciara Loftus
2025-08-29 15:19 ` Ivan Malov
2025-08-29 14:02 ` [RFC PATCH 2/3] net/ice: implement the link state on close device op Ciara Loftus
2025-08-29 14:02 ` [RFC PATCH 3/3] app/testpmd: support link state on close ethdev API Ciara Loftus
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).