RE: [PATCH iwl-net v3] ice: fix missing dpll notification for SW pins
From: Kubalewski, Arkadiusz
Date: Fri Feb 27 2026 - 09:48:44 EST
>From: Petr Oros <poros@xxxxxxxxxx>
>Sent: Friday, February 20, 2026 3:07 PM
>
>ice_dpll_notify_changes() sends dpll_pin_change_ntf() only for the
>direct CGU input pin stored in d->active_input. Software-controlled
>pins (SMA/U.FL) are separate dpll_pin objects that wrap a backing CGU
>input, but they never receive a change notification. As a result,
>userspace consumers such as synce4l that monitor SMA pins via dpll
>netlink never learn when the pin state transitions (e.g. from
>SELECTABLE to CONNECTED), even though 'dpll pin show' reports the
>correct state on demand.
>
>When the active input changes, also send dpll_pin_change_ntf() for any
>registered SMA/U.FL input pin whose backing CGU input matches the old
>or new active input.
>
>Fixes: 2dd5d03c77e2 ("ice: redesign dpll sma/u.fl pins control")
>Reported-by: kernel test robot <lkp@xxxxxxxxx>
>Closes: https://lore.kernel.org/oe-kbuild-all/202602200046.SGwK2tWh-
>lkp@xxxxxxxxx/
>Signed-off-by: Petr Oros <poros@xxxxxxxxxx>
Petr, many thanks for your patch!
LGTM.
Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@xxxxxxxxx>
>---
>v3:
>- Add kdoc for the helper.
>v2:
>- Extract ice_dpll_sw_pin_needs_notify() helper for readability,
>- Move loop variable into for() scope.
>
>drivers/net/ethernet/intel/ice/ice_dpll.c | 29 +++++++++++++++++++++++
> 1 file changed, 29 insertions(+)
>
>diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c
>b/drivers/net/ethernet/intel/ice/ice_dpll.c
>index c2ad39bfe177db..a9db85a1026388 100644
>--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
>+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
>@@ -2462,6 +2462,24 @@ static u64 ice_generate_clock_id(struct ice_pf *pf)
> return pci_get_dsn(pf->pdev);
> }
>
>+/**
>+ * ice_dpll_sw_pin_needs_notify - check if SW pin needs change
>notification
>+ * @p: pointer to SW pin (SMA or U.FL)
>+ * @active: currently active input pin (or NULL)
>+ * @old: previously active input pin (or NULL)
>+ *
>+ * Return: true if the SW pin is an input whose backing CGU pin matches
>either
>+ * the old or new active input, meaning its state has changed.
>+ */
>+static bool
>+ice_dpll_sw_pin_needs_notify(struct ice_dpll_pin *p,
>+ struct dpll_pin *active, struct dpll_pin *old)
>+{
>+ return p->pin &&
>+ p->direction == DPLL_PIN_DIRECTION_INPUT &&
>+ (p->input->pin == active || p->input->pin == old);
>+}
>+
> /**
> * ice_dpll_notify_changes - notify dpll subsystem about changes
> * @d: pointer do dpll
>@@ -2470,6 +2488,7 @@ static u64 ice_generate_clock_id(struct ice_pf *pf)
> */
> static void ice_dpll_notify_changes(struct ice_dpll *d)
> {
>+ struct ice_dplls *dplls = &d->pf->dplls;
> bool pin_notified = false;
>
> if (d->prev_dpll_state != d->dpll_state) {
>@@ -2477,6 +2496,8 @@ static void ice_dpll_notify_changes(struct ice_dpll
>*d)
> dpll_device_change_ntf(d->dpll);
> }
> if (d->prev_input != d->active_input) {
>+ struct dpll_pin *old = d->prev_input;
>+
> if (d->prev_input)
> dpll_pin_change_ntf(d->prev_input);
> d->prev_input = d->active_input;
>@@ -2484,6 +2505,14 @@ static void ice_dpll_notify_changes(struct ice_dpll
>*d)
> dpll_pin_change_ntf(d->active_input);
> pin_notified = true;
> }
>+ for (int i = 0; i < ICE_DPLL_PIN_SW_NUM; i++) {
>+ if (ice_dpll_sw_pin_needs_notify(&dplls->sma[i],
>+ d->active_input, old))
>+ dpll_pin_change_ntf(dplls->sma[i].pin);
>+ if (ice_dpll_sw_pin_needs_notify(&dplls->ufl[i],
>+ d->active_input, old))
>+ dpll_pin_change_ntf(dplls->ufl[i].pin);
>+ }
> }
> if (d->prev_phase_offset != d->phase_offset) {
> d->prev_phase_offset = d->phase_offset;
>--
>2.52.0