git: 8b2e75970c03 - main - ixl: Add led(4) identification support
Kevin Bowling <[email protected]>
| Newsgroups | gmane.os.freebsd.devel.cvs.src |
|---|---|
| Message-ID | <6a7be676.388a7.390be8b3__22217.9236284987$1786504887$gmane$org@gitrepo.freebsd.org> |
The branch main has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=8b2e75970c0328e7397290417cc06e9d9c763d2a commit 8b2e75970c0328e7397290417cc06e9d9c763d2a Author: Kevin Bowling <[email protected]> AuthorDate: 2026-08-12 00:54:21 +0000 Commit: Kevin Bowling <[email protected]> CommitDate: 2026-08-12 03:16:08 +0000 ixl: Add led(4) identification support Expose each physical port identification LED through /dev/led/ixl*. Use the existing GPIO LED helpers for most devices and the PHY provisioning interface for X710 10GBASE-T adapters. Preserve and restore the original GPIO or PHY indication mode, including before the interface is stopped. MFC after: 2 weeks --- share/man/man4/ixl.4 | 7 ++++- sys/dev/ixl/if_ixl.c | 78 +++++++++++++++++++++++++++++++++++++++++++++- sys/dev/ixl/ixl_pf.h | 5 +++ sys/dev/ixl/ixl_pf_iflib.c | 2 ++ 4 files changed, 90 insertions(+), 2 deletions(-) diff --git a/share/man/man4/ixl.4 b/share/man/man4/ixl.4 index 37d8c0cf5db8..b9c22e8b9b9c 100644 --- a/share/man/man4/ixl.4 +++ b/share/man/man4/ixl.4 @@ -29,7 +29,7 @@ .\" .\" * Other names and brands may be claimed as the property of others. .\" -.Dd August 9, 2026 +.Dd August 12, 2026 .Dt IXL 4 .Os .Sh NAME @@ -88,6 +88,10 @@ and/or TSO6, and finally LRO can be set and unset. .Pp For more information on configuring this device, see .Xr ifconfig 8 . +.Pp +The identification LED for each port is controlled through its +.Pa /dev/led/ixl* +device node. .Ss Additional Utilities There are additional tools available from Intel to help configure and update the adapters covered by this driver. @@ -301,6 +305,7 @@ email all the specific information related to the issue to .Xr arp 4 , .Xr iavf 4 , .Xr iflib 4 , +.Xr led 4 , .Xr netintro 4 , .Xr vlan 4 , .Xr ifconfig 8 , diff --git a/sys/dev/ixl/if_ixl.c b/sys/dev/ixl/if_ixl.c index 953882287386..886a4e52303c 100644 --- a/sys/dev/ixl/if_ixl.c +++ b/sys/dev/ixl/if_ixl.c @@ -122,6 +122,7 @@ static uint64_t ixl_if_get_counter(if_ctx_t ctx, ift_counter cnt); static int ixl_if_i2c_req(if_ctx_t ctx, struct ifi2creq *req); static int ixl_if_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data); static bool ixl_if_needs_restart(if_ctx_t ctx, enum iflib_restart_event event); +static void ixl_if_led_func(if_ctx_t ctx, int onoff); #ifdef PCI_IOV static void ixl_if_vflr_handle(if_ctx_t ctx); #endif @@ -193,13 +194,13 @@ static device_method_t ixl_if_methods[] = { DEVMETHOD(ifdi_i2c_req, ixl_if_i2c_req), DEVMETHOD(ifdi_priv_ioctl, ixl_if_priv_ioctl), DEVMETHOD(ifdi_needs_restart, ixl_if_needs_restart), + DEVMETHOD(ifdi_led_func, ixl_if_led_func), #ifdef PCI_IOV DEVMETHOD(ifdi_iov_init, ixl_if_iov_init), DEVMETHOD(ifdi_iov_uninit, ixl_if_iov_uninit), DEVMETHOD(ifdi_iov_vf_add, ixl_if_iov_vf_add), DEVMETHOD(ifdi_vflr_handle, ixl_if_vflr_handle), #endif - // ifdi_led_func // ifdi_debug DEVMETHOD_END }; @@ -1063,6 +1064,7 @@ ixl_if_stop(if_ctx_t ctx) INIT_DEBUGOUT("ixl_if_stop: begin\n"); + ixl_led_restore(pf); if (IXL_PF_IN_RECOVERY_MODE(pf)) return; @@ -1085,6 +1087,80 @@ ixl_if_stop(if_ctx_t ctx) ixl_set_link(pf, false); } +#define IXL_PHY_DEBUG_ALL \ + (I40E_AQ_PHY_DEBUG_DISABLE_LINK_FW | \ + I40E_AQ_PHY_DEBUG_DISABLE_ALL_LINK_FW) + +static bool +ixl_phy_controls_leds(const struct i40e_hw *hw) +{ + + /* These external 10GBASE-T PHYs own the identification LED. */ + return (hw->device_id == I40E_DEV_ID_10G_BASE_T || + hw->device_id == I40E_DEV_ID_10G_BASE_T4); +} + +static void +ixl_if_led_func(if_ctx_t ctx, int onoff) +{ + struct ixl_pf *pf; + struct i40e_hw *hw; + enum i40e_status_code status; + u16 phy_status; + + pf = iflib_get_softc(ctx); + hw = &pf->hw; + if (!onoff) { + ixl_led_restore(pf); + return; + } + if (pf->led_active) + return; + + pf->led_phy_controlled = ixl_phy_controls_leds(hw); + if (!pf->led_phy_controlled) { + pf->led_status = i40e_led_get(hw); + pf->led_active = true; + i40e_led_set(hw, 0xf, false); + return; + } + + if ((hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) == 0) + (void)i40e_aq_set_phy_debug(hw, IXL_PHY_DEBUG_ALL, NULL); + pf->led_phy_addr = I40E_PHY_LED_PROV_REG_1; + status = i40e_led_get_phy(hw, &pf->led_phy_addr, &phy_status); + if (status != I40E_SUCCESS) { + if ((hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) == 0) + (void)i40e_aq_set_phy_debug(hw, 0, NULL); + return; + } + pf->led_status = phy_status; + pf->led_active = true; + status = i40e_led_set_phy(hw, true, pf->led_phy_addr, 0); + if (status != I40E_SUCCESS) + ixl_led_restore(pf); +} + +void +ixl_led_restore(struct ixl_pf *pf) +{ + struct i40e_hw *hw; + + if (!pf->led_active) + return; + + hw = &pf->hw; + if (pf->led_phy_controlled) { + (void)i40e_led_set_phy(hw, false, pf->led_phy_addr, + pf->led_status | I40E_PHY_LED_MODE_ORIG); + if ((hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) == 0) + (void)i40e_aq_set_phy_debug(hw, 0, NULL); + } else { + i40e_led_set(hw, pf->led_status, false); + } + pf->led_active = false; +} + static int ixl_if_msix_intr_assign(if_ctx_t ctx, int msix) { diff --git a/sys/dev/ixl/ixl_pf.h b/sys/dev/ixl/ixl_pf.h index 74e1cad79731..7d751d3bd1dc 100644 --- a/sys/dev/ixl/ixl_pf.h +++ b/sys/dev/ixl/ixl_pf.h @@ -137,6 +137,10 @@ struct ixl_pf { #endif u32 state; u8 supported_speeds; + bool led_active; + bool led_phy_controlled; + u16 led_phy_addr; + u32 led_status; struct ixl_pf_qmgr qmgr; struct ixl_pf_qtag qtag; @@ -388,6 +392,7 @@ void ixl_shutdown_hmc(struct ixl_pf *); void ixl_handle_empr_reset(struct ixl_pf *); int ixl_prepare_for_reset(struct ixl_pf *pf, bool is_up); int ixl_rebuild_hw_structs_after_reset(struct ixl_pf *, bool is_up); +void ixl_led_restore(struct ixl_pf *pf); int ixl_pf_reset(struct ixl_pf *); #ifdef PCI_IOV diff --git a/sys/dev/ixl/ixl_pf_iflib.c b/sys/dev/ixl/ixl_pf_iflib.c index bdacf0cfa06d..90fc85198523 100644 --- a/sys/dev/ixl/ixl_pf_iflib.c +++ b/sys/dev/ixl/ixl_pf_iflib.c @@ -944,6 +944,8 @@ ixl_prepare_for_reset(struct ixl_pf *pf, bool is_up) int error, first_error; first_error = 0; + /* Restore identification before the reset tears down AdminQ access. */ + ixl_led_restore(pf); #ifdef PCI_IOV ixl_notify_vfs_reset(pf); error = ixl_quiesce_vfs_for_reset(pf);