[Intel-wired-lan] [PATCH iwl-next v2 3/4] ice: dpll: Rework U.FL muxed pin (SMA) control
Sergey Temerkhanov <[email protected]> Fri, 24 Jul 2026 12:13:49 +0000
| Newsgroups | org.osuosl.intel-wired-lan,org.kernel.vger.netdev |
|---|---|
| Message-ID | <[email protected]> |
Rework multiplexed pin control to match the state change listed in the design requirements. Signed-off-by: Sergey Temerkhanov <[email protected]> Reviewed-by: Aleksandr Loktionov <[email protected]> Reviewed-by: Przemyslaw Korba <[email protected]> --- drivers/net/ethernet/intel/ice/ice_dpll.c | 86 +++++++++++++++++++++-- 1 file changed, 80 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index 54958e17713b..cf54a7f2f836 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -1268,7 +1268,8 @@ static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p, type = ICE_DPLL_PIN_TYPE_INPUT; } ret = ice_dpll_pin_enable(&p->pf->hw, target, - d->eec.dpll_idx, type, extack); + d->pps.dpll_idx < ICE_DPLL_RCLK_NUM_MAX && target->state[d->pps.dpll_idx] == DPLL_PIN_STATE_CONNECTED ? + d->pps.dpll_idx : d->eec.dpll_idx, type, extack); if (!ret) ret = ice_dpll_pin_state_update(p->pf, target, type, extack); @@ -1304,6 +1305,7 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv, enum ice_dpll_pin_type type; struct ice_pf *pf = p->pf; struct ice_hw *hw; + u8 old_data = 0; bool enable; u8 data; int ret; @@ -1316,6 +1318,7 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv, ret = ice_read_sma_ctrl(hw, &data); if (ret) goto unlock; + old_data = data; ret = -EINVAL; switch (p->idx) { @@ -1379,14 +1382,85 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv, ret = ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_SOFTWARE, extack); if (ret) - goto unlock; + goto restore_sma_ctrl; - 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 && 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; + + switch (peer->direction) { + case DPLL_PIN_DIRECTION_OUTPUT: + peer_target = peer->output; + peer_type = ICE_DPLL_PIN_TYPE_OUTPUT; + break; + case DPLL_PIN_DIRECTION_INPUT: + peer_target = peer->input; + peer_type = ICE_DPLL_PIN_TYPE_INPUT; + break; + default: + ret = -EINVAL; + goto disable_pin; + } + if (!peer_target) { + ret = -EINVAL; + goto disable_pin; + } + peer_ret = ice_dpll_pin_enable(&pf->hw, peer_target, + pf->dplls.pps.dpll_idx < ICE_DPLL_RCLK_NUM_MAX && + peer_target->state[pf->dplls.pps.dpll_idx] == DPLL_PIN_STATE_CONNECTED ? + pf->dplls.pps.dpll_idx : 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) { + ret = peer_ret; + goto disable_pin; + } + } + } 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); + } + + goto unlock; + +disable_pin: + ice_dpll_pin_disable(hw, target, type, extack); + if (p->muxed && p->muxed->active) { + struct ice_dpll_pin *peer = p->muxed; + struct ice_dpll_pin *peer_target = NULL; + 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 if (peer->direction == DPLL_PIN_DIRECTION_INPUT) { + peer_target = peer->input; + peer_type = ICE_DPLL_PIN_TYPE_INPUT; + } + if (peer_target) + ice_dpll_pin_disable(&pf->hw, peer_target, peer_type, extack); + } +restore_sma_ctrl: + { + int restore_ret; + + restore_ret = ice_write_sma_ctrl(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