net/intel: make link state configurable on device start
cover net/intel: make link state configurable on device start
Starting a port always brings its link up, so the link partner sees the port as soon as the application starts it. An application that enables ports only after its own configuration is applied, such as a firewall or a switch, cannot keep a disabled port dark: it can only bring the link down right after rte_eth_dev_start(), and the link partner may still see the link flap.
The ice driver already has the link_state_on_close device argument to choose the link state when the port is stopped. This series adds its counterpart, link_state_on_start, to the ice, i40e and ixgbe drivers:
-a <pci>,link_state_on_start=down
With "down", the port is started with the link down, and the application brings it up later with rte_eth_dev_set_link_up(). The default "up" keeps the current behavior.
ixgbe has no firmware command to bring the link down, so "down" leaves the port in the same state as rte_eth_dev_set_link_down(): the laser is kept off on fiber links, the copper PHY is powered off right after the link setup.
Tested with testpmd on E810-C (ice, firmware 4.60) connected to a network packet broker: with link_state_on_start=down the link stays down after the port start and the link partner does not see it until "set link-up"; without the device argument the link comes up on start as before. i40e and ixgbe are build tested only.
Roman Khromenok (3):
net/ice: make link state configurable on device start net/i40e: make link state configurable on device start net/ixgbe: make link state configurable on device start
doc/guides/nics/i40e.rst | 13 ++++++ doc/guides/nics/ice.rst | 13 ++++++ doc/guides/nics/ixgbe.rst | 13 ++++++ doc/guides/rel_notes/release_26_11.rst | 13 +++++- drivers/net/intel/i40e/i40e_ethdev.c | 58 +++++++++++++++++++++++++- drivers/net/intel/i40e/i40e_ethdev.h | 2 + drivers/net/intel/ice/ice_ethdev.c | 36 +++++++++++++++- drivers/net/intel/ice/ice_ethdev.h | 1 + drivers/net/intel/ixgbe/ixgbe_ethdev.c | 44 ++++++++++++++++++- drivers/net/intel/ixgbe/ixgbe_ethdev.h | 2 + 10 files changed, 187 insertions(+), 8 deletions(-)
Signature · 1 line
2.47.3
PATCH 1/3 net/ice: make link state configurable on device start
The device start always brings the link up, so the port shows up on the link partner as soon as the application starts it, even if the application wants to enable it later, for example only after its configuration is applied.
Introduce the device argument link_state_on_start, the counterpart of link_state_on_close:
1. up: bring the link up (default, unchanged behavior)
2. down: bring (or keep) the link down; the application brings it up later with rte_eth_dev_set_link_up().
--- doc/guides/nics/ice.rst | 13 ++++++++++ doc/guides/rel_notes/release_26_11.rst | 2 ++ drivers/net/intel/ice/ice_ethdev.c | 36 ++++++++++++++++++++++++-- drivers/net/intel/ice/ice_ethdev.h | 1 + 4 files changed, 50 insertions(+), 2 deletions(-)
doc/guides/nics/ice.rst +13 -0
@@ -324,6 +324,19 @@ Runtime Configuration * ``up``: Leave the link in the up state. * ``initial``: Restore the link to the state it was in when the device started. +- ``Link state on start`` (default ``up``) + + The user can request that the link be kept down when the device is started, + so that the port does not show up on the link partner until the application + calls ``rte_eth_dev_set_link_up()``:: + + -a af:00.0,link_state_on_start=<state> + + Supported values for the ``<state>`` parameter: + + * ``up``: Bring the link up. + * ``down``: Bring (or keep) the link down. + - ``Low Rx latency`` (default ``0``) vRAN workloads require low latency DPDK interface for the front haul
doc/guides/rel_notes/release_26_11.rst +2 -0
@@ -90,6 +90,8 @@ New Features enabling QinQ tag insertion and outer IPv4/UDP checksum offloads on those paths. * Added support for getting and setting link (802.3x) flow control. * Added support for Tx rate limiting per queue. + * Added ``link_state_on_start`` devarg to keep the link down + when the device is started. * **Updated Intel ixgbe driver.**
drivers/net/intel/ice/ice_ethdev.c +34 -2
@@ -45,6 +45,7 @@#define ICE_RL_BURST_SIZE_ARG "rl_burst_size"#define ICE_SOURCE_PRUNE_ARG "source-prune"#define ICE_LINK_STATE_ON_CLOSE "link_state_on_close" +#define ICE_LINK_STATE_ON_START "link_state_on_start"#define ICE_CYCLECOUNTER_MASK 0xffffffffffffffffULL
@@ -64,6 +65,7 @@ static const char * const ice_valid_args[] = {ICE_RL_BURST_SIZE_ARG ,ICE_SOURCE_PRUNE_ARG ,ICE_LINK_STATE_ON_CLOSE , +ICE_LINK_STATE_ON_START , NULL };
@@ -2265,6 +2267,27 @@ parse_link_state_on_close(const char *key, const char *value, void *args)return ret; } +static int +parse_link_state_on_start (const char *key,const char *value,void *args) +{ +bool *link_down = args; + +if (value ==NULL || link_down ==NULL ) +return -EINVAL ; + +if (strcmp (value,"down" ) ==0 ) { + *link_down = true; + }else if (strcmp (value,"up" ) ==0 ) { + *link_down = false; + }else { +PMD_DRV_LOG (WARNING ,"%s: Invalid value \"%s\", " +"should be \"down\" or \"up\"" , key, value); +return -EINVAL ; + } + +return 0 ; +} +static int lookup_pps_type (const char *pps_name) {
@@ -2529,6 +2552,11 @@ static int ice_parse_devargs(struct rte_eth_dev *dev) ret =rte_kvargs_process (kvlist,ICE_LINK_STATE_ON_CLOSE , &parse_link_state_on_close, &ad->devargs.link_state_on_close); +if (ret) + goto bail; + + ret =rte_kvargs_process (kvlist,ICE_LINK_STATE_ON_START , + &parse_link_state_on_start, &ad->devargs.link_down_on_start); bail:rte_kvargs_free (kvlist);
@@ -4856,7 +4884,10 @@ ice_dev_start(struct rte_eth_dev *dev)ice_get_init_link_status (dev); -ice_dev_set_link_up (dev); +if (pf->adapter->devargs.link_down_on_start) +ice_dev_set_link_down (dev); +else +ice_dev_set_link_up (dev);/* Call get_link_info aq command to enable/disable LSE */ ice_link_update (dev,0 );
@@ -8118,7 +8149,8 @@ RTE_PMD_REGISTER_PARAM_STRING(net_ice,ICE_RL_BURST_SIZE_ARG "=<N>" ICE_SOURCE_PRUNE_ARG "=<0|1>" ICE_RX_LOW_LATENCY_ARG "=<0|1>" - ICE_LINK_STATE_ON_CLOSE "=<down|up|initial>"); +ICE_LINK_STATE_ON_CLOSE "=<down|up|initial>" + ICE_LINK_STATE_ON_START "=<down|up>");RTE_LOG_REGISTER_SUFFIX (ice_logtype_init, init,NOTICE );RTE_LOG_REGISTER_SUFFIX (ice_logtype_driver, driver,NOTICE );
drivers/net/intel/ice/ice_ethdev.h +1 -0
@@ -640,6 +640,7 @@ struct ice_devargs {bool source_prune;uint32_t rl_burst_size;int link_state_on_close; +bool link_down_on_start;int xtr_field_offs;uint8_t xtr_flag_offs[PROTO_XTR_MAX ];/* Name of the field. */
Signature · 1 line
2.47.3
PATCH 2/3 net/i40e: make link state configurable on device start
In reply to Roman KhromenokThe device start always applies the link configuration, which brings the link up, so the port shows up on the link partner as soon as the application starts it, even if the application wants to enable it later, for example only after its configuration is applied.
Introduce the device argument link_state_on_start, as for the ice driver:
1. up: bring the link up (default, unchanged behavior)
2. down: bring (or keep) the link down; the application brings it up later with rte_eth_dev_set_link_up(), which applies the link configuration.
--- doc/guides/nics/i40e.rst | 13 ++++++ doc/guides/rel_notes/release_26_11.rst | 5 +++ drivers/net/intel/i40e/i40e_ethdev.c | 58 +++++++++++++++++++++++++- drivers/net/intel/i40e/i40e_ethdev.h | 2 + 4 files changed, 76 insertions(+), 2 deletions(-)
doc/guides/nics/i40e.rst +13 -0
@@ -193,6 +193,19 @@ Runtime Configuration * ``segment``: Check number of mbuf segments not exceed hw limitation. * ``offload``: Check any unsupported offload flag. +- ``Link state on start`` (default ``up``) + + The user can request that the link be kept down when the device is started, + so that the port does not show up on the link partner until the application + calls ``rte_eth_dev_set_link_up()``:: + + -a 84:00.0,link_state_on_start=<state> + + Supported values for the ``<state>`` parameter: + + * ``up``: Bring the link up. + * ``down``: Bring (or keep) the link down. + QinQ Configuration ~~~~~~~~~~~~~~~~~~
doc/guides/rel_notes/release_26_11.rst +5 -0
@@ -74,6 +74,11 @@ New Features ``xdp_meta_rx_ts_valid_mask``. * Added ``read_clock`` operation to query the PTP hardware clock. +* **Updated Intel i40e driver.** + + * Added ``link_state_on_start`` devarg to keep the link down + when the device is started. + * **Updated Intel iavf driver.** * Runtime Rx/Tx queue setup is now automatically disabled
drivers/net/intel/i40e/i40e_ethdev.c +56 -2
91 lines not on this page · raw message
drivers/net/intel/i40e/i40e_ethdev.h +2 -0
@@ -1203,6 +1203,8 @@ struct i40e_pf {bool fw8_3gt;/* MAC config needs re-applying when link first comes up */ bool mac_config_on_link_up; +/* Keep the link down on device start */ +bool link_down_on_start;/* true when interrupt path unavailable */ bool use_aq_polling;
Signature · 1 line
2.47.3
PATCH 3/3 net/ixgbe: make link state configurable on device start
In reply to Roman KhromenokThe device start always turns on the laser or the copper PHY and sets up the link, so the port shows up on the link partner as soon as the application starts it, even if the application wants to enable it later, for example only after its configuration is applied.
Introduce the device argument link_state_on_start, as for the ice and i40e drivers:
1. up: bring the link up (default, unchanged behavior)
2. down: keep the laser off on fiber links and leave the port in the same state as after rte_eth_dev_set_link_down(); the application brings it up later with rte_eth_dev_set_link_up().
On copper links the PHY is still powered on to set up the link and powered off right after it.
--- doc/guides/nics/ixgbe.rst | 13 ++++++++ doc/guides/rel_notes/release_26_11.rst | 6 ++-- drivers/net/intel/ixgbe/ixgbe_ethdev.c | 44 ++++++++++++++++++++++++-- drivers/net/intel/ixgbe/ixgbe_ethdev.h | 2 ++ 4 files changed, 61 insertions(+), 4 deletions(-)
doc/guides/nics/ixgbe.rst +13 -0
@@ -187,6 +187,19 @@ It must be passed as part of EAL arguments. For example, This value is read only at probe time. Changing it requires restarting the process with a new EAL argument. +- ``link_state_on_start`` (default **up**) + + The user can request that the link be kept down when the device is started, + so that the port does not show up on the link partner until the application + calls ``rte_eth_dev_set_link_up()``:: + + -a 81:00.0,link_state_on_start=<state> + + Supported values for the ``<state>`` parameter: + + * ``up``: Bring the link up. + * ``down``: Turn off the laser on fiber links or the PHY on copper links. + .. note:: The driver rejects Flow Director when DCB is enabled.
doc/guides/rel_notes/release_26_11.rst +4 -2
@@ -100,8 +100,10 @@ New Features * **Updated Intel ixgbe driver.** - Added ``fdir_buffer_size`` devarg to select the Flow Director table size - (``64k``, ``128k`` or ``256k``) at probe time. The default remains ``64k``. + * Added ``fdir_buffer_size`` devarg to select the Flow Director table size + (``64k``, ``128k`` or ``256k``) at probe time. The default remains ``64k``. + * Added ``link_state_on_start`` devarg to keep the link down + when the device is started. * **Updated NXP DPAA2 ethernet driver.**
drivers/net/intel/ixgbe/ixgbe_ethdev.c +42 -2
85 lines not on this page · raw message
drivers/net/intel/ixgbe/ixgbe_ethdev.h +2 -0
@@ -492,6 +492,8 @@ struct ixgbe_adapter {/* Used for limiting SDP3 TX_DISABLE checks */ uint8_t sdp3_no_tx_disable; +/* Keep the link down on device start */ +bool link_down_on_start;uint16_t max_vfs;/* Used for VF link sync with PF's physical and logical (by checking
Signature · 1 line
2.47.3
Quoted 7 lines · On Fri, 2 Oct 2026 21:43:35 +0200 Roman Khromenok <[email protected]> wrote:
Starting a port always brings its link up, so the link partner sees the port as soon as the application starts it. An application that enables ports only after its own configuration is applied, such as a firewall or a switch, cannot keep a disabled port dark: it can only bring the link down right after
rte_eth_dev_start(), and the link partner may still see the link flap.
Quoted 5 lines
The ice driver already has the
link_state_on_closedevice argument to choose the link state when the port is stopped. This series adds its counterpart,link_state_on_start, to the ice, i40e and ixgbe drivers:-a <pci>,link_state_on_start=down
NAK.
DPDK devices should not be like snowflakes, everyone unique.
When I see patches like this I think one or more of the following:
- a user does not understand how DPDK devices work and does not want to change their application
- developer refuses to say no to the user.
- DPDK devices semantics are poorly documented.
- DPDK devices do not implement the link states in RFC2863 but should. RFC 2863 separates ifAdminStatus from ifOperStatus; ethdev should as well.
If you want something done better it must done at ethdev layer and you must coordinate across all existing devices. No more specials.
Take user input as problem description, not as directive on how to solve it.
The link_state_on_close argument in ice is not a precedent. It was a workaround for hotplug problems and should not have been a devarg either. Adding a matching on_start option to three drivers repeats the mistake. I should have objected stronger then.
Quoted 2 lines · Stephen Hemminger
If you want something done better it must done at ethdev layer and you must coordinate across all existing devices.
Thanks, understood. I withdraw this series.
The problem behind it: a firewall starts its ports at boot but must keep the ports that are disabled in its configuration down, so that the link partner never sees them. Today rte_eth_dev_start() brings the link up on most drivers, and the application can only bring it down afterwards.
Would an RFC along these lines be acceptable?
- ethdev keeps the administrative link state (RFC 2863 ifAdminStatus) set by rte_eth_dev_set_link_down()/up(), including before the port is started;
- rte_eth_dev_start() honors it: drivers that support it keep the link down on start, and for the others ethdev calls dev_set_link_down() right after dev_start(), so the semantics are the same for all devices;
- a new feature in the features matrix to track driver support.
Or would you prefer a separate API for the administrative state instead of changing the behavior of rte_eth_dev_set_link_down()?
Roman
Quoted 20 lines · On Sat, 3 Oct 2026 23:53:45 +0200 Roman Khromenok <[email protected]> wrote:
Quoted 2 lines · Stephen Hemminger
If you want something done better it must done at ethdev layer and you must coordinate across all existing devices.
Thanks, understood. I withdraw this series.
The problem behind it: a firewall starts its ports at boot but must keep the ports that are disabled in its configuration down, so that the link partner never sees them. Today
rte_eth_dev_start()brings the link up on most drivers, and the application can only bring it down afterwards.Would an RFC along these lines be acceptable?
- ethdev keeps the administrative link state (RFC 2863 ifAdminStatus) set by rte_eth_dev_set_link_down()/up(), including before the port is started;
-rte_eth_dev_start()honors it: drivers that support it keep the link down on start, and for the others ethdev callsdev_set_link_down()right afterdev_start(), so the semantics are the same for all devices;
- a new feature in the features matrix to track driver support.
Quoted 4 lines
Or would you prefer a separate API for the administrative state instead of changing the behavior of
rte_eth_dev_set_link_down()?Roman
No. Application should not call device start until it expects to bring link up.
The RFC 2863 stuff is for layered devices where lower layers are separate from the upper ones (ie. tunnels, bonding, etc).
Quoted 6 lines · On Fri, 2 Oct 2026 21:43:35 +0200 Roman Khromenok <[email protected]> wrote:
Starting a port always brings its link up, so the link partner sees the port as soon as the application starts it. An application that enables ports only after its own configuration is applied, such as a firewall or a switch, cannot keep a disabled port dark: it can only bring the link down right after
rte_eth_dev_start(), and the link partner may still see the link flap.
The point of start is to signal that the application is ready to send and receive packets. I would expect the normal startup sequence is:
1. EAL init
2. Detect devices
3. Configure internal state
4. Configure devices.
5. Start devices
A device should be dark from 2 to 5. No packets coming in or out and link is down.