* [PATCH iwl-next v1 0/4] Rework and fix ice dpll pin control
@ 2026-07-16 9:49 Sergey Temerkhanov
2026-07-16 9:49 ` [PATCH iwl-next v1 1/4] ice: dpll: Rework multiplexed pin notifications Sergey Temerkhanov
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Sergey Temerkhanov @ 2026-07-16 9:49 UTC (permalink / raw)
To: intel-wired-lan; +Cc: netdev
This series reworks and clarifies ice DPLL control logic.
Contains refactoring changes for better readability and
maintainability as well as the changes making the pin
controls compliant to design requirements.
Sergey Temerkhanov (4):
ice: dpll: Rework multiplexed pin notifications
ice: dpll: Use switch statements to handle pin states
ice: dpll: Rework U.FL muxed pin (SMA) control
ice: dpll: Rework the SMA control logic to match the requirements
drivers/net/ethernet/intel/ice/ice_dpll.c | 248 +++++++++++++++++-----
drivers/net/ethernet/intel/ice/ice_dpll.h | 1 +
2 files changed, 193 insertions(+), 56 deletions(-)
base-commit: bf696cf19d64727a5a95126733603269ed8c42c2
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH iwl-next v1 1/4] ice: dpll: Rework multiplexed pin notifications
2026-07-16 9:49 [PATCH iwl-next v1 0/4] Rework and fix ice dpll pin control Sergey Temerkhanov
@ 2026-07-16 9:49 ` Sergey Temerkhanov
2026-07-16 9:49 ` [PATCH iwl-next v1 2/4] ice: dpll: Use switch statements to handle pin states Sergey Temerkhanov
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Sergey Temerkhanov @ 2026-07-16 9:49 UTC (permalink / raw)
To: intel-wired-lan; +Cc: netdev
Use a pointer to the struct ice_dpll_pin to link multiplexed
pins. This allows to simplify the selection logic.
Signed-off-by: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Przemyslaw Korba <przemyslaw.korba@intel.com>
---
drivers/net/ethernet/intel/ice/ice_dpll.c | 60 +++++++++++------------
drivers/net/ethernet/intel/ice/ice_dpll.h | 1 +
2 files changed, 31 insertions(+), 30 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c
index 1ca137f67dd4..fed7c9fea953 100644
--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
@@ -544,6 +544,29 @@ ice_dpll_pin_disable(struct ice_hw *hw, struct ice_dpll_pin *pin,
return ret;
}
+/**
+ * ice_dpll_sw_pin_notify_peer - notify the paired SW pin after a state change
+ * @changed: the SW pin that was explicitly changed (already notified by dpll core)
+ *
+ * SMA and U.FL pins share physical signal paths in pairs (SMA1/U.FL1 and
+ * SMA2/U.FL2). When one pin's routing changes via the PCA9575 GPIO
+ * expander, the paired pin's state may also change. Send a change
+ * notification for the peer pin so userspace consumers monitoring the
+ * peer via dpll netlink learn about the update.
+ *
+ * Context: Called from dpll_pin_ops callbacks after pf->dplls.lock is
+ * released. Uses __dpll_pin_change_ntf() because dpll_lock is
+ * still held by the dpll netlink layer.
+ */
+static void ice_dpll_sw_pin_notify_peer(struct ice_dpll_pin *changed)
+{
+ struct ice_dpll_pin *peer;
+
+ peer = changed->muxed;
+ if (peer->pin)
+ __dpll_pin_change_ntf(peer->pin);
+}
+
/**
* ice_dpll_pin_store_state - updates the state of pin in SW bookkeeping
* @pin: pointer to a pin
@@ -1171,32 +1194,6 @@ ice_dpll_input_state_get(const struct dpll_pin *pin, void *pin_priv,
extack, ICE_DPLL_PIN_TYPE_INPUT);
}
-/**
- * ice_dpll_sw_pin_notify_peer - notify the paired SW pin after a state change
- * @d: pointer to dplls struct
- * @changed: the SW pin that was explicitly changed (already notified by dpll core)
- *
- * SMA and U.FL pins share physical signal paths in pairs (SMA1/U.FL1 and
- * SMA2/U.FL2). When one pin's routing changes via the PCA9575 GPIO
- * expander, the paired pin's state may also change. Send a change
- * notification for the peer pin so userspace consumers monitoring the
- * peer via dpll netlink learn about the update.
- *
- * Context: Called from dpll_pin_ops callbacks after pf->dplls.lock is
- * released. Uses __dpll_pin_change_ntf() because dpll_lock is
- * still held by the dpll netlink layer.
- */
-static void ice_dpll_sw_pin_notify_peer(struct ice_dplls *d,
- struct ice_dpll_pin *changed)
-{
- struct ice_dpll_pin *peer;
-
- peer = (changed >= d->sma && changed < d->sma + ICE_DPLL_PIN_SW_NUM) ?
- &d->ufl[changed->idx] : &d->sma[changed->idx];
- if (peer->pin)
- __dpll_pin_change_ntf(peer->pin);
-}
-
/**
* ice_dpll_sma_direction_set - set direction of SMA pin
* @p: pointer to a pin
@@ -1258,7 +1255,7 @@ static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p,
* backing pin when U.FL becomes inactive because the SMA pin may
* still be using it.
*/
- peer = &d->ufl[p->idx];
+ peer = p->muxed;
if (peer->active) {
struct ice_dpll_pin *target;
enum ice_dpll_pin_type type;
@@ -1388,7 +1385,7 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
unlock:
mutex_unlock(&pf->dplls.lock);
if (!ret)
- ice_dpll_sw_pin_notify_peer(&pf->dplls, p);
+ ice_dpll_sw_pin_notify_peer(p);
return ret;
}
@@ -1508,7 +1505,7 @@ ice_dpll_sma_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
unlock:
mutex_unlock(&pf->dplls.lock);
if (!ret)
- ice_dpll_sw_pin_notify_peer(&pf->dplls, sma);
+ ice_dpll_sw_pin_notify_peer(sma);
return ret;
}
@@ -1705,7 +1702,7 @@ ice_dpll_pin_sma_direction_set(const struct dpll_pin *pin, void *pin_priv,
ret = ice_dpll_sma_direction_set(p, direction, extack);
mutex_unlock(&pf->dplls.lock);
if (!ret)
- ice_dpll_sw_pin_notify_peer(&pf->dplls, p);
+ ice_dpll_sw_pin_notify_peer(p);
return ret;
}
@@ -4623,6 +4620,8 @@ static int ice_dpll_init_info_sw_pins(struct ice_pf *pf)
if (pin->input->ref_sync)
pin->ref_sync = pin->input->ref_sync - pin_abs_idx;
pin->output = &d->outputs[ICE_DPLL_PIN_SW_OUTPUT_ABS(i)];
+ pin->muxed = &d->ufl[i];
+
ice_dpll_phase_range_set(&pin->prop.phase_range, phase_adj_max);
}
for (i = 0; i < ICE_DPLL_PIN_SW_NUM; i++) {
@@ -4656,6 +4655,7 @@ static int ice_dpll_init_info_sw_pins(struct ice_pf *pf)
(DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |
caps);
}
+ pin->muxed = &d->sma[i];
ice_dpll_phase_range_set(&pin->prop.phase_range, phase_adj_max);
}
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.h b/drivers/net/ethernet/intel/ice/ice_dpll.h
index c59d746a8567..c102ff2649d9 100644
--- a/drivers/net/ethernet/intel/ice/ice_dpll.h
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.h
@@ -78,6 +78,7 @@ struct ice_dpll_pin {
s32 phase_adjust;
struct ice_dpll_pin *input;
struct ice_dpll_pin *output;
+ struct ice_dpll_pin *muxed;
enum dpll_pin_direction direction;
s64 phase_offset;
u8 status;
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH iwl-next v1 2/4] ice: dpll: Use switch statements to handle pin states
2026-07-16 9:49 [PATCH iwl-next v1 0/4] Rework and fix ice dpll pin control Sergey Temerkhanov
2026-07-16 9:49 ` [PATCH iwl-next v1 1/4] ice: dpll: Rework multiplexed pin notifications Sergey Temerkhanov
@ 2026-07-16 9:49 ` Sergey Temerkhanov
2026-07-16 9:49 ` [PATCH iwl-next v1 3/4] ice: dpll: Rework U.FL muxed pin (SMA) control Sergey Temerkhanov
2026-07-16 9:49 ` [PATCH iwl-next v1 4/4] ice: dpll: Rework the SMA control logic to match the requirements Sergey Temerkhanov
3 siblings, 0 replies; 5+ messages in thread
From: Sergey Temerkhanov @ 2026-07-16 9:49 UTC (permalink / raw)
To: intel-wired-lan; +Cc: netdev
Use switch statements to handle pin states to make the code more
readable. This also makes this code more future-proof, should any
new states appear.
This also changes how direction-mismatched state requests are handled in
ice_dpll_sma_pin_state_set(). Previously, requesting CONNECTED on an
INPUT-direction SMA pin or SELECTABLE on an OUTPUT-direction pin would
fall through to ice_dpll_pin_disable() and return success. After this
change those requests return -EINVAL without issuing a firmware command.
Because the DPLL netlink core does not filter pin states by direction
before calling the driver, this is a user-visible netlink API change.
Signed-off-by: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Przemyslaw Korba <przemyslaw.korba@intel.com>
---
drivers/net/ethernet/intel/ice/ice_dpll.c | 65 ++++++++++++++++++-----
1 file changed, 53 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c
index fed7c9fea953..54958e17713b 100644
--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
@@ -1320,10 +1320,12 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
ret = -EINVAL;
switch (p->idx) {
case ICE_DPLL_PIN_SW_1_IDX:
- if (state == DPLL_PIN_STATE_CONNECTED) {
+ switch (state) {
+ case DPLL_PIN_STATE_CONNECTED:
data &= ~ICE_SMA1_MASK;
enable = true;
- } else if (state == DPLL_PIN_STATE_DISCONNECTED) {
+ break;
+ case DPLL_PIN_STATE_DISCONNECTED:
/* Skip if U.FL1 is not active, setting TX_EN
* while DIR_EN is set would also deactivate
* the paired SMA1 output.
@@ -1334,18 +1336,21 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
}
data |= ICE_SMA1_TX_EN;
enable = false;
- } else {
+ break;
+ default:
goto unlock;
}
target = p->output;
type = ICE_DPLL_PIN_TYPE_OUTPUT;
break;
case ICE_DPLL_PIN_SW_2_IDX:
- if (state == DPLL_PIN_STATE_SELECTABLE) {
+ switch (state) {
+ case DPLL_PIN_STATE_SELECTABLE:
data |= ICE_SMA2_DIR_EN;
data &= ~ICE_SMA2_UFL2_RX_DIS;
enable = true;
- } else if (state == DPLL_PIN_STATE_DISCONNECTED) {
+ break;
+ case DPLL_PIN_STATE_DISCONNECTED:
/* Skip if U.FL2 is not active, setting
* UFL2_RX_DIS could also disable the paired
* SMA2 input.
@@ -1357,7 +1362,8 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
}
data |= ICE_SMA2_UFL2_RX_DIS;
enable = false;
- } else {
+ break;
+ default:
goto unlock;
}
target = p->input;
@@ -1484,14 +1490,43 @@ ice_dpll_sma_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
if (ret)
goto unlock;
}
- if (sma->direction == DPLL_PIN_DIRECTION_INPUT) {
- enable = state == DPLL_PIN_STATE_SELECTABLE;
+ switch (state) {
+ case DPLL_PIN_STATE_SELECTABLE:
+ if (sma->direction == DPLL_PIN_DIRECTION_OUTPUT) {
+ enable = false;
+ ret = -EINVAL;
+ goto unlock;
+ }
+ enable = true;
+ break;
+ case DPLL_PIN_STATE_CONNECTED:
+ if (sma->direction == DPLL_PIN_DIRECTION_INPUT) {
+ enable = false;
+ ret = -EINVAL;
+ goto unlock;
+ }
+ enable = true;
+ break;
+ case DPLL_PIN_STATE_DISCONNECTED:
+ enable = false;
+ break;
+ default:
+ ret = -EINVAL;
+ goto unlock;
+ }
+
+ switch (sma->direction) {
+ case DPLL_PIN_DIRECTION_INPUT:
target = sma->input;
type = ICE_DPLL_PIN_TYPE_INPUT;
- } else {
- enable = state == DPLL_PIN_STATE_CONNECTED;
+ break;
+ case DPLL_PIN_DIRECTION_OUTPUT:
target = sma->output;
type = ICE_DPLL_PIN_TYPE_OUTPUT;
+ break;
+ default:
+ ret = -EINVAL;
+ goto unlock;
}
if (enable)
@@ -4631,7 +4666,8 @@ static int ice_dpll_init_info_sw_pins(struct ice_pf *pf)
pin->prop.capabilities = caps;
pin->pf = pf;
pin->prop.board_label = ice_dpll_sw_pin_ufl[i];
- if (i == ICE_DPLL_PIN_SW_1_IDX) {
+ switch (i) {
+ case ICE_DPLL_PIN_SW_1_IDX:
pin->direction = DPLL_PIN_DIRECTION_OUTPUT;
pin_abs_idx = ICE_DPLL_PIN_SW_OUTPUT_ABS(i);
pin->prop.freq_supported =
@@ -4641,7 +4677,8 @@ static int ice_dpll_init_info_sw_pins(struct ice_pf *pf)
pin->prop.freq_supported_num = freq_supp_num;
pin->input = NULL;
pin->output = &d->outputs[pin_abs_idx];
- } else if (i == ICE_DPLL_PIN_SW_2_IDX) {
+ break;
+ case ICE_DPLL_PIN_SW_2_IDX:
pin->direction = DPLL_PIN_DIRECTION_INPUT;
pin_abs_idx = ICE_DPLL_PIN_SW_INPUT_ABS(i) +
input_idx_offset;
@@ -4654,6 +4691,10 @@ static int ice_dpll_init_info_sw_pins(struct ice_pf *pf)
pin->prop.capabilities =
(DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |
caps);
+ break;
+ default:
+ dev_err(ice_pf_to_dev(pf), "Invalid U.FL pin index: %d\n", i);
+ return -EINVAL;
}
pin->muxed = &d->sma[i];
ice_dpll_phase_range_set(&pin->prop.phase_range, phase_adj_max);
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH iwl-next v1 3/4] ice: dpll: Rework U.FL muxed pin (SMA) control
2026-07-16 9:49 [PATCH iwl-next v1 0/4] Rework and fix ice dpll pin control Sergey Temerkhanov
2026-07-16 9:49 ` [PATCH iwl-next v1 1/4] ice: dpll: Rework multiplexed pin notifications Sergey Temerkhanov
2026-07-16 9:49 ` [PATCH iwl-next v1 2/4] ice: dpll: Use switch statements to handle pin states Sergey Temerkhanov
@ 2026-07-16 9:49 ` Sergey Temerkhanov
2026-07-16 9:49 ` [PATCH iwl-next v1 4/4] ice: dpll: Rework the SMA control logic to match the requirements Sergey Temerkhanov
3 siblings, 0 replies; 5+ messages in thread
From: Sergey Temerkhanov @ 2026-07-16 9:49 UTC (permalink / raw)
To: intel-wired-lan; +Cc: netdev
Rework multiplexed pin control to match the state change listed in
the design requirements.
Signed-off-by: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Przemyslaw Korba <przemyslaw.korba@intel.com>
---
drivers/net/ethernet/intel/ice/ice_dpll.c | 35 ++++++++++++++++++++---
1 file changed, 31 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c
index 54958e17713b..cb14621b3aef 100644
--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
@@ -1381,12 +1381,39 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
if (ret)
goto unlock;
- if (enable)
+ if (enable) {
ret = ice_dpll_pin_enable(hw, target, d->dpll_idx, type, extack);
- else
+ if (!ret)
+ ret = ice_dpll_pin_state_update(pf, target, type, extack);
+ if (!ret && p->muxed->active) {
+ struct ice_dpll_pin *peer = p->muxed;
+ struct ice_dpll_pin *peer_target;
+ enum ice_dpll_pin_type peer_type;
+ int peer_ret;
+
+ if (peer->direction == DPLL_PIN_DIRECTION_OUTPUT) {
+ peer_target = peer->output;
+ peer_type = ICE_DPLL_PIN_TYPE_OUTPUT;
+ } else {
+ peer_target = peer->input;
+ peer_type = ICE_DPLL_PIN_TYPE_INPUT;
+ }
+ peer_ret = ice_dpll_pin_enable(&pf->hw, peer_target,
+ pf->dplls.eec.dpll_idx,
+ peer_type, NULL);
+ if (!peer_ret)
+ peer_ret = ice_dpll_pin_state_update(pf, peer_target,
+ peer_type, NULL);
+ if (peer_ret)
+ dev_warn(ice_pf_to_dev(pf),
+ "Failed to sync peer pin %u after enabling U.FL pin %u, err %d\n",
+ peer_target->idx, target->idx, peer_ret);
+ }
+ } else {
ret = ice_dpll_pin_disable(hw, target, type, extack);
- if (!ret)
- ret = ice_dpll_pin_state_update(pf, target, type, extack);
+ if (!ret)
+ ret = ice_dpll_pin_state_update(pf, target, type, extack);
+ }
unlock:
mutex_unlock(&pf->dplls.lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH iwl-next v1 4/4] ice: dpll: Rework the SMA control logic to match the requirements
2026-07-16 9:49 [PATCH iwl-next v1 0/4] Rework and fix ice dpll pin control Sergey Temerkhanov
` (2 preceding siblings ...)
2026-07-16 9:49 ` [PATCH iwl-next v1 3/4] ice: dpll: Rework U.FL muxed pin (SMA) control Sergey Temerkhanov
@ 2026-07-16 9:49 ` Sergey Temerkhanov
3 siblings, 0 replies; 5+ messages in thread
From: Sergey Temerkhanov @ 2026-07-16 9:49 UTC (permalink / raw)
To: intel-wired-lan; +Cc: netdev
Make the SMA control logic match the requirements:
Setting SMA1 as Rx automatically enables U.FL1 as Tx if U.FL1 is
disconnected.
Setting SMA1 as Tx automatically changes U.FL1 state to disconnected.
Setting SMA2 as Tx automatically enables U.FL2 as Rx if U.FL2 is
disconnected.
Setting SMA2 as Rx automatically changes U.FL2 state to disconnected.
Signed-off-by: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
Reviewed-by: Przemyslaw Korba <przemyslaw.korba@intel.com>
---
drivers/net/ethernet/intel/ice/ice_dpll.c | 88 ++++++++++++++++++++---
1 file changed, 78 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c
index cb14621b3aef..f11d90ed80f2 100644
--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
@@ -698,10 +698,10 @@ ice_dpll_sw_pins_update(struct ice_pf *pf)
p = &d->sma[ICE_DPLL_PIN_SW_2_IDX];
p->active = true;
p->direction = DPLL_PIN_DIRECTION_INPUT;
+ if (data & ICE_SMA2_DIR_EN)
+ p->direction = DPLL_PIN_DIRECTION_OUTPUT;
if ((data & ICE_SMA2_INACTIVE_MASK) == ICE_SMA2_INACTIVE_MASK)
p->active = false;
- else if (data & ICE_SMA2_DIR_EN)
- p->direction = DPLL_PIN_DIRECTION_OUTPUT;
p = &d->ufl[ICE_DPLL_PIN_SW_1_IDX];
if (!(data & (ICE_SMA1_DIR_EN | ICE_SMA1_TX_EN)))
@@ -1224,17 +1224,21 @@ static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p,
switch (p->idx) {
case ICE_DPLL_PIN_SW_1_IDX:
- data &= ~ICE_SMA1_MASK;
- if (direction == DPLL_PIN_DIRECTION_OUTPUT)
+ if (direction == DPLL_PIN_DIRECTION_OUTPUT) {
+ data &= ~ICE_SMA1_TX_EN;
data |= ICE_SMA1_DIR_EN;
+ } else {
+ data &= ~ICE_SMA1_DIR_EN;
+ data &= ~ICE_SMA1_TX_EN;
+ }
break;
case ICE_DPLL_PIN_SW_2_IDX:
if (direction == DPLL_PIN_DIRECTION_INPUT) {
data &= ~ICE_SMA2_DIR_EN;
- data |= ICE_SMA2_UFL2_RX_DIS;
} else {
- data &= ~(ICE_SMA2_TX_EN | ICE_SMA2_UFL2_RX_DIS);
data |= ICE_SMA2_DIR_EN;
+ data &= ~ICE_SMA2_UFL2_RX_DIS;
+ data &= ~ICE_SMA2_TX_EN;
}
break;
default:
@@ -1505,6 +1509,7 @@ ice_dpll_sma_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
struct ice_dpll *d = dpll_priv;
struct ice_pf *pf = sma->pf;
enum ice_dpll_pin_type type;
+ u8 old_data = 0;
bool enable;
int ret;
@@ -1556,13 +1561,76 @@ ice_dpll_sma_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
goto unlock;
}
- if (enable)
+ if (enable) {
+ u8 data;
+
+ ret = ice_read_sma_ctrl(&pf->hw, &data);
+ if (ret)
+ goto unlock;
+ old_data = data;
+ if (sma->idx == ICE_DPLL_PIN_SW_1_IDX) {
+ data &= ~ICE_SMA1_TX_EN;
+ } else if (sma->idx == ICE_DPLL_PIN_SW_2_IDX) {
+ data &= ~ICE_SMA2_UFL2_RX_DIS;
+ data &= ~ICE_SMA2_TX_EN;
+ }
+ ret = ice_write_sma_ctrl(&pf->hw, data);
+ if (ret)
+ goto unlock;
+ ret = ice_dpll_sw_pins_update(pf);
+ if (ret)
+ goto restore_sma_ctrl;
+
ret = ice_dpll_pin_enable(&pf->hw, target, d->dpll_idx, type,
extack);
- else
- ret = ice_dpll_pin_disable(&pf->hw, target, type, extack);
- if (!ret)
+ if (ret)
+ goto restore_sma_ctrl;
+ /* refresh target state first so a peer-side error cannot leave it stale */
ret = ice_dpll_pin_state_update(pf, target, type, extack);
+ if (ret)
+ goto restore_sma_ctrl;
+
+ if (sma->muxed->active) {
+ struct ice_dpll_pin *peer = sma->muxed;
+ struct ice_dpll_pin *peer_target;
+ enum ice_dpll_pin_type peer_type;
+
+ if (peer->direction == DPLL_PIN_DIRECTION_OUTPUT) {
+ peer_target = peer->output;
+ peer_type = ICE_DPLL_PIN_TYPE_OUTPUT;
+ } else {
+ peer_target = peer->input;
+ peer_type = ICE_DPLL_PIN_TYPE_INPUT;
+ }
+ ret = ice_dpll_pin_enable(&pf->hw, peer_target,
+ d->dpll_idx,
+ peer_type, extack);
+ if (!ret)
+ ret = ice_dpll_pin_state_update(pf, peer_target,
+ peer_type, extack);
+ if (ret)
+ goto restore_sma_ctrl;
+ }
+ } else {
+ ret = ice_dpll_pin_disable(&pf->hw, target, type, extack);
+ if (!ret)
+ ret = ice_dpll_pin_state_update(pf, target, type,
+ extack);
+ }
+ goto unlock;
+
+restore_sma_ctrl:
+ {
+ int restore_ret;
+
+ restore_ret = ice_write_sma_ctrl(&pf->hw, old_data);
+ if (!restore_ret)
+ restore_ret = ice_dpll_sw_pins_update(pf);
+ if (restore_ret)
+ dev_warn(ice_pf_to_dev(pf),
+ "Failed to restore SMA control after pin state error %d, restore err %d\n",
+ ret, restore_ret);
+ }
unlock:
mutex_unlock(&pf->dplls.lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-07-16 9:49 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-16 9:49 [PATCH iwl-next v1 0/4] Rework and fix ice dpll pin control Sergey Temerkhanov
2026-07-16 9:49 ` [PATCH iwl-next v1 1/4] ice: dpll: Rework multiplexed pin notifications Sergey Temerkhanov
2026-07-16 9:49 ` [PATCH iwl-next v1 2/4] ice: dpll: Use switch statements to handle pin states Sergey Temerkhanov
2026-07-16 9:49 ` [PATCH iwl-next v1 3/4] ice: dpll: Rework U.FL muxed pin (SMA) control Sergey Temerkhanov
2026-07-16 9:49 ` [PATCH iwl-next v1 4/4] ice: dpll: Rework the SMA control logic to match the requirements Sergey Temerkhanov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox