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().

Signed-off-by: Roman Khromenok <[email protected]>
---
 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(-)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index ba598742c5..1a78760ff1 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -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
diff --git a/doc/guides/rel_notes/release_26_11.rst 
b/doc/guides/rel_notes/release_26_11.rst
index e8905f5533..a7fda78c5b 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -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.**
 
diff --git a/drivers/net/intel/ice/ice_ethdev.c 
b/drivers/net/intel/ice/ice_ethdev.c
index 163304ba1e..51a82830af 100644
--- a/drivers/net/intel/ice/ice_ethdev.c
+++ b/drivers/net/intel/ice/ice_ethdev.c
@@ -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);
diff --git a/drivers/net/intel/ice/ice_ethdev.h 
b/drivers/net/intel/ice/ice_ethdev.h
index 8d5e17e2df..8794870c34 100644
--- a/drivers/net/intel/ice/ice_ethdev.h
+++ b/drivers/net/intel/ice/ice_ethdev.h
@@ -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. */
-- 
2.47.3

Reply via email to