git: a781965b91ea - main - ice: Add led(4) identification support

Kevin Bowling <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src,gmane.os.freebsd.current.scm
Message-ID <[email protected]>
The branch main has been updated by kbowling:

URL: https://cgit.FreeBSD.org/src/commit/?id=a781965b91ea390f9576ae42c35c842db74aab86

commit a781965b91ea390f9576ae42c35c842db74aab86
Author:     Kevin Bowling <[email protected]>
AuthorDate: 2026-08-12 01:29:31 +0000
Commit:     Kevin Bowling <[email protected]>
CommitDate: 2026-08-18 00:33:19 +0000

    ice: Add led(4) identification support
    
    Expose the firmware-controlled physical port identification LED
    through /dev/led/ice*.  Use the AdminQ port-identification command to
    select blinking mode and restore the netlist-selected original mode
    before the interface is stopped.
    
    MFC after:      2 weeks
    Sponsored by:   BBOX.io
---
 share/man/man4/ice.4       |  9 ++++++++-
 sys/dev/ice/ice_iflib.h    |  1 +
 sys/dev/ice/if_ice_iflib.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/share/man/man4/ice.4 b/share/man/man4/ice.4
index a54a6b3fd6f3..35f752e5e7f8 100644
--- a/share/man/man4/ice.4
+++ b/share/man/man4/ice.4
@@ -32,7 +32,7 @@
 .\"
 .\" * Other names and brands may be claimed as the property of others.
 .\"
-.Dd November 5, 2025
+.Dd August 11, 2026
 .Dt ICE 4
 .Os
 .Sh NAME
@@ -155,6 +155,12 @@ be set and unset.
 For more information on configuring this device, see
 .Xr ifconfig 8 .
 .Pp
+The identification LED for each port is controlled through the
+.Xr led 4
+interface at its
+.Pa /dev/led/ice*
+device node.
+.Pp
 The associated Virtual Function (VF) driver for this driver is
 .Xr iavf 4 .
 .Pp
@@ -1156,6 +1162,7 @@ email all the specific information related to the issue to
 .Aq Mt [email protected] .
 .Sh SEE ALSO
 .Xr iflib 4 ,
+.Xr led 4 ,
 .Xr vlan 4 ,
 .Xr ifconfig 8 ,
 .Xr sysctl 8
diff --git a/sys/dev/ice/ice_iflib.h b/sys/dev/ice/ice_iflib.h
index e1d5307a9516..3e3d4e5f8d84 100644
--- a/sys/dev/ice/ice_iflib.h
+++ b/sys/dev/ice/ice_iflib.h
@@ -314,6 +314,7 @@ struct ice_softc {
 
 	/* link status */
 	bool link_up;
+	bool led_active;
 
 	/* Ethertype filters enabled */
 	bool enable_tx_fc_filter;
diff --git a/sys/dev/ice/if_ice_iflib.c b/sys/dev/ice/if_ice_iflib.c
index 2722b8892d61..41324cc6779a 100644
--- a/sys/dev/ice/if_ice_iflib.c
+++ b/sys/dev/ice/if_ice_iflib.c
@@ -81,6 +81,7 @@ static void ice_if_multi_set(if_ctx_t ctx);
 static void ice_if_vlan_register(if_ctx_t ctx, u16 vtag);
 static void ice_if_vlan_unregister(if_ctx_t ctx, u16 vtag);
 static void ice_if_stop(if_ctx_t ctx);
+static void ice_if_led_func(if_ctx_t ctx, int onoff);
 static uint64_t ice_if_get_counter(if_ctx_t ctx, ift_counter counter);
 static int ice_if_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data);
 static int ice_if_i2c_req(if_ctx_t ctx, struct ifi2creq *req);
@@ -139,6 +140,7 @@ static void ice_rebuild_recovery_mode(struct ice_softc *sc);
 static void ice_free_irqvs(struct ice_softc *sc);
 static void ice_update_rx_mbuf_sz(struct ice_softc *sc);
 static void ice_poll_for_media_avail(struct ice_softc *sc);
+static void ice_led_restore(struct ice_softc *sc);
 static void ice_setup_scctx(struct ice_softc *sc);
 static int ice_allocate_msix(struct ice_softc *sc);
 static void ice_admin_timer(void *arg);
@@ -201,6 +203,7 @@ static device_method_t ice_iflib_methods[] = {
 	DEVMETHOD(ifdi_media_change, ice_if_media_change),
 	DEVMETHOD(ifdi_init, ice_if_init),
 	DEVMETHOD(ifdi_stop, ice_if_stop),
+	DEVMETHOD(ifdi_led_func, ice_if_led_func),
 	DEVMETHOD(ifdi_timer, ice_if_timer),
 	DEVMETHOD(ifdi_update_admin_status, ice_if_update_admin_status),
 	DEVMETHOD(ifdi_multi_set, ice_if_multi_set),
@@ -2524,6 +2527,9 @@ ice_prepare_for_reset(struct ice_softc *sc)
 	if (ice_test_state(&sc->state, ICE_STATE_RECOVERY_MODE))
 		return;
 
+	/* Restore identification while the control queues are still usable. */
+	ice_led_restore(sc);
+
 	/* inform the RDMA client */
 	ice_rdma_notify_reset(sc);
 	/* stop the RDMA client */
@@ -2718,6 +2724,9 @@ ice_rebuild(struct ice_softc *sc)
 	if (err)
 		goto err_shutdown_ctrlq;
 
+	/* Retry a restore which could not complete while reset was pending. */
+	ice_led_restore(sc);
+
 	err = ice_init_link_events(sc);
 	if (err) {
 		device_printf(dev, "ice_init_link_events failed: %s\n",
@@ -3139,6 +3148,7 @@ ice_if_stop(if_ctx_t ctx)
 	struct ice_softc *sc = (struct ice_softc *)iflib_get_softc(ctx);
 
 	ASSERT_CTX_LOCKED(sc);
+	ice_led_restore(sc);
 
 	/*
 	 * The iflib core may call IFDI_STOP prior to the first call to
@@ -3192,6 +3202,40 @@ ice_if_stop(if_ctx_t ctx)
 	}
 }
 
+/**
+ * ice_if_led_func - Control the physical port identification LED
+ * @ctx: iflib context structure
+ * @onoff: non-zero to identify the port, zero to restore normal operation
+ *
+ * The firmware implements identification as a blinking mode and retains the
+ * netlist-selected mode so it can be restored without a register snapshot.
+ */
+static void
+ice_if_led_func(if_ctx_t ctx, int onoff)
+{
+	struct ice_softc *sc = iflib_get_softc(ctx);
+	enum ice_status status;
+	bool active;
+
+	active = onoff != 0;
+	if (active == sc->led_active)
+		return;
+
+	status = ice_aq_set_port_id_led(sc->hw.port_info, !active, NULL);
+	if (status == ICE_SUCCESS)
+		sc->led_active = active;
+}
+
+static void
+ice_led_restore(struct ice_softc *sc)
+{
+
+	if (!sc->led_active)
+		return;
+	if (ice_aq_set_port_id_led(sc->hw.port_info, true, NULL) == ICE_SUCCESS)
+		sc->led_active = false;
+}
+
 /**
  * ice_if_get_counter - Get current value of an ifnet statistic
  * @ctx: iflib context pointer
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.